@fedify/fedify 1.5.0-dev.731 → 1.5.0-dev.732
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/CHANGES.md +3 -0
- package/esm/deno.js +1 -1
- package/esm/federation/middleware.js +50 -24
- package/esm/federation/mq.js +31 -0
- package/esm/vocab/vocab.js +176 -176
- package/package.json +1 -1
- package/types/federation/middleware.d.ts.map +1 -1
- package/types/federation/mq.d.ts +11 -0
- package/types/federation/mq.d.ts.map +1 -1
package/CHANGES.md
CHANGED
@@ -64,6 +64,9 @@ To be released.
|
|
64
64
|
- Deprecated the fourth parameter of the `ObjectAuthorizePredicate` type
|
65
65
|
in favor of the `RequestContext.getSignedKeyOwner()` method.
|
66
66
|
|
67
|
+
- Added an optional method `enqueueMany()` to `MessageQueue` interface
|
68
|
+
for sending multiple activities at once.
|
69
|
+
|
67
70
|
- Fixed a bug of the `fedify inbox` command where it had failed to render
|
68
71
|
the web interface when the `fedify` command was installed using
|
69
72
|
`deno install` command from JSR.
|
package/esm/deno.js
CHANGED
@@ -1289,7 +1289,7 @@ export class FederationImpl {
|
|
1289
1289
|
this._startQueueInternal(ctx.data);
|
1290
1290
|
const carrier = {};
|
1291
1291
|
propagation.inject(context.active(), carrier);
|
1292
|
-
const
|
1292
|
+
const messages = [];
|
1293
1293
|
for (const inbox in inboxes) {
|
1294
1294
|
const message = {
|
1295
1295
|
type: "outbox",
|
@@ -1308,18 +1308,31 @@ export class FederationImpl {
|
|
1308
1308
|
},
|
1309
1309
|
traceContext: carrier,
|
1310
1310
|
};
|
1311
|
-
|
1311
|
+
messages.push(message);
|
1312
|
+
}
|
1313
|
+
const { outboxQueue } = this;
|
1314
|
+
if (outboxQueue.enqueueMany == null) {
|
1315
|
+
const promises = messages.map((m) => outboxQueue.enqueue(m));
|
1316
|
+
const results = await Promise.allSettled(promises);
|
1317
|
+
const errors = results
|
1318
|
+
.filter((r) => r.status === "rejected")
|
1319
|
+
.map((r) => r.reason);
|
1320
|
+
if (errors.length > 0) {
|
1321
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {errors}", { activityId: activity.id.href, errors });
|
1322
|
+
if (errors.length > 1) {
|
1323
|
+
throw new AggregateError(errors, `Failed to enqueue activity ${activityId} to send later.`);
|
1324
|
+
}
|
1325
|
+
throw errors[0];
|
1326
|
+
}
|
1312
1327
|
}
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
throw new AggregateError(errors, `Failed to enqueue activity ${activityId} to send later.`);
|
1328
|
+
else {
|
1329
|
+
try {
|
1330
|
+
await outboxQueue.enqueueMany(messages);
|
1331
|
+
}
|
1332
|
+
catch (error) {
|
1333
|
+
logger.error("Failed to enqueue activity {activityId} to send later: {error}", { activityId: activity.id.href, error });
|
1334
|
+
throw error;
|
1321
1335
|
}
|
1322
|
-
throw errors[0];
|
1323
1336
|
}
|
1324
1337
|
}
|
1325
1338
|
fetch(request, options) {
|
@@ -2516,7 +2529,7 @@ export class InboxContextImpl extends ContextImpl {
|
|
2516
2529
|
}
|
2517
2530
|
const carrier = {};
|
2518
2531
|
propagation.inject(context.active(), carrier);
|
2519
|
-
const
|
2532
|
+
const messages = [];
|
2520
2533
|
for (const inbox in inboxes) {
|
2521
2534
|
const message = {
|
2522
2535
|
type: "outbox",
|
@@ -2533,18 +2546,31 @@ export class InboxContextImpl extends ContextImpl {
|
|
2533
2546
|
headers: {},
|
2534
2547
|
traceContext: carrier,
|
2535
2548
|
};
|
2536
|
-
|
2537
|
-
}
|
2538
|
-
const
|
2539
|
-
|
2540
|
-
.
|
2541
|
-
|
2542
|
-
|
2543
|
-
|
2544
|
-
|
2545
|
-
|
2546
|
-
|
2547
|
-
|
2549
|
+
messages.push(message);
|
2550
|
+
}
|
2551
|
+
const { outboxQueue } = this.federation;
|
2552
|
+
if (outboxQueue.enqueueMany == null) {
|
2553
|
+
const promises = messages.map((m) => outboxQueue.enqueue(m));
|
2554
|
+
const results = await Promise.allSettled(promises);
|
2555
|
+
const errors = results
|
2556
|
+
.filter((r) => r.status === "rejected")
|
2557
|
+
.map((r) => r.reason);
|
2558
|
+
if (errors.length > 0) {
|
2559
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{errors}", { activityId: this.activityId, errors });
|
2560
|
+
if (errors.length > 1) {
|
2561
|
+
throw new AggregateError(errors, `Failed to enqueue activity ${this.activityId} to forward later.`);
|
2562
|
+
}
|
2563
|
+
throw errors[0];
|
2564
|
+
}
|
2565
|
+
}
|
2566
|
+
else {
|
2567
|
+
try {
|
2568
|
+
await outboxQueue.enqueueMany(messages);
|
2569
|
+
}
|
2570
|
+
catch (error) {
|
2571
|
+
logger.error("Failed to enqueue activity {activityId} to forward later:\n{error}", { activityId: this.activityId, error });
|
2572
|
+
throw error;
|
2573
|
+
}
|
2548
2574
|
}
|
2549
2575
|
}
|
2550
2576
|
}
|
package/esm/federation/mq.js
CHANGED
@@ -39,6 +39,22 @@ export class InProcessMessageQueue {
|
|
39
39
|
}
|
40
40
|
return Promise.resolve();
|
41
41
|
}
|
42
|
+
enqueueMany(messages, options) {
|
43
|
+
if (messages.length === 0)
|
44
|
+
return Promise.resolve();
|
45
|
+
const delay = options?.delay == null
|
46
|
+
? 0
|
47
|
+
: Math.max(options.delay.total("millisecond"), 0);
|
48
|
+
if (delay > 0) {
|
49
|
+
setTimeout(() => this.enqueueMany(messages, { ...options, delay: undefined }), delay);
|
50
|
+
return Promise.resolve();
|
51
|
+
}
|
52
|
+
this.#messages.push(...messages);
|
53
|
+
for (const monitorId in this.#monitors) {
|
54
|
+
this.#monitors[monitorId]();
|
55
|
+
}
|
56
|
+
return Promise.resolve();
|
57
|
+
}
|
42
58
|
async listen(handler, options = {}) {
|
43
59
|
const signal = options.signal;
|
44
60
|
while (signal == null || !signal.aborted) {
|
@@ -107,6 +123,21 @@ export class ParallelMessageQueue {
|
|
107
123
|
enqueue(message, options) {
|
108
124
|
return this.queue.enqueue(message, options);
|
109
125
|
}
|
126
|
+
async enqueueMany(messages, options) {
|
127
|
+
if (this.queue.enqueueMany == null) {
|
128
|
+
const results = await Promise.allSettled(messages.map((message) => this.queue.enqueue(message, options)));
|
129
|
+
const errors = results
|
130
|
+
.filter((r) => r.status === "rejected")
|
131
|
+
.map((r) => r.reason);
|
132
|
+
if (errors.length > 1) {
|
133
|
+
throw new AggregateError(errors, "Failed to enqueue messages.");
|
134
|
+
}
|
135
|
+
else if (errors.length === 1)
|
136
|
+
throw errors[0];
|
137
|
+
return;
|
138
|
+
}
|
139
|
+
await this.queue.enqueueMany(messages, options);
|
140
|
+
}
|
110
141
|
listen(handler, options = {}) {
|
111
142
|
const workers = new Map();
|
112
143
|
return this.queue.listen(async (message) => {
|