@agoric/casting 0.3.5-pismo-dev-0d5327f.0 → 0.4.1-dev-bf4b59f.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +1 -1
  3. package/jsconfig.build.json +12 -0
  4. package/jsconfig.json +1 -15
  5. package/node-fetch-shim.d.ts +2 -0
  6. package/node-fetch-shim.d.ts.map +1 -0
  7. package/node-fetch-shim.js +3 -0
  8. package/package.json +22 -17
  9. package/src/casting-spec.d.ts +16 -0
  10. package/src/casting-spec.d.ts.map +1 -0
  11. package/src/casting-spec.js +39 -6
  12. package/src/change-follower.d.ts +2 -0
  13. package/src/change-follower.d.ts.map +1 -0
  14. package/src/change-follower.js +0 -1
  15. package/src/defaults.d.ts +21 -0
  16. package/src/defaults.d.ts.map +1 -0
  17. package/src/defaults.js +8 -3
  18. package/src/follower-cosmjs.d.ts +12 -0
  19. package/src/follower-cosmjs.d.ts.map +1 -0
  20. package/src/follower-cosmjs.js +114 -143
  21. package/src/follower.d.ts +2 -0
  22. package/src/follower.d.ts.map +1 -0
  23. package/src/follower.js +7 -7
  24. package/src/iterable.d.ts +24 -0
  25. package/src/iterable.d.ts.map +1 -0
  26. package/src/iterable.js +3 -45
  27. package/src/leader-netconfig.d.ts +4 -0
  28. package/src/leader-netconfig.d.ts.map +1 -0
  29. package/src/leader-netconfig.js +7 -6
  30. package/src/leader.d.ts +2 -0
  31. package/src/leader.d.ts.map +1 -0
  32. package/src/leader.js +0 -1
  33. package/src/main.d.ts +9 -0
  34. package/src/main.d.ts.map +1 -0
  35. package/src/main.js +2 -0
  36. package/src/netconfig.d.ts +47 -0
  37. package/src/netconfig.d.ts.map +1 -0
  38. package/src/netconfig.js +40 -0
  39. package/src/shuffle.d.ts +2 -0
  40. package/src/shuffle.d.ts.map +1 -0
  41. package/src/shuffle.js +0 -2
  42. package/src/types.d.ts +54 -0
  43. package/src/types.d.ts.map +1 -0
  44. package/src/types.js +3 -3
  45. package/test/deploy.js +1 -2
  46. package/test/fake-rpc-server.js +6 -3
  47. package/test/test-mvp.js +1 -1
  48. package/test/test-netconfig.js +48 -0
@@ -1,38 +1,33 @@
1
- // @ts-check
2
1
  /// <reference types="ses"/>
3
- /* eslint-disable no-await-in-loop, no-continue, @jessie.js/no-nested-await */
2
+ /* eslint-disable no-await-in-loop, @jessie.js/no-nested-await */
4
3
 
5
4
  import { E, Far } from '@endo/far';
6
- import * as tendermintRpcStar from '@cosmjs/tendermint-rpc';
5
+ import * as tendermint34 from '@cosmjs/tendermint-rpc';
7
6
  import * as stargateStar from '@cosmjs/stargate';
8
7
 
8
+ import { isStreamCell } from '@agoric/internal/src/lib-chainStorage.js';
9
+
9
10
  import { MAKE_DEFAULT_DECODER, MAKE_DEFAULT_UNSERIALIZER } from './defaults.js';
10
11
  import { makeCastingSpec } from './casting-spec.js';
11
12
  import { makeLeader as defaultMakeLeader } from './leader-netconfig.js';
12
13
 
13
14
  const { QueryClient } = stargateStar;
14
- const { Tendermint34Client } = tendermintRpcStar;
15
- const { details: X, quote: q } = assert;
15
+ const { Tendermint34Client } = tendermint34;
16
+ const { details: X, quote: q, Fail } = assert;
16
17
  const textDecoder = new TextDecoder();
17
18
 
18
- /** @template T @typedef {import('./types.js').StreamCell<T>} StreamCell */
19
- /** @template T @typedef {import('./types.js').ValueFollowerElement<T>} ValueFollowerElement */
20
- /** @template T @typedef {import('./types.js').Follower<ValueFollowerElement<T>>} ValueFollower */
19
+ /** @template T @typedef {import('./types.js').Follower<import('./types.js').ValueFollowerElement<T>>} ValueFollower */
21
20
 
21
+ // Copied from https://github.com/cosmos/cosmjs/pull/1328/files until release
22
22
  /**
23
- * This is an imperfect heuristic to navigate the migration from value cells to
24
- * stream cells.
25
- * At time of writing, no legacy cells have the same shape as a stream cell,
26
- * and we do not intend to create any more legacy value cells.
27
- *
28
- * @param {any} cell
23
+ * @typedef {{
24
+ * readonly value: Uint8Array;
25
+ * readonly height: number;
26
+ * }} QueryStoreResponse
27
+ * The response of an ABCI query to Tendermint.
28
+ * This is a subset of `tendermint34.AbciQueryResponse` in order
29
+ * to abstract away Tendermint versions.
29
30
  */
30
- const isStreamCell = cell =>
31
- cell &&
32
- typeof cell === 'object' &&
33
- Array.isArray(cell.values) &&
34
- typeof cell.blockHeight === 'string' &&
35
- /^0$|^[1-9][0-9]*$/.test(cell.blockHeight);
36
31
 
37
32
  /**
38
33
  * @param {Uint8Array} a
@@ -52,6 +47,22 @@ const arrayEqual = (a, b) => {
52
47
 
53
48
  const defaultDataPrefixBytes = new Uint8Array();
54
49
 
50
+ /**
51
+ * @param {Uint8Array} prefixedData
52
+ * @param {Uint8Array} prefix
53
+ */
54
+ const stripPrefix = (prefixedData, prefix) => {
55
+ assert(
56
+ prefixedData.length >= prefix.length,
57
+ X`result too short for data prefix ${prefix}`,
58
+ );
59
+ assert(
60
+ arrayEqual(prefixedData.subarray(0, prefix.length), prefix),
61
+ X`${prefixedData} doesn't start with data prefix ${prefix}`,
62
+ );
63
+ return prefixedData.slice(prefix.length);
64
+ };
65
+
55
66
  /**
56
67
  * @template T
57
68
  * @param {Iterable<T>} values
@@ -103,12 +114,11 @@ export const makeCosmjsFollower = (
103
114
  if (crasher) {
104
115
  E(crasher)
105
116
  .crash(`PROOF VERIFICATION FAILURE; crashing follower`, err)
106
- .catch(e => assert.fail(X`crashing follower failed: ${e}`));
117
+ .catch(e => Fail`crashing follower failed: ${e}`);
107
118
  }
108
119
  throw err;
109
120
  };
110
-
111
- assert(proofs.includes(proof), X`unrecognized follower proof mode ${proof}`);
121
+ proofs.includes(proof) || Fail`unrecognized follower proof mode ${proof}`;
112
122
 
113
123
  const where = 'CosmJS follower';
114
124
  const castingSpecP = makeCastingSpec(sourceP);
@@ -119,7 +129,7 @@ export const makeCosmjsFollower = (
119
129
  const tendermintClientPs = new Map();
120
130
  /**
121
131
  * @param {string} endpoint
122
- * @returns {tendermintRpcStar.Tendermint34Client}
132
+ * @returns {tendermint34.Tendermint34Client}
123
133
  */
124
134
  const provideTendermintClient = endpoint => {
125
135
  let clientP = tendermintClientPs.get(endpoint);
@@ -130,17 +140,6 @@ export const makeCosmjsFollower = (
130
140
  return clientP;
131
141
  };
132
142
 
133
- const getBlockHeight = async () => {
134
- const values = await E(leader).mapEndpoints(where, async endpoint => {
135
- const client = await provideTendermintClient(endpoint);
136
- const info = await client.abciInfo();
137
- const { lastBlockHeight } = info;
138
- assert.typeof(lastBlockHeight, 'number');
139
- return lastBlockHeight;
140
- });
141
- return collectSingle(values);
142
- };
143
-
144
143
  /** @type {Map<string, import('@cosmjs/stargate').QueryClient>} */
145
144
  const endpointToQueryClient = new Map();
146
145
 
@@ -162,24 +161,23 @@ export const makeCosmjsFollower = (
162
161
  };
163
162
 
164
163
  /**
165
- * @param {(endpoint: string, storeName: string, storeSubkey: Uint8Array) => Promise<Uint8Array>} tryGetPrefixedData
164
+ * @param {(endpoint: string, storeName: string, storeSubkey: Uint8Array) => Promise<QueryStoreResponse>} tryGetPrefixedData
165
+ * @returns {Promise<QueryStoreResponse>}
166
166
  */
167
- const retryGetDataAndStripPrefix = async tryGetPrefixedData => {
167
+ const retryGetPrefixedData = async tryGetPrefixedData => {
168
168
  const {
169
169
  storeName,
170
170
  storeSubkey,
171
171
  dataPrefixBytes = defaultDataPrefixBytes,
172
+ noDataValue,
172
173
  } = await castingSpecP;
173
174
 
174
- assert.typeof(
175
- storeName,
176
- 'string',
177
- X`storeName must be a string, got ${storeName}`,
178
- );
179
- assert(
180
- storeSubkey,
181
- X`storeSubkey must be a Uint8Array, got ${storeSubkey}`,
182
- );
175
+ if (typeof storeName !== 'string') {
176
+ throw Fail`storeName must be a string, got ${storeName}`;
177
+ }
178
+ if (!storeSubkey) {
179
+ throw Fail`storeSubkey must be a Uint8Array, got ${storeSubkey}`;
180
+ }
183
181
 
184
182
  // mapEndpoints is our retry loop.
185
183
  const values = await E(leader).mapEndpoints(where, async endpoint =>
@@ -199,60 +197,47 @@ export const makeCosmjsFollower = (
199
197
  }
200
198
  assert(result);
201
199
 
202
- if (result.length === 0) {
203
- // No data.
204
- return result;
200
+ /** @type {Uint8Array} */
201
+ let value;
202
+ if (result.value.length === 0) {
203
+ value = result.value;
204
+ } else if (noDataValue && arrayEqual(result.value, noDataValue)) {
205
+ value = new Uint8Array();
206
+ } else {
207
+ value = stripPrefix(result.value, dataPrefixBytes);
205
208
  }
206
-
207
- // Handle the data prefix if any.
208
- assert(
209
- result.length >= dataPrefixBytes.length,
210
- X`result too short for data prefix ${dataPrefixBytes}`,
211
- );
212
- assert(
213
- arrayEqual(result.subarray(0, dataPrefixBytes.length), dataPrefixBytes),
214
- X`${result} doesn't start with data prefix ${dataPrefixBytes}`,
215
- );
216
- return result.slice(dataPrefixBytes.length);
209
+ return { value, height: result.height };
217
210
  };
218
211
 
219
212
  /**
220
213
  * @param {number} [height]
221
- * @returns {Promise<Uint8Array>}
214
+ * @returns {Promise<QueryStoreResponse>}
222
215
  */
223
216
  const getProvenDataAtHeight = async height => {
224
- return retryGetDataAndStripPrefix(
225
- async (endpoint, storeName, storeSubkey) => {
226
- const queryClient = await provideQueryClient(endpoint);
227
- return E(queryClient).queryVerified(storeName, storeSubkey, height);
228
- },
229
- );
217
+ return retryGetPrefixedData(async (endpoint, storeName, storeSubkey) => {
218
+ const queryClient = await provideQueryClient(endpoint);
219
+ return E(queryClient).queryStoreVerified(storeName, storeSubkey, height);
220
+ });
230
221
  };
231
222
 
232
223
  /**
233
- * @param {number} height
224
+ * @param {number} [height] desired height, or the latest height if not set
225
+ * @returns {Promise<QueryStoreResponse>}
234
226
  */
235
227
  const getUnprovenDataAtHeight = async height => {
236
- return retryGetDataAndStripPrefix(
237
- async (endpoint, storeName, storeSubkey) => {
238
- const client = await provideTendermintClient(endpoint);
239
- const response = await client.abciQuery({
240
- path: `store/${storeName}/key`,
241
- data: storeSubkey,
242
- height,
243
- prove: false,
244
- });
245
- if (response.code !== 0) {
246
- throw new Error(`Tendermint ABCI query failed: ${response.log}`);
247
- }
248
- const { value } = response;
249
- return value;
250
- },
251
- );
228
+ return retryGetPrefixedData(async (endpoint, storeName, storeSubkey) => {
229
+ const queryClient = await provideQueryClient(endpoint);
230
+ return E(queryClient).queryAbci(
231
+ `store/${storeName}/key`,
232
+ storeSubkey,
233
+ height,
234
+ );
235
+ });
252
236
  };
253
237
 
254
238
  /**
255
- * @param {number} blockHeight
239
+ * @param {number} [blockHeight] desired height, or the latest height if not set
240
+ * @returns {Promise<QueryStoreResponse>}
256
241
  */
257
242
  const tryGetDataAtHeight = async blockHeight => {
258
243
  if (proof === 'strict') {
@@ -262,36 +247,33 @@ export const makeCosmjsFollower = (
262
247
  // Fast and loose.
263
248
  return getUnprovenDataAtHeight(blockHeight);
264
249
  } else if (proof === 'optimistic') {
265
- const allegedData = await getUnprovenDataAtHeight(blockHeight);
250
+ const alleged = await getUnprovenDataAtHeight(blockHeight);
266
251
 
267
252
  // Prove later, since it may take time we say we can't afford.
268
- getProvenDataAtHeight(blockHeight).then(provenData => {
269
- if (arrayEqual(provenData, allegedData)) {
253
+ getProvenDataAtHeight(alleged.height).then(proven => {
254
+ if (arrayEqual(proven.value, alleged.value)) {
270
255
  return;
271
256
  }
272
257
  crash(
273
258
  assert.error(
274
- X`Alleged value ${allegedData} did not match proof ${provenData}`,
259
+ X`Alleged value ${alleged.value} did not match proof ${proven.value}`,
275
260
  ),
276
261
  );
277
262
  }, crash);
278
263
 
279
264
  // Speculate that we got the right value.
280
- return allegedData;
265
+ return alleged;
281
266
  }
282
267
 
283
- assert.fail(
284
- X`Unrecognized proof option ${q(
285
- proof,
286
- )}, must be one of strict, none, or optimistic`,
287
- );
268
+ throw Fail`Unrecognized proof option ${q(
269
+ proof,
270
+ )}, must be one of strict, none, or optimistic`;
288
271
  };
289
272
 
290
273
  /**
291
- * @param {number} blockHeight
274
+ * @param {number} [blockHeight] desired height, or the latest height if not set
292
275
  */
293
276
  const getDataAtHeight = async blockHeight => {
294
- assert.typeof(blockHeight, 'number');
295
277
  for (let attempt = 0; ; attempt += 1) {
296
278
  try {
297
279
  // AWAIT
@@ -341,7 +323,7 @@ export const makeCosmjsFollower = (
341
323
  * @param {any} data
342
324
  * @param {number} blockHeight
343
325
  * @param {number} currentBlockHeight
344
- * @returns {Promise<ValueFollowerElement<T>>}
326
+ * @returns {Promise<import('./types.js').ValueFollowerElement<T>>}
345
327
  */
346
328
  const followerElementFromStreamCellValue = async (
347
329
  data,
@@ -350,13 +332,13 @@ export const makeCosmjsFollower = (
350
332
  ) => {
351
333
  // AWAIT
352
334
  const value = await /** @type {T} */ (
353
- unserializer ? E(unserializer).unserialize(data) : data
335
+ unserializer ? E(unserializer).fromCapData(data) : data
354
336
  );
355
337
  return { value, blockHeight, currentBlockHeight };
356
338
  };
357
339
 
358
340
  /**
359
- * @param {StreamCell<T>} streamCell
341
+ * @param {import('./types.js').StreamCell<T>} streamCell
360
342
  * @param {number} currentBlockHeight
361
343
  * @yields {ValueFollowerElement<T>}
362
344
  */
@@ -371,7 +353,7 @@ export const makeCosmjsFollower = (
371
353
  }
372
354
 
373
355
  /**
374
- * @param {StreamCell<T>} streamCell
356
+ * @param {import('./types.js').StreamCell<T>} streamCell
375
357
  * @param {number} currentBlockHeight
376
358
  * @yields {ValueFollowerElement<T>}
377
359
  */
@@ -386,7 +368,7 @@ export const makeCosmjsFollower = (
386
368
  }
387
369
 
388
370
  /**
389
- * @param {StreamCell<T>} streamCell
371
+ * @param {import('./types.js').StreamCell<T>} streamCell
390
372
  * @param {number} currentBlockHeight
391
373
  * @yields {ValueFollowerElement<T>}
392
374
  */
@@ -406,53 +388,51 @@ export const makeCosmjsFollower = (
406
388
  * @yields {ValueFollowerElement<T>}
407
389
  */
408
390
  async function* getLatestIterable() {
409
- let blockHeight;
410
- let data;
391
+ /** @type {number | undefined} the last known latest height */
392
+ let lastHeight;
393
+ let lastValue;
411
394
  for (;;) {
412
- const currentBlockHeight = await getBlockHeight();
413
- if (currentBlockHeight === blockHeight) {
395
+ const latest = await getDataAtHeight();
396
+ if (lastHeight && latest.height <= lastHeight) {
397
+ // Wait for a fresh block
414
398
  // TODO Long-poll for next block
415
399
  // https://github.com/Agoric/agoric-sdk/issues/6154
416
400
  await E(leader).jitter(where);
417
401
  continue;
418
402
  }
419
403
 
420
- const currentData = await getDataAtHeight(currentBlockHeight);
421
- if (currentData.length === 0) {
404
+ if (latest.value.length === 0) {
405
+ // No value, so try again
422
406
  // TODO Long-poll for block data change
423
407
  // https://github.com/Agoric/agoric-sdk/issues/6154
424
408
  await E(leader).jitter(where);
425
409
  continue;
426
410
  }
427
- const currentStreamCell = streamCellForData(
428
- currentBlockHeight,
429
- currentData,
430
- );
411
+ const currentStreamCell = streamCellForData(latest.height, latest.value);
431
412
 
432
- blockHeight = currentBlockHeight;
413
+ lastHeight = latest.height;
433
414
 
434
415
  // Ignore adjacent duplicates.
435
416
  // This can only occur for legacy cells.
436
417
  // It is possible that the data changed from and back to the last
437
418
  // sampled data, but ignoring intermediate changes is consistent with
438
419
  // the semantics of getLatestIterable.
439
- if (data !== undefined && arrayEqual(data, currentData)) {
420
+ if (lastValue !== undefined && arrayEqual(lastValue, latest.value)) {
440
421
  continue;
441
422
  }
442
423
  // However, streamCells that vacillate will reemit, since each iteration
443
424
  // at a unique block height is considered distinct.
444
425
 
445
- yield* lastValueFromCell(currentStreamCell, currentBlockHeight);
446
- data = currentData;
426
+ yield* lastValueFromCell(currentStreamCell, latest.height);
427
+ lastValue = latest.value;
447
428
  }
448
429
  }
449
430
 
450
431
  /**
451
- * @param {number} cursorBlockHeight
432
+ * @param {number} [cursorBlockHeight]
452
433
  * @yields {ValueFollowerElement<T>}
453
434
  */
454
435
  async function* getEachIterableAtHeight(cursorBlockHeight) {
455
- assert.typeof(cursorBlockHeight, 'number');
456
436
  // Track the data for the last emitted cell (the cell at the
457
437
  // cursorBlockHeight) so we know not to emit duplicates
458
438
  // of that cell.
@@ -462,7 +442,9 @@ export const makeCosmjsFollower = (
462
442
  // If the block has no corresponding data, wait for the first block to
463
443
  // contain data.
464
444
  for (;;) {
465
- cursorData = await getDataAtHeight(cursorBlockHeight);
445
+ ({ value: cursorData, height: cursorBlockHeight } = await getDataAtHeight(
446
+ cursorBlockHeight,
447
+ ));
466
448
  if (cursorData.length !== 0) {
467
449
  const cursorStreamCell = streamCellForData(
468
450
  cursorBlockHeight,
@@ -474,21 +456,11 @@ export const makeCosmjsFollower = (
474
456
  // TODO Long-poll for next block
475
457
  // https://github.com/Agoric/agoric-sdk/issues/6154
476
458
  await E(leader).jitter(where);
477
- cursorBlockHeight = await getBlockHeight();
478
459
  }
479
460
 
480
461
  // For each subsequent iteration, yield every value that has been
481
462
  // published since the last iteration and advance the cursor.
482
463
  for (;;) {
483
- const currentBlockHeight = await getBlockHeight();
484
- // Wait until the chain has added at least one block.
485
- if (currentBlockHeight <= cursorBlockHeight) {
486
- // TODO Long-poll for next block
487
- // https://github.com/Agoric/agoric-sdk/issues/6154
488
- await E(leader).jitter(where);
489
- continue;
490
- }
491
-
492
464
  // Scan backward for all changes since the last observed block and yield
493
465
  // them in forward order.
494
466
  // Stream cells allow us to skip blocks that did not change.
@@ -496,24 +468,27 @@ export const makeCosmjsFollower = (
496
468
  // the value for cells that changed.
497
469
  // This does imply accumulating a potentially large number of values if
498
470
  // the eachIterable gets sampled infrequently.
499
- let rightBlockHeight = currentBlockHeight;
500
- let rightData = await getDataAtHeight(rightBlockHeight);
501
- if (rightData.length === 0) {
471
+ let { value: rightData, height: rightBlockHeight } =
472
+ await getDataAtHeight();
473
+ if (rightBlockHeight <= cursorBlockHeight || rightData.length === 0) {
502
474
  // TODO Long-poll for next block
503
475
  // https://github.com/Agoric/agoric-sdk/issues/6154
504
476
  await E(leader).jitter(where);
505
477
  continue;
506
478
  }
479
+
507
480
  let rightStreamCell = streamCellForData(rightBlockHeight, rightData);
508
481
 
509
482
  // Compare block cell data pairwise (left, right) and accumulate
510
483
  // a stack of each cell we encounter.
511
484
  const currentData = rightData;
485
+ const currentBlockHeight = rightBlockHeight;
486
+
512
487
  const cells = [];
513
488
  while (rightBlockHeight > cursorBlockHeight) {
514
489
  if (rightStreamCell.blockHeight > rightBlockHeight) {
515
490
  const { storeName, storeSubkey } = await castingSpecP;
516
- throw new Error(
491
+ throw Error(
517
492
  `Corrupt storage cell for ${storeName} under key ${storeSubkey} at block-height ${rightBlockHeight} claims to being published at a later block height ${rightStreamCell.blockHeight}`,
518
493
  );
519
494
  }
@@ -522,7 +497,7 @@ export const makeCosmjsFollower = (
522
497
  if (leftBlockHeight <= cursorBlockHeight) {
523
498
  break;
524
499
  }
525
- const leftData = await getDataAtHeight(leftBlockHeight);
500
+ const leftData = (await getDataAtHeight(leftBlockHeight)).value;
526
501
  // Do not scan behind a cell with no data.
527
502
  // This should not happen but can be tolerated.
528
503
  if (leftData.length === 0) {
@@ -570,7 +545,7 @@ export const makeCosmjsFollower = (
570
545
  }
571
546
 
572
547
  /**
573
- * @param {number} cursorBlockHeight
548
+ * @param {number} [cursorBlockHeight]
574
549
  * @yields {ValueFollowerElement<T>}
575
550
  */
576
551
  async function* getReverseIterableAtHeight(cursorBlockHeight) {
@@ -578,8 +553,10 @@ export const makeCosmjsFollower = (
578
553
  // cursorBlockHeight) so we know not to emit duplicates
579
554
  // of that cell.
580
555
  let cursorData;
581
- while (cursorBlockHeight > 0) {
582
- cursorData = await getDataAtHeight(cursorBlockHeight);
556
+ while (cursorBlockHeight === undefined || cursorBlockHeight > 0) {
557
+ ({ value: cursorData, height: cursorBlockHeight } = await getDataAtHeight(
558
+ cursorBlockHeight,
559
+ ));
583
560
  if (cursorData.length === 0) {
584
561
  // No data at the cursor height, so signal beginning of stream.
585
562
  return;
@@ -596,15 +573,9 @@ export const makeCosmjsFollower = (
596
573
  return getLatestIterable();
597
574
  },
598
575
  async getEachIterable({ height = undefined } = {}) {
599
- if (height === undefined) {
600
- height = await getBlockHeight();
601
- }
602
576
  return getEachIterableAtHeight(height);
603
577
  },
604
578
  async getReverseIterable({ height = undefined } = {}) {
605
- if (height === undefined) {
606
- height = await getBlockHeight();
607
- }
608
579
  return getReverseIterableAtHeight(height);
609
580
  },
610
581
  });
@@ -0,0 +1,2 @@
1
+ export function makeFollower<T>(specP: ERef<import('./types').CastingSpec> | string, leaderOrMaker?: import("./types").LeaderOrMaker | undefined, options?: import("./types").FollowerOptions | undefined): Promise<import("./follower-cosmjs.js").ValueFollower<T>>;
2
+ //# sourceMappingURL=follower.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"follower.d.ts","sourceRoot":"","sources":["follower.js"],"names":[],"mappings":"AA4DO,uCALI,KAAK,OAAO,SAAS,EAAE,WAAW,CAAC,GAAG,MAAM,kLAYtD"}
package/src/follower.js CHANGED
@@ -1,10 +1,10 @@
1
- // @ts-check
1
+ // @jessie-check
2
2
 
3
3
  import { Far } from '@endo/far';
4
4
  import {
5
5
  mapAsyncIterable,
6
- makeNotifierIterable,
7
- makeSubscriptionIterable,
6
+ subscribeEach,
7
+ subscribeLatest,
8
8
  } from './iterable.js';
9
9
  import { makeCosmjsFollower } from './follower-cosmjs.js';
10
10
  import { makeCastingSpec } from './casting-spec.js';
@@ -22,10 +22,10 @@ const makeSubscriptionFollower = spec => {
22
22
  const { notifier, subscription } = await spec;
23
23
  let ai;
24
24
  if (notifier) {
25
- ai = makeNotifierIterable(notifier);
25
+ ai = subscribeLatest(notifier);
26
26
  } else {
27
27
  assert(subscription);
28
- ai = makeSubscriptionIterable(subscription);
28
+ ai = subscribeEach(subscription);
29
29
  }
30
30
  return mapAsyncIterable(ai, transform);
31
31
  },
@@ -34,10 +34,10 @@ const makeSubscriptionFollower = spec => {
34
34
  const { notifier, subscription } = await spec;
35
35
  let ai;
36
36
  if (subscription) {
37
- ai = makeSubscriptionIterable(subscription);
37
+ ai = subscribeEach(subscription);
38
38
  } else {
39
39
  assert(notifier);
40
- ai = makeNotifierIterable(notifier);
40
+ ai = subscribeLatest(notifier);
41
41
  }
42
42
  return mapAsyncIterable(ai, transform);
43
43
  },
@@ -0,0 +1,24 @@
1
+ export function mapAsyncIterable<TIn, TOut>(iterable: AsyncIterable<TIn>, transform: (value: TIn) => TOut): AsyncIterable<TOut>;
2
+ export function iterateLatest<T>(follower: ERef<import("./types").Follower<T>>): {
3
+ /** @returns {AsyncIterator<T>} */
4
+ [Symbol.asyncIterator]: () => AsyncIterator<T, any, undefined>;
5
+ } & import("@endo/eventual-send").RemotableBrand<{}, {
6
+ /** @returns {AsyncIterator<T>} */
7
+ [Symbol.asyncIterator]: () => AsyncIterator<T, any, undefined>;
8
+ }>;
9
+ export function iterateEach<T>(follower: ERef<import("./types").Follower<T>>, options?: import("./types").IterateEachOptions | undefined): {
10
+ /** @returns {AsyncIterator<T>} */
11
+ [Symbol.asyncIterator]: () => AsyncIterator<T, any, undefined>;
12
+ } & import("@endo/eventual-send").RemotableBrand<{}, {
13
+ /** @returns {AsyncIterator<T>} */
14
+ [Symbol.asyncIterator]: () => AsyncIterator<T, any, undefined>;
15
+ }>;
16
+ export function iterateReverse<T>(follower: ERef<import("./types").Follower<T>>, options?: import("./types").IterateEachOptions | undefined): {
17
+ /** @returns {AsyncIterator<T>} */
18
+ [Symbol.asyncIterator]: () => AsyncIterator<T, any, undefined>;
19
+ } & import("@endo/eventual-send").RemotableBrand<{}, {
20
+ /** @returns {AsyncIterator<T>} */
21
+ [Symbol.asyncIterator]: () => AsyncIterator<T, any, undefined>;
22
+ }>;
23
+ export { subscribeEach, subscribeLatest } from "@agoric/notifier/subscribe.js";
24
+ //# sourceMappingURL=iterable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iterable.d.ts","sourceRoot":"","sources":["iterable.js"],"names":[],"mappings":"AAWO,gIAON;AAQM;IAGH,kCAAkC;;;IAAlC,kCAAkC;;GAQlC;AASG;IAGH,kCAAkC;;;IAAlC,kCAAkC;;GAQlC;AAOG;IAGH,kCAAkC;;;IAAlC,kCAAkC;;GAQlC"}
package/src/iterable.js CHANGED
@@ -1,48 +1,6 @@
1
- // @ts-check
2
1
  import { E, Far } from '@endo/far';
3
- import { makeNotifier } from '@agoric/notifier';
4
2
 
5
- /**
6
- * @template T
7
- * @param {ERef<Notifier<T>>} notifier
8
- * @returns {ConsistentAsyncIterable<T>}
9
- */
10
- export const makeNotifierIterable = notifier =>
11
- makeNotifier(E(notifier).getSharableNotifierInternals());
12
-
13
- /**
14
- * TODO: Remove this function when we have `makePublisherKit`.
15
- *
16
- * @template T
17
- * @param {ERef<PublicationRecord<T>>} tailP
18
- * @returns {AsyncIterator<T>}
19
- */
20
- const makeSubscriptionIterator = tailP => {
21
- // To understand the implementation, start with
22
- // https://web.archive.org/web/20160404122250/http://wiki.ecmascript.org/doku.php?id=strawman:concurrency#infinite_queue
23
- return Far('SubscriptionIterator', {
24
- next: async () => {
25
- const resultP = E.get(tailP).head;
26
- tailP = E.get(tailP).tail;
27
- return resultP;
28
- },
29
- });
30
- };
31
-
32
- /**
33
- * TODO: Remove this function when we have `makePublisherKit`.
34
- *
35
- * @template T
36
- * @param {ERef<Subscription<T>>} subscription
37
- * @returns {ConsistentAsyncIterable<T>}
38
- */
39
- export const makeSubscriptionIterable = subscription =>
40
- harden({
41
- [Symbol.asyncIterator]: () =>
42
- makeSubscriptionIterator(
43
- E(subscription).getSharableSubscriptionInternals(),
44
- ),
45
- });
3
+ export { subscribeEach, subscribeLatest } from '@agoric/notifier/subscribe.js';
46
4
 
47
5
  /**
48
6
  * @template TIn
@@ -61,7 +19,7 @@ export const mapAsyncIterable = (iterable, transform) => {
61
19
  };
62
20
 
63
21
  /**
64
- * TODO: Remove this function when we have `makePublisherKit`.
22
+ * TODO: Remove this function when we have an @endo/publish-kit that suppports pull topics
65
23
  *
66
24
  * @template T
67
25
  * @param {ERef<import('./types').Follower<T>>} follower
@@ -80,7 +38,7 @@ export const iterateLatest = follower =>
80
38
  });
81
39
 
82
40
  /**
83
- * TODO: Remove this function when we have `makePublisherKit`.
41
+ * TODO: Remove this function when we have an @endo/publish-kit that suppports pull topics
84
42
  *
85
43
  * @template T
86
44
  * @param {ERef<import('./types.js').Follower<T>>} follower
@@ -0,0 +1,4 @@
1
+ export function makeLeaderFromRpcAddresses(rpcAddrs: string[], leaderOptions?: import("./types.js").LeaderOptions | undefined): import('./types.js').Leader;
2
+ export function makeLeaderFromNetworkConfig(netconfigURL: string, options?: import("./types.js").LeaderOptions | undefined): Promise<any>;
3
+ export function makeLeader(bootstrap?: string | undefined, options?: import("./types.js").LeaderOptions | undefined): ERef<import('./types.js').Leader>;
4
+ //# sourceMappingURL=leader-netconfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leader-netconfig.d.ts","sourceRoot":"","sources":["leader-netconfig.js"],"names":[],"mappings":"AAgBO,qDAJI,MAAM,EAAE,mEAEN,OAAO,YAAY,EAAE,MAAM,CAevC;AAMM,0DAHI,MAAM,0EAoChB;AAOM,sHAFM,KAAK,OAAO,YAAY,EAAE,MAAM,CAAC,CAO7C"}