sibujs 1.5.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/dist/browser.cjs +238 -69
- package/dist/browser.d.cts +5 -0
- package/dist/browser.d.ts +5 -0
- package/dist/browser.js +6 -6
- package/dist/build.cjs +916 -292
- 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-VAPYJN4X.js → chunk-3LR7GLWQ.js} +93 -23
- package/dist/{chunk-RJ46C3CS.js → chunk-3NSGB5JN.js} +71 -20
- package/dist/{chunk-XUEEGU5O.js → chunk-52YJLLRO.js} +16 -4
- package/dist/{chunk-XHK6BDAJ.js → chunk-54EDRCEF.js} +25 -8
- 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-BGN5ZMP4.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-BGTHZHJ5.js → chunk-JA6667UN.js} +188 -44
- package/dist/{chunk-7GRNSCFT.js → chunk-JXMMDLBY.js} +306 -183
- package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
- package/dist/{chunk-SFKNRVCU.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-BMPL52BF.js → chunk-MIUAXB7K.js} +118 -66
- package/dist/{chunk-JCDUJN2F.js → chunk-ND2664SF.js} +486 -153
- package/dist/{chunk-VQDZK23A.js → chunk-O2MNQFLP.js} +181 -66
- package/dist/{chunk-NHUC2QWH.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-K4G4ZQNR.js → chunk-VLPPXTYG.js} +84 -38
- package/dist/{chunk-OUZZEE4S.js → chunk-WOMYAHHI.js} +17 -11
- 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 +410 -99
- package/dist/data.d.cts +20 -2
- package/dist/data.d.ts +20 -2
- package/dist/data.js +11 -9
- package/dist/devtools.cjs +513 -223
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +12 -6
- package/dist/ecosystem.cjs +475 -144
- package/dist/ecosystem.d.cts +9 -7
- package/dist/ecosystem.d.ts +9 -7
- package/dist/ecosystem.js +12 -11
- package/dist/extras.cjs +3355 -1541
- package/dist/extras.d.cts +9 -9
- package/dist/extras.d.ts +9 -9
- package/dist/extras.js +58 -45
- package/dist/index.cjs +920 -292
- package/dist/index.d.cts +71 -8
- package/dist/index.d.ts +71 -8
- 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 +77 -34
- package/dist/motion.js +4 -4
- package/dist/patterns.cjs +335 -69
- package/dist/patterns.d.cts +11 -12
- package/dist/patterns.d.ts +11 -12
- package/dist/patterns.js +7 -7
- package/dist/performance.cjs +279 -108
- 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 +635 -260
- 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 +642 -222
- 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 +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 +463 -137
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +20 -17
- package/dist/widgets.cjs +977 -94
- 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-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
package/dist/ecosystem.cjs
CHANGED
|
@@ -38,12 +38,12 @@ function isDev() {
|
|
|
38
38
|
var _isDev = isDev();
|
|
39
39
|
function devAssert(condition, message) {
|
|
40
40
|
if (_isDev && !condition) {
|
|
41
|
-
throw new Error(`[
|
|
41
|
+
throw new Error(`[SibuJS] ${message}`);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
function devWarn(message) {
|
|
45
45
|
if (_isDev) {
|
|
46
|
-
console.warn(`[
|
|
46
|
+
console.warn(`[SibuJS] ${message}`);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -53,11 +53,11 @@ var subscriberStack = new Array(32);
|
|
|
53
53
|
var stackCapacity = 32;
|
|
54
54
|
var stackTop = -1;
|
|
55
55
|
var currentSubscriber = null;
|
|
56
|
-
var signalSubscribers = /* @__PURE__ */ new WeakMap();
|
|
57
56
|
var SUBS = "__s";
|
|
58
57
|
var notifyDepth = 0;
|
|
59
58
|
var pendingQueue = [];
|
|
60
59
|
var pendingSet = /* @__PURE__ */ new Set();
|
|
60
|
+
var propagateStack = [];
|
|
61
61
|
function safeInvoke(sub) {
|
|
62
62
|
try {
|
|
63
63
|
sub();
|
|
@@ -66,6 +66,15 @@ function safeInvoke(sub) {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
var trackingSuspended = false;
|
|
69
|
+
function retrack(effectFn, subscriber) {
|
|
70
|
+
const prev = currentSubscriber;
|
|
71
|
+
currentSubscriber = subscriber;
|
|
72
|
+
try {
|
|
73
|
+
effectFn();
|
|
74
|
+
} finally {
|
|
75
|
+
currentSubscriber = prev;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
69
78
|
function track(effectFn, subscriber) {
|
|
70
79
|
if (!subscriber) subscriber = effectFn;
|
|
71
80
|
cleanup(subscriber);
|
|
@@ -104,7 +113,6 @@ function recordDependency(signal2) {
|
|
|
104
113
|
let subs = signal2[SUBS];
|
|
105
114
|
if (!subs) {
|
|
106
115
|
subs = /* @__PURE__ */ new Set();
|
|
107
|
-
signalSubscribers.set(signal2, subs);
|
|
108
116
|
signal2[SUBS] = subs;
|
|
109
117
|
}
|
|
110
118
|
subs.add(currentSubscriber);
|
|
@@ -126,17 +134,17 @@ function queueSignalNotification(signal2) {
|
|
|
126
134
|
}
|
|
127
135
|
}
|
|
128
136
|
}
|
|
129
|
-
var
|
|
137
|
+
var maxDrainIterations = 1e5;
|
|
130
138
|
function drainNotificationQueue() {
|
|
131
139
|
if (notifyDepth > 0) return;
|
|
132
140
|
notifyDepth++;
|
|
133
141
|
try {
|
|
134
142
|
let i = 0;
|
|
135
143
|
while (i < pendingQueue.length) {
|
|
136
|
-
if (i >=
|
|
144
|
+
if (i >= maxDrainIterations) {
|
|
137
145
|
if (typeof console !== "undefined") {
|
|
138
146
|
console.error(
|
|
139
|
-
`[SibuJS] Notification queue exceeded ${
|
|
147
|
+
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
140
148
|
);
|
|
141
149
|
}
|
|
142
150
|
break;
|
|
@@ -145,47 +153,52 @@ function drainNotificationQueue() {
|
|
|
145
153
|
i++;
|
|
146
154
|
}
|
|
147
155
|
} finally {
|
|
148
|
-
pendingQueue.length = 0;
|
|
149
|
-
pendingSet.clear();
|
|
150
156
|
notifyDepth--;
|
|
157
|
+
if (notifyDepth === 0) {
|
|
158
|
+
pendingQueue.length = 0;
|
|
159
|
+
pendingSet.clear();
|
|
160
|
+
}
|
|
151
161
|
}
|
|
152
162
|
}
|
|
153
163
|
function propagateDirty(sub) {
|
|
154
164
|
sub();
|
|
155
|
-
|
|
156
|
-
|
|
165
|
+
const rootSig = sub._sig;
|
|
166
|
+
if (!rootSig) return;
|
|
167
|
+
const stack = propagateStack;
|
|
168
|
+
const baseLen = stack.length;
|
|
169
|
+
stack.push(rootSig);
|
|
170
|
+
while (stack.length > baseLen) {
|
|
171
|
+
const sig = stack.pop();
|
|
157
172
|
const first = sig.__f;
|
|
158
173
|
if (first) {
|
|
159
174
|
if (first._c) {
|
|
160
175
|
const nSig = first._sig;
|
|
161
|
-
nSig._d
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (!pendingSet.has(first)) {
|
|
176
|
+
if (!nSig._d) {
|
|
177
|
+
nSig._d = true;
|
|
178
|
+
stack.push(nSig);
|
|
179
|
+
}
|
|
180
|
+
} else if (!pendingSet.has(first)) {
|
|
166
181
|
pendingSet.add(first);
|
|
167
182
|
pendingQueue.push(first);
|
|
168
183
|
}
|
|
169
|
-
|
|
184
|
+
continue;
|
|
170
185
|
}
|
|
171
186
|
const subs = sig[SUBS];
|
|
172
|
-
if (!subs)
|
|
173
|
-
let nextSig;
|
|
187
|
+
if (!subs) continue;
|
|
174
188
|
for (const s of subs) {
|
|
175
189
|
if (s._c) {
|
|
176
|
-
s();
|
|
177
190
|
const nSig = s._sig;
|
|
178
|
-
if (nSig && !
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
191
|
+
if (nSig && !nSig._d) {
|
|
192
|
+
nSig._d = true;
|
|
193
|
+
stack.push(nSig);
|
|
194
|
+
} else if (!nSig) {
|
|
195
|
+
s();
|
|
182
196
|
}
|
|
183
197
|
} else if (!pendingSet.has(s)) {
|
|
184
198
|
pendingSet.add(s);
|
|
185
199
|
pendingQueue.push(s);
|
|
186
200
|
}
|
|
187
201
|
}
|
|
188
|
-
sig = nextSig;
|
|
189
202
|
}
|
|
190
203
|
}
|
|
191
204
|
function notifySubscribers(signal2) {
|
|
@@ -209,13 +222,23 @@ function notifySubscribers(signal2) {
|
|
|
209
222
|
}
|
|
210
223
|
let i = 0;
|
|
211
224
|
while (i < pendingQueue.length) {
|
|
225
|
+
if (i >= maxDrainIterations) {
|
|
226
|
+
if (typeof console !== "undefined") {
|
|
227
|
+
console.error(
|
|
228
|
+
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
212
233
|
safeInvoke(pendingQueue[i]);
|
|
213
234
|
i++;
|
|
214
235
|
}
|
|
215
236
|
} finally {
|
|
216
|
-
pendingQueue.length = 0;
|
|
217
|
-
pendingSet.clear();
|
|
218
237
|
notifyDepth--;
|
|
238
|
+
if (notifyDepth === 0) {
|
|
239
|
+
pendingQueue.length = 0;
|
|
240
|
+
pendingSet.clear();
|
|
241
|
+
}
|
|
219
242
|
}
|
|
220
243
|
return;
|
|
221
244
|
}
|
|
@@ -235,30 +258,48 @@ function notifySubscribers(signal2) {
|
|
|
235
258
|
notifyDepth++;
|
|
236
259
|
try {
|
|
237
260
|
let directCount = 0;
|
|
261
|
+
let hasComputedSub = false;
|
|
238
262
|
for (const sub of subs) {
|
|
263
|
+
if (sub._c) hasComputedSub = true;
|
|
239
264
|
pendingQueue[directCount++] = sub;
|
|
240
265
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
266
|
+
if (!hasComputedSub) {
|
|
267
|
+
for (let i2 = 0; i2 < directCount; i2++) {
|
|
268
|
+
safeInvoke(pendingQueue[i2]);
|
|
244
269
|
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
270
|
+
} else {
|
|
271
|
+
for (let i2 = 0; i2 < directCount; i2++) {
|
|
272
|
+
if (pendingQueue[i2]._c) {
|
|
273
|
+
propagateDirty(pendingQueue[i2]);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
for (let i2 = 0; i2 < directCount; i2++) {
|
|
277
|
+
const sub = pendingQueue[i2];
|
|
278
|
+
if (!sub._c && !pendingSet.has(sub)) {
|
|
279
|
+
pendingSet.add(sub);
|
|
280
|
+
safeInvoke(sub);
|
|
250
281
|
}
|
|
251
282
|
}
|
|
252
283
|
}
|
|
253
284
|
let i = directCount;
|
|
254
285
|
while (i < pendingQueue.length) {
|
|
286
|
+
if (i - directCount >= maxDrainIterations) {
|
|
287
|
+
if (typeof console !== "undefined") {
|
|
288
|
+
console.error(
|
|
289
|
+
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
255
294
|
safeInvoke(pendingQueue[i]);
|
|
256
295
|
i++;
|
|
257
296
|
}
|
|
258
297
|
} finally {
|
|
259
|
-
pendingQueue.length = 0;
|
|
260
|
-
pendingSet.clear();
|
|
261
298
|
notifyDepth--;
|
|
299
|
+
if (notifyDepth === 0) {
|
|
300
|
+
pendingQueue.length = 0;
|
|
301
|
+
pendingSet.clear();
|
|
302
|
+
}
|
|
262
303
|
}
|
|
263
304
|
}
|
|
264
305
|
function cleanup(subscriber) {
|
|
@@ -269,7 +310,9 @@ function cleanup(subscriber) {
|
|
|
269
310
|
if (subs) {
|
|
270
311
|
subs.delete(subscriber);
|
|
271
312
|
if (singleDep.__f === subscriber) {
|
|
272
|
-
singleDep.__f = void 0;
|
|
313
|
+
singleDep.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
314
|
+
} else if (subs.size === 1 && singleDep.__f === void 0) {
|
|
315
|
+
singleDep.__f = subs.values().next().value;
|
|
273
316
|
}
|
|
274
317
|
}
|
|
275
318
|
sub._dep = void 0;
|
|
@@ -282,7 +325,9 @@ function cleanup(subscriber) {
|
|
|
282
325
|
if (subs) {
|
|
283
326
|
subs.delete(subscriber);
|
|
284
327
|
if (signal2.__f === subscriber) {
|
|
285
|
-
signal2.__f = void 0;
|
|
328
|
+
signal2.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
329
|
+
} else if (subs.size === 1 && signal2.__f === void 0) {
|
|
330
|
+
signal2.__f = subs.values().next().value;
|
|
286
331
|
}
|
|
287
332
|
}
|
|
288
333
|
}
|
|
@@ -290,9 +335,28 @@ function cleanup(subscriber) {
|
|
|
290
335
|
}
|
|
291
336
|
|
|
292
337
|
// src/core/ssr-context.ts
|
|
293
|
-
var
|
|
338
|
+
var als = null;
|
|
339
|
+
try {
|
|
340
|
+
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
341
|
+
const req = Function("return typeof require==='function'?require:null")();
|
|
342
|
+
if (req) {
|
|
343
|
+
const mod = req("node:async_hooks");
|
|
344
|
+
als = new mod.AsyncLocalStorage();
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
} catch {
|
|
348
|
+
als = null;
|
|
349
|
+
}
|
|
350
|
+
var fallbackStore = { ssr: false, suspenseIdCounter: 0 };
|
|
351
|
+
function getSSRStore() {
|
|
352
|
+
if (als) {
|
|
353
|
+
const s = als.getStore();
|
|
354
|
+
if (s) return s;
|
|
355
|
+
}
|
|
356
|
+
return fallbackStore;
|
|
357
|
+
}
|
|
294
358
|
function isSSR() {
|
|
295
|
-
return
|
|
359
|
+
return getSSRStore().ssr;
|
|
296
360
|
}
|
|
297
361
|
|
|
298
362
|
// src/core/signals/effect.ts
|
|
@@ -302,26 +366,86 @@ function effect(effectFn, options) {
|
|
|
302
366
|
if (isSSR()) return () => {
|
|
303
367
|
};
|
|
304
368
|
const onError = options?.onError;
|
|
369
|
+
let userCleanups = [];
|
|
370
|
+
const onCleanup = (fn) => {
|
|
371
|
+
userCleanups.push(fn);
|
|
372
|
+
};
|
|
373
|
+
const runUserCleanups = () => {
|
|
374
|
+
if (userCleanups.length === 0) return;
|
|
375
|
+
const list = userCleanups;
|
|
376
|
+
userCleanups = [];
|
|
377
|
+
for (let i = list.length - 1; i >= 0; i--) {
|
|
378
|
+
try {
|
|
379
|
+
list[i]();
|
|
380
|
+
} catch (err) {
|
|
381
|
+
if (typeof console !== "undefined") {
|
|
382
|
+
console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
const invokeBody = () => effectFn(onCleanup);
|
|
305
388
|
const wrappedFn = onError ? () => {
|
|
306
389
|
try {
|
|
307
|
-
|
|
390
|
+
invokeBody();
|
|
308
391
|
} catch (err) {
|
|
309
392
|
onError(err);
|
|
310
393
|
}
|
|
311
|
-
} :
|
|
394
|
+
} : invokeBody;
|
|
312
395
|
let cleanupHandle = () => {
|
|
313
396
|
};
|
|
397
|
+
let running = false;
|
|
314
398
|
const subscriber = () => {
|
|
315
|
-
|
|
316
|
-
|
|
399
|
+
if (running) {
|
|
400
|
+
if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
401
|
+
console.warn(
|
|
402
|
+
"[SibuJS] effect re-entered itself while running \u2014 the triggering update will be ignored. Wrap mutual writes in `batch()` or split the effect to avoid this."
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
running = true;
|
|
408
|
+
try {
|
|
409
|
+
runUserCleanups();
|
|
410
|
+
cleanupHandle();
|
|
411
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
412
|
+
} finally {
|
|
413
|
+
running = false;
|
|
414
|
+
}
|
|
317
415
|
};
|
|
318
|
-
|
|
416
|
+
running = true;
|
|
417
|
+
try {
|
|
418
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
419
|
+
} finally {
|
|
420
|
+
running = false;
|
|
421
|
+
}
|
|
319
422
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
320
423
|
if (hook) hook.emit("effect:create", { effectFn });
|
|
424
|
+
let disposed = false;
|
|
321
425
|
return () => {
|
|
426
|
+
if (disposed) return;
|
|
427
|
+
disposed = true;
|
|
322
428
|
const h = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
323
|
-
if (h)
|
|
324
|
-
|
|
429
|
+
if (h) {
|
|
430
|
+
try {
|
|
431
|
+
h.emit("effect:destroy", { effectFn });
|
|
432
|
+
} catch {
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
try {
|
|
436
|
+
runUserCleanups();
|
|
437
|
+
} catch (err) {
|
|
438
|
+
if (typeof console !== "undefined") {
|
|
439
|
+
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
try {
|
|
443
|
+
cleanupHandle();
|
|
444
|
+
} catch (err) {
|
|
445
|
+
if (typeof console !== "undefined") {
|
|
446
|
+
console.warn("[SibuJS effect] dispose threw:", err);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
325
449
|
};
|
|
326
450
|
}
|
|
327
451
|
|
|
@@ -345,10 +469,13 @@ function enqueueBatchedSignal(signal2) {
|
|
|
345
469
|
return true;
|
|
346
470
|
}
|
|
347
471
|
function flushBatch() {
|
|
348
|
-
|
|
349
|
-
|
|
472
|
+
try {
|
|
473
|
+
for (const signal2 of pendingSignals) {
|
|
474
|
+
queueSignalNotification(signal2);
|
|
475
|
+
}
|
|
476
|
+
} finally {
|
|
477
|
+
pendingSignals.clear();
|
|
350
478
|
}
|
|
351
|
-
pendingSignals.clear();
|
|
352
479
|
drainNotificationQueue();
|
|
353
480
|
}
|
|
354
481
|
|
|
@@ -391,6 +518,85 @@ function signal(initial, options) {
|
|
|
391
518
|
}
|
|
392
519
|
|
|
393
520
|
// src/plugins/plugin.ts
|
|
521
|
+
function createPluginRegistry() {
|
|
522
|
+
const installedPlugins = /* @__PURE__ */ new Set();
|
|
523
|
+
const hooks = { init: [], mount: [], unmount: [], error: [] };
|
|
524
|
+
const provided = /* @__PURE__ */ new Map();
|
|
525
|
+
const registry = {
|
|
526
|
+
installedPlugins,
|
|
527
|
+
hooks,
|
|
528
|
+
provided,
|
|
529
|
+
plugin(p, options) {
|
|
530
|
+
if (installedPlugins.has(p.name)) {
|
|
531
|
+
console.warn(`[Plugin] "${p.name}" is already installed.`);
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
const ctx = {
|
|
535
|
+
onInit: (cb) => hooks.init.push(cb),
|
|
536
|
+
onMount: (cb) => hooks.mount.push(cb),
|
|
537
|
+
onUnmount: (cb) => hooks.unmount.push(cb),
|
|
538
|
+
onError: (cb) => hooks.error.push(cb),
|
|
539
|
+
provide: (key, value) => provided.set(key, value)
|
|
540
|
+
};
|
|
541
|
+
const initHooksBefore = hooks.init.length;
|
|
542
|
+
p.install(ctx, options);
|
|
543
|
+
installedPlugins.add(p.name);
|
|
544
|
+
const justAdded = hooks.init.slice(initHooksBefore);
|
|
545
|
+
for (const cb of justAdded) {
|
|
546
|
+
try {
|
|
547
|
+
cb();
|
|
548
|
+
} catch (e) {
|
|
549
|
+
console.error(`[Plugin] "${p.name}" init error:`, e);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
},
|
|
553
|
+
inject(key, defaultValue) {
|
|
554
|
+
if (provided.has(key)) return provided.get(key);
|
|
555
|
+
if (defaultValue !== void 0) return defaultValue;
|
|
556
|
+
throw new Error(`[Plugin] No provider found for key "${key}"`);
|
|
557
|
+
},
|
|
558
|
+
triggerMount(element) {
|
|
559
|
+
const snapshot = hooks.mount.slice();
|
|
560
|
+
for (const hook of snapshot) {
|
|
561
|
+
try {
|
|
562
|
+
hook(element);
|
|
563
|
+
} catch (e) {
|
|
564
|
+
console.error("[Plugin] Mount hook error:", e);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
triggerUnmount(element) {
|
|
569
|
+
const snapshot = hooks.unmount.slice();
|
|
570
|
+
for (const hook of snapshot) {
|
|
571
|
+
try {
|
|
572
|
+
hook(element);
|
|
573
|
+
} catch (e) {
|
|
574
|
+
console.error("[Plugin] Unmount hook error:", e);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
},
|
|
578
|
+
triggerError(error) {
|
|
579
|
+
const snapshot = hooks.error.slice();
|
|
580
|
+
for (const hook of snapshot) {
|
|
581
|
+
try {
|
|
582
|
+
hook(error);
|
|
583
|
+
} catch (e) {
|
|
584
|
+
console.error("[Plugin] Error hook error:", e);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
},
|
|
588
|
+
reset() {
|
|
589
|
+
installedPlugins.clear();
|
|
590
|
+
hooks.init.length = 0;
|
|
591
|
+
hooks.mount.length = 0;
|
|
592
|
+
hooks.unmount.length = 0;
|
|
593
|
+
hooks.error.length = 0;
|
|
594
|
+
provided.clear();
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
return registry;
|
|
598
|
+
}
|
|
599
|
+
var defaultRegistry = createPluginRegistry();
|
|
394
600
|
function createPlugin(name, install) {
|
|
395
601
|
return { name, install };
|
|
396
602
|
}
|
|
@@ -401,7 +607,7 @@ function mobXAdapter(options) {
|
|
|
401
607
|
const { autorun } = options;
|
|
402
608
|
const disposers = [];
|
|
403
609
|
function fromMobX(expression) {
|
|
404
|
-
const [getValue, setValue] = signal(
|
|
610
|
+
const [getValue, setValue] = signal(void 0);
|
|
405
611
|
const disposer = autorun(() => {
|
|
406
612
|
const newValue = expression();
|
|
407
613
|
batch(() => {
|
|
@@ -409,7 +615,13 @@ function mobXAdapter(options) {
|
|
|
409
615
|
});
|
|
410
616
|
});
|
|
411
617
|
disposers.push(disposer);
|
|
412
|
-
|
|
618
|
+
const getter = (() => getValue());
|
|
619
|
+
getter.dispose = () => {
|
|
620
|
+
const i = disposers.indexOf(disposer);
|
|
621
|
+
if (i >= 0) disposers.splice(i, 1);
|
|
622
|
+
disposer();
|
|
623
|
+
};
|
|
624
|
+
return getter;
|
|
413
625
|
}
|
|
414
626
|
function toMobX(sibuGetter, callback) {
|
|
415
627
|
return effect(() => {
|
|
@@ -431,6 +643,7 @@ function mobXAdapter(options) {
|
|
|
431
643
|
function derived(getter, options) {
|
|
432
644
|
devAssert(typeof getter === "function", "derived: argument must be a getter function.");
|
|
433
645
|
const debugName = options?.name;
|
|
646
|
+
const equals = options?.equals;
|
|
434
647
|
const cs = {};
|
|
435
648
|
cs._d = false;
|
|
436
649
|
cs._g = getter;
|
|
@@ -441,8 +654,14 @@ function derived(getter, options) {
|
|
|
441
654
|
markDirty._c = 1;
|
|
442
655
|
markDirty._sig = cs;
|
|
443
656
|
track(() => {
|
|
444
|
-
|
|
445
|
-
|
|
657
|
+
let threw = true;
|
|
658
|
+
try {
|
|
659
|
+
cs._v = getter();
|
|
660
|
+
cs._d = false;
|
|
661
|
+
threw = false;
|
|
662
|
+
} finally {
|
|
663
|
+
if (threw) cs._d = true;
|
|
664
|
+
}
|
|
446
665
|
}, markDirty);
|
|
447
666
|
const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
448
667
|
let evaluating = false;
|
|
@@ -455,11 +674,16 @@ function derived(getter, options) {
|
|
|
455
674
|
if (trackingSuspended) {
|
|
456
675
|
if (cs._d) {
|
|
457
676
|
evaluating = true;
|
|
677
|
+
let threw = true;
|
|
458
678
|
try {
|
|
459
|
-
|
|
460
|
-
|
|
679
|
+
retrack(() => {
|
|
680
|
+
cs._v = getter();
|
|
681
|
+
cs._d = false;
|
|
682
|
+
threw = false;
|
|
683
|
+
}, markDirty);
|
|
461
684
|
} finally {
|
|
462
685
|
evaluating = false;
|
|
686
|
+
if (threw) cs._d = true;
|
|
463
687
|
}
|
|
464
688
|
}
|
|
465
689
|
return cs._v;
|
|
@@ -468,13 +692,17 @@ function derived(getter, options) {
|
|
|
468
692
|
if (cs._d) {
|
|
469
693
|
const oldValue = cs._v;
|
|
470
694
|
evaluating = true;
|
|
695
|
+
let threw = true;
|
|
471
696
|
try {
|
|
472
|
-
|
|
697
|
+
retrack(() => {
|
|
698
|
+
const next = getter();
|
|
699
|
+
cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
|
|
473
700
|
cs._d = false;
|
|
474
|
-
|
|
701
|
+
threw = false;
|
|
475
702
|
}, markDirty);
|
|
476
703
|
} finally {
|
|
477
704
|
evaluating = false;
|
|
705
|
+
if (threw) cs._d = true;
|
|
478
706
|
}
|
|
479
707
|
if (hook && oldValue !== cs._v) {
|
|
480
708
|
hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
|
|
@@ -501,12 +729,12 @@ function reduxAdapter(options) {
|
|
|
501
729
|
setState(store.getState());
|
|
502
730
|
});
|
|
503
731
|
});
|
|
504
|
-
function
|
|
732
|
+
function select(selector) {
|
|
505
733
|
return derived(() => selector(getState()));
|
|
506
734
|
}
|
|
507
735
|
const api = {
|
|
508
736
|
getState,
|
|
509
|
-
|
|
737
|
+
select,
|
|
510
738
|
dispatch: store.dispatch.bind(store),
|
|
511
739
|
destroy: unsubscribe
|
|
512
740
|
};
|
|
@@ -524,12 +752,12 @@ function zustandAdapter(options) {
|
|
|
524
752
|
setSibuState(state);
|
|
525
753
|
});
|
|
526
754
|
});
|
|
527
|
-
function
|
|
755
|
+
function select(selector) {
|
|
528
756
|
return derived(() => selector(getState()));
|
|
529
757
|
}
|
|
530
758
|
const api = {
|
|
531
759
|
getState,
|
|
532
|
-
|
|
760
|
+
select,
|
|
533
761
|
setState: store.setState.bind(store),
|
|
534
762
|
destroy() {
|
|
535
763
|
unsubscribe();
|
|
@@ -541,29 +769,79 @@ function zustandAdapter(options) {
|
|
|
541
769
|
}
|
|
542
770
|
|
|
543
771
|
// src/utils/sanitize.ts
|
|
772
|
+
var SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
|
|
544
773
|
function sanitizeUrl(url) {
|
|
545
774
|
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
546
775
|
if (!trimmed) return "";
|
|
547
776
|
const lower = trimmed.toLowerCase();
|
|
548
|
-
|
|
549
|
-
|
|
777
|
+
let schemeEnd = -1;
|
|
778
|
+
for (let i = 0; i < lower.length; i++) {
|
|
779
|
+
const ch = lower.charCodeAt(i);
|
|
780
|
+
if (ch === 58) {
|
|
781
|
+
schemeEnd = i;
|
|
782
|
+
break;
|
|
783
|
+
}
|
|
784
|
+
if (ch === 47 || ch === 63 || ch === 35) break;
|
|
550
785
|
}
|
|
786
|
+
if (schemeEnd === -1) return trimmed;
|
|
787
|
+
const scheme = lower.slice(0, schemeEnd + 1);
|
|
788
|
+
if (!/^[a-z][a-z0-9+.-]*:$/.test(scheme)) return trimmed;
|
|
789
|
+
if (SAFE_URL_PROTOCOLS.indexOf(scheme) === -1) return "";
|
|
551
790
|
return trimmed;
|
|
552
791
|
}
|
|
792
|
+
function sanitizeSrcset(value) {
|
|
793
|
+
const parts = value.split(",");
|
|
794
|
+
const out = [];
|
|
795
|
+
for (let i = 0; i < parts.length; i++) {
|
|
796
|
+
const part = parts[i].trim();
|
|
797
|
+
if (!part) continue;
|
|
798
|
+
const m = part.match(/^(\S+)(\s+.+)?$/);
|
|
799
|
+
if (!m) continue;
|
|
800
|
+
const safe = sanitizeUrl(m[1]);
|
|
801
|
+
if (!safe) continue;
|
|
802
|
+
out.push(m[2] ? `${safe}${m[2]}` : safe);
|
|
803
|
+
}
|
|
804
|
+
return out.join(", ");
|
|
805
|
+
}
|
|
553
806
|
function sanitizeCSSValue(value) {
|
|
554
|
-
const
|
|
555
|
-
|
|
807
|
+
const decoded = value.replace(/\\([0-9a-fA-F]{1,6})\s?/g, (_m, hex) => {
|
|
808
|
+
const code = Number.parseInt(hex, 16);
|
|
809
|
+
if (!Number.isFinite(code) || code < 0 || code > 1114111) return "";
|
|
810
|
+
try {
|
|
811
|
+
return String.fromCodePoint(code);
|
|
812
|
+
} catch {
|
|
813
|
+
return "";
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
const lower = decoded.toLowerCase().replace(/\s+/g, "");
|
|
817
|
+
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")) {
|
|
556
818
|
return "";
|
|
557
819
|
}
|
|
558
820
|
return value;
|
|
559
821
|
}
|
|
560
|
-
var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
822
|
+
var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
823
|
+
"href",
|
|
824
|
+
"xlink:href",
|
|
825
|
+
"src",
|
|
826
|
+
"action",
|
|
827
|
+
"formaction",
|
|
828
|
+
"formtarget",
|
|
829
|
+
"cite",
|
|
830
|
+
"poster",
|
|
831
|
+
"background",
|
|
832
|
+
"srcset",
|
|
833
|
+
"ping",
|
|
834
|
+
"data"
|
|
835
|
+
]);
|
|
561
836
|
function isUrlAttribute(attr) {
|
|
562
837
|
return URL_ATTRIBUTES.has(attr);
|
|
563
838
|
}
|
|
564
839
|
|
|
565
840
|
// src/reactivity/bindAttribute.ts
|
|
566
841
|
var _isDev4 = isDev();
|
|
842
|
+
function setProp(el, key, val) {
|
|
843
|
+
el[key] = val;
|
|
844
|
+
}
|
|
567
845
|
function isEventHandlerAttr(name) {
|
|
568
846
|
if (name.length < 3) return false;
|
|
569
847
|
const lower = name.toLowerCase();
|
|
@@ -589,7 +867,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
589
867
|
}
|
|
590
868
|
if (typeof value === "boolean") {
|
|
591
869
|
if (attr in el && (attr === "checked" || attr === "disabled" || attr === "selected")) {
|
|
592
|
-
el
|
|
870
|
+
setProp(el, attr, value);
|
|
593
871
|
} else if (value) {
|
|
594
872
|
el.setAttribute(attr, "");
|
|
595
873
|
} else {
|
|
@@ -599,7 +877,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
599
877
|
}
|
|
600
878
|
const str = String(value);
|
|
601
879
|
if ((attr === "value" || attr === "checked") && attr in el) {
|
|
602
|
-
el
|
|
880
|
+
setProp(el, attr, attr === "checked" ? Boolean(value) : str);
|
|
603
881
|
} else {
|
|
604
882
|
el.setAttribute(attr, isUrlAttribute(attr) ? sanitizeUrl(str) : str);
|
|
605
883
|
}
|
|
@@ -636,24 +914,29 @@ function bindChildNode(placeholder, getter) {
|
|
|
636
914
|
let newNodes;
|
|
637
915
|
if (Array.isArray(result)) {
|
|
638
916
|
newNodes = [];
|
|
917
|
+
const seen = /* @__PURE__ */ new Set();
|
|
639
918
|
for (let i = 0; i < result.length; i++) {
|
|
640
919
|
const item = result[i];
|
|
641
920
|
if (item == null || typeof item === "boolean") continue;
|
|
642
|
-
|
|
921
|
+
const node = item instanceof Node ? item : document.createTextNode(String(item));
|
|
922
|
+
if (seen.has(node)) {
|
|
923
|
+
if (_isDev5)
|
|
924
|
+
devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
|
|
925
|
+
continue;
|
|
926
|
+
}
|
|
927
|
+
seen.add(node);
|
|
928
|
+
newNodes.push(node);
|
|
643
929
|
}
|
|
644
930
|
} else {
|
|
645
931
|
const node = result instanceof Node ? result : document.createTextNode(String(result));
|
|
646
932
|
newNodes = [node];
|
|
647
933
|
}
|
|
648
|
-
|
|
649
|
-
if (
|
|
934
|
+
let reused;
|
|
935
|
+
if (lastNodes.length > 0 && newNodes.length > 0) {
|
|
936
|
+
const lastSet = new Set(lastNodes);
|
|
937
|
+
reused = /* @__PURE__ */ new Set();
|
|
650
938
|
for (let i = 0; i < newNodes.length; i++) {
|
|
651
|
-
|
|
652
|
-
if (newNodes[i] === lastNodes[j]) {
|
|
653
|
-
reused.add(newNodes[i]);
|
|
654
|
-
break;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
939
|
+
if (lastSet.has(newNodes[i])) reused.add(newNodes[i]);
|
|
657
940
|
}
|
|
658
941
|
}
|
|
659
942
|
for (let i = 0; i < lastNodes.length; i++) {
|
|
@@ -692,6 +975,30 @@ function registerDisposer(node, teardown) {
|
|
|
692
975
|
}
|
|
693
976
|
|
|
694
977
|
// src/core/rendering/tagFactory.ts
|
|
978
|
+
var _isDev7 = isDev();
|
|
979
|
+
var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
|
|
980
|
+
function validateTagName(tag) {
|
|
981
|
+
const lower = tag.toLowerCase();
|
|
982
|
+
if (BLOCKED_TAGS.has(lower)) {
|
|
983
|
+
throw new Error(`tagFactory: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
|
|
987
|
+
"config",
|
|
988
|
+
"location",
|
|
989
|
+
"history",
|
|
990
|
+
"document",
|
|
991
|
+
"window",
|
|
992
|
+
"navigator",
|
|
993
|
+
"name",
|
|
994
|
+
"top",
|
|
995
|
+
"parent",
|
|
996
|
+
"self",
|
|
997
|
+
"frames"
|
|
998
|
+
]);
|
|
999
|
+
function setProp2(el, key, val) {
|
|
1000
|
+
el[key] = val;
|
|
1001
|
+
}
|
|
695
1002
|
var kebabCache = /* @__PURE__ */ new Map();
|
|
696
1003
|
function toKebab(prop) {
|
|
697
1004
|
let cached = kebabCache.get(prop);
|
|
@@ -816,79 +1123,103 @@ function appendChildren(el, nodes) {
|
|
|
816
1123
|
}
|
|
817
1124
|
}
|
|
818
1125
|
}
|
|
819
|
-
var tagFactory = (tag, ns) =>
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
if (
|
|
824
|
-
|
|
825
|
-
|
|
1126
|
+
var tagFactory = (tag, ns) => {
|
|
1127
|
+
return (first, second) => {
|
|
1128
|
+
validateTagName(tag);
|
|
1129
|
+
const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
|
|
1130
|
+
if (first === void 0) return el;
|
|
1131
|
+
if (typeof first === "string") {
|
|
1132
|
+
if (second !== void 0) {
|
|
1133
|
+
el.setAttribute("class", first);
|
|
1134
|
+
appendChildren(el, second);
|
|
1135
|
+
return el;
|
|
1136
|
+
}
|
|
1137
|
+
el.textContent = first;
|
|
826
1138
|
return el;
|
|
827
1139
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
if (typeof first === "number") {
|
|
832
|
-
el.textContent = String(first);
|
|
833
|
-
return el;
|
|
834
|
-
}
|
|
835
|
-
if (Array.isArray(first) || first instanceof Node || typeof first === "function") {
|
|
836
|
-
appendChildren(el, first);
|
|
837
|
-
return el;
|
|
838
|
-
}
|
|
839
|
-
const props = first;
|
|
840
|
-
const pClass = props.class;
|
|
841
|
-
if (pClass != null) applyClass(el, pClass);
|
|
842
|
-
const pId = props.id;
|
|
843
|
-
if (pId != null) el.id = pId;
|
|
844
|
-
const pNodes = second !== void 0 ? second : props.nodes;
|
|
845
|
-
if (pNodes != null) appendChildren(el, pNodes);
|
|
846
|
-
const pOn = props.on;
|
|
847
|
-
if (pOn) {
|
|
848
|
-
for (const ev in pOn) {
|
|
849
|
-
el.addEventListener(ev, pOn[ev]);
|
|
1140
|
+
if (typeof first === "number") {
|
|
1141
|
+
el.textContent = String(first);
|
|
1142
|
+
return el;
|
|
850
1143
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
1144
|
+
if (Array.isArray(first) || first instanceof Node || typeof first === "function") {
|
|
1145
|
+
appendChildren(el, first);
|
|
1146
|
+
return el;
|
|
1147
|
+
}
|
|
1148
|
+
const props = first;
|
|
1149
|
+
const pClass = props.class;
|
|
1150
|
+
if (pClass != null) applyClass(el, pClass);
|
|
1151
|
+
const pId = props.id;
|
|
1152
|
+
if (pId != null) {
|
|
1153
|
+
if (_isDev7 && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
|
|
1154
|
+
devWarn(
|
|
1155
|
+
`tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
el.id = pId;
|
|
1159
|
+
}
|
|
1160
|
+
const pNodes = second !== void 0 ? second : props.nodes;
|
|
1161
|
+
if (pNodes != null) appendChildren(el, pNodes);
|
|
1162
|
+
const pOn = props.on;
|
|
1163
|
+
if (pOn) {
|
|
1164
|
+
for (const ev in pOn) {
|
|
1165
|
+
const handler = pOn[ev];
|
|
1166
|
+
if (typeof handler === "function") {
|
|
1167
|
+
el.addEventListener(ev, handler);
|
|
1168
|
+
} else if (_isDev7) {
|
|
1169
|
+
devWarn(
|
|
1170
|
+
`tagFactory: on.${ev} handler is not a function (got ${typeof handler}). Event listener was not attached.`
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
const pStyle = props.style;
|
|
1176
|
+
if (pStyle != null) applyStyle(el, pStyle);
|
|
1177
|
+
const pRef = props.ref;
|
|
1178
|
+
if (pRef) pRef.current = el;
|
|
1179
|
+
for (const key in props) {
|
|
1180
|
+
switch (key) {
|
|
1181
|
+
case "class":
|
|
1182
|
+
case "id":
|
|
1183
|
+
case "nodes":
|
|
1184
|
+
case "on":
|
|
1185
|
+
case "style":
|
|
1186
|
+
case "ref":
|
|
1187
|
+
case "onElement":
|
|
1188
|
+
continue;
|
|
1189
|
+
// already handled above / below
|
|
1190
|
+
default: {
|
|
1191
|
+
const value = props[key];
|
|
1192
|
+
if (value == null) continue;
|
|
1193
|
+
const lkey = key.toLowerCase();
|
|
1194
|
+
if (lkey[0] === "o" && lkey[1] === "n") continue;
|
|
1195
|
+
if (typeof value === "function") {
|
|
1196
|
+
registerDisposer(el, bindAttribute(el, key, value));
|
|
1197
|
+
} else if (typeof value === "boolean") {
|
|
1198
|
+
if (key in el && (key === "checked" || key === "disabled" || key === "selected")) {
|
|
1199
|
+
setProp2(el, key, value);
|
|
1200
|
+
} else if (value) {
|
|
1201
|
+
el.setAttribute(key, "");
|
|
1202
|
+
} else {
|
|
1203
|
+
el.removeAttribute(key);
|
|
1204
|
+
}
|
|
878
1205
|
} else {
|
|
879
|
-
|
|
1206
|
+
const str = String(value);
|
|
1207
|
+
if (lkey === "srcset") {
|
|
1208
|
+
el.setAttribute(key, sanitizeSrcset(str));
|
|
1209
|
+
} else if (isUrlAttribute(lkey)) {
|
|
1210
|
+
el.setAttribute(key, sanitizeUrl(str));
|
|
1211
|
+
} else {
|
|
1212
|
+
el.setAttribute(key, str);
|
|
1213
|
+
}
|
|
880
1214
|
}
|
|
881
|
-
} else {
|
|
882
|
-
const str = String(value);
|
|
883
|
-
el.setAttribute(key, isUrlAttribute(key) ? sanitizeUrl(str) : str);
|
|
884
1215
|
}
|
|
885
1216
|
}
|
|
886
1217
|
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
1218
|
+
if (props.onElement && typeof props.onElement === "function") {
|
|
1219
|
+
props.onElement(el);
|
|
1220
|
+
}
|
|
1221
|
+
return el;
|
|
1222
|
+
};
|
|
892
1223
|
};
|
|
893
1224
|
|
|
894
1225
|
// src/ecosystem/ui/componentAdapter.ts
|