bonescript-compiler 0.5.3 → 0.5.4
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/LICENSE +21 -21
- package/dist/algorithm_catalog.js +166 -166
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +543 -75
- package/dist/cli.js.map +1 -1
- package/dist/emit_capability.d.ts +0 -13
- package/dist/emit_capability.js +134 -296
- package/dist/emit_capability.js.map +1 -1
- package/dist/emit_composition.js +3 -37
- package/dist/emit_composition.js.map +1 -1
- package/dist/emit_deploy.js +167 -165
- package/dist/emit_deploy.js.map +1 -1
- package/dist/emit_events.d.ts +0 -1
- package/dist/emit_events.js +275 -325
- package/dist/emit_events.js.map +1 -1
- package/dist/emit_extras.js +5 -3
- package/dist/emit_extras.js.map +1 -1
- package/dist/emit_full.js +112 -272
- package/dist/emit_full.js.map +1 -1
- package/dist/emit_maintenance.js +249 -249
- package/dist/emit_runtime.d.ts +11 -17
- package/dist/emit_runtime.js +688 -29
- package/dist/emit_runtime.js.map +1 -1
- package/dist/emit_sourcemap.js +66 -66
- package/dist/emit_tests.js +12 -47
- package/dist/emit_tests.js.map +1 -1
- package/dist/emit_websocket.js +3 -0
- package/dist/emit_websocket.js.map +1 -1
- package/dist/emitter.js +49 -94
- package/dist/emitter.js.map +1 -1
- package/dist/extension_manager.d.ts +2 -2
- package/dist/extension_manager.js +20 -9
- package/dist/extension_manager.js.map +1 -1
- package/dist/ir.d.ts +0 -4
- package/dist/lowering.d.ts +14 -5
- package/dist/lowering.js +417 -66
- package/dist/lowering.js.map +1 -1
- package/dist/module_loader.d.ts +2 -2
- package/dist/module_loader.js +23 -20
- package/dist/module_loader.js.map +1 -1
- package/dist/optimizer.js +3 -6
- package/dist/optimizer.js.map +1 -1
- package/dist/scaffold.d.ts +2 -2
- package/dist/scaffold.js +319 -315
- package/dist/scaffold.js.map +1 -1
- package/dist/solver.js +1 -1
- package/dist/solver.js.map +1 -1
- package/dist/source_map.js.map +1 -0
- package/dist/test.js.map +1 -0
- package/dist/test_typechecker.d.ts +5 -0
- package/dist/test_typechecker.js +126 -0
- package/dist/test_typechecker.js.map +1 -0
- package/dist/typechecker.d.ts +0 -7
- package/dist/typechecker.js +16 -103
- package/dist/typechecker.js.map +1 -1
- package/dist/verifier.d.ts +1 -5
- package/dist/verifier.js +38 -142
- package/dist/verifier.js.map +1 -1
- package/package.json +52 -62
- package/src/algorithm_catalog.ts +345 -345
- package/src/ast.d.ts +244 -0
- package/src/ast.ts +334 -334
- package/src/cli.ts +624 -98
- package/src/emit_batch.ts +140 -140
- package/src/emit_capability.ts +436 -613
- package/src/emit_composition.ts +196 -229
- package/src/emit_deploy.ts +190 -187
- package/src/emit_events.ts +307 -362
- package/src/emit_extras.ts +240 -237
- package/src/emit_full.ts +309 -472
- package/src/emit_maintenance.ts +459 -459
- package/src/emit_runtime.ts +730 -17
- package/src/emit_sourcemap.ts +140 -140
- package/src/emit_tests.ts +205 -243
- package/src/emit_websocket.ts +229 -226
- package/src/emitter.ts +578 -626
- package/src/extension_manager.ts +187 -177
- package/src/formatter.ts +297 -297
- package/src/index.ts +88 -88
- package/src/ir.ts +215 -216
- package/src/lexer.d.ts +195 -0
- package/src/lexer.ts +630 -630
- package/src/lowering.ts +556 -168
- package/src/module_loader.ts +114 -112
- package/src/optimizer.ts +196 -199
- package/src/parse_decls.d.ts +13 -0
- package/src/parse_decls.ts +409 -409
- package/src/parse_decls2.d.ts +13 -0
- package/src/parse_decls2.ts +244 -244
- package/src/parse_expr.d.ts +7 -0
- package/src/parse_expr.ts +197 -197
- package/src/parse_types.d.ts +6 -0
- package/src/parse_types.ts +54 -54
- package/src/parser.d.ts +10 -0
- package/src/parser.ts +1 -1
- package/src/parser_base.d.ts +19 -0
- package/src/parser_base.ts +57 -57
- package/src/parser_recovery.ts +153 -153
- package/src/scaffold.ts +375 -371
- package/src/solver.ts +330 -330
- package/src/typechecker.d.ts +52 -0
- package/src/typechecker.ts +591 -700
- package/src/types.d.ts +38 -0
- package/src/types.ts +122 -122
- package/src/verifier.ts +49 -154
- package/README.md +0 -382
- package/dist/commands/check.d.ts +0 -5
- package/dist/commands/check.js +0 -34
- package/dist/commands/check.js.map +0 -1
- package/dist/commands/compile.d.ts +0 -5
- package/dist/commands/compile.js +0 -215
- package/dist/commands/compile.js.map +0 -1
- package/dist/commands/debug.d.ts +0 -5
- package/dist/commands/debug.js +0 -59
- package/dist/commands/debug.js.map +0 -1
- package/dist/commands/diff.d.ts +0 -5
- package/dist/commands/diff.js +0 -123
- package/dist/commands/diff.js.map +0 -1
- package/dist/commands/fmt.d.ts +0 -5
- package/dist/commands/fmt.js +0 -49
- package/dist/commands/fmt.js.map +0 -1
- package/dist/commands/init.d.ts +0 -5
- package/dist/commands/init.js +0 -96
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/ir.d.ts +0 -5
- package/dist/commands/ir.js +0 -27
- package/dist/commands/ir.js.map +0 -1
- package/dist/commands/lex.d.ts +0 -5
- package/dist/commands/lex.js +0 -21
- package/dist/commands/lex.js.map +0 -1
- package/dist/commands/parse.d.ts +0 -5
- package/dist/commands/parse.js +0 -30
- package/dist/commands/parse.js.map +0 -1
- package/dist/commands/test.d.ts +0 -5
- package/dist/commands/test.js +0 -61
- package/dist/commands/test.js.map +0 -1
- package/dist/commands/verify_determinism.d.ts +0 -5
- package/dist/commands/verify_determinism.js +0 -64
- package/dist/commands/verify_determinism.js.map +0 -1
- package/dist/commands/watch.d.ts +0 -5
- package/dist/commands/watch.js +0 -50
- package/dist/commands/watch.js.map +0 -1
- package/dist/emit_auth.d.ts +0 -18
- package/dist/emit_auth.js +0 -507
- package/dist/emit_auth.js.map +0 -1
- package/dist/emit_database.d.ts +0 -7
- package/dist/emit_database.js +0 -72
- package/dist/emit_database.js.map +0 -1
- package/dist/emit_index.d.ts +0 -6
- package/dist/emit_index.js +0 -202
- package/dist/emit_index.js.map +0 -1
- package/dist/emit_models.d.ts +0 -12
- package/dist/emit_models.js +0 -171
- package/dist/emit_models.js.map +0 -1
- package/dist/emit_openapi.d.ts +0 -9
- package/dist/emit_openapi.js +0 -306
- package/dist/emit_openapi.js.map +0 -1
- package/dist/emit_package.d.ts +0 -7
- package/dist/emit_package.js +0 -68
- package/dist/emit_package.js.map +0 -1
- package/dist/emit_router.d.ts +0 -12
- package/dist/emit_router.js +0 -389
- package/dist/emit_router.js.map +0 -1
- package/dist/lowering_channels.d.ts +0 -11
- package/dist/lowering_channels.js +0 -103
- package/dist/lowering_channels.js.map +0 -1
- package/dist/lowering_entities.d.ts +0 -11
- package/dist/lowering_entities.js +0 -232
- package/dist/lowering_entities.js.map +0 -1
- package/dist/lowering_helpers.d.ts +0 -13
- package/dist/lowering_helpers.js +0 -76
- package/dist/lowering_helpers.js.map +0 -1
- package/src/commands/check.ts +0 -33
- package/src/commands/compile.ts +0 -191
- package/src/commands/debug.ts +0 -33
- package/src/commands/diff.ts +0 -105
- package/src/commands/fmt.ts +0 -22
- package/src/commands/init.ts +0 -72
- package/src/commands/ir.ts +0 -23
- package/src/commands/lex.ts +0 -17
- package/src/commands/parse.ts +0 -24
- package/src/commands/test.ts +0 -36
- package/src/commands/verify_determinism.ts +0 -66
- package/src/commands/watch.ts +0 -25
- package/src/emit_auth.ts +0 -513
- package/src/emit_database.ts +0 -72
- package/src/emit_index.ts +0 -210
- package/src/emit_models.ts +0 -176
- package/src/emit_openapi.ts +0 -315
- package/src/emit_package.ts +0 -66
- package/src/emit_router.ts +0 -408
- package/src/lowering_channels.ts +0 -108
- package/src/lowering_entities.ts +0 -258
- package/src/lowering_helpers.ts +0 -75
package/src/emit_batch.ts
CHANGED
|
@@ -1,140 +1,140 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BoneScript Batch Executor Emitter
|
|
3
|
-
* Generates a batch processing module for sync: batch capabilities.
|
|
4
|
-
* Batch capabilities are queued and processed in configurable intervals.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import * as IR from "./ir";
|
|
8
|
-
|
|
9
|
-
export function emitBatchExecutor(system: IR.IRSystem): string {
|
|
10
|
-
// Collect all batch capabilities
|
|
11
|
-
const batchMethods: { modName: string; method: IR.IRMethod }[] = [];
|
|
12
|
-
for (const mod of system.modules) {
|
|
13
|
-
for (const iface of mod.interfaces) {
|
|
14
|
-
for (const method of iface.methods) {
|
|
15
|
-
if (method.sync === "batch") {
|
|
16
|
-
batchMethods.push({ modName: mod.name, method });
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (batchMethods.length === 0) return "";
|
|
23
|
-
|
|
24
|
-
const lines: string[] = [];
|
|
25
|
-
lines.push(`// Generated by BoneScript compiler. DO NOT EDIT.`);
|
|
26
|
-
lines.push(`// Batch executor for sync: batch capabilities.`);
|
|
27
|
-
lines.push(`// Set BATCH_INTERVAL_MS to control flush frequency (default: 5000ms).`);
|
|
28
|
-
lines.push(``);
|
|
29
|
-
lines.push(`import { query } from "./db";`);
|
|
30
|
-
lines.push(`import { logger } from "./logger";`);
|
|
31
|
-
lines.push(`import { counter, histogram } from "./metrics";`);
|
|
32
|
-
lines.push(``);
|
|
33
|
-
|
|
34
|
-
// Batch queue type
|
|
35
|
-
lines.push(`interface BatchItem {`);
|
|
36
|
-
lines.push(` capability: string;`);
|
|
37
|
-
lines.push(` payload: Record<string, unknown>;`);
|
|
38
|
-
lines.push(` enqueuedAt: Date;`);
|
|
39
|
-
lines.push(` resolve: (result: any) => void;`);
|
|
40
|
-
lines.push(` reject: (err: Error) => void;`);
|
|
41
|
-
lines.push(`}`);
|
|
42
|
-
lines.push(``);
|
|
43
|
-
|
|
44
|
-
// Per-capability queues
|
|
45
|
-
lines.push(`const queues: Map<string, BatchItem[]> = new Map([`);
|
|
46
|
-
for (const { modName, method } of batchMethods) {
|
|
47
|
-
lines.push(` ["${modName}.${method.name}", []],`);
|
|
48
|
-
}
|
|
49
|
-
lines.push(`]);`);
|
|
50
|
-
lines.push(``);
|
|
51
|
-
|
|
52
|
-
// Enqueue function
|
|
53
|
-
lines.push(`export function enqueueBatch(capability: string, payload: Record<string, unknown>): Promise<any> {`);
|
|
54
|
-
lines.push(` return new Promise((resolve, reject) => {`);
|
|
55
|
-
lines.push(` const queue = queues.get(capability);`);
|
|
56
|
-
lines.push(` if (!queue) {`);
|
|
57
|
-
lines.push(` reject(new Error(\`Unknown batch capability: \${capability}\`));`);
|
|
58
|
-
lines.push(` return;`);
|
|
59
|
-
lines.push(` }`);
|
|
60
|
-
lines.push(` queue.push({ capability, payload, enqueuedAt: new Date(), resolve, reject });`);
|
|
61
|
-
lines.push(` counter("batch.enqueued", { capability });`);
|
|
62
|
-
lines.push(` });`);
|
|
63
|
-
lines.push(`}`);
|
|
64
|
-
lines.push(``);
|
|
65
|
-
|
|
66
|
-
// Flush function — processes all queued items
|
|
67
|
-
lines.push(`async function flushBatch(capability: string, items: BatchItem[]): Promise<void> {`);
|
|
68
|
-
lines.push(` if (items.length === 0) return;`);
|
|
69
|
-
lines.push(` const start = Date.now();`);
|
|
70
|
-
lines.push(` logger.info("batch_flush_started", { event: capability, metadata: { count: items.length } });`);
|
|
71
|
-
lines.push(``);
|
|
72
|
-
lines.push(` // Process items in a single DB transaction`);
|
|
73
|
-
lines.push(` const { pool } = require("./db");`);
|
|
74
|
-
lines.push(` const client = await pool.connect();`);
|
|
75
|
-
lines.push(` try {`);
|
|
76
|
-
lines.push(` await client.query("BEGIN");`);
|
|
77
|
-
lines.push(` for (const item of items) {`);
|
|
78
|
-
lines.push(` try {`);
|
|
79
|
-
lines.push(` // Execute the batch item`);
|
|
80
|
-
lines.push(` // Each capability's batch handler is registered below`);
|
|
81
|
-
lines.push(` const handler = batchHandlers.get(capability);`);
|
|
82
|
-
lines.push(` if (handler) {`);
|
|
83
|
-
lines.push(` const result = await handler(item.payload, client);`);
|
|
84
|
-
lines.push(` item.resolve(result);`);
|
|
85
|
-
lines.push(` } else {`);
|
|
86
|
-
lines.push(` item.reject(new Error(\`No batch handler for \${capability}\`));`);
|
|
87
|
-
lines.push(` }`);
|
|
88
|
-
lines.push(` } catch (e: any) {`);
|
|
89
|
-
lines.push(` item.reject(e);`);
|
|
90
|
-
lines.push(` }`);
|
|
91
|
-
lines.push(` }`);
|
|
92
|
-
lines.push(` await client.query("COMMIT");`);
|
|
93
|
-
lines.push(` histogram("batch.duration_ms", Date.now() - start, { capability });`);
|
|
94
|
-
lines.push(` counter("batch.processed", { capability, count: String(items.length) });`);
|
|
95
|
-
lines.push(` logger.info("batch_flush_completed", { event: capability, metadata: { count: items.length, duration_ms: Date.now() - start } });`);
|
|
96
|
-
lines.push(` } catch (e: any) {`);
|
|
97
|
-
lines.push(` await client.query("ROLLBACK");`);
|
|
98
|
-
lines.push(` for (const item of items) item.reject(e);`);
|
|
99
|
-
lines.push(` logger.error("batch_flush_failed", { event: capability, metadata: { error: e.message } });`);
|
|
100
|
-
lines.push(` } finally {`);
|
|
101
|
-
lines.push(` client.release();`);
|
|
102
|
-
lines.push(` }`);
|
|
103
|
-
lines.push(`}`);
|
|
104
|
-
lines.push(``);
|
|
105
|
-
|
|
106
|
-
// Batch handler registry
|
|
107
|
-
lines.push(`type BatchHandler = (payload: Record<string, unknown>, client: any) => Promise<any>;`);
|
|
108
|
-
lines.push(`const batchHandlers: Map<string, BatchHandler> = new Map();`);
|
|
109
|
-
lines.push(``);
|
|
110
|
-
lines.push(`export function registerBatchHandler(capability: string, handler: BatchHandler): void {`);
|
|
111
|
-
lines.push(` batchHandlers.set(capability, handler);`);
|
|
112
|
-
lines.push(`}`);
|
|
113
|
-
lines.push(``);
|
|
114
|
-
|
|
115
|
-
// Batch worker — flushes all queues on interval
|
|
116
|
-
lines.push(`export function startBatchWorker(intervalMs: number = parseInt(process.env.BATCH_INTERVAL_MS || "5000")): NodeJS.Timeout {`);
|
|
117
|
-
lines.push(` logger.info("batch_worker_started", { event: "startup", metadata: { interval_ms: intervalMs } });`);
|
|
118
|
-
lines.push(` return setInterval(async () => {`);
|
|
119
|
-
lines.push(` for (const [capability, queue] of queues) {`);
|
|
120
|
-
lines.push(` if (queue.length === 0) continue;`);
|
|
121
|
-
lines.push(` const batch = queue.splice(0, queue.length); // drain queue atomically`);
|
|
122
|
-
lines.push(` await flushBatch(capability, batch).catch(e => {`);
|
|
123
|
-
lines.push(` logger.error("batch_worker_error", { event: capability, metadata: { error: e.message } });`);
|
|
124
|
-
lines.push(` });`);
|
|
125
|
-
lines.push(` }`);
|
|
126
|
-
lines.push(` }, intervalMs);`);
|
|
127
|
-
lines.push(`}`);
|
|
128
|
-
lines.push(``);
|
|
129
|
-
|
|
130
|
-
// Capability-specific stub handlers
|
|
131
|
-
for (const { modName, method } of batchMethods) {
|
|
132
|
-
const key = `${modName}.${method.name}`;
|
|
133
|
-
lines.push(`// Batch handler for ${key}`);
|
|
134
|
-
lines.push(`// Register your implementation:`);
|
|
135
|
-
lines.push(`// registerBatchHandler("${key}", async (payload, client) => { ... });`);
|
|
136
|
-
lines.push(``);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return lines.join("\n");
|
|
140
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* BoneScript Batch Executor Emitter
|
|
3
|
+
* Generates a batch processing module for sync: batch capabilities.
|
|
4
|
+
* Batch capabilities are queued and processed in configurable intervals.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as IR from "./ir";
|
|
8
|
+
|
|
9
|
+
export function emitBatchExecutor(system: IR.IRSystem): string {
|
|
10
|
+
// Collect all batch capabilities
|
|
11
|
+
const batchMethods: { modName: string; method: IR.IRMethod }[] = [];
|
|
12
|
+
for (const mod of system.modules) {
|
|
13
|
+
for (const iface of mod.interfaces) {
|
|
14
|
+
for (const method of iface.methods) {
|
|
15
|
+
if (method.sync === "batch") {
|
|
16
|
+
batchMethods.push({ modName: mod.name, method });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (batchMethods.length === 0) return "";
|
|
23
|
+
|
|
24
|
+
const lines: string[] = [];
|
|
25
|
+
lines.push(`// Generated by BoneScript compiler. DO NOT EDIT.`);
|
|
26
|
+
lines.push(`// Batch executor for sync: batch capabilities.`);
|
|
27
|
+
lines.push(`// Set BATCH_INTERVAL_MS to control flush frequency (default: 5000ms).`);
|
|
28
|
+
lines.push(``);
|
|
29
|
+
lines.push(`import { query } from "./db";`);
|
|
30
|
+
lines.push(`import { logger } from "./logger";`);
|
|
31
|
+
lines.push(`import { counter, histogram } from "./metrics";`);
|
|
32
|
+
lines.push(``);
|
|
33
|
+
|
|
34
|
+
// Batch queue type
|
|
35
|
+
lines.push(`interface BatchItem {`);
|
|
36
|
+
lines.push(` capability: string;`);
|
|
37
|
+
lines.push(` payload: Record<string, unknown>;`);
|
|
38
|
+
lines.push(` enqueuedAt: Date;`);
|
|
39
|
+
lines.push(` resolve: (result: any) => void;`);
|
|
40
|
+
lines.push(` reject: (err: Error) => void;`);
|
|
41
|
+
lines.push(`}`);
|
|
42
|
+
lines.push(``);
|
|
43
|
+
|
|
44
|
+
// Per-capability queues
|
|
45
|
+
lines.push(`const queues: Map<string, BatchItem[]> = new Map([`);
|
|
46
|
+
for (const { modName, method } of batchMethods) {
|
|
47
|
+
lines.push(` ["${modName}.${method.name}", []],`);
|
|
48
|
+
}
|
|
49
|
+
lines.push(`]);`);
|
|
50
|
+
lines.push(``);
|
|
51
|
+
|
|
52
|
+
// Enqueue function
|
|
53
|
+
lines.push(`export function enqueueBatch(capability: string, payload: Record<string, unknown>): Promise<any> {`);
|
|
54
|
+
lines.push(` return new Promise((resolve, reject) => {`);
|
|
55
|
+
lines.push(` const queue = queues.get(capability);`);
|
|
56
|
+
lines.push(` if (!queue) {`);
|
|
57
|
+
lines.push(` reject(new Error(\`Unknown batch capability: \${capability}\`));`);
|
|
58
|
+
lines.push(` return;`);
|
|
59
|
+
lines.push(` }`);
|
|
60
|
+
lines.push(` queue.push({ capability, payload, enqueuedAt: new Date(), resolve, reject });`);
|
|
61
|
+
lines.push(` counter("batch.enqueued", { capability });`);
|
|
62
|
+
lines.push(` });`);
|
|
63
|
+
lines.push(`}`);
|
|
64
|
+
lines.push(``);
|
|
65
|
+
|
|
66
|
+
// Flush function — processes all queued items
|
|
67
|
+
lines.push(`async function flushBatch(capability: string, items: BatchItem[]): Promise<void> {`);
|
|
68
|
+
lines.push(` if (items.length === 0) return;`);
|
|
69
|
+
lines.push(` const start = Date.now();`);
|
|
70
|
+
lines.push(` logger.info("batch_flush_started", { event: capability, metadata: { count: items.length } });`);
|
|
71
|
+
lines.push(``);
|
|
72
|
+
lines.push(` // Process items in a single DB transaction`);
|
|
73
|
+
lines.push(` const { pool } = require("./db");`);
|
|
74
|
+
lines.push(` const client = await pool.connect();`);
|
|
75
|
+
lines.push(` try {`);
|
|
76
|
+
lines.push(` await client.query("BEGIN");`);
|
|
77
|
+
lines.push(` for (const item of items) {`);
|
|
78
|
+
lines.push(` try {`);
|
|
79
|
+
lines.push(` // Execute the batch item`);
|
|
80
|
+
lines.push(` // Each capability's batch handler is registered below`);
|
|
81
|
+
lines.push(` const handler = batchHandlers.get(capability);`);
|
|
82
|
+
lines.push(` if (handler) {`);
|
|
83
|
+
lines.push(` const result = await handler(item.payload, client);`);
|
|
84
|
+
lines.push(` item.resolve(result);`);
|
|
85
|
+
lines.push(` } else {`);
|
|
86
|
+
lines.push(` item.reject(new Error(\`No batch handler for \${capability}\`));`);
|
|
87
|
+
lines.push(` }`);
|
|
88
|
+
lines.push(` } catch (e: any) {`);
|
|
89
|
+
lines.push(` item.reject(e);`);
|
|
90
|
+
lines.push(` }`);
|
|
91
|
+
lines.push(` }`);
|
|
92
|
+
lines.push(` await client.query("COMMIT");`);
|
|
93
|
+
lines.push(` histogram("batch.duration_ms", Date.now() - start, { capability });`);
|
|
94
|
+
lines.push(` counter("batch.processed", { capability, count: String(items.length) });`);
|
|
95
|
+
lines.push(` logger.info("batch_flush_completed", { event: capability, metadata: { count: items.length, duration_ms: Date.now() - start } });`);
|
|
96
|
+
lines.push(` } catch (e: any) {`);
|
|
97
|
+
lines.push(` await client.query("ROLLBACK");`);
|
|
98
|
+
lines.push(` for (const item of items) item.reject(e);`);
|
|
99
|
+
lines.push(` logger.error("batch_flush_failed", { event: capability, metadata: { error: e.message } });`);
|
|
100
|
+
lines.push(` } finally {`);
|
|
101
|
+
lines.push(` client.release();`);
|
|
102
|
+
lines.push(` }`);
|
|
103
|
+
lines.push(`}`);
|
|
104
|
+
lines.push(``);
|
|
105
|
+
|
|
106
|
+
// Batch handler registry
|
|
107
|
+
lines.push(`type BatchHandler = (payload: Record<string, unknown>, client: any) => Promise<any>;`);
|
|
108
|
+
lines.push(`const batchHandlers: Map<string, BatchHandler> = new Map();`);
|
|
109
|
+
lines.push(``);
|
|
110
|
+
lines.push(`export function registerBatchHandler(capability: string, handler: BatchHandler): void {`);
|
|
111
|
+
lines.push(` batchHandlers.set(capability, handler);`);
|
|
112
|
+
lines.push(`}`);
|
|
113
|
+
lines.push(``);
|
|
114
|
+
|
|
115
|
+
// Batch worker — flushes all queues on interval
|
|
116
|
+
lines.push(`export function startBatchWorker(intervalMs: number = parseInt(process.env.BATCH_INTERVAL_MS || "5000")): NodeJS.Timeout {`);
|
|
117
|
+
lines.push(` logger.info("batch_worker_started", { event: "startup", metadata: { interval_ms: intervalMs } });`);
|
|
118
|
+
lines.push(` return setInterval(async () => {`);
|
|
119
|
+
lines.push(` for (const [capability, queue] of queues) {`);
|
|
120
|
+
lines.push(` if (queue.length === 0) continue;`);
|
|
121
|
+
lines.push(` const batch = queue.splice(0, queue.length); // drain queue atomically`);
|
|
122
|
+
lines.push(` await flushBatch(capability, batch).catch(e => {`);
|
|
123
|
+
lines.push(` logger.error("batch_worker_error", { event: capability, metadata: { error: e.message } });`);
|
|
124
|
+
lines.push(` });`);
|
|
125
|
+
lines.push(` }`);
|
|
126
|
+
lines.push(` }, intervalMs);`);
|
|
127
|
+
lines.push(`}`);
|
|
128
|
+
lines.push(``);
|
|
129
|
+
|
|
130
|
+
// Capability-specific stub handlers
|
|
131
|
+
for (const { modName, method } of batchMethods) {
|
|
132
|
+
const key = `${modName}.${method.name}`;
|
|
133
|
+
lines.push(`// Batch handler for ${key}`);
|
|
134
|
+
lines.push(`// Register your implementation:`);
|
|
135
|
+
lines.push(`// registerBatchHandler("${key}", async (payload, client) => { ... });`);
|
|
136
|
+
lines.push(``);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return lines.join("\n");
|
|
140
|
+
}
|