sibujs 4.8.0 → 4.10.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 +44 -6
- package/dist/browser.d.cts +3 -2
- package/dist/browser.d.ts +3 -2
- package/dist/browser.js +4 -4
- package/dist/build.cjs +128 -56
- package/dist/build.js +10 -10
- package/dist/cdn.dev.global.js +14 -14
- package/dist/cdn.full.dev.global.js +13 -13
- package/dist/cdn.full.global.js +12 -12
- package/dist/cdn.global.js +15 -15
- package/dist/{chunk-J3YQ457H.js → chunk-2NWHJ2UJ.js} +99 -61
- package/dist/{chunk-JUTFX2RM.js → chunk-4DCVJ4YA.js} +42 -15
- package/dist/{chunk-QGMSESDD.js → chunk-54F4TPHK.js} +2 -2
- package/dist/{chunk-KJ3UKABJ.js → chunk-5PC7OTQW.js} +1 -1
- package/dist/{chunk-V3LHZSU5.js → chunk-7WIHYHWD.js} +8 -1
- package/dist/{chunk-44MTL7ED.js → chunk-BMCR7TXG.js} +3 -3
- package/dist/{chunk-TQQUN4WR.js → chunk-D6HYFOWR.js} +39 -4
- package/dist/{chunk-VWT3VXPL.js → chunk-EVI4ZQO3.js} +2 -2
- package/dist/{chunk-CZPRSWSS.js → chunk-EVOK663Z.js} +1 -1
- package/dist/{chunk-DSID757X.js → chunk-FYUEL5IW.js} +1 -1
- package/dist/{chunk-UCNP3HVM.js → chunk-GMMDHJJT.js} +30 -12
- package/dist/{chunk-C7AA2CZX.js → chunk-GOL3FU5Q.js} +1 -1
- package/dist/{chunk-EGUQLBHE.js → chunk-GTS35FLA.js} +5 -4
- package/dist/{chunk-GSGNX35Q.js → chunk-IFRIBZ4O.js} +4 -4
- package/dist/{chunk-C5PEWEGH.js → chunk-IL5MMSCL.js} +19 -12
- package/dist/{chunk-ZVLHNEEL.js → chunk-ITEL5KPL.js} +6 -6
- package/dist/{chunk-RGLPEBDE.js → chunk-JCKUWWHU.js} +3 -3
- package/dist/{chunk-Q5J2LVKH.js → chunk-N6U4GOIU.js} +1 -1
- package/dist/{chunk-LI4W3U6C.js → chunk-TOPRMXFY.js} +1 -1
- package/dist/{chunk-4WMSTZ7J.js → chunk-VWPMWV7O.js} +4 -4
- package/dist/{chunk-O6TRVMJI.js → chunk-XUQUQJYE.js} +1 -1
- package/dist/data.cjs +67 -12
- package/dist/data.d.cts +32 -5
- package/dist/data.d.ts +32 -5
- package/dist/data.js +5 -5
- package/dist/devtools.cjs +41 -4
- package/dist/devtools.js +4 -4
- package/dist/ecosystem.cjs +41 -4
- package/dist/ecosystem.js +7 -7
- package/dist/extras.cjs +125 -41
- package/dist/extras.js +20 -20
- package/dist/index.cjs +128 -56
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +10 -10
- package/dist/motion.cjs +36 -4
- package/dist/motion.js +3 -3
- package/dist/patterns.cjs +41 -4
- package/dist/patterns.js +5 -5
- package/dist/performance.cjs +55 -14
- package/dist/performance.js +4 -4
- package/dist/plugins.cjs +176 -60
- package/dist/plugins.d.cts +62 -2
- package/dist/plugins.d.ts +62 -2
- package/dist/plugins.js +143 -61
- package/dist/ssr.cjs +77 -16
- package/dist/ssr.d.cts +4 -0
- package/dist/ssr.d.ts +4 -0
- package/dist/ssr.js +7 -7
- package/dist/testing.cjs +41 -4
- package/dist/testing.js +2 -2
- package/dist/ui.cjs +42 -5
- package/dist/ui.js +7 -7
- package/dist/widgets.cjs +36 -4
- package/dist/widgets.js +6 -6
- package/package.json +1 -1
package/dist/plugins.cjs
CHANGED
|
@@ -2008,6 +2008,24 @@ function untracked(fn) {
|
|
|
2008
2008
|
resumeTracking();
|
|
2009
2009
|
}
|
|
2010
2010
|
}
|
|
2011
|
+
var currentOwnerScope = null;
|
|
2012
|
+
function getOwnerScope() {
|
|
2013
|
+
return currentOwnerScope;
|
|
2014
|
+
}
|
|
2015
|
+
function runWithOwnerScope(scope, fn) {
|
|
2016
|
+
const prev = currentOwnerScope;
|
|
2017
|
+
currentOwnerScope = scope;
|
|
2018
|
+
try {
|
|
2019
|
+
return fn();
|
|
2020
|
+
} finally {
|
|
2021
|
+
currentOwnerScope = prev;
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
function bindOwnerScope(fn) {
|
|
2025
|
+
const scope = currentOwnerScope;
|
|
2026
|
+
if (scope === null) return fn;
|
|
2027
|
+
return (...args) => runWithOwnerScope(scope, () => fn(...args));
|
|
2028
|
+
}
|
|
2011
2029
|
var subscriberEpochCounter = 0;
|
|
2012
2030
|
function retrack(effectFn, subscriber) {
|
|
2013
2031
|
const prev = currentSubscriber;
|
|
@@ -2023,6 +2041,10 @@ function retrack(effectFn, subscriber) {
|
|
|
2023
2041
|
currentSubscriber = subscriber;
|
|
2024
2042
|
const sub2 = subscriber;
|
|
2025
2043
|
if (sub2._cap === void 0) sub2._cap = currentDisposerCapture();
|
|
2044
|
+
const prevScope = currentOwnerScope;
|
|
2045
|
+
if (prevScope !== null && !sub2._epoch && sub2._scope === void 0) sub2._scope = prevScope;
|
|
2046
|
+
const scope = sub2._scope === void 0 ? null : sub2._scope;
|
|
2047
|
+
if (scope !== prevScope) currentOwnerScope = scope;
|
|
2026
2048
|
const epoch = ++subscriberEpochCounter;
|
|
2027
2049
|
sub2._epoch = epoch;
|
|
2028
2050
|
sub2._structDirty = false;
|
|
@@ -2035,6 +2057,7 @@ function retrack(effectFn, subscriber) {
|
|
|
2035
2057
|
effectFn();
|
|
2036
2058
|
} finally {
|
|
2037
2059
|
currentSubscriber = prev;
|
|
2060
|
+
currentOwnerScope = prevScope;
|
|
2038
2061
|
if (savedDepth !== 0) {
|
|
2039
2062
|
suspendDepth = savedDepth;
|
|
2040
2063
|
suspendSavedSub = savedSuspendSub;
|
|
@@ -2069,23 +2092,26 @@ function track(effectFn, subscriber) {
|
|
|
2069
2092
|
trackingSuspended = false;
|
|
2070
2093
|
}
|
|
2071
2094
|
currentSubscriber = subscriber;
|
|
2095
|
+
const sub2 = subscriber;
|
|
2096
|
+
if (sub2._scope === void 0) sub2._scope = currentOwnerScope;
|
|
2097
|
+
const prevScope = currentOwnerScope;
|
|
2098
|
+
currentOwnerScope = sub2._scope;
|
|
2072
2099
|
try {
|
|
2073
2100
|
effectFn();
|
|
2074
2101
|
} finally {
|
|
2075
2102
|
currentSubscriber = prev;
|
|
2103
|
+
currentOwnerScope = prevScope;
|
|
2076
2104
|
if (savedDepth !== 0) {
|
|
2077
2105
|
suspendDepth = savedDepth;
|
|
2078
2106
|
suspendSavedSub = savedSuspendSub;
|
|
2079
2107
|
trackingSuspended = true;
|
|
2080
2108
|
}
|
|
2081
|
-
|
|
2082
|
-
for (let n = sub3.depsHead ?? null; n !== null; n = n.subNext) {
|
|
2109
|
+
for (let n = sub2.depsHead ?? null; n !== null; n = n.subNext) {
|
|
2083
2110
|
const sig = n.sig;
|
|
2084
2111
|
sig.__activeNode = n.prevActive;
|
|
2085
2112
|
n.prevActive = null;
|
|
2086
2113
|
}
|
|
2087
2114
|
}
|
|
2088
|
-
const sub2 = subscriber;
|
|
2089
2115
|
return sub2._dispose ?? (sub2._dispose = () => cleanup(subscriber));
|
|
2090
2116
|
}
|
|
2091
2117
|
function reactiveBinding(commit, ownerNode) {
|
|
@@ -2355,7 +2381,7 @@ function forEachSubscriber(signal2, visit) {
|
|
|
2355
2381
|
}
|
|
2356
2382
|
|
|
2357
2383
|
// src/reactivity/track.ts
|
|
2358
|
-
var _runtimeVersion = true ? "4.
|
|
2384
|
+
var _runtimeVersion = true ? "4.10.0" : "dev";
|
|
2359
2385
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
2360
2386
|
function resolveReactiveApi() {
|
|
2361
2387
|
const g2 = globalThis;
|
|
@@ -2387,6 +2413,9 @@ function resolveReactiveApi() {
|
|
|
2387
2413
|
getSubscriberCount,
|
|
2388
2414
|
getSubscriberDeps,
|
|
2389
2415
|
forEachSubscriber,
|
|
2416
|
+
getOwnerScope,
|
|
2417
|
+
runWithOwnerScope,
|
|
2418
|
+
bindOwnerScope,
|
|
2390
2419
|
version: _runtimeVersion
|
|
2391
2420
|
};
|
|
2392
2421
|
g2[REGISTRY_KEY] = local;
|
|
@@ -2410,6 +2439,9 @@ var notifySubscribers2 = API.notifySubscribers;
|
|
|
2410
2439
|
var getSubscriberCount2 = API.getSubscriberCount;
|
|
2411
2440
|
var getSubscriberDeps2 = API.getSubscriberDeps;
|
|
2412
2441
|
var forEachSubscriber2 = API.forEachSubscriber;
|
|
2442
|
+
var getOwnerScope2 = API.getOwnerScope ?? getOwnerScope;
|
|
2443
|
+
var runWithOwnerScope2 = API.runWithOwnerScope ?? runWithOwnerScope;
|
|
2444
|
+
var bindOwnerScope2 = API.bindOwnerScope ?? bindOwnerScope;
|
|
2413
2445
|
|
|
2414
2446
|
// src/reactivity/bindAttribute.ts
|
|
2415
2447
|
function bindAttribute(el, attr, getter) {
|
|
@@ -3269,6 +3301,11 @@ function flushUserCleanups(ctx) {
|
|
|
3269
3301
|
const list = ctx.userCleanups;
|
|
3270
3302
|
if (list.length === 0) return;
|
|
3271
3303
|
ctx.userCleanups = [];
|
|
3304
|
+
const scope = ctx.subscriber._scope ?? null;
|
|
3305
|
+
if (scope === getOwnerScope2()) runCleanups(list);
|
|
3306
|
+
else runWithOwnerScope2(scope, () => runCleanups(list));
|
|
3307
|
+
}
|
|
3308
|
+
function runCleanups(list) {
|
|
3272
3309
|
for (let i2 = list.length - 1; i2 >= 0; i2--) {
|
|
3273
3310
|
try {
|
|
3274
3311
|
list[i2]();
|
|
@@ -3418,9 +3455,14 @@ function normalizePathname(path2) {
|
|
|
3418
3455
|
const trimmed = path2.length > 1 ? path2.replace(/\/+$/, "") : path2;
|
|
3419
3456
|
return trimmed || "/";
|
|
3420
3457
|
}
|
|
3421
|
-
function
|
|
3422
|
-
|
|
3423
|
-
|
|
3458
|
+
function parseQuery(query) {
|
|
3459
|
+
return Object.fromEntries(new URLSearchParams(query));
|
|
3460
|
+
}
|
|
3461
|
+
function paramsIdentity(params) {
|
|
3462
|
+
return JSON.stringify(Object.entries(params).sort(([a2], [b2]) => a2 < b2 ? -1 : a2 > b2 ? 1 : 0));
|
|
3463
|
+
}
|
|
3464
|
+
function queryIdentity(query) {
|
|
3465
|
+
return paramsIdentity(typeof query === "string" ? parseQuery(query) : query);
|
|
3424
3466
|
}
|
|
3425
3467
|
function isPathnameAncestor(target, current) {
|
|
3426
3468
|
if (target === current) return true;
|
|
@@ -3885,12 +3927,12 @@ var _ComponentLoader = class _ComponentLoader {
|
|
|
3885
3927
|
* resolved, so the import happens once and later mounts call the module's
|
|
3886
3928
|
* factory directly.
|
|
3887
3929
|
*/
|
|
3888
|
-
async instantiate(plan, route2, routePath) {
|
|
3930
|
+
async instantiate(plan, route2, routePath, scope) {
|
|
3889
3931
|
if (plan.kind === "factory") {
|
|
3890
|
-
return this.instantiateFactory(plan.component, route2, routePath);
|
|
3932
|
+
return this.instantiateFactory(plan.component, route2, routePath, scope);
|
|
3891
3933
|
}
|
|
3892
3934
|
const factory = await this.resolveModuleFactory(plan, route2, routePath);
|
|
3893
|
-
return this.instantiateFactory(factory, route2, routePath);
|
|
3935
|
+
return this.instantiateFactory(factory, route2, routePath, scope);
|
|
3894
3936
|
}
|
|
3895
3937
|
/**
|
|
3896
3938
|
* Resolve a deferred plan's module and cache the factory it exports —
|
|
@@ -3935,14 +3977,14 @@ var _ComponentLoader = class _ComponentLoader {
|
|
|
3935
3977
|
* `depth` bounds that unwrapping; a module whose default is itself a module
|
|
3936
3978
|
* is a configuration error, not something to chase.
|
|
3937
3979
|
*/
|
|
3938
|
-
async instantiateFactory(component, route2, routePath, depth = 0) {
|
|
3939
|
-
const result = component();
|
|
3980
|
+
async instantiateFactory(component, route2, routePath, scope, depth = 0) {
|
|
3981
|
+
const result = scope ? runWithOwnerScope2(scope, component) : component();
|
|
3940
3982
|
const value = this.isThenable(result) ? await result : result;
|
|
3941
3983
|
if (this.isElement(value)) return value;
|
|
3942
3984
|
if (depth === 0 && this.isFactoryLike(value)) {
|
|
3943
3985
|
const factory = this.extractFactory(value, routePath);
|
|
3944
3986
|
this.planCache.set(this.keyFor(route2), { kind: "factory", component: factory });
|
|
3945
|
-
return this.instantiateFactory(factory, route2, routePath, depth + 1);
|
|
3987
|
+
return this.instantiateFactory(factory, route2, routePath, scope, depth + 1);
|
|
3946
3988
|
}
|
|
3947
3989
|
throw new Error(`Component for route "${routePath}" must return Element, got ${typeof value}`);
|
|
3948
3990
|
}
|
|
@@ -4121,7 +4163,7 @@ var _SibuRouter = class _SibuRouter {
|
|
|
4121
4163
|
}
|
|
4122
4164
|
createRouteContext(fullPath) {
|
|
4123
4165
|
const { path: path2, query: queryString, hash } = splitRouteUrl(fullPath);
|
|
4124
|
-
const query =
|
|
4166
|
+
const query = parseQuery(queryString);
|
|
4125
4167
|
const match = this.matcher.match(path2 || "/");
|
|
4126
4168
|
const params = match?.params || {};
|
|
4127
4169
|
const meta2 = match?.route.meta || {};
|
|
@@ -4285,7 +4327,7 @@ var _SibuRouter = class _SibuRouter {
|
|
|
4285
4327
|
}
|
|
4286
4328
|
isSameRoute(from, to) {
|
|
4287
4329
|
if (from.matched.length === 0 && to.matched.length > 0) return false;
|
|
4288
|
-
return from.path === to.path &&
|
|
4330
|
+
return from.path === to.path && paramsIdentity(from.params) === paramsIdentity(to.params) && queryIdentity(from.query) === queryIdentity(to.query) && from.hash === to.hash;
|
|
4289
4331
|
}
|
|
4290
4332
|
updateHistory(to, options) {
|
|
4291
4333
|
const fullPath = this.options.base + to.path + (Object.keys(to.query).length ? `?${new URLSearchParams(to.query).toString()}` : "") + (to.hash ? `#${to.hash}` : "");
|
|
@@ -4347,9 +4389,12 @@ var _SibuRouter = class _SibuRouter {
|
|
|
4347
4389
|
async loadPlan(route2, routePath) {
|
|
4348
4390
|
return this.loader.loadPlan(route2, routePath);
|
|
4349
4391
|
}
|
|
4350
|
-
/**
|
|
4351
|
-
|
|
4352
|
-
|
|
4392
|
+
/**
|
|
4393
|
+
* Create exactly one real instance from an already-resolved plan. With a
|
|
4394
|
+
* `scope`, the factory runs in it (see `RouteScope`).
|
|
4395
|
+
*/
|
|
4396
|
+
async instantiateComponent(plan, route2, routePath, scope) {
|
|
4397
|
+
return this.loader.instantiate(plan, route2, routePath, scope);
|
|
4353
4398
|
}
|
|
4354
4399
|
/** Resolve a route's module/factory without creating any component instance. */
|
|
4355
4400
|
async preloadPlan(route2, routePath) {
|
|
@@ -4505,14 +4550,72 @@ function setRoutes(routes) {
|
|
|
4505
4550
|
if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
|
|
4506
4551
|
_routerRef.current.updateRoutes(normalizeRoutes(routes));
|
|
4507
4552
|
}
|
|
4553
|
+
var RouteScope = class {
|
|
4554
|
+
constructor(route2) {
|
|
4555
|
+
this.released = false;
|
|
4556
|
+
const [get, set] = signal(route2);
|
|
4557
|
+
this.get = get;
|
|
4558
|
+
this.set = set;
|
|
4559
|
+
}
|
|
4560
|
+
/** The instance's route, or `null` once released. Reactive. */
|
|
4561
|
+
read() {
|
|
4562
|
+
return this.get();
|
|
4563
|
+
}
|
|
4564
|
+
/** Hand a kept instance the route of the navigation that kept it. */
|
|
4565
|
+
update(route2) {
|
|
4566
|
+
if (!this.released) this.set(route2);
|
|
4567
|
+
}
|
|
4568
|
+
/**
|
|
4569
|
+
* Called when the instance is disposed. The switch to "no scope" is
|
|
4570
|
+
* published a microtask later, once the whole dispose has finished: a
|
|
4571
|
+
* teardown the instance registered after this one (an `onMount` effect, say)
|
|
4572
|
+
* may still be alive at this point, and must not re-run against the
|
|
4573
|
+
* router-global route on its way out.
|
|
4574
|
+
*/
|
|
4575
|
+
release() {
|
|
4576
|
+
if (this.released) return;
|
|
4577
|
+
this.released = true;
|
|
4578
|
+
queueMicrotask(() => this.set(null));
|
|
4579
|
+
}
|
|
4580
|
+
};
|
|
4581
|
+
function activeRouteScope() {
|
|
4582
|
+
const scope = getOwnerScope2();
|
|
4583
|
+
return scope instanceof RouteScope ? scope : null;
|
|
4584
|
+
}
|
|
4585
|
+
function scopedRoute(router2) {
|
|
4586
|
+
const scope = activeRouteScope();
|
|
4587
|
+
if (scope) {
|
|
4588
|
+
const committed = scope.read();
|
|
4589
|
+
if (committed !== null) return committed;
|
|
4590
|
+
}
|
|
4591
|
+
return router2.currentRoute;
|
|
4592
|
+
}
|
|
4593
|
+
var instanceScopes = /* @__PURE__ */ new WeakMap();
|
|
4594
|
+
async function instantiateScoped(router2, plan, routeDef, routePath, route2) {
|
|
4595
|
+
const scope = new RouteScope(route2);
|
|
4596
|
+
const node = await router2.instantiateComponent(plan, routeDef, routePath, scope);
|
|
4597
|
+
if (node) {
|
|
4598
|
+
instanceScopes.set(node, scope);
|
|
4599
|
+
registerDisposer(node, () => scope.release());
|
|
4600
|
+
}
|
|
4601
|
+
return node;
|
|
4602
|
+
}
|
|
4603
|
+
function updateInstanceRoute(node, route2) {
|
|
4604
|
+
if (node) instanceScopes.get(node)?.update(route2);
|
|
4605
|
+
}
|
|
4606
|
+
function disposeOwned(node) {
|
|
4607
|
+
const scope = instanceScopes.get(node);
|
|
4608
|
+
if (scope) runWithOwnerScope2(scope, () => dispose(node));
|
|
4609
|
+
else dispose(node);
|
|
4610
|
+
}
|
|
4508
4611
|
function route() {
|
|
4509
4612
|
if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
|
|
4510
|
-
return _routerRef.current
|
|
4613
|
+
return scopedRoute(_routerRef.current);
|
|
4511
4614
|
}
|
|
4512
4615
|
function router() {
|
|
4513
4616
|
if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
|
|
4514
4617
|
return {
|
|
4515
|
-
currentRoute: _routerRef.current
|
|
4618
|
+
currentRoute: scopedRoute(_routerRef.current),
|
|
4516
4619
|
isReady: _routerRef.current.isReady,
|
|
4517
4620
|
isNavigating: _routerRef.current.isNavigating,
|
|
4518
4621
|
push: (to) => _routerRef.current?.push(to),
|
|
@@ -4598,13 +4701,13 @@ function Route() {
|
|
|
4598
4701
|
const commitTarget = (seq) => routeTorn || seq !== navSeq ? null : anchor.parentNode;
|
|
4599
4702
|
const release = (node) => {
|
|
4600
4703
|
if (!node) return;
|
|
4601
|
-
|
|
4704
|
+
disposeOwned(node);
|
|
4602
4705
|
node.parentNode?.removeChild(node);
|
|
4603
4706
|
};
|
|
4604
4707
|
const cleanupNodes = () => {
|
|
4605
4708
|
[currentNode, loadingNode, errorNode].forEach((node) => {
|
|
4606
4709
|
if (!node) return;
|
|
4607
|
-
|
|
4710
|
+
disposeOwned(node);
|
|
4608
4711
|
if (node.parentNode) {
|
|
4609
4712
|
node.parentNode.removeChild(node);
|
|
4610
4713
|
}
|
|
@@ -4680,7 +4783,7 @@ function Route() {
|
|
|
4680
4783
|
const update = async () => {
|
|
4681
4784
|
if (routeTorn || !_routerRef.current) return;
|
|
4682
4785
|
const seq = ++navSeq;
|
|
4683
|
-
const route2 = _routerRef.current
|
|
4786
|
+
const route2 = scopedRoute(_routerRef.current);
|
|
4684
4787
|
try {
|
|
4685
4788
|
const match = _routerRef.current["matcher"].match(route2.path);
|
|
4686
4789
|
if (!match) {
|
|
@@ -4692,6 +4795,7 @@ function Route() {
|
|
|
4692
4795
|
const routeDef = match.matched[0] || match.route;
|
|
4693
4796
|
const key = instanceKey(routeDef, [routeDef], route2);
|
|
4694
4797
|
if (routeDef === currentTopRoute && key === currentKey && currentNode) {
|
|
4798
|
+
updateInstanceRoute(currentNode, route2);
|
|
4695
4799
|
return;
|
|
4696
4800
|
}
|
|
4697
4801
|
if ("redirect" in routeDef) {
|
|
@@ -4711,7 +4815,7 @@ function Route() {
|
|
|
4711
4815
|
}
|
|
4712
4816
|
const plan = await _routerRef.current.loadPlan(routeDef, route2.path);
|
|
4713
4817
|
if (!commitTarget(seq)) return;
|
|
4714
|
-
const node = await _routerRef.current
|
|
4818
|
+
const node = await instantiateScoped(_routerRef.current, plan, routeDef, route2.path, route2);
|
|
4715
4819
|
const parent = commitTarget(seq);
|
|
4716
4820
|
if (!parent) {
|
|
4717
4821
|
release(node);
|
|
@@ -4746,9 +4850,11 @@ function Route() {
|
|
|
4746
4850
|
};
|
|
4747
4851
|
const routeTeardown = track2(wrappedUpdate);
|
|
4748
4852
|
if (!routeInitialized) {
|
|
4749
|
-
queueMicrotask(
|
|
4750
|
-
|
|
4751
|
-
|
|
4853
|
+
queueMicrotask(
|
|
4854
|
+
bindOwnerScope2(() => {
|
|
4855
|
+
if (!routeInitialized && anchor.parentNode) wrappedUpdate();
|
|
4856
|
+
})
|
|
4857
|
+
);
|
|
4752
4858
|
}
|
|
4753
4859
|
const routeCleanup = () => {
|
|
4754
4860
|
if (routeTorn) return;
|
|
@@ -4781,7 +4887,7 @@ function KeepAliveRoute(options) {
|
|
|
4781
4887
|
if (kaTorn || !_routerRef.current) return;
|
|
4782
4888
|
const seq = ++updateSeq;
|
|
4783
4889
|
const router2 = _routerRef.current;
|
|
4784
|
-
const route2 = router2
|
|
4890
|
+
const route2 = scopedRoute(router2);
|
|
4785
4891
|
const match = router2["matcher"].match(route2.path);
|
|
4786
4892
|
if (!match) return;
|
|
4787
4893
|
const { route: routeDef } = match;
|
|
@@ -4795,10 +4901,12 @@ function KeepAliveRoute(options) {
|
|
|
4795
4901
|
return;
|
|
4796
4902
|
}
|
|
4797
4903
|
if (!("component" in routeDef)) return;
|
|
4798
|
-
const
|
|
4799
|
-
const cacheKey = `${route2.path}${queryStr}${route2.hash ? `#${route2.hash}` : ""}`;
|
|
4904
|
+
const cacheKey = JSON.stringify([route2.path, queryIdentity(route2.query), route2.hash]);
|
|
4800
4905
|
const shouldCache = !includeNames || routeDef.name != null && includeNames.includes(routeDef.name);
|
|
4801
|
-
if (cacheKey === currentKey && currentNode)
|
|
4906
|
+
if (cacheKey === currentKey && currentNode) {
|
|
4907
|
+
updateInstanceRoute(currentNode, route2);
|
|
4908
|
+
return;
|
|
4909
|
+
}
|
|
4802
4910
|
if (!anchor.parentNode) return;
|
|
4803
4911
|
let node = null;
|
|
4804
4912
|
let fromCache = false;
|
|
@@ -4809,7 +4917,7 @@ function KeepAliveRoute(options) {
|
|
|
4809
4917
|
try {
|
|
4810
4918
|
const plan = await router2.loadPlan(routeDef, route2.path);
|
|
4811
4919
|
if (kaTorn || seq !== updateSeq) return;
|
|
4812
|
-
node = await router2
|
|
4920
|
+
node = await instantiateScoped(router2, plan, routeDef, route2.path, route2);
|
|
4813
4921
|
} catch (error) {
|
|
4814
4922
|
if (kaTorn || seq !== updateSeq) return;
|
|
4815
4923
|
console.error("[KeepAliveRoute] Component error:", error);
|
|
@@ -4817,20 +4925,21 @@ function KeepAliveRoute(options) {
|
|
|
4817
4925
|
}
|
|
4818
4926
|
if (!node) return;
|
|
4819
4927
|
if (kaTorn || seq !== updateSeq) {
|
|
4820
|
-
|
|
4928
|
+
disposeOwned(node);
|
|
4821
4929
|
return;
|
|
4822
4930
|
}
|
|
4823
4931
|
}
|
|
4824
4932
|
const parent = anchor.parentNode;
|
|
4825
4933
|
if (!parent) {
|
|
4826
|
-
if (!fromCache)
|
|
4934
|
+
if (!fromCache) disposeOwned(node);
|
|
4827
4935
|
return;
|
|
4828
4936
|
}
|
|
4829
4937
|
if (currentNode && currentNode !== node) {
|
|
4830
4938
|
if (currentNode.parentNode) currentNode.parentNode.removeChild(currentNode);
|
|
4831
|
-
if (!currentCached)
|
|
4939
|
+
if (!currentCached) disposeOwned(currentNode);
|
|
4832
4940
|
}
|
|
4833
4941
|
if (fromCache) {
|
|
4942
|
+
updateInstanceRoute(node, route2);
|
|
4834
4943
|
const idx = lruOrder.indexOf(cacheKey);
|
|
4835
4944
|
if (idx !== -1) lruOrder.splice(idx, 1);
|
|
4836
4945
|
lruOrder.push(cacheKey);
|
|
@@ -4845,7 +4954,7 @@ function KeepAliveRoute(options) {
|
|
|
4845
4954
|
}
|
|
4846
4955
|
const evictNode = cache.get(evictKey);
|
|
4847
4956
|
if (evictNode) {
|
|
4848
|
-
|
|
4957
|
+
disposeOwned(evictNode);
|
|
4849
4958
|
if (evictNode.parentNode) evictNode.parentNode.removeChild(evictNode);
|
|
4850
4959
|
cache.delete(evictKey);
|
|
4851
4960
|
}
|
|
@@ -4863,9 +4972,11 @@ function KeepAliveRoute(options) {
|
|
|
4863
4972
|
};
|
|
4864
4973
|
const kaTeardown = track2(wrappedUpdate);
|
|
4865
4974
|
if (!initialized) {
|
|
4866
|
-
queueMicrotask(
|
|
4867
|
-
|
|
4868
|
-
|
|
4975
|
+
queueMicrotask(
|
|
4976
|
+
bindOwnerScope2(() => {
|
|
4977
|
+
if (!initialized && anchor.parentNode) wrappedUpdate();
|
|
4978
|
+
})
|
|
4979
|
+
);
|
|
4869
4980
|
}
|
|
4870
4981
|
const kaCleanup = () => {
|
|
4871
4982
|
if (kaTorn) return;
|
|
@@ -4873,13 +4984,13 @@ function KeepAliveRoute(options) {
|
|
|
4873
4984
|
updateSeq++;
|
|
4874
4985
|
kaTeardown();
|
|
4875
4986
|
for (const node of cache.values()) {
|
|
4876
|
-
|
|
4987
|
+
disposeOwned(node);
|
|
4877
4988
|
if (node.parentNode) node.parentNode.removeChild(node);
|
|
4878
4989
|
}
|
|
4879
4990
|
cache.clear();
|
|
4880
4991
|
lruOrder.length = 0;
|
|
4881
4992
|
if (currentNode?.parentNode) currentNode.parentNode.removeChild(currentNode);
|
|
4882
|
-
if (currentNode && !currentCached)
|
|
4993
|
+
if (currentNode && !currentCached) disposeOwned(currentNode);
|
|
4883
4994
|
currentNode = null;
|
|
4884
4995
|
currentKey = "";
|
|
4885
4996
|
currentCached = false;
|
|
@@ -4898,7 +5009,7 @@ function RouterLink(props, children) {
|
|
|
4898
5009
|
const href = kind === "unsafe" ? "#" : rawHref;
|
|
4899
5010
|
const { path: hrefPathRaw, query: hrefQueryRaw, hash: hrefHash } = splitRouteUrl(href);
|
|
4900
5011
|
const targetPath = normalizePathname(hrefPathRaw);
|
|
4901
|
-
const targetQuery =
|
|
5012
|
+
const targetQuery = queryIdentity(hrefQueryRaw);
|
|
4902
5013
|
const link2 = document.createElement("a");
|
|
4903
5014
|
link2.href = href;
|
|
4904
5015
|
if (target) {
|
|
@@ -4916,7 +5027,7 @@ function RouterLink(props, children) {
|
|
|
4916
5027
|
const route2 = routeGetter();
|
|
4917
5028
|
const currentPath = normalizePathname(route2.path);
|
|
4918
5029
|
const isActive = kind === "internal" && isPathnameAncestor(targetPath, currentPath);
|
|
4919
|
-
const isExactActive = kind === "internal" && currentPath === targetPath &&
|
|
5030
|
+
const isExactActive = kind === "internal" && currentPath === targetPath && queryIdentity(route2.query) === targetQuery && route2.hash === hrefHash;
|
|
4920
5031
|
const classes = [];
|
|
4921
5032
|
if (isActive) {
|
|
4922
5033
|
if (activeClass) classes.push(activeClass);
|
|
@@ -5035,7 +5146,7 @@ function Suspense(props) {
|
|
|
5035
5146
|
generation++;
|
|
5036
5147
|
cleanupNodes();
|
|
5037
5148
|
});
|
|
5038
|
-
queueMicrotask(render);
|
|
5149
|
+
queueMicrotask(bindOwnerScope2(render));
|
|
5039
5150
|
return anchor;
|
|
5040
5151
|
}
|
|
5041
5152
|
var LAZY_MARKER = /* @__PURE__ */ Symbol.for("sibujs:lazy");
|
|
@@ -5103,7 +5214,7 @@ function Outlet() {
|
|
|
5103
5214
|
let outletTorn = false;
|
|
5104
5215
|
const clearCurrent = () => {
|
|
5105
5216
|
if (currentNode) {
|
|
5106
|
-
|
|
5217
|
+
disposeOwned(currentNode);
|
|
5107
5218
|
if (currentNode.parentNode) currentNode.parentNode.removeChild(currentNode);
|
|
5108
5219
|
currentNode = null;
|
|
5109
5220
|
}
|
|
@@ -5113,13 +5224,13 @@ function Outlet() {
|
|
|
5113
5224
|
const commitTarget = (seq) => outletTorn || seq !== navSeq ? null : anchor.parentNode;
|
|
5114
5225
|
const release = (node) => {
|
|
5115
5226
|
if (!node) return;
|
|
5116
|
-
|
|
5227
|
+
disposeOwned(node);
|
|
5117
5228
|
node.parentNode?.removeChild(node);
|
|
5118
5229
|
};
|
|
5119
5230
|
const update = async () => {
|
|
5120
5231
|
if (outletTorn || !_routerRef.current) return;
|
|
5121
5232
|
const seq = ++navSeq;
|
|
5122
|
-
const route2 = _routerRef.current
|
|
5233
|
+
const route2 = scopedRoute(_routerRef.current);
|
|
5123
5234
|
if (route2.matched.length < 2) {
|
|
5124
5235
|
clearCurrent();
|
|
5125
5236
|
return;
|
|
@@ -5130,12 +5241,15 @@ function Outlet() {
|
|
|
5130
5241
|
return;
|
|
5131
5242
|
}
|
|
5132
5243
|
const key = instanceKey(childRoute, route2.matched.slice(1), route2);
|
|
5133
|
-
if (childRoute === currentChild && key === currentKey && currentNode)
|
|
5244
|
+
if (childRoute === currentChild && key === currentKey && currentNode) {
|
|
5245
|
+
updateInstanceRoute(currentNode, route2);
|
|
5246
|
+
return;
|
|
5247
|
+
}
|
|
5134
5248
|
try {
|
|
5135
5249
|
const cacheKey = `${route2.path}\0${childRoute.path}`;
|
|
5136
5250
|
const plan = await _routerRef.current.loadPlan(childRoute, cacheKey);
|
|
5137
5251
|
if (!commitTarget(seq)) return;
|
|
5138
|
-
const node = await _routerRef.current
|
|
5252
|
+
const node = await instantiateScoped(_routerRef.current, plan, childRoute, cacheKey, route2);
|
|
5139
5253
|
const parent = commitTarget(seq);
|
|
5140
5254
|
if (!parent) {
|
|
5141
5255
|
release(node);
|
|
@@ -5154,9 +5268,11 @@ function Outlet() {
|
|
|
5154
5268
|
};
|
|
5155
5269
|
const outletTeardown = track2(update);
|
|
5156
5270
|
if (!anchor.parentNode) {
|
|
5157
|
-
queueMicrotask(
|
|
5158
|
-
|
|
5159
|
-
|
|
5271
|
+
queueMicrotask(
|
|
5272
|
+
bindOwnerScope2(() => {
|
|
5273
|
+
if (anchor.parentNode) update();
|
|
5274
|
+
})
|
|
5275
|
+
);
|
|
5160
5276
|
}
|
|
5161
5277
|
const outletCleanup = () => {
|
|
5162
5278
|
if (outletTorn) return;
|
|
@@ -5164,7 +5280,7 @@ function Outlet() {
|
|
|
5164
5280
|
navSeq++;
|
|
5165
5281
|
outletTeardown();
|
|
5166
5282
|
if (currentNode) {
|
|
5167
|
-
|
|
5283
|
+
disposeOwned(currentNode);
|
|
5168
5284
|
if (currentNode.parentNode) currentNode.parentNode.removeChild(currentNode);
|
|
5169
5285
|
currentNode = null;
|
|
5170
5286
|
}
|
|
@@ -5187,11 +5303,11 @@ function routerState() {
|
|
|
5187
5303
|
if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
|
|
5188
5304
|
const router2 = _routerRef.current;
|
|
5189
5305
|
return {
|
|
5190
|
-
currentPath: () => router2.
|
|
5191
|
-
params: () => router2.
|
|
5192
|
-
query: () => router2.
|
|
5193
|
-
hash: () => router2.
|
|
5194
|
-
meta: () => router2.
|
|
5306
|
+
currentPath: () => scopedRoute(router2).path,
|
|
5307
|
+
params: () => scopedRoute(router2).params,
|
|
5308
|
+
query: () => scopedRoute(router2).query,
|
|
5309
|
+
hash: () => scopedRoute(router2).hash,
|
|
5310
|
+
meta: () => scopedRoute(router2).meta,
|
|
5195
5311
|
isNavigating: () => router2.isNavigating,
|
|
5196
5312
|
isReady: () => router2.isReady
|
|
5197
5313
|
};
|
|
@@ -5905,7 +6021,7 @@ var CDN_ENTRY_POINTS = {
|
|
|
5905
6021
|
};
|
|
5906
6022
|
var packageInfo = {
|
|
5907
6023
|
name: "sibujs",
|
|
5908
|
-
version: true ? "4.
|
|
6024
|
+
version: true ? "4.10.0" : "dev",
|
|
5909
6025
|
entryPoints: MODULE_ENTRY_POINTS,
|
|
5910
6026
|
/**
|
|
5911
6027
|
* Generate the package.json `exports` map. Module entries resolve to the
|
|
@@ -6050,7 +6166,7 @@ var env = {
|
|
|
6050
6166
|
};
|
|
6051
6167
|
|
|
6052
6168
|
// src/plugins/versioning.ts
|
|
6053
|
-
var VERSION = true ? "4.
|
|
6169
|
+
var VERSION = true ? "4.10.0" : "dev";
|
|
6054
6170
|
var NUM = "(?:0|[1-9]\\d*)";
|
|
6055
6171
|
var PRE_ID = `(?:${NUM}|\\d*[a-zA-Z-][0-9a-zA-Z-]*)`;
|
|
6056
6172
|
var BUILD_ID = "[0-9a-zA-Z-]+";
|
package/dist/plugins.d.cts
CHANGED
|
@@ -180,6 +180,12 @@ type Params = Record<string, string>;
|
|
|
180
180
|
interface RouteContext {
|
|
181
181
|
readonly path: string;
|
|
182
182
|
readonly params: Params;
|
|
183
|
+
/**
|
|
184
|
+
* The decoded query (`+` is a space, `%XX` is decoded). A repeated key keeps
|
|
185
|
+
* its last value: `?tag=a&tag=b` is `{ tag: "b" }`. Two locations are the
|
|
186
|
+
* same route — for duplicate detection and `RouterLink` exact-active — when
|
|
187
|
+
* their queries have the same entries in any order.
|
|
188
|
+
*/
|
|
183
189
|
readonly query: Params;
|
|
184
190
|
readonly hash: string;
|
|
185
191
|
readonly meta: RouteMeta;
|
|
@@ -421,8 +427,11 @@ declare class SibuRouter {
|
|
|
421
427
|
* anything. Pair with {@link instantiateComponent} at the commit boundary.
|
|
422
428
|
*/
|
|
423
429
|
loadPlan(route: RouteDef, routePath: string): Promise<RoutePlan>;
|
|
424
|
-
/**
|
|
425
|
-
|
|
430
|
+
/**
|
|
431
|
+
* Create exactly one real instance from an already-resolved plan. With a
|
|
432
|
+
* `scope`, the factory runs in it (see `RouteScope`).
|
|
433
|
+
*/
|
|
434
|
+
instantiateComponent(plan: RoutePlan, route: RouteDef, routePath: string, scope?: RouteScope): Promise<Element>;
|
|
426
435
|
/** Resolve a route's module/factory without creating any component instance. */
|
|
427
436
|
preloadPlan(route: RouteDef, routePath: string): Promise<void>;
|
|
428
437
|
beforeEach(guard: NavigationGuard): () => void;
|
|
@@ -469,6 +478,50 @@ declare function createRouter(routesOrOptions: RouteDef[] | RouterOptions, optio
|
|
|
469
478
|
* Set routes on the global router (replaces existing routes).
|
|
470
479
|
*/
|
|
471
480
|
declare function setRoutes(routes: RouteDef[]): void;
|
|
481
|
+
/**
|
|
482
|
+
* The route one mounted route instance was committed with.
|
|
483
|
+
*
|
|
484
|
+
* A navigation commits the router's route first; the outlet swaps the
|
|
485
|
+
* component afterwards — a microtask later for a synchronous page, a whole
|
|
486
|
+
* chunk download later for a lazy one. If route instances read the
|
|
487
|
+
* router-global route, the outgoing page re-runs its effects against the
|
|
488
|
+
* INCOMING route's params in that window, and its teardown sees them too.
|
|
489
|
+
*
|
|
490
|
+
* So each instance reads its own scope instead. Outlets create one per
|
|
491
|
+
* instance, run the component factory in it (an owner scope, see
|
|
492
|
+
* reactivity/track-core.ts, so every computation the page creates — now or
|
|
493
|
+
* later, through its directives — inherits it), and then:
|
|
494
|
+
*
|
|
495
|
+
* - an instance the outlet KEEPS across a navigation (same record and instance
|
|
496
|
+
* key: a query/hash-only change, or a layout whose child changed) is handed
|
|
497
|
+
* the new route — it follows the navigation, as before;
|
|
498
|
+
* - an instance being REPLACED is never updated: it keeps observing its own
|
|
499
|
+
* route until it is disposed, and its teardown runs in its scope;
|
|
500
|
+
* - a KeepAlive view keeps its route while cached and gets the new route when
|
|
501
|
+
* it is shown again.
|
|
502
|
+
*
|
|
503
|
+
* Once the instance is disposed the scope is released: a computation that
|
|
504
|
+
* outlived it (an app-lifetime derived that happened to be created while the
|
|
505
|
+
* page rendered) is not the page's, and falls back to the router-global route.
|
|
506
|
+
*/
|
|
507
|
+
declare class RouteScope {
|
|
508
|
+
private readonly get;
|
|
509
|
+
private readonly set;
|
|
510
|
+
private released;
|
|
511
|
+
constructor(route: RouteContext);
|
|
512
|
+
/** The instance's route, or `null` once released. Reactive. */
|
|
513
|
+
read(): RouteContext | null;
|
|
514
|
+
/** Hand a kept instance the route of the navigation that kept it. */
|
|
515
|
+
update(route: RouteContext): void;
|
|
516
|
+
/**
|
|
517
|
+
* Called when the instance is disposed. The switch to "no scope" is
|
|
518
|
+
* published a microtask later, once the whole dispose has finished: a
|
|
519
|
+
* teardown the instance registered after this one (an `onMount` effect, say)
|
|
520
|
+
* may still be alive at this point, and must not re-run against the
|
|
521
|
+
* router-global route on its way out.
|
|
522
|
+
*/
|
|
523
|
+
release(): void;
|
|
524
|
+
}
|
|
472
525
|
/**
|
|
473
526
|
* Read the current route as a plain snapshot.
|
|
474
527
|
*
|
|
@@ -477,6 +530,13 @@ declare function setRoutes(routes: RouteDef[]): void;
|
|
|
477
530
|
* `RouteBase.key`). Inside a getter — `() => route().params.id` — the read is
|
|
478
531
|
* reactive, which is what a long-lived layout or a constant-`key` route needs.
|
|
479
532
|
*
|
|
533
|
+
* Inside a route instance (anything its component creates, and any effect,
|
|
534
|
+
* derived or binding created from there) this is the route THAT INSTANCE was
|
|
535
|
+
* committed with. An instance the outlet keeps across a navigation follows it;
|
|
536
|
+
* an instance being replaced keeps its own route until it is disposed, so its
|
|
537
|
+
* effects and teardown never observe the next page's params. Everywhere else
|
|
538
|
+
* it is the router's current route.
|
|
539
|
+
*
|
|
480
540
|
* @returns The active {@link RouteContext} (path, params, query, hash).
|
|
481
541
|
* @throws If no router has been created yet.
|
|
482
542
|
*/
|