@graffiti-garden/implementation-decentralized 0.0.3 → 0.0.4

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.
@@ -87,6 +87,7 @@ const MESSAGE_LABEL_UNLABELED = 0;
87
87
  const MESSAGE_LABEL_VALID = 1;
88
88
  const MESSAGE_LABEL_TRASH = 2;
89
89
  const MESSAGE_LABEL_INVALID = 3;
90
+ const CONCURRENCY = 16;
90
91
  class GraffitiDecentralized {
91
92
  dids = new import_dids.DecentralizedIdentifiers();
92
93
  authorization = new import_authorization.Authorization();
@@ -597,14 +598,14 @@ class GraffitiDecentralized {
597
598
  cursor: JSON.stringify({
598
599
  channels,
599
600
  cursors
600
- }),
601
- continue: (session2) => this.discoverMeta(channels, schema, cursors, session2)
601
+ })
602
602
  };
603
603
  }
604
604
  discover = (...args) => {
605
605
  const [channels, schema, session] = args;
606
606
  return this.discoverMeta(channels, schema, {}, session);
607
607
  };
608
+ // @ts-ignore
608
609
  continueDiscover = (...args) => {
609
610
  const [cursor, session] = args;
610
611
  let channels;
@@ -751,62 +752,160 @@ class GraffitiDecentralized {
751
752
  queryArguments.cursor,
752
753
  inboxToken
753
754
  );
755
+ const inFlight = [];
756
+ let doneValue = null;
754
757
  while (true) {
755
- const itResult = await iterator.next();
756
- if (itResult.done) return itResult.value;
757
- const result = itResult.value;
758
- const label = result.l;
759
- if (label !== MESSAGE_LABEL_VALID && label !== MESSAGE_LABEL_UNLABELED && label !== MESSAGE_LABEL_TRASH)
760
- continue;
761
- const messageId = result.id;
762
- const { o: object, m: metadataBytes, t: receivedTags } = result.m;
763
- let metadata;
764
- try {
765
- const metadataRaw = (0, import_dag_cbor.decode)(metadataBytes);
766
- metadata = MessageMetadataSchema.parse(metadataRaw);
767
- } catch (e) {
768
- this.inboxes.label(
758
+ while (doneValue === null && inFlight.length < CONCURRENCY) {
759
+ const itResult = await iterator.next();
760
+ if (itResult.done) {
761
+ doneValue = itResult.value;
762
+ break;
763
+ }
764
+ const processPromise = this.processOneLabeledMessage(
769
765
  inboxEndpoint,
770
- messageId,
771
- MESSAGE_LABEL_INVALID,
772
- inboxToken
773
- );
774
- continue;
766
+ itResult.value,
767
+ inboxToken,
768
+ recipient
769
+ ).catch((e) => {
770
+ throw e;
771
+ });
772
+ inFlight.push(processPromise);
775
773
  }
776
- const {
777
- [MESSAGE_DATA_STORAGE_BUCKET_KEY]: storageBucketKey,
778
- [MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY]: tombstonedMessageId
779
- } = metadata;
780
- const allowedTickets = MESSAGE_DATA_ALLOWED_TICKETS_KEY in metadata ? metadata[MESSAGE_DATA_ALLOWED_TICKETS_KEY] : void 0;
781
- const announcements = MESSAGE_DATA_ANNOUNCEMENTS_KEY in metadata ? metadata[MESSAGE_DATA_ANNOUNCEMENTS_KEY] : void 0;
782
- if (label === MESSAGE_LABEL_VALID) {
783
- yield {
784
- messageId,
785
- object,
786
- storageBucketKey,
787
- allowedTickets,
788
- tags: receivedTags,
789
- announcements
790
- };
791
- continue;
792
- } else if (label === MESSAGE_LABEL_TRASH) {
793
- if (!tombstonedMessageId) continue;
794
- const past = await this.inboxes.get(
774
+ const nextProcessedPromise = inFlight.shift();
775
+ if (!nextProcessedPromise) {
776
+ if (doneValue !== null) return doneValue;
777
+ throw new Error("Process queue empty but no return value");
778
+ }
779
+ const processed = await nextProcessedPromise;
780
+ if (processed) yield processed;
781
+ }
782
+ }
783
+ async processOneLabeledMessage(inboxEndpoint, result, inboxToken, recipient) {
784
+ const label = result.l;
785
+ if (label !== MESSAGE_LABEL_VALID && label !== MESSAGE_LABEL_UNLABELED && label !== MESSAGE_LABEL_TRASH)
786
+ return;
787
+ const messageId = result.id;
788
+ const { o: object, m: metadataBytes, t: receivedTags } = result.m;
789
+ let metadata;
790
+ try {
791
+ const metadataRaw = (0, import_dag_cbor.decode)(metadataBytes);
792
+ metadata = MessageMetadataSchema.parse(metadataRaw);
793
+ } catch (e) {
794
+ this.inboxes.label(
795
+ inboxEndpoint,
796
+ messageId,
797
+ MESSAGE_LABEL_INVALID,
798
+ inboxToken
799
+ );
800
+ return;
801
+ }
802
+ const {
803
+ [MESSAGE_DATA_STORAGE_BUCKET_KEY]: storageBucketKey,
804
+ [MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY]: tombstonedMessageId
805
+ } = metadata;
806
+ const allowedTickets = MESSAGE_DATA_ALLOWED_TICKETS_KEY in metadata ? metadata[MESSAGE_DATA_ALLOWED_TICKETS_KEY] : void 0;
807
+ const announcements = MESSAGE_DATA_ANNOUNCEMENTS_KEY in metadata ? metadata[MESSAGE_DATA_ANNOUNCEMENTS_KEY] : void 0;
808
+ if (label === MESSAGE_LABEL_VALID) {
809
+ return {
810
+ messageId,
811
+ object,
812
+ storageBucketKey,
813
+ allowedTickets,
814
+ tags: receivedTags,
815
+ announcements
816
+ };
817
+ } else if (label === MESSAGE_LABEL_TRASH) {
818
+ if (!tombstonedMessageId) return;
819
+ const past = await this.inboxes.get(
820
+ inboxEndpoint,
821
+ tombstonedMessageId,
822
+ inboxToken
823
+ );
824
+ if (!past || past[import_inboxes.LABELED_MESSAGE_MESSAGE_KEY][import_inboxes.MESSAGE_OBJECT_KEY].url !== object.url)
825
+ return;
826
+ if (past[import_inboxes.LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH) {
827
+ this.inboxes.label(
795
828
  inboxEndpoint,
796
829
  tombstonedMessageId,
830
+ MESSAGE_LABEL_TRASH,
797
831
  inboxToken
798
832
  );
799
- if (!past || past[import_inboxes.LABELED_MESSAGE_MESSAGE_KEY][import_inboxes.MESSAGE_OBJECT_KEY].url !== object.url)
800
- continue;
801
- if (past[import_inboxes.LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH) {
833
+ }
834
+ return {
835
+ messageId,
836
+ tombstone: true,
837
+ object,
838
+ storageBucketKey,
839
+ allowedTickets,
840
+ tags: receivedTags,
841
+ announcements
842
+ };
843
+ }
844
+ let validationError = void 0;
845
+ try {
846
+ const actor = object.actor;
847
+ const actorDocument = await this.dids.resolve(actor);
848
+ const storageBucketService = actorDocument?.service?.find(
849
+ (service) => service.id === import_sessions.DID_SERVICE_ID_GRAFFITI_STORAGE_BUCKET && service.type === import_sessions.DID_SERVICE_TYPE_GRAFFITI_STORAGE_BUCKET
850
+ );
851
+ if (!storageBucketService) {
852
+ throw new import_api.GraffitiErrorNotFound(
853
+ `Actor ${actor} has no storage bucket service`
854
+ );
855
+ }
856
+ if (typeof storageBucketService.serviceEndpoint !== "string") {
857
+ throw new import_api.GraffitiErrorNotFound(
858
+ `Actor ${actor} does not have a valid storage bucket endpoint`
859
+ );
860
+ }
861
+ const storageBucketEndpoint = storageBucketService.serviceEndpoint;
862
+ const objectBytes = await this.storageBuckets.get(
863
+ storageBucketEndpoint,
864
+ storageBucketKey,
865
+ import_object_encoding.MAX_OBJECT_SIZE_BYTES
866
+ );
867
+ if (MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata && !recipient) {
868
+ throw new import_api.GraffitiErrorForbidden(
869
+ `Recipient is required when allowed ticket is present`
870
+ );
871
+ }
872
+ const privateObjectInfo = allowedTickets ? { allowedTickets } : MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata ? {
873
+ recipient: recipient ?? "null",
874
+ allowedTicket: metadata[MESSAGE_DATA_ALLOWED_TICKET_KEY],
875
+ allowedIndex: metadata[MESSAGE_DATA_ALLOWED_TICKET_INDEX_KEY]
876
+ } : void 0;
877
+ await this.objectEncoding.validate(
878
+ object,
879
+ receivedTags,
880
+ objectBytes,
881
+ privateObjectInfo
882
+ );
883
+ } catch (e) {
884
+ validationError = e;
885
+ }
886
+ if (tombstonedMessageId) {
887
+ if (validationError instanceof import_api.GraffitiErrorNotFound) {
888
+ this.inboxes.get(inboxEndpoint, tombstonedMessageId, inboxToken).then((result2) => {
889
+ if (
890
+ // Make sure that it actually references the object being deleted
891
+ result2 && result2[import_inboxes.LABELED_MESSAGE_MESSAGE_KEY][import_inboxes.MESSAGE_OBJECT_KEY].url === object.url && // And that the object is not already marked as trash
892
+ result2[import_inboxes.LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH
893
+ ) {
894
+ this.inboxes.label(
895
+ inboxEndpoint,
896
+ tombstonedMessageId,
897
+ MESSAGE_LABEL_TRASH,
898
+ inboxToken
899
+ );
900
+ }
802
901
  this.inboxes.label(
803
902
  inboxEndpoint,
804
- tombstonedMessageId,
903
+ messageId,
805
904
  MESSAGE_LABEL_TRASH,
806
905
  inboxToken
807
906
  );
808
- }
809
- yield {
907
+ });
908
+ return {
810
909
  messageId,
811
910
  tombstone: true,
812
911
  object,
@@ -815,117 +914,48 @@ class GraffitiDecentralized {
815
914
  tags: receivedTags,
816
915
  announcements
817
916
  };
818
- continue;
819
- }
820
- let validationError = void 0;
821
- try {
822
- const actor = object.actor;
823
- const actorDocument = await this.dids.resolve(actor);
824
- const storageBucketService = actorDocument?.service?.find(
825
- (service) => service.id === import_sessions.DID_SERVICE_ID_GRAFFITI_STORAGE_BUCKET && service.type === import_sessions.DID_SERVICE_TYPE_GRAFFITI_STORAGE_BUCKET
917
+ } else {
918
+ console.error("Recieved an incorrect tombstone object");
919
+ console.error(validationError);
920
+ this.inboxes.label(
921
+ inboxEndpoint,
922
+ messageId,
923
+ MESSAGE_LABEL_INVALID,
924
+ inboxToken
826
925
  );
827
- if (!storageBucketService) {
828
- throw new import_api.GraffitiErrorNotFound(
829
- `Actor ${actor} has no storage bucket service`
830
- );
831
- }
832
- if (typeof storageBucketService.serviceEndpoint !== "string") {
833
- throw new import_api.GraffitiErrorNotFound(
834
- `Actor ${actor} does not have a valid storage bucket endpoint`
835
- );
836
- }
837
- const storageBucketEndpoint = storageBucketService.serviceEndpoint;
838
- const objectBytes = await this.storageBuckets.get(
839
- storageBucketEndpoint,
840
- storageBucketKey,
841
- import_object_encoding.MAX_OBJECT_SIZE_BYTES
926
+ }
927
+ } else {
928
+ if (validationError === void 0) {
929
+ this.inboxes.label(
930
+ inboxEndpoint,
931
+ messageId,
932
+ MESSAGE_LABEL_VALID,
933
+ inboxToken
842
934
  );
843
- if (MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata && !recipient) {
844
- throw new import_api.GraffitiErrorForbidden(
845
- `Recipient is required when allowed ticket is present`
846
- );
847
- }
848
- const privateObjectInfo = allowedTickets ? { allowedTickets } : MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata ? {
849
- recipient: recipient ?? "null",
850
- allowedTicket: metadata[MESSAGE_DATA_ALLOWED_TICKET_KEY],
851
- allowedIndex: metadata[MESSAGE_DATA_ALLOWED_TICKET_INDEX_KEY]
852
- } : void 0;
853
- await this.objectEncoding.validate(
935
+ return {
936
+ messageId,
854
937
  object,
855
- receivedTags,
856
- objectBytes,
857
- privateObjectInfo
938
+ storageBucketKey,
939
+ tags: receivedTags,
940
+ allowedTickets,
941
+ announcements
942
+ };
943
+ } else if (validationError instanceof import_api.GraffitiErrorNotFound) {
944
+ this.inboxes.label(
945
+ inboxEndpoint,
946
+ messageId,
947
+ MESSAGE_LABEL_TRASH,
948
+ inboxToken
858
949
  );
859
- } catch (e) {
860
- validationError = e;
861
- }
862
- if (tombstonedMessageId) {
863
- if (validationError instanceof import_api.GraffitiErrorNotFound) {
864
- this.inboxes.get(inboxEndpoint, tombstonedMessageId, inboxToken).then((result2) => {
865
- if (
866
- // Make sure that it actually references the object being deleted
867
- result2 && result2[import_inboxes.LABELED_MESSAGE_MESSAGE_KEY][import_inboxes.MESSAGE_OBJECT_KEY].url === object.url && // And that the object is not already marked as trash
868
- result2[import_inboxes.LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH
869
- ) {
870
- this.inboxes.label(
871
- inboxEndpoint,
872
- tombstonedMessageId,
873
- MESSAGE_LABEL_TRASH,
874
- inboxToken
875
- );
876
- }
877
- this.inboxes.label(
878
- inboxEndpoint,
879
- messageId,
880
- MESSAGE_LABEL_TRASH,
881
- inboxToken
882
- );
883
- });
884
- yield {
885
- messageId,
886
- tombstone: true,
887
- object,
888
- storageBucketKey,
889
- allowedTickets,
890
- tags: receivedTags,
891
- announcements
892
- };
893
- } else {
894
- console.error("Recieved an incorrect object");
895
- console.error(validationError);
896
- this.inboxes.label(
897
- inboxEndpoint,
898
- messageId,
899
- MESSAGE_LABEL_INVALID,
900
- inboxToken
901
- );
902
- }
903
950
  } else {
904
- if (validationError === void 0) {
905
- this.inboxes.label(
906
- inboxEndpoint,
907
- messageId,
908
- MESSAGE_LABEL_VALID,
909
- inboxToken
910
- );
911
- yield {
912
- messageId,
913
- object,
914
- storageBucketKey,
915
- tags: receivedTags,
916
- allowedTickets,
917
- announcements
918
- };
919
- } else {
920
- console.error("Recieved an incorrect object");
921
- console.error(validationError);
922
- this.inboxes.label(
923
- inboxEndpoint,
924
- messageId,
925
- MESSAGE_LABEL_INVALID,
926
- inboxToken
927
- );
928
- }
951
+ console.error("Recieved an incorrect object");
952
+ console.error(validationError);
953
+ this.inboxes.label(
954
+ inboxEndpoint,
955
+ messageId,
956
+ MESSAGE_LABEL_INVALID,
957
+ inboxToken
958
+ );
929
959
  }
930
960
  }
931
961
  }