houdini 1.0.0-next.4 → 1.0.0-next.5

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 (78) hide show
  1. package/build/cmd-cjs/index.js +1217 -1021
  2. package/build/cmd-esm/index.js +1217 -1021
  3. package/build/codegen/generators/artifacts/utils.d.ts +0 -1
  4. package/build/codegen-cjs/index.js +810 -676
  5. package/build/codegen-esm/index.js +810 -676
  6. package/build/lib/config.d.ts +10 -90
  7. package/build/lib/deepMerge.d.ts +1 -0
  8. package/build/lib/graphql.d.ts +5 -2
  9. package/build/lib/index.d.ts +2 -0
  10. package/build/lib/pipeline.d.ts +1 -1
  11. package/build/lib/plugin.d.ts +2 -0
  12. package/build/lib/types.d.ts +250 -2
  13. package/build/lib-cjs/index.js +351 -162
  14. package/build/lib-esm/index.js +349 -162
  15. package/build/runtime/cache/cache.d.ts +20 -3
  16. package/build/runtime/cache/staleManager.d.ts +30 -0
  17. package/build/runtime/cache/subscription.d.ts +2 -1
  18. package/build/runtime/client/plugins/subscription.d.ts +1 -2
  19. package/build/runtime/lib/config.d.ts +4 -0
  20. package/build/runtime/lib/index.d.ts +1 -0
  21. package/build/runtime/lib/key.d.ts +6 -0
  22. package/build/runtime/lib/types.d.ts +2 -2
  23. package/build/runtime/public/cache.d.ts +8 -1
  24. package/build/runtime/public/record.d.ts +11 -1
  25. package/build/runtime/public/tests/test.d.ts +9 -10
  26. package/build/runtime-cjs/cache/cache.d.ts +20 -3
  27. package/build/runtime-cjs/cache/cache.js +65 -6
  28. package/build/runtime-cjs/cache/gc.js +9 -0
  29. package/build/runtime-cjs/cache/staleManager.d.ts +30 -0
  30. package/build/runtime-cjs/cache/staleManager.js +95 -0
  31. package/build/runtime-cjs/cache/subscription.d.ts +2 -1
  32. package/build/runtime-cjs/cache/subscription.js +6 -3
  33. package/build/runtime-cjs/client/documentStore.js +1 -0
  34. package/build/runtime-cjs/client/plugins/cache.js +5 -3
  35. package/build/runtime-cjs/client/plugins/fetch.js +1 -0
  36. package/build/runtime-cjs/client/plugins/query.js +1 -0
  37. package/build/runtime-cjs/client/plugins/subscription.d.ts +1 -2
  38. package/build/runtime-cjs/client/plugins/subscription.js +2 -0
  39. package/build/runtime-cjs/lib/config.d.ts +4 -0
  40. package/build/runtime-cjs/lib/index.d.ts +1 -0
  41. package/build/runtime-cjs/lib/index.js +1 -0
  42. package/build/runtime-cjs/lib/key.d.ts +6 -0
  43. package/build/runtime-cjs/lib/key.js +41 -0
  44. package/build/runtime-cjs/lib/types.d.ts +2 -2
  45. package/build/runtime-cjs/public/cache.d.ts +8 -1
  46. package/build/runtime-cjs/public/cache.js +3 -0
  47. package/build/runtime-cjs/public/record.d.ts +11 -1
  48. package/build/runtime-cjs/public/record.js +8 -1
  49. package/build/runtime-cjs/public/tests/test.d.ts +9 -10
  50. package/build/runtime-esm/cache/cache.d.ts +20 -3
  51. package/build/runtime-esm/cache/cache.js +66 -7
  52. package/build/runtime-esm/cache/gc.js +9 -0
  53. package/build/runtime-esm/cache/staleManager.d.ts +30 -0
  54. package/build/runtime-esm/cache/staleManager.js +71 -0
  55. package/build/runtime-esm/cache/subscription.d.ts +2 -1
  56. package/build/runtime-esm/cache/subscription.js +6 -3
  57. package/build/runtime-esm/client/documentStore.js +1 -0
  58. package/build/runtime-esm/client/plugins/cache.js +5 -3
  59. package/build/runtime-esm/client/plugins/fetch.js +1 -0
  60. package/build/runtime-esm/client/plugins/query.js +1 -0
  61. package/build/runtime-esm/client/plugins/subscription.d.ts +1 -2
  62. package/build/runtime-esm/client/plugins/subscription.js +2 -0
  63. package/build/runtime-esm/lib/config.d.ts +4 -0
  64. package/build/runtime-esm/lib/index.d.ts +1 -0
  65. package/build/runtime-esm/lib/index.js +1 -0
  66. package/build/runtime-esm/lib/key.d.ts +6 -0
  67. package/build/runtime-esm/lib/key.js +17 -0
  68. package/build/runtime-esm/lib/types.d.ts +2 -2
  69. package/build/runtime-esm/public/cache.d.ts +8 -1
  70. package/build/runtime-esm/public/cache.js +3 -0
  71. package/build/runtime-esm/public/record.d.ts +11 -1
  72. package/build/runtime-esm/public/record.js +8 -1
  73. package/build/runtime-esm/public/tests/test.d.ts +9 -10
  74. package/build/test-cjs/index.js +893 -747
  75. package/build/test-esm/index.js +893 -747
  76. package/build/vite-cjs/index.js +1195 -998
  77. package/build/vite-esm/index.js +1195 -998
  78. package/package.json +3 -2
@@ -1,9 +1,11 @@
1
- import { defaultConfigValues, computeID, keyFieldsForType } from "../lib/config";
1
+ import { computeKey } from "../lib";
2
+ import { computeID, defaultConfigValues, keyFieldsForType } from "../lib/config";
2
3
  import { deepEquals } from "../lib/deepEquals";
3
4
  import { getFieldsForType } from "../lib/selection";
4
5
  import { GarbageCollector } from "./gc";
5
6
  import { ListManager } from "./lists";
6
7
  import { SchemaManager } from "./schema";
8
+ import { StaleManager } from "./staleManager";
7
9
  import { InMemoryStorage } from "./storage";
8
10
  import { evaluateKey, flattenList } from "./stuff";
9
11
  import { InMemorySubscriptions } from "./subscription";
@@ -16,6 +18,7 @@ class Cache {
16
18
  subscriptions: new InMemorySubscriptions(this),
17
19
  lists: new ListManager(this, rootID),
18
20
  lifetimes: new GarbageCollector(this),
21
+ staleManager: new StaleManager(this),
19
22
  schema: new SchemaManager(this)
20
23
  });
21
24
  if (config) {
@@ -45,13 +48,14 @@ class Cache {
45
48
  return subscribers;
46
49
  }
47
50
  read(...args) {
48
- const { data, partial, hasData } = this._internal_unstable.getSelection(...args);
51
+ const { data, partial, stale, hasData } = this._internal_unstable.getSelection(...args);
49
52
  if (!hasData) {
50
- return { data: null, partial: false };
53
+ return { data: null, partial: false, stale: false };
51
54
  }
52
55
  return {
53
56
  data,
54
- partial
57
+ partial,
58
+ stale
55
59
  };
56
60
  }
57
61
  subscribe(spec, variables = {}) {
@@ -87,6 +91,30 @@ class Cache {
87
91
  setConfig(config) {
88
92
  this._internal_unstable.setConfig(config);
89
93
  }
94
+ markTypeStale(type, options = {}) {
95
+ if (!type) {
96
+ this._internal_unstable.staleManager.markAllStale();
97
+ } else if (!options.field) {
98
+ this._internal_unstable.staleManager.markTypeStale(type);
99
+ } else {
100
+ this._internal_unstable.staleManager.markTypeFieldStale(
101
+ type,
102
+ options.field,
103
+ options.when
104
+ );
105
+ }
106
+ }
107
+ markRecordStale(id, options) {
108
+ if (options.field) {
109
+ const key = computeKey({ field: options.field, args: options.when ?? {} });
110
+ this._internal_unstable.staleManager.markFieldStale(id, key);
111
+ } else {
112
+ this._internal_unstable.staleManager.markRecordStale(id);
113
+ }
114
+ }
115
+ getFieldTime(id, field) {
116
+ return this._internal_unstable.staleManager.getFieldTime(id, field);
117
+ }
90
118
  }
91
119
  class CacheInternal {
92
120
  _disabled = false;
@@ -102,6 +130,7 @@ class CacheInternal {
102
130
  lists;
103
131
  cache;
104
132
  lifetimes;
133
+ staleManager;
105
134
  schema;
106
135
  constructor({
107
136
  storage,
@@ -109,6 +138,7 @@ class CacheInternal {
109
138
  lists,
110
139
  cache,
111
140
  lifetimes,
141
+ staleManager,
112
142
  schema
113
143
  }) {
114
144
  this.storage = storage;
@@ -116,6 +146,7 @@ class CacheInternal {
116
146
  this.lists = lists;
117
147
  this.cache = cache;
118
148
  this.lifetimes = lifetimes;
149
+ this.staleManager = staleManager;
119
150
  this.schema = schema;
120
151
  this._disabled = typeof globalThis.window === "undefined";
121
152
  try {
@@ -136,7 +167,8 @@ class CacheInternal {
136
167
  applyUpdates,
137
168
  layer,
138
169
  toNotify = [],
139
- forceNotify
170
+ forceNotify,
171
+ forceStale
140
172
  }) {
141
173
  if (this._disabled) {
142
174
  return [];
@@ -171,6 +203,11 @@ class CacheInternal {
171
203
  const displayLayer = layer.isDisplayLayer(displayLayers);
172
204
  if (displayLayer) {
173
205
  this.lifetimes.resetLifetime(parent, key);
206
+ if (forceStale) {
207
+ this.staleManager.markFieldStale(parent, key);
208
+ } else {
209
+ this.staleManager.setFieldTimeToNow(parent, key);
210
+ }
174
211
  }
175
212
  if (!fieldSelection) {
176
213
  let newValue = value;
@@ -402,12 +439,13 @@ class CacheInternal {
402
439
  stepsFromConnection = null
403
440
  }) {
404
441
  if (parent === null) {
405
- return { data: null, partial: false, hasData: true };
442
+ return { data: null, partial: false, stale: false, hasData: true };
406
443
  }
407
444
  const target = {};
408
445
  let hasData = false;
409
446
  let partial = false;
410
447
  let cascadeNull = false;
448
+ let stale = false;
411
449
  const typename = this.storage.get(parent, "__typename").value;
412
450
  let targetSelection = getFieldsForType(selection, typename);
413
451
  for (const [
@@ -416,6 +454,10 @@ class CacheInternal {
416
454
  ] of Object.entries(targetSelection)) {
417
455
  const key = evaluateKey(keyRaw, variables);
418
456
  const { value } = this.storage.get(parent, key);
457
+ const dt_field = this.staleManager.getFieldTime(parent, key);
458
+ if (dt_field === null) {
459
+ stale = true;
460
+ }
419
461
  let nextStep = stepsFromConnection;
420
462
  if (nextStep !== null) {
421
463
  if (nextStep >= 2) {
@@ -455,6 +497,9 @@ class CacheInternal {
455
497
  if (listValue.partial) {
456
498
  partial = true;
457
499
  }
500
+ if (listValue.stale) {
501
+ stale = true;
502
+ }
458
503
  if (listValue.hasData || value.length === 0) {
459
504
  hasData = true;
460
505
  }
@@ -469,6 +514,9 @@ class CacheInternal {
469
514
  if (objectFields.partial) {
470
515
  partial = true;
471
516
  }
517
+ if (objectFields.stale) {
518
+ stale = true;
519
+ }
472
520
  if (objectFields.hasData) {
473
521
  hasData = true;
474
522
  }
@@ -480,6 +528,7 @@ class CacheInternal {
480
528
  return {
481
529
  data: cascadeNull ? null : target,
482
530
  partial: hasData && partial,
531
+ stale: hasData && stale,
483
532
  hasData
484
533
  };
485
534
  }
@@ -507,6 +556,7 @@ class CacheInternal {
507
556
  }) {
508
557
  const result = [];
509
558
  let partialData = false;
559
+ let stale = false;
510
560
  let hasValues = false;
511
561
  for (const entry of linkedList) {
512
562
  if (Array.isArray(entry)) {
@@ -526,7 +576,12 @@ class CacheInternal {
526
576
  result.push(entry);
527
577
  continue;
528
578
  }
529
- const { data, partial, hasData } = this.getSelection({
579
+ const {
580
+ data,
581
+ partial,
582
+ stale: local_stale,
583
+ hasData
584
+ } = this.getSelection({
530
585
  parent: entry,
531
586
  selection: fields,
532
587
  variables,
@@ -536,6 +591,9 @@ class CacheInternal {
536
591
  if (partial) {
537
592
  partialData = true;
538
593
  }
594
+ if (local_stale) {
595
+ stale = true;
596
+ }
539
597
  if (hasData) {
540
598
  hasValues = true;
541
599
  }
@@ -543,6 +601,7 @@ class CacheInternal {
543
601
  return {
544
602
  data: result,
545
603
  partial: partialData,
604
+ stale,
546
605
  hasData: hasValues
547
606
  };
548
607
  }
@@ -14,6 +14,8 @@ class GarbageCollector {
14
14
  this.lifetimes.get(id).set(field, 0);
15
15
  }
16
16
  tick() {
17
+ const dt_tick = Date.now().valueOf();
18
+ const config_max_time = this.cache._internal_unstable.config.defaultLifetime;
17
19
  for (const [id, fieldMap] of this.lifetimes.entries()) {
18
20
  for (const [field, lifetime] of fieldMap.entries()) {
19
21
  if (this.cache._internal_unstable.subscriptions.get(id, field).length > 0) {
@@ -27,6 +29,13 @@ class GarbageCollector {
27
29
  if ([...fieldMap.keys()].length === 0) {
28
30
  this.lifetimes.delete(id);
29
31
  }
32
+ this.cache._internal_unstable.staleManager.delete(id, field);
33
+ }
34
+ if (config_max_time && config_max_time > 0) {
35
+ const dt_valueOf = this.cache.getFieldTime(id, field);
36
+ if (dt_valueOf && dt_tick - dt_valueOf > config_max_time) {
37
+ this.cache._internal_unstable.staleManager.markFieldStale(id, field);
38
+ }
30
39
  }
31
40
  }
32
41
  }
@@ -0,0 +1,30 @@
1
+ import type { Cache } from './cache';
2
+ export declare class StaleManager {
3
+ #private;
4
+ cache: Cache;
5
+ private fieldsTime;
6
+ constructor(cache: Cache);
7
+ /**
8
+ * get the FieldTime info
9
+ * @param id User:1
10
+ * @param field firstName
11
+ */
12
+ getFieldTime(id: string, field: string): number | undefined | null;
13
+ /**
14
+ * set the date to a field
15
+ * @param id User:1
16
+ * @param field firstName
17
+ */
18
+ setFieldTimeToNow(id: string, field: string): void;
19
+ /**
20
+ * set null to a field (stale)
21
+ * @param id User:1
22
+ * @param field firstName
23
+ */
24
+ markFieldStale(id: string, field: string): void;
25
+ markAllStale(): void;
26
+ markRecordStale(id: string): void;
27
+ markTypeStale(type: string): void;
28
+ markTypeFieldStale(type: string, field: string, when?: {}): void;
29
+ delete(id: string, field: string): void;
30
+ }
@@ -0,0 +1,71 @@
1
+ import { computeKey } from "../lib";
2
+ class StaleManager {
3
+ cache;
4
+ fieldsTime = /* @__PURE__ */ new Map();
5
+ constructor(cache) {
6
+ this.cache = cache;
7
+ }
8
+ #initMapId = (id) => {
9
+ if (!this.fieldsTime.get(id)) {
10
+ this.fieldsTime.set(id, /* @__PURE__ */ new Map());
11
+ }
12
+ };
13
+ getFieldTime(id, field) {
14
+ return this.fieldsTime.get(id)?.get(field);
15
+ }
16
+ setFieldTimeToNow(id, field) {
17
+ this.#initMapId(id);
18
+ this.fieldsTime.get(id)?.set(field, new Date().valueOf());
19
+ }
20
+ markFieldStale(id, field) {
21
+ this.#initMapId(id);
22
+ this.fieldsTime.get(id)?.set(field, null);
23
+ }
24
+ markAllStale() {
25
+ for (const [id, fieldMap] of this.fieldsTime.entries()) {
26
+ for (const [field] of fieldMap.entries()) {
27
+ this.markFieldStale(id, field);
28
+ }
29
+ }
30
+ }
31
+ markRecordStale(id) {
32
+ const fieldsTimeOfType = this.fieldsTime.get(id);
33
+ if (fieldsTimeOfType) {
34
+ for (const [field] of fieldsTimeOfType.entries()) {
35
+ this.markFieldStale(id, field);
36
+ }
37
+ }
38
+ }
39
+ markTypeStale(type) {
40
+ for (const [id, fieldMap] of this.fieldsTime.entries()) {
41
+ if (id.startsWith(`${type}:`)) {
42
+ for (const [field] of fieldMap.entries()) {
43
+ this.markFieldStale(id, field);
44
+ }
45
+ }
46
+ }
47
+ }
48
+ markTypeFieldStale(type, field, when) {
49
+ const key = computeKey({ field, args: when });
50
+ for (const [id, fieldMap] of this.fieldsTime.entries()) {
51
+ if (id.startsWith(`${type}:`)) {
52
+ for (const local_field of fieldMap.keys()) {
53
+ if (local_field === key) {
54
+ this.markFieldStale(id, field);
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ delete(id, field) {
61
+ if (this.fieldsTime.has(id)) {
62
+ this.fieldsTime.get(id)?.delete(field);
63
+ if (this.fieldsTime.get(id)?.size === 0) {
64
+ this.fieldsTime.delete(id);
65
+ }
66
+ }
67
+ }
68
+ }
69
+ export {
70
+ StaleManager
71
+ };
@@ -19,10 +19,11 @@ export declare class InMemorySubscriptions {
19
19
  [key: string]: GraphQLValue;
20
20
  };
21
21
  }): void;
22
- addFieldSubscription({ id, key, selection, }: {
22
+ addFieldSubscription({ id, key, selection, type, }: {
23
23
  id: string;
24
24
  key: string;
25
25
  selection: FieldSelection;
26
+ type: string;
26
27
  }): void;
27
28
  registerList({ list, id, key, parentType, selection, filters, variables, }: {
28
29
  list: Required<Required<SubscriptionSelection>['fields'][string]>['list'];
@@ -28,7 +28,8 @@ class InMemorySubscriptions {
28
28
  this.addFieldSubscription({
29
29
  id: parent,
30
30
  key,
31
- selection: [spec, targetSelection2]
31
+ selection: [spec, targetSelection2],
32
+ type
32
33
  });
33
34
  if (list) {
34
35
  this.registerList({
@@ -65,7 +66,8 @@ class InMemorySubscriptions {
65
66
  addFieldSubscription({
66
67
  id,
67
68
  key,
68
- selection
69
+ selection,
70
+ type
69
71
  }) {
70
72
  const spec = selection[0];
71
73
  if (!this.subscribers[id]) {
@@ -137,7 +139,8 @@ class InMemorySubscriptions {
137
139
  this.addFieldSubscription({
138
140
  id: parent,
139
141
  key,
140
- selection: [spec, fieldSelection]
142
+ selection: [spec, fieldSelection],
143
+ type: linkedType
141
144
  });
142
145
  if (list) {
143
146
  this.registerList({
@@ -31,6 +31,7 @@ class DocumentStore extends Writable {
31
31
  data: initialValue ?? null,
32
32
  errors: null,
33
33
  partial: false,
34
+ stale: false,
34
35
  source: null,
35
36
  fetching,
36
37
  variables: null
@@ -23,7 +23,8 @@ const cachePolicyPlugin = ({
23
23
  data: value.data,
24
24
  errors: null,
25
25
  source: DataSource.Cache,
26
- partial: value.partial
26
+ partial: value.partial,
27
+ stale: value.stale
27
28
  });
28
29
  }
29
30
  useCache = !!(value.data !== null && allowed);
@@ -34,10 +35,11 @@ const cachePolicyPlugin = ({
34
35
  data: value.data,
35
36
  errors: null,
36
37
  source: DataSource.Cache,
37
- partial: value.partial
38
+ partial: value.partial,
39
+ stale: value.stale
38
40
  });
39
41
  }
40
- if (useCache && !value.partial) {
42
+ if (useCache && !value.partial && !value.stale) {
41
43
  return;
42
44
  }
43
45
  }
@@ -32,6 +32,7 @@ const fetchPlugin = (target) => {
32
32
  data: result.data,
33
33
  errors: !result.errors || result.errors.length === 0 ? null : result.errors,
34
34
  partial: false,
35
+ stale: false,
35
36
  source: DataSource.Network
36
37
  });
37
38
  }
@@ -30,6 +30,7 @@ const queryPlugin = documentPlugin(ArtifactKind.Query, function() {
30
30
  errors: null,
31
31
  fetching: false,
32
32
  partial: false,
33
+ stale: false,
33
34
  source: DataSource.Cache,
34
35
  variables: ctx.variables ?? null
35
36
  });
@@ -1,4 +1,3 @@
1
- import type { GraphQLObject } from '../../lib/types';
2
1
  import type { ClientPluginContext } from '../documentStore';
3
2
  export declare function subscriptionPlugin(factory: SubscriptionHandler): import("../documentStore").ClientPlugin;
4
3
  export type SubscriptionHandler = (ctx: ClientPluginContext) => {
@@ -7,7 +6,7 @@ export type SubscriptionHandler = (ctx: ClientPluginContext) => {
7
6
  variables?: {};
8
7
  }, handlers: {
9
8
  next: (payload: {
10
- data?: GraphQLObject;
9
+ data?: {} | null;
11
10
  errors?: readonly {
12
11
  message: string;
13
12
  }[];
@@ -43,6 +43,7 @@ function subscriptionPlugin(factory) {
43
43
  errors: [...errors ?? []],
44
44
  fetching: false,
45
45
  partial: true,
46
+ stale: false,
46
47
  source: DataSource.Network,
47
48
  variables: ctx.variables ?? null
48
49
  });
@@ -51,6 +52,7 @@ function subscriptionPlugin(factory) {
51
52
  clearSubscription?.();
52
53
  resolve(ctx, {
53
54
  partial: true,
55
+ stale: false,
54
56
  source: DataSource.Network,
55
57
  data: null,
56
58
  errors: [data],
@@ -55,6 +55,10 @@ export type ConfigFile = {
55
55
  * Specifies whether or not the cache should always use partial data. For more information: https://www.houdinigraphql.com/guides/caching-data#partial-data
56
56
  */
57
57
  defaultPartial?: boolean;
58
+ /**
59
+ * Specifies after how long a data goes stale in miliseconds. (default: `undefined`)
60
+ */
61
+ defaultLifetime?: number;
58
62
  /**
59
63
  * Specifies whether mutations should append or prepend list. For more information: https://www.houdinigraphql.com/api/graphql (default: `append`)
60
64
  */
@@ -5,3 +5,4 @@ export * from './log';
5
5
  export * from './scalars';
6
6
  export * from './types';
7
7
  export * from './store';
8
+ export * from './key';
@@ -5,3 +5,4 @@ export * from "./log";
5
5
  export * from "./scalars";
6
6
  export * from "./types";
7
7
  export * from "./store";
8
+ export * from "./key";
@@ -0,0 +1,6 @@
1
+ export declare const computeKey: ({ field, args }: {
2
+ field: string;
3
+ args?: {
4
+ [key: string]: any;
5
+ } | undefined;
6
+ }) => string;
@@ -0,0 +1,17 @@
1
+ const computeKey = ({ field, args }) => {
2
+ const keys = Object.keys(args ?? {});
3
+ keys.sort();
4
+ return args && keys.length > 0 ? `${field}(${keys.map((key) => `${key}: ${stringifyObjectWithNoQuotesOnKeys(args[key])}`).join(", ")})` : field;
5
+ };
6
+ const stringifyObjectWithNoQuotesOnKeys = (obj_from_json) => {
7
+ if (Array.isArray(obj_from_json)) {
8
+ return `[${obj_from_json.map((obj) => `${stringifyObjectWithNoQuotesOnKeys(obj)}`).join(", ")}]`;
9
+ }
10
+ if (typeof obj_from_json !== "object" || obj_from_json instanceof Date || obj_from_json === null) {
11
+ return JSON.stringify(obj_from_json).replace(/"([^"]+)":/g, "$1: ");
12
+ }
13
+ return `{${Object.keys(obj_from_json).map((key) => `${key}: ${stringifyObjectWithNoQuotesOnKeys(obj_from_json[key])}`).join(", ")}}`;
14
+ };
15
+ export {
16
+ computeKey
17
+ };
@@ -80,7 +80,7 @@ export type BaseCompiledDocument = {
80
80
  paginated: boolean;
81
81
  direction: 'forward' | 'backward' | 'both';
82
82
  };
83
- pluginsData?: Record<string, any>;
83
+ plugin_data?: Record<string, any>;
84
84
  };
85
85
  export type HoudiniFetchContext = {
86
86
  variables: () => {};
@@ -164,7 +164,6 @@ export type SubscriptionSpec = {
164
164
  export type FetchQueryResult<_Data> = {
165
165
  result: RequestPayload<_Data | null>;
166
166
  source: DataSource | null;
167
- partial: boolean;
168
167
  };
169
168
  export type QueryResult<_Data = GraphQLObject, _Input = Record<string, any>> = {
170
169
  data: _Data | null;
@@ -173,6 +172,7 @@ export type QueryResult<_Data = GraphQLObject, _Input = Record<string, any>> = {
173
172
  }[] | null;
174
173
  fetching: boolean;
175
174
  partial: boolean;
175
+ stale: boolean;
176
176
  source: DataSource | null;
177
177
  variables: _Input | null;
178
178
  };
@@ -2,7 +2,7 @@ import type { Cache as _Cache } from '../cache/cache';
2
2
  import { type QueryArtifact } from '../lib';
3
3
  import { ListCollection } from './list';
4
4
  import { Record } from './record';
5
- import type { CacheTypeDef, IDFields, QueryInput, QueryList, QueryValue, TypeNames, ValidLists } from './types';
5
+ import type { ArgType, CacheTypeDef, IDFields, QueryInput, QueryList, QueryValue, TypeFieldNames, TypeNames, ValidLists } from './types';
6
6
  export declare class Cache<Def extends CacheTypeDef> {
7
7
  _internal_unstable: _Cache;
8
8
  constructor(cache: _Cache);
@@ -29,4 +29,11 @@ export declare class Cache<Def extends CacheTypeDef> {
29
29
  data: QueryValue<QueryList<Def>, _Query>;
30
30
  variables?: QueryInput<QueryList<Def>, _Query>;
31
31
  }): void;
32
+ /**
33
+ * Mark some elements of the cache stale.
34
+ */
35
+ markStale<_Type extends TypeNames<Def>, _Field extends TypeFieldNames<Def, _Type>>(type?: _Type, options?: {
36
+ field?: _Field;
37
+ when?: ArgType<Def, _Type, _Field>;
38
+ }): void;
32
39
  }
@@ -64,6 +64,9 @@ Please acknowledge this by setting acceptImperativeInstability to true in your c
64
64
  });
65
65
  return;
66
66
  }
67
+ markStale(type, options = {}) {
68
+ return this._internal_unstable.markTypeStale(type, options);
69
+ }
67
70
  }
68
71
  export {
69
72
  Cache
@@ -1,6 +1,6 @@
1
1
  import type { FragmentArtifact } from '../lib/types';
2
2
  import type { Cache } from './cache';
3
- import type { CacheTypeDef, FragmentList, FragmentValue, FragmentVariables, ValidTypes } from './types';
3
+ import type { ArgType, CacheTypeDef, FragmentList, FragmentValue, FragmentVariables, TypeFieldNames, ValidTypes } from './types';
4
4
  export declare class Record<Def extends CacheTypeDef, Type extends ValidTypes<Def>> {
5
5
  #private;
6
6
  type: string;
@@ -26,6 +26,16 @@ export declare class Record<Def extends CacheTypeDef, Type extends ValidTypes<De
26
26
  fragment: _Fragment;
27
27
  data: FragmentValue<FragmentList<Def, Type>, _Fragment>;
28
28
  variables?: FragmentVariables<FragmentList<Def, Type>, _Fragment>;
29
+ forceStale?: boolean;
29
30
  }): void;
30
31
  delete(): void;
32
+ /**
33
+ * Mark some elements of the record stale in the cache.
34
+ * @param field
35
+ * @param when
36
+ */
37
+ markStale<Field extends TypeFieldNames<Def, Type>>({ field, when, }?: {
38
+ field?: Field;
39
+ when?: ArgType<Def, Type, Field>;
40
+ }): void;
31
41
  }
@@ -47,12 +47,19 @@ class Record {
47
47
  config: this.#cache.config,
48
48
  artifact: args.fragment.artifact,
49
49
  input: args.variables
50
- }) ?? void 0
50
+ }) ?? void 0,
51
+ forceStale: args.forceStale
51
52
  });
52
53
  }
53
54
  delete() {
54
55
  this.#cache._internal_unstable.delete(this.#id);
55
56
  }
57
+ markStale({
58
+ field,
59
+ when
60
+ } = {}) {
61
+ this.#cache._internal_unstable.markRecordStale(this.#id, { field, when });
62
+ }
56
63
  }
57
64
  export {
58
65
  Record
@@ -1,7 +1,7 @@
1
1
  import { type SubscriptionSelection, type FragmentArtifact, type QueryArtifact } from '../../lib';
2
2
  import { Cache } from '../cache';
3
3
  import type { Record } from '../record';
4
- type CacheTypeDef = {
4
+ export type CacheTypeDefTest = {
5
5
  types: {
6
6
  __ROOT__: {
7
7
  idFields: {};
@@ -16,23 +16,23 @@ type CacheTypeDef = {
16
16
  args: never;
17
17
  };
18
18
  viewer: {
19
- type: Record<CacheTypeDef, 'User'> | null;
19
+ type: Record<CacheTypeDefTest, 'User'> | null;
20
20
  args: never;
21
21
  };
22
22
  pets: {
23
- type: (Record<CacheTypeDef, 'Cat'> | Record<CacheTypeDef, 'User'>)[];
23
+ type: (Record<CacheTypeDefTest, 'Cat'> | Record<CacheTypeDefTest, 'User'>)[];
24
24
  args: never;
25
25
  };
26
26
  listOfLists: {
27
- type: ((Record<CacheTypeDef, 'Cat'> | Record<CacheTypeDef, 'User'> | null | (null | Record<CacheTypeDef, 'User'>)[])[] | Record<CacheTypeDef, 'Cat'> | Record<CacheTypeDef, 'User'> | null)[];
27
+ type: ((Record<CacheTypeDefTest, 'Cat'> | Record<CacheTypeDefTest, 'User'> | null | (null | Record<CacheTypeDefTest, 'User'>)[])[] | Record<CacheTypeDefTest, 'Cat'> | Record<CacheTypeDefTest, 'User'> | null)[];
28
28
  args: never;
29
29
  };
30
30
  users: {
31
- type: Record<CacheTypeDef, 'User'>[] | null;
31
+ type: Record<CacheTypeDefTest, 'User'>[] | null;
32
32
  args: never;
33
33
  };
34
34
  pet: {
35
- type: Record<CacheTypeDef, 'Cat'> | Record<CacheTypeDef, 'User'>;
35
+ type: Record<CacheTypeDefTest, 'Cat'> | Record<CacheTypeDefTest, 'User'>;
36
36
  args: never;
37
37
  };
38
38
  };
@@ -60,7 +60,7 @@ type CacheTypeDef = {
60
60
  args: never;
61
61
  };
62
62
  parent: {
63
- type: Record<CacheTypeDef, 'User'>;
63
+ type: Record<CacheTypeDefTest, 'User'>;
64
64
  args: never;
65
65
  };
66
66
  id: {
@@ -84,7 +84,7 @@ type CacheTypeDef = {
84
84
  args: never;
85
85
  };
86
86
  parent: {
87
- type: Record<CacheTypeDef, 'User'> | null;
87
+ type: Record<CacheTypeDefTest, 'User'> | null;
88
88
  args: never;
89
89
  };
90
90
  id: {
@@ -147,11 +147,10 @@ type CacheTypeDef = {
147
147
  };
148
148
  };
149
149
  };
150
- export declare const testCache: () => Cache<CacheTypeDef>;
150
+ export declare const testCache: () => Cache<CacheTypeDefTest>;
151
151
  export declare const testFragment: (selection: SubscriptionSelection) => {
152
152
  artifact: FragmentArtifact;
153
153
  };
154
154
  export declare const testQuery: (selection: SubscriptionSelection) => {
155
155
  artifact: QueryArtifact;
156
156
  };
157
- export {};