@isograph/react 0.0.0-main-1200105f → 0.0.0-main-ffab3426
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/cache.d.ts +9 -3
- package/dist/cache.js +34 -14
- package/dist/componentCache.d.ts +6 -0
- package/dist/componentCache.js +29 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +18 -50
- package/package.json +3 -3
- package/src/cache.ts +40 -16
- package/src/componentCache.ts +48 -0
- package/src/index.tsx +34 -65
package/dist/cache.d.ts
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
import { ItemCleanupPair, ParentCache } from "@isograph/react-disposable-state";
|
2
2
|
import { PromiseWrapper } from "./PromiseWrapper";
|
3
3
|
import { IsographEntrypoint, NormalizationLinkedField, NormalizationScalarField, ReaderLinkedField, ReaderScalarField } from "./index";
|
4
|
+
declare global {
|
5
|
+
interface Window {
|
6
|
+
__LOG: boolean;
|
7
|
+
}
|
8
|
+
}
|
4
9
|
type IsoResolver = IsographEntrypoint<any, any, any>;
|
5
|
-
export declare function getOrCreateCacheForArtifact<T>(artifact:
|
10
|
+
export declare function getOrCreateCacheForArtifact<T>(artifact: IsographEntrypoint<any, any, T>, variables: object): ParentCache<PromiseWrapper<T>>;
|
6
11
|
declare let network: ((queryText: string, variables: object) => Promise<any>) | null;
|
7
12
|
export declare function setNetwork(newNetwork: typeof network): void;
|
8
13
|
export declare function makeNetworkRequest<T>(artifact: IsoResolver, variables: object): ItemCleanupPair<PromiseWrapper<T>>;
|
@@ -16,10 +21,11 @@ export type StoreRecord = {
|
|
16
21
|
};
|
17
22
|
export type DataId = string;
|
18
23
|
export declare const ROOT_ID: DataId & "__ROOT";
|
19
|
-
export declare
|
20
|
-
[index:
|
24
|
+
export declare function getStore(): {
|
25
|
+
[index: string]: StoreRecord | null;
|
21
26
|
__ROOT: StoreRecord;
|
22
27
|
};
|
28
|
+
export declare function clearStore(): void;
|
23
29
|
export declare function subscribe(callback: () => void): () => void;
|
24
30
|
export declare function onNextChange(): Promise<void>;
|
25
31
|
export declare function getParentRecordKey(astNode: NormalizationLinkedField | NormalizationScalarField | ReaderLinkedField | ReaderScalarField, variables: {
|
package/dist/cache.js
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.SECOND_SPLIT_KEY = exports.FIRST_SPLIT_KEY = exports.getParentRecordKey = exports.onNextChange = exports.subscribe = exports.
|
3
|
+
exports.SECOND_SPLIT_KEY = exports.FIRST_SPLIT_KEY = exports.getParentRecordKey = exports.onNextChange = exports.subscribe = exports.clearStore = exports.getStore = exports.ROOT_ID = exports.makeNetworkRequest = exports.setNetwork = exports.getOrCreateCacheForArtifact = void 0;
|
4
4
|
const react_disposable_state_1 = require("@isograph/react-disposable-state");
|
5
5
|
const PromiseWrapper_1 = require("./PromiseWrapper");
|
6
6
|
const cache = {};
|
7
7
|
function getOrCreateCache(index, factory) {
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
9
|
+
console.log("getting cache for", {
|
10
|
+
index,
|
11
|
+
cache: Object.keys(cache),
|
12
|
+
found: !!cache[index],
|
13
|
+
});
|
14
|
+
}
|
13
15
|
if (cache[index] == null) {
|
14
16
|
cache[index] = new react_disposable_state_1.ParentCache(factory);
|
15
17
|
}
|
@@ -49,12 +51,16 @@ function setNetwork(newNetwork) {
|
|
49
51
|
}
|
50
52
|
exports.setNetwork = setNetwork;
|
51
53
|
function makeNetworkRequest(artifact, variables) {
|
52
|
-
|
54
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
55
|
+
console.log("make network request", artifact, variables);
|
56
|
+
}
|
53
57
|
if (network == null) {
|
54
58
|
throw new Error("Network must be set before makeNetworkRequest is called");
|
55
59
|
}
|
56
60
|
const promise = network(artifact.queryText, variables).then((networkResponse) => {
|
57
|
-
|
61
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
62
|
+
console.log("network response", artifact);
|
63
|
+
}
|
58
64
|
normalizeData(artifact.normalizationAst, networkResponse.data, variables, artifact.nestedRefetchQueries);
|
59
65
|
return networkResponse.data;
|
60
66
|
});
|
@@ -69,13 +75,27 @@ function makeNetworkRequest(artifact, variables) {
|
|
69
75
|
}
|
70
76
|
exports.makeNetworkRequest = makeNetworkRequest;
|
71
77
|
exports.ROOT_ID = "__ROOT";
|
72
|
-
|
78
|
+
let store = {
|
73
79
|
__ROOT: {},
|
74
80
|
};
|
81
|
+
function getStore() {
|
82
|
+
return store;
|
83
|
+
}
|
84
|
+
exports.getStore = getStore;
|
85
|
+
function clearStore() {
|
86
|
+
store = {
|
87
|
+
__ROOT: {},
|
88
|
+
};
|
89
|
+
}
|
90
|
+
exports.clearStore = clearStore;
|
75
91
|
function normalizeData(normalizationAst, networkResponse, variables, nestedRefetchQueries) {
|
76
|
-
|
77
|
-
|
78
|
-
|
92
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
93
|
+
console.log("about to normalize", normalizationAst, networkResponse, variables);
|
94
|
+
}
|
95
|
+
normalizeDataIntoRecord(normalizationAst, networkResponse, store.__ROOT, exports.ROOT_ID, variables, nestedRefetchQueries);
|
96
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
97
|
+
console.log("after normalization", { store });
|
98
|
+
}
|
79
99
|
callSubscriptions();
|
80
100
|
}
|
81
101
|
function subscribe(callback) {
|
@@ -159,8 +179,8 @@ function normalizeLinkedField(astNode, networkResponseParentRecord, targetParent
|
|
159
179
|
function normalizeNetworkResponseObject(astNode, networkResponseData, targetParentRecordId, variables, index, nestedRefetchQueries) {
|
160
180
|
var _a;
|
161
181
|
const newStoreRecordId = getDataIdOfNetworkResponse(targetParentRecordId, networkResponseData, astNode, variables, index);
|
162
|
-
const newStoreRecord = (_a =
|
163
|
-
|
182
|
+
const newStoreRecord = (_a = store[newStoreRecordId]) !== null && _a !== void 0 ? _a : {};
|
183
|
+
store[newStoreRecordId] = newStoreRecord;
|
164
184
|
normalizeDataIntoRecord(astNode.selections, networkResponseData, newStoreRecord, newStoreRecordId, variables, nestedRefetchQueries);
|
165
185
|
return newStoreRecordId;
|
166
186
|
}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
import { ReaderArtifact, RefetchQueryArtifactWrapper } from "./index";
|
3
|
+
import { DataId } from "./cache";
|
4
|
+
export declare function getOrCreateCachedComponent(root: DataId, componentName: string, stringifiedArgs: string, readerArtifact: ReaderArtifact<any, any, any>, variables: {
|
5
|
+
[key: string]: string;
|
6
|
+
}, resolverRefetchQueries: RefetchQueryArtifactWrapper[]): import("react").FC<any>;
|
@@ -0,0 +1,29 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.getOrCreateCachedComponent = void 0;
|
4
|
+
const index_1 = require("./index");
|
5
|
+
const cachedComponentsById = {};
|
6
|
+
function getOrCreateCachedComponent(root, componentName, stringifiedArgs, readerArtifact, variables, resolverRefetchQueries) {
|
7
|
+
var _a, _b, _c;
|
8
|
+
cachedComponentsById[root] = (_a = cachedComponentsById[root]) !== null && _a !== void 0 ? _a : {};
|
9
|
+
const componentsByName = cachedComponentsById[root];
|
10
|
+
componentsByName[componentName] = (_b = componentsByName[componentName]) !== null && _b !== void 0 ? _b : {};
|
11
|
+
const byArgs = componentsByName[componentName];
|
12
|
+
byArgs[stringifiedArgs] =
|
13
|
+
(_c = byArgs[stringifiedArgs]) !== null && _c !== void 0 ? _c : (() => {
|
14
|
+
function Component(additionalRuntimeProps) {
|
15
|
+
const data = (0, index_1.readButDoNotEvaluate)({
|
16
|
+
kind: "FragmentReference",
|
17
|
+
readerArtifact: readerArtifact,
|
18
|
+
root,
|
19
|
+
variables,
|
20
|
+
nestedRefetchQueries: resolverRefetchQueries,
|
21
|
+
});
|
22
|
+
return readerArtifact.resolver(Object.assign({ data }, additionalRuntimeProps));
|
23
|
+
}
|
24
|
+
Component.displayName = `${componentName} (id: ${root}) @component`;
|
25
|
+
return Component;
|
26
|
+
})();
|
27
|
+
return byArgs[stringifiedArgs];
|
28
|
+
}
|
29
|
+
exports.getOrCreateCachedComponent = getOrCreateCachedComponent;
|
package/dist/index.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { DataId, StoreRecord, Link } from "./cache";
|
2
|
-
export { setNetwork, makeNetworkRequest, subscribe, DataId, Link, StoreRecord, } from "./cache";
|
2
|
+
export { setNetwork, makeNetworkRequest, subscribe, DataId, Link, StoreRecord, clearStore, } from "./cache";
|
3
3
|
export type IsographEntrypoint<TReadFromStore extends Object, TResolverProps, TResolverResult> = {
|
4
4
|
kind: "Entrypoint";
|
5
5
|
queryText: string;
|
@@ -103,7 +103,6 @@ export declare function defaultMissingFieldHandler(storeRecord: StoreRecord, roo
|
|
103
103
|
[index: string]: any;
|
104
104
|
} | null): Link | undefined;
|
105
105
|
export declare function setMissingFieldHandler(handler: typeof defaultMissingFieldHandler): void;
|
106
|
-
export declare function getRefReaderForName(name: string): any;
|
107
106
|
export type IsographComponentProps<TDataType, TOtherProps = Object> = {
|
108
107
|
data: TDataType;
|
109
108
|
} & TOtherProps;
|
package/dist/index.js
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.
|
3
|
+
exports.setMissingFieldHandler = exports.defaultMissingFieldHandler = exports.readButDoNotEvaluate = exports.read = exports.useLazyReference = exports.iso = exports.isoFetch = exports.clearStore = exports.subscribe = exports.makeNetworkRequest = exports.setNetwork = void 0;
|
7
4
|
const cache_1 = require("./cache");
|
8
5
|
const react_disposable_state_1 = require("@isograph/react-disposable-state");
|
9
|
-
const
|
6
|
+
const componentCache_1 = require("./componentCache");
|
10
7
|
var cache_2 = require("./cache");
|
11
8
|
Object.defineProperty(exports, "setNetwork", { enumerable: true, get: function () { return cache_2.setNetwork; } });
|
12
9
|
Object.defineProperty(exports, "makeNetworkRequest", { enumerable: true, get: function () { return cache_2.makeNetworkRequest; } });
|
13
10
|
Object.defineProperty(exports, "subscribe", { enumerable: true, get: function () { return cache_2.subscribe; } });
|
11
|
+
Object.defineProperty(exports, "clearStore", { enumerable: true, get: function () { return cache_2.clearStore; } });
|
14
12
|
function isoFetch(_text) {
|
15
13
|
return void 0;
|
16
14
|
}
|
@@ -33,9 +31,7 @@ function useLazyReference(entrypoint, variables) {
|
|
33
31
|
const cache = (0, cache_1.getOrCreateCacheForArtifact)(entrypoint, variables);
|
34
32
|
// TODO add comment explaining why we never use this value
|
35
33
|
// @ts-ignore
|
36
|
-
const data =
|
37
|
-
// @ts-ignore
|
38
|
-
(0, react_disposable_state_1.useLazyDisposableState)(cache).state;
|
34
|
+
const data = (0, react_disposable_state_1.useLazyDisposableState)(cache).state;
|
39
35
|
return {
|
40
36
|
queryReference: {
|
41
37
|
kind: "FragmentReference",
|
@@ -48,7 +44,7 @@ function useLazyReference(entrypoint, variables) {
|
|
48
44
|
}
|
49
45
|
exports.useLazyReference = useLazyReference;
|
50
46
|
function read(fragmentReference) {
|
51
|
-
var _a;
|
47
|
+
var _a, _b;
|
52
48
|
const variant = fragmentReference.readerArtifact.variant;
|
53
49
|
if (variant.kind === "Eager") {
|
54
50
|
const data = readData(fragmentReference.readerArtifact.readerAst, fragmentReference.root, (_a = fragmentReference.variables) !== null && _a !== void 0 ? _a : {}, fragmentReference.nestedRefetchQueries);
|
@@ -60,18 +56,8 @@ function read(fragmentReference) {
|
|
60
56
|
}
|
61
57
|
}
|
62
58
|
else if (variant.kind === "Component") {
|
63
|
-
|
64
|
-
|
65
|
-
const RefReaderForName = getRefReaderForName(variant.componentName);
|
66
|
-
// TODO do not create a new reference on every render?
|
67
|
-
return (react_1.default.createElement(RefReaderForName, { reference: {
|
68
|
-
kind: "FragmentReference",
|
69
|
-
readerArtifact: fragmentReference.readerArtifact,
|
70
|
-
root: fragmentReference.root,
|
71
|
-
variables: fragmentReference.variables,
|
72
|
-
nestedRefetchQueries: fragmentReference.nestedRefetchQueries,
|
73
|
-
}, additionalRuntimeProps: additionalRuntimeProps }));
|
74
|
-
};
|
59
|
+
// @ts-ignore
|
60
|
+
return (0, componentCache_1.getOrCreateCachedComponent)(fragmentReference.root, variant.componentName, "TODO", fragmentReference.readerArtifact, (_b = fragmentReference.variables) !== null && _b !== void 0 ? _b : {}, fragmentReference.nestedRefetchQueries);
|
75
61
|
}
|
76
62
|
// Why can't Typescript realize that this is unreachable??
|
77
63
|
throw new Error("This is unreachable");
|
@@ -80,7 +66,9 @@ exports.read = read;
|
|
80
66
|
function readButDoNotEvaluate(reference) {
|
81
67
|
var _a;
|
82
68
|
const response = readData(reference.readerArtifact.readerAst, reference.root, (_a = reference.variables) !== null && _a !== void 0 ? _a : {}, reference.nestedRefetchQueries);
|
83
|
-
|
69
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
70
|
+
console.log("done reading", { response });
|
71
|
+
}
|
84
72
|
if (response.kind === "MissingData") {
|
85
73
|
throw (0, cache_1.onNextChange)();
|
86
74
|
}
|
@@ -91,7 +79,7 @@ function readButDoNotEvaluate(reference) {
|
|
91
79
|
exports.readButDoNotEvaluate = readButDoNotEvaluate;
|
92
80
|
function readData(ast, root, variables, nestedRefetchQueries) {
|
93
81
|
var _a, _b, _c, _d;
|
94
|
-
let storeRecord = cache_1.
|
82
|
+
let storeRecord = (0, cache_1.getStore)()[root];
|
95
83
|
if (storeRecord === undefined) {
|
96
84
|
return { kind: "MissingData", reason: "No record for root " + root };
|
97
85
|
}
|
@@ -194,7 +182,9 @@ function readData(ast, root, variables, nestedRefetchQueries) {
|
|
194
182
|
const data = readData(field.readerArtifact.readerAst, root, variables,
|
195
183
|
// Refetch fields just read the id, and don't need refetch query artifacts
|
196
184
|
[]);
|
197
|
-
|
185
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
186
|
+
console.log("refetch field data", data, field);
|
187
|
+
}
|
198
188
|
if (data.kind === "MissingData") {
|
199
189
|
return {
|
200
190
|
kind: "MissingData",
|
@@ -218,7 +208,9 @@ function readData(ast, root, variables, nestedRefetchQueries) {
|
|
218
208
|
const data = readData(field.readerArtifact.readerAst, root, variables,
|
219
209
|
// Refetch fields just read the id, and don't need refetch query artifacts
|
220
210
|
[]);
|
221
|
-
|
211
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
212
|
+
console.log("refetch field data", data, field);
|
213
|
+
}
|
222
214
|
if (data.kind === "MissingData") {
|
223
215
|
return {
|
224
216
|
kind: "MissingData",
|
@@ -256,18 +248,7 @@ function readData(ast, root, variables, nestedRefetchQueries) {
|
|
256
248
|
}
|
257
249
|
}
|
258
250
|
else if (variant.kind === "Component") {
|
259
|
-
target[field.alias] = (
|
260
|
-
// TODO also incorporate the typename
|
261
|
-
const RefReaderForName = getRefReaderForName(variant.componentName);
|
262
|
-
// TODO do not create a new reference on every render?
|
263
|
-
return (react_1.default.createElement(RefReaderForName, { reference: {
|
264
|
-
kind: "FragmentReference",
|
265
|
-
readerArtifact: field.readerArtifact,
|
266
|
-
root,
|
267
|
-
variables,
|
268
|
-
nestedRefetchQueries: resolverRefetchQueries,
|
269
|
-
}, additionalRuntimeProps: additionalRuntimeProps }));
|
270
|
-
};
|
251
|
+
target[field.alias] = (0, componentCache_1.getOrCreateCachedComponent)(root, variant.componentName, "TODO", field.readerArtifact, variables, resolverRefetchQueries);
|
271
252
|
}
|
272
253
|
break;
|
273
254
|
}
|
@@ -311,19 +292,6 @@ function assertLink(link) {
|
|
311
292
|
}
|
312
293
|
throw new Error("Invalid link");
|
313
294
|
}
|
314
|
-
const refReaders = {};
|
315
|
-
function getRefReaderForName(name) {
|
316
|
-
if (refReaders[name] == null) {
|
317
|
-
function Component({ reference, additionalRuntimeProps, }) {
|
318
|
-
const data = readButDoNotEvaluate(reference);
|
319
|
-
return reference.readerArtifact.resolver(Object.assign({ data }, additionalRuntimeProps));
|
320
|
-
}
|
321
|
-
Component.displayName = `${name} @component`;
|
322
|
-
refReaders[name] = Component;
|
323
|
-
}
|
324
|
-
return refReaders[name];
|
325
|
-
}
|
326
|
-
exports.getRefReaderForName = getRefReaderForName;
|
327
295
|
function filterVariables(variables, allowedVariables) {
|
328
296
|
const result = {};
|
329
297
|
for (const key of allowedVariables) {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@isograph/react",
|
3
|
-
"version": "0.0.0-main-
|
3
|
+
"version": "0.0.0-main-ffab3426",
|
4
4
|
"description": "Use Isograph with React",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
@@ -15,8 +15,8 @@
|
|
15
15
|
"prepack": "yarn run test && yarn run compile"
|
16
16
|
},
|
17
17
|
"dependencies": {
|
18
|
-
"@isograph/disposable-types": "0.0.0-main-
|
19
|
-
"@isograph/react-disposable-state": "0.0.0-main-
|
18
|
+
"@isograph/disposable-types": "0.0.0-main-ffab3426",
|
19
|
+
"@isograph/react-disposable-state": "0.0.0-main-ffab3426",
|
20
20
|
"react": "^18.2.0"
|
21
21
|
},
|
22
22
|
"devDependencies": {
|
package/src/cache.ts
CHANGED
@@ -14,17 +14,25 @@ import {
|
|
14
14
|
RefetchQueryArtifactWrapper,
|
15
15
|
} from "./index";
|
16
16
|
|
17
|
+
declare global {
|
18
|
+
interface Window {
|
19
|
+
__LOG: boolean;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
17
23
|
const cache: { [index: string]: ParentCache<any> } = {};
|
18
24
|
|
19
25
|
function getOrCreateCache<T>(
|
20
26
|
index: string,
|
21
27
|
factory: Factory<T>
|
22
28
|
): ParentCache<T> {
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
29
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
30
|
+
console.log("getting cache for", {
|
31
|
+
index,
|
32
|
+
cache: Object.keys(cache),
|
33
|
+
found: !!cache[index],
|
34
|
+
});
|
35
|
+
}
|
28
36
|
if (cache[index] == null) {
|
29
37
|
cache[index] = new ParentCache(factory);
|
30
38
|
}
|
@@ -57,7 +65,7 @@ function stableCopy<T>(value: T): T {
|
|
57
65
|
type IsoResolver = IsographEntrypoint<any, any, any>;
|
58
66
|
|
59
67
|
export function getOrCreateCacheForArtifact<T>(
|
60
|
-
artifact:
|
68
|
+
artifact: IsographEntrypoint<any, any, T>,
|
61
69
|
variables: object
|
62
70
|
): ParentCache<PromiseWrapper<T>> {
|
63
71
|
const cacheKey = artifact.queryText + JSON.stringify(stableCopy(variables));
|
@@ -77,14 +85,18 @@ export function makeNetworkRequest<T>(
|
|
77
85
|
artifact: IsoResolver,
|
78
86
|
variables: object
|
79
87
|
): ItemCleanupPair<PromiseWrapper<T>> {
|
80
|
-
|
88
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
89
|
+
console.log("make network request", artifact, variables);
|
90
|
+
}
|
81
91
|
if (network == null) {
|
82
92
|
throw new Error("Network must be set before makeNetworkRequest is called");
|
83
93
|
}
|
84
94
|
|
85
95
|
const promise = network(artifact.queryText, variables).then(
|
86
96
|
(networkResponse) => {
|
87
|
-
|
97
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
98
|
+
console.log("network response", artifact);
|
99
|
+
}
|
88
100
|
normalizeData(
|
89
101
|
artifact.normalizationAst,
|
90
102
|
networkResponse.data,
|
@@ -133,12 +145,20 @@ export type StoreRecord = {
|
|
133
145
|
export type DataId = string;
|
134
146
|
|
135
147
|
export const ROOT_ID: DataId & "__ROOT" = "__ROOT";
|
136
|
-
|
148
|
+
let store: {
|
137
149
|
[index: DataId]: StoreRecord | null;
|
138
150
|
__ROOT: StoreRecord;
|
139
151
|
} = {
|
140
152
|
__ROOT: {},
|
141
153
|
};
|
154
|
+
export function getStore() {
|
155
|
+
return store;
|
156
|
+
}
|
157
|
+
export function clearStore() {
|
158
|
+
store = {
|
159
|
+
__ROOT: {},
|
160
|
+
};
|
161
|
+
}
|
142
162
|
|
143
163
|
type NetworkResponseScalarValue = string | number | boolean;
|
144
164
|
type NetworkResponseValue =
|
@@ -160,12 +180,14 @@ function normalizeData(
|
|
160
180
|
variables: Object,
|
161
181
|
nestedRefetchQueries: RefetchQueryArtifactWrapper[]
|
162
182
|
) {
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
183
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
184
|
+
console.log(
|
185
|
+
"about to normalize",
|
186
|
+
normalizationAst,
|
187
|
+
networkResponse,
|
188
|
+
variables
|
189
|
+
);
|
190
|
+
}
|
169
191
|
normalizeDataIntoRecord(
|
170
192
|
normalizationAst,
|
171
193
|
networkResponse,
|
@@ -174,7 +196,9 @@ function normalizeData(
|
|
174
196
|
variables as any,
|
175
197
|
nestedRefetchQueries
|
176
198
|
);
|
177
|
-
|
199
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
200
|
+
console.log("after normalization", { store });
|
201
|
+
}
|
178
202
|
callSubscriptions();
|
179
203
|
}
|
180
204
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import {
|
2
|
+
ReaderArtifact,
|
3
|
+
RefetchQueryArtifactWrapper,
|
4
|
+
readButDoNotEvaluate,
|
5
|
+
} from "./index";
|
6
|
+
import { DataId } from "./cache";
|
7
|
+
|
8
|
+
type ComponentName = string;
|
9
|
+
type StringifiedArgs = string;
|
10
|
+
const cachedComponentsById: {
|
11
|
+
[key: DataId]: {
|
12
|
+
[key: ComponentName]: { [key: StringifiedArgs]: React.FC<any> };
|
13
|
+
};
|
14
|
+
} = {};
|
15
|
+
export function getOrCreateCachedComponent(
|
16
|
+
root: DataId,
|
17
|
+
componentName: string,
|
18
|
+
stringifiedArgs: string,
|
19
|
+
readerArtifact: ReaderArtifact<any, any, any>,
|
20
|
+
variables: { [key: string]: string },
|
21
|
+
resolverRefetchQueries: RefetchQueryArtifactWrapper[]
|
22
|
+
) {
|
23
|
+
cachedComponentsById[root] = cachedComponentsById[root] ?? {};
|
24
|
+
const componentsByName = cachedComponentsById[root];
|
25
|
+
componentsByName[componentName] = componentsByName[componentName] ?? {};
|
26
|
+
const byArgs = componentsByName[componentName];
|
27
|
+
byArgs[stringifiedArgs] =
|
28
|
+
byArgs[stringifiedArgs] ??
|
29
|
+
(() => {
|
30
|
+
function Component(additionalRuntimeProps) {
|
31
|
+
const data = readButDoNotEvaluate({
|
32
|
+
kind: "FragmentReference",
|
33
|
+
readerArtifact: readerArtifact,
|
34
|
+
root,
|
35
|
+
variables,
|
36
|
+
nestedRefetchQueries: resolverRefetchQueries,
|
37
|
+
});
|
38
|
+
|
39
|
+
return readerArtifact.resolver({
|
40
|
+
data,
|
41
|
+
...additionalRuntimeProps,
|
42
|
+
});
|
43
|
+
}
|
44
|
+
Component.displayName = `${componentName} (id: ${root}) @component`;
|
45
|
+
return Component;
|
46
|
+
})();
|
47
|
+
return byArgs[stringifiedArgs];
|
48
|
+
}
|
package/src/index.tsx
CHANGED
@@ -6,12 +6,12 @@ import {
|
|
6
6
|
ROOT_ID,
|
7
7
|
getOrCreateCacheForArtifact,
|
8
8
|
onNextChange,
|
9
|
-
|
9
|
+
getStore,
|
10
10
|
getParentRecordKey,
|
11
11
|
} from "./cache";
|
12
12
|
import { useLazyDisposableState } from "@isograph/react-disposable-state";
|
13
13
|
import { type PromiseWrapper } from "./PromiseWrapper";
|
14
|
-
import
|
14
|
+
import { getOrCreateCachedComponent } from "./componentCache";
|
15
15
|
|
16
16
|
export {
|
17
17
|
setNetwork,
|
@@ -20,6 +20,7 @@ export {
|
|
20
20
|
DataId,
|
21
21
|
Link,
|
22
22
|
StoreRecord,
|
23
|
+
clearStore,
|
23
24
|
} from "./cache";
|
24
25
|
|
25
26
|
// This type should be treated as an opaque type.
|
@@ -205,12 +206,14 @@ export function useLazyReference<
|
|
205
206
|
>;
|
206
207
|
} {
|
207
208
|
// Typechecking fails here... TODO investigate
|
208
|
-
const cache = getOrCreateCacheForArtifact(
|
209
|
+
const cache = getOrCreateCacheForArtifact<TResolverResult>(
|
210
|
+
entrypoint,
|
211
|
+
variables
|
212
|
+
);
|
209
213
|
|
210
214
|
// TODO add comment explaining why we never use this value
|
211
215
|
// @ts-ignore
|
212
216
|
const data =
|
213
|
-
// @ts-ignore
|
214
217
|
useLazyDisposableState<PromiseWrapper<TResolverResult>>(cache).state;
|
215
218
|
|
216
219
|
return {
|
@@ -249,23 +252,15 @@ export function read<
|
|
249
252
|
return fragmentReference.readerArtifact.resolver(data.data);
|
250
253
|
}
|
251
254
|
} else if (variant.kind === "Component") {
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
root: fragmentReference.root,
|
262
|
-
variables: fragmentReference.variables,
|
263
|
-
nestedRefetchQueries: fragmentReference.nestedRefetchQueries,
|
264
|
-
}}
|
265
|
-
additionalRuntimeProps={additionalRuntimeProps}
|
266
|
-
/>
|
267
|
-
);
|
268
|
-
};
|
255
|
+
// @ts-ignore
|
256
|
+
return getOrCreateCachedComponent(
|
257
|
+
fragmentReference.root,
|
258
|
+
variant.componentName,
|
259
|
+
"TODO",
|
260
|
+
fragmentReference.readerArtifact,
|
261
|
+
fragmentReference.variables ?? {},
|
262
|
+
fragmentReference.nestedRefetchQueries
|
263
|
+
);
|
269
264
|
}
|
270
265
|
// Why can't Typescript realize that this is unreachable??
|
271
266
|
throw new Error("This is unreachable");
|
@@ -280,7 +275,9 @@ export function readButDoNotEvaluate<TReadFromStore extends Object>(
|
|
280
275
|
reference.variables ?? {},
|
281
276
|
reference.nestedRefetchQueries
|
282
277
|
);
|
283
|
-
|
278
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
279
|
+
console.log("done reading", { response });
|
280
|
+
}
|
284
281
|
if (response.kind === "MissingData") {
|
285
282
|
throw onNextChange();
|
286
283
|
} else {
|
@@ -305,7 +302,7 @@ function readData<TReadFromStore>(
|
|
305
302
|
variables: { [index: string]: string },
|
306
303
|
nestedRefetchQueries: RefetchQueryArtifactWrapper[]
|
307
304
|
): ReadDataResult<TReadFromStore> {
|
308
|
-
let storeRecord =
|
305
|
+
let storeRecord = getStore()[root];
|
309
306
|
if (storeRecord === undefined) {
|
310
307
|
return { kind: "MissingData", reason: "No record for root " + root };
|
311
308
|
}
|
@@ -431,7 +428,9 @@ function readData<TReadFromStore>(
|
|
431
428
|
// Refetch fields just read the id, and don't need refetch query artifacts
|
432
429
|
[]
|
433
430
|
);
|
434
|
-
|
431
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
432
|
+
console.log("refetch field data", data, field);
|
433
|
+
}
|
435
434
|
if (data.kind === "MissingData") {
|
436
435
|
return {
|
437
436
|
kind: "MissingData",
|
@@ -467,7 +466,9 @@ function readData<TReadFromStore>(
|
|
467
466
|
// Refetch fields just read the id, and don't need refetch query artifacts
|
468
467
|
[]
|
469
468
|
);
|
470
|
-
|
469
|
+
if (typeof window !== "undefined" && window.__LOG) {
|
470
|
+
console.log("refetch field data", data, field);
|
471
|
+
}
|
471
472
|
if (data.kind === "MissingData") {
|
472
473
|
return {
|
473
474
|
kind: "MissingData",
|
@@ -515,23 +516,14 @@ function readData<TReadFromStore>(
|
|
515
516
|
target[field.alias] = field.readerArtifact.resolver(data.data);
|
516
517
|
}
|
517
518
|
} else if (variant.kind === "Component") {
|
518
|
-
target[field.alias] = (
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
readerArtifact: field.readerArtifact,
|
527
|
-
root,
|
528
|
-
variables,
|
529
|
-
nestedRefetchQueries: resolverRefetchQueries,
|
530
|
-
}}
|
531
|
-
additionalRuntimeProps={additionalRuntimeProps}
|
532
|
-
/>
|
533
|
-
);
|
534
|
-
};
|
519
|
+
target[field.alias] = getOrCreateCachedComponent(
|
520
|
+
root,
|
521
|
+
variant.componentName,
|
522
|
+
"TODO",
|
523
|
+
field.readerArtifact,
|
524
|
+
variables,
|
525
|
+
resolverRefetchQueries
|
526
|
+
);
|
535
527
|
}
|
536
528
|
break;
|
537
529
|
}
|
@@ -605,29 +597,6 @@ function assertLink(link: DataTypeValue): Link | undefined | null {
|
|
605
597
|
throw new Error("Invalid link");
|
606
598
|
}
|
607
599
|
|
608
|
-
const refReaders: { [index: string]: any } = {};
|
609
|
-
export function getRefReaderForName(name: string) {
|
610
|
-
if (refReaders[name] == null) {
|
611
|
-
function Component({
|
612
|
-
reference,
|
613
|
-
additionalRuntimeProps,
|
614
|
-
}: {
|
615
|
-
reference: FragmentReference<any, any, any>;
|
616
|
-
additionalRuntimeProps: any;
|
617
|
-
}) {
|
618
|
-
const data = readButDoNotEvaluate(reference);
|
619
|
-
|
620
|
-
return reference.readerArtifact.resolver({
|
621
|
-
data,
|
622
|
-
...additionalRuntimeProps,
|
623
|
-
});
|
624
|
-
}
|
625
|
-
Component.displayName = `${name} @component`;
|
626
|
-
refReaders[name] = Component;
|
627
|
-
}
|
628
|
-
return refReaders[name];
|
629
|
-
}
|
630
|
-
|
631
600
|
export type IsographComponentProps<TDataType, TOtherProps = Object> = {
|
632
601
|
data: TDataType;
|
633
602
|
} & TOtherProps;
|