@semiont/event-sourcing 0.5.2 → 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/README.md +11 -0
- package/dist/event-log.d.ts +51 -0
- package/dist/event-log.d.ts.map +1 -0
- package/dist/event-store-factory.d.ts +19 -0
- package/dist/event-store-factory.d.ts.map +1 -0
- package/dist/event-store.d.ts +40 -0
- package/dist/event-store.d.ts.map +1 -0
- package/dist/identifier-utils.d.ts +10 -0
- package/dist/identifier-utils.d.ts.map +1 -0
- package/dist/index.d.ts +20 -566
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +80 -11
- package/dist/index.js.map +1 -1
- package/dist/query/event-query.d.ts +48 -0
- package/dist/query/event-query.d.ts.map +1 -0
- package/dist/storage/event-storage.d.ts +111 -0
- package/dist/storage/event-storage.d.ts.map +1 -0
- package/dist/storage/shard-utils.d.ts +56 -0
- package/dist/storage/shard-utils.d.ts.map +1 -0
- package/dist/storage/storage-uri-index.d.ts +60 -0
- package/dist/storage/storage-uri-index.d.ts.map +1 -0
- package/dist/storage/view-storage.d.ts +33 -0
- package/dist/storage/view-storage.d.ts.map +1 -0
- package/dist/view-manager.d.ts +84 -0
- package/dist/view-manager.d.ts.map +1 -0
- package/dist/views/projection-reducers.d.ts +73 -0
- package/dist/views/projection-reducers.d.ts.map +1 -0
- package/dist/views/view-materializer.d.ts +92 -0
- package/dist/views/view-materializer.d.ts.map +1 -0
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -399,6 +399,36 @@ var EventLog = class {
|
|
|
399
399
|
});
|
|
400
400
|
}
|
|
401
401
|
};
|
|
402
|
+
|
|
403
|
+
// src/views/projection-reducers.ts
|
|
404
|
+
function applyEntityTypeAdded(current, add) {
|
|
405
|
+
const set = new Set(current);
|
|
406
|
+
set.add(add);
|
|
407
|
+
return Array.from(set).sort((a, b) => a.localeCompare(b));
|
|
408
|
+
}
|
|
409
|
+
function applyTagSchemaAdded(current, add) {
|
|
410
|
+
const existingIdx = current.findIndex((s) => s.id === add.id);
|
|
411
|
+
let warning;
|
|
412
|
+
let next;
|
|
413
|
+
if (existingIdx >= 0) {
|
|
414
|
+
const existing = current[existingIdx];
|
|
415
|
+
if (!sameSchema(existing, add)) {
|
|
416
|
+
warning = {
|
|
417
|
+
schemaId: add.id,
|
|
418
|
+
message: `tag schema "${add.id}" overwritten \u2014 definition changed`
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
next = current.slice();
|
|
422
|
+
next[existingIdx] = add;
|
|
423
|
+
} else {
|
|
424
|
+
next = [...current, add];
|
|
425
|
+
}
|
|
426
|
+
next.sort((a, b) => a.id.localeCompare(b.id));
|
|
427
|
+
return warning ? { next, warning } : { next };
|
|
428
|
+
}
|
|
429
|
+
function sameSchema(a, b) {
|
|
430
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
431
|
+
}
|
|
402
432
|
var ResourceNotFoundError = class extends Error {
|
|
403
433
|
constructor(uri) {
|
|
404
434
|
super(`No resource found for URI: ${uri}`);
|
|
@@ -510,8 +540,7 @@ var ViewMaterializer = class {
|
|
|
510
540
|
name: "",
|
|
511
541
|
representations: [],
|
|
512
542
|
archived: false,
|
|
513
|
-
entityTypes: []
|
|
514
|
-
creationMethod: "api"
|
|
543
|
+
entityTypes: []
|
|
515
544
|
};
|
|
516
545
|
const annotations = {
|
|
517
546
|
resourceId,
|
|
@@ -537,7 +566,6 @@ var ViewMaterializer = class {
|
|
|
537
566
|
resource.name = event.payload.name;
|
|
538
567
|
resource.entityTypes = event.payload.entityTypes || [];
|
|
539
568
|
resource.dateCreated = event.timestamp;
|
|
540
|
-
resource.creationMethod = event.payload.creationMethod || "api";
|
|
541
569
|
resource.wasAttributedTo = didToAgent(event.userId);
|
|
542
570
|
if (!resource.representations) resource.representations = [];
|
|
543
571
|
const reps = Array.isArray(resource.representations) ? resource.representations : [resource.representations];
|
|
@@ -561,7 +589,6 @@ var ViewMaterializer = class {
|
|
|
561
589
|
resource.name = event.payload.name;
|
|
562
590
|
resource.entityTypes = event.payload.entityTypes || [];
|
|
563
591
|
resource.dateCreated = event.timestamp;
|
|
564
|
-
resource.creationMethod = "clone";
|
|
565
592
|
resource.sourceResourceId = event.payload.parentResourceId;
|
|
566
593
|
resource.wasAttributedTo = didToAgent(event.userId);
|
|
567
594
|
if (!resource.representations) resource.representations = [];
|
|
@@ -675,7 +702,8 @@ var ViewMaterializer = class {
|
|
|
675
702
|
* Mirrors GraphDBConsumer.rebuildAll() and Smelter.rebuildAll() — this is the
|
|
676
703
|
* recovery path that makes the ephemeral stateDir safe to wipe. The live
|
|
677
704
|
* append path (EventStore.appendEvent → materializeIncremental /
|
|
678
|
-
* materializeEntityTypes) is unchanged and runs in
|
|
705
|
+
* materializeEntityTypes / materializeTagSchemas) is unchanged and runs in
|
|
706
|
+
* addition.
|
|
679
707
|
*/
|
|
680
708
|
async rebuildAll(eventLog) {
|
|
681
709
|
this.logger?.info("[ViewMaterializer] Rebuilding all materialized views from event log");
|
|
@@ -685,6 +713,9 @@ var ViewMaterializer = class {
|
|
|
685
713
|
for (const event of systemEvents) {
|
|
686
714
|
if (event.type === "frame:entity-type-added") {
|
|
687
715
|
await this.materializeEntityTypes(event.payload.entityType);
|
|
716
|
+
} else if (event.type === "frame:tag-schema-added") {
|
|
717
|
+
const payload = event.payload;
|
|
718
|
+
await this.materializeTagSchemas(payload.schema);
|
|
688
719
|
}
|
|
689
720
|
}
|
|
690
721
|
const allResourceIds = await eventLog.getAllResourceIds();
|
|
@@ -717,7 +748,11 @@ var ViewMaterializer = class {
|
|
|
717
748
|
});
|
|
718
749
|
}
|
|
719
750
|
/**
|
|
720
|
-
* Materialize entity types view
|
|
751
|
+
* Materialize entity types view — System-level view.
|
|
752
|
+
*
|
|
753
|
+
* I/O shell around the pure {@link applyEntityTypeAdded} reducer:
|
|
754
|
+
* read JSON file → reduce → write JSON file. The reducer owns the
|
|
755
|
+
* dedup + sort semantics; the shell owns the disk I/O.
|
|
721
756
|
*/
|
|
722
757
|
async materializeEntityTypes(entityType) {
|
|
723
758
|
const entityTypesPath = path.join(
|
|
@@ -733,12 +768,44 @@ var ViewMaterializer = class {
|
|
|
733
768
|
} catch (error) {
|
|
734
769
|
if (error.code !== "ENOENT") throw error;
|
|
735
770
|
}
|
|
736
|
-
|
|
737
|
-
entityTypeSet.add(entityType);
|
|
738
|
-
view.entityTypes = Array.from(entityTypeSet).sort();
|
|
771
|
+
view.entityTypes = applyEntityTypeAdded(view.entityTypes, entityType);
|
|
739
772
|
await promises.mkdir(path.dirname(entityTypesPath), { recursive: true });
|
|
740
773
|
await promises.writeFile(entityTypesPath, JSON.stringify(view, null, 2));
|
|
741
774
|
}
|
|
775
|
+
/**
|
|
776
|
+
* Materialize tag schemas view — System-level view.
|
|
777
|
+
*
|
|
778
|
+
* I/O shell around the pure {@link applyTagSchemaAdded} reducer.
|
|
779
|
+
* The reducer owns the most-recent-wins semantics + the
|
|
780
|
+
* differing-content-overwrite-warning; the shell forwards the
|
|
781
|
+
* warning (when present) to this materializer's logger and writes
|
|
782
|
+
* the resulting state to disk.
|
|
783
|
+
*/
|
|
784
|
+
async materializeTagSchemas(schema) {
|
|
785
|
+
const tagSchemasPath = path.join(
|
|
786
|
+
this.config.basePath,
|
|
787
|
+
"projections",
|
|
788
|
+
"__system__",
|
|
789
|
+
"tagschemas.json"
|
|
790
|
+
);
|
|
791
|
+
let view = { tagSchemas: [] };
|
|
792
|
+
try {
|
|
793
|
+
const content = await promises.readFile(tagSchemasPath, "utf-8");
|
|
794
|
+
view = JSON.parse(content);
|
|
795
|
+
} catch (error) {
|
|
796
|
+
if (error.code !== "ENOENT") throw error;
|
|
797
|
+
}
|
|
798
|
+
const result = applyTagSchemaAdded(view.tagSchemas, schema);
|
|
799
|
+
if (result.warning) {
|
|
800
|
+
this.logger?.warn("[ViewMaterializer] Tag schema overwritten", {
|
|
801
|
+
schemaId: result.warning.schemaId,
|
|
802
|
+
message: result.warning.message
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
view.tagSchemas = result.next;
|
|
806
|
+
await promises.mkdir(path.dirname(tagSchemasPath), { recursive: true });
|
|
807
|
+
await promises.writeFile(tagSchemasPath, JSON.stringify(view, null, 2));
|
|
808
|
+
}
|
|
742
809
|
};
|
|
743
810
|
|
|
744
811
|
// src/view-manager.ts
|
|
@@ -776,13 +843,15 @@ var ViewManager = class _ViewManager {
|
|
|
776
843
|
);
|
|
777
844
|
}
|
|
778
845
|
/**
|
|
779
|
-
* Update system-level view (
|
|
846
|
+
* Update system-level view (entity types + tag schemas today).
|
|
780
847
|
* Serialized through a shared chain — see class doc.
|
|
781
848
|
*/
|
|
782
849
|
async materializeSystem(eventType, payload) {
|
|
783
850
|
await serializePerKey(_ViewManager.SYSTEM_KEY, this.systemChains, async () => {
|
|
784
851
|
if (eventType === "frame:entity-type-added") {
|
|
785
852
|
await this.materializer.materializeEntityTypes(payload.entityType);
|
|
853
|
+
} else if (eventType === "frame:tag-schema-added") {
|
|
854
|
+
await this.materializer.materializeTagSchemas(payload.schema);
|
|
786
855
|
}
|
|
787
856
|
});
|
|
788
857
|
}
|
|
@@ -1047,6 +1116,6 @@ function generateAnnotationId() {
|
|
|
1047
1116
|
return nanoid(21);
|
|
1048
1117
|
}
|
|
1049
1118
|
|
|
1050
|
-
export { EventLog, EventQuery, EventStorage, EventStore, FilesystemViewStorage, ResourceNotFoundError, ViewManager, ViewMaterializer, createEventStore, generateAnnotationId, getShardPath, jumpConsistentHash, removeStorageUriEntry, resolveStorageUri, sha256, writeStorageUriEntry };
|
|
1119
|
+
export { EventLog, EventQuery, EventStorage, EventStore, FilesystemViewStorage, ResourceNotFoundError, ViewManager, ViewMaterializer, applyEntityTypeAdded, applyTagSchemaAdded, createEventStore, generateAnnotationId, getShardPath, jumpConsistentHash, removeStorageUriEntry, resolveStorageUri, sha256, writeStorageUriEntry };
|
|
1051
1120
|
//# sourceMappingURL=index.js.map
|
|
1052
1121
|
//# sourceMappingURL=index.js.map
|