@khanacademy/wonder-blocks-data 2.3.0 → 2.3.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/dist/es/index.js +495 -892
- package/dist/index.js +783 -1071
- package/package.json +6 -5
- package/src/components/data.js +4 -6
- package/src/components/intercept-context.js +2 -3
- package/src/util/memory-cache.js +2 -1
- package/src/util/no-cache.js +2 -1
- package/src/util/request-handler.js +2 -1
- package/src/util/request-tracking.js +2 -3
- package/src/__tests__/index.test.js +0 -147
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-data",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.4",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -13,15 +13,16 @@
|
|
|
13
13
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@
|
|
16
|
+
"@babel/runtime": "^7.16.3",
|
|
17
|
+
"@khanacademy/wonder-blocks-core": "^4.0.0"
|
|
17
18
|
},
|
|
18
19
|
"peerDependencies": {
|
|
19
|
-
"react": "
|
|
20
|
+
"react": "16.14.0"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
|
-
"wb-dev-build-settings": "^0.0
|
|
23
|
+
"wb-dev-build-settings": "^0.2.0"
|
|
23
24
|
},
|
|
24
25
|
"author": "",
|
|
25
26
|
"license": "MIT",
|
|
26
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "9ebea88533e702011165072f090a377e02fa3f0f"
|
|
27
28
|
}
|
package/src/components/data.js
CHANGED
|
@@ -132,12 +132,10 @@ export default class Data<TOptions, TData: ValidData> extends React.Component<
|
|
|
132
132
|
{(value) => {
|
|
133
133
|
const handlerType = this.props.handler.type;
|
|
134
134
|
const interceptor = value[handlerType];
|
|
135
|
-
const handler =
|
|
136
|
-
interceptor
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
interceptor,
|
|
140
|
-
);
|
|
135
|
+
const handler =
|
|
136
|
+
this._getHandlerFromInterceptor(interceptor);
|
|
137
|
+
const getEntry =
|
|
138
|
+
this._getCacheLookupFnFromInterceptor(interceptor);
|
|
141
139
|
|
|
142
140
|
/**
|
|
143
141
|
* Need to share our types with InternalData so Flow
|
|
@@ -8,8 +8,7 @@ import type {InterceptContextData} from "../util/types.js";
|
|
|
8
8
|
*
|
|
9
9
|
* INTERNAL USE ONLY
|
|
10
10
|
*/
|
|
11
|
-
const InterceptContext: React.Context<InterceptContextData> =
|
|
12
|
-
{}
|
|
13
|
-
);
|
|
11
|
+
const InterceptContext: React.Context<InterceptContextData> =
|
|
12
|
+
React.createContext<InterceptContextData>({});
|
|
14
13
|
|
|
15
14
|
export default InterceptContext;
|
package/src/util/memory-cache.js
CHANGED
|
@@ -30,7 +30,8 @@ function deepClone<T: {...}>(source: T | $ReadOnly<T>): $ReadOnly<T> {
|
|
|
30
30
|
* absence of a custom cache. We use this for SSR too (see ./response-cache.js).
|
|
31
31
|
*/
|
|
32
32
|
export default class MemoryCache<TOptions, TData: ValidData>
|
|
33
|
-
implements ICache<TOptions, TData>
|
|
33
|
+
implements ICache<TOptions, TData>
|
|
34
|
+
{
|
|
34
35
|
_cache: Cache;
|
|
35
36
|
|
|
36
37
|
constructor(source: ?$ReadOnly<Cache> = null) {
|
package/src/util/no-cache.js
CHANGED
|
@@ -14,7 +14,8 @@ let defaultInstance: ?ICache<any, any> = null;
|
|
|
14
14
|
* requested data after hydration has finished.
|
|
15
15
|
*/
|
|
16
16
|
export default class NoCache<TOptions, TData: ValidData>
|
|
17
|
-
implements ICache<TOptions, TData>
|
|
17
|
+
implements ICache<TOptions, TData>
|
|
18
|
+
{
|
|
18
19
|
static get Default(): ICache<TOptions, TData> {
|
|
19
20
|
if (defaultInstance == null) {
|
|
20
21
|
defaultInstance = new NoCache<TOptions, TData>();
|
|
@@ -8,7 +8,8 @@ import type {ValidData, CacheEntry, IRequestHandler, ICache} from "./types.js";
|
|
|
8
8
|
* use with the Wonder Blocks Data framework.
|
|
9
9
|
*/
|
|
10
10
|
export default class RequestHandler<TOptions, TData: ValidData>
|
|
11
|
-
implements IRequestHandler<TOptions, TData>
|
|
11
|
+
implements IRequestHandler<TOptions, TData>
|
|
12
|
+
{
|
|
12
13
|
_type: string;
|
|
13
14
|
_cache: ?ICache<TOptions, TData>;
|
|
14
15
|
_hydrate: boolean;
|
|
@@ -25,9 +25,8 @@ type RequestCache = {
|
|
|
25
25
|
*
|
|
26
26
|
* INTERNAL USE ONLY
|
|
27
27
|
*/
|
|
28
|
-
export const TrackerContext: React.Context<?TrackerFn> =
|
|
29
|
-
null
|
|
30
|
-
);
|
|
28
|
+
export const TrackerContext: React.Context<?TrackerFn> =
|
|
29
|
+
new React.createContext<?TrackerFn>(null);
|
|
31
30
|
|
|
32
31
|
/**
|
|
33
32
|
* The default instance is stored here.
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
import {Server} from "@khanacademy/wonder-blocks-core";
|
|
3
|
-
import {
|
|
4
|
-
initializeCache,
|
|
5
|
-
fulfillAllDataRequests,
|
|
6
|
-
hasUnfulfilledRequests,
|
|
7
|
-
removeFromCache,
|
|
8
|
-
removeAllFromCache,
|
|
9
|
-
} from "../index.js";
|
|
10
|
-
import {ResponseCache} from "../util/response-cache.js";
|
|
11
|
-
import {RequestTracker} from "../util/request-tracking.js";
|
|
12
|
-
|
|
13
|
-
import type {IRequestHandler, ResponseCache as Cache} from "../index.js";
|
|
14
|
-
|
|
15
|
-
describe("@khanacademy/wonder-blocks-data", () => {
|
|
16
|
-
test("package exports what we expect", async () => {
|
|
17
|
-
// Arrange
|
|
18
|
-
const importedModule = import("../index.js");
|
|
19
|
-
|
|
20
|
-
// Act
|
|
21
|
-
const result = await importedModule;
|
|
22
|
-
|
|
23
|
-
// Assert
|
|
24
|
-
expect(Object.keys(result).sort()).toEqual(
|
|
25
|
-
[
|
|
26
|
-
"Data",
|
|
27
|
-
"InterceptCache",
|
|
28
|
-
"InterceptData",
|
|
29
|
-
"NoCache",
|
|
30
|
-
"RequestHandler",
|
|
31
|
-
"TrackData",
|
|
32
|
-
"hasUnfulfilledRequests",
|
|
33
|
-
"fulfillAllDataRequests",
|
|
34
|
-
"initializeCache",
|
|
35
|
-
"removeFromCache",
|
|
36
|
-
"removeAllFromCache",
|
|
37
|
-
].sort(),
|
|
38
|
-
);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
describe("#initializeCache", () => {
|
|
42
|
-
test("invokes ResponseCache.Default.initialize", () => {
|
|
43
|
-
// Arrange
|
|
44
|
-
const initializeSpy = jest.spyOn(
|
|
45
|
-
ResponseCache.Default,
|
|
46
|
-
"initialize",
|
|
47
|
-
);
|
|
48
|
-
const cache: Cache = ({}: any);
|
|
49
|
-
|
|
50
|
-
// Act
|
|
51
|
-
initializeCache(cache);
|
|
52
|
-
|
|
53
|
-
// Assert
|
|
54
|
-
expect(initializeSpy).toHaveBeenCalledWith(cache);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe("#fulfillAllDataRequests", () => {
|
|
59
|
-
test("when server-side, invokes RequestTracker.Default.fulfillTrackedRequests", () => {
|
|
60
|
-
// Arrange
|
|
61
|
-
jest.spyOn(Server, "isServerSide").mockReturnValue(true);
|
|
62
|
-
const fulfillTrackedRequests = jest.spyOn(
|
|
63
|
-
RequestTracker.Default,
|
|
64
|
-
"fulfillTrackedRequests",
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
// Act
|
|
68
|
-
fulfillAllDataRequests();
|
|
69
|
-
|
|
70
|
-
// Assert
|
|
71
|
-
expect(fulfillTrackedRequests).toHaveBeenCalled();
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
test("when client-side, rejects with error", async () => {
|
|
75
|
-
// Arrange
|
|
76
|
-
jest.spyOn(Server, "isServerSide").mockReturnValue(false);
|
|
77
|
-
|
|
78
|
-
// Act
|
|
79
|
-
const underTest = fulfillAllDataRequests();
|
|
80
|
-
|
|
81
|
-
// Assert
|
|
82
|
-
await expect(underTest).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
83
|
-
`"Data requests are not tracked when client-side"`,
|
|
84
|
-
);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
describe("#hasUnfulfilledRequests", () => {
|
|
89
|
-
test("when server-side, invokes RequestTracker.Default.hasUnfulfilledRequests", () => {
|
|
90
|
-
// Arrange
|
|
91
|
-
jest.spyOn(Server, "isServerSide").mockReturnValue(true);
|
|
92
|
-
const hasUnfulfilledRequestsSpy = jest.spyOn(
|
|
93
|
-
RequestTracker.Default,
|
|
94
|
-
"hasUnfulfilledRequests",
|
|
95
|
-
"get",
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
// Act
|
|
99
|
-
hasUnfulfilledRequests();
|
|
100
|
-
|
|
101
|
-
// Assert
|
|
102
|
-
expect(hasUnfulfilledRequestsSpy).toHaveBeenCalled();
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
test("when client-side, rejects with error", () => {
|
|
106
|
-
// Arrange
|
|
107
|
-
jest.spyOn(Server, "isServerSide").mockReturnValue(false);
|
|
108
|
-
|
|
109
|
-
// Act
|
|
110
|
-
const underTest = () => hasUnfulfilledRequests();
|
|
111
|
-
|
|
112
|
-
// Assert
|
|
113
|
-
expect(underTest).toThrowErrorMatchingInlineSnapshot(
|
|
114
|
-
`"Data requests are not tracked when client-side"`,
|
|
115
|
-
);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
describe("#removeFromCache", () => {
|
|
120
|
-
test("invokes ResponseCache.Default.remove", () => {
|
|
121
|
-
// Arrange
|
|
122
|
-
const removeSpy = jest.spyOn(ResponseCache.Default, "remove");
|
|
123
|
-
const fakeHandler: IRequestHandler<string, string> = ({}: any);
|
|
124
|
-
|
|
125
|
-
// Act
|
|
126
|
-
removeFromCache(fakeHandler, "REMOVE");
|
|
127
|
-
|
|
128
|
-
// Assert
|
|
129
|
-
expect(removeSpy).toHaveBeenCalledWith(fakeHandler, "REMOVE");
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
describe("#removeAllFromCache", () => {
|
|
134
|
-
test("invokes ResponseCache.Default.removeAll", () => {
|
|
135
|
-
// Arrange
|
|
136
|
-
const removeAllSpy = jest.spyOn(ResponseCache.Default, "removeAll");
|
|
137
|
-
const fakeHandler: IRequestHandler<string, string> = ({}: any);
|
|
138
|
-
const predicate = () => false;
|
|
139
|
-
|
|
140
|
-
// Act
|
|
141
|
-
removeAllFromCache(fakeHandler, predicate);
|
|
142
|
-
|
|
143
|
-
// Assert
|
|
144
|
-
expect(removeAllSpy).toHaveBeenCalledWith(fakeHandler, predicate);
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
});
|