effect-start 0.34.0 → 0.35.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 (127) hide show
  1. package/README.md +303 -36
  2. package/dist/Fetch.d.ts +1 -1
  3. package/dist/FileRouter.d.ts +1 -1
  4. package/dist/FileRouterCodegen.d.ts.map +1 -1
  5. package/dist/FileRouterCodegen.js +8 -2
  6. package/dist/FileRouterCodegen.js.map +1 -1
  7. package/dist/Job.d.ts +94 -0
  8. package/dist/Job.d.ts.map +1 -0
  9. package/dist/Job.js +157 -0
  10. package/dist/Job.js.map +1 -0
  11. package/dist/Password.d.ts +1 -1
  12. package/dist/Route.d.ts +20 -15
  13. package/dist/Route.d.ts.map +1 -1
  14. package/dist/Route.js +12 -0
  15. package/dist/Route.js.map +1 -1
  16. package/dist/RouteBody.d.ts +7 -7
  17. package/dist/RouteBody.d.ts.map +1 -1
  18. package/dist/RouteBody.js.map +1 -1
  19. package/dist/RouteHook.d.ts +1 -1
  20. package/dist/RouteHook.d.ts.map +1 -1
  21. package/dist/RouteHook.js.map +1 -1
  22. package/dist/RouteHttp.d.ts.map +1 -1
  23. package/dist/RouteHttp.js +10 -4
  24. package/dist/RouteHttp.js.map +1 -1
  25. package/dist/RouteLink.d.ts +16 -0
  26. package/dist/RouteLink.d.ts.map +1 -0
  27. package/dist/RouteLink.js +23 -0
  28. package/dist/RouteLink.js.map +1 -0
  29. package/dist/RouteMount.d.ts +29 -32
  30. package/dist/RouteMount.d.ts.map +1 -1
  31. package/dist/RouteMount.js.map +1 -1
  32. package/dist/RouteSchema.d.ts +81 -28
  33. package/dist/RouteSchema.d.ts.map +1 -1
  34. package/dist/RouteSchema.js +56 -101
  35. package/dist/RouteSchema.js.map +1 -1
  36. package/dist/RouteSse.d.ts +1 -1
  37. package/dist/RouteSse.d.ts.map +1 -1
  38. package/dist/RouteSse.js.map +1 -1
  39. package/dist/Socket.d.ts +1 -1
  40. package/dist/Start.js +1 -1
  41. package/dist/Start.js.map +1 -1
  42. package/dist/StaticFiles.d.ts +4 -10
  43. package/dist/StaticFiles.d.ts.map +1 -1
  44. package/dist/StaticFiles.js +3 -10
  45. package/dist/StaticFiles.js.map +1 -1
  46. package/dist/System.d.ts +1 -1
  47. package/dist/_Docker.d.ts +1 -1
  48. package/dist/_HtmlScanner.d.ts +42 -0
  49. package/dist/_HtmlScanner.d.ts.map +1 -0
  50. package/dist/_HtmlScanner.js +385 -0
  51. package/dist/_HtmlScanner.js.map +1 -0
  52. package/dist/_RouteLink.d.ts +16 -0
  53. package/dist/_RouteLink.d.ts.map +1 -0
  54. package/dist/_RouteLink.js +22 -0
  55. package/dist/_RouteLink.js.map +1 -0
  56. package/dist/bun/BunRoute.d.ts +4 -6
  57. package/dist/bun/BunRoute.d.ts.map +1 -1
  58. package/dist/bun/BunRoute.js +1 -1
  59. package/dist/bun/BunRoute.js.map +1 -1
  60. package/dist/bundler/Bundle.d.ts +1 -1
  61. package/dist/bundler/BundleRoute.d.ts +5 -6
  62. package/dist/bundler/BundleRoute.d.ts.map +1 -1
  63. package/dist/bundler/BundleRoute.js +5 -11
  64. package/dist/bundler/BundleRoute.js.map +1 -1
  65. package/dist/datastar/watchers/patchElements.js +1 -1
  66. package/dist/datastar/watchers/patchElements.js.map +1 -1
  67. package/dist/experimental/CsrfProtection.d.ts +67 -0
  68. package/dist/experimental/CsrfProtection.d.ts.map +1 -0
  69. package/dist/experimental/CsrfProtection.js +100 -0
  70. package/dist/experimental/CsrfProtection.js.map +1 -0
  71. package/dist/experimental/EncryptedCookies.d.ts +1 -1
  72. package/dist/experimental/KeyValueStore.d.ts +1 -1
  73. package/dist/lint/plugin.js +4 -0
  74. package/dist/lint/plugin.js.map +1 -1
  75. package/dist/sql/SqlClient.d.ts +1 -1
  76. package/dist/studio/Studio.d.ts +1 -1
  77. package/dist/studio/Studio.d.ts.map +1 -1
  78. package/dist/studio/Studio.js +4 -10
  79. package/dist/studio/Studio.js.map +1 -1
  80. package/dist/studio/routes/errors/route.d.ts +3 -3
  81. package/dist/studio/routes/errors/route.d.ts.map +1 -1
  82. package/dist/studio/routes/errors/route.js +3 -2
  83. package/dist/studio/routes/errors/route.js.map +1 -1
  84. package/dist/studio/routes/fiberDetail.d.ts +3 -7
  85. package/dist/studio/routes/fiberDetail.d.ts.map +1 -1
  86. package/dist/studio/routes/fibers/route.d.ts +3 -3
  87. package/dist/studio/routes/layout.d.ts +3 -3
  88. package/dist/studio/routes/logs/route.d.ts +3 -3
  89. package/dist/studio/routes/logs/route.d.ts.map +1 -1
  90. package/dist/studio/routes/logs/route.js +3 -2
  91. package/dist/studio/routes/logs/route.js.map +1 -1
  92. package/dist/studio/routes/metrics/route.d.ts +3 -3
  93. package/dist/studio/routes/route.d.ts +2 -2
  94. package/dist/studio/routes/routes/route.d.ts +2 -2
  95. package/dist/studio/routes/services/route.d.ts +2 -2
  96. package/dist/studio/routes/system/route.d.ts +3 -3
  97. package/dist/studio/routes/traceDetail.d.ts +3 -7
  98. package/dist/studio/routes/traceDetail.d.ts.map +1 -1
  99. package/dist/studio/routes/traces/route.d.ts +3 -3
  100. package/dist/studio/routes/traces/route.d.ts.map +1 -1
  101. package/dist/studio/routes/traces/route.js +3 -2
  102. package/dist/studio/routes/traces/route.js.map +1 -1
  103. package/dist/studio/routes/tree.d.ts +43 -51
  104. package/dist/studio/routes/tree.d.ts.map +1 -1
  105. package/package.json +4 -3
  106. package/src/FileRouterCodegen.ts +8 -2
  107. package/src/Route.ts +55 -34
  108. package/src/RouteBody.ts +15 -15
  109. package/src/RouteHook.ts +3 -3
  110. package/src/RouteHttp.ts +10 -4
  111. package/src/RouteLink.ts +56 -0
  112. package/src/RouteMount.ts +43 -48
  113. package/src/RouteSchema.ts +299 -166
  114. package/src/RouteSse.ts +3 -3
  115. package/src/Start.ts +1 -1
  116. package/src/StaticFiles.ts +10 -24
  117. package/src/_HtmlScanner.ts +415 -0
  118. package/src/bun/BunRoute.ts +11 -11
  119. package/src/bundler/BundleRoute.ts +8 -19
  120. package/src/datastar/watchers/patchElements.ts +1 -1
  121. package/src/dev.d.ts +3 -0
  122. package/src/experimental/CsrfProtection.ts +153 -0
  123. package/src/lint/plugin.js +2 -0
  124. package/src/studio/Studio.ts +4 -14
  125. package/src/studio/routes/errors/route.tsx +3 -2
  126. package/src/studio/routes/logs/route.tsx +3 -2
  127. package/src/studio/routes/traces/route.tsx +3 -2
@@ -1,15 +1,12 @@
1
1
  import * as Effect from "effect/Effect"
2
- import * as Layer from "effect/Layer"
3
2
  import * as Option from "effect/Option"
4
3
  import * as Schema from "effect/Schema"
5
4
  import * as Entity from "./Entity.ts"
6
5
  import * as FileSystem from "./FileSystem.ts"
7
- import * as PathPattern from "./_PathPattern.ts"
6
+ import type * as PathPattern from "./_PathPattern.ts"
8
7
  import * as Mime from "./_Mime.ts"
9
8
  import * as Route from "./Route.ts"
10
9
  import * as RouteSchema from "./RouteSchema.ts"
11
- import * as RouteTree from "./RouteTree.ts"
12
- import * as System from "./System.ts"
13
10
 
14
11
  const defaultMountPath = "/assets"
15
12
  const PathParamsSchema = Schema.Struct({
@@ -55,26 +52,15 @@ export const make = (directory: string) =>
55
52
  export const layer = (options: {
56
53
  directory: string
57
54
  path?: string
58
- }) =>
59
- Layer.effect(
60
- Route.Routes,
61
- Effect.gen(function* () {
62
- const existing = yield* Effect.serviceOption(Route.Routes).pipe(
63
- Effect.andThen(Option.getOrUndefined),
64
- )
65
- const trimmedMountPath = (options.path ?? defaultMountPath).trim().replace(/^\/+|\/+$/g, "")
66
- const mountPattern = (
67
- trimmedMountPath.length > 0 ? `/${trimmedMountPath}/:path+` : "/:path+"
68
- ) as PathPattern.PathPattern
69
- const staticFilesTree = Route.tree({
70
- [mountPattern]: make(options.directory),
71
- })
72
- if (!existing) {
73
- return staticFilesTree
74
- }
75
- return RouteTree.merge(existing, staticFilesTree)
76
- }),
77
- )
55
+ }) => {
56
+ const trimmedMountPath = (options.path ?? defaultMountPath).trim().replace(/^\/+|\/+$/g, "")
57
+ const mountPattern = (
58
+ trimmedMountPath.length > 0 ? `/${trimmedMountPath}/:path+` : "/:path+"
59
+ ) as PathPattern.PathPattern
60
+ return Route.layerMerge({
61
+ [mountPattern]: make(options.directory),
62
+ })
63
+ }
78
64
 
79
65
  function normalizeRelativePath(path: string): string | null {
80
66
  if (path.length === 0 || path.startsWith("/") || path.startsWith("\\")) {
@@ -0,0 +1,415 @@
1
+ const TEXT = 0
2
+ const TAG_OPEN = 1
3
+ const TAG_NAME = 2
4
+ const BEFORE_ATTR_NAME = 3
5
+ const ATTR_NAME = 4
6
+ const AFTER_ATTR_NAME = 5
7
+ const BEFORE_ATTR_VALUE = 6
8
+ const ATTR_VALUE_DOUBLE_QUOTED = 7
9
+ const ATTR_VALUE_SINGLE_QUOTED = 8
10
+ const ATTR_VALUE_UNQUOTED = 9
11
+ const SELF_CLOSING = 10
12
+ const BOGUS_COMMENT = 11
13
+
14
+ const RAW_TEXT_TAGS = ["script", "style", "textarea", "title"]
15
+
16
+ interface Span {
17
+ start: number
18
+ end: number
19
+ }
20
+
21
+ interface AttrInternal {
22
+ value: string
23
+ nameSpan: Span
24
+ valueSpan: Span | undefined
25
+ }
26
+
27
+ interface TokenizedElement {
28
+ tag: string
29
+ attrs: Map<string, AttrInternal>
30
+ end: number
31
+ }
32
+
33
+ function* tokenize(html: string): Generator<TokenizedElement> {
34
+ const len = html.length
35
+ let i = 0
36
+ let state = TEXT
37
+ let tag = ""
38
+ let attrName = ""
39
+ let attrNameStart = 0
40
+ let attrValue = ""
41
+ let attrValueStart = 0
42
+ let attrs = new Map<string, AttrInternal>()
43
+
44
+ let pending: TokenizedElement | undefined
45
+
46
+ const emit = (): string | undefined => {
47
+ const lower = tag.toLowerCase()
48
+ pending = { tag, attrs, end: i }
49
+ tag = ""
50
+ attrs = new Map()
51
+ return RAW_TEXT_TAGS.includes(lower) ? lower : undefined
52
+ }
53
+
54
+ const emitAndContinue = () => {
55
+ const rawTag = emit()
56
+ state = TEXT
57
+ if (rawTag) {
58
+ const needle = `</${rawTag}`
59
+ const idx = html.toLowerCase().indexOf(needle, i)
60
+ if (idx === -1) {
61
+ i = len
62
+ } else {
63
+ const end = html.indexOf(">", idx + needle.length)
64
+ i = end === -1 ? len : end + 1
65
+ }
66
+ }
67
+ }
68
+
69
+ const commitAttr = () => {
70
+ if (attrName) {
71
+ attrs.set(attrName.toLowerCase(), {
72
+ value: attrValue,
73
+ nameSpan: { start: attrNameStart, end: attrNameStart + attrName.length },
74
+ valueSpan: attrValueStart > 0
75
+ ? { start: attrValueStart, end: attrValueStart + attrValue.length }
76
+ : undefined,
77
+ })
78
+ attrName = ""
79
+ attrValue = ""
80
+ attrValueStart = 0
81
+ }
82
+ }
83
+
84
+ while (i < len) {
85
+ const ch = html[i]
86
+
87
+ switch (state) {
88
+ case TEXT:
89
+ if (ch === "<") {
90
+ const next = html[i + 1]
91
+ if (next === "!" && html[i + 2] === "-" && html[i + 3] === "-") {
92
+ const end = html.indexOf("-->", i + 4)
93
+ i = end === -1 ? len : end + 3
94
+ } else if (next === "!" || next === "?") {
95
+ state = BOGUS_COMMENT
96
+ i++
97
+ } else {
98
+ state = TAG_OPEN
99
+ i++
100
+ }
101
+ } else {
102
+ i++
103
+ }
104
+ break
105
+
106
+ case BOGUS_COMMENT: {
107
+ const end = html.indexOf(">", i)
108
+ i = end === -1 ? len : end + 1
109
+ state = TEXT
110
+ break
111
+ }
112
+
113
+ case TAG_OPEN:
114
+ if (ch === "/") {
115
+ const end = html.indexOf(">", i)
116
+ i = end === -1 ? len : end + 1
117
+ state = TEXT
118
+ } else if ((ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z")) {
119
+ tag = ch
120
+ state = TAG_NAME
121
+ i++
122
+ } else {
123
+ state = TEXT
124
+ }
125
+ break
126
+
127
+ case TAG_NAME:
128
+ if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r" || ch === "\f") {
129
+ state = BEFORE_ATTR_NAME
130
+ i++
131
+ } else if (ch === "/") {
132
+ state = SELF_CLOSING
133
+ i++
134
+ } else if (ch === ">") {
135
+ i++
136
+ emitAndContinue()
137
+ } else {
138
+ tag += ch
139
+ i++
140
+ }
141
+ break
142
+
143
+ case BEFORE_ATTR_NAME:
144
+ if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r" || ch === "\f") {
145
+ i++
146
+ } else if (ch === "/") {
147
+ state = SELF_CLOSING
148
+ i++
149
+ } else if (ch === ">") {
150
+ i++
151
+ emitAndContinue()
152
+ } else {
153
+ attrName = ch
154
+ attrNameStart = i
155
+ state = ATTR_NAME
156
+ i++
157
+ }
158
+ break
159
+
160
+ case ATTR_NAME:
161
+ if (ch === "=") {
162
+ state = BEFORE_ATTR_VALUE
163
+ i++
164
+ } else if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r" || ch === "\f") {
165
+ state = AFTER_ATTR_NAME
166
+ i++
167
+ } else if (ch === "/" || ch === ">") {
168
+ commitAttr()
169
+ if (ch === "/") {
170
+ state = SELF_CLOSING
171
+ i++
172
+ } else {
173
+ i++
174
+ emitAndContinue()
175
+ }
176
+ } else {
177
+ attrName += ch
178
+ i++
179
+ }
180
+ break
181
+
182
+ case AFTER_ATTR_NAME:
183
+ if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r" || ch === "\f") {
184
+ i++
185
+ } else if (ch === "=") {
186
+ state = BEFORE_ATTR_VALUE
187
+ i++
188
+ } else if (ch === "/") {
189
+ commitAttr()
190
+ state = SELF_CLOSING
191
+ i++
192
+ } else if (ch === ">") {
193
+ commitAttr()
194
+ i++
195
+ emitAndContinue()
196
+ } else {
197
+ commitAttr()
198
+ attrName = ch
199
+ attrNameStart = i
200
+ state = ATTR_NAME
201
+ i++
202
+ }
203
+ break
204
+
205
+ case BEFORE_ATTR_VALUE:
206
+ if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r" || ch === "\f") {
207
+ i++
208
+ } else if (ch === '"') {
209
+ attrValueStart = i + 1
210
+ state = ATTR_VALUE_DOUBLE_QUOTED
211
+ i++
212
+ } else if (ch === "'") {
213
+ attrValueStart = i + 1
214
+ state = ATTR_VALUE_SINGLE_QUOTED
215
+ i++
216
+ } else if (ch === ">") {
217
+ commitAttr()
218
+ i++
219
+ emitAndContinue()
220
+ } else {
221
+ attrValue = ch
222
+ attrValueStart = i
223
+ state = ATTR_VALUE_UNQUOTED
224
+ i++
225
+ }
226
+ break
227
+
228
+ case ATTR_VALUE_DOUBLE_QUOTED:
229
+ if (ch === '"') {
230
+ commitAttr()
231
+ state = BEFORE_ATTR_NAME
232
+ i++
233
+ } else {
234
+ attrValue += ch
235
+ i++
236
+ }
237
+ break
238
+
239
+ case ATTR_VALUE_SINGLE_QUOTED:
240
+ if (ch === "'") {
241
+ commitAttr()
242
+ state = BEFORE_ATTR_NAME
243
+ i++
244
+ } else {
245
+ attrValue += ch
246
+ i++
247
+ }
248
+ break
249
+
250
+ case ATTR_VALUE_UNQUOTED:
251
+ if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r" || ch === "\f") {
252
+ commitAttr()
253
+ state = BEFORE_ATTR_NAME
254
+ i++
255
+ } else if (ch === ">") {
256
+ commitAttr()
257
+ i++
258
+ emitAndContinue()
259
+ } else {
260
+ attrValue += ch
261
+ i++
262
+ }
263
+ break
264
+
265
+ case SELF_CLOSING:
266
+ if (ch === ">") {
267
+ i++
268
+ emitAndContinue()
269
+ } else {
270
+ state = BEFORE_ATTR_NAME
271
+ }
272
+ break
273
+ }
274
+
275
+ if (pending) {
276
+ yield pending
277
+ pending = undefined
278
+ }
279
+ }
280
+ }
281
+
282
+ interface ParsedElement {
283
+ readonly tagName: string
284
+ readonly attributes: ReadonlyMap<string, string>
285
+ }
286
+
287
+ export function* parse(html: string): Generator<ParsedElement> {
288
+ for (const tok of tokenize(html)) {
289
+ const attributes = new Map<string, string>()
290
+ for (const [name, attr] of tok.attrs) {
291
+ attributes.set(name, attr.value)
292
+ }
293
+ yield { tagName: tok.tag.toLowerCase(), attributes }
294
+ }
295
+ }
296
+
297
+ class MutableElement {
298
+ readonly tagName: string
299
+ private _attrs: Map<string, AttrInternal>
300
+ private _edits: Array<{ offset: number; deleteCount: number; insert: string }>
301
+ private _html: string
302
+ private _end: number
303
+
304
+ constructor(
305
+ tok: TokenizedElement,
306
+ edits: Array<{ offset: number; deleteCount: number; insert: string }>,
307
+ html: string,
308
+ ) {
309
+ this.tagName = tok.tag.toLowerCase()
310
+ this._attrs = tok.attrs
311
+ this._edits = edits
312
+ this._html = html
313
+ this._end = tok.end
314
+ }
315
+
316
+ getAttribute(name: string): string | null {
317
+ const attr = this._attrs.get(name.toLowerCase())
318
+ return attr ? attr.value : null
319
+ }
320
+
321
+ hasAttribute(name: string): boolean {
322
+ return this._attrs.has(name.toLowerCase())
323
+ }
324
+
325
+ setAttribute(name: string, value: string): this {
326
+ const lower = name.toLowerCase()
327
+ const attr = this._attrs.get(lower)
328
+ if (attr && attr.valueSpan) {
329
+ this._edits.push({
330
+ offset: attr.valueSpan.start,
331
+ deleteCount: attr.valueSpan.end - attr.valueSpan.start,
332
+ insert: value,
333
+ })
334
+ attr.value = value
335
+ } else if (attr) {
336
+ this._edits.push({
337
+ offset: attr.nameSpan.start,
338
+ deleteCount: attr.nameSpan.end - attr.nameSpan.start,
339
+ insert: `${name}="${value}"`,
340
+ })
341
+ attr.value = value
342
+ attr.valueSpan = { start: -1, end: -1 }
343
+ } else {
344
+ const insertAt = this._end - 1
345
+ this._edits.push({
346
+ offset: insertAt,
347
+ deleteCount: 0,
348
+ insert: ` ${name}="${value}"`,
349
+ })
350
+ this._attrs.set(lower, {
351
+ value,
352
+ nameSpan: { start: -1, end: -1 },
353
+ valueSpan: { start: -1, end: -1 },
354
+ })
355
+ }
356
+ return this
357
+ }
358
+
359
+ removeAttribute(name: string): this {
360
+ const lower = name.toLowerCase()
361
+ const attr = this._attrs.get(lower)
362
+ if (!attr || attr.nameSpan.start === -1) return this
363
+
364
+ let start = attr.nameSpan.start
365
+ const end = attr.valueSpan
366
+ ? attr.valueSpan.end + 1
367
+ : attr.nameSpan.end
368
+
369
+ while (start > 0 && " \t\n\r\f".includes(this._html[start - 1])) {
370
+ start--
371
+ }
372
+
373
+ this._edits.push({ offset: start, deleteCount: end - start, insert: "" })
374
+ this._attrs.delete(lower)
375
+ return this
376
+ }
377
+
378
+ get attributes(): IterableIterator<[string, string]> {
379
+ const entries = this._attrs.entries()
380
+ return (function* () {
381
+ for (const [name, attr] of entries) {
382
+ yield [name, attr.value] as [string, string]
383
+ }
384
+ })()
385
+ }
386
+ }
387
+
388
+ interface RewriteResult extends Iterable<MutableElement> {
389
+ toString(): string
390
+ }
391
+
392
+ export const rewrite = (html: string): RewriteResult => {
393
+ const edits: Array<{ offset: number; deleteCount: number; insert: string }> = []
394
+
395
+ return {
396
+ *[Symbol.iterator]() {
397
+ for (const tok of tokenize(html)) {
398
+ yield new MutableElement(tok, edits, html)
399
+ }
400
+ },
401
+ toString() {
402
+ if (edits.length === 0) return html
403
+
404
+ edits.sort((a, b) => b.offset - a.offset)
405
+ let result = html
406
+ for (const edit of edits) {
407
+ result =
408
+ result.slice(0, edit.offset) +
409
+ edit.insert +
410
+ result.slice(edit.offset + edit.deleteCount)
411
+ }
412
+ return result
413
+ },
414
+ }
415
+ }
@@ -25,7 +25,7 @@ export type BunDescriptors = {
25
25
  }
26
26
 
27
27
  export function descriptors(
28
- route: Route.Route.Route<any, any, any, any, any>,
28
+ route: Route.Route<any, any, any, any, any>,
29
29
  ): BunDescriptors | undefined {
30
30
  const descriptor = Route.descriptor(route) as Partial<BunDescriptors>
31
31
  if (typeof descriptor.bunPrefix === "string" && typeof descriptor.bunLoad === "function") {
@@ -45,29 +45,29 @@ export function htmlBundle(load: () => HTMLBundleModule | Promise<HTMLBundleModu
45
45
  const descriptors = { bunPrefix, bunLoad, format: "html" as const }
46
46
 
47
47
  return function <D extends Route.RouteDescriptor.Any, B extends {}, I extends Route.Route.Tuple>(
48
- self: Route.RouteSet.RouteSet<D, B, I>,
49
- ): Route.RouteSet.RouteSet<
48
+ self: Route.RouteSet<D, B, I>,
49
+ ): Route.RouteSet<
50
50
  D,
51
51
  B,
52
52
  [
53
53
  ...I,
54
- Route.Route.Route<
54
+ Route.Route<
55
55
  BunDescriptors & { format: "html" },
56
- { request: Request },
56
+ {},
57
57
  string,
58
58
  BunRouteError,
59
- BunServer.BunServer
59
+ BunServer.BunServer | Route.Request
60
60
  >,
61
61
  ]
62
62
  > {
63
63
  const handler: Route.Route.Handler<
64
- BunDescriptors & { format: "html" } & { request: Request },
64
+ BunDescriptors & { format: "html" },
65
65
  string,
66
66
  BunRouteError,
67
- BunServer.BunServer
67
+ BunServer.BunServer | Route.Request
68
68
  > = (context, next) =>
69
69
  Effect.gen(function* () {
70
- const originalRequest = context.request
70
+ const originalRequest = yield* Route.Request
71
71
  const bundleDepth = yield* FiberRef.get(bundleDepthRef)
72
72
 
73
73
  if (originalRequest.headers.get(INTERNAL_FETCH_HEADER) === "true") {
@@ -142,10 +142,10 @@ export function htmlBundle(load: () => HTMLBundleModule | Promise<HTMLBundleModu
142
142
 
143
143
  const route = Route.make<
144
144
  BunDescriptors & { format: "html" },
145
- { request: Request },
145
+ {},
146
146
  string,
147
147
  BunRouteError,
148
- BunServer.BunServer
148
+ BunServer.BunServer | Route.Request
149
149
  >(handler, descriptors)
150
150
 
151
151
  return Route.set([...Route.items(self), route] as any, Route.descriptor(self))
@@ -1,11 +1,8 @@
1
1
  import type * as Context from "effect/Context"
2
2
  import * as Effect from "effect/Effect"
3
- import * as Layer from "effect/Layer"
4
- import * as Option from "effect/Option"
5
3
  import * as Entity from "../Entity.ts"
6
4
  import * as PathPattern from "../_PathPattern.ts"
7
5
  import * as Route from "../Route.ts"
8
- import * as RouteTree from "../RouteTree.ts"
9
6
  import * as Values from "../_Values.ts"
10
7
  import * as Bundle from "./Bundle.ts"
11
8
 
@@ -23,7 +20,8 @@ export const make = <Tag extends Context.Tag<any, Bundle.BundleContext>>(tag: Ta
23
20
  Route.get(
24
21
  Route.render(function* (ctx) {
25
22
  const bundle = yield* tag
26
- const url = new URL(ctx.request.url)
23
+ const request = yield* Route.Request
24
+ const url = new URL(request.url)
27
25
  const mountPath = (ctx as unknown as { path?: string }).path ?? "/"
28
26
  const params = PathPattern.match(mountPath, url.pathname)
29
27
  const artifactPath = params ? Values.firstValue(params) : undefined
@@ -49,18 +47,9 @@ export const client = () => make(Bundle.ClientBundle)
49
47
  export const layer = (options?: {
50
48
  bundle?: Context.Tag<any, Bundle.BundleContext>
51
49
  path?: PathPattern.PathPattern
52
- }) =>
53
- Layer.effect(
54
- Route.Routes,
55
- Effect.gen(function* () {
56
- const existing = yield* Effect.serviceOption(Route.Routes).pipe(
57
- Effect.andThen(Option.getOrUndefined),
58
- )
59
- const path = options?.path ?? "/_bundle/:path+"
60
- const bundleTree = Route.tree({
61
- [path]: make(options?.bundle ?? Bundle.ClientBundle),
62
- })
63
- if (!existing) return bundleTree
64
- return RouteTree.merge(existing, bundleTree)
65
- }),
66
- )
50
+ }) => {
51
+ const path = options?.path ?? "/_bundle/:path+"
52
+ return Route.layerMerge({
53
+ [path]: make(options?.bundle ?? Bundle.ClientBundle),
54
+ })
55
+ }
@@ -403,7 +403,7 @@ const removeNode = (node: Node): void => {
403
403
  }
404
404
 
405
405
  const moveBefore: (parentNode: Node, node: Node, after: Node | null) => void = removeNode.call.bind(
406
- // @ts-expect-error
406
+ // @ts-ignore
407
407
  ctxPantry.moveBefore ?? ctxPantry.insertBefore,
408
408
  )
409
409
 
package/src/dev.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ declare module "effect-start/dev" {
2
+ export interface Routes {}
3
+ }