@arbidocs/client 0.4.169 → 0.5.0

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/dist/index.d.cts CHANGED
@@ -38763,6 +38763,41 @@ declare function createWorkspaceKeys(deps: WorkspaceKeysDeps): WorkspaceKeys;
38763
38763
  /** The workspace a 409 `{detail: {code: "workspace_key_required", workspace_ext_id}}` names. */
38764
38764
  declare function workspaceKeyRequiredOf(body: unknown): string | null;
38765
38765
 
38766
+ /**
38767
+ * Workspace opens, one at a time.
38768
+ *
38769
+ * The server keeps ONE open ("active") workspace per session, and every `POST /workspace/{id}/open`
38770
+ * replaces it. Every request that does not name its workspace reads that one. Two opens in flight
38771
+ * at once can land in either order, so the server may end on a workspace the client already left
38772
+ * while the client believes the other is open: the next lists read would return the wrong
38773
+ * workspace's data. So every open on a client goes through this queue (the SDK's
38774
+ * `selectWorkspace`, the re-open after a lost workspace, the re-open after a re-login, the
38775
+ * open-all): the server applies them in the order they were asked for, and ends on the last.
38776
+ *
38777
+ * The queue also says when the active workspace may have changed: `generation` moves whenever an
38778
+ * open that may change it starts (or one fails, leaving it unknown), so a read can tell whether
38779
+ * its response may belong to another workspace than the one it was issued for.
38780
+ */
38781
+ interface WorkspaceOpens {
38782
+ /**
38783
+ * Run `open` alone: after every open queued before it, before any queued after it. `target` is
38784
+ * read when it starts: the workspace it leaves active, or `null` when that is not one known
38785
+ * workspace (an open-all).
38786
+ */
38787
+ run<T>(target: () => string | null, open: () => Promise<T>): Promise<T>;
38788
+ /** An open is running or waiting. */
38789
+ readonly busy: boolean;
38790
+ /** Moves whenever an open that may change the server's active workspace starts or fails. */
38791
+ readonly generation: number;
38792
+ /** The workspace the last open left active on the server; `null` when unknown. */
38793
+ readonly active: string | null;
38794
+ /** Resolves once no open is running or waiting. */
38795
+ idle(): Promise<void>;
38796
+ /** The server session changed (a login, a re-login, a sign-out): nothing is known to be open. */
38797
+ reset(): void;
38798
+ }
38799
+ declare function createWorkspaceOpens(): WorkspaceOpens;
38800
+
38766
38801
  /**
38767
38802
  * storage.ts - IndexedDB Storage Module
38768
38803
  *
@@ -39098,6 +39133,12 @@ interface ArbiClient {
39098
39133
  * refused with 409 `workspace_key_required` primes the workspace it names and is sent again.
39099
39134
  */
39100
39135
  workspaceKeys: WorkspaceKeys;
39136
+ /**
39137
+ * Every workspace `/open` on this client, one at a time and in the order asked (the server keeps
39138
+ * one active workspace per session, so concurrent opens could leave it on a workspace the client
39139
+ * left). The SDK's `selectWorkspace` and the re-opens below all go through it.
39140
+ */
39141
+ workspaceOpens: WorkspaceOpens;
39101
39142
  /** High-level auth operations */
39102
39143
  auth: {
39103
39144
  register(params: RegisterParams): Promise<RegisterResult>;
@@ -39306,6 +39347,11 @@ interface OpenAllDeps {
39306
39347
  wrapped_key?: string | null;
39307
39348
  }> | null>;
39308
39349
  workspaceOpenProvider: WorkspaceOpenProvider;
39350
+ /**
39351
+ * The workspace to open last, so the session's active workspace ends on it (each `/open` makes
39352
+ * its workspace the active one): the selected workspace.
39353
+ */
39354
+ lastWorkspace?: () => string | null;
39309
39355
  }
39310
39356
  /**
39311
39357
  * Returns `openAllWorkspaces()`: seal every workspace key the user holds to this server session
@@ -39316,4 +39362,4 @@ interface OpenAllDeps {
39316
39362
  */
39317
39363
  declare function createAllWorkspacesOpener(deps: OpenAllDeps): () => Promise<void>;
39318
39364
 
39319
- export { type $defs, ACCESS_TOKEN_STORAGE_KEY, API_PREFIX, type ArbiClient, type ArbiClientOptions, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, CALL_KEY_BYTES, CHAT_KEY_BYTES, type CallPeer, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, ENCRYPTED_RECOVERY_KEY_SIZE, type KeyLoginCredentials, type KeyPair, type ListedWorkspaceKey, type LoginCredentials, type LoginParams, type LoginProfile, type LoginProvider, type LoginRequest, type LoginResponse, type LoginResult, type LoginWithKeyParams, type OfflineSealer, type OfflineSealerOptions, type OnReloginSuccess, type OpenAllDeps, type ParsedRecoveryUrl, type PasswordChangeCredentials, RECOVERY_KEY_ERRORS, type RecoveryKeyParams, type RecoveryKeyValidationResult, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type ReloginDeps, type ReloginFailure, type ReloginHandler, type ReopenDeps, SECURE_MAIL_KEY_BYTES, type SealedSecureMail, type SecureMailCiphertexts, type SecureMailClaim, type SessionClaims, type SessionData, type SessionKeys, type SessionManager, type SessionManagerOptions, type SessionPersistence, type SessionSignIn, type SessionState, type SessionStateStorage, type SessionUser, type SignInHooks, type SsoTokenSource, type StoredSessionState, type TokenProvider, UNENCRYPTED_RECOVERY_KEY_SIZE, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceKeys, type WorkspaceOpenProvider, type WsAgentDmStatusMessage, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsChatMessageMessage, type WsChatReadMessage, type WsChatUpdatedMessage, type WsConnectionClosedMessage, type WsConversationMessagePostedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, authRequestError, base64Decode, base64Encode, base64ToBytes, base64UrlToBytes, browserSessionStateStorage, buildCallFragment, buildCallLink, buildWebSocketUrl, bytesToBase64, bytesToBase64Url, canPersistSession, changePassword, clearAllData, clearSession, type components, computeSharedSecret, createAllWorkspacesOpener, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createOfflineSealer, createRecoveryFile, createRecoveryUrl, createReloginHandler, createSessionManager, createWorkspaceKeys, createWorkspaceReopener, decodeCallKey, decodeSecureMailKey, decryptCallTitle, decryptFile, decryptMessage, decryptMessageWithSharedSecret, decryptRecoveryKey, decryptWithChatKey, deriveDirectChatKey, deriveEncryptionKeypairFromSigning, derivePublicKey, encodeCallKey, encryptCallTitle, encryptFile, encryptMessage, encryptMessageWithSharedSecret, encryptRecoveryKey, encryptWithChatKey, encryptionKeypairFromSigningKey, generateCallKey, generateChatKey, generateIdentityKeypair, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRegistrationCredentials, generateUserKeypairs, getRecoveryKeyFilename, getSession, getUserEncryptionKeypair, hasSession, identityFromLoginResponse, initSodium, initializeDatabase, isEncryptedRecoveryKey, isMessageType, openCallKeyOf, openSealedCallKey, openSealedChatKey, openSecureMail, type operations, parseCallFragment, parseRecoveryUrl, parseServerMessage, passwordChangeErrorMessage, type paths, prewarmKeyPairs, readSessionClaims, saveSession, sealCallKey, sealCallKeyForPeers, sealChatKey, sealKeyForSession, sealSecureMail, sealedBoxDecrypt, sealedBoxEncrypt, secureMailClaim, signMessage, unlockIdentityWithPassword, unwrapIdentityKey, unwrapWorkspaceKey, updateWrappedIdentityKey, validateRecoveryKeyFile, type webhooks, workspaceKeyRequiredOf, wrapIdentityKey };
39365
+ export { type $defs, ACCESS_TOKEN_STORAGE_KEY, API_PREFIX, type ArbiClient, type ArbiClientOptions, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, CALL_KEY_BYTES, CHAT_KEY_BYTES, type CallPeer, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, ENCRYPTED_RECOVERY_KEY_SIZE, type KeyLoginCredentials, type KeyPair, type ListedWorkspaceKey, type LoginCredentials, type LoginParams, type LoginProfile, type LoginProvider, type LoginRequest, type LoginResponse, type LoginResult, type LoginWithKeyParams, type OfflineSealer, type OfflineSealerOptions, type OnReloginSuccess, type OpenAllDeps, type ParsedRecoveryUrl, type PasswordChangeCredentials, RECOVERY_KEY_ERRORS, type RecoveryKeyParams, type RecoveryKeyValidationResult, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type ReloginDeps, type ReloginFailure, type ReloginHandler, type ReopenDeps, SECURE_MAIL_KEY_BYTES, type SealedSecureMail, type SecureMailCiphertexts, type SecureMailClaim, type SessionClaims, type SessionData, type SessionKeys, type SessionManager, type SessionManagerOptions, type SessionPersistence, type SessionSignIn, type SessionState, type SessionStateStorage, type SessionUser, type SignInHooks, type SsoTokenSource, type StoredSessionState, type TokenProvider, UNENCRYPTED_RECOVERY_KEY_SIZE, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceKeys, type WorkspaceOpenProvider, type WorkspaceOpens, type WsAgentDmStatusMessage, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsChatMessageMessage, type WsChatReadMessage, type WsChatUpdatedMessage, type WsConnectionClosedMessage, type WsConversationMessagePostedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, authRequestError, base64Decode, base64Encode, base64ToBytes, base64UrlToBytes, browserSessionStateStorage, buildCallFragment, buildCallLink, buildWebSocketUrl, bytesToBase64, bytesToBase64Url, canPersistSession, changePassword, clearAllData, clearSession, type components, computeSharedSecret, createAllWorkspacesOpener, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createOfflineSealer, createRecoveryFile, createRecoveryUrl, createReloginHandler, createSessionManager, createWorkspaceKeys, createWorkspaceOpens, createWorkspaceReopener, decodeCallKey, decodeSecureMailKey, decryptCallTitle, decryptFile, decryptMessage, decryptMessageWithSharedSecret, decryptRecoveryKey, decryptWithChatKey, deriveDirectChatKey, deriveEncryptionKeypairFromSigning, derivePublicKey, encodeCallKey, encryptCallTitle, encryptFile, encryptMessage, encryptMessageWithSharedSecret, encryptRecoveryKey, encryptWithChatKey, encryptionKeypairFromSigningKey, generateCallKey, generateChatKey, generateIdentityKeypair, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRegistrationCredentials, generateUserKeypairs, getRecoveryKeyFilename, getSession, getUserEncryptionKeypair, hasSession, identityFromLoginResponse, initSodium, initializeDatabase, isEncryptedRecoveryKey, isMessageType, openCallKeyOf, openSealedCallKey, openSealedChatKey, openSecureMail, type operations, parseCallFragment, parseRecoveryUrl, parseServerMessage, passwordChangeErrorMessage, type paths, prewarmKeyPairs, readSessionClaims, saveSession, sealCallKey, sealCallKeyForPeers, sealChatKey, sealKeyForSession, sealSecureMail, sealedBoxDecrypt, sealedBoxEncrypt, secureMailClaim, signMessage, unlockIdentityWithPassword, unwrapIdentityKey, unwrapWorkspaceKey, updateWrappedIdentityKey, validateRecoveryKeyFile, type webhooks, workspaceKeyRequiredOf, wrapIdentityKey };
package/dist/index.d.ts CHANGED
@@ -38763,6 +38763,41 @@ declare function createWorkspaceKeys(deps: WorkspaceKeysDeps): WorkspaceKeys;
38763
38763
  /** The workspace a 409 `{detail: {code: "workspace_key_required", workspace_ext_id}}` names. */
38764
38764
  declare function workspaceKeyRequiredOf(body: unknown): string | null;
38765
38765
 
38766
+ /**
38767
+ * Workspace opens, one at a time.
38768
+ *
38769
+ * The server keeps ONE open ("active") workspace per session, and every `POST /workspace/{id}/open`
38770
+ * replaces it. Every request that does not name its workspace reads that one. Two opens in flight
38771
+ * at once can land in either order, so the server may end on a workspace the client already left
38772
+ * while the client believes the other is open: the next lists read would return the wrong
38773
+ * workspace's data. So every open on a client goes through this queue (the SDK's
38774
+ * `selectWorkspace`, the re-open after a lost workspace, the re-open after a re-login, the
38775
+ * open-all): the server applies them in the order they were asked for, and ends on the last.
38776
+ *
38777
+ * The queue also says when the active workspace may have changed: `generation` moves whenever an
38778
+ * open that may change it starts (or one fails, leaving it unknown), so a read can tell whether
38779
+ * its response may belong to another workspace than the one it was issued for.
38780
+ */
38781
+ interface WorkspaceOpens {
38782
+ /**
38783
+ * Run `open` alone: after every open queued before it, before any queued after it. `target` is
38784
+ * read when it starts: the workspace it leaves active, or `null` when that is not one known
38785
+ * workspace (an open-all).
38786
+ */
38787
+ run<T>(target: () => string | null, open: () => Promise<T>): Promise<T>;
38788
+ /** An open is running or waiting. */
38789
+ readonly busy: boolean;
38790
+ /** Moves whenever an open that may change the server's active workspace starts or fails. */
38791
+ readonly generation: number;
38792
+ /** The workspace the last open left active on the server; `null` when unknown. */
38793
+ readonly active: string | null;
38794
+ /** Resolves once no open is running or waiting. */
38795
+ idle(): Promise<void>;
38796
+ /** The server session changed (a login, a re-login, a sign-out): nothing is known to be open. */
38797
+ reset(): void;
38798
+ }
38799
+ declare function createWorkspaceOpens(): WorkspaceOpens;
38800
+
38766
38801
  /**
38767
38802
  * storage.ts - IndexedDB Storage Module
38768
38803
  *
@@ -39098,6 +39133,12 @@ interface ArbiClient {
39098
39133
  * refused with 409 `workspace_key_required` primes the workspace it names and is sent again.
39099
39134
  */
39100
39135
  workspaceKeys: WorkspaceKeys;
39136
+ /**
39137
+ * Every workspace `/open` on this client, one at a time and in the order asked (the server keeps
39138
+ * one active workspace per session, so concurrent opens could leave it on a workspace the client
39139
+ * left). The SDK's `selectWorkspace` and the re-opens below all go through it.
39140
+ */
39141
+ workspaceOpens: WorkspaceOpens;
39101
39142
  /** High-level auth operations */
39102
39143
  auth: {
39103
39144
  register(params: RegisterParams): Promise<RegisterResult>;
@@ -39306,6 +39347,11 @@ interface OpenAllDeps {
39306
39347
  wrapped_key?: string | null;
39307
39348
  }> | null>;
39308
39349
  workspaceOpenProvider: WorkspaceOpenProvider;
39350
+ /**
39351
+ * The workspace to open last, so the session's active workspace ends on it (each `/open` makes
39352
+ * its workspace the active one): the selected workspace.
39353
+ */
39354
+ lastWorkspace?: () => string | null;
39309
39355
  }
39310
39356
  /**
39311
39357
  * Returns `openAllWorkspaces()`: seal every workspace key the user holds to this server session
@@ -39316,4 +39362,4 @@ interface OpenAllDeps {
39316
39362
  */
39317
39363
  declare function createAllWorkspacesOpener(deps: OpenAllDeps): () => Promise<void>;
39318
39364
 
39319
- export { type $defs, ACCESS_TOKEN_STORAGE_KEY, API_PREFIX, type ArbiClient, type ArbiClientOptions, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, CALL_KEY_BYTES, CHAT_KEY_BYTES, type CallPeer, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, ENCRYPTED_RECOVERY_KEY_SIZE, type KeyLoginCredentials, type KeyPair, type ListedWorkspaceKey, type LoginCredentials, type LoginParams, type LoginProfile, type LoginProvider, type LoginRequest, type LoginResponse, type LoginResult, type LoginWithKeyParams, type OfflineSealer, type OfflineSealerOptions, type OnReloginSuccess, type OpenAllDeps, type ParsedRecoveryUrl, type PasswordChangeCredentials, RECOVERY_KEY_ERRORS, type RecoveryKeyParams, type RecoveryKeyValidationResult, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type ReloginDeps, type ReloginFailure, type ReloginHandler, type ReopenDeps, SECURE_MAIL_KEY_BYTES, type SealedSecureMail, type SecureMailCiphertexts, type SecureMailClaim, type SessionClaims, type SessionData, type SessionKeys, type SessionManager, type SessionManagerOptions, type SessionPersistence, type SessionSignIn, type SessionState, type SessionStateStorage, type SessionUser, type SignInHooks, type SsoTokenSource, type StoredSessionState, type TokenProvider, UNENCRYPTED_RECOVERY_KEY_SIZE, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceKeys, type WorkspaceOpenProvider, type WsAgentDmStatusMessage, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsChatMessageMessage, type WsChatReadMessage, type WsChatUpdatedMessage, type WsConnectionClosedMessage, type WsConversationMessagePostedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, authRequestError, base64Decode, base64Encode, base64ToBytes, base64UrlToBytes, browserSessionStateStorage, buildCallFragment, buildCallLink, buildWebSocketUrl, bytesToBase64, bytesToBase64Url, canPersistSession, changePassword, clearAllData, clearSession, type components, computeSharedSecret, createAllWorkspacesOpener, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createOfflineSealer, createRecoveryFile, createRecoveryUrl, createReloginHandler, createSessionManager, createWorkspaceKeys, createWorkspaceReopener, decodeCallKey, decodeSecureMailKey, decryptCallTitle, decryptFile, decryptMessage, decryptMessageWithSharedSecret, decryptRecoveryKey, decryptWithChatKey, deriveDirectChatKey, deriveEncryptionKeypairFromSigning, derivePublicKey, encodeCallKey, encryptCallTitle, encryptFile, encryptMessage, encryptMessageWithSharedSecret, encryptRecoveryKey, encryptWithChatKey, encryptionKeypairFromSigningKey, generateCallKey, generateChatKey, generateIdentityKeypair, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRegistrationCredentials, generateUserKeypairs, getRecoveryKeyFilename, getSession, getUserEncryptionKeypair, hasSession, identityFromLoginResponse, initSodium, initializeDatabase, isEncryptedRecoveryKey, isMessageType, openCallKeyOf, openSealedCallKey, openSealedChatKey, openSecureMail, type operations, parseCallFragment, parseRecoveryUrl, parseServerMessage, passwordChangeErrorMessage, type paths, prewarmKeyPairs, readSessionClaims, saveSession, sealCallKey, sealCallKeyForPeers, sealChatKey, sealKeyForSession, sealSecureMail, sealedBoxDecrypt, sealedBoxEncrypt, secureMailClaim, signMessage, unlockIdentityWithPassword, unwrapIdentityKey, unwrapWorkspaceKey, updateWrappedIdentityKey, validateRecoveryKeyFile, type webhooks, workspaceKeyRequiredOf, wrapIdentityKey };
39365
+ export { type $defs, ACCESS_TOKEN_STORAGE_KEY, API_PREFIX, type ArbiClient, type ArbiClientOptions, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, CALL_KEY_BYTES, CHAT_KEY_BYTES, type CallPeer, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, ENCRYPTED_RECOVERY_KEY_SIZE, type KeyLoginCredentials, type KeyPair, type ListedWorkspaceKey, type LoginCredentials, type LoginParams, type LoginProfile, type LoginProvider, type LoginRequest, type LoginResponse, type LoginResult, type LoginWithKeyParams, type OfflineSealer, type OfflineSealerOptions, type OnReloginSuccess, type OpenAllDeps, type ParsedRecoveryUrl, type PasswordChangeCredentials, RECOVERY_KEY_ERRORS, type RecoveryKeyParams, type RecoveryKeyValidationResult, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type ReloginDeps, type ReloginFailure, type ReloginHandler, type ReopenDeps, SECURE_MAIL_KEY_BYTES, type SealedSecureMail, type SecureMailCiphertexts, type SecureMailClaim, type SessionClaims, type SessionData, type SessionKeys, type SessionManager, type SessionManagerOptions, type SessionPersistence, type SessionSignIn, type SessionState, type SessionStateStorage, type SessionUser, type SignInHooks, type SsoTokenSource, type StoredSessionState, type TokenProvider, UNENCRYPTED_RECOVERY_KEY_SIZE, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceKeys, type WorkspaceOpenProvider, type WorkspaceOpens, type WsAgentDmStatusMessage, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsChatMessageMessage, type WsChatReadMessage, type WsChatUpdatedMessage, type WsConnectionClosedMessage, type WsConversationMessagePostedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, authRequestError, base64Decode, base64Encode, base64ToBytes, base64UrlToBytes, browserSessionStateStorage, buildCallFragment, buildCallLink, buildWebSocketUrl, bytesToBase64, bytesToBase64Url, canPersistSession, changePassword, clearAllData, clearSession, type components, computeSharedSecret, createAllWorkspacesOpener, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createOfflineSealer, createRecoveryFile, createRecoveryUrl, createReloginHandler, createSessionManager, createWorkspaceKeys, createWorkspaceOpens, createWorkspaceReopener, decodeCallKey, decodeSecureMailKey, decryptCallTitle, decryptFile, decryptMessage, decryptMessageWithSharedSecret, decryptRecoveryKey, decryptWithChatKey, deriveDirectChatKey, deriveEncryptionKeypairFromSigning, derivePublicKey, encodeCallKey, encryptCallTitle, encryptFile, encryptMessage, encryptMessageWithSharedSecret, encryptRecoveryKey, encryptWithChatKey, encryptionKeypairFromSigningKey, generateCallKey, generateChatKey, generateIdentityKeypair, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRegistrationCredentials, generateUserKeypairs, getRecoveryKeyFilename, getSession, getUserEncryptionKeypair, hasSession, identityFromLoginResponse, initSodium, initializeDatabase, isEncryptedRecoveryKey, isMessageType, openCallKeyOf, openSealedCallKey, openSealedChatKey, openSecureMail, type operations, parseCallFragment, parseRecoveryUrl, parseServerMessage, passwordChangeErrorMessage, type paths, prewarmKeyPairs, readSessionClaims, saveSession, sealCallKey, sealCallKeyForPeers, sealChatKey, sealKeyForSession, sealSecureMail, sealedBoxDecrypt, sealedBoxEncrypt, secureMailClaim, signMessage, unlockIdentityWithPassword, unwrapIdentityKey, unwrapWorkspaceKey, updateWrappedIdentityKey, validateRecoveryKeyFile, type webhooks, workspaceKeyRequiredOf, wrapIdentityKey };
package/dist/index.js CHANGED
@@ -1220,6 +1220,59 @@ function workspaceKeyRequiredOf(body) {
1220
1220
  return d.code === "workspace_key_required" && typeof d.workspace_ext_id === "string" ? d.workspace_ext_id : null;
1221
1221
  }
1222
1222
 
1223
+ // src/workspace-opens.ts
1224
+ function createWorkspaceOpens() {
1225
+ let tail = Promise.resolve();
1226
+ let pending = 0;
1227
+ let generation = 0;
1228
+ let active = null;
1229
+ return {
1230
+ run(target, open) {
1231
+ pending++;
1232
+ const result = tail.then(async () => {
1233
+ const workspaceId = target();
1234
+ if (workspaceId === null || workspaceId !== active) {
1235
+ generation++;
1236
+ active = null;
1237
+ }
1238
+ try {
1239
+ const value = await open();
1240
+ active = workspaceId;
1241
+ return value;
1242
+ } catch (error) {
1243
+ generation++;
1244
+ active = null;
1245
+ throw error;
1246
+ }
1247
+ });
1248
+ const done = () => {
1249
+ pending--;
1250
+ };
1251
+ tail = result.then(done, done);
1252
+ return result;
1253
+ },
1254
+ get busy() {
1255
+ return pending > 0;
1256
+ },
1257
+ get generation() {
1258
+ return generation;
1259
+ },
1260
+ get active() {
1261
+ return active;
1262
+ },
1263
+ async idle() {
1264
+ for (let current = tail; ; current = tail) {
1265
+ await current;
1266
+ if (current === tail && pending === 0) return;
1267
+ }
1268
+ },
1269
+ reset() {
1270
+ generation++;
1271
+ active = null;
1272
+ }
1273
+ };
1274
+ }
1275
+
1223
1276
  // src/middleware/auto-relogin.ts
1224
1277
  var NO_ACTIVE_WORKSPACE = /no active workspace/i;
1225
1278
  async function keyRequiredWorkspace(response) {
@@ -1498,7 +1551,11 @@ function createAllWorkspacesOpener(deps) {
1498
1551
  } catch {
1499
1552
  return;
1500
1553
  }
1501
- for (const ws of workspaces ?? []) {
1554
+ const last = deps.lastWorkspace?.() ?? null;
1555
+ const ordered = [...workspaces ?? []].sort(
1556
+ (a, b) => Number(a.external_id === last) - Number(b.external_id === last)
1557
+ );
1558
+ for (const ws of ordered) {
1502
1559
  if (!ws.wrapped_key || !ws.external_id) continue;
1503
1560
  try {
1504
1561
  const workspaceKey = deps.unwrapWorkspaceKey(ws.wrapped_key, session.signingPrivateKey);
@@ -1747,7 +1804,7 @@ function readBaseUrlPerRequest(fetchClient, base) {
1747
1804
  }
1748
1805
  var deploymentDomainOf = ({ deploymentDomain }) => typeof deploymentDomain === "function" ? deploymentDomain() : deploymentDomain;
1749
1806
  function createArbiClient(options) {
1750
- const { fetch: fetch2, session, persistence, workspaceKeys, auth } = createTransport(options);
1807
+ const { fetch: fetch2, session, persistence, workspaceKeys, workspaceOpens, auth } = createTransport(options);
1751
1808
  const authDeps = {
1752
1809
  fetchClient: fetch2,
1753
1810
  session,
@@ -1760,6 +1817,7 @@ function createArbiClient(options) {
1760
1817
  return {
1761
1818
  fetch: fetch2,
1762
1819
  workspaceKeys,
1820
+ workspaceOpens,
1763
1821
  session,
1764
1822
  auth: {
1765
1823
  register: (params) => register(params, authDeps),
@@ -1885,10 +1943,14 @@ function createTransport(options) {
1885
1943
  if (!response.ok) throw new Error(`Could not unlock the workspace (${response.status})`);
1886
1944
  }
1887
1945
  });
1946
+ const workspaceOpens = createWorkspaceOpens();
1888
1947
  let keysUser = session.getState().signedIn ? session.getState().userExtId : null;
1889
1948
  session.subscribe((state) => {
1890
1949
  const user = state.signedIn ? state.userExtId : null;
1891
- if (user !== keysUser) workspaceKeys.clear();
1950
+ if (user !== keysUser) {
1951
+ workspaceKeys.clear();
1952
+ workspaceOpens.reset();
1953
+ }
1892
1954
  keysUser = user;
1893
1955
  });
1894
1956
  const workspaceKeyRefreshProvider = {
@@ -1896,7 +1958,7 @@ function createTransport(options) {
1896
1958
  return (await workspaceKeys.wrappedKey(workspaceId).catch(() => null))?.wrappedKey ?? null;
1897
1959
  }
1898
1960
  };
1899
- const workspaceOpenProvider = {
1961
+ const rawWorkspaceOpenProvider = {
1900
1962
  async openWorkspace(accessToken, workspaceId, encryptedWorkspaceKey) {
1901
1963
  const query = "?include_documents=false&include_conversations=false&include_tags=false";
1902
1964
  try {
@@ -1918,6 +1980,16 @@ function createTransport(options) {
1918
1980
  }
1919
1981
  }
1920
1982
  };
1983
+ const workspaceOpenProvider = {
1984
+ openWorkspace: (accessToken, workspaceId, encryptedWorkspaceKey) => workspaceOpens.busy ? Promise.resolve(true) : workspaceOpens.run(
1985
+ () => workspaceId,
1986
+ () => rawWorkspaceOpenProvider.openWorkspace(
1987
+ accessToken,
1988
+ workspaceId,
1989
+ encryptedWorkspaceKey
1990
+ )
1991
+ )
1992
+ };
1921
1993
  let lastFailure = null;
1922
1994
  const expiredListeners = /* @__PURE__ */ new Set();
1923
1995
  const rawRelogin = createReloginHandler({
@@ -1951,15 +2023,19 @@ function createTransport(options) {
1951
2023
  }
1952
2024
  return null;
1953
2025
  }
1954
- const reopenWorkspace = createWorkspaceReopener({
2026
+ const reopenSelected = createWorkspaceReopener({
1955
2027
  crypto: cryptoProvider,
1956
2028
  persistence,
1957
2029
  authState,
1958
2030
  getAccessToken: () => session.getState().accessToken,
1959
2031
  workspaceKeyRefreshProvider,
1960
- workspaceOpenProvider
2032
+ workspaceOpenProvider: rawWorkspaceOpenProvider
2033
+ });
2034
+ let reopening = null;
2035
+ const reopenWorkspace = () => reopening ??= workspaceOpens.run(() => authState.getSelectedWorkspaceId(), reopenSelected).finally(() => {
2036
+ reopening = null;
1961
2037
  });
1962
- const openAllWorkspaces = createAllWorkspacesOpener({
2038
+ const openEveryWorkspace = createAllWorkspacesOpener({
1963
2039
  crypto: cryptoProvider,
1964
2040
  persistence,
1965
2041
  getAccessToken: () => session.getState().accessToken,
@@ -1969,8 +2045,10 @@ function createTransport(options) {
1969
2045
  const list = await listWorkspaces(accessToken);
1970
2046
  return list && workspaceKeys.remember(list);
1971
2047
  },
1972
- workspaceOpenProvider
2048
+ workspaceOpenProvider: rawWorkspaceOpenProvider,
2049
+ lastWorkspace: () => authState.getSelectedWorkspaceId()
1973
2050
  });
2051
+ const openAllWorkspaces = () => workspaceOpens.run(() => null, openEveryWorkspace);
1974
2052
  const fetchClient = createFetchClient({
1975
2053
  baseUrl: base(),
1976
2054
  credentials,
@@ -1999,6 +2077,7 @@ function createTransport(options) {
1999
2077
  session,
2000
2078
  persistence,
2001
2079
  workspaceKeys,
2080
+ workspaceOpens,
2002
2081
  auth: {
2003
2082
  relogin,
2004
2083
  reopenWorkspace,
@@ -2094,6 +2173,6 @@ function isMessageType(msg, type) {
2094
2173
  return msg.type === type;
2095
2174
  }
2096
2175
 
2097
- export { ACCESS_TOKEN_STORAGE_KEY, API_PREFIX, CALL_KEY_BYTES, CHAT_KEY_BYTES, ENCRYPTED_RECOVERY_KEY_SIZE, RECOVERY_KEY_ERRORS, SECURE_MAIL_KEY_BYTES, UNENCRYPTED_RECOVERY_KEY_SIZE, authRequestError, base64Decode, base64Encode, base64ToBytes, base64UrlToBytes, browserSessionStateStorage, buildCallFragment, buildCallLink, buildWebSocketUrl, bytesToBase64, bytesToBase64Url, canPersistSession, changePassword, clearAllData, clearSession, computeSharedSecret, createAllWorkspacesOpener, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createOfflineSealer, createRecoveryFile, createRecoveryUrl, createReloginHandler, createSessionManager, createWorkspaceKeys, createWorkspaceReopener, decodeCallKey, decodeSecureMailKey, decryptCallTitle, decryptFile, decryptMessage, decryptMessageWithSharedSecret, decryptRecoveryKey, decryptWithChatKey, deriveDirectChatKey, deriveEncryptionKeypairFromSigning, derivePublicKey, encodeCallKey, encryptCallTitle, encryptFile, encryptMessage, encryptMessageWithSharedSecret, encryptRecoveryKey, encryptWithChatKey, encryptionKeypairFromSigningKey, generateCallKey, generateChatKey, generateIdentityKeypair, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRegistrationCredentials, generateUserKeypairs, getRecoveryKeyFilename, getSession, getUserEncryptionKeypair, hasSession, identityFromLoginResponse, initSodium, initializeDatabase, isEncryptedRecoveryKey, isMessageType, openCallKeyOf, openSealedCallKey, openSealedChatKey, openSecureMail, parseCallFragment, parseRecoveryUrl, parseServerMessage, passwordChangeErrorMessage, prewarmKeyPairs, readSessionClaims, saveSession, sealCallKey, sealCallKeyForPeers, sealChatKey, sealKeyForSession, sealSecureMail, sealedBoxDecrypt, sealedBoxEncrypt, secureMailClaim, signMessage, unlockIdentityWithPassword, unwrapIdentityKey, unwrapWorkspaceKey, updateWrappedIdentityKey, validateRecoveryKeyFile, workspaceKeyRequiredOf, wrapIdentityKey };
2176
+ export { ACCESS_TOKEN_STORAGE_KEY, API_PREFIX, CALL_KEY_BYTES, CHAT_KEY_BYTES, ENCRYPTED_RECOVERY_KEY_SIZE, RECOVERY_KEY_ERRORS, SECURE_MAIL_KEY_BYTES, UNENCRYPTED_RECOVERY_KEY_SIZE, authRequestError, base64Decode, base64Encode, base64ToBytes, base64UrlToBytes, browserSessionStateStorage, buildCallFragment, buildCallLink, buildWebSocketUrl, bytesToBase64, bytesToBase64Url, canPersistSession, changePassword, clearAllData, clearSession, computeSharedSecret, createAllWorkspacesOpener, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createOfflineSealer, createRecoveryFile, createRecoveryUrl, createReloginHandler, createSessionManager, createWorkspaceKeys, createWorkspaceOpens, createWorkspaceReopener, decodeCallKey, decodeSecureMailKey, decryptCallTitle, decryptFile, decryptMessage, decryptMessageWithSharedSecret, decryptRecoveryKey, decryptWithChatKey, deriveDirectChatKey, deriveEncryptionKeypairFromSigning, derivePublicKey, encodeCallKey, encryptCallTitle, encryptFile, encryptMessage, encryptMessageWithSharedSecret, encryptRecoveryKey, encryptWithChatKey, encryptionKeypairFromSigningKey, generateCallKey, generateChatKey, generateIdentityKeypair, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRegistrationCredentials, generateUserKeypairs, getRecoveryKeyFilename, getSession, getUserEncryptionKeypair, hasSession, identityFromLoginResponse, initSodium, initializeDatabase, isEncryptedRecoveryKey, isMessageType, openCallKeyOf, openSealedCallKey, openSealedChatKey, openSecureMail, parseCallFragment, parseRecoveryUrl, parseServerMessage, passwordChangeErrorMessage, prewarmKeyPairs, readSessionClaims, saveSession, sealCallKey, sealCallKeyForPeers, sealChatKey, sealKeyForSession, sealSecureMail, sealedBoxDecrypt, sealedBoxEncrypt, secureMailClaim, signMessage, unlockIdentityWithPassword, unwrapIdentityKey, unwrapWorkspaceKey, updateWrappedIdentityKey, validateRecoveryKeyFile, workspaceKeyRequiredOf, wrapIdentityKey };
2098
2177
  //# sourceMappingURL=index.js.map
2099
2178
  //# sourceMappingURL=index.js.map