houdini 1.2.27 → 1.2.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/adapter/index.d.ts +1 -1
- package/build/cmd-cjs/index.js +4169 -1854
- package/build/cmd-esm/index.js +4169 -1854
- package/build/codegen/generators/artifacts/selection.d.ts +2 -1
- package/build/codegen/generators/typescript/inlineType.d.ts +5 -1
- package/build/codegen/generators/typescript/typeReference.d.ts +1 -1
- package/build/codegen/generators/typescript/types.d.ts +6 -3
- package/build/codegen/transforms/collectDefinitions.d.ts +1 -1
- package/build/codegen/transforms/componentFields.d.ts +8 -0
- package/build/codegen/transforms/fragmentVariables.d.ts +1 -1
- package/build/codegen/transforms/index.d.ts +1 -0
- package/build/codegen/validators/componentFields.d.ts +2 -0
- package/build/codegen/validators/index.d.ts +1 -0
- package/build/codegen-cjs/index.js +3674 -1393
- package/build/codegen-esm/index.js +3674 -1393
- package/build/lib/config.d.ts +21 -1
- package/build/lib/detectTools.d.ts +1 -1
- package/build/lib/graphql.d.ts +6 -0
- package/build/lib/imports.d.ts +1 -1
- package/build/lib/router/conventions.d.ts +1 -0
- package/build/lib/types.d.ts +4 -2
- package/build/lib/walk.d.ts +1 -0
- package/build/lib-cjs/index.js +1120 -747
- package/build/lib-esm/index.js +1119 -747
- package/build/runtime/cache/cache.d.ts +24 -3
- package/build/runtime/cache/storage.d.ts +1 -1
- package/build/runtime/client/index.d.ts +1 -0
- package/build/runtime/index.d.ts +1 -1
- package/build/runtime/lib/config.d.ts +9 -0
- package/build/runtime/lib/index.d.ts +1 -0
- package/build/runtime/lib/types.d.ts +18 -1
- package/build/runtime/router/server.d.ts +3 -1
- package/build/runtime/router/types.d.ts +1 -0
- package/build/runtime-cjs/cache/cache.d.ts +24 -3
- package/build/runtime-cjs/cache/cache.js +78 -8
- package/build/runtime-cjs/cache/storage.d.ts +1 -1
- package/build/runtime-cjs/cache/storage.js +16 -3
- package/build/runtime-cjs/client/index.d.ts +1 -0
- package/build/runtime-cjs/client/index.js +1 -0
- package/build/runtime-cjs/index.d.ts +1 -1
- package/build/runtime-cjs/lib/config.d.ts +9 -0
- package/build/runtime-cjs/lib/index.d.ts +1 -0
- package/build/runtime-cjs/lib/index.js +1 -0
- package/build/runtime-cjs/lib/types.d.ts +18 -1
- package/build/runtime-cjs/public/cache.js +3 -2
- package/build/runtime-cjs/router/server.d.ts +3 -1
- package/build/runtime-cjs/router/server.js +5 -2
- package/build/runtime-cjs/router/session.js +9 -6
- package/build/runtime-cjs/router/types.d.ts +1 -0
- package/build/runtime-esm/cache/cache.d.ts +24 -3
- package/build/runtime-esm/cache/cache.js +76 -8
- package/build/runtime-esm/cache/storage.d.ts +1 -1
- package/build/runtime-esm/cache/storage.js +16 -3
- package/build/runtime-esm/client/index.d.ts +1 -0
- package/build/runtime-esm/client/index.js +1 -0
- package/build/runtime-esm/index.d.ts +1 -1
- package/build/runtime-esm/lib/config.d.ts +9 -0
- package/build/runtime-esm/lib/index.d.ts +1 -0
- package/build/runtime-esm/lib/index.js +1 -0
- package/build/runtime-esm/lib/types.d.ts +18 -1
- package/build/runtime-esm/public/cache.js +3 -2
- package/build/runtime-esm/router/server.d.ts +3 -1
- package/build/runtime-esm/router/server.js +5 -2
- package/build/runtime-esm/router/session.js +9 -6
- package/build/runtime-esm/router/types.d.ts +1 -0
- package/build/test-cjs/index.js +3556 -1373
- package/build/test-esm/index.js +3556 -1373
- package/build/vite/schema.d.ts +4 -1
- package/build/vite-cjs/index.js +4543 -2823
- package/build/vite-esm/index.js +4540 -2822
- package/package.json +4 -3
|
@@ -3,7 +3,7 @@ import { type GraphQLSchema } from 'graphql';
|
|
|
3
3
|
import { createYoga } from 'graphql-yoga';
|
|
4
4
|
import type { HoudiniClient } from '../client';
|
|
5
5
|
import type { RouterManifest, RouterPageManifest, YogaServerOptions } from './types';
|
|
6
|
-
export declare function _serverHandler<ComponentType = unknown>({ schema, yoga, client, production, manifest, graphqlEndpoint, on_render, }: {
|
|
6
|
+
export declare function _serverHandler<ComponentType = unknown>({ schema, yoga, client, production, manifest, graphqlEndpoint, on_render, componentCache, }: {
|
|
7
7
|
schema?: GraphQLSchema | null;
|
|
8
8
|
yoga?: ReturnType<typeof createYoga> | null;
|
|
9
9
|
client: HoudiniClient;
|
|
@@ -11,11 +11,13 @@ export declare function _serverHandler<ComponentType = unknown>({ schema, yoga,
|
|
|
11
11
|
manifest: RouterManifest<ComponentType> | null;
|
|
12
12
|
assetPrefix: string;
|
|
13
13
|
graphqlEndpoint: string;
|
|
14
|
+
componentCache: Record<string, any>;
|
|
14
15
|
on_render: (args: {
|
|
15
16
|
url: string;
|
|
16
17
|
match: RouterPageManifest<ComponentType> | null;
|
|
17
18
|
manifest: RouterManifest<unknown>;
|
|
18
19
|
session: App.Session;
|
|
20
|
+
componentCache: Record<string, any>;
|
|
19
21
|
}) => Response | Promise<Response | undefined> | undefined;
|
|
20
22
|
} & Omit<YogaServerOptions, 'schema'>): (request: Request) => Promise<Response>;
|
|
21
23
|
export declare const serverAdapterFactory: (args: Parameters<typeof _serverHandler>[0]) => ReturnType<typeof createAdapter>;
|
|
@@ -37,7 +37,8 @@ function _serverHandler({
|
|
|
37
37
|
production,
|
|
38
38
|
manifest,
|
|
39
39
|
graphqlEndpoint,
|
|
40
|
-
on_render
|
|
40
|
+
on_render,
|
|
41
|
+
componentCache
|
|
41
42
|
}) {
|
|
42
43
|
if (schema && !yoga) {
|
|
43
44
|
yoga = (0, import_graphql_yoga.createYoga)({
|
|
@@ -46,6 +47,7 @@ function _serverHandler({
|
|
|
46
47
|
graphqlEndpoint
|
|
47
48
|
});
|
|
48
49
|
}
|
|
50
|
+
client.componentCache = componentCache;
|
|
49
51
|
if (schema) {
|
|
50
52
|
client.registerProxy(graphqlEndpoint, async ({ query, variables, session }) => {
|
|
51
53
|
const parsed = (0, import_graphql.parse)(query);
|
|
@@ -77,7 +79,8 @@ function _serverHandler({
|
|
|
77
79
|
url,
|
|
78
80
|
match,
|
|
79
81
|
session: await (0, import_session.get_session)(request.headers, session_keys),
|
|
80
|
-
manifest
|
|
82
|
+
manifest,
|
|
83
|
+
componentCache
|
|
81
84
|
});
|
|
82
85
|
if (rendered) {
|
|
83
86
|
return rendered;
|
|
@@ -31,13 +31,16 @@ async function handle_request(args) {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
async function redirect_auth(args) {
|
|
34
|
-
const { searchParams } = new URL(args.url, `http://${args.headers.get("host")}`);
|
|
34
|
+
const { searchParams, host } = new URL(args.url, `http://${args.headers.get("host")}`);
|
|
35
35
|
const { redirectTo, ...session } = Object.fromEntries(searchParams.entries());
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
const response = new Response("ok", {
|
|
37
|
+
status: 302,
|
|
38
|
+
headers: {
|
|
39
|
+
Location: redirectTo ?? "/"
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
await set_session(args, response, session);
|
|
43
|
+
return response;
|
|
41
44
|
}
|
|
42
45
|
const session_cookie_name = "__houdini__";
|
|
43
46
|
async function set_session(req, response, value) {
|
|
@@ -10,8 +10,10 @@ import { InMemorySubscriptions, type FieldSelection } from './subscription';
|
|
|
10
10
|
export declare class Cache {
|
|
11
11
|
#private;
|
|
12
12
|
_internal_unstable: CacheInternal;
|
|
13
|
-
constructor({ disabled, ...config }?: ConfigFile & {
|
|
13
|
+
constructor({ disabled, componentCache, createComponent, ...config }?: ConfigFile & {
|
|
14
14
|
disabled?: boolean;
|
|
15
|
+
componentCache?: Record<string, any>;
|
|
16
|
+
createComponent?: (comp: any, prop: Record<string, any>) => any;
|
|
15
17
|
});
|
|
16
18
|
write({ layer: layerID, notifySubscribers, ...args }: {
|
|
17
19
|
data: {
|
|
@@ -61,7 +63,9 @@ declare class CacheInternal {
|
|
|
61
63
|
cache: Cache;
|
|
62
64
|
lifetimes: GarbageCollector;
|
|
63
65
|
staleManager: StaleManager;
|
|
64
|
-
|
|
66
|
+
componentCache: Record<string, any>;
|
|
67
|
+
createComponent: (component: any, props: Record<string, any>) => any;
|
|
68
|
+
constructor({ storage, subscriptions, lists, cache, lifetimes, staleManager, disabled, config, componentCache, createComponent, }: {
|
|
65
69
|
storage: InMemoryStorage;
|
|
66
70
|
subscriptions: InMemorySubscriptions;
|
|
67
71
|
lists: ListManager;
|
|
@@ -70,6 +74,8 @@ declare class CacheInternal {
|
|
|
70
74
|
staleManager: StaleManager;
|
|
71
75
|
disabled: boolean;
|
|
72
76
|
config?: ConfigFile;
|
|
77
|
+
componentCache?: Record<string, any>;
|
|
78
|
+
createComponent: undefined | ((component: any, props: Record<string, any>) => any);
|
|
73
79
|
});
|
|
74
80
|
get config(): ConfigFile;
|
|
75
81
|
setConfig(config: ConfigFile): void;
|
|
@@ -108,8 +114,9 @@ declare class CacheInternal {
|
|
|
108
114
|
idFields(type: string): string[];
|
|
109
115
|
computeID(type: string, data: any): string;
|
|
110
116
|
isEmbedded(linkedType: string, value: GraphQLObject): boolean;
|
|
111
|
-
hydrateNestedList({ fields, variables, linkedList, stepsFromConnection, ignoreMasking, fullCheck, loading, }: {
|
|
117
|
+
hydrateNestedList({ fields, variables, linkedList, stepsFromConnection, ignoreMasking, fullCheck, loading, nullable, }: {
|
|
112
118
|
fields: SubscriptionSelection;
|
|
119
|
+
nullable: boolean;
|
|
113
120
|
variables?: {} | null;
|
|
114
121
|
linkedList: NestedList;
|
|
115
122
|
stepsFromConnection: number | null;
|
|
@@ -121,6 +128,7 @@ declare class CacheInternal {
|
|
|
121
128
|
partial: boolean;
|
|
122
129
|
stale: boolean;
|
|
123
130
|
hasData: boolean;
|
|
131
|
+
cascadeNull: boolean;
|
|
124
132
|
};
|
|
125
133
|
extractNestedListIDs({ value, abstract, recordID, key, linkedType, fields, variables, applyUpdates, specs, layer, forceNotify, }: {
|
|
126
134
|
value: GraphQLValue[];
|
|
@@ -144,4 +152,17 @@ export declare function evaluateFragmentVariables(variables: ValueMap, args: Gra
|
|
|
144
152
|
[k: string]: GraphQLValue;
|
|
145
153
|
};
|
|
146
154
|
export declare const rootID = "_ROOT_";
|
|
155
|
+
export declare function fragmentReference({ component, prop, }: {
|
|
156
|
+
component: {
|
|
157
|
+
name: string;
|
|
158
|
+
};
|
|
159
|
+
prop: string;
|
|
160
|
+
}): any;
|
|
161
|
+
export declare function defaultComponentField({ cache, component, loading, variables, parent, }: {
|
|
162
|
+
cache: Cache;
|
|
163
|
+
component: Required<Required<SubscriptionSelection>['fields'][string]>['component'];
|
|
164
|
+
loading?: boolean;
|
|
165
|
+
variables: Record<string, GraphQLValue> | undefined | null;
|
|
166
|
+
parent: string;
|
|
167
|
+
}): (props: any) => any;
|
|
147
168
|
export {};
|
|
@@ -12,7 +12,12 @@ import { evaluateKey } from "./stuff";
|
|
|
12
12
|
import { InMemorySubscriptions } from "./subscription";
|
|
13
13
|
class Cache {
|
|
14
14
|
_internal_unstable;
|
|
15
|
-
constructor({
|
|
15
|
+
constructor({
|
|
16
|
+
disabled,
|
|
17
|
+
componentCache,
|
|
18
|
+
createComponent,
|
|
19
|
+
...config
|
|
20
|
+
} = {}) {
|
|
16
21
|
this._internal_unstable = new CacheInternal({
|
|
17
22
|
cache: this,
|
|
18
23
|
storage: new InMemoryStorage(),
|
|
@@ -20,7 +25,9 @@ class Cache {
|
|
|
20
25
|
lists: new ListManager(this, rootID),
|
|
21
26
|
lifetimes: new GarbageCollector(this),
|
|
22
27
|
staleManager: new StaleManager(this),
|
|
23
|
-
disabled: disabled ?? typeof globalThis.window === "undefined"
|
|
28
|
+
disabled: disabled ?? typeof globalThis.window === "undefined",
|
|
29
|
+
componentCache,
|
|
30
|
+
createComponent
|
|
24
31
|
});
|
|
25
32
|
if (Object.keys(config).length > 0) {
|
|
26
33
|
this.setConfig(defaultConfigValues(config));
|
|
@@ -195,6 +202,8 @@ class CacheInternal {
|
|
|
195
202
|
cache;
|
|
196
203
|
lifetimes;
|
|
197
204
|
staleManager;
|
|
205
|
+
componentCache;
|
|
206
|
+
createComponent;
|
|
198
207
|
constructor({
|
|
199
208
|
storage,
|
|
200
209
|
subscriptions,
|
|
@@ -203,7 +212,9 @@ class CacheInternal {
|
|
|
203
212
|
lifetimes,
|
|
204
213
|
staleManager,
|
|
205
214
|
disabled,
|
|
206
|
-
config
|
|
215
|
+
config,
|
|
216
|
+
componentCache,
|
|
217
|
+
createComponent
|
|
207
218
|
}) {
|
|
208
219
|
this.storage = storage;
|
|
209
220
|
this.subscriptions = subscriptions;
|
|
@@ -212,6 +223,8 @@ class CacheInternal {
|
|
|
212
223
|
this.lifetimes = lifetimes;
|
|
213
224
|
this.staleManager = staleManager;
|
|
214
225
|
this._config = config;
|
|
226
|
+
this.componentCache = componentCache ?? {};
|
|
227
|
+
this.createComponent = createComponent ?? (() => ({}));
|
|
215
228
|
this._disabled = disabled;
|
|
216
229
|
try {
|
|
217
230
|
if (process.env.HOUDINI_TEST === "true") {
|
|
@@ -541,7 +554,8 @@ class CacheInternal {
|
|
|
541
554
|
visible,
|
|
542
555
|
directives,
|
|
543
556
|
loading: fieldLoading,
|
|
544
|
-
abstractHasRequired
|
|
557
|
+
abstractHasRequired,
|
|
558
|
+
component
|
|
545
559
|
}
|
|
546
560
|
] of Object.entries(targetSelection)) {
|
|
547
561
|
if (!visible && !ignoreMasking && !fullCheck) {
|
|
@@ -568,7 +582,13 @@ class CacheInternal {
|
|
|
568
582
|
if (generateLoading && !fieldLoading) {
|
|
569
583
|
continue;
|
|
570
584
|
}
|
|
571
|
-
|
|
585
|
+
const defaultValue = !component ? void 0 : defaultComponentField({
|
|
586
|
+
cache: this.cache,
|
|
587
|
+
component,
|
|
588
|
+
variables,
|
|
589
|
+
parent
|
|
590
|
+
});
|
|
591
|
+
let { value } = this.storage.get(parent, key, defaultValue);
|
|
572
592
|
const dt_field = this.staleManager.getFieldTime(parent, key);
|
|
573
593
|
if (dt_field === null) {
|
|
574
594
|
stale = true;
|
|
@@ -615,12 +635,16 @@ class CacheInternal {
|
|
|
615
635
|
stepsFromConnection: nextStep,
|
|
616
636
|
ignoreMasking: !!ignoreMasking,
|
|
617
637
|
fullCheck,
|
|
618
|
-
loading: generateLoading
|
|
638
|
+
loading: generateLoading,
|
|
639
|
+
nullable: !!nullable
|
|
619
640
|
});
|
|
620
641
|
fieldTarget[attributeName] = listValue.data;
|
|
621
642
|
if (listValue.partial) {
|
|
622
643
|
partial = true;
|
|
623
644
|
}
|
|
645
|
+
if (listValue.cascadeNull) {
|
|
646
|
+
cascadeNull = true;
|
|
647
|
+
}
|
|
624
648
|
if (listValue.stale) {
|
|
625
649
|
stale = true;
|
|
626
650
|
}
|
|
@@ -700,16 +724,19 @@ class CacheInternal {
|
|
|
700
724
|
stepsFromConnection,
|
|
701
725
|
ignoreMasking,
|
|
702
726
|
fullCheck,
|
|
703
|
-
loading
|
|
727
|
+
loading,
|
|
728
|
+
nullable
|
|
704
729
|
}) {
|
|
705
730
|
const result = [];
|
|
706
731
|
let partialData = false;
|
|
707
732
|
let stale = false;
|
|
708
733
|
let hasValues = false;
|
|
734
|
+
let cascadeNull = false;
|
|
709
735
|
for (const entry of linkedList) {
|
|
710
736
|
if (Array.isArray(entry)) {
|
|
711
737
|
const nestedValue = this.hydrateNestedList({
|
|
712
738
|
fields,
|
|
739
|
+
nullable,
|
|
713
740
|
variables,
|
|
714
741
|
linkedList: entry,
|
|
715
742
|
stepsFromConnection,
|
|
@@ -721,6 +748,9 @@ class CacheInternal {
|
|
|
721
748
|
if (nestedValue.partial) {
|
|
722
749
|
partialData = true;
|
|
723
750
|
}
|
|
751
|
+
if (nestedValue.cascadeNull) {
|
|
752
|
+
cascadeNull = true;
|
|
753
|
+
}
|
|
724
754
|
continue;
|
|
725
755
|
}
|
|
726
756
|
if (entry === null) {
|
|
@@ -741,6 +771,9 @@ class CacheInternal {
|
|
|
741
771
|
fullCheck,
|
|
742
772
|
loading
|
|
743
773
|
});
|
|
774
|
+
if (data === null && !nullable) {
|
|
775
|
+
cascadeNull = true;
|
|
776
|
+
}
|
|
744
777
|
result.push(data);
|
|
745
778
|
if (partial) {
|
|
746
779
|
partialData = true;
|
|
@@ -756,7 +789,8 @@ class CacheInternal {
|
|
|
756
789
|
data: result,
|
|
757
790
|
partial: partialData,
|
|
758
791
|
stale,
|
|
759
|
-
hasData: hasValues
|
|
792
|
+
hasData: hasValues,
|
|
793
|
+
cascadeNull
|
|
760
794
|
};
|
|
761
795
|
}
|
|
762
796
|
extractNestedListIDs({
|
|
@@ -885,8 +919,42 @@ function fragmentVariableValue(value, args) {
|
|
|
885
919
|
}
|
|
886
920
|
}
|
|
887
921
|
const rootID = "_ROOT_";
|
|
922
|
+
function fragmentReference({
|
|
923
|
+
component,
|
|
924
|
+
prop
|
|
925
|
+
}) {
|
|
926
|
+
return `${component.name}.${prop}`;
|
|
927
|
+
}
|
|
928
|
+
function defaultComponentField({
|
|
929
|
+
cache,
|
|
930
|
+
component,
|
|
931
|
+
loading,
|
|
932
|
+
variables,
|
|
933
|
+
parent
|
|
934
|
+
}) {
|
|
935
|
+
return (props) => {
|
|
936
|
+
const componentFn = cache._internal_unstable.componentCache[component.key];
|
|
937
|
+
const args = evaluateFragmentVariables(component.variables ?? {}, variables ?? {});
|
|
938
|
+
return cache._internal_unstable.createComponent(componentFn, {
|
|
939
|
+
...props,
|
|
940
|
+
[component.prop]: {
|
|
941
|
+
[fragmentKey]: {
|
|
942
|
+
loading,
|
|
943
|
+
values: {
|
|
944
|
+
[component.fragment]: {
|
|
945
|
+
variables: args,
|
|
946
|
+
parent
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
});
|
|
952
|
+
};
|
|
953
|
+
}
|
|
888
954
|
export {
|
|
889
955
|
Cache,
|
|
956
|
+
defaultComponentField,
|
|
890
957
|
evaluateFragmentVariables,
|
|
958
|
+
fragmentReference,
|
|
891
959
|
rootID
|
|
892
960
|
};
|
|
@@ -16,7 +16,7 @@ export declare class InMemoryStorage {
|
|
|
16
16
|
from: string;
|
|
17
17
|
to: string;
|
|
18
18
|
}): void;
|
|
19
|
-
get(id: string, field: string): {
|
|
19
|
+
get(id: string, field: string, defaultValue?: any): {
|
|
20
20
|
value: GraphQLField;
|
|
21
21
|
kind: 'link' | 'scalar' | 'unknown';
|
|
22
22
|
displayLayers: number[];
|
|
@@ -43,7 +43,7 @@ class InMemoryStorage {
|
|
|
43
43
|
layer.replaceID(replacement);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
get(id, field) {
|
|
46
|
+
get(id, field, defaultValue) {
|
|
47
47
|
const operations = {
|
|
48
48
|
[OperationKind.insert]: {
|
|
49
49
|
[OperationLocation.start]: [],
|
|
@@ -54,7 +54,7 @@ class InMemoryStorage {
|
|
|
54
54
|
const layerIDs = [];
|
|
55
55
|
for (let i = this.data.length - 1; i >= 0; i--) {
|
|
56
56
|
const layer = this.data[i];
|
|
57
|
-
|
|
57
|
+
let [layerValue, kind] = layer.get(id, field);
|
|
58
58
|
const layerOperations = layer.getOperations(id, field) || [];
|
|
59
59
|
layer.deletedIDs.forEach((v) => {
|
|
60
60
|
if (layer.operations[v]?.undoDeletesInList?.includes(field)) {
|
|
@@ -62,6 +62,12 @@ class InMemoryStorage {
|
|
|
62
62
|
}
|
|
63
63
|
operations.remove.add(v);
|
|
64
64
|
});
|
|
65
|
+
if (typeof layerValue === "undefined" && defaultValue) {
|
|
66
|
+
const targetLayer = this.topLayer;
|
|
67
|
+
const layerID = targetLayer.id;
|
|
68
|
+
targetLayer.writeField(id, field, defaultValue);
|
|
69
|
+
layerValue = defaultValue;
|
|
70
|
+
}
|
|
65
71
|
if (typeof layerValue === "undefined" && layerOperations.length === 0) {
|
|
66
72
|
if (layer.deletedIDs.size > 0) {
|
|
67
73
|
layerIDs.push(layer.id);
|
|
@@ -162,7 +168,14 @@ class InMemoryStorage {
|
|
|
162
168
|
serialize() {
|
|
163
169
|
return JSON.stringify({
|
|
164
170
|
rank: this.rank,
|
|
165
|
-
fields:
|
|
171
|
+
fields: Object.fromEntries(
|
|
172
|
+
Object.entries(this.topLayer.fields).map(([id, fieldMap]) => [
|
|
173
|
+
id,
|
|
174
|
+
Object.fromEntries(
|
|
175
|
+
Object.entries(fieldMap).filter(([_, value]) => typeof value !== "function")
|
|
176
|
+
)
|
|
177
|
+
])
|
|
178
|
+
),
|
|
166
179
|
links: this.topLayer.links
|
|
167
180
|
});
|
|
168
181
|
}
|
|
@@ -31,6 +31,7 @@ export declare class HoudiniClient {
|
|
|
31
31
|
operationName: string;
|
|
32
32
|
session: App.Session | null | undefined;
|
|
33
33
|
}) => Promise<any>>;
|
|
34
|
+
componentCache: Record<string, any>;
|
|
34
35
|
constructor({ url, fetchParams, plugins, pipeline, throwOnError, }?: HoudiniClientConstructorArgs);
|
|
35
36
|
observe<_Data extends GraphQLObject, _Input extends GraphQLVariables>({ enableCache, fetching, ...rest }: ObserveParams<_Data, DocumentArtifact, _Input>): DocumentStore<_Data, _Input>;
|
|
36
37
|
registerProxy(url: string, handler: (operation: {
|
|
@@ -3,6 +3,6 @@ import type { CacheTypeDef } from './generated';
|
|
|
3
3
|
import { Cache } from './public';
|
|
4
4
|
export * from './client';
|
|
5
5
|
export * from './lib';
|
|
6
|
-
export declare function graphql<_Payload>(str: TemplateStringsArray):
|
|
6
|
+
export declare function graphql<_Payload, _Result = _Payload>(str: TemplateStringsArray): _Result;
|
|
7
7
|
export declare const cache: Cache<CacheTypeDef>;
|
|
8
8
|
export declare function getCache(): InternalCache;
|
|
@@ -110,12 +110,21 @@ export type ConfigFile = {
|
|
|
110
110
|
/**
|
|
111
111
|
* For now, the cache's imperative API is considered unstable. In order to suppress the warning,
|
|
112
112
|
* you must enable this flag.
|
|
113
|
+
*
|
|
114
|
+
* @deprecated set features.imperativeCache instead
|
|
113
115
|
*/
|
|
114
116
|
acceptImperativeInstability?: boolean;
|
|
115
117
|
/**
|
|
116
118
|
* Configure the router
|
|
117
119
|
*/
|
|
118
120
|
router?: RouterConfig;
|
|
121
|
+
/**
|
|
122
|
+
* A collection of flags to opt-into experimental features that might break unexpectedly
|
|
123
|
+
*/
|
|
124
|
+
features?: {
|
|
125
|
+
componentFields?: boolean;
|
|
126
|
+
imperativeCache?: boolean;
|
|
127
|
+
};
|
|
119
128
|
};
|
|
120
129
|
type RouterConfig = {
|
|
121
130
|
auth?: AuthStrategy;
|
|
@@ -79,6 +79,7 @@ export type BaseCompiledDocument<_Kind extends ArtifactKinds> = {
|
|
|
79
79
|
selection: SubscriptionSelection;
|
|
80
80
|
rootType: string;
|
|
81
81
|
input?: InputObject;
|
|
82
|
+
hasComponents?: boolean;
|
|
82
83
|
refetch?: {
|
|
83
84
|
path: string[];
|
|
84
85
|
method: 'cursor' | 'offset';
|
|
@@ -156,12 +157,16 @@ export type SubscriptionSelection = {
|
|
|
156
157
|
arguments: ValueMap;
|
|
157
158
|
loading?: boolean;
|
|
158
159
|
}>;
|
|
160
|
+
components?: Record<string, {
|
|
161
|
+
prop: string;
|
|
162
|
+
attribute: string;
|
|
163
|
+
}>;
|
|
159
164
|
fields?: {
|
|
160
165
|
[fieldName: string]: {
|
|
161
166
|
type: string;
|
|
167
|
+
keyRaw: string;
|
|
162
168
|
nullable?: boolean;
|
|
163
169
|
required?: boolean;
|
|
164
|
-
keyRaw: string;
|
|
165
170
|
operations?: MutationOperation[];
|
|
166
171
|
list?: {
|
|
167
172
|
name: string;
|
|
@@ -182,6 +187,12 @@ export type SubscriptionSelection = {
|
|
|
182
187
|
selection?: SubscriptionSelection;
|
|
183
188
|
abstract?: boolean;
|
|
184
189
|
abstractHasRequired?: boolean;
|
|
190
|
+
component?: {
|
|
191
|
+
prop: string;
|
|
192
|
+
key: string;
|
|
193
|
+
fragment: string;
|
|
194
|
+
variables: ValueMap | null;
|
|
195
|
+
};
|
|
185
196
|
};
|
|
186
197
|
};
|
|
187
198
|
abstractFields?: {
|
|
@@ -333,6 +344,10 @@ export type ProjectManifest = {
|
|
|
333
344
|
local_schema: boolean;
|
|
334
345
|
/** Whether or not there is a custom instance of yoga defined */
|
|
335
346
|
local_yoga: boolean;
|
|
347
|
+
/** Information about componentFields defined in the project */
|
|
348
|
+
component_fields: Record<string, {
|
|
349
|
+
filepath: string;
|
|
350
|
+
}>;
|
|
336
351
|
};
|
|
337
352
|
export type PageManifest = {
|
|
338
353
|
id: string;
|
|
@@ -356,4 +371,6 @@ export type QueryManifest = {
|
|
|
356
371
|
loading: boolean;
|
|
357
372
|
/** The filepath of the unit */
|
|
358
373
|
path: string;
|
|
374
|
+
/** The list of variables that this query cares about */
|
|
375
|
+
variables: string[];
|
|
359
376
|
};
|
|
@@ -7,9 +7,10 @@ class Cache {
|
|
|
7
7
|
this._internal_unstable = cache;
|
|
8
8
|
}
|
|
9
9
|
validateInstabilityWarning() {
|
|
10
|
-
if (!this.config.acceptImperativeInstability) {
|
|
10
|
+
if (!this.config.acceptImperativeInstability && !this.config.features?.imperativeCache) {
|
|
11
11
|
console.warn(`\u26A0\uFE0F The imperative cache API is considered unstable and will change in any minor version release
|
|
12
|
-
Please acknowledge this by
|
|
12
|
+
Please acknowledge this by enabling the imperative cache feature flage in your config file.
|
|
13
|
+
For more information: https://houdinigraphql.com/api/cache`);
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
16
|
get(type, data) {
|
|
@@ -3,7 +3,7 @@ import { type GraphQLSchema } from 'graphql';
|
|
|
3
3
|
import { createYoga } from 'graphql-yoga';
|
|
4
4
|
import type { HoudiniClient } from '../client';
|
|
5
5
|
import type { RouterManifest, RouterPageManifest, YogaServerOptions } from './types';
|
|
6
|
-
export declare function _serverHandler<ComponentType = unknown>({ schema, yoga, client, production, manifest, graphqlEndpoint, on_render, }: {
|
|
6
|
+
export declare function _serverHandler<ComponentType = unknown>({ schema, yoga, client, production, manifest, graphqlEndpoint, on_render, componentCache, }: {
|
|
7
7
|
schema?: GraphQLSchema | null;
|
|
8
8
|
yoga?: ReturnType<typeof createYoga> | null;
|
|
9
9
|
client: HoudiniClient;
|
|
@@ -11,11 +11,13 @@ export declare function _serverHandler<ComponentType = unknown>({ schema, yoga,
|
|
|
11
11
|
manifest: RouterManifest<ComponentType> | null;
|
|
12
12
|
assetPrefix: string;
|
|
13
13
|
graphqlEndpoint: string;
|
|
14
|
+
componentCache: Record<string, any>;
|
|
14
15
|
on_render: (args: {
|
|
15
16
|
url: string;
|
|
16
17
|
match: RouterPageManifest<ComponentType> | null;
|
|
17
18
|
manifest: RouterManifest<unknown>;
|
|
18
19
|
session: App.Session;
|
|
20
|
+
componentCache: Record<string, any>;
|
|
19
21
|
}) => Response | Promise<Response | undefined> | undefined;
|
|
20
22
|
} & Omit<YogaServerOptions, 'schema'>): (request: Request) => Promise<Response>;
|
|
21
23
|
export declare const serverAdapterFactory: (args: Parameters<typeof _serverHandler>[0]) => ReturnType<typeof createAdapter>;
|
|
@@ -13,7 +13,8 @@ function _serverHandler({
|
|
|
13
13
|
production,
|
|
14
14
|
manifest,
|
|
15
15
|
graphqlEndpoint,
|
|
16
|
-
on_render
|
|
16
|
+
on_render,
|
|
17
|
+
componentCache
|
|
17
18
|
}) {
|
|
18
19
|
if (schema && !yoga) {
|
|
19
20
|
yoga = createYoga({
|
|
@@ -22,6 +23,7 @@ function _serverHandler({
|
|
|
22
23
|
graphqlEndpoint
|
|
23
24
|
});
|
|
24
25
|
}
|
|
26
|
+
client.componentCache = componentCache;
|
|
25
27
|
if (schema) {
|
|
26
28
|
client.registerProxy(graphqlEndpoint, async ({ query, variables, session }) => {
|
|
27
29
|
const parsed = parse(query);
|
|
@@ -53,7 +55,8 @@ function _serverHandler({
|
|
|
53
55
|
url,
|
|
54
56
|
match,
|
|
55
57
|
session: await get_session(request.headers, session_keys),
|
|
56
|
-
manifest
|
|
58
|
+
manifest,
|
|
59
|
+
componentCache
|
|
57
60
|
});
|
|
58
61
|
if (rendered) {
|
|
59
62
|
return rendered;
|
|
@@ -7,13 +7,16 @@ async function handle_request(args) {
|
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
async function redirect_auth(args) {
|
|
10
|
-
const { searchParams } = new URL(args.url, `http://${args.headers.get("host")}`);
|
|
10
|
+
const { searchParams, host } = new URL(args.url, `http://${args.headers.get("host")}`);
|
|
11
11
|
const { redirectTo, ...session } = Object.fromEntries(searchParams.entries());
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const response = new Response("ok", {
|
|
13
|
+
status: 302,
|
|
14
|
+
headers: {
|
|
15
|
+
Location: redirectTo ?? "/"
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
await set_session(args, response, session);
|
|
19
|
+
return response;
|
|
17
20
|
}
|
|
18
21
|
const session_cookie_name = "__houdini__";
|
|
19
22
|
async function set_session(req, response, value) {
|