effect-start 0.31.0 → 0.33.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 (227) hide show
  1. package/dist/Entity.d.ts +3 -0
  2. package/dist/Entity.d.ts.map +1 -1
  3. package/dist/Entity.js +20 -5
  4. package/dist/Entity.js.map +1 -1
  5. package/dist/Fetch.d.ts +1 -1
  6. package/dist/Fetch.d.ts.map +1 -1
  7. package/dist/Fetch.js +1 -1
  8. package/dist/Fetch.js.map +1 -1
  9. package/dist/Html.d.ts +5 -11
  10. package/dist/Html.d.ts.map +1 -1
  11. package/dist/Html.js +21 -1
  12. package/dist/Html.js.map +1 -1
  13. package/dist/KeyValueStore.d.ts +37 -0
  14. package/dist/KeyValueStore.d.ts.map +1 -0
  15. package/dist/KeyValueStore.js +99 -0
  16. package/dist/KeyValueStore.js.map +1 -0
  17. package/dist/Password.d.ts +26 -0
  18. package/dist/Password.d.ts.map +1 -0
  19. package/dist/Password.js +83 -0
  20. package/dist/Password.js.map +1 -0
  21. package/dist/Route.d.ts +2 -2
  22. package/dist/Route.d.ts.map +1 -1
  23. package/dist/Route.js +1 -1
  24. package/dist/Route.js.map +1 -1
  25. package/dist/RouteBody.d.ts +2 -2
  26. package/dist/RouteBody.d.ts.map +1 -1
  27. package/dist/RouteMount.d.ts +0 -20
  28. package/dist/RouteMount.d.ts.map +1 -1
  29. package/dist/RouteMount.js +0 -15
  30. package/dist/RouteMount.js.map +1 -1
  31. package/dist/RouteSse.d.ts +1 -2
  32. package/dist/RouteSse.d.ts.map +1 -1
  33. package/dist/RouteSse.js +2 -2
  34. package/dist/RouteSse.js.map +1 -1
  35. package/dist/Start.d.ts.map +1 -1
  36. package/dist/Start.js +4 -0
  37. package/dist/Start.js.map +1 -1
  38. package/dist/_StreamExtra.d.ts.map +1 -1
  39. package/dist/_StreamExtra.js +0 -1
  40. package/dist/_StreamExtra.js.map +1 -1
  41. package/dist/bun/BunRoute.d.ts.map +1 -1
  42. package/dist/bun/BunRoute.js +90 -78
  43. package/dist/bun/BunRoute.js.map +1 -1
  44. package/dist/bun/BunServer.d.ts +1 -1
  45. package/dist/bun/BunServer.d.ts.map +1 -1
  46. package/dist/bun/BunServer.js +8 -1
  47. package/dist/bun/BunServer.js.map +1 -1
  48. package/dist/datastar/attributes/computed.js +3 -3
  49. package/dist/datastar/attributes/computed.js.map +1 -1
  50. package/dist/datastar/attributes/on.js +11 -36
  51. package/dist/datastar/attributes/on.js.map +1 -1
  52. package/dist/datastar/engine.d.ts +9 -7
  53. package/dist/datastar/engine.d.ts.map +1 -1
  54. package/dist/datastar/engine.js +45 -29
  55. package/dist/datastar/engine.js.map +1 -1
  56. package/dist/datastar/jsx.d.ts +70 -0
  57. package/dist/datastar/jsx.d.ts.map +1 -0
  58. package/dist/datastar/jsx.js +2 -0
  59. package/dist/datastar/jsx.js.map +1 -0
  60. package/dist/datastar/window.d.ts +8 -0
  61. package/dist/datastar/window.d.ts.map +1 -0
  62. package/dist/datastar/window.js +4 -0
  63. package/dist/datastar/window.js.map +1 -0
  64. package/dist/experimental/KeyValueStore.d.ts +37 -0
  65. package/dist/experimental/KeyValueStore.d.ts.map +1 -0
  66. package/dist/experimental/KeyValueStore.js +99 -0
  67. package/dist/experimental/KeyValueStore.js.map +1 -0
  68. package/dist/experimental/SqlCache.d.ts +19 -0
  69. package/dist/experimental/SqlCache.d.ts.map +1 -0
  70. package/dist/experimental/SqlCache.js +35 -0
  71. package/dist/experimental/SqlCache.js.map +1 -0
  72. package/dist/experimental/SqlIntrospect.d.ts +92 -0
  73. package/dist/experimental/SqlIntrospect.d.ts.map +1 -0
  74. package/dist/experimental/SqlIntrospect.js +478 -0
  75. package/dist/experimental/SqlIntrospect.js.map +1 -0
  76. package/dist/index.d.ts +1 -0
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +1 -0
  79. package/dist/index.js.map +1 -1
  80. package/dist/jsx-runtime.d.ts +2 -2
  81. package/dist/jsx-runtime.d.ts.map +1 -1
  82. package/dist/jsx.d.ts +3216 -0
  83. package/dist/jsx.d.ts.map +1 -0
  84. package/dist/jsx.js +6 -0
  85. package/dist/jsx.js.map +1 -0
  86. package/dist/lint/plugin.d.ts +4 -3
  87. package/dist/lint/plugin.js +56 -17
  88. package/dist/lint/plugin.js.map +1 -1
  89. package/dist/sql/index.d.ts +0 -2
  90. package/dist/sql/index.d.ts.map +1 -1
  91. package/dist/sql/index.js +0 -2
  92. package/dist/sql/index.js.map +1 -1
  93. package/dist/studio/Studio.d.ts +1 -1
  94. package/dist/studio/Studio.d.ts.map +1 -1
  95. package/dist/studio/Studio.js +5 -4
  96. package/dist/studio/Studio.js.map +1 -1
  97. package/dist/studio/StudioErrors.d.ts.map +1 -1
  98. package/dist/studio/StudioErrors.js +2 -2
  99. package/dist/studio/StudioErrors.js.map +1 -1
  100. package/dist/studio/StudioLogger.js +3 -4
  101. package/dist/studio/StudioLogger.js.map +1 -1
  102. package/dist/studio/StudioStore.d.ts +26 -17
  103. package/dist/studio/StudioStore.d.ts.map +1 -1
  104. package/dist/studio/StudioStore.js +61 -44
  105. package/dist/studio/StudioStore.js.map +1 -1
  106. package/dist/studio/StudioTracer.d.ts.map +1 -1
  107. package/dist/studio/StudioTracer.js +10 -4
  108. package/dist/studio/StudioTracer.js.map +1 -1
  109. package/dist/studio/_Pretty.d.ts +4 -0
  110. package/dist/studio/_Pretty.d.ts.map +1 -0
  111. package/dist/studio/_Pretty.js +56 -0
  112. package/dist/studio/_Pretty.js.map +1 -0
  113. package/dist/studio/routes/errors/route.d.ts +1 -1
  114. package/dist/studio/routes/errors/route.d.ts.map +1 -1
  115. package/dist/studio/routes/errors/route.js +2 -2
  116. package/dist/studio/routes/errors/route.js.map +1 -1
  117. package/dist/studio/routes/fiberDetail.d.ts +1 -1
  118. package/dist/studio/routes/fiberDetail.js +4 -4
  119. package/dist/studio/routes/fiberDetail.js.map +1 -1
  120. package/dist/studio/routes/fibers/route.d.ts +2 -2
  121. package/dist/studio/routes/fibers/route.js +4 -4
  122. package/dist/studio/routes/fibers/route.js.map +1 -1
  123. package/dist/studio/routes/layout.d.ts +2 -0
  124. package/dist/studio/routes/layout.d.ts.map +1 -1
  125. package/dist/studio/routes/layout.html +3 -12
  126. package/dist/studio/routes/layout.js +6 -1
  127. package/dist/studio/routes/layout.js.map +1 -1
  128. package/dist/studio/routes/logs/route.d.ts +1 -1
  129. package/dist/studio/routes/logs/route.d.ts.map +1 -1
  130. package/dist/studio/routes/logs/route.js +2 -2
  131. package/dist/studio/routes/logs/route.js.map +1 -1
  132. package/dist/studio/routes/traceDetail.d.ts +1 -1
  133. package/dist/studio/routes/traceDetail.js +1 -1
  134. package/dist/studio/routes/traceDetail.js.map +1 -1
  135. package/dist/studio/routes/traces/route.d.ts +2 -2
  136. package/dist/studio/routes/traces/route.d.ts.map +1 -1
  137. package/dist/studio/routes/traces/route.js +9 -6
  138. package/dist/studio/routes/traces/route.js.map +1 -1
  139. package/dist/studio/routes/tree.d.ts +30 -8
  140. package/dist/studio/routes/tree.d.ts.map +1 -1
  141. package/dist/studio/ui/Errors.d.ts +1 -1
  142. package/dist/studio/ui/Errors.js +1 -1
  143. package/dist/studio/ui/Errors.js.map +1 -1
  144. package/dist/studio/ui/Fibers.d.ts +2 -2
  145. package/dist/studio/ui/Fibers.d.ts.map +1 -1
  146. package/dist/studio/ui/Fibers.js +4 -3
  147. package/dist/studio/ui/Fibers.js.map +1 -1
  148. package/dist/studio/ui/Logs.d.ts +1 -1
  149. package/dist/studio/ui/Logs.d.ts.map +1 -1
  150. package/dist/studio/ui/Logs.js +2 -1
  151. package/dist/studio/ui/Logs.js.map +1 -1
  152. package/dist/studio/ui/Metrics.d.ts +1 -1
  153. package/dist/studio/ui/Routes.d.ts +1 -1
  154. package/dist/studio/ui/Routes.d.ts.map +1 -1
  155. package/dist/studio/ui/Services.d.ts +1 -1
  156. package/dist/studio/ui/Services.d.ts.map +1 -1
  157. package/dist/studio/ui/Shell.d.ts +2 -2
  158. package/dist/studio/ui/Shell.d.ts.map +1 -1
  159. package/dist/studio/ui/System.d.ts +1 -1
  160. package/dist/studio/ui/Traces.d.ts +4 -3
  161. package/dist/studio/ui/Traces.d.ts.map +1 -1
  162. package/dist/studio/ui/Traces.js +36 -21
  163. package/dist/studio/ui/Traces.js.map +1 -1
  164. package/dist/studio/ui/_PrettyValue.d.ts +10 -0
  165. package/dist/studio/ui/_PrettyValue.d.ts.map +1 -0
  166. package/dist/studio/ui/_PrettyValue.js +27 -0
  167. package/dist/studio/ui/_PrettyValue.js.map +1 -0
  168. package/dist/tailwind/TailwindPlugin.d.ts.map +1 -1
  169. package/dist/tailwind/TailwindPlugin.js +89 -62
  170. package/dist/tailwind/TailwindPlugin.js.map +1 -1
  171. package/dist/ts/import-plugin.cjs +388 -0
  172. package/dist/ts/import-plugin.cjs.map +1 -0
  173. package/dist/ts/import-plugin.d.cts +87 -0
  174. package/dist/ts/import-plugin.d.cts.map +1 -0
  175. package/dist/ts/import-plugin.d.ts +87 -0
  176. package/dist/ts/import-plugin.d.ts.map +1 -0
  177. package/dist/ts/import-plugin.js +390 -0
  178. package/dist/ts/import-plugin.js.map +1 -0
  179. package/package.json +109 -8
  180. package/src/Entity.ts +32 -7
  181. package/src/Fetch.ts +2 -2
  182. package/src/Html.ts +28 -21
  183. package/src/Password.ts +130 -0
  184. package/src/Route.ts +2 -2
  185. package/src/RouteBody.ts +2 -2
  186. package/src/RouteMount.ts +0 -54
  187. package/src/RouteSse.ts +4 -4
  188. package/src/Start.ts +4 -0
  189. package/src/_StreamExtra.ts +0 -1
  190. package/src/bun/BunRoute.ts +117 -95
  191. package/src/bun/BunServer.ts +9 -2
  192. package/src/datastar/README.md +24 -8
  193. package/src/datastar/attributes/computed.ts +3 -3
  194. package/src/datastar/attributes/on.ts +11 -37
  195. package/src/datastar/engine.ts +61 -37
  196. package/src/datastar/jsx.d.ts +12 -26
  197. package/src/datastar/types.d.ts +8 -0
  198. package/src/experimental/KeyValueStore.ts +161 -0
  199. package/src/{sql → experimental}/SqlCache.ts +1 -1
  200. package/src/{sql → experimental}/SqlIntrospect.ts +1 -1
  201. package/src/index.ts +1 -0
  202. package/src/jsx-runtime.ts +1 -1
  203. package/src/jsx.d.ts +17 -2
  204. package/src/lint/plugin.js +54 -19
  205. package/src/sql/index.ts +0 -2
  206. package/src/studio/Studio.ts +6 -5
  207. package/src/studio/StudioErrors.ts +2 -3
  208. package/src/studio/StudioLogger.ts +4 -4
  209. package/src/studio/StudioStore.ts +177 -115
  210. package/src/studio/StudioTracer.ts +11 -5
  211. package/src/studio/_Pretty.ts +59 -0
  212. package/src/studio/routes/errors/route.tsx +3 -1
  213. package/src/studio/routes/fiberDetail.tsx +4 -4
  214. package/src/studio/routes/fibers/route.tsx +4 -4
  215. package/src/studio/routes/layout.html +3 -12
  216. package/src/studio/routes/layout.tsx +9 -1
  217. package/src/studio/routes/logs/route.tsx +3 -1
  218. package/src/studio/routes/traceDetail.tsx +1 -1
  219. package/src/studio/routes/traces/route.tsx +13 -6
  220. package/src/studio/ui/Errors.tsx +1 -1
  221. package/src/studio/ui/Fibers.tsx +14 -10
  222. package/src/studio/ui/Logs.tsx +15 -10
  223. package/src/studio/ui/Traces.tsx +80 -80
  224. package/src/studio/ui/_PrettyValue.tsx +34 -0
  225. package/src/tailwind/TailwindPlugin.ts +102 -75
  226. package/src/RouteTrie.ts +0 -205
  227. package/src/experimental/index.ts +0 -1
@@ -191,109 +191,136 @@ const CSS_IMPORT_REGEX = /@import\s+(?:url\()?["']?([^"')]+)["']?\)?\s*[^;]*;/
191
191
  const HTML_COMMENT_REGEX = /<!--[\s\S]*?-->/g
192
192
  const TEMPLATE_EXPRESSION_REGEX = /\$\{[^}]*\}/g
193
193
  const TAILWIND_CLASS_REGEX = /^[a-zA-Z0-9_:-]+(\[[^\]]*\])?$/
194
- const CLASS_NAME_PATTERNS = [
195
- // HTML class attributes with double quotes: <div class="bg-blue-500 text-white">
196
- '<[^>]*?\\sclass\\s*=\\s*"([^"]+)"',
194
+ const CLASS_ATTRIBUTE_PATTERNS = [
195
+ '\\sclass\\s*=\\s*"([^"]+)"',
196
+ "\\sclass\\s*=\\s*'([^']+)'",
197
+ '\\sclassName\\s*=\\s*"([^"]+)"',
198
+ "\\sclassName\\s*=\\s*'([^']+)'",
199
+ '\\sclassName\\s*=\\s*\\{\\s*"([^"]+)"\\s*\\}',
200
+ "\\sclassName\\s*=\\s*\\{\\s*'([^']+)'\\s*\\}",
201
+ "\\sclassName\\s*=\\s*\\{\\s*`([^`]*)`\\s*\\}",
202
+ "\\sclass\\s*=\\s*\\{\\s*`([^`]*)`\\s*\\}",
203
+ "\\sdata-class:([a-zA-Z0-9_:\\-]+(?:\\[[^\\]]*\\])?)\\s*=",
204
+ ]
197
205
 
198
- // HTML class attributes with single quotes: <div class='bg-blue-500 text-white'>
199
- "<[^>]*?\\sclass\\s*=\\s*'([^']+)'",
206
+ const CLASS_ATTRIBUTE_REGEX = new RegExp(
207
+ CLASS_ATTRIBUTE_PATTERNS.map((pattern) => `(?:${pattern})`).join("|"),
208
+ "g",
209
+ )
200
210
 
201
- // JSX className attributes with double quotes: <div className="bg-blue-500 text-white">
202
- '<[^>]*?\\sclassName\\s*=\\s*"([^"]+)"',
211
+ function hasCssImport(css: string, specifier?: string): boolean {
212
+ const [, importPath] = css.match(CSS_IMPORT_REGEX) ?? []
203
213
 
204
- // JSX className attributes with single quotes: <div className='bg-blue-500 text-white'>
205
- "<[^>]*?\\sclassName\\s*=\\s*'([^']+)'",
214
+ if (!importPath) return false
206
215
 
207
- // JSX className with braces and double quotes: <div className={"bg-blue-500 text-white"}>
208
- '<[^>]*?\\sclassName\\s*=\\s*\\{\\s*"([^"]+)"\\s*\\}',
216
+ return specifier === undefined || importPath.includes(specifier)
217
+ }
209
218
 
210
- // JSX className with braces and single quotes: <div className={'bg-blue-500 text-white'}>
211
- "<[^>]*?\\sclassName\\s*=\\s*\\{\\s*'([^']+)'\\s*\\}",
219
+ export function extractClassNames(source: string): Set<string> {
220
+ const candidates = new Set<string>()
221
+ const sourceWithoutComments = source.replace(HTML_COMMENT_REGEX, "")
212
222
 
213
- // JSX className with template literals: <div className={`bg-blue-500 ${variable}`}>
214
- "<[^>]*?\\sclassName\\s*=\\s*\\{\\s*`([^`]*)`\\s*\\}",
223
+ for (const tag of extractTagLikeSegments(sourceWithoutComments)) {
224
+ for (const match of tag.matchAll(CLASS_ATTRIBUTE_REGEX)) {
225
+ let classString = ""
226
+ for (let i = 1; i < match.length; i++) {
227
+ if (match[i] !== undefined) {
228
+ classString = match[i]
229
+ break
230
+ }
231
+ }
215
232
 
216
- // HTML class with template literals: <div class={`bg-blue-500 ${variable}`}>
217
- "<[^>]*?\\sclass\\s*=\\s*\\{\\s*`([^`]*)`\\s*\\}",
233
+ if (!classString) {
234
+ continue
235
+ }
218
236
 
219
- // HTML class at start of tag with double quotes: <div class="bg-blue-500">
220
- '<\\w+\\s+class\\s*=\\s*"([^"]+)"',
237
+ if (classString.includes("${")) {
238
+ const staticParts = classString.split(TEMPLATE_EXPRESSION_REGEX)
239
+
240
+ for (const part of staticParts) {
241
+ const names = part
242
+ .trim()
243
+ .split(/\s+/)
244
+ .filter((name) => {
245
+ if (name.length === 0) return false
246
+ if (name.endsWith("-") || name.startsWith("-")) return false
247
+ return TAILWIND_CLASS_REGEX.test(name)
248
+ })
249
+ names.forEach((name) => candidates.add(name))
250
+ }
251
+ } else {
252
+ const names = classString.split(/\s+/).filter((name) => name.length > 0)
253
+ names.forEach((name) => candidates.add(name))
254
+ }
255
+ }
221
256
 
222
- // HTML class at start of tag with single quotes: <div class='bg-blue-500'>
223
- "<\\w+\\s+class\\s*=\\s*'([^']+)'",
257
+ }
224
258
 
225
- // JSX className at start of tag with double quotes: <div className="bg-blue-500">
226
- '<\\w+\\s+className\\s*=\\s*"([^"]+)"',
259
+ return candidates
260
+ }
227
261
 
228
- // JSX className at start of tag with single quotes: <div className='bg-blue-500'>
229
- "<\\w+\\s+className\\s*=\\s*'([^']+)'",
262
+ function extractTagLikeSegments(source: string): Array<string> {
263
+ const tags: Array<string> = []
230
264
 
231
- // JSX className at start with braces and double quotes: <div className={"bg-blue-500"}>
232
- '<\\w+\\s+className\\s*=\\s*\\{\\s*"([^"]+)"\\s*\\}',
265
+ for (let i = 0; i < source.length; i++) {
266
+ if (source[i] !== "<") {
267
+ continue
268
+ }
233
269
 
234
- // JSX className at start with braces and single quotes: <div className={'bg-blue-500'}>
235
- "<\\w+\\s+className\\s*=\\s*\\{\\s*'([^']+)'\\s*\\}",
270
+ const next = source[i + 1]
271
+ if (!next || next === "/" || next === "!" || /\s/.test(next)) {
272
+ continue
273
+ }
236
274
 
237
- // JSX className at start with template literals: <div className={`bg-blue-500 ${variable}`}>
238
- "<\\w+\\s+className\\s*=\\s*\\{\\s*`([^`]*)`\\s*\\}",
275
+ let quote: '"' | "'" | "`" | null = null
276
+ let escaped = false
277
+ let braceDepth = 0
239
278
 
240
- // HTML class at start with template literals: <div class={`bg-blue-500 ${variable}`}>
241
- "<\\w+\\s+class\\s*=\\s*\\{\\s*`([^`]*)`\\s*\\}",
242
- ]
279
+ for (let j = i + 1; j < source.length; j++) {
280
+ const char = source[j]
243
281
 
244
- const CLASS_NAME_REGEX = new RegExp(
245
- CLASS_NAME_PATTERNS.map((pattern) => `(?:${pattern})`).join("|"),
246
- "g",
247
- )
282
+ if (quote !== null) {
283
+ if (escaped) {
284
+ escaped = false
285
+ continue
286
+ }
248
287
 
249
- function hasCssImport(css: string, specifier?: string): boolean {
250
- const [, importPath] = css.match(CSS_IMPORT_REGEX) ?? []
288
+ if (char === "\\") {
289
+ escaped = true
290
+ continue
291
+ }
251
292
 
252
- if (!importPath) return false
293
+ if (char === quote) {
294
+ quote = null
295
+ }
253
296
 
254
- return specifier === undefined || importPath.includes(specifier)
255
- }
297
+ continue
298
+ }
256
299
 
257
- export function extractClassNames(source: string): Set<string> {
258
- const candidates = new Set<string>()
259
- const sourceWithoutComments = source.replace(HTML_COMMENT_REGEX, "")
300
+ if (char === '"' || char === "'" || char === "`") {
301
+ quote = char
302
+ continue
303
+ }
260
304
 
261
- for (const match of sourceWithoutComments.matchAll(CLASS_NAME_REGEX)) {
262
- // Find the first non-undefined capture group (skip match[0] which is full match)
263
- let classString = ""
264
- for (let i = 1; i < match.length; i++) {
265
- if (match[i] !== undefined) {
266
- classString = match[i]
267
- break
305
+ if (char === "{") {
306
+ braceDepth++
307
+ continue
268
308
  }
269
- }
270
309
 
271
- if (!classString) {
272
- continue
273
- }
310
+ if (char === "}" && braceDepth > 0) {
311
+ braceDepth--
312
+ continue
313
+ }
274
314
 
275
- if (classString.includes("${")) {
276
- const staticParts = classString.split(TEMPLATE_EXPRESSION_REGEX)
277
-
278
- for (const part of staticParts) {
279
- const names = part
280
- .trim()
281
- .split(/\s+/)
282
- .filter((name) => {
283
- if (name.length === 0) return false
284
- if (name.endsWith("-") || name.startsWith("-")) return false
285
- return TAILWIND_CLASS_REGEX.test(name)
286
- })
287
- names.forEach((name) => candidates.add(name))
315
+ if (char === ">" && braceDepth === 0) {
316
+ tags.push(source.slice(i, j + 1))
317
+ i = j
318
+ break
288
319
  }
289
- } else {
290
- // Simple case: regular class string without expressions
291
- const names = classString.split(/\s+/).filter((name) => name.length > 0)
292
- names.forEach((name) => candidates.add(name))
293
320
  }
294
321
  }
295
322
 
296
- return candidates
323
+ return tags
297
324
  }
298
325
 
299
326
  async function scanFiles(dir: string): Promise<Set<string>> {
package/src/RouteTrie.ts DELETED
@@ -1,205 +0,0 @@
1
- import * as PathPattern from "./_PathPattern.ts"
2
- import * as Route from "./Route.ts"
3
-
4
- export interface Node {
5
- children: Record<string, Node>
6
- paramChild: Node | null
7
- paramName: string | null
8
- requiredWildcardChild: Node | null
9
- requiredWildcardName: string | null
10
- optionalWildcardChild: Node | null
11
- optionalWildcardName: string | null
12
- routes: Array<Route.Route.Route>
13
- }
14
-
15
- export interface RouteTrie {
16
- readonly methods: Record<string, Node>
17
- }
18
-
19
- export interface LookupResult {
20
- route: Route.Route.Route
21
- params: Record<string, string>
22
- }
23
-
24
- function createNode(): Node {
25
- return {
26
- children: {},
27
- paramChild: null,
28
- paramName: null,
29
- requiredWildcardChild: null,
30
- requiredWildcardName: null,
31
- optionalWildcardChild: null,
32
- optionalWildcardName: null,
33
- routes: [],
34
- }
35
- }
36
-
37
- function insertRoute(node: Node, segments: Array<string>, route: Route.Route.Route): void {
38
- if (segments.length === 0) {
39
- node.routes.push(route)
40
- return
41
- }
42
-
43
- const segment = segments[0]
44
- const rest = segments.slice(1)
45
-
46
- if (segment.startsWith(":")) {
47
- const name = segment.slice(1)
48
-
49
- if (name.endsWith("+")) {
50
- if (!node.requiredWildcardChild) {
51
- node.requiredWildcardChild = createNode()
52
- }
53
- node.requiredWildcardChild.requiredWildcardName = name.slice(0, -1)
54
- node.requiredWildcardChild.routes.push(route)
55
- } else if (name.endsWith("*")) {
56
- if (!node.optionalWildcardChild) {
57
- node.optionalWildcardChild = createNode()
58
- }
59
- node.optionalWildcardChild.optionalWildcardName = name.slice(0, -1)
60
- node.optionalWildcardChild.routes.push(route)
61
- } else if (name.endsWith("?")) {
62
- if (!node.paramChild) {
63
- node.paramChild = createNode()
64
- }
65
- node.paramChild.paramName = name.slice(0, -1)
66
- insertRoute(node.paramChild, rest, route)
67
- insertRoute(node, rest, route)
68
- } else {
69
- if (!node.paramChild) {
70
- node.paramChild = createNode()
71
- }
72
- node.paramChild.paramName = name
73
- insertRoute(node.paramChild, rest, route)
74
- }
75
- } else {
76
- if (!node.children[segment]) {
77
- node.children[segment] = createNode()
78
- }
79
- insertRoute(node.children[segment], rest, route)
80
- }
81
- }
82
-
83
- interface CollectedRoute {
84
- route: Route.Route.Route
85
- method: string
86
- path: string
87
- }
88
-
89
- function collectRoutes(
90
- items: Route.Route.Tuple,
91
- parentPath: string,
92
- parentMethod: string,
93
- ): Array<CollectedRoute> {
94
- const results: Array<CollectedRoute> = []
95
-
96
- for (const item of items) {
97
- const desc = Route.descriptor(item) as { path?: string; method?: string }
98
- const currentPath = typeof desc?.path === "string" ? parentPath + desc.path : parentPath
99
- const currentMethod = desc?.method ?? parentMethod
100
-
101
- if (Route.isRoute(item)) {
102
- if (currentPath !== "") {
103
- results.push({
104
- route: item,
105
- method: currentMethod,
106
- path: currentPath,
107
- })
108
- }
109
- } else {
110
- const nestedItems = Route.items(item)
111
- results.push(...collectRoutes(nestedItems, currentPath, currentMethod))
112
- }
113
- }
114
-
115
- return results
116
- }
117
-
118
- export function make(set: Route.RouteSet.Any): RouteTrie {
119
- const methods: Record<string, Node> = {}
120
- const collected = collectRoutes(Route.items(set), "", "*")
121
-
122
- for (const { route, method, path } of collected) {
123
- if (!methods[method]) {
124
- methods[method] = createNode()
125
- }
126
- const result = PathPattern.validate(path)
127
- if (!result.ok) {
128
- throw new Error(result.error)
129
- }
130
- insertRoute(methods[method], result.segments, route)
131
- }
132
-
133
- return { methods }
134
- }
135
-
136
- function lookupNode(
137
- node: Node,
138
- segments: Array<string>,
139
- params: Record<string, string>,
140
- ): Array<LookupResult> {
141
- const results: Array<LookupResult> = []
142
-
143
- if (segments.length === 0) {
144
- for (const route of node.routes) {
145
- results.push({ route, params })
146
- }
147
- if (node.optionalWildcardChild && node.optionalWildcardChild.optionalWildcardName) {
148
- for (const route of node.optionalWildcardChild.routes) {
149
- results.push({ route, params })
150
- }
151
- }
152
- return results
153
- }
154
-
155
- const segment = segments[0]
156
- const rest = segments.slice(1)
157
-
158
- if (node.children[segment]) {
159
- results.push(...lookupNode(node.children[segment], rest, params))
160
- }
161
-
162
- if (node.paramChild && node.paramChild.paramName) {
163
- const newParams = { ...params, [node.paramChild.paramName]: segment }
164
- results.push(...lookupNode(node.paramChild, rest, newParams))
165
- }
166
-
167
- if (node.requiredWildcardChild && node.requiredWildcardChild.requiredWildcardName) {
168
- const wildcardValue = segments.join("/")
169
- const newParams = {
170
- ...params,
171
- [node.requiredWildcardChild.requiredWildcardName]: wildcardValue,
172
- }
173
- for (const route of node.requiredWildcardChild.routes) {
174
- results.push({ route, params: newParams })
175
- }
176
- }
177
-
178
- if (node.optionalWildcardChild && node.optionalWildcardChild.optionalWildcardName) {
179
- const wildcardValue = segments.join("/")
180
- const newParams = {
181
- ...params,
182
- [node.optionalWildcardChild.optionalWildcardName]: wildcardValue,
183
- }
184
- for (const route of node.optionalWildcardChild.routes) {
185
- results.push({ route, params: newParams })
186
- }
187
- }
188
-
189
- return results
190
- }
191
-
192
- export function lookup(trie: RouteTrie, method: string, path: string): Array<LookupResult> {
193
- const segments = path.split("/").filter(Boolean)
194
- const results: Array<LookupResult> = []
195
-
196
- if (trie.methods[method]) {
197
- results.push(...lookupNode(trie.methods[method], segments, {}))
198
- }
199
-
200
- if (method !== "*" && trie.methods["*"]) {
201
- results.push(...lookupNode(trie.methods["*"], segments, {}))
202
- }
203
-
204
- return results
205
- }
@@ -1 +0,0 @@
1
- export * as EncryptedCookies from "./EncryptedCookies.ts"