@ketvietlab/ketjs 0.1.2 → 0.1.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 (307) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +8 -2
  3. package/dist/agent/capabilities.d.ts +1 -3
  4. package/dist/agent/capabilities.d.ts.map +1 -1
  5. package/dist/agent/capabilities.js +10 -1
  6. package/dist/agent/capabilities.js.map +1 -1
  7. package/dist/agent/permissions.d.ts +43 -1
  8. package/dist/agent/permissions.d.ts.map +1 -1
  9. package/dist/agent/permissions.js +50 -2
  10. package/dist/agent/permissions.js.map +1 -1
  11. package/dist/cli.js +246 -97
  12. package/dist/cli.js.map +1 -1
  13. package/dist/codegen/dts.d.ts.map +1 -1
  14. package/dist/codegen/dts.js +1 -0
  15. package/dist/codegen/dts.js.map +1 -1
  16. package/dist/data/changeset.d.ts +12 -0
  17. package/dist/data/changeset.d.ts.map +1 -1
  18. package/dist/data/changeset.js +73 -17
  19. package/dist/data/changeset.js.map +1 -1
  20. package/dist/data/expr.d.ts +25 -1
  21. package/dist/data/expr.d.ts.map +1 -1
  22. package/dist/data/expr.js +47 -6
  23. package/dist/data/expr.js.map +1 -1
  24. package/dist/data/fleet.d.ts +41 -1
  25. package/dist/data/fleet.d.ts.map +1 -1
  26. package/dist/data/fleet.js +100 -11
  27. package/dist/data/fleet.js.map +1 -1
  28. package/dist/data/migrate.d.ts +20 -0
  29. package/dist/data/migrate.d.ts.map +1 -1
  30. package/dist/data/migrate.js +86 -3
  31. package/dist/data/migrate.js.map +1 -1
  32. package/dist/data/physical.d.ts +5 -0
  33. package/dist/data/physical.d.ts.map +1 -0
  34. package/dist/data/physical.js +196 -0
  35. package/dist/data/physical.js.map +1 -0
  36. package/dist/data/pool.d.ts +2 -1
  37. package/dist/data/pool.d.ts.map +1 -1
  38. package/dist/data/pool.js +159 -31
  39. package/dist/data/pool.js.map +1 -1
  40. package/dist/data/query.d.ts +10 -1
  41. package/dist/data/query.d.ts.map +1 -1
  42. package/dist/data/query.js +136 -27
  43. package/dist/data/query.js.map +1 -1
  44. package/dist/data/sqlite.d.ts.map +1 -1
  45. package/dist/data/sqlite.js +350 -52
  46. package/dist/data/sqlite.js.map +1 -1
  47. package/dist/data/time.d.ts +13 -0
  48. package/dist/data/time.d.ts.map +1 -1
  49. package/dist/data/time.js +61 -17
  50. package/dist/data/time.js.map +1 -1
  51. package/dist/index.d.ts +45 -24
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +34 -18
  54. package/dist/index.js.map +1 -1
  55. package/dist/kernel/audit.d.ts +27 -0
  56. package/dist/kernel/audit.d.ts.map +1 -0
  57. package/dist/kernel/audit.js +67 -0
  58. package/dist/kernel/audit.js.map +1 -0
  59. package/dist/kernel/classification.d.ts +26 -0
  60. package/dist/kernel/classification.d.ts.map +1 -0
  61. package/dist/kernel/classification.js +73 -0
  62. package/dist/kernel/classification.js.map +1 -0
  63. package/dist/kernel/compose.d.ts +6 -2
  64. package/dist/kernel/compose.d.ts.map +1 -1
  65. package/dist/kernel/compose.js +269 -15
  66. package/dist/kernel/compose.js.map +1 -1
  67. package/dist/kernel/define.d.ts +2 -3
  68. package/dist/kernel/define.d.ts.map +1 -1
  69. package/dist/kernel/define.js +22 -12
  70. package/dist/kernel/define.js.map +1 -1
  71. package/dist/kernel/diff.d.ts.map +1 -1
  72. package/dist/kernel/diff.js +28 -4
  73. package/dist/kernel/diff.js.map +1 -1
  74. package/dist/kernel/graph.js +1 -1
  75. package/dist/kernel/graph.js.map +1 -1
  76. package/dist/kernel/i18n.d.ts +10 -1
  77. package/dist/kernel/i18n.d.ts.map +1 -1
  78. package/dist/kernel/i18n.js +34 -1
  79. package/dist/kernel/i18n.js.map +1 -1
  80. package/dist/kernel/layout.d.ts +97 -0
  81. package/dist/kernel/layout.d.ts.map +1 -1
  82. package/dist/kernel/layout.js +294 -12
  83. package/dist/kernel/layout.js.map +1 -1
  84. package/dist/kernel/menu.d.ts +33 -2
  85. package/dist/kernel/menu.d.ts.map +1 -1
  86. package/dist/kernel/menu.js +99 -7
  87. package/dist/kernel/menu.js.map +1 -1
  88. package/dist/kernel/modules.d.ts +3 -3
  89. package/dist/kernel/modules.d.ts.map +1 -1
  90. package/dist/kernel/modules.js +21 -21
  91. package/dist/kernel/modules.js.map +1 -1
  92. package/dist/kernel/permissions.d.ts +10 -0
  93. package/dist/kernel/permissions.d.ts.map +1 -0
  94. package/dist/kernel/permissions.js +365 -0
  95. package/dist/kernel/permissions.js.map +1 -0
  96. package/dist/kernel/schedule.d.ts +23 -0
  97. package/dist/kernel/schedule.d.ts.map +1 -0
  98. package/dist/kernel/schedule.js +83 -0
  99. package/dist/kernel/schedule.js.map +1 -0
  100. package/dist/kernel/types.d.ts.map +1 -1
  101. package/dist/kernel/types.js +5 -4
  102. package/dist/kernel/types.js.map +1 -1
  103. package/dist/kernel/workspace.d.ts +92 -14
  104. package/dist/kernel/workspace.d.ts.map +1 -1
  105. package/dist/kernel/workspace.js +128 -49
  106. package/dist/kernel/workspace.js.map +1 -1
  107. package/dist/pdf/assets/Inter-Bold.ttf +0 -0
  108. package/dist/pdf/assets/Inter-Regular.ttf +0 -0
  109. package/dist/pdf/assets/Inter-SemiBold.ttf +0 -0
  110. package/dist/pdf/assets/LICENSE.txt +92 -0
  111. package/dist/pdf/font.d.ts +10 -0
  112. package/dist/pdf/font.d.ts.map +1 -0
  113. package/dist/pdf/font.js +83 -0
  114. package/dist/pdf/font.js.map +1 -0
  115. package/dist/pdf/image.d.ts +8 -0
  116. package/dist/pdf/image.d.ts.map +1 -0
  117. package/dist/pdf/image.js +94 -0
  118. package/dist/pdf/image.js.map +1 -0
  119. package/dist/pdf/index.d.ts +15 -0
  120. package/dist/pdf/index.d.ts.map +1 -0
  121. package/dist/pdf/index.js +17 -0
  122. package/dist/pdf/index.js.map +1 -0
  123. package/dist/pdf/markup.d.ts +19 -0
  124. package/dist/pdf/markup.d.ts.map +1 -0
  125. package/dist/pdf/markup.js +146 -0
  126. package/dist/pdf/markup.js.map +1 -0
  127. package/dist/pdf/render.d.ts +14 -0
  128. package/dist/pdf/render.d.ts.map +1 -0
  129. package/dist/pdf/render.js +387 -0
  130. package/dist/pdf/render.js.map +1 -0
  131. package/dist/scaffold/index.js +6 -6
  132. package/dist/scaffold/index.js.map +1 -1
  133. package/dist/scaffold/templates/{app.test.ts.tmpl → deployment.test.ts.tmpl} +3 -3
  134. package/dist/scaffold/templates/ket.workspace.ts.tmpl +4 -6
  135. package/dist/scaffold/templates/module.ts.tmpl +1 -4
  136. package/dist/server/assets.d.ts +23 -0
  137. package/dist/server/assets.d.ts.map +1 -0
  138. package/dist/server/assets.js +97 -0
  139. package/dist/server/assets.js.map +1 -0
  140. package/dist/server/boot.d.ts +174 -38
  141. package/dist/server/boot.d.ts.map +1 -1
  142. package/dist/server/boot.js +399 -140
  143. package/dist/server/boot.js.map +1 -1
  144. package/dist/server/config.d.ts +30 -10
  145. package/dist/server/config.d.ts.map +1 -1
  146. package/dist/server/config.js +73 -17
  147. package/dist/server/config.js.map +1 -1
  148. package/dist/server/ctx.d.ts +10 -0
  149. package/dist/server/ctx.d.ts.map +1 -1
  150. package/dist/server/ctx.js +284 -48
  151. package/dist/server/ctx.js.map +1 -1
  152. package/dist/server/development.d.ts +10 -0
  153. package/dist/server/development.d.ts.map +1 -0
  154. package/dist/server/development.js +15 -0
  155. package/dist/server/development.js.map +1 -0
  156. package/dist/server/fn.d.ts +22 -3
  157. package/dist/server/fn.d.ts.map +1 -1
  158. package/dist/server/fn.js +116 -32
  159. package/dist/server/fn.js.map +1 -1
  160. package/dist/server/form.d.ts +33 -0
  161. package/dist/server/form.d.ts.map +1 -0
  162. package/dist/server/form.js +47 -0
  163. package/dist/server/form.js.map +1 -0
  164. package/dist/server/http.d.ts +82 -3
  165. package/dist/server/http.d.ts.map +1 -1
  166. package/dist/server/http.js +373 -37
  167. package/dist/server/http.js.map +1 -1
  168. package/dist/server/idem.d.ts +3 -2
  169. package/dist/server/idem.d.ts.map +1 -1
  170. package/dist/server/idem.js +12 -4
  171. package/dist/server/idem.js.map +1 -1
  172. package/dist/server/jobs.js +1 -1
  173. package/dist/server/jobs.js.map +1 -1
  174. package/dist/server/log/combinators.d.ts +42 -0
  175. package/dist/server/log/combinators.d.ts.map +1 -0
  176. package/dist/server/log/combinators.js +270 -0
  177. package/dist/server/log/combinators.js.map +1 -0
  178. package/dist/server/log/console.d.ts +12 -0
  179. package/dist/server/log/console.d.ts.map +1 -0
  180. package/dist/server/log/console.js +96 -0
  181. package/dist/server/log/console.js.map +1 -0
  182. package/dist/server/log/file.d.ts +11 -0
  183. package/dist/server/log/file.d.ts.map +1 -0
  184. package/dist/server/log/file.js +61 -0
  185. package/dist/server/log/file.js.map +1 -0
  186. package/dist/server/log/index.d.ts +23 -0
  187. package/dist/server/log/index.d.ts.map +1 -0
  188. package/dist/server/log/index.js +45 -0
  189. package/dist/server/log/index.js.map +1 -0
  190. package/dist/server/log/logger.d.ts +53 -0
  191. package/dist/server/log/logger.d.ts.map +1 -0
  192. package/dist/server/log/logger.js +94 -0
  193. package/dist/server/log/logger.js.map +1 -0
  194. package/dist/server/log/memory.d.ts +11 -0
  195. package/dist/server/log/memory.d.ts.map +1 -0
  196. package/dist/server/log/memory.js +25 -0
  197. package/dist/server/log/memory.js.map +1 -0
  198. package/dist/server/log/types.d.ts +112 -0
  199. package/dist/server/log/types.d.ts.map +1 -0
  200. package/dist/server/log/types.js +58 -0
  201. package/dist/server/log/types.js.map +1 -0
  202. package/dist/server/policy.d.ts +29 -0
  203. package/dist/server/policy.d.ts.map +1 -0
  204. package/dist/server/policy.js +29 -0
  205. package/dist/server/policy.js.map +1 -0
  206. package/dist/server/queue.d.ts +1 -1
  207. package/dist/server/queue.d.ts.map +1 -1
  208. package/dist/server/queue.js.map +1 -1
  209. package/dist/server/ratelimit.d.ts +48 -0
  210. package/dist/server/ratelimit.d.ts.map +1 -0
  211. package/dist/server/ratelimit.js +102 -0
  212. package/dist/server/ratelimit.js.map +1 -0
  213. package/dist/server/respond.d.ts.map +1 -1
  214. package/dist/server/respond.js +16 -1
  215. package/dist/server/respond.js.map +1 -1
  216. package/dist/server/runtime.d.ts +18 -3
  217. package/dist/server/runtime.d.ts.map +1 -1
  218. package/dist/server/runtime.js +32 -2
  219. package/dist/server/runtime.js.map +1 -1
  220. package/dist/server/schedule.d.ts +18 -0
  221. package/dist/server/schedule.d.ts.map +1 -0
  222. package/dist/server/schedule.js +70 -0
  223. package/dist/server/schedule.js.map +1 -0
  224. package/dist/server/sequence.d.ts +42 -0
  225. package/dist/server/sequence.d.ts.map +1 -0
  226. package/dist/server/sequence.js +97 -0
  227. package/dist/server/sequence.js.map +1 -0
  228. package/dist/server/session.d.ts +21 -0
  229. package/dist/server/session.d.ts.map +1 -1
  230. package/dist/server/session.js +84 -10
  231. package/dist/server/session.js.map +1 -1
  232. package/dist/server/sessionstore.d.ts +3 -1
  233. package/dist/server/sessionstore.d.ts.map +1 -1
  234. package/dist/server/sessionstore.js +7 -3
  235. package/dist/server/sessionstore.js.map +1 -1
  236. package/dist/server/storage/index.d.ts +1 -1
  237. package/dist/server/storage/index.d.ts.map +1 -1
  238. package/dist/server/storage/index.js +61 -1
  239. package/dist/server/storage/index.js.map +1 -1
  240. package/dist/server/storage/types.d.ts +8 -0
  241. package/dist/server/storage/types.d.ts.map +1 -1
  242. package/dist/server/storage/types.js +58 -0
  243. package/dist/server/storage/types.js.map +1 -1
  244. package/dist/server/stream.d.ts +8 -2
  245. package/dist/server/stream.d.ts.map +1 -1
  246. package/dist/server/stream.js +44 -4
  247. package/dist/server/stream.js.map +1 -1
  248. package/dist/server/streamstore.d.ts +10 -0
  249. package/dist/server/streamstore.d.ts.map +1 -1
  250. package/dist/server/streamstore.js +72 -6
  251. package/dist/server/streamstore.js.map +1 -1
  252. package/dist/server/tenants.d.ts +20 -18
  253. package/dist/server/tenants.d.ts.map +1 -1
  254. package/dist/server/tenants.js +133 -84
  255. package/dist/server/tenants.js.map +1 -1
  256. package/dist/server/transport/types.js +2 -2
  257. package/dist/server/transport/types.js.map +1 -1
  258. package/dist/server/worker.d.ts +19 -3
  259. package/dist/server/worker.d.ts.map +1 -1
  260. package/dist/server/worker.js +168 -21
  261. package/dist/server/worker.js.map +1 -1
  262. package/dist/testing.d.ts +26 -10
  263. package/dist/testing.d.ts.map +1 -1
  264. package/dist/testing.js +41 -14
  265. package/dist/testing.js.map +1 -1
  266. package/dist/theme/contracts.d.ts +14 -1
  267. package/dist/theme/contracts.d.ts.map +1 -1
  268. package/dist/theme/contracts.js +35 -6
  269. package/dist/theme/contracts.js.map +1 -1
  270. package/dist/theme/index.d.ts +1 -1
  271. package/dist/theme/index.d.ts.map +1 -1
  272. package/dist/theme/index.js +1 -1
  273. package/dist/theme/index.js.map +1 -1
  274. package/dist/theme/joint-runtime.d.ts +33 -0
  275. package/dist/theme/joint-runtime.d.ts.map +1 -0
  276. package/dist/theme/joint-runtime.js +121 -0
  277. package/dist/theme/joint-runtime.js.map +1 -0
  278. package/dist/theme/joints.d.ts.map +1 -1
  279. package/dist/theme/joints.js +15 -97
  280. package/dist/theme/joints.js.map +1 -1
  281. package/dist/theme/ktl/compile.d.ts +4 -0
  282. package/dist/theme/ktl/compile.d.ts.map +1 -1
  283. package/dist/theme/ktl/compile.js +54 -1
  284. package/dist/theme/ktl/compile.js.map +1 -1
  285. package/dist/theme/ktl/parser.d.ts +4 -0
  286. package/dist/theme/ktl/parser.d.ts.map +1 -1
  287. package/dist/theme/ktl/parser.js +8 -0
  288. package/dist/theme/ktl/parser.js.map +1 -1
  289. package/dist/theme/render.d.ts +8 -0
  290. package/dist/theme/render.d.ts.map +1 -1
  291. package/dist/theme/render.js +88 -118
  292. package/dist/theme/render.js.map +1 -1
  293. package/dist/theme/tokens.d.ts +18 -0
  294. package/dist/theme/tokens.d.ts.map +1 -1
  295. package/dist/theme/tokens.js +33 -0
  296. package/dist/theme/tokens.js.map +1 -1
  297. package/dist/theme/viewmodel.d.ts +24 -0
  298. package/dist/theme/viewmodel.d.ts.map +1 -1
  299. package/dist/theme/viewmodel.js +75 -6
  300. package/dist/theme/viewmodel.js.map +1 -1
  301. package/dist/types.d.ts +320 -56
  302. package/dist/types.d.ts.map +1 -1
  303. package/package.json +6 -2
  304. package/dist/kernel/apps.d.ts +0 -43
  305. package/dist/kernel/apps.d.ts.map +0 -1
  306. package/dist/kernel/apps.js +0 -234
  307. package/dist/kernel/apps.js.map +0 -1
@@ -0,0 +1,196 @@
1
+ // Physical-schema verification for adopting an application-owned migration.
2
+ //
3
+ // The ordinary migration marker is intentionally declarative: it records the
4
+ // manifest KetJS actually applied. A hand-written migration is the one exception,
5
+ // and it may advance that marker only after the adapter's catalog proves every
6
+ // modelled table, column, constraint, and index is at the requested target.
7
+ const truthy = (value) => value === true || value === 1 || value === '1' || value === 't' || value === 'true' || value === 'YES';
8
+ const normalizeType = (value) => {
9
+ const type = String(value ?? '')
10
+ .trim()
11
+ .toLowerCase()
12
+ .replace(/\s+/g, ' ')
13
+ .replace(/\s+primary key$/, '');
14
+ const aliases = {
15
+ int8: 'bigint',
16
+ float8: 'double precision',
17
+ timestamptz: 'timestamp with time zone',
18
+ decimal: 'numeric',
19
+ };
20
+ return aliases[type] ?? type;
21
+ };
22
+ const expectedType = (adapter, column) => normalizeType(adapter.columnSql(column));
23
+ async function inspectSqliteTable(adapter, table) {
24
+ const q = adapter.quoteIdent;
25
+ const rows = await adapter.all(`PRAGMA table_info(${q(table)})`);
26
+ if (!rows.length)
27
+ return null;
28
+ const columns = {};
29
+ for (const row of rows) {
30
+ const name = String(row.name);
31
+ const primary = truthy(row.pk);
32
+ columns[name] = {
33
+ type: normalizeType(row.type),
34
+ // SQLite reports `notnull = 0` for a generated TEXT PRIMARY KEY. Treat the
35
+ // primary-key contract as required while checking PK identity separately.
36
+ nullable: !truthy(row.notnull) && !primary,
37
+ primary,
38
+ };
39
+ }
40
+ const indexes = {};
41
+ for (const row of await adapter.all(`PRAGMA index_list(${q(table)})`)) {
42
+ const name = String(row.name);
43
+ const fieldRows = (await adapter.all(`PRAGMA index_info(${q(name)})`)).sort((a, b) => Number(a.seqno) - Number(b.seqno));
44
+ const expression = fieldRows.some((field) => Number(field.cid) === -2);
45
+ const fields = fieldRows.map((field) => (Number(field.cid) === -2 ? '<expression>' : String(field.name)));
46
+ indexes[name] = {
47
+ fields,
48
+ unique: truthy(row.unique),
49
+ expression,
50
+ partial: truthy(row.partial),
51
+ valid: true,
52
+ ready: true,
53
+ live: true,
54
+ };
55
+ }
56
+ return { columns, indexes };
57
+ }
58
+ async function inspectPostgresTable(adapter, table) {
59
+ const rows = await adapter.all(`SELECT column_name, data_type, is_nullable
60
+ FROM information_schema.columns
61
+ WHERE table_schema = 'public' AND table_name = $1
62
+ ORDER BY ordinal_position`, [table]);
63
+ if (!rows.length)
64
+ return null;
65
+ const primary = new Set((await adapter.all(`SELECT kcu.column_name
66
+ FROM information_schema.table_constraints tc
67
+ JOIN information_schema.key_column_usage kcu
68
+ ON kcu.constraint_name = tc.constraint_name
69
+ AND kcu.constraint_schema = tc.constraint_schema
70
+ WHERE tc.table_schema = 'public'
71
+ AND tc.table_name = $1
72
+ AND tc.constraint_type = 'PRIMARY KEY'
73
+ ORDER BY kcu.ordinal_position`, [table])).map((row) => String(row.column_name)));
74
+ const columns = {};
75
+ for (const row of rows) {
76
+ const name = String(row.column_name);
77
+ columns[name] = {
78
+ type: normalizeType(row.data_type),
79
+ nullable: String(row.is_nullable).toUpperCase() === 'YES',
80
+ primary: primary.has(name),
81
+ };
82
+ }
83
+ const indexRows = await adapter.all(`SELECT index_class.relname AS index_name,
84
+ index_meta.indisunique AS is_unique,
85
+ index_meta.indpred IS NOT NULL AS is_partial,
86
+ index_meta.indisvalid AS is_valid,
87
+ index_meta.indisready AS is_ready,
88
+ index_meta.indislive AS is_live,
89
+ indexed_key.attnum = 0 AS is_expression,
90
+ attribute.attname AS column_name,
91
+ indexed_key.ordinality AS position
92
+ FROM pg_class table_class
93
+ JOIN pg_namespace namespace ON namespace.oid = table_class.relnamespace
94
+ JOIN pg_index index_meta ON index_meta.indrelid = table_class.oid
95
+ JOIN pg_class index_class ON index_class.oid = index_meta.indexrelid
96
+ JOIN LATERAL unnest(index_meta.indkey) WITH ORDINALITY AS indexed_key(attnum, ordinality) ON true
97
+ LEFT JOIN pg_attribute attribute
98
+ ON attribute.attrelid = table_class.oid AND attribute.attnum = indexed_key.attnum
99
+ WHERE namespace.nspname = 'public'
100
+ AND table_class.relname = $1
101
+ AND NOT index_meta.indisprimary
102
+ ORDER BY index_class.relname, indexed_key.ordinality`, [table]);
103
+ const indexes = {};
104
+ for (const row of indexRows) {
105
+ const name = String(row.index_name);
106
+ const expression = truthy(row.is_expression);
107
+ const index = (indexes[name] ??= {
108
+ fields: [],
109
+ unique: truthy(row.is_unique),
110
+ expression: false,
111
+ partial: truthy(row.is_partial),
112
+ valid: truthy(row.is_valid),
113
+ ready: truthy(row.is_ready),
114
+ live: truthy(row.is_live),
115
+ });
116
+ index.expression ||= expression;
117
+ index.fields[Number(row.position) - 1] = expression ? '<expression>' : String(row.column_name);
118
+ }
119
+ return { columns, indexes };
120
+ }
121
+ const inspectTable = (adapter, table) => {
122
+ if (adapter.name === 'sqlite')
123
+ return inspectSqliteTable(adapter, table);
124
+ if (adapter.name === 'postgres')
125
+ return inspectPostgresTable(adapter, table);
126
+ throw new Error(`adapter "${adapter.name}" cannot verify a physical schema safely; catalog verification supports sqlite and postgres`);
127
+ };
128
+ const describeFields = (fields) => `(${fields.join(', ')})`;
129
+ /** Return every modelled difference between the physical database and `target`. */
130
+ export async function physicalSchemaIssues(adapter, previous, target) {
131
+ const issues = [];
132
+ const tableNames = new Set([...Object.keys(previous.tables), ...Object.keys(target.tables)]);
133
+ for (const tableName of [...tableNames].sort()) {
134
+ const before = previous.tables[tableName];
135
+ const expected = target.tables[tableName];
136
+ const actual = await inspectTable(adapter, tableName);
137
+ if (!expected) {
138
+ if (actual)
139
+ issues.push(`table ${tableName} still exists; expected it to be removed`);
140
+ continue;
141
+ }
142
+ if (!actual) {
143
+ issues.push(`table ${tableName} is missing`);
144
+ continue;
145
+ }
146
+ for (const [columnName, column] of Object.entries(expected.columns)) {
147
+ const held = actual.columns[columnName];
148
+ const path = `${tableName}.${columnName}`;
149
+ if (!held) {
150
+ issues.push(`column ${path} is missing`);
151
+ continue;
152
+ }
153
+ const type = expectedType(adapter, column);
154
+ if (held.type !== type)
155
+ issues.push(`column ${path} has type ${held.type || '(none)'}; expected ${type}`);
156
+ if (held.nullable !== column.optional)
157
+ issues.push(`column ${path} is ${held.nullable ? 'nullable' : 'NOT NULL'}; expected ${column.optional ? 'nullable' : 'NOT NULL'}`);
158
+ const primary = column.base === 'id';
159
+ if (held.primary !== primary)
160
+ issues.push(`column ${path} is ${held.primary ? '' : 'not '}the expected primary key`);
161
+ }
162
+ for (const columnName of Object.keys(before?.columns ?? {})) {
163
+ if (!expected.columns[columnName] && actual.columns[columnName])
164
+ issues.push(`column ${tableName}.${columnName} still exists; expected it to be removed`);
165
+ }
166
+ for (const [name, index] of Object.entries(expected.indexes ?? {})) {
167
+ const physicalName = `${tableName}__${name}`;
168
+ const held = actual.indexes[physicalName];
169
+ if (!held) {
170
+ issues.push(`index ${physicalName} is missing`);
171
+ continue;
172
+ }
173
+ if (held.unique !== index.unique)
174
+ issues.push(`index ${physicalName} is ${held.unique ? 'unique' : 'non-unique'}; expected ${index.unique ? 'unique' : 'non-unique'}`);
175
+ if (held.expression)
176
+ issues.push(`index ${physicalName} contains expressions; expected only model fields`);
177
+ if (held.partial)
178
+ issues.push(`index ${physicalName} is partial; expected an unfiltered index`);
179
+ if (!held.valid)
180
+ issues.push(`index ${physicalName} is invalid`);
181
+ if (!held.ready)
182
+ issues.push(`index ${physicalName} is not ready for inserts`);
183
+ if (!held.live)
184
+ issues.push(`index ${physicalName} is being dropped`);
185
+ if (held.fields.join('\0') !== index.fields.join('\0'))
186
+ issues.push(`index ${physicalName} covers ${describeFields(held.fields)}; expected ${describeFields(index.fields)}`);
187
+ }
188
+ for (const name of Object.keys(before?.indexes ?? {})) {
189
+ const physicalName = `${tableName}__${name}`;
190
+ if (!expected.indexes?.[name] && actual.indexes[physicalName])
191
+ issues.push(`index ${physicalName} still exists; expected it to be removed`);
192
+ }
193
+ }
194
+ return issues;
195
+ }
196
+ //# sourceMappingURL=physical.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"physical.js","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/data/physical.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import type { Adapter } from '../types.ts';
2
2
  export type PoolOptions = {
3
- create(key: string): Adapter;
3
+ /** Create a fresh adapter for this pool entry; the pool owns its open/close lifecycle. */
4
+ create(key: string): Adapter | Promise<Adapter>;
4
5
  /** How many databases may stay open at once. */
5
6
  max?: number;
6
7
  /** Close an idle database after this long. */
@@ -1 +1 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../../../../packages/ketjs/src/data/pool.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IAC5B,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB,CAAA;AAID,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACtC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACtE,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,WAAW,GAAG,WAAW,CAiF7D"}
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../../../../packages/ketjs/src/data/pool.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,MAAM,MAAM,WAAW,GAAG;IACxB,0FAA0F;IAC1F,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB,CAAA;AAID,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACtC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACtE,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,WAAW,GAAG,WAAW,CAiM7D"}
package/dist/data/pool.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // One adapter per database, kept warm and bounded.
2
2
  //
3
- // This is where the Odoo model hurts most in practice: a database per tenant means
3
+ // This is where the domain contract model hurts most in practice: a database per tenant means
4
4
  // connections multiply by tenant, and a Postgres cluster has a hard ceiling on them.
5
5
  // So the pool caps how many databases stay open at once, evicts the least recently
6
6
  // used, and refuses to close one that a request is still holding.
@@ -9,40 +9,128 @@ export function createAdapterPool(o) {
9
9
  const idleMs = o.idleMs ?? 5 * 60_000;
10
10
  const now = o.now ?? (() => Date.now());
11
11
  const entries = new Map();
12
+ const closing = new Set();
13
+ let state = 'open';
14
+ let closePromise = null;
15
+ const assertOpen = () => {
16
+ if (state !== 'open')
17
+ throw new Error('adapter pool is closed');
18
+ };
19
+ // Admission is separate from leasing an existing entry. Opening another
20
+ // datastore may have to close an idle one first, and that closing connection
21
+ // still consumes capacity until close() settles. Serializing this small path
22
+ // keeps a later acquire from slipping into the temporarily empty Map slot.
23
+ let admissionTail = Promise.resolve();
24
+ const withAdmission = async (fn) => {
25
+ const previous = admissionTail;
26
+ let release;
27
+ admissionTail = new Promise((resolve) => {
28
+ release = resolve;
29
+ });
30
+ await previous;
31
+ try {
32
+ return await fn();
33
+ }
34
+ finally {
35
+ release();
36
+ }
37
+ };
12
38
  const evictOne = async () => {
13
39
  let oldest = null;
14
40
  for (const [k, e] of entries) {
15
- if (e.leases > 0)
41
+ if (e.leases > 0 || e.opening || closing.has(e))
16
42
  continue;
17
43
  if (!oldest || e.lastUsed < oldest[1].lastUsed)
18
44
  oldest = [k, e];
19
45
  }
20
46
  if (!oldest)
21
47
  return false;
22
- entries.delete(oldest[0]);
23
- await oldest[1].adapter.close();
48
+ const [key, entry] = oldest;
49
+ closing.add(entry);
50
+ try {
51
+ await entry.adapter?.close();
52
+ }
53
+ finally {
54
+ // Keep the tombstone visible to size/open until close has settled. The
55
+ // admission lock keeps another datastore from claiming it meanwhile.
56
+ if (entries.get(key) === entry)
57
+ entries.delete(key);
58
+ closing.delete(entry);
59
+ }
24
60
  return true;
25
61
  };
26
62
  const acquire = async (key) => {
63
+ assertOpen();
27
64
  let e = entries.get(key);
65
+ if (e && closing.has(e))
66
+ e = undefined;
28
67
  if (!e) {
29
- // Make room before opening, never after: the cap is on connections actually held.
30
- while (entries.size >= max) {
31
- if (!(await evictOne())) {
32
- throw new Error(`adapter pool is full (${entries.size}/${max}) and every database is in use`);
68
+ e = await withAdmission(async () => {
69
+ assertOpen();
70
+ // Another acquire for this key may have won admission while we waited.
71
+ const admitted = entries.get(key);
72
+ if (admitted) {
73
+ // Eviction normally owns the admission lock for the whole close, so a
74
+ // closing entry here would mean that lifecycle invariant was broken.
75
+ // Never lease it even if a future close path forgets that invariant.
76
+ if (closing.has(admitted))
77
+ throw new Error(`adapter pool entry "${key}" is closing during admission`);
78
+ return admitted;
33
79
  }
80
+ // Make room before opening, never after: the cap is on connections
81
+ // actually held, including a victim whose close() is still in flight.
82
+ while (entries.size >= max) {
83
+ if (!(await evictOne())) {
84
+ throw new Error(`adapter pool is full (${entries.size}/${max}) and every database is in use`);
85
+ }
86
+ }
87
+ // close() marks the pool terminal before waiting for admission. An
88
+ // acquire already queued here must not create an adapter after shutdown.
89
+ assertOpen();
90
+ const entry = { adapter: null, leases: 0, lastUsed: now(), opening: null };
91
+ entries.set(key, entry);
92
+ entry.opening = (async () => {
93
+ const adapter = await o.create(key);
94
+ entry.adapter = adapter;
95
+ try {
96
+ await adapter.open();
97
+ }
98
+ catch (error) {
99
+ await adapter.close().catch(() => { });
100
+ entry.adapter = null;
101
+ throw error;
102
+ }
103
+ })().catch((error) => {
104
+ if (entries.get(key) === entry)
105
+ entries.delete(key);
106
+ throw error;
107
+ });
108
+ return entry;
109
+ });
110
+ }
111
+ if (closing.has(e))
112
+ throw new Error(`adapter pool entry "${key}" is closing`);
113
+ assertOpen();
114
+ e.leases++;
115
+ const opening = e.opening;
116
+ if (opening) {
117
+ try {
118
+ await opening;
34
119
  }
35
- const adapter = o.create(key);
36
- e = { adapter, leases: 0, lastUsed: now(), opening: null };
37
- entries.set(key, e);
38
- e.opening = adapter.open();
120
+ catch (error) {
121
+ e.leases = Math.max(0, e.leases - 1);
122
+ throw error;
123
+ }
124
+ if (e.opening === opening)
125
+ e.opening = null;
39
126
  }
40
- if (e.opening) {
41
- await e.opening;
42
- e.opening = null;
127
+ if (state !== 'open') {
128
+ e.leases = Math.max(0, e.leases - 1);
129
+ throw new Error('adapter pool is closed');
43
130
  }
44
- e.leases++;
45
131
  e.lastUsed = now();
132
+ if (!e.adapter)
133
+ throw new Error(`adapter pool failed to open "${key}"`);
46
134
  return e.adapter;
47
135
  };
48
136
  const release = (key) => {
@@ -64,22 +152,62 @@ export function createAdapterPool(o) {
64
152
  release(key);
65
153
  }
66
154
  },
67
- async evictIdle() {
68
- const cutoff = now() - idleMs;
69
- let n = 0;
70
- for (const [k, e] of [...entries]) {
71
- if (e.leases > 0 || e.lastUsed > cutoff)
72
- continue;
73
- entries.delete(k);
74
- await e.adapter.close();
75
- n++;
76
- }
77
- return n;
155
+ evictIdle() {
156
+ return withAdmission(async () => {
157
+ const cutoff = now() - idleMs;
158
+ let n = 0;
159
+ for (const [k, e] of [...entries]) {
160
+ if (e.leases > 0 || e.opening || closing.has(e) || e.lastUsed > cutoff)
161
+ continue;
162
+ closing.add(e);
163
+ try {
164
+ await e.adapter?.close();
165
+ n++;
166
+ }
167
+ finally {
168
+ if (entries.get(k) === e)
169
+ entries.delete(k);
170
+ closing.delete(e);
171
+ }
172
+ }
173
+ return n;
174
+ });
78
175
  },
79
- async close() {
80
- for (const [, e] of entries)
81
- await e.adapter.close();
82
- entries.clear();
176
+ close() {
177
+ if (closePromise)
178
+ return closePromise;
179
+ // Terminal state is visible synchronously. The actual drain is queued
180
+ // behind admission so it cannot race an eviction or a new datastore.
181
+ state = 'closing';
182
+ closePromise = withAdmission(async () => {
183
+ const errors = [];
184
+ for (const [key, e] of [...entries]) {
185
+ closing.add(e);
186
+ try {
187
+ if (e.opening)
188
+ await e.opening.catch(() => { });
189
+ await e.adapter?.close();
190
+ }
191
+ catch (error) {
192
+ errors.push(error);
193
+ }
194
+ finally {
195
+ e.adapter = null;
196
+ e.opening = null;
197
+ if (entries.get(key) === e)
198
+ entries.delete(key);
199
+ closing.delete(e);
200
+ }
201
+ }
202
+ entries.clear();
203
+ if (errors.length === 1)
204
+ throw errors[0];
205
+ if (errors.length > 1)
206
+ throw new AggregateError(errors, 'adapter pool failed to close');
207
+ }).finally(() => {
208
+ state = 'closed';
209
+ });
210
+ return closePromise;
83
211
  },
84
212
  get open() {
85
213
  return [...entries.keys()];
@@ -1 +1 @@
1
- {"version":3,"file":"pool.js","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/data/pool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/data/pool.ts"],"names":[],"mappings":"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"}
@@ -18,11 +18,20 @@ export type GroupSpec = {
18
18
  };
19
19
  export type AggregateSpec = {
20
20
  fn: 'count';
21
+ col?: Col;
21
22
  as: string;
22
23
  } | {
23
- fn: 'countDistinct' | 'sum' | 'avg' | 'min' | 'max';
24
+ fn: 'countDistinct' | 'sum' | 'min' | 'max';
24
25
  col: Col;
25
26
  as: string;
27
+ } | {
28
+ fn: 'avg';
29
+ col: Col;
30
+ as: string;
31
+ /** Required for decimal columns so both adapters return the same finite value. */
32
+ scale?: number;
33
+ /** Decimal averages currently support PostgreSQL-compatible half-away-from-zero rounding. */
34
+ rounding?: 'half-away-from-zero';
26
35
  };
27
36
  export type GroupOrder = {
28
37
  by: 'key' | 'count' | string;
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../../../packages/ketjs/src/data/query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../../../packages/ketjs/src/data/query.ts"],"names":[],"mappings":"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"}