sibujs 4.0.1 → 4.1.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 (55) hide show
  1. package/README.md +5 -1
  2. package/dist/browser.cjs +9 -2
  3. package/dist/browser.js +4 -4
  4. package/dist/build.cjs +86 -7
  5. package/dist/build.js +10 -10
  6. package/dist/cdn.global.js +10 -10
  7. package/dist/{chunk-52ERIVFD.js → chunk-4RH6D7GR.js} +3 -3
  8. package/dist/{chunk-YLV26GAJ.js → chunk-4U7KD3RY.js} +3 -3
  9. package/dist/{chunk-XET2RUJF.js → chunk-5GJ5RTHA.js} +1 -1
  10. package/dist/{chunk-PJDSI2K7.js → chunk-ANGSYNPX.js} +77 -14
  11. package/dist/{chunk-XZMCVZW6.js → chunk-BMSN6NWQ.js} +3 -3
  12. package/dist/{chunk-JYXQCELN.js → chunk-D3SZ4LVS.js} +9 -2
  13. package/dist/{chunk-IKVUUE7D.js → chunk-DAKLOMKS.js} +2 -2
  14. package/dist/{chunk-AD5YSZAN.js → chunk-DCDS2PQ6.js} +1 -1
  15. package/dist/{chunk-5BVKQX2F.js → chunk-FB7KQXZI.js} +4 -4
  16. package/dist/{chunk-J4WZMCIW.js → chunk-FMHIQNMP.js} +4 -4
  17. package/dist/{chunk-QD4I7ZGZ.js → chunk-I3VI34DP.js} +2 -2
  18. package/dist/{chunk-UNAYBND2.js → chunk-IM7N5WR4.js} +1 -1
  19. package/dist/{chunk-PTLJ7NQX.js → chunk-KSOEJGFO.js} +1 -1
  20. package/dist/{chunk-PHB3MCK4.js → chunk-LOFZHP6V.js} +2 -2
  21. package/dist/{chunk-E72G5JSK.js → chunk-MRAMKDHQ.js} +1 -1
  22. package/dist/{chunk-XDOMTQHM.js → chunk-PFTDGEPZ.js} +1 -1
  23. package/dist/{chunk-PHRH66Y7.js → chunk-SHDVWATN.js} +1 -1
  24. package/dist/{chunk-TVURNWDK.js → chunk-UFSQEO7P.js} +14 -2
  25. package/dist/{chunk-TNEHT3NG.js → chunk-XIHMS2Y6.js} +5 -5
  26. package/dist/{chunk-HPXTUPJD.js → chunk-XSZRJW76.js} +4 -4
  27. package/dist/data.cjs +9 -2
  28. package/dist/data.js +6 -6
  29. package/dist/devtools.cjs +9 -2
  30. package/dist/devtools.js +4 -4
  31. package/dist/ecosystem.cjs +9 -2
  32. package/dist/ecosystem.js +7 -7
  33. package/dist/extras.cjs +9 -2
  34. package/dist/extras.js +19 -19
  35. package/dist/index.cjs +87 -7
  36. package/dist/index.d.cts +133 -1
  37. package/dist/index.d.ts +133 -1
  38. package/dist/index.js +12 -10
  39. package/dist/motion.cjs +9 -2
  40. package/dist/motion.js +3 -3
  41. package/dist/patterns.cjs +9 -2
  42. package/dist/patterns.js +5 -5
  43. package/dist/performance.cjs +9 -2
  44. package/dist/performance.js +4 -4
  45. package/dist/plugins.cjs +9 -2
  46. package/dist/plugins.js +6 -6
  47. package/dist/ssr.cjs +9 -2
  48. package/dist/ssr.js +7 -7
  49. package/dist/testing.cjs +9 -2
  50. package/dist/testing.js +2 -2
  51. package/dist/ui.cjs +9 -2
  52. package/dist/ui.js +6 -6
  53. package/dist/widgets.cjs +9 -2
  54. package/dist/widgets.js +6 -6
  55. package/package.json +7 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SibuJS
2
2
 
3
- A lightweight, function-based frontend framework with fine-grained reactivity, direct DOM rendering, and zero compilation. **No Virtual DOM. No magic.**
3
+ A function-based frontend framework with fine-grained reactivity, direct DOM rendering, and zero compilation. **No Virtual DOM. No magic.**
4
4
 
5
5
  [NPM](https://www.npmjs.com/package/sibujs) · [License](https://github.com/hexplus/sibujs/blob/main/LICENSE)
6
6
 
@@ -147,6 +147,10 @@ The lean core: reactivity, rendering, and components. Everything below imports f
147
147
  ### Islands & Progressive Enhancement
148
148
  - **`enhance` / `enhanceAll`** — attach fine-grained reactivity to existing server-rendered HTML with no build step (the third rendering mode alongside `mount` and `hydrate`).
149
149
  - **`island` / `registerIsland` / `hydrateIslands`** — hydrate isolated interactive regions on demand.
150
+ - **`ctx.each`** — bind many elements the server already rendered (a board, a table, a keyboard) from one descriptor, with no new DOM.
151
+ - **`external`** — reactive integration with state SibuJS does not own: a domain engine, a canvas, an editor, a socket cache. `track()` where you read, `invalidate()` where you mutate.
152
+
153
+ Guides: [islands & progressive enhancement](docs/islands.md) · [external mutable state and update granularity](docs/architecture/external-state.md) · [running islands inside another framework's page](docs/interop.md). Reference application: [`examples/chess/`](examples/chess/).
150
154
 
151
155
  ---
152
156
 
package/dist/browser.cjs CHANGED
@@ -387,7 +387,14 @@ function reactiveBinding(commit, ownerNode) {
387
387
  subscriber._disposed = false;
388
388
  subscriber._errorPhase = "binding";
389
389
  subscriber._errorNode = ownerNode;
390
- run();
390
+ try {
391
+ run();
392
+ } catch (err) {
393
+ subscriber._disposed = true;
394
+ subscriber._errorNode = void 0;
395
+ cleanup(subscriber);
396
+ throw err;
397
+ }
391
398
  return subscriber._dispose ?? (subscriber._dispose = () => {
392
399
  subscriber._disposed = true;
393
400
  subscriber._errorNode = void 0;
@@ -619,7 +626,7 @@ function forEachSubscriber(signal2, visit) {
619
626
 
620
627
  // src/reactivity/track.ts
621
628
  var _isDev2 = isDev();
622
- var _runtimeVersion = true ? "4.0.1" : "dev";
629
+ var _runtimeVersion = true ? "4.1.0" : "dev";
623
630
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
624
631
  function resolveReactiveApi() {
625
632
  const g = globalThis;
package/dist/browser.js CHANGED
@@ -35,14 +35,14 @@ import {
35
35
  visibility,
36
36
  wakeLock,
37
37
  windowSize
38
- } from "./chunk-IKVUUE7D.js";
38
+ } from "./chunk-DAKLOMKS.js";
39
39
  import "./chunk-H3SRKIYX.js";
40
40
  import "./chunk-52XFPGSN.js";
41
41
  import "./chunk-7ZHH77QA.js";
42
- import "./chunk-XDOMTQHM.js";
42
+ import "./chunk-PFTDGEPZ.js";
43
43
  import "./chunk-TIRZCERI.js";
44
- import "./chunk-TVURNWDK.js";
45
- import "./chunk-JYXQCELN.js";
44
+ import "./chunk-UFSQEO7P.js";
45
+ import "./chunk-D3SZ4LVS.js";
46
46
  import "./chunk-VPP2FONR.js";
47
47
  export {
48
48
  animationFrame,
package/dist/build.cjs CHANGED
@@ -1132,6 +1132,7 @@ __export(index_exports, {
1132
1132
  enhance: () => enhance,
1133
1133
  enhanceAll: () => enhanceAll,
1134
1134
  enqueueBatchedSignal: () => enqueueBatchedSignal,
1135
+ external: () => external,
1135
1136
  fieldset: () => fieldset,
1136
1137
  figcaption: () => figcaption,
1137
1138
  figure: () => figure,
@@ -1945,7 +1946,14 @@ function reactiveBinding(commit, ownerNode) {
1945
1946
  subscriber._disposed = false;
1946
1947
  subscriber._errorPhase = "binding";
1947
1948
  subscriber._errorNode = ownerNode;
1948
- run();
1949
+ try {
1950
+ run();
1951
+ } catch (err) {
1952
+ subscriber._disposed = true;
1953
+ subscriber._errorNode = void 0;
1954
+ cleanup(subscriber);
1955
+ throw err;
1956
+ }
1949
1957
  return subscriber._dispose ?? (subscriber._dispose = () => {
1950
1958
  subscriber._disposed = true;
1951
1959
  subscriber._errorNode = void 0;
@@ -2177,7 +2185,7 @@ function forEachSubscriber(signal2, visit) {
2177
2185
 
2178
2186
  // src/reactivity/track.ts
2179
2187
  var _isDev4 = isDev();
2180
- var _runtimeVersion = true ? "4.0.1" : "dev";
2188
+ var _runtimeVersion = true ? "4.1.0" : "dev";
2181
2189
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
2182
2190
  function resolveReactiveApi() {
2183
2191
  const g2 = globalThis;
@@ -3432,6 +3440,17 @@ function signal(initial, options) {
3432
3440
  }
3433
3441
  return [get, set];
3434
3442
  }
3443
+ function external(options) {
3444
+ const [version, bump] = signal(0, options?.name ? { name: options.name } : void 0);
3445
+ return {
3446
+ track() {
3447
+ version();
3448
+ },
3449
+ invalidate() {
3450
+ bump((n) => n + 1);
3451
+ }
3452
+ };
3453
+ }
3435
3454
 
3436
3455
  // src/components/ErrorDisplay.ts
3437
3456
  var STYLES = `
@@ -5996,6 +6015,7 @@ function drainTeardowns(teardowns, label2) {
5996
6015
  }
5997
6016
  }
5998
6017
  }
6018
+ var EACH_KEYS = ["text", "attr", "class", "show", "on", "cleanup"];
5999
6019
  function resolveTarget(root, target) {
6000
6020
  if (target == null) return root;
6001
6021
  if (typeof target !== "string") return target;
@@ -6006,6 +6026,11 @@ function resolveTarget(root, target) {
6006
6026
  return null;
6007
6027
  }
6008
6028
  }
6029
+ function bindNode(el, commit) {
6030
+ if (isSSR()) return () => {
6031
+ };
6032
+ return reactiveBinding2(commit, el);
6033
+ }
6009
6034
  function readControlValue(el) {
6010
6035
  if (el instanceof HTMLInputElement) {
6011
6036
  if (el.type === "checkbox") return el.checked;
@@ -6029,6 +6054,50 @@ function writeControlValue(el, value) {
6029
6054
  const next = value == null ? "" : String(value);
6030
6055
  if (el.value !== next) el.value = next;
6031
6056
  }
6057
+ function applyEachBindings(ctx, el, spec, index) {
6058
+ const where = `ctx.each[${index}]`;
6059
+ if (isDev()) {
6060
+ for (const key of Object.keys(spec)) {
6061
+ devAssert(
6062
+ EACH_KEYS.includes(key),
6063
+ `${where}: unknown binding "${key}". Expected one of: ${EACH_KEYS.join(", ")}.`
6064
+ );
6065
+ }
6066
+ }
6067
+ if (spec.text !== void 0) {
6068
+ devAssert(typeof spec.text === "function", `${where}: "text" must be a function returning the value.`);
6069
+ ctx.text(el, spec.text);
6070
+ }
6071
+ if (spec.attr !== void 0) {
6072
+ for (const name of Object.keys(spec.attr)) {
6073
+ const value = spec.attr[name];
6074
+ devAssert(typeof value === "function", `${where}: attr["${name}"] must be a function returning the value.`);
6075
+ ctx.attr(el, name, value);
6076
+ }
6077
+ }
6078
+ if (spec.class !== void 0) {
6079
+ for (const name of Object.keys(spec.class)) {
6080
+ const on2 = spec.class[name];
6081
+ devAssert(typeof on2 === "function", `${where}: class["${name}"] must be a function returning a boolean.`);
6082
+ ctx.classed(el, name, on2);
6083
+ }
6084
+ }
6085
+ if (spec.show !== void 0) {
6086
+ devAssert(typeof spec.show === "function", `${where}: "show" must be a function returning a boolean.`);
6087
+ ctx.show(el, spec.show);
6088
+ }
6089
+ if (spec.on !== void 0) {
6090
+ for (const event of Object.keys(spec.on)) {
6091
+ const handler = spec.on[event];
6092
+ devAssert(typeof handler === "function", `${where}: on["${String(event)}"] must be a function.`);
6093
+ ctx.on(el, event, handler);
6094
+ }
6095
+ }
6096
+ if (spec.cleanup !== void 0) {
6097
+ devAssert(typeof spec.cleanup === "function", `${where}: "cleanup" must be a function.`);
6098
+ ctx.cleanup(spec.cleanup);
6099
+ }
6100
+ }
6032
6101
  function enhance(target, setup) {
6033
6102
  const root = typeof target === "string" ? typeof document !== "undefined" ? document.querySelector(target) : null : target;
6034
6103
  if (!root) {
@@ -6079,7 +6148,7 @@ function enhance(target, setup) {
6079
6148
  text: (t, value) => {
6080
6149
  bind(t, (el) => {
6081
6150
  teardowns.push(
6082
- effect(() => {
6151
+ bindNode(el, () => {
6083
6152
  const v = value();
6084
6153
  const next = v == null ? "" : String(v);
6085
6154
  if (el.textContent !== next) el.textContent = next;
@@ -6090,7 +6159,7 @@ function enhance(target, setup) {
6090
6159
  attr: (t, name, value) => {
6091
6160
  bind(t, (el) => {
6092
6161
  teardowns.push(
6093
- effect(() => {
6162
+ bindNode(el, () => {
6094
6163
  const v = value();
6095
6164
  const next = v == null ? null : String(v);
6096
6165
  setSafeAttribute(el, name, next, { syncValueProperty: false, label: "enhance attr()" });
@@ -6101,7 +6170,7 @@ function enhance(target, setup) {
6101
6170
  classed: (t, name, on2) => {
6102
6171
  bind(t, (el) => {
6103
6172
  teardowns.push(
6104
- effect(() => {
6173
+ bindNode(el, () => {
6105
6174
  el.classList.toggle(name, Boolean(on2()));
6106
6175
  })
6107
6176
  );
@@ -6111,7 +6180,7 @@ function enhance(target, setup) {
6111
6180
  bind(t, (el) => {
6112
6181
  const prevHidden = el.hidden;
6113
6182
  teardowns.push(
6114
- effect(() => {
6183
+ bindNode(el, () => {
6115
6184
  el.hidden = !when2();
6116
6185
  })
6117
6186
  );
@@ -6126,7 +6195,7 @@ function enhance(target, setup) {
6126
6195
  const [get, set] = state2;
6127
6196
  const evt = options?.event ?? (control instanceof HTMLSelectElement || control instanceof HTMLInputElement && (control.type === "checkbox" || control.type === "radio") ? "change" : "input");
6128
6197
  teardowns.push(
6129
- effect(() => {
6198
+ bindNode(el, () => {
6130
6199
  writeControlValue(control, get());
6131
6200
  })
6132
6201
  );
@@ -6135,6 +6204,16 @@ function enhance(target, setup) {
6135
6204
  teardowns.push(() => control.removeEventListener(evt, onInput));
6136
6205
  });
6137
6206
  },
6207
+ each: (target_, describe2) => {
6208
+ devAssert(typeof describe2 === "function", "ctx.each: second argument must be a function.");
6209
+ const elements = typeof target_ === "string" ? ctx.refs(target_) : Array.from(target_);
6210
+ for (let i2 = 0; i2 < elements.length; i2++) {
6211
+ const el = elements[i2];
6212
+ const spec = describe2(el, i2);
6213
+ if (spec == null) continue;
6214
+ applyEachBindings(ctx, el, spec, i2);
6215
+ }
6216
+ },
6138
6217
  cleanup: (fn) => {
6139
6218
  teardowns.push(fn);
6140
6219
  }
package/dist/build.js CHANGED
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  index_exports
3
- } from "./chunk-PJDSI2K7.js";
4
- import "./chunk-E72G5JSK.js";
3
+ } from "./chunk-ANGSYNPX.js";
4
+ import "./chunk-MRAMKDHQ.js";
5
5
  import "./chunk-HYCCIYNS.js";
6
- import "./chunk-PTLJ7NQX.js";
6
+ import "./chunk-KSOEJGFO.js";
7
7
  import "./chunk-CCSJMTRN.js";
8
- import "./chunk-XET2RUJF.js";
9
- import "./chunk-QD4I7ZGZ.js";
10
- import "./chunk-PHRH66Y7.js";
11
- import "./chunk-AD5YSZAN.js";
8
+ import "./chunk-5GJ5RTHA.js";
9
+ import "./chunk-I3VI34DP.js";
10
+ import "./chunk-SHDVWATN.js";
11
+ import "./chunk-DCDS2PQ6.js";
12
12
  import "./chunk-5INI7D2L.js";
13
13
  import "./chunk-7ZHH77QA.js";
14
- import "./chunk-XDOMTQHM.js";
14
+ import "./chunk-PFTDGEPZ.js";
15
15
  import "./chunk-TIRZCERI.js";
16
16
  import "./chunk-DHDZ7IVN.js";
17
- import "./chunk-TVURNWDK.js";
18
- import "./chunk-JYXQCELN.js";
17
+ import "./chunk-UFSQEO7P.js";
18
+ import "./chunk-D3SZ4LVS.js";
19
19
  import "./chunk-VPP2FONR.js";
20
20
 
21
21
  // src/build/compileTemplates.ts