@semiont/make-meaning 0.5.29 → 0.5.30
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 +23 -10
- package/dist/archivist-main.js +236 -131
- package/dist/archivist-main.js.map +1 -1
- package/dist/index.d.ts +19 -0
- package/dist/index.js +100 -4
- package/dist/index.js.map +1 -1
- package/dist/librarian-main.js +119 -50
- package/dist/librarian-main.js.map +1 -1
- package/dist/smelter-main.js +125 -25
- package/dist/smelter-main.js.map +1 -1
- package/dist/weaver-main.js +130 -28
- package/dist/weaver-main.js.map +1 -1
- package/package.json +12 -12
package/dist/index.d.ts
CHANGED
|
@@ -337,6 +337,25 @@ declare class Stower {
|
|
|
337
337
|
private handleYieldUpdate;
|
|
338
338
|
private handleYieldMv;
|
|
339
339
|
private handleMarkCreate;
|
|
340
|
+
/**
|
|
341
|
+
* Persist a detection unit's annotations as ONE acknowledged batch, then
|
|
342
|
+
* answer (JOB-RESTART-SAFETY P6).
|
|
343
|
+
*
|
|
344
|
+
* The difference from `mark:create` is the reply, and it is the whole point.
|
|
345
|
+
* `mark:create` is fire-and-forget: the worker's emit resolves when the bus
|
|
346
|
+
* accepts it, which says nothing about the event log, so a down Stower loses
|
|
347
|
+
* a unit silently and a flapping one hangs the worker forever. This answers
|
|
348
|
+
* only after every append has returned, so the worker can gate unit
|
|
349
|
+
* completion — and its checkpoint — on durability.
|
|
350
|
+
*
|
|
351
|
+
* Appends are sequential, not concurrent: the event log is the system of
|
|
352
|
+
* record and a batch that half-lands under concurrency is harder to reason
|
|
353
|
+
* about than one that stops at the first failure. A partial batch is
|
|
354
|
+
* reported as a failure and the worker retries the WHOLE unit, which is safe
|
|
355
|
+
* because ids are deterministic (P3) and the annotation fold is idempotent
|
|
356
|
+
* by id — re-appending what already landed changes nothing.
|
|
357
|
+
*/
|
|
358
|
+
private handleMarkCommit;
|
|
340
359
|
private handleMarkDelete;
|
|
341
360
|
private handleMarkUpdateBody;
|
|
342
361
|
private handleMarkArchive;
|
package/dist/index.js
CHANGED
|
@@ -11335,6 +11335,7 @@ var Stower = class {
|
|
|
11335
11335
|
pipe("yield:update", (e) => this.handleYieldUpdate(e)),
|
|
11336
11336
|
pipe("yield:mv", (e) => this.handleYieldMv(e)),
|
|
11337
11337
|
pipe("mark:create", (e) => this.handleMarkCreate(e)),
|
|
11338
|
+
pipe("mark:commit", (e) => this.handleMarkCommit(e)),
|
|
11338
11339
|
pipe("mark:delete", (e) => this.handleMarkDelete(e)),
|
|
11339
11340
|
pipe("mark:update-body", (e) => this.handleMarkUpdateBody(e)),
|
|
11340
11341
|
pipe("frame:add-entity-type", (e) => this.handleAddEntityType(e)),
|
|
@@ -11560,6 +11561,61 @@ var Stower = class {
|
|
|
11560
11561
|
});
|
|
11561
11562
|
}
|
|
11562
11563
|
}
|
|
11564
|
+
/**
|
|
11565
|
+
* Persist a detection unit's annotations as ONE acknowledged batch, then
|
|
11566
|
+
* answer (JOB-RESTART-SAFETY P6).
|
|
11567
|
+
*
|
|
11568
|
+
* The difference from `mark:create` is the reply, and it is the whole point.
|
|
11569
|
+
* `mark:create` is fire-and-forget: the worker's emit resolves when the bus
|
|
11570
|
+
* accepts it, which says nothing about the event log, so a down Stower loses
|
|
11571
|
+
* a unit silently and a flapping one hangs the worker forever. This answers
|
|
11572
|
+
* only after every append has returned, so the worker can gate unit
|
|
11573
|
+
* completion — and its checkpoint — on durability.
|
|
11574
|
+
*
|
|
11575
|
+
* Appends are sequential, not concurrent: the event log is the system of
|
|
11576
|
+
* record and a batch that half-lands under concurrency is harder to reason
|
|
11577
|
+
* about than one that stops at the first failure. A partial batch is
|
|
11578
|
+
* reported as a failure and the worker retries the WHOLE unit, which is safe
|
|
11579
|
+
* because ids are deterministic (P3) and the annotation fold is idempotent
|
|
11580
|
+
* by id — re-appending what already landed changes nothing.
|
|
11581
|
+
*/
|
|
11582
|
+
async handleMarkCommit(event) {
|
|
11583
|
+
if (!event._userId) {
|
|
11584
|
+
throw new Error("mark:commit missing _userId (gateway injection)");
|
|
11585
|
+
}
|
|
11586
|
+
const annotations = event.annotations ?? [];
|
|
11587
|
+
try {
|
|
11588
|
+
let persisted = 0;
|
|
11589
|
+
for (const annotation of annotations) {
|
|
11590
|
+
await this.stores.eventStore.appendEvent({
|
|
11591
|
+
type: "mark:added",
|
|
11592
|
+
resourceId: resourceId(event.resourceId),
|
|
11593
|
+
userId: userId(event._userId),
|
|
11594
|
+
version: 1,
|
|
11595
|
+
payload: { annotation }
|
|
11596
|
+
});
|
|
11597
|
+
persisted++;
|
|
11598
|
+
}
|
|
11599
|
+
this.logger.debug("Committed annotation batch", {
|
|
11600
|
+
correlationId: event.correlationId,
|
|
11601
|
+
resourceId: event.resourceId,
|
|
11602
|
+
persisted
|
|
11603
|
+
});
|
|
11604
|
+
this.eventBus.get("mark:commit-ok").next({
|
|
11605
|
+
correlationId: event.correlationId,
|
|
11606
|
+
response: { persisted, annotationIds: annotations.map((a) => String(a.id)) }
|
|
11607
|
+
});
|
|
11608
|
+
} catch (error) {
|
|
11609
|
+
this.logger.error("Failed to commit annotation batch", {
|
|
11610
|
+
correlationId: event.correlationId,
|
|
11611
|
+
error: errField(error)
|
|
11612
|
+
});
|
|
11613
|
+
this.eventBus.get("mark:commit-failed").next({
|
|
11614
|
+
correlationId: event.correlationId,
|
|
11615
|
+
message: error instanceof Error ? error.message : String(error)
|
|
11616
|
+
});
|
|
11617
|
+
}
|
|
11618
|
+
}
|
|
11563
11619
|
async handleMarkDelete(event) {
|
|
11564
11620
|
if (!event._userId) {
|
|
11565
11621
|
throw new Error("mark:delete missing _userId (gateway injection)");
|
|
@@ -13194,7 +13250,7 @@ function registerJobCommandHandlers(eventBus, jobQueue, state, parentLogger) {
|
|
|
13194
13250
|
});
|
|
13195
13251
|
eventBus.get("job:fail").subscribe(async (event) => {
|
|
13196
13252
|
try {
|
|
13197
|
-
const outcome = await jobQueue.failJob(jobId(event.jobId), event.error);
|
|
13253
|
+
const outcome = await jobQueue.failJob(jobId(event.jobId), event.error, event.completedUnits, event.failureClass);
|
|
13198
13254
|
if (outcome === "retried") {
|
|
13199
13255
|
logger.info("Job re-queued for retry", { jobId: event.jobId });
|
|
13200
13256
|
} else if (outcome === null) {
|
|
@@ -13220,16 +13276,45 @@ function registerJobCommandHandlers(eventBus, jobQueue, state, parentLogger) {
|
|
|
13220
13276
|
});
|
|
13221
13277
|
}
|
|
13222
13278
|
});
|
|
13279
|
+
eventBus.get("job:checkpoint").subscribe(async (event) => {
|
|
13280
|
+
try {
|
|
13281
|
+
await jobQueue.checkpointUnits(jobId(event.jobId), event.completedUnits);
|
|
13282
|
+
} catch (error) {
|
|
13283
|
+
logger.error("Failed to checkpoint job units", {
|
|
13284
|
+
jobId: event.jobId,
|
|
13285
|
+
error: error.message
|
|
13286
|
+
});
|
|
13287
|
+
}
|
|
13288
|
+
});
|
|
13223
13289
|
eventBus.get("job:cancel-requested").subscribe(async (event) => {
|
|
13224
13290
|
try {
|
|
13225
|
-
|
|
13226
|
-
|
|
13291
|
+
let cancelled;
|
|
13292
|
+
if (event.jobId) {
|
|
13293
|
+
const target = await jobQueue.getJob(jobId(event.jobId));
|
|
13294
|
+
if (!target) {
|
|
13295
|
+
cancelled = 0;
|
|
13296
|
+
} else if (target.status === "pending") {
|
|
13297
|
+
cancelled = await jobQueue.cancelJob(jobId(event.jobId)) ? 1 : 0;
|
|
13298
|
+
} else if (target.status === "running") {
|
|
13299
|
+
logger.info("Cancel of running job delegated to its worker", { jobId: event.jobId });
|
|
13300
|
+
cancelled = 1;
|
|
13301
|
+
} else {
|
|
13302
|
+
cancelled = 0;
|
|
13303
|
+
}
|
|
13304
|
+
logger.info("Cancel requested", { jobId: event.jobId, cancelled });
|
|
13305
|
+
} else if (event.jobType) {
|
|
13306
|
+
cancelled = await jobQueue.cancelPendingJobs(event.jobType);
|
|
13307
|
+
logger.info("Cancel requested", { jobType: event.jobType, cancelled });
|
|
13308
|
+
} else {
|
|
13309
|
+
cancelled = 0;
|
|
13310
|
+
}
|
|
13227
13311
|
eventBus.get("job:cancel-ok").next({
|
|
13228
13312
|
correlationId: event.correlationId,
|
|
13229
13313
|
response: { cancelled }
|
|
13230
13314
|
});
|
|
13231
13315
|
} catch (error) {
|
|
13232
|
-
logger.error("Failed to cancel
|
|
13316
|
+
logger.error("Failed to cancel jobs", {
|
|
13317
|
+
jobId: event.jobId,
|
|
13233
13318
|
jobType: event.jobType,
|
|
13234
13319
|
error: error.message
|
|
13235
13320
|
});
|
|
@@ -13239,6 +13324,17 @@ function registerJobCommandHandlers(eventBus, jobQueue, state, parentLogger) {
|
|
|
13239
13324
|
});
|
|
13240
13325
|
}
|
|
13241
13326
|
});
|
|
13327
|
+
eventBus.get("job:cancel").subscribe(async (event) => {
|
|
13328
|
+
try {
|
|
13329
|
+
await jobQueue.cancelJob(jobId(event.jobId));
|
|
13330
|
+
logger.info("Job cancelled by its worker", { jobId: event.jobId });
|
|
13331
|
+
} catch (error) {
|
|
13332
|
+
logger.error("Failed to cancel job", {
|
|
13333
|
+
jobId: event.jobId,
|
|
13334
|
+
error: error.message
|
|
13335
|
+
});
|
|
13336
|
+
}
|
|
13337
|
+
});
|
|
13242
13338
|
}
|
|
13243
13339
|
|
|
13244
13340
|
// src/handlers/index.ts
|