@agoric/swingset-liveslots 0.10.3-u17.1 → 0.10.3-u18.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 +17 -17
- package/src/index.js +1 -2
- package/src/types-index.d.ts +4 -0
- package/src/types-index.js +2 -0
- package/test/exo-utils.js +70 -0
- package/test/handled-promises.test.js +2 -70
- package/test/strict-test-env-upgrade.test.js +94 -0
- package/test/virtual-objects/set-debug-label-instances.js +1 -1
- package/test/virtual-objects/virtualObjectManager.test.js +4 -4
- package/tools/fakeVirtualObjectManager.js +2 -0
- package/tools/fakeVirtualSupport.js +10 -5
- package/tools/prepare-strict-test-env.js +124 -0
- package/tools/setup-vat-data.js +34 -7
- package/src/vatDataTypes.d.ts +0 -276
- package/src/vatDataTypes.js +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/swingset-liveslots",
|
|
3
|
-
"version": "0.10.3-
|
|
3
|
+
"version": "0.10.3-u18.0",
|
|
4
4
|
"description": "SwingSet ocap support layer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -17,22 +17,22 @@
|
|
|
17
17
|
"lint:eslint": "eslint ."
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@agoric/internal": "^0.4.0-
|
|
21
|
-
"@agoric/store": "^0.9.3-
|
|
22
|
-
"@endo/env-options": "^1.1.
|
|
23
|
-
"@endo/errors": "^1.2.
|
|
24
|
-
"@endo/eventual-send": "^1.2.
|
|
25
|
-
"@endo/exo": "^1.5.
|
|
26
|
-
"@endo/far": "^1.1.
|
|
27
|
-
"@endo/init": "^1.1.
|
|
28
|
-
"@endo/marshal": "^1.
|
|
29
|
-
"@endo/nat": "^5.0.
|
|
30
|
-
"@endo/pass-style": "^1.4.
|
|
31
|
-
"@endo/patterns": "^1.4.
|
|
32
|
-
"@endo/promise-kit": "^1.1.
|
|
20
|
+
"@agoric/internal": "^0.4.0-u18.0",
|
|
21
|
+
"@agoric/store": "^0.9.3-u18.0",
|
|
22
|
+
"@endo/env-options": "^1.1.7",
|
|
23
|
+
"@endo/errors": "^1.2.7",
|
|
24
|
+
"@endo/eventual-send": "^1.2.7",
|
|
25
|
+
"@endo/exo": "^1.5.6",
|
|
26
|
+
"@endo/far": "^1.1.8",
|
|
27
|
+
"@endo/init": "^1.1.6",
|
|
28
|
+
"@endo/marshal": "^1.6.1",
|
|
29
|
+
"@endo/nat": "^5.0.12",
|
|
30
|
+
"@endo/pass-style": "^1.4.6",
|
|
31
|
+
"@endo/patterns": "^1.4.6",
|
|
32
|
+
"@endo/promise-kit": "^1.1.7"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@agoric/kmarshal": "^0.1.1-
|
|
35
|
+
"@agoric/kmarshal": "^0.1.1-u18.0",
|
|
36
36
|
"ava": "^5.3.0"
|
|
37
37
|
},
|
|
38
38
|
"files": [
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"access": "public"
|
|
67
67
|
},
|
|
68
68
|
"typeCoverage": {
|
|
69
|
-
"atLeast": 75.
|
|
69
|
+
"atLeast": 75.24
|
|
70
70
|
},
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "c22e7250188bbdb07bc021dffdb88af0309a7aa8"
|
|
72
72
|
}
|
package/src/index.js
CHANGED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { provideLazy as provide } from '@agoric/store';
|
|
2
|
+
|
|
3
|
+
// Partially duplicates @agoric/vat-data to avoid circular dependencies.
|
|
4
|
+
export const makeExoUtils = VatData => {
|
|
5
|
+
const { defineDurableKind, makeKindHandle, watchPromise } = VatData;
|
|
6
|
+
|
|
7
|
+
const provideKindHandle = (baggage, kindName) =>
|
|
8
|
+
provide(baggage, `${kindName}_kindHandle`, () => makeKindHandle(kindName));
|
|
9
|
+
|
|
10
|
+
const emptyRecord = harden({});
|
|
11
|
+
const initEmpty = () => emptyRecord;
|
|
12
|
+
|
|
13
|
+
const defineDurableExoClass = (
|
|
14
|
+
kindHandle,
|
|
15
|
+
interfaceGuard,
|
|
16
|
+
init,
|
|
17
|
+
methods,
|
|
18
|
+
options,
|
|
19
|
+
) =>
|
|
20
|
+
defineDurableKind(kindHandle, init, methods, {
|
|
21
|
+
...options,
|
|
22
|
+
thisfulMethods: true,
|
|
23
|
+
interfaceGuard,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const prepareExoClass = (
|
|
27
|
+
baggage,
|
|
28
|
+
kindName,
|
|
29
|
+
interfaceGuard,
|
|
30
|
+
init,
|
|
31
|
+
methods,
|
|
32
|
+
options = undefined,
|
|
33
|
+
) =>
|
|
34
|
+
defineDurableExoClass(
|
|
35
|
+
provideKindHandle(baggage, kindName),
|
|
36
|
+
interfaceGuard,
|
|
37
|
+
init,
|
|
38
|
+
methods,
|
|
39
|
+
options,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const prepareExo = (
|
|
43
|
+
baggage,
|
|
44
|
+
kindName,
|
|
45
|
+
interfaceGuard,
|
|
46
|
+
methods,
|
|
47
|
+
options = undefined,
|
|
48
|
+
) => {
|
|
49
|
+
const makeSingleton = prepareExoClass(
|
|
50
|
+
baggage,
|
|
51
|
+
kindName,
|
|
52
|
+
interfaceGuard,
|
|
53
|
+
initEmpty,
|
|
54
|
+
methods,
|
|
55
|
+
options,
|
|
56
|
+
);
|
|
57
|
+
return provide(baggage, `the_${kindName}`, () => makeSingleton());
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
defineDurableKind,
|
|
62
|
+
makeKindHandle,
|
|
63
|
+
watchPromise,
|
|
64
|
+
|
|
65
|
+
provideKindHandle,
|
|
66
|
+
defineDurableExoClass,
|
|
67
|
+
prepareExoClass,
|
|
68
|
+
prepareExo,
|
|
69
|
+
};
|
|
70
|
+
};
|
|
@@ -2,7 +2,7 @@ import test from 'ava';
|
|
|
2
2
|
|
|
3
3
|
import { Fail } from '@endo/errors';
|
|
4
4
|
import { Far } from '@endo/marshal';
|
|
5
|
-
import { M
|
|
5
|
+
import { M } from '@agoric/store';
|
|
6
6
|
import { makePromiseKit } from '@endo/promise-kit';
|
|
7
7
|
// Disabled to avoid circular dependencies.
|
|
8
8
|
// import { makeStoreUtils } from '@agoric/vat-data/src/vat-data-bindings.js';
|
|
@@ -10,79 +10,11 @@ import { makePromiseKit } from '@endo/promise-kit';
|
|
|
10
10
|
import { kslot, kser } from '@agoric/kmarshal';
|
|
11
11
|
import { setupTestLiveslots } from './liveslots-helpers.js';
|
|
12
12
|
import { makeResolve, makeReject } from './util.js';
|
|
13
|
+
import { makeExoUtils } from './exo-utils.js';
|
|
13
14
|
|
|
14
15
|
// eslint-disable-next-line no-unused-vars
|
|
15
16
|
const compareEntriesByKey = ([ka], [kb]) => (ka < kb ? -1 : 1);
|
|
16
17
|
|
|
17
|
-
// Paritally duplicates @agoric/vat-data to avoid circular dependencies.
|
|
18
|
-
const makeExoUtils = VatData => {
|
|
19
|
-
const { defineDurableKind, makeKindHandle, watchPromise } = VatData;
|
|
20
|
-
|
|
21
|
-
const provideKindHandle = (baggage, kindName) =>
|
|
22
|
-
provide(baggage, `${kindName}_kindHandle`, () => makeKindHandle(kindName));
|
|
23
|
-
|
|
24
|
-
const emptyRecord = harden({});
|
|
25
|
-
const initEmpty = () => emptyRecord;
|
|
26
|
-
|
|
27
|
-
const defineDurableExoClass = (
|
|
28
|
-
kindHandle,
|
|
29
|
-
interfaceGuard,
|
|
30
|
-
init,
|
|
31
|
-
methods,
|
|
32
|
-
options,
|
|
33
|
-
) =>
|
|
34
|
-
defineDurableKind(kindHandle, init, methods, {
|
|
35
|
-
...options,
|
|
36
|
-
thisfulMethods: true,
|
|
37
|
-
interfaceGuard,
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
const prepareExoClass = (
|
|
41
|
-
baggage,
|
|
42
|
-
kindName,
|
|
43
|
-
interfaceGuard,
|
|
44
|
-
init,
|
|
45
|
-
methods,
|
|
46
|
-
options = undefined,
|
|
47
|
-
) =>
|
|
48
|
-
defineDurableExoClass(
|
|
49
|
-
provideKindHandle(baggage, kindName),
|
|
50
|
-
interfaceGuard,
|
|
51
|
-
init,
|
|
52
|
-
methods,
|
|
53
|
-
options,
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
const prepareExo = (
|
|
57
|
-
baggage,
|
|
58
|
-
kindName,
|
|
59
|
-
interfaceGuard,
|
|
60
|
-
methods,
|
|
61
|
-
options = undefined,
|
|
62
|
-
) => {
|
|
63
|
-
const makeSingleton = prepareExoClass(
|
|
64
|
-
baggage,
|
|
65
|
-
kindName,
|
|
66
|
-
interfaceGuard,
|
|
67
|
-
initEmpty,
|
|
68
|
-
methods,
|
|
69
|
-
options,
|
|
70
|
-
);
|
|
71
|
-
return provide(baggage, `the_${kindName}`, () => makeSingleton());
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
defineDurableKind,
|
|
76
|
-
makeKindHandle,
|
|
77
|
-
watchPromise,
|
|
78
|
-
|
|
79
|
-
provideKindHandle,
|
|
80
|
-
defineDurableExoClass,
|
|
81
|
-
prepareExoClass,
|
|
82
|
-
prepareExo,
|
|
83
|
-
};
|
|
84
|
-
};
|
|
85
|
-
|
|
86
18
|
// cf. packages/SwingSet/test/vat-durable-promise-watcher.js
|
|
87
19
|
const buildPromiseWatcherRootObject = (vatPowers, vatParameters, baggage) => {
|
|
88
20
|
const { VatData } = vatPowers;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/* global globalThis */
|
|
2
|
+
// eslint-disable-next-line import/order
|
|
3
|
+
import { annihilate, startLife } from '../tools/prepare-strict-test-env.js';
|
|
4
|
+
|
|
5
|
+
import test from 'ava';
|
|
6
|
+
|
|
7
|
+
import { makeUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js';
|
|
8
|
+
import { makeExoUtils } from './exo-utils.js';
|
|
9
|
+
|
|
10
|
+
test.serial('kind redefinition enforced', async t => {
|
|
11
|
+
annihilate();
|
|
12
|
+
|
|
13
|
+
const { prepareExoClass } = makeExoUtils(globalThis.VatData);
|
|
14
|
+
|
|
15
|
+
await startLife(async baggage => {
|
|
16
|
+
const makeTestExo = prepareExoClass(
|
|
17
|
+
baggage,
|
|
18
|
+
'TestExo',
|
|
19
|
+
undefined,
|
|
20
|
+
() => ({}),
|
|
21
|
+
{
|
|
22
|
+
foo() {
|
|
23
|
+
return 'bar';
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
baggage.init('testExo', makeTestExo());
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
await t.throwsAsync(
|
|
32
|
+
async () =>
|
|
33
|
+
startLife(async () => {
|
|
34
|
+
// Not redefining the kind here
|
|
35
|
+
}),
|
|
36
|
+
{ message: 'defineDurableKind not called for tags: [TestExo]' },
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
await startLife(async baggage => {
|
|
40
|
+
prepareExoClass(baggage, 'TestExo', undefined, () => ({}), {
|
|
41
|
+
foo() {
|
|
42
|
+
return 'baz';
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
t.is(baggage.get('testExo').foo(), 'baz');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test.serial('decided promise rejected', async t => {
|
|
51
|
+
annihilate();
|
|
52
|
+
|
|
53
|
+
const { prepareExo } = makeExoUtils(globalThis.VatData);
|
|
54
|
+
const { watchPromise } = globalThis.VatData;
|
|
55
|
+
|
|
56
|
+
t.plan(1);
|
|
57
|
+
|
|
58
|
+
await startLife(async baggage => {
|
|
59
|
+
const watcher = prepareExo(
|
|
60
|
+
baggage,
|
|
61
|
+
'DurablePromiseTestWatcher',
|
|
62
|
+
undefined,
|
|
63
|
+
{
|
|
64
|
+
onFulfilled(value) {
|
|
65
|
+
t.fail(
|
|
66
|
+
`First incarnation watcher onFulfilled triggered with value ${value}`,
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
onRejected(reason) {
|
|
70
|
+
t.fail(
|
|
71
|
+
`First incarnation watcher onRejected triggered with reason ${reason}`,
|
|
72
|
+
);
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const never = harden(new Promise(() => {}));
|
|
78
|
+
|
|
79
|
+
watchPromise(never, watcher);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
await startLife(async baggage => {
|
|
83
|
+
prepareExo(baggage, 'DurablePromiseTestWatcher', undefined, {
|
|
84
|
+
onFulfilled(value) {
|
|
85
|
+
t.fail(
|
|
86
|
+
`Second incarnation watcher onFulfilled triggered with value ${value}`,
|
|
87
|
+
);
|
|
88
|
+
},
|
|
89
|
+
onRejected(reason) {
|
|
90
|
+
t.deepEqual(reason, makeUpgradeDisconnection('vat upgraded', 1));
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -127,8 +127,8 @@ test('multifaceted virtual objects', t => {
|
|
|
127
127
|
|
|
128
128
|
flushStateCache();
|
|
129
129
|
t.deepEqual(log.splice(0), [
|
|
130
|
-
`get kindIDID => undefined`,
|
|
131
130
|
`get idCounters => undefined`,
|
|
131
|
+
`get kindIDID => undefined`,
|
|
132
132
|
`set kindIDID 1`,
|
|
133
133
|
`set vom.vkind.2.descriptor {"kindID":"2","tag":"multithing"}`,
|
|
134
134
|
`set vom.${kid}/1 ${multiThingVal('foo', 1)}`,
|
|
@@ -203,8 +203,8 @@ test('virtual object operations', t => {
|
|
|
203
203
|
// t3-0: 'thing-3' 200 0
|
|
204
204
|
const thing4 = makeThing('thing-4', 300); // [t4-0* t3-0* t2-0* t1-0*]
|
|
205
205
|
// t4-0: 'thing-4' 300 0
|
|
206
|
-
t.is(log.shift(), `get kindIDID => undefined`);
|
|
207
206
|
t.is(log.shift(), `get idCounters => undefined`);
|
|
207
|
+
t.is(log.shift(), `get kindIDID => undefined`);
|
|
208
208
|
t.is(log.shift(), `set kindIDID 1`);
|
|
209
209
|
t.is(log.shift(), `set vom.vkind.2.descriptor {"kindID":"2","tag":"thing"}`);
|
|
210
210
|
t.is(log.shift(), `set vom.vkind.3.descriptor {"kindID":"3","tag":"zot"}`);
|
|
@@ -468,8 +468,8 @@ test('symbol named methods', t => {
|
|
|
468
468
|
// t1-0: 'thing-1' 0 0
|
|
469
469
|
const thing2 = makeThing('thing-2', 100); // [t1-0* t2-0*]
|
|
470
470
|
// t2-0: 'thing-2' 100 0
|
|
471
|
-
t.is(log.shift(), `get kindIDID => undefined`);
|
|
472
471
|
t.is(log.shift(), `get idCounters => undefined`);
|
|
472
|
+
t.is(log.shift(), `get kindIDID => undefined`);
|
|
473
473
|
t.is(log.shift(), `set kindIDID 1`);
|
|
474
474
|
t.is(
|
|
475
475
|
log.shift(),
|
|
@@ -649,8 +649,8 @@ test('virtual object gc', t => {
|
|
|
649
649
|
},
|
|
650
650
|
});
|
|
651
651
|
|
|
652
|
-
t.is(log.shift(), `get kindIDID => undefined`);
|
|
653
652
|
t.is(log.shift(), `get idCounters => undefined`);
|
|
653
|
+
t.is(log.shift(), `get kindIDID => undefined`);
|
|
654
654
|
t.is(log.shift(), `set kindIDID 1`);
|
|
655
655
|
const skit = [
|
|
656
656
|
'storeKindIDTable',
|
|
@@ -23,6 +23,7 @@ export function makeFakeVirtualObjectManager(vrm, fakeStuff) {
|
|
|
23
23
|
VirtualObjectAwareWeakSet,
|
|
24
24
|
flushStateCache,
|
|
25
25
|
canBeDurable,
|
|
26
|
+
insistAllDurableKindsReconnected,
|
|
26
27
|
} = makeVirtualObjectManager(
|
|
27
28
|
fakeStuff.syscall,
|
|
28
29
|
vrm,
|
|
@@ -43,6 +44,7 @@ export function makeFakeVirtualObjectManager(vrm, fakeStuff) {
|
|
|
43
44
|
defineDurableKindMulti,
|
|
44
45
|
makeKindHandle,
|
|
45
46
|
canBeDurable,
|
|
47
|
+
insistAllDurableKindsReconnected,
|
|
46
48
|
VirtualObjectAwareWeakMap,
|
|
47
49
|
VirtualObjectAwareWeakSet,
|
|
48
50
|
};
|
|
@@ -28,12 +28,14 @@ class FakeFinalizationRegistry {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
class FakeWeakRef {
|
|
31
|
+
#target;
|
|
32
|
+
|
|
31
33
|
constructor(target) {
|
|
32
|
-
this
|
|
34
|
+
this.#target = target;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
deref() {
|
|
36
|
-
return this
|
|
38
|
+
return this.#target; // strong ref
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
|
|
@@ -41,6 +43,7 @@ export function makeFakeLiveSlotsStuff(options = {}) {
|
|
|
41
43
|
let vrm;
|
|
42
44
|
function setVrm(vrmToUse) {
|
|
43
45
|
assert(!vrm, 'vrm already configured');
|
|
46
|
+
vrmToUse.initializeIDCounters();
|
|
44
47
|
vrm = vrmToUse;
|
|
45
48
|
}
|
|
46
49
|
|
|
@@ -174,6 +177,7 @@ export function makeFakeLiveSlotsStuff(options = {}) {
|
|
|
174
177
|
// and the WeakRef may or may not contain the target value. Use
|
|
175
178
|
// options={weak:true} to match that behavior, or the default weak:false to
|
|
176
179
|
// keep strong references.
|
|
180
|
+
const WeakRefForSlot = weak ? RealWeakRef : FakeWeakRef;
|
|
177
181
|
const valToSlot = new WeakMap();
|
|
178
182
|
const slotToVal = new Map();
|
|
179
183
|
|
|
@@ -183,7 +187,7 @@ export function makeFakeLiveSlotsStuff(options = {}) {
|
|
|
183
187
|
|
|
184
188
|
function getValForSlot(slot) {
|
|
185
189
|
const d = slotToVal.get(slot);
|
|
186
|
-
return d &&
|
|
190
|
+
return d && d.deref();
|
|
187
191
|
}
|
|
188
192
|
|
|
189
193
|
function requiredValForSlot(slot) {
|
|
@@ -193,7 +197,7 @@ export function makeFakeLiveSlotsStuff(options = {}) {
|
|
|
193
197
|
}
|
|
194
198
|
|
|
195
199
|
function setValForSlot(slot, val) {
|
|
196
|
-
slotToVal.set(slot,
|
|
200
|
+
slotToVal.set(slot, new WeakRefForSlot(val));
|
|
197
201
|
}
|
|
198
202
|
|
|
199
203
|
function convertValToSlot(val) {
|
|
@@ -275,6 +279,7 @@ export function makeFakeLiveSlotsStuff(options = {}) {
|
|
|
275
279
|
return {
|
|
276
280
|
syscall,
|
|
277
281
|
allocateExportID,
|
|
282
|
+
allocatePromiseID,
|
|
278
283
|
allocateCollectionID,
|
|
279
284
|
getSlotForVal,
|
|
280
285
|
requiredValForSlot,
|
|
@@ -339,7 +344,7 @@ export function makeFakeWatchedPromiseManager(
|
|
|
339
344
|
* @param {object} [options]
|
|
340
345
|
* @param {number} [options.cacheSize]
|
|
341
346
|
* @param {boolean} [options.relaxDurabilityRules]
|
|
342
|
-
* @param {Map<
|
|
347
|
+
* @param {Map<string, string>} [options.fakeStore]
|
|
343
348
|
* @param {WeakMapConstructor} [options.WeakMap]
|
|
344
349
|
* @param {WeakSetConstructor} [options.WeakSet]
|
|
345
350
|
* @param {boolean} [options.weak]
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prepare Agoric SwingSet vat global strict environment for testing.
|
|
3
|
+
*
|
|
4
|
+
* Installs Hardened JS (and does lockdown), plus adds mocks for virtual objects
|
|
5
|
+
* and stores.
|
|
6
|
+
*
|
|
7
|
+
* Exports tools for simulating upgrades.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import '@agoric/internal/src/install-ses-debug.js';
|
|
11
|
+
|
|
12
|
+
// eslint-disable-next-line import/order
|
|
13
|
+
import { reincarnate, flushIncarnation } from './setup-vat-data.js';
|
|
14
|
+
|
|
15
|
+
import { makePromiseKit } from '@endo/promise-kit';
|
|
16
|
+
import { Fail } from '@endo/errors';
|
|
17
|
+
import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
|
|
18
|
+
import { makeUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js';
|
|
19
|
+
|
|
20
|
+
export { flushIncarnation };
|
|
21
|
+
export { eventLoopIteration as nextCrank };
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @import { PromiseKit } from '@endo/promise-kit'
|
|
25
|
+
* @import { Baggage } from '@agoric/swingset-liveslots'
|
|
26
|
+
* @import { ReincarnateOptions } from './setup-vat-data.js'
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** @type {ReincarnateOptions} */
|
|
30
|
+
let incarnation;
|
|
31
|
+
let incarnationNumber = 0;
|
|
32
|
+
|
|
33
|
+
/** @param {Omit<ReincarnateOptions, 'fakeVomKit' | 'fakeStore'>} [options] */
|
|
34
|
+
export const annihilate = (options = {}) => {
|
|
35
|
+
// @ts-expect-error fakeStore and fakeVomKit don't exist on type, but drop them if they do at runtime
|
|
36
|
+
const { fakeStore: _fs, fakeVomKit: _fvk, ...opts } = options;
|
|
37
|
+
incarnation = reincarnate({ relaxDurabilityRules: false, ...opts });
|
|
38
|
+
incarnationNumber = 0;
|
|
39
|
+
return incarnation;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** @returns {Baggage} */
|
|
43
|
+
export const getBaggage = () => {
|
|
44
|
+
return incarnation.fakeVomKit.cm.provideBaggage();
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {ReincarnateOptions} [fromIncarnation]
|
|
49
|
+
*/
|
|
50
|
+
export const nextLife = (fromIncarnation = incarnation) => {
|
|
51
|
+
incarnation = reincarnate(fromIncarnation);
|
|
52
|
+
incarnationNumber += 1;
|
|
53
|
+
return incarnation;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @template {(baggage: Baggage) => Promise<any> | any} B
|
|
58
|
+
* @param {B} build
|
|
59
|
+
* @param {(tools: Awaited<ReturnType<B>>) => Promise<void> | void} [run]
|
|
60
|
+
* @param {object} [options]
|
|
61
|
+
* @param {ReincarnateOptions} [options.fromIncarnation]
|
|
62
|
+
* @param {boolean} [options.cleanStart]
|
|
63
|
+
*/
|
|
64
|
+
export const startLife = async (
|
|
65
|
+
build,
|
|
66
|
+
run,
|
|
67
|
+
{ fromIncarnation, cleanStart } = {},
|
|
68
|
+
) => {
|
|
69
|
+
await eventLoopIteration();
|
|
70
|
+
if (cleanStart) annihilate();
|
|
71
|
+
const oldIncarnationNumber = incarnationNumber;
|
|
72
|
+
const oldIncarnation = incarnation;
|
|
73
|
+
const disconnectionObject = makeUpgradeDisconnection(
|
|
74
|
+
'vat upgraded',
|
|
75
|
+
oldIncarnationNumber,
|
|
76
|
+
);
|
|
77
|
+
const { fakeVomKit } = nextLife(fromIncarnation);
|
|
78
|
+
/** @type {Map<string, PromiseKit<any>>} */
|
|
79
|
+
const previouslyWatchedPromises = new Map();
|
|
80
|
+
let buildTools;
|
|
81
|
+
try {
|
|
82
|
+
buildTools = await build(getBaggage());
|
|
83
|
+
fakeVomKit.wpm.loadWatchedPromiseTable(vref => {
|
|
84
|
+
// See revivePromise in liveslots.js
|
|
85
|
+
const { getValForSlot, valToSlot, setValForSlot } = fakeVomKit.fakeStuff;
|
|
86
|
+
// Assume all promises were decided by the previous incarnation
|
|
87
|
+
!getValForSlot(vref) || Fail`Attempting to revive known promise ${vref}`;
|
|
88
|
+
const pk = makePromiseKit();
|
|
89
|
+
previouslyWatchedPromises.set(vref, pk);
|
|
90
|
+
const val = pk.promise;
|
|
91
|
+
valToSlot.set(val, vref);
|
|
92
|
+
setValForSlot(vref, val);
|
|
93
|
+
return val;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
fakeVomKit.vom.insistAllDurableKindsReconnected();
|
|
97
|
+
|
|
98
|
+
await eventLoopIteration();
|
|
99
|
+
// End of start crank
|
|
100
|
+
} catch (err) {
|
|
101
|
+
// Rollback upgrade
|
|
102
|
+
incarnation = oldIncarnation;
|
|
103
|
+
incarnationNumber = oldIncarnationNumber;
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Simulate a dispatch of previously decided promise rejections
|
|
108
|
+
// In real swingset this could happen after some deliveries
|
|
109
|
+
for (const { reject } of previouslyWatchedPromises.values()) {
|
|
110
|
+
reject(disconnectionObject);
|
|
111
|
+
}
|
|
112
|
+
await eventLoopIteration();
|
|
113
|
+
// End of resolution dispatch crank
|
|
114
|
+
|
|
115
|
+
if (run) {
|
|
116
|
+
await run(buildTools);
|
|
117
|
+
await eventLoopIteration();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return incarnation;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// Setup the initial incarnation
|
|
124
|
+
annihilate();
|
package/tools/setup-vat-data.js
CHANGED
|
@@ -12,7 +12,9 @@ import { makeFakeVirtualStuff } from './fakeVirtualSupport.js';
|
|
|
12
12
|
|
|
13
13
|
const { WeakMap, WeakSet } = globalThis;
|
|
14
14
|
|
|
15
|
-
/** @
|
|
15
|
+
/** @typedef {ReturnType<typeof makeFakeVirtualStuff>} FakeVomKit */
|
|
16
|
+
|
|
17
|
+
/** @type {FakeVomKit} */
|
|
16
18
|
let fakeVomKit;
|
|
17
19
|
|
|
18
20
|
globalThis.VatData = harden({
|
|
@@ -44,18 +46,43 @@ globalThis.VatData = harden({
|
|
|
44
46
|
|
|
45
47
|
globalThis[PassStyleOfEndowmentSymbol] = passStyleOf;
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
/**
|
|
50
|
+
* @typedef {import("@agoric/internal").Simplify<
|
|
51
|
+
* Omit<NonNullable<Parameters<typeof makeFakeVirtualStuff>[0]>, 'WeakMap' | 'WeakSet'> &
|
|
52
|
+
* { fakeVomKit: FakeVomKit; fakeStore: Map<string, string> }
|
|
53
|
+
* >} ReincarnateOptions
|
|
54
|
+
*/
|
|
49
55
|
|
|
50
|
-
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @param {Partial<ReincarnateOptions>} options
|
|
59
|
+
* @returns {Omit<ReincarnateOptions, 'fakeVomKit'>}
|
|
60
|
+
*/
|
|
61
|
+
export const flushIncarnation = (options = {}) => {
|
|
62
|
+
const { fakeVomKit: fvk = fakeVomKit, ...fakeStuffOptions } = options;
|
|
63
|
+
|
|
64
|
+
if (fvk) {
|
|
51
65
|
fvk.vom.flushStateCache();
|
|
52
66
|
fvk.cm.flushSchemaCache();
|
|
53
67
|
fvk.vrm.flushIDCounters();
|
|
54
68
|
}
|
|
55
69
|
|
|
70
|
+
// Clone previous fakeStore (if any) to avoid mutations from previous incarnation
|
|
71
|
+
const fakeStore = new Map(options.fakeStore);
|
|
72
|
+
|
|
73
|
+
return { ...fakeStuffOptions, fakeStore };
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @param {Partial<ReincarnateOptions>} options
|
|
79
|
+
* @returns {ReincarnateOptions}
|
|
80
|
+
*/
|
|
81
|
+
export const reincarnate = (options = {}) => {
|
|
82
|
+
const clonedIncarnation = flushIncarnation(options);
|
|
83
|
+
|
|
56
84
|
fakeVomKit = makeFakeVirtualStuff({
|
|
57
|
-
...
|
|
58
|
-
fakeStore,
|
|
85
|
+
...clonedIncarnation,
|
|
59
86
|
WeakMap,
|
|
60
87
|
WeakSet,
|
|
61
88
|
});
|
|
@@ -65,5 +92,5 @@ export const reincarnate = (options = {}) => {
|
|
|
65
92
|
// @ts-expect-error ditto
|
|
66
93
|
globalThis.WeakSet = fakeVomKit.vom.VirtualObjectAwareWeakSet;
|
|
67
94
|
|
|
68
|
-
return { ...
|
|
95
|
+
return { ...clonedIncarnation, fakeVomKit };
|
|
69
96
|
};
|
package/src/vatDataTypes.d.ts
DELETED
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Types for vat-data
|
|
3
|
-
*
|
|
4
|
-
* Facet is a single object with methods.
|
|
5
|
-
* Behavior is a description when defining a kind of what facets it will have.
|
|
6
|
-
* For the non-multi defineKind, there is just one facet so it doesn't have a key.
|
|
7
|
-
*/
|
|
8
|
-
import type {
|
|
9
|
-
MapStore,
|
|
10
|
-
SetStore,
|
|
11
|
-
StoreOptions,
|
|
12
|
-
WeakMapStore,
|
|
13
|
-
WeakSetStore,
|
|
14
|
-
} from '@agoric/store';
|
|
15
|
-
import type { Amplify, IsInstance, ReceivePower, StateShape } from '@endo/exo';
|
|
16
|
-
import type { RemotableObject } from '@endo/pass-style';
|
|
17
|
-
import type { RemotableBrand } from '@endo/eventual-send';
|
|
18
|
-
import type { InterfaceGuard, Pattern } from '@endo/patterns';
|
|
19
|
-
import type { makeWatchedPromiseManager } from './watchedPromises.js';
|
|
20
|
-
|
|
21
|
-
// TODO should be moved into @endo/patterns and eventually imported here
|
|
22
|
-
// instead of this local definition.
|
|
23
|
-
export type InterfaceGuardKit = Record<string, InterfaceGuard>;
|
|
24
|
-
export type { MapStore, Pattern };
|
|
25
|
-
|
|
26
|
-
// This needs `any` values. If they were `unknown`, code that uses Baggage
|
|
27
|
-
// would need explicit runtime checks or casts for every fetch, which is
|
|
28
|
-
// onerous.
|
|
29
|
-
export type Baggage = MapStore<string, any>;
|
|
30
|
-
|
|
31
|
-
type WatchedPromisesManager = ReturnType<typeof makeWatchedPromiseManager>;
|
|
32
|
-
|
|
33
|
-
type Tail<T extends any[]> = T extends [head: any, ...rest: infer Rest]
|
|
34
|
-
? Rest
|
|
35
|
-
: [];
|
|
36
|
-
|
|
37
|
-
// used to omit the 'context' parameter
|
|
38
|
-
type OmitFirstArg<F> = F extends (x: any, ...args: infer P) => infer R
|
|
39
|
-
? (...args: P) => R
|
|
40
|
-
: never;
|
|
41
|
-
|
|
42
|
-
// The type of a passable local object with methods.
|
|
43
|
-
// An internal helper to avoid having to repeat `O`.
|
|
44
|
-
type PrimaryRemotable<O> = O & RemotableObject & RemotableBrand<{}, O>;
|
|
45
|
-
|
|
46
|
-
export type KindFacet<O> = PrimaryRemotable<{
|
|
47
|
-
[K in keyof O]: OmitFirstArg<O[K]>; // omit the 'context' parameter
|
|
48
|
-
}>;
|
|
49
|
-
|
|
50
|
-
export type KindFacets<B> = {
|
|
51
|
-
[FacetKey in keyof B]: KindFacet<B[FacetKey]>;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export type KindContext<S, F> = { state: S; self: KindFacet<F> };
|
|
55
|
-
export type MultiKindContext<S, B> = { state: S; facets: KindFacets<B> };
|
|
56
|
-
|
|
57
|
-
export type PlusContext<C, M extends (...args: any[]) => any> = (
|
|
58
|
-
c: C,
|
|
59
|
-
...args: Parameters<M>
|
|
60
|
-
) => ReturnType<M>;
|
|
61
|
-
|
|
62
|
-
export type FunctionsPlusContext<
|
|
63
|
-
C,
|
|
64
|
-
O extends Record<string, (...args: any[]) => any>,
|
|
65
|
-
> = {
|
|
66
|
-
[K in keyof O]: PlusContext<C, O[K]>;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
declare class DurableKindHandleClass {
|
|
70
|
-
private descriptionTag: string;
|
|
71
|
-
}
|
|
72
|
-
export type DurableKindHandle = DurableKindHandleClass;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Grab bag of options that can be provided to `defineDurableKind` and its
|
|
76
|
-
* siblings. Not all options are meaningful in all contexts. See the
|
|
77
|
-
* doc-comments on each option.
|
|
78
|
-
*/
|
|
79
|
-
export type DefineKindOptions<C> = {
|
|
80
|
-
/**
|
|
81
|
-
* If provided, the `finish` function will be called after the instance is
|
|
82
|
-
* made and internally registered, but before it is returned. The finish
|
|
83
|
-
* function is to do any post-intantiation initialization that should be
|
|
84
|
-
* done before exposing the object to its clients.
|
|
85
|
-
*/
|
|
86
|
-
finish?: (context: C) => void;
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* If provided, it describes the shape of all state records of instances
|
|
90
|
-
* of this kind.
|
|
91
|
-
*/
|
|
92
|
-
stateShape?: StateShape;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* If a `receiveAmplifier` function is provided to an exo class kit definition,
|
|
96
|
-
* it will be called with an `Amplify` function. If provided to the definition
|
|
97
|
-
* of a normal exo or exo class, the definition will throw, since only
|
|
98
|
-
* exo kits can be amplified.
|
|
99
|
-
* An `Amplify` function is a function that takes a facet instance of
|
|
100
|
-
* this class kit as an argument, in which case it will return the facets
|
|
101
|
-
* record, giving access to all the facet instances of the same cohort.
|
|
102
|
-
*/
|
|
103
|
-
receiveAmplifier?: ReceivePower<Amplify>;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* If a `receiveInstanceTester` function is provided, it will be called
|
|
107
|
-
* during the definition of the exo class or exo class kit with an
|
|
108
|
-
* `IsInstance` function. The first argument of `IsInstance`
|
|
109
|
-
* is the value to be tested. When it may be a facet instance of an
|
|
110
|
-
* exo class kit, the optional second argument, if provided, is
|
|
111
|
-
* a `facetName`. In that case, the function tests only if the first
|
|
112
|
-
* argument is an instance of that facet of the associated exo class kit.
|
|
113
|
-
*/
|
|
114
|
-
receiveInstanceTester?: ReceivePower<IsInstance>;
|
|
115
|
-
|
|
116
|
-
// TODO properties above are identical to those in FarClassOptions.
|
|
117
|
-
// These are the only options that should be exposed by
|
|
118
|
-
// vat-data's public virtual/durable exo APIs. This DefineKindOptions
|
|
119
|
-
// should explicitly be a subtype, where the methods below are only for
|
|
120
|
-
// internal use, i.e., below the exo level.
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* As a kind option, intended for internal use only.
|
|
124
|
-
* Meaningful to `makeScalarBigMapStore` and its siblings. These maker
|
|
125
|
-
* fuctions will make either virtual or durable stores, depending on
|
|
126
|
-
* this flag. Defaults to off, making virtual but not durable collections.
|
|
127
|
-
*
|
|
128
|
-
* Generally, durable collections are provided with `provideDurableMapStore`
|
|
129
|
-
* and its sibling, which use this flag internally. If you do not make
|
|
130
|
-
* durable collections by other means, you can consider this as
|
|
131
|
-
* intended for internal use only.
|
|
132
|
-
*/
|
|
133
|
-
durable?: boolean;
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Intended for internal use only.
|
|
137
|
-
* Should the raw methods receive their `context` argument as their first
|
|
138
|
-
* argument or as their `this` binding? For `defineDurableKind` and its
|
|
139
|
-
* siblings (including `prepareSingleton`), this defaults to off, meaning that
|
|
140
|
-
* their behavior methods receive `context` as their first argument.
|
|
141
|
-
* `prepareExoClass` and its siblings (including `prepareExo`) use
|
|
142
|
-
* this flag internally to indicate that their methods receive `context`
|
|
143
|
-
* as their `this` binding.
|
|
144
|
-
*/
|
|
145
|
-
thisfulMethods?: boolean;
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Intended for internal use only.
|
|
149
|
-
* Only applicable if this is a class kind. A class kit kind should use
|
|
150
|
-
* `interfaceGuardKit` instead.
|
|
151
|
-
*
|
|
152
|
-
* If an `interfaceGuard` is provided, then the raw methods passed alongside
|
|
153
|
-
* it are wrapped by a function that first checks that this method's guard
|
|
154
|
-
* pattern is satisfied before calling the raw method.
|
|
155
|
-
*
|
|
156
|
-
* In `defineDurableKind` and its siblings, this defaults to `undefined`.
|
|
157
|
-
* Exo classes use this internally to protect their raw class methods
|
|
158
|
-
* using the provided interface.
|
|
159
|
-
* In absence, an exo is protected anyway, while a bare kind is
|
|
160
|
-
* not (detected by `!thisfulMethods`),
|
|
161
|
-
*/
|
|
162
|
-
interfaceGuard?: InterfaceGuard;
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Intended for internal use only.
|
|
166
|
-
* Only applicable if this is a class kit kind. A class kind should use
|
|
167
|
-
* `interfaceGuard` instead.
|
|
168
|
-
*
|
|
169
|
-
* If an `interfaceGuardKit` is provided, then each member of the
|
|
170
|
-
* interfaceGuardKit is used to guard the corresponding facet of the
|
|
171
|
-
* class kit.
|
|
172
|
-
*
|
|
173
|
-
* In `defineDurableKindMulti` and its siblings, this defaults to `undefined`.
|
|
174
|
-
* Exo class kits use this internally to protect their facets.
|
|
175
|
-
* In absence, an exo is protected anyway, while a bare kind is
|
|
176
|
-
* not (detected by `!thisfulMethods`),
|
|
177
|
-
*/
|
|
178
|
-
interfaceGuardKit?: InterfaceGuardKit;
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
export type VatData = {
|
|
182
|
-
// virtual kinds
|
|
183
|
-
/** @deprecated Use defineVirtualExoClass instead */
|
|
184
|
-
defineKind: <P extends Array<any>, S, F>(
|
|
185
|
-
tag: string,
|
|
186
|
-
init: (...args: P) => S,
|
|
187
|
-
facet: F,
|
|
188
|
-
options?: DefineKindOptions<KindContext<S, F>>,
|
|
189
|
-
) => (...args: P) => KindFacet<F>;
|
|
190
|
-
|
|
191
|
-
/** @deprecated Use defineVirtualExoClassKit instead */
|
|
192
|
-
defineKindMulti: <P extends Array<any>, S, B>(
|
|
193
|
-
tag: string,
|
|
194
|
-
init: (...args: P) => S,
|
|
195
|
-
behavior: B,
|
|
196
|
-
options?: DefineKindOptions<MultiKindContext<S, B>>,
|
|
197
|
-
) => (...args: P) => KindFacets<B>;
|
|
198
|
-
|
|
199
|
-
// durable kinds
|
|
200
|
-
makeKindHandle: (descriptionTag: string) => DurableKindHandle;
|
|
201
|
-
|
|
202
|
-
/** @deprecated Use defineDurableExoClass instead */
|
|
203
|
-
defineDurableKind: <P extends Array<any>, S, F>(
|
|
204
|
-
kindHandle: DurableKindHandle,
|
|
205
|
-
init: (...args: P) => S,
|
|
206
|
-
facet: F,
|
|
207
|
-
options?: DefineKindOptions<KindContext<S, F>>,
|
|
208
|
-
) => (...args: P) => KindFacet<F>;
|
|
209
|
-
|
|
210
|
-
/** @deprecated Use defineDurableExoClassKit instead */
|
|
211
|
-
defineDurableKindMulti: <P extends Array<any>, S, B>(
|
|
212
|
-
kindHandle: DurableKindHandle,
|
|
213
|
-
init: (...args: P) => S,
|
|
214
|
-
behavior: B,
|
|
215
|
-
options?: DefineKindOptions<MultiKindContext<S, B>>,
|
|
216
|
-
) => (...args: P) => KindFacets<B>;
|
|
217
|
-
|
|
218
|
-
providePromiseWatcher: WatchedPromisesManager['providePromiseWatcher'];
|
|
219
|
-
watchPromise: WatchedPromisesManager['watchPromise'];
|
|
220
|
-
|
|
221
|
-
makeScalarBigMapStore: <K, V>(
|
|
222
|
-
label: string,
|
|
223
|
-
options?: StoreOptions,
|
|
224
|
-
) => MapStore<K, V>;
|
|
225
|
-
makeScalarBigWeakMapStore: <K, V>(
|
|
226
|
-
label: string,
|
|
227
|
-
options?: StoreOptions,
|
|
228
|
-
) => WeakMapStore<K, V>;
|
|
229
|
-
|
|
230
|
-
makeScalarBigSetStore: <K>(
|
|
231
|
-
label: string,
|
|
232
|
-
options?: StoreOptions,
|
|
233
|
-
) => SetStore<K>;
|
|
234
|
-
makeScalarBigWeakSetStore: <K>(
|
|
235
|
-
label: string,
|
|
236
|
-
options?: StoreOptions,
|
|
237
|
-
) => WeakSetStore<K>;
|
|
238
|
-
canBeDurable: (specimen: unknown) => boolean;
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
// The JSDoc is repeated here and at the function definition so it appears
|
|
242
|
-
// in IDEs where it's used, regardless of type resolution.
|
|
243
|
-
export interface PickFacet {
|
|
244
|
-
/**
|
|
245
|
-
* When making a multi-facet kind, it's common to pick one facet to
|
|
246
|
-
* expose. E.g.,
|
|
247
|
-
*
|
|
248
|
-
* const makeFoo = (a, b, c, d) => makeFooBase(a, b, c, d).self;
|
|
249
|
-
*
|
|
250
|
-
* This helper reduces the duplication:
|
|
251
|
-
*
|
|
252
|
-
* const makeFoo = pickFacet(makeFooBase, 'self');
|
|
253
|
-
*/
|
|
254
|
-
<M extends (...args: any[]) => any, F extends keyof ReturnType<M>>(
|
|
255
|
-
maker: M,
|
|
256
|
-
facetName: F,
|
|
257
|
-
): (...args: Parameters<M>) => ReturnType<M>[F];
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/** @deprecated Use prepareExoClass instead */
|
|
261
|
-
export type PrepareKind = <P extends Array<any>, S, F>(
|
|
262
|
-
baggage: Baggage,
|
|
263
|
-
tag: string,
|
|
264
|
-
init: (...args: P) => S,
|
|
265
|
-
facet: F,
|
|
266
|
-
options?: DefineKindOptions<KindContext<S, F>>,
|
|
267
|
-
) => (...args: P) => KindFacet<F>;
|
|
268
|
-
|
|
269
|
-
/** @deprecated Use prepareExoClassKit instead */
|
|
270
|
-
export type PrepareKindMulti = <P extends Array<any>, S, B>(
|
|
271
|
-
baggage: Baggage,
|
|
272
|
-
tag: string,
|
|
273
|
-
init: (...args: P) => S,
|
|
274
|
-
behavior: B,
|
|
275
|
-
options?: DefineKindOptions<MultiKindContext<S, B>>,
|
|
276
|
-
) => (...args: P) => KindFacets<B>;
|
package/src/vatDataTypes.js
DELETED