@agentunion/fastaun-browser 0.5.8 → 0.5.10
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 +62 -0
- package/_packed_docs/CHANGELOG.md +62 -0
- package/_packed_docs/agent.md/examples//347/276/244/347/273/204-/345/274/200/345/217/221/345/233/242/351/230/237.md +21 -0
- 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 +43 -8
- package/_packed_docs/sdk/09-group-rpc-manual.md +18 -3
- package/_packed_docs/sdk/09-message-rpc-manual.md +34 -10
- package/dist/agent-md.d.ts.map +1 -1
- package/dist/agent-md.js +24 -1
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.d.ts.map +1 -1
- package/dist/aid-store.js +1 -3
- package/dist/aid-store.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 +1247 -269
- package/dist/client/delivery.d.ts +30 -7
- package/dist/client/delivery.d.ts.map +1 -1
- package/dist/client/delivery.js +354 -92
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.js +8 -8
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.d.ts.map +1 -1
- package/dist/client/lifecycle.js +41 -34
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +12 -0
- package/dist/client/rpc-pipeline.d.ts.map +1 -1
- package/dist/client/rpc-pipeline.js +205 -36
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +1 -1
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +72 -18
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +0 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +128 -45
- 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/facades.d.ts.map +1 -1
- package/dist/facades.js +7 -3
- package/dist/facades.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 +283 -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/_packed_docs//345/217/221/345/270/203/346/212/245/345/221/212-0.5.6.md +0 -260
|
@@ -19,6 +19,15 @@ const PROTECTED_HEADERS_METHODS = new Set([
|
|
|
19
19
|
'message.thought.put',
|
|
20
20
|
'group.thought.put',
|
|
21
21
|
]);
|
|
22
|
+
function generateMessageId() {
|
|
23
|
+
if (typeof crypto.randomUUID === 'function')
|
|
24
|
+
return `m-${crypto.randomUUID().replace(/-/g, '')}`;
|
|
25
|
+
const bytes = new Uint8Array(16);
|
|
26
|
+
crypto.getRandomValues(bytes);
|
|
27
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
28
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
29
|
+
return `m-${Array.from(bytes, (value) => value.toString(16).padStart(2, '0')).join('')}`;
|
|
30
|
+
}
|
|
22
31
|
const SIGNED_METHODS = new Set([
|
|
23
32
|
'message.send',
|
|
24
33
|
'message.v2.put_peer_pk', 'message.v2.bootstrap',
|
|
@@ -71,6 +80,7 @@ const SIGNED_METHODS = new Set([
|
|
|
71
80
|
'group.dissolve', 'group.suspend', 'group.resume',
|
|
72
81
|
]);
|
|
73
82
|
const SIGNING_KEY_CACHE_MAX = 32;
|
|
83
|
+
const IDENTITY_ADMISSION_RETRY_DELAYS_MS = [0, 50, 100, 200];
|
|
74
84
|
const signingKeyCache = new Map();
|
|
75
85
|
const certFingerprintCache = new Map();
|
|
76
86
|
function cacheGet(cache, key) {
|
|
@@ -120,6 +130,13 @@ async function signingCertFingerprint(certPem) {
|
|
|
120
130
|
}
|
|
121
131
|
const PULL_GATE_STALE_MS = 30000;
|
|
122
132
|
const PULL_GATE_OPERATION_TIMEOUT_MS = 3000;
|
|
133
|
+
function sameIdentityAdmissionRejection(error, original) {
|
|
134
|
+
const errorCode = Number(error?.code);
|
|
135
|
+
const originalCode = Number(original?.code);
|
|
136
|
+
const errorMessage = String(error instanceof Error ? error.message : error?.message ?? '').trim().toLowerCase();
|
|
137
|
+
const originalMessage = String(original instanceof Error ? original.message : original?.message ?? '').trim().toLowerCase();
|
|
138
|
+
return errorCode === -32003 && originalCode === -32003 && errorMessage === originalMessage;
|
|
139
|
+
}
|
|
123
140
|
const NON_IDEMPOTENT_TIMEOUT = 35;
|
|
124
141
|
const NON_IDEMPOTENT_METHODS = new Set([
|
|
125
142
|
'message.send', 'mail.send', 'group.send', 'group.create', 'group.invite',
|
|
@@ -170,6 +187,9 @@ export class RpcPipeline {
|
|
|
170
187
|
runtime;
|
|
171
188
|
pullGateStates = new Map();
|
|
172
189
|
inlineRealtimeScopes = new Set();
|
|
190
|
+
pullWorkTokens = new Set();
|
|
191
|
+
pullGeneration = 0;
|
|
192
|
+
pullInvalidationWait = null;
|
|
173
193
|
constructor(runtime) {
|
|
174
194
|
this.runtime = runtime;
|
|
175
195
|
}
|
|
@@ -359,6 +379,9 @@ export class RpcPipeline {
|
|
|
359
379
|
delete p._rpc_background;
|
|
360
380
|
if (method === 'message.send' || method === 'group.send') {
|
|
361
381
|
this.normalizeOutboundMessagePayload(p, method);
|
|
382
|
+
if (!Object.prototype.hasOwnProperty.call(p, 'message_id') || p.message_id == null) {
|
|
383
|
+
p.message_id = generateMessageId();
|
|
384
|
+
}
|
|
362
385
|
}
|
|
363
386
|
this.normalizeGroupCallIdentifier(method, p);
|
|
364
387
|
this.validateOutboundCall(method, p);
|
|
@@ -539,8 +562,8 @@ export class RpcPipeline {
|
|
|
539
562
|
const mode = method === 'message.history' ? 'history' : params.window_mode === 'tail' ? 'tail' : 'forward';
|
|
540
563
|
const cursor = mode === 'history'
|
|
541
564
|
? `before=${String(params.before_seq)}`
|
|
542
|
-
: `after=${String(params.after_seq ?? 0)}
|
|
543
|
-
return `p2p:${client._aid}
|
|
565
|
+
: `after=${String(params.after_seq ?? 0)}`;
|
|
566
|
+
return `p2p:${client._aid}|mode=${mode}|cursor=${cursor}|force=${String(Boolean(params.force))}|limit=${String(params.limit)}`;
|
|
544
567
|
}
|
|
545
568
|
if (method === 'group.pull' || method === 'group.v2.pull' || method === 'group.history') {
|
|
546
569
|
const gid = String(params.group_id ?? params.group_aid ?? '').trim();
|
|
@@ -549,13 +572,17 @@ export class RpcPipeline {
|
|
|
549
572
|
const mode = method === 'group.history' ? 'history' : params.window_mode === 'tail' ? 'tail' : 'forward';
|
|
550
573
|
const cursor = mode === 'history'
|
|
551
574
|
? `before=${String(params.before_seq)}`
|
|
552
|
-
: `after=${String(params.after_seq ?? params.after_message_seq ?? 0)}
|
|
553
|
-
|
|
575
|
+
: `after=${String(params.after_seq ?? params.after_message_seq ?? 0)}`;
|
|
576
|
+
const explicitCursor = this.explicitGroupCursorParams(params);
|
|
577
|
+
const cursorSuffix = Object.keys(explicitCursor).length > 0
|
|
578
|
+
? `|cursor_params=${stableStringify(explicitCursor)}`
|
|
579
|
+
: '';
|
|
580
|
+
return `group:${gid}|mode=${mode}|cursor=${cursor}${cursorSuffix}|force=${String(Boolean(params.force))}|limit=${String(params.limit)}`;
|
|
554
581
|
}
|
|
555
582
|
if (method === 'group.pull_events') {
|
|
556
583
|
const gid = String(params.group_id ?? params.group_aid ?? '').trim();
|
|
557
584
|
return gid
|
|
558
|
-
? `group_event:${gid}|forward|after=${String(params.after_event_seq ?? 0)}|limit=${String(params.limit)}`
|
|
585
|
+
? `group_event:${gid}|mode=forward|cursor=after=${String(params.after_event_seq ?? 0)}|force=${String(Boolean(params.force))}|limit=${String(params.limit)}`
|
|
559
586
|
: '';
|
|
560
587
|
}
|
|
561
588
|
return '';
|
|
@@ -578,8 +605,8 @@ export class RpcPipeline {
|
|
|
578
605
|
if (!state) {
|
|
579
606
|
state = { active: null, foreground: [], background: [], byKey: new Map(), lifecycle: new Map(), watchdog: null };
|
|
580
607
|
this.pullGateStates.set(name, state);
|
|
581
|
-
this.startPullGateWatchdog(state, name);
|
|
582
608
|
}
|
|
609
|
+
this.startPullGateWatchdog(state, name);
|
|
583
610
|
return state;
|
|
584
611
|
}
|
|
585
612
|
pullGateOperationTimeoutMs() {
|
|
@@ -597,6 +624,14 @@ export class RpcPipeline {
|
|
|
597
624
|
state.watchdog = timer;
|
|
598
625
|
timer.unref?.();
|
|
599
626
|
}
|
|
627
|
+
stopPullGateWatchdogs() {
|
|
628
|
+
for (const state of this.pullGateStates.values()) {
|
|
629
|
+
if (state.watchdog === null)
|
|
630
|
+
continue;
|
|
631
|
+
clearInterval(state.watchdog);
|
|
632
|
+
state.watchdog = null;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
600
635
|
checkPullGate(state, name) {
|
|
601
636
|
const active = state.active;
|
|
602
637
|
if (!active) {
|
|
@@ -608,18 +643,12 @@ export class RpcPipeline {
|
|
|
608
643
|
if (active.timedOut)
|
|
609
644
|
return;
|
|
610
645
|
active.timedOut = true;
|
|
646
|
+
active.invalidated = true;
|
|
647
|
+
this.pullGeneration += 1;
|
|
611
648
|
active.cancel?.();
|
|
612
649
|
const err = new TimeoutError(`pull gate timeout: ${active.namespace}`, { retryable: true });
|
|
613
650
|
this.runtime.client._clientLog?.warn(`pull gate watchdog timeout: gate=${name} key=${active.key}`);
|
|
614
|
-
state.lifecycle.set(active.namespace, 'idle');
|
|
615
|
-
if (state.active === active)
|
|
616
|
-
state.active = null;
|
|
617
|
-
if (state.byKey.get(active.key) === active)
|
|
618
|
-
state.byKey.delete(active.key);
|
|
619
|
-
active.resolve = () => { };
|
|
620
651
|
active.reject(err);
|
|
621
|
-
this.drainPullGate(state);
|
|
622
|
-
this.runtime.client._delivery?.onPullGateIdle?.(active.namespace);
|
|
623
652
|
}
|
|
624
653
|
realtimePullNamespace(key) {
|
|
625
654
|
for (const marker of ['|tail|', '|forward|']) {
|
|
@@ -640,7 +669,7 @@ export class RpcPipeline {
|
|
|
640
669
|
return request;
|
|
641
670
|
const state = this.pullGateStates.get(this.pullGateName(key));
|
|
642
671
|
const active = state?.active;
|
|
643
|
-
if (!active || active.
|
|
672
|
+
if (!active || active.key !== key || active.timedOut || active.invalidated)
|
|
644
673
|
return request;
|
|
645
674
|
const boundCancel = () => cancel.call(request);
|
|
646
675
|
active.cancel = boundCancel;
|
|
@@ -706,6 +735,32 @@ export class RpcPipeline {
|
|
|
706
735
|
const matches = (job) => job !== null && job.namespace === ns;
|
|
707
736
|
return matches(state.active) || state.foreground.some(matches) || state.background.some(matches);
|
|
708
737
|
}
|
|
738
|
+
hasAnyPullActivity() {
|
|
739
|
+
if (this.pullWorkTokens.size > 0)
|
|
740
|
+
return true;
|
|
741
|
+
for (const state of this.pullGateStates.values()) {
|
|
742
|
+
if (state.active || state.foreground.length > 0 || state.background.length > 0)
|
|
743
|
+
return true;
|
|
744
|
+
}
|
|
745
|
+
return false;
|
|
746
|
+
}
|
|
747
|
+
reservePullWork() {
|
|
748
|
+
const token = Symbol('pull-work');
|
|
749
|
+
this.pullWorkTokens.add(token);
|
|
750
|
+
let released = false;
|
|
751
|
+
return () => {
|
|
752
|
+
if (released)
|
|
753
|
+
return;
|
|
754
|
+
released = true;
|
|
755
|
+
this.pullWorkTokens.delete(token);
|
|
756
|
+
this.runtime.client._delivery?.onPullWorkSettled?.();
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
releasePullWorkToken(token) {
|
|
760
|
+
if (!this.pullWorkTokens.delete(token))
|
|
761
|
+
return;
|
|
762
|
+
this.runtime.client._delivery?.onPullWorkSettled?.();
|
|
763
|
+
}
|
|
709
764
|
async tryRunInlineRealtime(ns, seq, operation) {
|
|
710
765
|
const normalized = String(ns ?? '').trim();
|
|
711
766
|
if ((!normalized.startsWith('p2p:') && !normalized.startsWith('group:'))
|
|
@@ -744,7 +799,11 @@ export class RpcPipeline {
|
|
|
744
799
|
resumeResolve: null,
|
|
745
800
|
pullingStartedAt: 0,
|
|
746
801
|
timedOut: false,
|
|
802
|
+
invalidated: false,
|
|
747
803
|
cancel: null,
|
|
804
|
+
settled: Promise.resolve(),
|
|
805
|
+
settledResolve: null,
|
|
806
|
+
workToken: Symbol('inline-pull-work'),
|
|
748
807
|
};
|
|
749
808
|
this.inlineRealtimeScopes.add(normalized);
|
|
750
809
|
try {
|
|
@@ -791,17 +850,77 @@ export class RpcPipeline {
|
|
|
791
850
|
gate.inflight = false;
|
|
792
851
|
gate.startedAt = 0;
|
|
793
852
|
}
|
|
853
|
+
isPullGenerationCurrent(generation) {
|
|
854
|
+
return generation === this.pullGeneration;
|
|
855
|
+
}
|
|
856
|
+
invalidatePulls() {
|
|
857
|
+
if (this.pullInvalidationWait)
|
|
858
|
+
return this.pullInvalidationWait;
|
|
859
|
+
this.pullGeneration += 1;
|
|
860
|
+
const error = new Error('pull invalidated');
|
|
861
|
+
const waits = [];
|
|
862
|
+
for (const state of this.pullGateStates.values()) {
|
|
863
|
+
const jobs = new Set();
|
|
864
|
+
if (state.active)
|
|
865
|
+
jobs.add(state.active);
|
|
866
|
+
for (const job of state.foreground)
|
|
867
|
+
jobs.add(job);
|
|
868
|
+
for (const job of state.background)
|
|
869
|
+
jobs.add(job);
|
|
870
|
+
for (const job of jobs) {
|
|
871
|
+
job.invalidated = true;
|
|
872
|
+
if (!job.timedOut)
|
|
873
|
+
job.reject(error);
|
|
874
|
+
job.cancel?.();
|
|
875
|
+
job.resumeResolve?.();
|
|
876
|
+
job.resumeResolve = null;
|
|
877
|
+
if (job.running) {
|
|
878
|
+
waits.push(job.settled);
|
|
879
|
+
}
|
|
880
|
+
else {
|
|
881
|
+
this.releasePullWorkToken(job.workToken);
|
|
882
|
+
job.settledResolve?.();
|
|
883
|
+
job.settledResolve = null;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
state.foreground = state.foreground.filter((job) => !jobs.has(job));
|
|
887
|
+
state.background = state.background.filter((job) => !jobs.has(job));
|
|
888
|
+
for (const [key, job] of state.byKey.entries()) {
|
|
889
|
+
if (jobs.has(job) && !job.running)
|
|
890
|
+
state.byKey.delete(key);
|
|
891
|
+
}
|
|
892
|
+
this.drainPullGate(state);
|
|
893
|
+
}
|
|
894
|
+
const wait = Promise.all(waits).then(() => undefined);
|
|
895
|
+
this.runtime.client._delivery?.onPullWorkSettled?.();
|
|
896
|
+
let tracked;
|
|
897
|
+
tracked = wait.finally(() => {
|
|
898
|
+
if (this.pullInvalidationWait === tracked)
|
|
899
|
+
this.pullInvalidationWait = null;
|
|
900
|
+
});
|
|
901
|
+
this.pullInvalidationWait = tracked;
|
|
902
|
+
return tracked;
|
|
903
|
+
}
|
|
904
|
+
pullInvalidationInProgress() {
|
|
905
|
+
return this.pullInvalidationWait !== null;
|
|
906
|
+
}
|
|
794
907
|
async runPullSerialized(key, operation, background = false) {
|
|
795
|
-
if (
|
|
796
|
-
|
|
908
|
+
if (this.pullInvalidationInProgress()) {
|
|
909
|
+
throw new Error('pull invalidated');
|
|
910
|
+
}
|
|
911
|
+
if (!key) {
|
|
912
|
+
const releasePullWork = this.reservePullWork();
|
|
913
|
+
try {
|
|
914
|
+
return await this.executePullOperation(operation, background);
|
|
915
|
+
}
|
|
916
|
+
finally {
|
|
917
|
+
releasePullWork();
|
|
918
|
+
}
|
|
919
|
+
}
|
|
797
920
|
const state = this.pullGateState(key);
|
|
798
921
|
const namespace = this.pullScopeKey(key);
|
|
799
|
-
const
|
|
800
|
-
const
|
|
801
|
-
const queuedBackground = state.background.find((job) => job.namespace === namespace);
|
|
802
|
-
const existing = background
|
|
803
|
-
? (active ?? queuedForeground ?? queuedBackground)
|
|
804
|
-
: (queuedForeground ?? (active && !active.background ? active : null) ?? queuedBackground);
|
|
922
|
+
const candidate = state.byKey.get(key);
|
|
923
|
+
const existing = candidate && !candidate.timedOut && !candidate.invalidated ? candidate : null;
|
|
805
924
|
if (existing) {
|
|
806
925
|
if (!background && existing.background && existing !== state.active) {
|
|
807
926
|
const index = state.background.indexOf(existing);
|
|
@@ -812,16 +931,24 @@ export class RpcPipeline {
|
|
|
812
931
|
}
|
|
813
932
|
return await existing.promise;
|
|
814
933
|
}
|
|
934
|
+
const workToken = Symbol('pull-work');
|
|
935
|
+
this.pullWorkTokens.add(workToken);
|
|
815
936
|
let resolve;
|
|
816
937
|
let reject;
|
|
938
|
+
let settledResolve;
|
|
817
939
|
const promise = new Promise((res, rej) => { resolve = res; reject = rej; });
|
|
940
|
+
const settled = new Promise((resolveSettled) => { settledResolve = resolveSettled; });
|
|
818
941
|
void promise.catch(() => { });
|
|
819
942
|
const job = {
|
|
820
943
|
key, namespace, background, running: false, suspended: false, operation, promise, resolve, reject, timer: null,
|
|
821
944
|
resume: null, resumeResolve: null,
|
|
822
945
|
pullingStartedAt: 0,
|
|
823
946
|
timedOut: false,
|
|
947
|
+
invalidated: false,
|
|
824
948
|
cancel: null,
|
|
949
|
+
settled,
|
|
950
|
+
settledResolve,
|
|
951
|
+
workToken,
|
|
825
952
|
};
|
|
826
953
|
(background ? state.background : state.foreground).push(job);
|
|
827
954
|
state.byKey.set(key, job);
|
|
@@ -830,18 +957,36 @@ export class RpcPipeline {
|
|
|
830
957
|
return await promise;
|
|
831
958
|
}
|
|
832
959
|
async executePullOperation(operation, background) {
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
960
|
+
const client = this.runtime.client;
|
|
961
|
+
const hadPrevious = Object.prototype.hasOwnProperty.call(client, '_pullOperationGeneration');
|
|
962
|
+
const previous = client._pullOperationGeneration;
|
|
963
|
+
client._pullOperationGeneration = this.pullGeneration;
|
|
964
|
+
try {
|
|
965
|
+
if (background)
|
|
966
|
+
return await client._withBackgroundRpc(operation);
|
|
967
|
+
return await operation();
|
|
968
|
+
}
|
|
969
|
+
finally {
|
|
970
|
+
if (hadPrevious)
|
|
971
|
+
client._pullOperationGeneration = previous;
|
|
972
|
+
else
|
|
973
|
+
delete client._pullOperationGeneration;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
pullOperationIsCurrent() {
|
|
977
|
+
const generation = this.runtime.client._pullOperationGeneration;
|
|
978
|
+
return generation === undefined || this.isPullGenerationCurrent(generation);
|
|
979
|
+
}
|
|
980
|
+
throwIfPullInvalidated() {
|
|
981
|
+
if (!this.pullOperationIsCurrent())
|
|
982
|
+
throw new Error('pull invalidated');
|
|
836
983
|
}
|
|
837
984
|
async yieldPullGate(key, nextKey, background) {
|
|
838
985
|
if (!key)
|
|
839
986
|
return;
|
|
840
987
|
const state = this.pullGateState(key);
|
|
841
988
|
const namespace = this.pullScopeKey(key);
|
|
842
|
-
const job = state.active?.
|
|
843
|
-
? state.active
|
|
844
|
-
: [...state.foreground, ...state.background].find((candidate) => candidate.namespace === namespace);
|
|
989
|
+
const job = state.active?.key === key ? state.active : null;
|
|
845
990
|
if (!job || state.active !== job)
|
|
846
991
|
return;
|
|
847
992
|
const replacementKey = String(nextKey || key);
|
|
@@ -858,8 +1003,11 @@ export class RpcPipeline {
|
|
|
858
1003
|
state.active = null;
|
|
859
1004
|
(job.background ? state.background : state.foreground).push(job);
|
|
860
1005
|
this.drainPullGate(state);
|
|
861
|
-
if (job.resume)
|
|
1006
|
+
if (job.resume) {
|
|
862
1007
|
await job.resume;
|
|
1008
|
+
if (job.invalidated)
|
|
1009
|
+
throw new Error('pull invalidated');
|
|
1010
|
+
}
|
|
863
1011
|
}
|
|
864
1012
|
getPullLifecycle(namespace) {
|
|
865
1013
|
const ns = this.pullScopeKey(namespace);
|
|
@@ -901,16 +1049,21 @@ export class RpcPipeline {
|
|
|
901
1049
|
return;
|
|
902
1050
|
}
|
|
903
1051
|
job.running = true;
|
|
904
|
-
void this.executePullOperation(job.operation, job.background).then(job.
|
|
905
|
-
if (job.timedOut)
|
|
906
|
-
|
|
1052
|
+
void this.executePullOperation(job.operation, job.background).then((value) => { if (!job.timedOut && !job.invalidated)
|
|
1053
|
+
job.resolve(value); }, (error) => { if (!job.timedOut && !job.invalidated)
|
|
1054
|
+
job.reject(error); }).finally(() => {
|
|
1055
|
+
this.pullWorkTokens.delete(job.workToken);
|
|
907
1056
|
state.lifecycle.set(job.namespace, 'idle');
|
|
908
1057
|
if (state.active === job)
|
|
909
1058
|
state.active = null;
|
|
910
1059
|
if (state.byKey.get(job.key) === job)
|
|
911
1060
|
state.byKey.delete(job.key);
|
|
912
1061
|
this.drainPullGate(state);
|
|
913
|
-
|
|
1062
|
+
job.settledResolve?.();
|
|
1063
|
+
job.settledResolve = null;
|
|
1064
|
+
if (!job.invalidated)
|
|
1065
|
+
this.runtime.client._delivery?.onPullGateIdle?.(job.namespace);
|
|
1066
|
+
this.runtime.client._delivery?.onPullWorkSettled?.();
|
|
914
1067
|
});
|
|
915
1068
|
}
|
|
916
1069
|
armQueuedPullTimers(_state) { }
|
|
@@ -936,7 +1089,9 @@ export class RpcPipeline {
|
|
|
936
1089
|
request = client._transport.call(method, payload);
|
|
937
1090
|
return this.bindActivePullCancellation(method, payload, request);
|
|
938
1091
|
};
|
|
939
|
-
|
|
1092
|
+
const result = await this.transportCallWithIdentityRecovery(invokeTransport, method, payload);
|
|
1093
|
+
this.throwIfPullInvalidated();
|
|
1094
|
+
return result;
|
|
940
1095
|
}
|
|
941
1096
|
async transportCallWithIdentityRecovery(operation, method, params) {
|
|
942
1097
|
try {
|
|
@@ -946,11 +1101,25 @@ export class RpcPipeline {
|
|
|
946
1101
|
const recover = this.runtime.client._recoverIdentityAdmission;
|
|
947
1102
|
if (typeof recover !== 'function' || !await recover.call(this.runtime.client, err, method, params))
|
|
948
1103
|
throw err;
|
|
949
|
-
|
|
1104
|
+
let lastError = err;
|
|
1105
|
+
for (const delay of IDENTITY_ADMISSION_RETRY_DELAYS_MS) {
|
|
1106
|
+
if (delay > 0)
|
|
1107
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
1108
|
+
try {
|
|
1109
|
+
return await operation();
|
|
1110
|
+
}
|
|
1111
|
+
catch (retryError) {
|
|
1112
|
+
if (!sameIdentityAdmissionRejection(retryError, err))
|
|
1113
|
+
throw retryError;
|
|
1114
|
+
lastError = retryError;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
throw lastError;
|
|
950
1118
|
}
|
|
951
1119
|
}
|
|
952
1120
|
async postprocessResult(method, params, result, options = {}) {
|
|
953
1121
|
const client = this.runtime.client;
|
|
1122
|
+
this.throwIfPullInvalidated();
|
|
954
1123
|
let next = result;
|
|
955
1124
|
if ((method === 'group.send' || method === 'group.v2.send') && isJsonObject(next)) {
|
|
956
1125
|
next = normalizeGroupMentionMode(next);
|