Add explicit CRDT edit contracts and structured query values

This commit is contained in:
Timothy J. Aveni
2026-09-19 22:33:20 -07:00
parent 0555c929b1
commit 4c0c404a39
27 changed files with 3272 additions and 2745 deletions
+91
View File
@@ -0,0 +1,91 @@
import assert from "node:assert/strict";
import { test } from "node:test";
import { compileCapabilityResourceSource, compileCapabilitySource } from "../src/capability-language/index.js";
const source = { repository: "https://example.test/edit.git", commit: "a".repeat(40) };
const content = "record { text:string; tags:list<string>; }";
const iface = compileCapabilityResourceSource(
`interface Comment id "comment" revision "comment@1" {
value content id "content" : ${content} {
get id "content:get" execution snapshot targets [browser, server];
edit id "content:edit" execution transaction targets [browser, server];
}
}`,
{ source },
);
assert.ok(iface.ok && iface.resource.kind === "interface", JSON.stringify(iface.diagnostics));
const contract = iface.resource.revision;
const compile = (policy = `crdt(${content})`, binding = "edit") =>
compileCapabilitySource(
`
workspace Comments id "w" revision "w@1" commit "${"a".repeat(40)}" {
import interface Comment;
atom Comment id "comment";
conform Comment as Comment id "owner:comment" {
private state Content id "content" on Comment : ${content} policy ${policy};
initialize { content to state Content; };
bind content.get to state Content.read;
bind content.edit to state Content.${binding};
}
}`,
"comments.qx",
{ interfaces: new Map([["Comment", contract]]), interfaceClosure: [contract] },
);
test("native edit is an explicit typed change capability over structured content", () => {
const result = compile();
assert.ok(result.ok, JSON.stringify(result.diagnostics));
const member = contract.members[0]!;
assert.equal(member.kind, "value");
if (member.kind !== "value") return;
assert.deepEqual(member.operations[1]!.inputType, { kind: "change", value: member.valueType });
assert.equal(result.workspace.conformances[0]!.operationBindings[1]!.binding.kind, "state");
});
test("edit cannot target a register, mismatched profile, or ordinary replacement", () => {
for (const [policy, binding] of [
["register", "edit"],
["crdt(bytes)", "edit"],
[`crdt(${content})`, "write"],
]) {
const result = compile(policy, binding);
assert.equal(result.ok, false);
assert.ok(
result.diagnostics.some((d) => d.code === "invalid-state-binding"),
JSON.stringify(result.diagnostics),
);
}
});
test("authored prepared change transport values fail explicitly until their runtime is implemented", () => {
const result = compileCapabilityResourceSource(
'package P id "p" revision "p@1" { function applyChange id "apply" : change<string> -> unit; }',
{ source },
);
assert.equal(result.ok, false);
assert.ok(
result.diagnostics.some((d) => d.code === "unsupported-prepared-change"),
JSON.stringify(result.diagnostics),
);
});
test("generic edit retains its materialized type through specialization", () => {
const generic = compileCapabilityResourceSource(
`interface Cell<value T : storable> id "cell" revision "cell@1" {
value content id "content" : T { get id "get"; edit id "edit" execution transaction targets [browser, server]; }
}`,
{ source },
);
assert.ok(generic.ok && generic.resource.kind === "interface", JSON.stringify(generic.diagnostics));
const result = compileCapabilitySource(
`workspace W id "w" revision "w@1" commit "${"a".repeat(40)}" {
import interface Cell;
atom Note id "note";
conform Note as Cell<${content}> {
private state Content id "content" on Note : ${content} policy crdt(${content});
bind content to state Content;
}
}`,
"cell.qx",
{ interfaces: new Map([["Cell", generic.resource.revision]]), interfaceClosure: [generic.resource.revision] },
);
assert.ok(result.ok, JSON.stringify(result.diagnostics));
const applied = result.workspace.interfaceImports.find((i) => i.application)!;
assert.equal(applied.members[0]!.operations[1]!.inputType.kind, "change");
});