UNPKG

@metamask/ocap-kernel

Version:
199 lines 8.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isGCAction = exports.GCActionStruct = exports.isGCActionType = exports.queueTypeFromActionType = exports.KernelStatusStruct = exports.SubclusterStruct = exports.isClusterConfig = exports.ClusterConfigStruct = exports.isVatConfig = exports.VatConfigStruct = exports.VatMessageIdStruct = exports.isVatMessageId = exports.SubclusterIdStruct = exports.isSubclusterId = exports.VatIdStruct = exports.isVatId = exports.RunQueueItemStruct = exports.actionTypePriorities = exports.MessageStruct = exports.VatOneResolutionStruct = exports.CapDataStruct = exports.ROOT_OBJECT_VREF = void 0; exports.coerceMessage = coerceMessage; exports.coerceVatSyscallObject = coerceVatSyscallObject; exports.insistMessage = insistMessage; exports.insistVatId = insistVatId; exports.insistGCActionType = insistGCActionType; const superstruct_1 = require("@metamask/superstruct"); const utils_1 = require("@metamask/utils"); const assert_ts_1 = require("./utils/assert.cjs"); exports.ROOT_OBJECT_VREF = 'o+0'; exports.CapDataStruct = (0, superstruct_1.object)({ body: (0, superstruct_1.string)(), slots: (0, superstruct_1.array)((0, superstruct_1.string)()), }); exports.VatOneResolutionStruct = (0, superstruct_1.tuple)([ (0, superstruct_1.string)(), (0, superstruct_1.boolean)(), exports.CapDataStruct, ]); exports.MessageStruct = (0, superstruct_1.object)({ methargs: exports.CapDataStruct, result: (0, superstruct_1.exactOptional)((0, superstruct_1.union)([(0, superstruct_1.string)(), (0, superstruct_1.literal)(null)])), }); /** * Coerce a {@link SwingsetMessage} to our own JSON-RPC-compatible {@link Message}. * * @param message - The SwingsetMessage to coerce. * @returns The coerced Message. */ function coerceMessage(message) { if (message.result === undefined) { delete message.result; } return message; } /** * Coerce a {@link VatSyscallObject} to a JSON-RPC-compatible {@link JsonVatSyscallObject}. * * @param vso - The VatSyscallObject to coerce. * @returns The coerced VatSyscallObject. */ function coerceVatSyscallObject(vso) { if (vso[0] === 'send') { return ['send', vso[1], coerceMessage(vso[2])]; } return vso; } const RunQueueItemSendStruct = (0, superstruct_1.object)({ type: (0, superstruct_1.literal)('send'), target: (0, superstruct_1.string)(), // KRef message: exports.MessageStruct, }); const RunQueueItemNotifyStruct = (0, superstruct_1.object)({ type: (0, superstruct_1.literal)('notify'), vatId: (0, superstruct_1.string)(), kpid: (0, superstruct_1.string)(), }); const GCRunQueueTypeStruct = (0, superstruct_1.union)([ (0, superstruct_1.literal)('dropExports'), (0, superstruct_1.literal)('retireExports'), (0, superstruct_1.literal)('retireImports'), ]); exports.actionTypePriorities = [ 'dropExport', 'retireExport', 'retireImport', ]; const RunQueueItemGCActionStruct = (0, superstruct_1.object)({ type: GCRunQueueTypeStruct, vatId: (0, superstruct_1.string)(), // VatId krefs: (0, superstruct_1.array)((0, superstruct_1.string)()), // KRefs }); const RunQueueItemBringOutYourDeadStruct = (0, superstruct_1.object)({ type: (0, superstruct_1.literal)('bringOutYourDead'), vatId: (0, superstruct_1.string)(), }); exports.RunQueueItemStruct = (0, superstruct_1.union)([ RunQueueItemSendStruct, RunQueueItemNotifyStruct, RunQueueItemGCActionStruct, RunQueueItemBringOutYourDeadStruct, ]); /** * Assert that a value is a valid message. * * @param value - The value to check. * @throws if the value is not a valid message. */ function insistMessage(value) { (0, superstruct_1.is)(value, exports.MessageStruct) || (0, assert_ts_1.Fail) `not a valid message`; } const isVatId = (value) => typeof value === 'string' && value.at(0) === 'v' && value.slice(1) === String(Number(value.slice(1))); exports.isVatId = isVatId; /** * Assert that a value is a valid vat id. * * @param value - The value to check. * @throws if the value is not a valid vat id. */ function insistVatId(value) { (0, exports.isVatId)(value) || (0, assert_ts_1.Fail) `not a valid VatId`; } exports.VatIdStruct = (0, superstruct_1.define)('VatId', exports.isVatId); const isSubclusterId = (value) => typeof value === 'string' && value.at(0) === 's' && value.slice(1) === String(Number(value.slice(1))); exports.isSubclusterId = isSubclusterId; exports.SubclusterIdStruct = (0, superstruct_1.define)('SubclusterId', exports.isSubclusterId); const isVatMessageId = (value) => typeof value === 'string' && value.at(0) === 'm' && value.slice(1) === String(Number(value.slice(1))); exports.isVatMessageId = isVatMessageId; exports.VatMessageIdStruct = (0, superstruct_1.define)('VatMessageId', exports.isVatMessageId); const UserCodeSpecStruct = (0, superstruct_1.union)([ (0, superstruct_1.object)({ sourceSpec: (0, superstruct_1.string)(), }), (0, superstruct_1.object)({ bundleSpec: (0, superstruct_1.string)(), }), (0, superstruct_1.object)({ bundleName: (0, superstruct_1.string)(), }), ]); exports.VatConfigStruct = (0, superstruct_1.define)('VatConfig', (value) => { if (!value) { return false; } const { creationOptions, parameters, ...specOnly } = value; return ((0, superstruct_1.is)(specOnly, UserCodeSpecStruct) && (!creationOptions || (0, superstruct_1.is)(creationOptions, utils_1.UnsafeJsonStruct)) && (!parameters || (0, superstruct_1.is)(parameters, utils_1.UnsafeJsonStruct))); }); const isVatConfig = (value) => (0, superstruct_1.is)(value, exports.VatConfigStruct); exports.isVatConfig = isVatConfig; exports.ClusterConfigStruct = (0, superstruct_1.object)({ bootstrap: (0, superstruct_1.string)(), forceReset: (0, superstruct_1.exactOptional)((0, superstruct_1.boolean)()), vats: (0, superstruct_1.record)((0, superstruct_1.string)(), exports.VatConfigStruct), bundles: (0, superstruct_1.exactOptional)((0, superstruct_1.record)((0, superstruct_1.string)(), exports.VatConfigStruct)), }); const isClusterConfig = (value) => (0, superstruct_1.is)(value, exports.ClusterConfigStruct); exports.isClusterConfig = isClusterConfig; exports.SubclusterStruct = (0, superstruct_1.object)({ id: exports.SubclusterIdStruct, config: exports.ClusterConfigStruct, vats: (0, superstruct_1.array)(exports.VatIdStruct), }); exports.KernelStatusStruct = (0, superstruct_1.type)({ subclusters: (0, superstruct_1.array)(exports.SubclusterStruct), vats: (0, superstruct_1.array)((0, superstruct_1.object)({ id: exports.VatIdStruct, config: exports.VatConfigStruct, subclusterId: exports.SubclusterIdStruct, })), }); /** * A mapping of GC action type to queue event type. */ exports.queueTypeFromActionType = new Map([ // Note: From singular to plural ['dropExport', 'dropExports'], ['retireExport', 'retireExports'], ['retireImport', 'retireImports'], ]); const isGCActionType = (value) => exports.actionTypePriorities.includes(value); exports.isGCActionType = isGCActionType; /** * Assert that a value is a valid GC action type. * * @param value - The value to check. * @throws if the value is not a valid GC action type. */ function insistGCActionType(value) { (0, exports.isGCActionType)(value) || (0, assert_ts_1.Fail) `not a valid GCActionType ${value}`; } exports.GCActionStruct = (0, superstruct_1.define)('GCAction', (value) => { if (typeof value !== 'string') { return false; } const [vatId, actionType, kref] = value.split(' '); if (!(0, exports.isVatId)(vatId)) { return false; } if (!(0, exports.isGCActionType)(actionType)) { return false; } if (typeof kref !== 'string' || !kref.startsWith('ko')) { return false; } return true; }); const isGCAction = (value) => (0, superstruct_1.is)(value, exports.GCActionStruct); exports.isGCAction = isGCAction; //# sourceMappingURL=types.cjs.map