acrylblends 1.0.3 → 1.0.5

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 (256) hide show
  1. package/docs/framework/agents/index.md +6 -4
  2. package/docs/framework/workshop/README.md +3 -3
  3. package/docs/framework/workshop/facilitator.md +1 -0
  4. package/lib/accept-CNNHu4Cf.js +193 -0
  5. package/lib/{accepts-XBuZPVRI.js → accepts-Btq83xPd.js} +1 -1
  6. package/lib/accepts.js +1 -1
  7. package/lib/acryl-base.js +1 -331
  8. package/lib/adapter-CaZ6FZUU.js +37 -0
  9. package/lib/adapter.js +1 -36
  10. package/lib/{app-BM0rTCp7.js → app-CQcGWjrk.js} +4 -4
  11. package/lib/app-base-CpRMZL4v.js +332 -0
  12. package/lib/{audit-BXnYsLge.d.ts → audit-D5z9uwOP.d.ts} +14 -1
  13. package/lib/{base-NSN_SNv-.js → base-D_6kfOr-.js} +1 -1
  14. package/lib/basic-auth-C0HTRpXh.js +20 -0
  15. package/lib/basic-auth-DFLflXNe.js +95 -0
  16. package/lib/basic-auth.js +1 -94
  17. package/lib/bearer-auth-Cwxt-vgS.js +94 -0
  18. package/lib/bearer-auth.js +1 -93
  19. package/lib/body-D7f4e7w_.js +94 -0
  20. package/lib/body-limit-WmIjWRLt.js +66 -0
  21. package/lib/body-limit.js +1 -65
  22. package/lib/buffer-CkEOJCcY.js +51 -0
  23. package/lib/bun.js +3 -3
  24. package/lib/cache-B0bHH7s5.js +169 -0
  25. package/lib/cache.js +1 -168
  26. package/lib/{client-DDLXwhBo.js → client-BrMFnMEd.js} +1 -1
  27. package/lib/{client-modules-CLvWOjbd.js → client-modules-drj4mjhj.js} +4 -4
  28. package/lib/client.js +1 -1
  29. package/lib/color-COa3DplO.js +37 -0
  30. package/lib/combine-TWuGdcbC.js +137 -0
  31. package/lib/combine.js +1 -136
  32. package/lib/{components-cEW3ovK0.js → components-B2ka9Ax1.js} +4 -4
  33. package/lib/{components-JXVm45kK.js → components-PVXwaOaC.js} +2 -2
  34. package/lib/compress-BzWqsHF1.js +79 -0
  35. package/lib/compress-C-9vK4B2.d.ts +11 -0
  36. package/lib/compress-DCyrrQ5D.js +11 -0
  37. package/lib/compress.d.ts +1 -1
  38. package/lib/compress.js +2 -78
  39. package/lib/concurrent-DrF3d2c-.js +30 -0
  40. package/lib/conninfo-BCROmdnf.d.ts +11 -0
  41. package/lib/conninfo-CWJwieh4.js +19 -0
  42. package/lib/constants-CBSEudrb.js +7 -0
  43. package/lib/{context-DDO0cfuP.js → context-CkOh7Ygv.js} +2 -2
  44. package/lib/context-storage-iuPoI_CR.js +52 -0
  45. package/lib/context-storage.js +1 -51
  46. package/lib/cookie-B1LlkzOe.js +125 -0
  47. package/lib/cookie-BHIduy2T.js +82 -0
  48. package/lib/cookie.js +1 -81
  49. package/lib/cordis/db-sqlite.d.ts +1 -1
  50. package/lib/cordis/door.d.ts +17 -3
  51. package/lib/cordis/door.js +123 -16
  52. package/lib/cordis/inspect.js +4 -4
  53. package/lib/cordis/kv-db.d.ts +1 -1
  54. package/lib/cordis/kv-db.js +1 -1
  55. package/lib/cordis/kv-json.d.ts +1 -1
  56. package/lib/cordis/kv-json.js +1 -1
  57. package/lib/cordis/node-server.d.ts +1 -1
  58. package/lib/cordis/node-server.js +3 -116
  59. package/lib/cordis/router-http.d.ts +1 -1
  60. package/lib/cordis/router-http.js +2 -2
  61. package/lib/cordis/router.d.ts +1 -1
  62. package/lib/cordis/router.js +4 -4
  63. package/lib/cordis/state.js +7 -7
  64. package/lib/{core-CaY8XDZ6.js → core-BOu1jYua.js} +1 -1
  65. package/lib/cors-CbAQ-8qU.js +106 -0
  66. package/lib/cors.js +1 -105
  67. package/lib/crypto-iVP-N-tS.js +34 -0
  68. package/lib/csrf-DqqOZtgy.js +101 -0
  69. package/lib/csrf.js +1 -100
  70. package/lib/css-C5CPVMvM.js +134 -0
  71. package/lib/css.js +2 -133
  72. package/lib/db/sqlite.d.ts +1 -25
  73. package/lib/dev-CLgu-JRe.js +50 -0
  74. package/lib/dev.js +1 -49
  75. package/lib/dom-YjND9Jt3.js +74 -0
  76. package/lib/door/host.d.ts +2 -2
  77. package/lib/door/host.js +1 -1
  78. package/lib/door/page.d.ts +12 -1
  79. package/lib/door/page.js +22 -1
  80. package/lib/door/protocol.d.ts +2 -2
  81. package/lib/door/protocol.js +2 -197
  82. package/lib/encode-BhbNLrjp.js +33 -0
  83. package/lib/factory-CLdSf-xS.js +30 -0
  84. package/lib/factory.js +1 -29
  85. package/lib/handler-C0wZ0KwO.js +12 -0
  86. package/lib/helpers-BEjcdbgw.js +5 -0
  87. package/lib/{hooks-w72iLeFR.js → hooks-CfC07ri0.js} +1 -1
  88. package/lib/html-CgNa89xw.js +31 -0
  89. package/lib/html-DGExBFNg.js +103 -0
  90. package/lib/html.d.ts +2 -5
  91. package/lib/html.js +2 -30
  92. package/lib/http-exception-MjWkT89V.js +54 -0
  93. package/lib/http-exception.js +1 -53
  94. package/lib/{index-D4nVR3wu.d.ts → index-DMOtA-NJ.d.ts} +7 -1
  95. package/lib/index-dAzQsJG9.d.ts +6 -0
  96. package/lib/index.js +3 -3
  97. package/lib/ip-restriction-jKtKCRM_.js +166 -0
  98. package/lib/ip-restriction.js +1 -165
  99. package/lib/ipaddr-DCoIo528.js +238 -0
  100. package/lib/jsx/dom/client.js +1 -1
  101. package/lib/jsx/dom/jsx-dev-runtime.js +1 -1
  102. package/lib/jsx/dom/jsx-runtime.js +2 -1
  103. package/lib/jsx/dom/server.js +3 -3
  104. package/lib/jsx/dom.js +5 -73
  105. package/lib/jsx/jsx-dev-runtime.d.ts +2 -5
  106. package/lib/jsx/jsx-dev-runtime.js +2 -13
  107. package/lib/jsx/jsx-runtime.d.ts +2 -2
  108. package/lib/jsx/jsx-runtime.js +4 -4
  109. package/lib/jsx/streaming.js +1 -1
  110. package/lib/jsx-CUQgttxU.js +47 -0
  111. package/lib/jsx-dev-runtime-B4WTyq8r.js +14 -0
  112. package/lib/{jsx-dev-runtime-CWLRA2F3.js → jsx-dev-runtime-BLfA-EhI.js} +2 -2
  113. package/lib/jsx-dev-runtime-CGt4kNYr.d.ts +6 -0
  114. package/lib/jsx-renderer-CfifM4hT.js +99 -0
  115. package/lib/jsx-renderer.js +1 -98
  116. package/lib/jsx-runtime-COCRWBJ9.js +2 -0
  117. package/lib/jsx.js +5 -46
  118. package/lib/{jwk-LkzeoaU8.js → jwk-CDPpYQpD.js} +3 -3
  119. package/lib/jwk.js +1 -1
  120. package/lib/{jwt-BGJBw5AF.js → jwt-BXoIA2fQ.js} +2 -2
  121. package/lib/{jwt-CskdhEW9.js → jwt-lyS4Q3mT.js} +3 -3
  122. package/lib/jwt.js +2 -2
  123. package/lib/kv/db.d.ts +1 -10
  124. package/lib/kv/db.js +1 -56
  125. package/lib/kv/json.d.ts +1 -9
  126. package/lib/kv/json.js +1 -223
  127. package/lib/{language-D9a4zqvn.js → language-DeGRtLJt.js} +2 -2
  128. package/lib/language.js +1 -1
  129. package/lib/{linear-router-C3FPib6h.js → linear-router-CmZn_JLV.js} +2 -2
  130. package/lib/logger-Ckxu8diz.js +54 -0
  131. package/lib/logger.js +1 -53
  132. package/lib/loopback-only-BbasoF7R.js +90 -0
  133. package/lib/loopback-only.js +1 -89
  134. package/lib/method-not-allowed-TO2_hnfl.js +82 -0
  135. package/lib/method-not-allowed.js +1 -81
  136. package/lib/method-override-DnZKfJbV.js +103 -0
  137. package/lib/method-override.js +1 -102
  138. package/lib/middleware-BfG_fp8P.js +12 -0
  139. package/lib/mime-BnScXkQn.js +77 -0
  140. package/lib/mount-QkK_3NtJ.js +67 -0
  141. package/lib/mount.js +1 -66
  142. package/lib/node-server/conninfo.d.ts +1 -10
  143. package/lib/node-server/conninfo.js +1 -18
  144. package/lib/node-server/register.js +25 -2
  145. package/lib/node-server/serve-static.d.ts +1 -17
  146. package/lib/node-server/serve-static.js +1 -1
  147. package/lib/node-server.d.ts +2 -2
  148. package/lib/node-server.js +4 -4
  149. package/lib/open-BqK4D2Wn.d.ts +11 -0
  150. package/lib/open-But9E2rL.js +57 -0
  151. package/lib/open-CULVJgOc.d.ts +12 -0
  152. package/lib/open-Dp4sxspc.js +224 -0
  153. package/lib/open-T7kgbO2O.d.ts +27 -0
  154. package/lib/{pattern-router-HZxjDGEQ.js → pattern-router-CJBecJBd.js} +1 -1
  155. package/lib/powered-by-CXQNjNIX.js +24 -0
  156. package/lib/powered-by.js +1 -23
  157. package/lib/pretty-json-CeC1yvYt.js +39 -0
  158. package/lib/pretty-json.js +1 -38
  159. package/lib/{protocol-BizVt4J6.d.ts → protocol-C37gPePD.d.ts} +9 -2
  160. package/lib/protocol-Dt0AZBOz.js +213 -0
  161. package/lib/proxy-C2w_mH7k.js +121 -0
  162. package/lib/proxy.js +1 -120
  163. package/lib/quick.js +4 -4
  164. package/lib/{reg-exp-router-DC1R3qoY.js → reg-exp-router-C_WV84eV.js} +2 -2
  165. package/lib/request-DvMgGtlW.js +323 -0
  166. package/lib/request.js +1 -322
  167. package/lib/route-D8m-a2I1.js +126 -0
  168. package/lib/route.js +1 -125
  169. package/lib/router/linear-router.js +1 -1
  170. package/lib/router/pattern-router.js +1 -1
  171. package/lib/router/reg-exp-router.js +1 -1
  172. package/lib/router/smart-router.js +1 -1
  173. package/lib/router/trie-router.js +1 -1
  174. package/lib/router-Be_o6nFu.js +35 -0
  175. package/lib/router.js +1 -34
  176. package/lib/schema-validator-EK3cUUCt.js +22 -0
  177. package/lib/schema-validator.js +1 -21
  178. package/lib/{secure-headers-mP3j6Hm6.js → secure-headers-C5ZOcXqk.js} +1 -1
  179. package/lib/secure-headers.js +1 -1
  180. package/lib/serve-static-B7sqnftW.d.ts +18 -0
  181. package/lib/{serve-static-3uo_9rjF.js → serve-static-C1Nkj_xB.js} +2 -2
  182. package/lib/{serve-static-Cp5adzGo.js → serve-static-EiJf1zkO.js} +4 -4
  183. package/lib/serve-static.js +1 -1
  184. package/lib/{smart-router-C5CZ5XSM.js → smart-router-BjxkDQCE.js} +1 -1
  185. package/lib/{snapshot-text-DmE0YfeZ.js → snapshot-text-Bbx43mN0.js} +57 -9
  186. package/lib/{src-2Z4mJg0x.js → src-BTBm4OPD.js} +22 -6
  187. package/lib/src-LX0E4ec4.js +117 -0
  188. package/lib/{ssg-BwjcA-Ge.js → ssg-BEl7MHqg.js} +5 -5
  189. package/lib/ssg.js +1 -1
  190. package/lib/stream-CzM_SHkq.js +88 -0
  191. package/lib/{streaming-DHST3Scg.js → streaming-BlDaph8U.js} +3 -3
  192. package/lib/streaming.js +1 -1
  193. package/lib/{test-websocket-D8WWqE5G.js → test-websocket-BLeEvybj.js} +2 -2
  194. package/lib/testing-BQx5T_UX.js +17 -0
  195. package/lib/testing.js +1 -16
  196. package/lib/timeout-FeqZ9A-0.js +42 -0
  197. package/lib/timeout.js +1 -41
  198. package/lib/tiny.js +2 -2
  199. package/lib/trailing-slash-DwTx-1sk.js +85 -0
  200. package/lib/trailing-slash.js +1 -84
  201. package/lib/{trie-router-CfFbapzL.js → trie-router-JydLKUa2.js} +2 -2
  202. package/lib/url-BPh4d6j-.js +197 -0
  203. package/lib/utils/accept.js +1 -192
  204. package/lib/utils/basic-auth.js +1 -19
  205. package/lib/utils/body.js +1 -93
  206. package/lib/utils/buffer.js +1 -50
  207. package/lib/utils/color.js +1 -36
  208. package/lib/utils/compress.d.ts +1 -10
  209. package/lib/utils/compress.js +1 -10
  210. package/lib/utils/concurrent.js +1 -29
  211. package/lib/utils/constants.js +1 -6
  212. package/lib/utils/cookie.js +1 -124
  213. package/lib/utils/crypto.js +1 -33
  214. package/lib/utils/encode.js +1 -32
  215. package/lib/utils/handler.js +1 -11
  216. package/lib/utils/html.js +1 -102
  217. package/lib/utils/ipaddr.js +1 -237
  218. package/lib/utils/jwt.js +1 -1
  219. package/lib/utils/mime.js +1 -76
  220. package/lib/utils/stream.js +1 -87
  221. package/lib/utils/url.js +1 -196
  222. package/lib/{validator-D84mq-dO.js → validator-Btiyt5VJ.js} +3 -3
  223. package/lib/validator.js +1 -1
  224. package/lib/websocket-DsyBIKVA.js +56 -0
  225. package/lib/ws.js +1 -55
  226. package/package.json +1 -1
  227. package/plugins/acryl-door/src/cli/acryl.ts +5 -3
  228. package/plugins/acryl-door/src/host/channel.ts +36 -0
  229. package/plugins/acryl-door/src/host/chat-tools.ts +2 -0
  230. package/plugins/acryl-door/src/host/door.ts +44 -5
  231. package/plugins/acryl-door/src/host/shim.ts +23 -0
  232. package/plugins/acryl-door/src/host/verbs.ts +4 -3
  233. package/plugins/acryl-door/src/index.ts +39 -3
  234. package/plugins/acryl-door/src/page/driver/driver.ts +22 -1
  235. package/plugins/acryl-door/src/page/protocol.ts +13 -2
  236. package/plugins/acryl-node-server/src/register.ts +29 -2
  237. package/plugins/acryl-router/src/service.ts +19 -1
  238. package/plugins/agent/model.ts +6 -1
  239. package/plugins/agent/tools.ts +12 -2
  240. package/plugins/agent-panel/client/describe.ts +44 -0
  241. package/plugins/agent-panel/client/main.ts +67 -35
  242. package/plugins/agent-panel/index.ts +137 -35
  243. package/plugins/desktop/attach.ts +72 -0
  244. package/plugins/desktop/main.ts +17 -4
  245. package/plugins/extensions/index.ts +3 -4
  246. package/plugins/extensions/stage.ts +33 -5
  247. package/plugins/openai/index.ts +1 -1
  248. package/shared/DEFAULTS.md +4 -0
  249. package/templates/agent/AGENTS.md +2 -0
  250. package/templates/agent/blend.yaml +4 -1
  251. package/templates/agent/src/app.ts +2 -0
  252. package/templates/agent/src/routes.ts +1 -1
  253. package/templates/agent/template.json +1 -0
  254. package/templates/agent/test/builder.test.ts +26 -21
  255. package/lib/helpers-CvTauQT5.js +0 -5
  256. package/lib/middleware-CPQ8himN.js +0 -12
@@ -0,0 +1,67 @@
1
+ import { i as routePath } from "./route-D8m-a2I1.js";
2
+ //#region ../../plugins/acryl-router/src/core/middleware/mount/index.ts
3
+ const defaultReplaceRequest = (c) => {
4
+ const pathPrefix = routePath(c).replace(/\/\*$/, "");
5
+ const url = new URL(c.req.raw.url);
6
+ url.pathname = c.req.path.slice(pathPrefix.length) || "/";
7
+ return new Request(url, c.req.raw);
8
+ };
9
+ const defaultGetOptions = (c) => {
10
+ let executionContext = void 0;
11
+ try {
12
+ executionContext = c.executionCtx;
13
+ } catch {}
14
+ return [c.env, executionContext];
15
+ };
16
+ /**
17
+ * `mount()` allows you to mount applications built with other frameworks into your Acryl application.
18
+ *
19
+ *
20
+ * @param {Function} applicationHandler - other Request Handler
21
+ * @param {MountOptions} [options] - options of `mount()`
22
+ * @returns {MiddlewareHandler} handler to register with `app.all()`
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * import { Router as IttyRouter } from 'itty-router'
27
+ * import { Acryl } from 'acrylblends'
28
+ * import { mount } from 'acrylblends/mount'
29
+ * // Create itty-router application
30
+ * const ittyRouter = IttyRouter()
31
+ * // GET /itty-router/hello
32
+ * ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
33
+ *
34
+ * const app = new Acryl()
35
+ * app.all('/itty-router/*', mount(ittyRouter.handle))
36
+ * ```
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * const app = new Acryl()
41
+ * // Send the request to another application without modification.
42
+ * app.all('/app/*', mount(anotherApp, {
43
+ * replaceRequest: (req) => req,
44
+ * }))
45
+ * ```
46
+ */
47
+ const mount = (applicationHandler, options) => {
48
+ let replaceRequest;
49
+ let optionHandler;
50
+ if (options) if (typeof options === "function") optionHandler = options;
51
+ else {
52
+ optionHandler = options.optionHandler;
53
+ if (options.replaceRequest === false) replaceRequest = (request) => request;
54
+ else replaceRequest = options.replaceRequest;
55
+ }
56
+ const getOptions = optionHandler ? (c) => {
57
+ const options = optionHandler(c);
58
+ return Array.isArray(options) ? options : [options];
59
+ } : defaultGetOptions;
60
+ return async (c, next) => {
61
+ const res = await applicationHandler(replaceRequest ? replaceRequest(c.req.raw) : defaultReplaceRequest(c), ...getOptions(c));
62
+ if (res) return res;
63
+ await next();
64
+ };
65
+ };
66
+ //#endregion
67
+ export { mount as t };
package/lib/mount.js CHANGED
@@ -1,67 +1,2 @@
1
- import { routePath } from "./route.js";
2
- //#region ../../plugins/acryl-router/src/core/middleware/mount/index.ts
3
- const defaultReplaceRequest = (c) => {
4
- const pathPrefix = routePath(c).replace(/\/\*$/, "");
5
- const url = new URL(c.req.raw.url);
6
- url.pathname = c.req.path.slice(pathPrefix.length) || "/";
7
- return new Request(url, c.req.raw);
8
- };
9
- const defaultGetOptions = (c) => {
10
- let executionContext = void 0;
11
- try {
12
- executionContext = c.executionCtx;
13
- } catch {}
14
- return [c.env, executionContext];
15
- };
16
- /**
17
- * `mount()` allows you to mount applications built with other frameworks into your Acryl application.
18
- *
19
- *
20
- * @param {Function} applicationHandler - other Request Handler
21
- * @param {MountOptions} [options] - options of `mount()`
22
- * @returns {MiddlewareHandler} handler to register with `app.all()`
23
- *
24
- * @example
25
- * ```ts
26
- * import { Router as IttyRouter } from 'itty-router'
27
- * import { Acryl } from 'acrylblends'
28
- * import { mount } from 'acrylblends/mount'
29
- * // Create itty-router application
30
- * const ittyRouter = IttyRouter()
31
- * // GET /itty-router/hello
32
- * ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
33
- *
34
- * const app = new Acryl()
35
- * app.all('/itty-router/*', mount(ittyRouter.handle))
36
- * ```
37
- *
38
- * @example
39
- * ```ts
40
- * const app = new Acryl()
41
- * // Send the request to another application without modification.
42
- * app.all('/app/*', mount(anotherApp, {
43
- * replaceRequest: (req) => req,
44
- * }))
45
- * ```
46
- */
47
- const mount = (applicationHandler, options) => {
48
- let replaceRequest;
49
- let optionHandler;
50
- if (options) if (typeof options === "function") optionHandler = options;
51
- else {
52
- optionHandler = options.optionHandler;
53
- if (options.replaceRequest === false) replaceRequest = (request) => request;
54
- else replaceRequest = options.replaceRequest;
55
- }
56
- const getOptions = optionHandler ? (c) => {
57
- const options = optionHandler(c);
58
- return Array.isArray(options) ? options : [options];
59
- } : defaultGetOptions;
60
- return async (c, next) => {
61
- const res = await applicationHandler(replaceRequest ? replaceRequest(c.req.raw) : defaultReplaceRequest(c), ...getOptions(c));
62
- if (res) return res;
63
- await next();
64
- };
65
- };
66
- //#endregion
1
+ import { t as mount } from "./mount-QkK_3NtJ.js";
67
2
  export { mount };
@@ -1,11 +1,2 @@
1
- import { r as GetConnInfo } from "../types-Dv_nV2cv.js";
2
-
3
- //#region ../../plugins/acryl-node-server/src/adapter/conninfo.d.ts
4
- /**
5
- * ConnInfo Helper for Node.js
6
- * @param c Context
7
- * @returns ConnInfo
8
- */
9
- declare const getConnInfo: GetConnInfo;
10
- //#endregion
1
+ import { t as getConnInfo } from "../conninfo-BCROmdnf.js";
11
2
  export { getConnInfo };
@@ -1,19 +1,2 @@
1
- //#region ../../plugins/acryl-node-server/src/adapter/conninfo.ts
2
- /**
3
- * ConnInfo Helper for Node.js
4
- * @param c Context
5
- * @returns ConnInfo
6
- */
7
- const getConnInfo = (c) => {
8
- const bindings = c.env.server ? c.env.server : c.env;
9
- const address = bindings.incoming.socket.remoteAddress;
10
- const port = bindings.incoming.socket.remotePort;
11
- const family = bindings.incoming.socket.remoteFamily;
12
- return { remote: {
13
- address,
14
- port,
15
- addressType: family === "IPv4" ? "IPv4" : family === "IPv6" ? "IPv6" : void 0
16
- } };
17
- };
18
- //#endregion
1
+ import { t as getConnInfo } from "../conninfo-CWJwieh4.js";
19
2
  export { getConnInfo };
@@ -1,7 +1,7 @@
1
1
  import { n as compileModule } from "../transpile-QUK9b3eG.js";
2
2
  import { registerHooks } from "node:module";
3
- import { readFileSync } from "node:fs";
4
- import { fileURLToPath } from "node:url";
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
5
  //#region ../../plugins/acryl-node-server/src/register.ts
6
6
  /**
7
7
  * JSX files on Node: `node --import acrylblends/node-server/register src/index.ts`. Node strips TypeScript's types but does not compile JSX, so a
@@ -27,5 +27,28 @@ registerHooks({ load(url, context, nextLoad) {
27
27
  shortCircuit: true
28
28
  };
29
29
  } });
30
+ /**
31
+ * The framework's names for a file of the app: in an app the framework plugins are source under `plugins/`, not packages, so `acrylblends`, `acrylblends/body-limit` or `acryl-router`
32
+ * have nowhere to resolve from. A plugin installed while the app runs gets them from the extensions plugin; a plugin that is a ROW of `blend.yaml` is imported by `src/app.ts` before
33
+ * any of that exists, so the same names are resolved here, in the preload every `dev`, `start` and `test` script runs. Only a name that Node cannot resolve itself, only for the
34
+ * app's own files (never for something in `node_modules`), and only in an app that has the framework as vendored source: the published package resolves its own names.
35
+ */
36
+ const plugins = new URL("../../", import.meta.url);
37
+ const appRoot = new URL("../", plugins).href;
38
+ const resolver = new URL("extensions/resolve.ts", plugins);
39
+ if (existsSync(fileURLToPath(new URL("acryl-router/src/index.ts", plugins))) && existsSync(fileURLToPath(resolver))) {
40
+ const { routerAliases } = await import(resolver.href);
41
+ const aliases = routerAliases();
42
+ registerHooks({ resolve(specifier, context, nextResolve) {
43
+ try {
44
+ return nextResolve(specifier, context);
45
+ } catch (error) {
46
+ const alias = aliases[specifier];
47
+ const parent = context.parentURL;
48
+ if (alias !== void 0 && parent?.startsWith(appRoot) && !parent.includes("/node_modules/")) return nextResolve(pathToFileURL(alias).href, context);
49
+ throw error;
50
+ }
51
+ } });
52
+ }
30
53
  //#endregion
31
54
  export {};
@@ -1,18 +1,2 @@
1
- import { L as MiddlewareHandler, t as Context, v as Env } from "../context-DS3fYyG-.js";
2
- //#region ../../plugins/acryl-node-server/src/adapter/serve-static.d.ts
3
- type ServeStaticOptions<E extends Env = Env> = {
4
- /**
5
- * Root path. Relative path is based on current working directory from which the app was started.
6
- */
7
- root?: string;
8
- path?: string;
9
- index?: string;
10
- precompressed?: boolean; /** Allow percent signs in the routed request path. Defaults to false. */
11
- allowPercentInPath?: boolean;
12
- rewriteRequestPath?: (path: string, c: Context<E>) => string;
13
- onFound?: (path: string, c: Context<E>) => void | Promise<void>;
14
- onNotFound?: (path: string, c: Context<E>) => void | Promise<void>;
15
- };
16
- declare const serveStatic: <E extends Env = any>(options?: ServeStaticOptions<E>) => MiddlewareHandler<E>;
17
- //#endregion
1
+ import { n as serveStatic, t as ServeStaticOptions } from "../serve-static-B7sqnftW.js";
18
2
  export { ServeStaticOptions, serveStatic };
@@ -1,2 +1,2 @@
1
- import { t as serveStatic } from "../serve-static-3uo_9rjF.js";
1
+ import { t as serveStatic } from "../serve-static-C1Nkj_xB.js";
2
2
  export { serveStatic };
@@ -1,7 +1,7 @@
1
1
  import { t as Acryl } from "./app-D8riatvv.js";
2
2
  import { a as Owner, c as UpgradeHubOptions, d as upgradeWebSocket, f as WebSocketData, i as testWebSocket, l as UpgradeRouter, m as WebSocketServerLike, n as TestWebSocketOptions, o as UpgradeEmitter, p as WebSocketLike, r as TestWebSocketResult, s as UpgradeHub, t as TestSocket, u as RequestError } from "./test-websocket-DyeS50Tr.js";
3
- import { ServeStaticOptions, serveStatic } from "./node-server/serve-static.js";
4
- import { getConnInfo } from "./node-server/conninfo.js";
3
+ import { n as serveStatic, t as ServeStaticOptions } from "./serve-static-B7sqnftW.js";
4
+ import { t as getConnInfo } from "./conninfo-BCROmdnf.js";
5
5
  import { AddressInfo } from "node:net";
6
6
  import { IncomingMessage, Server, ServerOptions, ServerResponse, createServer } from "node:http";
7
7
  import { Http2SecureServer, Http2Server, Http2ServerRequest, Http2ServerResponse, SecureServerOptions, ServerOptions as ServerOptions$1, createSecureServer, createServer as createServer$1 } from "node:http2";
@@ -1,5 +1,5 @@
1
- import { a as serve, i as createAdaptorServer, l as RequestError, n as UpgradeEmitter, o as upgradeWebSocket, r as UpgradeHub, s as getRequestListener, t as testWebSocket } from "./test-websocket-D8WWqE5G.js";
2
- import { t as serveStatic } from "./serve-static-3uo_9rjF.js";
3
- import { getConnInfo } from "./node-server/conninfo.js";
4
- import { n as clientModules, t as buildClientModules } from "./client-modules-CLvWOjbd.js";
1
+ import { a as serve, i as createAdaptorServer, l as RequestError, n as UpgradeEmitter, o as upgradeWebSocket, r as UpgradeHub, s as getRequestListener, t as testWebSocket } from "./test-websocket-BLeEvybj.js";
2
+ import { t as serveStatic } from "./serve-static-C1Nkj_xB.js";
3
+ import { t as getConnInfo } from "./conninfo-CWJwieh4.js";
4
+ import { n as clientModules, t as buildClientModules } from "./client-modules-drj4mjhj.js";
5
5
  export { RequestError, UpgradeEmitter, UpgradeHub, buildClientModules, clientModules, createAdaptorServer, getConnInfo, getRequestListener, serve, serveStatic, testWebSocket, upgradeWebSocket };
@@ -0,0 +1,11 @@
1
+ import { r as KvOpened } from "./kv-9f-AlRKN.js";
2
+
3
+ //#region ../../plugins/acryl-kv-json/src/open.d.ts
4
+ interface OpenKvOptions {
5
+ /** The JSON file; its folder is created if missing. */
6
+ readonly path: string;
7
+ }
8
+ /** Open (and create, when missing) a JSON-file store. @throws when the file exists and is not a readable kv file. */
9
+ declare function openKv(options: OpenKvOptions): Promise<KvOpened>;
10
+ //#endregion
11
+ export { openKv as n, OpenKvOptions as t };
@@ -0,0 +1,57 @@
1
+ import { a as compareKeys, c as runChange, i as codePoints, o as decodeValue, r as checkKey, s as encodeValue } from "./src-DRFVEQQb.js";
2
+ //#region ../../plugins/acryl-kv-db/src/open.ts
3
+ const IDENTIFIER = /^[a-z_][a-z0-9_]*$/u;
4
+ /** The `kv` port over a `db`. It does not own the database: whoever opened it closes it, and calls after that reject. */
5
+ function kvOnDb(db, options = {}) {
6
+ const table = options.table ?? "kv";
7
+ if (!IDENTIFIER.test(table)) throw new TypeError(`acryl-kv-db: the table name must be a plain lower case SQL identifier, got ${JSON.stringify(table)}`);
8
+ let ready;
9
+ const ensure = () => {
10
+ ready ??= db.exec(`CREATE TABLE IF NOT EXISTS ${table} (key TEXT PRIMARY KEY, value TEXT NOT NULL)`).catch((error) => {
11
+ ready = void 0;
12
+ throw error;
13
+ });
14
+ return ready;
15
+ };
16
+ /**
17
+ * Run a statement after the table exists. The table's statement and this one are both handed to the database at once (its queue keeps
18
+ * their order), so a `close()` called right after a write cannot slip between them and leave the write on a closed database.
19
+ */
20
+ const after = async (work) => {
21
+ const created = ensure();
22
+ const result = work();
23
+ const [, value] = await Promise.all([created, result]);
24
+ return value;
25
+ };
26
+ const upsert = `INSERT INTO ${table} (key, value) VALUES (?, ?) ON CONFLICT (key) DO UPDATE SET value = excluded.value`;
27
+ return {
28
+ async get(key) {
29
+ checkKey(key);
30
+ const row = await after(() => db.get(`SELECT value FROM ${table} WHERE key = ?`, key));
31
+ return row === void 0 ? void 0 : decodeValue(row.value);
32
+ },
33
+ async set(key, value) {
34
+ checkKey(key);
35
+ const text = encodeValue(value);
36
+ await after(() => db.run(upsert, key, text));
37
+ },
38
+ async update(key, change) {
39
+ checkKey(key);
40
+ return after(() => db.transaction(async (tx) => {
41
+ const row = await tx.get(`SELECT value FROM ${table} WHERE key = ?`, key);
42
+ const text = encodeValue(runChange(change, row === void 0 ? void 0 : decodeValue(row.value)));
43
+ await tx.run(upsert, key, text);
44
+ return decodeValue(text);
45
+ }));
46
+ },
47
+ async delete(key) {
48
+ checkKey(key);
49
+ await after(() => db.run(`DELETE FROM ${table} WHERE key = ?`, key));
50
+ },
51
+ async list(prefix = "") {
52
+ return (await after(() => prefix === "" ? db.all(`SELECT key FROM ${table}`) : db.all(`SELECT key FROM ${table} WHERE substr(key, 1, ?) = ?`, codePoints(prefix), prefix))).map((row) => row.key).sort(compareKeys);
53
+ }
54
+ };
55
+ }
56
+ //#endregion
57
+ export { kvOnDb as t };
@@ -0,0 +1,12 @@
1
+ import { t as Db } from "./database-DBHdwefi.js";
2
+ import { n as Kv } from "./kv-9f-AlRKN.js";
3
+
4
+ //#region ../../plugins/acryl-kv-db/src/open.d.ts
5
+ interface KvOnDbOptions {
6
+ /** The table that holds the documents. Defaults to `kv`; a plain SQL identifier. */
7
+ readonly table?: string;
8
+ }
9
+ /** The `kv` port over a `db`. It does not own the database: whoever opened it closes it, and calls after that reject. */
10
+ declare function kvOnDb(db: Db, options?: KvOnDbOptions): Kv;
11
+ //#endregion
12
+ export { kvOnDb as n, KvOnDbOptions as t };
@@ -0,0 +1,224 @@
1
+ import { a as compareKeys, c as runChange, o as decodeValue, r as checkKey, s as encodeValue } from "./src-DRFVEQQb.js";
2
+ import { mkdir, open, readFile, readdir, rename, rm } from "node:fs/promises";
3
+ import { basename, dirname, join, resolve } from "node:path";
4
+ //#region ../../plugins/acryl-kv-json/src/open.ts
5
+ /**
6
+ * The plain way to open the JSON-file provider, for code without Cordis (an acrylblends app): `openKv({ path })` reads one JSON file into
7
+ * memory and resolves the `kv` port with the function that closes it. The Cordis plugin is a thin wrapper over this, so both run one code
8
+ * path. This entry imports nothing from Cordis.
9
+ *
10
+ * Every write persists the whole map: serialize to a temporary file in the same folder, flush it, rename it over the file, and flush the
11
+ * folder where the platform allows. The call resolves after the rename, so a crash leaves the old file or the new one, never half of one.
12
+ * Writes are grouped: the calls made in one turn of the event loop, and those that queue while a file write is in flight, are applied in
13
+ * call order and persisted together by one write, so a burst of calls costs one flush and one rename, not one each (on Windows each costs
14
+ * tens of milliseconds). One process owns the
15
+ * file: two writers would overwrite each other.
16
+ */
17
+ /** The file's own format version, for a later change of layout. */
18
+ const FORMAT = 1;
19
+ /** Stray temporary files from a crash end in `.tmp` and start with the file's name. */
20
+ const tempPrefix = (file) => `${basename(file)}.`;
21
+ /** The file content for a map of key to JSON text, keys in code point order, so the same data is the same bytes. */
22
+ function serialize(entries) {
23
+ const body = [...entries.keys()].sort(compareKeys).map((key) => `${JSON.stringify(key)}:${entries.get(key)}`).join(",");
24
+ return `{"version":${FORMAT},"entries":{${body}}}\n`;
25
+ }
26
+ function unreadable(file, reason) {
27
+ return /* @__PURE__ */ new Error(`acryl-kv-json: ${file} is not a readable kv file (${reason}); it was not changed`);
28
+ }
29
+ /** The entries of a file, or none when it does not exist. A file that exists and does not parse is an error: it is never started over. */
30
+ async function load(file) {
31
+ let text;
32
+ try {
33
+ text = await readFile(file, "utf8");
34
+ } catch (error) {
35
+ if (error.code === "ENOENT") return /* @__PURE__ */ new Map();
36
+ throw error;
37
+ }
38
+ let parsed;
39
+ try {
40
+ parsed = JSON.parse(text);
41
+ } catch (error) {
42
+ throw unreadable(file, error.message);
43
+ }
44
+ if (typeof parsed !== "object" || parsed === null || parsed.version !== FORMAT) throw unreadable(file, "not a version 1 kv file");
45
+ const entries = parsed.entries;
46
+ if (typeof entries !== "object" || entries === null || Array.isArray(entries)) throw unreadable(file, "no entries object");
47
+ return new Map(Object.entries(entries).map(([key, value]) => [key, JSON.stringify(value)]));
48
+ }
49
+ /** Remove the temporary files an earlier crash left beside the file. */
50
+ async function removeStrays(file) {
51
+ const prefix = tempPrefix(file);
52
+ for (const name of await readdir(dirname(file))) if (name.startsWith(prefix) && name.endsWith(".tmp")) await rm(join(dirname(file), name), { force: true });
53
+ }
54
+ const RENAME_RETRIES = 8;
55
+ /** Rename over the target. Windows refuses while a scanner or an indexer holds the target for a moment, so it is retried briefly. */
56
+ async function replace(from, to) {
57
+ for (let attempt = 0;; attempt += 1) try {
58
+ await rename(from, to);
59
+ return;
60
+ } catch (error) {
61
+ const code = error.code;
62
+ if (attempt >= RENAME_RETRIES || code !== "EPERM" && code !== "EBUSY" && code !== "EACCES") throw error;
63
+ await new Promise((resolveWait) => setTimeout(resolveWait, 10 * (attempt + 1)));
64
+ }
65
+ }
66
+ /** Flush the folder entry of a renamed file (POSIX); Windows cannot open a folder, and a filesystem that refuses is no worse than before. */
67
+ async function flushFolder(folder) {
68
+ if (process.platform === "win32") return;
69
+ try {
70
+ const handle = await open(folder, "r");
71
+ try {
72
+ await handle.sync();
73
+ } finally {
74
+ await handle.close();
75
+ }
76
+ } catch {}
77
+ }
78
+ /** Open (and create, when missing) a JSON-file store. @throws when the file exists and is not a readable kv file. */
79
+ async function openKv(options) {
80
+ const file = resolve(options.path);
81
+ await mkdir(dirname(file), { recursive: true });
82
+ await removeStrays(file);
83
+ let state = await load(file);
84
+ let closed = false;
85
+ let sequence = 0;
86
+ /** Calls waiting for the next file write, in call order. */
87
+ let queue = [];
88
+ /** Whether the loop that writes the queue runs; cleared by the loop itself, so a call queued after it ends starts a new one. */
89
+ let draining = false;
90
+ /** The latest loop, for `close` to wait on. */
91
+ let drained = Promise.resolve();
92
+ const guard = () => {
93
+ if (closed) throw new Error(`acryl-kv-json: ${file} is closed`);
94
+ };
95
+ /** Persist a map: the file is the old one or this one, never between. */
96
+ const persist = async (next) => {
97
+ sequence += 1;
98
+ const temp = join(dirname(file), `${tempPrefix(file)}${process.pid}.${sequence}.tmp`);
99
+ try {
100
+ const handle = await open(temp, "w");
101
+ try {
102
+ await handle.writeFile(serialize(next), "utf8");
103
+ await handle.sync();
104
+ } finally {
105
+ await handle.close();
106
+ }
107
+ await replace(temp, file);
108
+ } catch (error) {
109
+ await rm(temp, { force: true });
110
+ throw error;
111
+ }
112
+ await flushFolder(dirname(file));
113
+ };
114
+ /**
115
+ * Write the queue until it is empty. Each round takes every call queued so far and applies them in order to one copy of the state. A call
116
+ * whose change throws rejects with its error and changes nothing, and the others in the round still apply. The copy becomes the state
117
+ * only once it is on disk. A failed file write rejects every call in its round and leaves the state as it was.
118
+ */
119
+ const drain = async () => {
120
+ try {
121
+ await Promise.resolve();
122
+ await rounds();
123
+ } finally {
124
+ draining = false;
125
+ }
126
+ };
127
+ const rounds = async () => {
128
+ while (queue.length > 0) {
129
+ const round = queue;
130
+ queue = [];
131
+ const draft = new Map(state);
132
+ const applied = [];
133
+ for (const call of round) {
134
+ let change;
135
+ try {
136
+ change = call.change((key) => draft.get(key));
137
+ } catch (error) {
138
+ call.reject(error);
139
+ continue;
140
+ }
141
+ if (change.text === void 0) draft.delete(change.key);
142
+ else draft.set(change.key, change.text);
143
+ applied.push({
144
+ call,
145
+ result: change.result
146
+ });
147
+ }
148
+ if (applied.length === 0) continue;
149
+ try {
150
+ await persist(draft);
151
+ } catch (error) {
152
+ for (const { call } of applied) call.reject(error);
153
+ continue;
154
+ }
155
+ state = draft;
156
+ for (const { call, result } of applied) call.resolve(result);
157
+ }
158
+ };
159
+ /** Queue one change behind every earlier call; it resolves once a file write that contains it is on disk. */
160
+ const write = (change) => {
161
+ guard();
162
+ const done = new Promise((resolveCall, rejectCall) => {
163
+ queue.push({
164
+ change,
165
+ resolve: resolveCall,
166
+ reject: rejectCall
167
+ });
168
+ });
169
+ if (!draining) {
170
+ draining = true;
171
+ drained = drain();
172
+ }
173
+ return done;
174
+ };
175
+ return {
176
+ kv: {
177
+ async get(key) {
178
+ guard();
179
+ checkKey(key);
180
+ const text = state.get(key);
181
+ return text === void 0 ? void 0 : decodeValue(text);
182
+ },
183
+ async set(key, value) {
184
+ checkKey(key);
185
+ const text = encodeValue(value);
186
+ await write(() => ({
187
+ key,
188
+ text,
189
+ result: void 0
190
+ }));
191
+ },
192
+ async update(key, change) {
193
+ checkKey(key);
194
+ return write((read) => {
195
+ const text = read(key);
196
+ const encoded = encodeValue(runChange(change, text === void 0 ? void 0 : decodeValue(text)));
197
+ return {
198
+ key,
199
+ text: encoded,
200
+ result: decodeValue(encoded)
201
+ };
202
+ });
203
+ },
204
+ async delete(key) {
205
+ checkKey(key);
206
+ await write(() => ({
207
+ key,
208
+ text: void 0,
209
+ result: void 0
210
+ }));
211
+ },
212
+ async list(prefix = "") {
213
+ guard();
214
+ return [...state.keys()].filter((key) => key.startsWith(prefix)).sort(compareKeys);
215
+ }
216
+ },
217
+ close: async () => {
218
+ closed = true;
219
+ await drained;
220
+ }
221
+ };
222
+ }
223
+ //#endregion
224
+ export { openKv as t };
@@ -0,0 +1,27 @@
1
+ import { t as Db } from "./database-DBHdwefi.js";
2
+
3
+ //#region ../../plugins/acryl-db-sqlite/src/open.d.ts
4
+ interface OpenDbOptions {
5
+ /** The database file, its folder created if missing; `:memory:` for a database that lives until `close`. */
6
+ readonly path: string;
7
+ /** A folder of `NNN-name.sql` files numbered from 1, as a path or a file URL, applied in order before `openDb` resolves. */
8
+ readonly migrations?: string | URL;
9
+ /** How long SQLite waits for a competing file lock, in milliseconds. Defaults to 5000. */
10
+ readonly busyTimeoutMs?: number;
11
+ /** The WAL auto-checkpoint threshold in pages; 0 disables it. Defaults to 1000. */
12
+ readonly walAutoCheckpointPages?: number;
13
+ }
14
+ /** An open database: the port, and the one function that closes it. */
15
+ interface OpenDb {
16
+ readonly db: Db;
17
+ /** Waits for running operations and transactions, checkpoints the WAL and releases the file. Calling it again does nothing. */
18
+ close(): Promise<void>;
19
+ }
20
+ /**
21
+ * Open, configure and migrate a SQLite database.
22
+ * @throws when the migration files are misnamed or misnumbered, or a migration fails (the file is closed, and unchanged), or the
23
+ * database's schema is newer than the migrations.
24
+ */
25
+ declare function openDb(options: OpenDbOptions): Promise<OpenDb>;
26
+ //#endregion
27
+ export { OpenDbOptions as n, openDb as r, OpenDb as t };
@@ -1,4 +1,4 @@
1
- import { UnsupportedPathError } from "./router.js";
1
+ import { a as UnsupportedPathError } from "./router-Be_o6nFu.js";
2
2
  //#region ../../plugins/acryl-router/src/core/router/pattern-router/router.ts
3
3
  const emptyParams = Object.create(null);
4
4
  var PatternRouter = class {
@@ -0,0 +1,24 @@
1
+ //#region ../../plugins/acryl-router/src/core/middleware/powered-by/index.ts
2
+ /**
3
+ * Powered By Middleware for Acryl.
4
+ *
5
+ * @param options - The options for the Powered By Middleware.
6
+ * @returns {MiddlewareHandler} The middleware handler function.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { poweredBy } from 'acrylblends/powered-by'
11
+ *
12
+ * const app = new Acryl()
13
+ *
14
+ * app.use(poweredBy()) // With options: poweredBy({ serverName: "My Server" })
15
+ * ```
16
+ */
17
+ const poweredBy = (options) => {
18
+ return async function poweredBy(c, next) {
19
+ await next();
20
+ c.res.headers.set("X-Powered-By", options?.serverName ?? "Acryl");
21
+ };
22
+ };
23
+ //#endregion
24
+ export { poweredBy as t };
package/lib/powered-by.js CHANGED
@@ -1,24 +1,2 @@
1
- //#region ../../plugins/acryl-router/src/core/middleware/powered-by/index.ts
2
- /**
3
- * Powered By Middleware for Acryl.
4
- *
5
- * @param options - The options for the Powered By Middleware.
6
- * @returns {MiddlewareHandler} The middleware handler function.
7
- *
8
- * @example
9
- * ```ts
10
- * import { poweredBy } from 'acrylblends/powered-by'
11
- *
12
- * const app = new Acryl()
13
- *
14
- * app.use(poweredBy()) // With options: poweredBy({ serverName: "My Server" })
15
- * ```
16
- */
17
- const poweredBy = (options) => {
18
- return async function poweredBy(c, next) {
19
- await next();
20
- c.res.headers.set("X-Powered-By", options?.serverName ?? "Acryl");
21
- };
22
- };
23
- //#endregion
1
+ import { t as poweredBy } from "./powered-by-CXQNjNIX.js";
24
2
  export { poweredBy };