@agoric/internal 0.3.3-dev-1983095.0.1983095 → 0.3.3-dev-12db75d.0.12db75d

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/internal",
3
- "version": "0.3.3-dev-1983095.0.1983095",
3
+ "version": "0.3.3-dev-12db75d.0.12db75d",
4
4
  "description": "Externally unsupported utilities internal to agoric-sdk",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -20,7 +20,8 @@
20
20
  "lint:types": "yarn run -T tsc"
21
21
  },
22
22
  "dependencies": {
23
- "@agoric/base-zone": "0.1.1-dev-1983095.0.1983095",
23
+ "@agoric/base-zone": "0.1.1-dev-12db75d.0.12db75d",
24
+ "@endo/cache-map": "^1.1.0",
24
25
  "@endo/common": "^1.2.13",
25
26
  "@endo/compartment-mapper": "^1.6.3",
26
27
  "@endo/errors": "^1.2.13",
@@ -37,7 +38,7 @@
37
38
  "jessie.js": "^0.3.4"
38
39
  },
39
40
  "devDependencies": {
40
- "@agoric/cosmic-proto": "0.4.1-dev-1983095.0.1983095",
41
+ "@agoric/cosmic-proto": "0.4.1-dev-12db75d.0.12db75d",
41
42
  "@endo/exo": "^1.5.12",
42
43
  "@endo/init": "^1.1.12",
43
44
  "@endo/ses-ava": "^1.3.2",
@@ -65,5 +66,5 @@
65
66
  "typeCoverage": {
66
67
  "atLeast": 93.22
67
68
  },
68
- "gitHead": "19830957a8b4729ff4416240f0a20fde629744df"
69
+ "gitHead": "12db75daac43c6691a8e871585a8419839ad5fa9"
69
70
  }
@@ -35,6 +35,7 @@ export function makeStorageNodeChild(storageNodeRef: ERef<Remote<StorageNode> |
35
35
  * @import {ERef} from '@endo/far';
36
36
  * @import {Marshal, Passable} from '@endo/marshal';
37
37
  * @import {Remote, ERemote, TypedPattern} from './types.js';
38
+ * @import {EMarshaller} from './marshal/wrap-marshaller.js';
38
39
  */
39
40
  /** @typedef {Marshal<unknown>} Marshaller */
40
41
  /** @typedef {Pick<Marshaller, 'fromCapData'>} Unserializer */
@@ -69,7 +70,7 @@ export function prepareChainStorageNode(zone: import("@agoric/base-zone").Zone):
69
70
  }): StorageNode;
70
71
  setValue(value: string): Promise<void>;
71
72
  }>;
72
- export function makeSerializeToStorage(storageNode: ERemote<StorageNode>, marshaller: ERemote<Marshaller>): (value: Passable) => Promise<void>;
73
+ export function makeSerializeToStorage(storageNode: ERemote<StorageNode>, marshaller: ERemote<EMarshaller>): (value: Passable) => Promise<void>;
73
74
  export type Marshaller = Marshal<unknown>;
74
75
  export type Unserializer = Pick<Marshaller, "fromCapData">;
75
76
  /**
@@ -171,6 +172,7 @@ import type { Remote } from './types.js';
171
172
  import type { ERef } from '@endo/far';
172
173
  import type { TypedPattern } from './types.js';
173
174
  import type { ERemote } from './types.js';
175
+ import type { EMarshaller } from './marshal/wrap-marshaller.js';
174
176
  import type { Passable } from '@endo/marshal';
175
177
  import type { Marshal } from '@endo/marshal';
176
178
  //# sourceMappingURL=lib-chainStorage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lib-chainStorage.d.ts","sourceRoot":"","sources":["lib-chainStorage.js"],"names":[],"mappings":"AAkPA;;;;;;;;;;;;GAYG;AACH,2DATW,CAAC,OAAO,EAAE,cAAc,KAAK,GAAG,YAGhC,MAAM,gBAEd;IAA8B,QAAQ;CAGxC;;mBAnEqB,OAAO,CAAC,WAAW,CAAC;wBAWzB,MAAM,qBACO;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,WAAW;oBAYA,MAAM,GAAK,OAAO,CAAC,IAAI,CAAC;GAqDhD;AAcD;;;;;;;;GAQG;AACH,qDAJW,KAAK,OAAO,WAAW,CAAC,GAAG,IAAI,CAAC,aAChC,MAAM,GACJ,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAMxC;AA5RD;;;;GAIG;AAEH,6CAA6C;AAC7C,8DAA8D;AAE9D;;;;;;;;GAQG;AAEH;;;;;;GAMG;AAEH,uCAAuC;AACvC,8BADW,aAAa,UAAU,CAAC,CAIhC;AAwCI,mCAHI,GAAG,GACD,IAAI,IAAI,UAAU,CAOa;AAmB5C,qCAAqC;AACrC,gCADW,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAI/B;AAyCK,8CAFI,OAAO,mBAAmB,EAAE,IAAI,uDAwBxB,cAAc,KAAK,GAAG;;;;mBAiBnB,OAAO,CAAC,WAAW,CAAC;wBAWzB,MAAM,qBACO;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,WAAW;oBAYA,MAAM,GAAK,OAAO,CAAC,IAAI,CAAC;GA0BhD;AA+DM,oDAJI,QAAQ,WAAW,CAAC,cACpB,QAAQ,UAAU,CAAC,GACjB,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAQ9C;yBArSa,QAAQ,OAAO,CAAC;2BAChB,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC;;;;;eAM/B,MAAM;iBACN,MAAM;qBACN,MAAM;;;uBAKN,CAAC;;;;;iBAED,MAAM;YAEN,CAAC,EAAE;;;;;;;;;;;;;;;;cAoBH,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;;;;;aAC/B,MAAM,MAAM;;;;iBAEZ,MAAM,OAAO,CAAC,WAAW,CAAC;mBAC1B,CACT,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,KAC7B,WAAW;;;;;;;aA8BL,MAAM,OAAO,CAAC,MAAM,CAAC;;;;iBAErB,WAAW,CAAC,aAAa,CAAC;;;;;qBAC1B,MAAM,YAAY;;;;;4CAqBnB,KAAK,GACX,aAAa,GACb,KAAK,GACL,UAAU,GACV,SAAS,GACT,QAAQ,GACR,MAAM;;;;gDAGA,KAAK,GAAG,kBAAkB,GAAG,QAAQ;;;;mCAGrC,6BAA6B,GACnC,iCAAiC;;;;0CAG3B,CAAC,IAAI,EAAE,MAAM,CAAC;;;;2BAEd,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;;;;8CAErC,YAAY,EAAE;;;;6BAEd;IACJ,MAAM,EAAE,6BAA6B,CAAC;IACtC,IAAI,EAAE,2BAA2B,CAAC;CACnC,GACD;IACE,MAAM,EAAE,iCAAiC,CAAC;IAC1C,IAAI,EAAE,+BAA+B,CAAC;CACvC;4BAnIwC,YAAY;0BAFrC,WAAW;kCAEc,YAAY;6BAAZ,YAAY;8BADxB,eAAe;6BAAf,eAAe"}
1
+ {"version":3,"file":"lib-chainStorage.d.ts","sourceRoot":"","sources":["lib-chainStorage.js"],"names":[],"mappings":"AAmPA;;;;;;;;;;;;GAYG;AACH,2DATW,CAAC,OAAO,EAAE,cAAc,KAAK,GAAG,YAGhC,MAAM,gBAEd;IAA8B,QAAQ;CAGxC;;mBAnEqB,OAAO,CAAC,WAAW,CAAC;wBAWzB,MAAM,qBACO;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,WAAW;oBAYA,MAAM,GAAK,OAAO,CAAC,IAAI,CAAC;GAqDhD;AAcD;;;;;;;;GAQG;AACH,qDAJW,KAAK,OAAO,WAAW,CAAC,GAAG,IAAI,CAAC,aAChC,MAAM,GACJ,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAMxC;AA7RD;;;;;GAKG;AAEH,6CAA6C;AAC7C,8DAA8D;AAE9D;;;;;;;;GAQG;AAEH;;;;;;GAMG;AAEH,uCAAuC;AACvC,8BADW,aAAa,UAAU,CAAC,CAIhC;AAwCI,mCAHI,GAAG,GACD,IAAI,IAAI,UAAU,CAOa;AAmB5C,qCAAqC;AACrC,gCADW,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAI/B;AAyCK,8CAFI,OAAO,mBAAmB,EAAE,IAAI,uDAwBxB,cAAc,KAAK,GAAG;;;;mBAiBnB,OAAO,CAAC,WAAW,CAAC;wBAWzB,MAAM,qBACO;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,WAAW;oBAYA,MAAM,GAAK,OAAO,CAAC,IAAI,CAAC;GA0BhD;AA+DM,oDAJI,QAAQ,WAAW,CAAC,cACpB,QAAQ,WAAW,CAAC,GAClB,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAQ9C;yBArSa,QAAQ,OAAO,CAAC;2BAChB,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC;;;;;eAM/B,MAAM;iBACN,MAAM;qBACN,MAAM;;;uBAKN,CAAC;;;;;iBAED,MAAM;YAEN,CAAC,EAAE;;;;;;;;;;;;;;;;cAoBH,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;;;;;aAC/B,MAAM,MAAM;;;;iBAEZ,MAAM,OAAO,CAAC,WAAW,CAAC;mBAC1B,CACT,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,KAC7B,WAAW;;;;;;;aA8BL,MAAM,OAAO,CAAC,MAAM,CAAC;;;;iBAErB,WAAW,CAAC,aAAa,CAAC;;;;;qBAC1B,MAAM,YAAY;;;;;4CAqBnB,KAAK,GACX,aAAa,GACb,KAAK,GACL,UAAU,GACV,SAAS,GACT,QAAQ,GACR,MAAM;;;;gDAGA,KAAK,GAAG,kBAAkB,GAAG,QAAQ;;;;mCAGrC,6BAA6B,GACnC,iCAAiC;;;;0CAG3B,CAAC,IAAI,EAAE,MAAM,CAAC;;;;2BAEd,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;;;;8CAErC,YAAY,EAAE;;;;6BAEd;IACJ,MAAM,EAAE,6BAA6B,CAAC;IACtC,IAAI,EAAE,2BAA2B,CAAC;CACnC,GACD;IACE,MAAM,EAAE,iCAAiC,CAAC;IAC1C,IAAI,EAAE,+BAA+B,CAAC;CACvC;4BApIwC,YAAY;0BAFrC,WAAW;kCAEc,YAAY;6BAAZ,YAAY;iCAC9B,8BAA8B;8BAFxB,eAAe;6BAAf,eAAe"}
@@ -10,6 +10,7 @@ import * as cb from './callback.js';
10
10
  * @import {ERef} from '@endo/far';
11
11
  * @import {Marshal, Passable} from '@endo/marshal';
12
12
  * @import {Remote, ERemote, TypedPattern} from './types.js';
13
+ * @import {EMarshaller} from './marshal/wrap-marshaller.js';
13
14
  */
14
15
 
15
16
  /** @typedef {Marshal<unknown>} Marshaller */
@@ -296,7 +297,7 @@ harden(makeStorageNodeChild);
296
297
  // TODO find a better module for this
297
298
  /**
298
299
  * @param {ERemote<StorageNode>} storageNode
299
- * @param {ERemote<Marshaller>} marshaller
300
+ * @param {ERemote<EMarshaller>} marshaller
300
301
  * @returns {(value: Passable) => Promise<void>}
301
302
  */
302
303
  export const makeSerializeToStorage = (storageNode, marshaller) => {
@@ -0,0 +1,33 @@
1
+ export function wrapRemoteMarshallerSendSlotsOnly<Slot = unknown>(marshaller: ERemote<Pick<EMarshaller<Slot>, "fromCapData" | "toCapData">>, { serializeBodyFormat, errorTagging, ...otherMarshalOptions }?: MakeMarshalOptions, { valToSlot, slotToVal, cacheSeveredVal, }?: {
2
+ valToSlot?: WeakMapAPI<any, Slot> | null | undefined;
3
+ slotToVal?: WeakMapAPI<Slot, any> | null | undefined;
4
+ cacheSeveredVal?: boolean | undefined;
5
+ }): ReturnType<typeof Far<EMarshaller<Slot>>>;
6
+ export function wrapRemoteMarshallerDirectSend<Slot = unknown>(marshaller: ERemote<Pick<EMarshaller<Slot>, "fromCapData" | "toCapData">>): ReturnType<typeof Far<EMarshaller<Slot>>>;
7
+ export function wrapRemoteMarshaller<Slot = unknown>(marshaller: ERemote<Pick<EMarshaller<Slot>, "fromCapData" | "toCapData">>, { serializeBodyFormat, errorTagging, ...otherMarshalOptions }?: MakeMarshalOptions, { valToSlot, slotToVal, cacheSeveredVal, }?: {
8
+ valToSlot?: WeakMapAPI<any, Slot> | null | undefined;
9
+ slotToVal?: WeakMapAPI<Slot, any> | null | undefined;
10
+ cacheSeveredVal?: boolean | undefined;
11
+ }): ReturnType<typeof Far<EMarshaller<Slot>>>;
12
+ /**
13
+ * A Marshaller which methods may be async. Use this type to indicate accepting
14
+ * either a sync or async marshaller, usually through `E` eventual-sends.
15
+ */
16
+ export type EMarshaller<Slot = unknown> = Simplify<EOnly<Marshal<Slot>>>;
17
+ export type SlotWrapper<Slot = unknown> = ReturnType<typeof slotToWrapper<Slot>>;
18
+ import type { ERemote } from '../types.js';
19
+ import type { MakeMarshalOptions } from '@endo/marshal';
20
+ import type { WeakMapAPI } from '@endo/cache-map';
21
+ import { Far } from '@endo/far';
22
+ import type { Marshal } from '@endo/marshal';
23
+ import type { EOnly } from '@endo/eventual-send';
24
+ import type { Simplify } from '@endo/pass-style';
25
+ declare function slotToWrapper<Slot = unknown>(slot: Slot, iface?: string): {
26
+ /** @type {Slot} */
27
+ "__#private@#slot": Slot;
28
+ /** @type {InterfaceSpec} */
29
+ [Symbol.toStringTag]: `Alleged: ${string}` | "Remotable";
30
+ } & RemotableObject<`Alleged: ${string}` | "Remotable">;
31
+ import type { RemotableObject } from '@endo/pass-style';
32
+ export {};
33
+ //# sourceMappingURL=wrap-marshaller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap-marshaller.d.ts","sourceRoot":"","sources":["wrap-marshaller.js"],"names":[],"mappings":"AA4HO,kDATO,IAAI,wBACP,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,WAAW,CAAC,CAAC,kEAC7D,kBAAkB,+CAE1B;IAAiD,SAAS;IACT,SAAS;IACjC,eAAe;CACxC,GAAU,UAAU,CAAC,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CA4RrD;AAOM,+CAJO,IAAI,wBACP,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,WAAW,CAAC,CAAC,GAC3D,UAAU,CAAC,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAyBrD;AAxTM,qCATO,IAAI,wBACP,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,WAAW,CAAC,CAAC,kEAC7D,kBAAkB,+CAE1B;IAAiD,SAAS;IACT,SAAS;IACjC,eAAe;CACxC,GAAU,UAAU,CAAC,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CA4RrD;;;;;wBAjYa,IAAI,cACL,SAAS,MAAM,QAAQ,IAAI,CAAC,CAAC,CAAC;wBA+D7B,IAAI,cAAoB,UAAU,CAAC,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;6BAvElD,aAAa;wCAD0B,eAAe;gCAHnD,iBAAiB;oBAN1B,WAAW;6BASkC,eAAe;2BAFxD,qBAAqB;8BACD,kBAAkB;AA+D3C,+BAJD,IAAI,kBACP,IAAI,UACJ,MAAM,GAGJ;IA9Cb,mBAAmB;;IAGnB,4BAA4B;;IA2CK,mDAA8B,CAE5D;qCAlEqC,kBAAkB"}
@@ -0,0 +1,439 @@
1
+ // @ts-check
2
+ import { makeCacheMapKit } from '@endo/cache-map';
3
+ import { Fail, q } from '@endo/errors';
4
+ import { E } from '@endo/eventual-send';
5
+ import { Far } from '@endo/far';
6
+ import { PASS_STYLE } from '@endo/pass-style';
7
+ import { makeMarshal } from '@endo/marshal';
8
+ import { makeInaccessibleVal } from './inaccessible-val.js';
9
+
10
+ /**
11
+ * @import {WeakMapAPI} from '@endo/cache-map';
12
+ * @import {EOnly} from '@endo/eventual-send';
13
+ * @import {RemotableObject, Simplify} from '@endo/pass-style';
14
+ * @import {CapData, Passable, Marshal, MakeMarshalOptions} from '@endo/marshal';
15
+ * @import {ERemote} from '../types.js';
16
+ */
17
+
18
+ /**
19
+ * A Marshaller which methods may be async. Use this type to indicate accepting
20
+ * either a sync or async marshaller, usually through `E` eventual-sends.
21
+ *
22
+ * @template [Slot=unknown]
23
+ * @typedef {Simplify<EOnly<Marshal<Slot>>>} EMarshaller
24
+ */
25
+
26
+ const { slotToWrapper, wrapperToSlot } = (() => {
27
+ /** @typedef {'Remotable' | `Alleged: ${string}`} InterfaceSpec */
28
+
29
+ /** @template [Slot=unknown] */
30
+ class SlotWrapper {
31
+ /** @type {Slot} */
32
+ #slot;
33
+
34
+ /** @type {InterfaceSpec} */
35
+ [Symbol.toStringTag];
36
+
37
+ /**
38
+ * @param {Slot} slot
39
+ * @param {string} [iface]
40
+ */
41
+ constructor(slot, iface) {
42
+ if (iface == null || iface === 'Remotable') {
43
+ iface = 'Remotable';
44
+ } else if (!iface.startsWith('Alleged: ')) {
45
+ iface = `Alleged: ${iface}`;
46
+ }
47
+ this.#slot = slot;
48
+ this[Symbol.toStringTag] = /** @type {InterfaceSpec} */ (iface);
49
+ }
50
+
51
+ /** @param {SlotWrapper} wrapper */
52
+ static getSlot(wrapper) {
53
+ return wrapper.#slot;
54
+ }
55
+ }
56
+ Object.defineProperties(SlotWrapper.prototype, {
57
+ [PASS_STYLE]: { value: 'remotable' },
58
+ [Symbol.toStringTag]: { value: 'Alleged: SlotWrapper' },
59
+ });
60
+ Reflect.deleteProperty(SlotWrapper.prototype, 'constructor');
61
+ harden(SlotWrapper);
62
+
63
+ /**
64
+ * @type {<Slot = unknown>(
65
+ * wrapper: SlotWrapper<Slot> & RemotableObject<InterfaceSpec>,
66
+ * ) => Slot}
67
+ */
68
+ const getSlot = SlotWrapper.getSlot;
69
+
70
+ return {
71
+ /**
72
+ * @template [Slot=unknown]
73
+ * @param {Slot} slot
74
+ * @param {string} [iface]
75
+ */
76
+ slotToWrapper: (slot, iface) =>
77
+ /** @type {SlotWrapper<Slot> & RemotableObject<InterfaceSpec>} */ (
78
+ harden(new SlotWrapper(slot, iface))
79
+ ),
80
+
81
+ wrapperToSlot: getSlot,
82
+ };
83
+ })();
84
+
85
+ /**
86
+ * @template [Slot=unknown] @typedef {ReturnType<typeof slotToWrapper<Slot>>}
87
+ * SlotWrapper
88
+ */
89
+
90
+ const capacityOfDefaultCache = 50;
91
+
92
+ // TODO(https://github.com/Agoric/agoric-sdk/issues/12111)
93
+ // Check cost of using virtual-aware WeakMap in liveslots
94
+ /**
95
+ * @template K
96
+ * @template V
97
+ * @param {boolean} [weakKey]
98
+ */
99
+ const makeDefaultCacheMap = weakKey =>
100
+ /** @type {WeakMapAPI<K, V>} */ (
101
+ makeCacheMapKit(capacityOfDefaultCache, {
102
+ makeMap: weakKey ? WeakMap : Map,
103
+ }).cache
104
+ );
105
+
106
+ /**
107
+ * Wraps a marshaller, either sync or async, local or remote, into a local async
108
+ * marshaller which only sends slots for resolution to the wrapped marshaller.
109
+ * Optionally and by default, caches the resolution of slots.
110
+ *
111
+ * Assumes that a null-ish slot value is a severed presence that can be resolved
112
+ * locally. By default if a presence is mapped to a null-ish slot by the wrapped
113
+ * marshaller, that mapping is not cached, allowing the wrapped marshaller to
114
+ * create a mapping in the future.
115
+ *
116
+ * @template [Slot=unknown]
117
+ * @param {ERemote<Pick<EMarshaller<Slot>, 'fromCapData' | 'toCapData'>>} marshaller
118
+ * @param {MakeMarshalOptions} [marshalOptions]
119
+ * @param {object} [caches]
120
+ * @param {WeakMapAPI<object, Slot> | null} [caches.valToSlot]
121
+ * @param {WeakMapAPI<Slot, object> | null} [caches.slotToVal]
122
+ * @param {boolean} [caches.cacheSeveredVal]
123
+ * @returns {ReturnType<typeof Far<EMarshaller<Slot>>>}
124
+ */
125
+ export const wrapRemoteMarshallerSendSlotsOnly = (
126
+ marshaller,
127
+ {
128
+ serializeBodyFormat = 'smallcaps',
129
+ errorTagging = 'off', // Disable error tagging by default
130
+ ...otherMarshalOptions
131
+ } = {},
132
+ {
133
+ valToSlot = makeDefaultCacheMap(true),
134
+ slotToVal = makeDefaultCacheMap(false),
135
+ cacheSeveredVal = false,
136
+ } = {},
137
+ ) => {
138
+ const marshalOptions = harden({
139
+ serializeBodyFormat,
140
+ errorTagging,
141
+ ...otherMarshalOptions,
142
+ });
143
+ // The implementation of this wrapped marshaller internally uses 2 marshallers
144
+ // to transform the CapData into a Passable structure and vice-versa:
145
+ // - A cap pass-through marshaller which places capabilities as-is in the slots.
146
+ // When unserializing CapData with null-ish slots, a severed presence is created.
147
+ // This pass-through marshaller is used to locally process the structure, and
148
+ // separate capabilities into a slots array for potential resolution by the
149
+ // wrapped marshaller.
150
+ // - A "SlotWrapper" marshaller used to wrap into remotables the slots of the
151
+ // wrapped marshaller. When unserializing CapData, it is used to recreate
152
+ // CapData of a simple array of non-severed capabilities for resolution by
153
+ // the wrapped marshaller. When serializing to CapData, it allows extracting
154
+ // the slots from the capabilities array serialized by the wrapped marshaller.
155
+
156
+ /** @type {Marshal<object | null>} */
157
+ const passThroughMarshaller = makeMarshal(
158
+ undefined,
159
+ (slot, iface) => slot ?? makeInaccessibleVal(iface),
160
+ marshalOptions,
161
+ );
162
+
163
+ /** @type {Map<Slot, SlotWrapper<NonNullable<Slot>>>} */
164
+ const currentSlotToWrapper = new Map();
165
+
166
+ const convertWrapperToSlot = /** @type {typeof wrapperToSlot<Slot>} */ (
167
+ wrapperToSlot
168
+ );
169
+ /**
170
+ * @param {Slot} slot
171
+ * @param {string | undefined} [iface]
172
+ */
173
+ const convertSlotToWrapper = (slot, iface) => {
174
+ if (slot == null) {
175
+ // The wrapped marshaller may send us CapData with a null slot. These are not
176
+ // meant to be considered equivalent with each other, so bypass mapping.
177
+ return slotToWrapper(slot, iface);
178
+ }
179
+ let wrapper = currentSlotToWrapper.get(slot);
180
+ if (!wrapper) {
181
+ wrapper = slotToWrapper(slot, iface);
182
+ currentSlotToWrapper.set(slot, wrapper);
183
+ }
184
+
185
+ return wrapper;
186
+ };
187
+
188
+ /** @type {Pick<Marshal<Slot>, 'toCapData' | 'fromCapData'>} */
189
+ const slotWrapperMarshaller = makeMarshal(
190
+ convertWrapperToSlot,
191
+ convertSlotToWrapper,
192
+ marshalOptions,
193
+ );
194
+
195
+ /**
196
+ * Resolves an array of wrapped marshaller's slots to an array of
197
+ * capabilities.
198
+ *
199
+ * This is used by `fromCapData` to map slots before using the pass-through
200
+ * marshaller to recreate the passable data.
201
+ *
202
+ * @param {Slot[]} slots
203
+ * @param {(index: number) => SlotWrapper<NonNullable<Slot>>} getWrapper
204
+ * @returns {Promise<(object | null)[]>}
205
+ */
206
+ const mapSlotsToCaps = async (slots, getWrapper) => {
207
+ let hasRemoteCap = false;
208
+ const { length } = slots;
209
+ /** @type {(SlotWrapper<NonNullable<Slot>> | null | undefined)[]} */
210
+ const slotWrapperMappedSlots = Array.from({ length });
211
+ /** @type {(object | null | undefined)[]} */
212
+ const locallyResolvedCapSlots = Array.from({ length });
213
+
214
+ for (const [index, slot] of slots.entries()) {
215
+ if (slot === null) {
216
+ const nullSlot = /** @type {null} */ (slot);
217
+ slotWrapperMappedSlots[index] = nullSlot;
218
+ locallyResolvedCapSlots[index] = nullSlot;
219
+ } else if (slot !== undefined) {
220
+ const cachedCap = slotToVal?.get(slot);
221
+ if (cachedCap !== undefined) {
222
+ valToSlot?.set(cachedCap, slot);
223
+ locallyResolvedCapSlots[index] = cachedCap;
224
+ } else {
225
+ hasRemoteCap = true;
226
+ slotWrapperMappedSlots[index] = getWrapper(index);
227
+ }
228
+ }
229
+ }
230
+
231
+ await null;
232
+ if (hasRemoteCap) {
233
+ harden(slotWrapperMappedSlots);
234
+ const slotsOnlyCapData = slotWrapperMarshaller.toCapData(
235
+ slotWrapperMappedSlots,
236
+ );
237
+
238
+ /** @type {(object | null | undefined)[]} */
239
+ const remotelyResolvedCapSlots =
240
+ await E(marshaller).fromCapData(slotsOnlyCapData);
241
+
242
+ for (const [index, val] of remotelyResolvedCapSlots.entries()) {
243
+ if (val != null) {
244
+ const slot = slots[index];
245
+ slotToVal?.set(slot, val);
246
+ valToSlot?.set(val, slot);
247
+ locallyResolvedCapSlots[index] = val;
248
+ } else if (locallyResolvedCapSlots[index] === undefined) {
249
+ const slot = slots[index];
250
+ console.warn('⚠️ Unresolved local slot in wrapped marshaller', {
251
+ index,
252
+ slot,
253
+ });
254
+ }
255
+ }
256
+ }
257
+
258
+ return harden(locallyResolvedCapSlots);
259
+ };
260
+
261
+ /**
262
+ * Resolves an array of capabilities into an array of slots of the wrapped
263
+ * marshaller.
264
+ *
265
+ * This is used by `toCapData` to map slots after the pass-through marshaller
266
+ * has serialized the passable data.
267
+ *
268
+ * @param {object[]} caps
269
+ * @returns {Promise<Slot[]>}
270
+ */
271
+ const mapCapsToSlots = async caps => {
272
+ if (caps.length === 0) {
273
+ return caps;
274
+ }
275
+ let hasRemoteCap = false;
276
+ const { length } = caps;
277
+ /** @type {(Slot | null | undefined)[]} */
278
+ const locallyResolvedSlots = Array.from({ length });
279
+ /** @type {(object | null | undefined)[]} */
280
+ const remoteCapsToResolve = Array.from({ length });
281
+
282
+ for (const [index, cap] of caps.entries()) {
283
+ if (cap === null) {
284
+ // We shouldn't get null caps here, but we mirror handle them anyway
285
+ const nullCap = /** @type {null} */ (cap);
286
+ remoteCapsToResolve[index] = nullCap;
287
+ locallyResolvedSlots[index] = nullCap;
288
+ } else if (cap !== undefined) {
289
+ const cachedSlot = valToSlot?.get(cap);
290
+ if (cachedSlot !== undefined) {
291
+ if (cachedSlot !== null) {
292
+ slotToVal?.set(cachedSlot, cap);
293
+ }
294
+ locallyResolvedSlots[index] = cachedSlot;
295
+ } else {
296
+ hasRemoteCap = true;
297
+ remoteCapsToResolve[index] = cap;
298
+ }
299
+ }
300
+ }
301
+
302
+ await null;
303
+ if (hasRemoteCap) {
304
+ const remotelyResolvedSlotsCapData =
305
+ await E(marshaller).toCapData(remoteCapsToResolve);
306
+ try {
307
+ /** @type {(SlotWrapper<Slot> | null | undefined)[]} */
308
+ const slotWrapperMappedSlots = slotWrapperMarshaller.fromCapData(
309
+ remotelyResolvedSlotsCapData,
310
+ );
311
+ for (const [index, slotWrapper] of slotWrapperMappedSlots.entries()) {
312
+ if (slotWrapper != null) {
313
+ const slot = convertWrapperToSlot(slotWrapper);
314
+ const val = caps[index];
315
+ locallyResolvedSlots[index] = slot;
316
+ if (slot != null) {
317
+ slotToVal?.set(slot, val);
318
+ }
319
+ if (slot != null || cacheSeveredVal) {
320
+ valToSlot?.set(val, slot);
321
+ }
322
+ } else if (locallyResolvedSlots[index] === undefined) {
323
+ const cap = caps[index];
324
+ console.warn('⚠️ Unresolved local slot in wrapped marshaller', {
325
+ index,
326
+ cap,
327
+ });
328
+ }
329
+ }
330
+ } finally {
331
+ // We're done with the slotWrapperMarshaller, clear its state
332
+ currentSlotToWrapper.clear();
333
+ }
334
+ }
335
+
336
+ // All slots should have been resolved by now (or warned about)
337
+ return /** @type {Slot[]} */ (harden(locallyResolvedSlots));
338
+ };
339
+
340
+ /**
341
+ * Unfortunately CapData only contains iface information for slotted
342
+ * capabilities nested inside the body, which means we need to process the
343
+ * body to extract it. Maybe in the future CapData could be extended to carry
344
+ * this separately. See https://github.com/endojs/endo/issues/2991
345
+ *
346
+ * Since this helper is used internally to ultimately provide SlotWrapper
347
+ * objects to the corresponding marshaller, and that we use the same
348
+ * marshaller to extract the iface information, directly return the full
349
+ * SlotWrapper object instead of just the iface.
350
+ *
351
+ * @param {CapData<Slot>} data
352
+ */
353
+ const makeIfaceExtractor = data => {
354
+ const { slots } = data;
355
+ /** @param {number} index */
356
+ const getWrapper = index => {
357
+ const slot = slots[index];
358
+ let wrapper = currentSlotToWrapper.get(slot);
359
+ if (!wrapper) {
360
+ void slotWrapperMarshaller.fromCapData(data);
361
+ }
362
+ wrapper = currentSlotToWrapper.get(slot);
363
+ if (!wrapper) {
364
+ throw Fail`Marshaller didn't create wrapper for slot ${q(slot)} (index=${q(index)})`;
365
+ }
366
+ return wrapper;
367
+ };
368
+
369
+ return getWrapper;
370
+ };
371
+
372
+ /**
373
+ * @param {Passable} val
374
+ * @returns {Promise<CapData<Slot>>}
375
+ */
376
+ const toCapData = async val => {
377
+ const capData = passThroughMarshaller.toCapData(val);
378
+ const mappedSlots = await mapCapsToSlots(capData.slots);
379
+ return harden({ ...capData, slots: mappedSlots });
380
+ };
381
+
382
+ /**
383
+ * @param {CapData<Slot>} data
384
+ * @returns {Promise<Passable>}
385
+ */
386
+ const fromCapData = async data => {
387
+ const getWrapper = makeIfaceExtractor(data);
388
+ await null;
389
+ try {
390
+ const mappedSlots = await mapSlotsToCaps(data.slots, getWrapper);
391
+ return passThroughMarshaller.fromCapData({ ...data, slots: mappedSlots });
392
+ } finally {
393
+ currentSlotToWrapper.clear();
394
+ }
395
+ };
396
+
397
+ return Far('wrapped remote marshaller', {
398
+ toCapData,
399
+ fromCapData,
400
+
401
+ // for backwards compatibility
402
+ /** @deprecated use toCapData */
403
+ serialize: toCapData,
404
+ /** @deprecated use fromCapData */
405
+ unserialize: fromCapData,
406
+ });
407
+ };
408
+
409
+ /**
410
+ * @template [Slot=unknown]
411
+ * @param {ERemote<Pick<EMarshaller<Slot>, 'fromCapData' | 'toCapData'>>} marshaller
412
+ * @returns {ReturnType<typeof Far<EMarshaller<Slot>>>}
413
+ */
414
+ export const wrapRemoteMarshallerDirectSend = marshaller => {
415
+ /**
416
+ * @param {Passable} val
417
+ * @returns {Promise<CapData<Slot>>}
418
+ */
419
+ const toCapData = val => E(marshaller).toCapData(val);
420
+
421
+ /**
422
+ * @param {CapData<Slot>} data
423
+ * @returns {Promise<Passable>}
424
+ */
425
+ const fromCapData = data => E(marshaller).fromCapData(data);
426
+
427
+ return Far('wrapped remote marshaller', {
428
+ toCapData,
429
+ fromCapData,
430
+
431
+ // for backwards compatibility
432
+ /** @deprecated use toCapData */
433
+ serialize: toCapData,
434
+ /** @deprecated use fromCapData */
435
+ unserialize: fromCapData,
436
+ });
437
+ };
438
+
439
+ export const wrapRemoteMarshaller = wrapRemoteMarshallerSendSlotsOnly;
@@ -1 +1 @@
1
- {"version":3,"file":"storage-test-utils.d.ts","sourceRoot":"","sources":["storage-test-utils.js"],"names":[],"mappings":"AAyBO,yCAHI,MAAM,UACN,MAAM,6GAGC;AAElB;;;GAGG;AACH;;;;;EAEG;;eAMU,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO;mBAEzB,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM;;AA8CjC,8CAtBuB,GAAG,KAAK,GAAG,CAsB+B;AAU1D,6CAHI,MAAM,gBACN,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC;;;;;oBAwFrC,CAAb;;;;UAuDkB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;;sBAd3B,MAAM,KACJ,MAAM,EAAE;;0BA9FP,cAAc;;;8IAAd,cAAc;;;;EAiH7B;AAoBM,4CADO,oBAAoB,CA6BjC;AAUM,yCAPI,OAAO,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,WACvC,oBAAoB,GAAG,cAAc,QACrC,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAC9D,CAAK;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,EAAE,CAAC,GAAG;IAChD,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;CACpC,iBAkDL;6BAxGa,UAAU,CAAC,OAAO,kBAAkB,CAAC;;;;;;;;aAIrC,CACT,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,UAAU,EACvB,KAAK,CAAC,EAAE,MAAM,KACX,OAAO;UAKD,MAAM,MAAM,EAAE;;mCAEd,WAAW,GAAG,2BAA2B;qCAhQJ,uBAAuB;iCAOU,uBAAuB;oCAAvB,uBAAuB;gCAAvB,uBAAuB"}
1
+ {"version":3,"file":"storage-test-utils.d.ts","sourceRoot":"","sources":["storage-test-utils.js"],"names":[],"mappings":"AAyBO,yCAHI,MAAM,UACN,MAAM,6GAGC;AAElB;;;GAGG;AACH;;;;;EAEG;;eAMU,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO;mBAEzB,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM;;AA8CjC,8CAtBuB,GAAG,KAAK,GAAG,CAsB+B;AAU1D,6CAHI,MAAM,gBACN,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC;;;;;oBAyFvC,CAAC;;;;UAsDM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;;sBAd3B,MAAM,KACJ,MAAM,EAAE;;0BA9FP,cAAc;;;8IAAd,cAAc;;;;EAiH7B;AAoBM,4CADO,oBAAoB,CA6BjC;AAUM,yCAPI,OAAO,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,WACvC,oBAAoB,GAAG,cAAc,QACrC,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAC9D,CAAK;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,EAAE,CAAC,GAAG;IAChD,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;CACpC,iBAkDL;6BAxGa,UAAU,CAAC,OAAO,kBAAkB,CAAC;;;;;;;;aAIrC,CACT,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,UAAU,EACvB,KAAK,CAAC,EAAE,MAAM,KACX,OAAO;UAKD,MAAM,MAAM,EAAE;;mCAEd,WAAW,GAAG,2BAA2B;qCAhQJ,uBAAuB;iCAOU,uBAAuB;oCAAvB,uBAAuB;gCAAvB,uBAAuB"}