@khanacademy/wonder-blocks-data 13.0.11 → 13.0.12
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/CHANGELOG.md +8 -0
- package/package.json +3 -3
- package/src/components/__tests__/data.test.tsx +0 -832
- package/src/components/__tests__/gql-router.test.tsx +0 -63
- package/src/components/__tests__/intercept-requests.test.tsx +0 -57
- package/src/components/__tests__/track-data.test.tsx +0 -56
- package/src/components/data.ts +0 -73
- package/src/components/gql-router.tsx +0 -63
- package/src/components/intercept-context.ts +0 -19
- package/src/components/intercept-requests.tsx +0 -67
- package/src/components/track-data.tsx +0 -28
- package/src/hooks/__tests__/__snapshots__/use-shared-cache.test.ts.snap +0 -17
- package/src/hooks/__tests__/use-cached-effect.test.tsx +0 -789
- package/src/hooks/__tests__/use-gql-router-context.test.tsx +0 -132
- package/src/hooks/__tests__/use-gql.test.tsx +0 -204
- package/src/hooks/__tests__/use-hydratable-effect.test.ts +0 -708
- package/src/hooks/__tests__/use-request-interception.test.tsx +0 -254
- package/src/hooks/__tests__/use-server-effect.test.ts +0 -293
- package/src/hooks/__tests__/use-shared-cache.test.ts +0 -263
- package/src/hooks/use-cached-effect.ts +0 -297
- package/src/hooks/use-gql-router-context.ts +0 -49
- package/src/hooks/use-gql.ts +0 -58
- package/src/hooks/use-hydratable-effect.ts +0 -201
- package/src/hooks/use-request-interception.ts +0 -53
- package/src/hooks/use-server-effect.ts +0 -75
- package/src/hooks/use-shared-cache.ts +0 -107
- package/src/index.ts +0 -46
- package/src/util/__tests__/__snapshots__/scoped-in-memory-cache.test.ts.snap +0 -19
- package/src/util/__tests__/__snapshots__/serializable-in-memory-cache.test.ts.snap +0 -19
- package/src/util/__tests__/get-gql-data-from-response.test.ts +0 -186
- package/src/util/__tests__/get-gql-request-id.test.ts +0 -132
- package/src/util/__tests__/graphql-document-node-parser.test.ts +0 -535
- package/src/util/__tests__/hydration-cache-api.test.ts +0 -34
- package/src/util/__tests__/merge-gql-context.test.ts +0 -73
- package/src/util/__tests__/purge-caches.test.ts +0 -28
- package/src/util/__tests__/request-api.test.ts +0 -176
- package/src/util/__tests__/request-fulfillment.test.ts +0 -146
- package/src/util/__tests__/request-tracking.test.tsx +0 -321
- package/src/util/__tests__/result-from-cache-response.test.ts +0 -79
- package/src/util/__tests__/scoped-in-memory-cache.test.ts +0 -316
- package/src/util/__tests__/serializable-in-memory-cache.test.ts +0 -397
- package/src/util/__tests__/ssr-cache.test.ts +0 -636
- package/src/util/__tests__/to-gql-operation.test.ts +0 -41
- package/src/util/data-error.ts +0 -63
- package/src/util/get-gql-data-from-response.ts +0 -65
- package/src/util/get-gql-request-id.ts +0 -106
- package/src/util/gql-error.ts +0 -43
- package/src/util/gql-router-context.ts +0 -9
- package/src/util/gql-types.ts +0 -64
- package/src/util/graphql-document-node-parser.ts +0 -132
- package/src/util/graphql-types.ts +0 -28
- package/src/util/hydration-cache-api.ts +0 -30
- package/src/util/merge-gql-context.ts +0 -35
- package/src/util/purge-caches.ts +0 -14
- package/src/util/request-api.ts +0 -65
- package/src/util/request-fulfillment.ts +0 -121
- package/src/util/request-tracking.ts +0 -211
- package/src/util/result-from-cache-response.ts +0 -30
- package/src/util/scoped-in-memory-cache.ts +0 -121
- package/src/util/serializable-in-memory-cache.ts +0 -44
- package/src/util/ssr-cache.ts +0 -193
- package/src/util/status.ts +0 -35
- package/src/util/to-gql-operation.ts +0 -43
- package/src/util/types.ts +0 -145
- package/tsconfig-build.json +0 -12
- package/tsconfig-build.tsbuildinfo +0 -1
|
@@ -1,397 +0,0 @@
|
|
|
1
|
-
import * as WSCore from "@khanacademy/wonder-stuff-core";
|
|
2
|
-
import {SerializableInMemoryCache} from "../serializable-in-memory-cache";
|
|
3
|
-
|
|
4
|
-
describe("SerializableInMemoryCache", () => {
|
|
5
|
-
describe("#constructor", () => {
|
|
6
|
-
it("should clone the passed source data", () => {
|
|
7
|
-
// Arrange
|
|
8
|
-
const sourceData = {
|
|
9
|
-
scope: {
|
|
10
|
-
key: "value",
|
|
11
|
-
},
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
// Act
|
|
15
|
-
const cache = new SerializableInMemoryCache(sourceData);
|
|
16
|
-
// Try to mutate the cache.
|
|
17
|
-
sourceData["scope"] = {key: "SOME_NEW_DATA"};
|
|
18
|
-
const result = cache.get("scope", "key");
|
|
19
|
-
|
|
20
|
-
// Assert
|
|
21
|
-
expect(result).toStrictEqual("value");
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it("should throw if the cloning fails", () => {
|
|
25
|
-
// Arrange
|
|
26
|
-
jest.spyOn(WSCore, "clone").mockImplementationOnce(() => {
|
|
27
|
-
throw new Error("BANG!");
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
// Act
|
|
31
|
-
const underTest = () =>
|
|
32
|
-
new SerializableInMemoryCache({
|
|
33
|
-
scope: {
|
|
34
|
-
BAD: "FOOD",
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// Assert
|
|
39
|
-
expect(underTest).toThrowErrorMatchingInlineSnapshot(
|
|
40
|
-
`"An error occurred trying to initialize from a response cache snapshot: Error: BANG!"`,
|
|
41
|
-
);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
describe("#set", () => {
|
|
46
|
-
it.each`
|
|
47
|
-
id
|
|
48
|
-
${null}
|
|
49
|
-
${""}
|
|
50
|
-
${5}
|
|
51
|
-
${() => "BOO"}
|
|
52
|
-
`("should throw if the id is $id", ({id}: any) => {
|
|
53
|
-
// Arrange
|
|
54
|
-
const cache = new SerializableInMemoryCache();
|
|
55
|
-
|
|
56
|
-
// Act
|
|
57
|
-
const underTest = () => cache.set("scope", id, "value");
|
|
58
|
-
|
|
59
|
-
// Assert
|
|
60
|
-
expect(underTest).toThrowErrorMatchingSnapshot();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it.each`
|
|
64
|
-
scope
|
|
65
|
-
${null}
|
|
66
|
-
${""}
|
|
67
|
-
${5}
|
|
68
|
-
${() => "BOO"}
|
|
69
|
-
`("should throw if the scope is $scope", ({scope}: any) => {
|
|
70
|
-
// Arrange
|
|
71
|
-
const cache = new SerializableInMemoryCache();
|
|
72
|
-
|
|
73
|
-
// Act
|
|
74
|
-
const underTest = () => cache.set(scope, "key", "value");
|
|
75
|
-
|
|
76
|
-
// Assert
|
|
77
|
-
expect(underTest).toThrowErrorMatchingSnapshot();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it("should throw if the value is a function", () => {
|
|
81
|
-
// Arrange
|
|
82
|
-
const cache = new SerializableInMemoryCache();
|
|
83
|
-
|
|
84
|
-
// Act
|
|
85
|
-
const underTest = () => cache.set("scope", "key", () => "value");
|
|
86
|
-
|
|
87
|
-
// Assert
|
|
88
|
-
expect(underTest).toThrowErrorMatchingSnapshot();
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it("should store the entry in the cache", () => {
|
|
92
|
-
// Arrange
|
|
93
|
-
const cache = new SerializableInMemoryCache();
|
|
94
|
-
|
|
95
|
-
// Act
|
|
96
|
-
cache.set("scope", "key", "data");
|
|
97
|
-
const result = cache.get("scope", "key");
|
|
98
|
-
|
|
99
|
-
// Assert
|
|
100
|
-
expect(result).toStrictEqual("data");
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it("should replace the entry in the cache", () => {
|
|
104
|
-
// Arrange
|
|
105
|
-
const cache = new SerializableInMemoryCache({
|
|
106
|
-
scope: {
|
|
107
|
-
key: "data",
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
// Act
|
|
112
|
-
cache.set("scope", "key", "other_data");
|
|
113
|
-
const result = cache.get("scope", "key");
|
|
114
|
-
|
|
115
|
-
// Assert
|
|
116
|
-
expect(result).toStrictEqual("other_data");
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
describe("#retrieve", () => {
|
|
121
|
-
it("should return null if the scope is not cached", () => {
|
|
122
|
-
// Arrange
|
|
123
|
-
const cache = new SerializableInMemoryCache();
|
|
124
|
-
|
|
125
|
-
// Act
|
|
126
|
-
const result = cache.get("scope", "key");
|
|
127
|
-
|
|
128
|
-
// Assert
|
|
129
|
-
expect(result).toBeNull();
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it("should return null if the value is not in the cache scope", () => {
|
|
133
|
-
// Arrange
|
|
134
|
-
const cache = new SerializableInMemoryCache({
|
|
135
|
-
scope: {
|
|
136
|
-
key1: "data",
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// Act
|
|
141
|
-
const result = cache.get("scope", "key2");
|
|
142
|
-
|
|
143
|
-
// Assert
|
|
144
|
-
expect(result).toBeNull();
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
it("should return the entry if it exists", () => {
|
|
148
|
-
// Arrange
|
|
149
|
-
const cache = new SerializableInMemoryCache({
|
|
150
|
-
scope: {key: "value"},
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
// Act
|
|
154
|
-
const result = cache.get("scope", "key");
|
|
155
|
-
|
|
156
|
-
// Assert
|
|
157
|
-
expect(result).toStrictEqual("value");
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
describe("#purge", () => {
|
|
162
|
-
it("should remove the entry", () => {
|
|
163
|
-
// Arrange
|
|
164
|
-
const cache = new SerializableInMemoryCache({
|
|
165
|
-
scope1: {
|
|
166
|
-
key1: "data1",
|
|
167
|
-
key2: "data2",
|
|
168
|
-
},
|
|
169
|
-
scope2: {
|
|
170
|
-
key1: "data1",
|
|
171
|
-
key2: "data2",
|
|
172
|
-
},
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// Act
|
|
176
|
-
cache.purge("scope1", "key2");
|
|
177
|
-
const result = cache.clone();
|
|
178
|
-
|
|
179
|
-
// Assert
|
|
180
|
-
expect(result).toStrictEqual({
|
|
181
|
-
scope1: {
|
|
182
|
-
key1: "data1",
|
|
183
|
-
},
|
|
184
|
-
scope2: {
|
|
185
|
-
key1: "data1",
|
|
186
|
-
key2: "data2",
|
|
187
|
-
},
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it("should remove the entire scope if the purged item is the last item in the scope", () => {
|
|
192
|
-
const cache = new SerializableInMemoryCache({
|
|
193
|
-
scope1: {
|
|
194
|
-
key2: "data2",
|
|
195
|
-
},
|
|
196
|
-
scope2: {
|
|
197
|
-
key1: "data1",
|
|
198
|
-
key2: "data2",
|
|
199
|
-
},
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// Act
|
|
203
|
-
cache.purge("scope1", "key2");
|
|
204
|
-
const result = cache.clone();
|
|
205
|
-
|
|
206
|
-
// Assert
|
|
207
|
-
expect(result).toStrictEqual({
|
|
208
|
-
scope2: {
|
|
209
|
-
key1: "data1",
|
|
210
|
-
key2: "data2",
|
|
211
|
-
},
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
describe("#purgeScope", () => {
|
|
217
|
-
it("should remove matching entries only", () => {
|
|
218
|
-
// Arrange
|
|
219
|
-
const cache = new SerializableInMemoryCache({
|
|
220
|
-
scope1: {
|
|
221
|
-
key1: "a",
|
|
222
|
-
key2: "b",
|
|
223
|
-
key3: "a",
|
|
224
|
-
},
|
|
225
|
-
scope2: {
|
|
226
|
-
key1: "a",
|
|
227
|
-
key2: "b",
|
|
228
|
-
key3: "a",
|
|
229
|
-
},
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
// Act
|
|
233
|
-
cache.purgeScope("scope1", (id: any, value: any) => value === "a");
|
|
234
|
-
const result = cache.clone();
|
|
235
|
-
|
|
236
|
-
// Assert
|
|
237
|
-
expect(result).toStrictEqual({
|
|
238
|
-
scope1: {
|
|
239
|
-
key2: "b",
|
|
240
|
-
},
|
|
241
|
-
scope2: {
|
|
242
|
-
key1: "a",
|
|
243
|
-
key2: "b",
|
|
244
|
-
key3: "a",
|
|
245
|
-
},
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
it("should remove the entire scope when there is no predicate", () => {
|
|
250
|
-
// Arrange
|
|
251
|
-
const cache = new SerializableInMemoryCache({
|
|
252
|
-
scope1: {
|
|
253
|
-
key1: "data1",
|
|
254
|
-
key2: "data2",
|
|
255
|
-
},
|
|
256
|
-
scope2: {
|
|
257
|
-
key1: "data1",
|
|
258
|
-
key2: "data2",
|
|
259
|
-
},
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
// Act
|
|
263
|
-
cache.purgeScope("scope1");
|
|
264
|
-
const result = cache.clone();
|
|
265
|
-
|
|
266
|
-
// Assert
|
|
267
|
-
expect(result).toStrictEqual({
|
|
268
|
-
scope2: {
|
|
269
|
-
key1: "data1",
|
|
270
|
-
key2: "data2",
|
|
271
|
-
},
|
|
272
|
-
});
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
it("should not throw if the scope does not exist", () => {
|
|
276
|
-
// Arrange
|
|
277
|
-
const cache = new SerializableInMemoryCache({
|
|
278
|
-
scope1: {
|
|
279
|
-
key1: "data1",
|
|
280
|
-
},
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
// Act
|
|
284
|
-
const act = () => cache.purgeScope("scope2");
|
|
285
|
-
|
|
286
|
-
// Arrange
|
|
287
|
-
expect(act).not.toThrow();
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
describe("#purgeAll", () => {
|
|
292
|
-
it("should remove matching entries only", () => {
|
|
293
|
-
const cache = new SerializableInMemoryCache({
|
|
294
|
-
scope1: {key: "2"},
|
|
295
|
-
scope2: {key: "1"},
|
|
296
|
-
scope3: {key: "2"},
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
// Act
|
|
300
|
-
cache.purgeAll((scope: any, id: any, value: any) => value === "2");
|
|
301
|
-
const result = cache.clone();
|
|
302
|
-
|
|
303
|
-
// Assert
|
|
304
|
-
expect(result).toStrictEqual({
|
|
305
|
-
scope2: {key: "1"},
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
it("should remove the all items if there is no predicate", () => {
|
|
310
|
-
const cache = new SerializableInMemoryCache({
|
|
311
|
-
scope1: {key: "2"},
|
|
312
|
-
scope2: {key: "1"},
|
|
313
|
-
scope3: {key: "2"},
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
// Act
|
|
317
|
-
cache.purgeAll();
|
|
318
|
-
const result = cache.clone();
|
|
319
|
-
|
|
320
|
-
// Assert
|
|
321
|
-
expect(result).toStrictEqual({});
|
|
322
|
-
});
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
describe("#clone", () => {
|
|
326
|
-
it("should return a copy of the cache data", () => {
|
|
327
|
-
// Arrange
|
|
328
|
-
const data = {
|
|
329
|
-
scope1: {key: "2"},
|
|
330
|
-
scope2: {key: "1"},
|
|
331
|
-
scope3: {key: "2"},
|
|
332
|
-
} as const;
|
|
333
|
-
const cache = new SerializableInMemoryCache(data);
|
|
334
|
-
|
|
335
|
-
// Act
|
|
336
|
-
const result = cache.clone();
|
|
337
|
-
|
|
338
|
-
// Assert
|
|
339
|
-
expect(result).not.toBe(data);
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
it("should throw if there is an error during cloning", () => {
|
|
343
|
-
// Arrange
|
|
344
|
-
const cache = new SerializableInMemoryCache({
|
|
345
|
-
scope1: {key: "2"},
|
|
346
|
-
scope2: {key: "1"},
|
|
347
|
-
scope3: {key: "2"},
|
|
348
|
-
});
|
|
349
|
-
jest.spyOn(WSCore, "clone").mockImplementationOnce(() => {
|
|
350
|
-
throw new Error("BANG!");
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
// Act
|
|
354
|
-
const act = () => cache.clone();
|
|
355
|
-
|
|
356
|
-
// Assert
|
|
357
|
-
expect(act).toThrowErrorMatchingInlineSnapshot(`
|
|
358
|
-
"An error occurred while trying to clone the cache
|
|
359
|
-
caused by
|
|
360
|
-
Error: BANG!"
|
|
361
|
-
`);
|
|
362
|
-
});
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
describe("@inUse", () => {
|
|
366
|
-
it("should return true if the cache contains data", () => {
|
|
367
|
-
// Arrange
|
|
368
|
-
const cache = new SerializableInMemoryCache({
|
|
369
|
-
scope1: {key: "2"},
|
|
370
|
-
scope2: {key: "1"},
|
|
371
|
-
scope3: {key: "2"},
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
// Act
|
|
375
|
-
const result = cache.inUse;
|
|
376
|
-
|
|
377
|
-
// Assert
|
|
378
|
-
expect(result).toBeTruthy();
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
it("should return false if the cache is empty", () => {
|
|
382
|
-
// Arrange
|
|
383
|
-
const cache = new SerializableInMemoryCache({
|
|
384
|
-
scope1: {key: "2"},
|
|
385
|
-
scope2: {key: "1"},
|
|
386
|
-
scope3: {key: "2"},
|
|
387
|
-
});
|
|
388
|
-
cache.purgeAll();
|
|
389
|
-
|
|
390
|
-
// Act
|
|
391
|
-
const result = cache.inUse;
|
|
392
|
-
|
|
393
|
-
// Assert
|
|
394
|
-
expect(result).toBeFalsy();
|
|
395
|
-
});
|
|
396
|
-
});
|
|
397
|
-
});
|