@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
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
MESSAGE_METADATA_KEY,
|
|
35
35
|
MESSAGE_OBJECT_KEY,
|
|
36
36
|
MESSAGE_TAGS_KEY,
|
|
37
|
+
type LabeledMessage,
|
|
37
38
|
type MessageStream,
|
|
38
39
|
} from "../1-services/4-inboxes";
|
|
39
40
|
|
|
@@ -131,6 +132,8 @@ export interface GraffitiDecentralizedOptions {
|
|
|
131
132
|
defaultInboxEndpoints?: string[];
|
|
132
133
|
}
|
|
133
134
|
|
|
135
|
+
const CONCURRENCY = 16;
|
|
136
|
+
|
|
134
137
|
export class GraffitiDecentralized implements Graffiti {
|
|
135
138
|
protected readonly dids = new DecentralizedIdentifiers();
|
|
136
139
|
protected readonly authorization = new Authorization();
|
|
@@ -785,8 +788,6 @@ export class GraffitiDecentralized implements Graffiti {
|
|
|
785
788
|
channels,
|
|
786
789
|
cursors,
|
|
787
790
|
} satisfies infer_<typeof CursorSchema>),
|
|
788
|
-
continue: (session) =>
|
|
789
|
-
this.discoverMeta<Schema>(channels, schema, cursors, session),
|
|
790
791
|
};
|
|
791
792
|
}
|
|
792
793
|
|
|
@@ -795,6 +796,7 @@ export class GraffitiDecentralized implements Graffiti {
|
|
|
795
796
|
return this.discoverMeta<(typeof args)[1]>(channels, schema, {}, session);
|
|
796
797
|
};
|
|
797
798
|
|
|
799
|
+
// @ts-ignore
|
|
798
800
|
continueDiscover: Graffiti["continueDiscover"] = (...args) => {
|
|
799
801
|
const [cursor, session] = args;
|
|
800
802
|
// Extract the channels from the cursor
|
|
@@ -1009,237 +1011,277 @@ export class GraffitiDecentralized implements Graffiti {
|
|
|
1009
1011
|
inboxToken,
|
|
1010
1012
|
) as unknown as MessageStream<Schema>);
|
|
1011
1013
|
|
|
1014
|
+
const inFlight: Promise<SingleEndpointQueryResult<Schema> | void>[] = [];
|
|
1015
|
+
let doneValue: string | null = null;
|
|
1016
|
+
|
|
1012
1017
|
while (true) {
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1018
|
+
while (doneValue === null && inFlight.length < CONCURRENCY) {
|
|
1019
|
+
const itResult = await iterator.next();
|
|
1020
|
+
if (itResult.done) {
|
|
1021
|
+
doneValue = itResult.value;
|
|
1022
|
+
break;
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
const processPromise = this.processOneLabeledMessage<Schema>(
|
|
1026
|
+
inboxEndpoint,
|
|
1027
|
+
itResult.value,
|
|
1028
|
+
inboxToken,
|
|
1029
|
+
recipient,
|
|
1030
|
+
).catch((e) => {
|
|
1031
|
+
throw e;
|
|
1032
|
+
});
|
|
1033
|
+
|
|
1034
|
+
inFlight.push(processPromise);
|
|
1035
|
+
}
|
|
1016
1036
|
|
|
1017
|
-
const
|
|
1037
|
+
const nextProcessedPromise = inFlight.shift();
|
|
1018
1038
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1039
|
+
if (!nextProcessedPromise) {
|
|
1040
|
+
if (doneValue !== null) return doneValue;
|
|
1041
|
+
|
|
1042
|
+
throw new Error("Process queue empty but no return value");
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
const processed = await nextProcessedPromise;
|
|
1046
|
+
if (processed) yield processed;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
protected async processOneLabeledMessage<Schema extends JSONSchema>(
|
|
1051
|
+
inboxEndpoint: string,
|
|
1052
|
+
result: LabeledMessage<Schema>,
|
|
1053
|
+
inboxToken?: string | null,
|
|
1054
|
+
recipient?: string | null,
|
|
1055
|
+
): Promise<SingleEndpointQueryResult<Schema> | void> {
|
|
1056
|
+
const label = result.l;
|
|
1057
|
+
// Anything invalid or unexpected, we can skip
|
|
1058
|
+
if (
|
|
1059
|
+
label !== MESSAGE_LABEL_VALID &&
|
|
1060
|
+
label !== MESSAGE_LABEL_UNLABELED &&
|
|
1061
|
+
label !== MESSAGE_LABEL_TRASH
|
|
1062
|
+
)
|
|
1063
|
+
return;
|
|
1064
|
+
|
|
1065
|
+
const messageId = result.id;
|
|
1066
|
+
const { o: object, m: metadataBytes, t: receivedTags } = result.m;
|
|
1067
|
+
|
|
1068
|
+
let metadata: MessageMetadata;
|
|
1069
|
+
try {
|
|
1070
|
+
const metadataRaw = dagCborDecode(metadataBytes);
|
|
1071
|
+
metadata = MessageMetadataSchema.parse(metadataRaw);
|
|
1072
|
+
} catch (e) {
|
|
1073
|
+
this.inboxes.label(
|
|
1074
|
+
inboxEndpoint,
|
|
1075
|
+
messageId,
|
|
1076
|
+
MESSAGE_LABEL_INVALID,
|
|
1077
|
+
inboxToken,
|
|
1078
|
+
);
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
const {
|
|
1083
|
+
[MESSAGE_DATA_STORAGE_BUCKET_KEY]: storageBucketKey,
|
|
1084
|
+
[MESSAGE_DATA_TOMBSTONED_MESSAGE_ID_KEY]: tombstonedMessageId,
|
|
1085
|
+
} = metadata;
|
|
1086
|
+
|
|
1087
|
+
const allowedTickets =
|
|
1088
|
+
MESSAGE_DATA_ALLOWED_TICKETS_KEY in metadata
|
|
1089
|
+
? metadata[MESSAGE_DATA_ALLOWED_TICKETS_KEY]
|
|
1090
|
+
: undefined;
|
|
1091
|
+
const announcements =
|
|
1092
|
+
MESSAGE_DATA_ANNOUNCEMENTS_KEY in metadata
|
|
1093
|
+
? metadata[MESSAGE_DATA_ANNOUNCEMENTS_KEY]
|
|
1094
|
+
: undefined;
|
|
1095
|
+
|
|
1096
|
+
if (label === MESSAGE_LABEL_VALID) {
|
|
1097
|
+
return {
|
|
1098
|
+
messageId,
|
|
1099
|
+
object,
|
|
1100
|
+
storageBucketKey,
|
|
1101
|
+
allowedTickets,
|
|
1102
|
+
tags: receivedTags,
|
|
1103
|
+
announcements,
|
|
1104
|
+
};
|
|
1105
|
+
} else if (label === MESSAGE_LABEL_TRASH) {
|
|
1106
|
+
// If it is simply trash, just continue.
|
|
1107
|
+
if (!tombstonedMessageId) return;
|
|
1108
|
+
|
|
1109
|
+
// Make sure the tombstone points to a real message
|
|
1110
|
+
const past = await this.inboxes.get(
|
|
1111
|
+
inboxEndpoint,
|
|
1112
|
+
tombstonedMessageId,
|
|
1113
|
+
inboxToken,
|
|
1114
|
+
);
|
|
1021
1115
|
if (
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
label !== MESSAGE_LABEL_TRASH
|
|
1116
|
+
!past ||
|
|
1117
|
+
past[LABELED_MESSAGE_MESSAGE_KEY][MESSAGE_OBJECT_KEY].url !== object.url
|
|
1025
1118
|
)
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
const messageId = result.id;
|
|
1029
|
-
const { o: object, m: metadataBytes, t: receivedTags } = result.m;
|
|
1119
|
+
return;
|
|
1030
1120
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1121
|
+
// If the referred to message isn't labeled as trash, trash it
|
|
1122
|
+
// This may happen if a trash message is processed on another
|
|
1123
|
+
// device and the device cache is out of date.
|
|
1124
|
+
if (past[LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH) {
|
|
1125
|
+
// Label the message as trash
|
|
1036
1126
|
this.inboxes.label(
|
|
1037
1127
|
inboxEndpoint,
|
|
1038
|
-
|
|
1039
|
-
|
|
1128
|
+
tombstonedMessageId,
|
|
1129
|
+
MESSAGE_LABEL_TRASH,
|
|
1040
1130
|
inboxToken,
|
|
1041
1131
|
);
|
|
1042
|
-
continue;
|
|
1043
1132
|
}
|
|
1044
1133
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1134
|
+
// Return the tombstone
|
|
1135
|
+
return {
|
|
1136
|
+
messageId,
|
|
1137
|
+
tombstone: true,
|
|
1138
|
+
object,
|
|
1139
|
+
storageBucketKey,
|
|
1140
|
+
allowedTickets,
|
|
1141
|
+
tags: receivedTags,
|
|
1142
|
+
announcements,
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1049
1145
|
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
const
|
|
1055
|
-
|
|
1056
|
-
|
|
1146
|
+
// Otherwise, unlabeled: try to validate the object
|
|
1147
|
+
let validationError: unknown | undefined = undefined;
|
|
1148
|
+
try {
|
|
1149
|
+
const actor = object.actor;
|
|
1150
|
+
const actorDocument = await this.dids.resolve(actor);
|
|
1151
|
+
const storageBucketService = actorDocument?.service?.find(
|
|
1152
|
+
(service) =>
|
|
1153
|
+
service.id === DID_SERVICE_ID_GRAFFITI_STORAGE_BUCKET &&
|
|
1154
|
+
service.type === DID_SERVICE_TYPE_GRAFFITI_STORAGE_BUCKET,
|
|
1155
|
+
);
|
|
1156
|
+
if (!storageBucketService) {
|
|
1157
|
+
throw new GraffitiErrorNotFound(
|
|
1158
|
+
`Actor ${actor} has no storage bucket service`,
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
if (typeof storageBucketService.serviceEndpoint !== "string") {
|
|
1162
|
+
throw new GraffitiErrorNotFound(
|
|
1163
|
+
`Actor ${actor} does not have a valid storage bucket endpoint`,
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
const storageBucketEndpoint = storageBucketService.serviceEndpoint;
|
|
1167
|
+
|
|
1168
|
+
const objectBytes = await this.storageBuckets.get(
|
|
1169
|
+
storageBucketEndpoint,
|
|
1170
|
+
storageBucketKey,
|
|
1171
|
+
MAX_OBJECT_SIZE_BYTES,
|
|
1172
|
+
);
|
|
1173
|
+
|
|
1174
|
+
if (MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata && !recipient) {
|
|
1175
|
+
throw new GraffitiErrorForbidden(
|
|
1176
|
+
`Recipient is required when allowed ticket is present`,
|
|
1177
|
+
);
|
|
1178
|
+
}
|
|
1179
|
+
const privateObjectInfo = allowedTickets
|
|
1180
|
+
? { allowedTickets }
|
|
1181
|
+
: MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata
|
|
1182
|
+
? {
|
|
1183
|
+
recipient: recipient ?? "null",
|
|
1184
|
+
allowedTicket: metadata[MESSAGE_DATA_ALLOWED_TICKET_KEY],
|
|
1185
|
+
allowedIndex: metadata[MESSAGE_DATA_ALLOWED_TICKET_INDEX_KEY],
|
|
1186
|
+
}
|
|
1057
1187
|
: undefined;
|
|
1058
1188
|
|
|
1059
|
-
|
|
1060
|
-
|
|
1189
|
+
await this.objectEncoding.validate(
|
|
1190
|
+
object,
|
|
1191
|
+
receivedTags,
|
|
1192
|
+
objectBytes,
|
|
1193
|
+
privateObjectInfo,
|
|
1194
|
+
);
|
|
1195
|
+
} catch (e) {
|
|
1196
|
+
validationError = e;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
if (tombstonedMessageId) {
|
|
1200
|
+
if (validationError instanceof GraffitiErrorNotFound) {
|
|
1201
|
+
// Not found == The tombstone is correct
|
|
1202
|
+
this.inboxes
|
|
1203
|
+
// Get the referenced message
|
|
1204
|
+
.get(inboxEndpoint, tombstonedMessageId, inboxToken)
|
|
1205
|
+
.then((result) => {
|
|
1206
|
+
if (
|
|
1207
|
+
// Make sure that it actually references the object being deleted
|
|
1208
|
+
result &&
|
|
1209
|
+
result[LABELED_MESSAGE_MESSAGE_KEY][MESSAGE_OBJECT_KEY].url ===
|
|
1210
|
+
object.url &&
|
|
1211
|
+
// And that the object is not already marked as trash
|
|
1212
|
+
result[LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH
|
|
1213
|
+
) {
|
|
1214
|
+
// If valid but not yet trash, label the message as trash
|
|
1215
|
+
this.inboxes.label(
|
|
1216
|
+
inboxEndpoint,
|
|
1217
|
+
tombstonedMessageId,
|
|
1218
|
+
MESSAGE_LABEL_TRASH,
|
|
1219
|
+
inboxToken,
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
// Then, label the tombstone message as trash
|
|
1224
|
+
this.inboxes.label(
|
|
1225
|
+
inboxEndpoint,
|
|
1226
|
+
messageId,
|
|
1227
|
+
MESSAGE_LABEL_TRASH,
|
|
1228
|
+
inboxToken,
|
|
1229
|
+
);
|
|
1230
|
+
});
|
|
1231
|
+
|
|
1232
|
+
return {
|
|
1061
1233
|
messageId,
|
|
1234
|
+
tombstone: true,
|
|
1062
1235
|
object,
|
|
1063
1236
|
storageBucketKey,
|
|
1064
1237
|
allowedTickets,
|
|
1065
1238
|
tags: receivedTags,
|
|
1066
1239
|
announcements,
|
|
1067
1240
|
};
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
// Make sure the tombstone points to a real message
|
|
1074
|
-
const past = await this.inboxes.get(
|
|
1241
|
+
} else {
|
|
1242
|
+
console.error("Recieved an incorrect tombstone object");
|
|
1243
|
+
console.error(validationError);
|
|
1244
|
+
this.inboxes.label(
|
|
1075
1245
|
inboxEndpoint,
|
|
1076
|
-
|
|
1246
|
+
messageId,
|
|
1247
|
+
MESSAGE_LABEL_INVALID,
|
|
1077
1248
|
inboxToken,
|
|
1078
1249
|
);
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
if (past[LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH) {
|
|
1090
|
-
// Label the message as trash
|
|
1091
|
-
this.inboxes.label(
|
|
1092
|
-
inboxEndpoint,
|
|
1093
|
-
tombstonedMessageId,
|
|
1094
|
-
MESSAGE_LABEL_TRASH,
|
|
1095
|
-
inboxToken,
|
|
1096
|
-
);
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
// Return the tombstone
|
|
1100
|
-
yield {
|
|
1250
|
+
}
|
|
1251
|
+
} else {
|
|
1252
|
+
if (validationError === undefined) {
|
|
1253
|
+
this.inboxes.label(
|
|
1254
|
+
inboxEndpoint,
|
|
1255
|
+
messageId,
|
|
1256
|
+
MESSAGE_LABEL_VALID,
|
|
1257
|
+
inboxToken,
|
|
1258
|
+
);
|
|
1259
|
+
return {
|
|
1101
1260
|
messageId,
|
|
1102
|
-
tombstone: true,
|
|
1103
1261
|
object,
|
|
1104
1262
|
storageBucketKey,
|
|
1105
|
-
allowedTickets,
|
|
1106
1263
|
tags: receivedTags,
|
|
1264
|
+
allowedTickets,
|
|
1107
1265
|
announcements,
|
|
1108
1266
|
};
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
const storageBucketService = actorDocument?.service?.find(
|
|
1118
|
-
(service) =>
|
|
1119
|
-
service.id === DID_SERVICE_ID_GRAFFITI_STORAGE_BUCKET &&
|
|
1120
|
-
service.type === DID_SERVICE_TYPE_GRAFFITI_STORAGE_BUCKET,
|
|
1121
|
-
);
|
|
1122
|
-
if (!storageBucketService) {
|
|
1123
|
-
throw new GraffitiErrorNotFound(
|
|
1124
|
-
`Actor ${actor} has no storage bucket service`,
|
|
1125
|
-
);
|
|
1126
|
-
}
|
|
1127
|
-
if (typeof storageBucketService.serviceEndpoint !== "string") {
|
|
1128
|
-
throw new GraffitiErrorNotFound(
|
|
1129
|
-
`Actor ${actor} does not have a valid storage bucket endpoint`,
|
|
1130
|
-
);
|
|
1131
|
-
}
|
|
1132
|
-
const storageBucketEndpoint = storageBucketService.serviceEndpoint;
|
|
1133
|
-
|
|
1134
|
-
const objectBytes = await this.storageBuckets.get(
|
|
1135
|
-
storageBucketEndpoint,
|
|
1136
|
-
storageBucketKey,
|
|
1137
|
-
MAX_OBJECT_SIZE_BYTES,
|
|
1138
|
-
);
|
|
1139
|
-
|
|
1140
|
-
if (MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata && !recipient) {
|
|
1141
|
-
throw new GraffitiErrorForbidden(
|
|
1142
|
-
`Recipient is required when allowed ticket is present`,
|
|
1143
|
-
);
|
|
1144
|
-
}
|
|
1145
|
-
const privateObjectInfo = allowedTickets
|
|
1146
|
-
? { allowedTickets }
|
|
1147
|
-
: MESSAGE_DATA_ALLOWED_TICKET_KEY in metadata
|
|
1148
|
-
? {
|
|
1149
|
-
recipient: recipient ?? "null",
|
|
1150
|
-
allowedTicket: metadata[MESSAGE_DATA_ALLOWED_TICKET_KEY],
|
|
1151
|
-
allowedIndex: metadata[MESSAGE_DATA_ALLOWED_TICKET_INDEX_KEY],
|
|
1152
|
-
}
|
|
1153
|
-
: undefined;
|
|
1154
|
-
|
|
1155
|
-
await this.objectEncoding.validate(
|
|
1156
|
-
object,
|
|
1157
|
-
receivedTags,
|
|
1158
|
-
objectBytes,
|
|
1159
|
-
privateObjectInfo,
|
|
1267
|
+
} else if (validationError instanceof GraffitiErrorNotFound) {
|
|
1268
|
+
// Item was deleted before we got a chance to
|
|
1269
|
+
// validate it. Just label the message as trash.
|
|
1270
|
+
this.inboxes.label(
|
|
1271
|
+
inboxEndpoint,
|
|
1272
|
+
messageId,
|
|
1273
|
+
MESSAGE_LABEL_TRASH,
|
|
1274
|
+
inboxToken,
|
|
1160
1275
|
);
|
|
1161
|
-
} catch (e) {
|
|
1162
|
-
validationError = e;
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
if (tombstonedMessageId) {
|
|
1166
|
-
if (validationError instanceof GraffitiErrorNotFound) {
|
|
1167
|
-
// Not found == The tombstone is correct
|
|
1168
|
-
this.inboxes
|
|
1169
|
-
// Get the referenced message
|
|
1170
|
-
.get(inboxEndpoint, tombstonedMessageId, inboxToken)
|
|
1171
|
-
.then((result) => {
|
|
1172
|
-
if (
|
|
1173
|
-
// Make sure that it actually references the object being deleted
|
|
1174
|
-
result &&
|
|
1175
|
-
result[LABELED_MESSAGE_MESSAGE_KEY][MESSAGE_OBJECT_KEY].url ===
|
|
1176
|
-
object.url &&
|
|
1177
|
-
// And that the object is not already marked as trash
|
|
1178
|
-
result[LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH
|
|
1179
|
-
) {
|
|
1180
|
-
// If valid but not yet trash, label the message as trash
|
|
1181
|
-
this.inboxes.label(
|
|
1182
|
-
inboxEndpoint,
|
|
1183
|
-
tombstonedMessageId,
|
|
1184
|
-
MESSAGE_LABEL_TRASH,
|
|
1185
|
-
inboxToken,
|
|
1186
|
-
);
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
// Then, label the tombstone message as trash
|
|
1190
|
-
this.inboxes.label(
|
|
1191
|
-
inboxEndpoint,
|
|
1192
|
-
messageId,
|
|
1193
|
-
MESSAGE_LABEL_TRASH,
|
|
1194
|
-
inboxToken,
|
|
1195
|
-
);
|
|
1196
|
-
});
|
|
1197
|
-
|
|
1198
|
-
yield {
|
|
1199
|
-
messageId,
|
|
1200
|
-
tombstone: true,
|
|
1201
|
-
object,
|
|
1202
|
-
storageBucketKey,
|
|
1203
|
-
allowedTickets,
|
|
1204
|
-
tags: receivedTags,
|
|
1205
|
-
announcements,
|
|
1206
|
-
};
|
|
1207
|
-
} else {
|
|
1208
|
-
console.error("Recieved an incorrect object");
|
|
1209
|
-
console.error(validationError);
|
|
1210
|
-
this.inboxes.label(
|
|
1211
|
-
inboxEndpoint,
|
|
1212
|
-
messageId,
|
|
1213
|
-
MESSAGE_LABEL_INVALID,
|
|
1214
|
-
inboxToken,
|
|
1215
|
-
);
|
|
1216
|
-
}
|
|
1217
1276
|
} else {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
messageId,
|
|
1227
|
-
object,
|
|
1228
|
-
storageBucketKey,
|
|
1229
|
-
tags: receivedTags,
|
|
1230
|
-
allowedTickets,
|
|
1231
|
-
announcements,
|
|
1232
|
-
};
|
|
1233
|
-
} else {
|
|
1234
|
-
console.error("Recieved an incorrect object");
|
|
1235
|
-
console.error(validationError);
|
|
1236
|
-
this.inboxes.label(
|
|
1237
|
-
inboxEndpoint,
|
|
1238
|
-
messageId,
|
|
1239
|
-
MESSAGE_LABEL_INVALID,
|
|
1240
|
-
inboxToken,
|
|
1241
|
-
);
|
|
1242
|
-
}
|
|
1277
|
+
console.error("Recieved an incorrect object");
|
|
1278
|
+
console.error(validationError);
|
|
1279
|
+
this.inboxes.label(
|
|
1280
|
+
inboxEndpoint,
|
|
1281
|
+
messageId,
|
|
1282
|
+
MESSAGE_LABEL_INVALID,
|
|
1283
|
+
inboxToken,
|
|
1284
|
+
);
|
|
1243
1285
|
}
|
|
1244
1286
|
}
|
|
1245
1287
|
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../node_modules/@graffiti-garden/modal/src/style.css"],
|
|
4
|
-
"sourcesContent": [".graffiti-modal {\n --back: rgba(26, 26, 26, 0.85);\n --halfback: rgba(80, 80, 80, 0.85);\n --halfback2: rgba(26, 26, 26, 0.85);\n --hover: rgba(202, 122, 204, 0.3);\n --frontfaded: rgba(190, 190, 190);\n --front: rgba(240, 240, 240);\n --emph: rgb(202, 122, 204);\n --blurpix: 3px;\n border-color: var(--emph);\n box-sizing: border-box;\n border-width: 2px;\n padding: 0;\n margin: 0;\n border-radius: 1rem;\n box-shadow: 0 0 2rem black;\n overflow: hidden;\n opacity: 0;\n transition: opacity 0.3s;\n pointer-events: none;\n min-width: 95dvw;\n min-height: 95dvh;\n height: 95dvh;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: center;\n font-family:\n Inter,\n -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n \"Fira Sans\",\n \"Droid Sans\",\n \"Helvetica Neue\",\n sans-serif;\n color: var(--front);\n font-size: 150%;\n\n * {\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n }\n\n ::selection {\n background: rgba(202, 122, 204, 0.3);\n }\n\n :focus {\n outline: 2px solid var(--front);\n }\n\n header {\n width: 100%;\n display: flex;\n justify-content: flex-end;\n }\n\n main {\n flex: 1;\n max-width: 600px;\n width: 100%;\n gap: 2em;\n padding-inline: clamp(1rem, 4dvw, 3rem);\n padding-block: clamp(1rem, 4dvh, 3rem);\n margin-inline: clamp(1rem, 4dvw, 3rem);\n margin-block: clamp(1rem, 4dvh, 3rem);\n background: var(--back);\n border-radius: 1rem;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n scrollbar-color: var(--emph) rgba(0, 0, 0, 0);\n }\n\n ul {\n list-style-type: none;\n display: flex;\n flex-direction: column;\n gap: 0.5em;\n align-items: stretch;\n justify-content: stretch;\n }\n\n aside {\n color: var(--frontfaded);\n }\n\n .secondary,\n a:not([type=\"button\"]) {\n color: var(--emph);\n }\n\n h1 {\n font-size: 120%;\n font-family:\n Rock Salt,\n cursive,\n sans-serif;\n letter-spacing: 0.1em;\n text-align: center;\n color: var(--front);\n }\n\n h1 a:not([type=\"button\"]) {\n color: inherit;\n }\n\n h1 a:hover {\n background: none;\n color: inherit;\n }\n\n button,\n input[type=\"submit\"],\n input[type=\"text\"],\n a[type=\"button\"] {\n font-size: inherit;\n width: 100%;\n text-align: center;\n display: block;\n border-radius: 1rem;\n border: 2px solid var(--emph);\n padding: 1em;\n padding-top: 0.5em;\n padding-bottom: 0.5em;\n transition: 0.1s;\n text-overflow: ellipsis;\n background: none;\n line-height: 1.2em;\n }\n\n input[type=\"text\"] {\n font-weight: 500;\n background: var(--front);\n text-align: left;\n color: black;\n }\n\n header button {\n border-radius: 0 0 0 1rem;\n border-right: none;\n border-top: none;\n background-color: var(--halfback2);\n width: fit-content;\n position: relative;\n overflow: hidden;\n }\n\n header button::before {\n z-index: -1;\n top: 0;\n left: 0;\n height: 100%;\n position: absolute;\n width: 100%;\n content: \"\";\n background-color: var(--back);\n }\n\n @media (max-height: 600px) {\n main {\n gap: 1em;\n }\n\n h1 {\n font-size: 100%;\n }\n }\n\n @media (max-width: 600px) {\n main {\n border-radius: 0;\n margin: auto;\n overflow: auto;\n }\n\n header button {\n border-radius: 0;\n border-left: none;\n width: 100%;\n }\n\n html {\n justify-content: safe center;\n }\n }\n\n a {\n text-decoration: none;\n }\n\n :is(button, ul a, input[type=\"submit\"]):hover {\n cursor: pointer;\n background: var(--hover);\n color: var(--front);\n }\n\n a:hover {\n text-decoration: underline;\n cursor: pointer;\n }\n\n form {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: stretch;\n gap: 0.5em;\n }\n\n iframe {\n width: 100%;\n height: 100%;\n border: none;\n }\n\n :is(button, a[type=\"button\"], input[type=\"submit\"]).secondary {\n color: rgb(244, 213, 244);\n background: rgba(26, 26, 26, 0.6);\n }\n\n :is(button, a[type=\"button\"], input[type=\"submit\"]):not(.secondary) {\n background: var(--hover);\n color: white;\n }\n\n :is(button, a[type=\"button\"], input[type=\"submit\"]):hover {\n background: rgba(202, 122, 204, 0.6);\n color: white;\n text-decoration: none;\n }\n}\n\n.graffiti-modal[open] {\n pointer-events: inherit;\n opacity: 1;\n}\n\n.graffiti-modal::backdrop {\n background-color: black;\n opacity: 0.5;\n}\n\n.graffiti-modal::before {\n content: \"\";\n position: fixed;\n left: 0;\n right: 0;\n z-index: -1;\n background-image: url(graffiti.jpg);\n background-size: cover;\n background-repeat: no-repeat;\n background-position: 50% 50%;\n height: calc(100% + 2 * var(--blurpix));\n width: calc(100% + 2 * var(--blurpix));\n filter: blur(var(--blurpix));\n margin: calc(-1 * var(--blurpix));\n}\n"],
|
|
5
|
-
"mappings": "4BAAA,IAAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;",
|
|
6
|
-
"names": ["style_default"]
|
|
7
|
-
}
|