@metamask/ocap-kernel
Version:
OCap kernel core components
1 lines • 7.41 kB
Source Map (JSON)
{"version":3,"file":"kernel-marshal.mjs","sourceRoot":"","sources":["../../src/services/kernel-marshal.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert, Fail } from '@endo/errors';\nimport { Far, passStyleOf } from '@endo/far';\nimport { makeMarshal } from '@endo/marshal';\nimport type { CapData } from '@endo/marshal';\nimport type { Passable } from '@endo/pass-style';\n\nimport type { KRef } from '../types.ts';\n\n// Simple wrapper for serializing and unserializing marshalled values inside the\n// kernel, where we don't actually want to use clists nor actually allocate real\n// objects, but instead to stay entirely within the domain of krefs. This is\n// used to enable syntactic manipulation of serialized values while remaining\n// agnostic about the internal details of the serialization encoding.\n\ntype ObjectStandin = {\n getKref: () => string;\n iface: () => string;\n};\nexport type SlotValue = ObjectStandin | Promise<unknown>;\n\nconst { toStringTag } = Symbol;\n\n/**\n * Create a promise as a standin object for a kpid. This is never actually used\n * as a promise; its job is just to carry the kref as a tag while at the same\n * time looking to passStyleOf as if it's a Promise.\n *\n * @param kref - A KRef string to tag the result with.\n *\n * @returns A nominal Promise object tagged with `kref`.\n */\n// eslint-disable-next-line @typescript-eslint/promise-function-async\nfunction makeStandinPromise(kref: string): Promise<unknown> {\n const standinP = Promise.resolve(`${kref} stand in`);\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n Object.defineProperty(standinP, toStringTag, {\n value: kref,\n enumerable: false,\n });\n return harden(standinP);\n}\n\n/**\n * Extract the tagged `kref` from a standin promise.\n *\n * @param promise - A promise that has previously been labelled via `makeStandinPromise`.\n *\n * @returns The KRef tag that `promise` carries.\n */\nfunction getStandinPromiseTag(promise: Promise<unknown>): string {\n const desc = Object.getOwnPropertyDescriptor(promise, toStringTag);\n assert(desc !== undefined, 'promise lacks own @@toStringTag property');\n const kref = desc.value;\n assert.typeof(kref, 'string');\n return kref;\n}\n\n/**\n * Obtain a value serializable via `kser` for a given KRef.\n *\n * @param kref - The KRef string to get a value for.\n * @param iface - Option interface type descriptor string.\n *\n * @returns A `kser` serializable value for `kref`.\n */\nexport function kslot(kref: string, iface: string = 'undefined'): SlotValue {\n assert.typeof(kref, 'string');\n if (iface?.startsWith('Alleged: ')) {\n // Encoder prepends \"Alleged: \" to iface string, but the decoder doesn't strip it\n // Unclear whether it's the decoder or me who is wrong\n // eslint-disable-next-line no-param-reassign\n iface = iface.slice(9);\n }\n if (kref.startsWith('p') || kref.startsWith('kp') || kref.startsWith('rp')) {\n return makeStandinPromise(kref);\n }\n const standinObject = Far(iface, {\n iface: () => iface,\n getKref: () => `${kref}`,\n });\n return standinObject;\n}\n\n/**\n * Obtain the KRef associated with a value that was serialized with `kser`.\n *\n * @param obj - The value of interest.\n *\n * @returns a KRef string for `obj`.\n */\nexport function krefOf(obj: SlotValue): string {\n switch (passStyleOf(obj) as string) {\n case 'promise': {\n return getStandinPromiseTag(obj as Promise<unknown>);\n }\n case 'remotable': {\n const { getKref } = obj as ObjectStandin;\n assert.typeof(getKref, 'function', 'object lacks getKref function');\n return getKref();\n }\n default:\n // When krefOf() is called as part of kmarshal.serialize, marshal\n // will only give it things that are 'remotable' (Promises and the\n // Far objects created by kslot()). When krefOf() is called by\n // kernel code, it ought to throw if 'obj' is not one of the\n // objects created by our kslot().\n return Fail`krefOf requires a promise or remotable`;\n }\n}\n\nconst kmarshal = makeMarshal(krefOf, kslot, {\n serializeBodyFormat: 'smallcaps',\n errorTagging: 'off',\n});\n\n/**\n * Serialize a value in kernel space.\n *\n * @param value - The value to be serialized.\n *\n * @returns a capdata object that can be deserialized with `kunser`.\n */\nexport function kser(value: unknown): CapData<KRef> {\n return kmarshal.toCapData(harden(value as Passable));\n}\n\n/**\n * Deserialize a value that was serialized with `kser`.\n *\n * @param serializedValue -- The value to deserialize.\n *\n * @returns the deserialization of `serializedValue`.\n */\nexport function kunser(serializedValue: CapData<KRef>): unknown {\n return kmarshal.fromCapData(serializedValue);\n}\n\n/**\n * Produce a serialized form of an Error.\n *\n * @param message - The error message to construct the Error with.\n *\n * @returns The resulting error after serialization.\n */\nexport function makeError(message: string): CapData<KRef> {\n assert.typeof(message, 'string');\n return kser(Error(message));\n}\n"]}