{"version":3,"file":"refresh-queue.cjs","names":[],"sources":["../../src/auth/refresh-queue.ts"],"sourcesContent":["export interface CreateRefreshQueueOptions {\n    /**\n     * Reads the credential the refresh installs — typically the access token.\n     *\n     * Supplying it makes the queue skip a refresh whose work another caller has\n     * already done. Without it, only calls that literally overlap in time are\n     * collapsed.\n     */\n    getToken?: () => string | null | undefined;\n}\n\n/**\n * Deduplicate concurrent refresh calls. When multiple 401 responses arrive\n * at once, all of them share the same in-flight `refresh()` promise instead\n * of triggering N parallel refreshes.\n *\n * **In-flight sharing alone does not collapse a burst.** A page that fires\n * several requests at once gets several 401s back, but they do not land inside\n * one window: the stragglers arrive after the first refresh already resolved,\n * find no promise to join, and each starts another one — rotating a token that\n * is already fresh. Measured against a mock backend, five concurrent expired\n * requests took two refreshes, not one.\n *\n * Pass `getToken` to close that gap. The queue remembers the token its last\n * refresh produced, and a call that finds that same token still in place returns\n * immediately, because the refresh it was about to perform has already happened.\n * The same five requests then take exactly one refresh, and so do twenty.\n *\n * @param refresh - Performs the refresh and installs the new credentials.\n * @param options - Optional token reader that enables already-refreshed\n *   detection.\n * @returns A function that refreshes at most once per rotation.\n *\n * @example\n * const refresh = createRefreshQueue(() => AuthService.refresh(), {\n *     getToken: () => useAuthStore.getState().token,\n * });\n *\n * // In every request that hits 401:\n * await refresh();\n * // ...retry the original request\n */\nexport function createRefreshQueue(\n    refresh: () => Promise<void>,\n    options: CreateRefreshQueueOptions = {},\n): () => Promise<void> {\n    const { getToken } = options;\n    let current: Promise<void> | null = null;\n    let lastIssued: string | null = null;\n\n    return () => {\n        if (current) return current;\n\n        if (getToken && lastIssued !== null && getToken() === lastIssued) {\n            return Promise.resolve();\n        }\n\n        current = (async () => {\n            try {\n                await refresh();\n                if (getToken) lastIssued = getToken() ?? null;\n            } finally {\n                current = null;\n            }\n        })();\n        return current;\n    };\n}\n"],"mappings":"AA0CA,SAAgB,EACZ,EACA,EAAqC,CAAC,EACnB,CACnB,GAAM,CAAE,YAAa,EACjB,EAAgC,KAChC,EAA4B,KAEhC,UACQ,IAEA,GAAY,IAAe,MAAQ,EAAS,IAAM,EAC3C,QAAQ,QAAQ,GAG3B,GAAW,SAAY,CACnB,GAAI,CACA,MAAM,EAAQ,EACV,IAAU,EAAa,EAAS,GAAK,KAC7C,QAAU,CACN,EAAU,IACd,CACJ,EAAA,CAAG,EACI,GAEf"}