@agentunion/fastaun 0.5.33 → 0.5.35
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 +59 -2
- package/README.md +28 -26
- package/_packed_docs/CHANGELOG.md +59 -2
- package/_packed_docs/INDEX.md +26 -12
- package/_packed_docs/KITE_DOCS_GUIDE.md +17 -11
- package/_packed_docs/agent.md/SCHEMA.md +1 -1
- package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +2 -2
- package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +58 -8
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.1.md +17 -17
- package/_packed_docs/protocol/echo-probe-gateway.md +99 -0
- package/_packed_docs/protocol/echo-probe-sdk.md +91 -0
- 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 -316
- 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 -304
- 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/0.5.35-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +189 -0
- package/_packed_docs/sdk/0.5.35-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +204 -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 +19 -9
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +87 -20
- 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 +60 -13
- 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 -1659
- package/_packed_docs/sdk/09-stream-rpc-manual.md +33 -20
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +19 -17
- 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 +125 -30
- 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 +109 -33
- package/_packed_docs/sdk/INDEX.md +30 -18
- package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/2272.1.md +1 -1
- package/_packed_docs/sdk/Ownership2.1-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +5 -5
- package/_packed_docs/sdk/Ownership2.1-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +5 -5
- package/_packed_docs/sdk/Ownership2.1/350/257/246/347/273/206/350/256/276/350/256/241.md +9 -9
- package/_packed_docs/sdk/README.md +11 -6
- package/_packed_docs//346/266/210/346/201/257/345/274/271/346/200/247/350/241/245/346/213/211/351/200/232/351/201/223/345/256/236/346/226/275/350/256/241/345/210/222.md +400 -0
- package/_packed_docs//346/266/210/346/201/257/345/274/271/346/200/247/350/241/245/346/213/211/351/200/232/351/201/223/346/226/271/346/241/210.md +485 -0
- package/dist/auth.js +39 -45
- package/dist/auth.js.map +1 -1
- package/dist/client/control-messages.js +2 -2
- package/dist/client/control-messages.js.map +1 -1
- package/dist/client/delivery.d.ts +12 -1
- package/dist/client/delivery.js +281 -46
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/lifecycle.js +13 -1
- 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 +5 -0
- package/dist/client/rpc-pipeline.js +227 -63
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/sync-channels.d.ts +90 -0
- package/dist/client/sync-channels.js +508 -0
- package/dist/client/sync-channels.js.map +1 -0
- package/dist/client/v2-e2ee.d.ts +5 -1
- package/dist/client/v2-e2ee.js +420 -303
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +17 -0
- package/dist/client.js +373 -50
- package/dist/client.js.map +1 -1
- package/dist/events.d.ts +1 -0
- package/dist/events.js +5 -0
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mail-client.d.ts +101 -0
- package/dist/mail-client.js +369 -0
- package/dist/mail-client.js.map +1 -0
- package/dist/pubsub/binding.js +23 -3
- package/dist/pubsub/binding.js.map +1 -1
- package/dist/pubsub/channel.d.ts +15 -3
- package/dist/pubsub/channel.js +114 -7
- package/dist/pubsub/channel.js.map +1 -1
- package/dist/pubsub/client.d.ts +17 -2
- package/dist/pubsub/client.js +205 -40
- 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 +5 -2
- package/dist/pubsub/index.js +70 -54
- package/dist/pubsub/index.js.map +1 -1
- package/dist/pubsub/service.d.ts +9 -0
- package/dist/pubsub/service.js +266 -20
- package/dist/pubsub/service.js.map +1 -1
- package/dist/pubsub/types.d.ts +13 -1
- package/dist/storage/lowlevel.d.ts +3 -1
- package/dist/storage/lowlevel.js +13 -0
- package/dist/storage/lowlevel.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 +3 -1
- package/dist/storage/vfs.js +2 -2
- package/dist/storage/vfs.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +55 -5
- package/dist/tools/cross-sdk-agent.js +88 -21
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +16 -0
- package/dist/transport.js +129 -7
- package/dist/transport.js.map +1 -1
- package/dist/udp-standby.d.ts +89 -0
- package/dist/udp-standby.js +487 -0
- package/dist/udp-standby.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -1
- package/scripts/patch-imapflow-external.mjs +69 -0
|
@@ -166,12 +166,16 @@ 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
|
}
|
|
172
173
|
async call(method, params, assertCurrent, options) {
|
|
174
|
+
const echoStarted = params && this.runtime.client._echoStarts.get(params);
|
|
173
175
|
if (options?.background !== undefined || options?.deadline !== undefined)
|
|
174
176
|
params = { ...(params ?? {}), ...(options.background !== undefined ? { _rpc_background: options.background, _rpc_foreground: options.background === false } : {}), ...(options.deadline !== undefined ? { _rpc_deadline: options.deadline } : {}) };
|
|
177
|
+
if (params && echoStarted !== undefined)
|
|
178
|
+
this.runtime.client._echoStarts.set(params, echoStarted);
|
|
175
179
|
if (method.startsWith('storage.') || method.startsWith('group.fs.')) {
|
|
176
180
|
const { noCache, no_cache, ...wireParams } = params ?? {};
|
|
177
181
|
return storageReadCache(this.runtime.client).rpc(method, wireParams, Boolean(noCache ?? no_cache), (requestParams) => this._call(method, requestParams, undefined, assertCurrent));
|
|
@@ -183,9 +187,22 @@ export class RpcPipeline {
|
|
|
183
187
|
}
|
|
184
188
|
async _call(method, params, onSent, assertCurrent) {
|
|
185
189
|
const client = this.runtime.client;
|
|
190
|
+
if ((method === 'message.send' || method === 'group.send') && params && client._isEchoPayload(params.payload ?? params.content)) {
|
|
191
|
+
const started = client._echoStarts.get(params) ?? performance.now();
|
|
192
|
+
params = { ...params };
|
|
193
|
+
client._echoStarts.set(params, started);
|
|
194
|
+
}
|
|
186
195
|
const aid = client._aid, currentAid = client._currentAid;
|
|
187
196
|
const generation = client._delivery?.captureInlineAckGeneration?.();
|
|
188
197
|
const tStart = Date.now();
|
|
198
|
+
const standbyDeadline = Math.min(typeof params?._rpc_deadline === 'number' ? params._rpc_deadline : Infinity, tStart + (Number(client._sessionOptions?.timeouts?.call ?? 35) * 1000));
|
|
199
|
+
const standbyRelease = await client._udpStandby?.acquire(method, standbyDeadline);
|
|
200
|
+
if (client._udpStandby) {
|
|
201
|
+
const started = params && client._echoStarts.get(params);
|
|
202
|
+
params = { ...params, _rpc_deadline: standbyDeadline };
|
|
203
|
+
if (started !== undefined)
|
|
204
|
+
client._echoStarts.set(params, started);
|
|
205
|
+
}
|
|
189
206
|
const requestedAckSeq = method === 'message.ack' || method === 'message.v2.ack'
|
|
190
207
|
? Number(params?.seq
|
|
191
208
|
?? params?.up_to_seq
|
|
@@ -232,7 +249,7 @@ export class RpcPipeline {
|
|
|
232
249
|
const sender = String(p.sender_aid ?? '').trim();
|
|
233
250
|
if (!sender)
|
|
234
251
|
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 : []);
|
|
252
|
+
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
253
|
}
|
|
237
254
|
const runWithPullResponseScope = async (operation) => {
|
|
238
255
|
const scope = pullGateNamespace || (pullGateKey ? this.pullScopeKey(pullGateKey) : '');
|
|
@@ -255,6 +272,19 @@ export class RpcPipeline {
|
|
|
255
272
|
? this.runPullNamespaceSerialized.bind(this) : this.runPullSerialized.bind(this);
|
|
256
273
|
return await run(pullGateKey, async () => this.call(method, lockedParams), pullBackground);
|
|
257
274
|
}
|
|
275
|
+
if (method === 'message.send' || method === 'group.send') {
|
|
276
|
+
const echo = client._isEchoPayload(p.payload);
|
|
277
|
+
const stopped = client._maybeAppendEchoTraceSend(p);
|
|
278
|
+
if (echo) {
|
|
279
|
+
p.encrypt = false;
|
|
280
|
+
delete p.encrypted;
|
|
281
|
+
}
|
|
282
|
+
if (stopped) {
|
|
283
|
+
const result = { status: 'echo_return', message_id: p.message_id, from: p.to ?? p.group_id ?? client._aid, to: client._aid, ...(p.group_id ? { group_id: p.group_id } : {}), payload: p.payload };
|
|
284
|
+
await client._publishEchoReturn(method, p, result);
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
258
288
|
if (method === 'message.send') {
|
|
259
289
|
const encrypt = p.encrypt ?? true;
|
|
260
290
|
delete p.encrypt;
|
|
@@ -272,7 +302,6 @@ export class RpcPipeline {
|
|
|
272
302
|
deadline,
|
|
273
303
|
}));
|
|
274
304
|
}
|
|
275
|
-
client._maybeAppendEchoTraceSend(p);
|
|
276
305
|
}
|
|
277
306
|
if (method === 'group.send') {
|
|
278
307
|
const encrypt = p.encrypt ?? true;
|
|
@@ -291,7 +320,6 @@ export class RpcPipeline {
|
|
|
291
320
|
deadline,
|
|
292
321
|
}));
|
|
293
322
|
}
|
|
294
|
-
client._maybeAppendEchoTraceSend(p);
|
|
295
323
|
}
|
|
296
324
|
if (method === 'group.thought.put') {
|
|
297
325
|
const encrypt = p.encrypt ?? true;
|
|
@@ -324,6 +352,7 @@ export class RpcPipeline {
|
|
|
324
352
|
gateLocked: true,
|
|
325
353
|
force,
|
|
326
354
|
afterVolatileCursor: String(p.after_volatile_cursor ?? '').trim() || undefined,
|
|
355
|
+
background: Boolean(rpcBackground),
|
|
327
356
|
})));
|
|
328
357
|
return { messages };
|
|
329
358
|
}
|
|
@@ -415,18 +444,30 @@ export class RpcPipeline {
|
|
|
415
444
|
this.applyClientSignature(method, p);
|
|
416
445
|
assertCurrent?.();
|
|
417
446
|
const transportParams = deadline === undefined ? p : { ...p, _rpc_deadline: deadline };
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
447
|
+
const history = !onSent && client._historyChannels?.().isHistory(method, transportParams, rpcBackground);
|
|
448
|
+
const request = history
|
|
449
|
+
? client._historyChannels().call(method, transportParams, remaining, undefined, rpcBackground, (prepared) => this.applyClientSignature(method, prepared))
|
|
450
|
+
: onSent
|
|
451
|
+
? client._transport['_callWithSent'](method, transportParams, onSent, remaining, undefined, rpcBackground)
|
|
452
|
+
: remaining !== undefined
|
|
453
|
+
? (rpcBackground
|
|
454
|
+
? client._transport.call(method, transportParams, remaining, undefined, rpcBackground)
|
|
455
|
+
: client._transport.call(method, transportParams, remaining))
|
|
456
|
+
: (rpcBackground
|
|
457
|
+
? client._transport.call(method, transportParams, undefined, undefined, rpcBackground)
|
|
458
|
+
: client._transport.call(method, transportParams));
|
|
427
459
|
return this.bindActivePullCancellation(method, p, request);
|
|
428
460
|
};
|
|
429
|
-
let result
|
|
461
|
+
let result;
|
|
462
|
+
try {
|
|
463
|
+
result = await this.transportCallWithIdentityRecovery(invokeTransport, method, p);
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
const returned = await client._echoFailure(method, p, error, true);
|
|
467
|
+
if (returned)
|
|
468
|
+
return returned;
|
|
469
|
+
throw error;
|
|
470
|
+
}
|
|
430
471
|
invalidateStorageReadCache(client, method, p);
|
|
431
472
|
if (generation === client._delivery?.captureInlineAckGeneration?.()) {
|
|
432
473
|
if (method === 'group.unblock' && aid && client._aid === aid && client._currentAid === currentAid
|
|
@@ -439,6 +480,7 @@ export class RpcPipeline {
|
|
|
439
480
|
result = await this.postprocessResult(method, p, result, {
|
|
440
481
|
skipGroupState: deferGroupReadyPostprocess,
|
|
441
482
|
pullNamespace: pullGateNamespace,
|
|
483
|
+
background: Boolean(rpcBackground),
|
|
442
484
|
});
|
|
443
485
|
if (!skipSendResultEnvelope) {
|
|
444
486
|
result = client._delivery.attachSendResultEnvelope(method, p, result, Boolean(p.encrypted), sendResultModeSource);
|
|
@@ -451,6 +493,7 @@ export class RpcPipeline {
|
|
|
451
493
|
throw err;
|
|
452
494
|
}
|
|
453
495
|
finally {
|
|
496
|
+
standbyRelease?.();
|
|
454
497
|
if (generation === client._delivery?.captureInlineAckGeneration?.())
|
|
455
498
|
client._delivery?.requestBackgroundPullRecovery?.();
|
|
456
499
|
}
|
|
@@ -464,6 +507,8 @@ export class RpcPipeline {
|
|
|
464
507
|
throw new PermissionError(`method is internal_only: ${method}`);
|
|
465
508
|
}
|
|
466
509
|
const p = { ...(params ?? {}) };
|
|
510
|
+
if (params && client._echoStarts.has(params))
|
|
511
|
+
client._echoStarts.set(p, client._echoStarts.get(params));
|
|
467
512
|
this.mergeInstanceProtectedHeaders(method, p);
|
|
468
513
|
const requestedBackground = p._rpc_background ?? p._rpc_background_kind;
|
|
469
514
|
const rpcBackground = p._rpc_foreground === true ? false
|
|
@@ -913,6 +958,19 @@ export class RpcPipeline {
|
|
|
913
958
|
return false;
|
|
914
959
|
return (this.runtime.client._pullResponseKeys.get(this.pullScopeKey(key)) ?? 0) > 0;
|
|
915
960
|
}
|
|
961
|
+
pendingHistoryNamespaces() {
|
|
962
|
+
const namespaces = new Set();
|
|
963
|
+
for (const state of this.pullGateStates.values())
|
|
964
|
+
for (const job of state.background) {
|
|
965
|
+
if (job.invalidated || job.timedOut || /(?:mode=history|mode=tail|\|tail\||tail=true|volatile=true|force=true|class=(?:control|sdk_control))/.test(job.key))
|
|
966
|
+
continue;
|
|
967
|
+
if ((this.runtime.client._delivery?.automaticPullRetryAt?.(job.namespace, job.operation) ?? 0) > Date.now())
|
|
968
|
+
continue;
|
|
969
|
+
if (job.namespace.startsWith('p2p:') || job.namespace.startsWith('p2p.peer.v1/') || job.namespace.startsWith('group:') || job.namespace.startsWith('group_event:'))
|
|
970
|
+
namespaces.add(job.namespace);
|
|
971
|
+
}
|
|
972
|
+
return [...namespaces];
|
|
973
|
+
}
|
|
916
974
|
hasPullActivity(namespace, includePending = true) {
|
|
917
975
|
const ns = String(namespace ?? '').trim();
|
|
918
976
|
if ((!ns.startsWith('p2p:') && !ns.startsWith('p2p.peer.v1/') && !ns.startsWith('group:') && !ns.startsWith('message_class/')) || this.hasInlineRealtimeGuard(ns))
|
|
@@ -1313,6 +1371,98 @@ export class RpcPipeline {
|
|
|
1313
1371
|
armQueuedPullTimers(_state) { }
|
|
1314
1372
|
// ── raw-call ───────────────────────────────────────────────────────────────
|
|
1315
1373
|
async rawCall(method, params, opts = {}) {
|
|
1374
|
+
const client = this.runtime.client;
|
|
1375
|
+
const deadline = Math.min(typeof params?._rpc_deadline === 'number' ? params._rpc_deadline : Infinity, Date.now() + (opts.timeout ?? Number(client._sessionOptions?.timeouts?.call ?? 35) * 1000));
|
|
1376
|
+
const release = await client._udpStandby?.acquire(method, deadline);
|
|
1377
|
+
try {
|
|
1378
|
+
return await this.rawCallAdmitted(method, client._udpStandby ? { ...params, _rpc_deadline: deadline } : params, opts);
|
|
1379
|
+
}
|
|
1380
|
+
finally {
|
|
1381
|
+
release?.();
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
async rawCallAdmitted(method, params, opts = {}) {
|
|
1385
|
+
const client = this.runtime.client;
|
|
1386
|
+
const peerAck = method === 'message.ack' && params?.cursor_scope === 'peer';
|
|
1387
|
+
if (peerAck && params?.seq !== undefined) {
|
|
1388
|
+
params = { ...params, up_to_seq: Object.hasOwn(params, 'up_to_seq') ? params.up_to_seq : params.seq };
|
|
1389
|
+
delete params.seq;
|
|
1390
|
+
}
|
|
1391
|
+
const background = params?._rpc_foreground === true ? false : opts.background ?? params?._rpc_background ?? params?._rpc_background_kind;
|
|
1392
|
+
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];
|
|
1393
|
+
const seq = field ? params?.[field] : undefined;
|
|
1394
|
+
if (!background || !field || typeof seq !== 'number' || !Number.isSafeInteger(seq) || seq <= 0
|
|
1395
|
+
|| Object.keys(params ?? {}).some(key => /volatile|token|proof/.test(key)))
|
|
1396
|
+
return this.rawCallDirect(method, params, opts);
|
|
1397
|
+
const scope = () => [client._aid, client._currentAid, client._deviceId, client._slotId, client._gatewayConnectionId,
|
|
1398
|
+
client._delivery?.captureInlineAckGeneration?.(), client._transport, client._transport?._connectionGeneration, client._transport?._workerGeneration];
|
|
1399
|
+
const identity = scope();
|
|
1400
|
+
const range = { ...params };
|
|
1401
|
+
delete range[field];
|
|
1402
|
+
delete range._rpc_deadline;
|
|
1403
|
+
const key = stableStringify([method, range, opts]);
|
|
1404
|
+
const waitForResponse = (active) => new Promise((resolve, reject) => {
|
|
1405
|
+
let timer;
|
|
1406
|
+
const waiter = { seq, params: { ...params }, resolve: (value) => { clearTimeout(timer); resolve(value); },
|
|
1407
|
+
reject: (error) => { clearTimeout(timer); reject(error); } };
|
|
1408
|
+
active.waiters.push(waiter);
|
|
1409
|
+
const timeout = opts.timeout ?? client._transport?._timeout;
|
|
1410
|
+
const deadline = typeof params?._rpc_deadline === 'number' ? params._rpc_deadline : Infinity;
|
|
1411
|
+
const remaining = Math.min(typeof timeout === 'number' ? timeout : Infinity, deadline - Date.now());
|
|
1412
|
+
if (Number.isFinite(remaining))
|
|
1413
|
+
timer = setTimeout(() => {
|
|
1414
|
+
active.waiters = active.waiters.filter(item => item !== waiter);
|
|
1415
|
+
waiter.reject(new TimeoutError(`rpc timeout: ${method}`, { retryable: true }));
|
|
1416
|
+
}, Math.max(0, remaining));
|
|
1417
|
+
});
|
|
1418
|
+
let job = this.backgroundAcks.get(key);
|
|
1419
|
+
if (job && !job.scope.every((value, index) => value === identity[index]))
|
|
1420
|
+
job = undefined;
|
|
1421
|
+
if (job) {
|
|
1422
|
+
return waitForResponse(job);
|
|
1423
|
+
}
|
|
1424
|
+
job = { scope: identity, params: { ...params }, waiters: [] };
|
|
1425
|
+
const active = job;
|
|
1426
|
+
const response = waitForResponse(active);
|
|
1427
|
+
this.backgroundAcks.set(key, active);
|
|
1428
|
+
const assertCurrent = () => {
|
|
1429
|
+
const currentScope = scope();
|
|
1430
|
+
if (!active.scope.every((value, index) => value === currentScope[index]))
|
|
1431
|
+
throw new ConnectionError('ACK context changed');
|
|
1432
|
+
};
|
|
1433
|
+
void (async () => {
|
|
1434
|
+
try {
|
|
1435
|
+
while (active.waiters.length > 0) {
|
|
1436
|
+
assertCurrent();
|
|
1437
|
+
const latest = active.waiters.reduce((highest, waiter) => waiter.seq > highest.seq ? waiter : highest);
|
|
1438
|
+
const requested = latest.seq;
|
|
1439
|
+
try {
|
|
1440
|
+
const result = await this.rawCallDirect(method, { ...latest.params, [field]: requested }, opts, assertCurrent);
|
|
1441
|
+
const covered = active.waiters.filter(waiter => waiter.seq <= requested);
|
|
1442
|
+
active.waiters = active.waiters.filter(waiter => waiter.seq > requested);
|
|
1443
|
+
for (const waiter of covered)
|
|
1444
|
+
waiter.resolve(result);
|
|
1445
|
+
}
|
|
1446
|
+
catch (error) {
|
|
1447
|
+
const covered = active.waiters.filter(waiter => waiter.seq <= requested);
|
|
1448
|
+
active.waiters = active.waiters.filter(waiter => waiter.seq > requested);
|
|
1449
|
+
for (const waiter of covered)
|
|
1450
|
+
waiter.reject(error);
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
catch (error) {
|
|
1455
|
+
for (const waiter of active.waiters)
|
|
1456
|
+
waiter.reject(error);
|
|
1457
|
+
}
|
|
1458
|
+
finally {
|
|
1459
|
+
if (this.backgroundAcks.get(key) === active)
|
|
1460
|
+
this.backgroundAcks.delete(key);
|
|
1461
|
+
}
|
|
1462
|
+
})();
|
|
1463
|
+
return response;
|
|
1464
|
+
}
|
|
1465
|
+
async rawCallDirect(method, params, opts = {}, assertCurrent) {
|
|
1316
1466
|
const { timeout, trace, signed = true, background = false, pullGateKey = '' } = opts;
|
|
1317
1467
|
const client = this.runtime.client;
|
|
1318
1468
|
if (client._migrationPending)
|
|
@@ -1330,8 +1480,11 @@ export class RpcPipeline {
|
|
|
1330
1480
|
this.applyClientSignature(method, payload);
|
|
1331
1481
|
}
|
|
1332
1482
|
const invokeTransport = () => {
|
|
1483
|
+
assertCurrent?.();
|
|
1333
1484
|
let request;
|
|
1334
|
-
if (rpcBackground)
|
|
1485
|
+
if (client._historyChannels?.().isHistory(method, payload, rpcBackground))
|
|
1486
|
+
request = client._historyChannels().call(method, payload, timeout, trace, rpcBackground, signed ? (prepared) => this.applyClientSignature(method, prepared) : undefined);
|
|
1487
|
+
else if (rpcBackground)
|
|
1335
1488
|
request = client._transport.call(method, payload, timeout, trace, rpcBackground);
|
|
1336
1489
|
else if (trace !== undefined)
|
|
1337
1490
|
request = client._transport.call(method, payload, timeout, trace);
|
|
@@ -1364,7 +1517,7 @@ export class RpcPipeline {
|
|
|
1364
1517
|
}
|
|
1365
1518
|
}
|
|
1366
1519
|
observeBackgroundPullResponse(method, params, result, key = '') {
|
|
1367
|
-
if (params.message_class !== undefined && params.message_class !== 'normal' || params.volatile === true)
|
|
1520
|
+
if (params.message_class !== undefined && params.message_class !== 'normal' || params.volatile === true || params.storage_scope === 'volatile')
|
|
1368
1521
|
return;
|
|
1369
1522
|
if (!['message.pull', 'message.v2.pull', 'group.pull', 'group.v2.pull', 'group.pull_events'].includes(method)
|
|
1370
1523
|
|| params.force === true || params.window_mode === 'tail')
|
|
@@ -1418,59 +1571,70 @@ export class RpcPipeline {
|
|
|
1418
1571
|
// ── postprocess ────────────────────────────────────────────────────────────
|
|
1419
1572
|
async postprocessResult(method, params, result, options = {}) {
|
|
1420
1573
|
const client = this.runtime.client;
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
next
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
if (
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
const explicitCursorParams = this.explicitGroupCursorParams(params);
|
|
1455
|
-
const ownsCursor = Object.keys(explicitCursorParams).length === 0
|
|
1456
|
-
|| this.groupCursorTargetsCurrentInstance(explicitCursorParams);
|
|
1457
|
-
const isTail = String(next.window_mode ?? params.window_mode ?? '').trim().toLowerCase() === 'tail';
|
|
1458
|
-
if (!ownsCursor) {
|
|
1459
|
-
client._clientLog.debug(`group.pull external cursor skips local Forward commit: group=${gid}`);
|
|
1574
|
+
try {
|
|
1575
|
+
const pullNamespace = this.pullScopeKey(options.pullNamespace || this.pullGateKeyForCall(method, params));
|
|
1576
|
+
this.throwIfPullInvalidated(pullNamespace);
|
|
1577
|
+
let next = result;
|
|
1578
|
+
if ((method === 'message.send' || method === 'group.send') && next && typeof next === 'object'
|
|
1579
|
+
&& next.status === 'echo_return') {
|
|
1580
|
+
await client._publishEchoReturn(method, params, next);
|
|
1581
|
+
return next;
|
|
1582
|
+
}
|
|
1583
|
+
if ((method === 'group.send' || method === 'group.v2.send') && isUnknownJsonObject(next)) {
|
|
1584
|
+
next = normalizeGroupMentionMode(next);
|
|
1585
|
+
}
|
|
1586
|
+
if (method === 'group.get_settings' || method === 'group.set_settings') {
|
|
1587
|
+
next = normalizeGroupSettingsResponse(next);
|
|
1588
|
+
}
|
|
1589
|
+
if (method === 'group.thought.get' && isUnknownJsonObject(next)) {
|
|
1590
|
+
client._clientLog?.debug?.(`group.thought.get transport result: found=${String(next.found ?? '')}, raw_count=${Array.isArray(next.thoughts) ? next.thoughts.length : 0}`);
|
|
1591
|
+
next = await client._decryptGroupThoughts(next);
|
|
1592
|
+
}
|
|
1593
|
+
if (method === 'message.thought.get' && isUnknownJsonObject(next)) {
|
|
1594
|
+
client._clientLog?.debug?.(`message.thought.get transport result: found=${String(next.found ?? '')}, raw_count=${Array.isArray(next.thoughts) ? next.thoughts.length : 0}`);
|
|
1595
|
+
next = await client._decryptMessageThoughts(next);
|
|
1596
|
+
}
|
|
1597
|
+
if (method === 'message.pull' && isUnknownJsonObject(next)) {
|
|
1598
|
+
const isTail = String(next.window_mode ?? params.window_mode ?? '').trim().toLowerCase() === 'tail';
|
|
1599
|
+
if (!isTail && client._aid && client._seqTracker) {
|
|
1600
|
+
const ns = pullNamespace || `p2p:${client._aid}`;
|
|
1601
|
+
const afterSeq = Math.max(0, Number(params.after_seq ?? 0) || 0);
|
|
1602
|
+
await client._delivery.commitPlainForwardPage(ns, afterSeq, 'message.pull', next, '', options.background === true);
|
|
1603
|
+
}
|
|
1604
|
+
else {
|
|
1605
|
+
this.postprocessMessagePull(params, next);
|
|
1606
|
+
}
|
|
1460
1607
|
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1608
|
+
if (method === 'group.pull' && isUnknownJsonObject(next)) {
|
|
1609
|
+
if (Array.isArray(next.messages)) {
|
|
1610
|
+
next.messages = next.messages.map((message) => normalizeGroupMentionMode(message));
|
|
1611
|
+
}
|
|
1612
|
+
const gid = String(params.group_id ?? params.group_aid ?? '').trim();
|
|
1613
|
+
const explicitCursorParams = this.explicitGroupCursorParams(params);
|
|
1614
|
+
const ownsCursor = Object.keys(explicitCursorParams).length === 0
|
|
1615
|
+
|| this.groupCursorTargetsCurrentInstance(explicitCursorParams);
|
|
1616
|
+
const isTail = String(next.window_mode ?? params.window_mode ?? '').trim().toLowerCase() === 'tail';
|
|
1617
|
+
if (!ownsCursor) {
|
|
1618
|
+
client._clientLog.debug(`group.pull external cursor skips local Forward commit: group=${gid}`);
|
|
1619
|
+
}
|
|
1620
|
+
else if (!isTail && gid && client._seqTracker) {
|
|
1621
|
+
const ns = pullNamespace || `group:${gid}`;
|
|
1622
|
+
const afterSeq = Math.max(0, Number(params.after_message_seq ?? params.after_seq ?? 0) || 0);
|
|
1623
|
+
await client._delivery.commitPlainForwardPage(ns, afterSeq, 'group.pull', next, gid, options.background === true);
|
|
1624
|
+
}
|
|
1625
|
+
else {
|
|
1626
|
+
this.postprocessGroupPull(params, next);
|
|
1627
|
+
}
|
|
1465
1628
|
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1629
|
+
if (!options.skipGroupState) {
|
|
1630
|
+
next = await client._groupState.postprocessResult(method, params, next);
|
|
1468
1631
|
}
|
|
1632
|
+
return next;
|
|
1469
1633
|
}
|
|
1470
|
-
|
|
1471
|
-
|
|
1634
|
+
finally {
|
|
1635
|
+
if (method === 'message.pull' || method === 'group.pull')
|
|
1636
|
+
client._syncChannelCoordinator?.releaseResponse(result);
|
|
1472
1637
|
}
|
|
1473
|
-
return next;
|
|
1474
1638
|
}
|
|
1475
1639
|
// ── private helpers ────────────────────────────────────────────────────────
|
|
1476
1640
|
postprocessMessagePull(params, result) {
|