effect-start 0.22.0 → 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 -10
  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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect-start",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "src/",
@@ -32,6 +32,16 @@
32
32
  "bun": "./src/testing/index.ts",
33
33
  "default": "./dist/testing/index.js"
34
34
  },
35
+ "./console": {
36
+ "types": "./dist/console/index.d.ts",
37
+ "bun": "./src/console/index.ts",
38
+ "default": "./dist/console/index.js"
39
+ },
40
+ "./sql/*": {
41
+ "types": "./dist/sql/*/index.d.ts",
42
+ "bun": "./src/sql/*/index.ts",
43
+ "default": "./dist/sql/*/index.js"
44
+ },
35
45
  "./x/*": {
36
46
  "types": "./dist/x/*/index.d.ts",
37
47
  "bun": "./src/x/*/index.ts",
@@ -42,6 +52,11 @@
42
52
  "bun": "./src/x/tailwind/plugin.ts",
43
53
  "default": "./dist/x/tailwind/plugin.js"
44
54
  },
55
+ "./System": {
56
+ "types": "./dist/System.d.ts",
57
+ "bun": "./src/System.ts",
58
+ "default": "./dist/System.js"
59
+ },
45
60
  "./Unique": {
46
61
  "types": "./dist/Unique.d.ts",
47
62
  "bun": "./src/Unique.ts",
@@ -69,12 +84,12 @@
69
84
  "default": "./dist/hyper/index.js"
70
85
  },
71
86
  "./jsx-runtime": {
72
- "types": "./dist/hyper/jsx-runtime.d.ts",
87
+ "types": "./src/hyper/jsx-runtime.ts",
73
88
  "bun": "./src/hyper/jsx-runtime.ts",
74
89
  "default": "./dist/hyper/jsx-runtime.js"
75
90
  },
76
91
  "./jsx-dev-runtime": {
77
- "types": "./dist/hyper/jsx-runtime.d.ts",
92
+ "types": "./src/hyper/jsx-runtime.ts",
78
93
  "bun": "./src/hyper/jsx-runtime.ts",
79
94
  "default": "./dist/hyper/jsx-runtime.js"
80
95
  },
@@ -91,23 +106,20 @@
91
106
  "format": "bunx oxfmt",
92
107
  "lint": "oxlint --import-plugin --tsconfig tsconfig.json src/",
93
108
  "test": "bun test ./src/",
109
+ "test-sql": "bun add --no-save mssql @types/mssql postgres && TEST_SQL=1 bun test ./src/sql/",
94
110
  "deploy": "bunx --bun npm publish --access public"
95
111
  },
96
112
  "devDependencies": {
97
- "@effect/language-service": "^0.62.3",
98
113
  "@types/bun": "^1.3.4",
99
- "@types/react": "^19.2.7",
100
- "@types/react-dom": "^19.2.3",
114
+ "@types/jsdom": "^27.0.0",
101
115
  "effect-memfs": "^0.8.0",
102
- "expect-type": "^1.3.0",
116
+ "jsdom": "^28.0.0",
103
117
  "oxfmt": "latest",
104
118
  "oxlint": "^1.43.0",
105
119
  "tailwindcss": "^4.1.18",
106
- "ts-namespace-import": "nounder/ts-namespace-import#140c405",
107
120
  "typescript": "^5.9.3"
108
121
  },
109
122
  "peerDependencies": {
110
- "@effect/platform": ">=0.93.0",
111
- "effect": ">=3.19.0"
123
+ "effect": "^3.19.11"
112
124
  }
113
125
  }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Adapted from upcomnig Effect 4 aka effect-smol.
3
+ *
4
+ * Kept a minimal interface without tempaltes and file descirptor
5
+ * to keep it compatible if it lands in the core (ie. not in seperate platform package.)
6
+ */
7
+ import * as Context from "effect/Context"
8
+ import * as Effect from "effect/Effect"
9
+ import * as Pipeable from "effect/Pipeable"
10
+ import * as Predicate from "effect/Predicate"
11
+ import type * as Scope from "effect/Scope"
12
+ import type * as Sink from "effect/Sink"
13
+ import type * as Stream from "effect/Stream"
14
+ import * as Utils from "effect/Utils"
15
+
16
+ import type * as PlatformError from "./PlatformError.ts"
17
+
18
+ const TypeId: unique symbol = Symbol.for("effect-start/ChildProcess/Command")
19
+
20
+ type TypeId = typeof TypeId
21
+
22
+ type Stdio = "pipe" | "inherit" | "ignore"
23
+
24
+ export interface Command extends Pipeable.Pipeable {
25
+ readonly [TypeId]: TypeId
26
+ readonly command: string
27
+ readonly args: ReadonlyArray<string>
28
+ readonly cwd?: string
29
+ readonly env?: Record<string, string>
30
+ readonly stdin?: Stdio
31
+ readonly stdout?: Stdio
32
+ readonly stderr?: Stdio
33
+ readonly detached?: boolean
34
+ [Symbol.iterator](): Effect.EffectGenerator<
35
+ Effect.Effect<
36
+ ChildProcessHandle,
37
+ PlatformError.PlatformError,
38
+ ChildProcessSpawner | Scope.Scope
39
+ >
40
+ >
41
+ }
42
+
43
+ export namespace Command {
44
+ export interface Options {
45
+ readonly cwd?: string
46
+ readonly env?: Record<string, string>
47
+ readonly stdin?: Stdio
48
+ readonly stdout?: Stdio
49
+ readonly stderr?: Stdio
50
+ readonly detached?: boolean
51
+ }
52
+ }
53
+
54
+ const CommandProto = {
55
+ [TypeId]: TypeId,
56
+ pipe() {
57
+ return Pipeable.pipeArguments(this, arguments)
58
+ },
59
+ [Symbol.iterator](this: Command) {
60
+ return new Utils.SingleShotGen(new Utils.YieldWrap(spawn(this))) as any
61
+ },
62
+ }
63
+
64
+ export const isCommand = (u: unknown): u is Command => Predicate.hasProperty(u, TypeId)
65
+
66
+ export const make = (
67
+ command: string,
68
+ args?: ReadonlyArray<string>,
69
+ options?: Command.Options,
70
+ ): Command =>
71
+ Object.assign(Object.create(CommandProto), {
72
+ command,
73
+ args: args ?? [],
74
+ ...options,
75
+ })
76
+
77
+ export type Signal =
78
+ | "SIGABRT"
79
+ | "SIGALRM"
80
+ | "SIGBUS"
81
+ | "SIGCHLD"
82
+ | "SIGCONT"
83
+ | "SIGFPE"
84
+ | "SIGHUP"
85
+ | "SIGILL"
86
+ | "SIGINT"
87
+ | "SIGIO"
88
+ | "SIGIOT"
89
+ | "SIGKILL"
90
+ | "SIGPIPE"
91
+ | "SIGPOLL"
92
+ | "SIGPROF"
93
+ | "SIGPWR"
94
+ | "SIGQUIT"
95
+ | "SIGSEGV"
96
+ | "SIGSTKFLT"
97
+ | "SIGSTOP"
98
+ | "SIGSYS"
99
+ | "SIGTERM"
100
+ | "SIGTRAP"
101
+ | "SIGTSTP"
102
+ | "SIGTTIN"
103
+ | "SIGTTOU"
104
+ | "SIGUNUSED"
105
+ | "SIGURG"
106
+ | "SIGUSR1"
107
+ | "SIGUSR2"
108
+ | "SIGVTALRM"
109
+ | "SIGWINCH"
110
+ | "SIGXCPU"
111
+ | "SIGXFSZ"
112
+ | "SIGBREAK"
113
+ | "SIGLOST"
114
+ | "SIGINFO"
115
+
116
+ export interface KillOptions {
117
+ readonly killSignal?: Signal | undefined
118
+ }
119
+
120
+ export interface ChildProcessHandle {
121
+ readonly pid: number
122
+ readonly exitCode: Effect.Effect<number, PlatformError.PlatformError>
123
+ readonly isRunning: Effect.Effect<boolean, PlatformError.PlatformError>
124
+ readonly kill: (options?: KillOptions) => Effect.Effect<void, PlatformError.PlatformError>
125
+ readonly stdin: Sink.Sink<void, Uint8Array, never, PlatformError.PlatformError>
126
+ readonly stdout: Stream.Stream<Uint8Array, PlatformError.PlatformError>
127
+ readonly stderr: Stream.Stream<Uint8Array, PlatformError.PlatformError>
128
+ }
129
+
130
+ export class ChildProcessSpawner extends Context.Tag("effect-start/ChildProcessSpawner")<
131
+ ChildProcessSpawner,
132
+ {
133
+ readonly spawn: (
134
+ command: Command,
135
+ ) => Effect.Effect<ChildProcessHandle, PlatformError.PlatformError, Scope.Scope>
136
+ }
137
+ >() {}
138
+
139
+ export const spawn = (
140
+ command: Command,
141
+ ): Effect.Effect<
142
+ ChildProcessHandle,
143
+ PlatformError.PlatformError,
144
+ ChildProcessSpawner | Scope.Scope
145
+ > => Effect.flatMap(ChildProcessSpawner, (spawner) => spawner.spawn(command))
@@ -4,7 +4,6 @@
4
4
  import type * as Cause from "effect/Cause"
5
5
  import * as Data from "effect/Data"
6
6
  import * as Predicate from "effect/Predicate"
7
- import * as Schema from "effect/Schema"
8
7
  import type * as Types from "effect/Types"
9
8
 
10
9
  export const TypeId: unique symbol = Symbol.for("@effect/platform/Error/PlatformError")
@@ -27,24 +26,25 @@ export const TypeIdError = <const TypeId extends symbol, const Tag extends strin
27
26
  return Base as any
28
27
  }
29
28
 
30
- export const Module = Schema.Literal(
31
- "Clipboard",
32
- "Command",
33
- "FileSystem",
34
- "KeyValueStore",
35
- "Path",
36
- "Stream",
37
- "Terminal",
38
- )
29
+ export type SystemErrorReason =
30
+ | "AlreadyExists"
31
+ | "BadResource"
32
+ | "Busy"
33
+ | "InvalidData"
34
+ | "NotFound"
35
+ | "PermissionDenied"
36
+ | "TimedOut"
37
+ | "UnexpectedEof"
38
+ | "Unknown"
39
+ | "WouldBlock"
40
+ | "WriteZero"
39
41
 
40
- export class BadArgument extends Schema.TaggedError<BadArgument>(
41
- "@effect/platform/Error/BadArgument",
42
- )("BadArgument", {
43
- module: Module,
44
- method: Schema.String,
45
- description: Schema.optional(Schema.String),
46
- cause: Schema.optional(Schema.Defect),
47
- }) {
42
+ export class BadArgument extends Data.TaggedError("BadArgument")<{
43
+ module: string
44
+ method: string
45
+ description?: string | undefined
46
+ cause?: unknown
47
+ }> {
48
48
  readonly [TypeId]: typeof TypeId = TypeId
49
49
 
50
50
  get message(): string {
@@ -52,33 +52,15 @@ export class BadArgument extends Schema.TaggedError<BadArgument>(
52
52
  }
53
53
  }
54
54
 
55
- export const SystemErrorReason = Schema.Literal(
56
- "AlreadyExists",
57
- "BadResource",
58
- "Busy",
59
- "InvalidData",
60
- "NotFound",
61
- "PermissionDenied",
62
- "TimedOut",
63
- "UnexpectedEof",
64
- "Unknown",
65
- "WouldBlock",
66
- "WriteZero",
67
- )
68
-
69
- export type SystemErrorReason = typeof SystemErrorReason.Type
70
-
71
- export class SystemError extends Schema.TaggedError<SystemError>(
72
- "@effect/platform/Error/SystemError",
73
- )("SystemError", {
74
- reason: SystemErrorReason,
75
- module: Module,
76
- method: Schema.String,
77
- description: Schema.optional(Schema.String),
78
- syscall: Schema.optional(Schema.String),
79
- pathOrDescriptor: Schema.optional(Schema.Union(Schema.String, Schema.Number)),
80
- cause: Schema.optional(Schema.Defect),
81
- }) {
55
+ export class SystemError extends Data.TaggedError("SystemError")<{
56
+ reason: SystemErrorReason
57
+ module: string
58
+ method: string
59
+ description?: string | undefined
60
+ syscall?: string | undefined
61
+ pathOrDescriptor?: string | number | undefined
62
+ cause?: unknown
63
+ }> {
82
64
  readonly [TypeId]: typeof TypeId = TypeId
83
65
 
84
66
  get message(): string {
@@ -89,8 +71,3 @@ export class SystemError extends Schema.TaggedError<SystemError>(
89
71
  }
90
72
 
91
73
  export type PlatformError = BadArgument | SystemError
92
-
93
- export const PlatformError: Schema.Union<[typeof BadArgument, typeof SystemError]> = Schema.Union(
94
- BadArgument,
95
- SystemError,
96
- )
package/src/Route.ts CHANGED
@@ -221,10 +221,10 @@ export { sse } from "./RouteSse.ts"
221
221
 
222
222
  export function redirect(
223
223
  url: string | URL,
224
- status: 301 | 302 | 303 | 307 | 308 = 302,
224
+ options?: { status?: 301 | 302 | 303 | 307 | 308 },
225
225
  ): Entity.Entity<""> {
226
226
  return Entity.make("", {
227
- status,
227
+ status: options?.status ?? 302,
228
228
  headers: {
229
229
  location: url instanceof URL ? url.href : url,
230
230
  },
@@ -0,0 +1,76 @@
1
+ import * as Schema from "effect/Schema"
2
+
3
+ export class BadRequest extends Schema.TaggedError<BadRequest>()("BadRequest", {
4
+ message: Schema.String,
5
+ }) {
6
+ static readonly status = 400
7
+ }
8
+
9
+ export class Unauthorized extends Schema.TaggedError<Unauthorized>()("Unauthorized", {
10
+ message: Schema.String,
11
+ }) {
12
+ static readonly status = 401
13
+ }
14
+
15
+ export class Forbidden extends Schema.TaggedError<Forbidden>()("Forbidden", {
16
+ message: Schema.String,
17
+ }) {
18
+ static readonly status = 403
19
+ }
20
+
21
+ export class NotFound extends Schema.TaggedError<NotFound>()("NotFound", {
22
+ message: Schema.String,
23
+ }) {
24
+ static readonly status = 404
25
+ }
26
+
27
+ export class MethodNotAllowed extends Schema.TaggedError<MethodNotAllowed>()("MethodNotAllowed", {
28
+ message: Schema.String,
29
+ }) {
30
+ static readonly status = 405
31
+ }
32
+
33
+ export class Conflict extends Schema.TaggedError<Conflict>()("Conflict", {
34
+ message: Schema.String,
35
+ }) {
36
+ static readonly status = 409
37
+ }
38
+
39
+ export class Gone extends Schema.TaggedError<Gone>()("Gone", {
40
+ message: Schema.String,
41
+ }) {
42
+ static readonly status = 410
43
+ }
44
+
45
+ export class UnprocessableEntity extends Schema.TaggedError<UnprocessableEntity>()(
46
+ "UnprocessableEntity",
47
+ { message: Schema.String },
48
+ ) {
49
+ static readonly status = 422
50
+ }
51
+
52
+ export class TooManyRequests extends Schema.TaggedError<TooManyRequests>()("TooManyRequests", {
53
+ message: Schema.String,
54
+ }) {
55
+ static readonly status = 429
56
+ }
57
+
58
+ export class InternalServerError extends Schema.TaggedError<InternalServerError>()(
59
+ "InternalServerError",
60
+ { message: Schema.String },
61
+ ) {
62
+ static readonly status = 500
63
+ }
64
+
65
+ export class NotImplemented extends Schema.TaggedError<NotImplemented>()("NotImplemented", {
66
+ message: Schema.String,
67
+ }) {
68
+ static readonly status = 501
69
+ }
70
+
71
+ export class ServiceUnavailable extends Schema.TaggedError<ServiceUnavailable>()(
72
+ "ServiceUnavailable",
73
+ { message: Schema.String },
74
+ ) {
75
+ static readonly status = 503
76
+ }
package/src/RouteHttp.ts CHANGED
@@ -200,11 +200,15 @@ export const toWebHandlerRuntime = <R>(runtime: Runtime.Runtime<R>) => {
200
200
  const allRoutes = [...wildcards, ...methodRoutes]
201
201
  const selectedFormat = determineSelectedFormat(accept, allRoutes)
202
202
 
203
- const hasSpecificFormatRoutes = allRoutes.some((r) => {
203
+ const specificFormats = new Set<string>()
204
+ let hasWildcardFormatRoutes = false
205
+ for (const r of allRoutes) {
204
206
  const format = Route.descriptor(r).format
205
- return format && format !== "*"
206
- })
207
- const hasWildcardFormatRoutes = allRoutes.some((r) => Route.descriptor(r).format === "*")
207
+ if (format === "*") hasWildcardFormatRoutes = true
208
+ else if (format) specificFormats.add(format)
209
+ }
210
+ const hasSpecificFormatRoutes = specificFormats.size > 0
211
+ const varyAccept = specificFormats.size > 1
208
212
 
209
213
  if (selectedFormat === undefined && hasSpecificFormatRoutes && !hasWildcardFormatRoutes) {
210
214
  return Promise.resolve(respondError({ status: 406, message: "not acceptable" }))
@@ -272,7 +276,11 @@ export const toWebHandlerRuntime = <R>(runtime: Runtime.Runtime<R>) => {
272
276
  return respondError({ status: 406, message: "not acceptable" })
273
277
  }
274
278
 
275
- return yield* toResponse(entity, selectedFormat, runtime)
279
+ const response = yield* toResponse(entity, selectedFormat, runtime)
280
+ if (varyAccept) {
281
+ response.headers.set("vary", "Accept")
282
+ }
283
+ return response
276
284
  })
277
285
 
278
286
  if (tracerDisabled) {
@@ -2,9 +2,10 @@ import * as Effect from "effect/Effect"
2
2
  import type * as ParseResult from "effect/ParseResult"
3
3
  import * as Schema from "effect/Schema"
4
4
  import type * as Scope from "effect/Scope"
5
+ import * as Entity from "./Entity.ts"
5
6
  import * as Http from "./Http.ts"
6
7
  import * as PathPattern from "./PathPattern.ts"
7
- import type * as Route from "./Route.ts"
8
+ import * as Route from "./Route.ts"
8
9
  import * as RouteHook from "./RouteHook.ts"
9
10
 
10
11
  export interface RequestBodyError {
@@ -287,3 +288,97 @@ export function schemaBodyForm<
287
288
  }),
288
289
  )
289
290
  }
291
+
292
+ /**
293
+ * Intercepts typed errors from downstream handlers, encodes them through the
294
+ * schema, and returns a JSON response with the given status code.
295
+ *
296
+ * Without `schemaError`, handler errors fall through to global catch during
297
+ * execution of request. `schemaError` short circuts error handling by
298
+ * return an error response immedietly.
299
+ *
300
+ * TODO: store the errors in runtime to enable generating OpenAPI and other
301
+ * goodies.
302
+ */
303
+ export function schemaError<A, I, R>(
304
+ schema: Schema.Schema<A, I, R> & { readonly status: number },
305
+ ): <D extends Route.RouteDescriptor.Any, SB extends {}, P extends Route.Route.Tuple>(
306
+ self: Route.RouteSet.RouteSet<D, SB, P>,
307
+ ) => Route.RouteSet.RouteSet<D, SB, [...P, Route.Route.Route<{}, {}, unknown, never, R>]>
308
+ export function schemaError<A, I, R>(
309
+ schema: Schema.Schema<A, I, R>,
310
+ options: { readonly status: number },
311
+ ): <D extends Route.RouteDescriptor.Any, SB extends {}, P extends Route.Route.Tuple>(
312
+ self: Route.RouteSet.RouteSet<D, SB, P>,
313
+ ) => Route.RouteSet.RouteSet<D, SB, [...P, Route.Route.Route<{}, {}, unknown, never, R>]>
314
+ export function schemaError<A, I, R>(
315
+ schema: Schema.Schema<A, I, R> & { readonly status?: number },
316
+ options?: { readonly status: number },
317
+ ): <D extends Route.RouteDescriptor.Any, SB extends {}, P extends Route.Route.Tuple>(
318
+ self: Route.RouteSet.RouteSet<D, SB, P>,
319
+ ) => Route.RouteSet.RouteSet<D, SB, [...P, Route.Route.Route<{}, {}, unknown, never, R>]> {
320
+ const status = options?.status ?? (schema as any).status
321
+ if (typeof status !== "number") {
322
+ throw new Error(
323
+ "schemaError: status is required either via options or as a static property on the schema",
324
+ )
325
+ }
326
+ const encode = Schema.encode(schema)
327
+ const is = Schema.is(schema)
328
+ return function <D extends Route.RouteDescriptor.Any, SB extends {}, P extends Route.Route.Tuple>(
329
+ self: Route.RouteSet.RouteSet<D, SB, P>,
330
+ ): Route.RouteSet.RouteSet<D, SB, [...P, Route.Route.Route<{}, {}, unknown, never, R>]> {
331
+ const route = Route.make<{}, {}, unknown, never, R>((_context, next) =>
332
+ Entity.resolve(next()).pipe(
333
+ Effect.catchIf(is, (error) =>
334
+ Effect.map(Effect.orDie(encode(error)), (encoded) => Entity.make(encoded, { status })),
335
+ ),
336
+ ),
337
+ )
338
+
339
+ const items: [...P, Route.Route.Route<{}, {}, unknown, never, R>] = [
340
+ ...Route.items(self),
341
+ route,
342
+ ]
343
+
344
+ return Route.set(items, Route.descriptor(self))
345
+ }
346
+ }
347
+
348
+ export function schemaSuccess<A, I, R>(
349
+ schema: Schema.Schema<A, I, R>,
350
+ ): <D extends Route.RouteDescriptor.Any, SB extends {}, P extends Route.Route.Tuple>(
351
+ self: Route.RouteSet.RouteSet<D, SB, P>,
352
+ ) => Route.RouteSet.RouteSet<
353
+ D,
354
+ SB,
355
+ [...P, Route.Route.Route<{}, {}, I, ParseResult.ParseError, R>]
356
+ > {
357
+ const encode = Schema.encodeUnknown(schema)
358
+ return function <D extends Route.RouteDescriptor.Any, SB extends {}, P extends Route.Route.Tuple>(
359
+ self: Route.RouteSet.RouteSet<D, SB, P>,
360
+ ): Route.RouteSet.RouteSet<
361
+ D,
362
+ SB,
363
+ [...P, Route.Route.Route<{}, {}, I, ParseResult.ParseError, R>]
364
+ > {
365
+ const route = Route.make<{}, {}, I, ParseResult.ParseError, R>((_context, next) =>
366
+ Effect.flatMap(Entity.resolve(next()), (entity) =>
367
+ Effect.map(encode(entity.body), (encoded) =>
368
+ Entity.make(encoded, {
369
+ status: entity.status,
370
+ headers: entity.headers,
371
+ url: entity.url,
372
+ }),
373
+ ),
374
+ ),
375
+ )
376
+
377
+ const items: [...P, Route.Route.Route<{}, {}, I, ParseResult.ParseError, R>] = [
378
+ ...Route.items(self),
379
+ route,
380
+ ]
381
+
382
+ return Route.set(items, Route.descriptor(self))
383
+ }
384
+ }
package/src/RouteTree.ts CHANGED
@@ -147,6 +147,18 @@ export function* walk(tree: RouteTree): Generator<RouteMount.MountedRoute> {
147
147
  }
148
148
  }
149
149
 
150
+ export function merge(a: RouteTree, b: RouteTree): RouteTree {
151
+ const combined: RouteMap = { ...routes(a) }
152
+ for (const [path, items] of Object.entries(routes(b))) {
153
+ const key = path as PathPattern.PathPattern
154
+ combined[key] = combined[key] ? [...combined[key], ...items] : items
155
+ }
156
+ return {
157
+ [TypeId]: TypeId,
158
+ [RouteTreeRoutes]: sortRoutes(combined),
159
+ } as RouteTree
160
+ }
161
+
150
162
  export function isRouteTree(input: unknown): input is RouteTree {
151
163
  return Predicate.hasProperty(input, TypeId)
152
164
  }
package/src/Sql.ts ADDED
@@ -0,0 +1,51 @@
1
+ import * as Context from "effect/Context"
2
+ import * as Data from "effect/Data"
3
+ import type * as Effect from "effect/Effect"
4
+ import type * as Scope from "effect/Scope"
5
+
6
+ export class SqlError extends Data.TaggedError("SqlError")<{
7
+ readonly code: string
8
+ readonly message: string
9
+ readonly cause?: unknown
10
+ }> {}
11
+
12
+ export interface SqlQuery {
13
+ <T = any>(
14
+ strings: TemplateStringsArray,
15
+ ...values: Array<unknown>
16
+ ): Effect.Effect<ReadonlyArray<T>, SqlError>
17
+
18
+ readonly unsafe: <T = any>(
19
+ query: string,
20
+ values?: Array<unknown>,
21
+ ) => Effect.Effect<ReadonlyArray<T>, SqlError>
22
+
23
+ readonly values: {
24
+ <T extends Record<string, unknown>>(obj: T | ReadonlyArray<T>): SqlHelper<T>
25
+ <T extends Record<string, unknown>, K extends keyof T>(
26
+ obj: T | ReadonlyArray<T>,
27
+ ...columns: [K, ...Array<K>]
28
+ ): SqlHelper<Pick<T, K>>
29
+ }
30
+ }
31
+
32
+ export interface SqlClient extends SqlQuery {
33
+ readonly withTransaction: <A, E, R>(
34
+ self: Effect.Effect<A, E, R>,
35
+ ) => Effect.Effect<A, SqlError | E, R>
36
+
37
+ readonly reserve: Effect.Effect<SqlQuery, SqlError, Scope.Scope>
38
+
39
+ readonly close: (options?: { readonly timeout?: number }) => Effect.Effect<void, SqlError>
40
+
41
+ readonly use: <T>(fn: (driver: any) => Promise<T> | T) => Effect.Effect<T, SqlError>
42
+ }
43
+
44
+ export interface SqlHelper<T> {
45
+ readonly value: ReadonlyArray<T>
46
+ readonly columns: ReadonlyArray<keyof T>
47
+ }
48
+
49
+ export const SqlClient: Context.Tag<SqlClient, SqlClient> = Context.GenericTag<SqlClient>(
50
+ "effect-start/Sql/SqlClient",
51
+ )