sibujs 3.0.0 → 3.2.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 +6 -0
- package/dist/browser.cjs +16 -8
- package/dist/browser.js +6 -5
- package/dist/build.cjs +276 -150
- package/dist/build.js +35 -24
- package/dist/cdn.global.js +7 -7
- package/dist/{chunk-RJIRT46U.js → chunk-2C4E3HBM.js} +5 -5
- package/dist/{chunk-XDKP4T7G.js → chunk-4JCAUOLN.js} +45 -23
- package/dist/{chunk-VSNLICTS.js → chunk-5N74TKLD.js} +1 -1
- package/dist/{chunk-XVYB3J6C.js → chunk-7XDYVJLE.js} +19 -9
- package/dist/{chunk-L52H775O.js → chunk-BGNLPNGV.js} +20 -12
- package/dist/{chunk-6QZO7MMG.js → chunk-C427DVQF.js} +1 -1
- package/dist/{chunk-5WD7BYTZ.js → chunk-FDY42FIU.js} +3 -2
- package/dist/{chunk-4YTVESDX.js → chunk-FOI23UJL.js} +11 -1
- package/dist/{chunk-2RA7SHDA.js → chunk-GOJMFRBL.js} +20 -4
- package/dist/{chunk-2KM2724A.js → chunk-GOUM4JCT.js} +6 -6
- package/dist/chunk-H3SRKIYX.js +17 -0
- package/dist/{chunk-NEWH4O5U.js → chunk-H6PCHJZQ.js} +2 -2
- package/dist/{chunk-UCS6AMJ7.js → chunk-HMJFCBRR.js} +26 -3
- package/dist/{chunk-JYD2PWXH.js → chunk-HXMS4SNP.js} +22 -15
- package/dist/{chunk-DF3GTP4Q.js → chunk-JYXOEYI4.js} +12 -18
- package/dist/{chunk-KZA7ANXP.js → chunk-NFYWLRUO.js} +11 -18
- package/dist/{chunk-KH4OE6WY.js → chunk-NPIEEKPT.js} +20 -11
- package/dist/{chunk-V65KTDZW.js → chunk-OYLPZO4N.js} +33 -15
- package/dist/{chunk-LYTCUZ7H.js → chunk-RDRSWYNP.js} +1 -1
- package/dist/{chunk-UKMXT5T6.js → chunk-RLUJL2MV.js} +7 -12
- package/dist/{chunk-INBOWHQ3.js → chunk-V2MTG5FT.js} +99 -36
- package/dist/{chunk-CNZ35WI2.js → chunk-VJE6DDYM.js} +2 -2
- package/dist/{chunk-2JQUV4Y3.js → chunk-VOCE4NNK.js} +157 -75
- package/dist/{chunk-STFTTMO2.js → chunk-X67UYC74.js} +31 -12
- package/dist/{chunk-YMOIAHWA.js → chunk-YFDGQWDA.js} +1 -1
- package/dist/{chunk-L4DAT4WU.js → chunk-Z2FWAE4B.js} +28 -1
- package/dist/data.cjs +211 -93
- package/dist/data.d.cts +7 -1
- package/dist/data.d.ts +7 -1
- package/dist/data.js +8 -8
- package/dist/devtools.cjs +38 -10
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +6 -6
- package/dist/ecosystem.cjs +163 -65
- package/dist/ecosystem.js +9 -9
- package/dist/extras.cjs +420 -198
- package/dist/extras.d.cts +2 -2
- package/dist/extras.d.ts +2 -2
- package/dist/extras.js +27 -24
- package/dist/index.cjs +255 -139
- package/dist/index.d.cts +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.js +15 -13
- package/dist/{introspect-BZWKvQUZ.d.ts → introspect-DOZfmC-4.d.ts} +1 -1
- package/dist/{introspect-DsJlDD2T.d.cts → introspect-RjLfIFpL.d.cts} +1 -1
- package/dist/motion.cjs +10 -0
- package/dist/motion.js +3 -3
- package/dist/patterns.cjs +66 -39
- package/dist/patterns.js +8 -7
- package/dist/performance.cjs +101 -25
- package/dist/performance.d.cts +2 -2
- package/dist/performance.d.ts +2 -2
- package/dist/performance.js +8 -7
- package/dist/plugins.cjs +243 -138
- package/dist/plugins.d.cts +1 -1
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js +96 -45
- package/dist/{ssr-FXD2PPMC.js → ssr-2QDQ27EV.js} +5 -3
- package/dist/{ssr-CrVNy6Pa.d.cts → ssr-D62yFwuw.d.cts} +8 -1
- package/dist/{ssr-CrVNy6Pa.d.ts → ssr-D62yFwuw.d.ts} +8 -1
- package/dist/ssr.cjs +185 -68
- package/dist/ssr.d.cts +1 -1
- package/dist/ssr.d.ts +1 -1
- package/dist/ssr.js +12 -10
- package/dist/testing.cjs +9 -4
- package/dist/testing.js +3 -3
- package/dist/ui.cjs +76 -39
- package/dist/ui.js +10 -9
- package/dist/widgets.cjs +61 -23
- package/dist/widgets.js +8 -8
- package/package.json +3 -1
package/dist/extras.cjs
CHANGED
|
@@ -164,6 +164,7 @@ __export(extras_exports, {
|
|
|
164
164
|
inspectSignal: () => inspectSignal,
|
|
165
165
|
intersection: () => intersection,
|
|
166
166
|
invalidateQueries: () => invalidateQueries,
|
|
167
|
+
isDangerousMetaRefresh: () => isDangerousMetaRefresh,
|
|
167
168
|
isDebugEnabled: () => isDebugEnabled,
|
|
168
169
|
isHMRAvailable: () => isHMRAvailable,
|
|
169
170
|
isWasmCached: () => isWasmCached,
|
|
@@ -459,7 +460,7 @@ function retrack(effectFn, subscriber) {
|
|
|
459
460
|
}
|
|
460
461
|
}
|
|
461
462
|
function track(effectFn, subscriber) {
|
|
462
|
-
if (!subscriber)
|
|
463
|
+
if (!subscriber) return reactiveBinding(effectFn);
|
|
463
464
|
cleanup(subscriber);
|
|
464
465
|
const prev = currentSubscriber;
|
|
465
466
|
currentSubscriber = subscriber;
|
|
@@ -477,6 +478,32 @@ function track(effectFn, subscriber) {
|
|
|
477
478
|
const sub2 = subscriber;
|
|
478
479
|
return sub2._dispose ?? (sub2._dispose = () => cleanup(subscriber));
|
|
479
480
|
}
|
|
481
|
+
function reactiveBinding(commit) {
|
|
482
|
+
const run = () => {
|
|
483
|
+
const s2 = subscriber;
|
|
484
|
+
if (s2._disposed || s2._reentrant) return;
|
|
485
|
+
s2._reentrant = true;
|
|
486
|
+
try {
|
|
487
|
+
retrack(commit, subscriber);
|
|
488
|
+
} finally {
|
|
489
|
+
s2._reentrant = false;
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
const subscriber = run;
|
|
493
|
+
subscriber.depsHead = null;
|
|
494
|
+
subscriber.depsTail = null;
|
|
495
|
+
subscriber._epoch = 0;
|
|
496
|
+
subscriber._structDirty = false;
|
|
497
|
+
subscriber._runEpoch = 0;
|
|
498
|
+
subscriber._runs = 0;
|
|
499
|
+
subscriber._reentrant = false;
|
|
500
|
+
subscriber._disposed = false;
|
|
501
|
+
run();
|
|
502
|
+
return subscriber._dispose ?? (subscriber._dispose = () => {
|
|
503
|
+
subscriber._disposed = true;
|
|
504
|
+
cleanup(subscriber);
|
|
505
|
+
});
|
|
506
|
+
}
|
|
480
507
|
function recordDependency(signal2) {
|
|
481
508
|
if (!currentSubscriber) return;
|
|
482
509
|
const sub2 = currentSubscriber;
|
|
@@ -686,6 +713,7 @@ function derived(getter, options) {
|
|
|
686
713
|
const equals = options?.equals;
|
|
687
714
|
const cs = {};
|
|
688
715
|
cs._d = false;
|
|
716
|
+
cs._init = false;
|
|
689
717
|
cs._g = getter;
|
|
690
718
|
cs.__v = 0;
|
|
691
719
|
const markDirty = () => {
|
|
@@ -694,11 +722,18 @@ function derived(getter, options) {
|
|
|
694
722
|
};
|
|
695
723
|
markDirty._c = 1;
|
|
696
724
|
markDirty._sig = cs;
|
|
725
|
+
const recompute = () => {
|
|
726
|
+
const next = getter();
|
|
727
|
+
cs._v = equals && cs._init ? equals(cs._v, next) ? cs._v : next : next;
|
|
728
|
+
cs._d = false;
|
|
729
|
+
cs._init = true;
|
|
730
|
+
};
|
|
697
731
|
track(() => {
|
|
698
732
|
let threw = true;
|
|
699
733
|
try {
|
|
700
734
|
cs._v = getter();
|
|
701
735
|
cs._d = false;
|
|
736
|
+
cs._init = true;
|
|
702
737
|
threw = false;
|
|
703
738
|
} finally {
|
|
704
739
|
if (threw) cs._d = true;
|
|
@@ -714,20 +749,13 @@ function derived(getter, options) {
|
|
|
714
749
|
}
|
|
715
750
|
if (trackingSuspended) {
|
|
716
751
|
if (cs._d) {
|
|
752
|
+
const prev = cs._v;
|
|
717
753
|
evaluating = true;
|
|
718
|
-
let threw = true;
|
|
719
754
|
try {
|
|
720
|
-
|
|
721
|
-
retrack(() => {
|
|
722
|
-
const next = getter();
|
|
723
|
-
cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
|
|
724
|
-
cs._d = false;
|
|
725
|
-
threw = false;
|
|
726
|
-
}, markDirty);
|
|
755
|
+
retrack(recompute, markDirty);
|
|
727
756
|
if (!Object.is(prev, cs._v)) cs.__v++;
|
|
728
757
|
} finally {
|
|
729
758
|
evaluating = false;
|
|
730
|
-
if (threw) cs._d = true;
|
|
731
759
|
}
|
|
732
760
|
}
|
|
733
761
|
return cs._v;
|
|
@@ -736,18 +764,11 @@ function derived(getter, options) {
|
|
|
736
764
|
if (cs._d) {
|
|
737
765
|
const oldValue = cs._v;
|
|
738
766
|
evaluating = true;
|
|
739
|
-
let threw = true;
|
|
740
767
|
try {
|
|
741
|
-
retrack(
|
|
742
|
-
const next = getter();
|
|
743
|
-
cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
|
|
744
|
-
cs._d = false;
|
|
745
|
-
threw = false;
|
|
746
|
-
}, markDirty);
|
|
768
|
+
retrack(recompute, markDirty);
|
|
747
769
|
if (!Object.is(oldValue, cs._v)) cs.__v++;
|
|
748
770
|
} finally {
|
|
749
771
|
evaluating = false;
|
|
750
|
-
if (threw) cs._d = true;
|
|
751
772
|
}
|
|
752
773
|
if (hook && oldValue !== cs._v) {
|
|
753
774
|
hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
|
|
@@ -768,11 +789,15 @@ function derived(getter, options) {
|
|
|
768
789
|
var als = null;
|
|
769
790
|
try {
|
|
770
791
|
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
792
|
+
let mod = null;
|
|
793
|
+
const getBuiltin = process.getBuiltinModule;
|
|
794
|
+
if (typeof getBuiltin === "function") {
|
|
795
|
+
mod = getBuiltin("node:async_hooks");
|
|
796
|
+
} else {
|
|
797
|
+
const req = Function("return typeof require==='function'?require:null")();
|
|
798
|
+
if (req) mod = req("node:async_hooks");
|
|
775
799
|
}
|
|
800
|
+
if (mod) als = new mod.AsyncLocalStorage();
|
|
776
801
|
}
|
|
777
802
|
} catch {
|
|
778
803
|
als = null;
|
|
@@ -788,6 +813,17 @@ function getSSRStore() {
|
|
|
788
813
|
function isSSR() {
|
|
789
814
|
return getSSRStore().ssr;
|
|
790
815
|
}
|
|
816
|
+
function getRequestScopedCache(name) {
|
|
817
|
+
if (!isSSR()) return null;
|
|
818
|
+
const store = getSSRStore();
|
|
819
|
+
const caches = store.caches ?? (store.caches = /* @__PURE__ */ new Map());
|
|
820
|
+
let c = caches.get(name);
|
|
821
|
+
if (!c) {
|
|
822
|
+
c = /* @__PURE__ */ new Map();
|
|
823
|
+
caches.set(name, c);
|
|
824
|
+
}
|
|
825
|
+
return c;
|
|
826
|
+
}
|
|
791
827
|
|
|
792
828
|
// src/core/signals/effect.ts
|
|
793
829
|
var _g = globalThis;
|
|
@@ -874,6 +910,7 @@ function effect(effectFn, options) {
|
|
|
874
910
|
ctx.fn(ctx.onCleanup);
|
|
875
911
|
};
|
|
876
912
|
const sub2 = (() => {
|
|
913
|
+
if (ctx.disposed) return;
|
|
877
914
|
if (ctx.running) {
|
|
878
915
|
ctx.rerunPending = true;
|
|
879
916
|
return;
|
|
@@ -1070,9 +1107,12 @@ async function withRetry(fn, options, onRetry, signal2) {
|
|
|
1070
1107
|
}
|
|
1071
1108
|
|
|
1072
1109
|
// src/data/query.ts
|
|
1073
|
-
var
|
|
1074
|
-
function
|
|
1075
|
-
|
|
1110
|
+
var globalQueryCache = /* @__PURE__ */ new Map();
|
|
1111
|
+
function getActiveQueryCache() {
|
|
1112
|
+
return getRequestScopedCache("query") ?? globalQueryCache;
|
|
1113
|
+
}
|
|
1114
|
+
function getOrCreateEntry(cache, key, initialData) {
|
|
1115
|
+
let entry = cache.get(key);
|
|
1076
1116
|
if (!entry) {
|
|
1077
1117
|
entry = {
|
|
1078
1118
|
data: initialData,
|
|
@@ -1084,7 +1124,7 @@ function getOrCreateEntry(key, initialData) {
|
|
|
1084
1124
|
listeners: /* @__PURE__ */ new Set(),
|
|
1085
1125
|
refetchers: /* @__PURE__ */ new Set()
|
|
1086
1126
|
};
|
|
1087
|
-
|
|
1127
|
+
cache.set(key, entry);
|
|
1088
1128
|
}
|
|
1089
1129
|
return entry;
|
|
1090
1130
|
}
|
|
@@ -1104,6 +1144,7 @@ function query(key, fetcher, options = {}) {
|
|
|
1104
1144
|
select: select3
|
|
1105
1145
|
} = options;
|
|
1106
1146
|
const resolveKey = typeof key === "function" ? key : () => key;
|
|
1147
|
+
const cache = getActiveQueryCache();
|
|
1107
1148
|
const [data2, setData] = signal(initialData);
|
|
1108
1149
|
const [isFetching, setIsFetching] = signal(false);
|
|
1109
1150
|
const [error, setError] = signal(void 0);
|
|
@@ -1115,16 +1156,16 @@ function query(key, fetcher, options = {}) {
|
|
|
1115
1156
|
const isStale = derived(() => {
|
|
1116
1157
|
data2();
|
|
1117
1158
|
if (!currentKey) return true;
|
|
1118
|
-
const entry =
|
|
1159
|
+
const entry = cache.get(currentKey);
|
|
1119
1160
|
if (!entry || entry.dataUpdatedAt === 0) return true;
|
|
1120
1161
|
return Date.now() - entry.dataUpdatedAt >= staleTime;
|
|
1121
1162
|
});
|
|
1122
1163
|
async function doFetch() {
|
|
1123
1164
|
if (disposed || !currentKey || !enabled) return;
|
|
1124
1165
|
const key2 = currentKey;
|
|
1125
|
-
let entry =
|
|
1166
|
+
let entry = cache.get(key2);
|
|
1126
1167
|
if (!entry) {
|
|
1127
|
-
entry = getOrCreateEntry(key2);
|
|
1168
|
+
entry = getOrCreateEntry(cache, key2);
|
|
1128
1169
|
entry.listeners.add(onCacheUpdate);
|
|
1129
1170
|
entry.refetchers.add(doFetch);
|
|
1130
1171
|
}
|
|
@@ -1199,7 +1240,7 @@ function query(key, fetcher, options = {}) {
|
|
|
1199
1240
|
}
|
|
1200
1241
|
function onCacheUpdate() {
|
|
1201
1242
|
if (disposed || !currentKey) return;
|
|
1202
|
-
const entry =
|
|
1243
|
+
const entry = cache.get(currentKey);
|
|
1203
1244
|
if (!entry) {
|
|
1204
1245
|
batch(() => {
|
|
1205
1246
|
setData(void 0);
|
|
@@ -1219,7 +1260,7 @@ function query(key, fetcher, options = {}) {
|
|
|
1219
1260
|
const effectCleanup = effect(() => {
|
|
1220
1261
|
const key2 = resolveKey();
|
|
1221
1262
|
if (currentKey !== null && currentKey !== key2) {
|
|
1222
|
-
const oldEntry =
|
|
1263
|
+
const oldEntry = cache.get(currentKey);
|
|
1223
1264
|
if (oldEntry) {
|
|
1224
1265
|
oldEntry.listeners.delete(onCacheUpdate);
|
|
1225
1266
|
oldEntry.refetchers.delete(doFetch);
|
|
@@ -1227,13 +1268,13 @@ function query(key, fetcher, options = {}) {
|
|
|
1227
1268
|
if (oldEntry.subscribers <= 0 && cacheTime >= 0) {
|
|
1228
1269
|
const oldKey = currentKey;
|
|
1229
1270
|
if (oldEntry.gcTimer !== null) clearTimeout(oldEntry.gcTimer);
|
|
1230
|
-
oldEntry.gcTimer = setTimeout(() =>
|
|
1271
|
+
oldEntry.gcTimer = setTimeout(() => cache.delete(oldKey), cacheTime);
|
|
1231
1272
|
}
|
|
1232
1273
|
}
|
|
1233
1274
|
}
|
|
1234
1275
|
const keyChanged = currentKey !== key2;
|
|
1235
1276
|
currentKey = key2;
|
|
1236
|
-
const entry = getOrCreateEntry(key2, initialData);
|
|
1277
|
+
const entry = getOrCreateEntry(cache, key2, initialData);
|
|
1237
1278
|
if (keyChanged) entry.subscribers++;
|
|
1238
1279
|
if (entry.gcTimer !== null) {
|
|
1239
1280
|
clearTimeout(entry.gcTimer);
|
|
@@ -1287,7 +1328,7 @@ function query(key, fetcher, options = {}) {
|
|
|
1287
1328
|
effectCleanup();
|
|
1288
1329
|
if (intervalTimer) clearInterval(intervalTimer);
|
|
1289
1330
|
if (currentKey) {
|
|
1290
|
-
const entry =
|
|
1331
|
+
const entry = cache.get(currentKey);
|
|
1291
1332
|
if (entry) {
|
|
1292
1333
|
entry.listeners.delete(onCacheUpdate);
|
|
1293
1334
|
entry.refetchers.delete(doFetch);
|
|
@@ -1295,7 +1336,7 @@ function query(key, fetcher, options = {}) {
|
|
|
1295
1336
|
if (entry.subscribers <= 0 && cacheTime >= 0) {
|
|
1296
1337
|
const key2 = currentKey;
|
|
1297
1338
|
if (entry.gcTimer !== null) clearTimeout(entry.gcTimer);
|
|
1298
|
-
entry.gcTimer = setTimeout(() =>
|
|
1339
|
+
entry.gcTimer = setTimeout(() => cache.delete(key2), cacheTime);
|
|
1299
1340
|
}
|
|
1300
1341
|
}
|
|
1301
1342
|
}
|
|
@@ -1318,7 +1359,7 @@ function query(key, fetcher, options = {}) {
|
|
|
1318
1359
|
}
|
|
1319
1360
|
function invalidateQueries(keyOrPredicate) {
|
|
1320
1361
|
const predicate = typeof keyOrPredicate === "function" ? keyOrPredicate : (k) => k === keyOrPredicate;
|
|
1321
|
-
for (const [key, entry] of
|
|
1362
|
+
for (const [key, entry] of getActiveQueryCache().entries()) {
|
|
1322
1363
|
if (predicate(key)) {
|
|
1323
1364
|
entry.dataUpdatedAt = 0;
|
|
1324
1365
|
for (const refetcher of entry.refetchers) refetcher();
|
|
@@ -1326,10 +1367,10 @@ function invalidateQueries(keyOrPredicate) {
|
|
|
1326
1367
|
}
|
|
1327
1368
|
}
|
|
1328
1369
|
function getQueryData(key) {
|
|
1329
|
-
return
|
|
1370
|
+
return getActiveQueryCache().get(key)?.data;
|
|
1330
1371
|
}
|
|
1331
1372
|
function setQueryData(key, data2) {
|
|
1332
|
-
const entry =
|
|
1373
|
+
const entry = getActiveQueryCache().get(key);
|
|
1333
1374
|
if (!entry) return;
|
|
1334
1375
|
const newData = typeof data2 === "function" ? data2(entry.data) : data2;
|
|
1335
1376
|
entry.data = newData;
|
|
@@ -1339,14 +1380,15 @@ function setQueryData(key, data2) {
|
|
|
1339
1380
|
function clearQueryCache() {
|
|
1340
1381
|
const activeListeners = [];
|
|
1341
1382
|
const activeRefetchers = [];
|
|
1342
|
-
|
|
1383
|
+
const activeCache = getActiveQueryCache();
|
|
1384
|
+
for (const entry of activeCache.values()) {
|
|
1343
1385
|
if (entry.gcTimer) clearTimeout(entry.gcTimer);
|
|
1344
1386
|
if (entry.subscribers > 0) {
|
|
1345
1387
|
for (const listener of entry.listeners) activeListeners.push(listener);
|
|
1346
1388
|
for (const refetcher of entry.refetchers) activeRefetchers.push(refetcher);
|
|
1347
1389
|
}
|
|
1348
1390
|
}
|
|
1349
|
-
|
|
1391
|
+
activeCache.clear();
|
|
1350
1392
|
for (const listener of activeListeners) listener();
|
|
1351
1393
|
for (const refetcher of activeRefetchers) {
|
|
1352
1394
|
refetcher().catch((err) => {
|
|
@@ -1357,10 +1399,11 @@ function clearQueryCache() {
|
|
|
1357
1399
|
}
|
|
1358
1400
|
}
|
|
1359
1401
|
function __resetQueryCache() {
|
|
1360
|
-
|
|
1402
|
+
const activeCache = getActiveQueryCache();
|
|
1403
|
+
for (const entry of activeCache.values()) {
|
|
1361
1404
|
if (entry.gcTimer) clearTimeout(entry.gcTimer);
|
|
1362
1405
|
}
|
|
1363
|
-
|
|
1406
|
+
activeCache.clear();
|
|
1364
1407
|
}
|
|
1365
1408
|
|
|
1366
1409
|
// src/data/mutation.ts
|
|
@@ -1372,7 +1415,11 @@ function mutation(mutationFn, options = {}) {
|
|
|
1372
1415
|
const isSuccess = derived(() => status() === "success");
|
|
1373
1416
|
const isIdle = derived(() => status() === "idle");
|
|
1374
1417
|
let runId = 0;
|
|
1418
|
+
let abortController = null;
|
|
1375
1419
|
async function execute(variables) {
|
|
1420
|
+
abortController?.abort();
|
|
1421
|
+
abortController = new AbortController();
|
|
1422
|
+
const signal2 = abortController.signal;
|
|
1376
1423
|
const myRun = ++runId;
|
|
1377
1424
|
let context2;
|
|
1378
1425
|
batch(() => {
|
|
@@ -1384,7 +1431,7 @@ function mutation(mutationFn, options = {}) {
|
|
|
1384
1431
|
if (options.onMutate) {
|
|
1385
1432
|
context2 = await options.onMutate(variables);
|
|
1386
1433
|
}
|
|
1387
|
-
const result = await withRetry(() => mutationFn(variables), options.retry);
|
|
1434
|
+
const result = await withRetry(() => mutationFn(variables, signal2), options.retry, void 0, signal2);
|
|
1388
1435
|
if (myRun !== runId) return result;
|
|
1389
1436
|
batch(() => {
|
|
1390
1437
|
setData(result);
|
|
@@ -1396,6 +1443,7 @@ function mutation(mutationFn, options = {}) {
|
|
|
1396
1443
|
return result;
|
|
1397
1444
|
} catch (err) {
|
|
1398
1445
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
1446
|
+
if (errorObj instanceof DOMException && errorObj.name === "AbortError") throw errorObj;
|
|
1399
1447
|
if (myRun !== runId) throw errorObj;
|
|
1400
1448
|
batch(() => {
|
|
1401
1449
|
setError(errorObj);
|
|
@@ -1409,6 +1457,8 @@ function mutation(mutationFn, options = {}) {
|
|
|
1409
1457
|
}
|
|
1410
1458
|
function reset() {
|
|
1411
1459
|
runId++;
|
|
1460
|
+
abortController?.abort();
|
|
1461
|
+
abortController = null;
|
|
1412
1462
|
batch(() => {
|
|
1413
1463
|
setData(void 0);
|
|
1414
1464
|
setError(void 0);
|
|
@@ -1424,6 +1474,7 @@ function mutation(mutationFn, options = {}) {
|
|
|
1424
1474
|
isIdle,
|
|
1425
1475
|
mutate: (variables) => {
|
|
1426
1476
|
execute(variables).catch((err) => {
|
|
1477
|
+
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
1427
1478
|
if (typeof console !== "undefined") {
|
|
1428
1479
|
console.warn("[SibuJS mutation] mutate() failed; check `.error()` signal or onError option.", err);
|
|
1429
1480
|
}
|
|
@@ -1440,6 +1491,7 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
1440
1491
|
getNextPageParam,
|
|
1441
1492
|
getPreviousPageParam,
|
|
1442
1493
|
initialPageParam = 0,
|
|
1494
|
+
maxPages,
|
|
1443
1495
|
enabled = true,
|
|
1444
1496
|
retry: retryOptions,
|
|
1445
1497
|
onSuccess,
|
|
@@ -1463,8 +1515,9 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
1463
1515
|
let abortController = null;
|
|
1464
1516
|
let disposed = false;
|
|
1465
1517
|
let runId = 0;
|
|
1466
|
-
|
|
1467
|
-
|
|
1518
|
+
let inFlight = null;
|
|
1519
|
+
function fetchPage(pageParam, direction) {
|
|
1520
|
+
if (disposed) return Promise.resolve();
|
|
1468
1521
|
abortController?.abort();
|
|
1469
1522
|
abortController = new AbortController();
|
|
1470
1523
|
const signal2 = abortController.signal;
|
|
@@ -1475,39 +1528,44 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
1475
1528
|
if (direction === "prev") setIsFetchingPrev(true);
|
|
1476
1529
|
setError(void 0);
|
|
1477
1530
|
});
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
newPages
|
|
1485
|
-
|
|
1486
|
-
|
|
1531
|
+
const promise = (async () => {
|
|
1532
|
+
try {
|
|
1533
|
+
const page = await withRetry(() => fetcher({ signal: signal2, pageParam }), retryOptions, void 0, signal2);
|
|
1534
|
+
if (disposed || myRun !== runId) return;
|
|
1535
|
+
const currentPages = pages();
|
|
1536
|
+
let newPages = direction === "prev" ? [page, ...currentPages] : [...currentPages, page];
|
|
1537
|
+
if (maxPages != null && maxPages > 0 && newPages.length > maxPages) {
|
|
1538
|
+
newPages = direction === "prev" ? newPages.slice(0, maxPages) : newPages.slice(newPages.length - maxPages);
|
|
1539
|
+
}
|
|
1540
|
+
const nextParam = getNextPageParam(newPages[newPages.length - 1], newPages);
|
|
1541
|
+
const prevParam = getPreviousPageParam?.(newPages[0], newPages);
|
|
1542
|
+
batch(() => {
|
|
1543
|
+
setPages(newPages);
|
|
1544
|
+
setNextPageParam(nextParam);
|
|
1545
|
+
setPrevPageParam(prevParam);
|
|
1546
|
+
setIsFetching(false);
|
|
1547
|
+
setIsFetchingNext(false);
|
|
1548
|
+
setIsFetchingPrev(false);
|
|
1549
|
+
});
|
|
1550
|
+
onSuccess?.(newPages);
|
|
1551
|
+
} catch (err) {
|
|
1552
|
+
if (disposed || myRun !== runId) return;
|
|
1553
|
+
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
1554
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
1555
|
+
batch(() => {
|
|
1556
|
+
setError(errorObj);
|
|
1557
|
+
setIsFetching(false);
|
|
1558
|
+
setIsFetchingNext(false);
|
|
1559
|
+
setIsFetchingPrev(false);
|
|
1560
|
+
});
|
|
1561
|
+
onError?.(errorObj);
|
|
1487
1562
|
}
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
setIsFetching(false);
|
|
1495
|
-
setIsFetchingNext(false);
|
|
1496
|
-
setIsFetchingPrev(false);
|
|
1497
|
-
});
|
|
1498
|
-
onSuccess?.(newPages);
|
|
1499
|
-
} catch (err) {
|
|
1500
|
-
if (disposed || myRun !== runId) return;
|
|
1501
|
-
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
1502
|
-
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
1503
|
-
batch(() => {
|
|
1504
|
-
setError(errorObj);
|
|
1505
|
-
setIsFetching(false);
|
|
1506
|
-
setIsFetchingNext(false);
|
|
1507
|
-
setIsFetchingPrev(false);
|
|
1508
|
-
});
|
|
1509
|
-
onError?.(errorObj);
|
|
1510
|
-
}
|
|
1563
|
+
})();
|
|
1564
|
+
inFlight = promise;
|
|
1565
|
+
void promise.finally(() => {
|
|
1566
|
+
if (inFlight === promise) inFlight = null;
|
|
1567
|
+
});
|
|
1568
|
+
return promise;
|
|
1511
1569
|
}
|
|
1512
1570
|
const effectCleanup = effect(() => {
|
|
1513
1571
|
resolveKey();
|
|
@@ -1522,11 +1580,13 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
1522
1580
|
}
|
|
1523
1581
|
});
|
|
1524
1582
|
function fetchNextPage() {
|
|
1583
|
+
if (inFlight) return inFlight;
|
|
1525
1584
|
const param2 = nextPageParam();
|
|
1526
1585
|
if (param2 === void 0) return Promise.resolve();
|
|
1527
1586
|
return fetchPage(param2, "next");
|
|
1528
1587
|
}
|
|
1529
1588
|
function fetchPreviousPage() {
|
|
1589
|
+
if (inFlight) return inFlight;
|
|
1530
1590
|
const param2 = prevPageParam();
|
|
1531
1591
|
if (param2 === void 0) return Promise.resolve();
|
|
1532
1592
|
return fetchPage(param2, "prev");
|
|
@@ -1565,13 +1625,17 @@ function infiniteQuery(key, fetcher, options) {
|
|
|
1565
1625
|
function previous(getter) {
|
|
1566
1626
|
const [previous2, setPrevious] = signal(void 0);
|
|
1567
1627
|
let current = getter();
|
|
1568
|
-
effect(() => {
|
|
1628
|
+
const stop2 = effect(() => {
|
|
1569
1629
|
const next = getter();
|
|
1570
1630
|
if (!Object.is(next, current)) {
|
|
1571
1631
|
setPrevious(current);
|
|
1572
1632
|
current = next;
|
|
1573
1633
|
}
|
|
1574
1634
|
});
|
|
1635
|
+
Object.defineProperty(previous2, "dispose", {
|
|
1636
|
+
value: stop2,
|
|
1637
|
+
enumerable: false
|
|
1638
|
+
});
|
|
1575
1639
|
return previous2;
|
|
1576
1640
|
}
|
|
1577
1641
|
|
|
@@ -1579,7 +1643,7 @@ function previous(getter) {
|
|
|
1579
1643
|
function debounce(getter, delay) {
|
|
1580
1644
|
const [debounced, setDebounced] = signal(getter());
|
|
1581
1645
|
let timer = null;
|
|
1582
|
-
effect(() => {
|
|
1646
|
+
const stop2 = effect(() => {
|
|
1583
1647
|
const value = getter();
|
|
1584
1648
|
if (timer !== null) clearTimeout(timer);
|
|
1585
1649
|
timer = setTimeout(() => {
|
|
@@ -1587,6 +1651,16 @@ function debounce(getter, delay) {
|
|
|
1587
1651
|
timer = null;
|
|
1588
1652
|
}, delay);
|
|
1589
1653
|
});
|
|
1654
|
+
Object.defineProperty(debounced, "dispose", {
|
|
1655
|
+
value: () => {
|
|
1656
|
+
stop2();
|
|
1657
|
+
if (timer !== null) {
|
|
1658
|
+
clearTimeout(timer);
|
|
1659
|
+
timer = null;
|
|
1660
|
+
}
|
|
1661
|
+
},
|
|
1662
|
+
enumerable: false
|
|
1663
|
+
});
|
|
1590
1664
|
return debounced;
|
|
1591
1665
|
}
|
|
1592
1666
|
|
|
@@ -1596,7 +1670,8 @@ function throttle(getter, interval) {
|
|
|
1596
1670
|
let cooldown = false;
|
|
1597
1671
|
let pending = null;
|
|
1598
1672
|
let lastEmitted = getter();
|
|
1599
|
-
|
|
1673
|
+
let timer = null;
|
|
1674
|
+
const stop2 = effect(() => {
|
|
1600
1675
|
const value = getter();
|
|
1601
1676
|
if (!cooldown) {
|
|
1602
1677
|
if (!Object.is(value, lastEmitted)) {
|
|
@@ -1604,7 +1679,8 @@ function throttle(getter, interval) {
|
|
|
1604
1679
|
lastEmitted = value;
|
|
1605
1680
|
cooldown = true;
|
|
1606
1681
|
pending = null;
|
|
1607
|
-
setTimeout(() => {
|
|
1682
|
+
timer = setTimeout(() => {
|
|
1683
|
+
timer = null;
|
|
1608
1684
|
cooldown = false;
|
|
1609
1685
|
if (pending !== null) {
|
|
1610
1686
|
const trailingValue = pending.value;
|
|
@@ -1618,6 +1694,16 @@ function throttle(getter, interval) {
|
|
|
1618
1694
|
pending = { value };
|
|
1619
1695
|
}
|
|
1620
1696
|
});
|
|
1697
|
+
Object.defineProperty(throttled, "dispose", {
|
|
1698
|
+
value: () => {
|
|
1699
|
+
stop2();
|
|
1700
|
+
if (timer !== null) {
|
|
1701
|
+
clearTimeout(timer);
|
|
1702
|
+
timer = null;
|
|
1703
|
+
}
|
|
1704
|
+
},
|
|
1705
|
+
enumerable: false
|
|
1706
|
+
});
|
|
1621
1707
|
return throttled;
|
|
1622
1708
|
}
|
|
1623
1709
|
|
|
@@ -1746,28 +1832,45 @@ function idbGet(db, store, key) {
|
|
|
1746
1832
|
req.onerror = () => reject(req.error);
|
|
1747
1833
|
});
|
|
1748
1834
|
}
|
|
1749
|
-
function idbPut(db, store, item) {
|
|
1835
|
+
function idbPut(db, store, item, key) {
|
|
1750
1836
|
return new Promise((resolve, reject) => {
|
|
1751
1837
|
const tx = db.transaction(store, "readwrite");
|
|
1752
|
-
tx.objectStore(store).put(item);
|
|
1838
|
+
if (key !== void 0) tx.objectStore(store).put(item, key);
|
|
1839
|
+
else tx.objectStore(store).put(item);
|
|
1753
1840
|
tx.oncomplete = () => resolve();
|
|
1754
1841
|
tx.onerror = () => reject(tx.error);
|
|
1755
1842
|
});
|
|
1756
1843
|
}
|
|
1757
|
-
function
|
|
1844
|
+
function coalesceAndAddChange(tx, change, keyPath) {
|
|
1845
|
+
const store = tx.objectStore("_changes");
|
|
1846
|
+
const targetKey = change.item[keyPath];
|
|
1847
|
+
const cursorReq = store.openCursor();
|
|
1848
|
+
cursorReq.onsuccess = () => {
|
|
1849
|
+
const cursor = cursorReq.result;
|
|
1850
|
+
if (cursor) {
|
|
1851
|
+
const existing = cursor.value;
|
|
1852
|
+
const k = existing.item[keyPath];
|
|
1853
|
+
if (targetKey != null && k === targetKey) cursor.delete();
|
|
1854
|
+
cursor.continue();
|
|
1855
|
+
} else {
|
|
1856
|
+
store.put(change);
|
|
1857
|
+
}
|
|
1858
|
+
};
|
|
1859
|
+
}
|
|
1860
|
+
function idbPutWithChange(db, item, change, keyPath) {
|
|
1758
1861
|
return new Promise((resolve, reject) => {
|
|
1759
1862
|
const tx = db.transaction(["items", "_changes"], "readwrite");
|
|
1760
1863
|
tx.objectStore("items").put(item);
|
|
1761
|
-
tx
|
|
1864
|
+
coalesceAndAddChange(tx, change, keyPath);
|
|
1762
1865
|
tx.oncomplete = () => resolve();
|
|
1763
1866
|
tx.onerror = () => reject(tx.error);
|
|
1764
1867
|
});
|
|
1765
1868
|
}
|
|
1766
|
-
function idbDeleteWithChange(db, key, change) {
|
|
1869
|
+
function idbDeleteWithChange(db, key, change, keyPath) {
|
|
1767
1870
|
return new Promise((resolve, reject) => {
|
|
1768
1871
|
const tx = db.transaction(["items", "_changes"], "readwrite");
|
|
1769
1872
|
tx.objectStore("items").delete(key);
|
|
1770
|
-
tx
|
|
1873
|
+
coalesceAndAddChange(tx, change, keyPath);
|
|
1771
1874
|
tx.oncomplete = () => resolve();
|
|
1772
1875
|
tx.onerror = () => reject(tx.error);
|
|
1773
1876
|
});
|
|
@@ -1827,13 +1930,18 @@ async function offlineStore(options) {
|
|
|
1827
1930
|
setPendingCount(changes.length);
|
|
1828
1931
|
}
|
|
1829
1932
|
async function put(item) {
|
|
1830
|
-
await idbPutWithChange(db, item, { type: "put", item, timestamp: Date.now() });
|
|
1933
|
+
await idbPutWithChange(db, item, { type: "put", item, timestamp: Date.now() }, keyPath);
|
|
1831
1934
|
await refreshData();
|
|
1832
1935
|
}
|
|
1833
1936
|
async function remove(key) {
|
|
1834
1937
|
const existing = await idbGet(db, "items", key);
|
|
1835
1938
|
if (existing) {
|
|
1836
|
-
await idbDeleteWithChange(
|
|
1939
|
+
await idbDeleteWithChange(
|
|
1940
|
+
db,
|
|
1941
|
+
key,
|
|
1942
|
+
{ type: "delete", item: existing, timestamp: Date.now() },
|
|
1943
|
+
keyPath
|
|
1944
|
+
);
|
|
1837
1945
|
await refreshData();
|
|
1838
1946
|
}
|
|
1839
1947
|
}
|
|
@@ -1859,6 +1967,8 @@ async function offlineStore(options) {
|
|
|
1859
1967
|
snapshot.map((e) => e.key)
|
|
1860
1968
|
);
|
|
1861
1969
|
if (closed) return;
|
|
1970
|
+
} else if (typeof console !== "undefined") {
|
|
1971
|
+
console.warn(`[offlineStore] push rejected by adapter${result.error ? `: ${result.error}` : ""}`);
|
|
1862
1972
|
}
|
|
1863
1973
|
}
|
|
1864
1974
|
const remoteItems = await adapter.pull(lastSynced());
|
|
@@ -1877,7 +1987,7 @@ async function offlineStore(options) {
|
|
|
1877
1987
|
await idbPutMany(db, "items", safeRemote);
|
|
1878
1988
|
if (closed) return;
|
|
1879
1989
|
const now = Date.now();
|
|
1880
|
-
await idbPut(db, "_meta", now);
|
|
1990
|
+
await idbPut(db, "_meta", now, "lastSynced");
|
|
1881
1991
|
if (closed) return;
|
|
1882
1992
|
setLastSynced(now);
|
|
1883
1993
|
await refreshData();
|
|
@@ -1976,14 +2086,20 @@ function loaderData() {
|
|
|
1976
2086
|
async function preloadRoute(route, context2, callerSignal) {
|
|
1977
2087
|
if (!route.loader) return void 0;
|
|
1978
2088
|
const controller = new AbortController();
|
|
2089
|
+
let onAbort = null;
|
|
1979
2090
|
if (callerSignal) {
|
|
1980
2091
|
if (callerSignal.aborted) {
|
|
1981
2092
|
controller.abort();
|
|
1982
2093
|
} else {
|
|
1983
|
-
|
|
2094
|
+
onAbort = () => controller.abort();
|
|
2095
|
+
callerSignal.addEventListener("abort", onAbort, { once: true });
|
|
1984
2096
|
}
|
|
1985
2097
|
}
|
|
1986
|
-
|
|
2098
|
+
try {
|
|
2099
|
+
return await route.loader(context2, { signal: controller.signal });
|
|
2100
|
+
} finally {
|
|
2101
|
+
if (onAbort) callerSignal?.removeEventListener("abort", onAbort);
|
|
2102
|
+
}
|
|
1987
2103
|
}
|
|
1988
2104
|
|
|
1989
2105
|
// src/ui/socket.ts
|
|
@@ -2089,9 +2205,17 @@ function socket(url, options) {
|
|
|
2089
2205
|
}
|
|
2090
2206
|
|
|
2091
2207
|
// src/utils/sanitize.ts
|
|
2208
|
+
function stripControlChars(value) {
|
|
2209
|
+
return value.replace(/[\x00-\x20\x7f-\x9f]+/g, "");
|
|
2210
|
+
}
|
|
2211
|
+
function isEventHandlerAttr(name) {
|
|
2212
|
+
if (name.length < 3) return false;
|
|
2213
|
+
const lower = name.toLowerCase();
|
|
2214
|
+
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
2215
|
+
}
|
|
2092
2216
|
var SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
|
|
2093
2217
|
function sanitizeUrl(url) {
|
|
2094
|
-
const trimmed = url
|
|
2218
|
+
const trimmed = stripControlChars(url).trim();
|
|
2095
2219
|
if (!trimmed) return "";
|
|
2096
2220
|
const lower = trimmed.toLowerCase();
|
|
2097
2221
|
let schemeEnd = -1;
|
|
@@ -2140,7 +2264,20 @@ function sanitizeCSSValue(value) {
|
|
|
2140
2264
|
return value;
|
|
2141
2265
|
}
|
|
2142
2266
|
function stripHtml(html2) {
|
|
2143
|
-
|
|
2267
|
+
const input2 = String(html2);
|
|
2268
|
+
if (typeof DOMParser !== "undefined") {
|
|
2269
|
+
try {
|
|
2270
|
+
return new DOMParser().parseFromString(input2, "text/html").body.textContent ?? "";
|
|
2271
|
+
} catch {
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
let prev;
|
|
2275
|
+
let out = input2;
|
|
2276
|
+
do {
|
|
2277
|
+
prev = out;
|
|
2278
|
+
out = out.replace(/<[^>]*>/g, "");
|
|
2279
|
+
} while (out !== prev);
|
|
2280
|
+
return out.replace(/<[^>]*$/, "");
|
|
2144
2281
|
}
|
|
2145
2282
|
var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
2146
2283
|
"href",
|
|
@@ -2157,7 +2294,7 @@ var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
|
2157
2294
|
"data"
|
|
2158
2295
|
]);
|
|
2159
2296
|
function isUrlAttribute(attr) {
|
|
2160
|
-
return URL_ATTRIBUTES.has(attr);
|
|
2297
|
+
return URL_ATTRIBUTES.has(attr.toLowerCase());
|
|
2161
2298
|
}
|
|
2162
2299
|
|
|
2163
2300
|
// src/ui/stream.ts
|
|
@@ -2540,6 +2677,19 @@ function clipboard() {
|
|
|
2540
2677
|
return { text: text2, copy, copied, dispose: dispose2 };
|
|
2541
2678
|
}
|
|
2542
2679
|
|
|
2680
|
+
// src/utils/guards.ts
|
|
2681
|
+
var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
2682
|
+
function isUnsafeKey(key) {
|
|
2683
|
+
return UNSAFE_KEYS.has(key);
|
|
2684
|
+
}
|
|
2685
|
+
function stripUnsafeKeys(obj) {
|
|
2686
|
+
const out = {};
|
|
2687
|
+
for (const k of Object.keys(obj)) {
|
|
2688
|
+
if (!isUnsafeKey(k)) out[k] = obj[k];
|
|
2689
|
+
}
|
|
2690
|
+
return out;
|
|
2691
|
+
}
|
|
2692
|
+
|
|
2543
2693
|
// src/browser/dragDrop.ts
|
|
2544
2694
|
function resolveTarget2(target) {
|
|
2545
2695
|
return typeof target === "function" ? target : () => target.current;
|
|
@@ -2625,10 +2775,7 @@ function dropZone(element, options) {
|
|
|
2625
2775
|
const raw = e.dataTransfer.getData("application/json");
|
|
2626
2776
|
if (raw) {
|
|
2627
2777
|
try {
|
|
2628
|
-
transferData = JSON.parse(
|
|
2629
|
-
raw,
|
|
2630
|
-
(k, v) => k === "__proto__" || k === "constructor" || k === "prototype" ? void 0 : v
|
|
2631
|
-
);
|
|
2778
|
+
transferData = JSON.parse(raw, (k, v) => isUnsafeKey(k) ? void 0 : v);
|
|
2632
2779
|
} catch {
|
|
2633
2780
|
transferData = raw;
|
|
2634
2781
|
}
|
|
@@ -3561,11 +3708,7 @@ function machine(config) {
|
|
|
3561
3708
|
}
|
|
3562
3709
|
if (action) {
|
|
3563
3710
|
const rawPatch = action(ctx);
|
|
3564
|
-
const next = { ...ctx };
|
|
3565
|
-
for (const key of Object.keys(rawPatch)) {
|
|
3566
|
-
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
3567
|
-
next[key] = rawPatch[key];
|
|
3568
|
-
}
|
|
3711
|
+
const next = { ...ctx, ...stripUnsafeKeys(rawPatch) };
|
|
3569
3712
|
setContext(next);
|
|
3570
3713
|
}
|
|
3571
3714
|
setState(target);
|
|
@@ -3596,10 +3739,7 @@ function machine(config) {
|
|
|
3596
3739
|
function persisted(key, initial, options = {}) {
|
|
3597
3740
|
const storage = options.session ? sessionStorage : localStorage;
|
|
3598
3741
|
const serialize = options.serialize || JSON.stringify;
|
|
3599
|
-
const safeReviver = (k, v) =>
|
|
3600
|
-
if (k === "__proto__" || k === "constructor" || k === "prototype") return void 0;
|
|
3601
|
-
return v;
|
|
3602
|
-
};
|
|
3742
|
+
const safeReviver = (k, v) => isUnsafeKey(k) ? void 0 : v;
|
|
3603
3743
|
const deserialize = options.deserialize || ((raw) => JSON.parse(raw, safeReviver));
|
|
3604
3744
|
const encrypt = options.encrypt;
|
|
3605
3745
|
const decrypt = options.decrypt;
|
|
@@ -3889,6 +4029,7 @@ function deepClone(value) {
|
|
|
3889
4029
|
if (Array.isArray(v)) return v.map(clone);
|
|
3890
4030
|
const out = {};
|
|
3891
4031
|
for (const k of Object.keys(v)) {
|
|
4032
|
+
if (k === "__proto__") continue;
|
|
3892
4033
|
out[k] = clone(v[k]);
|
|
3893
4034
|
}
|
|
3894
4035
|
return out;
|
|
@@ -3906,12 +4047,7 @@ function globalStore(config) {
|
|
|
3906
4047
|
const execute = () => {
|
|
3907
4048
|
const current = getState();
|
|
3908
4049
|
const rawPatch = actionFn(current, payload);
|
|
3909
|
-
const patch =
|
|
3910
|
-
for (const key of Object.keys(rawPatch)) {
|
|
3911
|
-
if (key !== "__proto__" && key !== "constructor" && key !== "prototype") {
|
|
3912
|
-
patch[key] = rawPatch[key];
|
|
3913
|
-
}
|
|
3914
|
-
}
|
|
4050
|
+
const patch = stripUnsafeKeys(rawPatch);
|
|
3915
4051
|
setState({ ...current, ...patch });
|
|
3916
4052
|
const newState = getState();
|
|
3917
4053
|
for (const listener of listeners) {
|
|
@@ -3984,7 +4120,7 @@ function withBoundary(name, component) {
|
|
|
3984
4120
|
function createSlots(slots) {
|
|
3985
4121
|
return {
|
|
3986
4122
|
renderSlot(name, fallback) {
|
|
3987
|
-
const slotFn = slots[name];
|
|
4123
|
+
const slotFn = Object.hasOwn(slots, name) ? slots[name] : void 0;
|
|
3988
4124
|
if (slotFn) {
|
|
3989
4125
|
const result = slotFn();
|
|
3990
4126
|
if (Array.isArray(result)) {
|
|
@@ -3998,7 +4134,7 @@ function createSlots(slots) {
|
|
|
3998
4134
|
return fallback ? fallback() : null;
|
|
3999
4135
|
},
|
|
4000
4136
|
hasSlot(name) {
|
|
4001
|
-
return name
|
|
4137
|
+
return Object.hasOwn(slots, name);
|
|
4002
4138
|
}
|
|
4003
4139
|
};
|
|
4004
4140
|
}
|
|
@@ -4126,11 +4262,17 @@ function transition(element, options = {}) {
|
|
|
4126
4262
|
} = options;
|
|
4127
4263
|
const transitionValue = `${property} ${duration}ms ${easing} ${delay}ms`;
|
|
4128
4264
|
let activeTimer = null;
|
|
4265
|
+
let pendingResolve = null;
|
|
4129
4266
|
function cancelPending() {
|
|
4130
4267
|
if (activeTimer !== null) {
|
|
4131
4268
|
clearTimeout(activeTimer);
|
|
4132
4269
|
activeTimer = null;
|
|
4133
4270
|
}
|
|
4271
|
+
if (pendingResolve !== null) {
|
|
4272
|
+
const resolvePrev = pendingResolve;
|
|
4273
|
+
pendingResolve = null;
|
|
4274
|
+
resolvePrev();
|
|
4275
|
+
}
|
|
4134
4276
|
}
|
|
4135
4277
|
function enter() {
|
|
4136
4278
|
return new Promise((resolve) => {
|
|
@@ -4142,11 +4284,13 @@ function transition(element, options = {}) {
|
|
|
4142
4284
|
if (activeClass) element.classList.add(activeClass);
|
|
4143
4285
|
const done = () => {
|
|
4144
4286
|
activeTimer = null;
|
|
4287
|
+
pendingResolve = null;
|
|
4145
4288
|
if (enterClass) element.classList.remove(enterClass);
|
|
4146
4289
|
onEnterDone?.();
|
|
4147
4290
|
resolve();
|
|
4148
4291
|
};
|
|
4149
4292
|
if (duration > 0) {
|
|
4293
|
+
pendingResolve = resolve;
|
|
4150
4294
|
activeTimer = setTimeout(done, duration + delay);
|
|
4151
4295
|
} else {
|
|
4152
4296
|
done();
|
|
@@ -4162,11 +4306,13 @@ function transition(element, options = {}) {
|
|
|
4162
4306
|
if (enterClass) element.classList.remove(enterClass);
|
|
4163
4307
|
const done = () => {
|
|
4164
4308
|
activeTimer = null;
|
|
4309
|
+
pendingResolve = null;
|
|
4165
4310
|
if (leaveClass) element.classList.remove(leaveClass);
|
|
4166
4311
|
onLeaveDone?.();
|
|
4167
4312
|
resolve();
|
|
4168
4313
|
};
|
|
4169
4314
|
if (duration > 0) {
|
|
4315
|
+
pendingResolve = resolve;
|
|
4170
4316
|
activeTimer = setTimeout(done, duration + delay);
|
|
4171
4317
|
} else {
|
|
4172
4318
|
done();
|
|
@@ -4794,7 +4940,10 @@ function VirtualList(props) {
|
|
|
4794
4940
|
const visibleCount = Math.ceil(props.containerHeight / props.itemHeight) + 2 * overscan;
|
|
4795
4941
|
const endIndex = Math.min(items.length, startIndex + visibleCount);
|
|
4796
4942
|
content.style.top = `${startIndex * props.itemHeight}px`;
|
|
4797
|
-
content.
|
|
4943
|
+
while (content.firstChild) {
|
|
4944
|
+
dispose(content.firstChild);
|
|
4945
|
+
content.removeChild(content.firstChild);
|
|
4946
|
+
}
|
|
4798
4947
|
for (let i2 = startIndex; i2 < endIndex; i2++) {
|
|
4799
4948
|
const itemEl = props.renderItem(items[i2], i2);
|
|
4800
4949
|
itemEl.style.height = `${props.itemHeight}px`;
|
|
@@ -4802,7 +4951,7 @@ function VirtualList(props) {
|
|
|
4802
4951
|
content.appendChild(itemEl);
|
|
4803
4952
|
}
|
|
4804
4953
|
};
|
|
4805
|
-
effect(update);
|
|
4954
|
+
registerDisposer(container, effect(update));
|
|
4806
4955
|
return container;
|
|
4807
4956
|
}
|
|
4808
4957
|
|
|
@@ -4943,7 +5092,10 @@ function inputMask(options) {
|
|
|
4943
5092
|
}
|
|
4944
5093
|
}
|
|
4945
5094
|
}
|
|
4946
|
-
|
|
5095
|
+
try {
|
|
5096
|
+
input2.setSelectionRange(newCursor, newCursor);
|
|
5097
|
+
} catch {
|
|
5098
|
+
}
|
|
4947
5099
|
};
|
|
4948
5100
|
const onFocus = () => {
|
|
4949
5101
|
if (!input2.value) {
|
|
@@ -4985,9 +5137,12 @@ function aria(element, attrs) {
|
|
|
4985
5137
|
const ariaKey = key.startsWith("aria-") ? key : `aria-${key}`;
|
|
4986
5138
|
if (typeof value === "function") {
|
|
4987
5139
|
const getter = value;
|
|
4988
|
-
|
|
4989
|
-
element
|
|
4990
|
-
|
|
5140
|
+
registerDisposer(
|
|
5141
|
+
element,
|
|
5142
|
+
track(() => {
|
|
5143
|
+
element.setAttribute(ariaKey, String(getter()));
|
|
5144
|
+
})
|
|
5145
|
+
);
|
|
4991
5146
|
} else {
|
|
4992
5147
|
element.setAttribute(ariaKey, String(value));
|
|
4993
5148
|
}
|
|
@@ -5261,11 +5416,6 @@ var _isDev5 = isDev();
|
|
|
5261
5416
|
function setProp(el, key, val) {
|
|
5262
5417
|
el[key] = val;
|
|
5263
5418
|
}
|
|
5264
|
-
function isEventHandlerAttr(name) {
|
|
5265
|
-
if (name.length < 3) return false;
|
|
5266
|
-
const lower = name.toLowerCase();
|
|
5267
|
-
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
5268
|
-
}
|
|
5269
5419
|
function bindAttribute(el, attr, getter) {
|
|
5270
5420
|
if (isEventHandlerAttr(attr)) {
|
|
5271
5421
|
if (_isDev5)
|
|
@@ -5301,8 +5451,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
5301
5451
|
el.setAttribute(attr, isUrlAttribute(attr) ? sanitizeUrl(str) : str);
|
|
5302
5452
|
}
|
|
5303
5453
|
}
|
|
5304
|
-
|
|
5305
|
-
return teardown;
|
|
5454
|
+
return reactiveBinding(commit);
|
|
5306
5455
|
}
|
|
5307
5456
|
|
|
5308
5457
|
// src/ui/reactiveAttr.ts
|
|
@@ -5662,11 +5811,26 @@ function processQueue() {
|
|
|
5662
5811
|
scheduleFrame();
|
|
5663
5812
|
}
|
|
5664
5813
|
}
|
|
5814
|
+
var TIER_SPEED = { microtask: 0, frame: 1, timeout: 2, idle: 3 };
|
|
5815
|
+
function cancelScheduled() {
|
|
5816
|
+
if (scheduledHandle !== null) {
|
|
5817
|
+
if (scheduledKind === "frame") cancelAnimationFrame(scheduledHandle);
|
|
5818
|
+
else if (scheduledKind === "idle" && typeof cancelIdleCallback !== "undefined") cancelIdleCallback(scheduledHandle);
|
|
5819
|
+
else if (scheduledKind === "timeout") clearTimeout(scheduledHandle);
|
|
5820
|
+
}
|
|
5821
|
+
scheduledHandle = null;
|
|
5822
|
+
scheduledKind = null;
|
|
5823
|
+
}
|
|
5665
5824
|
function scheduleFrame() {
|
|
5666
|
-
if (scheduledKind !== null || microtaskScheduled) return;
|
|
5667
5825
|
const nextTask = taskQueue.find((t) => !t.cancelled);
|
|
5668
5826
|
if (!nextTask) return;
|
|
5669
|
-
|
|
5827
|
+
const desired = nextTask.priority <= Priority.USER_BLOCKING ? "microtask" : nextTask.priority === Priority.IDLE ? typeof requestIdleCallback !== "undefined" ? "idle" : "timeout" : "frame";
|
|
5828
|
+
if (microtaskScheduled) return;
|
|
5829
|
+
if (scheduledKind !== null) {
|
|
5830
|
+
if (TIER_SPEED[scheduledKind] <= TIER_SPEED[desired]) return;
|
|
5831
|
+
cancelScheduled();
|
|
5832
|
+
}
|
|
5833
|
+
if (desired === "microtask") {
|
|
5670
5834
|
microtaskScheduled = true;
|
|
5671
5835
|
scheduledKind = "microtask";
|
|
5672
5836
|
queueMicrotask(() => {
|
|
@@ -5674,22 +5838,20 @@ function scheduleFrame() {
|
|
|
5674
5838
|
scheduledKind = null;
|
|
5675
5839
|
processQueue();
|
|
5676
5840
|
});
|
|
5677
|
-
} else if (
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
}, 50);
|
|
5692
|
-
}
|
|
5841
|
+
} else if (desired === "idle") {
|
|
5842
|
+
scheduledKind = "idle";
|
|
5843
|
+
scheduledHandle = requestIdleCallback(() => {
|
|
5844
|
+
scheduledKind = null;
|
|
5845
|
+
scheduledHandle = null;
|
|
5846
|
+
processQueue();
|
|
5847
|
+
});
|
|
5848
|
+
} else if (desired === "timeout") {
|
|
5849
|
+
scheduledKind = "timeout";
|
|
5850
|
+
scheduledHandle = setTimeout(() => {
|
|
5851
|
+
scheduledKind = null;
|
|
5852
|
+
scheduledHandle = null;
|
|
5853
|
+
processQueue();
|
|
5854
|
+
}, 50);
|
|
5693
5855
|
} else {
|
|
5694
5856
|
scheduledKind = "frame";
|
|
5695
5857
|
scheduledHandle = requestAnimationFrame(() => {
|
|
@@ -5754,7 +5916,7 @@ function yieldToMain() {
|
|
|
5754
5916
|
async function processInChunks(items, processor, chunkSize = 50) {
|
|
5755
5917
|
for (let i2 = 0; i2 < items.length; i2++) {
|
|
5756
5918
|
processor(items[i2], i2);
|
|
5757
|
-
if (i2
|
|
5919
|
+
if ((i2 + 1) % chunkSize === 0 && i2 + 1 < items.length) {
|
|
5758
5920
|
await yieldToMain();
|
|
5759
5921
|
}
|
|
5760
5922
|
}
|
|
@@ -5935,16 +6097,14 @@ function noSideEffect(fn) {
|
|
|
5935
6097
|
}
|
|
5936
6098
|
|
|
5937
6099
|
// src/platform/ssr.ts
|
|
6100
|
+
function sanitizeUrlAttr(name, value) {
|
|
6101
|
+
return name === "srcset" ? sanitizeSrcset(value) : sanitizeUrl(value);
|
|
6102
|
+
}
|
|
5938
6103
|
var _isDev7 = isDev();
|
|
5939
6104
|
var SAFE_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
|
|
5940
6105
|
function isSafeAttrName(name) {
|
|
5941
6106
|
return SAFE_ATTR_NAME.test(name);
|
|
5942
6107
|
}
|
|
5943
|
-
function isEventHandlerAttr2(name) {
|
|
5944
|
-
if (name.length < 3) return false;
|
|
5945
|
-
const lower = name.toLowerCase();
|
|
5946
|
-
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
5947
|
-
}
|
|
5948
6108
|
var URL_ATTRS = /* @__PURE__ */ new Set([
|
|
5949
6109
|
"href",
|
|
5950
6110
|
"src",
|
|
@@ -6015,11 +6175,11 @@ function renderToString(element) {
|
|
|
6015
6175
|
for (const attr of Array.from(element.attributes)) {
|
|
6016
6176
|
const rawName = attr.name;
|
|
6017
6177
|
if (!isSafeAttrName(rawName)) continue;
|
|
6018
|
-
if (
|
|
6178
|
+
if (isEventHandlerAttr(rawName)) continue;
|
|
6019
6179
|
const lowerName = rawName.toLowerCase();
|
|
6020
6180
|
let value = attr.value;
|
|
6021
6181
|
if (URL_ATTRS.has(lowerName)) {
|
|
6022
|
-
value =
|
|
6182
|
+
value = sanitizeUrlAttr(lowerName, value);
|
|
6023
6183
|
if (!value) continue;
|
|
6024
6184
|
}
|
|
6025
6185
|
html2 += ` ${rawName}="${escapeAttr(value)}"`;
|
|
@@ -6156,11 +6316,11 @@ function buildAttrString(attrs, { allowEventHandlers = false } = {}) {
|
|
|
6156
6316
|
for (const rawKey of Object.keys(attrs)) {
|
|
6157
6317
|
if (!Object.hasOwn(attrs, rawKey)) continue;
|
|
6158
6318
|
if (!isSafeAttrName(rawKey)) continue;
|
|
6159
|
-
if (!allowEventHandlers &&
|
|
6319
|
+
if (!allowEventHandlers && isEventHandlerAttr(rawKey)) continue;
|
|
6160
6320
|
const lowerKey = rawKey.toLowerCase();
|
|
6161
6321
|
let value = String(attrs[rawKey]);
|
|
6162
6322
|
if (URL_ATTRS.has(lowerKey)) {
|
|
6163
|
-
value =
|
|
6323
|
+
value = sanitizeUrlAttr(lowerKey, value);
|
|
6164
6324
|
if (!value) continue;
|
|
6165
6325
|
}
|
|
6166
6326
|
out.push(`${rawKey}="${escapeAttr(value)}"`);
|
|
@@ -6168,12 +6328,17 @@ function buildAttrString(attrs, { allowEventHandlers = false } = {}) {
|
|
|
6168
6328
|
return out.join(" ");
|
|
6169
6329
|
}
|
|
6170
6330
|
function isDangerousMetaRefresh(metaProps) {
|
|
6171
|
-
|
|
6331
|
+
let httpEquiv;
|
|
6332
|
+
let content;
|
|
6333
|
+
for (const k in metaProps) {
|
|
6334
|
+
const lk = k.toLowerCase();
|
|
6335
|
+
if (lk === "http-equiv") httpEquiv = metaProps[k];
|
|
6336
|
+
else if (lk === "content") content = metaProps[k];
|
|
6337
|
+
}
|
|
6172
6338
|
if (typeof httpEquiv !== "string") return false;
|
|
6173
6339
|
if (httpEquiv.toLowerCase() !== "refresh") return false;
|
|
6174
|
-
const content = metaProps.content;
|
|
6175
6340
|
if (typeof content !== "string") return false;
|
|
6176
|
-
const normalized = content
|
|
6341
|
+
const normalized = stripControlChars(content).toLowerCase();
|
|
6177
6342
|
return normalized.includes("url=javascript:") || normalized.includes("url=data:") || normalized.includes("url=vbscript:") || normalized.includes("url=blob:");
|
|
6178
6343
|
}
|
|
6179
6344
|
function renderToDocument(component, options = {}) {
|
|
@@ -6251,11 +6416,11 @@ async function* renderToStream(element) {
|
|
|
6251
6416
|
for (const attr of Array.from(element.attributes)) {
|
|
6252
6417
|
const rawName = attr.name;
|
|
6253
6418
|
if (!isSafeAttrName(rawName)) continue;
|
|
6254
|
-
if (
|
|
6419
|
+
if (isEventHandlerAttr(rawName)) continue;
|
|
6255
6420
|
const lowerName = rawName.toLowerCase();
|
|
6256
6421
|
let value = attr.value;
|
|
6257
6422
|
if (URL_ATTRS.has(lowerName)) {
|
|
6258
|
-
value =
|
|
6423
|
+
value = sanitizeUrlAttr(lowerName, value);
|
|
6259
6424
|
if (!value) continue;
|
|
6260
6425
|
}
|
|
6261
6426
|
openTag += ` ${rawName}="${escapeAttr(value)}"`;
|
|
@@ -6332,11 +6497,11 @@ function hydrateProgressively(container, islands, options) {
|
|
|
6332
6497
|
(entries) => {
|
|
6333
6498
|
for (const entry of entries) {
|
|
6334
6499
|
if (entry.isIntersecting) {
|
|
6500
|
+
observer.disconnect();
|
|
6335
6501
|
const clientTree = factory();
|
|
6336
6502
|
clientTree.setAttribute("data-sibu-island", id);
|
|
6337
6503
|
clientTree.setAttribute("data-sibu-hydrated", "true");
|
|
6338
6504
|
marker2.replaceWith(clientTree);
|
|
6339
|
-
observer.disconnect();
|
|
6340
6505
|
break;
|
|
6341
6506
|
}
|
|
6342
6507
|
}
|
|
@@ -6593,6 +6758,12 @@ function denormalize(id, entities, schema) {
|
|
|
6593
6758
|
}
|
|
6594
6759
|
|
|
6595
6760
|
// src/performance/chunkLoader.ts
|
|
6761
|
+
function clearChildren(el) {
|
|
6762
|
+
while (el.firstChild) {
|
|
6763
|
+
dispose(el.firstChild);
|
|
6764
|
+
el.removeChild(el.firstChild);
|
|
6765
|
+
}
|
|
6766
|
+
}
|
|
6596
6767
|
function createChunkRegistry(config = {}) {
|
|
6597
6768
|
const {
|
|
6598
6769
|
maxCacheSize = 50,
|
|
@@ -6757,10 +6928,10 @@ function lazyChunk(id, loader, registry, fallback) {
|
|
|
6757
6928
|
const mod = await loader();
|
|
6758
6929
|
return typeof mod === "function" ? mod : mod.default;
|
|
6759
6930
|
}).then((component) => {
|
|
6760
|
-
container
|
|
6931
|
+
clearChildren(container);
|
|
6761
6932
|
container.appendChild(component());
|
|
6762
6933
|
}).catch((err) => {
|
|
6763
|
-
container
|
|
6934
|
+
clearChildren(container);
|
|
6764
6935
|
const errorEl = document.createElement("div");
|
|
6765
6936
|
errorEl.textContent = `Failed to load chunk '${id}': ${err.message}`;
|
|
6766
6937
|
container.appendChild(errorEl);
|
|
@@ -6787,24 +6958,28 @@ function sanitizeHeadAttr(key, value) {
|
|
|
6787
6958
|
if (HEAD_URL_ATTRS.has(key)) return sanitizeUrl(value);
|
|
6788
6959
|
return value;
|
|
6789
6960
|
}
|
|
6961
|
+
function isDangerousRefreshContent(content) {
|
|
6962
|
+
const normalized = stripControlChars(content).toLowerCase();
|
|
6963
|
+
return normalized.includes("url=javascript:") || normalized.includes("url=data:") || normalized.includes("url=vbscript:") || normalized.includes("url=blob:");
|
|
6964
|
+
}
|
|
6965
|
+
function getMetaAttr(metaProps, name) {
|
|
6966
|
+
for (const k in metaProps) {
|
|
6967
|
+
if (k.toLowerCase() === name) return metaProps[k];
|
|
6968
|
+
}
|
|
6969
|
+
return void 0;
|
|
6970
|
+
}
|
|
6790
6971
|
function isDangerousMetaRefresh2(metaProps) {
|
|
6791
|
-
const httpEquiv = metaProps
|
|
6972
|
+
const httpEquiv = getMetaAttr(metaProps, "http-equiv");
|
|
6792
6973
|
if (typeof httpEquiv !== "string") return false;
|
|
6793
6974
|
if (httpEquiv.toLowerCase() !== "refresh") return false;
|
|
6794
|
-
const content = metaProps
|
|
6975
|
+
const content = getMetaAttr(metaProps, "content");
|
|
6795
6976
|
if (typeof content !== "string") return false;
|
|
6796
|
-
|
|
6797
|
-
return normalized.includes("url=javascript:") || normalized.includes("url=data:") || normalized.includes("url=vbscript:") || normalized.includes("url=blob:");
|
|
6977
|
+
return isDangerousRefreshContent(content);
|
|
6798
6978
|
}
|
|
6799
6979
|
var SAFE_HEAD_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
|
|
6800
|
-
function isEventHandlerAttr3(name) {
|
|
6801
|
-
if (name.length < 3) return false;
|
|
6802
|
-
const lower = name.toLowerCase();
|
|
6803
|
-
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
6804
|
-
}
|
|
6805
6980
|
function isSafeHeadAttr(name) {
|
|
6806
6981
|
if (!SAFE_HEAD_ATTR_NAME.test(name)) return false;
|
|
6807
|
-
if (
|
|
6982
|
+
if (isEventHandlerAttr(name)) return false;
|
|
6808
6983
|
return true;
|
|
6809
6984
|
}
|
|
6810
6985
|
function escapeScriptJsonLocal(json) {
|
|
@@ -6837,15 +7012,27 @@ function Head(props) {
|
|
|
6837
7012
|
if (props.meta) {
|
|
6838
7013
|
for (const metaProps of props.meta) {
|
|
6839
7014
|
if (isDangerousMetaRefresh2(metaProps)) continue;
|
|
7015
|
+
const httpEquiv = getMetaAttr(metaProps, "http-equiv");
|
|
7016
|
+
const isRefreshNow = () => {
|
|
7017
|
+
const eq = typeof httpEquiv === "function" ? httpEquiv() : httpEquiv;
|
|
7018
|
+
return typeof eq === "string" && eq.toLowerCase() === "refresh";
|
|
7019
|
+
};
|
|
6840
7020
|
const el = document.createElement("meta");
|
|
6841
7021
|
for (const [key, value] of Object.entries(metaProps)) {
|
|
6842
7022
|
if (!isSafeHeadAttr(key)) continue;
|
|
7023
|
+
const isContent = key.toLowerCase() === "content";
|
|
6843
7024
|
if (typeof value === "function") {
|
|
6844
7025
|
const cleanupFn = effect(() => {
|
|
6845
|
-
|
|
7026
|
+
const resolved = value();
|
|
7027
|
+
if (isContent && isRefreshNow() && isDangerousRefreshContent(resolved)) {
|
|
7028
|
+
el.removeAttribute(key);
|
|
7029
|
+
return;
|
|
7030
|
+
}
|
|
7031
|
+
el.setAttribute(key, sanitizeHeadAttr(key, resolved));
|
|
6846
7032
|
});
|
|
6847
7033
|
effectCleanups.push(cleanupFn);
|
|
6848
7034
|
} else {
|
|
7035
|
+
if (isContent && isRefreshNow() && isDangerousRefreshContent(value)) continue;
|
|
6849
7036
|
el.setAttribute(key, sanitizeHeadAttr(key, value));
|
|
6850
7037
|
}
|
|
6851
7038
|
}
|
|
@@ -7379,6 +7566,7 @@ function bindChildNode(placeholder, getter) {
|
|
|
7379
7566
|
if (result == null || typeof result === "boolean") {
|
|
7380
7567
|
for (let i2 = 0; i2 < lastNodes.length; i2++) {
|
|
7381
7568
|
const node = lastNodes[i2];
|
|
7569
|
+
dispose(node);
|
|
7382
7570
|
if (node.parentNode) node.parentNode.removeChild(node);
|
|
7383
7571
|
}
|
|
7384
7572
|
lastNodes.length = 0;
|
|
@@ -7420,22 +7608,20 @@ function bindChildNode(placeholder, getter) {
|
|
|
7420
7608
|
for (let i2 = 0; i2 < lastNodes.length; i2++) {
|
|
7421
7609
|
const node = lastNodes[i2];
|
|
7422
7610
|
if (reused?.has(node)) continue;
|
|
7611
|
+
dispose(node);
|
|
7423
7612
|
if (node.parentNode) node.parentNode.removeChild(node);
|
|
7424
7613
|
}
|
|
7425
|
-
|
|
7614
|
+
let prev = placeholder;
|
|
7426
7615
|
for (let i2 = 0; i2 < newNodes.length; i2++) {
|
|
7427
7616
|
const node = newNodes[i2];
|
|
7428
|
-
if (
|
|
7429
|
-
|
|
7430
|
-
parent.insertBefore(node, anchor);
|
|
7431
|
-
}
|
|
7432
|
-
} else {
|
|
7433
|
-
parent.insertBefore(node, anchor);
|
|
7617
|
+
if (prev.nextSibling !== node) {
|
|
7618
|
+
parent.insertBefore(node, prev.nextSibling);
|
|
7434
7619
|
}
|
|
7620
|
+
prev = node;
|
|
7435
7621
|
}
|
|
7436
7622
|
lastNodes = newNodes;
|
|
7437
7623
|
}
|
|
7438
|
-
return
|
|
7624
|
+
return reactiveBinding(commit);
|
|
7439
7625
|
}
|
|
7440
7626
|
|
|
7441
7627
|
// src/core/rendering/tagFactory.ts
|
|
@@ -7464,6 +7650,18 @@ var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
|
|
|
7464
7650
|
function setProp2(el, key, val) {
|
|
7465
7651
|
el[key] = val;
|
|
7466
7652
|
}
|
|
7653
|
+
function looksLikeClassList(s2) {
|
|
7654
|
+
const t = s2.trim();
|
|
7655
|
+
if (!t) return false;
|
|
7656
|
+
const tokens = t.split(/\s+/);
|
|
7657
|
+
let sawClassish = false;
|
|
7658
|
+
for (let i2 = 0; i2 < tokens.length; i2++) {
|
|
7659
|
+
const tok = tokens[i2];
|
|
7660
|
+
if (!/^-?[A-Za-z_][A-Za-z0-9_:/.-]*$/.test(tok)) return false;
|
|
7661
|
+
if (/[-:/0-9]/.test(tok)) sawClassish = true;
|
|
7662
|
+
}
|
|
7663
|
+
return sawClassish;
|
|
7664
|
+
}
|
|
7467
7665
|
var kebabCache = /* @__PURE__ */ new Map();
|
|
7468
7666
|
function toKebab(prop) {
|
|
7469
7667
|
let cached = kebabCache.get(prop);
|
|
@@ -7599,6 +7797,11 @@ var tagFactory = (tag, ns) => {
|
|
|
7599
7797
|
appendChildren(el, second);
|
|
7600
7798
|
return el;
|
|
7601
7799
|
}
|
|
7800
|
+
if (_isDev9 && looksLikeClassList(first)) {
|
|
7801
|
+
devWarn(
|
|
7802
|
+
`tagFactory: lone string "${first}" looks like a class list but is being rendered as TEXT. For a class, use ${tag}({ class: "${first}" }) \u2014 or ${tag}("${first}", children) to set the class AND add children.`
|
|
7803
|
+
);
|
|
7804
|
+
}
|
|
7602
7805
|
el.textContent = first;
|
|
7603
7806
|
return el;
|
|
7604
7807
|
}
|
|
@@ -7656,7 +7859,7 @@ var tagFactory = (tag, ns) => {
|
|
|
7656
7859
|
const value = props[key];
|
|
7657
7860
|
if (value == null) continue;
|
|
7658
7861
|
const lkey = key.toLowerCase();
|
|
7659
|
-
if (
|
|
7862
|
+
if (isEventHandlerAttr(key)) continue;
|
|
7660
7863
|
if (typeof value === "function") {
|
|
7661
7864
|
registerDisposer(el, bindAttribute(el, key, value));
|
|
7662
7865
|
} else if (typeof value === "boolean") {
|
|
@@ -9011,6 +9214,7 @@ function createBootSequence() {
|
|
|
9011
9214
|
// src/devtools/debug.ts
|
|
9012
9215
|
var debugEnabled = false;
|
|
9013
9216
|
var perfMarks = /* @__PURE__ */ new Map();
|
|
9217
|
+
var MAX_PERF_SAMPLES = 1e3;
|
|
9014
9218
|
function enableDebug() {
|
|
9015
9219
|
debugEnabled = true;
|
|
9016
9220
|
console.log("[SibuJS] Debug mode enabled");
|
|
@@ -9035,7 +9239,11 @@ function perfTracker(label2) {
|
|
|
9035
9239
|
}
|
|
9036
9240
|
function endMeasure() {
|
|
9037
9241
|
const elapsed = globalThis.performance.now() - startTime;
|
|
9038
|
-
perfMarks.get(label2)
|
|
9242
|
+
const marks = perfMarks.get(label2);
|
|
9243
|
+
if (marks) {
|
|
9244
|
+
marks.push(elapsed);
|
|
9245
|
+
if (marks.length > MAX_PERF_SAMPLES) marks.shift();
|
|
9246
|
+
}
|
|
9039
9247
|
if (debugEnabled) {
|
|
9040
9248
|
debugLog("Perf", `${label2}: ${elapsed.toFixed(2)}ms`);
|
|
9041
9249
|
}
|
|
@@ -9989,7 +10197,7 @@ function withErrorTracking(name, component, reporter) {
|
|
|
9989
10197
|
}
|
|
9990
10198
|
};
|
|
9991
10199
|
}
|
|
9992
|
-
function formatError(error, context2) {
|
|
10200
|
+
function formatError(error, context2, seen = /* @__PURE__ */ new Set([error])) {
|
|
9993
10201
|
const lines = [];
|
|
9994
10202
|
const componentLabel = context2?.component ?? (error instanceof SibuError ? error.component : void 0);
|
|
9995
10203
|
if (componentLabel) {
|
|
@@ -10014,10 +10222,11 @@ function formatError(error, context2) {
|
|
|
10014
10222
|
lines.push(stackBody);
|
|
10015
10223
|
}
|
|
10016
10224
|
const cause = error.cause;
|
|
10017
|
-
if (cause instanceof Error) {
|
|
10225
|
+
if (cause instanceof Error && !seen.has(cause)) {
|
|
10226
|
+
seen.add(cause);
|
|
10018
10227
|
lines.push("");
|
|
10019
10228
|
lines.push("Caused by:");
|
|
10020
|
-
lines.push(formatError(cause));
|
|
10229
|
+
lines.push(formatError(cause, context2, seen));
|
|
10021
10230
|
}
|
|
10022
10231
|
return lines.join("\n");
|
|
10023
10232
|
}
|
|
@@ -10031,7 +10240,11 @@ function debugValue(value, formatter) {
|
|
|
10031
10240
|
const dispose2 = effect(() => {
|
|
10032
10241
|
const resolved = value();
|
|
10033
10242
|
entry.value = resolved;
|
|
10034
|
-
|
|
10243
|
+
try {
|
|
10244
|
+
entry.label = format(resolved);
|
|
10245
|
+
} catch (err) {
|
|
10246
|
+
entry.label = `<format error: ${err instanceof Error ? err.message : String(err)}>`;
|
|
10247
|
+
}
|
|
10035
10248
|
});
|
|
10036
10249
|
return () => {
|
|
10037
10250
|
dispose2();
|
|
@@ -11495,6 +11708,18 @@ function mobXAdapter(options) {
|
|
|
11495
11708
|
return createPlugin("sibu-mobx", (ctx) => {
|
|
11496
11709
|
const { autorun } = options;
|
|
11497
11710
|
const disposers = [];
|
|
11711
|
+
function trackDisposer(rawDispose) {
|
|
11712
|
+
let done = false;
|
|
11713
|
+
const wrapped = () => {
|
|
11714
|
+
if (done) return;
|
|
11715
|
+
done = true;
|
|
11716
|
+
const i2 = disposers.indexOf(wrapped);
|
|
11717
|
+
if (i2 >= 0) disposers.splice(i2, 1);
|
|
11718
|
+
rawDispose();
|
|
11719
|
+
};
|
|
11720
|
+
disposers.push(wrapped);
|
|
11721
|
+
return wrapped;
|
|
11722
|
+
}
|
|
11498
11723
|
function fromMobX(expression) {
|
|
11499
11724
|
const [getValue, setValue] = signal(void 0);
|
|
11500
11725
|
const disposer = autorun(() => {
|
|
@@ -11503,22 +11728,18 @@ function mobXAdapter(options) {
|
|
|
11503
11728
|
setValue(newValue);
|
|
11504
11729
|
});
|
|
11505
11730
|
});
|
|
11506
|
-
disposers.push(disposer);
|
|
11507
11731
|
const getter = (() => getValue());
|
|
11508
|
-
getter.dispose = ()
|
|
11509
|
-
const i2 = disposers.indexOf(disposer);
|
|
11510
|
-
if (i2 >= 0) disposers.splice(i2, 1);
|
|
11511
|
-
disposer();
|
|
11512
|
-
};
|
|
11732
|
+
getter.dispose = trackDisposer(disposer);
|
|
11513
11733
|
return getter;
|
|
11514
11734
|
}
|
|
11515
11735
|
function toMobX(sibuGetter, callback) {
|
|
11516
|
-
|
|
11736
|
+
const stop2 = effect(() => {
|
|
11517
11737
|
callback(sibuGetter());
|
|
11518
11738
|
});
|
|
11739
|
+
return trackDisposer(stop2);
|
|
11519
11740
|
}
|
|
11520
11741
|
function destroy() {
|
|
11521
|
-
for (const disposer of disposers) {
|
|
11742
|
+
for (const disposer of [...disposers]) {
|
|
11522
11743
|
disposer();
|
|
11523
11744
|
}
|
|
11524
11745
|
disposers.length = 0;
|
|
@@ -11979,6 +12200,7 @@ var materialAdapter = componentAdapter(materialConfig);
|
|
|
11979
12200
|
inspectSignal,
|
|
11980
12201
|
intersection,
|
|
11981
12202
|
invalidateQueries,
|
|
12203
|
+
isDangerousMetaRefresh,
|
|
11982
12204
|
isDebugEnabled,
|
|
11983
12205
|
isHMRAvailable,
|
|
11984
12206
|
isWasmCached,
|