Preserve nested CRDT recovery and serialize compound editor submissions

This commit is contained in:
Timothy J. Aveni
2026-09-20 23:26:13 -07:00
parent 2056c1e352
commit 47a3fe9eae
5 changed files with 37 additions and 1 deletions
+11 -1
View File
@@ -9,10 +9,20 @@ const source = { repository: "https://example.test/change.git", commit: "a".repe
test("compound captured changes survive planning, transport lowering and typed edit ports", async () => {
const plan = await compoundCrdtPlan();
const kernel = compileKernelProgram(plan) as {
operations: { operation: string; input: { fields: { change: { kind: string } } } }[];
operations: {
operation: string;
inputChanges?: (string | null)[][];
input: { fields: { change: { kind: string } } };
}[];
};
const operation = kernel.operations.find((op) => op.operation === "compound:update:call")!;
assert.equal(operation.input.fields.change.kind, "record");
const paths = kernel.operations as unknown as { operation: string; inputChanges?: (string | null)[][] }[];
assert.deepEqual(paths.find((op) => op.operation === "compound:update:call")!.inputChanges, [["change"]]);
assert.deepEqual(paths.find((op) => op.operation === "compound:batch:call")!.inputChanges, [
["edits", null, "change"],
]);
assert.deepEqual(paths.find((op) => op.operation === "compound:content:edit")!.inputChanges, [[]]);
const code = generatePortableTypeScriptBindings(plan.definition.bindingSchema, "compound:runtime@1", {
target: "browser",
});
+9
View File
@@ -2,6 +2,15 @@ external atom Note id "compound:note";
type Content = record { text: string; tags: list<string>; };
type Edit = record { change: change<Content>; resolved: bool; };
package EditRuntime id "compound:runtime" revision "compound:runtime@1" {
operation batch id "compound:runtime:batch" : record { edits: list<Edit>; } -> unit
mode call execution transaction targets [browser, server] receiver atom Note requires {
state content id "compound:batch:content" : Content [edit];
state resolved id "compound:batch:resolved" : bool [write];
} accept using checkBatch;
operation checkBatch id "compound:runtime:check-batch" : record { edits: list<Edit>; } -> unit
mode call execution snapshot targets [server] receiver atom Note requires {
state allowed id "compound:batch:allowed" : bool [read];
};
operation update id "compound:runtime:update" : Edit -> unit
mode call execution transaction targets [browser, server] receiver atom Note requires {
state content id "compound:edit:content" : Content [edit];
+3
View File
@@ -1,6 +1,9 @@
type Content = record { text: string; tags: list<string>; };
type Edit = record { change: change<Content>; resolved: bool; };
interface NoteData id "compound:data" revision "compound:data@1" {
operation batch id "compound:batch" : record { edits: list<Edit>; } -> unit {
call id "compound:batch:call" execution transaction targets [browser, server];
}
operation update id "compound:update" : Edit -> unit {
call id "compound:update:call" execution transaction targets [browser, server];
}
+4
View File
@@ -14,6 +14,10 @@ workspace Compound id "workspace:compound" revision "workspace:compound@1" commi
bind resolved.get to state Resolved.read;
bind title.get to state Title.read;
bind title.set to state Title.write;
bind batch.call to package EditRuntime.batch with {
content to state Content;
resolved to state Resolved;
} accept with { allowed to state Allowed; };
bind update.call to package EditRuntime.update with {
content to state Content;
resolved to state Resolved;