@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.
Files changed (86) hide show
  1. package/README.md +54 -29
  2. package/dist/cjs/clients.js +34 -24
  3. package/dist/cjs/clients.js.map +1 -1
  4. package/dist/cjs/config.js +9 -15
  5. package/dist/cjs/config.js.map +1 -1
  6. package/dist/cjs/ensureSchema.js +2 -2
  7. package/dist/cjs/ensureSchema.js.map +1 -1
  8. package/dist/cjs/index.js.map +1 -1
  9. package/dist/cjs/internal/matchSql.js +15 -4
  10. package/dist/cjs/internal/matchSql.js.map +1 -1
  11. package/dist/cjs/internal/readPlan.js +25 -1
  12. package/dist/cjs/internal/readPlan.js.map +1 -1
  13. package/dist/cjs/internal/transport.js +17 -13
  14. package/dist/cjs/internal/transport.js.map +1 -1
  15. package/dist/cjs/store.js +30 -25
  16. package/dist/cjs/store.js.map +1 -1
  17. package/dist/dts-cjs/clients.d.ts +66 -0
  18. package/dist/dts-cjs/clients.d.ts.map +1 -0
  19. package/dist/{dts → dts-cjs}/config.d.ts +9 -19
  20. package/dist/{dts → dts-cjs}/config.d.ts.map +1 -1
  21. package/dist/{dts → dts-cjs}/ensureSchema.d.ts +2 -2
  22. package/dist/dts-cjs/ensureSchema.d.ts.map +1 -0
  23. package/dist/{dts → dts-cjs}/index.d.ts +4 -3
  24. package/dist/dts-cjs/index.d.ts.map +1 -0
  25. package/dist/{dts → dts-cjs}/internal/ddl.d.ts +1 -1
  26. package/dist/{dts → dts-cjs}/internal/ddl.d.ts.map +1 -1
  27. package/dist/{dts → dts-cjs}/internal/matchSql.d.ts.map +1 -1
  28. package/dist/{dts → dts-cjs}/internal/readPlan.d.ts +1 -1
  29. package/dist/{dts → dts-cjs}/internal/readPlan.d.ts.map +1 -1
  30. package/dist/{dts → dts-cjs}/internal/transport.d.ts +20 -15
  31. package/dist/dts-cjs/internal/transport.d.ts.map +1 -0
  32. package/dist/dts-cjs/package.json +3 -0
  33. package/dist/dts-cjs/store.d.ts.map +1 -0
  34. package/dist/dts-esm/clients.d.ts +66 -0
  35. package/dist/dts-esm/clients.d.ts.map +1 -0
  36. package/dist/dts-esm/config.d.ts +48 -0
  37. package/dist/dts-esm/config.d.ts.map +1 -0
  38. package/dist/dts-esm/ensureSchema.d.ts +40 -0
  39. package/dist/dts-esm/ensureSchema.d.ts.map +1 -0
  40. package/dist/dts-esm/index.d.ts +42 -0
  41. package/dist/dts-esm/index.d.ts.map +1 -0
  42. package/dist/dts-esm/internal/ddl.d.ts +174 -0
  43. package/dist/dts-esm/internal/ddl.d.ts.map +1 -0
  44. package/dist/dts-esm/internal/matchSql.d.ts +164 -0
  45. package/dist/dts-esm/internal/matchSql.d.ts.map +1 -0
  46. package/dist/dts-esm/internal/readPlan.d.ts +72 -0
  47. package/dist/dts-esm/internal/readPlan.d.ts.map +1 -0
  48. package/dist/dts-esm/internal/transport.d.ts +131 -0
  49. package/dist/dts-esm/internal/transport.d.ts.map +1 -0
  50. package/dist/dts-esm/package.json +3 -0
  51. package/dist/dts-esm/store.d.ts +17 -0
  52. package/dist/dts-esm/store.d.ts.map +1 -0
  53. package/dist/esm/clients.js +34 -24
  54. package/dist/esm/clients.js.map +1 -1
  55. package/dist/esm/config.js +9 -15
  56. package/dist/esm/config.js.map +1 -1
  57. package/dist/esm/ensureSchema.js +2 -2
  58. package/dist/esm/ensureSchema.js.map +1 -1
  59. package/dist/esm/index.js +4 -3
  60. package/dist/esm/index.js.map +1 -1
  61. package/dist/esm/internal/matchSql.js +15 -4
  62. package/dist/esm/internal/matchSql.js.map +1 -1
  63. package/dist/esm/internal/readPlan.js +24 -1
  64. package/dist/esm/internal/readPlan.js.map +1 -1
  65. package/dist/esm/internal/transport.js +18 -14
  66. package/dist/esm/internal/transport.js.map +1 -1
  67. package/dist/esm/store.js +30 -25
  68. package/dist/esm/store.js.map +1 -1
  69. package/package.json +13 -11
  70. package/src/clients.ts +43 -31
  71. package/src/config.ts +12 -13
  72. package/src/ensureSchema.ts +2 -2
  73. package/src/index.ts +4 -3
  74. package/src/internal/ddl.ts +1 -1
  75. package/src/internal/matchSql.ts +15 -4
  76. package/src/internal/readPlan.ts +3 -2
  77. package/src/internal/transport.ts +28 -20
  78. package/src/store.ts +35 -28
  79. package/dist/dts/clients.d.ts +0 -34
  80. package/dist/dts/clients.d.ts.map +0 -1
  81. package/dist/dts/ensureSchema.d.ts.map +0 -1
  82. package/dist/dts/index.d.ts.map +0 -1
  83. package/dist/dts/internal/transport.d.ts.map +0 -1
  84. package/dist/dts/store.d.ts.map +0 -1
  85. /package/dist/{dts → dts-cjs}/internal/matchSql.d.ts +0 -0
  86. /package/dist/{dts → dts-cjs}/store.d.ts +0 -0
@@ -1,51 +1,61 @@
1
1
  /**
2
2
  * The TWO store-owned Postgres clients — the "Neon trap" mitigation (ADR-0002).
3
3
  *
4
- * `@effect/sql-pg` exposes a single `PgClient` (and `SqlClient`) tag; a
4
+ * `@effect/sql-pg` exposes a single `PgClient` (and `SqlClient`) service; a
5
5
  * `PgClient.layer` claims BOTH. If we built two `PgClient.layer`s they would
6
- * collide on that one tag — the second would shadow the first. So instead we
7
- * define two DISTINCT `Context.Tag`s, each HOLDING a `PgClient` value:
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
8
  *
9
9
  * - `PgClientPooled` — the pooled client used for reads, the append function,
10
- * and `notify`. Backed by a `pg.Pool`; connections are recycled per query.
10
+ * and `notify`. Its statements borrow a connection from the client's pool per
11
+ * query.
11
12
  * - `PgClientDirect` — a client used ONLY by `subscribe`'s `listen`. Its
12
- * built-in `listen` constructs a STANDALONE `pg.Client` from the pool's
13
- * `options`, inheriting the pool's host. On a Neon POOLED endpoint
14
- * (`…-pooler…`) that standalone connection lands on the PgBouncer front door,
15
- * which SILENTLY DROPS `LISTEN`/`NOTIFY` — the subscription would simply never
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
16
18
  * wake. Pointing `PgClientDirect` at Neon's DIRECT (non-pooler) endpoint fixes
17
19
  * it. `subscribe` is the ONLY method that touches `PgClientDirect`.
18
20
  *
19
- * For a plain (non-Neon) Postgres both tags point at the same URL; the split
20
- * costs nothing there. The two-tag design is what makes the Neon fix a
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
21
30
  * deployment-time wiring choice rather than a code change.
22
31
  */
23
- import { Reactivity } from '@effect/experimental';
24
32
  import { PgClient } from '@effect/sql-pg';
25
33
  import { Context, Layer } from 'effect';
34
+ import { Reactivity } from 'effect/reactivity';
26
35
  /**
27
- * The pooled client tag: reads, the append function, and `notify`. Holds a
36
+ * The pooled client service: reads, the append function, and `notify`. Holds a
28
37
  * `PgClient` value rather than being a `PgClient.layer`, so it never collides
29
- * with the direct client on the shared `PgClient`/`SqlClient` tag.
38
+ * with the direct client on the shared `PgClient`/`SqlClient` key.
30
39
  */
31
- export class PgClientPooled extends /*#__PURE__*/Context.Tag('@kairos-es/store-postgres/PgClientPooled')() {}
40
+ export class PgClientPooled extends /*#__PURE__*/Context.Service()('@kairos-es/store-postgres/PgClientPooled') {}
32
41
  /**
33
- * The direct (non-pooler) client tag: the `subscribe` listener ONLY. Point this
34
- * at a direct endpoint on Neon so `LISTEN`/`NOTIFY` is not dropped by the pooler.
42
+ * The direct (non-pooler) client service: the `subscribe` listener ONLY. Point
43
+ * this at a direct endpoint on Neon so `LISTEN`/`NOTIFY` is not dropped by the
44
+ * pooler.
35
45
  */
36
- export class PgClientDirect extends /*#__PURE__*/Context.Tag('@kairos-es/store-postgres/PgClientDirect')() {}
46
+ export class PgClientDirect extends /*#__PURE__*/Context.Service()('@kairos-es/store-postgres/PgClientDirect') {}
37
47
  /**
38
- * Build a `PgClientPooled` layer from a `PgClient` config. We construct the
39
- * client via `PgClient.make` (scoped) and place it in our OWN tag, then provide
40
- * `Reactivity.layer` (which `PgClient.make` requires) — exactly what the
48
+ * Build a `PgClientPooled` layer from a `PgClient` pool config. We construct the
49
+ * client via `PgClient.make` (scoped) and place it in our OWN service, then
50
+ * provide `Reactivity.layer` (which `PgClient.make` requires) — exactly what the
41
51
  * built-in `PgClient.layer` does internally, minus the collision-prone claim on
42
- * the shared `PgClient` tag.
52
+ * the shared `PgClient` key.
43
53
  */
44
- export const pooledLayer = config => Layer.scoped(PgClientPooled, PgClient.make(config)).pipe(Layer.provide(Reactivity.layer));
54
+ export const pooledLayer = config => Layer.effect(PgClientPooled, PgClient.make(config)).pipe(Layer.provide(Reactivity.layer));
45
55
  /**
46
- * Build a `PgClientDirect` layer from a `PgClient` config. Same construction as
56
+ * Build a `PgClientDirect` layer from a `PgClient` pool config. Same construction as
47
57
  * `pooledLayer`; the two differ only in which endpoint the caller points them
48
58
  * at (and that only matters on Neon).
49
59
  */
50
- export const directLayer = config => Layer.scoped(PgClientDirect, PgClient.make(config)).pipe(Layer.provide(Reactivity.layer));
60
+ export const directLayer = config => Layer.effect(PgClientDirect, PgClient.make(config)).pipe(Layer.provide(Reactivity.layer));
51
61
  //# sourceMappingURL=clients.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"clients.js","names":["Reactivity","PgClient","Context","Layer","PgClientPooled","Tag","PgClientDirect","pooledLayer","config","scoped","make","pipe","provide","layer","directLayer"],"sources":["../../src/clients.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;AAsBA,SAASA,UAAU,QAAQ,sBAAsB;AAEjD,SAASC,QAAQ,QAAQ,gBAAgB;AACzC,SAASC,OAAO,EAAEC,KAAK,QAAQ,QAAQ;AAEvC;;;;;AAKA,OAAM,MAAOC,cAAe,sBAAQF,OAAO,CAACG,GAAG,CAC7C,0CAA0C,CAC3C,EAAqC;AAEtC;;;;AAIA,OAAM,MAAOC,cAAe,sBAAQJ,OAAO,CAACG,GAAG,CAC7C,0CAA0C,CAC3C,EAAqC;AAEtC;;;;;;;AAOA,OAAO,MAAME,WAAW,GACtBC,MAA+B,IAE/BL,KAAK,CAACM,MAAM,CAACL,cAAc,EAAEH,QAAQ,CAACS,IAAI,CAACF,MAAM,CAAC,CAAC,CAACG,IAAI,CACtDR,KAAK,CAACS,OAAO,CAACZ,UAAU,CAACa,KAAK,CAAC,CAChC;AAEH;;;;;AAKA,OAAO,MAAMC,WAAW,GACtBN,MAA+B,IAE/BL,KAAK,CAACM,MAAM,CAACH,cAAc,EAAEL,QAAQ,CAACS,IAAI,CAACF,MAAM,CAAC,CAAC,CAACG,IAAI,CACtDR,KAAK,CAACS,OAAO,CAACZ,UAAU,CAACa,KAAK,CAAC,CAChC","ignoreList":[]}
1
+ {"version":3,"file":"clients.js","names":["PgClient","Context","Layer","Reactivity","PgClientPooled","Service","PgClientDirect","pooledLayer","config","effect","make","pipe","provide","layer","directLayer"],"sources":["../../src/clients.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,SAASA,QAAQ,QAAQ,gBAAgB;AACzC,SAASC,OAAO,EAAEC,KAAK,QAAQ,QAAQ;AACvC,SAASC,UAAU,QAAQ,mBAAmB;AAG9C;;;;;AAKA,OAAM,MAAOC,cAAe,sBAAQH,OAAO,CAACI,OAAO,EAGhD,CAAC,0CAA0C,CAAC;AAE/C;;;;;AAKA,OAAM,MAAOC,cAAe,sBAAQL,OAAO,CAACI,OAAO,EAGhD,CAAC,0CAA0C,CAAC;AAE/C;;;;;;;AAOA,OAAO,MAAME,WAAW,GACtBC,MAA6B,IAE7BN,KAAK,CAACO,MAAM,CAACL,cAAc,EAAEJ,QAAQ,CAACU,IAAI,CAACF,MAAM,CAAC,CAAC,CAACG,IAAI,CACtDT,KAAK,CAACU,OAAO,CAACT,UAAU,CAACU,KAAK,CAAC,CAChC;AAEH;;;;;AAKA,OAAO,MAAMC,WAAW,GACtBN,MAA6B,IAE7BN,KAAK,CAACO,MAAM,CAACH,cAAc,EAAEN,QAAQ,CAACU,IAAI,CAACF,MAAM,CAAC,CAAC,CAACG,IAAI,CACtDT,KAAK,CAACU,OAAO,CAACT,UAAU,CAACU,KAAK,CAAC,CAChC","ignoreList":[]}
@@ -27,7 +27,7 @@ import { oversizedIdentifier } from "./internal/ddl.js";
27
27
  * `sql(identifier)` dot-splits, so an embedded dot would silently re-partition
28
28
  * the name into the wrong schema/object.
29
29
  */
30
- const IdentifierAtom = /*#__PURE__*/Schema.String.pipe(/*#__PURE__*/Schema.nonEmptyString(), /*#__PURE__*/Schema.pattern(/^[^.]+$/, {
30
+ const IdentifierAtom = /*#__PURE__*/Schema.String.check(/*#__PURE__*/Schema.isNonEmpty(), /*#__PURE__*/Schema.isPattern(/^[^.]+$/, {
31
31
  identifier: 'PostgresIdentifierAtom',
32
32
  description: 'a non-empty identifier atom containing no "."'
33
33
  }));
@@ -58,30 +58,24 @@ const IdentifierAtom = /*#__PURE__*/Schema.String.pipe(/*#__PURE__*/Schema.nonEm
58
58
  * fetches before looping.
59
59
  */
60
60
  export const PostgresStoreConfig = /*#__PURE__*/Schema.Struct({
61
- // `exact: true` keeps the decoded type at `key?: T` (never `T | undefined`),
61
+ // `optionalKey` keeps the decoded type at `key?: T` (never `T | undefined`),
62
62
  // matching the repo's `exactOptionalPropertyTypes` discipline — an absent key,
63
63
  // not an explicit `undefined`.
64
- schema: Schema.optionalWith(IdentifierAtom, {
65
- exact: true
66
- }),
67
- tablePrefix: Schema.optionalWith(IdentifierAtom, {
68
- exact: true
69
- }),
70
- lockTimeout: Schema.optionalWith(Schema.Number.pipe(Schema.nonNegative(), Schema.finite()), {
71
- exact: true
72
- }),
64
+ schema: Schema.optionalKey(IdentifierAtom),
65
+ tablePrefix: Schema.optionalKey(IdentifierAtom),
66
+ lockTimeout: Schema.optionalKey(Schema.Number.check(Schema.isGreaterThanOrEqualTo(0), Schema.isFinite())),
73
67
  // The two subscribe knobs are core's field definitions, not this engine's: see
74
68
  // `subscriptionTuningFields`.
75
69
  ...subscriptionTuningFields
76
- }).pipe(
70
+ }).check(
77
71
  /*#__PURE__*/
78
72
  // Cross-field guard: the derived table/index/function/channel names must all
79
73
  // fit Postgres's 63-byte identifier limit. Returning the message string fails
80
- // the decode with it; `undefined`/`true` passes.
81
- Schema.filter(config => oversizedIdentifier(config) ?? true));
74
+ // the decode with it; `undefined` passes.
75
+ Schema.makeFilter(config => oversizedIdentifier(config)));
82
76
  /**
83
77
  * Decode an unknown value into a validated `PostgresStoreConfig`, throwing a
84
- * `ParseError` on any violation. Used by `layer`/`ensureSchema` so a bad config
78
+ * `SchemaError` on any violation. Used by `layer`/`ensureSchema` so a bad config
85
79
  * fails at construction time.
86
80
  */
87
81
  export const decodePostgresStoreConfig = /*#__PURE__*/Schema.decodeUnknownSync(PostgresStoreConfig);
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":["subscriptionTuningFields","Schema","oversizedIdentifier","IdentifierAtom","String","pipe","nonEmptyString","pattern","identifier","description","PostgresStoreConfig","Struct","schema","optionalWith","exact","tablePrefix","lockTimeout","Number","nonNegative","finite","filter","config","decodePostgresStoreConfig","decodeUnknownSync"],"sources":["../../src/config.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;AAoBA,SAASA,wBAAwB,QAAQ,iBAAiB;AAC1D,SAASC,MAAM,QAAQ,QAAQ;AAC/B,SAASC,mBAAmB,QAAQ,mBAAgB;AAEpD;;;;;;AAMA,MAAMC,cAAc,gBAAGF,MAAM,CAACG,MAAM,CAACC,IAAI,cACvCJ,MAAM,CAACK,cAAc,EAAE,eACvBL,MAAM,CAACM,OAAO,CAAC,SAAS,EAAE;EACxBC,UAAU,EAAE,wBAAwB;EACpCC,WAAW,EAAE;CACd,CAAC,CACH;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,OAAO,MAAMC,mBAAmB,gBAAGT,MAAM,CAACU,MAAM,CAAC;EAC/C;EACA;EACA;EACAC,MAAM,EAAEX,MAAM,CAACY,YAAY,CAACV,cAAc,EAAE;IAAEW,KAAK,EAAE;EAAI,CAAE,CAAC;EAC5DC,WAAW,EAAEd,MAAM,CAACY,YAAY,CAACV,cAAc,EAAE;IAAEW,KAAK,EAAE;EAAI,CAAE,CAAC;EACjEE,WAAW,EAAEf,MAAM,CAACY,YAAY,CAC9BZ,MAAM,CAACgB,MAAM,CAACZ,IAAI,CAACJ,MAAM,CAACiB,WAAW,EAAE,EAAEjB,MAAM,CAACkB,MAAM,EAAE,CAAC,EACzD;IAAEL,KAAK,EAAE;EAAI,CAAE,CAChB;EACD;EACA;EACA,GAAGd;CACJ,CAAC,CAACK,IAAI;AAAA;AACL;AACA;AACA;AACAJ,MAAM,CAACmB,MAAM,CAAEC,MAAM,IAAKnB,mBAAmB,CAACmB,MAAM,CAAC,IAAI,IAAI,CAAC,CAC/D;AAGD;;;;;AAKA,OAAO,MAAMC,yBAAyB,gBACpCrB,MAAM,CAACsB,iBAAiB,CAACb,mBAAmB,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"config.js","names":["subscriptionTuningFields","Schema","oversizedIdentifier","IdentifierAtom","String","check","isNonEmpty","isPattern","identifier","description","PostgresStoreConfig","Struct","schema","optionalKey","tablePrefix","lockTimeout","Number","isGreaterThanOrEqualTo","isFinite","makeFilter","config","decodePostgresStoreConfig","decodeUnknownSync"],"sources":["../../src/config.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;AAoBA,SAASA,wBAAwB,QAAQ,iBAAiB;AAC1D,SAASC,MAAM,QAAQ,QAAQ;AAC/B,SAASC,mBAAmB,QAAQ,mBAAgB;AAEpD;;;;;;AAMA,MAAMC,cAAc,gBAAGF,MAAM,CAACG,MAAM,CAACC,KAAK,cACxCJ,MAAM,CAACK,UAAU,EAAE,eACnBL,MAAM,CAACM,SAAS,CAAC,SAAS,EAAE;EAC1BC,UAAU,EAAE,wBAAwB;EACpCC,WAAW,EAAE;CACd,CAAC,CACH;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,OAAO,MAAMC,mBAAmB,gBAAGT,MAAM,CAACU,MAAM,CAAC;EAC/C;EACA;EACA;EACAC,MAAM,EAAEX,MAAM,CAACY,WAAW,CAACV,cAAc,CAAC;EAC1CW,WAAW,EAAEb,MAAM,CAACY,WAAW,CAACV,cAAc,CAAC;EAC/CY,WAAW,EAAEd,MAAM,CAACY,WAAW,CAC7BZ,MAAM,CAACe,MAAM,CAACX,KAAK,CAACJ,MAAM,CAACgB,sBAAsB,CAAC,CAAC,CAAC,EAAEhB,MAAM,CAACiB,QAAQ,EAAE,CAAC,CACzE;EACD;EACA;EACA,GAAGlB;CACJ,CAAC,CAACK,KAAK;AAAA;AACN;AACA;AACA;AACAJ,MAAM,CAACkB,UAAU,CAAEC,MAAM,IAAKlB,mBAAmB,CAACkB,MAAM,CAAC,CAAC,CAC3D;AAGD;;;;;AAKA,OAAO,MAAMC,yBAAyB,gBACpCpB,MAAM,CAACqB,iBAAiB,CAACZ,mBAAmB,CAAC","ignoreList":[]}
@@ -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` tag — NOT `PgClientPooled` — precisely so a consumer can drop it
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 } from '@effect/sql';
32
31
  import { Effect } from 'effect';
32
+ import { SqlClient } from 'effect/sql';
33
33
  import { decodePostgresStoreConfig } from "./config.js";
34
34
  import { resolveNames, runDdl } from "./internal/ddl.js";
35
35
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ensureSchema.js","names":["SqlClient","Effect","decodePostgresStoreConfig","resolveNames","runDdl","ensureSchema","config","gen","sql","names","all","discard"],"sources":["../../src/ensureSchema.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAASA,SAAS,QAAuB,aAAa;AACtD,SAASC,MAAM,QAAQ,QAAQ;AAC/B,SAASC,yBAAyB,QAAkC,aAAU;AAC9E,SAASC,YAAY,EAAEC,MAAM,QAAQ,mBAAgB;AAErD;;;;;AAKA,OAAO,MAAMC,YAAY,GACvBC,MAA2B,IAE3BL,MAAM,CAACM,GAAG,CAAC,aAAS;EAClB,MAAMC,GAAG,GAAG,OAAOR,SAAS,CAACA,SAAS;EACtC;EACA;EACA,MAAMS,KAAK,GAAGN,YAAY,CAACD,yBAAyB,CAACI,MAAM,CAAC,CAAC;EAC7D;EACA,OAAOL,MAAM,CAACS,GAAG,CAACN,MAAM,CAACI,GAAG,EAAEC,KAAK,CAAC,EAAE;IAAEE,OAAO,EAAE;EAAI,CAAE,CAAC;AAC1D,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"ensureSchema.js","names":["Effect","SqlClient","decodePostgresStoreConfig","resolveNames","runDdl","ensureSchema","config","gen","sql","names","all","discard"],"sources":["../../src/ensureSchema.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAASA,MAAM,QAAQ,QAAQ;AAC/B,SAASC,SAAS,QAAuB,YAAY;AACrD,SAASC,yBAAyB,QAAkC,aAAU;AAC9E,SAASC,YAAY,EAAEC,MAAM,QAAQ,mBAAgB;AAErD;;;;;AAKA,OAAO,MAAMC,YAAY,GACvBC,MAA2B,IAE3BN,MAAM,CAACO,GAAG,CAAC,aAAS;EAClB,MAAMC,GAAG,GAAG,OAAOP,SAAS,CAACA,SAAS;EACtC;EACA;EACA,MAAMQ,KAAK,GAAGN,YAAY,CAACD,yBAAyB,CAACI,MAAM,CAAC,CAAC;EAC7D;EACA,OAAON,MAAM,CAACU,GAAG,CAACN,MAAM,CAACI,GAAG,EAAEC,KAAK,CAAC,EAAE;IAAEE,OAAO,EAAE;EAAI,CAAE,CAAC;AAC1D,CAAC,CAAC","ignoreList":[]}
package/dist/esm/index.js CHANGED
@@ -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 tags and
34
- * assumes `ensureSchema` has run. `ensureSchema` requires the generic `SqlClient`
35
- * tag so it slots into any migrator; the runtime uses the store-owned tags.
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 { ensureSchema } from "./ensureSchema.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["directLayer","PgClientDirect","PgClientPooled","pooledLayer","ensureSchema","layer"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SACEA,WAAW,EACXC,cAAc,EACdC,cAAc,EACdC,WAAW,QACN,cAAW;AAElB,SAASC,YAAY,QAAQ,mBAAgB;AAC7C,SAASC,KAAK,QAAQ,YAAS","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["directLayer","PgClientDirect","PgClientPooled","pooledLayer","ensureSchema","layer"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,SACEA,WAAW,EACXC,cAAc,EACdC,cAAc,EACdC,WAAW,QACN,cAAW;AAElB,SAASC,YAAY,QAAQ,mBAAgB;AAC7C,SAASC,KAAK,QAAQ,YAAS","ignoreList":[]}
@@ -59,9 +59,20 @@ export const RECORDSET_ALIAS = 'ne';
59
59
  * Typed as a `Record` over `EventColumnName` so that adding a column to
60
60
  * `EVENT_COLUMNS` without saying where its value comes from is a COMPILE error,
61
61
  * rather than a column the insert silently leaves at its default. Every column but
62
- * `data` passes through as the recordset already types it — `text[]` tags,
63
- * `timestamptz`, `jsonb` metadata — because `jsonb_to_recordset` did the casting;
64
- * `data` crosses as base64 TEXT and is restored to `bytea` here, its one decode.
62
+ * `data` and `metadata` passes through as the recordset already types it — `text[]`
63
+ * tags, `timestamptz` — because `jsonb_to_recordset` did the casting; `data`
64
+ * crosses as base64 TEXT and is restored to `bytea` here, its one decode.
65
+ *
66
+ * `metadata` is wrapped in `COALESCE(…, '{}'::jsonb)`, for a caller this package's
67
+ * own client never is. `ensureSchema` replaces each append function with
68
+ * `CREATE OR REPLACE`, which keeps its argument signature, so a client from before
69
+ * the column existed (`1.0.0-alpha.3` and earlier) goes on calling the current body
70
+ * with events JSON that has no `metadata` key. `jsonb_to_recordset` reads an absent
71
+ * key as `NULL`, and an insert that names the column inserts that `NULL` rather than
72
+ * the column's `DEFAULT`, so `NOT NULL` would refuse every such append. The
73
+ * `COALESCE` gives that row the empty bag the `DEFAULT` would have, which is what
74
+ * makes "migrate, then deploy" a safe order from those versions. An event sent WITH
75
+ * a bag passes through unchanged, so what is stored for it does not move.
65
76
  */
66
77
  const EVENT_COLUMN_SOURCE = {
67
78
  type: `${RECORDSET_ALIAS}.type`,
@@ -69,7 +80,7 @@ const EVENT_COLUMN_SOURCE = {
69
80
  tags: `${RECORDSET_ALIAS}.tags`,
70
81
  uuid: `${RECORDSET_ALIAS}.uuid`,
71
82
  occurred_at: `${RECORDSET_ALIAS}.occurred_at`,
72
- metadata: `${RECORDSET_ALIAS}.metadata`
83
+ metadata: `COALESCE(${RECORDSET_ALIAS}.metadata, '{}'::jsonb)`
73
84
  };
74
85
  /**
75
86
  * The bare event column names — `type, data, tags, uuid, occurred_at, metadata` —
@@ -1 +1 @@
1
- {"version":3,"file":"matchSql.js","names":["EVENT_COLUMNS","eventRecordsetColumns","map","name","type","join","readColumns","prefix","RECORDSET_ALIAS","EVENT_COLUMN_SOURCE","data","tags","uuid","occurred_at","metadata","eventColumnList","eventInsertSelectList","allowedTypesPredicate","typesCol","taggedMatchChain","tokens","queryItemsExpr","tag","afterExpr","qualifiedRows","main","wildcardReadSql","typeOnlyReadSql","taggedReadSql"],"sources":["../../../src/internal/matchSql.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"matchSql.js","names":["EVENT_COLUMNS","eventRecordsetColumns","map","name","type","join","readColumns","prefix","RECORDSET_ALIAS","EVENT_COLUMN_SOURCE","data","tags","uuid","occurred_at","metadata","eventColumnList","eventInsertSelectList","allowedTypesPredicate","typesCol","taggedMatchChain","tokens","queryItemsExpr","tag","afterExpr","qualifiedRows","main","wildcardReadSql","typeOnlyReadSql","taggedReadSql"],"sources":["../../../src/internal/matchSql.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -1,3 +1,26 @@
1
+ /**
2
+ * The read-plan compiler for the Postgres engine, extracted from `store.ts` so it
3
+ * is a self-contained unit depending only on the PRE-QUOTED table names — never on
4
+ * the SQL clients. `store.ts`'s `read` and its `subscribe` — the latter feeding the
5
+ * plan to core's subscribe machine as that machine's `fetch` seam — both compile a
6
+ * plan here and run it against whichever client they hold.
7
+ *
8
+ * `compileFetchPlan` turns a servable `Query` into prepared SQL text plus a
9
+ * cursor-only `bind`, so a long-lived subscription re-binds only the cursor rather
10
+ * than re-dispatching the shape and re-serialising the query JSON on every poll.
11
+ * Which shape a query IS is not decided here: core's `classifyServableQuery` owns
12
+ * that dispatch beside the grammar it dispatches over (`Query.ts`), including the
13
+ * degenerate empty item's routing. The JSON/JSONB transport shapes and
14
+ * (de)serialisers — `EventRow`, `jsonbText`, `toQueryItemsJson`, `rowToSequenced`
15
+ * — live in `internal/transport.ts`, and this module only compiles plans.
16
+ *
17
+ * A plan compiled here is therefore the one place the Postgres engine dispatches
18
+ * a shape in TypeScript, and the exhaustiveness below protects BOTH verbs that
19
+ * compile one — `read`, and the `subscribe` poll sharing its plan. What it cannot
20
+ * reach is the append: its conflict guard covers the same three shapes inside its
21
+ * plpgsql body, where no compiler follows, and `ddl.ts` owns what that rests on
22
+ * instead.
23
+ */
1
24
  import { classifyServableQuery, ORIGIN } from '@kairos-es/core';
2
25
  import { taggedReadSql, typeOnlyReadSql, wildcardReadSql } from "./matchSql.js";
3
26
  import { jsonbText, toQueryItemsJson } from "./transport.js";
@@ -29,7 +52,7 @@ export const compileFetchPlan = (tables, query) => {
29
52
  };
30
53
  case 'typeOnly':
31
54
  {
32
- // node-postgres binds a JS array param as a Postgres array literal, so
55
+ // `@effect/sql-pg` binds a JS array of strings as a `text[]` param, so
33
56
  // `type = ANY($2)` matches any of the item's types. A branded `EventType` IS
34
57
  // its string to the driver, so nothing has to be unwrapped — but the list is
35
58
  // COPIED here, at compile time. The driver serialises the array afresh on
@@ -1 +1 @@
1
- {"version":3,"file":"readPlan.js","names":["classifyServableQuery","ORIGIN","taggedReadSql","typeOnlyReadSql","wildcardReadSql","jsonbText","toQueryItemsJson","compileFetchPlan","tables","query","shape","kind","text","main","bind","after","limit","types","itemsJson","tag","runFetch","sql","plan","unsafe"],"sources":["../../../src/internal/readPlan.ts"],"sourcesContent":[null],"mappings":"AAyBA,SAASA,qBAAqB,EAAEC,MAAM,QAAoB,iBAAiB;AAE3E,SAASC,aAAa,EAAEC,eAAe,EAAEC,eAAe,QAAQ,eAAY;AAC5E,SAAwBC,SAAS,EAAEC,gBAAgB,QAAQ,gBAAa;AA0BxE;;;;;;;;;;;;;;;;;;AAkBA,OAAO,MAAMC,gBAAgB,GAAGA,CAC9BC,MAAkB,EAClBC,KAAY,KACC;EACb,MAAMC,KAAK,GAAGV,qBAAqB,CAACS,KAAK,CAAC;EAC1C,QAAQC,KAAK,CAACC,IAAI;IAChB,KAAK,UAAU;MACb,OAAO;QACLC,IAAI,EAAER,eAAe,CAACI,MAAM,CAACK,IAAI,CAAC;QAClCC,IAAI,EAAEA,CAACC,KAAK,EAAEC,KAAK,KAAK,CAACD,KAAK,EAAEC,KAAK;OACtC;IACH,KAAK,UAAU;MAAE;QACf;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,MAAMC,KAAK,GAAG,CAAC,GAAGP,KAAK,CAACO,KAAK,CAAC;QAC9B,OAAO;UACLL,IAAI,EAAET,eAAe,CAACK,MAAM,CAACK,IAAI,CAAC;UAClCC,IAAI,EAAEA,CAACC,KAAK,EAAEC,KAAK,KAAK,CAACD,KAAK,EAAEE,KAAK,EAAED,KAAK;SAC7C;MACH;IACA,KAAK,QAAQ;MAAE;QACb;QACA;QACA,MAAME,SAAS,GAAGb,SAAS,CAACC,gBAAgB,CAACG,KAAK,CAAC,CAAC;QACpD,OAAO;UACLG,IAAI,EAAEV,aAAa,CAACM,MAAM,CAACK,IAAI,EAAEL,MAAM,CAACW,GAAG,CAAC;UAC5CL,IAAI,EAAEA,CAACC,KAAK,EAAEC,KAAK,KAAK,CAACE,SAAS,EAAEH,KAAK,EAAEC,KAAK;SACjD;MACH;EACF;AACF,CAAC;AAED;;;;AAIA,OAAO,MAAMI,QAAQ,GAAGA,CACtBC,GAAwB,EACxBC,IAAe,EACfP,KAA2B,EAC3BC,KAA4B,KAE5BK,GAAG,CAACE,MAAM,CAAWD,IAAI,CAACV,IAAI,EAAEU,IAAI,CAACR,IAAI,CAACC,KAAK,IAAId,MAAM,EAAEe,KAAK,IAAI,IAAI,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"readPlan.js","names":["classifyServableQuery","ORIGIN","taggedReadSql","typeOnlyReadSql","wildcardReadSql","jsonbText","toQueryItemsJson","compileFetchPlan","tables","query","shape","kind","text","main","bind","after","limit","types","itemsJson","tag","runFetch","sql","plan","unsafe"],"sources":["../../../src/internal/readPlan.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAASA,qBAAqB,EAAEC,MAAM,QAAoB,iBAAiB;AAG3E,SAASC,aAAa,EAAEC,eAAe,EAAEC,eAAe,QAAQ,eAAY;AAC5E,SAAwBC,SAAS,EAAEC,gBAAgB,QAAQ,gBAAa;AA0BxE;;;;;;;;;;;;;;;;;;AAkBA,OAAO,MAAMC,gBAAgB,GAAGA,CAC9BC,MAAkB,EAClBC,KAAY,KACC;EACb,MAAMC,KAAK,GAAGV,qBAAqB,CAACS,KAAK,CAAC;EAC1C,QAAQC,KAAK,CAACC,IAAI;IAChB,KAAK,UAAU;MACb,OAAO;QACLC,IAAI,EAAER,eAAe,CAACI,MAAM,CAACK,IAAI,CAAC;QAClCC,IAAI,EAAEA,CAACC,KAAK,EAAEC,KAAK,KAAK,CAACD,KAAK,EAAEC,KAAK;OACtC;IACH,KAAK,UAAU;MAAE;QACf;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,MAAMC,KAAK,GAAG,CAAC,GAAGP,KAAK,CAACO,KAAK,CAAC;QAC9B,OAAO;UACLL,IAAI,EAAET,eAAe,CAACK,MAAM,CAACK,IAAI,CAAC;UAClCC,IAAI,EAAEA,CAACC,KAAK,EAAEC,KAAK,KAAK,CAACD,KAAK,EAAEE,KAAK,EAAED,KAAK;SAC7C;MACH;IACA,KAAK,QAAQ;MAAE;QACb;QACA;QACA,MAAME,SAAS,GAAGb,SAAS,CAACC,gBAAgB,CAACG,KAAK,CAAC,CAAC;QACpD,OAAO;UACLG,IAAI,EAAEV,aAAa,CAACM,MAAM,CAACK,IAAI,EAAEL,MAAM,CAACW,GAAG,CAAC;UAC5CL,IAAI,EAAEA,CAACC,KAAK,EAAEC,KAAK,KAAK,CAACE,SAAS,EAAEH,KAAK,EAAEC,KAAK;SACjD;MACH;EACF;AACF,CAAC;AAED;;;;AAIA,OAAO,MAAMI,QAAQ,GAAGA,CACtBC,GAAwB,EACxBC,IAAe,EACfP,KAA2B,EAC3BC,KAA4B,KAE5BK,GAAG,CAACE,MAAM,CAAWD,IAAI,CAACV,IAAI,EAAEU,IAAI,CAACR,IAAI,CAACC,KAAK,IAAId,MAAM,EAAEe,KAAK,IAAI,IAAI,CAAC,CAAC","ignoreList":[]}
@@ -1,16 +1,18 @@
1
- import { DateTime, Encoding } from 'effect';
1
+ import { DateTime } from 'effect';
2
+ import { Base64 } from 'effect/encoding';
2
3
  /**
3
4
  * Serialise a value to a JSON STRING for transport as a `::jsonb`-cast bound
4
5
  * parameter.
5
6
  *
6
- * WHY not `sql.json(value)`: `@effect/sql-pg`'s `json` helper binds the RAW
7
- * value, and node-postgres serialises a JS *array* bound param as a Postgres
8
- * ARRAY literal (`{…}`), not JSON — so `sql.json([...])::jsonb` fails with a
9
- * `22P02` invalid-JSON error (an array literal is not valid JSON). Passing a
10
- * pre-stringified JSON string and casting `::jsonb` sends plain text that
11
- * Postgres parses as JSON, which round-trips reliably for both objects and
12
- * arrays. Kept as a named helper so every JSON-transport call site is consistent
13
- * and the reasoning lives in one place.
7
+ * WHY a string and not `sql.json(value)`: the read plan runs through
8
+ * `sql.unsafe(text, params)` with POSITIONAL parameters, and a positional
9
+ * parameter must be a plain scalar or a flat array of scalars — `@effect/sql-pg`
10
+ * cannot infer a Postgres type for an object or an array of objects, and a
11
+ * `sql.json` fragment is not a value that list can carry. A pre-stringified
12
+ * JSON string binds untyped and the `::jsonb` cast has Postgres parse it, which
13
+ * round-trips reliably for both objects and arrays on the positional path and
14
+ * the tagged-template path alike. Kept as a named helper so every
15
+ * JSON-transport call site is consistent and the reasoning lives in one place.
14
16
  */
15
17
  export const jsonbText = value => JSON.stringify(value);
16
18
  /** Serialise a `Query`'s items into their transport JSON shape. */
@@ -21,9 +23,11 @@ export const toQueryItemsJson = query => query.items.map(item => ({
21
23
  /** Serialise one core `DcbEvent` into its transport JSON shape. */
22
24
  export const toEventJson = event => ({
23
25
  type: event.type,
24
- // `Encoding.encodeBase64` (from `effect`) keeps this dependency-free and pure
25
- // — no `Buffer`, so no `@types/node` and no browser/runtime coupling.
26
- data: Encoding.encodeBase64(event.data),
26
+ // `Base64.encode` (from `effect/encoding`) keeps this dependency-free and pure
27
+ // — no `Buffer`, so no `@types/node` and no browser/runtime coupling. It emits
28
+ // the standard RFC 4648 alphabet with `=` padding, which is what plpgsql's
29
+ // `decode(…, 'base64')` reads.
30
+ data: Base64.encode(event.data),
27
31
  tags: [...event.tags],
28
32
  uuid: event.uuid,
29
33
  occurred_at: DateTime.formatIso(event.occurredAt),
@@ -50,7 +54,7 @@ const metadataFrom = value => {
50
54
  /**
51
55
  * Map a raw main-table row to a core `SequencedEvent`. `data` NULL → empty bytes
52
56
  * (a payload-less event round-trips to a zero-length `Uint8Array`); `occurred_at`
53
- * Date → `DateTime.Utc`; `id` string → branded `Position`; `metadata` through
57
+ * Date → `DateTime.Utc`; `id` → branded `Position`; `metadata` through
54
58
  * `metadataFrom`. The column is `NOT NULL DEFAULT '{}'`, so there is no absent
55
59
  * case to reconcile: an event appended with an empty bag reads back as `{}` on
56
60
  * this engine exactly as on the in-memory oracle.
@@ -71,7 +75,7 @@ export const rowToSequenced = row => ({
71
75
  data: row.data ?? new Uint8Array(0),
72
76
  tags: row.tags,
73
77
  uuid: row.uuid,
74
- occurredAt: DateTime.unsafeFromDate(row.occurred_at),
78
+ occurredAt: DateTime.fromDateUnsafe(row.occurred_at),
75
79
  metadata: metadataFrom(row.metadata)
76
80
  },
77
81
  position: BigInt(row.id)
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","names":["DateTime","Encoding","jsonbText","value","JSON","stringify","toQueryItemsJson","query","items","map","item","types","tags","toEventJson","event","type","data","encodeBase64","uuid","occurred_at","formatIso","occurredAt","metadata","metadataFrom","Array","isArray","Error","rowToSequenced","row","Uint8Array","unsafeFromDate","position","BigInt","id"],"sources":["../../../src/internal/transport.ts"],"sourcesContent":[null],"mappings":"AA4BA,SAASA,QAAQ,EAAEC,QAAQ,QAAQ,QAAQ;AAG3C;;;;;;;;;;;;;AAaA,OAAO,MAAMC,SAAS,GAAIC,KAAc,IAAaC,IAAI,CAACC,SAAS,CAACF,KAAK,CAAC;AAQ1E;AACA,OAAO,MAAMG,gBAAgB,GAAIC,KAAY,IAC3CA,KAAK,CAACC,KAAK,CAACC,GAAG,CAAEC,IAAI,KAAM;EACzBC,KAAK,EAAE,CAAC,GAAGD,IAAI,CAACC,KAAK,CAAC;EACtBC,IAAI,EAAE,CAAC,GAAGF,IAAI,CAACE,IAAI;CACpB,CAAC,CAAC;AA+BL;AACA,OAAO,MAAMC,WAAW,GAAIC,KAAe,KAAiB;EAC1DC,IAAI,EAAED,KAAK,CAACC,IAAI;EAChB;EACA;EACAC,IAAI,EAAEf,QAAQ,CAACgB,YAAY,CAACH,KAAK,CAACE,IAAI,CAAC;EACvCJ,IAAI,EAAE,CAAC,GAAGE,KAAK,CAACF,IAAI,CAAC;EACrBM,IAAI,EAAEJ,KAAK,CAACI,IAAI;EAChBC,WAAW,EAAEnB,QAAQ,CAACoB,SAAS,CAACN,KAAK,CAACO,UAAU,CAAC;EACjDC,QAAQ,EAAER,KAAK,CAACQ;CACjB,CAAC;AAgCF;;;;;;;;;;;;AAYA,MAAMC,YAAY,GAAIpB,KAAc,IAAc;EAChD,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,KAAK,IAAI,IAAIqB,KAAK,CAACC,OAAO,CAACtB,KAAK,CAAC,EAAE;IACvE,MAAM,IAAIuB,KAAK,CACb,sFAAsFtB,IAAI,CAACC,SAAS,CAACF,KAAK,CAAC,IAAI,CAChH;EACH;EACA,OAAOA,KAAiB;AAC1B,CAAC;AAED;;;;;;;;;;;;;;;;;;AAkBA,OAAO,MAAMwB,cAAc,GAAIC,GAAa,KAAsB;EAChEd,KAAK,EAAE;IACLC,IAAI,EAAEa,GAAG,CAACb,IAAwB;IAClCC,IAAI,EAAEY,GAAG,CAACZ,IAAI,IAAI,IAAIa,UAAU,CAAC,CAAC,CAAC;IACnCjB,IAAI,EAAEgB,GAAG,CAAChB,IAAmC;IAC7CM,IAAI,EAAEU,GAAG,CAACV,IAAwB;IAClCG,UAAU,EAAErB,QAAQ,CAAC8B,cAAc,CAACF,GAAG,CAACT,WAAW,CAAC;IACpDG,QAAQ,EAAEC,YAAY,CAACK,GAAG,CAACN,QAAQ;GACpC;EACDS,QAAQ,EAAEC,MAAM,CAACJ,GAAG,CAACK,EAAE;CACxB,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"transport.js","names":["DateTime","Base64","jsonbText","value","JSON","stringify","toQueryItemsJson","query","items","map","item","types","tags","toEventJson","event","type","data","encode","uuid","occurred_at","formatIso","occurredAt","metadata","metadataFrom","Array","isArray","Error","rowToSequenced","row","Uint8Array","fromDateUnsafe","position","BigInt","id"],"sources":["../../../src/internal/transport.ts"],"sourcesContent":[null],"mappings":"AA4BA,SAASA,QAAQ,QAAQ,QAAQ;AACjC,SAASC,MAAM,QAAQ,iBAAiB;AAGxC;;;;;;;;;;;;;;AAcA,OAAO,MAAMC,SAAS,GAAIC,KAAc,IAAaC,IAAI,CAACC,SAAS,CAACF,KAAK,CAAC;AAQ1E;AACA,OAAO,MAAMG,gBAAgB,GAAIC,KAAY,IAC3CA,KAAK,CAACC,KAAK,CAACC,GAAG,CAAEC,IAAI,KAAM;EACzBC,KAAK,EAAE,CAAC,GAAGD,IAAI,CAACC,KAAK,CAAC;EACtBC,IAAI,EAAE,CAAC,GAAGF,IAAI,CAACE,IAAI;CACpB,CAAC,CAAC;AA+BL;AACA,OAAO,MAAMC,WAAW,GAAIC,KAAe,KAAiB;EAC1DC,IAAI,EAAED,KAAK,CAACC,IAAI;EAChB;EACA;EACA;EACA;EACAC,IAAI,EAAEf,MAAM,CAACgB,MAAM,CAACH,KAAK,CAACE,IAAI,CAAC;EAC/BJ,IAAI,EAAE,CAAC,GAAGE,KAAK,CAACF,IAAI,CAAC;EACrBM,IAAI,EAAEJ,KAAK,CAACI,IAAI;EAChBC,WAAW,EAAEnB,QAAQ,CAACoB,SAAS,CAACN,KAAK,CAACO,UAAU,CAAC;EACjDC,QAAQ,EAAER,KAAK,CAACQ;CACjB,CAAC;AAoCF;;;;;;;;;;;;AAYA,MAAMC,YAAY,GAAIpB,KAAc,IAAc;EAChD,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,KAAK,IAAI,IAAIqB,KAAK,CAACC,OAAO,CAACtB,KAAK,CAAC,EAAE;IACvE,MAAM,IAAIuB,KAAK,CACb,sFAAsFtB,IAAI,CAACC,SAAS,CAACF,KAAK,CAAC,IAAI,CAChH;EACH;EACA,OAAOA,KAAiB;AAC1B,CAAC;AAED;;;;;;;;;;;;;;;;;;AAkBA,OAAO,MAAMwB,cAAc,GAAIC,GAAa,KAAsB;EAChEd,KAAK,EAAE;IACLC,IAAI,EAAEa,GAAG,CAACb,IAAwB;IAClCC,IAAI,EAAEY,GAAG,CAACZ,IAAI,IAAI,IAAIa,UAAU,CAAC,CAAC,CAAC;IACnCjB,IAAI,EAAEgB,GAAG,CAAChB,IAAmC;IAC7CM,IAAI,EAAEU,GAAG,CAACV,IAAwB;IAClCG,UAAU,EAAErB,QAAQ,CAAC8B,cAAc,CAACF,GAAG,CAACT,WAAW,CAAC;IACpDG,QAAQ,EAAEC,YAAY,CAACK,GAAG,CAACN,QAAQ;GACpC;EACDS,QAAQ,EAAEC,MAAM,CAACJ,GAAG,CAACK,EAAE;CACxB,CAAC","ignoreList":[]}
package/dist/esm/store.js CHANGED
@@ -46,15 +46,19 @@ const make = (config, names) => Effect.gen(function* () {
46
46
  * Nor would such a parameter be load-bearing for the REPEATABLE READ
47
47
  * transaction this runs inside, which is the trap worth naming, since a
48
48
  * closed-over client LOOKS like it must escape to its own snapshot.
49
- * `@effect/sql` resolves a statement's connection when the statement RUNS,
50
- * from the FIBRE CONTEXT rather than from the client value: `withTransaction`
51
- * acquires one connection and `Effect.locally`s it into
52
- * `FiberRef.currentContext` under its `TransactionConnection` tag, and every
53
- * statement a client builds resolves through a `getConnection` that reads
54
- * that tag first, falling back to the pool acquirer only when it is absent
55
- * (`@effect/sql@0.52` `src/internal/client.ts`). A statement therefore joins
56
- * a transaction by being RUN inside it, and passing the client along the call
57
- * chain neither adds to that nor is required by it. `read-postgres`'s
49
+ * `effect/sql` resolves a statement's connection when the statement RUNS,
50
+ * from the FIBRE CONTEXT: `withTransaction` acquires one connection and
51
+ * provides it under that client's OWN `TransactionConnection` key — one key
52
+ * per `SqlClient` instance — and every statement that client builds resolves
53
+ * through a `getConnection` that reads that key first, falling back to the
54
+ * pool only when it is absent (`effect/sql`'s `SqlClient.make`). So a
55
+ * statement joins a transaction by being RUN inside it AND by being built from
56
+ * the SAME client value that opened it; a statement from any other client,
57
+ * even one over the same database, runs on its own pooled connection outside
58
+ * the transaction. Here every statement in the frame — the isolation `SET`,
59
+ * the row fetch and this `MAX(id)` — comes from `pooled`, the client that
60
+ * opened it, so all three share its connection and its snapshot, and passing
61
+ * the client along the call chain would add nothing. `read-postgres`'s
58
62
  * `pinnedConnection` test observes the same fact from the SERVER: two
59
63
  * statements issued inside one transaction report one `pg_backend_pid()`.
60
64
  *
@@ -130,7 +134,7 @@ const make = (config, names) => Effect.gen(function* () {
130
134
  * conflict (zero rows) vs head (`MAX(id)`) is read from the returned rows by
131
135
  * the caller, never from a caught error.
132
136
  */
133
- const callAppendFn = select => pooled.withTransaction(setLocalLockTimeout(pooled, lockTimeout).pipe(Effect.zipRight(select)));
137
+ const callAppendFn = select => pooled.withTransaction(setLocalLockTimeout(pooled, lockTimeout).pipe(Effect.andThen(select)));
134
138
  const append = (events, condition) => {
135
139
  const eventsJson = events.map(toEventJson);
136
140
  // Raw mechanics: a CONFLICT is `AppendConditionFailed`; a `SqlError` (incl.
@@ -193,22 +197,23 @@ const make = (config, names) => Effect.gen(function* () {
193
197
  /**
194
198
  * Wire core's subscribe machine to the live clients: `fetch` is the
195
199
  * per-subscription compiled read plan run against the pooled client and mapped
196
- * to `SequencedEvent`s; `listen` is the direct client's ref-counted, non-pooled
197
- * LISTEN on this store's channel (the Neon-safe path — `clients.ts` owns why
198
- * there are two clients at all). The plan is compiled ONCE here so the poll
199
- * loop re-binds only the cursor.
200
+ * to `SequencedEvent`s; `listen` is the direct client's LISTEN on this store's
201
+ * channel (the Neon-safe path — `clients.ts` owns why there are two clients at
202
+ * all), which reserves one of that client's connections for as long as the
203
+ * subscription's wake fibre runs and drains its notification queue as a
204
+ * stream. The plan is compiled ONCE here so the poll loop re-binds only the
205
+ * cursor.
200
206
  *
201
207
  * The wake source is `NOTIFY`, and it is a LATENCY optimisation only: the
202
- * machine's periodic position-based poll is what makes delivery correct, which
203
- * matters more here than the general argument for it suggests. The
204
- * `@effect/sql-pg` listen client SWALLOWS connection errors and does not
205
- * auto-reconnect, so a dropped LISTEN typically goes quiet rather than
206
- * erroring — the machine's listen-side retry then never fires, and the poll is
207
- * the ONLY thing that recovers the subscription. The same silence is what a
208
- * Neon pooled endpoint produces if `PgClientDirect` is misconfigured: the
209
- * pooler drops `LISTEN`/`NOTIFY` without complaint and delivery degrades to
210
- * poll-rate rather than failing, which is why that trap is a deployment-time
211
- * wiring choice and not a runtime error.
208
+ * machine's periodic position-based poll is what makes delivery correct. A
209
+ * listening connection that DROPS fails its queue with the `SqlError` it died
210
+ * of, so the machine's listen-side retry re-subscribes on a fresh connection
211
+ * — but the notifications sent while it was down are gone, and only the poll
212
+ * recovers the events they announced. And some failures are silent: a Neon
213
+ * pooled endpoint, if `PgClientDirect` is misconfigured, accepts `LISTEN` and
214
+ * then never delivers a `NOTIFY`, so delivery degrades to poll-rate rather
215
+ * than failing, which is why that trap is a deployment-time wiring choice and
216
+ * not a runtime error.
212
217
  *
213
218
  * `E` is `SqlError.SqlError` — both seams fail with it, so the machine's single
214
219
  * error parameter carries it straight through to `makeContractStore`.
@@ -217,7 +222,7 @@ const make = (config, names) => Effect.gen(function* () {
217
222
  const plan = compileFetchPlan(tables, query);
218
223
  return subscribeStream({
219
224
  fetch: (from, limit) => runFetch(pooled, plan, from, limit).pipe(Effect.map(rows => rows.map(rowToSequenced))),
220
- listen: direct.listen(names.channel),
225
+ listen: Stream.unwrap(Effect.map(direct.listen(names.channel), Stream.fromQueue)),
221
226
  pollInterval,
222
227
  catchUpPageSize
223
228
  }, after);
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","names":["AppendConditionFailed","DcbEventStore","DEFAULT_CATCH_UP_PAGE_SIZE","DEFAULT_POLL_INTERVAL_MILLIS","makeContractStore","ORIGIN","subscribeStream","Effect","Layer","Stream","PgClientDirect","PgClientPooled","decodePostgresStoreConfig","quoteQualified","resolveNames","compileFetchPlan","runFetch","jsonbText","rowToSequenced","toEventJson","toQueryItemsJson","setLocalLockTimeout","sql","lockTimeout","make","config","names","gen","pooled","direct","pollInterval","catchUpPageSize","tables","main","mainTable","tag","tagTable","globalHead","pipe","map","rows","max","undefined","BigInt","readRowsAndHead","query","options","plan","limit","after","lastRow","at","head","id","withTransaction","unsafe","read","events","fromIterable","callAppendFn","select","zipRight","append","condition","eventsJson","appendUnconditionalFn","headFromRows","queryItems","failIfEventsMatch","afterId","appendFn","length","Error","subscribe","fetch","from","listen","channel","layer","decoded","effect"],"sources":["../../src/store.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"store.js","names":["AppendConditionFailed","DcbEventStore","DEFAULT_CATCH_UP_PAGE_SIZE","DEFAULT_POLL_INTERVAL_MILLIS","makeContractStore","ORIGIN","subscribeStream","Effect","Layer","Stream","PgClientDirect","PgClientPooled","decodePostgresStoreConfig","quoteQualified","resolveNames","compileFetchPlan","runFetch","jsonbText","rowToSequenced","toEventJson","toQueryItemsJson","setLocalLockTimeout","sql","lockTimeout","make","config","names","gen","pooled","direct","pollInterval","catchUpPageSize","tables","main","mainTable","tag","tagTable","globalHead","pipe","map","rows","max","undefined","BigInt","readRowsAndHead","query","options","plan","limit","after","lastRow","at","head","id","withTransaction","unsafe","read","events","fromIterable","callAppendFn","select","andThen","append","condition","eventsJson","appendUnconditionalFn","headFromRows","queryItems","failIfEventsMatch","afterId","appendFn","length","Error","subscribe","fetch","from","listen","unwrap","channel","fromQueue","layer","decoded","effect"],"sources":["../../src/store.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kairos-es/store-postgres",
3
- "version": "1.0.0-alpha.4",
3
+ "version": "1.0.0-alpha.6",
4
4
  "description": "Postgres DcbEventStore backend for kairos-es",
5
5
  "license": "BSD-3-Clause",
6
6
  "repository": {
@@ -11,21 +11,23 @@
11
11
  "sideEffects": [],
12
12
  "homepage": "https://github.com/neverbland/kairos-es",
13
13
  "peerDependencies": {
14
- "@effect/experimental": "^0.61.0",
15
- "@effect/platform": "^0.97.0",
16
- "@effect/sql": "^0.52.0",
17
- "@effect/sql-pg": "^0.53.0",
18
- "effect": "^3.22.0",
19
- "@kairos-es/core": "^1.0.0-alpha.4"
14
+ "@effect/sql-pg": "^4.0.5",
15
+ "effect": "^4.0.5",
16
+ "@kairos-es/core": "^1.0.0-alpha.6"
20
17
  },
21
18
  "main": "./dist/cjs/index.js",
22
19
  "module": "./dist/esm/index.js",
23
- "types": "./dist/dts/index.d.ts",
20
+ "types": "./dist/dts-cjs/index.d.ts",
24
21
  "exports": {
25
22
  ".": {
26
- "types": "./dist/dts/index.d.ts",
27
- "import": "./dist/esm/index.js",
28
- "default": "./dist/cjs/index.js"
23
+ "import": {
24
+ "types": "./dist/dts-esm/index.d.ts",
25
+ "default": "./dist/esm/index.js"
26
+ },
27
+ "require": {
28
+ "types": "./dist/dts-cjs/index.d.ts",
29
+ "default": "./dist/cjs/index.js"
30
+ }
29
31
  },
30
32
  "./package.json": "./package.json"
31
33
  },