@quereus/quereus 0.13.1 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +18 -11
  2. package/dist/src/core/database-assertions.d.ts +54 -0
  3. package/dist/src/core/database-assertions.d.ts.map +1 -0
  4. package/dist/src/core/database-assertions.js +237 -0
  5. package/dist/src/core/database-assertions.js.map +1 -0
  6. package/dist/src/core/database-events.d.ts +219 -0
  7. package/dist/src/core/database-events.d.ts.map +1 -0
  8. package/dist/src/core/database-events.js +368 -0
  9. package/dist/src/core/database-events.js.map +1 -0
  10. package/dist/src/core/database-transaction.d.ts +126 -0
  11. package/dist/src/core/database-transaction.d.ts.map +1 -0
  12. package/dist/src/core/database-transaction.js +345 -0
  13. package/dist/src/core/database-transaction.js.map +1 -0
  14. package/dist/src/core/database.d.ts +100 -34
  15. package/dist/src/core/database.d.ts.map +1 -1
  16. package/dist/src/core/database.js +435 -475
  17. package/dist/src/core/database.js.map +1 -1
  18. package/dist/src/core/statement.d.ts +12 -2
  19. package/dist/src/core/statement.d.ts.map +1 -1
  20. package/dist/src/core/statement.js +94 -42
  21. package/dist/src/core/statement.js.map +1 -1
  22. package/dist/src/core/utils.d.ts +4 -0
  23. package/dist/src/core/utils.d.ts.map +1 -0
  24. package/dist/src/core/utils.js +9 -0
  25. package/dist/src/core/utils.js.map +1 -0
  26. package/dist/src/index.d.ts +2 -0
  27. package/dist/src/index.d.ts.map +1 -1
  28. package/dist/src/index.js +1 -0
  29. package/dist/src/index.js.map +1 -1
  30. package/dist/src/parser/parser.d.ts.map +1 -1
  31. package/dist/src/parser/parser.js +17 -0
  32. package/dist/src/parser/parser.js.map +1 -1
  33. package/dist/src/runtime/emit/create-assertion.d.ts.map +1 -1
  34. package/dist/src/runtime/emit/create-assertion.js +2 -0
  35. package/dist/src/runtime/emit/create-assertion.js.map +1 -1
  36. package/dist/src/runtime/emit/create-index.d.ts.map +1 -1
  37. package/dist/src/runtime/emit/create-index.js +2 -0
  38. package/dist/src/runtime/emit/create-index.js.map +1 -1
  39. package/dist/src/runtime/emit/create-table.d.ts.map +1 -1
  40. package/dist/src/runtime/emit/create-table.js +2 -0
  41. package/dist/src/runtime/emit/create-table.js.map +1 -1
  42. package/dist/src/runtime/emit/create-view.d.ts.map +1 -1
  43. package/dist/src/runtime/emit/create-view.js +2 -0
  44. package/dist/src/runtime/emit/create-view.js.map +1 -1
  45. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  46. package/dist/src/runtime/emit/dml-executor.js +47 -0
  47. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  48. package/dist/src/runtime/emit/drop-assertion.d.ts.map +1 -1
  49. package/dist/src/runtime/emit/drop-assertion.js +2 -0
  50. package/dist/src/runtime/emit/drop-assertion.js.map +1 -1
  51. package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
  52. package/dist/src/runtime/emit/drop-table.js +2 -0
  53. package/dist/src/runtime/emit/drop-table.js.map +1 -1
  54. package/dist/src/runtime/emit/drop-view.d.ts.map +1 -1
  55. package/dist/src/runtime/emit/drop-view.js +2 -0
  56. package/dist/src/runtime/emit/drop-view.js.map +1 -1
  57. package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -1
  58. package/dist/src/runtime/emit/schema-declarative.js +4 -3
  59. package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
  60. package/dist/src/runtime/emit/transaction.d.ts.map +1 -1
  61. package/dist/src/runtime/emit/transaction.js +16 -75
  62. package/dist/src/runtime/emit/transaction.js.map +1 -1
  63. package/dist/src/schema/manager.d.ts.map +1 -1
  64. package/dist/src/schema/manager.js +31 -0
  65. package/dist/src/schema/manager.js.map +1 -1
  66. package/dist/src/util/comparison.d.ts +5 -0
  67. package/dist/src/util/comparison.d.ts.map +1 -1
  68. package/dist/src/util/comparison.js +16 -0
  69. package/dist/src/util/comparison.js.map +1 -1
  70. package/dist/src/util/event-support.d.ts +15 -0
  71. package/dist/src/util/event-support.d.ts.map +1 -0
  72. package/dist/src/util/event-support.js +20 -0
  73. package/dist/src/util/event-support.js.map +1 -0
  74. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  75. package/dist/src/vtab/memory/layer/manager.js +5 -0
  76. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  77. package/package.json +16 -16
package/README.md CHANGED
@@ -84,32 +84,39 @@ for await (const row of db.eval("select * from users")) {
84
84
  ### Reactive Patterns with Event Hooks
85
85
 
86
86
  ```typescript
87
- import { Database, DefaultVTableEventEmitter, MemoryTableModule } from '@quereus/quereus';
87
+ import { Database } from '@quereus/quereus';
88
88
 
89
89
  const db = new Database();
90
- const emitter = new DefaultVTableEventEmitter();
91
90
 
92
- // Subscribe to changes
93
- emitter.onDataChange((event) => {
94
- console.log(`${event.type} on ${event.tableName}:`, event.key);
91
+ // Subscribe to data changes at the database level
92
+ db.onDataChange((event) => {
93
+ console.log(`${event.type} on ${event.tableName} (module: ${event.moduleName})`);
94
+ if (event.remote) {
95
+ console.log('Change came from remote sync');
96
+ }
95
97
  if (event.type === 'update') {
96
98
  console.log('Changed columns:', event.changedColumns);
97
99
  }
98
100
  });
99
101
 
100
- // Configure memory module with event emitter
101
- db.registerModule('memory_events', new MemoryTableModule(emitter));
102
- db.setDefaultModule('memory_events');
102
+ // Subscribe to schema changes
103
+ db.onSchemaChange((event) => {
104
+ console.log(`${event.type} ${event.objectType}: ${event.objectName}`);
105
+ });
103
106
 
104
107
  // Events fire after commit
105
108
  await db.exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
109
+ // Output: create table: users
110
+
106
111
  await db.exec("INSERT INTO users VALUES (1, 'Alice')");
107
- // Output: insert on users: [1]
112
+ // Output: insert on users (module: memory)
108
113
  ```
109
114
 
115
+ The database-level event system aggregates events from all modules automatically. Events are batched within transactions and delivered only after successful commit.
116
+
110
117
  SQL values use native JavaScript types (`string`, `number`, `bigint`, `Uint8Array`, `null`). Temporal types are ISO 8601 strings. Results stream as async iterators.
111
118
 
112
- See the [Usage Guide](docs/usage.md) for complete API reference and [VTable Event Hooks](docs/vtab-events.md) for reactive patterns.
119
+ See the [Usage Guide](docs/usage.md) for complete API reference and [Module Authoring Guide](docs/module-authoring.md) for event system details.
113
120
 
114
121
  ## Platform Support & Storage
115
122
 
@@ -205,7 +212,7 @@ See [Store Documentation](docs/store.md) for the storage architecture and custom
205
212
  * [Type System](docs/types.md): Logical/physical types, temporal types, JSON, custom types
206
213
  * [Functions](docs/functions.md): Built-in scalar, aggregate, window, and JSON functions
207
214
  * [Memory Tables](docs/memory-table.md): Built-in MemoryTable module
208
- * [VTable Event Hooks](docs/vtab-events.md): Mutation and schema change events for reactive patterns
215
+ * [Module Authoring](docs/module-authoring.md): Virtual table module development and event system
209
216
  * [Date/Time Handling](docs/datetime.md): Temporal parsing, functions, and ISO 8601 formats
210
217
  * [Runtime](docs/runtime.md): Instruction-based execution and opcodes
211
218
  * [Error Handling](docs/error.md): Error types and status codes
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Global assertion evaluation for deferred constraint checking.
3
+ *
4
+ * This module handles the evaluation of CREATE ASSERTION constraints at transaction
5
+ * commit time. It optimizes assertion checking by:
6
+ * - Only evaluating assertions impacted by changed tables
7
+ * - Using row-specific filtering when possible to avoid full table scans
8
+ * - Injecting PK filters for parameterized per-row evaluation
9
+ */
10
+ import { type SqlValue } from '../common/types.js';
11
+ import * as AST from '../parser/ast.js';
12
+ import { BlockNode } from '../planner/nodes/block.js';
13
+ import type { Database } from './database.js';
14
+ /**
15
+ * Interface for accessing Database internals needed by the assertion evaluator.
16
+ * This decouples the evaluator from the full Database class.
17
+ */
18
+ export interface AssertionEvaluatorContext {
19
+ readonly schemaManager: Database['schemaManager'];
20
+ readonly optimizer: Database['optimizer'];
21
+ readonly options: Database['options'];
22
+ _buildPlan(statements: AST.Statement[]): BlockNode;
23
+ _findTable(tableName: string, schemaName?: string): ReturnType<Database['_findTable']>;
24
+ prepare(sql: string): ReturnType<Database['prepare']>;
25
+ getInstructionTracer(): ReturnType<Database['getInstructionTracer']>;
26
+ /** Get the set of changed base tables (lowercase qualified names) */
27
+ getChangedBaseTables(): Set<string>;
28
+ /** Get changed PK tuples for a specific base table */
29
+ getChangedKeyTuples(base: string): SqlValue[][];
30
+ }
31
+ /**
32
+ * Evaluates global assertions (CREATE ASSERTION) at transaction commit time.
33
+ *
34
+ * Assertions are evaluated only when the tables they reference have been modified.
35
+ * The evaluator uses constraint analysis to determine whether assertions can be
36
+ * checked per-row (more efficient) or require a full violation query.
37
+ */
38
+ export declare class AssertionEvaluator {
39
+ private readonly ctx;
40
+ constructor(ctx: AssertionEvaluatorContext);
41
+ /**
42
+ * Run all global assertions that are impacted by changes in the current transaction.
43
+ * @throws QuereusError with CONSTRAINT status if any assertion is violated
44
+ */
45
+ runGlobalAssertions(): Promise<void>;
46
+ private evaluateAssertion;
47
+ private executeViolationOnce;
48
+ private executeViolationPerChangedKeys;
49
+ private injectPkFilter;
50
+ private rewriteForPkFilter;
51
+ private tryWrapTableReference;
52
+ private collectTables;
53
+ }
54
+ //# sourceMappingURL=database-assertions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-assertions.d.ts","sourceRoot":"","sources":["../../../src/core/database-assertions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG/D,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAIxC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAQtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACzC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAEtC,UAAU,CAAC,UAAU,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC;IACnD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACtD,oBAAoB,IAAI,UAAU,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAErE,qEAAqE;IACrE,oBAAoB,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,sDAAsD;IACtD,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,EAAE,CAAC;CAChD;AAED;;;;;;GAMG;AACH,qBAAa,kBAAkB;IAClB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,yBAAyB;IAE3D;;;OAGG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;YAY5B,iBAAiB;YAgFjB,oBAAoB;YAapB,8BAA8B;IAmD5C,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,qBAAqB;IAiD7B,OAAO,CAAC,aAAa;CAYrB"}
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Global assertion evaluation for deferred constraint checking.
3
+ *
4
+ * This module handles the evaluation of CREATE ASSERTION constraints at transaction
5
+ * commit time. It optimizes assertion checking by:
6
+ * - Only evaluating assertions impacted by changed tables
7
+ * - Using row-specific filtering when possible to avoid full table scans
8
+ * - Injecting PK filters for parameterized per-row evaluation
9
+ */
10
+ import { QuereusError } from '../common/errors.js';
11
+ import { StatusCode } from '../common/types.js';
12
+ import { Parser } from '../parser/parser.js';
13
+ import { emitPlanNode } from '../runtime/emitters.js';
14
+ import { Scheduler } from '../runtime/scheduler.js';
15
+ import { BlockNode } from '../planner/nodes/block.js';
16
+ import { FilterNode } from '../planner/nodes/filter.js';
17
+ import { BinaryOpNode } from '../planner/nodes/scalar.js';
18
+ import { ParameterReferenceNode, ColumnReferenceNode, TableReferenceNode } from '../planner/nodes/reference.js';
19
+ import { EmissionContext } from '../runtime/emission-context.js';
20
+ import { isAsyncIterable } from '../runtime/utils.js';
21
+ import { analyzeRowSpecific } from '../planner/analysis/constraint-extractor.js';
22
+ /**
23
+ * Evaluates global assertions (CREATE ASSERTION) at transaction commit time.
24
+ *
25
+ * Assertions are evaluated only when the tables they reference have been modified.
26
+ * The evaluator uses constraint analysis to determine whether assertions can be
27
+ * checked per-row (more efficient) or require a full violation query.
28
+ */
29
+ export class AssertionEvaluator {
30
+ ctx;
31
+ constructor(ctx) {
32
+ this.ctx = ctx;
33
+ }
34
+ /**
35
+ * Run all global assertions that are impacted by changes in the current transaction.
36
+ * @throws QuereusError with CONSTRAINT status if any assertion is violated
37
+ */
38
+ async runGlobalAssertions() {
39
+ const assertions = this.ctx.schemaManager.getAllAssertions();
40
+ if (assertions.length === 0)
41
+ return;
42
+ const changedBases = this.ctx.getChangedBaseTables();
43
+ if (changedBases.size === 0)
44
+ return;
45
+ for (const assertion of assertions) {
46
+ await this.evaluateAssertion(assertion, changedBases);
47
+ }
48
+ }
49
+ async evaluateAssertion(assertion, changedBases) {
50
+ const parser = new Parser();
51
+ let ast;
52
+ try {
53
+ ast = parser.parse(assertion.violationSql);
54
+ }
55
+ catch (err) {
56
+ const error = err instanceof Error ? err : new Error(String(err));
57
+ throw new QuereusError(`Failed to parse deferred assertion '${assertion.name}': ${error.message}`, StatusCode.INTERNAL, error);
58
+ }
59
+ const plan = this.ctx._buildPlan([ast]);
60
+ const analyzed = this.ctx.optimizer.optimizeForAnalysis(plan, this.ctx);
61
+ // Collect base tables and relationKeys in this plan
62
+ const relationKeyToBase = new Map();
63
+ const baseTablesInPlan = new Set();
64
+ this.collectTables(analyzed, relationKeyToBase, baseTablesInPlan);
65
+ // Determine impact: if assertion has no dependencies, treat as global and always impacted
66
+ const hasDeps = baseTablesInPlan.size > 0;
67
+ let impacted = !hasDeps;
68
+ if (hasDeps) {
69
+ for (const b of baseTablesInPlan) {
70
+ if (changedBases.has(b)) {
71
+ impacted = true;
72
+ break;
73
+ }
74
+ }
75
+ }
76
+ if (!impacted)
77
+ return;
78
+ // Classify instances as row/global
79
+ const classifications = analyzeRowSpecific(analyzed);
80
+ // If any changed base appears as a global instance, run full violation query once
81
+ let requiresGlobal = false;
82
+ for (const [relKey, klass] of classifications) {
83
+ if (klass === 'global') {
84
+ const base = relationKeyToBase.get(relKey);
85
+ if (base && changedBases.has(base)) {
86
+ requiresGlobal = true;
87
+ break;
88
+ }
89
+ }
90
+ }
91
+ if (requiresGlobal) {
92
+ await this.executeViolationOnce(assertion.name, assertion.violationSql);
93
+ return;
94
+ }
95
+ // Collect row-specific references that correspond to changed bases
96
+ const rowSpecificChanged = [];
97
+ for (const [relKey, klass] of classifications) {
98
+ if (klass !== 'row')
99
+ continue;
100
+ const base = relationKeyToBase.get(relKey);
101
+ if (base && changedBases.has(base)) {
102
+ rowSpecificChanged.push({ relKey, base });
103
+ }
104
+ }
105
+ if (rowSpecificChanged.length === 0) {
106
+ // No row-specific changed refs (or no refs at all) → run once globally
107
+ await this.executeViolationOnce(assertion.name, assertion.violationSql);
108
+ return;
109
+ }
110
+ // Execute parameterized variants per changed key for each row-specific reference
111
+ for (const { relKey, base } of rowSpecificChanged) {
112
+ await this.executeViolationPerChangedKeys(assertion.name, analyzed, relKey, base);
113
+ }
114
+ }
115
+ async executeViolationOnce(assertionName, sql) {
116
+ const stmt = this.ctx.prepare(sql);
117
+ try {
118
+ // Use _iterateRowsRaw() to avoid transaction management - we're already inside
119
+ // the commit path and don't want to trigger nested commit/rollback behavior
120
+ for await (const _ of stmt._iterateRowsRaw()) {
121
+ throw new QuereusError(`Integrity assertion failed: ${assertionName}`, StatusCode.CONSTRAINT);
122
+ }
123
+ }
124
+ finally {
125
+ await stmt.finalize();
126
+ }
127
+ }
128
+ async executeViolationPerChangedKeys(assertionName, analyzed, targetRelationKey, base) {
129
+ const changedKeyTuples = this.ctx.getChangedKeyTuples(base);
130
+ if (changedKeyTuples.length === 0)
131
+ return;
132
+ // Find PK indices for the base table
133
+ const [schemaName, tableName] = base.split('.');
134
+ const table = this.ctx._findTable(tableName, schemaName);
135
+ if (!table) {
136
+ throw new QuereusError(`Assertion references unknown table ${base}`, StatusCode.INTERNAL);
137
+ }
138
+ const pkIndices = table.primaryKeyDefinition.map(def => def.index);
139
+ // Prepare a rewritten plan with an injected Filter on the target relationKey
140
+ const rewritten = this.injectPkFilter(analyzed, targetRelationKey, pkIndices);
141
+ const optimizedPlan = this.ctx.optimizer.optimize(rewritten, this.ctx);
142
+ // Emit and execute for each changed PK tuple; stop on first violation row
143
+ const emissionContext = new EmissionContext(this.ctx);
144
+ const rootInstruction = emitPlanNode(optimizedPlan, emissionContext);
145
+ const scheduler = new Scheduler(rootInstruction);
146
+ for (const tuple of changedKeyTuples) {
147
+ const params = {};
148
+ for (let i = 0; i < pkIndices.length; i++) {
149
+ params[`pk${i}`] = tuple[i];
150
+ }
151
+ const runtimeCtx = {
152
+ db: this.ctx,
153
+ stmt: undefined,
154
+ params,
155
+ context: new Map(),
156
+ tableContexts: new Map(),
157
+ tracer: this.ctx.getInstructionTracer(),
158
+ enableMetrics: this.ctx.options.getBooleanOption('runtime_stats'),
159
+ };
160
+ const result = await scheduler.run(runtimeCtx);
161
+ if (isAsyncIterable(result)) {
162
+ for await (const _ of result) {
163
+ throw new QuereusError(`Integrity assertion failed: ${assertionName}`, StatusCode.CONSTRAINT);
164
+ }
165
+ }
166
+ }
167
+ }
168
+ injectPkFilter(block, targetRelationKey, pkIndices) {
169
+ const newStatements = block.getChildren().map(stmt => this.rewriteForPkFilter(stmt, targetRelationKey, pkIndices));
170
+ if (newStatements.every((s, i) => s === block.getChildren()[i]))
171
+ return block;
172
+ return new BlockNode(block.scope, newStatements, block.parameters);
173
+ }
174
+ rewriteForPkFilter(node, targetRelationKey, pkIndices) {
175
+ // If this node is the target TableReference instance, wrap with a Filter
176
+ const maybe = this.tryWrapTableReference(node, targetRelationKey, pkIndices);
177
+ if (maybe)
178
+ return maybe;
179
+ const originalChildren = node.getChildren();
180
+ if (!originalChildren || originalChildren.length === 0)
181
+ return node;
182
+ const rewrittenChildren = originalChildren.map(child => this.rewriteForPkFilter(child, targetRelationKey, pkIndices));
183
+ const changed = rewrittenChildren.some((c, i) => c !== originalChildren[i]);
184
+ return changed ? node.withChildren(rewrittenChildren) : node;
185
+ }
186
+ tryWrapTableReference(node, targetRelationKey, pkIndices) {
187
+ if (!(node instanceof TableReferenceNode))
188
+ return null;
189
+ const tableSchema = node.tableSchema;
190
+ const schemaName = tableSchema.schemaName;
191
+ const tableName = tableSchema.name;
192
+ const relName = `${schemaName}.${tableName}`.toLowerCase();
193
+ const relKey = `${relName}#${node.id ?? 'unknown'}`;
194
+ if (relKey !== targetRelationKey)
195
+ return null;
196
+ // Build predicate: AND(col_pk_i = :pk{i}) for all PK columns
197
+ const relational = node;
198
+ const scope = relational.scope;
199
+ const attributes = relational.getAttributes();
200
+ const makeColumnRef = (colIndex) => {
201
+ const attr = attributes[colIndex];
202
+ const expr = { type: 'column', name: attr.name, table: tableName, schema: schemaName };
203
+ return new ColumnReferenceNode(scope, expr, attr.type, attr.id, colIndex);
204
+ };
205
+ const makeParamRef = (i, type) => {
206
+ const pexpr = { type: 'parameter', name: `pk${i}` };
207
+ return new ParameterReferenceNode(scope, pexpr, `pk${i}`, type);
208
+ };
209
+ let predicate = null;
210
+ for (let i = 0; i < pkIndices.length; i++) {
211
+ const colIdx = pkIndices[i];
212
+ const left = makeColumnRef(colIdx);
213
+ const right = makeParamRef(i, attributes[colIdx].type);
214
+ const bexpr = { type: 'binary', operator: '=', left: left.expression, right: right.expression };
215
+ const eqNode = new BinaryOpNode(scope, bexpr, left, right);
216
+ predicate = predicate
217
+ ? new BinaryOpNode(scope, { type: 'binary', operator: 'AND', left: predicate.expression, right: eqNode.expression }, predicate, eqNode)
218
+ : eqNode;
219
+ }
220
+ if (!predicate)
221
+ return null;
222
+ return new FilterNode(scope, relational, predicate);
223
+ }
224
+ collectTables(node, relToBase, bases) {
225
+ for (const child of node.getChildren()) {
226
+ this.collectTables(child, relToBase, bases);
227
+ }
228
+ if (node instanceof TableReferenceNode) {
229
+ const schema = node.tableSchema;
230
+ const baseName = `${schema.schemaName}.${schema.name}`.toLowerCase();
231
+ bases.add(baseName);
232
+ const relKey = `${baseName}#${node.id ?? 'unknown'}`;
233
+ relToBase.set(relKey, baseName);
234
+ }
235
+ }
236
+ }
237
+ //# sourceMappingURL=database-assertions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-assertions.js","sourceRoot":"","sources":["../../../src/core/database-assertions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Database-level event system for unified reactivity.
3
+ *
4
+ * This module provides a centralized event aggregator that collects and broadcasts
5
+ * data and schema change events from all virtual table modules. Events are batched
6
+ * within transactions and emitted after successful commit.
7
+ *
8
+ * Modules that implement their own event emission (detected via getEventEmitter())
9
+ * will have their events forwarded to the database level. For modules without
10
+ * native event support, the engine automatically emits events for local operations.
11
+ */
12
+ import type { Row, SqlValue } from '../common/types.js';
13
+ import type { VTableDataChangeEvent, VTableSchemaChangeEvent, VTableEventEmitter } from '../vtab/events.js';
14
+ /**
15
+ * Data change event emitted at the database level.
16
+ * Extends VTableDataChangeEvent with module identification.
17
+ */
18
+ export interface DatabaseDataChangeEvent {
19
+ /** The type of mutation operation */
20
+ type: 'insert' | 'update' | 'delete';
21
+ /** The module that raised this event */
22
+ moduleName: string;
23
+ /** Schema name containing the table */
24
+ schemaName: string;
25
+ /** Table name */
26
+ tableName: string;
27
+ /** Primary key values */
28
+ key?: SqlValue[];
29
+ /** Previous row data (for update/delete) */
30
+ oldRow?: Row;
31
+ /** New row data (for insert/update) */
32
+ newRow?: Row;
33
+ /** Column names that changed (for updates) */
34
+ changedColumns?: string[];
35
+ /** True if event originated from sync/remote source, false for local changes */
36
+ remote: boolean;
37
+ }
38
+ /**
39
+ * Schema change event emitted at the database level.
40
+ * Extends VTableSchemaChangeEvent with module identification.
41
+ */
42
+ export interface DatabaseSchemaChangeEvent {
43
+ /** The type of schema operation */
44
+ type: 'create' | 'alter' | 'drop';
45
+ /** The type of object being modified */
46
+ objectType: 'table' | 'index' | 'column';
47
+ /** The module that raised this event */
48
+ moduleName: string;
49
+ /** Schema name */
50
+ schemaName: string;
51
+ /** Object name (table name for table/column, index name for index) */
52
+ objectName: string;
53
+ /** Column name (for column operations) */
54
+ columnName?: string;
55
+ /** Old column name (for column rename) */
56
+ oldColumnName?: string;
57
+ /** DDL statement if available */
58
+ ddl?: string;
59
+ /** True if event originated from sync/remote source, false for local changes */
60
+ remote: boolean;
61
+ }
62
+ export type DatabaseDataChangeListener = (event: DatabaseDataChangeEvent) => void;
63
+ export type DatabaseSchemaChangeListener = (event: DatabaseSchemaChangeEvent) => void;
64
+ /**
65
+ * Options for subscribing to data change events.
66
+ * Reserved fields for future filtering capabilities, plus pass-through for module-specific options.
67
+ */
68
+ export interface DataChangeSubscriptionOptions {
69
+ /** Module-specific options passed through to modules */
70
+ [key: string]: unknown;
71
+ }
72
+ /**
73
+ * Options for subscribing to schema change events.
74
+ */
75
+ export interface SchemaChangeSubscriptionOptions {
76
+ /** Module-specific options passed through to modules */
77
+ [key: string]: unknown;
78
+ }
79
+ /**
80
+ * Central event emitter for database-level reactivity.
81
+ *
82
+ * Aggregates events from all virtual table modules and broadcasts them to
83
+ * registered listeners. Handles transaction batching - events are collected
84
+ * during a transaction and emitted only after successful commit.
85
+ *
86
+ * Supports savepoint semantics: events within a savepoint are tracked separately
87
+ * and can be discarded on ROLLBACK TO SAVEPOINT or merged on RELEASE.
88
+ */
89
+ export declare class DatabaseEventEmitter {
90
+ private dataListeners;
91
+ private schemaListeners;
92
+ /** Batched events waiting for commit (base transaction level) */
93
+ private batchedDataEvents;
94
+ private batchedSchemaEvents;
95
+ /** Savepoint layers for event batching - each layer captures events since that savepoint */
96
+ private dataEventLayers;
97
+ private schemaEventLayers;
98
+ /** Whether we're currently in a transaction (batching mode) */
99
+ private isBatching;
100
+ /** Map of module emitters we've subscribed to, for cleanup */
101
+ private moduleSubscriptions;
102
+ /**
103
+ * Subscribe to data change events from all modules.
104
+ * @param listener Callback invoked for each data change event
105
+ * @param _options Reserved for future filtering options
106
+ * @returns Unsubscribe function
107
+ */
108
+ onDataChange(listener: DatabaseDataChangeListener, _options?: DataChangeSubscriptionOptions): () => void;
109
+ /**
110
+ * Subscribe to schema change events from all modules.
111
+ * @param listener Callback invoked for each schema change event
112
+ * @param _options Reserved for future filtering options
113
+ * @returns Unsubscribe function
114
+ */
115
+ onSchemaChange(listener: DatabaseSchemaChangeListener, _options?: SchemaChangeSubscriptionOptions): () => void;
116
+ /**
117
+ * Check if there are any data change listeners registered.
118
+ */
119
+ hasDataListeners(): boolean;
120
+ /**
121
+ * Check if there are any schema change listeners registered.
122
+ */
123
+ hasSchemaListeners(): boolean;
124
+ /**
125
+ * Hook a module's event emitter to forward events to the database level.
126
+ * Called when a module with native event support is detected.
127
+ *
128
+ * @param moduleName The name of the module
129
+ * @param emitter The module's event emitter
130
+ */
131
+ hookModuleEmitter(moduleName: string, emitter: VTableEventEmitter): void;
132
+ /**
133
+ * Unhook a module's event emitter.
134
+ * Called when a module is unregistered.
135
+ *
136
+ * @param moduleName The name of the module
137
+ */
138
+ unhookModuleEmitter(moduleName: string): void;
139
+ /**
140
+ * Get the active data event store (top layer or base).
141
+ */
142
+ private getActiveDataStore;
143
+ /**
144
+ * Get the active schema event store (top layer or base).
145
+ */
146
+ private getActiveSchemaStore;
147
+ /**
148
+ * Handle a data change event from a module.
149
+ * If batching, queue the event; otherwise emit immediately.
150
+ */
151
+ private handleModuleDataEvent;
152
+ /**
153
+ * Handle a schema change event from a module.
154
+ * Schema events are typically not batched (DDL is usually auto-committed),
155
+ * but we support batching for consistency.
156
+ */
157
+ private handleModuleSchemaEvent;
158
+ /**
159
+ * Emit a data change event for a module that doesn't have native event support.
160
+ * Called by the engine after successful DML operations.
161
+ *
162
+ * @param moduleName The module name
163
+ * @param event The event to emit (will be converted to DatabaseDataChangeEvent)
164
+ */
165
+ emitAutoDataEvent(moduleName: string, event: VTableDataChangeEvent): void;
166
+ /**
167
+ * Emit a schema change event for a module that doesn't have native event support.
168
+ * Called by the engine after successful DDL operations.
169
+ *
170
+ * @param moduleName The module name
171
+ * @param event The event to emit
172
+ */
173
+ emitAutoSchemaEvent(moduleName: string, event: VTableSchemaChangeEvent): void;
174
+ /**
175
+ * Emit a data event to all listeners.
176
+ */
177
+ private emitDataEvent;
178
+ /**
179
+ * Emit a schema event to all listeners.
180
+ */
181
+ private emitSchemaEvent;
182
+ /**
183
+ * Start batching events (called at transaction begin).
184
+ */
185
+ startBatch(): void;
186
+ /**
187
+ * Flush all batched events to listeners (called after successful commit).
188
+ * Collects events from all layers (base + savepoint layers) and emits them.
189
+ */
190
+ flushBatch(): void;
191
+ /**
192
+ * Discard all batched events (called on rollback).
193
+ */
194
+ discardBatch(): void;
195
+ /**
196
+ * Begin a new savepoint layer for event batching.
197
+ * Events after this point will be captured in the new layer.
198
+ */
199
+ beginSavepointLayer(): void;
200
+ /**
201
+ * Rollback the current savepoint layer, discarding its events.
202
+ * Called on ROLLBACK TO SAVEPOINT.
203
+ */
204
+ rollbackSavepointLayer(): void;
205
+ /**
206
+ * Release the current savepoint layer, merging its events into the parent layer.
207
+ * Called on RELEASE SAVEPOINT.
208
+ */
209
+ releaseSavepointLayer(): void;
210
+ /**
211
+ * Remove all listeners and unhook all modules.
212
+ */
213
+ removeAllListeners(): void;
214
+ /**
215
+ * Check if currently batching events.
216
+ */
217
+ isBatchingEvents(): boolean;
218
+ }
219
+ //# sourceMappingURL=database-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-events.d.ts","sourceRoot":"","sources":["../../../src/core/database-events.ts"],"names":[],"mappings":"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"}