@nylorun/runtime 0.14.0-beta → 0.15.0-beta
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.
- package/CHANGELOG.md +104 -0
- package/README.md +75 -33
- package/dist/adapters/execution/restate.js +2 -2
- package/dist/adapters/replication/pgoutput.d.ts +5 -0
- package/dist/adapters/replication/pgoutput.js +4 -3
- package/dist/admin-openapi.json +184 -685
- package/dist/api/components.d.ts +308 -68
- package/dist/api/components.js +4 -5
- package/dist/api/gate/keys.d.ts +14 -0
- package/dist/api/gate/keys.js +59 -0
- package/dist/api/gate/routes.d.ts +34 -0
- package/dist/api/gate/routes.js +235 -0
- package/dist/api/http/define.js +0 -8
- package/dist/api/http/routes/access.js +25 -18
- package/dist/api/http/routes/tenant.d.ts +2 -1
- package/dist/api/http/routes/tenant.js +77 -5
- package/dist/api/http/routes/vaults.js +2 -2
- package/dist/api/openapi.js +4 -5
- package/dist/gates/contract.d.ts +51 -0
- package/dist/gates/contract.js +37 -0
- package/dist/gates/handler.d.ts +21 -0
- package/dist/gates/handler.js +55 -0
- package/dist/gates/http-client.d.ts +12 -0
- package/dist/gates/http-client.js +160 -0
- package/dist/gates/in-process.d.ts +32 -0
- package/dist/gates/in-process.js +42 -0
- package/dist/gates/inflight.d.ts +39 -0
- package/dist/gates/inflight.js +70 -0
- package/dist/gates/mcp-handler.d.ts +35 -0
- package/dist/gates/mcp-handler.js +142 -0
- package/dist/gates/meter.d.ts +24 -0
- package/dist/gates/meter.js +165 -0
- package/dist/gates/model-gate.d.ts +45 -0
- package/dist/gates/model-gate.js +1 -0
- package/dist/gates/tenant-vaults.d.ts +64 -0
- package/dist/gates/tenant-vaults.js +94 -0
- package/dist/gates/tool-calls.d.ts +51 -0
- package/dist/gates/tool-calls.js +64 -0
- package/dist/gates/tool-client.d.ts +12 -0
- package/dist/gates/tool-client.js +201 -0
- package/dist/gates/tool-contract.d.ts +116 -0
- package/dist/gates/tool-contract.js +64 -0
- package/dist/gates/tool-gate.d.ts +45 -0
- package/dist/gates/tool-gate.js +10 -0
- package/dist/host/admin-api.d.ts +7 -6
- package/dist/host/admin-api.js +9 -113
- package/dist/host/app.d.ts +1 -1
- package/dist/host/app.js +20 -24
- package/dist/host/config-for.d.ts +1 -1
- package/dist/host/config-for.js +2 -2
- package/dist/host/create-host.d.ts +5 -5
- package/dist/host/create-host.js +5 -15
- package/dist/host/execution.d.ts +20 -18
- package/dist/host/execution.js +2 -2
- package/dist/host/gates.d.ts +58 -0
- package/dist/host/gates.js +127 -0
- package/dist/host/http.d.ts +6 -1
- package/dist/host/http.js +17 -0
- package/dist/host/index.d.ts +1 -1
- package/dist/host/main.js +151 -71
- package/dist/host/stack-config.d.ts +71 -19
- package/dist/host/stack-config.js +192 -18
- package/dist/infra/database.d.ts +2 -2
- package/dist/infra/execution.d.ts +5 -5
- package/dist/infra/execution.js +8 -6
- package/dist/infra/index.d.ts +1 -1
- package/dist/infra/workers.d.ts +17 -17
- package/dist/infra/workers.js +9 -9
- package/dist/keys/client.d.ts +9 -0
- package/dist/keys/client.js +70 -0
- package/dist/keys/contract.d.ts +24 -0
- package/dist/keys/contract.js +12 -0
- package/dist/keys/keys.d.ts +41 -0
- package/dist/keys/keys.js +50 -0
- package/dist/mcp/connect.d.ts +43 -3
- package/dist/mcp/connect.js +12 -5
- package/dist/mcp/pool.d.ts +21 -3
- package/dist/mcp/pool.js +15 -2
- package/dist/openapi.json +887 -694
- package/dist/record/append.d.ts +51 -0
- package/dist/record/append.js +20 -0
- package/dist/{store/event.js → record/envelope.js} +1 -1
- package/dist/record/index.d.ts +11 -0
- package/dist/record/index.js +11 -0
- package/dist/store/postgres/connect.d.ts +15 -12
- package/dist/store/postgres/connect.js +24 -12
- package/dist/store/postgres/db.d.ts +16 -0
- package/dist/store/postgres/db.js +28 -0
- package/dist/store/postgres/drizzle/0000_foundation.sql +22 -0
- package/dist/store/postgres/drizzle/0001_baseline.sql +255 -0
- package/dist/store/postgres/drizzle/0002_stream_relay.sql +4 -0
- package/dist/store/postgres/drizzle/0003_tool_crossings.sql +9 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +34 -0
- package/dist/store/postgres/migrate.d.ts +68 -0
- package/dist/store/postgres/migrate.js +183 -0
- package/dist/store/postgres/record-writer.d.ts +4 -0
- package/dist/store/postgres/record-writer.js +34 -0
- package/dist/store/postgres/record.d.ts +2 -8
- package/dist/store/postgres/record.js +50 -54
- package/dist/store/postgres/schema.d.ts +3096 -0
- package/dist/store/postgres/schema.js +363 -0
- package/dist/store/postgres/store.d.ts +2 -4
- package/dist/store/postgres/store.js +481 -567
- package/dist/store/postgres/tenant.d.ts +56 -0
- package/dist/store/postgres/tenant.js +154 -0
- package/dist/store/types.d.ts +43 -87
- package/dist/store/types.js +0 -1
- package/dist/streams/control.d.ts +1 -1
- package/dist/streams/control.js +6 -2
- package/dist/streams/relay/types.d.ts +2 -1
- package/dist/streams/relay/types.js +2 -1
- package/dist/streams/types.d.ts +5 -0
- package/dist/tenant/advance.d.ts +7 -2
- package/dist/tenant/advance.js +95 -16
- package/dist/tenant/cause.d.ts +25 -0
- package/dist/tenant/cause.js +45 -0
- package/dist/tenant/commands.js +4 -2
- package/dist/tenant/context.d.ts +26 -3
- package/dist/tenant/delivery-token.js +17 -18
- package/dist/tenant/delivery.d.ts +1 -1
- package/dist/tenant/delivery.js +18 -13
- package/dist/tenant/effects.d.ts +15 -1
- package/dist/tenant/effects.js +93 -17
- package/dist/tenant/ephemeral.d.ts +16 -7
- package/dist/tenant/ephemeral.js +45 -111
- package/dist/tenant/history.d.ts +64 -0
- package/dist/tenant/history.js +120 -0
- package/dist/tenant/model-setting.d.ts +2 -2
- package/dist/tenant/module.d.ts +14 -28
- package/dist/tenant/module.js +131 -271
- package/dist/tenant/paths.d.ts +11 -16
- package/dist/tenant/paths.js +24 -68
- package/dist/tenant/pool.d.ts +1 -1
- package/dist/tenant/pool.js +1 -1
- package/dist/tenant/principals.d.ts +23 -11
- package/dist/tenant/principals.js +61 -49
- package/dist/tenant/runtime.d.ts +19 -1
- package/dist/tenant/runtime.js +40 -26
- package/dist/tenant/scheduler.d.ts +4 -2
- package/dist/tenant/scheduler.js +4 -4
- package/dist/tenant/session-streams.d.ts +2 -0
- package/dist/tenant/session-streams.js +8 -3
- package/dist/tenant/status.d.ts +3 -0
- package/dist/tenant/status.js +1 -1
- package/dist/tenant/store-pg.d.ts +9 -6
- package/dist/tenant/store-pg.js +60 -125
- package/dist/tenant/streams.d.ts +9 -25
- package/dist/tenant/streams.js +7 -22
- package/dist/tenant/tokens.js +16 -14
- package/dist/tenant/types.d.ts +41 -92
- package/dist/tenant/types.js +4 -15
- package/dist/tenant/worker.js +4 -4
- package/dist/vault/host-model.d.ts +31 -0
- package/dist/vault/host-model.js +57 -0
- package/dist/vault/service.d.ts +26 -15
- package/dist/vault/service.js +70 -109
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +9 -5
- package/dist/store/memory.d.ts +0 -69
- package/dist/store/memory.js +0 -810
- package/dist/store/postgres/migrations/001_initial.d.ts +0 -27
- package/dist/store/postgres/migrations/001_initial.js +0 -196
- package/dist/store/postgres/migrations/002_session_owner.d.ts +0 -6
- package/dist/store/postgres/migrations/002_session_owner.js +0 -13
- package/dist/store/postgres/migrations/003_subject_tokens.d.ts +0 -8
- package/dist/store/postgres/migrations/003_subject_tokens.js +0 -42
- package/dist/store/postgres/migrations/004_publishable_keys.d.ts +0 -6
- package/dist/store/postgres/migrations/004_publishable_keys.js +0 -18
- package/dist/store/postgres/migrations/005_action_endpoints.d.ts +0 -6
- package/dist/store/postgres/migrations/005_action_endpoints.js +0 -32
- package/dist/store/postgres/migrations/006_drop_executors.d.ts +0 -11
- package/dist/store/postgres/migrations/006_drop_executors.js +0 -32
- package/dist/store/postgres/migrations/007_event_time.d.ts +0 -7
- package/dist/store/postgres/migrations/007_event_time.js +0 -14
- package/dist/store/postgres/migrations/008_durable_streams.d.ts +0 -13
- package/dist/store/postgres/migrations/008_durable_streams.js +0 -35
- package/dist/store/postgres/migrations/index.d.ts +0 -53
- package/dist/store/postgres/migrations/index.js +0 -96
- package/dist/store/postgres/migrations/shared/index.d.ts +0 -31
- package/dist/store/postgres/migrations/shared/index.js +0 -92
- package/dist/store/postgres/names.d.ts +0 -11
- package/dist/store/postgres/names.js +0 -42
- package/dist/store/postgres/tenants.d.ts +0 -90
- package/dist/store/postgres/tenants.js +0 -228
- package/dist/streams/relay/memory.d.ts +0 -69
- package/dist/streams/relay/memory.js +0 -176
- package/dist/tenant/envelope.d.ts +0 -7
- package/dist/tenant/envelope.js +0 -22
- package/dist/tenant/quarantine-error.d.ts +0 -6
- package/dist/tenant/quarantine-error.js +0 -9
- package/dist/tenant/quarantine.d.ts +0 -27
- package/dist/tenant/quarantine.js +0 -72
- package/dist/tenant/store-memory.d.ts +0 -16
- package/dist/tenant/store-memory.js +0 -111
- /package/dist/{store → record}/cursor.d.ts +0 -0
- /package/dist/{store → record}/cursor.js +0 -0
- /package/dist/{store/event.d.ts → record/envelope.d.ts} +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The only write path into the record (Durable Streams §6, blueprint D27): the session's log
|
|
3
|
+
* head allocates the next sequence, the event is built on the envelope and checked against the
|
|
4
|
+
* catalog, and its row is written, both in the caller's transaction. The database holds one
|
|
5
|
+
* Tenant, so rows are keyed by session alone; the Tenant id is the caller's and goes into the
|
|
6
|
+
* envelope only. The caller holds the session row lock, which orders the session's appends,
|
|
7
|
+
* and passes the epoch it read under that lock.
|
|
8
|
+
*
|
|
9
|
+
* The two statements run through `RecordWriter`, which the store implements on its
|
|
10
|
+
* transaction (`store/postgres/record-writer.ts`): the database driver stays behind
|
|
11
|
+
* `store/postgres/` (session-store.md §3), and this module decides what is written.
|
|
12
|
+
*/
|
|
13
|
+
import type { EventPayload, EventType, LiveEvent, SessionEventOf } from "@nylorun/core/contracts";
|
|
14
|
+
/** The record's two statements, in the caller's transaction. */
|
|
15
|
+
export interface RecordWriter {
|
|
16
|
+
/**
|
|
17
|
+
* Advances the session's log head: the seq its next event takes, and the basin generation
|
|
18
|
+
* its events go to (a session's first event takes the Tenant's current one).
|
|
19
|
+
*/
|
|
20
|
+
advance(sessionId: string): Promise<{
|
|
21
|
+
seq: number;
|
|
22
|
+
generation: number;
|
|
23
|
+
}>;
|
|
24
|
+
/** Writes the event's row. */
|
|
25
|
+
insert(row: {
|
|
26
|
+
sessionId: string;
|
|
27
|
+
seq: number;
|
|
28
|
+
generation: number;
|
|
29
|
+
type: string;
|
|
30
|
+
body: LiveEvent;
|
|
31
|
+
}): Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
export interface AppendInput<T extends EventType> {
|
|
34
|
+
/** The database's one Tenant, for the envelope. */
|
|
35
|
+
tenantId: string;
|
|
36
|
+
sessionId: string;
|
|
37
|
+
turnId: string | null;
|
|
38
|
+
/** The session's ownership epoch, read under the caller's session row lock. */
|
|
39
|
+
epoch: number;
|
|
40
|
+
time: Date;
|
|
41
|
+
type: T;
|
|
42
|
+
payload: EventPayload<T>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Appends one event through `writer`. An event the catalog does not describe throws
|
|
46
|
+
* `InvalidEventError` before its row is written; the caller's transaction then rolls back.
|
|
47
|
+
*/
|
|
48
|
+
export declare function appendEvent<T extends EventType>(writer: RecordWriter, input: AppendInput<T>): Promise<{
|
|
49
|
+
event: SessionEventOf<T>;
|
|
50
|
+
generation: number;
|
|
51
|
+
}>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { buildEvent } from "./envelope.js";
|
|
2
|
+
/**
|
|
3
|
+
* Appends one event through `writer`. An event the catalog does not describe throws
|
|
4
|
+
* `InvalidEventError` before its row is written; the caller's transaction then rolls back.
|
|
5
|
+
*/
|
|
6
|
+
export async function appendEvent(writer, input) {
|
|
7
|
+
const { seq, generation } = await writer.advance(input.sessionId);
|
|
8
|
+
const event = buildEvent({
|
|
9
|
+
tenantId: input.tenantId,
|
|
10
|
+
sessionId: input.sessionId,
|
|
11
|
+
turnId: input.turnId,
|
|
12
|
+
seq,
|
|
13
|
+
epoch: input.epoch,
|
|
14
|
+
time: input.time,
|
|
15
|
+
type: input.type,
|
|
16
|
+
payload: input.payload,
|
|
17
|
+
});
|
|
18
|
+
await writer.insert({ sessionId: input.sessionId, seq, generation, type: input.type, body: event });
|
|
19
|
+
return { event, generation };
|
|
20
|
+
}
|
|
@@ -37,7 +37,7 @@ export function buildEvent(input) {
|
|
|
37
37
|
schemaVersion: entry.version,
|
|
38
38
|
source: { kind: entry.source, id: "runtime" },
|
|
39
39
|
evidence: "observed",
|
|
40
|
-
visibility: "public",
|
|
40
|
+
visibility: entry.visibility ?? "public",
|
|
41
41
|
retention: "full",
|
|
42
42
|
type,
|
|
43
43
|
payload: input.payload,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The record module (blueprint D27): the one write path into the record. It builds each event
|
|
3
|
+
* on the `nylorun.event/2` envelope, checks it against the event catalog, and holds the only
|
|
4
|
+
* insert into `session_events` and `session_log_heads`, whose Postgres statements it runs
|
|
5
|
+
* through the store's `RecordWriter` (`store/postgres/record-writer.ts`;
|
|
6
|
+
* `scripts/check-boundaries.mjs` refuses an insert anywhere else). Other folders import this
|
|
7
|
+
* file, never the module's own files.
|
|
8
|
+
*/
|
|
9
|
+
export { buildEvent, InvalidEventError, type EventInput } from "./envelope.js";
|
|
10
|
+
export { decodeCursor, encodeCursor } from "./cursor.js";
|
|
11
|
+
export { appendEvent, type AppendInput, type RecordWriter } from "./append.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The record module (blueprint D27): the one write path into the record. It builds each event
|
|
3
|
+
* on the `nylorun.event/2` envelope, checks it against the event catalog, and holds the only
|
|
4
|
+
* insert into `session_events` and `session_log_heads`, whose Postgres statements it runs
|
|
5
|
+
* through the store's `RecordWriter` (`store/postgres/record-writer.ts`;
|
|
6
|
+
* `scripts/check-boundaries.mjs` refuses an insert anywhere else). Other folders import this
|
|
7
|
+
* file, never the module's own files.
|
|
8
|
+
*/
|
|
9
|
+
export { buildEvent, InvalidEventError } from "./envelope.js";
|
|
10
|
+
export { decodeCursor, encodeCursor } from "./cursor.js";
|
|
11
|
+
export { appendEvent } from "./append.js";
|
|
@@ -11,7 +11,7 @@ export interface PostgresClientOptions {
|
|
|
11
11
|
applicationName?: string;
|
|
12
12
|
/**
|
|
13
13
|
* `statement_timeout`: a statement running or waiting for a lock longer fails. Default
|
|
14
|
-
* 60 s; 0 turns it off.
|
|
14
|
+
* 60 s; 0 turns it off. Migrations lift it (`lockMigrations` in `migrate.ts`).
|
|
15
15
|
*/
|
|
16
16
|
statementTimeoutMs?: number;
|
|
17
17
|
/**
|
|
@@ -21,18 +21,21 @@ export interface PostgresClientOptions {
|
|
|
21
21
|
idleInTransactionTimeoutMs?: number;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
* Opens a connection pool for Session
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
24
|
+
* Opens a connection pool on the Tenant's database, for its Session Store and the Tenant
|
|
25
|
+
* bootstrap (`tenant.ts`). Stores never end it, so the caller calls `client.end()` at
|
|
26
|
+
* shutdown. This module and its siblings are the only code that imports the Postgres driver
|
|
27
|
+
* and Drizzle (seam rule 3, `scripts/check-boundaries.mjs`); Drizzle runs on this pool
|
|
28
|
+
* (`db.ts`).
|
|
28
29
|
*
|
|
29
|
-
* Statements are
|
|
30
|
-
*
|
|
31
|
-
* named prepared statements would pile up on every pooled connection with the
|
|
32
|
-
* number of Tenants a Host serves. Unnamed statements still go in one round
|
|
33
|
-
* trip; the queries are simple enough that re-planning them costs little.
|
|
30
|
+
* Statements are prepared: one database holds one Tenant in fixed schemas, so every statement
|
|
31
|
+
* is the same for the whole pool (session-store.md §2).
|
|
34
32
|
*
|
|
35
|
-
* The pool
|
|
36
|
-
* a connection forever: both are bounded by default.
|
|
33
|
+
* The pool serves every request of the Host, so a statement or transaction that hangs must
|
|
34
|
+
* not hold a connection forever: both are bounded by default.
|
|
37
35
|
*/
|
|
38
36
|
export declare function createPostgresClient(url: string, options?: PostgresClientOptions): PostgresClient;
|
|
37
|
+
/**
|
|
38
|
+
* Throws, naming the setting, when Postgres cannot run the stream relay: logical decoding
|
|
39
|
+
* needs `wal_level = logical` (a restart) and a role allowed to replicate.
|
|
40
|
+
*/
|
|
41
|
+
export declare function assertLogicalReplication(sql: Sql): Promise<void>;
|
|
@@ -1,25 +1,22 @@
|
|
|
1
1
|
import postgres, {} from "postgres";
|
|
2
2
|
/**
|
|
3
|
-
* Opens a connection pool for Session
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* Opens a connection pool on the Tenant's database, for its Session Store and the Tenant
|
|
4
|
+
* bootstrap (`tenant.ts`). Stores never end it, so the caller calls `client.end()` at
|
|
5
|
+
* shutdown. This module and its siblings are the only code that imports the Postgres driver
|
|
6
|
+
* and Drizzle (seam rule 3, `scripts/check-boundaries.mjs`); Drizzle runs on this pool
|
|
7
|
+
* (`db.ts`).
|
|
7
8
|
*
|
|
8
|
-
* Statements are
|
|
9
|
-
*
|
|
10
|
-
* named prepared statements would pile up on every pooled connection with the
|
|
11
|
-
* number of Tenants a Host serves. Unnamed statements still go in one round
|
|
12
|
-
* trip; the queries are simple enough that re-planning them costs little.
|
|
9
|
+
* Statements are prepared: one database holds one Tenant in fixed schemas, so every statement
|
|
10
|
+
* is the same for the whole pool (session-store.md §2).
|
|
13
11
|
*
|
|
14
|
-
* The pool
|
|
15
|
-
* a connection forever: both are bounded by default.
|
|
12
|
+
* The pool serves every request of the Host, so a statement or transaction that hangs must
|
|
13
|
+
* not hold a connection forever: both are bounded by default.
|
|
16
14
|
*/
|
|
17
15
|
export function createPostgresClient(url, options = {}) {
|
|
18
16
|
return postgres(url, {
|
|
19
17
|
max: options.max ?? 10,
|
|
20
18
|
idle_timeout: options.idleTimeoutSeconds ?? 30,
|
|
21
19
|
connect_timeout: options.connectTimeoutSeconds ?? 10,
|
|
22
|
-
prepare: false,
|
|
23
20
|
onnotice: () => { },
|
|
24
21
|
connection: {
|
|
25
22
|
application_name: options.applicationName ?? "nylorun-runtime",
|
|
@@ -28,3 +25,18 @@ export function createPostgresClient(url, options = {}) {
|
|
|
28
25
|
},
|
|
29
26
|
});
|
|
30
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Throws, naming the setting, when Postgres cannot run the stream relay: logical decoding
|
|
30
|
+
* needs `wal_level = logical` (a restart) and a role allowed to replicate.
|
|
31
|
+
*/
|
|
32
|
+
export async function assertLogicalReplication(sql) {
|
|
33
|
+
const [row] = await sql `
|
|
34
|
+
SELECT current_setting('wal_level') AS wal_level,
|
|
35
|
+
(SELECT rolreplication OR rolsuper FROM pg_roles WHERE rolname = current_user) AS replicates`;
|
|
36
|
+
if (row?.wal_level !== "logical")
|
|
37
|
+
throw new Error(`Postgres has wal_level = ${row?.wal_level ?? "unknown"}; the stream relay needs logical replication. ` +
|
|
38
|
+
"Set wal_level = logical and restart Postgres (`nylorun start` does this for the local stack; " +
|
|
39
|
+
"on a managed Postgres, turn on its logical replication option). See DEPLOYMENT.md.");
|
|
40
|
+
if (!row.replicates)
|
|
41
|
+
throw new Error("The Runtime's Postgres role cannot replicate: grant it REPLICATION (ALTER ROLE … REPLICATION). See DEPLOYMENT.md.");
|
|
42
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type PostgresJsDatabase, type PostgresJsQueryResultHKT } from "drizzle-orm/postgres-js";
|
|
2
|
+
import type { PgDatabase } from "drizzle-orm/pg-core";
|
|
3
|
+
import type { Sql } from "postgres";
|
|
4
|
+
export type Database = PostgresJsDatabase<Record<string, never>>;
|
|
5
|
+
/** A database or one of its transactions: anything a query can run on. */
|
|
6
|
+
export type Queryable = PgDatabase<PostgresJsQueryResultHKT, Record<string, never>>;
|
|
7
|
+
/** A transaction of `Database` (`db.transaction`). */
|
|
8
|
+
export type Transaction = Parameters<Parameters<Database["transaction"]>[0]>[0];
|
|
9
|
+
/** The Drizzle database on `sql`. */
|
|
10
|
+
export declare function database(sql: Sql): Database;
|
|
11
|
+
/**
|
|
12
|
+
* The driver's error behind a Drizzle query error. Drizzle wraps every failed query in a
|
|
13
|
+
* `DrizzleQueryError` whose message holds the query and its parameters (secrets among them);
|
|
14
|
+
* the store surfaces the postgres.js error with its SQLSTATE `code`, as callers expect.
|
|
15
|
+
*/
|
|
16
|
+
export declare function driverError(error: unknown): unknown;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drizzle on the Tenant database's pool (session-store.md §3): `drizzle-orm/postgres-js` over
|
|
3
|
+
* the postgres.js pool `connect.ts` opens, with the snake_case column names `schema.ts`
|
|
4
|
+
* defines. One Drizzle instance per pool.
|
|
5
|
+
*
|
|
6
|
+
* Drizzle hands timestamps to its own column types: on the pool it is given, postgres.js stops
|
|
7
|
+
* parsing date and time values, so a raw query on that pool reads a `timestamptz` as text.
|
|
8
|
+
*/
|
|
9
|
+
import { DrizzleQueryError } from "drizzle-orm";
|
|
10
|
+
import { drizzle, } from "drizzle-orm/postgres-js";
|
|
11
|
+
const databases = new WeakMap();
|
|
12
|
+
/** The Drizzle database on `sql`. */
|
|
13
|
+
export function database(sql) {
|
|
14
|
+
let db = databases.get(sql);
|
|
15
|
+
if (!db) {
|
|
16
|
+
db = drizzle({ client: sql, casing: "snake_case" });
|
|
17
|
+
databases.set(sql, db);
|
|
18
|
+
}
|
|
19
|
+
return db;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The driver's error behind a Drizzle query error. Drizzle wraps every failed query in a
|
|
23
|
+
* `DrizzleQueryError` whose message holds the query and its parameters (secrets among them);
|
|
24
|
+
* the store surfaces the postgres.js error with its SQLSTATE `code`, as callers expect.
|
|
25
|
+
*/
|
|
26
|
+
export function driverError(error) {
|
|
27
|
+
return error instanceof DrizzleQueryError && error.cause !== undefined ? error.cause : error;
|
|
28
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- Custom SQL (drizzle-kit does not model it): the two schemas and `nylorun.doc(body)`, which
|
|
2
|
+
-- the generated columns of the baseline (0001) read. Its snapshot declares the schemas, so
|
|
3
|
+
-- the baseline does not create them again.
|
|
4
|
+
--
|
|
5
|
+
-- doc(body) casts a `json` body to `jsonb` for the generated columns. `jsonb` rejects the
|
|
6
|
+
-- escapes \u0000 and unpaired surrogates, which `json` keeps verbatim: they are replaced with
|
|
7
|
+
-- \ufffd first (the stored body is untouched). A body with no \u escape takes the plain cast.
|
|
8
|
+
CREATE SCHEMA IF NOT EXISTS nylorun;
|
|
9
|
+
--> statement-breakpoint
|
|
10
|
+
CREATE SCHEMA nylorun_streams;
|
|
11
|
+
--> statement-breakpoint
|
|
12
|
+
CREATE FUNCTION nylorun.doc(body json) RETURNS jsonb
|
|
13
|
+
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE AS $$
|
|
14
|
+
SELECT CASE WHEN strpos(body::text, '\u') = 0 THEN body::jsonb
|
|
15
|
+
ELSE regexp_replace(
|
|
16
|
+
body::text,
|
|
17
|
+
'(?<!\\)((?:\\\\)*)\\u(0000|[dD][89a-fA-F][0-9a-fA-F]{2})',
|
|
18
|
+
'\1\\ufffd',
|
|
19
|
+
'g'
|
|
20
|
+
)::jsonb
|
|
21
|
+
END
|
|
22
|
+
$$;
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
CREATE TABLE "nylorun"."actions" (
|
|
2
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
3
|
+
"body" json NOT NULL,
|
|
4
|
+
"session_id" text GENERATED ALWAYS AS (nylorun.doc(body)->>'sessionId') STORED,
|
|
5
|
+
"turn_id" text GENERATED ALWAYS AS (nylorun.doc(body)->>'turnId') STORED,
|
|
6
|
+
"agent_id" text GENERATED ALWAYS AS (nylorun.doc(body)->>'agentId') STORED,
|
|
7
|
+
"status" text GENERATED ALWAYS AS (nylorun.doc(body)->>'status') STORED,
|
|
8
|
+
"kind" text GENERATED ALWAYS AS (nylorun.doc(body)->>'kind') STORED,
|
|
9
|
+
"deadline_at" text GENERATED ALWAYS AS (nylorun.doc(body)->>'deadlineAt') STORED
|
|
10
|
+
);
|
|
11
|
+
--> statement-breakpoint
|
|
12
|
+
CREATE TABLE "nylorun"."commands" (
|
|
13
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
14
|
+
"body" json NOT NULL
|
|
15
|
+
);
|
|
16
|
+
--> statement-breakpoint
|
|
17
|
+
CREATE TABLE "nylorun"."definitions" (
|
|
18
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
19
|
+
"body" json NOT NULL
|
|
20
|
+
);
|
|
21
|
+
--> statement-breakpoint
|
|
22
|
+
CREATE TABLE "nylorun"."effects" (
|
|
23
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
24
|
+
"body" json NOT NULL,
|
|
25
|
+
"session_id" text GENERATED ALWAYS AS (nylorun.doc(body)->'request'->>'sessionId') STORED,
|
|
26
|
+
"turn_id" text GENERATED ALWAYS AS (nylorun.doc(body)->'request'->>'turnId') STORED,
|
|
27
|
+
"kind" text GENERATED ALWAYS AS (nylorun.doc(body)->'request'->>'kind') STORED,
|
|
28
|
+
"status" text GENERATED ALWAYS AS (nylorun.doc(body)->>'status') STORED
|
|
29
|
+
);
|
|
30
|
+
--> statement-breakpoint
|
|
31
|
+
CREATE TABLE "nylorun"."endpoints" (
|
|
32
|
+
"agent_id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
33
|
+
"url" text NOT NULL,
|
|
34
|
+
"implementation_version" text NOT NULL,
|
|
35
|
+
"manifest_hash" text,
|
|
36
|
+
"timeout_ms" integer NOT NULL,
|
|
37
|
+
"max_concurrent" integer NOT NULL,
|
|
38
|
+
"principal_id" text,
|
|
39
|
+
"last_delivery_at" text,
|
|
40
|
+
"last_success_at" text,
|
|
41
|
+
"last_error_code" text,
|
|
42
|
+
"last_error_message" text,
|
|
43
|
+
"consecutive_failures" integer DEFAULT 0 NOT NULL,
|
|
44
|
+
"served_implementation_version" text,
|
|
45
|
+
"served_manifest_hash" text,
|
|
46
|
+
"created_at" text NOT NULL,
|
|
47
|
+
"updated_at" text NOT NULL
|
|
48
|
+
);
|
|
49
|
+
--> statement-breakpoint
|
|
50
|
+
CREATE TABLE "nylorun"."links" (
|
|
51
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
52
|
+
"body" json NOT NULL,
|
|
53
|
+
"workflow_session_id" text GENERATED ALWAYS AS (nylorun.doc(body)->>'workflowSessionId') STORED
|
|
54
|
+
);
|
|
55
|
+
--> statement-breakpoint
|
|
56
|
+
CREATE TABLE "nylorun"."model_budgets" (
|
|
57
|
+
"scope" text NOT NULL,
|
|
58
|
+
"scope_id" text COLLATE "C" NOT NULL,
|
|
59
|
+
"period" text,
|
|
60
|
+
"limit_usd" double precision,
|
|
61
|
+
"limit_tokens" bigint,
|
|
62
|
+
"updated_at" text NOT NULL,
|
|
63
|
+
CONSTRAINT "model_budgets_pkey" PRIMARY KEY("scope","scope_id")
|
|
64
|
+
);
|
|
65
|
+
--> statement-breakpoint
|
|
66
|
+
CREATE TABLE "nylorun"."model_usage" (
|
|
67
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
68
|
+
"effect_key" text COLLATE "C" NOT NULL,
|
|
69
|
+
"session_id" text COLLATE "C" NOT NULL,
|
|
70
|
+
"turn_id" text COLLATE "C" NOT NULL,
|
|
71
|
+
"agent_id" text COLLATE "C" NOT NULL,
|
|
72
|
+
"provider" text,
|
|
73
|
+
"model" text,
|
|
74
|
+
"input_tokens" integer NOT NULL,
|
|
75
|
+
"output_tokens" integer NOT NULL,
|
|
76
|
+
"total_tokens" integer NOT NULL,
|
|
77
|
+
"cached_tokens" integer NOT NULL,
|
|
78
|
+
"cache_write_tokens" integer NOT NULL,
|
|
79
|
+
"reasoning_tokens" integer NOT NULL,
|
|
80
|
+
"cost_usd" double precision NOT NULL,
|
|
81
|
+
"duplicate" boolean NOT NULL,
|
|
82
|
+
"created_at" text NOT NULL
|
|
83
|
+
);
|
|
84
|
+
--> statement-breakpoint
|
|
85
|
+
CREATE TABLE "nylorun"."principals" (
|
|
86
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
87
|
+
"role" text NOT NULL,
|
|
88
|
+
"token_hash" text NOT NULL,
|
|
89
|
+
"idempotency_key" text,
|
|
90
|
+
"created_at" text NOT NULL,
|
|
91
|
+
CONSTRAINT "principals_token_hash_key" UNIQUE("token_hash")
|
|
92
|
+
);
|
|
93
|
+
--> statement-breakpoint
|
|
94
|
+
CREATE TABLE "nylorun"."publishable_keys" (
|
|
95
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
96
|
+
"key" text COLLATE "C" NOT NULL,
|
|
97
|
+
"name" text NOT NULL,
|
|
98
|
+
"origins_json" text NOT NULL,
|
|
99
|
+
"created_at" text NOT NULL,
|
|
100
|
+
"revoked_at" text,
|
|
101
|
+
CONSTRAINT "publishable_keys_key_key" UNIQUE("key"),
|
|
102
|
+
CONSTRAINT "publishable_keys_name_key" UNIQUE("name")
|
|
103
|
+
);
|
|
104
|
+
--> statement-breakpoint
|
|
105
|
+
CREATE TABLE "nylorun_streams"."relay_slots" (
|
|
106
|
+
"slot_name" text PRIMARY KEY NOT NULL,
|
|
107
|
+
"reconcile_pending" boolean NOT NULL
|
|
108
|
+
);
|
|
109
|
+
--> statement-breakpoint
|
|
110
|
+
CREATE TABLE "nylorun"."sandboxes" (
|
|
111
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
112
|
+
"body" json NOT NULL
|
|
113
|
+
);
|
|
114
|
+
--> statement-breakpoint
|
|
115
|
+
CREATE TABLE "nylorun_streams"."session_events" (
|
|
116
|
+
"session_id" text COLLATE "C" NOT NULL,
|
|
117
|
+
"seq" bigint NOT NULL,
|
|
118
|
+
"generation" integer NOT NULL,
|
|
119
|
+
"type" text NOT NULL,
|
|
120
|
+
"body" json NOT NULL,
|
|
121
|
+
"committed_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
122
|
+
CONSTRAINT "session_events_pkey" PRIMARY KEY("session_id","seq")
|
|
123
|
+
);
|
|
124
|
+
--> statement-breakpoint
|
|
125
|
+
CREATE TABLE "nylorun_streams"."session_log_heads" (
|
|
126
|
+
"session_id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
127
|
+
"generation" integer NOT NULL,
|
|
128
|
+
"head" bigint DEFAULT 0 NOT NULL
|
|
129
|
+
);
|
|
130
|
+
--> statement-breakpoint
|
|
131
|
+
CREATE TABLE "nylorun"."sessions" (
|
|
132
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
133
|
+
"body" json NOT NULL,
|
|
134
|
+
"status" text GENERATED ALWAYS AS (nylorun.doc(body)->>'status') STORED,
|
|
135
|
+
"agent_id" text GENERATED ALWAYS AS (nylorun.doc(body)->>'agentId') STORED,
|
|
136
|
+
"owner" text,
|
|
137
|
+
"epoch" bigint DEFAULT 0 NOT NULL,
|
|
138
|
+
"owner_expires_at" timestamp with time zone,
|
|
139
|
+
"owner_user_id" text GENERATED ALWAYS AS (nylorun.doc(body)->>'ownerUserId') STORED
|
|
140
|
+
);
|
|
141
|
+
--> statement-breakpoint
|
|
142
|
+
CREATE TABLE "nylorun"."signing_keys" (
|
|
143
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
144
|
+
"state" text NOT NULL,
|
|
145
|
+
"alg" text NOT NULL,
|
|
146
|
+
"public_jwk" text NOT NULL,
|
|
147
|
+
"kek_id" text NOT NULL,
|
|
148
|
+
"nonce" "bytea" NOT NULL,
|
|
149
|
+
"ciphertext" "bytea" NOT NULL,
|
|
150
|
+
"wrapped_dek" "bytea" NOT NULL,
|
|
151
|
+
"created_at" text NOT NULL,
|
|
152
|
+
"activated_at" text,
|
|
153
|
+
"retired_at" text,
|
|
154
|
+
"revoked_at" text,
|
|
155
|
+
CONSTRAINT "signing_keys_state_check" CHECK (state IN ('standby', 'current', 'previous', 'revoked')),
|
|
156
|
+
CONSTRAINT "signing_keys_alg_check" CHECK (alg = 'ES256')
|
|
157
|
+
);
|
|
158
|
+
--> statement-breakpoint
|
|
159
|
+
CREATE TABLE "nylorun"."subject_epochs" (
|
|
160
|
+
"subject" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
161
|
+
"epoch" bigint NOT NULL,
|
|
162
|
+
"revoked_at" text NOT NULL
|
|
163
|
+
);
|
|
164
|
+
--> statement-breakpoint
|
|
165
|
+
CREATE TABLE "nylorun"."subject_usage" (
|
|
166
|
+
"subject" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
167
|
+
"turn_tokens" double precision NOT NULL,
|
|
168
|
+
"refilled_at" text NOT NULL
|
|
169
|
+
);
|
|
170
|
+
--> statement-breakpoint
|
|
171
|
+
CREATE TABLE "nylorun"."tenant" (
|
|
172
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
173
|
+
"name" text NOT NULL,
|
|
174
|
+
"created_at" text NOT NULL,
|
|
175
|
+
"updated_at" text NOT NULL,
|
|
176
|
+
"schema_version" integer NOT NULL,
|
|
177
|
+
"singleton" boolean DEFAULT true NOT NULL,
|
|
178
|
+
"basin_generation" integer DEFAULT 0 NOT NULL,
|
|
179
|
+
"retired_generations" integer[] DEFAULT '{}' NOT NULL,
|
|
180
|
+
CONSTRAINT "tenant_singleton_key" UNIQUE("singleton"),
|
|
181
|
+
CONSTRAINT "tenant_singleton_check" CHECK (singleton)
|
|
182
|
+
);
|
|
183
|
+
--> statement-breakpoint
|
|
184
|
+
CREATE TABLE "nylorun"."tenant_settings" (
|
|
185
|
+
"key" text PRIMARY KEY NOT NULL,
|
|
186
|
+
"value" text NOT NULL
|
|
187
|
+
);
|
|
188
|
+
--> statement-breakpoint
|
|
189
|
+
CREATE TABLE "nylorun"."vault_audit" (
|
|
190
|
+
"ord" bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "nylorun"."vault_audit_ord_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1),
|
|
191
|
+
"id" text NOT NULL,
|
|
192
|
+
"at" text NOT NULL,
|
|
193
|
+
"actor" text NOT NULL,
|
|
194
|
+
"action" text NOT NULL,
|
|
195
|
+
"vault_id" text,
|
|
196
|
+
"credential_id" text,
|
|
197
|
+
"session_id" text,
|
|
198
|
+
"target" text,
|
|
199
|
+
"outcome" text NOT NULL,
|
|
200
|
+
CONSTRAINT "vault_audit_id_key" UNIQUE("id")
|
|
201
|
+
);
|
|
202
|
+
--> statement-breakpoint
|
|
203
|
+
CREATE TABLE "nylorun"."vault_credentials" (
|
|
204
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
205
|
+
"vault_id" text NOT NULL,
|
|
206
|
+
"name" text NOT NULL,
|
|
207
|
+
"type" text NOT NULL,
|
|
208
|
+
"binding_json" text NOT NULL,
|
|
209
|
+
"expires_at" text,
|
|
210
|
+
"created_at" text COLLATE "C" NOT NULL,
|
|
211
|
+
"rotated_at" text,
|
|
212
|
+
"kek_id" text NOT NULL,
|
|
213
|
+
"nonce" "bytea" NOT NULL,
|
|
214
|
+
"ciphertext" "bytea" NOT NULL,
|
|
215
|
+
"wrapped_dek" "bytea" NOT NULL
|
|
216
|
+
);
|
|
217
|
+
--> statement-breakpoint
|
|
218
|
+
CREATE TABLE "nylorun"."vault_idempotency" (
|
|
219
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
220
|
+
"body_hash" text NOT NULL,
|
|
221
|
+
"response" text NOT NULL
|
|
222
|
+
);
|
|
223
|
+
--> statement-breakpoint
|
|
224
|
+
CREATE TABLE "nylorun"."vaults" (
|
|
225
|
+
"id" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
226
|
+
"name" text NOT NULL,
|
|
227
|
+
"owner_user_id" text NOT NULL,
|
|
228
|
+
"metadata_json" text,
|
|
229
|
+
"created_at" text COLLATE "C" NOT NULL,
|
|
230
|
+
"scope" text DEFAULT 'user' NOT NULL,
|
|
231
|
+
CONSTRAINT "vaults_scope_check" CHECK (scope IN ('user', 'host'))
|
|
232
|
+
);
|
|
233
|
+
--> statement-breakpoint
|
|
234
|
+
ALTER TABLE "nylorun"."vault_credentials" ADD CONSTRAINT "vault_credentials_vault_id_fkey" FOREIGN KEY ("vault_id") REFERENCES "nylorun"."vaults"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
235
|
+
CREATE INDEX "actions_session" ON "nylorun"."actions" USING btree ("session_id","turn_id","status");--> statement-breakpoint
|
|
236
|
+
CREATE INDEX "actions_agent" ON "nylorun"."actions" USING btree ("agent_id","status");--> statement-breakpoint
|
|
237
|
+
CREATE INDEX "actions_status" ON "nylorun"."actions" USING btree ("status","kind");--> statement-breakpoint
|
|
238
|
+
CREATE INDEX "actions_deadline" ON "nylorun"."actions" USING btree ("status","deadline_at");--> statement-breakpoint
|
|
239
|
+
CREATE INDEX "effects_session" ON "nylorun"."effects" USING btree ("session_id","turn_id","status");--> statement-breakpoint
|
|
240
|
+
CREATE INDEX "effects_status" ON "nylorun"."effects" USING btree ("status","kind");--> statement-breakpoint
|
|
241
|
+
CREATE INDEX "links_workflow" ON "nylorun"."links" USING btree ("workflow_session_id");--> statement-breakpoint
|
|
242
|
+
CREATE INDEX "model_usage_effect" ON "nylorun"."model_usage" USING btree ("effect_key");--> statement-breakpoint
|
|
243
|
+
CREATE INDEX "model_usage_agent" ON "nylorun"."model_usage" USING btree ("agent_id","created_at");--> statement-breakpoint
|
|
244
|
+
CREATE INDEX "model_usage_turn" ON "nylorun"."model_usage" USING btree ("turn_id");--> statement-breakpoint
|
|
245
|
+
CREATE INDEX "model_usage_created" ON "nylorun"."model_usage" USING btree ("created_at");--> statement-breakpoint
|
|
246
|
+
CREATE INDEX "sessions_status" ON "nylorun"."sessions" USING btree ("status","owner_expires_at");--> statement-breakpoint
|
|
247
|
+
CREATE INDEX "sessions_agent" ON "nylorun"."sessions" USING btree ("agent_id");--> statement-breakpoint
|
|
248
|
+
CREATE INDEX "sessions_owner_user" ON "nylorun"."sessions" USING btree ("owner_user_id");--> statement-breakpoint
|
|
249
|
+
CREATE UNIQUE INDEX "signing_keys_one_standby" ON "nylorun"."signing_keys" USING btree ("state") WHERE state = 'standby';--> statement-breakpoint
|
|
250
|
+
CREATE UNIQUE INDEX "signing_keys_one_current" ON "nylorun"."signing_keys" USING btree ("state") WHERE state = 'current';--> statement-breakpoint
|
|
251
|
+
CREATE UNIQUE INDEX "signing_keys_one_previous" ON "nylorun"."signing_keys" USING btree ("state") WHERE state = 'previous';--> statement-breakpoint
|
|
252
|
+
CREATE INDEX "vault_audit_vault" ON "nylorun"."vault_audit" USING btree ("vault_id","ord");--> statement-breakpoint
|
|
253
|
+
CREATE INDEX "vault_credentials_vault" ON "nylorun"."vault_credentials" USING btree ("vault_id","created_at","id");--> statement-breakpoint
|
|
254
|
+
CREATE INDEX "vaults_owner" ON "nylorun"."vaults" USING btree ("owner_user_id","created_at","id");--> statement-breakpoint
|
|
255
|
+
CREATE UNIQUE INDEX "vaults_one_host" ON "nylorun"."vaults" USING btree ("scope") WHERE scope = 'host';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
-- Custom SQL (drizzle-kit does not model publications): the publication the stream relay
|
|
2
|
+
-- subscribes to (Durable Streams §7). Only inserts: the record is append-only.
|
|
3
|
+
CREATE PUBLICATION nylorun_stream_relay
|
|
4
|
+
FOR TABLE nylorun_streams.session_events WITH (publish = 'insert');
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
CREATE TABLE "nylorun"."tool_crossings" (
|
|
2
|
+
"key" text COLLATE "C" PRIMARY KEY NOT NULL,
|
|
3
|
+
"hash" text NOT NULL,
|
|
4
|
+
"started_at" text COLLATE "C" NOT NULL,
|
|
5
|
+
"settled_at" text COLLATE "C",
|
|
6
|
+
"answer" json
|
|
7
|
+
);
|
|
8
|
+
--> statement-breakpoint
|
|
9
|
+
CREATE INDEX "tool_crossings_settled" ON "nylorun"."tool_crossings" USING btree ("settled_at");
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "7",
|
|
3
|
+
"dialect": "postgresql",
|
|
4
|
+
"entries": [
|
|
5
|
+
{
|
|
6
|
+
"idx": 0,
|
|
7
|
+
"version": "7",
|
|
8
|
+
"when": 1790943952307,
|
|
9
|
+
"tag": "0000_foundation",
|
|
10
|
+
"breakpoints": true
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"idx": 1,
|
|
14
|
+
"version": "7",
|
|
15
|
+
"when": 1790943980707,
|
|
16
|
+
"tag": "0001_baseline",
|
|
17
|
+
"breakpoints": true
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"idx": 2,
|
|
21
|
+
"version": "7",
|
|
22
|
+
"when": 1790943989041,
|
|
23
|
+
"tag": "0002_stream_relay",
|
|
24
|
+
"breakpoints": true
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"idx": 3,
|
|
28
|
+
"version": "7",
|
|
29
|
+
"when": 1790956444115,
|
|
30
|
+
"tag": "0003_tool_crossings",
|
|
31
|
+
"breakpoints": true
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Sql } from "postgres";
|
|
2
|
+
import { type Queryable, type Transaction } from "./db.js";
|
|
3
|
+
/** Where the migrations are, next to this module (`src/` in development, `dist/` built). */
|
|
4
|
+
export declare const MIGRATIONS_FOLDER: string;
|
|
5
|
+
/** The journal of applied migrations: `nylorun.__drizzle_migrations`. */
|
|
6
|
+
export declare const MIGRATIONS_SCHEMA = "nylorun";
|
|
7
|
+
export declare const MIGRATIONS_TABLE = "__drizzle_migrations";
|
|
8
|
+
/**
|
|
9
|
+
* What schemas were called when one database held several Tenants (`"tenant_<id>"`). A
|
|
10
|
+
* database that still has one was written by an older Runtime and is refused.
|
|
11
|
+
*/
|
|
12
|
+
export declare const OLD_TENANT_SCHEMA_PREFIX = "tenant_";
|
|
13
|
+
export interface Migration {
|
|
14
|
+
/** The journal tag, `0001_baseline`. */
|
|
15
|
+
tag: string;
|
|
16
|
+
/** SHA-256 of the SQL file, as Drizzle records it. */
|
|
17
|
+
hash: string;
|
|
18
|
+
/** The journal's `when` (ms), recorded as `created_at`. */
|
|
19
|
+
when: number;
|
|
20
|
+
/** The file's statements, split at `--> statement-breakpoint`. */
|
|
21
|
+
statements: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
/** The migrations this Runtime ships, in order. */
|
|
24
|
+
export declare function shippedMigrations(): readonly Migration[];
|
|
25
|
+
/** The schema version this Runtime writes and expects: the number of shipped migrations. */
|
|
26
|
+
export declare function expectedSchemaVersion(): number;
|
|
27
|
+
/**
|
|
28
|
+
* Lifts `statement_timeout` for the transaction and takes the database's migration lock
|
|
29
|
+
* until it ends. Waiting for the lock, and the migrations done under it, may outlast the
|
|
30
|
+
* pool's statement timeout; a migration that timed out would fail the Host's readiness.
|
|
31
|
+
*/
|
|
32
|
+
export declare function lockMigrations(tx: Transaction): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Throws `database-layout-old` when the database was written by an older Runtime: one that
|
|
35
|
+
* kept several Tenants in one database (`tenant_<id>` schemas, a record keyed by Tenant), or a
|
|
36
|
+
* pre-release build of one Tenant per database whose hand-written migrations recorded
|
|
37
|
+
* themselves in `schema_version` tables.
|
|
38
|
+
*/
|
|
39
|
+
export declare function assertCurrentLayout(q: Queryable): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* The database's schema version: the number of migrations its journal records, or undefined
|
|
42
|
+
* when it has no journal (a database never migrated).
|
|
43
|
+
*/
|
|
44
|
+
export declare function readSchemaVersion(q: Queryable): Promise<number | undefined>;
|
|
45
|
+
/**
|
|
46
|
+
* Applies every migration of `migrations` the journal does not record, in `tx`. Take
|
|
47
|
+
* `lockMigrations` first (`migrateDatabase` does). Throws `schema-too-new` when the journal
|
|
48
|
+
* records a migration `migrations` does not have, and `migration-failed` when Postgres
|
|
49
|
+
* rejects a migration.
|
|
50
|
+
*/
|
|
51
|
+
export declare function applyMigrations(tx: Transaction, migrations?: readonly Migration[]): Promise<{
|
|
52
|
+
from: number;
|
|
53
|
+
to: number;
|
|
54
|
+
}>;
|
|
55
|
+
/**
|
|
56
|
+
* Refuses an old layout and applies the missing migrations, in one transaction under the
|
|
57
|
+
* migration lock. For tests and tools; the Host migrates through `openTenantDatabase`.
|
|
58
|
+
*/
|
|
59
|
+
export declare function migrateDatabase(pool: Sql, migrations?: readonly Migration[]): Promise<{
|
|
60
|
+
from: number;
|
|
61
|
+
to: number;
|
|
62
|
+
}>;
|
|
63
|
+
/**
|
|
64
|
+
* Whether Postgres rejected a statement (a SQLSTATE), rather than the connection or the
|
|
65
|
+
* server failing (classes 08, 53, 57, and the driver's own connection errors). Only the
|
|
66
|
+
* first says something about the Tenant's database.
|
|
67
|
+
*/
|
|
68
|
+
export declare function isStatementError(error: unknown): boolean;
|