@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.
@@ -7,7 +7,11 @@
7
7
 
8
8
  import type { ReactNode } from "react";
9
9
  import { invariant } from "../../errors";
10
- import type { EntryData } from "../../server/context";
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
- for (const parallelEntry of entry.parallel) {
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
- for (const parallelEntry of entry.parallel) {
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
- for (const parallelEntry of orphan.parallel) {
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
- for (const [slot, handler] of Object.entries(slots)) {
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 (!parallelEntry.loading && !options?.skipLoaders) {
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
- for (const entry of entries) {
564
- const belongsToRoute = entry.type === "route";
565
- const segments = await resolveLoaders(entry, context, belongsToRoute, deps);
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;