Build workspace agent, capability graph, and versioned cutovers
This commit is contained in:
Vendored
+121
-5
@@ -4,7 +4,15 @@ import {
|
||||
capabilityId,
|
||||
type WorkspaceRevision,
|
||||
} from "../../src/capability-model/index.js";
|
||||
import { compileCapabilitySource } from "../../src/capability-language/index.js";
|
||||
import {
|
||||
compileCapabilityResourceSource,
|
||||
compileCapabilitySource,
|
||||
type CapabilityImportEnvironment,
|
||||
} from "../../src/capability-language/index.js";
|
||||
import type {
|
||||
InterfaceRevision,
|
||||
PackageRevision,
|
||||
} from "../../src/capability-model/index.js";
|
||||
|
||||
export const fixtureId = {
|
||||
workspace: capabilityId.workspace("workspace:todo"),
|
||||
@@ -62,11 +70,119 @@ export const capabilityFixtureSource = readFileSync(
|
||||
"utf8",
|
||||
);
|
||||
|
||||
export const makeValidCapabilityWorkspace = (): WorkspaceRevision => {
|
||||
const result = compileCapabilitySource(
|
||||
capabilityFixtureSource,
|
||||
capabilityFixturePath,
|
||||
const resourceSource = (name: string) => readFileSync(
|
||||
resolve(process.cwd(), "test/fixtures", name),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
export const capabilityResourceSources = {
|
||||
named: resourceSource("named.interface.qx"),
|
||||
owned: resourceSource("owned.interface.qx"),
|
||||
summary: resourceSource("summary.interface.qx"),
|
||||
todo: resourceSource("todo.package.qx"),
|
||||
} as const;
|
||||
|
||||
const source = (repository: string, commit: string) => ({ repository, commit });
|
||||
|
||||
const interfaceRevision = (
|
||||
resource: { kind: "interface"; revision: InterfaceRevision } |
|
||||
{ kind: "package"; revision: PackageRevision },
|
||||
) => {
|
||||
if (resource.kind !== "interface") throw new Error("Expected interface fixture");
|
||||
return resource.revision;
|
||||
};
|
||||
|
||||
const packageRevision = (
|
||||
resource: { kind: "interface"; revision: InterfaceRevision } |
|
||||
{ kind: "package"; revision: PackageRevision },
|
||||
) => {
|
||||
if (resource.kind !== "package") throw new Error("Expected package fixture");
|
||||
return resource.revision;
|
||||
};
|
||||
|
||||
export const compileCapabilityFixture = (overrides: Partial<{
|
||||
workspace: string;
|
||||
named: string;
|
||||
owned: string;
|
||||
summary: string;
|
||||
todo: string;
|
||||
}> = {}) => {
|
||||
const named = compileCapabilityResourceSource(
|
||||
overrides.named ?? capabilityResourceSources.named,
|
||||
{
|
||||
source: source(
|
||||
"https://repos.quixos.org/quixos-todo/interface-named.git",
|
||||
"2".repeat(40),
|
||||
),
|
||||
fileName: "named.interface.qx",
|
||||
},
|
||||
);
|
||||
if (!named.ok) return named;
|
||||
const namedRevision = interfaceRevision(named.resource);
|
||||
const namedEnvironment: CapabilityImportEnvironment = {
|
||||
interfaces: new Map([["Named", namedRevision]]),
|
||||
interfaceClosure: [namedRevision],
|
||||
};
|
||||
const owned = compileCapabilityResourceSource(
|
||||
overrides.owned ?? capabilityResourceSources.owned,
|
||||
{
|
||||
source: source(
|
||||
"https://repos.quixos.org/quixos-todo/interface-owned.git",
|
||||
"3".repeat(40),
|
||||
),
|
||||
fileName: "owned.interface.qx",
|
||||
environment: namedEnvironment,
|
||||
},
|
||||
);
|
||||
if (!owned.ok) return owned;
|
||||
const ownedRevision = interfaceRevision(owned.resource);
|
||||
const summary = compileCapabilityResourceSource(
|
||||
overrides.summary ?? capabilityResourceSources.summary,
|
||||
{
|
||||
source: source(
|
||||
"https://repos.quixos.org/quixos-todo/interface-summary.git",
|
||||
"4".repeat(40),
|
||||
),
|
||||
fileName: "summary.interface.qx",
|
||||
},
|
||||
);
|
||||
if (!summary.ok) return summary;
|
||||
const summaryRevision = interfaceRevision(summary.resource);
|
||||
const todo = compileCapabilityResourceSource(
|
||||
overrides.todo ?? capabilityResourceSources.todo,
|
||||
{
|
||||
source: source(
|
||||
"https://repos.quixos.org/quixos-todo/package-todo-runtime.git",
|
||||
"5".repeat(40),
|
||||
),
|
||||
fileName: "todo.package.qx",
|
||||
environment: namedEnvironment,
|
||||
},
|
||||
);
|
||||
if (!todo.ok) return todo;
|
||||
const todoRevision = packageRevision(todo.resource);
|
||||
return compileCapabilitySource(
|
||||
overrides.workspace ?? capabilityFixtureSource,
|
||||
capabilityFixturePath,
|
||||
{
|
||||
interfaces: new Map([
|
||||
["Named", namedRevision],
|
||||
["Owned", ownedRevision],
|
||||
["Summary", summaryRevision],
|
||||
]),
|
||||
packages: new Map([["TodoRuntime", todoRevision]]),
|
||||
interfaceClosure: [
|
||||
namedRevision,
|
||||
ownedRevision,
|
||||
summaryRevision,
|
||||
],
|
||||
packageClosure: [todoRevision],
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const makeValidCapabilityWorkspace = (): WorkspaceRevision => {
|
||||
const result = compileCapabilityFixture();
|
||||
if (!result.ok) {
|
||||
throw new Error(
|
||||
result.diagnostics
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import interface Named;
|
||||
external atom Project id "atom:project";
|
||||
external atom ProjectComponent id "atom:project-component";
|
||||
|
||||
package ComponentRuntime id "package:component-runtime" revision "package:component-runtime@1" {
|
||||
constructor createComponent id "export:component-runtime:create-component" constructs ProjectComponent : atom-ref<Project>;
|
||||
operation propsGet id "export:component-runtime:props-get" : unit -> string mode call receiver atom ProjectComponent requires {
|
||||
interface project id "port:component:project" : Named;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import interface ReactComponent;
|
||||
|
||||
interface HasReactComponent id "interface:org.quixos.web-studio.has-react-component" revision "interface:org.quixos.web-studio.has-react-component@1" {
|
||||
relation component id "member:org.quixos.web-studio.has-react-component:component" : optional-one interface ReactComponent {
|
||||
resolve id "operation:org.quixos.web-studio.has-react-component:component:resolve";
|
||||
}
|
||||
}
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
interface Named id "interface:named" revision "interface:named@1" {
|
||||
value name id "member:named:name" : string {
|
||||
get id "operation:named:name:get";
|
||||
set id "operation:named:name:set";
|
||||
watch start id "operation:named:name:watch-start" stop id "operation:named:name:watch-stop";
|
||||
}
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
import interface Named;
|
||||
|
||||
interface Owned id "interface:owned" revision "interface:owned@1" {
|
||||
relation owner id "member:owned:owner" : exactly-one interface Named {
|
||||
resolve id "operation:owned:owner:resolve";
|
||||
connect id "operation:owned:owner:connect";
|
||||
disconnect id "operation:owned:owner:disconnect";
|
||||
watch start id "operation:owned:owner:watch-start" stop id "operation:owned:owner:watch-stop";
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
interface ReactComponent id "interface:org.quixos.web-studio.react-component" revision "interface:org.quixos.web-studio.react-component@1" {
|
||||
value props id "member:org.quixos.web-studio.react-component:props" : string {
|
||||
get id "operation:org.quixos.web-studio.react-component:props:get";
|
||||
}
|
||||
}
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
interface Summary id "interface:summary" revision "interface:summary@1" {
|
||||
value summary id "member:summary:summary" : string {
|
||||
get id "operation:summary:summary:get";
|
||||
}
|
||||
}
|
||||
Vendored
+4
-44
@@ -2,50 +2,10 @@ workspace Todo id "workspace:todo" revision "workspace:todo@1" commit "111111111
|
||||
atom Project id "atom:project" doc "A project containing work.";
|
||||
atom Person id "atom:person";
|
||||
|
||||
interface Named id "interface:named" revision "interface:named@1" source {
|
||||
repository "https://repos.quixos.org/quixos-todo/interface-named.git";
|
||||
commit "2222222222222222222222222222222222222222";
|
||||
} {
|
||||
value name id "member:named:name" : string {
|
||||
get id "operation:named:name:get";
|
||||
set id "operation:named:name:set";
|
||||
watch start id "operation:named:name:watch-start" stop id "operation:named:name:watch-stop";
|
||||
}
|
||||
}
|
||||
|
||||
interface Owned id "interface:owned" revision "interface:owned@1" source {
|
||||
repository "https://repos.quixos.org/quixos-todo/interface-owned.git";
|
||||
commit "3333333333333333333333333333333333333333";
|
||||
} {
|
||||
relation owner id "member:owned:owner" : exactly-one interface Named {
|
||||
resolve id "operation:owned:owner:resolve";
|
||||
connect id "operation:owned:owner:connect";
|
||||
disconnect id "operation:owned:owner:disconnect";
|
||||
watch start id "operation:owned:owner:watch-start" stop id "operation:owned:owner:watch-stop";
|
||||
}
|
||||
}
|
||||
|
||||
interface Summary id "interface:summary" revision "interface:summary@1" source {
|
||||
repository "https://repos.quixos.org/quixos-todo/interface-summary.git";
|
||||
commit "4444444444444444444444444444444444444444";
|
||||
} {
|
||||
value summary id "member:summary:summary" : string {
|
||||
get id "operation:summary:summary:get";
|
||||
}
|
||||
}
|
||||
|
||||
package TodoRuntime id "package:todo-runtime" revision "package:todo-runtime@1" source {
|
||||
repository "https://repos.quixos.org/quixos-todo/package-todo-runtime.git";
|
||||
commit "5555555555555555555555555555555555555555";
|
||||
} {
|
||||
operation summaryGet id "export:todo-runtime:summary-get" : unit -> string
|
||||
mode call receiver interfaces [Named] requires {
|
||||
state title id "port:summary:title" : string [read];
|
||||
interface named id "port:summary:named" : Named;
|
||||
constructor person id "port:summary:person" : Person;
|
||||
};
|
||||
constructor createPerson id "export:todo-runtime:create-person" constructs Person : unit;
|
||||
}
|
||||
import interface Named;
|
||||
import interface Owned;
|
||||
import interface Summary;
|
||||
import package TodoRuntime;
|
||||
|
||||
shared state ProjectTitle id "slot:project:title" on Project : string
|
||||
policy optimistic-register default "Untitled project";
|
||||
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
import interface Named;
|
||||
external atom Person id "atom:person";
|
||||
|
||||
package TodoRuntime id "package:todo-runtime" revision "package:todo-runtime@1" {
|
||||
operation summaryGet id "export:todo-runtime:summary-get" : unit -> string
|
||||
mode call receiver interfaces [Named] requires {
|
||||
state title id "port:summary:title" : string [read];
|
||||
interface named id "port:summary:named" : Named;
|
||||
constructor person id "port:summary:person" : Person;
|
||||
};
|
||||
constructor createPerson id "export:todo-runtime:create-person" constructs Person : unit;
|
||||
}
|
||||
+12
-30
@@ -2,34 +2,10 @@ workspace WebStudioFixture id "workspace:web-studio-fixture" revision "workspace
|
||||
atom Project id "atom:project";
|
||||
atom ProjectComponent id "atom:project-component";
|
||||
|
||||
interface ReactComponent id "interface:org.quixos.web-studio.react-component" revision "interface:org.quixos.web-studio.react-component@1" source {
|
||||
repository "https://repos.quixos.org/org-quixos-web-studio/interface-react-component.git";
|
||||
commit "2222222222222222222222222222222222222222";
|
||||
} {
|
||||
value props id "member:org.quixos.web-studio.react-component:props" : string {
|
||||
get id "operation:org.quixos.web-studio.react-component:props:get";
|
||||
}
|
||||
}
|
||||
|
||||
interface HasReactComponent id "interface:org.quixos.web-studio.has-react-component" revision "interface:org.quixos.web-studio.has-react-component@1" source {
|
||||
repository "https://repos.quixos.org/org-quixos-web-studio/interface-has-react-component.git";
|
||||
commit "3333333333333333333333333333333333333333";
|
||||
} {
|
||||
relation component id "member:org.quixos.web-studio.has-react-component:component" : optional-one interface ReactComponent {
|
||||
resolve id "operation:org.quixos.web-studio.has-react-component:component:resolve";
|
||||
}
|
||||
}
|
||||
|
||||
package ComponentRuntime id "package:component-runtime" revision "package:component-runtime@1" source {
|
||||
repository "https://repos.quixos.org/quixos-test/package-component-runtime.git";
|
||||
commit "4444444444444444444444444444444444444444";
|
||||
} {
|
||||
constructor createComponent id "export:component-runtime:create-component" constructs ProjectComponent : atom-ref<Project>;
|
||||
operation propsGet id "export:component-runtime:props-get" : unit -> string mode call receiver atom ProjectComponent requires {
|
||||
edge subject id "port:component:subject" : exactly-one atom Project [resolve];
|
||||
state projectName id "port:component:project-name" : string [read];
|
||||
};
|
||||
}
|
||||
import interface Named;
|
||||
import interface ReactComponent;
|
||||
import interface HasReactComponent;
|
||||
import package ComponentRuntime;
|
||||
|
||||
shared state ProjectName id "slot:project:name" on Project : string
|
||||
policy optimistic-register default "Untitled project";
|
||||
@@ -38,14 +14,20 @@ workspace WebStudioFixture id "workspace:web-studio-fixture" revision "workspace
|
||||
atom Project projection component id "projection:project:component" optional-one;
|
||||
}
|
||||
|
||||
conform Project as Named {
|
||||
bind name.get to state ProjectName.read;
|
||||
bind name.set to state ProjectName.write;
|
||||
bind name.watch-start to state ProjectName.watch-start;
|
||||
bind name.watch-stop to state ProjectName.watch-stop;
|
||||
}
|
||||
|
||||
conform Project as HasReactComponent {
|
||||
bind component.resolve to edge ProjectComponentEdge.component.resolve;
|
||||
materialize component if absent using constructor ProjectComponent via edge ProjectComponentEdge.subject;
|
||||
}
|
||||
conform ProjectComponent as ReactComponent {
|
||||
bind props.get to package ComponentRuntime.propsGet with {
|
||||
subject to edge ProjectComponentEdge.subject;
|
||||
projectName to state ProjectName via edge ProjectComponentEdge.subject;
|
||||
project to interface Named via edge ProjectComponentEdge.subject;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user