@graffiti-garden/implementation-decentralized 0.0.2 → 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/1-services/4-inboxes-tests.d.ts.map +1 -1
- package/dist/1-services/4-inboxes.d.ts +3 -3
- package/dist/1-services/4-inboxes.d.ts.map +1 -1
- 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/3-protocol/login-dialog.html.d.ts +1 -1
- package/dist/3-protocol/login-dialog.html.d.ts.map +1 -1
- package/dist/browser/index.js +7 -7
- package/dist/browser/index.js.map +3 -3
- package/dist/browser/login-dialog.html-VTDKJZBG.js +44 -0
- package/dist/browser/login-dialog.html-VTDKJZBG.js.map +7 -0
- package/dist/browser/{style-YUTCEBZV-RWYJV575.js → style-RMTPI5KV-Y5KAOOZR.js} +19 -36
- package/dist/browser/style-RMTPI5KV-Y5KAOOZR.js.map +7 -0
- package/dist/cjs/1-services/4-inboxes-tests.js +2 -0
- package/dist/cjs/1-services/4-inboxes-tests.js.map +2 -2
- package/dist/cjs/1-services/4-inboxes.js +17 -8
- package/dist/cjs/1-services/4-inboxes.js.map +2 -2
- 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 +193 -135
- package/dist/cjs/3-protocol/4-graffiti.js.map +3 -3
- package/dist/cjs/3-protocol/login-dialog.html.js +9 -9
- package/dist/cjs/3-protocol/login-dialog.html.js.map +1 -1
- package/dist/esm/1-services/4-inboxes-tests.js +2 -0
- package/dist/esm/1-services/4-inboxes-tests.js.map +2 -2
- package/dist/esm/1-services/4-inboxes.js +19 -9
- package/dist/esm/1-services/4-inboxes.js.map +2 -2
- 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 +194 -135
- package/dist/esm/3-protocol/4-graffiti.js.map +3 -3
- package/dist/esm/3-protocol/login-dialog.html.js +9 -9
- package/dist/esm/3-protocol/login-dialog.html.js.map +1 -1
- package/package.json +7 -7
- package/src/1-services/4-inboxes-tests.ts +2 -0
- package/src/1-services/4-inboxes.ts +25 -15
- 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 +260 -170
- package/src/3-protocol/login-dialog.html.ts +9 -9
- package/dist/browser/login-dialog.html-XUWYDNNI.js +0 -44
- package/dist/browser/login-dialog.html-XUWYDNNI.js.map +0 -7
- package/dist/browser/style-YUTCEBZV-RWYJV575.js.map +0 -7
|
@@ -21,6 +21,7 @@ import { Authorization } from "../1-services/1-authorization";
|
|
|
21
21
|
import { StorageBuckets } from "../1-services/3-storage-buckets";
|
|
22
22
|
import {
|
|
23
23
|
Inboxes,
|
|
24
|
+
LABELED_MESSAGE_LABEL_KEY,
|
|
24
25
|
LABELED_MESSAGE_MESSAGE_KEY,
|
|
25
26
|
MESSAGE_METADATA_KEY,
|
|
26
27
|
MESSAGE_OBJECT_KEY,
|
|
@@ -104,6 +105,7 @@ const MESSAGE_LABEL_UNLABELED = 0;
|
|
|
104
105
|
const MESSAGE_LABEL_VALID = 1;
|
|
105
106
|
const MESSAGE_LABEL_TRASH = 2;
|
|
106
107
|
const MESSAGE_LABEL_INVALID = 3;
|
|
108
|
+
const CONCURRENCY = 16;
|
|
107
109
|
class GraffitiDecentralized {
|
|
108
110
|
dids = new DecentralizedIdentifiers();
|
|
109
111
|
authorization = new Authorization();
|
|
@@ -194,11 +196,7 @@ class GraffitiDecentralized {
|
|
|
194
196
|
);
|
|
195
197
|
input?.setAttribute("value", proposedHandle);
|
|
196
198
|
input?.addEventListener("focus", () => input?.select());
|
|
197
|
-
|
|
198
|
-
setTimeout(() => r(), 0);
|
|
199
|
-
}).then(() => {
|
|
200
|
-
input?.focus();
|
|
201
|
-
});
|
|
199
|
+
setTimeout(() => input?.focus(), 0);
|
|
202
200
|
template?.querySelector("#graffiti-login-handle-form")?.addEventListener("submit", async (e) => {
|
|
203
201
|
e.preventDefault();
|
|
204
202
|
input?.setAttribute("disabled", "true");
|
|
@@ -239,11 +237,12 @@ class GraffitiDecentralized {
|
|
|
239
237
|
e.preventDefault();
|
|
240
238
|
this.login_("");
|
|
241
239
|
});
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
240
|
+
setTimeout(
|
|
241
|
+
() => template?.querySelector(
|
|
242
|
+
"#graffiti-login-new"
|
|
243
|
+
)?.focus(),
|
|
244
|
+
0
|
|
245
|
+
);
|
|
247
246
|
}
|
|
248
247
|
const createUrl = new URL(this.identityCreatorEndpoint);
|
|
249
248
|
createUrl.searchParams.set(
|
|
@@ -617,14 +616,14 @@ class GraffitiDecentralized {
|
|
|
617
616
|
cursor: JSON.stringify({
|
|
618
617
|
channels,
|
|
619
618
|
cursors
|
|
620
|
-
})
|
|
621
|
-
continue: (session2) => this.discoverMeta(channels, schema, cursors, session2)
|
|
619
|
+
})
|
|
622
620
|
};
|
|
623
621
|
}
|
|
624
622
|
discover = (...args) => {
|
|
625
623
|
const [channels, schema, session] = args;
|
|
626
624
|
return this.discoverMeta(channels, schema, {}, session);
|
|
627
625
|
};
|
|
626
|
+
// @ts-ignore
|
|
628
627
|
continueDiscover = (...args) => {
|
|
629
628
|
const [cursor, session] = args;
|
|
630
629
|
let channels;
|
|
@@ -771,150 +770,210 @@ class GraffitiDecentralized {
|
|
|
771
770
|
queryArguments.cursor,
|
|
772
771
|
inboxToken
|
|
773
772
|
);
|
|
773
|
+
const inFlight = [];
|
|
774
|
+
let doneValue = null;
|
|
774
775
|
while (true) {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
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(
|
|
783
|
+
inboxEndpoint,
|
|
784
|
+
itResult.value,
|
|
785
|
+
inboxToken,
|
|
786
|
+
recipient
|
|
787
|
+
).catch((e) => {
|
|
788
|
+
throw e;
|
|
789
|
+
});
|
|
790
|
+
inFlight.push(processPromise);
|
|
791
|
+
}
|
|
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) {
|
|
788
845
|
this.inboxes.label(
|
|
789
846
|
inboxEndpoint,
|
|
790
|
-
|
|
791
|
-
|
|
847
|
+
tombstonedMessageId,
|
|
848
|
+
MESSAGE_LABEL_TRASH,
|
|
792
849
|
inboxToken
|
|
793
850
|
);
|
|
794
|
-
continue;
|
|
795
|
-
}
|
|
796
|
-
const {
|
|
797
|
-
[MESSAGE_DATA_STORAGE_BUCKET_KEY]: storageBucketKey,
|
|
798
|
-
[MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY]: tombstonedMessageId
|
|
799
|
-
} = metadata;
|
|
800
|
-
const allowedTickets = MESSAGE_DATA_ALLOWED_TICKETS_KEY in metadata ? metadata[MESSAGE_DATA_ALLOWED_TICKETS_KEY] : void 0;
|
|
801
|
-
const announcements = MESSAGE_DATA_ANNOUNCEMENTS_KEY in metadata ? metadata[MESSAGE_DATA_ANNOUNCEMENTS_KEY] : void 0;
|
|
802
|
-
if (label === MESSAGE_LABEL_VALID) {
|
|
803
|
-
yield {
|
|
804
|
-
messageId,
|
|
805
|
-
object,
|
|
806
|
-
storageBucketKey,
|
|
807
|
-
allowedTickets,
|
|
808
|
-
tags: receivedTags,
|
|
809
|
-
announcements
|
|
810
|
-
};
|
|
811
|
-
continue;
|
|
812
851
|
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
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`
|
|
819
872
|
);
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
}
|
|
825
|
-
if (typeof storageBucketService.serviceEndpoint !== "string") {
|
|
826
|
-
throw new GraffitiErrorNotFound(
|
|
827
|
-
`Actor ${actor} does not have a valid storage bucket endpoint`
|
|
828
|
-
);
|
|
829
|
-
}
|
|
830
|
-
const storageBucketEndpoint = storageBucketService.serviceEndpoint;
|
|
831
|
-
const objectBytes = await this.storageBuckets.get(
|
|
832
|
-
storageBucketEndpoint,
|
|
833
|
-
storageBucketKey,
|
|
834
|
-
MAX_OBJECT_SIZE_BYTES
|
|
873
|
+
}
|
|
874
|
+
if (typeof storageBucketService.serviceEndpoint !== "string") {
|
|
875
|
+
throw new GraffitiErrorNotFound(
|
|
876
|
+
`Actor ${actor} does not have a valid storage bucket endpoint`
|
|
835
877
|
);
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
await this.objectEncoding.validate(
|
|
847
|
-
object,
|
|
848
|
-
receivedTags,
|
|
849
|
-
objectBytes,
|
|
850
|
-
privateObjectInfo
|
|
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`
|
|
851
888
|
);
|
|
852
|
-
} catch (e) {
|
|
853
|
-
validationError = e;
|
|
854
889
|
}
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
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
|
+
) {
|
|
866
912
|
this.inboxes.label(
|
|
867
913
|
inboxEndpoint,
|
|
868
|
-
|
|
914
|
+
tombstonedMessageId,
|
|
869
915
|
MESSAGE_LABEL_TRASH,
|
|
870
916
|
inboxToken
|
|
871
917
|
);
|
|
872
|
-
}
|
|
873
|
-
yield {
|
|
874
|
-
messageId,
|
|
875
|
-
tombstone: true,
|
|
876
|
-
object,
|
|
877
|
-
storageBucketKey,
|
|
878
|
-
allowedTickets,
|
|
879
|
-
tags: receivedTags,
|
|
880
|
-
announcements
|
|
881
|
-
};
|
|
882
|
-
} else {
|
|
883
|
-
console.error("Recieved an incorrect object");
|
|
884
|
-
console.error(validationError);
|
|
918
|
+
}
|
|
885
919
|
this.inboxes.label(
|
|
886
920
|
inboxEndpoint,
|
|
887
921
|
messageId,
|
|
888
|
-
|
|
922
|
+
MESSAGE_LABEL_TRASH,
|
|
889
923
|
inboxToken
|
|
890
924
|
);
|
|
891
|
-
}
|
|
925
|
+
});
|
|
926
|
+
return {
|
|
927
|
+
messageId,
|
|
928
|
+
tombstone: true,
|
|
929
|
+
object,
|
|
930
|
+
storageBucketKey,
|
|
931
|
+
allowedTickets,
|
|
932
|
+
tags: receivedTags,
|
|
933
|
+
announcements
|
|
934
|
+
};
|
|
892
935
|
} else {
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
}
|
|
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
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
} else {
|
|
946
|
+
if (validationError === void 0) {
|
|
947
|
+
this.inboxes.label(
|
|
948
|
+
inboxEndpoint,
|
|
949
|
+
messageId,
|
|
950
|
+
MESSAGE_LABEL_VALID,
|
|
951
|
+
inboxToken
|
|
952
|
+
);
|
|
953
|
+
return {
|
|
954
|
+
messageId,
|
|
955
|
+
object,
|
|
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
|
|
967
|
+
);
|
|
968
|
+
} else {
|
|
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
|
+
);
|
|
918
977
|
}
|
|
919
978
|
}
|
|
920
979
|
}
|