houdini 1.2.27 → 1.2.29

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.
Files changed (71) hide show
  1. package/build/adapter/index.d.ts +1 -1
  2. package/build/cmd-cjs/index.js +4169 -1854
  3. package/build/cmd-esm/index.js +4169 -1854
  4. package/build/codegen/generators/artifacts/selection.d.ts +2 -1
  5. package/build/codegen/generators/typescript/inlineType.d.ts +5 -1
  6. package/build/codegen/generators/typescript/typeReference.d.ts +1 -1
  7. package/build/codegen/generators/typescript/types.d.ts +6 -3
  8. package/build/codegen/transforms/collectDefinitions.d.ts +1 -1
  9. package/build/codegen/transforms/componentFields.d.ts +8 -0
  10. package/build/codegen/transforms/fragmentVariables.d.ts +1 -1
  11. package/build/codegen/transforms/index.d.ts +1 -0
  12. package/build/codegen/validators/componentFields.d.ts +2 -0
  13. package/build/codegen/validators/index.d.ts +1 -0
  14. package/build/codegen-cjs/index.js +3674 -1393
  15. package/build/codegen-esm/index.js +3674 -1393
  16. package/build/lib/config.d.ts +21 -1
  17. package/build/lib/detectTools.d.ts +1 -1
  18. package/build/lib/graphql.d.ts +6 -0
  19. package/build/lib/imports.d.ts +1 -1
  20. package/build/lib/router/conventions.d.ts +1 -0
  21. package/build/lib/types.d.ts +4 -2
  22. package/build/lib/walk.d.ts +1 -0
  23. package/build/lib-cjs/index.js +1120 -747
  24. package/build/lib-esm/index.js +1119 -747
  25. package/build/runtime/cache/cache.d.ts +24 -3
  26. package/build/runtime/cache/storage.d.ts +1 -1
  27. package/build/runtime/client/index.d.ts +1 -0
  28. package/build/runtime/index.d.ts +1 -1
  29. package/build/runtime/lib/config.d.ts +9 -0
  30. package/build/runtime/lib/index.d.ts +1 -0
  31. package/build/runtime/lib/types.d.ts +18 -1
  32. package/build/runtime/router/server.d.ts +3 -1
  33. package/build/runtime/router/types.d.ts +1 -0
  34. package/build/runtime-cjs/cache/cache.d.ts +24 -3
  35. package/build/runtime-cjs/cache/cache.js +78 -8
  36. package/build/runtime-cjs/cache/storage.d.ts +1 -1
  37. package/build/runtime-cjs/cache/storage.js +16 -3
  38. package/build/runtime-cjs/client/index.d.ts +1 -0
  39. package/build/runtime-cjs/client/index.js +1 -0
  40. package/build/runtime-cjs/index.d.ts +1 -1
  41. package/build/runtime-cjs/lib/config.d.ts +9 -0
  42. package/build/runtime-cjs/lib/index.d.ts +1 -0
  43. package/build/runtime-cjs/lib/index.js +1 -0
  44. package/build/runtime-cjs/lib/types.d.ts +18 -1
  45. package/build/runtime-cjs/public/cache.js +3 -2
  46. package/build/runtime-cjs/router/server.d.ts +3 -1
  47. package/build/runtime-cjs/router/server.js +5 -2
  48. package/build/runtime-cjs/router/session.js +9 -6
  49. package/build/runtime-cjs/router/types.d.ts +1 -0
  50. package/build/runtime-esm/cache/cache.d.ts +24 -3
  51. package/build/runtime-esm/cache/cache.js +76 -8
  52. package/build/runtime-esm/cache/storage.d.ts +1 -1
  53. package/build/runtime-esm/cache/storage.js +16 -3
  54. package/build/runtime-esm/client/index.d.ts +1 -0
  55. package/build/runtime-esm/client/index.js +1 -0
  56. package/build/runtime-esm/index.d.ts +1 -1
  57. package/build/runtime-esm/lib/config.d.ts +9 -0
  58. package/build/runtime-esm/lib/index.d.ts +1 -0
  59. package/build/runtime-esm/lib/index.js +1 -0
  60. package/build/runtime-esm/lib/types.d.ts +18 -1
  61. package/build/runtime-esm/public/cache.js +3 -2
  62. package/build/runtime-esm/router/server.d.ts +3 -1
  63. package/build/runtime-esm/router/server.js +5 -2
  64. package/build/runtime-esm/router/session.js +9 -6
  65. package/build/runtime-esm/router/types.d.ts +1 -0
  66. package/build/test-cjs/index.js +3556 -1373
  67. package/build/test-esm/index.js +3556 -1373
  68. package/build/vite/schema.d.ts +4 -1
  69. package/build/vite-cjs/index.js +4543 -2823
  70. package/build/vite-esm/index.js +4540 -2822
  71. 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
- if (redirectTo) {
37
- const response = Response.redirect(redirectTo, 302);
38
- await set_session(args, response, session);
39
- return response;
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) {
@@ -16,6 +16,7 @@ export type RouterPageManifest<_ComponentType> = {
16
16
  default: QueryArtifact;
17
17
  }>;
18
18
  loading: boolean;
19
+ variables: string[];
19
20
  }>;
20
21
  component: () => Promise<{
21
22
  default: (props: any) => _ComponentType;
@@ -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
- constructor({ storage, subscriptions, lists, cache, lifetimes, staleManager, disabled, config, }: {
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({ disabled, ...config } = {}) {
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
- let { value } = this.storage.get(parent, key);
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
- const [layerValue, kind] = layer.get(id, field);
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: this.topLayer.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: {
@@ -17,6 +17,7 @@ class HoudiniClient {
17
17
  plugins;
18
18
  throwOnError_operations;
19
19
  proxies = {};
20
+ componentCache = {};
20
21
  constructor({
21
22
  url,
22
23
  fetchParams,
@@ -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): _Payload;
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;
@@ -7,3 +7,4 @@ export * from './types';
7
7
  export * from './store';
8
8
  export * from './key';
9
9
  export * from './lru';
10
+ export * from './selection';
@@ -7,3 +7,4 @@ export * from "./types";
7
7
  export * from "./store";
8
8
  export * from "./key";
9
9
  export * from "./lru";
10
+ export * from "./selection";
@@ -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 setting acceptImperativeInstability to true in your config file.`);
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
- if (redirectTo) {
13
- const response = Response.redirect(redirectTo, 302);
14
- await set_session(args, response, session);
15
- return response;
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) {
@@ -16,6 +16,7 @@ export type RouterPageManifest<_ComponentType> = {
16
16
  default: QueryArtifact;
17
17
  }>;
18
18
  loading: boolean;
19
+ variables: string[];
19
20
  }>;
20
21
  component: () => Promise<{
21
22
  default: (props: any) => _ComponentType;