effect-start 0.23.0 → 0.25.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 (356) hide show
  1. package/dist/ChildProcess.js +32 -20
  2. package/dist/Commander.js +377 -293
  3. package/dist/ContentNegotiation.js +424 -318
  4. package/dist/Cookies.js +340 -271
  5. package/dist/Development.js +85 -49
  6. package/dist/Effectify.js +22 -14
  7. package/dist/Entity.js +260 -195
  8. package/dist/Fetch.js +192 -0
  9. package/dist/FilePathPattern.js +88 -77
  10. package/dist/FileRouter.js +192 -136
  11. package/dist/FileRouterCodegen.js +262 -191
  12. package/dist/FileSystem.js +126 -64
  13. package/dist/Http.js +96 -77
  14. package/dist/PathPattern.js +311 -273
  15. package/dist/PlatformError.js +36 -21
  16. package/dist/PlatformRuntime.js +65 -40
  17. package/dist/Route.js +122 -79
  18. package/dist/RouteBody.js +83 -58
  19. package/dist/RouteError.js +46 -25
  20. package/dist/RouteHook.js +58 -34
  21. package/dist/RouteHttp.js +346 -237
  22. package/dist/RouteHttpTracer.js +86 -58
  23. package/dist/RouteMount.js +81 -58
  24. package/dist/RouteSchema.js +253 -170
  25. package/dist/RouteSse.js +87 -72
  26. package/dist/RouteTree.js +99 -73
  27. package/dist/RouteTrie.js +160 -133
  28. package/dist/SchemaExtra.js +87 -62
  29. package/dist/Socket.js +32 -21
  30. package/dist/SqlIntrospect.js +317 -268
  31. package/dist/Start.js +55 -25
  32. package/dist/StartApp.js +3 -21
  33. package/dist/StreamExtra.js +109 -74
  34. package/dist/System.js +37 -21
  35. package/dist/TuplePathPattern.js +64 -58
  36. package/dist/Unique.js +159 -120
  37. package/dist/Values.js +48 -32
  38. package/dist/bun/BunBundle.js +158 -109
  39. package/dist/bun/BunChildProcessSpawner.js +121 -82
  40. package/dist/bun/BunImportTrackerPlugin.js +85 -63
  41. package/dist/bun/BunRoute.js +135 -99
  42. package/dist/bun/BunRuntime.js +39 -29
  43. package/dist/bun/BunServer.js +268 -140
  44. package/dist/bun/BunVirtualFilesPlugin.js +47 -33
  45. package/dist/bun/_BunEnhancedResolve.js +107 -82
  46. package/dist/bun/index.js +5 -5
  47. package/dist/bundler/Bundle.js +82 -38
  48. package/dist/bundler/BundleFiles.js +140 -82
  49. package/dist/bundler/BundleRoute.js +49 -38
  50. package/dist/client/Overlay.js +29 -28
  51. package/dist/client/ScrollState.js +94 -82
  52. package/dist/client/index.js +79 -61
  53. package/dist/console/Console.js +40 -24
  54. package/dist/console/ConsoleErrors.js +189 -178
  55. package/dist/console/ConsoleLogger.js +52 -43
  56. package/dist/console/ConsoleMetrics.js +69 -58
  57. package/dist/console/ConsoleProcess.js +57 -47
  58. package/dist/console/ConsoleStore.js +56 -45
  59. package/dist/console/ConsoleTracer.js +101 -88
  60. package/dist/console/Simulation.js +714 -563
  61. package/dist/console/index.js +3 -3
  62. package/dist/console/routes/tree.js +29 -28
  63. package/dist/datastar/actions/fetch.js +514 -381
  64. package/dist/datastar/actions/peek.js +12 -12
  65. package/dist/datastar/actions/setAll.js +18 -11
  66. package/dist/datastar/actions/toggleAll.js +18 -11
  67. package/dist/datastar/attributes/attr.js +48 -47
  68. package/dist/datastar/attributes/bind.js +186 -167
  69. package/dist/datastar/attributes/class.js +51 -44
  70. package/dist/datastar/attributes/computed.js +23 -24
  71. package/dist/datastar/attributes/effect.js +9 -8
  72. package/dist/datastar/attributes/indicator.js +32 -29
  73. package/dist/datastar/attributes/init.js +26 -25
  74. package/dist/datastar/attributes/jsonSignals.js +32 -29
  75. package/dist/datastar/attributes/on.js +76 -73
  76. package/dist/datastar/attributes/onIntersect.js +51 -51
  77. package/dist/datastar/attributes/onInterval.js +30 -29
  78. package/dist/datastar/attributes/onSignalPatch.js +49 -40
  79. package/dist/datastar/attributes/ref.js +10 -9
  80. package/dist/datastar/attributes/show.js +31 -30
  81. package/dist/datastar/attributes/signals.js +17 -16
  82. package/dist/datastar/attributes/style.js +56 -49
  83. package/dist/datastar/attributes/text.js +28 -25
  84. package/dist/datastar/engine.js +1079 -933
  85. package/dist/datastar/index.js +25 -24
  86. package/dist/datastar/utils.js +203 -155
  87. package/dist/datastar/watchers/patchElements.js +459 -372
  88. package/dist/datastar/watchers/patchSignals.js +13 -13
  89. package/dist/experimental/EncryptedCookies.js +305 -189
  90. package/dist/experimental/index.js +1 -1
  91. package/dist/hyper/Hyper.js +22 -17
  92. package/dist/hyper/HyperHtml.js +138 -123
  93. package/dist/hyper/HyperNode.js +11 -9
  94. package/dist/hyper/HyperRoute.js +41 -28
  95. package/dist/hyper/html.js +27 -27
  96. package/dist/hyper/index.js +5 -5
  97. package/dist/hyper/jsx-runtime.js +11 -5
  98. package/dist/index.js +8 -8
  99. package/dist/node/NodeFileSystem.js +606 -341
  100. package/dist/node/NodeUtils.js +21 -18
  101. package/dist/sql/Sql.js +8 -0
  102. package/dist/sql/bun/index.js +134 -67
  103. package/dist/sql/index.js +1 -0
  104. package/dist/sql/libsql/index.js +156 -0
  105. package/dist/sql/mssql/docker.js +103 -60
  106. package/dist/sql/mssql/index.js +182 -101
  107. package/dist/testing/TestLogger.js +39 -29
  108. package/dist/testing/index.js +2 -2
  109. package/dist/testing/utils.js +45 -23
  110. package/dist/x/cloudflare/CloudflareTunnel.js +61 -28
  111. package/dist/x/cloudflare/index.js +1 -1
  112. package/dist/x/tailscale/TailscaleTunnel.js +86 -60
  113. package/dist/x/tailscale/index.js +1 -1
  114. package/dist/x/tailwind/TailwindPlugin.js +280 -205
  115. package/dist/x/tailwind/compile.js +185 -129
  116. package/dist/x/tailwind/plugin.js +13 -11
  117. package/package.json +1 -1
  118. package/src/Development.ts +3 -1
  119. package/src/Entity.ts +17 -0
  120. package/src/Fetch.ts +271 -0
  121. package/src/SqlIntrospect.ts +64 -70
  122. package/src/Start.ts +24 -22
  123. package/src/StartApp.ts +11 -0
  124. package/src/bun/BunServer.ts +89 -16
  125. package/src/hyper/HyperHtml.ts +0 -1
  126. package/src/sql/bun/index.ts +1 -1
  127. package/src/sql/index.ts +1 -0
  128. package/src/sql/libsql/index.ts +173 -0
  129. package/src/sql/libsql/libsql.d.ts +39 -0
  130. package/src/sql/mssql/index.ts +1 -1
  131. package/src/x/tailscale/TailscaleTunnel.ts +7 -5
  132. package/dist/BlobStore.d.ts +0 -80
  133. package/dist/BlobStore.js +0 -19
  134. package/dist/ChildProcess.d.ts +0 -60
  135. package/dist/Commander.d.ts +0 -100
  136. package/dist/ContentNegotiation.d.ts +0 -12
  137. package/dist/Cookies.d.ts +0 -47
  138. package/dist/Development.d.ts +0 -39
  139. package/dist/Effectify.d.ts +0 -209
  140. package/dist/Entity.d.ts +0 -47
  141. package/dist/FilePathPattern.d.ts +0 -29
  142. package/dist/FileRouter.d.ts +0 -56
  143. package/dist/FileRouterCodegen.d.ts +0 -18
  144. package/dist/FileRouterPattern.d.ts +0 -9
  145. package/dist/FileRouterPattern.js +0 -35
  146. package/dist/FileSystem.d.ts +0 -158
  147. package/dist/Http.d.ts +0 -37
  148. package/dist/HttpAppExtra.d.ts +0 -7
  149. package/dist/HttpAppExtra.js +0 -320
  150. package/dist/HttpUtils.d.ts +0 -3
  151. package/dist/HttpUtils.js +0 -11
  152. package/dist/PathPattern.d.ts +0 -134
  153. package/dist/PlatformError.d.ts +0 -38
  154. package/dist/PlatformRuntime.d.ts +0 -27
  155. package/dist/Route.d.ts +0 -97
  156. package/dist/RouteBody.d.ts +0 -47
  157. package/dist/RouteError.d.ts +0 -98
  158. package/dist/RouteHook.d.ts +0 -12
  159. package/dist/RouteHttp.d.ts +0 -21
  160. package/dist/RouteHttpTracer.d.ts +0 -10
  161. package/dist/RouteMount.d.ts +0 -86
  162. package/dist/RouteSchema.d.ts +0 -86
  163. package/dist/RouteSse.d.ts +0 -21
  164. package/dist/RouteTree.d.ts +0 -57
  165. package/dist/RouteTrie.d.ts +0 -20
  166. package/dist/RouterPattern.d.ts +0 -118
  167. package/dist/RouterPattern.js +0 -269
  168. package/dist/SchemaExtra.d.ts +0 -7
  169. package/dist/Socket.d.ts +0 -27
  170. package/dist/Sql.d.ts +0 -34
  171. package/dist/Sql.js +0 -5
  172. package/dist/SqlIntrospect.d.ts +0 -91
  173. package/dist/Start.d.ts +0 -44
  174. package/dist/StartApp.d.ts +0 -19
  175. package/dist/StreamExtra.d.ts +0 -28
  176. package/dist/System.d.ts +0 -7
  177. package/dist/TuplePathPattern.d.ts +0 -9
  178. package/dist/Unique.d.ts +0 -50
  179. package/dist/Values.d.ts +0 -27
  180. package/dist/bun/BunBlobStoreDisk.d.ts +0 -6
  181. package/dist/bun/BunBlobStoreDisk.js +0 -116
  182. package/dist/bun/BunBlobStoreS3.d.ts +0 -11
  183. package/dist/bun/BunBlobStoreS3.js +0 -89
  184. package/dist/bun/BunBlobWatcherDisk.d.ts +0 -6
  185. package/dist/bun/BunBlobWatcherDisk.js +0 -60
  186. package/dist/bun/BunBlobWatcherQueue.d.ts +0 -6
  187. package/dist/bun/BunBlobWatcherQueue.js +0 -17
  188. package/dist/bun/BunBundle.d.ts +0 -11
  189. package/dist/bun/BunChildProcessSpawner.d.ts +0 -3
  190. package/dist/bun/BunHttpServer.d.ts +0 -44
  191. package/dist/bun/BunHttpServer.js +0 -186
  192. package/dist/bun/BunHttpServer_web.d.ts +0 -60
  193. package/dist/bun/BunHttpServer_web.js +0 -252
  194. package/dist/bun/BunImportTrackerPlugin.d.ts +0 -13
  195. package/dist/bun/BunPlatformHttpServer.d.ts +0 -10
  196. package/dist/bun/BunPlatformHttpServer.js +0 -53
  197. package/dist/bun/BunRoute.d.ts +0 -48
  198. package/dist/bun/BunRuntime.d.ts +0 -2
  199. package/dist/bun/BunServer.d.ts +0 -40
  200. package/dist/bun/BunServerRequest.d.ts +0 -60
  201. package/dist/bun/BunServerRequest.js +0 -252
  202. package/dist/bun/BunSql.d.ts +0 -4
  203. package/dist/bun/BunSql.js +0 -81
  204. package/dist/bun/BunVirtualFilesPlugin.d.ts +0 -4
  205. package/dist/bun/_BunEnhancedResolve.d.ts +0 -45
  206. package/dist/bun/index.d.ts +0 -5
  207. package/dist/bundler/Bundle.d.ts +0 -61
  208. package/dist/bundler/BundleFiles.d.ts +0 -13
  209. package/dist/bundler/BundleHttp.d.ts +0 -45
  210. package/dist/bundler/BundleHttp.js +0 -176
  211. package/dist/bundler/BundleRoute.d.ts +0 -27
  212. package/dist/client/Overlay.d.ts +0 -2
  213. package/dist/client/ScrollState.d.ts +0 -6
  214. package/dist/client/index.d.ts +0 -6
  215. package/dist/console/Console.d.ts +0 -6
  216. package/dist/console/ConsoleErrors.d.ts +0 -3
  217. package/dist/console/ConsoleLogger.d.ts +0 -3
  218. package/dist/console/ConsoleMetrics.d.ts +0 -3
  219. package/dist/console/ConsoleProcess.d.ts +0 -3
  220. package/dist/console/ConsoleStore.d.ts +0 -144
  221. package/dist/console/ConsoleTracer.d.ts +0 -3
  222. package/dist/console/Simulation.d.ts +0 -2
  223. package/dist/console/index.d.ts +0 -3
  224. package/dist/console/routes/errors/route.d.ts +0 -10
  225. package/dist/console/routes/errors/route.js +0 -47
  226. package/dist/console/routes/fiberDetail.d.ts +0 -16
  227. package/dist/console/routes/fiberDetail.js +0 -38
  228. package/dist/console/routes/fibers/route.d.ts +0 -10
  229. package/dist/console/routes/fibers/route.js +0 -19
  230. package/dist/console/routes/git/route.d.ts +0 -11
  231. package/dist/console/routes/git/route.js +0 -33
  232. package/dist/console/routes/layout.d.ts +0 -9
  233. package/dist/console/routes/layout.js +0 -3
  234. package/dist/console/routes/logs/route.d.ts +0 -10
  235. package/dist/console/routes/logs/route.js +0 -32
  236. package/dist/console/routes/metrics/route.d.ts +0 -10
  237. package/dist/console/routes/metrics/route.js +0 -17
  238. package/dist/console/routes/route.d.ts +0 -6
  239. package/dist/console/routes/route.js +0 -5
  240. package/dist/console/routes/routes/route.d.ts +0 -6
  241. package/dist/console/routes/routes/route.js +0 -20
  242. package/dist/console/routes/services/route.d.ts +0 -6
  243. package/dist/console/routes/services/route.js +0 -12
  244. package/dist/console/routes/system/route.d.ts +0 -10
  245. package/dist/console/routes/system/route.js +0 -18
  246. package/dist/console/routes/traceDetail.d.ts +0 -16
  247. package/dist/console/routes/traceDetail.js +0 -14
  248. package/dist/console/routes/traces/route.d.ts +0 -10
  249. package/dist/console/routes/traces/route.js +0 -39
  250. package/dist/console/routes/tree.d.ts +0 -153
  251. package/dist/console/ui/Errors.d.ts +0 -4
  252. package/dist/console/ui/Errors.js +0 -15
  253. package/dist/console/ui/Fibers.d.ts +0 -24
  254. package/dist/console/ui/Fibers.js +0 -121
  255. package/dist/console/ui/Git.d.ts +0 -20
  256. package/dist/console/ui/Git.js +0 -95
  257. package/dist/console/ui/Logs.d.ts +0 -4
  258. package/dist/console/ui/Logs.js +0 -25
  259. package/dist/console/ui/Metrics.d.ts +0 -4
  260. package/dist/console/ui/Metrics.js +0 -26
  261. package/dist/console/ui/Routes.d.ts +0 -8
  262. package/dist/console/ui/Routes.js +0 -70
  263. package/dist/console/ui/Services.d.ts +0 -10
  264. package/dist/console/ui/Services.js +0 -246
  265. package/dist/console/ui/Shell.d.ts +0 -10
  266. package/dist/console/ui/Shell.js +0 -7
  267. package/dist/console/ui/System.d.ts +0 -4
  268. package/dist/console/ui/System.js +0 -35
  269. package/dist/console/ui/Traces.d.ts +0 -12
  270. package/dist/console/ui/Traces.js +0 -179
  271. package/dist/datastar/actions/fetch.d.ts +0 -30
  272. package/dist/datastar/actions/peek.d.ts +0 -1
  273. package/dist/datastar/actions/setAll.d.ts +0 -1
  274. package/dist/datastar/actions/toggleAll.d.ts +0 -1
  275. package/dist/datastar/attributes/attr.d.ts +0 -1
  276. package/dist/datastar/attributes/bind.d.ts +0 -1
  277. package/dist/datastar/attributes/class.d.ts +0 -1
  278. package/dist/datastar/attributes/computed.d.ts +0 -1
  279. package/dist/datastar/attributes/effect.d.ts +0 -1
  280. package/dist/datastar/attributes/indicator.d.ts +0 -1
  281. package/dist/datastar/attributes/init.d.ts +0 -1
  282. package/dist/datastar/attributes/jsonSignals.d.ts +0 -1
  283. package/dist/datastar/attributes/on.d.ts +0 -1
  284. package/dist/datastar/attributes/onIntersect.d.ts +0 -1
  285. package/dist/datastar/attributes/onInterval.d.ts +0 -1
  286. package/dist/datastar/attributes/onSignalPatch.d.ts +0 -1
  287. package/dist/datastar/attributes/ref.d.ts +0 -1
  288. package/dist/datastar/attributes/show.d.ts +0 -1
  289. package/dist/datastar/attributes/signals.d.ts +0 -1
  290. package/dist/datastar/attributes/style.d.ts +0 -1
  291. package/dist/datastar/attributes/text.d.ts +0 -1
  292. package/dist/datastar/engine.d.ts +0 -162
  293. package/dist/datastar/happydom.d.ts +0 -1
  294. package/dist/datastar/happydom.js +0 -8
  295. package/dist/datastar/index.d.ts +0 -24
  296. package/dist/datastar/load.d.ts +0 -24
  297. package/dist/datastar/load.js +0 -24
  298. package/dist/datastar/utils.d.ts +0 -51
  299. package/dist/datastar/watchers/patchElements.d.ts +0 -1
  300. package/dist/datastar/watchers/patchSignals.d.ts +0 -1
  301. package/dist/experimental/EncryptedCookies.d.ts +0 -48
  302. package/dist/experimental/SseHttpResponse.d.ts +0 -7
  303. package/dist/experimental/SseHttpResponse.js +0 -28
  304. package/dist/experimental/index.d.ts +0 -1
  305. package/dist/hyper/Hyper.d.ts +0 -25
  306. package/dist/hyper/HyperHtml.d.ts +0 -23
  307. package/dist/hyper/HyperHtml.test.d.ts +0 -1
  308. package/dist/hyper/HyperHtml.test.js +0 -197
  309. package/dist/hyper/HyperNode.d.ts +0 -14
  310. package/dist/hyper/HyperRoute.d.ts +0 -8
  311. package/dist/hyper/HyperRoute.test.d.ts +0 -1
  312. package/dist/hyper/HyperRoute.test.js +0 -83
  313. package/dist/hyper/html.d.ts +0 -11
  314. package/dist/hyper/index.d.ts +0 -6
  315. package/dist/hyper/jsx-runtime.d.ts +0 -7
  316. package/dist/index.d.ts +0 -8
  317. package/dist/inference_check.d.ts +0 -1
  318. package/dist/inference_check.js +0 -15
  319. package/dist/lint/plugin.d.ts +0 -86
  320. package/dist/lint/plugin.js +0 -341
  321. package/dist/middlewares/BasicAuthMiddleware.d.ts +0 -8
  322. package/dist/middlewares/BasicAuthMiddleware.js +0 -22
  323. package/dist/middlewares/index.d.ts +0 -1
  324. package/dist/middlewares/index.js +0 -1
  325. package/dist/node/Effectify.d.ts +0 -209
  326. package/dist/node/Effectify.js +0 -19
  327. package/dist/node/FileSystem.d.ts +0 -7
  328. package/dist/node/FileSystem.js +0 -420
  329. package/dist/node/NodeFileSystem.d.ts +0 -7
  330. package/dist/node/NodeUtils.d.ts +0 -2
  331. package/dist/node/PlatformError.d.ts +0 -46
  332. package/dist/node/PlatformError.js +0 -43
  333. package/dist/node/Utils.d.ts +0 -1
  334. package/dist/node/Utils.js +0 -19
  335. package/dist/repro_fail.d.ts +0 -1
  336. package/dist/repro_fail.js +0 -14
  337. package/dist/sql/bun/index.d.ts +0 -3
  338. package/dist/sql/mssql/docker.d.ts +0 -2
  339. package/dist/sql/mssql/index.d.ts +0 -21
  340. package/dist/testing/TestHttpClient.d.ts +0 -13
  341. package/dist/testing/TestHttpClient.js +0 -68
  342. package/dist/testing/TestLogger.d.ts +0 -13
  343. package/dist/testing/index.d.ts +0 -2
  344. package/dist/testing/utils.d.ts +0 -9
  345. package/dist/x/cloudflare/CloudflareTunnel.d.ts +0 -10
  346. package/dist/x/cloudflare/index.d.ts +0 -1
  347. package/dist/x/datastar/Datastar.d.ts +0 -6
  348. package/dist/x/datastar/Datastar.js +0 -47
  349. package/dist/x/datastar/index.d.ts +0 -1
  350. package/dist/x/datastar/index.js +0 -1
  351. package/dist/x/tailscale/TailscaleTunnel.d.ts +0 -15
  352. package/dist/x/tailscale/index.d.ts +0 -1
  353. package/dist/x/tailwind/TailwindPlugin.d.ts +0 -23
  354. package/dist/x/tailwind/compile.d.ts +0 -19
  355. package/dist/x/tailwind/plugin.d.ts +0 -2
  356. /package/src/{Sql.ts → sql/Sql.ts} +0 -0
@@ -1,20 +1,23 @@
1
- import * as NFS from "node:fs/promises";
2
- import * as NPath from "node:path";
3
- export const getEntrypoint = () => NPath.dirname(process.argv[1]);
1
+ import * as NFS from "node:fs/promises"
2
+ import * as NPath from "node:path"
3
+
4
+ export const getEntrypoint = () => NPath.dirname(process.argv[1])
5
+
4
6
  export const findClosestPackageJson = async (path) => {
5
- const resolved = NPath.resolve(path);
6
- const stat = await NFS.stat(resolved).catch(() => undefined);
7
- let dir = stat?.isDirectory() ? resolved : NPath.dirname(resolved);
8
- const root = NPath.parse(dir).root;
9
- while (dir !== root) {
10
- const candidate = NPath.join(dir, "package.json");
11
- try {
12
- await NFS.access(candidate);
13
- return candidate;
14
- }
15
- catch {
16
- dir = NPath.dirname(dir);
17
- }
7
+ const resolved = NPath.resolve(path)
8
+ const stat = await NFS.stat(resolved).catch(() => undefined)
9
+ let dir = stat?.isDirectory() ? resolved : NPath.dirname(resolved)
10
+ const root = NPath.parse(dir).root
11
+
12
+ while (dir !== root) {
13
+ const candidate = NPath.join(dir, "package.json")
14
+ try {
15
+ await NFS.access(candidate)
16
+ return candidate
17
+ } catch {
18
+ dir = NPath.dirname(dir)
18
19
  }
19
- return undefined;
20
- };
20
+ }
21
+
22
+ return undefined
23
+ }
@@ -0,0 +1,8 @@
1
+ import * as Context from "effect/Context"
2
+ import * as Data from "effect/Data"
3
+
4
+ export class SqlError extends Data.TaggedError("SqlError") {}
5
+
6
+ export const SqlClient = Context.GenericTag(
7
+ "effect-start/Sql/SqlClient",
8
+ )
@@ -1,75 +1,142 @@
1
- import * as Effect from "effect/Effect";
2
- import * as Exit from "effect/Exit";
3
- import * as FiberRef from "effect/FiberRef";
4
- import * as GlobalValue from "effect/GlobalValue";
5
- import * as Layer from "effect/Layer";
6
- import * as Option from "effect/Option";
7
- import * as Sql from "../../Sql.js";
1
+ import * as Effect from "effect/Effect"
2
+ import * as Exit from "effect/Exit"
3
+ import * as FiberRef from "effect/FiberRef"
4
+ import * as GlobalValue from "effect/GlobalValue"
5
+ import * as Layer from "effect/Layer"
6
+ import * as Option from "effect/Option"
7
+ import * as Sql from "../Sql.js"
8
+
8
9
  const errorCode = (error) => {
9
- const e = error;
10
- if (typeof e?.errno === "string")
11
- return e.errno;
12
- return e?.code ?? "UNKNOWN";
13
- };
14
- const wrapError = (error) => new Sql.SqlError({
10
+ const e = error
11
+ if (typeof e?.errno === "string") return e.errno
12
+ return e?.code ?? "UNKNOWN"
13
+ }
14
+
15
+ const wrapError = (error) =>
16
+ new Sql.SqlError({
15
17
  code: errorCode(error),
16
18
  message: error instanceof Error ? error.message : String(error),
17
19
  cause: error,
18
- });
19
- const wrap = (fn) => Effect.tryPromise({ try: () => Promise.resolve(fn()), catch: wrapError });
20
+ })
21
+
22
+ const wrap = (fn) =>
23
+ Effect.tryPromise({ try: () => Promise.resolve(fn()), catch: wrapError })
24
+
20
25
  const makeValues = (obj, ...columns) => {
21
- const items = Array.isArray(obj) ? obj : [obj];
22
- const cols = columns.length > 0 ? columns : Object.keys(items[0]);
23
- return { value: items, columns: cols };
24
- };
25
- const currentTransaction = GlobalValue.globalValue(Symbol.for("effect-start/sql/bun/currentTransaction"), () => FiberRef.unsafeMake(Option.none()));
26
- const makeRun = (bunSql) => (fn) => Effect.flatMap(FiberRef.get(currentTransaction), (txOpt) => wrap(() => fn(Option.isSome(txOpt) ? txOpt.value.conn : bunSql)));
27
- const makeWithTransaction = (bunSql) => (self) => Effect.uninterruptibleMask((restore) => Effect.flatMap(FiberRef.get(currentTransaction), (txOpt) => {
28
- if (Option.isSome(txOpt)) {
29
- const { conn, depth } = txOpt.value;
30
- const name = `sp_${depth}`;
31
- return Effect.gen(function* () {
32
- yield* wrap(() => conn.unsafe(`SAVEPOINT ${name}`));
33
- const exit = yield* Effect.exit(restore(Effect.locally(self, currentTransaction, Option.some({ conn, depth: depth + 1 }))));
26
+ const items = Array.isArray(obj) ? obj : [obj]
27
+ const cols = columns.length > 0 ? columns : Object.keys(items[0])
28
+ return { value: items, columns: cols }
29
+ }
30
+
31
+ const currentTransaction = GlobalValue.globalValue(
32
+ Symbol.for("effect-start/sql/bun/currentTransaction"),
33
+ () => FiberRef.unsafeMake(Option.none()),
34
+ )
35
+
36
+ const makeRun =
37
+ (bunSql) =>
38
+ (fn) =>
39
+ Effect.flatMap(FiberRef.get(currentTransaction), (txOpt) =>
40
+ wrap(() => fn(Option.isSome(txOpt) ? txOpt.value.conn : bunSql)),
41
+ )
42
+
43
+ const makeWithTransaction =
44
+ (bunSql) =>
45
+ (self) =>
46
+ Effect.uninterruptibleMask((restore) =>
47
+ Effect.flatMap(FiberRef.get(currentTransaction), (txOpt) => {
48
+ if (Option.isSome(txOpt)) {
49
+ const { conn, depth } = txOpt.value
50
+ const name = `sp_${depth}`
51
+ return Effect.gen(function* () {
52
+ yield* wrap(() => conn.unsafe(`SAVEPOINT ${name}`))
53
+ const exit = yield* Effect.exit(
54
+ restore(
55
+ Effect.locally(self, currentTransaction, Option.some({ conn, depth: depth + 1 })),
56
+ ),
57
+ )
34
58
  if (Exit.isSuccess(exit)) {
35
- yield* wrap(() => conn.unsafe(`RELEASE SAVEPOINT ${name}`));
36
- return exit.value;
59
+ yield* wrap(() => conn.unsafe(`RELEASE SAVEPOINT ${name}`))
60
+ return exit.value
37
61
  }
38
- yield* wrap(() => conn.unsafe(`ROLLBACK TO SAVEPOINT ${name}`)).pipe(Effect.orDie);
39
- return yield* exit;
40
- });
41
- }
42
- const runTx = (conn) => Effect.gen(function* () {
43
- yield* wrap(() => conn.unsafe("BEGIN"));
44
- const exit = yield* Effect.exit(restore(Effect.locally(self, currentTransaction, Option.some({ conn, depth: 1 }))));
45
- if (Exit.isSuccess(exit)) {
46
- yield* wrap(() => conn.unsafe("COMMIT"));
47
- return exit.value;
62
+ yield* wrap(() => conn.unsafe(`ROLLBACK TO SAVEPOINT ${name}`)).pipe(Effect.orDie)
63
+ return yield* exit
64
+ })
48
65
  }
49
- yield* wrap(() => conn.unsafe("ROLLBACK")).pipe(Effect.orDie);
50
- return yield* exit;
51
- });
52
- return Effect.matchEffect(wrap(() => bunSql.reserve()), {
53
- onFailure: () => runTx(bunSql),
54
- onSuccess: (reserved) => Effect.ensuring(runTx(reserved), Effect.sync(() => reserved.release())),
55
- });
56
- }));
57
- export const layer = (config) => Layer.scoped(Sql.SqlClient, Effect.acquireRelease(Effect.try({
58
- try: () => {
59
- const bunSql = new Bun.SQL(config);
60
- const run = makeRun(bunSql);
61
- const use = (fn) => Effect.tryPromise({ try: () => Promise.resolve(fn(bunSql)), catch: wrapError });
62
- return Object.assign((strings, ...values) => run((conn) => conn(strings, ...values)), {
63
- unsafe: (query, values) => run((conn) => conn.unsafe(query, values)),
64
- values: makeValues,
65
- withTransaction: makeWithTransaction(bunSql),
66
- reserve: Effect.acquireRelease(wrap(() => bunSql.reserve()), (reserved) => Effect.sync(() => reserved.release())).pipe(Effect.map((reserved) => Object.assign((strings, ...values) => wrap(() => reserved(strings, ...values)), {
67
- unsafe: (query, values) => wrap(() => reserved.unsafe(query, values)),
68
- values: makeValues,
69
- }))),
70
- close: (options) => use((bunSql) => bunSql.close(options)),
71
- use,
72
- });
73
- },
74
- catch: wrapError,
75
- }), (client) => client.close().pipe(Effect.orDie)));
66
+
67
+ const runTx = (conn) =>
68
+ Effect.gen(function* () {
69
+ yield* wrap(() => conn.unsafe("BEGIN"))
70
+ const exit = yield* Effect.exit(
71
+ restore(Effect.locally(self, currentTransaction, Option.some({ conn, depth: 1 }))),
72
+ )
73
+ if (Exit.isSuccess(exit)) {
74
+ yield* wrap(() => conn.unsafe("COMMIT"))
75
+ return exit.value
76
+ }
77
+ yield* wrap(() => conn.unsafe("ROLLBACK")).pipe(Effect.orDie)
78
+ return yield* exit
79
+ })
80
+
81
+ return Effect.matchEffect(
82
+ wrap(() => bunSql.reserve()),
83
+ {
84
+ onFailure: () => runTx(bunSql),
85
+ onSuccess: (reserved) =>
86
+ Effect.ensuring(
87
+ runTx(reserved),
88
+ Effect.sync(() => reserved.release()),
89
+ ),
90
+ },
91
+ )
92
+ }),
93
+ )
94
+
95
+ export const layer = (
96
+ config,
97
+ ) =>
98
+ Layer.scoped(
99
+ Sql.SqlClient,
100
+ Effect.acquireRelease(
101
+ Effect.try({
102
+ try: () => {
103
+ const bunSql = new Bun.SQL(config)
104
+ const run = makeRun(bunSql)
105
+ const use = (fn) =>
106
+ Effect.tryPromise({ try: () => Promise.resolve(fn(bunSql)), catch: wrapError })
107
+ return Object.assign(
108
+ (strings, ...values) =>
109
+ run((conn) => conn(strings, ...values)),
110
+ {
111
+ unsafe: (query, values) =>
112
+ run((conn) => conn.unsafe(query, values)),
113
+ values: makeValues,
114
+ withTransaction: makeWithTransaction(bunSql),
115
+ reserve: Effect.acquireRelease(
116
+ wrap(() => bunSql.reserve()),
117
+ (reserved) => Effect.sync(() => reserved.release()),
118
+ ).pipe(
119
+ Effect.map(
120
+ (reserved) =>
121
+ Object.assign(
122
+ (strings, ...values) =>
123
+ wrap(() => reserved(strings, ...values)),
124
+ {
125
+ unsafe: (query, values) =>
126
+ wrap(() => reserved.unsafe(query, values)),
127
+ values: makeValues,
128
+ },
129
+ ),
130
+ ),
131
+ ),
132
+ close: (options) =>
133
+ use((bunSql) => bunSql.close(options)),
134
+ use,
135
+ },
136
+ )
137
+ },
138
+ catch: wrapError,
139
+ }),
140
+ (client) => client.close().pipe(Effect.orDie),
141
+ ),
142
+ )
@@ -0,0 +1 @@
1
+ export * as Sql from "./Sql.js"
@@ -0,0 +1,156 @@
1
+ import * as Effect from "effect/Effect"
2
+ import * as Exit from "effect/Exit"
3
+ import * as FiberRef from "effect/FiberRef"
4
+ import * as GlobalValue from "effect/GlobalValue"
5
+ import * as Layer from "effect/Layer"
6
+ import * as Option from "effect/Option"
7
+ import * as Sql from "../Sql.js"
8
+
9
+ const wrapError = (error) =>
10
+ new Sql.SqlError({
11
+ code: (error)?.code ?? "UNKNOWN",
12
+ message: error instanceof Error ? error.message : String(error),
13
+ cause: error,
14
+ })
15
+
16
+ const wrap = (fn) =>
17
+ Effect.tryPromise({ try: () => Promise.resolve(fn()), catch: wrapError })
18
+
19
+ const makeValues = (obj, ...columns) => {
20
+ const items = Array.isArray(obj) ? obj : [obj]
21
+ const cols = columns.length > 0 ? columns : Object.keys(items[0])
22
+ return { value: items, columns: cols }
23
+ }
24
+
25
+ const resultSetToRows = (result) => {
26
+ const { columns, rows } = result
27
+ return rows.map((row) => {
28
+ const obj = {}
29
+ for (let i = 0; i < columns.length; i++) obj[columns[i]] = row[i]
30
+ return obj
31
+ })
32
+ }
33
+
34
+ const buildQuery = (strings, values) => {
35
+ let sql = strings[0]
36
+ for (let i = 0; i < values.length; i++) sql += "?" + strings[i + 1]
37
+ return { sql, args: values }
38
+ }
39
+
40
+ const loadLibsql = () => import("@libsql/client")
41
+
42
+ const currentTransaction = GlobalValue.globalValue(
43
+ Symbol.for("effect-start/sql/libsql/currentTransaction"),
44
+ () => FiberRef.unsafeMake(Option.none()),
45
+ )
46
+
47
+ const executeQuery = (
48
+ client,
49
+ sql,
50
+ args,
51
+ ) =>
52
+ wrap(() => client.execute({ sql, args })).pipe(Effect.map(resultSetToRows<T>))
53
+
54
+ const runQuery = (
55
+ client,
56
+ strings,
57
+ values,
58
+ ) => {
59
+ const { sql, args } = buildQuery(strings, values)
60
+ return executeQuery(client, sql, args)
61
+ }
62
+
63
+ const runUnsafe = (
64
+ client,
65
+ query,
66
+ values,
67
+ ) =>
68
+ executeQuery(client, query, values ?? [])
69
+
70
+ const exec = (client, sql) =>
71
+ wrap(() => client.execute(sql))
72
+
73
+ const makeWithTransaction =
74
+ (client) =>
75
+ (self) =>
76
+ Effect.uninterruptibleMask((restore) =>
77
+ Effect.flatMap(FiberRef.get(currentTransaction), (txOpt) => {
78
+ if (Option.isSome(txOpt)) {
79
+ const { depth } = txOpt.value
80
+ const name = `sp_${depth}`
81
+ return Effect.gen(function* () {
82
+ yield* exec(client, `SAVEPOINT ${name}`)
83
+ const exit = yield* Effect.exit(
84
+ restore(
85
+ Effect.locally(self, currentTransaction, Option.some({ depth: depth + 1 })),
86
+ ),
87
+ )
88
+ if (Exit.isSuccess(exit)) {
89
+ yield* exec(client, `RELEASE SAVEPOINT ${name}`)
90
+ return exit.value
91
+ }
92
+ yield* exec(client, `ROLLBACK TO SAVEPOINT ${name}`).pipe(Effect.orDie)
93
+ return yield* exit
94
+ })
95
+ }
96
+
97
+ return Effect.gen(function* () {
98
+ yield* exec(client, "BEGIN")
99
+ const exit = yield* Effect.exit(
100
+ restore(Effect.locally(self, currentTransaction, Option.some({ depth: 1 }))),
101
+ )
102
+ if (Exit.isSuccess(exit)) {
103
+ yield* exec(client, "COMMIT")
104
+ return exit.value
105
+ }
106
+ yield* exec(client, "ROLLBACK").pipe(Effect.orDie)
107
+ return yield* exit
108
+ })
109
+ }),
110
+ )
111
+
112
+ export const layer = (config) =>
113
+ Layer.scoped(
114
+ Sql.SqlClient,
115
+ Effect.acquireRelease(
116
+ wrap(() => loadLibsql()).pipe(
117
+ Effect.map((libsql) => {
118
+ const client = libsql.createClient(config)
119
+ const use = (fn) =>
120
+ Effect.tryPromise({ try: () => Promise.resolve(fn(client)), catch: wrapError })
121
+ return Object.assign(
122
+ (strings, ...values) =>
123
+ runQuery(client, strings, values),
124
+ {
125
+ unsafe: (query, values) =>
126
+ runUnsafe(client, query, values),
127
+ values: makeValues,
128
+ withTransaction: makeWithTransaction(client),
129
+ reserve: Effect.acquireRelease(
130
+ wrap(() => loadLibsql()).pipe(
131
+ Effect.map((m) => m.createClient(config)),
132
+ ),
133
+ (reserved) => Effect.sync(() => reserved.close()),
134
+ ).pipe(
135
+ Effect.map(
136
+ (reserved) =>
137
+ Object.assign(
138
+ (strings, ...values) =>
139
+ runQuery(reserved, strings, values),
140
+ {
141
+ unsafe: (query, values) =>
142
+ runUnsafe(reserved, query, values),
143
+ values: makeValues,
144
+ },
145
+ ),
146
+ ),
147
+ ),
148
+ close: () => Effect.sync(() => client.close()),
149
+ use,
150
+ },
151
+ )
152
+ }),
153
+ ),
154
+ (client) => client.close().pipe(Effect.orDie),
155
+ ),
156
+ )
@@ -1,67 +1,110 @@
1
- import * as Effect from "effect/Effect";
2
- import * as Stream from "effect/Stream";
3
- import * as System from "../../System.js";
4
- import * as BunChildProcessSpawner from "../../bun/BunChildProcessSpawner.js";
5
- const PORT = 1433;
6
- const PASSWORD = "TestPass123";
7
- const CONTAINER = "effect-start-mssql";
8
- const exec = (...args) => Effect.scoped(Effect.gen(function* () {
9
- const handle = yield* System.spawn("docker", args, {
1
+ import * as Effect from "effect/Effect"
2
+ import * as Stream from "effect/Stream"
3
+
4
+ import * as System from "../../System.js"
5
+ import * as BunChildProcessSpawner from "../../bun/BunChildProcessSpawner.js"
6
+
7
+ const PORT = 1433
8
+ const PASSWORD = "TestPass123"
9
+ const CONTAINER = "effect-start-mssql"
10
+
11
+ const exec = (
12
+ ...args
13
+ ) =>
14
+ Effect.scoped(
15
+ Effect.gen(function* () {
16
+ const handle = yield* System.spawn("docker", args, {
10
17
  stdout: "ignore",
11
18
  stderr: "inherit",
12
- });
13
- return yield* handle.exitCode;
14
- }));
15
- const execStdout = (...args) => Effect.scoped(Effect.gen(function* () {
16
- const handle = yield* System.spawn("docker", args, {
19
+ })
20
+ return yield* handle.exitCode
21
+ }),
22
+ )
23
+
24
+ const execStdout = (
25
+ ...args
26
+ ) =>
27
+ Effect.scoped(
28
+ Effect.gen(function* () {
29
+ const handle = yield* System.spawn("docker", args, {
17
30
  stdout: "pipe",
18
31
  stderr: "inherit",
19
- });
20
- const [stdout] = yield* Effect.all([handle.stdout.pipe(Stream.decodeText("utf-8"), Stream.mkString), handle.exitCode], { concurrency: 2 });
21
- return stdout;
22
- }));
23
- const containerRunning = execStdout("ps", "-q", "-f", `name=${CONTAINER}`).pipe(Effect.map((stdout) => stdout.trim().length > 0));
24
- const removeContainer = exec("rm", "-f", CONTAINER).pipe(Effect.ignore);
25
- const loadMssql = () => import("mssql");
32
+ })
33
+ const [stdout] = yield* Effect.all(
34
+ [handle.stdout.pipe(Stream.decodeText("utf-8"), Stream.mkString), handle.exitCode],
35
+ { concurrency: 2 },
36
+ )
37
+ return stdout
38
+ }),
39
+ )
40
+
41
+ const containerRunning = execStdout("ps", "-q", "-f", `name=${CONTAINER}`).pipe(
42
+ Effect.map((stdout) => stdout.trim().length > 0),
43
+ )
44
+
45
+ const removeContainer = exec("rm", "-f", CONTAINER).pipe(Effect.ignore)
46
+
47
+ const loadMssql = () => import("mssql")
48
+
26
49
  const canConnect = Effect.tryPromise({
27
- try: async () => {
28
- const { ConnectionPool } = await loadMssql();
29
- const pool = new ConnectionPool({
30
- server: "localhost",
31
- user: "sa",
32
- password: PASSWORD,
33
- port: PORT,
34
- options: { encrypt: true, trustServerCertificate: true, connectTimeout: 3000 },
35
- });
36
- await pool.connect();
37
- await pool.close();
38
- return true;
39
- },
40
- catch: () => false,
41
- }).pipe(Effect.orElseSucceed(() => false));
50
+ try: async () => {
51
+ const { ConnectionPool } = await loadMssql()
52
+ const pool = new ConnectionPool({
53
+ server: "localhost",
54
+ user: "sa",
55
+ password: PASSWORD,
56
+ port: PORT,
57
+ options: { encrypt: true, trustServerCertificate: true, connectTimeout: 3000 },
58
+ })
59
+ await pool.connect()
60
+ await pool.close()
61
+ return true
62
+ },
63
+ catch: () => /** @type {const} */ false,
64
+ }).pipe(Effect.orElseSucceed(() => false))
65
+
42
66
  const waitReady = Effect.gen(function* () {
43
- const deadline = Date.now() + 60_000;
44
- while (Date.now() < deadline) {
45
- if (yield* canConnect)
46
- return;
47
- yield* Effect.sleep("2 seconds");
48
- }
49
- return yield* Effect.fail(new Error("Timed out waiting for MSSQL"));
50
- });
67
+ const deadline = Date.now() + 60_000
68
+ while (Date.now() < deadline) {
69
+ if (yield* canConnect) return
70
+ yield* Effect.sleep("2 seconds")
71
+ }
72
+ return yield* Effect.fail(new Error("Timed out waiting for MSSQL"))
73
+ })
74
+
51
75
  const program = Effect.gen(function* () {
52
- if (yield* containerRunning) {
53
- yield* Effect.log("MSSQL container already running");
54
- return;
55
- }
56
- yield* removeContainer;
57
- yield* Effect.log("Starting MSSQL container...");
58
- const code = yield* exec("run", "-d", "--name", CONTAINER, "-p", `${PORT}:1433`, "-e", "ACCEPT_EULA=Y", "-e", `MSSQL_SA_PASSWORD=${PASSWORD}`, "mcr.microsoft.com/azure-sql-edge");
59
- if (code !== 0) {
60
- return yield* Effect.fail(new Error(`docker run exited with code ${code}`));
61
- }
62
- yield* waitReady;
63
- yield* Effect.log("MSSQL ready");
64
- });
65
- const run = (effect) => Effect.runPromise(Effect.provide(effect, BunChildProcessSpawner.layer));
66
- export const start = () => run(program);
67
- export const stop = () => run(removeContainer);
76
+ if (yield* containerRunning) {
77
+ yield* Effect.log("MSSQL container already running")
78
+ return
79
+ }
80
+
81
+ yield* removeContainer
82
+
83
+ yield* Effect.log("Starting MSSQL container...")
84
+ const code = yield* exec(
85
+ "run",
86
+ "-d",
87
+ "--name",
88
+ CONTAINER,
89
+ "-p",
90
+ `${PORT}:1433`,
91
+ "-e",
92
+ "ACCEPT_EULA=Y",
93
+ "-e",
94
+ `MSSQL_SA_PASSWORD=${PASSWORD}`,
95
+ "mcr.microsoft.com/azure-sql-edge",
96
+ )
97
+ if (code !== 0) {
98
+ return yield* Effect.fail(new Error(`docker run exited with code ${code}`))
99
+ }
100
+
101
+ yield* waitReady
102
+ yield* Effect.log("MSSQL ready")
103
+ })
104
+
105
+ const run = (effect) =>
106
+ Effect.runPromise(Effect.provide(effect, BunChildProcessSpawner.layer))
107
+
108
+ export const start = () => run(program)
109
+
110
+ export const stop = () => run(removeContainer)