qubu 0.6.0 → 0.6.2

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 (95) hide show
  1. package/README.md +112 -0
  2. package/dist/{complete-DP7pliuY.mjs → canonical-B5_ouh-c.mjs} +466 -241
  3. package/dist/codegen.d.mts +2 -2
  4. package/dist/codegen.mjs +180 -90
  5. package/dist/column-Cyc2CMnG.mjs +116 -0
  6. package/dist/column-DDRvD7SF.mjs +721 -0
  7. package/dist/{constraints-YGyNPQ_z.mjs → constraints-CAmi18Uk.mjs} +8 -3
  8. package/dist/core.d.mts +3 -3
  9. package/dist/core.mjs +4 -5
  10. package/dist/diagnostics-I9vVtXkc.mjs +40 -0
  11. package/dist/diff.d.mts +9 -9
  12. package/dist/diff.mjs +152 -102
  13. package/dist/{explain-CkIK13L_.mjs → explain-BIqEmZha.mjs} +1 -1
  14. package/dist/expressions-_6JF_J77.mjs +130 -0
  15. package/dist/index-CaxrMD1A.d.mts +1 -0
  16. package/dist/index.d.mts +2 -2
  17. package/dist/index.mjs +414 -77
  18. package/dist/introspection/mysql.d.mts +26 -0
  19. package/dist/introspection/mysql.mjs +1278 -0
  20. package/dist/introspection/postgres.d.mts +43 -0
  21. package/dist/introspection/postgres.mjs +1889 -0
  22. package/dist/introspection/sqlite.d.mts +15 -0
  23. package/dist/introspection/sqlite.mjs +1172 -0
  24. package/dist/introspection.d.mts +26 -87
  25. package/dist/introspection.mjs +3 -4351
  26. package/dist/mysql.d.mts +3 -3
  27. package/dist/mysql.mjs +8 -7
  28. package/dist/{errors-Dxv73YJu.mjs → omit-VEr9Ydux.mjs} +5 -1
  29. package/dist/{on-conflict-DZQ85f1t.mjs → on-conflict-B2rFyHGF.mjs} +78 -8
  30. package/dist/on-duplicate-key-update-Czsw1Yq-.mjs +95 -0
  31. package/dist/postgres-hFhd0I9n.mjs +68 -0
  32. package/dist/postgres.d.mts +3 -3
  33. package/dist/postgres.mjs +3 -52
  34. package/dist/registry-BXE_4M9P.mjs +127 -0
  35. package/dist/{relational-CxnLCqZQ.mjs → relational-CoPBETjI.mjs} +3 -3
  36. package/dist/schema.d.mts +2 -2
  37. package/dist/schema.mjs +8 -7
  38. package/dist/{serialize-BN07IK0v.mjs → serialize-CyobNEx-.mjs} +174 -30
  39. package/dist/serialize-Du2UPZMt.d.mts +92 -0
  40. package/dist/snapshot/mysql.d.mts +5 -5
  41. package/dist/snapshot/mysql.mjs +32 -32
  42. package/dist/snapshot/postgres.d.mts +5 -5
  43. package/dist/snapshot/postgres.mjs +25 -25
  44. package/dist/snapshot/sqlite.d.mts +5 -5
  45. package/dist/snapshot/sqlite.mjs +30 -30
  46. package/dist/snapshot-mIb-Zzb5.mjs +1489 -0
  47. package/dist/snapshot.d.mts +4 -5
  48. package/dist/snapshot.mjs +3 -4
  49. package/dist/{source-SqrKWjFJ.mjs → source-DYSUqzvb.mjs} +2 -2
  50. package/dist/sqlite.d.mts +2 -2
  51. package/dist/sqlite.mjs +10 -10
  52. package/dist/{table-BwflqeAj.mjs → table-B8zEq0az.mjs} +4 -4
  53. package/dist/{types-BIJsj2fJ.mjs → types-CYHpSPwj.mjs} +10 -7
  54. package/dist/{types-CTCqtFlS.d.mts → types-CiMvKi5V.d.mts} +14 -4
  55. package/dist/{types-C0VkiwpR.d.mts → types-Dqr4o2I1.d.mts} +640 -189
  56. package/dist/value-CpaUFtjw.mjs +45 -0
  57. package/dist/vite/ambient.d.ts +2 -0
  58. package/dist/vite.d.mts +1 -1
  59. package/dist/vite.mjs +2 -0
  60. package/docs/dialects-and-execution.md +61 -11
  61. package/docs/getting-started.md +1 -1
  62. package/docs/guides/compose-queries.md +22 -0
  63. package/docs/guides/drizzle.md +11 -11
  64. package/docs/guides/extensions/typed-expressions.md +5 -3
  65. package/docs/guides/json.md +95 -2
  66. package/docs/guides/mutations.md +125 -0
  67. package/docs/guides/valtio-sync.md +113 -0
  68. package/docs/index.md +1 -1
  69. package/docs/migrations/adapters.md +58 -21
  70. package/docs/migrations/index.md +50 -12
  71. package/docs/migrations/operations.md +20 -6
  72. package/docs/migrations/recovery.md +7 -1
  73. package/docs/query-model/fragments.md +21 -1
  74. package/docs/reference/introspection-support.md +16 -18
  75. package/docs/reference/supported-surface.md +23 -11
  76. package/docs/schema/catalog-model.md +20 -7
  77. package/docs/schema/code-generation.md +4 -3
  78. package/docs/schema/diff.md +2 -2
  79. package/docs/schema/introspection.md +24 -16
  80. package/docs/schema/snapshots.md +18 -8
  81. package/docs/schema/storage-and-schema-sql.md +7 -2
  82. package/docs/sql-semantic-types.md +8 -0
  83. package/package.json +14 -1
  84. package/dist/canonical-DMvR9yBe.mjs +0 -972
  85. package/dist/column-Da37jYSD.mjs +0 -309
  86. package/dist/column-r1Y4ivwt.mjs +0 -327
  87. package/dist/complete-types-CY0KbzNw.d.mts +0 -371
  88. package/dist/index-B2rZf3-2.d.mts +0 -32
  89. package/dist/json-Db7XRD91.mjs +0 -169
  90. package/dist/omit-OxV58AwX.mjs +0 -5
  91. package/dist/registry-BRcUuazJ.mjs +0 -256
  92. package/dist/serialize-CEIIlWhC.d.mts +0 -66
  93. package/dist/snapshot-Xam8-q0j.mjs +0 -392
  94. package/dist/standard-DfcZEVOj.mjs +0 -12
  95. package/dist/value-D14I_XgL.mjs +0 -29
package/docs/index.md CHANGED
@@ -33,7 +33,7 @@ define a table, build a `SELECT`, and inspect its SQL and parameters.
33
33
  derivation and a native transactional database adapter.
34
34
  - [Extend Qubu](guides/extensions/overview.md) with a custom source, clause,
35
35
  dialect policy, or typed expression.
36
- - [Read JSON scalars](guides/json.md) from structured JSON paths.
36
+ - [Query nested JSON](guides/json.md) or read scalars from structured paths.
37
37
  - [Enable the Vite compiler hint](guides/vite-plugin.md) when query modules
38
38
  should opt into named imports through a directive.
39
39
  - [Inspect an existing database](schema/introspection.md) through the optional
@@ -2,38 +2,47 @@
2
2
 
3
3
  > Select a migration adapter from capabilities proven by its driver and environment, not from dialect name alone.
4
4
 
5
- Every executable migration adapter opens one pinned migration session and
5
+ Every executable migration adapter opens a migration session and
6
6
  advertises the exact behavior the executor may use:
7
7
 
8
- | Field | Contract |
9
- | -------------------------------------- | ----------------------------------------------------------------------------------- |
10
- | `dialect`, `serverVersion` | Physical target and optional version used for compatibility checks |
11
- | `session` | Must be `pinned` until `close()` resolves |
12
- | `transactionalDdl` | Whether DDL effects can roll back |
13
- | `optionalTransactions`, `transactions` | Whether optional phases join a transaction and which requirements are proven |
14
- | `lease`, `leaseKind` | Database-backed exclusion of another migration runner |
15
- | `locks` | Independently supported program DDL lock requirements |
16
- | `journal` | Database storage, head compare-and-swap, and atomic applied-record/head advancement |
17
- | `parameters` | Supported tagged parameter kinds |
18
- | `commitAmbiguity` | Ambiguous commit becomes `recovery-required` |
19
- | `forbiddenPhases` | Checkpointed support or explicit rejection |
20
- | `features` | Named constraints an artifact may require |
8
+ | Field | Contract |
9
+ | -------------------------------------- | -------------------------------------------------------------------------------------- |
10
+ | `dialect`, `serverVersion` | Physical target and optional version used for compatibility checks |
11
+ | `session` | `pinned` for the full lifecycle, or `atomic-batch` for one complete artifact per batch |
12
+ | `transactionalDdl` | Whether DDL effects can roll back |
13
+ | `optionalTransactions`, `transactions` | Whether optional phases join a transaction and which requirements are proven |
14
+ | `lease`, `leaseKind` | Database-backed exclusion of another migration runner |
15
+ | `locks` | Independently supported program DDL lock requirements |
16
+ | `journal` | Database storage, head compare-and-swap, and atomic applied-record/head advancement |
17
+ | `parameters` | Supported tagged parameter kinds |
18
+ | `commitAmbiguity` | Ambiguous commit becomes `recovery-required` |
19
+ | `forbiddenPhases` | Checkpointed support or explicit rejection |
20
+ | `features` | Named constraints an artifact may require |
21
21
 
22
22
  The migrator lease and a program's DDL lock are different controls. The lease
23
23
  excludes another Qubu runner; a DDL lock protects the database operation. The
24
24
  executor never treats one as proof of the other.
25
25
 
26
+ ## Trusted migration SQL
27
+
28
+ Migration SQL, including SQL conditions, is trusted across all adapters. Qubu
29
+ validates program structure and adapter capabilities, but does not parse SQL
30
+ to enforce safety. Callers must preserve executor-owned transactions, connection
31
+ settings, and migration journal state. For example, an explicit `COMMIT` can
32
+ leave schema changes applied without their journal record; atomicity and recovery
33
+ guarantees depend on respecting this contract.
34
+
26
35
  ## Current profiles
27
36
 
28
37
  The following stable profiles have live conformance coverage in this checkout:
29
38
 
30
- | Migration entrypoint | Dialect | Transactions | Locks | Forbidden phases | Notes |
31
- | ------------------------------------- | ---------- | ----------------------------- | --------------- | ---------------- | --------------------------------------------------- |
32
- | `@qubu/adapter-libsql/migration` | SQLite | required, optional | none, exclusive | unsupported | Pinned application-owned client |
33
- | `@qubu/adapter-node-sqlite/migration` | SQLite | required, optional | none, exclusive | unsupported | Pinned application-owned `DatabaseSync` |
34
- | `@qubu/adapter-pg/migration` | PostgreSQL | required, optional, forbidden | none, exclusive | checkpointed | Caller supplies an already-pinned client |
35
- | `@qubu/adapter-postgresjs/migration` | PostgreSQL | required, optional, forbidden | none, exclusive | checkpointed | Reserves and releases one connection |
36
- | `@qubu/adapter-pglite/migration` | PostgreSQL | required, optional, forbidden | none, exclusive | checkpointed | Uses the database query queue as the pinned session |
39
+ | Migration entrypoint | Dialect | Transactions | Locks | Forbidden phases | Notes |
40
+ | ------------------------------------- | ---------- | ----------------------------- | --------------- | ---------------- | ------------------------------------------------------ |
41
+ | `@qubu/adapter-libsql/migration` | SQLite | required, optional | none, exclusive | unsupported | Single-phase atomic batches through `client.migrate()` |
42
+ | `@qubu/adapter-node-sqlite/migration` | SQLite | required, optional | none, exclusive | unsupported | Pinned application-owned `DatabaseSync` |
43
+ | `@qubu/adapter-pg/migration` | PostgreSQL | required, optional, forbidden | none, exclusive | checkpointed | Caller supplies an already-pinned client |
44
+ | `@qubu/adapter-postgresjs/migration` | PostgreSQL | required, optional, forbidden | none, exclusive | checkpointed | Reserves and releases one connection |
45
+ | `@qubu/adapter-pglite/migration` | PostgreSQL | required, optional, forbidden | none, exclusive | checkpointed | Uses the database query queue as the pinned session |
37
46
 
38
47
  All five support every current tagged parameter kind (`null`, `boolean`,
39
48
  `string`, `number`, `bigint`, `bytes`, and `json`), a database journal and
@@ -68,3 +77,31 @@ const adapter = libsqlMigrationAdapter(client, {
68
77
 
69
78
  `DATABASE_URL` remains application configuration; neither the adapter nor CLI
70
79
  assigns deployment-provider meaning to it.
80
+
81
+ ## libSQL batch execution
82
+
83
+ Each executable artifact must contain exactly one phase and an embedded before
84
+ snapshot. The adapter submits its statements, SQL assertions, applied-history
85
+ record, head update, and terminal attempt state in one `client.migrate()` call.
86
+ For example, creating a table and recording that migration either both commit
87
+ or both roll back. Multiple artifacts are separate batches; earlier successful
88
+ artifacts remain applied if a later one fails.
89
+
90
+ Preparation reads the schema in a read transaction. The submitted batch checks
91
+ that the catalog still matches that inspection, the lease is still owned, and
92
+ the head still equals the expected parent. Foreign-key validation runs before
93
+ commit because libSQL temporarily disables enforcement during `migrate()`.
94
+
95
+ Schema fingerprint and property preconditions are checked against the embedded
96
+ before snapshot, whose physical facts are verified during preparation and
97
+ guarded by the in-batch catalog assertion. Object-presence and scalar SQL checks
98
+ run inside the batch. Postconditions must be object-presence/absence checks
99
+ without fingerprints, or scalar SQL checks returning `1`. Unsupported conditions
100
+ and multiple phases are rejected. SQL content is passed to the driver without
101
+ safety validation; each program entry must follow the driver's statement contract.
102
+
103
+ The database-row lease has no expiry or heartbeat. A process crash can leave
104
+ it held; ownership must be resolved before another runner can proceed. A lost
105
+ batch response is an uncertain outcome requiring journal inspection and, when
106
+ the attempt remains unresolved, explicit recovery. It is never assumed to be
107
+ a successful rollback.
@@ -25,18 +25,26 @@ The `@qubu/migrate` root intentionally exports only format/version constants
25
25
  and the central plan and artifact types. Import behavior from its focused
26
26
  entrypoint:
27
27
 
28
- | Entrypoint | Use it for |
29
- | -------------------------- | -------------------------------------------------------------------------- |
30
- | `@qubu/migrate/plan` | Create, encode, decode, fingerprint, and validate migration plans |
31
- | `@qubu/migrate/ddl` | Preview deterministic dialect SQL without opening a database |
32
- | `@qubu/migrate/artifact` | Compile programs; canonicalize, digest, seal, encode, and decode artifacts |
33
- | `@qubu/migrate/repository` | Verify a complete artifact chain and its journal prefix |
34
- | `@qubu/migrate/journal` | Implement or inspect the storage-neutral journal contract |
35
- | `@qubu/migrate/executor` | Apply artifacts and reconcile uncertain attempts |
36
- | `@qubu/migrate/baseline` | Verify and record the initial non-executable baseline |
37
- | `@qubu/migrate/status` | Inspect pending work, drift, requirements, and interrupted attempts |
38
- | `@qubu/migrate/bootstrap` | Plan a fresh SQLite database through the normal compiler |
39
- | `@qubu/migrate/testing` | Test adapter capabilities and deterministic failure boundaries |
28
+ | Entrypoint | Use it for |
29
+ | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
30
+ | `@qubu/migrate/plan` | Create, encode, decode, fingerprint, and validate migration plans |
31
+ | `@qubu/migrate/ddl` | Preview deterministic dialect SQL without opening a database |
32
+ | `@qubu/migrate/ddl/postgres` | Preview PostgreSQL SQL from an approved migration plan |
33
+ | `@qubu/migrate/ddl/sqlite` | Preview SQLite SQL from an approved migration plan |
34
+ | `@qubu/migrate/ddl/mysql` | Preview MySQL SQL from an approved migration plan |
35
+ | `@qubu/migrate/artifact` | Compile programs with a caller-supplied `SchemaDialect`; canonicalize, digest, seal, encode, and decode artifacts |
36
+ | `@qubu/migrate/artifact/postgres` | Compile reviewed plans with PostgreSQL's schema dialect |
37
+ | `@qubu/migrate/artifact/sqlite` | Compile reviewed plans with SQLite's schema dialect, including table rebuilds |
38
+ | `@qubu/migrate/artifact/mysql` | Compile reviewed plans with MySQL's schema dialect |
39
+ | `@qubu/migrate/repository` | Verify a complete artifact chain and its journal prefix |
40
+ | `@qubu/migrate/journal` | Implement or inspect the storage-neutral journal contract |
41
+ | `@qubu/migrate/executor` | Apply artifacts and reconcile uncertain attempts |
42
+ | `@qubu/migrate/baseline` | Verify and record the initial non-executable baseline |
43
+ | `@qubu/migrate/status` | Inspect pending work, drift, requirements, and interrupted attempts |
44
+ | `@qubu/migrate/bootstrap` | Prepare a fresh schema diff and expose shared bootstrap types; accepts a caller-supplied `SchemaDialect` for generic planning |
45
+ | `@qubu/migrate/bootstrap/postgres` | Plan a fresh PostgreSQL schema through the normal compiler |
46
+ | `@qubu/migrate/bootstrap/sqlite` | Plan a fresh SQLite schema through the normal compiler |
47
+ | `@qubu/migrate/testing` | Test adapter capabilities and deterministic failure boundaries |
40
48
 
41
49
  Start with [Artifacts and approval policy](artifacts-and-policy.md) when
42
50
  reviewing a migration format. Check [Adapter capability
@@ -44,3 +52,33 @@ profiles](adapters.md), use [Command line operations](operations.md) to
44
52
  configure an application, then keep [Recovery and reconciliation](recovery.md)
45
53
  with the deployment runbook. [Lotta Games adoption](lotta-adoption.md) records
46
54
  the downstream cutover boundary and current combo-matrix blocker.
55
+
56
+ Choose the dialect-specific bootstrap entrypoint when using a built-in dialect:
57
+
58
+ ```ts
59
+ import { planSchemaBootstrap } from "@qubu/migrate/bootstrap/postgres"
60
+
61
+ const result = planSchemaBootstrap(targetSnapshot)
62
+ ```
63
+
64
+ The neutral `@qubu/migrate/bootstrap` entrypoint contains the shared preparation
65
+ logic and generic planner. The PostgreSQL and SQLite entrypoints each import
66
+ only their matching schema dialect.
67
+
68
+ Use the same entrypoint pattern for convenience artifact compilers:
69
+
70
+ ```ts
71
+ import { compileMigrationProgram } from "@qubu/migrate/artifact/postgres"
72
+
73
+ const compiled = compileMigrationProgram(plan)
74
+ ```
75
+
76
+ The DDL entrypoints follow the same pattern. Use the neutral entrypoint when
77
+ the application supplies a `SchemaDialect`; use a dialect subpath when the
78
+ built-in dialect should be selected by the module:
79
+
80
+ ```ts
81
+ import { emitMigrationPlan } from "@qubu/migrate/ddl/postgres"
82
+
83
+ const preview = emitMigrationPlan(plan)
84
+ ```
@@ -70,7 +70,7 @@ working directory.
70
70
  | `qubu migrate apply [--dry-run]` | Applies the complete verified pending chain; dry-run performs status/preflight only | It never limits discovery to Git-added or branch-diff files |
71
71
  | `qubu migrate baseline <id> --confirm <fact>... [--dry-run]` | Without dry-run, strictly compares the live managed schema, initializes an empty journal, records baseline, then writes the artifact | Requires an empty artifact repository and all seven exact confirmations; dry-run does not inspect the database |
72
72
  | `qubu migrate reconcile <attempt-id> --outcome applied\|rolled_back --reason <text>` | Runs application-owned verification, then records the explicit outcome | Requires `verifyReconciliation` in config; no automatic inference |
73
- | `qubu schema bootstrap [--approve <operation-id=reason>...] [--dry-run]` | Plans an empty SQLite snapshot through diff/plan/program; executes through the normal executor unless dry-run | Currently rejects non-SQLite targets |
73
+ | `qubu schema bootstrap [--approve <operation-id=reason>...] [--dry-run]` | Plans an empty SQLite or PostgreSQL snapshot through diff/plan/program; executes through the normal executor unless dry-run | Rejects other dialects; unsafe or incomplete facts still require exact approvals or custom programs |
74
74
 
75
75
  JSON output is stable, newline-terminated, recursively key-sorted, and redacts
76
76
  credential-like keys and credentials or secrets embedded in URLs. Human output
@@ -94,11 +94,25 @@ snapshot. Logical IDs help reporting but do not prove equality. Objects not
94
94
  owned by the managed snapshot are returned separately as `unmanagedObjects`;
95
95
  Qubu journal objects are excluded by migration snapshot readers.
96
96
 
97
- `schema bootstrap` is for a fresh SQLite database. It produces the same
98
- versioned program and validation path as a migration. SQLite inline constraints
99
- are compiled into table creation, while table rebuilds are explicit phases with
100
- copy/postcondition checks. Session settings such as SQLite PRAGMAs remain in
101
- the application or adapter setup.
97
+ `schema bootstrap` is for a fresh SQLite database or a fresh PostgreSQL schema.
98
+ It produces the same reviewed plan, versioned program, sealed artifact, and
99
+ executor path as a migration. A complete PostgreSQL snapshot retains standalone
100
+ enums as authoritative objects; bootstrap creates each enum before a table that
101
+ uses it as a native column type. SQLite inline constraints are compiled into
102
+ table creation, while table rebuilds are explicit phases with copy/postcondition
103
+ checks. Session settings such as SQLite PRAGMAs remain in the application or
104
+ adapter setup.
105
+
106
+ Use the reviewed complete snapshot directly as the PostgreSQL target:
107
+
108
+ ```bash
109
+ qubu schema bootstrap --dry-run --format json --non-interactive
110
+ ```
111
+
112
+ The dry run prints the ordered phases without opening the adapter. Remove
113
+ `--dry-run` only after reviewing any operation IDs that require `--approve` or
114
+ an application-owned custom program. Bootstrap does not import or replay
115
+ Drizzle migration history.
102
116
 
103
117
  ## Baseline and cutover checklist
104
118
 
@@ -46,13 +46,19 @@ head, or a non-prefix repository fail before any statement executes.
46
46
  ## Execution and concurrency guarantees
47
47
 
48
48
  For each invocation, the executor verifies the entire repository, opens one
49
- pinned session, checks capabilities, acquires the migrator lease, validates the
49
+ migration session, checks capabilities, acquires the migrator lease, validates the
50
50
  journal and repository prefix, checks the live before-snapshot digest, then
51
51
  applies each pending artifact. Within an artifact it creates an attempt,
52
52
  executes ordered phases with preconditions and postconditions, writes durable
53
53
  checkpoints, appends immutable history, and compare-and-swaps the head.
54
54
  Resources are released in reverse order: DDL lock, migrator lease, then session.
55
55
 
56
+ An `atomic-batch` profile instead applies one single-phase artifact in one
57
+ database transaction, including its checks and terminal journal writes. It
58
+ records a completed phase checkpoint rather than intermediate statement
59
+ checkpoints. See [libSQL batch execution](./adapters.md#libsql-batch-execution)
60
+ for its supported conditions and concurrency guards.
61
+
56
62
  A second runner cannot rely on the lease alone. Atomic applied-record/head
57
63
  advancement uses the expected parent as a compare-and-swap guard. A runner that
58
64
  observes the already-matching head exits idempotently; a conflicting head is a
@@ -51,7 +51,8 @@ producer, consumer, and regression test all exist.
51
51
  ## Parameters are runtime data
52
52
 
53
53
  Parameter values are not fragment metadata. A renderer calls
54
- `context.parameter(value)`, and `render()` collects values in placeholder order:
54
+ `context.parameter(value)`, and `render()` collects values in placeholder order.
55
+ Pass a second argument when the adapter needs the runtime SQL domain too:
55
56
 
56
57
  ```ts
57
58
  import { and, eq, from, integer, like, render, select, table, text, where } from "qubu"
@@ -72,6 +73,25 @@ render(query)
72
73
  // parameters: [7, '%Ada%']
73
74
  ```
74
75
 
76
+ The optional domain metadata stays in a sidecar aligned with `parameters`:
77
+
78
+ ```ts
79
+ import { typedValue } from "qubu/core"
80
+ import type { SqlUuid } from "qubu"
81
+
82
+ const id = typedValue<SqlUuid, string>("108cb836-20d2-41b2-8c23-f0c94700aa7e", "uuid")
83
+ render(id)
84
+ // parameterSqlTypes: ["uuid"]
85
+ ```
86
+
87
+ The domain is a binding hint, not an instruction to convert the returned
88
+ JavaScript value. Result decoding comes from a field's `type` or an explicit
89
+ decoder.
90
+
91
+ Plain JavaScript values remain untyped at runtime. Use an explicit domain when
92
+ `Date` could mean either `DATE` or `TIMESTAMP`, or when a string is a UUID
93
+ rather than text.
94
+
75
95
  The parameter array follows the placeholders in the rendered text. `select()`
76
96
  normalizes independent clause values, but keep the final call in SQL order in
77
97
  new code so source scope and repair hints are visible at a glance.
@@ -4,7 +4,7 @@
4
4
 
5
5
  The optional `qubu/introspection` entrypoint reads one selected database
6
6
  namespace through a user-owned `CatalogConnection`. It returns normalized
7
- catalog data and can map that data to canonical Snapshot v1 or v2. The
7
+ catalog data and can map that data to canonical Snapshot v1. The
8
8
  application owns the driver and connection lifecycle. Snapshot diffing,
9
9
  migration planning, and DDL emission are separate Qubu capabilities; see the
10
10
  [ownership map](supported-surface.md#ownership-boundary).
@@ -46,7 +46,7 @@ SQL.
46
46
  ## PostgreSQL complete catalog surface
47
47
 
48
48
  The PostgreSQL reader also fills the complete normalized catalog used by
49
- Snapshot v2. It keeps PostgreSQL OIDs in current-run physical references and
49
+ Snapshot v1. It keeps PostgreSQL OIDs in current-run physical references and
50
50
  keeps decompiler output such as `pg_get_viewdef`, `pg_get_triggerdef`, and
51
51
  `pg_get_functiondef` as tagged SQL data. It does not evaluate that text.
52
52
 
@@ -55,9 +55,9 @@ The query and normalization layout follows the catalog-oriented parts of the
55
55
  while Qubu keeps the result as typed data instead of generating TypeScript
56
56
  declarations.
57
57
 
58
- Use `mapCatalogToCompleteSnapshot()` for this object set. Use
59
- `mapCatalogToSnapshot()` when a caller explicitly needs the existing table-only
60
- Snapshot v1.
58
+ Use `mapCatalogToSnapshot()` or its explicit
59
+ `mapCatalogToCompleteSnapshot()` alias for this object set. Both produce the
60
+ canonical Snapshot v1 shape.
61
61
 
62
62
  ## SQLite complete catalog surface
63
63
 
@@ -86,10 +86,9 @@ the selected namespace. SQLite does not provide the PostgreSQL object families
86
86
  such as routines, materialized views, policies, or ownership, so the reader
87
87
  does not fabricate them.
88
88
 
89
- `mapCatalogToCompleteSnapshot()` retains the typed views, triggers, deferred
90
- objects, opaque boundaries, and dialect extensions in Snapshot v2. The existing
91
- `mapCatalogToSnapshot()` still maps only tables and preserves Snapshot v1
92
- behavior.
89
+ `mapCatalogToSnapshot()` delegates to `mapCatalogToCompleteSnapshot()` and
90
+ retains typed views, triggers, deferred objects, opaque boundaries, and dialect
91
+ extensions in Snapshot v1.
93
92
 
94
93
  The query and normalization seams follow the catalog-reading portions of the
95
94
  [Drizzle SQLite introspector](https://github.com/drizzle-team/drizzle-orm/blob/main/drizzle-kit/src/introspect-sqlite.ts).
@@ -110,13 +109,13 @@ MySQL has typed complete records for views, routines and their parameters,
110
109
  triggers, partitions, collations used by selected tables or columns, and
111
110
  comments. View definitions come from `INFORMATION_SCHEMA.VIEWS`; each view's
112
111
  columns are joined back to the matching `COLUMNS` rows by physical table name,
113
- so the complete Snapshot v2 cross-reference points at the view's own column
112
+ so the complete Snapshot v1 cross-reference points at the view's own column
114
113
  IDs. Missing view definitions or unresolved trigger, partition, or other
115
114
  object references become deferred records with diagnostics.
116
115
 
117
116
  Scheduled events are retained as `CatalogOpaqueObject` records. Their event
118
117
  metadata and definition remain opaque, and the reader emits an
119
- `unmodeled-object` warning. Snapshot v2 keeps these records in
118
+ `unmodeled-object` warning. Snapshot v1 keeps these records in
120
119
  `opaqueObjects`; they are not treated as typed routines, triggers, or
121
120
  migration operations.
122
121
 
@@ -132,13 +131,12 @@ The query and normalization layout follows the catalog-reading portions of the
132
131
  while Qubu keeps the result as typed data instead of generating TypeScript
133
132
  declarations.
134
133
 
135
- Use `mapCatalogToCompleteSnapshot()` to retain these typed MySQL families and
136
- the opaque or deferred boundaries in Snapshot v2. Use `mapCatalogToSnapshot()`
137
- when a caller explicitly needs the existing table-only Snapshot v1.
134
+ Use `mapCatalogToSnapshot()` or `mapCatalogToCompleteSnapshot()` to retain these
135
+ typed MySQL families and the opaque or deferred boundaries in Snapshot v1.
138
136
 
139
137
  ## Snapshot v1 surface
140
138
 
141
- The mapper can emit these facts in canonical Snapshot v1:
139
+ The mapper emits these facts in canonical Snapshot v1:
142
140
 
143
141
  - one namespace and ordinary tables;
144
142
  - exact dialect-native column storage;
@@ -162,14 +160,14 @@ Snapshot v1 objects:
162
160
  - views and materialized views;
163
161
  - sequences, enums, domains, routines, triggers, policies, extensions,
164
162
  collations, comments, and partition metadata;
165
- - PostgreSQL identity sequence options that have no typed Snapshot v1 field;
163
+ - PostgreSQL identity sequence options that have no typed field;
166
164
  - SQLite virtual/shadow tables, attached namespaces, and unrecoverable
167
165
  generated or expression definitions;
168
166
  - MySQL/MariaDB differences, prefix indexes, invisible indexes, and advanced
169
167
  functional, full-text, or spatial index semantics.
170
168
 
171
- Use the complete catalog and Snapshot v2 mapper to retain supported PostgreSQL
172
- and MySQL families. MySQL scheduled events stay opaque, and MySQL sequences,
169
+ Use the Snapshot v1 mapper to retain supported PostgreSQL and MySQL families.
170
+ MySQL scheduled events stay opaque, and MySQL sequences,
173
171
  materialized views, row-level security (RLS) policies, extension objects, and
174
172
  ownership stay unsupported or deferred. When a row cannot be normalized safely, the reader
175
173
  keeps a typed deferred or opaque record and emits a diagnostic instead of
@@ -9,12 +9,15 @@
9
9
  | `qubu` | Runtime | Ordinary query and schema definitions, reads, writes, SQL templates, rendering, EXPLAIN, and execution contracts |
10
10
  | `qubu/core` | Runtime | Fragment and rendering primitives, dialect construction, SQL types, and extension constructors |
11
11
  | `qubu/codegen` | Runtime | Deterministic machine-owned TypeScript schemas from complete, non-lossy introspection |
12
- | `qubu/diff` | Runtime | Canonical Snapshot v1 or v2 comparison, rename hints, suggestions, and safety diagnostics |
13
- | `qubu/introspection` | Runtime | Catalog readers, normalized catalogs, and mapping to Snapshot v1 or v2 |
12
+ | `qubu/diff` | Runtime | Canonical Snapshot v1 comparison, rename hints, suggestions, and safety diagnostics |
13
+ | `qubu/introspection` | Runtime | Shared catalog contracts, normalized catalog models, diagnostics, and mapping to Snapshot v1 |
14
+ | `qubu/introspection/postgres` | Runtime | PostgreSQL catalog reader and catalog queries for one selected namespace |
15
+ | `qubu/introspection/sqlite` | Runtime | SQLite catalog reader and catalog queries for one selected namespace |
16
+ | `qubu/introspection/mysql` | Runtime | MySQL catalog reader and catalog queries for one selected namespace |
14
17
  | `qubu/mysql` | Runtime | The MySQL query dialect policy |
15
18
  | `qubu/postgres` | Runtime | PostgreSQL query dialect helpers such as `postgresDialect()` and `ilike()` |
16
19
  | `qubu/schema` | Runtime | Advanced schema metadata, storage and constraint models, source models, and schema-expression extensions |
17
- | `qubu/snapshot` | Runtime | Canonical Snapshot v1 and v2 traversal, encoding, decoding, diagnostics, and fingerprints |
20
+ | `qubu/snapshot` | Runtime | Canonical Snapshot v1 traversal, encoding, decoding, diagnostics, and fingerprints |
18
21
  | `qubu/snapshot/mysql` | Runtime | MySQL snapshot adapter, schema dialect, and convenience creators |
19
22
  | `qubu/snapshot/postgres` | Runtime | PostgreSQL snapshot adapter, schema dialect, and convenience creators |
20
23
  | `qubu/snapshot/sqlite` | Runtime | SQLite snapshot adapter, schema dialect, affinity helper, and convenience creators |
@@ -22,15 +25,24 @@
22
25
  | `qubu/vite` | Runtime | The optional `qubu()` Vite compiler hint |
23
26
  | `qubu/package.json` | JSON | The published package manifest |
24
27
  | `@qubu/migrate` | Runtime | Migration compiler format identity and shared plan types |
28
+ | `@qubu/pgvector` | Runtime | PostgreSQL pgvector columns, dense-vector codecs, distance expressions, and HNSW/IVFFlat index metadata |
25
29
  | `@qubu/migrate/plan` | Runtime | Pure migration planning with dependencies, decisions, preconditions, and explicit custom SQL |
26
- | `@qubu/migrate/ddl` | Runtime | DDL preflight and deterministic PostgreSQL, SQLite, or MySQL emission from a migration plan |
27
- | `@qubu/migrate/artifact` | Runtime | Versioned programs, strict artifacts and baselines, canonical encoding, and SHA-256 integrity |
30
+ | `@qubu/migrate/ddl` | Runtime | DDL preflight and generic emission from a migration plan and supplied schema dialect |
31
+ | `@qubu/migrate/ddl/postgres` | Runtime | PostgreSQL DDL emission from an approved migration plan |
32
+ | `@qubu/migrate/ddl/sqlite` | Runtime | SQLite DDL emission from an approved migration plan |
33
+ | `@qubu/migrate/ddl/mysql` | Runtime | MySQL DDL emission from an approved migration plan |
34
+ | `@qubu/migrate/artifact` | Runtime | Generic versioned program compilation with a caller-supplied schema dialect, plus strict artifacts and baselines |
35
+ | `@qubu/migrate/artifact/postgres` | Runtime | PostgreSQL versioned program compilation |
36
+ | `@qubu/migrate/artifact/sqlite` | Runtime | SQLite versioned program compilation, including table rebuilds |
37
+ | `@qubu/migrate/artifact/mysql` | Runtime | MySQL versioned program compilation |
28
38
  | `@qubu/migrate/repository` | Runtime | Strict full-chain and journal-prefix verification |
29
39
  | `@qubu/migrate/journal` | Runtime | Storage-neutral journal records, transitions, validation, and reference storage |
30
40
  | `@qubu/migrate/executor` | Runtime | Portable execution, structured errors, checkpointing, and explicit reconciliation |
31
41
  | `@qubu/migrate/baseline` | Runtime | Strict live baseline verification and physical managed-schema comparison |
32
42
  | `@qubu/migrate/status` | Runtime | Pending chain, managed drift, unmanaged objects, interrupted attempts, and incompatible requirements |
33
- | `@qubu/migrate/bootstrap` | Runtime | Fresh SQLite schema planning through the normal diff, plan, and program compiler |
43
+ | `@qubu/migrate/bootstrap` | Runtime | Shared bootstrap preparation, result types, and generic planning with a caller-supplied schema dialect |
44
+ | `@qubu/migrate/bootstrap/postgres` | Runtime | Fresh PostgreSQL schema planning through the normal diff, plan, and program compiler |
45
+ | `@qubu/migrate/bootstrap/sqlite` | Runtime | Fresh SQLite schema planning through the normal diff, plan, and program compiler |
34
46
  | `@qubu/migrate/testing` | Runtime | Deterministic fake adapters, fault boundaries, and adapter conformance checks |
35
47
  | `@qubu/cli` | Runtime and CLI | `@alloc/cmd-ts` commands, typed config, filesystem repositories, stable output, and exit codes |
36
48
  | `@qubu/drizzle` | Runtime | Shared Drizzle conversion errors and dialect types |
@@ -67,17 +79,17 @@ entrypoint table.
67
79
  | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
68
80
  | Schema values | `table`, immutable `schema` registries with namespaces, portable and dialect-native column storage descriptors, canonical default and generated-column metadata, identity descriptors, named primary, candidate-key, nullable unique, foreign-key, and check constraints, physical object names, included-column indexes, typed dialect extensions, and typed column helpers |
69
81
  | Read queries | Named projections, spreadable source columns, aliases, joins, typed custom and LATERAL `FROM` sources, correlated subqueries, `WHERE`, grouping with declared-key proofs, `HAVING`, ordering, window expressions, distinctness, pagination, row locking, ordinary and recursive CTEs, subqueries, and set operations |
70
- | Expressions | Comparison, boolean, arithmetic, null, range, membership, aggregate, window, string, JSON scalar reads, definition-backed and raw casts, cases, parameterized SQL templates, custom expressions, and branded deterministic schema expressions |
82
+ | Expressions | Comparison, boolean, arithmetic, null, range, membership, aggregate, window, string, JSON scalar reads and typed nested JSON query results, definition-backed and raw casts, cases, parameterized SQL templates, custom expressions, and branded deterministic schema expressions |
71
83
  | SQL type metadata | Portable domains and capabilities, physical column storage descriptors, `SqlTypeOf`, projected SQL type maps, `SourceLike` and `TableLike` field constraints, contextual literals, typed extension values, calls, and casts, plus a permissive `SqlUnknown` fallback |
72
- | Write queries | `INSERT` values, defaults, and selects; `UPDATE`; `DELETE`; typed assignments; `RETURNING`; and explicit unrestricted-write opt-in |
84
+ | Write queries | `INSERT` values, defaults, and selects; typed `UPDATE`, PostgreSQL `UPDATE ... FROM`, and `DELETE`; typed assignments; PostgreSQL/SQLite conflict clauses; MySQL duplicate-key updates and incoming rows; `RETURNING` on supporting dialects; and explicit unrestricted-write opt-in |
73
85
  | Rendering | Standard, PostgreSQL, SQLite, MySQL, and user-created policies for identifiers, placeholders, pagination, row locking, JSON, logical cast targets, schema literals, and EXPLAIN options |
74
86
  | Execution boundary | `QueryAdapter`, opt-in `ExplainableQueryAdapter`, `StreamingQueryAdapter`, and `TransactionalQueryAdapter` capabilities, bound clients from `qubu()`, structured results from `execute()` or `db.execute()`, row-only results from `executeRows()` or `db.rows()`, typed read streams from `stream()` or `db.stream()`, and adapter-decoded plan rows from `explain()` or `db.explain()` |
75
- | Snapshots | Pure Snapshot v1 and v2 creation, canonical encoding and strict decoding, immutable data, diagnostics, and FNV change-detection fingerprints |
87
+ | Snapshots | Pure Snapshot v1 creation, canonical encoding and strict decoding, immutable data, diagnostics, and FNV change-detection fingerprints |
76
88
  | Introspection | PostgreSQL, SQLite, and MySQL catalog readers for one selected namespace, normalized catalog data, structured diagnostics, and strict or explicit lossy snapshot mapping |
77
- | Snapshot diffing | Pure Snapshot v1 and v2 comparison, explicit rename evidence, non-authoritative suggestions, and safety diagnostics |
89
+ | Snapshot diffing | Pure Snapshot v1 comparison, explicit rename evidence, non-authoritative suggestions, and safety diagnostics |
78
90
  | Migration planning | Pure, dialect-neutral plans with stable ordering, dependency edges, preconditions, explicit review decisions, and tagged custom SQL |
79
91
  | DDL emission | Preflight plus deterministic PostgreSQL, SQLite, and MySQL statements from an approved `MigrationPlan` and matching `SchemaDialect` |
80
- | Migration operations | Strict artifacts and baselines, authoritative programs, repository and journal validation, adapter capability preflight, execution, status/drift, reconciliation, and SQLite bootstrap |
92
+ | Migration operations | Strict artifacts and baselines, authoritative programs, repository and journal validation, adapter capability preflight, execution, status/drift, reconciliation, SQLite bootstrap, and complete PostgreSQL bootstrap with standalone enum ordering |
81
93
  | Build tooling | The optional Vite directive transform and its matching TypeScript ambient declarations |
82
94
  | Drizzle conversion | Optional, dialect-specific runtime conversion from Qubu schema registries to Drizzle tables |
83
95
  | Source generation | Pure Snapshot v1 table source printing, deterministic camelCase IDs, exact physical metadata, controlled type mappings, and structured failure diagnostics |
@@ -31,25 +31,38 @@ IDs are evidence selected by the adapter's identity policy. PostgreSQL OIDs,
31
31
  SQLite implementation names, and similar catalog keys stay in current-run
32
32
  references and are not used as logical IDs.
33
33
 
34
- ## Snapshot v2
34
+ ## Snapshot v1
35
35
 
36
36
  `qubu/snapshot` provides the strict complete format as a separate API:
37
37
 
38
38
  ```ts
39
39
  import { decodeCompleteSchemaSnapshot, encodeCompleteSchemaSnapshot } from "qubu/snapshot"
40
40
 
41
- const encoded = encodeCompleteSchemaSnapshot(snapshotV2)
41
+ const encoded = encodeCompleteSchemaSnapshot(snapshotV1)
42
42
  const decoded = decodeCompleteSchemaSnapshot(encoded)
43
43
  ```
44
44
 
45
- Snapshot v2 uses the same `qubu-schema` envelope with `version: 2`. Its
45
+ Snapshot v1 uses the same `qubu-schema` envelope with `version: 1`. Its
46
46
  namespace, capability facts, object-family arrays, cross-object references,
47
47
  provenance, typed dialect extensions, and deferred/opaque boundaries are
48
48
  strictly validated. Arrays are ordered by logical ID (with ordinal sequences
49
49
  and index terms ordered by their semantic position), and the fingerprint is computed
50
50
  from the deterministic encoding.
51
51
 
52
- Snapshot v1 remains a separate strict format. `decodeSchemaSnapshot` still
53
- accepts only v1 and continues to reject unknown fields and future versions;
54
- v2 callers must select `decodeCompleteSchemaSnapshot` explicitly. Neither
55
- snapshot format evaluates database-provided SQL.
52
+ Normalized references to nested catalog objects retain their owner scope. A
53
+ table-local index or constraint reference is mapped with
54
+ `owner: { kind: "table", id }`; view columns use the view kind and ID; domain
55
+ constraints use the domain kind and ID. The legacy `tableId` shorthand on
56
+ catalog entity references is converted to that owner form at the Snapshot v1
57
+ boundary. Top-level references have no owner. This scope prevents equal child
58
+ IDs from different tables or object families from overwriting one another.
59
+
60
+ Catalog extension payloads and configuration records are opaque JSON. Their
61
+ keys and values are preserved through normalization and canonical encoding;
62
+ objects inside those payloads are not treated as Snapshot expressions or
63
+ native storage declarations.
64
+
65
+ Snapshot v1 is the only strict schema snapshot format. `decodeSchemaSnapshot`
66
+ and `decodeCompleteSchemaSnapshot` both validate the same version-1 envelope,
67
+ reject unknown fields and future versions, and never evaluate database-provided
68
+ SQL.
@@ -14,9 +14,10 @@ generator:
14
14
  ```ts
15
15
  import { writeFile } from "node:fs/promises"
16
16
  import { generateSchemaSource } from "qubu/codegen"
17
- import { mapCatalogToSnapshot, readSqliteCatalog } from "qubu/introspection"
17
+ import { mapCatalogToSnapshot } from "qubu/introspection"
18
+ import { readCatalog } from "qubu/introspection/sqlite"
18
19
 
19
- const catalog = await readSqliteCatalog(connection, { namespace: "main" })
20
+ const catalog = await readCatalog(connection, { namespace: "main" })
20
21
  const introspection = mapCatalogToSnapshot(catalog, { namespace: "main" })
21
22
  const generated = generateSchemaSource(introspection)
22
23
 
@@ -134,6 +135,6 @@ module does not look complete by omission.
134
135
 
135
136
  The entrypoint does not provide a CLI, filesystem ownership, live driver
136
137
  integration, multiple namespaces, runtime schema materialization, migrations,
137
- DDL, Snapshot v2 object generation, or hand-edit merging. Use
138
+ DDL, non-table object generation, or hand-edit merging. Use
138
139
  [Database introspection](introspection.md) for the catalog boundary and
139
140
  [Canonical schema snapshots](snapshots.md) for the identity artifact.
@@ -1,6 +1,6 @@
1
1
  # Snapshot diffing
2
2
 
3
- > Compare canonical Snapshot v1 or v2 values and review identity changes before a later planning step.
3
+ > Compare canonical Snapshot v1 values and review identity changes before a later planning step.
4
4
 
5
5
  The optional `qubu/diff` entrypoint compares immutable snapshot data. It does
6
6
  not open a connection, render SQL, execute a change, or infer migration history.
@@ -57,7 +57,7 @@ an `ambiguous` diagnostic and leaves both operations visible for review.
57
57
 
58
58
  Removing an object is marked `destructive`. Narrowing nullability, changing
59
59
  storage, removing a value, or changing a constraint can also receive that
60
- classification. Opaque and deferred Snapshot v2 records remain visible as
60
+ classification. Opaque and deferred Snapshot v1 records remain visible as
61
61
  `add` or `remove` data and produce `lossy` or `unsupported` diagnostics. They
62
62
  cannot be silently promoted to a rename.
63
63