@agentunion/fastaun-browser 0.4.13 → 0.5.1
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 +536 -386
- package/_packed_docs/CHANGELOG-validators.md +144 -0
- package/_packed_docs/CHANGELOG.md +536 -386
- package/_packed_docs/INDEX.md +159 -84
- package/_packed_docs/KITE_DOCS_GUIDE.md +48 -31
- package/_packed_docs/agent.md/SCHEMA.md +2 -0
- package/_packed_docs/agent.md/examples/codeagent-claudecode.md +2 -0
- package/_packed_docs/agent.md/examples/human-developer.md +2 -0
- package/_packed_docs/agent.md/examples/openclaw-lobster.md +2 -0
- package/_packed_docs/agent.md/examples/signed-openclaw-lobster.md +2 -0
- package/_packed_docs/agent.md//350/277/234/347/250/213agent.md/347/274/223/345/255/230/344/270/216etag/351/200/217/344/274/240/346/226/271/346/241/210.md +2 -0
- package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +266 -686
- package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +331 -0
- package/_packed_docs/design/2026-05-22-aun-rpc-trace-enhancement.md +2 -0
- package/_packed_docs/design/AUNClient/346/213/206/345/210/206/351/207/215/346/236/204/346/211/247/350/241/214/346/226/271/346/241/210.md +2 -0
- package/_packed_docs/design/E2EE_V2/347/256/200/345/214/226/344/270/2721DH/345/212/240Per-AID_Wrap/346/226/271/346/241/210.md +2 -0
- package/_packed_docs/design//350/267/250/350/257/255/350/250/200/345/256/271/345/231/250E2E/346/265/213/350/257/225/346/226/271/346/241/210.md +2 -0
- package/_packed_docs/protocol/00-/346/200/273/350/247/210/344/270/216/345/210/206/345/261/202.md +2 -0
- package/_packed_docs/protocol/00A-/350/256/276/350/256/241/345/216/237/345/210/231-/344/270/272Agent/350/200/214/347/224/237.md +2 -0
- 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 +2 -0
- package/_packed_docs/protocol/02-/350/257/201/344/271/246/344/270/216/344/277/241/344/273/273/344/275/223/347/263/273.md +2 -0
- package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +2 -0
- package/_packed_docs/protocol/04-Peer-/345/255/220/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/protocol/05-Relay-/345/255/220/345/215/217/350/256/256.md +2 -0
- 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 +2 -0
- package/_packed_docs/protocol/08-AUN-E2EE-Group.md +296 -900
- package/_packed_docs/protocol/08-AUN-E2EE.md +2 -0
- package/_packed_docs/protocol/09-/345/256/211/345/205/250/350/200/203/350/231/221.md +2 -0
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +66 -173
- package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +55 -0
- package/_packed_docs/protocol/12-Stream-/345/255/220/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/protocol/13-Agent/350/241/214/344/270/272/350/247/204/350/214/203.md +2 -0
- package/_packed_docs/protocol/14-/344/272/244/344/272/222/346/234/272/345/210/266-/345/223/215/345/272/224/346/250/241/345/274/217/344/270/216/350/207/252/344/270/273/346/250/241/345/274/217.md +2 -0
- package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/protocol/16-/347/263/273/347/273/237/347/233/256/345/275/225/344/277/235/346/212/244/346/226/271/346/241/210.md +177 -0
- package/_packed_docs/protocol/README.md +4 -1
- package/_packed_docs/protocol/agent.md/SCHEMA.md +2 -0
- package/_packed_docs/protocol/agent.md/examples/codeagent-claudecode.md +2 -0
- package/_packed_docs/protocol/agent.md/examples/human-developer.md +2 -0
- package/_packed_docs/protocol/agent.md/examples/openclaw-lobster.md +2 -0
- package/_packed_docs/protocol/aun-docs-guide.md +2 -0
- package/_packed_docs/protocol/index.md +10 -3
- package/_packed_docs/protocol//350/215/211/346/241/210-agent.md/347/255/276/345/220/215/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/protocol//350/215/211/346/241/210-/346/213/222/347/273/235/344/277/241/345/217/267/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225B-/346/211/251/345/261/225/346/200/247/346/214/207/345/215/227.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225C-/347/247/201/351/222/245/347/256/241/347/220/206/344/270/216/350/272/253/344/273/275/346/201/242/345/244/215.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225D-Root_CA_/346/262/273/347/220/206/346/234/272/345/210/266.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225E-Root_CA_/345/207/206/345/205/245/346/265/201/347/250/213.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225F-Issuer_CA_/347/224/263/350/257/267/346/265/201/347/250/213.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225G-AID_/345/255/244/345/204/277/351/242/204/351/230/262/344/270/216/346/225/221/346/217/264/346/234/272/345/210/266.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225H-Identity/346/234/215/345/212/241/345/256/236/347/216/260/346/214/207/345/215/227.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225I-/350/267/250/345/237/237/346/266/210/346/201/257/350/267/257/347/224/261/345/256/236/347/216/260/346/214/207/345/215/227.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225J-/345/256/242/346/210/267/347/253/257/346/216/245/345/205/245/347/244/272/344/276/213.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225K-Agent_Web/345/217/221/347/216/260/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225L-E2EE/345/256/236/347/216/260/346/214/207/345/215/227.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225M-JWT/350/256/244/350/257/201/345/256/236/347/216/260/346/214/207/345/215/227.md +2 -0
- package/_packed_docs/protocol//351/231/204/345/275/225N-/345/210/206/345/270/203/345/274/217Trace/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +2 -0
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +2 -0
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +2 -0
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +2 -0
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +6 -252
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +219 -177
- package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +4 -1
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +2 -0
- package/_packed_docs/sdk/09-collab-rpc-manual.md +581 -0
- package/_packed_docs/sdk/09-custody-api-manual.md +2 -0
- package/_packed_docs/sdk/09-group-rpc-manual.md +301 -634
- package/_packed_docs/sdk/09-message-rpc-manual.md +2 -0
- package/_packed_docs/sdk/09-meta-rpc-manual.md +2 -0
- package/_packed_docs/sdk/09-payload-reference.md +2 -0
- package/_packed_docs/sdk/09-proxy-rpc-manual.md +2 -0
- package/_packed_docs/sdk/09-storage-rpc-manual.md +984 -274
- package/_packed_docs/sdk/09-stream-rpc-manual.md +2 -0
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +36 -23
- package/_packed_docs/sdk/E2EE_V2/346/266/210/346/201/257/351/200/232/344/277/241/346/227/266/345/272/217/345/233/276.md +2 -0
- package/_packed_docs/sdk/INDEX.md +47 -30
- package/_packed_docs/sdk/Notify/351/200/232/347/237/245/346/226/271/346/241/210.md +2 -0
- package/_packed_docs/sdk/README.md +17 -15
- package/dist/aid-store.d.ts +25 -0
- package/dist/aid-store.d.ts.map +1 -1
- package/dist/aid-store.js +89 -8
- package/dist/aid-store.js.map +1 -1
- package/dist/bundle.js +19615 -16870
- package/dist/client/delivery.d.ts +15 -2
- package/dist/client/delivery.d.ts.map +1 -1
- package/dist/client/delivery.js +303 -54
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/group-state.d.ts.map +1 -1
- package/dist/client/group-state.js +36 -14
- package/dist/client/group-state.js.map +1 -1
- package/dist/client/lifecycle.js +2 -2
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +2 -0
- package/dist/client/rpc-pipeline.d.ts.map +1 -1
- package/dist/client/rpc-pipeline.js +235 -82
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +14 -1
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +300 -121
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +36 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +460 -57
- package/dist/client.js.map +1 -1
- package/dist/collab/client.d.ts +47 -0
- package/dist/collab/client.d.ts.map +1 -0
- package/dist/collab/client.js +136 -0
- package/dist/collab/client.js.map +1 -0
- package/dist/collab/errors.d.ts +16 -0
- package/dist/collab/errors.d.ts.map +1 -0
- package/dist/collab/errors.js +60 -0
- package/dist/collab/errors.js.map +1 -0
- package/dist/collab/index.d.ts +4 -0
- package/dist/collab/index.d.ts.map +1 -0
- package/dist/collab/index.js +4 -0
- package/dist/collab/index.js.map +1 -0
- package/dist/collab/types.d.ts +111 -0
- package/dist/collab/types.d.ts.map +1 -0
- package/dist/collab/types.js +2 -0
- package/dist/collab/types.js.map +1 -0
- package/dist/crypto.d.ts +6 -0
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +6 -0
- package/dist/crypto.js.map +1 -1
- package/dist/errors.d.ts +0 -20
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +9 -37
- package/dist/errors.js.map +1 -1
- package/dist/facades.d.ts +94 -0
- package/dist/facades.d.ts.map +1 -0
- package/dist/facades.js +389 -0
- package/dist/facades.js.map +1 -0
- package/dist/group-fs.d.ts +120 -0
- package/dist/group-fs.d.ts.map +1 -0
- package/dist/group-fs.js +539 -0
- package/dist/group-fs.js.map +1 -0
- package/dist/group-id.d.ts +9 -12
- package/dist/group-id.d.ts.map +1 -1
- package/dist/group-id.js +41 -63
- package/dist/group-id.js.map +1 -1
- package/dist/group-resources.d.ts +98 -0
- package/dist/group-resources.d.ts.map +1 -0
- package/dist/group-resources.js +635 -0
- package/dist/group-resources.js.map +1 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/index.d.ts +2 -54
- package/dist/keystore/index.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.d.ts +3 -0
- package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.js +65 -0
- package/dist/keystore/indexeddb-identity-store.js.map +1 -1
- package/dist/keystore/indexeddb-shared.d.ts +3 -17
- package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
- package/dist/keystore/indexeddb-shared.js +4 -47
- package/dist/keystore/indexeddb-shared.js.map +1 -1
- package/dist/keystore/indexeddb-token-store.d.ts +1 -64
- package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-token-store.js +45 -774
- package/dist/keystore/indexeddb-token-store.js.map +1 -1
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +4 -0
- package/dist/logger.js.map +1 -1
- package/dist/register-flow.d.ts +1 -0
- package/dist/register-flow.d.ts.map +1 -1
- package/dist/register-flow.js +3 -0
- package/dist/register-flow.js.map +1 -1
- package/dist/service-proxy.d.ts +1 -0
- package/dist/service-proxy.d.ts.map +1 -1
- package/dist/service-proxy.js +15 -3
- package/dist/service-proxy.js.map +1 -1
- package/dist/storage/errors.d.ts +28 -0
- package/dist/storage/errors.d.ts.map +1 -0
- package/dist/storage/errors.js +65 -0
- package/dist/storage/errors.js.map +1 -0
- package/dist/storage/index.d.ts +2 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/lowlevel.d.ts +322 -0
- package/dist/storage/lowlevel.d.ts.map +1 -0
- package/dist/storage/lowlevel.js +471 -0
- package/dist/storage/lowlevel.js.map +1 -0
- package/dist/storage/types.d.ts +59 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +113 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/storage/vfs.d.ts +166 -0
- package/dist/storage/vfs.d.ts.map +1 -0
- package/dist/storage/vfs.js +457 -0
- package/dist/storage/vfs.js.map +1 -0
- package/dist/tools/cross-sdk-agent.d.ts +3 -0
- package/dist/tools/cross-sdk-agent.d.ts.map +1 -0
- package/dist/tools/cross-sdk-agent.js +1376 -0
- package/dist/tools/cross-sdk-agent.js.map +1 -0
- package/dist/transport.d.ts +5 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +125 -12
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +39 -56
- package/dist/types.d.ts.map +1 -1
- package/dist/v2/session/session.d.ts +2 -0
- package/dist/v2/session/session.d.ts.map +1 -1
- package/dist/v2/session/session.js +58 -22
- package/dist/v2/session/session.js.map +1 -1
- package/dist/v2/state/commitment.d.ts +1 -1
- package/dist/v2/state/commitment.d.ts.map +1 -1
- package/dist/v2/state/commitment.js +5 -3
- package/dist/v2/state/commitment.js.map +1 -1
- package/dist/validators.d.ts +35 -0
- package/dist/validators.d.ts.map +1 -0
- package/dist/validators.js +127 -0
- package/dist/validators.js.map +1 -0
- 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 +44 -44
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { normalizeSlotId, slotIsolationKey } from '../config.js';
|
|
2
2
|
import { ClientSignatureError, ConnectionError, PermissionError, StateError, ValidationError } from '../errors.js';
|
|
3
3
|
import { normalizeGroupId } from '../group-id.js';
|
|
4
|
+
import { validateAIDFormat, validateGroupIDFormat } from '../validators.js';
|
|
4
5
|
import { p1363ToDer, pemToArrayBuffer, uint8ToBase64 } from '../crypto.js';
|
|
5
|
-
import { isJsonObject, } from '../types.js';
|
|
6
|
+
import { ConnectionState, isJsonObject, } from '../types.js';
|
|
6
7
|
const INTERNAL_ONLY_METHODS = new Set([
|
|
7
8
|
'auth.login1',
|
|
8
9
|
'auth.aid_login1',
|
|
@@ -12,9 +13,6 @@ const INTERNAL_ONLY_METHODS = new Set([
|
|
|
12
13
|
'auth.refresh_token',
|
|
13
14
|
'initialize',
|
|
14
15
|
]);
|
|
15
|
-
const REMOVED_E2EE_METHODS = new Set([
|
|
16
|
-
'group.rotate_epoch',
|
|
17
|
-
]);
|
|
18
16
|
const PROTECTED_HEADERS_METHODS = new Set([
|
|
19
17
|
'message.send',
|
|
20
18
|
'group.send',
|
|
@@ -32,40 +30,101 @@ const SIGNED_METHODS = new Set([
|
|
|
32
30
|
'group.v2.propose_state', 'group.v2.confirm_state',
|
|
33
31
|
'group.v2.get_proposal',
|
|
34
32
|
'group.kick', 'group.add_member',
|
|
35
|
-
'group.leave', 'group.remove_member',
|
|
36
|
-
'group.update',
|
|
37
|
-
'group.
|
|
38
|
-
'group.transfer_owner', 'group.
|
|
33
|
+
'group.leave', 'group.remove_member',
|
|
34
|
+
'group.update',
|
|
35
|
+
'group.set_role',
|
|
36
|
+
'group.transfer_owner', 'group.bind_group_aid', 'group.renew_group_aid', 'group.complete_transfer',
|
|
37
|
+
'group.review_join_request',
|
|
39
38
|
'group.batch_review_join_request',
|
|
40
39
|
'group.request_join', 'group.use_invite_code',
|
|
41
40
|
'group.thought.put',
|
|
42
41
|
'message.thought.put',
|
|
43
42
|
'group.set_settings',
|
|
44
|
-
'group.
|
|
45
|
-
'group.
|
|
46
|
-
'group.
|
|
47
|
-
'group.
|
|
48
|
-
'group.
|
|
49
|
-
'group.
|
|
50
|
-
'group.
|
|
51
|
-
'group.resources.get_access', 'group.resources.resolve_access_ticket',
|
|
43
|
+
'group.update_announcement',
|
|
44
|
+
'group.update_rules',
|
|
45
|
+
'group.fs.mkdir', 'group.fs.rm', 'group.fs.cp', 'group.fs.mv',
|
|
46
|
+
'group.fs.set_acl', 'group.fs.remove_acl',
|
|
47
|
+
'group.fs.mount', 'group.fs.umount',
|
|
48
|
+
'group.fs.check_upload', 'group.fs.create_upload_session',
|
|
49
|
+
'group.fs.complete_upload', 'group.fs.create_download_ticket',
|
|
52
50
|
'storage.put_object', 'storage.delete_object', 'storage.get_by_share',
|
|
53
51
|
'storage.create_share_link', 'storage.revoke_share_link',
|
|
54
52
|
'storage.create_upload_session', 'storage.complete_upload',
|
|
55
53
|
'storage.create_folder', 'storage.rename_folder', 'storage.move_folder',
|
|
56
54
|
'storage.delete_folder', 'storage.move_object', 'storage.copy_object',
|
|
57
55
|
'storage.batch_delete', 'storage.set_object_meta', 'storage.append_object',
|
|
56
|
+
'storage.set_acl', 'storage.remove_acl', 'storage.set_visibility',
|
|
57
|
+
'storage.check_access',
|
|
58
|
+
'storage.issue_token', 'storage.revoke_token',
|
|
59
|
+
'storage.create_symlink', 'storage.atomic_repoint',
|
|
60
|
+
'storage.rename_symlink', 'storage.delete_symlink',
|
|
61
|
+
'storage.fs.mkdir', 'storage.fs.remove', 'storage.fs.rename', 'storage.fs.copy',
|
|
62
|
+
'storage.fs.mount', 'storage.fs.approve', 'storage.fs.reject', 'storage.fs.unmount',
|
|
63
|
+
'storage.fs.invalidate_membership',
|
|
64
|
+
'storage.volume.create', 'storage.volume.renew', 'storage.volume.expire_due',
|
|
65
|
+
'collab.create', 'collab.commit', 'collab.clone',
|
|
66
|
+
'collab.prune', 'collab.unregister',
|
|
67
|
+
'collab.tag.create', 'collab.tag.restore',
|
|
68
|
+
'collab.tag.rm', 'collab.tag.prune',
|
|
58
69
|
'group.commit_state',
|
|
59
70
|
'group.ban', 'group.unban',
|
|
60
71
|
'group.dissolve', 'group.suspend', 'group.resume',
|
|
61
72
|
]);
|
|
73
|
+
const SIGNING_KEY_CACHE_MAX = 32;
|
|
74
|
+
const signingKeyCache = new Map();
|
|
75
|
+
const certFingerprintCache = new Map();
|
|
76
|
+
function cacheGet(cache, key) {
|
|
77
|
+
const value = cache.get(key);
|
|
78
|
+
if (value !== undefined) {
|
|
79
|
+
cache.delete(key);
|
|
80
|
+
cache.set(key, value);
|
|
81
|
+
}
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
function cachePut(cache, key, value) {
|
|
85
|
+
cache.set(key, value);
|
|
86
|
+
while (cache.size > SIGNING_KEY_CACHE_MAX) {
|
|
87
|
+
const first = cache.keys().next().value;
|
|
88
|
+
if (first === undefined)
|
|
89
|
+
break;
|
|
90
|
+
cache.delete(first);
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
async function sha256HexText(text) {
|
|
95
|
+
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(text));
|
|
96
|
+
return Array.from(new Uint8Array(digest)).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
97
|
+
}
|
|
98
|
+
async function signingPrivateKey(privateKeyPem) {
|
|
99
|
+
const key = await sha256HexText(privateKeyPem);
|
|
100
|
+
let cached = cacheGet(signingKeyCache, key);
|
|
101
|
+
if (!cached) {
|
|
102
|
+
const pkcs8 = pemToArrayBuffer(privateKeyPem);
|
|
103
|
+
cached = crypto.subtle.importKey('pkcs8', pkcs8, { name: 'ECDSA', namedCurve: 'P-256' }, false, ['sign']);
|
|
104
|
+
cachePut(signingKeyCache, key, cached);
|
|
105
|
+
}
|
|
106
|
+
return await cached;
|
|
107
|
+
}
|
|
108
|
+
async function signingCertFingerprint(certPem) {
|
|
109
|
+
const key = await sha256HexText(certPem);
|
|
110
|
+
let cached = cacheGet(certFingerprintCache, key);
|
|
111
|
+
if (!cached) {
|
|
112
|
+
cached = (async () => {
|
|
113
|
+
const certDer = pemToArrayBuffer(certPem);
|
|
114
|
+
const fpBuf = await crypto.subtle.digest('SHA-256', certDer);
|
|
115
|
+
return 'sha256:' + Array.from(new Uint8Array(fpBuf)).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
116
|
+
})();
|
|
117
|
+
cachePut(certFingerprintCache, key, cached);
|
|
118
|
+
}
|
|
119
|
+
return await cached;
|
|
120
|
+
}
|
|
62
121
|
const PULL_GATE_STALE_MS = 30000;
|
|
63
122
|
const NON_IDEMPOTENT_TIMEOUT = 35;
|
|
64
123
|
const NON_IDEMPOTENT_METHODS = new Set([
|
|
65
124
|
'message.send', 'group.send', 'group.create', 'group.invite',
|
|
66
125
|
'group.kick', 'group.remove_member', 'group.leave', 'group.dissolve',
|
|
67
|
-
'group.
|
|
68
|
-
'group.
|
|
126
|
+
'group.set_settings',
|
|
127
|
+
'group.update_announcement', 'group.update_rules',
|
|
69
128
|
'storage.put_object', 'storage.delete_object',
|
|
70
129
|
'storage.create_share_link', 'storage.revoke_share_link',
|
|
71
130
|
'storage.get_by_share',
|
|
@@ -73,19 +132,39 @@ const NON_IDEMPOTENT_METHODS = new Set([
|
|
|
73
132
|
'storage.create_folder', 'storage.rename_folder', 'storage.move_folder',
|
|
74
133
|
'storage.delete_folder', 'storage.move_object', 'storage.copy_object',
|
|
75
134
|
'storage.batch_delete', 'storage.set_object_meta', 'storage.append_object',
|
|
135
|
+
'storage.set_acl', 'storage.remove_acl', 'storage.set_visibility',
|
|
136
|
+
'storage.issue_token', 'storage.revoke_token',
|
|
137
|
+
'storage.create_symlink', 'storage.atomic_repoint',
|
|
138
|
+
'storage.rename_symlink', 'storage.delete_symlink',
|
|
139
|
+
'storage.fs.mkdir', 'storage.fs.remove', 'storage.fs.rename', 'storage.fs.copy',
|
|
140
|
+
'storage.fs.mount', 'storage.fs.approve', 'storage.fs.reject', 'storage.fs.unmount',
|
|
141
|
+
'storage.fs.invalidate_membership',
|
|
142
|
+
'storage.volume.create', 'storage.volume.renew', 'storage.volume.expire_due',
|
|
76
143
|
'auth.create_aid', 'auth.renew_cert', 'auth.rekey',
|
|
77
144
|
'message.thought.put', 'group.thought.put',
|
|
78
|
-
'group.add_member',
|
|
79
|
-
'group.
|
|
80
|
-
'group.
|
|
81
|
-
'group.
|
|
82
|
-
'group.
|
|
83
|
-
'group.
|
|
84
|
-
'
|
|
85
|
-
'
|
|
86
|
-
'
|
|
87
|
-
'
|
|
145
|
+
'group.add_member', 'group.bind_group_aid', 'group.complete_transfer',
|
|
146
|
+
'group.fs.mkdir', 'group.fs.rm', 'group.fs.cp', 'group.fs.mv',
|
|
147
|
+
'group.fs.set_acl', 'group.fs.remove_acl',
|
|
148
|
+
'group.fs.mount', 'group.fs.umount',
|
|
149
|
+
'group.fs.check_upload', 'group.fs.create_upload_session',
|
|
150
|
+
'group.fs.complete_upload', 'group.fs.create_download_ticket',
|
|
151
|
+
'collab.create', 'collab.commit', 'collab.clone',
|
|
152
|
+
'collab.prune', 'collab.unregister',
|
|
153
|
+
'collab.tag.create', 'collab.tag.restore',
|
|
154
|
+
'collab.tag.rm', 'collab.tag.prune',
|
|
88
155
|
]);
|
|
156
|
+
function hasMatchingV2Session(client) {
|
|
157
|
+
const session = client._v2Session;
|
|
158
|
+
if (!session)
|
|
159
|
+
return false;
|
|
160
|
+
if (session.currentIkPubDer === undefined)
|
|
161
|
+
return true;
|
|
162
|
+
return session.aid === client._aid && session.deviceId === client._deviceId;
|
|
163
|
+
}
|
|
164
|
+
function isTransientV2PullFallbackError(error) {
|
|
165
|
+
const text = (error instanceof Error ? error.message : String(error)).toLowerCase();
|
|
166
|
+
return text.includes('no_service') || text.includes('service plane unavailable');
|
|
167
|
+
}
|
|
89
168
|
export class RpcPipeline {
|
|
90
169
|
runtime;
|
|
91
170
|
constructor(runtime) {
|
|
@@ -107,7 +186,14 @@ export class RpcPipeline {
|
|
|
107
186
|
}
|
|
108
187
|
async callImpl(method, params) {
|
|
109
188
|
const client = this.runtime.client;
|
|
110
|
-
const
|
|
189
|
+
const preflight = this.preflight(method, params);
|
|
190
|
+
const p = preflight.params;
|
|
191
|
+
const rpcBackground = preflight.rpcBackground;
|
|
192
|
+
const runWithRpcPriority = async (operation) => {
|
|
193
|
+
if (!rpcBackground)
|
|
194
|
+
return await operation();
|
|
195
|
+
return await client._withBackgroundRpc(operation);
|
|
196
|
+
};
|
|
111
197
|
const skipSendResultEnvelope = Boolean(p._skip_send_result_envelope);
|
|
112
198
|
delete p._skip_send_result_envelope;
|
|
113
199
|
if (method === 'message.send') {
|
|
@@ -131,7 +217,7 @@ export class RpcPipeline {
|
|
|
131
217
|
if (encrypt) {
|
|
132
218
|
await client._ensureV2SessionReady('group.send', 'V2 session not initialized; encrypted group.send requires V2 (V1 E2EE removed)');
|
|
133
219
|
client._clientLog.debug('call route: group.send -> V2 encrypted send');
|
|
134
|
-
return await client._sendGroupV2(String(p.group_id ?? ''), p.payload ?? {}, {
|
|
220
|
+
return await client._sendGroupV2(String(p.group_aid ?? p.group_id ?? ''), p.payload ?? {}, {
|
|
135
221
|
messageId: String(p.message_id ?? '') || undefined,
|
|
136
222
|
timestamp: p.timestamp,
|
|
137
223
|
protectedHeaders: client._protectedHeadersFromParams(p),
|
|
@@ -161,27 +247,35 @@ export class RpcPipeline {
|
|
|
161
247
|
const pullGateKey = this.pullGateKeyForCall(method, p);
|
|
162
248
|
if (pullGateKey) {
|
|
163
249
|
return await this.runPullSerialized(pullGateKey, async () => {
|
|
164
|
-
return await this.callImplInner(method, p, skipSendResultEnvelope);
|
|
250
|
+
return await runWithRpcPriority(() => this.callImplInner(method, p, skipSendResultEnvelope));
|
|
165
251
|
});
|
|
166
252
|
}
|
|
167
|
-
return await this.callImplInner(method, p, skipSendResultEnvelope);
|
|
253
|
+
return await runWithRpcPriority(() => this.callImplInner(method, p, skipSendResultEnvelope));
|
|
168
254
|
}
|
|
169
255
|
async callImplInner(method, p, skipSendResultEnvelope = false) {
|
|
170
256
|
const client = this.runtime.client;
|
|
171
|
-
if (method === 'message.pull') {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
257
|
+
if (method === 'message.v2.pull' || (method === 'message.pull' && hasMatchingV2Session(client))) {
|
|
258
|
+
try {
|
|
259
|
+
await client._ensureV2SessionReady('message.pull');
|
|
260
|
+
client._clientLog.debug(`call route: ${method} -> V2 pull`);
|
|
261
|
+
const messages = await client._pullV2(Number(p.after_seq ?? 0) || 0, Number(p.limit ?? 50) || 50, { force: p.force === true });
|
|
262
|
+
return { messages };
|
|
263
|
+
}
|
|
264
|
+
catch (exc) {
|
|
265
|
+
if (method !== 'message.pull' || !isTransientV2PullFallbackError(exc)) {
|
|
266
|
+
throw exc;
|
|
267
|
+
}
|
|
268
|
+
client._clientLog.warn(`message.pull V2 route unavailable, fallback to plain pull: ${exc instanceof Error ? exc.message : String(exc)}`);
|
|
269
|
+
}
|
|
176
270
|
}
|
|
177
|
-
if (method === 'message.ack') {
|
|
271
|
+
if (method === 'message.v2.ack' || (method === 'message.ack' && hasMatchingV2Session(client))) {
|
|
178
272
|
await client._ensureV2SessionReady('message.ack');
|
|
179
|
-
client._clientLog.debug(
|
|
273
|
+
client._clientLog.debug(`call route: ${method} -> V2 ack`);
|
|
180
274
|
return await client._ackV2(Number(p.seq ?? p.up_to_seq ?? 0) || undefined);
|
|
181
275
|
}
|
|
182
|
-
if (method === 'group.pull' && p.group_id) {
|
|
276
|
+
if ((method === 'group.v2.pull' || method === 'group.pull') && p.group_id && (method === 'group.v2.pull' || hasMatchingV2Session(client))) {
|
|
183
277
|
await client._ensureV2SessionReady('group.pull');
|
|
184
|
-
client._clientLog.debug(
|
|
278
|
+
client._clientLog.debug(`call route: ${method} -> V2 pull`);
|
|
185
279
|
const hasExplicitAfterSeq = 'after_seq' in p || 'after_message_seq' in p;
|
|
186
280
|
const cursorParams = client._explicitGroupCursorParams(p);
|
|
187
281
|
const ownsCursor = Object.keys(cursorParams).length === 0 || client._groupCursorTargetsCurrentInstance(cursorParams);
|
|
@@ -192,24 +286,27 @@ export class RpcPipeline {
|
|
|
192
286
|
pullOpts.cursorParams = cursorParams;
|
|
193
287
|
if (!ownsCursor)
|
|
194
288
|
pullOpts.ownsCursor = false;
|
|
195
|
-
|
|
289
|
+
if (String(p.group_id ?? '').trim())
|
|
290
|
+
pullOpts.wireGroupId = String(p.group_id).trim();
|
|
291
|
+
const messages = await client._pullGroupV2(String(p.group_aid ?? p.group_id), Number(p.after_seq ?? p.after_message_seq ?? 0) || 0, Number(p.limit ?? 50) || 50, Object.keys(pullOpts).length > 0 ? pullOpts : undefined);
|
|
196
292
|
return { messages };
|
|
197
293
|
}
|
|
198
|
-
if (method === 'group.ack_messages' && p.group_id) {
|
|
294
|
+
if ((method === 'group.v2.ack' || method === 'group.ack_messages') && p.group_id && (method === 'group.v2.ack' || hasMatchingV2Session(client))) {
|
|
199
295
|
await client._ensureV2SessionReady('group.ack_messages');
|
|
200
|
-
client._clientLog.debug(
|
|
296
|
+
client._clientLog.debug(`call route: ${method} -> V2 ack`);
|
|
201
297
|
const cursorParams = client._explicitGroupCursorParams(p);
|
|
202
298
|
const ownsCursor = Object.keys(cursorParams).length === 0 || client._groupCursorTargetsCurrentInstance(cursorParams);
|
|
203
299
|
if (!ownsCursor) {
|
|
204
300
|
return await client._rawGroupAckMessages(p);
|
|
205
301
|
}
|
|
206
|
-
return await client._ackGroupV2(String(p.group_id), Number(p.seq ?? p.msg_seq ?? p.up_to_seq ?? 0) || undefined);
|
|
302
|
+
return await client._ackGroupV2(String(p.group_aid ?? p.group_id), Number(p.seq ?? p.msg_seq ?? p.up_to_seq ?? 0) || undefined);
|
|
207
303
|
}
|
|
208
304
|
await this.applyClientSignature(method, p);
|
|
209
305
|
const callTimeout = NON_IDEMPOTENT_METHODS.has(method) ? NON_IDEMPOTENT_TIMEOUT : undefined;
|
|
306
|
+
const rpcBackground = client._backgroundRpcDepth > 0;
|
|
210
307
|
let result = callTimeout
|
|
211
|
-
? await client._transport.call(method, p, callTimeout)
|
|
212
|
-
: await client._transport.call(method, p);
|
|
308
|
+
? await client._transport.call(method, p, callTimeout, undefined, rpcBackground)
|
|
309
|
+
: await client._transport.call(method, p, undefined, undefined, rpcBackground);
|
|
213
310
|
result = await this.postprocessResult(method, p, result);
|
|
214
311
|
if (!skipSendResultEnvelope) {
|
|
215
312
|
result = client._delivery.attachSendResultEnvelope(method, p, result, Boolean(p.encrypted));
|
|
@@ -218,20 +315,20 @@ export class RpcPipeline {
|
|
|
218
315
|
}
|
|
219
316
|
preflight(method, params) {
|
|
220
317
|
const client = this.runtime.client;
|
|
221
|
-
if (client.
|
|
318
|
+
if (client.state !== ConnectionState.READY) {
|
|
222
319
|
throw new ConnectionError('client is not connected');
|
|
223
320
|
}
|
|
224
321
|
if (INTERNAL_ONLY_METHODS.has(method)) {
|
|
225
322
|
throw new PermissionError(`method is internal_only: ${method}`);
|
|
226
323
|
}
|
|
227
|
-
if (method.startsWith('message.e2ee.') || method.startsWith('group.e2ee.') || REMOVED_E2EE_METHODS.has(method)) {
|
|
228
|
-
throw new PermissionError(`legacy E2EE method is removed in this SDK: ${method}`);
|
|
229
|
-
}
|
|
230
324
|
const p = { ...(params ?? {}) };
|
|
231
325
|
this.mergeInstanceProtectedHeaders(method, p);
|
|
326
|
+
const rpcBackground = Boolean(p._rpc_background) || client._backgroundRpcDepth > 0;
|
|
327
|
+
delete p._rpc_background;
|
|
232
328
|
if (method === 'message.send' || method === 'group.send') {
|
|
233
329
|
this.normalizeOutboundMessagePayload(p, method);
|
|
234
330
|
}
|
|
331
|
+
this.normalizeGroupCallIdentifier(method, p);
|
|
235
332
|
this.validateOutboundCall(method, p);
|
|
236
333
|
this.injectMessageCursorContext(method, p);
|
|
237
334
|
this.captureGroupCursorParams(method, p);
|
|
@@ -239,7 +336,7 @@ export class RpcPipeline {
|
|
|
239
336
|
const clampedParams = typeof client._clampAckParams === 'function'
|
|
240
337
|
? client._clampAckParams(method, p)
|
|
241
338
|
: p;
|
|
242
|
-
return { params: clampedParams };
|
|
339
|
+
return { params: clampedParams, rpcBackground };
|
|
243
340
|
}
|
|
244
341
|
mergeInstanceProtectedHeaders(method, params) {
|
|
245
342
|
const client = this.runtime.client;
|
|
@@ -264,6 +361,8 @@ export class RpcPipeline {
|
|
|
264
361
|
validateOutboundCall(method, params) {
|
|
265
362
|
if (method === 'message.send') {
|
|
266
363
|
this.validateMessageRecipient(params.to);
|
|
364
|
+
// 校验目标 AID 格式(拒绝 __system__ 等非法格式)
|
|
365
|
+
validateAIDFormat(params.to, 'message.send.to');
|
|
267
366
|
if ('persist' in params) {
|
|
268
367
|
throw new ValidationError("message.send no longer accepts 'persist'; configure delivery_mode during connect");
|
|
269
368
|
}
|
|
@@ -272,6 +371,8 @@ export class RpcPipeline {
|
|
|
272
371
|
}
|
|
273
372
|
}
|
|
274
373
|
if (method === 'group.send') {
|
|
374
|
+
// 校验目标 Group ID 格式
|
|
375
|
+
validateGroupIDFormat(params.group_id, 'group.send.group_id');
|
|
275
376
|
if ('persist' in params) {
|
|
276
377
|
throw new ValidationError("group.send does not accept 'persist'; group messages are always fanout");
|
|
277
378
|
}
|
|
@@ -289,17 +390,33 @@ export class RpcPipeline {
|
|
|
289
390
|
throw new ValidationError(`${method} requires context.type + context.id`);
|
|
290
391
|
}
|
|
291
392
|
}
|
|
292
|
-
if (method === 'group.thought.
|
|
293
|
-
|
|
393
|
+
if (method === 'group.thought.put') {
|
|
394
|
+
// 校验目标 Group ID 格式
|
|
395
|
+
validateGroupIDFormat(params.group_id, 'group.thought.put.group_id');
|
|
396
|
+
}
|
|
397
|
+
if (method === 'group.thought.get') {
|
|
398
|
+
if (!String(params.sender_aid ?? '').trim()) {
|
|
399
|
+
throw new ValidationError('group.thought.get requires sender_aid');
|
|
400
|
+
}
|
|
401
|
+
// 校验 sender_aid 格式
|
|
402
|
+
validateAIDFormat(params.sender_aid, 'group.thought.get.sender_aid');
|
|
403
|
+
// 校验目标 Group ID 格式
|
|
404
|
+
validateGroupIDFormat(params.group_id, 'group.thought.get.group_id');
|
|
294
405
|
}
|
|
295
406
|
if (method === 'message.thought.put') {
|
|
296
407
|
this.validateMessageRecipient(params.to);
|
|
297
408
|
if (!String(params.to ?? '').trim()) {
|
|
298
409
|
throw new ValidationError('message.thought.put requires to');
|
|
299
410
|
}
|
|
411
|
+
// 校验目标 AID 格式
|
|
412
|
+
validateAIDFormat(params.to, 'message.thought.put.to');
|
|
300
413
|
}
|
|
301
|
-
if (method === 'message.thought.get'
|
|
302
|
-
|
|
414
|
+
if (method === 'message.thought.get') {
|
|
415
|
+
if (!String(params.sender_aid ?? '').trim()) {
|
|
416
|
+
throw new ValidationError('message.thought.get requires sender_aid');
|
|
417
|
+
}
|
|
418
|
+
// 校验 sender_aid 格式
|
|
419
|
+
validateAIDFormat(params.sender_aid, 'message.thought.get.sender_aid');
|
|
303
420
|
}
|
|
304
421
|
}
|
|
305
422
|
injectMessageCursorContext(method, params) {
|
|
@@ -318,14 +435,19 @@ export class RpcPipeline {
|
|
|
318
435
|
params.slot_id = client._slotId;
|
|
319
436
|
}
|
|
320
437
|
async applyClientSignature(method, params) {
|
|
321
|
-
|
|
322
|
-
|
|
438
|
+
try {
|
|
439
|
+
if (!SIGNED_METHODS.has(method)) {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (this.shouldSkipClientSignature(method, params)) {
|
|
443
|
+
delete params.client_signature;
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
await this.runtime.client._signClientOperation(method, params);
|
|
323
447
|
}
|
|
324
|
-
|
|
325
|
-
delete params.
|
|
326
|
-
return;
|
|
448
|
+
finally {
|
|
449
|
+
delete params._client_signature_identity;
|
|
327
450
|
}
|
|
328
|
-
await this.runtime.client._signClientOperation(method, params);
|
|
329
451
|
}
|
|
330
452
|
shouldSkipClientSignature(method, params) {
|
|
331
453
|
if (method !== 'message.send' && method !== 'group.send')
|
|
@@ -335,7 +457,10 @@ export class RpcPipeline {
|
|
|
335
457
|
return this.runtime.client._isEchoPayload(params.payload);
|
|
336
458
|
}
|
|
337
459
|
async signClientOperation(method, params) {
|
|
338
|
-
const
|
|
460
|
+
const internal = params._client_signature_identity;
|
|
461
|
+
const currentAid = (internal && typeof internal === 'object')
|
|
462
|
+
? internal
|
|
463
|
+
: this.runtime.client._currentAid;
|
|
339
464
|
if (!currentAid?.privateKeyPem)
|
|
340
465
|
return;
|
|
341
466
|
try {
|
|
@@ -353,16 +478,13 @@ export class RpcPipeline {
|
|
|
353
478
|
.map(b => b.toString(16).padStart(2, '0'))
|
|
354
479
|
.join('');
|
|
355
480
|
const signData = new TextEncoder().encode(`${method}|${aid}|${ts}|${paramsHash}`);
|
|
356
|
-
const
|
|
357
|
-
const cryptoKey = await crypto.subtle.importKey('pkcs8', pkcs8, { name: 'ECDSA', namedCurve: 'P-256' }, false, ['sign']);
|
|
481
|
+
const cryptoKey = await signingPrivateKey(currentAid.privateKeyPem);
|
|
358
482
|
const sigP1363 = await crypto.subtle.sign({ name: 'ECDSA', hash: 'SHA-256' }, cryptoKey, signData);
|
|
359
483
|
const sigDer = p1363ToDer(new Uint8Array(sigP1363));
|
|
360
484
|
let certFingerprint = '';
|
|
361
485
|
const certPem = currentAid.certPem;
|
|
362
486
|
if (certPem) {
|
|
363
|
-
|
|
364
|
-
const fpBuf = await crypto.subtle.digest('SHA-256', certDer);
|
|
365
|
-
certFingerprint = 'sha256:' + Array.from(new Uint8Array(fpBuf)).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
487
|
+
certFingerprint = await signingCertFingerprint(certPem);
|
|
366
488
|
}
|
|
367
489
|
params.client_signature = {
|
|
368
490
|
aid,
|
|
@@ -383,11 +505,11 @@ export class RpcPipeline {
|
|
|
383
505
|
return client._aid ? `p2p:${client._aid}` : '';
|
|
384
506
|
}
|
|
385
507
|
if (method === 'group.pull' || method === 'group.v2.pull') {
|
|
386
|
-
const gid = String(params.group_id ?? '').trim();
|
|
508
|
+
const gid = String(params.group_aid ?? params.group_id ?? '').trim();
|
|
387
509
|
return gid ? `group:${gid}` : '';
|
|
388
510
|
}
|
|
389
511
|
if (method === 'group.pull_events') {
|
|
390
|
-
const gid = String(params.group_id ?? '').trim();
|
|
512
|
+
const gid = String(params.group_aid ?? params.group_id ?? '').trim();
|
|
391
513
|
return gid ? `group_event:${gid}` : '';
|
|
392
514
|
}
|
|
393
515
|
return '';
|
|
@@ -441,12 +563,14 @@ export class RpcPipeline {
|
|
|
441
563
|
async rawCall(method, params, options) {
|
|
442
564
|
const client = this.runtime.client;
|
|
443
565
|
const payload = { ...(params ?? {}) };
|
|
566
|
+
const rpcBackground = Boolean(payload._rpc_background) || client._backgroundRpcDepth > 0 || options?.background === true;
|
|
567
|
+
delete payload._rpc_background;
|
|
444
568
|
const signed = options?.signed ?? true;
|
|
445
569
|
if (signed) {
|
|
446
570
|
await this.applyClientSignature(method, payload);
|
|
447
571
|
}
|
|
448
572
|
const timeout = options?.timeout;
|
|
449
|
-
if (
|
|
573
|
+
if (rpcBackground) {
|
|
450
574
|
return await client._transport.call(method, payload, timeout, options?.trace, true);
|
|
451
575
|
}
|
|
452
576
|
if (options?.trace !== undefined) {
|
|
@@ -501,13 +625,13 @@ export class RpcPipeline {
|
|
|
501
625
|
}
|
|
502
626
|
}
|
|
503
627
|
if (client._seqTracker.getContiguousSeq(ns) !== contigBefore) {
|
|
504
|
-
client.
|
|
628
|
+
client._persistSeq?.(ns);
|
|
505
629
|
}
|
|
506
630
|
result._contig_before = contigBefore;
|
|
507
631
|
}
|
|
508
632
|
postprocessGroupPull(params, result) {
|
|
509
633
|
const client = this.runtime.client;
|
|
510
|
-
const gid = String(params.group_id ?? '').trim();
|
|
634
|
+
const gid = String(params.group_aid ?? params.group_id ?? '').trim();
|
|
511
635
|
if (!gid || !client._seqTracker) {
|
|
512
636
|
return;
|
|
513
637
|
}
|
|
@@ -528,7 +652,7 @@ export class RpcPipeline {
|
|
|
528
652
|
}
|
|
529
653
|
}
|
|
530
654
|
if (client._seqTracker.getContiguousSeq(ns) !== contigBefore) {
|
|
531
|
-
client.
|
|
655
|
+
client._persistSeq?.(ns);
|
|
532
656
|
}
|
|
533
657
|
result._contig_before = contigBefore;
|
|
534
658
|
}
|
|
@@ -548,14 +672,7 @@ export class RpcPipeline {
|
|
|
548
672
|
return;
|
|
549
673
|
}
|
|
550
674
|
const client = this.runtime.client;
|
|
551
|
-
|
|
552
|
-
const rawGroupId = String(params.group_id);
|
|
553
|
-
const normalizedGroupId = normalizeGroupId(rawGroupId);
|
|
554
|
-
if (normalizedGroupId && normalizedGroupId !== rawGroupId) {
|
|
555
|
-
client._clientLog?.debug?.(`call group_id normalized: ${rawGroupId} -> ${normalizedGroupId} method=${method}`);
|
|
556
|
-
}
|
|
557
|
-
params.group_id = normalizedGroupId;
|
|
558
|
-
}
|
|
675
|
+
this.normalizeGroupCallIdentifier(method, params);
|
|
559
676
|
if (params.device_id === undefined) {
|
|
560
677
|
params.device_id = client._deviceId;
|
|
561
678
|
}
|
|
@@ -563,6 +680,42 @@ export class RpcPipeline {
|
|
|
563
680
|
params.slot_id = client._slotId;
|
|
564
681
|
}
|
|
565
682
|
}
|
|
683
|
+
normalizeGroupCallIdentifier(method, params) {
|
|
684
|
+
if (!method.startsWith('group.')) {
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
const record = params;
|
|
688
|
+
const rawEntries = [
|
|
689
|
+
['group_aid', record.group_aid],
|
|
690
|
+
['groupAid', record.groupAid],
|
|
691
|
+
['group_id', record.group_id],
|
|
692
|
+
['groupId', record.groupId],
|
|
693
|
+
];
|
|
694
|
+
const found = rawEntries.find(([, value]) => String(value ?? '').trim());
|
|
695
|
+
if (found) {
|
|
696
|
+
const [key, raw] = found;
|
|
697
|
+
const rawGroupId = String(raw).trim();
|
|
698
|
+
const normalizedGroupId = normalizeGroupId(rawGroupId);
|
|
699
|
+
if (normalizedGroupId) {
|
|
700
|
+
if (normalizedGroupId !== rawGroupId) {
|
|
701
|
+
this.runtime.client._clientLog?.debug?.(`call group identifier normalized: ${key}=${rawGroupId} -> ${normalizedGroupId} method=${method}`);
|
|
702
|
+
}
|
|
703
|
+
const existingGroupId = String(record.group_id ?? record.groupId ?? '').trim();
|
|
704
|
+
if (key === 'group_id' || key === 'groupId') {
|
|
705
|
+
params.group_id = rawGroupId;
|
|
706
|
+
}
|
|
707
|
+
else if (existingGroupId) {
|
|
708
|
+
params.group_id = existingGroupId;
|
|
709
|
+
}
|
|
710
|
+
else {
|
|
711
|
+
params.group_id = normalizedGroupId;
|
|
712
|
+
}
|
|
713
|
+
params.group_aid = normalizedGroupId;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
delete record.groupAid;
|
|
717
|
+
delete record.groupId;
|
|
718
|
+
}
|
|
566
719
|
groupCursorParams(params) {
|
|
567
720
|
const cursorParams = {};
|
|
568
721
|
for (const key of ['device_id', 'slot_id', 'device_name', 'device_type']) {
|