sibujs 1.4.0 → 2.0.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/README.md +105 -119
- package/dist/browser.cjs +288 -80
- package/dist/browser.d.cts +19 -9
- package/dist/browser.d.ts +19 -9
- package/dist/browser.js +6 -6
- package/dist/build.cjs +1019 -313
- package/dist/build.d.cts +1 -1
- package/dist/build.d.ts +1 -1
- 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-3JHCYHWN.js +125 -0
- package/dist/{chunk-ZWKZCBO6.js → chunk-3LR7GLWQ.js} +154 -33
- package/dist/{chunk-3AIRKM3B.js → chunk-3NSGB5JN.js} +115 -34
- package/dist/{chunk-3ARAQO7B.js → chunk-52YJLLRO.js} +29 -6
- package/dist/chunk-54EDRCEF.js +93 -0
- package/dist/chunk-7JDB7I65.js +1327 -0
- package/dist/{chunk-WZSPOOER.js → chunk-CC65Y57T.js} +8 -5
- package/dist/{chunk-23VV7YD3.js → chunk-DFPFITST.js} +25 -30
- package/dist/{chunk-WR5D4EGH.js → chunk-GTBNNBJ6.js} +14 -2
- package/dist/chunk-HB24TBAF.js +121 -0
- package/dist/{chunk-CZUGLNJS.js → chunk-ITX6OO3F.js} +3 -3
- package/dist/{chunk-JAKHTMQU.js → chunk-JA6667UN.js} +206 -46
- package/dist/{chunk-77L6NL3X.js → chunk-JXMMDLBY.js} +306 -183
- package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
- package/dist/{chunk-F3FA4F32.js → chunk-KLRMB5ZS.js} +135 -79
- package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
- package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
- package/dist/{chunk-TSOKIX5Z.js → chunk-MIUAXB7K.js} +126 -74
- package/dist/{chunk-QWZG56ET.js → chunk-ND2664SF.js} +558 -190
- package/dist/{chunk-JCI5M6U6.js → chunk-O2MNQFLP.js} +261 -79
- package/dist/{chunk-EWFVA3TJ.js → chunk-R73P76YZ.js} +1 -1
- package/dist/{chunk-2BYQDGN3.js → chunk-SAHNHTFC.js} +234 -63
- package/dist/chunk-UCS6AMJ7.js +79 -0
- package/dist/{chunk-ZD6OAMTH.js → chunk-VLPPXTYG.js} +90 -35
- package/dist/{chunk-OUZZEE4S.js → chunk-WOMYAHHI.js} +17 -11
- package/dist/{contracts-xo5ckdRP.d.cts → contracts-ey_Qh8ef.d.cts} +7 -8
- package/dist/{contracts-xo5ckdRP.d.ts → contracts-ey_Qh8ef.d.ts} +7 -8
- package/dist/{customElement-D2DJp_xn.d.cts → customElement-CPfIrbvg.d.cts} +18 -9
- package/dist/{customElement-D2DJp_xn.d.ts → customElement-CPfIrbvg.d.ts} +18 -9
- package/dist/data.cjs +452 -100
- package/dist/data.d.cts +20 -2
- package/dist/data.d.ts +20 -2
- package/dist/data.js +11 -9
- package/dist/devtools.cjs +535 -247
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +34 -30
- package/dist/ecosystem.cjs +499 -143
- package/dist/ecosystem.d.cts +13 -11
- package/dist/ecosystem.d.ts +13 -11
- package/dist/ecosystem.js +12 -11
- package/dist/extras.cjs +3639 -1629
- package/dist/extras.d.cts +11 -11
- package/dist/extras.d.ts +11 -11
- package/dist/extras.js +58 -45
- package/dist/index.cjs +1023 -313
- package/dist/index.d.cts +128 -55
- package/dist/index.d.ts +128 -55
- package/dist/index.js +28 -16
- package/dist/{introspect-BumjnBKr.d.cts → introspect-BWNjNw64.d.cts} +22 -2
- package/dist/{introspect-CZrlcaYy.d.ts → introspect-cY2pg9pW.d.ts} +22 -2
- package/dist/motion.cjs +90 -36
- package/dist/motion.d.cts +1 -1
- package/dist/motion.d.ts +1 -1
- package/dist/motion.js +4 -4
- package/dist/patterns.cjs +414 -81
- package/dist/patterns.d.cts +53 -20
- package/dist/patterns.d.ts +53 -20
- package/dist/patterns.js +7 -7
- package/dist/performance.cjs +364 -108
- package/dist/performance.d.cts +29 -17
- package/dist/performance.d.ts +29 -17
- package/dist/performance.js +13 -6
- package/dist/plugin-D30wlGW5.d.cts +71 -0
- package/dist/plugin-D30wlGW5.d.ts +71 -0
- package/dist/plugins.cjs +652 -271
- package/dist/plugins.d.cts +13 -6
- package/dist/plugins.d.ts +13 -6
- package/dist/plugins.js +116 -50
- 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 +648 -219
- package/dist/ssr.d.cts +27 -7
- package/dist/ssr.d.ts +27 -7
- package/dist/ssr.js +12 -11
- package/dist/{tagFactory-DaJ0YWX6.d.ts → tagFactory-S17H2qxu.d.cts} +9 -1
- package/dist/{tagFactory-DaJ0YWX6.d.cts → tagFactory-S17H2qxu.d.ts} +9 -1
- package/dist/testing.cjs +252 -63
- package/dist/testing.d.cts +17 -4
- package/dist/testing.d.ts +17 -4
- package/dist/testing.js +100 -44
- package/dist/ui.cjs +576 -168
- package/dist/ui.d.cts +13 -16
- package/dist/ui.d.ts +13 -16
- package/dist/ui.js +20 -17
- package/dist/widgets.cjs +1001 -93
- 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-3CRQALYP.js +0 -877
- package/dist/chunk-4EI4AG32.js +0 -482
- package/dist/chunk-4MYMUBRS.js +0 -21
- package/dist/chunk-6HLLIF3K.js +0 -398
- package/dist/chunk-6LSNVCS2.js +0 -937
- package/dist/chunk-6SA3QQES.js +0 -61
- 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-BGN5ZMP4.js +0 -26
- 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-FGOEVHY3.js +0 -60
- package/dist/chunk-G3BOQPVO.js +0 -365
- package/dist/chunk-GCOK2LC3.js +0 -282
- package/dist/chunk-HGMJFBC7.js +0 -654
- 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-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-N6IZB6KJ.js +0 -567
- package/dist/chunk-NEKUBFPT.js +0 -60
- package/dist/chunk-NHUC2QWH.js +0 -282
- package/dist/chunk-NMRUZALC.js +0 -1097
- package/dist/chunk-NYVAC6P5.js +0 -37
- package/dist/chunk-OF7UZIVB.js +0 -725
- package/dist/chunk-P6W3STU4.js +0 -2249
- package/dist/chunk-PBHF5WKN.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-RQGQSLQK.js +0 -725
- package/dist/chunk-SDLZDHKP.js +0 -107
- package/dist/chunk-TNQWPPE6.js +0 -37
- 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-VRW3FULF.js +0 -725
- package/dist/chunk-WADYRCO2.js +0 -304
- package/dist/chunk-WILQZRO4.js +0 -282
- 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/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/customElement-BKQfbSZQ.d.cts +0 -262
- package/dist/customElement-BKQfbSZQ.d.ts +0 -262
- 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,125 @@
|
|
|
1
|
+
// src/plugins/plugin.ts
|
|
2
|
+
function createPluginRegistry() {
|
|
3
|
+
const installedPlugins = /* @__PURE__ */ new Set();
|
|
4
|
+
const hooks = { init: [], mount: [], unmount: [], error: [] };
|
|
5
|
+
const provided = /* @__PURE__ */ new Map();
|
|
6
|
+
const registry = {
|
|
7
|
+
installedPlugins,
|
|
8
|
+
hooks,
|
|
9
|
+
provided,
|
|
10
|
+
plugin(p, options) {
|
|
11
|
+
if (installedPlugins.has(p.name)) {
|
|
12
|
+
console.warn(`[Plugin] "${p.name}" is already installed.`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const ctx = {
|
|
16
|
+
onInit: (cb) => hooks.init.push(cb),
|
|
17
|
+
onMount: (cb) => hooks.mount.push(cb),
|
|
18
|
+
onUnmount: (cb) => hooks.unmount.push(cb),
|
|
19
|
+
onError: (cb) => hooks.error.push(cb),
|
|
20
|
+
provide: (key, value) => provided.set(key, value)
|
|
21
|
+
};
|
|
22
|
+
const initHooksBefore = hooks.init.length;
|
|
23
|
+
p.install(ctx, options);
|
|
24
|
+
installedPlugins.add(p.name);
|
|
25
|
+
const justAdded = hooks.init.slice(initHooksBefore);
|
|
26
|
+
for (const cb of justAdded) {
|
|
27
|
+
try {
|
|
28
|
+
cb();
|
|
29
|
+
} catch (e) {
|
|
30
|
+
console.error(`[Plugin] "${p.name}" init error:`, e);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
inject(key, defaultValue) {
|
|
35
|
+
if (provided.has(key)) return provided.get(key);
|
|
36
|
+
if (defaultValue !== void 0) return defaultValue;
|
|
37
|
+
throw new Error(`[Plugin] No provider found for key "${key}"`);
|
|
38
|
+
},
|
|
39
|
+
triggerMount(element) {
|
|
40
|
+
const snapshot = hooks.mount.slice();
|
|
41
|
+
for (const hook of snapshot) {
|
|
42
|
+
try {
|
|
43
|
+
hook(element);
|
|
44
|
+
} catch (e) {
|
|
45
|
+
console.error("[Plugin] Mount hook error:", e);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
triggerUnmount(element) {
|
|
50
|
+
const snapshot = hooks.unmount.slice();
|
|
51
|
+
for (const hook of snapshot) {
|
|
52
|
+
try {
|
|
53
|
+
hook(element);
|
|
54
|
+
} catch (e) {
|
|
55
|
+
console.error("[Plugin] Unmount hook error:", e);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
triggerError(error) {
|
|
60
|
+
const snapshot = hooks.error.slice();
|
|
61
|
+
for (const hook of snapshot) {
|
|
62
|
+
try {
|
|
63
|
+
hook(error);
|
|
64
|
+
} catch (e) {
|
|
65
|
+
console.error("[Plugin] Error hook error:", e);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
reset() {
|
|
70
|
+
installedPlugins.clear();
|
|
71
|
+
hooks.init.length = 0;
|
|
72
|
+
hooks.mount.length = 0;
|
|
73
|
+
hooks.unmount.length = 0;
|
|
74
|
+
hooks.error.length = 0;
|
|
75
|
+
provided.clear();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
return registry;
|
|
79
|
+
}
|
|
80
|
+
var defaultRegistry = createPluginRegistry();
|
|
81
|
+
var defaultRegistryTouched = false;
|
|
82
|
+
function createPlugin(name, install) {
|
|
83
|
+
return { name, install };
|
|
84
|
+
}
|
|
85
|
+
function plugin(plugin2, options) {
|
|
86
|
+
defaultRegistryTouched = true;
|
|
87
|
+
defaultRegistry.plugin(plugin2, options);
|
|
88
|
+
}
|
|
89
|
+
function inject(key, defaultValue) {
|
|
90
|
+
return defaultRegistry.inject(key, defaultValue);
|
|
91
|
+
}
|
|
92
|
+
function triggerPluginMount(element) {
|
|
93
|
+
defaultRegistry.triggerMount(element);
|
|
94
|
+
}
|
|
95
|
+
function triggerPluginUnmount(element) {
|
|
96
|
+
defaultRegistry.triggerUnmount(element);
|
|
97
|
+
}
|
|
98
|
+
function triggerPluginError(error) {
|
|
99
|
+
defaultRegistry.triggerError(error);
|
|
100
|
+
}
|
|
101
|
+
function resetPlugins() {
|
|
102
|
+
defaultRegistry.reset();
|
|
103
|
+
defaultRegistryTouched = false;
|
|
104
|
+
}
|
|
105
|
+
function setDefaultPluginRegistry(registry) {
|
|
106
|
+
if (defaultRegistryTouched && defaultRegistry.installedPlugins.size > 0) {
|
|
107
|
+
console.warn(
|
|
108
|
+
"[Plugin] Replacing default plugin registry while plugins are already installed on the singleton. This may indicate mixed singleton/registry usage."
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
defaultRegistry = registry;
|
|
112
|
+
defaultRegistryTouched = true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export {
|
|
116
|
+
createPluginRegistry,
|
|
117
|
+
createPlugin,
|
|
118
|
+
plugin,
|
|
119
|
+
inject,
|
|
120
|
+
triggerPluginMount,
|
|
121
|
+
triggerPluginUnmount,
|
|
122
|
+
triggerPluginError,
|
|
123
|
+
resetPlugins,
|
|
124
|
+
setDefaultPluginRegistry
|
|
125
|
+
};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
derived
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-54EDRCEF.js";
|
|
4
4
|
import {
|
|
5
5
|
effect
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-HB24TBAF.js";
|
|
7
7
|
import {
|
|
8
|
+
batch,
|
|
8
9
|
signal
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-CC65Y57T.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;
|
|
@@ -90,7 +95,7 @@ function persisted(key, initial, options = {}) {
|
|
|
90
95
|
}
|
|
91
96
|
const [value, setValue] = signal(restored);
|
|
92
97
|
let applyingFromStorage = false;
|
|
93
|
-
effect(() => {
|
|
98
|
+
const stopPersistEffect = effect(() => {
|
|
94
99
|
const current = value();
|
|
95
100
|
if (applyingFromStorage) return;
|
|
96
101
|
try {
|
|
@@ -130,6 +135,7 @@ function persisted(key, initial, options = {}) {
|
|
|
130
135
|
window.addEventListener("storage", storageListener);
|
|
131
136
|
}
|
|
132
137
|
const dispose = () => {
|
|
138
|
+
stopPersistEffect();
|
|
133
139
|
if (storageListener && typeof window !== "undefined") {
|
|
134
140
|
window.removeEventListener("storage", storageListener);
|
|
135
141
|
storageListener = null;
|
|
@@ -147,62 +153,144 @@ function persisted(key, initial, options = {}) {
|
|
|
147
153
|
// src/patterns/optimistic.ts
|
|
148
154
|
function optimistic(initialValue) {
|
|
149
155
|
const [value, setValue] = signal(initialValue);
|
|
150
|
-
const [
|
|
151
|
-
|
|
156
|
+
const [pending, setPending] = signal(false);
|
|
157
|
+
let inflightCount = 0;
|
|
158
|
+
let version = 0;
|
|
159
|
+
async function update(optimisticValue, asyncAction) {
|
|
160
|
+
const myVersion = ++version;
|
|
152
161
|
const previousValue = value();
|
|
153
162
|
setValue(optimisticValue);
|
|
163
|
+
inflightCount++;
|
|
154
164
|
setPending(true);
|
|
155
165
|
try {
|
|
156
166
|
const result = await asyncAction();
|
|
157
|
-
|
|
167
|
+
if (version === myVersion) {
|
|
168
|
+
setValue(result);
|
|
169
|
+
}
|
|
158
170
|
} catch {
|
|
159
|
-
|
|
171
|
+
if (version === myVersion) {
|
|
172
|
+
setValue(previousValue);
|
|
173
|
+
}
|
|
160
174
|
} finally {
|
|
161
|
-
|
|
175
|
+
inflightCount--;
|
|
176
|
+
if (inflightCount === 0) setPending(false);
|
|
162
177
|
}
|
|
163
178
|
}
|
|
164
|
-
return
|
|
179
|
+
return { value, pending, update };
|
|
165
180
|
}
|
|
166
181
|
function optimisticList(initialValue) {
|
|
167
182
|
const [items, setItems] = signal([...initialValue]);
|
|
168
|
-
|
|
183
|
+
const [pending, setPending] = signal(false);
|
|
184
|
+
let inflightCount = 0;
|
|
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
|
+
}
|
|
207
|
+
function begin() {
|
|
208
|
+
const v = ++version;
|
|
209
|
+
inflightCount++;
|
|
210
|
+
setPending(true);
|
|
211
|
+
return v;
|
|
212
|
+
}
|
|
213
|
+
function end(myVersion, revertFn) {
|
|
214
|
+
if (revertFn && version === myVersion) {
|
|
215
|
+
revertFn();
|
|
216
|
+
}
|
|
217
|
+
inflightCount--;
|
|
218
|
+
if (inflightCount === 0) setPending(false);
|
|
219
|
+
}
|
|
220
|
+
async function add(item, asyncAction) {
|
|
169
221
|
const prev = items();
|
|
222
|
+
const id = tagItem(item);
|
|
170
223
|
setItems([...prev, item]);
|
|
224
|
+
const myVersion = begin();
|
|
171
225
|
try {
|
|
172
226
|
const result = await asyncAction();
|
|
173
227
|
setItems((current) => {
|
|
174
|
-
const idx = current
|
|
228
|
+
const idx = findIndexById(current, id);
|
|
175
229
|
if (idx >= 0) {
|
|
176
230
|
const next = [...current];
|
|
177
231
|
next[idx] = result;
|
|
178
232
|
return next;
|
|
179
233
|
}
|
|
180
|
-
return [...current
|
|
234
|
+
return [...current, result];
|
|
181
235
|
});
|
|
236
|
+
idToItem.delete(id);
|
|
237
|
+
end(myVersion);
|
|
182
238
|
} catch {
|
|
183
|
-
|
|
239
|
+
idToItem.delete(id);
|
|
240
|
+
end(myVersion, () => setItems(prev));
|
|
184
241
|
}
|
|
185
242
|
}
|
|
186
|
-
async function
|
|
243
|
+
async function remove(predicate, asyncAction) {
|
|
187
244
|
const prev = items();
|
|
188
245
|
setItems(prev.filter((item) => !predicate(item)));
|
|
246
|
+
const myVersion = begin();
|
|
189
247
|
try {
|
|
190
248
|
await asyncAction();
|
|
249
|
+
end(myVersion);
|
|
191
250
|
} catch {
|
|
192
|
-
setItems(prev);
|
|
251
|
+
end(myVersion, () => setItems(prev));
|
|
193
252
|
}
|
|
194
253
|
}
|
|
195
|
-
async function
|
|
254
|
+
async function updateItem(predicate, patch, asyncAction) {
|
|
196
255
|
const prev = items();
|
|
197
|
-
|
|
256
|
+
const patchedIds = [];
|
|
257
|
+
setItems(
|
|
258
|
+
prev.map((item) => {
|
|
259
|
+
if (predicate(item)) {
|
|
260
|
+
const patched = { ...item, ...patch };
|
|
261
|
+
const id = tagItem(patched);
|
|
262
|
+
patchedIds.push(id);
|
|
263
|
+
return patched;
|
|
264
|
+
}
|
|
265
|
+
return item;
|
|
266
|
+
})
|
|
267
|
+
);
|
|
268
|
+
const myVersion = begin();
|
|
198
269
|
try {
|
|
199
270
|
const result = await asyncAction();
|
|
200
|
-
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);
|
|
281
|
+
end(myVersion);
|
|
201
282
|
} catch {
|
|
202
|
-
|
|
283
|
+
for (const id of patchedIds) idToItem.delete(id);
|
|
284
|
+
end(myVersion, () => setItems(prev));
|
|
203
285
|
}
|
|
204
286
|
}
|
|
205
|
-
return {
|
|
287
|
+
return {
|
|
288
|
+
items,
|
|
289
|
+
pending,
|
|
290
|
+
add,
|
|
291
|
+
remove,
|
|
292
|
+
update: updateItem
|
|
293
|
+
};
|
|
206
294
|
}
|
|
207
295
|
|
|
208
296
|
// src/patterns/timeTravel.ts
|
|
@@ -220,14 +308,16 @@ function timeline(initial, maxHistory = 100) {
|
|
|
220
308
|
const idx = index();
|
|
221
309
|
const newHistory = hist.slice(0, idx + 1);
|
|
222
310
|
newHistory.push(newValue);
|
|
223
|
-
|
|
224
|
-
newHistory.
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
+
});
|
|
231
321
|
}
|
|
232
322
|
function undo() {
|
|
233
323
|
if (canUndo()) {
|
|
@@ -240,8 +330,10 @@ function timeline(initial, maxHistory = 100) {
|
|
|
240
330
|
}
|
|
241
331
|
}
|
|
242
332
|
function reset() {
|
|
243
|
-
|
|
244
|
-
|
|
333
|
+
batch(() => {
|
|
334
|
+
setHistory([initial]);
|
|
335
|
+
setIndex(0);
|
|
336
|
+
});
|
|
245
337
|
}
|
|
246
338
|
function jumpTo(targetIndex) {
|
|
247
339
|
const hist = history();
|
|
@@ -253,8 +345,37 @@ function timeline(initial, maxHistory = 100) {
|
|
|
253
345
|
}
|
|
254
346
|
|
|
255
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
|
+
}
|
|
256
377
|
function globalStore(config) {
|
|
257
|
-
const initialState =
|
|
378
|
+
const initialState = deepClone(config.state);
|
|
258
379
|
const [getState, setState] = signal({ ...initialState });
|
|
259
380
|
const listeners = /* @__PURE__ */ new Set();
|
|
260
381
|
const middlewares = config.middleware || [];
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
effect
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HB24TBAF.js";
|
|
4
4
|
import {
|
|
5
5
|
batch,
|
|
6
6
|
signal
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-CC65Y57T.js";
|
|
8
8
|
|
|
9
9
|
// src/browser/media.ts
|
|
10
10
|
function media(query) {
|
|
@@ -72,6 +72,8 @@ function scroll(target) {
|
|
|
72
72
|
const [y, setY] = signal(0);
|
|
73
73
|
const [isScrolling, setIsScrolling] = signal(false);
|
|
74
74
|
let scrollTimer = null;
|
|
75
|
+
let currentTarget = null;
|
|
76
|
+
let effectCleanup = null;
|
|
75
77
|
if (typeof window === "undefined") {
|
|
76
78
|
return { x, y, isScrolling, dispose: () => {
|
|
77
79
|
} };
|
|
@@ -94,11 +96,26 @@ function scroll(target) {
|
|
|
94
96
|
scrollTimer = null;
|
|
95
97
|
}, 150);
|
|
96
98
|
};
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
function attachListener(eventTarget) {
|
|
100
|
+
if (currentTarget === eventTarget) return;
|
|
101
|
+
if (currentTarget) currentTarget.removeEventListener("scroll", handler);
|
|
102
|
+
currentTarget = eventTarget;
|
|
103
|
+
currentTarget.addEventListener("scroll", handler, { passive: true });
|
|
104
|
+
}
|
|
105
|
+
if (target) {
|
|
106
|
+
effectCleanup = effect(() => {
|
|
107
|
+
const el = target();
|
|
108
|
+
attachListener(el || window);
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
attachListener(window);
|
|
112
|
+
}
|
|
100
113
|
function dispose() {
|
|
101
|
-
|
|
114
|
+
effectCleanup?.();
|
|
115
|
+
if (currentTarget) {
|
|
116
|
+
currentTarget.removeEventListener("scroll", handler);
|
|
117
|
+
currentTarget = null;
|
|
118
|
+
}
|
|
102
119
|
if (scrollTimer !== null) {
|
|
103
120
|
clearTimeout(scrollTimer);
|
|
104
121
|
scrollTimer = null;
|
|
@@ -382,7 +399,10 @@ function dropZone(element, options) {
|
|
|
382
399
|
const raw = e.dataTransfer.getData("application/json");
|
|
383
400
|
if (raw) {
|
|
384
401
|
try {
|
|
385
|
-
transferData = JSON.parse(
|
|
402
|
+
transferData = JSON.parse(
|
|
403
|
+
raw,
|
|
404
|
+
(k, v) => k === "__proto__" || k === "constructor" || k === "prototype" ? void 0 : v
|
|
405
|
+
);
|
|
386
406
|
} catch {
|
|
387
407
|
transferData = raw;
|
|
388
408
|
}
|
|
@@ -617,31 +637,44 @@ function urlState() {
|
|
|
617
637
|
}
|
|
618
638
|
};
|
|
619
639
|
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
const
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
640
|
+
let lastSearch = window.location.search;
|
|
641
|
+
let lastHash = window.location.hash;
|
|
642
|
+
const [params, setParamsSignal] = signal(new URLSearchParams(lastSearch));
|
|
643
|
+
const [hash, setHashSignal] = signal(lastHash);
|
|
644
|
+
function syncFromLocation() {
|
|
645
|
+
const currentSearch = window.location.search;
|
|
646
|
+
const currentHash = window.location.hash;
|
|
647
|
+
if (currentSearch !== lastSearch) {
|
|
648
|
+
lastSearch = currentSearch;
|
|
649
|
+
setParamsSignal(new URLSearchParams(currentSearch));
|
|
650
|
+
}
|
|
651
|
+
if (currentHash !== lastHash) {
|
|
652
|
+
lastHash = currentHash;
|
|
653
|
+
setHashSignal(currentHash);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
window.addEventListener("popstate", syncFromLocation);
|
|
657
|
+
window.addEventListener("hashchange", syncFromLocation);
|
|
628
658
|
function setParams(next, opts = {}) {
|
|
629
659
|
const p = next instanceof URLSearchParams ? next : new URLSearchParams(next);
|
|
630
660
|
const query = p.toString();
|
|
631
661
|
const newUrl = `${window.location.pathname}${query ? `?${query}` : ""}${window.location.hash}`;
|
|
632
662
|
if (opts.replace) window.history.replaceState(null, "", newUrl);
|
|
633
663
|
else window.history.pushState(null, "", newUrl);
|
|
664
|
+
lastSearch = window.location.search;
|
|
634
665
|
setParamsSignal(new URLSearchParams(p));
|
|
635
666
|
}
|
|
636
667
|
function setHash(next, opts = {}) {
|
|
637
|
-
const normalized = next.startsWith("#") ? next :
|
|
668
|
+
const normalized = next && next !== "#" ? next.startsWith("#") ? next : `#${next}` : "";
|
|
638
669
|
const newUrl = `${window.location.pathname}${window.location.search}${normalized}`;
|
|
639
670
|
if (opts.replace) window.history.replaceState(null, "", newUrl);
|
|
640
671
|
else window.history.pushState(null, "", newUrl);
|
|
672
|
+
lastHash = normalized;
|
|
641
673
|
setHashSignal(normalized);
|
|
642
674
|
}
|
|
643
675
|
function dispose() {
|
|
644
|
-
window.removeEventListener("popstate",
|
|
676
|
+
window.removeEventListener("popstate", syncFromLocation);
|
|
677
|
+
window.removeEventListener("hashchange", syncFromLocation);
|
|
645
678
|
}
|
|
646
679
|
return { params, hash, setParams, setHash, dispose };
|
|
647
680
|
}
|
|
@@ -749,13 +782,21 @@ function wakeLock() {
|
|
|
749
782
|
}
|
|
750
783
|
const onVisibility = () => {
|
|
751
784
|
if (sentinel?.released && !document.hidden) {
|
|
752
|
-
|
|
785
|
+
request().catch((err) => {
|
|
786
|
+
if (typeof console !== "undefined") {
|
|
787
|
+
console.warn("[SibuJS wakeLock] re-acquire failed:", err);
|
|
788
|
+
}
|
|
789
|
+
});
|
|
753
790
|
}
|
|
754
791
|
};
|
|
755
792
|
document.addEventListener("visibilitychange", onVisibility);
|
|
756
793
|
function dispose() {
|
|
757
794
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
758
|
-
|
|
795
|
+
release().catch((err) => {
|
|
796
|
+
if (typeof console !== "undefined") {
|
|
797
|
+
console.warn("[SibuJS wakeLock] release failed:", err);
|
|
798
|
+
}
|
|
799
|
+
});
|
|
759
800
|
}
|
|
760
801
|
return { active, request, release, dispose };
|
|
761
802
|
}
|
|
@@ -951,11 +992,21 @@ function speech() {
|
|
|
951
992
|
};
|
|
952
993
|
}
|
|
953
994
|
const synth = window.speechSynthesis;
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
995
|
+
let interval = null;
|
|
996
|
+
function startPolling() {
|
|
997
|
+
if (interval !== null) return;
|
|
998
|
+
interval = setInterval(() => {
|
|
999
|
+
setSpeaking(synth.speaking);
|
|
1000
|
+
setPaused(synth.paused);
|
|
1001
|
+
if (!synth.speaking && !synth.paused) {
|
|
1002
|
+
clearInterval(interval);
|
|
1003
|
+
interval = null;
|
|
1004
|
+
}
|
|
1005
|
+
}, 200);
|
|
1006
|
+
}
|
|
1007
|
+
let disposed = false;
|
|
958
1008
|
function speak(text, options = {}) {
|
|
1009
|
+
if (disposed) return;
|
|
959
1010
|
const u = new SpeechSynthesisUtterance(text);
|
|
960
1011
|
if (options.lang) u.lang = options.lang;
|
|
961
1012
|
if (options.rate != null) u.rate = options.rate;
|
|
@@ -966,19 +1017,41 @@ function speech() {
|
|
|
966
1017
|
const match = voices.find((v) => v.name === options.voice);
|
|
967
1018
|
if (match) u.voice = match;
|
|
968
1019
|
}
|
|
969
|
-
u.addEventListener(
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1020
|
+
u.addEventListener(
|
|
1021
|
+
"start",
|
|
1022
|
+
() => {
|
|
1023
|
+
if (!disposed) setSpeaking(true);
|
|
1024
|
+
},
|
|
1025
|
+
{ once: true }
|
|
1026
|
+
);
|
|
1027
|
+
u.addEventListener(
|
|
1028
|
+
"end",
|
|
1029
|
+
() => {
|
|
1030
|
+
if (disposed) return;
|
|
1031
|
+
setSpeaking(false);
|
|
1032
|
+
setPaused(false);
|
|
1033
|
+
},
|
|
1034
|
+
{ once: true }
|
|
1035
|
+
);
|
|
1036
|
+
u.addEventListener(
|
|
1037
|
+
"error",
|
|
1038
|
+
() => {
|
|
1039
|
+
if (disposed) return;
|
|
1040
|
+
setSpeaking(false);
|
|
1041
|
+
setPaused(false);
|
|
1042
|
+
},
|
|
1043
|
+
{ once: true }
|
|
1044
|
+
);
|
|
978
1045
|
synth.speak(u);
|
|
1046
|
+
setSpeaking(true);
|
|
1047
|
+
startPolling();
|
|
979
1048
|
}
|
|
980
1049
|
function dispose() {
|
|
981
|
-
|
|
1050
|
+
disposed = true;
|
|
1051
|
+
if (interval !== null) {
|
|
1052
|
+
clearInterval(interval);
|
|
1053
|
+
interval = null;
|
|
1054
|
+
}
|
|
982
1055
|
synth.cancel();
|
|
983
1056
|
}
|
|
984
1057
|
return {
|
|
@@ -1207,13 +1280,21 @@ function imageLoader(src) {
|
|
|
1207
1280
|
};
|
|
1208
1281
|
img.src = url;
|
|
1209
1282
|
}
|
|
1283
|
+
let srcEffectTeardown = null;
|
|
1210
1284
|
if (typeof src === "function") {
|
|
1211
|
-
|
|
1285
|
+
srcEffectTeardown = effect(() => {
|
|
1286
|
+
const url = src();
|
|
1287
|
+
start(url);
|
|
1288
|
+
});
|
|
1212
1289
|
} else {
|
|
1213
1290
|
start(src);
|
|
1214
1291
|
}
|
|
1215
1292
|
function dispose() {
|
|
1216
1293
|
disposed = true;
|
|
1294
|
+
if (srcEffectTeardown) {
|
|
1295
|
+
srcEffectTeardown();
|
|
1296
|
+
srcEffectTeardown = null;
|
|
1297
|
+
}
|
|
1217
1298
|
if (current) {
|
|
1218
1299
|
current.onload = null;
|
|
1219
1300
|
current.onerror = null;
|