@graffiti-garden/implementation-decentralized 0.0.4 → 0.0.5

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.
@@ -708,79 +708,87 @@ export class GraffitiDecentralized implements Graffiti {
708
708
  >(async (it, index) => indexedSingleEndpointQueryNext<Schema>(it, index));
709
709
  let active = indexedIteratorNexts.length;
710
710
 
711
- while (active > 0) {
712
- const next: IndexedSingleEndpointQueryResult<Schema> =
713
- await Promise.race<any>(indexedIteratorNexts);
714
- if (next.error !== undefined) {
715
- // Remove it from the race
716
- indexedIteratorNexts[next.index] = new Promise(() => {});
717
- active--;
718
- yield {
719
- error: next.error,
720
- origin: allInboxes[next.index].serviceEndpoint,
721
- };
722
- } else if (next.result.done) {
723
- // Store the cursor for future use
724
- const inbox = allInboxes[next.index];
725
- cursors[inbox.serviceEndpoint] = next.result.value;
726
- // Remove it from the race
727
- indexedIteratorNexts[next.index] = new Promise(() => {});
728
- active--;
729
- } else {
730
- // Re-arm the iterator
731
- indexedIteratorNexts[next.index] =
732
- indexedSingleEndpointQueryNext<Schema>(
733
- iterators[next.index],
734
- next.index,
735
- );
736
- const { object, tombstone, tags: receivedTags } = next.result.value;
737
- if (tombstone) {
738
- if (tombstones.get(object.url) === true) continue;
739
- tombstones.set(object.url, true);
711
+ try {
712
+ while (active > 0) {
713
+ const next: IndexedSingleEndpointQueryResult<Schema> =
714
+ await Promise.race<any>(indexedIteratorNexts);
715
+ if (next.error !== undefined) {
716
+ // Remove it from the race
717
+ indexedIteratorNexts[next.index] = new Promise(() => {});
718
+ active--;
740
719
  yield {
741
- tombstone,
742
- object: { url: object.url },
720
+ error: next.error,
721
+ origin: allInboxes[next.index].serviceEndpoint,
743
722
  };
723
+ } else if (next.result.done) {
724
+ // Store the cursor for future use
725
+ const inbox = allInboxes[next.index];
726
+ cursors[inbox.serviceEndpoint] = next.result.value;
727
+ // Remove it from the race
728
+ indexedIteratorNexts[next.index] = new Promise(() => {});
729
+ active--;
744
730
  } else {
745
- // Filter already seen
746
- if (tombstones.get(object.url) === false) continue;
747
-
748
- // Fill in the matched channels
749
- const matchedTagIndices = tags.reduce<number[]>(
750
- (acc, tag, tagIndex) => {
751
- for (const receivedTag of receivedTags) {
752
- if (
753
- tag.length === receivedTag.length &&
754
- tag.every((b, i) => receivedTag[i] === b)
755
- ) {
756
- acc.push(tagIndex);
757
- break;
731
+ // Re-arm the iterator
732
+ indexedIteratorNexts[next.index] =
733
+ indexedSingleEndpointQueryNext<Schema>(
734
+ iterators[next.index],
735
+ next.index,
736
+ );
737
+ const { object, tombstone, tags: receivedTags } = next.result.value;
738
+ if (tombstone) {
739
+ if (tombstones.get(object.url) === true) continue;
740
+ tombstones.set(object.url, true);
741
+ yield {
742
+ tombstone,
743
+ object: { url: object.url },
744
+ };
745
+ } else {
746
+ // Filter already seen
747
+ if (tombstones.get(object.url) === false) continue;
748
+
749
+ // Fill in the matched channels
750
+ const matchedTagIndices = tags.reduce<number[]>(
751
+ (acc, tag, tagIndex) => {
752
+ for (const receivedTag of receivedTags) {
753
+ if (
754
+ tag.length === receivedTag.length &&
755
+ tag.every((b, i) => receivedTag[i] === b)
756
+ ) {
757
+ acc.push(tagIndex);
758
+ break;
759
+ }
758
760
  }
759
- }
760
- return acc;
761
- },
762
- [],
763
- );
764
- const matchedChannels = matchedTagIndices.map(
765
- (index) => channels[index],
766
- );
767
- if (matchedChannels.length === 0) {
761
+ return acc;
762
+ },
763
+ [],
764
+ );
765
+ const matchedChannels = matchedTagIndices.map(
766
+ (index) => channels[index],
767
+ );
768
+ if (matchedChannels.length === 0) {
769
+ yield {
770
+ error: new Error(
771
+ "Inbox returned object without matching channels",
772
+ ),
773
+ origin: allInboxes[next.index].serviceEndpoint,
774
+ };
775
+ }
776
+ tombstones.set(object.url, false);
768
777
  yield {
769
- error: new Error(
770
- "Inbox returned object without matching channels",
771
- ),
772
- origin: allInboxes[next.index].serviceEndpoint,
778
+ object: {
779
+ ...object,
780
+ channels: matchedChannels,
781
+ },
773
782
  };
774
783
  }
775
- tombstones.set(object.url, false);
776
- yield {
777
- object: {
778
- ...object,
779
- channels: matchedChannels,
780
- },
781
- };
782
784
  }
783
785
  }
786
+ } finally {
787
+ await Promise.all(
788
+ iterators.map<Promise<void>>(async (it) => {
789
+ await it.return("");
790
+ }),
791
+ );
784
792
  }
785
793
 
786
794
  return {
@@ -1014,36 +1022,40 @@ export class GraffitiDecentralized implements Graffiti {
1014
1022
  const inFlight: Promise<SingleEndpointQueryResult<Schema> | void>[] = [];
1015
1023
  let doneValue: string | null = null;
1016
1024
 
1017
- while (true) {
1018
- while (doneValue === null && inFlight.length < CONCURRENCY) {
1019
- const itResult = await iterator.next();
1020
- if (itResult.done) {
1021
- doneValue = itResult.value;
1022
- break;
1023
- }
1025
+ try {
1026
+ while (true) {
1027
+ while (doneValue === null && inFlight.length < CONCURRENCY) {
1028
+ const itResult = await iterator.next();
1029
+ if (itResult.done) {
1030
+ doneValue = itResult.value;
1031
+ break;
1032
+ }
1024
1033
 
1025
- const processPromise = this.processOneLabeledMessage<Schema>(
1026
- inboxEndpoint,
1027
- itResult.value,
1028
- inboxToken,
1029
- recipient,
1030
- ).catch((e) => {
1031
- throw e;
1032
- });
1034
+ const processPromise = this.processOneLabeledMessage<Schema>(
1035
+ inboxEndpoint,
1036
+ itResult.value,
1037
+ inboxToken,
1038
+ recipient,
1039
+ ).catch((e) => {
1040
+ throw e;
1041
+ });
1033
1042
 
1034
- inFlight.push(processPromise);
1035
- }
1043
+ inFlight.push(processPromise);
1044
+ }
1036
1045
 
1037
- const nextProcessedPromise = inFlight.shift();
1046
+ const nextProcessedPromise = inFlight.shift();
1038
1047
 
1039
- if (!nextProcessedPromise) {
1040
- if (doneValue !== null) return doneValue;
1048
+ if (!nextProcessedPromise) {
1049
+ if (doneValue !== null) return doneValue;
1041
1050
 
1042
- throw new Error("Process queue empty but no return value");
1043
- }
1051
+ throw new Error("Process queue empty but no return value");
1052
+ }
1044
1053
 
1045
- const processed = await nextProcessedPromise;
1046
- if (processed) yield processed;
1054
+ const processed = await nextProcessedPromise;
1055
+ if (processed) yield processed;
1056
+ }
1057
+ } finally {
1058
+ await iterator.return("");
1047
1059
  }
1048
1060
  }
1049
1061