Generalize live field bindings and use them for Studio canvas gestures
This commit is contained in:
@@ -22,6 +22,95 @@ const parsed = compileCapabilityResourceSource(
|
||||
assert.ok(parsed.ok && parsed.resource.kind === "interface", JSON.stringify(parsed.diagnostics));
|
||||
const iface = parsed.resource.revision;
|
||||
const environment = { interfaces: new Map([["Data", iface]]), interfaceClosure: [iface] };
|
||||
test("native fields certify one storage slot; only browser writes get live descriptors", () => {
|
||||
const parsed = compileCapabilityResourceSource(
|
||||
`interface Fields id "fields" revision "fields@1" {
|
||||
queryable field position id "position" : string {
|
||||
get id "position:get" execution snapshot targets [browser, server];
|
||||
set id "position:set" execution transaction targets [browser, server];
|
||||
}
|
||||
field remote id "remote" : string {
|
||||
get id "remote:get";
|
||||
set id "remote:set";
|
||||
}
|
||||
value arbitrary id "arbitrary" : string {
|
||||
get id "arbitrary:get" execution snapshot targets [browser,server];
|
||||
set id "arbitrary:set" execution transaction targets [browser, server];
|
||||
}
|
||||
value text id "text" : string {
|
||||
get id "text:get";
|
||||
edit id "text:edit" execution transaction targets [browser, server];
|
||||
}
|
||||
}`,
|
||||
{ source },
|
||||
);
|
||||
assert.ok(parsed.ok && parsed.resource.kind === "interface", JSON.stringify(parsed.diagnostics));
|
||||
const revision = parsed.resource.revision;
|
||||
const generated = generateInterfaceClientBindings({ Fields: revision });
|
||||
assert.match(generated, /defineFieldOperation<string, "register",/);
|
||||
assert.match(generated, /defineFieldOperation<string, "crdt",/);
|
||||
for (const member of revision.members) {
|
||||
const operation = member.operations.at(-1)!;
|
||||
assert.equal(
|
||||
publicOperationContract(revision, operation).fieldPolicy,
|
||||
member.displayName === "position" ? "register" : member.displayName === "text" ? "crdt" : undefined,
|
||||
);
|
||||
}
|
||||
const workspace = `workspace W id "w" revision "w@1" commit "${source.commit}" {
|
||||
import interface Fields; atom A id "a";
|
||||
conform A as Fields id "a:fields" {
|
||||
private state First id "first" on A : string policy register default "";
|
||||
private state Second id "second" on A : string policy register default "";
|
||||
private state Text id "text" on A : string policy crdt(string);
|
||||
initialize { text to state Text; };
|
||||
bind position.get to state First.read;
|
||||
bind position.set to state First.write;
|
||||
bind remote.get to state Second.read;
|
||||
bind remote.set to state Second.write;
|
||||
bind arbitrary.get to state Second.read;
|
||||
bind arbitrary.set to state Second.write;
|
||||
bind text.get to state Text.read;
|
||||
bind text.edit to state Text.edit;
|
||||
}
|
||||
}`;
|
||||
const env = { interfaces: new Map([["Fields", revision]]) };
|
||||
const good = compileCapabilitySource(workspace, "workspace.qx", env);
|
||||
assert.ok(good.ok, JSON.stringify(good.diagnostics));
|
||||
const bad = compileCapabilitySource(
|
||||
workspace.replace("bind position.set to state First.write", "bind position.set to state Second.write"),
|
||||
"workspace.qx",
|
||||
env,
|
||||
);
|
||||
assert.equal(bad.ok, false);
|
||||
assert.ok(
|
||||
bad.diagnostics.some((d) => d.message.includes("same native state slot")),
|
||||
JSON.stringify(bad.diagnostics),
|
||||
);
|
||||
const forwarded = workspace
|
||||
.replace("bind position.get to state First.read", "bind position.get to interface Fields.arbitrary.get")
|
||||
.replace("bind position.set to state First.write", "bind position.set to interface Fields.arbitrary.set");
|
||||
const goodForward = compileCapabilitySource(forwarded, "workspace.qx", env);
|
||||
assert.ok(goodForward.ok, JSON.stringify(goodForward.diagnostics));
|
||||
const pkg = compileCapabilityResourceSource(
|
||||
`package Setter id "setter" revision "setter@1" {
|
||||
operation replaceValue id "write" : string -> unit mode call execution transaction targets [browser,server] receiver any;
|
||||
}`,
|
||||
{ source },
|
||||
);
|
||||
assert.ok(pkg.ok && pkg.resource.kind === "package", JSON.stringify(pkg.diagnostics));
|
||||
const badForward = compileCapabilitySource(
|
||||
forwarded
|
||||
.replace("import interface Fields;", "import interface Fields; import package Setter;")
|
||||
.replace("bind arbitrary.set to state Second.write", "bind arbitrary.set to package Setter.replaceValue"),
|
||||
"workspace.qx",
|
||||
{ ...env, packages: new Map([["Setter", pkg.resource.revision]]) },
|
||||
);
|
||||
assert.equal(badForward.ok, false);
|
||||
assert.ok(
|
||||
badForward.diagnostics.some((d) => d.message.includes("same native state slot")),
|
||||
JSON.stringify(badForward.diagnostics),
|
||||
);
|
||||
});
|
||||
const compile = async () => {
|
||||
const pkg = compileCapabilityResourceSource(
|
||||
`import interface Data; package Views id "views" revision "views@1" {
|
||||
|
||||
Reference in New Issue
Block a user