@vidact/runtime 0.2.0-beta.7 → 0.2.0-beta.9

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.
@@ -1,11 +1,12 @@
1
- import { currentIntrinsicNamespace, withIntrinsicNamespace } from "../dom/intrinsic.js";
2
1
  import { HydrationMismatch, beginHydration, borrowHydrationSlotRange, claimHydrationArrayRange, claimHydrationComponentMount, claimHydrationComponentRange, claimHydrationNode, claimHydrationSlotRange, claimHydrationSuspenseFallback, claimHydrationText, claimHydrationTextRange, finishHydration, finishHydrationArrayRange, hydrationCursor, hydrationFragmentChildren, hydrationInsertionPoint, hydrationRangeParent, hydrationRootMarkers, isHydrating, isHydrationMismatch, noteHydrationStructuralParent, skipHydrationRange, withHydrationComponentRange, withHydrationCursor, withHydrationInsertion, withoutHydration } from "../hydration-bridge.js";
2
+ import { COMPILED_DELEGATED_EVENT_INVOKE, retainCompiledEventRoot } from "../dom/events.js";
3
+ import { currentIntrinsicNamespace, withIntrinsicNamespace } from "../dom/intrinsic.js";
3
4
  import { createKeyedList } from "../keyed-list.js";
4
5
  import { createIndexedList } from "../indexed-list.js";
5
6
  import { RENDERABLE, canReconcileRenderable, isRenderableProtocol, materializeRenderable, materializeRenderableWithInput, renderableIdentity, renderablePropsSnapshot } from "../renderable-protocol.js";
6
7
  import { scheduleDeferredTask, scheduleTask } from "../scheduler.js";
7
8
  import { forEachSource, intersectsSources, isEmptySources, unionSources } from "../source-mask.js";
8
- import { createStateSlot } from "../state-slot.js";
9
+ import { createReadOnlyStateSlot, createStateSlot, replaceReadOnlyStateSlot } from "../state-slot.js";
9
10
  import { BINDING, COMPONENT_SPREAD_SOURCE as COMPONENT_SPREAD_SOURCE$1, CONTEXT, STRUCTURAL } from "./types.js";
10
11
  import { isSuspension, subscribeResource, useAsync } from "./async-resource.js";
11
12
  import { hasInvalidChild } from "./validation.js";
@@ -17,7 +18,12 @@ let retainedUiEnabled = typeof __VIDACT_RETAINED_UI__ !== "undefined" && __VIDAC
17
18
  let profilingEnabled = false;
18
19
  let activeOwnerCount = 0;
19
20
  let createdOwnerCount = 0;
21
+ let createdUpdaterCount = 0;
22
+ let createdSchedulerPlanCount = 0;
20
23
  const noop = () => {};
24
+ const COMPILED_EVENT_HANDLER = Symbol("vidact.compiled-event");
25
+ const COMPILED_INLINE_EVENT_OWNER = Symbol("vidact.compiled-event.owner");
26
+ const UNSET_BINDING = Symbol(DEV ? "Vidact.UnsetBinding" : void 0);
21
27
  const wideSourceOperations = [
22
28
  isEmptySources,
23
29
  intersectsSources,
@@ -34,9 +40,18 @@ function deferred(render) {
34
40
  return [
35
41
  STRUCTURAL,
36
42
  (parent, before) => {
37
- const hydrated = claimHydrationSlotRange(parent);
38
- if (hydrated === void 0) insertValue(parent, render(), before);
39
- else insertValue(parent, render(), hydrated[1]);
43
+ const value = render();
44
+ if (ownedStructuralBinding(value)?.[2] === "slot") {
45
+ insertValue(parent, value, before);
46
+ return;
47
+ }
48
+ const hydrated = borrowHydrationSlotRange(parent, true);
49
+ if (hydrated === void 0) {
50
+ insertValue(parent, value, before);
51
+ return;
52
+ }
53
+ claimHydrationSlotRange(parent);
54
+ insertValue(parent, value, hydrated[1]);
40
55
  },
41
56
  "slot"
42
57
  ];
@@ -243,7 +258,7 @@ function recordCompiledDebugValue(valueInput, format) {
243
258
  const remove = subscribeBinding(valueInput, () => {
244
259
  frame.values[index] = read();
245
260
  });
246
- owner[1].add(remove);
261
+ owner[1].push(remove);
247
262
  }
248
263
  }
249
264
  /** @internal */
@@ -505,6 +520,7 @@ function createPortalStructural(children, container) {
505
520
  const fragment = document.createDocumentFragment();
506
521
  fragment.append(start, end);
507
522
  const portalOwner = withRootIdentity(rootIdentity, () => withContextFrame(context, createOwner));
523
+ let releaseEventRoot;
508
524
  try {
509
525
  withOwner(portalOwner, () => insertValue(fragment, children, end));
510
526
  } catch (error) {
@@ -513,11 +529,14 @@ function createPortalStructural(children, container) {
513
529
  throw error;
514
530
  }
515
531
  const rollback = () => {
532
+ releaseEventRoot?.();
533
+ releaseEventRoot = void 0;
516
534
  removeBetween(start, end);
517
535
  start.remove();
518
536
  end.remove();
519
537
  };
520
538
  const publication = [() => {
539
+ releaseEventRoot = retainCompiledEventRoot(container);
521
540
  container.insertBefore(fragment, null);
522
541
  try {
523
542
  commitRangeRefs(start, end);
@@ -573,12 +592,151 @@ const componentCommitOwners = /* @__PURE__ */ new WeakMap();
573
592
  const pendingInsertionCommits = /* @__PURE__ */ new WeakMap();
574
593
  const pendingOwnerCommits = /* @__PURE__ */ new WeakMap();
575
594
  const pendingRootPortals = /* @__PURE__ */ new WeakMap();
595
+ let pendingRefCount = 0;
596
+ let pendingInsertionOwnerCount = 0;
597
+ let pendingOwnerCommitCount = 0;
598
+ let visitedPublishedNodeCount = 0;
599
+ function setPendingRef(element, pending) {
600
+ if (!pendingRefs.has(element)) pendingRefCount += 1;
601
+ pendingRefs.set(element, pending);
602
+ }
603
+ function deletePendingRef(element, expected) {
604
+ if (expected !== void 0 && pendingRefs.get(element) !== expected) return false;
605
+ if (!pendingRefs.delete(element)) return false;
606
+ pendingRefCount -= 1;
607
+ return true;
608
+ }
576
609
  function createCompiledScope() {
577
610
  return createScope(wideSourceOperations);
578
611
  }
579
612
  function createNarrowCompiledScope() {
580
613
  return createScope(narrowSourceOperations);
581
614
  }
615
+ /** Compiler-emitted map callbacks only need a compact, narrow row scheduler. */
616
+ var CompilerKeyedScope = class {
617
+ owner = createOwner();
618
+ updaters = [];
619
+ pending = 0;
620
+ batchDepth = 0;
621
+ flushing = false;
622
+ hasWriter = false;
623
+ cachedUpdaterOrder;
624
+ [1](sources) {
625
+ if (this.owner[0]) return;
626
+ if (sources === void 0) {
627
+ this.flush();
628
+ return;
629
+ }
630
+ if (narrowSourceOperations[0](sources)) return;
631
+ const wasIdle = narrowSourceOperations[0](this.pending);
632
+ this.pending = narrowSourceOperations[2](this.pending, sources);
633
+ if (wasIdle && this.batchDepth === 0) this.schedule();
634
+ }
635
+ [3]() {
636
+ if (this.owner[0]) return;
637
+ try {
638
+ disposeOwner(this.owner);
639
+ } finally {
640
+ this.pending = 0;
641
+ for (const updater of this.updaters) if (updater !== void 0) updater[3] = false;
642
+ this.updaters.length = 0;
643
+ this.cachedUpdaterOrder = void 0;
644
+ }
645
+ }
646
+ constructor() {
647
+ const scope = this;
648
+ scopeOwners.set(scope, this.owner);
649
+ scopeNamespaces.set(scope, currentIntrinsicNamespace());
650
+ activeScopeCollector?.add(scope);
651
+ if (activeScopeCollector !== null) activeConstructionOwner = this.owner;
652
+ }
653
+ [0](reads, run, writes) {
654
+ if (this.owner[0]) throw new Error(DEV ? "cannot add an updater to a disposed scope" : "V002");
655
+ const errorOwner = activeOwner ?? this.owner;
656
+ const entry = [
657
+ reads,
658
+ writes,
659
+ run,
660
+ true,
661
+ errorOwner,
662
+ activeContextFrame ?? errorOwner[2]
663
+ ];
664
+ if (DEV) createdUpdaterCount += 1;
665
+ const index = this.updaters.length;
666
+ this.updaters.push(entry);
667
+ this.hasWriter ||= writes !== void 0;
668
+ this.cachedUpdaterOrder = void 0;
669
+ if (activeOwner === this.owner) return noop;
670
+ const remove = () => {
671
+ if (this.updaters[index] !== entry) return;
672
+ entry[3] = false;
673
+ this.updaters[index] = void 0;
674
+ this.cachedUpdaterOrder = void 0;
675
+ };
676
+ activeOwner?.[1].push(remove);
677
+ return remove;
678
+ }
679
+ [2](operation) {
680
+ this.batchDepth += 1;
681
+ transactionDepth += 1;
682
+ try {
683
+ return operation();
684
+ } finally {
685
+ this.batchDepth -= 1;
686
+ if (this.batchDepth === 0 && !narrowSourceOperations[0](this.pending)) this.schedule();
687
+ transactionDepth -= 1;
688
+ if (transactionDepth === 0) drainFlushes();
689
+ }
690
+ }
691
+ schedule() {
692
+ if (retainedUiEnabled) scheduleOwnerFlush(this.owner, this);
693
+ else scheduleFlush(this);
694
+ }
695
+ flush() {
696
+ if (this.flushing || narrowSourceOperations[0](this.pending)) return;
697
+ const operation = () => {
698
+ this.flushing = true;
699
+ try {
700
+ let pass = 0;
701
+ while (!narrowSourceOperations[0](this.pending)) {
702
+ pass += 1;
703
+ if (pass > MAX_FLUSH_PASSES) {
704
+ this.pending = 0;
705
+ throw new Error(DEV ? "Vidact compiled scope did not stabilize" : "V001");
706
+ }
707
+ let active = this.pending;
708
+ this.pending = 0;
709
+ const order = this.hasWriter ? this.cachedUpdaterOrder ??= topologicalUpdaterOrder(this.updaters, narrowSourceOperations) : void 0;
710
+ const count = order?.length ?? this.updaters.length;
711
+ for (let position = 0; position < count; position += 1) {
712
+ const index = order?.[position] ?? position;
713
+ const updater = this.updaters[index];
714
+ if (updater === void 0 || !updater[3] || !narrowSourceOperations[1](active, updater[0])) continue;
715
+ try {
716
+ const invoke = () => withOwner(updater[4], () => withContextFrame(updater[5], () => withScopeNamespace(this, () => updater[2](active))));
717
+ if (profilingEnabled) measureProfileWork(this.owner, "updater", invoke);
718
+ else invoke();
719
+ } catch (error) {
720
+ if (!routeOwnerError(updater[4], error)) {
721
+ failedOwner = updater[4];
722
+ throw error;
723
+ }
724
+ }
725
+ if (updater[1] !== void 0) active = narrowSourceOperations[2](active, updater[1]);
726
+ }
727
+ }
728
+ } finally {
729
+ this.flushing = false;
730
+ }
731
+ if (retainedUiEnabled) notifyRetainedFlush(this.owner[5] ?? null);
732
+ };
733
+ if (profilingEnabled) measureProfileWork(this.owner, "scheduler", operation, true);
734
+ else operation();
735
+ }
736
+ };
737
+ function createCompilerKeyedScope() {
738
+ return new CompilerKeyedScope();
739
+ }
582
740
  function runCompiledTransaction(operation) {
583
741
  transactionDepth += 1;
584
742
  try {
@@ -592,19 +750,20 @@ function createScope(operations) {
592
750
  const namespace = currentIntrinsicNamespace();
593
751
  const owner = createOwner();
594
752
  const updaters = [];
595
- const freeUpdaterIndexes = [];
596
- const addedDuringFlush = /* @__PURE__ */ new Set();
753
+ let freeUpdaterIndexes;
754
+ let addedDuringFlush;
597
755
  let batchDepth = 0;
598
756
  let flushing = false;
599
757
  let pending = 0;
600
758
  let cachedUpdaterOrder;
759
+ let hasWriter = false;
601
760
  const flush = () => {
602
761
  if (owner[0] || flushing) return;
603
762
  const operation = () => {
604
763
  flushing = true;
605
764
  try {
606
765
  let pass = 0;
607
- const updaterOrder = cachedUpdaterOrder ??= topologicalUpdaterOrder(updaters, operations);
766
+ const updaterOrder = hasWriter ? cachedUpdaterOrder ??= topologicalUpdaterOrder(updaters, operations) : void 0;
608
767
  while (!operations[0](pending)) {
609
768
  pass += 1;
610
769
  if (pass > MAX_FLUSH_PASSES) {
@@ -613,17 +772,19 @@ function createScope(operations) {
613
772
  }
614
773
  let active = pending;
615
774
  pending = 0;
616
- for (const index of updaterOrder) {
775
+ const updaterCount = updaterOrder?.length ?? updaters.length;
776
+ for (let position = 0; position < updaterCount; position += 1) {
777
+ const index = updaterOrder?.[position] ?? position;
617
778
  const updater = updaters[index];
618
- if (updater === void 0 || addedDuringFlush.has(updater) || !updater[3] || !operations[1](active, updater[0])) continue;
779
+ if (updater === void 0 || addedDuringFlush?.has(updater) || !updater[3] || !operations[1](active, updater[0])) continue;
619
780
  if (profilingEnabled) measureProfileWork(owner, "updater", () => updater[2](active));
620
781
  else updater[2](active);
621
782
  if (updater[1] !== void 0) active = operations[2](active, updater[1]);
622
783
  }
623
- addedDuringFlush.clear();
784
+ addedDuringFlush?.clear();
624
785
  }
625
786
  } finally {
626
- addedDuringFlush.clear();
787
+ addedDuringFlush?.clear();
627
788
  flushing = false;
628
789
  }
629
790
  if (retainedUiEnabled) notifyRetainedFlush(owner[5] ?? null);
@@ -651,24 +812,27 @@ function createScope(operations) {
651
812
  },
652
813
  true
653
814
  ];
654
- const index = freeUpdaterIndexes.pop() ?? updaters.length;
815
+ if (DEV) createdUpdaterCount += 1;
816
+ const index = freeUpdaterIndexes?.pop() ?? updaters.length;
655
817
  updaters[index] = entry;
818
+ hasWriter ||= writes !== void 0;
656
819
  cachedUpdaterOrder = void 0;
657
- if (flushing) addedDuringFlush.add(entry);
820
+ if (flushing) (addedDuringFlush ??= /* @__PURE__ */ new Set()).add(entry);
658
821
  const remove = () => {
659
822
  if (updaters[index] !== entry) return;
660
823
  entry[3] = false;
661
824
  updaters[index] = void 0;
662
825
  cachedUpdaterOrder = void 0;
663
- freeUpdaterIndexes.push(index);
826
+ (freeUpdaterIndexes ??= []).push(index);
664
827
  };
665
- if (activeOwner !== null && activeOwner !== owner) activeOwner[1].add(remove);
828
+ if (activeOwner !== null && activeOwner !== owner) activeOwner[1].push(remove);
666
829
  return remove;
667
830
  },
668
831
  (sources) => {
669
832
  if (owner[0] || operations[0](sources)) return;
833
+ const wasIdle = operations[0](pending);
670
834
  pending = operations[2](pending, sources);
671
- if (batchDepth === 0) {
835
+ if (wasIdle && batchDepth === 0) {
672
836
  if (retainedUiEnabled) scheduleOwnerFlush(owner, flush);
673
837
  else scheduleFlush(flush);
674
838
  }
@@ -696,8 +860,9 @@ function createScope(operations) {
696
860
  pending = 0;
697
861
  for (const updater of updaters) if (updater !== void 0) updater[3] = false;
698
862
  updaters.length = 0;
699
- freeUpdaterIndexes.length = 0;
700
- addedDuringFlush.clear();
863
+ hasWriter = false;
864
+ if (freeUpdaterIndexes !== void 0) freeUpdaterIndexes.length = 0;
865
+ addedDuringFlush?.clear();
701
866
  }
702
867
  }
703
868
  ];
@@ -708,7 +873,16 @@ function createScope(operations) {
708
873
  return scope;
709
874
  }
710
875
  function topologicalUpdaterOrder(updaters, operations) {
711
- const activeIndexes = updaters.flatMap((updater, index) => updater === void 0 || !updater[3] ? [] : [index]);
876
+ if (DEV) createdSchedulerPlanCount += 1;
877
+ const activeIndexes = [];
878
+ let hasWriter = false;
879
+ for (let index = 0; index < updaters.length; index += 1) {
880
+ const updater = updaters[index];
881
+ if (updater === void 0 || !updater[3]) continue;
882
+ activeIndexes.push(index);
883
+ if (updater[1] !== void 0) hasWriter = true;
884
+ }
885
+ if (!hasWriter) return activeIndexes;
712
886
  const readersBySource = /* @__PURE__ */ new Map();
713
887
  for (const readerIndex of activeIndexes) operations[3](updaters[readerIndex][0], (sourceIndex) => {
714
888
  const readers = readersBySource.get(sourceIndex);
@@ -808,7 +982,7 @@ function createCompiledMemo(scope, reads, writes, evaluate, readDependencies) {
808
982
  removeUpdater();
809
983
  throw new Error(DEV ? "createCompiledMemo received an unknown scope" : "V003");
810
984
  }
811
- owner[1].add(removeUpdater);
985
+ owner[1].push(removeUpdater);
812
986
  return slot;
813
987
  }
814
988
  function createContext(defaultValue) {
@@ -889,7 +1063,7 @@ function createCompiledExternalStore(scope, sourceMask, storeSubscribe, getSnaps
889
1063
  removeStoreUpdater();
890
1064
  throw error;
891
1065
  }
892
- owner[1].add(() => {
1066
+ owner[1].push(() => {
893
1067
  removeStoreUpdater();
894
1068
  deactivateStore();
895
1069
  });
@@ -902,7 +1076,7 @@ function createCompiledExternalStore(scope, sourceMask, storeSubscribe, getSnaps
902
1076
  disposeResource();
903
1077
  throw error;
904
1078
  }
905
- owner[1].add(() => {
1079
+ owner[1].push(() => {
906
1080
  removeStoreUpdater();
907
1081
  disposeResource();
908
1082
  });
@@ -961,26 +1135,59 @@ function useMemo(factory, _dependencies) {
961
1135
  function useCallback(callback, _dependencies) {
962
1136
  return callback;
963
1137
  }
1138
+ const ownedBlockFacades = /* @__PURE__ */ new WeakMap();
1139
+ const ownedFacadeBlocks = /* @__PURE__ */ new WeakMap();
1140
+ function ownedStructuralBinding(value) {
1141
+ if (isStructuralBinding(value)) return value;
1142
+ return isRenderableProtocol(value) ? ownedFacadeBlocks.get(value) : void 0;
1143
+ }
1144
+ /**
1145
+ * Owned blocks are arrays internally, which user-level data flow must never
1146
+ * observe: dependency code inspects children with `Array.isArray` and spreads
1147
+ * them. Prop reads wrap a block in a stable renderable facade that
1148
+ * materializes back to the block when rendered.
1149
+ */
1150
+ function sanitizeCompiledPropValue(value) {
1151
+ if (!isStructuralBinding(value)) return value;
1152
+ let facade = ownedBlockFacades.get(value);
1153
+ if (facade === void 0) {
1154
+ const capability = { props: {} };
1155
+ Object.defineProperty(capability, RENDERABLE, {
1156
+ configurable: false,
1157
+ enumerable: false,
1158
+ value: {
1159
+ identity: value,
1160
+ input: {},
1161
+ reconcile: false,
1162
+ construct: () => value
1163
+ }
1164
+ });
1165
+ facade = capability;
1166
+ ownedBlockFacades.set(value, facade);
1167
+ ownedFacadeBlocks.set(facade, value);
1168
+ }
1169
+ return facade;
1170
+ }
964
1171
  function createCompiledProp(scope, sourceMask, input, fallback) {
965
1172
  const assertWritable = stateWriteGuard(scope);
966
1173
  const upstream = isCompiledBinding(input) ? input : void 0;
967
1174
  const read = () => {
968
1175
  const value = upstream === void 0 ? input : upstream[1]();
969
- return value === void 0 && fallback !== void 0 ? fallback() : value;
1176
+ return sanitizeCompiledPropValue(value === void 0 && fallback !== void 0 ? fallback() : value);
970
1177
  };
971
1178
  const slot = createStateSlot(scope[1], sourceMask, read(), assertWritable);
972
1179
  if (upstream !== void 0) {
973
1180
  const remove = subscribeBinding(upstream, () => slot.replace(read()));
974
1181
  const owner = scopeOwners.get(scope);
975
1182
  if (owner === void 0) throw new Error(DEV ? "createCompiledProp received an unknown scope" : "V003");
976
- owner[1].add(remove);
1183
+ owner[1].push(remove);
977
1184
  }
978
1185
  return slot;
979
1186
  }
980
1187
  function createCompiledRestProp(scope, sourceMask, input, excludedNames) {
981
1188
  const excluded = new Set(excludedNames);
982
1189
  const entries = () => Object.entries(input).filter(([name]) => !excluded.has(name));
983
- const read = () => Object.fromEntries(entries().map(([name, value]) => [name, isCompiledBinding(value) ? value[1]() : value]));
1190
+ const read = () => Object.fromEntries(entries().map(([name, value]) => [name, sanitizeCompiledPropValue(isCompiledBinding(value) ? value[1]() : value)]));
984
1191
  const slot = createStateSlot(scope[1], sourceMask, read(), stateWriteGuard(scope));
985
1192
  const publish = () => {
986
1193
  const previous = slot.get();
@@ -995,7 +1202,7 @@ function createCompiledRestProp(scope, sourceMask, input, excludedNames) {
995
1202
  const removers = [...upstreams].map((upstream) => subscribeBinding(upstream, publish));
996
1203
  const owner = scopeOwners.get(scope);
997
1204
  if (owner === void 0) throw new Error(DEV ? "createCompiledRestProp received an unknown scope" : "V003");
998
- owner[1].add(() => {
1205
+ owner[1].push(() => {
999
1206
  for (const remove of removers) remove();
1000
1207
  });
1001
1208
  return slot;
@@ -1036,11 +1243,34 @@ function compiledEvent(scope, handler) {
1036
1243
  const owner = scopeOwners.get(scope);
1037
1244
  if (owner === void 0) throw new Error(DEV ? "compiledEvent received an unknown scope" : "V003");
1038
1245
  const errorOwner = activeOwner ?? owner;
1039
- return (...arguments_) => runOwnerTask(errorOwner, () => withOwner(errorOwner, () => scope[2](() => {
1040
- const current = isCompiledBinding(handler) ? handler[1]() : handler;
1041
- if (typeof current !== "function") return;
1042
- return current(...arguments_);
1043
- })));
1246
+ const listener = (...arguments_) => {
1247
+ if (errorOwner[0]) return;
1248
+ return runOwnerTask(errorOwner, () => withOwner(errorOwner, () => scope[2](() => {
1249
+ const current = isCompiledBinding(handler) ? handler[1]() : handler;
1250
+ if (typeof current !== "function") return;
1251
+ return current(...arguments_);
1252
+ })));
1253
+ };
1254
+ listener[COMPILED_EVENT_HANDLER] = true;
1255
+ return listener;
1256
+ }
1257
+ function compiledInlineEvent(scope, handler) {
1258
+ const owner = scopeOwners.get(scope);
1259
+ if (owner === void 0) throw new Error(DEV ? "compiledInlineEvent received an unknown scope" : "V003");
1260
+ const listener = handler;
1261
+ listener[COMPILED_INLINE_EVENT_OWNER] = activeOwner ?? owner;
1262
+ listener[COMPILED_DELEGATED_EVENT_INVOKE] = invokeCompiledInlineEvent;
1263
+ return listener;
1264
+ }
1265
+ function invokeCompiledInlineEvent(...arguments_) {
1266
+ const owner = this[COMPILED_INLINE_EVENT_OWNER];
1267
+ if (owner[0]) return;
1268
+ return runOwnerTask(owner, () => withOwner(owner, () => runCompiledTransaction(() => this(...arguments_))));
1269
+ }
1270
+ function isCompiledEventHandler(value) {
1271
+ if (typeof value !== "function") return false;
1272
+ const handler = value;
1273
+ return handler[COMPILED_EVENT_HANDLER] === true || typeof handler[COMPILED_DELEGATED_EVENT_INVOKE] === "function";
1044
1274
  }
1045
1275
  function captureCompiledTask(scope) {
1046
1276
  const owner = scope === void 0 ? activeOwner : scopeOwners.get(scope);
@@ -1102,7 +1332,12 @@ function when(scope, reads, condition, render, additionalScope, additionalReads)
1102
1332
  }
1103
1333
  function choose(scope, reads, mode, select, consequent, alternate, additionalScope, additionalReads) {
1104
1334
  return structural(scope, (parent, before) => {
1105
- const [start, end, hydrated] = structuralRange(parent, before, "choice");
1335
+ const range = structuralRange(parent, before, "choice", true, true);
1336
+ const markerlessHydration = range === void 0;
1337
+ const start = range?.[0] ?? document.createComment(DEV ? "vidact:choice" : "");
1338
+ const end = range?.[1] ?? document.createComment(DEV ? "/vidact:choice" : "");
1339
+ const hydrated = range?.[2] ?? true;
1340
+ const ownsMarkers = range?.[3] ?? true;
1106
1341
  let selected = -1;
1107
1342
  let branchOwner = null;
1108
1343
  let branchNodes = [];
@@ -1110,10 +1345,20 @@ function choose(scope, reads, mode, select, consequent, alternate, additionalSco
1110
1345
  const value = select();
1111
1346
  const next = mode === "not-nullish" ? value === null || value === void 0 ? 1 : 0 : value ? 0 : 1;
1112
1347
  if (next === selected) return;
1113
- const currentParent = rangeParent(start, end, "choice block");
1114
1348
  const nextOwner = createOwner();
1115
- const [fragment, nodes] = hydrated && selected === -1 ? withHydrationInsertion(currentParent, end, () => stageRender(next === 0 ? consequent : alternate, nextOwner)) : stageRender(next === 0 ? consequent : alternate, nextOwner);
1116
- currentParent.insertBefore(fragment, end);
1349
+ const render = next === 0 ? consequent : alternate;
1350
+ let nodes;
1351
+ if (markerlessHydration && selected === -1) {
1352
+ const [first, after, hydratedNodes] = stageMarkerlessHydrationRender(parent, before, render, nextOwner);
1353
+ parent.insertBefore(start, first);
1354
+ parent.insertBefore(end, after);
1355
+ nodes = hydratedNodes;
1356
+ } else {
1357
+ const currentParent = rangeParent(start, end, "choice block");
1358
+ const [fragment, stagedNodes] = hydrated && selected === -1 ? withHydrationInsertion(currentParent, end, () => stageRender(render, nextOwner)) : stageRender(render, nextOwner);
1359
+ currentParent.insertBefore(fragment, end);
1360
+ nodes = stagedNodes;
1361
+ }
1117
1362
  try {
1118
1363
  commitPublishedNodes(nodes);
1119
1364
  } catch (error) {
@@ -1139,8 +1384,10 @@ function choose(scope, reads, mode, select, consequent, alternate, additionalSco
1139
1384
  try {
1140
1385
  disposePublished(branchOwner, branchNodes);
1141
1386
  } finally {
1142
- start.remove();
1143
- end.remove();
1387
+ if (ownsMarkers) {
1388
+ start.remove();
1389
+ end.remove();
1390
+ }
1144
1391
  }
1145
1392
  });
1146
1393
  }, "slot");
@@ -1193,33 +1440,43 @@ function dispatch(scope, reads, type, key, render, additionalScope, additionalRe
1193
1440
  });
1194
1441
  }, "slot");
1195
1442
  }
1196
- function keyed(scope, reads, values, key, render, additionalScope, additionalReads) {
1443
+ function keyed(scope, reads, values, key, render, trackIndexOrAdditionalScope, additionalScopeOrReads, additionalReads) {
1444
+ const compilerManaged = typeof trackIndexOrAdditionalScope === "boolean";
1445
+ const trackIndex = typeof trackIndexOrAdditionalScope === "boolean" ? trackIndexOrAdditionalScope : true;
1446
+ const additionalScope = typeof trackIndexOrAdditionalScope === "boolean" ? additionalScopeOrReads : trackIndexOrAdditionalScope;
1447
+ const resolvedAdditionalReads = typeof trackIndexOrAdditionalScope === "boolean" ? additionalReads : additionalScopeOrReads;
1197
1448
  return structural(scope, (parent, before) => {
1198
1449
  const itemSource = 1;
1199
1450
  const indexSource = 2;
1200
1451
  const list = createKeyedList(parent, {
1201
1452
  key,
1202
1453
  render(value, index) {
1203
- const owner = createOwner();
1204
- const itemScope = createNarrowCompiledScope();
1205
- const valueSlot = createCompiledState(itemScope, itemSource, value);
1206
- const indexSlot = createCompiledState(itemScope, indexSource, index);
1454
+ const itemScope = compilerManaged ? createCompilerKeyedScope() : createNarrowCompiledScope();
1455
+ const owner = scopeOwners.get(itemScope);
1456
+ const valueSlot = compilerManaged ? createReadOnlyStateSlot(itemScope, itemSource, value) : createCompiledState(itemScope, itemSource, value);
1457
+ const indexSlot = trackIndex ? compilerManaged ? createReadOnlyStateSlot(itemScope, indexSource, index) : createCompiledState(itemScope, indexSource, index) : void 0;
1207
1458
  try {
1208
1459
  return [
1209
1460
  withOwner(owner, () => {
1210
- onCleanup(itemScope[3]);
1211
- return materialize(render(valueSlot, indexSlot, itemScope));
1461
+ const rendered = render(valueSlot, indexSlot, itemScope);
1462
+ return !isHydrating() && rendered instanceof Node && !(rendered instanceof DocumentFragment) ? [rendered] : materialize(rendered);
1212
1463
  }),
1213
1464
  (nextValue, nextIndex) => {
1465
+ if (Object.is(valueSlot.get(), nextValue) && (!trackIndex || indexSlot.get() === nextIndex)) return;
1214
1466
  itemScope[2](() => {
1215
- valueSlot.set(nextValue);
1216
- indexSlot.set(nextIndex);
1467
+ if (compilerManaged) {
1468
+ replaceReadOnlyStateSlot(valueSlot, nextValue);
1469
+ if (indexSlot !== void 0) replaceReadOnlyStateSlot(indexSlot, nextIndex);
1470
+ } else {
1471
+ valueSlot.set(nextValue);
1472
+ indexSlot?.set(nextIndex);
1473
+ }
1217
1474
  });
1218
1475
  },
1219
- () => disposeOwner(owner)
1476
+ itemScope
1220
1477
  ];
1221
1478
  } catch (error) {
1222
- disposeOwner(owner);
1479
+ itemScope[3]();
1223
1480
  throw error;
1224
1481
  }
1225
1482
  }
@@ -1234,7 +1491,7 @@ function keyed(scope, reads, values, key, render, additionalScope, additionalRea
1234
1491
  }
1235
1492
  };
1236
1493
  update();
1237
- const removeUpdater = subscribe(scope, reads, update, additionalScope, additionalReads);
1494
+ const removeUpdater = subscribe(scope, reads, update, additionalScope, resolvedAdditionalReads);
1238
1495
  onCleanup(() => {
1239
1496
  removeUpdater();
1240
1497
  list.dispose();
@@ -1295,7 +1552,7 @@ function compiledRoot(scope, render) {
1295
1552
  componentCommitOwners.set(end, owner);
1296
1553
  const fragment = document.createDocumentFragment();
1297
1554
  if (hydratedRange === void 0) fragment.append(start, end);
1298
- owner[1].add(() => {
1555
+ owner[1].push(() => {
1299
1556
  try {
1300
1557
  removeBetween(start, end);
1301
1558
  } finally {
@@ -1344,7 +1601,7 @@ function adoptCompiledRoot(root) {
1344
1601
  const range = componentRanges.get(root);
1345
1602
  if (range === void 0) return;
1346
1603
  const owner = scopeOwners.get(range[2]);
1347
- if (activeOwner !== null && owner !== void 0 && activeOwner !== owner) activeOwner[1].add(range[2][3]);
1604
+ if (activeOwner !== null && owner !== void 0 && activeOwner !== owner) activeOwner[1].push(range[2][3]);
1348
1605
  }
1349
1606
  function constructCompiledComponent(component, componentType) {
1350
1607
  const previousCollector = activeScopeCollector;
@@ -1370,14 +1627,16 @@ function constructCompiledComponent(component, componentType) {
1370
1627
  }
1371
1628
  function queueElementRef(element, value) {
1372
1629
  if (!isRefValue(value)) throw new TypeError(DEV ? "ref must be a callback or an object with current" : "V006");
1373
- pendingRefs.set(element, [activeOwner, value]);
1630
+ const pending = [activeOwner, value];
1631
+ setPendingRef(element, pending);
1632
+ activeOwner?.[1].push(() => deletePendingRef(element, pending));
1374
1633
  }
1375
1634
  function useImperativeHandle(ref, create, dependencies) {
1376
1635
  const owner = activeConstructionOwner;
1377
1636
  if (owner === null) throw new Error(DEV ? "useImperativeHandle must run during compiled component construction" : "V013");
1378
1637
  if (!isRefValue(ref)) throw new TypeError(DEV ? "imperative ref must be null, a callback, or an object with current" : "V006");
1379
1638
  if (dependencies !== void 0 && dependencies.length !== 0) throw new Error(DEV ? "reactive useImperativeHandle dependencies are not supported yet" : "V014");
1380
- queueOwnerCommit(owner, () => owner[1].add(attachRef(ref, create())));
1639
+ queueOwnerCommit(owner, () => owner[1].push(attachRef(ref, create())));
1381
1640
  }
1382
1641
  function useLayoutEffect(create, dependencies) {
1383
1642
  registerEffect(create, dependencies, false);
@@ -1394,7 +1653,7 @@ function useInsertionEffect(create, dependencies) {
1394
1653
  cleanup();
1395
1654
  cleanup = profilingEnabled ? readProfiledEffectCleanup(owner, create) : readEffectCleanup(create());
1396
1655
  });
1397
- lifetimeOwner[1].add(() => cleanup());
1656
+ lifetimeOwner[1].push(() => cleanup());
1398
1657
  return;
1399
1658
  }
1400
1659
  let cleanup = noop;
@@ -1415,7 +1674,7 @@ function useInsertionEffect(create, dependencies) {
1415
1674
  queueInsertionCommit(owner, () => {
1416
1675
  if (!lifetimeOwner[0]) activate();
1417
1676
  });
1418
- lifetimeOwner[1].add(disposeResource);
1677
+ lifetimeOwner[1].push(disposeResource);
1419
1678
  }
1420
1679
  function useEffect(create, dependencies) {
1421
1680
  registerEffect(create, dependencies, true);
@@ -1441,7 +1700,7 @@ function registerEffect(create, dependencies, passive) {
1441
1700
  });
1442
1701
  } else run();
1443
1702
  });
1444
- lifetimeOwner[1].add(() => {
1703
+ lifetimeOwner[1].push(() => {
1445
1704
  generation += 1;
1446
1705
  if (passive) (DEV ? scheduleTask : queueMicrotask)(() => runOwnerTask(lifetimeOwner, cleanup));
1447
1706
  else cleanup();
@@ -1477,7 +1736,7 @@ function registerEffect(create, dependencies, passive) {
1477
1736
  queueOwnerCommit(owner, () => {
1478
1737
  if (!lifetimeOwner[0]) activate();
1479
1738
  });
1480
- lifetimeOwner[1].add(disposeResource);
1739
+ lifetimeOwner[1].push(disposeResource);
1481
1740
  }
1482
1741
  function compiledLayoutEffect(scope, reads, readCreate, readDependencies) {
1483
1742
  compiledEffect(scope, reads, readCreate, readDependencies, false);
@@ -1508,7 +1767,7 @@ function compiledInsertionEffect(scope, reads, readCreate, readDependencies) {
1508
1767
  run,
1509
1768
  -20
1510
1769
  ]));
1511
- lifetimeOwner[1].add(() => {
1770
+ lifetimeOwner[1].push(() => {
1512
1771
  removeUpdater();
1513
1772
  cleanup();
1514
1773
  });
@@ -1555,7 +1814,7 @@ function compiledInsertionEffect(scope, reads, readCreate, readDependencies) {
1555
1814
  -20
1556
1815
  ]);
1557
1816
  });
1558
- lifetimeOwner[1].add(() => {
1817
+ lifetimeOwner[1].push(() => {
1559
1818
  removeUpdater();
1560
1819
  disposeResource();
1561
1820
  });
@@ -1600,7 +1859,7 @@ function compiledEffect(scope, reads, readCreate, readDependencies, passive = tr
1600
1859
  20
1601
1860
  ]);
1602
1861
  });
1603
- lifetimeOwner[1].add(() => {
1862
+ lifetimeOwner[1].push(() => {
1604
1863
  generation += 1;
1605
1864
  removeUpdater();
1606
1865
  if (passive) (DEV ? scheduleTask : queueMicrotask)(() => runOwnerTask(lifetimeOwner, cleanup));
@@ -1666,7 +1925,7 @@ function compiledEffect(scope, reads, readCreate, readDependencies, passive = tr
1666
1925
  20
1667
1926
  ]);
1668
1927
  });
1669
- lifetimeOwner[1].add(() => {
1928
+ lifetimeOwner[1].push(() => {
1670
1929
  removeUpdater();
1671
1930
  disposeResource();
1672
1931
  });
@@ -1756,7 +2015,7 @@ function compiledImperativeHandle(scope, reads, readRef, create, readDependencie
1756
2015
  ]);
1757
2016
  };
1758
2017
  const removeUpdater = subscribe(scope, reads, update);
1759
- owner[1].add(() => {
2018
+ owner[1].push(() => {
1760
2019
  removeUpdater();
1761
2020
  cleanup();
1762
2021
  });
@@ -1766,6 +2025,7 @@ function queueOwnerCommit(owner, commit) {
1766
2025
  if (commits === void 0) {
1767
2026
  commits = /* @__PURE__ */ new Set();
1768
2027
  pendingOwnerCommits.set(owner, commits);
2028
+ pendingOwnerCommitCount += 1;
1769
2029
  }
1770
2030
  commits.add(commit);
1771
2031
  }
@@ -1774,6 +2034,7 @@ function queueInsertionCommit(owner, commit) {
1774
2034
  if (commits === void 0) {
1775
2035
  commits = /* @__PURE__ */ new Set();
1776
2036
  pendingInsertionCommits.set(owner, commits);
2037
+ pendingInsertionOwnerCount += 1;
1777
2038
  }
1778
2039
  commits.add(commit);
1779
2040
  }
@@ -1795,7 +2056,7 @@ function mountCompiledRef(element, value) {
1795
2056
  current,
1796
2057
  (attached) => cleanup = attached
1797
2058
  ];
1798
- pendingRefs.set(element, pending);
2059
+ setPendingRef(element, pending);
1799
2060
  const removeUpdater = subscribeBinding(value, () => {
1800
2061
  const next = value[1]();
1801
2062
  if (Object.is(next, current)) return;
@@ -1844,7 +2105,7 @@ function mountCompiledRef(element, value) {
1844
2105
  });
1845
2106
  onCleanup(() => {
1846
2107
  removeUpdater();
1847
- if (pendingRefs.get(element) === pending) pendingRefs.delete(element);
2108
+ deletePendingRef(element, pending);
1848
2109
  cleanup();
1849
2110
  });
1850
2111
  }
@@ -1901,6 +2162,7 @@ function mountCompiled(component, host, options) {
1901
2162
  const range = componentRanges.get(root);
1902
2163
  if (range === void 0) throw new Error(DEV ? "mountCompiled received an unknown component result" : "V007");
1903
2164
  const previous = [...host.childNodes];
2165
+ const releaseEventRoot = retainCompiledEventRoot(host);
1904
2166
  try {
1905
2167
  root[1](host, previous[0] ?? null);
1906
2168
  const rootOwner = scopeOwners.get(range[2]);
@@ -1914,6 +2176,7 @@ function mountCompiled(component, host, options) {
1914
2176
  commitOwnerResources(rootOwner);
1915
2177
  if (!hydrating) for (const node of previous) host.removeChild(node);
1916
2178
  } catch (error) {
2179
+ releaseEventRoot();
1917
2180
  try {
1918
2181
  range[2][3]();
1919
2182
  } catch {}
@@ -1921,7 +2184,16 @@ function mountCompiled(component, host, options) {
1921
2184
  rootIdentity.onUncaughtError(error);
1922
2185
  return { dispose: noop };
1923
2186
  }
1924
- return { dispose: range[2][3] };
2187
+ let disposed = false;
2188
+ return { dispose: () => {
2189
+ if (disposed) return;
2190
+ disposed = true;
2191
+ try {
2192
+ range[2][3]();
2193
+ } finally {
2194
+ releaseEventRoot();
2195
+ }
2196
+ } };
1925
2197
  }
1926
2198
  function isCompiledBinding(value) {
1927
2199
  return Array.isArray(value) && value[0] === BINDING;
@@ -1935,9 +2207,12 @@ function isCompiledComponentResult(value) {
1935
2207
  function mountCompiledBinding(parent, value) {
1936
2208
  mountCompiledBindingBefore(parent, value, null);
1937
2209
  }
1938
- function mountCompiledProp(value, apply) {
2210
+ function applyCompiledPropValue(apply, element, name, next) {
2211
+ return element === void 0 ? apply(next) : apply(element, name, next);
2212
+ }
2213
+ function mountCompiledProp(value, apply, element, name) {
1939
2214
  let current = value[1]();
1940
- let cleanup = apply(current);
2215
+ let cleanup = applyCompiledPropValue(apply, element, name, current);
1941
2216
  const removeUpdater = subscribeBinding(value, () => {
1942
2217
  const next = value[1]();
1943
2218
  if (Object.is(next, current)) return;
@@ -1946,10 +2221,10 @@ function mountCompiledProp(value, apply) {
1946
2221
  let committedNext = false;
1947
2222
  stagePublication([() => {
1948
2223
  try {
1949
- nextCleanup = apply(next);
2224
+ nextCleanup = applyCompiledPropValue(apply, element, name, next);
1950
2225
  } catch (error) {
1951
2226
  try {
1952
- apply(previous);
2227
+ applyCompiledPropValue(apply, element, name, previous);
1953
2228
  } catch {}
1954
2229
  throw error;
1955
2230
  }
@@ -1960,7 +2235,7 @@ function mountCompiledProp(value, apply) {
1960
2235
  }, () => {
1961
2236
  if (!committedNext) return;
1962
2237
  nextCleanup?.();
1963
- cleanup = apply(previous);
2238
+ cleanup = applyCompiledPropValue(apply, element, name, previous);
1964
2239
  current = previous;
1965
2240
  committedNext = false;
1966
2241
  }]);
@@ -2018,11 +2293,32 @@ function structural(scope, mount, hydrationKind) {
2018
2293
  hydrationKind
2019
2294
  ];
2020
2295
  }
2021
- function structuralRange(parent, before, label) {
2296
+ function structuralRange(parent, before, label, borrowOuter = false, allowMarkerlessHydration = false) {
2297
+ const current = borrowHydrationSlotRange(parent, true);
2298
+ if (current !== void 0) {
2299
+ claimHydrationSlotRange(parent);
2300
+ return [
2301
+ current[0],
2302
+ current[1],
2303
+ true,
2304
+ true
2305
+ ];
2306
+ }
2307
+ if (borrowOuter) {
2308
+ const outer = borrowHydrationSlotRange(parent, false);
2309
+ if (outer !== void 0) return [
2310
+ outer[0],
2311
+ outer[1],
2312
+ true,
2313
+ false
2314
+ ];
2315
+ }
2316
+ if (allowMarkerlessHydration && hydrationCursor(parent) !== void 0) return void 0;
2022
2317
  const hydrated = claimHydrationSlotRange(parent);
2023
2318
  if (hydrated !== void 0) return [
2024
2319
  hydrated[0],
2025
2320
  hydrated[1],
2321
+ true,
2026
2322
  true
2027
2323
  ];
2028
2324
  const start = document.createComment(DEV ? `vidact:${label}` : "");
@@ -2032,14 +2328,27 @@ function structuralRange(parent, before, label) {
2032
2328
  return [
2033
2329
  start,
2034
2330
  end,
2035
- false
2331
+ false,
2332
+ true
2036
2333
  ];
2037
2334
  }
2038
2335
  function subscribe(scope, reads, run, additionalScope, additionalReads) {
2039
- const removers = [scope[0](reads, run)];
2040
- if (additionalScope !== void 0 && additionalReads !== void 0) removers.push(additionalScope[0](additionalReads, () => withScopeNamespace(scope, run)));
2336
+ let first;
2337
+ if (!isEmptySources(reads)) {
2338
+ const remove = scope[0](reads, run);
2339
+ if (remove !== noop) first = remove;
2340
+ }
2341
+ let second;
2342
+ if (additionalScope !== void 0 && additionalReads !== void 0 && !isEmptySources(additionalReads)) {
2343
+ const additionalRun = scopeNamespaces.get(additionalScope) === scopeNamespaces.get(scope) ? run : () => withScopeNamespace(scope, run);
2344
+ const remove = additionalScope[0](additionalReads, additionalRun);
2345
+ if (remove !== noop) second = remove;
2346
+ }
2347
+ if (first === void 0) return second ?? noop;
2348
+ if (second === void 0) return first;
2041
2349
  return () => {
2042
- for (const remove of removers) remove();
2350
+ first();
2351
+ second();
2043
2352
  };
2044
2353
  }
2045
2354
  function subscribeBinding(compiledBinding, run) {
@@ -2065,7 +2374,7 @@ function createOwner(context = activeContextFrame ?? activeOwner?.[2] ?? null, r
2065
2374
  if (profilingEnabled) {
2066
2375
  const owner = [
2067
2376
  false,
2068
- /* @__PURE__ */ new Set(),
2377
+ [],
2069
2378
  context,
2070
2379
  rootIdentity,
2071
2380
  boundary,
@@ -2077,14 +2386,14 @@ function createOwner(context = activeContextFrame ?? activeOwner?.[2] ?? null, r
2077
2386
  }
2078
2387
  const owner = retainedUiEnabled ? [
2079
2388
  false,
2080
- /* @__PURE__ */ new Set(),
2389
+ [],
2081
2390
  context,
2082
2391
  rootIdentity,
2083
2392
  boundary,
2084
2393
  retainedConnection
2085
2394
  ] : [
2086
2395
  false,
2087
- /* @__PURE__ */ new Set(),
2396
+ [],
2088
2397
  context,
2089
2398
  rootIdentity,
2090
2399
  boundary
@@ -2342,7 +2651,7 @@ function withRootIdentity(rootIdentity, operation) {
2342
2651
  }
2343
2652
  }
2344
2653
  function onCleanup(cleanup) {
2345
- activeOwner?.[1].add(cleanup);
2654
+ activeOwner?.[1].push(cleanup);
2346
2655
  }
2347
2656
  function disposeOwner(owner) {
2348
2657
  if (owner[0]) return;
@@ -2350,19 +2659,21 @@ function disposeOwner(owner) {
2350
2659
  disposalCascadeDepth += 1;
2351
2660
  disposalCascadeOwners.add(owner);
2352
2661
  if (DEV) activeOwnerCount -= 1;
2353
- pendingInsertionCommits.delete(owner);
2354
- pendingOwnerCommits.delete(owner);
2355
- const cleanups = [...owner[1]];
2356
- owner[1].clear();
2662
+ if (pendingInsertionCommits.delete(owner)) pendingInsertionOwnerCount -= 1;
2663
+ if (pendingOwnerCommits.delete(owner)) pendingOwnerCommitCount -= 1;
2357
2664
  let firstError;
2358
2665
  let hasError = false;
2359
2666
  try {
2360
- for (let index = cleanups.length - 1; index >= 0; index -= 1) try {
2361
- cleanups[index]?.();
2362
- } catch (error) {
2363
- if (!hasError) firstError = error;
2364
- hasError = true;
2667
+ for (let remaining = owner[1].length; remaining > 0; remaining -= 1) {
2668
+ const cleanup = owner[1].pop();
2669
+ try {
2670
+ cleanup?.();
2671
+ } catch (error) {
2672
+ if (!hasError) firstError = error;
2673
+ hasError = true;
2674
+ }
2365
2675
  }
2676
+ owner[1].length = 0;
2366
2677
  } finally {
2367
2678
  disposalCascadeDepth -= 1;
2368
2679
  if (disposalCascadeDepth === 0) disposalCascadeOwners.clear();
@@ -2373,103 +2684,141 @@ function disposeOwner(owner) {
2373
2684
  function readCompiledOwnerMetrics() {
2374
2685
  return {
2375
2686
  active: activeOwnerCount,
2376
- created: createdOwnerCount
2687
+ created: createdOwnerCount,
2688
+ updaters: createdUpdaterCount,
2689
+ schedulerPlans: createdSchedulerPlanCount
2377
2690
  };
2378
2691
  }
2692
+ /** @internal Test-only publication traversal evidence. */
2693
+ function readCompiledPublicationMetrics() {
2694
+ return { visitedNodes: visitedPublishedNodeCount };
2695
+ }
2696
+ function ensureMountedBindingRange(state) {
2697
+ if (state.start !== null && state.end !== null) return [state.start, state.end];
2698
+ const anchor = state.text;
2699
+ const parent = anchor?.parentNode;
2700
+ if (anchor === null || parent === null || parent === void 0) throw new Error(DEV ? "markerless binding text is detached" : "V010");
2701
+ state.start = document.createComment(DEV ? "vidact:binding" : "");
2702
+ state.end = document.createComment(DEV ? "/vidact:binding" : "");
2703
+ parent.insertBefore(state.start, anchor);
2704
+ parent.insertBefore(state.end, anchor.nextSibling);
2705
+ return [state.start, state.end];
2706
+ }
2707
+ function clearMountedBinding(state) {
2708
+ const [start, end] = ensureMountedBindingRange(state);
2709
+ const owner = state.currentOwner;
2710
+ state.currentOwner = null;
2711
+ state.text = null;
2712
+ disposeRange(owner, start, end);
2713
+ }
2379
2714
  function mountCompiledBindingBefore(parent, value, before) {
2380
- const unset = Symbol(DEV ? "Vidact.UnsetBinding" : void 0);
2381
2715
  const initial = value[1]();
2382
2716
  const scalarInitial = isScalarRenderValue(initial);
2717
+ const structuralInitial = ownedStructuralBinding(initial);
2383
2718
  const hydratedTextRange = scalarInitial ? claimHydrationTextRange(parent, toText(initial)) : void 0;
2384
- const borrowedHydrationRange = isHydrating() && !scalarInitial ? borrowHydrationSlotRange(parent, isStructuralBinding(initial) && initial[2] === "slot") : void 0;
2719
+ const borrowedHydrationRange = isHydrating() && !scalarInitial ? borrowHydrationSlotRange(parent, structuralInitial?.[2] === "slot") : void 0;
2385
2720
  const hydratedStructuralRange = isHydrating() && !scalarInitial ? borrowedHydrationRange ?? claimHydrationSlotRange(parent) : void 0;
2386
2721
  const hydratedRange = hydratedTextRange ?? hydratedStructuralRange;
2387
- const start = hydratedRange?.[0] ?? document.createComment(DEV ? "vidact:binding" : "");
2388
- const end = hydratedRange?.[1] ?? document.createComment(DEV ? "/vidact:binding" : "");
2389
- if (hydratedRange === void 0) {
2722
+ const markerlessScalar = hydratedRange === void 0 && scalarInitial && !isHydrating();
2723
+ let start = hydratedRange?.[0] ?? null;
2724
+ let end = hydratedRange?.[1] ?? null;
2725
+ if (!markerlessScalar && hydratedRange === void 0) {
2726
+ start = document.createComment(DEV ? "vidact:binding" : "");
2727
+ end = document.createComment(DEV ? "/vidact:binding" : "");
2390
2728
  parent.insertBefore(start, before);
2391
2729
  parent.insertBefore(end, before);
2392
2730
  }
2393
- let current = hydratedTextRange === void 0 ? unset : initial;
2394
- let currentOwner = null;
2395
- let text = hydratedTextRange?.[2] ?? null;
2396
- const stableRenderable = (renderable) => {
2397
- const identity = renderableIdentity(renderable);
2398
- let previous = renderablePropsSnapshot(renderable);
2399
- const input = binding(value[2], value[3], () => {
2400
- const next = value[1]();
2401
- if (!isRenderableProtocol(next) || !Object.is(renderableIdentity(next), identity)) return previous;
2402
- previous = renderablePropsSnapshot(next);
2403
- return previous;
2404
- }, value[4], value[5]);
2405
- return materializeRenderableWithInput(renderable, input);
2406
- };
2407
- const clear = () => {
2408
- const owner = currentOwner;
2409
- currentOwner = null;
2410
- text = null;
2411
- disposeRange(owner, start, end);
2731
+ const state = {
2732
+ start,
2733
+ end,
2734
+ current: hydratedTextRange === void 0 && !markerlessScalar ? UNSET_BINDING : initial,
2735
+ currentOwner: null,
2736
+ text: hydratedTextRange?.[2] ?? null
2412
2737
  };
2738
+ if (markerlessScalar) {
2739
+ state.text = document.createTextNode(toText(initial));
2740
+ parent.insertBefore(state.text, before);
2741
+ }
2413
2742
  const update = () => {
2414
2743
  const next = value[1]();
2415
- if (current !== unset && Object.is(next, current)) return;
2416
- if (current !== unset && isRenderableProtocol(current) && isRenderableProtocol(next) && canReconcileRenderable(current) && canReconcileRenderable(next) && Object.is(renderableIdentity(current), renderableIdentity(next))) {
2417
- current = next;
2744
+ if (state.current !== UNSET_BINDING && Object.is(next, state.current)) return;
2745
+ if (state.current !== UNSET_BINDING && isRenderableProtocol(state.current) && isRenderableProtocol(next) && canReconcileRenderable(state.current) && canReconcileRenderable(next) && Object.is(renderableIdentity(state.current), renderableIdentity(next))) {
2746
+ state.current = next;
2418
2747
  return;
2419
2748
  }
2420
- const currentParent = rangeParent(start, end, "binding range");
2421
2749
  if (isScalarRenderValue(next)) {
2422
2750
  const content = toText(next);
2423
- if (text !== null) {
2424
- const target = text;
2751
+ if (state.text !== null) {
2752
+ const target = state.text;
2425
2753
  const previousContent = target.data;
2426
- const previous = current;
2754
+ const previous = state.current;
2427
2755
  stagePublication([() => {
2428
2756
  if (target.data !== content) target.data = content;
2429
- current = next;
2757
+ state.current = next;
2430
2758
  }, () => {
2431
2759
  if (target.data !== previousContent) target.data = previousContent;
2432
- current = previous;
2760
+ state.current = previous;
2433
2761
  }]);
2434
2762
  return;
2435
2763
  }
2436
- clear();
2437
- text = document.createTextNode(content);
2438
- currentParent.insertBefore(text, end);
2439
- current = next;
2764
+ clearMountedBinding(state);
2765
+ const [rangeStart, rangeEnd] = ensureMountedBindingRange(state);
2766
+ const currentParent = rangeParent(rangeStart, rangeEnd, "binding range");
2767
+ state.text = document.createTextNode(content);
2768
+ currentParent.insertBefore(state.text, rangeEnd);
2769
+ state.current = next;
2440
2770
  return;
2441
2771
  }
2772
+ const [rangeStart, rangeEnd] = ensureMountedBindingRange(state);
2773
+ const currentParent = rangeParent(rangeStart, rangeEnd, "binding range");
2442
2774
  const nextOwner = createOwner();
2443
- const [fragment, staged] = stageValue(isRenderableProtocol(next) && canReconcileRenderable(next) ? stableRenderable(next) : next, nextOwner);
2775
+ const [fragment, staged] = stageValue(isRenderableProtocol(next) && canReconcileRenderable(next) ? stableRenderableBinding(value, next) : next, nextOwner);
2444
2776
  try {
2445
- clear();
2777
+ clearMountedBinding(state);
2446
2778
  } catch (error) {
2447
2779
  disposeOwner(nextOwner);
2448
2780
  throw error;
2449
2781
  }
2450
- currentOwner = nextOwner;
2451
- currentParent.insertBefore(fragment, end);
2782
+ state.currentOwner = nextOwner;
2783
+ currentParent.insertBefore(fragment, rangeEnd);
2452
2784
  commitPublishedNodes(staged);
2453
- current = next;
2785
+ state.current = next;
2454
2786
  };
2455
2787
  if (hydratedStructuralRange !== void 0) {
2788
+ const rangeEnd = hydratedStructuralRange[1];
2456
2789
  const nextOwner = createOwner();
2457
- const [fragment, staged] = withHydrationInsertion(parent, end, () => stageRender(() => isRenderableProtocol(initial) && canReconcileRenderable(initial) ? stableRenderable(initial) : initial, nextOwner));
2458
- parent.insertBefore(fragment, end);
2790
+ const [fragment, staged] = withHydrationInsertion(parent, rangeEnd, () => stageRender(() => isRenderableProtocol(initial) && canReconcileRenderable(initial) ? stableRenderableBinding(value, initial) : initial, nextOwner));
2791
+ parent.insertBefore(fragment, rangeEnd);
2459
2792
  commitPublishedNodes(staged);
2460
- currentOwner = nextOwner;
2461
- current = initial;
2462
- } else if (hydratedRange === void 0) update();
2793
+ state.currentOwner = nextOwner;
2794
+ state.current = initial;
2795
+ } else if (hydratedRange === void 0 && !markerlessScalar) update();
2463
2796
  const removeUpdater = subscribeBinding(value, update);
2464
2797
  onCleanup(() => {
2465
2798
  removeUpdater();
2466
- clear();
2799
+ if (state.start === null || state.end === null) {
2800
+ state.text?.remove();
2801
+ state.text = null;
2802
+ return;
2803
+ }
2804
+ clearMountedBinding(state);
2467
2805
  if (borrowedHydrationRange === void 0) {
2468
- start.remove();
2469
- end.remove();
2806
+ state.start.remove();
2807
+ state.end.remove();
2470
2808
  }
2471
2809
  });
2472
2810
  }
2811
+ function stableRenderableBinding(value, renderable) {
2812
+ const identity = renderableIdentity(renderable);
2813
+ let previous = renderablePropsSnapshot(renderable);
2814
+ const input = binding(value[2], value[3], () => {
2815
+ const next = value[1]();
2816
+ if (!isRenderableProtocol(next) || !Object.is(renderableIdentity(next), identity)) return previous;
2817
+ previous = renderablePropsSnapshot(next);
2818
+ return previous;
2819
+ }, value[4], value[5]);
2820
+ return materializeRenderableWithInput(renderable, input);
2821
+ }
2473
2822
  function materialize(value) {
2474
2823
  const insertionPoint = hydrationInsertionPoint();
2475
2824
  if (insertionPoint !== void 0) {
@@ -2526,6 +2875,30 @@ function stageRender(render, owner) {
2526
2875
  throw error;
2527
2876
  }
2528
2877
  }
2878
+ function stageMarkerlessHydrationRender(parent, before, render, owner) {
2879
+ const first = hydrationCursor(parent);
2880
+ if (first === void 0) throw new Error("markerless hydration render requires active hydration");
2881
+ try {
2882
+ withHydrationInsertion(parent, before, () => withOwner(owner, () => insertValue(parent, render(), before)));
2883
+ } catch (error) {
2884
+ try {
2885
+ disposeOwner(owner);
2886
+ } catch {}
2887
+ throw error;
2888
+ }
2889
+ const after = hydrationCursor(parent);
2890
+ if (after === void 0) {
2891
+ disposeOwner(owner);
2892
+ throw new Error("markerless hydration render lost its hydration cursor");
2893
+ }
2894
+ const nodes = [];
2895
+ for (let node = first; node !== null && node !== after; node = node.nextSibling) nodes.push(node);
2896
+ return [
2897
+ first,
2898
+ after,
2899
+ nodes
2900
+ ];
2901
+ }
2529
2902
  function insertValue(parent, value, before, moves) {
2530
2903
  if (value === null || value === void 0 || typeof value === "boolean") {
2531
2904
  claimHydrationText(parent, "");
@@ -2631,10 +3004,13 @@ function isRefValue(value) {
2631
3004
  return value === null || value === void 0 || typeof value === "function" || typeof value === "object" && value !== null && "current" in value;
2632
3005
  }
2633
3006
  function claimPendingRefOwners(root) {
3007
+ if (pendingRefCount === 0) return;
2634
3008
  visitNodes(root, (node) => {
2635
3009
  if (!(node instanceof Element)) return;
2636
3010
  const pending = pendingRefs.get(node);
2637
- if (pending !== void 0 && pending[0] === null) pending[0] = activeOwner;
3011
+ if (pending === void 0 || pending[0] !== null) return;
3012
+ pending[0] = activeOwner;
3013
+ activeOwner?.[1].push(() => deletePendingRef(node, pending));
2638
3014
  });
2639
3015
  }
2640
3016
  function commitPendingRefs(root) {
@@ -2647,9 +3023,9 @@ function commitPublishedNodes(nodes) {
2647
3023
  function commitPublishedNodesNow(nodes) {
2648
3024
  const publicationRoot = nodes[0]?.getRootNode();
2649
3025
  if (publicationRoot instanceof DocumentFragment && !(publicationRoot instanceof ShadowRoot)) return;
2650
- for (const node of nodes) commitNodeInsertions(node);
2651
- for (const node of nodes) commitNodeRefs(node);
2652
- for (const node of nodes) commitNodeResources(node);
3026
+ if (pendingInsertionOwnerCount > 0) for (const node of nodes) commitNodeInsertions(node);
3027
+ if (pendingRefCount > 0) for (const node of nodes) commitNodeRefs(node);
3028
+ if (pendingOwnerCommitCount > 0) for (const node of nodes) commitNodeResources(node);
2653
3029
  }
2654
3030
  function commitNodeInsertions(root) {
2655
3031
  visitNodes(root, (node) => {
@@ -2661,12 +3037,12 @@ function commitNodeRefs(root) {
2661
3037
  if (node instanceof Element) {
2662
3038
  const pending = pendingRefs.get(node);
2663
3039
  if (pending !== void 0) {
2664
- pendingRefs.delete(node);
3040
+ deletePendingRef(node, pending);
2665
3041
  const owner = pending[0] ?? activeOwner;
2666
3042
  commitContextInsertions(owner?.[2] ?? null);
2667
3043
  commitOwnerInsertions(owner ?? void 0);
2668
3044
  const cleanup = attachRef(pending[1], node);
2669
- if (pending[2] === void 0) owner?.[1].add(cleanup);
3045
+ if (pending[2] === void 0) owner?.[1].push(cleanup);
2670
3046
  else pending[2](cleanup);
2671
3047
  }
2672
3048
  }
@@ -2687,6 +3063,7 @@ function commitOwnerInsertions(owner) {
2687
3063
  const commits = pendingInsertionCommits.get(owner);
2688
3064
  if (commits === void 0) return;
2689
3065
  pendingInsertionCommits.delete(owner);
3066
+ pendingInsertionOwnerCount -= 1;
2690
3067
  for (const commit of commits) commit();
2691
3068
  }
2692
3069
  function commitOwnerResources(owner) {
@@ -2694,6 +3071,7 @@ function commitOwnerResources(owner) {
2694
3071
  const commits = pendingOwnerCommits.get(owner);
2695
3072
  if (commits === void 0) return;
2696
3073
  pendingOwnerCommits.delete(owner);
3074
+ pendingOwnerCommitCount -= 1;
2697
3075
  for (const commit of commits) commit();
2698
3076
  }
2699
3077
  function commitRangeRefs(start, end) {
@@ -2706,6 +3084,7 @@ function commitRangeRefs(start, end) {
2706
3084
  commitPublishedNodesNow(nodes);
2707
3085
  }
2708
3086
  function visitNodes(root, visit) {
3087
+ visitedPublishedNodeCount += 1;
2709
3088
  visit(root);
2710
3089
  for (const child of root.childNodes) visitNodes(child, visit);
2711
3090
  }
@@ -2757,7 +3136,8 @@ function drainFlushes() {
2757
3136
  throw new Error(DEV ? "Vidact compiled scopes did not stabilize" : "V011");
2758
3137
  }
2759
3138
  runs.set(flush, runCount);
2760
- flush();
3139
+ if (typeof flush === "function") flush();
3140
+ else flush[1]();
2761
3141
  }
2762
3142
  activePublication = null;
2763
3143
  committing = true;
@@ -2862,6 +3242,6 @@ function abortPublication(operations) {
2862
3242
  } catch {}
2863
3243
  }
2864
3244
  //#endregion
2865
- export { COMPONENT_SPREAD_SOURCE, DEV, Suspense, adoptCompiledRoot, binding, captureCompiledOwnerStack, captureCompiledTask, choose, compiledEffect, compiledEvent, compiledImperativeHandle, compiledInsertionEffect, compiledLayoutEffect, compiledRoot, constructCompiledComponent, createCompiledAsync, createCompiledContext, createCompiledEffectEvent, createCompiledExternalStore, createCompiledId, createCompiledMemo, createCompiledProp, createCompiledReducer, createCompiledRestProp, createCompiledScope, createCompiledState, createContext, createNarrowCompiledScope, createPortal, deferred, dispatch, enableProfiling, enableRetainedUi, errorBoundary, hydrateCompiled, indexed, isCompiledBinding, isCompiledComponentResult, isCompiledContext, isStructuralBinding, keyed, mountCompiled, mountCompiledBinding, mountCompiledProp, mountCompiledPropTransition, mountCompiledRef, objectRest, profiled, queueElementRef, readCompiledOwnerMetrics, recordCompiledDebugValue, registerCompiledCleanup, retainedActivity, runCompiledTransaction, runWithCompiledContext, suspense, use, useCallback, useContext, useEffect, useEffectEvent, useId, useImperativeHandle, useInsertionEffect, useLayoutEffect, useMemo, useSyncExternalStore, when };
3245
+ export { COMPONENT_SPREAD_SOURCE, DEV, Suspense, adoptCompiledRoot, binding, captureCompiledOwnerStack, captureCompiledTask, choose, compiledEffect, compiledEvent, compiledImperativeHandle, compiledInlineEvent, compiledInsertionEffect, compiledLayoutEffect, compiledRoot, constructCompiledComponent, createCompiledAsync, createCompiledContext, createCompiledEffectEvent, createCompiledExternalStore, createCompiledId, createCompiledMemo, createCompiledProp, createCompiledReducer, createCompiledRestProp, createCompiledScope, createCompiledState, createContext, createNarrowCompiledScope, createPortal, deferred, dispatch, enableProfiling, enableRetainedUi, errorBoundary, hydrateCompiled, indexed, isCompiledBinding, isCompiledComponentResult, isCompiledContext, isCompiledEventHandler, isStructuralBinding, keyed, mountCompiled, mountCompiledBinding, mountCompiledProp, mountCompiledPropTransition, mountCompiledRef, objectRest, profiled, queueElementRef, readCompiledOwnerMetrics, readCompiledPublicationMetrics, recordCompiledDebugValue, registerCompiledCleanup, retainedActivity, runCompiledTransaction, runWithCompiledContext, suspense, use, useCallback, useContext, useEffect, useEffectEvent, useId, useImperativeHandle, useInsertionEffect, useLayoutEffect, useMemo, useSyncExternalStore, when };
2866
3246
 
2867
3247
  //# sourceMappingURL=core.js.map