sibujs 1.5.0 → 2.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.
- package/dist/browser.cjs +332 -121
- package/dist/browser.d.cts +5 -0
- package/dist/browser.d.ts +5 -0
- package/dist/browser.js +6 -6
- package/dist/build.cjs +1049 -344
- package/dist/build.js +15 -13
- package/dist/cdn.global.js +17 -16
- package/dist/chunk-2RA7SHDA.js +65 -0
- package/dist/chunk-2UPRY23K.js +80 -0
- package/dist/{chunk-BMPL52BF.js → chunk-3DZP6OIT.js} +118 -66
- package/dist/chunk-3JHCYHWN.js +125 -0
- package/dist/{chunk-CZUGLNJS.js → chunk-45YP72ZQ.js} +3 -3
- package/dist/{chunk-JCDUJN2F.js → chunk-AMK2TYNW.js} +490 -153
- package/dist/{chunk-NHUC2QWH.js → chunk-CWBVQML6.js} +1 -1
- package/dist/{chunk-XHK6BDAJ.js → chunk-DRUZZAK4.js} +25 -8
- package/dist/{chunk-RJ46C3CS.js → chunk-GWWURC5M.js} +71 -20
- package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
- package/dist/{chunk-2BYQDGN3.js → chunk-KGYT6UO6.js} +234 -63
- package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
- package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
- package/dist/{chunk-XUEEGU5O.js → chunk-NASX6ST2.js} +16 -4
- package/dist/{chunk-VQDZK23A.js → chunk-O6EFQ3KT.js} +181 -66
- package/dist/{chunk-BGN5ZMP4.js → chunk-OJ3P4ECI.js} +14 -2
- package/dist/chunk-ON5MMR2J.js +1327 -0
- package/dist/{chunk-SFKNRVCU.js → chunk-P2HSJDDN.js} +135 -79
- package/dist/chunk-QO3WC6FS.js +384 -0
- package/dist/{chunk-WZSPOOER.js → chunk-RDTDJCAB.js} +8 -5
- package/dist/{chunk-7GRNSCFT.js → chunk-TH2ILCYW.js} +312 -185
- package/dist/chunk-UCS6AMJ7.js +79 -0
- package/dist/{chunk-VAPYJN4X.js → chunk-V6C4FADE.js} +93 -23
- package/dist/{chunk-OUZZEE4S.js → chunk-WANSMF2L.js} +17 -11
- package/dist/{chunk-23VV7YD3.js → chunk-WIPZPFBQ.js} +25 -30
- package/dist/chunk-WZA53FXU.js +149 -0
- package/dist/{chunk-BGTHZHJ5.js → chunk-ZAQSMOED.js} +188 -44
- package/dist/{customElement-BL3Uo8dL.d.cts → customElement-CPfIrbvg.d.cts} +14 -10
- package/dist/{customElement-BL3Uo8dL.d.ts → customElement-CPfIrbvg.d.ts} +14 -10
- package/dist/data.cjs +536 -151
- package/dist/data.d.cts +20 -2
- package/dist/data.d.ts +20 -2
- package/dist/data.js +11 -9
- package/dist/devtools.cjs +613 -266
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +12 -6
- package/dist/ecosystem.cjs +602 -197
- package/dist/ecosystem.d.cts +9 -7
- package/dist/ecosystem.d.ts +9 -7
- package/dist/ecosystem.js +12 -11
- package/dist/extras.cjs +3500 -1608
- package/dist/extras.d.cts +9 -9
- package/dist/extras.d.ts +9 -9
- package/dist/extras.js +58 -45
- package/dist/index.cjs +1055 -344
- package/dist/index.d.cts +85 -8
- package/dist/index.d.ts +85 -8
- package/dist/index.js +32 -16
- package/dist/{introspect-BumjnBKr.d.cts → introspect-2TOlQ7oa.d.cts} +25 -3
- package/dist/{introspect-CZrlcaYy.d.ts → introspect-DnIpHQQz.d.ts} +25 -3
- package/dist/motion.cjs +122 -63
- package/dist/motion.js +4 -4
- package/dist/patterns.cjs +450 -110
- package/dist/patterns.d.cts +11 -12
- package/dist/patterns.d.ts +11 -12
- package/dist/patterns.js +7 -7
- package/dist/performance.cjs +373 -149
- package/dist/performance.d.cts +23 -16
- package/dist/performance.d.ts +23 -16
- package/dist/performance.js +13 -8
- package/dist/plugin-D30wlGW5.d.cts +71 -0
- package/dist/plugin-D30wlGW5.d.ts +71 -0
- package/dist/plugins.cjs +729 -301
- package/dist/plugins.d.cts +10 -3
- package/dist/plugins.d.ts +10 -3
- package/dist/plugins.js +106 -38
- package/dist/{ssr-Do_SiVoL.d.cts → ssr-CrVNy6Pa.d.cts} +9 -15
- package/dist/{ssr-Do_SiVoL.d.ts → ssr-CrVNy6Pa.d.ts} +9 -15
- package/dist/{ssr-4PBXAOO3.js → ssr-FXD2PPMC.js} +4 -3
- package/dist/ssr.cjs +736 -274
- package/dist/ssr.d.cts +26 -6
- package/dist/ssr.d.ts +26 -6
- package/dist/ssr.js +12 -11
- package/dist/{tagFactory-DaJ0YWX6.d.cts → tagFactory-S17H2qxu.d.cts} +9 -1
- package/dist/{tagFactory-DaJ0YWX6.d.ts → tagFactory-S17H2qxu.d.ts} +9 -1
- package/dist/testing.cjs +303 -76
- package/dist/testing.d.cts +17 -4
- package/dist/testing.d.ts +17 -4
- package/dist/testing.js +100 -44
- package/dist/ui.cjs +589 -178
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +20 -17
- package/dist/widgets.cjs +1103 -146
- package/dist/widgets.d.cts +104 -2
- package/dist/widgets.d.ts +104 -2
- package/dist/widgets.js +9 -7
- package/package.json +8 -2
- package/dist/chunk-32DY64NT.js +0 -282
- package/dist/chunk-3AIRKM3B.js +0 -1263
- package/dist/chunk-3ARAQO7B.js +0 -398
- package/dist/chunk-3CRQALYP.js +0 -877
- package/dist/chunk-4EI4AG32.js +0 -482
- package/dist/chunk-4MYMUBRS.js +0 -21
- package/dist/chunk-5ZYQ6KDD.js +0 -154
- package/dist/chunk-6BMPXPUW.js +0 -26
- package/dist/chunk-6HLLIF3K.js +0 -398
- package/dist/chunk-6LSNVCS2.js +0 -937
- package/dist/chunk-6SA3QQES.js +0 -61
- package/dist/chunk-77L6NL3X.js +0 -1097
- package/dist/chunk-7BF6TK55.js +0 -1097
- package/dist/chunk-7TQKR4PP.js +0 -294
- package/dist/chunk-7V26P53V.js +0 -712
- package/dist/chunk-AZ3ISID5.js +0 -298
- package/dist/chunk-B7SWRFUT.js +0 -332
- package/dist/chunk-BTU3TJDS.js +0 -365
- package/dist/chunk-BW3WT46K.js +0 -937
- package/dist/chunk-C6KFWOFV.js +0 -616
- package/dist/chunk-CHF5OHIA.js +0 -61
- package/dist/chunk-CHJ27IGK.js +0 -26
- package/dist/chunk-CMBFNA7L.js +0 -27
- package/dist/chunk-DAHRH4ON.js +0 -331
- package/dist/chunk-DKOHBI74.js +0 -924
- package/dist/chunk-DTCOOBMX.js +0 -725
- package/dist/chunk-EBGIRKQY.js +0 -616
- package/dist/chunk-EUZND3CB.js +0 -27
- package/dist/chunk-EVCZO745.js +0 -365
- package/dist/chunk-EWFVA3TJ.js +0 -282
- package/dist/chunk-F3FA4F32.js +0 -292
- package/dist/chunk-FGOEVHY3.js +0 -60
- package/dist/chunk-G3BOQPVO.js +0 -365
- package/dist/chunk-GCOK2LC3.js +0 -282
- package/dist/chunk-GJPXRJ45.js +0 -37
- package/dist/chunk-HGMJFBC7.js +0 -654
- package/dist/chunk-JAKHTMQU.js +0 -1000
- package/dist/chunk-JCI5M6U6.js +0 -956
- package/dist/chunk-K4G4ZQNR.js +0 -286
- package/dist/chunk-K5ZUMYVS.js +0 -89
- package/dist/chunk-KQPDEVVS.js +0 -398
- package/dist/chunk-L6JRBDNS.js +0 -60
- package/dist/chunk-LA6KQEDU.js +0 -712
- package/dist/chunk-MB6QFH3I.js +0 -2776
- package/dist/chunk-MDVXJWFN.js +0 -304
- package/dist/chunk-MEZVEBPN.js +0 -2008
- package/dist/chunk-MK4ERFYL.js +0 -2249
- package/dist/chunk-MLKGABMK.js +0 -9
- package/dist/chunk-MQ5GOYPH.js +0 -2249
- package/dist/chunk-MYRV7VDM.js +0 -742
- package/dist/chunk-N6IZB6KJ.js +0 -567
- package/dist/chunk-NEKUBFPT.js +0 -60
- package/dist/chunk-NMRUZALC.js +0 -1097
- package/dist/chunk-NYVAC6P5.js +0 -37
- package/dist/chunk-NZIIMDWI.js +0 -84
- package/dist/chunk-OF7UZIVB.js +0 -725
- package/dist/chunk-P3XWXJZU.js +0 -282
- package/dist/chunk-P6W3STU4.js +0 -2249
- package/dist/chunk-PBHF5WKN.js +0 -616
- package/dist/chunk-PDZQY43A.js +0 -616
- package/dist/chunk-PTQJDMRT.js +0 -146
- package/dist/chunk-PZEGYCF5.js +0 -61
- package/dist/chunk-QBMDLBU2.js +0 -975
- package/dist/chunk-QWZG56ET.js +0 -2744
- package/dist/chunk-RQGQSLQK.js +0 -725
- package/dist/chunk-SDLZDHKP.js +0 -107
- package/dist/chunk-TDGZL5CU.js +0 -365
- package/dist/chunk-TNQWPPE6.js +0 -37
- package/dist/chunk-TSOKIX5Z.js +0 -654
- package/dist/chunk-UHNL42EF.js +0 -2730
- package/dist/chunk-UNXCEF6S.js +0 -21
- package/dist/chunk-V2XTI523.js +0 -347
- package/dist/chunk-VAU366PN.js +0 -2241
- package/dist/chunk-VMVDTCXB.js +0 -712
- package/dist/chunk-VQNQZCWJ.js +0 -61
- package/dist/chunk-VRW3FULF.js +0 -725
- package/dist/chunk-WADYRCO2.js +0 -304
- package/dist/chunk-WILQZRO4.js +0 -282
- package/dist/chunk-WR5D4EGH.js +0 -26
- package/dist/chunk-WUHJISPP.js +0 -298
- package/dist/chunk-XYU6TZOW.js +0 -182
- package/dist/chunk-Y6GP4QGG.js +0 -276
- package/dist/chunk-YECR7UIA.js +0 -347
- package/dist/chunk-YUTWTI4B.js +0 -654
- package/dist/chunk-Z65KYU7I.js +0 -26
- package/dist/chunk-Z6POF5YC.js +0 -975
- package/dist/chunk-ZBJP6WFL.js +0 -482
- package/dist/chunk-ZD6OAMTH.js +0 -277
- package/dist/chunk-ZWKZCBO6.js +0 -317
- package/dist/contracts-DDrwxvJ-.d.cts +0 -245
- package/dist/contracts-DDrwxvJ-.d.ts +0 -245
- package/dist/contracts-DOrhwbke.d.cts +0 -245
- package/dist/contracts-DOrhwbke.d.ts +0 -245
- package/dist/contracts-xo5ckdRP.d.cts +0 -240
- package/dist/contracts-xo5ckdRP.d.ts +0 -240
- package/dist/customElement-BKQfbSZQ.d.cts +0 -262
- package/dist/customElement-BKQfbSZQ.d.ts +0 -262
- package/dist/customElement-D2DJp_xn.d.cts +0 -313
- package/dist/customElement-D2DJp_xn.d.ts +0 -313
- package/dist/customElement-yz8uyk-0.d.cts +0 -308
- package/dist/customElement-yz8uyk-0.d.ts +0 -308
- package/dist/introspect-Cb0zgpi2.d.cts +0 -477
- package/dist/introspect-Y2xNXGSf.d.ts +0 -477
- package/dist/plugin-Bek4RhJY.d.cts +0 -43
- package/dist/plugin-Bek4RhJY.d.ts +0 -43
- package/dist/ssr-3RXHP5ES.js +0 -38
- package/dist/ssr-6GIMY5MX.js +0 -38
- package/dist/ssr-BA6sxxUd.d.cts +0 -135
- package/dist/ssr-BA6sxxUd.d.ts +0 -135
- package/dist/ssr-WKUPVSSK.js +0 -36
- package/dist/tagFactory-Dl8QCLga.d.cts +0 -23
- package/dist/tagFactory-Dl8QCLga.d.ts +0 -23
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// src/utils/sanitize.ts
|
|
2
|
+
var SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
|
|
3
|
+
function sanitizeUrl(url) {
|
|
4
|
+
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
5
|
+
if (!trimmed) return "";
|
|
6
|
+
const lower = trimmed.toLowerCase();
|
|
7
|
+
let schemeEnd = -1;
|
|
8
|
+
for (let i = 0; i < lower.length; i++) {
|
|
9
|
+
const ch = lower.charCodeAt(i);
|
|
10
|
+
if (ch === 58) {
|
|
11
|
+
schemeEnd = i;
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
14
|
+
if (ch === 47 || ch === 63 || ch === 35) break;
|
|
15
|
+
}
|
|
16
|
+
if (schemeEnd === -1) return trimmed;
|
|
17
|
+
const scheme = lower.slice(0, schemeEnd + 1);
|
|
18
|
+
if (!/^[a-z][a-z0-9+.-]*:$/.test(scheme)) return trimmed;
|
|
19
|
+
if (SAFE_URL_PROTOCOLS.indexOf(scheme) === -1) return "";
|
|
20
|
+
return trimmed;
|
|
21
|
+
}
|
|
22
|
+
function sanitizeSrcset(value) {
|
|
23
|
+
const parts = value.split(",");
|
|
24
|
+
const out = [];
|
|
25
|
+
for (let i = 0; i < parts.length; i++) {
|
|
26
|
+
const part = parts[i].trim();
|
|
27
|
+
if (!part) continue;
|
|
28
|
+
const m = part.match(/^(\S+)(\s+.+)?$/);
|
|
29
|
+
if (!m) continue;
|
|
30
|
+
const safe = sanitizeUrl(m[1]);
|
|
31
|
+
if (!safe) continue;
|
|
32
|
+
out.push(m[2] ? `${safe}${m[2]}` : safe);
|
|
33
|
+
}
|
|
34
|
+
return out.join(", ");
|
|
35
|
+
}
|
|
36
|
+
function sanitizeCSSValue(value) {
|
|
37
|
+
const decoded = value.replace(/\\([0-9a-fA-F]{1,6})\s?/g, (_m, hex) => {
|
|
38
|
+
const code = Number.parseInt(hex, 16);
|
|
39
|
+
if (!Number.isFinite(code) || code < 0 || code > 1114111) return "";
|
|
40
|
+
try {
|
|
41
|
+
return String.fromCodePoint(code);
|
|
42
|
+
} catch {
|
|
43
|
+
return "";
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const lower = decoded.toLowerCase().replace(/\s+/g, "");
|
|
47
|
+
if (lower.includes("url(") || lower.includes("expression(") || lower.includes("javascript:") || lower.includes("vbscript:") || lower.includes("-moz-binding") || lower.includes("behavior:") || lower.includes("@import") || lower.includes("image-set(") || lower.includes("filter:progid")) {
|
|
48
|
+
return "";
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
function stripHtml(html) {
|
|
53
|
+
return String(html).replace(/<[^>]*>/g, "");
|
|
54
|
+
}
|
|
55
|
+
var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
56
|
+
"href",
|
|
57
|
+
"xlink:href",
|
|
58
|
+
"src",
|
|
59
|
+
"action",
|
|
60
|
+
"formaction",
|
|
61
|
+
"formtarget",
|
|
62
|
+
"cite",
|
|
63
|
+
"poster",
|
|
64
|
+
"background",
|
|
65
|
+
"srcset",
|
|
66
|
+
"ping",
|
|
67
|
+
"data"
|
|
68
|
+
]);
|
|
69
|
+
function isUrlAttribute(attr) {
|
|
70
|
+
return URL_ATTRIBUTES.has(attr);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export {
|
|
74
|
+
sanitizeUrl,
|
|
75
|
+
sanitizeSrcset,
|
|
76
|
+
sanitizeCSSValue,
|
|
77
|
+
stripHtml,
|
|
78
|
+
isUrlAttribute
|
|
79
|
+
};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
derived
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DRUZZAK4.js";
|
|
4
4
|
import {
|
|
5
5
|
effect
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WZA53FXU.js";
|
|
7
7
|
import {
|
|
8
|
+
batch,
|
|
8
9
|
signal
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-RDTDJCAB.js";
|
|
10
11
|
|
|
11
12
|
// src/patterns/machine.ts
|
|
12
13
|
function machine(config) {
|
|
@@ -74,7 +75,11 @@ function machine(config) {
|
|
|
74
75
|
function persisted(key, initial, options = {}) {
|
|
75
76
|
const storage = options.session ? sessionStorage : localStorage;
|
|
76
77
|
const serialize = options.serialize || JSON.stringify;
|
|
77
|
-
const
|
|
78
|
+
const safeReviver = (k, v) => {
|
|
79
|
+
if (k === "__proto__" || k === "constructor" || k === "prototype") return void 0;
|
|
80
|
+
return v;
|
|
81
|
+
};
|
|
82
|
+
const deserialize = options.deserialize || ((raw) => JSON.parse(raw, safeReviver));
|
|
78
83
|
const encrypt = options.encrypt;
|
|
79
84
|
const decrypt = options.decrypt;
|
|
80
85
|
const syncTabs = options.session ? false : options.syncTabs ?? true;
|
|
@@ -178,6 +183,27 @@ function optimisticList(initialValue) {
|
|
|
178
183
|
const [pending, setPending] = signal(false);
|
|
179
184
|
let inflightCount = 0;
|
|
180
185
|
let version = 0;
|
|
186
|
+
let tempIdCounter = 0;
|
|
187
|
+
const itemIds = /* @__PURE__ */ new WeakMap();
|
|
188
|
+
const idToItem = /* @__PURE__ */ new Map();
|
|
189
|
+
function tagItem(item) {
|
|
190
|
+
const id = ++tempIdCounter;
|
|
191
|
+
if (item !== null && typeof item === "object") {
|
|
192
|
+
itemIds.set(item, id);
|
|
193
|
+
}
|
|
194
|
+
idToItem.set(id, item);
|
|
195
|
+
return id;
|
|
196
|
+
}
|
|
197
|
+
function findIndexById(list, id) {
|
|
198
|
+
for (let i = 0; i < list.length; i++) {
|
|
199
|
+
const it = list[i];
|
|
200
|
+
if (it !== null && typeof it === "object" && itemIds.get(it) === id) {
|
|
201
|
+
return i;
|
|
202
|
+
}
|
|
203
|
+
if (Object.is(it, idToItem.get(id))) return i;
|
|
204
|
+
}
|
|
205
|
+
return -1;
|
|
206
|
+
}
|
|
181
207
|
function begin() {
|
|
182
208
|
const v = ++version;
|
|
183
209
|
inflightCount++;
|
|
@@ -193,12 +219,13 @@ function optimisticList(initialValue) {
|
|
|
193
219
|
}
|
|
194
220
|
async function add(item, asyncAction) {
|
|
195
221
|
const prev = items();
|
|
222
|
+
const id = tagItem(item);
|
|
196
223
|
setItems([...prev, item]);
|
|
197
224
|
const myVersion = begin();
|
|
198
225
|
try {
|
|
199
226
|
const result = await asyncAction();
|
|
200
227
|
setItems((current) => {
|
|
201
|
-
const idx = current
|
|
228
|
+
const idx = findIndexById(current, id);
|
|
202
229
|
if (idx >= 0) {
|
|
203
230
|
const next = [...current];
|
|
204
231
|
next[idx] = result;
|
|
@@ -206,8 +233,10 @@ function optimisticList(initialValue) {
|
|
|
206
233
|
}
|
|
207
234
|
return [...current, result];
|
|
208
235
|
});
|
|
236
|
+
idToItem.delete(id);
|
|
209
237
|
end(myVersion);
|
|
210
238
|
} catch {
|
|
239
|
+
idToItem.delete(id);
|
|
211
240
|
end(myVersion, () => setItems(prev));
|
|
212
241
|
}
|
|
213
242
|
}
|
|
@@ -224,12 +253,13 @@ function optimisticList(initialValue) {
|
|
|
224
253
|
}
|
|
225
254
|
async function updateItem(predicate, patch, asyncAction) {
|
|
226
255
|
const prev = items();
|
|
227
|
-
const
|
|
256
|
+
const patchedIds = [];
|
|
228
257
|
setItems(
|
|
229
258
|
prev.map((item) => {
|
|
230
259
|
if (predicate(item)) {
|
|
231
260
|
const patched = { ...item, ...patch };
|
|
232
|
-
|
|
261
|
+
const id = tagItem(patched);
|
|
262
|
+
patchedIds.push(id);
|
|
233
263
|
return patched;
|
|
234
264
|
}
|
|
235
265
|
return item;
|
|
@@ -238,9 +268,19 @@ function optimisticList(initialValue) {
|
|
|
238
268
|
const myVersion = begin();
|
|
239
269
|
try {
|
|
240
270
|
const result = await asyncAction();
|
|
241
|
-
setItems(
|
|
271
|
+
setItems(
|
|
272
|
+
(current) => current.map((item) => {
|
|
273
|
+
if (item !== null && typeof item === "object") {
|
|
274
|
+
const existingId = itemIds.get(item);
|
|
275
|
+
if (existingId !== void 0 && patchedIds.includes(existingId)) return result;
|
|
276
|
+
}
|
|
277
|
+
return item;
|
|
278
|
+
})
|
|
279
|
+
);
|
|
280
|
+
for (const id of patchedIds) idToItem.delete(id);
|
|
242
281
|
end(myVersion);
|
|
243
282
|
} catch {
|
|
283
|
+
for (const id of patchedIds) idToItem.delete(id);
|
|
244
284
|
end(myVersion, () => setItems(prev));
|
|
245
285
|
}
|
|
246
286
|
}
|
|
@@ -249,10 +289,7 @@ function optimisticList(initialValue) {
|
|
|
249
289
|
pending,
|
|
250
290
|
add,
|
|
251
291
|
remove,
|
|
252
|
-
update: updateItem
|
|
253
|
-
addOptimistic: add,
|
|
254
|
-
removeOptimistic: remove,
|
|
255
|
-
updateOptimistic: updateItem
|
|
292
|
+
update: updateItem
|
|
256
293
|
};
|
|
257
294
|
}
|
|
258
295
|
|
|
@@ -271,14 +308,16 @@ function timeline(initial, maxHistory = 100) {
|
|
|
271
308
|
const idx = index();
|
|
272
309
|
const newHistory = hist.slice(0, idx + 1);
|
|
273
310
|
newHistory.push(newValue);
|
|
274
|
-
|
|
275
|
-
newHistory.
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
311
|
+
batch(() => {
|
|
312
|
+
if (newHistory.length > maxHistory) {
|
|
313
|
+
newHistory.shift();
|
|
314
|
+
setHistory(newHistory);
|
|
315
|
+
setIndex(newHistory.length - 1);
|
|
316
|
+
} else {
|
|
317
|
+
setHistory(newHistory);
|
|
318
|
+
setIndex(idx + 1);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
282
321
|
}
|
|
283
322
|
function undo() {
|
|
284
323
|
if (canUndo()) {
|
|
@@ -291,8 +330,10 @@ function timeline(initial, maxHistory = 100) {
|
|
|
291
330
|
}
|
|
292
331
|
}
|
|
293
332
|
function reset() {
|
|
294
|
-
|
|
295
|
-
|
|
333
|
+
batch(() => {
|
|
334
|
+
setHistory([initial]);
|
|
335
|
+
setIndex(0);
|
|
336
|
+
});
|
|
296
337
|
}
|
|
297
338
|
function jumpTo(targetIndex) {
|
|
298
339
|
const hist = history();
|
|
@@ -304,8 +345,37 @@ function timeline(initial, maxHistory = 100) {
|
|
|
304
345
|
}
|
|
305
346
|
|
|
306
347
|
// src/patterns/globalStore.ts
|
|
348
|
+
function deepClone(value) {
|
|
349
|
+
if (typeof structuredClone === "function") {
|
|
350
|
+
return structuredClone(value);
|
|
351
|
+
}
|
|
352
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
353
|
+
const clone = (v) => {
|
|
354
|
+
if (v === null || typeof v !== "object") return v;
|
|
355
|
+
if (seen.has(v)) throw new Error("deepClone: circular reference");
|
|
356
|
+
seen.add(v);
|
|
357
|
+
if (v instanceof Date) return new Date(v.getTime());
|
|
358
|
+
if (v instanceof Map) {
|
|
359
|
+
const out2 = /* @__PURE__ */ new Map();
|
|
360
|
+
for (const [k, val] of v) out2.set(clone(k), clone(val));
|
|
361
|
+
return out2;
|
|
362
|
+
}
|
|
363
|
+
if (v instanceof Set) {
|
|
364
|
+
const out2 = /* @__PURE__ */ new Set();
|
|
365
|
+
for (const val of v) out2.add(clone(val));
|
|
366
|
+
return out2;
|
|
367
|
+
}
|
|
368
|
+
if (Array.isArray(v)) return v.map(clone);
|
|
369
|
+
const out = {};
|
|
370
|
+
for (const k of Object.keys(v)) {
|
|
371
|
+
out[k] = clone(v[k]);
|
|
372
|
+
}
|
|
373
|
+
return out;
|
|
374
|
+
};
|
|
375
|
+
return clone(value);
|
|
376
|
+
}
|
|
307
377
|
function globalStore(config) {
|
|
308
|
-
const initialState =
|
|
378
|
+
const initialState = deepClone(config.state);
|
|
309
379
|
const [getState, setState] = signal({ ...initialState });
|
|
310
380
|
const listeners = /* @__PURE__ */ new Set();
|
|
311
381
|
const middlewares = config.middleware || [];
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createPlugin
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3JHCYHWN.js";
|
|
4
4
|
import {
|
|
5
5
|
tagFactory
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-P2HSJDDN.js";
|
|
7
7
|
import {
|
|
8
8
|
derived
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-DRUZZAK4.js";
|
|
10
10
|
import {
|
|
11
11
|
effect
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WZA53FXU.js";
|
|
13
13
|
import {
|
|
14
14
|
batch,
|
|
15
15
|
signal
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-RDTDJCAB.js";
|
|
17
17
|
|
|
18
18
|
// src/ecosystem/adapters/mobx.ts
|
|
19
19
|
function mobXAdapter(options) {
|
|
@@ -21,7 +21,7 @@ function mobXAdapter(options) {
|
|
|
21
21
|
const { autorun } = options;
|
|
22
22
|
const disposers = [];
|
|
23
23
|
function fromMobX(expression) {
|
|
24
|
-
const [getValue, setValue] = signal(
|
|
24
|
+
const [getValue, setValue] = signal(void 0);
|
|
25
25
|
const disposer = autorun(() => {
|
|
26
26
|
const newValue = expression();
|
|
27
27
|
batch(() => {
|
|
@@ -29,7 +29,13 @@ function mobXAdapter(options) {
|
|
|
29
29
|
});
|
|
30
30
|
});
|
|
31
31
|
disposers.push(disposer);
|
|
32
|
-
|
|
32
|
+
const getter = (() => getValue());
|
|
33
|
+
getter.dispose = () => {
|
|
34
|
+
const i = disposers.indexOf(disposer);
|
|
35
|
+
if (i >= 0) disposers.splice(i, 1);
|
|
36
|
+
disposer();
|
|
37
|
+
};
|
|
38
|
+
return getter;
|
|
33
39
|
}
|
|
34
40
|
function toMobX(sibuGetter, callback) {
|
|
35
41
|
return effect(() => {
|
|
@@ -57,12 +63,12 @@ function reduxAdapter(options) {
|
|
|
57
63
|
setState(store.getState());
|
|
58
64
|
});
|
|
59
65
|
});
|
|
60
|
-
function
|
|
66
|
+
function select(selector) {
|
|
61
67
|
return derived(() => selector(getState()));
|
|
62
68
|
}
|
|
63
69
|
const api = {
|
|
64
70
|
getState,
|
|
65
|
-
|
|
71
|
+
select,
|
|
66
72
|
dispatch: store.dispatch.bind(store),
|
|
67
73
|
destroy: unsubscribe
|
|
68
74
|
};
|
|
@@ -80,12 +86,12 @@ function zustandAdapter(options) {
|
|
|
80
86
|
setSibuState(state);
|
|
81
87
|
});
|
|
82
88
|
});
|
|
83
|
-
function
|
|
89
|
+
function select(selector) {
|
|
84
90
|
return derived(() => selector(getState()));
|
|
85
91
|
}
|
|
86
92
|
const api = {
|
|
87
93
|
getState,
|
|
88
|
-
|
|
94
|
+
select,
|
|
89
95
|
setState: store.setState.bind(store),
|
|
90
96
|
destroy() {
|
|
91
97
|
unsubscribe();
|
|
@@ -1,36 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isUrlAttribute,
|
|
3
|
+
sanitizeUrl
|
|
4
|
+
} from "./chunk-UCS6AMJ7.js";
|
|
1
5
|
import {
|
|
2
6
|
track
|
|
3
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QO3WC6FS.js";
|
|
4
8
|
import {
|
|
5
9
|
devWarn,
|
|
6
10
|
isDev
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
|
|
9
|
-
// src/utils/sanitize.ts
|
|
10
|
-
function sanitizeUrl(url) {
|
|
11
|
-
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
12
|
-
if (!trimmed) return "";
|
|
13
|
-
const lower = trimmed.toLowerCase();
|
|
14
|
-
if (lower.startsWith("javascript:") || lower.startsWith("data:") || lower.startsWith("vbscript:") || lower.startsWith("blob:")) {
|
|
15
|
-
return "";
|
|
16
|
-
}
|
|
17
|
-
return trimmed;
|
|
18
|
-
}
|
|
19
|
-
function sanitizeCSSValue(value) {
|
|
20
|
-
const lower = value.toLowerCase().replace(/\s+/g, "");
|
|
21
|
-
if (lower.includes("url(") || lower.includes("expression(") || lower.includes("javascript:") || lower.includes("-moz-binding")) {
|
|
22
|
-
return "";
|
|
23
|
-
}
|
|
24
|
-
return value;
|
|
25
|
-
}
|
|
26
|
-
var URL_ATTRIBUTES = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "cite", "poster", "background", "srcset"]);
|
|
27
|
-
function isUrlAttribute(attr) {
|
|
28
|
-
return URL_ATTRIBUTES.has(attr);
|
|
29
|
-
}
|
|
11
|
+
} from "./chunk-LMLD24FC.js";
|
|
30
12
|
|
|
31
13
|
// src/reactivity/bindAttribute.ts
|
|
32
14
|
var _isDev = isDev();
|
|
15
|
+
function setProp(el, key, val) {
|
|
16
|
+
el[key] = val;
|
|
17
|
+
}
|
|
18
|
+
function isEventHandlerAttr(name) {
|
|
19
|
+
if (name.length < 3) return false;
|
|
20
|
+
const lower = name.toLowerCase();
|
|
21
|
+
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
22
|
+
}
|
|
33
23
|
function bindAttribute(el, attr, getter) {
|
|
24
|
+
if (isEventHandlerAttr(attr)) {
|
|
25
|
+
if (_isDev)
|
|
26
|
+
devWarn(
|
|
27
|
+
`bindAttribute: refusing to bind event-handler attribute "${attr}". Use on:{ ${attr.slice(2)}: fn } instead.`
|
|
28
|
+
);
|
|
29
|
+
return () => {
|
|
30
|
+
};
|
|
31
|
+
}
|
|
34
32
|
function commit() {
|
|
35
33
|
let value;
|
|
36
34
|
try {
|
|
@@ -42,7 +40,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
42
40
|
}
|
|
43
41
|
if (typeof value === "boolean") {
|
|
44
42
|
if (attr in el && (attr === "checked" || attr === "disabled" || attr === "selected")) {
|
|
45
|
-
el
|
|
43
|
+
setProp(el, attr, value);
|
|
46
44
|
} else if (value) {
|
|
47
45
|
el.setAttribute(attr, "");
|
|
48
46
|
} else {
|
|
@@ -52,7 +50,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
52
50
|
}
|
|
53
51
|
const str = String(value);
|
|
54
52
|
if ((attr === "value" || attr === "checked") && attr in el) {
|
|
55
|
-
el
|
|
53
|
+
setProp(el, attr, attr === "checked" ? Boolean(value) : str);
|
|
56
54
|
} else {
|
|
57
55
|
el.setAttribute(attr, isUrlAttribute(attr) ? sanitizeUrl(str) : str);
|
|
58
56
|
}
|
|
@@ -83,7 +81,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
|
|
|
83
81
|
}
|
|
84
82
|
const str = String(value);
|
|
85
83
|
if ((name === "value" || name === "checked") && name in el) {
|
|
86
|
-
el
|
|
84
|
+
setProp(el, name, name === "checked" ? Boolean(value) : str);
|
|
87
85
|
} else {
|
|
88
86
|
el.setAttribute(name, isUrlAttribute(name) ? sanitizeUrl(str) : str);
|
|
89
87
|
}
|
|
@@ -99,9 +97,6 @@ function bindDynamic(el, nameGetter, valueGetter) {
|
|
|
99
97
|
}
|
|
100
98
|
|
|
101
99
|
export {
|
|
102
|
-
sanitizeUrl,
|
|
103
|
-
sanitizeCSSValue,
|
|
104
|
-
isUrlAttribute,
|
|
105
100
|
bindAttribute,
|
|
106
101
|
bindDynamic
|
|
107
102
|
};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isSSR
|
|
3
|
+
} from "./chunk-2RA7SHDA.js";
|
|
4
|
+
import {
|
|
5
|
+
track,
|
|
6
|
+
untracked
|
|
7
|
+
} from "./chunk-QO3WC6FS.js";
|
|
8
|
+
import {
|
|
9
|
+
devAssert
|
|
10
|
+
} from "./chunk-LMLD24FC.js";
|
|
11
|
+
|
|
12
|
+
// src/core/signals/effect.ts
|
|
13
|
+
var _g = globalThis;
|
|
14
|
+
function on(deps, handler) {
|
|
15
|
+
let prev;
|
|
16
|
+
let first = true;
|
|
17
|
+
return () => {
|
|
18
|
+
const value = deps();
|
|
19
|
+
if (first) {
|
|
20
|
+
first = false;
|
|
21
|
+
prev = value;
|
|
22
|
+
untracked(() => handler(value, void 0));
|
|
23
|
+
} else {
|
|
24
|
+
const p = prev;
|
|
25
|
+
prev = value;
|
|
26
|
+
untracked(() => handler(value, p));
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function effect(effectFn, options) {
|
|
31
|
+
devAssert(typeof effectFn === "function", "effect: argument must be a function.");
|
|
32
|
+
if (isSSR()) return () => {
|
|
33
|
+
};
|
|
34
|
+
const onError = options?.onError;
|
|
35
|
+
let userCleanups = [];
|
|
36
|
+
const onCleanup = (fn) => {
|
|
37
|
+
userCleanups.push(fn);
|
|
38
|
+
};
|
|
39
|
+
const runUserCleanups = () => {
|
|
40
|
+
if (userCleanups.length === 0) return;
|
|
41
|
+
const list = userCleanups;
|
|
42
|
+
userCleanups = [];
|
|
43
|
+
for (let i = list.length - 1; i >= 0; i--) {
|
|
44
|
+
try {
|
|
45
|
+
list[i]();
|
|
46
|
+
} catch (err) {
|
|
47
|
+
if (typeof console !== "undefined") {
|
|
48
|
+
console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const invokeBody = () => effectFn(onCleanup);
|
|
54
|
+
const wrappedFn = onError ? () => {
|
|
55
|
+
try {
|
|
56
|
+
invokeBody();
|
|
57
|
+
} catch (err) {
|
|
58
|
+
onError(err);
|
|
59
|
+
}
|
|
60
|
+
} : invokeBody;
|
|
61
|
+
let cleanupHandle = () => {
|
|
62
|
+
};
|
|
63
|
+
let running = false;
|
|
64
|
+
let rerunPending = false;
|
|
65
|
+
const MAX_RERUNS = 100;
|
|
66
|
+
const subscriber = () => {
|
|
67
|
+
if (running) {
|
|
68
|
+
rerunPending = true;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
running = true;
|
|
72
|
+
try {
|
|
73
|
+
let reruns = 0;
|
|
74
|
+
do {
|
|
75
|
+
rerunPending = false;
|
|
76
|
+
runUserCleanups();
|
|
77
|
+
cleanupHandle();
|
|
78
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
79
|
+
if (++reruns > MAX_RERUNS) {
|
|
80
|
+
if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
81
|
+
console.error(
|
|
82
|
+
`[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
rerunPending = false;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
} while (rerunPending);
|
|
89
|
+
} finally {
|
|
90
|
+
running = false;
|
|
91
|
+
rerunPending = false;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
running = true;
|
|
95
|
+
try {
|
|
96
|
+
let reruns = 0;
|
|
97
|
+
do {
|
|
98
|
+
rerunPending = false;
|
|
99
|
+
runUserCleanups();
|
|
100
|
+
cleanupHandle();
|
|
101
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
102
|
+
if (++reruns > MAX_RERUNS) {
|
|
103
|
+
if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
104
|
+
console.error(
|
|
105
|
+
`[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times on initial run \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
rerunPending = false;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
} while (rerunPending);
|
|
112
|
+
} finally {
|
|
113
|
+
running = false;
|
|
114
|
+
rerunPending = false;
|
|
115
|
+
}
|
|
116
|
+
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
117
|
+
if (hook) hook.emit("effect:create", { effectFn });
|
|
118
|
+
let disposed = false;
|
|
119
|
+
return () => {
|
|
120
|
+
if (disposed) return;
|
|
121
|
+
disposed = true;
|
|
122
|
+
const h = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
123
|
+
if (h) {
|
|
124
|
+
try {
|
|
125
|
+
h.emit("effect:destroy", { effectFn });
|
|
126
|
+
} catch {
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
runUserCleanups();
|
|
131
|
+
} catch (err) {
|
|
132
|
+
if (typeof console !== "undefined") {
|
|
133
|
+
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
cleanupHandle();
|
|
138
|
+
} catch (err) {
|
|
139
|
+
if (typeof console !== "undefined") {
|
|
140
|
+
console.warn("[SibuJS effect] dispose threw:", err);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export {
|
|
147
|
+
on,
|
|
148
|
+
effect
|
|
149
|
+
};
|