|
@@ -1,11 +1,14 @@
|
|
|
import {UUID} from "./types";
|
|
|
|
|
|
+import {createHash} from "crypto";
|
|
|
+
|
|
|
import {
|
|
|
Delta,
|
|
|
} from "./delta";
|
|
|
|
|
|
export class NodeCreation implements Delta {
|
|
|
readonly id: UUID;
|
|
|
+ readonly hash: Buffer;
|
|
|
|
|
|
// Inverse dependency: Deletions of this node.
|
|
|
deletions: Array<NodeDeletion> = []; // append-only
|
|
@@ -18,6 +21,10 @@ export class NodeCreation implements Delta {
|
|
|
|
|
|
constructor(id: UUID) {
|
|
|
this.id = id;
|
|
|
+ this.hash = createHash('sha256')
|
|
|
+ .update(typeof id) // prevent collisions between 'true' (actual boolean) and '"true"' (string "true")
|
|
|
+ .update(this.id.value.toString())
|
|
|
+ .digest();
|
|
|
}
|
|
|
|
|
|
getDependencies(): [] {
|
|
@@ -27,9 +34,15 @@ export class NodeCreation implements Delta {
|
|
|
getConflicts(): [] {
|
|
|
return [];
|
|
|
}
|
|
|
+
|
|
|
+ getHash(): Buffer {
|
|
|
+ return this.hash;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
export class NodeDeletion implements Delta {
|
|
|
+ readonly hash: Buffer;
|
|
|
+
|
|
|
// Dependency: The node being deleted.
|
|
|
readonly creation: NodeCreation;
|
|
|
|
|
@@ -52,6 +65,9 @@ export class NodeDeletion implements Delta {
|
|
|
this.creation = creation;
|
|
|
this.deletedEdges = deletedEdges;
|
|
|
|
|
|
+ // id is the hash of the creation's id (which is the hash of the UUID of the node :)
|
|
|
+ this.hash = createHash('sha256').update(this.creation.hash).digest();
|
|
|
+
|
|
|
// Detect conflicts
|
|
|
|
|
|
// Delete/delete
|
|
@@ -116,6 +132,10 @@ export class NodeDeletion implements Delta {
|
|
|
this.updateConflicts,
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ getHash(): Buffer {
|
|
|
+ return this.hash;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// Common functionality in EdgeCreation and EdgeUpdate: both set the target of an edge, and this can conflict with the deletion of the target.
|
|
@@ -159,6 +179,8 @@ export class EdgeCreation implements Delta {
|
|
|
readonly label: string;
|
|
|
readonly target: SetsTarget;
|
|
|
|
|
|
+ readonly hash: Buffer;
|
|
|
+
|
|
|
// Inverse dependency
|
|
|
// NodeDeletion if source of edge is deleted.
|
|
|
overwrittenBy: Array<EdgeUpdate | NodeDeletion> = []; // append-only
|
|
@@ -174,6 +196,12 @@ export class EdgeCreation implements Delta {
|
|
|
this.label = label;
|
|
|
this.target = new SetsTarget(this, target);
|
|
|
|
|
|
+ this.hash = createHash('sha256')
|
|
|
+ .update(source.hash)
|
|
|
+ .update('create').update(label)
|
|
|
+ .update('target').update(target.hash)
|
|
|
+ .digest();
|
|
|
+
|
|
|
// Detect conflicts
|
|
|
|
|
|
// Create/create
|
|
@@ -214,6 +242,10 @@ export class EdgeCreation implements Delta {
|
|
|
this.target.deleteTargetConflicts,
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ getHash(): Buffer {
|
|
|
+ return this.hash;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
export class EdgeUpdate implements Delta {
|
|
@@ -221,6 +253,8 @@ export class EdgeUpdate implements Delta {
|
|
|
readonly overwrites: EdgeCreation | EdgeUpdate;
|
|
|
readonly target: SetsTarget;
|
|
|
|
|
|
+ readonly hash: Buffer;
|
|
|
+
|
|
|
// Inverse dependency
|
|
|
// NodeDeletion if source of edge is deleted.
|
|
|
overwrittenBy: Array<EdgeUpdate | NodeDeletion> = []; // append-only
|
|
@@ -232,6 +266,11 @@ export class EdgeUpdate implements Delta {
|
|
|
this.overwrites = overwrites;
|
|
|
this.target = new SetsTarget(this, newTarget);
|
|
|
|
|
|
+ this.hash = createHash('sha256')
|
|
|
+ .update(overwrites.hash)
|
|
|
+ .update('target').update(newTarget.hash)
|
|
|
+ .digest();
|
|
|
+
|
|
|
// Detect conflicts
|
|
|
|
|
|
// Concurrent updates (by EdgeUpdate or NodeDeletion)
|
|
@@ -260,5 +299,9 @@ export class EdgeUpdate implements Delta {
|
|
|
this.target.deleteTargetConflicts,
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ getHash(): Buffer {
|
|
|
+ return this.hash;
|
|
|
+ }
|
|
|
}
|
|
|
|