-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate-client-module-cache.js
More file actions
90 lines (76 loc) · 1.76 KB
/
Copy pathcreate-client-module-cache.js
File metadata and controls
90 lines (76 loc) · 1.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import invariant from "tiny-invariant";
import {
IS_MODULE,
MODULE_FETCH,
IS_MODULE_CACHE,
MODULE_CACHE_FETCH,
MODULE_PENDING,
MODULE_SUCCESS,
MODULE_FAILURE,
} from "./constants";
export default function createClientModuleCache() {
const entries = new Map();
function fetch(module) {
invariant(
module && typeof module === "object" && module[IS_MODULE],
"expected module to be an object returned by `createModule`",
);
const entry = entries.get(module);
if (entry) {
return entry;
} else {
return createEntry(module);
}
}
function createEntry(module) {
const entryPromise = module[MODULE_FETCH]().then(
data => {
const successEntry = {
status: MODULE_SUCCESS,
module: data,
};
entries.set(module, successEntry);
return successEntry;
},
error => {
const failureEntry = {
status: MODULE_FAILURE,
error,
};
entries.set(module, failureEntry);
return failureEntry;
},
);
const pendingEntry = {
status: MODULE_PENDING,
listen: cb => {
let isCanceled = false;
entryPromise.then(entry => {
if (!isCanceled) {
cb(entry);
}
});
return () => {
isCanceled = true;
};
},
};
entries.set(module, pendingEntry);
return pendingEntry;
}
function preload(module) {
const result = fetch(module);
if (result.status === MODULE_PENDING) {
return new Promise(resolve => {
result.listen(resolve);
});
} else {
return Promise.resolve(result);
}
}
return {
[IS_MODULE_CACHE]: true,
[MODULE_CACHE_FETCH]: fetch,
preload,
};
}