@sequenceholdings/orm 2.9.0 → 2.11.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 (50) hide show
  1. package/README.md +71 -0
  2. package/dist/authoring.cjs +796 -7
  3. package/dist/authoring.cjs.map +1 -1
  4. package/dist/authoring.d.cts +11 -2
  5. package/dist/authoring.d.ts +11 -2
  6. package/dist/authoring.js +796 -7
  7. package/dist/authoring.js.map +1 -1
  8. package/dist/canonical.cjs +777 -6
  9. package/dist/canonical.cjs.map +1 -1
  10. package/dist/canonical.d.cts +43 -43
  11. package/dist/canonical.d.ts +43 -43
  12. package/dist/canonical.js +777 -6
  13. package/dist/canonical.js.map +1 -1
  14. package/dist/cli.cjs +7585 -7512
  15. package/dist/cli.cjs.map +1 -1
  16. package/dist/cli.d.cts +10 -1
  17. package/dist/cli.d.ts +10 -1
  18. package/dist/cli.js +7584 -7513
  19. package/dist/cli.js.map +1 -1
  20. package/dist/compiler.cjs +1059 -50
  21. package/dist/compiler.cjs.map +1 -1
  22. package/dist/compiler.d.cts +182 -2
  23. package/dist/compiler.d.ts +182 -2
  24. package/dist/compiler.js +1054 -51
  25. package/dist/compiler.js.map +1 -1
  26. package/dist/index.cjs +3720 -3447
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +96 -31
  29. package/dist/index.d.ts +96 -31
  30. package/dist/index.js +3714 -3446
  31. package/dist/index.js.map +1 -1
  32. package/dist/ir.cjs +787 -14
  33. package/dist/ir.cjs.map +1 -1
  34. package/dist/ir.d.cts +70 -59
  35. package/dist/ir.d.ts +70 -59
  36. package/dist/ir.js +787 -15
  37. package/dist/ir.js.map +1 -1
  38. package/dist/predicate-v2.cjs +802 -30
  39. package/dist/predicate-v2.cjs.map +1 -1
  40. package/dist/predicate-v2.d.cts +2 -0
  41. package/dist/predicate-v2.d.ts +2 -0
  42. package/dist/predicate-v2.js +802 -30
  43. package/dist/predicate-v2.js.map +1 -1
  44. package/dist/sdl.cjs +794 -24
  45. package/dist/sdl.cjs.map +1 -1
  46. package/dist/sdl.js +794 -24
  47. package/dist/sdl.js.map +1 -1
  48. package/package.json +1 -1
  49. package/dist/{definition-B99BsOAO.d.cts → definition-CevES7lM.d.cts} +2 -2
  50. package/dist/{definition-B99BsOAO.d.ts → definition-CevES7lM.d.ts} +2 -2
package/README.md CHANGED
@@ -170,6 +170,77 @@ the declaration with casts or edits to generated canonical JSON. ORM releases
170
170
  use the separate [Studio CLI chain release workflow](https://github.com/sequenceholdings/studio/blob/main/.changeset/README.md#studio-cli-chain-releases);
171
171
  chain packages do not use Changesets.
172
172
 
173
+ ## Synced table indexes (introduced in 2.11.0)
174
+
175
+ A typed synced table can declare non-unique secondary btree indexes with the
176
+ same `IndexInput` shape `defineTable` uses. The sync still owns the relation's
177
+ columns, keys and rows; the ORM owns only these indexes.
178
+
179
+ ```ts
180
+ export const links = defineSyncedTable("synced_customer_transaction_links", {
181
+ memberCustomerUid: t.text(), transactionUid: t.text(), postDate: t.date(),
182
+ relationshipManagerId: t.text(),
183
+ }, {
184
+ source: "gold.customer_transaction_links_current",
185
+ primaryKey: ["memberCustomerUid", "transactionUid"],
186
+ policies: { read: "true" },
187
+ indexes: [
188
+ { columns: ["postDate", "transactionUid"], name: "ix_ctl_post_date_txn" },
189
+ { columns: ["relationshipManagerId", "postDate", "transactionUid"], name: "ix_ctl_rm_post_date_txn" },
190
+ ],
191
+ });
192
+ ```
193
+
194
+ - Only typed synced tables (declared columns) can declare indexes. Every index
195
+ column must be declared. `unique: true` is rejected: the primary key already
196
+ identifies a row, and a unique index can fail the sync.
197
+ - Names follow `defineTable`: explicit, or `ix_<table>_<columns>`. They must fit
198
+ Postgres's 63-byte limit and be unique in the namespace. The index lives in
199
+ the physical relation's schema (for example `gold`), not `orm_<namespace>`.
200
+ - Indexes are part of the canonical form and content hash. Adding, changing or
201
+ removing one produces a new committed migration whose snapshot records them
202
+ under `_sequenceOrm.syncedIndexes`. Its SQL has no statements for them,
203
+ because the physical relation is bound per environment.
204
+ - Apply resolves each synced table's backing, the relation the serving stage
205
+ bound (not `source`). If the index name is free, it runs `CREATE INDEX` on that
206
+ relation and, in the same transaction, records the new index's OID in the
207
+ namespace's ledger, `orm_<namespace>._synced_index_ledger`. It drops removed or
208
+ changed indexes with a guarded `DROP INDEX IF EXISTS`, from the relation they
209
+ were on before a rebind, and deletes their ledger rows. Then it verifies each
210
+ index is the recorded, valid, non-unique btree on that relation with the
211
+ declared keys. Apply re-asserts them every time and is idempotent.
212
+ - **Ownership:** an index is the ORM's only while a ledger row for this
213
+ namespace's table and relation records its current OID. Apply never drops,
214
+ replaces or adopts any other index: a same-named index the sync built (even a
215
+ unique one), another namespace's index on a shared backing, or one someone
216
+ dropped and recreated under the name (it has a new OID). Apply fails with
217
+ SQLSTATE `55000` instead; rename the declared index. A ledger row whose index
218
+ vanished (the pipeline recreated the table) counts as not built, so the next
219
+ apply or reconcile builds and records it again.
220
+ - The index is created on the partitioned parent (never `ON ONLY`), so every
221
+ current partition and every partition a SNAPSHOT sync later attaches gets one.
222
+ - **Locking:** a partitioned parent cannot build `CONCURRENTLY`. The build holds
223
+ a `SHARE` lock that blocks the sync's writes until it finishes. Apply on a
224
+ large table between sync runs.
225
+ - **Privileges:** on Lakebase the applying identity can `CREATE INDEX` and
226
+ `DROP INDEX` on the sync's relation without owning it; the index belongs to
227
+ the relation's owner, so nothing that needs index ownership (`COMMENT ON
228
+ INDEX`, `ALTER INDEX`, `REINDEX`) is ever emitted. Each statement starts as
229
+ the applier, switches with `set_config('role', <schema owner>, true)` only to
230
+ read or write the ledger, and switches back before any index DDL. The ledger
231
+ lives in the namespace schema, belongs to its owner (`orm_exec`), and grants
232
+ consumers nothing; drizzle-kit convergence ignores it.
233
+ - **Drift:** if a pipeline drops and recreates the synced table, the indexes go
234
+ with it. `pendingSyncedIndexStatements` reports the missing ones, and any
235
+ index the ledger does not record. It reads the ledger as the schema owner in
236
+ one transaction, so pass a drizzle database that supports `transaction`. Atlas checks
237
+ them in rehearsal, reports them on `GET /api/orm/namespaces/<ns>/synced-indexes`,
238
+ and restores them on `POST` with `{ "expected_version_id": "<active version>" }`
239
+ (namespace admin) or on the next schema apply.
240
+ - `orm apply` requires a runtime that advertises `syncedIndexes` on
241
+ `/api/orm/runtime-capabilities`. Reviewed (controlled) and frozen namespaces
242
+ refuse synced indexes. v1 YAML synced tables still cannot declare indexes.
243
+
173
244
  ## Default read-only SQL (introduced in 2.6.0)
174
245
 
175
246
  With the matching SDK and Atlas rollout, every active v2 namespace supports