octane 0.13.5 → 0.13.7

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.
Files changed (49) hide show
  1. package/README.md +35 -0
  2. package/dist/cjs/dom-bindings.cjs +11 -24
  3. package/dist/cjs/error-codes.client.generated.cjs +12 -0
  4. package/dist/cjs/error-codes.server.generated.cjs +12 -0
  5. package/dist/cjs/index.cjs +6 -0
  6. package/dist/cjs/runtime.cjs +139 -57
  7. package/dist/cjs/runtime.server.cjs +56 -4
  8. package/dist/cjs/server/index.cjs +6 -0
  9. package/dist/cjs/signals/native-read-seeds.cjs +4 -2
  10. package/dist/cjs/version.cjs +1 -1
  11. package/dist/compiler/bundler.js +20 -0
  12. package/dist/compiler/compile.js +104 -54
  13. package/dist/compiler/parser-template-shape.js +13 -1
  14. package/dist/compiler/strong-diagnostics.js +81 -61
  15. package/dist/compiler/strong-html.js +5 -5
  16. package/dist/compiler/strong-mode.js +14 -0
  17. package/dist/compiler/strong-template-policy.js +89 -59
  18. package/dist/dom-binding-program.d.ts +1 -2
  19. package/dist/dom-binding-program.js +8 -23
  20. package/dist/dom-bindings.d.ts +2 -2
  21. package/dist/dom-bindings.js +11 -24
  22. package/dist/error-codes.client.generated.d.ts +3 -0
  23. package/dist/error-codes.client.generated.js +12 -0
  24. package/dist/error-codes.server.generated.d.ts +3 -0
  25. package/dist/error-codes.server.generated.js +12 -0
  26. package/dist/hydration/streamed-signals.js +2 -2
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +6 -0
  29. package/dist/node/dom-binding-program.js +8 -23
  30. package/dist/node/dom-bindings.js +11 -24
  31. package/dist/node/error-codes.client.generated.js +12 -0
  32. package/dist/node/error-codes.server.generated.js +12 -0
  33. package/dist/node/hydration/streamed-signals.js +2 -2
  34. package/dist/node/index.js +6 -0
  35. package/dist/node/runtime.js +136 -57
  36. package/dist/node/runtime.server.js +53 -4
  37. package/dist/node/server/index.js +6 -0
  38. package/dist/node/signals/native-read-seeds.js +2 -1
  39. package/dist/node/version.js +1 -1
  40. package/dist/runtime.d.ts +28 -1
  41. package/dist/runtime.js +136 -57
  42. package/dist/runtime.server.d.ts +12 -1
  43. package/dist/runtime.server.js +53 -4
  44. package/dist/server/index.d.ts +2 -1
  45. package/dist/server/index.js +6 -0
  46. package/dist/signals/native-read-seeds.d.ts +1 -0
  47. package/dist/signals/native-read-seeds.js +2 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +1 -1
package/README.md CHANGED
@@ -31,6 +31,41 @@ Applications that use only the Octane runtime do not need this peer.
31
31
  scoped state, derived values, async resources, and native component reads.
32
32
  The standard compiler handles signals automatically; no extra option is needed.
33
33
 
34
+ ## Dynamically selected compiled views
35
+
36
+ In a template, use `CompiledOutlet` when all dynamically selected components
37
+ render compiled Octane output. It owns the selected view inside the surrounding
38
+ tree: hooks, contexts, hydration, and cleanup follow their usual lifetimes.
39
+
40
+ ```tsx
41
+ import { CompiledContext, CompiledOutlet, createCompiledContext, useContext } from 'octane';
42
+
43
+ const Route = createCompiledContext<string>('home');
44
+
45
+ function Page({ name }: { name: string }) @{
46
+ <h1>{name + ': ' + useContext(Route)}</h1>
47
+ }
48
+
49
+ export function Shell({ screen, name, route }) @{
50
+ <CompiledContext context={Route} value={route}>
51
+ <CompiledOutlet key={route} component={screen ?? Page} props={{ name }} />
52
+ </CompiledContext>
53
+ }
54
+ ```
55
+
56
+ An unchanged component and key retain state; changing either replaces the view
57
+ and runs its cleanups. Use `@try` / `@pending` around the outlet when the
58
+ selected component may suspend. The outlet accepts only a function whose output
59
+ is compiled; it throws for host strings or bodies that return descriptors or
60
+ plain text (including an explicit `null` return). Use an ordinary
61
+ dynamic JSX tag when arbitrary renderables are intentional.
62
+
63
+ `createCompiledContext` creates a context read by `use` or `useContext`.
64
+ Provide it through `CompiledContext` with children authored between the
65
+ template tags. Rendering the context itself as a provider is an error. Existing
66
+ `createContext` providers continue to accept both compiled and descriptor
67
+ children; compiled contexts are a separate, opt-in contract.
68
+
34
69
  Custom Node build pipelines can opt into project-aware string-child inference
35
70
  through `octane/compiler/typescript`. See the
36
71
  [type-aware text compilation guide](https://github.com/octanejs/octane/blob/main/docs/compiler-text-inference.md).
@@ -108,14 +108,7 @@ function assertBindingRoot(root, descriptor) {
108
108
  }
109
109
  function isTextLeaf(node) {
110
110
  const first = node.firstChild;
111
- return first === null || !first.nextSibling && (first.nodeType === 3 || first.localName === "font");
112
- }
113
- const htmlWhitespace = /^[\t\n\f\r ]*$/;
114
- function skipBindingWhitespace(node) {
115
- while (node !== null && node.nodeType === 3 && htmlWhitespace.test(node.nodeValue)) {
116
- node = node.nextSibling;
117
- }
118
- return node;
111
+ return first === null || !first.nextSibling && first.nodeType === 3;
119
112
  }
120
113
  function resolveFixedNodes(root, descriptor) {
121
114
  assertBindingRoot(root, descriptor);
@@ -129,12 +122,12 @@ function resolveFixedNodes(root, descriptor) {
129
122
  throw new Error(__octaneDev ? "DOM bindings cannot adopt a mismatched static element topology." : (0, import_error_message_no_arguments.formatNoArgumentErrorMessage)(318));
130
123
  }
131
124
  if (i !== 0) {
132
- cursors[parent] = skipBindingWhitespace(node.nextSibling);
125
+ cursors[parent] = node.nextSibling;
133
126
  childIndices[parent]++;
134
127
  }
135
128
  nodes.push(node);
136
129
  childIndices.push(0);
137
- cursors.push(text || children === null ? null : skipBindingWhitespace(node.firstChild));
130
+ cursors.push(text || children === null ? null : node.firstChild);
138
131
  }
139
132
  for (let i = 0; i < nodes.length; i++) {
140
133
  if (childIndices[i] !== (descriptor.nodes[i][3] ?? 0)) {
@@ -181,11 +174,9 @@ function resolveAddressedNodes(root, descriptor) {
181
174
  }
182
175
  if (parent !== -1) {
183
176
  childCounts[parent]++;
184
- if (cursors[parent] !== void 0) cursors[parent] = skipBindingWhitespace(node.nextSibling);
177
+ if (cursors[parent] !== void 0) cursors[parent] = node.nextSibling;
185
178
  }
186
- cursors.push(
187
- text || children === null || openChildren ? void 0 : skipBindingWhitespace(node.firstChild)
188
- );
179
+ cursors.push(text || children === null || openChildren ? void 0 : node.firstChild);
189
180
  }
190
181
  for (let i = 0; i < descriptor.nodes.length; i++) {
191
182
  if (childCounts[i] !== (descriptor.nodes[i][3] ?? 0)) {
@@ -217,16 +208,12 @@ function normalizeFixedScalar(binding, value) {
217
208
  (binding[2] === "start" || binding[2] === "rowspan") && Number.isNaN(Number(value))) ? null : String(value);
218
209
  }
219
210
  }
220
- function writeFixedScalar(node, binding, value, previous) {
211
+ function writeFixedScalar(node, binding, value) {
221
212
  const name = binding[2];
222
213
  if (binding[1] === "text") {
223
214
  const text = node.firstChild;
224
- const current = text?.nodeValue;
225
215
  if (text === null) node.appendChild(node.ownerDocument.createTextNode(value));
226
- else if (current !== value) {
227
- if (current !== null) text.nodeValue = value;
228
- else if (previous !== void 0) node.textContent = value;
229
- }
216
+ else if (text.nodeValue !== value) text.nodeValue = value;
230
217
  } else if (value === null) {
231
218
  if (node.hasAttribute(name)) node.removeAttribute(name);
232
219
  } else if (node.getAttribute(name) !== value) {
@@ -257,7 +244,7 @@ function normalize(binding, value) {
257
244
  return normalizeFixedScalar(binding, value);
258
245
  }
259
246
  }
260
- function write(node, binding, value, previous) {
247
+ function write(node, binding, value) {
261
248
  const name = binding[2];
262
249
  if (binding[1] === "classToken") {
263
250
  node.classList.toggle(name, value !== null);
@@ -283,7 +270,7 @@ function write(node, binding, value, previous) {
283
270
  if (style.getPropertyValue(name) !== text || style.getPropertyPriority(name) !== priority)
284
271
  style.setProperty(name, text, priority);
285
272
  }
286
- } else return writeFixedScalar(node, binding, value, previous);
273
+ } else return writeFixedScalar(node, binding, value);
287
274
  }
288
275
  const __bindingURL = [
289
276
  (binding) => binding[1] === "url" || isFixedScalarChannel(binding),
@@ -476,7 +463,7 @@ function __adoptBindings(root, descriptor, source, options) {
476
463
  if (!style)
477
464
  styles.set(i, style = __createBindingStyleRestoration(nodes[binding[0]], binding));
478
465
  style.write(prepared);
479
- } else written = write(nodes[binding[0]], binding, prepared, last);
466
+ } else written = write(nodes[binding[0]], binding, prepared);
480
467
  if (!disposed) {
481
468
  previous[i] = prepared;
482
469
  if (binding[1] === "attr" || binding[1] === "boolean" || binding[1] === "aria" || binding[1] === "class" || binding[1] === "url" || binding[1] === "styleProperty" || binding[1] === "styleObject" || binding[1] === "text") {
@@ -902,7 +889,7 @@ function __adoptScalarBindings(root, descriptor, source, options) {
902
889
  const last = previous[i];
903
890
  if (value === last) continue;
904
891
  const binding = bindings[i];
905
- const published = writeChannel(nodes[binding[0]], binding, value, last);
892
+ const published = writeChannel(nodes[binding[0]], binding, value);
906
893
  if (!disposed) {
907
894
  previous[i] = value;
908
895
  const node = owned[i][0];
@@ -1074,6 +1074,18 @@ function formatClientError(code, ...args) {
1074
1074
  "A keyed list rollback record restored a different shape than it recorded. This is a bug in Octane.",
1075
1075
  args
1076
1076
  );
1077
+ case 344:
1078
+ return (0, import_error_message.formatDevErrorMessage)(
1079
+ "Provide a compiled context with <CompiledContext context={context}>.",
1080
+ args
1081
+ );
1082
+ case 345:
1083
+ return (0, import_error_message.formatDevErrorMessage)("CompiledContext requires compiled template children.", args);
1084
+ case 346:
1085
+ return (0, import_error_message.formatDevErrorMessage)(
1086
+ "CompiledOutlet requires a compiled component function with no returned renderable.",
1087
+ args
1088
+ );
1077
1089
  default:
1078
1090
  return (0, import_error_message.formatUnknownDevErrorMessage)(code);
1079
1091
  }
@@ -769,6 +769,18 @@ function formatServerError(code, ...args) {
769
769
  "`<textarea>` children must be text: strings, numbers, or arrays of them. One child was %s. A textarea's content is its default value, so it cannot contain elements; render them outside the textarea or pass a string.",
770
770
  args
771
771
  );
772
+ case 344:
773
+ return (0, import_error_message.formatDevErrorMessage)(
774
+ "Provide a compiled context with <CompiledContext context={context}>.",
775
+ args
776
+ );
777
+ case 345:
778
+ return (0, import_error_message.formatDevErrorMessage)("CompiledContext requires compiled template children.", args);
779
+ case 346:
780
+ return (0, import_error_message.formatDevErrorMessage)(
781
+ "CompiledOutlet requires a compiled component function with no returned renderable.",
782
+ args
783
+ );
772
784
  default:
773
785
  return (0, import_error_message.formatUnknownDevErrorMessage)(code);
774
786
  }
@@ -20,6 +20,8 @@ var index_exports = {};
20
20
  __export(index_exports, {
21
21
  Activity: () => import_runtime.Activity,
22
22
  Children: () => import_runtime.Children,
23
+ CompiledContext: () => import_runtime.CompiledContext,
24
+ CompiledOutlet: () => import_runtime.CompiledOutlet,
23
25
  EXTERNAL_HYDRATION_PROMISE: () => import_runtime.EXTERNAL_HYDRATION_PROMISE,
24
26
  ErrorBoundary: () => import_runtime.ErrorBoundary,
25
27
  Fragment: () => import_runtime.Fragment,
@@ -83,6 +85,7 @@ __export(index_exports, {
83
85
  componentSlot: () => import_runtime.componentSlot,
84
86
  componentSlotLite: () => import_runtime.componentSlotLite,
85
87
  componentSlotVoid: () => import_runtime.componentSlotVoid,
88
+ createCompiledContext: () => import_runtime.createCompiledContext,
86
89
  createContext: () => import_runtime.createContext,
87
90
  createElement: () => import_runtime.createElement,
88
91
  createHostContextRequest: () => import_runtime.createHostContextRequest,
@@ -268,6 +271,8 @@ var import_method_dep = require("./method-dep.cjs");
268
271
  0 && (module.exports = {
269
272
  Activity,
270
273
  Children,
274
+ CompiledContext,
275
+ CompiledOutlet,
271
276
  EXTERNAL_HYDRATION_PROMISE,
272
277
  ErrorBoundary,
273
278
  Fragment,
@@ -331,6 +336,7 @@ var import_method_dep = require("./method-dep.cjs");
331
336
  componentSlot,
332
337
  componentSlotLite,
333
338
  componentSlotVoid,
339
+ createCompiledContext,
334
340
  createContext,
335
341
  createElement,
336
342
  createHostContextRequest,
@@ -20,6 +20,8 @@ var runtime_exports = {};
20
20
  __export(runtime_exports, {
21
21
  Activity: () => Activity,
22
22
  Children: () => Children,
23
+ CompiledContext: () => CompiledContext,
24
+ CompiledOutlet: () => CompiledOutlet,
23
25
  EXTERNAL_HYDRATION_PROMISE: () => import_constants.EXTERNAL_HYDRATION_PROMISE,
24
26
  ErrorBoundary: () => ErrorBoundary,
25
27
  Fragment: () => Fragment,
@@ -98,6 +100,7 @@ __export(runtime_exports, {
98
100
  componentSlot: () => componentSlot,
99
101
  componentSlotLite: () => componentSlotLite,
100
102
  componentSlotVoid: () => componentSlotVoid,
103
+ createCompiledContext: () => createCompiledContext,
101
104
  createContext: () => createContext,
102
105
  createElement: () => createElement,
103
106
  createElementAt: () => createElementAt,
@@ -9849,10 +9852,39 @@ function __createCompiledContext(defaultValue) {
9849
9852
  };
9850
9853
  return initializeContext(ctx, defaultValue);
9851
9854
  }
9855
+ function createCompiledContext(defaultValue) {
9856
+ const ctx = function CompiledProvider(_props, _scope) {
9857
+ throw new TypeError((0, import_error_codes_client_generated.formatClientError)(344));
9858
+ };
9859
+ return initializeContext(ctx, defaultValue);
9860
+ }
9861
+ function CompiledContext(props, scope) {
9862
+ provideContext(scope, props.context, props.value);
9863
+ const children = props.children;
9864
+ if (children == null) return;
9865
+ if (!isChildrenBlock(children)) {
9866
+ throw new TypeError((0, import_error_codes_client_generated.formatClientError)(345));
9867
+ }
9868
+ const dialect = children[CHILDREN_BODY] ?? children;
9869
+ const previous = scope.hooks?.get(CHILDREN_DIALECT_SLOT);
9870
+ if (previous !== dialect) {
9871
+ if (previous !== void 0) {
9872
+ invalidateSharedBodyOutput(scope);
9873
+ if (TRANSITION_JOURNAL !== null && !ROOT_RENDER_ROLLBACK) {
9874
+ const hooks = scope.hooks;
9875
+ journalUndo(() => hooks.set(CHILDREN_DIALECT_SLOT, previous));
9876
+ }
9877
+ }
9878
+ ensureHooks(scope).set(CHILDREN_DIALECT_SLOT, dialect);
9879
+ }
9880
+ const output = renderSharedBody(children, void 0, scope, void 0);
9881
+ if (output != null) throw new TypeError((0, import_error_codes_client_generated.formatClientError)(345));
9882
+ }
9852
9883
  function initializeContext(ctx, defaultValue) {
9853
9884
  ctx.$$kind = import_runtime_tags.CONTEXT_TAG;
9854
9885
  ctx.defaultValue = defaultValue;
9855
9886
  ctx.$$version = 0;
9887
+ ctx.$$providerVersion = 0;
9856
9888
  (0, import_context_identity.registerContext)(ctx);
9857
9889
  if (__octaneDev) {
9858
9890
  (0, import_context_identity.defineRemovedContextMembers)(ctx);
@@ -9927,6 +9959,7 @@ function provideContext(scope, context, value) {
9927
9959
  else values.delete(context);
9928
9960
  });
9929
9961
  if (had) {
9962
+ context.$$providerVersion = context.$$providerVersion === context.$$version ? context.$$version + 1 : -1;
9930
9963
  context.$$version++;
9931
9964
  (0, import_context_epoch.bumpContextEpoch)();
9932
9965
  }
@@ -9935,6 +9968,11 @@ function provideContext(scope, context, value) {
9935
9968
  const CHILDREN_BODY = /* @__PURE__ */ Symbol.for("octane.childrenBody");
9936
9969
  const CHILDREN_CAPTURES = /* @__PURE__ */ Symbol.for("octane.childrenCaptures");
9937
9970
  const CHILDREN_SIGNAL_OWNER = /* @__PURE__ */ Symbol();
9971
+ function sameRenderBody(previous, next) {
9972
+ const previousBody = previous[CHILDREN_BODY];
9973
+ const nextBody = next[CHILDREN_BODY];
9974
+ return previousBody === void 0 || nextBody === void 0 || previousBody === nextBody;
9975
+ }
9938
9976
  function markSingleRoot(component) {
9939
9977
  component.$$singleRoot = true;
9940
9978
  return component;
@@ -11436,12 +11474,29 @@ function promoteMemoAncestry(scope) {
11436
11474
  function recordContextDependency(block, context) {
11437
11475
  if (block === null || !block.memoInChain) return;
11438
11476
  SKIPPED_ROW_REFRESH = refreshSkippedRows;
11439
- (block.$$ctxDirect ??= /* @__PURE__ */ new Map()).set(context, context.$$version);
11477
+ const direct = block.$$ctxDirect ??= /* @__PURE__ */ new Map();
11478
+ const previous = direct.get(context);
11479
+ direct.set(context, context.$$version);
11440
11480
  for (let current = block; current !== null; current = current.parentBlock) {
11441
11481
  if (current.body?.__memo === true || current.$$implicitBail === true) {
11442
11482
  (current.$$ctxReads ??= /* @__PURE__ */ new Map()).set(context, context.$$version);
11443
11483
  }
11444
11484
  }
11485
+ return previous;
11486
+ }
11487
+ function recordLocalContextValue(reader, block, context, value, previous) {
11488
+ if (reader === null || block === null || !block.memoInChain) return;
11489
+ if (typeof previous === "number" || context.$$providerVersion !== context.$$version) return;
11490
+ const cache = reader.$$ctxCache;
11491
+ const owner = cache === context ? reader.$$ctxCacheOwner : cache !== null && reader.$$ctxCacheOwner === null ? cache.get(context) : void 0;
11492
+ if (owner === null || owner === void 0 || owner === DEFAULT_CTX) return;
11493
+ if (previous !== void 0) {
11494
+ if (previous.owner !== owner || !Object.is(previous.value, value)) return;
11495
+ previous.version = context.$$version;
11496
+ block.$$ctxDirect.set(context, previous);
11497
+ } else {
11498
+ block.$$ctxDirect.set(context, { version: context.$$version, owner, value });
11499
+ }
11445
11500
  }
11446
11501
  let SCOPED_READ_TRACKING = false;
11447
11502
  let SCOPED_READS = null;
@@ -11599,8 +11654,10 @@ function readContextFrom(reader, block, context) {
11599
11654
  return context.defaultValue;
11600
11655
  }
11601
11656
  function readContextFromScope(scope, context) {
11602
- recordContextDependency(scope.block, context);
11603
- return readContextFrom(scope, scope.block, context);
11657
+ const previous = recordContextDependency(scope.block, context);
11658
+ const value = readContextFrom(scope, scope.block, context);
11659
+ recordLocalContextValue(scope, scope.block, context, value, previous);
11660
+ return value;
11604
11661
  }
11605
11662
  function getRendererOwnerVisibility(scope) {
11606
11663
  if (findHiddenActivity(scope.block) !== null) return "activity";
@@ -11618,8 +11675,10 @@ function reportRendererOwnerError(scope, error) {
11618
11675
  }
11619
11676
  }
11620
11677
  function useContextInternal(context) {
11621
- recordContextDependency(CURRENT_BLOCK, context);
11622
- return readContextFrom(CURRENT_SCOPE, CURRENT_BLOCK, context);
11678
+ const previous = recordContextDependency(CURRENT_BLOCK, context);
11679
+ const value = readContextFrom(CURRENT_SCOPE, CURRENT_BLOCK, context);
11680
+ recordLocalContextValue(CURRENT_SCOPE, CURRENT_BLOCK, context, value, previous);
11681
+ return value;
11623
11682
  }
11624
11683
  class SuspenseException {
11625
11684
  constructor(thenable) {
@@ -12649,7 +12708,13 @@ function parseTemplate(html, ns, frag) {
12649
12708
  initDomOperations();
12650
12709
  const t = (STAGED_DOM ? STAGED_DOM.view(document) : document).createElement("template");
12651
12710
  if (ns === 0) {
12652
- (STAGED_DOM ? STAGED_DOM.view(t) : t).innerHTML = frag ? `<octane-frag>${html}</octane-frag>` : html;
12711
+ (STAGED_DOM ? STAGED_DOM.view(t) : t).innerHTML = html;
12712
+ if (frag) {
12713
+ const owner = t.content.ownerDocument;
12714
+ const wrapper = (STAGED_DOM ? STAGED_DOM.view(owner) : owner).createElement("octane-frag");
12715
+ (STAGED_DOM ? STAGED_DOM.view(wrapper) : wrapper).appendChild(t.content);
12716
+ return fragmentTemplate(wrapper);
12717
+ }
12653
12718
  const root = getFirstChild(t.content);
12654
12719
  if (root.nodeType === 1 && root.localName === "octane-frag") {
12655
12720
  return fragmentTemplate(root);
@@ -15987,17 +16052,7 @@ function updateTextValue(node, value) {
15987
16052
  }
15988
16053
  }
15989
16054
  function setText(node, value, host) {
15990
- if (host !== void 0) {
15991
- if (node === null) {
15992
- node = (STAGED_DOM ? STAGED_DOM.view(host) : host).firstChild;
15993
- if (node === null || node.nodeType !== 3) {
15994
- node = (STAGED_DOM ? STAGED_DOM.view(document) : document).createTextNode("");
15995
- resetOnlyChildHost(host, node);
15996
- }
15997
- } else if ((STAGED_DOM ? STAGED_DOM.view(node) : node).parentNode !== host)
15998
- resetOnlyChildHost(host, node);
15999
- }
16000
- const target = node;
16055
+ const target = node ?? (STAGED_DOM ? STAGED_DOM.view(host) : host).firstChild;
16001
16056
  if (VIEW_TRANSITION_DRIVER) VIEW_TRANSITION_DRIVER.markDirty();
16002
16057
  if (TRANSITION_JOURNAL !== null)
16003
16058
  journalText(target, (STAGED_DOM ? STAGED_DOM.view(target) : target).nodeValue);
@@ -16005,12 +16060,6 @@ function setText(node, value, host) {
16005
16060
  if (hiddenTextWriter !== null && hiddenTextWriter(target, text)) return;
16006
16061
  (STAGED_DOM ? STAGED_DOM.view(target) : target).nodeValue = text;
16007
16062
  }
16008
- function resetOnlyChildHost(host, node) {
16009
- if (ROOT_RENDER_TRANSACTION !== null) journalRootRange(host, null, null);
16010
- const view = STAGED_DOM ? STAGED_DOM.view(host) : host;
16011
- view.textContent = "";
16012
- if (node !== null) view.appendChild(node);
16013
- }
16014
16063
  const DIRECT_SIGNAL_BINDING = /* @__PURE__ */ Symbol("octane.direct-signal-binding");
16015
16064
  const CLAIMED_BINDING_VALUE = /* @__PURE__ */ Symbol("octane.claimed-binding-value");
16016
16065
  function hydrateClaimedBindingCaches(scope, fields) {
@@ -21691,6 +21740,29 @@ function componentSlotVoid(parentScope, slotKey, domParent, comp, props, invocat
21691
21740
  invocationSite
21692
21741
  );
21693
21742
  }
21743
+ function rejectCompiledReturn(_block, _out, reset) {
21744
+ if (reset !== true) {
21745
+ throw new TypeError((0, import_error_codes_client_generated.formatClientError)(346));
21746
+ }
21747
+ }
21748
+ function CompiledOutlet(props, scope) {
21749
+ const comp = props.component;
21750
+ if (typeof comp !== "function") {
21751
+ throw new TypeError((0, import_error_codes_client_generated.formatClientError)(346));
21752
+ }
21753
+ const block = scope.block;
21754
+ componentSlotImpl(
21755
+ rejectCompiledReturn,
21756
+ scope,
21757
+ 0,
21758
+ block.parentNode,
21759
+ comp,
21760
+ comp,
21761
+ props.props,
21762
+ props.props,
21763
+ block.endMarker
21764
+ );
21765
+ }
21694
21766
  function componentSlotImpl(outputHandler, parentScope, slotKey, domParent, body, identity, props, renderProps, anchor, key, singleRoot, inherit, hasKey, invocationSite) {
21695
21767
  if (CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate) return;
21696
21768
  if (slotKey === 0 && parentScope !== RETURNED_OUTPUT_SCOPE) {
@@ -22536,8 +22608,6 @@ function hostComponent(scope, slot, tag, props, childrenBody, anchor) {
22536
22608
  anchor: null,
22537
22609
  ref: void 0,
22538
22610
  props: void 0,
22539
- body: void 0,
22540
- latest: void 0,
22541
22611
  childScope: void 0
22542
22612
  };
22543
22613
  scope.slots[slot] = state;
@@ -22553,13 +22623,7 @@ function hostComponent(scope, slot, tag, props, childrenBody, anchor) {
22553
22623
  }
22554
22624
  const el = state.el;
22555
22625
  applyHostProps(el, props, scope, state);
22556
- if (typeof childrenBody === "function") {
22557
- state.latest = childrenBody;
22558
- if (state.body === void 0) {
22559
- state.body = (props2, scope2, extra) => state.latest(props2, scope2, extra);
22560
- }
22561
- childSlot(state.childScope, 0, el, state.body, null, false, el);
22562
- } else if (childrenBody != null || state.childScope.slots[0] !== void 0) {
22626
+ if (childrenBody != null || state.childScope.slots[0] !== void 0) {
22563
22627
  childSlot(state.childScope, 0, el, childrenBody ?? null, null, false, el);
22564
22628
  }
22565
22629
  return el;
@@ -23505,7 +23569,23 @@ function renderHostTagChildren(d, block, el) {
23505
23569
  if (kids == null) return;
23506
23570
  if (typeof kids === "function") {
23507
23571
  let state = block.slots[0];
23508
- if (state === void 0) {
23572
+ if (state === void 0 || !sameRenderBody(state.block.body, kids)) {
23573
+ if (state !== void 0) {
23574
+ journalRootSlot(state, el, null, null);
23575
+ if (ROOT_RENDER_TRANSACTION !== null && !ROOT_RENDER_TRANSACTION.aborted && !ROOT_RENDER_ROLLBACK) {
23576
+ deferRootReplacement(
23577
+ state.block,
23578
+ el,
23579
+ getFirstChild(el),
23580
+ (STAGED_DOM ? STAGED_DOM.view(el) : el).lastChild
23581
+ );
23582
+ } else {
23583
+ unmountBlock(state.block, false);
23584
+ let child3;
23585
+ while ((child3 = getFirstChild(el)) !== null)
23586
+ (STAGED_DOM ? STAGED_DOM.view(el) : el).removeChild(child3);
23587
+ }
23588
+ }
23509
23589
  const child2 = createBlock(
23510
23590
  "dynamic",
23511
23591
  block,
@@ -23517,10 +23597,15 @@ function renderHostTagChildren(d, block, el) {
23517
23597
  void 0,
23518
23598
  renderReturnedValue
23519
23599
  );
23520
- state = { __kind: "hostTagChildrenSlot", block: child2 };
23521
- block.slots[0] = state;
23522
- registerSlot(block, state);
23600
+ if (state === void 0) {
23601
+ state = { __kind: "hostTagChildrenSlot", block: child2 };
23602
+ block.slots[0] = state;
23603
+ registerSlot(block, state);
23604
+ } else {
23605
+ state.block = child2;
23606
+ }
23523
23607
  } else {
23608
+ if (state.block.body !== kids) journalRootProperty(state.block, "body", state.block.body);
23524
23609
  state.block.body = kids;
23525
23610
  }
23526
23611
  renderBlock(state.block);
@@ -24076,12 +24161,7 @@ function bindSignalChild(parentScope, previous, slotKey, domParent, value, _site
24076
24161
  if (textToken && previous === value && !dangerouslySetInnerHTMLOwnsChild(domParent, value))
24077
24162
  return value;
24078
24163
  const prior = typeof previous === "object" && previous !== null && previous[DIRECT_SIGNAL_CHILD] === true ? previous : null;
24079
- let cachedText = prior?.text ?? (previous instanceof Text ? previous : null);
24080
- if (cachedText === null && textToken) {
24081
- const first = getFirstChild(domParent);
24082
- if (first !== null && first.nodeType === 3) cachedText = first;
24083
- else resetOnlyChildHost(domParent, null);
24084
- }
24164
+ const cachedText = prior?.text ?? (previous instanceof Text ? previous : textToken ? getFirstChild(domParent) : null);
24085
24165
  if (!isSignalHandle(value)) {
24086
24166
  const type = typeof value;
24087
24167
  const primitiveToken = slotKey !== 0 && !onlyChild && bindingMarker === void 0 && value !== null && type !== "object" && type !== "function" && !(CURRENT_BLOCK?.pending && !CURRENT_BLOCK.crossRenderUpdate);
@@ -24267,7 +24347,7 @@ function childSlot(parentScope, slotKey, domParent, value, anchor, ownEnd, ownsH
24267
24347
  if (state !== void 0 && ROOT_RENDER_TRANSACTION !== null) {
24268
24348
  const component = pureHost || preparedList !== null ? null : typeof elementType === "string" ? hostElementBody : valueComponent;
24269
24349
  const unchangedList = preparedList !== null && state.forSlot !== null;
24270
- const unchangedComponent = state.block !== null && component !== null && (component === state.currentComp || typeof value === "function" && state.currentIsBodyFn);
24350
+ const unchangedComponent = state.block !== null && component !== null && (component === state.currentComp || typeof value === "function" && state.currentIsBodyFn && sameRenderBody(state.currentComp, component));
24271
24351
  const unchangedHost = pureHost && state.hostNode !== null && state.block === null && state.hostNode.nodeType === 1 && isHostElementOfType(state.hostNode, elementType);
24272
24352
  const primitive = value == null || typeof value !== "object" && typeof value !== "function";
24273
24353
  const text = primitive ? coerceChildText(value) : null;
@@ -24582,7 +24662,7 @@ function childSlot(parentScope, slotKey, domParent, value, anchor, ownEnd, ownsH
24582
24662
  componentDescriptor = value;
24583
24663
  }
24584
24664
  if (comp !== null) {
24585
- if (isBodyFn && state.block !== null && state.currentIsBodyFn) {
24665
+ if (isBodyFn && state.block !== null && state.currentIsBodyFn && sameRenderBody(state.currentComp, comp)) {
24586
24666
  const taggedChildren = isChildrenBlock(comp);
24587
24667
  const wasImplicitlyArmed = state.block.$$implicitBail;
24588
24668
  if (taggedChildren && !wasImplicitlyArmed) {
@@ -24909,17 +24989,12 @@ function childTextHoleUpdate(parentScope, slotKey, domParent, value, cachedNode,
24909
24989
  if (!complex) {
24910
24990
  if (previous === value) return cachedNode;
24911
24991
  if (cachedNode != null && value !== null) {
24912
- setText(cachedNode, value === true ? "" : value, domParent);
24992
+ setText(cachedNode, value === true ? "" : value);
24913
24993
  return cachedNode;
24914
24994
  }
24915
24995
  }
24916
24996
  return childTextHole(parentScope, slotKey, domParent, value, cachedNode);
24917
24997
  }
24918
- function removeOnlyChildText(host, node) {
24919
- const view = STAGED_DOM ? STAGED_DOM.view(node) : node;
24920
- if (view.parentNode === host) view.remove();
24921
- else resetOnlyChildHost(host, null);
24922
- }
24923
24998
  function childTextHole(parentScope, slotKey, domParent, value, cachedNode) {
24924
24999
  if (domParent.nodeType === 1 && import_constants.VOID_ELEMENTS.has(domParent.localName) && !isPortalTarget(parentScope.block, domParent) && value != null) {
24925
25000
  throw new Error((0, import_error_codes_client_generated.formatClientError)(26, domParent.localName));
@@ -24949,12 +25024,10 @@ function childTextHole(parentScope, slotKey, domParent, value, cachedNode) {
24949
25024
  return null;
24950
25025
  return hydration3.hempty(domParent, vt === "string", siteLoc(parentScope, slotKey));
24951
25026
  }
24952
- removeOnlyChildText(domParent, cachedNode);
25027
+ (STAGED_DOM ? STAGED_DOM.view(cachedNode) : cachedNode).remove();
24953
25028
  return null;
24954
25029
  }
24955
25030
  if (cachedNode !== null) {
24956
- if ((STAGED_DOM ? STAGED_DOM.view(cachedNode) : cachedNode).parentNode !== domParent)
24957
- resetOnlyChildHost(domParent, cachedNode);
24958
25031
  updateTextValue(cachedNode, str);
24959
25032
  return cachedNode;
24960
25033
  }
@@ -24969,7 +25042,8 @@ function childTextHole(parentScope, slotKey, domParent, value, cachedNode) {
24969
25042
  if (!hydration2.framesSlotContent(domParent))
24970
25043
  return hydration2.htext(domParent, str, siteLoc(parentScope, slotKey));
24971
25044
  }
24972
- if (state === void 0 && cachedNode !== null) removeOnlyChildText(domParent, cachedNode);
25045
+ if (state === void 0 && cachedNode !== null)
25046
+ (STAGED_DOM ? STAGED_DOM.view(cachedNode) : cachedNode).remove();
24973
25047
  const hydration = import_hydration_flag.hydrating ? activeHydration() : null;
24974
25048
  if (hydration !== null && state === void 0)
24975
25049
  hydration.hydrateOnlyChild(
@@ -24994,8 +25068,12 @@ function ctxDepsChanged(block) {
24994
25068
  function ctxDirectChanged(block) {
24995
25069
  const direct = block.$$ctxDirect;
24996
25070
  if (direct === null) return false;
24997
- for (const [ctx, version] of direct) {
24998
- if (ctx.$$version !== version) return true;
25071
+ for (const [ctx, read] of direct) {
25072
+ const version = typeof read === "number" ? read : read.version;
25073
+ if (ctx.$$version === version) continue;
25074
+ if (typeof read === "number" || ctx.$$providerVersion !== ctx.$$version || !Object.is(read.owner.$$ctxValues?.get(ctx), read.value))
25075
+ return true;
25076
+ read.version = ctx.$$version;
24999
25077
  }
25000
25078
  return false;
25001
25079
  }
@@ -25064,7 +25142,8 @@ function restampCtxDeps(block) {
25064
25142
  }
25065
25143
  }
25066
25144
  if (hasDirect) {
25067
- for (const [ctx, v] of direct) {
25145
+ for (const [ctx, read] of direct) {
25146
+ const v = typeof read === "number" ? read : read.version;
25068
25147
  const cur = m.get(ctx);
25069
25148
  if (cur !== v) {
25070
25149
  const live = ctx.$$version;
@@ -32504,6 +32583,8 @@ function scriptResource(attrs) {
32504
32583
  0 && (module.exports = {
32505
32584
  Activity,
32506
32585
  Children,
32586
+ CompiledContext,
32587
+ CompiledOutlet,
32507
32588
  EXTERNAL_HYDRATION_PROMISE,
32508
32589
  ErrorBoundary,
32509
32590
  Fragment,
@@ -32582,6 +32663,7 @@ function scriptResource(attrs) {
32582
32663
  componentSlot,
32583
32664
  componentSlotLite,
32584
32665
  componentSlotVoid,
32666
+ createCompiledContext,
32585
32667
  createContext,
32586
32668
  createElement,
32587
32669
  createElementAt,