acrylblends 0.8.1 → 0.9.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 (235) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +83 -7
  3. package/dist/index.js.map +1 -1
  4. package/lib/audit-BXnYsLge.d.ts +58 -0
  5. package/lib/cell-ChU41DZD.d.ts +32 -0
  6. package/lib/client-modules-CLvWOjbd.js +267 -0
  7. package/lib/connection-ZLEso7XL.d.ts +25 -0
  8. package/lib/conninfo.d.ts +1 -23
  9. package/lib/cordis/db-sqlite.d.ts +56 -0
  10. package/lib/cordis/db-sqlite.js +58 -0
  11. package/lib/cordis/db.d.ts +8 -0
  12. package/lib/cordis/db.js +1 -0
  13. package/lib/cordis/door.d.ts +159 -0
  14. package/lib/cordis/door.js +757 -0
  15. package/lib/cordis/inspect.d.ts +77 -0
  16. package/lib/cordis/inspect.js +149 -0
  17. package/lib/cordis/kv-db.d.ts +16 -0
  18. package/lib/cordis/kv-db.js +18 -0
  19. package/lib/cordis/kv-json.d.ts +16 -0
  20. package/lib/cordis/kv-json.js +44 -0
  21. package/lib/cordis/kv.d.ts +8 -0
  22. package/lib/cordis/kv.js +1 -0
  23. package/lib/cordis/node-server.d.ts +45 -0
  24. package/lib/cordis/node-server.js +93 -0
  25. package/lib/cordis/router-http.d.ts +56 -0
  26. package/lib/cordis/router-http.js +117 -0
  27. package/lib/cordis/router.d.ts +8 -0
  28. package/lib/cordis/router.js +7 -0
  29. package/lib/cordis/state/react.d.ts +6 -0
  30. package/lib/cordis/state/react.js +11 -0
  31. package/lib/cordis/state.d.ts +33 -0
  32. package/lib/cordis/state.js +163 -0
  33. package/lib/core-CaY8XDZ6.js +19 -0
  34. package/lib/database-DBHdwefi.d.ts +44 -0
  35. package/lib/db/conformance.d.ts +11 -0
  36. package/lib/db/conformance.js +267 -0
  37. package/lib/db/sqlite.d.ts +1 -1
  38. package/lib/db/sqlite.js +1 -196
  39. package/lib/db.d.ts +2 -1
  40. package/lib/{src-0hI7M7cN.js → deprecated-BP4fPt38.js} +0 -17
  41. package/lib/door/host.d.ts +24 -0
  42. package/lib/door/host.js +2 -0
  43. package/lib/door/page.d.ts +105 -0
  44. package/lib/door/page.js +1030 -0
  45. package/lib/door/protocol.d.ts +2 -0
  46. package/lib/door/protocol.js +197 -0
  47. package/lib/error-t4N2js2I.d.ts +8 -0
  48. package/lib/etag-DaKMOjty.js +135 -0
  49. package/lib/etag.js +1 -134
  50. package/lib/helpers-CvTauQT5.js +5 -0
  51. package/lib/http-exception-kpGJkmpi.d.ts +57 -0
  52. package/lib/http-exception.d.ts +1 -56
  53. package/lib/{index-BLTYsyc1.d.ts → index-BnGgRKTv.d.ts} +3 -39
  54. package/lib/index-BqVQkTnu.d.ts +98 -0
  55. package/lib/index-Dmst2QCQ.d.ts +44 -0
  56. package/lib/index.d.ts +1 -1
  57. package/lib/index.js +2 -1
  58. package/lib/jwk-LkzeoaU8.js +117 -0
  59. package/lib/jwk.js +1 -116
  60. package/lib/jwt-CskdhEW9.js +115 -0
  61. package/lib/jwt.js +2 -114
  62. package/lib/kv/conformance.d.ts +13 -0
  63. package/lib/kv/conformance.js +301 -0
  64. package/lib/kv/db.d.ts +2 -2
  65. package/lib/kv/json.d.ts +1 -1
  66. package/lib/kv-9f-AlRKN.d.ts +39 -0
  67. package/lib/kv.d.ts +2 -1
  68. package/lib/language-D9a4zqvn.js +198 -0
  69. package/lib/language.js +1 -197
  70. package/lib/middleware-CPQ8himN.js +12 -0
  71. package/lib/node-server/serve-static.d.ts +0 -1
  72. package/lib/node-server/serve-static.js +1 -1
  73. package/lib/node-server.d.ts +1 -7
  74. package/lib/node-server.js +3 -1586
  75. package/lib/open-CMhnJODn.js +197 -0
  76. package/lib/protocol-BizVt4J6.d.ts +144 -0
  77. package/lib/request-id-CKVvHOO1.js +34 -0
  78. package/lib/request-id.js +1 -33
  79. package/lib/secure-headers-mP3j6Hm6.js +163 -0
  80. package/lib/secure-headers.js +1 -162
  81. package/lib/{serve-static-B849HlX2.js → serve-static-3uo_9rjF.js} +1 -4
  82. package/lib/server-DvgMGtzo.js +1323 -0
  83. package/lib/snapshot-text-D3NspDyT.js +338 -0
  84. package/lib/src-CwABFr6r.js +328 -0
  85. package/lib/timeout.d.ts +1 -1
  86. package/lib/timing-Cky7C1Jf.js +183 -0
  87. package/lib/timing.js +1 -182
  88. package/package.json +89 -1
  89. package/plugins/acryl-db/plugin.json +6 -1
  90. package/plugins/acryl-db-sqlite/plugin.json +4 -0
  91. package/plugins/acryl-db-sqlite/src/facade/node.ts +1 -1
  92. package/plugins/acryl-db-sqlite/src/index.ts +2 -2
  93. package/plugins/acryl-db-sqlite/src/open.ts +2 -2
  94. package/plugins/acryl-door/plugin.json +4 -1
  95. package/plugins/acryl-door/src/host/http.ts +2 -2
  96. package/plugins/acryl-door/src/host/mcp-routes.ts +1 -1
  97. package/plugins/acryl-door/src/host/operator-routes.ts +1 -1
  98. package/plugins/acryl-door/src/host/page-routes.ts +3 -3
  99. package/plugins/acryl-door/src/index.ts +2 -2
  100. package/plugins/acryl-inspect/plugin.json +4 -1
  101. package/plugins/acryl-inspect/src/service.ts +2 -2
  102. package/plugins/acryl-kv/plugin.json +6 -1
  103. package/plugins/acryl-kv-db/plugin.json +4 -0
  104. package/plugins/acryl-kv-db/src/index.ts +1 -1
  105. package/plugins/acryl-kv-db/src/open.ts +3 -3
  106. package/plugins/acryl-kv-json/plugin.json +4 -0
  107. package/plugins/acryl-kv-json/src/index.ts +1 -1
  108. package/plugins/acryl-kv-json/src/open.ts +2 -2
  109. package/plugins/acryl-node-server/plugin.json +5 -1
  110. package/plugins/acryl-node-server/src/adapter/conninfo.ts +1 -1
  111. package/plugins/acryl-node-server/src/adapter/early-hints.ts +1 -1
  112. package/plugins/acryl-node-server/src/adapter/serve-static.ts +2 -2
  113. package/plugins/acryl-node-server/src/adapter/websocket.ts +2 -2
  114. package/plugins/acryl-node-server/src/client-modules.ts +2 -2
  115. package/plugins/acryl-node-server/src/index.ts +1 -1
  116. package/plugins/acryl-router/plugin.json +11 -1
  117. package/plugins/acryl-router/src/connection.d.ts +25 -0
  118. package/plugins/acryl-router/src/core/app-base.d.ts +215 -0
  119. package/plugins/acryl-router/src/core/app.d.ts +19 -0
  120. package/plugins/acryl-router/src/core/client/client.d.ts +4 -0
  121. package/plugins/acryl-router/src/core/client/fetch-result-please.d.ts +35 -0
  122. package/plugins/acryl-router/src/core/client/index.d.ts +7 -0
  123. package/plugins/acryl-router/src/core/client/types.d.ts +229 -0
  124. package/plugins/acryl-router/src/core/client/utils.d.ts +18 -0
  125. package/plugins/acryl-router/src/core/compose.d.ts +14 -0
  126. package/plugins/acryl-router/src/core/context.d.ts +443 -0
  127. package/plugins/acryl-router/src/core/helper/accepts/accepts.d.ts +30 -0
  128. package/plugins/acryl-router/src/core/helper/accepts/index.d.ts +5 -0
  129. package/plugins/acryl-router/src/core/helper/conninfo/index.d.ts +5 -0
  130. package/plugins/acryl-router/src/core/helper/conninfo/types.d.ts +36 -0
  131. package/plugins/acryl-router/src/core/helper/cookie/index.d.ts +25 -0
  132. package/plugins/acryl-router/src/core/helper/css/common.d.ts +59 -0
  133. package/plugins/acryl-router/src/core/helper/css/index.d.ts +80 -0
  134. package/plugins/acryl-router/src/core/helper/dev/index.d.ts +20 -0
  135. package/plugins/acryl-router/src/core/helper/factory/index.d.ts +82 -0
  136. package/plugins/acryl-router/src/core/helper/html/index.d.ts +8 -0
  137. package/plugins/acryl-router/src/core/helper/proxy/index.d.ts +73 -0
  138. package/plugins/acryl-router/src/core/helper/route/index.d.ts +75 -0
  139. package/plugins/acryl-router/src/core/helper/ssg/index.d.ts +7 -0
  140. package/plugins/acryl-router/src/core/helper/ssg/middleware.d.ts +44 -0
  141. package/plugins/acryl-router/src/core/helper/ssg/plugins.d.ts +27 -0
  142. package/plugins/acryl-router/src/core/helper/ssg/ssg.d.ts +91 -0
  143. package/plugins/acryl-router/src/core/helper/ssg/utils.d.ts +16 -0
  144. package/plugins/acryl-router/src/core/helper/streaming/index.d.ts +8 -0
  145. package/plugins/acryl-router/src/core/helper/streaming/sse.d.ts +13 -0
  146. package/plugins/acryl-router/src/core/helper/streaming/stream.d.ts +3 -0
  147. package/plugins/acryl-router/src/core/helper/streaming/text.d.ts +3 -0
  148. package/plugins/acryl-router/src/core/helper/streaming/utils.d.ts +1 -0
  149. package/plugins/acryl-router/src/core/helper/testing/index.d.ts +13 -0
  150. package/plugins/acryl-router/src/core/helper/websocket/index.d.ts +70 -0
  151. package/plugins/acryl-router/src/core/http-exception.d.ts +58 -0
  152. package/plugins/acryl-router/src/core/index.d.ts +37 -0
  153. package/plugins/acryl-router/src/core/jsx/base.d.ts +61 -0
  154. package/plugins/acryl-router/src/core/jsx/children.d.ts +9 -0
  155. package/plugins/acryl-router/src/core/jsx/components.d.ts +15 -0
  156. package/plugins/acryl-router/src/core/jsx/constants.d.ts +6 -0
  157. package/plugins/acryl-router/src/core/jsx/context.d.ts +51 -0
  158. package/plugins/acryl-router/src/core/jsx/dom/components.d.ts +10 -0
  159. package/plugins/acryl-router/src/core/jsx/dom/context.d.ts +3 -0
  160. package/plugins/acryl-router/src/core/jsx/dom/css.d.ts +83 -0
  161. package/plugins/acryl-router/src/core/jsx/dom/hooks/index.d.ts +39 -0
  162. package/plugins/acryl-router/src/core/jsx/dom/intrinsic-element/components.d.ts +16 -0
  163. package/plugins/acryl-router/src/core/jsx/dom/jsx-dev-runtime.d.ts +8 -0
  164. package/plugins/acryl-router/src/core/jsx/dom/jsx-runtime.d.ts +7 -0
  165. package/plugins/acryl-router/src/core/jsx/dom/render.d.ts +73 -0
  166. package/plugins/acryl-router/src/core/jsx/dom/utils.d.ts +1 -0
  167. package/plugins/acryl-router/src/core/jsx/hooks/index.d.ts +47 -0
  168. package/plugins/acryl-router/src/core/jsx/index.d.ts +76 -0
  169. package/plugins/acryl-router/src/core/jsx/intrinsic-element/common.d.ts +6 -0
  170. package/plugins/acryl-router/src/core/jsx/intrinsic-element/components.d.ts +13 -0
  171. package/plugins/acryl-router/src/core/jsx/intrinsic-elements.d.ts +735 -0
  172. package/plugins/acryl-router/src/core/jsx/streaming.d.ts +36 -0
  173. package/plugins/acryl-router/src/core/jsx/types.d.ts +36 -0
  174. package/plugins/acryl-router/src/core/jsx/utils.d.ts +4 -0
  175. package/plugins/acryl-router/src/core/request/constants.d.ts +1 -0
  176. package/plugins/acryl-router/src/core/request.d.ts +306 -0
  177. package/plugins/acryl-router/src/core/router/reg-exp-router/index.d.ts +6 -0
  178. package/plugins/acryl-router/src/core/router/reg-exp-router/matcher.d.ts +7 -0
  179. package/plugins/acryl-router/src/core/router/reg-exp-router/node.d.ts +13 -0
  180. package/plugins/acryl-router/src/core/router/reg-exp-router/prepared-router.d.ts +17 -0
  181. package/plugins/acryl-router/src/core/router/reg-exp-router/router.d.ts +11 -0
  182. package/plugins/acryl-router/src/core/router/reg-exp-router/trie.d.ts +8 -0
  183. package/plugins/acryl-router/src/core/router/smart-router/index.d.ts +5 -0
  184. package/plugins/acryl-router/src/core/router/smart-router/router.d.ts +11 -0
  185. package/plugins/acryl-router/src/core/router/trie-router/index.d.ts +5 -0
  186. package/plugins/acryl-router/src/core/router/trie-router/node.d.ts +6 -0
  187. package/plugins/acryl-router/src/core/router/trie-router/router.d.ts +7 -0
  188. package/plugins/acryl-router/src/core/router/utils.d.ts +1 -0
  189. package/plugins/acryl-router/src/core/router.d.ts +97 -0
  190. package/plugins/acryl-router/src/core/types.d.ts +573 -0
  191. package/plugins/acryl-router/src/core/utils/accept.d.ts +6 -0
  192. package/plugins/acryl-router/src/core/utils/body.d.ts +79 -0
  193. package/plugins/acryl-router/src/core/utils/buffer.d.ts +17 -0
  194. package/plugins/acryl-router/src/core/utils/color.d.ts +21 -0
  195. package/plugins/acryl-router/src/core/utils/concurrent.d.ts +11 -0
  196. package/plugins/acryl-router/src/core/utils/constants.d.ts +4 -0
  197. package/plugins/acryl-router/src/core/utils/cookie.d.ts +41 -0
  198. package/plugins/acryl-router/src/core/utils/crypto.d.ts +15 -0
  199. package/plugins/acryl-router/src/core/utils/handler.d.ts +6 -0
  200. package/plugins/acryl-router/src/core/utils/headers.d.ts +8 -0
  201. package/plugins/acryl-router/src/core/utils/html.d.ts +44 -0
  202. package/plugins/acryl-router/src/core/utils/http-status.d.ts +32 -0
  203. package/plugins/acryl-router/src/core/utils/mime.d.ts +70 -0
  204. package/plugins/acryl-router/src/core/utils/stream.d.ts +31 -0
  205. package/plugins/acryl-router/src/core/utils/types.d.ts +128 -0
  206. package/plugins/acryl-router/src/core/utils/url.d.ts +44 -0
  207. package/plugins/acryl-router/src/core/validator/index.d.ts +7 -0
  208. package/plugins/acryl-router/src/core/validator/utils.d.ts +29 -0
  209. package/plugins/acryl-router/src/core/validator/validator.d.ts +16 -0
  210. package/plugins/acryl-router/src/helpers/index.d.ts +17 -0
  211. package/plugins/acryl-router/src/helpers/schema-validator.d.ts +54 -0
  212. package/plugins/acryl-router-http/plugin.json +4 -1
  213. package/plugins/acryl-router-http/src/index.ts +1 -1
  214. package/plugins/acryl-state/plugin.json +5 -1
  215. package/plugins/acryl-state/src/service.ts +3 -3
  216. package/plugins/tsconfig.json +32 -20
  217. package/docs/framework/UPSTREAM.md +0 -3
  218. package/docs/framework/upstream.json +0 -9
  219. package/lib/index-D4FAsBZu.d.ts +0 -85
  220. package/plugins/acryl-db/upstream.json +0 -18
  221. package/plugins/acryl-db-sqlite/upstream.json +0 -21
  222. package/plugins/acryl-door/upstream.json +0 -28
  223. package/plugins/acryl-inspect/upstream.json +0 -18
  224. package/plugins/acryl-kv/upstream.json +0 -18
  225. package/plugins/acryl-kv-db/upstream.json +0 -21
  226. package/plugins/acryl-kv-json/upstream.json +0 -22
  227. package/plugins/acryl-node-server/upstream.json +0 -21
  228. package/plugins/acryl-router/upstream.json +0 -20
  229. package/plugins/acryl-router-http/upstream.json +0 -22
  230. package/plugins/acryl-state/NOTICE +0 -30
  231. package/plugins/acryl-state/upstream.json +0 -22
  232. package/plugins/desktop/upstream.json +0 -12
  233. package/plugins/desktop-web/upstream.json +0 -12
  234. package/templates/todo/upstream.json +0 -12
  235. /package/lib/{index-CTy4N7ng.d.ts → deprecated-CTy4N7ng.d.ts} +0 -0
@@ -0,0 +1,58 @@
1
+ import { _ as UiResult, g as UiRequest, n as ChannelToHost, t as AuditEntry } from "./protocol-BizVt4J6.js";
2
+
3
+ //#region ../../plugins/acryl-door/src/host/channel.d.ts
4
+ /** The slice of a page's stream the channel needs, so tests can supply their own. */
5
+ interface PageStream {
6
+ send(data: string): void;
7
+ close(): void;
8
+ }
9
+ declare class UiChannel {
10
+ private readonly connections;
11
+ private readonly pending;
12
+ private nextId;
13
+ private clock;
14
+ private closed;
15
+ /**
16
+ * Register a page's stream. A stream already open for the same window is closed first, and its calls settle as `disconnected`.
17
+ * @returns the function to call when this stream ends.
18
+ */
19
+ attach(windowId: string, focused: boolean, stream: PageStream): () => void;
20
+ /** A message a page sent by POST. Only the window that was asked may answer a call, so another page cannot forge a result. */
21
+ receive(windowId: string, message: ChannelToHost): void;
22
+ /** True when at least one page is connected. */
23
+ get connected(): boolean;
24
+ /** The windows currently connected, most recently active first (for diagnostics and tests). */
25
+ windows(): readonly {
26
+ windowId: string;
27
+ focused: boolean;
28
+ }[];
29
+ /**
30
+ * Ask the current page to do something.
31
+ * @throws UiControlError `no-window`, `timeout`, `aborted`, `unloaded`, `disconnected`, or whatever the page refused with.
32
+ */
33
+ call(request: UiRequest, options?: {
34
+ signal?: AbortSignal;
35
+ timeoutMs?: number;
36
+ }): Promise<UiResult>;
37
+ /** Close every page's stream and settle every pending call as `unloaded`. */
38
+ close(): void;
39
+ private byRecency;
40
+ /** Forget a connection; its calls in flight settle as `disconnected` at once rather than waiting for their timeout. */
41
+ private drop;
42
+ private settle;
43
+ }
44
+ //#endregion
45
+ //#region ../../plugins/acryl-door/src/host/audit.d.ts
46
+ /** The audit log below a folder the caller owns (the app's `.acryl/` here; ACRYL's app home for the DSH face). */
47
+ declare function auditPath(folder: string): string;
48
+ declare class AuditLog {
49
+ private readonly path;
50
+ constructor(path: string);
51
+ /** Append one line; a failing disk never breaks the tool call. */
52
+ record(entry: AuditEntry): void;
53
+ /** The most recent entries, oldest first. */
54
+ recent(limit?: number): AuditEntry[];
55
+ private rotateIfLarge;
56
+ }
57
+ //#endregion
58
+ export { UiChannel as i, auditPath as n, PageStream as r, AuditLog as t };
@@ -0,0 +1,32 @@
1
+ //#region ../../plugins/acryl-state/src/cell.d.ts
2
+ /**
3
+ * Observable cells: the reactive core of the state service, with no Cordis and no DOM. A cell holds one value, tells its
4
+ * subscribers when it changes, and can be derived from other cells. The shape follows VanJS's `state` and `derive`
5
+ * (spec 046, M5): small enough to read in one sitting, and the same cell serves a React hook, a terminal component and a
6
+ * server-sent stream.
7
+ */
8
+ type Listener<T> = (value: T, previous: T) => void;
9
+ interface ReadonlyCell<T> {
10
+ readonly key: string;
11
+ get(): T;
12
+ /** Call `listener` after every change (never for a set to an equal value). Returns the unsubscribe function. */
13
+ subscribe(listener: Listener<T>): () => void;
14
+ }
15
+ interface Cell<T> extends ReadonlyCell<T> {
16
+ set(value: T): void;
17
+ update(change: (current: T) => T): void;
18
+ }
19
+ type ErrorSink = (error: unknown) => void;
20
+ /** A writable cell. `report` receives anything a listener throws; one failing listener never blocks the others. */
21
+ declare function createCell<T>(key: string, initial: T, report?: ErrorSink): Cell<T>;
22
+ type Values<D extends readonly ReadonlyCell<unknown>[]> = { [K in keyof D]: D[K] extends ReadonlyCell<infer V> ? V : never };
23
+ /**
24
+ * A read-only cell computed from other cells and recomputed whenever one of them changes. `dispose` detaches it from its
25
+ * inputs; after that it keeps its last value.
26
+ */
27
+ declare function createDerived<D extends readonly ReadonlyCell<unknown>[], T>(key: string, inputs: D, compute: (...values: Values<D>) => T, report?: ErrorSink): {
28
+ readonly cell: ReadonlyCell<T>;
29
+ readonly dispose: () => void;
30
+ };
31
+ //#endregion
32
+ export { createDerived as a, createCell as i, Listener as n, ReadonlyCell as r, Cell as t };
@@ -0,0 +1,267 @@
1
+ import { t as Acryl } from "./app-BM0rTCp7.js";
2
+ import "./core-CaY8XDZ6.js";
3
+ import { basePath } from "./route.js";
4
+ import "./helpers-CvTauQT5.js";
5
+ import { n as compileModule, t as MissingTypeScriptError } from "./transpile-QUK9b3eG.js";
6
+ import { dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
7
+ import { copyFileSync, mkdirSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "node:fs";
8
+ import { fileURLToPath } from "node:url";
9
+ //#region ../../plugins/acryl-node-server/src/client-modules.ts
10
+ /**
11
+ * Client components without a bundler. `clientModules({ root: 'src/client' })` is an app that serves the TypeScript and JSX modules of a
12
+ * folder to the browser as ES modules: a `.tsx`/`.ts`/`.jsx` file compiled with the app's own `typescript` (JSX for `acrylblends/jsx/dom`),
13
+ * a `.js`/`.mjs` file as it is. The framework's own browser imports (`acrylblends/jsx/dom` with its runtimes and `client`,
14
+ * `acrylblends/client` and `acrylblends/read-sse`) are rewritten to three self-contained files the same app serves, at a URL relative to each module, so a page needs
15
+ * one `<script type="module" src="/client/counter.tsx">` and no import map, under whatever path the app is routed at.
16
+ *
17
+ * Production runs without `typescript` (a deploy that leaves out devDependencies): `buildClientModules` writes the same compiled modules
18
+ * and the three browser files into a folder, and with `NODE_ENV=production` and `compiled` set, only that folder is served.
19
+ */
20
+ /** The folder the three browser files are served from, below the app's mount. A source folder of this name is not served. */
21
+ const RUNTIME_DIR = "@acrylblends";
22
+ /** The framework's browser imports and the browser file that provides each. */
23
+ const BROWSER_IMPORTS = {
24
+ "acrylblends/jsx/dom": "jsx-dom.js",
25
+ "acrylblends/jsx/dom/jsx-runtime": "jsx-dom.js",
26
+ "acrylblends/jsx/dom/jsx-dev-runtime": "jsx-dom.js",
27
+ "acrylblends/jsx/dom/client": "jsx-dom.js",
28
+ "acrylblends/client": "client.js",
29
+ "acrylblends/read-sse": "read-sse.js"
30
+ };
31
+ const RUNTIME_FILES = [
32
+ "jsx-dom.js",
33
+ "client.js",
34
+ "read-sse.js"
35
+ ];
36
+ const COMPILED = /* @__PURE__ */ new Set([
37
+ ".ts",
38
+ ".tsx",
39
+ ".jsx",
40
+ ".mts"
41
+ ]);
42
+ const SERVED = /* @__PURE__ */ new Set([
43
+ ...COMPILED,
44
+ ".js",
45
+ ".mjs"
46
+ ]);
47
+ const JS_TYPE = "text/javascript; charset=utf-8";
48
+ /** The cache bound when `cacheBytes` is not given. */
49
+ const DEFAULT_CACHE_BYTES = 16 * 1024 * 1024;
50
+ /** The framework's three browser files, next to the built module that contains this code. */
51
+ const defaultRuntimeDir = () => fileURLToPath(new URL("./browser/", import.meta.url));
52
+ /** A module path below the root (`widgets/counter.tsx`) with the URL prefix that reaches the browser files from it. */
53
+ const runtimePrefix = (relativePath) => {
54
+ const depth = relativePath.split("/").length - 1;
55
+ return depth === 0 ? "./" : "../".repeat(depth);
56
+ };
57
+ /** One client module compiled for the browser: TypeScript and JSX compiled, the framework's imports pointed at its browser files. */
58
+ function compileForBrowser(file, relativePath) {
59
+ const prefix = runtimePrefix(relativePath);
60
+ return compileModule(file, readFileSync(file, "utf8"), {
61
+ importSource: "acrylblends/jsx/dom",
62
+ defaultImportSource: "acrylblends/jsx/dom",
63
+ what: "is a client module",
64
+ rewrite: (specifier) => {
65
+ const target = BROWSER_IMPORTS[specifier];
66
+ return target === void 0 ? void 0 : `${prefix}${RUNTIME_DIR}/${target}`;
67
+ }
68
+ });
69
+ }
70
+ /**
71
+ * The path below the root a request names, or `undefined` when it must not be served: a `..` or dot segment, a backslash or NUL, an
72
+ * extension outside the served set, or a `.d.ts` file.
73
+ */
74
+ function servedPath(requestPath) {
75
+ let decoded;
76
+ try {
77
+ decoded = decodeURIComponent(requestPath);
78
+ } catch {
79
+ return;
80
+ }
81
+ const parts = decoded.split("/").filter((part) => part !== "");
82
+ if (parts.length === 0 || parts.some((part) => part.startsWith(".") || part.includes("\\") || part.includes("\0"))) return void 0;
83
+ const path = parts.join("/");
84
+ if (!SERVED.has(extname(path)) || path.endsWith(".d.ts")) return void 0;
85
+ return path;
86
+ }
87
+ /** A real file inside `root` (symbolic links followed), or `undefined`. */
88
+ function fileInside(root, path) {
89
+ try {
90
+ const file = realpathSync(join(root, ...path.split("/")));
91
+ return file.startsWith(root + sep) && statSync(file).isFile() ? file : void 0;
92
+ } catch {
93
+ return;
94
+ }
95
+ }
96
+ /** A file's validator: its size and modification time. */
97
+ const etagOf = (stat) => `"${stat.size.toString(36)}-${Math.trunc(stat.mtimeMs).toString(36)}"`;
98
+ /** Compiled modules, least recently served first, bounded by the UTF-8 bytes of their code. Exported for its tests. */
99
+ var CompileCache = class {
100
+ entries = /* @__PURE__ */ new Map();
101
+ bytes = 0;
102
+ limit;
103
+ constructor(limit) {
104
+ this.limit = limit;
105
+ }
106
+ get(file, mtimeMs, size) {
107
+ const entry = this.entries.get(file);
108
+ if (entry === void 0) return void 0;
109
+ this.entries.delete(file);
110
+ if (entry.mtimeMs !== mtimeMs || entry.size !== size) {
111
+ this.bytes -= entry.bytes;
112
+ return;
113
+ }
114
+ this.entries.set(file, entry);
115
+ return entry;
116
+ }
117
+ set(file, stat, code) {
118
+ const entry = {
119
+ mtimeMs: stat.mtimeMs,
120
+ size: stat.size,
121
+ etag: etagOf(stat),
122
+ code,
123
+ bytes: Buffer.byteLength(code)
124
+ };
125
+ const previous = this.entries.get(file);
126
+ if (previous !== void 0) {
127
+ this.entries.delete(file);
128
+ this.bytes -= previous.bytes;
129
+ }
130
+ if (entry.bytes > this.limit) return entry;
131
+ this.entries.set(file, entry);
132
+ this.bytes += entry.bytes;
133
+ for (const [key, old] of this.entries) {
134
+ if (this.bytes <= this.limit) break;
135
+ this.entries.delete(key);
136
+ this.bytes -= old.bytes;
137
+ }
138
+ return entry;
139
+ }
140
+ /** The UTF-8 bytes of code held now. */
141
+ get heldBytes() {
142
+ return this.bytes;
143
+ }
144
+ /** The files held now, least recently served first. */
145
+ get files() {
146
+ return [...this.entries.keys()];
147
+ }
148
+ };
149
+ const absolute = (path) => isAbsolute(path) ? path : resolve(path);
150
+ /** A folder's real path; one that does not exist (a production image that ships only the compiled folder) keeps its absolute path. */
151
+ const realFolder = (path) => {
152
+ try {
153
+ return realpathSync(absolute(path));
154
+ } catch {
155
+ return absolute(path);
156
+ }
157
+ };
158
+ /**
159
+ * An app serving a folder of client modules to the browser. Route it where the page's script tags point: `app.route('/client',
160
+ * clientModules({ root: 'src/client' }))` serves `src/client/counter.tsx` at `/client/counter.tsx`. Files are compiled on request and
161
+ * cached until they change (bounded by `cacheBytes`); a response carries an ETag and `Cache-Control: no-cache`, so an edit shows on the
162
+ * next reload. With `NODE_ENV=production` and `compiled` set, only the `compiled` folder is served and nothing is compiled.
163
+ * @param options - the folder, the precompiled folder, and the cache bound.
164
+ * @returns the app.
165
+ */
166
+ function clientModules(options) {
167
+ const root = realFolder(options.root);
168
+ const runtimeDir = absolute(options.runtimeDir ?? defaultRuntimeDir());
169
+ let compiled;
170
+ if (process.env.NODE_ENV === "production" && options.compiled !== void 0) try {
171
+ compiled = realpathSync(absolute(options.compiled));
172
+ } catch {
173
+ throw new Error(`acrylblends: the compiled client folder ${absolute(options.compiled)} does not exist; build it with buildClientModules before starting in production`);
174
+ }
175
+ const cache = new CompileCache(options.cacheBytes ?? DEFAULT_CACHE_BYTES);
176
+ const app = new Acryl();
177
+ app.get("/*", (c) => {
178
+ const requestPath = c.req.path.slice(basePath(c).length);
179
+ const runtime = /^\/@acrylblends\/([a-z-]+\.js)$/u.exec(requestPath)?.[1];
180
+ const send = (code, etag) => {
181
+ if (c.req.header("if-none-match") === etag) return c.body(null, 304, {
182
+ etag,
183
+ "cache-control": "no-cache"
184
+ });
185
+ return c.body(code, 200, {
186
+ "content-type": JS_TYPE,
187
+ etag,
188
+ "cache-control": "no-cache"
189
+ });
190
+ };
191
+ const serveFile = (file) => {
192
+ const stat = statSync(file);
193
+ return send(readFileSync(file, "utf8"), etagOf(stat));
194
+ };
195
+ if (runtime !== void 0) {
196
+ if (!RUNTIME_FILES.includes(runtime)) return c.notFound();
197
+ return serveFile(compiled === void 0 ? join(runtimeDir, runtime) : join(compiled, RUNTIME_DIR, runtime));
198
+ }
199
+ const path = servedPath(requestPath);
200
+ if (path === void 0 || path.split("/")[0] === RUNTIME_DIR) return c.notFound();
201
+ if (compiled !== void 0) {
202
+ const file = fileInside(compiled, path);
203
+ if (file !== void 0) return serveFile(file);
204
+ if (fileInside(root, path) !== void 0) return c.text(`acrylblends: ${path} is not in ${relative(process.cwd(), compiled) || compiled}; build the client modules again (buildClientModules)`, 500);
205
+ return c.notFound();
206
+ }
207
+ const file = fileInside(root, path);
208
+ if (file === void 0) return c.notFound();
209
+ if (!COMPILED.has(extname(file))) return serveFile(file);
210
+ const stat = statSync(file);
211
+ let entry = cache.get(file, stat.mtimeMs, stat.size);
212
+ if (entry === void 0) {
213
+ let code;
214
+ try {
215
+ code = compileForBrowser(file, path);
216
+ } catch (error) {
217
+ if (error instanceof MissingTypeScriptError) return c.text(error.message, 500);
218
+ throw error;
219
+ }
220
+ entry = cache.set(file, stat, code);
221
+ }
222
+ return send(entry.code, entry.etag);
223
+ });
224
+ return app;
225
+ }
226
+ /** Every served file below `dir`, as paths below `root` with `/` separators; dot entries, `node_modules` and the runtime folder skipped. */
227
+ function sourceFiles(root, dir = root) {
228
+ const files = [];
229
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
230
+ if (entry.name.startsWith(".") || entry.name === "node_modules" || dir === root && entry.name === RUNTIME_DIR) continue;
231
+ const full = join(dir, entry.name);
232
+ if (entry.isDirectory()) files.push(...sourceFiles(root, full));
233
+ else if (entry.isFile() && SERVED.has(extname(entry.name)) && !entry.name.endsWith(".d.ts")) files.push(relative(root, full).split(sep).join("/"));
234
+ }
235
+ return files.sort();
236
+ }
237
+ /**
238
+ * Compile a folder of client modules once, for a production that has no `typescript`: each module is written to `outDir` at the same
239
+ * relative path and file name (so the page's URLs stay the same), compiled exactly as {@link clientModules} compiles it, and the three
240
+ * browser files are copied to `outDir/@acrylblends/`. Files already in `outDir` that no source produces are left there.
241
+ * @param options - the source folder and the output folder.
242
+ * @returns the paths written, relative to `outDir`.
243
+ * @throws MissingTypeScriptError when the app has no `typescript`; an error when `outDir` lies inside `root`.
244
+ */
245
+ function buildClientModules(options) {
246
+ const root = realpathSync(absolute(options.root));
247
+ const outDir = absolute(options.outDir);
248
+ const runtimeDir = absolute(options.runtimeDir ?? defaultRuntimeDir());
249
+ if (outDir === root || outDir.startsWith(root + sep)) throw new Error(`acrylblends: the output folder ${outDir} lies inside the client folder ${root}`);
250
+ const written = [];
251
+ for (const path of sourceFiles(root)) {
252
+ const source = join(root, ...path.split("/"));
253
+ const target = join(outDir, ...path.split("/"));
254
+ mkdirSync(dirname(target), { recursive: true });
255
+ if (COMPILED.has(extname(path))) writeFileSync(target, compileForBrowser(source, path));
256
+ else copyFileSync(source, target);
257
+ written.push(path);
258
+ }
259
+ mkdirSync(join(outDir, RUNTIME_DIR), { recursive: true });
260
+ for (const name of RUNTIME_FILES) {
261
+ copyFileSync(join(runtimeDir, name), join(outDir, RUNTIME_DIR, name));
262
+ written.push(`${RUNTIME_DIR}/${name}`);
263
+ }
264
+ return written;
265
+ }
266
+ //#endregion
267
+ export { clientModules as n, buildClientModules as t };
@@ -0,0 +1,25 @@
1
+ import { t as Context } from "./context-DS3fYyG-.js";
2
+ import { r as GetConnInfo } from "./types-Dv_nV2cv.js";
3
+
4
+ //#region ../../plugins/acryl-router/src/connection.d.ts
5
+ /** An in-process caller (the terminal UI, a test) passes nothing, so a handler that needs a trusted peer must refuse an empty one. */
6
+ interface ConnectionInfo {
7
+ /** The peer address of the socket, when the request came over one (for example `127.0.0.1`). */
8
+ readonly remoteAddress?: string | undefined;
9
+ /** The local port the socket is connected to, the real one a `Host` header should be checked against. */
10
+ readonly localPort?: number | undefined;
11
+ }
12
+ /** What the router puts in `c.env`. */
13
+ interface RouterBindings {
14
+ readonly connection: ConnectionInfo;
15
+ }
16
+ /** The `Env` of an `Acryl` that wants `c.env.connection` typed: `new Acryl<RouterEnv>()`. */
17
+ interface RouterEnv {
18
+ Bindings: RouterBindings;
19
+ }
20
+ /** The transport facts of this request; empty for an in-process call or an `Acryl` run outside the router. */
21
+ declare function connectionOf(c: Context): ConnectionInfo;
22
+ /** The peer in the core's conninfo shape, for middleware written against it (for example `ipRestriction`). */
23
+ declare const getConnInfo: GetConnInfo;
24
+ //#endregion
25
+ export { getConnInfo as a, connectionOf as i, RouterBindings as n, RouterEnv as r, ConnectionInfo as t };
package/lib/conninfo.d.ts CHANGED
@@ -1,25 +1,3 @@
1
- import { t as Context } from "./context-DS3fYyG-.js";
2
1
  import { i as NetAddrInfo, n as ConnInfo, r as GetConnInfo, t as AddressType } from "./types-Dv_nV2cv.js";
3
-
4
- //#region ../../plugins/acryl-router/src/connection.d.ts
5
- /** An in-process caller (the terminal UI, a test) passes nothing, so a handler that needs a trusted peer must refuse an empty one. */
6
- interface ConnectionInfo {
7
- /** The peer address of the socket, when the request came over one (for example `127.0.0.1`). */
8
- readonly remoteAddress?: string | undefined;
9
- /** The local port the socket is connected to, the real one a `Host` header should be checked against. */
10
- readonly localPort?: number | undefined;
11
- }
12
- /** What the router puts in `c.env`. */
13
- interface RouterBindings {
14
- readonly connection: ConnectionInfo;
15
- }
16
- /** The `Env` of an `Acryl` that wants `c.env.connection` typed: `new Acryl<RouterEnv>()`. */
17
- interface RouterEnv {
18
- Bindings: RouterBindings;
19
- }
20
- /** The transport facts of this request; empty for an in-process call or an `Acryl` run outside the router. */
21
- declare function connectionOf(c: Context): ConnectionInfo;
22
- /** The peer in the core's conninfo shape, for middleware written against it (for example `ipRestriction`). */
23
- declare const getConnInfo: GetConnInfo;
24
- //#endregion
2
+ import { a as getConnInfo, i as connectionOf, n as RouterBindings, r as RouterEnv, t as ConnectionInfo } from "./connection-ZLEso7XL.js";
25
3
  export { type AddressType, type ConnInfo, type ConnectionInfo, type GetConnInfo, type NetAddrInfo, type RouterBindings, type RouterEnv, connectionOf, getConnInfo };
@@ -0,0 +1,56 @@
1
+ import { n as DbExecutor, r as SqlValue, t as Db } from "../database-DBHdwefi.js";
2
+ import { OpenDb, OpenDbOptions, openDb } from "../db/sqlite.js";
3
+ import { DatabaseSync, StatementSync } from "node:sqlite";
4
+ import { Context } from "@deepseek-ai/cordis";
5
+ import z from "@deepseek-ai/schemastery";
6
+
7
+ //#region ../../plugins/acryl-db-sqlite/src/facade/node.d.ts
8
+ /** Node SQLite connection settings for a database file. */
9
+ type NodeSqliteDatabaseOptions = {
10
+ /** SQLite WAL auto-checkpoint threshold. SQLite and this adapter default to 1,000 pages; 0 disables it. */readonly walAutoCheckpointPages?: number; /** Time SQLite waits for a competing file lock. SQLite defaults to 0; this adapter defaults to 5,000 ms. */
11
+ readonly busyTimeoutMs?: number;
12
+ };
13
+ /**
14
+ * Executes SQL on one connection. Prepared statements are cached per connection by SQL text, so the
15
+ * database and its transaction handles share them across transactions.
16
+ */
17
+ declare abstract class NodeSqliteExecutor implements DbExecutor {
18
+ protected readonly database: DatabaseSync;
19
+ protected readonly statements: Map<string, StatementSync>;
20
+ constructor(database: DatabaseSync, statements: Map<string, StatementSync>);
21
+ exec(sql: string): Promise<void>;
22
+ run(sql: string, ...params: SqlValue[]): Promise<{
23
+ readonly changes: number;
24
+ }>;
25
+ get<T extends object>(sql: string, ...params: SqlValue[]): Promise<T | undefined>;
26
+ all<T extends object>(sql: string, ...params: SqlValue[]): Promise<T[]>;
27
+ protected abstract runOperation<T>(operation: () => T): Promise<T>;
28
+ private statement;
29
+ }
30
+ /** `Db` adapter backed by Node's built-in `node:sqlite`. */
31
+ declare class NodeSqliteDatabase extends NodeSqliteExecutor implements Db {
32
+ private readonly access;
33
+ private closed;
34
+ constructor(database: DatabaseSync);
35
+ transaction<T>(callback: (transaction: DbExecutor) => Promise<T>): Promise<T>;
36
+ close(): Promise<void>;
37
+ protected runOperation<T>(operation: () => T): Promise<T>;
38
+ }
39
+ /** Open and configure a Node-backed SQLite database facade. */
40
+ declare function openNodeSqliteDatabase(path: string, options?: NodeSqliteDatabaseOptions): Promise<NodeSqliteDatabase>;
41
+ //#endregion
42
+ //#region ../../plugins/acryl-db-sqlite/src/index.d.ts
43
+ /** Stable Cordis plugin name, equal to the package name and the Loader row id. */
44
+ declare const name = "acryl-db-sqlite";
45
+ interface Config {
46
+ path?: string;
47
+ migrations?: string;
48
+ busyTimeoutMs?: number;
49
+ walAutoCheckpointPages?: number;
50
+ }
51
+ declare const Config: z<Config>;
52
+ /** The file name used in the app home when `path` is not configured. */
53
+ declare const DEFAULT_FILE = "data.sqlite";
54
+ declare function apply(ctx: Context, rawConfig?: Config): Promise<void>;
55
+ //#endregion
56
+ export { Config, DEFAULT_FILE, NodeSqliteDatabase, type NodeSqliteDatabaseOptions, type OpenDb, type OpenDbOptions, apply, name, openDb, openNodeSqliteDatabase };
@@ -0,0 +1,58 @@
1
+ import "../src-MWcsMS8i.js";
2
+ import { n as NodeSqliteDatabase, r as openNodeSqliteDatabase, t as openDb } from "../open-CMhnJODn.js";
3
+ import { dirname, isAbsolute, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import z from "@deepseek-ai/schemastery";
6
+ //#region ../../plugins/acryl-db-sqlite/src/index.ts
7
+ /**
8
+ * The SQLite provider of the `db` port (spec 049 slice 1): one `node:sqlite` file, opened with the ported facade's settings (WAL,
9
+ * `synchronous = NORMAL`, a busy timeout), migrated, and provided as `db`. App plugins declare `inject: ['db']` and import types from
10
+ * `acryl-db` only, so replacing this row with another provider does not touch them. The plugin is a thin wrapper over `openDb`
11
+ * (`acryl-db-sqlite/open`), the same opening for code without Cordis.
12
+ *
13
+ * Unloading withdraws `db` first, so consumers stop calling, and then closes the file: the close waits for running operations and
14
+ * transactions, checkpoints the WAL and releases the file.
15
+ */
16
+ /** Stable Cordis plugin name, equal to the package name and the Loader row id. */
17
+ const name = "acryl-db-sqlite";
18
+ function isAppHome(value) {
19
+ return typeof value === "object" && value !== null && "home" in value && typeof value.home === "string";
20
+ }
21
+ const Config = z.object({
22
+ path: z.string().description("The database file, absolute or relative to the app. Defaults to data.sqlite in the ACRYL app home; required where there is none."),
23
+ migrations: z.string().description("A folder of NNN-name.sql files numbered from 1, absolute or relative to the app, applied in order on start."),
24
+ busyTimeoutMs: z.natural().description("How long SQLite waits for a competing file lock, in milliseconds. Defaults to 5000."),
25
+ walAutoCheckpointPages: z.natural().description("The WAL auto-checkpoint threshold in pages; 0 disables it. Defaults to 1000.")
26
+ });
27
+ /** The file name used in the app home when `path` is not configured. */
28
+ const DEFAULT_FILE = "data.sqlite";
29
+ /** A configured path as a file path: absolute as given, relative to the Loader's base URL (the app) otherwise. */
30
+ function resolveFromApp(ctx, path, option) {
31
+ if (path.startsWith("file:")) return fileURLToPath(path);
32
+ if (isAbsolute(path)) return path;
33
+ const base = ctx.baseUrl;
34
+ if (base === void 0 || !base.startsWith("file:")) throw new Error(`acryl-db-sqlite: ${option} ${JSON.stringify(path)} is relative, but this app has no file base URL to resolve it from; give an absolute path`);
35
+ return resolve(base.endsWith("/") ? fileURLToPath(base) : dirname(fileURLToPath(base)), path);
36
+ }
37
+ async function apply(ctx, rawConfig = {}) {
38
+ const config = Config(rawConfig);
39
+ const appInstance = ctx.get("appInstance");
40
+ let file;
41
+ if (config.path !== void 0) file = resolveFromApp(ctx, config.path, "path");
42
+ else if (isAppHome(appInstance)) file = join(appInstance.home, DEFAULT_FILE);
43
+ else throw new Error("acryl-db-sqlite: no database path; set `path` in this row's config (there is no ACRYL app home to default to)");
44
+ const migrations = config.migrations === void 0 ? void 0 : resolveFromApp(ctx, config.migrations, "migrations");
45
+ const options = {
46
+ path: file,
47
+ ...migrations === void 0 ? {} : { migrations },
48
+ ...config.busyTimeoutMs === void 0 ? {} : { busyTimeoutMs: config.busyTimeoutMs },
49
+ ...config.walAutoCheckpointPages === void 0 ? {} : { walAutoCheckpointPages: config.walAutoCheckpointPages }
50
+ };
51
+ await ctx.effect(async function* () {
52
+ const opened = await openDb(options);
53
+ yield () => opened.close();
54
+ yield ctx.reflect.provide("db", opened.db);
55
+ }, `acryl-db-sqlite: ${file}`);
56
+ }
57
+ //#endregion
58
+ export { Config, DEFAULT_FILE, NodeSqliteDatabase, apply, name, openDb, openNodeSqliteDatabase };
@@ -0,0 +1,8 @@
1
+ import { t as Db } from "../database-DBHdwefi.js";
2
+
3
+ //#region ../../plugins/acryl-db/src/cordis.d.ts
4
+ declare module '@deepseek-ai/cordis' {
5
+ interface Context {
6
+ db: Db;
7
+ }
8
+ }
@@ -0,0 +1 @@
1
+ export {};