@semiont/make-meaning 0.5.29 → 0.5.31
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 +241 -150
- package/dist/archivist-main.js.map +1 -1
- package/dist/index.d.ts +26 -38
- package/dist/index.js +124 -76
- package/dist/index.js.map +1 -1
- package/dist/librarian-main.js +118 -50
- package/dist/librarian-main.js.map +1 -1
- package/dist/smelter-main.js +151 -42
- package/dist/smelter-main.js.map +1 -1
- package/dist/weaver-main.js +162 -51
- package/dist/weaver-main.js.map +1 -1
- package/package.json +13 -13
package/dist/weaver-main.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import { createTomlConfigLoader, accessToken, baseUrl as baseUrl$1, retryWithBackoff, isTransientFetchError, STARTUP_FETCH_RETRY, errField, burstBuffer, busRequest, resourceId, didToAgent, annotationId, findBodyItem } from '@semiont/core';
|
|
1
|
+
import { replyChannelsFor, createTomlConfigLoader, accessToken, baseUrl as baseUrl$1, retryWithBackoff, isTransientFetchError, STARTUP_FETCH_RETRY, errField, burstBuffer, busRequest, resourceId, didToAgent, annotationId, findBodyItem } from '@semiont/core';
|
|
2
|
+
import { getGraphDatabase, intendedGraphAnnotation } from '@semiont/graph';
|
|
2
3
|
import { existsSync, readFileSync, promises } from 'fs';
|
|
3
4
|
import * as path from 'path';
|
|
4
5
|
import { join } from 'path';
|
|
6
|
+
import '@semiont/observability';
|
|
7
|
+
import '@semiont/ontology';
|
|
8
|
+
import '@semiont/content';
|
|
9
|
+
import '@semiont/vectors';
|
|
10
|
+
import '@semiont/event-sourcing';
|
|
5
11
|
import { HttpTransport } from '@semiont/http-transport';
|
|
6
|
-
import { getGraphDatabase } from '@semiont/graph';
|
|
7
12
|
import { createServer } from 'http';
|
|
8
13
|
import { homedir } from 'os';
|
|
9
14
|
import { createProcessLogger } from '@semiont/observability/process-logger';
|
|
@@ -9910,18 +9915,18 @@ var Weaver = class _Weaver {
|
|
|
9910
9915
|
set.add(seq);
|
|
9911
9916
|
}
|
|
9912
9917
|
}
|
|
9913
|
-
noteApplied(
|
|
9914
|
-
const failed = this.failedSeqs.get(
|
|
9918
|
+
noteApplied(resourceId6, sequenceNumber) {
|
|
9919
|
+
const failed = this.failedSeqs.get(resourceId6);
|
|
9915
9920
|
let capped = sequenceNumber;
|
|
9916
9921
|
if (failed && failed.size > 0) {
|
|
9917
9922
|
capped = Math.min(capped, Math.min(...failed) - 1);
|
|
9918
9923
|
}
|
|
9919
|
-
const current = this.lastProcessed.get(
|
|
9924
|
+
const current = this.lastProcessed.get(resourceId6);
|
|
9920
9925
|
if (current !== void 0 && current >= capped) return;
|
|
9921
|
-
this.lastProcessed.set(
|
|
9926
|
+
this.lastProcessed.set(resourceId6, capped);
|
|
9922
9927
|
this.checkpointDirty = true;
|
|
9923
|
-
this.bus.emit("weave:applied", { resourceId, sequenceNumber: capped }).catch((err) => {
|
|
9924
|
-
this.logger.warn("weave:applied emit failed", { resourceId, sequenceNumber: capped, error: errField(err) });
|
|
9928
|
+
this.bus.emit("weave:applied", { resourceId: resourceId6, sequenceNumber: capped }).catch((err) => {
|
|
9929
|
+
this.logger.warn("weave:applied emit failed", { resourceId: resourceId6, sequenceNumber: capped, error: errField(err) });
|
|
9925
9930
|
});
|
|
9926
9931
|
}
|
|
9927
9932
|
async flushCheckpoint() {
|
|
@@ -9967,8 +9972,8 @@ var Weaver = class _Weaver {
|
|
|
9967
9972
|
return resources;
|
|
9968
9973
|
}
|
|
9969
9974
|
/** A resource's full event history over the bus, sorted by sequence. */
|
|
9970
|
-
async fetchResourceEvents(
|
|
9971
|
-
const reply = await busRequest(this.bus, "browse:events-requested", { resourceId });
|
|
9975
|
+
async fetchResourceEvents(resourceId6) {
|
|
9976
|
+
const reply = await busRequest(this.bus, "browse:events-requested", { resourceId: resourceId6 });
|
|
9972
9977
|
return [...reply.events].sort((a, b) => a.metadata.sequenceNumber - b.metadata.sequenceNumber);
|
|
9973
9978
|
}
|
|
9974
9979
|
async catchUp() {
|
|
@@ -10076,6 +10081,7 @@ var Weaver = class _Weaver {
|
|
|
10076
10081
|
let divergent = 0;
|
|
10077
10082
|
let healed = 0;
|
|
10078
10083
|
let healFailures = 0;
|
|
10084
|
+
let orphaned = 0;
|
|
10079
10085
|
for (const resource of resources) {
|
|
10080
10086
|
const rid = resource["@id"];
|
|
10081
10087
|
if (!rid) continue;
|
|
@@ -10084,11 +10090,17 @@ var Weaver = class _Weaver {
|
|
|
10084
10090
|
divergent++;
|
|
10085
10091
|
this.logger.warn("Reconcile divergence \u2014 healing from the log", { resourceId: String(rid), reason });
|
|
10086
10092
|
const result = await this.rebuildResource(resourceId(String(rid)));
|
|
10087
|
-
if (result.
|
|
10093
|
+
if (result.eventCount === 0) {
|
|
10094
|
+
orphaned++;
|
|
10095
|
+
this.logger.warn(
|
|
10096
|
+
"Reconcile found an orphaned view \u2014 the log has no events for this resource, so healing wrote nothing",
|
|
10097
|
+
{ resourceId: String(rid), reason, remedy: "semiont stop && semiont clean --store state && semiont start" }
|
|
10098
|
+
);
|
|
10099
|
+
} else if (result.eventsFailed === 0) healed++;
|
|
10088
10100
|
else healFailures++;
|
|
10089
10101
|
}
|
|
10090
|
-
const summary = { resourcesChecked: resources.length, divergent, healed, healFailures };
|
|
10091
|
-
if (divergent > 0 || healFailures > 0) {
|
|
10102
|
+
const summary = { resourcesChecked: resources.length, divergent, healed, healFailures, orphaned };
|
|
10103
|
+
if (divergent > 0 || healFailures > 0 || orphaned > 0) {
|
|
10092
10104
|
this.logger.warn("Weaver reconcile found divergence", summary);
|
|
10093
10105
|
} else {
|
|
10094
10106
|
this.logger.info("Weaver reconcile complete \u2014 projection matches the catalog", summary);
|
|
@@ -10130,13 +10142,13 @@ var Weaver = class _Weaver {
|
|
|
10130
10142
|
for (const id of viewIds) {
|
|
10131
10143
|
if (!graphIds.has(id)) return "annotation-set-mismatch";
|
|
10132
10144
|
}
|
|
10133
|
-
const bodyKey = (a) => _Weaver.canonicalJson(a.body ?? []);
|
|
10134
10145
|
const viewById = new Map(annotations.map((a) => [String(a.id), a]));
|
|
10135
10146
|
for (const graphAnnotation of graphAnnotations) {
|
|
10136
10147
|
const viewAnnotation = viewById.get(String(graphAnnotation.id));
|
|
10137
10148
|
if (!viewAnnotation) continue;
|
|
10138
|
-
|
|
10139
|
-
|
|
10149
|
+
const intended = intendedGraphAnnotation({ ...viewAnnotation, creator: graphAnnotation.creator });
|
|
10150
|
+
if (_Weaver.canonicalJson(graphAnnotation) !== _Weaver.canonicalJson(intended)) {
|
|
10151
|
+
return "annotation-content-mismatch";
|
|
10140
10152
|
}
|
|
10141
10153
|
}
|
|
10142
10154
|
return null;
|
|
@@ -10466,30 +10478,30 @@ var Weaver = class _Weaver {
|
|
|
10466
10478
|
* Rebuild entire resource from events.
|
|
10467
10479
|
* Bypasses the live pipeline — reads directly from event store.
|
|
10468
10480
|
*/
|
|
10469
|
-
async rebuildResource(
|
|
10481
|
+
async rebuildResource(resourceId6) {
|
|
10470
10482
|
const graphDb = this.ensureInitialized();
|
|
10471
|
-
this.logger.info("Rebuilding resource from events", { resourceId });
|
|
10483
|
+
this.logger.info("Rebuilding resource from events", { resourceId: resourceId6 });
|
|
10472
10484
|
try {
|
|
10473
|
-
await graphDb.deleteResource(
|
|
10485
|
+
await graphDb.deleteResource(resourceId6);
|
|
10474
10486
|
} catch (error) {
|
|
10475
|
-
this.logger.debug("No existing resource to delete", { resourceId });
|
|
10487
|
+
this.logger.debug("No existing resource to delete", { resourceId: resourceId6 });
|
|
10476
10488
|
}
|
|
10477
|
-
const events = await this.fetchResourceEvents(String(
|
|
10489
|
+
const events = await this.fetchResourceEvents(String(resourceId6));
|
|
10478
10490
|
let eventsFailed = 0;
|
|
10479
10491
|
for (const storedEvent of events) {
|
|
10480
10492
|
if (!await this.safeApplyEvent(storedEvent)) eventsFailed++;
|
|
10481
10493
|
}
|
|
10482
10494
|
if (events.length > 0 && eventsFailed === 0) {
|
|
10483
|
-
this.noteApplied(String(
|
|
10495
|
+
this.noteApplied(String(resourceId6), Math.max(...events.map((e) => e.metadata.sequenceNumber)));
|
|
10484
10496
|
}
|
|
10485
10497
|
if (eventsFailed > 0) {
|
|
10486
10498
|
this.logger.error("Resource rebuild dropped events \u2014 graph incomplete for this resource", {
|
|
10487
|
-
resourceId,
|
|
10499
|
+
resourceId: resourceId6,
|
|
10488
10500
|
eventsFailed
|
|
10489
10501
|
});
|
|
10490
10502
|
}
|
|
10491
|
-
this.logger.info("Resource rebuild complete", { resourceId, eventCount: events.length, eventsFailed });
|
|
10492
|
-
return { eventsApplied: events.length - eventsFailed, eventsFailed };
|
|
10503
|
+
this.logger.info("Resource rebuild complete", { resourceId: resourceId6, eventCount: events.length, eventsFailed });
|
|
10504
|
+
return { eventCount: events.length, eventsApplied: events.length - eventsFailed, eventsFailed };
|
|
10493
10505
|
}
|
|
10494
10506
|
/**
|
|
10495
10507
|
* Rebuild entire GraphDB from all events.
|
|
@@ -10510,15 +10522,15 @@ var Weaver = class _Weaver {
|
|
|
10510
10522
|
this.logger.info("Found resources to rebuild", { count: allResourceIds.length });
|
|
10511
10523
|
const ledger = /* @__PURE__ */ new Map();
|
|
10512
10524
|
this.logger.info("PASS 1: Creating all nodes (resources + annotations)");
|
|
10513
|
-
for (const
|
|
10514
|
-
const events = await this.fetchResourceEvents(String(
|
|
10525
|
+
for (const resourceId6 of allResourceIds) {
|
|
10526
|
+
const events = await this.fetchResourceEvents(String(resourceId6));
|
|
10515
10527
|
if (events.length === 0) continue;
|
|
10516
10528
|
const entry = {
|
|
10517
10529
|
maxSeq: Math.max(...events.map((e) => e.metadata.sequenceNumber)),
|
|
10518
10530
|
attempted: 0,
|
|
10519
10531
|
failed: 0
|
|
10520
10532
|
};
|
|
10521
|
-
ledger.set(String(
|
|
10533
|
+
ledger.set(String(resourceId6), entry);
|
|
10522
10534
|
for (const storedEvent of events) {
|
|
10523
10535
|
if (storedEvent.type === "mark:body-updated") {
|
|
10524
10536
|
continue;
|
|
@@ -10529,11 +10541,11 @@ var Weaver = class _Weaver {
|
|
|
10529
10541
|
}
|
|
10530
10542
|
this.logger.info("Pass 1 complete - all nodes created");
|
|
10531
10543
|
this.logger.info("PASS 2: Creating all REFERENCES edges");
|
|
10532
|
-
for (const
|
|
10533
|
-
const events = await this.fetchResourceEvents(String(
|
|
10544
|
+
for (const resourceId6 of allResourceIds) {
|
|
10545
|
+
const events = await this.fetchResourceEvents(String(resourceId6));
|
|
10534
10546
|
for (const storedEvent of events) {
|
|
10535
10547
|
if (storedEvent.type === "mark:body-updated") {
|
|
10536
|
-
const entry = ledger.get(String(
|
|
10548
|
+
const entry = ledger.get(String(resourceId6));
|
|
10537
10549
|
if (entry) entry.attempted++;
|
|
10538
10550
|
if (!await this.safeApplyEvent(storedEvent)) {
|
|
10539
10551
|
if (entry) entry.failed++;
|
|
@@ -10561,8 +10573,8 @@ var Weaver = class _Weaver {
|
|
|
10561
10573
|
* Get consumer health metrics.
|
|
10562
10574
|
*/
|
|
10563
10575
|
/** Highest applied sequence for a resource, if any — diagnostics/tests. */
|
|
10564
|
-
appliedUpTo(
|
|
10565
|
-
return this.lastProcessed.get(
|
|
10576
|
+
appliedUpTo(resourceId6) {
|
|
10577
|
+
return this.lastProcessed.get(resourceId6);
|
|
10566
10578
|
}
|
|
10567
10579
|
getHealthMetrics() {
|
|
10568
10580
|
return {
|
|
@@ -10614,6 +10626,110 @@ var FileWeaverCheckpoint = class {
|
|
|
10614
10626
|
await promises.rename(tmp, this.filePath);
|
|
10615
10627
|
}
|
|
10616
10628
|
};
|
|
10629
|
+
var MATCHER_CHANNELS = [
|
|
10630
|
+
"match:search-requested"
|
|
10631
|
+
];
|
|
10632
|
+
|
|
10633
|
+
// src/gatherer.ts
|
|
10634
|
+
var GATHERER_CHANNELS = [
|
|
10635
|
+
"gather:requested",
|
|
10636
|
+
"gather:resource-requested"
|
|
10637
|
+
];
|
|
10638
|
+
var STOWER_CHANNELS = [
|
|
10639
|
+
"yield:create",
|
|
10640
|
+
"yield:clone-persist",
|
|
10641
|
+
"yield:update",
|
|
10642
|
+
"yield:mv",
|
|
10643
|
+
"mark:create",
|
|
10644
|
+
"mark:commit",
|
|
10645
|
+
"mark:delete",
|
|
10646
|
+
"mark:update-body",
|
|
10647
|
+
"frame:add-entity-type",
|
|
10648
|
+
"frame:add-tag-schema",
|
|
10649
|
+
"mark:archive",
|
|
10650
|
+
"mark:unarchive",
|
|
10651
|
+
"mark:update-entity-types",
|
|
10652
|
+
"job:start",
|
|
10653
|
+
"job:complete",
|
|
10654
|
+
"job:fail"
|
|
10655
|
+
];
|
|
10656
|
+
|
|
10657
|
+
// src/browser.ts
|
|
10658
|
+
var BROWSER_CHANNELS = [
|
|
10659
|
+
"browse:resource-requested",
|
|
10660
|
+
"browse:anchored-text-requested",
|
|
10661
|
+
"browse:resources-requested",
|
|
10662
|
+
"browse:annotations-requested",
|
|
10663
|
+
"browse:annotation-requested",
|
|
10664
|
+
"browse:events-requested",
|
|
10665
|
+
"browse:annotation-history-requested",
|
|
10666
|
+
"browse:referenced-by-requested",
|
|
10667
|
+
"browse:entity-types-requested",
|
|
10668
|
+
"browse:tag-schemas-requested",
|
|
10669
|
+
"browse:agents-requested",
|
|
10670
|
+
"browse:directory-requested"
|
|
10671
|
+
];
|
|
10672
|
+
|
|
10673
|
+
// src/clone-token-manager.ts
|
|
10674
|
+
var CLONE_TOKEN_CHANNELS = [
|
|
10675
|
+
"yield:clone-token-requested",
|
|
10676
|
+
"yield:clone-resource-requested",
|
|
10677
|
+
"yield:clone-create"
|
|
10678
|
+
];
|
|
10679
|
+
|
|
10680
|
+
// src/service-channels.ts
|
|
10681
|
+
var SMELTER_AWAITED_OPERATIONS = [
|
|
10682
|
+
"browse:resource-requested",
|
|
10683
|
+
"browse:annotations-requested",
|
|
10684
|
+
"browse:resources-requested"
|
|
10685
|
+
];
|
|
10686
|
+
replyChannelsFor(SMELTER_AWAITED_OPERATIONS);
|
|
10687
|
+
var WEAVER_AWAITED_OPERATIONS = [
|
|
10688
|
+
"browse:resources-requested",
|
|
10689
|
+
"browse:events-requested",
|
|
10690
|
+
"browse:annotations-requested"
|
|
10691
|
+
];
|
|
10692
|
+
var WEAVER_REPLY_CHANNELS = replyChannelsFor(WEAVER_AWAITED_OPERATIONS);
|
|
10693
|
+
var LIBRARIAN_INBOUND_CHANNELS = [
|
|
10694
|
+
...MATCHER_CHANNELS,
|
|
10695
|
+
...GATHERER_CHANNELS,
|
|
10696
|
+
"gather:summary-requested",
|
|
10697
|
+
"weave:applied",
|
|
10698
|
+
"smelt:settled"
|
|
10699
|
+
];
|
|
10700
|
+
replyChannelsFor(LIBRARIAN_INBOUND_CHANNELS);
|
|
10701
|
+
var ARCHIVIST_INBOUND_CHANNELS = [
|
|
10702
|
+
...STOWER_CHANNELS,
|
|
10703
|
+
...BROWSER_CHANNELS,
|
|
10704
|
+
...CLONE_TOKEN_CHANNELS,
|
|
10705
|
+
"mark:create-request",
|
|
10706
|
+
"smelt:settled",
|
|
10707
|
+
// The annotation-context read moved here with the bytes (SINGLE-KB-MOUNT D5).
|
|
10708
|
+
"browse:annotation-context-requested"
|
|
10709
|
+
];
|
|
10710
|
+
var ARCHIVIST_OUTBOUND_STRAYS = [
|
|
10711
|
+
"mark:body-update-failed",
|
|
10712
|
+
// op keyed 'bind:update-body' (gateway handler re-emits mark:update-body)
|
|
10713
|
+
"yield:move-failed"
|
|
10714
|
+
// yield:mv has no registered operation; failure is direct-subscribed
|
|
10715
|
+
];
|
|
10716
|
+
[
|
|
10717
|
+
...ARCHIVIST_OUTBOUND_STRAYS,
|
|
10718
|
+
...replyChannelsFor(ARCHIVIST_INBOUND_CHANNELS)
|
|
10719
|
+
];
|
|
10720
|
+
async function runBootPass(pass, run, logger2, onState) {
|
|
10721
|
+
onState?.({ phase: "running" });
|
|
10722
|
+
try {
|
|
10723
|
+
const summary = await run();
|
|
10724
|
+
onState?.({ phase: "done", summary });
|
|
10725
|
+
} catch (error) {
|
|
10726
|
+
onState?.({ phase: "failed", error: error instanceof Error ? error.message : String(error) });
|
|
10727
|
+
logger2.error(`Boot pass '${pass}' failed \u2014 continuing with a store that may be behind`, {
|
|
10728
|
+
pass,
|
|
10729
|
+
error: errField(error)
|
|
10730
|
+
});
|
|
10731
|
+
}
|
|
10732
|
+
}
|
|
10617
10733
|
var configPath = join(homedir(), ".semiontconfig");
|
|
10618
10734
|
var tomlReader = {
|
|
10619
10735
|
readIfExists: (p) => existsSync(p) ? readFileSync(p, "utf-8") : null
|
|
@@ -10637,7 +10753,7 @@ if (maybeGraphConfig.type === "memory") {
|
|
|
10637
10753
|
}
|
|
10638
10754
|
var graphConfig = maybeGraphConfig;
|
|
10639
10755
|
var workerSecret = process.env.SEMIONT_WORKER_SECRET ?? "";
|
|
10640
|
-
var healthPort =
|
|
10756
|
+
var healthPort = 24102;
|
|
10641
10757
|
var stateHome = process.env.XDG_STATE_HOME ?? join(homedir(), ".local", "state");
|
|
10642
10758
|
var checkpointPath = join(stateHome, "semiont", "weaver-checkpoint.json");
|
|
10643
10759
|
var logger = createProcessLogger("weaver");
|
|
@@ -10698,7 +10814,12 @@ async function main() {
|
|
|
10698
10814
|
const httpTransport = new HttpTransport({
|
|
10699
10815
|
baseUrl: baseUrl$1(baseUrl),
|
|
10700
10816
|
token$: tokenSubject,
|
|
10701
|
-
tokenRefresher: refreshToken
|
|
10817
|
+
tokenRefresher: refreshToken,
|
|
10818
|
+
// Only the reply channels this process awaits — not the full bridged
|
|
10819
|
+
// set, whose global reply fan-out is the worker-OOM failure mode. See
|
|
10820
|
+
// WEAVER_AWAITED_OPERATIONS. The domain-event channels are added by
|
|
10821
|
+
// the actor state unit's start() below.
|
|
10822
|
+
channels: WEAVER_REPLY_CHANNELS
|
|
10702
10823
|
});
|
|
10703
10824
|
const actorStateUnit = createWeaverActorStateUnit({
|
|
10704
10825
|
bus: httpTransport.actor
|
|
@@ -10755,22 +10876,12 @@ async function main() {
|
|
|
10755
10876
|
};
|
|
10756
10877
|
process.on("SIGTERM", shutdown);
|
|
10757
10878
|
process.on("SIGINT", shutdown);
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
|
|
10763
|
-
|
|
10764
|
-
throw error;
|
|
10765
|
-
}
|
|
10766
|
-
reconcileState = { phase: "running" };
|
|
10767
|
-
try {
|
|
10768
|
-
const summary = await weaver.reconcile();
|
|
10769
|
-
reconcileState = { phase: "done", summary };
|
|
10770
|
-
} catch (error) {
|
|
10771
|
-
reconcileState = { phase: "failed", error: error instanceof Error ? error.message : String(error) };
|
|
10772
|
-
throw error;
|
|
10773
|
-
}
|
|
10879
|
+
await runBootPass("catch-up", () => weaver.catchUp(), logger, (s) => {
|
|
10880
|
+
catchUpState = s;
|
|
10881
|
+
});
|
|
10882
|
+
await runBootPass("reconcile", () => weaver.reconcile(), logger, (s) => {
|
|
10883
|
+
reconcileState = s;
|
|
10884
|
+
});
|
|
10774
10885
|
}
|
|
10775
10886
|
main().catch((error) => {
|
|
10776
10887
|
logger.error("Fatal", { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : void 0 });
|