houdini 1.2.2 → 1.2.4
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/cmd-cjs/index.js +183 -63
- package/build/cmd-esm/index.js +183 -63
- package/build/codegen-cjs/index.js +181 -61
- package/build/codegen-esm/index.js +181 -61
- package/build/lib/fs.d.ts +8 -1
- package/build/lib/index.d.ts +1 -0
- package/build/lib/parse.d.ts +1 -1
- package/build/lib/types.d.ts +11 -0
- package/build/lib-cjs/index.js +181 -69
- package/build/lib-esm/index.js +179 -69
- package/build/runtime/cache/cache.d.ts +5 -1
- package/build/runtime/cache/lists.d.ts +3 -3
- package/build/runtime/cache/storage.d.ts +8 -2
- package/build/runtime/cache/subscription.d.ts +1 -0
- package/build/runtime/client/documentStore.d.ts +9 -2
- package/build/runtime/client/index.d.ts +6 -3
- package/build/runtime/lib/index.d.ts +1 -0
- package/build/runtime/lib/lru.d.ts +52 -0
- package/build/runtime/lib/types.d.ts +1 -0
- package/build/runtime-cjs/cache/cache.d.ts +5 -1
- package/build/runtime-cjs/cache/cache.js +84 -27
- package/build/runtime-cjs/cache/lists.d.ts +3 -3
- package/build/runtime-cjs/cache/lists.js +20 -8
- package/build/runtime-cjs/cache/storage.d.ts +8 -2
- package/build/runtime-cjs/cache/storage.js +22 -5
- package/build/runtime-cjs/cache/subscription.d.ts +1 -0
- package/build/runtime-cjs/cache/subscription.js +3 -0
- package/build/runtime-cjs/client/documentStore.d.ts +9 -2
- package/build/runtime-cjs/client/documentStore.js +13 -9
- package/build/runtime-cjs/client/index.d.ts +6 -3
- package/build/runtime-cjs/client/index.js +6 -8
- package/build/runtime-cjs/client/plugins/cache.js +3 -0
- package/build/runtime-cjs/client/plugins/mutation.js +10 -6
- package/build/runtime-cjs/lib/index.d.ts +1 -0
- package/build/runtime-cjs/lib/index.js +1 -0
- package/build/runtime-cjs/lib/lru.d.ts +52 -0
- package/build/runtime-cjs/lib/lru.js +73 -0
- package/build/runtime-cjs/lib/types.d.ts +1 -0
- package/build/runtime-cjs/lib/types.js +7 -2
- package/build/runtime-esm/cache/cache.d.ts +5 -1
- package/build/runtime-esm/cache/cache.js +84 -27
- package/build/runtime-esm/cache/lists.d.ts +3 -3
- package/build/runtime-esm/cache/lists.js +20 -8
- package/build/runtime-esm/cache/storage.d.ts +8 -2
- package/build/runtime-esm/cache/storage.js +22 -5
- package/build/runtime-esm/cache/subscription.d.ts +1 -0
- package/build/runtime-esm/cache/subscription.js +3 -0
- package/build/runtime-esm/client/documentStore.d.ts +9 -2
- package/build/runtime-esm/client/documentStore.js +13 -9
- package/build/runtime-esm/client/index.d.ts +6 -3
- package/build/runtime-esm/client/index.js +6 -8
- package/build/runtime-esm/client/plugins/cache.js +3 -0
- package/build/runtime-esm/client/plugins/mutation.js +10 -6
- package/build/runtime-esm/lib/index.d.ts +1 -0
- package/build/runtime-esm/lib/index.js +1 -0
- package/build/runtime-esm/lib/lru.d.ts +52 -0
- package/build/runtime-esm/lib/lru.js +48 -0
- package/build/runtime-esm/lib/types.d.ts +1 -0
- package/build/runtime-esm/lib/types.js +5 -1
- package/build/test-cjs/index.js +181 -61
- package/build/test-esm/index.js +181 -61
- package/build/vite-cjs/index.js +200 -62
- package/build/vite-esm/index.js +200 -62
- package/package.json +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is a copy and paste of a very simple and effective LRU cache
|
|
3
|
+
* using javascript maps. It was copied under the MIT license found at the
|
|
4
|
+
* bottom of the page.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* JS maps (both plain objects and Map) maintain key insertion
|
|
8
|
+
* order, which means there is an easy way to simulate LRU behavior
|
|
9
|
+
* that should also perform quite well:
|
|
10
|
+
*
|
|
11
|
+
* To insert a new value, first delete the key from the inner _map,
|
|
12
|
+
* then _map.set(k, v). By deleting and reinserting, you ensure that the
|
|
13
|
+
* map sees the key as the last inserted key.
|
|
14
|
+
*
|
|
15
|
+
* Get does the same: if the key is present, delete and reinsert it.
|
|
16
|
+
*/
|
|
17
|
+
export declare class LRUCache<T> {
|
|
18
|
+
_capacity: number;
|
|
19
|
+
_map: Map<string, T>;
|
|
20
|
+
constructor(capacity?: number);
|
|
21
|
+
set(key: string, value: T): void;
|
|
22
|
+
get(key: string): T | null;
|
|
23
|
+
has(key: string): boolean;
|
|
24
|
+
delete(key: string): void;
|
|
25
|
+
size(): number;
|
|
26
|
+
capacity(): number;
|
|
27
|
+
clear(): void;
|
|
28
|
+
}
|
|
29
|
+
export declare function createLRUCache<T>(capacity?: number): LRUCache<T>;
|
|
30
|
+
/**
|
|
31
|
+
MIT License
|
|
32
|
+
|
|
33
|
+
Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
34
|
+
|
|
35
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
36
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
37
|
+
in the Software without restriction, including without limitation the rights
|
|
38
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
39
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
40
|
+
furnished to do so, subject to the following conditions:
|
|
41
|
+
|
|
42
|
+
The above copyright notice and this permission notice shall be included in all
|
|
43
|
+
copies or substantial portions of the Software.
|
|
44
|
+
|
|
45
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
46
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
47
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
48
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
49
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
50
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
51
|
+
SOFTWARE.
|
|
52
|
+
*/
|
|
@@ -8,6 +8,7 @@ import type { Layer, LayerID } from './storage';
|
|
|
8
8
|
import { InMemoryStorage } from './storage';
|
|
9
9
|
import { InMemorySubscriptions, type FieldSelection } from './subscription';
|
|
10
10
|
export declare class Cache {
|
|
11
|
+
#private;
|
|
11
12
|
_internal_unstable: CacheInternal;
|
|
12
13
|
constructor({ disabled, ...config }?: ConfigFile & {
|
|
13
14
|
disabled?: boolean;
|
|
@@ -33,7 +34,7 @@ export declare class Cache {
|
|
|
33
34
|
subscribe(spec: SubscriptionSpec, variables?: {}): void;
|
|
34
35
|
unsubscribe(spec: SubscriptionSpec, variables?: {}): void;
|
|
35
36
|
list(name: string, parentID?: string, allLists?: boolean): ListCollection;
|
|
36
|
-
delete(id: string): void;
|
|
37
|
+
delete(id: string, layer?: Layer): void;
|
|
37
38
|
setConfig(config: ConfigFile): void;
|
|
38
39
|
markTypeStale(options?: {
|
|
39
40
|
type: string;
|
|
@@ -46,6 +47,9 @@ export declare class Cache {
|
|
|
46
47
|
}): void;
|
|
47
48
|
getFieldTime(id: string, field: string): number | null | undefined;
|
|
48
49
|
config(): ConfigFile;
|
|
50
|
+
serialize(): string;
|
|
51
|
+
hydrate(...args: Parameters<InMemoryStorage['hydrate']>): void;
|
|
52
|
+
clearLayer(layerID: Layer['id']): void;
|
|
49
53
|
}
|
|
50
54
|
declare class CacheInternal {
|
|
51
55
|
private _disabled;
|
|
@@ -58,20 +58,7 @@ class Cache {
|
|
|
58
58
|
}) {
|
|
59
59
|
const layer = layerID ? this._internal_unstable.storage.getLayer(layerID) : this._internal_unstable.storage.topLayer;
|
|
60
60
|
const subscribers = this._internal_unstable.writeSelection({ ...args, layer }).map((sub) => sub[0]);
|
|
61
|
-
|
|
62
|
-
for (const spec of subscribers.concat(notifySubscribers)) {
|
|
63
|
-
if (!notified.includes(spec.set)) {
|
|
64
|
-
notified.push(spec.set);
|
|
65
|
-
spec.set(
|
|
66
|
-
this._internal_unstable.getSelection({
|
|
67
|
-
parent: spec.parentID || rootID,
|
|
68
|
-
selection: spec.selection,
|
|
69
|
-
variables: spec.variables?.() || {},
|
|
70
|
-
ignoreMasking: false
|
|
71
|
-
}).data
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
61
|
+
this.#notifySubscribers(subscribers.concat(notifySubscribers));
|
|
75
62
|
return subscribers;
|
|
76
63
|
}
|
|
77
64
|
read(...args) {
|
|
@@ -110,10 +97,10 @@ class Cache {
|
|
|
110
97
|
}
|
|
111
98
|
return handler;
|
|
112
99
|
}
|
|
113
|
-
delete(id) {
|
|
100
|
+
delete(id, layer) {
|
|
114
101
|
this._internal_unstable.subscriptions.removeAllSubscribers(id);
|
|
115
|
-
this._internal_unstable.lists.removeIDFromAllLists(id);
|
|
116
|
-
this._internal_unstable.storage.delete(id);
|
|
102
|
+
this._internal_unstable.lists.removeIDFromAllLists(id, layer);
|
|
103
|
+
this._internal_unstable.storage.delete(id, layer);
|
|
117
104
|
}
|
|
118
105
|
setConfig(config) {
|
|
119
106
|
this._internal_unstable.setConfig(config);
|
|
@@ -145,6 +132,76 @@ class Cache {
|
|
|
145
132
|
config() {
|
|
146
133
|
return this._internal_unstable.config;
|
|
147
134
|
}
|
|
135
|
+
serialize() {
|
|
136
|
+
return this._internal_unstable.storage.serialize();
|
|
137
|
+
}
|
|
138
|
+
hydrate(...args) {
|
|
139
|
+
return this._internal_unstable.storage.hydrate(...args);
|
|
140
|
+
}
|
|
141
|
+
clearLayer(layerID) {
|
|
142
|
+
const layer = this._internal_unstable.storage.getLayer(layerID);
|
|
143
|
+
if (!layer) {
|
|
144
|
+
throw new Error("Cannot find layer with id: " + layerID);
|
|
145
|
+
}
|
|
146
|
+
const toNotify = [];
|
|
147
|
+
const allFields = [];
|
|
148
|
+
for (const target of [layer.fields, layer.links]) {
|
|
149
|
+
for (const [id, fields] of Object.entries(target)) {
|
|
150
|
+
allFields.push(
|
|
151
|
+
...Object.entries(fields).map(([field, value]) => ({ id, field, value }))
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const displayFields = [];
|
|
156
|
+
for (const pair of allFields) {
|
|
157
|
+
const { displayLayers } = this._internal_unstable.storage.get(pair.id, pair.field);
|
|
158
|
+
if (!displayLayers.includes(layerID)) {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
displayFields.push(pair);
|
|
162
|
+
}
|
|
163
|
+
for (const [id, operation] of Object.entries(layer.operations)) {
|
|
164
|
+
if (operation.deleted) {
|
|
165
|
+
displayFields.push(
|
|
166
|
+
...this._internal_unstable.subscriptions.activeFields(id).map((field) => ({ id, field }))
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
const fields = Object.keys(operation.fields ?? {});
|
|
170
|
+
if (fields.length > 0) {
|
|
171
|
+
displayFields.push(...fields.map((field) => ({ id, field })));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
layer.clear();
|
|
175
|
+
for (const display of displayFields) {
|
|
176
|
+
const { field, id } = display;
|
|
177
|
+
const notify = !("value" in display) || this._internal_unstable.storage.get(id, field).value !== display.value;
|
|
178
|
+
if (notify) {
|
|
179
|
+
toNotify.push(
|
|
180
|
+
...this._internal_unstable.subscriptions.get(id, field).map((sub) => sub[0])
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
this.#notifySubscribers(toNotify);
|
|
185
|
+
}
|
|
186
|
+
#notifySubscribers(subs) {
|
|
187
|
+
if (subs.length === 0) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const notified = [];
|
|
191
|
+
for (const spec of subs) {
|
|
192
|
+
if (!notified.includes(spec.set)) {
|
|
193
|
+
notified.push(spec.set);
|
|
194
|
+
spec.set(
|
|
195
|
+
this._internal_unstable.getSelection({
|
|
196
|
+
parent: spec.parentID || rootID,
|
|
197
|
+
selection: spec.selection,
|
|
198
|
+
variables: spec.variables?.() || {},
|
|
199
|
+
ignoreMasking: false
|
|
200
|
+
}).data
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
148
205
|
}
|
|
149
206
|
class CacheInternal {
|
|
150
207
|
_disabled = false;
|
|
@@ -432,8 +489,16 @@ class CacheInternal {
|
|
|
432
489
|
operation.position || "last",
|
|
433
490
|
layer
|
|
434
491
|
);
|
|
492
|
+
} else if (operation.action === "toggle" && target instanceof Object && fieldSelection && operation.list) {
|
|
493
|
+
this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).toggleElement({
|
|
494
|
+
selection: fieldSelection,
|
|
495
|
+
data: target,
|
|
496
|
+
variables,
|
|
497
|
+
where: operation.position || "last",
|
|
498
|
+
layer
|
|
499
|
+
});
|
|
435
500
|
} else if (operation.action === "remove" && target instanceof Object && fieldSelection && operation.list) {
|
|
436
|
-
this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).remove(target, variables);
|
|
501
|
+
this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).remove(target, variables, layer);
|
|
437
502
|
} else if (operation.action === "delete" && operation.type) {
|
|
438
503
|
if (typeof target !== "string") {
|
|
439
504
|
throw new Error("Cannot delete a record with a non-string ID");
|
|
@@ -442,15 +507,7 @@ class CacheInternal {
|
|
|
442
507
|
if (!targetID) {
|
|
443
508
|
continue;
|
|
444
509
|
}
|
|
445
|
-
this.cache.delete(targetID);
|
|
446
|
-
} else if (operation.action === "toggle" && target instanceof Object && fieldSelection && operation.list) {
|
|
447
|
-
this.cache.list(operation.list, parentID, operation.target === "all").when(operation.when).toggleElement({
|
|
448
|
-
selection: fieldSelection,
|
|
449
|
-
data: target,
|
|
450
|
-
variables,
|
|
451
|
-
where: operation.position || "last",
|
|
452
|
-
layer
|
|
453
|
-
});
|
|
510
|
+
this.cache.delete(targetID, layer);
|
|
454
511
|
}
|
|
455
512
|
}
|
|
456
513
|
}
|
|
@@ -21,7 +21,7 @@ export declare class ListManager {
|
|
|
21
21
|
filters?: List['filters'];
|
|
22
22
|
abstract?: boolean;
|
|
23
23
|
}): void;
|
|
24
|
-
removeIDFromAllLists(id: string): void;
|
|
24
|
+
removeIDFromAllLists(id: string, layer?: Layer): void;
|
|
25
25
|
deleteField(parentID: string, field: string): void;
|
|
26
26
|
}
|
|
27
27
|
export declare class List {
|
|
@@ -54,8 +54,8 @@ export declare class List {
|
|
|
54
54
|
layer?: Layer;
|
|
55
55
|
}): void;
|
|
56
56
|
addToList(selection: SubscriptionSelection, data: {}, variables: {} | undefined, where: 'first' | 'last', layer?: Layer): void;
|
|
57
|
-
removeID(id: string, variables?: {}): true | undefined;
|
|
58
|
-
remove(data: {}, variables?: {}): true | undefined;
|
|
57
|
+
removeID(id: string, variables?: {}, layer?: Layer): true | undefined;
|
|
58
|
+
remove(data: {}, variables?: {}, layer?: Layer): true | undefined;
|
|
59
59
|
listType(data: {
|
|
60
60
|
__typename?: string;
|
|
61
61
|
}): string;
|
|
@@ -89,10 +89,10 @@ class ListManager {
|
|
|
89
89
|
this.lists.get(list.name).get(parentID).lists.push(handler);
|
|
90
90
|
this.listsByField.get(parentID).get(list.key).push(handler);
|
|
91
91
|
}
|
|
92
|
-
removeIDFromAllLists(id) {
|
|
92
|
+
removeIDFromAllLists(id, layer) {
|
|
93
93
|
for (const fieldMap of this.lists.values()) {
|
|
94
94
|
for (const list of fieldMap.values()) {
|
|
95
|
-
list.removeID(id);
|
|
95
|
+
list.removeID(id, void 0, layer);
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -189,6 +189,10 @@ class List {
|
|
|
189
189
|
updates: ["append", "prepend"],
|
|
190
190
|
selection: {
|
|
191
191
|
fields: {
|
|
192
|
+
__typename: {
|
|
193
|
+
keyRaw: "__typename",
|
|
194
|
+
type: "String"
|
|
195
|
+
},
|
|
192
196
|
node: {
|
|
193
197
|
type: listType,
|
|
194
198
|
keyRaw: "node",
|
|
@@ -213,7 +217,15 @@ class List {
|
|
|
213
217
|
};
|
|
214
218
|
insertData = {
|
|
215
219
|
newEntry: {
|
|
216
|
-
edges: [
|
|
220
|
+
edges: [
|
|
221
|
+
{
|
|
222
|
+
__typename: listType + "Edge",
|
|
223
|
+
node: {
|
|
224
|
+
...data,
|
|
225
|
+
__typename: listType
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
]
|
|
217
229
|
}
|
|
218
230
|
};
|
|
219
231
|
} else {
|
|
@@ -249,7 +261,7 @@ class List {
|
|
|
249
261
|
layer: layer?.id
|
|
250
262
|
});
|
|
251
263
|
}
|
|
252
|
-
removeID(id, variables = {}) {
|
|
264
|
+
removeID(id, variables = {}, layer) {
|
|
253
265
|
if (!this.validateWhen()) {
|
|
254
266
|
return;
|
|
255
267
|
}
|
|
@@ -296,7 +308,7 @@ class List {
|
|
|
296
308
|
subscribers.map((sub) => sub[0]),
|
|
297
309
|
variables
|
|
298
310
|
);
|
|
299
|
-
this.cache._internal_unstable.storage.remove(parentID, targetKey, targetID);
|
|
311
|
+
this.cache._internal_unstable.storage.remove(parentID, targetKey, targetID, layer);
|
|
300
312
|
for (const [spec] of subscribers) {
|
|
301
313
|
spec.set(
|
|
302
314
|
this.cache._internal_unstable.getSelection({
|
|
@@ -309,12 +321,12 @@ class List {
|
|
|
309
321
|
}
|
|
310
322
|
return true;
|
|
311
323
|
}
|
|
312
|
-
remove(data, variables = {}) {
|
|
324
|
+
remove(data, variables = {}, layer) {
|
|
313
325
|
const targetID = this.cache._internal_unstable.id(this.listType(data), data);
|
|
314
326
|
if (!targetID) {
|
|
315
327
|
return;
|
|
316
328
|
}
|
|
317
|
-
return this.removeID(targetID, variables);
|
|
329
|
+
return this.removeID(targetID, variables, layer);
|
|
318
330
|
}
|
|
319
331
|
listType(data) {
|
|
320
332
|
return data.__typename || this.type;
|
|
@@ -346,7 +358,7 @@ class List {
|
|
|
346
358
|
layer,
|
|
347
359
|
where
|
|
348
360
|
}) {
|
|
349
|
-
if (!this.remove(data, variables)) {
|
|
361
|
+
if (!this.remove(data, variables, layer)) {
|
|
350
362
|
this.addToList(selection, data, variables, where, layer);
|
|
351
363
|
}
|
|
352
364
|
}
|
|
@@ -8,8 +8,8 @@ export declare class InMemoryStorage {
|
|
|
8
8
|
get nextRank(): number;
|
|
9
9
|
createLayer(optimistic?: boolean): Layer;
|
|
10
10
|
insert(id: string, field: string, location: OperationLocations, target: string): void;
|
|
11
|
-
remove(id: string, field: string, target: string): void;
|
|
12
|
-
delete(id: string): void;
|
|
11
|
+
remove(id: string, field: string, target: string, layerToUser?: Layer): void;
|
|
12
|
+
delete(id: string, layerToUser?: Layer): void;
|
|
13
13
|
deleteField(id: string, field: string): void;
|
|
14
14
|
getLayer(id: number): Layer;
|
|
15
15
|
replaceID(replacement: {
|
|
@@ -25,6 +25,12 @@ export declare class InMemoryStorage {
|
|
|
25
25
|
writeField(id: string, field: string, value: GraphQLValue): number;
|
|
26
26
|
resolveLayer(id: number): void;
|
|
27
27
|
get topLayer(): Layer;
|
|
28
|
+
serialize(): string;
|
|
29
|
+
hydrate(args?: {
|
|
30
|
+
rank: number;
|
|
31
|
+
fields: EntityFieldMap;
|
|
32
|
+
links: LinkMap;
|
|
33
|
+
}, layer?: Layer): void;
|
|
28
34
|
}
|
|
29
35
|
export declare class Layer {
|
|
30
36
|
readonly id: LayerID;
|
|
@@ -27,7 +27,7 @@ module.exports = __toCommonJS(storage_exports);
|
|
|
27
27
|
var import_flatten = require("../lib/flatten");
|
|
28
28
|
class InMemoryStorage {
|
|
29
29
|
data;
|
|
30
|
-
idCount =
|
|
30
|
+
idCount = 1;
|
|
31
31
|
rank = 0;
|
|
32
32
|
constructor() {
|
|
33
33
|
this.data = [];
|
|
@@ -47,11 +47,11 @@ class InMemoryStorage {
|
|
|
47
47
|
insert(id, field, location, target) {
|
|
48
48
|
return this.topLayer.insert(id, field, location, target);
|
|
49
49
|
}
|
|
50
|
-
remove(id, field, target) {
|
|
51
|
-
return
|
|
50
|
+
remove(id, field, target, layerToUser = this.topLayer) {
|
|
51
|
+
return layerToUser.remove(id, field, target);
|
|
52
52
|
}
|
|
53
|
-
delete(id) {
|
|
54
|
-
return
|
|
53
|
+
delete(id, layerToUser = this.topLayer) {
|
|
54
|
+
return layerToUser.delete(id);
|
|
55
55
|
}
|
|
56
56
|
deleteField(id, field) {
|
|
57
57
|
return this.topLayer.deleteField(id, field);
|
|
@@ -185,6 +185,23 @@ class InMemoryStorage {
|
|
|
185
185
|
}
|
|
186
186
|
return this.data[this.data.length - 1];
|
|
187
187
|
}
|
|
188
|
+
serialize() {
|
|
189
|
+
return JSON.stringify({
|
|
190
|
+
rank: this.rank,
|
|
191
|
+
fields: this.topLayer.fields,
|
|
192
|
+
links: this.topLayer.links
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
hydrate(args, layer) {
|
|
196
|
+
if (!args) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const { rank, fields, links } = args;
|
|
200
|
+
this.rank = rank;
|
|
201
|
+
layer ??= this.createLayer(true);
|
|
202
|
+
layer.fields = fields;
|
|
203
|
+
layer.links = links;
|
|
204
|
+
}
|
|
188
205
|
}
|
|
189
206
|
class Layer {
|
|
190
207
|
id;
|
|
@@ -10,6 +10,7 @@ export declare class InMemorySubscriptions {
|
|
|
10
10
|
private subscribers;
|
|
11
11
|
private referenceCounts;
|
|
12
12
|
private keyVersions;
|
|
13
|
+
activeFields(parent: string): string[];
|
|
13
14
|
add({ parent, spec, selection, variables, parentType, }: {
|
|
14
15
|
parent: string;
|
|
15
16
|
parentType?: string;
|
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
import type { HoudiniClient } from '.';
|
|
2
|
+
import type { Cache } from '../cache/cache';
|
|
2
3
|
import type { Layer } from '../cache/storage';
|
|
3
4
|
import type { ConfigFile } from '../lib/config';
|
|
4
5
|
import { Writable } from '../lib/store';
|
|
5
6
|
import type { DocumentArtifact, QueryResult, GraphQLObject, SubscriptionSpec, CachePolicies, GraphQLVariables } from '../lib/types';
|
|
6
7
|
export declare class DocumentStore<_Data extends GraphQLObject, _Input extends GraphQLVariables> extends Writable<QueryResult<_Data, _Input>> {
|
|
7
8
|
#private;
|
|
9
|
+
readonly artifact: DocumentArtifact;
|
|
8
10
|
pendingPromise: {
|
|
9
11
|
then: (val: any) => void;
|
|
10
12
|
} | null;
|
|
11
|
-
|
|
13
|
+
serverSideFallback?: boolean;
|
|
14
|
+
constructor({ artifact, plugins, pipeline, client, cache, enableCache, initialValue, initialVariables, fetching, }: {
|
|
12
15
|
artifact: DocumentArtifact;
|
|
13
16
|
plugins?: ClientHooks[];
|
|
14
17
|
pipeline?: ClientHooks[];
|
|
15
18
|
client: HoudiniClient | null;
|
|
16
|
-
cache?:
|
|
19
|
+
cache?: Cache;
|
|
20
|
+
enableCache?: boolean;
|
|
17
21
|
initialValue?: _Data | null;
|
|
18
22
|
fetching?: boolean;
|
|
23
|
+
serverSideFallback?: boolean;
|
|
24
|
+
initialVariables?: _Input;
|
|
19
25
|
});
|
|
20
26
|
send({ metadata, session, fetch, variables, policy, stuff, cacheParams, setup, silenceEcho, }?: SendParams): Promise<QueryResult<_Data, _Input>>;
|
|
21
27
|
cleanup(): Promise<void>;
|
|
@@ -51,6 +57,7 @@ export type ClientPluginContext = {
|
|
|
51
57
|
disableRead?: boolean;
|
|
52
58
|
disableSubscriptions?: boolean;
|
|
53
59
|
applyUpdates?: string[];
|
|
60
|
+
serverSideFallback?: boolean;
|
|
54
61
|
};
|
|
55
62
|
stuff: App.Stuff;
|
|
56
63
|
};
|
|
@@ -32,20 +32,23 @@ const steps = {
|
|
|
32
32
|
backwards: ["end", "afterNetwork"]
|
|
33
33
|
};
|
|
34
34
|
class DocumentStore extends import_store.Writable {
|
|
35
|
-
|
|
35
|
+
artifact;
|
|
36
36
|
#client;
|
|
37
37
|
#configFile;
|
|
38
38
|
#plugins;
|
|
39
39
|
#lastVariables;
|
|
40
40
|
#lastContext = null;
|
|
41
41
|
pendingPromise = null;
|
|
42
|
+
serverSideFallback;
|
|
42
43
|
constructor({
|
|
43
44
|
artifact,
|
|
44
45
|
plugins,
|
|
45
46
|
pipeline,
|
|
46
47
|
client,
|
|
47
|
-
cache
|
|
48
|
+
cache,
|
|
49
|
+
enableCache = true,
|
|
48
50
|
initialValue,
|
|
51
|
+
initialVariables,
|
|
49
52
|
fetching
|
|
50
53
|
}) {
|
|
51
54
|
fetching ??= artifact.kind === import_types.ArtifactKind.Query;
|
|
@@ -56,7 +59,7 @@ class DocumentStore extends import_store.Writable {
|
|
|
56
59
|
stale: false,
|
|
57
60
|
source: null,
|
|
58
61
|
fetching,
|
|
59
|
-
variables: null
|
|
62
|
+
variables: initialVariables ?? null
|
|
60
63
|
};
|
|
61
64
|
super(initialState, () => {
|
|
62
65
|
return () => {
|
|
@@ -64,13 +67,14 @@ class DocumentStore extends import_store.Writable {
|
|
|
64
67
|
this.cleanup();
|
|
65
68
|
};
|
|
66
69
|
});
|
|
67
|
-
this
|
|
70
|
+
this.artifact = artifact;
|
|
68
71
|
this.#client = client;
|
|
69
72
|
this.#lastVariables = null;
|
|
70
73
|
this.#configFile = (0, import_config.getCurrentConfig)();
|
|
71
74
|
this.#plugins = pipeline ?? [
|
|
72
75
|
(0, import_plugins.cachePolicy)({
|
|
73
|
-
|
|
76
|
+
cache,
|
|
77
|
+
enabled: enableCache,
|
|
74
78
|
setFetching: (fetching2, data) => {
|
|
75
79
|
this.update((state) => {
|
|
76
80
|
const newState = { ...state, fetching: fetching2 };
|
|
@@ -97,9 +101,9 @@ class DocumentStore extends import_store.Writable {
|
|
|
97
101
|
} = {}) {
|
|
98
102
|
let context = new ClientPluginContextWrapper({
|
|
99
103
|
config: this.#configFile,
|
|
100
|
-
text: this
|
|
101
|
-
hash: this
|
|
102
|
-
policy: policy ?? this
|
|
104
|
+
text: this.artifact.raw,
|
|
105
|
+
hash: this.artifact.hash,
|
|
106
|
+
policy: policy ?? this.artifact.policy,
|
|
103
107
|
variables: null,
|
|
104
108
|
metadata,
|
|
105
109
|
session,
|
|
@@ -112,7 +116,7 @@ class DocumentStore extends import_store.Writable {
|
|
|
112
116
|
},
|
|
113
117
|
...stuff
|
|
114
118
|
},
|
|
115
|
-
artifact: this
|
|
119
|
+
artifact: this.artifact,
|
|
116
120
|
lastVariables: this.#lastVariables,
|
|
117
121
|
cacheParams
|
|
118
122
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference path="../../../../../houdini.d.ts" />
|
|
2
|
+
import type { Cache } from '../cache/cache';
|
|
2
3
|
import type { DocumentArtifact, GraphQLVariables, GraphQLObject, NestedList } from '../lib/types';
|
|
3
4
|
import type { ClientHooks, ClientPlugin } from './documentStore';
|
|
4
5
|
import { DocumentStore } from './documentStore';
|
|
@@ -12,10 +13,12 @@ export type HoudiniClientConstructorArgs = {
|
|
|
12
13
|
pipeline?: NestedList<ClientPlugin>;
|
|
13
14
|
throwOnError?: ThrowOnErrorParams;
|
|
14
15
|
};
|
|
15
|
-
export type ObserveParams<_Data extends GraphQLObject, _Artifact extends DocumentArtifact = DocumentArtifact> = {
|
|
16
|
+
export type ObserveParams<_Data extends GraphQLObject, _Artifact extends DocumentArtifact = DocumentArtifact, _Input extends GraphQLVariables = GraphQLVariables> = {
|
|
16
17
|
artifact: _Artifact;
|
|
17
|
-
|
|
18
|
+
enableCache?: boolean;
|
|
19
|
+
cache?: Cache;
|
|
18
20
|
initialValue?: _Data | null;
|
|
21
|
+
initialVariables?: _Input;
|
|
19
22
|
fetching?: boolean;
|
|
20
23
|
};
|
|
21
24
|
export declare class HoudiniClient {
|
|
@@ -23,6 +26,6 @@ export declare class HoudiniClient {
|
|
|
23
26
|
readonly plugins: ClientPlugin[];
|
|
24
27
|
readonly throwOnError_operations: ThrowOnErrorOperations[];
|
|
25
28
|
constructor({ url, fetchParams, plugins, pipeline, throwOnError, }: HoudiniClientConstructorArgs);
|
|
26
|
-
observe<_Data extends GraphQLObject, _Input extends GraphQLVariables>({
|
|
29
|
+
observe<_Data extends GraphQLObject, _Input extends GraphQLVariables>({ enableCache, fetching, ...rest }: ObserveParams<_Data, DocumentArtifact, _Input>): DocumentStore<_Data, _Input>;
|
|
27
30
|
}
|
|
28
31
|
export declare function createPluginHooks(plugins: ClientPlugin[]): ClientHooks[];
|
|
@@ -74,18 +74,16 @@ class HoudiniClient {
|
|
|
74
74
|
this.url = url;
|
|
75
75
|
}
|
|
76
76
|
observe({
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
fetching = false
|
|
77
|
+
enableCache = true,
|
|
78
|
+
fetching = false,
|
|
79
|
+
...rest
|
|
81
80
|
}) {
|
|
82
81
|
return new import_documentStore.DocumentStore({
|
|
83
82
|
client: this,
|
|
84
|
-
artifact,
|
|
85
83
|
plugins: createPluginHooks(this.plugins),
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
fetching,
|
|
85
|
+
enableCache,
|
|
86
|
+
...rest
|
|
89
87
|
});
|
|
90
88
|
}
|
|
91
89
|
}
|
|
@@ -97,6 +97,9 @@ const cachePolicy = ({
|
|
|
97
97
|
},
|
|
98
98
|
afterNetwork(ctx, { resolve, value, marshalVariables }) {
|
|
99
99
|
if (value.source !== import_types.DataSource.Cache && enabled && value.data && !ctx.cacheParams?.disableWrite) {
|
|
100
|
+
if (ctx.cacheParams && "serverSideFallback" in ctx.cacheParams) {
|
|
101
|
+
serverSideFallback = ctx.cacheParams?.serverSideFallback ?? serverSideFallback;
|
|
102
|
+
}
|
|
100
103
|
const targetCache = serverSide && serverSideFallback ? new import_cache2.Cache({ disabled: false }) : localCache;
|
|
101
104
|
let layer;
|
|
102
105
|
if (!serverSide && ctx.cacheParams?.layer) {
|
|
@@ -34,7 +34,7 @@ var import_utils = require("../utils");
|
|
|
34
34
|
const mutation = (0, import_utils.documentPlugin)(import_types.ArtifactKind.Mutation, () => {
|
|
35
35
|
return {
|
|
36
36
|
async start(ctx, { next, marshalVariables }) {
|
|
37
|
-
const
|
|
37
|
+
const layerOptimistic = import_cache.default._internal_unstable.storage.createLayer(true);
|
|
38
38
|
const optimisticResponse = ctx.stuff.optimisticResponse;
|
|
39
39
|
let toNotify = [];
|
|
40
40
|
if (optimisticResponse) {
|
|
@@ -45,25 +45,29 @@ const mutation = (0, import_utils.documentPlugin)(import_types.ArtifactKind.Muta
|
|
|
45
45
|
data: optimisticResponse
|
|
46
46
|
}),
|
|
47
47
|
variables: marshalVariables(ctx),
|
|
48
|
-
layer:
|
|
48
|
+
layer: layerOptimistic.id
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
ctx.cacheParams = {
|
|
52
52
|
...ctx.cacheParams,
|
|
53
|
-
layer,
|
|
53
|
+
layer: layerOptimistic,
|
|
54
54
|
notifySubscribers: toNotify,
|
|
55
55
|
forceNotify: true
|
|
56
56
|
};
|
|
57
57
|
next(ctx);
|
|
58
58
|
},
|
|
59
59
|
afterNetwork(ctx, { resolve }) {
|
|
60
|
-
ctx.cacheParams?.layer
|
|
60
|
+
if (ctx.cacheParams?.layer) {
|
|
61
|
+
import_cache.default.clearLayer(ctx.cacheParams.layer.id);
|
|
62
|
+
}
|
|
61
63
|
resolve(ctx);
|
|
62
64
|
},
|
|
63
65
|
end(ctx, { resolve, value }) {
|
|
64
66
|
const hasErrors = value.errors && value.errors.length > 0;
|
|
65
67
|
if (hasErrors) {
|
|
66
|
-
ctx.cacheParams?.layer
|
|
68
|
+
if (ctx.cacheParams?.layer) {
|
|
69
|
+
import_cache.default.clearLayer(ctx.cacheParams.layer.id);
|
|
70
|
+
}
|
|
67
71
|
}
|
|
68
72
|
if (ctx.cacheParams?.layer) {
|
|
69
73
|
import_cache.default._internal_unstable.storage.resolveLayer(ctx.cacheParams.layer.id);
|
|
@@ -73,7 +77,7 @@ const mutation = (0, import_utils.documentPlugin)(import_types.ArtifactKind.Muta
|
|
|
73
77
|
catch(ctx, { error }) {
|
|
74
78
|
if (ctx.cacheParams?.layer) {
|
|
75
79
|
const { layer } = ctx.cacheParams;
|
|
76
|
-
layer.
|
|
80
|
+
import_cache.default.clearLayer(layer.id);
|
|
77
81
|
import_cache.default._internal_unstable.storage.resolveLayer(layer.id);
|
|
78
82
|
}
|
|
79
83
|
throw error;
|
|
@@ -23,3 +23,4 @@ __reExport(lib_exports, require("./scalars"), module.exports);
|
|
|
23
23
|
__reExport(lib_exports, require("./types"), module.exports);
|
|
24
24
|
__reExport(lib_exports, require("./store"), module.exports);
|
|
25
25
|
__reExport(lib_exports, require("./key"), module.exports);
|
|
26
|
+
__reExport(lib_exports, require("./lru"), module.exports);
|