@askrjs/askr 0.0.1 → 0.0.2
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/README.md +18 -10
- package/dist/chunk-KR6HG7HF.js +38 -0
- package/dist/chunk-KR6HG7HF.js.map +1 -0
- package/dist/{chunk-L7RL4LYV.js → chunk-MIPES65F.js} +1486 -1905
- package/dist/chunk-MIPES65F.js.map +1 -0
- package/dist/{chunk-HIWJVOS4.js → chunk-PFOLLB6A.js} +38 -17
- package/dist/chunk-PFOLLB6A.js.map +1 -0
- package/dist/chunk-QECQ2TF6.js +28 -0
- package/dist/chunk-QECQ2TF6.js.map +1 -0
- package/dist/{chunk-UUM5W2RM.js → chunk-RJWOOUYV.js} +2 -2
- package/dist/chunk-RJWOOUYV.js.map +1 -0
- package/dist/index.cjs +1760 -1972
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -40
- package/dist/index.d.ts +52 -40
- package/dist/index.js +226 -52
- package/dist/index.js.map +1 -1
- package/dist/jsx/jsx-dev-runtime.cjs +9 -3
- package/dist/jsx/jsx-dev-runtime.cjs.map +1 -1
- package/dist/jsx/jsx-dev-runtime.d.cts +4 -9
- package/dist/jsx/jsx-dev-runtime.d.ts +4 -9
- package/dist/jsx/jsx-dev-runtime.js +10 -4
- package/dist/jsx/jsx-dev-runtime.js.map +1 -1
- package/dist/jsx/jsx-runtime.cjs +14 -5
- package/dist/jsx/jsx-runtime.cjs.map +1 -1
- package/dist/jsx/jsx-runtime.d.cts +9 -6
- package/dist/jsx/jsx-runtime.d.ts +9 -6
- package/dist/jsx/jsx-runtime.js +6 -2
- package/dist/{navigate-NLQOZQGM.js → navigate-SDZNA2ZE.js} +5 -5
- package/dist/{route-TVYWYCEJ.js → route-P5YQBT4T.js} +4 -4
- package/dist/{ssr-4ELUFK65.js → ssr-65K3IJ6B.js} +9 -5
- package/dist/{types-DUDmnzD8.d.cts → types-DLTViI21.d.cts} +15 -3
- package/dist/{types-DUDmnzD8.d.ts → types-DLTViI21.d.ts} +15 -3
- package/package.json +5 -3
- package/src/jsx/index.ts +4 -0
- package/src/jsx/jsx-dev-runtime.ts +7 -10
- package/src/jsx/jsx-runtime.ts +23 -11
- package/src/jsx/types.ts +22 -3
- package/src/jsx/utils.ts +19 -0
- package/dist/chunk-4CV4JOE5.js +0 -27
- package/dist/chunk-HIWJVOS4.js.map +0 -1
- package/dist/chunk-L7RL4LYV.js.map +0 -1
- package/dist/chunk-UUM5W2RM.js.map +0 -1
- package/dist/chunk-YNH3D4KW.js +0 -29
- package/dist/chunk-YNH3D4KW.js.map +0 -1
- package/dist/ssr-4ELUFK65.js.map +0 -1
- package/src/jsx/react-jsx-runtime.d.ts +0 -0
- /package/dist/{chunk-4CV4JOE5.js.map → navigate-SDZNA2ZE.js.map} +0 -0
- /package/dist/{navigate-NLQOZQGM.js.map → route-P5YQBT4T.js.map} +0 -0
- /package/dist/{route-TVYWYCEJ.js.map → ssr-65K3IJ6B.js.map} +0 -0
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Fragment,
|
|
3
3
|
init_jsx_runtime
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KR6HG7HF.js";
|
|
5
5
|
import {
|
|
6
6
|
__esm,
|
|
7
|
-
__export
|
|
8
|
-
|
|
9
|
-
} from "./chunk-4CV4JOE5.js";
|
|
7
|
+
__export
|
|
8
|
+
} from "./chunk-QECQ2TF6.js";
|
|
10
9
|
|
|
11
10
|
// src/dev/invariant.ts
|
|
12
11
|
function invariant(condition, message, context) {
|
|
@@ -267,17 +266,14 @@ var init_scheduler = __esm({
|
|
|
267
266
|
if (this.flushVersion >= target) return Promise.resolve();
|
|
268
267
|
return new Promise((resolve, reject) => {
|
|
269
268
|
const timer = setTimeout(() => {
|
|
269
|
+
const ns = globalThis.__ASKR__ || {};
|
|
270
270
|
const diag = {
|
|
271
271
|
flushVersion: this.flushVersion,
|
|
272
272
|
queueLen: this.q.length - this.head,
|
|
273
273
|
running: this.running,
|
|
274
274
|
inHandler: this.inHandler,
|
|
275
275
|
bulk: isBulkCommitActive(),
|
|
276
|
-
|
|
277
|
-
__ASKR_LAST_FASTPATH_STATS: globalThis.__ASKR_LAST_FASTPATH_STATS,
|
|
278
|
-
__ASKR_LAST_BULK_TEXT_FASTPATH_STATS: globalThis.__ASKR_LAST_BULK_TEXT_FASTPATH_STATS,
|
|
279
|
-
__ASKR_FASTPATH_COUNTERS: globalThis.__ASKR_FASTPATH_COUNTERS
|
|
280
|
-
}
|
|
276
|
+
namespace: ns
|
|
281
277
|
};
|
|
282
278
|
reject(
|
|
283
279
|
new Error(
|
|
@@ -354,248 +350,6 @@ var init_scheduler = __esm({
|
|
|
354
350
|
}
|
|
355
351
|
});
|
|
356
352
|
|
|
357
|
-
// src/runtime/fastlane.ts
|
|
358
|
-
function enterBulkCommit() {
|
|
359
|
-
_bulkCommitActive = true;
|
|
360
|
-
_appliedParents = /* @__PURE__ */ new WeakSet();
|
|
361
|
-
try {
|
|
362
|
-
const cleared = globalScheduler.clearPendingSyncTasks?.() ?? 0;
|
|
363
|
-
if (process.env.NODE_ENV !== "production") {
|
|
364
|
-
const _g = globalThis;
|
|
365
|
-
_g.__ASKR_FASTLANE_CLEARED_TASKS = cleared;
|
|
366
|
-
}
|
|
367
|
-
} catch (err) {
|
|
368
|
-
if (process.env.NODE_ENV !== "production") throw err;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
function exitBulkCommit() {
|
|
372
|
-
_bulkCommitActive = false;
|
|
373
|
-
_appliedParents = null;
|
|
374
|
-
}
|
|
375
|
-
function isBulkCommitActive2() {
|
|
376
|
-
return _bulkCommitActive;
|
|
377
|
-
}
|
|
378
|
-
function markFastPathApplied(parent) {
|
|
379
|
-
if (!_appliedParents) return;
|
|
380
|
-
try {
|
|
381
|
-
_appliedParents.add(parent);
|
|
382
|
-
} catch (e) {
|
|
383
|
-
void e;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
function isFastPathApplied(parent) {
|
|
387
|
-
return !!(_appliedParents && _appliedParents.has(parent));
|
|
388
|
-
}
|
|
389
|
-
function classifyUpdate(instance, result) {
|
|
390
|
-
if (!result || typeof result !== "object" || !("type" in result))
|
|
391
|
-
return { useFastPath: false, reason: "not-vnode" };
|
|
392
|
-
const vnode = result;
|
|
393
|
-
if (vnode == null || typeof vnode.type !== "string")
|
|
394
|
-
return { useFastPath: false, reason: "not-intrinsic" };
|
|
395
|
-
const parent = instance.target;
|
|
396
|
-
if (!parent) return { useFastPath: false, reason: "no-root" };
|
|
397
|
-
const firstChild = parent.children[0];
|
|
398
|
-
if (!firstChild) return { useFastPath: false, reason: "no-first-child" };
|
|
399
|
-
if (firstChild.tagName.toLowerCase() !== String(vnode.type).toLowerCase())
|
|
400
|
-
return { useFastPath: false, reason: "root-tag-mismatch" };
|
|
401
|
-
const children = vnode.children || vnode.props?.children;
|
|
402
|
-
if (!Array.isArray(children))
|
|
403
|
-
return { useFastPath: false, reason: "no-children-array" };
|
|
404
|
-
for (let i = 0; i < children.length; i++) {
|
|
405
|
-
const c = children[i];
|
|
406
|
-
if (typeof c === "object" && c !== null && "type" in c && typeof c.type === "function") {
|
|
407
|
-
return { useFastPath: false, reason: "component-child-present" };
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
if (instance.mountOperations.length > 0)
|
|
411
|
-
return { useFastPath: false, reason: "pending-mounts" };
|
|
412
|
-
const oldKeyMap = getKeyMapForElement(firstChild);
|
|
413
|
-
const decision = isKeyedReorderFastPathEligible(
|
|
414
|
-
firstChild,
|
|
415
|
-
children,
|
|
416
|
-
oldKeyMap
|
|
417
|
-
);
|
|
418
|
-
if (!decision.useFastPath || decision.totalKeyed < 128)
|
|
419
|
-
return { ...decision, useFastPath: false, reason: "renderer-declined" };
|
|
420
|
-
return { ...decision, useFastPath: true };
|
|
421
|
-
}
|
|
422
|
-
function commitReorderOnly(instance, result) {
|
|
423
|
-
const evaluate2 = globalThis.__ASKR_RENDERER?.evaluate;
|
|
424
|
-
if (typeof evaluate2 !== "function") {
|
|
425
|
-
logger.warn(
|
|
426
|
-
"[Tempo][FASTPATH][DEV] renderer.evaluate not available; declining fast-lane"
|
|
427
|
-
);
|
|
428
|
-
return false;
|
|
429
|
-
}
|
|
430
|
-
const schedBefore = process.env.NODE_ENV !== "production" ? globalScheduler.getState() : null;
|
|
431
|
-
enterBulkCommit();
|
|
432
|
-
try {
|
|
433
|
-
globalScheduler.runWithSyncProgress(() => {
|
|
434
|
-
evaluate2(result, instance.target);
|
|
435
|
-
try {
|
|
436
|
-
const comp = (init_component(), __toCommonJS(component_exports));
|
|
437
|
-
if (typeof comp?.finalizeReadSubscriptions === "function") {
|
|
438
|
-
try {
|
|
439
|
-
comp.finalizeReadSubscriptions(instance);
|
|
440
|
-
} catch (e) {
|
|
441
|
-
if (process.env.NODE_ENV !== "production") throw e;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
} catch (e) {
|
|
445
|
-
void e;
|
|
446
|
-
}
|
|
447
|
-
});
|
|
448
|
-
try {
|
|
449
|
-
const clearedAfter = globalScheduler.clearPendingSyncTasks?.() ?? 0;
|
|
450
|
-
if (process.env.NODE_ENV !== "production") {
|
|
451
|
-
const _g = globalThis;
|
|
452
|
-
_g.__ASKR_FASTLANE_CLEARED_AFTER = clearedAfter;
|
|
453
|
-
}
|
|
454
|
-
} catch (err) {
|
|
455
|
-
if (process.env.NODE_ENV !== "production") throw err;
|
|
456
|
-
}
|
|
457
|
-
if (process.env.NODE_ENV !== "production") {
|
|
458
|
-
const _g = globalThis;
|
|
459
|
-
const commitCount = _g.__ASKR_LAST_FASTPATH_COMMIT_COUNT ?? 0;
|
|
460
|
-
const invariants = {
|
|
461
|
-
commitCount,
|
|
462
|
-
mountOps: instance.mountOperations.length,
|
|
463
|
-
cleanupFns: instance.cleanupFns.length
|
|
464
|
-
};
|
|
465
|
-
_g.__ASKR_LAST_FASTLANE_INVARIANTS = invariants;
|
|
466
|
-
if (commitCount !== 1) {
|
|
467
|
-
throw new Error(
|
|
468
|
-
"Fast-lane invariant violated: expected exactly one DOM commit during reorder-only commit"
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
if (invariants.mountOps > 0) {
|
|
472
|
-
throw new Error(
|
|
473
|
-
"Fast-lane invariant violated: mount operations were registered during bulk commit"
|
|
474
|
-
);
|
|
475
|
-
}
|
|
476
|
-
if (invariants.cleanupFns > 0) {
|
|
477
|
-
throw new Error(
|
|
478
|
-
"Fast-lane invariant violated: cleanup functions were added during bulk commit"
|
|
479
|
-
);
|
|
480
|
-
}
|
|
481
|
-
const schedAfter = globalScheduler.getState();
|
|
482
|
-
if (schedBefore && schedAfter && // Only fail if outstanding tasks increased — consuming existing tasks is allowed
|
|
483
|
-
schedAfter.taskCount > schedBefore.taskCount) {
|
|
484
|
-
try {
|
|
485
|
-
console.error(
|
|
486
|
-
"[FASTLANE] schedBefore, schedAfter",
|
|
487
|
-
schedBefore,
|
|
488
|
-
schedAfter
|
|
489
|
-
);
|
|
490
|
-
console.error(
|
|
491
|
-
"[FASTLANE] enqueue logs",
|
|
492
|
-
globalThis.__ASKR_ENQUEUE_LOGS
|
|
493
|
-
);
|
|
494
|
-
} catch (e) {
|
|
495
|
-
void e;
|
|
496
|
-
}
|
|
497
|
-
throw new Error(
|
|
498
|
-
"Fast-lane invariant violated: scheduler enqueued leftover work during bulk commit"
|
|
499
|
-
);
|
|
500
|
-
}
|
|
501
|
-
let finalState = globalScheduler.getState();
|
|
502
|
-
const executing = globalScheduler.isExecuting();
|
|
503
|
-
const outstandingAfter = Math.max(
|
|
504
|
-
0,
|
|
505
|
-
finalState.taskCount - (executing ? 1 : 0)
|
|
506
|
-
);
|
|
507
|
-
if (outstandingAfter !== 0) {
|
|
508
|
-
if (process.env.NODE_ENV !== "production") {
|
|
509
|
-
let attempts = 0;
|
|
510
|
-
while (attempts < 5) {
|
|
511
|
-
const cleared = globalScheduler.clearPendingSyncTasks?.() ?? 0;
|
|
512
|
-
if (cleared === 0) break;
|
|
513
|
-
attempts++;
|
|
514
|
-
}
|
|
515
|
-
finalState = globalScheduler.getState();
|
|
516
|
-
const outstandingAfter2 = Math.max(
|
|
517
|
-
0,
|
|
518
|
-
finalState.taskCount - (globalScheduler.isExecuting() ? 1 : 0)
|
|
519
|
-
);
|
|
520
|
-
if (outstandingAfter2 !== 0) {
|
|
521
|
-
try {
|
|
522
|
-
const _g2 = globalThis;
|
|
523
|
-
console.error(
|
|
524
|
-
"[FASTLANE] Post-commit enqueue logs:",
|
|
525
|
-
_g2.__ASKR_ENQUEUE_LOGS
|
|
526
|
-
);
|
|
527
|
-
console.error(
|
|
528
|
-
"[FASTLANE] Cleared counts:",
|
|
529
|
-
_g2.__ASKR_FASTLANE_CLEARED_TASKS,
|
|
530
|
-
_g2.__ASKR_FASTLANE_CLEARED_AFTER
|
|
531
|
-
);
|
|
532
|
-
} catch (err) {
|
|
533
|
-
void err;
|
|
534
|
-
}
|
|
535
|
-
throw new Error(
|
|
536
|
-
`Fast-lane invariant violated: scheduler has ${finalState.taskCount} pending task(s) after commit`
|
|
537
|
-
);
|
|
538
|
-
}
|
|
539
|
-
} else {
|
|
540
|
-
globalScheduler.clearPendingSyncTasks?.();
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
return true;
|
|
545
|
-
} finally {
|
|
546
|
-
exitBulkCommit();
|
|
547
|
-
if (process.env.NODE_ENV !== "production") {
|
|
548
|
-
try {
|
|
549
|
-
const _g = globalThis;
|
|
550
|
-
_g.__ASKR_FASTLANE_BULK_FLAG_CHECK = isBulkCommitActive2();
|
|
551
|
-
} catch (e) {
|
|
552
|
-
void e;
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
if (process.env.NODE_ENV !== "production") {
|
|
557
|
-
const _g = globalThis;
|
|
558
|
-
if (_g.__ASKR_FASTLANE_BULK_FLAG_CHECK) {
|
|
559
|
-
delete _g.__ASKR_FASTLANE_BULK_FLAG_CHECK;
|
|
560
|
-
throw new Error(
|
|
561
|
-
"Fast-lane invariant violated: bulk commit flag still set after commit"
|
|
562
|
-
);
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
function tryRuntimeFastLaneSync(instance, result) {
|
|
567
|
-
const cls = classifyUpdate(instance, result);
|
|
568
|
-
if (!cls.useFastPath) return false;
|
|
569
|
-
try {
|
|
570
|
-
return commitReorderOnly(instance, result);
|
|
571
|
-
} catch (err) {
|
|
572
|
-
if (process.env.NODE_ENV !== "production") throw err;
|
|
573
|
-
return false;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
var _bulkCommitActive, _appliedParents;
|
|
577
|
-
var init_fastlane = __esm({
|
|
578
|
-
"src/runtime/fastlane.ts"() {
|
|
579
|
-
"use strict";
|
|
580
|
-
init_scheduler();
|
|
581
|
-
init_logger();
|
|
582
|
-
init_dom();
|
|
583
|
-
_bulkCommitActive = false;
|
|
584
|
-
_appliedParents = null;
|
|
585
|
-
if (typeof globalThis !== "undefined") {
|
|
586
|
-
const _g = globalThis;
|
|
587
|
-
_g.__ASKR_FASTLANE = {
|
|
588
|
-
isBulkCommitActive: isBulkCommitActive2,
|
|
589
|
-
enterBulkCommit,
|
|
590
|
-
exitBulkCommit,
|
|
591
|
-
tryRuntimeFastLaneSync,
|
|
592
|
-
markFastPathApplied,
|
|
593
|
-
isFastPathApplied
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
});
|
|
598
|
-
|
|
599
353
|
// src/runtime/context.ts
|
|
600
354
|
function withContext(frame, fn) {
|
|
601
355
|
const oldFrame = currentContextFrame;
|
|
@@ -621,9 +375,10 @@ function defineContext(defaultValue) {
|
|
|
621
375
|
key,
|
|
622
376
|
defaultValue,
|
|
623
377
|
Scope: (props) => {
|
|
378
|
+
const value = props.value;
|
|
624
379
|
return {
|
|
625
380
|
type: ContextScopeComponent,
|
|
626
|
-
props: { key, value
|
|
381
|
+
props: { key, value, children: props.children }
|
|
627
382
|
};
|
|
628
383
|
}
|
|
629
384
|
};
|
|
@@ -659,29 +414,29 @@ function ContextScopeComponent(props) {
|
|
|
659
414
|
parent: parentFrame,
|
|
660
415
|
values: /* @__PURE__ */ new Map([[key, value]])
|
|
661
416
|
};
|
|
417
|
+
function createFunctionChildInvoker(fn, frame, owner) {
|
|
418
|
+
return {
|
|
419
|
+
type: ContextFunctionChildInvoker,
|
|
420
|
+
props: { fn, __frame: frame, __owner: owner }
|
|
421
|
+
};
|
|
422
|
+
}
|
|
662
423
|
if (Array.isArray(children)) {
|
|
663
424
|
return children.map((child) => {
|
|
664
425
|
if (typeof child === "function") {
|
|
665
|
-
return
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
__owner: getCurrentComponentInstance()
|
|
671
|
-
}
|
|
672
|
-
};
|
|
426
|
+
return createFunctionChildInvoker(
|
|
427
|
+
child,
|
|
428
|
+
newFrame,
|
|
429
|
+
getCurrentComponentInstance()
|
|
430
|
+
);
|
|
673
431
|
}
|
|
674
432
|
return markWithFrame(child, newFrame);
|
|
675
433
|
});
|
|
676
434
|
} else if (typeof children === "function") {
|
|
677
|
-
return
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
__owner: getCurrentComponentInstance()
|
|
683
|
-
}
|
|
684
|
-
};
|
|
435
|
+
return createFunctionChildInvoker(
|
|
436
|
+
children,
|
|
437
|
+
newFrame,
|
|
438
|
+
getCurrentComponentInstance()
|
|
439
|
+
);
|
|
685
440
|
} else if (children) {
|
|
686
441
|
return markWithFrame(children, newFrame);
|
|
687
442
|
}
|
|
@@ -725,22 +480,126 @@ var init_context = __esm({
|
|
|
725
480
|
}
|
|
726
481
|
});
|
|
727
482
|
|
|
728
|
-
// src/renderer/
|
|
729
|
-
function
|
|
483
|
+
// src/renderer/diag/index.ts
|
|
484
|
+
function getDiagMap() {
|
|
485
|
+
try {
|
|
486
|
+
const root = globalThis;
|
|
487
|
+
if (!root.__ASKR_DIAG) root.__ASKR_DIAG = {};
|
|
488
|
+
return root.__ASKR_DIAG;
|
|
489
|
+
} catch (e) {
|
|
490
|
+
void e;
|
|
491
|
+
return {};
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
function __ASKR_set(key, value) {
|
|
495
|
+
try {
|
|
496
|
+
const g = getDiagMap();
|
|
497
|
+
g[key] = value;
|
|
498
|
+
try {
|
|
499
|
+
const root = globalThis;
|
|
500
|
+
try {
|
|
501
|
+
const ns = root.__ASKR__ || (root.__ASKR__ = {});
|
|
502
|
+
try {
|
|
503
|
+
ns[key] = value;
|
|
504
|
+
} catch (e) {
|
|
505
|
+
void e;
|
|
506
|
+
}
|
|
507
|
+
} catch (e) {
|
|
508
|
+
void e;
|
|
509
|
+
}
|
|
510
|
+
} catch (e) {
|
|
511
|
+
void e;
|
|
512
|
+
}
|
|
513
|
+
} catch (e) {
|
|
514
|
+
void e;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
function __ASKR_incCounter(key) {
|
|
518
|
+
try {
|
|
519
|
+
const g = getDiagMap();
|
|
520
|
+
const prev = typeof g[key] === "number" ? g[key] : 0;
|
|
521
|
+
const next = prev + 1;
|
|
522
|
+
g[key] = next;
|
|
523
|
+
try {
|
|
524
|
+
const root = globalThis;
|
|
525
|
+
const ns = root.__ASKR__ || (root.__ASKR__ = {});
|
|
526
|
+
try {
|
|
527
|
+
const nsPrev = typeof ns[key] === "number" ? ns[key] : 0;
|
|
528
|
+
ns[key] = nsPrev + 1;
|
|
529
|
+
} catch (e) {
|
|
530
|
+
void e;
|
|
531
|
+
}
|
|
532
|
+
} catch (e) {
|
|
533
|
+
void e;
|
|
534
|
+
}
|
|
535
|
+
} catch (e) {
|
|
536
|
+
void e;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
var init_diag = __esm({
|
|
540
|
+
"src/renderer/diag/index.ts"() {
|
|
541
|
+
"use strict";
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// src/runtime/fastlane-shared.ts
|
|
546
|
+
function isBulkCommitActive2() {
|
|
547
|
+
return _bulkCommitActive;
|
|
548
|
+
}
|
|
549
|
+
function markFastPathApplied(parent) {
|
|
550
|
+
if (!_appliedParents) return;
|
|
551
|
+
try {
|
|
552
|
+
_appliedParents.add(parent);
|
|
553
|
+
} catch (e) {
|
|
554
|
+
void e;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
var _bulkCommitActive, _appliedParents;
|
|
558
|
+
var init_fastlane_shared = __esm({
|
|
559
|
+
"src/runtime/fastlane-shared.ts"() {
|
|
560
|
+
"use strict";
|
|
561
|
+
_bulkCommitActive = false;
|
|
562
|
+
_appliedParents = null;
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
// src/renderer/types.ts
|
|
567
|
+
function _isDOMElement(node) {
|
|
568
|
+
return typeof node === "object" && node !== null && "type" in node;
|
|
569
|
+
}
|
|
570
|
+
var init_types = __esm({
|
|
571
|
+
"src/renderer/types.ts"() {
|
|
572
|
+
"use strict";
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
// src/renderer/cleanup.ts
|
|
577
|
+
function cleanupInstanceIfPresent(node, opts) {
|
|
730
578
|
if (!node) return;
|
|
731
579
|
if (!(node instanceof Element)) return;
|
|
580
|
+
const errors = [];
|
|
732
581
|
try {
|
|
733
582
|
const inst = node.__ASKR_INSTANCE;
|
|
734
583
|
if (inst) {
|
|
735
|
-
|
|
584
|
+
try {
|
|
585
|
+
cleanupComponent(inst);
|
|
586
|
+
} catch (err) {
|
|
587
|
+
if (opts?.strict) errors.push(err);
|
|
588
|
+
else if (process.env.NODE_ENV !== "production")
|
|
589
|
+
logger.warn("[Askr] cleanupComponent failed:", err);
|
|
590
|
+
}
|
|
736
591
|
try {
|
|
737
592
|
delete node.__ASKR_INSTANCE;
|
|
738
593
|
} catch (e) {
|
|
739
|
-
|
|
594
|
+
if (opts?.strict) errors.push(e);
|
|
595
|
+
else void e;
|
|
740
596
|
}
|
|
741
597
|
}
|
|
742
598
|
} catch (err) {
|
|
743
|
-
|
|
599
|
+
if (opts?.strict) errors.push(err);
|
|
600
|
+
else if (process.env.NODE_ENV !== "production") {
|
|
601
|
+
logger.warn("[Askr] cleanupInstanceIfPresent failed:", err);
|
|
602
|
+
}
|
|
744
603
|
}
|
|
745
604
|
try {
|
|
746
605
|
const descendants = node.querySelectorAll("*");
|
|
@@ -748,32 +607,57 @@ function cleanupInstanceIfPresent(node) {
|
|
|
748
607
|
try {
|
|
749
608
|
const inst = d.__ASKR_INSTANCE;
|
|
750
609
|
if (inst) {
|
|
751
|
-
|
|
610
|
+
try {
|
|
611
|
+
cleanupComponent(inst);
|
|
612
|
+
} catch (err) {
|
|
613
|
+
if (opts?.strict) errors.push(err);
|
|
614
|
+
else if (process.env.NODE_ENV !== "production") {
|
|
615
|
+
logger.warn(
|
|
616
|
+
"[Askr] cleanupInstanceIfPresent descendant cleanup failed:",
|
|
617
|
+
err
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
752
621
|
try {
|
|
753
622
|
delete d.__ASKR_INSTANCE;
|
|
754
623
|
} catch (e) {
|
|
755
|
-
|
|
624
|
+
if (opts?.strict) errors.push(e);
|
|
625
|
+
else void e;
|
|
756
626
|
}
|
|
757
627
|
}
|
|
758
628
|
} catch (err) {
|
|
759
|
-
|
|
629
|
+
if (opts?.strict) errors.push(err);
|
|
630
|
+
else if (process.env.NODE_ENV !== "production") {
|
|
631
|
+
logger.warn(
|
|
632
|
+
"[Askr] cleanupInstanceIfPresent descendant cleanup failed:",
|
|
633
|
+
err
|
|
634
|
+
);
|
|
635
|
+
}
|
|
760
636
|
}
|
|
761
637
|
}
|
|
762
638
|
} catch (err) {
|
|
763
|
-
|
|
639
|
+
if (opts?.strict) errors.push(err);
|
|
640
|
+
else if (process.env.NODE_ENV !== "production") {
|
|
641
|
+
logger.warn(
|
|
642
|
+
"[Askr] cleanupInstanceIfPresent descendant query failed:",
|
|
643
|
+
err
|
|
644
|
+
);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
if (errors.length > 0) {
|
|
648
|
+
throw new AggregateError(errors, "cleanupInstanceIfPresent failed");
|
|
764
649
|
}
|
|
765
650
|
}
|
|
766
|
-
function
|
|
767
|
-
|
|
768
|
-
}
|
|
769
|
-
function getKeyMapForElement(el) {
|
|
770
|
-
return keyedElements.get(el);
|
|
651
|
+
function cleanupInstancesUnder(node, opts) {
|
|
652
|
+
cleanupInstanceIfPresent(node, opts);
|
|
771
653
|
}
|
|
772
654
|
function removeElementListeners(element) {
|
|
773
655
|
const map = elementListeners.get(element);
|
|
774
656
|
if (map) {
|
|
775
657
|
for (const [eventName, entry] of map) {
|
|
776
|
-
|
|
658
|
+
if (entry.options !== void 0)
|
|
659
|
+
element.removeEventListener(eventName, entry.handler, entry.options);
|
|
660
|
+
else element.removeEventListener(eventName, entry.handler);
|
|
777
661
|
}
|
|
778
662
|
elementListeners.delete(element);
|
|
779
663
|
}
|
|
@@ -786,262 +670,42 @@ function removeAllListeners(root) {
|
|
|
786
670
|
removeElementListeners(children[i]);
|
|
787
671
|
}
|
|
788
672
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
673
|
+
var elementListeners;
|
|
674
|
+
var init_cleanup = __esm({
|
|
675
|
+
"src/renderer/cleanup.ts"() {
|
|
676
|
+
"use strict";
|
|
677
|
+
init_component();
|
|
678
|
+
init_logger();
|
|
679
|
+
elementListeners = /* @__PURE__ */ new WeakMap();
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
// src/renderer/keyed.ts
|
|
684
|
+
function getKeyMapForElement(el) {
|
|
685
|
+
return keyedElements.get(el);
|
|
686
|
+
}
|
|
687
|
+
function isKeyedReorderFastPathEligible(parent, newChildren, oldKeyMap) {
|
|
688
|
+
const keyedVnodes = [];
|
|
689
|
+
for (let i = 0; i < newChildren.length; i++) {
|
|
690
|
+
const child = newChildren[i];
|
|
691
|
+
if (typeof child === "object" && child !== null && "type" in child) {
|
|
692
|
+
const childObj = child;
|
|
693
|
+
if (childObj.key !== void 0) {
|
|
694
|
+
keyedVnodes.push({
|
|
695
|
+
key: childObj.key,
|
|
696
|
+
vnode: child
|
|
697
|
+
});
|
|
698
|
+
}
|
|
798
699
|
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
const
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
domRanges.set(context, { start, end });
|
|
809
|
-
const dom = createDOMNode(node);
|
|
810
|
-
if (dom) {
|
|
811
|
-
target.insertBefore(dom, end);
|
|
812
|
-
}
|
|
813
|
-
} else {
|
|
814
|
-
const vnode = node;
|
|
815
|
-
const firstChild = target.children[0];
|
|
816
|
-
if (firstChild && _isDOMElement(vnode) && typeof vnode.type === "string" && firstChild.tagName.toLowerCase() === vnode.type.toLowerCase()) {
|
|
817
|
-
const vnodeChildren = vnode.children || vnode.props?.children;
|
|
818
|
-
let isSimpleTextVNode = false;
|
|
819
|
-
let textContent;
|
|
820
|
-
if (!Array.isArray(vnodeChildren)) {
|
|
821
|
-
if (typeof vnodeChildren === "string" || typeof vnodeChildren === "number") {
|
|
822
|
-
isSimpleTextVNode = true;
|
|
823
|
-
textContent = String(vnodeChildren);
|
|
824
|
-
}
|
|
825
|
-
} else if (vnodeChildren.length === 1) {
|
|
826
|
-
const child = vnodeChildren[0];
|
|
827
|
-
if (typeof child === "string" || typeof child === "number") {
|
|
828
|
-
isSimpleTextVNode = true;
|
|
829
|
-
textContent = String(child);
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
if (isSimpleTextVNode && firstChild.childNodes.length === 1 && firstChild.firstChild?.nodeType === 3) {
|
|
833
|
-
firstChild.firstChild.data = textContent;
|
|
834
|
-
} else {
|
|
835
|
-
if (vnodeChildren) {
|
|
836
|
-
if (Array.isArray(vnodeChildren)) {
|
|
837
|
-
const hasKeys = vnodeChildren.some(
|
|
838
|
-
(child) => typeof child === "object" && child !== null && "key" in child
|
|
839
|
-
);
|
|
840
|
-
if (hasKeys) {
|
|
841
|
-
let oldKeyMap = keyedElements.get(firstChild);
|
|
842
|
-
if (!oldKeyMap) {
|
|
843
|
-
oldKeyMap = /* @__PURE__ */ new Map();
|
|
844
|
-
}
|
|
845
|
-
try {
|
|
846
|
-
if (process.env.ASKR_FORCE_BULK_POSREUSE === "1") {
|
|
847
|
-
try {
|
|
848
|
-
const keyedVnodes = [];
|
|
849
|
-
for (let i = 0; i < vnodeChildren.length; i++) {
|
|
850
|
-
const c = vnodeChildren[i];
|
|
851
|
-
if (_isDOMElement(c) && c.key !== void 0) {
|
|
852
|
-
keyedVnodes.push({
|
|
853
|
-
key: c.key,
|
|
854
|
-
vnode: c
|
|
855
|
-
});
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
if (keyedVnodes.length > 0 && keyedVnodes.length === vnodeChildren.length) {
|
|
859
|
-
logger.warn(
|
|
860
|
-
"[Askr][FASTPATH] forced positional bulk keyed reuse (evaluate-level)"
|
|
861
|
-
);
|
|
862
|
-
const stats = performBulkPositionalKeyedTextUpdate(
|
|
863
|
-
firstChild,
|
|
864
|
-
keyedVnodes
|
|
865
|
-
);
|
|
866
|
-
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
867
|
-
try {
|
|
868
|
-
const gl = globalThis;
|
|
869
|
-
gl.__ASKR_LAST_FASTPATH_STATS = stats;
|
|
870
|
-
gl.__ASKR_LAST_FASTPATH_COMMIT_COUNT = 1;
|
|
871
|
-
const counters = gl.__ASKR_FASTPATH_COUNTERS || {};
|
|
872
|
-
counters.bulkKeyedPositionalForced = (counters.bulkKeyedPositionalForced || 0) + 1;
|
|
873
|
-
gl.__ASKR_FASTPATH_COUNTERS = counters;
|
|
874
|
-
} catch (e) {
|
|
875
|
-
void e;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
try {
|
|
879
|
-
const map = /* @__PURE__ */ new Map();
|
|
880
|
-
const children = Array.from(firstChild.children);
|
|
881
|
-
for (let i = 0; i < children.length; i++) {
|
|
882
|
-
const el = children[i];
|
|
883
|
-
const k = el.getAttribute("data-key");
|
|
884
|
-
if (k !== null) {
|
|
885
|
-
map.set(k, el);
|
|
886
|
-
const n = Number(k);
|
|
887
|
-
if (!Number.isNaN(n)) map.set(n, el);
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
keyedElements.set(firstChild, map);
|
|
891
|
-
} catch (e) {
|
|
892
|
-
void e;
|
|
893
|
-
}
|
|
894
|
-
} else {
|
|
895
|
-
const newKeyMap = reconcileKeyedChildren(
|
|
896
|
-
firstChild,
|
|
897
|
-
vnodeChildren,
|
|
898
|
-
oldKeyMap
|
|
899
|
-
);
|
|
900
|
-
keyedElements.set(firstChild, newKeyMap);
|
|
901
|
-
}
|
|
902
|
-
} catch (err) {
|
|
903
|
-
logger.warn(
|
|
904
|
-
"[Askr][FASTPATH] forced bulk path failed, falling back",
|
|
905
|
-
err
|
|
906
|
-
);
|
|
907
|
-
const newKeyMap = reconcileKeyedChildren(
|
|
908
|
-
firstChild,
|
|
909
|
-
vnodeChildren,
|
|
910
|
-
oldKeyMap
|
|
911
|
-
);
|
|
912
|
-
keyedElements.set(firstChild, newKeyMap);
|
|
913
|
-
}
|
|
914
|
-
} else {
|
|
915
|
-
const newKeyMap = reconcileKeyedChildren(
|
|
916
|
-
firstChild,
|
|
917
|
-
vnodeChildren,
|
|
918
|
-
oldKeyMap
|
|
919
|
-
);
|
|
920
|
-
keyedElements.set(firstChild, newKeyMap);
|
|
921
|
-
}
|
|
922
|
-
} catch (e) {
|
|
923
|
-
void e;
|
|
924
|
-
const newKeyMap = reconcileKeyedChildren(
|
|
925
|
-
firstChild,
|
|
926
|
-
vnodeChildren,
|
|
927
|
-
oldKeyMap
|
|
928
|
-
);
|
|
929
|
-
keyedElements.set(firstChild, newKeyMap);
|
|
930
|
-
}
|
|
931
|
-
} else {
|
|
932
|
-
if (isBulkTextFastPathEligible(firstChild, vnodeChildren)) {
|
|
933
|
-
const stats = performBulkTextReplace(firstChild, vnodeChildren);
|
|
934
|
-
if (process.env.NODE_ENV !== "production") {
|
|
935
|
-
try {
|
|
936
|
-
const gl = globalThis;
|
|
937
|
-
gl.__ASKR_LAST_BULK_TEXT_FASTPATH_STATS = stats;
|
|
938
|
-
const counters = gl.__ASKR_FASTPATH_COUNTERS || {};
|
|
939
|
-
counters.bulkTextHits = (counters.bulkTextHits || 0) + 1;
|
|
940
|
-
gl.__ASKR_FASTPATH_COUNTERS = counters;
|
|
941
|
-
} catch (e) {
|
|
942
|
-
void e;
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
} else {
|
|
946
|
-
if (process.env.NODE_ENV !== "production") {
|
|
947
|
-
try {
|
|
948
|
-
const gl = globalThis;
|
|
949
|
-
const counters = gl.__ASKR_FASTPATH_COUNTERS || {};
|
|
950
|
-
counters.bulkTextMisses = (counters.bulkTextMisses || 0) + 1;
|
|
951
|
-
gl.__ASKR_FASTPATH_COUNTERS = counters;
|
|
952
|
-
} catch (e) {
|
|
953
|
-
void e;
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
updateUnkeyedChildren(firstChild, vnodeChildren);
|
|
957
|
-
keyedElements.delete(firstChild);
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
} else {
|
|
961
|
-
firstChild.textContent = "";
|
|
962
|
-
const dom = createDOMNode(vnodeChildren);
|
|
963
|
-
if (dom) firstChild.appendChild(dom);
|
|
964
|
-
keyedElements.delete(firstChild);
|
|
965
|
-
}
|
|
966
|
-
} else {
|
|
967
|
-
firstChild.textContent = "";
|
|
968
|
-
keyedElements.delete(firstChild);
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
updateElementFromVnode(firstChild, vnode, false);
|
|
972
|
-
} else {
|
|
973
|
-
target.textContent = "";
|
|
974
|
-
if (_isDOMElement(vnode) && typeof vnode.type === "string") {
|
|
975
|
-
const children = vnode.children;
|
|
976
|
-
if (Array.isArray(children) && children.some(
|
|
977
|
-
(child) => typeof child === "object" && child !== null && "key" in child
|
|
978
|
-
)) {
|
|
979
|
-
const el = document.createElement(vnode.type);
|
|
980
|
-
target.appendChild(el);
|
|
981
|
-
const props = vnode.props || {};
|
|
982
|
-
for (const [key, value] of Object.entries(props)) {
|
|
983
|
-
if (key === "children" || key === "key") continue;
|
|
984
|
-
if (value === void 0 || value === null || value === false)
|
|
985
|
-
continue;
|
|
986
|
-
if (key.startsWith("on") && key.length > 2) {
|
|
987
|
-
const eventName = key.slice(2).charAt(0).toLowerCase() + key.slice(3).toLowerCase();
|
|
988
|
-
const wrappedHandler = (event) => {
|
|
989
|
-
globalScheduler.setInHandler(true);
|
|
990
|
-
try {
|
|
991
|
-
value(event);
|
|
992
|
-
} catch (error) {
|
|
993
|
-
logger.error("[Askr] Event handler error:", error);
|
|
994
|
-
} finally {
|
|
995
|
-
globalScheduler.setInHandler(false);
|
|
996
|
-
}
|
|
997
|
-
};
|
|
998
|
-
el.addEventListener(eventName, wrappedHandler);
|
|
999
|
-
if (!elementListeners.has(el)) {
|
|
1000
|
-
elementListeners.set(el, /* @__PURE__ */ new Map());
|
|
1001
|
-
}
|
|
1002
|
-
elementListeners.get(el).set(eventName, {
|
|
1003
|
-
handler: wrappedHandler,
|
|
1004
|
-
original: value
|
|
1005
|
-
});
|
|
1006
|
-
continue;
|
|
1007
|
-
}
|
|
1008
|
-
if (key === "class" || key === "className") {
|
|
1009
|
-
el.className = String(value);
|
|
1010
|
-
} else if (key === "value" || key === "checked") {
|
|
1011
|
-
el[key] = value;
|
|
1012
|
-
} else {
|
|
1013
|
-
el.setAttribute(key, String(value));
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
const newKeyMap = reconcileKeyedChildren(el, children, void 0);
|
|
1017
|
-
keyedElements.set(el, newKeyMap);
|
|
1018
|
-
return;
|
|
1019
|
-
return;
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
const dom = createDOMNode(vnode);
|
|
1023
|
-
if (dom) {
|
|
1024
|
-
target.appendChild(dom);
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
function isKeyedReorderFastPathEligible(parent, newChildren, oldKeyMap) {
|
|
1030
|
-
const keyedVnodes = [];
|
|
1031
|
-
for (let i = 0; i < newChildren.length; i++) {
|
|
1032
|
-
const child = newChildren[i];
|
|
1033
|
-
if (_isDOMElement(child) && child.key !== void 0) {
|
|
1034
|
-
keyedVnodes.push({ key: child.key, vnode: child });
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
const totalKeyed = keyedVnodes.length;
|
|
1038
|
-
const newKeyOrder = keyedVnodes.map((kv) => kv.key);
|
|
1039
|
-
const oldKeyOrder = oldKeyMap ? Array.from(oldKeyMap.keys()) : [];
|
|
1040
|
-
let moveCount = 0;
|
|
1041
|
-
for (let i = 0; i < newKeyOrder.length; i++) {
|
|
1042
|
-
const k = newKeyOrder[i];
|
|
1043
|
-
if (i >= oldKeyOrder.length || oldKeyOrder[i] !== k || !oldKeyMap?.has(k)) {
|
|
1044
|
-
moveCount++;
|
|
700
|
+
}
|
|
701
|
+
const totalKeyed = keyedVnodes.length;
|
|
702
|
+
const newKeyOrder = keyedVnodes.map((kv) => kv.key);
|
|
703
|
+
const oldKeyOrder = oldKeyMap ? Array.from(oldKeyMap.keys()) : [];
|
|
704
|
+
let moveCount = 0;
|
|
705
|
+
for (let i = 0; i < newKeyOrder.length; i++) {
|
|
706
|
+
const k = newKeyOrder[i];
|
|
707
|
+
if (i >= oldKeyOrder.length || oldKeyOrder[i] !== k || !oldKeyMap?.has(k)) {
|
|
708
|
+
moveCount++;
|
|
1045
709
|
}
|
|
1046
710
|
}
|
|
1047
711
|
const FAST_MOVE_THRESHOLD_ABS = 64;
|
|
@@ -1082,8 +746,9 @@ function isKeyedReorderFastPathEligible(parent, newChildren, oldKeyMap) {
|
|
|
1082
746
|
let hasPropsPresent = false;
|
|
1083
747
|
for (let i = 0; i < keyedVnodes.length; i++) {
|
|
1084
748
|
const vnode = keyedVnodes[i].vnode;
|
|
1085
|
-
if (
|
|
1086
|
-
const
|
|
749
|
+
if (typeof vnode !== "object" || vnode === null) continue;
|
|
750
|
+
const vnodeObj = vnode;
|
|
751
|
+
const props = vnodeObj.props || {};
|
|
1087
752
|
for (const k of Object.keys(props)) {
|
|
1088
753
|
if (k === "children" || k === "key") continue;
|
|
1089
754
|
if (k.startsWith("on") && k.length > 2) continue;
|
|
@@ -1097,8 +762,9 @@ function isKeyedReorderFastPathEligible(parent, newChildren, oldKeyMap) {
|
|
|
1097
762
|
for (let i = 0; i < keyedVnodes.length; i++) {
|
|
1098
763
|
const { key, vnode } = keyedVnodes[i];
|
|
1099
764
|
const el = oldKeyMap?.get(key);
|
|
1100
|
-
if (!el ||
|
|
1101
|
-
const
|
|
765
|
+
if (!el || typeof vnode !== "object" || vnode === null) continue;
|
|
766
|
+
const vnodeObj = vnode;
|
|
767
|
+
const props = vnodeObj.props || {};
|
|
1102
768
|
for (const k of Object.keys(props)) {
|
|
1103
769
|
if (k === "children" || k === "key") continue;
|
|
1104
770
|
if (k.startsWith("on") && k.length > 2) continue;
|
|
@@ -1127,8 +793,9 @@ function isKeyedReorderFastPathEligible(parent, newChildren, oldKeyMap) {
|
|
|
1127
793
|
break;
|
|
1128
794
|
}
|
|
1129
795
|
}
|
|
1130
|
-
} catch {
|
|
796
|
+
} catch (e) {
|
|
1131
797
|
hasPropChanges = true;
|
|
798
|
+
void e;
|
|
1132
799
|
break;
|
|
1133
800
|
}
|
|
1134
801
|
}
|
|
@@ -1143,1024 +810,386 @@ function isKeyedReorderFastPathEligible(parent, newChildren, oldKeyMap) {
|
|
|
1143
810
|
hasPropChanges
|
|
1144
811
|
};
|
|
1145
812
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
if (_isDOMElement(child) && child.key !== void 0) {
|
|
1153
|
-
keyedVnodes.push({ key: child.key, vnode: child });
|
|
1154
|
-
} else {
|
|
1155
|
-
unkeyedVnodes.push(child);
|
|
1156
|
-
}
|
|
813
|
+
var keyedElements, _reconcilerRecordedParents;
|
|
814
|
+
var init_keyed = __esm({
|
|
815
|
+
"src/renderer/keyed.ts"() {
|
|
816
|
+
"use strict";
|
|
817
|
+
keyedElements = /* @__PURE__ */ new WeakMap();
|
|
818
|
+
_reconcilerRecordedParents = /* @__PURE__ */ new WeakSet();
|
|
1157
819
|
}
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
820
|
+
});
|
|
821
|
+
|
|
822
|
+
// src/renderer/dom.ts
|
|
823
|
+
function createDOMNode(node) {
|
|
824
|
+
if (!IS_DOM_AVAILABLE) {
|
|
825
|
+
if (process.env.NODE_ENV !== "production") {
|
|
826
|
+
try {
|
|
827
|
+
logger.warn("[Askr] createDOMNode called in non-DOM environment");
|
|
828
|
+
} catch (e) {
|
|
829
|
+
void e;
|
|
830
|
+
}
|
|
1166
831
|
}
|
|
832
|
+
return null;
|
|
1167
833
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
const { key, vnode } = keyedVnodes[i];
|
|
1171
|
-
const el = oldKeyMap?.get(key);
|
|
1172
|
-
if (!el || !_isDOMElement(vnode)) continue;
|
|
1173
|
-
const props = vnode.props || {};
|
|
1174
|
-
for (const k2 of Object.keys(props)) {
|
|
1175
|
-
if (k2 === "children" || k2 === "key") continue;
|
|
1176
|
-
if (k2.startsWith("on") && k2.length > 2) {
|
|
1177
|
-
continue;
|
|
1178
|
-
}
|
|
1179
|
-
const v = props[k2];
|
|
1180
|
-
try {
|
|
1181
|
-
if (k2 === "class" || k2 === "className") {
|
|
1182
|
-
if (el.className !== String(v)) {
|
|
1183
|
-
logger.warn("[Askr][FASTPATH][DEV] prop mismatch", {
|
|
1184
|
-
key,
|
|
1185
|
-
prop: k2,
|
|
1186
|
-
expected: String(v),
|
|
1187
|
-
actual: el.className
|
|
1188
|
-
});
|
|
1189
|
-
hasPropChanges = true;
|
|
1190
|
-
break;
|
|
1191
|
-
}
|
|
1192
|
-
} else if (k2 === "value" || k2 === "checked") {
|
|
1193
|
-
if (el[k2] !== v) {
|
|
1194
|
-
logger.warn("[Askr][FASTPATH][DEV] prop mismatch", {
|
|
1195
|
-
key,
|
|
1196
|
-
prop: k2,
|
|
1197
|
-
expected: v,
|
|
1198
|
-
actual: el[k2]
|
|
1199
|
-
});
|
|
1200
|
-
hasPropChanges = true;
|
|
1201
|
-
break;
|
|
1202
|
-
}
|
|
1203
|
-
} else {
|
|
1204
|
-
const attr = el.getAttribute(k2);
|
|
1205
|
-
if (v === void 0 || v === null || v === false) {
|
|
1206
|
-
if (attr !== null) {
|
|
1207
|
-
logger.warn(
|
|
1208
|
-
"[Askr][FASTPATH][DEV] prop mismatch (missing attr)",
|
|
1209
|
-
{
|
|
1210
|
-
key,
|
|
1211
|
-
prop: k2,
|
|
1212
|
-
expected: v,
|
|
1213
|
-
actual: attr
|
|
1214
|
-
}
|
|
1215
|
-
);
|
|
1216
|
-
hasPropChanges = true;
|
|
1217
|
-
break;
|
|
1218
|
-
}
|
|
1219
|
-
} else if (String(v) !== attr) {
|
|
1220
|
-
logger.warn("[Askr][FASTPATH][DEV] prop mismatch (attr diff)", {
|
|
1221
|
-
key,
|
|
1222
|
-
prop: k2,
|
|
1223
|
-
expected: String(v),
|
|
1224
|
-
actual: attr
|
|
1225
|
-
});
|
|
1226
|
-
hasPropChanges = true;
|
|
1227
|
-
break;
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
} catch {
|
|
1231
|
-
hasPropChanges = true;
|
|
1232
|
-
break;
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
if (hasPropChanges) break;
|
|
1236
|
-
}
|
|
1237
|
-
const decision = isKeyedReorderFastPathEligible(
|
|
1238
|
-
parent,
|
|
1239
|
-
newChildren,
|
|
1240
|
-
oldKeyMap
|
|
1241
|
-
);
|
|
1242
|
-
const useFastPath = decision.useFastPath;
|
|
1243
|
-
logger.warn("[Askr][FASTPATH][DEV] decision", decision);
|
|
1244
|
-
try {
|
|
1245
|
-
const hugeThreshold = Number(process.env.ASKR_BULK_HUGE_THRESHOLD) || 2048;
|
|
1246
|
-
if (!useFastPath && keyedVnodes.length >= hugeThreshold) {
|
|
1247
|
-
let allSimple = true;
|
|
1248
|
-
for (let i = 0; i < keyedVnodes.length; i++) {
|
|
1249
|
-
const vnode = keyedVnodes[i].vnode;
|
|
1250
|
-
if (!_isDOMElement(vnode)) {
|
|
1251
|
-
allSimple = false;
|
|
1252
|
-
break;
|
|
1253
|
-
}
|
|
1254
|
-
const dv = vnode;
|
|
1255
|
-
if (typeof dv.type !== "string") {
|
|
1256
|
-
allSimple = false;
|
|
1257
|
-
break;
|
|
1258
|
-
}
|
|
1259
|
-
const ch = dv.children || dv.props?.children;
|
|
1260
|
-
if (ch === void 0) continue;
|
|
1261
|
-
if (Array.isArray(ch)) {
|
|
1262
|
-
if (ch.length !== 1 || typeof ch[0] !== "string" && typeof ch[0] !== "number") {
|
|
1263
|
-
allSimple = false;
|
|
1264
|
-
break;
|
|
1265
|
-
}
|
|
1266
|
-
} else if (typeof ch !== "string" && typeof ch !== "number") {
|
|
1267
|
-
allSimple = false;
|
|
1268
|
-
break;
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
|
-
if (allSimple) {
|
|
1272
|
-
logger.warn("[Askr][FASTPATH] applying huge-list positional fallback");
|
|
1273
|
-
try {
|
|
1274
|
-
if (isBulkCommitActive2()) markFastPathApplied(parent);
|
|
1275
|
-
} catch (e) {
|
|
1276
|
-
void e;
|
|
1277
|
-
}
|
|
1278
|
-
const stats = performBulkPositionalKeyedTextUpdate(parent, keyedVnodes);
|
|
1279
|
-
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
1280
|
-
try {
|
|
1281
|
-
const gl = globalThis;
|
|
1282
|
-
gl.__ASKR_LAST_FASTPATH_STATS = stats;
|
|
1283
|
-
const counters = gl.__ASKR_FASTPATH_COUNTERS || {};
|
|
1284
|
-
counters.bulkKeyedHugeFallback = (counters.bulkKeyedHugeFallback || 0) + 1;
|
|
1285
|
-
gl.__ASKR_FASTPATH_COUNTERS = counters;
|
|
1286
|
-
gl.__ASKR_BULK_DIAG = {
|
|
1287
|
-
phase: "bulk-keyed-huge-fallback",
|
|
1288
|
-
stats
|
|
1289
|
-
};
|
|
1290
|
-
} catch (e) {
|
|
1291
|
-
void e;
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
return newKeyMap;
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
} catch (e) {
|
|
1298
|
-
void e;
|
|
834
|
+
if (typeof node === "string") {
|
|
835
|
+
return document.createTextNode(node);
|
|
1299
836
|
}
|
|
1300
|
-
if (
|
|
1301
|
-
|
|
1302
|
-
const gl = globalThis;
|
|
1303
|
-
gl.__ASKR_BULK_DIAG = {
|
|
1304
|
-
phase: "keyed-decision",
|
|
1305
|
-
decision,
|
|
1306
|
-
totalKeyed,
|
|
1307
|
-
oldKeyMapSize: oldKeyMap?.size ?? 0
|
|
1308
|
-
};
|
|
1309
|
-
} catch (e) {
|
|
1310
|
-
void e;
|
|
1311
|
-
}
|
|
837
|
+
if (typeof node === "number") {
|
|
838
|
+
return document.createTextNode(String(node));
|
|
1312
839
|
}
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
if (keyedVnodes.length >= (Number(process.env.ASKR_BULK_TEXT_THRESHOLD) || 1024)) {
|
|
1316
|
-
let missing = 0;
|
|
1317
|
-
try {
|
|
1318
|
-
const present = /* @__PURE__ */ new Set();
|
|
1319
|
-
const parentChildren2 = Array.from(parent.children);
|
|
1320
|
-
for (let i = 0; i < parentChildren2.length; i++) {
|
|
1321
|
-
const attr = parentChildren2[i].getAttribute("data-key");
|
|
1322
|
-
if (attr !== null) {
|
|
1323
|
-
present.add(attr);
|
|
1324
|
-
const n = Number(attr);
|
|
1325
|
-
if (!Number.isNaN(n)) present.add(n);
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
for (let i = 0; i < keyedVnodes.length; i++) {
|
|
1329
|
-
const k2 = keyedVnodes[i].key;
|
|
1330
|
-
if (!present.has(k2)) missing++;
|
|
1331
|
-
}
|
|
1332
|
-
} catch {
|
|
1333
|
-
missing = 0;
|
|
1334
|
-
}
|
|
1335
|
-
allSimpleText = keyedVnodes.length > 0 && keyedVnodes.every(({ vnode }) => {
|
|
1336
|
-
if (!_isDOMElement(vnode)) return false;
|
|
1337
|
-
const dv = vnode;
|
|
1338
|
-
if (typeof dv.type !== "string") return false;
|
|
1339
|
-
const ch = dv.children || dv.props?.children;
|
|
1340
|
-
if (ch === void 0) return true;
|
|
1341
|
-
if (Array.isArray(ch)) {
|
|
1342
|
-
return ch.length === 1 && (typeof ch[0] === "string" || typeof ch[0] === "number");
|
|
1343
|
-
}
|
|
1344
|
-
return typeof ch === "string" || typeof ch === "number";
|
|
1345
|
-
});
|
|
1346
|
-
let hasPropsPresent = false;
|
|
1347
|
-
for (let i = 0; i < keyedVnodes.length; i++) {
|
|
1348
|
-
const vnode = keyedVnodes[i].vnode;
|
|
1349
|
-
if (!_isDOMElement(vnode)) continue;
|
|
1350
|
-
const props = vnode.props || {};
|
|
1351
|
-
for (const k2 of Object.keys(props)) {
|
|
1352
|
-
if (k2 === "children" || k2 === "key") continue;
|
|
1353
|
-
if (k2.startsWith("on") && k2.length > 2) continue;
|
|
1354
|
-
if (k2.startsWith("data-")) continue;
|
|
1355
|
-
hasPropsPresent = true;
|
|
1356
|
-
break;
|
|
1357
|
-
}
|
|
1358
|
-
if (hasPropsPresent) break;
|
|
1359
|
-
}
|
|
1360
|
-
const missingRatio = missing / Math.max(1, keyedVnodes.length);
|
|
1361
|
-
if (missingRatio > 0.5 && allSimpleText && !hasPropsPresent) {
|
|
1362
|
-
logger.warn(
|
|
1363
|
-
"[Askr][FASTPATH] switching to positional bulk keyed fast-path due to missing keys ratio",
|
|
1364
|
-
missingRatio
|
|
1365
|
-
);
|
|
1366
|
-
try {
|
|
1367
|
-
if (isBulkCommitActive2()) markFastPathApplied(parent);
|
|
1368
|
-
} catch (e) {
|
|
1369
|
-
void e;
|
|
1370
|
-
}
|
|
1371
|
-
const stats = performBulkPositionalKeyedTextUpdate(parent, keyedVnodes);
|
|
1372
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1373
|
-
try {
|
|
1374
|
-
const gl = globalThis;
|
|
1375
|
-
gl.__ASKR_LAST_FASTPATH_STATS = stats;
|
|
1376
|
-
try {
|
|
1377
|
-
_reconcilerRecordedParents.add(parent);
|
|
1378
|
-
} catch (e) {
|
|
1379
|
-
void e;
|
|
1380
|
-
}
|
|
1381
|
-
gl.__ASKR_LAST_FASTPATH_COMMIT_COUNT = 1;
|
|
1382
|
-
const counters = gl.__ASKR_FASTPATH_COUNTERS || {};
|
|
1383
|
-
counters.bulkKeyedPositionalHits = (counters.bulkKeyedPositionalHits || 0) + 1;
|
|
1384
|
-
gl.__ASKR_FASTPATH_COUNTERS = counters;
|
|
1385
|
-
} catch (e) {
|
|
1386
|
-
void e;
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
|
-
return newKeyMap;
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
} catch (e) {
|
|
1393
|
-
void e;
|
|
840
|
+
if (!node) {
|
|
841
|
+
return null;
|
|
1394
842
|
}
|
|
1395
|
-
if (
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
} catch {
|
|
1401
|
-
parentFastpathApplied = false;
|
|
1402
|
-
}
|
|
1403
|
-
if (!parentFastpathApplied) {
|
|
1404
|
-
const gl = globalThis;
|
|
1405
|
-
try {
|
|
1406
|
-
if (_reconcilerRecordedParents.has(parent)) {
|
|
1407
|
-
_reconcilerRecordedParents.delete(parent);
|
|
1408
|
-
} else {
|
|
1409
|
-
delete gl.__ASKR_LAST_FASTPATH_STATS;
|
|
1410
|
-
delete gl.__ASKR_LAST_FASTPATH_REUSED;
|
|
1411
|
-
}
|
|
1412
|
-
} catch {
|
|
1413
|
-
delete gl.__ASKR_LAST_FASTPATH_STATS;
|
|
1414
|
-
delete gl.__ASKR_LAST_FASTPATH_REUSED;
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
} catch (e) {
|
|
1418
|
-
void e;
|
|
843
|
+
if (Array.isArray(node)) {
|
|
844
|
+
const fragment = document.createDocumentFragment();
|
|
845
|
+
for (let i = 0; i < node.length; i++) {
|
|
846
|
+
const dom = createDOMNode(node[i]);
|
|
847
|
+
if (dom) fragment.appendChild(dom);
|
|
1419
848
|
}
|
|
849
|
+
return fragment;
|
|
1420
850
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
const
|
|
1424
|
-
if (
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
}
|
|
1435
|
-
let stable = true;
|
|
1436
|
-
try {
|
|
1437
|
-
const parentChildren2 = Array.from(parent.children);
|
|
1438
|
-
if (parentChildren2.length === keyedVnodes.length) {
|
|
1439
|
-
const allSimple = keyedVnodes.every(({ vnode }) => {
|
|
1440
|
-
if (!_isDOMElement(vnode)) return false;
|
|
1441
|
-
const dv = vnode;
|
|
1442
|
-
if (typeof dv.type !== "string") return false;
|
|
1443
|
-
const ch = dv.children || dv.props?.children;
|
|
1444
|
-
if (ch === void 0) return true;
|
|
1445
|
-
if (Array.isArray(ch)) {
|
|
1446
|
-
return ch.length === 1 && (typeof ch[0] === "string" || typeof ch[0] === "number");
|
|
1447
|
-
}
|
|
1448
|
-
return typeof ch === "string" || typeof ch === "number";
|
|
1449
|
-
});
|
|
1450
|
-
if (allSimple || process.env.ASKR_FORCE_BULK_POSREUSE === "1") {
|
|
1451
|
-
logger.warn(
|
|
1452
|
-
"[Askr][FASTPATH] len-match heuristic triggered (positional bulk)"
|
|
1453
|
-
);
|
|
1454
|
-
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
1455
|
-
try {
|
|
1456
|
-
const gl = globalThis;
|
|
1457
|
-
gl.__ASKR_BULK_DIAG = {
|
|
1458
|
-
phase: "bulk-keyed-positional-trigger-lenmatch-early",
|
|
1459
|
-
totalKeyed: keyedVnodes.length,
|
|
1460
|
-
allSimple,
|
|
1461
|
-
forced: process.env.ASKR_FORCE_BULK_POSREUSE === "1"
|
|
1462
|
-
};
|
|
1463
|
-
} catch (e) {
|
|
1464
|
-
void e;
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
851
|
+
if (typeof node === "object" && node !== null && "type" in node) {
|
|
852
|
+
const type = node.type;
|
|
853
|
+
const props = node.props || {};
|
|
854
|
+
if (typeof type === "string") {
|
|
855
|
+
const el = document.createElement(type);
|
|
856
|
+
for (const key in props) {
|
|
857
|
+
const value = props[key];
|
|
858
|
+
if (key === "children" || key === "key") continue;
|
|
859
|
+
if (value === void 0 || value === null || value === false) continue;
|
|
860
|
+
if (key.startsWith("on") && key.length > 2) {
|
|
861
|
+
const eventName = key.slice(2).charAt(0).toLowerCase() + key.slice(3).toLowerCase();
|
|
862
|
+
const wrappedHandler = (event) => {
|
|
863
|
+
globalScheduler.setInHandler(true);
|
|
1467
864
|
try {
|
|
1468
|
-
|
|
1469
|
-
} catch (
|
|
1470
|
-
|
|
1471
|
-
}
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
};
|
|
1484
|
-
const counters = gl.__ASKR_FASTPATH_COUNTERS || {};
|
|
1485
|
-
counters.bulkKeyedPositionalHits = (counters.bulkKeyedPositionalHits || 0) + 1;
|
|
1486
|
-
if (process.env.ASKR_FORCE_BULK_POSREUSE === "1")
|
|
1487
|
-
counters.bulkKeyedPositionalForced = (counters.bulkKeyedPositionalForced || 0) + 1;
|
|
1488
|
-
gl.__ASKR_FASTPATH_COUNTERS = counters;
|
|
1489
|
-
} catch (e) {
|
|
1490
|
-
void e;
|
|
865
|
+
value(event);
|
|
866
|
+
} catch (error) {
|
|
867
|
+
logger.error("[Askr] Event handler error:", error);
|
|
868
|
+
} finally {
|
|
869
|
+
globalScheduler.setInHandler(false);
|
|
870
|
+
const state = globalScheduler.getState();
|
|
871
|
+
if ((state.queueLength ?? 0) > 0 && !state.running) {
|
|
872
|
+
queueMicrotask(() => {
|
|
873
|
+
try {
|
|
874
|
+
if (!globalScheduler.isExecuting()) globalScheduler.flush();
|
|
875
|
+
} catch (err) {
|
|
876
|
+
queueMicrotask(() => {
|
|
877
|
+
throw err;
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
});
|
|
1491
881
|
}
|
|
1492
882
|
}
|
|
1493
|
-
|
|
883
|
+
};
|
|
884
|
+
const options = eventName === "wheel" || eventName === "scroll" || eventName.startsWith("touch") ? { passive: true } : void 0;
|
|
885
|
+
if (options !== void 0)
|
|
886
|
+
el.addEventListener(eventName, wrappedHandler, options);
|
|
887
|
+
else el.addEventListener(eventName, wrappedHandler);
|
|
888
|
+
if (!elementListeners.has(el)) {
|
|
889
|
+
elementListeners.set(el, /* @__PURE__ */ new Map());
|
|
1494
890
|
}
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
891
|
+
elementListeners.get(el).set(eventName, {
|
|
892
|
+
handler: wrappedHandler,
|
|
893
|
+
original: value,
|
|
894
|
+
options
|
|
895
|
+
});
|
|
896
|
+
} else if (key === "class" || key === "className") {
|
|
897
|
+
el.className = String(value);
|
|
898
|
+
} else if (key === "value" || key === "checked") {
|
|
899
|
+
const tag = type.toLowerCase();
|
|
900
|
+
if (key === "value") {
|
|
901
|
+
if (tag === "input" || tag === "textarea" || tag === "select") {
|
|
902
|
+
el.value = String(value);
|
|
903
|
+
el.setAttribute("value", String(value));
|
|
904
|
+
} else {
|
|
905
|
+
el.setAttribute("value", String(value));
|
|
1510
906
|
}
|
|
1511
|
-
|
|
1512
|
-
|
|
907
|
+
} else {
|
|
908
|
+
if (tag === "input") {
|
|
909
|
+
el.checked = Boolean(value);
|
|
910
|
+
el.setAttribute("checked", String(Boolean(value)));
|
|
911
|
+
} else {
|
|
912
|
+
el.setAttribute("checked", String(Boolean(value)));
|
|
1513
913
|
}
|
|
1514
914
|
}
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
const stats = performBulkKeyedTextReplace(
|
|
1538
|
-
parent,
|
|
1539
|
-
keyedVnodes,
|
|
1540
|
-
oldKeyMap
|
|
1541
|
-
);
|
|
1542
|
-
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
1543
|
-
try {
|
|
1544
|
-
const gl = globalThis;
|
|
1545
|
-
gl.__ASKR_LAST_FASTPATH_STATS = stats;
|
|
1546
|
-
gl.__ASKR_BULK_DIAG = {
|
|
1547
|
-
phase: "bulk-keyed-applied",
|
|
1548
|
-
stats
|
|
1549
|
-
};
|
|
1550
|
-
const counters = gl.__ASKR_FASTPATH_COUNTERS || {};
|
|
1551
|
-
counters.bulkKeyedTextHits = (counters.bulkKeyedTextHits || 0) + 1;
|
|
1552
|
-
gl.__ASKR_FASTPATH_COUNTERS = counters;
|
|
1553
|
-
} catch (e) {
|
|
1554
|
-
void e;
|
|
915
|
+
} else {
|
|
916
|
+
el.setAttribute(key, String(value));
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
const vnodeKey = node.key ?? props?.key;
|
|
920
|
+
if (vnodeKey !== void 0) {
|
|
921
|
+
el.setAttribute("data-key", String(vnodeKey));
|
|
922
|
+
}
|
|
923
|
+
const children = props.children || node.children;
|
|
924
|
+
if (children) {
|
|
925
|
+
if (Array.isArray(children)) {
|
|
926
|
+
if (process.env.NODE_ENV !== "production") {
|
|
927
|
+
let hasElements = false;
|
|
928
|
+
let hasKeys = false;
|
|
929
|
+
for (let i = 0; i < children.length; i++) {
|
|
930
|
+
const item = children[i];
|
|
931
|
+
if (typeof item === "object" && item !== null && "type" in item) {
|
|
932
|
+
hasElements = true;
|
|
933
|
+
const itemProps = item.props || {};
|
|
934
|
+
if ("key" in itemProps) {
|
|
935
|
+
hasKeys = true;
|
|
936
|
+
break;
|
|
1555
937
|
}
|
|
1556
938
|
}
|
|
1557
|
-
return newKeyMap;
|
|
1558
939
|
}
|
|
1559
|
-
if (
|
|
1560
|
-
|
|
1561
|
-
"[Askr][FASTPATH] applying bulk keyed positional text fast-path (len-match)"
|
|
1562
|
-
);
|
|
1563
|
-
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
1564
|
-
try {
|
|
1565
|
-
const gl = globalThis;
|
|
1566
|
-
gl.__ASKR_BULK_DIAG = {
|
|
1567
|
-
phase: "bulk-keyed-positional-trigger-lenmatch",
|
|
1568
|
-
totalKeyed: keyedVnodes.length,
|
|
1569
|
-
keyMismatches
|
|
1570
|
-
};
|
|
1571
|
-
} catch (e) {
|
|
1572
|
-
void e;
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
try {
|
|
1576
|
-
if (isBulkCommitActive2()) markFastPathApplied(parent);
|
|
1577
|
-
} catch (e) {
|
|
1578
|
-
void e;
|
|
1579
|
-
}
|
|
1580
|
-
const stats = performBulkPositionalKeyedTextUpdate(
|
|
1581
|
-
parent,
|
|
1582
|
-
keyedVnodes
|
|
1583
|
-
);
|
|
1584
|
-
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
940
|
+
if (hasElements && !hasKeys) {
|
|
941
|
+
if (typeof console !== "undefined") {
|
|
1585
942
|
try {
|
|
1586
|
-
const
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
};
|
|
1592
|
-
const counters = gl.__ASKR_FASTPATH_COUNTERS || {};
|
|
1593
|
-
counters.bulkKeyedPositionalHits = (counters.bulkKeyedPositionalHits || 0) + 1;
|
|
1594
|
-
gl.__ASKR_FASTPATH_COUNTERS = counters;
|
|
943
|
+
const inst = getCurrentInstance();
|
|
944
|
+
const name = inst?.fn?.name || "<anonymous>";
|
|
945
|
+
logger.warn(
|
|
946
|
+
`Missing keys on dynamic lists in ${name}. Each child in a list should have a unique "key" prop.`
|
|
947
|
+
);
|
|
1595
948
|
} catch (e) {
|
|
949
|
+
logger.warn(
|
|
950
|
+
'Missing keys on dynamic lists. Each child in a list should have a unique "key" prop.'
|
|
951
|
+
);
|
|
1596
952
|
void e;
|
|
1597
953
|
}
|
|
1598
954
|
}
|
|
1599
|
-
return newKeyMap;
|
|
1600
|
-
}
|
|
1601
|
-
const mismatchRatio = keyMismatches / keyedVnodes.length;
|
|
1602
|
-
const POSITIONAL_THRESHOLD = 0.5;
|
|
1603
|
-
if (mismatchRatio > POSITIONAL_THRESHOLD) {
|
|
1604
|
-
logger.warn(
|
|
1605
|
-
"[Askr][FASTPATH] applying bulk keyed positional text fast-path"
|
|
1606
|
-
);
|
|
1607
|
-
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
1608
|
-
try {
|
|
1609
|
-
globalThis.__ASKR_BULK_DIAG = {
|
|
1610
|
-
phase: "bulk-keyed-positional-trigger",
|
|
1611
|
-
totalKeyed: keyedVnodes.length,
|
|
1612
|
-
keyMismatches
|
|
1613
|
-
};
|
|
1614
|
-
} catch (e) {
|
|
1615
|
-
void e;
|
|
1616
|
-
}
|
|
1617
|
-
}
|
|
1618
|
-
try {
|
|
1619
|
-
if (isBulkCommitActive2()) markFastPathApplied(parent);
|
|
1620
|
-
} catch (e) {
|
|
1621
|
-
void e;
|
|
1622
|
-
}
|
|
1623
|
-
const stats = performBulkPositionalKeyedTextUpdate(
|
|
1624
|
-
parent,
|
|
1625
|
-
keyedVnodes
|
|
1626
|
-
);
|
|
1627
|
-
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
1628
|
-
try {
|
|
1629
|
-
const gl = globalThis;
|
|
1630
|
-
gl.__ASKR_LAST_FASTPATH_STATS = stats;
|
|
1631
|
-
gl.__ASKR_BULK_DIAG = {
|
|
1632
|
-
phase: "bulk-keyed-positional-applied",
|
|
1633
|
-
stats
|
|
1634
|
-
};
|
|
1635
|
-
const counters = gl.__ASKR_FASTPATH_COUNTERS || {};
|
|
1636
|
-
counters.bulkKeyedPositionalHits = (counters.bulkKeyedPositionalHits || 0) + 1;
|
|
1637
|
-
gl.__ASKR_FASTPATH_COUNTERS = counters;
|
|
1638
|
-
} catch (e) {
|
|
1639
|
-
void e;
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
return newKeyMap;
|
|
1643
955
|
}
|
|
1644
956
|
}
|
|
957
|
+
for (let i = 0; i < children.length; i++) {
|
|
958
|
+
const dom = createDOMNode(children[i]);
|
|
959
|
+
if (dom) el.appendChild(dom);
|
|
960
|
+
}
|
|
961
|
+
} else {
|
|
962
|
+
const dom = createDOMNode(children);
|
|
963
|
+
if (dom) el.appendChild(dom);
|
|
1645
964
|
}
|
|
1646
|
-
} catch {
|
|
1647
|
-
stable = false;
|
|
1648
965
|
}
|
|
966
|
+
return el;
|
|
1649
967
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
const children = vnode.children || vnode.props?.children;
|
|
1660
|
-
if (Array.isArray(children)) {
|
|
1661
|
-
return children.length === 1 && (typeof children[0] === "string" || typeof children[0] === "number");
|
|
968
|
+
if (typeof type === "function") {
|
|
969
|
+
const frame = node[CONTEXT_FRAME_SYMBOL];
|
|
970
|
+
const snapshot = frame || getCurrentContextFrame();
|
|
971
|
+
const componentFn = type;
|
|
972
|
+
const isAsync = componentFn.constructor.name === "AsyncFunction";
|
|
973
|
+
if (isAsync) {
|
|
974
|
+
throw new Error(
|
|
975
|
+
"Async components are not supported. Use resource() for async work."
|
|
976
|
+
);
|
|
1662
977
|
}
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
}
|
|
1674
|
-
const children = vnode.children || vnode.props?.children;
|
|
1675
|
-
if (Array.isArray(children)) {
|
|
1676
|
-
if (children.length !== 1) {
|
|
1677
|
-
eligible = false;
|
|
1678
|
-
break;
|
|
1679
|
-
}
|
|
1680
|
-
const c = children[0];
|
|
1681
|
-
if (typeof c !== "string" && typeof c !== "number") {
|
|
1682
|
-
eligible = false;
|
|
1683
|
-
break;
|
|
1684
|
-
}
|
|
1685
|
-
} else if (children !== void 0 && typeof children !== "string" && typeof children !== "number") {
|
|
1686
|
-
eligible = false;
|
|
1687
|
-
break;
|
|
1688
|
-
}
|
|
1689
|
-
}
|
|
1690
|
-
const anyKeyMatches = !!oldKeyMap && keyedVnodes.some((kv) => oldKeyMap.has(kv.key));
|
|
1691
|
-
if (anyKeyMatches) {
|
|
1692
|
-
eligible = false;
|
|
1693
|
-
}
|
|
1694
|
-
if (eligible || process.env.ASKR_FORCE_POSREUSE === "1") {
|
|
1695
|
-
_triedPositionalReuse = true;
|
|
1696
|
-
if (process.env.ASKR_FORCE_POSREUSE === "1") {
|
|
1697
|
-
logger.warn(
|
|
1698
|
-
"[Askr][POSREUSE][FORCED] forcing positional reuse path for testing"
|
|
1699
|
-
);
|
|
1700
|
-
} else {
|
|
1701
|
-
logger.warn("[Askr][POSREUSE] positional reuse heuristic applied");
|
|
1702
|
-
}
|
|
1703
|
-
const existingChildren = parent.children;
|
|
1704
|
-
for (let i = 0; i < totalKeyed2; i++) {
|
|
1705
|
-
const { key, vnode } = keyedVnodes[i];
|
|
1706
|
-
const current = existingChildren[i];
|
|
1707
|
-
if (current && _isDOMElement(vnode)) {
|
|
1708
|
-
const vnodeType = vnode.type;
|
|
1709
|
-
if (current.tagName.toLowerCase() === vnodeType.toLowerCase()) {
|
|
1710
|
-
updateElementFromVnode(current, vnode);
|
|
1711
|
-
newKeyMap.set(key, current);
|
|
1712
|
-
continue;
|
|
1713
|
-
}
|
|
1714
|
-
}
|
|
1715
|
-
const newEl = createDOMNode(vnode);
|
|
1716
|
-
if (newEl instanceof Element) {
|
|
1717
|
-
if (current) {
|
|
1718
|
-
cleanupInstanceIfPresent(current);
|
|
1719
|
-
parent.replaceChild(newEl, current);
|
|
1720
|
-
} else parent.appendChild(newEl);
|
|
1721
|
-
newKeyMap.set(key, newEl);
|
|
1722
|
-
}
|
|
1723
|
-
}
|
|
1724
|
-
for (const vnode of unkeyedVnodes) {
|
|
1725
|
-
const newEl = createDOMNode(vnode);
|
|
1726
|
-
if (newEl) parent.appendChild(newEl);
|
|
1727
|
-
}
|
|
1728
|
-
return newKeyMap;
|
|
1729
|
-
}
|
|
978
|
+
const vnodeAny = node;
|
|
979
|
+
let childInstance = vnodeAny.__instance;
|
|
980
|
+
if (!childInstance) {
|
|
981
|
+
childInstance = createComponentInstance(
|
|
982
|
+
`comp-${Math.random().toString(36).slice(2, 7)}`,
|
|
983
|
+
componentFn,
|
|
984
|
+
props || {},
|
|
985
|
+
null
|
|
986
|
+
);
|
|
987
|
+
vnodeAny.__instance = childInstance;
|
|
1730
988
|
}
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
"[Askr][FASTPATH][DEV] Fast-path reconciliation invoked outside scheduler execution"
|
|
989
|
+
if (snapshot) {
|
|
990
|
+
childInstance.ownerFrame = snapshot;
|
|
991
|
+
}
|
|
992
|
+
const result = withContext(
|
|
993
|
+
snapshot,
|
|
994
|
+
() => renderComponentInline(childInstance)
|
|
1738
995
|
);
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
try {
|
|
1744
|
-
const pc = parent.children;
|
|
1745
|
-
parentChildrenArr = new Array(pc.length);
|
|
1746
|
-
for (let i = 0; i < pc.length; i++)
|
|
1747
|
-
parentChildrenArr[i] = pc[i];
|
|
1748
|
-
} catch {
|
|
1749
|
-
parentChildrenArr = void 0;
|
|
996
|
+
if (result instanceof Promise) {
|
|
997
|
+
throw new Error(
|
|
998
|
+
"Async components are not supported. Components must return synchronously."
|
|
999
|
+
);
|
|
1750
1000
|
}
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
for (let i = 0; i < parentChildren2.length; i++) {
|
|
1756
|
-
const ch = parentChildren2[i];
|
|
1757
|
-
const k2 = ch.getAttribute("data-key");
|
|
1758
|
-
if (k2 !== null) {
|
|
1759
|
-
localOldKeyMap.set(k2, ch);
|
|
1760
|
-
const n = Number(k2);
|
|
1761
|
-
if (!Number.isNaN(n)) localOldKeyMap.set(n, ch);
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
} catch {
|
|
1765
|
-
localOldKeyMap = void 0;
|
|
1001
|
+
const dom = withContext(snapshot, () => createDOMNode(result));
|
|
1002
|
+
if (dom instanceof Element) {
|
|
1003
|
+
mountInstanceInline(childInstance, dom);
|
|
1004
|
+
return dom;
|
|
1766
1005
|
}
|
|
1006
|
+
const host = document.createElement("div");
|
|
1007
|
+
if (dom instanceof DocumentFragment) {
|
|
1008
|
+
host.appendChild(dom);
|
|
1009
|
+
} else if (dom) {
|
|
1010
|
+
host.appendChild(dom);
|
|
1011
|
+
}
|
|
1012
|
+
mountInstanceInline(childInstance, host);
|
|
1013
|
+
return host;
|
|
1767
1014
|
}
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
let mapLookups = 0;
|
|
1777
|
-
let createdNodes = 0;
|
|
1778
|
-
let reusedCount = 0;
|
|
1779
|
-
for (let i = 0; i < keyedVnodes.length; i++) {
|
|
1780
|
-
const { key, vnode } = keyedVnodes[i];
|
|
1781
|
-
mapLookups++;
|
|
1782
|
-
let el;
|
|
1783
|
-
if (totalKeyed <= 20 && parentChildrenArr) {
|
|
1784
|
-
const ks = String(key);
|
|
1785
|
-
for (let j = 0; j < parentChildrenArr.length; j++) {
|
|
1786
|
-
const ch = parentChildrenArr[j];
|
|
1787
|
-
const k2 = ch.getAttribute("data-key");
|
|
1788
|
-
if (k2 !== null && (k2 === ks || Number(k2) === key)) {
|
|
1789
|
-
el = ch;
|
|
1790
|
-
break;
|
|
1015
|
+
if (typeof type === "symbol" && (type === Fragment || String(type) === "Symbol(Fragment)")) {
|
|
1016
|
+
const fragment = document.createDocumentFragment();
|
|
1017
|
+
const children = props.children || node.children;
|
|
1018
|
+
if (children) {
|
|
1019
|
+
if (Array.isArray(children)) {
|
|
1020
|
+
for (let i = 0; i < children.length; i++) {
|
|
1021
|
+
const dom = createDOMNode(children[i]);
|
|
1022
|
+
if (dom) fragment.appendChild(dom);
|
|
1791
1023
|
}
|
|
1024
|
+
} else {
|
|
1025
|
+
const dom = createDOMNode(children);
|
|
1026
|
+
if (dom) fragment.appendChild(dom);
|
|
1792
1027
|
}
|
|
1793
|
-
if (!el) el = oldKeyMap?.get(key);
|
|
1794
|
-
} else {
|
|
1795
|
-
el = localOldKeyMap?.get(key) ?? oldKeyMap?.get(key);
|
|
1796
1028
|
}
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1029
|
+
return fragment;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
return null;
|
|
1033
|
+
}
|
|
1034
|
+
function updateElementFromVnode(el, vnode, updateChildren = true) {
|
|
1035
|
+
if (!_isDOMElement(vnode)) {
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
const props = vnode.props || {};
|
|
1039
|
+
const vnodeKey = vnode.key ?? vnode.props?.key;
|
|
1040
|
+
if (vnodeKey !== void 0) {
|
|
1041
|
+
el.setAttribute("data-key", String(vnodeKey));
|
|
1042
|
+
}
|
|
1043
|
+
const existingListeners = elementListeners.get(el);
|
|
1044
|
+
const desiredEventNames = /* @__PURE__ */ new Set();
|
|
1045
|
+
for (const key in props) {
|
|
1046
|
+
const value = props[key];
|
|
1047
|
+
if (key === "children" || key === "key") continue;
|
|
1048
|
+
if (value === void 0 || value === null || value === false) {
|
|
1049
|
+
if (key === "class" || key === "className") {
|
|
1050
|
+
el.className = "";
|
|
1051
|
+
} else if (key.startsWith("on") && key.length > 2) {
|
|
1052
|
+
const eventName = key.slice(2).charAt(0).toLowerCase() + key.slice(3).toLowerCase();
|
|
1053
|
+
if (existingListeners && existingListeners.has(eventName)) {
|
|
1054
|
+
const entry = existingListeners.get(eventName);
|
|
1055
|
+
if (entry.options !== void 0)
|
|
1056
|
+
el.removeEventListener(eventName, entry.handler, entry.options);
|
|
1057
|
+
else el.removeEventListener(eventName, entry.handler);
|
|
1058
|
+
existingListeners.delete(eventName);
|
|
1805
1059
|
}
|
|
1060
|
+
continue;
|
|
1061
|
+
} else {
|
|
1062
|
+
el.removeAttribute(key);
|
|
1806
1063
|
}
|
|
1064
|
+
continue;
|
|
1807
1065
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1066
|
+
if (key === "class" || key === "className") {
|
|
1067
|
+
el.className = String(value);
|
|
1068
|
+
} else if (key === "value" || key === "checked") {
|
|
1069
|
+
el[key] = value;
|
|
1070
|
+
} else if (key.startsWith("on") && key.length > 2) {
|
|
1071
|
+
const eventName = key.slice(2).charAt(0).toLowerCase() + key.slice(3).toLowerCase();
|
|
1072
|
+
desiredEventNames.add(eventName);
|
|
1073
|
+
const existing = existingListeners?.get(eventName);
|
|
1074
|
+
if (existing && existing.original === value) {
|
|
1075
|
+
continue;
|
|
1813
1076
|
}
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
const
|
|
1818
|
-
|
|
1819
|
-
const orig = {};
|
|
1820
|
-
const elProto = Element.prototype;
|
|
1821
|
-
const nodeProto = Node.prototype;
|
|
1822
|
-
const removeFn = (() => {
|
|
1823
|
-
if (typeof document === "undefined" || typeof document.createElement !== "function")
|
|
1824
|
-
return void 0;
|
|
1077
|
+
if (existing) {
|
|
1078
|
+
el.removeEventListener(eventName, existing.handler);
|
|
1079
|
+
}
|
|
1080
|
+
const wrappedHandler = (event) => {
|
|
1081
|
+
globalScheduler.setInHandler(true);
|
|
1825
1082
|
try {
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
})();
|
|
1832
|
-
if (elProto.replaceChildren)
|
|
1833
|
-
orig.replaceChildren = elProto.replaceChildren;
|
|
1834
|
-
if (nodeProto.appendChild) orig.appendChild = nodeProto.appendChild;
|
|
1835
|
-
if (nodeProto.insertBefore) orig.insertBefore = nodeProto.insertBefore;
|
|
1836
|
-
if (nodeProto.removeChild) orig.removeChild = nodeProto.removeChild;
|
|
1837
|
-
if (nodeProto.replaceChild) orig.replaceChild = nodeProto.replaceChild;
|
|
1838
|
-
if (removeFn) orig.remove = removeFn;
|
|
1839
|
-
let violation = false;
|
|
1840
|
-
try {
|
|
1841
|
-
const fragment = document.createDocumentFragment();
|
|
1842
|
-
for (let i = 0; i < finalNodes.length; i++)
|
|
1843
|
-
fragment.appendChild(finalNodes[i]);
|
|
1844
|
-
let commitCount = 0;
|
|
1845
|
-
commitCount++;
|
|
1846
|
-
parent.replaceChildren(fragment);
|
|
1847
|
-
if (typeof globalThis !== "undefined") {
|
|
1848
|
-
globalThis["__ASKR_LAST_FASTPATH_COMMIT_COUNT"] = commitCount;
|
|
1083
|
+
value(event);
|
|
1084
|
+
} catch (error) {
|
|
1085
|
+
logger.error("[Askr] Event handler error:", error);
|
|
1086
|
+
} finally {
|
|
1087
|
+
globalScheduler.setInHandler(false);
|
|
1849
1088
|
}
|
|
1850
|
-
}
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
replaceChildrenCount,
|
|
1858
|
-
otherMutationCount
|
|
1859
|
-
}
|
|
1860
|
-
);
|
|
1861
|
-
throw new Error(
|
|
1862
|
-
"Fast-path must perform a single structural replacement (replaceChildren) and no other structural mutations"
|
|
1863
|
-
);
|
|
1089
|
+
};
|
|
1090
|
+
const options = eventName === "wheel" || eventName === "scroll" || eventName.startsWith("touch") ? { passive: true } : void 0;
|
|
1091
|
+
if (options !== void 0)
|
|
1092
|
+
el.addEventListener(eventName, wrappedHandler, options);
|
|
1093
|
+
else el.addEventListener(eventName, wrappedHandler);
|
|
1094
|
+
if (!elementListeners.has(el)) {
|
|
1095
|
+
elementListeners.set(el, /* @__PURE__ */ new Map());
|
|
1864
1096
|
}
|
|
1097
|
+
elementListeners.get(el).set(eventName, {
|
|
1098
|
+
handler: wrappedHandler,
|
|
1099
|
+
original: value,
|
|
1100
|
+
options
|
|
1101
|
+
});
|
|
1865
1102
|
} else {
|
|
1866
|
-
|
|
1867
|
-
const fragment = document.createDocumentFragment();
|
|
1868
|
-
let fragmentAppendCount = 0;
|
|
1869
|
-
for (let i = 0; i < finalNodes.length; i++) {
|
|
1870
|
-
fragment.appendChild(finalNodes[i]);
|
|
1871
|
-
fragmentAppendCount++;
|
|
1872
|
-
}
|
|
1873
|
-
const t_fragment = Date.now() - tFragmentStart;
|
|
1874
|
-
const schedBefore = process.env.NODE_ENV !== "production" ? globalScheduler.getState() : null;
|
|
1875
|
-
const wasExecuting = process.env.NODE_ENV !== "production" ? isSchedulerExecuting() : false;
|
|
1876
|
-
const tCommitStart = Date.now();
|
|
1877
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1878
|
-
}
|
|
1879
|
-
let commitCount = 0;
|
|
1880
|
-
commitCount++;
|
|
1881
|
-
try {
|
|
1882
|
-
const existing = Array.from(parent.childNodes);
|
|
1883
|
-
for (const n of existing) cleanupInstanceIfPresent(n);
|
|
1884
|
-
} catch (e) {
|
|
1885
|
-
void e;
|
|
1886
|
-
}
|
|
1887
|
-
try {
|
|
1888
|
-
const existing = Array.from(parent.childNodes);
|
|
1889
|
-
for (const n of existing) cleanupInstanceIfPresent(n);
|
|
1890
|
-
} catch (e) {
|
|
1891
|
-
void e;
|
|
1892
|
-
}
|
|
1893
|
-
parent.replaceChildren(fragment);
|
|
1894
|
-
if (typeof globalThis !== "undefined") {
|
|
1895
|
-
globalThis["__ASKR_LAST_FASTPATH_COMMIT_COUNT"] = commitCount;
|
|
1896
|
-
}
|
|
1897
|
-
const t_commit = Date.now() - tCommitStart;
|
|
1898
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1899
|
-
const schedAfter = globalScheduler.getState();
|
|
1900
|
-
if (!wasExecuting) {
|
|
1901
|
-
logger.warn(
|
|
1902
|
-
"[Askr][FASTPATH][DEV] Fast-path commit invoked outside scheduler execution"
|
|
1903
|
-
);
|
|
1904
|
-
}
|
|
1905
|
-
if (schedBefore && schedAfter) {
|
|
1906
|
-
if (schedBefore.taskCount !== schedAfter.taskCount) {
|
|
1907
|
-
logger.error(
|
|
1908
|
-
"[Askr][FASTPATH][DEV] Scheduler tasks were enqueued during fast-path commit",
|
|
1909
|
-
{
|
|
1910
|
-
before: schedBefore,
|
|
1911
|
-
after: schedAfter
|
|
1912
|
-
}
|
|
1913
|
-
);
|
|
1914
|
-
throw new Error("Fast-path must not enqueue scheduler tasks");
|
|
1915
|
-
}
|
|
1916
|
-
}
|
|
1917
|
-
const parentNodes = Array.from(parent.childNodes);
|
|
1918
|
-
if (parentNodes.length !== finalNodes.length) {
|
|
1919
|
-
logger.error("[Askr][FASTPATH][DEV] Parent child count mismatch", {
|
|
1920
|
-
parentCount: parentNodes.length,
|
|
1921
|
-
expected: finalNodes.length
|
|
1922
|
-
});
|
|
1923
|
-
throw new Error(
|
|
1924
|
-
"Fast-path must perform a single structural replacement"
|
|
1925
|
-
);
|
|
1926
|
-
}
|
|
1927
|
-
for (let i = 0; i < finalNodes.length; i++) {
|
|
1928
|
-
if (parentNodes[i] !== finalNodes[i]) {
|
|
1929
|
-
logger.error(
|
|
1930
|
-
"[Askr][FASTPATH][DEV] Final DOM order mismatch at index",
|
|
1931
|
-
i,
|
|
1932
|
-
{
|
|
1933
|
-
expected: finalNodes[i],
|
|
1934
|
-
found: parentNodes[i]
|
|
1935
|
-
}
|
|
1936
|
-
);
|
|
1937
|
-
throw new Error(
|
|
1938
|
-
"Fast-path final DOM order does not match expected nodes"
|
|
1939
|
-
);
|
|
1940
|
-
}
|
|
1941
|
-
}
|
|
1942
|
-
}
|
|
1943
|
-
const tBookkeepingStart = Date.now();
|
|
1944
|
-
for (let i = 0; i < keyedVnodes.length; i++) {
|
|
1945
|
-
const key = keyedVnodes[i].key;
|
|
1946
|
-
const node = finalNodes[i];
|
|
1947
|
-
if (node instanceof Element) newKeyMap.set(key, node);
|
|
1948
|
-
}
|
|
1949
|
-
const t_bookkeeping = Date.now() - tBookkeepingStart;
|
|
1950
|
-
if (process.env.ASKR_FASTPATH_TRACE === "1" || process.env.NODE_ENV !== "production") {
|
|
1951
|
-
const stats = {
|
|
1952
|
-
n: totalKeyed,
|
|
1953
|
-
moves: moveCount,
|
|
1954
|
-
lisLen: 0,
|
|
1955
|
-
t_lookup,
|
|
1956
|
-
t_fragment,
|
|
1957
|
-
t_commit,
|
|
1958
|
-
t_bookkeeping,
|
|
1959
|
-
fragmentAppendCount,
|
|
1960
|
-
mapLookups,
|
|
1961
|
-
createdNodes,
|
|
1962
|
-
reusedCount
|
|
1963
|
-
};
|
|
1964
|
-
if (typeof globalThis !== "undefined") {
|
|
1965
|
-
const _g = globalThis;
|
|
1966
|
-
_g["__ASKR_LAST_FASTPATH_STATS"] = stats;
|
|
1967
|
-
_g["__ASKR_LAST_FASTPATH_REUSED"] = reusedCount > 0;
|
|
1968
|
-
const historyKey = "__ASKR_LAST_FASTPATH_HISTORY";
|
|
1969
|
-
let hist = _g[historyKey];
|
|
1970
|
-
if (!hist) {
|
|
1971
|
-
hist = [];
|
|
1972
|
-
_g[historyKey] = hist;
|
|
1973
|
-
}
|
|
1974
|
-
hist.push(stats);
|
|
1975
|
-
}
|
|
1976
|
-
logger.warn("[Askr][FASTPATH]", JSON.stringify(stats));
|
|
1977
|
-
}
|
|
1103
|
+
el.setAttribute(key, String(value));
|
|
1978
1104
|
}
|
|
1979
|
-
return newKeyMap;
|
|
1980
1105
|
}
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
}
|
|
1989
|
-
}
|
|
1990
|
-
const tailsStart = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
|
|
1991
|
-
const keepSet = /* @__PURE__ */ new Set();
|
|
1992
|
-
const tails = [];
|
|
1993
|
-
const tailsIdx = [];
|
|
1994
|
-
const prev = new Array(positions.length).fill(-1);
|
|
1995
|
-
for (let i = 0; i < positions.length; i++) {
|
|
1996
|
-
const pos = positions[i];
|
|
1997
|
-
if (pos === -1) continue;
|
|
1998
|
-
let lo = 0;
|
|
1999
|
-
let hi = tails.length;
|
|
2000
|
-
while (lo < hi) {
|
|
2001
|
-
const mid = lo + hi >> 1;
|
|
2002
|
-
if (tails[mid] < pos) lo = mid + 1;
|
|
2003
|
-
else hi = mid;
|
|
2004
|
-
}
|
|
2005
|
-
if (lo === tails.length) {
|
|
2006
|
-
tails.push(pos);
|
|
2007
|
-
tailsIdx.push(i);
|
|
2008
|
-
} else {
|
|
2009
|
-
tails[lo] = pos;
|
|
2010
|
-
tailsIdx[lo] = i;
|
|
1106
|
+
if (existingListeners) {
|
|
1107
|
+
for (const eventName of existingListeners.keys()) {
|
|
1108
|
+
const entry = existingListeners.get(eventName);
|
|
1109
|
+
if (!desiredEventNames.has(eventName)) {
|
|
1110
|
+
el.removeEventListener(eventName, entry.handler);
|
|
1111
|
+
existingListeners.delete(eventName);
|
|
1112
|
+
}
|
|
2011
1113
|
}
|
|
2012
|
-
|
|
1114
|
+
if (existingListeners.size === 0) elementListeners.delete(el);
|
|
2013
1115
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
k = prev[k];
|
|
1116
|
+
if (updateChildren) {
|
|
1117
|
+
const children = vnode.children || props.children;
|
|
1118
|
+
updateElementChildren(el, children);
|
|
2018
1119
|
}
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
phase: "keyed-fallback-lis",
|
|
2025
|
-
positionsFound: positions.filter((p) => p !== -1).length,
|
|
2026
|
-
keepCount: keepSet.size,
|
|
2027
|
-
tLIS,
|
|
2028
|
-
previousDecision: prev2?.decision
|
|
2029
|
-
};
|
|
2030
|
-
} catch (e) {
|
|
2031
|
-
void e;
|
|
2032
|
-
}
|
|
1120
|
+
}
|
|
1121
|
+
function updateElementChildren(el, children) {
|
|
1122
|
+
if (!children) {
|
|
1123
|
+
el.textContent = "";
|
|
1124
|
+
return;
|
|
2033
1125
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
const el = oldKeyMap?.get(key);
|
|
2038
|
-
if (el && el.parentElement === parent) {
|
|
2039
|
-
if (keepSet.has(i)) {
|
|
2040
|
-
if (anchor === el) {
|
|
2041
|
-
anchor = el.nextSibling;
|
|
2042
|
-
}
|
|
2043
|
-
updateElementFromVnode(el, vnode);
|
|
2044
|
-
newKeyMap.set(key, el);
|
|
2045
|
-
} else {
|
|
2046
|
-
parent.insertBefore(el, anchor);
|
|
2047
|
-
updateElementFromVnode(el, vnode);
|
|
2048
|
-
newKeyMap.set(key, el);
|
|
2049
|
-
anchor = el.nextSibling;
|
|
2050
|
-
}
|
|
1126
|
+
if (!Array.isArray(children) && (typeof children === "string" || typeof children === "number")) {
|
|
1127
|
+
if (el.childNodes.length === 1 && el.firstChild?.nodeType === 3) {
|
|
1128
|
+
el.firstChild.data = String(children);
|
|
2051
1129
|
} else {
|
|
2052
|
-
|
|
2053
|
-
if (newEl instanceof Element) {
|
|
2054
|
-
parent.insertBefore(newEl, anchor);
|
|
2055
|
-
newKeyMap.set(key, newEl);
|
|
2056
|
-
anchor = newEl.nextSibling;
|
|
2057
|
-
}
|
|
1130
|
+
el.textContent = String(children);
|
|
2058
1131
|
}
|
|
1132
|
+
return;
|
|
2059
1133
|
}
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
parent.appendChild(newEl);
|
|
2064
|
-
}
|
|
1134
|
+
if (Array.isArray(children)) {
|
|
1135
|
+
updateUnkeyedChildren(el, children);
|
|
1136
|
+
return;
|
|
2065
1137
|
}
|
|
2066
|
-
|
|
1138
|
+
el.textContent = "";
|
|
1139
|
+
const dom = createDOMNode(children);
|
|
1140
|
+
if (dom) el.appendChild(dom);
|
|
2067
1141
|
}
|
|
2068
|
-
function
|
|
2069
|
-
const
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
const
|
|
2074
|
-
for (let i = 0; i <
|
|
2075
|
-
const
|
|
2076
|
-
const
|
|
2077
|
-
if (
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
1142
|
+
function updateUnkeyedChildren(parent, newChildren) {
|
|
1143
|
+
const existing = Array.from(parent.children);
|
|
1144
|
+
if (existing.length === 0 && parent.childNodes.length > 0) {
|
|
1145
|
+
parent.textContent = "";
|
|
1146
|
+
}
|
|
1147
|
+
const max = Math.max(existing.length, newChildren.length);
|
|
1148
|
+
for (let i = 0; i < max; i++) {
|
|
1149
|
+
const current = existing[i];
|
|
1150
|
+
const next = newChildren[i];
|
|
1151
|
+
if (next === void 0 && current) {
|
|
1152
|
+
cleanupInstanceIfPresent(current);
|
|
1153
|
+
current.remove();
|
|
1154
|
+
continue;
|
|
1155
|
+
}
|
|
1156
|
+
if (!current && next !== void 0) {
|
|
1157
|
+
const dom = createDOMNode(next);
|
|
1158
|
+
if (dom) parent.appendChild(dom);
|
|
1159
|
+
continue;
|
|
1160
|
+
}
|
|
1161
|
+
if (!current || next === void 0) continue;
|
|
1162
|
+
if (typeof next === "string" || typeof next === "number") {
|
|
1163
|
+
current.textContent = String(next);
|
|
1164
|
+
} else if (_isDOMElement(next)) {
|
|
1165
|
+
if (typeof next.type === "string") {
|
|
1166
|
+
if (current.tagName.toLowerCase() === next.type.toLowerCase()) {
|
|
1167
|
+
updateElementFromVnode(current, next);
|
|
2088
1168
|
} else {
|
|
2089
|
-
|
|
1169
|
+
const dom = createDOMNode(next);
|
|
1170
|
+
if (dom) {
|
|
1171
|
+
if (current instanceof Element) removeAllListeners(current);
|
|
1172
|
+
cleanupInstanceIfPresent(current);
|
|
1173
|
+
parent.replaceChild(dom, current);
|
|
1174
|
+
}
|
|
2090
1175
|
}
|
|
2091
1176
|
} else {
|
|
2092
|
-
|
|
1177
|
+
const dom = createDOMNode(next);
|
|
1178
|
+
if (dom) {
|
|
1179
|
+
if (current instanceof Element) removeAllListeners(current);
|
|
1180
|
+
cleanupInstanceIfPresent(current);
|
|
1181
|
+
parent.replaceChild(dom, current);
|
|
1182
|
+
}
|
|
2093
1183
|
}
|
|
2094
|
-
finalNodes.push(el);
|
|
2095
|
-
reused++;
|
|
2096
1184
|
} else {
|
|
2097
|
-
const dom = createDOMNode(
|
|
1185
|
+
const dom = createDOMNode(next);
|
|
2098
1186
|
if (dom) {
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
}
|
|
2103
|
-
}
|
|
2104
|
-
try {
|
|
2105
|
-
const toRemove = Array.from(parent.childNodes).filter(
|
|
2106
|
-
(n) => !finalNodes.includes(n)
|
|
2107
|
-
);
|
|
2108
|
-
for (const n of toRemove) cleanupInstanceIfPresent(n);
|
|
2109
|
-
} catch (e) {
|
|
2110
|
-
void e;
|
|
2111
|
-
}
|
|
2112
|
-
const existingChildren = Array.from(parent.children);
|
|
2113
|
-
const listenerSnapshots = new Array(existingChildren.length).fill(void 0);
|
|
2114
|
-
try {
|
|
2115
|
-
for (let i = 0; i < existingChildren.length; i++) {
|
|
2116
|
-
const ch = existingChildren[i];
|
|
2117
|
-
if (ch) {
|
|
2118
|
-
const map = elementListeners.get(ch);
|
|
2119
|
-
if (map && map.size > 0) {
|
|
2120
|
-
const clone = /* @__PURE__ */ new Map();
|
|
2121
|
-
for (const [k, v] of map) clone.set(k, v);
|
|
2122
|
-
listenerSnapshots[i] = clone;
|
|
2123
|
-
}
|
|
2124
|
-
}
|
|
2125
|
-
}
|
|
2126
|
-
} catch (e) {
|
|
2127
|
-
void e;
|
|
2128
|
-
}
|
|
2129
|
-
const fragment = document.createDocumentFragment();
|
|
2130
|
-
for (let i = 0; i < finalNodes.length; i++)
|
|
2131
|
-
fragment.appendChild(finalNodes[i]);
|
|
2132
|
-
parent.replaceChildren(fragment);
|
|
2133
|
-
try {
|
|
2134
|
-
for (let i = 0; i < finalNodes.length; i++) {
|
|
2135
|
-
const newNode = finalNodes[i];
|
|
2136
|
-
const snapshot = listenerSnapshots[i];
|
|
2137
|
-
if (snapshot && newNode instanceof Element) {
|
|
2138
|
-
for (const [eventName, entry] of snapshot) {
|
|
2139
|
-
const existing = elementListeners.get(newNode)?.get(eventName);
|
|
2140
|
-
if (existing && existing.original === entry.original) continue;
|
|
2141
|
-
newNode.addEventListener(eventName, entry.handler);
|
|
2142
|
-
if (!elementListeners.has(newNode))
|
|
2143
|
-
elementListeners.set(newNode, /* @__PURE__ */ new Map());
|
|
2144
|
-
elementListeners.get(newNode).set(eventName, entry);
|
|
2145
|
-
}
|
|
1187
|
+
if (current instanceof Element) removeAllListeners(current);
|
|
1188
|
+
cleanupInstanceIfPresent(current);
|
|
1189
|
+
parent.replaceChild(dom, current);
|
|
2146
1190
|
}
|
|
2147
1191
|
}
|
|
2148
|
-
} catch (e) {
|
|
2149
|
-
void e;
|
|
2150
|
-
}
|
|
2151
|
-
try {
|
|
2152
|
-
keyedElements.delete(parent);
|
|
2153
|
-
} catch (e) {
|
|
2154
|
-
void e;
|
|
2155
1192
|
}
|
|
2156
|
-
const t = typeof performance !== "undefined" && performance.now ? performance.now() - t0 : 0;
|
|
2157
|
-
const stats = {
|
|
2158
|
-
n: total,
|
|
2159
|
-
reused,
|
|
2160
|
-
created,
|
|
2161
|
-
t
|
|
2162
|
-
};
|
|
2163
|
-
return stats;
|
|
2164
1193
|
}
|
|
2165
1194
|
function performBulkPositionalKeyedTextUpdate(parent, keyedVnodes) {
|
|
2166
1195
|
const total = keyedVnodes.length;
|
|
@@ -2174,6 +1203,18 @@ function performBulkPositionalKeyedTextUpdate(parent, keyedVnodes) {
|
|
|
2174
1203
|
const vnodeType = vnode.type;
|
|
2175
1204
|
if (ch.tagName.toLowerCase() === vnodeType.toLowerCase()) {
|
|
2176
1205
|
const children = vnode.children || vnode.props?.children;
|
|
1206
|
+
try {
|
|
1207
|
+
if (process.env.ASKR_FASTPATH_DEBUG === "1" || process.env.ASKR_FASTPATH_DEBUG === "true") {
|
|
1208
|
+
logger.warn("[Askr][FASTPATH] positional idx", i, {
|
|
1209
|
+
chTag: ch.tagName.toLowerCase(),
|
|
1210
|
+
vnodeType,
|
|
1211
|
+
chChildNodes: ch.childNodes.length,
|
|
1212
|
+
childrenType: Array.isArray(children) ? "array" : typeof children
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1215
|
+
} catch (e) {
|
|
1216
|
+
void e;
|
|
1217
|
+
}
|
|
2177
1218
|
if (typeof children === "string" || typeof children === "number") {
|
|
2178
1219
|
if (ch.childNodes.length === 1 && ch.firstChild?.nodeType === 3) {
|
|
2179
1220
|
ch.firstChild.data = String(children);
|
|
@@ -2197,6 +1238,27 @@ function performBulkPositionalKeyedTextUpdate(parent, keyedVnodes) {
|
|
|
2197
1238
|
}
|
|
2198
1239
|
reused++;
|
|
2199
1240
|
continue;
|
|
1241
|
+
} else {
|
|
1242
|
+
try {
|
|
1243
|
+
if (process.env.ASKR_FASTPATH_DEBUG === "1" || process.env.ASKR_FASTPATH_DEBUG === "true") {
|
|
1244
|
+
logger.warn("[Askr][FASTPATH] positional tag mismatch", i, {
|
|
1245
|
+
chTag: ch.tagName.toLowerCase(),
|
|
1246
|
+
vnodeType
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
} catch (e) {
|
|
1250
|
+
void e;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
} else {
|
|
1254
|
+
try {
|
|
1255
|
+
if (process.env.ASKR_FASTPATH_DEBUG === "1" || process.env.ASKR_FASTPATH_DEBUG === "true") {
|
|
1256
|
+
logger.warn("[Askr][FASTPATH] positional missing or invalid", i, {
|
|
1257
|
+
ch: !!ch
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
} catch (e) {
|
|
1261
|
+
void e;
|
|
2200
1262
|
}
|
|
2201
1263
|
}
|
|
2202
1264
|
const dom = createDOMNode(vnode);
|
|
@@ -2220,12 +1282,99 @@ function performBulkPositionalKeyedTextUpdate(parent, keyedVnodes) {
|
|
|
2220
1282
|
} catch (e) {
|
|
2221
1283
|
void e;
|
|
2222
1284
|
}
|
|
1285
|
+
const stats = { n: total, reused, updatedKeys, t };
|
|
1286
|
+
try {
|
|
1287
|
+
if (process.env.ASKR_FASTPATH_DEBUG === "1" || process.env.ASKR_FASTPATH_DEBUG === "true") {
|
|
1288
|
+
logger.warn("[Askr][FASTPATH] bulk positional stats", stats);
|
|
1289
|
+
}
|
|
1290
|
+
__ASKR_set("__LAST_FASTPATH_STATS", stats);
|
|
1291
|
+
__ASKR_set("__LAST_FASTPATH_COMMIT_COUNT", 1);
|
|
1292
|
+
__ASKR_incCounter("bulkKeyedPositionalHits");
|
|
1293
|
+
} catch (e) {
|
|
1294
|
+
void e;
|
|
1295
|
+
}
|
|
1296
|
+
return stats;
|
|
1297
|
+
}
|
|
1298
|
+
function performBulkTextReplace(parent, newChildren) {
|
|
1299
|
+
const t0 = typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
|
|
1300
|
+
const existing = Array.from(parent.childNodes);
|
|
1301
|
+
const finalNodes = [];
|
|
1302
|
+
let reused = 0;
|
|
1303
|
+
let created = 0;
|
|
1304
|
+
for (let i = 0; i < newChildren.length; i++) {
|
|
1305
|
+
const vnode = newChildren[i];
|
|
1306
|
+
const existingNode = existing[i];
|
|
1307
|
+
if (typeof vnode === "string" || typeof vnode === "number") {
|
|
1308
|
+
const text = String(vnode);
|
|
1309
|
+
if (existingNode && existingNode.nodeType === 3) {
|
|
1310
|
+
existingNode.data = text;
|
|
1311
|
+
finalNodes.push(existingNode);
|
|
1312
|
+
reused++;
|
|
1313
|
+
} else {
|
|
1314
|
+
finalNodes.push(document.createTextNode(text));
|
|
1315
|
+
created++;
|
|
1316
|
+
}
|
|
1317
|
+
continue;
|
|
1318
|
+
}
|
|
1319
|
+
if (typeof vnode === "object" && vnode !== null && "type" in vnode) {
|
|
1320
|
+
const vnodeObj = vnode;
|
|
1321
|
+
if (typeof vnodeObj.type === "string") {
|
|
1322
|
+
const tag = vnodeObj.type;
|
|
1323
|
+
if (existingNode && existingNode.nodeType === 1 && existingNode.tagName.toLowerCase() === tag.toLowerCase()) {
|
|
1324
|
+
updateElementFromVnode(existingNode, vnode);
|
|
1325
|
+
finalNodes.push(existingNode);
|
|
1326
|
+
reused++;
|
|
1327
|
+
continue;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
const dom = createDOMNode(vnode);
|
|
1331
|
+
if (dom) {
|
|
1332
|
+
finalNodes.push(dom);
|
|
1333
|
+
created++;
|
|
1334
|
+
continue;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
const tBuild = (typeof performance !== "undefined" && performance.now ? performance.now() : Date.now()) - t0;
|
|
1339
|
+
try {
|
|
1340
|
+
const toRemove = Array.from(parent.childNodes).filter(
|
|
1341
|
+
(n) => !finalNodes.includes(n)
|
|
1342
|
+
);
|
|
1343
|
+
for (const n of toRemove) {
|
|
1344
|
+
if (n instanceof Element) removeAllListeners(n);
|
|
1345
|
+
cleanupInstanceIfPresent(n);
|
|
1346
|
+
}
|
|
1347
|
+
} catch (e) {
|
|
1348
|
+
void e;
|
|
1349
|
+
}
|
|
1350
|
+
const fragStart = Date.now();
|
|
1351
|
+
const fragment = document.createDocumentFragment();
|
|
1352
|
+
for (let i = 0; i < finalNodes.length; i++)
|
|
1353
|
+
fragment.appendChild(finalNodes[i]);
|
|
1354
|
+
try {
|
|
1355
|
+
__ASKR_incCounter("__DOM_REPLACE_COUNT");
|
|
1356
|
+
__ASKR_set("__LAST_DOM_REPLACE_STACK_DOM", new Error().stack);
|
|
1357
|
+
} catch (e) {
|
|
1358
|
+
void e;
|
|
1359
|
+
}
|
|
1360
|
+
parent.replaceChildren(fragment);
|
|
1361
|
+
const tCommit = Date.now() - fragStart;
|
|
1362
|
+
keyedElements.delete(parent);
|
|
2223
1363
|
const stats = {
|
|
2224
|
-
n:
|
|
1364
|
+
n: newChildren.length,
|
|
2225
1365
|
reused,
|
|
2226
|
-
|
|
2227
|
-
|
|
1366
|
+
created,
|
|
1367
|
+
tBuild,
|
|
1368
|
+
tCommit
|
|
2228
1369
|
};
|
|
1370
|
+
try {
|
|
1371
|
+
__ASKR_set("__LAST_BULK_TEXT_FASTPATH_STATS", stats);
|
|
1372
|
+
__ASKR_set("__LAST_FASTPATH_STATS", stats);
|
|
1373
|
+
__ASKR_set("__LAST_FASTPATH_COMMIT_COUNT", 1);
|
|
1374
|
+
__ASKR_incCounter("bulkTextFastpathHits");
|
|
1375
|
+
} catch (e) {
|
|
1376
|
+
void e;
|
|
1377
|
+
}
|
|
2229
1378
|
return stats;
|
|
2230
1379
|
}
|
|
2231
1380
|
function isBulkTextFastPathEligible(parent, newChildren) {
|
|
@@ -2235,12 +1384,12 @@ function isBulkTextFastPathEligible(parent, newChildren) {
|
|
|
2235
1384
|
if (total < threshold) {
|
|
2236
1385
|
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
2237
1386
|
try {
|
|
2238
|
-
|
|
1387
|
+
__ASKR_set("__BULK_DIAG", {
|
|
2239
1388
|
phase: "bulk-unkeyed-eligible",
|
|
2240
1389
|
reason: "too-small",
|
|
2241
1390
|
total,
|
|
2242
1391
|
threshold
|
|
2243
|
-
};
|
|
1392
|
+
});
|
|
2244
1393
|
} catch (e) {
|
|
2245
1394
|
void e;
|
|
2246
1395
|
}
|
|
@@ -2259,11 +1408,11 @@ function isBulkTextFastPathEligible(parent, newChildren) {
|
|
|
2259
1408
|
if (typeof dv.type === "function") {
|
|
2260
1409
|
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
2261
1410
|
try {
|
|
2262
|
-
|
|
1411
|
+
__ASKR_set("__BULK_DIAG", {
|
|
2263
1412
|
phase: "bulk-unkeyed-eligible",
|
|
2264
1413
|
reason: "component-child",
|
|
2265
1414
|
index: i
|
|
2266
|
-
};
|
|
1415
|
+
});
|
|
2267
1416
|
} catch (e) {
|
|
2268
1417
|
void e;
|
|
2269
1418
|
}
|
|
@@ -2292,438 +1441,806 @@ function isBulkTextFastPathEligible(parent, newChildren) {
|
|
|
2292
1441
|
const eligible = fraction >= requiredFraction && parent.childNodes.length >= total;
|
|
2293
1442
|
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
2294
1443
|
try {
|
|
2295
|
-
|
|
1444
|
+
__ASKR_set("__BULK_DIAG", {
|
|
2296
1445
|
phase: "bulk-unkeyed-eligible",
|
|
2297
1446
|
total,
|
|
2298
1447
|
simple,
|
|
2299
1448
|
fraction,
|
|
2300
1449
|
requiredFraction,
|
|
2301
1450
|
eligible
|
|
2302
|
-
};
|
|
1451
|
+
});
|
|
2303
1452
|
} catch (e) {
|
|
2304
1453
|
void e;
|
|
2305
1454
|
}
|
|
2306
1455
|
}
|
|
2307
1456
|
return eligible;
|
|
2308
1457
|
}
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
1458
|
+
var IS_DOM_AVAILABLE;
|
|
1459
|
+
var init_dom = __esm({
|
|
1460
|
+
"src/renderer/dom.ts"() {
|
|
1461
|
+
"use strict";
|
|
1462
|
+
init_scheduler();
|
|
1463
|
+
init_logger();
|
|
1464
|
+
init_jsx_runtime();
|
|
1465
|
+
init_context();
|
|
1466
|
+
init_component();
|
|
1467
|
+
init_cleanup();
|
|
1468
|
+
init_diag();
|
|
1469
|
+
init_types();
|
|
1470
|
+
init_keyed();
|
|
1471
|
+
IS_DOM_AVAILABLE = typeof document !== "undefined";
|
|
1472
|
+
}
|
|
1473
|
+
});
|
|
1474
|
+
|
|
1475
|
+
// src/renderer/fastpath.ts
|
|
1476
|
+
function applyRendererFastPath(parent, keyedVnodes, oldKeyMap, unkeyedVnodes) {
|
|
1477
|
+
if (typeof document === "undefined") return null;
|
|
1478
|
+
const totalKeyed = keyedVnodes.length;
|
|
1479
|
+
if (totalKeyed === 0 && (!unkeyedVnodes || unkeyedVnodes.length === 0))
|
|
1480
|
+
return null;
|
|
1481
|
+
if (!isSchedulerExecuting()) {
|
|
1482
|
+
logger.warn(
|
|
1483
|
+
"[Askr][FASTPATH][DEV] Fast-path reconciliation invoked outside scheduler execution"
|
|
1484
|
+
);
|
|
1485
|
+
}
|
|
1486
|
+
let parentChildrenArr;
|
|
1487
|
+
let localOldKeyMap;
|
|
1488
|
+
if (totalKeyed <= 20) {
|
|
1489
|
+
try {
|
|
1490
|
+
const pc = parent.children;
|
|
1491
|
+
parentChildrenArr = new Array(pc.length);
|
|
1492
|
+
for (let i = 0; i < pc.length; i++)
|
|
1493
|
+
parentChildrenArr[i] = pc[i];
|
|
1494
|
+
} catch (e) {
|
|
1495
|
+
parentChildrenArr = void 0;
|
|
1496
|
+
void e;
|
|
2329
1497
|
}
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
}
|
|
2342
|
-
} else if (Array.isArray(children) && children.length === 1 && (typeof children[0] === "string" || typeof children[0] === "number")) {
|
|
2343
|
-
if (el.childNodes.length === 1 && el.firstChild?.nodeType === 3) {
|
|
2344
|
-
el.firstChild.data = String(children[0]);
|
|
2345
|
-
} else {
|
|
2346
|
-
el.textContent = String(children[0]);
|
|
2347
|
-
}
|
|
2348
|
-
} else {
|
|
2349
|
-
updateElementFromVnode(el, vnode);
|
|
2350
|
-
}
|
|
2351
|
-
finalNodes.push(el);
|
|
2352
|
-
reused++;
|
|
2353
|
-
continue;
|
|
2354
|
-
}
|
|
2355
|
-
const dom2 = createDOMNode(vnode);
|
|
2356
|
-
if (dom2) {
|
|
2357
|
-
finalNodes.push(dom2);
|
|
2358
|
-
created++;
|
|
1498
|
+
} else {
|
|
1499
|
+
localOldKeyMap = /* @__PURE__ */ new Map();
|
|
1500
|
+
try {
|
|
1501
|
+
const parentChildren = Array.from(parent.children);
|
|
1502
|
+
for (let i = 0; i < parentChildren.length; i++) {
|
|
1503
|
+
const ch = parentChildren[i];
|
|
1504
|
+
const k = ch.getAttribute("data-key");
|
|
1505
|
+
if (k !== null) {
|
|
1506
|
+
localOldKeyMap.set(k, ch);
|
|
1507
|
+
const n = Number(k);
|
|
1508
|
+
if (!Number.isNaN(n)) localOldKeyMap.set(n, ch);
|
|
2359
1509
|
}
|
|
2360
|
-
continue;
|
|
2361
1510
|
}
|
|
1511
|
+
} catch (e) {
|
|
1512
|
+
localOldKeyMap = void 0;
|
|
1513
|
+
void e;
|
|
2362
1514
|
}
|
|
2363
|
-
const dom = createDOMNode(vnode);
|
|
2364
|
-
if (dom) {
|
|
2365
|
-
finalNodes.push(dom);
|
|
2366
|
-
created++;
|
|
2367
|
-
}
|
|
2368
|
-
}
|
|
2369
|
-
const tBuild = typeof performance !== "undefined" && performance.now ? performance.now() - t0 : 0;
|
|
2370
|
-
try {
|
|
2371
|
-
const toRemove = Array.from(parent.childNodes).filter(
|
|
2372
|
-
(n) => !finalNodes.includes(n)
|
|
2373
|
-
);
|
|
2374
|
-
for (const n of toRemove) cleanupInstanceIfPresent(n);
|
|
2375
|
-
} catch (e) {
|
|
2376
|
-
void e;
|
|
2377
1515
|
}
|
|
2378
|
-
const
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
function updateElementFromVnode(el, vnode, updateChildren = true) {
|
|
2395
|
-
if (!_isDOMElement(vnode)) {
|
|
2396
|
-
return;
|
|
2397
|
-
}
|
|
2398
|
-
const props = vnode.props || {};
|
|
2399
|
-
if (vnode.key !== void 0) {
|
|
2400
|
-
el.setAttribute("data-key", String(vnode.key));
|
|
2401
|
-
}
|
|
2402
|
-
const existingListeners = elementListeners.get(el);
|
|
2403
|
-
const desiredEventNames = /* @__PURE__ */ new Set();
|
|
2404
|
-
for (const key in props) {
|
|
2405
|
-
const value = props[key];
|
|
2406
|
-
if (key === "children" || key === "key") continue;
|
|
2407
|
-
if (value === void 0 || value === null || value === false) {
|
|
2408
|
-
if (key === "class" || key === "className") {
|
|
2409
|
-
el.className = "";
|
|
2410
|
-
} else if (key.startsWith("on") && key.length > 2) {
|
|
2411
|
-
const eventName = key.slice(2).charAt(0).toLowerCase() + key.slice(3).toLowerCase();
|
|
2412
|
-
if (existingListeners && existingListeners.has(eventName)) {
|
|
2413
|
-
const entry = existingListeners.get(eventName);
|
|
2414
|
-
el.removeEventListener(eventName, entry.handler);
|
|
2415
|
-
existingListeners.delete(eventName);
|
|
1516
|
+
const finalNodes = [];
|
|
1517
|
+
let mapLookups = 0;
|
|
1518
|
+
let createdNodes = 0;
|
|
1519
|
+
let reusedCount = 0;
|
|
1520
|
+
for (let i = 0; i < keyedVnodes.length; i++) {
|
|
1521
|
+
const { key, vnode } = keyedVnodes[i];
|
|
1522
|
+
mapLookups++;
|
|
1523
|
+
let el;
|
|
1524
|
+
if (totalKeyed <= 20 && parentChildrenArr) {
|
|
1525
|
+
const ks = String(key);
|
|
1526
|
+
for (let j = 0; j < parentChildrenArr.length; j++) {
|
|
1527
|
+
const ch = parentChildrenArr[j];
|
|
1528
|
+
const k = ch.getAttribute("data-key");
|
|
1529
|
+
if (k !== null && (k === ks || Number(k) === key)) {
|
|
1530
|
+
el = ch;
|
|
1531
|
+
break;
|
|
2416
1532
|
}
|
|
2417
|
-
continue;
|
|
2418
|
-
} else {
|
|
2419
|
-
el.removeAttribute(key);
|
|
2420
1533
|
}
|
|
2421
|
-
|
|
1534
|
+
if (!el) el = oldKeyMap?.get(key);
|
|
1535
|
+
} else {
|
|
1536
|
+
el = localOldKeyMap?.get(key) ?? oldKeyMap?.get(key);
|
|
2422
1537
|
}
|
|
2423
|
-
if (
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
el[key] = value;
|
|
2427
|
-
} else if (key.startsWith("on") && key.length > 2) {
|
|
2428
|
-
const eventName = key.slice(2).charAt(0).toLowerCase() + key.slice(3).toLowerCase();
|
|
2429
|
-
desiredEventNames.add(eventName);
|
|
2430
|
-
const existing = existingListeners?.get(eventName);
|
|
2431
|
-
if (existing && existing.original === value) {
|
|
2432
|
-
continue;
|
|
2433
|
-
}
|
|
2434
|
-
if (existing) {
|
|
2435
|
-
el.removeEventListener(eventName, existing.handler);
|
|
2436
|
-
}
|
|
2437
|
-
const wrappedHandler = (event) => {
|
|
2438
|
-
globalScheduler.setInHandler(true);
|
|
2439
|
-
try {
|
|
2440
|
-
value(event);
|
|
2441
|
-
} catch (error) {
|
|
2442
|
-
logger.error("[Askr] Event handler error:", error);
|
|
2443
|
-
} finally {
|
|
2444
|
-
globalScheduler.setInHandler(false);
|
|
2445
|
-
}
|
|
2446
|
-
};
|
|
2447
|
-
el.addEventListener(eventName, wrappedHandler);
|
|
2448
|
-
if (!elementListeners.has(el)) {
|
|
2449
|
-
elementListeners.set(el, /* @__PURE__ */ new Map());
|
|
2450
|
-
}
|
|
2451
|
-
elementListeners.get(el).set(eventName, {
|
|
2452
|
-
handler: wrappedHandler,
|
|
2453
|
-
original: value
|
|
2454
|
-
});
|
|
1538
|
+
if (el) {
|
|
1539
|
+
finalNodes.push(el);
|
|
1540
|
+
reusedCount++;
|
|
2455
1541
|
} else {
|
|
2456
|
-
|
|
1542
|
+
const newEl = createDOMNode(vnode);
|
|
1543
|
+
if (newEl) {
|
|
1544
|
+
finalNodes.push(newEl);
|
|
1545
|
+
createdNodes++;
|
|
1546
|
+
}
|
|
2457
1547
|
}
|
|
2458
1548
|
}
|
|
2459
|
-
if (
|
|
2460
|
-
for (const
|
|
2461
|
-
const
|
|
2462
|
-
if (
|
|
2463
|
-
|
|
2464
|
-
|
|
1549
|
+
if (unkeyedVnodes && unkeyedVnodes.length) {
|
|
1550
|
+
for (const vnode of unkeyedVnodes) {
|
|
1551
|
+
const newEl = createDOMNode(vnode);
|
|
1552
|
+
if (newEl) {
|
|
1553
|
+
finalNodes.push(newEl);
|
|
1554
|
+
createdNodes++;
|
|
2465
1555
|
}
|
|
2466
1556
|
}
|
|
2467
|
-
if (existingListeners.size === 0) elementListeners.delete(el);
|
|
2468
1557
|
}
|
|
2469
|
-
|
|
2470
|
-
const
|
|
2471
|
-
|
|
1558
|
+
try {
|
|
1559
|
+
const tFragmentStart = Date.now();
|
|
1560
|
+
const fragment = document.createDocumentFragment();
|
|
1561
|
+
let fragmentAppendCount = 0;
|
|
1562
|
+
for (let i = 0; i < finalNodes.length; i++) {
|
|
1563
|
+
fragment.appendChild(finalNodes[i]);
|
|
1564
|
+
fragmentAppendCount++;
|
|
1565
|
+
}
|
|
1566
|
+
try {
|
|
1567
|
+
const existing = Array.from(parent.childNodes);
|
|
1568
|
+
const toRemove = existing.filter((n) => !finalNodes.includes(n));
|
|
1569
|
+
for (const n of toRemove) {
|
|
1570
|
+
if (n instanceof Element) removeAllListeners(n);
|
|
1571
|
+
cleanupInstanceIfPresent(n);
|
|
1572
|
+
}
|
|
1573
|
+
} catch (e) {
|
|
1574
|
+
void e;
|
|
1575
|
+
}
|
|
1576
|
+
try {
|
|
1577
|
+
__ASKR_incCounter("__DOM_REPLACE_COUNT");
|
|
1578
|
+
__ASKR_set("__LAST_DOM_REPLACE_STACK_FASTPATH", new Error().stack);
|
|
1579
|
+
} catch (e) {
|
|
1580
|
+
void e;
|
|
1581
|
+
}
|
|
1582
|
+
parent.replaceChildren(fragment);
|
|
1583
|
+
try {
|
|
1584
|
+
__ASKR_set("__LAST_FASTPATH_COMMIT_COUNT", 1);
|
|
1585
|
+
} catch (e) {
|
|
1586
|
+
void e;
|
|
1587
|
+
}
|
|
1588
|
+
try {
|
|
1589
|
+
if (isBulkCommitActive2()) markFastPathApplied(parent);
|
|
1590
|
+
} catch (e) {
|
|
1591
|
+
void e;
|
|
1592
|
+
}
|
|
1593
|
+
const newKeyMap = /* @__PURE__ */ new Map();
|
|
1594
|
+
for (let i = 0; i < keyedVnodes.length; i++) {
|
|
1595
|
+
const key = keyedVnodes[i].key;
|
|
1596
|
+
const node = finalNodes[i];
|
|
1597
|
+
if (node instanceof Element) newKeyMap.set(key, node);
|
|
1598
|
+
}
|
|
1599
|
+
try {
|
|
1600
|
+
const stats = {
|
|
1601
|
+
n: totalKeyed,
|
|
1602
|
+
moves: 0,
|
|
1603
|
+
lisLen: 0,
|
|
1604
|
+
t_lookup: 0,
|
|
1605
|
+
t_fragment: Date.now() - tFragmentStart,
|
|
1606
|
+
t_commit: 0,
|
|
1607
|
+
t_bookkeeping: 0,
|
|
1608
|
+
fragmentAppendCount,
|
|
1609
|
+
mapLookups,
|
|
1610
|
+
createdNodes,
|
|
1611
|
+
reusedCount
|
|
1612
|
+
};
|
|
1613
|
+
if (typeof globalThis !== "undefined") {
|
|
1614
|
+
__ASKR_set("__LAST_FASTPATH_STATS", stats);
|
|
1615
|
+
__ASKR_set("__LAST_FASTPATH_REUSED", reusedCount > 0);
|
|
1616
|
+
__ASKR_incCounter("fastpathHistoryPush");
|
|
1617
|
+
}
|
|
1618
|
+
if (process.env.ASKR_FASTPATH_DEBUG === "1" || process.env.ASKR_FASTPATH_DEBUG === "true") {
|
|
1619
|
+
logger.warn(
|
|
1620
|
+
"[Askr][FASTPATH]",
|
|
1621
|
+
JSON.stringify({ n: totalKeyed, createdNodes, reusedCount })
|
|
1622
|
+
);
|
|
1623
|
+
}
|
|
1624
|
+
} catch (e) {
|
|
1625
|
+
void e;
|
|
1626
|
+
}
|
|
1627
|
+
try {
|
|
1628
|
+
_reconcilerRecordedParents.add(parent);
|
|
1629
|
+
} catch (e) {
|
|
1630
|
+
void e;
|
|
1631
|
+
}
|
|
1632
|
+
return newKeyMap;
|
|
1633
|
+
} catch (e) {
|
|
1634
|
+
void e;
|
|
1635
|
+
return null;
|
|
2472
1636
|
}
|
|
2473
1637
|
}
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
1638
|
+
var init_fastpath = __esm({
|
|
1639
|
+
"src/renderer/fastpath.ts"() {
|
|
1640
|
+
"use strict";
|
|
1641
|
+
init_dom();
|
|
1642
|
+
init_keyed();
|
|
1643
|
+
init_logger();
|
|
1644
|
+
init_cleanup();
|
|
1645
|
+
init_diag();
|
|
1646
|
+
init_scheduler();
|
|
1647
|
+
init_fastlane_shared();
|
|
2478
1648
|
}
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
1649
|
+
});
|
|
1650
|
+
|
|
1651
|
+
// src/renderer/reconcile.ts
|
|
1652
|
+
function reconcileKeyedChildren(parent, newChildren, oldKeyMap) {
|
|
1653
|
+
const newKeyMap = /* @__PURE__ */ new Map();
|
|
1654
|
+
const keyedVnodes = [];
|
|
1655
|
+
const unkeyedVnodes = [];
|
|
1656
|
+
for (let i = 0; i < newChildren.length; i++) {
|
|
1657
|
+
const child = newChildren[i];
|
|
1658
|
+
if (typeof child === "object" && child !== null && "type" in child) {
|
|
1659
|
+
const childObj = child;
|
|
1660
|
+
const rawKey = childObj.key ?? childObj.props?.key;
|
|
1661
|
+
if (rawKey !== void 0) {
|
|
1662
|
+
const key = typeof rawKey === "symbol" ? String(rawKey) : rawKey;
|
|
1663
|
+
keyedVnodes.push({ key, vnode: child });
|
|
1664
|
+
} else {
|
|
1665
|
+
unkeyedVnodes.push(child);
|
|
1666
|
+
}
|
|
2482
1667
|
} else {
|
|
2483
|
-
|
|
1668
|
+
unkeyedVnodes.push(child);
|
|
2484
1669
|
}
|
|
2485
|
-
return;
|
|
2486
1670
|
}
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
1671
|
+
try {
|
|
1672
|
+
const decision = isKeyedReorderFastPathEligible(
|
|
1673
|
+
parent,
|
|
1674
|
+
newChildren,
|
|
1675
|
+
oldKeyMap
|
|
1676
|
+
);
|
|
1677
|
+
if (decision.useFastPath && keyedVnodes.length >= 128 || // If we're executing inside a runtime bulk commit (fastlane), prefer the
|
|
1678
|
+
// renderer fast-path to ensure the single-commit invariant is preserved.
|
|
1679
|
+
isBulkCommitActive2()) {
|
|
1680
|
+
try {
|
|
1681
|
+
const map = applyRendererFastPath(
|
|
1682
|
+
parent,
|
|
1683
|
+
keyedVnodes,
|
|
1684
|
+
oldKeyMap,
|
|
1685
|
+
unkeyedVnodes
|
|
1686
|
+
);
|
|
1687
|
+
if (map) {
|
|
1688
|
+
try {
|
|
1689
|
+
keyedElements.set(parent, map);
|
|
1690
|
+
} catch (e) {
|
|
1691
|
+
void e;
|
|
1692
|
+
}
|
|
1693
|
+
return map;
|
|
1694
|
+
}
|
|
1695
|
+
} catch (e) {
|
|
1696
|
+
void e;
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
try {
|
|
1700
|
+
const total = keyedVnodes.length;
|
|
1701
|
+
if (total >= 10) {
|
|
1702
|
+
let matchCount = 0;
|
|
1703
|
+
try {
|
|
1704
|
+
for (let i = 0; i < total; i++) {
|
|
1705
|
+
const vnode = keyedVnodes[i].vnode;
|
|
1706
|
+
if (!vnode || typeof vnode !== "object" || typeof vnode.type !== "string")
|
|
1707
|
+
continue;
|
|
1708
|
+
const el = parent.children[i];
|
|
1709
|
+
if (!el) continue;
|
|
1710
|
+
if (el.tagName.toLowerCase() === String(vnode.type).toLowerCase())
|
|
1711
|
+
matchCount++;
|
|
1712
|
+
}
|
|
1713
|
+
} catch (e) {
|
|
1714
|
+
void e;
|
|
1715
|
+
}
|
|
1716
|
+
if (matchCount / total >= 0.9) {
|
|
1717
|
+
let hasPropChanges = false;
|
|
1718
|
+
try {
|
|
1719
|
+
for (let i = 0; i < total; i++) {
|
|
1720
|
+
const vnode = keyedVnodes[i].vnode;
|
|
1721
|
+
const el = parent.children[i];
|
|
1722
|
+
if (!el || !vnode || typeof vnode !== "object") continue;
|
|
1723
|
+
const props = vnode.props || {};
|
|
1724
|
+
for (const k of Object.keys(props)) {
|
|
1725
|
+
if (k === "children" || k === "key") continue;
|
|
1726
|
+
if (k.startsWith("on") && k.length > 2) continue;
|
|
1727
|
+
if (k.startsWith("data-")) continue;
|
|
1728
|
+
const v = props[k];
|
|
1729
|
+
try {
|
|
1730
|
+
if (k === "class" || k === "className") {
|
|
1731
|
+
if (el.className !== String(v)) {
|
|
1732
|
+
hasPropChanges = true;
|
|
1733
|
+
break;
|
|
1734
|
+
}
|
|
1735
|
+
} else if (k === "value" || k === "checked") {
|
|
1736
|
+
if (el[k] !== v) {
|
|
1737
|
+
hasPropChanges = true;
|
|
1738
|
+
break;
|
|
1739
|
+
}
|
|
1740
|
+
} else {
|
|
1741
|
+
const attr = el.getAttribute(k);
|
|
1742
|
+
if (v === void 0 || v === null || v === false) {
|
|
1743
|
+
if (attr !== null) {
|
|
1744
|
+
hasPropChanges = true;
|
|
1745
|
+
break;
|
|
1746
|
+
}
|
|
1747
|
+
} else if (String(v) !== attr) {
|
|
1748
|
+
hasPropChanges = true;
|
|
1749
|
+
break;
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
} catch (e) {
|
|
1753
|
+
hasPropChanges = true;
|
|
1754
|
+
void e;
|
|
1755
|
+
break;
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
if (hasPropChanges) break;
|
|
1759
|
+
}
|
|
1760
|
+
} catch (e) {
|
|
1761
|
+
void e;
|
|
1762
|
+
}
|
|
1763
|
+
if (hasPropChanges) {
|
|
1764
|
+
} else {
|
|
1765
|
+
try {
|
|
1766
|
+
const stats = performBulkPositionalKeyedTextUpdate(
|
|
1767
|
+
parent,
|
|
1768
|
+
keyedVnodes
|
|
1769
|
+
);
|
|
1770
|
+
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
1771
|
+
try {
|
|
1772
|
+
__ASKR_set("__LAST_FASTPATH_STATS", stats);
|
|
1773
|
+
__ASKR_set("__LAST_FASTPATH_COMMIT_COUNT", 1);
|
|
1774
|
+
__ASKR_incCounter("bulkKeyedPositionalHits");
|
|
1775
|
+
} catch (e) {
|
|
1776
|
+
void e;
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
try {
|
|
1780
|
+
const map = /* @__PURE__ */ new Map();
|
|
1781
|
+
const children = Array.from(parent.children);
|
|
1782
|
+
for (let i = 0; i < children.length; i++) {
|
|
1783
|
+
const el = children[i];
|
|
1784
|
+
const k = el.getAttribute("data-key");
|
|
1785
|
+
if (k !== null) {
|
|
1786
|
+
map.set(k, el);
|
|
1787
|
+
const n = Number(k);
|
|
1788
|
+
if (!Number.isNaN(n)) map.set(n, el);
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
keyedElements.set(parent, map);
|
|
1792
|
+
} catch (e) {
|
|
1793
|
+
void e;
|
|
1794
|
+
}
|
|
1795
|
+
return keyedElements.get(parent);
|
|
1796
|
+
} catch (e) {
|
|
1797
|
+
void e;
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
} catch (e) {
|
|
1803
|
+
void e;
|
|
1804
|
+
}
|
|
1805
|
+
} catch (e) {
|
|
1806
|
+
void e;
|
|
2499
1807
|
}
|
|
2500
|
-
const
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
1808
|
+
const finalNodes = [];
|
|
1809
|
+
const usedOldEls = /* @__PURE__ */ new WeakSet();
|
|
1810
|
+
const resolveOldElOnce = (k) => {
|
|
1811
|
+
if (!oldKeyMap) return void 0;
|
|
1812
|
+
const direct = oldKeyMap.get(k);
|
|
1813
|
+
if (direct && !usedOldEls.has(direct)) {
|
|
1814
|
+
usedOldEls.add(direct);
|
|
1815
|
+
return direct;
|
|
1816
|
+
}
|
|
1817
|
+
const s = String(k);
|
|
1818
|
+
const byString = oldKeyMap.get(s);
|
|
1819
|
+
if (byString && !usedOldEls.has(byString)) {
|
|
1820
|
+
usedOldEls.add(byString);
|
|
1821
|
+
return byString;
|
|
1822
|
+
}
|
|
1823
|
+
const n = Number(String(k));
|
|
1824
|
+
if (!Number.isNaN(n)) {
|
|
1825
|
+
const byNum = oldKeyMap.get(n);
|
|
1826
|
+
if (byNum && !usedOldEls.has(byNum)) {
|
|
1827
|
+
usedOldEls.add(byNum);
|
|
1828
|
+
return byNum;
|
|
1829
|
+
}
|
|
2508
1830
|
}
|
|
2509
|
-
|
|
2510
|
-
const
|
|
2511
|
-
|
|
2512
|
-
|
|
1831
|
+
try {
|
|
1832
|
+
const children = Array.from(parent.children);
|
|
1833
|
+
for (const ch of children) {
|
|
1834
|
+
if (usedOldEls.has(ch)) continue;
|
|
1835
|
+
const attr = ch.getAttribute("data-key");
|
|
1836
|
+
if (attr === s) {
|
|
1837
|
+
usedOldEls.add(ch);
|
|
1838
|
+
return ch;
|
|
1839
|
+
}
|
|
1840
|
+
const numAttr = Number(attr);
|
|
1841
|
+
if (!Number.isNaN(numAttr) && numAttr === k) {
|
|
1842
|
+
usedOldEls.add(ch);
|
|
1843
|
+
return ch;
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
} catch (e) {
|
|
1847
|
+
void e;
|
|
2513
1848
|
}
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
1849
|
+
return void 0;
|
|
1850
|
+
};
|
|
1851
|
+
for (let i = 0; i < newChildren.length; i++) {
|
|
1852
|
+
const child = newChildren[i];
|
|
1853
|
+
if (typeof child === "object" && child !== null && "type" in child) {
|
|
1854
|
+
const childObj = child;
|
|
1855
|
+
const rawKey = childObj.key ?? childObj.props?.key;
|
|
1856
|
+
if (rawKey !== void 0) {
|
|
1857
|
+
const key = typeof rawKey === "symbol" ? String(rawKey) : rawKey;
|
|
1858
|
+
const el = resolveOldElOnce(key);
|
|
1859
|
+
if (el && el.parentElement === parent) {
|
|
1860
|
+
updateElementFromVnode(el, child);
|
|
1861
|
+
finalNodes.push(el);
|
|
1862
|
+
newKeyMap.set(key, el);
|
|
1863
|
+
continue;
|
|
2527
1864
|
}
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
parent.replaceChild(dom, current);
|
|
1865
|
+
const dom2 = createDOMNode(child);
|
|
1866
|
+
if (dom2) {
|
|
1867
|
+
finalNodes.push(dom2);
|
|
1868
|
+
if (dom2 instanceof Element) newKeyMap.set(key, dom2);
|
|
2533
1869
|
}
|
|
1870
|
+
continue;
|
|
2534
1871
|
}
|
|
2535
|
-
}
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
1872
|
+
}
|
|
1873
|
+
try {
|
|
1874
|
+
const existing = parent.children[i];
|
|
1875
|
+
if (existing && (typeof child === "string" || typeof child === "number") && existing.nodeType === 1) {
|
|
1876
|
+
existing.textContent = String(child);
|
|
1877
|
+
finalNodes.push(existing);
|
|
1878
|
+
usedOldEls.add(existing);
|
|
1879
|
+
continue;
|
|
1880
|
+
}
|
|
1881
|
+
if (existing && typeof child === "object" && child !== null && "type" in child && (existing.getAttribute("data-key") === null || existing.getAttribute("data-key") === void 0) && typeof child.type === "string" && existing.tagName.toLowerCase() === String(child.type).toLowerCase()) {
|
|
1882
|
+
updateElementFromVnode(existing, child);
|
|
1883
|
+
finalNodes.push(existing);
|
|
1884
|
+
usedOldEls.add(existing);
|
|
1885
|
+
continue;
|
|
1886
|
+
}
|
|
1887
|
+
try {
|
|
1888
|
+
const avail = Array.from(parent.children).find(
|
|
1889
|
+
(ch) => !usedOldEls.has(ch) && ch.getAttribute("data-key") === null
|
|
1890
|
+
);
|
|
1891
|
+
if (avail) {
|
|
1892
|
+
if (typeof child === "string" || typeof child === "number") {
|
|
1893
|
+
avail.textContent = String(child);
|
|
1894
|
+
} else if (typeof child === "object" && child !== null && "type" in child && typeof child.type === "string" && avail.tagName.toLowerCase() === String(child.type).toLowerCase()) {
|
|
1895
|
+
updateElementFromVnode(avail, child);
|
|
1896
|
+
} else {
|
|
1897
|
+
const dom2 = createDOMNode(child);
|
|
1898
|
+
if (dom2) {
|
|
1899
|
+
finalNodes.push(dom2);
|
|
1900
|
+
continue;
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
usedOldEls.add(avail);
|
|
1904
|
+
finalNodes.push(avail);
|
|
1905
|
+
continue;
|
|
1906
|
+
}
|
|
1907
|
+
} catch (e) {
|
|
1908
|
+
void e;
|
|
2540
1909
|
}
|
|
1910
|
+
} catch (e) {
|
|
1911
|
+
void e;
|
|
2541
1912
|
}
|
|
1913
|
+
const dom = createDOMNode(child);
|
|
1914
|
+
if (dom) finalNodes.push(dom);
|
|
2542
1915
|
}
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
1916
|
+
if (typeof document === "undefined") return newKeyMap;
|
|
1917
|
+
const fragment = document.createDocumentFragment();
|
|
1918
|
+
for (let i = 0; i < finalNodes.length; i++)
|
|
1919
|
+
fragment.appendChild(finalNodes[i]);
|
|
1920
|
+
try {
|
|
1921
|
+
const existing = Array.from(parent.childNodes);
|
|
1922
|
+
for (const n of existing) {
|
|
1923
|
+
if (n instanceof Element) removeAllListeners(n);
|
|
1924
|
+
cleanupInstanceIfPresent(n);
|
|
1925
|
+
}
|
|
1926
|
+
} catch (e) {
|
|
1927
|
+
void e;
|
|
2547
1928
|
}
|
|
2548
|
-
|
|
2549
|
-
|
|
1929
|
+
try {
|
|
1930
|
+
__ASKR_incCounter("__DOM_REPLACE_COUNT");
|
|
1931
|
+
__ASKR_set("__LAST_DOM_REPLACE_STACK_RECONCILE", new Error().stack);
|
|
1932
|
+
} catch (e) {
|
|
1933
|
+
void e;
|
|
2550
1934
|
}
|
|
2551
|
-
|
|
2552
|
-
|
|
1935
|
+
parent.replaceChildren(fragment);
|
|
1936
|
+
keyedElements.delete(parent);
|
|
1937
|
+
return newKeyMap;
|
|
1938
|
+
}
|
|
1939
|
+
var init_reconcile = __esm({
|
|
1940
|
+
"src/renderer/reconcile.ts"() {
|
|
1941
|
+
"use strict";
|
|
1942
|
+
init_dom();
|
|
1943
|
+
init_keyed();
|
|
1944
|
+
init_cleanup();
|
|
1945
|
+
init_fastlane_shared();
|
|
1946
|
+
init_diag();
|
|
1947
|
+
init_fastpath();
|
|
2553
1948
|
}
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
1949
|
+
});
|
|
1950
|
+
|
|
1951
|
+
// src/renderer/evaluate.ts
|
|
1952
|
+
function evaluate(node, target, context) {
|
|
1953
|
+
if (!target) return;
|
|
1954
|
+
if (typeof document === "undefined") {
|
|
1955
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1956
|
+
try {
|
|
1957
|
+
console.warn("[Askr] evaluate() called in non-DOM environment; no-op.");
|
|
1958
|
+
} catch (e) {
|
|
1959
|
+
void e;
|
|
1960
|
+
}
|
|
2559
1961
|
}
|
|
2560
|
-
return
|
|
1962
|
+
return;
|
|
2561
1963
|
}
|
|
2562
|
-
if (
|
|
2563
|
-
const
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
const
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
1964
|
+
if (context && domRanges.has(context)) {
|
|
1965
|
+
const range = domRanges.get(context);
|
|
1966
|
+
let current = range.start.nextSibling;
|
|
1967
|
+
while (current && current !== range.end) {
|
|
1968
|
+
const next = current.nextSibling;
|
|
1969
|
+
current.remove();
|
|
1970
|
+
current = next;
|
|
1971
|
+
}
|
|
1972
|
+
const dom = createDOMNode(node);
|
|
1973
|
+
if (dom) {
|
|
1974
|
+
target.insertBefore(dom, range.end);
|
|
1975
|
+
}
|
|
1976
|
+
} else if (context) {
|
|
1977
|
+
const start = document.createComment("component-start");
|
|
1978
|
+
const end = document.createComment("component-end");
|
|
1979
|
+
target.appendChild(start);
|
|
1980
|
+
target.appendChild(end);
|
|
1981
|
+
domRanges.set(context, { start, end });
|
|
1982
|
+
const dom = createDOMNode(node);
|
|
1983
|
+
if (dom) {
|
|
1984
|
+
target.insertBefore(dom, end);
|
|
1985
|
+
}
|
|
1986
|
+
} else {
|
|
1987
|
+
const vnode = node;
|
|
1988
|
+
const firstChild = target.children[0];
|
|
1989
|
+
if (firstChild && _isDOMElement(vnode) && typeof vnode.type === "string" && firstChild.tagName.toLowerCase() === vnode.type.toLowerCase()) {
|
|
1990
|
+
const vnodeChildren = vnode.children || vnode.props?.children;
|
|
1991
|
+
let isSimpleTextVNode = false;
|
|
1992
|
+
let textContent;
|
|
1993
|
+
if (!Array.isArray(vnodeChildren)) {
|
|
1994
|
+
if (typeof vnodeChildren === "string" || typeof vnodeChildren === "number") {
|
|
1995
|
+
isSimpleTextVNode = true;
|
|
1996
|
+
textContent = String(vnodeChildren);
|
|
1997
|
+
}
|
|
1998
|
+
} else if (vnodeChildren.length === 1) {
|
|
1999
|
+
const child = vnodeChildren[0];
|
|
2000
|
+
if (typeof child === "string" || typeof child === "number") {
|
|
2001
|
+
isSimpleTextVNode = true;
|
|
2002
|
+
textContent = String(child);
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
if (isSimpleTextVNode && firstChild.childNodes.length === 1 && firstChild.firstChild?.nodeType === 3) {
|
|
2006
|
+
firstChild.firstChild.data = textContent;
|
|
2007
|
+
} else {
|
|
2008
|
+
if (vnodeChildren) {
|
|
2009
|
+
if (Array.isArray(vnodeChildren)) {
|
|
2010
|
+
const hasKeys = vnodeChildren.some(
|
|
2011
|
+
(child) => typeof child === "object" && child !== null && "key" in child
|
|
2012
|
+
);
|
|
2013
|
+
if (hasKeys) {
|
|
2014
|
+
let oldKeyMap = keyedElements.get(firstChild);
|
|
2015
|
+
if (!oldKeyMap) {
|
|
2016
|
+
oldKeyMap = /* @__PURE__ */ new Map();
|
|
2017
|
+
try {
|
|
2018
|
+
const children = Array.from(firstChild.children);
|
|
2019
|
+
for (let i = 0; i < children.length; i++) {
|
|
2020
|
+
const ch = children[i];
|
|
2021
|
+
const k = ch.getAttribute("data-key");
|
|
2022
|
+
if (k !== null) {
|
|
2023
|
+
oldKeyMap.set(k, ch);
|
|
2024
|
+
const n = Number(k);
|
|
2025
|
+
if (!Number.isNaN(n)) oldKeyMap.set(n, ch);
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
if (oldKeyMap.size > 0)
|
|
2029
|
+
keyedElements.set(firstChild, oldKeyMap);
|
|
2030
|
+
} catch (e) {
|
|
2031
|
+
void e;
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
try {
|
|
2035
|
+
if (process.env.ASKR_FORCE_BULK_POSREUSE === "1") {
|
|
2036
|
+
try {
|
|
2037
|
+
const keyedVnodes = [];
|
|
2038
|
+
for (let i = 0; i < vnodeChildren.length; i++) {
|
|
2039
|
+
const c = vnodeChildren[i];
|
|
2040
|
+
if (_isDOMElement(c) && c.key !== void 0) {
|
|
2041
|
+
keyedVnodes.push({
|
|
2042
|
+
key: c.key,
|
|
2043
|
+
vnode: c
|
|
2044
|
+
});
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
if (keyedVnodes.length > 0 && keyedVnodes.length === vnodeChildren.length) {
|
|
2048
|
+
if (process.env.ASKR_FASTPATH_DEBUG === "1" || process.env.ASKR_FASTPATH_DEBUG === "true") {
|
|
2049
|
+
logger.warn(
|
|
2050
|
+
"[Askr][FASTPATH] forced positional bulk keyed reuse (evaluate-level)"
|
|
2051
|
+
);
|
|
2052
|
+
}
|
|
2053
|
+
const stats = performBulkPositionalKeyedTextUpdate(
|
|
2054
|
+
firstChild,
|
|
2055
|
+
keyedVnodes
|
|
2056
|
+
);
|
|
2057
|
+
if (process.env.NODE_ENV !== "production" || process.env.ASKR_FASTPATH_DEBUG === "1") {
|
|
2058
|
+
try {
|
|
2059
|
+
__ASKR_set("__LAST_FASTPATH_STATS", stats);
|
|
2060
|
+
__ASKR_set("__LAST_FASTPATH_COMMIT_COUNT", 1);
|
|
2061
|
+
__ASKR_incCounter("bulkKeyedPositionalForced");
|
|
2062
|
+
} catch (e) {
|
|
2063
|
+
void e;
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
try {
|
|
2067
|
+
const map = /* @__PURE__ */ new Map();
|
|
2068
|
+
const children = Array.from(firstChild.children);
|
|
2069
|
+
for (let i = 0; i < children.length; i++) {
|
|
2070
|
+
const el = children[i];
|
|
2071
|
+
const k = el.getAttribute("data-key");
|
|
2072
|
+
if (k !== null) {
|
|
2073
|
+
map.set(k, el);
|
|
2074
|
+
const n = Number(k);
|
|
2075
|
+
if (!Number.isNaN(n)) map.set(n, el);
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
keyedElements.set(firstChild, map);
|
|
2079
|
+
} catch (e) {
|
|
2080
|
+
void e;
|
|
2081
|
+
}
|
|
2082
|
+
} else {
|
|
2083
|
+
const newKeyMap = reconcileKeyedChildren(
|
|
2084
|
+
firstChild,
|
|
2085
|
+
vnodeChildren,
|
|
2086
|
+
oldKeyMap
|
|
2087
|
+
);
|
|
2088
|
+
keyedElements.set(firstChild, newKeyMap);
|
|
2089
|
+
}
|
|
2090
|
+
} catch (err) {
|
|
2091
|
+
if (process.env.ASKR_FASTPATH_DEBUG === "1" || process.env.ASKR_FASTPATH_DEBUG === "true") {
|
|
2092
|
+
logger.warn(
|
|
2093
|
+
"[Askr][FASTPATH] forced bulk path failed, falling back",
|
|
2094
|
+
err
|
|
2095
|
+
);
|
|
2096
|
+
}
|
|
2097
|
+
const newKeyMap = reconcileKeyedChildren(
|
|
2098
|
+
firstChild,
|
|
2099
|
+
vnodeChildren,
|
|
2100
|
+
oldKeyMap
|
|
2101
|
+
);
|
|
2102
|
+
keyedElements.set(firstChild, newKeyMap);
|
|
2103
|
+
}
|
|
2104
|
+
} else {
|
|
2105
|
+
const newKeyMap = reconcileKeyedChildren(
|
|
2106
|
+
firstChild,
|
|
2107
|
+
vnodeChildren,
|
|
2108
|
+
oldKeyMap
|
|
2109
|
+
);
|
|
2110
|
+
keyedElements.set(firstChild, newKeyMap);
|
|
2111
|
+
}
|
|
2112
|
+
} catch (e) {
|
|
2113
|
+
void e;
|
|
2114
|
+
const newKeyMap = reconcileKeyedChildren(
|
|
2115
|
+
firstChild,
|
|
2116
|
+
vnodeChildren,
|
|
2117
|
+
oldKeyMap
|
|
2118
|
+
);
|
|
2119
|
+
keyedElements.set(firstChild, newKeyMap);
|
|
2120
|
+
}
|
|
2121
|
+
} else {
|
|
2122
|
+
if (isBulkTextFastPathEligible(firstChild, vnodeChildren)) {
|
|
2123
|
+
const stats = performBulkTextReplace(firstChild, vnodeChildren);
|
|
2124
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2584
2125
|
try {
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
});
|
|
2126
|
+
__ASKR_set("__LAST_BULK_TEXT_FASTPATH_STATS", stats);
|
|
2127
|
+
__ASKR_incCounter("bulkTextHits");
|
|
2128
|
+
} catch (e) {
|
|
2129
|
+
void e;
|
|
2590
2130
|
}
|
|
2591
|
-
}
|
|
2131
|
+
}
|
|
2132
|
+
} else {
|
|
2133
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2134
|
+
try {
|
|
2135
|
+
__ASKR_incCounter("bulkTextMisses");
|
|
2136
|
+
} catch (e) {
|
|
2137
|
+
void e;
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
updateUnkeyedChildren(firstChild, vnodeChildren);
|
|
2141
|
+
keyedElements.delete(firstChild);
|
|
2592
2142
|
}
|
|
2593
2143
|
}
|
|
2594
|
-
}
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2144
|
+
} else {
|
|
2145
|
+
firstChild.textContent = "";
|
|
2146
|
+
const dom = createDOMNode(vnodeChildren);
|
|
2147
|
+
if (dom) firstChild.appendChild(dom);
|
|
2148
|
+
keyedElements.delete(firstChild);
|
|
2598
2149
|
}
|
|
2599
|
-
elementListeners.get(el).set(eventName, {
|
|
2600
|
-
handler: wrappedHandler,
|
|
2601
|
-
original: value
|
|
2602
|
-
});
|
|
2603
|
-
} else if (key === "class" || key === "className") {
|
|
2604
|
-
el.className = String(value);
|
|
2605
|
-
} else if (key === "value" || key === "checked") {
|
|
2606
|
-
el[key] = value;
|
|
2607
|
-
el.setAttribute(key, String(value));
|
|
2608
2150
|
} else {
|
|
2609
|
-
|
|
2151
|
+
firstChild.textContent = "";
|
|
2152
|
+
keyedElements.delete(firstChild);
|
|
2610
2153
|
}
|
|
2611
2154
|
}
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2155
|
+
updateElementFromVnode(firstChild, vnode, false);
|
|
2156
|
+
} else {
|
|
2157
|
+
target.textContent = "";
|
|
2158
|
+
if (_isDOMElement(vnode) && typeof vnode.type === "string") {
|
|
2159
|
+
const children = vnode.children;
|
|
2160
|
+
if (Array.isArray(children) && children.some(
|
|
2161
|
+
(child) => typeof child === "object" && child !== null && "key" in child
|
|
2162
|
+
)) {
|
|
2163
|
+
const el = document.createElement(vnode.type);
|
|
2164
|
+
target.appendChild(el);
|
|
2165
|
+
const props = vnode.props || {};
|
|
2166
|
+
for (const [key, value] of Object.entries(props)) {
|
|
2167
|
+
if (key === "children" || key === "key") continue;
|
|
2168
|
+
if (value === void 0 || value === null || value === false)
|
|
2169
|
+
continue;
|
|
2170
|
+
if (key.startsWith("on") && key.length > 2) {
|
|
2171
|
+
const eventName = key.slice(2).charAt(0).toLowerCase() + key.slice(3).toLowerCase();
|
|
2172
|
+
const wrappedHandler = (event) => {
|
|
2173
|
+
globalScheduler.setInHandler(true);
|
|
2174
|
+
try {
|
|
2175
|
+
value(event);
|
|
2176
|
+
} catch (error) {
|
|
2177
|
+
logger.error("[Askr] Event handler error:", error);
|
|
2178
|
+
} finally {
|
|
2179
|
+
globalScheduler.setInHandler(false);
|
|
2630
2180
|
}
|
|
2181
|
+
};
|
|
2182
|
+
const options = eventName === "wheel" || eventName === "scroll" || eventName.startsWith("touch") ? { passive: true } : void 0;
|
|
2183
|
+
if (options !== void 0)
|
|
2184
|
+
el.addEventListener(eventName, wrappedHandler, options);
|
|
2185
|
+
else el.addEventListener(eventName, wrappedHandler);
|
|
2186
|
+
if (!elementListeners.has(el)) {
|
|
2187
|
+
elementListeners.set(el, /* @__PURE__ */ new Map());
|
|
2631
2188
|
}
|
|
2189
|
+
elementListeners.get(el).set(eventName, {
|
|
2190
|
+
handler: wrappedHandler,
|
|
2191
|
+
original: value,
|
|
2192
|
+
options
|
|
2193
|
+
});
|
|
2194
|
+
continue;
|
|
2632
2195
|
}
|
|
2633
|
-
if (
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2196
|
+
if (key === "class" || key === "className") {
|
|
2197
|
+
el.className = String(value);
|
|
2198
|
+
} else if (key === "value" || key === "checked") {
|
|
2199
|
+
el[key] = value;
|
|
2200
|
+
} else {
|
|
2201
|
+
el.setAttribute(key, String(value));
|
|
2639
2202
|
}
|
|
2640
2203
|
}
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
} else {
|
|
2646
|
-
const dom = createDOMNode(children);
|
|
2647
|
-
if (dom) el.appendChild(dom);
|
|
2204
|
+
const newKeyMap = reconcileKeyedChildren(el, children, void 0);
|
|
2205
|
+
keyedElements.set(el, newKeyMap);
|
|
2206
|
+
return;
|
|
2207
|
+
return;
|
|
2648
2208
|
}
|
|
2649
2209
|
}
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
const frame = node[CONTEXT_FRAME_SYMBOL];
|
|
2654
|
-
const snapshot = frame || getCurrentContextFrame();
|
|
2655
|
-
const componentFn = type;
|
|
2656
|
-
const isAsync = componentFn.constructor.name === "AsyncFunction";
|
|
2657
|
-
if (isAsync) {
|
|
2658
|
-
throw new Error(
|
|
2659
|
-
"Async components are not supported. Use resource() for async work."
|
|
2660
|
-
);
|
|
2661
|
-
}
|
|
2662
|
-
const vnodeAny = node;
|
|
2663
|
-
let childInstance = vnodeAny.__instance;
|
|
2664
|
-
if (!childInstance) {
|
|
2665
|
-
childInstance = createComponentInstance(
|
|
2666
|
-
`comp-${Math.random().toString(36).slice(2, 7)}`,
|
|
2667
|
-
componentFn,
|
|
2668
|
-
props || {},
|
|
2669
|
-
null
|
|
2670
|
-
);
|
|
2671
|
-
vnodeAny.__instance = childInstance;
|
|
2672
|
-
}
|
|
2673
|
-
if (snapshot) {
|
|
2674
|
-
childInstance.ownerFrame = snapshot;
|
|
2675
|
-
}
|
|
2676
|
-
const result = withContext(
|
|
2677
|
-
snapshot,
|
|
2678
|
-
() => renderComponentInline(childInstance)
|
|
2679
|
-
);
|
|
2680
|
-
if (result instanceof Promise) {
|
|
2681
|
-
throw new Error(
|
|
2682
|
-
"Async components are not supported. Components must return synchronously."
|
|
2683
|
-
);
|
|
2684
|
-
}
|
|
2685
|
-
const dom = withContext(snapshot, () => createDOMNode(result));
|
|
2686
|
-
if (dom instanceof Element) {
|
|
2687
|
-
mountInstanceInline(childInstance, dom);
|
|
2688
|
-
} else {
|
|
2689
|
-
const host = document.createElement("div");
|
|
2690
|
-
mountInstanceInline(childInstance, host);
|
|
2691
|
-
}
|
|
2692
|
-
return dom;
|
|
2693
|
-
}
|
|
2694
|
-
if (typeof type === "symbol" && (type === Fragment || String(type) === "Symbol(Fragment)")) {
|
|
2695
|
-
const fragment = document.createDocumentFragment();
|
|
2696
|
-
const children = props.children || node.children;
|
|
2697
|
-
if (children) {
|
|
2698
|
-
if (Array.isArray(children)) {
|
|
2699
|
-
for (let i = 0; i < children.length; i++) {
|
|
2700
|
-
const dom = createDOMNode(children[i]);
|
|
2701
|
-
if (dom) fragment.appendChild(dom);
|
|
2702
|
-
}
|
|
2703
|
-
} else {
|
|
2704
|
-
const dom = createDOMNode(children);
|
|
2705
|
-
if (dom) fragment.appendChild(dom);
|
|
2706
|
-
}
|
|
2210
|
+
const dom = createDOMNode(vnode);
|
|
2211
|
+
if (dom) {
|
|
2212
|
+
target.appendChild(dom);
|
|
2707
2213
|
}
|
|
2708
|
-
return fragment;
|
|
2709
2214
|
}
|
|
2710
2215
|
}
|
|
2711
|
-
return null;
|
|
2712
2216
|
}
|
|
2713
|
-
var domRanges
|
|
2714
|
-
var
|
|
2715
|
-
"src/renderer/
|
|
2217
|
+
var domRanges;
|
|
2218
|
+
var init_evaluate = __esm({
|
|
2219
|
+
"src/renderer/evaluate.ts"() {
|
|
2716
2220
|
"use strict";
|
|
2717
2221
|
init_scheduler();
|
|
2718
|
-
init_fastlane();
|
|
2719
2222
|
init_logger();
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2223
|
+
init_cleanup();
|
|
2224
|
+
init_keyed();
|
|
2225
|
+
init_reconcile();
|
|
2226
|
+
init_types();
|
|
2227
|
+
init_dom();
|
|
2228
|
+
init_diag();
|
|
2723
2229
|
domRanges = /* @__PURE__ */ new WeakMap();
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2230
|
+
}
|
|
2231
|
+
});
|
|
2232
|
+
|
|
2233
|
+
// src/renderer/index.ts
|
|
2234
|
+
var init_renderer = __esm({
|
|
2235
|
+
"src/renderer/index.ts"() {
|
|
2236
|
+
"use strict";
|
|
2237
|
+
init_types();
|
|
2238
|
+
init_cleanup();
|
|
2239
|
+
init_keyed();
|
|
2240
|
+
init_dom();
|
|
2241
|
+
init_evaluate();
|
|
2242
|
+
init_evaluate();
|
|
2243
|
+
init_keyed();
|
|
2727
2244
|
if (typeof globalThis !== "undefined") {
|
|
2728
2245
|
const _g = globalThis;
|
|
2729
2246
|
_g.__ASKR_RENDERER = {
|
|
@@ -2736,22 +2253,6 @@ var init_dom = __esm({
|
|
|
2736
2253
|
});
|
|
2737
2254
|
|
|
2738
2255
|
// src/runtime/component.ts
|
|
2739
|
-
var component_exports = {};
|
|
2740
|
-
__export(component_exports, {
|
|
2741
|
-
cleanupComponent: () => cleanupComponent,
|
|
2742
|
-
createComponentInstance: () => createComponentInstance,
|
|
2743
|
-
executeComponent: () => executeComponent,
|
|
2744
|
-
finalizeReadSubscriptions: () => finalizeReadSubscriptions,
|
|
2745
|
-
getCurrentComponentInstance: () => getCurrentComponentInstance,
|
|
2746
|
-
getCurrentInstance: () => getCurrentInstance,
|
|
2747
|
-
getNextStateIndex: () => getNextStateIndex,
|
|
2748
|
-
getSignal: () => getSignal,
|
|
2749
|
-
mountComponent: () => mountComponent,
|
|
2750
|
-
mountInstanceInline: () => mountInstanceInline,
|
|
2751
|
-
registerMountOperation: () => registerMountOperation,
|
|
2752
|
-
renderComponentInline: () => renderComponentInline,
|
|
2753
|
-
setCurrentComponentInstance: () => setCurrentComponentInstance
|
|
2754
|
-
});
|
|
2755
2256
|
function createComponentInstance(id, fn, props, target) {
|
|
2756
2257
|
const instance = {
|
|
2757
2258
|
id,
|
|
@@ -2777,6 +2278,7 @@ function createComponentInstance(id, fn, props, target) {
|
|
|
2777
2278
|
ownerFrame: null,
|
|
2778
2279
|
// Will be set by renderer when vnode is marked
|
|
2779
2280
|
ssr: false,
|
|
2281
|
+
cleanupStrict: false,
|
|
2780
2282
|
isRoot: false,
|
|
2781
2283
|
// Render-tracking (for precise state subscriptions)
|
|
2782
2284
|
_currentRenderToken: void 0,
|
|
@@ -2871,12 +2373,41 @@ function runComponent(instance) {
|
|
|
2871
2373
|
}
|
|
2872
2374
|
globalScheduler.enqueue(() => {
|
|
2873
2375
|
if (instance.target) {
|
|
2376
|
+
let oldChildren = [];
|
|
2874
2377
|
try {
|
|
2875
2378
|
const wasFirstMount = !instance.mounted;
|
|
2876
2379
|
const oldInstance = currentInstance;
|
|
2877
2380
|
currentInstance = instance;
|
|
2381
|
+
oldChildren = Array.from(instance.target.childNodes);
|
|
2878
2382
|
try {
|
|
2879
2383
|
evaluate(result, instance.target);
|
|
2384
|
+
} catch (e) {
|
|
2385
|
+
try {
|
|
2386
|
+
const newChildren = Array.from(instance.target.childNodes);
|
|
2387
|
+
for (const n of newChildren) {
|
|
2388
|
+
try {
|
|
2389
|
+
cleanupInstancesUnder(n);
|
|
2390
|
+
} catch (err) {
|
|
2391
|
+
logger.warn(
|
|
2392
|
+
"[Askr] error cleaning up failed commit children:",
|
|
2393
|
+
err
|
|
2394
|
+
);
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
} catch (_err) {
|
|
2398
|
+
void _err;
|
|
2399
|
+
}
|
|
2400
|
+
try {
|
|
2401
|
+
__ASKR_incCounter("__DOM_REPLACE_COUNT");
|
|
2402
|
+
__ASKR_set(
|
|
2403
|
+
"__LAST_DOM_REPLACE_STACK_COMPONENT_RESTORE",
|
|
2404
|
+
new Error().stack
|
|
2405
|
+
);
|
|
2406
|
+
} catch (e2) {
|
|
2407
|
+
void e2;
|
|
2408
|
+
}
|
|
2409
|
+
instance.target.replaceChildren(...oldChildren);
|
|
2410
|
+
throw e;
|
|
2880
2411
|
} finally {
|
|
2881
2412
|
currentInstance = oldInstance;
|
|
2882
2413
|
}
|
|
@@ -2886,7 +2417,35 @@ function runComponent(instance) {
|
|
|
2886
2417
|
executeMountOperations(instance);
|
|
2887
2418
|
}
|
|
2888
2419
|
} catch (renderError) {
|
|
2889
|
-
|
|
2420
|
+
try {
|
|
2421
|
+
const currentChildren = Array.from(instance.target.childNodes);
|
|
2422
|
+
for (const n of currentChildren) {
|
|
2423
|
+
try {
|
|
2424
|
+
cleanupInstancesUnder(n);
|
|
2425
|
+
} catch (err) {
|
|
2426
|
+
logger.warn(
|
|
2427
|
+
"[Askr] error cleaning up partial children during rollback:",
|
|
2428
|
+
err
|
|
2429
|
+
);
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
} catch (_err) {
|
|
2433
|
+
void _err;
|
|
2434
|
+
}
|
|
2435
|
+
try {
|
|
2436
|
+
try {
|
|
2437
|
+
__ASKR_incCounter("__DOM_REPLACE_COUNT");
|
|
2438
|
+
__ASKR_set(
|
|
2439
|
+
"__LAST_DOM_REPLACE_STACK_COMPONENT_ROLLBACK",
|
|
2440
|
+
new Error().stack
|
|
2441
|
+
);
|
|
2442
|
+
} catch (e) {
|
|
2443
|
+
void e;
|
|
2444
|
+
}
|
|
2445
|
+
instance.target.replaceChildren(...oldChildren);
|
|
2446
|
+
} catch {
|
|
2447
|
+
instance.target.innerHTML = domSnapshot;
|
|
2448
|
+
}
|
|
2890
2449
|
throw renderError;
|
|
2891
2450
|
}
|
|
2892
2451
|
}
|
|
@@ -2935,21 +2494,24 @@ function executeComponentSync(instance) {
|
|
|
2935
2494
|
executionFrame,
|
|
2936
2495
|
() => instance.fn(instance.props, context)
|
|
2937
2496
|
);
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
);
|
|
2944
|
-
}
|
|
2497
|
+
const renderTime = Date.now() - renderStartTime;
|
|
2498
|
+
if (renderTime > 5) {
|
|
2499
|
+
logger.warn(
|
|
2500
|
+
`[askr] Slow render detected: ${renderTime}ms. Consider optimizing component performance.`
|
|
2501
|
+
);
|
|
2945
2502
|
}
|
|
2946
2503
|
if (!instance.firstRenderComplete) {
|
|
2947
2504
|
instance.firstRenderComplete = true;
|
|
2948
2505
|
}
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2506
|
+
for (let i = 0; i < instance.stateValues.length; i++) {
|
|
2507
|
+
const state = instance.stateValues[i];
|
|
2508
|
+
if (state && !state._hasBeenRead) {
|
|
2509
|
+
try {
|
|
2510
|
+
const name = instance.fn?.name || "<anonymous>";
|
|
2511
|
+
logger.warn(
|
|
2512
|
+
`[askr] Unused state variable detected in ${name} at index ${i}. State should be read during render or removed.`
|
|
2513
|
+
);
|
|
2514
|
+
} catch {
|
|
2953
2515
|
logger.warn(
|
|
2954
2516
|
`[askr] Unused state variable detected. State should be read during render or removed.`
|
|
2955
2517
|
);
|
|
@@ -2984,13 +2546,13 @@ function finalizeReadSubscriptions(instance) {
|
|
|
2984
2546
|
if (token === void 0) return;
|
|
2985
2547
|
for (const s of oldSet) {
|
|
2986
2548
|
if (!newSet.has(s)) {
|
|
2987
|
-
const readers = s
|
|
2549
|
+
const readers = s._readers;
|
|
2988
2550
|
if (readers) readers.delete(instance);
|
|
2989
2551
|
}
|
|
2990
2552
|
}
|
|
2991
2553
|
instance.lastRenderToken = token;
|
|
2992
2554
|
for (const s of newSet) {
|
|
2993
|
-
let readers = s
|
|
2555
|
+
let readers = s._readers;
|
|
2994
2556
|
if (!readers) {
|
|
2995
2557
|
readers = /* @__PURE__ */ new Map();
|
|
2996
2558
|
s._readers = readers;
|
|
@@ -3008,13 +2570,30 @@ function mountComponent(instance) {
|
|
|
3008
2570
|
executeComponent(instance);
|
|
3009
2571
|
}
|
|
3010
2572
|
function cleanupComponent(instance) {
|
|
2573
|
+
const cleanupErrors = [];
|
|
3011
2574
|
for (const cleanup of instance.cleanupFns) {
|
|
3012
|
-
|
|
2575
|
+
try {
|
|
2576
|
+
cleanup();
|
|
2577
|
+
} catch (err) {
|
|
2578
|
+
if (instance.cleanupStrict) {
|
|
2579
|
+
cleanupErrors.push(err);
|
|
2580
|
+
} else {
|
|
2581
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2582
|
+
logger.warn("[Askr] cleanup function threw:", err);
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
3013
2586
|
}
|
|
3014
2587
|
instance.cleanupFns = [];
|
|
2588
|
+
if (cleanupErrors.length > 0) {
|
|
2589
|
+
throw new AggregateError(
|
|
2590
|
+
cleanupErrors,
|
|
2591
|
+
`Cleanup failed for component ${instance.id}`
|
|
2592
|
+
);
|
|
2593
|
+
}
|
|
3015
2594
|
if (instance._lastReadStates) {
|
|
3016
2595
|
for (const s of instance._lastReadStates) {
|
|
3017
|
-
const readers = s
|
|
2596
|
+
const readers = s._readers;
|
|
3018
2597
|
if (readers) readers.delete(instance);
|
|
3019
2598
|
}
|
|
3020
2599
|
instance._lastReadStates = /* @__PURE__ */ new Set();
|
|
@@ -3025,11 +2604,12 @@ var currentInstance, stateIndex, _globalRenderCounter;
|
|
|
3025
2604
|
var init_component = __esm({
|
|
3026
2605
|
"src/runtime/component.ts"() {
|
|
3027
2606
|
"use strict";
|
|
3028
|
-
init_dom();
|
|
3029
2607
|
init_scheduler();
|
|
3030
2608
|
init_context();
|
|
3031
2609
|
init_logger();
|
|
3032
|
-
|
|
2610
|
+
init_diag();
|
|
2611
|
+
init_fastlane_shared();
|
|
2612
|
+
init_renderer();
|
|
3033
2613
|
currentInstance = null;
|
|
3034
2614
|
stateIndex = 0;
|
|
3035
2615
|
_globalRenderCounter = 0;
|
|
@@ -3253,7 +2833,7 @@ function route(path, handler, namespace) {
|
|
|
3253
2833
|
}
|
|
3254
2834
|
if (registrationLocked) {
|
|
3255
2835
|
throw new Error(
|
|
3256
|
-
"Route registration is locked after app startup. Register routes at module load time before calling
|
|
2836
|
+
"Route registration is locked after app startup. Register routes at module load time before calling createIsland()."
|
|
3257
2837
|
);
|
|
3258
2838
|
}
|
|
3259
2839
|
if (typeof handler !== "function") {
|
|
@@ -3407,18 +2987,19 @@ export {
|
|
|
3407
2987
|
globalScheduler,
|
|
3408
2988
|
scheduleEventHandler,
|
|
3409
2989
|
init_scheduler,
|
|
3410
|
-
isBulkCommitActive2 as isBulkCommitActive,
|
|
3411
|
-
init_fastlane,
|
|
3412
2990
|
withAsyncResourceContext,
|
|
3413
2991
|
defineContext,
|
|
3414
2992
|
readContext,
|
|
3415
2993
|
getCurrentContextFrame,
|
|
3416
2994
|
init_context,
|
|
2995
|
+
isBulkCommitActive2 as isBulkCommitActive,
|
|
2996
|
+
init_fastlane_shared,
|
|
3417
2997
|
removeAllListeners,
|
|
3418
|
-
|
|
2998
|
+
init_renderer,
|
|
3419
2999
|
createComponentInstance,
|
|
3420
3000
|
getCurrentComponentInstance,
|
|
3421
3001
|
setCurrentComponentInstance,
|
|
3002
|
+
registerMountOperation,
|
|
3422
3003
|
getCurrentInstance,
|
|
3423
3004
|
getSignal,
|
|
3424
3005
|
getNextStateIndex,
|
|
@@ -3439,4 +3020,4 @@ export {
|
|
|
3439
3020
|
resolveRoute,
|
|
3440
3021
|
route_exports
|
|
3441
3022
|
};
|
|
3442
|
-
//# sourceMappingURL=chunk-
|
|
3023
|
+
//# sourceMappingURL=chunk-MIPES65F.js.map
|