Skip to content

Commit

Permalink
refactor: Prepare for better guard typing from endo
Browse files Browse the repository at this point in the history
  • Loading branch information
erights committed Aug 29, 2023
1 parent 1eed398 commit a35b833
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 120 deletions.
8 changes: 4 additions & 4 deletions packages/ERTP/src/issuerKit.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ export const hasIssuer = baggage => baggage.has(INSTANCE_KEY);
* `displayInfo` gives information to the UI on how to display the amount.
* @param {Baggage} issuerBaggage
* @param {string} name
* @param {K} [assetKind=AssetKind.NAT]
* @param {AdditionalDisplayInfo} [displayInfo={}]
* @param {K} [assetKind]
* @param {AdditionalDisplayInfo} [displayInfo]
* @param {ShutdownWithFailure} [optShutdownWithFailure] If this issuer fails in
* the middle of an atomic action (which btw should never happen), it
* potentially leaves its ledger in a corrupted state. If this function was
Expand Down Expand Up @@ -164,8 +164,8 @@ harden(makeDurableIssuerKit);
*
* `displayInfo` gives information to the UI on how to display the amount.
* @param {string} name
* @param {K} [assetKind='nat']
* @param {AdditionalDisplayInfo} [displayInfo={}]
* @param {K} [assetKind]
* @param {AdditionalDisplayInfo} [displayInfo]
* @param {ShutdownWithFailure} [optShutdownWithFailure] If this issuer fails in
* the middle of an atomic action (which btw should never happen), it
* potentially leaves its ledger in a corrupted state. If this function was
Expand Down
5 changes: 5 additions & 0 deletions packages/ERTP/src/payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
import { initEmpty } from '@agoric/store';
import { prepareExoClass } from '@agoric/vat-data';

/** @typedef {import('@endo/patterns').MethodGuard} MethodGuard */
/**
* @template {Record<string | symbol, MethodGuard>} [T=Record<string | symbol, MethodGuard>]
* @typedef {import('@endo/patterns').InterfaceGuard<T>} InterfaceGuard
*/
/** @typedef {import('@agoric/vat-data').Baggage} Baggage */

/**
Expand Down
5 changes: 5 additions & 0 deletions packages/ERTP/src/types-ambient.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

/// <reference types="ses"/>

/**
* @template {Key} [K=Key]
* @typedef {import('@endo/patterns').CopyBag<K>} CopyBag
*/

/**
* @template {AssetKind} [K=AssetKind]
* @typedef {object} Amount Amounts are descriptions of digital assets,
Expand Down
2 changes: 2 additions & 0 deletions packages/store/src/stores/store-utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Far } from '@endo/marshal';
import { M, matches } from '@endo/patterns';

/** @typedef {import('@endo/marshal').RankCompare} RankCompare */

const { Fail, quote: q } = assert;

// TODO: Undate `@endo/patterns` to export the original, and delete the
Expand Down
110 changes: 18 additions & 92 deletions packages/store/src/types.js
Original file line number Diff line number Diff line change
@@ -1,118 +1,44 @@
/// <reference types="ses"/>

/** @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<T>} CopyRecord */
/** @template T @typedef {import('@endo/marshal').CopyArray<T>} CopyArray */
/** @typedef {import('@endo/marshal').Checker} Checker */
/** @typedef {import('@endo/marshal/src/rankOrder').RankCompare} RankCompare */
/** @typedef {import('@endo/marshal/src/rankOrder').RankComparison} RankComparison */

// /////////////////////////////////////////////////////////////////////////////
// Placeholder redundant types, to be imported from `@endo/patterns` instead.

// TODO placeholder. Figure out how to import from `@endo/patterns` instead
/** @typedef {Passable} Key */

// TODO placeholder. Figure out how to import from `@endo/patterns` instead
/** @typedef {Passable} Pattern */

// TODO placeholder. Figure out how to import from `@endo/patterns` instead
/**
* @template {Key} [K=Key]
* @typedef {CopyTagged & {
* [Symbol.toStringTag]: 'copySet';
* payload: K[];
* }} CopySet
* Note TODO https://github.com/endojs/endo/issues/1488
*
* @typedef {import('@endo/pass-style').Passable} Passable
*/

// TODO placeholder. Figure out how to import from `@endo/patterns` instead
/** @typedef {import('@endo/pass-style').CopyTagged} CopyTagged */
/** @typedef {import('@endo/patterns').Pattern} Pattern */
/** @typedef {import('@endo/patterns').Key} Key */
/**
* @template {Key} [K=Key]
* @typedef {CopyTagged & {
* [Symbol.toStringTag]: 'copyBag';
* payload: [K, bigint][];
* }} CopyBag
* @typedef {import('@endo/patterns').CopySet<K>} CopySet
*/

// TODO placeholder. Figure out how to import from `@endo/patterns` instead
/**
* @template {Key} [K=Key]
* @template {Passable} [V=Passable]
* @typedef {CopyTagged & {
* [Symbol.toStringTag]: 'copyMap';
* payload: { keys: K[]; values: V[] };
* }} CopyMap
*/

// TODO placeholder. Figure out how to import from `@endo/patterns` instead
/**
* @typedef {object} GuardMakers
* @property {<M extends Record<any, any>>(
* interfaceName: string,
* methodGuards: M,
* options?: { sloppy?: boolean },
* ) => InterfaceGuard} interface
* @property {(...argGuards: ArgGuard[]) => MethodGuardMaker} call Guard a
* synchronous call
* @property {(...argGuards: ArgGuard[]) => MethodGuardMaker} callWhen Guard an
* async call
* @property {(argGuard: ArgGuard) => ArgGuard} await Guard an await
* @typedef {import('@endo/patterns').CopyMap<K, V>} CopyMap
*/

// TODO placeholder. Figure out how to import from `@endo/patterns` instead
/** @typedef {(...args: any[]) => any} Method */

// TODO placeholder. Figure out how to import from `@endo/patterns` instead
/**
* @typedef {{
* klass: 'Interface';
* interfaceName: string;
* methodGuards: Record<string | symbol, MethodGuard>;
* sloppy?: boolean;
* }} InterfaceGuard
*/

// TODO placeholder. Figure out how to import from `@endo/patterns` instead
/** @typedef {any} MethodGuardMaker */

// TODO placeholder. Figure out how to import from `@endo/patterns` instead
/**
* @typedef {{
* klass: 'methodGuard';
* callKind: 'sync' | 'async';
* returnGuard: unknown;
* }} MethodGuard
*/

// TODO placeholder. Figure out how to import from `@endo/patterns` instead
/** @typedef {any} ArgGuard */

// /////////////////////////////////////////////////////////////////////////////

/**
* @typedef {object} StoreOptions Of the dimensions on which KeyedStores can
* differ, we only represent a few of them as standard options. A given store
* maker should document which options it supports, as well as its positions
* on dimensions for which it does not support options.
* @property {boolean} [longLived=true] Which way to optimize a weak store. True
* @property {boolean} [longLived] Which way to optimize a weak store. True
* means that we expect this weak store to outlive most of its keys, in which
* case we internally may use a JavaScript `WeakMap`. Otherwise we internally
* may use a JavaScript `Map`. Defaults to true, so please mark short lived
* stores explicitly.
* @property {boolean} [durable=false] The contents of this store survive
* termination of its containing process, allowing for restart or upgrade but
* at the cost of forbidding storage of references to ephemeral data. Defaults
* to false.
* @property {boolean} [fakeDurable=false] This store pretends to be a durable
* store but does not enforce that the things stored in it actually be
* themselves durable (whereas an actual durable store would forbid storage of
* such items). This is in service of allowing incremental transition to use
* of durable stores, to enable normal operation and testing when some stuff
* @property {boolean} [durable] The contents of this store survive termination
* of its containing process, allowing for restart or upgrade but at the cost
* of forbidding storage of references to ephemeral data. Defaults to false.
* @property {boolean} [fakeDurable] This store pretends to be a durable store
* but does not enforce that the things stored in it actually be themselves
* durable (whereas an actual durable store would forbid storage of such
* items). This is in service of allowing incremental transition to use of
* durable stores, to enable normal operation and testing when some stuff
* intended to eventually be durable has not yet been made durable. A store
* marked as fakeDurable will appear to operate normally but any attempt to
* upgrade its containing vat will fail with an error.
* upgrade its containing vat will fail with an error. Defaults to false.
* @property {Pattern} [keyShape]
* @property {Pattern} [valueShape]
*/
Expand Down
34 changes: 29 additions & 5 deletions packages/swingset-liveslots/src/vatDataTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@
* Behavior is a description when defining a kind of what facets it will have.
* For the non-multi defineKind, there is just one facet so it doesn't have a key.
*/
import type { InterfaceGuard, Pattern } from '@endo/patterns';
import type {
InterfaceGuard,
MapStore,
Pattern,
SetStore,
StoreOptions,
WeakMapStore,
WeakSetStore,
} from '@agoric/store';

// TODO should be moved into @endo/patterns and eventually imported here
// instead of this local definition.
export type InterfaceGuardKit = Record<string, InterfaceGuard>;

export type { MapStore, Pattern };

// This needs `any` values. If they were `unknown`, code that uses Baggage
Expand Down Expand Up @@ -97,15 +100,36 @@ export type DefineKindOptions<C> = {

/**
* Intended for internal use only.
* Only applicable if this is a class kind. A class kit kind should use
* `interfaceGuardKit` instead.
*
* If an `interfaceGuard` is provided, then the raw methods passed alongside
* it are wrapped by a function that first checks that this method's guard
* pattern is satisfied before calling the raw method.
*
* In `defineDurableKind` and its siblings, this defaults to off.
* `prepareExoClass` use this internally to protect their raw class methods
* In `defineDurableKind` and its siblings, this defaults to `undefined`.
* Exo classes use this internally to protect their raw class methods
* using the provided interface.
* In absence, an exo is protected anyway, while a bare kind is
* not (detected by `!thisfulMethods`),
*/
interfaceGuard?: InterfaceGuard;

/**
* Intended for internal use only.
* Only applicable if this is a class kit kind. A class kind should use
* `interfaceGuard` instead.
*
* If an `interfaceGuardKit` is provided, then each member of the
* interfaceGuardKit is used to guard the corresponding facet of the
* class kit.
*
* In `defineDurableKindMulti` and its siblings, this defaults to `undefined`.
* Exo class kits use this internally to protect their facets.
* In absence, an exo is protected anyway, while a bare kind is
* not (detected by `!thisfulMethods`),
*/
interfaceGuard?: InterfaceGuard<unknown>;
interfaceGuardKit?: InterfaceGuardKit;
};

export type VatData = {
Expand Down
11 changes: 10 additions & 1 deletion packages/swingset-liveslots/src/virtualObjectManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@ export const makeVirtualObjectManager = (
stateShape = undefined,
thisfulMethods = false,
interfaceGuard = undefined,
interfaceGuardKit = undefined,
} = options;

const statePrototype = {}; // Not frozen yet
Expand All @@ -739,11 +740,19 @@ export const makeVirtualObjectManager = (
switch (assessFacetiousness(behavior)) {
case 'one': {
assert(!multifaceted);
interfaceGuardKit === undefined ||
Fail`Use an interfaceGuard, not interfaceGuardKit, to protect class ${q(
tag,
)}`;
proposedFacetNames = undefined;
break;
}
case 'many': {
assert(multifaceted);
interfaceGuard === undefined ||
Fail`Use an interfaceGuardKit, not an interfaceGuard, to protect class kit ${q(
tag,
)}`;
proposedFacetNames = ownKeys(behavior).sort();
break;
}
Expand Down Expand Up @@ -954,7 +963,7 @@ export const makeVirtualObjectManager = (
makeContextProviderKit(contextCache, getSlotForVal, facetNames),
behavior,
thisfulMethods,
interfaceGuard,
interfaceGuardKit,
);
} else {
proto = defendPrototype(
Expand Down
3 changes: 2 additions & 1 deletion packages/time/src/timeMath.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import { RelativeTimeRecordShape, TimestampRecordShape } from './typeGuards.js';

const { Fail, quote: q } = assert;
/**
* @typedef {import('@endo/marshal').RankComparison} RankComparison
*
* @typedef {import('./types').TimerBrand} TimerBrand
* @typedef {import('./types').Timestamp} Timestamp
* @typedef {import('./types').RelativeTime} RelativeTime
* @typedef {import('./types').RelativeTimeValue} RelativeTimeValue
* @typedef {import('./types').TimestampValue} TimestampValue
* @typedef {import('./types').TimeMathType} TimeMathType
*
*/

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/time/src/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable no-use-before-define, no-undef */
import type { ERef } from '@endo/eventual-send';

import type { RankComparison } from '@agoric/store';
import type { RankComparison } from '@endo/marshal';

/// <reference types="@agoric/notifier/src/types.js"/>

Expand Down
Loading

0 comments on commit a35b833

Please sign in to comment.