octane 0.2.13 → 0.2.14

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.
@@ -319,6 +319,7 @@ var import_dom_stage = require("./dom-stage.cjs");
319
319
  var import_dom_binding_styles = require("./dom-binding-styles.cjs");
320
320
  var import_dom_binding_handoff = require("./dom-binding-handoff.cjs");
321
321
  var import_context_epoch = require("./context-epoch.cjs");
322
+ var import_control_handoff = require("./signals/control-handoff.cjs");
322
323
  var import_constants = require("./constants.cjs");
323
324
  var import_event_names = require("./event-names.cjs");
324
325
  var import_has_own = require("./has-own.cjs");
@@ -2426,7 +2427,9 @@ function rollbackRootRender(transaction) {
2426
2427
  }
2427
2428
  function retireDetachedBindingLeases(owner) {
2428
2429
  for (const lease of owner.bindingLeases) {
2429
- if (owner.bindingContainer.contains(lease.anchor)) continue;
2430
+ const preparation = lease.host !== void 0 && !lease.active() ? PRESENTATION_PREPARATIONS.get(lease) : void 0;
2431
+ if (preparation !== void 0 ? !preparation.scope.block.disposed : owner.bindingContainer.contains(lease.anchor))
2432
+ continue;
2430
2433
  owner.bindingLeases.delete(lease);
2431
2434
  PRESENTATION_PREPARATIONS.delete(lease);
2432
2435
  (0, import_dom_binding_handoff.releaseBindingHandoff)(lease);
@@ -6461,7 +6464,8 @@ function nativeEffectPublicationCurrent(entry, slot) {
6461
6464
  if (ROOT_RENDER_TRANSACTION !== null) journalObjectOnce(slot);
6462
6465
  slot.deps = void 0;
6463
6466
  slot.active = slot.connectedFn !== null;
6464
- invalidateRender(entry.scope.block, entry.scope.block);
6467
+ if (!entry.scope.block.idState.renderOwner?.disposed && !blockSubtreeDisposed(entry.scope.block))
6468
+ scheduleNativeRead(entry.scope.block);
6465
6469
  return false;
6466
6470
  }
6467
6471
  function drainMutationEffects() {
@@ -8831,6 +8835,7 @@ function releasePreservedHydrateActivation(state) {
8831
8835
  function pendingHydrateOwner(target) {
8832
8836
  let owner = null;
8833
8837
  for (let block = target; block !== null; block = block.parentBlock) {
8838
+ if (block.block !== block) continue;
8834
8839
  const state = block.slots[0];
8835
8840
  if (state?.__kind === "hydrateBlockSlot" && !state.hydrated && preservedHydrateActivations?.has(state))
8836
8841
  owner = state;
@@ -12025,7 +12030,7 @@ function isAdoptionControl(error) {
12025
12030
  }
12026
12031
  function presentationFailure(error) {
12027
12032
  const frame = PRESENTATION_HYDRATION;
12028
- if (frame?.revision !== void 0 && !isSuspenseException(error) && !isAdoptionControl(error)) {
12033
+ if (frame !== null && !isSuspenseException(error) && !isAdoptionControl(error)) {
12029
12034
  const failure = new PresentationAdoptionMiss(frame.lease, false);
12030
12035
  failure.failure = error;
12031
12036
  throw failure;
@@ -12036,12 +12041,25 @@ function presentationMiss(retry = true) {
12036
12041
  throw new PresentationAdoptionMiss(PRESENTATION_HYDRATION?.lease, retry);
12037
12042
  }
12038
12043
  function currentPresentation(frame) {
12039
- if (frame.revision === void 0) return true;
12044
+ if (frame.controls !== void 0 && [...frame.controls.values()].some(({ valid }) => !valid()))
12045
+ return false;
12046
+ if (frame.revision === void 0 && frame.controls === void 0) return true;
12040
12047
  const lease = frame.lease;
12041
- return lease.active() && lease.valid?.() !== false && lease.revision?.() === frame.revision && lease.root.parentNode !== null && lease.end?.parentNode === lease.root.parentNode && [...frame.witnesses.values()].every(
12048
+ return lease.active() && lease.valid?.() !== false && lease.revision?.() === frame.revision && lease.root.parentNode !== null && (lease.host === void 0 ? lease.end?.parentNode === lease.root.parentNode : lease.owner === frame.scope.block.idState.renderOwner && frame.scope.block.idState.renderOwner.bindingContainer.contains(lease.root)) && [...frame.witnesses.values()].every(
12042
12049
  (witness) => witness === null || (0, import_native_read_collector.validateNativeReadWitness)(witness)
12043
12050
  );
12044
12051
  }
12052
+ function trackPresentationFrame(frame) {
12053
+ if (frame.current !== void 0) return;
12054
+ frame.current = currentPresentation;
12055
+ (WIP_CAPTURE.presentations ??= []).push(frame);
12056
+ if (frame.hydration === null) return;
12057
+ frame.hydration.presentation = true;
12058
+ for (let block = frame.scope.block; block !== null; block = block.parentBlock) {
12059
+ preserveRootCreatedDom(block);
12060
+ if (block === frame.hydration.rootBlock) break;
12061
+ }
12062
+ }
12045
12063
  function currentPresentations(capture) {
12046
12064
  return capture.presentations?.every((frame) => frame.current(frame)) !== false;
12047
12065
  }
@@ -12077,7 +12095,7 @@ function hasClosedPresentationView(lease, scope, id) {
12077
12095
  return false;
12078
12096
  }
12079
12097
  }
12080
- function beginPresentationHydration(scope, id, supported = false, structural = false, conditionalRest = false) {
12098
+ function beginPresentationHydration(scope, id, supported = false, structural = false, conditionalRest = false, host = false) {
12081
12099
  const owner = scope.block.idState.renderOwner;
12082
12100
  if (PRESENTATION_HYDRATION !== null && PRESENTATION_HYDRATION.scope.block.idState.renderOwner === owner) {
12083
12101
  if (conditionalRest) {
@@ -12089,15 +12107,17 @@ function beginPresentationHydration(scope, id, supported = false, structural = f
12089
12107
  if (owner?.bindingLeases === void 0 || WIP_CAPTURE === null) return null;
12090
12108
  const hydration = activeHydration();
12091
12109
  const lease = [...owner.bindingLeases].find(
12092
- (candidate) => candidate.id === id && (candidate.root === scope.block.startMarker || candidate.root === hydration?.node || candidate.root.nodeType === 8 && candidate.root.nextSibling === hydration?.node)
12110
+ (candidate) => candidate.id === id && (candidate.root === scope.block.startMarker || candidate.root === hydration?.node || candidate.root.nodeType === 8 && candidate.root.nextSibling === hydration?.node || candidate.host !== void 0 && PRESENTATION_PREPARATIONS.get(candidate)?.scope === scope)
12093
12111
  );
12094
12112
  if (lease === void 0) return null;
12113
+ if (!lease.active()) throw new PresentationAdoptionMiss(lease, false);
12114
+ if (host !== (lease.host !== void 0)) throw new PresentationAdoptionMiss(lease, false);
12095
12115
  if (conditionalRest ? !supported || !structural || !hasClosedPresentationView(lease, scope, id) : !supported)
12096
12116
  throw new PresentationAdoptionMiss(lease, false);
12097
12117
  const revision = lease.revision?.();
12098
- if (revision !== void 0 && revision >= 0 && lease.valid?.() === false)
12118
+ if ((revision === void 0 || revision >= 0) && lease.valid?.() === false)
12099
12119
  throw new PresentationAdoptionMiss(lease, false);
12100
- if (revision !== void 0 && (!structural || revision < 0))
12120
+ if (revision !== void 0 && (!structural && !host || revision < 0))
12101
12121
  throw new PresentationAdoptionMiss(lease, revision < 0, revision);
12102
12122
  const pending = PRESENTATION_PREPARATIONS.get(lease);
12103
12123
  const frame = {
@@ -12110,42 +12130,95 @@ function beginPresentationHydration(scope, id, supported = false, structural = f
12110
12130
  readToken: beginNativeReadScope(scope),
12111
12131
  witnessToken: beginNativeReadWitness(),
12112
12132
  witnesses: pending?.scope === scope ? new Map(pending.witnesses) : /* @__PURE__ */ new Map(),
12133
+ ...lease.host === void 0 ? {} : { hostSuccessors: new Map(pending?.scope === scope ? pending.hostSuccessors : void 0) },
12134
+ ...pending?.scope === scope && pending.controls !== void 0 ? { controls: new Map(pending.controls) } : {},
12113
12135
  completed: false,
12114
12136
  lease,
12115
- ...revision === void 0 ? {} : { revision, current: currentPresentation },
12137
+ ...revision === void 0 ? {} : { revision },
12116
12138
  hydration
12117
12139
  };
12118
12140
  PRESENTATION_HYDRATION = frame;
12119
- if (revision !== void 0 && hydration !== null) {
12120
- hydration.presentation = true;
12121
- for (let block = scope.block; block !== null; block = block.parentBlock) {
12122
- preserveRootCreatedDom(block);
12123
- if (block === hydration.rootBlock) break;
12124
- }
12125
- }
12141
+ if (revision !== void 0 || frame.controls !== void 0) trackPresentationFrame(frame);
12126
12142
  PRESENTATION_PREPARATIONS.set(lease, frame);
12127
- if (revision !== void 0) (WIP_CAPTURE.presentations ??= []).push(frame);
12143
+ const hostRefs = host ? WIP_CAPTURE.refs : void 0;
12128
12144
  (WIP_CAPTURE.renderCleanups ??= []).push((discarded) => {
12129
12145
  if (discarded || !frame.completed || owner.disposed || scope.block.disposed || PRESENTATION_PREPARATIONS.get(lease) !== frame)
12130
12146
  return;
12131
12147
  if (!currentPresentation(frame)) {
12132
- frame.hydration?.retryPresentation?.();
12148
+ if (frame.hydration?.retryPresentation !== void 0) frame.hydration.retryPresentation();
12149
+ else throw new PresentationAdoptionMiss(lease, false);
12133
12150
  return;
12134
12151
  }
12135
12152
  PRESENTATION_PREPARATIONS.delete(lease);
12136
12153
  owner.bindingLeases.delete(lease);
12137
12154
  (0, import_dom_binding_handoff.releaseBindingHandoff)(lease);
12155
+ let publicationStarted = false;
12138
12156
  let published = false;
12157
+ let hostFailed = false;
12158
+ let hostFailure;
12139
12159
  try {
12140
12160
  lease.retire(() => {
12141
- for (const writes of frame.writes.values()) for (const write of writes.values()) write();
12161
+ publicationStarted = true;
12162
+ try {
12163
+ for (const writes of frame.writes.values()) for (const write of writes.values()) write();
12164
+ } catch (error) {
12165
+ for (const stop of frame.hostSuccessors?.values() ?? []) {
12166
+ try {
12167
+ stop();
12168
+ } catch {
12169
+ }
12170
+ }
12171
+ frame.hostSuccessors?.clear();
12172
+ for (const [element, control] of frame.controls ?? []) {
12173
+ const binding = control.binding;
12174
+ if (binding.disposed && control.valid(true)) continue;
12175
+ (owner.controlLeases ??= /* @__PURE__ */ new Map()).set(element, control.lease);
12176
+ if (binding.disposed) continue;
12177
+ if (binding.input !== void 0) renderControlledState(element).v = UNCONTROLLED;
12178
+ control.stop = binding.unsubscribe;
12179
+ binding.unsubscribe = void 0;
12180
+ disposeDirectSignalBinding(binding);
12181
+ }
12182
+ for (const control of frame.controls?.values() ?? []) {
12183
+ try {
12184
+ control.stop?.();
12185
+ } catch {
12186
+ }
12187
+ }
12188
+ throw error;
12189
+ }
12142
12190
  published = true;
12143
12191
  });
12144
12192
  } catch (error) {
12145
- if (!published) throw error;
12146
- reportRendererOwnerError(scope, error);
12193
+ if (!publicationStarted) throw error;
12194
+ if (frame.hostSuccessors !== void 0) {
12195
+ hostFailed = true;
12196
+ hostFailure = error;
12197
+ } else reportRendererOwnerError(scope, error);
12147
12198
  } finally {
12199
+ if (frame.hostSuccessors !== void 0 && (!published || lease.valid?.() === false)) {
12200
+ published = false;
12201
+ owner.bindingLeases.add(lease);
12202
+ PRESENTATION_PREPARATIONS.set(lease, frame);
12203
+ for (const entry of hostRefs) if (entry.el === lease.root) entry.ref = null;
12204
+ for (const stop of frame.hostSuccessors.values()) {
12205
+ try {
12206
+ stop();
12207
+ } catch (error) {
12208
+ if (!hostFailed) {
12209
+ hostFailed = true;
12210
+ hostFailure = error;
12211
+ }
12212
+ }
12213
+ }
12214
+ if (!hostFailed) {
12215
+ hostFailed = true;
12216
+ hostFailure = new Error((0, import_error_codes_client_generated.formatClientError)(77));
12217
+ }
12218
+ }
12219
+ frame.hostSuccessors?.clear();
12148
12220
  frame.writes.clear();
12221
+ frame.controls?.clear();
12149
12222
  if (published && !owner.disposed && owner.current !== null && [...frame.witnesses.values()].some(
12150
12223
  (witness) => witness !== null && !(0, import_native_read_collector.validateNativeReadWitness)(witness)
12151
12224
  )) {
@@ -12155,6 +12228,7 @@ function beginPresentationHydration(scope, id, supported = false, structural = f
12155
12228
  }
12156
12229
  frame.witnesses.clear();
12157
12230
  }
12231
+ if (hostFailed) reportRendererOwnerError(scope, hostFailure);
12158
12232
  });
12159
12233
  return frame;
12160
12234
  }
@@ -12173,13 +12247,33 @@ function preparedPresentationAttribute(el, name, value, kind) {
12173
12247
  const result = coerceAttrValue(el, name, value);
12174
12248
  return result === "" && import_constants.BOOLEAN_ATTR_PROPS.has(name.toLowerCase()) ? true : result;
12175
12249
  }
12176
- function preparePresentationSignalAttribute(args, frame) {
12177
- const [scope, previous, element, name, value, site, attributeKind = "attr"] = args;
12250
+ function preparePresentationSignalBinding(args, frame, text = false) {
12251
+ const [scope, previous, element] = args;
12252
+ const name = text ? void 0 : args[3];
12253
+ const value = args[text ? 3 : 4];
12254
+ const site = args[text ? 4 : 5];
12255
+ const attributeKind = text ? void 0 : args[6] ?? "attr";
12256
+ const kind = text ? args[5] ? "textOnlyChild" : "text" : "attribute";
12178
12257
  return runWithBlockSignalOwner(scope, () => {
12179
12258
  const handle = isSignalHandle(value) ? value : null;
12180
- const current = handle === null ? value : handle.get();
12181
- const prepared = preparedPresentationAttribute(element, name, current, attributeKind);
12259
+ const witness = handle !== null && frame.lease.host !== void 0 ? beginNativeReadWitness(true) : -1;
12260
+ let current;
12261
+ let readCompleted = false;
12262
+ try {
12263
+ current = handle === null ? value : handle.get();
12264
+ readCompleted = true;
12265
+ } finally {
12266
+ if (witness >= 0)
12267
+ frame.witnesses.set(handle, finishNativeReadWitness(witness, readCompleted));
12268
+ }
12269
+ if (text && (current !== null && (typeof current === "object" || typeof current === "function") || typeof args[7] !== "string"))
12270
+ presentationMiss(false);
12271
+ const prepared = text ? bindingText(element, current, args[7]) : preparedPresentationAttribute(element, name, current, attributeKind);
12182
12272
  if (handle === null) {
12273
+ if (text) {
12274
+ frame.writes.get(element)?.delete("signalText");
12275
+ return prepared;
12276
+ }
12183
12277
  preparePresentationOperation(
12184
12278
  frame,
12185
12279
  element,
@@ -12189,12 +12283,12 @@ function preparePresentationSignalAttribute(args, frame) {
12189
12283
  return value;
12190
12284
  }
12191
12285
  const prior = previous;
12192
- const reusable = prior?.[DIRECT_SIGNAL_BINDING] === true && !prior.disposed && prior.unsubscribe === void 0 && prior.handle === handle && prior.target === element && prior.site === site && prior.name === name && prior.attributeKind === attributeKind;
12286
+ const reusable = prior?.[DIRECT_SIGNAL_BINDING] === true && !prior.disposed && prior.unsubscribe === void 0 && prior.handle === handle && prior.target === element && prior.kind === kind && prior.site === site && prior.name === name && prior.attributeKind === attributeKind;
12193
12287
  const binding = reusable ? prior : {
12194
12288
  [DIRECT_SIGNAL_BINDING]: true,
12195
12289
  scope,
12196
12290
  target: element,
12197
- kind: "attribute",
12291
+ kind,
12198
12292
  site,
12199
12293
  name,
12200
12294
  attributeKind,
@@ -12202,16 +12296,114 @@ function preparePresentationSignalAttribute(args, frame) {
12202
12296
  value: current,
12203
12297
  disposed: false
12204
12298
  };
12299
+ if (text) binding.text = prepared;
12205
12300
  if (!reusable) registerHookCleanup(scope, () => disposeDirectSignalBinding(binding));
12206
- preparePresentationOperation(frame, element, name, () => {
12301
+ frame.hostSuccessors?.set(binding, () => disposeDirectSignalBinding(binding));
12302
+ preparePresentationOperation(frame, element, name ?? "signalText", () => {
12207
12303
  if (binding.disposed) return;
12208
- writeDirectSignalScalar(element, prepared, "attribute", previous, name, attributeKind);
12304
+ if (!text)
12305
+ writeDirectSignalScalar(element, prepared, "attribute", previous, name, attributeKind);
12209
12306
  binding.value = current;
12210
12307
  runWithBlockSignalOwner(scope, () => activateDirectSignalBinding(binding, void 0));
12211
12308
  });
12212
12309
  return binding;
12213
12310
  });
12214
12311
  }
12312
+ function preparePresentationSignalValue(args, frame) {
12313
+ const [scope, previous, element, handle, site] = args;
12314
+ return runWithBlockSignalOwner(scope, () => {
12315
+ if (element.localName !== "textarea" || element.namespaceURI !== HTML_NS || !isWritableSignal(handle))
12316
+ presentationMiss(false);
12317
+ validateDirectSignalControl(element, site);
12318
+ const value = handle.get();
12319
+ if (typeof value !== "string") presentationMiss(false);
12320
+ const owner = scope.block.idState.renderOwner;
12321
+ const lease = owner.controlLeases?.get(element);
12322
+ const valid = (retired = false) => owner.bindingContainer.contains(element) && (!retired || frame.lease.valid?.() !== false) && (lease !== void 0 && !retired ? lease.owner === owner && lease.active() && runWithBlockSignalOwner(scope, () => lease.matches(handle)) : !(0, import_control_handoff.hasSignalControlBinding)(element, "value") && !(0, import_early_values.hasHydrationControlSignalWriter)(element, "value"));
12323
+ if (!valid()) presentationMiss(false);
12324
+ const prior = previous;
12325
+ const reusable = prior?.[DIRECT_SIGNAL_BINDING] === true && !prior.disposed && prior.input === void 0 && prior.handle === handle && prior.target === element && prior.kind === "value" && prior.site === site;
12326
+ const binding = reusable ? prior : {
12327
+ [DIRECT_SIGNAL_BINDING]: true,
12328
+ scope,
12329
+ target: element,
12330
+ kind: "value",
12331
+ site,
12332
+ handle,
12333
+ value,
12334
+ disposed: false
12335
+ };
12336
+ (frame.controls ??= /* @__PURE__ */ new Map()).set(element, { valid, binding, lease });
12337
+ trackPresentationFrame(frame);
12338
+ if (!reusable) registerHookCleanup(scope, () => disposeDirectSignalBinding(binding));
12339
+ if (binding.unsubscribe === void 0) {
12340
+ const notify = Object.assign(
12341
+ () => {
12342
+ if (binding.controlWriterCleanup !== void 0) updateDirectSignalBinding(binding);
12343
+ },
12344
+ {
12345
+ [import_read_protocol.NATIVE_TRANSITION_CONSUMER]: {
12346
+ active: () => binding.controlWriterCleanup !== void 0 && !binding.disposed && !scope.block.disposed,
12347
+ prepare: () => prepareNativeTransitionBlock(scope.block)
12348
+ }
12349
+ }
12350
+ );
12351
+ const stop = handle[import_types.SIGNAL_BINDING_SUBSCRIBE](
12352
+ notify,
12353
+ () => disposeDirectSignalBinding(binding)
12354
+ );
12355
+ if (typeof stop !== "function") throw new TypeError((0, import_error_codes_client_generated.formatClientError)(74));
12356
+ if (binding.disposed || scope.block.disposed) {
12357
+ stop();
12358
+ presentationMiss(false);
12359
+ }
12360
+ binding.unsubscribe = stop;
12361
+ }
12362
+ preparePresentationOperation(frame, element, "value", () => {
12363
+ if (binding.disposed || scope.block.disposed) return;
12364
+ runWithBlockSignalOwner(scope, () => {
12365
+ if (!valid()) throw new Error((0, import_error_codes_client_generated.formatClientError)(77));
12366
+ const before = (0, import_event_capture.snapshotHydrationControl)(element);
12367
+ const ctrl = armControlled(element);
12368
+ ctrl.composing = before.composing || lease?.composing() === true;
12369
+ if (ctrl.composing) element.addEventListener("blur", onCtrlCompositionEnd);
12370
+ ctrl.v = UNCONTROLLED;
12371
+ let failed = false;
12372
+ let failure;
12373
+ if (lease !== void 0) {
12374
+ try {
12375
+ lease.retire();
12376
+ } catch (error) {
12377
+ failed = true;
12378
+ failure = error;
12379
+ } finally {
12380
+ lease.owner = void 0;
12381
+ }
12382
+ }
12383
+ if (lease !== void 0 && !scope.block.disposed && !valid(true))
12384
+ throw failed ? failure : new Error((0, import_error_codes_client_generated.formatClientError)(77));
12385
+ if (lease !== void 0) owner.controlLeases.delete(element);
12386
+ if (!binding.disposed && !scope.block.disposed) {
12387
+ const snapshot = (0, import_event_capture.snapshotHydrationControl)(element);
12388
+ binding.value = element.value;
12389
+ binding.pendingControl = snapshot.editRevision > (lease === void 0 ? 0 : before.editRevision);
12390
+ installDirectSignalControl(binding);
12391
+ if (!binding.pendingControl) (0, import_event_capture.consumeHydrationControl)(element, snapshot.revision);
12392
+ if (binding.pendingControl) queueDirectSignalControlAdoption(binding);
12393
+ else {
12394
+ const current = readSignalBinding(handle);
12395
+ ctrl.sawV = true;
12396
+ ctrl.v = value;
12397
+ binding.value = current;
12398
+ writeDirectSignalBinding(binding, current);
12399
+ }
12400
+ }
12401
+ if (failed) reportRendererOwnerError(scope, failure);
12402
+ });
12403
+ });
12404
+ return binding;
12405
+ });
12406
+ }
12215
12407
  function presentationHostWrite(writer, ...args) {
12216
12408
  const frame = PRESENTATION_HYDRATION;
12217
12409
  if (frame === null) return writer(...args);
@@ -12243,6 +12435,20 @@ function presentationHostWrite(writer, ...args) {
12243
12435
  function presentationWrite(writer, kind, ...args) {
12244
12436
  const frame = PRESENTATION_HYDRATION;
12245
12437
  if (frame === null) return writer(...args);
12438
+ if (frame.lease.host !== void 0) {
12439
+ const channels = frame.lease.host;
12440
+ const changed2 = kind.endsWith("IfChanged") || kind.startsWith("updateFresh");
12441
+ const element2 = kind === "bindSignalAttribute" || kind === "nativeStyleBinding" || kind === "nativeProjectionBinding" ? args[2] : args[changed2 ? 2 : 0];
12442
+ const keys = kind === "nativeProjectionBinding" ? args[4].map((field) => field === "className" ? "class" : field) : kind === "setStyleProperties" ? args[1].filter((_, index) => index % 2 === 0).map((key2) => "style:" + key2) : [
12443
+ kind === "nativeStyleBinding" || kind === "setStyle" ? "style" : kind === "setStyleProperty" ? "style:" + args[1] : kind.includes("Class") ? "class" : kind === "bindSignalAttribute" ? args[3] : args[changed2 ? 3 : 1]
12444
+ ];
12445
+ if (element2 !== frame.lease.root || keys.some((key2) => !channels.has(key2)) || kind === "bindSignalValue" || kind === "setEventHandler" || kind === "bindSignalText" || kind === "setText" || kind === "markDangerouslySetInnerHTMLChildren")
12446
+ presentationMiss(false);
12447
+ }
12448
+ if (kind === "queueNativeChangeDiagnostic") {
12449
+ preparePresentationOperation(frame, args[0], "nativeChangeDiagnostic", () => writer(...args));
12450
+ return void 0;
12451
+ }
12246
12452
  if (kind === "markDangerouslySetInnerHTMLChildren") {
12247
12453
  const element2 = args[0];
12248
12454
  if (!frame.writes.get(element2)?.has("hostProps") || element2[DANGER_HTML_ACTIVE] === true)
@@ -12250,28 +12456,32 @@ function presentationWrite(writer, kind, ...args) {
12250
12456
  preparePresentationOperation(frame, element2, "hostChildren", () => writer(element2));
12251
12457
  return void 0;
12252
12458
  }
12253
- if (kind === "bindSignalText") {
12254
- const value = args[3];
12255
- if (value !== null && (typeof value === "object" || typeof value === "function") || typeof args[7] !== "string")
12256
- presentationMiss(false);
12257
- return bindingText(args[2], value, args[7]);
12258
- }
12459
+ if (kind === "bindSignalText") return preparePresentationSignalBinding(args, frame, true);
12259
12460
  if (kind === "setText") {
12260
12461
  const text = coerceText(args[1]);
12261
12462
  preparePresentationOperation(frame, args[0], "text", () => writer(args[0], text));
12262
12463
  return void 0;
12263
12464
  }
12264
- if (kind === "bindSignalAttribute") return preparePresentationSignalAttribute(args, frame);
12465
+ if (kind === "bindSignalAttribute") return preparePresentationSignalBinding(args, frame);
12466
+ if (kind === "bindSignalValue") return preparePresentationSignalValue(args, frame);
12265
12467
  if (kind === "nativeStyleBinding" || kind === "nativeProjectionBinding") {
12266
12468
  const [owner, slot, el] = args;
12267
12469
  const style = kind === "nativeStyleBinding";
12268
- nativePresentationBinding(
12269
- owner,
12270
- slot,
12271
- el,
12272
- style ? preparedNativeStyleBody : preparedNativeProjectionBody,
12273
- style ? { el, value: args[3], frame } : { el, compute: args[3], fields: args[4], frame }
12274
- );
12470
+ try {
12471
+ nativePresentationBinding(
12472
+ owner,
12473
+ slot,
12474
+ el,
12475
+ style ? preparedNativeStyleBody : preparedNativeProjectionBody,
12476
+ style ? { el, value: args[3], frame } : { el, compute: args[3], fields: args[4], frame }
12477
+ );
12478
+ } finally {
12479
+ if (frame.hostSuccessors !== void 0) {
12480
+ const binding = owner.slots[slot];
12481
+ if (binding !== void 0)
12482
+ frame.hostSuccessors.set(binding, () => disposeNativeStyleBinding(binding));
12483
+ }
12484
+ }
12275
12485
  return void 0;
12276
12486
  }
12277
12487
  const prepared = args.slice();
@@ -12490,11 +12700,14 @@ function disposeDirectSignalBinding(binding) {
12490
12700
  if (DEFERRED_LAYOUT_DRIVER?.stageAction(() => disposeDirectSignalBinding(binding)) === true)
12491
12701
  return;
12492
12702
  binding.disposed = true;
12493
- binding.unsubscribe?.();
12494
- retireNativeTransitionBlock(binding.scope.block);
12495
- binding.controlWriterCleanup?.();
12496
- if (binding.input !== void 0) {
12497
- domNode(binding.target).removeEventListener("input", binding.input);
12703
+ try {
12704
+ binding.unsubscribe?.();
12705
+ } finally {
12706
+ retireNativeTransitionBlock(binding.scope.block);
12707
+ binding.controlWriterCleanup?.();
12708
+ if (binding.input !== void 0) {
12709
+ domNode(binding.target).removeEventListener("input", binding.input);
12710
+ }
12498
12711
  }
12499
12712
  }
12500
12713
  function directSignalControlValue(binding, snapshot) {
@@ -12659,6 +12872,8 @@ function activateDirectSignalBinding(binding, revision) {
12659
12872
  }
12660
12873
  }
12661
12874
  function createDirectSignalBinding(scope, target, value, site, kind, name, attributeKind, text) {
12875
+ if (kind === "value" && scope.block.idState.renderOwner?.controlLeases?.has(target))
12876
+ presentationMiss(false);
12662
12877
  const handle = isSignalHandle(value) ? value : null;
12663
12878
  const binding = {
12664
12879
  [DIRECT_SIGNAL_BINDING]: true,
@@ -14635,6 +14850,8 @@ function bindSignalHostPropSources(scope, previous, element, sources, site, hasN
14635
14850
  binding.sources = sources;
14636
14851
  }
14637
14852
  const valueControl = winningSignalHostControl(sources, "value");
14853
+ if (valueControl !== null && scope.block.idState.renderOwner?.controlLeases?.has(element))
14854
+ presentationMiss(false);
14638
14855
  const checkedControl = winningSignalHostControl(sources, "checked");
14639
14856
  const controlSnapshot = isWritableSignal(valueControl) || isWritableSignal(checkedControl) ? (0, import_event_capture.snapshotHydrationControl)(element) : null;
14640
14857
  if (controlSnapshot !== null) {
@@ -16287,6 +16504,7 @@ function setNativeChangeDiagnosticMetadata(el, value) {
16287
16504
  if (value === "runtime") queueDevFormDiagnostic(el, CURRENT_SCOPE ?? void 0, true);
16288
16505
  }
16289
16506
  function setValue(el, value) {
16507
+ if (CURRENT_SCOPE?.block.idState.renderOwner?.controlLeases?.has(el)) presentationMiss(false);
16290
16508
  const input = el;
16291
16509
  const ctrl = armControlled(el);
16292
16510
  if (TRANSITION_JOURNAL !== null) journalControlled(el, "value", "defaultValue");
@@ -27046,6 +27264,11 @@ function makeRoot(container, rootBlock, currentBody, currentKey, idState, output
27046
27264
  }
27047
27265
  unmounted = true;
27048
27266
  renderOwner.disposed = true;
27267
+ if (renderOwner.controlLeases !== void 0) {
27268
+ for (const lease of renderOwner.controlLeases.values())
27269
+ if (lease !== void 0) lease.owner = void 0;
27270
+ renderOwner.controlLeases.clear();
27271
+ }
27049
27272
  if (renderOwner.bindingLeases !== void 0) {
27050
27273
  for (const lease of renderOwner.bindingLeases) {
27051
27274
  (0, import_dom_binding_handoff.releaseBindingHandoff)(lease);
@@ -27106,7 +27329,8 @@ function makeRoot(container, rootBlock, currentBody, currentKey, idState, output
27106
27329
  }
27107
27330
  function createRootWithOutputHandler(container, options, outputHandler) {
27108
27331
  assertValidRootContainer(container);
27109
- if (options?.bindingLeases !== void 0) throw new Error((0, import_error_codes_client_generated.formatClientError)(76));
27332
+ if (options?.bindingLeases !== void 0 || options?.controlLeases !== void 0)
27333
+ throw new Error((0, import_error_codes_client_generated.formatClientError)(76));
27110
27334
  options = warnCreateRootElementOption(options);
27111
27335
  const ownerToken = claimRootContainer(container);
27112
27336
  registerDelegationTarget(container, true);
@@ -27166,12 +27390,20 @@ function hydrateRoot(container, bodyOrElement, propsOrOptions, rootOptions) {
27166
27390
  const bindingLeases = rootOptions?.bindingLeases?.map((handle) => {
27167
27391
  const capability = handle;
27168
27392
  const lease = capability[import_dom_binding_handoff.BINDING_HANDOFF]?.();
27169
- if (lease === void 0 || !lease.active() || lease.owner !== void 0 || !container.contains(lease.root))
27393
+ if (lease === void 0 || !lease.active() || lease.host !== void 0 && lease.valid?.() === false || lease.owner !== void 0 || !container.contains(lease.root))
27170
27394
  throw new Error((0, import_error_codes_client_generated.formatClientError)(77));
27171
27395
  return lease;
27172
27396
  });
27173
27397
  if (bindingLeases !== void 0 && new Set(bindingLeases).size !== bindingLeases.length)
27174
27398
  throw new Error((0, import_error_codes_client_generated.formatClientError)(78));
27399
+ const controlLeases = rootOptions?.controlLeases?.map((handle) => {
27400
+ const lease = handle?.[import_control_handoff.CONTROL_HANDOFF]?.();
27401
+ if (!bindingLeases?.length || lease === void 0 || !lease.active() || lease.owner !== void 0 || lease.channel !== "value" || lease.control.localName !== "textarea" || !container.contains(lease.control))
27402
+ throw new Error((0, import_error_codes_client_generated.formatClientError)(77));
27403
+ return lease;
27404
+ });
27405
+ if (controlLeases !== void 0 && new Set(controlLeases.map((lease) => lease.control)).size !== controlLeases.length)
27406
+ throw new Error((0, import_error_codes_client_generated.formatClientError)(78));
27175
27407
  const nativeSidecar = findHydrateSeedSidecar(container, import_native_read_seeds.NATIVE_SIGNAL_SEED_ATTR);
27176
27408
  const nativeManifest = nativeSidecar === null ? void 0 : (0, import_native_read_seeds.parseNativeSignalManifest)(
27177
27409
  (STAGED_DOM?.view(nativeSidecar) ?? nativeSidecar).textContent || ""
@@ -27233,6 +27465,10 @@ function hydrateRoot(container, bodyOrElement, propsOrOptions, rootOptions) {
27233
27465
  rootOptions
27234
27466
  );
27235
27467
  const owner = idState.renderOwner;
27468
+ if (controlLeases !== void 0) {
27469
+ owner.controlLeases = new Map(controlLeases.map((lease) => [lease.control, lease]));
27470
+ for (const lease of controlLeases) lease.owner = owner;
27471
+ }
27236
27472
  if (bindingLeases !== void 0) {
27237
27473
  owner.bindingLeases = new Set(bindingLeases);
27238
27474
  owner.bindingContainer = container;
@@ -27266,7 +27502,7 @@ function hydrateRoot(container, bodyOrElement, propsOrOptions, rootOptions) {
27266
27502
  while (firstNode !== null && (firstNode.nodeType === 10 || isRendererHydrationStyle(firstNode)))
27267
27503
  firstNode = getNextSibling(firstNode);
27268
27504
  const hydration = new HydrationCapability(rootBlock, firstNode, seeds);
27269
- if (bindingLeases?.some((lease) => lease.revision !== void 0)) {
27505
+ if (bindingLeases?.length) {
27270
27506
  const attempted = rootBlock;
27271
27507
  hydration.retryPresentation = () => {
27272
27508
  if (owner.disposed || owner.current !== attempted) return;
@@ -27274,7 +27510,12 @@ function hydrateRoot(container, bodyOrElement, propsOrOptions, rootOptions) {
27274
27510
  collectVisibleSubtreeRefs(attempted, refs);
27275
27511
  withRefDetachSuppression(refs, () => unmountBlock(attempted, false));
27276
27512
  queueMicrotask(() => {
27277
- if (!owner.disposed && owner.current === attempted) adopt();
27513
+ if (owner.disposed || owner.current !== attempted) return;
27514
+ try {
27515
+ adopt();
27516
+ } catch (error) {
27517
+ if (!reportUncaughtError(rootBlock, error)) throw error;
27518
+ }
27278
27519
  });
27279
27520
  };
27280
27521
  }
@@ -26,6 +26,7 @@ __export(streamed_signals_exports, {
26
26
  });
27
27
  module.exports = __toCommonJS(streamed_signals_exports);
28
28
  var import_data_encoding = require("../data-encoding.cjs");
29
+ var import_stream_protocol = require("../stream-protocol.cjs");
29
30
  var import_streamed_signals_protocol = require("../streamed-signals-protocol.cjs");
30
31
  var import_signal_query_observation = require("./signal-query-observation.cjs");
31
32
  const DEFAULT_MAX_FRAME_BYTES = 4 * 1024 * 1024;
@@ -182,12 +183,12 @@ function escapeAttribute(value) {
182
183
  }
183
184
  function streamedRendererFrameScript(frame, nonce) {
184
185
  const encoded = (0, import_streamed_signals_protocol.encodeStreamedRendererFrameForScript)(frame);
185
- return `<script${nonce === void 0 ? "" : ` nonce="${escapeAttribute(nonce)}"`}>globalThis.__octaneStreamedRenderer.receive(${encoded});</script>`;
186
+ return `<script ${import_stream_protocol.STREAM_SCRIPT_ATTR}${nonce === void 0 ? "" : ` nonce="${escapeAttribute(nonce)}"`}>globalThis.__octaneStreamedRenderer.receive(${encoded});</script>`;
186
187
  }
187
188
  function streamedSignalSelectionScript(identity, nonce) {
188
189
  if (!(0, import_streamed_signals_protocol.isStreamFrameIdentity)(identity)) throw new TypeError("Invalid streamed signal identity.");
189
190
  const encoded = JSON.stringify(identity).replace(/&/g, "\\u0026").replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
190
- return `<script${nonce === void 0 ? "" : ` nonce="${escapeAttribute(nonce)}"`}>(function(g){var k="__octaneStreamedRenderer",e=g[k];if(!e){var q=[];g[k]={version:1,frames:q,receive:function(f){if(q.length>=512){this.overflow=true;return;}q.push(f);}};}var z="__octaneStreamedSignalSelections",v=g[z];if(!v){var a=[];v=g[z]={version:1,identities:a,register:function(i){if(a.length>=256){this.overflow=true;return;}a.push(i);}};}v.register(${encoded});})(globalThis);</script>`;
191
+ return `<script ${import_stream_protocol.STREAM_SCRIPT_ATTR}${nonce === void 0 ? "" : ` nonce="${escapeAttribute(nonce)}"`}>(function(g){var k="__octaneStreamedRenderer",e=g[k];if(!e){var q=[];g[k]={version:1,frames:q,receive:function(f){if(q.length>=512){this.overflow=true;return;}q.push(f);}};}var z="__octaneStreamedSignalSelections",v=g[z];if(!v){var a=[];v=g[z]={version:1,identities:a,register:function(i){if(a.length>=256){this.overflow=true;return;}a.push(i);}};}v.register(${encoded});})(globalThis);</script>`;
191
192
  }
192
193
  function createStreamedSignalInjection(identity, result, options = {}) {
193
194
  const budget = limits(options);