sibujs 3.3.0 → 3.3.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 (54) hide show
  1. package/dist/browser.cjs +210 -26
  2. package/dist/browser.js +4 -4
  3. package/dist/build.cjs +193 -89
  4. package/dist/build.js +10 -10
  5. package/dist/cdn.global.js +7 -7
  6. package/dist/{chunk-24DBWDTK.js → chunk-37BUKSLH.js} +1 -1
  7. package/dist/{chunk-IHBVTURX.js → chunk-4UUMSLSL.js} +4 -4
  8. package/dist/{chunk-USDR2GFV.js → chunk-6LTFHJQG.js} +3 -3
  9. package/dist/{chunk-MWZFOIBG.js → chunk-AMIKDMLP.js} +4 -4
  10. package/dist/{chunk-JBXNCZSC.js → chunk-F7FXQ3QS.js} +1 -1
  11. package/dist/{chunk-BEIKESVL.js → chunk-IKLYI3RF.js} +9 -9
  12. package/dist/{chunk-NUWKIEHE.js → chunk-LU2MQXQQ.js} +2 -2
  13. package/dist/{chunk-WVJJUFPC.js → chunk-M5KBNOSJ.js} +2 -2
  14. package/dist/{chunk-7JHWAGRQ.js → chunk-MHBCEJQO.js} +1 -1
  15. package/dist/{chunk-Q2ERM6NT.js → chunk-NHKQKKZU.js} +1 -1
  16. package/dist/{chunk-6G6UNHZI.js → chunk-RYMOSG5B.js} +5 -5
  17. package/dist/{chunk-F4UM7QBJ.js → chunk-SLMFA3ZZ.js} +1 -1
  18. package/dist/{chunk-X3NHE2DK.js → chunk-TEFZT5PJ.js} +83 -17
  19. package/dist/{chunk-SLCUP2EK.js → chunk-ULLTNDRA.js} +3 -3
  20. package/dist/{chunk-M6WSIGYW.js → chunk-VOVVTOEA.js} +2 -2
  21. package/dist/{chunk-XQ7XSGYP.js → chunk-WL7BIR6O.js} +1 -1
  22. package/dist/{chunk-CVMMULHO.js → chunk-WW6DAGGR.js} +4 -4
  23. package/dist/{chunk-5K72I3UQ.js → chunk-WZG2SZOT.js} +21 -4
  24. package/dist/{chunk-S4FHR5ZZ.js → chunk-XH2RTYEQ.js} +3 -3
  25. package/dist/{chunk-4WXWJ4SW.js → chunk-Z37APKBV.js} +4 -4
  26. package/dist/data.cjs +161 -23
  27. package/dist/data.js +6 -6
  28. package/dist/devtools.cjs +245 -31
  29. package/dist/devtools.js +4 -4
  30. package/dist/ecosystem.cjs +183 -45
  31. package/dist/ecosystem.js +7 -7
  32. package/dist/extras.cjs +185 -86
  33. package/dist/extras.js +19 -19
  34. package/dist/index.cjs +193 -89
  35. package/dist/index.d.cts +59 -8
  36. package/dist/index.d.ts +59 -8
  37. package/dist/index.js +10 -10
  38. package/dist/motion.cjs +329 -13
  39. package/dist/motion.js +3 -3
  40. package/dist/patterns.cjs +161 -23
  41. package/dist/patterns.js +5 -5
  42. package/dist/performance.cjs +258 -23
  43. package/dist/performance.js +4 -4
  44. package/dist/plugins.cjs +244 -51
  45. package/dist/plugins.js +6 -6
  46. package/dist/ssr.cjs +183 -44
  47. package/dist/ssr.js +7 -7
  48. package/dist/testing.cjs +396 -5
  49. package/dist/testing.js +2 -2
  50. package/dist/ui.cjs +221 -32
  51. package/dist/ui.js +6 -6
  52. package/dist/widgets.cjs +146 -26
  53. package/dist/widgets.js +6 -6
  54. package/package.json +1 -1
package/dist/plugins.cjs CHANGED
@@ -203,7 +203,7 @@ function isSafeAttrName(name) {
203
203
  return SAFE_ATTR_NAME.test(name);
204
204
  }
205
205
  function ssrErrorComment(err) {
206
- if (_isDev8) {
206
+ if (_isDev9) {
207
207
  const msg = escapeHtml(err instanceof Error ? err.message : String(err));
208
208
  return `<!--SSR error: ${safeCommentText(msg)}-->`;
209
209
  }
@@ -233,10 +233,10 @@ function renderToString(element) {
233
233
  }
234
234
  const tag = element.tagName.toLowerCase();
235
235
  if (tag === "script" || tag === "style") {
236
- return _isDev8 ? `<!--ssr:${tag}-stripped-->` : "";
236
+ return _isDev9 ? `<!--ssr:${tag}-stripped-->` : "";
237
237
  }
238
238
  if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
239
- return _isDev8 ? "<!--ssr:invalid-tag-->" : "";
239
+ return _isDev9 ? "<!--ssr:invalid-tag-->" : "";
240
240
  }
241
241
  let html2 = `<${tag}`;
242
242
  for (const attr of Array.from(element.attributes)) {
@@ -277,7 +277,7 @@ function hydrate(component, container, options = {}) {
277
277
  const first = mismatches[0];
278
278
  if (options.onMismatch) {
279
279
  options.onMismatch(first);
280
- } else if (_isDev8) {
280
+ } else if (_isDev9) {
281
281
  console.warn(
282
282
  `[SibuJS hydration] ${first.message}
283
283
  at ${first.path}
@@ -472,11 +472,11 @@ async function* renderToStream(element) {
472
472
  }
473
473
  const tag = element.tagName.toLowerCase();
474
474
  if (tag === "script" || tag === "style") {
475
- if (_isDev8) yield `<!--ssr:${tag}-stripped-->`;
475
+ if (_isDev9) yield `<!--ssr:${tag}-stripped-->`;
476
476
  return;
477
477
  }
478
478
  if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
479
- if (_isDev8) yield "<!--ssr:invalid-tag-->";
479
+ if (_isDev9) yield "<!--ssr:invalid-tag-->";
480
480
  return;
481
481
  }
482
482
  let openTag = `<${tag}`;
@@ -579,7 +579,7 @@ function hydrateProgressively(container, islands, options) {
579
579
  }
580
580
  container.setAttribute("data-sibu-hydrated", "progressive");
581
581
  return () => {
582
- for (const cleanup2 of cleanups) cleanup2();
582
+ for (const cleanup3 of cleanups) cleanup3();
583
583
  };
584
584
  }
585
585
  function resetSSRState() {
@@ -608,7 +608,7 @@ function ssrSuspense(props) {
608
608
  },
609
609
  (err) => {
610
610
  if (timer) clearTimeout(timer);
611
- if (_isDev8) console.warn("[SibuJS SSR] ssrSuspense rejected:", err);
611
+ if (_isDev9) console.warn("[SibuJS SSR] ssrSuspense rejected:", err);
612
612
  return { id, html: fallbackHtml };
613
613
  }
614
614
  );
@@ -651,7 +651,7 @@ function serializeState(state, nonce, options) {
651
651
  }
652
652
  function deserializeState(validate) {
653
653
  if (typeof window === "undefined") return void 0;
654
- if (_isDev8 && !validate) {
654
+ if (_isDev9 && !validate) {
655
655
  console.warn(
656
656
  "[SibuJS SSR] deserializeState() called without a validate guard \u2014 tampered SSR payloads will not be detected."
657
657
  );
@@ -668,14 +668,14 @@ function escapeHtml(str) {
668
668
  function escapeAttr(str) {
669
669
  return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
670
670
  }
671
- var _isDev8, SAFE_ATTR_NAME, URL_ATTRS, VOID_ELEMENTS, SAFE_ID, SAFE_SUSPENSE_ID, SSR_DATA_ATTR, DEFAULT_MAX_SSR_BYTES;
671
+ var _isDev9, SAFE_ATTR_NAME, URL_ATTRS, VOID_ELEMENTS, SAFE_ID, SAFE_SUSPENSE_ID, SSR_DATA_ATTR, DEFAULT_MAX_SSR_BYTES;
672
672
  var init_ssr = __esm({
673
673
  "src/platform/ssr.ts"() {
674
674
  "use strict";
675
675
  init_dev();
676
676
  init_ssr_context();
677
677
  init_sanitize();
678
- _isDev8 = isDev();
678
+ _isDev9 = isDev();
679
679
  SAFE_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
680
680
  URL_ATTRS = /* @__PURE__ */ new Set([
681
681
  "href",
@@ -804,6 +804,9 @@ init_sanitize();
804
804
 
805
805
  // src/reactivity/track.ts
806
806
  init_dev();
807
+
808
+ // src/reactivity/track-core.ts
809
+ init_dev();
807
810
  var _isDev2 = isDev();
808
811
  var POOL_MAX = 4096;
809
812
  var nodePool = [];
@@ -887,6 +890,7 @@ function unlinkSub(node) {
887
890
  else sub2.depsTail = prev;
888
891
  }
889
892
  var currentSubscriber = null;
893
+ var suspendSavedSub = null;
890
894
  var notifyDepth = 0;
891
895
  var pendingQueue = [];
892
896
  var pendingSet = /* @__PURE__ */ new Set();
@@ -898,6 +902,35 @@ function safeInvoke(sub2) {
898
902
  if (_isDev2) devWarn(`Subscriber threw during notification: ${err instanceof Error ? err.message : String(err)}`);
899
903
  }
900
904
  }
905
+ var suspendDepth = 0;
906
+ var trackingSuspended = false;
907
+ function suspendTracking() {
908
+ if (suspendDepth === 0) {
909
+ suspendSavedSub = currentSubscriber;
910
+ currentSubscriber = null;
911
+ trackingSuspended = true;
912
+ }
913
+ suspendDepth++;
914
+ }
915
+ function resumeTracking() {
916
+ suspendDepth--;
917
+ if (suspendDepth === 0) {
918
+ currentSubscriber = suspendSavedSub;
919
+ suspendSavedSub = null;
920
+ trackingSuspended = false;
921
+ }
922
+ }
923
+ function isTrackingSuspended() {
924
+ return trackingSuspended;
925
+ }
926
+ function untracked(fn) {
927
+ suspendTracking();
928
+ try {
929
+ return fn();
930
+ } finally {
931
+ resumeTracking();
932
+ }
933
+ }
901
934
  var subscriberEpochCounter = 0;
902
935
  function retrack(effectFn, subscriber) {
903
936
  const prev = currentSubscriber;
@@ -1007,6 +1040,16 @@ function cleanup(subscriber) {
1007
1040
  var maxSubscriberRepeats = 50;
1008
1041
  var maxDrainIterations = 1e6;
1009
1042
  var drainEpoch = 0;
1043
+ function setMaxSubscriberRepeats(n) {
1044
+ const prev = maxSubscriberRepeats;
1045
+ if (Number.isFinite(n) && n > 0) maxSubscriberRepeats = Math.floor(n);
1046
+ return prev;
1047
+ }
1048
+ function setMaxDrainIterations(n) {
1049
+ const prev = maxDrainIterations;
1050
+ if (Number.isFinite(n) && n > 0) maxDrainIterations = Math.floor(n);
1051
+ return prev;
1052
+ }
1010
1053
  function tickRepeat(sub2) {
1011
1054
  const s2 = sub2;
1012
1055
  if (s2._runEpoch !== drainEpoch) {
@@ -1048,6 +1091,20 @@ function drainQueue() {
1048
1091
  safeInvoke(sub2);
1049
1092
  }
1050
1093
  }
1094
+ function drainNotificationQueue() {
1095
+ if (notifyDepth > 0) return;
1096
+ notifyDepth++;
1097
+ drainEpoch++;
1098
+ try {
1099
+ drainQueue();
1100
+ } finally {
1101
+ notifyDepth--;
1102
+ if (notifyDepth === 0) {
1103
+ pendingQueue.length = 0;
1104
+ pendingSet.clear();
1105
+ }
1106
+ }
1107
+ }
1051
1108
  function propagateDirty(sub2) {
1052
1109
  sub2();
1053
1110
  const rootSig = sub2._sig;
@@ -1080,6 +1137,22 @@ function propagateDirty(sub2) {
1080
1137
  }
1081
1138
  }
1082
1139
  }
1140
+ function queueSignalNotification(signal2) {
1141
+ const sig = signal2;
1142
+ let node = sig.subsHead ?? null;
1143
+ while (node) {
1144
+ const s2 = node.sub;
1145
+ if (s2) {
1146
+ if (s2._c) {
1147
+ propagateDirty(s2);
1148
+ } else if (!pendingSet.has(s2)) {
1149
+ pendingSet.add(s2);
1150
+ pendingQueue.push(s2);
1151
+ }
1152
+ }
1153
+ node = node.sigNext;
1154
+ }
1155
+ }
1083
1156
  function notifySubscribers(signal2) {
1084
1157
  const sig = signal2;
1085
1158
  const head2 = sig.subsHead;
@@ -1125,15 +1198,94 @@ function notifySubscribers(signal2) {
1125
1198
  }
1126
1199
  }
1127
1200
  }
1201
+ function getSubscriberCount(signal2) {
1202
+ return signal2.__sc ?? 0;
1203
+ }
1204
+ function getSubscriberDeps(subscriber) {
1205
+ const sub2 = subscriber;
1206
+ const out = [];
1207
+ let node = sub2.depsHead ?? null;
1208
+ while (node) {
1209
+ if (node.sig) out.push(node.sig);
1210
+ node = node.subNext;
1211
+ }
1212
+ return out;
1213
+ }
1214
+ function forEachSubscriber(signal2, visit) {
1215
+ let node = signal2.subsHead ?? null;
1216
+ while (node) {
1217
+ const s2 = node.sub;
1218
+ if (s2) visit(s2);
1219
+ node = node.sigNext;
1220
+ }
1221
+ }
1128
1222
 
1129
- // src/reactivity/bindAttribute.ts
1223
+ // src/reactivity/track.ts
1130
1224
  var _isDev3 = isDev();
1225
+ var _runtimeVersion = typeof __SIBU_VERSION__ !== "undefined" ? __SIBU_VERSION__ : "dev";
1226
+ var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
1227
+ function resolveReactiveApi() {
1228
+ const g2 = globalThis;
1229
+ const existing = g2[REGISTRY_KEY];
1230
+ if (existing) {
1231
+ if (_isDev3 && !existing.__dupWarned) {
1232
+ existing.__dupWarned = true;
1233
+ devWarn(
1234
+ `Multiple instances of the reactive runtime detected on this page (active: ${existing.version}, duplicate: ${_runtimeVersion}). Reactivity still works \u2014 all copies share the first one \u2014 but de-duplicate sibujs in your bundler (e.g. Vite optimizeDeps.exclude: ['sibujs'] or resolve.dedupe: ['sibujs']).`
1235
+ );
1236
+ }
1237
+ return existing;
1238
+ }
1239
+ const local = {
1240
+ suspendTracking,
1241
+ resumeTracking,
1242
+ isTrackingSuspended,
1243
+ untracked,
1244
+ retrack,
1245
+ track,
1246
+ reactiveBinding,
1247
+ recordDependency,
1248
+ cleanup,
1249
+ setMaxSubscriberRepeats,
1250
+ setMaxDrainIterations,
1251
+ drainNotificationQueue,
1252
+ queueSignalNotification,
1253
+ notifySubscribers,
1254
+ getSubscriberCount,
1255
+ getSubscriberDeps,
1256
+ forEachSubscriber,
1257
+ version: _runtimeVersion
1258
+ };
1259
+ g2[REGISTRY_KEY] = local;
1260
+ return local;
1261
+ }
1262
+ var API = resolveReactiveApi();
1263
+ var suspendTracking2 = API.suspendTracking;
1264
+ var resumeTracking2 = API.resumeTracking;
1265
+ var isTrackingSuspended2 = API.isTrackingSuspended;
1266
+ var untracked2 = API.untracked;
1267
+ var retrack2 = API.retrack;
1268
+ var track2 = API.track;
1269
+ var reactiveBinding2 = API.reactiveBinding;
1270
+ var recordDependency2 = API.recordDependency;
1271
+ var cleanup2 = API.cleanup;
1272
+ var setMaxSubscriberRepeats2 = API.setMaxSubscriberRepeats;
1273
+ var setMaxDrainIterations2 = API.setMaxDrainIterations;
1274
+ var drainNotificationQueue2 = API.drainNotificationQueue;
1275
+ var queueSignalNotification2 = API.queueSignalNotification;
1276
+ var notifySubscribers2 = API.notifySubscribers;
1277
+ var getSubscriberCount2 = API.getSubscriberCount;
1278
+ var getSubscriberDeps2 = API.getSubscriberDeps;
1279
+ var forEachSubscriber2 = API.forEachSubscriber;
1280
+
1281
+ // src/reactivity/bindAttribute.ts
1282
+ var _isDev4 = isDev();
1131
1283
  function setProp(el, key, val) {
1132
1284
  el[key] = val;
1133
1285
  }
1134
1286
  function bindAttribute(el, attr, getter) {
1135
1287
  if (isEventHandlerAttr(attr)) {
1136
- if (_isDev3)
1288
+ if (_isDev4)
1137
1289
  devWarn(
1138
1290
  `bindAttribute: refusing to bind event-handler attribute "${attr}". Use on:{ ${attr.slice(2)}: fn } instead.`
1139
1291
  );
@@ -1145,7 +1297,7 @@ function bindAttribute(el, attr, getter) {
1145
1297
  try {
1146
1298
  value = getter();
1147
1299
  } catch (err) {
1148
- if (_isDev3)
1300
+ if (_isDev4)
1149
1301
  devWarn(`bindAttribute: getter for "${attr}" threw: ${err instanceof Error ? err.message : String(err)}`);
1150
1302
  return;
1151
1303
  }
@@ -1166,7 +1318,7 @@ function bindAttribute(el, attr, getter) {
1166
1318
  el.setAttribute(attr, sanitizeAttributeString(attr, str));
1167
1319
  }
1168
1320
  }
1169
- return reactiveBinding(commit);
1321
+ return reactiveBinding2(commit);
1170
1322
  }
1171
1323
 
1172
1324
  // src/reactivity/bindChildNode.ts
@@ -1175,7 +1327,7 @@ init_dev();
1175
1327
  // src/core/rendering/dispose.ts
1176
1328
  init_dev();
1177
1329
  var elementDisposers = /* @__PURE__ */ new WeakMap();
1178
- var _isDev4 = isDev();
1330
+ var _isDev5 = isDev();
1179
1331
  var activeBindingCount = 0;
1180
1332
  function registerDisposer(node, teardown) {
1181
1333
  let disposers = elementDisposers.get(node);
@@ -1184,7 +1336,7 @@ function registerDisposer(node, teardown) {
1184
1336
  elementDisposers.set(node, disposers);
1185
1337
  }
1186
1338
  disposers.push(teardown);
1187
- if (_isDev4) activeBindingCount++;
1339
+ if (_isDev5) activeBindingCount++;
1188
1340
  }
1189
1341
  function dispose(node) {
1190
1342
  const stack = [node];
@@ -1203,12 +1355,12 @@ function dispose(node) {
1203
1355
  if (disposers) {
1204
1356
  const snapshot = disposers.slice();
1205
1357
  elementDisposers.delete(current);
1206
- if (_isDev4) activeBindingCount -= snapshot.length;
1358
+ if (_isDev5) activeBindingCount -= snapshot.length;
1207
1359
  for (const d of snapshot) {
1208
1360
  try {
1209
1361
  d();
1210
1362
  } catch (err) {
1211
- if (_isDev4 && typeof console !== "undefined") {
1363
+ if (_isDev5 && typeof console !== "undefined") {
1212
1364
  console.warn("[SibuJS] Disposer threw during cleanup:", err);
1213
1365
  }
1214
1366
  }
@@ -1219,12 +1371,12 @@ function dispose(node) {
1219
1371
  if (!added || added.length === 0) break;
1220
1372
  const moreSnapshot = added.slice();
1221
1373
  elementDisposers.delete(current);
1222
- if (_isDev4) activeBindingCount -= moreSnapshot.length;
1374
+ if (_isDev5) activeBindingCount -= moreSnapshot.length;
1223
1375
  for (const d of moreSnapshot) {
1224
1376
  try {
1225
1377
  d();
1226
1378
  } catch (err) {
1227
- if (_isDev4 && typeof console !== "undefined") {
1379
+ if (_isDev5 && typeof console !== "undefined") {
1228
1380
  console.warn("[SibuJS] Disposer threw during cleanup:", err);
1229
1381
  }
1230
1382
  }
@@ -1235,7 +1387,7 @@ function dispose(node) {
1235
1387
  }
1236
1388
 
1237
1389
  // src/reactivity/bindChildNode.ts
1238
- var _isDev5 = isDev();
1390
+ var _isDev6 = isDev();
1239
1391
  function bindChildNode(placeholder, getter) {
1240
1392
  let lastNodes = [];
1241
1393
  function commit() {
@@ -1243,7 +1395,7 @@ function bindChildNode(placeholder, getter) {
1243
1395
  try {
1244
1396
  result = getter();
1245
1397
  } catch (err) {
1246
- if (_isDev5) devWarn(`bindChildNode: getter threw: ${err instanceof Error ? err.message : String(err)}`);
1398
+ if (_isDev6) devWarn(`bindChildNode: getter threw: ${err instanceof Error ? err.message : String(err)}`);
1247
1399
  return;
1248
1400
  }
1249
1401
  if (result == null || typeof result === "boolean") {
@@ -1269,7 +1421,7 @@ function bindChildNode(placeholder, getter) {
1269
1421
  if (item == null || typeof item === "boolean") continue;
1270
1422
  const node = item instanceof Node ? item : document.createTextNode(String(item));
1271
1423
  if (seen.has(node)) {
1272
- if (_isDev5)
1424
+ if (_isDev6)
1273
1425
  devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
1274
1426
  continue;
1275
1427
  }
@@ -1304,13 +1456,13 @@ function bindChildNode(placeholder, getter) {
1304
1456
  }
1305
1457
  lastNodes = newNodes;
1306
1458
  }
1307
- return reactiveBinding(commit);
1459
+ return reactiveBinding2(commit);
1308
1460
  }
1309
1461
 
1310
1462
  // src/core/rendering/tagFactory.ts
1311
1463
  init_sanitize();
1312
1464
  var SVG_NS = "http://www.w3.org/2000/svg";
1313
- var _isDev6 = isDev();
1465
+ var _isDev7 = isDev();
1314
1466
  var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
1315
1467
  function isBlockedTag(tag) {
1316
1468
  return BLOCKED_TAGS.has(tag.toLowerCase());
@@ -1353,7 +1505,7 @@ function toKebab(prop) {
1353
1505
  }
1354
1506
  function applyStyle(el, style2) {
1355
1507
  if (typeof style2 === "function") {
1356
- const teardown = track(() => {
1508
+ const teardown = track2(() => {
1357
1509
  el.setAttribute("style", style2());
1358
1510
  });
1359
1511
  registerDisposer(el, teardown);
@@ -1369,7 +1521,7 @@ function applyStyle(el, style2) {
1369
1521
  const name = toKebab(prop);
1370
1522
  if (typeof val === "function") {
1371
1523
  const getter = val;
1372
- const teardown = track(() => {
1524
+ const teardown = track2(() => {
1373
1525
  htmlEl.style.setProperty(name, sanitizeCSSValue(String(getter())));
1374
1526
  });
1375
1527
  registerDisposer(el, teardown);
@@ -1384,7 +1536,7 @@ function applyClass(el, cls) {
1384
1536
  return;
1385
1537
  }
1386
1538
  if (typeof cls === "function") {
1387
- const teardown = track(() => {
1539
+ const teardown = track2(() => {
1388
1540
  el.setAttribute("class", cls());
1389
1541
  });
1390
1542
  registerDisposer(el, teardown);
@@ -1411,7 +1563,7 @@ function applyClass(el, cls) {
1411
1563
  }
1412
1564
  el.setAttribute("class", r);
1413
1565
  };
1414
- const teardown = track(update);
1566
+ const teardown = track2(update);
1415
1567
  registerDisposer(el, teardown);
1416
1568
  } else {
1417
1569
  el.setAttribute("class", result);
@@ -1481,7 +1633,7 @@ var tagFactory = (tag, ns) => {
1481
1633
  appendChildren(el, second);
1482
1634
  return el;
1483
1635
  }
1484
- if (_isDev6 && looksLikeClassList(first)) {
1636
+ if (_isDev7 && looksLikeClassList(first)) {
1485
1637
  devWarn(
1486
1638
  `tagFactory: lone string "${first}" looks like a class list but is being rendered as TEXT. For a class, use ${tag}({ class: "${first}" }) \u2014 or ${tag}("${first}", children) to set the class AND add children.`
1487
1639
  );
@@ -1502,7 +1654,7 @@ var tagFactory = (tag, ns) => {
1502
1654
  if (pClass != null) applyClass(el, pClass);
1503
1655
  const pId = props.id;
1504
1656
  if (pId != null) {
1505
- if (_isDev6 && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
1657
+ if (_isDev7 && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
1506
1658
  devWarn(
1507
1659
  `tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
1508
1660
  );
@@ -1517,7 +1669,7 @@ var tagFactory = (tag, ns) => {
1517
1669
  const handler = pOn[ev];
1518
1670
  if (typeof handler === "function") {
1519
1671
  el.addEventListener(ev, handler);
1520
- } else if (_isDev6) {
1672
+ } else if (_isDev7) {
1521
1673
  devWarn(
1522
1674
  `tagFactory: on.${ev} handler is not a function (got ${typeof handler}). Event listener was not attached.`
1523
1675
  );
@@ -1630,7 +1782,7 @@ var area = tagFactory("area");
1630
1782
  var audio = tagFactory("audio");
1631
1783
  var img = tagFactory("img");
1632
1784
  var map = tagFactory("map");
1633
- var track2 = tagFactory("track");
1785
+ var track3 = tagFactory("track");
1634
1786
  var video = tagFactory("video");
1635
1787
  var embed = tagFactory("embed");
1636
1788
  var iframe = tagFactory("iframe");
@@ -1707,16 +1859,57 @@ var marquee = tagFactory("marquee");
1707
1859
  // src/reactivity/batch.ts
1708
1860
  var batchDepth = 0;
1709
1861
  var pendingSignals = /* @__PURE__ */ new Set();
1710
- function enqueueBatchedSignal(signal2) {
1862
+ function batchImpl(fn) {
1863
+ batchDepth++;
1864
+ try {
1865
+ return fn();
1866
+ } finally {
1867
+ batchDepth--;
1868
+ if (batchDepth === 0) {
1869
+ flushBatch();
1870
+ }
1871
+ }
1872
+ }
1873
+ function enqueueBatchedSignalImpl(signal2) {
1711
1874
  if (batchDepth === 0) return false;
1712
1875
  pendingSignals.add(signal2);
1713
1876
  return true;
1714
1877
  }
1878
+ function isBatchingImpl() {
1879
+ return batchDepth > 0;
1880
+ }
1881
+ function flushBatch() {
1882
+ try {
1883
+ for (const signal2 of pendingSignals) {
1884
+ queueSignalNotification2(signal2);
1885
+ }
1886
+ } finally {
1887
+ pendingSignals.clear();
1888
+ }
1889
+ drainNotificationQueue2();
1890
+ }
1891
+ var BATCH_REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.batch.v1");
1892
+ function resolveBatchApi() {
1893
+ const g2 = globalThis;
1894
+ const existing = g2[BATCH_REGISTRY_KEY];
1895
+ if (existing) return existing;
1896
+ const local = {
1897
+ batch: batchImpl,
1898
+ enqueueBatchedSignal: enqueueBatchedSignalImpl,
1899
+ isBatching: isBatchingImpl
1900
+ };
1901
+ g2[BATCH_REGISTRY_KEY] = local;
1902
+ return local;
1903
+ }
1904
+ var API2 = resolveBatchApi();
1905
+ var batch = API2.batch;
1906
+ var enqueueBatchedSignal = API2.enqueueBatchedSignal;
1907
+ var isBatching = API2.isBatching;
1715
1908
 
1716
1909
  // src/core/signals/signal.ts
1717
1910
  init_dev();
1718
1911
  var _g = globalThis;
1719
- var _isDev7 = isDev();
1912
+ var _isDev8 = isDev();
1720
1913
  function signal(initial, options) {
1721
1914
  const state = {
1722
1915
  value: initial,
@@ -1727,11 +1920,11 @@ function signal(initial, options) {
1727
1920
  __activeNode: null,
1728
1921
  __name: void 0
1729
1922
  };
1730
- const debugName = _isDev7 ? options?.name : void 0;
1923
+ const debugName = _isDev8 ? options?.name : void 0;
1731
1924
  const equalsFn = options?.equals;
1732
1925
  if (debugName) state.__name = debugName;
1733
1926
  function get() {
1734
- recordDependency(state);
1927
+ recordDependency2(state);
1735
1928
  return state.value;
1736
1929
  }
1737
1930
  get.__signal = state;
@@ -1744,15 +1937,15 @@ function signal(initial, options) {
1744
1937
  if (equalsFn(prev, newValue)) return;
1745
1938
  state.value = newValue;
1746
1939
  state.__v++;
1747
- if (_isDev7) {
1940
+ if (_isDev8) {
1748
1941
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1749
1942
  if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
1750
1943
  }
1751
1944
  if (!enqueueBatchedSignal(state)) {
1752
- notifySubscribers(state);
1945
+ notifySubscribers2(state);
1753
1946
  }
1754
1947
  };
1755
- } else if (_isDev7) {
1948
+ } else if (_isDev8) {
1756
1949
  set = (next) => {
1757
1950
  const prev = state.value;
1758
1951
  const newValue = typeof next === "function" ? next(prev) : next;
@@ -1762,7 +1955,7 @@ function signal(initial, options) {
1762
1955
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1763
1956
  if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
1764
1957
  if (!enqueueBatchedSignal(state)) {
1765
- notifySubscribers(state);
1958
+ notifySubscribers2(state);
1766
1959
  }
1767
1960
  };
1768
1961
  } else {
@@ -1773,11 +1966,11 @@ function signal(initial, options) {
1773
1966
  state.value = newValue;
1774
1967
  state.__v++;
1775
1968
  if (!enqueueBatchedSignal(state)) {
1776
- notifySubscribers(state);
1969
+ notifySubscribers2(state);
1777
1970
  }
1778
1971
  };
1779
1972
  }
1780
- if (_isDev7) {
1973
+ if (_isDev8) {
1781
1974
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1782
1975
  if (hook) hook.emit("signal:create", { signal: state, name: debugName, getter: get, initial });
1783
1976
  }
@@ -1834,7 +2027,7 @@ function drainReruns(ctx) {
1834
2027
  do {
1835
2028
  ctx.rerunPending = false;
1836
2029
  if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
1837
- retrack(ctx.bodyFn, ctx.subscriber);
2030
+ retrack2(ctx.bodyFn, ctx.subscriber);
1838
2031
  } while (ctx.rerunPending && ++reruns <= MAX_RERUNS);
1839
2032
  if (ctx.rerunPending) {
1840
2033
  ctx.rerunPending = false;
@@ -1863,7 +2056,7 @@ function disposeEffect(ctx) {
1863
2056
  }
1864
2057
  }
1865
2058
  try {
1866
- cleanup(ctx.subscriber);
2059
+ cleanup2(ctx.subscriber);
1867
2060
  } catch (err) {
1868
2061
  if (typeof console !== "undefined") {
1869
2062
  console.warn("[SibuJS effect] dispose threw:", err);
@@ -1908,7 +2101,7 @@ function effect(effectFn, options) {
1908
2101
  try {
1909
2102
  ctx.rerunPending = false;
1910
2103
  if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
1911
- retrack(ctx.bodyFn, sub2);
2104
+ retrack2(ctx.bodyFn, sub2);
1912
2105
  if (ctx.rerunPending) drainReruns(ctx);
1913
2106
  } finally {
1914
2107
  ctx.running = false;
@@ -1924,7 +2117,7 @@ function effect(effectFn, options) {
1924
2117
  ctx.subscriber = sub2;
1925
2118
  ctx.running = true;
1926
2119
  try {
1927
- retrack(ctx.bodyFn, ctx.subscriber);
2120
+ retrack2(ctx.bodyFn, ctx.subscriber);
1928
2121
  if (ctx.rerunPending) drainReruns(ctx);
1929
2122
  } finally {
1930
2123
  ctx.running = false;
@@ -2943,7 +3136,7 @@ function Route() {
2943
3136
  await originalUpdate();
2944
3137
  routeInitialized = true;
2945
3138
  };
2946
- const routeTeardown = track(wrappedUpdate);
3139
+ const routeTeardown = track2(wrappedUpdate);
2947
3140
  if (!routeInitialized) {
2948
3141
  queueMicrotask(() => {
2949
3142
  if (!routeInitialized && anchor.parentNode) wrappedUpdate();
@@ -3056,7 +3249,7 @@ function KeepAliveRoute(options) {
3056
3249
  await update();
3057
3250
  initialized = true;
3058
3251
  };
3059
- const kaTeardown = track(wrappedUpdate);
3252
+ const kaTeardown = track2(wrappedUpdate);
3060
3253
  if (!initialized) {
3061
3254
  queueMicrotask(() => {
3062
3255
  if (!initialized && anchor.parentNode) wrappedUpdate();
@@ -3321,7 +3514,7 @@ function Outlet() {
3321
3514
  console.error("[Outlet] Failed to render child route:", error);
3322
3515
  }
3323
3516
  };
3324
- const outletTeardown = track(update);
3517
+ const outletTeardown = track2(update);
3325
3518
  if (!anchor.parentNode) {
3326
3519
  queueMicrotask(() => {
3327
3520
  if (anchor.parentNode) update();
package/dist/plugins.js CHANGED
@@ -35,14 +35,14 @@ import {
35
35
  } from "./chunk-3JHCYHWN.js";
36
36
  import {
37
37
  span
38
- } from "./chunk-24DBWDTK.js";
38
+ } from "./chunk-37BUKSLH.js";
39
39
  import {
40
40
  escapeScriptJson,
41
41
  isDangerousMetaRefresh,
42
42
  renderToString
43
43
  } from "./chunk-R3QEDXFS.js";
44
- import "./chunk-NUWKIEHE.js";
45
- import "./chunk-Q2ERM6NT.js";
44
+ import "./chunk-LU2MQXQQ.js";
45
+ import "./chunk-NHKQKKZU.js";
46
46
  import {
47
47
  dispose,
48
48
  registerDisposer
@@ -55,14 +55,14 @@ import {
55
55
  } from "./chunk-L3GAGWCC.js";
56
56
  import {
57
57
  effect
58
- } from "./chunk-7JHWAGRQ.js";
58
+ } from "./chunk-MHBCEJQO.js";
59
59
  import "./chunk-GOJMFRBL.js";
60
60
  import {
61
61
  signal
62
- } from "./chunk-5K72I3UQ.js";
62
+ } from "./chunk-WZG2SZOT.js";
63
63
  import {
64
64
  track
65
- } from "./chunk-X3NHE2DK.js";
65
+ } from "./chunk-TEFZT5PJ.js";
66
66
  import "./chunk-COY6PUD2.js";
67
67
 
68
68
  // src/plugins/i18n.ts