octane 0.1.50 → 0.1.51
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/cjs/runtime.cjs +52 -33
- package/dist/cjs/signals/engine.cjs +9 -3
- package/dist/cjs/version.cjs +1 -1
- package/dist/compiler/bundler.js +76 -30
- package/dist/compiler/client-only-server.js +10 -6
- package/dist/compiler/compile-renderer-boundaries.js +2 -2
- package/dist/compiler/compile.js +61 -29
- package/dist/compiler/css-module-imports.js +9 -5
- package/dist/compiler/hydrate-boundaries.js +105 -28
- package/dist/compiler/slot-hooks.js +8 -4
- package/dist/compiler/vite.js +53 -9
- package/dist/runtime.js +52 -33
- package/dist/signals/engine.js +9 -3
- package/dist/universal-core.js +99 -26
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/cjs/runtime.cjs
CHANGED
|
@@ -4238,29 +4238,53 @@ function __useStateWithGetter(initial, slot) {
|
|
|
4238
4238
|
let HIDDEN_REVEAL_ACTIONS = null;
|
|
4239
4239
|
function deferHiddenRevealAction(boundary, action) {
|
|
4240
4240
|
const deferred = HIDDEN_REVEAL_ACTIONS ??= /* @__PURE__ */ new WeakMap();
|
|
4241
|
-
|
|
4242
|
-
if (
|
|
4243
|
-
|
|
4241
|
+
let queue = deferred.get(boundary);
|
|
4242
|
+
if (queue === void 0) {
|
|
4243
|
+
queue = { entries: [], live: 0 };
|
|
4244
|
+
deferred.set(boundary, queue);
|
|
4245
|
+
}
|
|
4246
|
+
const entry = { action, active: true, queue };
|
|
4247
|
+
queue.entries.push(entry);
|
|
4248
|
+
queue.live++;
|
|
4249
|
+
return entry;
|
|
4250
|
+
}
|
|
4251
|
+
function claimHiddenRevealAction(boundary, entry) {
|
|
4252
|
+
const queue = entry.queue;
|
|
4253
|
+
if (HIDDEN_REVEAL_ACTIONS?.get(boundary) !== queue) return null;
|
|
4254
|
+
if (!entry.active) return null;
|
|
4255
|
+
entry.active = false;
|
|
4256
|
+
if (--queue.live === 0) HIDDEN_REVEAL_ACTIONS.delete(boundary);
|
|
4257
|
+
return entry.action;
|
|
4258
|
+
}
|
|
4259
|
+
function cancelHiddenRevealAction(boundary, entry) {
|
|
4260
|
+
const queue = entry.queue;
|
|
4261
|
+
if (claimHiddenRevealAction(boundary, entry) === null || queue.live === 0) return;
|
|
4262
|
+
if (queue.entries.length > queue.live * 2) {
|
|
4263
|
+
queue.entries = queue.entries.filter((candidate) => candidate.active);
|
|
4264
|
+
}
|
|
4244
4265
|
}
|
|
4245
4266
|
function publishHiddenRevealActions(boundary) {
|
|
4246
|
-
const
|
|
4247
|
-
if (
|
|
4267
|
+
const queue = HIDDEN_REVEAL_ACTIONS?.get(boundary);
|
|
4268
|
+
if (queue === void 0) return;
|
|
4269
|
+
const entries = queue.entries;
|
|
4248
4270
|
if (boundary.__kind === "activityBlockSlot") {
|
|
4249
|
-
|
|
4250
|
-
|
|
4271
|
+
const end = entries.length;
|
|
4272
|
+
for (let i = 0; i < end; i++) {
|
|
4273
|
+
const entry = entries[i];
|
|
4274
|
+
if (!entry.active) continue;
|
|
4251
4275
|
enqueueEffectEventCommitAction(() => {
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
actions.splice(index, 1);
|
|
4256
|
-
if (actions.length === 0) HIDDEN_REVEAL_ACTIONS.delete(boundary);
|
|
4257
|
-
return action();
|
|
4276
|
+
const claimed = claimHiddenRevealAction(boundary, entry);
|
|
4277
|
+
if (claimed === null) return;
|
|
4278
|
+
return claimed();
|
|
4258
4279
|
});
|
|
4259
4280
|
}
|
|
4260
4281
|
return;
|
|
4261
4282
|
}
|
|
4262
4283
|
HIDDEN_REVEAL_ACTIONS.delete(boundary);
|
|
4263
|
-
for (let i = 0; i <
|
|
4284
|
+
for (let i = 0; i < entries.length; i++) {
|
|
4285
|
+
const entry = entries[i];
|
|
4286
|
+
if (entry.active) enqueueEffectEventCommitAction(entry.action);
|
|
4287
|
+
}
|
|
4264
4288
|
}
|
|
4265
4289
|
function useLinkedState(source, reconcile, options, slot) {
|
|
4266
4290
|
if (typeof options === "symbol") {
|
|
@@ -5334,10 +5358,10 @@ function beginHydratePreload(state) {
|
|
|
5334
5358
|
return promise;
|
|
5335
5359
|
}
|
|
5336
5360
|
function resolveHydrateWaiters(state, reason) {
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
state.hydrationWaiters
|
|
5340
|
-
for (
|
|
5361
|
+
const waiters = state.hydrationWaiters;
|
|
5362
|
+
if (waiters === null) return;
|
|
5363
|
+
state.hydrationWaiters = null;
|
|
5364
|
+
for (const waiter of waiters) waiter(reason);
|
|
5341
5365
|
}
|
|
5342
5366
|
function waitForHydratePrefetchStrategy(state, strategy) {
|
|
5343
5367
|
const controller = state.prefetchAbort;
|
|
@@ -5351,13 +5375,13 @@ function waitForHydratePrefetchStrategy(state, strategy) {
|
|
|
5351
5375
|
if (settled) return;
|
|
5352
5376
|
settled = true;
|
|
5353
5377
|
cleanup?.();
|
|
5354
|
-
state.hydrationWaiters
|
|
5378
|
+
state.hydrationWaiters?.delete(onHydrate);
|
|
5355
5379
|
signal.removeEventListener("abort", onAbort);
|
|
5356
5380
|
resolve(reason);
|
|
5357
5381
|
};
|
|
5358
5382
|
const onHydrate = () => finish("hydrate");
|
|
5359
5383
|
const onAbort = () => finish("abort");
|
|
5360
|
-
state.hydrationWaiters.add(onHydrate);
|
|
5384
|
+
(state.hydrationWaiters ??= /* @__PURE__ */ new Set()).add(onHydrate);
|
|
5361
5385
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5362
5386
|
cleanup = strategy._s?.({
|
|
5363
5387
|
element: state.wrapper,
|
|
@@ -5757,7 +5781,7 @@ function createHydrateSlot(props, scope, boundaryId) {
|
|
|
5757
5781
|
prefetchPromise: null,
|
|
5758
5782
|
preloadPromise: null,
|
|
5759
5783
|
loadedBody: null,
|
|
5760
|
-
hydrationWaiters:
|
|
5784
|
+
hydrationWaiters: null,
|
|
5761
5785
|
activationGeneration: 0,
|
|
5762
5786
|
activationRequested: !serverPreserved,
|
|
5763
5787
|
activationReady: !serverPreserved,
|
|
@@ -19475,28 +19499,23 @@ function enqueueInlineCaughtError(state) {
|
|
|
19475
19499
|
const handler = rootErrorHandlersFor(block)?.onCaughtError;
|
|
19476
19500
|
if (handler === void 0) return;
|
|
19477
19501
|
const error = state.err;
|
|
19478
|
-
let
|
|
19502
|
+
let parked = null;
|
|
19479
19503
|
let cleanupRegistered = false;
|
|
19480
19504
|
const action = (owner2) => {
|
|
19481
|
-
|
|
19505
|
+
parked = null;
|
|
19482
19506
|
if (block.disposed || state.block !== block) return;
|
|
19483
19507
|
const hidden = owner2 ?? findScheduledVisibilityOwner(block, true);
|
|
19484
19508
|
if (hidden !== null) {
|
|
19485
|
-
parkedOwner = hidden;
|
|
19486
19509
|
if (!cleanupRegistered) {
|
|
19487
19510
|
cleanupRegistered = true;
|
|
19488
19511
|
(block.cleanups ??= []).push(() => {
|
|
19489
|
-
const
|
|
19490
|
-
|
|
19491
|
-
if (
|
|
19492
|
-
|
|
19493
|
-
if (actions === void 0) return;
|
|
19494
|
-
const index = actions.indexOf(action);
|
|
19495
|
-
if (index !== -1) actions.splice(index, 1);
|
|
19496
|
-
if (actions.length === 0) HIDDEN_REVEAL_ACTIONS.delete(owner3);
|
|
19512
|
+
const pending = parked;
|
|
19513
|
+
parked = null;
|
|
19514
|
+
if (pending === null) return;
|
|
19515
|
+
cancelHiddenRevealAction(pending.owner, pending.entry);
|
|
19497
19516
|
});
|
|
19498
19517
|
}
|
|
19499
|
-
deferHiddenRevealAction(hidden, action);
|
|
19518
|
+
parked = { owner: hidden, entry: deferHiddenRevealAction(hidden, action) };
|
|
19500
19519
|
return;
|
|
19501
19520
|
}
|
|
19502
19521
|
return { state, block, error, handler, resume: action };
|
|
@@ -333,10 +333,14 @@ class ScopeImpl {
|
|
|
333
333
|
type,
|
|
334
334
|
...node ? { key: node.key, revision: node.revision } : {}
|
|
335
335
|
};
|
|
336
|
-
if (this.events.length === this.traceLimit)
|
|
337
|
-
|
|
336
|
+
if (this.events.length === this.traceLimit) {
|
|
337
|
+
this.events[(event.sequence - 1) % this.traceLimit] = event;
|
|
338
|
+
} else {
|
|
339
|
+
this.events.push(event);
|
|
340
|
+
}
|
|
338
341
|
}
|
|
339
342
|
inspect() {
|
|
343
|
+
const traceStart = this.traceLimit && this.events.length === this.traceLimit ? this.sequence % this.traceLimit : 0;
|
|
340
344
|
return {
|
|
341
345
|
scopeKey: this.scopeKey,
|
|
342
346
|
epoch: this.epoch,
|
|
@@ -365,7 +369,9 @@ class ScopeImpl {
|
|
|
365
369
|
dependencies
|
|
366
370
|
};
|
|
367
371
|
}),
|
|
368
|
-
trace: this.events.map((event) => ({
|
|
372
|
+
trace: this.events.map((event, index) => ({
|
|
373
|
+
...traceStart ? this.events[(traceStart + index) % this.events.length] : event
|
|
374
|
+
}))
|
|
369
375
|
};
|
|
370
376
|
}
|
|
371
377
|
dispose() {
|
package/dist/cjs/version.cjs
CHANGED
|
@@ -21,7 +21,7 @@ __export(version_exports, {
|
|
|
21
21
|
version: () => version
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(version_exports);
|
|
24
|
-
const version = "0.1.
|
|
24
|
+
const version = "0.1.51";
|
|
25
25
|
// Annotate the CommonJS export names for ESM import in node:
|
|
26
26
|
0 && (module.exports = {
|
|
27
27
|
version
|
package/dist/compiler/bundler.js
CHANGED
|
@@ -75,6 +75,21 @@ export const OCTANE_RUNTIME_REQUESTS = Object.freeze({
|
|
|
75
75
|
server: 'octane/server',
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
+
// Vite can classify descriptor exports from its transform-local preflight AST,
|
|
79
|
+
// but the neutral compiler must never trust caller-supplied facts or a naked
|
|
80
|
+
// authored AST. Only opaque objects registered here can bypass the established
|
|
81
|
+
// string classifier, and each proof is consumed once for its exact source/id.
|
|
82
|
+
const descriptorChildrenExportProofs = new WeakMap();
|
|
83
|
+
const descriptorChildrenExportAuthorities = new WeakMap();
|
|
84
|
+
|
|
85
|
+
function consumeDescriptorChildrenExportProof(proof, source, id) {
|
|
86
|
+
if (proof === null || typeof proof !== 'object') return null;
|
|
87
|
+
const prepared = descriptorChildrenExportProofs.get(proof);
|
|
88
|
+
descriptorChildrenExportProofs.delete(proof);
|
|
89
|
+
if (prepared?.source !== source || prepared.id !== id) return null;
|
|
90
|
+
return prepared.exports;
|
|
91
|
+
}
|
|
92
|
+
|
|
78
93
|
/** Strip bundler query/hash suffixes without changing the underlying path. */
|
|
79
94
|
export function cleanModuleId(id) {
|
|
80
95
|
const query = id.indexOf('?');
|
|
@@ -259,6 +274,7 @@ export function findVoidComponentExports(source, id) {
|
|
|
259
274
|
}
|
|
260
275
|
|
|
261
276
|
const voidBindings = new Set();
|
|
277
|
+
const memoDependents = new Map();
|
|
262
278
|
const hasLowerableJsxReturnBranches = createJsxReturnBranchClassifier(ast.body || []);
|
|
263
279
|
// Mirrors the compile-time lowering decisions exactly (nullish-guard @{}
|
|
264
280
|
// bodies AND React-style conditional JSX returns), so cross-module call-site
|
|
@@ -273,41 +289,40 @@ export function findVoidComponentExports(source, id) {
|
|
|
273
289
|
continue;
|
|
274
290
|
}
|
|
275
291
|
if (declaration.type !== 'VariableDeclaration' || declaration.kind !== 'const') continue;
|
|
292
|
+
// Resolve only the exact, immutable `const Export = memo(Local)` form. The
|
|
293
|
+
// imported memo identity is lexical proof; method calls, comparators, and
|
|
294
|
+
// arbitrary wrappers stay unknown. Index the reverse edges once so a chain
|
|
295
|
+
// declared outermost-first does not rescan every declaration per link.
|
|
276
296
|
for (const item of declaration.declarations || []) {
|
|
297
|
+
const init = item.init;
|
|
277
298
|
if (
|
|
278
299
|
item.id?.type === 'Identifier' &&
|
|
279
|
-
(
|
|
280
|
-
|
|
281
|
-
isVoidFunction(item.init)
|
|
300
|
+
(init?.type === 'FunctionExpression' || init?.type === 'ArrowFunctionExpression') &&
|
|
301
|
+
isVoidFunction(init)
|
|
282
302
|
) {
|
|
283
303
|
voidBindings.add(item.id.name);
|
|
284
304
|
}
|
|
305
|
+
if (
|
|
306
|
+
item.id?.type !== 'Identifier' ||
|
|
307
|
+
init?.type !== 'CallExpression' ||
|
|
308
|
+
init.callee?.type !== 'Identifier' ||
|
|
309
|
+
!memoLocals.has(init.callee.name) ||
|
|
310
|
+
init.arguments?.length !== 1 ||
|
|
311
|
+
init.arguments[0]?.type !== 'Identifier'
|
|
312
|
+
)
|
|
313
|
+
continue;
|
|
314
|
+
const target = init.arguments[0].name;
|
|
315
|
+
let dependents = memoDependents.get(target);
|
|
316
|
+
if (dependents === undefined) memoDependents.set(target, (dependents = []));
|
|
317
|
+
dependents.push(item.id.name);
|
|
285
318
|
}
|
|
286
319
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
for (const declaration of declarations) {
|
|
294
|
-
if (declaration.type !== 'VariableDeclaration' || declaration.kind !== 'const') continue;
|
|
295
|
-
for (const item of declaration.declarations || []) {
|
|
296
|
-
const init = item.init;
|
|
297
|
-
if (
|
|
298
|
-
item.id?.type !== 'Identifier' ||
|
|
299
|
-
voidBindings.has(item.id.name) ||
|
|
300
|
-
init?.type !== 'CallExpression' ||
|
|
301
|
-
init.callee?.type !== 'Identifier' ||
|
|
302
|
-
!memoLocals.has(init.callee.name) ||
|
|
303
|
-
init.arguments?.length !== 1 ||
|
|
304
|
-
init.arguments[0]?.type !== 'Identifier' ||
|
|
305
|
-
!voidBindings.has(init.arguments[0].name)
|
|
306
|
-
)
|
|
307
|
-
continue;
|
|
308
|
-
voidBindings.add(item.id.name);
|
|
309
|
-
changed = true;
|
|
310
|
-
}
|
|
320
|
+
const pending = [...voidBindings];
|
|
321
|
+
for (let index = 0; index < pending.length; index++) {
|
|
322
|
+
for (const dependent of memoDependents.get(pending[index]) ?? []) {
|
|
323
|
+
if (voidBindings.has(dependent)) continue;
|
|
324
|
+
voidBindings.add(dependent);
|
|
325
|
+
pending.push(dependent);
|
|
311
326
|
}
|
|
312
327
|
}
|
|
313
328
|
|
|
@@ -518,6 +533,7 @@ class OctaneBundlerCompiler {
|
|
|
518
533
|
if (renderer.intrinsics !== undefined) this.pragmaOwnedModules.add(renderer.intrinsics);
|
|
519
534
|
}
|
|
520
535
|
this.warn = typeof options.warn === 'function' ? options.warn : null;
|
|
536
|
+
descriptorChildrenExportAuthorities.set(this, options._descriptorPreflightAuthority ?? null);
|
|
521
537
|
this.warnedOwnership = new Set();
|
|
522
538
|
this.warnedCompileDiagnostics = new Set();
|
|
523
539
|
// Deliberately instance-scoped: separate projects/build environments must
|
|
@@ -933,8 +949,30 @@ class OctaneBundlerCompiler {
|
|
|
933
949
|
return findStaticRuntimeImportRequests(code, this._canonicalModuleId(id));
|
|
934
950
|
}
|
|
935
951
|
|
|
952
|
+
/** @internal Create a one-transform descriptor-export proof from a read-only AST. */
|
|
953
|
+
_prepareDescriptorChildrenExports(authority, source, id, ast) {
|
|
954
|
+
if (
|
|
955
|
+
authority === null ||
|
|
956
|
+
authority !== descriptorChildrenExportAuthorities.get(this) ||
|
|
957
|
+
typeof source !== 'string' ||
|
|
958
|
+
typeof id !== 'string' ||
|
|
959
|
+
ast === null ||
|
|
960
|
+
typeof ast !== 'object' ||
|
|
961
|
+
ast.type !== 'Program'
|
|
962
|
+
) {
|
|
963
|
+
throw new TypeError('Invalid descriptor-children preflight input.');
|
|
964
|
+
}
|
|
965
|
+
const proof = Object.freeze({});
|
|
966
|
+
descriptorChildrenExportProofs.set(proof, {
|
|
967
|
+
source,
|
|
968
|
+
id,
|
|
969
|
+
exports: Object.freeze(findDescriptorChildrenExports(ast, id)),
|
|
970
|
+
});
|
|
971
|
+
return proof;
|
|
972
|
+
}
|
|
973
|
+
|
|
936
974
|
/** CSS proof discovery uses the same ownership gate as the eventual compile. */
|
|
937
|
-
findCssModuleImportRequests(code, id, environment = 'client') {
|
|
975
|
+
findCssModuleImportRequests(code, id, environment = 'client', parsedAst = null) {
|
|
938
976
|
if (typeof code !== 'string' || !code.includes('.module.')) return [];
|
|
939
977
|
// The live-read witness currently follows DOM host ownership only. Even
|
|
940
978
|
// a DOM-owned module can delegate a JSX-valued prop to another renderer.
|
|
@@ -956,7 +994,7 @@ class OctaneBundlerCompiler {
|
|
|
956
994
|
) {
|
|
957
995
|
return [];
|
|
958
996
|
}
|
|
959
|
-
return findCssModuleImportRequests(code, filename);
|
|
997
|
+
return findCssModuleImportRequests(parsedAst ?? code, filename);
|
|
960
998
|
}
|
|
961
999
|
|
|
962
1000
|
/**
|
|
@@ -1014,6 +1052,11 @@ class OctaneBundlerCompiler {
|
|
|
1014
1052
|
|
|
1015
1053
|
transform(code, id, options = {}) {
|
|
1016
1054
|
assertNativeReadOptions(options);
|
|
1055
|
+
const preparedDescriptorChildrenExports = consumeDescriptorChildrenExportProof(
|
|
1056
|
+
options._descriptorChildrenExportsProof,
|
|
1057
|
+
code,
|
|
1058
|
+
id,
|
|
1059
|
+
);
|
|
1017
1060
|
const file = cleanModuleId(id);
|
|
1018
1061
|
const hydrateBoundaryPath = hydrateBoundaryPathFromId(id);
|
|
1019
1062
|
const collected = {
|
|
@@ -1199,7 +1242,10 @@ class OctaneBundlerCompiler {
|
|
|
1199
1242
|
voidComponentExports: findVoidComponentExports(voidComponentAst, filename),
|
|
1200
1243
|
}),
|
|
1201
1244
|
...(cssModuleConstantImports === undefined ? null : { cssModuleConstantImports }),
|
|
1202
|
-
descriptorChildrenExports:
|
|
1245
|
+
descriptorChildrenExports:
|
|
1246
|
+
preparedDescriptorChildrenExports === null
|
|
1247
|
+
? findDescriptorChildrenExports(code, filename)
|
|
1248
|
+
: [...preparedDescriptorChildrenExports],
|
|
1203
1249
|
...finishMetadata(collected),
|
|
1204
1250
|
};
|
|
1205
1251
|
}
|
|
@@ -151,12 +151,16 @@ export function createClientReferenceManifest(entries) {
|
|
|
151
151
|
/** Return the runtime import/re-export requests that a bundler should resolve. */
|
|
152
152
|
export function findStaticRuntimeImportRequests(source, filename = 'unknown') {
|
|
153
153
|
let ast;
|
|
154
|
-
|
|
155
|
-
ast =
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
154
|
+
if (source && typeof source === 'object' && source.type === 'Program') {
|
|
155
|
+
ast = source;
|
|
156
|
+
} else {
|
|
157
|
+
try {
|
|
158
|
+
ast = parseModule(source, filename);
|
|
159
|
+
} catch {
|
|
160
|
+
// The owning compiler/parser will report the useful syntax diagnostic. Import
|
|
161
|
+
// classification is an adapter prepass and must not replace it.
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
160
164
|
}
|
|
161
165
|
const requests = new Set();
|
|
162
166
|
for (const statement of ast.body ?? []) {
|
|
@@ -499,7 +499,7 @@ function owningComponentForReference(components, node) {
|
|
|
499
499
|
}
|
|
500
500
|
|
|
501
501
|
function ownerReachableComponentsAst(ast, localSpecializations) {
|
|
502
|
-
const localNames =
|
|
502
|
+
const localNames = localSpecializations.components;
|
|
503
503
|
const dependencies = new Map();
|
|
504
504
|
const reachable = new Set(
|
|
505
505
|
[...localSpecializations.exported].filter((name) => localNames.has(name)),
|
|
@@ -702,7 +702,7 @@ function collectSpecializationAstReplacements(node, cloneNames, runtime, aliases
|
|
|
702
702
|
}
|
|
703
703
|
|
|
704
704
|
function specializeLocalComponentsAst(region, index, state) {
|
|
705
|
-
const localNames =
|
|
705
|
+
const localNames = state.localSpecializations.components;
|
|
706
706
|
const selected = new Set([
|
|
707
707
|
...jsxComponentReferences(region, localNames),
|
|
708
708
|
...localCallReferences(region, localNames),
|
package/dist/compiler/compile.js
CHANGED
|
@@ -5340,38 +5340,70 @@ function classifyStableHookfulChildCalls(moduleBody, ctx) {
|
|
|
5340
5340
|
});
|
|
5341
5341
|
}
|
|
5342
5342
|
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
}
|
|
5343
|
+
const dependents = new Map();
|
|
5344
|
+
const removalQueue = [];
|
|
5345
|
+
for (const [name, candidate] of candidates) {
|
|
5346
|
+
let invalid = false;
|
|
5347
|
+
for (const edge of candidate.dependencies) {
|
|
5348
|
+
const childName = tagBindingName(edge);
|
|
5349
|
+
if (!candidates.has(childName)) {
|
|
5350
|
+
invalid = true;
|
|
5351
|
+
continue;
|
|
5353
5352
|
}
|
|
5353
|
+
let childDependents = dependents.get(childName);
|
|
5354
|
+
if (childDependents === undefined) {
|
|
5355
|
+
dependents.set(childName, (childDependents = []));
|
|
5356
|
+
}
|
|
5357
|
+
childDependents.push(name);
|
|
5354
5358
|
}
|
|
5359
|
+
if (invalid) removalQueue.push(name);
|
|
5355
5360
|
}
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5361
|
+
for (let index = 0; index < removalQueue.length; index++) {
|
|
5362
|
+
const name = removalQueue[index];
|
|
5363
|
+
if (!candidates.delete(name)) continue;
|
|
5364
|
+
const parentNames = dependents.get(name);
|
|
5365
|
+
if (parentNames === undefined) continue;
|
|
5366
|
+
for (const parentName of parentNames) {
|
|
5367
|
+
if (candidates.has(parentName)) removalQueue.push(parentName);
|
|
5368
|
+
}
|
|
5369
|
+
}
|
|
5370
|
+
|
|
5371
|
+
const captureOwners = [];
|
|
5372
|
+
const captureValues = [];
|
|
5373
|
+
const publicationOwners = [];
|
|
5374
|
+
const publicationValues = [];
|
|
5375
|
+
for (const [name, candidate] of candidates) {
|
|
5376
|
+
for (const capture of candidate.captures) {
|
|
5377
|
+
captureOwners.push(name);
|
|
5378
|
+
captureValues.push(capture);
|
|
5379
|
+
}
|
|
5380
|
+
for (const publication of candidate.publications) {
|
|
5381
|
+
publicationOwners.push(name);
|
|
5382
|
+
publicationValues.push(publication);
|
|
5383
|
+
}
|
|
5384
|
+
}
|
|
5385
|
+
for (let index = 0; index < captureOwners.length; index++) {
|
|
5386
|
+
const parentNames = dependents.get(captureOwners[index]);
|
|
5387
|
+
if (parentNames === undefined) continue;
|
|
5388
|
+
const capture = captureValues[index];
|
|
5389
|
+
for (const parentName of parentNames) {
|
|
5390
|
+
const parent = candidates.get(parentName);
|
|
5391
|
+
if (parent === undefined || parent.captures.has(capture)) continue;
|
|
5392
|
+
parent.captures.add(capture);
|
|
5393
|
+
captureOwners.push(parentName);
|
|
5394
|
+
captureValues.push(capture);
|
|
5395
|
+
}
|
|
5396
|
+
}
|
|
5397
|
+
for (let index = 0; index < publicationOwners.length; index++) {
|
|
5398
|
+
const parentNames = dependents.get(publicationOwners[index]);
|
|
5399
|
+
if (parentNames === undefined) continue;
|
|
5400
|
+
const publication = publicationValues[index];
|
|
5401
|
+
for (const parentName of parentNames) {
|
|
5402
|
+
const parent = candidates.get(parentName);
|
|
5403
|
+
if (parent === undefined || parent.publications.has(publication)) continue;
|
|
5404
|
+
parent.publications.add(publication);
|
|
5405
|
+
publicationOwners.push(parentName);
|
|
5406
|
+
publicationValues.push(publication);
|
|
5375
5407
|
}
|
|
5376
5408
|
}
|
|
5377
5409
|
for (const [name, candidate] of candidates) {
|
|
@@ -10,12 +10,16 @@ export function isPlainCssModuleId(id) {
|
|
|
10
10
|
|
|
11
11
|
/** Only authored CSS-module imports can ask the host for this narrow proof. */
|
|
12
12
|
export function findCssModuleImportRequests(source, id) {
|
|
13
|
-
if (typeof source !== 'string' || !source.includes('.module.')) return [];
|
|
14
13
|
let ast;
|
|
15
|
-
|
|
16
|
-
ast =
|
|
17
|
-
}
|
|
18
|
-
return [];
|
|
14
|
+
if (source && typeof source === 'object' && source.type === 'Program') {
|
|
15
|
+
ast = source;
|
|
16
|
+
} else {
|
|
17
|
+
if (typeof source !== 'string' || !source.includes('.module.')) return [];
|
|
18
|
+
try {
|
|
19
|
+
ast = parseModule(source, id);
|
|
20
|
+
} catch {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
19
23
|
}
|
|
20
24
|
const requests = new Set();
|
|
21
25
|
for (const statement of ast.body ?? []) {
|
|
@@ -693,17 +693,38 @@ function visitJsxTag(name, visitIdentifier) {
|
|
|
693
693
|
}
|
|
694
694
|
|
|
695
695
|
/** Collect names whose values must cross from the parent module into a queried child. */
|
|
696
|
-
function collectCaptures(
|
|
696
|
+
function collectCaptures(
|
|
697
|
+
nodes,
|
|
698
|
+
importBindings,
|
|
699
|
+
shadowedImports = new Set(),
|
|
700
|
+
additionalBindings = null,
|
|
701
|
+
) {
|
|
697
702
|
const captures = new Set();
|
|
698
703
|
const scopes = [];
|
|
699
704
|
const seen = new WeakSet();
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
705
|
+
// Module slicing can consult a second binding set without materializing its
|
|
706
|
+
// union for every boundary. Preserve the single-set path for all other walks.
|
|
707
|
+
const isBound =
|
|
708
|
+
additionalBindings === null
|
|
709
|
+
? (name) => {
|
|
710
|
+
if (importBindings.has(name) && !shadowedImports.has(name)) return true;
|
|
711
|
+
for (let index = scopes.length - 1; index >= 0; index--) {
|
|
712
|
+
if (scopes[index].has(name)) return true;
|
|
713
|
+
}
|
|
714
|
+
return false;
|
|
715
|
+
}
|
|
716
|
+
: (name) => {
|
|
717
|
+
if (
|
|
718
|
+
(importBindings.has(name) || additionalBindings.has(name)) &&
|
|
719
|
+
!shadowedImports.has(name)
|
|
720
|
+
) {
|
|
721
|
+
return true;
|
|
722
|
+
}
|
|
723
|
+
for (let index = scopes.length - 1; index >= 0; index--) {
|
|
724
|
+
if (scopes[index].has(name)) return true;
|
|
725
|
+
}
|
|
726
|
+
return false;
|
|
727
|
+
};
|
|
707
728
|
const reference = (node) => {
|
|
708
729
|
if (node?.name && !isBound(node.name)) captures.add(node.name);
|
|
709
730
|
};
|
|
@@ -976,8 +997,31 @@ function privateModuleDeclarationGraph(ast, importBindings) {
|
|
|
976
997
|
return { byBinding, records };
|
|
977
998
|
}
|
|
978
999
|
|
|
1000
|
+
function sortedBoundaryRanges(boundaries) {
|
|
1001
|
+
return boundaries
|
|
1002
|
+
.map((boundary) => ({ end: boundary.node.end, start: boundary.node.start }))
|
|
1003
|
+
.sort((left, right) => left.start - right.start || left.end - right.end);
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
function declarationContainsBoundary(node, boundaryRanges) {
|
|
1007
|
+
let low = 0;
|
|
1008
|
+
let high = boundaryRanges.length;
|
|
1009
|
+
while (low < high) {
|
|
1010
|
+
const middle = (low + high) >>> 1;
|
|
1011
|
+
if (boundaryRanges[middle].start < node.start) low = middle + 1;
|
|
1012
|
+
else high = middle;
|
|
1013
|
+
}
|
|
1014
|
+
for (let index = low; index < boundaryRanges.length; index++) {
|
|
1015
|
+
const boundary = boundaryRanges[index];
|
|
1016
|
+
if (boundary.start > node.end) break;
|
|
1017
|
+
if (boundary.end <= node.end) return true;
|
|
1018
|
+
}
|
|
1019
|
+
return false;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
979
1022
|
function movableModuleDeclarations(analysis) {
|
|
980
1023
|
const records = [];
|
|
1024
|
+
let boundaryRanges = null;
|
|
981
1025
|
const moduleBindings = topLevelBindingNames(analysis.ast);
|
|
982
1026
|
const exportedBindings = localExportBindings(analysis.ast);
|
|
983
1027
|
for (const node of analysis.ast.body ?? []) {
|
|
@@ -994,11 +1038,8 @@ function movableModuleDeclarations(analysis) {
|
|
|
994
1038
|
// A declaration containing its own Hydrate site needs another extraction
|
|
995
1039
|
// pass after it moves. Keep that uncommon declaration in the parent until
|
|
996
1040
|
// recursive declaration slicing has an explicit protocol of its own.
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
(boundary) => boundary.node.start >= node.start && boundary.node.end <= node.end,
|
|
1000
|
-
)
|
|
1001
|
-
) {
|
|
1041
|
+
boundaryRanges ??= sortedBoundaryRanges(analysis.boundaries);
|
|
1042
|
+
if (declarationContainsBoundary(node, boundaryRanges)) {
|
|
1002
1043
|
continue;
|
|
1003
1044
|
}
|
|
1004
1045
|
const bindings = declarationBindingSet(node);
|
|
@@ -1007,6 +1048,7 @@ function movableModuleDeclarations(analysis) {
|
|
|
1007
1048
|
records.push({
|
|
1008
1049
|
bindings,
|
|
1009
1050
|
dependencies: new Set(),
|
|
1051
|
+
order: records.length,
|
|
1010
1052
|
retainedDependencies: new Set(),
|
|
1011
1053
|
node,
|
|
1012
1054
|
});
|
|
@@ -1123,8 +1165,12 @@ function hydrateBoundaryElement(
|
|
|
1123
1165
|
if (boundary.disabled) return node;
|
|
1124
1166
|
assertDirectChildren(boundary, boundary.filename);
|
|
1125
1167
|
validateBoundary(boundary, boundary.filename, boundary.hookNames);
|
|
1126
|
-
const
|
|
1127
|
-
|
|
1168
|
+
const captures = collectCaptures(
|
|
1169
|
+
node.children,
|
|
1170
|
+
importBindings,
|
|
1171
|
+
boundary.shadowedImports,
|
|
1172
|
+
additionalModuleBindings.size === 0 ? null : additionalModuleBindings,
|
|
1173
|
+
);
|
|
1128
1174
|
const attributes = [
|
|
1129
1175
|
...(opening.attributes ?? []),
|
|
1130
1176
|
jsxExpressionAttribute('__load', hydrateLoaderExpression(boundary, request), opening),
|
|
@@ -1222,8 +1268,9 @@ function extractedModuleAst(
|
|
|
1222
1268
|
const moduleBindings = moduleBindingsByPath.get(boundary.path) ?? new Set();
|
|
1223
1269
|
const captures = collectCaptures(
|
|
1224
1270
|
boundary.node.children,
|
|
1225
|
-
|
|
1271
|
+
analysis.imports.importBindings,
|
|
1226
1272
|
boundary.shadowedImports,
|
|
1273
|
+
moduleBindings.size === 0 ? null : moduleBindings,
|
|
1227
1274
|
);
|
|
1228
1275
|
const pathName = boundary.path.replace(/[^A-Za-z0-9_$]/g, '_');
|
|
1229
1276
|
const componentName = uniqueGeneratedName(source, `__OctaneHydrateBoundary_${pathName}`);
|
|
@@ -1276,7 +1323,35 @@ function extractedModuleAst(
|
|
|
1276
1323
|
return pruneUnusedImportsAst(program, false);
|
|
1277
1324
|
}
|
|
1278
1325
|
|
|
1279
|
-
function
|
|
1326
|
+
function moduleReferencesForBoundary(analysis, boundary, request, moduleBindingsByPath) {
|
|
1327
|
+
assertDirectChildren(boundary, boundary.filename);
|
|
1328
|
+
validateBoundary(boundary, boundary.filename, analysis.imports.hookNames);
|
|
1329
|
+
const collectModuleReferences = (nodes) =>
|
|
1330
|
+
collectCaptures(nodes, analysis.imports.importBindings).filter(
|
|
1331
|
+
(name) => !boundary.shadowedImports.has(name),
|
|
1332
|
+
);
|
|
1333
|
+
if (boundary.children.length === 0) {
|
|
1334
|
+
return collectModuleReferences(boundary.node.children);
|
|
1335
|
+
}
|
|
1336
|
+
const nestedAnalysis = {
|
|
1337
|
+
...analysis,
|
|
1338
|
+
roots: boundary.children,
|
|
1339
|
+
};
|
|
1340
|
+
const fragment = transformHydrateAst(
|
|
1341
|
+
{
|
|
1342
|
+
type: 'Program',
|
|
1343
|
+
sourceType: 'module',
|
|
1344
|
+
body: boundary.node.children,
|
|
1345
|
+
metadata: { path: [] },
|
|
1346
|
+
},
|
|
1347
|
+
nestedAnalysis,
|
|
1348
|
+
request,
|
|
1349
|
+
moduleBindingsByPath,
|
|
1350
|
+
);
|
|
1351
|
+
return collectModuleReferences(fragment.body);
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
function createModuleMovePlanAst(analysis, request) {
|
|
1280
1355
|
const candidates = movableModuleDeclarations(analysis);
|
|
1281
1356
|
if (candidates.records.length === 0) {
|
|
1282
1357
|
return {
|
|
@@ -1340,13 +1415,9 @@ function createModuleMovePlanAst(source, analysis, request) {
|
|
|
1340
1415
|
const referencesByPath = new Map();
|
|
1341
1416
|
for (const boundary of analysis.boundaries) {
|
|
1342
1417
|
if (boundary.disabled || hasPermanentStaticAncestor(boundary)) continue;
|
|
1343
|
-
const childAst = extractedModuleAst(source, analysis, boundary, request, allBindingsByPath);
|
|
1344
1418
|
referencesByPath.set(
|
|
1345
1419
|
boundary.path,
|
|
1346
|
-
|
|
1347
|
-
(childAst.body ?? []).filter((node) => node.type !== 'ImportDeclaration'),
|
|
1348
|
-
analysis.imports.importBindings,
|
|
1349
|
-
),
|
|
1420
|
+
moduleReferencesForBoundary(analysis, boundary, request, allBindingsByPath),
|
|
1350
1421
|
);
|
|
1351
1422
|
}
|
|
1352
1423
|
const recordsForReferences = (childReferences) => {
|
|
@@ -1371,8 +1442,11 @@ function createModuleMovePlanAst(source, analysis, request) {
|
|
|
1371
1442
|
return records;
|
|
1372
1443
|
};
|
|
1373
1444
|
const preliminaryCounts = new Map();
|
|
1374
|
-
|
|
1375
|
-
|
|
1445
|
+
const preliminaryRecordsByPath = new Map();
|
|
1446
|
+
for (const [path, references] of referencesByPath) {
|
|
1447
|
+
const records = recordsForReferences(references);
|
|
1448
|
+
preliminaryRecordsByPath.set(path, records);
|
|
1449
|
+
for (const record of records) {
|
|
1376
1450
|
preliminaryCounts.set(record, (preliminaryCounts.get(record) ?? 0) + 1);
|
|
1377
1451
|
}
|
|
1378
1452
|
}
|
|
@@ -1383,9 +1457,12 @@ function createModuleMovePlanAst(source, analysis, request) {
|
|
|
1383
1457
|
const movedRecords = new Set();
|
|
1384
1458
|
for (const boundary of analysis.boundaries) {
|
|
1385
1459
|
if (boundary.disabled || hasPermanentStaticAncestor(boundary)) continue;
|
|
1386
|
-
const records =
|
|
1387
|
-
if (records
|
|
1388
|
-
const ordered =
|
|
1460
|
+
const records = preliminaryRecordsByPath.get(boundary.path);
|
|
1461
|
+
if (records === undefined) continue;
|
|
1462
|
+
const ordered = [...records]
|
|
1463
|
+
.filter((record) => !eagerRecords.has(record))
|
|
1464
|
+
.sort((left, right) => left.order - right.order);
|
|
1465
|
+
if (ordered.length === 0) continue;
|
|
1389
1466
|
bindingsByPath.set(boundary.path, new Set(ordered.flatMap((record) => [...record.bindings])));
|
|
1390
1467
|
declarationsByPath.set(boundary.path, ordered);
|
|
1391
1468
|
for (const record of ordered) movedRecords.add(record);
|
|
@@ -1532,7 +1609,7 @@ export function prepareHydrateBoundaries(source, filename, boundaryPath = null,
|
|
|
1532
1609
|
boundary.hookNames = analysis.imports.hookNames;
|
|
1533
1610
|
}
|
|
1534
1611
|
const request = sameSourceRequest(filename);
|
|
1535
|
-
const moduleMovePlan = createModuleMovePlanAst(
|
|
1612
|
+
const moduleMovePlan = createModuleMovePlanAst(analysis, request);
|
|
1536
1613
|
const permanentStaticRemoved =
|
|
1537
1614
|
boundaryPath === null
|
|
1538
1615
|
? createPermanentStaticRemovalPlanAst(analysis, request, moduleMovePlan)
|
|
@@ -232,10 +232,14 @@ function collectVoidJsxImportCandidates(ast) {
|
|
|
232
232
|
*/
|
|
233
233
|
export function findVoidComponentImports(source, id) {
|
|
234
234
|
let ast;
|
|
235
|
-
|
|
236
|
-
ast =
|
|
237
|
-
}
|
|
238
|
-
|
|
235
|
+
if (source && typeof source === 'object' && source.type === 'Program') {
|
|
236
|
+
ast = source;
|
|
237
|
+
} else {
|
|
238
|
+
try {
|
|
239
|
+
ast = parseModule(source, id);
|
|
240
|
+
} catch {
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
239
243
|
}
|
|
240
244
|
const unique = new Map();
|
|
241
245
|
for (const candidate of [
|
package/dist/compiler/vite.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import * as nodeCrypto from 'node:crypto';
|
|
17
17
|
import * as nodeFs from 'node:fs';
|
|
18
18
|
import * as nodePath from 'node:path';
|
|
19
|
+
import { parseModule } from '@tsrx/core';
|
|
19
20
|
import {
|
|
20
21
|
CLIENT_REFERENCE_MANIFEST_FILENAME,
|
|
21
22
|
cleanModuleId,
|
|
@@ -38,6 +39,7 @@ const PROFILE_DEFINE = '__OCTANE_PROFILE_ENABLED__';
|
|
|
38
39
|
const VOID_EXPORTS_META = 'octane:void-component-exports';
|
|
39
40
|
const DESCRIPTOR_CHILDREN_EXPORTS_META = 'octane:descriptor-children-exports';
|
|
40
41
|
const CLIENT_REFERENCE_META = 'octane:client-reference';
|
|
42
|
+
const DESCRIPTOR_PREFLIGHT_AUTHORITY = Symbol('octane.descriptor-preflight');
|
|
41
43
|
|
|
42
44
|
function realRoot(path) {
|
|
43
45
|
try {
|
|
@@ -491,9 +493,8 @@ async function loadDescriptorChildrenImports(
|
|
|
491
493
|
return proven;
|
|
492
494
|
}
|
|
493
495
|
|
|
494
|
-
async function loadClientOnlyImports(context, compiler,
|
|
496
|
+
async function loadClientOnlyImports(context, compiler, requests, importer) {
|
|
495
497
|
if (typeof context.resolve !== 'function') return [];
|
|
496
|
-
const requests = compiler.findServerImportRequests(code, importer);
|
|
497
498
|
const classified = [];
|
|
498
499
|
await Promise.all(
|
|
499
500
|
requests.map(async (request) => {
|
|
@@ -611,6 +612,7 @@ export function octane(options = {}) {
|
|
|
611
612
|
// virtual module until its own transform publishes metadata.
|
|
612
613
|
let allowDescriptorGraphLoad = true;
|
|
613
614
|
let compiler = createOctaneCompiler({
|
|
615
|
+
_descriptorPreflightAuthority: DESCRIPTOR_PREFLIGHT_AUTHORITY,
|
|
614
616
|
root: projectRoot,
|
|
615
617
|
exclude: options.exclude,
|
|
616
618
|
profile: profileEnabled,
|
|
@@ -630,6 +632,7 @@ export function octane(options = {}) {
|
|
|
630
632
|
cssModuleProofStates.clear();
|
|
631
633
|
projectRoot = nodePath.resolve(root);
|
|
632
634
|
compiler = createOctaneCompiler({
|
|
635
|
+
_descriptorPreflightAuthority: DESCRIPTOR_PREFLIGHT_AUTHORITY,
|
|
633
636
|
root: projectRoot,
|
|
634
637
|
exclude: options.exclude,
|
|
635
638
|
profile: profileEnabled,
|
|
@@ -752,9 +755,47 @@ export function octane(options = {}) {
|
|
|
752
755
|
? forceSsr
|
|
753
756
|
: transformOptions?.ssr === true || this.environment?.config?.consumer === 'server';
|
|
754
757
|
const environment = server ? 'server' : 'client';
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
+
// Parse authored source once, synchronously classify every applicable
|
|
759
|
+
// adapter concern, then let the AST fall out of scope before any graph
|
|
760
|
+
// loading begins. Compilation keeps its independent authoritative parser.
|
|
761
|
+
const preflight = (() => {
|
|
762
|
+
const authoredSource = code;
|
|
763
|
+
let ast;
|
|
764
|
+
try {
|
|
765
|
+
ast = parseModule(authoredSource, id);
|
|
766
|
+
} catch {
|
|
767
|
+
// Every adapter classifier uses this exact parser/source/id and would
|
|
768
|
+
// return an empty result after repeating the same failed parse. Preserve
|
|
769
|
+
// those facts without the retries. The compiler receives no descriptor
|
|
770
|
+
// proof, so its canonical-id fallback and authoritative diagnostics stay
|
|
771
|
+
// unchanged.
|
|
772
|
+
return {
|
|
773
|
+
cssRequests: [],
|
|
774
|
+
descriptorExportsProof: null,
|
|
775
|
+
descriptorImports: [],
|
|
776
|
+
serverImportRequests: [],
|
|
777
|
+
voidImports: [],
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
return {
|
|
781
|
+
cssRequests: specializeCssModuleConstants
|
|
782
|
+
? compiler.findCssModuleImportRequests(code, id, environment, ast)
|
|
783
|
+
: [],
|
|
784
|
+
descriptorExportsProof: compiler._prepareDescriptorChildrenExports(
|
|
785
|
+
DESCRIPTOR_PREFLIGHT_AUTHORITY,
|
|
786
|
+
code,
|
|
787
|
+
id,
|
|
788
|
+
ast,
|
|
789
|
+
),
|
|
790
|
+
descriptorImports: findDescriptorChildrenImports(ast, id),
|
|
791
|
+
serverImportRequests: server ? compiler.findServerImportRequests(ast, id) : [],
|
|
792
|
+
voidImports:
|
|
793
|
+
specializeProductionRoots && !server && !hmrEnabled && !profileEnabled
|
|
794
|
+
? findVoidComponentImports(ast, id)
|
|
795
|
+
: [],
|
|
796
|
+
};
|
|
797
|
+
})();
|
|
798
|
+
const cssRequests = preflight.cssRequests;
|
|
758
799
|
const loadCssImports = () =>
|
|
759
800
|
loadCssModuleImports(
|
|
760
801
|
this,
|
|
@@ -774,6 +815,9 @@ export function octane(options = {}) {
|
|
|
774
815
|
.filter((key) => key.startsWith('export\0'))
|
|
775
816
|
.map((key) => key.slice('export\0'.length));
|
|
776
817
|
const result = compiler.transform(code, id, {
|
|
818
|
+
...(preflight.descriptorExportsProof === null
|
|
819
|
+
? null
|
|
820
|
+
: { _descriptorChildrenExportsProof: preflight.descriptorExportsProof }),
|
|
777
821
|
environment,
|
|
778
822
|
hmr: !server && hmrEnabled ? 'vite' : false,
|
|
779
823
|
// DEV server transforms also carry SSR-only diagnostics. HMR itself
|
|
@@ -849,11 +893,11 @@ export function octane(options = {}) {
|
|
|
849
893
|
};
|
|
850
894
|
|
|
851
895
|
if (server) {
|
|
852
|
-
const descriptorImports =
|
|
896
|
+
const descriptorImports = preflight.descriptorImports.filter(
|
|
853
897
|
(candidate) => candidate.local !== undefined || !nodeFs.existsSync(cleanModuleId(id)),
|
|
854
898
|
);
|
|
855
899
|
return Promise.all([
|
|
856
|
-
loadClientOnlyImports(this, compiler,
|
|
900
|
+
loadClientOnlyImports(this, compiler, preflight.serverImportRequests, id),
|
|
857
901
|
loadDescriptorChildrenImports(
|
|
858
902
|
this,
|
|
859
903
|
descriptorImports,
|
|
@@ -871,9 +915,9 @@ export function octane(options = {}) {
|
|
|
871
915
|
|
|
872
916
|
const voidImports =
|
|
873
917
|
specializeProductionRoots && !server && !hmrEnabled && !profileEnabled
|
|
874
|
-
?
|
|
918
|
+
? preflight.voidImports
|
|
875
919
|
: [];
|
|
876
|
-
const descriptorImports =
|
|
920
|
+
const descriptorImports = preflight.descriptorImports.filter(
|
|
877
921
|
(candidate) => candidate.local !== undefined || !nodeFs.existsSync(cleanModuleId(id)),
|
|
878
922
|
);
|
|
879
923
|
if (voidImports.length === 0 && descriptorImports.length === 0 && cssRequests.length === 0) {
|
package/dist/runtime.js
CHANGED
|
@@ -4071,29 +4071,53 @@ function __useStateWithGetter(initial, slot) {
|
|
|
4071
4071
|
let HIDDEN_REVEAL_ACTIONS = null;
|
|
4072
4072
|
function deferHiddenRevealAction(boundary, action) {
|
|
4073
4073
|
const deferred = HIDDEN_REVEAL_ACTIONS ??= /* @__PURE__ */ new WeakMap();
|
|
4074
|
-
|
|
4075
|
-
if (
|
|
4076
|
-
|
|
4074
|
+
let queue = deferred.get(boundary);
|
|
4075
|
+
if (queue === void 0) {
|
|
4076
|
+
queue = { entries: [], live: 0 };
|
|
4077
|
+
deferred.set(boundary, queue);
|
|
4078
|
+
}
|
|
4079
|
+
const entry = { action, active: true, queue };
|
|
4080
|
+
queue.entries.push(entry);
|
|
4081
|
+
queue.live++;
|
|
4082
|
+
return entry;
|
|
4083
|
+
}
|
|
4084
|
+
function claimHiddenRevealAction(boundary, entry) {
|
|
4085
|
+
const queue = entry.queue;
|
|
4086
|
+
if (HIDDEN_REVEAL_ACTIONS?.get(boundary) !== queue) return null;
|
|
4087
|
+
if (!entry.active) return null;
|
|
4088
|
+
entry.active = false;
|
|
4089
|
+
if (--queue.live === 0) HIDDEN_REVEAL_ACTIONS.delete(boundary);
|
|
4090
|
+
return entry.action;
|
|
4091
|
+
}
|
|
4092
|
+
function cancelHiddenRevealAction(boundary, entry) {
|
|
4093
|
+
const queue = entry.queue;
|
|
4094
|
+
if (claimHiddenRevealAction(boundary, entry) === null || queue.live === 0) return;
|
|
4095
|
+
if (queue.entries.length > queue.live * 2) {
|
|
4096
|
+
queue.entries = queue.entries.filter((candidate) => candidate.active);
|
|
4097
|
+
}
|
|
4077
4098
|
}
|
|
4078
4099
|
function publishHiddenRevealActions(boundary) {
|
|
4079
|
-
const
|
|
4080
|
-
if (
|
|
4100
|
+
const queue = HIDDEN_REVEAL_ACTIONS?.get(boundary);
|
|
4101
|
+
if (queue === void 0) return;
|
|
4102
|
+
const entries = queue.entries;
|
|
4081
4103
|
if (boundary.__kind === "activityBlockSlot") {
|
|
4082
|
-
|
|
4083
|
-
|
|
4104
|
+
const end = entries.length;
|
|
4105
|
+
for (let i = 0; i < end; i++) {
|
|
4106
|
+
const entry = entries[i];
|
|
4107
|
+
if (!entry.active) continue;
|
|
4084
4108
|
enqueueEffectEventCommitAction(() => {
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
actions.splice(index, 1);
|
|
4089
|
-
if (actions.length === 0) HIDDEN_REVEAL_ACTIONS.delete(boundary);
|
|
4090
|
-
return action();
|
|
4109
|
+
const claimed = claimHiddenRevealAction(boundary, entry);
|
|
4110
|
+
if (claimed === null) return;
|
|
4111
|
+
return claimed();
|
|
4091
4112
|
});
|
|
4092
4113
|
}
|
|
4093
4114
|
return;
|
|
4094
4115
|
}
|
|
4095
4116
|
HIDDEN_REVEAL_ACTIONS.delete(boundary);
|
|
4096
|
-
for (let i = 0; i <
|
|
4117
|
+
for (let i = 0; i < entries.length; i++) {
|
|
4118
|
+
const entry = entries[i];
|
|
4119
|
+
if (entry.active) enqueueEffectEventCommitAction(entry.action);
|
|
4120
|
+
}
|
|
4097
4121
|
}
|
|
4098
4122
|
function useLinkedState(source, reconcile, options, slot) {
|
|
4099
4123
|
if (typeof options === "symbol") {
|
|
@@ -5167,10 +5191,10 @@ function beginHydratePreload(state) {
|
|
|
5167
5191
|
return promise;
|
|
5168
5192
|
}
|
|
5169
5193
|
function resolveHydrateWaiters(state, reason) {
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
state.hydrationWaiters
|
|
5173
|
-
for (
|
|
5194
|
+
const waiters = state.hydrationWaiters;
|
|
5195
|
+
if (waiters === null) return;
|
|
5196
|
+
state.hydrationWaiters = null;
|
|
5197
|
+
for (const waiter of waiters) waiter(reason);
|
|
5174
5198
|
}
|
|
5175
5199
|
function waitForHydratePrefetchStrategy(state, strategy) {
|
|
5176
5200
|
const controller = state.prefetchAbort;
|
|
@@ -5184,13 +5208,13 @@ function waitForHydratePrefetchStrategy(state, strategy) {
|
|
|
5184
5208
|
if (settled) return;
|
|
5185
5209
|
settled = true;
|
|
5186
5210
|
cleanup?.();
|
|
5187
|
-
state.hydrationWaiters
|
|
5211
|
+
state.hydrationWaiters?.delete(onHydrate);
|
|
5188
5212
|
signal.removeEventListener("abort", onAbort);
|
|
5189
5213
|
resolve(reason);
|
|
5190
5214
|
};
|
|
5191
5215
|
const onHydrate = () => finish("hydrate");
|
|
5192
5216
|
const onAbort = () => finish("abort");
|
|
5193
|
-
state.hydrationWaiters.add(onHydrate);
|
|
5217
|
+
(state.hydrationWaiters ??= /* @__PURE__ */ new Set()).add(onHydrate);
|
|
5194
5218
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
5195
5219
|
cleanup = strategy._s?.({
|
|
5196
5220
|
element: state.wrapper,
|
|
@@ -5590,7 +5614,7 @@ function createHydrateSlot(props, scope, boundaryId) {
|
|
|
5590
5614
|
prefetchPromise: null,
|
|
5591
5615
|
preloadPromise: null,
|
|
5592
5616
|
loadedBody: null,
|
|
5593
|
-
hydrationWaiters:
|
|
5617
|
+
hydrationWaiters: null,
|
|
5594
5618
|
activationGeneration: 0,
|
|
5595
5619
|
activationRequested: !serverPreserved,
|
|
5596
5620
|
activationReady: !serverPreserved,
|
|
@@ -19309,28 +19333,23 @@ function enqueueInlineCaughtError(state) {
|
|
|
19309
19333
|
const handler = rootErrorHandlersFor(block)?.onCaughtError;
|
|
19310
19334
|
if (handler === void 0) return;
|
|
19311
19335
|
const error = state.err;
|
|
19312
|
-
let
|
|
19336
|
+
let parked = null;
|
|
19313
19337
|
let cleanupRegistered = false;
|
|
19314
19338
|
const action = (owner2) => {
|
|
19315
|
-
|
|
19339
|
+
parked = null;
|
|
19316
19340
|
if (block.disposed || state.block !== block) return;
|
|
19317
19341
|
const hidden = owner2 ?? findScheduledVisibilityOwner(block, true);
|
|
19318
19342
|
if (hidden !== null) {
|
|
19319
|
-
parkedOwner = hidden;
|
|
19320
19343
|
if (!cleanupRegistered) {
|
|
19321
19344
|
cleanupRegistered = true;
|
|
19322
19345
|
(block.cleanups ??= []).push(() => {
|
|
19323
|
-
const
|
|
19324
|
-
|
|
19325
|
-
if (
|
|
19326
|
-
|
|
19327
|
-
if (actions === void 0) return;
|
|
19328
|
-
const index = actions.indexOf(action);
|
|
19329
|
-
if (index !== -1) actions.splice(index, 1);
|
|
19330
|
-
if (actions.length === 0) HIDDEN_REVEAL_ACTIONS.delete(owner3);
|
|
19346
|
+
const pending = parked;
|
|
19347
|
+
parked = null;
|
|
19348
|
+
if (pending === null) return;
|
|
19349
|
+
cancelHiddenRevealAction(pending.owner, pending.entry);
|
|
19331
19350
|
});
|
|
19332
19351
|
}
|
|
19333
|
-
deferHiddenRevealAction(hidden, action);
|
|
19352
|
+
parked = { owner: hidden, entry: deferHiddenRevealAction(hidden, action) };
|
|
19334
19353
|
return;
|
|
19335
19354
|
}
|
|
19336
19355
|
return { state, block, error, handler, resume: action };
|
package/dist/signals/engine.js
CHANGED
|
@@ -332,10 +332,14 @@ class ScopeImpl {
|
|
|
332
332
|
type,
|
|
333
333
|
...node ? { key: node.key, revision: node.revision } : {}
|
|
334
334
|
};
|
|
335
|
-
if (this.events.length === this.traceLimit)
|
|
336
|
-
|
|
335
|
+
if (this.events.length === this.traceLimit) {
|
|
336
|
+
this.events[(event.sequence - 1) % this.traceLimit] = event;
|
|
337
|
+
} else {
|
|
338
|
+
this.events.push(event);
|
|
339
|
+
}
|
|
337
340
|
}
|
|
338
341
|
inspect() {
|
|
342
|
+
const traceStart = this.traceLimit && this.events.length === this.traceLimit ? this.sequence % this.traceLimit : 0;
|
|
339
343
|
return {
|
|
340
344
|
scopeKey: this.scopeKey,
|
|
341
345
|
epoch: this.epoch,
|
|
@@ -364,7 +368,9 @@ class ScopeImpl {
|
|
|
364
368
|
dependencies
|
|
365
369
|
};
|
|
366
370
|
}),
|
|
367
|
-
trace: this.events.map((event) => ({
|
|
371
|
+
trace: this.events.map((event, index) => ({
|
|
372
|
+
...traceStart ? this.events[(traceStart + index) % this.events.length] : event
|
|
373
|
+
}))
|
|
368
374
|
};
|
|
369
375
|
}
|
|
370
376
|
dispose() {
|
package/dist/universal-core.js
CHANGED
|
@@ -8914,6 +8914,7 @@ function createObjectDriver(renderer = "object") {
|
|
|
8914
8914
|
);
|
|
8915
8915
|
}
|
|
8916
8916
|
const state = container[OBJECT_DRIVER_STATE];
|
|
8917
|
+
const useBatchedDetaches = batch.commands.length >= 4096;
|
|
8917
8918
|
const simulated = /* @__PURE__ */ new Map();
|
|
8918
8919
|
const destroyed = /* @__PURE__ */ new Set();
|
|
8919
8920
|
const readSimulated = (id) => {
|
|
@@ -8946,27 +8947,66 @@ function createObjectDriver(renderer = "object") {
|
|
|
8946
8947
|
const DETACHED = /* @__PURE__ */ Symbol("octane.object-driver.detached");
|
|
8947
8948
|
const parentChanges = /* @__PURE__ */ new Map();
|
|
8948
8949
|
let rootChildren = null;
|
|
8950
|
+
let pendingDetaches = null;
|
|
8949
8951
|
const readParent = (id) => {
|
|
8950
8952
|
if (parentChanges.has(id)) return parentChanges.get(id);
|
|
8951
8953
|
return state.parents.has(id) ? state.parents.get(id) : DETACHED;
|
|
8952
8954
|
};
|
|
8955
|
+
const flushPendingDetaches = (parent, children) => {
|
|
8956
|
+
const detached = pendingDetaches?.get(parent);
|
|
8957
|
+
if (detached === void 0) return;
|
|
8958
|
+
let write = 0;
|
|
8959
|
+
for (let read = 0; read < children.length; read++) {
|
|
8960
|
+
const child = children[read];
|
|
8961
|
+
if (!detached.delete(child)) children[write++] = child;
|
|
8962
|
+
}
|
|
8963
|
+
if (detached.size !== 0) {
|
|
8964
|
+
const missing = detached.values().next().value;
|
|
8965
|
+
throw new Error(`Object driver: child ${missing} is not attached.`);
|
|
8966
|
+
}
|
|
8967
|
+
children.length = write;
|
|
8968
|
+
pendingDetaches.delete(parent);
|
|
8969
|
+
if (pendingDetaches.size === 0) pendingDetaches = null;
|
|
8970
|
+
};
|
|
8953
8971
|
const simulatedChildren = (parent) => {
|
|
8972
|
+
let children;
|
|
8954
8973
|
if (parent === null) {
|
|
8955
|
-
|
|
8974
|
+
children = rootChildren ??= container.children.map((child) => child.id);
|
|
8975
|
+
} else {
|
|
8976
|
+
const value = readSimulated(parent);
|
|
8977
|
+
if (value === void 0) throw new Error(`Object driver: unknown parent ${parent}.`);
|
|
8978
|
+
children = value.children;
|
|
8956
8979
|
}
|
|
8957
|
-
|
|
8958
|
-
|
|
8959
|
-
return value.children;
|
|
8980
|
+
flushPendingDetaches(parent, children);
|
|
8981
|
+
return children;
|
|
8960
8982
|
};
|
|
8961
|
-
const detachSimulated = (id) => {
|
|
8983
|
+
const detachSimulated = (id, defer) => {
|
|
8962
8984
|
const parent = readParent(id);
|
|
8963
8985
|
if (parent === DETACHED) return;
|
|
8964
|
-
|
|
8965
|
-
|
|
8966
|
-
|
|
8967
|
-
|
|
8986
|
+
if (useBatchedDetaches && defer) {
|
|
8987
|
+
const detaches = pendingDetaches ??= /* @__PURE__ */ new Map();
|
|
8988
|
+
const detached = detaches.get(parent);
|
|
8989
|
+
if (detached === void 0) detaches.set(parent, /* @__PURE__ */ new Set([id]));
|
|
8990
|
+
else detached.add(id);
|
|
8991
|
+
} else {
|
|
8992
|
+
const children = simulatedChildren(parent);
|
|
8993
|
+
const index = children.indexOf(id);
|
|
8994
|
+
if (index === -1) throw new Error(`Object driver: child ${id} is not attached.`);
|
|
8995
|
+
children.splice(index, 1);
|
|
8996
|
+
}
|
|
8968
8997
|
parentChanges.set(id, DETACHED);
|
|
8969
8998
|
};
|
|
8999
|
+
const forgetPendingDetachParent = (parent) => {
|
|
9000
|
+
if (pendingDetaches === null) return;
|
|
9001
|
+
pendingDetaches.delete(parent);
|
|
9002
|
+
if (pendingDetaches.size === 0) pendingDetaches = null;
|
|
9003
|
+
};
|
|
9004
|
+
const flushAllPendingDetaches = () => {
|
|
9005
|
+
while (pendingDetaches !== null) {
|
|
9006
|
+
const parent = pendingDetaches.keys().next().value;
|
|
9007
|
+
simulatedChildren(parent);
|
|
9008
|
+
}
|
|
9009
|
+
};
|
|
8970
9010
|
for (const command of batch.commands) {
|
|
8971
9011
|
if (command.op === "create") {
|
|
8972
9012
|
if (hasSimulated(command.id))
|
|
@@ -9048,7 +9088,7 @@ function createObjectDriver(renderer = "object") {
|
|
|
9048
9088
|
}
|
|
9049
9089
|
if (!hasSimulated(command.id))
|
|
9050
9090
|
throw new Error(`Object driver: unknown child ${command.id}.`);
|
|
9051
|
-
detachSimulated(command.id);
|
|
9091
|
+
detachSimulated(command.id, false);
|
|
9052
9092
|
const children = simulatedChildren(command.parent);
|
|
9053
9093
|
const before = command.before === null ? children.length : children.indexOf(command.before);
|
|
9054
9094
|
if (before === -1) throw new Error(`Object driver: unknown before id ${command.before}.`);
|
|
@@ -9065,11 +9105,10 @@ function createObjectDriver(renderer = "object") {
|
|
|
9065
9105
|
if (command.parent !== null && typeof command.parent !== "number") {
|
|
9066
9106
|
throw new Error("Object driver does not support portal target parents.");
|
|
9067
9107
|
}
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
parentChanges.set(command.id, DETACHED);
|
|
9108
|
+
if (readParent(command.id) !== command.parent) {
|
|
9109
|
+
throw new Error(`Object driver: child ${command.id} is not attached.`);
|
|
9110
|
+
}
|
|
9111
|
+
detachSimulated(command.id, true);
|
|
9073
9112
|
for (const type of readSimulated(command.id).localCallbacks.keys()) {
|
|
9074
9113
|
cleanupKeys.add(keyFor(command.id, type));
|
|
9075
9114
|
}
|
|
@@ -9077,12 +9116,14 @@ function createObjectDriver(renderer = "object") {
|
|
|
9077
9116
|
const instance = readSimulated(command.id);
|
|
9078
9117
|
if (instance === void 0)
|
|
9079
9118
|
throw new Error(`Object driver: unknown destroy ${command.id}.`);
|
|
9080
|
-
detachSimulated(command.id);
|
|
9119
|
+
detachSimulated(command.id, true);
|
|
9081
9120
|
for (const child of instance.children) parentChanges.set(child, DETACHED);
|
|
9082
9121
|
instance.children.length = 0;
|
|
9122
|
+
forgetPendingDetachParent(command.id);
|
|
9083
9123
|
destroyed.add(command.id);
|
|
9084
9124
|
}
|
|
9085
9125
|
}
|
|
9126
|
+
flushAllPendingDetaches();
|
|
9086
9127
|
for (const [id, instance] of stagedInstances) {
|
|
9087
9128
|
const staged = readSimulated(id);
|
|
9088
9129
|
if (staged === void 0) continue;
|
|
@@ -9097,16 +9138,48 @@ function createObjectDriver(renderer = "object") {
|
|
|
9097
9138
|
}
|
|
9098
9139
|
let status = "prepared";
|
|
9099
9140
|
let acceptedCallbacksRan = false;
|
|
9100
|
-
|
|
9101
|
-
const
|
|
9141
|
+
let pendingLiveDetaches = null;
|
|
9142
|
+
const liveChildren = (parent) => {
|
|
9143
|
+
const children = objectChildren(container, parent, state.instances);
|
|
9144
|
+
const detached = pendingLiveDetaches?.get(parent);
|
|
9145
|
+
if (detached === void 0) return children;
|
|
9146
|
+
let write = 0;
|
|
9147
|
+
for (let read = 0; read < children.length; read++) {
|
|
9148
|
+
const child = children[read];
|
|
9149
|
+
if (!detached.has(child.id)) children[write++] = child;
|
|
9150
|
+
}
|
|
9151
|
+
children.length = write;
|
|
9152
|
+
pendingLiveDetaches.delete(parent);
|
|
9153
|
+
if (pendingLiveDetaches.size === 0) pendingLiveDetaches = null;
|
|
9154
|
+
return children;
|
|
9155
|
+
};
|
|
9156
|
+
const detachLive = (id, defer) => {
|
|
9102
9157
|
if (!state.parents.has(id)) return;
|
|
9103
9158
|
const parent = state.parents.get(id);
|
|
9104
9159
|
const instance = state.instances.get(id);
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9160
|
+
if (useBatchedDetaches && defer) {
|
|
9161
|
+
const detaches = pendingLiveDetaches ??= /* @__PURE__ */ new Map();
|
|
9162
|
+
const detached = detaches.get(parent);
|
|
9163
|
+
if (detached === void 0) detaches.set(parent, /* @__PURE__ */ new Set([id]));
|
|
9164
|
+
else detached.add(id);
|
|
9165
|
+
} else {
|
|
9166
|
+
const children = liveChildren(parent);
|
|
9167
|
+
const index = children.indexOf(instance);
|
|
9168
|
+
if (index !== -1) children.splice(index, 1);
|
|
9169
|
+
}
|
|
9108
9170
|
state.parents.delete(id);
|
|
9109
9171
|
};
|
|
9172
|
+
const forgetPendingLiveParent = (parent) => {
|
|
9173
|
+
if (pendingLiveDetaches === null) return;
|
|
9174
|
+
pendingLiveDetaches.delete(parent);
|
|
9175
|
+
if (pendingLiveDetaches.size === 0) pendingLiveDetaches = null;
|
|
9176
|
+
};
|
|
9177
|
+
const flushAllPendingLiveDetaches = () => {
|
|
9178
|
+
while (pendingLiveDetaches !== null) {
|
|
9179
|
+
const parent = pendingLiveDetaches.keys().next().value;
|
|
9180
|
+
liveChildren(parent);
|
|
9181
|
+
}
|
|
9182
|
+
};
|
|
9110
9183
|
return {
|
|
9111
9184
|
apply() {
|
|
9112
9185
|
if (status !== "prepared") return;
|
|
@@ -9163,7 +9236,7 @@ function createObjectDriver(renderer = "object") {
|
|
|
9163
9236
|
throw new Error("Object driver does not support portal target parents.");
|
|
9164
9237
|
}
|
|
9165
9238
|
const instance = state.instances.get(command.id);
|
|
9166
|
-
detachLive(command.id);
|
|
9239
|
+
detachLive(command.id, false);
|
|
9167
9240
|
const children = liveChildren(command.parent);
|
|
9168
9241
|
const before = command.before === null ? children.length : children.indexOf(state.instances.get(command.before));
|
|
9169
9242
|
children.splice(before, 0, instance);
|
|
@@ -9172,14 +9245,13 @@ function createObjectDriver(renderer = "object") {
|
|
|
9172
9245
|
if (command.parent !== null && typeof command.parent !== "number") {
|
|
9173
9246
|
throw new Error("Object driver does not support portal target parents.");
|
|
9174
9247
|
}
|
|
9175
|
-
|
|
9176
|
-
children.splice(children.indexOf(state.instances.get(command.id)), 1);
|
|
9177
|
-
state.parents.delete(command.id);
|
|
9248
|
+
detachLive(command.id, true);
|
|
9178
9249
|
} else if (command.op === "destroy") {
|
|
9179
9250
|
const instance = state.instances.get(command.id);
|
|
9180
|
-
detachLive(command.id);
|
|
9251
|
+
detachLive(command.id, true);
|
|
9181
9252
|
for (const child of instance.children) state.parents.delete(child.id);
|
|
9182
9253
|
instance.children.length = 0;
|
|
9254
|
+
forgetPendingLiveParent(command.id);
|
|
9183
9255
|
state.instances.delete(command.id);
|
|
9184
9256
|
state.parents.delete(command.id);
|
|
9185
9257
|
state.events.delete(command.id);
|
|
@@ -9188,6 +9260,7 @@ function createObjectDriver(renderer = "object") {
|
|
|
9188
9260
|
state.localCleanups.delete(command.id);
|
|
9189
9261
|
}
|
|
9190
9262
|
}
|
|
9263
|
+
flushAllPendingLiveDetaches();
|
|
9191
9264
|
container.commits.push(batch);
|
|
9192
9265
|
});
|
|
9193
9266
|
runCommitTasks(tasks);
|
package/dist/version.js
CHANGED