@agentunion/fastaun-browser 0.5.18 → 0.5.19
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 +44 -2
- package/_packed_docs/CHANGELOG.md +44 -2
- package/_packed_docs/INDEX.md +136 -14
- package/_packed_docs/KITE_DOCS_GUIDE.md +42 -16
- package/_packed_docs/agent.md/SCHEMA.md +245 -205
- package/_packed_docs/aun/345/210/206/345/270/203/345/274/217/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +42 -15
- package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +4 -4
- package/_packed_docs/protocol/01-/350/272/253/344/273/275/344/270/216/345/207/255/350/257/201/345/215/217/350/256/256-auth.md +45 -134
- package/_packed_docs/protocol/07-/351/224/231/350/257/257/347/240/201/344/270/216/347/212/266/346/200/201/346/234/272.md +5 -20
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +28 -9
- package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +22 -27
- package/_packed_docs/protocol/agent.md/SCHEMA.md +4 -0
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +5 -2
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +250 -283
- package/_packed_docs/sdk/09-group-rpc-manual.md +46 -14
- package/_packed_docs/sdk/09-message-rpc-manual.md +40 -2
- package/_packed_docs/sdk/09-storage-rpc-manual.md +74 -64
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +25 -5
- package/_packed_docs/sdk/INDEX.md +76 -17
- package/dist/agent-md-schema.d.ts +3 -0
- package/dist/agent-md-schema.d.ts.map +1 -1
- package/dist/agent-md-schema.js +45 -11
- package/dist/agent-md-schema.js.map +1 -1
- package/dist/agent-md.d.ts +45 -2
- package/dist/agent-md.d.ts.map +1 -1
- package/dist/agent-md.js +519 -30
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.d.ts +12 -46
- package/dist/aid-store.d.ts.map +1 -1
- package/dist/aid-store.js +113 -246
- package/dist/aid-store.js.map +1 -1
- package/dist/aid.d.ts.map +1 -1
- package/dist/aid.js +20 -7
- package/dist/aid.js.map +1 -1
- package/dist/auth.d.ts +4 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +343 -23
- package/dist/auth.js.map +1 -1
- package/dist/bundle.js +37330 -32005
- package/dist/cert-utils.d.ts +1 -1
- package/dist/cert-utils.d.ts.map +1 -1
- package/dist/cert-utils.js +19 -7
- package/dist/cert-utils.js.map +1 -1
- package/dist/client/delivery.d.ts +15 -1
- package/dist/client/delivery.d.ts.map +1 -1
- package/dist/client/delivery.js +147 -51
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts.map +1 -1
- package/dist/client/rpc-pipeline.js +19 -5
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +1 -0
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +104 -30
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +100 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +1204 -23
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +3 -2
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +4 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +41 -1
- package/dist/events.js.map +1 -1
- package/dist/facades.d.ts +82 -2
- package/dist/facades.d.ts.map +1 -1
- package/dist/facades.js +98 -4
- package/dist/facades.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/keystore/index.d.ts +17 -0
- package/dist/keystore/index.d.ts.map +1 -1
- package/dist/keystore/indexeddb-shared.d.ts +10 -1
- package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
- package/dist/keystore/indexeddb-shared.js +111 -0
- package/dist/keystore/indexeddb-shared.js.map +1 -1
- package/dist/keystore/indexeddb-token-store.d.ts +7 -1
- package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-token-store.js +30 -1
- package/dist/keystore/indexeddb-token-store.js.map +1 -1
- package/dist/org-protocol.d.ts +98 -0
- package/dist/org-protocol.d.ts.map +1 -0
- package/dist/org-protocol.js +1742 -0
- package/dist/org-protocol.js.map +1 -0
- package/dist/ownership-proof.d.ts +93 -5
- package/dist/ownership-proof.d.ts.map +1 -1
- package/dist/ownership-proof.js +239 -53
- package/dist/ownership-proof.js.map +1 -1
- package/dist/ownership-v21.d.ts +177 -0
- package/dist/ownership-v21.d.ts.map +1 -0
- package/dist/ownership-v21.js +609 -0
- package/dist/ownership-v21.js.map +1 -0
- package/dist/ownership-workflow.d.ts +146 -0
- package/dist/ownership-workflow.d.ts.map +1 -0
- package/dist/ownership-workflow.js +1066 -0
- package/dist/ownership-workflow.js.map +1 -0
- package/dist/seq-tracker.d.ts +1 -0
- package/dist/seq-tracker.d.ts.map +1 -1
- package/dist/seq-tracker.js +10 -2
- package/dist/seq-tracker.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +82 -0
- package/dist/tools/cross-sdk-agent.d.ts.map +1 -1
- package/dist/tools/cross-sdk-agent.js +332 -7
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +6 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +88 -2
- package/dist/transport.js.map +1 -1
- package/dist/v2/e2ee/decrypt.d.ts +1 -0
- package/dist/v2/e2ee/decrypt.d.ts.map +1 -1
- package/dist/v2/e2ee/decrypt.js +9 -1
- package/dist/v2/e2ee/decrypt.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/client/v2-e2ee.js
CHANGED
|
@@ -1000,11 +1000,12 @@ export class V2E2EECoordinator {
|
|
|
1000
1000
|
client._clientLog.debug(`V2 sender IK pending retry delivered: key=${key}`);
|
|
1001
1001
|
continue;
|
|
1002
1002
|
}
|
|
1003
|
-
client._v2SenderIKPending.delete(key);
|
|
1004
1003
|
const seq = Number(entry.msg.seq ?? 0);
|
|
1005
1004
|
if (entry.groupId) {
|
|
1006
|
-
if (client._delivery.isSelfSentGroupMessage?.(entry.msg))
|
|
1005
|
+
if (client._delivery.isSelfSentGroupMessage?.(entry.msg)) {
|
|
1006
|
+
client._v2SenderIKPending.delete(key);
|
|
1007
1007
|
continue;
|
|
1008
|
+
}
|
|
1008
1009
|
plaintext = normalizeGroupMentionMode(plaintext, entry.msg, entry.msg.envelope_json);
|
|
1009
1010
|
plaintext.group_id = entry.groupId;
|
|
1010
1011
|
await client._publishPulledMessage('group.message_created', `group:${entry.groupId}`, seq, plaintext, false, 'pending_retry');
|
|
@@ -1012,6 +1013,7 @@ export class V2E2EECoordinator {
|
|
|
1012
1013
|
else {
|
|
1013
1014
|
await client._publishPulledMessage('message.received', `p2p:${client._aid ?? ''}`, seq, plaintext, false, 'pending_retry');
|
|
1014
1015
|
}
|
|
1016
|
+
client._v2SenderIKPending.delete(key);
|
|
1015
1017
|
client._clientLog.debug(`V2 sender IK pending retry delivered: key=${key}`);
|
|
1016
1018
|
}
|
|
1017
1019
|
}
|
|
@@ -1110,6 +1112,12 @@ export class V2E2EECoordinator {
|
|
|
1110
1112
|
history_error: { code: 'decrypt_failed', message: reason },
|
|
1111
1113
|
};
|
|
1112
1114
|
}
|
|
1115
|
+
ensureDeliveryCurrent(ns, generation, inlineGeneration) {
|
|
1116
|
+
if (Number(this.client._v2RuntimeGeneration ?? 0) !== generation
|
|
1117
|
+
|| (inlineGeneration !== undefined && !this.client._delivery.isInlineGenerationCurrent(inlineGeneration))
|
|
1118
|
+
|| this.client._rpcPipeline?.isPullNamespaceCurrent?.(ns) === false)
|
|
1119
|
+
throw new StateError('pull invalidated');
|
|
1120
|
+
}
|
|
1113
1121
|
async decodeP2PWindowMessage(msg, publish, history, source, orderedPublish = false) {
|
|
1114
1122
|
const client = this.client;
|
|
1115
1123
|
const seq = strictWindowSeq(msg.seq, 'messages[].seq', true);
|
|
@@ -1257,6 +1265,8 @@ export class V2E2EECoordinator {
|
|
|
1257
1265
|
}
|
|
1258
1266
|
async pullV2TailInternal(params, deferPublish = false) {
|
|
1259
1267
|
const client = this.client;
|
|
1268
|
+
const generation = Number(client._v2RuntimeGeneration ?? 0);
|
|
1269
|
+
const inlineGeneration = client._delivery.captureInlineGeneration?.();
|
|
1260
1270
|
if (params.window_mode !== 'tail')
|
|
1261
1271
|
throw new ValidationError('window_mode must equal tail');
|
|
1262
1272
|
if ('ack_up_to_seq' in params || params.force === true)
|
|
@@ -1271,19 +1281,27 @@ export class V2E2EECoordinator {
|
|
|
1271
1281
|
}, `${ns}|tail|after=${afterSeq}|limit=${limit}`);
|
|
1272
1282
|
const result = await client._callRawV2Rpc('message.v2.pull', { window_mode: 'tail', after_seq: afterSeq, limit, _rpc_foreground: true }, pullGateKey);
|
|
1273
1283
|
const page = validateTailPage(result, afterSeq, limit);
|
|
1274
|
-
if (ns) {
|
|
1275
|
-
client._seqTracker.commitTailWindow(ns, {
|
|
1276
|
-
windowStartSeq: page.windowStart, headSeq: page.head, coveredThroughSeq: page.head, pageLimit: limit,
|
|
1277
|
-
});
|
|
1278
|
-
client._persistSeq(ns);
|
|
1279
|
-
await client._saveSeqTrackerState?.();
|
|
1280
|
-
}
|
|
1281
1284
|
const decoded = [];
|
|
1282
1285
|
for (const msg of page.messages) {
|
|
1286
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
1283
1287
|
const plaintext = await this.decodeP2PWindowMessage(msg, true, false, 'tail', deferPublish);
|
|
1284
1288
|
if (plaintext)
|
|
1285
1289
|
decoded.push(plaintext);
|
|
1286
1290
|
}
|
|
1291
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
1292
|
+
if (ns) {
|
|
1293
|
+
const proof = {
|
|
1294
|
+
windowStartSeq: page.windowStart, headSeq: page.head, coveredThroughSeq: page.head, pageLimit: limit,
|
|
1295
|
+
};
|
|
1296
|
+
if (deferPublish)
|
|
1297
|
+
client._delivery.deferTailWindow(ns, proof);
|
|
1298
|
+
else {
|
|
1299
|
+
client._seqTracker.commitTailWindow(ns, proof);
|
|
1300
|
+
client._persistSeq(ns);
|
|
1301
|
+
await client._saveSeqTrackerState?.();
|
|
1302
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1287
1305
|
const ack = ns ? client._seqTracker.getContiguousSeq(ns) : 0;
|
|
1288
1306
|
if (ns)
|
|
1289
1307
|
client._delivery.onPullPage?.(ns, decoded.length, result.has_more === true, page.head, typeof result.remaining === 'number' && Number.isSafeInteger(result.remaining) && result.remaining >= 0 ? result.remaining : null, page.messages.length, ack, page.head);
|
|
@@ -1320,6 +1338,8 @@ export class V2E2EECoordinator {
|
|
|
1320
1338
|
}
|
|
1321
1339
|
async pullV2Impl(afterSeq = 0, limit = 50, opts) {
|
|
1322
1340
|
const client = this.client;
|
|
1341
|
+
const generation = Number(client._v2RuntimeGeneration ?? 0);
|
|
1342
|
+
const inlineGeneration = client._delivery.captureInlineGeneration?.();
|
|
1323
1343
|
await client._ensureV2SessionReady('message.pull');
|
|
1324
1344
|
const ns = client._aid ? `p2p:${client._aid}` : '';
|
|
1325
1345
|
let volatileCursor = String(opts?.afterVolatileCursor ?? client._delivery.volatilePullCursor() ?? '').trim();
|
|
@@ -1365,6 +1385,7 @@ export class V2E2EECoordinator {
|
|
|
1365
1385
|
const pipelineQueue = new V2PullPageQueue(V2_PULL_PIPELINE_QUEUE_CAPACITY);
|
|
1366
1386
|
let pipelineProducer = null;
|
|
1367
1387
|
let pipelineStopped = false;
|
|
1388
|
+
let pipelineResume = null;
|
|
1368
1389
|
const startPipeline = (startAfterSeq, startVolatileCursor) => {
|
|
1369
1390
|
if (pipelineRunning || pageCount >= maxPages || limit < V2_PULL_MAX_PAGE_LIMIT)
|
|
1370
1391
|
return;
|
|
@@ -1385,6 +1406,7 @@ export class V2E2EECoordinator {
|
|
|
1385
1406
|
if (pipelineStopped)
|
|
1386
1407
|
break;
|
|
1387
1408
|
const rawPageMessages = (Array.isArray(result?.messages) ? result.messages : []);
|
|
1409
|
+
const completed = new Promise((resolve) => { pipelineResume = resolve; });
|
|
1388
1410
|
const enqueued = await pipelineQueue.put({
|
|
1389
1411
|
result,
|
|
1390
1412
|
afterSeq: producerAfterSeq,
|
|
@@ -1395,6 +1417,9 @@ export class V2E2EECoordinator {
|
|
|
1395
1417
|
}, rawPageMessages.length);
|
|
1396
1418
|
if (!enqueued || pipelineStopped)
|
|
1397
1419
|
break;
|
|
1420
|
+
await completed;
|
|
1421
|
+
if (pipelineStopped)
|
|
1422
|
+
break;
|
|
1398
1423
|
const volatileMessages = client._delivery.volatileMessages(rawPageMessages);
|
|
1399
1424
|
if (volatileMessages.length > 0)
|
|
1400
1425
|
break;
|
|
@@ -1429,6 +1454,8 @@ export class V2E2EECoordinator {
|
|
|
1429
1454
|
};
|
|
1430
1455
|
const stopPipeline = async () => {
|
|
1431
1456
|
pipelineStopped = true;
|
|
1457
|
+
pipelineResume?.();
|
|
1458
|
+
pipelineResume = null;
|
|
1432
1459
|
pipelineQueue.close();
|
|
1433
1460
|
if (pipelineProducer) {
|
|
1434
1461
|
const producer = pipelineProducer;
|
|
@@ -1514,9 +1541,7 @@ export class V2E2EECoordinator {
|
|
|
1514
1541
|
.map((msg) => Number(msg.seq ?? 0))
|
|
1515
1542
|
.filter((seq) => Number.isFinite(seq) && seq > 0);
|
|
1516
1543
|
const pageContigBefore = ns ? client._seqTracker.getContiguousSeq(ns) : 0;
|
|
1517
|
-
|
|
1518
|
-
? client._seqTracker.snapshotNamespace(ns)
|
|
1519
|
-
: null;
|
|
1544
|
+
let pageTrackerSnapshot;
|
|
1520
1545
|
const pageMaxSeq = seqs.length > 0 ? Math.max(...seqs) : nextAfterSeq;
|
|
1521
1546
|
const pageContiguousSeq = contiguousPullSeq(pageContigBefore, seqs, result.contiguous_seq);
|
|
1522
1547
|
const deferredKeyFetches = new Map();
|
|
@@ -1622,10 +1647,18 @@ export class V2E2EECoordinator {
|
|
|
1622
1647
|
const serverAckSeq = parsedServerAckSeq ?? 0;
|
|
1623
1648
|
const retentionFloor = Math.max(0, Number(result.retention_floor_seq ?? 0));
|
|
1624
1649
|
if (ns) {
|
|
1625
|
-
|
|
1650
|
+
let commitTarget = Math.max(pageContigBefore, Number.isFinite(retentionFloor) ? retentionFloor : 0, pageCount === 1 ? deferredServerCursor : 0, serverAckSeq, blockedSeq > 0 ? blockedSeq - 1 : pageContiguousSeq);
|
|
1651
|
+
commitTarget = client._delivery.pendingTailDeliveryThrough?.(ns, commitTarget) ?? commitTarget;
|
|
1626
1652
|
let ackSeq = pageContigBefore;
|
|
1627
1653
|
let contigAdvanced = false;
|
|
1628
1654
|
try {
|
|
1655
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
1656
|
+
const state = client._seqTracker.getSyncState?.(ns);
|
|
1657
|
+
const deliveryThrough = client._delivery.pendingTailDeliveryThrough?.(ns, state && commitTarget >= state.tail - 1 ? Math.max(commitTarget, state.head) : commitTarget) ?? (state && commitTarget >= state.tail - 1 ? Math.max(commitTarget, state.head) : commitTarget);
|
|
1658
|
+
await client._drainOrderedMessages(ns, undefined, false, false, deliveryThrough);
|
|
1659
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
1660
|
+
pageTrackerSnapshot = client._seqTracker.snapshotNamespace?.(ns);
|
|
1661
|
+
client._delivery.commitPendingTailWindow?.(ns, commitTarget);
|
|
1629
1662
|
if (commitTarget > pageContigBefore) {
|
|
1630
1663
|
client._seqTracker.forceContiguousSeq(ns, commitTarget);
|
|
1631
1664
|
if (retentionFloor > pageContigBefore) {
|
|
@@ -1642,19 +1675,23 @@ export class V2E2EECoordinator {
|
|
|
1642
1675
|
contigAdvanced = ackSeq !== pageContigBefore;
|
|
1643
1676
|
if (contigAdvanced) {
|
|
1644
1677
|
await client._commitSeqTrackerState(ns);
|
|
1678
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
1645
1679
|
if (pageCount === 1 && deferredServerCursor > 0)
|
|
1646
1680
|
this.clearForwardCursor(ns, ackSeq);
|
|
1647
1681
|
}
|
|
1682
|
+
client._delivery.completePendingTailWindow?.(ns);
|
|
1648
1683
|
}
|
|
1649
1684
|
catch (exc) {
|
|
1650
|
-
if (
|
|
1651
|
-
client.
|
|
1685
|
+
if (Number(client._v2RuntimeGeneration ?? 0) === generation
|
|
1686
|
+
&& (inlineGeneration === undefined || client._delivery.isInlineGenerationCurrent(inlineGeneration))
|
|
1687
|
+
&& client._rpcPipeline?.isPullNamespaceCurrent?.(ns) !== false
|
|
1688
|
+
&& pageTrackerSnapshot !== undefined
|
|
1689
|
+
&& typeof client._seqTracker.restoreNamespaceSnapshot === 'function') {
|
|
1690
|
+
client._seqTracker._restoreNamespaceSnapshotPreservingPush(ns, pageTrackerSnapshot);
|
|
1652
1691
|
}
|
|
1653
1692
|
client._clientLog.error?.(`message.v2.pull Forward commit rolled back: ns=${ns} target=${commitTarget} error=${formatE2EEError(exc)}`);
|
|
1654
1693
|
throw exc;
|
|
1655
1694
|
}
|
|
1656
|
-
if (contigAdvanced)
|
|
1657
|
-
await client._drainOrderedMessages(ns, undefined, false, false);
|
|
1658
1695
|
for (const fetch of deferredKeyFetches.values()) {
|
|
1659
1696
|
this.scheduleSenderIKFetch(fetch.fromAid, fetch.senderDeviceId, fetch.groupId);
|
|
1660
1697
|
}
|
|
@@ -1721,6 +1758,10 @@ export class V2E2EECoordinator {
|
|
|
1721
1758
|
});
|
|
1722
1759
|
if (!shouldContinue)
|
|
1723
1760
|
break;
|
|
1761
|
+
if (pipelinePage) {
|
|
1762
|
+
pipelineResume?.();
|
|
1763
|
+
pipelineResume = null;
|
|
1764
|
+
}
|
|
1724
1765
|
if (shouldContinueForPipeline && !volatileAdvanced && !pipelineRunning && limit >= V2_PULL_MAX_PAGE_LIMIT) {
|
|
1725
1766
|
if (pendingAckSeq > 0) {
|
|
1726
1767
|
await this.confirmForwardP2PAck(pendingAckSeq);
|
|
@@ -1965,6 +2006,8 @@ export class V2E2EECoordinator {
|
|
|
1965
2006
|
}
|
|
1966
2007
|
async pullGroupV2TailInternal(params, deferPublish = false) {
|
|
1967
2008
|
const client = this.client;
|
|
2009
|
+
const generation = Number(client._v2RuntimeGeneration ?? 0);
|
|
2010
|
+
const inlineGeneration = client._delivery.captureInlineGeneration?.();
|
|
1968
2011
|
if (params.window_mode !== 'tail')
|
|
1969
2012
|
throw new ValidationError('window_mode must equal tail');
|
|
1970
2013
|
if ('ack_up_to_seq' in params || params.force === true)
|
|
@@ -2000,18 +2043,26 @@ export class V2E2EECoordinator {
|
|
|
2000
2043
|
if (resultAid)
|
|
2001
2044
|
groupAid = resultAid;
|
|
2002
2045
|
const page = validateTailPage(result, afterSeq, limit);
|
|
2003
|
-
client._seqTracker.commitTailWindow(ns, {
|
|
2004
|
-
windowStartSeq: page.windowStart, headSeq: page.head, coveredThroughSeq: page.head, pageLimit: limit,
|
|
2005
|
-
});
|
|
2006
|
-
client._persistSeq(ns);
|
|
2007
|
-
await client._saveSeqTrackerState?.();
|
|
2008
2046
|
const decoded = [];
|
|
2009
2047
|
for (const msg of page.messages) {
|
|
2048
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
2010
2049
|
client._logMessageDebug?.('tail-raw', 'group.v2.pull', 'group.message_created', msg);
|
|
2011
2050
|
const plaintext = await this.decodeGroupWindowMessage(msg, groupId, groupAid, true, false, 'tail', deferPublish);
|
|
2012
2051
|
if (plaintext)
|
|
2013
2052
|
decoded.push(plaintext);
|
|
2014
2053
|
}
|
|
2054
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
2055
|
+
const proof = {
|
|
2056
|
+
windowStartSeq: page.windowStart, headSeq: page.head, coveredThroughSeq: page.head, pageLimit: limit,
|
|
2057
|
+
};
|
|
2058
|
+
if (deferPublish)
|
|
2059
|
+
client._delivery.deferTailWindow(ns, proof);
|
|
2060
|
+
else {
|
|
2061
|
+
client._seqTracker.commitTailWindow(ns, proof);
|
|
2062
|
+
client._persistSeq(ns);
|
|
2063
|
+
await client._saveSeqTrackerState?.();
|
|
2064
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
2065
|
+
}
|
|
2015
2066
|
const ack = client._seqTracker.getContiguousSeq(ns);
|
|
2016
2067
|
if (ownsCursor)
|
|
2017
2068
|
client._delivery.onPullPage?.(ns, decoded.length, result.has_more === true, page.head, typeof result.remaining === 'number' && Number.isSafeInteger(result.remaining) && result.remaining >= 0 ? result.remaining : null, page.messages.length, ack, page.head);
|
|
@@ -2056,6 +2107,8 @@ export class V2E2EECoordinator {
|
|
|
2056
2107
|
}
|
|
2057
2108
|
async pullGroupV2Impl(groupId, afterSeq = 0, limit = 50, opts) {
|
|
2058
2109
|
const client = this.client;
|
|
2110
|
+
const generation = Number(client._v2RuntimeGeneration ?? 0);
|
|
2111
|
+
const inlineGeneration = client._delivery.captureInlineGeneration?.();
|
|
2059
2112
|
await client._ensureV2SessionReady('group.pull');
|
|
2060
2113
|
const gid = String(groupId ?? '').trim();
|
|
2061
2114
|
if (!gid)
|
|
@@ -2117,6 +2170,7 @@ export class V2E2EECoordinator {
|
|
|
2117
2170
|
const pipelineQueue = new V2PullPageQueue(V2_PULL_PIPELINE_QUEUE_CAPACITY);
|
|
2118
2171
|
let pipelineProducer = null;
|
|
2119
2172
|
let pipelineStopped = false;
|
|
2173
|
+
let pipelineResume = null;
|
|
2120
2174
|
const startPipeline = (startAfterSeq) => {
|
|
2121
2175
|
if (pipelineRunning || pageCount >= maxPages || limit < V2_PULL_MAX_PAGE_LIMIT || !ownsCursor)
|
|
2122
2176
|
return;
|
|
@@ -2136,6 +2190,7 @@ export class V2E2EECoordinator {
|
|
|
2136
2190
|
if (pipelineStopped)
|
|
2137
2191
|
break;
|
|
2138
2192
|
const pageMessages = (Array.isArray(result?.messages) ? result.messages : []);
|
|
2193
|
+
const completed = new Promise((resolve) => { pipelineResume = resolve; });
|
|
2139
2194
|
const enqueued = await pipelineQueue.put({
|
|
2140
2195
|
result,
|
|
2141
2196
|
afterSeq: producerAfterSeq,
|
|
@@ -2146,6 +2201,9 @@ export class V2E2EECoordinator {
|
|
|
2146
2201
|
}, pageMessages.length);
|
|
2147
2202
|
if (!enqueued || pipelineStopped)
|
|
2148
2203
|
break;
|
|
2204
|
+
await completed;
|
|
2205
|
+
if (pipelineStopped)
|
|
2206
|
+
break;
|
|
2149
2207
|
const messages = deduplicateForwardPageMessages(pageMessages, producerAfterSeq);
|
|
2150
2208
|
const seqs = messages.map((msg) => Number(msg.seq ?? 0)).filter((seq) => Number.isFinite(seq) && seq > 0);
|
|
2151
2209
|
const nextAfter = Math.max(contiguousPullSeq(producerAfterSeq, seqs, result.contiguous_seq), producerAfterSeq);
|
|
@@ -2174,6 +2232,8 @@ export class V2E2EECoordinator {
|
|
|
2174
2232
|
};
|
|
2175
2233
|
const stopPipeline = async () => {
|
|
2176
2234
|
pipelineStopped = true;
|
|
2235
|
+
pipelineResume?.();
|
|
2236
|
+
pipelineResume = null;
|
|
2177
2237
|
pipelineQueue.close();
|
|
2178
2238
|
if (pipelineProducer) {
|
|
2179
2239
|
const producer = pipelineProducer;
|
|
@@ -2245,9 +2305,7 @@ export class V2E2EECoordinator {
|
|
|
2245
2305
|
.map((msg) => Number(msg.seq ?? 0))
|
|
2246
2306
|
.filter((seq) => Number.isFinite(seq) && seq > 0);
|
|
2247
2307
|
const pageContigBefore = client._seqTracker.getContiguousSeq(ns);
|
|
2248
|
-
|
|
2249
|
-
? client._seqTracker.snapshotNamespace(ns)
|
|
2250
|
-
: null;
|
|
2308
|
+
let pageTrackerSnapshot;
|
|
2251
2309
|
const pageMaxSeq = seqs.length > 0 ? Math.max(...seqs) : nextAfterSeq;
|
|
2252
2310
|
const pageContiguousSeq = contiguousPullSeq(pageContigBefore, seqs, result.contiguous_seq);
|
|
2253
2311
|
const deferredKeyFetches = new Map();
|
|
@@ -2383,11 +2441,19 @@ export class V2E2EECoordinator {
|
|
|
2383
2441
|
const retentionFloor = Math.max(Number(result.retention_floor_message_seq ?? result.retention_floor_seq ?? 0), Number(cursor?.retention_floor_seq ?? 0));
|
|
2384
2442
|
const visibilityFloor = Math.max(0, Math.max(0, Number(result.earliest_available_message_seq ?? 1) - 1), Number(cursor?.join_seq ?? 0));
|
|
2385
2443
|
const effectiveFloor = Math.max(retentionFloor, visibilityFloor);
|
|
2386
|
-
|
|
2444
|
+
let commitTarget = Math.max(pageContigBefore, Number.isFinite(effectiveFloor) ? effectiveFloor : 0, ownsCursor && pageCount === 1 ? deferredServerCursor : 0, cursorCurrentSeq, blockedSeq > 0 ? blockedSeq - 1 : pageContiguousSeq);
|
|
2445
|
+
commitTarget = client._delivery.pendingTailDeliveryThrough?.(ns, commitTarget) ?? commitTarget;
|
|
2387
2446
|
let ackSeq = pageContigBefore;
|
|
2388
2447
|
let contigAdvanced = false;
|
|
2389
2448
|
if (ownsCursor) {
|
|
2390
2449
|
try {
|
|
2450
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
2451
|
+
const state = client._seqTracker.getSyncState?.(ns);
|
|
2452
|
+
const deliveryThrough = client._delivery.pendingTailDeliveryThrough?.(ns, state && commitTarget >= state.tail - 1 ? Math.max(commitTarget, state.head) : commitTarget) ?? (state && commitTarget >= state.tail - 1 ? Math.max(commitTarget, state.head) : commitTarget);
|
|
2453
|
+
await client._drainOrderedMessages(ns, undefined, false, false, deliveryThrough);
|
|
2454
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
2455
|
+
pageTrackerSnapshot = client._seqTracker.snapshotNamespace?.(ns);
|
|
2456
|
+
client._delivery.commitPendingTailWindow?.(ns, commitTarget);
|
|
2391
2457
|
if (commitTarget > pageContigBefore) {
|
|
2392
2458
|
client._seqTracker.forceContiguousSeq(ns, commitTarget);
|
|
2393
2459
|
if (effectiveFloor > pageContigBefore) {
|
|
@@ -2404,19 +2470,23 @@ export class V2E2EECoordinator {
|
|
|
2404
2470
|
contigAdvanced = ackSeq !== pageContigBefore;
|
|
2405
2471
|
if (contigAdvanced) {
|
|
2406
2472
|
await client._commitSeqTrackerState(ns);
|
|
2473
|
+
this.ensureDeliveryCurrent(ns, generation, inlineGeneration);
|
|
2407
2474
|
if (pageCount === 1 && deferredServerCursor > 0)
|
|
2408
2475
|
this.clearForwardCursor(ns, ackSeq);
|
|
2409
2476
|
}
|
|
2477
|
+
client._delivery.completePendingTailWindow?.(ns);
|
|
2410
2478
|
}
|
|
2411
2479
|
catch (exc) {
|
|
2412
|
-
if (
|
|
2413
|
-
client.
|
|
2480
|
+
if (Number(client._v2RuntimeGeneration ?? 0) === generation
|
|
2481
|
+
&& (inlineGeneration === undefined || client._delivery.isInlineGenerationCurrent(inlineGeneration))
|
|
2482
|
+
&& client._rpcPipeline?.isPullNamespaceCurrent?.(ns) !== false
|
|
2483
|
+
&& pageTrackerSnapshot !== undefined
|
|
2484
|
+
&& typeof client._seqTracker.restoreNamespaceSnapshot === 'function') {
|
|
2485
|
+
client._seqTracker._restoreNamespaceSnapshotPreservingPush(ns, pageTrackerSnapshot);
|
|
2414
2486
|
}
|
|
2415
2487
|
client._clientLog.error?.(`group.v2.pull Forward commit rolled back: group=${gid} ns=${ns} target=${commitTarget} error=${formatE2EEError(exc)}`);
|
|
2416
2488
|
throw exc;
|
|
2417
2489
|
}
|
|
2418
|
-
if (contigAdvanced)
|
|
2419
|
-
await client._drainOrderedMessages(ns, undefined, false, false);
|
|
2420
2490
|
}
|
|
2421
2491
|
for (const fetch of deferredKeyFetches.values()) {
|
|
2422
2492
|
this.scheduleSenderIKFetch(fetch.fromAid, fetch.senderDeviceId, fetch.groupId);
|
|
@@ -2480,6 +2550,10 @@ export class V2E2EECoordinator {
|
|
|
2480
2550
|
});
|
|
2481
2551
|
if (!shouldContinue)
|
|
2482
2552
|
break;
|
|
2553
|
+
if (pipelinePage) {
|
|
2554
|
+
pipelineResume?.();
|
|
2555
|
+
pipelineResume = null;
|
|
2556
|
+
}
|
|
2483
2557
|
if (shouldContinueForPipeline && !pipelineRunning && limit >= V2_PULL_MAX_PAGE_LIMIT) {
|
|
2484
2558
|
if (pendingAckSeq > 0) {
|
|
2485
2559
|
await this.confirmForwardGroupAck(gid, pendingAckSeq, groupAid);
|