@agoric/vow 0.1.1-dev-0af876f.0 → 0.1.1-dev-a4f86eb.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/vow",
3
- "version": "0.1.1-dev-0af876f.0+0af876f",
3
+ "version": "0.1.1-dev-a4f86eb.0+a4f86eb",
4
4
  "description": "Remote (shortening and disconnection-tolerant) Promise-likes",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -20,8 +20,8 @@
20
20
  "lint:types": "tsc"
21
21
  },
22
22
  "dependencies": {
23
- "@agoric/base-zone": "0.1.1-dev-0af876f.0+0af876f",
24
- "@agoric/internal": "0.3.3-dev-0af876f.0+0af876f",
23
+ "@agoric/base-zone": "0.1.1-dev-a4f86eb.0+a4f86eb",
24
+ "@agoric/internal": "0.3.3-dev-a4f86eb.0+a4f86eb",
25
25
  "@endo/env-options": "^1.1.4",
26
26
  "@endo/eventual-send": "^1.2.2",
27
27
  "@endo/pass-style": "^1.4.0",
@@ -53,5 +53,5 @@
53
53
  "typeCoverage": {
54
54
  "atLeast": 89.6
55
55
  },
56
- "gitHead": "0af876fb087f76a8144730969bb88b13403d02db"
56
+ "gitHead": "a4f86eb7fd602980a40d00d739897090d3667d3d"
57
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["watch.js"],"names":[],"mappings":"AAkIO,mCAJI,IAAI,cACJ,MAAM,OAAO,GAAG,CAAC,gCACR,GAAG,aAAa,GAAG,KAAK,GAAG,iBAe/B,CAAC,QACD,QAAQ,MACR,QAAQ,UACA,CAAC,SAAT,GAAG,EAAG,qBACT,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,2EAEhB,CAAC,yIAoBb;oBAIa,UAAU,CAAC,OAAO,YAAY,CAAC;0BAtKJ,mBAAmB;4BACmB,YAAY;yBAAZ,YAAY;0BAAZ,YAAY;6BAAZ,YAAY"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["watch.js"],"names":[],"mappings":"AA2JO,mCAJI,IAAI,cACJ,MAAM,OAAO,GAAG,CAAC,gCACR,GAAG,aAAa,GAAG,KAAK,GAAG,iBAe/B,CAAC,QACD,QAAQ,MACR,QAAQ,UACA,CAAC,SAAT,GAAG,EAAG,qBACT,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,2EAEhB,CAAC,yIAoBb;oBAIa,UAAU,CAAC,OAAO,YAAY,CAAC;0BA/LJ,mBAAmB;4BACmB,YAAY;yBAAZ,YAAY;0BAAZ,YAAY;6BAAZ,YAAY"}
package/src/watch.js CHANGED
@@ -65,8 +65,23 @@ const settle = (resolver, watcher, wcb, value, watcherArgs = []) => {
65
65
  * @param {IsRetryableReason} isRetryableReason
66
66
  * @param {ReturnType<typeof makeWatchNextStep>} watchNextStep
67
67
  */
68
- const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) =>
69
- zone.exoClass(
68
+ const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) => {
69
+ // We use an ephemeral WeakSet for the previously seen vows in a watch operation
70
+ // While watch is durable, it suffices to detect the cycle in a single incarnation
71
+ /** @type {WeakMap<PromiseWatcher, WeakSet<any>>} */
72
+ const watcherSeenPayloads = new WeakMap();
73
+
74
+ /** @param {PromiseWatcher} watcher */
75
+ const getSeenPayloads = watcher => {
76
+ let seenPayloads = watcherSeenPayloads.get(watcher);
77
+ if (!seenPayloads) {
78
+ seenPayloads = new WeakSet();
79
+ watcherSeenPayloads.set(watcher, seenPayloads);
80
+ }
81
+ return seenPayloads;
82
+ };
83
+
84
+ return zone.exoClass(
70
85
  'PromiseWatcher',
71
86
  PromiseWatcherI,
72
87
  /**
@@ -91,12 +106,20 @@ const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) =>
91
106
  /** @type {Required<PromiseWatcher>['onFulfilled']} */
92
107
  onFulfilled(value) {
93
108
  const { watcher, watcherArgs, resolver } = this.state;
94
- if (getVowPayload(value)) {
109
+ const payload = getVowPayload(value);
110
+ if (payload) {
111
+ const seenPayloads = getSeenPayloads(this.self);
112
+ // TODO: rely on endowed helper to get storable cap from payload
113
+ if (seenPayloads.has(payload.vowV0)) {
114
+ return this.self.onRejected(Error('Vow resolution cycle detected'));
115
+ }
116
+ seenPayloads.add(payload.vowV0);
95
117
  // We've been shortened, so reflect our state accordingly, and go again.
96
118
  this.state.vow = value;
97
119
  watchNextStep(value, this.self);
98
120
  return;
99
121
  }
122
+ watcherSeenPayloads.delete(this.self);
100
123
  this.state.priorRetryValue = undefined;
101
124
  this.state.watcher = undefined;
102
125
  this.state.resolver = undefined;
@@ -115,6 +138,7 @@ const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) =>
115
138
  return;
116
139
  }
117
140
  }
141
+ watcherSeenPayloads.delete(this.self);
118
142
  this.state.priorRetryValue = undefined;
119
143
  this.state.resolver = undefined;
120
144
  this.state.watcher = undefined;
@@ -122,6 +146,7 @@ const preparePromiseWatcher = (zone, isRetryableReason, watchNextStep) =>
122
146
  },
123
147
  },
124
148
  );
149
+ };
125
150
 
126
151
  /**
127
152
  * @param {Zone} zone
package/src/when.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"when.d.ts","sourceRoot":"","sources":["when.js"],"names":[],"mappings":"AAQO,8EAMQ,CAAC,EACA,QAAQ,eACR,QAAQ,qBACX,CAAC,yBACO,QAAQ,CAAC,CAAC,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,sCAC9C,GAAG,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,kBAC/C,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,CA2C1C;mBAIa,UAAU,CAAC,OAAO,QAAQ,CAAC;uCAhEO,YAAY;6BAAZ,YAAY"}
1
+ {"version":3,"file":"when.d.ts","sourceRoot":"","sources":["when.js"],"names":[],"mappings":"AAQO,8EAMQ,CAAC,EACA,QAAQ,eACR,QAAQ,qBACX,CAAC,yBACO,QAAQ,CAAC,CAAC,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,sCAC9C,GAAG,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,kBAC/C,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAmD1C;mBAIa,UAAU,CAAC,OAAO,QAAQ,CAAC;uCAxEO,YAAY;6BAAZ,YAAY"}
package/src/when.js CHANGED
@@ -28,11 +28,19 @@ export const makeWhen = (
28
28
  let result = await specimenP;
29
29
  let payload = getVowPayload(result);
30
30
  let priorRetryValue;
31
+ const seenPayloads = new WeakSet();
31
32
  while (payload) {
32
- result = await basicE(payload.vowV0)
33
+ // TODO: rely on endowed helpers for getting storable cap and performing
34
+ // shorten "next step"
35
+ const { vowV0 } = payload;
36
+ if (seenPayloads.has(vowV0)) {
37
+ throw Error('Vow resolution cycle detected');
38
+ }
39
+ result = await basicE(vowV0)
33
40
  .shorten()
34
41
  .then(
35
42
  res => {
43
+ seenPayloads.add(vowV0);
36
44
  priorRetryValue = undefined;
37
45
  return res;
38
46
  },