@reckona/mreact-router 0.0.152 → 0.0.154

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 (105) hide show
  1. package/README.md +1 -1
  2. package/dist/actions.d.ts +10 -0
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +6 -0
  5. package/dist/actions.js.map +1 -1
  6. package/dist/adapters/aws-lambda.d.ts +18 -0
  7. package/dist/adapters/aws-lambda.d.ts.map +1 -1
  8. package/dist/adapters/aws-lambda.js +18 -0
  9. package/dist/adapters/aws-lambda.js.map +1 -1
  10. package/dist/adapters/cloudflare.d.ts +33 -0
  11. package/dist/adapters/cloudflare.d.ts.map +1 -1
  12. package/dist/adapters/cloudflare.js +33 -0
  13. package/dist/adapters/cloudflare.js.map +1 -1
  14. package/dist/adapters/edge.d.ts +5 -0
  15. package/dist/adapters/edge.d.ts.map +1 -1
  16. package/dist/adapters/edge.js +5 -0
  17. package/dist/adapters/edge.js.map +1 -1
  18. package/dist/adapters/node.d.ts +5 -0
  19. package/dist/adapters/node.d.ts.map +1 -1
  20. package/dist/adapters/node.js +5 -0
  21. package/dist/adapters/node.js.map +1 -1
  22. package/dist/adapters/static.d.ts +5 -0
  23. package/dist/adapters/static.d.ts.map +1 -1
  24. package/dist/adapters/static.js +5 -0
  25. package/dist/adapters/static.js.map +1 -1
  26. package/dist/build.d.ts +15 -0
  27. package/dist/build.d.ts.map +1 -1
  28. package/dist/build.js +85 -2
  29. package/dist/build.js.map +1 -1
  30. package/dist/cache.d.ts +15 -0
  31. package/dist/cache.d.ts.map +1 -1
  32. package/dist/cache.js +15 -0
  33. package/dist/cache.js.map +1 -1
  34. package/dist/cookies.d.ts +16 -0
  35. package/dist/cookies.d.ts.map +1 -1
  36. package/dist/cookies.js +16 -0
  37. package/dist/cookies.js.map +1 -1
  38. package/dist/dev-server.d.ts +5 -0
  39. package/dist/dev-server.d.ts.map +1 -1
  40. package/dist/dev-server.js +5 -0
  41. package/dist/dev-server.js.map +1 -1
  42. package/dist/link.d.ts +10 -0
  43. package/dist/link.d.ts.map +1 -1
  44. package/dist/link.js +5 -0
  45. package/dist/link.js.map +1 -1
  46. package/dist/middleware.d.ts.map +1 -1
  47. package/dist/middleware.js +39 -4
  48. package/dist/middleware.js.map +1 -1
  49. package/dist/module-runner.d.ts +6 -0
  50. package/dist/module-runner.d.ts.map +1 -1
  51. package/dist/module-runner.js +71 -0
  52. package/dist/module-runner.js.map +1 -1
  53. package/dist/navigation.d.ts +53 -0
  54. package/dist/navigation.d.ts.map +1 -1
  55. package/dist/navigation.js +48 -0
  56. package/dist/navigation.js.map +1 -1
  57. package/dist/render.d.ts +34 -0
  58. package/dist/render.d.ts.map +1 -1
  59. package/dist/render.js +161 -27
  60. package/dist/render.js.map +1 -1
  61. package/dist/route-module-loader.d.ts +6 -1
  62. package/dist/route-module-loader.d.ts.map +1 -1
  63. package/dist/route-module-loader.js +8 -1
  64. package/dist/route-module-loader.js.map +1 -1
  65. package/dist/serve.d.ts +5 -0
  66. package/dist/serve.d.ts.map +1 -1
  67. package/dist/serve.js +5 -0
  68. package/dist/serve.js.map +1 -1
  69. package/dist/session.d.ts +19 -0
  70. package/dist/session.d.ts.map +1 -1
  71. package/dist/session.js +19 -0
  72. package/dist/session.js.map +1 -1
  73. package/dist/typed-routes.d.ts +5 -0
  74. package/dist/typed-routes.d.ts.map +1 -1
  75. package/dist/typed-routes.js +5 -0
  76. package/dist/typed-routes.js.map +1 -1
  77. package/dist/types.d.ts +15 -0
  78. package/dist/types.d.ts.map +1 -1
  79. package/dist/types.js +5 -0
  80. package/dist/types.js.map +1 -1
  81. package/dist/vite.d.ts.map +1 -1
  82. package/dist/vite.js +1 -0
  83. package/dist/vite.js.map +1 -1
  84. package/package.json +11 -11
  85. package/src/actions.ts +18 -0
  86. package/src/adapters/aws-lambda.ts +18 -0
  87. package/src/adapters/cloudflare.ts +33 -0
  88. package/src/adapters/edge.ts +5 -0
  89. package/src/adapters/node.ts +5 -0
  90. package/src/adapters/static.ts +5 -0
  91. package/src/build.ts +118 -1
  92. package/src/cache.ts +15 -0
  93. package/src/cookies.ts +16 -0
  94. package/src/dev-server.ts +5 -0
  95. package/src/link.ts +10 -0
  96. package/src/middleware.ts +54 -4
  97. package/src/module-runner.ts +91 -0
  98. package/src/navigation.ts +53 -0
  99. package/src/render.ts +229 -25
  100. package/src/route-module-loader.ts +15 -0
  101. package/src/serve.ts +5 -0
  102. package/src/session.ts +19 -0
  103. package/src/typed-routes.ts +5 -0
  104. package/src/types.ts +15 -0
  105. package/src/vite.ts +1 -0
package/dist/session.d.ts CHANGED
@@ -21,9 +21,28 @@ export interface SessionCookieOptions {
21
21
  sameSite?: "Strict" | "Lax" | "None";
22
22
  secure?: boolean;
23
23
  }
24
+ /**
25
+ * Creates a process-local session store backed by an in-memory LRU-like map.
26
+ *
27
+ * Use it for development, tests, or single-process deployments; production multi-instance deployments should provide a shared `SessionStore`.
28
+ */
24
29
  export declare function createMemorySessionStore<TData>(options?: MemorySessionStoreOptions): SessionStore<TData>;
30
+ /**
31
+ * Reads the current session cookie, loads the matching session record, and deletes expired records.
32
+ */
25
33
  export declare function getSession<TData>(request: Request, store: SessionStore<TData>, options?: SessionCookieOptions): Promise<SessionRecord<TData> | undefined>;
34
+ /**
35
+ * Creates a new session record, stores it, and appends the session cookie to the response.
36
+ */
26
37
  export declare function createSession<TData>(response: Response, store: SessionStore<TData>, data: TData, options?: SessionCookieOptions): Promise<SessionRecord<TData>>;
38
+ /**
39
+ * Deletes the current session record when present and appends an expiring session cookie to the response.
40
+ */
27
41
  export declare function destroySession<TData>(request: Request, response: Response, store: SessionStore<TData>, options?: SessionCookieOptions): Promise<void>;
42
+ /**
43
+ * Replaces the current session id while preserving the stored session data.
44
+ *
45
+ * Use this after authentication or privilege changes to reduce session fixation risk.
46
+ */
28
47
  export declare function rotateSession<TData>(request: Request, response: Response, store: SessionStore<TData>, options?: SessionCookieOptions): Promise<SessionRecord<TData> | undefined>;
29
48
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa,CAAC,KAAK,GAAG,OAAO;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,KAAK,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY,CAAC,KAAK,GAAG,OAAO;IAC3C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC;IAC9F,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA+CD,wBAAgB,wBAAwB,CAAC,KAAK,EAC5C,OAAO,GAAE,yBAA8B,GACtC,YAAY,CAAC,KAAK,CAAC,CAoErB;AAUD,wBAAsB,UAAU,CAAC,KAAK,EACpC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAC1B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAmB3C;AAED,wBAAsB,aAAa,CAAC,KAAK,EACvC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAC1B,IAAI,EAAE,KAAK,EACX,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAgB/B;AAED,wBAAsB,cAAc,CAAC,KAAK,EACxC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAC1B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,wBAAsB,aAAa,CAAC,KAAK,EACvC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAC1B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAW3C"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa,CAAC,KAAK,GAAG,OAAO;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,KAAK,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY,CAAC,KAAK,GAAG,OAAO;IAC3C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC;IAC9F,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA+CD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAC5C,OAAO,GAAE,yBAA8B,GACtC,YAAY,CAAC,KAAK,CAAC,CAoErB;AAUD;;GAEG;AACH,wBAAsB,UAAU,CAAC,KAAK,EACpC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAC1B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAmB3C;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,KAAK,EACvC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAC1B,IAAI,EAAE,KAAK,EACX,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAgB/B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,KAAK,EACxC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAC1B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,KAAK,EACvC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAC1B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAW3C"}
package/dist/session.js CHANGED
@@ -31,6 +31,11 @@ function createSessionId() {
31
31
  }
32
32
  return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
33
33
  }
34
+ /**
35
+ * Creates a process-local session store backed by an in-memory LRU-like map.
36
+ *
37
+ * Use it for development, tests, or single-process deployments; production multi-instance deployments should provide a shared `SessionStore`.
38
+ */
34
39
  export function createMemorySessionStore(options = {}) {
35
40
  const maxEntries = positiveIntegerOrDefault(options.maxEntries, 100_000);
36
41
  const sweepIntervalMs = nonNegativeIntegerOrDefault(options.sweepIntervalMs, 60_000);
@@ -94,6 +99,9 @@ function positiveIntegerOrDefault(value, fallback) {
94
99
  function nonNegativeIntegerOrDefault(value, fallback) {
95
100
  return value === undefined || !Number.isInteger(value) || value < 0 ? fallback : value;
96
101
  }
102
+ /**
103
+ * Reads the current session cookie, loads the matching session record, and deletes expired records.
104
+ */
97
105
  export async function getSession(request, store, options = {}) {
98
106
  const id = readSessionId(request, options);
99
107
  if (id === undefined || id.length === 0) {
@@ -109,6 +117,9 @@ export async function getSession(request, store, options = {}) {
109
117
  }
110
118
  return record;
111
119
  }
120
+ /**
121
+ * Creates a new session record, stores it, and appends the session cookie to the response.
122
+ */
112
123
  export async function createSession(response, store, data, options = {}) {
113
124
  const now = Date.now();
114
125
  const maxAgeSeconds = options.maxAgeSeconds ?? DEFAULT_MAX_AGE_SECONDS;
@@ -124,6 +135,9 @@ export async function createSession(response, store, data, options = {}) {
124
135
  });
125
136
  return record;
126
137
  }
138
+ /**
139
+ * Deletes the current session record when present and appends an expiring session cookie to the response.
140
+ */
127
141
  export async function destroySession(request, response, store, options = {}) {
128
142
  const id = readSessionId(request, options);
129
143
  if (id !== undefined) {
@@ -135,6 +149,11 @@ export async function destroySession(request, response, store, options = {}) {
135
149
  secure: options.secure ?? isProduction(),
136
150
  });
137
151
  }
152
+ /**
153
+ * Replaces the current session id while preserving the stored session data.
154
+ *
155
+ * Use this after authentication or privilege changes to reduce session fixation risk.
156
+ */
138
157
  export async function rotateSession(request, response, store, options = {}) {
139
158
  const current = await getSession(request, store, options);
140
159
  if (current === undefined) {
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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","sourcesContent":["import { deleteCookie, parseCookieHeader, setCookie } from \"./cookies.js\";\n\nexport interface SessionRecord<TData = unknown> {\n createdAt: number;\n data: TData;\n expiresAt: number;\n id: string;\n rotatedAt?: number;\n}\n\nexport interface SessionStore<TData = unknown> {\n delete(id: string): void | Promise<void>;\n get(id: string): SessionRecord<TData> | undefined | Promise<SessionRecord<TData> | undefined>;\n set(record: SessionRecord<TData>): void | Promise<void>;\n}\n\nexport interface MemorySessionStoreOptions {\n maxEntries?: number;\n sweepIntervalMs?: number;\n}\n\nexport interface SessionCookieOptions {\n cookieName?: string;\n maxAgeSeconds?: number;\n path?: string;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n secure?: boolean;\n}\n\nconst DEFAULT_MAX_AGE_SECONDS = 7 * 24 * 60 * 60;\nconst SESSION_COOKIE_DEV = \"mreact.session\";\nconst SESSION_COOKIE_PROD = \"__Host-mreact.session\";\n\nfunction isProduction(): boolean {\n return process.env.NODE_ENV === \"production\";\n}\n\nfunction defaultCookieName(): string {\n return isProduction() ? SESSION_COOKIE_PROD : SESSION_COOKIE_DEV;\n}\n\nfunction sessionCookieOptions(options: SessionCookieOptions = {}) {\n const production = isProduction();\n\n return {\n httpOnly: true,\n maxAge: options.maxAgeSeconds ?? DEFAULT_MAX_AGE_SECONDS,\n path: production ? \"/\" : options.path ?? \"/\",\n sameSite: options.sameSite ?? \"Lax\",\n secure: options.secure ?? production,\n } as const;\n}\n\nfunction readSessionId(\n request: Request,\n options: SessionCookieOptions = {},\n): string | undefined {\n const values = parseCookieHeader(request.headers.get(\"cookie\"));\n return values.get(options.cookieName ?? defaultCookieName());\n}\n\nfunction createSessionId(): string {\n const bytes = new Uint8Array(32);\n\n globalThis.crypto.getRandomValues(bytes);\n\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\nexport function createMemorySessionStore<TData>(\n options: MemorySessionStoreOptions = {},\n): SessionStore<TData> {\n const maxEntries = positiveIntegerOrDefault(options.maxEntries, 100_000);\n const sweepIntervalMs = nonNegativeIntegerOrDefault(options.sweepIntervalMs, 60_000);\n const records = new Map<string, SessionRecord<TData>>();\n let nextSweepAt = 0;\n\n function sweepExpired(now: number): void {\n for (const [id, value] of records) {\n if (value.expiresAt <= now) {\n records.delete(id);\n }\n }\n\n nextSweepAt = now + sweepIntervalMs;\n }\n\n function maybeSweepExpired(now: number): void {\n if (sweepIntervalMs === 0 || now >= nextSweepAt) {\n sweepExpired(now);\n }\n }\n\n function evictOldestEntries(): void {\n while (records.size > maxEntries) {\n const oldestId = records.keys().next().value;\n\n if (oldestId === undefined) {\n return;\n }\n\n records.delete(oldestId);\n }\n }\n\n return {\n delete(id) {\n records.delete(id);\n },\n get(id) {\n const now = Date.now();\n maybeSweepExpired(now);\n const record = records.get(id);\n\n if (record !== undefined && record.expiresAt <= now) {\n records.delete(id);\n return undefined;\n }\n\n if (record !== undefined) {\n records.delete(id);\n records.set(id, record);\n }\n\n return record;\n },\n set(record) {\n const now = Date.now();\n maybeSweepExpired(now);\n\n records.delete(record.id);\n records.set(record.id, record);\n\n if (records.size > maxEntries) {\n sweepExpired(now);\n evictOldestEntries();\n }\n },\n };\n}\n\nfunction positiveIntegerOrDefault(value: number | undefined, fallback: number): number {\n return value === undefined || !Number.isInteger(value) || value < 1 ? fallback : value;\n}\n\nfunction nonNegativeIntegerOrDefault(value: number | undefined, fallback: number): number {\n return value === undefined || !Number.isInteger(value) || value < 0 ? fallback : value;\n}\n\nexport async function getSession<TData>(\n request: Request,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<SessionRecord<TData> | undefined> {\n const id = readSessionId(request, options);\n\n if (id === undefined || id.length === 0) {\n return undefined;\n }\n\n const record = await store.get(id);\n\n if (record === undefined) {\n return undefined;\n }\n\n if (record.expiresAt <= Date.now()) {\n await store.delete(id);\n return undefined;\n }\n\n return record;\n}\n\nexport async function createSession<TData>(\n response: Response,\n store: SessionStore<TData>,\n data: TData,\n options: SessionCookieOptions = {},\n): Promise<SessionRecord<TData>> {\n const now = Date.now();\n const maxAgeSeconds = options.maxAgeSeconds ?? DEFAULT_MAX_AGE_SECONDS;\n const record: SessionRecord<TData> = {\n createdAt: now,\n data,\n expiresAt: now + maxAgeSeconds * 1000,\n id: createSessionId(),\n };\n\n await store.set(record);\n setCookie(response, options.cookieName ?? defaultCookieName(), record.id, {\n ...sessionCookieOptions({ ...options, maxAgeSeconds }),\n });\n\n return record;\n}\n\nexport async function destroySession<TData>(\n request: Request,\n response: Response,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<void> {\n const id = readSessionId(request, options);\n\n if (id !== undefined) {\n await store.delete(id);\n }\n\n deleteCookie(response, options.cookieName ?? defaultCookieName(), {\n path: isProduction() ? \"/\" : options.path ?? \"/\",\n sameSite: options.sameSite ?? \"Lax\",\n secure: options.secure ?? isProduction(),\n });\n}\n\nexport async function rotateSession<TData>(\n request: Request,\n response: Response,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<SessionRecord<TData> | undefined> {\n const current = await getSession(request, store, options);\n\n if (current === undefined) {\n return undefined;\n }\n\n await store.delete(current.id);\n const next = await createSession(response, store, current.data, options);\n\n return { ...next, rotatedAt: Date.now() };\n}\n"]}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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","sourcesContent":["import { deleteCookie, parseCookieHeader, setCookie } from \"./cookies.js\";\n\nexport interface SessionRecord<TData = unknown> {\n createdAt: number;\n data: TData;\n expiresAt: number;\n id: string;\n rotatedAt?: number;\n}\n\nexport interface SessionStore<TData = unknown> {\n delete(id: string): void | Promise<void>;\n get(id: string): SessionRecord<TData> | undefined | Promise<SessionRecord<TData> | undefined>;\n set(record: SessionRecord<TData>): void | Promise<void>;\n}\n\nexport interface MemorySessionStoreOptions {\n maxEntries?: number;\n sweepIntervalMs?: number;\n}\n\nexport interface SessionCookieOptions {\n cookieName?: string;\n maxAgeSeconds?: number;\n path?: string;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n secure?: boolean;\n}\n\nconst DEFAULT_MAX_AGE_SECONDS = 7 * 24 * 60 * 60;\nconst SESSION_COOKIE_DEV = \"mreact.session\";\nconst SESSION_COOKIE_PROD = \"__Host-mreact.session\";\n\nfunction isProduction(): boolean {\n return process.env.NODE_ENV === \"production\";\n}\n\nfunction defaultCookieName(): string {\n return isProduction() ? SESSION_COOKIE_PROD : SESSION_COOKIE_DEV;\n}\n\nfunction sessionCookieOptions(options: SessionCookieOptions = {}) {\n const production = isProduction();\n\n return {\n httpOnly: true,\n maxAge: options.maxAgeSeconds ?? DEFAULT_MAX_AGE_SECONDS,\n path: production ? \"/\" : options.path ?? \"/\",\n sameSite: options.sameSite ?? \"Lax\",\n secure: options.secure ?? production,\n } as const;\n}\n\nfunction readSessionId(\n request: Request,\n options: SessionCookieOptions = {},\n): string | undefined {\n const values = parseCookieHeader(request.headers.get(\"cookie\"));\n return values.get(options.cookieName ?? defaultCookieName());\n}\n\nfunction createSessionId(): string {\n const bytes = new Uint8Array(32);\n\n globalThis.crypto.getRandomValues(bytes);\n\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/**\n * Creates a process-local session store backed by an in-memory LRU-like map.\n *\n * Use it for development, tests, or single-process deployments; production multi-instance deployments should provide a shared `SessionStore`.\n */\nexport function createMemorySessionStore<TData>(\n options: MemorySessionStoreOptions = {},\n): SessionStore<TData> {\n const maxEntries = positiveIntegerOrDefault(options.maxEntries, 100_000);\n const sweepIntervalMs = nonNegativeIntegerOrDefault(options.sweepIntervalMs, 60_000);\n const records = new Map<string, SessionRecord<TData>>();\n let nextSweepAt = 0;\n\n function sweepExpired(now: number): void {\n for (const [id, value] of records) {\n if (value.expiresAt <= now) {\n records.delete(id);\n }\n }\n\n nextSweepAt = now + sweepIntervalMs;\n }\n\n function maybeSweepExpired(now: number): void {\n if (sweepIntervalMs === 0 || now >= nextSweepAt) {\n sweepExpired(now);\n }\n }\n\n function evictOldestEntries(): void {\n while (records.size > maxEntries) {\n const oldestId = records.keys().next().value;\n\n if (oldestId === undefined) {\n return;\n }\n\n records.delete(oldestId);\n }\n }\n\n return {\n delete(id) {\n records.delete(id);\n },\n get(id) {\n const now = Date.now();\n maybeSweepExpired(now);\n const record = records.get(id);\n\n if (record !== undefined && record.expiresAt <= now) {\n records.delete(id);\n return undefined;\n }\n\n if (record !== undefined) {\n records.delete(id);\n records.set(id, record);\n }\n\n return record;\n },\n set(record) {\n const now = Date.now();\n maybeSweepExpired(now);\n\n records.delete(record.id);\n records.set(record.id, record);\n\n if (records.size > maxEntries) {\n sweepExpired(now);\n evictOldestEntries();\n }\n },\n };\n}\n\nfunction positiveIntegerOrDefault(value: number | undefined, fallback: number): number {\n return value === undefined || !Number.isInteger(value) || value < 1 ? fallback : value;\n}\n\nfunction nonNegativeIntegerOrDefault(value: number | undefined, fallback: number): number {\n return value === undefined || !Number.isInteger(value) || value < 0 ? fallback : value;\n}\n\n/**\n * Reads the current session cookie, loads the matching session record, and deletes expired records.\n */\nexport async function getSession<TData>(\n request: Request,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<SessionRecord<TData> | undefined> {\n const id = readSessionId(request, options);\n\n if (id === undefined || id.length === 0) {\n return undefined;\n }\n\n const record = await store.get(id);\n\n if (record === undefined) {\n return undefined;\n }\n\n if (record.expiresAt <= Date.now()) {\n await store.delete(id);\n return undefined;\n }\n\n return record;\n}\n\n/**\n * Creates a new session record, stores it, and appends the session cookie to the response.\n */\nexport async function createSession<TData>(\n response: Response,\n store: SessionStore<TData>,\n data: TData,\n options: SessionCookieOptions = {},\n): Promise<SessionRecord<TData>> {\n const now = Date.now();\n const maxAgeSeconds = options.maxAgeSeconds ?? DEFAULT_MAX_AGE_SECONDS;\n const record: SessionRecord<TData> = {\n createdAt: now,\n data,\n expiresAt: now + maxAgeSeconds * 1000,\n id: createSessionId(),\n };\n\n await store.set(record);\n setCookie(response, options.cookieName ?? defaultCookieName(), record.id, {\n ...sessionCookieOptions({ ...options, maxAgeSeconds }),\n });\n\n return record;\n}\n\n/**\n * Deletes the current session record when present and appends an expiring session cookie to the response.\n */\nexport async function destroySession<TData>(\n request: Request,\n response: Response,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<void> {\n const id = readSessionId(request, options);\n\n if (id !== undefined) {\n await store.delete(id);\n }\n\n deleteCookie(response, options.cookieName ?? defaultCookieName(), {\n path: isProduction() ? \"/\" : options.path ?? \"/\",\n sameSite: options.sameSite ?? \"Lax\",\n secure: options.secure ?? isProduction(),\n });\n}\n\n/**\n * Replaces the current session id while preserving the stored session data.\n *\n * Use this after authentication or privilege changes to reduce session fixation risk.\n */\nexport async function rotateSession<TData>(\n request: Request,\n response: Response,\n store: SessionStore<TData>,\n options: SessionCookieOptions = {},\n): Promise<SessionRecord<TData> | undefined> {\n const current = await getSession(request, store, options);\n\n if (current === undefined) {\n return undefined;\n }\n\n await store.delete(current.id);\n const next = await createSession(response, store, current.data, options);\n\n return { ...next, rotatedAt: Date.now() };\n}\n"]}
@@ -24,6 +24,11 @@ export type AppRouteLinkHrefSuffix = "" | `?${string}` | `#${string}` | `?${stri
24
24
  export type AppRouteLinkPathname<Path extends `/${string}`> = Path extends "/" ? "/" : Path extends `/${infer Segments}` ? `/${AppRouteLinkSegments<Segments>}` : never;
25
25
  export type AppRouteLinkSegments<Segments extends string> = Segments extends `${infer Segment}/${infer Rest}` ? `${AppRouteLinkSegment<Segment>}/${AppRouteLinkSegments<Rest>}` : AppRouteLinkSegment<Segments>;
26
26
  export type AppRouteLinkSegment<Segment extends string> = Segment extends `:${string}` ? string : Segment;
27
+ /**
28
+ * Builds an internal app-route URL from a route pattern and typed params/search options.
29
+ *
30
+ * Dynamic `:param` and `:...catchAll` segments are URL-encoded, search values are serialized with `URLSearchParams`, and protocol-relative or external paths are rejected.
31
+ */
27
32
  export declare function href<const Path extends `/${string}`>(path: Path, ...args: HasRouteParams<Path> extends true ? [options: DynamicHrefOptions<Path>] : [options?: StaticHrefOptions]): string;
28
33
  export {};
29
34
  //# sourceMappingURL=typed-routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"typed-routes.d.ts","sourceRoot":"","sources":["../src/typed-routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"typed-routes.d.ts","sourceRoot":"","sources":["../src/typed-routes.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Builds an internal app-route URL from a route pattern and typed params/search options.
3
+ *
4
+ * Dynamic `:param` and `:...catchAll` segments are URL-encoded, search values are serialized with `URLSearchParams`, and protocol-relative or external paths are rejected.
5
+ */
1
6
  export function href(path, ...args) {
2
7
  assertInternalRoutePath(path);
3
8
  const options = args[0];
@@ -1 +1 @@
1
- {"version":3,"file":"typed-routes.js","sourceRoot":"","sources":["../src/typed-routes.ts"],"names":[],"mappings":"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","sourcesContent":["export type RouteSearchValue = boolean | number | string | null | undefined;\nexport type RouteSearchParams = Record<\n string,\n RouteSearchValue | readonly RouteSearchValue[]\n>;\n\nexport type RouteParamsFor<Path extends `/${string}`> = Simplify<ExtractRouteParams<Path>>;\n\nexport type AppRouteHref<Path extends `/${string}`> = keyof RouteParamsFor<Path> extends never\n ? (options?: StaticHrefOptions) => string\n : (options: DynamicHrefOptions<Path>) => string;\n\nexport type AppRouteLinkHref<Path extends `/${string}`> =\n `${AppRouteLinkPathname<Path>}${AppRouteLinkHrefSuffix}`;\n\nexport interface StaticHrefOptions {\n hash?: string | undefined;\n search?: RouteSearchParams | undefined;\n}\n\nexport interface DynamicHrefOptions<Path extends `/${string}`> extends StaticHrefOptions {\n params: RouteParamsFor<Path>;\n}\n\ntype HasRouteParams<Path extends `/${string}`> = keyof RouteParamsFor<Path> extends never\n ? false\n : true;\n\ntype ExtractRouteParams<Path extends string> = Path extends `${infer Segment}/${infer Rest}`\n ? SegmentRouteParam<Segment> & ExtractRouteParams<Rest>\n : SegmentRouteParam<Path>;\n\ntype SegmentRouteParam<Segment extends string> = Segment extends `:...${infer Name}`\n ? { [Key in Name]: readonly string[] }\n : Segment extends `:${infer Name}`\n ? { [Key in Name]: string }\n : Record<never, never>;\n\ntype Simplify<T> = { [Key in keyof T]: T[Key] } & {};\n\nexport type AppRouteLinkHrefSuffix = \"\" | `?${string}` | `#${string}` | `?${string}#${string}`;\n\nexport type AppRouteLinkPathname<Path extends `/${string}`> = Path extends \"/\"\n ? \"/\"\n : Path extends `/${infer Segments}`\n ? `/${AppRouteLinkSegments<Segments>}`\n : never;\n\nexport type AppRouteLinkSegments<Segments extends string> = Segments extends `${infer Segment}/${infer Rest}`\n ? `${AppRouteLinkSegment<Segment>}/${AppRouteLinkSegments<Rest>}`\n : AppRouteLinkSegment<Segments>;\n\nexport type AppRouteLinkSegment<Segment extends string> = Segment extends `:${string}`\n ? string\n : Segment;\n\nexport function href<const Path extends `/${string}`>(\n path: Path,\n ...args: HasRouteParams<Path> extends true\n ? [options: DynamicHrefOptions<Path>]\n : [options?: StaticHrefOptions]\n): string {\n assertInternalRoutePath(path);\n\n const options = args[0] as\n | (StaticHrefOptions & { params?: Record<string, readonly string[] | string> | undefined })\n | undefined;\n const params =\n options !== undefined && \"params\" in options && options.params !== undefined\n ? (options.params as Record<string, readonly string[] | string>)\n : {};\n const pathname = path\n .split(\"/\")\n .map((segment) => {\n if (segment.startsWith(\":...\")) {\n const name = segment.slice(4);\n const value = params[name];\n\n if (!Array.isArray(value)) {\n throw new Error(`Missing catch-all route param ${JSON.stringify(name)} for ${path}.`);\n }\n\n return value.map((part) => encodeURIComponent(part)).join(\"/\");\n }\n\n if (segment.startsWith(\":\")) {\n const name = segment.slice(1);\n const value = params[name];\n\n if (typeof value !== \"string\") {\n throw new Error(`Missing route param ${JSON.stringify(name)} for ${path}.`);\n }\n\n return encodeURIComponent(value);\n }\n\n return segment;\n })\n .join(\"/\");\n const search = searchString(options?.search);\n const hash = options?.hash === undefined ? \"\" : `#${encodeURIComponent(options.hash)}`;\n\n return `${pathname}${search}${hash}`;\n}\n\nfunction assertInternalRoutePath(path: string): void {\n if (!path.startsWith(\"/\") || path.startsWith(\"//\")) {\n throw new Error(`href() expected an internal route path, received ${JSON.stringify(path)}.`);\n }\n\n for (let index = 0; index < path.length; index += 1) {\n const code = path.charCodeAt(index);\n\n if (code <= 0x1f || code === 0x7f) {\n throw new Error(\"href() route paths must not contain control characters.\");\n }\n }\n}\n\nfunction searchString(search: RouteSearchParams | undefined): string {\n if (search === undefined) {\n return \"\";\n }\n\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(search)) {\n const values = Array.isArray(value) ? value : [value];\n\n for (const entry of values) {\n if (entry !== undefined && entry !== null) {\n params.append(key, String(entry));\n }\n }\n }\n\n const value = params.toString();\n\n return value === \"\" ? \"\" : `?${value}`;\n}\n"]}
1
+ {"version":3,"file":"typed-routes.js","sourceRoot":"","sources":["../src/typed-routes.ts"],"names":[],"mappings":"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","sourcesContent":["export type RouteSearchValue = boolean | number | string | null | undefined;\nexport type RouteSearchParams = Record<\n string,\n RouteSearchValue | readonly RouteSearchValue[]\n>;\n\nexport type RouteParamsFor<Path extends `/${string}`> = Simplify<ExtractRouteParams<Path>>;\n\nexport type AppRouteHref<Path extends `/${string}`> = keyof RouteParamsFor<Path> extends never\n ? (options?: StaticHrefOptions) => string\n : (options: DynamicHrefOptions<Path>) => string;\n\nexport type AppRouteLinkHref<Path extends `/${string}`> =\n `${AppRouteLinkPathname<Path>}${AppRouteLinkHrefSuffix}`;\n\nexport interface StaticHrefOptions {\n hash?: string | undefined;\n search?: RouteSearchParams | undefined;\n}\n\nexport interface DynamicHrefOptions<Path extends `/${string}`> extends StaticHrefOptions {\n params: RouteParamsFor<Path>;\n}\n\ntype HasRouteParams<Path extends `/${string}`> = keyof RouteParamsFor<Path> extends never\n ? false\n : true;\n\ntype ExtractRouteParams<Path extends string> = Path extends `${infer Segment}/${infer Rest}`\n ? SegmentRouteParam<Segment> & ExtractRouteParams<Rest>\n : SegmentRouteParam<Path>;\n\ntype SegmentRouteParam<Segment extends string> = Segment extends `:...${infer Name}`\n ? { [Key in Name]: readonly string[] }\n : Segment extends `:${infer Name}`\n ? { [Key in Name]: string }\n : Record<never, never>;\n\ntype Simplify<T> = { [Key in keyof T]: T[Key] } & {};\n\nexport type AppRouteLinkHrefSuffix = \"\" | `?${string}` | `#${string}` | `?${string}#${string}`;\n\nexport type AppRouteLinkPathname<Path extends `/${string}`> = Path extends \"/\"\n ? \"/\"\n : Path extends `/${infer Segments}`\n ? `/${AppRouteLinkSegments<Segments>}`\n : never;\n\nexport type AppRouteLinkSegments<Segments extends string> = Segments extends `${infer Segment}/${infer Rest}`\n ? `${AppRouteLinkSegment<Segment>}/${AppRouteLinkSegments<Rest>}`\n : AppRouteLinkSegment<Segments>;\n\nexport type AppRouteLinkSegment<Segment extends string> = Segment extends `:${string}`\n ? string\n : Segment;\n\n/**\n * Builds an internal app-route URL from a route pattern and typed params/search options.\n *\n * Dynamic `:param` and `:...catchAll` segments are URL-encoded, search values are serialized with `URLSearchParams`, and protocol-relative or external paths are rejected.\n */\nexport function href<const Path extends `/${string}`>(\n path: Path,\n ...args: HasRouteParams<Path> extends true\n ? [options: DynamicHrefOptions<Path>]\n : [options?: StaticHrefOptions]\n): string {\n assertInternalRoutePath(path);\n\n const options = args[0] as\n | (StaticHrefOptions & { params?: Record<string, readonly string[] | string> | undefined })\n | undefined;\n const params =\n options !== undefined && \"params\" in options && options.params !== undefined\n ? (options.params as Record<string, readonly string[] | string>)\n : {};\n const pathname = path\n .split(\"/\")\n .map((segment) => {\n if (segment.startsWith(\":...\")) {\n const name = segment.slice(4);\n const value = params[name];\n\n if (!Array.isArray(value)) {\n throw new Error(`Missing catch-all route param ${JSON.stringify(name)} for ${path}.`);\n }\n\n return value.map((part) => encodeURIComponent(part)).join(\"/\");\n }\n\n if (segment.startsWith(\":\")) {\n const name = segment.slice(1);\n const value = params[name];\n\n if (typeof value !== \"string\") {\n throw new Error(`Missing route param ${JSON.stringify(name)} for ${path}.`);\n }\n\n return encodeURIComponent(value);\n }\n\n return segment;\n })\n .join(\"/\");\n const search = searchString(options?.search);\n const hash = options?.hash === undefined ? \"\" : `#${encodeURIComponent(options.hash)}`;\n\n return `${pathname}${search}${hash}`;\n}\n\nfunction assertInternalRoutePath(path: string): void {\n if (!path.startsWith(\"/\") || path.startsWith(\"//\")) {\n throw new Error(`href() expected an internal route path, received ${JSON.stringify(path)}.`);\n }\n\n for (let index = 0; index < path.length; index += 1) {\n const code = path.charCodeAt(index);\n\n if (code <= 0x1f || code === 0x7f) {\n throw new Error(\"href() route paths must not contain control characters.\");\n }\n }\n}\n\nfunction searchString(search: RouteSearchParams | undefined): string {\n if (search === undefined) {\n return \"\";\n }\n\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(search)) {\n const values = Array.isArray(value) ? value : [value];\n\n for (const entry of values) {\n if (entry !== undefined && entry !== null) {\n params.append(key, String(entry));\n }\n }\n }\n\n const value = params.toString();\n\n return value === \"\" ? \"\" : `?${value}`;\n}\n"]}
package/dist/types.d.ts CHANGED
@@ -12,6 +12,11 @@ export interface LoaderContext<TParams extends RouteParams = RouteParams> {
12
12
  queryClient: QueryClient;
13
13
  request: Request;
14
14
  }
15
+ /**
16
+ * Context passed to a route `generateMetadata` export.
17
+ *
18
+ * Metadata is evaluated on the server after loader data is available, so it can derive head tags, robots data, sitemap entries, and security header directives from the same request and route params as the page.
19
+ */
15
20
  export interface GenerateMetadataContext<TData = unknown, TParams extends RouteParams = RouteParams> {
16
21
  data: TData;
17
22
  params: TParams;
@@ -27,6 +32,11 @@ export interface PageProps<TData = unknown, TParams extends RouteParams = RouteP
27
32
  request: Request;
28
33
  }
29
34
  export type PageComponent<TLoader extends RouteLoader> = (props: PageProps<InferLoaderData<TLoader>, InferLoaderParams<TLoader>>) => ReactCompatNode;
35
+ /**
36
+ * Preserves the relationship between a page component and its loader when authoring route files.
37
+ *
38
+ * Wrap a default page export with `definePage<typeof loader>(...)` to infer `data` and `params` props from the route loader without changing runtime behavior.
39
+ */
30
40
  export declare function definePage<TLoader extends RouteLoader>(component: PageComponent<TLoader>): PageComponent<TLoader>;
31
41
  export interface LayoutProps<TParams extends RouteParams = RouteParams> {
32
42
  children: ReactCompatNode;
@@ -42,6 +52,11 @@ export interface MetadataImage {
42
52
  url: MetadataScalar;
43
53
  width?: MetadataScalar;
44
54
  }
55
+ /**
56
+ * Declarative metadata returned by route metadata exports.
57
+ *
58
+ * Values are rendered into the document head and response headers by the app router; use `generateMetadata` when the values depend on loader data, params, or the current request.
59
+ */
45
60
  export interface RouteMetadata {
46
61
  alternates?: {
47
62
  canonical?: MetadataScalar;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC;AAExD,MAAM,MAAM,eAAe,CAAC,OAAO,SAAS,WAAW,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;AAExF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC;AAErE,MAAM,MAAM,iBAAiB,CAAC,OAAO,SAAS,WAAW,IAAI,OAAO,SAAS,CAC3E,OAAO,EAAE,MAAM,QAAQ,EACvB,GAAG,IAAI,EAAE,KAAK,EAAE,KACb,OAAO,GACR,QAAQ,SAAS;IAAE,MAAM,EAAE,MAAM,OAAO,CAAA;CAAE,GACxC,OAAO,SAAS,WAAW,GACzB,OAAO,GACP,WAAW,GACb,WAAW,GACb,WAAW,CAAC;AAEhB,MAAM,WAAW,aAAa,CAAC,OAAO,SAAS,WAAW,GAAG,WAAW;IACtE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB,CACtC,KAAK,GAAG,OAAO,EACf,OAAO,SAAS,WAAW,GAAG,WAAW;IAEzC,IAAI,EAAE,KAAK,CAAC;IACZ,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB,CAAC,OAAO,SAAS,WAAW,GAAG,WAAW;IAC5E,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,SAAS,CAAC,KAAK,GAAG,OAAO,EAAE,OAAO,SAAS,WAAW,GAAG,WAAW;IACnF,IAAI,EAAE,KAAK,CAAC;IACZ,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,aAAa,CAAC,OAAO,SAAS,WAAW,IAAI,CACvD,KAAK,EAAE,SAAS,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC,KACnE,eAAe,CAAC;AAErB;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,SAAS,WAAW,EACpD,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC,GAChC,aAAa,CAAC,OAAO,CAAC,CAExB;AAED,MAAM,WAAW,WAAW,CAAC,OAAO,SAAS,WAAW,GAAG,WAAW;IACpE,QAAQ,EAAE,eAAe,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,UAAU,GAAG,eAAe,CAAC;AAEzC,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,GAAG,EAAE,cAAc,CAAC;IACpB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE;QACX,SAAS,CAAC,EAAE,cAAc,CAAC;KAC5B,CAAC;IACF,GAAG,CAAC,EAAE;QACJ,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC;QACxD,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC;KACtD,CAAC;IACF,WAAW,CAAC,EAAE,cAAc,CAAC;IAC7B,IAAI,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACtC,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,cAAc,CAAC;QACvB,IAAI,CAAC,EAAE,cAAc,CAAC;KACvB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,WAAW,CAAC,EAAE,cAAc,CAAC;QAC7B,KAAK,CAAC,EAAE,aAAa,GAAG,cAAc,CAAC;QACvC,MAAM,CAAC,EAAE,SAAS,CAAC,aAAa,GAAG,cAAc,CAAC,EAAE,CAAC;QACrD,KAAK,CAAC,EAAE,cAAc,CAAC;KACxB,CAAC;IACF,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,MAAM,CAAC,EACH,MAAM,GACN;QACE,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,CAAC;IACN,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,UAAU,CAAC,EAAE,cAAc,GAAG,kBAAkB,CAAC;IACjD,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,QAAQ,CAAC,EAAE,cAAc,GAAG,gBAAgB,CAAC;CAC9C;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAEjF,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CACpD;AAED,MAAM,WAAW,oBAAoB;IACnC,kBAAkB,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,CAAC;IAClD,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS,CAAC;IACxD,IAAI,CAAC,EAAE,4BAA4B,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5F,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC5C;AAED,MAAM,WAAW,4BAA4B;IAC3C,iBAAiB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,UAAU,EAAE,GAAG,SAAS,CAAC;IACvD,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAClD;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAClD,SAAS,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,YAAY,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC"}
package/dist/types.js CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Preserves the relationship between a page component and its loader when authoring route files.
3
+ *
4
+ * Wrap a default page export with `definePage<typeof loader>(...)` to infer `data` and `params` props from the route loader without changing runtime behavior.
5
+ */
1
6
  export function definePage(component) {
2
7
  return component;
3
8
  }
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAmDA,MAAM,UAAU,UAAU,CACxB,SAAiC;IAEjC,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { ReactCompatNode } from \"@reckona/mreact-compat\";\nimport type { QueryClient } from \"@reckona/mreact-query\";\n\nexport type RouteLoader = (...args: never[]) => unknown;\n\nexport type InferLoaderData<TLoader extends RouteLoader> = Awaited<ReturnType<TLoader>>;\n\nexport type RouteParams = Record<string, readonly string[] | string>;\n\nexport type InferLoaderParams<TLoader extends RouteLoader> = TLoader extends (\n context: infer TContext,\n ...args: never[]\n) => unknown\n ? TContext extends { params: infer TParams }\n ? TParams extends RouteParams\n ? TParams\n : RouteParams\n : RouteParams\n : RouteParams;\n\nexport interface LoaderContext<TParams extends RouteParams = RouteParams> {\n env?: unknown;\n params: TParams;\n queryClient: QueryClient;\n request: Request;\n}\n\nexport interface GenerateMetadataContext<\n TData = unknown,\n TParams extends RouteParams = RouteParams,\n> {\n data: TData;\n params: TParams;\n request: Request;\n}\n\nexport interface RouteHandlerContext<TParams extends RouteParams = RouteParams> {\n params: TParams;\n request: Request;\n}\n\nexport interface PageProps<TData = unknown, TParams extends RouteParams = RouteParams> {\n data: TData;\n params: TParams;\n request: Request;\n}\n\nexport type PageComponent<TLoader extends RouteLoader> = (\n props: PageProps<InferLoaderData<TLoader>, InferLoaderParams<TLoader>>,\n) => ReactCompatNode;\n\nexport function definePage<TLoader extends RouteLoader>(\n component: PageComponent<TLoader>,\n): PageComponent<TLoader> {\n return component;\n}\n\nexport interface LayoutProps<TParams extends RouteParams = RouteParams> {\n children: ReactCompatNode;\n params: TParams;\n request: Request;\n}\n\nexport type MReactNode = ReactCompatNode;\n\nexport type MetadataScalar = boolean | number | string;\n\nexport interface MetadataImage {\n alt?: MetadataScalar;\n height?: MetadataScalar;\n type?: MetadataScalar;\n url: MetadataScalar;\n width?: MetadataScalar;\n}\n\nexport interface RouteMetadata {\n alternates?: {\n canonical?: MetadataScalar;\n };\n csp?: {\n disable?: boolean;\n directives?: Record<string, readonly string[] | string>;\n nonce?: string;\n remove?: readonly string[];\n replace?: Record<string, readonly string[] | string>;\n };\n description?: MetadataScalar;\n head?: readonly RouteHeadDescriptor[];\n icons?: {\n apple?: MetadataScalar;\n icon?: MetadataScalar;\n };\n openGraph?: {\n description?: MetadataScalar;\n image?: MetadataImage | MetadataScalar;\n images?: readonly (MetadataImage | MetadataScalar)[];\n title?: MetadataScalar;\n };\n lang?: MetadataScalar;\n robots?:\n | string\n | {\n follow?: boolean;\n index?: boolean;\n };\n security?: RouteSecurityHeaders;\n themeColor?: MetadataScalar | MetadataThemeColor;\n title?: MetadataScalar;\n viewport?: MetadataScalar | MetadataViewport;\n}\n\nexport type MetadataViewport = Record<string, MetadataScalar | null | undefined>;\n\nexport interface MetadataThemeColor {\n color?: MetadataScalar;\n media?: MetadataScalar;\n}\n\nexport interface RouteHeadDescriptor {\n attrs?: Record<string, boolean | number | string | undefined>;\n content?: string;\n nonce?: boolean | string;\n tag: \"base\" | \"link\" | \"meta\" | \"script\" | \"style\";\n}\n\nexport interface RouteSecurityHeaders {\n contentTypeOptions?: \"nosniff\" | null | undefined;\n frameOptions?: \"DENY\" | \"SAMEORIGIN\" | null | undefined;\n hsts?: RouteStrictTransportSecurity | false | null | undefined;\n permissionsPolicy?: Record<string, readonly string[] | null | undefined> | null | undefined;\n referrerPolicy?: string | null | undefined;\n}\n\nexport interface RouteStrictTransportSecurity {\n includeSubDomains?: boolean | undefined;\n maxAge: number;\n preload?: boolean | undefined;\n}\n\nexport interface RobotsContext {\n baseUrl: string;\n host: string;\n request: Request;\n}\n\nexport interface RobotsManifest {\n host?: string | undefined;\n rules?: RobotsRule | readonly RobotsRule[] | undefined;\n sitemap?: string | readonly string[] | undefined;\n}\n\nexport interface RobotsRule {\n allow?: string | readonly string[] | undefined;\n disallow?: string | readonly string[] | undefined;\n userAgent: string | readonly string[];\n}\n\nexport interface SitemapContext {\n baseUrl: string;\n host: string;\n request: Request;\n}\n\nexport interface SitemapEntry {\n changeFrequency?: string | undefined;\n lastModified?: Date | string | number | undefined;\n priority?: number | undefined;\n url: string;\n}\n\nexport interface ManifestContext {\n baseUrl: string;\n host: string;\n request: Request;\n}\n\nexport type ManifestDescriptor = Record<string, unknown>;\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAwDA;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,SAAiC;IAEjC,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { ReactCompatNode } from \"@reckona/mreact-compat\";\nimport type { QueryClient } from \"@reckona/mreact-query\";\n\nexport type RouteLoader = (...args: never[]) => unknown;\n\nexport type InferLoaderData<TLoader extends RouteLoader> = Awaited<ReturnType<TLoader>>;\n\nexport type RouteParams = Record<string, readonly string[] | string>;\n\nexport type InferLoaderParams<TLoader extends RouteLoader> = TLoader extends (\n context: infer TContext,\n ...args: never[]\n) => unknown\n ? TContext extends { params: infer TParams }\n ? TParams extends RouteParams\n ? TParams\n : RouteParams\n : RouteParams\n : RouteParams;\n\nexport interface LoaderContext<TParams extends RouteParams = RouteParams> {\n env?: unknown;\n params: TParams;\n queryClient: QueryClient;\n request: Request;\n}\n\n/**\n * Context passed to a route `generateMetadata` export.\n *\n * Metadata is evaluated on the server after loader data is available, so it can derive head tags, robots data, sitemap entries, and security header directives from the same request and route params as the page.\n */\nexport interface GenerateMetadataContext<\n TData = unknown,\n TParams extends RouteParams = RouteParams,\n> {\n data: TData;\n params: TParams;\n request: Request;\n}\n\nexport interface RouteHandlerContext<TParams extends RouteParams = RouteParams> {\n params: TParams;\n request: Request;\n}\n\nexport interface PageProps<TData = unknown, TParams extends RouteParams = RouteParams> {\n data: TData;\n params: TParams;\n request: Request;\n}\n\nexport type PageComponent<TLoader extends RouteLoader> = (\n props: PageProps<InferLoaderData<TLoader>, InferLoaderParams<TLoader>>,\n) => ReactCompatNode;\n\n/**\n * Preserves the relationship between a page component and its loader when authoring route files.\n *\n * Wrap a default page export with `definePage<typeof loader>(...)` to infer `data` and `params` props from the route loader without changing runtime behavior.\n */\nexport function definePage<TLoader extends RouteLoader>(\n component: PageComponent<TLoader>,\n): PageComponent<TLoader> {\n return component;\n}\n\nexport interface LayoutProps<TParams extends RouteParams = RouteParams> {\n children: ReactCompatNode;\n params: TParams;\n request: Request;\n}\n\nexport type MReactNode = ReactCompatNode;\n\nexport type MetadataScalar = boolean | number | string;\n\nexport interface MetadataImage {\n alt?: MetadataScalar;\n height?: MetadataScalar;\n type?: MetadataScalar;\n url: MetadataScalar;\n width?: MetadataScalar;\n}\n\n/**\n * Declarative metadata returned by route metadata exports.\n *\n * Values are rendered into the document head and response headers by the app router; use `generateMetadata` when the values depend on loader data, params, or the current request.\n */\nexport interface RouteMetadata {\n alternates?: {\n canonical?: MetadataScalar;\n };\n csp?: {\n disable?: boolean;\n directives?: Record<string, readonly string[] | string>;\n nonce?: string;\n remove?: readonly string[];\n replace?: Record<string, readonly string[] | string>;\n };\n description?: MetadataScalar;\n head?: readonly RouteHeadDescriptor[];\n icons?: {\n apple?: MetadataScalar;\n icon?: MetadataScalar;\n };\n openGraph?: {\n description?: MetadataScalar;\n image?: MetadataImage | MetadataScalar;\n images?: readonly (MetadataImage | MetadataScalar)[];\n title?: MetadataScalar;\n };\n lang?: MetadataScalar;\n robots?:\n | string\n | {\n follow?: boolean;\n index?: boolean;\n };\n security?: RouteSecurityHeaders;\n themeColor?: MetadataScalar | MetadataThemeColor;\n title?: MetadataScalar;\n viewport?: MetadataScalar | MetadataViewport;\n}\n\nexport type MetadataViewport = Record<string, MetadataScalar | null | undefined>;\n\nexport interface MetadataThemeColor {\n color?: MetadataScalar;\n media?: MetadataScalar;\n}\n\nexport interface RouteHeadDescriptor {\n attrs?: Record<string, boolean | number | string | undefined>;\n content?: string;\n nonce?: boolean | string;\n tag: \"base\" | \"link\" | \"meta\" | \"script\" | \"style\";\n}\n\nexport interface RouteSecurityHeaders {\n contentTypeOptions?: \"nosniff\" | null | undefined;\n frameOptions?: \"DENY\" | \"SAMEORIGIN\" | null | undefined;\n hsts?: RouteStrictTransportSecurity | false | null | undefined;\n permissionsPolicy?: Record<string, readonly string[] | null | undefined> | null | undefined;\n referrerPolicy?: string | null | undefined;\n}\n\nexport interface RouteStrictTransportSecurity {\n includeSubDomains?: boolean | undefined;\n maxAge: number;\n preload?: boolean | undefined;\n}\n\nexport interface RobotsContext {\n baseUrl: string;\n host: string;\n request: Request;\n}\n\nexport interface RobotsManifest {\n host?: string | undefined;\n rules?: RobotsRule | readonly RobotsRule[] | undefined;\n sitemap?: string | readonly string[] | undefined;\n}\n\nexport interface RobotsRule {\n allow?: string | readonly string[] | undefined;\n disallow?: string | readonly string[] | undefined;\n userAgent: string | readonly string[];\n}\n\nexport interface SitemapContext {\n baseUrl: string;\n host: string;\n request: Request;\n}\n\nexport interface SitemapEntry {\n changeFrequency?: string | undefined;\n lastModified?: Date | string | number | undefined;\n priority?: number | undefined;\n url: string;\n}\n\nexport interface ManifestContext {\n baseUrl: string;\n host: string;\n request: Request;\n}\n\nexport type ManifestDescriptor = Record<string, unknown>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,UAAU,EAEhB,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AA0BhE,OAAO,EAAsB,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAKxE,MAAM,WAAW,8BAA+B,SAAQ,uBAAuB;IAC7E,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7C,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;IAC1C,UAAU,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC3C,YAAY,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACjD,UAAU,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACxC,aAAa,CAAC,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACzD,WAAW,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;CACnD;AAQD,MAAM,WAAW,0BAA2B,SAAQ,uBAAuB;IACzE,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7C,UAAU,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC3C,YAAY,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACjD,UAAU,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACxC,aAAa,CAAC,EAAE,4BAA4B,GAAG,SAAS,CAAC;CAC1D;AAmBD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,0BAA0B,GAAG,MAAM,CA0SrF;AAqBD,eAAO,MAAM,YAAY,kCAA4B,CAAC;AAoCtD,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,SAAS,OAAO,EAAE,GAC1B,wBAAwB,GAAG,SAAS,CActC;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,kBAAkB,CAc5B;AAyFD,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAA;CAAO,GACjF,OAAO,CAAC,QAAQ,CAAC,CAuEnB"}
1
+ {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,UAAU,EAEhB,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AA0BhE,OAAO,EAAsB,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAKxE,MAAM,WAAW,8BAA+B,SAAQ,uBAAuB;IAC7E,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7C,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;IAC1C,UAAU,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC3C,YAAY,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACjD,UAAU,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACxC,aAAa,CAAC,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACzD,WAAW,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;CACnD;AAQD,MAAM,WAAW,0BAA2B,SAAQ,uBAAuB;IACzE,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7C,UAAU,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC3C,YAAY,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACjD,UAAU,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACxC,aAAa,CAAC,EAAE,4BAA4B,GAAG,SAAS,CAAC;CAC1D;AAmBD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,0BAA0B,GAAG,MAAM,CA0SrF;AAqBD,eAAO,MAAM,YAAY,kCAA4B,CAAC;AAoCtD,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,SAAS,OAAO,EAAE,GAC1B,wBAAwB,GAAG,SAAS,CActC;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,kBAAkB,CAc5B;AA0FD,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAA;CAAO,GACjF,OAAO,CAAC,QAAQ,CAAC,CAuEnB"}
package/dist/vite.js CHANGED
@@ -381,6 +381,7 @@ async function handleAppRouterViteRequest(options, incoming, outgoing, next) {
381
381
  await sendResponse(outgoing, await renderAppRequest({
382
382
  appDir: project.routesDir,
383
383
  define: options.define,
384
+ dev: true,
384
385
  importPolicy: {
385
386
  ...options.importPolicy,
386
387
  allowedSourceDirs: project.allowedSourceDirs,