@fictjs/runtime 0.9.0 → 0.10.0

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 (75) hide show
  1. package/dist/advanced.cjs +9 -9
  2. package/dist/advanced.d.cts +4 -4
  3. package/dist/advanced.d.ts +4 -4
  4. package/dist/advanced.js +4 -4
  5. package/dist/{binding-BWchH3Kp.d.ts → binding-DUEukRxl.d.cts} +4 -2
  6. package/dist/{binding-BWchH3Kp.d.cts → binding-DqxS9ZQf.d.ts} +4 -2
  7. package/dist/{chunk-JVYH76ZX.js → chunk-2JRPPCG7.js} +3 -3
  8. package/dist/{chunk-FVX77557.js → chunk-DKA2I6ET.js} +3 -3
  9. package/dist/{chunk-UBFDB6OL.cjs → chunk-EQ5E4WOV.cjs} +216 -50
  10. package/dist/chunk-EQ5E4WOV.cjs.map +1 -0
  11. package/dist/{chunk-DXG3TARY.js → chunk-F4RVNXOL.js} +196 -30
  12. package/dist/chunk-F4RVNXOL.js.map +1 -0
  13. package/dist/{chunk-OAM7HABA.cjs → chunk-I4GKKAAY.cjs} +226 -182
  14. package/dist/chunk-I4GKKAAY.cjs.map +1 -0
  15. package/dist/{chunk-PG4QX2I2.cjs → chunk-K3DH5SD5.cjs} +17 -17
  16. package/dist/{chunk-PG4QX2I2.cjs.map → chunk-K3DH5SD5.cjs.map} +1 -1
  17. package/dist/{chunk-N6ODUM2Y.js → chunk-P4TZLFV6.js} +3 -3
  18. package/dist/{chunk-T2LNV5Q5.js → chunk-R6FINS25.js} +50 -6
  19. package/dist/chunk-R6FINS25.js.map +1 -0
  20. package/dist/{chunk-LBE6DC3V.cjs → chunk-SZLJCQFZ.cjs} +40 -40
  21. package/dist/{chunk-LBE6DC3V.cjs.map → chunk-SZLJCQFZ.cjs.map} +1 -1
  22. package/dist/{chunk-PD6IQY2Y.cjs → chunk-V7BC64W2.cjs} +8 -8
  23. package/dist/{chunk-PD6IQY2Y.cjs.map → chunk-V7BC64W2.cjs.map} +1 -1
  24. package/dist/{devtools-5AipK9CX.d.cts → devtools-C4Hgfa-S.d.ts} +14 -2
  25. package/dist/{devtools-BDp76luf.d.ts → devtools-CMxlJUTx.d.cts} +14 -2
  26. package/dist/index.cjs +42 -42
  27. package/dist/index.d.cts +5 -5
  28. package/dist/index.d.ts +5 -5
  29. package/dist/index.dev.js +230 -25
  30. package/dist/index.dev.js.map +1 -1
  31. package/dist/index.js +3 -3
  32. package/dist/internal-list.cjs +4 -4
  33. package/dist/internal-list.d.cts +2 -2
  34. package/dist/internal-list.d.ts +2 -2
  35. package/dist/internal-list.js +3 -3
  36. package/dist/internal.cjs +5 -5
  37. package/dist/internal.d.cts +6 -6
  38. package/dist/internal.d.ts +6 -6
  39. package/dist/internal.js +4 -4
  40. package/dist/jsx-dev-runtime.d.cts +671 -0
  41. package/dist/jsx-dev-runtime.d.ts +671 -0
  42. package/dist/jsx-runtime.d.cts +671 -0
  43. package/dist/jsx-runtime.d.ts +671 -0
  44. package/dist/{list-DL5DOFcO.d.ts → list-BBzsJhrm.d.ts} +1 -1
  45. package/dist/{list-hP7hQ9Vk.d.cts → list-_NJCcjl1.d.cts} +1 -1
  46. package/dist/loader.cjs +24 -20
  47. package/dist/loader.cjs.map +1 -1
  48. package/dist/loader.d.cts +2 -2
  49. package/dist/loader.d.ts +2 -2
  50. package/dist/loader.js +7 -3
  51. package/dist/loader.js.map +1 -1
  52. package/dist/{props-BpZz0AOq.d.cts → props--zJ4ebbT.d.cts} +2 -2
  53. package/dist/{props-CjLH0JE-.d.ts → props-BAGR7j-j.d.ts} +2 -2
  54. package/dist/{resume-BJ4oHLi_.d.cts → resume-C5IKAIdh.d.ts} +2 -2
  55. package/dist/{resume-CuyJWXP_.d.ts → resume-DPZxmA95.d.cts} +2 -2
  56. package/dist/{scope-jPt5DHRT.d.ts → scope-CuImnvh1.d.ts} +1 -1
  57. package/dist/{scope-BJCtq8hJ.d.cts → scope-Dq5hOu7c.d.cts} +1 -1
  58. package/dist/{signal-C4ISF17w.d.cts → signal-Z4KkDk9h.d.cts} +12 -1
  59. package/dist/{signal-C4ISF17w.d.ts → signal-Z4KkDk9h.d.ts} +12 -1
  60. package/package.json +2 -2
  61. package/src/devtools.ts +19 -2
  62. package/src/dom.ts +58 -4
  63. package/src/effect.ts +5 -5
  64. package/src/hooks.ts +13 -5
  65. package/src/lifecycle.ts +41 -3
  66. package/src/loader.ts +10 -4
  67. package/src/signal.ts +191 -18
  68. package/src/transition.ts +9 -3
  69. package/dist/chunk-DXG3TARY.js.map +0 -1
  70. package/dist/chunk-OAM7HABA.cjs.map +0 -1
  71. package/dist/chunk-T2LNV5Q5.js.map +0 -1
  72. package/dist/chunk-UBFDB6OL.cjs.map +0 -1
  73. /package/dist/{chunk-JVYH76ZX.js.map → chunk-2JRPPCG7.js.map} +0 -0
  74. /package/dist/{chunk-FVX77557.js.map → chunk-DKA2I6ET.js.map} +0 -0
  75. /package/dist/{chunk-N6ODUM2Y.js.map → chunk-P4TZLFV6.js.map} +0 -0
package/dist/index.dev.js CHANGED
@@ -181,8 +181,35 @@ var currentRoot;
181
181
  var currentEffectCleanups;
182
182
  var globalErrorHandlers = /* @__PURE__ */ new WeakMap();
183
183
  var globalSuspenseHandlers = /* @__PURE__ */ new WeakMap();
184
+ var rootDevtoolsIds = /* @__PURE__ */ new WeakMap();
185
+ var nextRootDevtoolsId = 0;
186
+ function registerRootDevtools(root) {
187
+ if (!isDev2) return;
188
+ const hook = getDevtoolsHook();
189
+ if (!hook?.registerRoot) return;
190
+ const id = ++nextRootDevtoolsId;
191
+ rootDevtoolsIds.set(root, id);
192
+ hook.registerRoot(id);
193
+ }
194
+ function disposeRootDevtools(root) {
195
+ if (!isDev2) return;
196
+ const id = rootDevtoolsIds.get(root);
197
+ if (id === void 0) return;
198
+ const hook = getDevtoolsHook();
199
+ hook?.disposeRoot?.(id);
200
+ rootDevtoolsIds.delete(root);
201
+ }
202
+ function setRootSuspendDevtools(root, suspended) {
203
+ if (!isDev2) return;
204
+ const id = rootDevtoolsIds.get(root);
205
+ if (id === void 0) return;
206
+ const hook = getDevtoolsHook();
207
+ hook?.rootSuspend?.(id, suspended);
208
+ }
184
209
  function createRootContext(parent) {
185
- return { parent, cleanups: [], destroyCallbacks: [], suspended: false };
210
+ const root = { parent, cleanups: [], destroyCallbacks: [], suspended: false };
211
+ registerRootDevtools(root);
212
+ return root;
186
213
  }
187
214
  function pushRoot(root) {
188
215
  if (!enterRootGuard(root)) {
@@ -262,6 +289,7 @@ function destroyRoot(root) {
262
289
  if (globalSuspenseHandlers.has(root)) {
263
290
  globalSuspenseHandlers.delete(root);
264
291
  }
292
+ disposeRootDevtools(root);
265
293
  }
266
294
  function createRoot(fn, options2) {
267
295
  const parent = options2?.inherit ? currentRoot : void 0;
@@ -398,7 +426,10 @@ function handleSuspend(token, startRoot) {
398
426
  const handler = handlers[i];
399
427
  const handled = handler(token);
400
428
  if (handled !== false) {
401
- if (originRoot) originRoot.suspended = true;
429
+ if (originRoot) {
430
+ originRoot.suspended = true;
431
+ setRootSuspendDevtools(originRoot, true);
432
+ }
402
433
  return true;
403
434
  }
404
435
  }
@@ -411,7 +442,10 @@ function handleSuspend(token, startRoot) {
411
442
  const handler = globalForRoot[i];
412
443
  const handled = handler(token);
413
444
  if (handled !== false) {
414
- if (originRoot) originRoot.suspended = true;
445
+ if (originRoot) {
446
+ originRoot.suspended = true;
447
+ setRootSuspendDevtools(originRoot, true);
448
+ }
415
449
  return true;
416
450
  }
417
451
  }
@@ -420,7 +454,7 @@ function handleSuspend(token, startRoot) {
420
454
  }
421
455
 
422
456
  // src/effect.ts
423
- function createEffect(fn) {
457
+ function createEffect(fn, options2) {
424
458
  let cleanups = [];
425
459
  const rootForError = getCurrentRoot();
426
460
  const doCleanup = () => {
@@ -447,7 +481,7 @@ function createEffect(fn) {
447
481
  });
448
482
  cleanups = bucket;
449
483
  };
450
- const disposeEffect = effectWithCleanup(run, doCleanup, rootForError);
484
+ const disposeEffect = effectWithCleanup(run, doCleanup, rootForError, options2);
451
485
  const teardown = () => {
452
486
  runCleanupList(cleanups);
453
487
  disposeEffect();
@@ -455,7 +489,7 @@ function createEffect(fn) {
455
489
  registerRootCleanup(teardown);
456
490
  return teardown;
457
491
  }
458
- function createRenderEffect(fn) {
492
+ function createRenderEffect(fn, options2) {
459
493
  let cleanup;
460
494
  const rootForError = getCurrentRoot();
461
495
  const doCleanup = () => {
@@ -481,7 +515,7 @@ function createRenderEffect(fn) {
481
515
  throw err;
482
516
  }
483
517
  };
484
- const disposeEffect = effectWithCleanup(run, doCleanup, rootForError);
518
+ const disposeEffect = effectWithCleanup(run, doCleanup, rootForError, options2);
485
519
  const teardown = () => {
486
520
  if (cleanup) {
487
521
  cleanup();
@@ -759,6 +793,15 @@ function purgeDeps(sub) {
759
793
  while (dep !== void 0) dep = unlink(dep, sub);
760
794
  }
761
795
  function disposeNode(node) {
796
+ if (isDev4) {
797
+ if ("fn" in node && typeof node.fn === "function") {
798
+ disposeEffectDevtools(node);
799
+ } else if ("getter" in node && typeof node.getter === "function") {
800
+ disposeComputedDevtools(node);
801
+ } else if ("currentValue" in node) {
802
+ disposeSignalDevtools(node);
803
+ }
804
+ }
762
805
  node.depsTail = void 0;
763
806
  node.flags = 0;
764
807
  purgeDeps(node);
@@ -812,6 +855,7 @@ function runEffect(e) {
812
855
  const flags = e.flags;
813
856
  const runCleanup = () => {
814
857
  if (!e.runCleanup) return;
858
+ if (isDev4) effectCleanupDevtools(e);
815
859
  inCleanup = true;
816
860
  activeCleanupFlushId = currentFlushId;
817
861
  try {
@@ -824,7 +868,6 @@ function runEffect(e) {
824
868
  if (flags & Dirty) {
825
869
  runCleanup();
826
870
  ++cycle;
827
- if (isDev4) effectRunDevtools(e);
828
871
  e.depsTail = void 0;
829
872
  e.flags = WatchingRunning;
830
873
  const prevSub = activeSub;
@@ -862,7 +905,6 @@ function runEffect(e) {
862
905
  if (isDirty) {
863
906
  runCleanup();
864
907
  ++cycle;
865
- if (isDev4) effectRunDevtools(e);
866
908
  e.depsTail = void 0;
867
909
  e.flags = WatchingRunning;
868
910
  const prevSub = activeSub;
@@ -896,19 +938,30 @@ function scheduleFlush() {
896
938
  }
897
939
  function flush() {
898
940
  beginFlushGuard();
941
+ let flushReported = false;
942
+ const finishFlush = () => {
943
+ if (flushReported && isDev4) {
944
+ flushEndDevtools();
945
+ }
946
+ endFlushGuard();
947
+ };
899
948
  if (batchDepth > 0) {
900
949
  scheduleFlush();
901
- endFlushGuard();
950
+ finishFlush();
902
951
  return;
903
952
  }
904
953
  const hasWork = highPriorityQueue.length > 0 || lowPriorityQueue.length > 0;
905
954
  if (!hasWork) {
906
955
  flushScheduled = false;
907
- endFlushGuard();
956
+ finishFlush();
908
957
  return;
909
958
  }
910
959
  currentFlushId++;
911
960
  flushScheduled = false;
961
+ if (isDev4) {
962
+ flushStartDevtools();
963
+ flushReported = true;
964
+ }
912
965
  let highIndex = 0;
913
966
  while (highIndex < highPriorityQueue.length) {
914
967
  const e = highPriorityQueue[highIndex];
@@ -928,7 +981,7 @@ function flush() {
928
981
  highPriorityQueue.length = 0;
929
982
  lowPriorityQueue.length = 0;
930
983
  flushScheduled = false;
931
- endFlushGuard();
984
+ finishFlush();
932
985
  return;
933
986
  }
934
987
  highIndex++;
@@ -943,7 +996,7 @@ function flush() {
943
996
  lowPriorityQueue.length -= lowIndex;
944
997
  }
945
998
  scheduleFlush();
946
- endFlushGuard();
999
+ finishFlush();
947
1000
  return;
948
1001
  }
949
1002
  const e = lowPriorityQueue[lowIndex];
@@ -963,14 +1016,14 @@ function flush() {
963
1016
  highPriorityQueue.length = 0;
964
1017
  lowPriorityQueue.length = 0;
965
1018
  flushScheduled = false;
966
- endFlushGuard();
1019
+ finishFlush();
967
1020
  return;
968
1021
  }
969
1022
  lowIndex++;
970
1023
  runEffect(e);
971
1024
  }
972
1025
  lowPriorityQueue.length = 0;
973
- endFlushGuard();
1026
+ finishFlush();
974
1027
  }
975
1028
  function signal(initialValue, options2) {
976
1029
  const s = {
@@ -1043,6 +1096,7 @@ function computed(getter, options2) {
1043
1096
  if (options2?.equals !== void 0) c.equals = options2.equals;
1044
1097
  if (options2?.name !== void 0) c.name = options2.name;
1045
1098
  if (options2?.devToolsSource !== void 0) c.devToolsSource = options2.devToolsSource;
1099
+ if (options2?.internal === true) c.devToolsInternal = true;
1046
1100
  if (isDev4) registerComputedDevtools(c);
1047
1101
  const bound = computedOper.bind(
1048
1102
  c
@@ -1093,7 +1147,7 @@ function computedOper() {
1093
1147
  if (activeSub !== void 0) link(this, activeSub, cycle);
1094
1148
  return this.value;
1095
1149
  }
1096
- function effectWithCleanup(fn, cleanupRunner, root) {
1150
+ function effectWithCleanup(fn, cleanupRunner, root, options2) {
1097
1151
  const e = {
1098
1152
  fn,
1099
1153
  subs: void 0,
@@ -1102,6 +1156,8 @@ function effectWithCleanup(fn, cleanupRunner, root) {
1102
1156
  depsTail: void 0,
1103
1157
  flags: WatchingRunning,
1104
1158
  runCleanup: cleanupRunner,
1159
+ ...options2?.name !== void 0 ? { name: options2.name } : {},
1160
+ ...options2?.devToolsSource !== void 0 ? { devToolsSource: options2.devToolsSource } : {},
1105
1161
  __id: void 0
1106
1162
  };
1107
1163
  const resolvedRoot = root ?? getCurrentRoot();
@@ -1109,14 +1165,14 @@ function effectWithCleanup(fn, cleanupRunner, root) {
1109
1165
  e.root = resolvedRoot;
1110
1166
  }
1111
1167
  if (isDev4) registerEffectDevtools(e);
1168
+ e.fn = wrapEffectFnWithDevtoolsTiming(e, fn);
1112
1169
  const prevSub = activeSub;
1113
1170
  if (prevSub !== void 0) link(e, prevSub, 0);
1114
1171
  activeSub = e;
1115
1172
  let didThrow = false;
1116
1173
  let thrown;
1117
1174
  try {
1118
- if (isDev4) effectRunDevtools(e);
1119
- fn();
1175
+ e.fn();
1120
1176
  } catch (err) {
1121
1177
  didThrow = true;
1122
1178
  thrown = err;
@@ -1137,7 +1193,11 @@ function effectOper() {
1137
1193
  disposeNode(this);
1138
1194
  }
1139
1195
  function batch(fn) {
1196
+ const enteringOuterBatch = batchDepth === 0;
1140
1197
  ++batchDepth;
1198
+ if (enteringOuterBatch && isDev4) {
1199
+ batchStartDevtools();
1200
+ }
1141
1201
  let result;
1142
1202
  let error;
1143
1203
  try {
@@ -1147,6 +1207,9 @@ function batch(fn) {
1147
1207
  } finally {
1148
1208
  --batchDepth;
1149
1209
  if (batchDepth === 0) {
1210
+ if (isDev4) {
1211
+ batchEndDevtools();
1212
+ }
1150
1213
  try {
1151
1214
  flush();
1152
1215
  } catch (flushErr) {
@@ -1195,18 +1258,49 @@ function setTransitionContext(value) {
1195
1258
  var registerSignalDevtools = () => void 0;
1196
1259
  var updateSignalDevtools = () => {
1197
1260
  };
1261
+ var disposeSignalDevtools = () => {
1262
+ };
1198
1263
  var registerComputedDevtools = () => void 0;
1199
1264
  var updateComputedDevtools = () => {
1200
1265
  };
1266
+ var disposeComputedDevtools = () => {
1267
+ };
1201
1268
  var registerEffectDevtools = () => void 0;
1202
1269
  var effectRunDevtools = () => {
1203
1270
  };
1271
+ var wrapEffectFnWithDevtoolsTiming = (_node, fn) => fn;
1272
+ var effectCleanupDevtools = () => {
1273
+ };
1274
+ var disposeEffectDevtools = () => {
1275
+ };
1204
1276
  var trackDependencyDevtools = () => {
1205
1277
  };
1206
1278
  var untrackDependencyDevtools = () => {
1207
1279
  };
1280
+ var batchStartDevtools = () => {
1281
+ };
1282
+ var batchEndDevtools = () => {
1283
+ };
1284
+ var flushStartDevtools = () => {
1285
+ };
1286
+ var flushEndDevtools = () => {
1287
+ };
1288
+ var clearDevtoolsSignalSetters = () => {
1289
+ };
1208
1290
  if (true ? true : typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
1209
1291
  let nextDevtoolsId = 0;
1292
+ const getSignalSetterMap = () => {
1293
+ if (typeof globalThis === "undefined") return void 0;
1294
+ const global = globalThis;
1295
+ if (!global.__FICT_DEVTOOLS_SIGNALS__) {
1296
+ global.__FICT_DEVTOOLS_SIGNALS__ = /* @__PURE__ */ new Map();
1297
+ }
1298
+ return global.__FICT_DEVTOOLS_SIGNALS__;
1299
+ };
1300
+ const getExistingSignalSetterMap = () => {
1301
+ if (typeof globalThis === "undefined") return void 0;
1302
+ return globalThis.__FICT_DEVTOOLS_SIGNALS__;
1303
+ };
1210
1304
  registerSignalDevtools = (node) => {
1211
1305
  const hook = getDevtoolsHook();
1212
1306
  if (!hook) return void 0;
@@ -1218,6 +1312,9 @@ if (true ? true : typeof process !== "undefined" && process.env?.NODE_ENV !== "p
1218
1312
  if (ownerId !== void 0) options2.ownerId = ownerId;
1219
1313
  hook.registerSignal(id, node.currentValue, options2);
1220
1314
  node.__id = id;
1315
+ getSignalSetterMap()?.set(id, (value) => {
1316
+ signalOper.call(node, value);
1317
+ });
1221
1318
  return id;
1222
1319
  };
1223
1320
  updateSignalDevtools = (node, value) => {
@@ -1226,9 +1323,19 @@ if (true ? true : typeof process !== "undefined" && process.env?.NODE_ENV !== "p
1226
1323
  const id = node.__id;
1227
1324
  if (id) hook.updateSignal(id, value);
1228
1325
  };
1326
+ disposeSignalDevtools = (node) => {
1327
+ const identifiable = node;
1328
+ const id = identifiable.__id;
1329
+ if (!id) return;
1330
+ const hook = getDevtoolsHook();
1331
+ hook?.disposeSignal?.(id);
1332
+ getExistingSignalSetterMap()?.delete(id);
1333
+ delete identifiable.__id;
1334
+ };
1229
1335
  registerComputedDevtools = (node) => {
1230
1336
  const hook = getDevtoolsHook();
1231
1337
  if (!hook) return void 0;
1338
+ if (node.devToolsInternal) return void 0;
1232
1339
  const id = ++nextDevtoolsId;
1233
1340
  const options2 = {};
1234
1341
  if (node.name !== void 0) options2.name = node.name;
@@ -1246,20 +1353,55 @@ if (true ? true : typeof process !== "undefined" && process.env?.NODE_ENV !== "p
1246
1353
  const id = node.__id;
1247
1354
  if (id) hook.updateComputed(id, value);
1248
1355
  };
1356
+ disposeComputedDevtools = (node) => {
1357
+ const identifiable = node;
1358
+ const id = identifiable.__id;
1359
+ if (!id) return;
1360
+ const hook = getDevtoolsHook();
1361
+ hook?.disposeComputed?.(id);
1362
+ delete identifiable.__id;
1363
+ };
1249
1364
  registerEffectDevtools = (node) => {
1250
1365
  const hook = getDevtoolsHook();
1251
1366
  if (!hook) return void 0;
1252
1367
  const id = ++nextDevtoolsId;
1368
+ const options2 = {};
1253
1369
  const ownerId = __fictGetCurrentComponentId();
1254
- hook.registerEffect(id, ownerId !== void 0 ? { ownerId } : void 0);
1370
+ if (ownerId !== void 0) options2.ownerId = ownerId;
1371
+ if (node.devToolsSource !== void 0) options2.source = node.devToolsSource;
1372
+ hook.registerEffect(id, Object.keys(options2).length > 0 ? options2 : void 0);
1255
1373
  node.__id = id;
1256
1374
  return id;
1257
1375
  };
1258
- effectRunDevtools = (node) => {
1376
+ effectRunDevtools = (node, duration) => {
1259
1377
  const hook = getDevtoolsHook();
1260
1378
  if (!hook) return;
1261
1379
  const id = node.__id;
1262
- if (id) hook.effectRun(id);
1380
+ if (id) hook.effectRun(id, duration);
1381
+ };
1382
+ wrapEffectFnWithDevtoolsTiming = (node, fn) => {
1383
+ return () => {
1384
+ const startedAt = performance.now();
1385
+ try {
1386
+ fn();
1387
+ } finally {
1388
+ effectRunDevtools(node, performance.now() - startedAt);
1389
+ }
1390
+ };
1391
+ };
1392
+ effectCleanupDevtools = (node) => {
1393
+ const hook = getDevtoolsHook();
1394
+ if (!hook) return;
1395
+ const id = node.__id;
1396
+ if (id) hook.effectCleanup?.(id);
1397
+ };
1398
+ disposeEffectDevtools = (node) => {
1399
+ const identifiable = node;
1400
+ const id = identifiable.__id;
1401
+ if (!id) return;
1402
+ const hook = getDevtoolsHook();
1403
+ hook?.disposeEffect?.(id);
1404
+ delete identifiable.__id;
1263
1405
  };
1264
1406
  trackDependencyDevtools = (dep, sub) => {
1265
1407
  const hook = getDevtoolsHook();
@@ -1275,6 +1417,25 @@ if (true ? true : typeof process !== "undefined" && process.env?.NODE_ENV !== "p
1275
1417
  const subId = sub.__id;
1276
1418
  if (depId && subId) hook.untrackDependency(subId, depId);
1277
1419
  };
1420
+ batchStartDevtools = () => {
1421
+ const hook = getDevtoolsHook();
1422
+ hook?.batchStart?.();
1423
+ };
1424
+ batchEndDevtools = () => {
1425
+ const hook = getDevtoolsHook();
1426
+ hook?.batchEnd?.();
1427
+ };
1428
+ flushStartDevtools = () => {
1429
+ const hook = getDevtoolsHook();
1430
+ hook?.flushStart?.();
1431
+ };
1432
+ flushEndDevtools = () => {
1433
+ const hook = getDevtoolsHook();
1434
+ hook?.flushEnd?.();
1435
+ };
1436
+ clearDevtoolsSignalSetters = () => {
1437
+ getExistingSignalSetterMap()?.clear();
1438
+ };
1278
1439
  }
1279
1440
 
1280
1441
  // src/memo.ts
@@ -1331,7 +1492,11 @@ function useTransition() {
1331
1492
  throw thrown;
1332
1493
  }
1333
1494
  if (result && typeof result.then === "function") {
1334
- Promise.resolve(result).finally(() => {
1495
+ void Promise.resolve(result).catch((error) => {
1496
+ if (typeof console !== "undefined" && typeof console.error === "function") {
1497
+ console.error("[fict/transition] Async transition failed.", error);
1498
+ }
1499
+ }).finally(() => {
1335
1500
  endPending();
1336
1501
  });
1337
1502
  return;
@@ -2651,6 +2816,32 @@ var SVG_NS = "http://www.w3.org/2000/svg";
2651
2816
  var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
2652
2817
  var isDev7 = true ? true : typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
2653
2818
  var nextComponentId = 1;
2819
+ function collectComponentMountElements(node) {
2820
+ if (node instanceof DocumentFragment) {
2821
+ return Array.from(node.childNodes).filter(
2822
+ (child) => child instanceof HTMLElement
2823
+ );
2824
+ }
2825
+ if (node instanceof HTMLElement) {
2826
+ if (node.hasAttribute("data-fict-host")) {
2827
+ const children = Array.from(node.children).filter(
2828
+ (child) => child instanceof HTMLElement
2829
+ );
2830
+ if (children.length > 0) return children;
2831
+ }
2832
+ return [node];
2833
+ }
2834
+ return [];
2835
+ }
2836
+ function annotateComponentElements(elements, componentId, componentName) {
2837
+ for (const element of elements) {
2838
+ element.setAttribute("data-fict-component", componentName);
2839
+ element.setAttribute("data-fict-component-id", String(componentId));
2840
+ const annotated = element;
2841
+ annotated.__fict_component_id__ = componentId;
2842
+ annotated.__fict_component_name__ = componentName;
2843
+ }
2844
+ }
2654
2845
  function render(view, container) {
2655
2846
  const root = createRootContext();
2656
2847
  const prev = pushRoot(root);
@@ -2762,10 +2953,11 @@ function createElementWithContext(node, namespace) {
2762
2953
  });
2763
2954
  const props = createPropsProxy(baseProps);
2764
2955
  const hook = isDev7 ? getDevtoolsHook() : void 0;
2956
+ const componentName = vnode.type.name || "Anonymous";
2765
2957
  const parentId = hook ? __fictGetCurrentComponentId() : void 0;
2766
2958
  const componentId = hook ? nextComponentId++ : void 0;
2767
2959
  if (hook?.registerComponent && componentId !== void 0) {
2768
- hook.registerComponent(componentId, vnode.type.name || "Anonymous", parentId);
2960
+ hook.registerComponent(componentId, componentName, parentId);
2769
2961
  }
2770
2962
  const ctx = __fictPushContext();
2771
2963
  if (componentId !== void 0) {
@@ -2776,9 +2968,13 @@ function createElementWithContext(node, namespace) {
2776
2968
  }
2777
2969
  try {
2778
2970
  const rendered = vnode.type(props);
2971
+ let mountElements;
2972
+ if (hook && componentId !== void 0) {
2973
+ hook.componentRender?.(componentId);
2974
+ }
2779
2975
  if (hook && componentId !== void 0) {
2780
2976
  onMount(() => {
2781
- hook.componentMount?.(componentId);
2977
+ hook.componentMount?.(componentId, mountElements);
2782
2978
  });
2783
2979
  onCleanup(() => hook.componentUnmount?.(componentId));
2784
2980
  }
@@ -2801,9 +2997,18 @@ function createElementWithContext(node, namespace) {
2801
2997
  } else {
2802
2998
  host.appendChild(content);
2803
2999
  }
3000
+ if (hook && componentId !== void 0) {
3001
+ mountElements = collectComponentMountElements(host);
3002
+ annotateComponentElements(mountElements, componentId, componentName);
3003
+ }
2804
3004
  return host;
2805
3005
  }
2806
- return createElementWithContext(rendered, namespace);
3006
+ const componentRoot = createElementWithContext(rendered, namespace);
3007
+ if (hook && componentId !== void 0) {
3008
+ mountElements = collectComponentMountElements(componentRoot);
3009
+ annotateComponentElements(mountElements, componentId, componentName);
3010
+ }
3011
+ return componentRoot;
2807
3012
  } catch (err) {
2808
3013
  if (handleSuspend(err)) {
2809
3014
  return document.createComment("fict:suspend");