sibujs 1.0.0-beta.3 → 1.0.0-beta.5

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 (68) hide show
  1. package/README.md +87 -81
  2. package/dist/browser.cjs +6 -3
  3. package/dist/browser.js +17 -440
  4. package/dist/build.cjs +51 -10
  5. package/dist/build.js +10 -8
  6. package/dist/cdn.global.js +4 -4
  7. package/dist/chunk-2X5NDXNG.js +877 -0
  8. package/dist/chunk-353KB3DI.js +271 -0
  9. package/dist/chunk-6BCDNGIH.js +1839 -0
  10. package/dist/chunk-6BDUQJ7K.js +949 -0
  11. package/dist/chunk-6DJQF4Z7.js +33 -0
  12. package/dist/chunk-BS5EYKCJ.js +26 -0
  13. package/dist/chunk-CHJ27IGK.js +26 -0
  14. package/dist/chunk-DKXVN442.js +90 -0
  15. package/dist/chunk-DZZMIMGL.js +725 -0
  16. package/dist/chunk-E6BNBVMK.js +457 -0
  17. package/dist/chunk-GVDEIJ3G.js +291 -0
  18. package/dist/chunk-HGKEBAW3.js +63 -0
  19. package/dist/chunk-HJNW3HLI.js +255 -0
  20. package/dist/chunk-JLOASJXU.js +654 -0
  21. package/dist/chunk-K5ZUMYVS.js +89 -0
  22. package/dist/chunk-K7JUDY3C.js +364 -0
  23. package/dist/chunk-MWE3PK5S.js +551 -0
  24. package/dist/chunk-MXR7LXGC.js +1084 -0
  25. package/dist/chunk-QI6ZDDUR.js +35 -0
  26. package/dist/chunk-UKDBQVM3.js +346 -0
  27. package/dist/chunk-USPT25TC.js +365 -0
  28. package/dist/chunk-WGCQNOEQ.js +712 -0
  29. package/dist/chunk-XFW7B23S.js +282 -0
  30. package/dist/data.cjs +11 -3
  31. package/dist/data.js +26 -920
  32. package/dist/devtools.js +36 -1046
  33. package/dist/ecosystem.cjs +6 -3
  34. package/dist/ecosystem.d.cts +1 -14
  35. package/dist/ecosystem.d.ts +1 -14
  36. package/dist/ecosystem.js +16 -356
  37. package/dist/extras.cjs +1102 -998
  38. package/dist/extras.d.cts +15 -2356
  39. package/dist/extras.d.ts +15 -2356
  40. package/dist/extras.js +337 -4925
  41. package/dist/index.cjs +51 -10
  42. package/dist/index.d.cts +1 -1
  43. package/dist/index.d.ts +1 -1
  44. package/dist/index.js +14 -10
  45. package/dist/motion.js +21 -323
  46. package/dist/patterns.cjs +16 -5
  47. package/dist/patterns.d.cts +8 -0
  48. package/dist/patterns.d.ts +8 -0
  49. package/dist/patterns.js +15 -251
  50. package/dist/performance.js +36 -616
  51. package/dist/plugin-Bek4RhJY.d.cts +43 -0
  52. package/dist/plugin-Bek4RhJY.d.ts +43 -0
  53. package/dist/plugins.cjs +914 -36
  54. package/dist/plugins.d.cts +6 -2
  55. package/dist/plugins.d.ts +6 -2
  56. package/dist/plugins.js +106 -36
  57. package/dist/ssr-NFAIHWJJ.js +35 -0
  58. package/dist/ssr.cjs +17 -10
  59. package/dist/ssr.d.cts +209 -209
  60. package/dist/ssr.d.ts +209 -209
  61. package/dist/ssr.js +32 -685
  62. package/dist/startup-0Qv6aosO.d.cts +291 -0
  63. package/dist/startup-0Qv6aosO.d.ts +291 -0
  64. package/dist/ui.cjs +26 -13
  65. package/dist/ui.js +43 -826
  66. package/dist/widgets.cjs +42 -5
  67. package/dist/widgets.js +14 -531
  68. package/package.json +7 -2
package/README.md CHANGED
@@ -671,7 +671,7 @@ function App() {
671
671
  ${RouterLink({ to: "/", nodes: "Home" })}
672
672
  ${RouterLink({ to: "/about", nodes: "About" })}
673
673
  </nav>
674
- ${route()}
674
+ ${Route()}
675
675
  </div>`;
676
676
  }
677
677
 
@@ -710,14 +710,14 @@ Trans("greeting", { name: "Mark" });
710
710
 
711
711
  ---
712
712
 
713
- ## Extras (`sibu/extras`)
713
+ ## Patterns (`sibujs/patterns`)
714
714
 
715
- Advanced features, imported separately to keep the core lean.
715
+ Advanced state management patterns, imported separately to keep the core lean.
716
716
 
717
717
  ### State Machines
718
718
 
719
719
  ```ts
720
- import { machine } from "sibujs/extras";
720
+ import { machine } from "sibujs/patterns";
721
721
 
722
722
  const { state, send, matches, can } = machine({
723
723
  initial: "idle",
@@ -749,30 +749,28 @@ can("RETRY"); // false (not in error state)
749
749
  ### Form Validation
750
750
 
751
751
  ```ts
752
- import { form, required, email, minLength } from "sibujs/extras";
752
+ import { form, required, email, minLength } from "sibujs/ui";
753
753
 
754
- const form = form({
755
- fields: {
756
- username: { initial: "", validators: [required(), minLength(3)] },
757
- email: { initial: "", validators: [required(), email()] },
758
- },
759
- onSubmit: (values) => api.register(values),
754
+ const myForm = form({
755
+ username: { initial: "", validators: [required(), minLength(3)] },
756
+ email: { initial: "", validators: [required(), email()] },
760
757
  });
761
758
 
762
759
  // Reactive getters
763
- form.fields.username.value();
764
- form.errors.username();
765
- form.isValid();
766
- form.isDirty();
760
+ myForm.fields.username.value();
761
+ myForm.fields.username.error();
762
+ myForm.isValid();
763
+ myForm.isDirty();
767
764
 
768
- // Handle submission
769
- form.handleSubmit();
765
+ // Handle submission (pass callback to handleSubmit)
766
+ const onSubmit = myForm.handleSubmit((values) => api.register(values));
767
+ // Attach to form: on: { submit: onSubmit }
770
768
  ```
771
769
 
772
770
  ### Global Store
773
771
 
774
772
  ```ts
775
- import { globalStore } from "sibujs/extras";
773
+ import { globalStore } from "sibujs/patterns";
776
774
 
777
775
  const store = globalStore({
778
776
  state: { count: 0, user: null },
@@ -780,7 +778,7 @@ const store = globalStore({
780
778
  increment: (state) => ({ ...state, count: state.count + 1 }),
781
779
  setUser: (state, user) => ({ ...state, user }),
782
780
  },
783
- middleware: [(action, state) => console.log(action, state)],
781
+ middleware: [(state, action, payload, next) => { console.log(action, state); next(); }],
784
782
  });
785
783
 
786
784
  store.dispatch("increment");
@@ -791,7 +789,7 @@ count(); // 1
791
789
  ### Persistent State
792
790
 
793
791
  ```ts
794
- import { persisted } from "sibujs/extras";
792
+ import { persisted } from "sibujs/patterns";
795
793
 
796
794
  // Auto-saves to localStorage, restores on page load
797
795
  const [theme, setTheme] = persisted("app-theme", "light");
@@ -801,7 +799,7 @@ setTheme("dark"); // saved to localStorage automatically
801
799
  ### Time Travel
802
800
 
803
801
  ```ts
804
- import { timeline } from "sibujs/extras";
802
+ import { timeline } from "sibujs/patterns";
805
803
 
806
804
  const { value, set, undo, redo, canUndo, canRedo } = timeline("initial");
807
805
  set("second");
@@ -813,7 +811,7 @@ redo(); // value() === "third"
813
811
  ### Optimistic Updates
814
812
 
815
813
  ```ts
816
- import { optimistic } from "sibujs/extras";
814
+ import { optimistic } from "sibujs/patterns";
817
815
 
818
816
  const [likes, addLike] = optimistic(0);
819
817
  addLike(likes() + 1, async () => {
@@ -821,10 +819,10 @@ addLike(likes() + 1, async () => {
821
819
  });
822
820
  ```
823
821
 
824
- ### Data Fetching
822
+ ## Data Fetching (`sibujs/data`)
825
823
 
826
824
  ```ts
827
- import { query, mutation, infiniteQuery, resource } from "sibujs/extras";
825
+ import { query, mutation, infiniteQuery, resource } from "sibujs/data";
828
826
 
829
827
  // Query with caching, stale-while-revalidate, and auto-refetch
830
828
  const { data, loading, error, refetch } = query("users", async ({ signal }) => {
@@ -836,7 +834,7 @@ const { data, loading, error, refetch } = query("users", async ({ signal }) => {
836
834
  });
837
835
 
838
836
  // Cache management
839
- import { invalidateQueries, setQueryData } from "sibujs/extras";
837
+ import { invalidateQueries, setQueryData } from "sibujs/data";
840
838
  invalidateQueries("users");
841
839
  setQueryData("users", (prev) => [...prev, newUser]);
842
840
 
@@ -872,7 +870,7 @@ resource.data(); // reactive
872
870
  ### Debounce, Throttle, and Previous
873
871
 
874
872
  ```ts
875
- import { debounce, throttle, previous } from "sibujs/extras";
873
+ import { debounce, throttle, previous } from "sibujs/data";
876
874
 
877
875
  // Debounced reactive value (updates after 300ms of inactivity)
878
876
  const debouncedSearch = debounce(() => searchInput(), 300);
@@ -885,7 +883,7 @@ const prevCount = previous(count);
885
883
  // prevCount() is the value before the last change
886
884
  ```
887
885
 
888
- ### Browser APIs
886
+ ## Browser APIs (`sibujs/browser`)
889
887
 
890
888
  All browser APIs return reactive getters and a `dispose` function for cleanup.
891
889
 
@@ -904,7 +902,7 @@ import {
904
902
  battery,
905
903
  idle,
906
904
  permissions,
907
- } from "sibujs/extras";
905
+ } from "sibujs/browser";
908
906
 
909
907
  // Media queries
910
908
  const { matches: isMobile } = media("(max-width: 768px)");
@@ -952,7 +950,8 @@ const { state: cameraPermission } = permissions("camera");
952
950
  ### Real-Time Communication
953
951
 
954
952
  ```ts
955
- import { socket, stream, eventBus } from "sibujs/extras";
953
+ import { socket, stream } from "sibujs/data";
954
+ import { eventBus } from "sibujs/ui";
956
955
 
957
956
  // WebSocket with auto-reconnect and heartbeat
958
957
  const { data, status, send, close } = socket("wss://api.example.com/ws", {
@@ -976,11 +975,13 @@ bus.emit("notify", "Hello!");
976
975
  off(); // unsubscribe
977
976
  ```
978
977
 
978
+ ## UI Utilities (`sibujs/ui`)
979
+
979
980
  ### Virtual List
980
981
 
981
982
  ```ts
982
983
  import { html, signal } from "sibujs";
983
- import { VirtualList } from "sibujs/extras";
984
+ import { VirtualList } from "sibujs/ui";
984
985
 
985
986
  VirtualList({
986
987
  items: () => largeArray(),
@@ -991,10 +992,10 @@ VirtualList({
991
992
  });
992
993
  ```
993
994
 
994
- ### Transitions and Animations
995
+ ## Transitions and Animations (`sibujs/motion`)
995
996
 
996
997
  ```ts
997
- import { transition, TransitionGroup, viewTransition } from "sibujs/extras";
998
+ import { transition, TransitionGroup, viewTransition } from "sibujs/motion";
998
999
 
999
1000
  // Single element transition
1000
1001
  const { enter, leave } = transition(element, {
@@ -1023,7 +1024,7 @@ await start();
1023
1024
  ### Dialogs and Toasts
1024
1025
 
1025
1026
  ```ts
1026
- import { dialog, toast } from "sibujs/extras";
1027
+ import { dialog, toast } from "sibujs/ui";
1027
1028
 
1028
1029
  // Dialog state
1029
1030
  const dialog = dialog();
@@ -1043,7 +1044,7 @@ dismiss(id);
1043
1044
  ### Pagination and Infinite Scroll
1044
1045
 
1045
1046
  ```ts
1046
- import { pagination, infiniteScroll } from "sibujs/extras";
1047
+ import { pagination, infiniteScroll } from "sibujs/ui";
1047
1048
 
1048
1049
  // Pagination
1049
1050
  const { page, totalPages, next, prev, goTo, startIndex, endIndex } = pagination({
@@ -1062,7 +1063,7 @@ const { sentinelRef, loading } = infiniteScroll({
1062
1063
  ### Intersection Observer and Lazy Loading
1063
1064
 
1064
1065
  ```ts
1065
- import { intersection, lazyLoad } from "sibujs/extras";
1066
+ import { intersection, lazyLoad } from "sibujs/ui";
1066
1067
 
1067
1068
  // Track element visibility
1068
1069
  const { isIntersecting, intersectionRatio, observe } = intersection({
@@ -1079,7 +1080,7 @@ const cleanup = lazyLoad(placeholder, () => {
1079
1080
  ### Input Masks
1080
1081
 
1081
1082
  ```ts
1082
- import { inputMask, phoneMask, dateMask, creditCardMask } from "sibujs/extras";
1083
+ import { inputMask, phoneMask, dateMask, creditCardMask } from "sibujs/ui";
1083
1084
 
1084
1085
  const phone = inputMask(phoneMask()); // (999) 999-9999
1085
1086
  const date = inputMask(dateMask()); // 99/99/9999
@@ -1094,7 +1095,7 @@ phone.rawValue(); // unformatted: "5551234567"
1094
1095
 
1095
1096
  ```ts
1096
1097
  import { html } from "sibujs";
1097
- import { aria, FocusTrap, hotkey, announce } from "sibujs/extras";
1098
+ import { aria, FocusTrap, hotkey, announce } from "sibujs/ui";
1098
1099
 
1099
1100
  // Reactive ARIA attributes
1100
1101
  aria(element, {
@@ -1116,7 +1117,7 @@ announce("Item deleted", "polite");
1116
1117
 
1117
1118
  ```ts
1118
1119
  import { html } from "sibujs";
1119
- import { scopedStyle, withScopedStyle } from "sibujs/extras";
1120
+ import { scopedStyle, withScopedStyle } from "sibujs/ui";
1120
1121
 
1121
1122
  // Manual scoping
1122
1123
  const { scope, attr } = scopedStyle(`
@@ -1133,7 +1134,7 @@ const StyledCard = withScopedStyle(`
1133
1134
  ### Higher-Order Components
1134
1135
 
1135
1136
  ```ts
1136
- import { withDefaults, withWrapper, compose } from "sibujs/extras";
1137
+ import { withDefaults, withWrapper, compose } from "sibujs/patterns";
1137
1138
 
1138
1139
  const Button = withDefaults(BaseButton, { variant: "primary", size: "md" });
1139
1140
 
@@ -1149,7 +1150,7 @@ const EnhancedButton = compose(withLogging, withTheme, withTooltip)(BaseButton);
1149
1150
 
1150
1151
  ```ts
1151
1152
  import { html, signal } from "sibujs";
1152
- import { composable } from "sibujs/extras";
1153
+ import { composable } from "sibujs/ui";
1153
1154
 
1154
1155
  const counterSetup = composable(() => {
1155
1156
  const [count, setCount] = signal(0);
@@ -1165,14 +1166,14 @@ function MyComponent() {
1165
1166
 
1166
1167
  ---
1167
1168
 
1168
- ## Widgets (`sibu/extras`)
1169
+ ## Widgets (`sibujs/widgets`)
1169
1170
 
1170
1171
  Headless UI primitives -- state logic and keyboard navigation without opinions on markup. Build your own UI on top.
1171
1172
 
1172
1173
  ### Tabs
1173
1174
 
1174
1175
  ```ts
1175
- import { tabs } from "sibujs/extras";
1176
+ import { tabs } from "sibujs/widgets";
1176
1177
 
1177
1178
  const tabs = tabs({
1178
1179
  tabs: [
@@ -1192,7 +1193,7 @@ tabs.prevTab();
1192
1193
  ### Select
1193
1194
 
1194
1195
  ```ts
1195
- import { select } from "sibujs/extras";
1196
+ import { select } from "sibujs/widgets";
1196
1197
 
1197
1198
  const select = select({
1198
1199
  items: ["Apple", "Banana", "Cherry"],
@@ -1209,7 +1210,7 @@ select.isSelected("Apple"); // true
1209
1210
  ### Accordion
1210
1211
 
1211
1212
  ```ts
1212
- import { accordion } from "sibujs/extras";
1213
+ import { accordion } from "sibujs/widgets";
1213
1214
 
1214
1215
  const accordion = accordion({
1215
1216
  items: [
@@ -1228,7 +1229,7 @@ accordion.collapseAll();
1228
1229
  ### Combobox
1229
1230
 
1230
1231
  ```ts
1231
- import { combobox } from "sibujs/extras";
1232
+ import { combobox } from "sibujs/widgets";
1232
1233
 
1233
1234
  const combo = combobox({
1234
1235
  items: ["New York", "Los Angeles", "Chicago", "Houston"],
@@ -1244,7 +1245,7 @@ combo.selectedItem(); // "Chicago"
1244
1245
  ### Popover and Tooltip
1245
1246
 
1246
1247
  ```ts
1247
- import { popover, tooltip } from "sibujs/extras";
1248
+ import { popover, tooltip } from "sibujs/widgets";
1248
1249
 
1249
1250
  const popover = popover();
1250
1251
  popover.toggle();
@@ -1259,7 +1260,7 @@ tooltip.isVisible(); // true (after 200ms delay)
1259
1260
  ### File Upload
1260
1261
 
1261
1262
  ```ts
1262
- import { fileUpload } from "sibujs/extras";
1263
+ import { fileUpload } from "sibujs/widgets";
1263
1264
 
1264
1265
  const upload = fileUpload({
1265
1266
  accept: "image/*",
@@ -1277,7 +1278,7 @@ upload.clear();
1277
1278
  ### Date Picker
1278
1279
 
1279
1280
  ```ts
1280
- import { datePicker } from "sibujs/extras";
1281
+ import { datePicker } from "sibujs/widgets";
1281
1282
 
1282
1283
  const picker = datePicker({
1283
1284
  minDate: new Date(2020, 0, 1),
@@ -1293,7 +1294,7 @@ picker.selectedDate(); // Date
1293
1294
  ### Content Editable
1294
1295
 
1295
1296
  ```ts
1296
- import { contentEditable } from "sibujs/extras";
1297
+ import { contentEditable } from "sibujs/widgets";
1297
1298
 
1298
1299
  const editor = contentEditable();
1299
1300
  editor.setContent("<b>Hello</b> world");
@@ -1305,11 +1306,11 @@ editor.content(); // reactive HTML string
1305
1306
 
1306
1307
  ---
1307
1308
 
1308
- ## Web Components (`sibu/extras`)
1309
+ ## Web Components (`sibujs/ui`)
1309
1310
 
1310
1311
  ```ts
1311
1312
  import { html, signal } from "sibujs";
1312
- import { defineElement } from "sibujs/extras";
1313
+ import { defineElement } from "sibujs/ui";
1313
1314
 
1314
1315
  defineElement("my-counter", (props) => {
1315
1316
  const [count, setCount] = signal(Number(props.initial) || 0);
@@ -1326,7 +1327,7 @@ defineElement("my-counter", (props) => {
1326
1327
 
1327
1328
  ---
1328
1329
 
1329
- ## SSR and Static Generation (`sibu/extras`)
1330
+ ## SSR and Static Generation (`sibujs/ssr`)
1330
1331
 
1331
1332
  ### Server-Side Rendering
1332
1333
 
@@ -1336,7 +1337,7 @@ import {
1336
1337
  renderToStream,
1337
1338
  renderToDocument,
1338
1339
  hydrate,
1339
- } from "sibujs/extras";
1340
+ } from "sibujs/ssr";
1340
1341
 
1341
1342
  // Render component to HTML string
1342
1343
  const markup = renderToString(App());
@@ -1361,7 +1362,7 @@ hydrate(App, document.getElementById("root"));
1361
1362
  ### Islands Architecture
1362
1363
 
1363
1364
  ```ts
1364
- import { island, hydrateIslands, hydrateProgressively } from "sibujs/extras";
1365
+ import { island, hydrateIslands, hydrateProgressively } from "sibujs/ssr";
1365
1366
 
1366
1367
  // Server: mark interactive islands
1367
1368
  const header = island("header", () => InteractiveHeader());
@@ -1380,7 +1381,7 @@ hydrateProgressively(document.body, islands, { threshold: 0.1 });
1380
1381
 
1381
1382
  ```ts
1382
1383
  import { html } from "sibujs";
1383
- import { ssrSuspense, renderToSuspenseStream, suspenseSwapScript } from "sibujs/extras";
1384
+ import { ssrSuspense, renderToSuspenseStream, suspenseSwapScript } from "sibujs/ssr";
1384
1385
 
1385
1386
  const boundary = ssrSuspense({
1386
1387
  fallback: () => html`<div>Loading...</div>`,
@@ -1394,7 +1395,7 @@ const stream = renderToSuspenseStream(shell, [boundary.promise]);
1394
1395
  ### Static Site Generation
1395
1396
 
1396
1397
  ```ts
1397
- import { generateStaticSite } from "sibujs/extras";
1398
+ import { generateStaticSite } from "sibujs/ssr";
1398
1399
 
1399
1400
  const result = await generateStaticSite({
1400
1401
  routes: ["/", "/about", "/blog/1", "/blog/2"],
@@ -1408,19 +1409,19 @@ result.errors; // [{ path: "/blog/2", error: Error }]
1408
1409
 
1409
1410
  ---
1410
1411
 
1411
- ## Concurrent Rendering (`sibu/extras`)
1412
+ ## Concurrent Rendering (`sibujs/performance`)
1412
1413
 
1413
1414
  ```ts
1414
1415
  import {
1415
1416
  startTransition,
1416
1417
  deferredValue,
1417
1418
  transitionState,
1418
- id,
1419
+ uniqueId,
1419
1420
  scheduleUpdate,
1420
1421
  yieldToMain,
1421
1422
  processInChunks,
1422
1423
  Priority,
1423
- } from "sibujs/extras";
1424
+ } from "sibujs/performance";
1424
1425
 
1425
1426
  // Non-blocking state updates
1426
1427
  startTransition(() => {
@@ -1434,7 +1435,7 @@ const deferredQuery = deferredValue(() => query());
1434
1435
  const [isPending, startTransition] = transitionState();
1435
1436
 
1436
1437
  // Unique IDs (SSR-safe)
1437
- const id = id(); // "sibu-0"
1438
+ const myId = uniqueId(); // "sibu-0"
1438
1439
  const labelId = uniqueId("label"); // "sibu-1-label"
1439
1440
 
1440
1441
  // Priority-based scheduling
@@ -1450,7 +1451,7 @@ await processInChunks(bigArray, (item) => processItem(item), 50);
1450
1451
 
1451
1452
  ---
1452
1453
 
1453
- ## DevTools (`sibu/extras`)
1454
+ ## DevTools (`sibujs/devtools`)
1454
1455
 
1455
1456
  ### Debugging and Performance
1456
1457
 
@@ -1458,11 +1459,11 @@ await processInChunks(bigArray, (item) => processItem(item), 50);
1458
1459
  import {
1459
1460
  enableDebug,
1460
1461
  debugLog,
1461
- performance,
1462
+ perfTracker,
1462
1463
  measureRender,
1463
1464
  getPerformanceReport,
1464
1465
  checkLeaks,
1465
- } from "sibujs/extras";
1466
+ } from "sibujs/devtools";
1466
1467
 
1467
1468
  enableDebug();
1468
1469
  debugLog("Counter", "increment", { value: 5 });
@@ -1471,7 +1472,7 @@ debugLog("Counter", "increment", { value: 5 });
1471
1472
  const MeasuredList = measureRender("ItemList", ItemList);
1472
1473
 
1473
1474
  // Manual performance tracking
1474
- const perf = performance("search");
1475
+ const perf = perfTracker("search");
1475
1476
  perf.startMeasure();
1476
1477
  // ... expensive operation
1477
1478
  perf.endMeasure();
@@ -1488,7 +1489,7 @@ checkLeaks(); // { "Counter": 2 } -- 2 unclean instances
1488
1489
  ### DevTools Integration
1489
1490
 
1490
1491
  ```ts
1491
- import { initDevTools, devState, getActiveDevTools } from "sibujs/extras";
1492
+ import { initDevTools, devState, getActiveDevTools } from "sibujs/devtools";
1492
1493
 
1493
1494
  const devtools = initDevTools({ maxEvents: 1000 });
1494
1495
 
@@ -1509,7 +1510,7 @@ devtools.snapshot();
1509
1510
  ### Hot Module Replacement
1510
1511
 
1511
1512
  ```ts
1512
- import { hmrState, registerHMR, createHMRBoundary } from "sibujs/extras";
1513
+ import { hmrState, registerHMR, createHMRBoundary } from "sibujs/devtools";
1513
1514
 
1514
1515
  // State that persists across HMR updates
1515
1516
  const [count, setCount] = hmrState("counter", 0);
@@ -1525,12 +1526,12 @@ boundary.accept(() => console.log("Module updated"));
1525
1526
 
1526
1527
  ---
1527
1528
 
1528
- ## Ecosystem Adapters (`sibu/extras`)
1529
+ ## Ecosystem Adapters (`sibujs/ecosystem`)
1529
1530
 
1530
1531
  ### State Management
1531
1532
 
1532
1533
  ```ts
1533
- import { reduxAdapter, zustandAdapter, mobXAdapter } from "sibujs/extras";
1534
+ import { reduxAdapter, zustandAdapter, mobXAdapter } from "sibujs/ecosystem";
1534
1535
 
1535
1536
  // Use Redux store with Sibu reactivity
1536
1537
  const { useSelector, dispatch } = reduxAdapter(reduxStore);
@@ -1546,7 +1547,7 @@ const { useObservable } = mobXAdapter();
1546
1547
  ### UI Framework Integration
1547
1548
 
1548
1549
  ```ts
1549
- import { componentAdapter, createTheme } from "sibujs/extras";
1550
+ import { componentAdapter, createTheme } from "sibujs/ecosystem";
1550
1551
 
1551
1552
  const adapter = componentAdapter();
1552
1553
  const theme = createTheme({ colors: { primary: "#007bff" } });
@@ -1554,7 +1555,7 @@ const theme = createTheme({ colors: { primary: "#007bff" } });
1554
1555
 
1555
1556
  ---
1556
1557
 
1557
- ## Build (`sibu/build`)
1558
+ ## Build (`sibujs/build`)
1558
1559
 
1559
1560
  Bundler plugins and deployment utilities.
1560
1561
 
@@ -1572,7 +1573,7 @@ Additional build utilities: CDN deployment, type declaration generation, bundle
1572
1573
 
1573
1574
  ---
1574
1575
 
1575
- ## Testing (`sibu/testing`)
1576
+ ## Testing (`sibujs/testing`)
1576
1577
 
1577
1578
  Component testing utilities, accessibility testing, E2E helpers, snapshot testing, and visual regression support. Works with Vitest, Jest, and Playwright.
1578
1579
 
@@ -1592,15 +1593,20 @@ unmount();
1592
1593
  Sibu is split into modular entry points. Import only what you use.
1593
1594
 
1594
1595
  ```
1595
- sibujs Core: signal, effect, derived, mount, each, when, html, tags, ErrorBoundary
1596
- sibujs/data Data fetching: query, mutation, infiniteQuery, socket, stream
1597
- sibujs/browser Browser APIs: media, geo, resize, scroll, online, battery, ...
1598
- sibujs/patterns State patterns: machine, persisted, timeline, optimistic, store
1599
- sibujs/motion Transitions: transition, spring, viewTransition, reducedMotion
1600
- sibujs/ui Forms, a11y, dialogs, toasts, virtual lists, composables, web components
1601
- sibujs/plugins Router, i18n
1602
- sibujs/build Vite plugin, Webpack plugin, CDN utilities, template compiler
1603
- sibujs/testing Component testing utilities
1596
+ sibujs Core: signal, effect, derived, mount, each, when, html, tags, ErrorBoundary
1597
+ sibujs/plugins Router, i18n
1598
+ sibujs/data Data fetching: query, mutation, infiniteQuery, socket, stream
1599
+ sibujs/browser Browser APIs: media, geo, resize, scroll, online, battery, ...
1600
+ sibujs/patterns State patterns: machine, persisted, timeline, optimistic, globalStore
1601
+ sibujs/motion Transitions: transition, TransitionGroup, viewTransition, reducedMotion
1602
+ sibujs/ui Forms, a11y, dialogs, toasts, virtual lists, composables, web components
1603
+ sibujs/widgets Headless UI: tabs, select, accordion, combobox, popover, datePicker, ...
1604
+ sibujs/ssr SSR, hydration, islands, static site generation
1605
+ sibujs/performance Concurrent rendering, scheduling, DOM recycling, chunk loading
1606
+ sibujs/devtools Debugging, profiling, HMR, component introspection
1607
+ sibujs/ecosystem Adapters: Redux, MobX, Zustand, Material UI, Chakra, Ant Design
1608
+ sibujs/build Vite plugin, Webpack plugin, template compiler, CDN utilities
1609
+ sibujs/testing Component testing utilities
1604
1610
  ```
1605
1611
 
1606
1612
  The core has zero dependencies beyond TypeScript. Tree shaking works at the module level -- unused subpaths are not included in your bundle.
@@ -1636,4 +1642,4 @@ before submitting a PR.
1636
1642
 
1637
1643
  ## License
1638
1644
 
1639
- MIT -- (c) 2025 [hexplus](https://github.com/hexplus)
1645
+ MIT -- (c) 2025-2026 [hexplus](https://github.com/hexplus)
package/dist/browser.cjs CHANGED
@@ -58,9 +58,12 @@ function track(effectFn, subscriber) {
58
58
  }
59
59
  subscriberStack[stackTop] = subscriber;
60
60
  currentSubscriber = subscriber;
61
- effectFn();
62
- stackTop--;
63
- currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
61
+ try {
62
+ effectFn();
63
+ } finally {
64
+ stackTop--;
65
+ currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
66
+ }
64
67
  return () => cleanup(subscriber);
65
68
  }
66
69
  function suspendTracking() {