@agoric/base-zone 0.1.1-orchestration-dev-096c4e8.0 → 0.1.1-u17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,3 +2,18 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ### 0.1.1-u17.0 (2024-09-17)
7
+
8
+
9
+ ### Features
10
+
11
+ * **base-zone:** add `zone.watchPromise` ([9ce80d0](https://github.com/Agoric/agoric-sdk/commit/9ce80d06c0a56471d2da9f372b0b2d93d31d159a))
12
+ * **base-zone:** alt revocable api using amplifier ([#8977](https://github.com/Agoric/agoric-sdk/issues/8977)) ([5cdf6e3](https://github.com/Agoric/agoric-sdk/commit/5cdf6e3a8b4fbb5cb8e276e6efeec65d9c3d6623))
13
+ * **base-zone:** new package ([b7bc677](https://github.com/Agoric/agoric-sdk/commit/b7bc677238eee5969ac0a95dc066434ef676216e))
14
+ * **watchUtils:** handle non-storables ([8c27c67](https://github.com/Agoric/agoric-sdk/commit/8c27c6725ba7ef4b71d3ab0ccfdbddd755bcd926))
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * **base-zone,zone:** import `isPassable` from @endo/pass-style ([#9230](https://github.com/Agoric/agoric-sdk/issues/9230)) ([fbd8633](https://github.com/Agoric/agoric-sdk/commit/fbd8633ae9f8420a589dd9bc32925418f2dde060))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/base-zone",
3
- "version": "0.1.1-orchestration-dev-096c4e8.0+096c4e8",
3
+ "version": "0.1.1-u17.0",
4
4
  "description": "Allocation zone abstraction library and heap implementation",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/Agoric/agoric-sdk",
@@ -27,27 +27,28 @@
27
27
  "author": "Agoric",
28
28
  "license": "Apache-2.0",
29
29
  "dependencies": {
30
- "@agoric/store": "0.9.3-orchestration-dev-096c4e8.0+096c4e8",
31
- "@endo/common": "^1.1.0",
32
- "@endo/exo": "^1.2.1",
33
- "@endo/far": "^1.0.4",
34
- "@endo/pass-style": "^1.2.0",
35
- "@endo/patterns": "^1.2.0"
30
+ "@agoric/store": "^0.9.3-u17.0",
31
+ "@endo/common": "^1.2.5",
32
+ "@endo/errors": "^1.2.5",
33
+ "@endo/exo": "^1.5.3",
34
+ "@endo/far": "^1.1.5",
35
+ "@endo/pass-style": "^1.4.3",
36
+ "@endo/patterns": "^1.4.3"
36
37
  },
37
38
  "devDependencies": {
38
- "@endo/init": "^1.0.4",
39
- "@endo/ses-ava": "^1.1.2",
39
+ "@endo/init": "^1.1.4",
40
+ "@endo/ses-ava": "^1.2.5",
40
41
  "ava": "^5.3.0"
41
42
  },
42
43
  "publishConfig": {
43
44
  "access": "public"
44
45
  },
45
46
  "engines": {
46
- "node": ">=14.15.0"
47
+ "node": "^18.12 || ^20.9"
47
48
  },
48
49
  "ava": {
49
50
  "files": [
50
- "test/**/test-*.js"
51
+ "test/**/*.test.*"
51
52
  ],
52
53
  "require": [
53
54
  "@endo/init/debug.js"
@@ -56,7 +57,7 @@
56
57
  "workerThreads": false
57
58
  },
58
59
  "typeCoverage": {
59
- "atLeast": 89.25
60
+ "atLeast": 91.4
60
61
  },
61
- "gitHead": "096c4e8fce80e9a509b0e1a30fda11736c4570e1"
62
+ "gitHead": "515c4c0efccfc91b97da30037c10fc4b076851e2"
62
63
  }
package/src/exports.d.ts CHANGED
@@ -5,5 +5,4 @@
5
5
  // Types exposed from modules.
6
6
  //
7
7
 
8
- // @ts-expect-error TS1383: Only named exports may use 'export type'.
9
8
  export type * from './types.js';
package/src/heap.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export function makeHeapZone(baseLabel?: string | undefined): import('./types.js').Zone;
1
+ export function makeHeapZone(baseLabel?: string | undefined): import("./types.js").Zone;
2
2
  //# sourceMappingURL=heap.d.ts.map
package/src/heap.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"heap.d.ts","sourceRoot":"","sources":["heap.js"],"names":[],"mappings":"AAmCO,8DAFM,OAAO,YAAY,EAAE,IAAI,CA2BrC"}
1
+ {"version":3,"file":"heap.d.ts","sourceRoot":"","sources":["heap.js"],"names":[],"mappings":"AAmCO,8DAFM,OAAO,YAAY,EAAE,IAAI,CA4BrC"}
package/src/heap.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
  // @jessie-check
3
3
 
4
- import { Far } from '@endo/far';
4
+ import { Far, isPassable } from '@endo/pass-style';
5
5
  import { makeExo, defineExoClass, defineExoClassKit } from '@endo/exo';
6
6
  import {
7
7
  makeScalarMapStore,
@@ -12,7 +12,7 @@ import {
12
12
 
13
13
  import { makeOnceKit } from './make-once.js';
14
14
  import { agoricVatDataKeys as keys } from './keys.js';
15
- import { isPassable } from './is-passable.js';
15
+ import { watchPromise } from './watch-promise.js';
16
16
 
17
17
  /**
18
18
  * @type {import('./types.js').Stores}
@@ -50,6 +50,7 @@ export const makeHeapZone = (baseLabel = 'heapZone') => {
50
50
  subZone: wrapProvider(makeSubZone),
51
51
 
52
52
  makeOnce,
53
+ watchPromise,
53
54
  detached: detachedHeapStores.detached,
54
55
  isStorable: detachedHeapStores.isStorable,
55
56
 
package/src/index.d.ts CHANGED
@@ -2,4 +2,5 @@ export * from "./exports.js";
2
2
  export * from "./make-once.js";
3
3
  export * from "./keys.js";
4
4
  export * from "./is-passable.js";
5
+ export * from "./watch-promise.js";
5
6
  //# sourceMappingURL=index.d.ts.map
package/src/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  // @jessie-check
2
2
 
3
+ /// <reference types="@agoric/store/exported.js" />
4
+
3
5
  // eslint-disable-next-line import/export
4
6
  export * from './exports.js';
5
7
 
@@ -7,3 +9,4 @@ export * from './exports.js';
7
9
  export * from './make-once.js';
8
10
  export * from './keys.js';
9
11
  export * from './is-passable.js';
12
+ export * from './watch-promise.js';
@@ -1,2 +1,2 @@
1
- export function isPassable(specimen: any): specimen is any;
1
+ export function isPassable(specimen: any): specimen is Passable;
2
2
  //# sourceMappingURL=is-passable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"is-passable.d.ts","sourceRoot":"","sources":["is-passable.js"],"names":[],"mappings":"AAcO,qCAHI,GAAG,mBAWb"}
1
+ {"version":3,"file":"is-passable.d.ts","sourceRoot":"","sources":["is-passable.js"],"names":[],"mappings":"AAOO,qCAHI,GAAG,GACD,QAAQ,IAAI,QAAQ,CAE6B"}
@@ -1,23 +1,8 @@
1
- import { passStyleOf } from '@endo/pass-style';
1
+ import { isPassable as realIsPassable } from '@endo/pass-style';
2
2
 
3
3
  /**
4
- * Is `specimen` Passable? This returns true iff `passStyleOf(specimen)`
5
- * returns a string. This returns `false` iff `passStyleOf(specimen)` throws.
6
- * Under no normal circumstance should `isPassable(specimen)` throw.
7
- *
8
- * TODO implement an isPassable that does not rely on try/catch, and
9
- * move it to @endo/pass-style.
10
- * This implementation is just a standin until then
11
- *
4
+ * @deprecated Import `isPassable` directly from `@endo/pass-style`
12
5
  * @param {any} specimen
13
6
  * @returns {specimen is Passable}
14
7
  */
15
- export const isPassable = specimen => {
16
- try {
17
- // In fact, it never returns undefined. It either returns a
18
- // string or throws.
19
- return passStyleOf(specimen) !== undefined;
20
- } catch (_) {
21
- return false;
22
- }
23
- };
8
+ export const isPassable = specimen => realIsPassable(specimen);
package/src/keys.d.ts CHANGED
@@ -3,5 +3,5 @@
3
3
  *
4
4
  * @type {import('./types.js').KeyMakers}
5
5
  */
6
- export const agoricVatDataKeys: import('./types.js').KeyMakers;
6
+ export const agoricVatDataKeys: import("./types.js").KeyMakers;
7
7
  //# sourceMappingURL=keys.d.ts.map
@@ -1,5 +1,5 @@
1
- export function makeOnceKit(debugName: string, stores: import('./types.js').Stores, backingStore?: any): {
1
+ export function makeOnceKit(debugName: string, stores: import("./types.js").Stores, backingStore?: globalThis.MapStore<string, any> | undefined): {
2
2
  makeOnce: <V>(key: string, maker: (key: string) => V) => V;
3
- wrapProvider: <T extends (key: string, ...rest: unknown[]) => any>(provider: T, labelToKeys?: ((label: string) => string[]) | undefined) => T;
3
+ wrapProvider: <T extends (key: string, ...rest: any[]) => any>(provider: T, labelToKeys?: ((label: string) => string[]) | undefined) => T;
4
4
  };
5
5
  //# sourceMappingURL=make-once.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"make-once.d.ts","sourceRoot":"","sources":["make-once.js"],"names":[],"mappings":"AAYO,uCAJI,MAAM,UACN,OAAO,YAAY,EAAE,MAAM;uBA0DzB,MAAM,eACA,MAAM;mCA/BH,MAAM,WAAW,OAAO,EAAE,KAAK,GAAG,sCAEnC,MAAM,KAAK,MAAM,EAAE;EA6CvC"}
1
+ {"version":3,"file":"make-once.d.ts","sourceRoot":"","sources":["make-once.js"],"names":[],"mappings":"AAYO,uCAJI,MAAM,UACN,OAAO,YAAY,EAAE,MAAM;eAyDvB,CAAC,OACH,MAAM,SACN,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,KAChB,CAAC;mBAhCsC,CAAC,SAAxC,CAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAI,YACxC,CAAC,yBACO,MAAM,KAAK,MAAM,EAAE,kBACzB,CAAC;EA4Cf"}
package/src/make-once.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // @ts-check
2
- const { Fail } = assert;
2
+ import { Fail } from '@endo/errors';
3
3
 
4
4
  /** @param {string} label */
5
5
  const defaultLabelToKeys = label => harden([label]);
@@ -35,7 +35,7 @@ export const makeOnceKit = (debugName, stores, backingStore = undefined) => {
35
35
  * Ensure the wrapped function is only called once per incarnation. It is
36
36
  * expected to update the backing store directly.
37
37
  *
38
- * @template {(key: string, ...rest: unknown[]) => any} T
38
+ * @template {(key: string, ...rest: any[]) => any} T
39
39
  * @param {T} provider
40
40
  * @param {(label: string) => string[]} [labelToKeys]
41
41
  * @returns {T}
@@ -1,9 +1,16 @@
1
- export function prepareRevocableKit<U extends unknown = any>(zone: import('@agoric/base-zone').Zone, uKindName: string, uMethodNames: (string | symbol)[], options?: RevocableKitOptions<any> | undefined): (underlying: U) => RevocableKit<U>;
2
- export type Revoker = {
1
+ export function prepareRevocableMakerKit<U = any>(zone: import("@agoric/base-zone").Zone, uKindName: string, uMethodNames: (string | symbol)[], options?: RevocableKitOptions<any> | undefined): RevocableMakerKit<U>;
2
+ export type RevocableMakerKit<U = any> = {
3
+ revoke: (revocable: U) => boolean;
4
+ /**
5
+ * Forwards to the underlying exo object, until revoked
6
+ */
7
+ makeRevocable: (underlying: U) => U;
8
+ };
9
+ export type RevokerFacet = {
3
10
  revoke: () => boolean;
4
11
  };
5
- export type RevocableKit<U extends unknown = any> = {
6
- revoker: Revoker;
12
+ export type RevocableKit<U = any> = {
13
+ revoker: RevokerFacet;
7
14
  /**
8
15
  * Forwards to the underlying exo object, until revoked
9
16
  */
@@ -15,7 +22,7 @@ export type RevocableKitThis<U = any> = {
15
22
  underlying: U;
16
23
  };
17
24
  };
18
- export type RevocableKitOptions<U extends unknown = any> = {
25
+ export type RevocableKitOptions<U = any> = {
19
26
  /**
20
27
  * The `interfaceName` of the underlying interface guard.
21
28
  * Defaults to the `uKindName`.
@@ -1 +1 @@
1
- {"version":3,"file":"prepare-revocable.d.ts","sourceRoot":"","sources":["prepare-revocable.js"],"names":[],"mappings":"AA6DO,mEATI,OAAO,mBAAmB,EAAE,IAAI,aAChC,MAAM,gBAEN,CAAC,MAAM,GAAC,MAAM,CAAC,EAAE,sFAiF3B;;YAjIa,MAAM,OAAO;;;aAMb,OAAO;;;;eACP,CAAC;;;YAOD,aAAa,CAAC,CAAC;WACf;QAAE,UAAU,EAAE,CAAC,CAAA;KAAE;;;;;;;;;;;;;;;;;;kDAkBnB,iBAAiB,CAAC,CAAC,WAAW,GAAG,EAAE,KAAK,GAAG"}
1
+ {"version":3,"file":"prepare-revocable.d.ts","sourceRoot":"","sources":["prepare-revocable.js"],"names":[],"mappings":"AAqEO,yCAVO,CAAC,cACJ,OAAO,mBAAmB,EAAE,IAAI,aAChC,MAAM,gBAEN,CAAC,MAAM,GAAC,MAAM,CAAC,EAAE,mDAIf,iBAAiB,CAAC,CAAC,CAAC,CAyGhC;8BArKa,CAAC;YAED,CAAC,SAAS,EAAE,CAAC,KAAK,OAAO;;;;mBACzB,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC;;;YAMpB,MAAM,OAAO;;yBAIb,CAAC;aAED,YAAY;;;;eACZ,CAAC;;6BAKD,CAAC;YAED,YAAY,CAAC,CAAC,CAAC;WACf;QAAE,UAAU,EAAE,CAAC,CAAA;KAAE;;gCAIjB,CAAC;;;;;;;;;;;;;;;;kDAcH,gBAAgB,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,KAAK,GAAG"}
@@ -1,17 +1,26 @@
1
- import { M } from '@endo/patterns';
1
+ import { Fail, q } from '@endo/errors';
2
2
  import { fromUniqueEntries } from '@endo/common/from-unique-entries.js';
3
+ import { M } from '@endo/patterns';
3
4
 
4
- const { Fail, quote: q } = assert;
5
+ /** @import {Amplify} from '@endo/exo'; */
6
+
7
+ /**
8
+ * @template [U=any]
9
+ * @typedef {object} RevocableMakerKit
10
+ * @property {(revocable: U) => boolean} revoke
11
+ * @property {(underlying: U) => U} makeRevocable
12
+ * Forwards to the underlying exo object, until revoked
13
+ */
5
14
 
6
15
  /**
7
- * @typedef {object} Revoker
16
+ * @typedef {object} RevokerFacet
8
17
  * @property {() => boolean} revoke
9
18
  */
10
19
 
11
20
  /**
12
- * @template {any} [U=any]
21
+ * @template [U=any]
13
22
  * @typedef {object} RevocableKit
14
- * @property {Revoker} revoker
23
+ * @property {RevokerFacet} revoker
15
24
  * @property {U} revocable
16
25
  * Forwards to the underlying exo object, until revoked
17
26
  */
@@ -24,7 +33,7 @@ const { Fail, quote: q } = assert;
24
33
  */
25
34
 
26
35
  /**
27
- * @template {any} [U=any]
36
+ * @template [U=any]
28
37
  * @typedef {object} RevocableKitOptions
29
38
  * @property {string} [uInterfaceName]
30
39
  * The `interfaceName` of the underlying interface guard.
@@ -48,8 +57,7 @@ const { Fail, quote: q } = assert;
48
57
  * Make an exo class kit for wrapping an underlying exo class,
49
58
  * where the wrapper is a revocable forwarder.
50
59
  *
51
- * @deprecated Change to `prepareRevocableMakerKit` once #8977 happens
52
- * @template {any} [U=any]
60
+ * @template [U=any]
53
61
  * @param {import('@agoric/base-zone').Zone} zone
54
62
  * @param {string} uKindName
55
63
  * The `kindName` of the underlying exo class
@@ -57,9 +65,9 @@ const { Fail, quote: q } = assert;
57
65
  * The method names of the underlying exo class that should be represented
58
66
  * by transparently-forwarding methods of the revocable caretaker.
59
67
  * @param {RevocableKitOptions} [options]
60
- * @returns {(underlying: U) => RevocableKit<U>}
68
+ * @returns {RevocableMakerKit<U>}
61
69
  */
62
- export const prepareRevocableKit = (
70
+ export const prepareRevocableMakerKit = (
63
71
  zone,
64
72
  uKindName,
65
73
  uMethodNames,
@@ -87,6 +95,9 @@ export const prepareRevocableKit = (
87
95
 
88
96
  const revocableKindName = `${uKindName}_caretaker`;
89
97
 
98
+ /** @type {Amplify<any>} */
99
+ let amplifier;
100
+
90
101
  const makeRevocableKit = zone.exoClassKit(
91
102
  revocableKindName,
92
103
  RevocableIKit,
@@ -128,11 +139,36 @@ export const prepareRevocableKit = (
128
139
  stateShape: {
129
140
  underlying: M.opt(M.remotable('underlying')),
130
141
  },
142
+ receiveAmplifier: amp => {
143
+ amplifier = amp;
144
+ },
131
145
  },
132
146
  );
133
147
 
134
- // eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
135
- // @ts-ignore parameter confusion
136
- return makeRevocableKit;
148
+ /**
149
+ * @param {U} underlying
150
+ * @returns {U}
151
+ */
152
+ const makeRevocable = underlying =>
153
+ // @ts-expect-error some confusion about UU vs Guarded<U> I think
154
+ makeRevocableKit(underlying).revocable;
155
+
156
+ /**
157
+ * @param {U} revocable
158
+ * @returns {boolean}
159
+ */
160
+ const revoke = revocable => {
161
+ /** @type {RevocableKit<U>} */
162
+ const facets = amplifier(revocable);
163
+ if (facets === undefined) {
164
+ return false;
165
+ }
166
+ return facets.revoker.revoke();
167
+ };
168
+
169
+ return harden({
170
+ revoke,
171
+ makeRevocable,
172
+ });
137
173
  };
138
- harden(prepareRevocableKit);
174
+ harden(prepareRevocableMakerKit);
package/src/types.d.ts CHANGED
@@ -1,11 +1,5 @@
1
- export type KeyCategories = 'exoClass' | 'exoClassKit' | 'exo' | 'store' | 'zone';
2
- export type KeyMakers = {
3
- exoClass: (label: string) => string[];
4
- exoClassKit: (label: string) => string[];
5
- exo: (label: string) => string[];
6
- store: (label: string) => string[];
7
- zone: (label: string) => string[];
8
- };
1
+ export type KeyCategories = "exoClass" | "exoClassKit" | "exo" | "store" | "zone";
2
+ export type KeyMakers = Record<KeyCategories, (label: string) => string[]>;
9
3
  /**
10
4
  * A bag of methods for creating defensible objects and
11
5
  * collections with the same allocation semantics (ephemeral, persistent, etc)
@@ -32,6 +26,10 @@ export type ExoZone = {
32
26
  * create a new Zone that can be passed to untrusted consumers without exposing the storage of the parent zone
33
27
  */
34
28
  subZone: (label: string, options?: StoreOptions) => Zone;
29
+ /**
30
+ * register a promise watcher created by this zone
31
+ */
32
+ watchPromise: typeof watchPromise;
35
33
  };
36
34
  export type Stores = {
37
35
  /**
@@ -45,21 +43,22 @@ export type Stores = {
45
43
  /**
46
44
  * provide a Map-like store named `label` in the zone
47
45
  */
48
- mapStore: <K, V>(label: string, options?: StoreOptions) => MapStore<K, V>;
46
+ mapStore: (label: string, options?: StoreOptions) => MapStore<any, any>;
49
47
  /**
50
48
  * provide a Set-like store named `label` in the zone
51
49
  */
52
- setStore: <K_1>(label: string, options?: StoreOptions) => SetStore<K_1>;
50
+ setStore: <K>(label: string, options?: StoreOptions) => SetStore<K>;
53
51
  /**
54
52
  * provide a WeakMap-like store named `label` in the zone
55
53
  */
56
- weakMapStore: <K_2, V_1>(label: string, options?: StoreOptions) => WeakMapStore<K_2, V_1>;
54
+ weakMapStore: <K, V>(label: string, options?: StoreOptions) => WeakMapStore<K, V>;
57
55
  /**
58
56
  * provide a WeakSet-like store named `label` in the zone
59
57
  */
60
- weakSetStore: <K_3>(label: string, options?: StoreOptions) => WeakSetStore<K_3>;
58
+ weakSetStore: <K>(label: string, options?: StoreOptions) => WeakSetStore<K>;
61
59
  };
62
60
  import { makeExo } from '@endo/exo';
63
61
  import { defineExoClass } from '@endo/exo';
64
62
  import { defineExoClassKit } from '@endo/exo';
63
+ import { watchPromise } from './watch-promise.js';
65
64
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":"4BAGc,UAAU,GAAG,aAAa,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM;;sBACvB,MAAM,KAAK,MAAM,EAAE;yBAAnB,MAAM,KAAK,MAAM,EAAE;iBAAnB,MAAM,KAAK,MAAM,EAAE;mBAAnB,MAAM,KAAK,MAAM,EAAE;kBAAnB,MAAM,KAAK,MAAM,EAAE;;;;;;mBAGlD,OAAO,GAAG,MAAM;;;;;SAMf,cAAc;;;;cACd,qBAAqB;;;;iBACrB,wBAAwB;;;;uBACf,MAAM,eAAe,MAAM;;;;qBAC5B,MAAM,YAAY,YAAY,KAAK,IAAI;;;;;;cAK/C,MAAM,MAAM;;;;2BACD,OAAO,KAAK,OAAO;;;;4BACjB,MAAM,YAAY,YAAY;;;;2BAChC,MAAM,YAAY,YAAY;;;;oCAE3C,MAAM,YAAY,YAAY;;;;+BAG9B,MAAM,YAAY,YAAY;;wBA7BiB,WAAW;+BAAX,WAAW;kCAAX,WAAW"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":"4BAac,UAAU,GAAG,aAAa,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM;wBACrD,MAAM,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;;;;;mBAGnD,OAAO,GAAG,MAAM;;;;;SAMf,OAAO,OAAO;;;;cACd,OAAO,cAAc;;;;iBACrB,OAAO,iBAAiB;;;;cACxB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,KAAK,CAAC;;;;aAChD,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,IAAI;;;;kBAC/C,OAAO,YAAY;;;;;;cAKnB,MAAM,MAAM;;;;gBACZ,CAAC,QAAQ,EAAE,OAAO,KAAK,OAAO;;;;cAC9B,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;;;;cAC7D,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC;;;;kBACzD,CAAC,CAAC,EAAE,CAAC,EAClB,KAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;;;;kBAEnD,CAAC,CAAC,EACf,KAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,YAAY,CAAC,CAAC,CAAC;;wBAxCH,WAAW;+BAAX,WAAW;kCAAX,WAAW;6BAEzC,oBAAoB"}
package/src/types.js CHANGED
@@ -1,5 +1,15 @@
1
1
  // eslint-disable-next-line no-unused-vars
2
2
  import { makeExo, defineExoClass, defineExoClassKit } from '@endo/exo';
3
+ // eslint-disable-next-line no-unused-vars
4
+ import { watchPromise } from './watch-promise.js';
5
+
6
+ // Ensure this is a module.
7
+ export {};
8
+
9
+ /**
10
+ * @import {Key} from '@endo/patterns';
11
+ * @import {Passable} from '@endo/pass-style';
12
+ */
3
13
 
4
14
  /** @typedef {'exoClass' | 'exoClassKit' | 'exo' | 'store' | 'zone'} KeyCategories */
5
15
  /** @typedef {Record<KeyCategories, (label: string) => string[]>} KeyMakers */
@@ -16,15 +26,16 @@ import { makeExo, defineExoClass, defineExoClassKit } from '@endo/exo';
16
26
  * @property {typeof defineExoClassKit} exoClassKit create a "kit" maker function that can be used to create a record of exo-objects sharing the same state
17
27
  * @property {<T>(key: string, maker: (key: string) => T) => T} makeOnce create or retrieve a singleton object bound to this zone
18
28
  * @property {(label: string, options?: StoreOptions) => Zone} subZone create a new Zone that can be passed to untrusted consumers without exposing the storage of the parent zone
29
+ * @property {typeof watchPromise} watchPromise register a promise watcher created by this zone
19
30
  */
20
31
 
21
32
  /**
22
33
  * @typedef {object} Stores
23
34
  * @property {() => Stores} detached obtain store providers which are detached (the stores are anonymous rather than bound to `label` in the zone)
24
35
  * @property {(specimen: unknown) => boolean} isStorable return true if the specimen can be stored in the zone, whether as exo-object state or in a store
25
- * @property {<K,V>(label: string, options?: StoreOptions) => MapStore<K, V>} mapStore provide a Map-like store named `label` in the zone
36
+ * @property {(label: string, options?: StoreOptions) => MapStore<any, any>} mapStore provide a Map-like store named `label` in the zone
26
37
  * @property {<K>(label: string, options?: StoreOptions) => SetStore<K>} setStore provide a Set-like store named `label` in the zone
27
- * @property {<K,V>(
38
+ * @property {<K, V>(
28
39
  * label: string, options?: StoreOptions) => WeakMapStore<K, V>
29
40
  * } weakMapStore provide a WeakMap-like store named `label` in the zone
30
41
  * @property {<K>(
@@ -0,0 +1,29 @@
1
+ /**
2
+ * A PromiseWatcher method guard callable with or more arguments, returning void.
3
+ */
4
+ export const PromiseWatcherHandler: import("@endo/patterns").MethodGuard;
5
+ /**
6
+ * A PromiseWatcher interface that has both onFulfilled and onRejected handlers.
7
+ */
8
+ export const PromiseWatcherI: import("@endo/patterns").InterfaceGuard<{
9
+ onFulfilled: import("@endo/patterns").MethodGuard;
10
+ onRejected: import("@endo/patterns").MethodGuard;
11
+ }>;
12
+ /**
13
+ * A PromiseWatcher interface that has only an onFulfilled handler.
14
+ */
15
+ export const PromiseWatcherFulfilledI: import("@endo/patterns").InterfaceGuard<{
16
+ onFulfilled: import("@endo/patterns").MethodGuard;
17
+ }>;
18
+ /**
19
+ * A PromiseWatcher interface that has only an onRejected handler.
20
+ */
21
+ export const PromiseWatcherRejectedI: import("@endo/patterns").InterfaceGuard<{
22
+ onRejected: import("@endo/patterns").MethodGuard;
23
+ }>;
24
+ export function watchPromise(p: Promise<any>, watcher: PromiseWatcher, ...watcherArgs: unknown[]): void;
25
+ export type PromiseWatcher = {
26
+ onFulfilled?: ((fulfilment: unknown, ...args: unknown[]) => void) | undefined;
27
+ onRejected?: ((reason: unknown, ...args: unknown[]) => void) | undefined;
28
+ };
29
+ //# sourceMappingURL=watch-promise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-promise.d.ts","sourceRoot":"","sources":["watch-promise.js"],"names":[],"mappings":"AAOA;;GAEG;AACH,yEAA6E;AAE7E;;GAEG;AACH;;;GAGG;AAEH;;GAEG;AACH;;GAEG;AAEH;;GAEG;AACH;;GAEG;AAuCI,gCALI,OAAO,CAAC,GAAG,CAAC,WACZ,cAAc,kBACX,OAAO,EAAA,GACR,IAAI,CAUhB;;gCA3C0B,OAAO,WAAW,OAAO,EAAE,KAAK,IAAI;2BACxC,OAAO,WAAW,OAAO,EAAE,KAAK,IAAI"}
@@ -0,0 +1,81 @@
1
+ // @ts-check
2
+ import { Fail } from '@endo/errors';
3
+ import { M } from '@endo/patterns';
4
+ import { E } from '@endo/far';
5
+
6
+ const { apply } = Reflect;
7
+
8
+ /**
9
+ * A PromiseWatcher method guard callable with or more arguments, returning void.
10
+ */
11
+ export const PromiseWatcherHandler = M.call(M.raw()).rest(M.raw()).returns();
12
+
13
+ /**
14
+ * A PromiseWatcher interface that has both onFulfilled and onRejected handlers.
15
+ */
16
+ export const PromiseWatcherI = M.interface('PromiseWatcher', {
17
+ onFulfilled: PromiseWatcherHandler,
18
+ onRejected: PromiseWatcherHandler,
19
+ });
20
+
21
+ /**
22
+ * A PromiseWatcher interface that has only an onFulfilled handler.
23
+ */
24
+ export const PromiseWatcherFulfilledI = M.interface('PromiseWatcherFulfilled', {
25
+ onFulfilled: PromiseWatcherHandler,
26
+ });
27
+
28
+ /**
29
+ * A PromiseWatcher interface that has only an onRejected handler.
30
+ */
31
+ export const PromiseWatcherRejectedI = M.interface('PromiseWatcherRejected', {
32
+ onRejected: PromiseWatcherHandler,
33
+ });
34
+
35
+ /**
36
+ * @typedef {object} PromiseWatcher
37
+ * @property {(fulfilment: unknown, ...args: unknown[]) => void} [onFulfilled]
38
+ * @property {(reason: unknown, ...args: unknown[]) => void} [onRejected]
39
+ */
40
+
41
+ /**
42
+ * Adapt a promise watcher method to E.when.
43
+ * @param {Record<PropertyKey, (...args: unknown[]) => unknown>} that
44
+ * @param {PropertyKey} prop
45
+ * @param {unknown[]} postArgs
46
+ */
47
+ const callMeMaybe = (that, prop, postArgs) => {
48
+ const fn = that[prop];
49
+ if (!fn) {
50
+ return undefined;
51
+ }
52
+ assert.typeof(fn, 'function');
53
+ /**
54
+ * @param {unknown} arg value or reason
55
+ */
56
+ const wrapped = arg => {
57
+ // Don't return a value, to prevent E.when from subscribing to a resulting
58
+ // promise.
59
+ apply(fn, that, [arg, ...postArgs]);
60
+ };
61
+ return wrapped;
62
+ };
63
+
64
+ /**
65
+ * Shim the promise watcher behaviour when VatData.watchPromise is not available.
66
+ *
67
+ * @param {Promise<any>} p
68
+ * @param {PromiseWatcher} watcher
69
+ * @param {...unknown} watcherArgs
70
+ * @returns {void}
71
+ */
72
+ export const watchPromise = (p, watcher, ...watcherArgs) => {
73
+ Promise.resolve(p) === p || Fail`watchPromise only watches promises`;
74
+ const onFulfilled = callMeMaybe(watcher, 'onFulfilled', watcherArgs);
75
+ const onRejected = callMeMaybe(watcher, 'onRejected', watcherArgs);
76
+ onFulfilled ||
77
+ onRejected ||
78
+ Fail`promise watcher must implement at least one handler method`;
79
+ void E.when(p, onFulfilled, onRejected);
80
+ };
81
+ harden(watchPromise);
@@ -1,4 +1,3 @@
1
- // eslint-disable-next-line import/order
2
1
  import { test } from './prepare-test-env-ava.js';
3
2
 
4
3
  import { makeHeapZone } from '../heap.js';
@@ -5,7 +5,7 @@ import { test } from './prepare-test-env-ava.js';
5
5
  // eslint-disable-next-line import/order
6
6
  import { M } from '@endo/patterns';
7
7
  import { makeHeapZone } from '../src/heap.js';
8
- import { prepareRevocableKit } from '../src/prepare-revocable.js';
8
+ import { prepareRevocableMakerKit } from '../src/prepare-revocable.js';
9
9
 
10
10
  const UpCounterI = M.interface('UpCounter', {
11
11
  incr: M.call()
@@ -38,16 +38,17 @@ test('test revoke defineVirtualExoClass', t => {
38
38
  },
39
39
  );
40
40
 
41
- const makeRevocableUpCounterKit = prepareRevocableKit(zone, 'UpCounter', [
42
- 'incr',
43
- ]);
41
+ const { revoke, makeRevocable } = prepareRevocableMakerKit(
42
+ zone,
43
+ 'UpCounter',
44
+ ['incr'],
45
+ );
44
46
 
45
- const makeUpCounterKit = x =>
46
- makeRevocableUpCounterKit(makeUnderlyingUpCounter(x));
47
+ const makeUpCounter = x => makeRevocable(makeUnderlyingUpCounter(x));
47
48
 
48
- const { revoker, revocable: upCounter } = makeUpCounterKit(3);
49
+ const upCounter = makeUpCounter(3);
49
50
  t.is(upCounter.incr(5), 8);
50
- t.is(revoker.revoke(), true);
51
+ t.is(revoke(upCounter), true);
51
52
  t.throws(() => upCounter.incr(1), {
52
53
  message: '"UpCounter_caretaker" revoked',
53
54
  });
@@ -79,7 +80,7 @@ test('test revoke defineVirtualExoClassKit', t => {
79
80
  },
80
81
  );
81
82
 
82
- const makeRevocableUpCounterKit = prepareRevocableKit(
83
+ const { revoke, makeRevocable } = prepareRevocableMakerKit(
83
84
  zone,
84
85
  'UpCounter',
85
86
  ['incr'],
@@ -89,8 +90,12 @@ test('test revoke defineVirtualExoClassKit', t => {
89
90
  },
90
91
  extraMethods: {
91
92
  selfRevoke() {
92
- const { revoker } = this.facets;
93
- return revoker.revoke();
93
+ // Could directly use the revoker facet instead, but this
94
+ // should now be considered more of an internal detail that
95
+ // we should deemphasize. This tests the code pattern we wish
96
+ // to encourage.
97
+ const { revocable } = this.facets;
98
+ return revoke(revocable);
94
99
  },
95
100
  },
96
101
  },
@@ -98,8 +103,7 @@ test('test revoke defineVirtualExoClassKit', t => {
98
103
 
99
104
  const makeCounterKit = x => {
100
105
  const { up: upCounter, down: downCounter } = makeUnderlyingCounterKit(x);
101
- const { revocable: revocableUpCounter } =
102
- makeRevocableUpCounterKit(upCounter);
106
+ const revocableUpCounter = makeRevocable(upCounter);
103
107
  return harden({
104
108
  up: revocableUpCounter,
105
109
  down: downCounter,
package/tsconfig.json CHANGED
@@ -1,9 +1,7 @@
1
1
  // This file can contain .js-specific Typescript compiler config.
2
2
  {
3
3
  "extends": "../../tsconfig.json",
4
- "compilerOptions": {
5
- "maxNodeModuleJsDepth": 2,
6
- },
4
+ "compilerOptions": {},
7
5
  "include": [
8
6
  "*.js",
9
7
  "scripts",
File without changes