@agentunion/fastaun-browser 0.5.9 → 0.5.11
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/CHANGELOG.md +64 -0
- package/_packed_docs/CHANGELOG.md +64 -0
- package/_packed_docs/INDEX.md +3 -3
- package/_packed_docs/KITE_DOCS_GUIDE.md +1 -1
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +6 -5
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +102 -8
- package/_packed_docs/sdk/09-group-rpc-manual.md +18 -3
- package/_packed_docs/sdk/09-message-rpc-manual.md +34 -10
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +3 -2
- package/_packed_docs/sdk/INDEX.md +2 -1
- package/dist/agent-md.d.ts.map +1 -1
- package/dist/agent-md.js +23 -1
- package/dist/agent-md.js.map +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +16 -2
- package/dist/auth.js.map +1 -1
- package/dist/bundle.js +1374 -267
- package/dist/client/delivery.d.ts +34 -11
- package/dist/client/delivery.d.ts.map +1 -1
- package/dist/client/delivery.js +390 -100
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.js +6 -6
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.d.ts.map +1 -1
- package/dist/client/lifecycle.js +34 -38
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +4 -0
- package/dist/client/rpc-pipeline.d.ts.map +1 -1
- package/dist/client/rpc-pipeline.js +70 -4
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +4 -1
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +169 -38
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +83 -33
- package/dist/client.js.map +1 -1
- package/dist/events.d.ts +31 -2
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +167 -7
- package/dist/events.js.map +1 -1
- package/dist/register-flow.d.ts.map +1 -1
- package/dist/register-flow.js +16 -2
- package/dist/register-flow.js.map +1 -1
- package/dist/transport.d.ts +10 -1
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +427 -29
- package/dist/transport.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
package/dist/client/delivery.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { slotIsolationKey } from '../config.js';
|
|
2
|
+
import { normalizeGroupAid } from '../group-id.js';
|
|
2
3
|
import { ConnectionState, isJsonObject } from '../types.js';
|
|
3
4
|
import { hasGroupMentionModeField, normalizeGroupMentionMode } from './mention-mode.js';
|
|
4
5
|
const PUSHED_SEQS_LIMIT = 50_000;
|
|
@@ -62,6 +63,26 @@ function nonNegativeSafeSequenceHint(value) {
|
|
|
62
63
|
return null;
|
|
63
64
|
return value;
|
|
64
65
|
}
|
|
66
|
+
function canonicalDeliverySource(source) {
|
|
67
|
+
switch (String(source ?? '').trim()) {
|
|
68
|
+
case 'group-push':
|
|
69
|
+
case 'ordered':
|
|
70
|
+
case 'legacy':
|
|
71
|
+
return 'push';
|
|
72
|
+
case 'tail':
|
|
73
|
+
case 'pull-drained':
|
|
74
|
+
case 'pull_drained':
|
|
75
|
+
return 'pull';
|
|
76
|
+
case 'inline-push':
|
|
77
|
+
return 'inline_push';
|
|
78
|
+
case 'pending-retry':
|
|
79
|
+
return 'pending_retry';
|
|
80
|
+
case '':
|
|
81
|
+
return 'direct';
|
|
82
|
+
default:
|
|
83
|
+
return String(source).trim();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
65
86
|
function deduplicatePlainForwardPageMessages(value, afterSeq) {
|
|
66
87
|
if (!Array.isArray(value))
|
|
67
88
|
return [];
|
|
@@ -94,6 +115,11 @@ function p2pAppEventFromPlainPullMessage(message) {
|
|
|
94
115
|
}
|
|
95
116
|
export class MessageDeliveryEngine {
|
|
96
117
|
runtime;
|
|
118
|
+
syncRun = 0;
|
|
119
|
+
syncingNamespaces = new Set();
|
|
120
|
+
syncSessions = new Map();
|
|
121
|
+
pendingPullDeliveryChanges = null;
|
|
122
|
+
deliveryGeneration = 0;
|
|
97
123
|
realtimeTailResults = null;
|
|
98
124
|
realtimeSyncing = null;
|
|
99
125
|
pendingP2pPullUpper = null;
|
|
@@ -113,7 +139,10 @@ export class MessageDeliveryEngine {
|
|
|
113
139
|
this.runtime = runtime;
|
|
114
140
|
}
|
|
115
141
|
resetInlineAckState() {
|
|
142
|
+
this.syncStopped('aborted');
|
|
116
143
|
this.inlineGeneration += 1;
|
|
144
|
+
this.deliveryGeneration += 1;
|
|
145
|
+
this.pendingPullDeliveryChanges = null;
|
|
117
146
|
void this.runtime.client._rpcPipeline?.invalidatePulls?.();
|
|
118
147
|
this.realtimeSyncing = null;
|
|
119
148
|
this.pendingP2pPullUpper = null;
|
|
@@ -126,6 +155,8 @@ export class MessageDeliveryEngine {
|
|
|
126
155
|
this.pendingP2PInlineAcks = null;
|
|
127
156
|
this.pendingGroupInlineAcks = null;
|
|
128
157
|
this.pendingGroupInlineAckNamespaces = null;
|
|
158
|
+
this.syncingNamespaces.clear();
|
|
159
|
+
this.syncSessions.clear();
|
|
129
160
|
}
|
|
130
161
|
isInlineGenerationCurrent(generation) {
|
|
131
162
|
return generation === this.inlineGeneration;
|
|
@@ -158,6 +189,95 @@ export class MessageDeliveryEngine {
|
|
|
158
189
|
endRealtimeSync(ns) {
|
|
159
190
|
this.realtimeSyncing?.delete(ns);
|
|
160
191
|
}
|
|
192
|
+
onPullStarted(ns) {
|
|
193
|
+
if (!ns || this.syncingNamespaces.has(ns))
|
|
194
|
+
return;
|
|
195
|
+
if (this.syncingNamespaces.size === 0) {
|
|
196
|
+
this.syncRun += 1;
|
|
197
|
+
this.syncSessions.clear();
|
|
198
|
+
this.runtime.client._dispatcher?.enqueue?.('sync.started', {
|
|
199
|
+
run_id: this.syncRun,
|
|
200
|
+
source: 'pull',
|
|
201
|
+
syncing: true,
|
|
202
|
+
namespaces_pending: 1,
|
|
203
|
+
received_total: 0,
|
|
204
|
+
namespace: ns,
|
|
205
|
+
started_at: Date.now(),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
this.syncingNamespaces.add(ns);
|
|
209
|
+
this.syncSessions.set(ns, { pages: 0, raw: 0, pulled: 0 });
|
|
210
|
+
}
|
|
211
|
+
onPullPage(ns, pulledCount, hasMore, maxSeen, remaining, rawCount = pulledCount, currentSeq, targetSeq) {
|
|
212
|
+
this.onPullStarted(ns);
|
|
213
|
+
if (!ns)
|
|
214
|
+
return;
|
|
215
|
+
const session = this.syncSessions.get(ns) ?? { pages: 0, raw: 0, pulled: 0 };
|
|
216
|
+
session.pages += 1;
|
|
217
|
+
session.raw += Math.max(0, rawCount);
|
|
218
|
+
session.pulled += Math.max(0, pulledCount);
|
|
219
|
+
this.syncSessions.set(ns, session);
|
|
220
|
+
const received = session.pulled;
|
|
221
|
+
const progress = {
|
|
222
|
+
run_id: this.syncRun,
|
|
223
|
+
source: 'pull',
|
|
224
|
+
namespace: ns,
|
|
225
|
+
page: session.pages,
|
|
226
|
+
page_raw_count: Math.max(0, rawCount),
|
|
227
|
+
page_pulled_count: Math.max(0, pulledCount),
|
|
228
|
+
pulled_count: received,
|
|
229
|
+
received_total: received,
|
|
230
|
+
batch_size: Math.max(0, pulledCount),
|
|
231
|
+
estimated_remaining: hasMore ? undefined : 0,
|
|
232
|
+
max_seen: maxSeen,
|
|
233
|
+
has_more: hasMore,
|
|
234
|
+
};
|
|
235
|
+
if (typeof currentSeq === 'number' && Number.isSafeInteger(currentSeq) && currentSeq >= 0) {
|
|
236
|
+
progress.current_seq = currentSeq;
|
|
237
|
+
}
|
|
238
|
+
if (typeof targetSeq === 'number' && Number.isSafeInteger(targetSeq) && targetSeq >= 0) {
|
|
239
|
+
progress.target_seq = targetSeq;
|
|
240
|
+
}
|
|
241
|
+
if (typeof remaining === 'number' && Number.isSafeInteger(remaining) && remaining >= 0) {
|
|
242
|
+
progress.remaining = remaining;
|
|
243
|
+
progress.estimated_remaining = progress.remaining;
|
|
244
|
+
}
|
|
245
|
+
this.runtime.client._dispatcher?.enqueue?.('sync.progress', progress);
|
|
246
|
+
}
|
|
247
|
+
onPullAborted() {
|
|
248
|
+
this.syncStopped('aborted');
|
|
249
|
+
}
|
|
250
|
+
syncStopped(reason = 'pull_drained') {
|
|
251
|
+
if (this.syncingNamespaces.size === 0)
|
|
252
|
+
return;
|
|
253
|
+
const sessions = [...this.syncSessions.entries()];
|
|
254
|
+
const receivedTotal = sessions.reduce((total, [, session]) => total + session.pulled, 0);
|
|
255
|
+
this.syncingNamespaces.clear();
|
|
256
|
+
this.syncSessions.clear();
|
|
257
|
+
const payload = {
|
|
258
|
+
run_id: this.syncRun,
|
|
259
|
+
source: 'pull',
|
|
260
|
+
syncing: false,
|
|
261
|
+
namespaces_pending: 0,
|
|
262
|
+
received_total: receivedTotal,
|
|
263
|
+
reason,
|
|
264
|
+
stopped_at: Date.now(),
|
|
265
|
+
};
|
|
266
|
+
if (sessions.length === 1) {
|
|
267
|
+
const [namespace, session] = sessions[0];
|
|
268
|
+
payload.namespace = namespace;
|
|
269
|
+
payload.pages = session.pages;
|
|
270
|
+
payload.pulled_count = session.pulled;
|
|
271
|
+
}
|
|
272
|
+
else if (sessions.length > 1) {
|
|
273
|
+
payload.namespaces = sessions.map(([namespace]) => namespace);
|
|
274
|
+
payload.pages = sessions.reduce((total, [, session]) => total + session.pages, 0);
|
|
275
|
+
payload.pulled_count = receivedTotal;
|
|
276
|
+
}
|
|
277
|
+
this.runtime.client._dispatcher?.enqueue?.('sync.stopped', {
|
|
278
|
+
...payload,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
161
281
|
hasPendingPull(ns) {
|
|
162
282
|
const pending = ns.startsWith('p2p:') ? this.pendingP2pPullUpper : this.pendingGroupPullUpper;
|
|
163
283
|
return (pending?.get(ns) ?? 0) > 0;
|
|
@@ -167,6 +287,93 @@ export class MessageDeliveryEngine {
|
|
|
167
287
|
return;
|
|
168
288
|
this.schedulePendingPullIfNeeded(ns, 'pull-gate-idle');
|
|
169
289
|
}
|
|
290
|
+
onPullWorkSettled() {
|
|
291
|
+
const pipeline = this.runtime.client._rpcPipeline;
|
|
292
|
+
if (pipeline?.hasAnyPullActivity?.() === true)
|
|
293
|
+
return;
|
|
294
|
+
void this.flushPullDeliveryChanges().finally(() => this.syncStopped('pull_drained'));
|
|
295
|
+
}
|
|
296
|
+
deliveryChangeNamespace(event, payload, ns = '') {
|
|
297
|
+
if (event === 'message.received')
|
|
298
|
+
return 'p2p';
|
|
299
|
+
if (event !== 'group.message_created')
|
|
300
|
+
return '';
|
|
301
|
+
if (!isJsonObject(payload))
|
|
302
|
+
return '';
|
|
303
|
+
const aid = String(this.runtime.client._aid ?? '').trim().toLowerCase();
|
|
304
|
+
const dot = aid.indexOf('.');
|
|
305
|
+
const localIssuer = dot > 0 ? aid.slice(dot + 1) : '';
|
|
306
|
+
const fallback = ns.startsWith('group:') ? ns.slice('group:'.length) : '';
|
|
307
|
+
const groupAid = normalizeGroupAid(payload.group_aid ?? payload.group_id ?? fallback, { localIssuer });
|
|
308
|
+
return groupAid.includes('.') ? `group:${groupAid}` : '';
|
|
309
|
+
}
|
|
310
|
+
isDeliverableMessageBody(event, payload) {
|
|
311
|
+
if ((event !== 'message.received' && event !== 'group.message_created') || !isJsonObject(payload))
|
|
312
|
+
return false;
|
|
313
|
+
const messageId = typeof payload.message_id === 'string' && payload.message_id.trim().length > 0;
|
|
314
|
+
const seq = typeof payload.seq === 'number' && Number.isSafeInteger(payload.seq) && payload.seq > 0;
|
|
315
|
+
return messageId || seq;
|
|
316
|
+
}
|
|
317
|
+
recordDeliveryChange(changes, event, payload, ns, generation) {
|
|
318
|
+
if (generation !== this.deliveryGeneration || !this.isDeliverableMessageBody(event, payload))
|
|
319
|
+
return;
|
|
320
|
+
const namespace = this.deliveryChangeNamespace(event, payload, ns);
|
|
321
|
+
if (!namespace)
|
|
322
|
+
return;
|
|
323
|
+
changes.set(namespace, (changes.get(namespace) ?? 0) + 1);
|
|
324
|
+
}
|
|
325
|
+
deliveryChangesPayload(changes) {
|
|
326
|
+
return [...changes.entries()]
|
|
327
|
+
.filter(([, deliveredCount]) => deliveredCount > 0)
|
|
328
|
+
.sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)
|
|
329
|
+
.map(([namespace, deliveredCount]) => ({ namespace, delivered_count: deliveredCount }));
|
|
330
|
+
}
|
|
331
|
+
createDeliveryChangeBatch(trigger) {
|
|
332
|
+
return { generation: this.deliveryGeneration, trigger, changes: new Map(), closed: false };
|
|
333
|
+
}
|
|
334
|
+
async flushRealtimeDeliveryChanges(batch) {
|
|
335
|
+
if (batch.closed)
|
|
336
|
+
return;
|
|
337
|
+
batch.closed = true;
|
|
338
|
+
if (batch.generation !== this.deliveryGeneration)
|
|
339
|
+
return;
|
|
340
|
+
if (this.deliveryChangesPayload(batch.changes).length === 0)
|
|
341
|
+
return;
|
|
342
|
+
const pendingPull = this.pendingPullDeliveryChanges;
|
|
343
|
+
this.pendingPullDeliveryChanges = null;
|
|
344
|
+
if (pendingPull) {
|
|
345
|
+
for (const [namespace, count] of pendingPull) {
|
|
346
|
+
batch.changes.set(namespace, (batch.changes.get(namespace) ?? 0) + count);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (batch.generation !== this.deliveryGeneration)
|
|
350
|
+
return;
|
|
351
|
+
const changes = this.deliveryChangesPayload(batch.changes);
|
|
352
|
+
if (changes.length === 0)
|
|
353
|
+
return;
|
|
354
|
+
this.runtime.client._dispatcher.enqueue('delivery.changed', {
|
|
355
|
+
trigger: batch.trigger,
|
|
356
|
+
source: batch.trigger,
|
|
357
|
+
changes,
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
async flushPullDeliveryChanges() {
|
|
361
|
+
const generation = this.deliveryGeneration;
|
|
362
|
+
const pending = this.pendingPullDeliveryChanges;
|
|
363
|
+
if (!pending || pending.size === 0 || generation !== this.deliveryGeneration)
|
|
364
|
+
return;
|
|
365
|
+
this.pendingPullDeliveryChanges = null;
|
|
366
|
+
if (generation !== this.deliveryGeneration)
|
|
367
|
+
return;
|
|
368
|
+
const changes = this.deliveryChangesPayload(pending);
|
|
369
|
+
if (changes.length === 0)
|
|
370
|
+
return;
|
|
371
|
+
this.runtime.client._dispatcher.enqueue('delivery.changed', {
|
|
372
|
+
trigger: 'pull_drained',
|
|
373
|
+
source: 'pull',
|
|
374
|
+
changes,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
170
377
|
recordPendingPull(ns, seq) {
|
|
171
378
|
if (!ns || !Number.isSafeInteger(seq) || seq <= 0)
|
|
172
379
|
return;
|
|
@@ -768,7 +975,7 @@ export class MessageDeliveryEngine {
|
|
|
768
975
|
}
|
|
769
976
|
const message = normalizeGroupMentionMode(rawMessage);
|
|
770
977
|
if (this.recallEventFromGroupMessage(message)) {
|
|
771
|
-
if (await this.publishGroupRecallTombstone(groupId, seq, message)) {
|
|
978
|
+
if (await this.publishGroupRecallTombstone(groupId, seq, message, 'pull')) {
|
|
772
979
|
this.ensurePullOperationCurrent();
|
|
773
980
|
this.markPublishedSeq(ns, seq);
|
|
774
981
|
publishedCount += 1;
|
|
@@ -835,16 +1042,19 @@ export class MessageDeliveryEngine {
|
|
|
835
1042
|
this.ensurePullOperationCurrent();
|
|
836
1043
|
await this.confirmPlainForwardAck(ns, ackMethod, pendingAckSeq, groupId);
|
|
837
1044
|
}
|
|
1045
|
+
const remaining = typeof response.remaining === 'number' && Number.isSafeInteger(response.remaining) && response.remaining >= 0
|
|
1046
|
+
? response.remaining : null;
|
|
1047
|
+
this.onPullPage(ns, publishedCount, response.has_more === true, messages.length > 0 ? Number(messages[messages.length - 1].seq ?? 0) : undefined, remaining, messages.length, client._seqTracker.getContiguousSeq(ns), messages.length > 0 ? Number(messages[messages.length - 1].seq ?? 0) : undefined);
|
|
838
1048
|
return { rawCount: messages.length, publishedCount };
|
|
839
1049
|
}
|
|
840
|
-
enqueueOrderedMessage(ns, event, seq, payload) {
|
|
1050
|
+
enqueueOrderedMessage(ns, event, seq, payload, source = 'push') {
|
|
841
1051
|
const client = this.runtime.client;
|
|
842
1052
|
let queue = client._pendingOrderedMsgs.get(ns);
|
|
843
1053
|
if (!queue) {
|
|
844
1054
|
queue = new Map();
|
|
845
1055
|
client._pendingOrderedMsgs.set(ns, queue);
|
|
846
1056
|
}
|
|
847
|
-
queue.set(seq, { event, payload });
|
|
1057
|
+
queue.set(seq, { event, payload, source });
|
|
848
1058
|
if (queue.size > PENDING_ORDERED_LIMIT) {
|
|
849
1059
|
const drop = [...queue.keys()].sort((a, b) => a - b).slice(0, queue.size - PENDING_ORDERED_LIMIT);
|
|
850
1060
|
for (const oldSeq of drop)
|
|
@@ -854,23 +1064,23 @@ export class MessageDeliveryEngine {
|
|
|
854
1064
|
isGroupEventNamespace(ns) {
|
|
855
1065
|
return ns.startsWith('group_event:');
|
|
856
1066
|
}
|
|
857
|
-
async publishOrderedQueueItem(ns, event, seq, payload, pullResponse = false) {
|
|
1067
|
+
async publishOrderedQueueItem(ns, event, seq, payload, pullResponse = false, source = 'push', batch) {
|
|
858
1068
|
const client = this.runtime.client;
|
|
859
1069
|
if (event === 'group.changed' && this.isGroupEventNamespace(ns)) {
|
|
860
|
-
await this.publishOrderedGroupChanged(payload);
|
|
1070
|
+
await this.publishOrderedGroupChanged(payload, source);
|
|
861
1071
|
return;
|
|
862
1072
|
}
|
|
863
1073
|
if (event === 'message.recalled') {
|
|
864
|
-
await this.publishMessageRecallTombstone(seq, payload);
|
|
1074
|
+
await this.publishMessageRecallTombstone(seq, payload, source);
|
|
865
1075
|
return;
|
|
866
1076
|
}
|
|
867
1077
|
if (pullResponse) {
|
|
868
|
-
await client._withPullResponseProcessing(ns, () => client._publishAppEvent(event, payload));
|
|
1078
|
+
await client._withPullResponseProcessing(ns, () => client._publishAppEvent(event, payload, source, ns, batch));
|
|
869
1079
|
return;
|
|
870
1080
|
}
|
|
871
|
-
await client._publishAppEvent(event, payload);
|
|
1081
|
+
await client._publishAppEvent(event, payload, source, ns, batch);
|
|
872
1082
|
}
|
|
873
|
-
async publishOrderedGroupChanged(payload) {
|
|
1083
|
+
async publishOrderedGroupChanged(payload, source = 'ordered') {
|
|
874
1084
|
const client = this.runtime.client;
|
|
875
1085
|
if (isJsonObject(payload)) {
|
|
876
1086
|
const eventPayload = payload;
|
|
@@ -882,7 +1092,7 @@ export class MessageDeliveryEngine {
|
|
|
882
1092
|
client._cleanupDissolvedGroup?.(groupId);
|
|
883
1093
|
}
|
|
884
1094
|
}
|
|
885
|
-
await client._publishAppEvent('group.changed', payload);
|
|
1095
|
+
await client._publishAppEvent('group.changed', payload, source);
|
|
886
1096
|
}
|
|
887
1097
|
isInstanceScopedMessageEvent(event) {
|
|
888
1098
|
return event === 'message.received'
|
|
@@ -905,18 +1115,27 @@ export class MessageDeliveryEngine {
|
|
|
905
1115
|
}
|
|
906
1116
|
return result;
|
|
907
1117
|
}
|
|
908
|
-
normalizePublishedMessagePayload(event, payload) {
|
|
1118
|
+
normalizePublishedMessagePayload(event, payload, source = 'direct') {
|
|
1119
|
+
let normalized;
|
|
909
1120
|
if (this.isInstanceScopedMessageEvent(event)) {
|
|
910
1121
|
payload = this.stripInlineInternalFields(payload);
|
|
911
1122
|
if (event === 'group.message_created')
|
|
912
1123
|
payload = normalizeGroupMentionMode(payload);
|
|
913
|
-
|
|
1124
|
+
normalized = this.attachAppMessageEnvelope(this.stripInternalSenderDeviceFields(this.attachCurrentInstanceContext(payload)));
|
|
914
1125
|
}
|
|
915
|
-
if (this.isGroupScopedEvent(event)) {
|
|
1126
|
+
else if (this.isGroupScopedEvent(event)) {
|
|
916
1127
|
payload = this.stripInlineInternalFields(payload);
|
|
917
|
-
|
|
1128
|
+
normalized = this.attachAppGroupEventEnvelope(this.attachCurrentInstanceContext(payload));
|
|
918
1129
|
}
|
|
919
|
-
|
|
1130
|
+
else {
|
|
1131
|
+
normalized = payload;
|
|
1132
|
+
}
|
|
1133
|
+
const canonicalSource = canonicalDeliverySource(source);
|
|
1134
|
+
if (canonicalSource === 'direct' || !isJsonObject(normalized))
|
|
1135
|
+
return normalized;
|
|
1136
|
+
if (!this.isInstanceScopedMessageEvent(event) && !this.isGroupScopedEvent(event))
|
|
1137
|
+
return normalized;
|
|
1138
|
+
return { ...normalized, source: canonicalSource };
|
|
920
1139
|
}
|
|
921
1140
|
stripInlineInternalFields(payload) {
|
|
922
1141
|
if (!isJsonObject(payload))
|
|
@@ -1043,6 +1262,7 @@ export class MessageDeliveryEngine {
|
|
|
1043
1262
|
setIfPresent('type', firstValue(body.type, params.type, params.message_type, params.payload_type));
|
|
1044
1263
|
setIfPresent('kind', firstValue(body.kind, params.kind));
|
|
1045
1264
|
setIfPresent('version', firstValue(body.version, params.version));
|
|
1265
|
+
setIfPresent('message_id', firstValue(params.message_id, body.message_id, resultObj.message_id));
|
|
1046
1266
|
setIfPresent('timestamp', firstValue(params.timestamp, resultObj.timestamp, resultObj.created_at, resultObj.t_server, Date.now()));
|
|
1047
1267
|
envelope.encrypted = Boolean(encrypted);
|
|
1048
1268
|
const context = this.envelopeMetadata(params.context);
|
|
@@ -1184,7 +1404,7 @@ export class MessageDeliveryEngine {
|
|
|
1184
1404
|
return `p2p|tombstone:${tombstoneId}`;
|
|
1185
1405
|
return `p2p|unknown:${Date.now()}:${Math.random()}`;
|
|
1186
1406
|
}
|
|
1187
|
-
async publishMessageRecallTombstone(seq, message) {
|
|
1407
|
+
async publishMessageRecallTombstone(seq, message, source = 'push') {
|
|
1188
1408
|
const client = this.runtime.client;
|
|
1189
1409
|
const eventPayload = this.recallEventFromMessage(message);
|
|
1190
1410
|
if (!eventPayload)
|
|
@@ -1205,7 +1425,7 @@ export class MessageDeliveryEngine {
|
|
|
1205
1425
|
for (const [oldKey] of drop)
|
|
1206
1426
|
seen.delete(oldKey);
|
|
1207
1427
|
}
|
|
1208
|
-
await client._publishAppEvent('message.recalled', eventPayload);
|
|
1428
|
+
await client._publishAppEvent('message.recalled', eventPayload, source);
|
|
1209
1429
|
client._clientLog.debug(`message.recalled published: seq=${String(seq)} ids=${JSON.stringify(eventPayload.message_ids)}`);
|
|
1210
1430
|
return true;
|
|
1211
1431
|
}
|
|
@@ -1288,7 +1508,7 @@ export class MessageDeliveryEngine {
|
|
|
1288
1508
|
return `${normalizedGroupId}|tombstone:${tombstoneId}`;
|
|
1289
1509
|
return `${normalizedGroupId}|unknown:${Date.now()}:${Math.random()}`;
|
|
1290
1510
|
}
|
|
1291
|
-
async publishGroupRecallTombstone(groupId, seq, message) {
|
|
1511
|
+
async publishGroupRecallTombstone(groupId, seq, message, source = 'push') {
|
|
1292
1512
|
const client = this.runtime.client;
|
|
1293
1513
|
const eventPayload = this.recallEventFromGroupMessage(message);
|
|
1294
1514
|
if (!eventPayload)
|
|
@@ -1311,7 +1531,7 @@ export class MessageDeliveryEngine {
|
|
|
1311
1531
|
for (const [oldKey] of drop)
|
|
1312
1532
|
seen.delete(oldKey);
|
|
1313
1533
|
}
|
|
1314
|
-
await client._publishAppEvent('group.message_recalled', eventPayload);
|
|
1534
|
+
await client._publishAppEvent('group.message_recalled', eventPayload, source);
|
|
1315
1535
|
client._clientLog.debug(`group.message_recalled published: group=${groupId} seq=${String(seq)} ids=${JSON.stringify(eventPayload.message_ids)}`);
|
|
1316
1536
|
return true;
|
|
1317
1537
|
}
|
|
@@ -1385,8 +1605,9 @@ export class MessageDeliveryEngine {
|
|
|
1385
1605
|
if (contig !== contigBefore)
|
|
1386
1606
|
this.persistSeq(ns);
|
|
1387
1607
|
}
|
|
1388
|
-
async publishAppEvent(event, payload) {
|
|
1608
|
+
async publishAppEvent(event, payload, source = 'direct', ns = '', batch) {
|
|
1389
1609
|
const client = this.runtime.client;
|
|
1610
|
+
const generation = this.deliveryGeneration;
|
|
1390
1611
|
if ((event === 'message.received' || event === 'group.message_created') && isJsonObject(payload)) {
|
|
1391
1612
|
client._maybeAppendEchoTraceReceive(payload);
|
|
1392
1613
|
}
|
|
@@ -1406,7 +1627,32 @@ export class MessageDeliveryEngine {
|
|
|
1406
1627
|
client._clientLog.debug(`agent_md etag inject skipped: ${String(exc)}`);
|
|
1407
1628
|
}
|
|
1408
1629
|
}
|
|
1409
|
-
|
|
1630
|
+
const canonicalSource = canonicalDeliverySource(source);
|
|
1631
|
+
let normalized = this.normalizePublishedMessagePayload(event, payload, source);
|
|
1632
|
+
if (isJsonObject(normalized)
|
|
1633
|
+
&& (this.isInstanceScopedMessageEvent(event) || this.isGroupScopedEvent(event))
|
|
1634
|
+
&& canonicalSource !== 'direct') {
|
|
1635
|
+
normalized = { ...normalized, source: canonicalSource };
|
|
1636
|
+
}
|
|
1637
|
+
client._dispatcher.enqueue(event, normalized);
|
|
1638
|
+
if (generation !== this.deliveryGeneration)
|
|
1639
|
+
return;
|
|
1640
|
+
if (canonicalSource !== 'pull' && canonicalSource !== 'pending_retry'
|
|
1641
|
+
&& canonicalSource !== 'push' && canonicalSource !== 'inline_push')
|
|
1642
|
+
return;
|
|
1643
|
+
if (canonicalSource === 'push' || canonicalSource === 'inline_push') {
|
|
1644
|
+
const localBatch = batch ?? this.createDeliveryChangeBatch(canonicalSource);
|
|
1645
|
+
this.recordDeliveryChange(localBatch.changes, event, payload, ns, generation);
|
|
1646
|
+
if (!batch)
|
|
1647
|
+
await this.flushRealtimeDeliveryChanges(localBatch);
|
|
1648
|
+
}
|
|
1649
|
+
else {
|
|
1650
|
+
const changes = this.pendingPullDeliveryChanges ?? new Map();
|
|
1651
|
+
this.pendingPullDeliveryChanges = changes;
|
|
1652
|
+
this.recordDeliveryChange(changes, event, payload, ns, generation);
|
|
1653
|
+
if (client._rpcPipeline?.hasAnyPullActivity?.() !== true)
|
|
1654
|
+
await this.flushPullDeliveryChanges();
|
|
1655
|
+
}
|
|
1410
1656
|
}
|
|
1411
1657
|
messageTargetsCurrentInstance(message) {
|
|
1412
1658
|
if (!isJsonObject(message))
|
|
@@ -1562,7 +1808,7 @@ export class MessageDeliveryEngine {
|
|
|
1562
1808
|
const client = this.runtime.client;
|
|
1563
1809
|
try {
|
|
1564
1810
|
if (!isJsonObject(data)) {
|
|
1565
|
-
await client._publishAppEvent('message.received', data);
|
|
1811
|
+
await client._publishAppEvent('message.received', data, 'push');
|
|
1566
1812
|
return;
|
|
1567
1813
|
}
|
|
1568
1814
|
const msg = { ...data };
|
|
@@ -1614,7 +1860,7 @@ export class MessageDeliveryEngine {
|
|
|
1614
1860
|
await client._publishEncryptedPushMessage('message.received', 'message.undecryptable', '', seq ?? 0, msg, false);
|
|
1615
1861
|
return;
|
|
1616
1862
|
}
|
|
1617
|
-
await client._publishAppEvent('message.received', msg);
|
|
1863
|
+
await client._publishAppEvent('message.received', msg, 'push');
|
|
1618
1864
|
}
|
|
1619
1865
|
}
|
|
1620
1866
|
catch (exc) {
|
|
@@ -1630,7 +1876,7 @@ export class MessageDeliveryEngine {
|
|
|
1630
1876
|
_decrypt_error: String(exc),
|
|
1631
1877
|
};
|
|
1632
1878
|
client._attachV2EnvelopeMetadataFromSource(safeEvent, data);
|
|
1633
|
-
await client._publishAppEvent('message.undecryptable', safeEvent);
|
|
1879
|
+
await client._publishAppEvent('message.undecryptable', safeEvent, 'push');
|
|
1634
1880
|
}
|
|
1635
1881
|
}
|
|
1636
1882
|
}
|
|
@@ -1658,7 +1904,7 @@ export class MessageDeliveryEngine {
|
|
|
1658
1904
|
const client = this.runtime.client;
|
|
1659
1905
|
try {
|
|
1660
1906
|
if (!isJsonObject(data)) {
|
|
1661
|
-
await client._publishAppEvent('group.message_created', data);
|
|
1907
|
+
await client._publishAppEvent('group.message_created', data, 'push');
|
|
1662
1908
|
return;
|
|
1663
1909
|
}
|
|
1664
1910
|
const msg = { ...data };
|
|
@@ -1737,7 +1983,7 @@ export class MessageDeliveryEngine {
|
|
|
1737
1983
|
await client._publishEncryptedPushMessage('group.message_created', 'group.message_undecryptable', '', seq ?? 0, msg, true);
|
|
1738
1984
|
return;
|
|
1739
1985
|
}
|
|
1740
|
-
await client._publishAppEvent('group.message_created', msg);
|
|
1986
|
+
await client._publishAppEvent('group.message_created', msg, 'push');
|
|
1741
1987
|
}
|
|
1742
1988
|
}
|
|
1743
1989
|
catch (exc) {
|
|
@@ -1753,7 +1999,7 @@ export class MessageDeliveryEngine {
|
|
|
1753
1999
|
_decrypt_error: String(exc),
|
|
1754
2000
|
};
|
|
1755
2001
|
client._attachV2EnvelopeMetadataFromSource(safeEvent, data);
|
|
1756
|
-
await client._publishAppEvent('group.message_undecryptable', safeEvent);
|
|
2002
|
+
await client._publishAppEvent('group.message_undecryptable', safeEvent, 'push');
|
|
1757
2003
|
}
|
|
1758
2004
|
}
|
|
1759
2005
|
}
|
|
@@ -1761,7 +2007,7 @@ export class MessageDeliveryEngine {
|
|
|
1761
2007
|
const client = this.runtime.client;
|
|
1762
2008
|
const groupId = (notification.group_id ?? '');
|
|
1763
2009
|
if (!groupId) {
|
|
1764
|
-
await client._publishAppEvent('group.message_created', notification);
|
|
2010
|
+
await client._publishAppEvent('group.message_created', notification, 'push');
|
|
1765
2011
|
return;
|
|
1766
2012
|
}
|
|
1767
2013
|
if (client._sessionOptions?.background_sync === false) {
|
|
@@ -1778,7 +2024,7 @@ export class MessageDeliveryEngine {
|
|
|
1778
2024
|
}
|
|
1779
2025
|
catch (exc) {
|
|
1780
2026
|
client._clientLog.warn(`auto pull group message failed:${String(exc)}`);
|
|
1781
|
-
await client._publishAppEvent('group.message_created', notification);
|
|
2027
|
+
await client._publishAppEvent('group.message_created', notification, 'push');
|
|
1782
2028
|
return;
|
|
1783
2029
|
}
|
|
1784
2030
|
}
|
|
@@ -1808,7 +2054,7 @@ export class MessageDeliveryEngine {
|
|
|
1808
2054
|
// 两种情况都不能再把原始通知当作第二条业务消息发布。
|
|
1809
2055
|
client._clientLog.warn(`auto pull group message commit/ack failed:${String(exc)}`);
|
|
1810
2056
|
if (!rawCompleted) {
|
|
1811
|
-
await client._publishAppEvent('group.message_created', notification);
|
|
2057
|
+
await client._publishAppEvent('group.message_created', notification, 'push');
|
|
1812
2058
|
}
|
|
1813
2059
|
}
|
|
1814
2060
|
}
|
|
@@ -1821,12 +2067,15 @@ export class MessageDeliveryEngine {
|
|
|
1821
2067
|
return;
|
|
1822
2068
|
const delayMs = Math.min(P2P_GAP_FILL_RETRY_BASE_MS * retryAttempt, P2P_GAP_FILL_RETRY_MAX_MS);
|
|
1823
2069
|
client._gapFillDone.add(retryKey);
|
|
2070
|
+
const releasePullWork = client._rpcPipeline?.reservePullWork?.() ?? (() => { });
|
|
1824
2071
|
client._clientLog.debug(`P2P message gap-fill retry scheduled: ns=${ns} attempt=${retryAttempt} delay_ms=${delayMs}`);
|
|
1825
2072
|
globalThis.setTimeout(() => {
|
|
1826
2073
|
client._gapFillDone.delete(retryKey);
|
|
1827
|
-
if (client.state !== ConnectionState.READY || client._closing)
|
|
2074
|
+
if (client.state !== ConnectionState.READY || client._closing) {
|
|
2075
|
+
releasePullWork();
|
|
1828
2076
|
return;
|
|
1829
|
-
|
|
2077
|
+
}
|
|
2078
|
+
client._safeAsync(this.fillP2pGap(retryAttempt).finally(releasePullWork));
|
|
1830
2079
|
}, delayMs);
|
|
1831
2080
|
}
|
|
1832
2081
|
async fillP2pGap(retryAttempt = 0) {
|
|
@@ -1943,6 +2192,7 @@ export class MessageDeliveryEngine {
|
|
|
1943
2192
|
client._gapFillDone.add(dedupKey);
|
|
1944
2193
|
this.runtime.delivery.setGapFillActive(true);
|
|
1945
2194
|
let continuationAfterSeq = 0;
|
|
2195
|
+
let failed = false;
|
|
1946
2196
|
try {
|
|
1947
2197
|
let nextAfterSeq = afterSeq;
|
|
1948
2198
|
const maxPages = singlePage ? 1 : 100;
|
|
@@ -1982,6 +2232,7 @@ export class MessageDeliveryEngine {
|
|
|
1982
2232
|
}
|
|
1983
2233
|
const eventSeqs = [];
|
|
1984
2234
|
let hasDissolvedEvent = false;
|
|
2235
|
+
let publishedEventCount = 0;
|
|
1985
2236
|
for (const evt of eventObjects) {
|
|
1986
2237
|
const eventSeq = Number(evt.event_seq ?? 0);
|
|
1987
2238
|
if (Number.isFinite(eventSeq) && eventSeq > 0)
|
|
@@ -2003,7 +2254,8 @@ export class MessageDeliveryEngine {
|
|
|
2003
2254
|
}
|
|
2004
2255
|
}
|
|
2005
2256
|
if (Number.isFinite(eventSeq) && eventSeq > 0 && !client._pushedSeqs.get(ns)?.has(eventSeq)) {
|
|
2006
|
-
this.enqueueOrderedMessage(ns, 'group.changed', eventSeq, evt);
|
|
2257
|
+
this.enqueueOrderedMessage(ns, 'group.changed', eventSeq, evt, 'pull');
|
|
2258
|
+
publishedEventCount += 1;
|
|
2007
2259
|
}
|
|
2008
2260
|
}
|
|
2009
2261
|
const ackContig = client._seqTracker.getContiguousSeq(ns);
|
|
@@ -2029,6 +2281,7 @@ export class MessageDeliveryEngine {
|
|
|
2029
2281
|
client._clientLog.warn('group event auto-ack failed: group=' + groupId, e);
|
|
2030
2282
|
}
|
|
2031
2283
|
}
|
|
2284
|
+
this.onPullPage(ns, publishedEventCount, result.has_more === true, eventObjects.length > 0 ? Number(eventObjects[eventObjects.length - 1].event_seq ?? 0) : undefined, typeof result.remaining === 'number' && Number.isSafeInteger(result.remaining) && result.remaining >= 0 ? result.remaining : null, eventObjects.length, ackContig, eventObjects.length > 0 ? Number(eventObjects[eventObjects.length - 1].event_seq ?? 0) : undefined);
|
|
2032
2285
|
const nextAfter = Math.max(eventSeqs.length > 0 ? Math.max(...eventSeqs) : nextAfterSeq, nextAfterSeq);
|
|
2033
2286
|
if (singlePage && result.has_more === true && nextAfter > nextAfterSeq) {
|
|
2034
2287
|
continuationAfterSeq = nextAfter;
|
|
@@ -2042,11 +2295,14 @@ export class MessageDeliveryEngine {
|
|
|
2042
2295
|
}
|
|
2043
2296
|
}
|
|
2044
2297
|
catch (exc) {
|
|
2298
|
+
failed = true;
|
|
2045
2299
|
client._clientLog.warn(`group event gap-fill failed:${String(exc)}`);
|
|
2046
2300
|
}
|
|
2047
2301
|
finally {
|
|
2048
2302
|
client._gapFillDone.delete(dedupKey);
|
|
2049
2303
|
this.runtime.delivery.setGapFillActive(false);
|
|
2304
|
+
if (!client._rpcPipeline)
|
|
2305
|
+
this.syncStopped(failed ? 'aborted' : 'pull_drained');
|
|
2050
2306
|
if (singlePage && continuationAfterSeq > afterSeq) {
|
|
2051
2307
|
this.enqueueOnlineUnreadEventHint({
|
|
2052
2308
|
group_id: groupId,
|
|
@@ -2527,7 +2783,7 @@ export class MessageDeliveryEngine {
|
|
|
2527
2783
|
? tracker.snapshotNamespace(ns)
|
|
2528
2784
|
: null;
|
|
2529
2785
|
try {
|
|
2530
|
-
const published = await this.publishPulledMessage(event, ns, seq, payload);
|
|
2786
|
+
const published = await this.publishPulledMessage(event, ns, seq, payload, true, 'inline_push');
|
|
2531
2787
|
if (!this.isInlineGenerationCurrent(generation))
|
|
2532
2788
|
return false;
|
|
2533
2789
|
if (!published)
|
|
@@ -3107,13 +3363,13 @@ export class MessageDeliveryEngine {
|
|
|
3107
3363
|
}
|
|
3108
3364
|
}
|
|
3109
3365
|
catch (exc) {
|
|
3110
|
-
client._dispatcher.
|
|
3366
|
+
client._dispatcher.enqueue('seq_tracker.persist_error', {
|
|
3111
3367
|
phase: 'restore',
|
|
3112
3368
|
aid,
|
|
3113
3369
|
device_id: deviceId,
|
|
3114
3370
|
slot_id: slotId,
|
|
3115
3371
|
error: String(exc),
|
|
3116
|
-
})
|
|
3372
|
+
});
|
|
3117
3373
|
}
|
|
3118
3374
|
}
|
|
3119
3375
|
async migrateSeqStateGroupIds(state) {
|
|
@@ -3321,13 +3577,13 @@ export class MessageDeliveryEngine {
|
|
|
3321
3577
|
catch (exc) {
|
|
3322
3578
|
const error = formatDeliveryError(exc);
|
|
3323
3579
|
client._clientLog.warn(`save SeqTracker state failed: ${error}`);
|
|
3324
|
-
client._dispatcher.
|
|
3580
|
+
client._dispatcher.enqueue('seq_tracker.persist_error', {
|
|
3325
3581
|
phase: 'save',
|
|
3326
3582
|
aid,
|
|
3327
3583
|
device_id: deviceId,
|
|
3328
3584
|
slot_id: slotId,
|
|
3329
3585
|
error: String(error),
|
|
3330
|
-
})
|
|
3586
|
+
});
|
|
3331
3587
|
if (throwOnError)
|
|
3332
3588
|
throw exc;
|
|
3333
3589
|
}
|
|
@@ -3446,7 +3702,7 @@ export class MessageDeliveryEngine {
|
|
|
3446
3702
|
}
|
|
3447
3703
|
return params;
|
|
3448
3704
|
}
|
|
3449
|
-
async drainOrderedMessages(ns, beforeSeq, pullResponse = false, persist = true) {
|
|
3705
|
+
async drainOrderedMessages(ns, beforeSeq, pullResponse = false, persist = true, batch, source = 'pull') {
|
|
3450
3706
|
const client = this.runtime.client;
|
|
3451
3707
|
this.ensurePullOperationCurrent();
|
|
3452
3708
|
const queue = client._pendingOrderedMsgs.get(ns);
|
|
@@ -3457,16 +3713,34 @@ export class MessageDeliveryEngine {
|
|
|
3457
3713
|
.filter((seq) => seq <= contig && (beforeSeq === undefined || seq < beforeSeq))
|
|
3458
3714
|
.sort((a, b) => a - b);
|
|
3459
3715
|
let delivered = false;
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
const
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3716
|
+
const drainBatches = new Map();
|
|
3717
|
+
try {
|
|
3718
|
+
for (const seq of ready) {
|
|
3719
|
+
this.ensurePullOperationCurrent();
|
|
3720
|
+
const item = queue.get(seq);
|
|
3721
|
+
queue.delete(seq);
|
|
3722
|
+
if (!item || client._pushedSeqs.get(ns)?.has(seq))
|
|
3723
|
+
continue;
|
|
3724
|
+
const itemSource = item.source ?? source;
|
|
3725
|
+
let itemBatch = batch;
|
|
3726
|
+
if ((itemSource === 'push' || itemSource === 'inline_push')
|
|
3727
|
+
&& (!batch || batch.trigger !== itemSource)) {
|
|
3728
|
+
itemBatch = drainBatches.get(itemSource);
|
|
3729
|
+
if (!itemBatch) {
|
|
3730
|
+
itemBatch = this.createDeliveryChangeBatch(itemSource);
|
|
3731
|
+
drainBatches.set(itemSource, itemBatch);
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
await this.publishOrderedQueueItem(ns, item.event, seq, item.payload, pullResponse, itemSource, itemBatch);
|
|
3735
|
+
this.ensurePullOperationCurrent();
|
|
3736
|
+
this.markPublishedSeq(ns, seq);
|
|
3737
|
+
delivered = true;
|
|
3738
|
+
}
|
|
3739
|
+
}
|
|
3740
|
+
finally {
|
|
3741
|
+
for (const drainBatch of drainBatches.values()) {
|
|
3742
|
+
await this.flushRealtimeDeliveryChanges(drainBatch);
|
|
3743
|
+
}
|
|
3470
3744
|
}
|
|
3471
3745
|
if (queue.size === 0) {
|
|
3472
3746
|
client._pendingOrderedMsgs.delete(ns);
|
|
@@ -3476,75 +3750,91 @@ export class MessageDeliveryEngine {
|
|
|
3476
3750
|
}
|
|
3477
3751
|
}
|
|
3478
3752
|
}
|
|
3479
|
-
async publishOrderedMessage(event, ns, seq, payload) {
|
|
3753
|
+
async publishOrderedMessage(event, ns, seq, payload, source = 'push', operationBatch) {
|
|
3480
3754
|
const client = this.runtime.client;
|
|
3481
|
-
const
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3755
|
+
const ownsBatch = !operationBatch && (source === 'push' || source === 'inline_push');
|
|
3756
|
+
const batch = operationBatch ?? (ownsBatch ? this.createDeliveryChangeBatch(source) : undefined);
|
|
3757
|
+
try {
|
|
3758
|
+
const seqNum = Number(seq);
|
|
3759
|
+
if (!Number.isFinite(seqNum) || !Number.isInteger(seqNum) || seqNum <= 0) {
|
|
3760
|
+
await this.publishOrderedQueueItem(ns, event, seqNum, payload, false, source, batch);
|
|
3761
|
+
return true;
|
|
3762
|
+
}
|
|
3763
|
+
if (client._pushedSeqs.get(ns)?.has(seqNum)) {
|
|
3764
|
+
const queue = client._pendingOrderedMsgs.get(ns);
|
|
3765
|
+
queue?.delete(seqNum);
|
|
3766
|
+
if (queue && queue.size === 0)
|
|
3767
|
+
client._pendingOrderedMsgs.delete(ns);
|
|
3768
|
+
return false;
|
|
3769
|
+
}
|
|
3770
|
+
const contig = client._seqTracker.getContiguousSeq(ns);
|
|
3771
|
+
if (seqNum > contig) {
|
|
3772
|
+
this.enqueueOrderedMessage(ns, event, seqNum, payload, source);
|
|
3773
|
+
return false;
|
|
3774
|
+
}
|
|
3775
|
+
await this.drainOrderedMessages(ns, seqNum, true, true, batch, source);
|
|
3776
|
+
if (client._pushedSeqs.get(ns)?.has(seqNum))
|
|
3777
|
+
return false;
|
|
3487
3778
|
const queue = client._pendingOrderedMsgs.get(ns);
|
|
3488
3779
|
queue?.delete(seqNum);
|
|
3489
3780
|
if (queue && queue.size === 0)
|
|
3490
3781
|
client._pendingOrderedMsgs.delete(ns);
|
|
3491
|
-
|
|
3782
|
+
await this.publishOrderedQueueItem(ns, event, seqNum, payload, false, source, batch);
|
|
3783
|
+
this.markPublishedSeq(ns, seqNum);
|
|
3784
|
+
await this.drainOrderedMessages(ns, undefined, false, true, batch, source);
|
|
3785
|
+
if (!client._pendingOrderedMsgs.get(ns))
|
|
3786
|
+
await this.saveSeqTrackerState();
|
|
3787
|
+
return true;
|
|
3492
3788
|
}
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
return false;
|
|
3789
|
+
finally {
|
|
3790
|
+
if (ownsBatch && batch)
|
|
3791
|
+
await this.flushRealtimeDeliveryChanges(batch);
|
|
3497
3792
|
}
|
|
3498
|
-
await this.drainOrderedMessages(ns, seqNum, true);
|
|
3499
|
-
if (client._pushedSeqs.get(ns)?.has(seqNum))
|
|
3500
|
-
return false;
|
|
3501
|
-
const queue = client._pendingOrderedMsgs.get(ns);
|
|
3502
|
-
queue?.delete(seqNum);
|
|
3503
|
-
if (queue && queue.size === 0)
|
|
3504
|
-
client._pendingOrderedMsgs.delete(ns);
|
|
3505
|
-
await this.publishOrderedQueueItem(ns, event, seqNum, payload);
|
|
3506
|
-
this.markPublishedSeq(ns, seqNum);
|
|
3507
|
-
await this.drainOrderedMessages(ns);
|
|
3508
|
-
if (!client._pendingOrderedMsgs.get(ns))
|
|
3509
|
-
await this.saveSeqTrackerState();
|
|
3510
|
-
return true;
|
|
3511
3793
|
}
|
|
3512
|
-
async publishPulledMessage(event, ns, seq, payload, persist = true) {
|
|
3794
|
+
async publishPulledMessage(event, ns, seq, payload, persist = true, source = 'pull', operationBatch) {
|
|
3513
3795
|
const client = this.runtime.client;
|
|
3514
|
-
|
|
3515
|
-
const
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3796
|
+
const ownsBatch = !operationBatch && (source === 'push' || source === 'inline_push');
|
|
3797
|
+
const batch = operationBatch ?? (ownsBatch ? this.createDeliveryChangeBatch(source) : undefined);
|
|
3798
|
+
try {
|
|
3799
|
+
this.ensurePullOperationCurrent();
|
|
3800
|
+
const seqNum = Number(seq);
|
|
3801
|
+
if (!Number.isFinite(seqNum) || !Number.isInteger(seqNum) || seqNum <= 0 || !ns) {
|
|
3802
|
+
if (event === 'message.recalled') {
|
|
3803
|
+
const published = await client._withPullResponseProcessing(ns, () => this.publishMessageRecallTombstone(seq, payload, source));
|
|
3804
|
+
this.ensurePullOperationCurrent();
|
|
3805
|
+
return published;
|
|
3806
|
+
}
|
|
3807
|
+
await client._withPullResponseProcessing(ns, () => client._publishAppEvent(event, payload, source, ns, batch));
|
|
3519
3808
|
this.ensurePullOperationCurrent();
|
|
3520
|
-
return
|
|
3809
|
+
return true;
|
|
3810
|
+
}
|
|
3811
|
+
const queue = client._pendingOrderedMsgs.get(ns);
|
|
3812
|
+
if (client._pushedSeqs.get(ns)?.has(seqNum)) {
|
|
3813
|
+
queue?.delete(seqNum);
|
|
3814
|
+
if (queue && queue.size === 0)
|
|
3815
|
+
client._pendingOrderedMsgs.delete(ns);
|
|
3816
|
+
return false;
|
|
3521
3817
|
}
|
|
3522
|
-
await
|
|
3818
|
+
await this.drainOrderedMessages(ns, seqNum, false, persist, batch, source);
|
|
3523
3819
|
this.ensurePullOperationCurrent();
|
|
3524
|
-
return true;
|
|
3525
|
-
}
|
|
3526
|
-
const queue = client._pendingOrderedMsgs.get(ns);
|
|
3527
|
-
if (client._pushedSeqs.get(ns)?.has(seqNum)) {
|
|
3528
3820
|
queue?.delete(seqNum);
|
|
3529
3821
|
if (queue && queue.size === 0)
|
|
3530
3822
|
client._pendingOrderedMsgs.delete(ns);
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
client.
|
|
3538
|
-
if (event === 'message.recalled') {
|
|
3539
|
-
const published = await client._withPullResponseProcessing(ns, () => this.publishMessageRecallTombstone(seqNum, payload));
|
|
3823
|
+
if (event === 'message.recalled') {
|
|
3824
|
+
const published = await client._withPullResponseProcessing(ns, () => this.publishMessageRecallTombstone(seqNum, payload, source));
|
|
3825
|
+
this.ensurePullOperationCurrent();
|
|
3826
|
+
this.markPublishedSeq(ns, seqNum);
|
|
3827
|
+
return published;
|
|
3828
|
+
}
|
|
3829
|
+
await client._withPullResponseProcessing(ns, () => client._publishAppEvent(event, payload, source, ns, batch));
|
|
3540
3830
|
this.ensurePullOperationCurrent();
|
|
3541
3831
|
this.markPublishedSeq(ns, seqNum);
|
|
3542
|
-
return
|
|
3832
|
+
return true;
|
|
3833
|
+
}
|
|
3834
|
+
finally {
|
|
3835
|
+
if (ownsBatch && batch)
|
|
3836
|
+
await this.flushRealtimeDeliveryChanges(batch);
|
|
3543
3837
|
}
|
|
3544
|
-
await client._withPullResponseProcessing(ns, () => client._publishAppEvent(event, payload));
|
|
3545
|
-
this.ensurePullOperationCurrent();
|
|
3546
|
-
this.markPublishedSeq(ns, seqNum);
|
|
3547
|
-
return true;
|
|
3548
3838
|
}
|
|
3549
3839
|
}
|
|
3550
3840
|
//# sourceMappingURL=delivery.js.map
|