diff --git a/packages/marshal/src/encodePassable.js b/packages/marshal/src/encodePassable.js index 554de133cf..387a88b402 100644 --- a/packages/marshal/src/encodePassable.js +++ b/packages/marshal/src/encodePassable.js @@ -12,7 +12,10 @@ import { /** @typedef {import('@endo/pass-style').PassStyle} PassStyle */ /** @typedef {import('@endo/pass-style').Passable} Passable */ /** @typedef {import('@endo/pass-style').RemotableObject} Remotable */ -/** @template T @typedef {import('@endo/pass-style').CopyRecord} CopyRecord */ +/** + * @template {Passable} [T=Passable] + * @typedef {import('@endo/pass-style').CopyRecord} CopyRecord + */ /** @typedef {import('./types.js').RankCover} RankCover */ const { quote: q, Fail } = assert; diff --git a/packages/pass-style/src/typeGuards.js b/packages/pass-style/src/typeGuards.js index 37ff3d7676..2d2f13e267 100644 --- a/packages/pass-style/src/typeGuards.js +++ b/packages/pass-style/src/typeGuards.js @@ -1,8 +1,14 @@ import { passStyleOf } from './passStyleOf.js'; /** @typedef {import('./types.js').Passable} Passable */ -/** @template T @typedef {import('./types.js').CopyArray} CopyArray */ -/** @template T @typedef {import('./types.js').CopyRecord} CopyRecord */ +/** + * @template {Passable} [T=Passable] + * @typedef {import('./types.js').CopyArray} CopyArray + */ +/** + * @template {Passable} [T=Passable] + * @typedef {import('./types.js').CopyRecord} CopyRecord + */ /** @typedef {import('./types.js').RemotableObject} Remotable */ const { Fail, quote: q } = assert; diff --git a/packages/pass-style/src/types.js b/packages/pass-style/src/types.js index a34714499e..7d187e1096 100644 --- a/packages/pass-style/src/types.js +++ b/packages/pass-style/src/types.js @@ -20,23 +20,26 @@ export {}; /** * @typedef {*} Passable * - * A Passable is acyclic data that can be marshalled. It must be hardened to remain + * A Passable is acyclic data that can be marshalled. It must be hardened to + * remain * stable (even if some components are proxies; see PureData restriction below), * and is classified by PassStyle: * * Atomic primitive values have a PrimitiveStyle (PassStyle - * 'undefined' | 'null' | 'boolean' | 'number' | 'bigint' | 'string' | 'symbol'). + * 'undefined' | 'null' | 'boolean' | 'number' | 'bigint' + * | 'string' | 'symbol'). * * Containers aggregate other Passables into * * sequences as CopyArrays (PassStyle 'copyArray'), or * * string-keyed dictionaries as CopyRecords (PassStyle 'copyRecord'), or * * higher-order types as CopyTaggeds (PassStyle 'tagged'). - * * PassableCaps (PassStyle 'remotable' | 'promise') expose local values to remote - * interaction. - * * As a special case to support system observability, error objects are Passable - * (PassStyle 'error'). + * * PassableCaps (PassStyle 'remotable' | 'promise') expose local values to + * remote interaction. + * * As a special case to support system observability, error objects are + * Passable (PassStyle 'error'). * - * A Passable is essentially a pass-by-copy superstructure with a pass-by-reference - * exit point at the site of each PassableCap (which marshalling represents using - * 'slots'). + * A Passable is essentially a pass-by-copy superstructure with a + * pass-by-reference + * exit point at the site of each PassableCap (which marshalling represents + * using 'slots'). */ /** @@ -50,14 +53,16 @@ export {}; * * A Passable is PureData when its entire data structure is free of PassableCaps * (remotables and promises) and error objects. - * PureData is an arbitrary composition of primitive values into CopyArray and/or + * PureData is an arbitrary composition of primitive values into CopyArray + * and/or * CopyRecord and/or CopyTagged containers (or a single primitive value with no * container), and is fully pass-by-copy. * * This restriction assures absence of side effects and interleaving risks *given* * that none of the containers can be a Proxy instance. * TODO SECURITY BUG we plan to enforce this, giving PureData the same security - * properties as the proposed [Records and Tuples](https://github.com/tc39/proposal-record-tuple). + * properties as the proposed + * [Records and Tuples](https://github.com/tc39/proposal-record-tuple). * * Given this (currently counter-factual) assumption, a PureData value cannot * be used as a communications channel, @@ -82,34 +87,40 @@ export {}; */ /** - * @template {Passable} T + * @template {Passable} [T=Passable] * @typedef {T[]} CopyArray * * A Passable sequence of Passable values. */ /** - * @template {Passable} T + * @template {Passable} [T=Passable] * @typedef {Record} CopyRecord * * A Passable dictionary in which each key is a string and each value is Passable. */ /** + * @template {string} [Tag=string] + * @template {Passable} [Payload=Passable] * @typedef {{ - * [Symbol.toStringTag]: string, - * payload: Passable, + * [Symbol.toStringTag]: Tag, + * payload: Payload, * [passStyle: symbol]: 'tagged' | string, * }} CopyTagged * * A Passable "tagged record" with semantics specific to the tag identified in - * the `[Symbol.toStringTag]` property (such as 'copySet', 'copyBag', or 'copyMap'). - * It must have a property with key equal to the `PASS_STYLE` export and value 'tagged' - * and no other properties except `[Symbol.toStringTag]` and `payload`, - * but TypeScript complains about a declaration like `[PASS_STYLE]: 'tagged'` - * because importing packages do not know what `PASS_STYLE` is + * the `[Symbol.toStringTag]` property (such as 'copySet', 'copyBag', + * or 'copyMap'). + * It must have a property with key equal to the `PASS_STYLE` export and + * value 'tagged' + * and no other properties except `[Symbol.toStringTag]` and `payload`. + * + * TODO + * But TypeScript complains about a declaration like `[PASS_STYLE]: 'tagged'` + * because importing packages do not know what `PASS_STYLE` is, * so we appease it with a looser but less accurate definition - * using symbol index properties. + * using symbol index properties and `| string`. */ /** diff --git a/packages/patterns/src/patterns/internal-types.js b/packages/patterns/src/patterns/internal-types.js index dfba1cbcba..072cac4fe7 100644 --- a/packages/patterns/src/patterns/internal-types.js +++ b/packages/patterns/src/patterns/internal-types.js @@ -1,11 +1,21 @@ /// -/** @typedef {import('@endo/marshal').Passable} Passable */ -/** @typedef {import('@endo/marshal').PassStyle} PassStyle */ -/** @typedef {import('@endo/marshal').CopyTagged} CopyTagged */ -/** @template T @typedef {import('@endo/marshal').CopyRecord} CopyRecord */ -/** @template T @typedef {import('@endo/marshal').CopyArray} CopyArray */ -/** @typedef {import('@endo/marshal').Checker} Checker */ +/** @typedef {import('@endo/pass-style').Passable} Passable */ +/** @typedef {import('@endo/pass-style').PassStyle} PassStyle */ +/** + * @template {string} [Tag=string] + * @template {Passable} [Payload=Passable] + * @typedef {import('@endo/pass-style').CopyTagged} CopyTagged + */ +/** + * @template {Passable} [T=Passable] + * @typedef {import('@endo/pass-style').CopyRecord} CopyRecord + */ +/** + * @template {Passable} [T=Passable] + * @typedef {import('@endo/pass-style').CopyArray} CopyArray + */ +/** @typedef {import('@endo/pass-style').Checker} Checker */ /** @typedef {import('@endo/marshal').RankCompare} RankCompare */ /** @typedef {import('@endo/marshal').RankCover} RankCover */ diff --git a/packages/patterns/src/types.js b/packages/patterns/src/types.js index c56dd06649..2c18776e73 100644 --- a/packages/patterns/src/types.js +++ b/packages/patterns/src/types.js @@ -2,12 +2,22 @@ export {}; -/** @typedef {import('@endo/marshal').Passable} Passable */ -/** @typedef {import('@endo/marshal').PassStyle} PassStyle */ -/** @typedef {import('@endo/marshal').CopyTagged} CopyTagged */ -/** @template T @typedef {import('@endo/marshal').CopyRecord} CopyRecord */ -/** @template T @typedef {import('@endo/marshal').CopyArray} CopyArray */ -/** @typedef {import('@endo/marshal').Checker} Checker */ +/** @typedef {import('@endo/pass-style').Passable} Passable */ +/** @typedef {import('@endo/pass-style').PassStyle} PassStyle */ +/** + * @template {string} [Tag=string] + * @template {Passable} [Payload=Passable] + * @typedef {import('@endo/pass-style').CopyTagged} CopyTagged + */ +/** + * @template {Passable} [T=Passable] + * @typedef {import('@endo/pass-style').CopyRecord} CopyRecord + */ +/** + * @template {Passable} [T=Passable] + * @typedef {import('@endo/pass-style').CopyArray} CopyArray + */ +/** @typedef {import('@endo/pass-style').Checker} Checker */ /** @typedef {import('@endo/marshal').RankCompare} RankCompare */ /** @typedef {import('@endo/marshal').RankCover} RankCover */ @@ -101,10 +111,7 @@ export {}; /** * @template {Key} [K=Key] - * @typedef {CopyTagged & { - * [Symbol.toStringTag]: 'copySet', - * payload: Array, - * }} CopySet + * @typedef {CopyTagged<'copySet', K[]>} CopySet * * A Passable collection of Keys that are all mutually distinguishable * according to the key distributed equality semantics exposed by `keyEQ`. @@ -112,10 +119,7 @@ export {}; /** * @template {Key} [K=Key] - * @typedef {CopyTagged & { - * [Symbol.toStringTag]: 'copyBag', - * payload: Array<[K, bigint]>, - * }} CopyBag + * @typedef {CopyTagged<'copyBag', [K, bigint][]>} CopyBag * * A Passable collection of entries with Keys that are all mutually distinguishable * according to the key distributed equality semantics exposed by `keyEQ`, @@ -125,10 +129,7 @@ export {}; /** * @template {Key} [K=Key] * @template {Passable} [V=Passable] - * @typedef {CopyTagged & { - * [Symbol.toStringTag]: 'copyMap', - * payload: { keys: Array, values: Array }, - * }} CopyMap + * @typedef {CopyTagged<'copyMap', { keys: K[], values: V[] }>} CopyMap * * A Passable collection of entries with Keys that are all mutually distinguishable * according to the key distributed equality semantics exposed by `keyEQ`, @@ -144,9 +145,7 @@ export {}; // TODO: enumerate Matcher tag values? /** - * @typedef {CopyTagged & { - * [Symbol.toStringTag]: `match:${string}`, - * }} Matcher + * @typedef {CopyTagged<`match:${string}`, Passable>} Matcher * * A Pattern representing the predicate characterizing a category of Passables, * such as strings or 8-bit unsigned integer numbers or CopyArrays of Remotables. @@ -509,10 +508,7 @@ export {}; /** * @template {Record} [T=Record] - * @typedef {CopyTagged & { - * [Symbol.toStringTag]: 'guard:interfaceGuard', - * payload: InterfaceGuardPayload, - * }} InterfaceGuard + * @typedef {CopyTagged<'guard:interfaceGuard', InterfaceGuardPayload>}InterfaceGuard */ /** @@ -581,10 +577,7 @@ export {}; */ /** - * @typedef {CopyTagged & { - * [Symbol.toStringTag]: 'guard:methodGuard', - * payload: MethodGuardPayload, - * }} MethodGuard + * @typedef {CopyTagged<'guard:methodGuard', MethodGuardPayload>} MethodGuard */ /** @@ -594,10 +587,7 @@ export {}; */ /** - * @typedef {CopyTagged & { - * [Symbol.toStringTag]: 'guard:awaitArgGuard' - * payload: AwaitArgGuardPayload, - * }} AwaitArgGuard + * @typedef {CopyTagged<'guard:awaitArgGuard', AwaitArgGuardPayload>} AwaitArgGuard */ /** @typedef {AwaitArgGuard | Pattern} ArgGuard */ diff --git a/packages/patterns/test/test-copyBag.js b/packages/patterns/test/test-copyBag.js index 0666e7abda..49dc555084 100644 --- a/packages/patterns/test/test-copyBag.js +++ b/packages/patterns/test/test-copyBag.js @@ -204,7 +204,7 @@ test('matching', t => { test('types', t => { const bag = makeCopyBag([['a', 1n]]); - // TODO: restore at-ts-expect-error should not be 'any' + // @ts-expect-error No 'foo' in [string, bigint][] bag.payload.foo; const [str, count] = bag.payload[0]; str.concat; // string