@shivaedev/sql 0.28.0 → 0.30.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +96 -4
  3. package/dist/batchedDelete.d.ts +33 -0
  4. package/dist/batchedDelete.d.ts.map +1 -0
  5. package/dist/batchedDelete.js +64 -0
  6. package/dist/batchedDelete.js.map +1 -0
  7. package/dist/compositeRepository.d.ts +14 -13
  8. package/dist/compositeRepository.d.ts.map +1 -1
  9. package/dist/compositeRepository.js.map +1 -1
  10. package/dist/jsonb.d.ts +3 -0
  11. package/dist/jsonb.d.ts.map +1 -0
  12. package/dist/jsonb.js +9 -0
  13. package/dist/jsonb.js.map +1 -0
  14. package/dist/repository.d.ts +5 -9
  15. package/dist/repository.d.ts.map +1 -1
  16. package/dist/repository.js +21 -17
  17. package/dist/repository.js.map +1 -1
  18. package/dist/repositoryChanges.d.ts +1 -0
  19. package/dist/repositoryChanges.d.ts.map +1 -1
  20. package/dist/repositoryChanges.js +9 -1
  21. package/dist/repositoryChanges.js.map +1 -1
  22. package/dist/repositoryCollection.d.ts +28 -0
  23. package/dist/repositoryCollection.d.ts.map +1 -0
  24. package/dist/repositoryCollection.js +21 -0
  25. package/dist/repositoryCollection.js.map +1 -0
  26. package/dist/repositoryUpdate.d.ts +31 -0
  27. package/dist/repositoryUpdate.d.ts.map +1 -0
  28. package/dist/repositoryUpdate.js +16 -0
  29. package/dist/repositoryUpdate.js.map +1 -0
  30. package/dist/repositoryWrites.d.ts +5 -2
  31. package/dist/repositoryWrites.d.ts.map +1 -1
  32. package/dist/repositoryWrites.js +19 -4
  33. package/dist/repositoryWrites.js.map +1 -1
  34. package/dist/testing.d.ts +2 -1
  35. package/dist/testing.d.ts.map +1 -1
  36. package/dist/testing.js +1 -1
  37. package/dist/testing.js.map +1 -1
  38. package/dist/tryPurgeLock.d.ts +4 -0
  39. package/dist/tryPurgeLock.d.ts.map +1 -0
  40. package/dist/tryPurgeLock.js +15 -0
  41. package/dist/tryPurgeLock.js.map +1 -0
  42. package/dist/versionedRepository.d.ts +3 -2
  43. package/dist/versionedRepository.d.ts.map +1 -1
  44. package/dist/versionedRepository.js.map +1 -1
  45. package/package.json +4 -4
  46. package/src/batchedDelete.ts +93 -0
  47. package/src/compositeRepository.ts +25 -34
  48. package/src/jsonb.ts +12 -0
  49. package/src/repository.ts +30 -28
  50. package/src/repositoryChanges.ts +9 -1
  51. package/src/repositoryCollection.ts +46 -0
  52. package/src/repositoryUpdate.ts +65 -0
  53. package/src/repositoryWrites.ts +19 -4
  54. package/src/testing.ts +7 -3
  55. package/src/tryPurgeLock.ts +18 -0
  56. package/src/versionedRepository.ts +3 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.30.0 - 2026-11-01
4
+
5
+ ### Added
6
+
7
+ - Repositories offer PostgreSQL `deleteBatched` retention purges with independently committed batches, a pause and row cap, one table change hint per batch, and a run lock that skips overlapping purges of the same table.
8
+ - Select `columns` in unversioned repository `update` and `updateVoid` calls to change only those fields by primary key without reading the row first, while publishing committed record and bucket changes.
9
+ - Encode PostgreSQL `jsonb` columns and decode their nested values with the `jsonb` schema helper.
10
+
11
+ ### Fixed
12
+
13
+ - Accept read-back values for native overrideable model fields in repository update inputs, including `Model.DateTimeUpdateFromDate`, so selected rows can be passed back unchanged.
14
+
15
+ ## 0.29.0 - 2026-10-31
16
+
17
+ ### Added
18
+
19
+ - `expectPublished` accepts a function of the successful write result, so generated-id inserts can assert their own record keys.
20
+
21
+ ### Breaking
22
+
23
+ - Bucket-bearing repositories require their contract collection in `makeRepository`'s `collection` option. Pass the collection already used by query read keys; its name must equal `tableName` and its bucket fields must match the model's `bucket` annotations. Registration fails with the typed `BucketRegistrationError` when declarations disagree or the collection is missing. Handle this new registration error when constructing repositories.
24
+
3
25
  ## 0.28.0 - 2026-10-31
4
26
 
5
27
  ### Added
package/README.md CHANGED
@@ -91,7 +91,7 @@ const makeInvoiceLines = makeRepository(InvoiceLine, {
91
91
  });
92
92
  ```
93
93
 
94
- The database supplies `id` on insert. Its `Model.Field` includes the ID in selected rows, updates and JSON, and leaves it out of insertion. Keep the repository's ID field in the update variant. An ordinary field such as `name` participates in the writable variants; native update takes that update shape, so pass the complete input the model requires.
94
+ The database supplies `id` on insert. Its `Model.Field` includes the ID in selected rows, updates and JSON, and leaves it out of insertion. Keep the repository's ID field in the update variant. An ordinary field such as `name` participates in the writable variants. By default, `update` takes the complete update shape; select particular columns when changing only part of a row.
95
95
 
96
96
  `amount` uses a text column in this example. `Schema.NumberFromString` encodes a number for storage and decodes the driver's string on reads. The SQL schema still owns column types, constraints and defaults.
97
97
 
@@ -128,6 +128,29 @@ class Sample extends Model.Class<Sample>("Sample")({
128
128
 
129
129
  The decoded value is an integer array in every variant. The database variants encode a native typed `int4[]` parameter; JSON retains the ordinary array. The same storage codec on `select` lets equality filters encode empty arrays too. `PgTypes.array` resolves the built-in `int4` array OID; `getOrThrow` unwraps that known constructor result. PostgreSQL still enforces its integer range on writes.
130
130
 
131
+ For a PostgreSQL `jsonb` column, wrap the value schema with `jsonb`:
132
+
133
+ ```ts
134
+ import { jsonb } from "@shivaedev/sql/jsonb.ts";
135
+
136
+ const Details = Schema.Struct({
137
+ amount: Schema.NumberFromString,
138
+ routes: Schema.Array(Schema.Struct({ routeKey: Schema.String })),
139
+ });
140
+
141
+ class Receipt extends Model.Class<Receipt>("Receipt")({
142
+ id: Schema.Int,
143
+ details: Model.Field({
144
+ select: jsonb(Details),
145
+ insert: jsonb(Details),
146
+ update: jsonb(Details),
147
+ json: Details,
148
+ }),
149
+ }) {}
150
+ ```
151
+
152
+ `jsonb` uses native `PgTypes.jsonb` parameters. The supplied schema encodes nested values for storage and decodes PostgreSQL's returned object through the repository, including projections. Here `amount` is a number in application code and a string inside the stored JSON. Invalid input or stored data fails with `SchemaError`. Use `jsonb(Schema.NullOr(Details))` for a nullable column: a null input binds SQL `NULL`. The application still owns the column's DDL.
153
+
131
154
  ### 2. Per feature: write and query through the model
132
155
 
133
156
  ```ts
@@ -159,6 +182,18 @@ yield* lines.update(input, { onMissing: "fail" });
159
182
 
160
183
  This returns the decoded model or fails with `NoSuchElementError` in the error channel, just like `findById`. It supports single-column and composite keys and executes one `UPDATE … RETURNING` statement without checking existence first. A successful update announces changes after commit; a missing row announces nothing. Without the option, a missing row remains a defect. Versioned repositories use their existing `OptimisticConcurrencyError` contract instead.
161
184
 
185
+ To change chosen columns without reading the row first, pass their names beside an input containing the primary key and those values:
186
+
187
+ ```ts
188
+ yield* lines.update({ id: 1, amount: 55 }, { columns: ["amount"] });
189
+ yield* lines.updateVoid({ id: 1, note: null }, { columns: ["note"] });
190
+ yield* lines.update({ id: 2, name: "Travel" }, { columns: ["name"], onMissing: "fail" });
191
+ ```
192
+
193
+ Each call executes one `UPDATE … RETURNING` without a preliminary read, encodes only the selected fields and every primary-key component through the model's update schemas, and publishes its table, record and old/new bucket keys after commit. Other columns retain their stored values, including omitted update timestamps. The column list is nonempty and contains writable fields other than the primary key; invalid selections fail with `SchemaError`. Composite-key inputs include every key component. `updateVoid` discards the returned row; `update` returns the decoded model and keeps the same missing-row behavior as a complete update. Column selection is available on unversioned repositories.
194
+
195
+ A selected row can be passed unchanged to `update` or `updateVoid`, including a model with native `Model.DateTimeUpdateFromDate`. Repository update inputs accept its ordinary read-back date-time value without requiring `Model.Override`; a supplied value is preserved.
196
+
162
197
  For lists, choose the fields the caller needs:
163
198
 
164
199
  ```ts
@@ -378,6 +413,48 @@ Unconditional batch writes use one `INSERT ... RETURNING` statement per chunk, w
378
413
 
379
414
  Each batch call starts `transact`, so a later chunk failure rolls back earlier chunks. A surrounding `transact` groups several calls into one commit and one deduplicated change batch.
380
415
 
416
+ ### Retention purges
417
+
418
+ On PostgreSQL, `deleteBatched({ where, batchSize, maxRows, pause })` removes matching rows in independently committed transactions and returns the number removed. `where` uses the same encoded filters as `findMany`, including comparisons. Each batch deletes at most `batchSize` rows; the last batch shrinks to respect `maxRows`. `batchSize` is a positive safe integer and `maxRows` is a nonnegative safe integer. A zero cap or no matching rows returns zero without announcing changes.
419
+
420
+ Each nonempty batch publishes one table-level change hint after commit, so queries watching the table refresh once per batch. It does not enumerate record or bucket keys. Use table subscriptions for data subject to retention purges. A later failure rolls back only its batch and its hint; earlier batches remain committed. SQL failures remain typed `SqlError` and invalid limits fail with `SchemaError`.
421
+
422
+ `pause` is an Effect duration between full batches while the cap permits more work. The method holds a PostgreSQL session advisory lock for the run; another purge of that table skips and returns zero, even when called through another repository instance. The lock is released on completion, failure or interruption. The run reserves one connection for the lock and uses another for batch transactions: allow at least two pool connections, plus capacity for other work. Use a direct PostgreSQL connection or session pooling, since transaction pooling cannot preserve session locks. Rows locked by other transactions are skipped and can be removed by a later run. Purges have no ordering guarantee.
423
+
424
+ Call it outside `transact` and native transactions so each batch can commit independently. Calling it inside either, or on another SQL driver, fails with `BatchedDeleteUnavailable` from `@shivaedev/sql/batchedDelete.ts`, whose `reason` is `"transaction"` or `"dialect"`.
425
+
426
+ An hourly job can bound retention work without keeping one large transaction open:
427
+
428
+ ```ts
429
+ import { Clock, Effect } from "effect";
430
+ import { defineSchedule } from "@shivaedev/jobs/server/defineSchedule.ts";
431
+ import { makeRepository } from "@shivaedev/sql/repository.ts";
432
+ import { AuditEntry } from "./models.ts";
433
+
434
+ export const PurgeAudit = defineSchedule({
435
+ name: "purge-audit",
436
+ cron: "0 * * * *",
437
+ }).run(
438
+ Effect.gen(function* () {
439
+ const audit = yield* makeRepository(AuditEntry, {
440
+ idColumn: "id",
441
+ tableName: "audit_entries",
442
+ spanPrefix: "AuditEntry",
443
+ });
444
+ const now = yield* Clock.currentTimeMillis;
445
+ const removed = yield* audit.deleteBatched({
446
+ where: { createdAt: { lt: new Date(now - 30 * 24 * 60 * 60 * 1_000) } },
447
+ batchSize: 1_000,
448
+ maxRows: 50_000,
449
+ pause: "100 millis",
450
+ });
451
+ yield* Effect.log({ removed });
452
+ }),
453
+ );
454
+ ```
455
+
456
+ Here the application's `AuditEntry` model has a `createdAt` field decoded as `Date`. Register `PurgeAudit` in the jobs Layer's `jobs` list and provide the database and change-feed Layers to the worker.
457
+
381
458
  ### Optimistic concurrency
382
459
 
383
460
  Declare a numeric version field in the model's select and update variants, leave it out of insert, and select it with `versionColumn`:
@@ -454,9 +531,15 @@ class Note extends Model.Class<Note>("Note")({
454
531
  }) {}
455
532
 
456
533
  const notes = collection("notes", Note.fields.id, { listId: Note.fields.listId, owner: Note.fields.owner });
534
+ const makeNotes = makeRepository(Note, {
535
+ collection: notes,
536
+ idColumn: "id",
537
+ spanPrefix: "Notes",
538
+ tableName: "notes",
539
+ });
457
540
  ```
458
541
 
459
- Use the repository's table name as the collection name in query read keys. Every inserted, updated or deleted row announces its record key and each declared bucket from the old and new stored values. An insert belongs only to its new buckets; a move announces both sides; a delete announces the old buckets. Bucket codecs decode stored values before producing keys, so a `bucket(Schema.NumberFromString)` field matches a numeric query bucket even when stored as text. Nullable and optional bucket values contribute no key when absent. Bucket codecs must need no services and decode to strings, numbers or absent values.
542
+ Pass the contract collection as the repository's `collection` option when the model has buckets. Registration fails with `BucketRegistrationError` if the collection is missing, its name differs from `tableName`, or its bucket field names differ from the model's annotated fields. The error names both declarations. Repositories without buckets may omit the collection. Every inserted, updated or deleted row announces its record key and each declared bucket from the old and new stored values. An insert belongs only to its new buckets; a move announces both sides; a delete announces the old buckets. Bucket codecs decode stored values before producing keys, so a `bucket(Schema.NumberFromString)` field matches a numeric query bucket even when stored as text. Nullable and optional bucket values contribute no key when absent. Bucket codecs must need no services and decode to strings, numbers or absent values.
460
543
 
461
544
  Bucket writes require PostgreSQL 18 or later: native `RETURNING old` supplies old values atomically, including for conflict updates. Repositories without bucket fields keep their existing SQL dialect support. Bulk writes keep every record and bucket key; the PostgreSQL publisher splits large batches into NOTIFY payloads.
462
545
 
@@ -568,7 +651,7 @@ NOTIFY is a wake-up signal, not a durable log. Transaction payloads contain only
568
651
 
569
652
  Import the module that defines the name; there is no root entry.
570
653
  - `@shivaedev/sql/clientOptions.ts`: `clientOptions(options, { snakeCase? })`, `SqlNameTransforms` — Add default native name transforms to driver or app host options; opt out with `snakeCase: false`.
571
- - `@shivaedev/sql/repository.ts`: `makeRepository(model, options)` — `tableName`, scalar or composite `idColumn`, `spanPrefix`, optional `versionColumn`, `conflictColumns` and `conflictWhere`; requires native `SqlClient`.
654
+ - `@shivaedev/sql/repository.ts`: `makeRepository(model, options)` — `tableName`, scalar or composite `idColumn`, `spanPrefix`, optional `versionColumn`, `conflictColumns` and `conflictWhere`, and `collection` required for bucket models; requires native `SqlClient`.
572
655
  - `@shivaedev/sql/repository.ts`: `OptimisticConcurrencyError` — Typed stale or missing-row failure for versioned writes, with `tableName`, `id`, `expectedVersion`, `reason: "missing" | "stale"`.
573
656
  - `@shivaedev/sql/tupleIn.ts`: `tupleIn(model, fields, tuples, types)` — Filter entry matching two or more fields together against a list of tuples, for `where` in reads and unversioned deletes.
574
657
  - `@shivaedev/sql/upsertResult.ts`: `UpsertRow` — The `{ row, inserted }` result of an unconditional upsert.
@@ -584,6 +667,7 @@ Import the module that defines the name; there is no root entry.
584
667
  - `@shivaedev/sql/pendingPostgresMigrations.ts`: `pendingPostgresMigrations({ loader, table?, components? })` — Pending ledger migrations as ID and name, and pending schema components as name and detail.
585
668
  - `@shivaedev/sql/postgresRelease.ts`: `postgresRelease(release, table?)`, `readPostgresRelease(table?)` — Release marker schema component and its reader.
586
669
  - `@shivaedev/sql/postgresChanges.ts`: `postgresChanges(options)` — Scoped PostgreSQL LISTEN/NOTIFY Layer for commit-bound invalidation.
670
+ - `@shivaedev/sql/repositoryCollection.ts`: `BucketRegistrationError` — Registration failure with table, collection and bucket field names.
587
671
  - `@shivaedev/sql/testing.ts`: `withChangeCoverage(body, { covers })`, `expectPublished(keys)`, `UnannouncedWrites`, `PublishedKeysMismatch` — Test assertions that every write announced its keys and that the expected keys were published.
588
672
 
589
673
  ### Install and database setup
@@ -662,4 +746,12 @@ yield* withChangeCoverage(
662
746
 
663
747
  The coverage check verifies the declarations, not the contents of arbitrary SQL. Raw writers must declare every affected record and bucket, including unchanged buckets. Transaction statistics retain writes from rolled-back savepoints, so those writes still need declarations during a coverage check.
664
748
 
665
- `body.pipe(expectPublished(keys))` compares the distinct published keys, regardless of order, and preserves the body's result. Put it outside the committing transaction. It observes the existing change channel and leaves delivery intact; recorded keys from rolled-back writes do not count. A mismatch fails with `PublishedKeysMismatch`, whose `expected`, `actual` and message show both key sets. The assertion happens after the body, so a mismatch does not roll back a committed write. See [automatic change delivery](https://github.com/ShivaeDev/platform/blob/main/docs/framework/changes.md) for host defaults and coverage limits.
749
+ `body.pipe(expectPublished(keys))` accepts an array or a function of the successful body result and compares the distinct published keys, regardless of order, and preserves the body's result. Put it outside the committing transaction. It observes the existing change channel and leaves delivery intact; recorded keys from rolled-back writes do not count. A mismatch fails with `PublishedKeysMismatch`, whose `expected`, `actual` and message show both key sets. The assertion happens after the body, so a mismatch does not roll back a committed write. For generated ids, derive keys after the write:
750
+
751
+ ```ts
752
+ const note = yield* repository.insert(draft).pipe(
753
+ expectPublished((row: Note) => invalidationKeys([notes.item(row.id), notes.bucket.listId(row.listId), notes.bucket.owner(row.owner)])),
754
+ );
755
+ ```
756
+
757
+ See [automatic change delivery](https://github.com/ShivaeDev/platform/blob/main/docs/framework/changes.md) for host defaults and coverage limits.
@@ -0,0 +1,33 @@
1
+ import { type Duration, Effect, Schema } from "effect";
2
+ import type { Model } from "effect/schema";
3
+ import { SqlClient } from "effect/sql";
4
+ import type { SqlError } from "effect/sql/SqlError";
5
+ import type { Fragment } from "effect/sql/Statement";
6
+ import { type FindManyFilter } from "#repositoryFilter.ts";
7
+ export interface BatchedDeleteOptions<TModel extends Model.Any> {
8
+ readonly batchSize: number;
9
+ readonly maxRows: number;
10
+ readonly pause: Duration.Input;
11
+ readonly where: FindManyFilter<TModel>;
12
+ }
13
+ declare const BatchedDeleteUnavailable_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
14
+ readonly _tag: "BatchedDeleteUnavailable";
15
+ } & Readonly<A>;
16
+ export declare class BatchedDeleteUnavailable extends BatchedDeleteUnavailable_base<{
17
+ readonly reason: "transaction" | "dialect";
18
+ }> {
19
+ }
20
+ export interface BatchedDelete<TModel extends Model.Any> {
21
+ readonly deleteBatched: (options: BatchedDeleteOptions<TModel>) => Effect.Effect<number, SqlError | Schema.SchemaError | BatchedDeleteUnavailable, TModel["fields"][keyof TModel["fields"]]["EncodingServices"]>;
22
+ }
23
+ export declare const makeBatchedDelete: (model: Model.Any, args_1: {
24
+ readonly tableName: string;
25
+ readonly spanPrefix: string;
26
+ }, changes: {
27
+ record: (rows: readonly Readonly<Record<string, unknown>>[]) => Effect.Effect<void, Schema.SchemaError, never>;
28
+ recordTable: (rows: number) => Effect.Effect<void, never, never>;
29
+ returning: (base?: import("effect/sql/Statement").Statement<import("effect/sql/SqlConnection").Row>) => Fragment;
30
+ write: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, SqlError | Exclude<E, SqlError>, Exclude<Exclude<R, SqlClient.SqlClient>, import("effect/reactivity/Reactivity").Reactivity>>;
31
+ }) => Effect.Effect<(options: BatchedDeleteOptions<Model.Any>) => Effect.Effect<number, BatchedDeleteUnavailable | Schema.SchemaError | SqlError, unknown>, never, SqlClient.SqlClient>;
32
+ export {};
33
+ //# sourceMappingURL=batchedDelete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batchedDelete.d.ts","sourceRoot":"","sources":["../src/batchedDelete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,QAAQ,EAAE,MAAM,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAa,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,KAAK,cAAc,EAAc,MAAM,sBAAsB,CAAC;AAGvE,MAAM,WAAW,oBAAoB,CAAC,MAAM,SAAS,KAAK,CAAC,GAAG;IAC7D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;CACvC;;;;AAED,qBAAa,wBAAyB,SAAQ,8BAA6C;IAC1F,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;CAC3C,CAAC;CAAG;AAEL,MAAM,WAAW,aAAa,CAAC,MAAM,SAAS,KAAK,CAAC,GAAG;IACtD,QAAQ,CAAC,aAAa,EAAE,CACvB,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,KACjC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC,WAAW,GAAG,wBAAwB,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;CACnJ;AAMD,eAAO,MAAM,iBAAiB;wBAEoB,MAAM;yBAAuB,MAAM;;;;;;8BA+CnE,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC,0HAa/C,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { Data, Effect, Option, Schema } from "effect";
2
+ import { SqlClient, SqlSchema } from "effect/sql";
3
+ import { makeFilter } from "#repositoryFilter.ts";
4
+ import { tryPurgeLock } from "#tryPurgeLock.ts";
5
+ export class BatchedDeleteUnavailable extends Data.TaggedError("BatchedDeleteUnavailable") {
6
+ }
7
+ const Positive = Schema.Number.check(Schema.isInt(), Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(Number.MAX_SAFE_INTEGER));
8
+ const Nonnegative = Schema.Number.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(0), Schema.isLessThanOrEqualTo(Number.MAX_SAFE_INTEGER));
9
+ const Limits = Schema.Struct({ batchSize: Positive, maxRows: Nonnegative });
10
+ export const makeBatchedDelete = Effect.fnUntraced(function* (model, { tableName, spanPrefix }, changes) {
11
+ const sql = yield* SqlClient.SqlClient;
12
+ const { where } = makeFilter(model, sql);
13
+ const available = Effect.gen(function* () {
14
+ if (sql.driver !== "pg") {
15
+ return yield* new BatchedDeleteUnavailable({ reason: "dialect" });
16
+ }
17
+ if (Option.isSome(yield* Effect.serviceOption(sql.transactionService))) {
18
+ return yield* new BatchedDeleteUnavailable({ reason: "transaction" });
19
+ }
20
+ });
21
+ function deleteBatch(predicate, limit) {
22
+ const count = SqlSchema.findOne({
23
+ execute: (batchLimit) => sql `with removed as (
24
+ delete from ${sql(tableName)} where (tableoid, ctid) in (
25
+ select tableoid, ctid from ${sql(tableName)} where ${predicate} limit ${batchLimit} for update skip locked
26
+ ) returning 1
27
+ ) select count(*)::text as count from removed`,
28
+ Request: Schema.Number,
29
+ Result: Schema.Struct({ count: Schema.NumberFromString }),
30
+ });
31
+ return changes.write(Effect.gen(function* () {
32
+ const result = yield* count(limit).pipe(Effect.catchTag("NoSuchElementError", Effect.die));
33
+ yield* changes.recordTable(result.count);
34
+ return result.count;
35
+ }));
36
+ }
37
+ const runBatches = Effect.fnUntraced(function* (options, predicate) {
38
+ const { batchSize, maxRows } = options;
39
+ let removed = 0;
40
+ while (removed < maxRows) {
41
+ const limit = Math.min(batchSize, maxRows - removed);
42
+ const count = yield* deleteBatch(predicate, limit);
43
+ removed += count;
44
+ if (count < limit || removed === maxRows) {
45
+ break;
46
+ }
47
+ yield* Effect.sleep(options.pause);
48
+ }
49
+ return removed;
50
+ });
51
+ return (options) => Effect.gen(function* () {
52
+ yield* available;
53
+ const { maxRows } = yield* Schema.decodeUnknownEffect(Limits)(options);
54
+ const predicate = yield* where(options.where, true, true);
55
+ if (maxRows === 0) {
56
+ return 0;
57
+ }
58
+ if (!(yield* tryPurgeLock(tableName).pipe(Effect.provideService(SqlClient.SqlClient, sql)))) {
59
+ return 0;
60
+ }
61
+ return yield* runBatches(options, predicate);
62
+ }).pipe(Effect.scoped, Effect.withSpan(`${spanPrefix}.deleteBatched`));
63
+ });
64
+ //# sourceMappingURL=batchedDelete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batchedDelete.js","sourceRoot":"","sources":["../src/batchedDelete.ts"],"names":[],"mappings":"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"}
@@ -3,26 +3,24 @@ import { Effect, Schema } from "effect";
3
3
  import type { Model } from "effect/schema";
4
4
  import { type SqlClient } from "effect/sql";
5
5
  import type { SqlError } from "effect/sql/SqlError";
6
+ import type { BatchedDelete } from "#batchedDelete.ts";
6
7
  import type { RepositoryChanges } from "#repositoryChanges.ts";
7
8
  import type { RepositoryListFilter } from "#repositoryFilter.ts";
9
+ import type { Update, UpdateVoid } from "#repositoryUpdate.ts";
8
10
  import type { IdColumn, NativeRepository } from "#versionedRepository.ts";
9
11
  export type CompositeKey<TModel extends Model.Any> = readonly [IdColumn<TModel>, IdColumn<TModel>, ...IdColumn<TModel>[]];
10
12
  export type PrimaryKey<TModel extends Model.Any> = IdColumn<TModel> | CompositeKey<TModel>;
11
13
  type DeleteWhere<TModel extends Model.Any> = (where: RepositoryListFilter<TModel>) => Effect.Effect<void, SqlError | Schema.SchemaError, TModel["fields"][keyof TModel["fields"]]["EncodingServices"]>;
12
- interface Update<TModel extends Model.Any> {
13
- (input: TModel["update"]["Type"], options: {
14
- readonly onMissing: "fail";
15
- }): Effect.Effect<TModel["Type"], SqlError | Schema.SchemaError | Cause.NoSuchElementError, TModel["update"]["EncodingServices"] | TModel["DecodingServices"]>;
16
- (input: TModel["update"]["Type"]): Effect.Effect<TModel["Type"], SqlError | Schema.SchemaError, TModel["update"]["EncodingServices"] | TModel["DecodingServices"]>;
17
- }
18
- export type Repository<TModel extends Model.Any, TId extends PrimaryKey<TModel>> = [TId] extends [IdColumn<TModel>] ? Omit<NativeRepository<TModel, Extract<TId, IdColumn<TModel>>>, "delete" | "update"> & {
14
+ export type Repository<TModel extends Model.Any, TId extends PrimaryKey<TModel>> = BatchedDelete<TModel> & ([TId] extends [IdColumn<TModel>] ? Omit<NativeRepository<TModel, Extract<TId, IdColumn<TModel>>>, "delete" | "update" | "updateVoid"> & {
19
15
  readonly delete: NativeRepository<TModel, Extract<TId, IdColumn<TModel>>>["delete"] & DeleteWhere<TModel>;
20
- readonly update: Update<TModel>;
21
- } : TId extends CompositeKey<TModel> ? Omit<NativeRepository<TModel, TId[number]>, "findById" | "delete" | "update"> & {
22
- readonly update: Update<TModel>;
16
+ readonly update: Update<TModel, TId extends readonly PropertyKey[] ? TId[number] : Extract<TId, PropertyKey>>;
17
+ readonly updateVoid: UpdateVoid<TModel, TId extends readonly PropertyKey[] ? TId[number] : Extract<TId, PropertyKey>>;
18
+ } : TId extends CompositeKey<TModel> ? Omit<NativeRepository<TModel, TId[number]>, "findById" | "delete" | "update" | "updateVoid"> & {
19
+ readonly update: Update<TModel, TId extends readonly PropertyKey[] ? TId[number] : Extract<TId, PropertyKey>>;
20
+ readonly updateVoid: UpdateVoid<TModel, TId extends readonly PropertyKey[] ? TId[number] : Extract<TId, PropertyKey>>;
23
21
  readonly findById: (id: Pick<TModel["Type"], TId[number]>) => Effect.Effect<TModel["Type"], SqlError | Schema.SchemaError | Cause.NoSuchElementError, TModel["DecodingServices"] | TModel["fields"][TId[number]]["EncodingServices"]>;
24
22
  readonly delete: ((id: Pick<TModel["Type"], TId[number]>) => Effect.Effect<void, SqlError | Schema.SchemaError, TModel["fields"][TId[number]]["EncodingServices"]>) & DeleteWhere<TModel>;
25
- } : never;
23
+ } : never);
26
24
  export declare function makeCompositeCrud(model: Model.Any, sql: SqlClient.SqlClient, options: {
27
25
  readonly columns: readonly string[];
28
26
  readonly tableName: string;
@@ -32,9 +30,12 @@ export declare function makeCompositeCrud(model: Model.Any, sql: SqlClient.SqlCl
32
30
  insert: (input: unknown) => Effect.Effect<unknown, Schema.SchemaError | SqlError, unknown>;
33
31
  insertVoid: (input: unknown) => Effect.Effect<void, Schema.SchemaError | SqlError, unknown>;
34
32
  update: (input: unknown, settings?: {
35
- readonly onMissing: "fail";
33
+ readonly onMissing?: "fail";
34
+ readonly columns?: readonly string[];
35
+ }) => Effect.Effect<unknown, Cause.NoSuchElementError | Schema.SchemaError | SqlError, unknown>;
36
+ updateVoid: (input: unknown, settings?: {
37
+ readonly columns: readonly string[];
36
38
  }) => Effect.Effect<unknown, Cause.NoSuchElementError | Schema.SchemaError | SqlError, unknown>;
37
- updateVoid: (input: unknown) => Effect.Effect<void, Schema.SchemaError | SqlError, unknown>;
38
39
  findById: (id: unknown) => Effect.Effect<unknown, Cause.NoSuchElementError | Schema.SchemaError | SqlError, unknown>;
39
40
  };
40
41
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"compositeRepository.d.ts","sourceRoot":"","sources":["../src/compositeRepository.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compositeRepository.d.ts","sourceRoot":"","sources":["../src/compositeRepository.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"compositeRepository.js","sourceRoot":"","sources":["../src/compositeRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAkB,SAAS,EAAE,MAAM,YAAY,CAAC;AAIvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AA6CxD,MAAM,UAAU,iBAAiB,CAChC,KAAgB,EAChB,GAAwB,EACxB,OAIC,EACD,OAA0B;IAE1B,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAChC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACtB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACxB,CAAC,CAAC,CACF,CAAC;IACF,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1F,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACxF,SAAS,SAAS,CAAC,KAAwC;QAC1D,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAA,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC;QAC9B,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,MAAM,CAAC,OAAO,CACb,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EACpE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAA,iBAAiB,GAAG,CAAC,SAAS,CAAC,UAAU,SAAS,CAAC,GAAG,CAAC,EAAE,CACrE;QACF,OAAO,EAAE,GAAG;QACZ,MAAM,EAAE,KAAK;KACb,CAAC,CAAC;IAEH,OAAO;QACN,GAAG,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC;QAC5E,QAAQ,EAAE,CAAC,EAAW,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,UAAU,WAAW,CAAC,CAAC;KACnF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"compositeRepository.js","sourceRoot":"","sources":["../src/compositeRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAkB,SAAS,EAAE,MAAM,YAAY,CAAC;AAMvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAkCxD,MAAM,UAAU,iBAAiB,CAChC,KAAgB,EAChB,GAAwB,EACxB,OAIC,EACD,OAA0B;IAE1B,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAChC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACtB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACxB,CAAC,CAAC,CACF,CAAC;IACF,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1F,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACxF,SAAS,SAAS,CAAC,KAAwC;QAC1D,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAA,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC;QAC9B,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,MAAM,CAAC,OAAO,CACb,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EACpE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAA,iBAAiB,GAAG,CAAC,SAAS,CAAC,UAAU,SAAS,CAAC,GAAG,CAAC,EAAE,CACrE;QACF,OAAO,EAAE,GAAG;QACZ,MAAM,EAAE,KAAK;KACb,CAAC,CAAC;IAEH,OAAO;QACN,GAAG,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC;QAC5E,QAAQ,EAAE,CAAC,EAAW,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,UAAU,WAAW,CAAC,CAAC;KACnF,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Schema } from "effect";
2
+ export declare function jsonb<TSchema extends Schema.Top>(schema: TSchema): Schema.compose<TSchema, Schema.decodeTo<Schema.Unknown, Schema.Unknown, never, never>>;
3
+ //# sourceMappingURL=jsonb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonb.d.ts","sourceRoot":"","sources":["../src/jsonb.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAE9C,wBAAgB,KAAK,CAAC,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,0FAQhE"}
package/dist/jsonb.js ADDED
@@ -0,0 +1,9 @@
1
+ import * as PgTypes from "@effect/sql-pg/PgTypes";
2
+ import { Schema, SchemaGetter } from "effect";
3
+ export function jsonb(schema) {
4
+ return Schema.Unknown.pipe(Schema.decodeTo(Schema.Unknown, {
5
+ decode: SchemaGetter.transform((value) => (PgTypes.isParameter(value) ? value.value : value)),
6
+ encode: SchemaGetter.transform(PgTypes.jsonb),
7
+ }), Schema.decodeTo(schema));
8
+ }
9
+ //# sourceMappingURL=jsonb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonb.js","sourceRoot":"","sources":["../src/jsonb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE9C,MAAM,UAAU,KAAK,CAA6B,MAAe;IAChE,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CACzB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE;QAC/B,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC7F,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;KAC7C,CAAC,EACF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CACvB,CAAC;AACH,CAAC"}
@@ -5,6 +5,7 @@ import { type BatchWrites } from "#batchWrites.ts";
5
5
  import { type PrimaryKey, type Repository } from "#compositeRepository.ts";
6
6
  import { type ConflictColumns, type ConflictWrites } from "#conflictWrites.ts";
7
7
  import { type SelectWrites } from "#insertFromSelect.ts";
8
+ import { type BucketRegistrationError, type RepositoryOptions } from "#repositoryCollection.ts";
8
9
  import type { FindManyFilter, RepositoryFilter, RepositoryListFilter } from "#repositoryFilter.ts";
9
10
  import { type Queries } from "#repositoryQueries.ts";
10
11
  import { type VersionColumn, type VersionedWrites } from "#versionedRepository.ts";
@@ -36,31 +37,26 @@ export declare class OptimisticConcurrencyError extends OptimisticConcurrencyErr
36
37
  readonly reason: "missing" | "stale";
37
38
  }> {
38
39
  }
39
- interface RepositoryOptions<TId> {
40
- readonly idColumn: TId;
41
- readonly spanPrefix: string;
42
- readonly tableName: string;
43
- }
44
40
  type VersionedRepository<TModel extends Model.Any, TId extends PrimaryKey<TModel>> = Omit<Repository<TModel, TId>, keyof VersionedWrites<TModel, TId>> & VersionedWrites<TModel, TId> & Queries<TModel>;
45
41
  export declare function makeRepository<TModel extends Model.Any, const TId extends PrimaryKey<TModel>, const TConflict extends ConflictColumns<TModel>, const TWhere extends keyof RepositoryFilter<TModel> = never>(model: TModel, options: RepositoryOptions<TId> & {
46
42
  readonly versionColumn: VersionColumn<TModel, TId>;
47
43
  readonly conflictColumns: TConflict;
48
44
  readonly conflictWhere?: Pick<RepositoryFilter<TModel>, TWhere>;
49
- }): Effect.Effect<VersionedRepository<TModel, TId> & Pick<ConflictWrites<TModel, never, TModel["fields"][Extract<TWhere, keyof TModel["fields"]>]["EncodingServices"]>, "insertOrIgnore">, never, SqlClient.SqlClient>;
45
+ }): Effect.Effect<VersionedRepository<TModel, TId> & Pick<ConflictWrites<TModel, never, TModel["fields"][Extract<TWhere, keyof TModel["fields"]>]["EncodingServices"]>, "insertOrIgnore">, BucketRegistrationError, SqlClient.SqlClient>;
50
46
  export declare function makeRepository<TModel extends Model.Any, const TId extends PrimaryKey<TModel>>(model: TModel, options: RepositoryOptions<TId> & {
51
47
  readonly versionColumn: VersionColumn<TModel, TId>;
52
48
  readonly conflictColumns?: never;
53
49
  readonly conflictWhere?: never;
54
- }): Effect.Effect<VersionedRepository<TModel, TId>, never, SqlClient.SqlClient>;
50
+ }): Effect.Effect<VersionedRepository<TModel, TId>, BucketRegistrationError, SqlClient.SqlClient>;
55
51
  export declare function makeRepository<TModel extends Model.Any, const TId extends PrimaryKey<TModel>, const TConflict extends ConflictColumns<TModel>, const TWhere extends keyof RepositoryFilter<TModel> = never>(model: TModel, options: RepositoryOptions<TId> & {
56
52
  readonly versionColumn?: never;
57
53
  readonly conflictColumns: TConflict;
58
54
  readonly conflictWhere?: Pick<RepositoryFilter<TModel>, TWhere>;
59
- }): Effect.Effect<Repository<TModel, TId> & BatchWrites<TModel> & SelectWrites<TModel> & Queries<TModel> & ConflictWrites<TModel, TConflict[number] | (TId extends readonly PropertyKey[] ? TId[number] : TId), TModel["fields"][Extract<TWhere, keyof TModel["fields"]>]["EncodingServices"]>, never, SqlClient.SqlClient>;
55
+ }): Effect.Effect<Repository<TModel, TId> & BatchWrites<TModel> & SelectWrites<TModel> & Queries<TModel> & ConflictWrites<TModel, TConflict[number] | (TId extends readonly PropertyKey[] ? TId[number] : TId), TModel["fields"][Extract<TWhere, keyof TModel["fields"]>]["EncodingServices"]>, BucketRegistrationError, SqlClient.SqlClient>;
60
56
  export declare function makeRepository<TModel extends Model.Any, const TId extends PrimaryKey<TModel>>(model: TModel, options: RepositoryOptions<TId> & {
61
57
  readonly versionColumn?: never;
62
58
  readonly conflictColumns?: never;
63
59
  readonly conflictWhere?: never;
64
- }): Effect.Effect<Repository<TModel, TId> & BatchWrites<TModel> & SelectWrites<TModel> & Queries<TModel>, never, SqlClient.SqlClient>;
60
+ }): Effect.Effect<Repository<TModel, TId> & BatchWrites<TModel> & SelectWrites<TModel> & Queries<TModel>, BucketRegistrationError, SqlClient.SqlClient>;
65
61
  export {};
66
62
  //# sourceMappingURL=repository.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"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"}
@@ -1,43 +1,47 @@
1
1
  import { Data, Effect } from "effect";
2
2
  import { SqlClient } from "effect/sql";
3
+ import { makeBatchedDelete } from "#batchedDelete.ts";
3
4
  import { makeInsertMany } from "#batchWrites.ts";
4
5
  import { makeCompositeCrud } from "#compositeRepository.ts";
5
6
  import { makeConflictWrites } from "#conflictWrites.ts";
6
7
  import { makeInsertFromSelect } from "#insertFromSelect.ts";
7
8
  import { repositoryChanges } from "#repositoryChanges.ts";
9
+ import { validateRepositoryCollection } from "#repositoryCollection.ts";
8
10
  import { makeQueries } from "#repositoryQueries.ts";
9
11
  import { makeVersionedWrites } from "#versionedRepository.ts";
10
12
  export class OptimisticConcurrencyError extends Data.TaggedError("OptimisticConcurrencyError") {
11
13
  }
12
14
  export function makeRepository(model, options) {
13
15
  return Effect.fnUntraced(function* () {
16
+ yield* validateRepositoryCollection(model.fields, options);
14
17
  const sql = yield* SqlClient.SqlClient;
15
18
  const composite = typeof options.idColumn === "object";
16
19
  const idColumns = (composite ? options.idColumn : [options.idColumn]).map(String);
17
20
  const changes = yield* repositoryChanges(sql, options.tableName, idColumns, model.fields);
18
- const crud = makeCompositeCrud(model, sql, { ...options, columns: idColumns }, changes);
21
+ const crud = {
22
+ ...makeCompositeCrud(model, sql, { ...options, columns: idColumns }, changes),
23
+ deleteBatched: yield* makeBatchedDelete(model, options, changes),
24
+ };
19
25
  const queries = makeQueries(model, sql, options);
20
- return options.versionColumn === undefined
21
- ? {
22
- ...crud,
23
- insertFromSelect: makeInsertFromSelect(model, sql, { ...options, changes }, "insertFromSelect"),
24
- insertMany: makeInsertMany(model, sql, { ...options, changes }, "insertMany"),
25
- ...(options.conflictColumns === undefined
26
- ? {}
27
- : makeConflictWrites(model, sql, { ...options, changes, conflictColumns: options.conflictColumns, idColumns })),
28
- ...queries,
29
- }
30
- : {
31
- ...crud,
32
- ...makeVersionedWrites(model, sql, {
26
+ return {
27
+ ...crud,
28
+ ...queries,
29
+ ...(options.versionColumn === undefined
30
+ ? {
31
+ insertFromSelect: makeInsertFromSelect(model, sql, { ...options, changes }, "insertFromSelect"),
32
+ insertMany: makeInsertMany(model, sql, { ...options, changes }, "insertMany"),
33
+ ...(options.conflictColumns === undefined
34
+ ? {}
35
+ : makeConflictWrites(model, sql, { ...options, changes, conflictColumns: options.conflictColumns, idColumns })),
36
+ }
37
+ : makeVersionedWrites(model, sql, {
33
38
  ...options,
34
39
  changes,
35
40
  conflict: (id, expectedVersion, reason) => new OptimisticConcurrencyError({ expectedVersion, id, reason, tableName: options.tableName }),
36
41
  idColumns,
37
42
  versionColumn: options.versionColumn,
38
- }),
39
- ...queries,
40
- };
43
+ })),
44
+ };
41
45
  })();
42
46
  }
43
47
  //# sourceMappingURL=repository.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"repository.js","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAe,MAAM,QAAQ,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAoB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAoC,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAA6C,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EAAE,oBAAoB,EAAqB,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAiB,mBAAmB,EAA4C,MAAM,yBAAyB,CAAC;AAwBvH,MAAM,OAAO,0BAA2B,SAAQ,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAK3F;CAAG;AAsEL,MAAM,UAAU,cAAc,CAC7B,KAAa,EACb,OAIC;IAED,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;QACjC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC;QACvC,MAAM,SAAS,GAAG,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC;QACvD,MAAM,SAAS,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClF,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1F,MAAM,IAAI,GAAG,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;QACxF,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC,aAAa,KAAK,SAAS;YACzC,CAAC,CAAC;gBACA,GAAG,IAAI;gBACP,gBAAgB,EAAE,oBAAoB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,kBAAkB,CAAC;gBAC/F,UAAU,EAAE,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,YAAY,CAAC;gBAC7E,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS;oBACxC,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC;gBAChH,GAAG,OAAO;aACV;YACF,CAAC,CAAC;gBACA,GAAG,IAAI;gBACP,GAAG,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE;oBAClC,GAAG,OAAO;oBACV,OAAO;oBACP,QAAQ,EAAE,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,0BAA0B,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;oBACxI,SAAS;oBACT,aAAa,EAAE,OAAO,CAAC,aAAa;iBACpC,CAAC;gBACF,GAAG,OAAO;aACV,CAAC;IACL,CAAC,CAAC,EAAE,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAe,MAAM,QAAQ,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAoB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAoC,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAA6C,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EAAE,oBAAoB,EAAqB,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAwD,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AAE9H,OAAO,EAAE,WAAW,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAiB,mBAAmB,EAA4C,MAAM,yBAAyB,CAAC;AAwBvH,MAAM,OAAO,0BAA2B,SAAQ,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAK3F;CAAG;AAoEL,MAAM,UAAU,cAAc,CAC7B,KAAa,EACb,OAIC;IAED,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;QACjC,KAAK,CAAC,CAAC,4BAA4B,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC;QACvC,MAAM,SAAS,GAAG,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC;QACvD,MAAM,SAAS,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClF,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1F,MAAM,IAAI,GAAG;YACZ,GAAG,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,CAAC;YAC7E,aAAa,EAAE,KAAK,CAAC,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC;SAChE,CAAC;QACF,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACjD,OAAO;YACN,GAAG,IAAI;YACP,GAAG,OAAO;YACV,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS;gBACtC,CAAC,CAAC;oBACA,gBAAgB,EAAE,oBAAoB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,kBAAkB,CAAC;oBAC/F,UAAU,EAAE,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,YAAY,CAAC;oBAC7E,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS;wBACxC,CAAC,CAAC,EAAE;wBACJ,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC;iBAChH;gBACF,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE;oBAChC,GAAG,OAAO;oBACV,OAAO;oBACP,QAAQ,EAAE,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,0BAA0B,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;oBACxI,SAAS;oBACT,aAAa,EAAE,OAAO,CAAC,aAAa;iBACpC,CAAC,CAAC;SACL,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;AACN,CAAC"}
@@ -4,6 +4,7 @@ import { SqlClient } from "effect/sql";
4
4
  export type RepositoryChanges = Effect.Success<ReturnType<typeof repositoryChanges>>;
5
5
  export declare const repositoryChanges: (sql: SqlClient.SqlClient, table: string, columns: readonly string[], fields?: Schema.Struct.Fields | undefined) => Effect.Effect<{
6
6
  record: (rows: readonly Readonly<Record<string, unknown>>[]) => Effect.Effect<void, Schema.SchemaError, never>;
7
+ recordTable: (rows: number) => Effect.Effect<void, never, never>;
7
8
  returning: (base?: import("effect/sql/Statement").Statement<import("effect/sql/SqlConnection").Row>) => import("effect/sql/Statement").Fragment;
8
9
  write: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, import("effect/sql/SqlError").SqlError | Exclude<E, import("effect/sql/SqlError").SqlError>, Exclude<Exclude<R, SqlClient.SqlClient>, Reactivity.Reactivity>>;
9
10
  }, never, never>;
@@ -1 +1 @@
1
- {"version":3,"file":"repositoryChanges.d.ts","sourceRoot":"","sources":["../src/repositoryChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAMvC,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAErF,eAAO,MAAM,iBAAiB;;;YAuDd,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBAIrD,CAAC"}
1
+ {"version":3,"file":"repositoryChanges.d.ts","sourceRoot":"","sources":["../src/repositoryChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAMvC,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAErF,eAAO,MAAM,iBAAiB;;;;YAuDd,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBAYrD,CAAC"}
@@ -50,6 +50,14 @@ export const repositoryChanges = Effect.fnUntraced(function* (sql, table, column
50
50
  function write(effect) {
51
51
  return provide(transact(effect, { onSqlError: (error) => error }));
52
52
  }
53
- return { record, returning, write };
53
+ const recordTable = Effect.fnUntraced(function* (rows) {
54
+ if (rows === 0) {
55
+ return;
56
+ }
57
+ const declarations = yield* ChangeDeclarations;
58
+ yield* declarations.declare(table, [table], rows);
59
+ yield* provide(invalidateOnCommit([table]));
60
+ });
61
+ return { record, recordTable, returning, write };
54
62
  });
55
63
  //# sourceMappingURL=repositoryChanges.js.map