-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate-server-module-cache.js
More file actions
117 lines (100 loc) · 2.49 KB
/
Copy pathcreate-server-module-cache.js
File metadata and controls
117 lines (100 loc) · 2.49 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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import invariant from "tiny-invariant";
import {
IS_MODULE,
MODULE_FETCH,
MODULE_CHUNK_NAME,
IS_MODULE_CACHE,
MODULE_CACHE_FETCH,
MODULE_PENDING,
MODULE_SUCCESS,
MODULE_FAILURE,
} from "./constants";
export default function createServerModuleCache() {
const entries = new Map();
const chunks = new Set();
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 {
const pendingEntry = {
status: MODULE_PENDING,
listen,
};
entries.set(module, pendingEntry);
return pendingEntry;
}
}
function preload(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) {
if (entry.status === MODULE_PENDING) {
if (entry.promise) {
return entry.promise;
} else {
return createEntry(module);
}
} else {
return Promise.resolve(entry);
}
} else {
return createEntry(module);
}
}
function createEntry(module) {
const chunkName = module[MODULE_CHUNK_NAME];
invariant(
chunkName,
"expected module chunk name to be present\n" +
"did you try preloading a module without specifying a chunk name?",
);
chunks.add(chunkName);
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,
promise: entryPromise,
};
entries.set(module, pendingEntry);
return entryPromise;
}
function listen() {
invariant(
false,
"cannot listen to entry of server module cache\n" +
"did you try to use a server module cache " +
"outside a server-rendering context?",
);
}
return {
[IS_MODULE_CACHE]: true,
[MODULE_CACHE_FETCH]: fetch,
preload,
chunks: () => [...chunks],
};
}