UNPKG

@metamask/ocap-kernel

Version:
131 lines 4.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.kslot = kslot; exports.krefOf = krefOf; exports.kser = kser; exports.kunser = kunser; exports.makeError = makeError; const errors_1 = require("@endo/errors"); const far_1 = require("@endo/far"); const marshal_1 = require("@endo/marshal"); const { toStringTag } = Symbol; /** * Create a promise as a standin object for a kpid. This is never actually used * as a promise; its job is just to carry the kref as a tag while at the same * time looking to passStyleOf as if it's a Promise. * * @param kref - A KRef string to tag the result with. * * @returns A nominal Promise object tagged with `kref`. */ // eslint-disable-next-line @typescript-eslint/promise-function-async function makeStandinPromise(kref) { const standinP = Promise.resolve(`${kref} stand in`); // eslint-disable-next-line @typescript-eslint/no-floating-promises Object.defineProperty(standinP, toStringTag, { value: kref, enumerable: false, }); return harden(standinP); } /** * Extract the tagged `kref` from a standin promise. * * @param promise - A promise that has previously been labelled via `makeStandinPromise`. * * @returns The KRef tag that `promise` carries. */ function getStandinPromiseTag(promise) { const desc = Object.getOwnPropertyDescriptor(promise, toStringTag); (0, errors_1.assert)(desc !== undefined, 'promise lacks own @@toStringTag property'); const kref = desc.value; errors_1.assert.typeof(kref, 'string'); return kref; } /** * Obtain a value serializable via `kser` for a given KRef. * * @param kref - The KRef string to get a value for. * @param iface - Option interface type descriptor string. * * @returns A `kser` serializable value for `kref`. */ function kslot(kref, iface = 'undefined') { errors_1.assert.typeof(kref, 'string'); if (iface?.startsWith('Alleged: ')) { // Encoder prepends "Alleged: " to iface string, but the decoder doesn't strip it // Unclear whether it's the decoder or me who is wrong // eslint-disable-next-line no-param-reassign iface = iface.slice(9); } if (kref.startsWith('p') || kref.startsWith('kp') || kref.startsWith('rp')) { return makeStandinPromise(kref); } const standinObject = (0, far_1.Far)(iface, { iface: () => iface, getKref: () => `${kref}`, }); return standinObject; } /** * Obtain the KRef associated with a value that was serialized with `kser`. * * @param obj - The value of interest. * * @returns a KRef string for `obj`. */ function krefOf(obj) { switch ((0, far_1.passStyleOf)(obj)) { case 'promise': { return getStandinPromiseTag(obj); } case 'remotable': { const { getKref } = obj; errors_1.assert.typeof(getKref, 'function', 'object lacks getKref function'); return getKref(); } default: // When krefOf() is called as part of kmarshal.serialize, marshal // will only give it things that are 'remotable' (Promises and the // Far objects created by kslot()). When krefOf() is called by // kernel code, it ought to throw if 'obj' is not one of the // objects created by our kslot(). return (0, errors_1.Fail) `krefOf requires a promise or remotable`; } } const kmarshal = (0, marshal_1.makeMarshal)(krefOf, kslot, { serializeBodyFormat: 'smallcaps', errorTagging: 'off', }); /** * Serialize a value in kernel space. * * @param value - The value to be serialized. * * @returns a capdata object that can be deserialized with `kunser`. */ function kser(value) { return kmarshal.toCapData(harden(value)); } /** * Deserialize a value that was serialized with `kser`. * * @param serializedValue -- The value to deserialize. * * @returns the deserialization of `serializedValue`. */ function kunser(serializedValue) { return kmarshal.fromCapData(serializedValue); } /** * Produce a serialized form of an Error. * * @param message - The error message to construct the Error with. * * @returns The resulting error after serialization. */ function makeError(message) { errors_1.assert.typeof(message, 'string'); return kser(Error(message)); } //# sourceMappingURL=kernel-marshal.cjs.map