@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 +15 -0
- package/package.json +14 -13
- package/src/exports.d.ts +0 -1
- package/src/heap.d.ts +1 -1
- package/src/heap.d.ts.map +1 -1
- package/src/heap.js +3 -2
- package/src/index.d.ts +1 -0
- package/src/index.js +3 -0
- package/src/is-passable.d.ts +1 -1
- package/src/is-passable.d.ts.map +1 -1
- package/src/is-passable.js +3 -18
- package/src/keys.d.ts +1 -1
- package/src/make-once.d.ts +2 -2
- package/src/make-once.d.ts.map +1 -1
- package/src/make-once.js +2 -2
- package/src/prepare-revocable.d.ts +12 -5
- package/src/prepare-revocable.d.ts.map +1 -1
- package/src/prepare-revocable.js +50 -14
- package/src/types.d.ts +11 -12
- package/src/types.d.ts.map +1 -1
- package/src/types.js +13 -2
- package/src/watch-promise.d.ts +29 -0
- package/src/watch-promise.d.ts.map +1 -0
- package/src/watch-promise.js +81 -0
- package/test/{test-exos.js → exos.test.js} +0 -1
- package/test/{test-prepare-revocable.js → prepare-revocable.test.js} +17 -13
- package/tsconfig.json +1 -3
- /package/test/{test-make-once.js → make-once.test.js} +0 -0
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-
|
|
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-
|
|
31
|
-
"@endo/common": "^1.
|
|
32
|
-
"@endo/
|
|
33
|
-
"@endo/
|
|
34
|
-
"@endo/
|
|
35
|
-
"@endo/
|
|
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.
|
|
39
|
-
"@endo/ses-ava": "^1.
|
|
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": "
|
|
47
|
+
"node": "^18.12 || ^20.9"
|
|
47
48
|
},
|
|
48
49
|
"ava": {
|
|
49
50
|
"files": [
|
|
50
|
-
"test
|
|
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":
|
|
60
|
+
"atLeast": 91.4
|
|
60
61
|
},
|
|
61
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "515c4c0efccfc91b97da30037c10fc4b076851e2"
|
|
62
63
|
}
|
package/src/exports.d.ts
CHANGED
package/src/heap.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export function makeHeapZone(baseLabel?: string | undefined): import(
|
|
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,
|
|
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/
|
|
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 {
|
|
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
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';
|
package/src/is-passable.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export function isPassable(specimen: any): specimen is
|
|
1
|
+
export function isPassable(specimen: any): specimen is Passable;
|
|
2
2
|
//# sourceMappingURL=is-passable.d.ts.map
|
package/src/is-passable.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"is-passable.d.ts","sourceRoot":"","sources":["is-passable.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"is-passable.d.ts","sourceRoot":"","sources":["is-passable.js"],"names":[],"mappings":"AAOO,qCAHI,GAAG,GACD,QAAQ,IAAI,QAAQ,CAE6B"}
|
package/src/is-passable.js
CHANGED
|
@@ -1,23 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isPassable as realIsPassable } from '@endo/pass-style';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
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
package/src/make-once.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export function makeOnceKit(debugName: string, stores: import(
|
|
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:
|
|
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
|
package/src/make-once.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
|
|
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:
|
|
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
|
|
2
|
-
export type
|
|
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
|
|
6
|
-
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
|
|
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":"
|
|
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"}
|
package/src/prepare-revocable.js
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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}
|
|
16
|
+
* @typedef {object} RevokerFacet
|
|
8
17
|
* @property {() => boolean} revoke
|
|
9
18
|
*/
|
|
10
19
|
|
|
11
20
|
/**
|
|
12
|
-
* @template
|
|
21
|
+
* @template [U=any]
|
|
13
22
|
* @typedef {object} RevocableKit
|
|
14
|
-
* @property {
|
|
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
|
|
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
|
-
* @
|
|
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 {
|
|
68
|
+
* @returns {RevocableMakerKit<U>}
|
|
61
69
|
*/
|
|
62
|
-
export const
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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(
|
|
174
|
+
harden(prepareRevocableMakerKit);
|
package/src/types.d.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
export type KeyCategories =
|
|
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:
|
|
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: <
|
|
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: <
|
|
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: <
|
|
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
|
package/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":"
|
|
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 {
|
|
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);
|
|
@@ -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 {
|
|
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
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
const { revoke, makeRevocable } = prepareRevocableMakerKit(
|
|
42
|
+
zone,
|
|
43
|
+
'UpCounter',
|
|
44
|
+
['incr'],
|
|
45
|
+
);
|
|
44
46
|
|
|
45
|
-
const
|
|
46
|
-
makeRevocableUpCounterKit(makeUnderlyingUpCounter(x));
|
|
47
|
+
const makeUpCounter = x => makeRevocable(makeUnderlyingUpCounter(x));
|
|
47
48
|
|
|
48
|
-
const
|
|
49
|
+
const upCounter = makeUpCounter(3);
|
|
49
50
|
t.is(upCounter.incr(5), 8);
|
|
50
|
-
t.is(
|
|
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
|
|
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
|
-
|
|
93
|
-
|
|
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
|
|
102
|
-
makeRevocableUpCounterKit(upCounter);
|
|
106
|
+
const revocableUpCounter = makeRevocable(upCounter);
|
|
103
107
|
return harden({
|
|
104
108
|
up: revocableUpCounter,
|
|
105
109
|
down: downCounter,
|
package/tsconfig.json
CHANGED
|
File without changes
|