Compare commits

..
24 changed files with 579 additions and 130 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
{
"monorepoCommit": "ba8d4f92667f39bb02d542cb492b71a32ec914bf",
"monorepoCommit": "4c88728f144add3457b4273d4b9a04ee53c53be3",
"sourcePath": "quixos-instance/packages/project-runtime"
}
-8
View File
@@ -1,8 +0,0 @@
{
"messages": {
"org.quixos.web-studio.SearchDocument": {
"module": "../messages.js",
"export": "searchDocumentBinding"
}
}
}
+4 -1
View File
@@ -1,7 +1,8 @@
# Generated by qx-scaffold-v1
# Generated from the checked package contract
package_id: "package:project-runtime"
package_revision_id: "package:project-runtime@1"
runtime_protocol_version: "quixos-capabilities-v1"
exports: { export_id: "export:project-runtime:new-project" runtime_symbol: "newProject" }
exports: { export_id: "export:project-runtime:create-project" runtime_symbol: "createProject" }
exports: { export_id: "export:project-runtime:add-task" runtime_symbol: "addTask" }
exports: { export_id: "export:project-runtime:task-count-get" runtime_symbol: "taskCountGet" }
@@ -10,3 +11,5 @@ exports: { export_id: "export:project-runtime:task-count-watch-stop" runtime_sym
exports: { export_id: "export:project-runtime:search-document-get" runtime_symbol: "searchDocumentGet" }
exports: { export_id: "export:project-runtime:search-document-watch" runtime_symbol: "searchDocumentWatch" }
exports: { export_id: "export:project-runtime:search-document-watch-stop" runtime_symbol: "searchDocumentWatchStop" }
exports: { export_id: "create-tag" runtime_symbol: "createTag" }
exports: { export_id: "add-tag" runtime_symbol: "addTag" }
Generated
+7 -7
View File
@@ -37,17 +37,17 @@
"quixosNixHelpers": {
"flake": false,
"locked": {
"lastModified": 1789364768,
"narHash": "sha256-6tINqOSLd3TTACk/HAfhXqo07H69yjX3Q/DrrAPWzus=",
"ref": "refs/tags/quixos-reachability/cf7945abb6ee2533a34dff4a7d4a956e70efe007",
"rev": "cf7945abb6ee2533a34dff4a7d4a956e70efe007",
"revCount": 22,
"lastModified": 1789602549,
"narHash": "sha256-DD66dQ3dzEvG13Zju/4sVSV4pnktSUkJ/Rbr1KkHMdg=",
"ref": "refs/tags/quixos-reachability/e2747066ca7d9d001dcb5dd936e17969ed88fc5f",
"rev": "e2747066ca7d9d001dcb5dd936e17969ed88fc5f",
"revCount": 32,
"type": "git",
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
},
"original": {
"ref": "refs/tags/quixos-reachability/cf7945abb6ee2533a34dff4a7d4a956e70efe007",
"rev": "cf7945abb6ee2533a34dff4a7d4a956e70efe007",
"ref": "refs/tags/quixos-reachability/e2747066ca7d9d001dcb5dd936e17969ed88fc5f",
"rev": "e2747066ca7d9d001dcb5dd936e17969ed88fc5f",
"type": "git",
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
}
+8 -3
View File
@@ -6,12 +6,18 @@
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/cf7945abb6ee2533a34dff4a7d4a956e70efe007&rev=cf7945abb6ee2533a34dff4a7d4a956e70efe007";
url = "git+https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git?ref=refs/tags/quixos-reachability/e2747066ca7d9d001dcb5dd936e17969ed88fc5f&rev=e2747066ca7d9d001dcb5dd936e17969ed88fc5f";
flake = false;
};
};
outputs = inputs@{ nixpkgs, flake-utils, quixosNixHelpers, ... }:
outputs =
inputs@{
nixpkgs,
flake-utils,
quixosNixHelpers,
...
}:
let
quixosHelpers = import "${quixosNixHelpers}/quixos-package-helpers.nix";
in
@@ -19,7 +25,6 @@
inherit inputs nixpkgs flake-utils;
packageRoot = ./.;
migrationEntrypoint = "dist/migrate.js";
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=d3d050d9cb84421fd8043ebe34fd0cae9132f6a2"
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=446fd4e36e9700cf27ce20b472a8d512133e9370"
},
"devDependencies": {
"@types/node": "^24",
+12
View File
@@ -1,9 +1,14 @@
import interface TagData;
external atom Tag id "atom:tag";
import interface Named;
import interface ProjectTasks;
external atom Project id "atom:project";
external atom Task id "atom:task";
package ProjectRuntime id "package:project-runtime" revision "package:project-runtime@1" {
function newProject id "export:project-runtime:new-project" : unit -> atom-ref<Project> requires {
constructor project id "port:project-runtime:new-project" : Project input unit;
};
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 {
interface tasks id "port:project-runtime:tasks" : ProjectTasks;
@@ -25,4 +30,11 @@ package ProjectRuntime id "package:project-runtime" revision "package:project-ru
interface tasks id "port:project-search:tasks" : ProjectTasks;
};
operation searchDocumentWatchStop id "export:project-runtime:search-document-watch-stop" : watch-handle -> unit mode watch-stop receiver atom Project;
constructor createTag id "create-tag" constructs Tag : string requires {
interface data id "tag-data" : TagData;
};
operation addTag id "add-tag" : string -> atom-ref<Tag> mode call receiver atom Project requires {
interface catalog id "catalog" : ProjectTasks;
constructor tag id "tag-constructor" : Tag input string;
};
}
+7 -3
View File
@@ -1,14 +1,18 @@
quixos-lock version 1 {
quixos source {
repository "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos.git";
commit "ba8d4f92667f39bb02d542cb492b71a32ec914bf";
commit "4c88728f144add3457b4273d4b9a04ee53c53be3";
}
interface Named source {
repository "https://repos.quixos.org/quixos-templates/interface-named.git";
commit "046a719004a6dda537a5dc98ef60f55a43eba0e4";
commit "fbd8d695bcb49c7a2bd3394002bc828a75cdc11b";
}
interface ProjectTasks source {
repository "https://repos.quixos.org/quixos-templates/interface-project-tasks.git";
commit "522f030dfd656ef788ae9a0b0b43b06144912042";
commit "7cb6436aa1c2a455e4dc649ac3fe9d15de136360";
}
interface TagData source {
repository "https://repos.quixos.org/quixos-templates/interface-tag-data.git";
commit "944d1186ff82c2b00fe0db4fd839bbbfc66b0a72";
}
}
-48
View File
@@ -1,48 +0,0 @@
{
"generatedBy": "qx-scaffold-v1",
"name": "ProjectRuntime",
"id": "package:project-runtime",
"revision": "package:project-runtime@1",
"exports": [
{
"name": "createProject",
"id": "export:project-runtime:create-project",
"file": "src/impl/createProject.ts"
},
{
"name": "addTask",
"id": "export:project-runtime:add-task",
"file": "src/impl/addTask.ts"
},
{
"name": "taskCountGet",
"id": "export:project-runtime:task-count-get",
"file": "src/impl/taskCountGet.ts"
},
{
"name": "taskCountWatch",
"id": "export:project-runtime:task-count-watch",
"file": "src/impl/taskCountWatch.ts"
},
{
"name": "taskCountWatchStop",
"id": "export:project-runtime:task-count-watch-stop",
"file": "src/impl/taskCountWatchStop.ts"
},
{
"name": "searchDocumentGet",
"id": "export:project-runtime:search-document-get",
"file": "src/impl/searchDocumentGet.ts"
},
{
"name": "searchDocumentWatch",
"id": "export:project-runtime:search-document-watch",
"file": "src/impl/searchDocumentWatch.ts"
},
{
"name": "searchDocumentWatchStop",
"id": "export:project-runtime:search-document-watch-stop",
"file": "src/impl/searchDocumentWatchStop.ts"
}
]
}
+464 -7
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export {addTask as handler} from "../project.impl.js";
export { addTask as handler } from "../project.impl.js";
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export {createProject as handler} from "../project.impl.js";
export { createProject as handler } from "../project.impl.js";
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export {searchDocument as handler} from "../project.impl.js";
export { searchDocument as handler } from "../project.impl.js";
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export {searchDocument as handler} from "../project.impl.js";
export { searchDocument as handler } from "../project.impl.js";
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export {stopWatch as handler} from "../project.impl.js";
export { stopWatch as handler } from "../project.impl.js";
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export {taskCount as handler} from "../project.impl.js";
export { taskCount as handler } from "../project.impl.js";
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export {taskCount as handler} from "../project.impl.js";
export { taskCount as handler } from "../project.impl.js";
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export {stopWatch as handler} from "../project.impl.js";
export { stopWatch as handler } from "../project.impl.js";
+10 -6
View File
@@ -1,11 +1,15 @@
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" } },
}};
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, {}),
encode: (value) => encodeQxValue(schema, value, {}),
decode: (value) => decodeQxValue(schema, value, {}),
};
+1 -1
View File
@@ -1,3 +1,3 @@
// Generated by qx-scaffold-v1
import {serveMigration} from "@quixos/camino-package-runtime";
import { serveMigration } from "@quixos/camino-package-runtime";
await serveMigration({});
+25 -11
View File
@@ -1,21 +1,35 @@
import type { Contexts } from "./gen/qx.js";
export const createProject = ({ objectId }: Contexts["createProject"]) => objectId;
export const createTag = async ({ ports, input, objectId }: Contexts["createTag"]) => {
await ports.data["name.set"](input.trim() || "New tag");
return objectId;
};
export const addTag = async ({ ports, input }: Contexts["addTag"]) => {
if (!input.trim()) throw new Error("Enter a tag name");
const tag = await ports.tag.construct(input.trim());
await ports.catalog["tags.connect"](tag);
return tag;
};
export const addTask = async ({ input, ports }: Contexts["addTask"]) => {
const task = await ports.task.construct(input.trim() || "Untitled task");
await ports.tasks["tasks.connect"](task);
return task;
};
export const taskCount = { kind: "derived" as const, get: async ({ ports }: Contexts["taskCountGet"]) =>
(await ports.tasks["tasks.resolve"]()).length,
export const taskCount = {
kind: "derived" as const,
get: async ({ ports }: Contexts["taskCountGet"]) => (await ports.tasks["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 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;
+26 -20
View File
@@ -1,21 +1,27 @@
// Generated by qx-scaffold-v1
import {servePackageRuntime} from "@quixos/camino-package-runtime";
import {createRuntime} from "./gen/qx.js";
import {handler as impl0} from "./impl/createProject.js";
import {handler as impl1} from "./impl/addTask.js";
import {handler as impl2} from "./impl/taskCountGet.js";
import {handler as impl3} from "./impl/taskCountWatch.js";
import {handler as impl4} from "./impl/taskCountWatchStop.js";
import {handler as impl5} from "./impl/searchDocumentGet.js";
import {handler as impl6} from "./impl/searchDocumentWatch.js";
import {handler as impl7} from "./impl/searchDocumentWatchStop.js";
servePackageRuntime(createRuntime({
"createProject": impl0,
"addTask": impl1,
"taskCountGet": impl2,
"taskCountWatch": impl3,
"taskCountWatchStop": impl4,
"searchDocumentGet": impl5,
"searchDocumentWatch": impl6,
"searchDocumentWatchStop": impl7,
}));
import { servePackageRuntime } from "@quixos/camino-package-runtime";
import { createRuntime } from "./gen/qx.js";
import { addTag, createTag } from "./project.impl.js";
import { handler as impl0 } from "./impl/createProject.js";
import { handler as impl1 } from "./impl/addTask.js";
import { handler as impl2 } from "./impl/taskCountGet.js";
import { handler as impl3 } from "./impl/taskCountWatch.js";
import { handler as impl4 } from "./impl/taskCountWatchStop.js";
import { handler as impl5 } from "./impl/searchDocumentGet.js";
import { handler as impl6 } from "./impl/searchDocumentWatch.js";
import { handler as impl7 } from "./impl/searchDocumentWatchStop.js";
servePackageRuntime(
createRuntime({
addTag,
createTag,
newProject: ({ ports }) => ports.project.construct(),
createProject: impl0,
addTask: impl1,
taskCountGet: impl2,
taskCountWatch: impl3,
taskCountWatchStop: impl4,
searchDocumentGet: impl5,
searchDocumentWatch: impl6,
searchDocumentWatchStop: impl7,
}),
);
+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=d3d050d9cb84421fd8043ebe34fd0cae9132f6a2" = { filename = "@quixos-camino-package-runtime-https-08b8790f1a-5bde059ead.zip"; hash = "sha512-W94Fnq0rn4MyBqRUUhH0ZcTzVv9MfF59dHtwpFLhg+/jK4QG5wi/uNgRR3xEVszpN8yrBWO6uiJGlkGmNnrczA=="; };
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=446fd4e36e9700cf27ce20b472a8d512133e9370" = { filename = "@quixos-camino-package-runtime-https-84d8fd5109-6d173f9220.zip"; hash = "sha512-bRc/kiD/ODsJqBNX4+RTqdsczILibHLhB+X8MckDCoK+j32c4Hszh87obb1Rwjb5o35aI0fzArQqCwK270zzlw=="; };
"@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=d3d050d9cb84421fd8043ebe34fd0cae9132f6a2":
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=446fd4e36e9700cf27ce20b472a8d512133e9370":
version: 0.1.0
resolution: "@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=d3d050d9cb84421fd8043ebe34fd0cae9132f6a2"
resolution: "@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=446fd4e36e9700cf27ce20b472a8d512133e9370"
dependencies:
"@bufbuild/protobuf": "npm:^2.12.1"
"@connectrpc/connect": "npm:^2.1.2"
"@connectrpc/connect-node": "npm:^2.1.2"
checksum: 10c0/5bde059ead2b9f833206a4545211f465c4f356ff4c7c5e7d747b70a452e183efe32b8406e708bfb8d811477c4456cce937ccab0563baba22469641a6367adccc
checksum: 10c0/6d173f9220ff383b09a81357e3e453a9db1ccc82e26c72e107e5fc31c9030a82be8f7d9ce07b3387cee86dbd51c236f9a37e5a2347f302b42a0b02b6ef4cf397
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=d3d050d9cb84421fd8043ebe34fd0cae9132f6a2"
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=446fd4e36e9700cf27ce20b472a8d512133e9370"
"@types/node": "npm:^24"
typescript: "npm:^7.0.2"
bin: