@fedify/fedify 2.3.0-dev.1069 → 2.3.0-dev.1099
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/{builder-DQ2zYTeA.mjs → builder-BkRRjxzb.mjs} +4 -4
- package/dist/{chunk-nlSIicah.js → chunk-CRNNMoPX.js} +2 -2
- package/dist/{chunk-QSgtlS85.mjs → chunk-DNRtMIoB.mjs} +1 -1
- package/dist/{client-z-8dc-e1.d.cts → client-CAM_bQXx.d.cts} +1 -0
- package/dist/{client-AtlibPOU.d.ts → client-CSddvgWN.d.ts} +1 -2
- package/dist/compat/mod.d.cts +2 -1
- package/dist/compat/mod.d.ts +2 -3
- package/dist/compat/mod.js +3 -3
- package/dist/compat/outgoing-jsonld.test.mjs +2 -2
- package/dist/compat/public-audience.test.mjs +2 -2
- package/dist/compat/transformers.test.mjs +2 -2
- package/dist/{context-7Azky82W.mjs → context-BAE7AKLA.mjs} +61 -3
- package/dist/{context-DrNqYkPw.d.ts → context-C0C_sRha.d.cts} +6 -7
- package/dist/{context-BKLGj9QO.d.cts → context-Dqgt8saU.d.ts} +6 -5
- package/dist/{deno-CFXqOz6w.mjs → deno-DBabeupC.mjs} +1 -1
- package/dist/{docloader-QNtAtTZF.mjs → docloader-DA5FzJOR.mjs} +3 -3
- package/dist/{esm-DhnRLoG9.mjs → esm-sdtqOUPu.mjs} +5 -7
- package/dist/{execAsync-eck5rbtb.mjs → execAsync-DCBrgFiV.mjs} +2 -2
- package/dist/federation/builder.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +86 -4
- package/dist/federation/idempotency.test.mjs +3 -3
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/keycache.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +387 -20
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +4 -3
- package/dist/federation/mod.d.ts +4 -5
- package/dist/federation/mod.js +2 -2
- package/dist/federation/mq.test.mjs +1 -1
- package/dist/federation/negotiation.test.mjs +1 -1
- package/dist/federation/router.test.mjs +1 -1
- package/dist/federation/send.test.mjs +133 -139
- package/dist/federation/webfinger.test.mjs +3 -3
- package/dist/{getMachineId-bsd-DqZ4QRFp.mjs → getMachineId-bsd-etIyxDet.mjs} +3 -3
- package/dist/{getMachineId-darwin-DMbbW3m7.mjs → getMachineId-darwin-D23zTf4g.mjs} +3 -3
- package/dist/{getMachineId-linux-lyeD2ug3.mjs → getMachineId-linux-ObI47Hql.mjs} +2 -2
- package/dist/{getMachineId-unsupported-JuKr57jY.mjs → getMachineId-unsupported-Ddu-PFeh.mjs} +2 -2
- package/dist/{getMachineId-win-Dxyf5pJq.mjs → getMachineId-win-Dpap6v5i.mjs} +3 -3
- package/dist/{http-QHJGzUe8.mjs → http-5G18W3NP.mjs} +59 -11
- package/dist/{http-CrGuipxe.d.cts → http-BDZeS5om.d.ts} +2 -1
- package/dist/{http-aQzN9Ayi.d.ts → http-C87EWkO0.d.cts} +2 -3
- package/dist/{http-D2EDlTr2.js → http-Dzy5c472.js} +58 -10
- package/dist/{http-e1wtIlFo.cjs → http-W2u_KBoQ.cjs} +57 -9
- package/dist/{key-CpAxygvh.mjs → key-D9dUsyow.mjs} +2 -2
- package/dist/{kv-CbLNp3zQ.d.cts → kv-D6hNiMTK.d.ts} +1 -0
- package/dist/{kv-cache-B3GfB70S.cjs → kv-cache-BygrlQ1c.cjs} +2 -2
- package/dist/{kv-cache-KLjvIlKt.js → kv-cache-CBSgxEsZ.js} +2 -2
- package/dist/{kv-cache-Bmv7tUzz.mjs → kv-cache-CiiNwT6W.mjs} +2 -2
- package/dist/{kv-GFYnFoOl.d.ts → kv-gJ8LYbxX.d.cts} +1 -3
- package/dist/{ld-Ce_vkKjG.mjs → ld-hbxDLO1k.mjs} +3 -3
- package/dist/{middleware-DsGmXfXz.mjs → middleware-BXnhAGF9.mjs} +201 -119
- package/dist/{middleware-DOLrvK_b.cjs → middleware-Caj827xW.cjs} +358 -139
- package/dist/{middleware-BJMPv7_l.mjs → middleware-DZQsPMZb.mjs} +1 -1
- package/dist/{middleware-De241etq.js → middleware-vCF_cKAq.js} +346 -111
- package/dist/{mod-CLgIXe9w.d.ts → mod-B0rWmfW5.d.cts} +4 -5
- package/dist/{mod-CMEbIaNh.d.cts → mod-BhU_H1I_.d.ts} +4 -3
- package/dist/{mod-B8Z8mBLk.d.ts → mod-CLPnQPsv.d.cts} +2 -3
- package/dist/{mod-Cr3f-ACa.d.cts → mod-DHO9lk3D.d.ts} +3 -2
- package/dist/{mod-CR8soWa9.d.ts → mod-DXY9JF28.d.cts} +3 -4
- package/dist/{mod-DClCOv0M.d.cts → mod-Dx3-hqyo.d.ts} +2 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.d.cts +9 -8
- package/dist/mod.d.ts +9 -10
- package/dist/mod.js +9 -9
- package/dist/{negotiation-VnHNB0Q5.mjs → negotiation-DDstyBvc.mjs} +29 -0
- package/dist/nodeinfo/client.test.mjs +2 -2
- package/dist/nodeinfo/handler.test.mjs +2 -2
- package/dist/nodeinfo/mod.d.cts +2 -1
- package/dist/nodeinfo/mod.d.ts +2 -3
- package/dist/nodeinfo/mod.js +3 -3
- package/dist/otel/exporter.test.mjs +2 -2
- package/dist/otel/mod.d.cts +2 -1
- package/dist/otel/mod.d.ts +2 -3
- package/dist/otel/mod.js +2 -2
- package/dist/{outgoing-jsonld-Bi7n-dEy.mjs → outgoing-jsonld-BgFLCJQ_.mjs} +2 -2
- package/dist/{owner-CptqhsOy.d.cts → owner-CnngXDNJ.d.ts} +2 -1
- package/dist/{owner-74ARJ5TL.d.ts → owner-DEvZuyOE.d.cts} +2 -3
- package/dist/{owner-DmgzyItA.mjs → owner-DwJe0BH9.mjs} +2 -2
- package/dist/{proof-BU1TpFYI.cjs → proof-CZCaAURh.cjs} +3 -3
- package/dist/{proof-DLDsFYfD.js → proof-DMJJZnKd.js} +2 -2
- package/dist/{proof-C3q2IhUr.mjs → proof-erpV_J_n.mjs} +5 -5
- package/dist/runtime/mod.d.cts +1 -0
- package/dist/runtime/mod.d.ts +1 -2
- package/dist/runtime/mod.js +3 -3
- package/dist/{send-CTi2iPXp.mjs → send-BOwz4Hw5.mjs} +128 -4
- package/dist/sig/http.test.mjs +140 -27
- package/dist/sig/key.test.mjs +2 -2
- package/dist/sig/ld.test.mjs +3 -3
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.cts +4 -3
- package/dist/sig/mod.d.ts +4 -5
- package/dist/sig/mod.js +4 -4
- package/dist/sig/owner.test.mjs +2 -2
- package/dist/sig/proof.test.mjs +3 -3
- package/dist/testing/mod.d.mts +6 -1
- package/dist/testing/mod.mjs +1 -2
- package/dist/{transformers-ve6e2xcg.js → transformers-BGMIq1cs.js} +2 -2
- package/dist/{types-hvL8ElAs.js → types-CAY3OdLq.js} +2 -2
- package/dist/utils/docloader.test.mjs +3 -3
- package/dist/utils/kv-cache.test.mjs +2 -2
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +2 -1
- package/dist/utils/mod.d.ts +2 -3
- package/dist/utils/mod.js +3 -3
- package/dist/vocab/cjs.test.mjs +1 -1
- package/dist/vocab/mod.d.cts +1 -0
- package/dist/vocab/mod.d.ts +1 -2
- package/dist/vocab/mod.js +2 -2
- package/package.json +15 -15
- package/dist/middleware-CibncbiT.cjs +0 -4
- package/dist/{client-CIiz1WX7.mjs → client-B_A6mfn3.mjs} +1 -1
- package/dist/{public-audience-PVTwU_Ex.mjs → public-audience-N3pyOx2p.mjs} +1 -1
- /package/dist/{router-CrMLXoOr.mjs → router-BT_F5748.mjs} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
|
-
require("./chunk-DDcVe30Y.cjs");
|
|
3
|
+
const require_chunk = require("./chunk-DDcVe30Y.cjs");
|
|
4
4
|
const require_transformers = require("./transformers-NeAONrAq.cjs");
|
|
5
|
-
const require_http = require("./http-
|
|
6
|
-
const require_proof = require("./proof-
|
|
5
|
+
const require_http = require("./http-W2u_KBoQ.cjs");
|
|
6
|
+
const require_proof = require("./proof-CZCaAURh.cjs");
|
|
7
7
|
const require_types = require("./types-KC4QAoxe.cjs");
|
|
8
|
-
const require_kv_cache = require("./kv-cache-
|
|
8
|
+
const require_kv_cache = require("./kv-cache-BygrlQ1c.cjs");
|
|
9
9
|
let _logtape_logtape = require("@logtape/logtape");
|
|
10
10
|
let _fedify_vocab = require("@fedify/vocab");
|
|
11
11
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
@@ -211,7 +211,7 @@ var FederationBuilderImpl = class {
|
|
|
211
211
|
this.collectionTypeIds = {};
|
|
212
212
|
}
|
|
213
213
|
async build(options) {
|
|
214
|
-
const { FederationImpl } = await Promise.resolve().then(() =>
|
|
214
|
+
const { FederationImpl } = await Promise.resolve().then(() => middleware_exports);
|
|
215
215
|
const f = new FederationImpl(options);
|
|
216
216
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
217
217
|
f.router = this.router.clone();
|
|
@@ -788,6 +788,12 @@ var FederationMetrics = class {
|
|
|
788
788
|
inboxProcessingDuration;
|
|
789
789
|
httpServerRequestCount;
|
|
790
790
|
httpServerRequestDuration;
|
|
791
|
+
queueTaskEnqueued;
|
|
792
|
+
queueTaskStarted;
|
|
793
|
+
queueTaskCompleted;
|
|
794
|
+
queueTaskFailed;
|
|
795
|
+
queueTaskDuration;
|
|
796
|
+
queueTaskInFlight;
|
|
791
797
|
constructor(meterProvider) {
|
|
792
798
|
const meter = meterProvider.getMeter(require_http.name, require_http.version);
|
|
793
799
|
this.deliverySent = meter.createCounter("activitypub.delivery.sent", {
|
|
@@ -834,6 +840,46 @@ var FederationMetrics = class {
|
|
|
834
840
|
1e4
|
|
835
841
|
] }
|
|
836
842
|
});
|
|
843
|
+
this.queueTaskEnqueued = meter.createCounter("fedify.queue.task.enqueued", {
|
|
844
|
+
description: "Tasks Fedify enqueued for inbox, outbox, or fanout work.",
|
|
845
|
+
unit: "{task}"
|
|
846
|
+
});
|
|
847
|
+
this.queueTaskStarted = meter.createCounter("fedify.queue.task.started", {
|
|
848
|
+
description: "Tasks Fedify began processing as a queue worker.",
|
|
849
|
+
unit: "{task}"
|
|
850
|
+
});
|
|
851
|
+
this.queueTaskCompleted = meter.createCounter("fedify.queue.task.completed", {
|
|
852
|
+
description: "Queue tasks Fedify finished processing without throwing.",
|
|
853
|
+
unit: "{task}"
|
|
854
|
+
});
|
|
855
|
+
this.queueTaskFailed = meter.createCounter("fedify.queue.task.failed", {
|
|
856
|
+
description: "Queue tasks Fedify abandoned because processing threw.",
|
|
857
|
+
unit: "{task}"
|
|
858
|
+
});
|
|
859
|
+
this.queueTaskDuration = meter.createHistogram("fedify.queue.task.duration", {
|
|
860
|
+
description: "Duration of queue task processing in Fedify workers.",
|
|
861
|
+
unit: "ms",
|
|
862
|
+
advice: { explicitBucketBoundaries: [
|
|
863
|
+
5,
|
|
864
|
+
10,
|
|
865
|
+
25,
|
|
866
|
+
50,
|
|
867
|
+
75,
|
|
868
|
+
100,
|
|
869
|
+
250,
|
|
870
|
+
500,
|
|
871
|
+
750,
|
|
872
|
+
1e3,
|
|
873
|
+
2500,
|
|
874
|
+
5e3,
|
|
875
|
+
7500,
|
|
876
|
+
1e4
|
|
877
|
+
] }
|
|
878
|
+
});
|
|
879
|
+
this.queueTaskInFlight = meter.createUpDownCounter("fedify.queue.task.in_flight", {
|
|
880
|
+
description: "Queue tasks currently being processed in this Fedify process.",
|
|
881
|
+
unit: "{task}"
|
|
882
|
+
});
|
|
837
883
|
}
|
|
838
884
|
recordDelivery(inbox, durationMs, success, activityType) {
|
|
839
885
|
const deliveryAttributes = {
|
|
@@ -868,7 +914,85 @@ var FederationMetrics = class {
|
|
|
868
914
|
this.httpServerRequestCount.add(1, attributes);
|
|
869
915
|
this.httpServerRequestDuration.record(durationMs, attributes);
|
|
870
916
|
}
|
|
917
|
+
recordQueueTaskEnqueued(common, attempt) {
|
|
918
|
+
const attributes = buildQueueTaskAttributes(common);
|
|
919
|
+
attributes["fedify.queue.task.attempt"] = attempt;
|
|
920
|
+
this.queueTaskEnqueued.add(1, attributes);
|
|
921
|
+
}
|
|
922
|
+
recordQueueTaskStarted(common) {
|
|
923
|
+
this.queueTaskStarted.add(1, buildQueueTaskAttributes(common));
|
|
924
|
+
}
|
|
925
|
+
incrementQueueTaskInFlight(common) {
|
|
926
|
+
this.queueTaskInFlight.add(1, buildQueueTaskInFlightAttributes(common));
|
|
927
|
+
}
|
|
928
|
+
decrementQueueTaskInFlight(common) {
|
|
929
|
+
this.queueTaskInFlight.add(-1, buildQueueTaskInFlightAttributes(common));
|
|
930
|
+
}
|
|
931
|
+
recordQueueTaskOutcome(common, result, durationMs) {
|
|
932
|
+
const attributes = buildQueueTaskAttributes(common);
|
|
933
|
+
attributes["fedify.queue.task.result"] = result;
|
|
934
|
+
if (result === "completed") this.queueTaskCompleted.add(1, attributes);
|
|
935
|
+
else if (result === "failed") this.queueTaskFailed.add(1, attributes);
|
|
936
|
+
this.queueTaskDuration.record(durationMs, attributes);
|
|
937
|
+
}
|
|
871
938
|
};
|
|
939
|
+
function buildQueueTaskAttributes(common) {
|
|
940
|
+
const attributes = { "fedify.queue.role": common.role };
|
|
941
|
+
const backend = getQueueBackend(common.queue);
|
|
942
|
+
if (backend != null) attributes["fedify.queue.backend"] = backend;
|
|
943
|
+
const nativeRetrial = common.queue?.nativeRetrial;
|
|
944
|
+
if (typeof nativeRetrial === "boolean") attributes["fedify.queue.native_retrial"] = nativeRetrial;
|
|
945
|
+
if (common.activityType != null) attributes["activitypub.activity.type"] = common.activityType;
|
|
946
|
+
return attributes;
|
|
947
|
+
}
|
|
948
|
+
function buildQueueTaskInFlightAttributes(common) {
|
|
949
|
+
return buildQueueTaskAttributes({
|
|
950
|
+
role: common.role,
|
|
951
|
+
queue: common.queue
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
/**
|
|
955
|
+
* Returns the constructor name of the given message queue, when it is a
|
|
956
|
+
* meaningful identifier. Used as a best-effort `fedify.queue.backend`
|
|
957
|
+
* attribute on queue task metrics; returns `undefined` for plain object
|
|
958
|
+
* literals (whose constructor is `Object`) so the attribute does not appear
|
|
959
|
+
* with a non-informative value.
|
|
960
|
+
* @since 2.3.0
|
|
961
|
+
*/
|
|
962
|
+
function getQueueBackend(queue) {
|
|
963
|
+
const name = queue?.constructor?.name;
|
|
964
|
+
if (name == null || name === "" || name === "Object") return void 0;
|
|
965
|
+
return name;
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* Records `fedify.queue.task.enqueued` for an outgoing outbox enqueue.
|
|
969
|
+
*
|
|
970
|
+
* Both `Context.sendActivity()` and `OutboxContext.forwardActivity()` enqueue
|
|
971
|
+
* outbox messages with the same metric attributes (role, queue, activity
|
|
972
|
+
* type, attempt), so they share this helper rather than each defining a local
|
|
973
|
+
* closure.
|
|
974
|
+
* @since 2.3.0
|
|
975
|
+
*/
|
|
976
|
+
function recordOutboxEnqueue(meterProvider, outboxQueue, message) {
|
|
977
|
+
getFederationMetrics(meterProvider).recordQueueTaskEnqueued({
|
|
978
|
+
role: "outbox",
|
|
979
|
+
queue: outboxQueue,
|
|
980
|
+
activityType: message.activityType
|
|
981
|
+
}, message.attempt);
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Whether the given thrown value is an `AbortError`.
|
|
985
|
+
*
|
|
986
|
+
* `processQueuedTask` distinguishes aborted tasks (recorded as
|
|
987
|
+
* `fedify.queue.task.result=aborted`) from other failures so that backend
|
|
988
|
+
* shutdown signals do not inflate the `fedify.queue.task.failed` counter.
|
|
989
|
+
* @since 2.3.0
|
|
990
|
+
*/
|
|
991
|
+
function isAbortError(error) {
|
|
992
|
+
if (error == null || typeof error !== "object") return false;
|
|
993
|
+
const name = error.name;
|
|
994
|
+
return typeof name === "string" && name === "AbortError";
|
|
995
|
+
}
|
|
872
996
|
const KNOWN_HTTP_METHODS = new Set([
|
|
873
997
|
"CONNECT",
|
|
874
998
|
"DELETE",
|
|
@@ -990,6 +1114,11 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
|
|
|
990
1114
|
});
|
|
991
1115
|
throw error;
|
|
992
1116
|
}
|
|
1117
|
+
getFederationMetrics(meterProvider).recordQueueTaskEnqueued({
|
|
1118
|
+
role: "inbox",
|
|
1119
|
+
queue,
|
|
1120
|
+
activityType: (0, _fedify_vocab.getTypeId)(activity).href
|
|
1121
|
+
}, 0);
|
|
993
1122
|
logger.info("Activity {activityId} is enqueued.", {
|
|
994
1123
|
activityId: activity.id?.href,
|
|
995
1124
|
activity: json,
|
|
@@ -1150,6 +1279,35 @@ var KvKeyCache = class {
|
|
|
1150
1279
|
};
|
|
1151
1280
|
//#endregion
|
|
1152
1281
|
//#region src/federation/negotiation.ts
|
|
1282
|
+
/*!
|
|
1283
|
+
* Adapted directly from negotiator at https://github.com/jshttp/negotiator/
|
|
1284
|
+
* which is licensed as follows:
|
|
1285
|
+
*
|
|
1286
|
+
* (The MIT License)
|
|
1287
|
+
*
|
|
1288
|
+
* Copyright (c) 2012-2014 Federico Romero
|
|
1289
|
+
* Copyright (c) 2012-2014 Isaac Z. Schlueter
|
|
1290
|
+
* Copyright (c) 2014-2015 Douglas Christopher Wilson
|
|
1291
|
+
*
|
|
1292
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
|
1293
|
+
* a copy of this software and associated documentation files (the
|
|
1294
|
+
* 'Software'), to deal in the Software without restriction, including
|
|
1295
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
|
1296
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
1297
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
|
1298
|
+
* the following conditions:
|
|
1299
|
+
*
|
|
1300
|
+
* The above copyright notice and this permission notice shall be
|
|
1301
|
+
* included in all copies or substantial portions of the Software.
|
|
1302
|
+
*
|
|
1303
|
+
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
1304
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
1305
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
1306
|
+
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
1307
|
+
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
1308
|
+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
1309
|
+
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
1310
|
+
*/
|
|
1153
1311
|
function compareSpecs(a, b) {
|
|
1154
1312
|
return b.q - a.q || (b.s ?? 0) - (a.s ?? 0) || (a.o ?? 0) - (b.o ?? 0) || a.i - b.i || 0;
|
|
1155
1313
|
}
|
|
@@ -2032,6 +2190,14 @@ async function _handleOrderedCollection(request, { name, values, context, tracer
|
|
|
2032
2190
|
* @since 1.8.0
|
|
2033
2191
|
*/
|
|
2034
2192
|
var CustomCollectionHandler = class {
|
|
2193
|
+
name;
|
|
2194
|
+
values;
|
|
2195
|
+
context;
|
|
2196
|
+
callbacks;
|
|
2197
|
+
tracerProvider;
|
|
2198
|
+
Collection;
|
|
2199
|
+
CollectionPage;
|
|
2200
|
+
filterPredicate;
|
|
2035
2201
|
/**
|
|
2036
2202
|
* The tracer for telemetry.
|
|
2037
2203
|
* @type {Tracer}
|
|
@@ -2896,6 +3062,14 @@ async function handleWebFingerInternal(request, { context, host, actorDispatcher
|
|
|
2896
3062
|
}
|
|
2897
3063
|
//#endregion
|
|
2898
3064
|
//#region src/federation/middleware.ts
|
|
3065
|
+
var middleware_exports = /* @__PURE__ */ require_chunk.__exportAll({
|
|
3066
|
+
ContextImpl: () => ContextImpl,
|
|
3067
|
+
FederationImpl: () => FederationImpl,
|
|
3068
|
+
InboxContextImpl: () => InboxContextImpl,
|
|
3069
|
+
KvSpecDeterminer: () => KvSpecDeterminer,
|
|
3070
|
+
OutboxContextImpl: () => OutboxContextImpl,
|
|
3071
|
+
createFederation: () => createFederation
|
|
3072
|
+
});
|
|
2899
3073
|
/**
|
|
2900
3074
|
* Create a new {@link Federation} instance.
|
|
2901
3075
|
* @param parameters Parameters for initializing the instance.
|
|
@@ -3059,78 +3233,123 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3059
3233
|
processQueuedTask(contextData, message) {
|
|
3060
3234
|
const tracer = this._getTracer();
|
|
3061
3235
|
const extractedContext = _opentelemetry_api.propagation.extract(_opentelemetry_api.context.active(), message.traceContext);
|
|
3236
|
+
const meter = getFederationMetrics(this.meterProvider);
|
|
3062
3237
|
return (0, _logtape_logtape.withContext)({ messageId: message.id }, async () => {
|
|
3063
|
-
if (message.type === "fanout")
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3238
|
+
if (message.type === "fanout") {
|
|
3239
|
+
const common = {
|
|
3240
|
+
role: "fanout",
|
|
3241
|
+
queue: this.fanoutQueue,
|
|
3242
|
+
activityType: message.activityType
|
|
3243
|
+
};
|
|
3244
|
+
await tracer.startActiveSpan("activitypub.fanout", {
|
|
3245
|
+
kind: _opentelemetry_api.SpanKind.CONSUMER,
|
|
3246
|
+
attributes: { "activitypub.activity.type": message.activityType }
|
|
3247
|
+
}, extractedContext, async (span) => {
|
|
3248
|
+
const spanCtx = span.spanContext();
|
|
3249
|
+
return await (0, _logtape_logtape.withContext)({
|
|
3250
|
+
traceId: spanCtx.traceId,
|
|
3251
|
+
spanId: spanCtx.spanId
|
|
3252
|
+
}, async () => {
|
|
3253
|
+
if (message.activityId != null) span.setAttribute("activitypub.activity.id", message.activityId);
|
|
3254
|
+
meter.recordQueueTaskStarted(common);
|
|
3255
|
+
meter.incrementQueueTaskInFlight(common);
|
|
3256
|
+
const startedAt = performance.now();
|
|
3257
|
+
let outcome = "completed";
|
|
3258
|
+
try {
|
|
3259
|
+
await this.#listenFanoutMessage(contextData, message);
|
|
3260
|
+
} catch (e) {
|
|
3261
|
+
const aborted = isAbortError(e);
|
|
3262
|
+
outcome = aborted ? "aborted" : "failed";
|
|
3263
|
+
if (!aborted) span.setStatus({
|
|
3264
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3265
|
+
message: String(e)
|
|
3266
|
+
});
|
|
3267
|
+
throw e;
|
|
3268
|
+
} finally {
|
|
3269
|
+
meter.recordQueueTaskOutcome(common, outcome, getDurationMs(startedAt));
|
|
3270
|
+
meter.decrementQueueTaskInFlight(common);
|
|
3271
|
+
span.end();
|
|
3272
|
+
}
|
|
3273
|
+
});
|
|
3084
3274
|
});
|
|
3085
|
-
})
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
spanId: spanCtx.spanId
|
|
3097
|
-
}, async () => {
|
|
3098
|
-
if (message.activityId != null) span.setAttribute("activitypub.activity.id", message.activityId);
|
|
3099
|
-
try {
|
|
3100
|
-
await this.#listenOutboxMessage(contextData, message, span);
|
|
3101
|
-
} catch (e) {
|
|
3102
|
-
span.setStatus({
|
|
3103
|
-
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3104
|
-
message: String(e)
|
|
3105
|
-
});
|
|
3106
|
-
throw e;
|
|
3107
|
-
} finally {
|
|
3108
|
-
span.end();
|
|
3275
|
+
} else if (message.type === "outbox") {
|
|
3276
|
+
const common = {
|
|
3277
|
+
role: "outbox",
|
|
3278
|
+
queue: this.outboxQueue,
|
|
3279
|
+
activityType: message.activityType
|
|
3280
|
+
};
|
|
3281
|
+
await tracer.startActiveSpan("activitypub.outbox", {
|
|
3282
|
+
kind: _opentelemetry_api.SpanKind.CONSUMER,
|
|
3283
|
+
attributes: {
|
|
3284
|
+
"activitypub.activity.type": message.activityType,
|
|
3285
|
+
"activitypub.activity.retries": message.attempt
|
|
3109
3286
|
}
|
|
3287
|
+
}, extractedContext, async (span) => {
|
|
3288
|
+
const spanCtx = span.spanContext();
|
|
3289
|
+
return await (0, _logtape_logtape.withContext)({
|
|
3290
|
+
traceId: spanCtx.traceId,
|
|
3291
|
+
spanId: spanCtx.spanId
|
|
3292
|
+
}, async () => {
|
|
3293
|
+
if (message.activityId != null) span.setAttribute("activitypub.activity.id", message.activityId);
|
|
3294
|
+
meter.recordQueueTaskStarted(common);
|
|
3295
|
+
meter.incrementQueueTaskInFlight(common);
|
|
3296
|
+
const startedAt = performance.now();
|
|
3297
|
+
let outcome = "completed";
|
|
3298
|
+
try {
|
|
3299
|
+
await this.#listenOutboxMessage(contextData, message, span);
|
|
3300
|
+
} catch (e) {
|
|
3301
|
+
const aborted = isAbortError(e);
|
|
3302
|
+
outcome = aborted ? "aborted" : "failed";
|
|
3303
|
+
if (!aborted) span.setStatus({
|
|
3304
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3305
|
+
message: String(e)
|
|
3306
|
+
});
|
|
3307
|
+
throw e;
|
|
3308
|
+
} finally {
|
|
3309
|
+
meter.recordQueueTaskOutcome(common, outcome, getDurationMs(startedAt));
|
|
3310
|
+
meter.decrementQueueTaskInFlight(common);
|
|
3311
|
+
span.end();
|
|
3312
|
+
}
|
|
3313
|
+
});
|
|
3110
3314
|
});
|
|
3111
|
-
})
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3315
|
+
} else if (message.type === "inbox") {
|
|
3316
|
+
const common = {
|
|
3317
|
+
role: "inbox",
|
|
3318
|
+
queue: this.inboxQueue
|
|
3319
|
+
};
|
|
3320
|
+
await tracer.startActiveSpan("activitypub.inbox", {
|
|
3321
|
+
kind: _opentelemetry_api.SpanKind.CONSUMER,
|
|
3322
|
+
attributes: { "activitypub.shared_inbox": message.identifier == null }
|
|
3323
|
+
}, extractedContext, async (span) => {
|
|
3324
|
+
const spanCtx = span.spanContext();
|
|
3325
|
+
return await (0, _logtape_logtape.withContext)({
|
|
3326
|
+
traceId: spanCtx.traceId,
|
|
3327
|
+
spanId: spanCtx.spanId
|
|
3328
|
+
}, async () => {
|
|
3329
|
+
meter.recordQueueTaskStarted(common);
|
|
3330
|
+
meter.incrementQueueTaskInFlight(common);
|
|
3331
|
+
const startedAt = performance.now();
|
|
3332
|
+
let outcome = "completed";
|
|
3333
|
+
try {
|
|
3334
|
+
await this.#listenInboxMessage(contextData, message, span, (activityType) => {
|
|
3335
|
+
common.activityType = activityType;
|
|
3336
|
+
});
|
|
3337
|
+
} catch (e) {
|
|
3338
|
+
const aborted = isAbortError(e);
|
|
3339
|
+
outcome = aborted ? "aborted" : "failed";
|
|
3340
|
+
if (!aborted) span.setStatus({
|
|
3341
|
+
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3342
|
+
message: String(e)
|
|
3343
|
+
});
|
|
3344
|
+
throw e;
|
|
3345
|
+
} finally {
|
|
3346
|
+
meter.recordQueueTaskOutcome(common, outcome, getDurationMs(startedAt));
|
|
3347
|
+
meter.decrementQueueTaskInFlight(common);
|
|
3348
|
+
span.end();
|
|
3349
|
+
}
|
|
3350
|
+
});
|
|
3132
3351
|
});
|
|
3133
|
-
}
|
|
3352
|
+
}
|
|
3134
3353
|
});
|
|
3135
3354
|
}
|
|
3136
3355
|
async #listenFanoutMessage(data, message) {
|
|
@@ -3287,10 +3506,19 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3287
3506
|
...logData,
|
|
3288
3507
|
error
|
|
3289
3508
|
});
|
|
3290
|
-
|
|
3509
|
+
const retryMessage = {
|
|
3291
3510
|
...message,
|
|
3292
3511
|
attempt: message.attempt + 1
|
|
3293
|
-
}
|
|
3512
|
+
};
|
|
3513
|
+
const { outboxQueue } = this;
|
|
3514
|
+
if (outboxQueue != null) {
|
|
3515
|
+
await outboxQueue.enqueue(retryMessage, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
3516
|
+
getFederationMetrics(this.meterProvider).recordQueueTaskEnqueued({
|
|
3517
|
+
role: "outbox",
|
|
3518
|
+
queue: outboxQueue,
|
|
3519
|
+
activityType: retryMessage.activityType
|
|
3520
|
+
}, retryMessage.attempt);
|
|
3521
|
+
}
|
|
3294
3522
|
} else logger.error("Failed to send activity {activityId} to {inbox} after {attempt} attempts; giving up:\n{error}", {
|
|
3295
3523
|
...logData,
|
|
3296
3524
|
error
|
|
@@ -3299,7 +3527,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3299
3527
|
}
|
|
3300
3528
|
logger.info("Successfully sent activity {activityId} to {inbox}.", { ...logData });
|
|
3301
3529
|
}
|
|
3302
|
-
async #listenInboxMessage(ctxData, message, span) {
|
|
3530
|
+
async #listenInboxMessage(ctxData, message, span, onActivityType) {
|
|
3303
3531
|
const logger = (0, _logtape_logtape.getLogger)([
|
|
3304
3532
|
"fedify",
|
|
3305
3533
|
"federation",
|
|
@@ -3313,7 +3541,9 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3313
3541
|
if (identity != null) context = this.#createContext(baseUrl, ctxData, { documentLoader: "identifier" in identity || "username" in identity ? await context.getDocumentLoader(identity) : context.getDocumentLoader(identity) });
|
|
3314
3542
|
}
|
|
3315
3543
|
const activity = await _fedify_vocab.Activity.fromJsonLd(message.activity, context);
|
|
3316
|
-
|
|
3544
|
+
const activityType = (0, _fedify_vocab.getTypeId)(activity).href;
|
|
3545
|
+
span.setAttribute("activitypub.activity.type", activityType);
|
|
3546
|
+
onActivityType?.(activityType);
|
|
3317
3547
|
if (activity.id != null) span.setAttribute("activitypub.activity.id", activity.id.href);
|
|
3318
3548
|
const cacheKey = activity.id == null ? null : [
|
|
3319
3549
|
...this.kvPrefixes.activityIdempotence,
|
|
@@ -3341,7 +3571,7 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3341
3571
|
});
|
|
3342
3572
|
span.setStatus({
|
|
3343
3573
|
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3344
|
-
message: `Unsupported activity type: ${
|
|
3574
|
+
message: `Unsupported activity type: ${activityType}`
|
|
3345
3575
|
});
|
|
3346
3576
|
span.end();
|
|
3347
3577
|
return;
|
|
@@ -3349,7 +3579,6 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3349
3579
|
const { class: cls, listener } = dispatched;
|
|
3350
3580
|
span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
|
|
3351
3581
|
try {
|
|
3352
|
-
const activityType = (0, _fedify_vocab.getTypeId)(activity).href;
|
|
3353
3582
|
const started = performance.now();
|
|
3354
3583
|
try {
|
|
3355
3584
|
await listener(context.toInboxContext(message.identifier, message.activity, activity.id?.href, activityType), activity);
|
|
@@ -3394,10 +3623,19 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3394
3623
|
activity: message.activity,
|
|
3395
3624
|
recipient: message.identifier
|
|
3396
3625
|
});
|
|
3397
|
-
|
|
3626
|
+
const retryMessage = {
|
|
3398
3627
|
...message,
|
|
3399
3628
|
attempt: message.attempt + 1
|
|
3400
|
-
}
|
|
3629
|
+
};
|
|
3630
|
+
const { inboxQueue } = this;
|
|
3631
|
+
if (inboxQueue != null) {
|
|
3632
|
+
await inboxQueue.enqueue(retryMessage, { delay: Temporal.Duration.compare(delay, { seconds: 0 }) < 0 ? Temporal.Duration.from({ seconds: 0 }) : delay });
|
|
3633
|
+
getFederationMetrics(this.meterProvider).recordQueueTaskEnqueued({
|
|
3634
|
+
role: "inbox",
|
|
3635
|
+
queue: inboxQueue,
|
|
3636
|
+
activityType
|
|
3637
|
+
}, retryMessage.attempt);
|
|
3638
|
+
}
|
|
3401
3639
|
} else logger.error("Failed to process the incoming activity {activityId} after {trial} attempts; giving up:\n{error}", {
|
|
3402
3640
|
error,
|
|
3403
3641
|
activityId: activity.id?.href,
|
|
@@ -3586,9 +3824,11 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3586
3824
|
});
|
|
3587
3825
|
}
|
|
3588
3826
|
const { outboxQueue } = this;
|
|
3589
|
-
if (outboxQueue.enqueueMany == null) {
|
|
3590
|
-
const
|
|
3591
|
-
|
|
3827
|
+
if (outboxQueue.enqueueMany == null || orderingKey != null) {
|
|
3828
|
+
const errors = (await Promise.allSettled(messages.map(async (m) => {
|
|
3829
|
+
await outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey });
|
|
3830
|
+
recordOutboxEnqueue(this.meterProvider, outboxQueue, m.message);
|
|
3831
|
+
}))).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
3592
3832
|
if (errors.length > 0) {
|
|
3593
3833
|
logger.error("Failed to enqueue activity {activityId} to send later: {errors}", {
|
|
3594
3834
|
activityId: activity.id.href,
|
|
@@ -3597,25 +3837,17 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3597
3837
|
if (errors.length > 1) throw new AggregateError(errors, `Failed to enqueue activity ${activityId} to send later.`);
|
|
3598
3838
|
throw errors[0];
|
|
3599
3839
|
}
|
|
3600
|
-
} else
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
logger.error("Failed to enqueue activity {activityId} to send later: {
|
|
3840
|
+
} else {
|
|
3841
|
+
try {
|
|
3842
|
+
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
3843
|
+
} catch (error) {
|
|
3844
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {error}", {
|
|
3605
3845
|
activityId: activity.id.href,
|
|
3606
|
-
|
|
3846
|
+
error
|
|
3607
3847
|
});
|
|
3608
|
-
|
|
3609
|
-
throw errors[0];
|
|
3848
|
+
throw error;
|
|
3610
3849
|
}
|
|
3611
|
-
|
|
3612
|
-
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
3613
|
-
} catch (error) {
|
|
3614
|
-
logger.error("Failed to enqueue activity {activityId} to send later: {error}", {
|
|
3615
|
-
activityId: activity.id.href,
|
|
3616
|
-
error
|
|
3617
|
-
});
|
|
3618
|
-
throw error;
|
|
3850
|
+
for (const m of messages) recordOutboxEnqueue(this.meterProvider, outboxQueue, m.message);
|
|
3619
3851
|
}
|
|
3620
3852
|
}
|
|
3621
3853
|
fetch(request, options) {
|
|
@@ -4431,6 +4663,11 @@ var ContextImpl = class ContextImpl {
|
|
|
4431
4663
|
};
|
|
4432
4664
|
if (!this.federation.manuallyStartQueue) this.federation._startQueueInternal(this.data);
|
|
4433
4665
|
await this.federation.fanoutQueue.enqueue(message, { orderingKey: options.orderingKey });
|
|
4666
|
+
getFederationMetrics(this.federation.meterProvider).recordQueueTaskEnqueued({
|
|
4667
|
+
role: "fanout",
|
|
4668
|
+
queue: this.federation.fanoutQueue,
|
|
4669
|
+
activityType: message.activityType
|
|
4670
|
+
}, 0);
|
|
4434
4671
|
return true;
|
|
4435
4672
|
}
|
|
4436
4673
|
async *getFollowers(identifier) {
|
|
@@ -4561,6 +4798,7 @@ var ContextImpl = class ContextImpl {
|
|
|
4561
4798
|
kvPrefixes: this.federation.kvPrefixes,
|
|
4562
4799
|
queue: this.federation.inboxQueue,
|
|
4563
4800
|
span,
|
|
4801
|
+
meterProvider: this.federation.meterProvider,
|
|
4564
4802
|
tracerProvider: options.tracerProvider ?? this.tracerProvider,
|
|
4565
4803
|
idempotencyStrategy: this.federation.idempotencyStrategy
|
|
4566
4804
|
});
|
|
@@ -4810,8 +5048,10 @@ async function forwardActivityInternal(ctx, loggerCategory, forwarder, recipient
|
|
|
4810
5048
|
}
|
|
4811
5049
|
const { outboxQueue } = ctx.federation;
|
|
4812
5050
|
if (outboxQueue.enqueueMany == null || orderingKey != null) {
|
|
4813
|
-
const
|
|
4814
|
-
|
|
5051
|
+
const errors = (await Promise.allSettled(messages.map(async (m) => {
|
|
5052
|
+
await outboxQueue.enqueue(m.message, { orderingKey: m.orderingKey });
|
|
5053
|
+
recordOutboxEnqueue(ctx.federation.meterProvider, outboxQueue, m.message);
|
|
5054
|
+
}))).filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
4815
5055
|
if (errors.length > 0) {
|
|
4816
5056
|
logger.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", {
|
|
4817
5057
|
activityId: ctx.activityId,
|
|
@@ -4820,14 +5060,17 @@ async function forwardActivityInternal(ctx, loggerCategory, forwarder, recipient
|
|
|
4820
5060
|
if (errors.length > 1) throw new AggregateError(errors, `Failed to enqueue activity ${ctx.activityId} to forward later.`);
|
|
4821
5061
|
throw errors[0];
|
|
4822
5062
|
}
|
|
4823
|
-
} else
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
activityId
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
5063
|
+
} else {
|
|
5064
|
+
try {
|
|
5065
|
+
await outboxQueue.enqueueMany(messages.map((m) => m.message));
|
|
5066
|
+
} catch (error) {
|
|
5067
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{error}", {
|
|
5068
|
+
activityId: ctx.activityId,
|
|
5069
|
+
error
|
|
5070
|
+
});
|
|
5071
|
+
throw error;
|
|
5072
|
+
}
|
|
5073
|
+
for (const m of messages) recordOutboxEnqueue(ctx.federation.meterProvider, outboxQueue, m.message);
|
|
4831
5074
|
}
|
|
4832
5075
|
return true;
|
|
4833
5076
|
}
|
|
@@ -4965,36 +5208,6 @@ function getRequestId(request) {
|
|
|
4965
5208
|
return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
4966
5209
|
}
|
|
4967
5210
|
//#endregion
|
|
4968
|
-
Object.defineProperty(exports, "ContextImpl", {
|
|
4969
|
-
enumerable: true,
|
|
4970
|
-
get: function() {
|
|
4971
|
-
return ContextImpl;
|
|
4972
|
-
}
|
|
4973
|
-
});
|
|
4974
|
-
Object.defineProperty(exports, "FederationImpl", {
|
|
4975
|
-
enumerable: true,
|
|
4976
|
-
get: function() {
|
|
4977
|
-
return FederationImpl;
|
|
4978
|
-
}
|
|
4979
|
-
});
|
|
4980
|
-
Object.defineProperty(exports, "InboxContextImpl", {
|
|
4981
|
-
enumerable: true,
|
|
4982
|
-
get: function() {
|
|
4983
|
-
return InboxContextImpl;
|
|
4984
|
-
}
|
|
4985
|
-
});
|
|
4986
|
-
Object.defineProperty(exports, "KvSpecDeterminer", {
|
|
4987
|
-
enumerable: true,
|
|
4988
|
-
get: function() {
|
|
4989
|
-
return KvSpecDeterminer;
|
|
4990
|
-
}
|
|
4991
|
-
});
|
|
4992
|
-
Object.defineProperty(exports, "OutboxContextImpl", {
|
|
4993
|
-
enumerable: true,
|
|
4994
|
-
get: function() {
|
|
4995
|
-
return OutboxContextImpl;
|
|
4996
|
-
}
|
|
4997
|
-
});
|
|
4998
5211
|
Object.defineProperty(exports, "Router", {
|
|
4999
5212
|
enumerable: true,
|
|
5000
5213
|
get: function() {
|
|
@@ -5049,6 +5262,12 @@ Object.defineProperty(exports, "handleWebFinger", {
|
|
|
5049
5262
|
return handleWebFinger;
|
|
5050
5263
|
}
|
|
5051
5264
|
});
|
|
5265
|
+
Object.defineProperty(exports, "middleware_exports", {
|
|
5266
|
+
enumerable: true,
|
|
5267
|
+
get: function() {
|
|
5268
|
+
return middleware_exports;
|
|
5269
|
+
}
|
|
5270
|
+
});
|
|
5052
5271
|
Object.defineProperty(exports, "respondWithObject", {
|
|
5053
5272
|
enumerable: true,
|
|
5054
5273
|
get: function() {
|