@isograph/react 0.0.0-main-1cd3db6d → 0.0.0-main-2c275831
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/dist/PromiseWrapper.js +1 -1
- package/dist/cache.d.ts +4 -4
- package/dist/cache.js +30 -35
- package/dist/componentCache.d.ts +2 -2
- package/dist/componentCache.js +1 -1
- package/dist/index.d.ts +23 -20
- package/dist/index.js +62 -58
- package/package.json +3 -3
- package/src/PromiseWrapper.ts +1 -1
- package/src/cache.ts +65 -92
- package/src/componentCache.ts +4 -8
- package/src/index.tsx +142 -204
package/src/cache.ts
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
ItemCleanupPair,
|
4
|
-
ParentCache,
|
5
|
-
} from "@isograph/react-disposable-state";
|
6
|
-
import { PromiseWrapper, wrapPromise } from "./PromiseWrapper";
|
1
|
+
import { Factory, ItemCleanupPair, ParentCache } from '@isograph/react-disposable-state';
|
2
|
+
import { PromiseWrapper, wrapPromise } from './PromiseWrapper';
|
7
3
|
import {
|
8
4
|
Argument,
|
9
5
|
ArgumentValue,
|
@@ -14,7 +10,7 @@ import {
|
|
14
10
|
ReaderLinkedField,
|
15
11
|
ReaderScalarField,
|
16
12
|
RefetchQueryArtifactWrapper,
|
17
|
-
} from
|
13
|
+
} from './index';
|
18
14
|
|
19
15
|
declare global {
|
20
16
|
interface Window {
|
@@ -24,12 +20,9 @@ declare global {
|
|
24
20
|
|
25
21
|
const cache: { [index: string]: ParentCache<any> } = {};
|
26
22
|
|
27
|
-
function getOrCreateCache<T>(
|
28
|
-
|
29
|
-
|
30
|
-
): ParentCache<T> {
|
31
|
-
if (typeof window !== "undefined" && window.__LOG) {
|
32
|
-
console.log("getting cache for", {
|
23
|
+
function getOrCreateCache<T>(index: string, factory: Factory<T>): ParentCache<T> {
|
24
|
+
if (typeof window !== 'undefined' && window.__LOG) {
|
25
|
+
console.log('getting cache for', {
|
33
26
|
index,
|
34
27
|
cache: Object.keys(cache),
|
35
28
|
found: !!cache[index],
|
@@ -48,7 +41,7 @@ function getOrCreateCache<T>(
|
|
48
41
|
* results.
|
49
42
|
*/
|
50
43
|
export function stableCopy<T>(value: T): T {
|
51
|
-
if (!value || typeof value !==
|
44
|
+
if (!value || typeof value !== 'object') {
|
52
45
|
return value;
|
53
46
|
}
|
54
47
|
if (Array.isArray(value)) {
|
@@ -68,11 +61,10 @@ type IsoResolver = IsographEntrypoint<any, any, any>;
|
|
68
61
|
|
69
62
|
export function getOrCreateCacheForArtifact<T>(
|
70
63
|
artifact: IsographEntrypoint<any, any, T>,
|
71
|
-
variables: object
|
64
|
+
variables: object,
|
72
65
|
): ParentCache<PromiseWrapper<T>> {
|
73
66
|
const cacheKey = artifact.queryText + JSON.stringify(stableCopy(variables));
|
74
|
-
const factory: Factory<PromiseWrapper<T>> = () =>
|
75
|
-
makeNetworkRequest<T>(artifact, variables);
|
67
|
+
const factory: Factory<PromiseWrapper<T>> = () => makeNetworkRequest<T>(artifact, variables);
|
76
68
|
return getOrCreateCache<PromiseWrapper<T>>(cacheKey, factory);
|
77
69
|
}
|
78
70
|
|
@@ -85,29 +77,27 @@ export function setNetwork(newNetwork: typeof network) {
|
|
85
77
|
|
86
78
|
export function makeNetworkRequest<T>(
|
87
79
|
artifact: IsoResolver,
|
88
|
-
variables: object
|
80
|
+
variables: object,
|
89
81
|
): ItemCleanupPair<PromiseWrapper<T>> {
|
90
|
-
if (typeof window !==
|
91
|
-
console.log(
|
82
|
+
if (typeof window !== 'undefined' && window.__LOG) {
|
83
|
+
console.log('make network request', artifact, variables);
|
92
84
|
}
|
93
85
|
if (network == null) {
|
94
|
-
throw new Error(
|
86
|
+
throw new Error('Network must be set before makeNetworkRequest is called');
|
95
87
|
}
|
96
88
|
|
97
|
-
const promise = network(artifact.queryText, variables).then(
|
98
|
-
(
|
99
|
-
|
100
|
-
console.log("network response", artifact);
|
101
|
-
}
|
102
|
-
normalizeData(
|
103
|
-
artifact.normalizationAst,
|
104
|
-
networkResponse.data,
|
105
|
-
variables,
|
106
|
-
artifact.nestedRefetchQueries
|
107
|
-
);
|
108
|
-
return networkResponse.data;
|
89
|
+
const promise = network(artifact.queryText, variables).then((networkResponse) => {
|
90
|
+
if (typeof window !== 'undefined' && window.__LOG) {
|
91
|
+
console.log('network response', artifact);
|
109
92
|
}
|
110
|
-
|
93
|
+
normalizeData(
|
94
|
+
artifact.normalizationAst,
|
95
|
+
networkResponse.data,
|
96
|
+
variables,
|
97
|
+
artifact.nestedRefetchQueries,
|
98
|
+
);
|
99
|
+
return networkResponse.data;
|
100
|
+
});
|
111
101
|
|
112
102
|
const wrapper = wrapPromise(promise);
|
113
103
|
|
@@ -146,7 +136,7 @@ export type StoreRecord = {
|
|
146
136
|
|
147
137
|
export type DataId = string;
|
148
138
|
|
149
|
-
export const ROOT_ID: DataId &
|
139
|
+
export const ROOT_ID: DataId & '__ROOT' = '__ROOT';
|
150
140
|
let store: {
|
151
141
|
[index: DataId]: StoreRecord | null;
|
152
142
|
__ROOT: StoreRecord;
|
@@ -180,15 +170,10 @@ function normalizeData(
|
|
180
170
|
normalizationAst: NormalizationAst,
|
181
171
|
networkResponse: NetworkResponseObject,
|
182
172
|
variables: Object,
|
183
|
-
nestedRefetchQueries: RefetchQueryArtifactWrapper[]
|
173
|
+
nestedRefetchQueries: RefetchQueryArtifactWrapper[],
|
184
174
|
) {
|
185
|
-
if (typeof window !==
|
186
|
-
console.log(
|
187
|
-
"about to normalize",
|
188
|
-
normalizationAst,
|
189
|
-
networkResponse,
|
190
|
-
variables
|
191
|
-
);
|
175
|
+
if (typeof window !== 'undefined' && window.__LOG) {
|
176
|
+
console.log('about to normalize', normalizationAst, networkResponse, variables);
|
192
177
|
}
|
193
178
|
normalizeDataIntoRecord(
|
194
179
|
normalizationAst,
|
@@ -196,10 +181,10 @@ function normalizeData(
|
|
196
181
|
store.__ROOT,
|
197
182
|
ROOT_ID,
|
198
183
|
variables as any,
|
199
|
-
nestedRefetchQueries
|
184
|
+
nestedRefetchQueries,
|
200
185
|
);
|
201
|
-
if (typeof window !==
|
202
|
-
console.log(
|
186
|
+
if (typeof window !== 'undefined' && window.__LOG) {
|
187
|
+
console.log('after normalization', { store });
|
203
188
|
}
|
204
189
|
callSubscriptions();
|
205
190
|
}
|
@@ -233,27 +218,27 @@ function normalizeDataIntoRecord(
|
|
233
218
|
targetParentRecord: StoreRecord,
|
234
219
|
targetParentRecordId: DataId,
|
235
220
|
variables: { [index: string]: string },
|
236
|
-
nestedRefetchQueries: RefetchQueryArtifactWrapper[]
|
221
|
+
nestedRefetchQueries: RefetchQueryArtifactWrapper[],
|
237
222
|
) {
|
238
223
|
for (const normalizationNode of normalizationAst) {
|
239
224
|
switch (normalizationNode.kind) {
|
240
|
-
case
|
225
|
+
case 'Scalar': {
|
241
226
|
normalizeScalarField(
|
242
227
|
normalizationNode,
|
243
228
|
networkResponseParentRecord,
|
244
229
|
targetParentRecord,
|
245
|
-
variables
|
230
|
+
variables,
|
246
231
|
);
|
247
232
|
break;
|
248
233
|
}
|
249
|
-
case
|
234
|
+
case 'Linked': {
|
250
235
|
normalizeLinkedField(
|
251
236
|
normalizationNode,
|
252
237
|
networkResponseParentRecord,
|
253
238
|
targetParentRecord,
|
254
239
|
targetParentRecordId,
|
255
240
|
variables,
|
256
|
-
nestedRefetchQueries
|
241
|
+
nestedRefetchQueries,
|
257
242
|
);
|
258
243
|
break;
|
259
244
|
}
|
@@ -265,19 +250,16 @@ function normalizeScalarField(
|
|
265
250
|
astNode: NormalizationScalarField,
|
266
251
|
networkResponseParentRecord: NetworkResponseObject,
|
267
252
|
targetStoreRecord: StoreRecord,
|
268
|
-
variables: { [index: string]: string }
|
253
|
+
variables: { [index: string]: string },
|
269
254
|
) {
|
270
255
|
const networkResponseKey = getNetworkResponseKey(astNode);
|
271
256
|
const networkResponseData = networkResponseParentRecord[networkResponseKey];
|
272
257
|
const parentRecordKey = getParentRecordKey(astNode, variables);
|
273
258
|
|
274
|
-
if (
|
275
|
-
networkResponseData == null ||
|
276
|
-
isScalarOrEmptyArray(networkResponseData)
|
277
|
-
) {
|
259
|
+
if (networkResponseData == null || isScalarOrEmptyArray(networkResponseData)) {
|
278
260
|
targetStoreRecord[parentRecordKey] = networkResponseData;
|
279
261
|
} else {
|
280
|
-
throw new Error(
|
262
|
+
throw new Error('Unexpected object array when normalizing scalar');
|
281
263
|
}
|
282
264
|
}
|
283
265
|
|
@@ -290,7 +272,7 @@ function normalizeLinkedField(
|
|
290
272
|
targetParentRecord: StoreRecord,
|
291
273
|
targetParentRecordId: DataId,
|
292
274
|
variables: { [index: string]: string },
|
293
|
-
nestedRefetchQueries: RefetchQueryArtifactWrapper[]
|
275
|
+
nestedRefetchQueries: RefetchQueryArtifactWrapper[],
|
294
276
|
) {
|
295
277
|
const networkResponseKey = getNetworkResponseKey(astNode);
|
296
278
|
const networkResponseData = networkResponseParentRecord[networkResponseKey];
|
@@ -302,9 +284,7 @@ function normalizeLinkedField(
|
|
302
284
|
}
|
303
285
|
|
304
286
|
if (isScalarButNotEmptyArray(networkResponseData)) {
|
305
|
-
throw new Error(
|
306
|
-
"Unexpected scalar network response when normalizing a linked field"
|
307
|
-
);
|
287
|
+
throw new Error('Unexpected scalar network response when normalizing a linked field');
|
308
288
|
}
|
309
289
|
|
310
290
|
if (Array.isArray(networkResponseData)) {
|
@@ -318,7 +298,7 @@ function normalizeLinkedField(
|
|
318
298
|
targetParentRecordId,
|
319
299
|
variables,
|
320
300
|
i,
|
321
|
-
nestedRefetchQueries
|
301
|
+
nestedRefetchQueries,
|
322
302
|
);
|
323
303
|
dataIds.push({ __link: newStoreRecordId });
|
324
304
|
}
|
@@ -330,7 +310,7 @@ function normalizeLinkedField(
|
|
330
310
|
targetParentRecordId,
|
331
311
|
variables,
|
332
312
|
null,
|
333
|
-
nestedRefetchQueries
|
313
|
+
nestedRefetchQueries,
|
334
314
|
);
|
335
315
|
targetParentRecord[parentRecordKey] = {
|
336
316
|
__link: newStoreRecordId,
|
@@ -344,14 +324,14 @@ function normalizeNetworkResponseObject(
|
|
344
324
|
targetParentRecordId: string,
|
345
325
|
variables: { [index: string]: string },
|
346
326
|
index: number | null,
|
347
|
-
nestedRefetchQueries: RefetchQueryArtifactWrapper[]
|
327
|
+
nestedRefetchQueries: RefetchQueryArtifactWrapper[],
|
348
328
|
): DataId /* The id of the modified or newly created item */ {
|
349
329
|
const newStoreRecordId = getDataIdOfNetworkResponse(
|
350
330
|
targetParentRecordId,
|
351
331
|
networkResponseData,
|
352
332
|
astNode,
|
353
333
|
variables,
|
354
|
-
index
|
334
|
+
index,
|
355
335
|
);
|
356
336
|
|
357
337
|
const newStoreRecord = store[newStoreRecordId] ?? {};
|
@@ -363,14 +343,14 @@ function normalizeNetworkResponseObject(
|
|
363
343
|
newStoreRecord,
|
364
344
|
newStoreRecordId,
|
365
345
|
variables,
|
366
|
-
nestedRefetchQueries
|
346
|
+
nestedRefetchQueries,
|
367
347
|
);
|
368
348
|
|
369
349
|
return newStoreRecordId;
|
370
350
|
}
|
371
351
|
|
372
352
|
function isScalarOrEmptyArray(
|
373
|
-
data: NonNullable<NetworkResponseValue
|
353
|
+
data: NonNullable<NetworkResponseValue>,
|
374
354
|
): data is NetworkResponseScalarValue | NetworkResponseScalarValue[] {
|
375
355
|
// N.B. empty arrays count as empty arrays of scalar fields.
|
376
356
|
if (Array.isArray(data)) {
|
@@ -378,14 +358,12 @@ function isScalarOrEmptyArray(
|
|
378
358
|
return (data as any).every((x: any) => isScalarOrEmptyArray(x));
|
379
359
|
}
|
380
360
|
const isScalarValue =
|
381
|
-
typeof data ===
|
382
|
-
typeof data === "number" ||
|
383
|
-
typeof data === "boolean";
|
361
|
+
typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean';
|
384
362
|
return isScalarValue;
|
385
363
|
}
|
386
364
|
|
387
365
|
function isScalarButNotEmptyArray(
|
388
|
-
data: NonNullable<NetworkResponseValue
|
366
|
+
data: NonNullable<NetworkResponseValue>,
|
389
367
|
): data is NetworkResponseScalarValue | NetworkResponseScalarValue[] {
|
390
368
|
// N.B. empty arrays count as empty arrays of linked fields.
|
391
369
|
if (Array.isArray(data)) {
|
@@ -396,9 +374,7 @@ function isScalarButNotEmptyArray(
|
|
396
374
|
return (data as any).every((x: any) => isScalarOrEmptyArray(x));
|
397
375
|
}
|
398
376
|
const isScalarValue =
|
399
|
-
typeof data ===
|
400
|
-
typeof data === "number" ||
|
401
|
-
typeof data === "boolean";
|
377
|
+
typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean';
|
402
378
|
return isScalarValue;
|
403
379
|
}
|
404
380
|
|
@@ -408,7 +384,7 @@ export function getParentRecordKey(
|
|
408
384
|
| NormalizationScalarField
|
409
385
|
| ReaderLinkedField
|
410
386
|
| ReaderScalarField,
|
411
|
-
variables: { [index: string]: string }
|
387
|
+
variables: { [index: string]: string },
|
412
388
|
): string {
|
413
389
|
let parentRecordKey = astNode.fieldName;
|
414
390
|
const fieldParameters = astNode.arguments;
|
@@ -423,35 +399,32 @@ export function getParentRecordKey(
|
|
423
399
|
|
424
400
|
function getStoreKeyChunkForArgumentValue(
|
425
401
|
argumentValue: ArgumentValue,
|
426
|
-
variables: { [index: string]: string }
|
402
|
+
variables: { [index: string]: string },
|
427
403
|
) {
|
428
404
|
switch (argumentValue.kind) {
|
429
|
-
case
|
405
|
+
case 'Literal': {
|
430
406
|
return argumentValue.value;
|
431
407
|
break;
|
432
408
|
}
|
433
|
-
case
|
409
|
+
case 'Variable': {
|
434
410
|
return variables[argumentValue.name];
|
435
411
|
break;
|
436
412
|
}
|
437
413
|
default: {
|
438
414
|
// TODO configure eslint to allow unused vars starting with _
|
439
415
|
let _: never = argumentValue;
|
440
|
-
throw new Error(
|
416
|
+
throw new Error('Unexpected case');
|
441
417
|
}
|
442
418
|
}
|
443
419
|
}
|
444
420
|
|
445
|
-
function getStoreKeyChunkForArgument(
|
446
|
-
argument: Argument,
|
447
|
-
variables: { [index: string]: string }
|
448
|
-
) {
|
421
|
+
function getStoreKeyChunkForArgument(argument: Argument, variables: { [index: string]: string }) {
|
449
422
|
const chunk = getStoreKeyChunkForArgumentValue(argument[1], variables);
|
450
423
|
return `${FIRST_SPLIT_KEY}${argument[0]}${SECOND_SPLIT_KEY}${chunk}`;
|
451
424
|
}
|
452
425
|
|
453
426
|
function getNetworkResponseKey(
|
454
|
-
astNode: NormalizationLinkedField | NormalizationScalarField
|
427
|
+
astNode: NormalizationLinkedField | NormalizationScalarField,
|
455
428
|
): string {
|
456
429
|
let networkResponseKey = astNode.fieldName;
|
457
430
|
const fieldParameters = astNode.arguments;
|
@@ -460,17 +433,17 @@ function getNetworkResponseKey(
|
|
460
433
|
const [argumentName, argumentValue] = fieldParameter;
|
461
434
|
let argumentValueChunk;
|
462
435
|
switch (argumentValue.kind) {
|
463
|
-
case
|
464
|
-
argumentValueChunk =
|
436
|
+
case 'Literal': {
|
437
|
+
argumentValueChunk = 'l_' + argumentValue.value;
|
465
438
|
break;
|
466
439
|
}
|
467
|
-
case
|
468
|
-
argumentValueChunk =
|
440
|
+
case 'Variable': {
|
441
|
+
argumentValueChunk = 'v_' + argumentValue.name;
|
469
442
|
break;
|
470
443
|
}
|
471
444
|
default: {
|
472
445
|
let _: never = argumentValue;
|
473
|
-
throw new Error(
|
446
|
+
throw new Error('Unexpected case');
|
474
447
|
}
|
475
448
|
}
|
476
449
|
networkResponseKey += `${FIRST_SPLIT_KEY}${argumentName}${SECOND_SPLIT_KEY}${argumentValueChunk}`;
|
@@ -480,8 +453,8 @@ function getNetworkResponseKey(
|
|
480
453
|
}
|
481
454
|
|
482
455
|
// an alias might be pullRequests____first___first____after___cursor
|
483
|
-
export const FIRST_SPLIT_KEY =
|
484
|
-
export const SECOND_SPLIT_KEY =
|
456
|
+
export const FIRST_SPLIT_KEY = '____';
|
457
|
+
export const SECOND_SPLIT_KEY = '___';
|
485
458
|
|
486
459
|
// Returns a key to look up an item in the store
|
487
460
|
function getDataIdOfNetworkResponse(
|
@@ -489,7 +462,7 @@ function getDataIdOfNetworkResponse(
|
|
489
462
|
dataToNormalize: NetworkResponseObject,
|
490
463
|
astNode: NormalizationLinkedField | NormalizationScalarField,
|
491
464
|
variables: { [index: string]: string },
|
492
|
-
index: number | null
|
465
|
+
index: number | null,
|
493
466
|
): DataId {
|
494
467
|
// Check whether the dataToNormalize has an id field. If so, that is the key.
|
495
468
|
// If not, we construct an id from the parentRecordId and the field parameters.
|
package/src/componentCache.ts
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
RefetchQueryArtifactWrapper,
|
4
|
-
readButDoNotEvaluate,
|
5
|
-
} from "./index";
|
6
|
-
import { DataId, stableCopy } from "./cache";
|
1
|
+
import { ReaderArtifact, RefetchQueryArtifactWrapper, readButDoNotEvaluate } from './index';
|
2
|
+
import { DataId, stableCopy } from './cache';
|
7
3
|
|
8
4
|
type ComponentName = string;
|
9
5
|
type StringifiedArgs = string;
|
@@ -17,7 +13,7 @@ export function getOrCreateCachedComponent(
|
|
17
13
|
componentName: string,
|
18
14
|
readerArtifact: ReaderArtifact<any, any, any>,
|
19
15
|
variables: { [key: string]: string },
|
20
|
-
resolverRefetchQueries: RefetchQueryArtifactWrapper[]
|
16
|
+
resolverRefetchQueries: RefetchQueryArtifactWrapper[],
|
21
17
|
) {
|
22
18
|
const stringifiedArgs = JSON.stringify(stableCopy(variables));
|
23
19
|
cachedComponentsById[root] = cachedComponentsById[root] ?? {};
|
@@ -29,7 +25,7 @@ export function getOrCreateCachedComponent(
|
|
29
25
|
(() => {
|
30
26
|
function Component(additionalRuntimeProps) {
|
31
27
|
const data = readButDoNotEvaluate({
|
32
|
-
kind:
|
28
|
+
kind: 'FragmentReference',
|
33
29
|
readerArtifact: readerArtifact,
|
34
30
|
root,
|
35
31
|
variables,
|