Compare commits

..
13 changed files with 378 additions and 73 deletions
+4
View File
@@ -0,0 +1,4 @@
{
"monorepoCommit": "15b93e42825a3f8055f6305999a12c5b1cc73330",
"sourcePath": "quixos-instance/packages/project-runtime"
}
+8
View File
@@ -0,0 +1,8 @@
{
"messages": {
"org.quixos.web-studio.SearchDocument": {
"module": "../messages.js",
"export": "searchDocumentBinding"
}
}
}
Generated
+7 -7
View File
@@ -37,17 +37,17 @@
"quixosNixHelpers": {
"flake": false,
"locked": {
"lastModified": 1788543053,
"narHash": "sha256-3YReATWEVxZinYVi/l3cwOz+oFoZUrwj24kUBQTmUpQ=",
"ref": "refs/tags/quixos-reachability/56bbcd22d17f8c7f120b1e0b5bd1d5a86e91a80a",
"rev": "56bbcd22d17f8c7f120b1e0b5bd1d5a86e91a80a",
"revCount": 8,
"lastModified": 1789354913,
"narHash": "sha256-vCdz/2jZ15GpA7YkmjLGOuO/LoZIeI8v7joDD5EI0oE=",
"ref": "refs/tags/quixos-reachability/8b2a224698da3659dd9a81e237dfe79238ee2836",
"rev": "8b2a224698da3659dd9a81e237dfe79238ee2836",
"revCount": 18,
"type": "git",
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
},
"original": {
"ref": "refs/tags/quixos-reachability/56bbcd22d17f8c7f120b1e0b5bd1d5a86e91a80a",
"rev": "56bbcd22d17f8c7f120b1e0b5bd1d5a86e91a80a",
"ref": "refs/tags/quixos-reachability/8b2a224698da3659dd9a81e237dfe79238ee2836",
"rev": "8b2a224698da3659dd9a81e237dfe79238ee2836",
"type": "git",
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
}
+2 -1
View File
@@ -6,7 +6,7 @@
flake-utils.url = "github:numtide/flake-utils";
quixosNixHelpers = {
url = "git+https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git?ref=refs/tags/quixos-reachability/56bbcd22d17f8c7f120b1e0b5bd1d5a86e91a80a&rev=56bbcd22d17f8c7f120b1e0b5bd1d5a86e91a80a";
url = "git+https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git?ref=refs/tags/quixos-reachability/8b2a224698da3659dd9a81e237dfe79238ee2836&rev=8b2a224698da3659dd9a81e237dfe79238ee2836";
flake = false;
};
};
@@ -18,6 +18,7 @@
quixosHelpers.mkCaminoTsYarnNixifyFlake {
inherit inputs nixpkgs flake-utils;
packageRoot = ./.;
bindingOptions = builtins.fromJSON (builtins.readFile ./bindings.json);
promptName = "project-runtime";
bundle = {
entry = "dist/server.js";
+1 -1
View File
@@ -12,7 +12,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=a998690446ecf647e3af78e369492c1a3663b66d"
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=110e41b268c8ac309e6757f2af3331de417ff9b0"
},
"devDependencies": {
"@types/node": "^24",
+1 -1
View File
@@ -7,7 +7,7 @@ package ProjectRuntime id "package:project-runtime" revision "package:project-ru
constructor createProject id "export:project-runtime:create-project" constructs Project : unit;
operation addTask id "export:project-runtime:add-task" : string -> atom-ref<Task> mode call receiver atom Project requires {
edge tasks id "port:project-actions:tasks" : many-unique atom Task [connect];
constructor task id "port:project-actions:task-constructor" : Task;
constructor task id "port:project-actions:task-constructor" : Task input string;
};
operation taskCountGet id "export:project-runtime:task-count-get" : unit -> uint32 mode call receiver atom Project requires {
edge tasks id "port:project-count:tasks" : many-unique atom Task [resolve];
+3 -5
View File
@@ -1,16 +1,14 @@
quixos-lock version 1 {
quixos source {
repository "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos.git";
commit "9c3ab572ecfbc83785038c3d9f174516df15d63f";
commit "15b93e42825a3f8055f6305999a12c5b1cc73330";
}
interface Named source {
repository "https://repos.quixos.org/quixos-templates/interface-named.git";
commit "14be607ed250f8c3ce1633558573fc1449f6f2a1";
commit "eb37f96b090db2c5e2dda1f4238fdd4154b29ca0";
}
interface ProjectTasks source {
repository "https://repos.quixos.org/quixos-templates/interface-project-tasks.git";
commit "2590966c1f95da08126f1cb830be7dcc6dc715d9";
commit "6744ffed19ecd855ebbac17a095c5096ddee2d7b";
}
}
+316
View File
File diff suppressed because one or more lines are too long
+11
View File
@@ -0,0 +1,11 @@
import { encodeQxValue, decodeQxValue, type MessageBinding, type QxValueType } from "@quixos/camino-package-runtime";
type SearchDocument = { title: string; subtitle: string; keywords: string[] };
const schema: QxValueType = { kind: "record", fields: {
title: { kind: "scalar", name: "string" }, subtitle: { kind: "scalar", name: "string" },
keywords: { kind: "list", value: { kind: "scalar", name: "string" } },
}};
export const searchDocumentBinding: MessageBinding<SearchDocument> = {
encode: value => encodeQxValue(schema, value, {}),
decode: value => decodeQxValue(schema, value, {}),
};
+12 -33
View File
@@ -1,42 +1,21 @@
import {
derived,
objectRef,
type RuntimeContext,
} from "@quixos/camino-package-runtime";
import type { Contexts } from "./gen/qx.js";
export const createProject = (context: RuntimeContext) => context.objectId;
export const addTask = async (context: RuntimeContext) => {
const requestedTitle = typeof context.input.value === "string"
? context.input.value.trim()
: "";
const taskId = await context
.constructor("port:project-actions:task-constructor")
.construct({ value: requestedTitle || "Untitled task" });
await context.edge("port:project-actions:tasks").connect(taskId);
return objectRef(taskId);
export const createProject = ({ objectId }: Contexts["createProject"]) => objectId;
export const addTask = async ({ input, ports }: Contexts["addTask"]) => {
const task = await ports.task.construct(input.trim() || "Untitled task");
await ports.tasks.connect(task);
return task;
};
export const taskCount = derived(async (context) =>
(await context.edge("port:project-count:tasks").resolve()).length,
);
export const searchDocument = derived(async (context) => {
const [name, tasks] = await Promise.all([
context.interface("port:project-search:named")
.invoke("operation:named:name:get"),
context.interface("port:project-search:tasks")
.invoke("operation:project-tasks:tasks:resolve"),
]);
if (typeof name !== "string" || !Array.isArray(tasks)) {
throw new Error("Project search dependencies returned invalid values");
}
export const taskCount = { kind: "derived" as const, get: async ({ ports }: Contexts["taskCountGet"]) =>
(await ports.tasks.resolve()).length,
};
export const searchDocument = { kind: "derived" as const, get: async ({ ports }: Contexts["searchDocumentGet"]) => {
const [name, tasks] = await Promise.all([ports.named["name.get"](), ports.tasks["tasks.resolve"]()]);
const count = tasks.length;
return {
title: name || "Untitled project",
subtitle: `Project · ${count} ${count === 1 ? "task" : "tasks"}`,
keywords: ["project", "workspace", count === 0 ? "empty" : "tasks"],
};
});
}};
export const stopWatch = () => null;
+8 -20
View File
@@ -1,22 +1,10 @@
import { servePackageRuntime } from "@quixos/camino-package-runtime";
import {
addTask,
createProject,
searchDocument,
stopWatch,
taskCount,
} from "./project.impl.js";
import { createRuntime, type Implementation } from "./gen/qx.js";
import { addTask, createProject, searchDocument, stopWatch, taskCount } from "./project.impl.js";
servePackageRuntime({
packageRevisionId: "package:project-runtime@1",
exports: {
"export:project-runtime:create-project": createProject,
"export:project-runtime:add-task": addTask,
"export:project-runtime:task-count-get": taskCount,
"export:project-runtime:task-count-watch": taskCount,
"export:project-runtime:task-count-watch-stop": stopWatch,
"export:project-runtime:search-document-get": searchDocument,
"export:project-runtime:search-document-watch": searchDocument,
"export:project-runtime:search-document-watch-stop": stopWatch,
},
});
const implementation: Implementation = {
createProject, addTask,
taskCountGet: taskCount, taskCountWatch: taskCount, taskCountWatchStop: stopWatch,
searchDocumentGet: searchDocument, searchDocumentWatch: searchDocument, searchDocumentWatchStop: stopWatch,
};
servePackageRuntime(createRuntime(implementation));
+1 -1
View File
@@ -159,7 +159,7 @@ cacheEntries = {
"@bufbuild/protobuf@npm:2.12.1" = { filename = "@bufbuild-protobuf-npm-2.12.1-d8afb467b3-2d40cfe4ec.zip"; hash = "sha512-LUDP5Ow7sOPwarLih3HcXcVm6qywVfvok9dWIbBAfQJy1I9ApJCtR97YOe1UFRThr3G7E68CSzrjbvDFbVbdqQ=="; };
"@connectrpc/connect-node@npm:2.1.2" = { filename = "@connectrpc-connect-node-npm-2.1.2-021434d5d5-ba8b0c9384.zip"; hash = "sha512-uosMk4TDgps3eqeoJtwM1Qpgk1J9LscBRgSRKDYzbqlgSitazqQrEEd/i+RWnknd7WbKD8d/X1sCcDXgKeE+qQ=="; };
"@connectrpc/connect@npm:2.1.2" = { filename = "@connectrpc-connect-npm-2.1.2-ab34825de3-4e15000890.zip"; hash = "sha512-ThUACJAjt1Lv1E+pQKWuHh+gDhvrxLoM7ScruTWSDYw7hbd0UOZErUQruMqaJ1sMFxNviWuo7/A2F4Ex2wHWFQ=="; };
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=a998690446ecf647e3af78e369492c1a3663b66d" = { filename = "@quixos-camino-package-runtime-https-683bcbf33c-c90d5d5c53.zip"; hash = "sha512-yQ1dXFMR2k+xbkka2rrhsAcrQFZlJAZEYM0hqwGzdV5RJ+fhQEh3BEgoPiL2yxrxulU4zg/jsj8BTBFRp1feyg=="; };
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=110e41b268c8ac309e6757f2af3331de417ff9b0" = { filename = "@quixos-camino-package-runtime-https-5a5a438f14-75b1ffcea9.zip"; hash = "sha512-dbH/zqm6gwFck1pSrJAEXNUl6wfHpOL+jj4IwdHCyf5VOMKInCLr73Yx9NYUvqn3zw3AOfdm/8bUeTz2Htxo/A=="; };
"@types/node@npm:24.13.3" = { filename = "@types-node-npm-24.13.3-b512a0bbeb-a5bc08f49b.zip"; hash = "sha512-pbwI9JuVgdzcqQ4CzXcZejx5mECAdmSULlzVFhpVPU0q6AZPfjKUQQ10jX0Ji1wYSL5/pQwG8pxBk6sWvk5Z6w=="; };
"@typescript/typescript-linux-arm64@npm:7.0.2" = { filename = "@typescript-typescript-linux-arm64-npm-7.0.2-9cacfc53a0-10c0.zip"; hash = "sha512-s4c7nGT/lQIw6x0IfrL0b3ECy/D0g7UoDLdiIWJoM6EGXk5N/dmXdxUdA8Cr3hV/3nO2BYKTQ6Ai8/zGhiSQ3A=="; };
"@typescript/typescript-linux-x64@npm:7.0.2" = { filename = "@typescript-typescript-linux-x64-npm-7.0.2-8dd7ff8d24-10c0.zip"; hash = "sha512-k9EUK5CZ3OOPnyslp8SAAonHJpnpPmlaulppI/NmFyCzNs3UN/TLPUkyQia3KIxgbyTzKoXI5L5fl8Uj9bJ7Cg=="; };
+4 -4
View File
@@ -31,14 +31,14 @@ __metadata:
languageName: node
linkType: hard
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=a998690446ecf647e3af78e369492c1a3663b66d":
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=110e41b268c8ac309e6757f2af3331de417ff9b0":
version: 0.1.0
resolution: "@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=a998690446ecf647e3af78e369492c1a3663b66d"
resolution: "@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=110e41b268c8ac309e6757f2af3331de417ff9b0"
dependencies:
"@bufbuild/protobuf": "npm:^2.12.1"
"@connectrpc/connect": "npm:^2.1.2"
"@connectrpc/connect-node": "npm:^2.1.2"
checksum: 10c0/c90d5d5c5311da4fb16e491adabae1b0072b40566524064460cd21ab01b3755e5127e7e14048770448283e22f6cb1af1ba5538ce0fe3b23f014c1151a757deca
checksum: 10c0/75b1ffcea9ba83015c935a52ac90045cd525eb07c7a4e2fe8e3e08c1d1c2c9fe5538c2889c22ebef7631f4d614bea9f7cf0dc039f766ffc6d4793cf61edc68fc
languageName: node
linkType: hard
@@ -46,7 +46,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@quixos/project-runtime@workspace:."
dependencies:
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=a998690446ecf647e3af78e369492c1a3663b66d"
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=110e41b268c8ac309e6757f2af3331de417ff9b0"
"@types/node": "npm:^24"
typescript: "npm:^7.0.2"
bin: