@jundle/cloudflare 0.0.1-13 → 0.0.1-15
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/package.json +1 -1
- package/src/harness.js +71 -4
package/package.json
CHANGED
package/src/harness.js
CHANGED
|
@@ -146,8 +146,10 @@ async function fetchJson(url) {
|
|
|
146
146
|
|
|
147
147
|
// Pull-based invalidation (SPEC §16.11): one loopback fetch per
|
|
148
148
|
// dispatch. Evicts invalidated dev-module keys (evaluated +
|
|
149
|
-
// text) and JSON values for edited JSON files,
|
|
150
|
-
//
|
|
149
|
+
// text) and JSON values for edited JSON files, and rebuilt
|
|
150
|
+
// dep files (dep text + evaluated deps, plus every app
|
|
151
|
+
// module — SPEC §16.5), then advances the seen version.
|
|
152
|
+
// The dev server prunes acked batches.
|
|
151
153
|
// After eviction, pushes fresh SSR-variant instances for the
|
|
152
154
|
// browser-env subset (see pushSsrUpdates) before the entry
|
|
153
155
|
// re-imports, so the entry's decode already sees them.
|
|
@@ -168,6 +170,37 @@ async function syncVersion() {
|
|
|
168
170
|
if (k.split("\0")[1] === file) assetValueCache.delete(k);
|
|
169
171
|
}
|
|
170
172
|
}
|
|
173
|
+
// Dep invalidation (SPEC §16.5, §16.11): an on-demand
|
|
174
|
+
// unification run rebuilt existing dep bundles (same
|
|
175
|
+
// URL, new bytes) or remapped existing specs (the old
|
|
176
|
+
// files are dead). Evict the changed dep text —
|
|
177
|
+
// bundle-dir units share the entry's `file\0rel`
|
|
178
|
+
// prefix — then clear every evaluated module, app and
|
|
179
|
+
// dep alike (mirrors NodeRunner.invalidateAll).
|
|
180
|
+
// Evaluated app modules may hold the old dep exports,
|
|
181
|
+
// the closure walk prunes cached subtrees, and dep
|
|
182
|
+
// modules hold state coupled to the app modules (the
|
|
183
|
+
// Flight client's chunk map assumes the shim's cache
|
|
184
|
+
// outlives it — clearing the shim without the client
|
|
185
|
+
// makes the client require a chunk the fresh shim
|
|
186
|
+
// never loaded). Only the TEXT eviction is targeted:
|
|
187
|
+
// unchanged dep text is still valid input, so it
|
|
188
|
+
// stays cached and no re-fetch is needed for it. The
|
|
189
|
+
// fresh text is fetched lazily by the next entry
|
|
190
|
+
// import, not eagerly here: a re-fetch failure after
|
|
191
|
+
// the version advanced would leave the dep
|
|
192
|
+
// permanently broken until restart.
|
|
193
|
+
const depFiles = data.depFiles || [];
|
|
194
|
+
if (depFiles.length > 0) {
|
|
195
|
+
for (const file of depFiles) {
|
|
196
|
+
for (const k of depText.keys()) {
|
|
197
|
+
if (k === file || k.startsWith(`${file}\0`)) depText.delete(k);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
evaluated.clear();
|
|
201
|
+
textCache.clear();
|
|
202
|
+
depEvaluated.clear();
|
|
203
|
+
}
|
|
171
204
|
await pushSsrUpdates(data.clientInvalidated || []);
|
|
172
205
|
}
|
|
173
206
|
|
|
@@ -187,16 +220,50 @@ async function syncVersion() {
|
|
|
187
220
|
// document in a worker), and surfacing it would trip the
|
|
188
221
|
// hot client's first-update overlay rule and force a full
|
|
189
222
|
// reload on the next update instead of HMR.
|
|
223
|
+
//
|
|
224
|
+
// The re-import can install a second (browser) shim over
|
|
225
|
+
// the dev shim's globals — client.browser.js imports
|
|
226
|
+
// ./shim.js first, so any module importing the client
|
|
227
|
+
// runtime installs it as a side effect — and the
|
|
228
|
+
// client's chunkCache skips re-loading chunks, so a
|
|
229
|
+
// poisoned global makes the next render require through
|
|
230
|
+
// an empty shim ("has not been loaded yet"). Snapshot the
|
|
231
|
+
// four shim globals before the re-import and restore
|
|
232
|
+
// them before the push lands (finally, so a failed
|
|
233
|
+
// import cannot leave them poisoned). A snapshot of
|
|
234
|
+
// undefined restores by deleting the global, not by
|
|
235
|
+
// assigning undefined (the shim was not installed yet).
|
|
236
|
+
const SHIM_GLOBALS = [
|
|
237
|
+
"__webpack_require__",
|
|
238
|
+
"__webpack_chunk_load__",
|
|
239
|
+
"__webpack_get_script_filename__",
|
|
240
|
+
"__jundleFlight",
|
|
241
|
+
];
|
|
242
|
+
function snapshotShimGlobals() {
|
|
243
|
+
return SHIM_GLOBALS.map((name) => [name, globalThis[name]]);
|
|
244
|
+
}
|
|
245
|
+
function restoreShimGlobals(saved) {
|
|
246
|
+
for (const [name, value] of saved) {
|
|
247
|
+
if (value === undefined) delete globalThis[name];
|
|
248
|
+
else globalThis[name] = value;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
190
251
|
async function pushSsrUpdates(clientKeys) {
|
|
191
252
|
for (const key of clientKeys) {
|
|
192
253
|
const [env, file] = key.split("\0");
|
|
193
254
|
const url = `/@jundle/module?env=${encodeURIComponent(env)}&file=${encodeURIComponent(file)}`;
|
|
255
|
+
const saved = snapshotShimGlobals();
|
|
256
|
+
let rec;
|
|
257
|
+
let ok = false;
|
|
194
258
|
try {
|
|
195
|
-
|
|
196
|
-
|
|
259
|
+
rec = await ensureModuleByUrl(url);
|
|
260
|
+
ok = true;
|
|
197
261
|
} catch (e) {
|
|
198
262
|
console.error(`[jundle runner] SSR push ${url}: ${e && e.message ? e.message : String(e)}`);
|
|
263
|
+
} finally {
|
|
264
|
+
restoreShimGlobals(saved);
|
|
199
265
|
}
|
|
266
|
+
if (ok) globalThis.__jundleFlight?.updateModule?.(url, rec.exports);
|
|
200
267
|
}
|
|
201
268
|
}
|
|
202
269
|
|