Implement rule-based Studio creation, usable canvas and Reader, and consolidated package authoring
This commit is contained in:
@@ -71,17 +71,10 @@ export async function executionScaffold(
|
|||||||
outputs = { nixpkgs, flake-utils, helpers, ... }:
|
outputs = { nixpkgs, flake-utils, helpers, ... }:
|
||||||
flake-utils.lib.eachDefaultSystem (system: let
|
flake-utils.lib.eachDefaultSystem (system: let
|
||||||
pkgs = import nixpkgs { inherit system; };
|
pkgs = import nixpkgs { inherit system; };
|
||||||
|
camino = import (helpers + "/quixos-package-helpers.nix");
|
||||||
in {
|
in {
|
||||||
devShells.default = (import (helpers + "/quixos-package-helpers.nix")).mkCaminoYarnShell { inherit pkgs; };
|
devShells.default = (import (helpers + "/quixos-package-helpers.nix")).mkCaminoYarnShell { inherit pkgs; };
|
||||||
quixosPackages.checkedArtifacts = context:
|
quixosPackages.checkedArtifacts = context:
|
||||||
import ./package.nix { inherit pkgs context; camino = import (helpers + "/quixos-package-helpers.nix"); };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
create(
|
|
||||||
"package.nix",
|
|
||||||
`{ pkgs, camino, context }:
|
|
||||||
let
|
let
|
||||||
plan = builtins.fromJSON (builtins.readFile context.plan);
|
plan = builtins.fromJSON (builtins.readFile context.plan);
|
||||||
package = pkgs.lib.findFirst (entry: entry.revision == context.packageRevisionId)
|
package = pkgs.lib.findFirst (entry: entry.revision == context.packageRevisionId)
|
||||||
@@ -103,6 +96,8 @@ in camino.assembleCaminoPackage {
|
|||||||
}) ++ pkgs.lib.optional (modules != {}) (camino.mkCaminoReactPackage {
|
}) ++ pkgs.lib.optional (modules != {}) (camino.mkCaminoReactPackage {
|
||||||
inherit pkgs context dependencies modules; src = ./.;
|
inherit pkgs context dependencies modules; src = ./.;
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -210,7 +210,8 @@ export const editStructure = (source: string, edit: StructuralEdit): string => {
|
|||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
const identifiers = node.children.filter((entry) => entry.kind === "identifier");
|
const identifiers = node.children.filter((entry) => entry.kind === "identifier");
|
||||||
const position = identifiers[identifiers.length - 1].end;
|
const targetArguments = node.children.find((entry) => entry.kind === "typeArguments");
|
||||||
|
const position = targetArguments?.end ?? identifiers[identifiers.length - 1].end;
|
||||||
result = applySourceEdits(source, [{ start: position, end: position, text: ` id ${JSON.stringify(edit.id)}` }]);
|
result = applySourceEdits(source, [{ start: position, end: position, text: ` id ${JSON.stringify(edit.id)}` }]);
|
||||||
} else if (edit.operation === "append") {
|
} else if (edit.operation === "append") {
|
||||||
const closing = syntax.tokens.find((token) => token.kind === "RBRACE" && token.end === node.end);
|
const closing = syntax.tokens.find((token) => token.kind === "RBRACE" && token.end === node.end);
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ export function compileKernelProgram(plan: ExecutionPlan): unknown {
|
|||||||
interface: bound.interfaceRevisionId,
|
interface: bound.interfaceRevisionId,
|
||||||
...(!bound.receiver &&
|
...(!bound.receiver &&
|
||||||
!bound.via &&
|
!bound.via &&
|
||||||
(requirement.operations ?? iface.members.flatMap(m=>m.operations.map(o=>o.id))).every(
|
(requirement.operations ?? iface.members.flatMap((m) => m.operations.map((o) => o.id))).every(
|
||||||
(id) => iface.members.flatMap((m) => m.operations).find((o) => o.id === id)?.scope === "class",
|
(id) => iface.members.flatMap((m) => m.operations).find((o) => o.id === id)?.scope === "class",
|
||||||
)
|
)
|
||||||
? { staticAtom: operation.atomId }
|
? { staticAtom: operation.atomId }
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ test("checked component scaffolding composes with execution handlers without rep
|
|||||||
assert.equal(await fs.readFile(flake, "utf8"), retainedFlake);
|
assert.equal(await fs.readFile(flake, "utf8"), retainedFlake);
|
||||||
assert.match(await fs.readFile(entriesFile, "utf8"), /retained entry comment/);
|
assert.match(await fs.readFile(entriesFile, "utf8"), /retained entry comment/);
|
||||||
assert.match(await fs.readFile(path.join(root, "src/server.ts"), "utf8"), /echo/);
|
assert.match(await fs.readFile(path.join(root, "src/server.ts"), "utf8"), /echo/);
|
||||||
assert.match(await fs.readFile(path.join(root, "flake.nix"), "utf8"), /import \.\/package\.nix/);
|
assert.match(await fs.readFile(path.join(root, "flake.nix"), "utf8"), /mkCaminoReactPackage/);
|
||||||
await assert.rejects(
|
await assert.rejects(
|
||||||
apply("component", {
|
apply("component", {
|
||||||
name: "Card",
|
name: "Card",
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ test("execution scaffolds route typed handlers by declared effect and target wit
|
|||||||
assert.match(await read("src/impl/asyncWork.ts"), /RemoteImplementation/);
|
assert.match(await read("src/impl/asyncWork.ts"), /RemoteImplementation/);
|
||||||
assert.match(await read("src/impl/both.ts"), /PortableImplementation/);
|
assert.match(await read("src/impl/both.ts"), /PortableImplementation/);
|
||||||
assert.match(await read("flake.nix"), /checkedArtifacts/);
|
assert.match(await read("flake.nix"), /checkedArtifacts/);
|
||||||
assert.match(await read("package.nix"), /entries.browser/);
|
assert.match(await read("flake.nix"), /entries.browser/);
|
||||||
await assert.rejects(add("both", "transaction targets [browser, server]"), /unique/);
|
await assert.rejects(add("both", "transaction targets [browser, server]"), /unique/);
|
||||||
await assert.rejects(add("invalid", "snapshot targets [remote]"), /browser\/server/);
|
await assert.rejects(add("invalid", "snapshot targets [remote]"), /browser\/server/);
|
||||||
await assert.rejects(apply("function", { name: "missing", id: "export:missing" }), /explicit execution/);
|
await assert.rejects(apply("function", { name: "missing", id: "export:missing" }), /explicit execution/);
|
||||||
|
|||||||
@@ -101,3 +101,17 @@ test("conformance enrollment, major edits, imports, and private attachment remov
|
|||||||
const imported = editStructure(removed, { operation: "import", kind: "interface", name: "Playable" });
|
const imported = editStructure(removed, { operation: "import", kind: "interface", name: "Playable" });
|
||||||
assert.equal(editStructure(imported, { operation: "import", kind: "interface", name: "Playable" }), imported);
|
assert.equal(editStructure(imported, { operation: "import", kind: "interface", name: "Playable" }), imported);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("enrolling a generic conformance or rule places its identity after target arguments", () => {
|
||||||
|
for (const source of [
|
||||||
|
"fragment { conform Game as View<atom Game> {} }",
|
||||||
|
"fragment { conform<object T> Source<T> as View<T> {} }",
|
||||||
|
]) {
|
||||||
|
const enrolled = editStructure(source, {
|
||||||
|
operation: "conformance-id",
|
||||||
|
target: { kind: "conformanceDecl" },
|
||||||
|
id: "rule:view",
|
||||||
|
});
|
||||||
|
assert.match(enrolled, /as View<[^>]+> id "rule:view"/);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user