@iblai/web-utils 1.10.12 → 1.11.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iblai/web-utils",
3
- "version": "1.10.11",
3
+ "version": "1.10.13",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.esm.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1,3 +1,4 @@
1
+ export * from "./use-tenant-switch-sync";
1
2
  export * from "./subscription/use-subscription-handler";
2
3
  export * from "./subscription/constants";
3
4
  export * from "./subscription/class-subscription-flow";
@@ -0,0 +1,13 @@
1
+ export interface UseTenantSwitchSyncOptions {
2
+ /** Called when ANOTHER tab broadcasts a tenant switch (self-echo filtered out). */
3
+ onRemoteSwitch?: (tenant: string) => void;
4
+ }
5
+ /**
6
+ * Subscribe to cross-tab tenant-switch broadcasts. Ignores this tab's own echo
7
+ * (BroadcastChannel delivers to sibling instances in the same tab) and refreshes
8
+ * the shared switch lock so this tab won't auto-revert during the switch window.
9
+ *
10
+ * @example
11
+ * useTenantSwitchSync();
12
+ */
13
+ export declare function useTenantSwitchSync(options?: UseTenantSwitchSyncOptions): void;
@@ -3,7 +3,8 @@ import { useAdvancedChat as _useAdvancedChat } from "./hooks/chat/use-advanced-c
3
3
  import { useTimeTracker as _useTimeTracker } from "./features/tracking/use-time-tracker";
4
4
  import { useMentorSettings as _useMentorSettings } from "./hooks/use-mentor-settings";
5
5
  import { getTimeAgo as _getTimeAgo } from "./utils";
6
- import { isInIframe as _isInIframe, sendMessageToParentWebsite as _sendMessageToParentWebsite, deleteCookie as _deleteCookie, getDomainParts as _getDomainParts, deleteCookieOnAllDomains as _deleteCookieOnAllDomains, getParentDomain as _getParentDomain, setCookieForAuth as _setCookieForAuth, clearCookies as _clearCookies, isLoggedIn as _isLoggedIn, getPlatformKey as _getPlatformKey, redirectToAuthSpa as _redirectToAuthSpa, getAuthSpaJoinUrl as _getAuthSpaJoinUrl, redirectToAuthSpaJoinTenant as _redirectToAuthSpaJoinTenant, handleLogout as _handleLogout } from "./utils/auth";
6
+ import { isInIframe as _isInIframe, sendMessageToParentWebsite as _sendMessageToParentWebsite, deleteCookie as _deleteCookie, getDomainParts as _getDomainParts, deleteCookieOnAllDomains as _deleteCookieOnAllDomains, getParentDomain as _getParentDomain, setCookieForAuth as _setCookieForAuth, clearCookies as _clearCookies, isLoggedIn as _isLoggedIn, getPlatformKey as _getPlatformKey, redirectToAuthSpa as _redirectToAuthSpa, getAuthSpaJoinUrl as _getAuthSpaJoinUrl, redirectToAuthSpaJoinTenant as _redirectToAuthSpaJoinTenant, handleLogout as _handleLogout, handleTenantSwitch as _handleTenantSwitch, getTabId as _getTabId, readTenantSwitchLock as _readTenantSwitchLock, writeTenantSwitchLock as _writeTenantSwitchLock, refreshTenantSwitchLock as _refreshTenantSwitchLock, clearTenantSwitchLock as _clearTenantSwitchLock, isTenantSwitchInProgress as _isTenantSwitchInProgress } from "./utils/auth";
7
+ import { useTenantSwitchSync as _useTenantSwitchSync } from "./hooks/use-tenant-switch-sync";
7
8
  import { AuthProvider as _AuthProvider, TenantProvider as _TenantProvider, MentorProvider as _MentorProvider } from "./providers";
8
9
  import { useSearchParams as _useSearchParams, useParams as _useParams, useRouter as _useRouter, usePathname as _usePathname } from "next/navigation";
9
10
  export declare const useGetChatDetails: typeof _useGetChatDetails;
@@ -87,6 +88,14 @@ export declare const redirectToAuthSpa: typeof _redirectToAuthSpa;
87
88
  export declare const getAuthSpaJoinUrl: typeof _getAuthSpaJoinUrl;
88
89
  export declare const redirectToAuthSpaJoinTenant: typeof _redirectToAuthSpaJoinTenant;
89
90
  export declare const handleLogout: typeof _handleLogout;
91
+ export declare const handleTenantSwitch: typeof _handleTenantSwitch;
92
+ export declare const getTabId: typeof _getTabId;
93
+ export declare const readTenantSwitchLock: typeof _readTenantSwitchLock;
94
+ export declare const writeTenantSwitchLock: typeof _writeTenantSwitchLock;
95
+ export declare const refreshTenantSwitchLock: typeof _refreshTenantSwitchLock;
96
+ export declare const clearTenantSwitchLock: typeof _clearTenantSwitchLock;
97
+ export declare const isTenantSwitchInProgress: typeof _isTenantSwitchInProgress;
98
+ export declare const useTenantSwitchSync: typeof _useTenantSwitchSync;
90
99
  export declare const chatActions: import("@reduxjs/toolkit").CaseReducerActions<import("@reduxjs/toolkit").SliceCaseReducers<import("./features/chat/slice").ChatSliceState>, string>;
91
100
  export declare const selectSessionId: (state: {
92
101
  chatSliceShared: import("./features/chat/slice").ChatSliceState;
@@ -121,4 +130,5 @@ export declare const useRouter: typeof _useRouter;
121
130
  export declare const usePathname: typeof _usePathname;
122
131
  export type { ChatMode } from "./types";
123
132
  export type { OAuthRequiredData, OAuthResolvedData, } from "./hooks/chat/use-chat-v2";
124
- export type { RedirectToAuthSpaOptions, HandleLogoutOptions, } from "./utils/auth";
133
+ export type { RedirectToAuthSpaOptions, HandleLogoutOptions, TenantSwitchLock, HandleTenantSwitchOptions, } from "./utils/auth";
134
+ export type { UseTenantSwitchSyncOptions } from "./hooks/use-tenant-switch-sync";
@@ -198,3 +198,65 @@ export interface HandleLogoutOptions {
198
198
  * ```
199
199
  */
200
200
  export declare function handleLogout(options: HandleLogoutOptions): void;
201
+ export declare const TENANT_SWITCH_CHANNEL = "ibl-tenant-switch";
202
+ export declare const TENANT_SWITCH_LOCK_KEY = "ibl_tenant_switch_lock";
203
+ export declare const DEFAULT_TENANT_SWITCH_LOCK_TTL_MS = 8000;
204
+ export interface TenantSwitchLock {
205
+ tenant: string;
206
+ /** `${ts}-${tabId}` — monotonic; newer wins. */
207
+ token: string;
208
+ ts: number;
209
+ senderId: string;
210
+ }
211
+ /**
212
+ * Stable per-tab id. Uses sessionStorage so it survives same-tab reloads while
213
+ * staying unique per tab/window.
214
+ */
215
+ export declare function getTabId(): string;
216
+ /** The active (non-expired) tenant-switch lock, or null. */
217
+ export declare function readTenantSwitchLock(ttlMs?: number): TenantSwitchLock | null;
218
+ /** Write a fresh lock for `tenant` (newest intent). Returns the lock written. */
219
+ export declare function writeTenantSwitchLock(tenant: string): TenantSwitchLock;
220
+ /** Extend an existing lock's window from "now" (no-op when no active lock). */
221
+ export declare function refreshTenantSwitchLock(): void;
222
+ export declare function clearTenantSwitchLock(): void;
223
+ /** True while a tenant switch is in flight — gate automatic reverts on this. */
224
+ export declare function isTenantSwitchInProgress(ttlMs?: number): boolean;
225
+ export interface HandleTenantSwitchOptions {
226
+ /** Auth SPA base URL (e.g. config.authUrl()). */
227
+ authUrl: string;
228
+ /** localStorage key for the saved redirect path (default "redirect-to"). */
229
+ redirectPathStorageKey?: string;
230
+ /** localStorage key for a JWT to forward through the switch (default "edx_jwt_token"). */
231
+ preserveTokenKey?: string;
232
+ /** localStorage key holding the tenant (default "tenant"). */
233
+ tenantStorageKey?: string;
234
+ /** Cookie name signalling a switch is in progress (default "ibl_tenant_switching"). */
235
+ tenantSwitchingCookie?: string;
236
+ /** Query-param names for the auth URL. */
237
+ queryParams?: {
238
+ tenant?: string;
239
+ redirectTo?: string;
240
+ };
241
+ /** Persist the current path so the app returns to it post-switch. */
242
+ saveRedirect?: boolean;
243
+ /** Explicit redirect target (defaults to window.location.origin). */
244
+ redirectUrl?: string;
245
+ /** Broadcast to other tabs + clear storage (true for user-initiated; default true). */
246
+ broadcast?: boolean;
247
+ /** Lock TTL override. */
248
+ lockTtlMs?: number;
249
+ /** Injected so this util stays React-free (mentorai passes the SDK's). */
250
+ clearCurrentTenantCookie?: () => void;
251
+ }
252
+ /**
253
+ * Switch the active tenant. Coordinates across tabs (TTL lock + BroadcastChannel),
254
+ * clears storage, then redirects through the auth SPA's `/login/complete`.
255
+ *
256
+ * @example
257
+ * await handleTenantSwitch("acme", {
258
+ * authUrl: config.authUrl(),
259
+ * clearCurrentTenantCookie,
260
+ * });
261
+ */
262
+ export declare function handleTenantSwitch(tenant: string, options: HandleTenantSwitchOptions): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iblai/web-utils",
3
- "version": "1.10.12",
3
+ "version": "1.11.0",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.esm.js",
6
6
  "types": "./dist/index.d.ts",