@metamask/ocap-kernel
Version:
OCap kernel core components
1 lines • 17.1 kB
Source Map (JSON)
{"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n SwingSetCapData,\n Message as SwingsetMessage,\n VatSyscallObject,\n VatSyscallSend,\n} from '@agoric/swingset-liveslots';\nimport type { CapData } from '@endo/marshal';\nimport type { VatCheckpoint } from '@metamask/kernel-store';\nimport type { JsonRpcMessage } from '@metamask/kernel-utils';\nimport type { DuplexStream } from '@metamask/streams';\nimport {\n define,\n is,\n object,\n string,\n array,\n record,\n union,\n tuple,\n literal,\n boolean,\n exactOptional,\n type,\n} from '@metamask/superstruct';\nimport type { Infer } from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport { UnsafeJsonStruct } from '@metamask/utils';\n\nimport { Fail } from './utils/assert.ts';\n\nexport type VatId = string;\nexport type RemoteId = string;\nexport type EndpointId = VatId | RemoteId;\nexport type SubclusterId = string;\n\nexport type KRef = string;\nexport type VRef = string;\nexport type RRef = string;\nexport type ERef = VRef | RRef;\nexport type Ref = KRef | ERef;\n\nexport const ROOT_OBJECT_VREF: VRef = 'o+0';\n\nexport const CapDataStruct = object({\n body: string(),\n slots: array(string()),\n});\n\nexport const VatOneResolutionStruct = tuple([\n string(),\n boolean(),\n CapDataStruct,\n]);\n\nexport const MessageStruct = object({\n methargs: CapDataStruct,\n result: exactOptional(union([string(), literal(null)])),\n});\n\n/**\n * JSON-RPC-compatible Message type, originally from @agoric/swingset-liveslots.\n */\nexport type Message = Infer<typeof MessageStruct>;\n\n/**\n * Coerce a {@link SwingsetMessage} to our own JSON-RPC-compatible {@link Message}.\n *\n * @param message - The SwingsetMessage to coerce.\n * @returns The coerced Message.\n */\nexport function coerceMessage(message: SwingsetMessage): Message {\n if (message.result === undefined) {\n delete (message as Message).result;\n }\n return message as Message;\n}\n\ntype JsonVatSyscallObject =\n | Exclude<VatSyscallObject, VatSyscallSend>\n | ['send', string, Message];\n\n/**\n * Coerce a {@link VatSyscallObject} to a JSON-RPC-compatible {@link JsonVatSyscallObject}.\n *\n * @param vso - The VatSyscallObject to coerce.\n * @returns The coerced VatSyscallObject.\n */\nexport function coerceVatSyscallObject(\n vso: VatSyscallObject,\n): JsonVatSyscallObject {\n if (vso[0] === 'send') {\n return ['send', vso[1], coerceMessage(vso[2])];\n }\n return vso as JsonVatSyscallObject;\n}\n\nconst RunQueueItemSendStruct = object({\n type: literal('send'),\n target: string(), // KRef\n message: MessageStruct,\n});\n\nexport type RunQueueItemSend = Infer<typeof RunQueueItemSendStruct>;\n\nconst RunQueueItemNotifyStruct = object({\n type: literal('notify'),\n vatId: string(),\n kpid: string(),\n});\n\nexport type RunQueueItemNotify = Infer<typeof RunQueueItemNotifyStruct>;\n\nconst GCRunQueueTypeStruct = union([\n literal('dropExports'),\n literal('retireExports'),\n literal('retireImports'),\n]);\n\nexport type GCRunQueueType = Infer<typeof GCRunQueueTypeStruct>;\n\nexport type GCActionType = 'dropExport' | 'retireExport' | 'retireImport';\nexport const actionTypePriorities: GCActionType[] = [\n 'dropExport',\n 'retireExport',\n 'retireImport',\n];\n\nconst RunQueueItemGCActionStruct = object({\n type: GCRunQueueTypeStruct,\n vatId: string(), // VatId\n krefs: array(string()), // KRefs\n});\n\nexport type RunQueueItemGCAction = Infer<typeof RunQueueItemGCActionStruct>;\n\nconst RunQueueItemBringOutYourDeadStruct = object({\n type: literal('bringOutYourDead'),\n vatId: string(),\n});\n\nexport type RunQueueItemBringOutYourDead = Infer<\n typeof RunQueueItemBringOutYourDeadStruct\n>;\n\nexport const RunQueueItemStruct = union([\n RunQueueItemSendStruct,\n RunQueueItemNotifyStruct,\n RunQueueItemGCActionStruct,\n RunQueueItemBringOutYourDeadStruct,\n]);\n\nexport type RunQueueItem = Infer<typeof RunQueueItemStruct>;\n\n/**\n * Assert that a value is a valid message.\n *\n * @param value - The value to check.\n * @throws if the value is not a valid message.\n */\nexport function insistMessage(value: unknown): asserts value is Message {\n is(value, MessageStruct) || Fail`not a valid message`;\n}\n\n// Per-endpoint persistent state\ntype EndpointState<IdType> = {\n name: string;\n id: IdType;\n nextExportObjectIdCounter: number;\n nextExportPromiseIdCounter: number;\n eRefToKRef: Map<ERef, KRef>;\n kRefToERef: Map<KRef, ERef>;\n};\n\ntype KernelVatState = {\n messagePort: typeof MessagePort;\n state: EndpointState<VatId>;\n source: string;\n kvTable: Map<string, string>;\n};\n\ntype RemoteState = {\n state: EndpointState<RemoteId>;\n connectToURL: string;\n // more here about maintaining connection...\n};\n\n// Kernel persistent state\n\nexport type PromiseState = 'unresolved' | 'fulfilled' | 'rejected';\n\nexport type KernelPromise = {\n state: PromiseState;\n decider?: EndpointId;\n subscribers?: EndpointId[];\n value?: CapData<KRef>;\n};\n\nexport type KernelState = {\n vats: Map<VatId, KernelVatState>;\n remotes: Map<RemoteId, RemoteState>;\n kernelPromises: Map<KRef, KernelPromise>;\n};\n\nexport const isVatId = (value: unknown): value is VatId =>\n typeof value === 'string' &&\n value.at(0) === 'v' &&\n value.slice(1) === String(Number(value.slice(1)));\n\n/**\n * Assert that a value is a valid vat id.\n *\n * @param value - The value to check.\n * @throws if the value is not a valid vat id.\n */\nexport function insistVatId(value: unknown): asserts value is VatId {\n isVatId(value) || Fail`not a valid VatId`;\n}\n\nexport const VatIdStruct = define<VatId>('VatId', isVatId);\n\nexport const isSubclusterId = (value: unknown): value is SubclusterId =>\n typeof value === 'string' &&\n value.at(0) === 's' &&\n value.slice(1) === String(Number(value.slice(1)));\n\nexport const SubclusterIdStruct = define<SubclusterId>(\n 'SubclusterId',\n isSubclusterId,\n);\n\nexport type VatMessageId = `m${number}`;\n\nexport const isVatMessageId = (value: unknown): value is VatMessageId =>\n typeof value === 'string' &&\n value.at(0) === 'm' &&\n value.slice(1) === String(Number(value.slice(1)));\n\nexport const VatMessageIdStruct = define<VatMessageId>(\n 'VatMessageId',\n isVatMessageId,\n);\n\n/**\n * A \"service\" for managing vat workers. Abstracts platform-specific details of\n * how vat workers are launched, terminated, and connected to the kernel.\n */\nexport type VatWorkerService = {\n /**\n * Launch a new worker with a specific vat id.\n *\n * @param vatId - The vat id of the worker to launch.\n * @param vatConfig - Configuration object describing vat.\n * @returns A promise for a duplex stream connected to the worker\n * which rejects if a worker with the given vat id already exists.\n */\n launch: (\n vatId: VatId,\n vatConfig: VatConfig,\n ) => Promise<DuplexStream<JsonRpcMessage, JsonRpcMessage>>;\n /**\n * Terminate a worker identified by its vat id.\n *\n * @param vatId - The vat id of the worker to terminate.\n * @param error - An optional error to terminate the worker with.\n * @returns A promise that resolves when the worker has terminated\n * or rejects if that worker does not exist.\n */\n terminate: (vatId: VatId, error?: Error) => Promise<void>;\n /**\n * Terminate all workers managed by the service.\n *\n * @returns A promise that resolves after all workers have terminated\n * or rejects if there was an error during termination.\n */\n terminateAll: () => Promise<void>;\n};\n\n// Cluster configuration\n\nexport type VatConfig = UserCodeSpec & {\n creationOptions?: Record<string, Json>;\n parameters?: Record<string, Json>;\n};\n\nconst UserCodeSpecStruct = union([\n object({\n sourceSpec: string(),\n }),\n object({\n bundleSpec: string(),\n }),\n object({\n bundleName: string(),\n }),\n]);\n\ntype UserCodeSpec = Infer<typeof UserCodeSpecStruct>;\n\nexport const VatConfigStruct = define<VatConfig>('VatConfig', (value) => {\n if (!value) {\n return false;\n }\n\n const { creationOptions, parameters, ...specOnly } = value as Record<\n string,\n unknown\n >;\n\n return (\n is(specOnly, UserCodeSpecStruct) &&\n (!creationOptions || is(creationOptions, UnsafeJsonStruct)) &&\n (!parameters || is(parameters, UnsafeJsonStruct))\n );\n});\n\nexport const isVatConfig = (value: unknown): value is VatConfig =>\n is(value, VatConfigStruct);\n\nexport type VatConfigTable = Record<string, VatConfig>;\n\nexport const ClusterConfigStruct = object({\n bootstrap: string(),\n forceReset: exactOptional(boolean()),\n services: exactOptional(array(string())),\n vats: record(string(), VatConfigStruct),\n bundles: exactOptional(record(string(), VatConfigStruct)),\n});\n\nexport type ClusterConfig = Infer<typeof ClusterConfigStruct>;\n\nexport const isClusterConfig = (value: unknown): value is ClusterConfig =>\n is(value, ClusterConfigStruct);\n\nexport const SubclusterStruct = object({\n id: SubclusterIdStruct,\n config: ClusterConfigStruct,\n vats: array(VatIdStruct),\n});\n\nexport type Subcluster = Infer<typeof SubclusterStruct>;\n\nexport const KernelStatusStruct = type({\n subclusters: array(SubclusterStruct),\n vats: array(\n object({\n id: VatIdStruct,\n config: VatConfigStruct,\n subclusterId: SubclusterIdStruct,\n }),\n ),\n});\n\nexport type KernelStatus = Infer<typeof KernelStatusStruct>;\n\nexport type UserCodeStartFn = (parameters?: Record<string, Json>) => object;\n\n/**\n * A mapping of GC action type to queue event type.\n */\nexport const queueTypeFromActionType = new Map<GCActionType, GCRunQueueType>([\n // Note: From singular to plural\n ['dropExport', 'dropExports'],\n ['retireExport', 'retireExports'],\n ['retireImport', 'retireImports'],\n]);\n\nexport const isGCActionType = (value: unknown): value is GCActionType =>\n actionTypePriorities.includes(value as GCActionType);\n\n/**\n * Assert that a value is a valid GC action type.\n *\n * @param value - The value to check.\n * @throws if the value is not a valid GC action type.\n */\nexport function insistGCActionType(\n value: unknown,\n): asserts value is GCActionType {\n isGCActionType(value) || Fail`not a valid GCActionType ${value}`;\n}\n\nexport type GCAction = `${VatId} ${GCActionType} ${KRef}`;\n\nexport const GCActionStruct = define<GCAction>('GCAction', (value: unknown) => {\n if (typeof value !== 'string') {\n return false;\n }\n const [vatId, actionType, kref] = value.split(' ');\n if (!isVatId(vatId)) {\n return false;\n }\n if (!isGCActionType(actionType)) {\n return false;\n }\n if (typeof kref !== 'string' || !kref.startsWith('ko')) {\n return false;\n }\n return true;\n});\n\nexport const isGCAction = (value: unknown): value is GCAction =>\n is(value, GCActionStruct);\n\nexport type CrankResults = {\n didDelivery?: VatId; // the vat on which we made a delivery\n abort?: boolean; // changes should be discarded, not committed\n terminate?: { vatId: VatId; reject: boolean; info: SwingSetCapData };\n};\n\nexport type VatDeliveryResult = [VatCheckpoint, string | null];\n"]}