@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.
- package/dist/3-protocol/3-object-encoding.d.ts.map +1 -1
- package/dist/3-protocol/4-graffiti.d.ts +2 -1
- package/dist/3-protocol/4-graffiti.d.ts.map +1 -1
- package/dist/browser/index.js +7 -7
- package/dist/browser/index.js.map +3 -3
- package/dist/browser/{style-3ALLGCD7-QNFKN6AK.js → style-RMTPI5KV-Y5KAOOZR.js} +2 -1
- package/dist/browser/style-RMTPI5KV-Y5KAOOZR.js.map +7 -0
- package/dist/cjs/3-protocol/1-sessions.js +1 -1
- package/dist/cjs/3-protocol/1-sessions.js.map +2 -2
- package/dist/cjs/3-protocol/3-object-encoding.js +3 -2
- package/dist/cjs/3-protocol/3-object-encoding.js.map +2 -2
- package/dist/cjs/3-protocol/4-graffiti.js +182 -152
- package/dist/cjs/3-protocol/4-graffiti.js.map +3 -3
- package/dist/esm/3-protocol/1-sessions.js +1 -1
- package/dist/esm/3-protocol/1-sessions.js.map +2 -2
- package/dist/esm/3-protocol/3-object-encoding.js +3 -2
- package/dist/esm/3-protocol/3-object-encoding.js.map +2 -2
- package/dist/esm/3-protocol/4-graffiti.js +182 -152
- package/dist/esm/3-protocol/4-graffiti.js.map +3 -3
- package/package.json +7 -7
- package/src/3-protocol/1-sessions.ts +1 -1
- package/src/3-protocol/3-object-encoding.ts +4 -2
- package/src/3-protocol/4-graffiti.ts +242 -200
- package/dist/browser/style-3ALLGCD7-QNFKN6AK.js.map +0 -7
|
@@ -105,6 +105,7 @@ const MESSAGE_LABEL_UNLABELED = 0;
|
|
|
105
105
|
const MESSAGE_LABEL_VALID = 1;
|
|
106
106
|
const MESSAGE_LABEL_TRASH = 2;
|
|
107
107
|
const MESSAGE_LABEL_INVALID = 3;
|
|
108
|
+
const CONCURRENCY = 16;
|
|
108
109
|
class GraffitiDecentralized {
|
|
109
110
|
dids = new DecentralizedIdentifiers();
|
|
110
111
|
authorization = new Authorization();
|
|
@@ -615,14 +616,14 @@ class GraffitiDecentralized {
|
|
|
615
616
|
cursor: JSON.stringify({
|
|
616
617
|
channels,
|
|
617
618
|
cursors
|
|
618
|
-
})
|
|
619
|
-
continue: (session2) => this.discoverMeta(channels, schema, cursors, session2)
|
|
619
|
+
})
|
|
620
620
|
};
|
|
621
621
|
}
|
|
622
622
|
discover = (...args) => {
|
|
623
623
|
const [channels, schema, session] = args;
|
|
624
624
|
return this.discoverMeta(channels, schema, {}, session);
|
|
625
625
|
};
|
|
626
|
+
// @ts-ignore
|
|
626
627
|
continueDiscover = (...args) => {
|
|
627
628
|
const [cursor, session] = args;
|
|
628
629
|
let channels;
|
|
@@ -769,62 +770,160 @@ class GraffitiDecentralized {
|
|
|
769
770
|
queryArguments.cursor,
|
|
770
771
|
inboxToken
|
|
771
772
|
);
|
|
773
|
+
const inFlight = [];
|
|
774
|
+
let doneValue = null;
|
|
772
775
|
while (true) {
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
const { o: object, m: metadataBytes, t: receivedTags } = result.m;
|
|
781
|
-
let metadata;
|
|
782
|
-
try {
|
|
783
|
-
const metadataRaw = dagCborDecode(metadataBytes);
|
|
784
|
-
metadata = MessageMetadataSchema.parse(metadataRaw);
|
|
785
|
-
} catch (e) {
|
|
786
|
-
this.inboxes.label(
|
|
776
|
+
while (doneValue === null && inFlight.length < CONCURRENCY) {
|
|
777
|
+
const itResult = await iterator.next();
|
|
778
|
+
if (itResult.done) {
|
|
779
|
+
doneValue = itResult.value;
|
|
780
|
+
break;
|
|
781
|
+
}
|
|
782
|
+
const processPromise = this.processOneLabeledMessage(
|
|
787
783
|
inboxEndpoint,
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
)
|
|
792
|
-
|
|
784
|
+
itResult.value,
|
|
785
|
+
inboxToken,
|
|
786
|
+
recipient
|
|
787
|
+
).catch((e) => {
|
|
788
|
+
throw e;
|
|
789
|
+
});
|
|
790
|
+
inFlight.push(processPromise);
|
|
793
791
|
}
|
|
794
|
-
const
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
const
|
|
800
|
-
if (
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
792
|
+
const nextProcessedPromise = inFlight.shift();
|
|
793
|
+
if (!nextProcessedPromise) {
|
|
794
|
+
if (doneValue !== null) return doneValue;
|
|
795
|
+
throw new Error("Process queue empty but no return value");
|
|
796
|
+
}
|
|
797
|
+
const processed = await nextProcessedPromise;
|
|
798
|
+
if (processed) yield processed;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
async processOneLabeledMessage(inboxEndpoint, result, inboxToken, recipient) {
|
|
802
|
+
const label = result.l;
|
|
803
|
+
if (label !== MESSAGE_LABEL_VALID && label !== MESSAGE_LABEL_UNLABELED && label !== MESSAGE_LABEL_TRASH)
|
|
804
|
+
return;
|
|
805
|
+
const messageId = result.id;
|
|
806
|
+
const { o: object, m: metadataBytes, t: receivedTags } = result.m;
|
|
807
|
+
let metadata;
|
|
808
|
+
try {
|
|
809
|
+
const metadataRaw = dagCborDecode(metadataBytes);
|
|
810
|
+
metadata = MessageMetadataSchema.parse(metadataRaw);
|
|
811
|
+
} catch (e) {
|
|
812
|
+
this.inboxes.label(
|
|
813
|
+
inboxEndpoint,
|
|
814
|
+
messageId,
|
|
815
|
+
MESSAGE_LABEL_INVALID,
|
|
816
|
+
inboxToken
|
|
817
|
+
);
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
const {
|
|
821
|
+
[MESSAGE_DATA_STORAGE_BUCKET_KEY]: storageBucketKey,
|
|
822
|
+
[MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY]: tombstonedMessageId
|
|
823
|
+
} = metadata;
|
|
824
|
+
const allowedTickets = MESSAGE_DATA_ALLOWED_TICKETS_KEY in metadata ? metadata[MESSAGE_DATA_ALLOWED_TICKETS_KEY] : void 0;
|
|
825
|
+
const announcements = MESSAGE_DATA_ANNOUNCEMENTS_KEY in metadata ? metadata[MESSAGE_DATA_ANNOUNCEMENTS_KEY] : void 0;
|
|
826
|
+
if (label === MESSAGE_LABEL_VALID) {
|
|
827
|
+
return {
|
|
828
|
+
messageId,
|
|
829
|
+
object,
|
|
830
|
+
storageBucketKey,
|
|
831
|
+
allowedTickets,
|
|
832
|
+
tags: receivedTags,
|
|
833
|
+
announcements
|
|
834
|
+
};
|
|
835
|
+
} else if (label === MESSAGE_LABEL_TRASH) {
|
|
836
|
+
if (!tombstonedMessageId) return;
|
|
837
|
+
const past = await this.inboxes.get(
|
|
838
|
+
inboxEndpoint,
|
|
839
|
+
tombstonedMessageId,
|
|
840
|
+
inboxToken
|
|
841
|
+
);
|
|
842
|
+
if (!past || past[LABELED_MESSAGE_MESSAGE_KEY][MESSAGE_OBJECT_KEY].url !== object.url)
|
|
843
|
+
return;
|
|
844
|
+
if (past[LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH) {
|
|
845
|
+
this.inboxes.label(
|
|
813
846
|
inboxEndpoint,
|
|
814
847
|
tombstonedMessageId,
|
|
848
|
+
MESSAGE_LABEL_TRASH,
|
|
815
849
|
inboxToken
|
|
816
850
|
);
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
851
|
+
}
|
|
852
|
+
return {
|
|
853
|
+
messageId,
|
|
854
|
+
tombstone: true,
|
|
855
|
+
object,
|
|
856
|
+
storageBucketKey,
|
|
857
|
+
allowedTickets,
|
|
858
|
+
tags: receivedTags,
|
|
859
|
+
announcements
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
let validationError = void 0;
|
|
863
|
+
try {
|
|
864
|
+
const actor = object.actor;
|
|
865
|
+
const actorDocument = await this.dids.resolve(actor);
|
|
866
|
+
const storageBucketService = actorDocument?.service?.find(
|
|
867
|
+
(service) => service.id === DID_SERVICE_ID_GRAFFITI_STORAGE_BUCKET && service.type === DID_SERVICE_TYPE_GRAFFITI_STORAGE_BUCKET
|
|
868
|
+
);
|
|
869
|
+
if (!storageBucketService) {
|
|
870
|
+
throw new GraffitiErrorNotFound(
|
|
871
|
+
`Actor ${actor} has no storage bucket service`
|
|
872
|
+
);
|
|
873
|
+
}
|
|
874
|
+
if (typeof storageBucketService.serviceEndpoint !== "string") {
|
|
875
|
+
throw new GraffitiErrorNotFound(
|
|
876
|
+
`Actor ${actor} does not have a valid storage bucket endpoint`
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
const storageBucketEndpoint = storageBucketService.serviceEndpoint;
|
|
880
|
+
const objectBytes = await this.storageBuckets.get(
|
|
881
|
+
storageBucketEndpoint,
|
|
882
|
+
storageBucketKey,
|
|
883
|
+
MAX_OBJECT_SIZE_BYTES
|
|
884
|
+
);
|
|
885
|
+
if (MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata && !recipient) {
|
|
886
|
+
throw new GraffitiErrorForbidden(
|
|
887
|
+
`Recipient is required when allowed ticket is present`
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
const privateObjectInfo = allowedTickets ? { allowedTickets } : MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata ? {
|
|
891
|
+
recipient: recipient ?? "null",
|
|
892
|
+
allowedTicket: metadata[MESSAGE_DATA_ALLOWED_TICKET_KEY],
|
|
893
|
+
allowedIndex: metadata[MESSAGE_DATA_ALLOWED_TICKET_INDEX_KEY]
|
|
894
|
+
} : void 0;
|
|
895
|
+
await this.objectEncoding.validate(
|
|
896
|
+
object,
|
|
897
|
+
receivedTags,
|
|
898
|
+
objectBytes,
|
|
899
|
+
privateObjectInfo
|
|
900
|
+
);
|
|
901
|
+
} catch (e) {
|
|
902
|
+
validationError = e;
|
|
903
|
+
}
|
|
904
|
+
if (tombstonedMessageId) {
|
|
905
|
+
if (validationError instanceof GraffitiErrorNotFound) {
|
|
906
|
+
this.inboxes.get(inboxEndpoint, tombstonedMessageId, inboxToken).then((result2) => {
|
|
907
|
+
if (
|
|
908
|
+
// Make sure that it actually references the object being deleted
|
|
909
|
+
result2 && result2[LABELED_MESSAGE_MESSAGE_KEY][MESSAGE_OBJECT_KEY].url === object.url && // And that the object is not already marked as trash
|
|
910
|
+
result2[LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH
|
|
911
|
+
) {
|
|
912
|
+
this.inboxes.label(
|
|
913
|
+
inboxEndpoint,
|
|
914
|
+
tombstonedMessageId,
|
|
915
|
+
MESSAGE_LABEL_TRASH,
|
|
916
|
+
inboxToken
|
|
917
|
+
);
|
|
918
|
+
}
|
|
820
919
|
this.inboxes.label(
|
|
821
920
|
inboxEndpoint,
|
|
822
|
-
|
|
921
|
+
messageId,
|
|
823
922
|
MESSAGE_LABEL_TRASH,
|
|
824
923
|
inboxToken
|
|
825
924
|
);
|
|
826
|
-
}
|
|
827
|
-
|
|
925
|
+
});
|
|
926
|
+
return {
|
|
828
927
|
messageId,
|
|
829
928
|
tombstone: true,
|
|
830
929
|
object,
|
|
@@ -833,117 +932,48 @@ class GraffitiDecentralized {
|
|
|
833
932
|
tags: receivedTags,
|
|
834
933
|
announcements
|
|
835
934
|
};
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
935
|
+
} else {
|
|
936
|
+
console.error("Recieved an incorrect tombstone object");
|
|
937
|
+
console.error(validationError);
|
|
938
|
+
this.inboxes.label(
|
|
939
|
+
inboxEndpoint,
|
|
940
|
+
messageId,
|
|
941
|
+
MESSAGE_LABEL_INVALID,
|
|
942
|
+
inboxToken
|
|
844
943
|
);
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
);
|
|
854
|
-
}
|
|
855
|
-
const storageBucketEndpoint = storageBucketService.serviceEndpoint;
|
|
856
|
-
const objectBytes = await this.storageBuckets.get(
|
|
857
|
-
storageBucketEndpoint,
|
|
858
|
-
storageBucketKey,
|
|
859
|
-
MAX_OBJECT_SIZE_BYTES
|
|
944
|
+
}
|
|
945
|
+
} else {
|
|
946
|
+
if (validationError === void 0) {
|
|
947
|
+
this.inboxes.label(
|
|
948
|
+
inboxEndpoint,
|
|
949
|
+
messageId,
|
|
950
|
+
MESSAGE_LABEL_VALID,
|
|
951
|
+
inboxToken
|
|
860
952
|
);
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
`Recipient is required when allowed ticket is present`
|
|
864
|
-
);
|
|
865
|
-
}
|
|
866
|
-
const privateObjectInfo = allowedTickets ? { allowedTickets } : MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata ? {
|
|
867
|
-
recipient: recipient ?? "null",
|
|
868
|
-
allowedTicket: metadata[MESSAGE_DATA_ALLOWED_TICKET_KEY],
|
|
869
|
-
allowedIndex: metadata[MESSAGE_DATA_ALLOWED_TICKET_INDEX_KEY]
|
|
870
|
-
} : void 0;
|
|
871
|
-
await this.objectEncoding.validate(
|
|
953
|
+
return {
|
|
954
|
+
messageId,
|
|
872
955
|
object,
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
956
|
+
storageBucketKey,
|
|
957
|
+
tags: receivedTags,
|
|
958
|
+
allowedTickets,
|
|
959
|
+
announcements
|
|
960
|
+
};
|
|
961
|
+
} else if (validationError instanceof GraffitiErrorNotFound) {
|
|
962
|
+
this.inboxes.label(
|
|
963
|
+
inboxEndpoint,
|
|
964
|
+
messageId,
|
|
965
|
+
MESSAGE_LABEL_TRASH,
|
|
966
|
+
inboxToken
|
|
876
967
|
);
|
|
877
|
-
} catch (e) {
|
|
878
|
-
validationError = e;
|
|
879
|
-
}
|
|
880
|
-
if (tombstonedMessageId) {
|
|
881
|
-
if (validationError instanceof GraffitiErrorNotFound) {
|
|
882
|
-
this.inboxes.get(inboxEndpoint, tombstonedMessageId, inboxToken).then((result2) => {
|
|
883
|
-
if (
|
|
884
|
-
// Make sure that it actually references the object being deleted
|
|
885
|
-
result2 && result2[LABELED_MESSAGE_MESSAGE_KEY][MESSAGE_OBJECT_KEY].url === object.url && // And that the object is not already marked as trash
|
|
886
|
-
result2[LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH
|
|
887
|
-
) {
|
|
888
|
-
this.inboxes.label(
|
|
889
|
-
inboxEndpoint,
|
|
890
|
-
tombstonedMessageId,
|
|
891
|
-
MESSAGE_LABEL_TRASH,
|
|
892
|
-
inboxToken
|
|
893
|
-
);
|
|
894
|
-
}
|
|
895
|
-
this.inboxes.label(
|
|
896
|
-
inboxEndpoint,
|
|
897
|
-
messageId,
|
|
898
|
-
MESSAGE_LABEL_TRASH,
|
|
899
|
-
inboxToken
|
|
900
|
-
);
|
|
901
|
-
});
|
|
902
|
-
yield {
|
|
903
|
-
messageId,
|
|
904
|
-
tombstone: true,
|
|
905
|
-
object,
|
|
906
|
-
storageBucketKey,
|
|
907
|
-
allowedTickets,
|
|
908
|
-
tags: receivedTags,
|
|
909
|
-
announcements
|
|
910
|
-
};
|
|
911
|
-
} else {
|
|
912
|
-
console.error("Recieved an incorrect object");
|
|
913
|
-
console.error(validationError);
|
|
914
|
-
this.inboxes.label(
|
|
915
|
-
inboxEndpoint,
|
|
916
|
-
messageId,
|
|
917
|
-
MESSAGE_LABEL_INVALID,
|
|
918
|
-
inboxToken
|
|
919
|
-
);
|
|
920
|
-
}
|
|
921
968
|
} else {
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
messageId,
|
|
931
|
-
object,
|
|
932
|
-
storageBucketKey,
|
|
933
|
-
tags: receivedTags,
|
|
934
|
-
allowedTickets,
|
|
935
|
-
announcements
|
|
936
|
-
};
|
|
937
|
-
} else {
|
|
938
|
-
console.error("Recieved an incorrect object");
|
|
939
|
-
console.error(validationError);
|
|
940
|
-
this.inboxes.label(
|
|
941
|
-
inboxEndpoint,
|
|
942
|
-
messageId,
|
|
943
|
-
MESSAGE_LABEL_INVALID,
|
|
944
|
-
inboxToken
|
|
945
|
-
);
|
|
946
|
-
}
|
|
969
|
+
console.error("Recieved an incorrect object");
|
|
970
|
+
console.error(validationError);
|
|
971
|
+
this.inboxes.label(
|
|
972
|
+
inboxEndpoint,
|
|
973
|
+
messageId,
|
|
974
|
+
MESSAGE_LABEL_INVALID,
|
|
975
|
+
inboxToken
|
|
976
|
+
);
|
|
947
977
|
}
|
|
948
978
|
}
|
|
949
979
|
}
|