nexus-ai-pro 2.0.0 → 2.2.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 (282) hide show
  1. package/API_STABILITY.md +65 -0
  2. package/CHANGELOG.md +267 -1
  3. package/MIGRATING.md +1 -1
  4. package/README.md +17 -8
  5. package/dist/agent/create-agent.d.ts +9 -1
  6. package/dist/agent/create-agent.js +40 -1
  7. package/dist/cache/memory-cache.d.ts +8 -0
  8. package/dist/cache/memory-cache.js +9 -0
  9. package/dist/cache/semantic-cache.d.ts +6 -3
  10. package/dist/cache/semantic-cache.js +5 -2
  11. package/dist/cli/args.js +3 -0
  12. package/dist/cli/db.d.ts +16 -4
  13. package/dist/cli/db.js +169 -22
  14. package/dist/cli/doctor.d.ts +17 -0
  15. package/dist/cli/doctor.js +53 -0
  16. package/dist/cli/graph.d.ts +9 -0
  17. package/dist/cli/graph.js +47 -0
  18. package/dist/cli.js +21 -2
  19. package/dist/core/lifecycle.js +11 -6
  20. package/dist/core/nexus.d.ts +12 -2
  21. package/dist/core/nexus.js +106 -23
  22. package/dist/doctor/index.d.ts +90 -0
  23. package/dist/doctor/index.js +237 -0
  24. package/dist/evals/judge.d.ts +11 -0
  25. package/dist/evals/judge.js +33 -0
  26. package/dist/evaluate/index.d.ts +1 -0
  27. package/dist/evaluate/index.js +1 -0
  28. package/dist/evaluate/provenance.d.ts +22 -0
  29. package/dist/evaluate/provenance.js +10 -0
  30. package/dist/evaluate/run.js +20 -4
  31. package/dist/graph/durability.d.ts +27 -0
  32. package/dist/graph/durability.js +66 -0
  33. package/dist/graph/errors.d.ts +30 -4
  34. package/dist/graph/errors.js +18 -2
  35. package/dist/graph/event-stream.d.ts +75 -0
  36. package/dist/graph/event-stream.js +289 -0
  37. package/dist/graph/functional.d.ts +80 -7
  38. package/dist/graph/functional.js +138 -35
  39. package/dist/graph/graph.d.ts +56 -8
  40. package/dist/graph/graph.js +331 -49
  41. package/dist/graph/index.d.ts +4 -2
  42. package/dist/graph/index.js +3 -1
  43. package/dist/graph/lint.d.ts +57 -0
  44. package/dist/graph/lint.js +141 -0
  45. package/dist/graph/run-control.d.ts +28 -0
  46. package/dist/graph/run-control.js +26 -0
  47. package/dist/images/evals.js +4 -2
  48. package/dist/operations/adapters.d.ts +52 -4
  49. package/dist/operations/adapters.js +194 -7
  50. package/dist/operations/runner.js +14 -15
  51. package/dist/operations/stats.js +8 -1
  52. package/dist/operations/store.d.ts +5 -1
  53. package/dist/operations/store.js +7 -0
  54. package/dist/ops/circuit-breaker.d.ts +52 -0
  55. package/dist/ops/circuit-breaker.js +4 -0
  56. package/dist/ops/circuit-store.d.ts +13 -2
  57. package/dist/ops/circuit-store.js +68 -0
  58. package/dist/ops/circuit-sync.d.ts +17 -0
  59. package/dist/ops/circuit-sync.js +86 -0
  60. package/dist/ops/health.d.ts +24 -0
  61. package/dist/ops/health.js +38 -10
  62. package/dist/ops/index.d.ts +1 -1
  63. package/dist/ops/index.js +1 -1
  64. package/dist/ops/rate-limit-adapters.d.ts +23 -0
  65. package/dist/ops/rate-limit-adapters.js +34 -0
  66. package/dist/ops/rate-limiter.d.ts +14 -2
  67. package/dist/ops/rate-limiter.js +31 -0
  68. package/dist/postgres/circuits.d.ts +21 -4
  69. package/dist/postgres/circuits.js +65 -4
  70. package/dist/postgres/client.d.ts +0 -2
  71. package/dist/postgres/client.js +0 -4
  72. package/dist/postgres/evaluate.d.ts +16 -4
  73. package/dist/postgres/evaluate.js +17 -5
  74. package/dist/postgres/index.d.ts +32 -11
  75. package/dist/postgres/index.js +65 -31
  76. package/dist/postgres/migrations.d.ts +60 -0
  77. package/dist/postgres/migrations.js +121 -0
  78. package/dist/postgres/operations.d.ts +14 -3
  79. package/dist/postgres/operations.js +45 -15
  80. package/dist/postgres/prompts.d.ts +11 -2
  81. package/dist/postgres/prompts.js +14 -3
  82. package/dist/postgres/rollups.d.ts +35 -0
  83. package/dist/postgres/rollups.js +129 -0
  84. package/dist/postgres/store.d.ts +11 -2
  85. package/dist/postgres/store.js +14 -3
  86. package/dist/postgres/traces.d.ts +13 -3
  87. package/dist/postgres/traces.js +25 -3
  88. package/dist/postgres/vectors.d.ts +11 -2
  89. package/dist/postgres/vectors.js +14 -3
  90. package/dist/router/auto-router.d.ts +34 -7
  91. package/dist/router/auto-router.js +201 -68
  92. package/dist/server/assistant.d.ts +44 -0
  93. package/dist/server/assistant.js +39 -0
  94. package/dist/server/errors.d.ts +12 -0
  95. package/dist/server/errors.js +7 -0
  96. package/dist/server/index.d.ts +1 -1
  97. package/dist/server/index.js +1 -1
  98. package/dist/server/runs.d.ts +28 -1
  99. package/dist/server/runs.js +110 -14
  100. package/dist/sqlite/index.d.ts +16 -3
  101. package/dist/sqlite/index.js +16 -3
  102. package/dist/sqlite/migrations.d.ts +26 -0
  103. package/dist/sqlite/migrations.js +63 -0
  104. package/dist/sqlite/operations.d.ts +14 -3
  105. package/dist/sqlite/operations.js +42 -15
  106. package/dist/sqlite/store.d.ts +9 -2
  107. package/dist/sqlite/store.js +13 -3
  108. package/dist/sqlite/vectors.d.ts +11 -2
  109. package/dist/sqlite/vectors.js +13 -2
  110. package/dist/store/tenant.d.ts +12 -0
  111. package/dist/store/tenant.js +29 -0
  112. package/dist/tenancy/index.d.ts +113 -0
  113. package/dist/tenancy/index.js +233 -0
  114. package/dist/testing/record.d.ts +42 -0
  115. package/dist/testing/record.js +57 -5
  116. package/dist/tracing/index.d.ts +3 -3
  117. package/dist/tracing/index.js +2 -2
  118. package/dist/tracing/instrument.js +30 -0
  119. package/dist/tracing/otlp.d.ts +91 -0
  120. package/dist/tracing/otlp.js +124 -0
  121. package/dist/tracing/rollups.d.ts +100 -0
  122. package/dist/tracing/rollups.js +139 -0
  123. package/dist/tracing/stores.d.ts +17 -0
  124. package/dist/tracing/stores.js +23 -0
  125. package/dist/tracing/tracer.d.ts +50 -4
  126. package/dist/tracing/tracer.js +85 -6
  127. package/dist/types/config.d.ts +33 -2
  128. package/dist/types/evaluate.d.ts +37 -0
  129. package/dist/types/graph.d.ts +354 -9
  130. package/dist/types/graph.js +3 -1
  131. package/dist/types/messages.d.ts +5 -0
  132. package/dist/types/operations.d.ts +22 -2
  133. package/dist/types/response.d.ts +20 -0
  134. package/dist/types/server.d.ts +18 -0
  135. package/dist/types/tracing.d.ts +11 -0
  136. package/dist/utils/schema-migrations.d.ts +97 -0
  137. package/dist/utils/schema-migrations.js +91 -0
  138. package/dist/utils/signals.d.ts +17 -0
  139. package/dist/utils/signals.js +26 -0
  140. package/dist/utils/tenant.d.ts +14 -0
  141. package/dist/utils/tenant.js +16 -0
  142. package/dist/version.d.ts +5 -0
  143. package/dist/version.js +1 -0
  144. package/dist-cjs/agent/create-agent.d.ts +9 -1
  145. package/dist-cjs/agent/create-agent.js +40 -1
  146. package/dist-cjs/cache/memory-cache.d.ts +8 -0
  147. package/dist-cjs/cache/memory-cache.js +9 -0
  148. package/dist-cjs/cache/semantic-cache.d.ts +6 -3
  149. package/dist-cjs/cache/semantic-cache.js +5 -2
  150. package/dist-cjs/cli/args.js +3 -0
  151. package/dist-cjs/cli/db.d.ts +16 -4
  152. package/dist-cjs/cli/db.js +200 -20
  153. package/dist-cjs/cli/doctor.d.ts +17 -0
  154. package/dist-cjs/cli/doctor.js +56 -0
  155. package/dist-cjs/cli/graph.d.ts +9 -0
  156. package/dist-cjs/cli/graph.js +50 -0
  157. package/dist-cjs/core/lifecycle.js +11 -6
  158. package/dist-cjs/core/nexus.d.ts +12 -2
  159. package/dist-cjs/core/nexus.js +106 -23
  160. package/dist-cjs/doctor/index.d.ts +90 -0
  161. package/dist-cjs/doctor/index.js +276 -0
  162. package/dist-cjs/evals/judge.d.ts +11 -0
  163. package/dist-cjs/evals/judge.js +33 -0
  164. package/dist-cjs/evaluate/index.d.ts +1 -0
  165. package/dist-cjs/evaluate/index.js +3 -1
  166. package/dist-cjs/evaluate/provenance.d.ts +22 -0
  167. package/dist-cjs/evaluate/provenance.js +14 -0
  168. package/dist-cjs/evaluate/run.js +20 -4
  169. package/dist-cjs/graph/durability.d.ts +27 -0
  170. package/dist-cjs/graph/durability.js +70 -0
  171. package/dist-cjs/graph/errors.d.ts +30 -4
  172. package/dist-cjs/graph/errors.js +20 -3
  173. package/dist-cjs/graph/event-stream.d.ts +75 -0
  174. package/dist-cjs/graph/event-stream.js +295 -0
  175. package/dist-cjs/graph/functional.d.ts +80 -7
  176. package/dist-cjs/graph/functional.js +137 -34
  177. package/dist-cjs/graph/graph.d.ts +56 -8
  178. package/dist-cjs/graph/graph.js +330 -48
  179. package/dist-cjs/graph/index.d.ts +4 -2
  180. package/dist-cjs/graph/index.js +7 -1
  181. package/dist-cjs/graph/lint.d.ts +57 -0
  182. package/dist-cjs/graph/lint.js +144 -0
  183. package/dist-cjs/graph/run-control.d.ts +28 -0
  184. package/dist-cjs/graph/run-control.js +30 -0
  185. package/dist-cjs/images/evals.js +4 -2
  186. package/dist-cjs/operations/adapters.d.ts +52 -4
  187. package/dist-cjs/operations/adapters.js +193 -6
  188. package/dist-cjs/operations/runner.js +14 -15
  189. package/dist-cjs/operations/stats.js +8 -1
  190. package/dist-cjs/operations/store.d.ts +5 -1
  191. package/dist-cjs/operations/store.js +7 -0
  192. package/dist-cjs/ops/circuit-breaker.d.ts +52 -0
  193. package/dist-cjs/ops/circuit-breaker.js +4 -0
  194. package/dist-cjs/ops/circuit-store.d.ts +13 -2
  195. package/dist-cjs/ops/circuit-store.js +68 -0
  196. package/dist-cjs/ops/circuit-sync.d.ts +17 -0
  197. package/dist-cjs/ops/circuit-sync.js +87 -0
  198. package/dist-cjs/ops/health.d.ts +24 -0
  199. package/dist-cjs/ops/health.js +38 -10
  200. package/dist-cjs/ops/index.d.ts +1 -1
  201. package/dist-cjs/ops/rate-limit-adapters.d.ts +23 -0
  202. package/dist-cjs/ops/rate-limit-adapters.js +35 -1
  203. package/dist-cjs/ops/rate-limiter.d.ts +14 -2
  204. package/dist-cjs/ops/rate-limiter.js +32 -0
  205. package/dist-cjs/postgres/circuits.d.ts +21 -4
  206. package/dist-cjs/postgres/circuits.js +98 -3
  207. package/dist-cjs/postgres/client.d.ts +0 -2
  208. package/dist-cjs/postgres/client.js +0 -5
  209. package/dist-cjs/postgres/evaluate.d.ts +16 -4
  210. package/dist-cjs/postgres/evaluate.js +50 -4
  211. package/dist-cjs/postgres/index.d.ts +32 -11
  212. package/dist-cjs/postgres/index.js +69 -20
  213. package/dist-cjs/postgres/migrations.d.ts +60 -0
  214. package/dist-cjs/postgres/migrations.js +129 -0
  215. package/dist-cjs/postgres/operations.d.ts +14 -3
  216. package/dist-cjs/postgres/operations.js +78 -14
  217. package/dist-cjs/postgres/prompts.d.ts +11 -2
  218. package/dist-cjs/postgres/prompts.js +47 -2
  219. package/dist-cjs/postgres/rollups.d.ts +35 -0
  220. package/dist-cjs/postgres/rollups.js +168 -0
  221. package/dist-cjs/postgres/store.d.ts +11 -2
  222. package/dist-cjs/postgres/store.js +47 -2
  223. package/dist-cjs/postgres/traces.d.ts +13 -3
  224. package/dist-cjs/postgres/traces.js +58 -2
  225. package/dist-cjs/postgres/vectors.d.ts +11 -2
  226. package/dist-cjs/postgres/vectors.js +47 -2
  227. package/dist-cjs/router/auto-router.d.ts +34 -7
  228. package/dist-cjs/router/auto-router.js +201 -68
  229. package/dist-cjs/server/assistant.d.ts +44 -0
  230. package/dist-cjs/server/assistant.js +39 -0
  231. package/dist-cjs/server/errors.d.ts +12 -0
  232. package/dist-cjs/server/errors.js +9 -1
  233. package/dist-cjs/server/index.d.ts +1 -1
  234. package/dist-cjs/server/index.js +2 -1
  235. package/dist-cjs/server/runs.d.ts +28 -1
  236. package/dist-cjs/server/runs.js +109 -13
  237. package/dist-cjs/sqlite/index.d.ts +16 -3
  238. package/dist-cjs/sqlite/index.js +31 -10
  239. package/dist-cjs/sqlite/migrations.d.ts +26 -0
  240. package/dist-cjs/sqlite/migrations.js +71 -0
  241. package/dist-cjs/sqlite/operations.d.ts +14 -3
  242. package/dist-cjs/sqlite/operations.js +76 -15
  243. package/dist-cjs/sqlite/store.d.ts +9 -2
  244. package/dist-cjs/sqlite/store.js +47 -3
  245. package/dist-cjs/sqlite/vectors.d.ts +11 -2
  246. package/dist-cjs/sqlite/vectors.js +47 -2
  247. package/dist-cjs/store/tenant.d.ts +12 -0
  248. package/dist-cjs/store/tenant.js +33 -0
  249. package/dist-cjs/tenancy/index.d.ts +113 -0
  250. package/dist-cjs/tenancy/index.js +250 -0
  251. package/dist-cjs/testing/record.d.ts +42 -0
  252. package/dist-cjs/testing/record.js +57 -5
  253. package/dist-cjs/tracing/index.d.ts +3 -3
  254. package/dist-cjs/tracing/index.js +4 -1
  255. package/dist-cjs/tracing/instrument.js +30 -0
  256. package/dist-cjs/tracing/otlp.d.ts +91 -0
  257. package/dist-cjs/tracing/otlp.js +129 -0
  258. package/dist-cjs/tracing/rollups.d.ts +100 -0
  259. package/dist-cjs/tracing/rollups.js +147 -0
  260. package/dist-cjs/tracing/stores.d.ts +17 -0
  261. package/dist-cjs/tracing/stores.js +24 -0
  262. package/dist-cjs/tracing/tracer.d.ts +50 -4
  263. package/dist-cjs/tracing/tracer.js +87 -6
  264. package/dist-cjs/types/config.d.ts +33 -2
  265. package/dist-cjs/types/evaluate.d.ts +37 -0
  266. package/dist-cjs/types/graph.d.ts +354 -9
  267. package/dist-cjs/types/graph.js +3 -1
  268. package/dist-cjs/types/messages.d.ts +5 -0
  269. package/dist-cjs/types/operations.d.ts +22 -2
  270. package/dist-cjs/types/response.d.ts +20 -0
  271. package/dist-cjs/types/server.d.ts +18 -0
  272. package/dist-cjs/types/tracing.d.ts +11 -0
  273. package/dist-cjs/utils/schema-migrations.d.ts +97 -0
  274. package/dist-cjs/utils/schema-migrations.js +102 -0
  275. package/dist-cjs/utils/signals.d.ts +17 -0
  276. package/dist-cjs/utils/signals.js +29 -0
  277. package/dist-cjs/utils/tenant.d.ts +14 -0
  278. package/dist-cjs/utils/tenant.js +22 -0
  279. package/dist-cjs/version.d.ts +5 -0
  280. package/dist-cjs/version.js +4 -0
  281. package/llms.txt +4 -3
  282. package/package.json +110 -2
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SchemaMigrationError = exports.migrationChecksum = void 0;
4
+ exports.postgresMigrationStatus = postgresMigrationStatus;
5
+ exports.applyPostgresMigrations = applyPostgresMigrations;
6
+ exports.migrationsTableStatements = migrationsTableStatements;
7
+ const schema_migrations_js_1 = require("../utils/schema-migrations.js");
8
+ const client_js_1 = require("./client.js");
9
+ var schema_migrations_js_2 = require("../utils/schema-migrations.js");
10
+ Object.defineProperty(exports, "migrationChecksum", { enumerable: true, get: function () { return schema_migrations_js_2.migrationChecksum; } });
11
+ Object.defineProperty(exports, "SchemaMigrationError", { enumerable: true, get: function () { return schema_migrations_js_2.SchemaMigrationError; } });
12
+ const LOCK_NAME = 'migrate';
13
+ const DB_NOW = '(extract(epoch from clock_timestamp()) * 1000)';
14
+ async function postgresMigrationStatus(client, migrations, options = {}) {
15
+ return (0, schema_migrations_js_1.planMigrations)(migrations, await readApplied(client, options.table ?? schema_migrations_js_1.MIGRATIONS_TABLE));
16
+ }
17
+ async function applyPostgresMigrations(client, migrations, options = {}) {
18
+ const tableName = options.table ?? schema_migrations_js_1.MIGRATIONS_TABLE;
19
+ if (options.dryRun) {
20
+ const status = await postgresMigrationStatus(client, migrations, options);
21
+ (0, schema_migrations_js_1.assertUnchanged)(status);
22
+ return { applied: status.pending, statements: status.pending.flatMap((m) => [...m.statements]), dryRun: true };
23
+ }
24
+ (0, schema_migrations_js_1.planMigrations)(migrations, []);
25
+ await bootstrap(client, tableName);
26
+ const owner = `migrator-${globalThis.crypto.randomUUID()}`;
27
+ const lockTtlMs = options.lockTtlMs ?? 600_000;
28
+ await acquire(client, tableName, owner, lockTtlMs, options.lockTimeoutMs ?? 120_000);
29
+ try {
30
+ const status = (0, schema_migrations_js_1.planMigrations)(migrations, await readApplied(client, tableName));
31
+ (0, schema_migrations_js_1.assertUnchanged)(status);
32
+ const statements = [];
33
+ for (const migration of status.pending) {
34
+ if (!(await claim(client, tableName, owner, lockTtlMs))) {
35
+ throw new schema_migrations_js_1.SchemaMigrationError('MIGRATION_LOCKED', `The migration lock lapsed before ${(0, schema_migrations_js_1.label)(migration)}`);
36
+ }
37
+ const apply = async (connection) => {
38
+ for (const statement of migration.statements)
39
+ await connection.query(statement);
40
+ await connection.query(`INSERT INTO ${(0, client_js_1.quoteTable)(tableName)} (component, version, name, checksum, applied_at)
41
+ VALUES ($1, $2, $3, $4, $5) ON CONFLICT (component, version) DO NOTHING`, [
42
+ migration.component,
43
+ migration.version,
44
+ migration.name,
45
+ (0, schema_migrations_js_1.migrationChecksum)(migration),
46
+ new Date().toISOString(),
47
+ ]);
48
+ };
49
+ if (options.transaction)
50
+ await options.transaction(apply);
51
+ else
52
+ await apply(client);
53
+ statements.push(...migration.statements);
54
+ }
55
+ return { applied: status.pending, statements, dryRun: false };
56
+ }
57
+ finally {
58
+ await client
59
+ .query(`DELETE FROM ${lockTable(tableName)} WHERE name = $1 AND owner = $2`, [LOCK_NAME, owner])
60
+ .catch(() => undefined);
61
+ }
62
+ }
63
+ function migrationsTableStatements(table = schema_migrations_js_1.MIGRATIONS_TABLE) {
64
+ return [
65
+ `CREATE TABLE IF NOT EXISTS ${(0, client_js_1.quoteTable)(table)} (
66
+ component text NOT NULL,
67
+ version integer NOT NULL,
68
+ name text NOT NULL,
69
+ checksum text NOT NULL,
70
+ applied_at text COLLATE "C" NOT NULL,
71
+ PRIMARY KEY (component, version)
72
+ )`,
73
+ `CREATE TABLE IF NOT EXISTS ${lockTable(table)} (
74
+ name text PRIMARY KEY,
75
+ owner text NOT NULL,
76
+ expires_at double precision NOT NULL
77
+ )`,
78
+ ];
79
+ }
80
+ async function bootstrap(client, table) {
81
+ for (const statement of migrationsTableStatements(table)) {
82
+ try {
83
+ await client.query(statement);
84
+ }
85
+ catch (error) {
86
+ const code = error?.code;
87
+ if (code !== '23505' && code !== '42P07')
88
+ throw error;
89
+ }
90
+ }
91
+ }
92
+ async function readApplied(client, table) {
93
+ const { rows: exists } = await client.query('SELECT to_regclass($1) IS NOT NULL AS present', [(0, client_js_1.quoteTable)(table)]);
94
+ if (!exists[0]?.present)
95
+ return [];
96
+ const { rows } = await client.query(`SELECT component, version, name, checksum, applied_at FROM ${(0, client_js_1.quoteTable)(table)} ORDER BY applied_at, component, version`);
97
+ return rows.map((row) => {
98
+ const value = row;
99
+ return {
100
+ component: String(value.component),
101
+ version: Number(value.version),
102
+ name: String(value.name),
103
+ checksum: String(value.checksum),
104
+ appliedAt: String(value.applied_at),
105
+ };
106
+ });
107
+ }
108
+ async function acquire(client, table, owner, ttlMs, timeoutMs) {
109
+ const deadline = Date.now() + timeoutMs;
110
+ let wait = 50;
111
+ while (!(await claim(client, table, owner, ttlMs))) {
112
+ if (Date.now() >= deadline) {
113
+ throw new schema_migrations_js_1.SchemaMigrationError('MIGRATION_LOCKED', `Another migrator held the lock for ${timeoutMs} ms. It is released when that migrator finishes, or when its lease lapses.`);
114
+ }
115
+ await (0, schema_migrations_js_1.delay)(wait);
116
+ wait = Math.min(wait * 2, 1_000);
117
+ }
118
+ }
119
+ async function claim(client, table, owner, ttlMs) {
120
+ const lock = lockTable(table);
121
+ const { rows } = await client.query(`INSERT INTO ${lock} (name, owner, expires_at) VALUES ($1, $2, ${DB_NOW} + $3::double precision)
122
+ ON CONFLICT (name) DO UPDATE SET owner = EXCLUDED.owner, expires_at = EXCLUDED.expires_at
123
+ WHERE ${lock}.owner = EXCLUDED.owner OR ${lock}.expires_at < ${DB_NOW}
124
+ RETURNING owner`, [LOCK_NAME, owner, ttlMs]);
125
+ return rows.length > 0;
126
+ }
127
+ function lockTable(table) {
128
+ return (0, client_js_1.quoteTable)(`${table}_lock`);
129
+ }
@@ -1,12 +1,20 @@
1
1
  import type { OperationRecord, OperationStore, OperationStoreFilter, OperationStoreStats } from '../types/operations.js';
2
+ import type { MigrationResult, SchemaMigration } from '../utils/schema-migrations.js';
2
3
  import { type PostgresLikeClient } from './client.js';
4
+ import type { PostgresMigrateOptions } from './migrations.js';
3
5
  /** Options for the Postgres operation store. */
4
6
  export interface PostgresOperationStoreOptions {
5
7
  /** Table name, optionally schema-qualified. Defaults to `nexus_operations`. */
6
8
  table?: string;
7
9
  }
8
- /** The schema, as statements. Applied by `migrate()`, `nexus db sql`, or the application's own tooling. */
10
+ /** The schema, as statements: every migration's, in order. For `nexus db sql` or the application's own tooling. */
9
11
  export declare function operationStoreMigration(options?: PostgresOperationStoreOptions): string[];
12
+ /**
13
+ * The versioned schema, which `migrate()` and `nexus db migrate` apply. Version 1 is the 2.0 table;
14
+ * version 2 indexes queued work by age, so a claim reads the oldest few rows instead of sorting the
15
+ * queue; version 3 indexes queued work by tenant.
16
+ */
17
+ export declare function operationStoreMigrations(options?: PostgresOperationStoreOptions): SchemaMigration[];
10
18
  /**
11
19
  * Operation records in Postgres.
12
20
  *
@@ -25,8 +33,11 @@ export declare class PostgresOperationStore<TResult = unknown> implements Operat
25
33
  private readonly options;
26
34
  private readonly table;
27
35
  constructor(client: PostgresLikeClient, options?: PostgresOperationStoreOptions);
28
- /** Creates the table and indexes if they do not exist. Never runs implicitly. */
29
- migrate(): Promise<void>;
36
+ /**
37
+ * Applies this store's pending migrations, recorded in `nexus_schema_migrations`, under a lock.
38
+ * Never runs implicitly. Safe on a database an older release created: what exists is kept.
39
+ */
40
+ migrate(options?: PostgresMigrateOptions): Promise<MigrationResult>;
30
41
  /**
31
42
  * Inserts a new record. Throws `OperationDuplicateError` when its idempotency key is already
32
43
  * claimed. Refuses records carrying raw bytes.
@@ -1,7 +1,41 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.PostgresOperationStore = void 0;
4
37
  exports.operationStoreMigration = operationStoreMigration;
38
+ exports.operationStoreMigrations = operationStoreMigrations;
5
39
  const errors_js_1 = require("../operations/errors.js");
6
40
  const serialization_js_1 = require("../operations/serialization.js");
7
41
  const operations_js_1 = require("../types/operations.js");
@@ -9,8 +43,33 @@ const client_js_1 = require("./client.js");
9
43
  const DEFAULT_TABLE = 'nexus_operations';
10
44
  const TERMINAL = operations_js_1.TERMINAL_OPERATION_STATUSES.map((status) => `'${status}'`).join(', ');
11
45
  function operationStoreMigration(options = {}) {
46
+ return operationStoreMigrations(options).flatMap((migration) => [...migration.statements]);
47
+ }
48
+ function operationStoreMigrations(options = {}) {
12
49
  const name = options.table ?? DEFAULT_TABLE;
13
50
  const table = (0, client_js_1.quoteTable)(name);
51
+ const component = `operations:${name}`;
52
+ return [
53
+ { component, version: 1, name: 'create the operations table', statements: createStatements(name, table) },
54
+ {
55
+ component,
56
+ version: 2,
57
+ name: 'index queued work by age',
58
+ statements: [
59
+ `CREATE INDEX IF NOT EXISTS ${(0, client_js_1.quoteDerived)(name, 'queued')} ON ${table} (created_at, id) WHERE status = 'queued'`,
60
+ ],
61
+ },
62
+ {
63
+ component,
64
+ version: 3,
65
+ name: 'index queued work by tenant',
66
+ statements: [
67
+ `CREATE INDEX IF NOT EXISTS ${(0, client_js_1.quoteDerived)(name, 'tenant_queued')} ON ${table} ((doc ->> 'tenantId'), created_at, id) WHERE status = 'queued'`,
68
+ ],
69
+ },
70
+ ];
71
+ }
72
+ function createStatements(name, table) {
14
73
  return [
15
74
  `CREATE TABLE IF NOT EXISTS ${table} (
16
75
  id text PRIMARY KEY,
@@ -36,8 +95,9 @@ class PostgresOperationStore {
36
95
  this.options = options;
37
96
  this.table = (0, client_js_1.quoteTable)(options.table ?? DEFAULT_TABLE);
38
97
  }
39
- async migrate() {
40
- await (0, client_js_1.runStatements)(this.client, operationStoreMigration(this.options));
98
+ async migrate(options = {}) {
99
+ const { applyPostgresMigrations } = await Promise.resolve().then(() => __importStar(require('./migrations.js')));
100
+ return applyPostgresMigrations(this.client, operationStoreMigrations(this.options), options);
41
101
  }
42
102
  async create(record) {
43
103
  (0, serialization_js_1.assertSerializableRecord)(record);
@@ -99,29 +159,21 @@ class PostgresOperationStore {
99
159
  }
100
160
  async listQueued(limit, filter) {
101
161
  const params = [new Date().toISOString(), limit];
102
- let kind = '';
103
- if (filter?.kindPrefix) {
104
- params.push(filter.kindPrefix);
105
- kind = ' AND substr(kind, 1, char_length($3)) = $3';
106
- }
162
+ const narrowed = filterSql(filter, params);
107
163
  const { rows } = await this.client.query(`SELECT doc::text AS doc FROM ${this.table}
108
- WHERE status = 'queued' AND (lease_expires_at IS NULL OR lease_expires_at <= $1)${kind}
164
+ WHERE status = 'queued' AND (lease_expires_at IS NULL OR lease_expires_at <= $1)${narrowed}
109
165
  ORDER BY created_at, id
110
166
  LIMIT $2`, params);
111
167
  return rows.map((row) => (0, client_js_1.fromJson)(row.doc));
112
168
  }
113
169
  async stats(now, filter) {
114
170
  const params = [now];
115
- let kind = '';
116
- if (filter?.kindPrefix) {
117
- params.push(filter.kindPrefix);
118
- kind = ' AND substr(kind, 1, char_length($2)) = $2';
119
- }
171
+ const narrowed = filterSql(filter, params);
120
172
  const { rows } = await this.client.query(`SELECT status, count(*)::int AS count,
121
173
  min(created_at) FILTER (WHERE status = 'queued') AS oldest,
122
174
  count(*) FILTER (WHERE status = 'running' AND (lease_expires_at IS NULL OR lease_expires_at <= $1))::int AS lapsed
123
175
  FROM ${this.table}
124
- WHERE status NOT IN (${TERMINAL})${kind}
176
+ WHERE status NOT IN (${TERMINAL})${narrowed}
125
177
  GROUP BY status`, params);
126
178
  return statsFromRows(rows);
127
179
  }
@@ -144,6 +196,18 @@ class PostgresOperationStore {
144
196
  }
145
197
  }
146
198
  exports.PostgresOperationStore = PostgresOperationStore;
199
+ function filterSql(filter, params) {
200
+ let sql = '';
201
+ if (filter?.kindPrefix) {
202
+ params.push(filter.kindPrefix);
203
+ sql += ` AND substr(kind, 1, char_length($${params.length})) = $${params.length}`;
204
+ }
205
+ if (filter?.tenantId !== undefined) {
206
+ params.push(filter.tenantId);
207
+ sql += ` AND doc ->> 'tenantId' = $${params.length}`;
208
+ }
209
+ return sql;
210
+ }
147
211
  function statsFromRows(rows) {
148
212
  const byStatus = {};
149
213
  let oldestQueuedAt;
@@ -1,10 +1,16 @@
1
1
  import type { PromptHistoryEntry, PromptLabel, PromptStore, PromptVersion } from '../types/prompts.js';
2
+ import type { MigrationResult, SchemaMigration } from '../utils/schema-migrations.js';
2
3
  import { type PostgresLikeClient } from './client.js';
4
+ import type { PostgresMigrateOptions } from './migrations.js';
3
5
  /** Options for the Postgres prompt store. */
4
6
  export interface PostgresPromptStoreOptions {
5
7
  /** Table name prefix, optionally schema-qualified. Defaults to `nexus_prompt`, for `nexus_prompt_versions` and so on. */
6
8
  table?: string;
7
9
  }
10
+ /**
11
+ * The versioned schema, which `migrate()` and `nexus db migrate` apply. Version 1 is the 2.0 schema.
12
+ */
13
+ export declare function promptStoreMigrations(options?: PostgresPromptStoreOptions): SchemaMigration[];
8
14
  /** The schema for the prompt store, as statements. */
9
15
  export declare function promptStoreMigration(options?: PostgresPromptStoreOptions): string[];
10
16
  /**
@@ -20,8 +26,11 @@ export declare class PostgresPromptStore implements PromptStore {
20
26
  private readonly labels;
21
27
  private readonly history;
22
28
  constructor(client: PostgresLikeClient, options?: PostgresPromptStoreOptions);
23
- /** Creates the prompt tables if they do not exist. Never runs implicitly. */
24
- migrate(): Promise<void>;
29
+ /**
30
+ * Applies this store's pending migrations, recorded in `nexus_schema_migrations`, under a lock.
31
+ * Never runs implicitly. Safe on a database an older release created: what exists is kept.
32
+ */
33
+ migrate(options?: PostgresMigrateOptions): Promise<MigrationResult>;
25
34
  /** Stores a version, unless one with the same content version exists. */
26
35
  saveVersion(version: PromptVersion): Promise<void>;
27
36
  /** Reads a version. */
@@ -1,12 +1,56 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.PostgresPromptStore = void 0;
37
+ exports.promptStoreMigrations = promptStoreMigrations;
4
38
  exports.promptStoreMigration = promptStoreMigration;
5
39
  const client_js_1 = require("./client.js");
6
40
  function tables(options) {
7
41
  const base = options.table ?? 'nexus_prompt';
8
42
  return { base, versions: `${base}_versions`, labels: `${base}_labels`, history: `${base}_history` };
9
43
  }
44
+ function promptStoreMigrations(options = {}) {
45
+ return [
46
+ {
47
+ component: `prompts:${tables(options).versions}`,
48
+ version: 1,
49
+ name: 'create the prompt tables',
50
+ statements: promptStoreMigration(options),
51
+ },
52
+ ];
53
+ }
10
54
  function promptStoreMigration(options = {}) {
11
55
  const names = tables(options);
12
56
  return [
@@ -48,8 +92,9 @@ class PostgresPromptStore {
48
92
  this.labels = (0, client_js_1.quoteTable)(names.labels);
49
93
  this.history = (0, client_js_1.quoteTable)(names.history);
50
94
  }
51
- async migrate() {
52
- await (0, client_js_1.runStatements)(this.client, promptStoreMigration(this.options));
95
+ async migrate(options = {}) {
96
+ const { applyPostgresMigrations } = await Promise.resolve().then(() => __importStar(require('./migrations.js')));
97
+ return applyPostgresMigrations(this.client, promptStoreMigrations(this.options), options);
53
98
  }
54
99
  async saveVersion(version) {
55
100
  await this.client.query(`INSERT INTO ${this.versions} (name, version, created_at, doc) VALUES ($1, $2, $3, $4::jsonb) ON CONFLICT DO NOTHING`, [version.name, version.version, version.createdAt, JSON.stringify(version)]);
@@ -0,0 +1,35 @@
1
+ import { type RollupKey, type RollupQuery, type RollupRow, type RollupStore, type RollupTotals } from '../tracing/rollups.js';
2
+ import type { MigrationResult, SchemaMigration } from '../utils/schema-migrations.js';
3
+ import { type PostgresLikeClient } from './client.js';
4
+ import type { PostgresMigrateOptions } from './migrations.js';
5
+ /** Options for the Postgres rollup store. */
6
+ export interface PostgresRollupStoreOptions {
7
+ /** Table name, optionally schema-qualified. Defaults to `nexus_rollups`. */
8
+ table?: string;
9
+ }
10
+ /** The schema, as statements: every migration's, in order. */
11
+ export declare function rollupStoreMigration(options?: PostgresRollupStoreOptions): string[];
12
+ /** The versioned schema, which `migrate()` and `nexus db migrate` apply. */
13
+ export declare function rollupStoreMigrations(options?: PostgresRollupStoreOptions): SchemaMigration[];
14
+ /**
15
+ * Rollup rows in Postgres, so a dashboard's totals live beside its traces and survive a restart.
16
+ *
17
+ * Adding to a row is one `INSERT … ON CONFLICT DO UPDATE` that sums every total, latency buckets
18
+ * included, so two workers finishing runs in the same hour both count. A query reads only the rows
19
+ * of its range: a month of one tenant is a few hundred rows, however many runs it held.
20
+ */
21
+ export declare class PostgresRollupStore implements RollupStore {
22
+ private readonly client;
23
+ private readonly options;
24
+ private readonly table;
25
+ constructor(client: PostgresLikeClient, options?: PostgresRollupStoreOptions);
26
+ /**
27
+ * Applies this store's pending migrations, recorded in `nexus_schema_migrations`, under a lock.
28
+ * Never runs implicitly.
29
+ */
30
+ migrate(options?: PostgresMigrateOptions): Promise<MigrationResult>;
31
+ /** Adds totals to the row for `key`, creating it, in one statement. */
32
+ add(key: RollupKey, totals: RollupTotals): Promise<void>;
33
+ /** Rows matching a query, oldest hour first, filtered as the in-memory store filters them. */
34
+ query(query?: RollupQuery): Promise<RollupRow[]>;
35
+ }
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.PostgresRollupStore = void 0;
37
+ exports.rollupStoreMigration = rollupStoreMigration;
38
+ exports.rollupStoreMigrations = rollupStoreMigrations;
39
+ const rollups_js_1 = require("../tracing/rollups.js");
40
+ const client_js_1 = require("./client.js");
41
+ const sql_js_1 = require("./sql.js");
42
+ const DEFAULT_TABLE = 'nexus_rollups';
43
+ function rollupStoreMigration(options = {}) {
44
+ return rollupStoreMigrations(options).flatMap((migration) => [...migration.statements]);
45
+ }
46
+ function rollupStoreMigrations(options = {}) {
47
+ const name = options.table ?? DEFAULT_TABLE;
48
+ const table = (0, client_js_1.quoteTable)(name);
49
+ return [
50
+ {
51
+ component: `rollups:${name}`,
52
+ version: 1,
53
+ name: 'create the rollups table',
54
+ statements: [
55
+ `CREATE TABLE IF NOT EXISTS ${table} (
56
+ hour text COLLATE "C" NOT NULL,
57
+ kind text NOT NULL,
58
+ name text NOT NULL,
59
+ model text NOT NULL,
60
+ provider text NOT NULL,
61
+ tenant text NOT NULL,
62
+ runs bigint NOT NULL,
63
+ errors bigint NOT NULL,
64
+ cost double precision NOT NULL,
65
+ input_tokens bigint NOT NULL,
66
+ output_tokens bigint NOT NULL,
67
+ latency bigint[] NOT NULL,
68
+ PRIMARY KEY (hour, kind, name, model, provider, tenant)
69
+ )`,
70
+ `CREATE INDEX IF NOT EXISTS ${(0, client_js_1.quoteDerived)(name, 'tenant_hour')} ON ${table} (tenant, hour)`,
71
+ ],
72
+ },
73
+ ];
74
+ }
75
+ class PostgresRollupStore {
76
+ client;
77
+ options;
78
+ table;
79
+ constructor(client, options = {}) {
80
+ this.client = client;
81
+ this.options = options;
82
+ this.table = (0, client_js_1.quoteTable)(options.table ?? DEFAULT_TABLE);
83
+ }
84
+ async migrate(options = {}) {
85
+ const { applyPostgresMigrations } = await Promise.resolve().then(() => __importStar(require('./migrations.js')));
86
+ return applyPostgresMigrations(this.client, rollupStoreMigrations(this.options), options);
87
+ }
88
+ async add(key, totals) {
89
+ const t = this.table;
90
+ await this.client.query(`INSERT INTO ${t} (hour, kind, name, model, provider, tenant, runs, errors, cost, input_tokens, output_tokens, latency)
91
+ VALUES ($1, $2, $3, $4, $5, $6, $7::bigint, $8::bigint, $9::double precision, $10::bigint, $11::bigint, $12::bigint[])
92
+ ON CONFLICT (hour, kind, name, model, provider, tenant) DO UPDATE SET
93
+ runs = ${t}.runs + EXCLUDED.runs,
94
+ errors = ${t}.errors + EXCLUDED.errors,
95
+ cost = ${t}.cost + EXCLUDED.cost,
96
+ input_tokens = ${t}.input_tokens + EXCLUDED.input_tokens,
97
+ output_tokens = ${t}.output_tokens + EXCLUDED.output_tokens,
98
+ latency = ARRAY(
99
+ SELECT coalesce(stored, 0) + coalesce(added, 0)
100
+ FROM unnest(${t}.latency, EXCLUDED.latency) WITH ORDINALITY AS bucket(stored, added, position)
101
+ ORDER BY position
102
+ )`, [
103
+ key.hour,
104
+ key.kind,
105
+ key.name,
106
+ key.model,
107
+ key.provider,
108
+ key.tenant,
109
+ totals.runs,
110
+ totals.errors,
111
+ totals.cost,
112
+ totals.inputTokens,
113
+ totals.outputTokens,
114
+ `{${bucketsOf(totals.latency).join(',')}}`,
115
+ ]);
116
+ }
117
+ async query(query = {}) {
118
+ const params = new sql_js_1.SqlParams();
119
+ const where = [];
120
+ if (query.since)
121
+ where.push(`hour >= ${params.add(hourOf(query.since))}`);
122
+ if (query.until)
123
+ where.push(`hour <= ${params.add(query.until)}`);
124
+ if (query.kind !== undefined) {
125
+ const kinds = Array.isArray(query.kind) ? query.kind : [query.kind];
126
+ where.push(kinds.length ? `kind IN (${kinds.map((kind) => params.add(kind)).join(', ')})` : 'FALSE');
127
+ }
128
+ if (query.model !== undefined)
129
+ where.push(`model = ${params.add(query.model)}`);
130
+ if (query.provider !== undefined)
131
+ where.push(`provider = ${params.add(query.provider)}`);
132
+ if (query.tenant !== undefined)
133
+ where.push(`tenant = ${params.add(query.tenant)}`);
134
+ if (query.name !== undefined)
135
+ where.push(`name = ${params.add(query.name)}`);
136
+ const { rows } = await this.client.query(`SELECT hour, kind, name, model, provider, tenant, runs::text AS runs, errors::text AS errors, cost,
137
+ input_tokens::text AS input_tokens, output_tokens::text AS output_tokens, latency::text AS latency
138
+ FROM ${this.table}
139
+ ${where.length ? `WHERE ${where.join(' AND ')}` : ''}
140
+ ORDER BY hour, kind, name, model, provider, tenant`, params.values);
141
+ return rows.map((raw) => {
142
+ const row = raw;
143
+ return {
144
+ hour: String(row.hour),
145
+ kind: row.kind,
146
+ name: String(row.name),
147
+ model: String(row.model),
148
+ provider: String(row.provider),
149
+ tenant: String(row.tenant),
150
+ runs: Number(row.runs),
151
+ errors: Number(row.errors),
152
+ cost: Number(row.cost),
153
+ inputTokens: Number(row.input_tokens),
154
+ outputTokens: Number(row.output_tokens),
155
+ latency: String(row.latency).replace(/[{}]/g, '').split(',').filter(Boolean).map(Number),
156
+ };
157
+ });
158
+ }
159
+ }
160
+ exports.PostgresRollupStore = PostgresRollupStore;
161
+ function bucketsOf(latency) {
162
+ return Array.from({ length: rollups_js_1.ROLLUP_LATENCY_BOUNDS_MS.length + 1 }, (_, index) => Math.round(latency[index] ?? 0));
163
+ }
164
+ function hourOf(iso) {
165
+ const date = new Date(iso);
166
+ date.setUTCMinutes(0, 0, 0);
167
+ return date.toISOString();
168
+ }
@@ -1,5 +1,7 @@
1
1
  import type { Store, StoreIndexOptions, StoreItem, StoreNamespace, StorePutOptions, StoreSearchOptions } from '../types/store.js';
2
+ import type { MigrationResult, SchemaMigration } from '../utils/schema-migrations.js';
2
3
  import { type PostgresLikeClient } from './client.js';
4
+ import type { PostgresMigrateOptions } from './migrations.js';
3
5
  /** Options for the Postgres store. */
4
6
  export interface PostgresStoreOptions {
5
7
  /** Table name, optionally schema-qualified. Defaults to `nexus_store`. */
@@ -15,6 +17,10 @@ export interface PostgresStoreOptions {
15
17
  /** Replaces the system clock, for tests. */
16
18
  now?: () => Date;
17
19
  }
20
+ /**
21
+ * The versioned schema, which `migrate()` and `nexus db migrate` apply. Version 1 is the 2.0 schema.
22
+ */
23
+ export declare function storeMigrations(options?: Pick<PostgresStoreOptions, 'table' | 'vectorDimensions'>): SchemaMigration[];
18
24
  /** The schema, as statements. With `vectorDimensions`, pgvector's extension is created too. */
19
25
  export declare function storeMigration(options?: Pick<PostgresStoreOptions, 'table' | 'vectorDimensions'>): string[];
20
26
  /**
@@ -31,8 +37,11 @@ export declare class PostgresStore implements Store {
31
37
  private readonly table;
32
38
  private readonly now;
33
39
  constructor(client: PostgresLikeClient, options?: PostgresStoreOptions);
34
- /** Creates the table, indexes, and pgvector extension if configured. Never runs implicitly. */
35
- migrate(): Promise<void>;
40
+ /**
41
+ * Applies this store's pending migrations, recorded in `nexus_schema_migrations`, under a lock.
42
+ * Never runs implicitly. Safe on a database an older release created: what exists is kept.
43
+ */
44
+ migrate(options?: PostgresMigrateOptions): Promise<MigrationResult>;
36
45
  /** Stores an item, keeping its original `createdAt` when it replaces one. */
37
46
  put<V>(namespace: StoreNamespace, key: string, value: V, options?: StorePutOptions): Promise<void>;
38
47
  /** Reads an item, or `undefined` when it does not exist or has expired. */