@agoric/base-zone 0.1.1-dev-7ffae88.0 → 0.1.1-orchestration-dev-096c4e8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/base-zone",
3
- "version": "0.1.1-dev-7ffae88.0+7ffae88",
3
+ "version": "0.1.1-orchestration-dev-096c4e8.0+096c4e8",
4
4
  "description": "Allocation zone abstraction library and heap implementation",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/Agoric/agoric-sdk",
@@ -19,6 +19,7 @@
19
19
  },
20
20
  "exports": {
21
21
  ".": "./src/index.js",
22
+ "./zone-helpers.js": "./zone-helpers.js",
22
23
  "./heap.js": "./heap.js",
23
24
  "./tools/*": "./tools/*"
24
25
  },
@@ -26,14 +27,16 @@
26
27
  "author": "Agoric",
27
28
  "license": "Apache-2.0",
28
29
  "dependencies": {
29
- "@agoric/store": "0.9.3-dev-7ffae88.0+7ffae88",
30
- "@endo/exo": "^1.1.0",
31
- "@endo/far": "^1.0.2",
32
- "@endo/pass-style": "^1.1.0",
33
- "@endo/patterns": "^1.1.0"
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"
34
36
  },
35
37
  "devDependencies": {
36
- "@endo/init": "^1.0.2",
38
+ "@endo/init": "^1.0.4",
39
+ "@endo/ses-ava": "^1.1.2",
37
40
  "ava": "^5.3.0"
38
41
  },
39
42
  "publishConfig": {
@@ -53,7 +56,7 @@
53
56
  "workerThreads": false
54
57
  },
55
58
  "typeCoverage": {
56
- "atLeast": 88.7
59
+ "atLeast": 89.25
57
60
  },
58
- "gitHead": "7ffae88ae37df782d5ffe3cf92261a498b0f636c"
61
+ "gitHead": "096c4e8fce80e9a509b0e1a30fda11736c4570e1"
59
62
  }
@@ -0,0 +1,36 @@
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 = {
3
+ revoke: () => boolean;
4
+ };
5
+ export type RevocableKit<U extends unknown = any> = {
6
+ revoker: Revoker;
7
+ /**
8
+ * Forwards to the underlying exo object, until revoked
9
+ */
10
+ revocable: U;
11
+ };
12
+ export type RevocableKitThis<U = any> = {
13
+ facets: RevocableKit<U>;
14
+ state: {
15
+ underlying: U;
16
+ };
17
+ };
18
+ export type RevocableKitOptions<U extends unknown = any> = {
19
+ /**
20
+ * The `interfaceName` of the underlying interface guard.
21
+ * Defaults to the `uKindName`.
22
+ */
23
+ uInterfaceName?: string | undefined;
24
+ /**
25
+ * For guarding the `extraMethods`, if you include them below. These appear
26
+ * only on the synthesized interface guard for the revocable caretaker, and
27
+ * do not necessarily correspond to any method of the underlying.
28
+ */
29
+ extraMethodGuards?: Record<string | symbol, import("@endo/patterns").MethodGuard> | undefined;
30
+ /**
31
+ * Extra methods adding behavior only to the revocable caretaker, and
32
+ * do not necessarily correspond to any methods of the underlying.
33
+ */
34
+ extraMethods?: Record<string | symbol, (this: RevocableKitThis<U>, ...args: any[]) => any> | undefined;
35
+ };
36
+ //# sourceMappingURL=prepare-revocable.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,138 @@
1
+ import { M } from '@endo/patterns';
2
+ import { fromUniqueEntries } from '@endo/common/from-unique-entries.js';
3
+
4
+ const { Fail, quote: q } = assert;
5
+
6
+ /**
7
+ * @typedef {object} Revoker
8
+ * @property {() => boolean} revoke
9
+ */
10
+
11
+ /**
12
+ * @template {any} [U=any]
13
+ * @typedef {object} RevocableKit
14
+ * @property {Revoker} revoker
15
+ * @property {U} revocable
16
+ * Forwards to the underlying exo object, until revoked
17
+ */
18
+
19
+ /**
20
+ * @template [U=any]
21
+ * @typedef {object} RevocableKitThis
22
+ * @property {RevocableKit<U>} facets
23
+ * @property {{ underlying: U }} state
24
+ */
25
+
26
+ /**
27
+ * @template {any} [U=any]
28
+ * @typedef {object} RevocableKitOptions
29
+ * @property {string} [uInterfaceName]
30
+ * The `interfaceName` of the underlying interface guard.
31
+ * Defaults to the `uKindName`.
32
+ * @property {Record<
33
+ * string|symbol,
34
+ * import('@endo/patterns').MethodGuard
35
+ * >} [extraMethodGuards]
36
+ * For guarding the `extraMethods`, if you include them below. These appear
37
+ * only on the synthesized interface guard for the revocable caretaker, and
38
+ * do not necessarily correspond to any method of the underlying.
39
+ * @property {Record<
40
+ * string|symbol,
41
+ * (this: RevocableKitThis<U>, ...args: any[]) => any
42
+ * >} [extraMethods]
43
+ * Extra methods adding behavior only to the revocable caretaker, and
44
+ * do not necessarily correspond to any methods of the underlying.
45
+ */
46
+
47
+ /**
48
+ * Make an exo class kit for wrapping an underlying exo class,
49
+ * where the wrapper is a revocable forwarder.
50
+ *
51
+ * @deprecated Change to `prepareRevocableMakerKit` once #8977 happens
52
+ * @template {any} [U=any]
53
+ * @param {import('@agoric/base-zone').Zone} zone
54
+ * @param {string} uKindName
55
+ * The `kindName` of the underlying exo class
56
+ * @param {(string|symbol)[]} uMethodNames
57
+ * The method names of the underlying exo class that should be represented
58
+ * by transparently-forwarding methods of the revocable caretaker.
59
+ * @param {RevocableKitOptions} [options]
60
+ * @returns {(underlying: U) => RevocableKit<U>}
61
+ */
62
+ export const prepareRevocableKit = (
63
+ zone,
64
+ uKindName,
65
+ uMethodNames,
66
+ options = {},
67
+ ) => {
68
+ const {
69
+ uInterfaceName = uKindName,
70
+ extraMethodGuards = undefined,
71
+ extraMethods = undefined,
72
+ } = options;
73
+ const RevocableIKit = harden({
74
+ revoker: M.interface(`${uInterfaceName}_revoker`, {
75
+ revoke: M.call().returns(M.boolean()),
76
+ }),
77
+ revocable: M.interface(
78
+ `${uInterfaceName}_revocable`,
79
+ {
80
+ ...extraMethodGuards,
81
+ },
82
+ {
83
+ defaultGuards: 'raw',
84
+ },
85
+ ),
86
+ });
87
+
88
+ const revocableKindName = `${uKindName}_caretaker`;
89
+
90
+ const makeRevocableKit = zone.exoClassKit(
91
+ revocableKindName,
92
+ RevocableIKit,
93
+ underlying => ({
94
+ underlying,
95
+ }),
96
+ {
97
+ revoker: {
98
+ revoke() {
99
+ const { state } = this;
100
+ if (state.underlying === undefined) {
101
+ return false;
102
+ }
103
+ state.underlying = undefined;
104
+ return true;
105
+ },
106
+ },
107
+ revocable: {
108
+ ...fromUniqueEntries(
109
+ uMethodNames.map(name => [
110
+ name,
111
+ {
112
+ // Use concise method syntax for exo methods
113
+ [name](...args) {
114
+ // @ts-expect-error normal exo-this typing confusion
115
+ const { underlying } = this.state;
116
+ underlying !== undefined ||
117
+ Fail`${q(revocableKindName)} revoked`;
118
+ return underlying[name](...args);
119
+ },
120
+ // @ts-expect-error using possible symbol as index type
121
+ }[name],
122
+ ]),
123
+ ),
124
+ ...extraMethods,
125
+ },
126
+ },
127
+ {
128
+ stateShape: {
129
+ underlying: M.opt(M.remotable('underlying')),
130
+ },
131
+ },
132
+ );
133
+
134
+ // eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
135
+ // @ts-ignore parameter confusion
136
+ return makeRevocableKit;
137
+ };
138
+ harden(prepareRevocableKit);
@@ -1,5 +1,4 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
1
+ import { wrapTest } from '@endo/ses-ava';
2
+ import rawTest from 'ava';
2
3
 
3
- import test from 'ava';
4
-
5
- export { test };
4
+ export const test = wrapTest(rawTest);
@@ -0,0 +1,117 @@
1
+ // Modeled on test-heap-classes.js
2
+
3
+ import { test } from './prepare-test-env-ava.js';
4
+
5
+ // eslint-disable-next-line import/order
6
+ import { M } from '@endo/patterns';
7
+ import { makeHeapZone } from '../src/heap.js';
8
+ import { prepareRevocableKit } from '../src/prepare-revocable.js';
9
+
10
+ const UpCounterI = M.interface('UpCounter', {
11
+ incr: M.call()
12
+ // TODO M.number() should not be needed to get a better error message
13
+ .optional(M.and(M.number(), M.gte(0)))
14
+ .returns(M.number()),
15
+ });
16
+
17
+ const DownCounterI = M.interface('DownCounter', {
18
+ decr: M.call()
19
+ // TODO M.number() should not be needed to get a better error message
20
+ .optional(M.and(M.number(), M.gte(0)))
21
+ .returns(M.number()),
22
+ });
23
+
24
+ test('test revoke defineVirtualExoClass', t => {
25
+ const zone = makeHeapZone('rootZone');
26
+
27
+ const makeUnderlyingUpCounter = zone.exoClass(
28
+ 'UpCounter',
29
+ UpCounterI,
30
+ /** @param {number} [x] */
31
+ (x = 0) => ({ x }),
32
+ {
33
+ incr(y = 1) {
34
+ const { state } = this;
35
+ state.x += y;
36
+ return state.x;
37
+ },
38
+ },
39
+ );
40
+
41
+ const makeRevocableUpCounterKit = prepareRevocableKit(zone, 'UpCounter', [
42
+ 'incr',
43
+ ]);
44
+
45
+ const makeUpCounterKit = x =>
46
+ makeRevocableUpCounterKit(makeUnderlyingUpCounter(x));
47
+
48
+ const { revoker, revocable: upCounter } = makeUpCounterKit(3);
49
+ t.is(upCounter.incr(5), 8);
50
+ t.is(revoker.revoke(), true);
51
+ t.throws(() => upCounter.incr(1), {
52
+ message: '"UpCounter_caretaker" revoked',
53
+ });
54
+ });
55
+
56
+ test('test revoke defineVirtualExoClassKit', t => {
57
+ const zone = makeHeapZone('rootZone');
58
+
59
+ const makeUnderlyingCounterKit = zone.exoClassKit(
60
+ 'Counter',
61
+ { up: UpCounterI, down: DownCounterI },
62
+ /** @param {number} [x] */
63
+ (x = 0) => ({ x }),
64
+ {
65
+ up: {
66
+ incr(y = 1) {
67
+ const { state } = this;
68
+ state.x += y;
69
+ return state.x;
70
+ },
71
+ },
72
+ down: {
73
+ decr(y = 1) {
74
+ const { state } = this;
75
+ state.x -= y;
76
+ return state.x;
77
+ },
78
+ },
79
+ },
80
+ );
81
+
82
+ const makeRevocableUpCounterKit = prepareRevocableKit(
83
+ zone,
84
+ 'UpCounter',
85
+ ['incr'],
86
+ {
87
+ extraMethodGuards: {
88
+ selfRevoke: M.call().returns(M.boolean()),
89
+ },
90
+ extraMethods: {
91
+ selfRevoke() {
92
+ const { revoker } = this.facets;
93
+ return revoker.revoke();
94
+ },
95
+ },
96
+ },
97
+ );
98
+
99
+ const makeCounterKit = x => {
100
+ const { up: upCounter, down: downCounter } = makeUnderlyingCounterKit(x);
101
+ const { revocable: revocableUpCounter } =
102
+ makeRevocableUpCounterKit(upCounter);
103
+ return harden({
104
+ up: revocableUpCounter,
105
+ down: downCounter,
106
+ });
107
+ };
108
+
109
+ const { up: upCounter, down: downCounter } = makeCounterKit(3);
110
+ t.is(upCounter.incr(5), 8);
111
+ t.is(downCounter.decr(), 7);
112
+ t.is(upCounter.selfRevoke(), true);
113
+ t.throws(() => upCounter.incr(3), {
114
+ message: '"UpCounter_caretaker" revoked',
115
+ });
116
+ t.is(downCounter.decr(), 6);
117
+ });
@@ -0,0 +1,2 @@
1
+ export * from "./src/prepare-revocable.js";
2
+ //# sourceMappingURL=zone-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zone-helpers.d.ts","sourceRoot":"","sources":["zone-helpers.js"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export * from './src/prepare-revocable.js';