@fictjs/runtime 0.16.0 → 0.17.1

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 (81) hide show
  1. package/dist/advanced.cjs +9 -9
  2. package/dist/advanced.d.cts +3 -3
  3. package/dist/advanced.d.ts +3 -3
  4. package/dist/advanced.js +4 -4
  5. package/dist/{binding-CQUGLLBI.d.ts → binding-BfzY9rae.d.ts} +2 -2
  6. package/dist/{binding-BlABuUiG.d.cts → binding-CDR2ERoq.d.cts} +2 -2
  7. package/dist/{chunk-CBRGOLTR.cjs → chunk-2J4INHDT.cjs} +40 -40
  8. package/dist/{chunk-CBRGOLTR.cjs.map → chunk-2J4INHDT.cjs.map} +1 -1
  9. package/dist/{chunk-BADX4WTQ.cjs → chunk-CKKZDUHM.cjs} +21 -18
  10. package/dist/chunk-CKKZDUHM.cjs.map +1 -0
  11. package/dist/{chunk-ZWQLXWSV.js → chunk-DHRRJJ6W.js} +8 -5
  12. package/dist/chunk-DHRRJJ6W.js.map +1 -0
  13. package/dist/{chunk-4P4DYWLQ.js → chunk-LFLFSJFU.js} +3 -3
  14. package/dist/{chunk-WJMZ7X46.cjs → chunk-NBDEMBBX.cjs} +47 -85
  15. package/dist/chunk-NBDEMBBX.cjs.map +1 -0
  16. package/dist/{chunk-MAHWGB55.js → chunk-OKPQWORE.js} +47 -85
  17. package/dist/chunk-OKPQWORE.js.map +1 -0
  18. package/dist/{chunk-RK2WSQYL.js → chunk-OLHZBAIF.js} +3 -3
  19. package/dist/{chunk-ZJZ6LMDN.js → chunk-R2HYEOP7.js} +470 -172
  20. package/dist/chunk-R2HYEOP7.js.map +1 -0
  21. package/dist/{chunk-AR2T7JEX.cjs → chunk-UG2IFQOY.cjs} +650 -352
  22. package/dist/chunk-UG2IFQOY.cjs.map +1 -0
  23. package/dist/{chunk-ECNK25S4.cjs → chunk-VP2WC7X3.cjs} +8 -8
  24. package/dist/{chunk-ECNK25S4.cjs.map → chunk-VP2WC7X3.cjs.map} +1 -1
  25. package/dist/{devtools-DWIZRe7L.d.cts → devtools-BwkkQ6DN.d.cts} +1 -1
  26. package/dist/{devtools-DNnnDGu1.d.ts → devtools-CK3SVU_w.d.ts} +1 -1
  27. package/dist/index.cjs +55 -42
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +4 -4
  30. package/dist/index.d.ts +4 -4
  31. package/dist/index.dev.js +260 -156
  32. package/dist/index.dev.js.map +1 -1
  33. package/dist/index.js +16 -3
  34. package/dist/index.js.map +1 -1
  35. package/dist/internal-list.cjs +4 -4
  36. package/dist/internal-list.js +3 -3
  37. package/dist/internal.cjs +5 -5
  38. package/dist/internal.d.cts +4 -4
  39. package/dist/internal.d.ts +4 -4
  40. package/dist/internal.js +4 -4
  41. package/dist/jsx-dev-runtime.cjs.map +1 -1
  42. package/dist/jsx-dev-runtime.d.cts +46 -0
  43. package/dist/jsx-dev-runtime.d.ts +46 -0
  44. package/dist/jsx-dev-runtime.js.map +1 -1
  45. package/dist/jsx-runtime.cjs.map +1 -1
  46. package/dist/jsx-runtime.d.cts +46 -0
  47. package/dist/jsx-runtime.d.ts +46 -0
  48. package/dist/jsx-runtime.js.map +1 -1
  49. package/dist/loader.cjs +143 -26
  50. package/dist/loader.cjs.map +1 -1
  51. package/dist/loader.d.cts +1 -1
  52. package/dist/loader.d.ts +1 -1
  53. package/dist/loader.js +122 -5
  54. package/dist/loader.js.map +1 -1
  55. package/dist/{props-DabFQwLR.d.ts → props-CFoQ471Y.d.ts} +47 -1
  56. package/dist/{props-tImUZAty.d.cts → props-D4tK8Gn0.d.cts} +47 -1
  57. package/dist/{resume-C5IKAIdh.d.ts → resume-C166aAVg.d.ts} +2 -2
  58. package/dist/{resume-DPZxmA95.d.cts → resume-C20cRVj9.d.cts} +2 -2
  59. package/dist/{scope-gpOMWTlf.d.ts → scope-BFzD_7hx.d.ts} +1 -1
  60. package/dist/{scope-GwC4DJ50.d.cts → scope-Ck3mTQVS.d.cts} +1 -1
  61. package/package.json +1 -1
  62. package/src/binding.ts +561 -166
  63. package/src/context.ts +8 -1
  64. package/src/dom.ts +26 -44
  65. package/src/effect.ts +9 -12
  66. package/src/error-boundary.ts +8 -0
  67. package/src/hydration.ts +25 -6
  68. package/src/jsx.ts +46 -0
  69. package/src/lifecycle.ts +31 -79
  70. package/src/loader.ts +153 -4
  71. package/src/resume.ts +5 -5
  72. package/src/signal.ts +4 -1
  73. package/src/suspense.ts +8 -0
  74. package/dist/chunk-AR2T7JEX.cjs.map +0 -1
  75. package/dist/chunk-BADX4WTQ.cjs.map +0 -1
  76. package/dist/chunk-MAHWGB55.js.map +0 -1
  77. package/dist/chunk-WJMZ7X46.cjs.map +0 -1
  78. package/dist/chunk-ZJZ6LMDN.js.map +0 -1
  79. package/dist/chunk-ZWQLXWSV.js.map +0 -1
  80. /package/dist/{chunk-4P4DYWLQ.js.map → chunk-LFLFSJFU.js.map} +0 -0
  81. /package/dist/{chunk-RK2WSQYL.js.map → chunk-OLHZBAIF.js.map} +0 -0
@@ -40,7 +40,7 @@ import {
40
40
  setTransitionContext,
41
41
  signal,
42
42
  untrack
43
- } from "./chunk-MAHWGB55.js";
43
+ } from "./chunk-OKPQWORE.js";
44
44
 
45
45
  // src/transition.ts
46
46
  function startTransition(fn) {
@@ -340,7 +340,7 @@ function withHydration(root, fn) {
340
340
  owner
341
341
  });
342
342
  try {
343
- fn();
343
+ return fn();
344
344
  } finally {
345
345
  hydrationStack.pop();
346
346
  }
@@ -352,7 +352,7 @@ function withHydrationRange(start, end, owner, fn) {
352
352
  owner
353
353
  });
354
354
  try {
355
- fn();
355
+ return fn();
356
356
  } finally {
357
357
  hydrationStack.pop();
358
358
  }
@@ -383,6 +383,18 @@ function claimNodes(templateRoot, fallback) {
383
383
  }
384
384
  return frag;
385
385
  }
386
+ function claimText(value, fallback) {
387
+ const ctx = hydrationStack[hydrationStack.length - 1];
388
+ if (!ctx || !ctx.cursor || ctx.cursor === ctx.boundary || ctx.cursor.nodeType !== Node.TEXT_NODE) {
389
+ return fallback();
390
+ }
391
+ const text = ctx.cursor;
392
+ ctx.cursor = text.nextSibling;
393
+ if (text.data !== value) {
394
+ text.data = value;
395
+ }
396
+ return text;
397
+ }
386
398
  function isHydratingActive() {
387
399
  return hydrationStack.length > 0;
388
400
  }
@@ -395,7 +407,9 @@ var PROP_CACHE = Symbol("fict:prop");
395
407
  var STYLE_CACHE = Symbol("fict:style");
396
408
  var CLASS_STATE_CACHE = Symbol("fict:class-state");
397
409
  var CLASS_VALUE_CACHE = Symbol("fict:class-value");
398
- var EVENT_TUPLE_LISTENER_CACHE = Symbol("fict:event-tuple-listener-cache");
410
+ var EVENT_LISTENER_CACHE = Symbol("fict:event-listener-cache");
411
+ var REF_ASSIGN_CACHE = Symbol("fict:ref-assign-cache");
412
+ var CHILDREN_BINDING_CACHE = Symbol("fict:children-binding-cache");
399
413
  var NON_REACTIVE_FN_MARKER = Symbol.for("fict:non-reactive-fn");
400
414
  var REACTIVE_FN_MARKER = Symbol.for("fict:reactive-fn");
401
415
  var NON_REACTIVE_FN_REGISTRY_KEY = Symbol.for("fict:non-reactive-fn-registry");
@@ -423,6 +437,10 @@ function isExplicitReactiveFn(value) {
423
437
  if (typeof value !== "function") return false;
424
438
  return value[REACTIVE_FN_MARKER] === true;
425
439
  }
440
+ var registeredCreateElement;
441
+ function registerCreateElement(fn) {
442
+ registeredCreateElement = fn;
443
+ }
426
444
  function isReactive(value) {
427
445
  if (typeof value !== "function") return false;
428
446
  if (isNonReactiveFn(value)) return false;
@@ -1085,26 +1103,18 @@ function globalEventHandler(e) {
1085
1103
  if (!node) return false;
1086
1104
  const handler = node[key];
1087
1105
  if (handler && !node.disabled) {
1088
- const resolveData = (value) => {
1089
- if (typeof value === "function") {
1090
- try {
1091
- const fn = value;
1092
- return fn.length > 0 ? fn(e) : fn();
1093
- } catch {
1094
- return value();
1095
- }
1096
- }
1097
- return value;
1098
- };
1099
1106
  const rawData = node[dataKey];
1100
1107
  const hasData = rawData !== void 0;
1101
- const resolvedNodeData = hasData ? resolveData(rawData) : void 0;
1108
+ const resolvedNodeData = hasData ? resolveEventData(rawData, e) : void 0;
1102
1109
  batch2(() => {
1103
1110
  if (typeof handler === "function") {
1104
1111
  callEventHandler(handler, e, node, hasData ? resolvedNodeData : void 0);
1105
1112
  } else if (Array.isArray(handler)) {
1106
- const tupleData = resolveData(handler[1]);
1107
- callEventHandler(handler[0], e, node, tupleData);
1113
+ const tupleHandler = resolveEventHandlerValue(
1114
+ handler[0]
1115
+ );
1116
+ const tupleData = resolveEventData(handler[1], e);
1117
+ callEventHandler(tupleHandler, e, node, tupleData);
1108
1118
  }
1109
1119
  });
1110
1120
  if (e.cancelBubble) return false;
@@ -1152,89 +1162,104 @@ function globalEventHandler(e) {
1152
1162
  }
1153
1163
  retarget(oriTarget);
1154
1164
  }
1155
- function addEventListener(node, name, handler, delegate) {
1165
+ function addEventListener(node, name, handler, delegate, options) {
1156
1166
  if (delegate) {
1157
1167
  const key = `$$${name}`;
1158
1168
  const dataKey = `${key}Data`;
1169
+ const rootRef2 = getCurrentRoot();
1170
+ const delegationDocument = resolveDelegationDocument(node, rootRef2);
1171
+ delegateEvents([name], delegationDocument);
1159
1172
  if (handler == null) {
1160
1173
  ;
1161
1174
  node[key] = void 0;
1162
1175
  node[dataKey] = void 0;
1163
1176
  return;
1164
1177
  }
1165
- if (Array.isArray(handler)) {
1166
- ;
1167
- node[key] = handler[0];
1168
- node[dataKey] = handler[1];
1169
- } else {
1170
- ;
1171
- node[key] = handler;
1172
- node[dataKey] = void 0;
1173
- }
1178
+ ;
1179
+ node[key] = createEventInvoker(
1180
+ name,
1181
+ handler,
1182
+ node,
1183
+ rootRef2
1184
+ );
1185
+ node[dataKey] = void 0;
1174
1186
  return;
1175
1187
  }
1188
+ removeStoredEventListener(node, name, options);
1176
1189
  if (handler == null) return;
1177
- if (Array.isArray(handler)) {
1178
- const store = getTupleEventListenerStore(node);
1179
- const existing = store.get(name);
1180
- if (existing) {
1181
- node.removeEventListener(name, existing);
1182
- }
1183
- const handlerFn = handler[0];
1184
- const wrapped = (e) => handlerFn.call(node, handler[1], e);
1185
- store.set(name, wrapped);
1186
- node.addEventListener(name, wrapped);
1187
- return;
1190
+ const rootRef = getCurrentRoot();
1191
+ const wrapped = createEventInvoker(name, handler, node, rootRef);
1192
+ node.addEventListener(name, wrapped, options);
1193
+ getStoredEventListenerStore(node).set(getEventListenerStoreKey(name, options), {
1194
+ listener: wrapped,
1195
+ options
1196
+ });
1197
+ }
1198
+ function resolveDelegationDocument(node, rootRef) {
1199
+ const nodeDocument = node.ownerDocument ?? void 0;
1200
+ if (rootRef?.ownerDocument && nodeDocument?.defaultView == null) {
1201
+ return rootRef.ownerDocument;
1188
1202
  }
1189
- node.addEventListener(name, handler);
1203
+ return nodeDocument ?? rootRef?.ownerDocument ?? document;
1190
1204
  }
1191
- function getTupleEventListenerStore(node) {
1205
+ function getStoredEventListenerStore(node) {
1192
1206
  const host = node;
1193
- if (!host[EVENT_TUPLE_LISTENER_CACHE]) {
1194
- host[EVENT_TUPLE_LISTENER_CACHE] = /* @__PURE__ */ new Map();
1207
+ if (!host[EVENT_LISTENER_CACHE]) {
1208
+ host[EVENT_LISTENER_CACHE] = /* @__PURE__ */ new Map();
1195
1209
  }
1196
- return host[EVENT_TUPLE_LISTENER_CACHE];
1210
+ return host[EVENT_LISTENER_CACHE];
1211
+ }
1212
+ function getEventListenerStoreKey(name, options) {
1213
+ const capture = typeof options === "boolean" ? options : options?.capture === true;
1214
+ const passive = typeof options === "object" && options?.passive === true;
1215
+ const once = typeof options === "object" && options?.once === true;
1216
+ return `${name}:${capture ? 1 : 0}:${passive ? 1 : 0}:${once ? 1 : 0}`;
1197
1217
  }
1198
- function removeStoredTupleEventListener(node, name) {
1218
+ function removeStoredEventListener(node, name, options) {
1199
1219
  const host = node;
1200
- const store = host[EVENT_TUPLE_LISTENER_CACHE];
1220
+ const store = host[EVENT_LISTENER_CACHE];
1201
1221
  if (!store) return;
1202
- const wrapped = store.get(name);
1203
- if (!wrapped) return;
1204
- node.removeEventListener(name, wrapped);
1205
- store.delete(name);
1222
+ const entry = store.get(getEventListenerStoreKey(name, options));
1223
+ if (!entry) return;
1224
+ node.removeEventListener(name, entry.listener, entry.options);
1225
+ store.delete(getEventListenerStoreKey(name, options));
1206
1226
  if (store.size === 0) {
1207
- delete host[EVENT_TUPLE_LISTENER_CACHE];
1227
+ delete host[EVENT_LISTENER_CACHE];
1208
1228
  }
1209
1229
  }
1210
- function bindEvent(el, eventName, handler, options) {
1211
- if (handler == null) return () => {
1212
- };
1213
- const rootRef = getCurrentRoot();
1214
- const shouldDelegate = options == null && DelegatedEvents.has(eventName);
1215
- if (shouldDelegate) {
1216
- const key = `$$${eventName}`;
1217
- delegateEvents([eventName]);
1218
- const resolveHandler = isStrictlyReactive(handler) ? handler : () => handler;
1219
- el[key] = function(...args) {
1220
- try {
1221
- const fn = resolveHandler();
1222
- callEventHandler(fn, args[0], el);
1223
- } catch (err) {
1224
- if (!handleError(err, { source: "event", eventName }, rootRef)) {
1225
- throw err;
1226
- }
1227
- }
1228
- };
1229
- return () => {
1230
- el[key] = void 0;
1231
- };
1230
+ function resolveEventData(value, event) {
1231
+ if (typeof value !== "function") return value;
1232
+ if (isReactive(value)) {
1233
+ return value();
1232
1234
  }
1233
- const getHandler = isStrictlyReactive(handler) ? handler : () => handler;
1234
- const wrapped = (event) => {
1235
+ try {
1236
+ const fn = value;
1237
+ return fn.length > 0 ? fn(event) : fn();
1238
+ } catch {
1239
+ return value();
1240
+ }
1241
+ }
1242
+ function resolveEventHandlerValue(value) {
1243
+ if (isStrictlyReactive(value)) {
1244
+ return value();
1245
+ }
1246
+ return value;
1247
+ }
1248
+ function createEventInvoker(eventName, handler, node, rootRef) {
1249
+ return (event) => {
1235
1250
  try {
1236
- const resolved = getHandler();
1237
- callEventHandler(resolved, event, el);
1251
+ if (Array.isArray(handler)) {
1252
+ const resolvedHandler2 = resolveEventHandlerValue(
1253
+ handler[0]
1254
+ );
1255
+ const data = resolveEventData(handler[1], event);
1256
+ callEventHandler(resolvedHandler2, event, node, data);
1257
+ return;
1258
+ }
1259
+ const resolvedHandler = resolveEventHandlerValue(
1260
+ handler
1261
+ );
1262
+ callEventHandler(resolvedHandler, event, node);
1238
1263
  } catch (err) {
1239
1264
  if (handleError(err, { source: "event", eventName }, rootRef)) {
1240
1265
  return;
@@ -1242,55 +1267,340 @@ function bindEvent(el, eventName, handler, options) {
1242
1267
  throw err;
1243
1268
  }
1244
1269
  };
1245
- el.addEventListener(eventName, wrapped, options);
1246
- const cleanup = () => el.removeEventListener(eventName, wrapped, options);
1270
+ }
1271
+ function bindEvent(el, eventName, handler, options) {
1272
+ if (handler == null) return () => {
1273
+ };
1274
+ const shouldDelegate = options == null && DelegatedEvents.has(eventName);
1275
+ if (shouldDelegate) {
1276
+ addEventListener(el, eventName, handler, true);
1277
+ return () => {
1278
+ addEventListener(el, eventName, null, true);
1279
+ };
1280
+ }
1281
+ addEventListener(
1282
+ el,
1283
+ eventName,
1284
+ handler,
1285
+ false,
1286
+ options
1287
+ );
1288
+ const cleanup = () => removeStoredEventListener(el, eventName, options);
1247
1289
  registerRootCleanup(cleanup);
1248
1290
  return cleanup;
1249
1291
  }
1250
- function bindRef(el, ref) {
1292
+ function bindRef(el, ref, registerCleanup = true) {
1251
1293
  if (ref == null) return () => {
1252
1294
  };
1253
1295
  const getRef = isReactive(ref) ? ref : () => ref;
1254
- const applyRef2 = (refValue) => {
1296
+ let currentRef;
1297
+ const applyRefValue = (refValue, value) => {
1255
1298
  if (refValue == null) return;
1256
1299
  if (typeof refValue === "function") {
1257
1300
  ;
1258
- refValue(el);
1301
+ refValue(value);
1259
1302
  } else if (typeof refValue === "object" && "current" in refValue) {
1260
1303
  ;
1261
- refValue.current = el;
1304
+ refValue.current = value;
1262
1305
  }
1263
1306
  };
1264
- const initialRef = getRef();
1265
- applyRef2(initialRef);
1307
+ const clearCurrentRef = () => {
1308
+ if (currentRef == null) return;
1309
+ applyRefValue(currentRef, null);
1310
+ currentRef = void 0;
1311
+ };
1312
+ const syncRef = (nextRef) => {
1313
+ if (nextRef === currentRef) return;
1314
+ clearCurrentRef();
1315
+ currentRef = nextRef;
1316
+ applyRefValue(currentRef, el);
1317
+ };
1318
+ let disposeTracking;
1266
1319
  if (isReactive(ref)) {
1267
- const cleanup2 = createRenderEffect(() => {
1268
- const currentRef = getRef();
1269
- applyRef2(currentRef);
1320
+ disposeTracking = createRenderEffect(() => {
1321
+ syncRef(getRef());
1270
1322
  });
1271
- registerRootCleanup(cleanup2);
1272
- const nullifyCleanup = () => {
1273
- const currentRef = getRef();
1274
- if (currentRef && typeof currentRef === "object" && "current" in currentRef) {
1275
- ;
1276
- currentRef.current = null;
1277
- }
1278
- };
1279
- registerRootCleanup(nullifyCleanup);
1280
- return () => {
1281
- cleanup2();
1282
- nullifyCleanup();
1283
- };
1323
+ } else {
1324
+ syncRef(getRef());
1325
+ }
1326
+ if (registerCleanup) {
1327
+ registerRootCleanup(clearCurrentRef);
1328
+ }
1329
+ return () => {
1330
+ disposeTracking?.();
1331
+ clearCurrentRef();
1332
+ };
1333
+ }
1334
+ function resolveAssignedChildrenValue(value) {
1335
+ if (typeof value === "function") {
1336
+ return isReactive(value) ? value() : null;
1284
1337
  }
1285
- const cleanup = () => {
1286
- const refValue = getRef();
1287
- if (refValue && typeof refValue === "object" && "current" in refValue) {
1338
+ return value ?? null;
1339
+ }
1340
+ function resolveAssignedRefValue(value) {
1341
+ if (isReactive(value)) {
1342
+ return value();
1343
+ }
1344
+ return value;
1345
+ }
1346
+ function createAssignedRefState(node, owner, initialValue) {
1347
+ const valueSignal = signal(initialValue);
1348
+ let currentRef;
1349
+ const applyRefValue = (refValue, value) => {
1350
+ if (refValue == null) return;
1351
+ if (typeof refValue === "function") {
1352
+ ;
1353
+ refValue(value);
1354
+ } else if (typeof refValue === "object" && "current" in refValue) {
1288
1355
  ;
1289
- refValue.current = null;
1356
+ refValue.current = value;
1290
1357
  }
1291
1358
  };
1292
- registerRootCleanup(cleanup);
1293
- return cleanup;
1359
+ const clearCurrentRef = () => {
1360
+ if (currentRef == null) return;
1361
+ applyRefValue(currentRef, null);
1362
+ currentRef = void 0;
1363
+ };
1364
+ const syncRef = (nextRef) => {
1365
+ if (nextRef === currentRef) return;
1366
+ clearCurrentRef();
1367
+ currentRef = nextRef;
1368
+ applyRefValue(currentRef, node);
1369
+ };
1370
+ const disposeTracking = createRenderEffect(() => {
1371
+ syncRef(resolveAssignedRefValue(valueSignal()));
1372
+ });
1373
+ return {
1374
+ cleanup: () => {
1375
+ disposeTracking();
1376
+ clearCurrentRef();
1377
+ },
1378
+ owner,
1379
+ registeredCleanup: false,
1380
+ value: (next) => {
1381
+ valueSignal(next);
1382
+ syncRef(resolveAssignedRefValue(next));
1383
+ }
1384
+ };
1385
+ }
1386
+ function bindAssignedChildren(node, getValue, createElementFn) {
1387
+ const hostRoot = getCurrentRoot();
1388
+ const createFn = createElementFn ?? registeredCreateElement;
1389
+ let currentNodes = [];
1390
+ let currentText = null;
1391
+ let currentRoot = null;
1392
+ let initialHydrating = __fictIsHydrating();
1393
+ const collectCurrentChildren = () => Array.from(node.childNodes);
1394
+ const clearCurrentNodes = () => {
1395
+ if (currentRoot) {
1396
+ destroyRoot(currentRoot);
1397
+ currentRoot = null;
1398
+ }
1399
+ if (currentNodes.length > 0) {
1400
+ removeNodes(currentNodes);
1401
+ currentNodes = [];
1402
+ }
1403
+ currentText = null;
1404
+ };
1405
+ const setTextNode = (textValue, shouldInsert) => {
1406
+ if (!shouldInsert) {
1407
+ clearCurrentNodes();
1408
+ if (node.childNodes.length > 0) {
1409
+ node.replaceChildren();
1410
+ }
1411
+ initialHydrating = false;
1412
+ return;
1413
+ }
1414
+ if (initialHydrating && isHydratingActive()) {
1415
+ const hydratedNodes = collectCurrentChildren();
1416
+ if (hydratedNodes.length === 1 && hydratedNodes[0]?.nodeType === Node.TEXT_NODE) {
1417
+ const hydratedText = hydratedNodes[0];
1418
+ if (hydratedText.data !== textValue) {
1419
+ hydratedText.data = textValue;
1420
+ }
1421
+ currentText = hydratedText;
1422
+ currentNodes = [hydratedText];
1423
+ initialHydrating = false;
1424
+ return;
1425
+ }
1426
+ }
1427
+ const textNode = currentText ?? (node.ownerDocument ?? document).createTextNode(textValue);
1428
+ if (textNode.data !== textValue) {
1429
+ textNode.data = textValue;
1430
+ }
1431
+ if (currentNodes.length === 1 && currentNodes[0] === textNode) {
1432
+ currentText = textNode;
1433
+ return;
1434
+ }
1435
+ if (currentRoot) {
1436
+ destroyRoot(currentRoot);
1437
+ currentRoot = null;
1438
+ }
1439
+ if (currentNodes.length > 0) {
1440
+ removeNodes(currentNodes);
1441
+ currentNodes = [];
1442
+ }
1443
+ node.replaceChildren(textNode);
1444
+ currentText = textNode;
1445
+ currentNodes = [textNode];
1446
+ initialHydrating = false;
1447
+ };
1448
+ const dispose = createRenderEffect(() => {
1449
+ const value = getValue();
1450
+ const isPrimitive = value == null || value === false || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
1451
+ if (isPrimitive) {
1452
+ const textValue = value == null || value === false ? "" : String(value);
1453
+ const shouldInsert = value != null && value !== false;
1454
+ setTextNode(textValue, shouldInsert);
1455
+ return;
1456
+ }
1457
+ clearCurrentNodes();
1458
+ const root = createRootContext(hostRoot);
1459
+ const prev = pushRoot(root);
1460
+ let nodes;
1461
+ let currentHydratedNodes;
1462
+ let handledError = false;
1463
+ try {
1464
+ const ownerDocument = node.ownerDocument ?? hostRoot?.ownerDocument ?? document;
1465
+ const createValue = () => {
1466
+ if (value instanceof Node) {
1467
+ return value;
1468
+ }
1469
+ if (Array.isArray(value)) {
1470
+ if (value.every((v) => v instanceof Node)) {
1471
+ return value;
1472
+ }
1473
+ if (createFn) {
1474
+ const mapped = [];
1475
+ for (const item of value) {
1476
+ mapped.push(...toNodeArray(createFn(item), ownerDocument));
1477
+ }
1478
+ return mapped;
1479
+ }
1480
+ return ownerDocument.createTextNode(String(value));
1481
+ }
1482
+ return createFn ? createFn(value) : ownerDocument.createTextNode(String(value));
1483
+ };
1484
+ const newNode = initialHydrating && isHydratingActive() ? withHydration(node, () => createValue()) : createValue();
1485
+ nodes = toNodeArray(newNode, ownerDocument);
1486
+ if (root.suspended) {
1487
+ handledError = true;
1488
+ destroyRoot(root);
1489
+ return;
1490
+ }
1491
+ if (initialHydrating) {
1492
+ const hydratedNodes = collectCurrentChildren();
1493
+ const reuseHydratedNodes = hydratedNodes.length === nodes.length && nodes.every((candidate, index) => candidate === hydratedNodes[index]);
1494
+ if (reuseHydratedNodes) {
1495
+ currentHydratedNodes = hydratedNodes;
1496
+ } else {
1497
+ node.replaceChildren(...nodes);
1498
+ }
1499
+ } else {
1500
+ node.replaceChildren(...nodes);
1501
+ }
1502
+ } catch (err) {
1503
+ if (handleSuspend(err, root)) {
1504
+ handledError = true;
1505
+ destroyRoot(root);
1506
+ return;
1507
+ }
1508
+ if (handleError(err, { source: "renderChild" }, root)) {
1509
+ handledError = true;
1510
+ destroyRoot(root);
1511
+ return;
1512
+ }
1513
+ throw err;
1514
+ } finally {
1515
+ popRoot(prev);
1516
+ if (!handledError) {
1517
+ flushOnMount(root);
1518
+ }
1519
+ }
1520
+ currentRoot = root;
1521
+ currentNodes = currentHydratedNodes ?? nodes;
1522
+ initialHydrating = false;
1523
+ });
1524
+ return () => {
1525
+ dispose();
1526
+ clearCurrentNodes();
1527
+ };
1528
+ }
1529
+ function updateChildrenBinding(node, value, createElementFn) {
1530
+ const host = node;
1531
+ const createFn = createElementFn ?? registeredCreateElement;
1532
+ const owner = getCurrentRoot();
1533
+ let state = host[CHILDREN_BINDING_CACHE];
1534
+ if (state && state.owner !== owner) {
1535
+ state.cleanup?.();
1536
+ state.cleanup = void 0;
1537
+ delete host[CHILDREN_BINDING_CACHE];
1538
+ state = void 0;
1539
+ }
1540
+ if (!state) {
1541
+ const valueSignal = signal(value);
1542
+ const cleanup = bindAssignedChildren(
1543
+ node,
1544
+ () => resolveAssignedChildrenValue(valueSignal()),
1545
+ createFn
1546
+ );
1547
+ const nextState = {
1548
+ cleanup,
1549
+ owner,
1550
+ value: valueSignal
1551
+ };
1552
+ state = nextState;
1553
+ host[CHILDREN_BINDING_CACHE] = nextState;
1554
+ registerRootCleanup(() => {
1555
+ state?.cleanup?.();
1556
+ if (state) {
1557
+ state.cleanup = void 0;
1558
+ }
1559
+ if (host[CHILDREN_BINDING_CACHE] === state) {
1560
+ delete host[CHILDREN_BINDING_CACHE];
1561
+ }
1562
+ });
1563
+ return;
1564
+ }
1565
+ state.value(value);
1566
+ }
1567
+ function updateAssignedRefBinding(node, value) {
1568
+ const host = node;
1569
+ const owner = getCurrentRoot();
1570
+ let state = host[REF_ASSIGN_CACHE];
1571
+ if (state && state.owner !== owner) {
1572
+ state.cleanup?.();
1573
+ state.cleanup = void 0;
1574
+ delete host[REF_ASSIGN_CACHE];
1575
+ state = void 0;
1576
+ }
1577
+ if (!state && value == null) {
1578
+ return;
1579
+ }
1580
+ if (!state) {
1581
+ state = createAssignedRefState(node, owner, value);
1582
+ host[REF_ASSIGN_CACHE] = state;
1583
+ }
1584
+ state.value?.(value);
1585
+ if (value == null) {
1586
+ if (!state.registeredCleanup) {
1587
+ state.cleanup?.();
1588
+ state.cleanup = void 0;
1589
+ delete host[REF_ASSIGN_CACHE];
1590
+ }
1591
+ return;
1592
+ }
1593
+ if (!state.registeredCleanup && getCurrentRoot()) {
1594
+ state.registeredCleanup = true;
1595
+ registerRootCleanup(() => {
1596
+ state.cleanup?.();
1597
+ state.cleanup = void 0;
1598
+ state.value = void 0;
1599
+ if (host[REF_ASSIGN_CACHE] === state) {
1600
+ delete host[REF_ASSIGN_CACHE];
1601
+ }
1602
+ });
1603
+ }
1294
1604
  }
1295
1605
  function spread(node, props = {}, isSVG = false, skipChildren = false, exclude = []) {
1296
1606
  const prevProps = {};
@@ -1300,23 +1610,12 @@ function spread(node, props = {}, isSVG = false, skipChildren = false, exclude =
1300
1610
  if (!next || typeof next !== "object") return {};
1301
1611
  return next;
1302
1612
  };
1303
- if (!skipChildren) {
1304
- createRenderEffect(() => {
1305
- const nextProps = resolveProps();
1306
- if ("children" in nextProps) {
1307
- prevProps.children = nextProps.children;
1308
- }
1309
- });
1310
- }
1311
- createRenderEffect(() => {
1312
- const nextProps = resolveProps();
1313
- if (typeof nextProps.ref === "function") {
1314
- ;
1315
- nextProps.ref(node);
1316
- }
1317
- });
1613
+ bindRef(
1614
+ node,
1615
+ (typeof props === "function" ? () => resolveProps().ref : resolveProps().ref) ?? null
1616
+ );
1318
1617
  createRenderEffect(() => {
1319
- assign(node, resolveProps(), isSVG, true, prevProps, true, excludedProps);
1618
+ assign(node, resolveProps(), isSVG, skipChildren, prevProps, true, excludedProps);
1320
1619
  });
1321
1620
  return prevProps;
1322
1621
  }
@@ -1325,19 +1624,26 @@ function assign(node, props, isSVG = false, skipChildren = false, prevProps = {}
1325
1624
  for (const prop2 in prevProps) {
1326
1625
  if (excludedProps?.has(prop2)) continue;
1327
1626
  if (!(prop2 in props)) {
1328
- if (prop2 === "children") continue;
1627
+ if (prop2 === "children") {
1628
+ if (!skipChildren) {
1629
+ updateChildrenBinding(node, void 0);
1630
+ prevProps.children = void 0;
1631
+ }
1632
+ continue;
1633
+ }
1329
1634
  prevProps[prop2] = assignProp(node, prop2, null, prevProps[prop2], isSVG, skipRef, props);
1330
1635
  }
1331
1636
  }
1332
1637
  for (const prop2 in props) {
1333
1638
  if (excludedProps?.has(prop2)) continue;
1639
+ const value = props[prop2];
1334
1640
  if (prop2 === "children") {
1335
1641
  if (!skipChildren) {
1642
+ updateChildrenBinding(node, value);
1336
1643
  prevProps.children = props.children;
1337
1644
  }
1338
1645
  continue;
1339
1646
  }
1340
- const value = props[prop2];
1341
1647
  prevProps[prop2] = assignProp(node, prop2, value, prevProps[prop2], isSVG, skipRef, props);
1342
1648
  }
1343
1649
  }
@@ -1351,9 +1657,8 @@ function assignProp(node, prop2, value, prev, isSVG, skipRef, props) {
1351
1657
  }
1352
1658
  if (value === prev) return prev;
1353
1659
  if (prop2 === "ref") {
1354
- if (!skipRef && typeof value === "function") {
1355
- ;
1356
- value(node);
1660
+ if (!skipRef) {
1661
+ updateAssignedRefBinding(node, value);
1357
1662
  }
1358
1663
  return value;
1359
1664
  }
@@ -1363,34 +1668,41 @@ function assignProp(node, prop2, value, prev, isSVG, skipRef, props) {
1363
1668
  node.setAttribute(prop2, value);
1364
1669
  return value;
1365
1670
  }
1366
- if (prev && typeof prev !== "string") node.removeEventListener(eventName, prev);
1367
- if (value) node.addEventListener(eventName, value);
1671
+ if (prev && typeof prev !== "string") removeStoredEventListener(node, eventName);
1672
+ addEventListener(
1673
+ node,
1674
+ eventName,
1675
+ value,
1676
+ false
1677
+ );
1368
1678
  return value;
1369
1679
  }
1370
1680
  if (prop2.slice(0, 10) === "oncapture:") {
1371
1681
  const eventName = prop2.slice(10);
1372
- if (prev) node.removeEventListener(eventName, prev, true);
1373
- if (value) node.addEventListener(eventName, value, true);
1682
+ if (prev) removeStoredEventListener(node, eventName, true);
1683
+ addEventListener(
1684
+ node,
1685
+ eventName,
1686
+ value,
1687
+ false,
1688
+ true
1689
+ );
1374
1690
  return value;
1375
1691
  }
1376
1692
  if (prop2.slice(0, 2) === "on") {
1377
1693
  const eventName = prop2.slice(2).toLowerCase();
1378
1694
  const shouldDelegate = DelegatedEvents.has(eventName);
1379
1695
  if (!shouldDelegate && prev) {
1380
- if (Array.isArray(prev)) {
1381
- removeStoredTupleEventListener(node, eventName);
1382
- } else {
1383
- node.removeEventListener(eventName, prev);
1384
- }
1696
+ removeStoredEventListener(node, eventName);
1385
1697
  }
1386
1698
  if (shouldDelegate || value) {
1387
1699
  addEventListener(
1388
1700
  node,
1389
1701
  eventName,
1390
1702
  value,
1391
- shouldDelegate
1703
+ shouldDelegate,
1704
+ false
1392
1705
  );
1393
- if (shouldDelegate) delegateEvents([eventName]);
1394
1706
  }
1395
1707
  return value;
1396
1708
  }
@@ -2147,6 +2459,7 @@ function hydrateComponent(view, container) {
2147
2459
  function createElement(node) {
2148
2460
  return createElementWithContext(node, null, resolveOwnerDocument());
2149
2461
  }
2462
+ registerCreateElement(createElement);
2150
2463
  function resolveNamespace(tagName, namespace) {
2151
2464
  if (tagName === "svg") return "svg";
2152
2465
  if (tagName === "math") return "mathml";
@@ -2158,22 +2471,28 @@ function resolveNamespace(tagName, namespace) {
2158
2471
  function resolveOwnerDocument(ownerDocument) {
2159
2472
  return ownerDocument ?? getCurrentRoot()?.ownerDocument ?? document;
2160
2473
  }
2474
+ function createTextNodeWithHydration(value, ownerDocument) {
2475
+ if (!isHydratingActive()) {
2476
+ return ownerDocument.createTextNode(value);
2477
+ }
2478
+ return claimText(value, () => ownerDocument.createTextNode(value));
2479
+ }
2161
2480
  function createElementWithContext(node, namespace, ownerDocument) {
2162
2481
  if (node instanceof Node) {
2163
2482
  return node;
2164
2483
  }
2165
2484
  if (node === null || node === void 0 || node === false) {
2166
- return ownerDocument.createTextNode("");
2485
+ return createTextNodeWithHydration("", ownerDocument);
2167
2486
  }
2168
2487
  if (isReactive(node)) {
2169
2488
  const resolved = node();
2170
2489
  if (resolved === node) {
2171
- return ownerDocument.createTextNode("");
2490
+ return createTextNodeWithHydration("", ownerDocument);
2172
2491
  }
2173
2492
  return createElementWithContext(resolved, namespace, ownerDocument);
2174
2493
  }
2175
2494
  if (typeof node === "function") {
2176
- return ownerDocument.createTextNode("");
2495
+ return createTextNodeWithHydration("", ownerDocument);
2177
2496
  }
2178
2497
  if (typeof node === "object" && node !== null && !(node instanceof Node)) {
2179
2498
  if ("marker" in node) {
@@ -2200,10 +2519,10 @@ function createElementWithContext(node, namespace, ownerDocument) {
2200
2519
  return frag;
2201
2520
  }
2202
2521
  if (typeof node === "string" || typeof node === "number") {
2203
- return ownerDocument.createTextNode(String(node));
2522
+ return createTextNodeWithHydration(String(node), ownerDocument);
2204
2523
  }
2205
2524
  if (typeof node === "boolean") {
2206
- return ownerDocument.createTextNode("");
2525
+ return createTextNodeWithHydration("", ownerDocument);
2207
2526
  }
2208
2527
  const vnode = node;
2209
2528
  if (typeof vnode.type === "function") {
@@ -2412,7 +2731,7 @@ function appendChildNode(parent, child, namespace, ownerDocument) {
2412
2731
  }
2413
2732
  let domNode;
2414
2733
  if (typeof child !== "object" || child === null) {
2415
- domNode = parentOwnerDocument.createTextNode(String(child ?? ""));
2734
+ domNode = createTextNodeWithHydration(String(child ?? ""), parentOwnerDocument);
2416
2735
  } else {
2417
2736
  domNode = createElementWithContext(child, namespace, parentOwnerDocument);
2418
2737
  }
@@ -2448,33 +2767,12 @@ function appendChildren(parent, children, namespace, ownerDocument) {
2448
2767
  appendChildNode(parent, children, namespace, ownerDocument);
2449
2768
  }
2450
2769
  function applyRef(el, value) {
2451
- if (typeof value === "function") {
2452
- const refFn = value;
2453
- refFn(el);
2454
- const root = getCurrentRoot();
2455
- if (root) {
2456
- registerRootCleanup(() => {
2457
- refFn(null);
2458
- });
2459
- } else if (isDev2) {
2460
- console.warn(
2461
- "[fict] Ref applied outside of a root context. The ref cleanup (setting to null) will not run automatically. Consider using createRoot() or ensure the element is created within a component."
2462
- );
2463
- }
2464
- } else if (value && typeof value === "object" && "current" in value) {
2465
- const refObj = value;
2466
- refObj.current = el;
2467
- const root = getCurrentRoot();
2468
- if (root) {
2469
- registerRootCleanup(() => {
2470
- refObj.current = null;
2471
- });
2472
- } else if (isDev2) {
2473
- console.warn(
2474
- "[fict] Ref applied outside of a root context. The ref cleanup (setting to null) will not run automatically. Consider using createRoot() or ensure the element is created within a component."
2475
- );
2476
- }
2770
+ if (!getCurrentRoot() && isDev2) {
2771
+ console.warn(
2772
+ "[fict] Ref applied outside of a root context. The ref cleanup (setting to null) will not run automatically. Consider using createRoot() or ensure the element is created within a component."
2773
+ );
2477
2774
  }
2775
+ bindRef(el, value);
2478
2776
  }
2479
2777
  function applyProps(el, props, isSVG = false) {
2480
2778
  props = unwrapProps(props);
@@ -2717,4 +3015,4 @@ export {
2717
3015
  createElement,
2718
3016
  template
2719
3017
  };
2720
- //# sourceMappingURL=chunk-ZJZ6LMDN.js.map
3018
+ //# sourceMappingURL=chunk-R2HYEOP7.js.map