@agentunion/fastaun-browser 0.5.2 → 0.5.4
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 +74 -0
- package/_packed_docs/CHANGELOG.md +74 -0
- package/_packed_docs/INDEX.md +16 -10
- package/_packed_docs/KITE_DOCS_GUIDE.md +4 -2
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +202 -75
- package/_packed_docs/protocol/README.md +3 -2
- package/_packed_docs/protocol/aun-docs-guide.md +3 -2
- package/_packed_docs/protocol/index.md +6 -5
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +20 -1
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +303 -28
- package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +30 -6
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +28 -12
- package/_packed_docs/sdk/09-group-rpc-manual.md +126 -42
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +6 -4
- package/_packed_docs/sdk/INDEX.md +17 -17
- package/dist/bundle.js +1084 -296
- package/dist/client/delivery.d.ts +4 -0
- package/dist/client/delivery.d.ts.map +1 -1
- package/dist/client/delivery.js +174 -7
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/v2-e2ee.js +2 -2
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +27 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +118 -12
- package/dist/client.js.map +1 -1
- package/dist/facades.d.ts +9 -0
- package/dist/facades.d.ts.map +1 -1
- package/dist/facades.js +314 -77
- package/dist/facades.js.map +1 -1
- package/dist/group-index.d.ts +105 -0
- package/dist/group-index.d.ts.map +1 -0
- package/dist/group-index.js +252 -0
- package/dist/group-index.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/keystore/index.d.ts +15 -0
- package/dist/keystore/index.d.ts.map +1 -1
- package/dist/keystore/indexeddb-shared.d.ts +7 -1
- package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
- package/dist/keystore/indexeddb-shared.js +63 -2
- package/dist/keystore/indexeddb-shared.js.map +1 -1
- package/dist/keystore/indexeddb-token-store.d.ts +3 -1
- package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-token-store.js +22 -1
- package/dist/keystore/indexeddb-token-store.js.map +1 -1
- package/dist/tools/cross-sdk-agent.js +3 -1
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +2 -1
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +17 -31
- 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
package/dist/client.js
CHANGED
|
@@ -30,6 +30,7 @@ import { decryptMessage, } from './v2/e2ee/index.js';
|
|
|
30
30
|
import { ecdsaVerifyRaw } from './v2/crypto/ecdsa.js';
|
|
31
31
|
import { AUNLogger } from './logger.js';
|
|
32
32
|
import { AgentMdManager } from './agent-md.js';
|
|
33
|
+
import { GroupIndexMetaCache } from './group-index.js';
|
|
33
34
|
import { certMatchesFingerprint, normalizeFingerprintHex } from './cert-utils.js';
|
|
34
35
|
import { AUNError, AuthError, ConnectionError, E2EEError, NotFoundError, PermissionError, StateError, TimeoutError, ValidationError, } from './errors.js';
|
|
35
36
|
import { isJsonObject, ConnectionState, STATE_TO_PUBLIC, } from './types.js';
|
|
@@ -67,6 +68,14 @@ function attachGatewayProximity(message, source) {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
}
|
|
71
|
+
function groupIndexBodyText(value) {
|
|
72
|
+
if (typeof value === 'string')
|
|
73
|
+
return value;
|
|
74
|
+
if (value && typeof value === 'object' && !Array.isArray(value) && 'body' in value) {
|
|
75
|
+
return String(value.body ?? '');
|
|
76
|
+
}
|
|
77
|
+
return '';
|
|
78
|
+
}
|
|
70
79
|
const DEFAULT_SESSION_OPTIONS = {
|
|
71
80
|
auto_reconnect: true,
|
|
72
81
|
heartbeat_interval: 30.0,
|
|
@@ -565,6 +574,8 @@ export class AUNClient {
|
|
|
565
574
|
_v2LazyProposeTriggered = new Map();
|
|
566
575
|
/** agent.md 运行时管理器,负责上传、下载、缓存和 RPC 元数据观察。 */
|
|
567
576
|
_agentMdManager;
|
|
577
|
+
_groupIndexMetaCache = new GroupIndexMetaCache();
|
|
578
|
+
_groupIndexCacheLoaded = new Set();
|
|
568
579
|
/** 消息序列号跟踪器(群消息 + P2P 空洞检测) */
|
|
569
580
|
_seqTracker = new SeqTracker();
|
|
570
581
|
_seqTrackerContext = null;
|
|
@@ -574,9 +585,13 @@ export class AUNClient {
|
|
|
574
585
|
_pushedSeqs = new Map();
|
|
575
586
|
/** 已解密但因 seq 空洞暂缓发布的应用层消息(按 namespace -> seq) */
|
|
576
587
|
_pendingOrderedMsgs = new Map();
|
|
588
|
+
/** push 处理队列:按 P2P / group namespace 串行化异步解密与有序投递。 */
|
|
589
|
+
_pushProcessQueues = new Map();
|
|
577
590
|
/** Lazy group sync:首次发送群消息前自动拉取历史 */
|
|
578
591
|
_groupSynced = new Set();
|
|
579
|
-
/**
|
|
592
|
+
/** P2P 撤回去重:原始 message_id -> 时间戳,保证应用层只回调一次 */
|
|
593
|
+
_messageRecallSeen = new Map();
|
|
594
|
+
/** 群撤回去重:group_id|sorted(message_ids) -> 时间戳,保证应用层只回调一次 */
|
|
580
595
|
_groupRecallSeen = new Map();
|
|
581
596
|
/** 在线未读 hint 队列:同一 group 只保留最后一条,延迟 drain 降低登录瞬时拉取压力。 */
|
|
582
597
|
_onlineUnreadHintQueue = new Map();
|
|
@@ -693,11 +708,9 @@ export class AUNClient {
|
|
|
693
708
|
timeout: DEFAULT_SESSION_OPTIONS.timeouts.call,
|
|
694
709
|
onDisconnect: (error, closeCode) => this._handleTransportDisconnect(error, closeCode),
|
|
695
710
|
});
|
|
696
|
-
this._transport.setMetaObserver((meta) => {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
});
|
|
700
|
-
});
|
|
711
|
+
this._transport.setMetaObserver((meta) => this._observeRpcMeta(meta).catch((exc) => {
|
|
712
|
+
this._clientLog.debug(`rpc meta observer skipped: ${String(exc)}`);
|
|
713
|
+
}));
|
|
701
714
|
this._runtime = new ClientRuntime(this);
|
|
702
715
|
this._identityRuntime = new IdentityRuntimeManager(this._runtime);
|
|
703
716
|
this._peerDirectory = new PeerDirectory(this._runtime);
|
|
@@ -733,6 +746,9 @@ export class AUNClient {
|
|
|
733
746
|
this._dispatcher.subscribe('_raw.message.received', (data) => {
|
|
734
747
|
this._onRawMessageReceived(data);
|
|
735
748
|
});
|
|
749
|
+
this._dispatcher.subscribe('_raw.message.recalled', (data) => {
|
|
750
|
+
this._safeAsync(this._onRawMessageRecalled(data));
|
|
751
|
+
});
|
|
736
752
|
// 群组消息推送:re-publish(V2 加密消息走 V2 push 路径)
|
|
737
753
|
this._dispatcher.subscribe('_raw.group.message_created', (data) => {
|
|
738
754
|
this._onRawGroupMessageCreated(data);
|
|
@@ -766,7 +782,7 @@ export class AUNClient {
|
|
|
766
782
|
this._safeAsync(this._onGroupStateCommitted(data));
|
|
767
783
|
});
|
|
768
784
|
// 其他事件直接透传
|
|
769
|
-
for (const evt of ['message.
|
|
785
|
+
for (const evt of ['message.ack', 'storage.object_changed']) {
|
|
770
786
|
this._dispatcher.subscribe(`_raw.${evt}`, (data) => {
|
|
771
787
|
this._dispatcher.publish(evt, data);
|
|
772
788
|
});
|
|
@@ -815,7 +831,96 @@ export class AUNClient {
|
|
|
815
831
|
}
|
|
816
832
|
/** transport 的 meta observer:吸收 gateway 注入的 _meta 字段。失败不影响业务。 */
|
|
817
833
|
async _observeRpcMeta(meta) {
|
|
834
|
+
const groupIndexes = isJsonObject(meta.group_indexes)
|
|
835
|
+
? meta.group_indexes
|
|
836
|
+
: {};
|
|
837
|
+
for (const groupAid of Object.keys(groupIndexes)) {
|
|
838
|
+
await this._loadGroupIndexCache(groupAid);
|
|
839
|
+
}
|
|
840
|
+
this._groupIndexMetaCache.observeRpcMeta(meta, { localAid: this._aid ?? '' });
|
|
818
841
|
await this._agentMdManager.observeRpcMeta(meta, this._aid);
|
|
842
|
+
for (const groupAid of Object.keys(groupIndexes)) {
|
|
843
|
+
await this._persistGroupIndexCache(groupAid, {
|
|
844
|
+
remote_meta: this._groupIndexMetaCache.remoteMeta(this._aid ?? '', groupAid) ?? {},
|
|
845
|
+
local_etag: this._groupIndexMetaCache.localEtag(this._aid ?? '', groupAid),
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
isGroupIndexStale(groupAid) {
|
|
850
|
+
return this._groupIndexMetaCache.isStale(this._aid ?? '', groupAid);
|
|
851
|
+
}
|
|
852
|
+
markGroupIndexFresh(groupAid, options) {
|
|
853
|
+
this._groupIndexMetaCache.markFresh(this._aid ?? '', groupAid, options);
|
|
854
|
+
void this._persistGroupIndexCache(groupAid, { local_etag: String(options.etag ?? '') });
|
|
855
|
+
}
|
|
856
|
+
getGroupIndexRemoteMeta(groupAid) {
|
|
857
|
+
return this._groupIndexMetaCache.remoteMeta(this._aid ?? '', groupAid);
|
|
858
|
+
}
|
|
859
|
+
getGroupIndexLocalEtag(groupAid) {
|
|
860
|
+
return this._groupIndexMetaCache.localEtag(this._aid ?? '', groupAid);
|
|
861
|
+
}
|
|
862
|
+
async getGroupIndexCachedSettings(groupAid, keys) {
|
|
863
|
+
await this._loadGroupIndexCache(groupAid);
|
|
864
|
+
return this._groupIndexMetaCache.cachedSettings(this._aid ?? '', groupAid, keys.map((item) => String(item)));
|
|
865
|
+
}
|
|
866
|
+
async getGroupIndexCachedSettingsByEntries(groupAid, keys, entries) {
|
|
867
|
+
await this._loadGroupIndexCache(groupAid);
|
|
868
|
+
return this._groupIndexMetaCache.cachedSettingsByEntries(this._aid ?? '', groupAid, keys.map((item) => String(item)), entries);
|
|
869
|
+
}
|
|
870
|
+
cacheGroupIndexSettings(groupAid, settings, options) {
|
|
871
|
+
this._groupIndexMetaCache.cacheSettings(this._aid ?? '', groupAid, settings, options);
|
|
872
|
+
const entryEtags = {};
|
|
873
|
+
for (const item of options?.entries ?? []) {
|
|
874
|
+
const key = String(item.key ?? '');
|
|
875
|
+
if (key)
|
|
876
|
+
entryEtags[key] = String(item.etag ?? '');
|
|
877
|
+
}
|
|
878
|
+
const fields = {
|
|
879
|
+
settings,
|
|
880
|
+
entry_etags: entryEtags,
|
|
881
|
+
remote_meta: this._groupIndexMetaCache.remoteMeta(this._aid ?? '', groupAid) ?? {},
|
|
882
|
+
local_etag: String(options?.etag ?? this._groupIndexMetaCache.localEtag(this._aid ?? '', groupAid) ?? ''),
|
|
883
|
+
};
|
|
884
|
+
const indexJsonl = groupIndexBodyText(options?.groupIndex);
|
|
885
|
+
if (indexJsonl)
|
|
886
|
+
fields.index_jsonl = indexJsonl;
|
|
887
|
+
return this._persistGroupIndexCache(groupAid, fields);
|
|
888
|
+
}
|
|
889
|
+
_groupIndexCacheKey(groupAid) {
|
|
890
|
+
return `${this._aid ?? ''}\x00${String(groupAid ?? '')}`;
|
|
891
|
+
}
|
|
892
|
+
async _loadGroupIndexCache(groupAid) {
|
|
893
|
+
const localAid = String(this._aid ?? '').trim();
|
|
894
|
+
const group = String(groupAid ?? '').trim();
|
|
895
|
+
if (!localAid || !group || typeof this._tokenStore.loadGroupIndexCache !== 'function')
|
|
896
|
+
return;
|
|
897
|
+
const key = this._groupIndexCacheKey(group);
|
|
898
|
+
if (this._groupIndexCacheLoaded.has(key))
|
|
899
|
+
return;
|
|
900
|
+
this._groupIndexCacheLoaded.add(key);
|
|
901
|
+
const record = await this._tokenStore.loadGroupIndexCache(localAid, group);
|
|
902
|
+
if (!record)
|
|
903
|
+
return;
|
|
904
|
+
this._groupIndexMetaCache.restore(localAid, group, {
|
|
905
|
+
remote_meta: record.remote_meta,
|
|
906
|
+
local_etag: record.local_etag,
|
|
907
|
+
settings: record.settings,
|
|
908
|
+
entry_etags: record.entry_etags,
|
|
909
|
+
});
|
|
910
|
+
}
|
|
911
|
+
async _persistGroupIndexCache(groupAid, fields) {
|
|
912
|
+
const localAid = String(this._aid ?? '').trim();
|
|
913
|
+
const group = String(groupAid ?? '').trim();
|
|
914
|
+
if (!localAid || !group || typeof this._tokenStore.upsertGroupIndexCache !== 'function')
|
|
915
|
+
return;
|
|
916
|
+
const record = await this._tokenStore.upsertGroupIndexCache(localAid, group, fields);
|
|
917
|
+
this._groupIndexCacheLoaded.add(this._groupIndexCacheKey(group));
|
|
918
|
+
this._groupIndexMetaCache.restore(localAid, group, {
|
|
919
|
+
remote_meta: record.remote_meta,
|
|
920
|
+
local_etag: record.local_etag,
|
|
921
|
+
settings: record.settings,
|
|
922
|
+
entry_etags: record.entry_etags,
|
|
923
|
+
});
|
|
819
924
|
}
|
|
820
925
|
get state() {
|
|
821
926
|
return this._publicState(this._state);
|
|
@@ -968,11 +1073,9 @@ export class AUNClient {
|
|
|
968
1073
|
timeout: DEFAULT_SESSION_OPTIONS.timeouts.call,
|
|
969
1074
|
onDisconnect: (error, closeCode) => this._handleTransportDisconnect(error, closeCode),
|
|
970
1075
|
});
|
|
971
|
-
this._transport.setMetaObserver((meta) => {
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
});
|
|
975
|
-
});
|
|
1076
|
+
this._transport.setMetaObserver((meta) => this._observeRpcMeta(meta).catch((exc) => {
|
|
1077
|
+
this._clientLog.debug(`rpc meta observer skipped: ${String(exc)}`);
|
|
1078
|
+
}));
|
|
976
1079
|
this._auth.setLogger(this._logAuth);
|
|
977
1080
|
this._transport.setLogger(this._logTransport);
|
|
978
1081
|
this._dispatcher.setLogger(this._logEvents);
|
|
@@ -1506,6 +1609,9 @@ export class AUNClient {
|
|
|
1506
1609
|
_onRawMessageReceived(data) {
|
|
1507
1610
|
this._delivery.onRawMessageReceived(data);
|
|
1508
1611
|
}
|
|
1612
|
+
async _onRawMessageRecalled(data) {
|
|
1613
|
+
return this._delivery.onRawMessageRecalled(data);
|
|
1614
|
+
}
|
|
1509
1615
|
/** 处理群组消息推送:re-publish(V2 加密消息走 V2 push 路径) */
|
|
1510
1616
|
_onRawGroupMessageCreated(data) {
|
|
1511
1617
|
return this._delivery.onRawGroupMessageCreated(data);
|