@voltro/database 0.34.0 → 0.35.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.
- package/CHANGELOG.md +167 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +624 -620
- package/dist/sql.d.ts +155 -23
- package/dist/sql.js +690 -645
- package/package.json +2 -2
package/dist/sql.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { SqlError } from '@effect/sql';
|
|
|
7
7
|
import { SqlError as SqlError_2 } from '@effect/sql/SqlError';
|
|
8
8
|
import { Statement } from '@effect/sql';
|
|
9
9
|
|
|
10
|
-
export declare const acquireMigrationLock: (sql: SqlClient.SqlClient) => Effect.Effect<void, SqlError_2>;
|
|
10
|
+
export declare const acquireMigrationLock: (sql: SqlClient.SqlClient, scope?: MigrationLockScope) => Effect.Effect<void, SqlError_2>;
|
|
11
11
|
|
|
12
12
|
declare interface AggregateColumn<TResult = number | Date | null> {
|
|
13
13
|
readonly op: 'count' | 'sum' | 'avg' | 'min' | 'max' | 'count-distinct' | 'window-row-number' | 'window-rank' | 'window-dense-rank' | 'window-lag' | 'window-lead' | 'window-sum-over' | 'window-avg-over' | 'column';
|
|
@@ -58,6 +58,14 @@ declare type AnyTable = Table<string, Record<string, ColumnDefinition<unknown>>,
|
|
|
58
58
|
|
|
59
59
|
declare type AnyView = View<string, Record<string, ColumnDefinition<unknown>>>;
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* The dialect-correct value for an `appliedAt` column, given an ISO instant.
|
|
63
|
+
*
|
|
64
|
+
* MySQL-family: UTC wall clock, `YYYY-MM-DD HH:MM:SS.fff`.
|
|
65
|
+
* Everything else: the ISO string, offset included.
|
|
66
|
+
*/
|
|
67
|
+
export declare const appliedAtValue: (sql: SqlClient.SqlClient, iso: string) => Effect.Effect<string>;
|
|
68
|
+
|
|
61
69
|
/**
|
|
62
70
|
* One row of `_voltro_migrations` — what the applier writes after a
|
|
63
71
|
* successful plan execution. Same shape exposed via inspect RPC for
|
|
@@ -106,7 +114,7 @@ export declare interface AppliedOp {
|
|
|
106
114
|
* no-op (except sqlite's ATTACH, which the splitter runs standalone and
|
|
107
115
|
* whose "already attached" error the caller can ignore).
|
|
108
116
|
*/
|
|
109
|
-
export declare const applyNamespacedSchema: (tables: ReadonlyArray<AnyTable>, namespace: string, dialect?: DialectId) => Effect.Effect<void, never, SqlClient.SqlClient>;
|
|
117
|
+
export declare const applyNamespacedSchema: (tables: ReadonlyArray<AnyTable>, namespace: string, dialect?: DialectId, options?: SchemaApplyOptions) => Effect.Effect<void, never, SqlClient.SqlClient>;
|
|
110
118
|
|
|
111
119
|
/**
|
|
112
120
|
* Execute a `MigrationPlan` against the connected database.
|
|
@@ -145,6 +153,15 @@ export declare interface ApplyPlanCtx {
|
|
|
145
153
|
readonly source: 'auto-diff' | 'file';
|
|
146
154
|
/** Optional human note via `voltro db apply --note "..."`. */
|
|
147
155
|
readonly notes?: string;
|
|
156
|
+
/**
|
|
157
|
+
* Schema scope for the migration advisory lock (see `migrations/lock.ts`).
|
|
158
|
+
* Absent → resolved from configuration (`DB_SCHEMA`), which is what every
|
|
159
|
+
* CLI path wants; explicit for programmatic callers whose schema does not
|
|
160
|
+
* come from the environment. Every taker of this lock must resolve the
|
|
161
|
+
* scope the same way, or two writers in one schema stop excluding each
|
|
162
|
+
* other — worse than the cluster-wide key this replaced.
|
|
163
|
+
*/
|
|
164
|
+
readonly lockSchema?: string;
|
|
148
165
|
/**
|
|
149
166
|
* Re-plan against the LIVE schema — the convergence proof.
|
|
150
167
|
*
|
|
@@ -172,23 +189,13 @@ export declare interface ApplyPlanCtx {
|
|
|
172
189
|
readonly replan: (sql: SqlClient.SqlClient) => Effect.Effect<MigrationPlan, SqlError_2, SqlClient.SqlClient>;
|
|
173
190
|
}
|
|
174
191
|
|
|
175
|
-
/**
|
|
176
|
-
* Effect that applies the emitted DDL to the provided SqlClient. Splits
|
|
177
|
-
* on `;` only outside dollar-quoted blocks (the postgres NOTIFY trigger
|
|
178
|
-
* function body uses `$$`), so the plpgsql block stays intact as a
|
|
179
|
-
* single statement. SQLite has no `$$` quoting so the splitter is a
|
|
180
|
-
* superset.
|
|
181
|
-
*
|
|
182
|
-
* Caller passes the dialect explicitly. Defaults to `'postgres'` for
|
|
183
|
-
* call-sites that haven't migrated yet.
|
|
184
|
-
*/
|
|
185
192
|
export declare const applySchema: (tables: ReadonlyArray<AnyTable>, dialect?: DialectId,
|
|
186
193
|
/** NOTIFY channel for the reactive triggers. Pass the SAME value the store
|
|
187
194
|
* was built with. They are two halves of one contract and used to be able to
|
|
188
195
|
* disagree silently: the store listened on its `cdcChannel` while the DDL
|
|
189
196
|
* always emitted on the default, so a custom channel received nothing and
|
|
190
197
|
* raised nothing. */
|
|
191
|
-
cdcChannel?: string) => Effect.Effect<void, never, SqlClient.SqlClient>;
|
|
198
|
+
cdcChannel?: string, options?: SchemaApplyOptions) => Effect.Effect<void, never, SqlClient.SqlClient>;
|
|
192
199
|
|
|
193
200
|
/**
|
|
194
201
|
* The OPT-IN refuse gate over the advisory. By default (`VOLTRO_ROLLING_DEPLOY`
|
|
@@ -1275,6 +1282,8 @@ export declare interface FileMigrationRunResult {
|
|
|
1275
1282
|
*/
|
|
1276
1283
|
export declare const fingerprintSchema: (snapshot: SchemaSnapshot) => string;
|
|
1277
1284
|
|
|
1285
|
+
export declare const fnv1a64: (input: string) => bigint;
|
|
1286
|
+
|
|
1278
1287
|
/** Human/PR-comment rendering. Markdown-free on purpose — the CI job that posts
|
|
1279
1288
|
* it to a PR wraps it, and a terminal reader gets the same text. */
|
|
1280
1289
|
export declare const formatBranchRehearsal: (report: BranchRehearsalReport) => string;
|
|
@@ -1450,6 +1459,20 @@ export declare const isFileMigration: (value: unknown) => value is FileMigration
|
|
|
1450
1459
|
/** Type guard — narrows an unknown value to a {@link RawSqlFragment}. */
|
|
1451
1460
|
export declare const isRawSqlFragment: (value: unknown) => value is RawSqlFragment;
|
|
1452
1461
|
|
|
1462
|
+
/**
|
|
1463
|
+
* True when re-RUNNING this exact statement is a no-op if the previous attempt
|
|
1464
|
+
* (or a sibling process) already applied it. This is what makes an IN-PLACE
|
|
1465
|
+
* statement retry sound on the per-operation dialects: the auto-migrate
|
|
1466
|
+
* emitter's DDL is `IF NOT EXISTS`-shaped almost everywhere, and mysql's one
|
|
1467
|
+
* exception (plain `CREATE INDEX` — the dialect cannot spell the conditional)
|
|
1468
|
+
* is tolerated by `isReRunnableDuplicateIndex` above, which is precisely the
|
|
1469
|
+
* re-run contract this predicate leans on. Anything else (sqlite `ATTACH`,
|
|
1470
|
+
* a bare `ADD CONSTRAINT`) is NOT a retry candidate: a half-applied non-
|
|
1471
|
+
* idempotent statement retried blindly turns a transient error into a
|
|
1472
|
+
* confusing permanent one.
|
|
1473
|
+
*/
|
|
1474
|
+
export declare const isReRunSafeDdl: (statement: string, dialect: DialectId) => boolean;
|
|
1475
|
+
|
|
1453
1476
|
/**
|
|
1454
1477
|
* A json-path index entry, produced by {@link jsonIndex}. Unlike a plain
|
|
1455
1478
|
* `{ expr }` (verbatim, dialect-specific) this carries the column + path
|
|
@@ -1497,6 +1520,40 @@ declare type MergeMixinFields<Mixins extends ReadonlyArray<AnyMixin>> = Mixins e
|
|
|
1497
1520
|
*/
|
|
1498
1521
|
export declare const migration: (spec: FileMigration) => FileMigration;
|
|
1499
1522
|
|
|
1523
|
+
/**
|
|
1524
|
+
* The postgres advisory-lock key for a schema. Default schema (undefined /
|
|
1525
|
+
* `'public'`) → the EXACT legacy constant (rolling-deploy pin, see above).
|
|
1526
|
+
* Otherwise FNV-1a 64 of `voltro_migration_lock:<schema>`, with the sign
|
|
1527
|
+
* bit cleared so the value is a positive signed 64-bit int (`pg_advisory_
|
|
1528
|
+
* lock(bigint)`). Collisions across schemas are possible and ACCEPTABLE —
|
|
1529
|
+
* a collision reintroduces serialization between two schemas, not a race.
|
|
1530
|
+
*/
|
|
1531
|
+
export declare const migrationLockKeyForSchema: (schema: string | undefined) => bigint;
|
|
1532
|
+
|
|
1533
|
+
/**
|
|
1534
|
+
* The mysql/mssql lock NAME for a schema. Default → the EXACT pre-1.5 name
|
|
1535
|
+
* (`voltro_migration_<key36>`). Otherwise the schema is suffixed; MySQL
|
|
1536
|
+
* caps `GET_LOCK` names at 64 chars, so a name that would overflow falls
|
|
1537
|
+
* back to a hashed suffix (`_h<fnv-1a-64 hex>`, 46 chars total) instead of
|
|
1538
|
+
* a server error. Note mysql's `GET_LOCK` scope is the SERVER: on
|
|
1539
|
+
* mysql/mariadb `DB_SCHEMA` is not a connection pin (the database comes
|
|
1540
|
+
* from the URL), but setting it to the database name is how two apps on
|
|
1541
|
+
* one server un-share this lock.
|
|
1542
|
+
*/
|
|
1543
|
+
export declare const migrationLockNameForSchema: (schema: string | undefined) => string;
|
|
1544
|
+
|
|
1545
|
+
/**
|
|
1546
|
+
* Which schema's migration lock to take. `schema` undefined → resolve from
|
|
1547
|
+
* configuration (`DB_SCHEMA`, the same variable `connectionConfig.ts` pins
|
|
1548
|
+
* the postgres `search_path` from); the empty string and `'public'`
|
|
1549
|
+
* normalize to the default scope. The scope must come from CONFIGURATION —
|
|
1550
|
+
* never from a per-call `current_schema()` probe, whose answer can drift
|
|
1551
|
+
* per session while the configured value cannot.
|
|
1552
|
+
*/
|
|
1553
|
+
export declare interface MigrationLockScope {
|
|
1554
|
+
readonly schema?: string | undefined;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1500
1557
|
/**
|
|
1501
1558
|
* Discriminated union for the concrete DDL operations the planner
|
|
1502
1559
|
* emits. Every variant carries the `table` (most ops act on one
|
|
@@ -1725,6 +1782,18 @@ declare interface NarrowedFromSpec {
|
|
|
1725
1782
|
readonly using?: string;
|
|
1726
1783
|
}
|
|
1727
1784
|
|
|
1785
|
+
/**
|
|
1786
|
+
* Postgres identifier for the trigger function backing a given channel.
|
|
1787
|
+
*
|
|
1788
|
+
* Derived from the channel, NOT a single global name, and that is the whole
|
|
1789
|
+
* point: `CREATE OR REPLACE FUNCTION framework_notify_change()` is one row in
|
|
1790
|
+
* `pg_proc` for the entire database, so two schemas applied with different
|
|
1791
|
+
* channels overwrote each other and the last one won. Everything applied
|
|
1792
|
+
* earlier then emitted on somebody else's channel — silently, because a NOTIFY
|
|
1793
|
+
* nobody listens to is not an error.
|
|
1794
|
+
*/
|
|
1795
|
+
export declare const notifyFunctionName: (channel: string) => string;
|
|
1796
|
+
|
|
1728
1797
|
/** Negation of an arbitrary sub-predicate → `NOT (...)`. Wraps any
|
|
1729
1798
|
* leaf/and/or/subquery subtree (distinct from the per-column `neq` and
|
|
1730
1799
|
* the narrow `notInSubquery`/`notExists`). */
|
|
@@ -1938,13 +2007,19 @@ declare interface PredicateLeaf {
|
|
|
1938
2007
|
* missing half: the lifecycle validated, registered, and never ran, so every
|
|
1939
2008
|
* tenant came up empty and nothing said so.
|
|
1940
2009
|
*
|
|
1941
|
-
* The seeds run through
|
|
1942
|
-
* (`
|
|
1943
|
-
* check. A seed failure REJECTS — see `fireTenantCreateSeeds` for why,
|
|
1944
|
-
* note that re-calling this function is safe (the DDL is `IF NOT EXISTS`
|
|
1945
|
-
* seed steps are idempotent by contract).
|
|
2010
|
+
* The seeds run through `setTenantCreateSeedHook` — the hook itself IS
|
|
2011
|
+
* installed at boot (`seedRunner.ts`); with no seeds declared this costs one
|
|
2012
|
+
* null check. A seed failure REJECTS — see `fireTenantCreateSeeds` for why,
|
|
2013
|
+
* and note that re-calling this function is safe (the DDL is `IF NOT EXISTS`
|
|
2014
|
+
* and seed steps are idempotent by contract).
|
|
2015
|
+
*
|
|
2016
|
+
* Wired by BOTH boot paths through `makeTenantProvisioner` (@voltro/cli):
|
|
2017
|
+
* under `tenantIsolation: 'namespace'` on a SQL dialect, every namespace store
|
|
2018
|
+
* view provisions lazily on first use — memoised per namespace per process.
|
|
2019
|
+
* Eager provisioning is the APP's move (call this from a seed/startup over its
|
|
2020
|
+
* own tenant table); the framework has no tenant registry to enumerate.
|
|
1946
2021
|
*/
|
|
1947
|
-
export declare const provisionTenantNamespace: (tables: ReadonlyArray<AnyTable>, namespace: string, sqlLayer: Layer.Layer<SqlClient.SqlClient, ConfigError.ConfigError | SqlError.SqlError, never>, dialect?: DialectId) => Promise<void>;
|
|
2022
|
+
export declare const provisionTenantNamespace: (tables: ReadonlyArray<AnyTable>, namespace: string, sqlLayer: Layer.Layer<SqlClient.SqlClient, ConfigError.ConfigError | SqlError.SqlError, never>, dialect?: DialectId, options?: SchemaApplyOptions) => Promise<void>;
|
|
1948
2023
|
|
|
1949
2024
|
/**
|
|
1950
2025
|
* The runtime-facing materialized query — a plain bag of strings the store and
|
|
@@ -2274,6 +2349,15 @@ export declare interface ReactiveTriggerDrift {
|
|
|
2274
2349
|
readonly functionOutdated: boolean;
|
|
2275
2350
|
}
|
|
2276
2351
|
|
|
2352
|
+
/**
|
|
2353
|
+
* Trigger name for one table on one channel.
|
|
2354
|
+
*
|
|
2355
|
+
* The channel is part of the name so a table reachable from two channels keeps
|
|
2356
|
+
* one trigger per channel, instead of the second install's `DROP TRIGGER IF
|
|
2357
|
+
* EXISTS` silently removing the first.
|
|
2358
|
+
*/
|
|
2359
|
+
export declare const reactiveTriggerName: (tableName: string, channel: string) => string;
|
|
2360
|
+
|
|
2277
2361
|
/**
|
|
2278
2362
|
* The statements that bring the DATABASE's change triggers back in line with
|
|
2279
2363
|
* what the schema declares.
|
|
@@ -2400,12 +2484,21 @@ export declare const rehearsedOperation: (planned: PlannedOperation) => Rehearse
|
|
|
2400
2484
|
*/
|
|
2401
2485
|
export declare const rehearseMigrationOnBranch: (ops: BranchRehearsalOps) => Promise<BranchRehearsalReport>;
|
|
2402
2486
|
|
|
2403
|
-
export declare const releaseMigrationLock: (sql: SqlClient.SqlClient) => Effect.Effect<void, SqlError_2>;
|
|
2487
|
+
export declare const releaseMigrationLock: (sql: SqlClient.SqlClient, scope?: MigrationLockScope) => Effect.Effect<void, SqlError_2>;
|
|
2404
2488
|
|
|
2405
2489
|
export declare const renderColumnMysql: (col: ColumnSnapshot) => string;
|
|
2406
2490
|
|
|
2407
2491
|
export declare const renderColumnPg: (col: ColumnSnapshot) => string;
|
|
2408
2492
|
|
|
2493
|
+
/**
|
|
2494
|
+
* The effective lock schema: an explicit scope wins; otherwise `DB_SCHEMA`
|
|
2495
|
+
* (the one env var the CLI's connection resolver reads for the schema pin).
|
|
2496
|
+
* `undefined` = the default schema → the legacy constant key/name.
|
|
2497
|
+
*/
|
|
2498
|
+
export declare const resolveMigrationLockSchema: (scope?: MigrationLockScope) => string | undefined;
|
|
2499
|
+
|
|
2500
|
+
declare type RetryDecision = 'retry' | 'noRetry';
|
|
2501
|
+
|
|
2409
2502
|
/**
|
|
2410
2503
|
* Roll back a single file-based migration by id. Looks up the
|
|
2411
2504
|
* migration's `down` body via file discovery (the file must still be
|
|
@@ -2419,6 +2512,7 @@ export declare const renderColumnPg: (col: ColumnSnapshot) => string;
|
|
|
2419
2512
|
export declare const rollbackFileBasedMigration: (sql: SqlClient.SqlClient, ctx: {
|
|
2420
2513
|
projectRoot: string;
|
|
2421
2514
|
id: string;
|
|
2515
|
+
lockSchema?: string;
|
|
2422
2516
|
}) => Effect.Effect<{
|
|
2423
2517
|
id: string;
|
|
2424
2518
|
durationMs: number;
|
|
@@ -2506,6 +2600,9 @@ export declare interface RunFileBasedMigrationsCtx {
|
|
|
2506
2600
|
readonly projectRoot: string;
|
|
2507
2601
|
readonly env: 'dev' | 'staging' | 'prod';
|
|
2508
2602
|
readonly appliedBy: string;
|
|
2603
|
+
/** Schema scope for the migration advisory lock (see `migrations/lock.ts`).
|
|
2604
|
+
* Absent → resolved from configuration (`DB_SCHEMA`). */
|
|
2605
|
+
readonly lockSchema?: string;
|
|
2509
2606
|
}
|
|
2510
2607
|
|
|
2511
2608
|
/**
|
|
@@ -2516,7 +2613,7 @@ export declare interface RunFileBasedMigrationsCtx {
|
|
|
2516
2613
|
* `voltro_isr_cache` so framework releases that grow new columns
|
|
2517
2614
|
* don't crash old DBs at boot.
|
|
2518
2615
|
*/
|
|
2519
|
-
export declare const runFrameworkBootstrap: (tables: ReadonlyArray<AnyTable>, sqlLayer: Layer.Layer<SqlClient.SqlClient, ConfigError.ConfigError | SqlError.SqlError, never>, dialect?: DialectId) => Promise<void>;
|
|
2616
|
+
export declare const runFrameworkBootstrap: (tables: ReadonlyArray<AnyTable>, sqlLayer: Layer.Layer<SqlClient.SqlClient, ConfigError.ConfigError | SqlError.SqlError, never>, dialect?: DialectId, options?: SchemaApplyOptions) => Promise<void>;
|
|
2520
2617
|
|
|
2521
2618
|
/**
|
|
2522
2619
|
* Run `applySchema` against a fresh SqlClient from the provided sqlLayer.
|
|
@@ -2526,7 +2623,7 @@ export declare const runFrameworkBootstrap: (tables: ReadonlyArray<AnyTable>, sq
|
|
|
2526
2623
|
* `dialect` is passed through to the DDL emitter so SQL types + reactive
|
|
2527
2624
|
* trigger emission match the underlying engine.
|
|
2528
2625
|
*/
|
|
2529
|
-
export declare const runMigrate: (tables: ReadonlyArray<AnyTable>, sqlLayer: Layer.Layer<SqlClient.SqlClient, ConfigError.ConfigError | SqlError.SqlError, never>, dialect?: DialectId) => Promise<void>;
|
|
2626
|
+
export declare const runMigrate: (tables: ReadonlyArray<AnyTable>, sqlLayer: Layer.Layer<SqlClient.SqlClient, ConfigError.ConfigError | SqlError.SqlError, never>, dialect?: DialectId, options?: SchemaApplyOptions) => Promise<void>;
|
|
2530
2627
|
|
|
2531
2628
|
/**
|
|
2532
2629
|
* Top-level entry point — called once per boot. Returns a
|
|
@@ -2545,6 +2642,36 @@ export declare interface RunPlannedMigrationsCtx {
|
|
|
2545
2642
|
readonly dialectId: string;
|
|
2546
2643
|
}
|
|
2547
2644
|
|
|
2645
|
+
/**
|
|
2646
|
+
* Effect that applies the emitted DDL to the provided SqlClient. Splits
|
|
2647
|
+
* on `;` only outside dollar-quoted blocks (the postgres NOTIFY trigger
|
|
2648
|
+
* function body uses `$$`), so the plpgsql block stays intact as a
|
|
2649
|
+
* single statement. SQLite has no `$$` quoting so the splitter is a
|
|
2650
|
+
* superset.
|
|
2651
|
+
*
|
|
2652
|
+
* Caller passes the dialect explicitly. Defaults to `'postgres'` for
|
|
2653
|
+
* call-sites that haven't migrated yet.
|
|
2654
|
+
*/
|
|
2655
|
+
/**
|
|
2656
|
+
* Cross-cutting options for the auto-migrate apply entry points.
|
|
2657
|
+
*
|
|
2658
|
+
* `retryFilter` is the DIALECT's own transient-failure predicate
|
|
2659
|
+
* (`SqlDialect.retryFilter`), threaded in by the caller because this package
|
|
2660
|
+
* deliberately has NO dialect registry — the CLI loads the dialect module and
|
|
2661
|
+
* hands its predicate through (optimizations 1.6). Absent → no retry, the
|
|
2662
|
+
* pre-1.6 behavior. Present → a transient DDL failure (SQLITE_BUSY meeting
|
|
2663
|
+
* the schema lock, a deadlock victim) is retried BOUNDED instead of dying on
|
|
2664
|
+
* the first attempt while every equivalent DML statement would be retried.
|
|
2665
|
+
*
|
|
2666
|
+
* `lockSchema` scopes the migration advisory lock (see `migrations/lock.ts`);
|
|
2667
|
+
* absent → `DB_SCHEMA` from the environment, the same configuration the
|
|
2668
|
+
* connection's `search_path` pin reads.
|
|
2669
|
+
*/
|
|
2670
|
+
export declare interface SchemaApplyOptions {
|
|
2671
|
+
readonly retryFilter?: (error: unknown) => RetryDecision;
|
|
2672
|
+
readonly lockSchema?: string;
|
|
2673
|
+
}
|
|
2674
|
+
|
|
2548
2675
|
/**
|
|
2549
2676
|
* The full schema as the planner sees it on one side of the diff.
|
|
2550
2677
|
* Both the declared side and the introspected side conform to this
|
|
@@ -3331,6 +3458,11 @@ declare interface View<Name extends string, Fields extends Record<string, Column
|
|
|
3331
3458
|
* `pg_advisory_lock(bigint)` wants a number; we hard-code a constant
|
|
3332
3459
|
* inside the safe-integer range so every consumer races for the same
|
|
3333
3460
|
* lock without doing string hashing at runtime.
|
|
3461
|
+
*
|
|
3462
|
+
* This is the key for the DEFAULT schema, and it must stay EXACTLY this
|
|
3463
|
+
* value: a rolling deploy of a default-schema app has old and new
|
|
3464
|
+
* replicas migrating side by side, and they can only serialize if both
|
|
3465
|
+
* generations compute the SAME key.
|
|
3334
3466
|
*/
|
|
3335
3467
|
export declare const VOLTRO_MIGRATION_LOCK_KEY = 6322741009312437n;
|
|
3336
3468
|
|
|
@@ -3366,7 +3498,7 @@ declare interface WindowSpec {
|
|
|
3366
3498
|
* leaves the postgres lock held until that connection closes (which
|
|
3367
3499
|
* the pooled SqlClient does on Effect scope cleanup).
|
|
3368
3500
|
*/
|
|
3369
|
-
export declare const withMigrationLock: <A, E, R = never>(sql: SqlClient.SqlClient, work: Effect.Effect<A, E, R
|
|
3501
|
+
export declare const withMigrationLock: <A, E, R = never>(sql: SqlClient.SqlClient, work: Effect.Effect<A, E, R>, scope?: MigrationLockScope) => Effect.Effect<A, E | SqlError_2, R>;
|
|
3370
3502
|
|
|
3371
3503
|
/** Tree of relations to eager-load. */
|
|
3372
3504
|
declare type WithSpec = Readonly<Record<string, true | EagerLoadSpec>>;
|