@shivaedev/sql 0.44.0 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.46.0 - 2026-11-07
4
+
5
+ ### Fixed
6
+
7
+ - Keep PostgreSQL change listeners connected past the query pool's connection lifetime so live subscriptions receive committed changes without periodic Resync. Reconnect and resynchronize when the listener connection is lost.
8
+
9
+ ### Breaking
10
+
11
+ - Remove `connectionTTL` from `PostgresChangesOptions`. Remove that option from direct `postgresChanges` calls; keep `connectionTTL` on `postgresLayer` or the server database config to recycle query connections.
12
+
13
+ ## 0.45.0 - 2026-11-06
14
+
15
+ ### Breaking
16
+
17
+ - Drop calls and imports of the removed `applyLowMemoryPostgres`. Move desired server values into the host's required `postgresSettings` declaration, typed by `PostgresSettings` from `@shivaedev/sql/postgresSettings.ts`.
18
+
3
19
  ## 0.44.0 - 2026-11-06
4
20
 
5
21
  ### Breaking
package/README.md CHANGED
@@ -29,32 +29,17 @@ Migrations are ordinary Effects loaded by native Migrator. `migratePostgres` add
29
29
 
30
30
  The work has three parts: describe the model and provide its database once, choose repository operations per feature, and put each changed write inside the transaction that owns its commit.
31
31
 
32
- ### Low-memory PostgreSQL hosts
32
+ ### PostgreSQL server settings
33
33
 
34
- `applyLowMemoryPostgres({ pointInTimeRecovery })` from `@shivaedev/sql/applyLowMemoryPostgres.ts` is an opt-in database-owner operation for small applications on Linux hosts that bill cgroup memory, including filesystem page cache. It uses the provided native `SqlClient` to write `ALTER SYSTEM` settings and request a reload. Run it once, outside a transaction, against the app's dedicated PostgreSQL instance with a role allowed to change these settings. It changes the whole instance, including every database on it. Keep it out of normal application startup and numbered migrations.
34
+ Applications declare server settings through `postgresSettings` on server's [`appDatabase`](https://github.com/ShivaeDev/platform/tree/main/packages/server#postgresql-server-settings) and database-backed hosts. SQL owns the `PostgresSettings` type and `applyPostgresSettings` in `@shivaedev/sql/postgresSettings.ts`; the host runs the applier during database startup, before migrations, outside their transaction. Settings describe the cluster's current configuration, rather than numbered migration history. The declaration maps PostgreSQL setting names to string values, including PostgreSQL units; it has no preset or implicit settings.
35
35
 
36
- ```ts
37
- import { Config, Effect } from "effect";
38
- import { applyLowMemoryPostgres } from "@shivaedev/sql/applyLowMemoryPostgres.ts";
39
- import { postgresLayer } from "@shivaedev/sql/postgresLayer.ts";
40
-
41
- const configure = Effect.gen(function* () {
42
- const url = yield* Config.Redacted("DATABASE_URL");
43
- yield* applyLowMemoryPostgres({ pointInTimeRecovery: false }).pipe(Effect.provide(postgresLayer(url)));
44
- }).pipe(Effect.scoped);
45
- ```
46
-
47
- Restart PostgreSQL after this operation. `shared_buffers=32MB`, `max_connections=50` and `wal_buffers=4MB` take effect on restart. The reload settings are `jit=off`, `max_parallel_workers_per_gather=0`, `hash_mem_multiplier=1`, `autovacuum_max_workers=2`, `autovacuum_work_mem=32MB`, `idle_in_transaction_session_timeout=10min` and `wal_compression=zstd`. `idle_session_timeout=0` keeps idle LISTEN connections alive. Use PostgreSQL 18 with zstd support; older versions can require a restart for additional settings. Command-line `-c` settings override `ALTER SYSTEM`, so remove conflicting overrides. A failed operation can leave earlier settings written; correct the reported SQL error before restarting.
48
-
49
- Point-in-time recovery is an explicit per-app memory and storage choice. With `pointInTimeRecovery: false`, the preset disables WAL archiving with `archive_mode=off`; it leaves `archive_timeout` alone and needs no backup bucket or pgBackRest configuration. Remove the host's archive and backup jobs and bucket configuration as well. This choice gives up recovery to a time between backups. With `true`, retain the host's working WAL archiving, backup bucket and restore procedure; the preset sets `archive_timeout=300` seconds. It does not provision backups or enable archiving. A timeout of 60 seconds can force a 16 MB WAL segment each minute even when the app is idle.
50
-
51
- For PITR hosts, pgBackRest derives its process count from the CPU limit. Set a CPU limit of 2 or explicitly set `PGBACKREST_BACKUP_PROCESS_MAX=1` on the PostgreSQL service. Eight processes under a 32-vCPU limit exhausted a 477 MiB container in the reported Railway workload. Declare both CPU and memory limits in infrastructure as code: an omitted limit can be reset by the next plan. Keep enough headroom for backups, maintenance and the app's total connection budget across replicas and workers.
36
+ The applier reads `pg_settings`, compares live values with the declaration, writes only differences with `ALTER SYSTEM SET`, and requests `pg_reload_conf()`. Equivalent numeric, memory and time units compare equally. A restart-only change logs its setting name and wanted value as pending; the live value remains until PostgreSQL restarts. These settings affect every database in the cluster, so apps sharing a cluster must agree on them.
52
37
 
53
- Pair this preset with server's [cache trim and connection lifetime](https://github.com/ShivaeDev/platform/tree/main/packages/server#low-memory-postgresql-hosts). Railway measurements supplied with this preset found billing within 0.2% of `memory.current`, shared memory around 45 MB instead of 175 MB, and small-app idle usage around 150–250 MB instead of 0.95 GB with preset, trim and connection recycling. Peaks returned within 5–10 minutes. These are workload observations, not memory limits or a promise for another app; measure your own cgroup before selecting a memory limit.
38
+ `ALTER SYSTEM` requires a superuser for these server settings. On a non-superuser deployment, or when PostgreSQL refuses a value, startup warns with the setting name, live value and wanted value, then continues starting the app. Manage those settings through the database operator when the app cannot change them.
54
39
 
55
40
  ### One PostgreSQL pool per application
56
41
 
57
- `postgresLayer(url, options)` from `@shivaedev/sql/postgresLayer.ts` provides the native `PgPool` service from `@effect/sql-pg/PgPool`, `PgClient`, `SqlClient` and a database-local Reactivity service together. `options` accepts `applicationName`, `maxConnections`, `minConnections`, `connectionTTL`, `idleTimeout`, `transformQueryNames` and `transformResultNames`. Queries, transactions and raw connections reserved with `yield* pool.reserve` share the same `maxConnections` budget. A reservation holds its connection until its scope closes; release it before waiting for work that needs that slot.
42
+ `postgresLayer(url, options)` from `@shivaedev/sql/postgresLayer.ts` provides the native `PgPool` service from `@effect/sql-pg/PgPool`, `PgClient`, `SqlClient` and a database-local Reactivity service together. `options` accepts `applicationName`, `maxConnections`, `minConnections`, `connectionTTL`, `idleTimeout`, `transformQueryNames` and `transformResultNames`. The default `maxConnections` is 10, matching native `PgPool`. Database hosts expose this through `config.maxConnections`. Queries, transactions and raw connections reserved with `yield* pool.reserve` share the same `maxConnections` budget. A reservation holds its connection until its scope closes; release it before waiting for work that needs that slot.
58
43
 
59
44
  ```ts
60
45
  import * as PgPool from "@effect/sql-pg/PgPool";
@@ -1,5 +1,5 @@
1
1
  import * as PgClient from "@effect/sql-pg/PgClient";
2
- import type * as PgConnection from "@effect/sql-pg/PgConnection";
2
+ import * as PgConnection from "@effect/sql-pg/PgConnection";
3
3
  import * as PgPool from "@effect/sql-pg/PgPool";
4
4
  import { Effect } from "effect";
5
5
  import { SqlClient, Statement } from "effect/sql";
@@ -1 +1 @@
1
- {"version":3,"file":"makePostgresClient.d.ts","sourceRoot":"","sources":["../../src/adapters/makePostgresClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,KAAK,YAAY,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAqB,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,SAAS,EAAsB,SAAS,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAgB,MAAM,qBAAqB,CAAC;AAI7D,eAAO,MAAM,kBAAkB;;;kBAuBf,OAAO;sBACH,MAAM;sBASN,MAAM,WAAW,MAAM;;4EAIzC,CAAC"}
1
+ {"version":3,"file":"makePostgresClient.d.ts","sourceRoot":"","sources":["../../src/adapters/makePostgresClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,YAAY,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAqB,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,SAAS,EAAsB,SAAS,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAgB,MAAM,qBAAqB,CAAC;AAI7D,eAAO,MAAM,kBAAkB;;;kBA0Bf,OAAO;sBACH,MAAM;sBAKN,MAAM,WAAW,MAAM;;4EAIzC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import * as PgClient from "@effect/sql-pg/PgClient";
2
+ import * as PgConnection from "@effect/sql-pg/PgConnection";
2
3
  import * as PgPool from "@effect/sql-pg/PgPool";
3
4
  import { Effect, Predicate, Stream } from "effect";
4
5
  import { SqlClient, Statement } from "effect/sql";
@@ -6,11 +7,11 @@ import { SqlError, UnknownError } from "effect/sql/SqlError";
6
7
  const json = Statement.custom("PgJson");
7
8
  export const makePostgresClient = Effect.fn("Sql.makePostgresClient")(function* (config) {
8
9
  const pool = yield* PgPool.PgPool;
9
- const acquirer = Effect.map(pool.get, postgresConnection);
10
+ const acquirer = Effect.flatMap(pool.get, (connection) => postgresConnection.pipe(Effect.provideService(PgConnection.PgConnection, connection)));
10
11
  const client = yield* SqlClient.make({
11
12
  acquirer,
12
- borrower: (use) => pool.use((connection) => use(postgresConnection(connection))),
13
- commit,
13
+ borrower: (use) => pool.use((connection) => Effect.flatMap(postgresConnection.pipe(Effect.provideService(PgConnection.PgConnection, connection)), use)),
14
+ commit: (connection) => Effect.flatMap(connection.executeRaw("COMMIT", []), commitResult),
14
15
  compiler: PgClient.makeCompiler(config.transformQueryNames),
15
16
  driver: "pg",
16
17
  prepareTransactionControls: true,
@@ -21,7 +22,7 @@ export const makePostgresClient = Effect.fn("Sql.makePostgresClient")(function*
21
22
  ["server.address", config.host ?? "localhost"],
22
23
  ["server.port", config.port ?? 5432],
23
24
  ],
24
- transactionAcquirer: Effect.map(pool.reserve, postgresConnection),
25
+ transactionAcquirer: Effect.flatMap(pool.reserve, (connection) => postgresConnection.pipe(Effect.provideService(PgConnection.PgConnection, connection))),
25
26
  transformRows: config.transformResultNames === undefined ? undefined : Statement.defaultTransforms(config.transformResultNames).array,
26
27
  });
27
28
  return Object.assign(client, {
@@ -29,10 +30,6 @@ export const makePostgresClient = Effect.fn("Sql.makePostgresClient")(function*
29
30
  config,
30
31
  json: (value) => Statement.fragment([json(value)]),
31
32
  listen: (channel) => Effect.gen(function* () {
32
- // TTL checkout retains expired leases until its scope closes; LISTEN must not pin those old backends for another lifetime.
33
- if (pool.config.connectionTTL !== undefined) {
34
- yield* pool.use(() => Effect.void);
35
- }
36
33
  const connection = yield* pool.reserve;
37
34
  return yield* connection.listen(channel);
38
35
  }),
@@ -40,7 +37,8 @@ export const makePostgresClient = Effect.fn("Sql.makePostgresClient")(function*
40
37
  poolStats: pool.stats,
41
38
  });
42
39
  });
43
- function postgresConnection(connection) {
40
+ const postgresConnection = Effect.gen(function* () {
41
+ const connection = yield* PgConnection.PgConnection;
44
42
  function execute(sql, params, transformRows, prepare = true) {
45
43
  const rows = Effect.map(connection.query(sql, params, prepare), (result) => result.rows);
46
44
  return transformRows === undefined ? rows : Effect.map(rows, transformRows);
@@ -56,9 +54,9 @@ function postgresConnection(connection) {
56
54
  executeValues: (sql, params) => connection.queryValues(sql, params),
57
55
  executeValuesUnprepared: (sql, params) => connection.queryValues(sql, params, false),
58
56
  };
59
- }
60
- function commit(connection) {
61
- return Effect.flatMap(connection.executeRaw("COMMIT", []), (result) => Predicate.hasProperty(result, "command") && result.command === "ROLLBACK"
57
+ });
58
+ function commitResult(result) {
59
+ return Predicate.hasProperty(result, "command") && result.command === "ROLLBACK"
62
60
  ? Effect.fail(new SqlError({
63
61
  reason: new UnknownError({
64
62
  cause: new Error("COMMIT rolled back an aborted transaction"),
@@ -66,6 +64,6 @@ function commit(connection) {
66
64
  operation: "commit",
67
65
  }),
68
66
  }))
69
- : Effect.void);
67
+ : Effect.void;
70
68
  }
71
69
  //# sourceMappingURL=makePostgresClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"makePostgresClient.js","sourceRoot":"","sources":["../../src/adapters/makePostgresClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"makePostgresClient.js","sourceRoot":"","sources":["../../src/adapters/makePostgresClient.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"listenForChanges.d.ts","sourceRoot":"","sources":["../src/listenForChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,MAAM,EAAiB,KAAK,EAAE,MAAM,QAAQ,CAAC;AACjF,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AASnE,eAAO,MAAM,gBAAgB,qPA4F3B,CAAC"}
1
+ {"version":3,"file":"listenForChanges.d.ts","sourceRoot":"","sources":["../src/listenForChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,MAAM,EAAiB,KAAK,EAAE,MAAM,QAAQ,CAAC;AACtF,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AASnE,eAAO,MAAM,gBAAgB,qPAsF3B,CAAC"}
@@ -1,4 +1,4 @@
1
- import { Clock, Deferred, Duration, Effect, Queue, Random, Scope } from "effect";
1
+ import { Clock, Deferred, Effect, Queue, Random, Scope } from "effect";
2
2
  import * as Reactivity from "effect/reactivity/Reactivity";
3
3
  import { SqlClient } from "effect/sql";
4
4
  import { decodeKeys, resyncPayload } from "./notifyPayload.js";
@@ -27,9 +27,6 @@ export const listenForChanges = Effect.fn("PostgresChanges.listenForChanges")(fu
27
27
  const attempt = Effect.scoped(Effect.gen(function* () {
28
28
  const scope = yield* listenerScope(timeout);
29
29
  const notifications = yield* listener.listen(channel).pipe(Scope.provide(scope), deadline);
30
- const interval = Duration.toMillis(Duration.fromInputUnsafe(options.heartbeatInterval ?? "5 seconds"));
31
- const lifetime = Duration.toMillis(Duration.fromInputUnsafe(options.connectionTTL ?? Duration.infinity));
32
- const renewAt = (yield* Clock.currentTimeMillis) + (lifetime === 0 ? interval : lifetime);
33
30
  const token = JSON.stringify({ heartbeat: `${yield* Random.nextInt}:${yield* Random.nextInt}` });
34
31
  let ack = yield* Deferred.make();
35
32
  function receive(payload) {
@@ -56,10 +53,7 @@ export const listenForChanges = Effect.fn("PostgresChanges.listenForChanges")(fu
56
53
  }
57
54
  yield* Deferred.succeed(ready, undefined);
58
55
  while (true) {
59
- yield* Effect.sleep(Math.min(interval, Math.max(0, renewAt - (yield* Clock.currentTimeMillis))));
60
- if ((yield* Clock.currentTimeMillis) >= renewAt) {
61
- return;
62
- }
56
+ yield* Effect.sleep(options.heartbeatInterval ?? "5 seconds");
63
57
  ack = yield* Deferred.make();
64
58
  yield* Effect.andThen(send, Deferred.await(ack)).pipe(deadline);
65
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"listenForChanges.js","sourceRoot":"","sources":["../src/listenForChanges.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"listenForChanges.js","sourceRoot":"","sources":["../src/listenForChanges.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,6 @@ export interface PostgresChangesOptions {
12
12
  readonly channel: string;
13
13
  readonly client: PostgresChangeClient;
14
14
  readonly connectionSetting?: string;
15
- readonly "connectionTTL"?: Duration.Input | undefined;
16
15
  readonly heartbeatInterval?: Duration.Input;
17
16
  readonly heartbeatTimeout?: Duration.Input;
18
17
  readonly listenerClient?: Pick<PostgresChangeClient, "listen">;
@@ -1 +1 @@
1
- {"version":3,"file":"postgresChanges.d.ts","sourceRoot":"","sources":["../src/postgresChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvF,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAQpD,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAqB,SAAQ,SAAS,CAAC,SAAS;IAChE,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;CAC1H;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC5C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;CACrC;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,oHAwC9D"}
1
+ {"version":3,"file":"postgresChanges.d.ts","sourceRoot":"","sources":["../src/postgresChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvF,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAQpD,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAqB,SAAQ,SAAS,CAAC,SAAS;IAChE,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;CAC1H;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC5C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;CACrC;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,oHAwC9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"postgresChanges.js","sourceRoot":"","sources":["../src/postgresChanges.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgresChanges.js","sourceRoot":"","sources":["../src/postgresChanges.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { Effect } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ export type PostgresSettings = Readonly<Record<string, string>>;
4
+ export declare const applyPostgresSettings: (settings: Readonly<Record<string, string>>) => Effect.Effect<void, never, SqlClient.SqlClient>;
5
+ //# sourceMappingURL=postgresSettings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgresSettings.d.ts","sourceRoot":"","sources":["../src/postgresSettings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAa,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAUhE,eAAO,MAAM,qBAAqB,iGA4ChC,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { SqlClient, SqlSchema } from "effect/sql";
3
+ const Setting = Schema.Struct({
4
+ context: Schema.String,
5
+ pendingRestart: Schema.Boolean,
6
+ setting: Schema.String,
7
+ unit: Schema.NullOr(Schema.String),
8
+ vartype: Schema.String,
9
+ }).pipe(Schema.encodeKeys({ pendingRestart: "pending_restart" }));
10
+ export const applyPostgresSettings = Effect.fn("Sql.applyPostgresSettings")(function* (settings) {
11
+ const sql = (yield* SqlClient.SqlClient).withoutTransforms();
12
+ const read = SqlSchema.findAll({
13
+ execute: (name) => sql `select setting, unit, vartype, context, pending_restart from pg_settings where name = ${name}`,
14
+ Request: Schema.String,
15
+ Result: Setting,
16
+ });
17
+ const changed = [];
18
+ for (const [name, wanted] of Object.entries(settings)) {
19
+ let live = "unavailable";
20
+ yield* Effect.gen(function* () {
21
+ const [current] = yield* read(name);
22
+ if (current === undefined) {
23
+ return yield* Effect.logWarning("PostgreSQL setting is unknown", { live, setting: name, wanted });
24
+ }
25
+ live = `${current.setting}${current.unit === null ? "" : ` ${current.unit}`}`;
26
+ if (yield* settingMatches(current, wanted)) {
27
+ return;
28
+ }
29
+ yield* sql.unsafe(`ALTER SYSTEM SET "${name.replaceAll('"', '""')}" = '${wanted.replaceAll("'", "''")}'`).unprepared;
30
+ changed.push({ live, name, restart: current.context === "postmaster", wanted });
31
+ }).pipe(Effect.catch((error) => Effect.logWarning("Could not apply PostgreSQL setting", { error, live, setting: name, wanted })));
32
+ }
33
+ if (changed.length === 0) {
34
+ return;
35
+ }
36
+ yield* sql `select pg_reload_conf()`.pipe(Effect.andThen(Effect.forEach(changed, (change) => Effect.gen(function* () {
37
+ const [current] = yield* read(change.name);
38
+ // Reload signals are asynchronous; postmaster settings written above already require a restart.
39
+ if (current?.pendingRestart || change.restart) {
40
+ yield* Effect.logWarning("PostgreSQL setting pending restart", { setting: change.name, wanted: change.wanted });
41
+ }
42
+ }))), Effect.catch((error) => Effect.forEach(changed, ({ name, live, wanted }) => Effect.logWarning("Could not reload PostgreSQL setting", { error, live, setting: name, wanted }))));
43
+ });
44
+ const settingMatches = Effect.fnUntraced(function* (current, wanted) {
45
+ if (current.setting === wanted) {
46
+ return true;
47
+ }
48
+ const sql = yield* SqlClient.SqlClient;
49
+ let comparison = sql `${current.setting} = ${wanted}`;
50
+ if (current.vartype === "bool") {
51
+ comparison = sql `${current.setting}::boolean = ${wanted}::boolean`;
52
+ }
53
+ else if (["integer", "real"].includes(current.vartype)) {
54
+ if (/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/iu.test(wanted.trim())) {
55
+ comparison = sql `${current.setting}::numeric = ${wanted}::numeric`;
56
+ }
57
+ else if (["B", "kB", "8kB", "MB"].includes(current.unit ?? "")) {
58
+ const unit = current.unit === "8kB" ? "8kB" : `1${current.unit}`;
59
+ comparison = sql `${current.setting}::numeric * pg_size_bytes(${unit}) = pg_size_bytes(${wanted})`;
60
+ }
61
+ else if (["us", "ms", "s", "min", "h", "d"].includes(current.unit ?? "")) {
62
+ comparison = sql `${current.setting}::numeric * extract(epoch from ${`1 ${current.unit}`}::interval) = extract(epoch from ${wanted}::interval)`;
63
+ }
64
+ }
65
+ const [row] = yield* SqlSchema.findAll({
66
+ execute: () => sql `select ${comparison} as matches`,
67
+ Request: Schema.Void,
68
+ Result: Schema.Struct({ matches: Schema.Boolean }),
69
+ })();
70
+ return row?.matches === true;
71
+ });
72
+ //# sourceMappingURL=postgresSettings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgresSettings.js","sourceRoot":"","sources":["../src/postgresSettings.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shivaedev/sql",
3
- "version": "0.44.0",
3
+ "version": "0.46.0",
4
4
  "description": "Schema-derived repositories over native Effect SQL",
5
5
  "keywords": [
6
6
  "effect"
@@ -47,23 +47,23 @@
47
47
  "@shivaedev/service": "0.8.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@effect/platform-node": "4.1.0",
51
- "@effect/sql-pg": "4.1.0",
52
- "@effect/sql-sqlite-node": "4.1.0",
53
- "@shivaedev/contract": "0.41.0",
54
- "@shivaedev/jobs": "0.40.1",
55
- "@shivaedev/quality": "0.67.0",
56
- "@shivaedev/test-kits": "0.9.0",
57
- "@shivaedev/test-sql": "0.24.2",
58
- "@shivaedev/test-story": "0.43.0",
50
+ "@effect/platform-node": "4.1.1",
51
+ "@effect/sql-pg": "4.1.1",
52
+ "@effect/sql-sqlite-node": "4.1.1",
53
+ "@shivaedev/contract": "0.43.0",
54
+ "@shivaedev/jobs": "0.41.1",
55
+ "@shivaedev/quality": "0.69.4",
56
+ "@shivaedev/test-kits": "0.10.1",
57
+ "@shivaedev/test-sql": "0.24.4",
58
+ "@shivaedev/test-story": "0.45.1",
59
59
  "@types/node": "24.19.2",
60
- "effect": "4.1.0",
60
+ "effect": "4.1.1",
61
61
  "typescript": "7.0.2",
62
62
  "vitest": "5.0.5"
63
63
  },
64
64
  "peerDependencies": {
65
- "@effect/sql-pg": "4.1.0",
66
- "effect": "4.1.0"
65
+ "@effect/sql-pg": "4.1.1",
66
+ "effect": "4.1.1"
67
67
  },
68
68
  "peerDependenciesMeta": {
69
69
  "@effect/sql-pg": {
@@ -1,5 +1,5 @@
1
1
  import * as PgClient from "@effect/sql-pg/PgClient";
2
- import type * as PgConnection from "@effect/sql-pg/PgConnection";
2
+ import * as PgConnection from "@effect/sql-pg/PgConnection";
3
3
  import * as PgPool from "@effect/sql-pg/PgPool";
4
4
  import { Effect, Predicate, Stream } from "effect";
5
5
  import { SqlClient, type SqlConnection, Statement } from "effect/sql";
@@ -9,11 +9,12 @@ const json = Statement.custom<PgClient.PgCustom>("PgJson");
9
9
 
10
10
  export const makePostgresClient = Effect.fn("Sql.makePostgresClient")(function* (config: PgClient.PgClientConfig) {
11
11
  const pool = yield* PgPool.PgPool;
12
- const acquirer = Effect.map(pool.get, postgresConnection);
12
+ const acquirer = Effect.flatMap(pool.get, (connection) => postgresConnection.pipe(Effect.provideService(PgConnection.PgConnection, connection)));
13
13
  const client = yield* SqlClient.make({
14
14
  acquirer,
15
- borrower: (use) => pool.use((connection) => use(postgresConnection(connection))),
16
- commit,
15
+ borrower: (use) =>
16
+ pool.use((connection) => Effect.flatMap(postgresConnection.pipe(Effect.provideService(PgConnection.PgConnection, connection)), use)),
17
+ commit: (connection) => Effect.flatMap(connection.executeRaw("COMMIT", []), commitResult),
17
18
  compiler: PgClient.makeCompiler(config.transformQueryNames),
18
19
  driver: "pg",
19
20
  prepareTransactionControls: true,
@@ -24,7 +25,9 @@ export const makePostgresClient = Effect.fn("Sql.makePostgresClient")(function*
24
25
  ["server.address", config.host ?? "localhost"],
25
26
  ["server.port", config.port ?? 5432],
26
27
  ],
27
- transactionAcquirer: Effect.map(pool.reserve, postgresConnection),
28
+ transactionAcquirer: Effect.flatMap(pool.reserve, (connection) =>
29
+ postgresConnection.pipe(Effect.provideService(PgConnection.PgConnection, connection)),
30
+ ),
28
31
  transformRows: config.transformResultNames === undefined ? undefined : Statement.defaultTransforms(config.transformResultNames).array,
29
32
  });
30
33
  return Object.assign(client, {
@@ -33,10 +36,6 @@ export const makePostgresClient = Effect.fn("Sql.makePostgresClient")(function*
33
36
  json: (value: unknown) => Statement.fragment([json(value)]),
34
37
  listen: (channel: string) =>
35
38
  Effect.gen(function* () {
36
- // TTL checkout retains expired leases until its scope closes; LISTEN must not pin those old backends for another lifetime.
37
- if (pool.config.connectionTTL !== undefined) {
38
- yield* pool.use(() => Effect.void);
39
- }
40
39
  const connection = yield* pool.reserve;
41
40
  return yield* connection.listen(channel);
42
41
  }),
@@ -46,7 +45,8 @@ export const makePostgresClient = Effect.fn("Sql.makePostgresClient")(function*
46
45
  }) satisfies PgClient.PgClient;
47
46
  });
48
47
 
49
- function postgresConnection(connection: PgConnection.PgConnection): SqlConnection.Connection {
48
+ const postgresConnection = Effect.gen(function* () {
49
+ const connection = yield* PgConnection.PgConnection;
50
50
  function execute(sql: string, params: readonly unknown[], transformRows: Parameters<SqlConnection.Connection["execute"]>[2], prepare = true) {
51
51
  const rows = Effect.map(connection.query(sql, params, prepare), (result) => result.rows);
52
52
  return transformRows === undefined ? rows : Effect.map(rows, transformRows);
@@ -61,21 +61,19 @@ function postgresConnection(connection: PgConnection.PgConnection): SqlConnectio
61
61
  executeUnprepared: (sql, params, transformRows) => execute(sql, params, transformRows, false),
62
62
  executeValues: (sql, params) => connection.queryValues(sql, params),
63
63
  executeValuesUnprepared: (sql, params) => connection.queryValues(sql, params, false),
64
- };
65
- }
64
+ } satisfies SqlConnection.Connection;
65
+ });
66
66
 
67
- function commit(connection: SqlConnection.Connection) {
68
- return Effect.flatMap(connection.executeRaw("COMMIT", []), (result) =>
69
- Predicate.hasProperty(result, "command") && result.command === "ROLLBACK"
70
- ? Effect.fail(
71
- new SqlError({
72
- reason: new UnknownError({
73
- cause: new Error("COMMIT rolled back an aborted transaction"),
74
- message: "PgClient: COMMIT rolled back an aborted transaction",
75
- operation: "commit",
76
- }),
67
+ function commitResult(result: unknown) {
68
+ return Predicate.hasProperty(result, "command") && result.command === "ROLLBACK"
69
+ ? Effect.fail(
70
+ new SqlError({
71
+ reason: new UnknownError({
72
+ cause: new Error("COMMIT rolled back an aborted transaction"),
73
+ message: "PgClient: COMMIT rolled back an aborted transaction",
74
+ operation: "commit",
77
75
  }),
78
- )
79
- : Effect.void,
80
- );
76
+ }),
77
+ )
78
+ : Effect.void;
81
79
  }
@@ -1,4 +1,4 @@
1
- import { Clock, Deferred, Duration, Effect, Queue, Random, Scope } from "effect";
1
+ import { Clock, Deferred, type Duration, Effect, Queue, Random, Scope } from "effect";
2
2
  import * as Reactivity from "effect/reactivity/Reactivity";
3
3
  import { SqlClient } from "effect/sql";
4
4
  import type { SqlError } from "effect/sql/SqlError";
@@ -38,9 +38,6 @@ export const listenForChanges = Effect.fn("PostgresChanges.listenForChanges")(fu
38
38
  Effect.gen(function* () {
39
39
  const scope = yield* listenerScope(timeout);
40
40
  const notifications = yield* listener.listen(channel).pipe(Scope.provide(scope), deadline);
41
- const interval = Duration.toMillis(Duration.fromInputUnsafe(options.heartbeatInterval ?? "5 seconds"));
42
- const lifetime = Duration.toMillis(Duration.fromInputUnsafe(options.connectionTTL ?? Duration.infinity));
43
- const renewAt = (yield* Clock.currentTimeMillis) + (lifetime === 0 ? interval : lifetime);
44
41
  const token = JSON.stringify({ heartbeat: `${yield* Random.nextInt}:${yield* Random.nextInt}` });
45
42
  let ack = yield* Deferred.make<void>();
46
43
  function receive(payload: string) {
@@ -76,10 +73,7 @@ export const listenForChanges = Effect.fn("PostgresChanges.listenForChanges")(fu
76
73
  }
77
74
  yield* Deferred.succeed(ready, undefined);
78
75
  while (true) {
79
- yield* Effect.sleep(Math.min(interval, Math.max(0, renewAt - (yield* Clock.currentTimeMillis))));
80
- if ((yield* Clock.currentTimeMillis) >= renewAt) {
81
- return;
82
- }
76
+ yield* Effect.sleep(options.heartbeatInterval ?? "5 seconds");
83
77
  ack = yield* Deferred.make<void>();
84
78
  yield* Effect.andThen(send, Deferred.await(ack)).pipe(deadline);
85
79
  }
@@ -21,7 +21,6 @@ export interface PostgresChangesOptions {
21
21
  readonly channel: string;
22
22
  readonly client: PostgresChangeClient;
23
23
  readonly connectionSetting?: string;
24
- readonly "connectionTTL"?: Duration.Input | undefined;
25
24
  readonly heartbeatInterval?: Duration.Input;
26
25
  readonly heartbeatTimeout?: Duration.Input;
27
26
  readonly listenerClient?: Pick<PostgresChangeClient, "listen">;
@@ -0,0 +1,84 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { SqlClient, SqlSchema } from "effect/sql";
3
+
4
+ export type PostgresSettings = Readonly<Record<string, string>>;
5
+
6
+ const Setting = Schema.Struct({
7
+ context: Schema.String,
8
+ pendingRestart: Schema.Boolean,
9
+ setting: Schema.String,
10
+ unit: Schema.NullOr(Schema.String),
11
+ vartype: Schema.String,
12
+ }).pipe(Schema.encodeKeys({ pendingRestart: "pending_restart" }));
13
+
14
+ export const applyPostgresSettings = Effect.fn("Sql.applyPostgresSettings")(function* (settings: PostgresSettings) {
15
+ const sql = (yield* SqlClient.SqlClient).withoutTransforms();
16
+ const read = SqlSchema.findAll({
17
+ execute: (name) => sql`select setting, unit, vartype, context, pending_restart from pg_settings where name = ${name}`,
18
+ Request: Schema.String,
19
+ Result: Setting,
20
+ });
21
+ const changed: Array<{ name: string; live: string; wanted: string; restart: boolean }> = [];
22
+ for (const [name, wanted] of Object.entries(settings)) {
23
+ let live = "unavailable";
24
+ yield* Effect.gen(function* () {
25
+ const [current] = yield* read(name);
26
+ if (current === undefined) {
27
+ return yield* Effect.logWarning("PostgreSQL setting is unknown", { live, setting: name, wanted });
28
+ }
29
+ live = `${current.setting}${current.unit === null ? "" : ` ${current.unit}`}`;
30
+ if (yield* settingMatches(current, wanted)) {
31
+ return;
32
+ }
33
+ yield* sql.unsafe(`ALTER SYSTEM SET "${name.replaceAll('"', '""')}" = '${wanted.replaceAll("'", "''")}'`).unprepared;
34
+ changed.push({ live, name, restart: current.context === "postmaster", wanted });
35
+ }).pipe(Effect.catch((error) => Effect.logWarning("Could not apply PostgreSQL setting", { error, live, setting: name, wanted })));
36
+ }
37
+ if (changed.length === 0) {
38
+ return;
39
+ }
40
+ yield* sql`select pg_reload_conf()`.pipe(
41
+ Effect.andThen(
42
+ Effect.forEach(changed, (change) =>
43
+ Effect.gen(function* () {
44
+ const [current] = yield* read(change.name);
45
+ // Reload signals are asynchronous; postmaster settings written above already require a restart.
46
+ if (current?.pendingRestart || change.restart) {
47
+ yield* Effect.logWarning("PostgreSQL setting pending restart", { setting: change.name, wanted: change.wanted });
48
+ }
49
+ }),
50
+ ),
51
+ ),
52
+ Effect.catch((error) =>
53
+ Effect.forEach(changed, ({ name, live, wanted }) =>
54
+ Effect.logWarning("Could not reload PostgreSQL setting", { error, live, setting: name, wanted }),
55
+ ),
56
+ ),
57
+ );
58
+ });
59
+
60
+ const settingMatches = Effect.fnUntraced(function* (current: typeof Setting.Type, wanted: string) {
61
+ if (current.setting === wanted) {
62
+ return true;
63
+ }
64
+ const sql = yield* SqlClient.SqlClient;
65
+ let comparison = sql`${current.setting} = ${wanted}`;
66
+ if (current.vartype === "bool") {
67
+ comparison = sql`${current.setting}::boolean = ${wanted}::boolean`;
68
+ } else if (["integer", "real"].includes(current.vartype)) {
69
+ if (/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/iu.test(wanted.trim())) {
70
+ comparison = sql`${current.setting}::numeric = ${wanted}::numeric`;
71
+ } else if (["B", "kB", "8kB", "MB"].includes(current.unit ?? "")) {
72
+ const unit = current.unit === "8kB" ? "8kB" : `1${current.unit}`;
73
+ comparison = sql`${current.setting}::numeric * pg_size_bytes(${unit}) = pg_size_bytes(${wanted})`;
74
+ } else if (["us", "ms", "s", "min", "h", "d"].includes(current.unit ?? "")) {
75
+ comparison = sql`${current.setting}::numeric * extract(epoch from ${`1 ${current.unit}`}::interval) = extract(epoch from ${wanted}::interval)`;
76
+ }
77
+ }
78
+ const [row] = yield* SqlSchema.findAll({
79
+ execute: () => sql`select ${comparison} as matches`,
80
+ Request: Schema.Void,
81
+ Result: Schema.Struct({ matches: Schema.Boolean }),
82
+ })();
83
+ return row?.matches === true;
84
+ });
@@ -1,7 +0,0 @@
1
- import { Effect } from "effect";
2
- import { SqlClient } from "effect/sql";
3
- export interface LowMemoryPostgresOptions {
4
- readonly pointInTimeRecovery: boolean;
5
- }
6
- export declare const applyLowMemoryPostgres: (args_0: LowMemoryPostgresOptions) => Effect.Effect<void, import("effect/sql/SqlError").SqlError, SqlClient.SqlClient>;
7
- //# sourceMappingURL=applyLowMemoryPostgres.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"applyLowMemoryPostgres.d.ts","sourceRoot":"","sources":["../src/applyLowMemoryPostgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;CACtC;AAED,eAAO,MAAM,sBAAsB,wHAoBjC,CAAC"}
@@ -1,24 +0,0 @@
1
- import { Effect } from "effect";
2
- import { SqlClient } from "effect/sql";
3
- export const applyLowMemoryPostgres = Effect.fn("Sql.applyLowMemoryPostgres")(function* ({ pointInTimeRecovery }) {
4
- const sql = yield* SqlClient.SqlClient;
5
- const settings = {
6
- "autovacuum_max_workers": "2",
7
- "autovacuum_work_mem": "32MB",
8
- "hash_mem_multiplier": "1",
9
- "idle_in_transaction_session_timeout": "10min",
10
- "idle_session_timeout": "0",
11
- jit: "off",
12
- "max_connections": "50",
13
- "max_parallel_workers_per_gather": "0",
14
- "shared_buffers": "32MB",
15
- "wal_buffers": "4MB",
16
- "wal_compression": "zstd",
17
- ...(pointInTimeRecovery ? { "archive_timeout": "300" } : { "archive_mode": "off" }),
18
- };
19
- for (const [name, value] of Object.entries(settings)) {
20
- yield* sql.unsafe(`ALTER SYSTEM SET ${name} = '${value}'`);
21
- }
22
- yield* sql `select pg_reload_conf()`;
23
- });
24
- //# sourceMappingURL=applyLowMemoryPostgres.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"applyLowMemoryPostgres.js","sourceRoot":"","sources":["../src/applyLowMemoryPostgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAMvC,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,EAAE,CAAC,4BAA4B,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,mBAAmB,EAA4B;IACzI,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC;IACvC,MAAM,QAAQ,GAAG;QAChB,wBAAwB,EAAE,GAAG;QAC7B,qBAAqB,EAAE,MAAM;QAC7B,qBAAqB,EAAE,GAAG;QAC1B,qCAAqC,EAAE,OAAO;QAC9C,sBAAsB,EAAE,GAAG;QAC3B,GAAG,EAAE,KAAK;QACV,iBAAiB,EAAE,IAAI;QACvB,iCAAiC,EAAE,GAAG;QACtC,gBAAgB,EAAE,MAAM;QACxB,aAAa,EAAE,KAAK;QACpB,iBAAiB,EAAE,MAAM;QACzB,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;KACnF,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtD,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,oBAAoB,IAAI,OAAO,KAAK,GAAG,CAAC,CAAC;IAC5D,CAAC;IACD,KAAK,CAAC,CAAC,GAAG,CAAA,yBAAyB,CAAC;AACrC,CAAC,CAAC,CAAC"}
@@ -1,28 +0,0 @@
1
- import { Effect } from "effect";
2
- import { SqlClient } from "effect/sql";
3
-
4
- export interface LowMemoryPostgresOptions {
5
- readonly pointInTimeRecovery: boolean;
6
- }
7
-
8
- export const applyLowMemoryPostgres = Effect.fn("Sql.applyLowMemoryPostgres")(function* ({ pointInTimeRecovery }: LowMemoryPostgresOptions) {
9
- const sql = yield* SqlClient.SqlClient;
10
- const settings = {
11
- "autovacuum_max_workers": "2",
12
- "autovacuum_work_mem": "32MB",
13
- "hash_mem_multiplier": "1",
14
- "idle_in_transaction_session_timeout": "10min",
15
- "idle_session_timeout": "0",
16
- jit: "off",
17
- "max_connections": "50",
18
- "max_parallel_workers_per_gather": "0",
19
- "shared_buffers": "32MB",
20
- "wal_buffers": "4MB",
21
- "wal_compression": "zstd",
22
- ...(pointInTimeRecovery ? { "archive_timeout": "300" } : { "archive_mode": "off" }),
23
- };
24
- for (const [name, value] of Object.entries(settings)) {
25
- yield* sql.unsafe(`ALTER SYSTEM SET ${name} = '${value}'`);
26
- }
27
- yield* sql`select pg_reload_conf()`;
28
- });