sibujs 4.7.0 → 4.8.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 (81) hide show
  1. package/dist/browser.cjs +45 -4
  2. package/dist/browser.d.cts +23 -0
  3. package/dist/browser.d.ts +23 -0
  4. package/dist/browser.js +6 -5
  5. package/dist/build.cjs +513 -78
  6. package/dist/build.d.cts +22 -8
  7. package/dist/build.d.ts +22 -8
  8. package/dist/build.js +68 -21
  9. package/dist/cdn.dev.global.js +15 -13
  10. package/dist/cdn.full.dev.global.js +15 -13
  11. package/dist/cdn.full.global.js +14 -12
  12. package/dist/cdn.global.js +14 -12
  13. package/dist/chunk-3ACAAQIN.js +224 -0
  14. package/dist/{chunk-DKXRACVN.js → chunk-44MTL7ED.js} +6 -6
  15. package/dist/{chunk-3QWBSL5R.js → chunk-4WMSTZ7J.js} +8 -5
  16. package/dist/{chunk-H3SRKIYX.js → chunk-62BDYGAG.js} +8 -0
  17. package/dist/{chunk-BSY63EM6.js → chunk-C5PEWEGH.js} +20 -5
  18. package/dist/{chunk-BC2SECJD.js → chunk-C7AA2CZX.js} +1 -1
  19. package/dist/{chunk-SLM3IA34.js → chunk-CZPRSWSS.js} +1 -1
  20. package/dist/{chunk-FQRUXCEE.js → chunk-DSID757X.js} +1 -1
  21. package/dist/{chunk-ZVL7TY4K.js → chunk-EGUQLBHE.js} +22 -8
  22. package/dist/{chunk-2INLLLMZ.js → chunk-EXXSN3BW.js} +202 -26
  23. package/dist/{chunk-HURREPU2.js → chunk-FC6KCJSA.js} +87 -150
  24. package/dist/{chunk-Z3OHK6QT.js → chunk-GSGNX35Q.js} +5 -5
  25. package/dist/{chunk-XYV3EDB7.js → chunk-J3YQ457H.js} +37 -20
  26. package/dist/{chunk-VZSG24LS.js → chunk-JUTFX2RM.js} +18 -10
  27. package/dist/{chunk-RUSSKG6G.js → chunk-KJ3UKABJ.js} +1 -1
  28. package/dist/{chunk-UNWRJRKC.js → chunk-LI4W3U6C.js} +1 -1
  29. package/dist/{chunk-FNJXNGYZ.js → chunk-O6TRVMJI.js} +58 -6
  30. package/dist/{chunk-7LUJQAOJ.js → chunk-Q5J2LVKH.js} +1 -1
  31. package/dist/{chunk-4AWA2PVD.js → chunk-QGMSESDD.js} +10 -5
  32. package/dist/{chunk-XZR4PXRE.js → chunk-RGLPEBDE.js} +13 -10
  33. package/dist/{chunk-JWKYU5GV.js → chunk-TQQUN4WR.js} +1 -1
  34. package/dist/{chunk-WOLJZUFQ.js → chunk-UCNP3HVM.js} +12 -8
  35. package/dist/{chunk-WEQ3DMVL.js → chunk-V3LHZSU5.js} +1 -1
  36. package/dist/{chunk-UOL2ECCS.js → chunk-VWT3VXPL.js} +18 -12
  37. package/dist/{chunk-2BPG2XDA.js → chunk-ZVLHNEEL.js} +17 -35
  38. package/dist/{customElement-MmInOW1U.d.ts → customElement-pYDKUzWl.d.cts} +11 -3
  39. package/dist/{customElement-MmInOW1U.d.cts → customElement-pYDKUzWl.d.ts} +11 -3
  40. package/dist/data.cjs +9 -2
  41. package/dist/data.js +6 -6
  42. package/dist/devtools.cjs +1 -1
  43. package/dist/devtools.js +5 -5
  44. package/dist/ecosystem.cjs +400 -37
  45. package/dist/ecosystem.js +9 -8
  46. package/dist/extras.cjs +621 -252
  47. package/dist/extras.d.cts +2 -2
  48. package/dist/extras.d.ts +2 -2
  49. package/dist/extras.js +24 -23
  50. package/dist/index.cjs +464 -70
  51. package/dist/index.d.cts +28 -2
  52. package/dist/index.d.ts +28 -2
  53. package/dist/index.js +16 -12
  54. package/dist/motion.cjs +1 -1
  55. package/dist/motion.js +3 -3
  56. package/dist/patterns.cjs +10 -7
  57. package/dist/patterns.js +6 -6
  58. package/dist/performance.cjs +31 -2
  59. package/dist/performance.d.cts +12 -2
  60. package/dist/performance.d.ts +12 -2
  61. package/dist/performance.js +8 -6
  62. package/dist/plugins.cjs +558 -231
  63. package/dist/plugins.d.cts +8 -3
  64. package/dist/plugins.d.ts +8 -3
  65. package/dist/plugins.js +22 -28
  66. package/dist/{ssr-XOTUASDO.js → ssr-5OWAH3U2.js} +4 -2
  67. package/dist/{ssr-Bli9XRW5.d.ts → ssr-C8hgIAw7.d.cts} +6 -0
  68. package/dist/{ssr-Bli9XRW5.d.cts → ssr-C8hgIAw7.d.ts} +6 -0
  69. package/dist/ssr.cjs +457 -131
  70. package/dist/ssr.d.cts +55 -5
  71. package/dist/ssr.d.ts +55 -5
  72. package/dist/ssr.js +11 -9
  73. package/dist/testing.cjs +3 -3
  74. package/dist/testing.js +4 -4
  75. package/dist/ui.cjs +608 -240
  76. package/dist/ui.d.cts +1 -1
  77. package/dist/ui.d.ts +1 -1
  78. package/dist/ui.js +9 -8
  79. package/dist/widgets.cjs +1 -1
  80. package/dist/widgets.js +7 -7
  81. package/package.json +5 -4
package/dist/browser.cjs CHANGED
@@ -674,7 +674,7 @@ function forEachSubscriber(signal2, visit) {
674
674
  }
675
675
 
676
676
  // src/reactivity/track.ts
677
- var _runtimeVersion = true ? "4.7.0" : "dev";
677
+ var _runtimeVersion = true ? "4.8.0" : "dev";
678
678
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
679
679
  function resolveReactiveApi() {
680
680
  const g = globalThis;
@@ -1658,13 +1658,19 @@ function colorScheme() {
1658
1658
  }
1659
1659
 
1660
1660
  // src/browser/format.ts
1661
+ var I18N_STATE = /* @__PURE__ */ Symbol.for("sibujs.i18n.v1");
1662
+ function activeI18nLocale() {
1663
+ const state2 = globalThis[I18N_STATE];
1664
+ if (!state2) return void 0;
1665
+ return state2.getLocale ? state2.getLocale() : state2.locale?.[0]();
1666
+ }
1661
1667
  function formatNumber(value, options) {
1662
1668
  const { locale, ...formatOptions } = options ?? {};
1663
- return new Intl.NumberFormat(locale, formatOptions).format(value);
1669
+ return new Intl.NumberFormat(locale ?? activeI18nLocale(), formatOptions).format(value);
1664
1670
  }
1665
1671
  function formatCurrency(value, currency, options) {
1666
1672
  const { locale, ...formatOptions } = options ?? {};
1667
- return new Intl.NumberFormat(locale, {
1673
+ return new Intl.NumberFormat(locale ?? activeI18nLocale(), {
1668
1674
  ...formatOptions,
1669
1675
  style: "currency",
1670
1676
  currency
@@ -2592,6 +2598,36 @@ function textSelection() {
2592
2598
  };
2593
2599
  }
2594
2600
 
2601
+ // src/utils/sanitize.ts
2602
+ function stripControlChars(value) {
2603
+ return value.replace(/[\x00-\x20\x7f-\x9f]+/g, "");
2604
+ }
2605
+ var SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
2606
+ var OUTER_TRIM = /^[\x00-\x20\x7f-\x9f]+|[\x00-\x20\x7f-\x9f]+$/g;
2607
+ function sanitizeUrl(url) {
2608
+ const probe = stripControlChars(url).trim();
2609
+ if (!probe) return "";
2610
+ const output = url.replace(OUTER_TRIM, "");
2611
+ if (probe.length >= 2 && (probe[0] === "\\" || probe[0] === "/") && (probe[1] === "\\" || probe[1] === "/") && (probe[0] === "\\" || probe[1] === "\\")) {
2612
+ return "";
2613
+ }
2614
+ const lower = probe.toLowerCase();
2615
+ let schemeEnd = -1;
2616
+ for (let i = 0; i < lower.length; i++) {
2617
+ const ch = lower.charCodeAt(i);
2618
+ if (ch === 58) {
2619
+ schemeEnd = i;
2620
+ break;
2621
+ }
2622
+ if (ch === 47 || ch === 63 || ch === 35) break;
2623
+ }
2624
+ if (schemeEnd === -1) return output;
2625
+ const scheme = lower.slice(0, schemeEnd + 1);
2626
+ if (!/^[a-z][a-z0-9+.-]*:$/.test(scheme)) return output;
2627
+ if (SAFE_URL_PROTOCOLS.indexOf(scheme) === -1) return "";
2628
+ return output;
2629
+ }
2630
+
2595
2631
  // src/browser/imageLoader.ts
2596
2632
  function imageLoader(src) {
2597
2633
  const [status, setStatus] = signal("pending");
@@ -2633,6 +2669,11 @@ function imageLoader(src) {
2633
2669
  abandonCurrent();
2634
2670
  resetState();
2635
2671
  if (disposed || token !== startToken) return;
2672
+ const safe = sanitizeUrl(String(url));
2673
+ if (!safe) {
2674
+ setStatus("error");
2675
+ return;
2676
+ }
2636
2677
  const img = new Image();
2637
2678
  current = img;
2638
2679
  currentSettled = false;
@@ -2651,7 +2692,7 @@ function imageLoader(src) {
2651
2692
  currentSettled = true;
2652
2693
  setStatus("error");
2653
2694
  };
2654
- img.src = url;
2695
+ img.src = safe;
2655
2696
  }
2656
2697
  let srcEffectTeardown = null;
2657
2698
  if (typeof src === "function") {
@@ -198,6 +198,18 @@ declare function colorScheme(): {
198
198
  /**
199
199
  * Locale-aware number and currency formatting using Intl.NumberFormat.
200
200
  *
201
+ * LOCALE. An explicit `locale` option always wins. Without one, the active i18n
202
+ * locale is used when the i18n plugin is loaded (`setLocale()` / `getLocale()`),
203
+ * and the runtime's default locale otherwise. The i18n read is reactive, so a
204
+ * formatter called inside a binding re-formats in place when the locale
205
+ * switches:
206
+ *
207
+ * ```ts
208
+ * span(() => formatCurrency(price(), "EUR")); // follows setLocale("es")
209
+ * ```
210
+ *
211
+ * On the server the read is request-scoped, exactly as `getLocale()` is.
212
+ *
201
213
  * @example
202
214
  * ```ts
203
215
  * formatNumber(1234567.89); // "1,234,567.89" (locale-dependent)
@@ -792,6 +804,13 @@ declare function vibrate(pattern: number | number[]): boolean;
792
804
  * Ensures a `<link rel="icon">` exists — creates one if missing, updates
793
805
  * the `href` otherwise.
794
806
  *
807
+ * NOT routed through the canonical URL allowlist, deliberately: `data:` icons
808
+ * are this helper's purpose (see `svgFavicon`), and the allowlist refuses
809
+ * `data:`. That is safe here because an icon link only ever fetches an image —
810
+ * the browser never navigates to, executes or renders it as a document, so no
811
+ * scheme turns this sink into script. Do not copy this exception to any sink
812
+ * that navigates, executes or embeds.
813
+ *
795
814
  * @param url Favicon URL or `data:` URI
796
815
  *
797
816
  * @example
@@ -874,6 +893,10 @@ interface ImageLoaderState {
874
893
  * and its value changes, the previous load is abandoned and a new one
875
894
  * starts.
876
895
  *
896
+ * The URL passes the framework's canonical URL policy first (`http:`,
897
+ * `https:`, relative, …). A refused URL — `javascript:`, `data:`, `blob:`, … —
898
+ * requests nothing and reports `status() === "error"`.
899
+ *
877
900
  * @example
878
901
  * ```ts
879
902
  * const img = imageLoader("/hero.jpg");
package/dist/browser.d.ts CHANGED
@@ -198,6 +198,18 @@ declare function colorScheme(): {
198
198
  /**
199
199
  * Locale-aware number and currency formatting using Intl.NumberFormat.
200
200
  *
201
+ * LOCALE. An explicit `locale` option always wins. Without one, the active i18n
202
+ * locale is used when the i18n plugin is loaded (`setLocale()` / `getLocale()`),
203
+ * and the runtime's default locale otherwise. The i18n read is reactive, so a
204
+ * formatter called inside a binding re-formats in place when the locale
205
+ * switches:
206
+ *
207
+ * ```ts
208
+ * span(() => formatCurrency(price(), "EUR")); // follows setLocale("es")
209
+ * ```
210
+ *
211
+ * On the server the read is request-scoped, exactly as `getLocale()` is.
212
+ *
201
213
  * @example
202
214
  * ```ts
203
215
  * formatNumber(1234567.89); // "1,234,567.89" (locale-dependent)
@@ -792,6 +804,13 @@ declare function vibrate(pattern: number | number[]): boolean;
792
804
  * Ensures a `<link rel="icon">` exists — creates one if missing, updates
793
805
  * the `href` otherwise.
794
806
  *
807
+ * NOT routed through the canonical URL allowlist, deliberately: `data:` icons
808
+ * are this helper's purpose (see `svgFavicon`), and the allowlist refuses
809
+ * `data:`. That is safe here because an icon link only ever fetches an image —
810
+ * the browser never navigates to, executes or renders it as a document, so no
811
+ * scheme turns this sink into script. Do not copy this exception to any sink
812
+ * that navigates, executes or embeds.
813
+ *
795
814
  * @param url Favicon URL or `data:` URI
796
815
  *
797
816
  * @example
@@ -874,6 +893,10 @@ interface ImageLoaderState {
874
893
  * and its value changes, the previous load is abandoned and a new one
875
894
  * starts.
876
895
  *
896
+ * The URL passes the framework's canonical URL policy first (`http:`,
897
+ * `https:`, relative, …). A refused URL — `javascript:`, `data:`, `blob:`, … —
898
+ * requests nothing and reports `status() === "error"`.
899
+ *
877
900
  * @example
878
901
  * ```ts
879
902
  * const img = imageLoader("/hero.jpg");
package/dist/browser.js CHANGED
@@ -36,14 +36,15 @@ import {
36
36
  visibility,
37
37
  wakeLock,
38
38
  windowSize
39
- } from "./chunk-ZVL7TY4K.js";
40
- import "./chunk-H3SRKIYX.js";
39
+ } from "./chunk-EGUQLBHE.js";
41
40
  import "./chunk-52XFPGSN.js";
41
+ import "./chunk-62BDYGAG.js";
42
42
  import "./chunk-7ZHH77QA.js";
43
- import "./chunk-WEQ3DMVL.js";
43
+ import "./chunk-V3LHZSU5.js";
44
+ import "./chunk-EXXSN3BW.js";
44
45
  import "./chunk-7XHATCIH.js";
45
- import "./chunk-FQRUXCEE.js";
46
- import "./chunk-JWKYU5GV.js";
46
+ import "./chunk-DSID757X.js";
47
+ import "./chunk-TQQUN4WR.js";
47
48
  import "./chunk-NYNYSPK7.js";
48
49
  export {
49
50
  __resetSpeechCoordinator,