sibujs 4.9.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 +41 -4
- package/dist/browser.js +4 -4
- package/dist/build.cjs +102 -38
- 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-FNOK662L.js → chunk-2NWHJ2UJ.js} +73 -43
- package/dist/{chunk-KG25XMGP.js → chunk-4DCVJ4YA.js} +15 -8
- package/dist/{chunk-CF2KCWRE.js → chunk-54F4TPHK.js} +2 -2
- package/dist/{chunk-X7NRHFZR.js → chunk-5PC7OTQW.js} +1 -1
- package/dist/{chunk-SBTZEYNI.js → chunk-7WIHYHWD.js} +8 -1
- package/dist/{chunk-K6K5ACO6.js → chunk-BMCR7TXG.js} +3 -3
- package/dist/{chunk-G2WHYEL7.js → chunk-D6HYFOWR.js} +39 -4
- package/dist/{chunk-5MLWTIQE.js → chunk-EVI4ZQO3.js} +2 -2
- package/dist/{chunk-CDBKFGXN.js → chunk-EVOK663Z.js} +1 -1
- package/dist/{chunk-SYHGGDNW.js → chunk-FYUEL5IW.js} +1 -1
- package/dist/{chunk-562UVHMM.js → chunk-GMMDHJJT.js} +11 -6
- package/dist/{chunk-FHCZMHHE.js → chunk-GOL3FU5Q.js} +1 -1
- package/dist/{chunk-YW6HQKGO.js → chunk-GTS35FLA.js} +2 -2
- package/dist/{chunk-2K3Z3XO4.js → chunk-IFRIBZ4O.js} +4 -4
- package/dist/{chunk-DRMLIF6M.js → chunk-IL5MMSCL.js} +19 -12
- package/dist/{chunk-XJVTQUIV.js → chunk-ITEL5KPL.js} +5 -5
- package/dist/{chunk-TV464N2M.js → chunk-JCKUWWHU.js} +3 -3
- package/dist/{chunk-QBKCK6MJ.js → chunk-N6U4GOIU.js} +1 -1
- package/dist/{chunk-NQMKWBKU.js → chunk-TOPRMXFY.js} +1 -1
- package/dist/{chunk-7OV5Q2UU.js → chunk-VWPMWV7O.js} +4 -4
- package/dist/{chunk-MPWDSTYK.js → chunk-XUQUQJYE.js} +1 -1
- package/dist/data.cjs +48 -6
- package/dist/data.d.cts +9 -1
- package/dist/data.d.ts +9 -1
- 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 +75 -25
- package/dist/extras.js +20 -20
- package/dist/index.cjs +102 -38
- package/dist/index.d.cts +16 -0
- package/dist/index.d.ts +16 -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 +163 -51
- package/dist/plugins.d.cts +56 -2
- package/dist/plugins.d.ts +56 -2
- package/dist/plugins.js +130 -52
- package/dist/ssr.cjs +50 -9
- package/dist/ssr.js +7 -7
- package/dist/testing.cjs +41 -4
- package/dist/testing.js +2 -2
- package/dist/ui.cjs +41 -4
- 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]();
|
|
@@ -3890,12 +3927,12 @@ var _ComponentLoader = class _ComponentLoader {
|
|
|
3890
3927
|
* resolved, so the import happens once and later mounts call the module's
|
|
3891
3928
|
* factory directly.
|
|
3892
3929
|
*/
|
|
3893
|
-
async instantiate(plan, route2, routePath) {
|
|
3930
|
+
async instantiate(plan, route2, routePath, scope) {
|
|
3894
3931
|
if (plan.kind === "factory") {
|
|
3895
|
-
return this.instantiateFactory(plan.component, route2, routePath);
|
|
3932
|
+
return this.instantiateFactory(plan.component, route2, routePath, scope);
|
|
3896
3933
|
}
|
|
3897
3934
|
const factory = await this.resolveModuleFactory(plan, route2, routePath);
|
|
3898
|
-
return this.instantiateFactory(factory, route2, routePath);
|
|
3935
|
+
return this.instantiateFactory(factory, route2, routePath, scope);
|
|
3899
3936
|
}
|
|
3900
3937
|
/**
|
|
3901
3938
|
* Resolve a deferred plan's module and cache the factory it exports —
|
|
@@ -3940,14 +3977,14 @@ var _ComponentLoader = class _ComponentLoader {
|
|
|
3940
3977
|
* `depth` bounds that unwrapping; a module whose default is itself a module
|
|
3941
3978
|
* is a configuration error, not something to chase.
|
|
3942
3979
|
*/
|
|
3943
|
-
async instantiateFactory(component, route2, routePath, depth = 0) {
|
|
3944
|
-
const result = component();
|
|
3980
|
+
async instantiateFactory(component, route2, routePath, scope, depth = 0) {
|
|
3981
|
+
const result = scope ? runWithOwnerScope2(scope, component) : component();
|
|
3945
3982
|
const value = this.isThenable(result) ? await result : result;
|
|
3946
3983
|
if (this.isElement(value)) return value;
|
|
3947
3984
|
if (depth === 0 && this.isFactoryLike(value)) {
|
|
3948
3985
|
const factory = this.extractFactory(value, routePath);
|
|
3949
3986
|
this.planCache.set(this.keyFor(route2), { kind: "factory", component: factory });
|
|
3950
|
-
return this.instantiateFactory(factory, route2, routePath, depth + 1);
|
|
3987
|
+
return this.instantiateFactory(factory, route2, routePath, scope, depth + 1);
|
|
3951
3988
|
}
|
|
3952
3989
|
throw new Error(`Component for route "${routePath}" must return Element, got ${typeof value}`);
|
|
3953
3990
|
}
|
|
@@ -4352,9 +4389,12 @@ var _SibuRouter = class _SibuRouter {
|
|
|
4352
4389
|
async loadPlan(route2, routePath) {
|
|
4353
4390
|
return this.loader.loadPlan(route2, routePath);
|
|
4354
4391
|
}
|
|
4355
|
-
/**
|
|
4356
|
-
|
|
4357
|
-
|
|
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);
|
|
4358
4398
|
}
|
|
4359
4399
|
/** Resolve a route's module/factory without creating any component instance. */
|
|
4360
4400
|
async preloadPlan(route2, routePath) {
|
|
@@ -4510,14 +4550,72 @@ function setRoutes(routes) {
|
|
|
4510
4550
|
if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
|
|
4511
4551
|
_routerRef.current.updateRoutes(normalizeRoutes(routes));
|
|
4512
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
|
+
}
|
|
4513
4611
|
function route() {
|
|
4514
4612
|
if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
|
|
4515
|
-
return _routerRef.current
|
|
4613
|
+
return scopedRoute(_routerRef.current);
|
|
4516
4614
|
}
|
|
4517
4615
|
function router() {
|
|
4518
4616
|
if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
|
|
4519
4617
|
return {
|
|
4520
|
-
currentRoute: _routerRef.current
|
|
4618
|
+
currentRoute: scopedRoute(_routerRef.current),
|
|
4521
4619
|
isReady: _routerRef.current.isReady,
|
|
4522
4620
|
isNavigating: _routerRef.current.isNavigating,
|
|
4523
4621
|
push: (to) => _routerRef.current?.push(to),
|
|
@@ -4603,13 +4701,13 @@ function Route() {
|
|
|
4603
4701
|
const commitTarget = (seq) => routeTorn || seq !== navSeq ? null : anchor.parentNode;
|
|
4604
4702
|
const release = (node) => {
|
|
4605
4703
|
if (!node) return;
|
|
4606
|
-
|
|
4704
|
+
disposeOwned(node);
|
|
4607
4705
|
node.parentNode?.removeChild(node);
|
|
4608
4706
|
};
|
|
4609
4707
|
const cleanupNodes = () => {
|
|
4610
4708
|
[currentNode, loadingNode, errorNode].forEach((node) => {
|
|
4611
4709
|
if (!node) return;
|
|
4612
|
-
|
|
4710
|
+
disposeOwned(node);
|
|
4613
4711
|
if (node.parentNode) {
|
|
4614
4712
|
node.parentNode.removeChild(node);
|
|
4615
4713
|
}
|
|
@@ -4685,7 +4783,7 @@ function Route() {
|
|
|
4685
4783
|
const update = async () => {
|
|
4686
4784
|
if (routeTorn || !_routerRef.current) return;
|
|
4687
4785
|
const seq = ++navSeq;
|
|
4688
|
-
const route2 = _routerRef.current
|
|
4786
|
+
const route2 = scopedRoute(_routerRef.current);
|
|
4689
4787
|
try {
|
|
4690
4788
|
const match = _routerRef.current["matcher"].match(route2.path);
|
|
4691
4789
|
if (!match) {
|
|
@@ -4697,6 +4795,7 @@ function Route() {
|
|
|
4697
4795
|
const routeDef = match.matched[0] || match.route;
|
|
4698
4796
|
const key = instanceKey(routeDef, [routeDef], route2);
|
|
4699
4797
|
if (routeDef === currentTopRoute && key === currentKey && currentNode) {
|
|
4798
|
+
updateInstanceRoute(currentNode, route2);
|
|
4700
4799
|
return;
|
|
4701
4800
|
}
|
|
4702
4801
|
if ("redirect" in routeDef) {
|
|
@@ -4716,7 +4815,7 @@ function Route() {
|
|
|
4716
4815
|
}
|
|
4717
4816
|
const plan = await _routerRef.current.loadPlan(routeDef, route2.path);
|
|
4718
4817
|
if (!commitTarget(seq)) return;
|
|
4719
|
-
const node = await _routerRef.current
|
|
4818
|
+
const node = await instantiateScoped(_routerRef.current, plan, routeDef, route2.path, route2);
|
|
4720
4819
|
const parent = commitTarget(seq);
|
|
4721
4820
|
if (!parent) {
|
|
4722
4821
|
release(node);
|
|
@@ -4751,9 +4850,11 @@ function Route() {
|
|
|
4751
4850
|
};
|
|
4752
4851
|
const routeTeardown = track2(wrappedUpdate);
|
|
4753
4852
|
if (!routeInitialized) {
|
|
4754
|
-
queueMicrotask(
|
|
4755
|
-
|
|
4756
|
-
|
|
4853
|
+
queueMicrotask(
|
|
4854
|
+
bindOwnerScope2(() => {
|
|
4855
|
+
if (!routeInitialized && anchor.parentNode) wrappedUpdate();
|
|
4856
|
+
})
|
|
4857
|
+
);
|
|
4757
4858
|
}
|
|
4758
4859
|
const routeCleanup = () => {
|
|
4759
4860
|
if (routeTorn) return;
|
|
@@ -4786,7 +4887,7 @@ function KeepAliveRoute(options) {
|
|
|
4786
4887
|
if (kaTorn || !_routerRef.current) return;
|
|
4787
4888
|
const seq = ++updateSeq;
|
|
4788
4889
|
const router2 = _routerRef.current;
|
|
4789
|
-
const route2 = router2
|
|
4890
|
+
const route2 = scopedRoute(router2);
|
|
4790
4891
|
const match = router2["matcher"].match(route2.path);
|
|
4791
4892
|
if (!match) return;
|
|
4792
4893
|
const { route: routeDef } = match;
|
|
@@ -4802,7 +4903,10 @@ function KeepAliveRoute(options) {
|
|
|
4802
4903
|
if (!("component" in routeDef)) return;
|
|
4803
4904
|
const cacheKey = JSON.stringify([route2.path, queryIdentity(route2.query), route2.hash]);
|
|
4804
4905
|
const shouldCache = !includeNames || routeDef.name != null && includeNames.includes(routeDef.name);
|
|
4805
|
-
if (cacheKey === currentKey && currentNode)
|
|
4906
|
+
if (cacheKey === currentKey && currentNode) {
|
|
4907
|
+
updateInstanceRoute(currentNode, route2);
|
|
4908
|
+
return;
|
|
4909
|
+
}
|
|
4806
4910
|
if (!anchor.parentNode) return;
|
|
4807
4911
|
let node = null;
|
|
4808
4912
|
let fromCache = false;
|
|
@@ -4813,7 +4917,7 @@ function KeepAliveRoute(options) {
|
|
|
4813
4917
|
try {
|
|
4814
4918
|
const plan = await router2.loadPlan(routeDef, route2.path);
|
|
4815
4919
|
if (kaTorn || seq !== updateSeq) return;
|
|
4816
|
-
node = await router2
|
|
4920
|
+
node = await instantiateScoped(router2, plan, routeDef, route2.path, route2);
|
|
4817
4921
|
} catch (error) {
|
|
4818
4922
|
if (kaTorn || seq !== updateSeq) return;
|
|
4819
4923
|
console.error("[KeepAliveRoute] Component error:", error);
|
|
@@ -4821,20 +4925,21 @@ function KeepAliveRoute(options) {
|
|
|
4821
4925
|
}
|
|
4822
4926
|
if (!node) return;
|
|
4823
4927
|
if (kaTorn || seq !== updateSeq) {
|
|
4824
|
-
|
|
4928
|
+
disposeOwned(node);
|
|
4825
4929
|
return;
|
|
4826
4930
|
}
|
|
4827
4931
|
}
|
|
4828
4932
|
const parent = anchor.parentNode;
|
|
4829
4933
|
if (!parent) {
|
|
4830
|
-
if (!fromCache)
|
|
4934
|
+
if (!fromCache) disposeOwned(node);
|
|
4831
4935
|
return;
|
|
4832
4936
|
}
|
|
4833
4937
|
if (currentNode && currentNode !== node) {
|
|
4834
4938
|
if (currentNode.parentNode) currentNode.parentNode.removeChild(currentNode);
|
|
4835
|
-
if (!currentCached)
|
|
4939
|
+
if (!currentCached) disposeOwned(currentNode);
|
|
4836
4940
|
}
|
|
4837
4941
|
if (fromCache) {
|
|
4942
|
+
updateInstanceRoute(node, route2);
|
|
4838
4943
|
const idx = lruOrder.indexOf(cacheKey);
|
|
4839
4944
|
if (idx !== -1) lruOrder.splice(idx, 1);
|
|
4840
4945
|
lruOrder.push(cacheKey);
|
|
@@ -4849,7 +4954,7 @@ function KeepAliveRoute(options) {
|
|
|
4849
4954
|
}
|
|
4850
4955
|
const evictNode = cache.get(evictKey);
|
|
4851
4956
|
if (evictNode) {
|
|
4852
|
-
|
|
4957
|
+
disposeOwned(evictNode);
|
|
4853
4958
|
if (evictNode.parentNode) evictNode.parentNode.removeChild(evictNode);
|
|
4854
4959
|
cache.delete(evictKey);
|
|
4855
4960
|
}
|
|
@@ -4867,9 +4972,11 @@ function KeepAliveRoute(options) {
|
|
|
4867
4972
|
};
|
|
4868
4973
|
const kaTeardown = track2(wrappedUpdate);
|
|
4869
4974
|
if (!initialized) {
|
|
4870
|
-
queueMicrotask(
|
|
4871
|
-
|
|
4872
|
-
|
|
4975
|
+
queueMicrotask(
|
|
4976
|
+
bindOwnerScope2(() => {
|
|
4977
|
+
if (!initialized && anchor.parentNode) wrappedUpdate();
|
|
4978
|
+
})
|
|
4979
|
+
);
|
|
4873
4980
|
}
|
|
4874
4981
|
const kaCleanup = () => {
|
|
4875
4982
|
if (kaTorn) return;
|
|
@@ -4877,13 +4984,13 @@ function KeepAliveRoute(options) {
|
|
|
4877
4984
|
updateSeq++;
|
|
4878
4985
|
kaTeardown();
|
|
4879
4986
|
for (const node of cache.values()) {
|
|
4880
|
-
|
|
4987
|
+
disposeOwned(node);
|
|
4881
4988
|
if (node.parentNode) node.parentNode.removeChild(node);
|
|
4882
4989
|
}
|
|
4883
4990
|
cache.clear();
|
|
4884
4991
|
lruOrder.length = 0;
|
|
4885
4992
|
if (currentNode?.parentNode) currentNode.parentNode.removeChild(currentNode);
|
|
4886
|
-
if (currentNode && !currentCached)
|
|
4993
|
+
if (currentNode && !currentCached) disposeOwned(currentNode);
|
|
4887
4994
|
currentNode = null;
|
|
4888
4995
|
currentKey = "";
|
|
4889
4996
|
currentCached = false;
|
|
@@ -5039,7 +5146,7 @@ function Suspense(props) {
|
|
|
5039
5146
|
generation++;
|
|
5040
5147
|
cleanupNodes();
|
|
5041
5148
|
});
|
|
5042
|
-
queueMicrotask(render);
|
|
5149
|
+
queueMicrotask(bindOwnerScope2(render));
|
|
5043
5150
|
return anchor;
|
|
5044
5151
|
}
|
|
5045
5152
|
var LAZY_MARKER = /* @__PURE__ */ Symbol.for("sibujs:lazy");
|
|
@@ -5107,7 +5214,7 @@ function Outlet() {
|
|
|
5107
5214
|
let outletTorn = false;
|
|
5108
5215
|
const clearCurrent = () => {
|
|
5109
5216
|
if (currentNode) {
|
|
5110
|
-
|
|
5217
|
+
disposeOwned(currentNode);
|
|
5111
5218
|
if (currentNode.parentNode) currentNode.parentNode.removeChild(currentNode);
|
|
5112
5219
|
currentNode = null;
|
|
5113
5220
|
}
|
|
@@ -5117,13 +5224,13 @@ function Outlet() {
|
|
|
5117
5224
|
const commitTarget = (seq) => outletTorn || seq !== navSeq ? null : anchor.parentNode;
|
|
5118
5225
|
const release = (node) => {
|
|
5119
5226
|
if (!node) return;
|
|
5120
|
-
|
|
5227
|
+
disposeOwned(node);
|
|
5121
5228
|
node.parentNode?.removeChild(node);
|
|
5122
5229
|
};
|
|
5123
5230
|
const update = async () => {
|
|
5124
5231
|
if (outletTorn || !_routerRef.current) return;
|
|
5125
5232
|
const seq = ++navSeq;
|
|
5126
|
-
const route2 = _routerRef.current
|
|
5233
|
+
const route2 = scopedRoute(_routerRef.current);
|
|
5127
5234
|
if (route2.matched.length < 2) {
|
|
5128
5235
|
clearCurrent();
|
|
5129
5236
|
return;
|
|
@@ -5134,12 +5241,15 @@ function Outlet() {
|
|
|
5134
5241
|
return;
|
|
5135
5242
|
}
|
|
5136
5243
|
const key = instanceKey(childRoute, route2.matched.slice(1), route2);
|
|
5137
|
-
if (childRoute === currentChild && key === currentKey && currentNode)
|
|
5244
|
+
if (childRoute === currentChild && key === currentKey && currentNode) {
|
|
5245
|
+
updateInstanceRoute(currentNode, route2);
|
|
5246
|
+
return;
|
|
5247
|
+
}
|
|
5138
5248
|
try {
|
|
5139
5249
|
const cacheKey = `${route2.path}\0${childRoute.path}`;
|
|
5140
5250
|
const plan = await _routerRef.current.loadPlan(childRoute, cacheKey);
|
|
5141
5251
|
if (!commitTarget(seq)) return;
|
|
5142
|
-
const node = await _routerRef.current
|
|
5252
|
+
const node = await instantiateScoped(_routerRef.current, plan, childRoute, cacheKey, route2);
|
|
5143
5253
|
const parent = commitTarget(seq);
|
|
5144
5254
|
if (!parent) {
|
|
5145
5255
|
release(node);
|
|
@@ -5158,9 +5268,11 @@ function Outlet() {
|
|
|
5158
5268
|
};
|
|
5159
5269
|
const outletTeardown = track2(update);
|
|
5160
5270
|
if (!anchor.parentNode) {
|
|
5161
|
-
queueMicrotask(
|
|
5162
|
-
|
|
5163
|
-
|
|
5271
|
+
queueMicrotask(
|
|
5272
|
+
bindOwnerScope2(() => {
|
|
5273
|
+
if (anchor.parentNode) update();
|
|
5274
|
+
})
|
|
5275
|
+
);
|
|
5164
5276
|
}
|
|
5165
5277
|
const outletCleanup = () => {
|
|
5166
5278
|
if (outletTorn) return;
|
|
@@ -5168,7 +5280,7 @@ function Outlet() {
|
|
|
5168
5280
|
navSeq++;
|
|
5169
5281
|
outletTeardown();
|
|
5170
5282
|
if (currentNode) {
|
|
5171
|
-
|
|
5283
|
+
disposeOwned(currentNode);
|
|
5172
5284
|
if (currentNode.parentNode) currentNode.parentNode.removeChild(currentNode);
|
|
5173
5285
|
currentNode = null;
|
|
5174
5286
|
}
|
|
@@ -5191,11 +5303,11 @@ function routerState() {
|
|
|
5191
5303
|
if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
|
|
5192
5304
|
const router2 = _routerRef.current;
|
|
5193
5305
|
return {
|
|
5194
|
-
currentPath: () => router2.
|
|
5195
|
-
params: () => router2.
|
|
5196
|
-
query: () => router2.
|
|
5197
|
-
hash: () => router2.
|
|
5198
|
-
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,
|
|
5199
5311
|
isNavigating: () => router2.isNavigating,
|
|
5200
5312
|
isReady: () => router2.isReady
|
|
5201
5313
|
};
|
|
@@ -5909,7 +6021,7 @@ var CDN_ENTRY_POINTS = {
|
|
|
5909
6021
|
};
|
|
5910
6022
|
var packageInfo = {
|
|
5911
6023
|
name: "sibujs",
|
|
5912
|
-
version: true ? "4.
|
|
6024
|
+
version: true ? "4.10.0" : "dev",
|
|
5913
6025
|
entryPoints: MODULE_ENTRY_POINTS,
|
|
5914
6026
|
/**
|
|
5915
6027
|
* Generate the package.json `exports` map. Module entries resolve to the
|
|
@@ -6054,7 +6166,7 @@ var env = {
|
|
|
6054
6166
|
};
|
|
6055
6167
|
|
|
6056
6168
|
// src/plugins/versioning.ts
|
|
6057
|
-
var VERSION = true ? "4.
|
|
6169
|
+
var VERSION = true ? "4.10.0" : "dev";
|
|
6058
6170
|
var NUM = "(?:0|[1-9]\\d*)";
|
|
6059
6171
|
var PRE_ID = `(?:${NUM}|\\d*[a-zA-Z-][0-9a-zA-Z-]*)`;
|
|
6060
6172
|
var BUILD_ID = "[0-9a-zA-Z-]+";
|
package/dist/plugins.d.cts
CHANGED
|
@@ -427,8 +427,11 @@ declare class SibuRouter {
|
|
|
427
427
|
* anything. Pair with {@link instantiateComponent} at the commit boundary.
|
|
428
428
|
*/
|
|
429
429
|
loadPlan(route: RouteDef, routePath: string): Promise<RoutePlan>;
|
|
430
|
-
/**
|
|
431
|
-
|
|
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>;
|
|
432
435
|
/** Resolve a route's module/factory without creating any component instance. */
|
|
433
436
|
preloadPlan(route: RouteDef, routePath: string): Promise<void>;
|
|
434
437
|
beforeEach(guard: NavigationGuard): () => void;
|
|
@@ -475,6 +478,50 @@ declare function createRouter(routesOrOptions: RouteDef[] | RouterOptions, optio
|
|
|
475
478
|
* Set routes on the global router (replaces existing routes).
|
|
476
479
|
*/
|
|
477
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
|
+
}
|
|
478
525
|
/**
|
|
479
526
|
* Read the current route as a plain snapshot.
|
|
480
527
|
*
|
|
@@ -483,6 +530,13 @@ declare function setRoutes(routes: RouteDef[]): void;
|
|
|
483
530
|
* `RouteBase.key`). Inside a getter — `() => route().params.id` — the read is
|
|
484
531
|
* reactive, which is what a long-lived layout or a constant-`key` route needs.
|
|
485
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
|
+
*
|
|
486
540
|
* @returns The active {@link RouteContext} (path, params, query, hash).
|
|
487
541
|
* @throws If no router has been created yet.
|
|
488
542
|
*/
|
package/dist/plugins.d.ts
CHANGED
|
@@ -427,8 +427,11 @@ declare class SibuRouter {
|
|
|
427
427
|
* anything. Pair with {@link instantiateComponent} at the commit boundary.
|
|
428
428
|
*/
|
|
429
429
|
loadPlan(route: RouteDef, routePath: string): Promise<RoutePlan>;
|
|
430
|
-
/**
|
|
431
|
-
|
|
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>;
|
|
432
435
|
/** Resolve a route's module/factory without creating any component instance. */
|
|
433
436
|
preloadPlan(route: RouteDef, routePath: string): Promise<void>;
|
|
434
437
|
beforeEach(guard: NavigationGuard): () => void;
|
|
@@ -475,6 +478,50 @@ declare function createRouter(routesOrOptions: RouteDef[] | RouterOptions, optio
|
|
|
475
478
|
* Set routes on the global router (replaces existing routes).
|
|
476
479
|
*/
|
|
477
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
|
+
}
|
|
478
525
|
/**
|
|
479
526
|
* Read the current route as a plain snapshot.
|
|
480
527
|
*
|
|
@@ -483,6 +530,13 @@ declare function setRoutes(routes: RouteDef[]): void;
|
|
|
483
530
|
* `RouteBase.key`). Inside a getter — `() => route().params.id` — the read is
|
|
484
531
|
* reactive, which is what a long-lived layout or a constant-`key` route needs.
|
|
485
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
|
+
*
|
|
486
540
|
* @returns The active {@link RouteContext} (path, params, query, hash).
|
|
487
541
|
* @throws If no router has been created yet.
|
|
488
542
|
*/
|