@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.
- package/dist/3-protocol/4-graffiti.d.ts.map +1 -1
- package/dist/browser/index.js +5 -5
- package/dist/browser/index.js.map +3 -3
- package/dist/cjs/3-protocol/4-graffiti.js +88 -76
- package/dist/cjs/3-protocol/4-graffiti.js.map +2 -2
- package/dist/esm/3-protocol/4-graffiti.js +88 -76
- package/dist/esm/3-protocol/4-graffiti.js.map +2 -2
- package/package.json +2 -2
- package/src/3-protocol/4-graffiti.ts +100 -88
|
@@ -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
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
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
|
-
|
|
742
|
-
|
|
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
|
-
//
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
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
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
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
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
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
|
-
|
|
1018
|
-
while (
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
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
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
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
|
-
|
|
1035
|
-
|
|
1043
|
+
inFlight.push(processPromise);
|
|
1044
|
+
}
|
|
1036
1045
|
|
|
1037
|
-
|
|
1046
|
+
const nextProcessedPromise = inFlight.shift();
|
|
1038
1047
|
|
|
1039
|
-
|
|
1040
|
-
|
|
1048
|
+
if (!nextProcessedPromise) {
|
|
1049
|
+
if (doneValue !== null) return doneValue;
|
|
1041
1050
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1051
|
+
throw new Error("Process queue empty but no return value");
|
|
1052
|
+
}
|
|
1044
1053
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1054
|
+
const processed = await nextProcessedPromise;
|
|
1055
|
+
if (processed) yield processed;
|
|
1056
|
+
}
|
|
1057
|
+
} finally {
|
|
1058
|
+
await iterator.return("");
|
|
1047
1059
|
}
|
|
1048
1060
|
}
|
|
1049
1061
|
|