@ketvietlab/ketjs 0.1.1

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 (283) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/dist/agent/capabilities.d.ts +62 -0
  4. package/dist/agent/capabilities.d.ts.map +1 -0
  5. package/dist/agent/capabilities.js +89 -0
  6. package/dist/agent/capabilities.js.map +1 -0
  7. package/dist/agent/permissions.d.ts +56 -0
  8. package/dist/agent/permissions.d.ts.map +1 -0
  9. package/dist/agent/permissions.js +209 -0
  10. package/dist/agent/permissions.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +698 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/codegen/dts.d.ts +3 -0
  16. package/dist/codegen/dts.d.ts.map +1 -0
  17. package/dist/codegen/dts.js +94 -0
  18. package/dist/codegen/dts.js.map +1 -0
  19. package/dist/data/adapter.d.ts +4 -0
  20. package/dist/data/adapter.d.ts.map +1 -0
  21. package/dist/data/adapter.js +18 -0
  22. package/dist/data/adapter.js.map +1 -0
  23. package/dist/data/changeset.d.ts +49 -0
  24. package/dist/data/changeset.d.ts.map +1 -0
  25. package/dist/data/changeset.js +206 -0
  26. package/dist/data/changeset.js.map +1 -0
  27. package/dist/data/expr.d.ts +59 -0
  28. package/dist/data/expr.d.ts.map +1 -0
  29. package/dist/data/expr.js +61 -0
  30. package/dist/data/expr.js.map +1 -0
  31. package/dist/data/fleet.d.ts +28 -0
  32. package/dist/data/fleet.d.ts.map +1 -0
  33. package/dist/data/fleet.js +82 -0
  34. package/dist/data/fleet.js.map +1 -0
  35. package/dist/data/list-search.d.ts +93 -0
  36. package/dist/data/list-search.d.ts.map +1 -0
  37. package/dist/data/list-search.js +268 -0
  38. package/dist/data/list-search.js.map +1 -0
  39. package/dist/data/migrate.d.ts +75 -0
  40. package/dist/data/migrate.d.ts.map +1 -0
  41. package/dist/data/migrate.js +136 -0
  42. package/dist/data/migrate.js.map +1 -0
  43. package/dist/data/pool.d.ts +20 -0
  44. package/dist/data/pool.d.ts.map +1 -0
  45. package/dist/data/pool.js +92 -0
  46. package/dist/data/pool.js.map +1 -0
  47. package/dist/data/query.d.ts +111 -0
  48. package/dist/data/query.d.ts.map +1 -0
  49. package/dist/data/query.js +268 -0
  50. package/dist/data/query.js.map +1 -0
  51. package/dist/data/sqlite.d.ts +3 -0
  52. package/dist/data/sqlite.d.ts.map +1 -0
  53. package/dist/data/sqlite.js +107 -0
  54. package/dist/data/sqlite.js.map +1 -0
  55. package/dist/data/time.d.ts +9 -0
  56. package/dist/data/time.d.ts.map +1 -0
  57. package/dist/data/time.js +107 -0
  58. package/dist/data/time.js.map +1 -0
  59. package/dist/index.d.ts +79 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +51 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/kernel/apps.d.ts +43 -0
  64. package/dist/kernel/apps.d.ts.map +1 -0
  65. package/dist/kernel/apps.js +234 -0
  66. package/dist/kernel/apps.js.map +1 -0
  67. package/dist/kernel/compose.d.ts +6 -0
  68. package/dist/kernel/compose.d.ts.map +1 -0
  69. package/dist/kernel/compose.js +976 -0
  70. package/dist/kernel/compose.js.map +1 -0
  71. package/dist/kernel/define.d.ts +9 -0
  72. package/dist/kernel/define.d.ts.map +1 -0
  73. package/dist/kernel/define.js +140 -0
  74. package/dist/kernel/define.js.map +1 -0
  75. package/dist/kernel/diff.d.ts +11 -0
  76. package/dist/kernel/diff.d.ts.map +1 -0
  77. package/dist/kernel/diff.js +106 -0
  78. package/dist/kernel/diff.js.map +1 -0
  79. package/dist/kernel/errors.d.ts +17 -0
  80. package/dist/kernel/errors.d.ts.map +1 -0
  81. package/dist/kernel/errors.js +43 -0
  82. package/dist/kernel/errors.js.map +1 -0
  83. package/dist/kernel/graph.d.ts +3 -0
  84. package/dist/kernel/graph.d.ts.map +1 -0
  85. package/dist/kernel/graph.js +56 -0
  86. package/dist/kernel/graph.js.map +1 -0
  87. package/dist/kernel/i18n.d.ts +43 -0
  88. package/dist/kernel/i18n.d.ts.map +1 -0
  89. package/dist/kernel/i18n.js +79 -0
  90. package/dist/kernel/i18n.js.map +1 -0
  91. package/dist/kernel/index.d.ts +7 -0
  92. package/dist/kernel/index.d.ts.map +1 -0
  93. package/dist/kernel/index.js +7 -0
  94. package/dist/kernel/index.js.map +1 -0
  95. package/dist/kernel/layout.d.ts +17 -0
  96. package/dist/kernel/layout.d.ts.map +1 -0
  97. package/dist/kernel/layout.js +77 -0
  98. package/dist/kernel/layout.js.map +1 -0
  99. package/dist/kernel/menu.d.ts +27 -0
  100. package/dist/kernel/menu.d.ts.map +1 -0
  101. package/dist/kernel/menu.js +65 -0
  102. package/dist/kernel/menu.js.map +1 -0
  103. package/dist/kernel/modules.d.ts +31 -0
  104. package/dist/kernel/modules.d.ts.map +1 -0
  105. package/dist/kernel/modules.js +322 -0
  106. package/dist/kernel/modules.js.map +1 -0
  107. package/dist/kernel/routes.d.ts +24 -0
  108. package/dist/kernel/routes.d.ts.map +1 -0
  109. package/dist/kernel/routes.js +98 -0
  110. package/dist/kernel/routes.js.map +1 -0
  111. package/dist/kernel/types.d.ts +8 -0
  112. package/dist/kernel/types.d.ts.map +1 -0
  113. package/dist/kernel/types.js +67 -0
  114. package/dist/kernel/types.js.map +1 -0
  115. package/dist/kernel/workspace.d.ts +62 -0
  116. package/dist/kernel/workspace.d.ts.map +1 -0
  117. package/dist/kernel/workspace.js +156 -0
  118. package/dist/kernel/workspace.js.map +1 -0
  119. package/dist/scaffold/index.d.ts +2 -0
  120. package/dist/scaffold/index.d.ts.map +1 -0
  121. package/dist/scaffold/index.js +49 -0
  122. package/dist/scaffold/index.js.map +1 -0
  123. package/dist/scaffold/templates/app.test.ts.tmpl +17 -0
  124. package/dist/scaffold/templates/biome.json.tmpl +30 -0
  125. package/dist/scaffold/templates/dev.mjs.tmpl +16 -0
  126. package/dist/scaffold/templates/gitignore.tmpl +24 -0
  127. package/dist/scaffold/templates/ket.workspace.ts.tmpl +18 -0
  128. package/dist/scaffold/templates/module.ts.tmpl +27 -0
  129. package/dist/scaffold/templates/package.json.tmpl +25 -0
  130. package/dist/scaffold/templates/tsconfig.json.tmpl +15 -0
  131. package/dist/server/boot.d.ts +173 -0
  132. package/dist/server/boot.d.ts.map +1 -0
  133. package/dist/server/boot.js +659 -0
  134. package/dist/server/boot.js.map +1 -0
  135. package/dist/server/config.d.ts +48 -0
  136. package/dist/server/config.d.ts.map +1 -0
  137. package/dist/server/config.js +82 -0
  138. package/dist/server/config.js.map +1 -0
  139. package/dist/server/ctx.d.ts +13 -0
  140. package/dist/server/ctx.d.ts.map +1 -0
  141. package/dist/server/ctx.js +496 -0
  142. package/dist/server/ctx.js.map +1 -0
  143. package/dist/server/fn.d.ts +34 -0
  144. package/dist/server/fn.d.ts.map +1 -0
  145. package/dist/server/fn.js +170 -0
  146. package/dist/server/fn.js.map +1 -0
  147. package/dist/server/http.d.ts +79 -0
  148. package/dist/server/http.d.ts.map +1 -0
  149. package/dist/server/http.js +459 -0
  150. package/dist/server/http.js.map +1 -0
  151. package/dist/server/idem.d.ts +31 -0
  152. package/dist/server/idem.d.ts.map +1 -0
  153. package/dist/server/idem.js +68 -0
  154. package/dist/server/idem.js.map +1 -0
  155. package/dist/server/jobs.d.ts +5 -0
  156. package/dist/server/jobs.d.ts.map +1 -0
  157. package/dist/server/jobs.js +24 -0
  158. package/dist/server/jobs.js.map +1 -0
  159. package/dist/server/multipart.d.ts +18 -0
  160. package/dist/server/multipart.d.ts.map +1 -0
  161. package/dist/server/multipart.js +183 -0
  162. package/dist/server/multipart.js.map +1 -0
  163. package/dist/server/project.d.ts +9 -0
  164. package/dist/server/project.d.ts.map +1 -0
  165. package/dist/server/project.js +67 -0
  166. package/dist/server/project.js.map +1 -0
  167. package/dist/server/queue.d.ts +80 -0
  168. package/dist/server/queue.d.ts.map +1 -0
  169. package/dist/server/queue.js +494 -0
  170. package/dist/server/queue.js.map +1 -0
  171. package/dist/server/respond.d.ts +91 -0
  172. package/dist/server/respond.d.ts.map +1 -0
  173. package/dist/server/respond.js +99 -0
  174. package/dist/server/respond.js.map +1 -0
  175. package/dist/server/runtime.d.ts +14 -0
  176. package/dist/server/runtime.d.ts.map +1 -0
  177. package/dist/server/runtime.js +25 -0
  178. package/dist/server/runtime.js.map +1 -0
  179. package/dist/server/session.d.ts +55 -0
  180. package/dist/server/session.d.ts.map +1 -0
  181. package/dist/server/session.js +172 -0
  182. package/dist/server/session.js.map +1 -0
  183. package/dist/server/sessionstore.d.ts +54 -0
  184. package/dist/server/sessionstore.d.ts.map +1 -0
  185. package/dist/server/sessionstore.js +232 -0
  186. package/dist/server/sessionstore.js.map +1 -0
  187. package/dist/server/storage/index.d.ts +11 -0
  188. package/dist/server/storage/index.d.ts.map +1 -0
  189. package/dist/server/storage/index.js +31 -0
  190. package/dist/server/storage/index.js.map +1 -0
  191. package/dist/server/storage/local.d.ts +5 -0
  192. package/dist/server/storage/local.d.ts.map +1 -0
  193. package/dist/server/storage/local.js +165 -0
  194. package/dist/server/storage/local.js.map +1 -0
  195. package/dist/server/storage/s3.d.ts +11 -0
  196. package/dist/server/storage/s3.d.ts.map +1 -0
  197. package/dist/server/storage/s3.js +133 -0
  198. package/dist/server/storage/s3.js.map +1 -0
  199. package/dist/server/storage/sigv4.d.ts +23 -0
  200. package/dist/server/storage/sigv4.d.ts.map +1 -0
  201. package/dist/server/storage/sigv4.js +79 -0
  202. package/dist/server/storage/sigv4.js.map +1 -0
  203. package/dist/server/storage/types.d.ts +37 -0
  204. package/dist/server/storage/types.d.ts.map +1 -0
  205. package/dist/server/storage/types.js +82 -0
  206. package/dist/server/storage/types.js.map +1 -0
  207. package/dist/server/stream.d.ts +43 -0
  208. package/dist/server/stream.d.ts.map +1 -0
  209. package/dist/server/stream.js +117 -0
  210. package/dist/server/stream.js.map +1 -0
  211. package/dist/server/streamstore.d.ts +29 -0
  212. package/dist/server/streamstore.d.ts.map +1 -0
  213. package/dist/server/streamstore.js +140 -0
  214. package/dist/server/streamstore.js.map +1 -0
  215. package/dist/server/tenants.d.ts +108 -0
  216. package/dist/server/tenants.d.ts.map +1 -0
  217. package/dist/server/tenants.js +172 -0
  218. package/dist/server/tenants.js.map +1 -0
  219. package/dist/server/transport/index.d.ts +5 -0
  220. package/dist/server/transport/index.d.ts.map +1 -0
  221. package/dist/server/transport/index.js +3 -0
  222. package/dist/server/transport/index.js.map +1 -0
  223. package/dist/server/transport/memory.d.ts +14 -0
  224. package/dist/server/transport/memory.d.ts.map +1 -0
  225. package/dist/server/transport/memory.js +36 -0
  226. package/dist/server/transport/memory.js.map +1 -0
  227. package/dist/server/transport/types.d.ts +44 -0
  228. package/dist/server/transport/types.d.ts.map +1 -0
  229. package/dist/server/transport/types.js +79 -0
  230. package/dist/server/transport/types.js.map +1 -0
  231. package/dist/server/worker.d.ts +33 -0
  232. package/dist/server/worker.d.ts.map +1 -0
  233. package/dist/server/worker.js +428 -0
  234. package/dist/server/worker.js.map +1 -0
  235. package/dist/testing.d.ts +146 -0
  236. package/dist/testing.d.ts.map +1 -0
  237. package/dist/testing.js +406 -0
  238. package/dist/testing.js.map +1 -0
  239. package/dist/theme/contracts.d.ts +4 -0
  240. package/dist/theme/contracts.d.ts.map +1 -0
  241. package/dist/theme/contracts.js +87 -0
  242. package/dist/theme/contracts.js.map +1 -0
  243. package/dist/theme/index.d.ts +8 -0
  244. package/dist/theme/index.d.ts.map +1 -0
  245. package/dist/theme/index.js +7 -0
  246. package/dist/theme/index.js.map +1 -0
  247. package/dist/theme/joints.d.ts +19 -0
  248. package/dist/theme/joints.d.ts.map +1 -0
  249. package/dist/theme/joints.js +126 -0
  250. package/dist/theme/joints.js.map +1 -0
  251. package/dist/theme/ktl/compile.d.ts +26 -0
  252. package/dist/theme/ktl/compile.d.ts.map +1 -0
  253. package/dist/theme/ktl/compile.js +226 -0
  254. package/dist/theme/ktl/compile.js.map +1 -0
  255. package/dist/theme/ktl/lexer.d.ts +20 -0
  256. package/dist/theme/ktl/lexer.d.ts.map +1 -0
  257. package/dist/theme/ktl/lexer.js +56 -0
  258. package/dist/theme/ktl/lexer.js.map +1 -0
  259. package/dist/theme/ktl/parser.d.ts +64 -0
  260. package/dist/theme/ktl/parser.d.ts.map +1 -0
  261. package/dist/theme/ktl/parser.js +220 -0
  262. package/dist/theme/ktl/parser.js.map +1 -0
  263. package/dist/theme/render.d.ts +19 -0
  264. package/dist/theme/render.d.ts.map +1 -0
  265. package/dist/theme/render.js +246 -0
  266. package/dist/theme/render.js.map +1 -0
  267. package/dist/theme/templates.d.ts +2 -0
  268. package/dist/theme/templates.d.ts.map +1 -0
  269. package/dist/theme/templates.js +40 -0
  270. package/dist/theme/templates.js.map +1 -0
  271. package/dist/theme/tokens.d.ts +4 -0
  272. package/dist/theme/tokens.d.ts.map +1 -0
  273. package/dist/theme/tokens.js +15 -0
  274. package/dist/theme/tokens.js.map +1 -0
  275. package/dist/theme/viewmodel.d.ts +6 -0
  276. package/dist/theme/viewmodel.d.ts.map +1 -0
  277. package/dist/theme/viewmodel.js +40 -0
  278. package/dist/theme/viewmodel.js.map +1 -0
  279. package/dist/types.d.ts +614 -0
  280. package/dist/types.d.ts.map +1 -0
  281. package/dist/types.js +3 -0
  282. package/dist/types.js.map +1 -0
  283. package/package.json +60 -0
@@ -0,0 +1,170 @@
1
+ // The atom. One declaration yields an HTTP endpoint, a typed client method, a
2
+ // manifest entry, an agent tool descriptor and a dry-runnable test handle.
3
+ // Written once, never restated.
4
+ import { createContext } from './ctx.js';
5
+ import { createIdempotency } from './idem.js';
6
+ import { KetError } from '../kernel/errors.js';
7
+ import { project } from './project.js';
8
+ import { isDateText, parseType } from '../kernel/types.js';
9
+ import { queueFor } from './queue.js';
10
+ const registry = new Map();
11
+ export function defineFn(spec) {
12
+ if (typeof spec.handler !== 'function')
13
+ throw new KetError({ code: 'E_FN_NO_HANDLER', message: 'defineFn() requires a handler' });
14
+ return spec;
15
+ }
16
+ export function registerFunctions(modules) {
17
+ registry.clear();
18
+ for (const m of modules)
19
+ for (const [name, def] of Object.entries(m.functions))
20
+ registry.set(`${m.name}.${name}`, def);
21
+ return registry;
22
+ }
23
+ const JS_OF = {
24
+ id: 'string',
25
+ text: 'string',
26
+ ref: 'string',
27
+ int: 'number',
28
+ float: 'number',
29
+ bool: 'boolean',
30
+ date: 'string',
31
+ datetime: 'string',
32
+ json: 'object',
33
+ };
34
+ const DECIMAL = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/;
35
+ export function validateInput(fnKey, manifest, args) {
36
+ const sig = manifest.functions[fnKey]?.input ?? {};
37
+ const errors = [];
38
+ for (const [name, tspec] of Object.entries(sig)) {
39
+ const t = parseType(tspec);
40
+ const v = args?.[name];
41
+ if (v == null) {
42
+ if (t.ok && !t.optional)
43
+ errors.push(`missing required input "${name}" (${tspec})`);
44
+ continue;
45
+ }
46
+ if (!t.ok)
47
+ continue;
48
+ const want = JS_OF[t.base];
49
+ if (want && typeof v !== want)
50
+ errors.push(`input "${name}" expects ${t.base} (${want}), got ${typeof v}`);
51
+ if (t.base === 'decimal' &&
52
+ !((typeof v === 'number' && Number.isFinite(v)) || (typeof v === 'string' && DECIMAL.test(v.trim()))))
53
+ errors.push(`input "${name}" expects a finite number or an exact decimal string`);
54
+ if (t.base === 'int' && typeof v === 'number' && !Number.isInteger(v))
55
+ errors.push(`input "${name}" expects an integer`);
56
+ if (t.base === 'date' && !isDateText(v))
57
+ errors.push(`input "${name}" expects a calendar date (YYYY-MM-DD)`);
58
+ }
59
+ for (const k of Object.keys(args ?? {})) {
60
+ if (!(k in sig))
61
+ errors.push(`unknown input "${k}" (accepted: ${Object.keys(sig).join(', ') || 'none'})`);
62
+ }
63
+ if (errors.length) {
64
+ throw new KetError({
65
+ code: 'E_INVALID_INPUT',
66
+ message: `${fnKey}: ${errors.join('; ')}`,
67
+ hint: `signature: ${JSON.stringify(sig)}`,
68
+ });
69
+ }
70
+ }
71
+ const stores = new WeakMap();
72
+ const idemFor = (adapter) => {
73
+ let p = stores.get(adapter);
74
+ if (!p) {
75
+ p = createIdempotency(adapter);
76
+ stores.set(adapter, p);
77
+ }
78
+ return p;
79
+ };
80
+ export const _resetIdempotency = () => {
81
+ /* records are durable; nothing to clear */
82
+ };
83
+ export async function callFn(fnKey, args, o) {
84
+ const def = registry.get(fnKey);
85
+ const owner = fnKey.split('.')[0];
86
+ if (o.manifest.disabledModules?.includes(owner)) {
87
+ throw new KetError({
88
+ code: 'E_APP_NOT_INSTALLED',
89
+ module: owner,
90
+ message: `"${fnKey}" belongs to "${owner}", which is not installed on this database`,
91
+ hint: `install "${owner}" first — the code ships with this deployment, it is simply switched off here`,
92
+ });
93
+ }
94
+ if (!def)
95
+ throw new KetError({
96
+ code: 'E_UNKNOWN_FUNCTION',
97
+ message: `no server function "${fnKey}"`,
98
+ hint: `known: ${[...registry.keys()].join(', ')}`,
99
+ });
100
+ // Permission is checked before the input is validated, so a caller who may not
101
+ // call this at all learns that and nothing else — not which arguments it takes,
102
+ // and not whether the ones they guessed were right.
103
+ if (o.allow && !o.allow.includes(fnKey)) {
104
+ throw new KetError({
105
+ code: 'E_FN_NOT_PERMITTED',
106
+ module: owner,
107
+ message: `this caller may not call "${fnKey}"`,
108
+ hint: 'grant a role that includes it — `ket permissions --grant` shows what any set of functions reaches',
109
+ });
110
+ }
111
+ validateInput(fnKey, o.manifest, args);
112
+ const meta = o.manifest.functions[fnKey];
113
+ const dryRun = o.dryRun ?? false;
114
+ // Create system queue tables on the root adapter before user code can enter a
115
+ // transaction. Lazy DDL inside a rolled-back transaction would otherwise leave
116
+ // an in-memory "initialized" marker pointing at a table that no longer exists.
117
+ if (Object.keys(o.manifest.jobs).length)
118
+ await queueFor(o.adapter);
119
+ const idemKey = o.idempotencyKey ? `${fnKey}:${o.idempotencyKey}` : null;
120
+ let idem = null;
121
+ if (idemKey) {
122
+ if (!meta.idempotent) {
123
+ throw new KetError({
124
+ code: 'E_NOT_IDEMPOTENT',
125
+ message: `"${fnKey}" is not declared idempotent but was called with an idempotency key`,
126
+ hint: 'declare `idempotent: true` on the function, or drop the key',
127
+ });
128
+ }
129
+ idem = await idemFor(o.adapter);
130
+ // Claim the key before doing any work. Losing the race means another caller is
131
+ // either mid-flight or already finished, and both are answered from the record.
132
+ const claimed = await idem.claim(idemKey, fnKey);
133
+ if (!claimed) {
134
+ const existing = await idem.read(idemKey);
135
+ if (existing?.state === 'done')
136
+ return { ...existing.result, replayed: true };
137
+ throw new KetError({
138
+ code: 'E_IDEMPOTENCY_IN_FLIGHT',
139
+ message: `"${fnKey}" is already running with idempotency key "${o.idempotencyKey}"`,
140
+ hint: 'retry shortly; the first call has not finished yet',
141
+ });
142
+ }
143
+ }
144
+ if (dryRun && !meta.dryRun)
145
+ throw new KetError({ code: 'E_NO_DRY_RUN', message: `"${fnKey}" does not support dry-run` });
146
+ const ctx = createContext({
147
+ adapter: o.adapter,
148
+ manifest: o.manifest,
149
+ fnKey,
150
+ dryRun,
151
+ actor: o.actor ?? null,
152
+ scope: o.scope,
153
+ queueNotify: o.queueNotify,
154
+ });
155
+ let result;
156
+ try {
157
+ const value = project(fnKey, meta.output, await def.handler(ctx, args ?? {}));
158
+ result = { ok: true, value, writes: ctx.writes, dryRun };
159
+ }
160
+ catch (e) {
161
+ // A claim whose call then failed must not wedge the key forever.
162
+ if (idemKey && idem)
163
+ await idem.release(idemKey);
164
+ throw e;
165
+ }
166
+ if (idemKey && idem)
167
+ await idem.complete(idemKey, result);
168
+ return result;
169
+ }
170
+ //# sourceMappingURL=fn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fn.js","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/server/fn.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import type { RouteResult } from './respond.ts';
2
+ import type { IncomingMessage, ServerResponse } from 'node:http';
3
+ import type { StreamStore } from './stream.ts';
4
+ import type { Adapter, Manifest, Scope } from '../types.ts';
5
+ import type { AdapterPool } from '../data/pool.ts';
6
+ import type { ThemeRuntime } from '../theme/render.ts';
7
+ import type { RouteParams } from '../kernel/routes.ts';
8
+ type HttpRoute = (url: URL, req: IncomingMessage, params: RouteParams) => Promise<RouteResult> | RouteResult;
9
+ export type ServeOpts = {
10
+ manifest: Manifest;
11
+ /** A single database. Use `pool` + `resolveDatastore` for one database per tenant. */
12
+ adapter?: Adapter | null;
13
+ /** One database per tenant, resolved per request and leased from a bounded pool. */
14
+ pool?: AdapterPool;
15
+ /**
16
+ * Which database this request belongs to. Resolution happens exactly once, here,
17
+ * because ctx is the only thing that touches data — so a request cannot end up
18
+ * reading the wrong tenant by forgetting to pass something along.
19
+ */
20
+ resolveDatastore?: (url: URL, req: IncomingMessage) => string | null;
21
+ theme?: ThemeRuntime | ((url: URL, req: IncomingMessage) => Promise<ThemeRuntime | null>);
22
+ /** Browser modules for islands available to this request. */
23
+ islandClients?: ThemeRuntime['clients'] | ((url: URL, req: IncomingMessage) => Promise<ThemeRuntime['clients']>);
24
+ port?: number;
25
+ /** Defaults to a table on the app's adapter; swap for memory on a single instance. */
26
+ streamStore?: StreamStore;
27
+ /**
28
+ * Which language this request is in. Resolved in one place, like the datastore,
29
+ * so a handler cannot answer in the wrong one by forgetting to pass it along.
30
+ */
31
+ resolveLocale?: (url: URL, req: IncomingMessage) => string;
32
+ /**
33
+ * Which company and branches this request acts as. Resolved here for the same
34
+ * reason the datastore is: a handler that had to remember to pass it along would
35
+ * eventually forget, and forgetting means answering with another company's rows.
36
+ */
37
+ resolveScope?: (url: URL, req: IncomingMessage) => Scope | Promise<Scope>;
38
+ /** Authenticated user id captured into functions and any jobs they enqueue. */
39
+ resolveActor?: (url: URL, req: IncomingMessage) => string | null | Promise<string | null>;
40
+ /** Functions this request may call. Null means unrestricted — see boot.ts. */
41
+ resolveAllow?: (url: URL, req: IncomingMessage) => Promise<readonly string[] | null>;
42
+ /** Disable PostgreSQL notification while retaining polling correctness. */
43
+ queueNotify?: boolean;
44
+ /** Serve files from disk under a URL prefix. Meant for stylesheets during design. */
45
+ /** Static file mounts. One fixed directory, or a resolver that answers per request. */
46
+ assets?: AssetMount | AssetMount[];
47
+ /** Extra routes, matched before the theme takes the request. */
48
+ routes?: Record<string, HttpRoute>;
49
+ pageScope?: (url: URL, req: IncomingMessage) => Record<string, unknown> | Promise<Record<string, unknown>>;
50
+ /** Theme region returned for progressive GET navigation. */
51
+ pageRegion?: string;
52
+ };
53
+ /**
54
+ * A mount is either a directory, or a function from the rest of the path to an
55
+ * absolute file — which is how a module's assets can stop being served the moment
56
+ * the module is uninstalled, without rebuilding the server.
57
+ */
58
+ export type AssetMount = {
59
+ prefix: string;
60
+ dir?: string;
61
+ resolve?: (rest: string, url: URL, req: IncomingMessage) => Promise<string | null>;
62
+ };
63
+ export declare function createKetServer(o: ServeOpts): Promise<{
64
+ server: import("node:http").Server<typeof IncomingMessage, typeof ServerResponse>;
65
+ streams: {
66
+ store: StreamStore;
67
+ open(id: string): Promise<import("./stream.ts").Writer>;
68
+ since(id: string, fromSeq?: number): Promise<import("./stream.ts").Since>;
69
+ tail(id: string, fromSeq?: number, opt?: {
70
+ pollMs?: number;
71
+ timeoutMs?: number;
72
+ }): AsyncGenerator<import("./stream.ts").Chunk>;
73
+ sweep(olderThanMs?: number): Promise<number>;
74
+ };
75
+ listen(port?: number): Promise<number>;
76
+ close(): Promise<void>;
77
+ }>;
78
+ export {};
79
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../../packages/ketjs/src/server/http.ts"],"names":[],"mappings":"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"}