@fragno-dev/core 0.1.7 → 0.1.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.
Files changed (183) hide show
  1. package/.turbo/turbo-build.log +131 -64
  2. package/CHANGELOG.md +19 -0
  3. package/dist/api/api.d.ts +38 -2
  4. package/dist/api/api.d.ts.map +1 -0
  5. package/dist/api/api.js +9 -2
  6. package/dist/api/api.js.map +1 -0
  7. package/dist/api/bind-services.d.ts +6 -0
  8. package/dist/api/bind-services.d.ts.map +1 -0
  9. package/dist/api/bind-services.js +20 -0
  10. package/dist/api/bind-services.js.map +1 -0
  11. package/dist/api/error.d.ts +26 -0
  12. package/dist/api/error.d.ts.map +1 -0
  13. package/dist/{api-DngJDcmO.js → api/error.js} +2 -8
  14. package/dist/api/error.js.map +1 -0
  15. package/dist/api/fragment-definition-builder.d.ts +313 -0
  16. package/dist/api/fragment-definition-builder.d.ts.map +1 -0
  17. package/dist/api/fragment-definition-builder.js +326 -0
  18. package/dist/api/fragment-definition-builder.js.map +1 -0
  19. package/dist/api/fragment-instantiator.d.ts +216 -0
  20. package/dist/api/fragment-instantiator.d.ts.map +1 -0
  21. package/dist/api/fragment-instantiator.js +487 -0
  22. package/dist/api/fragment-instantiator.js.map +1 -0
  23. package/dist/api/fragno-response.d.ts +30 -0
  24. package/dist/api/fragno-response.d.ts.map +1 -0
  25. package/dist/api/fragno-response.js +73 -0
  26. package/dist/api/fragno-response.js.map +1 -0
  27. package/dist/api/internal/path.d.ts +50 -0
  28. package/dist/api/internal/path.d.ts.map +1 -0
  29. package/dist/api/internal/path.js +76 -0
  30. package/dist/api/internal/path.js.map +1 -0
  31. package/dist/api/internal/response-stream.d.ts +43 -0
  32. package/dist/api/internal/response-stream.d.ts.map +1 -0
  33. package/dist/api/internal/response-stream.js +81 -0
  34. package/dist/api/internal/response-stream.js.map +1 -0
  35. package/dist/api/internal/route.js +10 -0
  36. package/dist/api/internal/route.js.map +1 -0
  37. package/dist/api/mutable-request-state.d.ts +82 -0
  38. package/dist/api/mutable-request-state.d.ts.map +1 -0
  39. package/dist/api/mutable-request-state.js +97 -0
  40. package/dist/api/mutable-request-state.js.map +1 -0
  41. package/dist/api/request-context-storage.d.ts +42 -0
  42. package/dist/api/request-context-storage.d.ts.map +1 -0
  43. package/dist/api/request-context-storage.js +43 -0
  44. package/dist/api/request-context-storage.js.map +1 -0
  45. package/dist/api/request-input-context.d.ts +89 -0
  46. package/dist/api/request-input-context.d.ts.map +1 -0
  47. package/dist/api/request-input-context.js +118 -0
  48. package/dist/api/request-input-context.js.map +1 -0
  49. package/dist/api/request-middleware.d.ts +50 -0
  50. package/dist/api/request-middleware.d.ts.map +1 -0
  51. package/dist/api/request-middleware.js +83 -0
  52. package/dist/api/request-middleware.js.map +1 -0
  53. package/dist/api/request-output-context.d.ts +41 -0
  54. package/dist/api/request-output-context.d.ts.map +1 -0
  55. package/dist/api/request-output-context.js +119 -0
  56. package/dist/api/request-output-context.js.map +1 -0
  57. package/dist/api/route-handler-input-options.d.ts +21 -0
  58. package/dist/api/route-handler-input-options.d.ts.map +1 -0
  59. package/dist/api/route.d.ts +54 -3
  60. package/dist/api/route.d.ts.map +1 -0
  61. package/dist/api/route.js +29 -2
  62. package/dist/api/route.js.map +1 -0
  63. package/dist/api/shared-types.d.ts +47 -0
  64. package/dist/api/shared-types.d.ts.map +1 -0
  65. package/dist/api/shared-types.js +1 -0
  66. package/dist/client/client-error.d.ts +60 -0
  67. package/dist/client/client-error.d.ts.map +1 -0
  68. package/dist/client/client-error.js +92 -0
  69. package/dist/client/client-error.js.map +1 -0
  70. package/dist/client/client.d.ts +210 -4
  71. package/dist/client/client.d.ts.map +1 -0
  72. package/dist/client/client.js +397 -6
  73. package/dist/client/client.js.map +1 -0
  74. package/dist/client/client.svelte.d.ts +5 -3
  75. package/dist/client/client.svelte.d.ts.map +1 -1
  76. package/dist/client/client.svelte.js +1 -5
  77. package/dist/client/client.svelte.js.map +1 -1
  78. package/dist/client/internal/fetcher-merge.js +36 -0
  79. package/dist/client/internal/fetcher-merge.js.map +1 -0
  80. package/dist/client/internal/ndjson-streaming.js +139 -0
  81. package/dist/client/internal/ndjson-streaming.js.map +1 -0
  82. package/dist/client/react.d.ts +5 -3
  83. package/dist/client/react.d.ts.map +1 -1
  84. package/dist/client/react.js +3 -5
  85. package/dist/client/react.js.map +1 -1
  86. package/dist/client/solid.d.ts +5 -3
  87. package/dist/client/solid.d.ts.map +1 -1
  88. package/dist/client/solid.js +2 -5
  89. package/dist/client/solid.js.map +1 -1
  90. package/dist/client/vanilla.d.ts +5 -3
  91. package/dist/client/vanilla.d.ts.map +1 -1
  92. package/dist/client/vanilla.js +2 -43
  93. package/dist/client/vanilla.js.map +1 -1
  94. package/dist/client/vue.d.ts +5 -3
  95. package/dist/client/vue.d.ts.map +1 -1
  96. package/dist/client/vue.js +1 -5
  97. package/dist/client/vue.js.map +1 -1
  98. package/dist/http/http-status.d.ts +26 -0
  99. package/dist/http/http-status.d.ts.map +1 -0
  100. package/dist/integrations/react-ssr.js +1 -1
  101. package/dist/internal/symbols.d.ts +9 -0
  102. package/dist/internal/symbols.d.ts.map +1 -0
  103. package/dist/internal/symbols.js +10 -0
  104. package/dist/internal/symbols.js.map +1 -0
  105. package/dist/mod-client.d.ts +36 -0
  106. package/dist/mod-client.d.ts.map +1 -0
  107. package/dist/mod-client.js +21 -0
  108. package/dist/mod-client.js.map +1 -0
  109. package/dist/mod.d.ts +7 -4
  110. package/dist/mod.js +4 -6
  111. package/dist/request/request.d.ts +4 -0
  112. package/dist/request/request.js +5 -0
  113. package/dist/test/test.d.ts +62 -35
  114. package/dist/test/test.d.ts.map +1 -1
  115. package/dist/test/test.js +75 -40
  116. package/dist/test/test.js.map +1 -1
  117. package/dist/util/async.js +40 -0
  118. package/dist/util/async.js.map +1 -0
  119. package/dist/util/content-type.js +49 -0
  120. package/dist/util/content-type.js.map +1 -0
  121. package/dist/util/nanostores.js +31 -0
  122. package/dist/util/nanostores.js.map +1 -0
  123. package/dist/{ssr-BByDVfFD.js → util/ssr.js} +2 -2
  124. package/dist/util/ssr.js.map +1 -0
  125. package/dist/util/types-util.d.ts +8 -0
  126. package/dist/util/types-util.d.ts.map +1 -0
  127. package/package.json +19 -12
  128. package/src/api/api.ts +41 -6
  129. package/src/api/bind-services.ts +42 -0
  130. package/src/api/fragment-definition-builder.extend.test.ts +810 -0
  131. package/src/api/fragment-definition-builder.test.ts +499 -0
  132. package/src/api/fragment-definition-builder.ts +1088 -0
  133. package/src/api/fragment-instantiator.test.ts +1488 -0
  134. package/src/api/fragment-instantiator.ts +1053 -0
  135. package/src/api/fragment-services.test.ts +727 -0
  136. package/src/api/request-context-storage.ts +64 -0
  137. package/src/api/request-middleware.test.ts +301 -225
  138. package/src/api/route.test.ts +87 -1
  139. package/src/api/route.ts +345 -24
  140. package/src/api/shared-types.ts +43 -0
  141. package/src/client/client-builder.test.ts +23 -23
  142. package/src/client/client.ssr.test.ts +3 -3
  143. package/src/client/client.svelte.test.ts +15 -15
  144. package/src/client/client.test.ts +22 -22
  145. package/src/client/client.ts +72 -12
  146. package/src/client/internal/fetcher-merge.ts +1 -1
  147. package/src/client/react.test.ts +2 -2
  148. package/src/client/solid.test.ts +2 -2
  149. package/src/client/vanilla.test.ts +2 -2
  150. package/src/client/vue.test.ts +2 -2
  151. package/src/internal/symbols.ts +5 -0
  152. package/src/mod-client.ts +59 -0
  153. package/src/mod.ts +26 -9
  154. package/src/request/request.ts +8 -0
  155. package/src/test/test.test.ts +200 -381
  156. package/src/test/test.ts +190 -117
  157. package/tsdown.config.ts +8 -5
  158. package/dist/api/fragment-builder.d.ts +0 -4
  159. package/dist/api/fragment-builder.js +0 -3
  160. package/dist/api/fragment-instantiation.d.ts +0 -4
  161. package/dist/api/fragment-instantiation.js +0 -6
  162. package/dist/api-BWN97TOr.d.ts +0 -377
  163. package/dist/api-BWN97TOr.d.ts.map +0 -1
  164. package/dist/api-DngJDcmO.js.map +0 -1
  165. package/dist/client-C5LsYHEI.js +0 -782
  166. package/dist/client-C5LsYHEI.js.map +0 -1
  167. package/dist/fragment-builder-DOnCVBqc.js +0 -47
  168. package/dist/fragment-builder-DOnCVBqc.js.map +0 -1
  169. package/dist/fragment-builder-MGr68GNb.d.ts +0 -409
  170. package/dist/fragment-builder-MGr68GNb.d.ts.map +0 -1
  171. package/dist/fragment-instantiation-C4wvwl6V.js +0 -446
  172. package/dist/fragment-instantiation-C4wvwl6V.js.map +0 -1
  173. package/dist/request-output-context-CdIjwmEN.js +0 -320
  174. package/dist/request-output-context-CdIjwmEN.js.map +0 -1
  175. package/dist/route-Bl9Zr1Yv.d.ts +0 -26
  176. package/dist/route-Bl9Zr1Yv.d.ts.map +0 -1
  177. package/dist/route-C5Uryylh.js +0 -21
  178. package/dist/route-C5Uryylh.js.map +0 -1
  179. package/dist/ssr-BByDVfFD.js.map +0 -1
  180. package/src/api/fragment-builder.ts +0 -80
  181. package/src/api/fragment-instantiation.test.ts +0 -460
  182. package/src/api/fragment-instantiation.ts +0 -499
  183. package/src/api/fragment.test.ts +0 -537
@@ -1,320 +0,0 @@
1
- import { r as FragnoApiValidationError } from "./api-DngJDcmO.js";
2
-
3
- //#region src/api/internal/route.ts
4
- function getMountRoute(opts) {
5
- const mountRoute = opts.mountRoute ?? `/api/${opts.name}`;
6
- if (mountRoute.endsWith("/")) return mountRoute.slice(0, -1);
7
- return mountRoute;
8
- }
9
-
10
- //#endregion
11
- //#region src/api/request-input-context.ts
12
- var RequestInputContext = class RequestInputContext {
13
- #path;
14
- #method;
15
- #pathParams;
16
- #searchParams;
17
- #headers;
18
- #body;
19
- #parsedBody;
20
- #inputSchema;
21
- #shouldValidateInput;
22
- constructor(config) {
23
- this.#path = config.path;
24
- this.#method = config.method;
25
- this.#pathParams = config.pathParams;
26
- this.#searchParams = config.searchParams;
27
- this.#headers = config.headers;
28
- this.#body = config.rawBody;
29
- this.#parsedBody = config.parsedBody;
30
- this.#inputSchema = config.inputSchema;
31
- this.#shouldValidateInput = config.shouldValidateInput ?? true;
32
- }
33
- /**
34
- * Create a RequestContext from a Request object for server-side handling
35
- */
36
- static async fromRequest(config) {
37
- return new RequestInputContext({
38
- method: config.method,
39
- path: config.path,
40
- pathParams: config.state.pathParams,
41
- searchParams: config.state.searchParams,
42
- headers: config.state.headers,
43
- parsedBody: config.state.body,
44
- rawBody: config.rawBody,
45
- inputSchema: config.inputSchema,
46
- shouldValidateInput: config.shouldValidateInput
47
- });
48
- }
49
- /**
50
- * Create a RequestContext for server-side rendering contexts (no Request object)
51
- */
52
- static fromSSRContext(config) {
53
- return new RequestInputContext({
54
- method: config.method,
55
- path: config.path,
56
- pathParams: config.pathParams,
57
- searchParams: config.searchParams ?? new URLSearchParams(),
58
- headers: config.headers ?? new Headers(),
59
- parsedBody: "body" in config ? config.body : void 0,
60
- inputSchema: "inputSchema" in config ? config.inputSchema : void 0,
61
- shouldValidateInput: false
62
- });
63
- }
64
- /**
65
- * The HTTP method as string (e.g., `GET`, `POST`)
66
- */
67
- get method() {
68
- return this.#method;
69
- }
70
- /**
71
- * The matched route path (e.g., `/users/:id`)
72
- * @remarks `string`
73
- */
74
- get path() {
75
- return this.#path;
76
- }
77
- /**
78
- * Extracted path parameters as object (e.g., `{ id: '123' }`)
79
- * @remarks `Record<string, string>`
80
- */
81
- get pathParams() {
82
- return this.#pathParams;
83
- }
84
- /**
85
- * [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) object for query parameters
86
- * @remarks `URLSearchParams`
87
- */
88
- get query() {
89
- return this.#searchParams;
90
- }
91
- /**
92
- * [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object for request headers
93
- * @remarks `Headers`
94
- */
95
- get headers() {
96
- return this.#headers;
97
- }
98
- get rawBody() {
99
- return this.#body;
100
- }
101
- /**
102
- * Input validation context (only if inputSchema is defined)
103
- * @remarks `InputContext`
104
- */
105
- get input() {
106
- if (!this.#inputSchema) return;
107
- return {
108
- schema: this.#inputSchema,
109
- valid: async () => {
110
- if (!this.#shouldValidateInput) return this.#parsedBody;
111
- return this.#validateInput();
112
- }
113
- };
114
- }
115
- async #validateInput() {
116
- if (!this.#inputSchema) throw new Error("No input schema defined for this route");
117
- if (this.#parsedBody instanceof FormData || this.#parsedBody instanceof Blob) throw new Error("Schema validation is only supported for JSON data, not FormData or Blob");
118
- const result = await this.#inputSchema["~standard"].validate(this.#parsedBody);
119
- if (result.issues) throw new FragnoApiValidationError("Validation failed", result.issues);
120
- return result.value;
121
- }
122
- };
123
-
124
- //#endregion
125
- //#region src/api/internal/response-stream.ts
126
- var ResponseStream = class {
127
- #writer;
128
- #encoder;
129
- #abortSubscribers = [];
130
- #responseReadable;
131
- #aborted = false;
132
- #closed = false;
133
- /**
134
- * Whether the stream has been aborted.
135
- */
136
- get aborted() {
137
- return this.#aborted;
138
- }
139
- /**
140
- * Whether the stream has been closed normally.
141
- */
142
- get closed() {
143
- return this.#closed;
144
- }
145
- /**
146
- * The readable stream that the response is piped to.
147
- */
148
- get responseReadable() {
149
- return this.#responseReadable;
150
- }
151
- constructor(writable, readable) {
152
- this.#writer = writable.getWriter();
153
- this.#encoder = new TextEncoder();
154
- const reader = readable.getReader();
155
- this.#abortSubscribers.push(async () => {
156
- await reader.cancel();
157
- });
158
- this.#responseReadable = new ReadableStream({
159
- async pull(controller) {
160
- const { done, value } = await reader.read();
161
- if (done) controller.close();
162
- else controller.enqueue(value);
163
- },
164
- cancel: () => {
165
- this.abort();
166
- }
167
- });
168
- }
169
- async writeRaw(input) {
170
- try {
171
- if (typeof input === "string") input = this.#encoder.encode(input);
172
- await this.#writer.write(input);
173
- } catch {}
174
- }
175
- write(input) {
176
- return this.writeRaw(JSON.stringify(input) + "\n");
177
- }
178
- sleep(ms) {
179
- return new Promise((res) => setTimeout(res, ms));
180
- }
181
- async close() {
182
- try {
183
- await this.#writer.close();
184
- } catch {} finally {
185
- this.#closed = true;
186
- }
187
- }
188
- onAbort(listener) {
189
- this.#abortSubscribers.push(listener);
190
- }
191
- /**
192
- * Abort the stream.
193
- * You can call this method when stream is aborted by external event.
194
- */
195
- abort() {
196
- if (!this.aborted) {
197
- this.#aborted = true;
198
- this.#abortSubscribers.forEach((subscriber) => subscriber());
199
- }
200
- }
201
- };
202
-
203
- //#endregion
204
- //#region src/api/request-output-context.ts
205
- /**
206
- * Utility function to merge headers from multiple sources.
207
- * Later headers override earlier ones.
208
- */
209
- function mergeHeaders(...headerSources) {
210
- const mergedHeaders = new Headers();
211
- for (const headerSource of headerSources) {
212
- if (!headerSource) continue;
213
- if (headerSource instanceof Headers) for (const [key, value] of headerSource.entries()) mergedHeaders.set(key, value);
214
- else if (Array.isArray(headerSource)) for (const [key, value] of headerSource) mergedHeaders.set(key, value);
215
- else for (const [key, value] of Object.entries(headerSource)) mergedHeaders.set(key, value);
216
- }
217
- return mergedHeaders;
218
- }
219
- var OutputContext = class {
220
- /**
221
- * Creates an error response.
222
- *
223
- * Shortcut for `throw new FragnoApiError(...)`
224
- */
225
- error = ({ message, code }, initOrStatus, headers) => {
226
- if (typeof initOrStatus === "undefined") return Response.json({
227
- message,
228
- code
229
- }, {
230
- status: 500,
231
- headers
232
- });
233
- if (typeof initOrStatus === "number") return Response.json({
234
- message,
235
- code
236
- }, {
237
- status: initOrStatus,
238
- headers
239
- });
240
- const mergedHeaders = mergeHeaders(initOrStatus.headers, headers);
241
- return Response.json({
242
- message,
243
- code
244
- }, {
245
- status: initOrStatus.status,
246
- headers: mergedHeaders
247
- });
248
- };
249
- empty = (initOrStatus, headers) => {
250
- const defaultHeaders = {};
251
- if (typeof initOrStatus === "undefined") {
252
- const mergedHeaders$1 = mergeHeaders(defaultHeaders, headers);
253
- return new Response(null, {
254
- status: 201,
255
- headers: mergedHeaders$1
256
- });
257
- }
258
- if (typeof initOrStatus === "number") {
259
- const mergedHeaders$1 = mergeHeaders(defaultHeaders, headers);
260
- return new Response(null, {
261
- status: initOrStatus,
262
- headers: mergedHeaders$1
263
- });
264
- }
265
- const mergedHeaders = mergeHeaders(defaultHeaders, initOrStatus.headers, headers);
266
- return new Response(null, {
267
- status: initOrStatus.status,
268
- headers: mergedHeaders
269
- });
270
- };
271
- json = (object, initOrStatus, headers) => {
272
- if (typeof initOrStatus === "undefined") return Response.json(object, {
273
- status: 200,
274
- headers
275
- });
276
- if (typeof initOrStatus === "number") return Response.json(object, {
277
- status: initOrStatus,
278
- headers
279
- });
280
- const mergedHeaders = mergeHeaders(initOrStatus.headers, headers);
281
- return Response.json(object, {
282
- status: initOrStatus.status,
283
- headers: mergedHeaders
284
- });
285
- };
286
- jsonStream = (cb, { onError, headers } = {}) => {
287
- const defaultHeaders = {
288
- "content-type": "application/x-ndjson; charset=utf-8",
289
- "transfer-encoding": "chunked",
290
- "cache-control": "no-cache"
291
- };
292
- const { readable, writable } = new TransformStream();
293
- const stream = new ResponseStream(writable, readable);
294
- (async () => {
295
- try {
296
- await cb(stream);
297
- } catch (e) {
298
- if (e === void 0) {} else if (e instanceof Error && onError) await onError(e, stream);
299
- else console.error(e);
300
- } finally {
301
- stream.close();
302
- }
303
- })();
304
- return new Response(stream.responseReadable, {
305
- status: 200,
306
- headers: mergeHeaders(defaultHeaders, headers)
307
- });
308
- };
309
- };
310
- var RequestOutputContext = class extends OutputContext {
311
- #outputSchema;
312
- constructor(outputSchema) {
313
- super();
314
- this.#outputSchema = outputSchema;
315
- }
316
- };
317
-
318
- //#endregion
319
- export { getMountRoute as i, RequestOutputContext as n, RequestInputContext as r, OutputContext as t };
320
- //# sourceMappingURL=request-output-context-CdIjwmEN.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"request-output-context-CdIjwmEN.js","names":["#path","#method","#pathParams","#searchParams","#headers","#body","#parsedBody","#inputSchema","#shouldValidateInput","#validateInput","#aborted","#closed","#responseReadable","#writer","#encoder","#abortSubscribers","mergedHeaders","#outputSchema"],"sources":["../src/api/internal/route.ts","../src/api/request-input-context.ts","../src/api/internal/response-stream.ts","../src/api/request-output-context.ts"],"sourcesContent":["export function getMountRoute(opts: { mountRoute?: string; name: string }) {\n const mountRoute = opts.mountRoute ?? `/api/${opts.name}`;\n\n if (mountRoute.endsWith(\"/\")) {\n return mountRoute.slice(0, -1);\n }\n\n return mountRoute;\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { ExtractPathParams } from \"./internal/path\";\nimport { FragnoApiValidationError, type HTTPMethod } from \"./api\";\nimport type { MutableRequestState } from \"./mutable-request-state\";\n\nexport type RequestBodyType =\n | unknown // JSON\n | FormData\n | Blob\n | null\n | undefined;\n\nexport class RequestInputContext<\n TPath extends string = string,\n TInputSchema extends StandardSchemaV1 | undefined = undefined,\n> {\n readonly #path: TPath;\n readonly #method: string;\n readonly #pathParams: ExtractPathParams<TPath>;\n readonly #searchParams: URLSearchParams;\n readonly #headers: Headers;\n readonly #body: string | undefined;\n readonly #parsedBody: RequestBodyType;\n readonly #inputSchema: TInputSchema | undefined;\n readonly #shouldValidateInput: boolean;\n\n constructor(config: {\n path: TPath;\n method: string;\n pathParams: ExtractPathParams<TPath>;\n searchParams: URLSearchParams;\n parsedBody: RequestBodyType;\n rawBody?: string;\n headers: Headers;\n request?: Request;\n inputSchema?: TInputSchema;\n shouldValidateInput?: boolean;\n }) {\n this.#path = config.path;\n this.#method = config.method;\n this.#pathParams = config.pathParams;\n this.#searchParams = config.searchParams;\n this.#headers = config.headers;\n this.#body = config.rawBody;\n this.#parsedBody = config.parsedBody;\n this.#inputSchema = config.inputSchema;\n this.#shouldValidateInput = config.shouldValidateInput ?? true;\n }\n\n /**\n * Create a RequestContext from a Request object for server-side handling\n */\n static async fromRequest<\n TPath extends string,\n TInputSchema extends StandardSchemaV1 | undefined = undefined,\n >(config: {\n request: Request;\n method: string;\n path: TPath;\n pathParams: ExtractPathParams<TPath>;\n inputSchema?: TInputSchema;\n shouldValidateInput?: boolean;\n state: MutableRequestState;\n rawBody?: string;\n }): Promise<RequestInputContext<TPath, TInputSchema>> {\n // Use the mutable state (potentially modified by middleware)\n return new RequestInputContext({\n method: config.method,\n path: config.path,\n pathParams: config.state.pathParams as ExtractPathParams<TPath>,\n searchParams: config.state.searchParams,\n headers: config.state.headers,\n parsedBody: config.state.body,\n rawBody: config.rawBody,\n inputSchema: config.inputSchema,\n shouldValidateInput: config.shouldValidateInput,\n });\n }\n\n /**\n * Create a RequestContext for server-side rendering contexts (no Request object)\n */\n static fromSSRContext<\n TPath extends string,\n TInputSchema extends StandardSchemaV1 | undefined = undefined,\n >(\n config:\n | {\n method: \"GET\";\n path: TPath;\n pathParams: ExtractPathParams<TPath>;\n searchParams?: URLSearchParams;\n headers?: Headers;\n }\n | {\n method: Exclude<HTTPMethod, \"GET\">;\n path: TPath;\n pathParams: ExtractPathParams<TPath>;\n searchParams?: URLSearchParams;\n headers?: Headers;\n body: RequestBodyType;\n inputSchema?: TInputSchema;\n },\n ): RequestInputContext<TPath, TInputSchema> {\n return new RequestInputContext({\n method: config.method,\n path: config.path,\n pathParams: config.pathParams,\n searchParams: config.searchParams ?? new URLSearchParams(),\n headers: config.headers ?? new Headers(),\n parsedBody: \"body\" in config ? config.body : undefined,\n inputSchema: \"inputSchema\" in config ? config.inputSchema : undefined,\n shouldValidateInput: false, // No input validation in SSR context\n });\n }\n\n /**\n * The HTTP method as string (e.g., `GET`, `POST`)\n */\n get method(): string {\n return this.#method;\n }\n /**\n * The matched route path (e.g., `/users/:id`)\n * @remarks `string`\n */\n get path(): TPath {\n return this.#path;\n }\n /**\n * Extracted path parameters as object (e.g., `{ id: '123' }`)\n * @remarks `Record<string, string>`\n */\n get pathParams(): ExtractPathParams<TPath> {\n return this.#pathParams;\n }\n /**\n * [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) object for query parameters\n * @remarks `URLSearchParams`\n */\n get query(): URLSearchParams {\n return this.#searchParams;\n }\n /**\n * [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object for request headers\n * @remarks `Headers`\n */\n get headers(): Headers {\n return this.#headers;\n }\n\n get rawBody(): string | undefined {\n return this.#body;\n }\n\n /**\n * Input validation context (only if inputSchema is defined)\n * @remarks `InputContext`\n */\n get input(): TInputSchema extends undefined\n ? undefined\n : {\n schema: TInputSchema;\n valid: () => Promise<\n TInputSchema extends StandardSchemaV1\n ? StandardSchemaV1.InferOutput<TInputSchema>\n : unknown\n >;\n } {\n if (!this.#inputSchema) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return undefined as any;\n }\n\n return {\n schema: this.#inputSchema,\n valid: async () => {\n if (!this.#shouldValidateInput) {\n // In SSR context, return the body directly without validation\n return this.#parsedBody;\n }\n\n return this.#validateInput();\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n }\n\n async #validateInput(): Promise<\n TInputSchema extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<TInputSchema> : never\n > {\n if (!this.#inputSchema) {\n throw new Error(\"No input schema defined for this route\");\n }\n\n if (this.#parsedBody instanceof FormData || this.#parsedBody instanceof Blob) {\n throw new Error(\"Schema validation is only supported for JSON data, not FormData or Blob\");\n }\n\n const result = await this.#inputSchema[\"~standard\"].validate(this.#parsedBody);\n\n if (result.issues) {\n throw new FragnoApiValidationError(\"Validation failed\", result.issues);\n }\n\n return result.value as TInputSchema extends StandardSchemaV1\n ? StandardSchemaV1.InferOutput<TInputSchema>\n : never;\n }\n}\n","/**\n * @module\n * Stream utility.\n *\n * Modified from honojs/hono\n * Original source: https://github.com/honojs/hono/blob/0e3db674ad3f40be215a55a18062dd8e387ce525/src/utils/stream.ts\n * License: MIT\n * Date obtained: August 28 2025\n * Copyright (c) 2021-present Yusuke Wada and Hono contributors\n */\n\ntype Error<Message extends string> = { __errorMessage: Message };\n\nexport class ResponseStream<TArray> {\n #writer: WritableStreamDefaultWriter<Uint8Array>;\n #encoder: TextEncoder;\n #abortSubscribers: (() => void | Promise<void>)[] = [];\n #responseReadable: ReadableStream;\n\n #aborted: boolean = false;\n #closed: boolean = false;\n\n /**\n * Whether the stream has been aborted.\n */\n get aborted(): boolean {\n return this.#aborted;\n }\n\n /**\n * Whether the stream has been closed normally.\n */\n get closed(): boolean {\n return this.#closed;\n }\n\n /**\n * The readable stream that the response is piped to.\n */\n get responseReadable(): ReadableStream {\n return this.#responseReadable;\n }\n\n constructor(writable: WritableStream, readable: ReadableStream) {\n this.#writer = writable.getWriter();\n this.#encoder = new TextEncoder();\n const reader = readable.getReader();\n\n // in case the user disconnects, let the reader know to cancel\n // this in-turn results in responseReadable being closed\n // and writeSSE method no longer blocks indefinitely\n this.#abortSubscribers.push(async () => {\n await reader.cancel();\n });\n\n this.#responseReadable = new ReadableStream({\n async pull(controller) {\n const { done, value } = await reader.read();\n if (done) {\n controller.close();\n } else {\n controller.enqueue(value);\n }\n },\n cancel: () => {\n this.abort();\n },\n });\n }\n\n async writeRaw(input: Uint8Array | string): Promise<void> {\n try {\n if (typeof input === \"string\") {\n input = this.#encoder.encode(input);\n }\n await this.#writer.write(input);\n } catch {\n // Do nothing.\n }\n }\n\n write(\n input: TArray extends (infer U)[]\n ? U\n : Error<\"To use a streaming response, outputSchema must be an array.\">,\n ): Promise<void> {\n return this.writeRaw(JSON.stringify(input) + \"\\n\");\n }\n\n sleep(ms: number): Promise<unknown> {\n return new Promise((res) => setTimeout(res, ms));\n }\n\n async close() {\n try {\n await this.#writer.close();\n } catch {\n // Do nothing. If you want to handle errors, create a stream by yourself.\n } finally {\n this.#closed = true;\n }\n }\n\n onAbort(listener: () => void | Promise<void>) {\n this.#abortSubscribers.push(listener);\n }\n\n /**\n * Abort the stream.\n * You can call this method when stream is aborted by external event.\n */\n abort() {\n if (!this.aborted) {\n this.#aborted = true;\n this.#abortSubscribers.forEach((subscriber) => subscriber());\n }\n }\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { ContentlessStatusCode, StatusCode } from \"../http/http-status\";\nimport { ResponseStream } from \"./internal/response-stream\";\nimport type { InferOrUnknown } from \"../util/types-util\";\n\nexport type ResponseData = string | ArrayBuffer | ReadableStream | Uint8Array<ArrayBuffer>;\n\ninterface ResponseInit<T extends StatusCode = StatusCode> {\n headers?: HeadersInit;\n status?: T;\n statusText?: string;\n}\n\n/**\n * Utility function to merge headers from multiple sources.\n * Later headers override earlier ones.\n */\nfunction mergeHeaders(...headerSources: (HeadersInit | undefined)[]): HeadersInit | undefined {\n const mergedHeaders = new Headers();\n\n for (const headerSource of headerSources) {\n if (!headerSource) {\n continue;\n }\n\n if (headerSource instanceof Headers) {\n for (const [key, value] of headerSource.entries()) {\n mergedHeaders.set(key, value);\n }\n } else if (Array.isArray(headerSource)) {\n for (const [key, value] of headerSource) {\n mergedHeaders.set(key, value);\n }\n } else {\n for (const [key, value] of Object.entries(headerSource)) {\n mergedHeaders.set(key, value);\n }\n }\n }\n\n return mergedHeaders;\n}\n\nexport abstract class OutputContext<const TOutput, const TErrorCode extends string> {\n /**\n * Creates an error response.\n *\n * Shortcut for `throw new FragnoApiError(...)`\n */\n error = (\n { message, code }: { message: string; code: TErrorCode },\n initOrStatus?: ResponseInit | StatusCode,\n headers?: HeadersInit,\n ): Response => {\n if (typeof initOrStatus === \"undefined\") {\n return Response.json({ message: message, code }, { status: 500, headers });\n }\n\n if (typeof initOrStatus === \"number\") {\n return Response.json({ message: message, code }, { status: initOrStatus, headers });\n }\n\n const mergedHeaders = mergeHeaders(initOrStatus.headers, headers);\n return Response.json(\n { message: message, code },\n { status: initOrStatus.status, headers: mergedHeaders },\n );\n };\n\n empty = (\n initOrStatus?: ResponseInit<ContentlessStatusCode> | ContentlessStatusCode,\n headers?: HeadersInit,\n ): Response => {\n const defaultHeaders = {};\n\n if (typeof initOrStatus === \"undefined\") {\n const mergedHeaders = mergeHeaders(defaultHeaders, headers);\n return new Response(null, {\n status: 201,\n headers: mergedHeaders,\n });\n }\n\n if (typeof initOrStatus === \"number\") {\n const mergedHeaders = mergeHeaders(defaultHeaders, headers);\n return new Response(null, {\n status: initOrStatus,\n headers: mergedHeaders,\n });\n }\n\n const mergedHeaders = mergeHeaders(defaultHeaders, initOrStatus.headers, headers);\n return new Response(null, {\n status: initOrStatus.status,\n headers: mergedHeaders,\n });\n };\n\n json = (\n object: TOutput,\n initOrStatus?: ResponseInit | StatusCode,\n headers?: HeadersInit,\n ): Response => {\n if (typeof initOrStatus === \"undefined\") {\n return Response.json(object, {\n status: 200,\n headers,\n });\n }\n\n if (typeof initOrStatus === \"number\") {\n return Response.json(object, {\n status: initOrStatus,\n headers,\n });\n }\n\n const mergedHeaders = mergeHeaders(initOrStatus.headers, headers);\n return Response.json(object, {\n status: initOrStatus.status,\n headers: mergedHeaders,\n });\n };\n\n jsonStream = (\n cb: (stream: ResponseStream<TOutput>) => void | Promise<void>,\n {\n onError,\n headers,\n }: {\n onError?: (error: Error, stream: ResponseStream<TOutput>) => void | Promise<void>;\n headers?: HeadersInit;\n } = {},\n ): Response => {\n // Note: this is intentionally an arrow function (=>) to keep `this` context.\n const defaultHeaders = {\n \"content-type\": \"application/x-ndjson; charset=utf-8\",\n \"transfer-encoding\": \"chunked\",\n \"cache-control\": \"no-cache\",\n };\n\n const { readable, writable } = new TransformStream();\n const stream = new ResponseStream(writable, readable);\n\n (async () => {\n try {\n await cb(stream);\n } catch (e) {\n if (e === undefined) {\n // If reading is canceled without a reason value (e.g. by StreamingApi)\n // then the .pipeTo() promise will reject with undefined.\n // In this case, do nothing because the stream is already closed.\n } else if (e instanceof Error && onError) {\n await onError(e, stream);\n } else {\n console.error(e);\n }\n } finally {\n stream.close();\n }\n })();\n\n return new Response(stream.responseReadable, {\n status: 200,\n headers: mergeHeaders(defaultHeaders, headers),\n });\n };\n}\n\nexport class RequestOutputContext<\n const TOutputSchema extends StandardSchemaV1 | undefined = undefined,\n const TErrorCode extends string = string,\n> extends OutputContext<InferOrUnknown<TOutputSchema>, TErrorCode> {\n // eslint-disable-next-line no-unused-private-class-members\n #outputSchema?: TOutputSchema;\n\n constructor(outputSchema?: TOutputSchema) {\n super();\n this.#outputSchema = outputSchema;\n }\n}\n"],"mappings":"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"}
@@ -1,26 +0,0 @@
1
- import { n as HTTPMethod, t as FragnoRouteConfig } from "./api-BWN97TOr.js";
2
- import { StandardSchemaV1 } from "@standard-schema/spec";
3
-
4
- //#region src/api/route.d.ts
5
- type AnyFragnoRouteConfig = FragnoRouteConfig<HTTPMethod, string, any, any, any, any>;
6
- interface RouteFactoryContext<TConfig, TDeps, TServices> {
7
- config: TConfig;
8
- deps: TDeps;
9
- services: TServices;
10
- }
11
- type RouteFactory<TConfig, TDeps, TServices, TRoutes$1 extends readonly FragnoRouteConfig<HTTPMethod, string, StandardSchemaV1 | undefined, StandardSchemaV1 | undefined, string, string>[]> = (context: RouteFactoryContext<TConfig, TDeps, TServices>) => TRoutes$1;
12
- type AnyRouteOrFactory = AnyFragnoRouteConfig | RouteFactory<any, any, any, any>;
13
- type FlattenRouteFactories<T extends readonly AnyRouteOrFactory[]> = T extends readonly [infer First, ...infer Rest extends readonly AnyRouteOrFactory[]] ? First extends RouteFactory<any, any, any, infer TRoutes> ? [...TRoutes, ...FlattenRouteFactories<Rest>] : [First, ...FlattenRouteFactories<Rest>] : [];
14
- declare function resolveRouteFactories<TConfig, TDeps, TServices, const TRoutesOrFactories extends readonly AnyRouteOrFactory[]>(context: RouteFactoryContext<TConfig, TDeps, TServices>, routesOrFactories: TRoutesOrFactories): FlattenRouteFactories<TRoutesOrFactories>;
15
- declare function defineRoute<const TMethod extends HTTPMethod, const TPath extends string, const TOutputSchema extends StandardSchemaV1 | undefined, const TErrorCode extends string = string, const TQueryParameters extends string = string>(config: FragnoRouteConfig<TMethod, TPath, undefined, TOutputSchema, TErrorCode, TQueryParameters> & {
16
- inputSchema?: undefined;
17
- }): FragnoRouteConfig<TMethod, TPath, undefined, TOutputSchema, TErrorCode, TQueryParameters>;
18
- declare function defineRoute<const TMethod extends HTTPMethod, const TPath extends string, const TInputSchema extends StandardSchemaV1, const TOutputSchema extends StandardSchemaV1 | undefined, const TErrorCode extends string = string, const TQueryParameters extends string = string>(config: FragnoRouteConfig<TMethod, TPath, TInputSchema, TOutputSchema, TErrorCode, TQueryParameters> & {
19
- inputSchema: TInputSchema;
20
- }): FragnoRouteConfig<TMethod, TPath, TInputSchema, TOutputSchema, TErrorCode, TQueryParameters>;
21
- declare function defineRoutes<TConfig = {}, TDeps = {}, TServices = {}>(): {
22
- create: <const TRoutes$1 extends readonly FragnoRouteConfig<HTTPMethod, string, StandardSchemaV1 | undefined, StandardSchemaV1 | undefined, string, string>[]>(fn: (context: RouteFactoryContext<TConfig, TDeps, TServices>) => TRoutes$1) => RouteFactory<TConfig, TDeps, TServices, TRoutes$1>;
23
- };
24
- //#endregion
25
- export { RouteFactoryContext as a, resolveRouteFactories as c, RouteFactory as i, AnyRouteOrFactory as n, defineRoute as o, FlattenRouteFactories as r, defineRoutes as s, AnyFragnoRouteConfig as t };
26
- //# sourceMappingURL=route-Bl9Zr1Yv.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"route-Bl9Zr1Yv.d.ts","names":[],"sources":["../src/api/route.ts"],"sourcesContent":[],"mappings":";;;;KAIY,oBAAA,GAAuB,kBAAkB;UAEpC;EAFL,MAAA,EAGF,OAHE;EAEK,IAAA,EAET,KAFS;EACP,QAAA,EAEE,SAFF;;AAEE,KAGA,YAHA,CAAA,OAAA,EAAA,KAAA,EAAA,SAAA,EAAA,kBAAA,SAOe,iBAPf,CAQR,UARQ,EAAA,MAAA,EAUR,gBAVQ,GAAA,SAAA,EAWR,gBAXQ,GAAA,SAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,GAAA,CAAA,OAAA,EAeE,mBAfF,CAesB,OAftB,EAe+B,KAf/B,EAesC,SAftC,CAAA,EAAA,GAeqD,SAfrD;AAAS,KAkBT,iBAAA,GAAoB,oBAlBX,GAkBkC,YAlBlC,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,CAAA;AAGT,KAiBA,qBAjBY,CAAA,UAAA,SAiB6B,iBAjB7B,EAAA,CAAA,GAiBoD,CAjBpD,SAAA,SAAA,CAKpB,KAAA,MAAA,EAEA,GAAA,KAAA,cAAA,SAY6B,iBAZ7B,EAAA,CACA,GAcA,KAdA,SAcc,YAdd,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,KAAA,QAAA,CAAA,GAAA,CAAA,GAeM,OAfN,EAAA,GAekB,qBAflB,CAewC,IAfxC,CAAA,CAAA,GAAA,CAgBG,KAhBH,EAAA,GAgBa,qBAhBb,CAgBmC,IAhBnC,CAAA,CAAA,GAAA,EAAA;AAJuB,iBAwBX,qBAxBW,CAAA,OAAA,EAAA,KAAA,EAAA,SAAA,EAAA,iCAAA,SA4BiB,iBA5BjB,EAAA,CAAA,CAAA,OAAA,EA8BhB,mBA9BgB,CA8BI,OA9BJ,EA8Ba,KA9Bb,EA8BoB,SA9BpB,CAAA,EAAA,iBAAA,EA+BN,kBA/BM,CAAA,EAgCxB,qBAhCwB,CAgCF,kBAhCE,CAAA;AAQO,iBA8ClB,WA9CkB,CAAA,sBA+CV,UA/CU,EAAA,oBAAA,MAAA,EAAA,4BAiDJ,gBAjDI,GAAA,SAAA,EAAA,yBAAA,MAAA,GAAA,MAAA,EAAA,+BAAA,MAAA,GAAA,MAAA,CAAA,CAAA,MAAA,EAqDxB,iBArDwB,CAsD9B,OAtD8B,EAuD9B,KAvD8B,EAAA,SAAA,EAyD9B,aAzD8B,EA0D9B,UA1D8B,EA2D9B,gBA3D8B,CAAA,GAAA;EAAS,WAAA,CAAA,EAAA,SAAA;CAAO,CAAA,EA6D/C,iBA7D+C,CA6D7B,OA7D6B,EA6DpB,KA7DoB,EAAA,SAAA,EA6DF,aA7DE,EA6Da,UA7Db,EA6DyB,gBA7DzB,CAAA;AAApC,iBAgEE,WAhEF,CAAA,sBAiEU,UAjEV,EAAA,oBAAA,MAAA,EAAA,2BAmEe,gBAnEf,EAAA,4BAoEgB,gBApEhB,GAAA,SAAA,EAAA,yBAAA,MAAA,GAAA,MAAA,EAAA,+BAAA,MAAA,GAAA,MAAA,CAAA,CAAA,MAAA,EAwEJ,iBAxEI,CAyEV,OAzEU,EA0EV,KA1EU,EA2EV,YA3EU,EA4EV,aA5EU,EA6EV,UA7EU,EA8EV,gBA9EU,CAAA,GAAA;EAAmD,WAAA,EA+E5C,YA/E4C;CAAO,CAAA,EAgFrE,iBAhFqE,CAgFnD,OAhFmD,EAgF1C,KAhF0C,EAgFnC,YAhFmC,EAgFrB,aAhFqB,EAgFN,UAhFM,EAgFM,gBAhFN,CAAA;AAG5D,iBAoGI,YApGgB,CAAA,UAAA,CAAA,CAAA,EAAA,QAAuB,CAAA,CAAA,EAAA,YAAY,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA;EAEvD,MAAA,EAAA,CAAA,wBAAqB,SAqGI,iBArGJ,CAsGzB,UAtGyB,EAAA,MAAA,EAwGzB,gBAxGyB,GAAA,SAAA,EAyGzB,gBAzGyB,GAAA,SAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,CAAA,EAAA,EAAA,CAAA,OAAA,EA8Gb,mBA9Ga,CA8GO,OA9GP,EA8GgB,KA9GhB,EA8GuB,SA9GvB,CAAA,EAAA,GA8GsC,SA9GtC,EAAA,GA+G1B,YA/G0B,CA+Gb,OA/Ga,EA+GJ,KA/GI,EA+GG,SA/GH,EA+Gc,SA/Gd,CAAA;CAAoB"}
@@ -1,21 +0,0 @@
1
- //#region src/api/route.ts
2
- function resolveRouteFactories(context, routesOrFactories) {
3
- const routes = [];
4
- for (const item of routesOrFactories) if (typeof item === "function") {
5
- const factoryRoutes = item(context);
6
- routes.push(...factoryRoutes);
7
- } else routes.push(item);
8
- return routes;
9
- }
10
- function defineRoute(config) {
11
- return config;
12
- }
13
- function defineRoutes() {
14
- return { create: (fn) => {
15
- return fn;
16
- } };
17
- }
18
-
19
- //#endregion
20
- export { defineRoutes as n, resolveRouteFactories as r, defineRoute as t };
21
- //# sourceMappingURL=route-C5Uryylh.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"route-C5Uryylh.js","names":["routes: any[]"],"sources":["../src/api/route.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { FragnoRouteConfig, HTTPMethod } from \"./api\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyFragnoRouteConfig = FragnoRouteConfig<HTTPMethod, string, any, any, any, any>;\n\nexport interface RouteFactoryContext<TConfig, TDeps, TServices> {\n config: TConfig;\n deps: TDeps;\n services: TServices;\n}\n\nexport type RouteFactory<\n TConfig,\n TDeps,\n TServices,\n TRoutes extends readonly FragnoRouteConfig<\n HTTPMethod,\n string,\n StandardSchemaV1 | undefined,\n StandardSchemaV1 | undefined,\n string,\n string\n >[],\n> = (context: RouteFactoryContext<TConfig, TDeps, TServices>) => TRoutes;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyRouteOrFactory = AnyFragnoRouteConfig | RouteFactory<any, any, any, any>;\n\nexport type FlattenRouteFactories<T extends readonly AnyRouteOrFactory[]> = T extends readonly [\n infer First,\n ...infer Rest extends readonly AnyRouteOrFactory[],\n]\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n First extends RouteFactory<any, any, any, infer TRoutes>\n ? [...TRoutes, ...FlattenRouteFactories<Rest>]\n : [First, ...FlattenRouteFactories<Rest>]\n : [];\n\n// Helper to resolve route factories into routes\nexport function resolveRouteFactories<\n TConfig,\n TDeps,\n TServices,\n const TRoutesOrFactories extends readonly AnyRouteOrFactory[],\n>(\n context: RouteFactoryContext<TConfig, TDeps, TServices>,\n routesOrFactories: TRoutesOrFactories,\n): FlattenRouteFactories<TRoutesOrFactories> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const routes: any[] = [];\n\n for (const item of routesOrFactories) {\n if (typeof item === \"function\") {\n // It's a route factory\n const factoryRoutes = item(context);\n routes.push(...factoryRoutes);\n } else {\n // It's a direct route\n routes.push(item);\n }\n }\n\n return routes as FlattenRouteFactories<TRoutesOrFactories>;\n}\n\n// TODO(Wilco): Do these overloads actually do anything?\n// TODO(Wilco): ValidPath<T> should be added back in here.\n\n// Overload for routes without inputSchema\nexport function defineRoute<\n const TMethod extends HTTPMethod,\n const TPath extends string,\n const TOutputSchema extends StandardSchemaV1 | undefined,\n const TErrorCode extends string = string,\n const TQueryParameters extends string = string,\n>(\n config: FragnoRouteConfig<\n TMethod,\n TPath,\n undefined,\n TOutputSchema,\n TErrorCode,\n TQueryParameters\n > & { inputSchema?: undefined },\n): FragnoRouteConfig<TMethod, TPath, undefined, TOutputSchema, TErrorCode, TQueryParameters>;\n\n// Overload for routes with inputSchema\nexport function defineRoute<\n const TMethod extends HTTPMethod,\n const TPath extends string,\n const TInputSchema extends StandardSchemaV1,\n const TOutputSchema extends StandardSchemaV1 | undefined,\n const TErrorCode extends string = string,\n const TQueryParameters extends string = string,\n>(\n config: FragnoRouteConfig<\n TMethod,\n TPath,\n TInputSchema,\n TOutputSchema,\n TErrorCode,\n TQueryParameters\n > & { inputSchema: TInputSchema },\n): FragnoRouteConfig<TMethod, TPath, TInputSchema, TOutputSchema, TErrorCode, TQueryParameters>;\n\n// implementation\nexport function defineRoute<\n const TMethod extends HTTPMethod,\n const TPath extends string,\n const TInputSchema extends StandardSchemaV1 | undefined,\n const TOutputSchema extends StandardSchemaV1 | undefined,\n const TErrorCode extends string = string,\n const TQueryParameters extends string = string,\n>(\n config: FragnoRouteConfig<\n TMethod,\n TPath,\n TInputSchema,\n TOutputSchema,\n TErrorCode,\n TQueryParameters\n >,\n): FragnoRouteConfig<TMethod, TPath, TInputSchema, TOutputSchema, TErrorCode, TQueryParameters> {\n return config;\n}\n\nexport function defineRoutes<TConfig = {}, TDeps = {}, TServices = {}>() {\n return {\n create: <\n const TRoutes extends readonly FragnoRouteConfig<\n HTTPMethod,\n string,\n StandardSchemaV1 | undefined,\n StandardSchemaV1 | undefined,\n string,\n string\n >[],\n >(\n fn: (context: RouteFactoryContext<TConfig, TDeps, TServices>) => TRoutes,\n ): RouteFactory<TConfig, TDeps, TServices, TRoutes> => {\n return fn;\n },\n };\n}\n"],"mappings":";AAwCA,SAAgB,sBAMd,SACA,mBAC2C;CAE3C,MAAMA,SAAgB,EAAE;AAExB,MAAK,MAAM,QAAQ,kBACjB,KAAI,OAAO,SAAS,YAAY;EAE9B,MAAM,gBAAgB,KAAK,QAAQ;AACnC,SAAO,KAAK,GAAG,cAAc;OAG7B,QAAO,KAAK,KAAK;AAIrB,QAAO;;AA4CT,SAAgB,YAQd,QAQ8F;AAC9F,QAAO;;AAGT,SAAgB,eAAyD;AACvE,QAAO,EACL,SAUE,OACqD;AACrD,SAAO;IAEV"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ssr-BByDVfFD.js","names":["stores: FetcherStore[]","clientInitialData: Map<string, unknown> | undefined","stores"],"sources":["../src/util/ssr.ts"],"sourcesContent":["import { allTasks } from \"nanostores\";\nimport type { FetcherStore } from \"@nanostores/query\";\n\nlet stores: FetcherStore[] = [];\n\nexport const SSR_ENABLED = false;\n\nexport function getStores() {\n return stores;\n}\n\nexport function addStore(store: FetcherStore) {\n stores.push(store);\n}\n\nexport function cleanStores() {\n stores = [];\n}\n\n// Client side\ndeclare global {\n interface Window {\n __FRAGNO_INITIAL_DATA__?: [string, unknown][];\n }\n}\n\nlet clientInitialData: Map<string, unknown> | undefined;\n\nexport function hydrateFromWindow() {\n if (typeof window !== \"undefined\" && window.__FRAGNO_INITIAL_DATA__) {\n clientInitialData = new Map(window.__FRAGNO_INITIAL_DATA__);\n delete window.__FRAGNO_INITIAL_DATA__;\n console.warn(\"hydrateFromWindow\", {\n clientInitialData: Array.from(clientInitialData.entries()),\n });\n }\n}\n\nexport function getInitialData(key: string): unknown | undefined {\n if (clientInitialData?.has(key)) {\n const data = clientInitialData.get(key);\n clientInitialData.delete(key);\n return data;\n }\n return undefined;\n}\n\nfunction listenToStores(): void {\n for (const store of getStores()) {\n // By calling `listen`, we trigger the fetcher function of the store.\n // This will start the data fetching process on the server.\n // We don't need to do anything with the return value of `listen`, as we\n // are only interested in starting the data fetching.\n store.listen(() => {});\n }\n}\n\n// Server side\nexport async function getFinalStoreValues(): Promise<Map<string, unknown>> {\n listenToStores();\n await allTasks();\n\n const stores = getStores();\n const storesInitialValue = new Map<string, unknown>();\n\n for (const store of stores) {\n const value = store.get();\n if (!value || !store.key || value.loading) {\n continue;\n }\n storesInitialValue.set(store.key, value.data);\n }\n\n return storesInitialValue;\n}\n"],"mappings":";;;AAGA,IAAIA,SAAyB,EAAE;AAE/B,MAAa,cAAc;AAE3B,SAAgB,YAAY;AAC1B,QAAO;;AAGT,SAAgB,SAAS,OAAqB;AAC5C,QAAO,KAAK,MAAM;;AAGpB,SAAgB,cAAc;AAC5B,UAAS,EAAE;;AAUb,IAAIC;AAEJ,SAAgB,oBAAoB;AAClC,KAAI,OAAO,WAAW,eAAe,OAAO,yBAAyB;AACnE,sBAAoB,IAAI,IAAI,OAAO,wBAAwB;AAC3D,SAAO,OAAO;AACd,UAAQ,KAAK,qBAAqB,EAChC,mBAAmB,MAAM,KAAK,kBAAkB,SAAS,CAAC,EAC3D,CAAC;;;AAIN,SAAgB,eAAe,KAAkC;AAC/D,KAAI,mBAAmB,IAAI,IAAI,EAAE;EAC/B,MAAM,OAAO,kBAAkB,IAAI,IAAI;AACvC,oBAAkB,OAAO,IAAI;AAC7B,SAAO;;;AAKX,SAAS,iBAAuB;AAC9B,MAAK,MAAM,SAAS,WAAW,CAK7B,OAAM,aAAa,GAAG;;AAK1B,eAAsB,sBAAqD;AACzE,iBAAgB;AAChB,OAAM,UAAU;CAEhB,MAAMC,WAAS,WAAW;CAC1B,MAAM,qCAAqB,IAAI,KAAsB;AAErD,MAAK,MAAM,SAASA,UAAQ;EAC1B,MAAM,QAAQ,MAAM,KAAK;AACzB,MAAI,CAAC,SAAS,CAAC,MAAM,OAAO,MAAM,QAChC;AAEF,qBAAmB,IAAI,MAAM,KAAK,MAAM,KAAK;;AAG/C,QAAO"}
@@ -1,80 +0,0 @@
1
- import type { FragnoPublicConfig } from "./fragment-instantiation";
2
-
3
- export interface FragmentDefinition<
4
- TConfig,
5
- TDeps = {},
6
- TServices extends Record<string, unknown> = {},
7
- TAdditionalContext extends Record<string, unknown> = {},
8
- > {
9
- name: string;
10
- dependencies?: (config: TConfig, options: FragnoPublicConfig) => TDeps;
11
- services?: (config: TConfig, options: FragnoPublicConfig, deps: TDeps) => TServices;
12
- additionalContext?: TAdditionalContext;
13
- }
14
-
15
- export class FragmentBuilder<
16
- const TConfig,
17
- const TDeps = {},
18
- const TServices extends Record<string, unknown> = {},
19
- const TAdditionalContext extends Record<string, unknown> = {},
20
- > {
21
- #definition: FragmentDefinition<TConfig, TDeps, TServices, TAdditionalContext>;
22
-
23
- constructor(definition: FragmentDefinition<TConfig, TDeps, TServices, TAdditionalContext>) {
24
- this.#definition = definition;
25
- }
26
-
27
- get definition() {
28
- return this.#definition;
29
- }
30
-
31
- get $requiredOptions(): FragnoPublicConfig {
32
- throw new Error("Type only method. Do not call.");
33
- }
34
-
35
- withDependencies<TNewDeps>(
36
- fn: (
37
- context: { config: TConfig; fragnoConfig: FragnoPublicConfig } & TAdditionalContext,
38
- ) => TNewDeps,
39
- ): FragmentBuilder<TConfig, TNewDeps, {}, TAdditionalContext> {
40
- return new FragmentBuilder<TConfig, TNewDeps, {}, TAdditionalContext>({
41
- name: this.#definition.name,
42
- dependencies: (config: TConfig, options: FragnoPublicConfig) => {
43
- return fn({ config, fragnoConfig: options } as {
44
- config: TConfig;
45
- fragnoConfig: FragnoPublicConfig;
46
- } & TAdditionalContext);
47
- },
48
- services: undefined,
49
- additionalContext: this.#definition.additionalContext,
50
- });
51
- }
52
-
53
- withServices<TNewServices extends Record<string, unknown>>(
54
- fn: (
55
- context: {
56
- config: TConfig;
57
- fragnoConfig: FragnoPublicConfig;
58
- deps: TDeps;
59
- } & TAdditionalContext,
60
- ) => TNewServices,
61
- ): FragmentBuilder<TConfig, TDeps, TNewServices, TAdditionalContext> {
62
- return new FragmentBuilder<TConfig, TDeps, TNewServices, TAdditionalContext>({
63
- name: this.#definition.name,
64
- dependencies: this.#definition.dependencies,
65
- services: (config: TConfig, options: FragnoPublicConfig, deps: TDeps) => {
66
- return fn({ config, fragnoConfig: options, deps } as {
67
- config: TConfig;
68
- fragnoConfig: FragnoPublicConfig;
69
- deps: TDeps;
70
- } & TAdditionalContext);
71
- },
72
- additionalContext: this.#definition.additionalContext,
73
- });
74
- }
75
- }
76
- export function defineFragment<TConfig = {}>(name: string): FragmentBuilder<TConfig, {}, {}, {}> {
77
- return new FragmentBuilder({
78
- name,
79
- });
80
- }