From 5fa54f0287b467d3d6baf354a36263a4aa36ec55 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Thu, 25 Apr 2024 10:31:59 -0700 Subject: [PATCH] feat(types): fromCapData is Passable, but unknown is more practical --- packages/captp/src/captp.js | 3 ++- packages/marshal/src/marshal-stringify.js | 2 +- packages/marshal/src/marshal.js | 8 ++++---- packages/marshal/src/types.js | 10 +++++---- packages/marshal/src/types.test-d.ts | 25 ++++++++++++++++++++++- packages/pass-style/src/internal-types.js | 2 +- packages/pass-style/src/passStyleOf.js | 3 --- 7 files changed, 38 insertions(+), 15 deletions(-) diff --git a/packages/captp/src/captp.js b/packages/captp/src/captp.js index 2f68f643ae..91d2b68d9b 100644 --- a/packages/captp/src/captp.js +++ b/packages/captp/src/captp.js @@ -410,6 +410,7 @@ export const makeCapTP = ( epoch, questionID, target, + // @ts-expect-error Type 'unknown' is not assignable to type 'Passable'. method: serialize(harden([null, args])), }); return promise; @@ -425,6 +426,7 @@ export const makeCapTP = ( epoch, questionID, target, + // @ts-expect-error Type 'unknown' is not assignable to type 'Passable'. method: serialize(harden([prop, args])), }); return promise; @@ -493,7 +495,6 @@ export const makeCapTP = ( } // If we imported this slot, mark it as one our peer exported. - // @ts-expect-error map lacks value type return slotToImported.get(recvSlot.add(slot)); } diff --git a/packages/marshal/src/marshal-stringify.js b/packages/marshal/src/marshal-stringify.js index c07a0d52f8..e581cdefed 100644 --- a/packages/marshal/src/marshal-stringify.js +++ b/packages/marshal/src/marshal-stringify.js @@ -44,7 +44,7 @@ harden(stringify); /** * @param {string} str - * @returns {Passable} + * @returns {unknown} */ const parse = str => unserialize( diff --git a/packages/marshal/src/marshal.js b/packages/marshal/src/marshal.js index f49dcc062f..ed4ebc2060 100644 --- a/packages/marshal/src/marshal.js +++ b/packages/marshal/src/marshal.js @@ -234,12 +234,12 @@ export const makeMarshal = ( }; const makeFullRevive = slots => { - /** @type {Map} */ + /** @type {Map} */ const valMap = new Map(); /** * @param {{iface?: string, index: number}} slotData - * @returns {RemotableObject | Promise} + * @returns {PassableCap} */ const decodeSlotCommon = slotData => { const { iface = undefined, index, ...rest } = slotData; @@ -346,7 +346,7 @@ export const makeMarshal = ( const makeDecodeSlotFromSmallcaps = prefix => { /** * @param {string} stringEncoding - * @param {(e: unknown) => Passable} _decodeRecur + * @param {(e: unknown) => PassableCap} _decodeRecur * @returns {RemotableObject | Promise} */ return (stringEncoding, _decodeRecur) => { @@ -404,7 +404,7 @@ export const makeMarshal = ( // which should be considered fixed once we've completed the switch // to smallcaps. assertPassable(result); - return result; + return /** @type {PassableCap} */ (result); }; return harden({ diff --git a/packages/marshal/src/types.js b/packages/marshal/src/types.js index d150190e85..c70818bf34 100644 --- a/packages/marshal/src/types.js +++ b/packages/marshal/src/types.js @@ -1,21 +1,23 @@ // @ts-check export {}; -/** @import {Passable} from '@endo/pass-style' */ +/** @import {Passable, PassableCap} from '@endo/pass-style' */ /** * @template Slot + * @template {PassableCap} [Value=any] * @callback ConvertValToSlot - * @param {import("@endo/pass-style").PassableCap} val + * @param {Value} val * @returns {Slot} */ /** * @template Slot + * @template {PassableCap} [Value=any] * @callback ConvertSlotToVal * @param {Slot} slot * @param {string} [iface] - * @returns {import("@endo/pass-style").PassableCap} + * @returns {Value} */ /** @@ -88,7 +90,7 @@ export {}; /** * @template Slot * @callback ToCapData - * @param {any} val a Passable + * @param {Passable} val * @returns {CapData} */ diff --git a/packages/marshal/src/types.test-d.ts b/packages/marshal/src/types.test-d.ts index 47ff6da6c3..a94dcd420b 100644 --- a/packages/marshal/src/types.test-d.ts +++ b/packages/marshal/src/types.test-d.ts @@ -1,6 +1,11 @@ import { expectType, expectNotType } from 'tsd'; -import type { PrimitiveStyle } from '@endo/pass-style'; +import { + Far, + type PrimitiveStyle, + type RemotableObject, +} from '@endo/pass-style'; +import { makeMarshal } from './marshal.js'; expectType('string'); expectType('number'); @@ -8,3 +13,21 @@ expectType('number'); expectType(1); // @ts-expect-error expectType('str'); + +type KCap = RemotableObject & { getKref: () => string; iface: () => string }; +const valToSlot = (s: KCap) => s.getKref(); +const slotToVal = (s: string) => null as unknown as KCap; +const marshal = makeMarshal(valToSlot, slotToVal); +const cycled = marshal.fromCapData(marshal.toCapData(null as unknown as KCap)); +expectType(cycled); + +const m = makeMarshal(); +type SlottedRemotable = { getBoardId: () => string }; +const foo = Far('foo'); +const foo1 = Far('foo', { getBoardId: () => 'board1' }); +const foo2 = Far('foo', { getBoardId: () => 'board2' }); +const bar = Far('bar'); +const bar1 = Far('bar', { getBoardId: () => 'board1' }); +m.toCapData(harden({ o: foo1 })); +m.toCapData(harden({ o: foo2 })); +m.toCapData(harden({ o: bar1 })); diff --git a/packages/pass-style/src/internal-types.js b/packages/pass-style/src/internal-types.js index 68d8c01435..d3796eb0de 100644 --- a/packages/pass-style/src/internal-types.js +++ b/packages/pass-style/src/internal-types.js @@ -23,6 +23,6 @@ export {}; * `assertValid` still needs to be called to determine if it * actually is valid. * @property {(candidate: any, - * passStyleOfRecur: PassStyleOf + * passStyleOfRecur: (val: any) => PassStyle * ) => void} assertValid */ diff --git a/packages/pass-style/src/passStyleOf.js b/packages/pass-style/src/passStyleOf.js index 8bc5141b06..12d8563561 100644 --- a/packages/pass-style/src/passStyleOf.js +++ b/packages/pass-style/src/passStyleOf.js @@ -168,12 +168,10 @@ const makePassStyleOf = passStyleHelpers => { } for (const helper of passStyleHelpers) { if (helper.canBeValid(inner)) { - // @ts-expect-error XXX helper.assertValid(inner, passStyleOfRecur); return helper.styleName; } } - // @ts-expect-error XXX remotableHelper.assertValid(inner, passStyleOfRecur); return 'remotable'; } @@ -182,7 +180,6 @@ const makePassStyleOf = passStyleHelpers => { Fail`Cannot pass non-frozen objects like ${inner}. Use harden()`; typeof inner.then !== 'function' || Fail`Cannot pass non-promise thenables`; - // @ts-expect-error XXX remotableHelper.assertValid(inner, passStyleOfRecur); return 'remotable'; }