effect-start 0.18.0 → 0.20.0

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 (203) hide show
  1. package/README.md +3 -3
  2. package/dist/Development.d.ts +8 -3
  3. package/dist/Development.js +14 -7
  4. package/dist/Effectify.d.ts +212 -0
  5. package/dist/Effectify.js +19 -0
  6. package/dist/FilePathPattern.d.ts +29 -0
  7. package/dist/FilePathPattern.js +86 -0
  8. package/dist/FileRouter.d.ts +39 -41
  9. package/dist/FileRouter.js +104 -158
  10. package/dist/FileRouterCodegen.d.ts +7 -8
  11. package/dist/FileRouterCodegen.js +97 -66
  12. package/dist/PlatformError.d.ts +46 -0
  13. package/dist/PlatformError.js +43 -0
  14. package/dist/PlatformRuntime.d.ts +27 -0
  15. package/dist/PlatformRuntime.js +51 -0
  16. package/dist/Route.d.ts +6 -2
  17. package/dist/Route.js +22 -0
  18. package/dist/RouteBody.d.ts +1 -1
  19. package/dist/RouteHttp.d.ts +1 -1
  20. package/dist/RouteHttp.js +12 -19
  21. package/dist/RouteMount.d.ts +2 -1
  22. package/dist/Start.d.ts +33 -6
  23. package/dist/Start.js +31 -13
  24. package/dist/Unique.d.ts +50 -0
  25. package/dist/Unique.js +187 -0
  26. package/dist/bun/BunHttpServer.js +5 -6
  27. package/dist/bun/BunPlatformHttpServer.d.ts +10 -0
  28. package/dist/bun/BunPlatformHttpServer.js +53 -0
  29. package/dist/bun/BunRoute.d.ts +4 -6
  30. package/dist/bun/BunRoute.js +10 -18
  31. package/dist/bun/BunRuntime.d.ts +2 -1
  32. package/dist/bun/BunRuntime.js +10 -5
  33. package/dist/bun/BunServer.d.ts +33 -0
  34. package/dist/bun/BunServer.js +133 -0
  35. package/dist/bun/BunServerRequest.d.ts +60 -0
  36. package/dist/bun/BunServerRequest.js +252 -0
  37. package/dist/bun/index.d.ts +1 -1
  38. package/dist/bun/index.js +1 -1
  39. package/dist/datastar/actions/fetch.d.ts +30 -0
  40. package/dist/datastar/actions/fetch.js +411 -0
  41. package/dist/datastar/actions/peek.d.ts +1 -0
  42. package/dist/datastar/actions/peek.js +14 -0
  43. package/dist/datastar/actions/setAll.d.ts +1 -0
  44. package/dist/datastar/actions/setAll.js +13 -0
  45. package/dist/datastar/actions/toggleAll.d.ts +1 -0
  46. package/dist/datastar/actions/toggleAll.js +13 -0
  47. package/dist/datastar/attributes/attr.d.ts +1 -0
  48. package/dist/datastar/attributes/attr.js +49 -0
  49. package/dist/datastar/attributes/bind.d.ts +1 -0
  50. package/dist/datastar/attributes/bind.js +183 -0
  51. package/dist/datastar/attributes/class.d.ts +1 -0
  52. package/dist/datastar/attributes/class.js +50 -0
  53. package/dist/datastar/attributes/computed.d.ts +1 -0
  54. package/dist/datastar/attributes/computed.js +27 -0
  55. package/dist/datastar/attributes/effect.d.ts +1 -0
  56. package/dist/datastar/attributes/effect.js +10 -0
  57. package/dist/datastar/attributes/indicator.d.ts +1 -0
  58. package/dist/datastar/attributes/indicator.js +32 -0
  59. package/dist/datastar/attributes/init.d.ts +1 -0
  60. package/dist/datastar/attributes/init.js +27 -0
  61. package/dist/datastar/attributes/jsonSignals.d.ts +1 -0
  62. package/dist/datastar/attributes/jsonSignals.js +31 -0
  63. package/dist/datastar/attributes/on.d.ts +1 -0
  64. package/dist/datastar/attributes/on.js +59 -0
  65. package/dist/datastar/attributes/onIntersect.d.ts +1 -0
  66. package/dist/datastar/attributes/onIntersect.js +54 -0
  67. package/dist/datastar/attributes/onInterval.d.ts +1 -0
  68. package/dist/datastar/attributes/onInterval.js +31 -0
  69. package/dist/datastar/attributes/onSignalPatch.d.ts +1 -0
  70. package/dist/datastar/attributes/onSignalPatch.js +44 -0
  71. package/dist/datastar/attributes/ref.d.ts +1 -0
  72. package/dist/datastar/attributes/ref.js +11 -0
  73. package/dist/datastar/attributes/show.d.ts +1 -0
  74. package/dist/datastar/attributes/show.js +32 -0
  75. package/dist/datastar/attributes/signals.d.ts +1 -0
  76. package/dist/datastar/attributes/signals.js +18 -0
  77. package/dist/datastar/attributes/style.d.ts +1 -0
  78. package/dist/datastar/attributes/style.js +56 -0
  79. package/dist/datastar/attributes/text.d.ts +1 -0
  80. package/dist/datastar/attributes/text.js +27 -0
  81. package/dist/datastar/engine.d.ts +156 -0
  82. package/dist/datastar/engine.js +971 -0
  83. package/dist/datastar/index.d.ts +24 -0
  84. package/dist/datastar/index.js +24 -0
  85. package/dist/datastar/load.d.ts +24 -0
  86. package/dist/datastar/load.js +24 -0
  87. package/dist/datastar/utils.d.ts +51 -0
  88. package/dist/datastar/utils.js +205 -0
  89. package/dist/datastar/watchers/patchElements.d.ts +1 -0
  90. package/dist/datastar/watchers/patchElements.js +420 -0
  91. package/dist/datastar/watchers/patchSignals.d.ts +1 -0
  92. package/dist/datastar/watchers/patchSignals.js +15 -0
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.js +1 -0
  95. package/dist/node/Effectify.d.ts +209 -0
  96. package/dist/node/Effectify.js +19 -0
  97. package/dist/node/FileSystem.d.ts +3 -5
  98. package/dist/node/FileSystem.js +42 -62
  99. package/dist/node/NodeFileSystem.d.ts +7 -0
  100. package/dist/node/NodeFileSystem.js +420 -0
  101. package/dist/node/NodeUtils.d.ts +2 -0
  102. package/dist/node/NodeUtils.js +20 -0
  103. package/dist/node/PlatformError.d.ts +46 -0
  104. package/dist/node/PlatformError.js +43 -0
  105. package/dist/testing/TestLogger.js +1 -1
  106. package/dist/x/tailwind/plugin.js +1 -1
  107. package/package.json +18 -7
  108. package/src/Development.ts +36 -40
  109. package/src/Effectify.ts +269 -0
  110. package/src/FilePathPattern.ts +115 -0
  111. package/src/FileRouter.ts +178 -255
  112. package/src/FileRouterCodegen.ts +135 -92
  113. package/src/PlatformError.ts +117 -0
  114. package/src/PlatformRuntime.ts +108 -0
  115. package/src/Route.ts +31 -2
  116. package/src/RouteBody.ts +1 -1
  117. package/src/RouteHttp.ts +15 -29
  118. package/src/RouteMount.ts +1 -1
  119. package/src/Start.ts +61 -27
  120. package/src/Unique.ts +232 -0
  121. package/src/bun/BunPlatformHttpServer.ts +88 -0
  122. package/src/bun/BunRoute.ts +14 -24
  123. package/src/bun/BunRuntime.ts +21 -5
  124. package/src/bun/BunServer.ts +228 -0
  125. package/src/bun/index.ts +1 -1
  126. package/src/datastar/README.md +18 -0
  127. package/src/datastar/actions/fetch.ts +609 -0
  128. package/src/datastar/actions/peek.ts +17 -0
  129. package/src/datastar/actions/setAll.ts +20 -0
  130. package/src/datastar/actions/toggleAll.ts +20 -0
  131. package/src/datastar/attributes/attr.ts +50 -0
  132. package/src/datastar/attributes/bind.ts +220 -0
  133. package/src/datastar/attributes/class.ts +57 -0
  134. package/src/datastar/attributes/computed.ts +33 -0
  135. package/src/datastar/attributes/effect.ts +11 -0
  136. package/src/datastar/attributes/indicator.ts +39 -0
  137. package/src/datastar/attributes/init.ts +35 -0
  138. package/src/datastar/attributes/jsonSignals.ts +38 -0
  139. package/src/datastar/attributes/on.ts +71 -0
  140. package/src/datastar/attributes/onIntersect.ts +65 -0
  141. package/src/datastar/attributes/onInterval.ts +39 -0
  142. package/src/datastar/attributes/onSignalPatch.ts +63 -0
  143. package/src/datastar/attributes/ref.ts +12 -0
  144. package/src/datastar/attributes/show.ts +33 -0
  145. package/src/datastar/attributes/signals.ts +22 -0
  146. package/src/datastar/attributes/style.ts +63 -0
  147. package/src/datastar/attributes/text.ts +30 -0
  148. package/src/datastar/engine.ts +1341 -0
  149. package/src/datastar/index.ts +25 -0
  150. package/src/datastar/utils.ts +286 -0
  151. package/src/datastar/watchers/patchElements.ts +554 -0
  152. package/src/datastar/watchers/patchSignals.ts +15 -0
  153. package/src/index.ts +1 -0
  154. package/src/node/{FileSystem.ts → NodeFileSystem.ts} +59 -97
  155. package/src/node/{Utils.ts → NodeUtils.ts} +2 -0
  156. package/src/testing/TestLogger.ts +1 -1
  157. package/src/x/tailwind/plugin.ts +1 -1
  158. package/dist/Random.d.ts +0 -5
  159. package/dist/Random.js +0 -49
  160. package/src/Commander.test.ts +0 -1639
  161. package/src/ContentNegotiation.test.ts +0 -603
  162. package/src/Development.test.ts +0 -119
  163. package/src/Entity.test.ts +0 -592
  164. package/src/FileRouterCodegen.todo.ts +0 -1133
  165. package/src/FileRouterPattern.test.ts +0 -147
  166. package/src/FileRouterPattern.ts +0 -59
  167. package/src/FileRouter_files.test.ts +0 -64
  168. package/src/FileRouter_path.test.ts +0 -145
  169. package/src/FileRouter_tree.test.ts +0 -132
  170. package/src/Http.test.ts +0 -319
  171. package/src/HttpAppExtra.test.ts +0 -103
  172. package/src/HttpUtils.test.ts +0 -85
  173. package/src/PathPattern.test.ts +0 -648
  174. package/src/Random.ts +0 -59
  175. package/src/RouteBody.test.ts +0 -232
  176. package/src/RouteHook.test.ts +0 -40
  177. package/src/RouteHttp.test.ts +0 -2909
  178. package/src/RouteMount.test.ts +0 -481
  179. package/src/RouteSchema.test.ts +0 -427
  180. package/src/RouteSse.test.ts +0 -249
  181. package/src/RouteTree.test.ts +0 -494
  182. package/src/RouteTrie.test.ts +0 -322
  183. package/src/RouterPattern.test.ts +0 -676
  184. package/src/RouterPattern.ts +0 -416
  185. package/src/StartApp.ts +0 -47
  186. package/src/Values.test.ts +0 -263
  187. package/src/bun/BunBundle.test.ts +0 -268
  188. package/src/bun/BunBundle_imports.test.ts +0 -48
  189. package/src/bun/BunHttpServer.test.ts +0 -251
  190. package/src/bun/BunHttpServer.ts +0 -306
  191. package/src/bun/BunImportTrackerPlugin.test.ts +0 -77
  192. package/src/bun/BunRoute.test.ts +0 -162
  193. package/src/bundler/BundleHttp.test.ts +0 -132
  194. package/src/effect/HttpRouter.test.ts +0 -548
  195. package/src/experimental/EncryptedCookies.test.ts +0 -488
  196. package/src/hyper/HyperHtml.test.ts +0 -209
  197. package/src/hyper/HyperRoute.test.tsx +0 -197
  198. package/src/middlewares/BasicAuthMiddleware.test.ts +0 -84
  199. package/src/testing/TestHttpClient.test.ts +0 -83
  200. package/src/testing/TestLogger.test.ts +0 -51
  201. package/src/x/datastar/Datastar.test.ts +0 -266
  202. package/src/x/tailwind/TailwindPlugin.test.ts +0 -333
  203. /package/src/bun/{BunHttpServer_web.ts → BunServerRequest.ts} +0 -0
@@ -1,416 +0,0 @@
1
- export type RouterPattern = `/${string}`
2
-
3
- export type ParamDelimiter = "_" | "-" | "." | "," | ";" | "!" | "@" | "~"
4
- export type ParamPrefix = `${string}${ParamDelimiter}` | ""
5
- export type ParamSuffix = `${ParamDelimiter}${string}` | ""
6
-
7
- export type LiteralSegment<
8
- Value extends string = string,
9
- > = {
10
- _tag: "LiteralSegment"
11
- value: Value
12
- }
13
-
14
- export type ParamSegment<
15
- Name extends string = string,
16
- Optional extends boolean = boolean,
17
- Prefix extends ParamPrefix = "",
18
- Suffix extends ParamSuffix = "",
19
- > = {
20
- _tag: "ParamSegment"
21
- name: Name
22
- optional?: Optional
23
- prefix?: Prefix
24
- suffix?: Suffix
25
- }
26
-
27
- export type RestSegment<
28
- Name extends string = string,
29
- Optional extends boolean = boolean,
30
- > = {
31
- _tag: "RestSegment"
32
- name: Name
33
- optional?: Optional
34
- }
35
-
36
- export type Segment =
37
- | LiteralSegment
38
- | ParamSegment<
39
- string,
40
- boolean,
41
- ParamPrefix,
42
- ParamSuffix
43
- >
44
- | RestSegment
45
-
46
- /**
47
- * Parses a route path string into a tuple of Segment types at compile time.
48
- *
49
- * @example
50
- * ```ts
51
- * type Usage = Segments<"/users/[id]/posts/[...rest]">
52
- * type Expected = [
53
- * LiteralSegment<"users">,
54
- * ParamSegment<"id", false>,
55
- * LiteralSegment<"posts">,
56
- * RestSegment<"rest", false>
57
- * ]
58
- * ```
59
- *
60
- * Supports:
61
- * - Literals: `users` → `LiteralSegment<"users">`
62
- * - Params: `[id]` → `ParamSegment<"id", false>`
63
- * - Params (optional): `[[id]]` → `ParamSegment<"id", true>`
64
- * - Rest: `[...rest]` → `RestSegment<"rest", false>`
65
- * - Rest (optional): `[[...rest]]` → `RestSegment<"rest", true>`
66
- * - {Pre,Suf}fixed params: `prefix_[id]_suffix` → `ParamSegment<"id", false, "prefix_", "_suffix">`
67
- * - Malformed segments: `pk_[id]foo` → `undefined` (suffix must start with delimiter)
68
- *
69
- * @limit Paths with more than 48 segments in TypeScript 5.9.3 will fail with
70
- * `TS2589: Type instantiation is excessively deep and possibly infinite`.
71
- */
72
- export type Segments<Path extends string> = Path extends `/${infer PathRest}`
73
- ? Segments<PathRest>
74
- : Path extends `${infer Head}/${infer Tail}`
75
- ? [ExtractSegment<Head>, ...Segments<Tail>]
76
- : Path extends "" ? []
77
- : [ExtractSegment<Path>]
78
-
79
- const PARAM_PATTERN =
80
- /^(?<prefix>.*[^a-zA-Z0-9])?\[(?<name>[^\]]+)\](?<suffix>[^a-zA-Z0-9].*)?$/
81
-
82
- export function parseSegment(segment: string): Segment | null {
83
- if (
84
- segment.startsWith("[[...")
85
- && segment.endsWith("]]")
86
- ) {
87
- return {
88
- _tag: "RestSegment",
89
- name: segment.slice(5, -2),
90
- optional: true,
91
- }
92
- }
93
-
94
- if (
95
- segment.startsWith("[...")
96
- && segment.endsWith("]")
97
- ) {
98
- return {
99
- _tag: "RestSegment",
100
- name: segment.slice(4, -1),
101
- }
102
- }
103
-
104
- if (
105
- segment.startsWith("[[")
106
- && segment.endsWith("]]")
107
- ) {
108
- return {
109
- _tag: "ParamSegment",
110
- name: segment.slice(2, -2),
111
- optional: true,
112
- }
113
- }
114
-
115
- const match = segment.match(PARAM_PATTERN)
116
- if (match?.groups) {
117
- const { prefix, name, suffix } = match.groups
118
-
119
- return {
120
- _tag: "ParamSegment",
121
- name,
122
- prefix: (prefix as ParamPrefix) || undefined,
123
- suffix: (suffix as ParamSuffix) || undefined,
124
- }
125
- }
126
-
127
- if (/^[\p{L}\p{N}._~-]+$/u.test(segment)) {
128
- return { _tag: "LiteralSegment", value: segment }
129
- }
130
-
131
- return null
132
- }
133
-
134
- export function parse(pattern: string): Segment[] {
135
- const segments = pattern.split("/").filter(Boolean).map(parseSegment)
136
-
137
- if (segments.some((seg) => seg === null)) {
138
- throw new Error(
139
- `Invalid path segment in "${pattern}": contains invalid characters or format`,
140
- )
141
- }
142
-
143
- return segments as Segment[]
144
- }
145
-
146
- export function formatSegment(seg: Segment): string {
147
- switch (seg._tag) {
148
- case "LiteralSegment":
149
- return seg.value
150
- case "ParamSegment": {
151
- const param = seg.optional ? `[[${seg.name}]]` : `[${seg.name}]`
152
- return (seg.prefix ?? "") + param + (seg.suffix ?? "")
153
- }
154
- case "RestSegment":
155
- return seg.optional ? `[[...${seg.name}]]` : `[...${seg.name}]`
156
- }
157
- }
158
-
159
- export function format(segments: Segment[]): `/${string}` {
160
- const joined = segments.map(formatSegment).join("/")
161
- return (joined ? `/${joined}` : "/") as `/${string}`
162
- }
163
-
164
- function buildPaths(
165
- segments: Segment[],
166
- mapper: (seg: Segment) => string,
167
- restWildcard: string,
168
- ): string[] {
169
- const optionalRestIndex = segments.findIndex(
170
- (s) => s._tag === "RestSegment" && s.optional,
171
- )
172
-
173
- if (optionalRestIndex !== -1) {
174
- const before = segments.slice(0, optionalRestIndex)
175
- const beforeJoined = before.map(mapper).join("/")
176
- const basePath = beforeJoined ? "/" + beforeJoined : "/"
177
- const withWildcard = basePath === "/"
178
- ? restWildcard
179
- : basePath + restWildcard
180
- return [basePath, withWildcard]
181
- }
182
-
183
- const joined = segments.map(mapper).join("/")
184
- return [joined ? "/" + joined : "/"]
185
- }
186
-
187
- function colonParamSegment(segment: Segment): string {
188
- switch (segment._tag) {
189
- case "LiteralSegment":
190
- return segment.value
191
- case "ParamSegment": {
192
- const param = `:${segment.name}${segment.optional ? "?" : ""}`
193
- return (segment.prefix ?? "") + param + (segment.suffix ?? "")
194
- }
195
- case "RestSegment":
196
- return "*"
197
- }
198
- }
199
-
200
- /**
201
- * Converts to colon-style path pattern (used by Hono, Bun, itty-router).
202
- *
203
- * - `[param]` → `:param`
204
- * - `[[param]]` → `:param?`
205
- * - `[...param]` → `*`
206
- * - `[[...param]]` → `/`, `/*`
207
- * - `pk_[id]` → `pk_:id`
208
- */
209
- export function toColon(path: RouterPattern): string[] {
210
- return buildPaths(parse(path), colonParamSegment, "/*")
211
- }
212
-
213
- export const toHono = toColon
214
-
215
- /**
216
- * Converts to Express path pattern.
217
- *
218
- * - `[param]` → `:param`
219
- * - `[[param]]` → `{/:param}`
220
- * - `[...param]` → `/*param`
221
- * - `[[...param]]` → `/`, `/*param`
222
- * - `pk_[id]` → `pk_:id`
223
- */
224
- export function toExpress(path: RouterPattern): string[] {
225
- const segments = parse(path)
226
- const optionalRestIndex = segments.findIndex(
227
- (s) => s._tag === "RestSegment" && s.optional,
228
- )
229
-
230
- const mapper = (segment: Segment): string => {
231
- switch (segment._tag) {
232
- case "LiteralSegment":
233
- return segment.value
234
- case "ParamSegment": {
235
- const param = `:${segment.name}`
236
- return (segment.prefix ?? "") + param + (segment.suffix ?? "")
237
- }
238
- case "RestSegment":
239
- return `*${segment.name}`
240
- }
241
- }
242
-
243
- if (optionalRestIndex !== -1) {
244
- const before = segments.slice(0, optionalRestIndex)
245
- const rest = segments[optionalRestIndex]
246
- if (rest._tag !== "RestSegment") throw new Error("unreachable")
247
- const restName = rest.name
248
- const beforeJoined = before.map(mapper).join("/")
249
- const basePath = beforeJoined ? "/" + beforeJoined : "/"
250
- const withWildcard = basePath === "/"
251
- ? `/*${restName}`
252
- : basePath + `/*${restName}`
253
- return [basePath, withWildcard]
254
- }
255
-
256
- let result = ""
257
- for (let i = 0; i < segments.length; i++) {
258
- const segment = segments[i]
259
- const isFirst = i === 0
260
- switch (segment._tag) {
261
- case "LiteralSegment":
262
- result += "/" + segment.value
263
- break
264
- case "ParamSegment":
265
- if (segment.optional && !segment.prefix && !segment.suffix) {
266
- result += isFirst
267
- ? "/{/:$name}".replace("$name", segment.name)
268
- : `{/:${segment.name}}`
269
- } else {
270
- const param = `:${segment.name}`
271
- result += "/"
272
- + (segment.prefix ?? "")
273
- + param
274
- + (segment.suffix ?? "")
275
- }
276
- break
277
- case "RestSegment":
278
- result += `/*${segment.name}`
279
- break
280
- }
281
- }
282
- return [result || "/"]
283
- }
284
-
285
- /**
286
- * Converts to Effect HttpRouter/find-my-way path pattern.
287
- *
288
- * - `[param]` → `:param`
289
- * - `[[param]]` → `:param?` (must be final segment)
290
- * - `[...param]` → `*`
291
- * - `[[...param]]` → `/`, `/*`
292
- * - `pk_[id]` → `pk_:id`
293
- */
294
- export function toEffect(path: RouterPattern): string[] {
295
- return buildPaths(parse(path), colonParamSegment, "/*")
296
- }
297
-
298
- /**
299
- * Converts to URLPattern path pattern.
300
- *
301
- * - `[param]` → `:param`
302
- * - `[[param]]` → `:param?`
303
- * - `[...param]` → `:param+`
304
- * - `[[...param]]` → `:param*`
305
- * - `pk_[id]` → `pk_:id`
306
- */
307
- export function toURLPattern(path: RouterPattern): string[] {
308
- const segments = parse(path)
309
- const joined = segments
310
- .map((segment) => {
311
- switch (segment._tag) {
312
- case "LiteralSegment":
313
- return segment.value
314
- case "ParamSegment": {
315
- const param = `:${segment.name}${segment.optional ? "?" : ""}`
316
- return (segment.prefix ?? "") + param + (segment.suffix ?? "")
317
- }
318
- case "RestSegment":
319
- return `:${segment.name}${segment.optional ? "*" : "+"}`
320
- }
321
- })
322
- .join("/")
323
- return [joined ? "/" + joined : "/"]
324
- }
325
-
326
- /**
327
- * Converts to Remix path pattern.
328
- *
329
- * - `[param]` → `$param`
330
- * - `[[param]]` → `($param)`
331
- * - `[...param]` → `$`
332
- * - `[[...param]]` → `/`, `$`
333
- * - `pk_[id]` → (not supported, emits `pk_$id`)
334
- */
335
- export function toRemix(path: RouterPattern): string[] {
336
- const segments = parse(path)
337
- const optionalRestIndex = segments.findIndex(
338
- (s) => s._tag === "RestSegment" && s.optional,
339
- )
340
-
341
- const mapper = (segment: Segment): string => {
342
- switch (segment._tag) {
343
- case "LiteralSegment":
344
- return segment.value
345
- case "ParamSegment": {
346
- const param = segment.optional
347
- ? `($${segment.name})`
348
- : `$${segment.name}`
349
- return (segment.prefix ?? "") + param + (segment.suffix ?? "")
350
- }
351
- case "RestSegment":
352
- return "$"
353
- }
354
- }
355
-
356
- if (optionalRestIndex !== -1) {
357
- const before = segments.slice(0, optionalRestIndex)
358
- const beforeJoined = before.map(mapper).join("/")
359
- const basePath = beforeJoined ? "/" + beforeJoined : "/"
360
- const withWildcard = basePath === "/" ? "$" : basePath + "/$"
361
- return [basePath, withWildcard]
362
- }
363
-
364
- const joined = segments.map(mapper).join("/")
365
- return [joined ? "/" + joined : "/"]
366
- }
367
-
368
- /**
369
- * Converts to Bun.serve path pattern.
370
- *
371
- * Since Bun doesn't support optional params (`:param?`), optional segments
372
- * are expanded into multiple routes recursively.
373
- *
374
- * - `[param]` → `:param`
375
- * - `[[param]]` → `/`, `/:param` (two routes)
376
- * - `[...param]` → `*`
377
- * - `[[...param]]` → `/`, `/*` (two routes)
378
- * - `pk_[id]` → `pk_:id`
379
- */
380
- export function toBun(path: RouterPattern): string[] {
381
- const segments = parse(path)
382
-
383
- const optionalIndex = segments.findIndex(
384
- (s) =>
385
- (s._tag === "ParamSegment" || s._tag === "RestSegment") && s.optional,
386
- )
387
-
388
- if (optionalIndex === -1) {
389
- return buildPaths(segments, colonParamSegment, "/*")
390
- }
391
-
392
- const before = segments.slice(0, optionalIndex)
393
- const optional = { ...segments[optionalIndex], optional: false }
394
- const after = segments.slice(optionalIndex + 1)
395
-
396
- return [
397
- ...toBun(format(before)),
398
- ...toBun(format([...before, optional, ...after])),
399
- ]
400
- }
401
-
402
- type ExtractSegment<S extends string> = S extends `[[...${infer Name}]]`
403
- ? RestSegment<Name, true>
404
- : S extends `[...${infer Name}]` ? RestSegment<Name, false>
405
- : S extends `[[${infer Name}]]` ? ParamSegment<Name, true, "", "">
406
- : S extends
407
- `${infer Pre
408
- extends `${string}${ParamDelimiter}`}[${infer Name}]${infer Suf}`
409
- ? Suf extends `${infer Delim extends ParamDelimiter}${infer SufRest}`
410
- ? ParamSegment<Name, false, Pre, `${Delim}${SufRest}`>
411
- : Suf extends "" ? ParamSegment<Name, false, Pre, "">
412
- : undefined
413
- : S extends `[${infer Name}]${infer Suf extends `${ParamDelimiter}${string}`}`
414
- ? ParamSegment<Name, false, "", Suf>
415
- : S extends `[${infer Name}]` ? ParamSegment<Name, false, "", "">
416
- : LiteralSegment<S>
package/src/StartApp.ts DELETED
@@ -1,47 +0,0 @@
1
- import * as HttpApp from "@effect/platform/HttpApp"
2
- import * as Context from "effect/Context"
3
- import * as Effect from "effect/Effect"
4
- import * as Function from "effect/Function"
5
- import * as Layer from "effect/Layer"
6
- import * as PubSub from "effect/PubSub"
7
- import * as Ref from "effect/Ref"
8
-
9
- type StartMiddleware = <E, R>(
10
- self: HttpApp.Default<E, R>,
11
- ) => HttpApp.Default<never, never>
12
-
13
- export class StartApp extends Context.Tag("effect-start/StartApp")<
14
- StartApp,
15
- {
16
- readonly env: "development" | "production" | string
17
- readonly addMiddleware: (
18
- middleware: StartMiddleware,
19
- ) => Effect.Effect<void>
20
- readonly middleware: Ref.Ref<StartMiddleware>
21
- readonly events: PubSub.PubSub<any>
22
- }
23
- >() {
24
- }
25
-
26
- export function layer(options?: {
27
- env?: string
28
- }) {
29
- return Layer.effect(
30
- StartApp,
31
- Effect.gen(function*() {
32
- const env = options?.env ?? process.env.NODE_ENV ?? "development"
33
- const middleware = yield* Ref.make(
34
- Function.identity as StartMiddleware,
35
- )
36
- const events = yield* PubSub.unbounded()
37
-
38
- return StartApp.of({
39
- env,
40
- middleware,
41
- addMiddleware: (f) =>
42
- Ref.update(middleware, (prev) => (app) => f(prev(app))),
43
- events,
44
- })
45
- }),
46
- )
47
- }