@kairos-es/store-postgres 1.0.0-alpha.4 → 1.0.0-alpha.6
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/README.md +54 -29
- package/dist/cjs/clients.js +34 -24
- package/dist/cjs/clients.js.map +1 -1
- package/dist/cjs/config.js +9 -15
- package/dist/cjs/config.js.map +1 -1
- package/dist/cjs/ensureSchema.js +2 -2
- package/dist/cjs/ensureSchema.js.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/matchSql.js +15 -4
- package/dist/cjs/internal/matchSql.js.map +1 -1
- package/dist/cjs/internal/readPlan.js +25 -1
- package/dist/cjs/internal/readPlan.js.map +1 -1
- package/dist/cjs/internal/transport.js +17 -13
- package/dist/cjs/internal/transport.js.map +1 -1
- package/dist/cjs/store.js +30 -25
- package/dist/cjs/store.js.map +1 -1
- package/dist/dts-cjs/clients.d.ts +66 -0
- package/dist/dts-cjs/clients.d.ts.map +1 -0
- package/dist/{dts → dts-cjs}/config.d.ts +9 -19
- package/dist/{dts → dts-cjs}/config.d.ts.map +1 -1
- package/dist/{dts → dts-cjs}/ensureSchema.d.ts +2 -2
- package/dist/dts-cjs/ensureSchema.d.ts.map +1 -0
- package/dist/{dts → dts-cjs}/index.d.ts +4 -3
- package/dist/dts-cjs/index.d.ts.map +1 -0
- package/dist/{dts → dts-cjs}/internal/ddl.d.ts +1 -1
- package/dist/{dts → dts-cjs}/internal/ddl.d.ts.map +1 -1
- package/dist/{dts → dts-cjs}/internal/matchSql.d.ts.map +1 -1
- package/dist/{dts → dts-cjs}/internal/readPlan.d.ts +1 -1
- package/dist/{dts → dts-cjs}/internal/readPlan.d.ts.map +1 -1
- package/dist/{dts → dts-cjs}/internal/transport.d.ts +20 -15
- package/dist/dts-cjs/internal/transport.d.ts.map +1 -0
- package/dist/dts-cjs/package.json +3 -0
- package/dist/dts-cjs/store.d.ts.map +1 -0
- package/dist/dts-esm/clients.d.ts +66 -0
- package/dist/dts-esm/clients.d.ts.map +1 -0
- package/dist/dts-esm/config.d.ts +48 -0
- package/dist/dts-esm/config.d.ts.map +1 -0
- package/dist/dts-esm/ensureSchema.d.ts +40 -0
- package/dist/dts-esm/ensureSchema.d.ts.map +1 -0
- package/dist/dts-esm/index.d.ts +42 -0
- package/dist/dts-esm/index.d.ts.map +1 -0
- package/dist/dts-esm/internal/ddl.d.ts +174 -0
- package/dist/dts-esm/internal/ddl.d.ts.map +1 -0
- package/dist/dts-esm/internal/matchSql.d.ts +164 -0
- package/dist/dts-esm/internal/matchSql.d.ts.map +1 -0
- package/dist/dts-esm/internal/readPlan.d.ts +72 -0
- package/dist/dts-esm/internal/readPlan.d.ts.map +1 -0
- package/dist/dts-esm/internal/transport.d.ts +131 -0
- package/dist/dts-esm/internal/transport.d.ts.map +1 -0
- package/dist/dts-esm/package.json +3 -0
- package/dist/dts-esm/store.d.ts +17 -0
- package/dist/dts-esm/store.d.ts.map +1 -0
- package/dist/esm/clients.js +34 -24
- package/dist/esm/clients.js.map +1 -1
- package/dist/esm/config.js +9 -15
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/ensureSchema.js +2 -2
- package/dist/esm/ensureSchema.js.map +1 -1
- package/dist/esm/index.js +4 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/matchSql.js +15 -4
- package/dist/esm/internal/matchSql.js.map +1 -1
- package/dist/esm/internal/readPlan.js +24 -1
- package/dist/esm/internal/readPlan.js.map +1 -1
- package/dist/esm/internal/transport.js +18 -14
- package/dist/esm/internal/transport.js.map +1 -1
- package/dist/esm/store.js +30 -25
- package/dist/esm/store.js.map +1 -1
- package/package.json +13 -11
- package/src/clients.ts +43 -31
- package/src/config.ts +12 -13
- package/src/ensureSchema.ts +2 -2
- package/src/index.ts +4 -3
- package/src/internal/ddl.ts +1 -1
- package/src/internal/matchSql.ts +15 -4
- package/src/internal/readPlan.ts +3 -2
- package/src/internal/transport.ts +28 -20
- package/src/store.ts +35 -28
- package/dist/dts/clients.d.ts +0 -34
- package/dist/dts/clients.d.ts.map +0 -1
- package/dist/dts/ensureSchema.d.ts.map +0 -1
- package/dist/dts/index.d.ts.map +0 -1
- package/dist/dts/internal/transport.d.ts.map +0 -1
- package/dist/dts/store.d.ts.map +0 -1
- /package/dist/{dts → dts-cjs}/internal/matchSql.d.ts +0 -0
- /package/dist/{dts → dts-cjs}/store.d.ts +0 -0
package/dist/cjs/store.js
CHANGED
|
@@ -52,15 +52,19 @@ const make = (config, names) => _effect.Effect.gen(function* () {
|
|
|
52
52
|
* Nor would such a parameter be load-bearing for the REPEATABLE READ
|
|
53
53
|
* transaction this runs inside, which is the trap worth naming, since a
|
|
54
54
|
* closed-over client LOOKS like it must escape to its own snapshot.
|
|
55
|
-
*
|
|
56
|
-
* from the FIBRE CONTEXT
|
|
57
|
-
*
|
|
58
|
-
* `
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
55
|
+
* `effect/sql` resolves a statement's connection when the statement RUNS,
|
|
56
|
+
* from the FIBRE CONTEXT: `withTransaction` acquires one connection and
|
|
57
|
+
* provides it under that client's OWN `TransactionConnection` key — one key
|
|
58
|
+
* per `SqlClient` instance — and every statement that client builds resolves
|
|
59
|
+
* through a `getConnection` that reads that key first, falling back to the
|
|
60
|
+
* pool only when it is absent (`effect/sql`'s `SqlClient.make`). So a
|
|
61
|
+
* statement joins a transaction by being RUN inside it AND by being built from
|
|
62
|
+
* the SAME client value that opened it; a statement from any other client,
|
|
63
|
+
* even one over the same database, runs on its own pooled connection outside
|
|
64
|
+
* the transaction. Here every statement in the frame — the isolation `SET`,
|
|
65
|
+
* the row fetch and this `MAX(id)` — comes from `pooled`, the client that
|
|
66
|
+
* opened it, so all three share its connection and its snapshot, and passing
|
|
67
|
+
* the client along the call chain would add nothing. `read-postgres`'s
|
|
64
68
|
* `pinnedConnection` test observes the same fact from the SERVER: two
|
|
65
69
|
* statements issued inside one transaction report one `pg_backend_pid()`.
|
|
66
70
|
*
|
|
@@ -136,7 +140,7 @@ const make = (config, names) => _effect.Effect.gen(function* () {
|
|
|
136
140
|
* conflict (zero rows) vs head (`MAX(id)`) is read from the returned rows by
|
|
137
141
|
* the caller, never from a caught error.
|
|
138
142
|
*/
|
|
139
|
-
const callAppendFn = select => pooled.withTransaction(setLocalLockTimeout(pooled, lockTimeout).pipe(_effect.Effect.
|
|
143
|
+
const callAppendFn = select => pooled.withTransaction(setLocalLockTimeout(pooled, lockTimeout).pipe(_effect.Effect.andThen(select)));
|
|
140
144
|
const append = (events, condition) => {
|
|
141
145
|
const eventsJson = events.map(_transport.toEventJson);
|
|
142
146
|
// Raw mechanics: a CONFLICT is `AppendConditionFailed`; a `SqlError` (incl.
|
|
@@ -199,22 +203,23 @@ const make = (config, names) => _effect.Effect.gen(function* () {
|
|
|
199
203
|
/**
|
|
200
204
|
* Wire core's subscribe machine to the live clients: `fetch` is the
|
|
201
205
|
* per-subscription compiled read plan run against the pooled client and mapped
|
|
202
|
-
* to `SequencedEvent`s; `listen` is the direct client's
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
+
* to `SequencedEvent`s; `listen` is the direct client's LISTEN on this store's
|
|
207
|
+
* channel (the Neon-safe path — `clients.ts` owns why there are two clients at
|
|
208
|
+
* all), which reserves one of that client's connections for as long as the
|
|
209
|
+
* subscription's wake fibre runs and drains its notification queue as a
|
|
210
|
+
* stream. The plan is compiled ONCE here so the poll loop re-binds only the
|
|
211
|
+
* cursor.
|
|
206
212
|
*
|
|
207
213
|
* The wake source is `NOTIFY`, and it is a LATENCY optimisation only: the
|
|
208
|
-
* machine's periodic position-based poll is what makes delivery correct
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
* wiring choice and not a runtime error.
|
|
214
|
+
* machine's periodic position-based poll is what makes delivery correct. A
|
|
215
|
+
* listening connection that DROPS fails its queue with the `SqlError` it died
|
|
216
|
+
* of, so the machine's listen-side retry re-subscribes on a fresh connection
|
|
217
|
+
* — but the notifications sent while it was down are gone, and only the poll
|
|
218
|
+
* recovers the events they announced. And some failures are silent: a Neon
|
|
219
|
+
* pooled endpoint, if `PgClientDirect` is misconfigured, accepts `LISTEN` and
|
|
220
|
+
* then never delivers a `NOTIFY`, so delivery degrades to poll-rate rather
|
|
221
|
+
* than failing, which is why that trap is a deployment-time wiring choice and
|
|
222
|
+
* not a runtime error.
|
|
218
223
|
*
|
|
219
224
|
* `E` is `SqlError.SqlError` — both seams fail with it, so the machine's single
|
|
220
225
|
* error parameter carries it straight through to `makeContractStore`.
|
|
@@ -223,7 +228,7 @@ const make = (config, names) => _effect.Effect.gen(function* () {
|
|
|
223
228
|
const plan = (0, _readPlan.compileFetchPlan)(tables, query);
|
|
224
229
|
return (0, _core.subscribeStream)({
|
|
225
230
|
fetch: (from, limit) => (0, _readPlan.runFetch)(pooled, plan, from, limit).pipe(_effect.Effect.map(rows => rows.map(_transport.rowToSequenced))),
|
|
226
|
-
listen: direct.listen(names.channel),
|
|
231
|
+
listen: _effect.Stream.unwrap(_effect.Effect.map(direct.listen(names.channel), _effect.Stream.fromQueue)),
|
|
227
232
|
pollInterval,
|
|
228
233
|
catchUpPageSize
|
|
229
234
|
}, after);
|
package/dist/cjs/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","names":["_core","require","_effect","_clients","_config","_ddl","_readPlan","_transport","setLocalLockTimeout","sql","lockTimeout","make","config","names","Effect","gen","pooled","PgClientPooled","direct","PgClientDirect","pollInterval","DEFAULT_POLL_INTERVAL_MILLIS","catchUpPageSize","DEFAULT_CATCH_UP_PAGE_SIZE","tables","main","quoteQualified","mainTable","tag","tagTable","globalHead","pipe","map","rows","max","undefined","ORIGIN","BigInt","readRowsAndHead","query","options","plan","compileFetchPlan","limit","runFetch","after","lastRow","at","head","id","withTransaction","unsafe","read","events","Stream","fromIterable","rowToSequenced","callAppendFn","select","
|
|
1
|
+
{"version":3,"file":"store.js","names":["_core","require","_effect","_clients","_config","_ddl","_readPlan","_transport","setLocalLockTimeout","sql","lockTimeout","make","config","names","Effect","gen","pooled","PgClientPooled","direct","PgClientDirect","pollInterval","DEFAULT_POLL_INTERVAL_MILLIS","catchUpPageSize","DEFAULT_CATCH_UP_PAGE_SIZE","tables","main","quoteQualified","mainTable","tag","tagTable","globalHead","pipe","map","rows","max","undefined","ORIGIN","BigInt","readRowsAndHead","query","options","plan","compileFetchPlan","limit","runFetch","after","lastRow","at","head","id","withTransaction","unsafe","read","events","Stream","fromIterable","rowToSequenced","callAppendFn","select","andThen","append","condition","eventsJson","toEventJson","appendUnconditionalFn","jsonbText","headFromRows","queryItems","toQueryItemsJson","failIfEventsMatch","afterId","appendFn","length","AppendConditionFailed","Error","subscribe","subscribeStream","fetch","from","listen","unwrap","channel","fromQueue","layer","decoded","decodePostgresStoreConfig","Layer","effect","DcbEventStore","resolveNames","makeContractStore","exports"],"sources":["../../src/store.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The TWO store-owned Postgres clients — the "Neon trap" mitigation (ADR-0002).
|
|
3
|
+
*
|
|
4
|
+
* `@effect/sql-pg` exposes a single `PgClient` (and `SqlClient`) service; a
|
|
5
|
+
* `PgClient.layer` claims BOTH. If we built two `PgClient.layer`s they would
|
|
6
|
+
* collide on that one key — the second would shadow the first. So instead we
|
|
7
|
+
* define two DISTINCT `Context.Service`s, each HOLDING a `PgClient` value:
|
|
8
|
+
*
|
|
9
|
+
* - `PgClientPooled` — the pooled client used for reads, the append function,
|
|
10
|
+
* and `notify`. Its statements borrow a connection from the client's pool per
|
|
11
|
+
* query.
|
|
12
|
+
* - `PgClientDirect` — a client used ONLY by `subscribe`'s `listen`. Its
|
|
13
|
+
* built-in `listen` RESERVES a connection from that client's own pool and
|
|
14
|
+
* holds it for the life of the subscription, so the listening session lives
|
|
15
|
+
* on whatever host the client was configured with. On a Neon POOLED endpoint
|
|
16
|
+
* (`…-pooler…`) that session is a PgBouncer front-door connection, which
|
|
17
|
+
* SILENTLY DROPS `LISTEN`/`NOTIFY` — the subscription would simply never
|
|
18
|
+
* wake. Pointing `PgClientDirect` at Neon's DIRECT (non-pooler) endpoint fixes
|
|
19
|
+
* it. `subscribe` is the ONLY method that touches `PgClientDirect`.
|
|
20
|
+
*
|
|
21
|
+
* Because each live subscription holds one of `PgClientDirect`'s pooled
|
|
22
|
+
* connections until it closes, that client's `maxConnections` is also the number
|
|
23
|
+
* of subscriptions that can be listening at once. A subscription past it waits
|
|
24
|
+
* for a connection on its wake fibre only — delivery still proceeds at the poll
|
|
25
|
+
* rate meanwhile (see `store.ts`) — so size the direct client for the expected
|
|
26
|
+
* subscriber count rather than for query throughput.
|
|
27
|
+
*
|
|
28
|
+
* For a plain (non-Neon) Postgres both services point at the same URL; the split
|
|
29
|
+
* costs nothing there. The two-service design is what makes the Neon fix a
|
|
30
|
+
* deployment-time wiring choice rather than a code change.
|
|
31
|
+
*/
|
|
32
|
+
import { PgClient } from '@effect/sql-pg';
|
|
33
|
+
import { Context, Layer } from 'effect';
|
|
34
|
+
import type { SqlError } from 'effect/sql';
|
|
35
|
+
declare const PgClientPooled_base: Context.ServiceClass<PgClientPooled, "@kairos-es/store-postgres/PgClientPooled", PgClient.PgClient>;
|
|
36
|
+
/**
|
|
37
|
+
* The pooled client service: reads, the append function, and `notify`. Holds a
|
|
38
|
+
* `PgClient` value rather than being a `PgClient.layer`, so it never collides
|
|
39
|
+
* with the direct client on the shared `PgClient`/`SqlClient` key.
|
|
40
|
+
*/
|
|
41
|
+
export declare class PgClientPooled extends PgClientPooled_base {
|
|
42
|
+
}
|
|
43
|
+
declare const PgClientDirect_base: Context.ServiceClass<PgClientDirect, "@kairos-es/store-postgres/PgClientDirect", PgClient.PgClient>;
|
|
44
|
+
/**
|
|
45
|
+
* The direct (non-pooler) client service: the `subscribe` listener ONLY. Point
|
|
46
|
+
* this at a direct endpoint on Neon so `LISTEN`/`NOTIFY` is not dropped by the
|
|
47
|
+
* pooler.
|
|
48
|
+
*/
|
|
49
|
+
export declare class PgClientDirect extends PgClientDirect_base {
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Build a `PgClientPooled` layer from a `PgClient` pool config. We construct the
|
|
53
|
+
* client via `PgClient.make` (scoped) and place it in our OWN service, then
|
|
54
|
+
* provide `Reactivity.layer` (which `PgClient.make` requires) — exactly what the
|
|
55
|
+
* built-in `PgClient.layer` does internally, minus the collision-prone claim on
|
|
56
|
+
* the shared `PgClient` key.
|
|
57
|
+
*/
|
|
58
|
+
export declare const pooledLayer: (config: PgClient.PgPoolConfig) => Layer.Layer<PgClientPooled, SqlError.SqlError>;
|
|
59
|
+
/**
|
|
60
|
+
* Build a `PgClientDirect` layer from a `PgClient` pool config. Same construction as
|
|
61
|
+
* `pooledLayer`; the two differ only in which endpoint the caller points them
|
|
62
|
+
* at (and that only matters on Neon).
|
|
63
|
+
*/
|
|
64
|
+
export declare const directLayer: (config: PgClient.PgPoolConfig) => Layer.Layer<PgClientDirect, SqlError.SqlError>;
|
|
65
|
+
export {};
|
|
66
|
+
//# sourceMappingURL=clients.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../../src/clients.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAEvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;;AAE1C;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,mBAGW;CAAG;;AAElD;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,mBAGW;CAAG;AAElD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,QAAQ,CAAC,YAAY,KAC5B,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,QAAQ,CAAC,QAAQ,CAG7C,CAAA;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,QAAQ,CAAC,YAAY,KAC5B,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,QAAQ,CAAC,QAAQ,CAG7C,CAAA"}
|
|
@@ -25,30 +25,20 @@ import { Schema } from 'effect';
|
|
|
25
25
|
* `DEFAULT_CATCH_UP_PAGE_SIZE`: how many events a single catch-up/live read
|
|
26
26
|
* fetches before looping.
|
|
27
27
|
*/
|
|
28
|
-
export declare const PostgresStoreConfig: Schema.
|
|
29
|
-
pollInterval: Schema.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
schema: Schema.optionalWith<Schema.filter<Schema.filter<typeof Schema.String>>, {
|
|
36
|
-
exact: true;
|
|
37
|
-
}>;
|
|
38
|
-
tablePrefix: Schema.optionalWith<Schema.filter<Schema.filter<typeof Schema.String>>, {
|
|
39
|
-
exact: true;
|
|
40
|
-
}>;
|
|
41
|
-
lockTimeout: Schema.optionalWith<Schema.filter<Schema.filter<typeof Schema.Number>>, {
|
|
42
|
-
exact: true;
|
|
43
|
-
}>;
|
|
44
|
-
}>>;
|
|
28
|
+
export declare const PostgresStoreConfig: Schema.Struct<{
|
|
29
|
+
readonly pollInterval: Schema.optionalKey<Schema.Number>;
|
|
30
|
+
readonly catchUpPageSize: Schema.optionalKey<Schema.Int>;
|
|
31
|
+
readonly schema: Schema.optionalKey<Schema.String>;
|
|
32
|
+
readonly tablePrefix: Schema.optionalKey<Schema.String>;
|
|
33
|
+
readonly lockTimeout: Schema.optionalKey<Schema.Number>;
|
|
34
|
+
}>;
|
|
45
35
|
export type PostgresStoreConfig = typeof PostgresStoreConfig.Type;
|
|
46
36
|
/**
|
|
47
37
|
* Decode an unknown value into a validated `PostgresStoreConfig`, throwing a
|
|
48
|
-
* `
|
|
38
|
+
* `SchemaError` on any violation. Used by `layer`/`ensureSchema` so a bad config
|
|
49
39
|
* fails at construction time.
|
|
50
40
|
*/
|
|
51
|
-
export declare const decodePostgresStoreConfig: (
|
|
41
|
+
export declare const decodePostgresStoreConfig: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => {
|
|
52
42
|
readonly schema?: string;
|
|
53
43
|
readonly tablePrefix?: string;
|
|
54
44
|
readonly lockTimeout?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAiB/B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAiB/B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,mBAAmB;;;;;;EAiB/B,CAAA;AACD,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAC,IAAI,CAAA;AAEjE;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;;;;;;CACS,CAAA"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This is deliberately NOT a migrator. It is a single `Effect<void, SqlError,
|
|
5
5
|
* SqlClient>` that creates (or refreshes) every object a store owns: both
|
|
6
6
|
* tables, both indexes, and both plpgsql functions. It requires the GENERIC
|
|
7
|
-
* `SqlClient`
|
|
7
|
+
* `SqlClient` service — NOT `PgClientPooled` — precisely so a consumer can drop it
|
|
8
8
|
* straight into THEIR OWN migrator, e.g.:
|
|
9
9
|
*
|
|
10
10
|
* ```ts
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
* bodies carry no bound values (pure schema), and the append functions keep
|
|
29
29
|
* their runtime VALUES as bound parameters, never interpolated.
|
|
30
30
|
*/
|
|
31
|
-
import { SqlClient, type SqlError } from '@effect/sql';
|
|
32
31
|
import { Effect } from 'effect';
|
|
32
|
+
import { SqlClient, type SqlError } from 'effect/sql';
|
|
33
33
|
import { type PostgresStoreConfig } from './config.js';
|
|
34
34
|
/**
|
|
35
35
|
* Produce the migration payload for `config`. Resolves the object names once and
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensureSchema.d.ts","sourceRoot":"","sources":["../../src/ensureSchema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAG9E;;;;GAIG;AACH,eAAO,MAAM,YAAY,GACvB,QAAQ,mBAAmB,KAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,SAAS,CAQzD,CAAA"}
|
|
@@ -30,9 +30,10 @@
|
|
|
30
30
|
* const store = layer(config).pipe(Layer.provide(clients))
|
|
31
31
|
* ```
|
|
32
32
|
*
|
|
33
|
-
* The store `layer` performs NO DDL: it depends only on the two client
|
|
34
|
-
* assumes `ensureSchema` has run. `ensureSchema` requires the generic
|
|
35
|
-
*
|
|
33
|
+
* The store `layer` performs NO DDL: it depends only on the two client services
|
|
34
|
+
* and assumes `ensureSchema` has run. `ensureSchema` requires the generic
|
|
35
|
+
* `SqlClient` service so it slots into any migrator; the runtime uses the
|
|
36
|
+
* store-owned services.
|
|
36
37
|
*/
|
|
37
38
|
export { directLayer, PgClientDirect, PgClientPooled, pooledLayer, } from './clients.js';
|
|
38
39
|
export type { PostgresStoreConfig } from './config.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,EACL,WAAW,EACX,cAAc,EACd,cAAc,EACd,WAAW,GACZ,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* would emit; VALUES stay bound parameters (`sql.unsafe` with `params`) and are
|
|
26
26
|
* never interpolated.
|
|
27
27
|
*/
|
|
28
|
-
import type { SqlClient, Statement } from '
|
|
28
|
+
import type { SqlClient, Statement } from 'effect/sql';
|
|
29
29
|
/**
|
|
30
30
|
* A store is one physical `{ schema, tablePrefix }` pair. Every object it owns
|
|
31
31
|
* (both tables, both indexes, both functions, and the NOTIFY channel) is derived
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ddl.d.ts","sourceRoot":"","sources":["../../../src/internal/ddl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ddl.d.ts","sourceRoot":"","sources":["../../../src/internal/ddl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAWtD;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAA;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED,gDAAgD;AAChD,eAAO,MAAM,cAAc,WAAW,CAAA;AACtC,sDAAsD;AACtD,eAAO,MAAM,oBAAoB,eAAe,CAAA;AAuChD;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAI,QAAQ;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B,KAAG,MAAM,GAAG,SAQZ,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,GAAI,QAAQ;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B,KAAG,aAkBH,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,MAIhC,CAAA;AA2Cd;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAC1B;AAoOD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,qBAAqB,GAC7B,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,GACpE,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAAG,iBAAiB,CAAC,CAAA;AAE5D;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,GAClC,OAAO,aAAa,EACpB,SAAS,qBAAqB,KAC7B,MAqBF,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,aAAa,KAAG,aAAa,CAAC,MAAM,CAmExE,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GACjB,KAAK,SAAS,CAAC,SAAS,EACxB,OAAO,aAAa,KACnB,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CACmB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matchSql.d.ts","sourceRoot":"","sources":["../../../src/internal/matchSql.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH;;;;;;;;;;GAUG;AACH,QAAA,MAAM,aAAa,kMASlB,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AAE/D;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAExB,CAAA;AAEZ;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,eAAW,KAAG,MAGvC,CAAA;AAEH;;;;GAIG;AACH,eAAO,MAAM,eAAe,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"matchSql.d.ts","sourceRoot":"","sources":["../../../src/internal/matchSql.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH;;;;;;;;;;GAUG;AACH,QAAA,MAAM,aAAa,kMASlB,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AAE/D;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAExB,CAAA;AAEZ;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,eAAW,KAAG,MAGvC,CAAA;AAEH;;;;GAIG;AACH,eAAO,MAAM,eAAe,OAAO,CAAA;AAgCnC;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,MAE7B,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAExB,CAAA;AAEZ;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAU,MAAM,KAAG,MACkD,CAAA;AAE3G,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,qCAAqC;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,gBAAgB,GAAI,QAAQ,WAAW,KAAG,MA6BnD,CAAA;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,QAAQ,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAAC,KAC9C,MAImD,CAAA;AAEtD,kFAAkF;AAClF,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,MAKnC,CAAA;AAEZ,4EAA4E;AAC5E,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,MAKnC,CAAA;AAEZ;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,EAAE,KAAK,MAAM,KAAG,MAWtC,CAAA"}
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
* plpgsql body, where no compiler follows, and `ddl.ts` owns what that rests on
|
|
22
22
|
* instead.
|
|
23
23
|
*/
|
|
24
|
-
import type { SqlClient, SqlError } from '@effect/sql';
|
|
25
24
|
import type { Position, ReadLimit } from '@kairos-es/core';
|
|
26
25
|
import { type Query } from '@kairos-es/core';
|
|
27
26
|
import type { Effect } from 'effect';
|
|
27
|
+
import type { SqlClient, SqlError } from 'effect/sql';
|
|
28
28
|
import { type EventRow } from './transport.js';
|
|
29
29
|
/** The pre-quoted table names a plan reads from (see `quoteQualified`). */
|
|
30
30
|
export interface ReadTables {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readPlan.d.ts","sourceRoot":"","sources":["../../../src/internal/readPlan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;
|
|
1
|
+
{"version":3,"file":"readPlan.d.ts","sourceRoot":"","sources":["../../../src/internal/readPlan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EAAiC,KAAK,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAC3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErD,OAAO,EAAE,KAAK,QAAQ,EAA+B,MAAM,aAAa,CAAA;AAExE,2EAA2E;AAC3E,MAAM,WAAW,UAAU;IACzB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,qCAAqC;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,CACb,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,SAAS,GAAG,IAAI,KACpB,aAAa,CAAC,OAAO,CAAC,CAAA;CAC5B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,UAAU,EAClB,OAAO,KAAK,KACX,SAiCF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,GACnB,KAAK,SAAS,CAAC,SAAS,EACxB,MAAM,SAAS,EACf,OAAO,QAAQ,GAAG,SAAS,EAC3B,OAAO,SAAS,GAAG,SAAS,KAC3B,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,CACiB,CAAA"}
|
|
@@ -25,14 +25,15 @@ import type { EventColumnName } from './matchSql.js';
|
|
|
25
25
|
* Serialise a value to a JSON STRING for transport as a `::jsonb`-cast bound
|
|
26
26
|
* parameter.
|
|
27
27
|
*
|
|
28
|
-
* WHY not `sql.json(value)`:
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
28
|
+
* WHY a string and not `sql.json(value)`: the read plan runs through
|
|
29
|
+
* `sql.unsafe(text, params)` with POSITIONAL parameters, and a positional
|
|
30
|
+
* parameter must be a plain scalar or a flat array of scalars — `@effect/sql-pg`
|
|
31
|
+
* cannot infer a Postgres type for an object or an array of objects, and a
|
|
32
|
+
* `sql.json` fragment is not a value that list can carry. A pre-stringified
|
|
33
|
+
* JSON string binds untyped and the `::jsonb` cast has Postgres parse it, which
|
|
34
|
+
* round-trips reliably for both objects and arrays on the positional path and
|
|
35
|
+
* the tagged-template path alike. Kept as a named helper so every
|
|
36
|
+
* JSON-transport call site is consistent and the reasoning lives in one place.
|
|
36
37
|
*/
|
|
37
38
|
export declare const jsonbText: (value: unknown) => string;
|
|
38
39
|
/** The JSON shape of one query item: types OR-filter, tags AND-superset. */
|
|
@@ -75,9 +76,10 @@ export type EventJson = {
|
|
|
75
76
|
export declare const toEventJson: (event: DcbEvent) => EventJson;
|
|
76
77
|
/**
|
|
77
78
|
* The per-column TS types of a raw driver row — one entry per `EVENT_COLUMNS`
|
|
78
|
-
* name. These are
|
|
79
|
-
* for a payload-less event), `occurred_at` a
|
|
80
|
-
* `
|
|
79
|
+
* name. These are the JS types `@effect/sql-pg`'s default binary codecs decode
|
|
80
|
+
* to: `data` a `Uint8Array` (or null for a payload-less event), `occurred_at` a
|
|
81
|
+
* JS `Date`, `tags` a `string[]`, `metadata` whatever the driver parses a
|
|
82
|
+
* `jsonb` value into — declared
|
|
81
83
|
* `unknown`, because `jsonb` is the one column here whose SQL type does not
|
|
82
84
|
* fix its JS shape, and `metadataFrom` below is where it is checked. `id`
|
|
83
85
|
* (the `bigserial` position) is NOT here — it is prepended by the read projection
|
|
@@ -92,21 +94,24 @@ interface EventRowColumns {
|
|
|
92
94
|
readonly metadata: unknown;
|
|
93
95
|
}
|
|
94
96
|
/**
|
|
95
|
-
* A raw row from the main table as
|
|
97
|
+
* A raw row from the main table as the driver returns it, as `id` plus a
|
|
96
98
|
* mapped type over the shared `EventColumnName` descriptor. `id` is `int8`, which
|
|
97
|
-
* the driver hands back as a
|
|
99
|
+
* the driver's default codec hands back as a `bigint` (JS `number` is unsafe past
|
|
100
|
+
* 2^53). `rowToSequenced` still passes it through `BigInt(…)`, so a client
|
|
101
|
+
* configured with its own `int8` codec that yields the decimal string instead
|
|
102
|
+
* still mints a real `bigint` position.
|
|
98
103
|
* The payload columns cannot drift from the read projection: a rename in
|
|
99
104
|
* `EVENT_COLUMNS` breaks this mapped type.
|
|
100
105
|
*/
|
|
101
106
|
export type EventRow = {
|
|
102
|
-
readonly id: string;
|
|
107
|
+
readonly id: bigint | string;
|
|
103
108
|
} & {
|
|
104
109
|
readonly [K in EventColumnName]: EventRowColumns[K];
|
|
105
110
|
};
|
|
106
111
|
/**
|
|
107
112
|
* Map a raw main-table row to a core `SequencedEvent`. `data` NULL → empty bytes
|
|
108
113
|
* (a payload-less event round-trips to a zero-length `Uint8Array`); `occurred_at`
|
|
109
|
-
* Date → `DateTime.Utc`; `id`
|
|
114
|
+
* Date → `DateTime.Utc`; `id` → branded `Position`; `metadata` through
|
|
110
115
|
* `metadataFrom`. The column is `NOT NULL DEFAULT '{}'`, so there is no absent
|
|
111
116
|
* case to reconcile: an event appended with an empty bag reads back as `{}` on
|
|
112
117
|
* this engine exactly as on the in-memory oracle.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/internal/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EACV,QAAQ,EACR,QAAQ,EAER,KAAK,EACL,cAAc,EACf,MAAM,iBAAiB,CAAA;AAGxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,GAAI,OAAO,OAAO,KAAG,MAA+B,CAAA;AAE1E,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACrC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACrC;AAED,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,GAAI,OAAO,KAAK,KAAG,aAAa,CAAC,aAAa,CAItE,CAAA;AAEL;;;;;;;;GAQG;AACH,UAAU,gBAAgB;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;CAC5B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GAAG;IAAE,QAAQ,EAAE,CAAC,IAAI,eAAe,GAAG,gBAAgB,CAAC,CAAC,CAAC;CAAE,CAAA;AAEhF,mEAAmE;AACnE,eAAO,MAAM,WAAW,GAAI,OAAO,QAAQ,KAAG,SAW5C,CAAA;AAEF;;;;;;;;;;GAUG;AACH,UAAU,eAAe;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC3B;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG;IACxD,QAAQ,EAAE,CAAC,IAAI,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC;CACpD,CAAA;AAuBD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,QAAQ,KAAG,cAU7C,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"AAiDA,OAAO,EAGL,aAAa,EAQd,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAA6B,KAAK,EAAsB,MAAM,QAAQ,CAAA;AAE7E,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1D,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,UAAU,CAAA;AA2U9E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,GAChB,SAAQ,mBAAwB,KAC/B,KAAK,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,EAAE,cAAc,GAAG,cAAc,CASnE,CAAA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The TWO store-owned Postgres clients — the "Neon trap" mitigation (ADR-0002).
|
|
3
|
+
*
|
|
4
|
+
* `@effect/sql-pg` exposes a single `PgClient` (and `SqlClient`) service; a
|
|
5
|
+
* `PgClient.layer` claims BOTH. If we built two `PgClient.layer`s they would
|
|
6
|
+
* collide on that one key — the second would shadow the first. So instead we
|
|
7
|
+
* define two DISTINCT `Context.Service`s, each HOLDING a `PgClient` value:
|
|
8
|
+
*
|
|
9
|
+
* - `PgClientPooled` — the pooled client used for reads, the append function,
|
|
10
|
+
* and `notify`. Its statements borrow a connection from the client's pool per
|
|
11
|
+
* query.
|
|
12
|
+
* - `PgClientDirect` — a client used ONLY by `subscribe`'s `listen`. Its
|
|
13
|
+
* built-in `listen` RESERVES a connection from that client's own pool and
|
|
14
|
+
* holds it for the life of the subscription, so the listening session lives
|
|
15
|
+
* on whatever host the client was configured with. On a Neon POOLED endpoint
|
|
16
|
+
* (`…-pooler…`) that session is a PgBouncer front-door connection, which
|
|
17
|
+
* SILENTLY DROPS `LISTEN`/`NOTIFY` — the subscription would simply never
|
|
18
|
+
* wake. Pointing `PgClientDirect` at Neon's DIRECT (non-pooler) endpoint fixes
|
|
19
|
+
* it. `subscribe` is the ONLY method that touches `PgClientDirect`.
|
|
20
|
+
*
|
|
21
|
+
* Because each live subscription holds one of `PgClientDirect`'s pooled
|
|
22
|
+
* connections until it closes, that client's `maxConnections` is also the number
|
|
23
|
+
* of subscriptions that can be listening at once. A subscription past it waits
|
|
24
|
+
* for a connection on its wake fibre only — delivery still proceeds at the poll
|
|
25
|
+
* rate meanwhile (see `store.ts`) — so size the direct client for the expected
|
|
26
|
+
* subscriber count rather than for query throughput.
|
|
27
|
+
*
|
|
28
|
+
* For a plain (non-Neon) Postgres both services point at the same URL; the split
|
|
29
|
+
* costs nothing there. The two-service design is what makes the Neon fix a
|
|
30
|
+
* deployment-time wiring choice rather than a code change.
|
|
31
|
+
*/
|
|
32
|
+
import { PgClient } from '@effect/sql-pg';
|
|
33
|
+
import { Context, Layer } from 'effect';
|
|
34
|
+
import type { SqlError } from 'effect/sql';
|
|
35
|
+
declare const PgClientPooled_base: Context.ServiceClass<PgClientPooled, "@kairos-es/store-postgres/PgClientPooled", PgClient.PgClient>;
|
|
36
|
+
/**
|
|
37
|
+
* The pooled client service: reads, the append function, and `notify`. Holds a
|
|
38
|
+
* `PgClient` value rather than being a `PgClient.layer`, so it never collides
|
|
39
|
+
* with the direct client on the shared `PgClient`/`SqlClient` key.
|
|
40
|
+
*/
|
|
41
|
+
export declare class PgClientPooled extends PgClientPooled_base {
|
|
42
|
+
}
|
|
43
|
+
declare const PgClientDirect_base: Context.ServiceClass<PgClientDirect, "@kairos-es/store-postgres/PgClientDirect", PgClient.PgClient>;
|
|
44
|
+
/**
|
|
45
|
+
* The direct (non-pooler) client service: the `subscribe` listener ONLY. Point
|
|
46
|
+
* this at a direct endpoint on Neon so `LISTEN`/`NOTIFY` is not dropped by the
|
|
47
|
+
* pooler.
|
|
48
|
+
*/
|
|
49
|
+
export declare class PgClientDirect extends PgClientDirect_base {
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Build a `PgClientPooled` layer from a `PgClient` pool config. We construct the
|
|
53
|
+
* client via `PgClient.make` (scoped) and place it in our OWN service, then
|
|
54
|
+
* provide `Reactivity.layer` (which `PgClient.make` requires) — exactly what the
|
|
55
|
+
* built-in `PgClient.layer` does internally, minus the collision-prone claim on
|
|
56
|
+
* the shared `PgClient` key.
|
|
57
|
+
*/
|
|
58
|
+
export declare const pooledLayer: (config: PgClient.PgPoolConfig) => Layer.Layer<PgClientPooled, SqlError.SqlError>;
|
|
59
|
+
/**
|
|
60
|
+
* Build a `PgClientDirect` layer from a `PgClient` pool config. Same construction as
|
|
61
|
+
* `pooledLayer`; the two differ only in which endpoint the caller points them
|
|
62
|
+
* at (and that only matters on Neon).
|
|
63
|
+
*/
|
|
64
|
+
export declare const directLayer: (config: PgClient.PgPoolConfig) => Layer.Layer<PgClientDirect, SqlError.SqlError>;
|
|
65
|
+
export {};
|
|
66
|
+
//# sourceMappingURL=clients.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../../src/clients.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAEvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;;AAE1C;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,mBAGW;CAAG;;AAElD;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,mBAGW;CAAG;AAElD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,QAAQ,CAAC,YAAY,KAC5B,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,QAAQ,CAAC,QAAQ,CAG7C,CAAA;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,QAAQ,CAAC,YAAY,KAC5B,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,QAAQ,CAAC,QAAQ,CAG7C,CAAA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for a Postgres store instance.
|
|
4
|
+
*
|
|
5
|
+
* - `schema` — the Postgres schema that owns the store's objects (default
|
|
6
|
+
* `public`). `ensureSchema` creates it defensively.
|
|
7
|
+
* - `tablePrefix` — the base name for the store's tables/indexes/functions
|
|
8
|
+
* (default `dcb_events`). Two stores with different prefixes (or schemas)
|
|
9
|
+
* cohabit one database without interference.
|
|
10
|
+
* - `lockTimeout` — seconds passed to `set_config('lock_timeout', …, true)`
|
|
11
|
+
* inside every append, bounding how long a blocked writer waits on the
|
|
12
|
+
* exclusive lock. `0` (the default) means wait indefinitely — parity with the
|
|
13
|
+
* in-memory semaphore's unbounded wait, so the shared contract suite behaves
|
|
14
|
+
* identically across engines. A non-zero timeout that fires (`55P03`) is a
|
|
15
|
+
* Postgres-only outcome surfaced OFF the shared `append` contract (a defect),
|
|
16
|
+
* never as `AppendConditionFailed` — the in-memory oracle cannot produce it.
|
|
17
|
+
* - `pollInterval` — MILLISECONDS a live `subscribe` waits for a NOTIFY wake
|
|
18
|
+
* before re-reading from its cursor anyway, defaulting to core's
|
|
19
|
+
* `DEFAULT_POLL_INTERVAL_MILLIS`. Because this engine HAS a wake source, the
|
|
20
|
+
* value bounds worst-case live-tail latency rather than being it — only a
|
|
21
|
+
* subscriber no NOTIFY reaches waits the whole interval; lower it (e.g. in tests)
|
|
22
|
+
* to poll faster. See `packages/core/src/SubscribeMachine.ts` for what the poll
|
|
23
|
+
* guarantees and what a wake source is for.
|
|
24
|
+
* - `catchUpPageSize` — the `subscribe` reconcile page size, defaulting to core's
|
|
25
|
+
* `DEFAULT_CATCH_UP_PAGE_SIZE`: how many events a single catch-up/live read
|
|
26
|
+
* fetches before looping.
|
|
27
|
+
*/
|
|
28
|
+
export declare const PostgresStoreConfig: Schema.Struct<{
|
|
29
|
+
readonly pollInterval: Schema.optionalKey<Schema.Number>;
|
|
30
|
+
readonly catchUpPageSize: Schema.optionalKey<Schema.Int>;
|
|
31
|
+
readonly schema: Schema.optionalKey<Schema.String>;
|
|
32
|
+
readonly tablePrefix: Schema.optionalKey<Schema.String>;
|
|
33
|
+
readonly lockTimeout: Schema.optionalKey<Schema.Number>;
|
|
34
|
+
}>;
|
|
35
|
+
export type PostgresStoreConfig = typeof PostgresStoreConfig.Type;
|
|
36
|
+
/**
|
|
37
|
+
* Decode an unknown value into a validated `PostgresStoreConfig`, throwing a
|
|
38
|
+
* `SchemaError` on any violation. Used by `layer`/`ensureSchema` so a bad config
|
|
39
|
+
* fails at construction time.
|
|
40
|
+
*/
|
|
41
|
+
export declare const decodePostgresStoreConfig: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => {
|
|
42
|
+
readonly schema?: string;
|
|
43
|
+
readonly tablePrefix?: string;
|
|
44
|
+
readonly lockTimeout?: number;
|
|
45
|
+
readonly pollInterval?: number;
|
|
46
|
+
readonly catchUpPageSize?: number;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAiB/B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,mBAAmB;;;;;;EAiB/B,CAAA;AACD,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAC,IAAI,CAAA;AAEjE;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;;;;;;CACS,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ensureSchema` — the idempotent DDL migration building block (ADR-0002).
|
|
3
|
+
*
|
|
4
|
+
* This is deliberately NOT a migrator. It is a single `Effect<void, SqlError,
|
|
5
|
+
* SqlClient>` that creates (or refreshes) every object a store owns: both
|
|
6
|
+
* tables, both indexes, and both plpgsql functions. It requires the GENERIC
|
|
7
|
+
* `SqlClient` service — NOT `PgClientPooled` — precisely so a consumer can drop it
|
|
8
|
+
* straight into THEIR OWN migrator, e.g.:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* Migrator.fromRecord({
|
|
12
|
+
* '0001_kairos_store_dcb_events': ensureSchema(config),
|
|
13
|
+
* })
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* or simply run it once at boot. We ship no `FileSystem`/`Path`/`ChildProcess`
|
|
17
|
+
* dependency and no `PgMigrator`; migration ORCHESTRATION belongs to the
|
|
18
|
+
* consumer, this package only provides the idempotent PAYLOAD.
|
|
19
|
+
*
|
|
20
|
+
* Idempotence: every statement is `CREATE … IF NOT EXISTS` or `CREATE OR REPLACE
|
|
21
|
+
* FUNCTION`, so re-running it is safe. It is NOT a no-op across versions: a
|
|
22
|
+
* re-run replaces the append functions with this version's, and does NOT alter
|
|
23
|
+
* an existing table, so a column a newer version adds must be added by hand
|
|
24
|
+
* before the re-run (the release notes give the statement). A store whose
|
|
25
|
+
* table gained a column but whose functions were never replaced keeps writing
|
|
26
|
+
* through the old ones, which do not know the column. Names come from
|
|
27
|
+
* `sql(identifier)` (via the pre-quoted builder in `internal/ddl.ts`); the DDL
|
|
28
|
+
* bodies carry no bound values (pure schema), and the append functions keep
|
|
29
|
+
* their runtime VALUES as bound parameters, never interpolated.
|
|
30
|
+
*/
|
|
31
|
+
import { Effect } from 'effect';
|
|
32
|
+
import { SqlClient, type SqlError } from 'effect/sql';
|
|
33
|
+
import { type PostgresStoreConfig } from './config.js';
|
|
34
|
+
/**
|
|
35
|
+
* Produce the migration payload for `config`. Resolves the object names once and
|
|
36
|
+
* runs the ordered idempotent DDL against whatever `SqlClient` the caller's
|
|
37
|
+
* migrator (or boot code) provides.
|
|
38
|
+
*/
|
|
39
|
+
export declare const ensureSchema: (config: PostgresStoreConfig) => Effect.Effect<void, SqlError.SqlError, SqlClient.SqlClient>;
|
|
40
|
+
//# sourceMappingURL=ensureSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensureSchema.d.ts","sourceRoot":"","sources":["../../src/ensureSchema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAA6B,KAAK,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAG9E;;;;GAIG;AACH,eAAO,MAAM,YAAY,GACvB,QAAQ,mBAAmB,KAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,SAAS,CAQzD,CAAA"}
|