litedbmodel 1.2.9 → 2.0.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/README.md +1 -1
- package/dist/DBModel.d.ts.map +1 -1
- package/dist/DBModel.js +6 -0
- package/dist/DBModel.js.map +1 -1
- package/dist/scp/authoring-sql.d.ts +56 -0
- package/dist/scp/authoring-sql.d.ts.map +1 -0
- package/dist/scp/authoring-sql.js +83 -0
- package/dist/scp/authoring-sql.js.map +1 -0
- package/dist/scp/authoring.d.ts +155 -0
- package/dist/scp/authoring.d.ts.map +1 -0
- package/dist/scp/authoring.js +162 -0
- package/dist/scp/authoring.js.map +1 -0
- package/dist/scp/bridge.d.ts +64 -0
- package/dist/scp/bridge.d.ts.map +1 -0
- package/dist/scp/bridge.js +329 -0
- package/dist/scp/bridge.js.map +1 -0
- package/dist/scp/catalog.d.ts +91 -0
- package/dist/scp/catalog.d.ts.map +1 -0
- package/dist/scp/catalog.js +203 -0
- package/dist/scp/catalog.js.map +1 -0
- package/dist/scp/codegen.d.ts +131 -0
- package/dist/scp/codegen.d.ts.map +1 -0
- package/dist/scp/codegen.js +137 -0
- package/dist/scp/codegen.js.map +1 -0
- package/dist/scp/compile-dialect.d.ts +39 -0
- package/dist/scp/compile-dialect.d.ts.map +1 -0
- package/dist/scp/compile-dialect.js +62 -0
- package/dist/scp/compile-dialect.js.map +1 -0
- package/dist/scp/compile-sqlite.d.ts +114 -0
- package/dist/scp/compile-sqlite.d.ts.map +1 -0
- package/dist/scp/compile-sqlite.js +149 -0
- package/dist/scp/compile-sqlite.js.map +1 -0
- package/dist/scp/dialect.d.ts +141 -0
- package/dist/scp/dialect.d.ts.map +1 -0
- package/dist/scp/dialect.js +194 -0
- package/dist/scp/dialect.js.map +1 -0
- package/dist/scp/errors.d.ts +36 -0
- package/dist/scp/errors.d.ts.map +1 -0
- package/dist/scp/errors.js +72 -0
- package/dist/scp/errors.js.map +1 -0
- package/dist/scp/guard.d.ts +47 -0
- package/dist/scp/guard.d.ts.map +1 -0
- package/dist/scp/guard.js +137 -0
- package/dist/scp/guard.js.map +1 -0
- package/dist/scp/index.cjs +4744 -0
- package/dist/scp/index.d.ts +49 -0
- package/dist/scp/index.d.ts.map +1 -0
- package/dist/scp/index.js +164 -0
- package/dist/scp/index.js.map +1 -0
- package/dist/scp/index.mjs +2000 -0
- package/dist/scp/ir.d.ts +92 -0
- package/dist/scp/ir.d.ts.map +1 -0
- package/dist/scp/ir.js +28 -0
- package/dist/scp/ir.js.map +1 -0
- package/dist/scp/relation.d.ts +136 -0
- package/dist/scp/relation.d.ts.map +1 -0
- package/dist/scp/relation.js +191 -0
- package/dist/scp/relation.js.map +1 -0
- package/dist/scp/render.d.ts +40 -0
- package/dist/scp/render.d.ts.map +1 -0
- package/dist/scp/render.js +170 -0
- package/dist/scp/render.js.map +1 -0
- package/dist/scp/runtime.d.ts +295 -0
- package/dist/scp/runtime.d.ts.map +1 -0
- package/dist/scp/runtime.js +665 -0
- package/dist/scp/runtime.js.map +1 -0
- package/dist/scp/typed-object.d.ts +88 -0
- package/dist/scp/typed-object.d.ts.map +1 -0
- package/dist/scp/typed-object.js +163 -0
- package/dist/scp/typed-object.js.map +1 -0
- package/dist/scp/write-plan.d.ts +161 -0
- package/dist/scp/write-plan.d.ts.map +1 -0
- package/dist/scp/write-plan.js +528 -0
- package/dist/scp/write-plan.js.map +1 -0
- package/dist/scp/write-runtime.d.ts +80 -0
- package/dist/scp/write-runtime.d.ts.map +1 -0
- package/dist/scp/write-runtime.js +167 -0
- package/dist/scp/write-runtime.js.map +1 -0
- package/dist/scp/writes.d.ts +251 -0
- package/dist/scp/writes.d.ts.map +1 -0
- package/dist/scp/writes.js +176 -0
- package/dist/scp/writes.js.map +1 -0
- package/docs/proposal/contracts-architecture-feasibility.md +328 -0
- package/docs/proposal/contracts-architecture.md +579 -0
- package/docs/proposal/litedbmodel-v2-scp-architecture.md +382 -0
- package/docs/proposal/sql-dynamic-expansion-spec.md +175 -0
- package/package.json +27 -5
- package/docs/README_REVIEW.md +0 -23
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* litedbmodel v2 SCP — the WS1↔WS3 Backend-Compile bridge (WS3, #23).
|
|
4
|
+
*
|
|
5
|
+
* WS2 (`authoring.ts`) produces the REAL behavior-contracts `ComponentGraphIR`: a
|
|
6
|
+
* Component's body carries `componentRef` / `map` nodes whose `ports` are Expression IR.
|
|
7
|
+
* The SQL-structural ports (`where`, `select`, `values.<field>`, `set.<field>`, `limit`,
|
|
8
|
+
* `order`, …) are NOT plain scalars — the `where` port is `{arr:[ <cond-expr>, … ]}` where
|
|
9
|
+
* a SKIP-optional condition is a pure `{cond:[c, <frag-expr>, null]}` node (WS2), and a
|
|
10
|
+
* comparison condition is a closed-set Expression `{eq:[<colRef>, <valueExpr>]}` (spec §7).
|
|
11
|
+
*
|
|
12
|
+
* WS1's Backend-Compile (`compile-sqlite.ts`) consumes a structured `SelectDesc` /
|
|
13
|
+
* `Condition[]`. NOTHING produced that shape from the real IR — this module closes that
|
|
14
|
+
* gap. It reads a raw `componentRef`/`map` node's ports directly and lowers them to WS1's
|
|
15
|
+
* `CompiledOperation` (SQL text + fragment tree + static param slots), performing the
|
|
16
|
+
* **SKIP → fragment-existence collapse**: a `{cond:[c, frag, null]}` where-member becomes a
|
|
17
|
+
* fragment guarded by `when: c` (present iff `c` is present), exactly the existence rule
|
|
18
|
+
* `render.ts` implements (dynamic-expansion spec §2). This is the single place that maps
|
|
19
|
+
* the real bc port shape → WS1 compile input; WS1's compiler is unchanged (its golden
|
|
20
|
+
* SQL text is the pinned bar) and now has a producer for its `SelectDesc`/`Condition`.
|
|
21
|
+
*
|
|
22
|
+
* ## WHERE condition interpretation (spec §7) — closed-set ONLY
|
|
23
|
+
*
|
|
24
|
+
* SKIP existence, IN-list membership and IS NULL are **fragment structure, NOT Expression
|
|
25
|
+
* IR opcodes** (catalog `where` port type is `fragment`; bc `expression-ir.md` §4: SKIP is
|
|
26
|
+
* OUTSIDE Expression IR). But bc's authoring lowering (`compileBehaviors`) only emits
|
|
27
|
+
* closed-set Expression IR into a port, so every where-member arrives as a closed-set node.
|
|
28
|
+
* This bridge therefore reads them STRUCTURALLY into fragment kinds WITHOUT inventing any
|
|
29
|
+
* opcode (the hard rule): every member is one of bc's closed operators, decoded here.
|
|
30
|
+
*
|
|
31
|
+
* - `{eq:[<colRef>, null]}` → `{ kind:'isNull', column }` (SQL `col IS NULL`)
|
|
32
|
+
* - `{eq:[<colRef>, <valueExpr>]}` → `{ kind:'eq', column, value:<valueExpr> }`
|
|
33
|
+
* - `{eq:[{ref:[IN_SENTINEL, col]}, <arrExpr>]}` → `{ kind:'in', column, value:<arrExpr> }`
|
|
34
|
+
* - `{lt|le|gt|ge|ne:[<colRef>, v]}` → `{ kind:'cmp', column, op, value:v }`
|
|
35
|
+
* - `{and|or:[m1, m2, …]}` → a nested `{ kind:'group', connector, conditions }`
|
|
36
|
+
* - `{cond:[c, <member>, null]}` → the lowered `<member>` with `skipWhen: c` (SKIP)
|
|
37
|
+
*
|
|
38
|
+
* The LEFT operand of a comparison names the column (spec §7 `{ref:["author_id"]}`): its
|
|
39
|
+
* `ref` path's LAST segment is the column name. The RIGHT operand is the value slot — a
|
|
40
|
+
* closed-set Expression IR node bound at render time. The litedbmodel authoring helpers
|
|
41
|
+
* ({@link import('./authoring-sql')}) produce exactly these closed-set encodings, so the
|
|
42
|
+
* WS2 portability guard passes and this decoder round-trips them to the WS1 fragment tree.
|
|
43
|
+
*/
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.IN_SENTINEL = void 0;
|
|
46
|
+
exports.compileNode = compileNode;
|
|
47
|
+
exports.compileComponentNodes = compileComponentNodes;
|
|
48
|
+
/** The reserved column-ref path head that marks an IN-list membership (see module doc). */
|
|
49
|
+
exports.IN_SENTINEL = '@in';
|
|
50
|
+
const compile_sqlite_1 = require("./compile-sqlite");
|
|
51
|
+
const compile_dialect_1 = require("./compile-dialect");
|
|
52
|
+
const dialect_1 = require("./dialect");
|
|
53
|
+
function isMap(n) {
|
|
54
|
+
return 'map' in n;
|
|
55
|
+
}
|
|
56
|
+
/** The catalog-name + ports of a `componentRef`/`map` body node (uniform view). */
|
|
57
|
+
function nodeRef(n) {
|
|
58
|
+
return isMap(n) ? { component: n.map.component, ports: n.map.ports } : { component: n.component, ports: n.ports };
|
|
59
|
+
}
|
|
60
|
+
// ── Port readers (structural — no evaluation) ─────────────────────────────────
|
|
61
|
+
/** A port that must be a literal string (`table`, `order`, `group`, `returning`). */
|
|
62
|
+
function stringPort(ports, name) {
|
|
63
|
+
const v = ports[name];
|
|
64
|
+
if (v === undefined)
|
|
65
|
+
return undefined;
|
|
66
|
+
if (typeof v !== 'string') {
|
|
67
|
+
throw new Error(`bridge: port '${name}' must be a literal string in the IR (got ${JSON.stringify(v)})`);
|
|
68
|
+
}
|
|
69
|
+
return v;
|
|
70
|
+
}
|
|
71
|
+
/** A `{arr:[...]}` port → its element array (a bc-lowered literal array). */
|
|
72
|
+
function arrPort(ports, name) {
|
|
73
|
+
const v = ports[name];
|
|
74
|
+
if (v === undefined)
|
|
75
|
+
return undefined;
|
|
76
|
+
if (typeof v === 'object' && v !== null && 'arr' in v && Array.isArray(v.arr)) {
|
|
77
|
+
return v.arr;
|
|
78
|
+
}
|
|
79
|
+
throw new Error(`bridge: port '${name}' must be an {arr:[...]} literal in the IR (got ${JSON.stringify(v)})`);
|
|
80
|
+
}
|
|
81
|
+
/** `select` / `returning` string-array port → `string[]` (elements must be literals). */
|
|
82
|
+
function stringArrayPort(ports, name) {
|
|
83
|
+
const arr = arrPort(ports, name);
|
|
84
|
+
if (arr === undefined)
|
|
85
|
+
return undefined;
|
|
86
|
+
return arr.map((e) => {
|
|
87
|
+
if (typeof e !== 'string')
|
|
88
|
+
throw new Error(`bridge: '${name}' entries must be literal strings (got ${JSON.stringify(e)})`);
|
|
89
|
+
return e;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** The single-key operator name of an Expression node, or undefined if not a 1-key object. */
|
|
93
|
+
function opKey(node) {
|
|
94
|
+
if (node === null || typeof node !== 'object' || Array.isArray(node))
|
|
95
|
+
return undefined;
|
|
96
|
+
const keys = Object.keys(node);
|
|
97
|
+
return keys.length === 1 ? keys[0] : undefined;
|
|
98
|
+
}
|
|
99
|
+
/** The column name carried by a `ref`/`refOpt` path (its LAST segment — spec §7). */
|
|
100
|
+
function columnOf(node, ctx) {
|
|
101
|
+
const op = opKey(node);
|
|
102
|
+
if (op !== 'ref' && op !== 'refOpt') {
|
|
103
|
+
throw new Error(`bridge: ${ctx}: the column operand must be a {ref:[...]} / {refOpt:[...]} path, got ${JSON.stringify(node)}`);
|
|
104
|
+
}
|
|
105
|
+
const path = node[op];
|
|
106
|
+
if (!Array.isArray(path) || path.length === 0 || typeof path[path.length - 1] !== 'string') {
|
|
107
|
+
throw new Error(`bridge: ${ctx}: column ref path must be a non-empty string path`);
|
|
108
|
+
}
|
|
109
|
+
return path[path.length - 1];
|
|
110
|
+
}
|
|
111
|
+
const CMP_OPS = {
|
|
112
|
+
lt: '<',
|
|
113
|
+
le: '<=',
|
|
114
|
+
gt: '>',
|
|
115
|
+
ge: '>=',
|
|
116
|
+
ne: '<>',
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* If a column operand is an IN-list membership marker (its `ref`/`refOpt` path head is
|
|
120
|
+
* {@link IN_SENTINEL}), return the real column name (the segment AFTER the sentinel);
|
|
121
|
+
* otherwise undefined. The sentinel keeps IN-list expressible with only the closed-set
|
|
122
|
+
* `eq` + `ref` operators (no invented `in` opcode).
|
|
123
|
+
*/
|
|
124
|
+
function inSentinelColumn(node) {
|
|
125
|
+
const op = opKey(node);
|
|
126
|
+
if (op !== 'ref' && op !== 'refOpt')
|
|
127
|
+
return undefined;
|
|
128
|
+
const path = node[op];
|
|
129
|
+
if (Array.isArray(path) && path.length >= 2 && path[0] === exports.IN_SENTINEL && typeof path[path.length - 1] === 'string') {
|
|
130
|
+
return path[path.length - 1];
|
|
131
|
+
}
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Lower ONE where-member Expression node to a WS1 {@link Condition} (structural read).
|
|
136
|
+
* A `{cond:[c, member, null]}` node is the SKIP-optional collapse: the inner `member` is
|
|
137
|
+
* lowered and its `skipWhen` set to `c` (present iff `c` is present — dynamic-expansion §2).
|
|
138
|
+
*/
|
|
139
|
+
function lowerWhereMember(node, at) {
|
|
140
|
+
const op = opKey(node);
|
|
141
|
+
if (op === undefined) {
|
|
142
|
+
throw new Error(`bridge: ${at}: a where member must be a single-operator Expression node, got ${JSON.stringify(node)}`);
|
|
143
|
+
}
|
|
144
|
+
if (op === 'cond') {
|
|
145
|
+
// SKIP-optional: {cond:[c, <member>, null]}. The else branch MUST be null (absence).
|
|
146
|
+
const args = node.cond;
|
|
147
|
+
if (!Array.isArray(args) || args.length !== 3 || args[2] !== null) {
|
|
148
|
+
throw new Error(`bridge: ${at}: a SKIP-optional condition must be {cond:[c, <member>, null]} (else = null)`);
|
|
149
|
+
}
|
|
150
|
+
const inner = lowerWhereMember(args[1], `${at}.cond.then`);
|
|
151
|
+
if (inner.skipWhen !== undefined) {
|
|
152
|
+
throw new Error(`bridge: ${at}: nested SKIP guards are not supported (one cond per member)`);
|
|
153
|
+
}
|
|
154
|
+
return { ...inner, skipWhen: args[0] };
|
|
155
|
+
}
|
|
156
|
+
if (op === 'and' || op === 'or') {
|
|
157
|
+
// A nested group: {and|or:[m1, m2, ...]} → a Condition group.
|
|
158
|
+
const args = node[op];
|
|
159
|
+
if (!Array.isArray(args) || args.length < 2) {
|
|
160
|
+
throw new Error(`bridge: ${at}: '${op}' group expects >= 2 members`);
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
kind: 'group',
|
|
164
|
+
connector: op === 'and' ? 'AND' : 'OR',
|
|
165
|
+
conditions: args.map((m, i) => lowerWhereMember(m, `${at}.${op}[${i}]`)),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (op === 'eq') {
|
|
169
|
+
const [col, val] = binOperands(node, op, at);
|
|
170
|
+
// IN-list membership: the column ref path head is the reserved IN_SENTINEL.
|
|
171
|
+
const inCol = inSentinelColumn(col);
|
|
172
|
+
if (inCol !== undefined) {
|
|
173
|
+
return { kind: 'in', column: inCol, value: val };
|
|
174
|
+
}
|
|
175
|
+
// IS NULL: `eq(col, null)` (a null literal RHS) → SQL `col IS NULL` (v1 parity).
|
|
176
|
+
if (val === null) {
|
|
177
|
+
return { kind: 'isNull', column: columnOf(col, at) };
|
|
178
|
+
}
|
|
179
|
+
return { kind: 'eq', column: columnOf(col, at), value: val };
|
|
180
|
+
}
|
|
181
|
+
if (op in CMP_OPS) {
|
|
182
|
+
const [col, val] = binOperands(node, op, at);
|
|
183
|
+
return { kind: 'cmp', column: columnOf(col, at), op: CMP_OPS[op], value: val };
|
|
184
|
+
}
|
|
185
|
+
throw new Error(`bridge: ${at}: unsupported where operator '${op}' (supported: eq/ne/lt/le/gt/ge/and/or/cond; IN via ${exports.IN_SENTINEL} column head; IS NULL via eq(col,null))`);
|
|
186
|
+
}
|
|
187
|
+
/** Read the two operands of a binary comparison node, fail-closed on arity. */
|
|
188
|
+
function binOperands(node, op, at) {
|
|
189
|
+
const args = node[op];
|
|
190
|
+
if (!Array.isArray(args) || args.length !== 2) {
|
|
191
|
+
throw new Error(`bridge: ${at}: '${op}' expects exactly 2 operands`);
|
|
192
|
+
}
|
|
193
|
+
return [args[0], args[1]];
|
|
194
|
+
}
|
|
195
|
+
/** Lower the `where` port (`{arr:[...]}` of member nodes) to a WS1 `Condition[]`. */
|
|
196
|
+
function lowerWherePort(ports, at) {
|
|
197
|
+
const arr = arrPort(ports, 'where');
|
|
198
|
+
if (arr === undefined)
|
|
199
|
+
return undefined;
|
|
200
|
+
return arr.map((m, i) => lowerWhereMember(m, `${at}.where[${i}]`));
|
|
201
|
+
}
|
|
202
|
+
// ── The write value/set record families (`values.<field>` / `set.<field>`) ────
|
|
203
|
+
/**
|
|
204
|
+
* Collect a flattened write record family (`<prefix>.<field>` ports) → an ordered
|
|
205
|
+
* `Record<field, ExprNode>`. Field order = declaration (insertion) order of the ports,
|
|
206
|
+
* which is the SQL column order the golden pins.
|
|
207
|
+
*/
|
|
208
|
+
function collectFamily(ports, prefix) {
|
|
209
|
+
const out = {};
|
|
210
|
+
for (const k of Object.keys(ports)) {
|
|
211
|
+
if (k.startsWith(`${prefix}.`))
|
|
212
|
+
out[k.slice(prefix.length + 1)] = ports[k];
|
|
213
|
+
}
|
|
214
|
+
return out;
|
|
215
|
+
}
|
|
216
|
+
/** Parse the Insert conflict ports into WS1's `onConflict` / `onConflictAction`. */
|
|
217
|
+
function conflictOf(ports) {
|
|
218
|
+
const onConflict = stringPort(ports, 'onConflict');
|
|
219
|
+
const action = stringPort(ports, 'onConflictAction');
|
|
220
|
+
if (onConflict === undefined)
|
|
221
|
+
return {};
|
|
222
|
+
const keys = onConflict.split(',').map((s) => s.trim()).filter((s) => s.length > 0);
|
|
223
|
+
if (action === undefined || action === 'ignore') {
|
|
224
|
+
return { onConflict: keys, onConflictAction: 'ignore' };
|
|
225
|
+
}
|
|
226
|
+
if (action === 'update') {
|
|
227
|
+
// Update all inserted columns except the conflict keys (SQLite `excluded.*` upsert).
|
|
228
|
+
return { onConflict: keys, onConflictAction: { updateColumns: 'all' } };
|
|
229
|
+
}
|
|
230
|
+
// `update:col1,col2` — explicit update column list.
|
|
231
|
+
const m = /^update:(.+)$/.exec(action);
|
|
232
|
+
if (m) {
|
|
233
|
+
return { onConflict: keys, onConflictAction: { updateColumns: m[1].split(',').map((s) => s.trim()) } };
|
|
234
|
+
}
|
|
235
|
+
throw new Error(`bridge: unsupported onConflictAction '${action}' (expected 'ignore' / 'update' / 'update:col,col')`);
|
|
236
|
+
}
|
|
237
|
+
/** RETURNING port (`"id, title"` literal) → `string[]`. */
|
|
238
|
+
function returningOf(ports) {
|
|
239
|
+
const r = stringPort(ports, 'returning');
|
|
240
|
+
if (r === undefined)
|
|
241
|
+
return undefined;
|
|
242
|
+
return r.split(',').map((s) => s.trim()).filter((s) => s.length > 0);
|
|
243
|
+
}
|
|
244
|
+
// ── Node → CompiledOperation ──────────────────────────────────────────────────
|
|
245
|
+
/**
|
|
246
|
+
* Backend-Compile ONE catalog `componentRef`/`map` body node into a WS1
|
|
247
|
+
* {@link CompiledOperation}. This is the real IR → WS1 compile-input bridge for the
|
|
248
|
+
* SQL CRUD primitives.
|
|
249
|
+
*/
|
|
250
|
+
function compileNode(node, dialect = dialect_1.SQLITE) {
|
|
251
|
+
const { component, ports } = nodeRef(node);
|
|
252
|
+
const table = stringPort(ports, 'table');
|
|
253
|
+
if (table === undefined)
|
|
254
|
+
throw new Error(`bridge: ${component} node requires a literal 'table' port`);
|
|
255
|
+
const at = `${component}`;
|
|
256
|
+
switch (component) {
|
|
257
|
+
case 'Select': {
|
|
258
|
+
const select = stringArrayPort(ports, 'select');
|
|
259
|
+
if (select === undefined)
|
|
260
|
+
throw new Error(`bridge: Select requires a 'select' {arr:[...]} port`);
|
|
261
|
+
const desc = { table, select };
|
|
262
|
+
const where = lowerWherePort(ports, at);
|
|
263
|
+
if (where !== undefined)
|
|
264
|
+
desc.where = where;
|
|
265
|
+
const order = stringPort(ports, 'order');
|
|
266
|
+
if (order !== undefined)
|
|
267
|
+
desc.order = order;
|
|
268
|
+
const group = stringPort(ports, 'group');
|
|
269
|
+
if (group !== undefined)
|
|
270
|
+
desc.group = group;
|
|
271
|
+
if (ports.limit !== undefined)
|
|
272
|
+
desc.limit = ports.limit;
|
|
273
|
+
if (ports.offset !== undefined)
|
|
274
|
+
desc.offset = ports.offset;
|
|
275
|
+
return (0, compile_sqlite_1.compileSelect)(desc);
|
|
276
|
+
}
|
|
277
|
+
case 'Insert': {
|
|
278
|
+
const values = collectFamily(ports, 'values');
|
|
279
|
+
if (Object.keys(values).length === 0)
|
|
280
|
+
throw new Error(`bridge: Insert requires at least one 'values.<field>' port`);
|
|
281
|
+
const desc = { table, values, ...conflictOf(ports) };
|
|
282
|
+
const returning = returningOf(ports);
|
|
283
|
+
if (returning !== undefined)
|
|
284
|
+
desc.returning = returning;
|
|
285
|
+
return (0, compile_dialect_1.compileInsertFor)(dialect, desc);
|
|
286
|
+
}
|
|
287
|
+
case 'Update': {
|
|
288
|
+
const set = collectFamily(ports, 'set');
|
|
289
|
+
if (Object.keys(set).length === 0)
|
|
290
|
+
throw new Error(`bridge: Update requires at least one 'set.<field>' port`);
|
|
291
|
+
const where = lowerWherePort(ports, at);
|
|
292
|
+
if (where === undefined)
|
|
293
|
+
throw new Error(`bridge: Update requires a 'where' port`);
|
|
294
|
+
const desc = { table, set, where };
|
|
295
|
+
const returning = returningOf(ports);
|
|
296
|
+
if (returning !== undefined)
|
|
297
|
+
desc.returning = returning;
|
|
298
|
+
return (0, compile_sqlite_1.compileUpdate)(desc);
|
|
299
|
+
}
|
|
300
|
+
case 'Delete': {
|
|
301
|
+
const where = lowerWherePort(ports, at);
|
|
302
|
+
if (where === undefined)
|
|
303
|
+
throw new Error(`bridge: Delete requires a 'where' port`);
|
|
304
|
+
const desc = { table, where };
|
|
305
|
+
const returning = returningOf(ports);
|
|
306
|
+
if (returning !== undefined)
|
|
307
|
+
desc.returning = returning;
|
|
308
|
+
return (0, compile_sqlite_1.compileDelete)(desc);
|
|
309
|
+
}
|
|
310
|
+
default:
|
|
311
|
+
throw new Error(`bridge: catalog component '${component}' has no Backend-Compile (SQL CRUD only: Select/Insert/Update/Delete)`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Backend-Compile every catalog node of a component into a `nodeId → CompiledOperation`
|
|
316
|
+
* map. `cond` nodes carry no catalog reference and are skipped (they are pure Expression,
|
|
317
|
+
* evaluated by bc's `runBehavior`). The thin runtime looks up a node's `CompiledOperation`
|
|
318
|
+
* by `ctx.nodeId` when its handler fires.
|
|
319
|
+
*/
|
|
320
|
+
function compileComponentNodes(component, dialect = dialect_1.SQLITE) {
|
|
321
|
+
const out = new Map();
|
|
322
|
+
for (const n of component.body) {
|
|
323
|
+
if ('cond' in n)
|
|
324
|
+
continue;
|
|
325
|
+
out.set(n.id, compileNode(n, dialect));
|
|
326
|
+
}
|
|
327
|
+
return out;
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/scp/bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* litedbmodel v2 SCP catalog — WS1 (#21).
|
|
3
|
+
*
|
|
4
|
+
* `LITEDBMODEL_CATALOG` is the behavior-contracts–typed `Catalog` that IS the whole
|
|
5
|
+
* per-DSL difference litedbmodel supplies as a SQL-backend consumer (bc C2: "the only
|
|
6
|
+
* per-DSL difference is the catalog"). It mirrors the SHAPE of graphddb's
|
|
7
|
+
* `GRAPHDDB_CATALOG` (`src/spec/catalog.ts`) exactly: compact `PortSchema` constructors,
|
|
8
|
+
* an `entry()` helper, per-primitive `inputPorts`, an `output.shape`, and a
|
|
9
|
+
* `portableToIR` flag. The effect implementation (SQL execution + row→model assembly) is
|
|
10
|
+
* bound separately in the handler registry (WS3, C4 — catalog declares, registry binds).
|
|
11
|
+
*
|
|
12
|
+
* ## Catalog names (spec §1 / §11 item 1)
|
|
13
|
+
*
|
|
14
|
+
* `Select` / `Insert` / `Update` / `Delete` are the CRUD leaf components. `Fragment` is
|
|
15
|
+
* the dynamic WHERE/SET fragment-tree component (SKIP → fragment existence rules, §8);
|
|
16
|
+
* `Tx` is the multi-statement transaction envelope. As in graphddb, the transaction
|
|
17
|
+
* envelope (`Tx`) is `portableToIR: false` — a transaction is emitted as a Component
|
|
18
|
+
* whose body references the per-statement CRUD primitives; the atomic BEGIN/COMMIT
|
|
19
|
+
* envelope is the runtime's execution concern (WS3), never a portable-IR node.
|
|
20
|
+
*
|
|
21
|
+
* ## Port schema conventions
|
|
22
|
+
*
|
|
23
|
+
* A `CatalogEntry.inputPorts` names the STATIC ports of the emitted wiring. Two families
|
|
24
|
+
* are dynamic by construction and are validated by {@link assertComponentsInCatalog}
|
|
25
|
+
* against documented patterns instead of being statically enumerable:
|
|
26
|
+
*
|
|
27
|
+
* - **`where`/`set`/`values` records**: one port per model field, flattened one-port-
|
|
28
|
+
* per-field under a `<group>.<field>` key ({@link WRITE_PORT_FAMILIES}). These carry
|
|
29
|
+
* Expression IR (the field's value/condition), from the closed operator set only.
|
|
30
|
+
*
|
|
31
|
+
* The CRUD entries carry `additionalPorts: true` (bc#26) so bc's shared port check
|
|
32
|
+
* (`checkPortNames` / `buildComponentDefinition`) accepts the dynamic families; every
|
|
33
|
+
* DECLARED port keeps bc's required/type checks regardless of the opt-in. `Tx`'s single
|
|
34
|
+
* port is static, so it keeps bc's fail-closed default.
|
|
35
|
+
*/
|
|
36
|
+
import { type Catalog, type CatalogEntry, type Component } from 'behavior-contracts';
|
|
37
|
+
/**
|
|
38
|
+
* The catalog-name literal union — one entry per SQL primitive litedbmodel declares:
|
|
39
|
+
* the CRUD leaves (`Select` / `Insert` / `Update` / `Delete`), the dynamic WHERE/SET
|
|
40
|
+
* fragment-tree component (`Fragment`), and the multi-statement transaction envelope
|
|
41
|
+
* (`Tx`).
|
|
42
|
+
*/
|
|
43
|
+
export type CatalogName = 'Select' | 'Insert' | 'Update' | 'Delete' | 'Fragment' | 'Tx';
|
|
44
|
+
/**
|
|
45
|
+
* litedbmodel's specific-component catalog (spec §11 item 1) — the behavior-contracts
|
|
46
|
+
* `Catalog`-typed source of truth. Each entry declares the Port schema of one SQL
|
|
47
|
+
* primitive AS THE BACKEND COMPILE WIRES IT; the effect implementation is bound
|
|
48
|
+
* separately in the handler registry (WS3, C4). All entries except `Tx` may appear in
|
|
49
|
+
* the portable IR.
|
|
50
|
+
*/
|
|
51
|
+
export declare const LITEDBMODEL_CATALOG: Catalog;
|
|
52
|
+
/** Look up a catalog entry by name (undefined for an unknown primitive). */
|
|
53
|
+
export declare function catalogEntry(name: string): CatalogEntry | undefined;
|
|
54
|
+
/** The catalog names litedbmodel declares (the C2 per-DSL surface). */
|
|
55
|
+
export declare const CATALOG_NAMES: readonly CatalogName[];
|
|
56
|
+
/**
|
|
57
|
+
* The CQRS write catalog: the names whose presence in a component body makes the
|
|
58
|
+
* component a COMMAND (spec §2.4 — effect is derived from the graph, not authored).
|
|
59
|
+
* `Select`/`Fragment` are read-side; `Insert`/`Update`/`Delete`/`Tx` are write-side.
|
|
60
|
+
*/
|
|
61
|
+
export declare const WRITE_CATALOG_NAMES: readonly CatalogName[];
|
|
62
|
+
/**
|
|
63
|
+
* The dynamic per-field write-port families (`<group>.<field>` — the flattened record
|
|
64
|
+
* convention; longest-prefix wins). A `values.<field>` (Insert) or `set.<field>`
|
|
65
|
+
* (Update) port carries the field's Expression IR value.
|
|
66
|
+
*/
|
|
67
|
+
export declare const WRITE_PORT_FAMILIES: readonly string[];
|
|
68
|
+
/**
|
|
69
|
+
* The emitter's catalog validation (loud; a violation is a BUILD error), mirrored from
|
|
70
|
+
* graphddb's `assertComponentsInCatalog`. Every `componentRef` / `map` body node of every
|
|
71
|
+
* emitted component must:
|
|
72
|
+
*
|
|
73
|
+
* 1. reference a declared catalog name;
|
|
74
|
+
* 2. wire every `required` port of that entry;
|
|
75
|
+
* 3. wire ONLY declared ports — a port is declared if it is a static `inputPorts` name or
|
|
76
|
+
* a write record-family port ({@link WRITE_PORT_FAMILIES}, write entries only).
|
|
77
|
+
*
|
|
78
|
+
* All violations are collected and thrown as one error. `cond` nodes carry no component
|
|
79
|
+
* reference and are skipped.
|
|
80
|
+
*/
|
|
81
|
+
export declare function assertComponentsInCatalog(components: readonly Component[]): void;
|
|
82
|
+
/** litedbmodel's CQRS effect vocabulary, mapped 1:1 from bc's `BehaviorEffect`. */
|
|
83
|
+
export type ContractEffect = 'query' | 'command';
|
|
84
|
+
/**
|
|
85
|
+
* Derive one component's Query/Command classification FROM THE GRAPH: behavior-contracts'
|
|
86
|
+
* `classifyBehaviorEffect` over {@link WRITE_CATALOG_NAMES} — a component is a `'command'`
|
|
87
|
+
* iff its body references a write-catalog primitive, else a `'query'` (spec §2.4: effect
|
|
88
|
+
* is derived, never authored).
|
|
89
|
+
*/
|
|
90
|
+
export declare function deriveContractEffect(component: Component): ContractEffect;
|
|
91
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/scp/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAA0B,KAAK,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAmB,MAAM,oBAAoB,CAAC;AAE9H;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,IAAI,CAAC;AAmDT;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,OAmBjC,CAAC;AAEF,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAEnE;AAED,uEAAuE;AACvE,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAO/C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,WAAW,EAKrD,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAGhD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CA4BhF;AAGD,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,CAAC;AAEjD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS,GAAG,cAAc,CAEzE"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* litedbmodel v2 SCP catalog — WS1 (#21).
|
|
4
|
+
*
|
|
5
|
+
* `LITEDBMODEL_CATALOG` is the behavior-contracts–typed `Catalog` that IS the whole
|
|
6
|
+
* per-DSL difference litedbmodel supplies as a SQL-backend consumer (bc C2: "the only
|
|
7
|
+
* per-DSL difference is the catalog"). It mirrors the SHAPE of graphddb's
|
|
8
|
+
* `GRAPHDDB_CATALOG` (`src/spec/catalog.ts`) exactly: compact `PortSchema` constructors,
|
|
9
|
+
* an `entry()` helper, per-primitive `inputPorts`, an `output.shape`, and a
|
|
10
|
+
* `portableToIR` flag. The effect implementation (SQL execution + row→model assembly) is
|
|
11
|
+
* bound separately in the handler registry (WS3, C4 — catalog declares, registry binds).
|
|
12
|
+
*
|
|
13
|
+
* ## Catalog names (spec §1 / §11 item 1)
|
|
14
|
+
*
|
|
15
|
+
* `Select` / `Insert` / `Update` / `Delete` are the CRUD leaf components. `Fragment` is
|
|
16
|
+
* the dynamic WHERE/SET fragment-tree component (SKIP → fragment existence rules, §8);
|
|
17
|
+
* `Tx` is the multi-statement transaction envelope. As in graphddb, the transaction
|
|
18
|
+
* envelope (`Tx`) is `portableToIR: false` — a transaction is emitted as a Component
|
|
19
|
+
* whose body references the per-statement CRUD primitives; the atomic BEGIN/COMMIT
|
|
20
|
+
* envelope is the runtime's execution concern (WS3), never a portable-IR node.
|
|
21
|
+
*
|
|
22
|
+
* ## Port schema conventions
|
|
23
|
+
*
|
|
24
|
+
* A `CatalogEntry.inputPorts` names the STATIC ports of the emitted wiring. Two families
|
|
25
|
+
* are dynamic by construction and are validated by {@link assertComponentsInCatalog}
|
|
26
|
+
* against documented patterns instead of being statically enumerable:
|
|
27
|
+
*
|
|
28
|
+
* - **`where`/`set`/`values` records**: one port per model field, flattened one-port-
|
|
29
|
+
* per-field under a `<group>.<field>` key ({@link WRITE_PORT_FAMILIES}). These carry
|
|
30
|
+
* Expression IR (the field's value/condition), from the closed operator set only.
|
|
31
|
+
*
|
|
32
|
+
* The CRUD entries carry `additionalPorts: true` (bc#26) so bc's shared port check
|
|
33
|
+
* (`checkPortNames` / `buildComponentDefinition`) accepts the dynamic families; every
|
|
34
|
+
* DECLARED port keeps bc's required/type checks regardless of the opt-in. `Tx`'s single
|
|
35
|
+
* port is static, so it keeps bc's fail-closed default.
|
|
36
|
+
*/
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.WRITE_PORT_FAMILIES = exports.WRITE_CATALOG_NAMES = exports.CATALOG_NAMES = exports.LITEDBMODEL_CATALOG = void 0;
|
|
39
|
+
exports.catalogEntry = catalogEntry;
|
|
40
|
+
exports.assertComponentsInCatalog = assertComponentsInCatalog;
|
|
41
|
+
exports.deriveContractEffect = deriveContractEffect;
|
|
42
|
+
const behavior_contracts_1 = require("behavior-contracts");
|
|
43
|
+
// Compact schema constructors (the IR bundle is size-budgeted — graphddb convention).
|
|
44
|
+
const P = (type, required) => (required ? { type, required } : { type });
|
|
45
|
+
/**
|
|
46
|
+
* The shared read-port surface for `Select`: `table` always; the optional
|
|
47
|
+
* `where` (a fragment-tree reference — see `Fragment`), `order`, `limit`, `offset`,
|
|
48
|
+
* `group` wiring, and the always-emitted `select` projection.
|
|
49
|
+
*
|
|
50
|
+
* `where` is typed `fragment` (not `expr`): a Select's dynamic WHERE is a fragment tree
|
|
51
|
+
* (§8), NOT a single Expression — the SKIP existence rules live on the tree, outside the
|
|
52
|
+
* Expression IR vocabulary (bc `expression-ir.md` §4: SKIP is OUTSIDE Expression IR).
|
|
53
|
+
* `limit` / `offset` are `expr` (they may be an input-ref or a `coalesce` default, §8).
|
|
54
|
+
*/
|
|
55
|
+
const SELECT_PORTS = {
|
|
56
|
+
table: P('string', true),
|
|
57
|
+
select: P('string[]', true),
|
|
58
|
+
where: P('fragment'),
|
|
59
|
+
order: P('string'),
|
|
60
|
+
limit: P('expr'),
|
|
61
|
+
offset: P('expr'),
|
|
62
|
+
group: P('string'),
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* The shared write-port surface for `Insert`/`Update`/`Delete`: `table` always;
|
|
66
|
+
* `where` (fragment tree — required existence enforced by the compiler, not here, since a
|
|
67
|
+
* Select may legitimately omit it); `returning` projection; `onConflict` wiring for
|
|
68
|
+
* Insert. The per-field value/set ports (`values.<field>` / `set.<field>`) are dynamic
|
|
69
|
+
* ({@link WRITE_PORT_FAMILIES}) and each carries an Expression IR value.
|
|
70
|
+
*/
|
|
71
|
+
const WRITE_PORTS = {
|
|
72
|
+
table: P('string', true),
|
|
73
|
+
where: P('fragment'),
|
|
74
|
+
returning: P('string'),
|
|
75
|
+
onConflict: P('string'),
|
|
76
|
+
onConflictAction: P('string'),
|
|
77
|
+
};
|
|
78
|
+
const entry = (name, inputPorts, shape, portableToIR) => ({
|
|
79
|
+
name,
|
|
80
|
+
inputPorts,
|
|
81
|
+
output: { shape },
|
|
82
|
+
portableToIR,
|
|
83
|
+
// Dynamic port families (where/set/values record ports) are validated by
|
|
84
|
+
// assertComponentsInCatalog, not statically enumerable. Tx overrides back to
|
|
85
|
+
// fail-closed (its one port is static).
|
|
86
|
+
additionalPorts: true,
|
|
87
|
+
});
|
|
88
|
+
/**
|
|
89
|
+
* litedbmodel's specific-component catalog (spec §11 item 1) — the behavior-contracts
|
|
90
|
+
* `Catalog`-typed source of truth. Each entry declares the Port schema of one SQL
|
|
91
|
+
* primitive AS THE BACKEND COMPILE WIRES IT; the effect implementation is bound
|
|
92
|
+
* separately in the handler registry (WS3, C4). All entries except `Tx` may appear in
|
|
93
|
+
* the portable IR.
|
|
94
|
+
*/
|
|
95
|
+
exports.LITEDBMODEL_CATALOG = {
|
|
96
|
+
// Read: `items` (a Select root yields a row list; per-row collapse to `item` is the
|
|
97
|
+
// consumer's cardinality concern, mirrored from graphddb Query's `cardinality` port).
|
|
98
|
+
Select: entry('Select', { ...SELECT_PORTS, cardinality: P('string') }, 'items', true),
|
|
99
|
+
// Writes yield the RETURNING row list (`items`); a single-row write collapses at the
|
|
100
|
+
// consumer boundary, same as reads.
|
|
101
|
+
Insert: entry('Insert', WRITE_PORTS, 'items', true),
|
|
102
|
+
Update: entry('Update', WRITE_PORTS, 'items', true),
|
|
103
|
+
Delete: entry('Delete', WRITE_PORTS, 'items', true),
|
|
104
|
+
// The dynamic WHERE/SET fragment-tree component (§8). Its ports carry the fragment
|
|
105
|
+
// tree; the compiler resolves SKIP/AND-OR structure to fragment existence rules.
|
|
106
|
+
Fragment: entry('Fragment', { tree: P('fragment', true) }, 'item', true),
|
|
107
|
+
// The runtime-side atomic envelope: never referenced by the portable IR (a transaction
|
|
108
|
+
// IS a component over the CRUD primitives) — runtime-only. Its single port is static,
|
|
109
|
+
// so it keeps bc's fail-closed default (no additionalPorts opt-in).
|
|
110
|
+
Tx: {
|
|
111
|
+
...entry('Tx', { statements: P('map[]', true) }, 'item', false),
|
|
112
|
+
additionalPorts: false,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
/** Look up a catalog entry by name (undefined for an unknown primitive). */
|
|
116
|
+
function catalogEntry(name) {
|
|
117
|
+
return exports.LITEDBMODEL_CATALOG[name];
|
|
118
|
+
}
|
|
119
|
+
/** The catalog names litedbmodel declares (the C2 per-DSL surface). */
|
|
120
|
+
exports.CATALOG_NAMES = [
|
|
121
|
+
'Select',
|
|
122
|
+
'Insert',
|
|
123
|
+
'Update',
|
|
124
|
+
'Delete',
|
|
125
|
+
'Fragment',
|
|
126
|
+
'Tx',
|
|
127
|
+
];
|
|
128
|
+
/**
|
|
129
|
+
* The CQRS write catalog: the names whose presence in a component body makes the
|
|
130
|
+
* component a COMMAND (spec §2.4 — effect is derived from the graph, not authored).
|
|
131
|
+
* `Select`/`Fragment` are read-side; `Insert`/`Update`/`Delete`/`Tx` are write-side.
|
|
132
|
+
*/
|
|
133
|
+
exports.WRITE_CATALOG_NAMES = [
|
|
134
|
+
'Insert',
|
|
135
|
+
'Update',
|
|
136
|
+
'Delete',
|
|
137
|
+
'Tx',
|
|
138
|
+
];
|
|
139
|
+
const WRITE_SET = new Set(exports.WRITE_CATALOG_NAMES);
|
|
140
|
+
/**
|
|
141
|
+
* The dynamic per-field write-port families (`<group>.<field>` — the flattened record
|
|
142
|
+
* convention; longest-prefix wins). A `values.<field>` (Insert) or `set.<field>`
|
|
143
|
+
* (Update) port carries the field's Expression IR value.
|
|
144
|
+
*/
|
|
145
|
+
exports.WRITE_PORT_FAMILIES = [
|
|
146
|
+
'values.',
|
|
147
|
+
'set.',
|
|
148
|
+
];
|
|
149
|
+
/**
|
|
150
|
+
* The emitter's catalog validation (loud; a violation is a BUILD error), mirrored from
|
|
151
|
+
* graphddb's `assertComponentsInCatalog`. Every `componentRef` / `map` body node of every
|
|
152
|
+
* emitted component must:
|
|
153
|
+
*
|
|
154
|
+
* 1. reference a declared catalog name;
|
|
155
|
+
* 2. wire every `required` port of that entry;
|
|
156
|
+
* 3. wire ONLY declared ports — a port is declared if it is a static `inputPorts` name or
|
|
157
|
+
* a write record-family port ({@link WRITE_PORT_FAMILIES}, write entries only).
|
|
158
|
+
*
|
|
159
|
+
* All violations are collected and thrown as one error. `cond` nodes carry no component
|
|
160
|
+
* reference and are skipped.
|
|
161
|
+
*/
|
|
162
|
+
function assertComponentsInCatalog(components) {
|
|
163
|
+
const errs = [];
|
|
164
|
+
for (const c of components) {
|
|
165
|
+
for (const n of c.body) {
|
|
166
|
+
if ('cond' in n)
|
|
167
|
+
continue;
|
|
168
|
+
const ref = 'map' in n ? n.map : n;
|
|
169
|
+
const entryDef = exports.LITEDBMODEL_CATALOG[ref.component];
|
|
170
|
+
if (entryDef === undefined) {
|
|
171
|
+
errs.push(`${c.name}/${n.id}: references '${ref.component}', not a LITEDBMODEL_CATALOG entry (known: ${exports.CATALOG_NAMES.join(', ')})`);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const ports = ref.ports;
|
|
175
|
+
for (const [p, s] of Object.entries(entryDef.inputPorts)) {
|
|
176
|
+
if (s.required === true && !(p in ports)) {
|
|
177
|
+
errs.push(`${c.name}/${n.id} (${ref.component}): required port '${p}' is not wired`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const isWriteItem = WRITE_SET.has(ref.component);
|
|
181
|
+
for (const p of Object.keys(ports)) {
|
|
182
|
+
if (p in entryDef.inputPorts)
|
|
183
|
+
continue;
|
|
184
|
+
if (isWriteItem && exports.WRITE_PORT_FAMILIES.some((f) => p.startsWith(f)))
|
|
185
|
+
continue;
|
|
186
|
+
errs.push(`${c.name}/${n.id} (${ref.component}): port '${p}' is not declared by the catalog entry (nor a write record-family port)`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (errs.length > 0) {
|
|
191
|
+
throw new Error(`litedbmodel catalog validation failed (${errs.length} violation${errs.length === 1 ? '' : 's'}):\n - ${errs.join('\n - ')}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Derive one component's Query/Command classification FROM THE GRAPH: behavior-contracts'
|
|
196
|
+
* `classifyBehaviorEffect` over {@link WRITE_CATALOG_NAMES} — a component is a `'command'`
|
|
197
|
+
* iff its body references a write-catalog primitive, else a `'query'` (spec §2.4: effect
|
|
198
|
+
* is derived, never authored).
|
|
199
|
+
*/
|
|
200
|
+
function deriveContractEffect(component) {
|
|
201
|
+
return (0, behavior_contracts_1.classifyBehaviorEffect)(component, exports.WRITE_CATALOG_NAMES) === 'writing' ? 'command' : 'query';
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/scp/catalog.ts"],"names":[],"mappings":"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"}
|