@metamask/ocap-kernel
Version:
OCap kernel core components
200 lines • 8.21 kB
JavaScript
;
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)()),
services: (0, superstruct_1.exactOptional)((0, superstruct_1.array)((0, superstruct_1.string)())),
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