effect-start 0.22.1 → 0.23.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 (313) hide show
  1. package/dist/BlobStore.d.ts +80 -0
  2. package/dist/BlobStore.js +19 -0
  3. package/dist/ChildProcess.d.ts +60 -0
  4. package/dist/ChildProcess.js +30 -0
  5. package/dist/Commander.d.ts +3 -6
  6. package/dist/Commander.js +6 -13
  7. package/dist/ContentNegotiation.d.ts +8 -9
  8. package/dist/ContentNegotiation.js +32 -37
  9. package/dist/Cookies.d.ts +47 -0
  10. package/dist/Cookies.js +273 -363
  11. package/dist/Development.d.ts +2 -2
  12. package/dist/Development.js +3 -4
  13. package/dist/Effectify.d.ts +1 -4
  14. package/dist/FilePathPattern.d.ts +3 -3
  15. package/dist/FileRouter.d.ts +5 -8
  16. package/dist/FileRouter.js +9 -10
  17. package/dist/FileRouterCodegen.d.ts +1 -1
  18. package/dist/FileRouterCodegen.js +33 -13
  19. package/dist/FileSystem.d.ts +158 -0
  20. package/dist/FileSystem.js +64 -125
  21. package/dist/Http.js +2 -6
  22. package/dist/PathPattern.d.ts +7 -7
  23. package/dist/PathPattern.js +1 -3
  24. package/dist/PlatformError.d.ts +24 -32
  25. package/dist/PlatformError.js +3 -21
  26. package/dist/PlatformRuntime.js +5 -10
  27. package/dist/Route.d.ts +14 -19
  28. package/dist/Route.js +8 -11
  29. package/dist/RouteBody.d.ts +6 -12
  30. package/dist/RouteBody.js +2 -2
  31. package/dist/RouteError.d.ts +98 -0
  32. package/dist/RouteError.js +55 -0
  33. package/dist/RouteHook.js +6 -11
  34. package/dist/RouteHttp.d.ts +3 -3
  35. package/dist/RouteHttp.js +27 -22
  36. package/dist/RouteMount.d.ts +16 -50
  37. package/dist/RouteMount.js +6 -20
  38. package/dist/RouteSchema.d.ts +22 -1
  39. package/dist/RouteSchema.js +33 -0
  40. package/dist/RouteSse.js +4 -10
  41. package/dist/RouteTree.d.ts +2 -1
  42. package/dist/RouteTree.js +17 -15
  43. package/dist/RouteTrie.d.ts +2 -2
  44. package/dist/RouteTrie.js +4 -9
  45. package/dist/SchemaExtra.d.ts +1 -1
  46. package/dist/Socket.d.ts +27 -0
  47. package/dist/Socket.js +20 -28
  48. package/dist/Sql.d.ts +34 -0
  49. package/dist/Sql.js +5 -0
  50. package/dist/SqlIntrospect.d.ts +91 -0
  51. package/dist/SqlIntrospect.js +466 -0
  52. package/dist/Start.d.ts +4 -6
  53. package/dist/Start.js +10 -2
  54. package/dist/StreamExtra.d.ts +1 -1
  55. package/dist/StreamExtra.js +9 -9
  56. package/dist/System.d.ts +7 -0
  57. package/dist/System.js +22 -0
  58. package/dist/TuplePathPattern.js +55 -50
  59. package/dist/Unique.js +7 -7
  60. package/dist/Values.d.ts +2 -1
  61. package/dist/Values.js +19 -13
  62. package/dist/bun/BunBlobStoreDisk.d.ts +6 -0
  63. package/dist/bun/BunBlobStoreDisk.js +116 -0
  64. package/dist/bun/BunBlobStoreS3.d.ts +11 -0
  65. package/dist/bun/BunBlobStoreS3.js +89 -0
  66. package/dist/bun/BunBlobWatcherDisk.d.ts +6 -0
  67. package/dist/bun/BunBlobWatcherDisk.js +60 -0
  68. package/dist/bun/BunBlobWatcherQueue.d.ts +6 -0
  69. package/dist/bun/BunBlobWatcherQueue.js +17 -0
  70. package/dist/bun/BunBundle.d.ts +5 -6
  71. package/dist/bun/BunBundle.js +7 -15
  72. package/dist/bun/BunChildProcessSpawner.d.ts +3 -0
  73. package/dist/bun/BunChildProcessSpawner.js +103 -0
  74. package/dist/bun/BunImportTrackerPlugin.d.ts +1 -1
  75. package/dist/bun/BunImportTrackerPlugin.js +3 -5
  76. package/dist/bun/BunRoute.d.ts +3 -2
  77. package/dist/bun/BunRoute.js +5 -7
  78. package/dist/bun/BunRuntime.js +1 -1
  79. package/dist/bun/BunServer.d.ts +11 -4
  80. package/dist/bun/BunServer.js +35 -11
  81. package/dist/bun/BunSql.d.ts +4 -0
  82. package/dist/bun/BunSql.js +81 -0
  83. package/dist/bun/_BunEnhancedResolve.d.ts +3 -3
  84. package/dist/bun/_BunEnhancedResolve.js +2 -4
  85. package/dist/bun/index.d.ts +1 -0
  86. package/dist/bun/index.js +1 -0
  87. package/dist/bundler/Bundle.d.ts +2 -1
  88. package/dist/bundler/Bundle.js +1 -1
  89. package/dist/bundler/BundleFiles.d.ts +5 -5
  90. package/dist/bundler/BundleFiles.js +10 -8
  91. package/dist/bundler/BundleRoute.d.ts +27 -0
  92. package/dist/bundler/BundleRoute.js +51 -0
  93. package/dist/client/ScrollState.js +2 -6
  94. package/dist/client/index.js +6 -8
  95. package/dist/console/Console.d.ts +6 -0
  96. package/dist/console/Console.js +26 -0
  97. package/dist/console/ConsoleErrors.d.ts +3 -0
  98. package/dist/console/ConsoleErrors.js +200 -0
  99. package/dist/console/ConsoleLogger.d.ts +3 -0
  100. package/dist/console/ConsoleLogger.js +47 -0
  101. package/dist/console/ConsoleMetrics.d.ts +3 -0
  102. package/dist/console/ConsoleMetrics.js +61 -0
  103. package/dist/console/ConsoleProcess.d.ts +3 -0
  104. package/dist/console/ConsoleProcess.js +49 -0
  105. package/dist/console/ConsoleStore.d.ts +144 -0
  106. package/dist/console/ConsoleStore.js +61 -0
  107. package/dist/console/ConsoleTracer.d.ts +3 -0
  108. package/dist/console/ConsoleTracer.js +94 -0
  109. package/dist/console/Simulation.d.ts +2 -0
  110. package/dist/console/Simulation.js +633 -0
  111. package/dist/console/index.d.ts +3 -0
  112. package/dist/console/index.js +3 -0
  113. package/dist/console/routes/errors/route.d.ts +10 -0
  114. package/dist/console/routes/errors/route.js +47 -0
  115. package/dist/console/routes/fiberDetail.d.ts +16 -0
  116. package/dist/console/routes/fiberDetail.js +38 -0
  117. package/dist/console/routes/fibers/route.d.ts +10 -0
  118. package/dist/console/routes/fibers/route.js +19 -0
  119. package/dist/console/routes/git/route.d.ts +11 -0
  120. package/dist/console/routes/git/route.js +33 -0
  121. package/dist/console/routes/layout.d.ts +9 -0
  122. package/dist/console/routes/layout.js +3 -0
  123. package/dist/console/routes/logs/route.d.ts +10 -0
  124. package/dist/console/routes/logs/route.js +32 -0
  125. package/dist/console/routes/metrics/route.d.ts +10 -0
  126. package/dist/console/routes/metrics/route.js +17 -0
  127. package/dist/console/routes/route.d.ts +6 -0
  128. package/dist/console/routes/route.js +5 -0
  129. package/dist/console/routes/routes/route.d.ts +6 -0
  130. package/dist/console/routes/routes/route.js +20 -0
  131. package/dist/console/routes/services/route.d.ts +6 -0
  132. package/dist/console/routes/services/route.js +12 -0
  133. package/dist/console/routes/system/route.d.ts +10 -0
  134. package/dist/console/routes/system/route.js +18 -0
  135. package/dist/console/routes/traceDetail.d.ts +16 -0
  136. package/dist/console/routes/traceDetail.js +14 -0
  137. package/dist/console/routes/traces/route.d.ts +10 -0
  138. package/dist/console/routes/traces/route.js +39 -0
  139. package/dist/console/routes/tree.d.ts +153 -0
  140. package/dist/console/routes/tree.js +29 -0
  141. package/dist/console/ui/Errors.d.ts +4 -0
  142. package/dist/console/ui/Errors.js +15 -0
  143. package/dist/console/ui/Fibers.d.ts +24 -0
  144. package/dist/console/ui/Fibers.js +121 -0
  145. package/dist/console/ui/Git.d.ts +20 -0
  146. package/dist/console/ui/Git.js +95 -0
  147. package/dist/console/ui/Logs.d.ts +4 -0
  148. package/dist/console/ui/Logs.js +25 -0
  149. package/dist/console/ui/Metrics.d.ts +4 -0
  150. package/dist/console/ui/Metrics.js +26 -0
  151. package/dist/console/ui/Routes.d.ts +8 -0
  152. package/dist/console/ui/Routes.js +70 -0
  153. package/dist/console/ui/Services.d.ts +10 -0
  154. package/dist/console/ui/Services.js +246 -0
  155. package/dist/console/ui/Shell.d.ts +10 -0
  156. package/dist/console/ui/Shell.js +7 -0
  157. package/dist/console/ui/System.d.ts +4 -0
  158. package/dist/console/ui/System.js +35 -0
  159. package/dist/console/ui/Traces.d.ts +12 -0
  160. package/dist/console/ui/Traces.js +179 -0
  161. package/dist/datastar/actions/fetch.d.ts +1 -1
  162. package/dist/datastar/actions/fetch.js +10 -18
  163. package/dist/datastar/actions/peek.js +1 -2
  164. package/dist/datastar/actions/setAll.js +1 -2
  165. package/dist/datastar/actions/toggleAll.js +1 -2
  166. package/dist/datastar/attributes/attr.js +1 -2
  167. package/dist/datastar/attributes/bind.js +10 -18
  168. package/dist/datastar/attributes/class.js +2 -5
  169. package/dist/datastar/attributes/computed.js +2 -3
  170. package/dist/datastar/attributes/effect.js +1 -2
  171. package/dist/datastar/attributes/indicator.js +2 -4
  172. package/dist/datastar/attributes/init.js +2 -3
  173. package/dist/datastar/attributes/jsonSignals.js +1 -2
  174. package/dist/datastar/attributes/on.js +41 -22
  175. package/dist/datastar/attributes/onIntersect.js +2 -3
  176. package/dist/datastar/attributes/onInterval.js +2 -3
  177. package/dist/datastar/attributes/onSignalPatch.js +2 -4
  178. package/dist/datastar/attributes/ref.js +1 -2
  179. package/dist/datastar/attributes/show.js +1 -2
  180. package/dist/datastar/attributes/signals.js +1 -2
  181. package/dist/datastar/attributes/style.js +6 -12
  182. package/dist/datastar/attributes/text.js +1 -2
  183. package/dist/datastar/engine.d.ts +13 -7
  184. package/dist/datastar/engine.js +76 -48
  185. package/dist/datastar/happydom.d.ts +1 -0
  186. package/dist/datastar/happydom.js +8 -0
  187. package/dist/datastar/index.d.ts +1 -1
  188. package/dist/datastar/index.js +1 -1
  189. package/dist/datastar/utils.js +4 -7
  190. package/dist/datastar/watchers/patchElements.js +24 -45
  191. package/dist/datastar/watchers/patchSignals.js +1 -2
  192. package/dist/experimental/EncryptedCookies.d.ts +2 -5
  193. package/dist/experimental/EncryptedCookies.js +17 -48
  194. package/dist/experimental/index.d.ts +0 -1
  195. package/dist/experimental/index.js +0 -1
  196. package/dist/hyper/Hyper.d.ts +2 -9
  197. package/dist/hyper/Hyper.js +1 -12
  198. package/dist/hyper/HyperHtml.d.ts +1 -1
  199. package/dist/hyper/HyperHtml.js +18 -12
  200. package/dist/hyper/HyperHtml.test.d.ts +1 -0
  201. package/dist/hyper/HyperHtml.test.js +197 -0
  202. package/dist/hyper/HyperRoute.test.js +14 -3
  203. package/dist/hyper/html.d.ts +11 -0
  204. package/dist/hyper/html.js +30 -0
  205. package/dist/hyper/index.d.ts +2 -0
  206. package/dist/hyper/index.js +1 -0
  207. package/dist/hyper/jsx-runtime.d.ts +1 -1
  208. package/dist/hyper/jsx-runtime.js +1 -1
  209. package/dist/index.d.ts +1 -0
  210. package/dist/index.js +1 -0
  211. package/dist/lint/plugin.d.ts +86 -0
  212. package/dist/lint/plugin.js +341 -0
  213. package/dist/node/NodeFileSystem.d.ts +2 -2
  214. package/dist/node/NodeFileSystem.js +4 -14
  215. package/dist/sql/bun/index.d.ts +3 -0
  216. package/dist/sql/bun/index.js +75 -0
  217. package/dist/sql/mssql/docker.d.ts +2 -0
  218. package/dist/sql/mssql/docker.js +67 -0
  219. package/dist/sql/mssql/index.d.ts +21 -0
  220. package/dist/sql/mssql/index.js +113 -0
  221. package/dist/testing/TestLogger.js +4 -1
  222. package/dist/testing/index.d.ts +0 -1
  223. package/dist/testing/index.js +0 -1
  224. package/dist/testing/utils.d.ts +3 -3
  225. package/dist/testing/utils.js +4 -4
  226. package/dist/x/cloudflare/CloudflareTunnel.d.ts +2 -5
  227. package/dist/x/cloudflare/CloudflareTunnel.js +14 -27
  228. package/dist/x/datastar/Datastar.d.ts +1 -1
  229. package/dist/x/datastar/Datastar.js +13 -12
  230. package/dist/x/datastar/index.d.ts +1 -2
  231. package/dist/x/datastar/index.js +1 -2
  232. package/dist/x/tailscale/TailscaleTunnel.d.ts +15 -0
  233. package/dist/x/tailscale/TailscaleTunnel.js +68 -0
  234. package/dist/x/tailscale/index.d.ts +1 -0
  235. package/dist/x/tailscale/index.js +1 -0
  236. package/dist/x/tailwind/TailwindPlugin.js +19 -19
  237. package/dist/x/tailwind/compile.d.ts +2 -2
  238. package/dist/x/tailwind/compile.js +2 -4
  239. package/package.json +22 -9
  240. package/src/ChildProcess.ts +145 -0
  241. package/src/PlatformError.ts +27 -50
  242. package/src/Route.ts +2 -2
  243. package/src/RouteError.ts +76 -0
  244. package/src/RouteHttp.ts +13 -5
  245. package/src/RouteSchema.ts +96 -1
  246. package/src/RouteTree.ts +12 -0
  247. package/src/Sql.ts +51 -0
  248. package/src/SqlIntrospect.ts +620 -0
  249. package/src/Start.ts +15 -3
  250. package/src/System.ts +43 -0
  251. package/src/Values.ts +7 -0
  252. package/src/bun/BunChildProcessSpawner.ts +143 -0
  253. package/src/bun/BunRoute.ts +5 -2
  254. package/src/bun/BunServer.ts +22 -1
  255. package/src/bun/index.ts +1 -0
  256. package/src/bundler/BundleRoute.ts +66 -0
  257. package/src/console/Console.ts +42 -0
  258. package/src/console/ConsoleErrors.ts +213 -0
  259. package/src/console/ConsoleLogger.ts +56 -0
  260. package/src/console/ConsoleMetrics.ts +72 -0
  261. package/src/console/ConsoleProcess.ts +59 -0
  262. package/src/console/ConsoleStore.ts +187 -0
  263. package/src/console/ConsoleTracer.ts +107 -0
  264. package/src/console/Simulation.ts +814 -0
  265. package/src/console/console.html +340 -0
  266. package/src/console/index.ts +3 -0
  267. package/src/console/routes/errors/route.tsx +97 -0
  268. package/src/console/routes/fiberDetail.tsx +54 -0
  269. package/src/console/routes/fibers/route.tsx +45 -0
  270. package/src/console/routes/git/route.tsx +64 -0
  271. package/src/console/routes/layout.tsx +4 -0
  272. package/src/console/routes/logs/route.tsx +77 -0
  273. package/src/console/routes/metrics/route.tsx +36 -0
  274. package/src/console/routes/route.tsx +8 -0
  275. package/src/console/routes/routes/route.tsx +30 -0
  276. package/src/console/routes/services/route.tsx +21 -0
  277. package/src/console/routes/system/route.tsx +43 -0
  278. package/src/console/routes/traceDetail.tsx +22 -0
  279. package/src/console/routes/traces/route.tsx +81 -0
  280. package/src/console/routes/tree.ts +30 -0
  281. package/src/console/ui/Errors.tsx +76 -0
  282. package/src/console/ui/Fibers.tsx +321 -0
  283. package/src/console/ui/Git.tsx +182 -0
  284. package/src/console/ui/Logs.tsx +46 -0
  285. package/src/console/ui/Metrics.tsx +78 -0
  286. package/src/console/ui/Routes.tsx +125 -0
  287. package/src/console/ui/Services.tsx +273 -0
  288. package/src/console/ui/Shell.tsx +62 -0
  289. package/src/console/ui/System.tsx +131 -0
  290. package/src/console/ui/Traces.tsx +426 -0
  291. package/src/datastar/README.md +6 -1
  292. package/src/datastar/actions/fetch.ts +0 -1
  293. package/src/datastar/attributes/on.ts +40 -20
  294. package/src/datastar/engine.ts +51 -0
  295. package/src/datastar/jsx.d.ts +79 -0
  296. package/src/hyper/Hyper.ts +1 -16
  297. package/src/hyper/HyperHtml.ts +6 -4
  298. package/src/hyper/HyperRoute.ts +2 -1
  299. package/src/hyper/html.ts +47 -0
  300. package/src/hyper/index.ts +2 -0
  301. package/src/hyper/jsx.d.ts +5 -3
  302. package/src/index.ts +1 -0
  303. package/src/lint/plugin.js +129 -0
  304. package/src/sql/bun/index.ts +147 -0
  305. package/src/sql/mssql/docker.ts +117 -0
  306. package/src/sql/mssql/index.ts +223 -0
  307. package/src/sql/mssql/mssql.d.ts +41 -0
  308. package/src/x/cloudflare/CloudflareTunnel.ts +8 -36
  309. package/src/x/tailscale/TailscaleTunnel.ts +113 -0
  310. package/src/x/tailscale/index.ts +1 -0
  311. package/src/x/datastar/Datastar.ts +0 -61
  312. package/src/x/datastar/index.ts +0 -2
  313. package/src/x/datastar/jsx-datastar.d.ts +0 -60
package/dist/RouteHttp.js CHANGED
@@ -33,8 +33,8 @@ const mediaTypeToFormat = {
33
33
  * This is what @effect/platform does to signal request cancelation.
34
34
  */
35
35
  export const clientAbortFiberId = FiberId.runtime(-499, 0);
36
- const isClientAbort = (cause) => Cause.isInterruptedOnly(cause)
37
- && HashSet.some(Cause.interruptors(cause), (id) => id === clientAbortFiberId);
36
+ const isClientAbort = (cause) => Cause.isInterruptedOnly(cause) &&
37
+ HashSet.some(Cause.interruptors(cause), (id) => id === clientAbortFiberId);
38
38
  const getStatusFromCause = (cause) => {
39
39
  const failure = Cause.failureOption(cause);
40
40
  if (failure._tag === "Some") {
@@ -51,10 +51,11 @@ const respondError = (options) => new Response(JSON.stringify(options, null, 2),
51
51
  });
52
52
  function streamResponse(stream, headers, status, runtime) {
53
53
  const encoder = new TextEncoder();
54
- const byteStream = stream.pipe(Stream.map((chunk) => typeof chunk === "string"
55
- ? encoder.encode(chunk)
56
- : chunk), Stream.catchAll((error) => Stream.fail(error instanceof Error ? error : new Error(String(error)))));
57
- return new Response(Stream.toReadableStreamRuntime(byteStream, runtime), { status, headers: headers });
54
+ const byteStream = stream.pipe(Stream.map((chunk) => typeof chunk === "string" ? encoder.encode(chunk) : chunk), Stream.catchAll((error) => Stream.fail(error instanceof Error ? error : new Error(String(error)))));
55
+ return new Response(Stream.toReadableStreamRuntime(byteStream, runtime), {
56
+ status,
57
+ headers: headers,
58
+ });
58
59
  }
59
60
  function toResponse(entity, format, runtime) {
60
61
  const contentType = Entity.type(entity);
@@ -80,9 +81,7 @@ function determineSelectedFormat(accept, routes) {
80
81
  .map((r) => Route.descriptor(r).format)
81
82
  .filter((f) => Boolean(f) && f !== "*");
82
83
  const uniqueFormats = [...new Set(formats)];
83
- const mediaTypes = uniqueFormats
84
- .map((f) => formatToMediaType[f])
85
- .filter(Boolean);
84
+ const mediaTypes = uniqueFormats.map((f) => formatToMediaType[f]).filter(Boolean);
86
85
  if (mediaTypes.length === 0) {
87
86
  return undefined;
88
87
  }
@@ -123,14 +122,18 @@ export const toWebHandlerRuntime = (runtime) => {
123
122
  }
124
123
  const allRoutes = [...wildcards, ...methodRoutes];
125
124
  const selectedFormat = determineSelectedFormat(accept, allRoutes);
126
- const hasSpecificFormatRoutes = allRoutes.some((r) => {
125
+ const specificFormats = new Set();
126
+ let hasWildcardFormatRoutes = false;
127
+ for (const r of allRoutes) {
127
128
  const format = Route.descriptor(r).format;
128
- return format && format !== "*";
129
- });
130
- const hasWildcardFormatRoutes = allRoutes.some((r) => Route.descriptor(r).format === "*");
131
- if (selectedFormat === undefined
132
- && hasSpecificFormatRoutes
133
- && !hasWildcardFormatRoutes) {
129
+ if (format === "*")
130
+ hasWildcardFormatRoutes = true;
131
+ else if (format)
132
+ specificFormats.add(format);
133
+ }
134
+ const hasSpecificFormatRoutes = specificFormats.size > 0;
135
+ const varyAccept = specificFormats.size > 1;
136
+ if (selectedFormat === undefined && hasSpecificFormatRoutes && !hasWildcardFormatRoutes) {
134
137
  return Promise.resolve(respondError({ status: 406, message: "not acceptable" }));
135
138
  }
136
139
  const createChain = (initialContext) => {
@@ -168,18 +171,20 @@ export const toWebHandlerRuntime = (runtime) => {
168
171
  return runNext();
169
172
  };
170
173
  const effect = Effect.withFiberRuntime((fiber) => {
171
- const tracerDisabled = !fiber.getFiberRef(FiberRef.currentTracerEnabled)
172
- || fiber.getFiberRef(RouteHttpTracer.currentTracerDisabledWhen)(request);
174
+ const tracerDisabled = !fiber.getFiberRef(FiberRef.currentTracerEnabled) ||
175
+ fiber.getFiberRef(RouteHttpTracer.currentTracerDisabledWhen)(request);
173
176
  const url = new URL(request.url);
174
177
  const innerEffect = Effect.gen(function* () {
175
178
  const result = yield* createChain({ request, selectedFormat });
176
- const entity = Entity.isEntity(result)
177
- ? result
178
- : Entity.make(result, { status: 200 });
179
+ const entity = Entity.isEntity(result) ? result : Entity.make(result, { status: 200 });
179
180
  if (entity.status === 404 && entity.body === undefined) {
180
181
  return respondError({ status: 406, message: "not acceptable" });
181
182
  }
182
- return yield* toResponse(entity, selectedFormat, runtime);
183
+ const response = yield* toResponse(entity, selectedFormat, runtime);
184
+ if (varyAccept) {
185
+ response.headers.set("vary", "Accept");
186
+ }
187
+ return response;
183
188
  });
184
189
  if (tracerDisabled) {
185
190
  return innerEffect;
@@ -1,8 +1,8 @@
1
- import * as Types from "effect/Types";
2
- import * as Http from "./Http.ts";
3
- import * as PathPattern from "./PathPattern.ts";
1
+ import type * as Types from "effect/Types";
2
+ import type * as Http from "./Http.ts";
3
+ import type * as PathPattern from "./PathPattern.ts";
4
4
  import * as Route from "./Route.ts";
5
- import * as RouteBody from "./RouteBody.ts";
5
+ import type * as RouteBody from "./RouteBody.ts";
6
6
  type Module = typeof import("./RouteMount.ts");
7
7
  export type Self = RouteMount.Builder | Module;
8
8
  export declare const use: RouteMount.Describer<"*">;
@@ -28,8 +28,7 @@ export declare namespace RouteMount {
28
28
  }
29
29
  export type EmptySet<M extends Method, B = {}> = Route.RouteSet.RouteSet<{
30
30
  method: M;
31
- }, B, [
32
- ]>;
31
+ }, B, []>;
33
32
  export type Items<S> = S extends Builder<any, infer I> ? I : [];
34
33
  export type BuilderBindings<S> = S extends Builder<any, infer I> ? Types.Simplify<WildcardBindings<I>> & {
35
34
  request: Request;
@@ -54,19 +53,13 @@ export declare namespace RouteMount {
54
53
  [K in keyof I]: PrefixPathItem<Prefix, I[K]>;
55
54
  } extends infer R extends Route.Route.Tuple ? R : never;
56
55
  export interface Add {
57
- <S extends Self, P extends string, R extends Route.RouteSet.Any>(this: S, path: P, routes: R): Builder<{}, [
58
- ...Items<S>,
59
- ...PrefixPath<P, Route.RouteSet.Items<R>>
60
- ]>;
56
+ <S extends Self, P extends string, R extends Route.RouteSet.Any>(this: S, path: P, routes: R): Builder<{}, [...Items<S>, ...PrefixPath<P, Route.RouteSet.Items<R>>]>;
61
57
  <S extends Self, P extends string, R extends Route.RouteSet.Any>(this: S, path: P,
62
58
  /**
63
59
  * Callback form provides a builder seeded with higher-level bindings so
64
60
  * nested routes can type-infer outer context when mounting.
65
61
  */
66
- routes: (self: Builder<{}, []>) => R): Builder<{}, [
67
- ...Items<S>,
68
- ...PrefixPath<P, Route.RouteSet.Items<R>>
69
- ]>;
62
+ routes: (self: Builder<{}, []>) => R): Builder<{}, [...Items<S>, ...PrefixPath<P, Route.RouteSet.Items<R>>]>;
70
63
  }
71
64
  export type FlattenItems<M extends Method, B, I extends Route.Route.Tuple> = I extends [
72
65
  Route.Route.Route<infer D, infer RB, infer A, infer E, infer R>,
@@ -78,42 +71,15 @@ export declare namespace RouteMount {
78
71
  ...FlattenItems<M, Types.Simplify<B & RB>, Tail>
79
72
  ] : [];
80
73
  export interface Describer<M extends Method> {
81
- <S extends Self, A extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A): Builder<{}, [
82
- ...Items<S>,
83
- ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<A>>
84
- ]>;
85
- <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B): Builder<{}, [
86
- ...Items<S>,
87
- ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<B>>
88
- ]>;
89
- <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C): Builder<{}, [
90
- ...Items<S>,
91
- ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<C>>
92
- ]>;
93
- <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D): Builder<{}, [
94
- ...Items<S>,
95
- ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<D>>
96
- ]>;
97
- <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any, E extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D, ef: (e: D) => E): Builder<{}, [
98
- ...Items<S>,
99
- ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<E>>
100
- ]>;
101
- <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any, E extends Route.RouteSet.Any, F extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D, ef: (e: D) => E, fg: (f: E) => F): Builder<{}, [
102
- ...Items<S>,
103
- ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<F>>
104
- ]>;
105
- <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any, E extends Route.RouteSet.Any, F extends Route.RouteSet.Any, G extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D, ef: (e: D) => E, fg: (f: E) => F, gh: (g: F) => G): Builder<{}, [
106
- ...Items<S>,
107
- ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<G>>
108
- ]>;
109
- <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any, E extends Route.RouteSet.Any, F extends Route.RouteSet.Any, G extends Route.RouteSet.Any, H extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D, ef: (e: D) => E, fg: (f: E) => F, gh: (g: F) => G, hi: (h: G) => H): Builder<{}, [
110
- ...Items<S>,
111
- ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<H>>
112
- ]>;
113
- <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any, E extends Route.RouteSet.Any, F extends Route.RouteSet.Any, G extends Route.RouteSet.Any, H extends Route.RouteSet.Any, I extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D, ef: (e: D) => E, fg: (f: E) => F, gh: (g: F) => G, hi: (h: G) => H, ij: (i: H) => I): Builder<{}, [
114
- ...Items<S>,
115
- ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<I>>
116
- ]>;
74
+ <S extends Self, A extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A): Builder<{}, [...Items<S>, ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<A>>]>;
75
+ <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B): Builder<{}, [...Items<S>, ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<B>>]>;
76
+ <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C): Builder<{}, [...Items<S>, ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<C>>]>;
77
+ <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D): Builder<{}, [...Items<S>, ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<D>>]>;
78
+ <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any, E extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D, ef: (e: D) => E): Builder<{}, [...Items<S>, ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<E>>]>;
79
+ <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any, E extends Route.RouteSet.Any, F extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D, ef: (e: D) => E, fg: (f: E) => F): Builder<{}, [...Items<S>, ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<F>>]>;
80
+ <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any, E extends Route.RouteSet.Any, F extends Route.RouteSet.Any, G extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D, ef: (e: D) => E, fg: (f: E) => F, gh: (g: F) => G): Builder<{}, [...Items<S>, ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<G>>]>;
81
+ <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any, E extends Route.RouteSet.Any, F extends Route.RouteSet.Any, G extends Route.RouteSet.Any, H extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D, ef: (e: D) => E, fg: (f: E) => F, gh: (g: F) => G, hi: (h: G) => H): Builder<{}, [...Items<S>, ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<H>>]>;
82
+ <S extends Self, A extends Route.RouteSet.Any, B extends Route.RouteSet.Any, C extends Route.RouteSet.Any, D extends Route.RouteSet.Any, E extends Route.RouteSet.Any, F extends Route.RouteSet.Any, G extends Route.RouteSet.Any, H extends Route.RouteSet.Any, I extends Route.RouteSet.Any>(this: S, ab: (a: EmptySet<M, BuilderBindings<S>>) => A, bc: (b: A) => B, cd: (c: B) => C, de: (d: C) => D, ef: (e: D) => E, fg: (f: E) => F, gh: (g: F) => G, hi: (h: G) => H, ij: (i: H) => I): Builder<{}, [...Items<S>, ...FlattenItems<M, BuilderBindings<S>, Route.RouteSet.Items<I>>]>;
117
83
  }
118
84
  export {};
119
85
  }
@@ -10,27 +10,18 @@ export const patch = makeMethodDescriber("PATCH");
10
10
  export const head = makeMethodDescriber("HEAD");
11
11
  export const options = makeMethodDescriber("OPTIONS");
12
12
  export const add = function (path, routes) {
13
- const baseItems = Route.isRouteSet(this)
14
- ? Route.items(this)
15
- : [];
16
- const routeSet = typeof routes === "function"
17
- ? routes(make([]))
18
- : routes;
13
+ const baseItems = Route.isRouteSet(this) ? Route.items(this) : [];
14
+ const routeSet = typeof routes === "function" ? routes(make([])) : routes;
19
15
  const routeItems = Route.items(routeSet);
20
16
  const newItems = routeItems.map((item) => {
21
17
  const itemDescriptor = Route.descriptor(item);
22
- const concatenatedPath = typeof itemDescriptor?.path === "string"
23
- ? path + itemDescriptor.path
24
- : path;
18
+ const concatenatedPath = typeof itemDescriptor?.path === "string" ? path + itemDescriptor.path : path;
25
19
  const newDescriptor = { ...itemDescriptor, path: concatenatedPath };
26
20
  return Route.isRoute(item)
27
21
  ? Route.make(item.handler, newDescriptor)
28
22
  : Route.set(Route.items(item), newDescriptor);
29
23
  });
30
- return make([
31
- ...baseItems,
32
- ...newItems,
33
- ]);
24
+ return make([...baseItems, ...newItems]);
34
25
  };
35
26
  const Proto = Object.assign(Object.create(null), {
36
27
  [RouteSetTypeId]: RouteSetTypeId,
@@ -55,9 +46,7 @@ function make(items) {
55
46
  }
56
47
  function makeMethodDescriber(method) {
57
48
  function describeMethod(...fs) {
58
- const baseItems = Route.isRouteSet(this)
59
- ? Route.items(this)
60
- : [];
49
+ const baseItems = Route.isRouteSet(this) ? Route.items(this) : [];
61
50
  const methodSet = Route.set([], { method });
62
51
  const f = Function.flow(...fs);
63
52
  const result = f(methodSet);
@@ -68,10 +57,7 @@ function makeMethodDescriber(method) {
68
57
  const newDescriptor = { method, ...itemDescriptor };
69
58
  return Route.make(item.handler, newDescriptor);
70
59
  });
71
- return make([
72
- ...baseItems,
73
- ...flattenedItems,
74
- ]);
60
+ return make([...baseItems, ...flattenedItems]);
75
61
  }
76
62
  return describeMethod;
77
63
  }
@@ -1,4 +1,4 @@
1
- import * as ParseResult from "effect/ParseResult";
1
+ import type * as ParseResult from "effect/ParseResult";
2
2
  import * as Schema from "effect/Schema";
3
3
  import type * as Scope from "effect/Scope";
4
4
  import * as Http from "./Http.ts";
@@ -63,3 +63,24 @@ export declare function schemaBodyForm<A, I extends Partial<Record<string, Reado
63
63
  body: A;
64
64
  }, unknown, RequestBodyError | ParseResult.ParseError, R | Scope.Scope>
65
65
  ]>;
66
+ /**
67
+ * Intercepts typed errors from downstream handlers, encodes them through the
68
+ * schema, and returns a JSON response with the given status code.
69
+ *
70
+ * Without `schemaError`, handler errors fall through to global catch during
71
+ * execution of request. `schemaError` short circuts error handling by
72
+ * return an error response immedietly.
73
+ *
74
+ * TODO: store the errors in runtime to enable generating OpenAPI and other
75
+ * goodies.
76
+ */
77
+ export declare function schemaError<A, I, R>(schema: Schema.Schema<A, I, R> & {
78
+ readonly status: number;
79
+ }): <D extends Route.RouteDescriptor.Any, SB extends {}, P extends Route.Route.Tuple>(self: Route.RouteSet.RouteSet<D, SB, P>) => Route.RouteSet.RouteSet<D, SB, [...P, Route.Route.Route<{}, {}, unknown, never, R>]>;
80
+ export declare function schemaError<A, I, R>(schema: Schema.Schema<A, I, R>, options: {
81
+ readonly status: number;
82
+ }): <D extends Route.RouteDescriptor.Any, SB extends {}, P extends Route.Route.Tuple>(self: Route.RouteSet.RouteSet<D, SB, P>) => Route.RouteSet.RouteSet<D, SB, [...P, Route.Route.Route<{}, {}, unknown, never, R>]>;
83
+ export declare function schemaSuccess<A, I, R>(schema: Schema.Schema<A, I, R>): <D extends Route.RouteDescriptor.Any, SB extends {}, P extends Route.Route.Tuple>(self: Route.RouteSet.RouteSet<D, SB, P>) => Route.RouteSet.RouteSet<D, SB, [
84
+ ...P,
85
+ Route.Route.Route<{}, {}, I, ParseResult.ParseError, R>
86
+ ]>;
@@ -1,7 +1,9 @@
1
1
  import * as Effect from "effect/Effect";
2
2
  import * as Schema from "effect/Schema";
3
+ import * as Entity from "./Entity.js";
3
4
  import * as Http from "./Http.js";
4
5
  import * as PathPattern from "./PathPattern.js";
6
+ import * as Route from "./Route.js";
5
7
  import * as RouteHook from "./RouteHook.js";
6
8
  export const RequestBodyError = (reason, cause) => ({ _tag: "RequestBodyError", reason, cause });
7
9
  export const File = Schema.TaggedStruct("File", {
@@ -153,3 +155,34 @@ export function schemaBodyForm(fields) {
153
155
  };
154
156
  }));
155
157
  }
158
+ export function schemaError(schema, options) {
159
+ const status = options?.status ?? schema.status;
160
+ if (typeof status !== "number") {
161
+ throw new Error("schemaError: status is required either via options or as a static property on the schema");
162
+ }
163
+ const encode = Schema.encode(schema);
164
+ const is = Schema.is(schema);
165
+ return function (self) {
166
+ const route = Route.make((_context, next) => Entity.resolve(next()).pipe(Effect.catchIf(is, (error) => Effect.map(Effect.orDie(encode(error)), (encoded) => Entity.make(encoded, { status })))));
167
+ const items = [
168
+ ...Route.items(self),
169
+ route,
170
+ ];
171
+ return Route.set(items, Route.descriptor(self));
172
+ };
173
+ }
174
+ export function schemaSuccess(schema) {
175
+ const encode = Schema.encodeUnknown(schema);
176
+ return function (self) {
177
+ const route = Route.make((_context, next) => Effect.flatMap(Entity.resolve(next()), (entity) => Effect.map(encode(entity.body), (encoded) => Entity.make(encoded, {
178
+ status: entity.status,
179
+ headers: entity.headers,
180
+ url: entity.url,
181
+ }))));
182
+ const items = [
183
+ ...Route.items(self),
184
+ route,
185
+ ];
186
+ return Route.set(items, Route.descriptor(self));
187
+ };
188
+ }
package/dist/RouteSse.js CHANGED
@@ -8,8 +8,7 @@ import * as StreamExtra from "./StreamExtra.js";
8
8
  const HEARTBEAT_INTERVAL = Duration.seconds(5);
9
9
  const HEARTBEAT = ": <3\n\n";
10
10
  function isTaggedEvent(event) {
11
- return Object.hasOwn(event, "_tag")
12
- && typeof event["_tag"] === "string";
11
+ return Object.hasOwn(event, "_tag") && typeof event["_tag"] === "string";
13
12
  }
14
13
  function formatSseEvent(event) {
15
14
  if (isTaggedEvent(event)) {
@@ -60,9 +59,7 @@ export function sse(handler) {
60
59
  };
61
60
  return Effect.map(getStream(), (eventStream) => {
62
61
  const formattedStream = Stream.map(eventStream, formatSseEvent);
63
- const heartbeat = Stream
64
- .repeat(Stream.succeed(HEARTBEAT), Schedule.spaced(HEARTBEAT_INTERVAL))
65
- .pipe(Stream.drop(1));
62
+ const heartbeat = Stream.repeat(Stream.succeed(HEARTBEAT), Schedule.spaced(HEARTBEAT_INTERVAL)).pipe(Stream.drop(1));
66
63
  const merged = Stream.merge(formattedStream, heartbeat, {
67
64
  haltStrategy: "left",
68
65
  });
@@ -70,16 +67,13 @@ export function sse(handler) {
70
67
  headers: {
71
68
  "content-type": "text/event-stream",
72
69
  "cache-control": "no-cache",
73
- "connection": "keep-alive",
70
+ connection: "keep-alive",
74
71
  },
75
72
  });
76
73
  });
77
74
  };
78
75
  const route = Route.make(sseHandler, { format: "text" });
79
- const items = [
80
- ...Route.items(self),
81
- route,
82
- ];
76
+ const items = [...Route.items(self), route];
83
77
  return Route.set(items, Route.descriptor(self));
84
78
  };
85
79
  }
@@ -1,6 +1,6 @@
1
1
  import * as PathPattern from "./PathPattern.ts";
2
2
  import * as Route from "./Route.ts";
3
- import * as RouteMount from "./RouteMount.ts";
3
+ import type * as RouteMount from "./RouteMount.ts";
4
4
  declare const TypeId: unique symbol;
5
5
  declare const RouteTreeRoutes: unique symbol;
6
6
  type MethodRoute = Route.Route.With<{
@@ -47,6 +47,7 @@ export type WalkDescriptor = {
47
47
  method: string;
48
48
  } & Route.RouteDescriptor.Any;
49
49
  export declare function walk(tree: RouteTree): Generator<RouteMount.MountedRoute>;
50
+ export declare function merge(a: RouteTree, b: RouteTree): RouteTree;
50
51
  export declare function isRouteTree(input: unknown): input is RouteTree;
51
52
  export interface LookupResult {
52
53
  route: RouteMount.MountedRoute;
package/dist/RouteTree.js CHANGED
@@ -11,27 +11,18 @@ function routes(tree) {
11
11
  function sortScore(path) {
12
12
  const segments = path.split("/");
13
13
  const greedyIdx = segments.findIndex((s) => s.endsWith("*") || s.endsWith("+"));
14
- const maxPriority = Math.max(...segments.map((s) => !s.startsWith(":")
15
- ? 0
16
- : s.endsWith("*")
17
- ? 4
18
- : s.endsWith("+")
19
- ? 3
20
- : s.endsWith("?")
21
- ? 2
22
- : 1), 0);
14
+ const maxPriority = Math.max(...segments.map((s) => !s.startsWith(":") ? 0 : s.endsWith("*") ? 4 : s.endsWith("+") ? 3 : s.endsWith("?") ? 2 : 1), 0);
23
15
  return greedyIdx === -1
24
- // non-greedy: sort by depth, then by max segment priority
25
- ? (segments.length << 16) + (maxPriority << 8)
26
- // greedy: sort after non-greedy, by greedy position (later = first), then priority
27
- : (1 << 24) + ((16 - greedyIdx) << 16) + (maxPriority << 8);
16
+ ? // non-greedy: sort by depth, then by max segment priority
17
+ (segments.length << 16) + (maxPriority << 8)
18
+ : // greedy: sort after non-greedy, by greedy position (later = first), then priority
19
+ (1 << 24) + ((16 - greedyIdx) << 16) + (maxPriority << 8);
28
20
  }
29
21
  function sortRoutes(input) {
30
22
  const keys = Object.keys(input).sort((a, b) => sortScore(a) - sortScore(b) || a.localeCompare(b));
31
23
  const sorted = {};
32
24
  for (const key of keys) {
33
- sorted[key] =
34
- input[key];
25
+ sorted[key] = input[key];
35
26
  }
36
27
  return sorted;
37
28
  }
@@ -74,6 +65,17 @@ export function* walk(tree) {
74
65
  yield* flattenRoutes(path, _routes[path]);
75
66
  }
76
67
  }
68
+ export function merge(a, b) {
69
+ const combined = { ...routes(a) };
70
+ for (const [path, items] of Object.entries(routes(b))) {
71
+ const key = path;
72
+ combined[key] = combined[key] ? [...combined[key], ...items] : items;
73
+ }
74
+ return {
75
+ [TypeId]: TypeId,
76
+ [RouteTreeRoutes]: sortRoutes(combined),
77
+ };
78
+ }
77
79
  export function isRouteTree(input) {
78
80
  return Predicate.hasProperty(input, TypeId);
79
81
  }
@@ -7,7 +7,7 @@ export interface Node {
7
7
  requiredWildcardName: string | null;
8
8
  optionalWildcardChild: Node | null;
9
9
  optionalWildcardName: string | null;
10
- routes: Route.Route.Route[];
10
+ routes: Array<Route.Route.Route>;
11
11
  }
12
12
  export interface RouteTrie {
13
13
  readonly methods: Record<string, Node>;
@@ -17,4 +17,4 @@ export interface LookupResult {
17
17
  params: Record<string, string>;
18
18
  }
19
19
  export declare function make(set: Route.RouteSet.Any): RouteTrie;
20
- export declare function lookup(trie: RouteTrie, method: string, path: string): LookupResult[];
20
+ export declare function lookup(trie: RouteTrie, method: string, path: string): Array<LookupResult>;
package/dist/RouteTrie.js CHANGED
@@ -62,9 +62,7 @@ function collectRoutes(items, parentPath, parentMethod) {
62
62
  const results = [];
63
63
  for (const item of items) {
64
64
  const desc = Route.descriptor(item);
65
- const currentPath = typeof desc?.path === "string"
66
- ? parentPath + desc.path
67
- : parentPath;
65
+ const currentPath = typeof desc?.path === "string" ? parentPath + desc.path : parentPath;
68
66
  const currentMethod = desc?.method ?? parentMethod;
69
67
  if (Route.isRoute(item)) {
70
68
  if (currentPath !== "") {
@@ -103,8 +101,7 @@ function lookupNode(node, segments, params) {
103
101
  for (const route of node.routes) {
104
102
  results.push({ route, params });
105
103
  }
106
- if (node.optionalWildcardChild
107
- && node.optionalWildcardChild.optionalWildcardName) {
104
+ if (node.optionalWildcardChild && node.optionalWildcardChild.optionalWildcardName) {
108
105
  for (const route of node.optionalWildcardChild.routes) {
109
106
  results.push({ route, params });
110
107
  }
@@ -120,8 +117,7 @@ function lookupNode(node, segments, params) {
120
117
  const newParams = { ...params, [node.paramChild.paramName]: segment };
121
118
  results.push(...lookupNode(node.paramChild, rest, newParams));
122
119
  }
123
- if (node.requiredWildcardChild
124
- && node.requiredWildcardChild.requiredWildcardName) {
120
+ if (node.requiredWildcardChild && node.requiredWildcardChild.requiredWildcardName) {
125
121
  const wildcardValue = segments.join("/");
126
122
  const newParams = {
127
123
  ...params,
@@ -131,8 +127,7 @@ function lookupNode(node, segments, params) {
131
127
  results.push({ route, params: newParams });
132
128
  }
133
129
  }
134
- if (node.optionalWildcardChild
135
- && node.optionalWildcardChild.optionalWildcardName) {
130
+ if (node.optionalWildcardChild && node.optionalWildcardChild.optionalWildcardName) {
136
131
  const wildcardValue = segments.join("/");
137
132
  const newParams = {
138
133
  ...params,
@@ -1,4 +1,4 @@
1
- import * as Schema from "effect/Schema";
1
+ import type * as Schema from "effect/Schema";
2
2
  import * as SchemaAST from "effect/SchemaAST";
3
3
  export declare function getBaseSchemaAST(schema: Schema.Schema.Any): SchemaAST.AST;
4
4
  export declare function isOptional(schema: Schema.Schema.Any): boolean;
@@ -0,0 +1,27 @@
1
+ export declare const SocketErrorTypeId: unique symbol;
2
+ export type SocketErrorTypeId = typeof SocketErrorTypeId;
3
+ export declare const isSocketError: (u: unknown) => u is SocketError;
4
+ export type SocketError = SocketGenericError | SocketCloseError;
5
+ declare const SocketGenericError_base: new <A extends Record<string, any>>(args: import("effect/Types").Simplify<A>) => import("effect/Cause").YieldableError & Record<typeof SocketErrorTypeId, typeof SocketErrorTypeId> & {
6
+ readonly _tag: "SocketError";
7
+ } & Readonly<A>;
8
+ export declare class SocketGenericError extends SocketGenericError_base<{
9
+ readonly reason: "Write" | "Read" | "Open" | "OpenTimeout";
10
+ readonly cause: unknown;
11
+ }> {
12
+ get message(): string;
13
+ }
14
+ declare const SocketCloseError_base: new <A extends Record<string, any>>(args: import("effect/Types").Simplify<A>) => import("effect/Cause").YieldableError & Record<typeof SocketErrorTypeId, typeof SocketErrorTypeId> & {
15
+ readonly _tag: "SocketError";
16
+ } & Readonly<A>;
17
+ export declare class SocketCloseError extends SocketCloseError_base<{
18
+ readonly reason: "Close";
19
+ readonly code: number;
20
+ readonly closeReason?: string | undefined;
21
+ }> {
22
+ static is(u: unknown): u is SocketCloseError;
23
+ static isClean(isClean: (code: number) => boolean): (u: unknown) => u is SocketCloseError;
24
+ get message(): string;
25
+ }
26
+ export declare const defaultCloseCodeIsError: (code: number) => boolean;
27
+ export {};
package/dist/Socket.js CHANGED
@@ -1,37 +1,29 @@
1
1
  /*
2
2
  * Adapted from @effect/platform
3
3
  */
4
- import * as Predicate from "effect/Predicate"
5
- import * as PlatformError from "./PlatformError.js"
6
-
7
- export const SocketErrorTypeId = Symbol.for("@effect/platform/Socket/SocketError")
8
-
9
- export const isSocketError = (u) =>
10
- Predicate.hasProperty(u, SocketErrorTypeId)
11
-
4
+ import * as Predicate from "effect/Predicate";
5
+ import * as PlatformError from "./PlatformError.js";
6
+ export const SocketErrorTypeId = Symbol.for("@effect/platform/Socket/SocketError");
7
+ export const isSocketError = (u) => Predicate.hasProperty(u, SocketErrorTypeId);
12
8
  export class SocketGenericError extends PlatformError.TypeIdError(SocketErrorTypeId, "SocketError") {
13
- get message() {
14
- return `An error occurred during ${this.reason}`
15
- }
9
+ get message() {
10
+ return `An error occurred during ${this.reason}`;
11
+ }
16
12
  }
17
-
18
13
  export class SocketCloseError extends PlatformError.TypeIdError(SocketErrorTypeId, "SocketError") {
19
- static is(u) {
20
- return isSocketError(u) && u.reason === "Close"
21
- }
22
-
23
- static isClean(isClean) {
24
- return function(u) {
25
- return SocketCloseError.is(u) && isClean(u.code)
14
+ static is(u) {
15
+ return isSocketError(u) && u.reason === "Close";
16
+ }
17
+ static isClean(isClean) {
18
+ return function (u) {
19
+ return SocketCloseError.is(u) && isClean(u.code);
20
+ };
26
21
  }
27
- }
28
-
29
- get message() {
30
- if (this.closeReason) {
31
- return `${this.reason}: ${this.code}: ${this.closeReason}`
22
+ get message() {
23
+ if (this.closeReason) {
24
+ return `${this.reason}: ${this.code}: ${this.closeReason}`;
25
+ }
26
+ return `${this.reason}: ${this.code}`;
32
27
  }
33
- return `${this.reason}: ${this.code}`
34
- }
35
28
  }
36
-
37
- export const defaultCloseCodeIsError = (code) => code !== 1000 && code !== 1006
29
+ export const defaultCloseCodeIsError = (code) => code !== 1000 && code !== 1006;
package/dist/Sql.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ import * as Context from "effect/Context";
2
+ import type * as Effect from "effect/Effect";
3
+ import type * as Scope from "effect/Scope";
4
+ declare const SqlError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
5
+ readonly _tag: "SqlError";
6
+ } & Readonly<A>;
7
+ export declare class SqlError extends SqlError_base<{
8
+ readonly code: string;
9
+ readonly message: string;
10
+ readonly cause?: unknown;
11
+ }> {
12
+ }
13
+ export interface SqlQuery {
14
+ <T = any>(strings: TemplateStringsArray, ...values: Array<unknown>): Effect.Effect<ReadonlyArray<T>, SqlError>;
15
+ readonly unsafe: <T = any>(query: string, values?: Array<unknown>) => Effect.Effect<ReadonlyArray<T>, SqlError>;
16
+ readonly values: {
17
+ <T extends Record<string, unknown>>(obj: T | ReadonlyArray<T>): SqlHelper<T>;
18
+ <T extends Record<string, unknown>, K extends keyof T>(obj: T | ReadonlyArray<T>, ...columns: [K, ...Array<K>]): SqlHelper<Pick<T, K>>;
19
+ };
20
+ }
21
+ export interface SqlClient extends SqlQuery {
22
+ readonly withTransaction: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, SqlError | E, R>;
23
+ readonly reserve: Effect.Effect<SqlQuery, SqlError, Scope.Scope>;
24
+ readonly close: (options?: {
25
+ readonly timeout?: number;
26
+ }) => Effect.Effect<void, SqlError>;
27
+ readonly use: <T>(fn: (driver: any) => Promise<T> | T) => Effect.Effect<T, SqlError>;
28
+ }
29
+ export interface SqlHelper<T> {
30
+ readonly value: ReadonlyArray<T>;
31
+ readonly columns: ReadonlyArray<keyof T>;
32
+ }
33
+ export declare const SqlClient: Context.Tag<SqlClient, SqlClient>;
34
+ export {};
package/dist/Sql.js ADDED
@@ -0,0 +1,5 @@
1
+ import * as Context from "effect/Context";
2
+ import * as Data from "effect/Data";
3
+ export class SqlError extends Data.TaggedError("SqlError") {
4
+ }
5
+ export const SqlClient = Context.GenericTag("effect-start/Sql/SqlClient");