Skip to content

Commit fc3b39b

Browse files
committed
initial prototype
1 parent f92dff4 commit fc3b39b

16 files changed

+166
-13
lines changed

examples/next/app/api/fuse/route.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { createAPIRouteHandler } from 'fuse/next'
2+
import persistedDocuments from '@/fuse/persisted-documents.json'
23

34
const files = require.context('../../../types', true, /\.ts$/)
45
files
56
.keys()
67
.filter((path: string) => path.includes('types/'))
78
.forEach(files)
89

9-
const layer = createAPIRouteHandler()
10+
const layer = createAPIRouteHandler({
11+
persistedOperationsStore: persistedDocuments,
12+
})
1013

1114
export const GET = layer
1215
export const POST = layer

examples/next/app/rsc/page.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import * as React from 'react'
2-
import { registerClient, createClient, fetchExchange } from 'fuse/next/server'
2+
import {
3+
registerClient,
4+
createClient,
5+
fetchExchange,
6+
persistedExchange,
7+
} from 'fuse/next/server'
38

49
import { graphql } from '@/fuse'
510
import { LaunchItem } from '@/components/LaunchItem'
@@ -14,7 +19,7 @@ const { getClient } = registerClient(() =>
1419
process.env.NODE_ENV === 'production'
1520
? 'https://spacex-fuse.vercel.app/api/fuse'
1621
: 'http://localhost:3000/api/fuse',
17-
exchanges: [fetchExchange],
22+
exchanges: [persistedExchange, fetchExchange],
1823
}),
1924
)
2025

examples/next/components/DatalayerProvider.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
cacheExchange,
77
fetchExchange,
88
createClient,
9+
persistedExchange,
910
} from 'fuse/next/client'
1011
import React from 'react'
1112

@@ -17,7 +18,7 @@ export const DatalayerProvider = (props: any) => {
1718
process.env.NODE_ENV === 'production'
1819
? 'https://spacex-fuse.vercel.app/api/fuse'
1920
: 'http://localhost:3000/api/fuse',
20-
exchanges: [cacheExchange, ssr, fetchExchange],
21+
exchanges: [cacheExchange, ssr, persistedExchange, fetchExchange],
2122
suspense: true,
2223
})
2324

examples/next/fuse/graphql.ts

+49
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ export const LaunchFieldsFragmentDoc = {
281281
selectionSet: {
282282
kind: 'SelectionSet',
283283
selections: [
284+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
284285
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
285286
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
286287
{ kind: 'Field', name: { kind: 'Name', value: 'launchDate' } },
@@ -303,6 +304,7 @@ export const SiteLocationFieldsFragmentDoc = {
303304
selectionSet: {
304305
kind: 'SelectionSet',
305306
selections: [
307+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
306308
{ kind: 'Field', name: { kind: 'Name', value: 'latitude' } },
307309
{ kind: 'Field', name: { kind: 'Name', value: 'longitude' } },
308310
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
@@ -325,6 +327,7 @@ export const LaunchSiteFieldsFragmentDoc = {
325327
selectionSet: {
326328
kind: 'SelectionSet',
327329
selections: [
330+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
328331
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
329332
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
330333
{ kind: 'Field', name: { kind: 'Name', value: 'details' } },
@@ -335,6 +338,7 @@ export const LaunchSiteFieldsFragmentDoc = {
335338
selectionSet: {
336339
kind: 'SelectionSet',
337340
selections: [
341+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
338342
{
339343
kind: 'FragmentSpread',
340344
name: { kind: 'Name', value: 'SiteLocationFields' },
@@ -355,6 +359,7 @@ export const LaunchSiteFieldsFragmentDoc = {
355359
selectionSet: {
356360
kind: 'SelectionSet',
357361
selections: [
362+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
358363
{ kind: 'Field', name: { kind: 'Name', value: 'latitude' } },
359364
{ kind: 'Field', name: { kind: 'Name', value: 'longitude' } },
360365
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
@@ -377,13 +382,15 @@ export const TotalCountFieldsFragmentDoc = {
377382
selectionSet: {
378383
kind: 'SelectionSet',
379384
selections: [
385+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
380386
{ kind: 'Field', name: { kind: 'Name', value: 'totalCount' } },
381387
],
382388
},
383389
},
384390
],
385391
} as unknown as DocumentNode<TotalCountFieldsFragment, unknown>
386392
export const Launches_SsrDocument = {
393+
__meta__: { hash: 'bb6e5ac452c5d08659b1855799a08ee2543a05ca' },
387394
kind: 'Document',
388395
definitions: [
389396
{
@@ -411,6 +418,7 @@ export const Launches_SsrDocument = {
411418
selectionSet: {
412419
kind: 'SelectionSet',
413420
selections: [
421+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
414422
{
415423
kind: 'Field',
416424
name: { kind: 'Name', value: 'launches' },
@@ -435,12 +443,17 @@ export const Launches_SsrDocument = {
435443
selectionSet: {
436444
kind: 'SelectionSet',
437445
selections: [
446+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
438447
{
439448
kind: 'Field',
440449
name: { kind: 'Name', value: 'nodes' },
441450
selectionSet: {
442451
kind: 'SelectionSet',
443452
selections: [
453+
{
454+
kind: 'Field',
455+
name: { kind: 'Name', value: '__typename' },
456+
},
444457
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
445458
{
446459
kind: 'FragmentSpread',
@@ -469,6 +482,7 @@ export const Launches_SsrDocument = {
469482
selectionSet: {
470483
kind: 'SelectionSet',
471484
selections: [
485+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
472486
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
473487
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
474488
{ kind: 'Field', name: { kind: 'Name', value: 'launchDate' } },
@@ -486,13 +500,15 @@ export const Launches_SsrDocument = {
486500
selectionSet: {
487501
kind: 'SelectionSet',
488502
selections: [
503+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
489504
{ kind: 'Field', name: { kind: 'Name', value: 'totalCount' } },
490505
],
491506
},
492507
},
493508
],
494509
} as unknown as DocumentNode<Launches_SsrQuery, Launches_SsrQueryVariables>
495510
export const Launches_RscDocument = {
511+
__meta__: { hash: '616ad65c55a2a69941aff21ec3c1d0964773771f' },
496512
kind: 'Document',
497513
definitions: [
498514
{
@@ -520,6 +536,7 @@ export const Launches_RscDocument = {
520536
selectionSet: {
521537
kind: 'SelectionSet',
522538
selections: [
539+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
523540
{
524541
kind: 'Field',
525542
name: { kind: 'Name', value: 'launches' },
@@ -544,12 +561,17 @@ export const Launches_RscDocument = {
544561
selectionSet: {
545562
kind: 'SelectionSet',
546563
selections: [
564+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
547565
{
548566
kind: 'Field',
549567
name: { kind: 'Name', value: 'nodes' },
550568
selectionSet: {
551569
kind: 'SelectionSet',
552570
selections: [
571+
{
572+
kind: 'Field',
573+
name: { kind: 'Name', value: '__typename' },
574+
},
553575
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
554576
{
555577
kind: 'FragmentSpread',
@@ -578,6 +600,7 @@ export const Launches_RscDocument = {
578600
selectionSet: {
579601
kind: 'SelectionSet',
580602
selections: [
603+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
581604
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
582605
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
583606
{ kind: 'Field', name: { kind: 'Name', value: 'launchDate' } },
@@ -595,13 +618,15 @@ export const Launches_RscDocument = {
595618
selectionSet: {
596619
kind: 'SelectionSet',
597620
selections: [
621+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
598622
{ kind: 'Field', name: { kind: 'Name', value: 'totalCount' } },
599623
],
600624
},
601625
},
602626
],
603627
} as unknown as DocumentNode<Launches_RscQuery, Launches_RscQueryVariables>
604628
export const LaunchDetailsDocument = {
629+
__meta__: { hash: '06f997a01891cf62f3b0499580b0d70a0d9658ae' },
605630
kind: 'Document',
606631
definitions: [
607632
{
@@ -621,6 +646,7 @@ export const LaunchDetailsDocument = {
621646
selectionSet: {
622647
kind: 'SelectionSet',
623648
selections: [
649+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
624650
{
625651
kind: 'Field',
626652
name: { kind: 'Name', value: 'node' },
@@ -637,6 +663,7 @@ export const LaunchDetailsDocument = {
637663
selectionSet: {
638664
kind: 'SelectionSet',
639665
selections: [
666+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
640667
{
641668
kind: 'InlineFragment',
642669
typeCondition: {
@@ -646,6 +673,10 @@ export const LaunchDetailsDocument = {
646673
selectionSet: {
647674
kind: 'SelectionSet',
648675
selections: [
676+
{
677+
kind: 'Field',
678+
name: { kind: 'Name', value: '__typename' },
679+
},
649680
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
650681
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
651682
{
@@ -663,6 +694,10 @@ export const LaunchDetailsDocument = {
663694
selectionSet: {
664695
kind: 'SelectionSet',
665696
selections: [
697+
{
698+
kind: 'Field',
699+
name: { kind: 'Name', value: '__typename' },
700+
},
666701
{
667702
kind: 'FragmentSpread',
668703
name: { kind: 'Name', value: 'LaunchSiteFields' },
@@ -676,6 +711,10 @@ export const LaunchDetailsDocument = {
676711
selectionSet: {
677712
kind: 'SelectionSet',
678713
selections: [
714+
{
715+
kind: 'Field',
716+
name: { kind: 'Name', value: '__typename' },
717+
},
679718
{
680719
kind: 'Field',
681720
name: { kind: 'Name', value: 'cost' },
@@ -714,6 +753,7 @@ export const LaunchDetailsDocument = {
714753
selectionSet: {
715754
kind: 'SelectionSet',
716755
selections: [
756+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
717757
{ kind: 'Field', name: { kind: 'Name', value: 'latitude' } },
718758
{ kind: 'Field', name: { kind: 'Name', value: 'longitude' } },
719759
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
@@ -731,6 +771,7 @@ export const LaunchDetailsDocument = {
731771
selectionSet: {
732772
kind: 'SelectionSet',
733773
selections: [
774+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
734775
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
735776
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
736777
{ kind: 'Field', name: { kind: 'Name', value: 'details' } },
@@ -741,6 +782,7 @@ export const LaunchDetailsDocument = {
741782
selectionSet: {
742783
kind: 'SelectionSet',
743784
selections: [
785+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
744786
{
745787
kind: 'FragmentSpread',
746788
name: { kind: 'Name', value: 'SiteLocationFields' },
@@ -754,6 +796,7 @@ export const LaunchDetailsDocument = {
754796
],
755797
} as unknown as DocumentNode<LaunchDetailsQuery, LaunchDetailsQueryVariables>
756798
export const PageLaunchesDocument = {
799+
__meta__: { hash: '351e381d4b9bbd1da05483d9f533cc48dfcd2777' },
757800
kind: 'Document',
758801
definitions: [
759802
{
@@ -781,6 +824,7 @@ export const PageLaunchesDocument = {
781824
selectionSet: {
782825
kind: 'SelectionSet',
783826
selections: [
827+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
784828
{
785829
kind: 'Field',
786830
name: { kind: 'Name', value: 'launches' },
@@ -805,12 +849,17 @@ export const PageLaunchesDocument = {
805849
selectionSet: {
806850
kind: 'SelectionSet',
807851
selections: [
852+
{ kind: 'Field', name: { kind: 'Name', value: '__typename' } },
808853
{
809854
kind: 'Field',
810855
name: { kind: 'Name', value: 'nodes' },
811856
selectionSet: {
812857
kind: 'SelectionSet',
813858
selections: [
859+
{
860+
kind: 'Field',
861+
name: { kind: 'Name', value: '__typename' },
862+
},
814863
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
815864
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
816865
],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"bb6e5ac452c5d08659b1855799a08ee2543a05ca": "fragment LaunchFields on Launch { __typename id image launchDate name } fragment TotalCountFields on QueryLaunchesList { __typename totalCount } query Launches_SSR($limit: Int, $offset: Int) { __typename launches(limit: $limit, offset: $offset) { __typename nodes { __typename id ...LaunchFields } ...TotalCountFields } }",
3+
"616ad65c55a2a69941aff21ec3c1d0964773771f": "fragment LaunchFields on Launch { __typename id image launchDate name } fragment TotalCountFields on QueryLaunchesList { __typename totalCount } query Launches_RSC($limit: Int, $offset: Int) { __typename launches(limit: $limit, offset: $offset) { __typename nodes { __typename id ...LaunchFields } ...TotalCountFields } }",
4+
"06f997a01891cf62f3b0499580b0d70a0d9658ae": "fragment LaunchSiteFields on Site { __typename details id location { __typename ...SiteLocationFields } name status } fragment SiteLocationFields on Location { __typename latitude longitude name region } query LaunchDetails($id: ID!) { __typename node(id: $id) { __typename ... on Launch { __typename details id image launchDate name rocket { __typename company cost country description } site { __typename ...LaunchSiteFields } } } }",
5+
"351e381d4b9bbd1da05483d9f533cc48dfcd2777": "query PageLaunches($limit: Int, $offset: Int) { __typename launches(limit: $limit, offset: $offset) { __typename nodes { __typename id name } totalCount } }"
6+
}

examples/next/pages/test.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
ssrExchange,
1010
cacheExchange,
1111
fetchExchange,
12+
persistedExchange,
1213
} from 'fuse/next/pages'
1314

1415
import { graphql } from '@/fuse'
@@ -65,7 +66,7 @@ export async function getServerSideProps() {
6566
process.env.NODE_ENV === 'production'
6667
? 'https://spacex-fuse.vercel.app/api/fuse'
6768
: 'http://localhost:3000/api/fuse',
68-
exchanges: [cacheExchange, ssrCache, fetchExchange],
69+
exchanges: [cacheExchange, ssrCache, persistedExchange, fetchExchange],
6970
})
7071

7172
await client.query(LaunchesQuery, { limit: 10, offset: 0 }).toPromise()
@@ -84,5 +85,5 @@ export default withGraphQLClient((ssrCache) => ({
8485
process.env.NODE_ENV === 'production'
8586
? 'https://spacex-fuse.vercel.app/api/fuse'
8687
: 'http://localhost:3000/api/fuse',
87-
exchanges: [cacheExchange, ssrCache, fetchExchange],
88+
exchanges: [cacheExchange, ssrCache, persistedExchange, fetchExchange],
8889
}))(Page)

examples/next/schema.graphql

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,4 @@ type User implements Node {
8282
firstName: String
8383
id: ID!
8484
name: String
85-
}
85+
}

packages/core/client.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
// src/next/client.ts
2+
import { Exchange } from '@urql/core'
23
import { useQuery, UrqlProvider } from '@urql/next'
34
export * from 'urql'
45
export { UrqlProvider as Provider, useQuery }
6+
7+
export const persistedExchange: Exchange

packages/core/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,13 @@
6767
"@graphql-typed-document-node/core": "^3.2.0",
6868
"@graphql-yoga/plugin-defer-stream": "^3.0.0",
6969
"@graphql-yoga/plugin-disable-introspection": "^2.0.0",
70+
"@graphql-yoga/plugin-persisted-operations": "^3.0.1",
7071
"@parcel/watcher": "^2.3.0",
7172
"@pothos/core": "^3.38.0",
7273
"@pothos/plugin-dataloader": "^3.17.1",
7374
"@pothos/plugin-relay": "^3.44.0",
7475
"@urql/core": "^4.2.0",
76+
"@urql/exchange-persisted": "^4.1.1",
7577
"@urql/next": "^1.1.0",
7678
"dataloader": "^2.2.2",
7779
"graphql": "^16.8.1",

packages/core/rsc.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
// src/next/rsc.ts
2+
import { Exchange } from '@urql/core'
23
export { registerUrql as registerClient } from '@urql/next/rsc'
34
export * from '@urql/core'
5+
6+
export const persistedExchange: Exchange

packages/core/src/next/client.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
import { useQuery, UrqlProvider } from '@urql/next'
2+
import { persistedExchange as urqlPersistedExchange } from '@urql/exchange-persisted'
3+
4+
export const persistedExchange = urqlPersistedExchange({
5+
enforcePersistedQueries: process.env.NODE_ENV === 'production',
6+
enableForMutation: true,
7+
generateHash: (_, document) =>
8+
Promise.resolve((document as any)['__meta__']['hash']),
9+
})
210

311
export * from 'urql'
412
export { useQuery, UrqlProvider as Provider }

0 commit comments

Comments
 (0)