@rangojs/router 0.0.0-experimental.2

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.
Files changed (155) hide show
  1. package/CLAUDE.md +7 -0
  2. package/README.md +19 -0
  3. package/dist/vite/index.js +1298 -0
  4. package/package.json +140 -0
  5. package/skills/caching/SKILL.md +319 -0
  6. package/skills/document-cache/SKILL.md +152 -0
  7. package/skills/hooks/SKILL.md +359 -0
  8. package/skills/intercept/SKILL.md +292 -0
  9. package/skills/layout/SKILL.md +216 -0
  10. package/skills/loader/SKILL.md +365 -0
  11. package/skills/middleware/SKILL.md +442 -0
  12. package/skills/parallel/SKILL.md +255 -0
  13. package/skills/route/SKILL.md +141 -0
  14. package/skills/router-setup/SKILL.md +403 -0
  15. package/skills/theme/SKILL.md +54 -0
  16. package/skills/typesafety/SKILL.md +352 -0
  17. package/src/__mocks__/version.ts +6 -0
  18. package/src/__tests__/component-utils.test.ts +76 -0
  19. package/src/__tests__/route-definition.test.ts +63 -0
  20. package/src/__tests__/urls.test.tsx +436 -0
  21. package/src/browser/event-controller.ts +876 -0
  22. package/src/browser/index.ts +18 -0
  23. package/src/browser/link-interceptor.ts +121 -0
  24. package/src/browser/lru-cache.ts +69 -0
  25. package/src/browser/merge-segment-loaders.ts +126 -0
  26. package/src/browser/navigation-bridge.ts +893 -0
  27. package/src/browser/navigation-client.ts +162 -0
  28. package/src/browser/navigation-store.ts +823 -0
  29. package/src/browser/partial-update.ts +559 -0
  30. package/src/browser/react/Link.tsx +248 -0
  31. package/src/browser/react/NavigationProvider.tsx +275 -0
  32. package/src/browser/react/ScrollRestoration.tsx +94 -0
  33. package/src/browser/react/context.ts +53 -0
  34. package/src/browser/react/index.ts +52 -0
  35. package/src/browser/react/location-state-shared.ts +120 -0
  36. package/src/browser/react/location-state.ts +62 -0
  37. package/src/browser/react/use-action.ts +240 -0
  38. package/src/browser/react/use-client-cache.ts +56 -0
  39. package/src/browser/react/use-handle.ts +178 -0
  40. package/src/browser/react/use-href.tsx +208 -0
  41. package/src/browser/react/use-link-status.ts +134 -0
  42. package/src/browser/react/use-navigation.ts +150 -0
  43. package/src/browser/react/use-segments.ts +188 -0
  44. package/src/browser/request-controller.ts +164 -0
  45. package/src/browser/rsc-router.tsx +353 -0
  46. package/src/browser/scroll-restoration.ts +324 -0
  47. package/src/browser/server-action-bridge.ts +747 -0
  48. package/src/browser/shallow.ts +35 -0
  49. package/src/browser/types.ts +464 -0
  50. package/src/cache/__tests__/document-cache.test.ts +522 -0
  51. package/src/cache/__tests__/memory-segment-store.test.ts +487 -0
  52. package/src/cache/__tests__/memory-store.test.ts +484 -0
  53. package/src/cache/cache-scope.ts +565 -0
  54. package/src/cache/cf/__tests__/cf-cache-store.test.ts +428 -0
  55. package/src/cache/cf/cf-cache-store.ts +428 -0
  56. package/src/cache/cf/index.ts +19 -0
  57. package/src/cache/document-cache.ts +340 -0
  58. package/src/cache/index.ts +58 -0
  59. package/src/cache/memory-segment-store.ts +150 -0
  60. package/src/cache/memory-store.ts +253 -0
  61. package/src/cache/types.ts +387 -0
  62. package/src/client.rsc.tsx +88 -0
  63. package/src/client.tsx +621 -0
  64. package/src/component-utils.ts +76 -0
  65. package/src/components/DefaultDocument.tsx +23 -0
  66. package/src/default-error-boundary.tsx +88 -0
  67. package/src/deps/browser.ts +8 -0
  68. package/src/deps/html-stream-client.ts +2 -0
  69. package/src/deps/html-stream-server.ts +2 -0
  70. package/src/deps/rsc.ts +10 -0
  71. package/src/deps/ssr.ts +2 -0
  72. package/src/errors.ts +259 -0
  73. package/src/handle.ts +120 -0
  74. package/src/handles/MetaTags.tsx +193 -0
  75. package/src/handles/index.ts +6 -0
  76. package/src/handles/meta.ts +247 -0
  77. package/src/href-client.ts +128 -0
  78. package/src/href-context.ts +33 -0
  79. package/src/href.ts +177 -0
  80. package/src/index.rsc.ts +79 -0
  81. package/src/index.ts +87 -0
  82. package/src/loader.rsc.ts +204 -0
  83. package/src/loader.ts +47 -0
  84. package/src/network-error-thrower.tsx +21 -0
  85. package/src/outlet-context.ts +15 -0
  86. package/src/root-error-boundary.tsx +277 -0
  87. package/src/route-content-wrapper.tsx +198 -0
  88. package/src/route-definition.ts +1371 -0
  89. package/src/route-map-builder.ts +146 -0
  90. package/src/route-types.ts +198 -0
  91. package/src/route-utils.ts +89 -0
  92. package/src/router/__tests__/match-context.test.ts +104 -0
  93. package/src/router/__tests__/match-pipelines.test.ts +537 -0
  94. package/src/router/__tests__/match-result.test.ts +566 -0
  95. package/src/router/__tests__/on-error.test.ts +935 -0
  96. package/src/router/__tests__/pattern-matching.test.ts +577 -0
  97. package/src/router/error-handling.ts +287 -0
  98. package/src/router/handler-context.ts +158 -0
  99. package/src/router/loader-resolution.ts +326 -0
  100. package/src/router/manifest.ts +138 -0
  101. package/src/router/match-context.ts +264 -0
  102. package/src/router/match-middleware/background-revalidation.ts +236 -0
  103. package/src/router/match-middleware/cache-lookup.ts +261 -0
  104. package/src/router/match-middleware/cache-store.ts +266 -0
  105. package/src/router/match-middleware/index.ts +81 -0
  106. package/src/router/match-middleware/intercept-resolution.ts +268 -0
  107. package/src/router/match-middleware/segment-resolution.ts +174 -0
  108. package/src/router/match-pipelines.ts +214 -0
  109. package/src/router/match-result.ts +214 -0
  110. package/src/router/metrics.ts +62 -0
  111. package/src/router/middleware.test.ts +1355 -0
  112. package/src/router/middleware.ts +748 -0
  113. package/src/router/pattern-matching.ts +272 -0
  114. package/src/router/revalidation.ts +190 -0
  115. package/src/router/router-context.ts +299 -0
  116. package/src/router/types.ts +96 -0
  117. package/src/router.ts +3876 -0
  118. package/src/rsc/__tests__/helpers.test.ts +175 -0
  119. package/src/rsc/handler.ts +1060 -0
  120. package/src/rsc/helpers.ts +64 -0
  121. package/src/rsc/index.ts +56 -0
  122. package/src/rsc/nonce.ts +18 -0
  123. package/src/rsc/types.ts +237 -0
  124. package/src/segment-system.tsx +456 -0
  125. package/src/server/__tests__/request-context.test.ts +171 -0
  126. package/src/server/context.ts +417 -0
  127. package/src/server/handle-store.ts +230 -0
  128. package/src/server/loader-registry.ts +174 -0
  129. package/src/server/request-context.ts +554 -0
  130. package/src/server/root-layout.tsx +10 -0
  131. package/src/server/tsconfig.json +14 -0
  132. package/src/server.ts +146 -0
  133. package/src/ssr/__tests__/ssr-handler.test.tsx +188 -0
  134. package/src/ssr/index.tsx +234 -0
  135. package/src/theme/ThemeProvider.tsx +291 -0
  136. package/src/theme/ThemeScript.tsx +61 -0
  137. package/src/theme/__tests__/theme.test.ts +120 -0
  138. package/src/theme/constants.ts +55 -0
  139. package/src/theme/index.ts +58 -0
  140. package/src/theme/theme-context.ts +70 -0
  141. package/src/theme/theme-script.ts +152 -0
  142. package/src/theme/types.ts +182 -0
  143. package/src/theme/use-theme.ts +44 -0
  144. package/src/types.ts +1561 -0
  145. package/src/urls.ts +726 -0
  146. package/src/use-loader.tsx +346 -0
  147. package/src/vite/__tests__/expose-loader-id.test.ts +117 -0
  148. package/src/vite/expose-action-id.ts +344 -0
  149. package/src/vite/expose-handle-id.ts +209 -0
  150. package/src/vite/expose-loader-id.ts +357 -0
  151. package/src/vite/expose-location-state-id.ts +177 -0
  152. package/src/vite/index.ts +787 -0
  153. package/src/vite/package-resolution.ts +125 -0
  154. package/src/vite/version.d.ts +12 -0
  155. package/src/vite/virtual-entries.ts +109 -0
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Package Resolution Utilities
3
+ *
4
+ * Handles detection of workspace vs npm install context and generates
5
+ * appropriate aliases and exclude lists for Vite configuration.
6
+ */
7
+
8
+ import { existsSync } from "node:fs";
9
+ import { resolve } from "node:path";
10
+ import packageJson from "../../package.json" with { type: "json" };
11
+
12
+ /**
13
+ * The canonical name used in virtual entries (without scope)
14
+ */
15
+ const VIRTUAL_PACKAGE_NAME = "@rangojs/router";
16
+
17
+ /**
18
+ * Get the published package name (e.g., "@rangojs/router")
19
+ */
20
+ export function getPublishedPackageName(): string {
21
+ return packageJson.name;
22
+ }
23
+
24
+ /**
25
+ * Check if the package is installed from npm (scoped) vs workspace (unscoped)
26
+ *
27
+ * In workspace development:
28
+ * - Package is installed as "@rangojs/router" via pnpm workspace alias
29
+ * - The scoped name (@rangojs/router) doesn't exist in node_modules
30
+ *
31
+ * When installed from npm:
32
+ * - Package is installed as "@rangojs/router"
33
+ * - We need aliases to map "@rangojs/router/*" to "@rangojs/router/*"
34
+ */
35
+ export function isInstalledFromNpm(): boolean {
36
+ const packageName = getPublishedPackageName();
37
+ // Check if the scoped package exists in node_modules
38
+ return existsSync(resolve(process.cwd(), "node_modules", packageName));
39
+ }
40
+
41
+ /**
42
+ * Check if we're in a monorepo/workspace development context
43
+ */
44
+ export function isWorkspaceDevelopment(): boolean {
45
+ return !isInstalledFromNpm();
46
+ }
47
+
48
+ /**
49
+ * Subpaths that need to be excluded from Vite's dependency optimization
50
+ * and potentially aliased
51
+ */
52
+ const PACKAGE_SUBPATHS = [
53
+ "",
54
+ "/browser",
55
+ "/client",
56
+ "/server",
57
+ "/rsc",
58
+ "/ssr",
59
+ "/internal/deps/browser",
60
+ "/internal/deps/html-stream-client",
61
+ "/internal/deps/ssr",
62
+ "/internal/deps/rsc",
63
+ ] as const;
64
+
65
+ /**
66
+ * Generate the list of modules to exclude from Vite's dependency optimization.
67
+ *
68
+ * We include both the published name and the virtual name because
69
+ * Vite's optimizer runs before alias resolution.
70
+ */
71
+ export function getExcludeDeps(): string[] {
72
+ const packageName = getPublishedPackageName();
73
+ const excludes: string[] = [];
74
+
75
+ for (const subpath of PACKAGE_SUBPATHS) {
76
+ // Add scoped package paths
77
+ excludes.push(`${packageName}${subpath}`);
78
+ // Add virtual/aliased paths (before alias resolution)
79
+ if (packageName !== VIRTUAL_PACKAGE_NAME) {
80
+ excludes.push(`${VIRTUAL_PACKAGE_NAME}${subpath}`);
81
+ }
82
+ }
83
+
84
+ return excludes;
85
+ }
86
+
87
+ /**
88
+ * Subpaths that need aliasing (subset of PACKAGE_SUBPATHS)
89
+ */
90
+ const ALIAS_SUBPATHS = [
91
+ "/internal/deps/browser",
92
+ "/internal/deps/ssr",
93
+ "/internal/deps/rsc",
94
+ "/internal/deps/html-stream-client",
95
+ "/internal/deps/html-stream-server",
96
+ "/browser",
97
+ "/client",
98
+ "/server",
99
+ "/rsc",
100
+ "/ssr",
101
+ ] as const;
102
+
103
+ /**
104
+ * Generate aliases to map virtual package paths to the actual published package.
105
+ *
106
+ * Only needed when installed from npm, where the package is under @rangojs/router
107
+ * but virtual entries import from rsc-router/*.
108
+ *
109
+ * Returns empty object in workspace development where rsc-router resolves directly.
110
+ */
111
+ export function getPackageAliases(): Record<string, string> {
112
+ if (isWorkspaceDevelopment()) {
113
+ // No aliases needed - rsc-router resolves directly
114
+ return {};
115
+ }
116
+
117
+ const packageName = getPublishedPackageName();
118
+ const aliases: Record<string, string> = {};
119
+
120
+ for (const subpath of ALIAS_SUBPATHS) {
121
+ aliases[`${VIRTUAL_PACKAGE_NAME}${subpath}`] = `${packageName}${subpath}`;
122
+ }
123
+
124
+ return aliases;
125
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Type declarations for rsc-router:version virtual module.
3
+ * This module is provided by the Vite plugin at build/dev time.
4
+ */
5
+
6
+ declare module "@rangojs/router:version" {
7
+ /**
8
+ * Auto-generated version string for cache invalidation.
9
+ * Changes on server restart (dev) or build (prod).
10
+ */
11
+ export const VERSION: string;
12
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Default virtual entry file contents for rsc-router.
3
+ * These are used when users don't provide their own entry files.
4
+ */
5
+
6
+ export const VIRTUAL_ENTRY_BROWSER: string = `
7
+ import {
8
+ createFromReadableStream,
9
+ createFromFetch,
10
+ setServerCallback,
11
+ encodeReply,
12
+ createTemporaryReferenceSet,
13
+ } from "@rangojs/router/internal/deps/browser";
14
+ import { createElement, StrictMode } from "react";
15
+ import { hydrateRoot } from "react-dom/client";
16
+ import { rscStream } from "@rangojs/router/internal/deps/html-stream-client";
17
+ import { initBrowserApp, RSCRouter } from "@rangojs/router/browser";
18
+
19
+ async function initializeApp() {
20
+ const deps = {
21
+ createFromFetch,
22
+ createFromReadableStream,
23
+ encodeReply,
24
+ setServerCallback,
25
+ createTemporaryReferenceSet,
26
+ };
27
+
28
+ await initBrowserApp({ rscStream, deps });
29
+
30
+ hydrateRoot(
31
+ document,
32
+ createElement(StrictMode, null, createElement(RSCRouter))
33
+ );
34
+ }
35
+
36
+ initializeApp().catch(console.error);
37
+ `.trim();
38
+
39
+ export const VIRTUAL_ENTRY_SSR: string = `
40
+ import { createFromReadableStream } from "@rangojs/router/internal/deps/ssr";
41
+ import { renderToReadableStream } from "react-dom/server.edge";
42
+ import { injectRSCPayload } from "@rangojs/router/internal/deps/html-stream-server";
43
+ import { createSSRHandler } from "@rangojs/router/ssr";
44
+
45
+ export const renderHTML = createSSRHandler({
46
+ createFromReadableStream,
47
+ renderToReadableStream,
48
+ injectRSCPayload,
49
+ loadBootstrapScriptContent: () =>
50
+ import.meta.viteRsc.loadBootstrapScriptContent("index"),
51
+ });
52
+ `.trim();
53
+
54
+ /**
55
+ * Generate the RSC entry content with the specified router path
56
+ */
57
+ export function getVirtualEntryRSC(routerPath: string): string {
58
+ return `
59
+ import {
60
+ renderToReadableStream,
61
+ decodeReply,
62
+ createTemporaryReferenceSet,
63
+ loadServerAction,
64
+ decodeAction,
65
+ decodeFormState,
66
+ } from "@rangojs/router/internal/deps/rsc";
67
+ import { router } from "${routerPath}";
68
+ import { createRSCHandler } from "@rangojs/router/rsc";
69
+ import { VERSION } from "@rangojs/router:version";
70
+
71
+ // Import loader manifest to ensure all fetchable loaders are registered at startup
72
+ // This is critical for serverless/multi-process deployments where the loader module
73
+ // might not be imported before a GET request arrives
74
+ import "virtual:rsc-router/loader-manifest";
75
+
76
+ export default createRSCHandler({
77
+ router,
78
+ version: VERSION,
79
+ deps: {
80
+ renderToReadableStream,
81
+ decodeReply,
82
+ createTemporaryReferenceSet,
83
+ loadServerAction,
84
+ decodeAction,
85
+ decodeFormState,
86
+ },
87
+ loadSSRModule: () =>
88
+ import.meta.viteRsc.loadModule("ssr", "index"),
89
+ });
90
+ `.trim();
91
+ }
92
+
93
+ /**
94
+ * Virtual module IDs
95
+ */
96
+ export const VIRTUAL_IDS = {
97
+ browser: "virtual:rsc-router/entry.browser.js",
98
+ ssr: "virtual:rsc-router/entry.ssr.js",
99
+ rsc: "virtual:rsc-router/entry.rsc.js",
100
+ version: "@rangojs/router:version",
101
+ } as const;
102
+
103
+ /**
104
+ * Virtual module content for version.
105
+ * Exports VERSION - a timestamp that changes on server restart (dev) or at build time (production).
106
+ */
107
+ export function getVirtualVersionContent(version: string): string {
108
+ return `export const VERSION = ${JSON.stringify(version)};`;
109
+ }