@solidjs/router 1.0.0-next.7 → 1.0.0-next.9
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/claims.js +8 -1
- package/dist/data/action.js +23 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +33 -5
- package/package.json +1 -1
package/dist/claims.js
CHANGED
|
@@ -84,7 +84,14 @@ export function setupLinkClaims(router, explicitLinks) {
|
|
|
84
84
|
// linkState derives from (the in-flight pendingTarget is readable in the
|
|
85
85
|
// effect phase because the isRouting write flushes after the target is
|
|
86
86
|
// assigned), the effect phase sweeps the registry untracked.
|
|
87
|
-
|
|
87
|
+
//
|
|
88
|
+
// `transparent` keeps the effect invisible to the hydration id scheme.
|
|
89
|
+
// This setup is client-only, so an id-consuming node here has no server
|
|
90
|
+
// counterpart and every subsequent hydration id would shift by one child
|
|
91
|
+
// slot — lazy-route lookups miss and hydration leaves server nodes
|
|
92
|
+
// unclaimed. (The option is honored by the runtime but missing from the
|
|
93
|
+
// published EffectOptions type, hence the cast.)
|
|
94
|
+
createRenderEffect(() => (router.location.pathname, router.isRouting()), () => registry.forEach(a => refresh(a, claimed.get(a))), { transparent: true });
|
|
88
95
|
onCleanup(registerElementClaim(node => {
|
|
89
96
|
if (node.nodeName.toUpperCase() !== "A")
|
|
90
97
|
return;
|
package/dist/data/action.js
CHANGED
|
@@ -157,6 +157,13 @@ function actionImpl(fn, options = {}) {
|
|
|
157
157
|
form && setFormBusy(form, 1);
|
|
158
158
|
let settled;
|
|
159
159
|
let response;
|
|
160
|
+
// The transport consumer is awaited before a single-flight mutation
|
|
161
|
+
// resolves, so a counter delta over the call tells whether this action's
|
|
162
|
+
// metadata was already applied. Overlapping mutations can cross-attribute
|
|
163
|
+
// a run (skipping one default revalidation another pass just covered) —
|
|
164
|
+
// a far smaller window than predicting from the function's identity,
|
|
165
|
+
// which misses every response the server returned without flight data.
|
|
166
|
+
const flightApplicationsBefore = flightApplications;
|
|
160
167
|
try {
|
|
161
168
|
settled = await settleActionResult(run({
|
|
162
169
|
call: runMutation,
|
|
@@ -167,7 +174,7 @@ function actionImpl(fn, options = {}) {
|
|
|
167
174
|
}
|
|
168
175
|
: undefined
|
|
169
176
|
}));
|
|
170
|
-
response = await handleResponse(settled.value, settled.error, router.navigatorFactory());
|
|
177
|
+
response = await handleResponse(settled.value, settled.error, router.navigatorFactory(), flightApplications !== flightApplicationsBefore);
|
|
171
178
|
}
|
|
172
179
|
finally {
|
|
173
180
|
form && setFormBusy(form, -1);
|
|
@@ -263,6 +270,11 @@ async function settleActionResult(result) {
|
|
|
263
270
|
}
|
|
264
271
|
return result;
|
|
265
272
|
}
|
|
273
|
+
// Invocation count of the flight-data consumer. An action compares it across
|
|
274
|
+
// its mutation call to learn whether the transport already applied this
|
|
275
|
+
// response's metadata (and so the default revalidation pass must not run
|
|
276
|
+
// again and wipe the freshly seeded cache).
|
|
277
|
+
let flightApplications = 0;
|
|
266
278
|
/**
|
|
267
279
|
* Registers the router as the single-flight consumer of the server function
|
|
268
280
|
* transport. Subscribing is the opt-in: while registered, the transport
|
|
@@ -275,7 +287,10 @@ async function settleActionResult(result) {
|
|
|
275
287
|
* collection work on the server. Returns the unsubscribe function.
|
|
276
288
|
*/
|
|
277
289
|
export function setupFlightDataConsumer(router) {
|
|
278
|
-
return subscribeFlightData((data, { response }) =>
|
|
290
|
+
return subscribeFlightData((data, { response }) => {
|
|
291
|
+
flightApplications++;
|
|
292
|
+
return applyResponseMetadata(response, router.navigatorFactory(), data);
|
|
293
|
+
});
|
|
279
294
|
}
|
|
280
295
|
/**
|
|
281
296
|
* Applies a server function response's integration metadata: `X-Revalidate`
|
|
@@ -306,7 +321,7 @@ async function applyResponseMetadata(metadata, navigate, flightData) {
|
|
|
306
321
|
// trigger revalidation
|
|
307
322
|
await revalidate(keys, false);
|
|
308
323
|
}
|
|
309
|
-
async function handleResponse(response, error, navigate) {
|
|
324
|
+
async function handleResponse(response, error, navigate, metadataHandled) {
|
|
310
325
|
let data;
|
|
311
326
|
let flightData;
|
|
312
327
|
let metadata;
|
|
@@ -335,6 +350,10 @@ async function handleResponse(response, error, navigate) {
|
|
|
335
350
|
return { error: response };
|
|
336
351
|
else
|
|
337
352
|
data = response;
|
|
338
|
-
|
|
353
|
+
// The transport consumer applies metadata before returning a server
|
|
354
|
+
// function's unwrapped value. Do not treat that value as a second plain
|
|
355
|
+
// action response and invalidate the freshly seeded query cache again.
|
|
356
|
+
if (!metadataHandled || metadata || flightData)
|
|
357
|
+
await applyResponseMetadata(metadata, navigate, flightData);
|
|
339
358
|
return data != null ? { data } : undefined;
|
|
340
359
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ export { useHref, useIsRouting, useLinkState, useLocation, useMatch, useNavigate
|
|
|
4
4
|
export type { LinkState } from "./routing.js";
|
|
5
5
|
export { mergeSearchString as _mergeSearchString } from "./utils.js";
|
|
6
6
|
export { int } from "./paths.js";
|
|
7
|
-
export type { RoutePaths, PathParamsOf, PathEnd, TypedMatchFilter } from "./paths.js";
|
|
7
|
+
export type { RoutePaths, PathParamsOf, PathEnd, TypedMatchFilter, DefaultSearchTypes } from "./paths.js";
|
|
8
8
|
export * from "./data/index.js";
|
|
9
|
-
export type { Location, LocationChange, SearchParams, MatchFilter, MatchFilters, NavigateOptions, Navigator, OutputMatch, Params, PathMatch, RouteSectionProps, RoutePreloadFunc, RoutePreloadFuncArgs, RouteDefinition, RouteDescription, RouteMatch, RouterIntegration, RouterUtils, SetParams, Submission, BeforeLeaveEventArgs, TypedPath, TypedSearchPath, StandardSchemaV1 } from "./types.js";
|
|
9
|
+
export type { Location, LocationChange, SearchParams, MatchFilter, MatchFilters, NavigateOptions, Navigator, OutputMatch, Params, PathMatch, RouteSectionProps, RoutePreloadFunc, RoutePreloadFuncArgs, RouteDefinition, RouteDescription, RouteMatch, RouterIntegration, RouterUtils, SetParams, SetSearchParams, Submission, BeforeLeaveEventArgs, TypedPath, TypedSearchPath, StandardSchemaV1 } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -267,7 +267,16 @@ function setupLinkClaims(router, explicitLinks) {
|
|
|
267
267
|
// linkState derives from (the in-flight pendingTarget is readable in the
|
|
268
268
|
// effect phase because the isRouting write flushes after the target is
|
|
269
269
|
// assigned), the effect phase sweeps the registry untracked.
|
|
270
|
-
|
|
270
|
+
//
|
|
271
|
+
// `transparent` keeps the effect invisible to the hydration id scheme.
|
|
272
|
+
// This setup is client-only, so an id-consuming node here has no server
|
|
273
|
+
// counterpart and every subsequent hydration id would shift by one child
|
|
274
|
+
// slot — lazy-route lookups miss and hydration leaves server nodes
|
|
275
|
+
// unclaimed. (The option is honored by the runtime but missing from the
|
|
276
|
+
// published EffectOptions type, hence the cast.)
|
|
277
|
+
createRenderEffect(() => (router.location.pathname, router.isRouting()), () => registry.forEach(a => refresh(a, claimed.get(a))), {
|
|
278
|
+
transparent: true
|
|
279
|
+
});
|
|
271
280
|
onCleanup(registerElementClaim(node => {
|
|
272
281
|
if (node.nodeName.toUpperCase() !== "A") return;
|
|
273
282
|
const a = node;
|
|
@@ -2372,6 +2381,13 @@ function actionImpl(fn, options = {}) {
|
|
|
2372
2381
|
form && setFormBusy(form, 1);
|
|
2373
2382
|
let settled;
|
|
2374
2383
|
let response;
|
|
2384
|
+
// The transport consumer is awaited before a single-flight mutation
|
|
2385
|
+
// resolves, so a counter delta over the call tells whether this action's
|
|
2386
|
+
// metadata was already applied. Overlapping mutations can cross-attribute
|
|
2387
|
+
// a run (skipping one default revalidation another pass just covered) —
|
|
2388
|
+
// a far smaller window than predicting from the function's identity,
|
|
2389
|
+
// which misses every response the server returned without flight data.
|
|
2390
|
+
const flightApplicationsBefore = flightApplications;
|
|
2375
2391
|
try {
|
|
2376
2392
|
settled = await settleActionResult(run({
|
|
2377
2393
|
call: runMutation,
|
|
@@ -2379,7 +2395,7 @@ function actionImpl(fn, options = {}) {
|
|
|
2379
2395
|
for (const hook of submitHooks.values()) hook(...variables);
|
|
2380
2396
|
} : undefined
|
|
2381
2397
|
}));
|
|
2382
|
-
response = await handleResponse(settled.value, settled.error, router.navigatorFactory());
|
|
2398
|
+
response = await handleResponse(settled.value, settled.error, router.navigatorFactory(), flightApplications !== flightApplicationsBefore);
|
|
2383
2399
|
} finally {
|
|
2384
2400
|
form && setFormBusy(form, -1);
|
|
2385
2401
|
}
|
|
@@ -2474,6 +2490,12 @@ async function settleActionResult(result) {
|
|
|
2474
2490
|
return result;
|
|
2475
2491
|
}
|
|
2476
2492
|
|
|
2493
|
+
// Invocation count of the flight-data consumer. An action compares it across
|
|
2494
|
+
// its mutation call to learn whether the transport already applied this
|
|
2495
|
+
// response's metadata (and so the default revalidation pass must not run
|
|
2496
|
+
// again and wipe the freshly seeded cache).
|
|
2497
|
+
let flightApplications = 0;
|
|
2498
|
+
|
|
2477
2499
|
/**
|
|
2478
2500
|
* Registers the router as the single-flight consumer of the server function
|
|
2479
2501
|
* transport. Subscribing is the opt-in: while registered, the transport
|
|
@@ -2488,7 +2510,10 @@ async function settleActionResult(result) {
|
|
|
2488
2510
|
function setupFlightDataConsumer(router) {
|
|
2489
2511
|
return subscribeFlightData((data, {
|
|
2490
2512
|
response
|
|
2491
|
-
}) =>
|
|
2513
|
+
}) => {
|
|
2514
|
+
flightApplications++;
|
|
2515
|
+
return applyResponseMetadata(response, router.navigatorFactory(), data);
|
|
2516
|
+
});
|
|
2492
2517
|
}
|
|
2493
2518
|
|
|
2494
2519
|
/**
|
|
@@ -2518,7 +2543,7 @@ async function applyResponseMetadata(metadata, navigate, flightData) {
|
|
|
2518
2543
|
// trigger revalidation
|
|
2519
2544
|
await revalidate(keys, false);
|
|
2520
2545
|
}
|
|
2521
|
-
async function handleResponse(response, error, navigate) {
|
|
2546
|
+
async function handleResponse(response, error, navigate, metadataHandled) {
|
|
2522
2547
|
let data;
|
|
2523
2548
|
let flightData;
|
|
2524
2549
|
let metadata;
|
|
@@ -2544,7 +2569,10 @@ async function handleResponse(response, error, navigate) {
|
|
|
2544
2569
|
} else if (error) return {
|
|
2545
2570
|
error: response
|
|
2546
2571
|
};else data = response;
|
|
2547
|
-
|
|
2572
|
+
// The transport consumer applies metadata before returning a server
|
|
2573
|
+
// function's unwrapped value. Do not treat that value as a second plain
|
|
2574
|
+
// action response and invalidate the freshly seeded query cache again.
|
|
2575
|
+
if (!metadataHandled || metadata || flightData) await applyResponseMetadata(metadata, navigate, flightData);
|
|
2548
2576
|
return data != null ? {
|
|
2549
2577
|
data
|
|
2550
2578
|
} : undefined;
|