@awiki/dsh-plugin 0.3.5 → 0.3.7-dsh-test.20260831.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.
Files changed (73) hide show
  1. package/README.md +45 -32
  2. package/README.zh.md +33 -28
  3. package/THIRD_PARTY_NOTICES.md +1 -1
  4. package/cordis.patch.yml +3 -1
  5. package/lib/client.js +1348 -637
  6. package/lib/client.js.map +1 -1
  7. package/lib/index.js +989 -393
  8. package/lib/provider.js +57 -16
  9. package/lib/{sdk-adapter-CDLTgHJA.mjs → sdk-adapter-FGaOi8It.mjs} +167 -50
  10. package/lib/typert.host.js +411 -128
  11. package/lib/typert.remote-client.d.ts +19 -5
  12. package/lib/typert.remote-client.d.ts.map +1 -1
  13. package/lib/typert.remote-client.js +411 -128
  14. package/lib/types/client/AwikiDevices.d.ts +28 -0
  15. package/lib/types/client/AwikiDevices.d.ts.map +1 -0
  16. package/lib/types/client/AwikiDevices.js +85 -0
  17. package/lib/types/client/AwikiDevices.js.map +1 -0
  18. package/lib/types/client/AwikiIdentityAccess.d.ts +6 -5
  19. package/lib/types/client/AwikiIdentityAccess.d.ts.map +1 -1
  20. package/lib/types/client/AwikiIdentityAccess.js +88 -27
  21. package/lib/types/client/AwikiIdentityAccess.js.map +1 -1
  22. package/lib/types/client/AwikiOverlay.d.ts.map +1 -1
  23. package/lib/types/client/AwikiOverlay.js +5 -12
  24. package/lib/types/client/AwikiOverlay.js.map +1 -1
  25. package/lib/types/client/AwikiRecoveryForm.d.ts.map +1 -1
  26. package/lib/types/client/AwikiRecoveryForm.js +1 -1
  27. package/lib/types/client/AwikiRecoveryForm.js.map +1 -1
  28. package/lib/types/client/controller.d.ts +20 -28
  29. package/lib/types/client/controller.d.ts.map +1 -1
  30. package/lib/types/client/controller.js +41 -162
  31. package/lib/types/client/controller.js.map +1 -1
  32. package/lib/types/client/index.d.ts.map +1 -1
  33. package/lib/types/client/index.js +8 -2
  34. package/lib/types/client/index.js.map +1 -1
  35. package/lib/types/client/slots.d.ts +10 -6
  36. package/lib/types/client/slots.d.ts.map +1 -1
  37. package/lib/types/conversation-preferences.d.ts.map +1 -1
  38. package/lib/types/conversation-preferences.js +0 -17
  39. package/lib/types/conversation-preferences.js.map +1 -1
  40. package/lib/types/index.d.ts +54 -13
  41. package/lib/types/index.d.ts.map +1 -1
  42. package/lib/types/index.js +739 -221
  43. package/lib/types/index.js.map +1 -1
  44. package/lib/types/listener-state.d.ts +5 -3
  45. package/lib/types/listener-state.d.ts.map +1 -1
  46. package/lib/types/listener-state.js +28 -13
  47. package/lib/types/listener-state.js.map +1 -1
  48. package/lib/types/listener.d.ts +9 -32
  49. package/lib/types/listener.d.ts.map +1 -1
  50. package/lib/types/listener.js +11 -127
  51. package/lib/types/listener.js.map +1 -1
  52. package/lib/types/provider-api.d.ts +99 -7
  53. package/lib/types/provider-api.d.ts.map +1 -1
  54. package/lib/types/provider.d.ts +7 -1
  55. package/lib/types/provider.d.ts.map +1 -1
  56. package/lib/types/provider.js +58 -15
  57. package/lib/types/provider.js.map +1 -1
  58. package/lib/types/realtime-supervisor.d.ts +54 -0
  59. package/lib/types/realtime-supervisor.d.ts.map +1 -0
  60. package/lib/types/realtime-supervisor.js +242 -0
  61. package/lib/types/realtime-supervisor.js.map +1 -0
  62. package/lib/types/sdk-adapter.d.ts +31 -5
  63. package/lib/types/sdk-adapter.d.ts.map +1 -1
  64. package/lib/types/sdk-adapter.js +162 -59
  65. package/lib/types/sdk-adapter.js.map +1 -1
  66. package/lib/types/types.d.ts +76 -27
  67. package/lib/types/types.d.ts.map +1 -1
  68. package/lib/types/types.js.map +1 -1
  69. package/package.json +5 -2
  70. package/lib/types/profile-state.d.ts +0 -11
  71. package/lib/types/profile-state.d.ts.map +0 -1
  72. package/lib/types/profile-state.js +0 -48
  73. package/lib/types/profile-state.js.map +0 -1
package/lib/provider.js CHANGED
@@ -1,26 +1,67 @@
1
- import { t as RustSdkAdapter } from "./sdk-adapter-CDLTgHJA.mjs";
1
+ import { t as RustSdkAdapter } from "./sdk-adapter-FGaOi8It.mjs";
2
2
  import { openImCoreNodeClient } from "@awiki/im-core-node";
3
3
  //#region lib/types/provider.js
4
4
  /** Production AWiki provider backed by the versioned Rust IM Core Node bridge. */
5
5
  /** Cordis plugin name used by Loader diagnostics. */
6
6
  const name = "awiki-rust-sdk-provider";
7
- /** The AWiki service must own its provider registry before this plugin loads. */
8
- const inject = ["awiki"];
7
+ /** AWiki orchestration and the independent identity service must load first. */
8
+ const inject = ["awiki", "anpIdentity"];
9
+ const IDENTITY_PROVIDER_CAPABILITIES = [
10
+ "IDENTITY_READ",
11
+ "IDENTITY_CREATE",
12
+ "IDENTITY_IMPORT",
13
+ "IDENTITY_SIGN",
14
+ "IDENTITY_ECDH_SEALED",
15
+ "IDENTITY_DOCUMENT_UPDATE",
16
+ "IDENTITY_KEY_LIFECYCLE",
17
+ "IDENTITY_DELETE",
18
+ "IDENTITY_HTTP_SIGNATURE",
19
+ "AWIKI_LEGACY_ROOT_TRANSFER_V1"
20
+ ];
9
21
  /** Register one SDK client whose disposal follows this provider's fiber. */
10
22
  function apply(ctx) {
11
- ctx.effect(() => ctx.awiki.registerClientFactory((options) => new RustSdkAdapter(openImCoreNodeClient({
12
- stateRoot: options.stateRoot,
13
- serviceBaseUrl: options.userServiceUrl,
14
- didDomain: options.userServiceDomain,
15
- userServiceEndpoint: options.userServiceUrl,
16
- messageServiceEndpoint: options.messageServiceUrl,
17
- mailServiceEndpoint: options.mailServiceUrl,
18
- anpServiceEndpoint: options.messageServiceUrl,
19
- anpServiceDid: options.messageServiceDid,
20
- multiDeviceHandleRecoveryEnabled: true,
21
- multiDeviceAudience: "awiki-user-service",
22
- externalHttpAllowInsecureLoopbackForTesting: options.allowInsecureLoopbackForTesting
23
- }))), "awiki Rust SDK client");
23
+ ctx.effect(() => {
24
+ const lease = ctx.anpIdentity.acquireProvider({
25
+ consumer: "@awiki/dsh-plugin",
26
+ capabilities: [...IDENTITY_PROVIDER_CAPABILITIES],
27
+ ttlSeconds: 3600
28
+ });
29
+ try {
30
+ const unregister = ctx.awiki.registerClientFactory((options) => {
31
+ const openOptions = {
32
+ stateRoot: options.stateRoot,
33
+ serviceBaseUrl: options.userServiceUrl,
34
+ didDomain: options.userServiceDomain,
35
+ userServiceEndpoint: options.userServiceUrl,
36
+ messageServiceEndpoint: options.messageServiceUrl,
37
+ mailServiceEndpoint: options.mailServiceUrl,
38
+ anpServiceEndpoint: options.messageServiceUrl,
39
+ anpServiceDid: options.messageServiceDid,
40
+ clientVersionInfo: {
41
+ product: "awiki-daemon",
42
+ release: "0815",
43
+ version: "0.1.91"
44
+ },
45
+ multiDeviceHandleRecoveryEnabled: true,
46
+ multiDeviceDeviceRevokeEnabled: true,
47
+ multiDeviceAudience: "awiki-user-service",
48
+ externalHttpAllowInsecureLoopbackForTesting: options.allowInsecureLoopbackForTesting,
49
+ identityProvider: lease
50
+ };
51
+ return new RustSdkAdapter(openImCoreNodeClient(openOptions));
52
+ });
53
+ return async () => {
54
+ try {
55
+ await unregister();
56
+ } finally {
57
+ lease.dispose();
58
+ }
59
+ };
60
+ } catch (error) {
61
+ lease.dispose();
62
+ throw error;
63
+ }
64
+ }, "awiki Rust SDK client");
24
65
  }
25
66
  //#endregion
26
67
  export { apply, inject, name };
@@ -20,11 +20,12 @@ const RUST_FAILURE_CODES = {
20
20
  auth_revoked: "identity-recovery-required",
21
21
  conflict: "conflict",
22
22
  join_required: "handle-unavailable",
23
- state_in_use: "state-in-use",
23
+ state_in_use: "conflict",
24
24
  rate_limited: "rate-limited",
25
25
  timeout: "network",
26
26
  transport_unavailable: "network",
27
27
  sync_failed: "network",
28
+ sync_blocked: "conflict",
28
29
  session_expired: "network",
29
30
  attachment_transfer_network: "network",
30
31
  recovery_reconciliation_unavailable: "network",
@@ -33,15 +34,36 @@ const RUST_FAILURE_CODES = {
33
34
  /** Closed provider error consumed by the Host's fixed public failure mapping. */
34
35
  var AwikiSdkError = class extends Error {
35
36
  code;
37
+ realtimeFailureCode;
36
38
  name = "AwikiSdkError";
37
- constructor(code) {
39
+ constructor(code, realtimeFailureCode) {
38
40
  super(`AWiki SDK operation failed: ${code}`);
39
41
  this.code = code;
42
+ this.realtimeFailureCode = realtimeFailureCode;
40
43
  }
41
44
  };
42
45
  function fail(code = "remote") {
43
46
  throw new AwikiSdkError(code);
44
47
  }
48
+ const REALTIME_RETRY_WARNING_PRIORITY = [
49
+ "sync.retry.local_state.actor_closed",
50
+ "sync.retry.local_state.database_busy",
51
+ "sync.retry.local_state.constraint_failed",
52
+ "sync.retry.local_state.schema_unavailable",
53
+ "sync.retry.local_state.storage_unavailable",
54
+ "sync.retry.local_state.codec_unavailable",
55
+ "sync.retry.local_state.other",
56
+ "sync.retry.transport_unavailable",
57
+ "sync.retry.service_unavailable",
58
+ "sync.retry.local_state_unavailable"
59
+ ];
60
+ function realtimeSyncFailureCode(status, warnings) {
61
+ if (status === "retryable_failure") return REALTIME_RETRY_WARNING_PRIORITY.find((code) => warnings.includes(code)) ?? "sync.retryable_failure";
62
+ if (status === "recovery_required") return "sync.recovery_required";
63
+ if (status === "auth_revoked") return "sync.auth_revoked";
64
+ if (status === "blocked") return "sync.blocked";
65
+ return "sync.unexpected_status";
66
+ }
45
67
  function mapError(error, ambiguousSend = false) {
46
68
  if (error instanceof AwikiSdkError) throw error;
47
69
  let code = "remote";
@@ -103,11 +125,6 @@ function uint32(value) {
103
125
  if (!Number.isSafeInteger(value) || value < 0 || value > 4294967295) fail();
104
126
  return value;
105
127
  }
106
- function recoveryE2eeGroupCount(impact) {
107
- if (typeof impact !== "object" || impact === null) fail();
108
- const value = impact;
109
- return uint32(value.unsupportedE2eeGroupCount !== void 0 ? value.unsupportedE2eeGroupCount : value.unsupportedE2EeGroupCount);
110
- }
111
128
  function boolean(value) {
112
129
  if (typeof value !== "boolean") fail();
113
130
  return value;
@@ -197,6 +214,26 @@ function identity(value) {
197
214
  registeredAt: safeInteger(value.registeredAtMs)
198
215
  };
199
216
  }
217
+ function joinProgress(value) {
218
+ return {
219
+ joinSessionId: required(value.joinSessionId),
220
+ localPhase: value.localPhase,
221
+ remoteState: value.remoteState,
222
+ expiresAt: required(value.expiresAt),
223
+ ...value.sas === void 0 ? {} : { sas: required(value.sas) },
224
+ completed: boolean(value.completed),
225
+ ...value.identity === void 0 ? {} : { identity: identity(value.identity) }
226
+ };
227
+ }
228
+ function adminJoinProgress(value) {
229
+ return {
230
+ joinSessionId: required(value.joinSessionId),
231
+ localPhase: value.localPhase,
232
+ remoteState: value.remoteState,
233
+ expiresAt: required(value.expiresAt),
234
+ ...value.sas === void 0 ? {} : { sas: required(value.sas) }
235
+ };
236
+ }
200
237
  function profile(value) {
201
238
  return {
202
239
  did: required(value.did),
@@ -307,17 +344,25 @@ var RustSdkAdapter = class {
307
344
  client;
308
345
  attachmentConversations = /* @__PURE__ */ new Map();
309
346
  disposal;
347
+ realtime;
348
+ agentInbox;
310
349
  listener;
311
350
  constructor(client) {
312
351
  this.client = Promise.resolve(client);
313
- this.listener = {
352
+ this.realtime = {
314
353
  syncNow: (reason) => this.listenerSyncNow(reason),
315
- startRealtime: () => this.listenerStartRealtime(),
354
+ startRealtime: () => this.listenerStartRealtime()
355
+ };
356
+ this.agentInbox = {
316
357
  listConversations: (request) => this.listenerConversations(request),
317
358
  getHistory: (request) => this.listenerHistory(request),
318
359
  markConversationRead: (conversationId) => this.markConversationRead(conversationId),
319
360
  sendText: (request) => this.sendText(request)
320
361
  };
362
+ this.listener = {
363
+ ...this.realtime,
364
+ ...this.agentInbox
365
+ };
321
366
  }
322
367
  async run(operation, ambiguousSend = false) {
323
368
  try {
@@ -520,8 +565,7 @@ var RustSdkAdapter = class {
520
565
  return this.run(async (client) => {
521
566
  const result = await client.syncNow({ reason });
522
567
  if (result.status === "idle" || result.status === "changed") return;
523
- if (result.status === "auth_revoked") fail("identity-recovery-required");
524
- fail("network");
568
+ throw new AwikiSdkError(result.status === "auth_revoked" ? "identity-recovery-required" : "network", realtimeSyncFailureCode(result.status, result.warnings));
525
569
  });
526
570
  }
527
571
  listenerStartRealtime() {
@@ -529,6 +573,9 @@ var RustSdkAdapter = class {
529
573
  const session = await client.startRealtime();
530
574
  return {
531
575
  nextEvent: () => this.run(() => session.nextEvent()),
576
+ getStatus: () => this.run(async () => {
577
+ return { connected: (await session.getStatus()).connected };
578
+ }),
532
579
  stop: () => this.run(() => session.stop())
533
580
  };
534
581
  });
@@ -591,7 +638,114 @@ var RustSdkAdapter = class {
591
638
  });
592
639
  }
593
640
  registerIdentity(request) {
594
- return this.run(async (client) => identity(await client.completeRegistration(request)));
641
+ return this.run(async (client) => {
642
+ const value = await client.completeRegistrationWithOutcome(request);
643
+ if (value.status === "registered") return {
644
+ status: "registered",
645
+ identity: identity(value.identity)
646
+ };
647
+ return {
648
+ status: "join-required",
649
+ continuationId: required(value.existingHandle.continuationId),
650
+ fullHandle: required(value.existingHandle.fullHandle),
651
+ mode: value.existingHandle.mode === "handle_recovery_rebind" ? "handle-recovery-rebind" : "ordinary",
652
+ requiresUserPresence: boolean(value.existingHandle.requiresUserPresence)
653
+ };
654
+ });
655
+ }
656
+ beginDeviceJoin(request) {
657
+ return this.run(async (client) => joinProgress(await client.beginPreparedRegistrationJoin(request)));
658
+ }
659
+ getDeviceJoinStatus(joinSessionId) {
660
+ return this.run(async (client) => joinProgress(await client.resumePreparedRegistrationJoin({ joinSessionId })));
661
+ }
662
+ listLocalDeviceJoinSessions() {
663
+ return this.run(async (client) => (await client.listLocalDeviceJoinSessions()).map((value) => ({
664
+ joinSessionId: required(value.joinSessionId),
665
+ side: value.side,
666
+ localPhase: value.localPhase,
667
+ expiresAt: required(value.expiresAt)
668
+ })));
669
+ }
670
+ cancelDeviceJoin(joinSessionId) {
671
+ return this.run(async (client) => {
672
+ const value = await client.cancelPreparedRegistrationJoin({ joinSessionId });
673
+ return {
674
+ joinSessionId: required(value.joinSessionId),
675
+ side: value.side,
676
+ localPhase: value.localPhase,
677
+ expiresAt: required(value.expiresAt)
678
+ };
679
+ });
680
+ }
681
+ getCurrentDeviceSummary() {
682
+ return this.run(async (client) => {
683
+ const value = await client.getCurrentDeviceSummary();
684
+ return {
685
+ ...value.role === void 0 ? {} : { role: value.role },
686
+ readiness: value.readiness,
687
+ canManage: boolean(value.canManage)
688
+ };
689
+ });
690
+ }
691
+ syncDeviceManagement() {
692
+ return this.run(async (client) => {
693
+ await client.syncNow({ reason: "foreground_reconcile" });
694
+ });
695
+ }
696
+ getDeviceRegistry() {
697
+ return this.run(async (client) => (await client.getDeviceRegistry()).devices.map((value) => ({
698
+ deviceId: required(value.protocolDeviceId),
699
+ status: value.status,
700
+ role: value.role,
701
+ managementReady: boolean(value.managementReady),
702
+ isCurrent: boolean(value.isCurrent)
703
+ })));
704
+ }
705
+ listLocalDeviceJoinRequests() {
706
+ return this.run(async (client) => (await client.listLocalDeviceJoinRequests()).map((value) => ({
707
+ joinSessionId: required(value.joinSessionId),
708
+ candidateKeyFingerprint: required(value.candidateKeyFingerprint),
709
+ issuedAt: required(value.issuedAt),
710
+ expiresAt: required(value.expiresAt),
711
+ state: value.state,
712
+ claimedByCurrentDevice: boolean(value.claimedByCurrentDevice),
713
+ canStartVerification: boolean(value.canStartVerification)
714
+ })));
715
+ }
716
+ startDeviceJoinVerification(request) {
717
+ return this.run(async (client) => adminJoinProgress(await client.startDeviceJoinVerification(request)));
718
+ }
719
+ getLocalDeviceJoinVerificationProgress(joinSessionId) {
720
+ return this.run(async (client) => adminJoinProgress(await client.getLocalDeviceJoinVerificationProgress({ joinSessionId })));
721
+ }
722
+ prepareDeviceJoinApproval(joinSessionId) {
723
+ return this.run(async (client) => {
724
+ return { approvalHandle: required((await client.prepareDeviceJoinApproval({
725
+ joinSessionId,
726
+ sasConfirmed: true
727
+ })).approvalHandle) };
728
+ });
729
+ }
730
+ confirmDeviceJoinApproval(approvalHandle) {
731
+ return this.run(async (client) => adminJoinProgress(await client.confirmDeviceJoinApproval({
732
+ approvalHandle,
733
+ userPresenceConfirmed: true
734
+ })));
735
+ }
736
+ rejectDeviceJoin(joinSessionId, reason) {
737
+ return this.run(async (client) => adminJoinProgress(await client.rejectDeviceJoin({
738
+ joinSessionId,
739
+ reason
740
+ })));
741
+ }
742
+ revokeDevice(deviceId) {
743
+ return this.run(async (client) => {
744
+ await client.revokeDevice({
745
+ targetDeviceId: deviceId,
746
+ userPresenceConfirmed: true
747
+ });
748
+ });
595
749
  }
596
750
  updateDisplayName(request) {
597
751
  return this.run(async (client) => identity(await client.updateDisplayName(request.displayName)));
@@ -616,9 +770,7 @@ var RustSdkAdapter = class {
616
770
  ...value.failureCode === void 0 ? {} : { failureCode: value.failureCode },
617
771
  retryable: boolean(value.retryable),
618
772
  localOrdinaryDataWillMigrate: boolean(value.impact.localOrdinaryDataWillMigrate),
619
- otherDevicesMustRejoin: boolean(value.impact.otherDevicesMustRejoin),
620
- unsupportedE2eeGroupCount: recoveryE2eeGroupCount(value.impact),
621
- unsupportedDidOnlyGroupCount: uint32(value.impact.unsupportedDidOnlyGroupCount)
773
+ otherDevicesMustRejoin: boolean(value.impact.otherDevicesMustRejoin)
622
774
  };
623
775
  }
624
776
  sendRecoveryOtp(request) {
@@ -720,41 +872,6 @@ var RustSdkAdapter = class {
720
872
  member
721
873
  })));
722
874
  }
723
- resumeGroupRebindRecovery() {
724
- return this.run(async (client) => {
725
- const value = await client.resumeGroupRebindRecovery(100);
726
- const journal = value;
727
- const statuses = /* @__PURE__ */ new Map();
728
- for (const item of journal.items ?? []) {
729
- const { groupDid: rawGroupDid, layer: rawLayer, phase: rawPhase } = item;
730
- if (typeof rawGroupDid !== "string" || typeof rawLayer !== "string" || typeof rawPhase !== "string" || typeof item.blocked !== "boolean") throw new TypeError("invalid group recovery item");
731
- const groupDid = required(rawGroupDid);
732
- const layer = required(rawLayer);
733
- const phase = required(rawPhase);
734
- if (layer !== "p4" && layer !== "p6") throw new TypeError("invalid group recovery item");
735
- if (phase === "complete") continue;
736
- const status = item.blocked || phase === "blocked" ? "blocked" : "pending";
737
- if (statuses.get(groupDid) !== "blocked") statuses.set(groupDid, status);
738
- }
739
- for (const group of journal.sendPausedGroups ?? []) {
740
- if (typeof group !== "string") throw new TypeError("invalid paused recovery group");
741
- const groupDid = required(group);
742
- if (!statuses.has(groupDid)) statuses.set(groupDid, "pending");
743
- }
744
- const items = [...statuses].map(([groupDid, status]) => ({
745
- groupDid,
746
- status
747
- }));
748
- const hasJournal = journal.items !== void 0 || journal.sendPausedGroups !== void 0;
749
- return {
750
- processed: uint32(value.processed),
751
- completed: uint32(value.completed),
752
- pending: hasJournal ? items.filter((item) => item.status === "pending").length : uint32(value.pending),
753
- blocked: hasJournal ? items.filter((item) => item.status === "blocked").length : uint32(value.blocked),
754
- items
755
- };
756
- });
757
- }
758
875
  listConversations(request) {
759
876
  return this.run(async (client) => {
760
877
  const conversations = await client.listConversations(request);