@jarenjs/db 0.84.3 → 0.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ARCHITECTURE.md CHANGED
@@ -1167,8 +1167,10 @@ calls with different bound values.
1167
1167
  `physical.js` compiles column codecs and verifies declarations against that
1168
1168
  inventory. The existing entity core, tracker and graph row merger execute both
1169
1169
  hybrid and column layouts; there is no separate relational store. The query
1170
- planner reports decoded evaluation for physical codecs, and refuses physical
1171
- keyset continuation until its identity semantics are qualified.
1170
+ planner preserves codec semantics through qualified native plans and explicit
1171
+ residuals, and refuses physical keyset continuation until its identity semantics
1172
+ are qualified. Present-null scalar predicates and safe fluent projection
1173
+ flattening join this native subset; strict binding failures stop before a scan.
1172
1174
 
1173
1175
  `sql.js` binds trusted statements to `store.js` transaction views. It reuses the
1174
1176
  read classifier's tokenizer and the driver's scope owner. Writes invalidate all
@@ -1176,6 +1178,21 @@ clean tracked entities; pending edits and incomplete capture populations refuse.
1176
1178
  `invariants.js` uses the shared Query compiler for store rules; the dialect lowers
1177
1179
  a bounded database subset into ordered trigger bodies. `migrate.js` reuses its
1178
1180
  existing rebuild/receipt transaction and verifies preservation before publication.
1179
- The backup publisher remains shared by Node online and Bun serialized snapshots.
1181
+ The backup publisher uses Node online backup and Bun disk-backed VACUUM INTO.
1182
+ The standalone snapshot helper shares destination reservation and cleanup across
1183
+ both hosts, including transaction failures.
1180
1184
 
1181
1185
  `src/search.js` composes core lexical mechanics and the JSON predicate compiler over complete bounded entity snapshots. Committed capture and data-version checks invalidate derived state; SHA-256 source content validates persisted caches across reopen. Snapshot storage uses existing collection transactions. See [search execution](docs/SEARCH.md); native full-text dialects remain unqualified.
1186
+
1187
+ `dialects/sqlite-relational.js` owns the explicit SQLite expression and statement
1188
+ compiler; `dialects/sqlite-schema.js` reuses it for ordered tables, indexes and
1189
+ triggers. `table-migration.js` owns reviewed source/target guards, native copying
1190
+ and preservation checks, with catalog/pragma spellings in the SQLite dialect.
1191
+ The supplied driver owns transactions and cursors. These programs are explicitly
1192
+ SQLite-semantic and never enter the JSON residual evaluator. See
1193
+ [the native SQLite contract](docs/SQLITE-RELATIONAL.md).
1194
+
1195
+ `engine-metadata.js` holds inert version/table constants so schema inspection
1196
+ does not import runtime owners. `/query`, `/model` and `/entity` expose those
1197
+ mechanisms without the root store import. `compileEntityModel` performs one model
1198
+ normalization for both entities and mapping; openStore reuses that result.
package/README.md CHANGED
@@ -1379,6 +1379,10 @@ Every subpath a consumer can import, derived from the manifest by
1379
1379
  | `@jarenjs/db/package.json` | metadata | — |
1380
1380
  | `@jarenjs/db/node-worker` | JavaScript | declared |
1381
1381
  | `@jarenjs/db/node-pool` | JavaScript | declared |
1382
+ | `@jarenjs/db/relational` | JavaScript | declared |
1383
+ | `@jarenjs/db/query` | JavaScript | declared |
1384
+ | `@jarenjs/db/model` | JavaScript | declared |
1385
+ | `@jarenjs/db/entity` | JavaScript | declared |
1382
1386
  <!--/fact-->
1383
1387
 
1384
1388
 
@@ -1431,3 +1435,10 @@ SQLite constraint/audit triggers for installation through that migration boundar
1431
1435
  Native column reads and bounded mutation documents are specified in [NATIVE-PLANS](docs/NATIVE-PLANS.md), including SQL census coverage, resource accounting and refusals.
1432
1436
 
1433
1437
  `@jarenjs/db/search` composes the resident ranker with bounded authoritative entity reads and optional atomic snapshot storage. See [persisted search](docs/SEARCH.md).
1438
+
1439
+ Column-first table definitions, guarded same-connection rebuilds, exact matched writes,
1440
+ partial conflicts, raw-text JSON queries and byte-valued operations use
1441
+ [`@jarenjs/db/relational`](docs/SQLITE-RELATIONAL.md). Both host entries export
1442
+ `snapshotDatabase(connection, newPath)` for a disk-backed committed-WAL copy.
1443
+ Existing-connection consumers can import `/query`, `/model` and `/entity`;
1444
+ `compileEntityModel` shares one normalization between queries and mapping.
@@ -2352,7 +2352,9 @@ relation navigation across physical layouts is not qualified.
2352
2352
  | `decimal` | exact decimal string, including trailing zeros | TEXT |
2353
2353
  | `blob-hex` | lowercase hexadecimal string | BLOB |
2354
2354
 
2355
- Unsafe narrowing refuses `JD2003`. A byte handle never enters the public entity.
2355
+ Unsafe narrowing refuses `JD2003`. A byte handle never enters the JSON-facing entity;
2356
+ [the native SQLite channel](SQLITE-RELATIONAL.md#exact-writes-and-bytes) preserves
2357
+ Uint8Array/Buffer values on the same synchronous connection.
2356
2358
  `null: "null"` maps SQL NULL to present JSON null; `"absent"` omits the property;
2357
2359
  `"reject"` refuses it. With the JSON codec, JSON null is stored as the text `null`,
2358
2360
  so SQL NULL can independently mean absence. `default: "database"` omits an absent
@@ -2361,9 +2363,10 @@ writes to the database. A generated integer identity uses the existing
2361
2363
  `x-entity.default: "auto"` declaration. Direct updates with identical values and
2362
2364
  identical tracked saves produce no effective writes.
2363
2365
 
2364
- Mapped query documents execute through the existing decoded-row evaluator;
2365
- explanations report this residual and strict pushdown refuses it. Scalar graph
2366
- loads use mapped names; complex codec predicates require query documents.
2366
+ Mapped query documents use the qualified native subset in [NATIVE-PLANS](NATIVE-PLANS.md).
2367
+ Present-null scalar equality/ranges preserve Jaren semantics. Unsupported codecs
2368
+ and shapes retain explicit residuals; strict mode also rejects unsupported bound
2369
+ externals before fetching rows. Scalar graph loads use mapped names.
2367
2370
  Physical `page` and `after` continuation refuse until codec-aware keysets are
2368
2371
  qualified; an explicit `take`/`skip` load remains available.
2369
2372
  Capture/live/replication for adopted application triggers is not qualified and
@@ -2414,3 +2417,10 @@ must stay in the safe-number range.
2414
2417
  ## Native column mutation documents
2415
2418
 
2416
2419
  Asynchronous entity sets expose `mutate(document)` for conditional updates, conflict-aware upserts and bounded same-entity insert-select. The closed grammar, no-op/revision behavior, output bounds and transactional qualifications are specified in [NATIVE-PLANS](NATIVE-PLANS.md).
2420
+
2421
+ Explicit physical DDL metadata and live-schema migration planning are specified
2422
+ in [SQLITE-RELATIONAL](SQLITE-RELATIONAL.md#physical-schema-ownership). Opening a
2423
+ physical entity retains adoption-only behavior. Public plans create complete
2424
+ ordered declarations; an incomplete generated/default definition or view remains
2425
+ adoption metadata. SQLite expressions preserve a separate, explicit semantic
2426
+ contract for raw text, bytes, nulls, collations and floating totals.
@@ -49,6 +49,13 @@ Floating sums/averages and date/datetime grouping remain residual. Physical text
49
49
  comparisons explicitly use codepoint collation, independent of a column's declared
50
50
  collation; an incompatible index may therefore stop helping that query.
51
51
 
52
+ Safe identity/object projection chains, including a projected join followed by
53
+ filtering and ordering, flatten without crossing windows, grouping or inner
54
+ ordering. Standalone min/max over supported scalar columns and sum/avg over safe
55
+ integer columns now lower natively, preserving empty-sequence and present-null
56
+ errors. Missing or unbindable external values refuse strict execution and both
57
+ cursor APIs before any decoded fetch; a nullable slot accepts explicit null.
58
+
52
59
  `explain` reports the emitted SQL, scan narrative, profile bounds and last
53
60
  execution's admitted statement/returned-row/serialized-wire-byte counts. These
54
61
  are application admission costs. SQLite does not expose visited-row counts or
@@ -73,12 +80,13 @@ const result = await store.entity('Inventory').mutate({
73
80
  });
74
81
  ```
75
82
 
76
- The three operations are:
83
+ The operations are:
77
84
 
78
85
  | Operation | Required document members | Meaning |
79
86
  |---|---|---|
80
- | `update` | `key`, `set`; `expectedRevision` for a versioned entity | Complete primary key and revision predicate; writes only changed columns and increments the revision once. Missing/stale/identical rows yield zero affected rows. |
81
- | `upsert` | `values`, `conflict`, `update` | Insert or update the named supplied members only if their stored values differ. `conflict` is the complete ordered primary key. |
87
+ | `update` | `key` and/or `where`, `set` and/or `expressions`; `expectedRevision` for a versioned entity | Exact assignments with an atomic predicate. Default changed reporting suppresses identical writes; `reporting: 'matched'` executes them. A declared version increments once on a write. |
88
+ | `upsert` | `values`, `conflict`; `update` or `onConflict: 'nothing'` | Ordered logical conflict columns may name a non-primary UNIQUE identity; `conflictWhere` matches a partial index. Default changed reporting suppresses identical updates. |
89
+ | `delete` | `key` and/or `where`; `expectedRevision` for a versioned entity | One conditional or bulk delete, with the same transactional output bounds. |
82
90
  | `insert-select` | `source`, `where`, `select`, `conflict`, `onConflict: 'nothing'` | Same-entity scalar/literal projection, bounded source rows, conflict-ignore insertion. Source and target path codecs and NULL policies must match. |
83
91
 
84
92
  `returning` is a nonempty list of logical stored members (default: all). `maxRows`
@@ -92,14 +100,23 @@ before insertion, even if all rows would conflict. Output bounds and codec/schem
92
100
  validation run inside the transaction; failure rolls back rows and trigger effects.
93
101
  The byte bound checks decoded output, not a database allocation interrupt.
94
102
  The statement's `RETURNING` view follows SQLite timing; later AFTER-trigger
95
- modifications are not an extra readback. Same-input replay yields no effective
96
- write, no revision increment and no additional trigger effects.
103
+ modifications are not an extra readback. Changed-reporting same-input literal replay yields no effective write, revision
104
+ increment or additional trigger effects. Matched reporting and arithmetic
105
+ expressions intentionally may write on repeat.
97
106
 
98
107
  Mutations are untracked. Re-read affected rows before subsequent tracked editing;
99
108
  a previously tracked revision remains stale and retains normal conflict checks.
100
109
  Use `tx.entity(name).mutate(document)` to compose writes, receipts and jobs in one
101
- transaction. An outer failure rolls everything back. No synchronous `mutate`
102
- facade or generic bulk mutation expression language is declared.
110
+ transaction. An outer failure rolls everything back. `entityCore` on a synchronous
111
+ connection also settles these mutations synchronously. `where` accepts a native
112
+ Jaren predicate or structural `sql` expression; `expressions` maps exact logical
113
+ assignment names to `sql` expressions, with logical columns resolved to physical
114
+ names. A member cannot appear in both `set` and `expressions`.
115
+
116
+ For cross-table insert-select, expression conflict updates, raw JSON text, bytes
117
+ and complete SQLite null/collation semantics use the explicit
118
+ [native SQLite surface](SQLITE-RELATIONAL.md). It shares expression emission with
119
+ entity mutations while retaining its own native SQL result contract.
103
120
 
104
121
  ## Bounded ranges and live qualification
105
122
 
@@ -0,0 +1,190 @@
1
+ # Native SQLite programs on an existing connection
2
+
3
+ `@jarenjs/db/relational` provides structural SQL authoring, physical table DDL,
4
+ and guarded migrations. `relational(connection)` requires an available
5
+ synchronous SQLite connection from `@jarenjs/db/node` or `@jarenjs/db/bun`.
6
+ It opens no store and uses the supplied connection and transaction. Expressions
7
+ are closed `$sql` nodes built by `sql`; strings are bound values, never SQL
8
+ fragments. Identifiers are quoted as single names. `planRelational` returns
9
+ `{ sql, params, access }` for review without reading the database.
10
+
11
+ ## Choose the expression semantics
12
+
13
+ | Surface | Null, text and numeric semantics | Execution |
14
+ |---|---|---|
15
+ | LINQ / JSON query over mapped entities | Jaren equality, codepoint text comparison, declared codecs; present null remains null | Qualified native plan; `strict: true` refuses any required residual, including unsupported external bindings |
16
+ | `sql` expressions and `relational` | SQLite three-valued logic, native affinities, explicit BINARY/NOCASE/RTRIM, native aggregates | One native statement; no decoded-row fallback |
17
+
18
+ For example, Jaren equality regards two present nulls as equal, while SQLite
19
+ `=` yields SQL NULL and `IS` supplies a null-safe comparison. Jaren sum over an
20
+ empty sequence is zero and a present null is a type error. SQLite `sum` skips
21
+ null and returns null without inputs; `total` returns floating zero. SQLite
22
+ floating accumulation and ASCII NOCASE are deliberate choices on this surface.
23
+ No mapping must omit a null member to use native SQL.
24
+
25
+ ```js
26
+ import { relational, sql } from '@jarenjs/db/relational';
27
+ const r = relational(connection);
28
+ const c = sql.column;
29
+ const query = {
30
+ from: { table: 'staging', as: 's' },
31
+ columns: {
32
+ id: c('id', 's'), raw: c('body', 's'),
33
+ price: sql.cast(sql.call('json_extract', [c('body', 's'), '$.price']), 'REAL'),
34
+ },
35
+ where: sql.binary('IS', c('supplier', 's'), sql.param('supplier')),
36
+ orderBy: [{ by: sql.collate(c('sku', 's'), 'NOCASE'), nulls: 'first' }],
37
+ };
38
+ for (const row of r.iterate(query, { externals: { supplier: null } })) {
39
+ consume(row); // original raw text and native byte values are preserved
40
+ }
41
+ ```
42
+
43
+ `all`, `get`, `iterate` and `execute` settle synchronously. `iterate` uses the
44
+ shared cursor lifecycle, releases its statement on early return or failure,
45
+ and reports `streaming`/`barrier` from the driver. `all` intentionally collects
46
+ the result. SQLite may itself sort or build temporary query structures.
47
+
48
+ Selections support table and subquery sources, inner/left/cross joins, correlated
49
+ `sql.scalar`/`sql.exists`, CASE, IN/NOT IN, DISTINCT, grouped and distinct
50
+ aggregates, HAVING, UNION/UNION ALL and ordered windows. The declaration file
51
+ lists the closed operators and functions, including trim/coalesce, LIKE, JSON
52
+ extraction, casts and SQLite date functions. Neither arbitrary function names
53
+ nor a raw-expression escape hatch is accepted.
54
+
55
+ ## Exact writes and bytes
56
+
57
+ ```js
58
+ const result = r.execute({
59
+ op: 'update', table: 'claims',
60
+ set: { revision: sql.binary('+', c('revision'), 1), status: 'done' },
61
+ where: sql.binary('AND',
62
+ sql.binary('=', c('revision'), sql.param('expected')),
63
+ sql.binary('=', c('owner'), sql.param('owner'))),
64
+ }, { externals: { expected: 3, owner: 'worker-1' } });
65
+ // result.affected is SQLite's direct statement count, excluding trigger writes.
66
+ ```
67
+
68
+ UPDATE emits exactly the supplied assignments. `reporting: 'matched'` is the
69
+ native surface's default and executes identical assignments, so UPDATE OF and
70
+ immutability triggers run. `reporting: 'changed'` adds a BINARY, null-safe
71
+ comparison to suppress unchanged rows. UPDATE and DELETE require an explicit
72
+ `where`; literal `1` authorizes every row. Predicates and arithmetic belong to
73
+ one statement. The existing entity updater retains changed-row behavior;
74
+ `entity.mutate` adds explicit matched reporting and expression assignments.
75
+
76
+ INSERT accepts `values` or a `source` selection with ordered target `columns`.
77
+ A source may read another table or an intermediate legacy shape. `ignore: true`
78
+ uses INSERT OR IGNORE. `conflict` accepts ordered column/expression targets, an
79
+ optional partial-index `where`, and `action: 'nothing'` or `'update'` with an
80
+ exact `set` and optional `updateWhere`. Use `sql.column(name, 'excluded')` for
81
+ incoming values. Conflict-target expressions contain literal schema values so
82
+ SQLite can match its index. No read-then-write emulation occurs.
83
+
84
+ `Uint8Array` and Node `Buffer` values bind as bytes; returned binary values stay
85
+ bytes. Subarray offsets and zero bytes survive without hex strings or JSON
86
+ arrays. Combine metadata, image, conflict and history writes inside the existing
87
+ synchronous transaction; failure rolls back all of them. Optional `returning`
88
+ collects rows using SQLite RETURNING timing, before subsequent AFTER-trigger
89
+ changes. Unlike bounded entity mutation documents, this explicit native surface
90
+ has no automatic result row/byte limit; use a bounded selection or streaming read
91
+ when handling large results.
92
+
93
+ ## Physical schema ownership
94
+
95
+ ```js
96
+ import { defineTable, planTable, planTableMigration, applyTableMigration } from '@jarenjs/db/relational';
97
+ const history = defineTable({
98
+ name: 'history', primaryKey: ['id'],
99
+ columns: [
100
+ { name: 'id', type: 'INTEGER', identity: 'autoincrement', nullable: false },
101
+ { name: 'body', type: 'TEXT', nullable: false },
102
+ { name: 'revision', type: 'INTEGER', default: 1, nullable: false },
103
+ ],
104
+ indexes: [{ name: 'history_revision', terms: [{ by: c('revision'), direction: 'desc' }] }],
105
+ triggers: [{ name: 'history_immutable', timing: 'before', event: 'update',
106
+ steps: [{ raise: { action: 'abort', message: 'immutable history' } }] }],
107
+ });
108
+ const ddl = planTable(history).createSql;
109
+ const migration = planTableMigration(connection, history, { id: 'history-v2', allowRebuild: true });
110
+ // Inspect migration.statements and migration.finish before applying the plan.
111
+ applyTableMigration(connection, migration);
112
+ ```
113
+
114
+ Columns retain declaration order and exact INTEGER/REAL/TEXT/BLOB/NUMERIC/ANY
115
+ types. Definitions support ordered primary keys, rowid or AUTOINCREMENT identity,
116
+ nullability, database defaults, generated columns, STRICT/WITHOUT ROWID, named
117
+ UNIQUE/CHECK/foreign-key constraints and delete/update actions. Index terms
118
+ support expressions, direction and collation, with an optional partial predicate.
119
+ Triggers support BEFORE/AFTER, INSERT/UPDATE/DELETE, UPDATE OF, OLD/NEW conditions,
120
+ mutation steps and RAISE. Schema expressions use the same structural emitter,
121
+ with quoted inline literals because SQLite disallows schema parameters.
122
+
123
+ Entity `.physical(...)` metadata can also supply column `type`, `defaultValue`,
124
+ `collation`, `identity`, `check`, `generatedExpression` and `stored`, plus table
125
+ `constraints`, `indexes`, `triggers`, `strict` and `withoutRowid`.
126
+ `planEntity(...).createSql` now emits explicit table DDL for complete writable
127
+ declarations; views and incomplete generated/default definitions remain adoption
128
+ metadata. `openStore` still verifies physical tables without creating them.
129
+ Identical physical models produce an empty `planModelMigration`; changed
130
+ physical tables use the live-schema `planTableMigration` API.
131
+
132
+ ## Guarded upgrades
133
+
134
+ Planning inspects the existing schema without modifying it. A differing existing
135
+ table requires `allowRebuild: true`; additions currently use the same guarded
136
+ rebuild. Every removed column needs `dropColumns`; removing an existing explicit
137
+ index/trigger requires `dropObjects`. Unmentioned indexes and triggers survive.
138
+ An optional `copy` maps writable non-key target columns to structural expressions;
139
+ new columns otherwise use their defaults. The plan retains the source schema and
140
+ an exact canonical checksum. Applying an edited plan or a stale source refuses.
141
+ A target already matching the reviewed plan is a no-op on repeat.
142
+
143
+ Execution creates a replacement, copies natively, verifies row counts and
144
+ unchanged values/storage classes, drops/renames atomically, restores indexes and
145
+ triggers, and checks foreign keys and the target schema. Primary-key columns,
146
+ unshadowed hidden rowids, raw text, bytes and AUTOINCREMENT high-water marks are
147
+ preserved. A key change, rowid-ownership change or ambiguous rowid alias refuses.
148
+ No migration history table or model adoption is needed.
149
+
150
+ Rebuilds require SQLite's foreign-key transition outside a transaction. For a
151
+ nested upgrade use `withForeignKeysSuspended(connection, () => { ... })` as the
152
+ outer scope, then nested `connection.transaction`/migration calls share savepoints.
153
+ The helper owns an IMMEDIATE transaction, checks references, and restores
154
+ `foreign_keys` and `legacy_alter_table` after success or failure. Its callback must
155
+ settle synchronously. A rebuild inside an already open FK-enabled transaction
156
+ refuses before DDL. Node/Bun regressions cover populated history and references,
157
+ failed copies, repeat reopening, nested rollback, and process death after DROP
158
+ with WAL recovery. These tests do not establish power-loss durability.
159
+
160
+ ## Read-only inspection and disk snapshots
161
+
162
+ `readSchema` from `@jarenjs/db/model` inventories tables without adopting them,
163
+ but excludes engine bookkeeping. For a scanner that must include framework tables,
164
+ select table names directly from `sqlite_schema` with `relational`, or use the
165
+ public `connection.dialect.introspect.tables()` statement. A native selection can use `sql.call('typeof', [sql.column(name)])` and
166
+ `sql.column('rowid')` to inspect actual text storage in otherwise unknown shapes.
167
+ Declared affinity does not determine a value's storage class. WITHOUT ROWID tables
168
+ and shadowed rowid aliases require an explicit different identity selection.
169
+
170
+ Both host driver entries export `snapshotDatabase(connection, newPath)`. It
171
+ reserves a new destination, refuses any existing file (even empty), includes
172
+ committed WAL data through VACUUM INTO, syncs the output and cleans up a failed
173
+ copy. It allocates no database-sized JavaScript image. SQLite page caches and
174
+ its temporary storage govern native working memory. The copy runs synchronously
175
+ inside the asynchronous filesystem operation; it is not an incremental-progress
176
+ or interruption API. A snapshot inside an active transaction fails and cleans up.
177
+ Explicit keys, retained histories and bytes survive; [SQLite VACUUM](https://www.sqlite.org/lang_vacuum.html)
178
+ may renumber unaliased rowids, so this is not a page-identical archival copy. Bun store backups
179
+ use the same disk-backed path; Node store backup keeps its online-backup binding.
180
+
181
+ ## Lightweight engines
182
+
183
+ Use `@jarenjs/db/query`, `/model` and `/entity` for existing-connection consumers;
184
+ `/relational` needs neither entity normalization nor a query plan cache.
185
+ `compileEntityModel(model)` returns `{ entities, mapping }` from one normalization,
186
+ avoiding the duplicated work of separate `normalizeEntities` and `explainMapping`
187
+ calls. No global strong model cache is introduced. Keep connection/query caches
188
+ bounded and reuse compiled metadata. Smaller import graphs alone do not prove
189
+ the complete application meets its RSS budget; measure application memory with
190
+ representative workloads.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jarenjs/db",
3
3
  "private": false,
4
- "version": "0.84.3",
4
+ "version": "0.85.0",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
7
7
  "types": "./types/index.d.ts",
@@ -48,6 +48,22 @@
48
48
  "./node-pool": {
49
49
  "types": "./types/node-pool.d.ts",
50
50
  "default": "./src/drivers/node-pool.js"
51
+ },
52
+ "./relational": {
53
+ "types": "./types/relational.d.ts",
54
+ "default": "./src/relational-api.js"
55
+ },
56
+ "./query": {
57
+ "types": "./types/query.d.ts",
58
+ "default": "./src/query-api.js"
59
+ },
60
+ "./model": {
61
+ "types": "./types/model.d.ts",
62
+ "default": "./src/model-api.js"
63
+ },
64
+ "./entity": {
65
+ "types": "./types/entity.d.ts",
66
+ "default": "./src/entity.js"
51
67
  }
52
68
  },
53
69
  "files": [
@@ -88,9 +104,9 @@
88
104
  "prepack": "npm run build:types"
89
105
  },
90
106
  "dependencies": {
91
- "@jarenjs/core": "^0.84.3",
92
- "@jarenjs/json": "^0.84.3",
93
- "@jarenjs/validate": "^0.84.3"
107
+ "@jarenjs/core": "^0.85.0",
108
+ "@jarenjs/json": "^0.85.0",
109
+ "@jarenjs/validate": "^0.85.0"
94
110
  },
95
111
  "bin": {
96
112
  "jaren-db": "./src/cli.js"
@@ -233,10 +233,167 @@
233
233
  },
234
234
  "generated": {
235
235
  "type": "boolean"
236
+ },
237
+ "type": {
238
+ "enum": [
239
+ "INTEGER",
240
+ "REAL",
241
+ "TEXT",
242
+ "BLOB",
243
+ "NUMERIC"
244
+ ]
245
+ },
246
+ "defaultValue": {
247
+ "description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
248
+ "anyOf": [
249
+ {
250
+ "type": [
251
+ "string",
252
+ "number",
253
+ "null"
254
+ ]
255
+ },
256
+ {
257
+ "type": "object",
258
+ "required": [
259
+ "$sql"
260
+ ],
261
+ "properties": {
262
+ "$sql": {
263
+ "enum": [
264
+ "column",
265
+ "value",
266
+ "binary",
267
+ "not",
268
+ "in",
269
+ "call",
270
+ "cast",
271
+ "collate",
272
+ "case",
273
+ "scalar",
274
+ "exists"
275
+ ]
276
+ }
277
+ }
278
+ }
279
+ ]
280
+ },
281
+ "collation": {
282
+ "enum": [
283
+ "BINARY",
284
+ "NOCASE",
285
+ "RTRIM"
286
+ ]
287
+ },
288
+ "identity": {
289
+ "enum": [
290
+ "rowid",
291
+ "autoincrement"
292
+ ]
293
+ },
294
+ "check": {
295
+ "description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
296
+ "anyOf": [
297
+ {
298
+ "type": [
299
+ "string",
300
+ "number",
301
+ "null"
302
+ ]
303
+ },
304
+ {
305
+ "type": "object",
306
+ "required": [
307
+ "$sql"
308
+ ],
309
+ "properties": {
310
+ "$sql": {
311
+ "enum": [
312
+ "column",
313
+ "value",
314
+ "binary",
315
+ "not",
316
+ "in",
317
+ "call",
318
+ "cast",
319
+ "collate",
320
+ "case",
321
+ "scalar",
322
+ "exists"
323
+ ]
324
+ }
325
+ }
326
+ }
327
+ ]
328
+ },
329
+ "generatedExpression": {
330
+ "description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
331
+ "anyOf": [
332
+ {
333
+ "type": [
334
+ "string",
335
+ "number",
336
+ "null"
337
+ ]
338
+ },
339
+ {
340
+ "type": "object",
341
+ "required": [
342
+ "$sql"
343
+ ],
344
+ "properties": {
345
+ "$sql": {
346
+ "enum": [
347
+ "column",
348
+ "value",
349
+ "binary",
350
+ "not",
351
+ "in",
352
+ "call",
353
+ "cast",
354
+ "collate",
355
+ "case",
356
+ "scalar",
357
+ "exists"
358
+ ]
359
+ }
360
+ }
361
+ }
362
+ ]
363
+ },
364
+ "stored": {
365
+ "type": "boolean"
236
366
  }
237
367
  },
238
368
  "additionalProperties": false
239
369
  }
370
+ },
371
+ "constraints": {
372
+ "type": "array",
373
+ "items": {
374
+ "type": "object"
375
+ },
376
+ "description": "Structural SQLite declarations validated by planTable."
377
+ },
378
+ "indexes": {
379
+ "type": "array",
380
+ "items": {
381
+ "type": "object"
382
+ },
383
+ "description": "Structural SQLite declarations validated by planTable."
384
+ },
385
+ "triggers": {
386
+ "type": "array",
387
+ "items": {
388
+ "type": "object"
389
+ },
390
+ "description": "Structural SQLite declarations validated by planTable."
391
+ },
392
+ "strict": {
393
+ "type": "boolean"
394
+ },
395
+ "withoutRowid": {
396
+ "type": "boolean"
240
397
  }
241
398
  },
242
399
  "additionalProperties": false