@agentunion/fastaun 0.5.32 → 0.5.34
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 +58 -0
- package/README.md +28 -26
- package/_packed_docs/CHANGELOG.md +58 -0
- package/_packed_docs/INDEX.md +17 -3
- package/_packed_docs/KITE_DOCS_GUIDE.md +10 -4
- package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +58 -8
- package/_packed_docs/sdk/0.5.33-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +464 -0
- package/_packed_docs/sdk/0.5.33-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +499 -0
- package/_packed_docs/sdk/0.5.34-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +133 -0
- package/_packed_docs/sdk/0.5.34-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +107 -0
- package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +16 -13
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +13 -1
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +17 -7
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +55 -14
- package/_packed_docs/sdk/09-collab-rpc-manual.md +48 -30
- package/_packed_docs/sdk/09-custody-api-manual.md +3 -3
- package/_packed_docs/sdk/09-group-rpc-manual.md +53 -6
- package/_packed_docs/sdk/09-message-rpc-manual.md +22 -0
- package/_packed_docs/sdk/09-meta-rpc-manual.md +2 -1
- package/_packed_docs/sdk/09-payload-reference.md +9 -8
- package/_packed_docs/sdk/09-proxy-rpc-manual.md +20 -14
- package/_packed_docs/sdk/09-storage-rpc-manual.md +1698 -1642
- package/_packed_docs/sdk/09-stream-rpc-manual.md +33 -20
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +11 -9
- package/_packed_docs/sdk/AUN/344/272/213/344/273/266/345/217/221/345/270/203/350/256/242/351/230/205/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +53 -28
- package/_packed_docs/sdk/AUN/344/272/213/344/273/266/345/217/221/345/270/203/350/256/242/351/230/205/345/274/200/345/217/221/347/247/273/346/244/215/346/214/207/345/215/227.md +62 -28
- package/_packed_docs/sdk/INDEX.md +21 -9
- package/_packed_docs/sdk/README.md +11 -6
- package/dist/agent-md.d.ts +2 -1
- package/dist/agent-md.js +17 -0
- package/dist/agent-md.js.map +1 -1
- package/dist/auth.js +8 -2
- package/dist/auth.js.map +1 -1
- package/dist/client/control-messages.js +4 -4
- package/dist/client/control-messages.js.map +1 -1
- package/dist/client/delivery.d.ts +5 -0
- package/dist/client/delivery.js +146 -32
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/lifecycle.js +3 -0
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-budget.d.ts +21 -0
- package/dist/client/rpc-budget.js +82 -0
- package/dist/client/rpc-budget.js.map +1 -0
- package/dist/client/rpc-pipeline.d.ts +3 -0
- package/dist/client/rpc-pipeline.js +193 -65
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/sync-channels.d.ts +89 -0
- package/dist/client/sync-channels.js +489 -0
- package/dist/client/sync-channels.js.map +1 -0
- package/dist/client/v2-e2ee.d.ts +4 -1
- package/dist/client/v2-e2ee.js +401 -298
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +9 -4
- package/dist/client.js +125 -15
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js.map +1 -1
- package/dist/ownership-workflow.d.ts +23 -3
- package/dist/ownership-workflow.js +36 -13
- package/dist/ownership-workflow.js.map +1 -1
- package/dist/pubsub/binding.js +14 -1
- package/dist/pubsub/binding.js.map +1 -1
- package/dist/pubsub/channel.d.ts +4 -0
- package/dist/pubsub/channel.js +26 -0
- package/dist/pubsub/channel.js.map +1 -1
- package/dist/pubsub/client.d.ts +9 -0
- package/dist/pubsub/client.js +154 -31
- package/dist/pubsub/client.js.map +1 -1
- package/dist/pubsub/credentials.d.ts +3 -0
- package/dist/pubsub/credentials.js +57 -20
- package/dist/pubsub/credentials.js.map +1 -1
- package/dist/pubsub/index.d.ts +3 -0
- package/dist/pubsub/index.js +69 -53
- package/dist/pubsub/index.js.map +1 -1
- package/dist/pubsub/service.d.ts +3 -0
- package/dist/pubsub/service.js +167 -12
- package/dist/pubsub/service.js.map +1 -1
- package/dist/pubsub/types.d.ts +2 -0
- package/dist/storage/lowlevel.d.ts +7 -3
- package/dist/storage/lowlevel.js +15 -0
- package/dist/storage/lowlevel.js.map +1 -1
- package/dist/storage/read-cache.js +12 -0
- package/dist/storage/read-cache.js.map +1 -1
- package/dist/storage/types.d.ts +10 -0
- package/dist/storage/types.js.map +1 -1
- package/dist/storage/vfs.d.ts +7 -3
- package/dist/storage/vfs.js +2 -2
- package/dist/storage/vfs.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +62 -6
- package/dist/tools/cross-sdk-agent.js +169 -37
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +12 -0
- package/dist/transport.js +91 -6
- package/dist/transport.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -166,6 +166,7 @@ export class RpcPipeline {
|
|
|
166
166
|
inlineRealtimeScopes = new Set();
|
|
167
167
|
pullInvalidationWait = null;
|
|
168
168
|
pullDrainedCheckQueued = false;
|
|
169
|
+
backgroundAcks = new Map();
|
|
169
170
|
constructor(runtime) {
|
|
170
171
|
this.runtime = runtime;
|
|
171
172
|
}
|
|
@@ -232,7 +233,7 @@ export class RpcPipeline {
|
|
|
232
233
|
const sender = String(p.sender_aid ?? '').trim();
|
|
233
234
|
if (!sender)
|
|
234
235
|
throw new ValidationError('peer ACK requires sender_aid');
|
|
235
|
-
return await client._v2E2EE.ackPeerV2(sender, requestedAckSeq || undefined, Array.isArray(p.volatile_cursors) ? p.volatile_cursors : [], Array.isArray(p.volatile_ids) ? p.volatile_ids : []);
|
|
236
|
+
return await client._v2E2EE.ackPeerV2(sender, requestedAckSeq || undefined, Array.isArray(p.volatile_cursors) ? p.volatile_cursors : [], Array.isArray(p.volatile_ids) ? p.volatile_ids : [], rpcBackground);
|
|
236
237
|
}
|
|
237
238
|
const runWithPullResponseScope = async (operation) => {
|
|
238
239
|
const scope = pullGateNamespace || (pullGateKey ? this.pullScopeKey(pullGateKey) : '');
|
|
@@ -415,15 +416,18 @@ export class RpcPipeline {
|
|
|
415
416
|
this.applyClientSignature(method, p);
|
|
416
417
|
assertCurrent?.();
|
|
417
418
|
const transportParams = deadline === undefined ? p : { ...p, _rpc_deadline: deadline };
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
419
|
+
const history = !onSent && client._historyChannels?.().isHistory(method, transportParams, rpcBackground);
|
|
420
|
+
const request = history
|
|
421
|
+
? client._historyChannels().call(method, transportParams, remaining, undefined, rpcBackground, (prepared) => this.applyClientSignature(method, prepared))
|
|
422
|
+
: onSent
|
|
423
|
+
? client._transport['_callWithSent'](method, transportParams, onSent, remaining, undefined, rpcBackground)
|
|
424
|
+
: remaining !== undefined
|
|
425
|
+
? (rpcBackground
|
|
426
|
+
? client._transport.call(method, transportParams, remaining, undefined, rpcBackground)
|
|
427
|
+
: client._transport.call(method, transportParams, remaining))
|
|
428
|
+
: (rpcBackground
|
|
429
|
+
? client._transport.call(method, transportParams, undefined, undefined, rpcBackground)
|
|
430
|
+
: client._transport.call(method, transportParams));
|
|
427
431
|
return this.bindActivePullCancellation(method, p, request);
|
|
428
432
|
};
|
|
429
433
|
let result = await this.transportCallWithIdentityRecovery(invokeTransport, method, p);
|
|
@@ -528,14 +532,30 @@ export class RpcPipeline {
|
|
|
528
532
|
throw new ValidationError('message_class must be normal, control or sdk_control');
|
|
529
533
|
}
|
|
530
534
|
if (['message.send', 'group.send', 'group.v2.send'].includes(method)) {
|
|
531
|
-
|
|
535
|
+
let messageClass = Object.hasOwn(params, 'message_class') ? params.message_class : 'normal';
|
|
532
536
|
if (typeof messageClass !== 'string' || !['normal', 'control', 'sdk_control'].includes(messageClass)) {
|
|
533
537
|
throw new ValidationError('message_class must be normal, control or sdk_control');
|
|
534
538
|
}
|
|
539
|
+
const classes = this.runtime.client._negotiatedCapabilities?.message_classes_v2?.[method.startsWith('group.') ? 'group' : 'p2p'];
|
|
540
|
+
if (messageClass === 'control' && (!Array.isArray(classes) || !classes.includes('control'))) {
|
|
541
|
+
const protectedHeaders = this.runtime.client._protectedHeadersFromParams(params) ?? {};
|
|
542
|
+
if (protectedHeaders.message_class !== undefined && protectedHeaders.message_class !== messageClass) {
|
|
543
|
+
throw new ValidationError('protected message_class differs from the requested class');
|
|
544
|
+
}
|
|
545
|
+
delete params.message_class;
|
|
546
|
+
for (const field of ['protected_headers', 'headers']) {
|
|
547
|
+
if (isJsonObject(params[field])) {
|
|
548
|
+
const headers = { ...params[field] };
|
|
549
|
+
delete headers.message_class;
|
|
550
|
+
params[field] = headers;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
messageClass = 'normal';
|
|
554
|
+
}
|
|
535
555
|
if (method.startsWith('group.') && messageClass === 'sdk_control') {
|
|
536
556
|
throw new StateError('SDK control messages are not supported for groups', { stringCode: 'unsupported_protocol' });
|
|
537
557
|
}
|
|
538
|
-
if (method.startsWith('group.') && Number(params.ttl) > 0
|
|
558
|
+
if (method.startsWith('group.') && messageClass !== 'normal' && Number(params.ttl) > 0
|
|
539
559
|
&& !this.runtime.client._controlMessages().supports(messageClass, true)) {
|
|
540
560
|
throw new StateError('volatile group delivery protocol has not been negotiated', { stringCode: 'unsupported_protocol' });
|
|
541
561
|
}
|
|
@@ -546,6 +566,9 @@ export class RpcPipeline {
|
|
|
546
566
|
}
|
|
547
567
|
params.protected_headers = { ...protectedHeaders, message_class: messageClass };
|
|
548
568
|
if (messageClass === 'sdk_control') {
|
|
569
|
+
if (params.encrypt === false && (!isJsonObject(params.payload) || params.payload.type !== 'e2ee.p2p_encrypted')) {
|
|
570
|
+
throw new ValidationError('SDK control messages require E2EE');
|
|
571
|
+
}
|
|
549
572
|
const negotiated = this.runtime.client._negotiatedCapabilities ?? {};
|
|
550
573
|
const scope = method.startsWith('group.') ? 'group' : 'p2p';
|
|
551
574
|
const classes = negotiated.message_classes_v2?.[scope];
|
|
@@ -556,9 +579,12 @@ export class RpcPipeline {
|
|
|
556
579
|
throw new ValidationError('protected SDK control protocol differs from the request');
|
|
557
580
|
}
|
|
558
581
|
params.protected_headers = { ...params.protected_headers, sdk_control_protocol: protocol, sdk_control_version: version };
|
|
559
|
-
if (!
|
|
560
|
-
|
|
561
|
-
|
|
582
|
+
if (!protocol || typeof protocol !== 'string' || !Number.isSafeInteger(version) || Number(version) <= 0) {
|
|
583
|
+
throw new ValidationError('SDK control requires a protocol and positive integer version');
|
|
584
|
+
}
|
|
585
|
+
if (!Array.isArray(classes) || !classes.includes('sdk_control')
|
|
586
|
+
|| !Array.isArray(negotiated.sdk_control_protocols?.[protocol]) || !negotiated.sdk_control_protocols[protocol].includes(version)) {
|
|
587
|
+
delete params.message_class;
|
|
562
588
|
}
|
|
563
589
|
}
|
|
564
590
|
}
|
|
@@ -891,6 +917,19 @@ export class RpcPipeline {
|
|
|
891
917
|
return false;
|
|
892
918
|
return (this.runtime.client._pullResponseKeys.get(this.pullScopeKey(key)) ?? 0) > 0;
|
|
893
919
|
}
|
|
920
|
+
pendingHistoryNamespaces() {
|
|
921
|
+
const namespaces = new Set();
|
|
922
|
+
for (const state of this.pullGateStates.values())
|
|
923
|
+
for (const job of state.background) {
|
|
924
|
+
if (job.invalidated || job.timedOut || /(?:mode=history|mode=tail|\|tail\||tail=true|volatile=true|force=true|class=(?:control|sdk_control))/.test(job.key))
|
|
925
|
+
continue;
|
|
926
|
+
if ((this.runtime.client._delivery?.automaticPullRetryAt?.(job.namespace, job.operation) ?? 0) > Date.now())
|
|
927
|
+
continue;
|
|
928
|
+
if (job.namespace.startsWith('p2p:') || job.namespace.startsWith('p2p.peer.v1/') || job.namespace.startsWith('group:') || job.namespace.startsWith('group_event:'))
|
|
929
|
+
namespaces.add(job.namespace);
|
|
930
|
+
}
|
|
931
|
+
return [...namespaces];
|
|
932
|
+
}
|
|
894
933
|
hasPullActivity(namespace, includePending = true) {
|
|
895
934
|
const ns = String(namespace ?? '').trim();
|
|
896
935
|
if ((!ns.startsWith('p2p:') && !ns.startsWith('p2p.peer.v1/') && !ns.startsWith('group:') && !ns.startsWith('message_class/')) || this.hasInlineRealtimeGuard(ns))
|
|
@@ -1291,6 +1330,86 @@ export class RpcPipeline {
|
|
|
1291
1330
|
armQueuedPullTimers(_state) { }
|
|
1292
1331
|
// ── raw-call ───────────────────────────────────────────────────────────────
|
|
1293
1332
|
async rawCall(method, params, opts = {}) {
|
|
1333
|
+
const client = this.runtime.client;
|
|
1334
|
+
const peerAck = method === 'message.ack' && params?.cursor_scope === 'peer';
|
|
1335
|
+
if (peerAck && params?.seq !== undefined) {
|
|
1336
|
+
params = { ...params, up_to_seq: Object.hasOwn(params, 'up_to_seq') ? params.up_to_seq : params.seq };
|
|
1337
|
+
delete params.seq;
|
|
1338
|
+
}
|
|
1339
|
+
const background = params?._rpc_foreground === true ? false : opts.background ?? params?._rpc_background ?? params?._rpc_background_kind;
|
|
1340
|
+
const field = peerAck ? 'up_to_seq' : { 'message.ack': 'seq', 'message.v2.ack': 'up_to_seq', 'group.ack_messages': 'msg_seq', 'group.v2.ack': 'up_to_seq', 'group.ack_events': 'event_seq' }[method];
|
|
1341
|
+
const seq = field ? params?.[field] : undefined;
|
|
1342
|
+
if (!background || !field || typeof seq !== 'number' || !Number.isSafeInteger(seq) || seq <= 0
|
|
1343
|
+
|| Object.keys(params ?? {}).some(key => /volatile|token|proof/.test(key)))
|
|
1344
|
+
return this.rawCallDirect(method, params, opts);
|
|
1345
|
+
const scope = () => [client._aid, client._currentAid, client._deviceId, client._slotId, client._gatewayConnectionId,
|
|
1346
|
+
client._delivery?.captureInlineAckGeneration?.(), client._transport, client._transport?._connectionGeneration, client._transport?._workerGeneration];
|
|
1347
|
+
const identity = scope();
|
|
1348
|
+
const range = { ...params };
|
|
1349
|
+
delete range[field];
|
|
1350
|
+
const key = stableStringify([method, range, opts]);
|
|
1351
|
+
const waitForResponse = (active) => new Promise((resolve, reject) => {
|
|
1352
|
+
let timer;
|
|
1353
|
+
const waiter = { seq, resolve: (value) => { clearTimeout(timer); resolve(value); },
|
|
1354
|
+
reject: (error) => { clearTimeout(timer); reject(error); } };
|
|
1355
|
+
active.waiters.push(waiter);
|
|
1356
|
+
const timeout = opts.timeout ?? client._transport?._timeout;
|
|
1357
|
+
const deadline = typeof params?._rpc_deadline === 'number' ? params._rpc_deadline : Infinity;
|
|
1358
|
+
const remaining = Math.min(typeof timeout === 'number' ? timeout : Infinity, deadline - Date.now());
|
|
1359
|
+
if (Number.isFinite(remaining))
|
|
1360
|
+
timer = setTimeout(() => {
|
|
1361
|
+
active.waiters = active.waiters.filter(item => item !== waiter);
|
|
1362
|
+
waiter.reject(new TimeoutError(`rpc timeout: ${method}`, { retryable: true }));
|
|
1363
|
+
}, Math.max(0, remaining));
|
|
1364
|
+
});
|
|
1365
|
+
let job = this.backgroundAcks.get(key);
|
|
1366
|
+
if (job && !job.scope.every((value, index) => value === identity[index]))
|
|
1367
|
+
job = undefined;
|
|
1368
|
+
if (job) {
|
|
1369
|
+
return waitForResponse(job);
|
|
1370
|
+
}
|
|
1371
|
+
job = { scope: identity, params: { ...params }, waiters: [] };
|
|
1372
|
+
const active = job;
|
|
1373
|
+
const response = waitForResponse(active);
|
|
1374
|
+
this.backgroundAcks.set(key, active);
|
|
1375
|
+
const assertCurrent = () => {
|
|
1376
|
+
const currentScope = scope();
|
|
1377
|
+
if (!active.scope.every((value, index) => value === currentScope[index]))
|
|
1378
|
+
throw new ConnectionError('ACK context changed');
|
|
1379
|
+
};
|
|
1380
|
+
void (async () => {
|
|
1381
|
+
try {
|
|
1382
|
+
while (active.waiters.length > 0) {
|
|
1383
|
+
assertCurrent();
|
|
1384
|
+
const latest = active.waiters.reduce((highest, waiter) => waiter.seq > highest.seq ? waiter : highest);
|
|
1385
|
+
const requested = latest.seq;
|
|
1386
|
+
try {
|
|
1387
|
+
const result = await this.rawCallDirect(method, { ...active.params, [field]: requested }, opts, assertCurrent);
|
|
1388
|
+
const covered = active.waiters.filter(waiter => waiter.seq <= requested);
|
|
1389
|
+
active.waiters = active.waiters.filter(waiter => waiter.seq > requested);
|
|
1390
|
+
for (const waiter of covered)
|
|
1391
|
+
waiter.resolve(result);
|
|
1392
|
+
}
|
|
1393
|
+
catch (error) {
|
|
1394
|
+
const covered = active.waiters.filter(waiter => waiter.seq <= requested);
|
|
1395
|
+
active.waiters = active.waiters.filter(waiter => waiter.seq > requested);
|
|
1396
|
+
for (const waiter of covered)
|
|
1397
|
+
waiter.reject(error);
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
catch (error) {
|
|
1402
|
+
for (const waiter of active.waiters)
|
|
1403
|
+
waiter.reject(error);
|
|
1404
|
+
}
|
|
1405
|
+
finally {
|
|
1406
|
+
if (this.backgroundAcks.get(key) === active)
|
|
1407
|
+
this.backgroundAcks.delete(key);
|
|
1408
|
+
}
|
|
1409
|
+
})();
|
|
1410
|
+
return response;
|
|
1411
|
+
}
|
|
1412
|
+
async rawCallDirect(method, params, opts = {}, assertCurrent) {
|
|
1294
1413
|
const { timeout, trace, signed = true, background = false, pullGateKey = '' } = opts;
|
|
1295
1414
|
const client = this.runtime.client;
|
|
1296
1415
|
if (client._migrationPending)
|
|
@@ -1308,8 +1427,11 @@ export class RpcPipeline {
|
|
|
1308
1427
|
this.applyClientSignature(method, payload);
|
|
1309
1428
|
}
|
|
1310
1429
|
const invokeTransport = () => {
|
|
1430
|
+
assertCurrent?.();
|
|
1311
1431
|
let request;
|
|
1312
|
-
if (rpcBackground)
|
|
1432
|
+
if (client._historyChannels?.().isHistory(method, payload, rpcBackground))
|
|
1433
|
+
request = client._historyChannels().call(method, payload, timeout, trace, rpcBackground, signed ? (prepared) => this.applyClientSignature(method, prepared) : undefined);
|
|
1434
|
+
else if (rpcBackground)
|
|
1313
1435
|
request = client._transport.call(method, payload, timeout, trace, rpcBackground);
|
|
1314
1436
|
else if (trace !== undefined)
|
|
1315
1437
|
request = client._transport.call(method, payload, timeout, trace);
|
|
@@ -1342,7 +1464,7 @@ export class RpcPipeline {
|
|
|
1342
1464
|
}
|
|
1343
1465
|
}
|
|
1344
1466
|
observeBackgroundPullResponse(method, params, result, key = '') {
|
|
1345
|
-
if (params.message_class !== undefined && params.message_class !== 'normal' || params.volatile === true)
|
|
1467
|
+
if (params.message_class !== undefined && params.message_class !== 'normal' || params.volatile === true || params.storage_scope === 'volatile')
|
|
1346
1468
|
return;
|
|
1347
1469
|
if (!['message.pull', 'message.v2.pull', 'group.pull', 'group.v2.pull', 'group.pull_events'].includes(method)
|
|
1348
1470
|
|| params.force === true || params.window_mode === 'tail')
|
|
@@ -1396,59 +1518,65 @@ export class RpcPipeline {
|
|
|
1396
1518
|
// ── postprocess ────────────────────────────────────────────────────────────
|
|
1397
1519
|
async postprocessResult(method, params, result, options = {}) {
|
|
1398
1520
|
const client = this.runtime.client;
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
if (method === 'group.pull' && isUnknownJsonObject(next)) {
|
|
1428
|
-
if (Array.isArray(next.messages)) {
|
|
1429
|
-
next.messages = next.messages.map((message) => normalizeGroupMentionMode(message));
|
|
1430
|
-
}
|
|
1431
|
-
const gid = String(params.group_id ?? params.group_aid ?? '').trim();
|
|
1432
|
-
const explicitCursorParams = this.explicitGroupCursorParams(params);
|
|
1433
|
-
const ownsCursor = Object.keys(explicitCursorParams).length === 0
|
|
1434
|
-
|| this.groupCursorTargetsCurrentInstance(explicitCursorParams);
|
|
1435
|
-
const isTail = String(next.window_mode ?? params.window_mode ?? '').trim().toLowerCase() === 'tail';
|
|
1436
|
-
if (!ownsCursor) {
|
|
1437
|
-
client._clientLog.debug(`group.pull external cursor skips local Forward commit: group=${gid}`);
|
|
1521
|
+
try {
|
|
1522
|
+
const pullNamespace = this.pullScopeKey(options.pullNamespace || this.pullGateKeyForCall(method, params));
|
|
1523
|
+
this.throwIfPullInvalidated(pullNamespace);
|
|
1524
|
+
let next = result;
|
|
1525
|
+
if ((method === 'group.send' || method === 'group.v2.send') && isUnknownJsonObject(next)) {
|
|
1526
|
+
next = normalizeGroupMentionMode(next);
|
|
1527
|
+
}
|
|
1528
|
+
if (method === 'group.get_settings' || method === 'group.set_settings') {
|
|
1529
|
+
next = normalizeGroupSettingsResponse(next);
|
|
1530
|
+
}
|
|
1531
|
+
if (method === 'group.thought.get' && isUnknownJsonObject(next)) {
|
|
1532
|
+
client._clientLog?.debug?.(`group.thought.get transport result: found=${String(next.found ?? '')}, raw_count=${Array.isArray(next.thoughts) ? next.thoughts.length : 0}`);
|
|
1533
|
+
next = await client._decryptGroupThoughts(next);
|
|
1534
|
+
}
|
|
1535
|
+
if (method === 'message.thought.get' && isUnknownJsonObject(next)) {
|
|
1536
|
+
client._clientLog?.debug?.(`message.thought.get transport result: found=${String(next.found ?? '')}, raw_count=${Array.isArray(next.thoughts) ? next.thoughts.length : 0}`);
|
|
1537
|
+
next = await client._decryptMessageThoughts(next);
|
|
1538
|
+
}
|
|
1539
|
+
if (method === 'message.pull' && isUnknownJsonObject(next)) {
|
|
1540
|
+
const isTail = String(next.window_mode ?? params.window_mode ?? '').trim().toLowerCase() === 'tail';
|
|
1541
|
+
if (!isTail && client._aid && client._seqTracker) {
|
|
1542
|
+
const ns = pullNamespace || `p2p:${client._aid}`;
|
|
1543
|
+
const afterSeq = Math.max(0, Number(params.after_seq ?? 0) || 0);
|
|
1544
|
+
await client._delivery.commitPlainForwardPage(ns, afterSeq, 'message.pull', next);
|
|
1545
|
+
}
|
|
1546
|
+
else {
|
|
1547
|
+
this.postprocessMessagePull(params, next);
|
|
1548
|
+
}
|
|
1438
1549
|
}
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1550
|
+
if (method === 'group.pull' && isUnknownJsonObject(next)) {
|
|
1551
|
+
if (Array.isArray(next.messages)) {
|
|
1552
|
+
next.messages = next.messages.map((message) => normalizeGroupMentionMode(message));
|
|
1553
|
+
}
|
|
1554
|
+
const gid = String(params.group_id ?? params.group_aid ?? '').trim();
|
|
1555
|
+
const explicitCursorParams = this.explicitGroupCursorParams(params);
|
|
1556
|
+
const ownsCursor = Object.keys(explicitCursorParams).length === 0
|
|
1557
|
+
|| this.groupCursorTargetsCurrentInstance(explicitCursorParams);
|
|
1558
|
+
const isTail = String(next.window_mode ?? params.window_mode ?? '').trim().toLowerCase() === 'tail';
|
|
1559
|
+
if (!ownsCursor) {
|
|
1560
|
+
client._clientLog.debug(`group.pull external cursor skips local Forward commit: group=${gid}`);
|
|
1561
|
+
}
|
|
1562
|
+
else if (!isTail && gid && client._seqTracker) {
|
|
1563
|
+
const ns = pullNamespace || `group:${gid}`;
|
|
1564
|
+
const afterSeq = Math.max(0, Number(params.after_message_seq ?? params.after_seq ?? 0) || 0);
|
|
1565
|
+
await client._delivery.commitPlainForwardPage(ns, afterSeq, 'group.pull', next, gid);
|
|
1566
|
+
}
|
|
1567
|
+
else {
|
|
1568
|
+
this.postprocessGroupPull(params, next);
|
|
1569
|
+
}
|
|
1443
1570
|
}
|
|
1444
|
-
|
|
1445
|
-
|
|
1571
|
+
if (!options.skipGroupState) {
|
|
1572
|
+
next = await client._groupState.postprocessResult(method, params, next);
|
|
1446
1573
|
}
|
|
1574
|
+
return next;
|
|
1447
1575
|
}
|
|
1448
|
-
|
|
1449
|
-
|
|
1576
|
+
finally {
|
|
1577
|
+
if (method === 'message.pull' || method === 'group.pull')
|
|
1578
|
+
client._syncChannelCoordinator?.releaseResponse(result);
|
|
1450
1579
|
}
|
|
1451
|
-
return next;
|
|
1452
1580
|
}
|
|
1453
1581
|
// ── private helpers ────────────────────────────────────────────────────────
|
|
1454
1582
|
postprocessMessagePull(params, result) {
|