octane 0.3.3 → 0.3.5

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.
@@ -42,6 +42,10 @@ function moveNativeNodeBefore(parent, node, anchor, focused, contentEditable) {
42
42
  moveBefore.call(parent, node, anchor);
43
43
  return;
44
44
  }
45
+ if (node.parentNode !== parent || anchor !== null && anchor.parentNode !== parent) {
46
+ parent.insertBefore(node, anchor);
47
+ return;
48
+ }
45
49
  if (node === anchor || node.nextSibling === anchor) return;
46
50
  if (anchor === null || (node.compareDocumentPosition(anchor) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0) {
47
51
  let cursor = node.nextSibling;
@@ -6739,7 +6739,13 @@ function renderBlockInner(block) {
6739
6739
  block.__thenableDone = false;
6740
6740
  }
6741
6741
  if (block.$$ctxReads !== null) block.$$ctxReads.clear();
6742
- if (block.$$ctxDirect !== null) block.$$ctxDirect.clear();
6742
+ if (block.$$ctxDirect !== null) {
6743
+ const state = block.slots[0];
6744
+ if (state?.__kind === "hydrateBlockSlot" && state.parentBlock === block && !state.independent && !state.hydrated) {
6745
+ state.contextChanged = block.$$ctxDepsEpoch !== (0, import_context_epoch.contextEpochNow)() && ctxDirectChanged(block);
6746
+ }
6747
+ block.$$ctxDirect.clear();
6748
+ }
6743
6749
  block.$$ctxDepsEpoch = (0, import_context_epoch.contextEpochNow)();
6744
6750
  block.currentRenderMode = urgentTransitionRender !== null ? "urgent" : block.pendingMode ?? prevBlock?.currentRenderMode ?? "urgent";
6745
6751
  block.currentRenderDeferred = urgentTransitionRender !== null ? false : block.pendingMode !== null ? block.pendingDeferred : prevBlock?.currentRenderDeferred ?? false;
@@ -6764,7 +6770,9 @@ function renderBlockInner(block) {
6764
6770
  renderRetry = true;
6765
6771
  return true;
6766
6772
  }
6767
- if (out !== void 0 && block.outputHandler !== null) block.outputHandler(block, out);
6773
+ if (block.outputHandler !== null && (out !== void 0 || block.slots[0]?.returnedOutput === true)) {
6774
+ block.outputHandler(block, out ?? null);
6775
+ }
6768
6776
  finishEffectRender(block);
6769
6777
  if (!block.mounted) block.mounted = true;
6770
6778
  if (block.renderStatus === RENDER_RETRYING) block.renderStatus = RENDER_VALID;
@@ -6823,6 +6831,14 @@ function renderBlockInner(block) {
6823
6831
  }
6824
6832
  }
6825
6833
  }
6834
+ let RETURNED_OUTPUT_SCOPE = null;
6835
+ function setReturnedOutputOwner(state, returned) {
6836
+ if (state.returnedOutput === returned) return;
6837
+ if (TRANSITION_JOURNAL !== null && !ROOT_RENDER_ROLLBACK) {
6838
+ TRANSITION_JOURNAL.push(JOURNAL_PROP, state, "returnedOutput", state.returnedOutput);
6839
+ }
6840
+ state.returnedOutput = returned;
6841
+ }
6826
6842
  function returnSlotTail(block, state) {
6827
6843
  const candidates = [
6828
6844
  state?.end,
@@ -6839,59 +6855,82 @@ function returnSlotTail(block, state) {
6839
6855
  }
6840
6856
  return null;
6841
6857
  }
6842
- function renderReturnedValue(block, out) {
6843
- const isComponentDescriptor = out !== null && out.$$kind === import_runtime_tags.ELEMENT_TAG && out.key == null && typeof out.type === "function";
6844
- const existingRet = block.slots[0];
6845
- let replacedStart = null;
6846
- let replacedEnd = null;
6847
- const useSingleRoot = isComponentDescriptor && (out.type.$$singleRoot === true || activeHydration()?.passthroughRanges === true || // STICKY regime: a return slot mounted through the componentSlot route
6848
- // (most importantly by the passthrough-hydration branch above, whose
6849
- // condition is false again once hydration ends) keeps that route while
6850
- // the returned component identity is unchanged. Falling through to the
6851
- // childSlot route would dispose the slot for a mere kind flip — tearing
6852
- // down the very subtree hydration just adopted on its FIRST update. An
6853
- // identity change still disposes below (matching remount semantics).
6854
- existingRet !== void 0 && existingRet.__kind === "componentSlotSlot" && existingRet.currentComp === out.type);
6855
- if (existingRet !== void 0 && existingRet.__kind !== (useSingleRoot ? "componentSlotSlot" : "childSlot")) {
6856
- const swapDriver = TRANSITION_SWAP_DRIVER;
6857
- const transitionMode = block.currentRenderMode === "transition";
6858
- const committedSuspense = swapDriver !== null && activeHydration() === null && preservesCommittedSuspense(block);
6859
- const transitionSwap = ROOT_RENDER_TRANSACTION === null || committedSuspense ? swapDriver : null;
6860
- const suspenseSwap = transitionSwap !== null && !transitionMode && activeHydration() === null && committedSuspense;
6861
- if (transitionSwap !== null && activeHydration() === null && (transitionMode || suspenseSwap)) {
6862
- const tail = returnSlotTail(block, existingRet);
6863
- if (tail !== null) {
6864
- const probe = transitionSwap.render(
6865
- block,
6866
- block.parentNode,
6867
- tail,
6868
- ROOT_RENDERABLE_BODY,
6869
- out,
6870
- renderReturnedValue
6871
- );
6872
- transitionSwap.dispose(probe.wip);
6873
- if (probe.failed) throw probe.error;
6874
- if (probe.suspended) throw new SuspenseException(probe.suspended);
6875
- }
6858
+ function renderReturnedValue(block, out, reset) {
6859
+ const previous = RETURNED_OUTPUT_SCOPE;
6860
+ RETURNED_OUTPUT_SCOPE = block;
6861
+ try {
6862
+ if (reset === true) {
6863
+ const state2 = block.slots[0];
6864
+ if (state2 !== void 0) disposeReturnSlot(block, state2);
6865
+ return;
6876
6866
  }
6877
- if (ROOT_RENDER_TRANSACTION !== null && !existingRet.inherited && !existingRet.borrowed && existingRet.ownerHost == null) {
6878
- const first = existingRet.start ?? existingRet.hostNode ?? existingRet.text ?? existingRet.block?.startMarker ?? existingRet.end ?? null;
6879
- const last = existingRet.end ?? existingRet.block?.endMarker ?? first;
6880
- if (sharesBlockBoundary(block, first, last)) {
6881
- replacedStart = first;
6882
- replacedEnd = last;
6867
+ const isComponentDescriptor = out !== null && out.$$kind === import_runtime_tags.ELEMENT_TAG && out.key == null && typeof out.type === "function";
6868
+ const existingRet = block.slots[0];
6869
+ let replacedStart = null;
6870
+ let replacedEnd = null;
6871
+ const useSingleRoot = isComponentDescriptor && (out.type.$$singleRoot === true || activeHydration()?.passthroughRanges === true || // STICKY regime: a return slot mounted through the componentSlot route
6872
+ // (most importantly by the passthrough-hydration branch above, whose
6873
+ // condition is false again once hydration ends) keeps that route while
6874
+ // the returned component identity is unchanged. Falling through to the
6875
+ // childSlot route would dispose the slot for a mere kind flip — tearing
6876
+ // down the very subtree hydration just adopted on its FIRST update. An
6877
+ // identity change still disposes below (matching remount semantics).
6878
+ existingRet !== void 0 && existingRet.__kind === "componentSlotSlot" && existingRet.currentComp === out.type);
6879
+ if (existingRet !== void 0 && existingRet.__kind !== (useSingleRoot ? "componentSlotSlot" : "childSlot")) {
6880
+ const swapDriver = TRANSITION_SWAP_DRIVER;
6881
+ const transitionMode = block.currentRenderMode === "transition";
6882
+ const committedSuspense = swapDriver !== null && activeHydration() === null && preservesCommittedSuspense(block);
6883
+ const transitionSwap = ROOT_RENDER_TRANSACTION === null || committedSuspense ? swapDriver : null;
6884
+ const suspenseSwap = transitionSwap !== null && !transitionMode && activeHydration() === null && committedSuspense;
6885
+ if (transitionSwap !== null && activeHydration() === null && (transitionMode || suspenseSwap)) {
6886
+ const tail = returnSlotTail(block, existingRet);
6887
+ if (tail !== null) {
6888
+ const probe = transitionSwap.render(
6889
+ block,
6890
+ block.parentNode,
6891
+ tail,
6892
+ ROOT_RENDERABLE_BODY,
6893
+ out,
6894
+ renderReturnedValue
6895
+ );
6896
+ transitionSwap.dispose(probe.wip);
6897
+ if (probe.failed) throw probe.error;
6898
+ if (probe.suspended) throw new SuspenseException(probe.suspended);
6899
+ }
6900
+ }
6901
+ if (ROOT_RENDER_TRANSACTION !== null && !existingRet.inherited && !existingRet.borrowed && existingRet.ownerHost == null) {
6902
+ const first = existingRet.start ?? existingRet.hostNode ?? existingRet.text ?? existingRet.block?.startMarker ?? existingRet.end ?? null;
6903
+ const last = existingRet.end ?? existingRet.block?.endMarker ?? first;
6904
+ if (sharesBlockBoundary(block, first, last)) {
6905
+ replacedStart = first;
6906
+ replacedEnd = last;
6907
+ }
6883
6908
  }
6909
+ disposeReturnSlot(block, existingRet);
6910
+ if (block.disposed) return;
6884
6911
  }
6885
- disposeReturnSlot(block, existingRet);
6886
- if (block.disposed) return;
6887
- }
6888
- if (useSingleRoot) {
6889
- const d = out;
6890
- if (typeof __OCTANE_PROFILE_ENABLED__ !== "undefined" && __OCTANE_PROFILE_ENABLED__ && !(0, import_profiling.__profileHasComponentMetadata)(d.type)) {
6891
- withProfileComponentOverride(
6892
- d.type,
6893
- null,
6894
- () => componentSlot(
6912
+ if (useSingleRoot) {
6913
+ const d = out;
6914
+ if (typeof __OCTANE_PROFILE_ENABLED__ !== "undefined" && __OCTANE_PROFILE_ENABLED__ && !(0, import_profiling.__profileHasComponentMetadata)(d.type)) {
6915
+ withProfileComponentOverride(
6916
+ d.type,
6917
+ null,
6918
+ () => componentSlot(
6919
+ block,
6920
+ 0,
6921
+ block.parentNode,
6922
+ d.type,
6923
+ d.props,
6924
+ block.endMarker,
6925
+ d.key ?? void 0,
6926
+ true,
6927
+ void 0,
6928
+ activeHydration() !== null && elementKeyWasProvided(d),
6929
+ d.__octaneInvocationSite
6930
+ )
6931
+ );
6932
+ } else {
6933
+ componentSlot(
6895
6934
  block,
6896
6935
  0,
6897
6936
  block.parentNode,
@@ -6903,66 +6942,63 @@ function renderReturnedValue(block, out) {
6903
6942
  void 0,
6904
6943
  activeHydration() !== null && elementKeyWasProvided(d),
6905
6944
  d.__octaneInvocationSite
6906
- )
6907
- );
6945
+ );
6946
+ }
6908
6947
  } else {
6909
- componentSlot(
6910
- block,
6911
- 0,
6912
- block.parentNode,
6913
- d.type,
6914
- d.props,
6915
- block.endMarker,
6916
- d.key ?? void 0,
6917
- true,
6918
- void 0,
6919
- activeHydration() !== null && elementKeyWasProvided(d),
6920
- d.__octaneInvocationSite
6921
- );
6948
+ const returnHydration = activeHydration();
6949
+ if (returnHydration !== null && block.slots[0] === void 0 && block.startMarker !== null && block.endMarker !== null && block.startMarker !== block.endMarker && block.startMarker.nodeType === 8 && block.endMarker.nodeType === 8 && (getNextSibling(block.startMarker) === block.endMarker || returnHydration.isUnframedRootRange(block.startMarker, block.endMarker))) {
6950
+ const borrowed = {
6951
+ __kind: "childSlot",
6952
+ start: block.startMarker,
6953
+ end: block.endMarker,
6954
+ ownerHost: null,
6955
+ borrowed: true,
6956
+ compactable: false,
6957
+ block: null,
6958
+ text: null,
6959
+ currentComp: null,
6960
+ currentIsBodyFn: false,
6961
+ forSlot: null,
6962
+ hostNode: null,
6963
+ portal: null
6964
+ };
6965
+ block.slots[0] = borrowed;
6966
+ registerSlot(block, borrowed);
6967
+ }
6968
+ childSlot(block, 0, block.parentNode, out, block.endMarker);
6922
6969
  }
6923
- } else {
6924
- const returnHydration = activeHydration();
6925
- if (returnHydration !== null && block.slots[0] === void 0 && block.startMarker !== null && block.endMarker !== null && block.startMarker !== block.endMarker && block.startMarker.nodeType === 8 && block.endMarker.nodeType === 8 && (getNextSibling(block.startMarker) === block.endMarker || returnHydration.isUnframedRootRange(block.startMarker, block.endMarker))) {
6926
- const borrowed = {
6927
- __kind: "childSlot",
6928
- start: block.startMarker,
6929
- end: block.endMarker,
6930
- ownerHost: null,
6931
- borrowed: true,
6932
- compactable: false,
6933
- block: null,
6934
- text: null,
6935
- currentComp: null,
6936
- currentIsBodyFn: false,
6937
- forSlot: null,
6938
- hostNode: null,
6939
- portal: null
6940
- };
6941
- block.slots[0] = borrowed;
6942
- registerSlot(block, borrowed);
6970
+ if (replacedStart !== null) {
6971
+ const incoming = block.slots[0];
6972
+ const first = incoming.start ?? incoming.hostNode ?? incoming.text ?? incoming.block?.startMarker ?? incoming.end ?? null;
6973
+ const last = incoming.end ?? incoming.block?.endMarker ?? first;
6974
+ replaceSharedBlockBoundary(block, replacedStart, replacedEnd, first, last);
6943
6975
  }
6944
- childSlot(block, 0, block.parentNode, out, block.endMarker);
6945
- }
6946
- if (replacedStart !== null) {
6947
- const incoming = block.slots[0];
6948
- const first = incoming.start ?? incoming.hostNode ?? incoming.text ?? incoming.block?.startMarker ?? incoming.end ?? null;
6949
- const last = incoming.end ?? incoming.block?.endMarker ?? first;
6950
- replaceSharedBlockBoundary(block, replacedStart, replacedEnd, first, last);
6976
+ const state = block.slots[0];
6977
+ if (!block.disposed && state !== void 0 && state.returnedOutput !== true) {
6978
+ if (TRANSITION_JOURNAL !== null && !ROOT_RENDER_ROLLBACK) {
6979
+ TRANSITION_JOURNAL.push(JOURNAL_PROP, state, "returnedOutput", state.returnedOutput);
6980
+ }
6981
+ state.returnedOutput = true;
6982
+ }
6983
+ } finally {
6984
+ RETURNED_OUTPUT_SCOPE = previous;
6951
6985
  }
6952
6986
  }
6953
6987
  function disposeReturnSlot(block, state) {
6988
+ const kind = state.__kind;
6989
+ const end = (kind === "ifBlockSlot" || kind === "switchBlockSlot") && state.start === null && state.block?.endMarker != null ? state.block.endMarker : state.end;
6954
6990
  const transaction = ROOT_RENDER_TRANSACTION;
6955
6991
  if (transaction !== null && !transaction.aborted && !ROOT_RENDER_ROLLBACK) {
6956
6992
  const parent = state.ownerHost ?? block.parentNode;
6957
6993
  const borrowed = state.inherited === true || state.borrowed === true;
6958
- let first = state.ownerHost != null || borrowed && state.start === null ? getFirstChild(parent) : borrowed ? getNextSibling(state.start) : state.start ?? state.hostNode ?? state.text ?? state.block?.startMarker ?? state.end ?? null;
6959
- if (borrowed && first === state.end) first = null;
6960
- const last = first === null ? null : state.ownerHost != null || borrowed && state.end === null ? (STAGED_DOM?.view(parent) ?? parent).lastChild : borrowed ? domNode(state.end).previousSibling : state.end ?? state.block?.endMarker ?? first;
6994
+ let first = state.ownerHost != null || borrowed && state.start === null ? getFirstChild(parent) : borrowed ? getNextSibling(state.start) : state.start ?? state.hostNode ?? state.text ?? state.block?.startMarker ?? end ?? null;
6995
+ if (borrowed && first === end) first = null;
6996
+ const last = first === null ? null : state.ownerHost != null || borrowed && end === null ? (STAGED_DOM?.view(parent) ?? parent).lastChild : borrowed ? domNode(end).previousSibling : end ?? state.block?.endMarker ?? first;
6961
6997
  journalRootSlot(
6962
6998
  state,
6963
6999
  parent,
6964
7000
  borrowed ? state.start : first !== null ? (STAGED_DOM?.view(first) ?? first).previousSibling : (STAGED_DOM?.view(parent) ?? parent).lastChild,
6965
- borrowed ? state.end : (STAGED_DOM?.view(last) ?? last)?.nextSibling ?? null
7001
+ borrowed ? end : (STAGED_DOM?.view(last) ?? last)?.nextSibling ?? null
6966
7002
  );
6967
7003
  const retiredBlock = state.block ?? state.portal?.block;
6968
7004
  if (retiredBlock != null) retireRootBlock(retiredBlock);
@@ -6985,7 +7021,7 @@ function disposeReturnSlot(block, state) {
6985
7021
  block.slots[0] = void 0;
6986
7022
  return;
6987
7023
  }
6988
- if (state.__kind === "childSlot") {
7024
+ if (kind === "childSlot") {
6989
7025
  if (state.portal) {
6990
7026
  teardownPortalState(state.portal);
6991
7027
  state.portal = null;
@@ -6999,13 +7035,17 @@ function disposeReturnSlot(block, state) {
6999
7035
  clearChildContent(state);
7000
7036
  if (!state.borrowed) {
7001
7037
  domNode(state.start)?.remove();
7002
- domNode(state.end)?.remove();
7038
+ domNode(end)?.remove();
7003
7039
  }
7004
7040
  } else {
7005
- if (state.block) unmountBlock(state.block, true);
7006
- if (!state.inherited) {
7041
+ if (kind === "componentSlotSlot") {
7042
+ if (state.block) unmountBlock(state.block, true);
7043
+ } else {
7044
+ unmountSlot(state, true);
7045
+ }
7046
+ if (!state.inherited && !state.borrowed) {
7007
7047
  domNode(state.start)?.remove?.();
7008
- domNode(state.end)?.remove?.();
7048
+ domNode(end)?.remove?.();
7009
7049
  }
7010
7050
  }
7011
7051
  const reg = block._slots;
@@ -8505,6 +8545,10 @@ function renderSharedBody(body, props, scope, extra) {
8505
8545
  }
8506
8546
  }
8507
8547
  function invalidateSharedBodyOutput(scope) {
8548
+ const state = scope.slots[0];
8549
+ if (scope === scope.block && scope.block.outputHandler !== null && (state?.__kind === "childSlot" || state?.__kind === "componentSlotSlot" || state?.__kind === "ifBlockSlot" || state?.__kind === "switchBlockSlot" || state?.__kind === "activityBlockSlot")) {
8550
+ setReturnedOutputOwner(state, true);
8551
+ }
8508
8552
  const first = scope.compilerMemo;
8509
8553
  if (first === null) return;
8510
8554
  invalidateSharedBodyMemoRegion(first);
@@ -9579,6 +9623,7 @@ function createHydrateSlot(props, scope, boundaryId, boundaryBody) {
9579
9623
  end,
9580
9624
  parentBlock,
9581
9625
  props,
9626
+ contextChanged: false,
9582
9627
  boundaryId: (STAGED_DOM?.view(wrapper) ?? wrapper).getAttribute(import_constants.HYDRATE_ID_ATTR) ?? boundaryId,
9583
9628
  intentBoundary,
9584
9629
  delegatedDynamicIntent: (0, import_event_capture.takeDelegatedDynamicHydrationIntent)(wrapper),
@@ -9898,6 +9943,7 @@ function initializeHydrateComponent(boundaryBody) {
9898
9943
  if (state.independent !== (props.__independent !== void 0)) {
9899
9944
  throw new Error((0, import_error_codes_client_generated.formatClientError)(66));
9900
9945
  }
9946
+ const surroundingUpdate = state.props !== props || state.contextChanged;
9901
9947
  state.props = props;
9902
9948
  if (!state.independent && !state.hydrated) {
9903
9949
  const strategy = resolveHydrateStrategy(state);
@@ -9905,7 +9951,8 @@ function initializeHydrateComponent(boundaryBody) {
9905
9951
  cleanupHydrateStrategy(state);
9906
9952
  invalidateHydrateActivation(state);
9907
9953
  } else if (!state.activationRequested) {
9908
- requestHydrateBoundary(state);
9954
+ const shouldDefer = surroundingUpdate ? false : strategy._d ? strategy._d() : strategy._t !== "load";
9955
+ if (!shouldDefer) requestHydrateBoundary(state);
9909
9956
  }
9910
9957
  }
9911
9958
  }
@@ -18429,6 +18476,18 @@ function componentSlotVoid(parentScope, slotKey, domParent, comp, props, anchor,
18429
18476
  }
18430
18477
  function componentSlotImpl(outputHandler, parentScope, slotKey, domParent, body, identity, props, renderProps, anchor, key, singleRoot, inherit, hasKey, invocationSite) {
18431
18478
  if (CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate) return;
18479
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE) {
18480
+ const state2 = parentScope.slots[0];
18481
+ if (state2?.returnedOutput === true) {
18482
+ if (state2.__kind === "componentSlotSlot") {
18483
+ setReturnedOutputOwner(state2, false);
18484
+ } else {
18485
+ const block = parentScope.block;
18486
+ block.outputHandler(block, null, true);
18487
+ if (block.disposed) return;
18488
+ }
18489
+ }
18490
+ }
18432
18491
  const parentBlock = parentScope.block;
18433
18492
  const hydration = activeHydration();
18434
18493
  if (hydration !== null && (anchor != null && hydration.isFresh(anchor) || hydration.isFresh(domParent))) {
@@ -20670,6 +20729,18 @@ function bindingChildSlot(parentScope, slotKey, domParent, value, marker, anchor
20670
20729
  }
20671
20730
  function childSlot(parentScope, slotKey, domParent, value, anchor, ownEnd, ownsHost, compactable, includeKeyedSingle = true, compiledMapBody, compiledMapKey, compiledMapFlags, compiledMapDeps, mappedFallback, bindingMarker) {
20672
20731
  if (CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate) return;
20732
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE) {
20733
+ const state2 = parentScope.slots[0];
20734
+ if (state2?.returnedOutput === true) {
20735
+ if (state2.__kind === "childSlot") {
20736
+ setReturnedOutputOwner(state2, false);
20737
+ } else {
20738
+ const block = parentScope.block;
20739
+ block.outputHandler(block, null, true);
20740
+ if (block.disposed) return;
20741
+ }
20742
+ }
20743
+ }
20673
20744
  if (IMPLICIT_SIGNAL_CHILD_DEPTH === 0) {
20674
20745
  const existing = parentScope.slots[slotKey];
20675
20746
  const previous = existing?.implicitSignal;
@@ -21298,6 +21369,9 @@ function textSlot(parentScope, slotKey, domParent, value, anchor, ownEnd, compac
21298
21369
  childSlot(parentScope, slotKey, domParent, value, anchor, ownEnd, void 0, compactable);
21299
21370
  return;
21300
21371
  }
21372
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE && state.returnedOutput === true) {
21373
+ setReturnedOutputOwner(state, false);
21374
+ }
21301
21375
  const str = vt === "string" ? value : vt === "boolean" || value == null ? "" : String(value);
21302
21376
  if (state.text !== null) {
21303
21377
  updateTextValue(state.text, str);
@@ -24806,6 +24880,17 @@ function renderBranchSlot(parentScope, slotKey, state, domParent, next, body, ma
24806
24880
  }
24807
24881
  function ifBlock(parentScope, slotKey, domParent, cond, thenBody, elseBody, anchor, env) {
24808
24882
  let state = parentScope.slots[slotKey];
24883
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE && state?.returnedOutput === true) {
24884
+ if (CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate) return;
24885
+ if (state.__kind === "ifBlockSlot") {
24886
+ setReturnedOutputOwner(state, false);
24887
+ } else {
24888
+ const block = parentScope.block;
24889
+ block.outputHandler(block, null, true);
24890
+ if (block.disposed) return;
24891
+ state = void 0;
24892
+ }
24893
+ }
24809
24894
  if (state === void 0) {
24810
24895
  const hydration = activeHydration();
24811
24896
  let start = null;
@@ -25153,6 +25238,18 @@ function queueActivityDeactivation(state, block, commitVersion) {
25153
25238
  }
25154
25239
  function activityBlock(parentScope, slotKey, domParent, mode, body, anchor, env) {
25155
25240
  if (CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate) return;
25241
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE) {
25242
+ const state2 = parentScope.slots[0];
25243
+ if (state2?.returnedOutput === true) {
25244
+ if (state2.__kind === "activityBlockSlot") {
25245
+ setReturnedOutputOwner(state2, false);
25246
+ } else {
25247
+ const block = parentScope.block;
25248
+ block.outputHandler(block, null, true);
25249
+ if (block.disposed) return;
25250
+ }
25251
+ }
25252
+ }
25156
25253
  if (mode === "hidden") ensureScheduledVisibilityDriver();
25157
25254
  const parentBlock = parentScope.block;
25158
25255
  const hydration = activeHydration();
@@ -25409,6 +25506,17 @@ function deactivateScope(scope, disconnectPassive = true) {
25409
25506
  }
25410
25507
  function switchBlock(parentScope, slotKey, domParent, discriminant, cases, defaultBody, anchor, env) {
25411
25508
  let state = parentScope.slots[slotKey];
25509
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE && state?.returnedOutput === true) {
25510
+ if (CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate) return;
25511
+ if (state.__kind === "switchBlockSlot") {
25512
+ setReturnedOutputOwner(state, false);
25513
+ } else {
25514
+ const block = parentScope.block;
25515
+ block.outputHandler(block, null, true);
25516
+ if (block.disposed) return;
25517
+ state = void 0;
25518
+ }
25519
+ }
25412
25520
  if (state === void 0) {
25413
25521
  const hydration = activeHydration();
25414
25522
  let start = null;
@@ -25798,7 +25906,8 @@ function fastMapSlot(scopeOrItems, slotOrMethod, domParent, items, method, nativ
25798
25906
  callback = native;
25799
25907
  native = mapSlot(items, method);
25800
25908
  }
25801
- const state = scopeOrItems.slots[slotOrMethod]?.forSlot;
25909
+ const slot = scopeOrItems.slots[slotOrMethod];
25910
+ const state = slot?.forSlot;
25802
25911
  const parent = native === true ? fastHostListParent(state, items, flags) : null;
25803
25912
  if (parent === null) {
25804
25913
  return mapSlot(
@@ -25817,6 +25926,9 @@ function fastMapSlot(scopeOrItems, slotOrMethod, domParent, items, method, nativ
25817
25926
  ownEnd
25818
25927
  );
25819
25928
  }
25929
+ if (slotOrMethod === 0 && scopeOrItems !== RETURNED_OUTPUT_SCOPE && slot.returnedOutput === true) {
25930
+ setReturnedOutputOwner(slot, false);
25931
+ }
25820
25932
  mountFastHostItems(
25821
25933
  scopeOrItems,
25822
25934
  state,
@@ -26734,6 +26846,10 @@ function moveFocusedNodeBefore(parent, node, anchor, snapshots) {
26734
26846
  moveBefore.call(parent, node, anchor);
26735
26847
  return;
26736
26848
  }
26849
+ if (STAGED_DOM.view(node).parentNode !== parent || anchor !== null && STAGED_DOM.view(anchor).parentNode !== parent) {
26850
+ STAGED_DOM.view(parent).insertBefore(node, anchor);
26851
+ return;
26852
+ }
26737
26853
  if (node === anchor || getNextSibling(node) === anchor) return;
26738
26854
  if (anchor === null || ((STAGED_DOM?.view(node) ?? node).compareDocumentPosition(anchor) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0) {
26739
26855
  let cursor = getNextSibling(node);
@@ -21,7 +21,7 @@ __export(version_exports, {
21
21
  version: () => version
22
22
  });
23
23
  module.exports = __toCommonJS(version_exports);
24
- const version = "0.3.3";
24
+ const version = "0.3.5";
25
25
  // Annotate the CommonJS export names for ESM import in node:
26
26
  0 && (module.exports = {
27
27
  version
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Move native presentation without detaching the node that owns active editing.
2
+ * Move native presentation without detaching active editing when possible.
3
3
  * Both the general renderer and renderer-free keyed views use this leaf; callers
4
4
  * retain their own focus/selection capture and commit lifetime.
5
5
  */
@@ -19,6 +19,10 @@ function moveNativeNodeBefore(parent, node, anchor, focused, contentEditable) {
19
19
  moveBefore.call(parent, node, anchor);
20
20
  return;
21
21
  }
22
+ if (node.parentNode !== parent || anchor !== null && anchor.parentNode !== parent) {
23
+ parent.insertBefore(node, anchor);
24
+ return;
25
+ }
22
26
  if (node === anchor || node.nextSibling === anchor) return;
23
27
  if (anchor === null || (node.compareDocumentPosition(anchor) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0) {
24
28
  let cursor = node.nextSibling;
@@ -29,6 +29,7 @@ interface ResultState {
29
29
  values: number;
30
30
  terminal: boolean;
31
31
  frames: StreamedSignalResultFrame[];
32
+ frameSizes: number[];
32
33
  bytes: number;
33
34
  consumer?: StreamedResultConsumer;
34
35
  timer?: ReturnType<typeof setTimeout>;
@@ -14,6 +14,7 @@ class StreamedReceiverError extends Error {
14
14
  function retainCompletedResult(result) {
15
15
  if (result.frames.at(-1)?.kind === "complete" && result.consumer?.retainCompleted?.(result.frames) === true) {
16
16
  result.frames = [];
17
+ result.frameSizes.length = 0;
17
18
  result.bytes = 0;
18
19
  }
19
20
  }
@@ -54,6 +55,7 @@ function createStreamedResultReceiverState(options, commitPlacement) {
54
55
  } catch {
55
56
  }
56
57
  state.result.frames.length = 0;
58
+ state.result.frameSizes.length = 0;
57
59
  state.result.bytes = 0;
58
60
  }
59
61
  if (state.result.timer !== void 0) clearTimeout(state.result.timer);
@@ -96,7 +98,15 @@ function createStreamedResultReceiverState(options, commitPlacement) {
96
98
  }
97
99
  const state = {
98
100
  identity,
99
- result: { sequence: 0, opened: false, values: 0, terminal: false, frames: [], bytes: 0 },
101
+ result: {
102
+ sequence: 0,
103
+ opened: false,
104
+ values: 0,
105
+ terminal: false,
106
+ frames: [],
107
+ frameSizes: [],
108
+ bytes: 0
109
+ },
100
110
  placementSequence: 0,
101
111
  contentRevision
102
112
  };
@@ -128,10 +138,11 @@ function createStreamedResultReceiverState(options, commitPlacement) {
128
138
  if (accepted === state.result.frames.length) state.result.bytes = 0;
129
139
  else {
130
140
  for (let index = 0; index < accepted; index++) {
131
- state.result.bytes -= frameBytes(state.result.frames[index]);
141
+ state.result.bytes -= state.result.frameSizes[index];
132
142
  }
133
143
  }
134
144
  state.result.frames.splice(0, accepted);
145
+ state.result.frameSizes.splice(0, accepted);
135
146
  }
136
147
  retainCompletedResult(state.result);
137
148
  return () => {
@@ -174,6 +185,7 @@ function createStreamedResultReceiverState(options, commitPlacement) {
174
185
  throw new StreamedReceiverError("overflow", "Streamed result mailbox exceeded its bound.");
175
186
  }
176
187
  result.frames.push(frame);
188
+ result.frameSizes.push(bytes);
177
189
  result.bytes += bytes;
178
190
  }
179
191
  if (frame.kind === "complete" || frame.kind === "error") {
package/dist/runtime.d.ts CHANGED
@@ -210,7 +210,7 @@ export declare function finishNativeReadWitness(token: number, completed: boolea
210
210
  export declare function replayNativeReadWitness(witness: NativeReadWitness | null | undefined): void;
211
211
  export declare function hookSlots(count: number): number;
212
212
  type BlockKind = 'root' | 'control-flow' | 'dynamic' | 'portal';
213
- type OutputHandler = (block: Block, value: unknown) => void;
213
+ type OutputHandler = (block: Block, value: unknown, reset?: true) => void;
214
214
  interface RootIdState {
215
215
  prefix: string;
216
216
  next: number;
package/dist/runtime.js CHANGED
@@ -6592,7 +6592,13 @@ function renderBlockInner(block) {
6592
6592
  block.__thenableDone = false;
6593
6593
  }
6594
6594
  if (block.$$ctxReads !== null) block.$$ctxReads.clear();
6595
- if (block.$$ctxDirect !== null) block.$$ctxDirect.clear();
6595
+ if (block.$$ctxDirect !== null) {
6596
+ const state = block.slots[0];
6597
+ if (state?.__kind === "hydrateBlockSlot" && state.parentBlock === block && !state.independent && !state.hydrated) {
6598
+ state.contextChanged = block.$$ctxDepsEpoch !== contextEpochNow() && ctxDirectChanged(block);
6599
+ }
6600
+ block.$$ctxDirect.clear();
6601
+ }
6596
6602
  block.$$ctxDepsEpoch = contextEpochNow();
6597
6603
  block.currentRenderMode = urgentTransitionRender !== null ? "urgent" : block.pendingMode ?? prevBlock?.currentRenderMode ?? "urgent";
6598
6604
  block.currentRenderDeferred = urgentTransitionRender !== null ? false : block.pendingMode !== null ? block.pendingDeferred : prevBlock?.currentRenderDeferred ?? false;
@@ -6617,7 +6623,9 @@ function renderBlockInner(block) {
6617
6623
  renderRetry = true;
6618
6624
  return true;
6619
6625
  }
6620
- if (out !== void 0 && block.outputHandler !== null) block.outputHandler(block, out);
6626
+ if (block.outputHandler !== null && (out !== void 0 || block.slots[0]?.returnedOutput === true)) {
6627
+ block.outputHandler(block, out ?? null);
6628
+ }
6621
6629
  finishEffectRender(block);
6622
6630
  if (!block.mounted) block.mounted = true;
6623
6631
  if (block.renderStatus === RENDER_RETRYING) block.renderStatus = RENDER_VALID;
@@ -6676,6 +6684,14 @@ function renderBlockInner(block) {
6676
6684
  }
6677
6685
  }
6678
6686
  }
6687
+ let RETURNED_OUTPUT_SCOPE = null;
6688
+ function setReturnedOutputOwner(state, returned) {
6689
+ if (state.returnedOutput === returned) return;
6690
+ if (TRANSITION_JOURNAL !== null && !ROOT_RENDER_ROLLBACK) {
6691
+ TRANSITION_JOURNAL.push(JOURNAL_PROP, state, "returnedOutput", state.returnedOutput);
6692
+ }
6693
+ state.returnedOutput = returned;
6694
+ }
6679
6695
  function returnSlotTail(block, state) {
6680
6696
  const candidates = [
6681
6697
  state?.end,
@@ -6692,59 +6708,82 @@ function returnSlotTail(block, state) {
6692
6708
  }
6693
6709
  return null;
6694
6710
  }
6695
- function renderReturnedValue(block, out) {
6696
- const isComponentDescriptor = out !== null && out.$$kind === ELEMENT_TAG && out.key == null && typeof out.type === "function";
6697
- const existingRet = block.slots[0];
6698
- let replacedStart = null;
6699
- let replacedEnd = null;
6700
- const useSingleRoot = isComponentDescriptor && (out.type.$$singleRoot === true || activeHydration()?.passthroughRanges === true || // STICKY regime: a return slot mounted through the componentSlot route
6701
- // (most importantly by the passthrough-hydration branch above, whose
6702
- // condition is false again once hydration ends) keeps that route while
6703
- // the returned component identity is unchanged. Falling through to the
6704
- // childSlot route would dispose the slot for a mere kind flip — tearing
6705
- // down the very subtree hydration just adopted on its FIRST update. An
6706
- // identity change still disposes below (matching remount semantics).
6707
- existingRet !== void 0 && existingRet.__kind === "componentSlotSlot" && existingRet.currentComp === out.type);
6708
- if (existingRet !== void 0 && existingRet.__kind !== (useSingleRoot ? "componentSlotSlot" : "childSlot")) {
6709
- const swapDriver = TRANSITION_SWAP_DRIVER;
6710
- const transitionMode = block.currentRenderMode === "transition";
6711
- const committedSuspense = swapDriver !== null && activeHydration() === null && preservesCommittedSuspense(block);
6712
- const transitionSwap = ROOT_RENDER_TRANSACTION === null || committedSuspense ? swapDriver : null;
6713
- const suspenseSwap = transitionSwap !== null && !transitionMode && activeHydration() === null && committedSuspense;
6714
- if (transitionSwap !== null && activeHydration() === null && (transitionMode || suspenseSwap)) {
6715
- const tail = returnSlotTail(block, existingRet);
6716
- if (tail !== null) {
6717
- const probe = transitionSwap.render(
6718
- block,
6719
- block.parentNode,
6720
- tail,
6721
- ROOT_RENDERABLE_BODY,
6722
- out,
6723
- renderReturnedValue
6724
- );
6725
- transitionSwap.dispose(probe.wip);
6726
- if (probe.failed) throw probe.error;
6727
- if (probe.suspended) throw new SuspenseException(probe.suspended);
6728
- }
6711
+ function renderReturnedValue(block, out, reset) {
6712
+ const previous = RETURNED_OUTPUT_SCOPE;
6713
+ RETURNED_OUTPUT_SCOPE = block;
6714
+ try {
6715
+ if (reset === true) {
6716
+ const state2 = block.slots[0];
6717
+ if (state2 !== void 0) disposeReturnSlot(block, state2);
6718
+ return;
6729
6719
  }
6730
- if (ROOT_RENDER_TRANSACTION !== null && !existingRet.inherited && !existingRet.borrowed && existingRet.ownerHost == null) {
6731
- const first = existingRet.start ?? existingRet.hostNode ?? existingRet.text ?? existingRet.block?.startMarker ?? existingRet.end ?? null;
6732
- const last = existingRet.end ?? existingRet.block?.endMarker ?? first;
6733
- if (sharesBlockBoundary(block, first, last)) {
6734
- replacedStart = first;
6735
- replacedEnd = last;
6720
+ const isComponentDescriptor = out !== null && out.$$kind === ELEMENT_TAG && out.key == null && typeof out.type === "function";
6721
+ const existingRet = block.slots[0];
6722
+ let replacedStart = null;
6723
+ let replacedEnd = null;
6724
+ const useSingleRoot = isComponentDescriptor && (out.type.$$singleRoot === true || activeHydration()?.passthroughRanges === true || // STICKY regime: a return slot mounted through the componentSlot route
6725
+ // (most importantly by the passthrough-hydration branch above, whose
6726
+ // condition is false again once hydration ends) keeps that route while
6727
+ // the returned component identity is unchanged. Falling through to the
6728
+ // childSlot route would dispose the slot for a mere kind flip — tearing
6729
+ // down the very subtree hydration just adopted on its FIRST update. An
6730
+ // identity change still disposes below (matching remount semantics).
6731
+ existingRet !== void 0 && existingRet.__kind === "componentSlotSlot" && existingRet.currentComp === out.type);
6732
+ if (existingRet !== void 0 && existingRet.__kind !== (useSingleRoot ? "componentSlotSlot" : "childSlot")) {
6733
+ const swapDriver = TRANSITION_SWAP_DRIVER;
6734
+ const transitionMode = block.currentRenderMode === "transition";
6735
+ const committedSuspense = swapDriver !== null && activeHydration() === null && preservesCommittedSuspense(block);
6736
+ const transitionSwap = ROOT_RENDER_TRANSACTION === null || committedSuspense ? swapDriver : null;
6737
+ const suspenseSwap = transitionSwap !== null && !transitionMode && activeHydration() === null && committedSuspense;
6738
+ if (transitionSwap !== null && activeHydration() === null && (transitionMode || suspenseSwap)) {
6739
+ const tail = returnSlotTail(block, existingRet);
6740
+ if (tail !== null) {
6741
+ const probe = transitionSwap.render(
6742
+ block,
6743
+ block.parentNode,
6744
+ tail,
6745
+ ROOT_RENDERABLE_BODY,
6746
+ out,
6747
+ renderReturnedValue
6748
+ );
6749
+ transitionSwap.dispose(probe.wip);
6750
+ if (probe.failed) throw probe.error;
6751
+ if (probe.suspended) throw new SuspenseException(probe.suspended);
6752
+ }
6753
+ }
6754
+ if (ROOT_RENDER_TRANSACTION !== null && !existingRet.inherited && !existingRet.borrowed && existingRet.ownerHost == null) {
6755
+ const first = existingRet.start ?? existingRet.hostNode ?? existingRet.text ?? existingRet.block?.startMarker ?? existingRet.end ?? null;
6756
+ const last = existingRet.end ?? existingRet.block?.endMarker ?? first;
6757
+ if (sharesBlockBoundary(block, first, last)) {
6758
+ replacedStart = first;
6759
+ replacedEnd = last;
6760
+ }
6736
6761
  }
6762
+ disposeReturnSlot(block, existingRet);
6763
+ if (block.disposed) return;
6737
6764
  }
6738
- disposeReturnSlot(block, existingRet);
6739
- if (block.disposed) return;
6740
- }
6741
- if (useSingleRoot) {
6742
- const d = out;
6743
- if (typeof __OCTANE_PROFILE_ENABLED__ !== "undefined" && __OCTANE_PROFILE_ENABLED__ && !__profileHasComponentMetadata(d.type)) {
6744
- withProfileComponentOverride(
6745
- d.type,
6746
- null,
6747
- () => componentSlot(
6765
+ if (useSingleRoot) {
6766
+ const d = out;
6767
+ if (typeof __OCTANE_PROFILE_ENABLED__ !== "undefined" && __OCTANE_PROFILE_ENABLED__ && !__profileHasComponentMetadata(d.type)) {
6768
+ withProfileComponentOverride(
6769
+ d.type,
6770
+ null,
6771
+ () => componentSlot(
6772
+ block,
6773
+ 0,
6774
+ block.parentNode,
6775
+ d.type,
6776
+ d.props,
6777
+ block.endMarker,
6778
+ d.key ?? void 0,
6779
+ true,
6780
+ void 0,
6781
+ activeHydration() !== null && elementKeyWasProvided(d),
6782
+ d.__octaneInvocationSite
6783
+ )
6784
+ );
6785
+ } else {
6786
+ componentSlot(
6748
6787
  block,
6749
6788
  0,
6750
6789
  block.parentNode,
@@ -6756,66 +6795,63 @@ function renderReturnedValue(block, out) {
6756
6795
  void 0,
6757
6796
  activeHydration() !== null && elementKeyWasProvided(d),
6758
6797
  d.__octaneInvocationSite
6759
- )
6760
- );
6798
+ );
6799
+ }
6761
6800
  } else {
6762
- componentSlot(
6763
- block,
6764
- 0,
6765
- block.parentNode,
6766
- d.type,
6767
- d.props,
6768
- block.endMarker,
6769
- d.key ?? void 0,
6770
- true,
6771
- void 0,
6772
- activeHydration() !== null && elementKeyWasProvided(d),
6773
- d.__octaneInvocationSite
6774
- );
6801
+ const returnHydration = activeHydration();
6802
+ if (returnHydration !== null && block.slots[0] === void 0 && block.startMarker !== null && block.endMarker !== null && block.startMarker !== block.endMarker && block.startMarker.nodeType === 8 && block.endMarker.nodeType === 8 && (getNextSibling(block.startMarker) === block.endMarker || returnHydration.isUnframedRootRange(block.startMarker, block.endMarker))) {
6803
+ const borrowed = {
6804
+ __kind: "childSlot",
6805
+ start: block.startMarker,
6806
+ end: block.endMarker,
6807
+ ownerHost: null,
6808
+ borrowed: true,
6809
+ compactable: false,
6810
+ block: null,
6811
+ text: null,
6812
+ currentComp: null,
6813
+ currentIsBodyFn: false,
6814
+ forSlot: null,
6815
+ hostNode: null,
6816
+ portal: null
6817
+ };
6818
+ block.slots[0] = borrowed;
6819
+ registerSlot(block, borrowed);
6820
+ }
6821
+ childSlot(block, 0, block.parentNode, out, block.endMarker);
6775
6822
  }
6776
- } else {
6777
- const returnHydration = activeHydration();
6778
- if (returnHydration !== null && block.slots[0] === void 0 && block.startMarker !== null && block.endMarker !== null && block.startMarker !== block.endMarker && block.startMarker.nodeType === 8 && block.endMarker.nodeType === 8 && (getNextSibling(block.startMarker) === block.endMarker || returnHydration.isUnframedRootRange(block.startMarker, block.endMarker))) {
6779
- const borrowed = {
6780
- __kind: "childSlot",
6781
- start: block.startMarker,
6782
- end: block.endMarker,
6783
- ownerHost: null,
6784
- borrowed: true,
6785
- compactable: false,
6786
- block: null,
6787
- text: null,
6788
- currentComp: null,
6789
- currentIsBodyFn: false,
6790
- forSlot: null,
6791
- hostNode: null,
6792
- portal: null
6793
- };
6794
- block.slots[0] = borrowed;
6795
- registerSlot(block, borrowed);
6823
+ if (replacedStart !== null) {
6824
+ const incoming = block.slots[0];
6825
+ const first = incoming.start ?? incoming.hostNode ?? incoming.text ?? incoming.block?.startMarker ?? incoming.end ?? null;
6826
+ const last = incoming.end ?? incoming.block?.endMarker ?? first;
6827
+ replaceSharedBlockBoundary(block, replacedStart, replacedEnd, first, last);
6796
6828
  }
6797
- childSlot(block, 0, block.parentNode, out, block.endMarker);
6798
- }
6799
- if (replacedStart !== null) {
6800
- const incoming = block.slots[0];
6801
- const first = incoming.start ?? incoming.hostNode ?? incoming.text ?? incoming.block?.startMarker ?? incoming.end ?? null;
6802
- const last = incoming.end ?? incoming.block?.endMarker ?? first;
6803
- replaceSharedBlockBoundary(block, replacedStart, replacedEnd, first, last);
6829
+ const state = block.slots[0];
6830
+ if (!block.disposed && state !== void 0 && state.returnedOutput !== true) {
6831
+ if (TRANSITION_JOURNAL !== null && !ROOT_RENDER_ROLLBACK) {
6832
+ TRANSITION_JOURNAL.push(JOURNAL_PROP, state, "returnedOutput", state.returnedOutput);
6833
+ }
6834
+ state.returnedOutput = true;
6835
+ }
6836
+ } finally {
6837
+ RETURNED_OUTPUT_SCOPE = previous;
6804
6838
  }
6805
6839
  }
6806
6840
  function disposeReturnSlot(block, state) {
6841
+ const kind = state.__kind;
6842
+ const end = (kind === "ifBlockSlot" || kind === "switchBlockSlot") && state.start === null && state.block?.endMarker != null ? state.block.endMarker : state.end;
6807
6843
  const transaction = ROOT_RENDER_TRANSACTION;
6808
6844
  if (transaction !== null && !transaction.aborted && !ROOT_RENDER_ROLLBACK) {
6809
6845
  const parent = state.ownerHost ?? block.parentNode;
6810
6846
  const borrowed = state.inherited === true || state.borrowed === true;
6811
- let first = state.ownerHost != null || borrowed && state.start === null ? getFirstChild(parent) : borrowed ? getNextSibling(state.start) : state.start ?? state.hostNode ?? state.text ?? state.block?.startMarker ?? state.end ?? null;
6812
- if (borrowed && first === state.end) first = null;
6813
- const last = first === null ? null : state.ownerHost != null || borrowed && state.end === null ? (STAGED_DOM?.view(parent) ?? parent).lastChild : borrowed ? domNode(state.end).previousSibling : state.end ?? state.block?.endMarker ?? first;
6847
+ let first = state.ownerHost != null || borrowed && state.start === null ? getFirstChild(parent) : borrowed ? getNextSibling(state.start) : state.start ?? state.hostNode ?? state.text ?? state.block?.startMarker ?? end ?? null;
6848
+ if (borrowed && first === end) first = null;
6849
+ const last = first === null ? null : state.ownerHost != null || borrowed && end === null ? (STAGED_DOM?.view(parent) ?? parent).lastChild : borrowed ? domNode(end).previousSibling : end ?? state.block?.endMarker ?? first;
6814
6850
  journalRootSlot(
6815
6851
  state,
6816
6852
  parent,
6817
6853
  borrowed ? state.start : first !== null ? (STAGED_DOM?.view(first) ?? first).previousSibling : (STAGED_DOM?.view(parent) ?? parent).lastChild,
6818
- borrowed ? state.end : (STAGED_DOM?.view(last) ?? last)?.nextSibling ?? null
6854
+ borrowed ? end : (STAGED_DOM?.view(last) ?? last)?.nextSibling ?? null
6819
6855
  );
6820
6856
  const retiredBlock = state.block ?? state.portal?.block;
6821
6857
  if (retiredBlock != null) retireRootBlock(retiredBlock);
@@ -6838,7 +6874,7 @@ function disposeReturnSlot(block, state) {
6838
6874
  block.slots[0] = void 0;
6839
6875
  return;
6840
6876
  }
6841
- if (state.__kind === "childSlot") {
6877
+ if (kind === "childSlot") {
6842
6878
  if (state.portal) {
6843
6879
  teardownPortalState(state.portal);
6844
6880
  state.portal = null;
@@ -6852,13 +6888,17 @@ function disposeReturnSlot(block, state) {
6852
6888
  clearChildContent(state);
6853
6889
  if (!state.borrowed) {
6854
6890
  domNode(state.start)?.remove();
6855
- domNode(state.end)?.remove();
6891
+ domNode(end)?.remove();
6856
6892
  }
6857
6893
  } else {
6858
- if (state.block) unmountBlock(state.block, true);
6859
- if (!state.inherited) {
6894
+ if (kind === "componentSlotSlot") {
6895
+ if (state.block) unmountBlock(state.block, true);
6896
+ } else {
6897
+ unmountSlot(state, true);
6898
+ }
6899
+ if (!state.inherited && !state.borrowed) {
6860
6900
  domNode(state.start)?.remove?.();
6861
- domNode(state.end)?.remove?.();
6901
+ domNode(end)?.remove?.();
6862
6902
  }
6863
6903
  }
6864
6904
  const reg = block._slots;
@@ -8358,6 +8398,10 @@ function renderSharedBody(body, props, scope, extra) {
8358
8398
  }
8359
8399
  }
8360
8400
  function invalidateSharedBodyOutput(scope) {
8401
+ const state = scope.slots[0];
8402
+ if (scope === scope.block && scope.block.outputHandler !== null && (state?.__kind === "childSlot" || state?.__kind === "componentSlotSlot" || state?.__kind === "ifBlockSlot" || state?.__kind === "switchBlockSlot" || state?.__kind === "activityBlockSlot")) {
8403
+ setReturnedOutputOwner(state, true);
8404
+ }
8361
8405
  const first = scope.compilerMemo;
8362
8406
  if (first === null) return;
8363
8407
  invalidateSharedBodyMemoRegion(first);
@@ -9432,6 +9476,7 @@ function createHydrateSlot(props, scope, boundaryId, boundaryBody) {
9432
9476
  end,
9433
9477
  parentBlock,
9434
9478
  props,
9479
+ contextChanged: false,
9435
9480
  boundaryId: (STAGED_DOM?.view(wrapper) ?? wrapper).getAttribute(HYDRATE_ID_ATTR) ?? boundaryId,
9436
9481
  intentBoundary,
9437
9482
  delegatedDynamicIntent: takeDelegatedDynamicHydrationIntent(wrapper),
@@ -9751,6 +9796,7 @@ function initializeHydrateComponent(boundaryBody) {
9751
9796
  if (state.independent !== (props.__independent !== void 0)) {
9752
9797
  throw new Error(formatClientError(66));
9753
9798
  }
9799
+ const surroundingUpdate = state.props !== props || state.contextChanged;
9754
9800
  state.props = props;
9755
9801
  if (!state.independent && !state.hydrated) {
9756
9802
  const strategy = resolveHydrateStrategy(state);
@@ -9758,7 +9804,8 @@ function initializeHydrateComponent(boundaryBody) {
9758
9804
  cleanupHydrateStrategy(state);
9759
9805
  invalidateHydrateActivation(state);
9760
9806
  } else if (!state.activationRequested) {
9761
- requestHydrateBoundary(state);
9807
+ const shouldDefer = surroundingUpdate ? false : strategy._d ? strategy._d() : strategy._t !== "load";
9808
+ if (!shouldDefer) requestHydrateBoundary(state);
9762
9809
  }
9763
9810
  }
9764
9811
  }
@@ -18291,6 +18338,18 @@ function componentSlotVoid(parentScope, slotKey, domParent, comp, props, anchor,
18291
18338
  }
18292
18339
  function componentSlotImpl(outputHandler, parentScope, slotKey, domParent, body, identity, props, renderProps, anchor, key, singleRoot, inherit, hasKey, invocationSite) {
18293
18340
  if (CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate) return;
18341
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE) {
18342
+ const state2 = parentScope.slots[0];
18343
+ if (state2?.returnedOutput === true) {
18344
+ if (state2.__kind === "componentSlotSlot") {
18345
+ setReturnedOutputOwner(state2, false);
18346
+ } else {
18347
+ const block = parentScope.block;
18348
+ block.outputHandler(block, null, true);
18349
+ if (block.disposed) return;
18350
+ }
18351
+ }
18352
+ }
18294
18353
  const parentBlock = parentScope.block;
18295
18354
  const hydration = activeHydration();
18296
18355
  if (hydration !== null && (anchor != null && hydration.isFresh(anchor) || hydration.isFresh(domParent))) {
@@ -20532,6 +20591,18 @@ function bindingChildSlot(parentScope, slotKey, domParent, value, marker, anchor
20532
20591
  }
20533
20592
  function childSlot(parentScope, slotKey, domParent, value, anchor, ownEnd, ownsHost, compactable, includeKeyedSingle = true, compiledMapBody, compiledMapKey, compiledMapFlags, compiledMapDeps, mappedFallback, bindingMarker) {
20534
20593
  if (CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate) return;
20594
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE) {
20595
+ const state2 = parentScope.slots[0];
20596
+ if (state2?.returnedOutput === true) {
20597
+ if (state2.__kind === "childSlot") {
20598
+ setReturnedOutputOwner(state2, false);
20599
+ } else {
20600
+ const block = parentScope.block;
20601
+ block.outputHandler(block, null, true);
20602
+ if (block.disposed) return;
20603
+ }
20604
+ }
20605
+ }
20535
20606
  if (IMPLICIT_SIGNAL_CHILD_DEPTH === 0) {
20536
20607
  const existing = parentScope.slots[slotKey];
20537
20608
  const previous = existing?.implicitSignal;
@@ -21160,6 +21231,9 @@ function textSlot(parentScope, slotKey, domParent, value, anchor, ownEnd, compac
21160
21231
  childSlot(parentScope, slotKey, domParent, value, anchor, ownEnd, void 0, compactable);
21161
21232
  return;
21162
21233
  }
21234
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE && state.returnedOutput === true) {
21235
+ setReturnedOutputOwner(state, false);
21236
+ }
21163
21237
  const str = vt === "string" ? value : vt === "boolean" || value == null ? "" : String(value);
21164
21238
  if (state.text !== null) {
21165
21239
  updateTextValue(state.text, str);
@@ -24668,6 +24742,17 @@ function renderBranchSlot(parentScope, slotKey, state, domParent, next, body, ma
24668
24742
  }
24669
24743
  function ifBlock(parentScope, slotKey, domParent, cond, thenBody, elseBody, anchor, env) {
24670
24744
  let state = parentScope.slots[slotKey];
24745
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE && state?.returnedOutput === true) {
24746
+ if (CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate) return;
24747
+ if (state.__kind === "ifBlockSlot") {
24748
+ setReturnedOutputOwner(state, false);
24749
+ } else {
24750
+ const block = parentScope.block;
24751
+ block.outputHandler(block, null, true);
24752
+ if (block.disposed) return;
24753
+ state = void 0;
24754
+ }
24755
+ }
24671
24756
  if (state === void 0) {
24672
24757
  const hydration = activeHydration();
24673
24758
  let start = null;
@@ -25015,6 +25100,18 @@ function queueActivityDeactivation(state, block, commitVersion) {
25015
25100
  }
25016
25101
  function activityBlock(parentScope, slotKey, domParent, mode, body, anchor, env) {
25017
25102
  if (CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate) return;
25103
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE) {
25104
+ const state2 = parentScope.slots[0];
25105
+ if (state2?.returnedOutput === true) {
25106
+ if (state2.__kind === "activityBlockSlot") {
25107
+ setReturnedOutputOwner(state2, false);
25108
+ } else {
25109
+ const block = parentScope.block;
25110
+ block.outputHandler(block, null, true);
25111
+ if (block.disposed) return;
25112
+ }
25113
+ }
25114
+ }
25018
25115
  if (mode === "hidden") ensureScheduledVisibilityDriver();
25019
25116
  const parentBlock = parentScope.block;
25020
25117
  const hydration = activeHydration();
@@ -25271,6 +25368,17 @@ function deactivateScope(scope, disconnectPassive = true) {
25271
25368
  }
25272
25369
  function switchBlock(parentScope, slotKey, domParent, discriminant, cases, defaultBody, anchor, env) {
25273
25370
  let state = parentScope.slots[slotKey];
25371
+ if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE && state?.returnedOutput === true) {
25372
+ if (CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate) return;
25373
+ if (state.__kind === "switchBlockSlot") {
25374
+ setReturnedOutputOwner(state, false);
25375
+ } else {
25376
+ const block = parentScope.block;
25377
+ block.outputHandler(block, null, true);
25378
+ if (block.disposed) return;
25379
+ state = void 0;
25380
+ }
25381
+ }
25274
25382
  if (state === void 0) {
25275
25383
  const hydration = activeHydration();
25276
25384
  let start = null;
@@ -25660,7 +25768,8 @@ function fastMapSlot(scopeOrItems, slotOrMethod, domParent, items, method, nativ
25660
25768
  callback = native;
25661
25769
  native = mapSlot(items, method);
25662
25770
  }
25663
- const state = scopeOrItems.slots[slotOrMethod]?.forSlot;
25771
+ const slot = scopeOrItems.slots[slotOrMethod];
25772
+ const state = slot?.forSlot;
25664
25773
  const parent = native === true ? fastHostListParent(state, items, flags) : null;
25665
25774
  if (parent === null) {
25666
25775
  return mapSlot(
@@ -25679,6 +25788,9 @@ function fastMapSlot(scopeOrItems, slotOrMethod, domParent, items, method, nativ
25679
25788
  ownEnd
25680
25789
  );
25681
25790
  }
25791
+ if (slotOrMethod === 0 && scopeOrItems !== RETURNED_OUTPUT_SCOPE && slot.returnedOutput === true) {
25792
+ setReturnedOutputOwner(slot, false);
25793
+ }
25682
25794
  mountFastHostItems(
25683
25795
  scopeOrItems,
25684
25796
  state,
@@ -26596,6 +26708,10 @@ function moveFocusedNodeBefore(parent, node, anchor, snapshots) {
26596
26708
  moveBefore.call(parent, node, anchor);
26597
26709
  return;
26598
26710
  }
26711
+ if (STAGED_DOM.view(node).parentNode !== parent || anchor !== null && STAGED_DOM.view(anchor).parentNode !== parent) {
26712
+ STAGED_DOM.view(parent).insertBefore(node, anchor);
26713
+ return;
26714
+ }
26599
26715
  if (node === anchor || getNextSibling(node) === anchor) return;
26600
26716
  if (anchor === null || ((STAGED_DOM?.view(node) ?? node).compareDocumentPosition(anchor) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0) {
26601
26717
  let cursor = getNextSibling(node);
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = "0.3.3";
1
+ const version = "0.3.5";
2
2
  export {
3
3
  version
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "octane",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": [