@rangojs/router 0.0.0-experimental.002d056c → 0.0.0-experimental.07cdfab0
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/vite/index.js +4 -4
- package/package.json +1 -1
- package/skills/parallel/SKILL.md +59 -0
- package/src/browser/event-controller.ts +5 -0
- package/src/browser/navigation-client.ts +14 -27
- package/src/browser/prefetch/cache.ts +6 -6
- package/src/browser/prefetch/fetch.ts +13 -14
- package/src/browser/rsc-router.tsx +19 -0
- package/src/browser/segment-reconciler.ts +6 -1
- package/src/cache/document-cache.ts +17 -7
- package/src/debug.ts +2 -2
- package/src/route-definition/dsl-helpers.ts +32 -7
- package/src/router/lazy-includes.ts +2 -1
- package/src/router/manifest.ts +6 -2
- package/src/router/segment-resolution/fresh.ts +74 -9
- package/src/router/segment-resolution/revalidation.ts +298 -272
- package/src/router.ts +1 -1
- package/src/segment-system.tsx +140 -4
- package/src/server/context.ts +90 -13
- package/src/ssr/index.tsx +1 -0
- package/src/types/segments.ts +2 -0
- package/src/urls/path-helper.ts +1 -1
- package/src/vite/utils/banner.ts +3 -3
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
|
|
8
8
|
import type { ReactNode } from "react";
|
|
9
9
|
import { invariant } from "../../errors";
|
|
10
|
-
import
|
|
10
|
+
import {
|
|
11
|
+
getParallelEntries,
|
|
12
|
+
getParallelSlotEntries,
|
|
13
|
+
type EntryData,
|
|
14
|
+
} from "../../server/context";
|
|
11
15
|
import type {
|
|
12
16
|
HandlerContext,
|
|
13
17
|
InternalHandlerContext,
|
|
@@ -197,7 +201,10 @@ export async function resolveSegment<TEnv>(
|
|
|
197
201
|
...(entry.mountPath ? { mountPath: entry.mountPath } : {}),
|
|
198
202
|
});
|
|
199
203
|
|
|
200
|
-
|
|
204
|
+
const resolvedParallelEntries = new Set<string>();
|
|
205
|
+
for (const { slot, entry: parallelEntry } of getParallelSlotEntries(
|
|
206
|
+
entry.parallel,
|
|
207
|
+
)) {
|
|
201
208
|
const parallelSegments = await resolveParallelEntry(
|
|
202
209
|
parallelEntry,
|
|
203
210
|
params,
|
|
@@ -207,8 +214,11 @@ export async function resolveSegment<TEnv>(
|
|
|
207
214
|
deps,
|
|
208
215
|
options,
|
|
209
216
|
routeKey,
|
|
217
|
+
[slot],
|
|
218
|
+
!resolvedParallelEntries.has(parallelEntry.id),
|
|
210
219
|
);
|
|
211
220
|
segments.push(...parallelSegments);
|
|
221
|
+
resolvedParallelEntries.add(parallelEntry.id);
|
|
212
222
|
}
|
|
213
223
|
|
|
214
224
|
for (const orphan of entry.layout) {
|
|
@@ -286,7 +296,10 @@ export async function resolveSegment<TEnv>(
|
|
|
286
296
|
segments.push(...orphanSegments);
|
|
287
297
|
}
|
|
288
298
|
|
|
289
|
-
|
|
299
|
+
const resolvedParallelEntries = new Set<string>();
|
|
300
|
+
for (const { slot, entry: parallelEntry } of getParallelSlotEntries(
|
|
301
|
+
entry.parallel,
|
|
302
|
+
)) {
|
|
290
303
|
const parallelSegments = await resolveParallelEntry(
|
|
291
304
|
parallelEntry,
|
|
292
305
|
params,
|
|
@@ -296,8 +309,11 @@ export async function resolveSegment<TEnv>(
|
|
|
296
309
|
deps,
|
|
297
310
|
options,
|
|
298
311
|
routeKey,
|
|
312
|
+
[slot],
|
|
313
|
+
!resolvedParallelEntries.has(parallelEntry.id),
|
|
299
314
|
);
|
|
300
315
|
segments.push(...parallelSegments);
|
|
316
|
+
resolvedParallelEntries.add(parallelEntry.id);
|
|
301
317
|
}
|
|
302
318
|
|
|
303
319
|
segments.push({
|
|
@@ -368,7 +384,10 @@ export async function resolveOrphanLayout<TEnv>(
|
|
|
368
384
|
...(orphan.mountPath ? { mountPath: orphan.mountPath } : {}),
|
|
369
385
|
});
|
|
370
386
|
|
|
371
|
-
|
|
387
|
+
const resolvedParallelEntries = new Set<string>();
|
|
388
|
+
for (const { slot, entry: parallelEntry } of getParallelSlotEntries(
|
|
389
|
+
orphan.parallel,
|
|
390
|
+
)) {
|
|
372
391
|
const parallelSegments = await resolveParallelEntry(
|
|
373
392
|
parallelEntry,
|
|
374
393
|
params,
|
|
@@ -378,8 +397,11 @@ export async function resolveOrphanLayout<TEnv>(
|
|
|
378
397
|
deps,
|
|
379
398
|
options,
|
|
380
399
|
routeKey,
|
|
400
|
+
[slot],
|
|
401
|
+
!resolvedParallelEntries.has(parallelEntry.id),
|
|
381
402
|
);
|
|
382
403
|
segments.push(...parallelSegments);
|
|
404
|
+
resolvedParallelEntries.add(parallelEntry.id);
|
|
383
405
|
}
|
|
384
406
|
|
|
385
407
|
return segments;
|
|
@@ -397,6 +419,8 @@ export async function resolveParallelEntry<TEnv>(
|
|
|
397
419
|
deps: SegmentResolutionDeps<TEnv>,
|
|
398
420
|
options?: ResolveSegmentOptions,
|
|
399
421
|
routeKey?: string,
|
|
422
|
+
slotNames?: `@${string}`[],
|
|
423
|
+
includeLoaders: boolean = true,
|
|
400
424
|
): Promise<ResolvedSegment[]> {
|
|
401
425
|
invariant(
|
|
402
426
|
parallelEntry.type === "parallel",
|
|
@@ -411,7 +435,14 @@ export async function resolveParallelEntry<TEnv>(
|
|
|
411
435
|
| ReactNode
|
|
412
436
|
>;
|
|
413
437
|
|
|
414
|
-
|
|
438
|
+
const slotsToResolve = slotNames ?? (Object.keys(slots) as `@${string}`[]);
|
|
439
|
+
|
|
440
|
+
for (const slot of slotsToResolve) {
|
|
441
|
+
const handler = slots[slot];
|
|
442
|
+
if (handler === undefined) {
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
|
|
415
446
|
let component: ReactNode | undefined = await tryStaticSlot(
|
|
416
447
|
parallelEntry,
|
|
417
448
|
slot,
|
|
@@ -472,7 +503,7 @@ export async function resolveParallelEntry<TEnv>(
|
|
|
472
503
|
});
|
|
473
504
|
}
|
|
474
505
|
|
|
475
|
-
if (!
|
|
506
|
+
if (!options?.skipLoaders && includeLoaders) {
|
|
476
507
|
const loaderSegments = await resolveLoaders(
|
|
477
508
|
parallelEntry,
|
|
478
509
|
context,
|
|
@@ -480,6 +511,15 @@ export async function resolveParallelEntry<TEnv>(
|
|
|
480
511
|
deps,
|
|
481
512
|
parentShortCode,
|
|
482
513
|
);
|
|
514
|
+
// Tag parallel-owned loaders so renderSegments can stream them
|
|
515
|
+
// using the parallel's loading() instead of awaiting on the layout
|
|
516
|
+
const parallelLoading =
|
|
517
|
+
parallelEntry.loading === false ? undefined : parallelEntry.loading;
|
|
518
|
+
if (parallelLoading) {
|
|
519
|
+
for (const seg of loaderSegments) {
|
|
520
|
+
seg.parallelLoading = parallelLoading;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
483
523
|
segments.push(...loaderSegments);
|
|
484
524
|
}
|
|
485
525
|
|
|
@@ -560,10 +600,35 @@ export async function resolveLoadersOnly<TEnv>(
|
|
|
560
600
|
): Promise<ResolvedSegment[]> {
|
|
561
601
|
const loaderSegments: ResolvedSegment[] = [];
|
|
562
602
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
603
|
+
async function collectEntryLoaders(
|
|
604
|
+
entry: EntryData,
|
|
605
|
+
belongsToRoute: boolean,
|
|
606
|
+
shortCodeOverride?: string,
|
|
607
|
+
): Promise<void> {
|
|
608
|
+
const segments = await resolveLoaders(
|
|
609
|
+
entry,
|
|
610
|
+
context,
|
|
611
|
+
belongsToRoute,
|
|
612
|
+
deps,
|
|
613
|
+
shortCodeOverride,
|
|
614
|
+
);
|
|
566
615
|
loaderSegments.push(...segments);
|
|
616
|
+
|
|
617
|
+
const seenParallelEntryIds = new Set<string>();
|
|
618
|
+
for (const parallelEntry of getParallelEntries(entry.parallel)) {
|
|
619
|
+
if (seenParallelEntryIds.has(parallelEntry.id)) continue;
|
|
620
|
+
seenParallelEntryIds.add(parallelEntry.id);
|
|
621
|
+
await collectEntryLoaders(parallelEntry, belongsToRoute, entry.shortCode);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
const childBelongsToRoute = belongsToRoute || entry.type === "route";
|
|
625
|
+
for (const layoutEntry of entry.layout) {
|
|
626
|
+
await collectEntryLoaders(layoutEntry, childBelongsToRoute);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
for (const entry of entries) {
|
|
631
|
+
await collectEntryLoaders(entry, entry.type === "route");
|
|
567
632
|
}
|
|
568
633
|
|
|
569
634
|
return loaderSegments;
|