Compare commits

..
28 changed files with 414 additions and 472 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
{
"monorepoCommit": "99b2868b7e974441744657b35049f5baae4a499b",
"monorepoCommit": "810617559b0ee9c662c4b566e16cb3629b44fbce",
"sourcePath": "quixos-instance/packages/todo-react-runtime"
}
+8
View File
@@ -0,0 +1,8 @@
{
"messages": {
"org.quixos.web-studio.ReactProps": {
"module": "@quixos/camino-package-runtime",
"export": "opaqueReactPropsBinding"
}
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
# Generated from the checked package contract
# Generated by qx-scaffold-v1
package_id: "package:todo-react-runtime"
package_revision_id: "package:todo-react-runtime@1"
runtime_protocol_version: "quixos-capabilities-v1"
Generated
+7 -7
View File
@@ -37,17 +37,17 @@
"quixosNixHelpers": {
"flake": false,
"locked": {
"lastModified": 1789602549,
"narHash": "sha256-DD66dQ3dzEvG13Zju/4sVSV4pnktSUkJ/Rbr1KkHMdg=",
"ref": "refs/tags/quixos-reachability/e2747066ca7d9d001dcb5dd936e17969ed88fc5f",
"rev": "e2747066ca7d9d001dcb5dd936e17969ed88fc5f",
"revCount": 32,
"lastModified": 1789364768,
"narHash": "sha256-6tINqOSLd3TTACk/HAfhXqo07H69yjX3Q/DrrAPWzus=",
"ref": "refs/tags/quixos-reachability/cf7945abb6ee2533a34dff4a7d4a956e70efe007",
"rev": "cf7945abb6ee2533a34dff4a7d4a956e70efe007",
"revCount": 22,
"type": "git",
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
},
"original": {
"ref": "refs/tags/quixos-reachability/e2747066ca7d9d001dcb5dd936e17969ed88fc5f",
"rev": "e2747066ca7d9d001dcb5dd936e17969ed88fc5f",
"ref": "refs/tags/quixos-reachability/cf7945abb6ee2533a34dff4a7d4a956e70efe007",
"rev": "cf7945abb6ee2533a34dff4a7d4a956e70efe007",
"type": "git",
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
}
+10 -10
View File
@@ -6,18 +6,12 @@
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/e2747066ca7d9d001dcb5dd936e17969ed88fc5f&rev=e2747066ca7d9d001dcb5dd936e17969ed88fc5f";
url = "git+https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git?ref=refs/tags/quixos-reachability/cf7945abb6ee2533a34dff4a7d4a956e70efe007&rev=cf7945abb6ee2533a34dff4a7d4a956e70efe007";
flake = false;
};
};
outputs =
inputs@{
nixpkgs,
flake-utils,
quixosNixHelpers,
...
}:
outputs = inputs@{ nixpkgs, flake-utils, quixosNixHelpers, ... }:
let
quixosHelpers = import "${quixosNixHelpers}/quixos-package-helpers.nix";
in
@@ -25,14 +19,20 @@
inherit inputs nixpkgs flake-utils;
packageRoot = ./.;
migrationEntrypoint = "dist/migrate.js";
bindingOptions = builtins.fromJSON (builtins.readFile ./bindings.json);
promptName = "todo-react-runtime";
bundle = {
entry = "src/server.ts";
browserSources = true;
entry = "dist/server.js";
};
installServer = {
libexecName = "todo-react-runtime";
descriptorPath = "descriptor.quixos-package.txtpb";
extraFiles = [
{
source = "dist/todo-component.mjs";
target = "todo-component.mjs";
}
];
};
};
}
+2 -2
View File
@@ -8,11 +8,11 @@
"server": "dist/server.js"
},
"scripts": {
"build": "rm -rf dist && tsc -p tsconfig.build.json",
"build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/build-component.mjs",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=cd2b04dc8c2daeea633bf8ecdd31d20fdc41f2ab"
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=110e41b268c8ac309e6757f2af3331de417ff9b0"
},
"devDependencies": {
"@types/node": "^24",
+16 -6
View File
@@ -1,16 +1,26 @@
import interface TaskData;
external atom TaskReactComponent id "atom:task-react-component";
external atom Task id "atom:task";
type TaskProps = record {data: interface-ref<TaskData>;};
package TodoReactRuntime id "package:todo-react-runtime" revision "package:todo-react-runtime@1" {
constructor createComponent id "export:todo-react-runtime:create-component" constructs TaskReactComponent : atom-ref<Task>;
operation sourceGet id "export:todo-react-runtime:source-get" : unit -> string mode call receiver atom TaskReactComponent;
operation propsGet id "export:todo-react-runtime:props-get" : unit -> TaskProps mode call receiver atom TaskReactComponent requires {
interface data id "port:todo-react-runtime:data" : TaskData;
operation propsGet id "export:todo-react-runtime:props-get" : unit -> message "org.quixos.web-studio.ReactProps" mode call receiver atom TaskReactComponent requires {
edge subject id "port:todo-react:subject" : exactly-one atom Task [resolve];
state title id "port:todo-react:title" : string [read];
state status id "port:todo-react:status" : string [read];
state priority id "port:todo-react:priority" : string [read];
state notes id "port:todo-react:notes" : string [read];
state dueDate id "port:todo-react:due-date" : string [read];
state energy id "port:todo-react:energy" : string [read];
};
operation propsWatch id "export:todo-react-runtime:props-watch" : unit -> watch-handle mode watch-start emits TaskProps receiver atom TaskReactComponent requires {
interface data id "port:todo-react-runtime:data" : TaskData;
operation propsWatch id "export:todo-react-runtime:props-watch" : unit -> watch-handle mode watch-start emits message "org.quixos.web-studio.ReactProps" receiver atom TaskReactComponent requires {
edge subject id "port:todo-react:subject" : exactly-one atom Task [resolve];
state title id "port:todo-react:title" : string [read];
state status id "port:todo-react:status" : string [read];
state priority id "port:todo-react:priority" : string [read];
state notes id "port:todo-react:notes" : string [read];
state dueDate id "port:todo-react:due-date" : string [read];
state energy id "port:todo-react:energy" : string [read];
};
operation propsWatchStop id "export:todo-react-runtime:props-watch-stop" : watch-handle -> unit mode watch-stop receiver atom TaskReactComponent;
}
+5 -3
View File
@@ -2,9 +2,11 @@
"backend": "typescript",
"bindingOutput": "src/gen/qx.ts",
"options": {
"react": {
"propsExports": ["propsGet"],
"components": [{ "module": "../todo-component.js", "propsExport": "propsGet" }]
"messages": {
"org.quixos.web-studio.ReactProps": {
"module": "@quixos/camino-package-runtime",
"export": "opaqueReactPropsBinding"
}
}
}
}
+1 -5
View File
@@ -1,10 +1,6 @@
quixos-lock version 1 {
quixos source {
repository "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos.git";
commit "99b2868b7e974441744657b35049f5baae4a499b";
}
interface TaskData source {
repository "https://repos.quixos.org/quixos-templates/interface-task-data.git";
commit "ad2eac936b1d7f30eed9c0a74d1c220ec073b625";
commit "810617559b0ee9c662c4b566e16cb3629b44fbce";
}
}
+4
View File
@@ -0,0 +1,4 @@
{
"generatedBy": "qx-scaffold-v1",
"resources": []
}
+33
View File
@@ -0,0 +1,33 @@
{
"generatedBy": "qx-scaffold-v1",
"name": "TodoReactRuntime",
"id": "package:todo-react-runtime",
"revision": "package:todo-react-runtime@1",
"exports": [
{
"name": "createComponent",
"id": "export:todo-react-runtime:create-component",
"file": "src/impl/createComponent.ts"
},
{
"name": "sourceGet",
"id": "export:todo-react-runtime:source-get",
"file": "src/impl/sourceGet.ts"
},
{
"name": "propsGet",
"id": "export:todo-react-runtime:props-get",
"file": "src/impl/propsGet.ts"
},
{
"name": "propsWatch",
"id": "export:todo-react-runtime:props-watch",
"file": "src/impl/propsWatch.ts"
},
{
"name": "propsWatchStop",
"id": "export:todo-react-runtime:props-watch-stop",
"file": "src/impl/propsWatchStop.ts"
}
]
}
+34
View File
@@ -0,0 +1,34 @@
import { build } from "esbuild";
const platformModules = new Map([
[
"@quixos/web-studio-react-runtime",
"/__quixos/platform/web-studio-react-runtime/v1.mjs",
],
["react", "/__quixos/platform/react/v18.mjs"],
["react/jsx-runtime", "/__quixos/platform/react-jsx-runtime/v18.mjs"],
["react/jsx-dev-runtime", "/__quixos/platform/react-jsx-dev-runtime/v18.mjs"],
]);
await build({
entryPoints: ["dist/todo-component.js"],
outfile: "dist/todo-component.mjs",
bundle: true,
format: "esm",
platform: "browser",
target: "es2022",
sourcemap: true,
plugins: [
{
name: "quixos-platform-modules",
setup(buildApi) {
buildApi.onResolve({ filter: /.*/ }, (args) => {
const platformPath = platformModules.get(args.path);
return platformPath
? { path: platformPath, external: true }
: undefined;
});
},
},
],
});
-4
View File
@@ -1,4 +0,0 @@
declare module "*?browser-source" {
const source: string;
export default source;
}
+153 -302
View File
File diff suppressed because one or more lines are too long
-6
View File
@@ -1,6 +0,0 @@
// Generated from checked QX contracts. Do not edit.
import type {ObjectRef, InterfaceReference, ReadableField, WritableField} from "@quixos/web-studio-react-runtime";
export type Interface0 = InterfaceReference<"interface:task-data@1", {"title": WritableField<string>;"status": WritableField<string>;"priority": WritableField<string>;"notes": WritableField<string>;"dueDate": WritableField<string>;"energy": WritableField<string>}> ;
export type ReactResults = {"propsGet": {"data": Interface0}};
type CheckedComponent<K extends keyof ReactResults, C extends (props: {camino: ReactResults[K]; render: any; dispatch: (action: any) => void}) => unknown> = C;
type Component0 = CheckedComponent<"propsGet", typeof import("../todo-component.js")["default"]>;
+29 -20
View File
@@ -1,25 +1,28 @@
// Generated by the Quixos React platform contract. Do not edit.
declare module "@quixos/web-studio-react-runtime" {
import type * as React from "react";
export function useComponentOverlayContainer(): HTMLElement;
export function useComponentStyleRoot(): ShadowRoot;
export type ObjectRef<AtomId extends string> = string & {
readonly $quixosAtom: AtomId;
};
export type FieldCapability = {objectId: string; interfaceRevisionId: string; getOperationId: string; watchOperationId?: string; setOperationId?: string; inputKind?: "fields" | "value"};
export type ReadableField<T> = {readonly value?: T; readonly capability: FieldCapability};
/** set(T) uses the resolved capability: native CRDT fields send incremental edits;
* custom/manual setters receive semantic values. Storage provenance grants no authority. */
export type WritableField<T> = ReadableField<T> & {readonly $writeType?: (value: T) => T; readonly writable: true; readonly capability: FieldCapability & {setOperationId: string}};
export type LiveFieldProp<T> = ReadableField<T>;
export type InterfaceReference<I extends string, Fields> = {readonly $quixosRef: string; readonly interfaceRevisionId: I; readonly fields: Fields};
export type LiveFieldProp<T> = {
value: T;
source: {
objectId: string;
slotId: string;
valueType?: string;
storagePolicy?: string;
revision?: string | number | bigint;
crdtSnapshot?: {
type: string;
encoding: string;
payload: string;
};
};
};
export type ReactComponentHostProps<Action> = {
onAction?: (action: Action) => void;
fallback?: React.ReactNode;
fallback?: unknown;
className?: string;
style?: React.CSSProperties;
/** Optional extra action. The host still displays and reports errors by default. */
extraErrorAction?: (error: Error) => void;
style?: Record<string, string | number | undefined>;
onError?: (error: Error) => void;
};
export type ReactComponentImplementationProps<CaminoProps, RenderProps, Action> = {
camino: CaminoProps;
@@ -36,10 +39,16 @@ declare module "@quixos/web-studio-react-runtime" {
interfaceRevisionId: string,
operationId: string,
value?: unknown,
options?: {clientMutationId?: string; signal?: AbortSignal},
) => Promise<Result>;
export const h: typeof React.createElement;
export function useLiveField<T>(field: ReadableField<T>, options: {write: (value: T) => Promise<void>}): readonly [T, (value: T) => Promise<void>];
export function useLiveField<T>(field: WritableField<T>): readonly [T, (value: T) => Promise<void>];
export function useLiveField<T>(field: ReadableField<T>): readonly [T];
export const h: (...args: any[]) => any;
export const useLiveField: <T>(
field: LiveFieldProp<T>,
options?: {
reconcileRegister?: (state: {
confirmed: T;
optimistic: T;
pending: boolean;
}) => T;
},
) => [T, (value: T) => void | Promise<void>];
}
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export { createComponent as handler } from "../todo-react.impl.js";
export {createComponent as handler} from "../todo-react.impl.js";
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export { props as handler } from "../todo-react.impl.js";
export {props as handler} from "../todo-react.impl.js";
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export { props as handler } from "../todo-react.impl.js";
export {props as handler} from "../todo-react.impl.js";
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export { stopWatch as handler } from "../todo-react.impl.js";
export {stopWatch as handler} from "../todo-react.impl.js";
+1 -1
View File
@@ -1,2 +1,2 @@
// This adapter keeps the implementation file hand-authored.
export { source as handler } from "../todo-react.impl.js";
export {source as handler} from "../todo-react.impl.js";
+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({});
+14 -16
View File
@@ -1,17 +1,15 @@
// Generated by qx-scaffold-v1
import { servePackageRuntime } from "@quixos/camino-package-runtime";
import { createRuntime } from "./gen/qx.js";
import { handler as impl0 } from "./impl/createComponent.js";
import { handler as impl1 } from "./impl/sourceGet.js";
import { handler as impl2 } from "./impl/propsGet.js";
import { handler as impl3 } from "./impl/propsWatch.js";
import { handler as impl4 } from "./impl/propsWatchStop.js";
servePackageRuntime(
createRuntime({
createComponent: impl0,
sourceGet: impl1,
propsGet: impl2,
propsWatch: impl3,
propsWatchStop: impl4,
}),
);
import {servePackageRuntime} from "@quixos/camino-package-runtime";
import {createRuntime} from "./gen/qx.js";
import {handler as impl0} from "./impl/createComponent.js";
import {handler as impl1} from "./impl/sourceGet.js";
import {handler as impl2} from "./impl/propsGet.js";
import {handler as impl3} from "./impl/propsWatch.js";
import {handler as impl4} from "./impl/propsWatchStop.js";
servePackageRuntime(createRuntime({
"createComponent": impl0,
"sourceGet": impl1,
"propsGet": impl2,
"propsWatch": impl3,
"propsWatchStop": impl4,
}));
+57 -69
View File
@@ -1,11 +1,23 @@
import { useLiveField, type ReactComponentImplementationProps } from "@quixos/web-studio-react-runtime";
import {
useLiveField,
type LiveFieldProp,
type ReactComponentImplementationProps,
} from "@quixos/web-studio-react-runtime";
import type {
TodoReactComponentAction,
TodoReactComponentRenderProps,
} from "./gen/quixos.todo.TodoReactComponent.react.js";
import type { ReactResults } from "./gen/react-props.gen.js";
type TodoReactComponentCaminoProps = ReactResults["propsGet"];
type TodoReactComponentCaminoProps = {
task_id: string;
title: LiveFieldProp<string>;
status: LiveFieldProp<string>;
priority: LiveFieldProp<string>;
notes: LiveFieldProp<string>;
due_date: LiveFieldProp<string>;
energy: LiveFieldProp<string>;
display_label: string;
};
const palette = {
ink: "#28362d",
@@ -17,8 +29,9 @@ const palette = {
berry: "#a9544f",
};
const statusTone = (status: string) =>
status === "DONE" ? palette.moss : status === "ARCHIVED" ? palette.muted : "#52749a";
const statusTone = (status: string) => status === "DONE"
? palette.moss
: status === "ARCHIVED" ? palette.muted : "#52749a";
const fieldLabelStyle = {
display: "grid",
@@ -47,32 +60,34 @@ type TodoComponentImplementationProps = ReactComponentImplementationProps<
TodoReactComponentAction
>;
export default function TodoComponent({ camino: props, render, dispatch }: TodoComponentImplementationProps) {
const [title, setTitle] = useLiveField(props.data.fields.title);
const [status, setStatus] = useLiveField(props.data.fields.status);
const [priority, setPriority] = useLiveField(props.data.fields.priority);
const [notes, setNotes] = useLiveField(props.data.fields.notes);
const [dueDate, setDueDate] = useLiveField(props.data.fields.dueDate);
const [energy, setEnergy] = useLiveField(props.data.fields.energy);
export default function TodoComponent({
camino: props,
render,
dispatch,
}: TodoComponentImplementationProps) {
const [title, setTitle] = useLiveField(props.title);
const [status, setStatus] = useLiveField(props.status);
const [priority, setPriority] = useLiveField(props.priority);
const [notes, setNotes] = useLiveField(props.notes);
const [dueDate, setDueDate] = useLiveField(props.due_date);
const [energy, setEnergy] = useLiveField(props.energy);
const done = status === "DONE";
return (
<div
style={{
display: "grid",
gap: render.compact ? "9px" : "13px",
minWidth: 0,
height: "100%",
padding: render.compact ? "11px" : "15px",
border: render.selected ? `2px solid ${palette.honey}` : `1px solid ${palette.line}`,
borderRadius: "12px",
background: palette.cream,
boxShadow: render.selected ? "0 0 0 3px rgba(217,155,61,.14)" : "none",
color: palette.ink,
fontFamily: "Avenir Next, Nunito, ui-sans-serif, system-ui, sans-serif",
overflow: "auto",
}}
>
<div style={{
display: "grid",
gap: render.compact ? "9px" : "13px",
minWidth: 0,
height: "100%",
padding: render.compact ? "11px" : "15px",
border: render.selected ? `2px solid ${palette.honey}` : `1px solid ${palette.line}`,
borderRadius: "12px",
background: palette.cream,
boxShadow: render.selected ? "0 0 0 3px rgba(217,155,61,.14)" : "none",
color: palette.ink,
fontFamily: "Avenir Next, Nunito, ui-sans-serif, system-ui, sans-serif",
overflow: "auto",
}}>
<div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: "10px" }}>
<button
type="button"
@@ -93,16 +108,14 @@ export default function TodoComponent({ camino: props, render, dispatch }: TodoC
{done ? "✓" : ""}
</button>
<div style={{ display: "grid", flex: 1, gap: "3px", minWidth: 0 }}>
<strong
style={{
overflow: "hidden",
fontSize: render.compact ? "14px" : "17px",
lineHeight: 1.25,
textDecoration: done ? "line-through" : "none",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
}}
>
<strong style={{
overflow: "hidden",
fontSize: render.compact ? "14px" : "17px",
lineHeight: 1.25,
textDecoration: done ? "line-through" : "none",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
}}>
{title || "Untitled task"}
</strong>
<span style={{ color: statusTone(status), fontSize: "10px", fontWeight: 800, letterSpacing: ".08em" }}>
@@ -137,11 +150,7 @@ export default function TodoComponent({ camino: props, render, dispatch }: TodoC
<div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(112px, 1fr))", gap: "8px" }}>
<label style={fieldLabelStyle}>
Status
<select
style={controlStyle}
value={status}
onChange={(event: { currentTarget: HTMLSelectElement }) => void setStatus(event.currentTarget.value)}
>
<select style={controlStyle} value={status} onChange={(event: { currentTarget: HTMLSelectElement }) => void setStatus(event.currentTarget.value)}>
<option value="OPEN">Open</option>
<option value="DONE">Done</option>
<option value="ARCHIVED">Archived</option>
@@ -149,11 +158,7 @@ export default function TodoComponent({ camino: props, render, dispatch }: TodoC
</label>
<label style={fieldLabelStyle}>
Priority
<select
style={controlStyle}
value={priority}
onChange={(event: { currentTarget: HTMLSelectElement }) => void setPriority(event.currentTarget.value)}
>
<select style={controlStyle} value={priority} onChange={(event: { currentTarget: HTMLSelectElement }) => void setPriority(event.currentTarget.value)}>
<option value="LOW">Low</option>
<option value="NORMAL">Normal</option>
<option value="HIGH">High</option>
@@ -161,11 +166,7 @@ export default function TodoComponent({ camino: props, render, dispatch }: TodoC
</label>
<label style={fieldLabelStyle}>
Energy
<select
style={controlStyle}
value={energy}
onChange={(event: { currentTarget: HTMLSelectElement }) => void setEnergy(event.currentTarget.value)}
>
<select style={controlStyle} value={energy} onChange={(event: { currentTarget: HTMLSelectElement }) => void setEnergy(event.currentTarget.value)}>
<option value="LOW">Low</option>
<option value="MEDIUM">Medium</option>
<option value="HIGH">High</option>
@@ -173,12 +174,7 @@ export default function TodoComponent({ camino: props, render, dispatch }: TodoC
</label>
<label style={fieldLabelStyle}>
Due
<input
style={controlStyle}
type="date"
value={dueDate}
onInput={(event: { currentTarget: HTMLInputElement }) => void setDueDate(event.currentTarget.value)}
/>
<input style={controlStyle} type="date" value={dueDate} onInput={(event: { currentTarget: HTMLInputElement }) => void setDueDate(event.currentTarget.value)} />
</label>
</div>
<label style={fieldLabelStyle}>
@@ -201,16 +197,8 @@ export default function TodoComponent({ camino: props, render, dispatch }: TodoC
</div>
)}
<div
style={{
color: palette.muted,
fontSize: "10px",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
}}
>
{props.data.$quixosRef}
<div style={{ color: palette.muted, fontSize: "10px", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
{props.task_id}
</div>
</div>
);
+21 -7
View File
@@ -1,10 +1,24 @@
import componentSource from "./todo-component.js?browser-source";
import type { Contexts, Results } from "./gen/qx.js";
import fs from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
import type { Contexts } from "./gen/qx.js";
export const source = () => componentSource;
const componentSourcePath = path.join(path.dirname(fileURLToPath(import.meta.url)), "todo-component.mjs");
export const source = () => fs.readFile(componentSourcePath, "utf8");
export const createComponent = ({ objectId }: Contexts["createComponent"]) => objectId;
export const props = {
kind: "derived" as const,
get: async ({ ports }: Contexts["propsGet"]): Promise<Results["propsGet"]> => ({ data: ports.data.objectId }),
};
export const props = { kind: "derived" as const, get: async ({ objectId, ports }: Contexts["propsGet"]): Promise<Record<string, unknown>> => {
const tasks = await ports.subject.resolve();
if (tasks.length !== 1) throw new Error(`Task component has ${tasks.length} subjects`);
const [title, status, priority, titleLive, statusLive, priorityLive, notesLive, dueDateLive, energyLive] = await Promise.all([
ports.title.get(), ports.status.get(), ports.priority.get(),
ports.title.live(), ports.status.live(), ports.priority.live(),
ports.notes.live(), ports.dueDate.live(), ports.energy.live(),
]);
const priorityText = priority && priority !== "NORMAL" ? ` ${priority.toLowerCase()}` : "";
return {
task_id: tasks[0], component_id: objectId, title: titleLive, status: statusLive,
priority: priorityLive, notes: notesLive, due_date: dueDateLive, energy: energyLive,
display_label: `[${status || "OPEN"}]${priorityText} ${title || "Untitled task"}`,
};
}};
export const stopWatch = () => null;
+7 -2
View File
@@ -9,10 +9,15 @@
"forceConsistentCasingInFileNames": true,
"preserveSymlinks": true,
"resolveJsonModule": true,
"types": ["node"],
"types": [
"node"
],
"outDir": "dist",
"rootDir": "src",
"jsx": "react-jsx"
},
"include": ["src/**/*.ts", "src/**/*.tsx"]
"include": [
"src/**/*.ts",
"src/**/*.tsx"
]
}
+1 -1
View File
@@ -161,7 +161,7 @@ cacheEntries = {
"@connectrpc/connect@npm:2.1.2" = { filename = "@connectrpc-connect-npm-2.1.2-ab34825de3-4e15000890.zip"; hash = "sha512-ThUACJAjt1Lv1E+pQKWuHh+gDhvrxLoM7ScruTWSDYw7hbd0UOZErUQruMqaJ1sMFxNviWuo7/A2F4Ex2wHWFQ=="; };
"@esbuild/linux-arm64@npm:0.25.12" = { filename = "@esbuild-linux-arm64-npm-0.25.12-a5aaa0e70e-10c0.zip"; hash = "sha512-tm9zhnNR4GZv4A+Sgbt9jdCJ0iGlzvYxGCaxaScbhFH14mX7QWJRYaCvFCZB1dseApmaq6mNwbilL0wJnbB8tw=="; };
"@esbuild/linux-x64@npm:0.25.12" = { filename = "@esbuild-linux-x64-npm-0.25.12-07c7c22cce-10c0.zip"; hash = "sha512-U2QGT8ZIZN8q2WPSFDC32+sZGKgp49gvnHzIf/vKVR4xIzjcgBbjAIKI+FqfGBmGBWu8eCpS7lR9JDXdUHOFkw=="; };
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=cd2b04dc8c2daeea633bf8ecdd31d20fdc41f2ab" = { filename = "@quixos-camino-package-runtime-https-99aa94a9bf-7872db96f5.zip"; hash = "sha512-eHLblvUv7jzGJ45p9j7PY5UsK74OeyZp2Z36rC5ki0BlGUXgCHAzeJ6YvaWov64433kSLJT9NjkocOgUacVvZg=="; };
"@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=="; };
"@types/prop-types@npm:15.7.15" = { filename = "@types-prop-types-npm-15.7.15-cefe16a1fa-b59aad1ad1.zip"; hash = "sha512-tZqtGtGb8XM89ST9TmGBlsbHaQ9I7nCjJ+tFCkKquOigY/vlnKClcBrr4tktWCKSwPuEXqV0dPahX2mUsOJgsg=="; };
"@types/react@npm:18.3.31" = { filename = "@types-react-npm-18.3.31-d376eb19a5-44180549dd.zip"; hash = "sha512-RBgFSd0EX1Nuzs0545qs34KOdq3BxKkLEy9FPiPMNwxGSNkQKuQBFy69j9ixl3qQGjniFOU+x3FxsnUUtYjBeQ=="; };
+4 -4
View File
@@ -213,14 +213,14 @@ __metadata:
languageName: node
linkType: hard
"@quixos/camino-package-runtime@https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=cd2b04dc8c2daeea633bf8ecdd31d20fdc41f2ab":
"@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=cd2b04dc8c2daeea633bf8ecdd31d20fdc41f2ab"
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/7872db96f52fee3cc6278e69f63ecf63952c2bbe0e7b2669d99dfaac2e648b40651945e0087033789e98bda5a8bfae38df79122c94fd36392870e81469c56f66
checksum: 10c0/75b1ffcea9ba83015c935a52ac90045cd525eb07c7a4e2fe8e3e08c1d1c2c9fe5538c2889c22ebef7631f4d614bea9f7cf0dc039f766ffc6d4793cf61edc68fc
languageName: node
linkType: hard
@@ -228,7 +228,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@quixos/todo-react-runtime@workspace:."
dependencies:
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=cd2b04dc8c2daeea633bf8ecdd31d20fdc41f2ab"
"@quixos/camino-package-runtime": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git#commit=110e41b268c8ac309e6757f2af3331de417ff9b0"
"@types/node": "npm:^24"
"@types/react": "npm:^18.3.12"
esbuild: "npm:^0.25.12"