Skip to content

Commit

Permalink
convert types.js to .d.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed Jan 10, 2024
1 parent 4929b9a commit 05f133e
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 186 deletions.
2 changes: 2 additions & 0 deletions packages/pass-style/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# typescript-eslint errors on this because it has no typecheck information, because tsc produced it for the `types.d.ts` instead
/src/types.js
163 changes: 163 additions & 0 deletions packages/pass-style/src/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/* eslint-disable no-use-before-define */
import { PASS_STYLE } from './passStyle-helpers.js';

export type PrimitiveStyle =
| 'undefined'
| 'null'
| 'boolean'
| 'number'
| 'bigint'
| 'string'
| 'symbol';
export type ContainerStyle = 'copyRecord' | 'copyArray' | 'tagged';
export type PassStyle =
| PrimitiveStyle
| ContainerStyle
| 'remotable'
| 'error'
| 'promise';
export type PassStyled<S extends string> = {
[PASS_STYLE]: S;
};
export type ExtractStyle<P extends PassStyled<any>> = P[typeof PASS_STYLE];
export type PassByCopy =
| import('type-fest').Primitive
| Error
| any[]
| CopyRecord
| CopyTagged;
export type PassByRef =
| RemotableObject
| Promise<RemotableObject>
| Promise<PassByCopy>;
/**
* 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').
* * Containers aggregate other Passables into
* * sequences as CopyArrays (PassStyle 'copyArray'), or
* * string-keyed dictionaries as CopyRecords (PassStyle 'copyRecord'), or
* * higher-level 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').
*
* 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').
*/
export type Passable = PassByCopy | PassByRef;
export type PassStyleOf = {
(p: undefined): 'undefined';
(p: string): 'string';
(p: boolean): 'boolean';
(p: number): 'number';
(p: bigint): 'bigint';
(p: symbol): 'symbol';
(p: null): 'null';
(p: Promise<any>): 'promise';
(p: Error): 'error';
(p: CopyTagged): 'tagged';
(p: any[]): 'copyArray';
(p: Iterable<any>): 'remotable';
(p: Iterator<any, any, undefined>): 'remotable';
<T extends PassStyled<any>>(p: T): ExtractStyle<T>;
(p: { [key: string]: any }): 'copyRecord';
(p: any): PassStyle;
};
/**
* 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
* 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).
*
* Given this (currently counter-factual) assumption, a PureData value cannot
* be used as a communications channel,
* and can therefore be safely shared with subgraphs that should not be able
* to communicate with each other.
* Without that assumption, such a guarantee requires a marshal-unmarshal round
* trip (as exists between vats) to produce data structures disconnected from
* any potential proxies.
*/
export type PureData = Passable;
export type TaggedRecord<S extends string, I extends string> = PassStyled<S> & {
[Symbol.toStringTag]: I;
};
/**
* An object marked as remotely accessible using the `Far` or `Remotable`
* functions, or a local presence representing such a remote object.
*
* A more natural name would be Remotable, but that could be confused with the
* value of the `Remotable` export of this module (a function).
*/
export type RemotableObject<I extends string = string> = TaggedRecord<
'remotable',
I
>;
/**
* The authority-bearing leaves of a Passable's pass-by-copy superstructure.
*/
export type PassableCap = Promise<any> | RemotableObject;
/**
* A Passable sequence of Passable values.
*/
export type CopyArray<T extends Passable = any> = T[];
/**
* A Passable dictionary in which each key is a string and each value is Passable.
*/
export type CopyRecord<T extends Passable = any> = Record<string, T>;
/**
* 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`.
*/
export type CopyTagged<
Tag extends string = string,
Payload extends Passable = any,
> = TaggedRecord<'tagged', Tag> & {
payload: Payload;
};
/**
* This is an interface specification.
* For now, it is just a string, but will eventually be `PureData`. Either
* way, it must remain pure, so that it can be safely shared by subgraphs that
* are not supposed to be able to communicate.
*/
export type InterfaceSpec = string;
/**
* Internal to a useful pattern for writing checking logic
* (a "checkFoo" function) that can be used to implement a predicate
* (an "isFoo" function) or a validator (an "assertFoo" function).
*
* * A predicate ideally only returns `true` or `false` and rarely throws.
* * A validator throws an informative diagnostic when the predicate
* would have returned `false`, and simply returns `undefined` normally
* when the predicate would have returned `true`.
* * The internal checking function that they share is parameterized by a
* `Checker` that determines how to proceed with a failure condition.
* Predicates pass in an identity function as checker. Validators
* pass in `assertChecker` which is a trivial wrapper around `assert`.
*
* See the various uses for good examples.
*/
export type Checker = (
cond: boolean,
details?: import('ses').Details | undefined,
) => boolean;
188 changes: 2 additions & 186 deletions packages/pass-style/src/types.js
Original file line number Diff line number Diff line change
@@ -1,189 +1,5 @@
/* eslint-disable no-unused-vars */
/** @file Empty twin for .d.ts */
/* eslint-disable */
import { PASS_STYLE } from './passStyle-helpers.js';

export {};

/**
* @typedef { 'undefined' | 'null' |
* 'boolean' | 'number' | 'bigint' | 'string' | 'symbol'
* } PrimitiveStyle
*/

/** @typedef {'copyRecord' | 'copyArray' | 'tagged'} ContainerStyle */

/**
* @typedef { PrimitiveStyle |
* ContainerStyle |
* 'remotable' |
* 'error' | 'promise'
* } PassStyle
*/

/**
* @template {string} S style
* @typedef {{ [PASS_STYLE]: S }} PassStyled
*/

/**
* @template {PassStyled<any>} P
* @typedef {P[typeof PASS_STYLE]} ExtractStyle
*/

/** @typedef {import('type-fest').Primitive | Error | CopyArray | CopyRecord | CopyTagged } PassByCopy */
/** @typedef {RemotableObject | Promise<RemotableObject> | Promise<PassByCopy> } PassByRef */

/**
* @typedef {PassByCopy | PassByRef} Passable
*
* 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').
* * Containers aggregate other Passables into
* * sequences as CopyArrays (PassStyle 'copyArray'), or
* * string-keyed dictionaries as CopyRecords (PassStyle 'copyRecord'), or
* * higher-level 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').
*
* 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').
*/

// Cases match in sequence. The final case 'remotable' is for a Passable that isn't one of the others.
/**
* @typedef {{
* (p: undefined): 'undefined';
* (p: string): 'string';
* (p: boolean): 'boolean';
* (p: number): 'number';
* (p: bigint): 'bigint';
* (p: symbol): 'symbol';
* (p: null): 'null';
* (p: Promise): 'promise';
* (p: Error): 'error';
* (p: CopyTagged): 'tagged';
* (p: Array): 'copyArray';
* (p: Iterable): 'remotable';
* (p: Iterator): 'remotable';
* <T extends PassStyled<any>>(p: T): ExtractStyle<T>
* (p: {[key: string]: any}): 'copyRecord';
* (p: RemotableObject): 'remotable';
* (p: any): PassStyle;
* }} PassStyleOf
*/

/**
* @typedef {Passable} PureData
*
* 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
* 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).
*
* Given this (currently counter-factual) assumption, a PureData value cannot
* be used as a communications channel,
* and can therefore be safely shared with subgraphs that should not be able
* to communicate with each other.
* Without that assumption, such a guarantee requires a marshal-unmarshal round
* trip (as exists between vats) to produce data structures disconnected from
* any potential proxies.
*/

/**
* @template {string} S pass style
* @template {InterfaceSpec} I interface tag
* @typedef {PassStyled<S> & {[Symbol.toStringTag]: I}} TaggedRecord
*/

/**
* @template {InterfaceSpec} [I=string]
* @typedef {TaggedRecord<'remotable', I>} RemotableObject
*
* An object marked as remotely accessible using the `Far` or `Remotable`
* functions, or a local presence representing such a remote object.
*
* A more natural name would be Remotable, but that could be confused with the
* value of the `Remotable` export of this module (a function).
*/

/**
* @typedef {Promise | RemotableObject} PassableCap
*
* The authority-bearing leaves of a Passable's pass-by-copy superstructure.
*/

// TODO a better default type. Ideally it's Passable, but that causes a circular definition.
/**
* @template {Passable} [T=object]
* @typedef {T[]} CopyArray
*
* A Passable sequence of Passable values.
*/

// TODO a better default type. Ideally it's Passable, but that causes a circular definition.
/**
* @template {Passable} [T=object]
* @typedef {Record<string, T>} CopyRecord
*
* A Passable dictionary in which each key is a string and each value is Passable.
*/

/**
* @template {InterfaceSpec} [Tag=string]
* @template {Passable} [Payload=any]
* @typedef {TaggedRecord<'tagged', Tag> & {
* payload: Payload,
* }} 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`.
*/

/**
* @typedef {string} InterfaceSpec
* This is an interface specification.
* For now, it is just a string, but will eventually be `PureData`. Either
* way, it must remain pure, so that it can be safely shared by subgraphs that
* are not supposed to be able to communicate.
*/

/**
* @callback Checker
* Internal to a useful pattern for writing checking logic
* (a "checkFoo" function) that can be used to implement a predicate
* (an "isFoo" function) or a validator (an "assertFoo" function).
*
* * A predicate ideally only returns `true` or `false` and rarely throws.
* * A validator throws an informative diagnostic when the predicate
* would have returned `false`, and simply returns `undefined` normally
* when the predicate would have returned `true`.
* * The internal checking function that they share is parameterized by a
* `Checker` that determines how to proceed with a failure condition.
* Predicates pass in an identity function as checker. Validators
* pass in `assertChecker` which is a trivial wrapper around `assert`.
*
* See the various uses for good examples.
* @param {boolean} cond
* @param {import('ses').Details} [details]
* @returns {boolean}
*/

0 comments on commit 05f133e

Please sign in to comment.