Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 110e41b268 | |||
| 2b7035fe81 | |||
| 79fbee2b32 | |||
| 8480674212 | |||
| 652ac8e53e | |||
| a2fe7e4f5e | |||
| 0907f97803 | |||
| ce6ae8f662 | |||
| 549c4539d5 | |||
| fa9e77e75c | |||
| a998690446 | |||
| 46c8950a75 | |||
| 2de080c09f | |||
| c15a8a51fa | |||
| d83f82c90f | |||
| b7b4a63155 | |||
| 04614be2c9 | |||
| 16b344c0ad | |||
| 385a5bd595 | |||
| 9771b0803e | |||
| 2dfba87179 | |||
| ab46f4f136 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos.git",
|
"sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos",
|
||||||
"sourceCommit": "64e5ed409717f2a7c59fe5d94ed0cf0dc7e24a2a",
|
"sourceCommit": "e25eee6ce4f13702b2454a9354bc79a29eb2e4a1",
|
||||||
"sourcePath": "quixos-instance/packages/camino-package-runtime",
|
"sourcePath": "quixos-instance/packages/camino-package-runtime",
|
||||||
"exportName": "camino-package-runtime",
|
"exportName": "camino-package-runtime",
|
||||||
"mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git"
|
"mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/camino-package-runtime.git"
|
||||||
|
|||||||
Binary file not shown.
Vendored
+84
@@ -0,0 +1,84 @@
|
|||||||
|
import { type Value } from "./camino/api_pb.js";
|
||||||
|
import { liveValue, type RuntimeHandler, type DerivedHandler } from "./index.js";
|
||||||
|
export type { QxObjectRef } from "./references.js";
|
||||||
|
declare const watchBrand: unique symbol;
|
||||||
|
export type QxWatchHandle = string & {
|
||||||
|
readonly [watchBrand]: true;
|
||||||
|
};
|
||||||
|
export type MessageBinding<T> = {
|
||||||
|
encode(value: T): Value;
|
||||||
|
decode(value: Value): T;
|
||||||
|
};
|
||||||
|
export type QxLiveValue = ReturnType<typeof liveValue>;
|
||||||
|
export declare const opaqueReactPropsBinding: MessageBinding<Record<string, unknown>>;
|
||||||
|
export type BindingValue<B> = B extends MessageBinding<infer T> ? T : never;
|
||||||
|
export type QxHandler<C, O> = (context: C) => O | Promise<O>;
|
||||||
|
export type QxDerived<C, O> = {
|
||||||
|
kind: "derived";
|
||||||
|
get: QxHandler<C, O>;
|
||||||
|
};
|
||||||
|
export type QxSession<C> = {
|
||||||
|
id: string;
|
||||||
|
run<T>(work: (context: C) => Promise<T>): Promise<T>;
|
||||||
|
close(): Promise<void>;
|
||||||
|
};
|
||||||
|
export type QxContextLifecycle<C> = {
|
||||||
|
signal?: AbortSignal;
|
||||||
|
openSession?: () => Promise<QxSession<C>>;
|
||||||
|
};
|
||||||
|
export declare const qxDerived: <C, O>(get: QxHandler<C, O>) => QxDerived<C, O>;
|
||||||
|
/** Versioned binding ABI. This mirrors the language-neutral value IR. */
|
||||||
|
export type QxValueType = {
|
||||||
|
kind: "builtin";
|
||||||
|
name: "unit" | "watch-handle";
|
||||||
|
} | {
|
||||||
|
kind: "scalar";
|
||||||
|
name: string;
|
||||||
|
} | {
|
||||||
|
kind: "message";
|
||||||
|
descriptorId: string;
|
||||||
|
} | {
|
||||||
|
kind: "record";
|
||||||
|
fields: Record<string, QxValueType>;
|
||||||
|
} | {
|
||||||
|
kind: "object-ref";
|
||||||
|
expectation: unknown;
|
||||||
|
} | {
|
||||||
|
kind: "optional" | "list";
|
||||||
|
value: QxValueType;
|
||||||
|
};
|
||||||
|
export type QxOperationSpec = {
|
||||||
|
id: string;
|
||||||
|
inputType: QxValueType;
|
||||||
|
outputType: QxValueType;
|
||||||
|
};
|
||||||
|
export type QxPortSpec = {
|
||||||
|
kind: "state";
|
||||||
|
id: string;
|
||||||
|
valueType: QxValueType;
|
||||||
|
primitives: string[];
|
||||||
|
} | {
|
||||||
|
kind: "edge";
|
||||||
|
id: string;
|
||||||
|
primitives: string[];
|
||||||
|
} | {
|
||||||
|
kind: "interface";
|
||||||
|
id: string;
|
||||||
|
operations: Record<string, QxOperationSpec>;
|
||||||
|
} | {
|
||||||
|
kind: "constructor";
|
||||||
|
id: string;
|
||||||
|
inputType: QxValueType;
|
||||||
|
};
|
||||||
|
export type QxHandlerSpec = {
|
||||||
|
inputType: QxValueType;
|
||||||
|
outputType: QxValueType;
|
||||||
|
eventType?: QxValueType;
|
||||||
|
ports: Record<string, QxPortSpec>;
|
||||||
|
};
|
||||||
|
export type QxMessages = Record<string, MessageBinding<any>>;
|
||||||
|
export declare const decodeQxValue: (type: QxValueType, value: Value | undefined, messages: QxMessages) => any;
|
||||||
|
export declare const encodeQxValue: (type: QxValueType, value: any, messages: QxMessages) => Value;
|
||||||
|
/** The sole unchecked cast connects generated contracts to the dynamic RPC runtime. */
|
||||||
|
export declare const bindQxHandler: <C, O>(spec: QxHandlerSpec, handler: QxHandler<C, O> | QxDerived<C, O>, messages: QxMessages) => RuntimeHandler | DerivedHandler;
|
||||||
|
//# sourceMappingURL=bindings.d.ts.map
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"bindings.d.ts","sourceRoot":"","sources":["../src/bindings.ts"],"names":[],"mappings":"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"}
|
||||||
Vendored
+174
@@ -0,0 +1,174 @@
|
|||||||
|
import { create } from "@bufbuild/protobuf";
|
||||||
|
import { ValueSchema, ObjectValueSchema } from "./camino/api_pb.js";
|
||||||
|
import { derived, jsToProtoValue, liveValue, protoValueToJs } from "./index.js";
|
||||||
|
import { assertReferenceFree, referenceToWire } from "./references.js";
|
||||||
|
const reactPropsDescriptor = "org.quixos.web-studio.ReactProps";
|
||||||
|
// Explicit temporary props exception, matching orch's RPC contract. Field shapes
|
||||||
|
// remain unchecked pending generics; ordinary messages and state do not gain it.
|
||||||
|
export const opaqueReactPropsBinding = {
|
||||||
|
encode(value) {
|
||||||
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
||||||
|
throw new Error("React props must be an object");
|
||||||
|
return jsToProtoValue(value);
|
||||||
|
},
|
||||||
|
decode(value) {
|
||||||
|
if (value.kind.case !== "objectValue")
|
||||||
|
throw new Error("React props must be an object");
|
||||||
|
return protoValueToJs(value);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export const qxDerived = (get) => ({ kind: "derived", get });
|
||||||
|
// Conversion belongs at the binding boundary. It does not add orchestrator validation.
|
||||||
|
export const decodeQxValue = (type, value, messages) => {
|
||||||
|
if (type.kind === "builtin" && type.name === "unit")
|
||||||
|
return null;
|
||||||
|
if (type.kind === "optional" && !value)
|
||||||
|
return null;
|
||||||
|
if (!value)
|
||||||
|
throw new Error("Missing QX wire value");
|
||||||
|
if (type.kind === "record") {
|
||||||
|
if (value.kind.case !== "objectValue")
|
||||||
|
throw new Error("Expected QX record");
|
||||||
|
const fields = value.kind.value.fields;
|
||||||
|
if (Object.keys(fields).some((name) => !Object.hasOwn(type.fields, name)))
|
||||||
|
throw new Error("Unexpected QX record field");
|
||||||
|
return Object.fromEntries(Object.entries(type.fields).map(([name, field]) => [name, decodeQxValue(field, fields[name], messages)]));
|
||||||
|
}
|
||||||
|
if (type.kind === "optional")
|
||||||
|
return value.kind.case === "nullValue" ? null : decodeQxValue(type.value, value, messages);
|
||||||
|
if (type.kind === "list") {
|
||||||
|
if (value.kind.case !== "listValue")
|
||||||
|
throw new Error("Expected QX list");
|
||||||
|
return value.kind.value.values.map((entry) => decodeQxValue(type.value, entry, messages));
|
||||||
|
}
|
||||||
|
if (type.kind === "message") {
|
||||||
|
if (type.descriptorId !== reactPropsDescriptor)
|
||||||
|
assertReferenceFree(protoValueToJs(value));
|
||||||
|
const decoded = requireMessage(messages, type.descriptorId).decode(value);
|
||||||
|
if (type.descriptorId !== reactPropsDescriptor)
|
||||||
|
assertReferenceFree(decoded);
|
||||||
|
return decoded;
|
||||||
|
}
|
||||||
|
if (type.kind === "object-ref") {
|
||||||
|
if (value.kind.case !== "refValue")
|
||||||
|
throw new Error("Expected a declared RPC object reference");
|
||||||
|
return protoValueToJs(value);
|
||||||
|
}
|
||||||
|
if (value.kind.case === "refValue")
|
||||||
|
throw new Error("Reference supplied to a non-reference value");
|
||||||
|
if (type.kind === "scalar") {
|
||||||
|
if (type.name === "int64" || type.name === "uint64") {
|
||||||
|
if (value.kind.case !== "integerValue")
|
||||||
|
throw new Error("Expected QX integer");
|
||||||
|
return BigInt(value.kind.value);
|
||||||
|
}
|
||||||
|
if (type.name === "bytes") {
|
||||||
|
if (value.kind.case !== "bytesValue")
|
||||||
|
throw new Error("Expected QX bytes");
|
||||||
|
return value.kind.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return protoValueToJs(value);
|
||||||
|
};
|
||||||
|
const requireMessage = (messages, id) => {
|
||||||
|
const binding = messages[id];
|
||||||
|
if (!binding)
|
||||||
|
throw new Error(`Missing message binding ${id}`);
|
||||||
|
return binding;
|
||||||
|
};
|
||||||
|
export const encodeQxValue = (type, value, messages) => {
|
||||||
|
if (type.kind === "builtin" && type.name === "unit")
|
||||||
|
return jsToProtoValue(null);
|
||||||
|
if (type.kind === "record") {
|
||||||
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
||||||
|
throw new Error("Expected QX record");
|
||||||
|
if (Object.keys(value).some((name) => !Object.hasOwn(type.fields, name)))
|
||||||
|
throw new Error("Unexpected QX record field");
|
||||||
|
const fields = Object.fromEntries(Object.entries(type.fields).map(([name, field]) => {
|
||||||
|
if (!Object.hasOwn(value, name) && field.kind !== "optional")
|
||||||
|
throw new Error(`Missing QX record field ${name}`);
|
||||||
|
return [name, encodeQxValue(field, value[name] ?? (field.kind === "optional" ? null : value[name]), messages)];
|
||||||
|
}));
|
||||||
|
return create(ValueSchema, { kind: { case: "objectValue", value: create(ObjectValueSchema, { fields }) } });
|
||||||
|
}
|
||||||
|
if (type.kind === "optional")
|
||||||
|
return value === null ? jsToProtoValue(null) : encodeQxValue(type.value, value, messages);
|
||||||
|
if (type.kind === "list")
|
||||||
|
return jsToProtoValue(value.map((entry) => liveValue(encodeQxValue(type.value, entry, messages))));
|
||||||
|
if (type.kind === "object-ref") {
|
||||||
|
referenceToWire(value);
|
||||||
|
return jsToProtoValue(value);
|
||||||
|
}
|
||||||
|
if (type.kind !== "message" || type.descriptorId !== reactPropsDescriptor)
|
||||||
|
assertReferenceFree(value);
|
||||||
|
if (type.kind === "message") {
|
||||||
|
const encoded = requireMessage(messages, type.descriptorId).encode(value);
|
||||||
|
if (type.descriptorId !== reactPropsDescriptor)
|
||||||
|
assertReferenceFree(protoValueToJs(encoded));
|
||||||
|
return encoded;
|
||||||
|
}
|
||||||
|
return jsToProtoValue(value);
|
||||||
|
};
|
||||||
|
const inputValue = (context, type) => {
|
||||||
|
if (type.kind === "message" || type.kind === "record")
|
||||||
|
return create(ValueSchema, { kind: { case: "objectValue",
|
||||||
|
value: create(ObjectValueSchema, { fields: context.inputProto }) } });
|
||||||
|
return context.inputProto.value;
|
||||||
|
};
|
||||||
|
const inputFields = (type, value, messages) => {
|
||||||
|
if (type.kind === "builtin" && type.name === "unit")
|
||||||
|
return {};
|
||||||
|
const encoded = encodeQxValue(type, value, messages);
|
||||||
|
if (type.kind === "message" || type.kind === "record") {
|
||||||
|
if (encoded.kind.case !== "objectValue")
|
||||||
|
throw new Error("Message inputs must encode an object value");
|
||||||
|
return Object.fromEntries(Object.entries(encoded.kind.value.fields).map(([key, entry]) => [key, liveValue(entry)]));
|
||||||
|
}
|
||||||
|
return { value: liveValue(encoded) };
|
||||||
|
};
|
||||||
|
/** The sole unchecked cast connects generated contracts to the dynamic RPC runtime. */
|
||||||
|
export const bindQxHandler = (spec, handler, messages) => {
|
||||||
|
const bindContext = (raw) => {
|
||||||
|
const ports = Object.fromEntries(Object.entries(spec.ports).map(([name, port]) => {
|
||||||
|
switch (port.kind) {
|
||||||
|
case "state": {
|
||||||
|
const state = raw.state(port.id);
|
||||||
|
return [name, {
|
||||||
|
...(port.primitives.includes("read") ? { get: async () => decodeQxValue(port.valueType, (await state.live()).$quixosValue, messages), live: () => state.live() } : {}),
|
||||||
|
...(port.primitives.includes("write") ? { set: async (value) => state.set(liveValue(encodeQxValue(port.valueType, value, messages))) } : {}),
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
case "edge": {
|
||||||
|
const edge = raw.edge(port.id);
|
||||||
|
return [name, { ...Object.fromEntries(port.primitives.map((primitive) => [primitive, edge[primitive]])),
|
||||||
|
...(port.primitives.includes("resolve") ? { collection: edge.collection } : {}),
|
||||||
|
...(port.primitives.includes("resolve") && port.primitives.includes("connect") && port.primitives.includes("disconnect") ? { replace: edge.replace } : {}) }];
|
||||||
|
}
|
||||||
|
case "interface": {
|
||||||
|
const target = raw.interface(port.id);
|
||||||
|
return [name, { objectId: target.objectId,
|
||||||
|
live: Object.fromEntries(Object.entries(port.operations).map(([name, operation]) => [name,
|
||||||
|
(input) => target.live(operation.id, inputFields(operation.inputType, input, messages)),
|
||||||
|
])),
|
||||||
|
...Object.fromEntries(Object.entries(port.operations).map(([name, operation]) => [name,
|
||||||
|
async (input) => decodeQxValue(operation.outputType, (await target.live(operation.id, inputFields(operation.inputType, input, messages))).$quixosValue, messages),
|
||||||
|
])) }];
|
||||||
|
}
|
||||||
|
case "constructor": return [name, { construct: (input) => raw.constructor(port.id).construct(inputFields(port.inputType, input, messages)) }];
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return { objectId: raw.objectId, signal: raw.signal,
|
||||||
|
...(raw.openSession ? { openSession: async () => {
|
||||||
|
const session = await raw.openSession();
|
||||||
|
return { id: session.id, close: () => session.close(),
|
||||||
|
run: (work) => session.run((next) => work(bindContext(next))) };
|
||||||
|
} } : {}),
|
||||||
|
input: decodeQxValue(spec.inputType, inputValue(raw, spec.inputType), messages), ports };
|
||||||
|
};
|
||||||
|
const execute = async (raw) => {
|
||||||
|
const context = bindContext(raw);
|
||||||
|
const value = await (typeof handler === "function" ? handler(context) : handler.get(context));
|
||||||
|
return liveValue(encodeQxValue(spec.eventType ?? spec.outputType, value, messages));
|
||||||
|
};
|
||||||
|
return typeof handler === "function" ? execute : derived(execute);
|
||||||
|
};
|
||||||
Vendored
+110
@@ -104,6 +104,14 @@ export type StateValueSource = Message<"camino.StateValueSource"> & {
|
|||||||
* @generated from field: uint64 revision = 5;
|
* @generated from field: uint64 revision = 5;
|
||||||
*/
|
*/
|
||||||
revision: bigint;
|
revision: bigint;
|
||||||
|
/**
|
||||||
|
* CRDT-backed state is still read as its materialized Value. The snapshot
|
||||||
|
* travels with the writable source identity so a client can retain and
|
||||||
|
* advance a local replica without exposing the document to package code.
|
||||||
|
*
|
||||||
|
* @generated from field: camino.CrdtValue crdt_snapshot = 6;
|
||||||
|
*/
|
||||||
|
crdtSnapshot?: CrdtValue | undefined;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message camino.StateValueSource.
|
* Describes the message camino.StateValueSource.
|
||||||
@@ -534,6 +542,78 @@ export type DisconnectEdgeResponse = Message<"camino.DisconnectEdgeResponse"> &
|
|||||||
* Use `create(DisconnectEdgeResponseSchema)` to create a new message.
|
* Use `create(DisconnectEdgeResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export declare const DisconnectEdgeResponseSchema: GenMessage<DisconnectEdgeResponse>;
|
export declare const DisconnectEdgeResponseSchema: GenMessage<DisconnectEdgeResponse>;
|
||||||
|
/**
|
||||||
|
* @generated from message camino.CollectionEntry
|
||||||
|
*/
|
||||||
|
export type CollectionEntry = Message<"camino.CollectionEntry"> & {
|
||||||
|
/**
|
||||||
|
* Existing entry identity to preserve; empty allocates a new canonical edge.
|
||||||
|
*
|
||||||
|
* @generated from field: string edge_id = 1;
|
||||||
|
*/
|
||||||
|
edgeId: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string target_object_id = 2;
|
||||||
|
*/
|
||||||
|
targetObjectId: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: camino.Value key = 3;
|
||||||
|
*/
|
||||||
|
key?: Value | undefined;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Describes the message camino.CollectionEntry.
|
||||||
|
* Use `create(CollectionEntrySchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export declare const CollectionEntrySchema: GenMessage<CollectionEntry>;
|
||||||
|
/**
|
||||||
|
* @generated from message camino.ReadCollectionResponse
|
||||||
|
*/
|
||||||
|
export type ReadCollectionResponse = Message<"camino.ReadCollectionResponse"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: uint64 revision = 1;
|
||||||
|
*/
|
||||||
|
revision: bigint;
|
||||||
|
/**
|
||||||
|
* @generated from field: repeated camino.CollectionEntry entries = 2;
|
||||||
|
*/
|
||||||
|
entries: CollectionEntry[];
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Describes the message camino.ReadCollectionResponse.
|
||||||
|
* Use `create(ReadCollectionResponseSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export declare const ReadCollectionResponseSchema: GenMessage<ReadCollectionResponse>;
|
||||||
|
/**
|
||||||
|
* @generated from message camino.ReplaceCollectionRequest
|
||||||
|
*/
|
||||||
|
export type ReplaceCollectionRequest = Message<"camino.ReplaceCollectionRequest"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: string object_id = 1;
|
||||||
|
*/
|
||||||
|
objectId: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string edge_type_id = 2;
|
||||||
|
*/
|
||||||
|
edgeTypeId: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string projection_id = 3;
|
||||||
|
*/
|
||||||
|
projectionId: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: uint64 expected_revision = 4;
|
||||||
|
*/
|
||||||
|
expectedRevision: bigint;
|
||||||
|
/**
|
||||||
|
* @generated from field: repeated camino.CollectionEntry entries = 5;
|
||||||
|
*/
|
||||||
|
entries: CollectionEntry[];
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Describes the message camino.ReplaceCollectionRequest.
|
||||||
|
* Use `create(ReplaceCollectionRequestSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export declare const ReplaceCollectionRequestSchema: GenMessage<ReplaceCollectionRequest>;
|
||||||
/**
|
/**
|
||||||
* @generated from message camino.ListOpsRequest
|
* @generated from message camino.ListOpsRequest
|
||||||
*/
|
*/
|
||||||
@@ -578,6 +658,12 @@ export type WatchObjectRequest = Message<"camino.WatchObjectRequest"> & {
|
|||||||
* @generated from field: bool include_snapshot = 3;
|
* @generated from field: bool include_snapshot = 3;
|
||||||
*/
|
*/
|
||||||
includeSnapshot: boolean;
|
includeSnapshot: boolean;
|
||||||
|
/**
|
||||||
|
* Managed runtimes must watch only their injected attachments.
|
||||||
|
*
|
||||||
|
* @generated from field: repeated string attachment_ids = 4;
|
||||||
|
*/
|
||||||
|
attachmentIds: string[];
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message camino.WatchObjectRequest.
|
* Describes the message camino.WatchObjectRequest.
|
||||||
@@ -688,6 +774,14 @@ export type CaminoEdge = Message<"camino.CaminoEdge"> & {
|
|||||||
* @generated from field: string created_at = 9;
|
* @generated from field: string created_at = 9;
|
||||||
*/
|
*/
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string first_key_json = 10;
|
||||||
|
*/
|
||||||
|
firstKeyJson: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string second_key_json = 11;
|
||||||
|
*/
|
||||||
|
secondKeyJson: string;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message camino.CaminoEdge.
|
* Describes the message camino.CaminoEdge.
|
||||||
@@ -816,6 +910,22 @@ export declare const CaminoService: GenService<{
|
|||||||
input: typeof DisconnectEdgeRequestSchema;
|
input: typeof DisconnectEdgeRequestSchema;
|
||||||
output: typeof DisconnectEdgeResponseSchema;
|
output: typeof DisconnectEdgeResponseSchema;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @generated from rpc camino.CaminoService.ReadCollection
|
||||||
|
*/
|
||||||
|
readCollection: {
|
||||||
|
methodKind: "unary";
|
||||||
|
input: typeof ResolveEdgeRequestSchema;
|
||||||
|
output: typeof ReadCollectionResponseSchema;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @generated from rpc camino.CaminoService.ReplaceCollection
|
||||||
|
*/
|
||||||
|
replaceCollection: {
|
||||||
|
methodKind: "unary";
|
||||||
|
input: typeof ReplaceCollectionRequestSchema;
|
||||||
|
output: typeof ReadCollectionResponseSchema;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* @generated from rpc camino.CaminoService.ListOps
|
* @generated from rpc camino.CaminoService.ListOps
|
||||||
*/
|
*/
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+23
-8
File diff suppressed because one or more lines are too long
Vendored
+34
@@ -34,6 +34,10 @@ export type AtomConformance = Message<"camino.AtomConformance"> & {
|
|||||||
* @generated from field: string interface_revision_id = 2;
|
* @generated from field: string interface_revision_id = 2;
|
||||||
*/
|
*/
|
||||||
interfaceRevisionId: string;
|
interfaceRevisionId: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string conformance_id = 3;
|
||||||
|
*/
|
||||||
|
conformanceId: string;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message camino.AtomConformance.
|
* Describes the message camino.AtomConformance.
|
||||||
@@ -68,6 +72,10 @@ export type StateAttachment = Message<"camino.StateAttachment"> & {
|
|||||||
* @generated from field: string default_value_json = 6;
|
* @generated from field: string default_value_json = 6;
|
||||||
*/
|
*/
|
||||||
defaultValueJson: string;
|
defaultValueJson: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string owner_conformance_id = 7;
|
||||||
|
*/
|
||||||
|
ownerConformanceId: string;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message camino.StateAttachment.
|
* Describes the message camino.StateAttachment.
|
||||||
@@ -127,6 +135,28 @@ export type EdgeEndpoint = Message<"camino.EdgeEndpoint"> & {
|
|||||||
* @generated from field: bool ordered = 5;
|
* @generated from field: bool ordered = 5;
|
||||||
*/
|
*/
|
||||||
ordered: boolean;
|
ordered: boolean;
|
||||||
|
/**
|
||||||
|
* Empty means restrict. Direction is the endpoint being deleted.
|
||||||
|
*
|
||||||
|
* @generated from field: string on_delete = 6;
|
||||||
|
*/
|
||||||
|
onDelete: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: bool retain_other = 7;
|
||||||
|
*/
|
||||||
|
retainOther: boolean;
|
||||||
|
/**
|
||||||
|
* Empty for sets/lists, otherwise string, boolean, or int64 map keys.
|
||||||
|
*
|
||||||
|
* @generated from field: string key_type = 8;
|
||||||
|
*/
|
||||||
|
keyType: string;
|
||||||
|
/**
|
||||||
|
* Explicit read-only dependency injection traversal, not mutation authority.
|
||||||
|
*
|
||||||
|
* @generated from field: bool public_traversal = 9;
|
||||||
|
*/
|
||||||
|
publicTraversal: boolean;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message camino.EdgeEndpoint.
|
* Describes the message camino.EdgeEndpoint.
|
||||||
@@ -153,6 +183,10 @@ export type EdgeAttachment = Message<"camino.EdgeAttachment"> & {
|
|||||||
* @generated from field: camino.EdgeEndpoint second = 4;
|
* @generated from field: camino.EdgeEndpoint second = 4;
|
||||||
*/
|
*/
|
||||||
second?: EdgeEndpoint | undefined;
|
second?: EdgeEndpoint | undefined;
|
||||||
|
/**
|
||||||
|
* @generated from field: string owner_conformance_id = 5;
|
||||||
|
*/
|
||||||
|
ownerConformanceId: string;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message camino.EdgeAttachment.
|
* Describes the message camino.EdgeAttachment.
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"schema_pb.d.ts","sourceRoot":"","sources":["../../src/camino/schema_pb.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"schema_pb.d.ts","sourceRoot":"","sources":["../../src/camino/schema_pb.ts"],"names":[],"mappings":"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"}
|
||||||
Vendored
+1
-1
@@ -5,7 +5,7 @@ import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
|||||||
/**
|
/**
|
||||||
* Describes the file camino/schema.proto.
|
* Describes the file camino/schema.proto.
|
||||||
*/
|
*/
|
||||||
export const file_camino_schema = /*@__PURE__*/ fileDesc("ChNjYW1pbm8vc2NoZW1hLnByb3RvEgZjYW1pbm8iNwoOQXRvbURlZmluaXRpb24SDwoHYXRvbV9pZBgBIAEoCRIUCgxkaXNwbGF5X25hbWUYAiABKAkiQQoPQXRvbUNvbmZvcm1hbmNlEg8KB2F0b21faWQYASABKAkSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAIgASgJIqQBCg9TdGF0ZUF0dGFjaG1lbnQSDwoHc2xvdF9pZBgBIAEoCRIYChBhdHRhY2hlZF9hdG9tX2lkGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCRIXCg92YWx1ZV90eXBlX2pzb24YBCABKAkSGwoTc3RvcmFnZV9wb2xpY3lfanNvbhgFIAEoCRIaChJkZWZhdWx0X3ZhbHVlX2pzb24YBiABKAkiUAoSRW5kcG9pbnRDb25zdHJhaW50EhEKB2F0b21faWQYASABKAlIABIfChVpbnRlcmZhY2VfcmV2aXNpb25faWQYAiABKAlIAEIGCgRraW5kIqYBCgxFZGdlRW5kcG9pbnQSFQoNcHJvamVjdGlvbl9pZBgBIAEoCRIUCgxkaXNwbGF5X25hbWUYAiABKAkSLgoKY29uc3RyYWludBgDIAEoCzIaLmNhbWluby5FbmRwb2ludENvbnN0cmFpbnQSKAoLY2FyZGluYWxpdHkYBCABKA4yEy5jYW1pbm8uQ2FyZGluYWxpdHkSDwoHb3JkZXJlZBgFIAEoCCKHAQoORWRnZUF0dGFjaG1lbnQSFAoMZWRnZV90eXBlX2lkGAEgASgJEhQKDGRpc3BsYXlfbmFtZRgCIAEoCRIjCgVmaXJzdBgDIAEoCzIULmNhbWluby5FZGdlRW5kcG9pbnQSJAoGc2Vjb25kGAQgASgLMhQuY2FtaW5vLkVkZ2VFbmRwb2ludCLsAQoPUGVyc2lzdGVuY2VQbGFuEhQKDHdvcmtzcGFjZV9pZBgBIAEoCRIdChV3b3Jrc3BhY2VfcmV2aXNpb25faWQYAiABKAkSJQoFYXRvbXMYAyADKAsyFi5jYW1pbm8uQXRvbURlZmluaXRpb24SLQoMY29uZm9ybWFuY2VzGAQgAygLMhcuY2FtaW5vLkF0b21Db25mb3JtYW5jZRInCgZzdGF0ZXMYBSADKAsyFy5jYW1pbm8uU3RhdGVBdHRhY2htZW50EiUKBWVkZ2VzGAYgAygLMhYuY2FtaW5vLkVkZ2VBdHRhY2htZW50KmgKC0NhcmRpbmFsaXR5EhsKF0NBUkRJTkFMSVRZX1VOU1BFQ0lGSUVEEAASEAoMT1BUSU9OQUxfT05FEAESDwoLRVhBQ1RMWV9PTkUQAhIICgRNQU5ZEAMSDwoLTUFOWV9VTklRVUUQBGIGcHJvdG8z");
|
export const file_camino_schema = /*@__PURE__*/ fileDesc("ChNjYW1pbm8vc2NoZW1hLnByb3RvEgZjYW1pbm8iNwoOQXRvbURlZmluaXRpb24SDwoHYXRvbV9pZBgBIAEoCRIUCgxkaXNwbGF5X25hbWUYAiABKAkiWQoPQXRvbUNvbmZvcm1hbmNlEg8KB2F0b21faWQYASABKAkSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAIgASgJEhYKDmNvbmZvcm1hbmNlX2lkGAMgASgJIsIBCg9TdGF0ZUF0dGFjaG1lbnQSDwoHc2xvdF9pZBgBIAEoCRIYChBhdHRhY2hlZF9hdG9tX2lkGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCRIXCg92YWx1ZV90eXBlX2pzb24YBCABKAkSGwoTc3RvcmFnZV9wb2xpY3lfanNvbhgFIAEoCRIaChJkZWZhdWx0X3ZhbHVlX2pzb24YBiABKAkSHAoUb3duZXJfY29uZm9ybWFuY2VfaWQYByABKAkiUAoSRW5kcG9pbnRDb25zdHJhaW50EhEKB2F0b21faWQYASABKAlIABIfChVpbnRlcmZhY2VfcmV2aXNpb25faWQYAiABKAlIAEIGCgRraW5kIvsBCgxFZGdlRW5kcG9pbnQSFQoNcHJvamVjdGlvbl9pZBgBIAEoCRIUCgxkaXNwbGF5X25hbWUYAiABKAkSLgoKY29uc3RyYWludBgDIAEoCzIaLmNhbWluby5FbmRwb2ludENvbnN0cmFpbnQSKAoLY2FyZGluYWxpdHkYBCABKA4yEy5jYW1pbm8uQ2FyZGluYWxpdHkSDwoHb3JkZXJlZBgFIAEoCBIRCglvbl9kZWxldGUYBiABKAkSFAoMcmV0YWluX290aGVyGAcgASgIEhAKCGtleV90eXBlGAggASgJEhgKEHB1YmxpY190cmF2ZXJzYWwYCSABKAgipQEKDkVkZ2VBdHRhY2htZW50EhQKDGVkZ2VfdHlwZV9pZBgBIAEoCRIUCgxkaXNwbGF5X25hbWUYAiABKAkSIwoFZmlyc3QYAyABKAsyFC5jYW1pbm8uRWRnZUVuZHBvaW50EiQKBnNlY29uZBgEIAEoCzIULmNhbWluby5FZGdlRW5kcG9pbnQSHAoUb3duZXJfY29uZm9ybWFuY2VfaWQYBSABKAki7AEKD1BlcnNpc3RlbmNlUGxhbhIUCgx3b3Jrc3BhY2VfaWQYASABKAkSHQoVd29ya3NwYWNlX3JldmlzaW9uX2lkGAIgASgJEiUKBWF0b21zGAMgAygLMhYuY2FtaW5vLkF0b21EZWZpbml0aW9uEi0KDGNvbmZvcm1hbmNlcxgEIAMoCzIXLmNhbWluby5BdG9tQ29uZm9ybWFuY2USJwoGc3RhdGVzGAUgAygLMhcuY2FtaW5vLlN0YXRlQXR0YWNobWVudBIlCgVlZGdlcxgGIAMoCzIWLmNhbWluby5FZGdlQXR0YWNobWVudCpoCgtDYXJkaW5hbGl0eRIbChdDQVJESU5BTElUWV9VTlNQRUNJRklFRBAAEhAKDE9QVElPTkFMX09ORRABEg8KC0VYQUNUTFlfT05FEAISCAoETUFOWRADEg8KC01BTllfVU5JUVVFEARiBnByb3RvMw");
|
||||||
/**
|
/**
|
||||||
* Describes the message camino.AtomDefinition.
|
* Describes the message camino.AtomDefinition.
|
||||||
* Use `create(AtomDefinitionSchema)` to create a new message.
|
* Use `create(AtomDefinitionSchema)` to create a new message.
|
||||||
|
|||||||
Vendored
+36
-8
@@ -1,4 +1,8 @@
|
|||||||
import http from "node:http";
|
import http from "node:http";
|
||||||
|
import { type QxObjectRef } from "./references.js";
|
||||||
|
export * from "./bindings.js";
|
||||||
|
export { relationshipMap, relationshipList, relationshipSet } from "./relationships.js";
|
||||||
|
export { createMigrationContext, migrationObjectId, serveMigration, type MigrationContext, type MigrationInput, type MigrationOutput, type MigrationEdge } from "./migration.js";
|
||||||
import { type Client, type ConnectRouter } from "@connectrpc/connect";
|
import { type Client, type ConnectRouter } from "@connectrpc/connect";
|
||||||
import { CaminoService, type Value } from "./camino/api_pb.js";
|
import { CaminoService, type Value } from "./camino/api_pb.js";
|
||||||
import { OrchestratorRuntime } from "./quixos/orch_pb.js";
|
import { OrchestratorRuntime } from "./quixos/orch_pb.js";
|
||||||
@@ -14,9 +18,7 @@ export type RuntimeDependency = {
|
|||||||
attachmentId: string;
|
attachmentId: string;
|
||||||
projectionId: string;
|
projectionId: string;
|
||||||
};
|
};
|
||||||
export declare const objectRef: (objectId: string) => {
|
export declare const objectRef: (reference: QxObjectRef) => QxObjectRef<string>;
|
||||||
$quixosRef: string;
|
|
||||||
};
|
|
||||||
export declare const liveValue: (value: Value) => {
|
export declare const liveValue: (value: Value) => {
|
||||||
$quixosValue: Value;
|
$quixosValue: Value;
|
||||||
};
|
};
|
||||||
@@ -34,20 +36,37 @@ export type StatePort<T = unknown> = {
|
|||||||
export type EdgePort = {
|
export type EdgePort = {
|
||||||
edgeTypeId: string;
|
edgeTypeId: string;
|
||||||
projectionId: string;
|
projectionId: string;
|
||||||
resolve(): Promise<string[]>;
|
resolve(): Promise<QxObjectRef[]>;
|
||||||
connect(targetObjectId: string): Promise<void>;
|
connect(target: QxObjectRef): Promise<void>;
|
||||||
|
disconnect(target: QxObjectRef): Promise<void>;
|
||||||
|
collection(): Promise<RelationshipCollection>;
|
||||||
|
replace(entries: RelationshipEntry[], expectedRevision: bigint): Promise<RelationshipCollection>;
|
||||||
|
};
|
||||||
|
export type RelationshipEntry<T extends QxObjectRef = QxObjectRef> = {
|
||||||
|
edgeId?: string;
|
||||||
|
target: T;
|
||||||
|
key?: string | boolean | bigint;
|
||||||
|
};
|
||||||
|
export type RelationshipCollection<T extends QxObjectRef = QxObjectRef> = {
|
||||||
|
revision: bigint;
|
||||||
|
entries: RelationshipEntry<T>[];
|
||||||
};
|
};
|
||||||
export type InterfacePort = {
|
export type InterfacePort = {
|
||||||
|
objectId: QxObjectRef;
|
||||||
interfaceRevisionId: string;
|
interfaceRevisionId: string;
|
||||||
invoke(operationId: string, input?: Record<string, unknown>): Promise<unknown>;
|
invoke(operationId: string, input?: Record<string, unknown>): Promise<unknown>;
|
||||||
|
live(operationId: string, input?: Record<string, unknown>): Promise<ReturnType<typeof liveValue>>;
|
||||||
};
|
};
|
||||||
export type ConstructorPort = {
|
export type ConstructorPort = {
|
||||||
atomId: string;
|
atomId: string;
|
||||||
construct(input?: Record<string, unknown>): Promise<string>;
|
construct(input?: Record<string, unknown>): Promise<QxObjectRef>;
|
||||||
};
|
};
|
||||||
export type RuntimePort = StatePort | EdgePort | InterfacePort | ConstructorPort;
|
export type RuntimePort = StatePort | EdgePort | InterfacePort | ConstructorPort;
|
||||||
export type RuntimeContext = {
|
export type RuntimeContext = {
|
||||||
objectId: string;
|
/** Cooperative cancellation. Completion is acknowledged only after the handler returns. */
|
||||||
|
signal?: AbortSignal;
|
||||||
|
openSession?: () => Promise<RuntimeSession>;
|
||||||
|
objectId: QxObjectRef;
|
||||||
input: Record<string, unknown>;
|
input: Record<string, unknown>;
|
||||||
inputProto: Record<string, Value>;
|
inputProto: Record<string, Value>;
|
||||||
ports: ReadonlyMap<string, RuntimePort>;
|
ports: ReadonlyMap<string, RuntimePort>;
|
||||||
@@ -56,6 +75,16 @@ export type RuntimeContext = {
|
|||||||
interface(portId: string): InterfacePort;
|
interface(portId: string): InterfacePort;
|
||||||
constructor(portId: string): ConstructorPort;
|
constructor(portId: string): ConstructorPort;
|
||||||
};
|
};
|
||||||
|
export type RuntimeSession = {
|
||||||
|
id: string;
|
||||||
|
run<T>(work: (context: RuntimeContext) => Promise<T>): Promise<T>;
|
||||||
|
/** Close the external resource first, then close its host retention/session. */
|
||||||
|
close(): Promise<void>;
|
||||||
|
};
|
||||||
|
export declare class RuntimeAuthorityError extends Error {
|
||||||
|
readonly retryable: boolean;
|
||||||
|
constructor(message: string);
|
||||||
|
}
|
||||||
export declare const createRuntimeContext: (camino: CaminoClient, orch: OrchClient, request: RuntimeRequest) => RuntimeContext;
|
export declare const createRuntimeContext: (camino: CaminoClient, orch: OrchClient, request: RuntimeRequest) => RuntimeContext;
|
||||||
export type RuntimeHandler = (context: RuntimeContext) => unknown | Promise<unknown>;
|
export type RuntimeHandler = (context: RuntimeContext) => unknown | Promise<unknown>;
|
||||||
export type DerivedHandler = {
|
export type DerivedHandler = {
|
||||||
@@ -78,5 +107,4 @@ type RuntimeRequest = {
|
|||||||
input: Record<string, Value>;
|
input: Record<string, Value>;
|
||||||
dependencies: import("./quixos/refs_pb.js").InjectedDependency[];
|
dependencies: import("./quixos/refs_pb.js").InjectedDependency[];
|
||||||
};
|
};
|
||||||
export {};
|
|
||||||
//# sourceMappingURL=index.d.ts.map
|
//# sourceMappingURL=index.d.ts.map
|
||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAoC,KAAK,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAExG,OAAO,EACL,aAAa,EAOb,KAAK,KAAK,EACX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAU1D,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AACxD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AA+BnF,eAAO,MAAM,SAAS,GAAI,UAAU,MAAM;;CAA+B,CAAC;AAC1E,eAAO,MAAM,SAAS,GAAI,OAAO,KAAK;;CAA8B,CAAC;AAErE,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,KAoC/C,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,KAAK,GAAG,SAAS,KAAG,OAoBzD,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;;CACmC,CAAC;AAEjG,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,OAAO,IAAI;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IAClB,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC;IAC9C,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7B,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD,CAAC;AACF,MAAM,MAAM,aAAa,GAAG;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChF,CAAC;AACF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7D,CAAC;AACF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,eAAe,CAAC;AAEjF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAClC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACxC,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC/B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC;IACzC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC;CAC9C,CAAC;AAOF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,YAAY,EACpB,MAAM,UAAU,EAChB,SAAS,cAAc,KACtB,cA2FF,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AACrF,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,cAAc,CAAA;CAAE,CAAC;AACtE,eAAO,MAAM,OAAO,GAAI,KAAK,cAAc,KAAG,cAA4C,CAAC;AAyB3F,eAAO,MAAM,0BAA0B,GAAI,QAAQ;IACjD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAAC,CAAC;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,MAsBS,QAAQ,aAAa,kBA0I9B,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,QAAQ;IAC1C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAAC,CAAC;CAC1D,yEAaA,CAAC;AACF,KAAK,cAAc,GAAG;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7B,YAAY,EAAE,OAAO,qBAAqB,EAAE,kBAAkB,EAAE,CAAC;CAClE,CAAC"}
|
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
||||||
Vendored
+324
-130
@@ -1,6 +1,12 @@
|
|||||||
import http from "node:http";
|
import http from "node:http";
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
|
import { createInvocationRegistry } from "./invocations.js";
|
||||||
|
import { isObjectReference, referenceFromWire, referenceToWire, assertReferenceFree } from "./references.js";
|
||||||
|
export * from "./bindings.js";
|
||||||
|
export { relationshipMap, relationshipList, relationshipSet } from "./relationships.js";
|
||||||
import { AsyncLocalStorage } from "node:async_hooks";
|
import { AsyncLocalStorage } from "node:async_hooks";
|
||||||
import { randomUUID } from "node:crypto";
|
import { createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
||||||
|
export { createMigrationContext, migrationObjectId, serveMigration } from "./migration.js";
|
||||||
import { create, equals } from "@bufbuild/protobuf";
|
import { create, equals } from "@bufbuild/protobuf";
|
||||||
import { Code, ConnectError, createClient } from "@connectrpc/connect";
|
import { Code, ConnectError, createClient } from "@connectrpc/connect";
|
||||||
import { connectNodeAdapter, createConnectTransport } from "@connectrpc/connect-node";
|
import { connectNodeAdapter, createConnectTransport } from "@connectrpc/connect-node";
|
||||||
@@ -23,9 +29,11 @@ const base64ToBytes = (value) => Buffer.from(value, "base64");
|
|||||||
const isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
const isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
||||||
const isWrappedValue = (value) => isRecord(value) && "$quixosValue" in value &&
|
const isWrappedValue = (value) => isRecord(value) && "$quixosValue" in value &&
|
||||||
isRecord(value.$quixosValue) && value.$quixosValue.$typeName === "camino.Value";
|
isRecord(value.$quixosValue) && value.$quixosValue.$typeName === "camino.Value";
|
||||||
export const objectRef = (objectId) => ({ $quixosRef: objectId });
|
export const objectRef = (reference) => { referenceToWire(reference); return reference; };
|
||||||
export const liveValue = (value) => ({ $quixosValue: value });
|
export const liveValue = (value) => ({ $quixosValue: value });
|
||||||
export const jsToProtoValue = (value) => {
|
export const jsToProtoValue = (value) => {
|
||||||
|
if (isObjectReference(value))
|
||||||
|
return create(ValueSchema, { kind: { case: "refValue", value: create(RefValueSchema, { objectId: referenceToWire(value) }) } });
|
||||||
if (isWrappedValue(value))
|
if (isWrappedValue(value))
|
||||||
return value.$quixosValue;
|
return value.$quixosValue;
|
||||||
if (value === null || value === undefined) {
|
if (value === null || value === undefined) {
|
||||||
@@ -46,11 +54,8 @@ export const jsToProtoValue = (value) => {
|
|||||||
kind: { case: "listValue", value: create(ListValueSchema, { values: value.map(jsToProtoValue) }) },
|
kind: { case: "listValue", value: create(ListValueSchema, { values: value.map(jsToProtoValue) }) },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (isRecord(value) && typeof value.$quixosRef === "string") {
|
if (isRecord(value) && "$quixosRef" in value)
|
||||||
return create(ValueSchema, {
|
throw new Error("Raw ID wrappers are not object references");
|
||||||
kind: { case: "refValue", value: create(RefValueSchema, { objectId: value.$quixosRef }) },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (isRecord(value) && typeof value.$quixosCrdtType === "string" &&
|
if (isRecord(value) && typeof value.$quixosCrdtType === "string" &&
|
||||||
typeof value.$quixosCrdtPayload === "string") {
|
typeof value.$quixosCrdtPayload === "string") {
|
||||||
return create(ValueSchema, {
|
return create(ValueSchema, {
|
||||||
@@ -78,7 +83,7 @@ export const protoValueToJs = (value) => {
|
|||||||
case "stringValue":
|
case "stringValue":
|
||||||
case "integerValue": return value.kind.value;
|
case "integerValue": return value.kind.value;
|
||||||
case "bytesValue": return bytesToBase64(value.kind.value);
|
case "bytesValue": return bytesToBase64(value.kind.value);
|
||||||
case "refValue": return value.kind.value.objectId;
|
case "refValue": return referenceFromWire(value.kind.value.objectId);
|
||||||
case "listValue": return value.kind.value.values.map(protoValueToJs);
|
case "listValue": return value.kind.value.values.map(protoValueToJs);
|
||||||
case "objectValue": return Object.fromEntries(Object.entries(value.kind.value.fields).map(([key, entry]) => [key, protoValueToJs(entry)]));
|
case "objectValue": return Object.fromEntries(Object.entries(value.kind.value.fields).map(([key, entry]) => [key, protoValueToJs(entry)]));
|
||||||
case "crdtValue": return {
|
case "crdtValue": return {
|
||||||
@@ -89,6 +94,10 @@ export const protoValueToJs = (value) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const protoFieldsToJs = (fields) => Object.fromEntries(Object.entries(fields).map(([key, value]) => [key, protoValueToJs(value)]));
|
export const protoFieldsToJs = (fields) => Object.fromEntries(Object.entries(fields).map(([key, value]) => [key, protoValueToJs(value)]));
|
||||||
|
export class RuntimeAuthorityError extends Error {
|
||||||
|
retryable;
|
||||||
|
constructor(message) { super(message); this.name = "RuntimeAuthorityError"; this.retryable = /WORKSPACE_FENCED|STALE_EPOCH/.test(message); }
|
||||||
|
}
|
||||||
const targetForEdge = (edge, projectionId) => edge.firstProjectionId === projectionId ? edge.secondObjectId : edge.firstObjectId;
|
const targetForEdge = (edge, projectionId) => edge.firstProjectionId === projectionId ? edge.secondObjectId : edge.firstObjectId;
|
||||||
export const createRuntimeContext = (camino, orch, request) => {
|
export const createRuntimeContext = (camino, orch, request) => {
|
||||||
const ports = new Map();
|
const ports = new Map();
|
||||||
@@ -96,21 +105,23 @@ export const createRuntimeContext = (camino, orch, request) => {
|
|||||||
switch (dependency.binding.case) {
|
switch (dependency.binding.case) {
|
||||||
case "stateSlotId": {
|
case "stateSlotId": {
|
||||||
const slotId = dependency.binding.value;
|
const slotId = dependency.binding.value;
|
||||||
|
const dependencyObjectId = dependency.objectId || request.objectId;
|
||||||
const state = {
|
const state = {
|
||||||
slotId,
|
slotId,
|
||||||
async get() {
|
async get() {
|
||||||
await recordDependency({ kind: "state", objectId: request.objectId, attachmentId: slotId });
|
await recordDependency({ kind: "state", objectId: dependencyObjectId, attachmentId: slotId });
|
||||||
return protoValueToJs((await camino.readState({ objectId: request.objectId, slotId })).value);
|
return protoValueToJs((await camino.readState({ objectId: dependencyObjectId, slotId })).value);
|
||||||
},
|
},
|
||||||
async live() {
|
async live() {
|
||||||
await recordDependency({ kind: "state", objectId: request.objectId, attachmentId: slotId });
|
await recordDependency({ kind: "state", objectId: dependencyObjectId, attachmentId: slotId });
|
||||||
const value = await camino.readState({ objectId: request.objectId, slotId });
|
const value = await camino.readState({ objectId: dependencyObjectId, slotId });
|
||||||
if (!value.value)
|
if (!value.value)
|
||||||
throw new Error(`State ${slotId} returned no value`);
|
throw new Error(`State ${slotId} returned no value`);
|
||||||
return liveValue(value.value);
|
return liveValue(value.value);
|
||||||
},
|
},
|
||||||
async set(value) {
|
async set(value) {
|
||||||
await camino.writeState({ objectId: request.objectId, slotId, value: jsToProtoValue(value) });
|
assertReferenceFree(isWrappedValue(value) ? protoValueToJs(value.$quixosValue) : value);
|
||||||
|
await camino.writeState({ objectId: dependencyObjectId, slotId, value: jsToProtoValue(value) });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ports.set(dependency.portId, state);
|
ports.set(dependency.portId, state);
|
||||||
@@ -118,34 +129,86 @@ export const createRuntimeContext = (camino, orch, request) => {
|
|||||||
}
|
}
|
||||||
case "edge": {
|
case "edge": {
|
||||||
const { edgeTypeId, projectionId } = dependency.binding.value;
|
const { edgeTypeId, projectionId } = dependency.binding.value;
|
||||||
|
const dependencyObjectId = dependency.objectId || request.objectId;
|
||||||
|
const collectionResult = (response) => ({ revision: response.revision,
|
||||||
|
entries: response.entries.map((entry) => ({ edgeId: entry.edgeId, target: referenceFromWire(entry.targetObjectId),
|
||||||
|
...(entry.key ? { key: entry.key.kind.case === "integerValue" ? BigInt(entry.key.kind.value) : protoValueToJs(entry.key) } : {}) })) });
|
||||||
const edge = {
|
const edge = {
|
||||||
edgeTypeId,
|
edgeTypeId,
|
||||||
projectionId,
|
projectionId,
|
||||||
async resolve() {
|
async collection() {
|
||||||
await recordDependency({ kind: "edge", objectId: request.objectId, attachmentId: edgeTypeId, projectionId });
|
await recordDependency({ kind: "edge", objectId: dependencyObjectId, attachmentId: edgeTypeId, projectionId });
|
||||||
const result = await camino.resolveEdge({ objectId: request.objectId, edgeTypeId, projectionId });
|
return collectionResult(await camino.readCollection({ objectId: dependencyObjectId, edgeTypeId, projectionId }));
|
||||||
return result.edges.map((entry) => targetForEdge(entry, projectionId));
|
|
||||||
},
|
},
|
||||||
async connect(targetObjectId) {
|
async replace(entries, expectedRevision) {
|
||||||
await camino.connectEdge({ objectId: request.objectId, edgeTypeId, projectionId, targetObjectId });
|
return collectionResult(await camino.replaceCollection({ objectId: dependencyObjectId, edgeTypeId, projectionId, expectedRevision,
|
||||||
|
entries: entries.map((entry) => {
|
||||||
|
assertReferenceFree(entry.key);
|
||||||
|
return { edgeId: entry.edgeId ?? "", targetObjectId: referenceToWire(entry.target), key: entry.key === undefined ? undefined : jsToProtoValue(entry.key) };
|
||||||
|
}) }));
|
||||||
|
},
|
||||||
|
async resolve() {
|
||||||
|
await recordDependency({ kind: "edge", objectId: dependencyObjectId, attachmentId: edgeTypeId, projectionId });
|
||||||
|
const result = await camino.resolveEdge({ objectId: dependencyObjectId, edgeTypeId, projectionId });
|
||||||
|
return result.edges.map((entry) => referenceFromWire(targetForEdge(entry, projectionId)));
|
||||||
|
},
|
||||||
|
async connect(target) {
|
||||||
|
const targetObjectId = referenceToWire(target);
|
||||||
|
await camino.connectEdge({ objectId: dependencyObjectId, edgeTypeId, projectionId, targetObjectId });
|
||||||
|
},
|
||||||
|
async disconnect(target) {
|
||||||
|
const targetObjectId = referenceToWire(target);
|
||||||
|
const result = await camino.resolveEdge({ objectId: dependencyObjectId, edgeTypeId, projectionId });
|
||||||
|
for (const entry of result.edges) {
|
||||||
|
if (targetForEdge(entry, projectionId) === targetObjectId)
|
||||||
|
await camino.disconnectEdge({ edgeId: entry.id });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ports.set(dependency.portId, edge);
|
ports.set(dependency.portId, edge);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "receiverInterfaceRevisionId": {
|
case "interfaceRevisionId": {
|
||||||
const interfaceRevisionId = dependency.binding.value;
|
const interfaceRevisionId = dependency.binding.value;
|
||||||
|
const dependencyObjectId = dependency.objectId || request.objectId;
|
||||||
|
const invoke = async (operationId, input) => {
|
||||||
|
const response = await orch.invokeCapability({
|
||||||
|
capability: create(CapabilityRefSchema, { interfaceRevisionId, operationId }),
|
||||||
|
objectId: dependencyObjectId,
|
||||||
|
input: Object.fromEntries(Object.entries(input).map(([key, value]) => [key, jsToProtoValue(value)])),
|
||||||
|
});
|
||||||
|
if (!response.ok)
|
||||||
|
throw new Error(response.error || `Capability ${operationId} failed`);
|
||||||
|
for (const dependency of response.dependencies) {
|
||||||
|
if (dependency.kind === "state") {
|
||||||
|
await recordDependency({
|
||||||
|
kind: "state",
|
||||||
|
objectId: dependency.objectId,
|
||||||
|
attachmentId: dependency.attachmentId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (dependency.kind === "edge") {
|
||||||
|
await recordDependency({
|
||||||
|
kind: "edge",
|
||||||
|
objectId: dependency.objectId,
|
||||||
|
attachmentId: dependency.attachmentId,
|
||||||
|
projectionId: dependency.projectionId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response.result;
|
||||||
|
};
|
||||||
const capability = {
|
const capability = {
|
||||||
|
objectId: referenceFromWire(dependencyObjectId),
|
||||||
interfaceRevisionId,
|
interfaceRevisionId,
|
||||||
async invoke(operationId, input = {}) {
|
async invoke(operationId, input = {}) {
|
||||||
const response = await orch.invokeCapability({
|
return protoValueToJs(await invoke(operationId, input));
|
||||||
capability: create(CapabilityRefSchema, { interfaceRevisionId, operationId }),
|
},
|
||||||
objectId: request.objectId,
|
async live(operationId, input = {}) {
|
||||||
input: Object.fromEntries(Object.entries(input).map(([key, value]) => [key, jsToProtoValue(value)])),
|
const value = await invoke(operationId, input);
|
||||||
});
|
if (!value)
|
||||||
if (!response.ok)
|
throw new Error(`Capability ${operationId} returned no value`);
|
||||||
throw new Error(response.error || `Capability ${operationId} failed`);
|
return liveValue(value);
|
||||||
return protoValueToJs(response.result);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ports.set(dependency.portId, capability);
|
ports.set(dependency.portId, capability);
|
||||||
@@ -162,7 +225,7 @@ export const createRuntimeContext = (camino, orch, request) => {
|
|||||||
});
|
});
|
||||||
if (!response.object)
|
if (!response.object)
|
||||||
throw new Error(`Constructor ${atomId} returned no object`);
|
throw new Error(`Constructor ${atomId} returned no object`);
|
||||||
return response.object.id;
|
return referenceFromWire(response.object.id);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ports.set(dependency.portId, constructor);
|
ports.set(dependency.portId, constructor);
|
||||||
@@ -176,7 +239,7 @@ export const createRuntimeContext = (camino, orch, request) => {
|
|||||||
return port;
|
return port;
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
objectId: request.objectId,
|
objectId: referenceFromWire(request.objectId),
|
||||||
input: protoFieldsToJs(request.input),
|
input: protoFieldsToJs(request.input),
|
||||||
inputProto: request.input,
|
inputProto: request.input,
|
||||||
ports,
|
ports,
|
||||||
@@ -200,9 +263,12 @@ const protoDependencies = (dependencies) => dependencies.map((entry) => create(D
|
|||||||
projectionId: entry.kind === "edge" ? entry.projectionId : "",
|
projectionId: entry.kind === "edge" ? entry.projectionId : "",
|
||||||
}));
|
}));
|
||||||
export const createPackageRuntimeRoutes = (config) => {
|
export const createPackageRuntimeRoutes = (config) => {
|
||||||
|
const invocations = createInvocationRegistry();
|
||||||
const headers = {};
|
const headers = {};
|
||||||
if (process.env.CAMINO_RUNTIME_AUTH_TOKEN) {
|
const processToken = process.env.CAMINO_RUNTIME_AUTH_TOKEN ?? (process.env.CAMINO_RUNTIME_AUTH_TOKEN_FILE
|
||||||
headers["x-camino-runtime-token"] = process.env.CAMINO_RUNTIME_AUTH_TOKEN;
|
? readFileSync(process.env.CAMINO_RUNTIME_AUTH_TOKEN_FILE, "utf8").trim() : "");
|
||||||
|
if (processToken) {
|
||||||
|
headers["x-camino-runtime-token"] = processToken;
|
||||||
}
|
}
|
||||||
else if (process.env.CAMINO_RUNTIME_AUTH_REQUIRED === "1") {
|
else if (process.env.CAMINO_RUNTIME_AUTH_REQUIRED === "1") {
|
||||||
throw new Error("CAMINO_RUNTIME_AUTH_TOKEN is required");
|
throw new Error("CAMINO_RUNTIME_AUTH_TOKEN is required");
|
||||||
@@ -221,22 +287,123 @@ export const createPackageRuntimeRoutes = (config) => {
|
|||||||
baseUrl: config.orchUrl ?? process.env.QUIXOS_ORCH_URL ?? "http://127.0.0.1:7311",
|
baseUrl: config.orchUrl ?? process.env.QUIXOS_ORCH_URL ?? "http://127.0.0.1:7311",
|
||||||
httpVersion: "1.1",
|
httpVersion: "1.1",
|
||||||
}));
|
}));
|
||||||
|
const authenticateInstance = (header) => {
|
||||||
|
if (!process.env.QUIXOS_RUNTIME_INSTANCE_ID)
|
||||||
|
return; // standalone development ABI
|
||||||
|
const supplied = Buffer.from(header.get("x-quixos-instance-token") ?? "");
|
||||||
|
const expected = Buffer.from(processToken);
|
||||||
|
if (!expected.length || supplied.length !== expected.length || !timingSafeEqual(supplied, expected)) {
|
||||||
|
throw new ConnectError("Invalid runtime instance credential", Code.Unauthenticated);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const clientsFor = (request) => {
|
||||||
|
const context = request.context;
|
||||||
|
if (process.env.QUIXOS_RUNTIME_INSTANCE_ID && (!context?.grant || context.instanceId !== process.env.QUIXOS_RUNTIME_INSTANCE_ID || !context.workspaceEpoch)) {
|
||||||
|
throw new ConnectError("Managed invocation requires an exact instance and epoch grant", Code.Unauthenticated);
|
||||||
|
}
|
||||||
|
if (!context?.grant)
|
||||||
|
return { camino, orch };
|
||||||
|
const transport = (url) => createConnectTransport({ baseUrl: url, httpVersion: "1.1", interceptors: [(next) => async (call) => {
|
||||||
|
call.header.set("x-quixos-invocation-grant", context.grant);
|
||||||
|
call.header.set("x-camino-runtime-token", processToken);
|
||||||
|
return next(call);
|
||||||
|
}] });
|
||||||
|
return {
|
||||||
|
camino: createClient(CaminoService, transport(config.caminoUrl ?? process.env.CAMINO_URL ?? "http://127.0.0.1:7310")),
|
||||||
|
orch: createClient(OrchestratorRuntime, transport(config.orchUrl ?? process.env.QUIXOS_ORCH_URL ?? "http://127.0.0.1:7311")),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const runtimeControl = async (operation, input) => {
|
||||||
|
const response = await fetch(`${config.caminoUrl ?? process.env.CAMINO_URL ?? "http://127.0.0.1:7310"}/__runtime/${operation}`, {
|
||||||
|
method: "POST", headers: { "content-type": "application/json", "x-camino-runtime-token": processToken }, body: JSON.stringify(input), signal: AbortSignal.timeout(10_000),
|
||||||
|
});
|
||||||
|
const value = await response.json();
|
||||||
|
if (!response.ok)
|
||||||
|
throw new RuntimeAuthorityError(value.error ?? "Runtime authority request failed");
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
const attachSessions = (runtimeContext, request) => {
|
||||||
|
if (!request.context?.grant || !request.context.ownerConformanceId)
|
||||||
|
return;
|
||||||
|
runtimeContext.openSession = async () => {
|
||||||
|
const ownerId = request.context.ownerConformanceId;
|
||||||
|
const registration = { grant: request.context.grant, objectId: request.objectId, ownerId,
|
||||||
|
sessionId: `session:${randomBytes(16).toString("hex")}`, token: randomBytes(32).toString("base64url") };
|
||||||
|
const register = () => runtimeControl("register-session", registration);
|
||||||
|
const registered = await register().catch((error) => {
|
||||||
|
// Retry a transport/lost-response failure with exactly the same identity.
|
||||||
|
// Admission/authority errors are definitive and must not be retried here.
|
||||||
|
if (error instanceof RuntimeAuthorityError)
|
||||||
|
throw error;
|
||||||
|
return register();
|
||||||
|
});
|
||||||
|
let closed = false;
|
||||||
|
return {
|
||||||
|
id: registered.sessionId,
|
||||||
|
async run(work) {
|
||||||
|
if (closed)
|
||||||
|
throw new RuntimeAuthorityError("SESSION_CLOSED");
|
||||||
|
// Acquisition happens before user code. A fence failure can be retried
|
||||||
|
// by the caller without replaying a side-effecting callback.
|
||||||
|
const grant = await runtimeControl("acquire-session", registered);
|
||||||
|
const execution = invocations.begin(grant.invocationId);
|
||||||
|
const sessionRequest = { ...request, context: { grant: grant.grant, instanceId: grant.instanceId, workspaceEpoch: grant.epoch } };
|
||||||
|
const clients = clientsFor(sessionRequest);
|
||||||
|
const context = createRuntimeContext(clients.camino, clients.orch, sessionRequest);
|
||||||
|
context.signal = execution.signal;
|
||||||
|
try {
|
||||||
|
return await work(context);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
execution.finish();
|
||||||
|
await runtimeControl("complete-invocation", { invocationId: grant.invocationId }).catch((error) => console.error("Session completion will be reconciled by the host", error));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async close() { await runtimeControl("close-session", registered); closed = true; },
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
return (router) => router.service(PackageRuntime, {
|
return (router) => router.service(PackageRuntime, {
|
||||||
handshake: () => create(HandshakeResponseSchema, {
|
handshake: (request) => create(HandshakeResponseSchema, {
|
||||||
packageRevisionId: config.packageRevisionId,
|
packageRevisionId: config.packageRevisionId,
|
||||||
runtimeProtocolVersion: "quixos-capabilities-v1",
|
runtimeProtocolVersion: "quixos-capabilities-v1",
|
||||||
exportIds: Object.keys(config.exports),
|
exportIds: Object.keys(config.exports),
|
||||||
|
capabilities: ["invocation-completion-v1", "instance-authentication-v1", "epoch-grants-v1"],
|
||||||
|
instanceId: process.env.QUIXOS_RUNTIME_INSTANCE_ID ?? "",
|
||||||
|
authenticationProof: request.nonce && processToken ? createHmac("sha256", processToken)
|
||||||
|
.update(JSON.stringify([request.nonce, process.env.QUIXOS_RUNTIME_INSTANCE_ID ?? "", config.packageRevisionId]))
|
||||||
|
.digest("hex") : "",
|
||||||
}),
|
}),
|
||||||
invoke: async (request) => {
|
getInvocationStatus: (request, context) => {
|
||||||
|
authenticateInstance(context.requestHeader);
|
||||||
|
return invocations.status(request.invocationId);
|
||||||
|
},
|
||||||
|
cancelInvocation: (request, context) => {
|
||||||
|
authenticateInstance(context.requestHeader);
|
||||||
|
return invocations.cancel(request.invocationId);
|
||||||
|
},
|
||||||
|
invoke: async (request, context) => {
|
||||||
|
authenticateInstance(context.requestHeader);
|
||||||
|
const { camino, orch } = clientsFor(request);
|
||||||
const exportId = request.export?.exportId;
|
const exportId = request.export?.exportId;
|
||||||
const handler = exportId ? config.exports[exportId] : undefined;
|
const handler = exportId ? config.exports[exportId] : undefined;
|
||||||
if (!handler)
|
if (!handler)
|
||||||
throw new ConnectError(`Unknown export ${exportId ?? ""}`, Code.NotFound);
|
throw new ConnectError(`Unknown export ${exportId ?? ""}`, Code.NotFound);
|
||||||
|
const execution = invocations.begin(request.invocationId || (process.env.QUIXOS_RUNTIME_INSTANCE_ID ? "" : randomUUID()));
|
||||||
try {
|
try {
|
||||||
const result = await evaluate(handler, createRuntimeContext(camino, orch, request));
|
const runtimeContext = createRuntimeContext(camino, orch, request);
|
||||||
return create(InvokeResponseSchema, { ok: true, result: result.value });
|
attachSessions(runtimeContext, request);
|
||||||
|
runtimeContext.signal = AbortSignal.any([context.signal, execution.signal]);
|
||||||
|
const result = await evaluate(handler, runtimeContext);
|
||||||
|
execution.finish();
|
||||||
|
return create(InvokeResponseSchema, {
|
||||||
|
ok: true,
|
||||||
|
result: result.value,
|
||||||
|
dependencies: protoDependencies(result.dependencies),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
|
execution.finish(true);
|
||||||
return create(InvokeResponseSchema, {
|
return create(InvokeResponseSchema, {
|
||||||
ok: false,
|
ok: false,
|
||||||
error: error instanceof Error ? error.message : String(error),
|
error: error instanceof Error ? error.message : String(error),
|
||||||
@@ -244,114 +411,141 @@ export const createPackageRuntimeRoutes = (config) => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: async function* (request, context) {
|
watch: async function* (request, context) {
|
||||||
|
authenticateInstance(context.requestHeader);
|
||||||
|
const { camino, orch } = clientsFor(request);
|
||||||
const exportId = request.export?.exportId;
|
const exportId = request.export?.exportId;
|
||||||
const handler = exportId ? config.exports[exportId] : undefined;
|
const handler = exportId ? config.exports[exportId] : undefined;
|
||||||
if (!handler || !isDerived(handler)) {
|
if (!handler || !isDerived(handler)) {
|
||||||
throw new ConnectError(`Export ${exportId ?? ""} is not derived`, Code.FailedPrecondition);
|
throw new ConnectError(`Export ${exportId ?? ""} is not derived`, Code.FailedPrecondition);
|
||||||
}
|
}
|
||||||
const watchId = `watch:${randomUUID()}`;
|
const execution = invocations.begin(request.invocationId || (process.env.QUIXOS_RUNTIME_INSTANCE_ID ? "" : randomUUID()));
|
||||||
const runtimeContext = createRuntimeContext(camino, orch, request);
|
const signal = AbortSignal.any([context.signal, execution.signal]);
|
||||||
const subscriptions = new Map();
|
try {
|
||||||
const establishing = new Map();
|
const watchId = `watch:${randomUUID()}`;
|
||||||
const ensureSubscription = async (dependency) => {
|
const runtimeContext = createRuntimeContext(camino, orch, request);
|
||||||
const key = dependencyKey(dependency);
|
attachSessions(runtimeContext, request);
|
||||||
if (subscriptions.has(key))
|
runtimeContext.signal = signal;
|
||||||
return;
|
const subscriptions = new Map();
|
||||||
const pending = establishing.get(key);
|
const establishing = new Map();
|
||||||
if (pending)
|
let subscriptionEpoch = 0;
|
||||||
return await pending;
|
const ensureSubscription = async (dependency) => {
|
||||||
const establish = (async () => {
|
const key = dependencyKey(dependency);
|
||||||
const controller = new AbortController();
|
if (subscriptions.has(key))
|
||||||
const stream = camino.watchObject({ objectId: dependency.objectId, includeSnapshot: true }, { signal: controller.signal })[Symbol.asyncIterator]();
|
return;
|
||||||
|
const pending = establishing.get(key);
|
||||||
|
if (pending)
|
||||||
|
return await pending;
|
||||||
|
const establish = (async () => {
|
||||||
|
const controller = new AbortController();
|
||||||
|
const stream = camino.watchObject({ objectId: dependency.objectId, includeSnapshot: true, attachmentIds: request.context?.grant ? [dependency.attachmentId] : [] }, { signal: controller.signal })[Symbol.asyncIterator]();
|
||||||
|
try {
|
||||||
|
// Camino subscribes before producing the snapshot, so once this
|
||||||
|
// resolves the following state/edge read cannot race the stream.
|
||||||
|
const snapshot = await stream.next();
|
||||||
|
if (snapshot.done)
|
||||||
|
throw new Error(`Dependency stream ${key} ended during setup`);
|
||||||
|
const waitNext = () => stream.next().then((result) => ({ key, done: Boolean(result.done) }), (error) => ({ key, done: true, error }));
|
||||||
|
const subscription = {
|
||||||
|
dependency,
|
||||||
|
controller,
|
||||||
|
waitNext,
|
||||||
|
next: Promise.resolve({ key, done: false }),
|
||||||
|
};
|
||||||
|
subscription.next = waitNext();
|
||||||
|
subscriptions.set(key, subscription);
|
||||||
|
subscriptionEpoch += 1;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
controller.abort();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
establishing.set(key, establish);
|
||||||
try {
|
try {
|
||||||
// Camino subscribes before producing the snapshot, so once this
|
await establish;
|
||||||
// resolves the following state/edge read cannot race the stream.
|
|
||||||
const snapshot = await stream.next();
|
|
||||||
if (snapshot.done)
|
|
||||||
throw new Error(`Dependency stream ${key} ended during setup`);
|
|
||||||
const waitNext = () => stream.next().then((result) => ({ key, done: Boolean(result.done) }), (error) => ({ key, done: true, error }));
|
|
||||||
const subscription = {
|
|
||||||
dependency,
|
|
||||||
controller,
|
|
||||||
waitNext,
|
|
||||||
next: Promise.resolve({ key, done: false }),
|
|
||||||
};
|
|
||||||
subscription.next = waitNext();
|
|
||||||
subscriptions.set(key, subscription);
|
|
||||||
}
|
}
|
||||||
catch (error) {
|
finally {
|
||||||
controller.abort();
|
establishing.delete(key);
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
})();
|
};
|
||||||
establishing.set(key, establish);
|
const abortAll = () => {
|
||||||
|
for (const subscription of subscriptions.values()) {
|
||||||
|
subscription.controller.abort();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
signal.addEventListener("abort", abortAll, { once: true });
|
||||||
|
const evaluateWithStableSubscriptions = async () => {
|
||||||
|
// A direct state/edge port records its dependency before reading it,
|
||||||
|
// but a nested interface invocation can only report its transitive
|
||||||
|
// dependencies after that invocation returns. Once a new dependency
|
||||||
|
// stream is established, evaluate again so every read contributing to
|
||||||
|
// the emitted value happened after its stream became live.
|
||||||
|
for (let pass = 0; pass < 32; pass += 1) {
|
||||||
|
const before = subscriptionEpoch;
|
||||||
|
const result = await evaluate(handler, runtimeContext, ensureSubscription);
|
||||||
|
if (subscriptionEpoch === before)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
throw new Error("Derived dependency discovery did not stabilize after 32 passes");
|
||||||
|
};
|
||||||
try {
|
try {
|
||||||
await establish;
|
let current = await evaluateWithStableSubscriptions();
|
||||||
|
yield create(WatchEventSchema, {
|
||||||
|
watchId,
|
||||||
|
value: current.value,
|
||||||
|
dependencies: protoDependencies(current.dependencies),
|
||||||
|
initial: true,
|
||||||
|
});
|
||||||
|
const abort = new Promise((resolve) => {
|
||||||
|
if (signal.aborted)
|
||||||
|
resolve("abort");
|
||||||
|
else
|
||||||
|
signal.addEventListener("abort", () => resolve("abort"), { once: true });
|
||||||
|
});
|
||||||
|
while (!signal.aborted) {
|
||||||
|
if (subscriptions.size === 0) {
|
||||||
|
await abort;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const outcome = await Promise.race([
|
||||||
|
...[...subscriptions.values()].map((entry) => entry.next),
|
||||||
|
abort,
|
||||||
|
]);
|
||||||
|
if (outcome === "abort")
|
||||||
|
break;
|
||||||
|
const subscription = subscriptions.get(outcome.key);
|
||||||
|
if (!subscription)
|
||||||
|
continue;
|
||||||
|
if (outcome.error)
|
||||||
|
throw outcome.error;
|
||||||
|
if (outcome.done)
|
||||||
|
throw new Error(`Dependency stream ${outcome.key} ended unexpectedly`);
|
||||||
|
subscription.next = subscription.waitNext();
|
||||||
|
const updated = await evaluateWithStableSubscriptions();
|
||||||
|
const active = new Set(updated.dependencies.map(dependencyKey));
|
||||||
|
for (const [key, entry] of subscriptions) {
|
||||||
|
if (!active.has(key)) {
|
||||||
|
entry.controller.abort();
|
||||||
|
subscriptions.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!equals(ValueSchema, current.value, updated.value)) {
|
||||||
|
yield create(WatchEventSchema, {
|
||||||
|
watchId,
|
||||||
|
value: updated.value,
|
||||||
|
dependencies: protoDependencies(updated.dependencies),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
current = updated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
establishing.delete(key);
|
signal.removeEventListener("abort", abortAll);
|
||||||
}
|
abortAll();
|
||||||
};
|
|
||||||
const abortAll = () => {
|
|
||||||
for (const subscription of subscriptions.values()) {
|
|
||||||
subscription.controller.abort();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
context.signal.addEventListener("abort", abortAll, { once: true });
|
|
||||||
let current = await evaluate(handler, runtimeContext, ensureSubscription);
|
|
||||||
yield create(WatchEventSchema, {
|
|
||||||
watchId,
|
|
||||||
value: current.value,
|
|
||||||
dependencies: protoDependencies(current.dependencies),
|
|
||||||
initial: true,
|
|
||||||
});
|
|
||||||
const abort = new Promise((resolve) => {
|
|
||||||
if (context.signal.aborted)
|
|
||||||
resolve("abort");
|
|
||||||
else
|
|
||||||
context.signal.addEventListener("abort", () => resolve("abort"), { once: true });
|
|
||||||
});
|
|
||||||
try {
|
|
||||||
while (!context.signal.aborted) {
|
|
||||||
if (subscriptions.size === 0) {
|
|
||||||
await abort;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const outcome = await Promise.race([
|
|
||||||
...[...subscriptions.values()].map((entry) => entry.next),
|
|
||||||
abort,
|
|
||||||
]);
|
|
||||||
if (outcome === "abort")
|
|
||||||
break;
|
|
||||||
const subscription = subscriptions.get(outcome.key);
|
|
||||||
if (!subscription)
|
|
||||||
continue;
|
|
||||||
if (outcome.error)
|
|
||||||
throw outcome.error;
|
|
||||||
if (outcome.done)
|
|
||||||
throw new Error(`Dependency stream ${outcome.key} ended unexpectedly`);
|
|
||||||
subscription.next = subscription.waitNext();
|
|
||||||
const updated = await evaluate(handler, runtimeContext, ensureSubscription);
|
|
||||||
const active = new Set(updated.dependencies.map(dependencyKey));
|
|
||||||
for (const [key, entry] of subscriptions) {
|
|
||||||
if (!active.has(key)) {
|
|
||||||
entry.controller.abort();
|
|
||||||
subscriptions.delete(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!equals(ValueSchema, current.value, updated.value)) {
|
|
||||||
yield create(WatchEventSchema, {
|
|
||||||
watchId,
|
|
||||||
value: updated.value,
|
|
||||||
dependencies: protoDependencies(updated.dependencies),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
current = updated;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
context.signal.removeEventListener("abort", abortAll);
|
execution.finish();
|
||||||
abortAll();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
/** Execution completion, not HTTP disconnection, is the drain boundary. */
|
||||||
|
export declare const createInvocationRegistry: () => {
|
||||||
|
begin(id: string): {
|
||||||
|
signal: AbortSignal;
|
||||||
|
finish(failed?: boolean): void;
|
||||||
|
};
|
||||||
|
status(id: string): {
|
||||||
|
invocationId: string;
|
||||||
|
state: string;
|
||||||
|
};
|
||||||
|
cancel(id: string): {
|
||||||
|
invocationId: string;
|
||||||
|
state: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
//# sourceMappingURL=invocations.d.ts.map
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"invocations.d.ts","sourceRoot":"","sources":["../src/invocations.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,eAAO,MAAM,wBAAwB;IAGjC,KAAK,KAAK,MAAM;QAOL,MAAM;QAA2B,MAAM;;IAElD,MAAM,KAAK,MAAM;QAAa,YAAY;QAAM,KAAK;;IACrD,MAAM,KAAK,MAAM;;;;CASpB,CAAC"}
|
||||||
Vendored
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/** Execution completion, not HTTP disconnection, is the drain boundary. */
|
||||||
|
export const createInvocationRegistry = () => {
|
||||||
|
const entries = new Map();
|
||||||
|
return {
|
||||||
|
begin(id) {
|
||||||
|
if (!id || entries.has(id))
|
||||||
|
throw new Error("Invocation ID is missing or already used; invocations are never replayed implicitly");
|
||||||
|
// Completed identities remain until process retirement. A bounded process
|
||||||
|
// may reject new work; it must not evict and accidentally replay a call.
|
||||||
|
if (entries.size >= 100_000)
|
||||||
|
throw new Error("Invocation registry full; explicit runtime retirement required");
|
||||||
|
const entry = { state: "running", controller: new AbortController() };
|
||||||
|
entries.set(id, entry);
|
||||||
|
return { signal: entry.controller.signal, finish(failed = false) { entry.state = failed ? "failed" : "completed"; } };
|
||||||
|
},
|
||||||
|
status(id) { return { invocationId: id, state: entries.get(id)?.state ?? "unknown" }; },
|
||||||
|
cancel(id) {
|
||||||
|
const entry = entries.get(id);
|
||||||
|
if (entry && ["running", "cancellation-requested"].includes(entry.state)) {
|
||||||
|
entry.state = "cancellation-requested";
|
||||||
|
entry.controller.abort();
|
||||||
|
}
|
||||||
|
return this.status(id);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
Vendored
+72
@@ -0,0 +1,72 @@
|
|||||||
|
export type MigrationInput = {
|
||||||
|
schemaVersion: 1;
|
||||||
|
executionId: string;
|
||||||
|
exportId: string;
|
||||||
|
ports: {
|
||||||
|
name: string;
|
||||||
|
binding: string;
|
||||||
|
view: "old" | "new";
|
||||||
|
access: ("read" | "write" | "create" | "edge")[];
|
||||||
|
atomId?: string;
|
||||||
|
attachedAtomId?: string;
|
||||||
|
defaultValue?: unknown;
|
||||||
|
states?: {
|
||||||
|
objectId: string;
|
||||||
|
value: unknown;
|
||||||
|
}[];
|
||||||
|
edges?: MigrationEdge[];
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
export type MigrationEdge = {
|
||||||
|
id: string;
|
||||||
|
edgeTypeId: string;
|
||||||
|
firstObjectId: string;
|
||||||
|
secondObjectId: string;
|
||||||
|
firstProjectionId: string;
|
||||||
|
secondProjectionId: string;
|
||||||
|
firstOrdinal?: number;
|
||||||
|
secondOrdinal?: number;
|
||||||
|
firstKeyJson?: string;
|
||||||
|
secondKeyJson?: string;
|
||||||
|
};
|
||||||
|
export type MigrationOutput = {
|
||||||
|
schemaVersion: 1;
|
||||||
|
executionId: string;
|
||||||
|
writes: {
|
||||||
|
port: string;
|
||||||
|
objectId: string;
|
||||||
|
value: unknown;
|
||||||
|
}[];
|
||||||
|
creates: {
|
||||||
|
port: string;
|
||||||
|
logicalKey: string;
|
||||||
|
objectId: string;
|
||||||
|
}[];
|
||||||
|
edgeReplacements: {
|
||||||
|
port: string;
|
||||||
|
edges: MigrationEdge[];
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
export type MigrationContext = {
|
||||||
|
enumerate(port: string): {
|
||||||
|
objectId: string;
|
||||||
|
value: unknown;
|
||||||
|
}[];
|
||||||
|
read(port: string, objectId: string): unknown;
|
||||||
|
write(port: string, objectId: string, value: unknown): void;
|
||||||
|
create(port: string, logicalKey: string): string;
|
||||||
|
edges(port: string): MigrationEdge[];
|
||||||
|
replaceEdges(port: string, edges: MigrationEdge[]): void;
|
||||||
|
};
|
||||||
|
export declare const migrationObjectId: (executionId: string, port: string, logicalKey: string) => string;
|
||||||
|
/** No ordinary RuntimeContext or network/database clients are supplied here.
|
||||||
|
* Process isolation belongs to the host, not this convenience API. */
|
||||||
|
export declare const createMigrationContext: (input: MigrationInput) => {
|
||||||
|
context: MigrationContext;
|
||||||
|
result: () => MigrationOutput;
|
||||||
|
};
|
||||||
|
/** Entrypoint for an immutable package's dedicated bin/migrate executable.
|
||||||
|
* stdout is protocol-only; send diagnostics to stderr. The host independently
|
||||||
|
* validates every write, helper identity, contract, and completion receipt. */
|
||||||
|
export declare const serveMigration: (exports: Record<string, (context: MigrationContext) => void | Promise<void>>) => Promise<void>;
|
||||||
|
//# sourceMappingURL=migration.d.ts.map
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,CAAC,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IACxD,KAAK,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAC5H,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAC;QAChD,MAAM,CAAC,EAAE;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,OAAO,CAAA;SAAC,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;KAAC,EAAE,CAAC;CAC7E,CAAC;AACF,MAAM,MAAM,aAAa,GAAG;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC;AACjQ,MAAM,MAAM,eAAe,GAAG;IAAC,aAAa,EAAE,CAAC,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IACnE,MAAM,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAC,EAAE,CAAC;IAC3D,OAAO,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAChE,gBAAgB,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,EAAE,CAAA;KAAC,EAAE,CAAA;CAAC,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAC,EAAE,CAAC;IAC9D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IACjD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAAC;IACrC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;CAC1D,CAAC;AACF,eAAO,MAAM,iBAAiB,gBAAiB,MAAM,QAAQ,MAAM,cAAc,MAAM,WACwB,CAAC;AAEhH;sEACsE;AACtE,eAAO,MAAM,sBAAsB,UAAW,cAAc;;;CAgD3D,CAAC;AAEF;;+EAE+E;AAC/E,eAAO,MAAM,cAAc,YAAmB,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,kBAehH,CAAC"}
|
||||||
Vendored
+93
@@ -0,0 +1,93 @@
|
|||||||
|
import { createHash } from "node:crypto";
|
||||||
|
export const migrationObjectId = (executionId, port, logicalKey) => `obj:migration:${createHash("sha256").update(JSON.stringify([executionId, port, logicalKey])).digest("hex")}`;
|
||||||
|
/** No ordinary RuntimeContext or network/database clients are supplied here.
|
||||||
|
* Process isolation belongs to the host, not this convenience API. */
|
||||||
|
export const createMigrationContext = (input) => {
|
||||||
|
if (input.schemaVersion !== 1 || !input.executionId || new Set(input.ports.map((entry) => entry.name)).size !== input.ports.length)
|
||||||
|
throw new Error("Invalid migration input");
|
||||||
|
const output = { schemaVersion: 1, executionId: input.executionId, writes: [], creates: [], edgeReplacements: [] };
|
||||||
|
const port = (name, access) => {
|
||||||
|
const selected = input.ports.find((entry) => entry.name === name);
|
||||||
|
if (!selected?.access.includes(access) || (selected.view === "old" && access !== "read"))
|
||||||
|
throw new Error(`Migration port ${name} does not grant ${access}`);
|
||||||
|
return selected;
|
||||||
|
};
|
||||||
|
const context = {
|
||||||
|
enumerate(name) {
|
||||||
|
const selected = port(name, "read"), states = structuredClone(selected.states ?? []);
|
||||||
|
if (selected.view === "new" && Object.hasOwn(selected, "defaultValue"))
|
||||||
|
for (const helper of output.creates) {
|
||||||
|
if (input.ports.find((entry) => entry.name === helper.port)?.atomId === selected.attachedAtomId && !states.some((entry) => entry.objectId === helper.objectId))
|
||||||
|
states.push({ objectId: helper.objectId, value: structuredClone(selected.defaultValue) });
|
||||||
|
}
|
||||||
|
if (selected.view === "new")
|
||||||
|
for (const write of output.writes) {
|
||||||
|
if (input.ports.find((entry) => entry.name === write.port)?.binding !== selected.binding)
|
||||||
|
continue;
|
||||||
|
const existing = states.findIndex((entry) => entry.objectId === write.objectId), entry = { objectId: write.objectId, value: structuredClone(write.value) };
|
||||||
|
if (existing < 0)
|
||||||
|
states.push(entry);
|
||||||
|
else
|
||||||
|
states[existing] = entry;
|
||||||
|
}
|
||||||
|
return states.sort((a, b) => a.objectId < b.objectId ? -1 : a.objectId > b.objectId ? 1 : 0);
|
||||||
|
},
|
||||||
|
read(name, objectId) { return context.enumerate(name).find((entry) => entry.objectId === objectId)?.value; },
|
||||||
|
write(name, objectId, value) {
|
||||||
|
port(name, "write");
|
||||||
|
const previous = output.writes.findIndex((entry) => entry.port === name && entry.objectId === objectId);
|
||||||
|
const entry = { port: name, objectId, value: structuredClone(value) };
|
||||||
|
if (previous < 0)
|
||||||
|
output.writes.push(entry);
|
||||||
|
else
|
||||||
|
output.writes[previous] = entry;
|
||||||
|
},
|
||||||
|
create(name, logicalKey) {
|
||||||
|
port(name, "create");
|
||||||
|
if (!logicalKey || logicalKey.length > 1024)
|
||||||
|
throw new Error("Migration creation requires a bounded stable logical key");
|
||||||
|
const objectId = migrationObjectId(input.executionId, name, logicalKey);
|
||||||
|
if (!output.creates.some((entry) => entry.objectId === objectId))
|
||||||
|
output.creates.push({ port: name, logicalKey, objectId });
|
||||||
|
return objectId;
|
||||||
|
},
|
||||||
|
edges(name) {
|
||||||
|
const selected = port(name, "read");
|
||||||
|
const replacement = selected.view === "new" ? output.edgeReplacements.find((entry) => input.ports.find((candidate) => candidate.name === entry.port)?.binding === selected.binding) : undefined;
|
||||||
|
return structuredClone(replacement?.edges ?? selected.edges ?? []);
|
||||||
|
},
|
||||||
|
replaceEdges(name, edges) {
|
||||||
|
port(name, "edge");
|
||||||
|
const previous = output.edgeReplacements.findIndex((entry) => entry.port === name);
|
||||||
|
const entry = { port: name, edges: structuredClone(edges) };
|
||||||
|
if (previous < 0)
|
||||||
|
output.edgeReplacements.push(entry);
|
||||||
|
else
|
||||||
|
output.edgeReplacements[previous] = entry;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return { context, result: () => structuredClone(output) };
|
||||||
|
};
|
||||||
|
/** Entrypoint for an immutable package's dedicated bin/migrate executable.
|
||||||
|
* stdout is protocol-only; send diagnostics to stderr. The host independently
|
||||||
|
* validates every write, helper identity, contract, and completion receipt. */
|
||||||
|
export const serveMigration = async (exports) => {
|
||||||
|
const chunks = [];
|
||||||
|
let bytes = 0;
|
||||||
|
for await (const chunk of process.stdin) {
|
||||||
|
bytes += chunk.length;
|
||||||
|
if (bytes > 16 * 1024 * 1024)
|
||||||
|
throw new Error("Migration input exceeds 16 MiB");
|
||||||
|
chunks.push(Buffer.from(chunk));
|
||||||
|
}
|
||||||
|
const input = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
||||||
|
const implementation = Object.hasOwn(exports, input.exportId) ? exports[input.exportId] : undefined;
|
||||||
|
if (!implementation)
|
||||||
|
throw new Error("Unknown migration export");
|
||||||
|
const execution = createMigrationContext(input);
|
||||||
|
await implementation(execution.context);
|
||||||
|
const result = JSON.stringify(execution.result());
|
||||||
|
if (Buffer.byteLength(result) > 16 * 1024 * 1024)
|
||||||
|
throw new Error("Migration output exceeds 16 MiB");
|
||||||
|
process.stdout.write(`${result}\n`);
|
||||||
|
};
|
||||||
Vendored
+65
-6
@@ -42,6 +42,46 @@ export type ConstructObjectResponse = Message<"quixos.orch.ConstructObjectRespon
|
|||||||
* Use `create(ConstructObjectResponseSchema)` to create a new message.
|
* Use `create(ConstructObjectResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export declare const ConstructObjectResponseSchema: GenMessage<ConstructObjectResponse>;
|
export declare const ConstructObjectResponseSchema: GenMessage<ConstructObjectResponse>;
|
||||||
|
/**
|
||||||
|
* @generated from message quixos.orch.ResolveOrConstructRelatedObjectRequest
|
||||||
|
*/
|
||||||
|
export type ResolveOrConstructRelatedObjectRequest = Message<"quixos.orch.ResolveOrConstructRelatedObjectRequest"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: string object_id = 1;
|
||||||
|
*/
|
||||||
|
objectId: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string interface_revision_id = 2;
|
||||||
|
*/
|
||||||
|
interfaceRevisionId: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string member_id = 3;
|
||||||
|
*/
|
||||||
|
memberId: string;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.orch.ResolveOrConstructRelatedObjectRequest.
|
||||||
|
* Use `create(ResolveOrConstructRelatedObjectRequestSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export declare const ResolveOrConstructRelatedObjectRequestSchema: GenMessage<ResolveOrConstructRelatedObjectRequest>;
|
||||||
|
/**
|
||||||
|
* @generated from message quixos.orch.ResolveOrConstructRelatedObjectResponse
|
||||||
|
*/
|
||||||
|
export type ResolveOrConstructRelatedObjectResponse = Message<"quixos.orch.ResolveOrConstructRelatedObjectResponse"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: camino.CaminoObject object = 1;
|
||||||
|
*/
|
||||||
|
object?: CaminoObject | undefined;
|
||||||
|
/**
|
||||||
|
* @generated from field: bool constructed = 2;
|
||||||
|
*/
|
||||||
|
constructed: boolean;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.orch.ResolveOrConstructRelatedObjectResponse.
|
||||||
|
* Use `create(ResolveOrConstructRelatedObjectResponseSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export declare const ResolveOrConstructRelatedObjectResponseSchema: GenMessage<ResolveOrConstructRelatedObjectResponse>;
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.InvokeCapabilityRequest
|
* @generated from message quixos.orch.InvokeCapabilityRequest
|
||||||
*/
|
*/
|
||||||
@@ -60,6 +100,13 @@ export type InvokeCapabilityRequest = Message<"quixos.orch.InvokeCapabilityReque
|
|||||||
input: {
|
input: {
|
||||||
[key: string]: Value;
|
[key: string]: Value;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Identifies one logical client mutation across the capability and Camino
|
||||||
|
* layers so a live-value controller can recognize its own confirmation.
|
||||||
|
*
|
||||||
|
* @generated from field: string client_mutation_id = 4;
|
||||||
|
*/
|
||||||
|
clientMutationId: string;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.InvokeCapabilityRequest.
|
* Describes the message quixos.orch.InvokeCapabilityRequest.
|
||||||
@@ -90,6 +137,10 @@ export type InvokeCapabilityResponse = Message<"quixos.orch.InvokeCapabilityResp
|
|||||||
* @generated from field: string error = 5;
|
* @generated from field: string error = 5;
|
||||||
*/
|
*/
|
||||||
error: string;
|
error: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: repeated quixos.runtime.DerivedDependency dependencies = 6;
|
||||||
|
*/
|
||||||
|
dependencies: DerivedDependency[];
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.InvokeCapabilityResponse.
|
* Describes the message quixos.orch.InvokeCapabilityResponse.
|
||||||
@@ -353,17 +404,17 @@ export type PackageRuntimeStatus = Message<"quixos.orch.PackageRuntimeStatus"> &
|
|||||||
*/
|
*/
|
||||||
packageRevisionId: string;
|
packageRevisionId: string;
|
||||||
/**
|
/**
|
||||||
* @generated from field: string source_repo = 3;
|
* @generated from field: string source_repository = 3;
|
||||||
*/
|
*/
|
||||||
sourceRepo: string;
|
sourceRepository: string;
|
||||||
/**
|
/**
|
||||||
* @generated from field: string server_installable = 4;
|
* @generated from field: string source_commit = 4;
|
||||||
*/
|
*/
|
||||||
serverInstallable: string;
|
sourceCommit: string;
|
||||||
/**
|
/**
|
||||||
* @generated from field: string source_path = 5;
|
* @generated from field: string build_target = 5;
|
||||||
*/
|
*/
|
||||||
sourcePath: string;
|
buildTarget: string;
|
||||||
/**
|
/**
|
||||||
* @generated from field: string server_path = 6;
|
* @generated from field: string server_path = 6;
|
||||||
*/
|
*/
|
||||||
@@ -426,6 +477,14 @@ export declare const OrchestratorRuntime: GenService<{
|
|||||||
input: typeof ConstructObjectRequestSchema;
|
input: typeof ConstructObjectRequestSchema;
|
||||||
output: typeof ConstructObjectResponseSchema;
|
output: typeof ConstructObjectResponseSchema;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @generated from rpc quixos.orch.OrchestratorRuntime.ResolveOrConstructRelatedObject
|
||||||
|
*/
|
||||||
|
resolveOrConstructRelatedObject: {
|
||||||
|
methodKind: "unary";
|
||||||
|
input: typeof ResolveOrConstructRelatedObjectRequestSchema;
|
||||||
|
output: typeof ResolveOrConstructRelatedObjectResponseSchema;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* @generated from rpc quixos.orch.OrchestratorRuntime.GetWorkspace
|
* @generated from rpc quixos.orch.OrchestratorRuntime.GetWorkspace
|
||||||
*/
|
*/
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+27
-17
@@ -9,7 +9,7 @@ import { file_quixos_runtime } from "./runtime_pb.js";
|
|||||||
/**
|
/**
|
||||||
* Describes the file quixos/orch.proto.
|
* Describes the file quixos/orch.proto.
|
||||||
*/
|
*/
|
||||||
export const file_quixos_orch = /*@__PURE__*/ fileDesc("ChFxdWl4b3Mvb3JjaC5wcm90bxILcXVpeG9zLm9yY2gipQEKFkNvbnN0cnVjdE9iamVjdFJlcXVlc3QSDwoHYXRvbV9pZBgBIAEoCRI9CgVpbnB1dBgCIAMoCzIuLnF1aXhvcy5vcmNoLkNvbnN0cnVjdE9iamVjdFJlcXVlc3QuSW5wdXRFbnRyeRo7CgpJbnB1dEVudHJ5EgsKA2tleRgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLmNhbWluby5WYWx1ZToCOAEiPwoXQ29uc3RydWN0T2JqZWN0UmVzcG9uc2USJAoGb2JqZWN0GAEgASgLMhQuY2FtaW5vLkNhbWlub09iamVjdCLUAQoXSW52b2tlQ2FwYWJpbGl0eVJlcXVlc3QSKQoKY2FwYWJpbGl0eRgBIAEoCzIVLnF1aXhvcy5DYXBhYmlsaXR5UmVmEhEKCW9iamVjdF9pZBgCIAEoCRI+CgVpbnB1dBgDIAMoCzIvLnF1aXhvcy5vcmNoLkludm9rZUNhcGFiaWxpdHlSZXF1ZXN0LklucHV0RW50cnkaOwoKSW5wdXRFbnRyeRILCgNrZXkYASABKAkSHAoFdmFsdWUYAiABKAsyDS5jYW1pbm8uVmFsdWU6AjgBIpgBChhJbnZva2VDYXBhYmlsaXR5UmVzcG9uc2USFQoNaW52b2NhdGlvbl9pZBgBIAEoCRIrCgphY3RpdmF0aW9uGAIgASgLMhcucXVpeG9zLm9yY2guQWN0aXZhdGlvbhIKCgJvaxgDIAEoCBIdCgZyZXN1bHQYBCABKAsyDS5jYW1pbm8uVmFsdWUSDQoFZXJyb3IYBSABKAki0gEKFldhdGNoQ2FwYWJpbGl0eVJlcXVlc3QSKQoKY2FwYWJpbGl0eRgBIAEoCzIVLnF1aXhvcy5DYXBhYmlsaXR5UmVmEhEKCW9iamVjdF9pZBgCIAEoCRI9CgVpbnB1dBgDIAMoCzIuLnF1aXhvcy5vcmNoLldhdGNoQ2FwYWJpbGl0eVJlcXVlc3QuSW5wdXRFbnRyeRo7CgpJbnB1dEVudHJ5EgsKA2tleRgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLmNhbWluby5WYWx1ZToCOAEi4wEKFFdhdGNoQ2FwYWJpbGl0eUV2ZW50EhUKDWludm9jYXRpb25faWQYASABKAkSKwoKYWN0aXZhdGlvbhgCIAEoCzIXLnF1aXhvcy5vcmNoLkFjdGl2YXRpb24SEAoId2F0Y2hfaWQYAyABKAkSHAoFdmFsdWUYBCABKAsyDS5jYW1pbm8uVmFsdWUSNwoMZGVwZW5kZW5jaWVzGAUgAygLMiEucXVpeG9zLnJ1bnRpbWUuRGVyaXZlZERlcGVuZGVuY3kSDQoFZXJyb3IYBiABKAkSDwoHaW5pdGlhbBgHIAEoCCIVChNHZXRXb3Jrc3BhY2VSZXF1ZXN0ImcKFEdldFdvcmtzcGFjZVJlc3BvbnNlEhQKDHdvcmtzcGFjZV9pZBgBIAEoCRIdChV3b3Jrc3BhY2VfcmV2aXNpb25faWQYAiABKAkSGgoSc291cmNlX3Jvb3RfY29tbWl0GAMgASgJIhgKFkxpc3RBY3RpdmF0aW9uc1JlcXVlc3QiHwodTGlzdFBhY2thZ2VEZXNjcmlwdG9yc1JlcXVlc3QiUAoeTGlzdFBhY2thZ2VEZXNjcmlwdG9yc1Jlc3BvbnNlEi4KC2Rlc2NyaXB0b3JzGAEgAygLMhkucXVpeG9zLlBhY2thZ2VEZXNjcmlwdG9yIhwKGkxpc3RQYWNrYWdlUnVudGltZXNSZXF1ZXN0IlIKG0xpc3RQYWNrYWdlUnVudGltZXNSZXNwb25zZRIzCghydW50aW1lcxgBIAMoCzIhLnF1aXhvcy5vcmNoLlBhY2thZ2VSdW50aW1lU3RhdHVzIkcKF0xpc3RBY3RpdmF0aW9uc1Jlc3BvbnNlEiwKC2FjdGl2YXRpb25zGAEgAygLMhcucXVpeG9zLm9yY2guQWN0aXZhdGlvbiI/ChZDbG9zZUFjdGl2YXRpb25SZXF1ZXN0EhUKDWFjdGl2YXRpb25faWQYASABKAkSDgoGcmVhc29uGAIgASgJIkYKF0Nsb3NlQWN0aXZhdGlvblJlc3BvbnNlEisKCmFjdGl2YXRpb24YASABKAsyFy5xdWl4b3Mub3JjaC5BY3RpdmF0aW9uIusBCgpBY3RpdmF0aW9uEhUKDWFjdGl2YXRpb25faWQYASABKAkSKAoGZXhwb3J0GAIgASgLMhgucXVpeG9zLlBhY2thZ2VFeHBvcnRSZWYSEQoJb2JqZWN0X2lkGAMgASgJEg0KBXN0YXRlGAQgASgJEg4KBmRlbWFuZBgFIAEoDRIRCglvcGVuZWRfYXQYBiABKAkSFAoMbGFzdF91c2VkX2F0GAcgASgJEhgKEGlkbGVfZGVhZGxpbmVfYXQYCCABKAkSEQoJY2xvc2VkX2F0GAkgASgJEhQKDGNsb3NlX3JlYXNvbhgKIAEoCSKxAgoUUGFja2FnZVJ1bnRpbWVTdGF0dXMSEwoLcnVudGltZV9rZXkYASABKAkSGwoTcGFja2FnZV9yZXZpc2lvbl9pZBgCIAEoCRITCgtzb3VyY2VfcmVwbxgDIAEoCRIaChJzZXJ2ZXJfaW5zdGFsbGFibGUYBCABKAkSEwoLc291cmNlX3BhdGgYBSABKAkSEwoLc2VydmVyX3BhdGgYBiABKAkSCwoDcGlkGAcgASgNEg0KBXN0YXRlGAggASgJEhIKCnN0YXJ0ZWRfYXQYCSABKAkSGQoRbGFzdF9oYW5kc2hha2VfYXQYCiABKAkSIAoYcnVudGltZV9wcm90b2NvbF92ZXJzaW9uGAsgASgJEh8KF2FkdmVydGlzZWRfZXhwb3J0X2NvdW50GAwgASgNMp8GChNPcmNoZXN0cmF0b3JSdW50aW1lEl8KEEludm9rZUNhcGFiaWxpdHkSJC5xdWl4b3Mub3JjaC5JbnZva2VDYXBhYmlsaXR5UmVxdWVzdBolLnF1aXhvcy5vcmNoLkludm9rZUNhcGFiaWxpdHlSZXNwb25zZRJbCg9XYXRjaENhcGFiaWxpdHkSIy5xdWl4b3Mub3JjaC5XYXRjaENhcGFiaWxpdHlSZXF1ZXN0GiEucXVpeG9zLm9yY2guV2F0Y2hDYXBhYmlsaXR5RXZlbnQwARJcCg9Db25zdHJ1Y3RPYmplY3QSIy5xdWl4b3Mub3JjaC5Db25zdHJ1Y3RPYmplY3RSZXF1ZXN0GiQucXVpeG9zLm9yY2guQ29uc3RydWN0T2JqZWN0UmVzcG9uc2USUwoMR2V0V29ya3NwYWNlEiAucXVpeG9zLm9yY2guR2V0V29ya3NwYWNlUmVxdWVzdBohLnF1aXhvcy5vcmNoLkdldFdvcmtzcGFjZVJlc3BvbnNlEnEKFkxpc3RQYWNrYWdlRGVzY3JpcHRvcnMSKi5xdWl4b3Mub3JjaC5MaXN0UGFja2FnZURlc2NyaXB0b3JzUmVxdWVzdBorLnF1aXhvcy5vcmNoLkxpc3RQYWNrYWdlRGVzY3JpcHRvcnNSZXNwb25zZRJoChNMaXN0UGFja2FnZVJ1bnRpbWVzEicucXVpeG9zLm9yY2guTGlzdFBhY2thZ2VSdW50aW1lc1JlcXVlc3QaKC5xdWl4b3Mub3JjaC5MaXN0UGFja2FnZVJ1bnRpbWVzUmVzcG9uc2USXAoPTGlzdEFjdGl2YXRpb25zEiMucXVpeG9zLm9yY2guTGlzdEFjdGl2YXRpb25zUmVxdWVzdBokLnF1aXhvcy5vcmNoLkxpc3RBY3RpdmF0aW9uc1Jlc3BvbnNlElwKD0Nsb3NlQWN0aXZhdGlvbhIjLnF1aXhvcy5vcmNoLkNsb3NlQWN0aXZhdGlvblJlcXVlc3QaJC5xdWl4b3Mub3JjaC5DbG9zZUFjdGl2YXRpb25SZXNwb25zZWIGcHJvdG8z", [file_camino_api, file_quixos_package, file_quixos_refs, file_quixos_runtime]);
|
export const file_quixos_orch = /*@__PURE__*/ fileDesc("ChFxdWl4b3Mvb3JjaC5wcm90bxILcXVpeG9zLm9yY2gipQEKFkNvbnN0cnVjdE9iamVjdFJlcXVlc3QSDwoHYXRvbV9pZBgBIAEoCRI9CgVpbnB1dBgCIAMoCzIuLnF1aXhvcy5vcmNoLkNvbnN0cnVjdE9iamVjdFJlcXVlc3QuSW5wdXRFbnRyeRo7CgpJbnB1dEVudHJ5EgsKA2tleRgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLmNhbWluby5WYWx1ZToCOAEiPwoXQ29uc3RydWN0T2JqZWN0UmVzcG9uc2USJAoGb2JqZWN0GAEgASgLMhQuY2FtaW5vLkNhbWlub09iamVjdCJtCiZSZXNvbHZlT3JDb25zdHJ1Y3RSZWxhdGVkT2JqZWN0UmVxdWVzdBIRCglvYmplY3RfaWQYASABKAkSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAIgASgJEhEKCW1lbWJlcl9pZBgDIAEoCSJkCidSZXNvbHZlT3JDb25zdHJ1Y3RSZWxhdGVkT2JqZWN0UmVzcG9uc2USJAoGb2JqZWN0GAEgASgLMhQuY2FtaW5vLkNhbWlub09iamVjdBITCgtjb25zdHJ1Y3RlZBgCIAEoCCLwAQoXSW52b2tlQ2FwYWJpbGl0eVJlcXVlc3QSKQoKY2FwYWJpbGl0eRgBIAEoCzIVLnF1aXhvcy5DYXBhYmlsaXR5UmVmEhEKCW9iamVjdF9pZBgCIAEoCRI+CgVpbnB1dBgDIAMoCzIvLnF1aXhvcy5vcmNoLkludm9rZUNhcGFiaWxpdHlSZXF1ZXN0LklucHV0RW50cnkSGgoSY2xpZW50X211dGF0aW9uX2lkGAQgASgJGjsKCklucHV0RW50cnkSCwoDa2V5GAEgASgJEhwKBXZhbHVlGAIgASgLMg0uY2FtaW5vLlZhbHVlOgI4ASLRAQoYSW52b2tlQ2FwYWJpbGl0eVJlc3BvbnNlEhUKDWludm9jYXRpb25faWQYASABKAkSKwoKYWN0aXZhdGlvbhgCIAEoCzIXLnF1aXhvcy5vcmNoLkFjdGl2YXRpb24SCgoCb2sYAyABKAgSHQoGcmVzdWx0GAQgASgLMg0uY2FtaW5vLlZhbHVlEg0KBWVycm9yGAUgASgJEjcKDGRlcGVuZGVuY2llcxgGIAMoCzIhLnF1aXhvcy5ydW50aW1lLkRlcml2ZWREZXBlbmRlbmN5ItIBChZXYXRjaENhcGFiaWxpdHlSZXF1ZXN0EikKCmNhcGFiaWxpdHkYASABKAsyFS5xdWl4b3MuQ2FwYWJpbGl0eVJlZhIRCglvYmplY3RfaWQYAiABKAkSPQoFaW5wdXQYAyADKAsyLi5xdWl4b3Mub3JjaC5XYXRjaENhcGFiaWxpdHlSZXF1ZXN0LklucHV0RW50cnkaOwoKSW5wdXRFbnRyeRILCgNrZXkYASABKAkSHAoFdmFsdWUYAiABKAsyDS5jYW1pbm8uVmFsdWU6AjgBIuMBChRXYXRjaENhcGFiaWxpdHlFdmVudBIVCg1pbnZvY2F0aW9uX2lkGAEgASgJEisKCmFjdGl2YXRpb24YAiABKAsyFy5xdWl4b3Mub3JjaC5BY3RpdmF0aW9uEhAKCHdhdGNoX2lkGAMgASgJEhwKBXZhbHVlGAQgASgLMg0uY2FtaW5vLlZhbHVlEjcKDGRlcGVuZGVuY2llcxgFIAMoCzIhLnF1aXhvcy5ydW50aW1lLkRlcml2ZWREZXBlbmRlbmN5Eg0KBWVycm9yGAYgASgJEg8KB2luaXRpYWwYByABKAgiFQoTR2V0V29ya3NwYWNlUmVxdWVzdCJnChRHZXRXb3Jrc3BhY2VSZXNwb25zZRIUCgx3b3Jrc3BhY2VfaWQYASABKAkSHQoVd29ya3NwYWNlX3JldmlzaW9uX2lkGAIgASgJEhoKEnNvdXJjZV9yb290X2NvbW1pdBgDIAEoCSIYChZMaXN0QWN0aXZhdGlvbnNSZXF1ZXN0Ih8KHUxpc3RQYWNrYWdlRGVzY3JpcHRvcnNSZXF1ZXN0IlAKHkxpc3RQYWNrYWdlRGVzY3JpcHRvcnNSZXNwb25zZRIuCgtkZXNjcmlwdG9ycxgBIAMoCzIZLnF1aXhvcy5QYWNrYWdlRGVzY3JpcHRvciIcChpMaXN0UGFja2FnZVJ1bnRpbWVzUmVxdWVzdCJSChtMaXN0UGFja2FnZVJ1bnRpbWVzUmVzcG9uc2USMwoIcnVudGltZXMYASADKAsyIS5xdWl4b3Mub3JjaC5QYWNrYWdlUnVudGltZVN0YXR1cyJHChdMaXN0QWN0aXZhdGlvbnNSZXNwb25zZRIsCgthY3RpdmF0aW9ucxgBIAMoCzIXLnF1aXhvcy5vcmNoLkFjdGl2YXRpb24iPwoWQ2xvc2VBY3RpdmF0aW9uUmVxdWVzdBIVCg1hY3RpdmF0aW9uX2lkGAEgASgJEg4KBnJlYXNvbhgCIAEoCSJGChdDbG9zZUFjdGl2YXRpb25SZXNwb25zZRIrCgphY3RpdmF0aW9uGAEgASgLMhcucXVpeG9zLm9yY2guQWN0aXZhdGlvbiLrAQoKQWN0aXZhdGlvbhIVCg1hY3RpdmF0aW9uX2lkGAEgASgJEigKBmV4cG9ydBgCIAEoCzIYLnF1aXhvcy5QYWNrYWdlRXhwb3J0UmVmEhEKCW9iamVjdF9pZBgDIAEoCRINCgVzdGF0ZRgEIAEoCRIOCgZkZW1hbmQYBSABKA0SEQoJb3BlbmVkX2F0GAYgASgJEhQKDGxhc3RfdXNlZF9hdBgHIAEoCRIYChBpZGxlX2RlYWRsaW5lX2F0GAggASgJEhEKCWNsb3NlZF9hdBgJIAEoCRIUCgxjbG9zZV9yZWFzb24YCiABKAkiswIKFFBhY2thZ2VSdW50aW1lU3RhdHVzEhMKC3J1bnRpbWVfa2V5GAEgASgJEhsKE3BhY2thZ2VfcmV2aXNpb25faWQYAiABKAkSGQoRc291cmNlX3JlcG9zaXRvcnkYAyABKAkSFQoNc291cmNlX2NvbW1pdBgEIAEoCRIUCgxidWlsZF90YXJnZXQYBSABKAkSEwoLc2VydmVyX3BhdGgYBiABKAkSCwoDcGlkGAcgASgNEg0KBXN0YXRlGAggASgJEhIKCnN0YXJ0ZWRfYXQYCSABKAkSGQoRbGFzdF9oYW5kc2hha2VfYXQYCiABKAkSIAoYcnVudGltZV9wcm90b2NvbF92ZXJzaW9uGAsgASgJEh8KF2FkdmVydGlzZWRfZXhwb3J0X2NvdW50GAwgASgNMq4HChNPcmNoZXN0cmF0b3JSdW50aW1lEl8KEEludm9rZUNhcGFiaWxpdHkSJC5xdWl4b3Mub3JjaC5JbnZva2VDYXBhYmlsaXR5UmVxdWVzdBolLnF1aXhvcy5vcmNoLkludm9rZUNhcGFiaWxpdHlSZXNwb25zZRJbCg9XYXRjaENhcGFiaWxpdHkSIy5xdWl4b3Mub3JjaC5XYXRjaENhcGFiaWxpdHlSZXF1ZXN0GiEucXVpeG9zLm9yY2guV2F0Y2hDYXBhYmlsaXR5RXZlbnQwARJcCg9Db25zdHJ1Y3RPYmplY3QSIy5xdWl4b3Mub3JjaC5Db25zdHJ1Y3RPYmplY3RSZXF1ZXN0GiQucXVpeG9zLm9yY2guQ29uc3RydWN0T2JqZWN0UmVzcG9uc2USjAEKH1Jlc29sdmVPckNvbnN0cnVjdFJlbGF0ZWRPYmplY3QSMy5xdWl4b3Mub3JjaC5SZXNvbHZlT3JDb25zdHJ1Y3RSZWxhdGVkT2JqZWN0UmVxdWVzdBo0LnF1aXhvcy5vcmNoLlJlc29sdmVPckNvbnN0cnVjdFJlbGF0ZWRPYmplY3RSZXNwb25zZRJTCgxHZXRXb3Jrc3BhY2USIC5xdWl4b3Mub3JjaC5HZXRXb3Jrc3BhY2VSZXF1ZXN0GiEucXVpeG9zLm9yY2guR2V0V29ya3NwYWNlUmVzcG9uc2UScQoWTGlzdFBhY2thZ2VEZXNjcmlwdG9ycxIqLnF1aXhvcy5vcmNoLkxpc3RQYWNrYWdlRGVzY3JpcHRvcnNSZXF1ZXN0GisucXVpeG9zLm9yY2guTGlzdFBhY2thZ2VEZXNjcmlwdG9yc1Jlc3BvbnNlEmgKE0xpc3RQYWNrYWdlUnVudGltZXMSJy5xdWl4b3Mub3JjaC5MaXN0UGFja2FnZVJ1bnRpbWVzUmVxdWVzdBooLnF1aXhvcy5vcmNoLkxpc3RQYWNrYWdlUnVudGltZXNSZXNwb25zZRJcCg9MaXN0QWN0aXZhdGlvbnMSIy5xdWl4b3Mub3JjaC5MaXN0QWN0aXZhdGlvbnNSZXF1ZXN0GiQucXVpeG9zLm9yY2guTGlzdEFjdGl2YXRpb25zUmVzcG9uc2USXAoPQ2xvc2VBY3RpdmF0aW9uEiMucXVpeG9zLm9yY2guQ2xvc2VBY3RpdmF0aW9uUmVxdWVzdBokLnF1aXhvcy5vcmNoLkNsb3NlQWN0aXZhdGlvblJlc3BvbnNlYgZwcm90bzM", [file_camino_api, file_quixos_package, file_quixos_refs, file_quixos_runtime]);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.ConstructObjectRequest.
|
* Describes the message quixos.orch.ConstructObjectRequest.
|
||||||
* Use `create(ConstructObjectRequestSchema)` to create a new message.
|
* Use `create(ConstructObjectRequestSchema)` to create a new message.
|
||||||
@@ -20,86 +20,96 @@ export const ConstructObjectRequestSchema = /*@__PURE__*/ messageDesc(file_quixo
|
|||||||
* Use `create(ConstructObjectResponseSchema)` to create a new message.
|
* Use `create(ConstructObjectResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ConstructObjectResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 1);
|
export const ConstructObjectResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 1);
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.orch.ResolveOrConstructRelatedObjectRequest.
|
||||||
|
* Use `create(ResolveOrConstructRelatedObjectRequestSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export const ResolveOrConstructRelatedObjectRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 2);
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.orch.ResolveOrConstructRelatedObjectResponse.
|
||||||
|
* Use `create(ResolveOrConstructRelatedObjectResponseSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export const ResolveOrConstructRelatedObjectResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 3);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.InvokeCapabilityRequest.
|
* Describes the message quixos.orch.InvokeCapabilityRequest.
|
||||||
* Use `create(InvokeCapabilityRequestSchema)` to create a new message.
|
* Use `create(InvokeCapabilityRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const InvokeCapabilityRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 2);
|
export const InvokeCapabilityRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 4);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.InvokeCapabilityResponse.
|
* Describes the message quixos.orch.InvokeCapabilityResponse.
|
||||||
* Use `create(InvokeCapabilityResponseSchema)` to create a new message.
|
* Use `create(InvokeCapabilityResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const InvokeCapabilityResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 3);
|
export const InvokeCapabilityResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 5);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.WatchCapabilityRequest.
|
* Describes the message quixos.orch.WatchCapabilityRequest.
|
||||||
* Use `create(WatchCapabilityRequestSchema)` to create a new message.
|
* Use `create(WatchCapabilityRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const WatchCapabilityRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 4);
|
export const WatchCapabilityRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 6);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.WatchCapabilityEvent.
|
* Describes the message quixos.orch.WatchCapabilityEvent.
|
||||||
* Use `create(WatchCapabilityEventSchema)` to create a new message.
|
* Use `create(WatchCapabilityEventSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const WatchCapabilityEventSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 5);
|
export const WatchCapabilityEventSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 7);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.GetWorkspaceRequest.
|
* Describes the message quixos.orch.GetWorkspaceRequest.
|
||||||
* Use `create(GetWorkspaceRequestSchema)` to create a new message.
|
* Use `create(GetWorkspaceRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const GetWorkspaceRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 6);
|
export const GetWorkspaceRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 8);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.GetWorkspaceResponse.
|
* Describes the message quixos.orch.GetWorkspaceResponse.
|
||||||
* Use `create(GetWorkspaceResponseSchema)` to create a new message.
|
* Use `create(GetWorkspaceResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const GetWorkspaceResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 7);
|
export const GetWorkspaceResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 9);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.ListActivationsRequest.
|
* Describes the message quixos.orch.ListActivationsRequest.
|
||||||
* Use `create(ListActivationsRequestSchema)` to create a new message.
|
* Use `create(ListActivationsRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListActivationsRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 8);
|
export const ListActivationsRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 10);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.ListPackageDescriptorsRequest.
|
* Describes the message quixos.orch.ListPackageDescriptorsRequest.
|
||||||
* Use `create(ListPackageDescriptorsRequestSchema)` to create a new message.
|
* Use `create(ListPackageDescriptorsRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListPackageDescriptorsRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 9);
|
export const ListPackageDescriptorsRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 11);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.ListPackageDescriptorsResponse.
|
* Describes the message quixos.orch.ListPackageDescriptorsResponse.
|
||||||
* Use `create(ListPackageDescriptorsResponseSchema)` to create a new message.
|
* Use `create(ListPackageDescriptorsResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListPackageDescriptorsResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 10);
|
export const ListPackageDescriptorsResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 12);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.ListPackageRuntimesRequest.
|
* Describes the message quixos.orch.ListPackageRuntimesRequest.
|
||||||
* Use `create(ListPackageRuntimesRequestSchema)` to create a new message.
|
* Use `create(ListPackageRuntimesRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListPackageRuntimesRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 11);
|
export const ListPackageRuntimesRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 13);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.ListPackageRuntimesResponse.
|
* Describes the message quixos.orch.ListPackageRuntimesResponse.
|
||||||
* Use `create(ListPackageRuntimesResponseSchema)` to create a new message.
|
* Use `create(ListPackageRuntimesResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListPackageRuntimesResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 12);
|
export const ListPackageRuntimesResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 14);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.ListActivationsResponse.
|
* Describes the message quixos.orch.ListActivationsResponse.
|
||||||
* Use `create(ListActivationsResponseSchema)` to create a new message.
|
* Use `create(ListActivationsResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListActivationsResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 13);
|
export const ListActivationsResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 15);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.CloseActivationRequest.
|
* Describes the message quixos.orch.CloseActivationRequest.
|
||||||
* Use `create(CloseActivationRequestSchema)` to create a new message.
|
* Use `create(CloseActivationRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const CloseActivationRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 14);
|
export const CloseActivationRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 16);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.CloseActivationResponse.
|
* Describes the message quixos.orch.CloseActivationResponse.
|
||||||
* Use `create(CloseActivationResponseSchema)` to create a new message.
|
* Use `create(CloseActivationResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const CloseActivationResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 15);
|
export const CloseActivationResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 17);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.Activation.
|
* Describes the message quixos.orch.Activation.
|
||||||
* Use `create(ActivationSchema)` to create a new message.
|
* Use `create(ActivationSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ActivationSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 16);
|
export const ActivationSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 18);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.orch.PackageRuntimeStatus.
|
* Describes the message quixos.orch.PackageRuntimeStatus.
|
||||||
* Use `create(PackageRuntimeStatusSchema)` to create a new message.
|
* Use `create(PackageRuntimeStatusSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const PackageRuntimeStatusSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 17);
|
export const PackageRuntimeStatusSchema = /*@__PURE__*/ messageDesc(file_quixos_orch, 19);
|
||||||
/**
|
/**
|
||||||
* @generated from service quixos.orch.OrchestratorRuntime
|
* @generated from service quixos.orch.OrchestratorRuntime
|
||||||
*/
|
*/
|
||||||
|
|||||||
Vendored
+2
-18
@@ -17,27 +17,11 @@ export type PackageDescriptor = Message<"quixos.PackageDescriptor"> & {
|
|||||||
*/
|
*/
|
||||||
packageRevisionId: string;
|
packageRevisionId: string;
|
||||||
/**
|
/**
|
||||||
* @generated from field: string source_repo = 3;
|
* @generated from field: string runtime_protocol_version = 3;
|
||||||
*/
|
|
||||||
sourceRepo: string;
|
|
||||||
/**
|
|
||||||
* @generated from field: string source_ref = 4;
|
|
||||||
*/
|
|
||||||
sourceRef: string;
|
|
||||||
/**
|
|
||||||
* @generated from field: string resolved_source_ref = 5;
|
|
||||||
*/
|
|
||||||
resolvedSourceRef: string;
|
|
||||||
/**
|
|
||||||
* @generated from field: string server_installable = 6;
|
|
||||||
*/
|
|
||||||
serverInstallable: string;
|
|
||||||
/**
|
|
||||||
* @generated from field: string runtime_protocol_version = 7;
|
|
||||||
*/
|
*/
|
||||||
runtimeProtocolVersion: string;
|
runtimeProtocolVersion: string;
|
||||||
/**
|
/**
|
||||||
* @generated from field: repeated quixos.RuntimeExport exports = 8;
|
* @generated from field: repeated quixos.RuntimeExport exports = 4;
|
||||||
*/
|
*/
|
||||||
exports: RuntimeExport[];
|
exports: RuntimeExport[];
|
||||||
};
|
};
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"package_pb.d.ts","sourceRoot":"","sources":["../../src/quixos/package_pb.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAExE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,OACmb,CAAC;AAEtd;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,0BAA0B,CAAC,GAAG;IACpE;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,UAAU,CAAC,iBAAiB,CAC7B,CAAC;AAEtC;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,sBAAsB,CAAC,GAAG;IAC5D;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAAU,CAAC,aAAa,CACrB,CAAC"}
|
{"version":3,"file":"package_pb.d.ts","sourceRoot":"","sources":["../../src/quixos/package_pb.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAExE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,OACgT,CAAC;AAEnV;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,0BAA0B,CAAC,GAAG;IACpE;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,UAAU,CAAC,iBAAiB,CAC7B,CAAC;AAEtC;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,sBAAsB,CAAC,GAAG;IAC5D;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAAU,CAAC,aAAa,CACrB,CAAC"}
|
||||||
Vendored
+1
-1
@@ -5,7 +5,7 @@ import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
|||||||
/**
|
/**
|
||||||
* Describes the file quixos/package.proto.
|
* Describes the file quixos/package.proto.
|
||||||
*/
|
*/
|
||||||
export const file_quixos_package = /*@__PURE__*/ fileDesc("ChRxdWl4b3MvcGFja2FnZS5wcm90bxIGcXVpeG9zIvABChFQYWNrYWdlRGVzY3JpcHRvchISCgpwYWNrYWdlX2lkGAEgASgJEhsKE3BhY2thZ2VfcmV2aXNpb25faWQYAiABKAkSEwoLc291cmNlX3JlcG8YAyABKAkSEgoKc291cmNlX3JlZhgEIAEoCRIbChNyZXNvbHZlZF9zb3VyY2VfcmVmGAUgASgJEhoKEnNlcnZlcl9pbnN0YWxsYWJsZRgGIAEoCRIgChhydW50aW1lX3Byb3RvY29sX3ZlcnNpb24YByABKAkSJgoHZXhwb3J0cxgIIAMoCzIVLnF1aXhvcy5SdW50aW1lRXhwb3J0IjoKDVJ1bnRpbWVFeHBvcnQSEQoJZXhwb3J0X2lkGAEgASgJEhYKDnJ1bnRpbWVfc3ltYm9sGAIgASgJYgZwcm90bzM");
|
export const file_quixos_package = /*@__PURE__*/ fileDesc("ChRxdWl4b3MvcGFja2FnZS5wcm90bxIGcXVpeG9zIo4BChFQYWNrYWdlRGVzY3JpcHRvchISCgpwYWNrYWdlX2lkGAEgASgJEhsKE3BhY2thZ2VfcmV2aXNpb25faWQYAiABKAkSIAoYcnVudGltZV9wcm90b2NvbF92ZXJzaW9uGAMgASgJEiYKB2V4cG9ydHMYBCADKAsyFS5xdWl4b3MuUnVudGltZUV4cG9ydCI6Cg1SdW50aW1lRXhwb3J0EhEKCWV4cG9ydF9pZBgBIAEoCRIWCg5ydW50aW1lX3N5bWJvbBgCIAEoCWIGcHJvdG8z");
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.PackageDescriptor.
|
* Describes the message quixos.PackageDescriptor.
|
||||||
* Use `create(PackageDescriptorSchema)` to create a new message.
|
* Use `create(PackageDescriptorSchema)` to create a new message.
|
||||||
|
|||||||
Vendored
+9
-2
@@ -65,10 +65,10 @@ export type InjectedDependency = Message<"quixos.InjectedDependency"> & {
|
|||||||
case: "edge";
|
case: "edge";
|
||||||
} | {
|
} | {
|
||||||
/**
|
/**
|
||||||
* @generated from field: string receiver_interface_revision_id = 4;
|
* @generated from field: string interface_revision_id = 4;
|
||||||
*/
|
*/
|
||||||
value: string;
|
value: string;
|
||||||
case: "receiverInterfaceRevisionId";
|
case: "interfaceRevisionId";
|
||||||
} | {
|
} | {
|
||||||
/**
|
/**
|
||||||
* @generated from field: string constructor_atom_id = 5;
|
* @generated from field: string constructor_atom_id = 5;
|
||||||
@@ -79,6 +79,13 @@ export type InjectedDependency = Message<"quixos.InjectedDependency"> & {
|
|||||||
case: undefined;
|
case: undefined;
|
||||||
value?: undefined;
|
value?: undefined;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Defaults to the invocation receiver. A checked dependency traversal can
|
||||||
|
* select a related object explicitly before the package runtime starts.
|
||||||
|
*
|
||||||
|
* @generated from field: string object_id = 6;
|
||||||
|
*/
|
||||||
|
objectId: string;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.InjectedDependency.
|
* Describes the message quixos.InjectedDependency.
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"refs_pb.d.ts","sourceRoot":"","sources":["../../src/quixos/refs_pb.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAExE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,OACsiB,CAAC;AAEtkB;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,sBAAsB,CAAC,GAAG;IAC5D;;OAEG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAAU,CAAC,aAAa,CACxB,CAAC;AAEnC;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,yBAAyB,CAAC,GAAG;IAClE;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,UAAU,CAAC,gBAAgB,CAC9B,CAAC;AAEnC;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,2BAA2B,CAAC,GAAG;IACtE;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,EAAE;QACP;;WAEG;QACH,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,aAAa,CAAC;KACrB,GAAG;QACF;;WAEG;QACH,KAAK,EAAE,cAAc,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;KACd,GAAG;QACF;;WAEG;QACH,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,6BAA6B,CAAC;KACrC,GAAG;QACF;;WAEG;QACH,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,mBAAmB,CAAC;KAC3B,GAAG;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,KAAK,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC;CAC5C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,UAAU,CAAC,kBAAkB,CAClC,CAAC;AAEnC;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,uBAAuB,CAAC,GAAG;IAC9D;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,UAAU,CAAC,cAAc,CAC1B,CAAC"}
|
{"version":3,"file":"refs_pb.d.ts","sourceRoot":"","sources":["../../src/quixos/refs_pb.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAExE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,OACmjB,CAAC;AAEnlB;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,sBAAsB,CAAC,GAAG;IAC5D;;OAEG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAAU,CAAC,aAAa,CACxB,CAAC;AAEnC;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,yBAAyB,CAAC,GAAG;IAClE;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,UAAU,CAAC,gBAAgB,CAC9B,CAAC;AAEnC;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,2BAA2B,CAAC,GAAG;IACtE;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,EAAE;QACP;;WAEG;QACH,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,aAAa,CAAC;KACrB,GAAG;QACF;;WAEG;QACH,KAAK,EAAE,cAAc,CAAC;QACtB,IAAI,EAAE,MAAM,CAAC;KACd,GAAG;QACF;;WAEG;QACH,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,qBAAqB,CAAC;KAC7B,GAAG;QACF;;WAEG;QACH,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,mBAAmB,CAAC;KAC3B,GAAG;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,KAAK,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC;IAE3C;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,UAAU,CAAC,kBAAkB,CAClC,CAAC;AAEnC;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,uBAAuB,CAAC,GAAG;IAC9D;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,UAAU,CAAC,cAAc,CAC1B,CAAC"}
|
||||||
Vendored
+1
-1
@@ -5,7 +5,7 @@ import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
|||||||
/**
|
/**
|
||||||
* Describes the file quixos/refs.proto.
|
* Describes the file quixos/refs.proto.
|
||||||
*/
|
*/
|
||||||
export const file_quixos_refs = /*@__PURE__*/ fileDesc("ChFxdWl4b3MvcmVmcy5wcm90bxIGcXVpeG9zIkQKDUNhcGFiaWxpdHlSZWYSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAEgASgJEhQKDG9wZXJhdGlvbl9pZBgCIAEoCSJCChBQYWNrYWdlRXhwb3J0UmVmEhsKE3BhY2thZ2VfcmV2aXNpb25faWQYASABKAkSEQoJZXhwb3J0X2lkGAIgASgJIroBChJJbmplY3RlZERlcGVuZGVuY3kSDwoHcG9ydF9pZBgBIAEoCRIXCg1zdGF0ZV9zbG90X2lkGAIgASgJSAASJgoEZWRnZRgDIAEoCzIWLnF1aXhvcy5FZGdlRGVwZW5kZW5jeUgAEigKHnJlY2VpdmVyX2ludGVyZmFjZV9yZXZpc2lvbl9pZBgEIAEoCUgAEh0KE2NvbnN0cnVjdG9yX2F0b21faWQYBSABKAlIAEIJCgdiaW5kaW5nIj0KDkVkZ2VEZXBlbmRlbmN5EhQKDGVkZ2VfdHlwZV9pZBgBIAEoCRIVCg1wcm9qZWN0aW9uX2lkGAIgASgJYgZwcm90bzM");
|
export const file_quixos_refs = /*@__PURE__*/ fileDesc("ChFxdWl4b3MvcmVmcy5wcm90bxIGcXVpeG9zIkQKDUNhcGFiaWxpdHlSZWYSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAEgASgJEhQKDG9wZXJhdGlvbl9pZBgCIAEoCSJCChBQYWNrYWdlRXhwb3J0UmVmEhsKE3BhY2thZ2VfcmV2aXNpb25faWQYASABKAkSEQoJZXhwb3J0X2lkGAIgASgJIsQBChJJbmplY3RlZERlcGVuZGVuY3kSDwoHcG9ydF9pZBgBIAEoCRIXCg1zdGF0ZV9zbG90X2lkGAIgASgJSAASJgoEZWRnZRgDIAEoCzIWLnF1aXhvcy5FZGdlRGVwZW5kZW5jeUgAEh8KFWludGVyZmFjZV9yZXZpc2lvbl9pZBgEIAEoCUgAEh0KE2NvbnN0cnVjdG9yX2F0b21faWQYBSABKAlIABIRCglvYmplY3RfaWQYBiABKAlCCQoHYmluZGluZyI9Cg5FZGdlRGVwZW5kZW5jeRIUCgxlZGdlX3R5cGVfaWQYASABKAkSFQoNcHJvamVjdGlvbl9pZBgCIAEoCWIGcHJvdG8z");
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.CapabilityRef.
|
* Describes the message quixos.CapabilityRef.
|
||||||
* Use `create(CapabilityRefSchema)` to create a new message.
|
* Use `create(CapabilityRefSchema)` to create a new message.
|
||||||
|
|||||||
Vendored
+114
@@ -14,6 +14,10 @@ export type HandshakeRequest = Message<"quixos.runtime.HandshakeRequest"> & {
|
|||||||
* @generated from field: string orch_protocol_version = 1;
|
* @generated from field: string orch_protocol_version = 1;
|
||||||
*/
|
*/
|
||||||
orchProtocolVersion: string;
|
orchProtocolVersion: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string nonce = 2;
|
||||||
|
*/
|
||||||
|
nonce: string;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.runtime.HandshakeRequest.
|
* Describes the message quixos.runtime.HandshakeRequest.
|
||||||
@@ -36,12 +40,94 @@ export type HandshakeResponse = Message<"quixos.runtime.HandshakeResponse"> & {
|
|||||||
* @generated from field: repeated string export_ids = 3;
|
* @generated from field: repeated string export_ids = 3;
|
||||||
*/
|
*/
|
||||||
exportIds: string[];
|
exportIds: string[];
|
||||||
|
/**
|
||||||
|
* @generated from field: string instance_id = 4;
|
||||||
|
*/
|
||||||
|
instanceId: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string authentication_proof = 5;
|
||||||
|
*/
|
||||||
|
authenticationProof: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: repeated string capabilities = 6;
|
||||||
|
*/
|
||||||
|
capabilities: string[];
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.runtime.HandshakeResponse.
|
* Describes the message quixos.runtime.HandshakeResponse.
|
||||||
* Use `create(HandshakeResponseSchema)` to create a new message.
|
* Use `create(HandshakeResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export declare const HandshakeResponseSchema: GenMessage<HandshakeResponse>;
|
export declare const HandshakeResponseSchema: GenMessage<HandshakeResponse>;
|
||||||
|
/**
|
||||||
|
* @generated from message quixos.runtime.InvocationContext
|
||||||
|
*/
|
||||||
|
export type InvocationContext = Message<"quixos.runtime.InvocationContext"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: string workspace_epoch = 1;
|
||||||
|
*/
|
||||||
|
workspaceEpoch: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string instance_id = 2;
|
||||||
|
*/
|
||||||
|
instanceId: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string binding_digest = 3;
|
||||||
|
*/
|
||||||
|
bindingDigest: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string grant = 4;
|
||||||
|
*/
|
||||||
|
grant: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: string session_id = 5;
|
||||||
|
*/
|
||||||
|
sessionId: string;
|
||||||
|
/**
|
||||||
|
* Host-selected owner; packages must not invent workspace-local ownership.
|
||||||
|
*
|
||||||
|
* @generated from field: string owner_conformance_id = 6;
|
||||||
|
*/
|
||||||
|
ownerConformanceId: string;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.runtime.InvocationContext.
|
||||||
|
* Use `create(InvocationContextSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export declare const InvocationContextSchema: GenMessage<InvocationContext>;
|
||||||
|
/**
|
||||||
|
* @generated from message quixos.runtime.InvocationControlRequest
|
||||||
|
*/
|
||||||
|
export type InvocationControlRequest = Message<"quixos.runtime.InvocationControlRequest"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: string invocation_id = 1;
|
||||||
|
*/
|
||||||
|
invocationId: string;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.runtime.InvocationControlRequest.
|
||||||
|
* Use `create(InvocationControlRequestSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export declare const InvocationControlRequestSchema: GenMessage<InvocationControlRequest>;
|
||||||
|
/**
|
||||||
|
* @generated from message quixos.runtime.InvocationStatus
|
||||||
|
*/
|
||||||
|
export type InvocationStatus = Message<"quixos.runtime.InvocationStatus"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: string invocation_id = 1;
|
||||||
|
*/
|
||||||
|
invocationId: string;
|
||||||
|
/**
|
||||||
|
* unknown, running, cancellation-requested, completed, failed
|
||||||
|
*
|
||||||
|
* @generated from field: string state = 2;
|
||||||
|
*/
|
||||||
|
state: string;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.runtime.InvocationStatus.
|
||||||
|
* Use `create(InvocationStatusSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export declare const InvocationStatusSchema: GenMessage<InvocationStatus>;
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.runtime.InvokeRequest
|
* @generated from message quixos.runtime.InvokeRequest
|
||||||
*/
|
*/
|
||||||
@@ -68,6 +154,10 @@ export type InvokeRequest = Message<"quixos.runtime.InvokeRequest"> & {
|
|||||||
* @generated from field: repeated quixos.InjectedDependency dependencies = 5;
|
* @generated from field: repeated quixos.InjectedDependency dependencies = 5;
|
||||||
*/
|
*/
|
||||||
dependencies: InjectedDependency[];
|
dependencies: InjectedDependency[];
|
||||||
|
/**
|
||||||
|
* @generated from field: quixos.runtime.InvocationContext context = 6;
|
||||||
|
*/
|
||||||
|
context?: InvocationContext | undefined;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.runtime.InvokeRequest.
|
* Describes the message quixos.runtime.InvokeRequest.
|
||||||
@@ -90,6 +180,10 @@ export type InvokeResponse = Message<"quixos.runtime.InvokeResponse"> & {
|
|||||||
* @generated from field: string error = 3;
|
* @generated from field: string error = 3;
|
||||||
*/
|
*/
|
||||||
error: string;
|
error: string;
|
||||||
|
/**
|
||||||
|
* @generated from field: repeated quixos.runtime.DerivedDependency dependencies = 4;
|
||||||
|
*/
|
||||||
|
dependencies: DerivedDependency[];
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.runtime.InvokeResponse.
|
* Describes the message quixos.runtime.InvokeResponse.
|
||||||
@@ -122,6 +216,10 @@ export type WatchRequest = Message<"quixos.runtime.WatchRequest"> & {
|
|||||||
* @generated from field: repeated quixos.InjectedDependency dependencies = 5;
|
* @generated from field: repeated quixos.InjectedDependency dependencies = 5;
|
||||||
*/
|
*/
|
||||||
dependencies: InjectedDependency[];
|
dependencies: InjectedDependency[];
|
||||||
|
/**
|
||||||
|
* @generated from field: quixos.runtime.InvocationContext context = 6;
|
||||||
|
*/
|
||||||
|
context?: InvocationContext | undefined;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.runtime.WatchRequest.
|
* Describes the message quixos.runtime.WatchRequest.
|
||||||
@@ -212,5 +310,21 @@ export declare const PackageRuntime: GenService<{
|
|||||||
input: typeof WatchRequestSchema;
|
input: typeof WatchRequestSchema;
|
||||||
output: typeof WatchEventSchema;
|
output: typeof WatchEventSchema;
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @generated from rpc quixos.runtime.PackageRuntime.GetInvocationStatus
|
||||||
|
*/
|
||||||
|
getInvocationStatus: {
|
||||||
|
methodKind: "unary";
|
||||||
|
input: typeof InvocationControlRequestSchema;
|
||||||
|
output: typeof InvocationStatusSchema;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @generated from rpc quixos.runtime.PackageRuntime.CancelInvocation
|
||||||
|
*/
|
||||||
|
cancelInvocation: {
|
||||||
|
methodKind: "unary";
|
||||||
|
input: typeof InvocationControlRequestSchema;
|
||||||
|
output: typeof InvocationStatusSchema;
|
||||||
|
};
|
||||||
}>;
|
}>;
|
||||||
//# sourceMappingURL=runtime_pb.d.ts.map
|
//# sourceMappingURL=runtime_pb.d.ts.map
|
||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"runtime_pb.d.ts","sourceRoot":"","sources":["../../src/quixos/runtime_pb.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"runtime_pb.d.ts","sourceRoot":"","sources":["../../src/quixos/runtime_pb.ts"],"names":[],"mappings":"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"}
|
||||||
Vendored
+21
-6
@@ -7,7 +7,7 @@ import { file_quixos_refs } from "./refs_pb.js";
|
|||||||
/**
|
/**
|
||||||
* Describes the file quixos/runtime.proto.
|
* Describes the file quixos/runtime.proto.
|
||||||
*/
|
*/
|
||||||
export const file_quixos_runtime = /*@__PURE__*/ fileDesc("ChRxdWl4b3MvcnVudGltZS5wcm90bxIOcXVpeG9zLnJ1bnRpbWUiMQoQSGFuZHNoYWtlUmVxdWVzdBIdChVvcmNoX3Byb3RvY29sX3ZlcnNpb24YASABKAkiZgoRSGFuZHNoYWtlUmVzcG9uc2USGwoTcGFja2FnZV9yZXZpc2lvbl9pZBgBIAEoCRIgChhydW50aW1lX3Byb3RvY29sX3ZlcnNpb24YAiABKAkSEgoKZXhwb3J0X2lkcxgDIAMoCSKLAgoNSW52b2tlUmVxdWVzdBIVCg1pbnZvY2F0aW9uX2lkGAEgASgJEigKBmV4cG9ydBgCIAEoCzIYLnF1aXhvcy5QYWNrYWdlRXhwb3J0UmVmEhEKCW9iamVjdF9pZBgDIAEoCRI3CgVpbnB1dBgEIAMoCzIoLnF1aXhvcy5ydW50aW1lLkludm9rZVJlcXVlc3QuSW5wdXRFbnRyeRIwCgxkZXBlbmRlbmNpZXMYBSADKAsyGi5xdWl4b3MuSW5qZWN0ZWREZXBlbmRlbmN5GjsKCklucHV0RW50cnkSCwoDa2V5GAEgASgJEhwKBXZhbHVlGAIgASgLMg0uY2FtaW5vLlZhbHVlOgI4ASJKCg5JbnZva2VSZXNwb25zZRIKCgJvaxgBIAEoCBIdCgZyZXN1bHQYAiABKAsyDS5jYW1pbm8uVmFsdWUSDQoFZXJyb3IYAyABKAkiiQIKDFdhdGNoUmVxdWVzdBIVCg1pbnZvY2F0aW9uX2lkGAEgASgJEigKBmV4cG9ydBgCIAEoCzIYLnF1aXhvcy5QYWNrYWdlRXhwb3J0UmVmEhEKCW9iamVjdF9pZBgDIAEoCRI2CgVpbnB1dBgEIAMoCzInLnF1aXhvcy5ydW50aW1lLldhdGNoUmVxdWVzdC5JbnB1dEVudHJ5EjAKDGRlcGVuZGVuY2llcxgFIAMoCzIaLnF1aXhvcy5JbmplY3RlZERlcGVuZGVuY3kaOwoKSW5wdXRFbnRyeRILCgNrZXkYASABKAkSHAoFdmFsdWUYAiABKAsyDS5jYW1pbm8uVmFsdWU6AjgBImIKEURlcml2ZWREZXBlbmRlbmN5EgwKBGtpbmQYASABKAkSEQoJb2JqZWN0X2lkGAIgASgJEhUKDWF0dGFjaG1lbnRfaWQYAyABKAkSFQoNcHJvamVjdGlvbl9pZBgEIAEoCSKVAQoKV2F0Y2hFdmVudBIQCgh3YXRjaF9pZBgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLmNhbWluby5WYWx1ZRI3CgxkZXBlbmRlbmNpZXMYAyADKAsyIS5xdWl4b3MucnVudGltZS5EZXJpdmVkRGVwZW5kZW5jeRINCgVlcnJvchgEIAEoCRIPCgdpbml0aWFsGAUgASgIMvABCg5QYWNrYWdlUnVudGltZRJQCglIYW5kc2hha2USIC5xdWl4b3MucnVudGltZS5IYW5kc2hha2VSZXF1ZXN0GiEucXVpeG9zLnJ1bnRpbWUuSGFuZHNoYWtlUmVzcG9uc2USRwoGSW52b2tlEh0ucXVpeG9zLnJ1bnRpbWUuSW52b2tlUmVxdWVzdBoeLnF1aXhvcy5ydW50aW1lLkludm9rZVJlc3BvbnNlEkMKBVdhdGNoEhwucXVpeG9zLnJ1bnRpbWUuV2F0Y2hSZXF1ZXN0GhoucXVpeG9zLnJ1bnRpbWUuV2F0Y2hFdmVudDABYgZwcm90bzM", [file_camino_api, file_quixos_refs]);
|
export const file_quixos_runtime = /*@__PURE__*/ fileDesc("ChRxdWl4b3MvcnVudGltZS5wcm90bxIOcXVpeG9zLnJ1bnRpbWUiQAoQSGFuZHNoYWtlUmVxdWVzdBIdChVvcmNoX3Byb3RvY29sX3ZlcnNpb24YASABKAkSDQoFbm9uY2UYAiABKAkirwEKEUhhbmRzaGFrZVJlc3BvbnNlEhsKE3BhY2thZ2VfcmV2aXNpb25faWQYASABKAkSIAoYcnVudGltZV9wcm90b2NvbF92ZXJzaW9uGAIgASgJEhIKCmV4cG9ydF9pZHMYAyADKAkSEwoLaW5zdGFuY2VfaWQYBCABKAkSHAoUYXV0aGVudGljYXRpb25fcHJvb2YYBSABKAkSFAoMY2FwYWJpbGl0aWVzGAYgAygJIpoBChFJbnZvY2F0aW9uQ29udGV4dBIXCg93b3Jrc3BhY2VfZXBvY2gYASABKAkSEwoLaW5zdGFuY2VfaWQYAiABKAkSFgoOYmluZGluZ19kaWdlc3QYAyABKAkSDQoFZ3JhbnQYBCABKAkSEgoKc2Vzc2lvbl9pZBgFIAEoCRIcChRvd25lcl9jb25mb3JtYW5jZV9pZBgGIAEoCSIxChhJbnZvY2F0aW9uQ29udHJvbFJlcXVlc3QSFQoNaW52b2NhdGlvbl9pZBgBIAEoCSI4ChBJbnZvY2F0aW9uU3RhdHVzEhUKDWludm9jYXRpb25faWQYASABKAkSDQoFc3RhdGUYAiABKAkivwIKDUludm9rZVJlcXVlc3QSFQoNaW52b2NhdGlvbl9pZBgBIAEoCRIoCgZleHBvcnQYAiABKAsyGC5xdWl4b3MuUGFja2FnZUV4cG9ydFJlZhIRCglvYmplY3RfaWQYAyABKAkSNwoFaW5wdXQYBCADKAsyKC5xdWl4b3MucnVudGltZS5JbnZva2VSZXF1ZXN0LklucHV0RW50cnkSMAoMZGVwZW5kZW5jaWVzGAUgAygLMhoucXVpeG9zLkluamVjdGVkRGVwZW5kZW5jeRIyCgdjb250ZXh0GAYgASgLMiEucXVpeG9zLnJ1bnRpbWUuSW52b2NhdGlvbkNvbnRleHQaOwoKSW5wdXRFbnRyeRILCgNrZXkYASABKAkSHAoFdmFsdWUYAiABKAsyDS5jYW1pbm8uVmFsdWU6AjgBIoMBCg5JbnZva2VSZXNwb25zZRIKCgJvaxgBIAEoCBIdCgZyZXN1bHQYAiABKAsyDS5jYW1pbm8uVmFsdWUSDQoFZXJyb3IYAyABKAkSNwoMZGVwZW5kZW5jaWVzGAQgAygLMiEucXVpeG9zLnJ1bnRpbWUuRGVyaXZlZERlcGVuZGVuY3kivQIKDFdhdGNoUmVxdWVzdBIVCg1pbnZvY2F0aW9uX2lkGAEgASgJEigKBmV4cG9ydBgCIAEoCzIYLnF1aXhvcy5QYWNrYWdlRXhwb3J0UmVmEhEKCW9iamVjdF9pZBgDIAEoCRI2CgVpbnB1dBgEIAMoCzInLnF1aXhvcy5ydW50aW1lLldhdGNoUmVxdWVzdC5JbnB1dEVudHJ5EjAKDGRlcGVuZGVuY2llcxgFIAMoCzIaLnF1aXhvcy5JbmplY3RlZERlcGVuZGVuY3kSMgoHY29udGV4dBgGIAEoCzIhLnF1aXhvcy5ydW50aW1lLkludm9jYXRpb25Db250ZXh0GjsKCklucHV0RW50cnkSCwoDa2V5GAEgASgJEhwKBXZhbHVlGAIgASgLMg0uY2FtaW5vLlZhbHVlOgI4ASJiChFEZXJpdmVkRGVwZW5kZW5jeRIMCgRraW5kGAEgASgJEhEKCW9iamVjdF9pZBgCIAEoCRIVCg1hdHRhY2htZW50X2lkGAMgASgJEhUKDXByb2plY3Rpb25faWQYBCABKAkilQEKCldhdGNoRXZlbnQSEAoId2F0Y2hfaWQYASABKAkSHAoFdmFsdWUYAiABKAsyDS5jYW1pbm8uVmFsdWUSNwoMZGVwZW5kZW5jaWVzGAMgAygLMiEucXVpeG9zLnJ1bnRpbWUuRGVyaXZlZERlcGVuZGVuY3kSDQoFZXJyb3IYBCABKAkSDwoHaW5pdGlhbBgFIAEoCDKzAwoOUGFja2FnZVJ1bnRpbWUSUAoJSGFuZHNoYWtlEiAucXVpeG9zLnJ1bnRpbWUuSGFuZHNoYWtlUmVxdWVzdBohLnF1aXhvcy5ydW50aW1lLkhhbmRzaGFrZVJlc3BvbnNlEkcKBkludm9rZRIdLnF1aXhvcy5ydW50aW1lLkludm9rZVJlcXVlc3QaHi5xdWl4b3MucnVudGltZS5JbnZva2VSZXNwb25zZRJDCgVXYXRjaBIcLnF1aXhvcy5ydW50aW1lLldhdGNoUmVxdWVzdBoaLnF1aXhvcy5ydW50aW1lLldhdGNoRXZlbnQwARJhChNHZXRJbnZvY2F0aW9uU3RhdHVzEigucXVpeG9zLnJ1bnRpbWUuSW52b2NhdGlvbkNvbnRyb2xSZXF1ZXN0GiAucXVpeG9zLnJ1bnRpbWUuSW52b2NhdGlvblN0YXR1cxJeChBDYW5jZWxJbnZvY2F0aW9uEigucXVpeG9zLnJ1bnRpbWUuSW52b2NhdGlvbkNvbnRyb2xSZXF1ZXN0GiAucXVpeG9zLnJ1bnRpbWUuSW52b2NhdGlvblN0YXR1c2IGcHJvdG8z", [file_camino_api, file_quixos_refs]);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.runtime.HandshakeRequest.
|
* Describes the message quixos.runtime.HandshakeRequest.
|
||||||
* Use `create(HandshakeRequestSchema)` to create a new message.
|
* Use `create(HandshakeRequestSchema)` to create a new message.
|
||||||
@@ -18,31 +18,46 @@ export const HandshakeRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_runt
|
|||||||
* Use `create(HandshakeResponseSchema)` to create a new message.
|
* Use `create(HandshakeResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const HandshakeResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 1);
|
export const HandshakeResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 1);
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.runtime.InvocationContext.
|
||||||
|
* Use `create(InvocationContextSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export const InvocationContextSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 2);
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.runtime.InvocationControlRequest.
|
||||||
|
* Use `create(InvocationControlRequestSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export const InvocationControlRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 3);
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.runtime.InvocationStatus.
|
||||||
|
* Use `create(InvocationStatusSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export const InvocationStatusSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 4);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.runtime.InvokeRequest.
|
* Describes the message quixos.runtime.InvokeRequest.
|
||||||
* Use `create(InvokeRequestSchema)` to create a new message.
|
* Use `create(InvokeRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const InvokeRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 2);
|
export const InvokeRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 5);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.runtime.InvokeResponse.
|
* Describes the message quixos.runtime.InvokeResponse.
|
||||||
* Use `create(InvokeResponseSchema)` to create a new message.
|
* Use `create(InvokeResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const InvokeResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 3);
|
export const InvokeResponseSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 6);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.runtime.WatchRequest.
|
* Describes the message quixos.runtime.WatchRequest.
|
||||||
* Use `create(WatchRequestSchema)` to create a new message.
|
* Use `create(WatchRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const WatchRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 4);
|
export const WatchRequestSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 7);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.runtime.DerivedDependency.
|
* Describes the message quixos.runtime.DerivedDependency.
|
||||||
* Use `create(DerivedDependencySchema)` to create a new message.
|
* Use `create(DerivedDependencySchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const DerivedDependencySchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 5);
|
export const DerivedDependencySchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 8);
|
||||||
/**
|
/**
|
||||||
* Describes the message quixos.runtime.WatchEvent.
|
* Describes the message quixos.runtime.WatchEvent.
|
||||||
* Use `create(WatchEventSchema)` to create a new message.
|
* Use `create(WatchEventSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const WatchEventSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 6);
|
export const WatchEventSchema = /*@__PURE__*/ messageDesc(file_quixos_runtime, 9);
|
||||||
/**
|
/**
|
||||||
* @generated from service quixos.runtime.PackageRuntime
|
* @generated from service quixos.runtime.PackageRuntime
|
||||||
*/
|
*/
|
||||||
|
|||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
declare const referenceBrand: unique symbol;
|
||||||
|
export interface QxObjectRef<Identity extends string = string> {
|
||||||
|
readonly [referenceBrand]: {
|
||||||
|
readonly [K in Identity]: true;
|
||||||
|
};
|
||||||
|
equals(other: QxObjectRef<string>): boolean;
|
||||||
|
}
|
||||||
|
export declare const isObjectReference: (value: unknown) => value is QxObjectRef;
|
||||||
|
/** Internal transport boundary; intentionally not exported from the SDK entry. */
|
||||||
|
export declare const referenceFromWire: (id: string) => QxObjectRef;
|
||||||
|
export declare const referenceToWire: (value: unknown) => string;
|
||||||
|
export declare const assertReferenceFree: (value: unknown, seen?: Set<object>) => void;
|
||||||
|
export {};
|
||||||
|
//# sourceMappingURL=references.d.ts.map
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"references.d.ts","sourceRoot":"","sources":["../src/references.ts"],"names":[],"mappings":"AAGA,OAAO,CAAC,MAAM,cAAc,EAAE,OAAO,MAAM,CAAC;AAC5C,MAAM,WAAW,WAAW,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM;IAC3D,QAAQ,CAAC,CAAC,cAAc,CAAC,EAAE;QAAC,QAAQ,EAAE,CAAC,IAAI,QAAQ,GAAG,IAAI;KAAC,CAAC;IAC5D,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;CAC7C;AAQD,eAAO,MAAM,iBAAiB,UAAW,OAAO,KAAG,KAAK,IAAI,WACU,CAAC;AAEvE,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,OAAQ,MAAM,KAAG,WAG9C,CAAC;AACF,eAAO,MAAM,eAAe,UAAW,OAAO,KAAG,MAGhD,CAAC;AACF,eAAO,MAAM,mBAAmB,UAAW,OAAO,yBAA6B,IAO9E,CAAC"}
|
||||||
Vendored
+35
@@ -0,0 +1,35 @@
|
|||||||
|
/** Opaque runtime identity. The wire codec, never ordinary package state, owns
|
||||||
|
* the raw ID. These handles do not themselves confer authority or a lease. */
|
||||||
|
const identities = new WeakMap();
|
||||||
|
class Reference {
|
||||||
|
constructor(id) { identities.set(this, id); Object.freeze(this); }
|
||||||
|
equals(other) { return isObjectReference(other) && identities.get(this) === identities.get(other); }
|
||||||
|
toJSON() { throw new Error("Object references cannot be serialized into ordinary data"); }
|
||||||
|
toString() { throw new Error("Object references cannot be coerced to strings"); }
|
||||||
|
[Symbol.toPrimitive]() { throw new Error("Object references cannot be coerced to scalar values"); }
|
||||||
|
}
|
||||||
|
export const isObjectReference = (value) => typeof value === "object" && value !== null && identities.has(value);
|
||||||
|
/** Internal transport boundary; intentionally not exported from the SDK entry. */
|
||||||
|
export const referenceFromWire = (id) => {
|
||||||
|
if (typeof id !== "string" || !id)
|
||||||
|
throw new Error("Missing object reference identity");
|
||||||
|
return new Reference(id);
|
||||||
|
};
|
||||||
|
export const referenceToWire = (value) => {
|
||||||
|
if (!isObjectReference(value))
|
||||||
|
throw new Error("Expected an opaque object reference, not a raw ID");
|
||||||
|
return identities.get(value);
|
||||||
|
};
|
||||||
|
export const assertReferenceFree = (value, seen = new Set()) => {
|
||||||
|
if (!value || typeof value !== "object")
|
||||||
|
return;
|
||||||
|
if (isObjectReference(value))
|
||||||
|
throw new Error("Managed references belong in declared RPC references or graph relationships, not ordinary state/messages");
|
||||||
|
if (seen.has(value))
|
||||||
|
throw new Error("Cyclic ordinary data");
|
||||||
|
seen.add(value);
|
||||||
|
if (!(value instanceof Uint8Array))
|
||||||
|
for (const child of Object.values(value))
|
||||||
|
assertReferenceFree(child, seen);
|
||||||
|
seen.delete(value);
|
||||||
|
};
|
||||||
Vendored
+30
@@ -0,0 +1,30 @@
|
|||||||
|
import type { QxObjectRef } from "./references.js";
|
||||||
|
import type { RelationshipCollection, RelationshipEntry } from "./index.js";
|
||||||
|
type Key = string | boolean | bigint;
|
||||||
|
type Port<T extends QxObjectRef> = {
|
||||||
|
collection(): Promise<RelationshipCollection<T>>;
|
||||||
|
replace(entries: RelationshipEntry<T>[], expectedRevision: bigint): Promise<RelationshipCollection<T>>;
|
||||||
|
};
|
||||||
|
/** Helpers never retry a failed CAS or silently overwrite concurrent edits. */
|
||||||
|
export declare const relationshipMap: <T extends QxObjectRef, K extends Key = Key>(port: Port<T>) => {
|
||||||
|
read: () => Promise<RelationshipCollection<T>>;
|
||||||
|
get(key: K): Promise<{
|
||||||
|
revision: bigint;
|
||||||
|
value: T | undefined;
|
||||||
|
}>;
|
||||||
|
set(key: K, target: T, expectedRevision: bigint): Promise<RelationshipCollection<T>>;
|
||||||
|
delete(key: K, expectedRevision: bigint): Promise<RelationshipCollection<T>>;
|
||||||
|
};
|
||||||
|
export declare const relationshipList: <T extends QxObjectRef>(port: Port<T>) => {
|
||||||
|
read: () => Promise<RelationshipCollection<T>>;
|
||||||
|
insert(index: number, target: T, expectedRevision: bigint): Promise<RelationshipCollection<T>>;
|
||||||
|
move(edgeId: string, index: number, expectedRevision: bigint): Promise<RelationshipCollection<T>>;
|
||||||
|
delete(edgeId: string, expectedRevision: bigint): Promise<RelationshipCollection<T>>;
|
||||||
|
};
|
||||||
|
export declare const relationshipSet: <T extends QxObjectRef>(port: Port<T>) => {
|
||||||
|
read: () => Promise<RelationshipCollection<T>>;
|
||||||
|
add(target: T, expectedRevision: bigint): Promise<RelationshipCollection<T>>;
|
||||||
|
delete(target: T, expectedRevision: bigint): Promise<RelationshipCollection<T>>;
|
||||||
|
};
|
||||||
|
export {};
|
||||||
|
//# sourceMappingURL=relationships.d.ts.map
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../src/relationships.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAC,sBAAsB,EAAE,iBAAiB,EAAC,MAAM,YAAY,CAAC;AAC1E,KAAK,GAAG,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AACrC,KAAK,IAAI,CAAC,CAAC,SAAS,WAAW,IAAI;IAAC,UAAU,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;IAAC,OAAO,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAA;CAAC,CAAC;AAM9L,+EAA+E;AAC/E,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,GAAG,GAAG,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC;IACvF,IAAI;IACE,GAAG,MAAM,CAAC;;;;IACV,GAAG,MAAM,CAAC,UAAU,CAAC,oBAAoB,MAAM;IAO/C,MAAM,MAAM,CAAC,oBAAoB,MAAM;CAI7C,CAAC;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,WAAW,QAAQ,IAAI,CAAC,CAAC,CAAC;IACnE,IAAI;IACE,MAAM,QAAQ,MAAM,UAAU,CAAC,oBAAoB,MAAM;IAMzD,IAAI,SAAS,MAAM,SAAS,MAAM,oBAAoB,MAAM;IAQ5D,MAAM,SAAS,MAAM,oBAAoB,MAAM;CAKrD,CAAC;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,WAAW,QAAQ,IAAI,CAAC,CAAC,CAAC;IAClE,IAAI;IACE,GAAG,SAAS,CAAC,oBAAoB,MAAM;IAKvC,MAAM,SAAS,CAAC,oBAAoB,MAAM;CAIhD,CAAC"}
|
||||||
Vendored
+60
@@ -0,0 +1,60 @@
|
|||||||
|
const checked = async (port, revision) => {
|
||||||
|
const snapshot = await port.collection();
|
||||||
|
if (snapshot.revision !== revision)
|
||||||
|
throw new Error("STALE_COLLECTION_REVISION");
|
||||||
|
return snapshot;
|
||||||
|
};
|
||||||
|
/** Helpers never retry a failed CAS or silently overwrite concurrent edits. */
|
||||||
|
export const relationshipMap = (port) => ({
|
||||||
|
read: () => port.collection(),
|
||||||
|
async get(key) { const snapshot = await port.collection(); return { revision: snapshot.revision, value: snapshot.entries.find((entry) => entry.key === key)?.target }; },
|
||||||
|
async set(key, target, expectedRevision) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
const entries = snapshot.entries.filter((entry) => entry.key !== key);
|
||||||
|
const existing = snapshot.entries.find((entry) => entry.key === key && entry.target.equals(target));
|
||||||
|
entries.push(existing ?? { key, target });
|
||||||
|
return port.replace(entries, expectedRevision);
|
||||||
|
},
|
||||||
|
async delete(key, expectedRevision) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
return port.replace(snapshot.entries.filter((entry) => entry.key !== key), expectedRevision);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export const relationshipList = (port) => ({
|
||||||
|
read: () => port.collection(),
|
||||||
|
async insert(index, target, expectedRevision) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
if (!Number.isSafeInteger(index) || index < 0 || index > snapshot.entries.length)
|
||||||
|
throw new Error("List index out of bounds");
|
||||||
|
snapshot.entries.splice(index, 0, { target });
|
||||||
|
return port.replace(snapshot.entries, expectedRevision);
|
||||||
|
},
|
||||||
|
async move(edgeId, index, expectedRevision) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
const prior = snapshot.entries.findIndex((entry) => entry.edgeId === edgeId);
|
||||||
|
if (prior < 0 || !Number.isSafeInteger(index) || index < 0 || index >= snapshot.entries.length)
|
||||||
|
throw new Error("Unknown list entry or invalid index");
|
||||||
|
const [entry] = snapshot.entries.splice(prior, 1);
|
||||||
|
snapshot.entries.splice(index, 0, entry);
|
||||||
|
return port.replace(snapshot.entries, expectedRevision);
|
||||||
|
},
|
||||||
|
async delete(edgeId, expectedRevision) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
if (!snapshot.entries.some((entry) => entry.edgeId === edgeId))
|
||||||
|
throw new Error("Unknown list entry");
|
||||||
|
return port.replace(snapshot.entries.filter((entry) => entry.edgeId !== edgeId), expectedRevision);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export const relationshipSet = (port) => ({
|
||||||
|
read: () => port.collection(),
|
||||||
|
async add(target, expectedRevision) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
if (snapshot.entries.some((entry) => entry.target.equals(target)))
|
||||||
|
return snapshot;
|
||||||
|
return port.replace([...snapshot.entries, { target }], expectedRevision);
|
||||||
|
},
|
||||||
|
async delete(target, expectedRevision) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
return port.replace(snapshot.entries.filter((entry) => !entry.target.equals(target)), expectedRevision);
|
||||||
|
},
|
||||||
|
});
|
||||||
Generated
+14
-14
@@ -74,17 +74,17 @@
|
|||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1788542526,
|
"lastModified": 1789328055,
|
||||||
"narHash": "sha256-NaEdW9HKjRpOhZ8TBs6ieD/YuJ2jDyLPVk076wk6Kzs=",
|
"narHash": "sha256-tZVGOpDnT80j3roNQXpCxw8BxNZxqVutclxr49Vhg4w=",
|
||||||
"ref": "refs/tags/quixos-reachability/27373d801b31fbced51cc33bc2a9c92499a46ba3",
|
"ref": "refs/tags/quixos-reachability/9867bf4552c09ee71ebeefe08e652fd870894130",
|
||||||
"rev": "27373d801b31fbced51cc33bc2a9c92499a46ba3",
|
"rev": "9867bf4552c09ee71ebeefe08e652fd870894130",
|
||||||
"revCount": 28,
|
"revCount": 45,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git"
|
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"ref": "refs/tags/quixos-reachability/27373d801b31fbced51cc33bc2a9c92499a46ba3",
|
"ref": "refs/tags/quixos-reachability/9867bf4552c09ee71ebeefe08e652fd870894130",
|
||||||
"rev": "27373d801b31fbced51cc33bc2a9c92499a46ba3",
|
"rev": "9867bf4552c09ee71ebeefe08e652fd870894130",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git"
|
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git"
|
||||||
}
|
}
|
||||||
@@ -92,17 +92,17 @@
|
|||||||
"quixosNixHelpers": {
|
"quixosNixHelpers": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1783914102,
|
"lastModified": 1788574090,
|
||||||
"narHash": "sha256-A9EnXxKaODNrSUpw1IlUBR8fe4px5I+wNJFUFGbZY7c=",
|
"narHash": "sha256-bSgc0LS2Ub01fnE14VqazdZzFuVPl4sykmA2d1l4kDs=",
|
||||||
"ref": "refs/heads/exported",
|
"ref": "refs/tags/quixos-reachability/7177130c0365f2fa58ea4877366e1c5d17db4c01",
|
||||||
"rev": "1f0c39b01501d646fe97dfc6e5777ccab0bde2f1",
|
"rev": "7177130c0365f2fa58ea4877366e1c5d17db4c01",
|
||||||
"revCount": 6,
|
"revCount": 4,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
|
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"ref": "refs/heads/exported",
|
"ref": "refs/tags/quixos-reachability/7177130c0365f2fa58ea4877366e1c5d17db4c01",
|
||||||
"rev": "1f0c39b01501d646fe97dfc6e5777ccab0bde2f1",
|
"rev": "7177130c0365f2fa58ea4877366e1c5d17db4c01",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
|
"url": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
quixos-protocol.url = "git+https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git?ref=refs/tags/quixos-reachability/27373d801b31fbced51cc33bc2a9c92499a46ba3&rev=27373d801b31fbced51cc33bc2a9c92499a46ba3";
|
quixos-protocol.url = "git+https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git?ref=refs/tags/quixos-reachability/9867bf4552c09ee71ebeefe08e652fd870894130&rev=9867bf4552c09ee71ebeefe08e652fd870894130";
|
||||||
quixosNixHelpers = {
|
quixosNixHelpers = {
|
||||||
url = "git+https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git?ref=refs/heads/exported&rev=1f0c39b01501d646fe97dfc6e5777ccab0bde2f1";
|
url = "git+https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-nix-helpers.git?ref=refs/tags/quixos-reachability/7177130c0365f2fa58ea4877366e1c5d17db4c01&rev=7177130c0365f2fa58ea4877366e1c5d17db4c01";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -14,23 +14,36 @@
|
|||||||
outputs = inputs@{ nixpkgs, flake-utils, quixosNixHelpers, ... }:
|
outputs = inputs@{ nixpkgs, flake-utils, quixosNixHelpers, ... }:
|
||||||
let
|
let
|
||||||
quixosHelpers = import "${quixosNixHelpers}/quixos-package-helpers.nix";
|
quixosHelpers = import "${quixosNixHelpers}/quixos-package-helpers.nix";
|
||||||
in
|
packageOutputs = quixosHelpers.mkCaminoTsYarnNixifyFlake {
|
||||||
quixosHelpers.mkCaminoTsYarnNixifyFlake {
|
inherit inputs nixpkgs flake-utils;
|
||||||
inherit inputs nixpkgs flake-utils;
|
packageRoot = ./.;
|
||||||
packageRoot = ./.;
|
sourceName = "quixos-camino-package-runtime-source";
|
||||||
sourceName = "quixos-camino-package-runtime-source";
|
promptName = "camino-package-runtime";
|
||||||
promptName = "camino-package-runtime";
|
nativeBuildInputs = { pkgs, ... }: [
|
||||||
nativeBuildInputs = { pkgs, ... }: [
|
pkgs.protobuf
|
||||||
pkgs.protobuf
|
];
|
||||||
];
|
buildEnv = { inputs, pkgs, system }: {
|
||||||
buildEnv = { inputs, pkgs, system }: {
|
QUIXOS_PROTO_PATH = "${pkgs.protobuf}/include:${inputs.quixos-protocol.packages.${system}.default}/proto";
|
||||||
QUIXOS_PROTO_PATH = "${pkgs.protobuf}/include:${inputs.quixos-protocol.packages.${system}.default}/proto";
|
};
|
||||||
|
devShellPackages = { pkgs, ... }: [
|
||||||
|
pkgs.protobuf
|
||||||
|
];
|
||||||
|
devShellHook = { inputs, pkgs, system, ... }: ''
|
||||||
|
export QUIXOS_PROTO_PATH="${pkgs.protobuf}/include:${inputs.quixos-protocol.packages.${system}.default}/proto''${QUIXOS_PROTO_PATH:+:$QUIXOS_PROTO_PATH}"
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
devShellPackages = { pkgs, ... }: [
|
in
|
||||||
pkgs.protobuf
|
packageOutputs // flake-utils.lib.eachDefaultSystem (system:
|
||||||
];
|
let
|
||||||
devShellHook = { inputs, pkgs, system, ... }: ''
|
pkgs = import nixpkgs { inherit system; };
|
||||||
export QUIXOS_PROTO_PATH="${pkgs.protobuf}/include:${inputs.quixos-protocol.packages.${system}.default}/proto''${QUIXOS_PROTO_PATH:+:$QUIXOS_PROTO_PATH}"
|
builtPackage = packageOutputs.packages.${system}.default;
|
||||||
'';
|
in
|
||||||
};
|
{
|
||||||
|
checks.dist-current = pkgs.runCommand "camino-package-runtime-dist-current" { } ''
|
||||||
|
diff --recursive --unified \
|
||||||
|
${./dist} \
|
||||||
|
${builtPackage}/libexec/-quixos-camino-package-runtime/dist
|
||||||
|
touch "$out"
|
||||||
|
'';
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+183
@@ -0,0 +1,183 @@
|
|||||||
|
import { create } from "@bufbuild/protobuf";
|
||||||
|
import { ValueSchema, ObjectValueSchema, type Value } from "./camino/api_pb.js";
|
||||||
|
import { derived, jsToProtoValue, liveValue, protoValueToJs,
|
||||||
|
type RuntimeContext, type RuntimeHandler, type DerivedHandler } from "./index.js";
|
||||||
|
|
||||||
|
export type { QxObjectRef } from "./references.js";
|
||||||
|
import { assertReferenceFree, referenceToWire } from "./references.js";
|
||||||
|
declare const watchBrand: unique symbol;
|
||||||
|
export type QxWatchHandle = string & { readonly [watchBrand]: true };
|
||||||
|
export type MessageBinding<T> = { encode(value: T): Value; decode(value: Value): T };
|
||||||
|
export type QxLiveValue = ReturnType<typeof liveValue>;
|
||||||
|
const reactPropsDescriptor = "org.quixos.web-studio.ReactProps";
|
||||||
|
// Explicit temporary props exception, matching orch's RPC contract. Field shapes
|
||||||
|
// remain unchecked pending generics; ordinary messages and state do not gain it.
|
||||||
|
export const opaqueReactPropsBinding: MessageBinding<Record<string, unknown>> = {
|
||||||
|
encode(value) {
|
||||||
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("React props must be an object");
|
||||||
|
return jsToProtoValue(value);
|
||||||
|
},
|
||||||
|
decode(value) {
|
||||||
|
if (value.kind.case !== "objectValue") throw new Error("React props must be an object");
|
||||||
|
return protoValueToJs(value) as Record<string, unknown>;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
export type BindingValue<B> = B extends MessageBinding<infer T> ? T : never;
|
||||||
|
export type QxHandler<C, O> = (context: C) => O | Promise<O>;
|
||||||
|
export type QxDerived<C, O> = { kind: "derived"; get: QxHandler<C, O> };
|
||||||
|
export type QxSession<C> = {id: string; run<T>(work: (context: C) => Promise<T>): Promise<T>; close(): Promise<void>};
|
||||||
|
export type QxContextLifecycle<C> = {signal?: AbortSignal; openSession?: () => Promise<QxSession<C>>};
|
||||||
|
export const qxDerived = <C, O>(get: QxHandler<C, O>): QxDerived<C, O> => ({ kind: "derived", get });
|
||||||
|
|
||||||
|
/** Versioned binding ABI. This mirrors the language-neutral value IR. */
|
||||||
|
export type QxValueType =
|
||||||
|
| { kind: "builtin"; name: "unit" | "watch-handle" }
|
||||||
|
| { kind: "scalar"; name: string }
|
||||||
|
| { kind: "message"; descriptorId: string }
|
||||||
|
| { kind: "record"; fields: Record<string, QxValueType> }
|
||||||
|
| { kind: "object-ref"; expectation: unknown }
|
||||||
|
| { kind: "optional" | "list"; value: QxValueType };
|
||||||
|
export type QxOperationSpec = { id: string; inputType: QxValueType; outputType: QxValueType };
|
||||||
|
export type QxPortSpec =
|
||||||
|
| { kind: "state"; id: string; valueType: QxValueType; primitives: string[] }
|
||||||
|
| { kind: "edge"; id: string; primitives: string[] }
|
||||||
|
| { kind: "interface"; id: string; operations: Record<string, QxOperationSpec> }
|
||||||
|
| { kind: "constructor"; id: string; inputType: QxValueType };
|
||||||
|
export type QxHandlerSpec = {
|
||||||
|
inputType: QxValueType; outputType: QxValueType; eventType?: QxValueType;
|
||||||
|
ports: Record<string, QxPortSpec>;
|
||||||
|
};
|
||||||
|
export type QxMessages = Record<string, MessageBinding<any>>;
|
||||||
|
|
||||||
|
// Conversion belongs at the binding boundary. It does not add orchestrator validation.
|
||||||
|
export const decodeQxValue = (type: QxValueType, value: Value | undefined, messages: QxMessages): any => {
|
||||||
|
if (type.kind === "builtin" && type.name === "unit") return null;
|
||||||
|
if (type.kind === "optional" && !value) return null;
|
||||||
|
if (!value) throw new Error("Missing QX wire value");
|
||||||
|
if (type.kind === "record") {
|
||||||
|
if (value.kind.case !== "objectValue") throw new Error("Expected QX record");
|
||||||
|
const fields = value.kind.value.fields;
|
||||||
|
if (Object.keys(fields).some((name) => !Object.hasOwn(type.fields, name))) throw new Error("Unexpected QX record field");
|
||||||
|
return Object.fromEntries(Object.entries(type.fields).map(([name, field]) => [name, decodeQxValue(field, fields[name], messages)]));
|
||||||
|
}
|
||||||
|
if (type.kind === "optional") return value.kind.case === "nullValue" ? null : decodeQxValue(type.value, value, messages);
|
||||||
|
if (type.kind === "list") {
|
||||||
|
if (value.kind.case !== "listValue") throw new Error("Expected QX list");
|
||||||
|
return value.kind.value.values.map((entry) => decodeQxValue(type.value, entry, messages));
|
||||||
|
}
|
||||||
|
if (type.kind === "message") {
|
||||||
|
if (type.descriptorId !== reactPropsDescriptor) assertReferenceFree(protoValueToJs(value));
|
||||||
|
const decoded = requireMessage(messages, type.descriptorId).decode(value);
|
||||||
|
if (type.descriptorId !== reactPropsDescriptor) assertReferenceFree(decoded);
|
||||||
|
return decoded;
|
||||||
|
}
|
||||||
|
if (type.kind === "object-ref") {
|
||||||
|
if (value.kind.case !== "refValue") throw new Error("Expected a declared RPC object reference");
|
||||||
|
return protoValueToJs(value);
|
||||||
|
}
|
||||||
|
if (value.kind.case === "refValue") throw new Error("Reference supplied to a non-reference value");
|
||||||
|
if (type.kind === "scalar") {
|
||||||
|
if (type.name === "int64" || type.name === "uint64") {
|
||||||
|
if (value.kind.case !== "integerValue") throw new Error("Expected QX integer");
|
||||||
|
return BigInt(value.kind.value);
|
||||||
|
}
|
||||||
|
if (type.name === "bytes") {
|
||||||
|
if (value.kind.case !== "bytesValue") throw new Error("Expected QX bytes");
|
||||||
|
return value.kind.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return protoValueToJs(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const requireMessage = (messages: QxMessages, id: string) => {
|
||||||
|
const binding = messages[id];
|
||||||
|
if (!binding) throw new Error(`Missing message binding ${id}`);
|
||||||
|
return binding;
|
||||||
|
};
|
||||||
|
export const encodeQxValue = (type: QxValueType, value: any, messages: QxMessages): Value => {
|
||||||
|
if (type.kind === "builtin" && type.name === "unit") return jsToProtoValue(null);
|
||||||
|
if (type.kind === "record") {
|
||||||
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Expected QX record");
|
||||||
|
if (Object.keys(value).some((name) => !Object.hasOwn(type.fields, name))) throw new Error("Unexpected QX record field");
|
||||||
|
const fields = Object.fromEntries(Object.entries(type.fields).map(([name, field]) => {
|
||||||
|
if (!Object.hasOwn(value, name) && field.kind !== "optional") throw new Error(`Missing QX record field ${name}`);
|
||||||
|
return [name, encodeQxValue(field, value[name] ?? (field.kind === "optional" ? null : value[name]), messages)];
|
||||||
|
}));
|
||||||
|
return create(ValueSchema, {kind: {case: "objectValue", value: create(ObjectValueSchema, {fields})}});
|
||||||
|
}
|
||||||
|
if (type.kind === "optional") return value === null ? jsToProtoValue(null) : encodeQxValue(type.value, value, messages);
|
||||||
|
if (type.kind === "list") return jsToProtoValue(value.map((entry: unknown) => liveValue(encodeQxValue(type.value, entry, messages))));
|
||||||
|
if (type.kind === "object-ref") { referenceToWire(value); return jsToProtoValue(value); }
|
||||||
|
if (type.kind !== "message" || type.descriptorId !== reactPropsDescriptor) assertReferenceFree(value);
|
||||||
|
if (type.kind === "message") {
|
||||||
|
const encoded = requireMessage(messages, type.descriptorId).encode(value);
|
||||||
|
if (type.descriptorId !== reactPropsDescriptor) assertReferenceFree(protoValueToJs(encoded));
|
||||||
|
return encoded;
|
||||||
|
}
|
||||||
|
return jsToProtoValue(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const inputValue = (context: RuntimeContext, type: QxValueType) => {
|
||||||
|
if (type.kind === "message" || type.kind === "record") return create(ValueSchema, { kind: { case: "objectValue",
|
||||||
|
value: create(ObjectValueSchema, { fields: context.inputProto }) } });
|
||||||
|
return context.inputProto.value;
|
||||||
|
};
|
||||||
|
const inputFields = (type: QxValueType, value: unknown, messages: QxMessages): Record<string, unknown> => {
|
||||||
|
if (type.kind === "builtin" && type.name === "unit") return {};
|
||||||
|
const encoded = encodeQxValue(type, value, messages);
|
||||||
|
if (type.kind === "message" || type.kind === "record") {
|
||||||
|
if (encoded.kind.case !== "objectValue") throw new Error("Message inputs must encode an object value");
|
||||||
|
return Object.fromEntries(Object.entries(encoded.kind.value.fields).map(([key, entry]) => [key, liveValue(entry)]));
|
||||||
|
}
|
||||||
|
return { value: liveValue(encoded) };
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The sole unchecked cast connects generated contracts to the dynamic RPC runtime. */
|
||||||
|
export const bindQxHandler = <C, O>(
|
||||||
|
spec: QxHandlerSpec, handler: QxHandler<C, O> | QxDerived<C, O>, messages: QxMessages,
|
||||||
|
): RuntimeHandler | DerivedHandler => {
|
||||||
|
const bindContext = (raw: RuntimeContext): C => {
|
||||||
|
const ports = Object.fromEntries(Object.entries(spec.ports).map(([name, port]) => {
|
||||||
|
switch (port.kind) {
|
||||||
|
case "state": {
|
||||||
|
const state = raw.state(port.id);
|
||||||
|
return [name, {
|
||||||
|
...(port.primitives.includes("read") ? { get: async () => decodeQxValue(port.valueType, (await state.live()).$quixosValue, messages), live: () => state.live() } : {}),
|
||||||
|
...(port.primitives.includes("write") ? { set: async (value: unknown) => state.set(liveValue(encodeQxValue(port.valueType, value, messages))) } : {}),
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
case "edge": {
|
||||||
|
const edge = raw.edge(port.id);
|
||||||
|
return [name, {...Object.fromEntries(port.primitives.map((primitive) => [primitive, edge[primitive as "resolve" | "connect" | "disconnect"]])),
|
||||||
|
...(port.primitives.includes("resolve") ? {collection: edge.collection} : {}),
|
||||||
|
...(port.primitives.includes("resolve") && port.primitives.includes("connect") && port.primitives.includes("disconnect") ? {replace: edge.replace} : {})}];
|
||||||
|
}
|
||||||
|
case "interface": {
|
||||||
|
const target = raw.interface(port.id);
|
||||||
|
return [name, {objectId: target.objectId,
|
||||||
|
live: Object.fromEntries(Object.entries(port.operations).map(([name, operation]) => [name,
|
||||||
|
(input: unknown) => target.live(operation.id, inputFields(operation.inputType, input, messages)),
|
||||||
|
])),
|
||||||
|
...Object.fromEntries(Object.entries(port.operations).map(([name, operation]) => [name,
|
||||||
|
async (input: unknown) => decodeQxValue(operation.outputType,
|
||||||
|
(await target.live(operation.id, inputFields(operation.inputType, input, messages))).$quixosValue, messages),
|
||||||
|
]))}];
|
||||||
|
}
|
||||||
|
case "constructor": return [name, { construct: (input: unknown) => raw.constructor(port.id).construct(inputFields(port.inputType, input, messages)) }];
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return { objectId: raw.objectId, signal: raw.signal,
|
||||||
|
...(raw.openSession ? {openSession: async () => {
|
||||||
|
const session = await raw.openSession!();
|
||||||
|
return {id: session.id, close: () => session.close(),
|
||||||
|
run: <T>(work: (context: C) => Promise<T>) => session.run((next) => work(bindContext(next)))};
|
||||||
|
}} : {}),
|
||||||
|
input: decodeQxValue(spec.inputType, inputValue(raw, spec.inputType), messages), ports } as C;
|
||||||
|
};
|
||||||
|
const execute = async (raw: RuntimeContext) => {
|
||||||
|
const context = bindContext(raw);
|
||||||
|
const value = await (typeof handler === "function" ? handler(context) : handler.get(context));
|
||||||
|
return liveValue(encodeQxValue(spec.eventType ?? spec.outputType, value, messages));
|
||||||
|
};
|
||||||
|
return typeof handler === "function" ? execute : derived(execute);
|
||||||
|
};
|
||||||
+138
-8
File diff suppressed because one or more lines are too long
+42
-1
@@ -10,7 +10,7 @@ import type { Message } from "@bufbuild/protobuf";
|
|||||||
* Describes the file camino/schema.proto.
|
* Describes the file camino/schema.proto.
|
||||||
*/
|
*/
|
||||||
export const file_camino_schema: GenFile = /*@__PURE__*/
|
export const file_camino_schema: GenFile = /*@__PURE__*/
|
||||||
fileDesc("ChNjYW1pbm8vc2NoZW1hLnByb3RvEgZjYW1pbm8iNwoOQXRvbURlZmluaXRpb24SDwoHYXRvbV9pZBgBIAEoCRIUCgxkaXNwbGF5X25hbWUYAiABKAkiQQoPQXRvbUNvbmZvcm1hbmNlEg8KB2F0b21faWQYASABKAkSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAIgASgJIqQBCg9TdGF0ZUF0dGFjaG1lbnQSDwoHc2xvdF9pZBgBIAEoCRIYChBhdHRhY2hlZF9hdG9tX2lkGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCRIXCg92YWx1ZV90eXBlX2pzb24YBCABKAkSGwoTc3RvcmFnZV9wb2xpY3lfanNvbhgFIAEoCRIaChJkZWZhdWx0X3ZhbHVlX2pzb24YBiABKAkiUAoSRW5kcG9pbnRDb25zdHJhaW50EhEKB2F0b21faWQYASABKAlIABIfChVpbnRlcmZhY2VfcmV2aXNpb25faWQYAiABKAlIAEIGCgRraW5kIqYBCgxFZGdlRW5kcG9pbnQSFQoNcHJvamVjdGlvbl9pZBgBIAEoCRIUCgxkaXNwbGF5X25hbWUYAiABKAkSLgoKY29uc3RyYWludBgDIAEoCzIaLmNhbWluby5FbmRwb2ludENvbnN0cmFpbnQSKAoLY2FyZGluYWxpdHkYBCABKA4yEy5jYW1pbm8uQ2FyZGluYWxpdHkSDwoHb3JkZXJlZBgFIAEoCCKHAQoORWRnZUF0dGFjaG1lbnQSFAoMZWRnZV90eXBlX2lkGAEgASgJEhQKDGRpc3BsYXlfbmFtZRgCIAEoCRIjCgVmaXJzdBgDIAEoCzIULmNhbWluby5FZGdlRW5kcG9pbnQSJAoGc2Vjb25kGAQgASgLMhQuY2FtaW5vLkVkZ2VFbmRwb2ludCLsAQoPUGVyc2lzdGVuY2VQbGFuEhQKDHdvcmtzcGFjZV9pZBgBIAEoCRIdChV3b3Jrc3BhY2VfcmV2aXNpb25faWQYAiABKAkSJQoFYXRvbXMYAyADKAsyFi5jYW1pbm8uQXRvbURlZmluaXRpb24SLQoMY29uZm9ybWFuY2VzGAQgAygLMhcuY2FtaW5vLkF0b21Db25mb3JtYW5jZRInCgZzdGF0ZXMYBSADKAsyFy5jYW1pbm8uU3RhdGVBdHRhY2htZW50EiUKBWVkZ2VzGAYgAygLMhYuY2FtaW5vLkVkZ2VBdHRhY2htZW50KmgKC0NhcmRpbmFsaXR5EhsKF0NBUkRJTkFMSVRZX1VOU1BFQ0lGSUVEEAASEAoMT1BUSU9OQUxfT05FEAESDwoLRVhBQ1RMWV9PTkUQAhIICgRNQU5ZEAMSDwoLTUFOWV9VTklRVUUQBGIGcHJvdG8z");
|
fileDesc("ChNjYW1pbm8vc2NoZW1hLnByb3RvEgZjYW1pbm8iNwoOQXRvbURlZmluaXRpb24SDwoHYXRvbV9pZBgBIAEoCRIUCgxkaXNwbGF5X25hbWUYAiABKAkiWQoPQXRvbUNvbmZvcm1hbmNlEg8KB2F0b21faWQYASABKAkSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAIgASgJEhYKDmNvbmZvcm1hbmNlX2lkGAMgASgJIsIBCg9TdGF0ZUF0dGFjaG1lbnQSDwoHc2xvdF9pZBgBIAEoCRIYChBhdHRhY2hlZF9hdG9tX2lkGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCRIXCg92YWx1ZV90eXBlX2pzb24YBCABKAkSGwoTc3RvcmFnZV9wb2xpY3lfanNvbhgFIAEoCRIaChJkZWZhdWx0X3ZhbHVlX2pzb24YBiABKAkSHAoUb3duZXJfY29uZm9ybWFuY2VfaWQYByABKAkiUAoSRW5kcG9pbnRDb25zdHJhaW50EhEKB2F0b21faWQYASABKAlIABIfChVpbnRlcmZhY2VfcmV2aXNpb25faWQYAiABKAlIAEIGCgRraW5kIvsBCgxFZGdlRW5kcG9pbnQSFQoNcHJvamVjdGlvbl9pZBgBIAEoCRIUCgxkaXNwbGF5X25hbWUYAiABKAkSLgoKY29uc3RyYWludBgDIAEoCzIaLmNhbWluby5FbmRwb2ludENvbnN0cmFpbnQSKAoLY2FyZGluYWxpdHkYBCABKA4yEy5jYW1pbm8uQ2FyZGluYWxpdHkSDwoHb3JkZXJlZBgFIAEoCBIRCglvbl9kZWxldGUYBiABKAkSFAoMcmV0YWluX290aGVyGAcgASgIEhAKCGtleV90eXBlGAggASgJEhgKEHB1YmxpY190cmF2ZXJzYWwYCSABKAgipQEKDkVkZ2VBdHRhY2htZW50EhQKDGVkZ2VfdHlwZV9pZBgBIAEoCRIUCgxkaXNwbGF5X25hbWUYAiABKAkSIwoFZmlyc3QYAyABKAsyFC5jYW1pbm8uRWRnZUVuZHBvaW50EiQKBnNlY29uZBgEIAEoCzIULmNhbWluby5FZGdlRW5kcG9pbnQSHAoUb3duZXJfY29uZm9ybWFuY2VfaWQYBSABKAki7AEKD1BlcnNpc3RlbmNlUGxhbhIUCgx3b3Jrc3BhY2VfaWQYASABKAkSHQoVd29ya3NwYWNlX3JldmlzaW9uX2lkGAIgASgJEiUKBWF0b21zGAMgAygLMhYuY2FtaW5vLkF0b21EZWZpbml0aW9uEi0KDGNvbmZvcm1hbmNlcxgEIAMoCzIXLmNhbWluby5BdG9tQ29uZm9ybWFuY2USJwoGc3RhdGVzGAUgAygLMhcuY2FtaW5vLlN0YXRlQXR0YWNobWVudBIlCgVlZGdlcxgGIAMoCzIWLmNhbWluby5FZGdlQXR0YWNobWVudCpoCgtDYXJkaW5hbGl0eRIbChdDQVJESU5BTElUWV9VTlNQRUNJRklFRBAAEhAKDE9QVElPTkFMX09ORRABEg8KC0VYQUNUTFlfT05FEAISCAoETUFOWRADEg8KC01BTllfVU5JUVVFEARiBnByb3RvMw");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message camino.AtomDefinition
|
* @generated from message camino.AtomDefinition
|
||||||
@@ -47,6 +47,11 @@ export type AtomConformance = Message<"camino.AtomConformance"> & {
|
|||||||
* @generated from field: string interface_revision_id = 2;
|
* @generated from field: string interface_revision_id = 2;
|
||||||
*/
|
*/
|
||||||
interfaceRevisionId: string;
|
interfaceRevisionId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string conformance_id = 3;
|
||||||
|
*/
|
||||||
|
conformanceId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,6 +94,11 @@ export type StateAttachment = Message<"camino.StateAttachment"> & {
|
|||||||
* @generated from field: string default_value_json = 6;
|
* @generated from field: string default_value_json = 6;
|
||||||
*/
|
*/
|
||||||
defaultValueJson: string;
|
defaultValueJson: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string owner_conformance_id = 7;
|
||||||
|
*/
|
||||||
|
ownerConformanceId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,6 +165,32 @@ export type EdgeEndpoint = Message<"camino.EdgeEndpoint"> & {
|
|||||||
* @generated from field: bool ordered = 5;
|
* @generated from field: bool ordered = 5;
|
||||||
*/
|
*/
|
||||||
ordered: boolean;
|
ordered: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty means restrict. Direction is the endpoint being deleted.
|
||||||
|
*
|
||||||
|
* @generated from field: string on_delete = 6;
|
||||||
|
*/
|
||||||
|
onDelete: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bool retain_other = 7;
|
||||||
|
*/
|
||||||
|
retainOther: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty for sets/lists, otherwise string, boolean, or int64 map keys.
|
||||||
|
*
|
||||||
|
* @generated from field: string key_type = 8;
|
||||||
|
*/
|
||||||
|
keyType: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Explicit read-only dependency injection traversal, not mutation authority.
|
||||||
|
*
|
||||||
|
* @generated from field: bool public_traversal = 9;
|
||||||
|
*/
|
||||||
|
publicTraversal: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -187,6 +223,11 @@ export type EdgeAttachment = Message<"camino.EdgeAttachment"> & {
|
|||||||
* @generated from field: camino.EdgeEndpoint second = 4;
|
* @generated from field: camino.EdgeEndpoint second = 4;
|
||||||
*/
|
*/
|
||||||
second?: EdgeEndpoint | undefined;
|
second?: EdgeEndpoint | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string owner_conformance_id = 5;
|
||||||
|
*/
|
||||||
|
ownerConformanceId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+244
-48
@@ -1,6 +1,12 @@
|
|||||||
import http from "node:http";
|
import http from "node:http";
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
|
import { createInvocationRegistry } from "./invocations.js";
|
||||||
|
import { isObjectReference, referenceFromWire, referenceToWire, assertReferenceFree, type QxObjectRef } from "./references.js";
|
||||||
|
export * from "./bindings.js";
|
||||||
|
export {relationshipMap, relationshipList, relationshipSet} from "./relationships.js";
|
||||||
import { AsyncLocalStorage } from "node:async_hooks";
|
import { AsyncLocalStorage } from "node:async_hooks";
|
||||||
import { randomUUID } from "node:crypto";
|
import { createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
||||||
|
export {createMigrationContext, migrationObjectId, serveMigration, type MigrationContext, type MigrationInput, type MigrationOutput, type MigrationEdge} from "./migration.js";
|
||||||
import { create, equals } from "@bufbuild/protobuf";
|
import { create, equals } from "@bufbuild/protobuf";
|
||||||
import { Code, ConnectError, createClient, type Client, type ConnectRouter } from "@connectrpc/connect";
|
import { Code, ConnectError, createClient, type Client, type ConnectRouter } from "@connectrpc/connect";
|
||||||
import { connectNodeAdapter, createConnectTransport } from "@connectrpc/connect-node";
|
import { connectNodeAdapter, createConnectTransport } from "@connectrpc/connect-node";
|
||||||
@@ -60,10 +66,11 @@ const isWrappedValue = (value: unknown): value is { $quixosValue: Value } =>
|
|||||||
isRecord(value) && "$quixosValue" in value &&
|
isRecord(value) && "$quixosValue" in value &&
|
||||||
isRecord(value.$quixosValue) && value.$quixosValue.$typeName === "camino.Value";
|
isRecord(value.$quixosValue) && value.$quixosValue.$typeName === "camino.Value";
|
||||||
|
|
||||||
export const objectRef = (objectId: string) => ({ $quixosRef: objectId });
|
export const objectRef = (reference: QxObjectRef) => { referenceToWire(reference); return reference; };
|
||||||
export const liveValue = (value: Value) => ({ $quixosValue: value });
|
export const liveValue = (value: Value) => ({ $quixosValue: value });
|
||||||
|
|
||||||
export const jsToProtoValue = (value: unknown): Value => {
|
export const jsToProtoValue = (value: unknown): Value => {
|
||||||
|
if (isObjectReference(value)) return create(ValueSchema, {kind: {case: "refValue", value: create(RefValueSchema, {objectId: referenceToWire(value)})}});
|
||||||
if (isWrappedValue(value)) return value.$quixosValue;
|
if (isWrappedValue(value)) return value.$quixosValue;
|
||||||
if (value === null || value === undefined) {
|
if (value === null || value === undefined) {
|
||||||
return create(ValueSchema, { kind: { case: "nullValue", value: create(NullValueSchema, {}) } });
|
return create(ValueSchema, { kind: { case: "nullValue", value: create(NullValueSchema, {}) } });
|
||||||
@@ -78,11 +85,7 @@ export const jsToProtoValue = (value: unknown): Value => {
|
|||||||
kind: { case: "listValue", value: create(ListValueSchema, { values: value.map(jsToProtoValue) }) },
|
kind: { case: "listValue", value: create(ListValueSchema, { values: value.map(jsToProtoValue) }) },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (isRecord(value) && typeof value.$quixosRef === "string") {
|
if (isRecord(value) && "$quixosRef" in value) throw new Error("Raw ID wrappers are not object references");
|
||||||
return create(ValueSchema, {
|
|
||||||
kind: { case: "refValue", value: create(RefValueSchema, { objectId: value.$quixosRef }) },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (isRecord(value) && typeof value.$quixosCrdtType === "string" &&
|
if (isRecord(value) && typeof value.$quixosCrdtType === "string" &&
|
||||||
typeof value.$quixosCrdtPayload === "string") {
|
typeof value.$quixosCrdtPayload === "string") {
|
||||||
return create(ValueSchema, {
|
return create(ValueSchema, {
|
||||||
@@ -110,7 +113,7 @@ export const protoValueToJs = (value: Value | undefined): unknown => {
|
|||||||
case "stringValue":
|
case "stringValue":
|
||||||
case "integerValue": return value.kind.value;
|
case "integerValue": return value.kind.value;
|
||||||
case "bytesValue": return bytesToBase64(value.kind.value);
|
case "bytesValue": return bytesToBase64(value.kind.value);
|
||||||
case "refValue": return value.kind.value.objectId;
|
case "refValue": return referenceFromWire(value.kind.value.objectId);
|
||||||
case "listValue": return value.kind.value.values.map(protoValueToJs);
|
case "listValue": return value.kind.value.values.map(protoValueToJs);
|
||||||
case "objectValue": return Object.fromEntries(
|
case "objectValue": return Object.fromEntries(
|
||||||
Object.entries(value.kind.value.fields).map(([key, entry]) => [key, protoValueToJs(entry)]),
|
Object.entries(value.kind.value.fields).map(([key, entry]) => [key, protoValueToJs(entry)]),
|
||||||
@@ -135,21 +138,31 @@ export type StatePort<T = unknown> = {
|
|||||||
export type EdgePort = {
|
export type EdgePort = {
|
||||||
edgeTypeId: string;
|
edgeTypeId: string;
|
||||||
projectionId: string;
|
projectionId: string;
|
||||||
resolve(): Promise<string[]>;
|
resolve(): Promise<QxObjectRef[]>;
|
||||||
connect(targetObjectId: string): Promise<void>;
|
connect(target: QxObjectRef): Promise<void>;
|
||||||
|
disconnect(target: QxObjectRef): Promise<void>;
|
||||||
|
collection(): Promise<RelationshipCollection>;
|
||||||
|
replace(entries: RelationshipEntry[], expectedRevision: bigint): Promise<RelationshipCollection>;
|
||||||
};
|
};
|
||||||
|
export type RelationshipEntry<T extends QxObjectRef = QxObjectRef> = {edgeId?: string; target: T; key?: string | boolean | bigint};
|
||||||
|
export type RelationshipCollection<T extends QxObjectRef = QxObjectRef> = {revision: bigint; entries: RelationshipEntry<T>[]};
|
||||||
export type InterfacePort = {
|
export type InterfacePort = {
|
||||||
|
objectId: QxObjectRef;
|
||||||
interfaceRevisionId: string;
|
interfaceRevisionId: string;
|
||||||
invoke(operationId: string, input?: Record<string, unknown>): Promise<unknown>;
|
invoke(operationId: string, input?: Record<string, unknown>): Promise<unknown>;
|
||||||
|
live(operationId: string, input?: Record<string, unknown>): Promise<ReturnType<typeof liveValue>>;
|
||||||
};
|
};
|
||||||
export type ConstructorPort = {
|
export type ConstructorPort = {
|
||||||
atomId: string;
|
atomId: string;
|
||||||
construct(input?: Record<string, unknown>): Promise<string>;
|
construct(input?: Record<string, unknown>): Promise<QxObjectRef>;
|
||||||
};
|
};
|
||||||
export type RuntimePort = StatePort | EdgePort | InterfacePort | ConstructorPort;
|
export type RuntimePort = StatePort | EdgePort | InterfacePort | ConstructorPort;
|
||||||
|
|
||||||
export type RuntimeContext = {
|
export type RuntimeContext = {
|
||||||
objectId: string;
|
/** Cooperative cancellation. Completion is acknowledged only after the handler returns. */
|
||||||
|
signal?: AbortSignal;
|
||||||
|
openSession?: () => Promise<RuntimeSession>;
|
||||||
|
objectId: QxObjectRef;
|
||||||
input: Record<string, unknown>;
|
input: Record<string, unknown>;
|
||||||
inputProto: Record<string, Value>;
|
inputProto: Record<string, Value>;
|
||||||
ports: ReadonlyMap<string, RuntimePort>;
|
ports: ReadonlyMap<string, RuntimePort>;
|
||||||
@@ -159,6 +172,17 @@ export type RuntimeContext = {
|
|||||||
constructor(portId: string): ConstructorPort;
|
constructor(portId: string): ConstructorPort;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type RuntimeSession = {
|
||||||
|
id: string;
|
||||||
|
run<T>(work: (context: RuntimeContext) => Promise<T>): Promise<T>;
|
||||||
|
/** Close the external resource first, then close its host retention/session. */
|
||||||
|
close(): Promise<void>;
|
||||||
|
};
|
||||||
|
export class RuntimeAuthorityError extends Error {
|
||||||
|
readonly retryable: boolean;
|
||||||
|
constructor(message: string) { super(message); this.name = "RuntimeAuthorityError"; this.retryable = /WORKSPACE_FENCED|STALE_EPOCH/.test(message); }
|
||||||
|
}
|
||||||
|
|
||||||
const targetForEdge = (
|
const targetForEdge = (
|
||||||
edge: { firstObjectId: string; secondObjectId: string; firstProjectionId: string },
|
edge: { firstObjectId: string; secondObjectId: string; firstProjectionId: string },
|
||||||
projectionId: string,
|
projectionId: string,
|
||||||
@@ -174,20 +198,22 @@ export const createRuntimeContext = (
|
|||||||
switch (dependency.binding.case) {
|
switch (dependency.binding.case) {
|
||||||
case "stateSlotId": {
|
case "stateSlotId": {
|
||||||
const slotId = dependency.binding.value;
|
const slotId = dependency.binding.value;
|
||||||
|
const dependencyObjectId = dependency.objectId || request.objectId;
|
||||||
const state: StatePort = {
|
const state: StatePort = {
|
||||||
slotId,
|
slotId,
|
||||||
async get() {
|
async get() {
|
||||||
await recordDependency({ kind: "state", objectId: request.objectId, attachmentId: slotId });
|
await recordDependency({ kind: "state", objectId: dependencyObjectId, attachmentId: slotId });
|
||||||
return protoValueToJs((await camino.readState({ objectId: request.objectId, slotId })).value);
|
return protoValueToJs((await camino.readState({ objectId: dependencyObjectId, slotId })).value);
|
||||||
},
|
},
|
||||||
async live() {
|
async live() {
|
||||||
await recordDependency({ kind: "state", objectId: request.objectId, attachmentId: slotId });
|
await recordDependency({ kind: "state", objectId: dependencyObjectId, attachmentId: slotId });
|
||||||
const value = await camino.readState({ objectId: request.objectId, slotId });
|
const value = await camino.readState({ objectId: dependencyObjectId, slotId });
|
||||||
if (!value.value) throw new Error(`State ${slotId} returned no value`);
|
if (!value.value) throw new Error(`State ${slotId} returned no value`);
|
||||||
return liveValue(value.value);
|
return liveValue(value.value);
|
||||||
},
|
},
|
||||||
async set(value) {
|
async set(value) {
|
||||||
await camino.writeState({ objectId: request.objectId, slotId, value: jsToProtoValue(value) });
|
assertReferenceFree(isWrappedValue(value) ? protoValueToJs(value.$quixosValue) : value);
|
||||||
|
await camino.writeState({ objectId: dependencyObjectId, slotId, value: jsToProtoValue(value) });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ports.set(dependency.portId, state);
|
ports.set(dependency.portId, state);
|
||||||
@@ -195,33 +221,82 @@ export const createRuntimeContext = (
|
|||||||
}
|
}
|
||||||
case "edge": {
|
case "edge": {
|
||||||
const { edgeTypeId, projectionId } = dependency.binding.value;
|
const { edgeTypeId, projectionId } = dependency.binding.value;
|
||||||
|
const dependencyObjectId = dependency.objectId || request.objectId;
|
||||||
|
const collectionResult = (response: {revision: bigint; entries: {edgeId: string; targetObjectId: string; key?: Value}[]}): RelationshipCollection => ({revision: response.revision,
|
||||||
|
entries: response.entries.map((entry) => ({edgeId: entry.edgeId, target: referenceFromWire(entry.targetObjectId),
|
||||||
|
...(entry.key ? {key: entry.key.kind.case === "integerValue" ? BigInt(entry.key.kind.value) : protoValueToJs(entry.key) as string | boolean} : {})}))});
|
||||||
const edge: EdgePort = {
|
const edge: EdgePort = {
|
||||||
edgeTypeId,
|
edgeTypeId,
|
||||||
projectionId,
|
projectionId,
|
||||||
async resolve() {
|
async collection() {
|
||||||
await recordDependency({ kind: "edge", objectId: request.objectId, attachmentId: edgeTypeId, projectionId });
|
await recordDependency({kind: "edge", objectId: dependencyObjectId, attachmentId: edgeTypeId, projectionId});
|
||||||
const result = await camino.resolveEdge({ objectId: request.objectId, edgeTypeId, projectionId });
|
return collectionResult(await camino.readCollection({objectId: dependencyObjectId, edgeTypeId, projectionId}));
|
||||||
return result.edges.map((entry) => targetForEdge(entry, projectionId));
|
|
||||||
},
|
},
|
||||||
async connect(targetObjectId) {
|
async replace(entries, expectedRevision) {
|
||||||
await camino.connectEdge({ objectId: request.objectId, edgeTypeId, projectionId, targetObjectId });
|
return collectionResult(await camino.replaceCollection({objectId: dependencyObjectId, edgeTypeId, projectionId, expectedRevision,
|
||||||
|
entries: entries.map((entry) => {
|
||||||
|
assertReferenceFree(entry.key);
|
||||||
|
return {edgeId: entry.edgeId ?? "", targetObjectId: referenceToWire(entry.target), key: entry.key === undefined ? undefined : jsToProtoValue(entry.key)};
|
||||||
|
})}));
|
||||||
|
},
|
||||||
|
async resolve() {
|
||||||
|
await recordDependency({ kind: "edge", objectId: dependencyObjectId, attachmentId: edgeTypeId, projectionId });
|
||||||
|
const result = await camino.resolveEdge({ objectId: dependencyObjectId, edgeTypeId, projectionId });
|
||||||
|
return result.edges.map((entry) => referenceFromWire(targetForEdge(entry, projectionId)));
|
||||||
|
},
|
||||||
|
async connect(target) {
|
||||||
|
const targetObjectId = referenceToWire(target);
|
||||||
|
await camino.connectEdge({ objectId: dependencyObjectId, edgeTypeId, projectionId, targetObjectId });
|
||||||
|
},
|
||||||
|
async disconnect(target) {
|
||||||
|
const targetObjectId = referenceToWire(target);
|
||||||
|
const result = await camino.resolveEdge({ objectId: dependencyObjectId, edgeTypeId, projectionId });
|
||||||
|
for (const entry of result.edges) {
|
||||||
|
if (targetForEdge(entry, projectionId) === targetObjectId) await camino.disconnectEdge({ edgeId: entry.id });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ports.set(dependency.portId, edge);
|
ports.set(dependency.portId, edge);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "receiverInterfaceRevisionId": {
|
case "interfaceRevisionId": {
|
||||||
const interfaceRevisionId = dependency.binding.value;
|
const interfaceRevisionId = dependency.binding.value;
|
||||||
|
const dependencyObjectId = dependency.objectId || request.objectId;
|
||||||
|
const invoke = async (operationId: string, input: Record<string, unknown>) => {
|
||||||
|
const response = await orch.invokeCapability({
|
||||||
|
capability: create(CapabilityRefSchema, { interfaceRevisionId, operationId }),
|
||||||
|
objectId: dependencyObjectId,
|
||||||
|
input: Object.fromEntries(Object.entries(input).map(([key, value]) => [key, jsToProtoValue(value)])),
|
||||||
|
});
|
||||||
|
if (!response.ok) throw new Error(response.error || `Capability ${operationId} failed`);
|
||||||
|
for (const dependency of response.dependencies) {
|
||||||
|
if (dependency.kind === "state") {
|
||||||
|
await recordDependency({
|
||||||
|
kind: "state",
|
||||||
|
objectId: dependency.objectId,
|
||||||
|
attachmentId: dependency.attachmentId,
|
||||||
|
});
|
||||||
|
} else if (dependency.kind === "edge") {
|
||||||
|
await recordDependency({
|
||||||
|
kind: "edge",
|
||||||
|
objectId: dependency.objectId,
|
||||||
|
attachmentId: dependency.attachmentId,
|
||||||
|
projectionId: dependency.projectionId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response.result;
|
||||||
|
};
|
||||||
const capability: InterfacePort = {
|
const capability: InterfacePort = {
|
||||||
|
objectId: referenceFromWire(dependencyObjectId),
|
||||||
interfaceRevisionId,
|
interfaceRevisionId,
|
||||||
async invoke(operationId, input = {}) {
|
async invoke(operationId, input = {}) {
|
||||||
const response = await orch.invokeCapability({
|
return protoValueToJs(await invoke(operationId, input));
|
||||||
capability: create(CapabilityRefSchema, { interfaceRevisionId, operationId }),
|
},
|
||||||
objectId: request.objectId,
|
async live(operationId, input = {}) {
|
||||||
input: Object.fromEntries(Object.entries(input).map(([key, value]) => [key, jsToProtoValue(value)])),
|
const value = await invoke(operationId, input);
|
||||||
});
|
if (!value) throw new Error(`Capability ${operationId} returned no value`);
|
||||||
if (!response.ok) throw new Error(response.error || `Capability ${operationId} failed`);
|
return liveValue(value);
|
||||||
return protoValueToJs(response.result);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ports.set(dependency.portId, capability);
|
ports.set(dependency.portId, capability);
|
||||||
@@ -237,7 +312,7 @@ export const createRuntimeContext = (
|
|||||||
input: Object.fromEntries(Object.entries(input).map(([key, value]) => [key, jsToProtoValue(value)])),
|
input: Object.fromEntries(Object.entries(input).map(([key, value]) => [key, jsToProtoValue(value)])),
|
||||||
});
|
});
|
||||||
if (!response.object) throw new Error(`Constructor ${atomId} returned no object`);
|
if (!response.object) throw new Error(`Constructor ${atomId} returned no object`);
|
||||||
return response.object.id;
|
return referenceFromWire(response.object.id);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ports.set(dependency.portId, constructor);
|
ports.set(dependency.portId, constructor);
|
||||||
@@ -250,7 +325,7 @@ export const createRuntimeContext = (
|
|||||||
return port as T;
|
return port as T;
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
objectId: request.objectId,
|
objectId: referenceFromWire(request.objectId),
|
||||||
input: protoFieldsToJs(request.input),
|
input: protoFieldsToJs(request.input),
|
||||||
inputProto: request.input,
|
inputProto: request.input,
|
||||||
ports,
|
ports,
|
||||||
@@ -294,9 +369,12 @@ export const createPackageRuntimeRoutes = (config: {
|
|||||||
caminoUrl?: string;
|
caminoUrl?: string;
|
||||||
orchUrl?: string;
|
orchUrl?: string;
|
||||||
}) => {
|
}) => {
|
||||||
|
const invocations = createInvocationRegistry();
|
||||||
const headers: Record<string, string> = {};
|
const headers: Record<string, string> = {};
|
||||||
if (process.env.CAMINO_RUNTIME_AUTH_TOKEN) {
|
const processToken = process.env.CAMINO_RUNTIME_AUTH_TOKEN ?? (process.env.CAMINO_RUNTIME_AUTH_TOKEN_FILE
|
||||||
headers["x-camino-runtime-token"] = process.env.CAMINO_RUNTIME_AUTH_TOKEN;
|
? readFileSync(process.env.CAMINO_RUNTIME_AUTH_TOKEN_FILE, "utf8").trim() : "");
|
||||||
|
if (processToken) {
|
||||||
|
headers["x-camino-runtime-token"] = processToken;
|
||||||
} else if (process.env.CAMINO_RUNTIME_AUTH_REQUIRED === "1") {
|
} else if (process.env.CAMINO_RUNTIME_AUTH_REQUIRED === "1") {
|
||||||
throw new Error("CAMINO_RUNTIME_AUTH_TOKEN is required");
|
throw new Error("CAMINO_RUNTIME_AUTH_TOKEN is required");
|
||||||
}
|
}
|
||||||
@@ -315,20 +393,114 @@ export const createPackageRuntimeRoutes = (config: {
|
|||||||
httpVersion: "1.1",
|
httpVersion: "1.1",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const authenticateInstance = (header: Headers) => {
|
||||||
|
if (!process.env.QUIXOS_RUNTIME_INSTANCE_ID) return; // standalone development ABI
|
||||||
|
const supplied = Buffer.from(header.get("x-quixos-instance-token") ?? "");
|
||||||
|
const expected = Buffer.from(processToken);
|
||||||
|
if (!expected.length || supplied.length !== expected.length || !timingSafeEqual(supplied, expected)) {
|
||||||
|
throw new ConnectError("Invalid runtime instance credential", Code.Unauthenticated);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const clientsFor = (request: { context?: { grant: string; instanceId: string; workspaceEpoch: string } }) => {
|
||||||
|
const context = request.context;
|
||||||
|
if (process.env.QUIXOS_RUNTIME_INSTANCE_ID && (!context?.grant || context.instanceId !== process.env.QUIXOS_RUNTIME_INSTANCE_ID || !context.workspaceEpoch)) {
|
||||||
|
throw new ConnectError("Managed invocation requires an exact instance and epoch grant", Code.Unauthenticated);
|
||||||
|
}
|
||||||
|
if (!context?.grant) return { camino, orch };
|
||||||
|
const transport = (url: string) => createConnectTransport({ baseUrl: url, httpVersion: "1.1", interceptors: [(next) => async (call) => {
|
||||||
|
call.header.set("x-quixos-invocation-grant", context.grant);
|
||||||
|
call.header.set("x-camino-runtime-token", processToken);
|
||||||
|
return next(call);
|
||||||
|
}] });
|
||||||
|
return {
|
||||||
|
camino: createClient(CaminoService, transport(config.caminoUrl ?? process.env.CAMINO_URL ?? "http://127.0.0.1:7310")),
|
||||||
|
orch: createClient(OrchestratorRuntime, transport(config.orchUrl ?? process.env.QUIXOS_ORCH_URL ?? "http://127.0.0.1:7311")),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const runtimeControl = async <T>(operation: string, input: unknown): Promise<T> => {
|
||||||
|
const response = await fetch(`${config.caminoUrl ?? process.env.CAMINO_URL ?? "http://127.0.0.1:7310"}/__runtime/${operation}`, {
|
||||||
|
method: "POST", headers: { "content-type": "application/json", "x-camino-runtime-token": processToken }, body: JSON.stringify(input), signal: AbortSignal.timeout(10_000),
|
||||||
|
});
|
||||||
|
const value = await response.json() as T & {error?: string};
|
||||||
|
if (!response.ok) throw new RuntimeAuthorityError(value.error ?? "Runtime authority request failed");
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
const attachSessions = (runtimeContext: RuntimeContext, request: RuntimeRequest & {context?: {grant: string; instanceId: string; workspaceEpoch: string; ownerConformanceId?: string}}) => {
|
||||||
|
if (!request.context?.grant || !request.context.ownerConformanceId) return;
|
||||||
|
runtimeContext.openSession = async () => {
|
||||||
|
const ownerId = request.context!.ownerConformanceId!;
|
||||||
|
const registration = { grant: request.context!.grant, objectId: request.objectId, ownerId,
|
||||||
|
sessionId: `session:${randomBytes(16).toString("hex")}`, token: randomBytes(32).toString("base64url") };
|
||||||
|
const register = () => runtimeControl<{sessionId: string; token: string}>("register-session", registration);
|
||||||
|
const registered = await register().catch((error) => {
|
||||||
|
// Retry a transport/lost-response failure with exactly the same identity.
|
||||||
|
// Admission/authority errors are definitive and must not be retried here.
|
||||||
|
if (error instanceof RuntimeAuthorityError) throw error;
|
||||||
|
return register();
|
||||||
|
});
|
||||||
|
let closed = false;
|
||||||
|
return {
|
||||||
|
id: registered.sessionId,
|
||||||
|
async run(work) {
|
||||||
|
if (closed) throw new RuntimeAuthorityError("SESSION_CLOSED");
|
||||||
|
// Acquisition happens before user code. A fence failure can be retried
|
||||||
|
// by the caller without replaying a side-effecting callback.
|
||||||
|
const grant = await runtimeControl<{grant: string; epoch: string; instanceId: string; invocationId: string; bindingDigest: string}>("acquire-session", registered);
|
||||||
|
const execution = invocations.begin(grant.invocationId);
|
||||||
|
const sessionRequest = { ...request, context: { grant: grant.grant, instanceId: grant.instanceId, workspaceEpoch: grant.epoch } };
|
||||||
|
const clients = clientsFor(sessionRequest);
|
||||||
|
const context = createRuntimeContext(clients.camino, clients.orch, sessionRequest);
|
||||||
|
context.signal = execution.signal;
|
||||||
|
try { return await work(context); }
|
||||||
|
finally {
|
||||||
|
execution.finish();
|
||||||
|
await runtimeControl("complete-invocation", { invocationId: grant.invocationId }).catch((error) => console.error("Session completion will be reconciled by the host", error));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async close() { await runtimeControl("close-session", registered); closed = true; },
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
return (router: ConnectRouter) => router.service(PackageRuntime, {
|
return (router: ConnectRouter) => router.service(PackageRuntime, {
|
||||||
handshake: () => create(HandshakeResponseSchema, {
|
handshake: (request) => create(HandshakeResponseSchema, {
|
||||||
packageRevisionId: config.packageRevisionId,
|
packageRevisionId: config.packageRevisionId,
|
||||||
runtimeProtocolVersion: "quixos-capabilities-v1",
|
runtimeProtocolVersion: "quixos-capabilities-v1",
|
||||||
exportIds: Object.keys(config.exports),
|
exportIds: Object.keys(config.exports),
|
||||||
|
capabilities: ["invocation-completion-v1", "instance-authentication-v1", "epoch-grants-v1"],
|
||||||
|
instanceId: process.env.QUIXOS_RUNTIME_INSTANCE_ID ?? "",
|
||||||
|
authenticationProof: request.nonce && processToken ? createHmac("sha256", processToken)
|
||||||
|
.update(JSON.stringify([request.nonce, process.env.QUIXOS_RUNTIME_INSTANCE_ID ?? "", config.packageRevisionId]))
|
||||||
|
.digest("hex") : "",
|
||||||
}),
|
}),
|
||||||
invoke: async (request) => {
|
getInvocationStatus: (request, context) => {
|
||||||
|
authenticateInstance(context.requestHeader);
|
||||||
|
return invocations.status(request.invocationId);
|
||||||
|
},
|
||||||
|
cancelInvocation: (request, context) => {
|
||||||
|
authenticateInstance(context.requestHeader);
|
||||||
|
return invocations.cancel(request.invocationId);
|
||||||
|
},
|
||||||
|
invoke: async (request, context) => {
|
||||||
|
authenticateInstance(context.requestHeader);
|
||||||
|
const { camino, orch } = clientsFor(request);
|
||||||
const exportId = request.export?.exportId;
|
const exportId = request.export?.exportId;
|
||||||
const handler = exportId ? config.exports[exportId] : undefined;
|
const handler = exportId ? config.exports[exportId] : undefined;
|
||||||
if (!handler) throw new ConnectError(`Unknown export ${exportId ?? ""}`, Code.NotFound);
|
if (!handler) throw new ConnectError(`Unknown export ${exportId ?? ""}`, Code.NotFound);
|
||||||
|
const execution = invocations.begin(request.invocationId || (process.env.QUIXOS_RUNTIME_INSTANCE_ID ? "" : randomUUID()));
|
||||||
try {
|
try {
|
||||||
const result = await evaluate(handler, createRuntimeContext(camino, orch, request));
|
const runtimeContext = createRuntimeContext(camino, orch, request);
|
||||||
return create(InvokeResponseSchema, { ok: true, result: result.value });
|
attachSessions(runtimeContext, request);
|
||||||
|
runtimeContext.signal = AbortSignal.any([context.signal, execution.signal]);
|
||||||
|
const result = await evaluate(handler, runtimeContext);
|
||||||
|
execution.finish();
|
||||||
|
return create(InvokeResponseSchema, {
|
||||||
|
ok: true,
|
||||||
|
result: result.value,
|
||||||
|
dependencies: protoDependencies(result.dependencies),
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
execution.finish(true);
|
||||||
return create(InvokeResponseSchema, {
|
return create(InvokeResponseSchema, {
|
||||||
ok: false,
|
ok: false,
|
||||||
error: error instanceof Error ? error.message : String(error),
|
error: error instanceof Error ? error.message : String(error),
|
||||||
@@ -336,13 +508,20 @@ export const createPackageRuntimeRoutes = (config: {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: async function* (request, context) {
|
watch: async function* (request, context) {
|
||||||
|
authenticateInstance(context.requestHeader);
|
||||||
|
const { camino, orch } = clientsFor(request);
|
||||||
const exportId = request.export?.exportId;
|
const exportId = request.export?.exportId;
|
||||||
const handler = exportId ? config.exports[exportId] : undefined;
|
const handler = exportId ? config.exports[exportId] : undefined;
|
||||||
if (!handler || !isDerived(handler)) {
|
if (!handler || !isDerived(handler)) {
|
||||||
throw new ConnectError(`Export ${exportId ?? ""} is not derived`, Code.FailedPrecondition);
|
throw new ConnectError(`Export ${exportId ?? ""} is not derived`, Code.FailedPrecondition);
|
||||||
}
|
}
|
||||||
|
const execution = invocations.begin(request.invocationId || (process.env.QUIXOS_RUNTIME_INSTANCE_ID ? "" : randomUUID()));
|
||||||
|
const signal = AbortSignal.any([context.signal, execution.signal]);
|
||||||
|
try {
|
||||||
const watchId = `watch:${randomUUID()}`;
|
const watchId = `watch:${randomUUID()}`;
|
||||||
const runtimeContext = createRuntimeContext(camino, orch, request);
|
const runtimeContext = createRuntimeContext(camino, orch, request);
|
||||||
|
attachSessions(runtimeContext, request);
|
||||||
|
runtimeContext.signal = signal;
|
||||||
type WatchOutcome = { key: string; done: boolean; error?: unknown };
|
type WatchOutcome = { key: string; done: boolean; error?: unknown };
|
||||||
type Subscription = {
|
type Subscription = {
|
||||||
dependency: RuntimeDependency;
|
dependency: RuntimeDependency;
|
||||||
@@ -352,6 +531,7 @@ export const createPackageRuntimeRoutes = (config: {
|
|||||||
};
|
};
|
||||||
const subscriptions = new Map<string, Subscription>();
|
const subscriptions = new Map<string, Subscription>();
|
||||||
const establishing = new Map<string, Promise<void>>();
|
const establishing = new Map<string, Promise<void>>();
|
||||||
|
let subscriptionEpoch = 0;
|
||||||
|
|
||||||
const ensureSubscription = async (dependency: RuntimeDependency) => {
|
const ensureSubscription = async (dependency: RuntimeDependency) => {
|
||||||
const key = dependencyKey(dependency);
|
const key = dependencyKey(dependency);
|
||||||
@@ -361,7 +541,7 @@ export const createPackageRuntimeRoutes = (config: {
|
|||||||
const establish = (async () => {
|
const establish = (async () => {
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const stream = camino.watchObject(
|
const stream = camino.watchObject(
|
||||||
{ objectId: dependency.objectId, includeSnapshot: true },
|
{ objectId: dependency.objectId, includeSnapshot: true, attachmentIds: request.context?.grant ? [dependency.attachmentId] : [] },
|
||||||
{ signal: controller.signal },
|
{ signal: controller.signal },
|
||||||
)[Symbol.asyncIterator]();
|
)[Symbol.asyncIterator]();
|
||||||
try {
|
try {
|
||||||
@@ -381,6 +561,7 @@ export const createPackageRuntimeRoutes = (config: {
|
|||||||
};
|
};
|
||||||
subscription.next = waitNext();
|
subscription.next = waitNext();
|
||||||
subscriptions.set(key, subscription);
|
subscriptions.set(key, subscription);
|
||||||
|
subscriptionEpoch += 1;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
controller.abort();
|
controller.abort();
|
||||||
throw error;
|
throw error;
|
||||||
@@ -399,9 +580,24 @@ export const createPackageRuntimeRoutes = (config: {
|
|||||||
subscription.controller.abort();
|
subscription.controller.abort();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
context.signal.addEventListener("abort", abortAll, { once: true });
|
signal.addEventListener("abort", abortAll, { once: true });
|
||||||
|
|
||||||
let current = await evaluate(handler, runtimeContext, ensureSubscription);
|
const evaluateWithStableSubscriptions = async () => {
|
||||||
|
// A direct state/edge port records its dependency before reading it,
|
||||||
|
// but a nested interface invocation can only report its transitive
|
||||||
|
// dependencies after that invocation returns. Once a new dependency
|
||||||
|
// stream is established, evaluate again so every read contributing to
|
||||||
|
// the emitted value happened after its stream became live.
|
||||||
|
for (let pass = 0; pass < 32; pass += 1) {
|
||||||
|
const before = subscriptionEpoch;
|
||||||
|
const result = await evaluate(handler, runtimeContext, ensureSubscription);
|
||||||
|
if (subscriptionEpoch === before) return result;
|
||||||
|
}
|
||||||
|
throw new Error("Derived dependency discovery did not stabilize after 32 passes");
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
let current = await evaluateWithStableSubscriptions();
|
||||||
yield create(WatchEventSchema, {
|
yield create(WatchEventSchema, {
|
||||||
watchId,
|
watchId,
|
||||||
value: current.value,
|
value: current.value,
|
||||||
@@ -410,11 +606,10 @@ export const createPackageRuntimeRoutes = (config: {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const abort = new Promise<"abort">((resolve) => {
|
const abort = new Promise<"abort">((resolve) => {
|
||||||
if (context.signal.aborted) resolve("abort");
|
if (signal.aborted) resolve("abort");
|
||||||
else context.signal.addEventListener("abort", () => resolve("abort"), { once: true });
|
else signal.addEventListener("abort", () => resolve("abort"), { once: true });
|
||||||
});
|
});
|
||||||
try {
|
while (!signal.aborted) {
|
||||||
while (!context.signal.aborted) {
|
|
||||||
if (subscriptions.size === 0) {
|
if (subscriptions.size === 0) {
|
||||||
await abort;
|
await abort;
|
||||||
break;
|
break;
|
||||||
@@ -430,7 +625,7 @@ export const createPackageRuntimeRoutes = (config: {
|
|||||||
if (outcome.done) throw new Error(`Dependency stream ${outcome.key} ended unexpectedly`);
|
if (outcome.done) throw new Error(`Dependency stream ${outcome.key} ended unexpectedly`);
|
||||||
subscription.next = subscription.waitNext();
|
subscription.next = subscription.waitNext();
|
||||||
|
|
||||||
const updated = await evaluate(handler, runtimeContext, ensureSubscription);
|
const updated = await evaluateWithStableSubscriptions();
|
||||||
const active = new Set(updated.dependencies.map(dependencyKey));
|
const active = new Set(updated.dependencies.map(dependencyKey));
|
||||||
for (const [key, entry] of subscriptions) {
|
for (const [key, entry] of subscriptions) {
|
||||||
if (!active.has(key)) {
|
if (!active.has(key)) {
|
||||||
@@ -448,9 +643,10 @@ export const createPackageRuntimeRoutes = (config: {
|
|||||||
current = updated;
|
current = updated;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
context.signal.removeEventListener("abort", abortAll);
|
signal.removeEventListener("abort", abortAll);
|
||||||
abortAll();
|
abortAll();
|
||||||
}
|
}
|
||||||
|
} finally { execution.finish(); }
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/** Execution completion, not HTTP disconnection, is the drain boundary. */
|
||||||
|
export const createInvocationRegistry = () => {
|
||||||
|
const entries = new Map<string, { state: string; controller: AbortController }>();
|
||||||
|
return {
|
||||||
|
begin(id: string) {
|
||||||
|
if (!id || entries.has(id)) throw new Error("Invocation ID is missing or already used; invocations are never replayed implicitly");
|
||||||
|
// Completed identities remain until process retirement. A bounded process
|
||||||
|
// may reject new work; it must not evict and accidentally replay a call.
|
||||||
|
if (entries.size >= 100_000) throw new Error("Invocation registry full; explicit runtime retirement required");
|
||||||
|
const entry = { state: "running", controller: new AbortController() };
|
||||||
|
entries.set(id, entry);
|
||||||
|
return { signal: entry.controller.signal, finish(failed = false) { entry.state = failed ? "failed" : "completed"; } };
|
||||||
|
},
|
||||||
|
status(id: string) { return { invocationId: id, state: entries.get(id)?.state ?? "unknown" }; },
|
||||||
|
cancel(id: string) {
|
||||||
|
const entry = entries.get(id);
|
||||||
|
if (entry && ["running", "cancellation-requested"].includes(entry.state)) {
|
||||||
|
entry.state = "cancellation-requested";
|
||||||
|
entry.controller.abort();
|
||||||
|
}
|
||||||
|
return this.status(id);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import {createHash} from "node:crypto";
|
||||||
|
|
||||||
|
export type MigrationInput = {
|
||||||
|
schemaVersion: 1; executionId: string; exportId: string;
|
||||||
|
ports: {name: string; binding: string; view: "old" | "new"; access: ("read" | "write" | "create" | "edge")[]; atomId?: string;
|
||||||
|
attachedAtomId?: string; defaultValue?: unknown;
|
||||||
|
states?: {objectId: string; value: unknown}[]; edges?: MigrationEdge[]}[];
|
||||||
|
};
|
||||||
|
export type MigrationEdge = {id: string; edgeTypeId: string; firstObjectId: string; secondObjectId: string; firstProjectionId: string; secondProjectionId: string; firstOrdinal?: number; secondOrdinal?: number; firstKeyJson?: string; secondKeyJson?: string};
|
||||||
|
export type MigrationOutput = {schemaVersion: 1; executionId: string;
|
||||||
|
writes: {port: string; objectId: string; value: unknown}[];
|
||||||
|
creates: {port: string; logicalKey: string; objectId: string}[];
|
||||||
|
edgeReplacements: {port: string; edges: MigrationEdge[]}[]};
|
||||||
|
export type MigrationContext = {
|
||||||
|
enumerate(port: string): {objectId: string; value: unknown}[];
|
||||||
|
read(port: string, objectId: string): unknown;
|
||||||
|
write(port: string, objectId: string, value: unknown): void;
|
||||||
|
create(port: string, logicalKey: string): string;
|
||||||
|
edges(port: string): MigrationEdge[];
|
||||||
|
replaceEdges(port: string, edges: MigrationEdge[]): void;
|
||||||
|
};
|
||||||
|
export const migrationObjectId = (executionId: string, port: string, logicalKey: string) =>
|
||||||
|
`obj:migration:${createHash("sha256").update(JSON.stringify([executionId, port, logicalKey])).digest("hex")}`;
|
||||||
|
|
||||||
|
/** No ordinary RuntimeContext or network/database clients are supplied here.
|
||||||
|
* Process isolation belongs to the host, not this convenience API. */
|
||||||
|
export const createMigrationContext = (input: MigrationInput) => {
|
||||||
|
if (input.schemaVersion !== 1 || !input.executionId || new Set(input.ports.map((entry) => entry.name)).size !== input.ports.length) throw new Error("Invalid migration input");
|
||||||
|
const output: MigrationOutput = {schemaVersion: 1, executionId: input.executionId, writes: [], creates: [], edgeReplacements: []};
|
||||||
|
const port = (name: string, access: string) => {
|
||||||
|
const selected = input.ports.find((entry) => entry.name === name);
|
||||||
|
if (!selected?.access.includes(access as "read") || (selected.view === "old" && access !== "read")) throw new Error(`Migration port ${name} does not grant ${access}`);
|
||||||
|
return selected;
|
||||||
|
};
|
||||||
|
const context: MigrationContext = {
|
||||||
|
enumerate(name) {
|
||||||
|
const selected = port(name, "read"), states = structuredClone(selected.states ?? []);
|
||||||
|
if (selected.view === "new" && Object.hasOwn(selected, "defaultValue")) for (const helper of output.creates) {
|
||||||
|
if (input.ports.find((entry) => entry.name === helper.port)?.atomId === selected.attachedAtomId && !states.some((entry) => entry.objectId === helper.objectId)) states.push({objectId: helper.objectId, value: structuredClone(selected.defaultValue)});
|
||||||
|
}
|
||||||
|
if (selected.view === "new") for (const write of output.writes) {
|
||||||
|
if (input.ports.find((entry) => entry.name === write.port)?.binding !== selected.binding) continue;
|
||||||
|
const existing = states.findIndex((entry) => entry.objectId === write.objectId), entry = {objectId: write.objectId, value: structuredClone(write.value)};
|
||||||
|
if (existing < 0) states.push(entry); else states[existing] = entry;
|
||||||
|
}
|
||||||
|
return states.sort((a, b) => a.objectId < b.objectId ? -1 : a.objectId > b.objectId ? 1 : 0);
|
||||||
|
},
|
||||||
|
read(name, objectId) {return context.enumerate(name).find((entry) => entry.objectId === objectId)?.value;},
|
||||||
|
write(name, objectId, value) {
|
||||||
|
port(name, "write");
|
||||||
|
const previous = output.writes.findIndex((entry) => entry.port === name && entry.objectId === objectId);
|
||||||
|
const entry = {port: name, objectId, value: structuredClone(value)};
|
||||||
|
if (previous < 0) output.writes.push(entry); else output.writes[previous] = entry;
|
||||||
|
},
|
||||||
|
create(name, logicalKey) {
|
||||||
|
port(name, "create");
|
||||||
|
if (!logicalKey || logicalKey.length > 1024) throw new Error("Migration creation requires a bounded stable logical key");
|
||||||
|
const objectId = migrationObjectId(input.executionId, name, logicalKey);
|
||||||
|
if (!output.creates.some((entry) => entry.objectId === objectId)) output.creates.push({port: name, logicalKey, objectId});
|
||||||
|
return objectId;
|
||||||
|
},
|
||||||
|
edges(name) {
|
||||||
|
const selected = port(name, "read");
|
||||||
|
const replacement = selected.view === "new" ? output.edgeReplacements.find((entry) => input.ports.find((candidate) => candidate.name === entry.port)?.binding === selected.binding) : undefined;
|
||||||
|
return structuredClone(replacement?.edges ?? selected.edges ?? []);
|
||||||
|
},
|
||||||
|
replaceEdges(name, edges) {
|
||||||
|
port(name, "edge");
|
||||||
|
const previous = output.edgeReplacements.findIndex((entry) => entry.port === name);
|
||||||
|
const entry = {port: name, edges: structuredClone(edges)};
|
||||||
|
if (previous < 0) output.edgeReplacements.push(entry); else output.edgeReplacements[previous] = entry;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return {context, result: () => structuredClone(output)};
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Entrypoint for an immutable package's dedicated bin/migrate executable.
|
||||||
|
* stdout is protocol-only; send diagnostics to stderr. The host independently
|
||||||
|
* validates every write, helper identity, contract, and completion receipt. */
|
||||||
|
export const serveMigration = async (exports: Record<string, (context: MigrationContext) => void | Promise<void>>) => {
|
||||||
|
const chunks: Buffer[] = []; let bytes = 0;
|
||||||
|
for await (const chunk of process.stdin) {
|
||||||
|
bytes += chunk.length;
|
||||||
|
if (bytes > 16 * 1024 * 1024) throw new Error("Migration input exceeds 16 MiB");
|
||||||
|
chunks.push(Buffer.from(chunk));
|
||||||
|
}
|
||||||
|
const input = JSON.parse(Buffer.concat(chunks).toString("utf8")) as MigrationInput;
|
||||||
|
const implementation = Object.hasOwn(exports, input.exportId) ? exports[input.exportId] : undefined;
|
||||||
|
if (!implementation) throw new Error("Unknown migration export");
|
||||||
|
const execution = createMigrationContext(input);
|
||||||
|
await implementation(execution.context);
|
||||||
|
const result = JSON.stringify(execution.result());
|
||||||
|
if (Buffer.byteLength(result) > 16 * 1024 * 1024) throw new Error("Migration output exceeds 16 MiB");
|
||||||
|
process.stdout.write(`${result}\n`);
|
||||||
|
};
|
||||||
+87
-17
@@ -18,7 +18,7 @@ import type { Message } from "@bufbuild/protobuf";
|
|||||||
* Describes the file quixos/orch.proto.
|
* Describes the file quixos/orch.proto.
|
||||||
*/
|
*/
|
||||||
export const file_quixos_orch: GenFile = /*@__PURE__*/
|
export const file_quixos_orch: GenFile = /*@__PURE__*/
|
||||||
fileDesc("ChFxdWl4b3Mvb3JjaC5wcm90bxILcXVpeG9zLm9yY2gipQEKFkNvbnN0cnVjdE9iamVjdFJlcXVlc3QSDwoHYXRvbV9pZBgBIAEoCRI9CgVpbnB1dBgCIAMoCzIuLnF1aXhvcy5vcmNoLkNvbnN0cnVjdE9iamVjdFJlcXVlc3QuSW5wdXRFbnRyeRo7CgpJbnB1dEVudHJ5EgsKA2tleRgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLmNhbWluby5WYWx1ZToCOAEiPwoXQ29uc3RydWN0T2JqZWN0UmVzcG9uc2USJAoGb2JqZWN0GAEgASgLMhQuY2FtaW5vLkNhbWlub09iamVjdCLUAQoXSW52b2tlQ2FwYWJpbGl0eVJlcXVlc3QSKQoKY2FwYWJpbGl0eRgBIAEoCzIVLnF1aXhvcy5DYXBhYmlsaXR5UmVmEhEKCW9iamVjdF9pZBgCIAEoCRI+CgVpbnB1dBgDIAMoCzIvLnF1aXhvcy5vcmNoLkludm9rZUNhcGFiaWxpdHlSZXF1ZXN0LklucHV0RW50cnkaOwoKSW5wdXRFbnRyeRILCgNrZXkYASABKAkSHAoFdmFsdWUYAiABKAsyDS5jYW1pbm8uVmFsdWU6AjgBIpgBChhJbnZva2VDYXBhYmlsaXR5UmVzcG9uc2USFQoNaW52b2NhdGlvbl9pZBgBIAEoCRIrCgphY3RpdmF0aW9uGAIgASgLMhcucXVpeG9zLm9yY2guQWN0aXZhdGlvbhIKCgJvaxgDIAEoCBIdCgZyZXN1bHQYBCABKAsyDS5jYW1pbm8uVmFsdWUSDQoFZXJyb3IYBSABKAki0gEKFldhdGNoQ2FwYWJpbGl0eVJlcXVlc3QSKQoKY2FwYWJpbGl0eRgBIAEoCzIVLnF1aXhvcy5DYXBhYmlsaXR5UmVmEhEKCW9iamVjdF9pZBgCIAEoCRI9CgVpbnB1dBgDIAMoCzIuLnF1aXhvcy5vcmNoLldhdGNoQ2FwYWJpbGl0eVJlcXVlc3QuSW5wdXRFbnRyeRo7CgpJbnB1dEVudHJ5EgsKA2tleRgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLmNhbWluby5WYWx1ZToCOAEi4wEKFFdhdGNoQ2FwYWJpbGl0eUV2ZW50EhUKDWludm9jYXRpb25faWQYASABKAkSKwoKYWN0aXZhdGlvbhgCIAEoCzIXLnF1aXhvcy5vcmNoLkFjdGl2YXRpb24SEAoId2F0Y2hfaWQYAyABKAkSHAoFdmFsdWUYBCABKAsyDS5jYW1pbm8uVmFsdWUSNwoMZGVwZW5kZW5jaWVzGAUgAygLMiEucXVpeG9zLnJ1bnRpbWUuRGVyaXZlZERlcGVuZGVuY3kSDQoFZXJyb3IYBiABKAkSDwoHaW5pdGlhbBgHIAEoCCIVChNHZXRXb3Jrc3BhY2VSZXF1ZXN0ImcKFEdldFdvcmtzcGFjZVJlc3BvbnNlEhQKDHdvcmtzcGFjZV9pZBgBIAEoCRIdChV3b3Jrc3BhY2VfcmV2aXNpb25faWQYAiABKAkSGgoSc291cmNlX3Jvb3RfY29tbWl0GAMgASgJIhgKFkxpc3RBY3RpdmF0aW9uc1JlcXVlc3QiHwodTGlzdFBhY2thZ2VEZXNjcmlwdG9yc1JlcXVlc3QiUAoeTGlzdFBhY2thZ2VEZXNjcmlwdG9yc1Jlc3BvbnNlEi4KC2Rlc2NyaXB0b3JzGAEgAygLMhkucXVpeG9zLlBhY2thZ2VEZXNjcmlwdG9yIhwKGkxpc3RQYWNrYWdlUnVudGltZXNSZXF1ZXN0IlIKG0xpc3RQYWNrYWdlUnVudGltZXNSZXNwb25zZRIzCghydW50aW1lcxgBIAMoCzIhLnF1aXhvcy5vcmNoLlBhY2thZ2VSdW50aW1lU3RhdHVzIkcKF0xpc3RBY3RpdmF0aW9uc1Jlc3BvbnNlEiwKC2FjdGl2YXRpb25zGAEgAygLMhcucXVpeG9zLm9yY2guQWN0aXZhdGlvbiI/ChZDbG9zZUFjdGl2YXRpb25SZXF1ZXN0EhUKDWFjdGl2YXRpb25faWQYASABKAkSDgoGcmVhc29uGAIgASgJIkYKF0Nsb3NlQWN0aXZhdGlvblJlc3BvbnNlEisKCmFjdGl2YXRpb24YASABKAsyFy5xdWl4b3Mub3JjaC5BY3RpdmF0aW9uIusBCgpBY3RpdmF0aW9uEhUKDWFjdGl2YXRpb25faWQYASABKAkSKAoGZXhwb3J0GAIgASgLMhgucXVpeG9zLlBhY2thZ2VFeHBvcnRSZWYSEQoJb2JqZWN0X2lkGAMgASgJEg0KBXN0YXRlGAQgASgJEg4KBmRlbWFuZBgFIAEoDRIRCglvcGVuZWRfYXQYBiABKAkSFAoMbGFzdF91c2VkX2F0GAcgASgJEhgKEGlkbGVfZGVhZGxpbmVfYXQYCCABKAkSEQoJY2xvc2VkX2F0GAkgASgJEhQKDGNsb3NlX3JlYXNvbhgKIAEoCSKzAgoUUGFja2FnZVJ1bnRpbWVTdGF0dXMSEwoLcnVudGltZV9rZXkYASABKAkSGwoTcGFja2FnZV9yZXZpc2lvbl9pZBgCIAEoCRIZChFzb3VyY2VfcmVwb3NpdG9yeRgDIAEoCRIVCg1zb3VyY2VfY29tbWl0GAQgASgJEhQKDGJ1aWxkX3RhcmdldBgFIAEoCRITCgtzZXJ2ZXJfcGF0aBgGIAEoCRILCgNwaWQYByABKA0SDQoFc3RhdGUYCCABKAkSEgoKc3RhcnRlZF9hdBgJIAEoCRIZChFsYXN0X2hhbmRzaGFrZV9hdBgKIAEoCRIgChhydW50aW1lX3Byb3RvY29sX3ZlcnNpb24YCyABKAkSHwoXYWR2ZXJ0aXNlZF9leHBvcnRfY291bnQYDCABKA0ynwYKE09yY2hlc3RyYXRvclJ1bnRpbWUSXwoQSW52b2tlQ2FwYWJpbGl0eRIkLnF1aXhvcy5vcmNoLkludm9rZUNhcGFiaWxpdHlSZXF1ZXN0GiUucXVpeG9zLm9yY2guSW52b2tlQ2FwYWJpbGl0eVJlc3BvbnNlElsKD1dhdGNoQ2FwYWJpbGl0eRIjLnF1aXhvcy5vcmNoLldhdGNoQ2FwYWJpbGl0eVJlcXVlc3QaIS5xdWl4b3Mub3JjaC5XYXRjaENhcGFiaWxpdHlFdmVudDABElwKD0NvbnN0cnVjdE9iamVjdBIjLnF1aXhvcy5vcmNoLkNvbnN0cnVjdE9iamVjdFJlcXVlc3QaJC5xdWl4b3Mub3JjaC5Db25zdHJ1Y3RPYmplY3RSZXNwb25zZRJTCgxHZXRXb3Jrc3BhY2USIC5xdWl4b3Mub3JjaC5HZXRXb3Jrc3BhY2VSZXF1ZXN0GiEucXVpeG9zLm9yY2guR2V0V29ya3NwYWNlUmVzcG9uc2UScQoWTGlzdFBhY2thZ2VEZXNjcmlwdG9ycxIqLnF1aXhvcy5vcmNoLkxpc3RQYWNrYWdlRGVzY3JpcHRvcnNSZXF1ZXN0GisucXVpeG9zLm9yY2guTGlzdFBhY2thZ2VEZXNjcmlwdG9yc1Jlc3BvbnNlEmgKE0xpc3RQYWNrYWdlUnVudGltZXMSJy5xdWl4b3Mub3JjaC5MaXN0UGFja2FnZVJ1bnRpbWVzUmVxdWVzdBooLnF1aXhvcy5vcmNoLkxpc3RQYWNrYWdlUnVudGltZXNSZXNwb25zZRJcCg9MaXN0QWN0aXZhdGlvbnMSIy5xdWl4b3Mub3JjaC5MaXN0QWN0aXZhdGlvbnNSZXF1ZXN0GiQucXVpeG9zLm9yY2guTGlzdEFjdGl2YXRpb25zUmVzcG9uc2USXAoPQ2xvc2VBY3RpdmF0aW9uEiMucXVpeG9zLm9yY2guQ2xvc2VBY3RpdmF0aW9uUmVxdWVzdBokLnF1aXhvcy5vcmNoLkNsb3NlQWN0aXZhdGlvblJlc3BvbnNlYgZwcm90bzM", [file_camino_api, file_quixos_package, file_quixos_refs, file_quixos_runtime]);
|
fileDesc("ChFxdWl4b3Mvb3JjaC5wcm90bxILcXVpeG9zLm9yY2gipQEKFkNvbnN0cnVjdE9iamVjdFJlcXVlc3QSDwoHYXRvbV9pZBgBIAEoCRI9CgVpbnB1dBgCIAMoCzIuLnF1aXhvcy5vcmNoLkNvbnN0cnVjdE9iamVjdFJlcXVlc3QuSW5wdXRFbnRyeRo7CgpJbnB1dEVudHJ5EgsKA2tleRgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLmNhbWluby5WYWx1ZToCOAEiPwoXQ29uc3RydWN0T2JqZWN0UmVzcG9uc2USJAoGb2JqZWN0GAEgASgLMhQuY2FtaW5vLkNhbWlub09iamVjdCJtCiZSZXNvbHZlT3JDb25zdHJ1Y3RSZWxhdGVkT2JqZWN0UmVxdWVzdBIRCglvYmplY3RfaWQYASABKAkSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAIgASgJEhEKCW1lbWJlcl9pZBgDIAEoCSJkCidSZXNvbHZlT3JDb25zdHJ1Y3RSZWxhdGVkT2JqZWN0UmVzcG9uc2USJAoGb2JqZWN0GAEgASgLMhQuY2FtaW5vLkNhbWlub09iamVjdBITCgtjb25zdHJ1Y3RlZBgCIAEoCCLwAQoXSW52b2tlQ2FwYWJpbGl0eVJlcXVlc3QSKQoKY2FwYWJpbGl0eRgBIAEoCzIVLnF1aXhvcy5DYXBhYmlsaXR5UmVmEhEKCW9iamVjdF9pZBgCIAEoCRI+CgVpbnB1dBgDIAMoCzIvLnF1aXhvcy5vcmNoLkludm9rZUNhcGFiaWxpdHlSZXF1ZXN0LklucHV0RW50cnkSGgoSY2xpZW50X211dGF0aW9uX2lkGAQgASgJGjsKCklucHV0RW50cnkSCwoDa2V5GAEgASgJEhwKBXZhbHVlGAIgASgLMg0uY2FtaW5vLlZhbHVlOgI4ASLRAQoYSW52b2tlQ2FwYWJpbGl0eVJlc3BvbnNlEhUKDWludm9jYXRpb25faWQYASABKAkSKwoKYWN0aXZhdGlvbhgCIAEoCzIXLnF1aXhvcy5vcmNoLkFjdGl2YXRpb24SCgoCb2sYAyABKAgSHQoGcmVzdWx0GAQgASgLMg0uY2FtaW5vLlZhbHVlEg0KBWVycm9yGAUgASgJEjcKDGRlcGVuZGVuY2llcxgGIAMoCzIhLnF1aXhvcy5ydW50aW1lLkRlcml2ZWREZXBlbmRlbmN5ItIBChZXYXRjaENhcGFiaWxpdHlSZXF1ZXN0EikKCmNhcGFiaWxpdHkYASABKAsyFS5xdWl4b3MuQ2FwYWJpbGl0eVJlZhIRCglvYmplY3RfaWQYAiABKAkSPQoFaW5wdXQYAyADKAsyLi5xdWl4b3Mub3JjaC5XYXRjaENhcGFiaWxpdHlSZXF1ZXN0LklucHV0RW50cnkaOwoKSW5wdXRFbnRyeRILCgNrZXkYASABKAkSHAoFdmFsdWUYAiABKAsyDS5jYW1pbm8uVmFsdWU6AjgBIuMBChRXYXRjaENhcGFiaWxpdHlFdmVudBIVCg1pbnZvY2F0aW9uX2lkGAEgASgJEisKCmFjdGl2YXRpb24YAiABKAsyFy5xdWl4b3Mub3JjaC5BY3RpdmF0aW9uEhAKCHdhdGNoX2lkGAMgASgJEhwKBXZhbHVlGAQgASgLMg0uY2FtaW5vLlZhbHVlEjcKDGRlcGVuZGVuY2llcxgFIAMoCzIhLnF1aXhvcy5ydW50aW1lLkRlcml2ZWREZXBlbmRlbmN5Eg0KBWVycm9yGAYgASgJEg8KB2luaXRpYWwYByABKAgiFQoTR2V0V29ya3NwYWNlUmVxdWVzdCJnChRHZXRXb3Jrc3BhY2VSZXNwb25zZRIUCgx3b3Jrc3BhY2VfaWQYASABKAkSHQoVd29ya3NwYWNlX3JldmlzaW9uX2lkGAIgASgJEhoKEnNvdXJjZV9yb290X2NvbW1pdBgDIAEoCSIYChZMaXN0QWN0aXZhdGlvbnNSZXF1ZXN0Ih8KHUxpc3RQYWNrYWdlRGVzY3JpcHRvcnNSZXF1ZXN0IlAKHkxpc3RQYWNrYWdlRGVzY3JpcHRvcnNSZXNwb25zZRIuCgtkZXNjcmlwdG9ycxgBIAMoCzIZLnF1aXhvcy5QYWNrYWdlRGVzY3JpcHRvciIcChpMaXN0UGFja2FnZVJ1bnRpbWVzUmVxdWVzdCJSChtMaXN0UGFja2FnZVJ1bnRpbWVzUmVzcG9uc2USMwoIcnVudGltZXMYASADKAsyIS5xdWl4b3Mub3JjaC5QYWNrYWdlUnVudGltZVN0YXR1cyJHChdMaXN0QWN0aXZhdGlvbnNSZXNwb25zZRIsCgthY3RpdmF0aW9ucxgBIAMoCzIXLnF1aXhvcy5vcmNoLkFjdGl2YXRpb24iPwoWQ2xvc2VBY3RpdmF0aW9uUmVxdWVzdBIVCg1hY3RpdmF0aW9uX2lkGAEgASgJEg4KBnJlYXNvbhgCIAEoCSJGChdDbG9zZUFjdGl2YXRpb25SZXNwb25zZRIrCgphY3RpdmF0aW9uGAEgASgLMhcucXVpeG9zLm9yY2guQWN0aXZhdGlvbiLrAQoKQWN0aXZhdGlvbhIVCg1hY3RpdmF0aW9uX2lkGAEgASgJEigKBmV4cG9ydBgCIAEoCzIYLnF1aXhvcy5QYWNrYWdlRXhwb3J0UmVmEhEKCW9iamVjdF9pZBgDIAEoCRINCgVzdGF0ZRgEIAEoCRIOCgZkZW1hbmQYBSABKA0SEQoJb3BlbmVkX2F0GAYgASgJEhQKDGxhc3RfdXNlZF9hdBgHIAEoCRIYChBpZGxlX2RlYWRsaW5lX2F0GAggASgJEhEKCWNsb3NlZF9hdBgJIAEoCRIUCgxjbG9zZV9yZWFzb24YCiABKAkiswIKFFBhY2thZ2VSdW50aW1lU3RhdHVzEhMKC3J1bnRpbWVfa2V5GAEgASgJEhsKE3BhY2thZ2VfcmV2aXNpb25faWQYAiABKAkSGQoRc291cmNlX3JlcG9zaXRvcnkYAyABKAkSFQoNc291cmNlX2NvbW1pdBgEIAEoCRIUCgxidWlsZF90YXJnZXQYBSABKAkSEwoLc2VydmVyX3BhdGgYBiABKAkSCwoDcGlkGAcgASgNEg0KBXN0YXRlGAggASgJEhIKCnN0YXJ0ZWRfYXQYCSABKAkSGQoRbGFzdF9oYW5kc2hha2VfYXQYCiABKAkSIAoYcnVudGltZV9wcm90b2NvbF92ZXJzaW9uGAsgASgJEh8KF2FkdmVydGlzZWRfZXhwb3J0X2NvdW50GAwgASgNMq4HChNPcmNoZXN0cmF0b3JSdW50aW1lEl8KEEludm9rZUNhcGFiaWxpdHkSJC5xdWl4b3Mub3JjaC5JbnZva2VDYXBhYmlsaXR5UmVxdWVzdBolLnF1aXhvcy5vcmNoLkludm9rZUNhcGFiaWxpdHlSZXNwb25zZRJbCg9XYXRjaENhcGFiaWxpdHkSIy5xdWl4b3Mub3JjaC5XYXRjaENhcGFiaWxpdHlSZXF1ZXN0GiEucXVpeG9zLm9yY2guV2F0Y2hDYXBhYmlsaXR5RXZlbnQwARJcCg9Db25zdHJ1Y3RPYmplY3QSIy5xdWl4b3Mub3JjaC5Db25zdHJ1Y3RPYmplY3RSZXF1ZXN0GiQucXVpeG9zLm9yY2guQ29uc3RydWN0T2JqZWN0UmVzcG9uc2USjAEKH1Jlc29sdmVPckNvbnN0cnVjdFJlbGF0ZWRPYmplY3QSMy5xdWl4b3Mub3JjaC5SZXNvbHZlT3JDb25zdHJ1Y3RSZWxhdGVkT2JqZWN0UmVxdWVzdBo0LnF1aXhvcy5vcmNoLlJlc29sdmVPckNvbnN0cnVjdFJlbGF0ZWRPYmplY3RSZXNwb25zZRJTCgxHZXRXb3Jrc3BhY2USIC5xdWl4b3Mub3JjaC5HZXRXb3Jrc3BhY2VSZXF1ZXN0GiEucXVpeG9zLm9yY2guR2V0V29ya3NwYWNlUmVzcG9uc2UScQoWTGlzdFBhY2thZ2VEZXNjcmlwdG9ycxIqLnF1aXhvcy5vcmNoLkxpc3RQYWNrYWdlRGVzY3JpcHRvcnNSZXF1ZXN0GisucXVpeG9zLm9yY2guTGlzdFBhY2thZ2VEZXNjcmlwdG9yc1Jlc3BvbnNlEmgKE0xpc3RQYWNrYWdlUnVudGltZXMSJy5xdWl4b3Mub3JjaC5MaXN0UGFja2FnZVJ1bnRpbWVzUmVxdWVzdBooLnF1aXhvcy5vcmNoLkxpc3RQYWNrYWdlUnVudGltZXNSZXNwb25zZRJcCg9MaXN0QWN0aXZhdGlvbnMSIy5xdWl4b3Mub3JjaC5MaXN0QWN0aXZhdGlvbnNSZXF1ZXN0GiQucXVpeG9zLm9yY2guTGlzdEFjdGl2YXRpb25zUmVzcG9uc2USXAoPQ2xvc2VBY3RpdmF0aW9uEiMucXVpeG9zLm9yY2guQ2xvc2VBY3RpdmF0aW9uUmVxdWVzdBokLnF1aXhvcy5vcmNoLkNsb3NlQWN0aXZhdGlvblJlc3BvbnNlYgZwcm90bzM", [file_camino_api, file_quixos_package, file_quixos_refs, file_quixos_runtime]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.ConstructObjectRequest
|
* @generated from message quixos.orch.ConstructObjectRequest
|
||||||
@@ -59,6 +59,55 @@ export type ConstructObjectResponse = Message<"quixos.orch.ConstructObjectRespon
|
|||||||
export const ConstructObjectResponseSchema: GenMessage<ConstructObjectResponse> = /*@__PURE__*/
|
export const ConstructObjectResponseSchema: GenMessage<ConstructObjectResponse> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 1);
|
messageDesc(file_quixos_orch, 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message quixos.orch.ResolveOrConstructRelatedObjectRequest
|
||||||
|
*/
|
||||||
|
export type ResolveOrConstructRelatedObjectRequest = Message<"quixos.orch.ResolveOrConstructRelatedObjectRequest"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: string object_id = 1;
|
||||||
|
*/
|
||||||
|
objectId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string interface_revision_id = 2;
|
||||||
|
*/
|
||||||
|
interfaceRevisionId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string member_id = 3;
|
||||||
|
*/
|
||||||
|
memberId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.orch.ResolveOrConstructRelatedObjectRequest.
|
||||||
|
* Use `create(ResolveOrConstructRelatedObjectRequestSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export const ResolveOrConstructRelatedObjectRequestSchema: GenMessage<ResolveOrConstructRelatedObjectRequest> = /*@__PURE__*/
|
||||||
|
messageDesc(file_quixos_orch, 2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message quixos.orch.ResolveOrConstructRelatedObjectResponse
|
||||||
|
*/
|
||||||
|
export type ResolveOrConstructRelatedObjectResponse = Message<"quixos.orch.ResolveOrConstructRelatedObjectResponse"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: camino.CaminoObject object = 1;
|
||||||
|
*/
|
||||||
|
object?: CaminoObject | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: bool constructed = 2;
|
||||||
|
*/
|
||||||
|
constructed: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.orch.ResolveOrConstructRelatedObjectResponse.
|
||||||
|
* Use `create(ResolveOrConstructRelatedObjectResponseSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export const ResolveOrConstructRelatedObjectResponseSchema: GenMessage<ResolveOrConstructRelatedObjectResponse> = /*@__PURE__*/
|
||||||
|
messageDesc(file_quixos_orch, 3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.InvokeCapabilityRequest
|
* @generated from message quixos.orch.InvokeCapabilityRequest
|
||||||
*/
|
*/
|
||||||
@@ -77,6 +126,14 @@ export type InvokeCapabilityRequest = Message<"quixos.orch.InvokeCapabilityReque
|
|||||||
* @generated from field: map<string, camino.Value> input = 3;
|
* @generated from field: map<string, camino.Value> input = 3;
|
||||||
*/
|
*/
|
||||||
input: { [key: string]: Value };
|
input: { [key: string]: Value };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifies one logical client mutation across the capability and Camino
|
||||||
|
* layers so a live-value controller can recognize its own confirmation.
|
||||||
|
*
|
||||||
|
* @generated from field: string client_mutation_id = 4;
|
||||||
|
*/
|
||||||
|
clientMutationId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,7 +141,7 @@ export type InvokeCapabilityRequest = Message<"quixos.orch.InvokeCapabilityReque
|
|||||||
* Use `create(InvokeCapabilityRequestSchema)` to create a new message.
|
* Use `create(InvokeCapabilityRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const InvokeCapabilityRequestSchema: GenMessage<InvokeCapabilityRequest> = /*@__PURE__*/
|
export const InvokeCapabilityRequestSchema: GenMessage<InvokeCapabilityRequest> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 2);
|
messageDesc(file_quixos_orch, 4);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.InvokeCapabilityResponse
|
* @generated from message quixos.orch.InvokeCapabilityResponse
|
||||||
@@ -114,6 +171,11 @@ export type InvokeCapabilityResponse = Message<"quixos.orch.InvokeCapabilityResp
|
|||||||
* @generated from field: string error = 5;
|
* @generated from field: string error = 5;
|
||||||
*/
|
*/
|
||||||
error: string;
|
error: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: repeated quixos.runtime.DerivedDependency dependencies = 6;
|
||||||
|
*/
|
||||||
|
dependencies: DerivedDependency[];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -121,7 +183,7 @@ export type InvokeCapabilityResponse = Message<"quixos.orch.InvokeCapabilityResp
|
|||||||
* Use `create(InvokeCapabilityResponseSchema)` to create a new message.
|
* Use `create(InvokeCapabilityResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const InvokeCapabilityResponseSchema: GenMessage<InvokeCapabilityResponse> = /*@__PURE__*/
|
export const InvokeCapabilityResponseSchema: GenMessage<InvokeCapabilityResponse> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 3);
|
messageDesc(file_quixos_orch, 5);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.WatchCapabilityRequest
|
* @generated from message quixos.orch.WatchCapabilityRequest
|
||||||
@@ -148,7 +210,7 @@ export type WatchCapabilityRequest = Message<"quixos.orch.WatchCapabilityRequest
|
|||||||
* Use `create(WatchCapabilityRequestSchema)` to create a new message.
|
* Use `create(WatchCapabilityRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const WatchCapabilityRequestSchema: GenMessage<WatchCapabilityRequest> = /*@__PURE__*/
|
export const WatchCapabilityRequestSchema: GenMessage<WatchCapabilityRequest> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 4);
|
messageDesc(file_quixos_orch, 6);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.WatchCapabilityEvent
|
* @generated from message quixos.orch.WatchCapabilityEvent
|
||||||
@@ -195,7 +257,7 @@ export type WatchCapabilityEvent = Message<"quixos.orch.WatchCapabilityEvent"> &
|
|||||||
* Use `create(WatchCapabilityEventSchema)` to create a new message.
|
* Use `create(WatchCapabilityEventSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const WatchCapabilityEventSchema: GenMessage<WatchCapabilityEvent> = /*@__PURE__*/
|
export const WatchCapabilityEventSchema: GenMessage<WatchCapabilityEvent> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 5);
|
messageDesc(file_quixos_orch, 7);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.GetWorkspaceRequest
|
* @generated from message quixos.orch.GetWorkspaceRequest
|
||||||
@@ -208,7 +270,7 @@ export type GetWorkspaceRequest = Message<"quixos.orch.GetWorkspaceRequest"> & {
|
|||||||
* Use `create(GetWorkspaceRequestSchema)` to create a new message.
|
* Use `create(GetWorkspaceRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const GetWorkspaceRequestSchema: GenMessage<GetWorkspaceRequest> = /*@__PURE__*/
|
export const GetWorkspaceRequestSchema: GenMessage<GetWorkspaceRequest> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 6);
|
messageDesc(file_quixos_orch, 8);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.GetWorkspaceResponse
|
* @generated from message quixos.orch.GetWorkspaceResponse
|
||||||
@@ -235,7 +297,7 @@ export type GetWorkspaceResponse = Message<"quixos.orch.GetWorkspaceResponse"> &
|
|||||||
* Use `create(GetWorkspaceResponseSchema)` to create a new message.
|
* Use `create(GetWorkspaceResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const GetWorkspaceResponseSchema: GenMessage<GetWorkspaceResponse> = /*@__PURE__*/
|
export const GetWorkspaceResponseSchema: GenMessage<GetWorkspaceResponse> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 7);
|
messageDesc(file_quixos_orch, 9);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.ListActivationsRequest
|
* @generated from message quixos.orch.ListActivationsRequest
|
||||||
@@ -248,7 +310,7 @@ export type ListActivationsRequest = Message<"quixos.orch.ListActivationsRequest
|
|||||||
* Use `create(ListActivationsRequestSchema)` to create a new message.
|
* Use `create(ListActivationsRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListActivationsRequestSchema: GenMessage<ListActivationsRequest> = /*@__PURE__*/
|
export const ListActivationsRequestSchema: GenMessage<ListActivationsRequest> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 8);
|
messageDesc(file_quixos_orch, 10);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.ListPackageDescriptorsRequest
|
* @generated from message quixos.orch.ListPackageDescriptorsRequest
|
||||||
@@ -261,7 +323,7 @@ export type ListPackageDescriptorsRequest = Message<"quixos.orch.ListPackageDesc
|
|||||||
* Use `create(ListPackageDescriptorsRequestSchema)` to create a new message.
|
* Use `create(ListPackageDescriptorsRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListPackageDescriptorsRequestSchema: GenMessage<ListPackageDescriptorsRequest> = /*@__PURE__*/
|
export const ListPackageDescriptorsRequestSchema: GenMessage<ListPackageDescriptorsRequest> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 9);
|
messageDesc(file_quixos_orch, 11);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.ListPackageDescriptorsResponse
|
* @generated from message quixos.orch.ListPackageDescriptorsResponse
|
||||||
@@ -278,7 +340,7 @@ export type ListPackageDescriptorsResponse = Message<"quixos.orch.ListPackageDes
|
|||||||
* Use `create(ListPackageDescriptorsResponseSchema)` to create a new message.
|
* Use `create(ListPackageDescriptorsResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListPackageDescriptorsResponseSchema: GenMessage<ListPackageDescriptorsResponse> = /*@__PURE__*/
|
export const ListPackageDescriptorsResponseSchema: GenMessage<ListPackageDescriptorsResponse> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 10);
|
messageDesc(file_quixos_orch, 12);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.ListPackageRuntimesRequest
|
* @generated from message quixos.orch.ListPackageRuntimesRequest
|
||||||
@@ -291,7 +353,7 @@ export type ListPackageRuntimesRequest = Message<"quixos.orch.ListPackageRuntime
|
|||||||
* Use `create(ListPackageRuntimesRequestSchema)` to create a new message.
|
* Use `create(ListPackageRuntimesRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListPackageRuntimesRequestSchema: GenMessage<ListPackageRuntimesRequest> = /*@__PURE__*/
|
export const ListPackageRuntimesRequestSchema: GenMessage<ListPackageRuntimesRequest> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 11);
|
messageDesc(file_quixos_orch, 13);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.ListPackageRuntimesResponse
|
* @generated from message quixos.orch.ListPackageRuntimesResponse
|
||||||
@@ -308,7 +370,7 @@ export type ListPackageRuntimesResponse = Message<"quixos.orch.ListPackageRuntim
|
|||||||
* Use `create(ListPackageRuntimesResponseSchema)` to create a new message.
|
* Use `create(ListPackageRuntimesResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListPackageRuntimesResponseSchema: GenMessage<ListPackageRuntimesResponse> = /*@__PURE__*/
|
export const ListPackageRuntimesResponseSchema: GenMessage<ListPackageRuntimesResponse> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 12);
|
messageDesc(file_quixos_orch, 14);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.ListActivationsResponse
|
* @generated from message quixos.orch.ListActivationsResponse
|
||||||
@@ -325,7 +387,7 @@ export type ListActivationsResponse = Message<"quixos.orch.ListActivationsRespon
|
|||||||
* Use `create(ListActivationsResponseSchema)` to create a new message.
|
* Use `create(ListActivationsResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ListActivationsResponseSchema: GenMessage<ListActivationsResponse> = /*@__PURE__*/
|
export const ListActivationsResponseSchema: GenMessage<ListActivationsResponse> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 13);
|
messageDesc(file_quixos_orch, 15);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.CloseActivationRequest
|
* @generated from message quixos.orch.CloseActivationRequest
|
||||||
@@ -347,7 +409,7 @@ export type CloseActivationRequest = Message<"quixos.orch.CloseActivationRequest
|
|||||||
* Use `create(CloseActivationRequestSchema)` to create a new message.
|
* Use `create(CloseActivationRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const CloseActivationRequestSchema: GenMessage<CloseActivationRequest> = /*@__PURE__*/
|
export const CloseActivationRequestSchema: GenMessage<CloseActivationRequest> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 14);
|
messageDesc(file_quixos_orch, 16);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.CloseActivationResponse
|
* @generated from message quixos.orch.CloseActivationResponse
|
||||||
@@ -364,7 +426,7 @@ export type CloseActivationResponse = Message<"quixos.orch.CloseActivationRespon
|
|||||||
* Use `create(CloseActivationResponseSchema)` to create a new message.
|
* Use `create(CloseActivationResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const CloseActivationResponseSchema: GenMessage<CloseActivationResponse> = /*@__PURE__*/
|
export const CloseActivationResponseSchema: GenMessage<CloseActivationResponse> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 15);
|
messageDesc(file_quixos_orch, 17);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.Activation
|
* @generated from message quixos.orch.Activation
|
||||||
@@ -426,7 +488,7 @@ export type Activation = Message<"quixos.orch.Activation"> & {
|
|||||||
* Use `create(ActivationSchema)` to create a new message.
|
* Use `create(ActivationSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const ActivationSchema: GenMessage<Activation> = /*@__PURE__*/
|
export const ActivationSchema: GenMessage<Activation> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 16);
|
messageDesc(file_quixos_orch, 18);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.orch.PackageRuntimeStatus
|
* @generated from message quixos.orch.PackageRuntimeStatus
|
||||||
@@ -498,7 +560,7 @@ export type PackageRuntimeStatus = Message<"quixos.orch.PackageRuntimeStatus"> &
|
|||||||
* Use `create(PackageRuntimeStatusSchema)` to create a new message.
|
* Use `create(PackageRuntimeStatusSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const PackageRuntimeStatusSchema: GenMessage<PackageRuntimeStatus> = /*@__PURE__*/
|
export const PackageRuntimeStatusSchema: GenMessage<PackageRuntimeStatus> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_orch, 17);
|
messageDesc(file_quixos_orch, 19);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from service quixos.orch.OrchestratorRuntime
|
* @generated from service quixos.orch.OrchestratorRuntime
|
||||||
@@ -528,6 +590,14 @@ export const OrchestratorRuntime: GenService<{
|
|||||||
input: typeof ConstructObjectRequestSchema;
|
input: typeof ConstructObjectRequestSchema;
|
||||||
output: typeof ConstructObjectResponseSchema;
|
output: typeof ConstructObjectResponseSchema;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @generated from rpc quixos.orch.OrchestratorRuntime.ResolveOrConstructRelatedObject
|
||||||
|
*/
|
||||||
|
resolveOrConstructRelatedObject: {
|
||||||
|
methodKind: "unary";
|
||||||
|
input: typeof ResolveOrConstructRelatedObjectRequestSchema;
|
||||||
|
output: typeof ResolveOrConstructRelatedObjectResponseSchema;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* @generated from rpc quixos.orch.OrchestratorRuntime.GetWorkspace
|
* @generated from rpc quixos.orch.OrchestratorRuntime.GetWorkspace
|
||||||
*/
|
*/
|
||||||
|
|||||||
+11
-3
@@ -10,7 +10,7 @@ import type { Message } from "@bufbuild/protobuf";
|
|||||||
* Describes the file quixos/refs.proto.
|
* Describes the file quixos/refs.proto.
|
||||||
*/
|
*/
|
||||||
export const file_quixos_refs: GenFile = /*@__PURE__*/
|
export const file_quixos_refs: GenFile = /*@__PURE__*/
|
||||||
fileDesc("ChFxdWl4b3MvcmVmcy5wcm90bxIGcXVpeG9zIkQKDUNhcGFiaWxpdHlSZWYSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAEgASgJEhQKDG9wZXJhdGlvbl9pZBgCIAEoCSJCChBQYWNrYWdlRXhwb3J0UmVmEhsKE3BhY2thZ2VfcmV2aXNpb25faWQYASABKAkSEQoJZXhwb3J0X2lkGAIgASgJIroBChJJbmplY3RlZERlcGVuZGVuY3kSDwoHcG9ydF9pZBgBIAEoCRIXCg1zdGF0ZV9zbG90X2lkGAIgASgJSAASJgoEZWRnZRgDIAEoCzIWLnF1aXhvcy5FZGdlRGVwZW5kZW5jeUgAEigKHnJlY2VpdmVyX2ludGVyZmFjZV9yZXZpc2lvbl9pZBgEIAEoCUgAEh0KE2NvbnN0cnVjdG9yX2F0b21faWQYBSABKAlIAEIJCgdiaW5kaW5nIj0KDkVkZ2VEZXBlbmRlbmN5EhQKDGVkZ2VfdHlwZV9pZBgBIAEoCRIVCg1wcm9qZWN0aW9uX2lkGAIgASgJYgZwcm90bzM");
|
fileDesc("ChFxdWl4b3MvcmVmcy5wcm90bxIGcXVpeG9zIkQKDUNhcGFiaWxpdHlSZWYSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAEgASgJEhQKDG9wZXJhdGlvbl9pZBgCIAEoCSJCChBQYWNrYWdlRXhwb3J0UmVmEhsKE3BhY2thZ2VfcmV2aXNpb25faWQYASABKAkSEQoJZXhwb3J0X2lkGAIgASgJIsQBChJJbmplY3RlZERlcGVuZGVuY3kSDwoHcG9ydF9pZBgBIAEoCRIXCg1zdGF0ZV9zbG90X2lkGAIgASgJSAASJgoEZWRnZRgDIAEoCzIWLnF1aXhvcy5FZGdlRGVwZW5kZW5jeUgAEh8KFWludGVyZmFjZV9yZXZpc2lvbl9pZBgEIAEoCUgAEh0KE2NvbnN0cnVjdG9yX2F0b21faWQYBSABKAlIABIRCglvYmplY3RfaWQYBiABKAlCCQoHYmluZGluZyI9Cg5FZGdlRGVwZW5kZW5jeRIUCgxlZGdlX3R5cGVfaWQYASABKAkSFQoNcHJvamVjdGlvbl9pZBgCIAEoCWIGcHJvdG8z");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.CapabilityRef
|
* @generated from message quixos.CapabilityRef
|
||||||
@@ -82,10 +82,10 @@ export type InjectedDependency = Message<"quixos.InjectedDependency"> & {
|
|||||||
case: "edge";
|
case: "edge";
|
||||||
} | {
|
} | {
|
||||||
/**
|
/**
|
||||||
* @generated from field: string receiver_interface_revision_id = 4;
|
* @generated from field: string interface_revision_id = 4;
|
||||||
*/
|
*/
|
||||||
value: string;
|
value: string;
|
||||||
case: "receiverInterfaceRevisionId";
|
case: "interfaceRevisionId";
|
||||||
} | {
|
} | {
|
||||||
/**
|
/**
|
||||||
* @generated from field: string constructor_atom_id = 5;
|
* @generated from field: string constructor_atom_id = 5;
|
||||||
@@ -93,6 +93,14 @@ export type InjectedDependency = Message<"quixos.InjectedDependency"> & {
|
|||||||
value: string;
|
value: string;
|
||||||
case: "constructorAtomId";
|
case: "constructorAtomId";
|
||||||
} | { case: undefined; value?: undefined };
|
} | { case: undefined; value?: undefined };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defaults to the invocation receiver. A checked dependency traversal can
|
||||||
|
* select a related object explicitly before the package runtime starts.
|
||||||
|
*
|
||||||
|
* @generated from field: string object_id = 6;
|
||||||
|
*/
|
||||||
|
objectId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+142
-6
@@ -14,7 +14,7 @@ import type { Message } from "@bufbuild/protobuf";
|
|||||||
* Describes the file quixos/runtime.proto.
|
* Describes the file quixos/runtime.proto.
|
||||||
*/
|
*/
|
||||||
export const file_quixos_runtime: GenFile = /*@__PURE__*/
|
export const file_quixos_runtime: GenFile = /*@__PURE__*/
|
||||||
fileDesc("ChRxdWl4b3MvcnVudGltZS5wcm90bxIOcXVpeG9zLnJ1bnRpbWUiMQoQSGFuZHNoYWtlUmVxdWVzdBIdChVvcmNoX3Byb3RvY29sX3ZlcnNpb24YASABKAkiZgoRSGFuZHNoYWtlUmVzcG9uc2USGwoTcGFja2FnZV9yZXZpc2lvbl9pZBgBIAEoCRIgChhydW50aW1lX3Byb3RvY29sX3ZlcnNpb24YAiABKAkSEgoKZXhwb3J0X2lkcxgDIAMoCSKLAgoNSW52b2tlUmVxdWVzdBIVCg1pbnZvY2F0aW9uX2lkGAEgASgJEigKBmV4cG9ydBgCIAEoCzIYLnF1aXhvcy5QYWNrYWdlRXhwb3J0UmVmEhEKCW9iamVjdF9pZBgDIAEoCRI3CgVpbnB1dBgEIAMoCzIoLnF1aXhvcy5ydW50aW1lLkludm9rZVJlcXVlc3QuSW5wdXRFbnRyeRIwCgxkZXBlbmRlbmNpZXMYBSADKAsyGi5xdWl4b3MuSW5qZWN0ZWREZXBlbmRlbmN5GjsKCklucHV0RW50cnkSCwoDa2V5GAEgASgJEhwKBXZhbHVlGAIgASgLMg0uY2FtaW5vLlZhbHVlOgI4ASJKCg5JbnZva2VSZXNwb25zZRIKCgJvaxgBIAEoCBIdCgZyZXN1bHQYAiABKAsyDS5jYW1pbm8uVmFsdWUSDQoFZXJyb3IYAyABKAkiiQIKDFdhdGNoUmVxdWVzdBIVCg1pbnZvY2F0aW9uX2lkGAEgASgJEigKBmV4cG9ydBgCIAEoCzIYLnF1aXhvcy5QYWNrYWdlRXhwb3J0UmVmEhEKCW9iamVjdF9pZBgDIAEoCRI2CgVpbnB1dBgEIAMoCzInLnF1aXhvcy5ydW50aW1lLldhdGNoUmVxdWVzdC5JbnB1dEVudHJ5EjAKDGRlcGVuZGVuY2llcxgFIAMoCzIaLnF1aXhvcy5JbmplY3RlZERlcGVuZGVuY3kaOwoKSW5wdXRFbnRyeRILCgNrZXkYASABKAkSHAoFdmFsdWUYAiABKAsyDS5jYW1pbm8uVmFsdWU6AjgBImIKEURlcml2ZWREZXBlbmRlbmN5EgwKBGtpbmQYASABKAkSEQoJb2JqZWN0X2lkGAIgASgJEhUKDWF0dGFjaG1lbnRfaWQYAyABKAkSFQoNcHJvamVjdGlvbl9pZBgEIAEoCSKVAQoKV2F0Y2hFdmVudBIQCgh3YXRjaF9pZBgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLmNhbWluby5WYWx1ZRI3CgxkZXBlbmRlbmNpZXMYAyADKAsyIS5xdWl4b3MucnVudGltZS5EZXJpdmVkRGVwZW5kZW5jeRINCgVlcnJvchgEIAEoCRIPCgdpbml0aWFsGAUgASgIMvABCg5QYWNrYWdlUnVudGltZRJQCglIYW5kc2hha2USIC5xdWl4b3MucnVudGltZS5IYW5kc2hha2VSZXF1ZXN0GiEucXVpeG9zLnJ1bnRpbWUuSGFuZHNoYWtlUmVzcG9uc2USRwoGSW52b2tlEh0ucXVpeG9zLnJ1bnRpbWUuSW52b2tlUmVxdWVzdBoeLnF1aXhvcy5ydW50aW1lLkludm9rZVJlc3BvbnNlEkMKBVdhdGNoEhwucXVpeG9zLnJ1bnRpbWUuV2F0Y2hSZXF1ZXN0GhoucXVpeG9zLnJ1bnRpbWUuV2F0Y2hFdmVudDABYgZwcm90bzM", [file_camino_api, file_quixos_refs]);
|
fileDesc("ChRxdWl4b3MvcnVudGltZS5wcm90bxIOcXVpeG9zLnJ1bnRpbWUiQAoQSGFuZHNoYWtlUmVxdWVzdBIdChVvcmNoX3Byb3RvY29sX3ZlcnNpb24YASABKAkSDQoFbm9uY2UYAiABKAkirwEKEUhhbmRzaGFrZVJlc3BvbnNlEhsKE3BhY2thZ2VfcmV2aXNpb25faWQYASABKAkSIAoYcnVudGltZV9wcm90b2NvbF92ZXJzaW9uGAIgASgJEhIKCmV4cG9ydF9pZHMYAyADKAkSEwoLaW5zdGFuY2VfaWQYBCABKAkSHAoUYXV0aGVudGljYXRpb25fcHJvb2YYBSABKAkSFAoMY2FwYWJpbGl0aWVzGAYgAygJIpoBChFJbnZvY2F0aW9uQ29udGV4dBIXCg93b3Jrc3BhY2VfZXBvY2gYASABKAkSEwoLaW5zdGFuY2VfaWQYAiABKAkSFgoOYmluZGluZ19kaWdlc3QYAyABKAkSDQoFZ3JhbnQYBCABKAkSEgoKc2Vzc2lvbl9pZBgFIAEoCRIcChRvd25lcl9jb25mb3JtYW5jZV9pZBgGIAEoCSIxChhJbnZvY2F0aW9uQ29udHJvbFJlcXVlc3QSFQoNaW52b2NhdGlvbl9pZBgBIAEoCSI4ChBJbnZvY2F0aW9uU3RhdHVzEhUKDWludm9jYXRpb25faWQYASABKAkSDQoFc3RhdGUYAiABKAkivwIKDUludm9rZVJlcXVlc3QSFQoNaW52b2NhdGlvbl9pZBgBIAEoCRIoCgZleHBvcnQYAiABKAsyGC5xdWl4b3MuUGFja2FnZUV4cG9ydFJlZhIRCglvYmplY3RfaWQYAyABKAkSNwoFaW5wdXQYBCADKAsyKC5xdWl4b3MucnVudGltZS5JbnZva2VSZXF1ZXN0LklucHV0RW50cnkSMAoMZGVwZW5kZW5jaWVzGAUgAygLMhoucXVpeG9zLkluamVjdGVkRGVwZW5kZW5jeRIyCgdjb250ZXh0GAYgASgLMiEucXVpeG9zLnJ1bnRpbWUuSW52b2NhdGlvbkNvbnRleHQaOwoKSW5wdXRFbnRyeRILCgNrZXkYASABKAkSHAoFdmFsdWUYAiABKAsyDS5jYW1pbm8uVmFsdWU6AjgBIoMBCg5JbnZva2VSZXNwb25zZRIKCgJvaxgBIAEoCBIdCgZyZXN1bHQYAiABKAsyDS5jYW1pbm8uVmFsdWUSDQoFZXJyb3IYAyABKAkSNwoMZGVwZW5kZW5jaWVzGAQgAygLMiEucXVpeG9zLnJ1bnRpbWUuRGVyaXZlZERlcGVuZGVuY3kivQIKDFdhdGNoUmVxdWVzdBIVCg1pbnZvY2F0aW9uX2lkGAEgASgJEigKBmV4cG9ydBgCIAEoCzIYLnF1aXhvcy5QYWNrYWdlRXhwb3J0UmVmEhEKCW9iamVjdF9pZBgDIAEoCRI2CgVpbnB1dBgEIAMoCzInLnF1aXhvcy5ydW50aW1lLldhdGNoUmVxdWVzdC5JbnB1dEVudHJ5EjAKDGRlcGVuZGVuY2llcxgFIAMoCzIaLnF1aXhvcy5JbmplY3RlZERlcGVuZGVuY3kSMgoHY29udGV4dBgGIAEoCzIhLnF1aXhvcy5ydW50aW1lLkludm9jYXRpb25Db250ZXh0GjsKCklucHV0RW50cnkSCwoDa2V5GAEgASgJEhwKBXZhbHVlGAIgASgLMg0uY2FtaW5vLlZhbHVlOgI4ASJiChFEZXJpdmVkRGVwZW5kZW5jeRIMCgRraW5kGAEgASgJEhEKCW9iamVjdF9pZBgCIAEoCRIVCg1hdHRhY2htZW50X2lkGAMgASgJEhUKDXByb2plY3Rpb25faWQYBCABKAkilQEKCldhdGNoRXZlbnQSEAoId2F0Y2hfaWQYASABKAkSHAoFdmFsdWUYAiABKAsyDS5jYW1pbm8uVmFsdWUSNwoMZGVwZW5kZW5jaWVzGAMgAygLMiEucXVpeG9zLnJ1bnRpbWUuRGVyaXZlZERlcGVuZGVuY3kSDQoFZXJyb3IYBCABKAkSDwoHaW5pdGlhbBgFIAEoCDKzAwoOUGFja2FnZVJ1bnRpbWUSUAoJSGFuZHNoYWtlEiAucXVpeG9zLnJ1bnRpbWUuSGFuZHNoYWtlUmVxdWVzdBohLnF1aXhvcy5ydW50aW1lLkhhbmRzaGFrZVJlc3BvbnNlEkcKBkludm9rZRIdLnF1aXhvcy5ydW50aW1lLkludm9rZVJlcXVlc3QaHi5xdWl4b3MucnVudGltZS5JbnZva2VSZXNwb25zZRJDCgVXYXRjaBIcLnF1aXhvcy5ydW50aW1lLldhdGNoUmVxdWVzdBoaLnF1aXhvcy5ydW50aW1lLldhdGNoRXZlbnQwARJhChNHZXRJbnZvY2F0aW9uU3RhdHVzEigucXVpeG9zLnJ1bnRpbWUuSW52b2NhdGlvbkNvbnRyb2xSZXF1ZXN0GiAucXVpeG9zLnJ1bnRpbWUuSW52b2NhdGlvblN0YXR1cxJeChBDYW5jZWxJbnZvY2F0aW9uEigucXVpeG9zLnJ1bnRpbWUuSW52b2NhdGlvbkNvbnRyb2xSZXF1ZXN0GiAucXVpeG9zLnJ1bnRpbWUuSW52b2NhdGlvblN0YXR1c2IGcHJvdG8z", [file_camino_api, file_quixos_refs]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.runtime.HandshakeRequest
|
* @generated from message quixos.runtime.HandshakeRequest
|
||||||
@@ -24,6 +24,11 @@ export type HandshakeRequest = Message<"quixos.runtime.HandshakeRequest"> & {
|
|||||||
* @generated from field: string orch_protocol_version = 1;
|
* @generated from field: string orch_protocol_version = 1;
|
||||||
*/
|
*/
|
||||||
orchProtocolVersion: string;
|
orchProtocolVersion: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string nonce = 2;
|
||||||
|
*/
|
||||||
|
nonce: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,6 +56,21 @@ export type HandshakeResponse = Message<"quixos.runtime.HandshakeResponse"> & {
|
|||||||
* @generated from field: repeated string export_ids = 3;
|
* @generated from field: repeated string export_ids = 3;
|
||||||
*/
|
*/
|
||||||
exportIds: string[];
|
exportIds: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string instance_id = 4;
|
||||||
|
*/
|
||||||
|
instanceId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string authentication_proof = 5;
|
||||||
|
*/
|
||||||
|
authenticationProof: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: repeated string capabilities = 6;
|
||||||
|
*/
|
||||||
|
capabilities: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,6 +80,91 @@ export type HandshakeResponse = Message<"quixos.runtime.HandshakeResponse"> & {
|
|||||||
export const HandshakeResponseSchema: GenMessage<HandshakeResponse> = /*@__PURE__*/
|
export const HandshakeResponseSchema: GenMessage<HandshakeResponse> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_runtime, 1);
|
messageDesc(file_quixos_runtime, 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message quixos.runtime.InvocationContext
|
||||||
|
*/
|
||||||
|
export type InvocationContext = Message<"quixos.runtime.InvocationContext"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: string workspace_epoch = 1;
|
||||||
|
*/
|
||||||
|
workspaceEpoch: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string instance_id = 2;
|
||||||
|
*/
|
||||||
|
instanceId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string binding_digest = 3;
|
||||||
|
*/
|
||||||
|
bindingDigest: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string grant = 4;
|
||||||
|
*/
|
||||||
|
grant: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: string session_id = 5;
|
||||||
|
*/
|
||||||
|
sessionId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Host-selected owner; packages must not invent workspace-local ownership.
|
||||||
|
*
|
||||||
|
* @generated from field: string owner_conformance_id = 6;
|
||||||
|
*/
|
||||||
|
ownerConformanceId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.runtime.InvocationContext.
|
||||||
|
* Use `create(InvocationContextSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export const InvocationContextSchema: GenMessage<InvocationContext> = /*@__PURE__*/
|
||||||
|
messageDesc(file_quixos_runtime, 2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message quixos.runtime.InvocationControlRequest
|
||||||
|
*/
|
||||||
|
export type InvocationControlRequest = Message<"quixos.runtime.InvocationControlRequest"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: string invocation_id = 1;
|
||||||
|
*/
|
||||||
|
invocationId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.runtime.InvocationControlRequest.
|
||||||
|
* Use `create(InvocationControlRequestSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export const InvocationControlRequestSchema: GenMessage<InvocationControlRequest> = /*@__PURE__*/
|
||||||
|
messageDesc(file_quixos_runtime, 3);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from message quixos.runtime.InvocationStatus
|
||||||
|
*/
|
||||||
|
export type InvocationStatus = Message<"quixos.runtime.InvocationStatus"> & {
|
||||||
|
/**
|
||||||
|
* @generated from field: string invocation_id = 1;
|
||||||
|
*/
|
||||||
|
invocationId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unknown, running, cancellation-requested, completed, failed
|
||||||
|
*
|
||||||
|
* @generated from field: string state = 2;
|
||||||
|
*/
|
||||||
|
state: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the message quixos.runtime.InvocationStatus.
|
||||||
|
* Use `create(InvocationStatusSchema)` to create a new message.
|
||||||
|
*/
|
||||||
|
export const InvocationStatusSchema: GenMessage<InvocationStatus> = /*@__PURE__*/
|
||||||
|
messageDesc(file_quixos_runtime, 4);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.runtime.InvokeRequest
|
* @generated from message quixos.runtime.InvokeRequest
|
||||||
*/
|
*/
|
||||||
@@ -88,6 +193,11 @@ export type InvokeRequest = Message<"quixos.runtime.InvokeRequest"> & {
|
|||||||
* @generated from field: repeated quixos.InjectedDependency dependencies = 5;
|
* @generated from field: repeated quixos.InjectedDependency dependencies = 5;
|
||||||
*/
|
*/
|
||||||
dependencies: InjectedDependency[];
|
dependencies: InjectedDependency[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: quixos.runtime.InvocationContext context = 6;
|
||||||
|
*/
|
||||||
|
context?: InvocationContext | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,7 +205,7 @@ export type InvokeRequest = Message<"quixos.runtime.InvokeRequest"> & {
|
|||||||
* Use `create(InvokeRequestSchema)` to create a new message.
|
* Use `create(InvokeRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const InvokeRequestSchema: GenMessage<InvokeRequest> = /*@__PURE__*/
|
export const InvokeRequestSchema: GenMessage<InvokeRequest> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_runtime, 2);
|
messageDesc(file_quixos_runtime, 5);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.runtime.InvokeResponse
|
* @generated from message quixos.runtime.InvokeResponse
|
||||||
@@ -115,6 +225,11 @@ export type InvokeResponse = Message<"quixos.runtime.InvokeResponse"> & {
|
|||||||
* @generated from field: string error = 3;
|
* @generated from field: string error = 3;
|
||||||
*/
|
*/
|
||||||
error: string;
|
error: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: repeated quixos.runtime.DerivedDependency dependencies = 4;
|
||||||
|
*/
|
||||||
|
dependencies: DerivedDependency[];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -122,7 +237,7 @@ export type InvokeResponse = Message<"quixos.runtime.InvokeResponse"> & {
|
|||||||
* Use `create(InvokeResponseSchema)` to create a new message.
|
* Use `create(InvokeResponseSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const InvokeResponseSchema: GenMessage<InvokeResponse> = /*@__PURE__*/
|
export const InvokeResponseSchema: GenMessage<InvokeResponse> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_runtime, 3);
|
messageDesc(file_quixos_runtime, 6);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.runtime.WatchRequest
|
* @generated from message quixos.runtime.WatchRequest
|
||||||
@@ -152,6 +267,11 @@ export type WatchRequest = Message<"quixos.runtime.WatchRequest"> & {
|
|||||||
* @generated from field: repeated quixos.InjectedDependency dependencies = 5;
|
* @generated from field: repeated quixos.InjectedDependency dependencies = 5;
|
||||||
*/
|
*/
|
||||||
dependencies: InjectedDependency[];
|
dependencies: InjectedDependency[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: quixos.runtime.InvocationContext context = 6;
|
||||||
|
*/
|
||||||
|
context?: InvocationContext | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,7 +279,7 @@ export type WatchRequest = Message<"quixos.runtime.WatchRequest"> & {
|
|||||||
* Use `create(WatchRequestSchema)` to create a new message.
|
* Use `create(WatchRequestSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const WatchRequestSchema: GenMessage<WatchRequest> = /*@__PURE__*/
|
export const WatchRequestSchema: GenMessage<WatchRequest> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_runtime, 4);
|
messageDesc(file_quixos_runtime, 7);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.runtime.DerivedDependency
|
* @generated from message quixos.runtime.DerivedDependency
|
||||||
@@ -191,7 +311,7 @@ export type DerivedDependency = Message<"quixos.runtime.DerivedDependency"> & {
|
|||||||
* Use `create(DerivedDependencySchema)` to create a new message.
|
* Use `create(DerivedDependencySchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const DerivedDependencySchema: GenMessage<DerivedDependency> = /*@__PURE__*/
|
export const DerivedDependencySchema: GenMessage<DerivedDependency> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_runtime, 5);
|
messageDesc(file_quixos_runtime, 8);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from message quixos.runtime.WatchEvent
|
* @generated from message quixos.runtime.WatchEvent
|
||||||
@@ -228,7 +348,7 @@ export type WatchEvent = Message<"quixos.runtime.WatchEvent"> & {
|
|||||||
* Use `create(WatchEventSchema)` to create a new message.
|
* Use `create(WatchEventSchema)` to create a new message.
|
||||||
*/
|
*/
|
||||||
export const WatchEventSchema: GenMessage<WatchEvent> = /*@__PURE__*/
|
export const WatchEventSchema: GenMessage<WatchEvent> = /*@__PURE__*/
|
||||||
messageDesc(file_quixos_runtime, 6);
|
messageDesc(file_quixos_runtime, 9);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @generated from service quixos.runtime.PackageRuntime
|
* @generated from service quixos.runtime.PackageRuntime
|
||||||
@@ -258,6 +378,22 @@ export const PackageRuntime: GenService<{
|
|||||||
input: typeof WatchRequestSchema;
|
input: typeof WatchRequestSchema;
|
||||||
output: typeof WatchEventSchema;
|
output: typeof WatchEventSchema;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @generated from rpc quixos.runtime.PackageRuntime.GetInvocationStatus
|
||||||
|
*/
|
||||||
|
getInvocationStatus: {
|
||||||
|
methodKind: "unary";
|
||||||
|
input: typeof InvocationControlRequestSchema;
|
||||||
|
output: typeof InvocationStatusSchema;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @generated from rpc quixos.runtime.PackageRuntime.CancelInvocation
|
||||||
|
*/
|
||||||
|
cancelInvocation: {
|
||||||
|
methodKind: "unary";
|
||||||
|
input: typeof InvocationControlRequestSchema;
|
||||||
|
output: typeof InvocationStatusSchema;
|
||||||
|
},
|
||||||
}> = /*@__PURE__*/
|
}> = /*@__PURE__*/
|
||||||
serviceDesc(file_quixos_runtime, 0);
|
serviceDesc(file_quixos_runtime, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/** Opaque runtime identity. The wire codec, never ordinary package state, owns
|
||||||
|
* the raw ID. These handles do not themselves confer authority or a lease. */
|
||||||
|
const identities = new WeakMap<object, string>();
|
||||||
|
declare const referenceBrand: unique symbol;
|
||||||
|
export interface QxObjectRef<Identity extends string = string> {
|
||||||
|
readonly [referenceBrand]: {readonly [K in Identity]: true};
|
||||||
|
equals(other: QxObjectRef<string>): boolean;
|
||||||
|
}
|
||||||
|
class Reference {
|
||||||
|
constructor(id: string) { identities.set(this, id); Object.freeze(this); }
|
||||||
|
equals(other: unknown) { return isObjectReference(other) && identities.get(this) === identities.get(other); }
|
||||||
|
toJSON(): never { throw new Error("Object references cannot be serialized into ordinary data"); }
|
||||||
|
toString(): never { throw new Error("Object references cannot be coerced to strings"); }
|
||||||
|
[Symbol.toPrimitive](): never { throw new Error("Object references cannot be coerced to scalar values"); }
|
||||||
|
}
|
||||||
|
export const isObjectReference = (value: unknown): value is QxObjectRef =>
|
||||||
|
typeof value === "object" && value !== null && identities.has(value);
|
||||||
|
|
||||||
|
/** Internal transport boundary; intentionally not exported from the SDK entry. */
|
||||||
|
export const referenceFromWire = (id: string): QxObjectRef => {
|
||||||
|
if (typeof id !== "string" || !id) throw new Error("Missing object reference identity");
|
||||||
|
return new Reference(id) as unknown as QxObjectRef;
|
||||||
|
};
|
||||||
|
export const referenceToWire = (value: unknown): string => {
|
||||||
|
if (!isObjectReference(value)) throw new Error("Expected an opaque object reference, not a raw ID");
|
||||||
|
return identities.get(value)!;
|
||||||
|
};
|
||||||
|
export const assertReferenceFree = (value: unknown, seen = new Set<object>()): void => {
|
||||||
|
if (!value || typeof value !== "object") return;
|
||||||
|
if (isObjectReference(value)) throw new Error("Managed references belong in declared RPC references or graph relationships, not ordinary state/messages");
|
||||||
|
if (seen.has(value)) throw new Error("Cyclic ordinary data");
|
||||||
|
seen.add(value);
|
||||||
|
if (!(value instanceof Uint8Array)) for (const child of Object.values(value)) assertReferenceFree(child, seen);
|
||||||
|
seen.delete(value);
|
||||||
|
};
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import type {QxObjectRef} from "./references.js";
|
||||||
|
import type {RelationshipCollection, RelationshipEntry} from "./index.js";
|
||||||
|
type Key = string | boolean | bigint;
|
||||||
|
type Port<T extends QxObjectRef> = {collection(): Promise<RelationshipCollection<T>>; replace(entries: RelationshipEntry<T>[], expectedRevision: bigint): Promise<RelationshipCollection<T>>};
|
||||||
|
const checked = async <T extends QxObjectRef>(port: Port<T>, revision: bigint) => {
|
||||||
|
const snapshot = await port.collection();
|
||||||
|
if (snapshot.revision !== revision) throw new Error("STALE_COLLECTION_REVISION");
|
||||||
|
return snapshot;
|
||||||
|
};
|
||||||
|
/** Helpers never retry a failed CAS or silently overwrite concurrent edits. */
|
||||||
|
export const relationshipMap = <T extends QxObjectRef, K extends Key = Key>(port: Port<T>) => ({
|
||||||
|
read: () => port.collection(),
|
||||||
|
async get(key: K) {const snapshot = await port.collection(); return {revision: snapshot.revision, value: snapshot.entries.find((entry) => entry.key === key)?.target};},
|
||||||
|
async set(key: K, target: T, expectedRevision: bigint) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
const entries = snapshot.entries.filter((entry) => entry.key !== key);
|
||||||
|
const existing = snapshot.entries.find((entry) => entry.key === key && entry.target.equals(target));
|
||||||
|
entries.push(existing ?? {key, target});
|
||||||
|
return port.replace(entries, expectedRevision);
|
||||||
|
},
|
||||||
|
async delete(key: K, expectedRevision: bigint) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
return port.replace(snapshot.entries.filter((entry) => entry.key !== key), expectedRevision);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export const relationshipList = <T extends QxObjectRef>(port: Port<T>) => ({
|
||||||
|
read: () => port.collection(),
|
||||||
|
async insert(index: number, target: T, expectedRevision: bigint) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
if (!Number.isSafeInteger(index) || index < 0 || index > snapshot.entries.length) throw new Error("List index out of bounds");
|
||||||
|
snapshot.entries.splice(index, 0, {target});
|
||||||
|
return port.replace(snapshot.entries, expectedRevision);
|
||||||
|
},
|
||||||
|
async move(edgeId: string, index: number, expectedRevision: bigint) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
const prior = snapshot.entries.findIndex((entry) => entry.edgeId === edgeId);
|
||||||
|
if (prior < 0 || !Number.isSafeInteger(index) || index < 0 || index >= snapshot.entries.length) throw new Error("Unknown list entry or invalid index");
|
||||||
|
const [entry] = snapshot.entries.splice(prior, 1);
|
||||||
|
snapshot.entries.splice(index, 0, entry);
|
||||||
|
return port.replace(snapshot.entries, expectedRevision);
|
||||||
|
},
|
||||||
|
async delete(edgeId: string, expectedRevision: bigint) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
if (!snapshot.entries.some((entry) => entry.edgeId === edgeId)) throw new Error("Unknown list entry");
|
||||||
|
return port.replace(snapshot.entries.filter((entry) => entry.edgeId !== edgeId), expectedRevision);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export const relationshipSet = <T extends QxObjectRef>(port: Port<T>) => ({
|
||||||
|
read: () => port.collection(),
|
||||||
|
async add(target: T, expectedRevision: bigint) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
if (snapshot.entries.some((entry) => entry.target.equals(target))) return snapshot;
|
||||||
|
return port.replace([...snapshot.entries, {target}], expectedRevision);
|
||||||
|
},
|
||||||
|
async delete(target: T, expectedRevision: bigint) {
|
||||||
|
const snapshot = await checked(port, expectedRevision);
|
||||||
|
return port.replace(snapshot.entries.filter((entry) => !entry.target.equals(target)), expectedRevision);
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
import assert from "node:assert/strict";
|
||||||
|
import test from "node:test";
|
||||||
|
import { referenceFromWire } from "../dist/references.js";
|
||||||
|
import { bindQxHandler, decodeQxValue, encodeQxValue, jsToProtoValue, liveValue, protoValueToJs, opaqueReactPropsBinding } from "../dist/index.js";
|
||||||
|
const scalar = (name) => ({ kind: "scalar", name });
|
||||||
|
const unit = { kind: "builtin", name: "unit" };
|
||||||
|
test("opaque React props retain managed references while ordinary messages remain closed", () => {
|
||||||
|
const descriptorId = "org.quixos.web-studio.ReactProps";
|
||||||
|
const reference = referenceFromWire("obj:task");
|
||||||
|
const type = {kind: "message", descriptorId};
|
||||||
|
const messages = {[descriptorId]: opaqueReactPropsBinding};
|
||||||
|
const decoded = decodeQxValue(type, encodeQxValue(type, {subject: reference, title: "Task"}, messages), messages);
|
||||||
|
assert.ok(decoded.subject.equals(reference));
|
||||||
|
assert.equal(decoded.title, "Task");
|
||||||
|
assert.throws(() => opaqueReactPropsBinding.encode(null), /object/);
|
||||||
|
assert.throws(() => opaqueReactPropsBinding.encode([]), /object/);
|
||||||
|
assert.throws(() => encodeQxValue({kind: "message", descriptorId: "Ordinary"}, {subject: reference},
|
||||||
|
{Ordinary: opaqueReactPropsBinding}), /Managed references/);
|
||||||
|
});
|
||||||
|
test("declared record inputs preserve opaque references without opening message codecs", async () => {
|
||||||
|
const target = referenceFromWire("obj:board");
|
||||||
|
const type = {kind: "record", fields: {
|
||||||
|
target: {kind: "object-ref", expectation: {kind: "atom", atomId: "board"}},
|
||||||
|
x: scalar("double"), note: {kind: "optional", value: scalar("string")},
|
||||||
|
}};
|
||||||
|
const encoded = encodeQxValue(type, {target, x: 12}, {});
|
||||||
|
const decoded = decodeQxValue(type, encoded, {});
|
||||||
|
assert.ok(decoded.target.equals(target));
|
||||||
|
assert.equal(decoded.x, 12);
|
||||||
|
assert.equal(decoded.note, null);
|
||||||
|
assert.throws(() => JSON.stringify(decoded), /cannot be serialized/);
|
||||||
|
assert.throws(() => encodeQxValue(type, {target, x: 12, hidden: target}, {}), /Unexpected/);
|
||||||
|
assert.throws(() => encodeQxValue(type, {x: 12}, {}), /Missing/);
|
||||||
|
assert.throws(() => encodeQxValue(type, {target: "obj:board", x: 12}, {}), /opaque object reference/);
|
||||||
|
const handler = bindQxHandler({inputType: type, outputType: unit, ports: {}}, async (context) => {
|
||||||
|
assert.ok(context.input.target.equals(target));
|
||||||
|
assert.equal(context.input.x, 12);
|
||||||
|
}, {});
|
||||||
|
await handler({objectId: target, inputProto: encoded.kind.value.fields});
|
||||||
|
});
|
||||||
|
test("typed sessions rebind ports and cancellation to each acquired invocation", async () => {
|
||||||
|
const first = new AbortController(), second = new AbortController();
|
||||||
|
let closed = false;
|
||||||
|
const context = (value, signal) => ({objectId: referenceFromWire("obj:owner"), inputProto: {}, signal,
|
||||||
|
state: () => ({live: async () => liveValue(jsToProtoValue(value))})});
|
||||||
|
const raw = {...context(1n, first.signal), openSession: async () => ({id: "session:test",
|
||||||
|
run: (work) => work(context(2n, second.signal)), close: async () => {closed = true;}})};
|
||||||
|
const handler = bindQxHandler({inputType: unit, outputType: unit, ports: {counter: {kind: "state", id: "counter", valueType: scalar("int64"), primitives: ["read"]}}}, async (bound) => {
|
||||||
|
assert.equal(bound.signal, first.signal);
|
||||||
|
const session = await bound.openSession();
|
||||||
|
await session.run(async (next) => {
|
||||||
|
assert.equal(next.signal, second.signal);
|
||||||
|
assert.equal(await next.ports.counter.get(), 2n);
|
||||||
|
assert.equal(next.openSession, undefined);
|
||||||
|
});
|
||||||
|
await session.close();
|
||||||
|
}, {});
|
||||||
|
await handler(raw);
|
||||||
|
assert.equal(closed, true);
|
||||||
|
});
|
||||||
|
test("binding codecs round trip nested bytes, 64-bit integers, nulls, and references", () => {
|
||||||
|
const values = [[scalar("int64"), -(2n ** 63n)], [scalar("uint64"), 2n ** 64n - 1n],
|
||||||
|
[scalar("bytes"), new Uint8Array([0, 255])],
|
||||||
|
[{ kind: "list", value: { kind: "optional", value: scalar("int64") } }, [null, 2n ** 60n]],
|
||||||
|
[{ kind: "object-ref", expectation: { kind: "atom", atomId: "thing" } }, referenceFromWire("obj:thing")]];
|
||||||
|
for (const [type, value] of values) assert.deepEqual(decodeQxValue(type, encodeQxValue(type, value, {}), {}), value);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("opaque references pass declared RPC boundaries but cannot enter ordinary data", () => {
|
||||||
|
const reference = referenceFromWire("obj:thing");
|
||||||
|
const type = {kind: "object-ref", expectation: {kind: "atom", atomId: "thing"}};
|
||||||
|
const roundtrip = decodeQxValue(type, encodeQxValue(type, reference, {}), {});
|
||||||
|
assert.equal(reference.equals(roundtrip), true);
|
||||||
|
assert.equal(reference.equals(referenceFromWire("obj:other")), false);
|
||||||
|
assert.throws(() => JSON.stringify({nested: [reference]}), /cannot be serialized/);
|
||||||
|
assert.throws(() => String(reference), /cannot be coerced/);
|
||||||
|
assert.throws(() => encodeQxValue(type, "obj:thing", {}), /opaque/);
|
||||||
|
assert.throws(() => encodeQxValue(scalar("string"), reference, {}), /Managed references/);
|
||||||
|
const message = {kind: "message", descriptorId: "Payload"};
|
||||||
|
assert.throws(() => encodeQxValue(message, {nested: reference}, {Payload: {encode: jsToProtoValue}}), /Managed references/);
|
||||||
|
assert.throws(() => encodeQxValue(message, {}, {Payload: {encode: () => jsToProtoValue(reference)}}), /Managed references/);
|
||||||
|
assert.throws(() => decodeQxValue(message, jsToProtoValue(reference), {Payload: {decode: () => ({})}}), /Managed references/);
|
||||||
|
});
|
||||||
|
test("typed state and interface ports preserve declared values and exact operation IDs", async () => {
|
||||||
|
const spec = { inputType: scalar("int64"), outputType: scalar("bytes"), ports: {
|
||||||
|
data: { kind: "state", id: "state-id", valueType: scalar("int64"), primitives: ["read", "write"] },
|
||||||
|
reader: { kind: "interface", id: "interface-id", operations: { "payload.get": { id: "get-id", inputType: unit, outputType: scalar("bytes") } } },
|
||||||
|
} };
|
||||||
|
let written;
|
||||||
|
const handler = bindQxHandler(spec, async ({ input, ports }) => {
|
||||||
|
assert.equal(input, 2n ** 60n);
|
||||||
|
assert.equal(await ports.data.get(), 9n);
|
||||||
|
assert.deepEqual((await ports.data.live()).$quixosValue, jsToProtoValue(9n));
|
||||||
|
assert.ok(ports.reader.objectId.equals(referenceFromWire("obj:reader")));
|
||||||
|
assert.deepEqual((await ports.reader.live["payload.get"]()).$quixosValue, jsToProtoValue(new Uint8Array([7])));
|
||||||
|
await ports.data.set(input);
|
||||||
|
return ports.reader["payload.get"]();
|
||||||
|
}, {});
|
||||||
|
const result = await handler({ inputProto: { value: jsToProtoValue(2n ** 60n) }, objectId: "obj",
|
||||||
|
state: (id) => { assert.equal(id, "state-id"); return {
|
||||||
|
live: async () => liveValue(jsToProtoValue(9n)), set: async (value) => { written = value; },
|
||||||
|
}; },
|
||||||
|
interface: (id) => { assert.equal(id, "interface-id"); return { objectId: referenceFromWire("obj:reader"), live: async (operation, input) => {
|
||||||
|
assert.equal(operation, "get-id"); assert.deepEqual(input, {}); return liveValue(jsToProtoValue(new Uint8Array([7])));
|
||||||
|
} }; },
|
||||||
|
});
|
||||||
|
assert.equal(written.$quixosValue.kind.value, String(2n ** 60n));
|
||||||
|
assert.deepEqual(result.$quixosValue.kind.value, new Uint8Array([7]));
|
||||||
|
});
|
||||||
|
test("external message bindings and derived event types are used at the boundary", async () => {
|
||||||
|
const message = { kind: "message", descriptorId: "Payload" };
|
||||||
|
const messages = { Payload: { encode: jsToProtoValue, decode: protoValueToJs } };
|
||||||
|
const handler = bindQxHandler({ inputType: message, outputType: { kind: "builtin", name: "watch-handle" }, eventType: message, ports: {} },
|
||||||
|
{ kind: "derived", get: ({ input }) => ({ value: input.title }) }, messages);
|
||||||
|
assert.equal(handler.kind, "derived");
|
||||||
|
const result = await handler.get({ objectId: "obj", inputProto: { title: jsToProtoValue("hello") } });
|
||||||
|
assert.deepEqual(protoValueToJs(result.$quixosValue), { value: "hello" });
|
||||||
|
assert.throws(() => encodeQxValue(message, {}, {}), /Missing message binding/);
|
||||||
|
});
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import fs from 'node:fs/promises';
|
||||||
|
import os from 'node:os';
|
||||||
|
import path from 'node:path';
|
||||||
|
import crypto from 'node:crypto';
|
||||||
|
import {spawnSync} from 'node:child_process';
|
||||||
|
|
||||||
|
test('supervised SDK reads a credential file and proves instance identity without an environment token', async t => {
|
||||||
|
const directory = await fs.mkdtemp(path.join(os.tmpdir(), 'qx-sdk-credential-'));
|
||||||
|
t.after(() => fs.rm(directory, {recursive:true, force:true}));
|
||||||
|
const token = crypto.randomBytes(32).toString('hex');
|
||||||
|
const filename = path.join(directory, 'process-token');
|
||||||
|
await fs.writeFile(filename, token, {mode:0o600});
|
||||||
|
const env = {...process.env, CAMINO_RUNTIME_AUTH_TOKEN_FILE: filename,
|
||||||
|
CAMINO_RUNTIME_AUTH_REQUIRED:'1', QUIXOS_RUNTIME_INSTANCE_ID:'instance:test'};
|
||||||
|
delete env.CAMINO_RUNTIME_AUTH_TOKEN;
|
||||||
|
const result = spawnSync(process.execPath, ['--input-type=module', '-e', `
|
||||||
|
import {createPackageRuntimeRoutes} from ${JSON.stringify(new URL('../dist/index.js', import.meta.url).href)};
|
||||||
|
createPackageRuntimeRoutes({packageRevisionId:'package:test',exports:{}})({
|
||||||
|
service(_type, implementation) { console.log(JSON.stringify(implementation.handshake({nonce:'challenge'}))); }
|
||||||
|
});
|
||||||
|
`], {env, encoding:'utf8'});
|
||||||
|
assert.equal(result.status, 0, result.stderr);
|
||||||
|
const handshake = JSON.parse(result.stdout);
|
||||||
|
assert.equal(handshake.authenticationProof, crypto.createHmac('sha256', token)
|
||||||
|
.update(JSON.stringify(['challenge','instance:test','package:test'])).digest('hex'));
|
||||||
|
assert.ok(handshake.capabilities.includes('epoch-grants-v1'));
|
||||||
|
assert.ok(!result.stdout.includes(token));
|
||||||
|
});
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import test from "node:test";
|
||||||
|
import assert from "node:assert/strict";
|
||||||
|
import { createInvocationRegistry } from "../dist/invocations.js";
|
||||||
|
|
||||||
|
test("cancel requests do not acknowledge execution completion or allow replay", () => {
|
||||||
|
const registry = createInvocationRegistry();
|
||||||
|
const execution = registry.begin("call-1");
|
||||||
|
assert.equal(registry.cancel("call-1").state, "cancellation-requested");
|
||||||
|
assert.equal(execution.signal.aborted, true);
|
||||||
|
assert.equal(registry.status("call-1").state, "cancellation-requested");
|
||||||
|
execution.finish();
|
||||||
|
assert.equal(registry.status("call-1").state, "completed");
|
||||||
|
assert.throws(() => registry.begin("call-1"), /already used/);
|
||||||
|
assert.equal(registry.status("missing").state, "unknown");
|
||||||
|
});
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import test from "node:test";
|
||||||
|
import assert from "node:assert/strict";
|
||||||
|
import {createMigrationContext, migrationObjectId} from "../dist/migration.js";
|
||||||
|
test("migration context offers restricted ports and deterministic helper identities", () => {
|
||||||
|
const input = {schemaVersion: 1, executionId: "operation:transition", exportId: "migrate", ports: [
|
||||||
|
{name: "old", binding: "slot:name", view: "old", access: ["read"], states: [{objectId: "obj:one", value: "Alice"}]},
|
||||||
|
{name: "new", binding: "slot:name", view: "new", access: ["write"]}, {name: "newRead", binding: "slot:name", view: "new", access: ["read"]},
|
||||||
|
{name: "helpers", binding: "atom:helper", view: "new", access: ["create"]},
|
||||||
|
]};
|
||||||
|
const {context, result} = createMigrationContext(input);
|
||||||
|
assert.equal(context.read("old", "obj:one"), "Alice");
|
||||||
|
assert.throws(() => context.write("old", "obj:one", "Bob"), /does not grant/);
|
||||||
|
assert.throws(() => context.read("new", "obj:one"), /does not grant/);
|
||||||
|
context.write("new", "obj:one", "Alice");
|
||||||
|
assert.equal(context.read("newRead", "obj:one"), "Alice");
|
||||||
|
context.write("new", "obj:one", "Bob");
|
||||||
|
assert.equal(context.read("newRead", "obj:one"), "Bob");
|
||||||
|
assert.equal(context.read("old", "obj:one"), "Alice");
|
||||||
|
const helper = context.create("helpers", "one");
|
||||||
|
assert.equal(helper, migrationObjectId(input.executionId, "helpers", "one"));
|
||||||
|
assert.equal(context.create("helpers", "one"), helper);
|
||||||
|
assert.equal(result().creates.length, 1);
|
||||||
|
assert.deepEqual(input.ports[0].states, [{objectId: "obj:one", value: "Alice"}]);
|
||||||
|
});
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import test from "node:test";
|
||||||
|
import assert from "node:assert/strict";
|
||||||
|
import {relationshipMap, relationshipList, relationshipSet} from "../dist/index.js";
|
||||||
|
import {referenceFromWire} from "../dist/references.js";
|
||||||
|
test("relationship helpers preserve handles and require explicit collection revisions", async () => {
|
||||||
|
let current = {revision: 0n, entries: []}, serial = 0;
|
||||||
|
const port = {collection: async () => ({revision: current.revision, entries: current.entries.map((entry) => ({...entry}))}),
|
||||||
|
replace: async (entries, revision) => {
|
||||||
|
assert.equal(revision, current.revision);
|
||||||
|
current = {revision: revision + 1n, entries: entries.map((entry) => ({...entry, edgeId: entry.edgeId ?? `edge:${++serial}`}))};
|
||||||
|
return port.collection();
|
||||||
|
}};
|
||||||
|
const a = referenceFromWire("obj:a"), b = referenceFromWire("obj:b");
|
||||||
|
const map = relationshipMap(port);
|
||||||
|
await map.set("a1", a, 0n);
|
||||||
|
assert.equal((await map.get("a1")).value.equals(a), true);
|
||||||
|
await assert.rejects(() => map.set("b1", b, 0n), /STALE_COLLECTION/);
|
||||||
|
await map.delete("a1", 1n);
|
||||||
|
const list = relationshipList(port);
|
||||||
|
const inserted = await list.insert(0, a, 2n);
|
||||||
|
await list.insert(1, b, 3n);
|
||||||
|
const moved = await list.move(inserted.entries[0].edgeId, 1, 4n);
|
||||||
|
assert.equal(moved.entries[1].target.equals(a), true);
|
||||||
|
const set = relationshipSet(port);
|
||||||
|
const unchanged = await set.add(referenceFromWire("obj:a"), 5n);
|
||||||
|
assert.equal(unchanged.revision, 5n);
|
||||||
|
});
|
||||||
+211
-3
@@ -1,6 +1,7 @@
|
|||||||
import assert from "node:assert/strict";
|
import assert from "node:assert/strict";
|
||||||
import http from "node:http";
|
import http from "node:http";
|
||||||
import test from "node:test";
|
import test from "node:test";
|
||||||
|
import { referenceFromWire } from "../dist/references.js";
|
||||||
import { create } from "@bufbuild/protobuf";
|
import { create } from "@bufbuild/protobuf";
|
||||||
import { createClient } from "@connectrpc/connect";
|
import { createClient } from "@connectrpc/connect";
|
||||||
import { connectNodeAdapter, createConnectTransport } from "@connectrpc/connect-node";
|
import { connectNodeAdapter, createConnectTransport } from "@connectrpc/connect-node";
|
||||||
@@ -9,18 +10,24 @@ import {
|
|||||||
createRuntimeContext,
|
createRuntimeContext,
|
||||||
derived,
|
derived,
|
||||||
jsToProtoValue,
|
jsToProtoValue,
|
||||||
|
liveValue,
|
||||||
protoValueToJs,
|
protoValueToJs,
|
||||||
} from "../dist/index.js";
|
} from "../dist/index.js";
|
||||||
import {
|
import {
|
||||||
CaminoObjectSchema,
|
CaminoObjectSchema,
|
||||||
CaminoService,
|
CaminoService,
|
||||||
|
CrdtValueSchema,
|
||||||
|
StateValueSourceSchema,
|
||||||
|
ValueSchema,
|
||||||
|
ValueSourceSchema,
|
||||||
} from "../dist/camino/api_pb.js";
|
} from "../dist/camino/api_pb.js";
|
||||||
import {
|
import {
|
||||||
EdgeDependencySchema,
|
EdgeDependencySchema,
|
||||||
InjectedDependencySchema,
|
InjectedDependencySchema,
|
||||||
PackageExportRefSchema,
|
PackageExportRefSchema,
|
||||||
} from "../dist/quixos/refs_pb.js";
|
} from "../dist/quixos/refs_pb.js";
|
||||||
import { PackageRuntime } from "../dist/quixos/runtime_pb.js";
|
import { InvokeCapabilityResponseSchema, OrchestratorRuntime } from "../dist/quixos/orch_pb.js";
|
||||||
|
import { DerivedDependencySchema, PackageRuntime } from "../dist/quixos/runtime_pb.js";
|
||||||
|
|
||||||
const listen = async (routes) => {
|
const listen = async (routes) => {
|
||||||
const server = http.createServer((request, response) => void connectNodeAdapter({ routes })(request, response));
|
const server = http.createServer((request, response) => void connectNodeAdapter({ routes })(request, response));
|
||||||
@@ -39,16 +46,40 @@ const listen = async (routes) => {
|
|||||||
test("generic values preserve nested values and object references", () => {
|
test("generic values preserve nested values and object references", () => {
|
||||||
const value = jsToProtoValue({
|
const value = jsToProtoValue({
|
||||||
title: "A task",
|
title: "A task",
|
||||||
target: { $quixosRef: "obj:target" },
|
target: referenceFromWire("obj:target"),
|
||||||
tags: ["one", "two"],
|
tags: ["one", "two"],
|
||||||
});
|
});
|
||||||
assert.deepEqual(protoValueToJs(value), {
|
assert.deepEqual(protoValueToJs(value), {
|
||||||
title: "A task",
|
title: "A task",
|
||||||
target: "obj:target",
|
target: referenceFromWire("obj:target"),
|
||||||
tags: ["one", "two"],
|
tags: ["one", "two"],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("live values preserve writable CRDT source identity through derivation", () => {
|
||||||
|
const value = create(ValueSchema, {
|
||||||
|
kind: { case: "stringValue", value: "notes" },
|
||||||
|
source: create(ValueSourceSchema, {
|
||||||
|
state: create(StateValueSourceSchema, {
|
||||||
|
objectId: "obj:task",
|
||||||
|
slotId: "slot:task:notes",
|
||||||
|
revision: 7n,
|
||||||
|
crdtSnapshot: create(CrdtValueSchema, {
|
||||||
|
type: "quixos.automerge-document.v1",
|
||||||
|
encoding: "automerge-snapshot-v1",
|
||||||
|
payload: new Uint8Array([1, 2, 3]),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const forwarded = jsToProtoValue(liveValue(value));
|
||||||
|
assert.equal(forwarded.source?.state?.objectId, "obj:task");
|
||||||
|
assert.equal(forwarded.source?.state?.slotId, "slot:task:notes");
|
||||||
|
assert.equal(forwarded.source?.state?.revision, 7n);
|
||||||
|
assert.deepEqual(forwarded.source?.state?.crdtSnapshot?.payload, new Uint8Array([1, 2, 3]));
|
||||||
|
});
|
||||||
|
|
||||||
test("runtime context exposes only explicitly injected ports", async () => {
|
test("runtime context exposes only explicitly injected ports", async () => {
|
||||||
const writes = [];
|
const writes = [];
|
||||||
const camino = {
|
const camino = {
|
||||||
@@ -93,6 +124,183 @@ test("runtime context exposes only explicitly injected ports", async () => {
|
|||||||
assert.deepEqual(await context.edge("port:children").resolve(), []);
|
assert.deepEqual(await context.edge("port:children").resolve(), []);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("injected ports preserve an explicitly traversed object through PackageRuntime RPC", async () => {
|
||||||
|
const reads = [];
|
||||||
|
const caminoServer = await listen((router) => router.service(CaminoService, {
|
||||||
|
readState: (request) => {
|
||||||
|
reads.push(request);
|
||||||
|
return { value: jsToProtoValue("Project name") };
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
const runtimeServer = await listen(createPackageRuntimeRoutes({
|
||||||
|
packageRevisionId: "package:test@1",
|
||||||
|
caminoUrl: caminoServer.url,
|
||||||
|
exports: {
|
||||||
|
"export:test:value": (context) => context.state("port:value").get(),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
const client = createClient(PackageRuntime, createConnectTransport({
|
||||||
|
baseUrl: runtimeServer.url,
|
||||||
|
httpVersion: "1.1",
|
||||||
|
}));
|
||||||
|
try {
|
||||||
|
const response = await client.invoke({
|
||||||
|
export: create(PackageExportRefSchema, {
|
||||||
|
packageRevisionId: "package:test@1",
|
||||||
|
exportId: "export:test:value",
|
||||||
|
}),
|
||||||
|
objectId: "obj:component",
|
||||||
|
dependencies: [create(InjectedDependencySchema, {
|
||||||
|
portId: "port:value",
|
||||||
|
objectId: "obj:project",
|
||||||
|
binding: { case: "stateSlotId", value: "slot:project:name" },
|
||||||
|
})],
|
||||||
|
});
|
||||||
|
assert.equal(response.ok, true);
|
||||||
|
assert.equal(protoValueToJs(response.result), "Project name");
|
||||||
|
assert.equal(reads.length, 1);
|
||||||
|
assert.equal(reads[0]?.objectId, "obj:project");
|
||||||
|
} finally {
|
||||||
|
await runtimeServer.close();
|
||||||
|
await caminoServer.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("interface views invoke a related object and propagate transitive live dependencies", async () => {
|
||||||
|
const invocations = [];
|
||||||
|
const sourceValue = create(ValueSchema, {
|
||||||
|
kind: { case: "stringValue", value: "Project name" },
|
||||||
|
source: create(ValueSourceSchema, {
|
||||||
|
state: create(StateValueSourceSchema, {
|
||||||
|
objectId: "obj:project",
|
||||||
|
slotId: "slot:project:name",
|
||||||
|
revision: 4n,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const orchServer = await listen((router) => router.service(OrchestratorRuntime, {
|
||||||
|
invokeCapability: (request) => {
|
||||||
|
invocations.push(request);
|
||||||
|
return create(InvokeCapabilityResponseSchema, {
|
||||||
|
ok: true,
|
||||||
|
result: sourceValue,
|
||||||
|
dependencies: [create(DerivedDependencySchema, {
|
||||||
|
kind: "state",
|
||||||
|
objectId: "obj:project",
|
||||||
|
attachmentId: "slot:project:name",
|
||||||
|
})],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
const runtimeServer = await listen(createPackageRuntimeRoutes({
|
||||||
|
packageRevisionId: "package:test@1",
|
||||||
|
orchUrl: orchServer.url,
|
||||||
|
exports: {
|
||||||
|
"export:test:value": derived((context) =>
|
||||||
|
context.interface("port:named").live("operation:named:name:get")),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
const client = createClient(PackageRuntime, createConnectTransport({
|
||||||
|
baseUrl: runtimeServer.url,
|
||||||
|
httpVersion: "1.1",
|
||||||
|
}));
|
||||||
|
try {
|
||||||
|
const response = await client.invoke({
|
||||||
|
export: create(PackageExportRefSchema, {
|
||||||
|
packageRevisionId: "package:test@1",
|
||||||
|
exportId: "export:test:value",
|
||||||
|
}),
|
||||||
|
objectId: "obj:component",
|
||||||
|
dependencies: [create(InjectedDependencySchema, {
|
||||||
|
portId: "port:named",
|
||||||
|
objectId: "obj:project",
|
||||||
|
binding: { case: "interfaceRevisionId", value: "interface:named@1" },
|
||||||
|
})],
|
||||||
|
});
|
||||||
|
assert.equal(response.ok, true);
|
||||||
|
assert.equal(invocations[0]?.objectId, "obj:project");
|
||||||
|
assert.equal(invocations[0]?.capability?.interfaceRevisionId, "interface:named@1");
|
||||||
|
assert.equal(response.dependencies[0]?.objectId, "obj:project");
|
||||||
|
assert.equal(response.dependencies[0]?.attachmentId, "slot:project:name");
|
||||||
|
assert.equal(response.result?.source?.state?.revision, 4n);
|
||||||
|
} finally {
|
||||||
|
await runtimeServer.close();
|
||||||
|
await orchServer.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("derived interface views reread after their transitive subscriptions become live", async () => {
|
||||||
|
let current = "before subscription";
|
||||||
|
let invocationCount = 0;
|
||||||
|
const caminoServer = await listen((router) => router.service(CaminoService, {
|
||||||
|
watchObject: async function* (request, context) {
|
||||||
|
// Model a write racing the first nested capability read. Camino makes
|
||||||
|
// the subscription live before yielding this snapshot.
|
||||||
|
current = "after subscription";
|
||||||
|
yield {
|
||||||
|
objectId: request.objectId,
|
||||||
|
snapshot: create(CaminoObjectSchema, {
|
||||||
|
id: request.objectId,
|
||||||
|
atomId: "atom:project",
|
||||||
|
workspaceRevisionId: "workspace:test@1",
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
await new Promise((resolve) =>
|
||||||
|
context.signal.addEventListener("abort", resolve, { once: true }));
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
const orchServer = await listen((router) => router.service(OrchestratorRuntime, {
|
||||||
|
invokeCapability: () => {
|
||||||
|
invocationCount += 1;
|
||||||
|
return create(InvokeCapabilityResponseSchema, {
|
||||||
|
ok: true,
|
||||||
|
result: jsToProtoValue(current),
|
||||||
|
dependencies: [create(DerivedDependencySchema, {
|
||||||
|
kind: "state",
|
||||||
|
objectId: "obj:project",
|
||||||
|
attachmentId: "slot:project:name",
|
||||||
|
})],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
const runtimeServer = await listen(createPackageRuntimeRoutes({
|
||||||
|
packageRevisionId: "package:test@1",
|
||||||
|
caminoUrl: caminoServer.url,
|
||||||
|
orchUrl: orchServer.url,
|
||||||
|
exports: {
|
||||||
|
"export:test:value": derived((context) =>
|
||||||
|
context.interface("port:named").invoke("operation:named:name:get")),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
const client = createClient(PackageRuntime, createConnectTransport({
|
||||||
|
baseUrl: runtimeServer.url,
|
||||||
|
httpVersion: "1.1",
|
||||||
|
}));
|
||||||
|
const controller = new AbortController();
|
||||||
|
try {
|
||||||
|
const stream = client.watch({
|
||||||
|
export: create(PackageExportRefSchema, {
|
||||||
|
packageRevisionId: "package:test@1",
|
||||||
|
exportId: "export:test:value",
|
||||||
|
}),
|
||||||
|
objectId: "obj:component",
|
||||||
|
dependencies: [create(InjectedDependencySchema, {
|
||||||
|
portId: "port:named",
|
||||||
|
objectId: "obj:project",
|
||||||
|
binding: { case: "interfaceRevisionId", value: "interface:named@1" },
|
||||||
|
})],
|
||||||
|
}, { signal: controller.signal })[Symbol.asyncIterator]();
|
||||||
|
const initial = await stream.next();
|
||||||
|
assert.equal(protoValueToJs(initial.value?.value), "after subscription");
|
||||||
|
assert.equal(invocationCount, 2);
|
||||||
|
} finally {
|
||||||
|
controller.abort();
|
||||||
|
await runtimeServer.close();
|
||||||
|
await orchServer.close();
|
||||||
|
await caminoServer.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test("derived watches subscribe before reading and emit only real changes", async () => {
|
test("derived watches subscribe before reading and emit only real changes", async () => {
|
||||||
let current = "before";
|
let current = "before";
|
||||||
let subscribed = false;
|
let subscribed = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user