@cxkit/version-core
Advanced tools
+23
-0
@@ -220,2 +220,11 @@ "use strict"; | ||
| } | ||
| function getConfirmedVersion(prefix) { | ||
| return localStorage.getItem(getStorageKey(prefix, "confirmed_version")); | ||
| } | ||
| function setConfirmedVersion(prefix, buildId) { | ||
| localStorage.setItem(getStorageKey(prefix, "confirmed_version"), buildId); | ||
| } | ||
| function removeConfirmedVersion(prefix) { | ||
| localStorage.removeItem(getStorageKey(prefix, "confirmed_version")); | ||
| } | ||
@@ -281,2 +290,7 @@ // src/checker.ts | ||
| } | ||
| const confirmedVersion = getConfirmedVersion(opts.storagePrefix); | ||
| if (confirmedVersion && confirmedVersion === env.buildId) { | ||
| removeConfirmedVersion(opts.storagePrefix); | ||
| debugLog("Confirmed version matches current buildId, refresh was successful", { confirmedVersion }); | ||
| } | ||
| const oldVersion = getPersistedVersion(opts.storagePrefix); | ||
@@ -335,2 +349,10 @@ if (oldVersion === env.buildId) return; | ||
| } | ||
| const confirmedVersion = getConfirmedVersion(opts.storagePrefix); | ||
| if (confirmedVersion === latestManifest.buildId) { | ||
| debugLog("This buildId was already confirmed by user, suppressing popup to avoid loop", { | ||
| confirmedVersion, | ||
| currentBuildId: env.buildId | ||
| }); | ||
| return; | ||
| } | ||
| const reloadGuard = getReloadGuard(opts.storagePrefix); | ||
@@ -430,2 +452,3 @@ updatePendingState(latestManifest); | ||
| emitter.emit("update-confirmed", manifest); | ||
| setConfirmedVersion(opts.storagePrefix, state.latestBuildId); | ||
| const context = buildRefreshContext( | ||
@@ -432,0 +455,0 @@ state.latestBuildId, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/index.ts","../src/events.ts","../src/fetcher.ts","../src/refresh.ts","../src/storage.ts","../src/checker.ts"],"sourcesContent":["export { createVersionChecker } from './checker'\r\nexport type {\r\n VersionManifest,\r\n VersionRuntimeEnv,\r\n RefreshStrategy,\r\n RefreshContext,\r\n CheckerOptions,\r\n CheckerState,\r\n CheckerEventMap,\r\n VersionChecker\r\n} from './types'\r\n","import type { CheckerEventMap } from './types'\r\n\r\ntype Handler<T = unknown> = (payload: T) => void\r\n\r\n/**\r\n * Lightweight typed event emitter.\r\n * No external dependencies.\r\n */\r\nexport class EventEmitter {\r\n private listeners = new Map<string, Set<Handler>>()\r\n\r\n on<E extends keyof CheckerEventMap>(event: E, handler: Handler<CheckerEventMap[E]>): () => void {\r\n if (!this.listeners.has(event)) {\r\n this.listeners.set(event, new Set())\r\n }\r\n this.listeners.get(event)!.add(handler as Handler)\r\n return () => this.off(event, handler)\r\n }\r\n\r\n off<E extends keyof CheckerEventMap>(event: E, handler: Handler<CheckerEventMap[E]>): void {\r\n this.listeners.get(event)?.delete(handler as Handler)\r\n }\r\n\r\n emit<E extends keyof CheckerEventMap>(event: E, payload: CheckerEventMap[E]): void {\r\n this.listeners.get(event)?.forEach((handler) => {\r\n try {\r\n handler(payload)\r\n } catch (err) {\r\n console.error(`[cxkit] Error in \"${event}\" handler:`, err)\r\n }\r\n })\r\n }\r\n\r\n removeAll(): void {\r\n this.listeners.clear()\r\n }\r\n}\r\n","import type { VersionManifest, VersionRuntimeEnv } from './types'\r\n\r\nconst DEV_MOCK_QUERY_KEY = '__mock_version_update'\r\n\r\nexport function isDevMockEnabled(): boolean {\r\n return new URLSearchParams(window.location.search).get(DEV_MOCK_QUERY_KEY) === '1'\r\n}\r\n\r\nexport function readGlobalString(\r\n name: '__APP_VERSION__' | '__APP_BUILD_ID__' | '__APP_BUILD_TIME__' | '__APP_BASE_URL__'\r\n): string {\r\n const value = (globalThis as Record<string, unknown>)[name]\r\n return typeof value === 'string' ? value : ''\r\n}\r\n\r\nexport function resolveRuntimeEnv(\r\n envOverride: VersionRuntimeEnv,\r\n devMock: boolean\r\n): Required<VersionRuntimeEnv> {\r\n const DEV_MOCK_BUILD_ID = 'mock-current-build'\r\n const devMockEnabled = devMock && isDevMockEnabled()\r\n\r\n return {\r\n version: envOverride.version || readGlobalString('__APP_VERSION__'),\r\n buildId: devMockEnabled\r\n ? DEV_MOCK_BUILD_ID\r\n : envOverride.buildId || readGlobalString('__APP_BUILD_ID__'),\r\n buildTime: envOverride.buildTime || readGlobalString('__APP_BUILD_TIME__'),\r\n baseUrl: envOverride.baseUrl || readGlobalString('__APP_BASE_URL__')\r\n }\r\n}\r\n\r\nexport function getActiveLocationHref(): string {\r\n const wujieLocation = (window as any).$wujie?.location\r\n if (wujieLocation && typeof wujieLocation.href === 'string') {\r\n return wujieLocation.href\r\n }\r\n return window.location.href\r\n}\r\n\r\nexport function buildVersionManifestUrl(\r\n versionUrl: string | (() => string) | undefined,\r\n env: Required<VersionRuntimeEnv>\r\n): string {\r\n const DEFAULT_VERSION_URL = 'version.json'\r\n const customVersionUrl = typeof versionUrl === 'function' ? versionUrl() : versionUrl\r\n const manifestUrl = customVersionUrl || DEFAULT_VERSION_URL\r\n const baseUrl = env.baseUrl\r\n const versionBase = baseUrl\r\n ? new URL(baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`, getActiveLocationHref())\r\n : new URL(getActiveLocationHref())\r\n const url = new URL(manifestUrl, versionBase.toString())\r\n url.searchParams.set('t', Date.now().toString())\r\n return url.toString()\r\n}\r\n\r\nexport async function fetchVersionManifest(\r\n versionUrl: string | (() => string) | undefined,\r\n env: Required<VersionRuntimeEnv>,\r\n debugLog: (message: string, payload?: unknown) => void\r\n): Promise<VersionManifest> {\r\n const requestUrl = buildVersionManifestUrl(versionUrl, env)\r\n debugLog('Requesting version manifest', { requestUrl })\r\n\r\n const response = await fetch(requestUrl, { cache: 'no-store' })\r\n\r\n if (!response.ok) {\r\n throw new Error(`Version manifest request failed: ${response.status}`)\r\n }\r\n\r\n const manifest = (await response.json()) as VersionManifest\r\n debugLog('Version manifest received', manifest)\r\n return manifest\r\n}\r\n","import type { RefreshContext, RefreshStrategy } from './types'\r\nimport { isDevMockEnabled } from './fetcher'\r\n\r\nconst APP_VERSION_QUERY_KEY = '__app_v'\r\n\r\nfunction isEmbedded(): boolean {\r\n return Boolean((window as any).$wujie)\r\n}\r\n\r\nexport function resolveRefreshStrategy(strategy: RefreshStrategy, embedded: boolean): Exclude<RefreshStrategy, 'auto'> {\r\n if (strategy === 'auto') {\r\n return embedded ? 'top' : 'self'\r\n }\r\n return strategy\r\n}\r\n\r\nfunction reloadSelf(buildId: string): void {\r\n const currentUrl = new URL(window.location.href)\r\n const currentVersion = currentUrl.searchParams.get(APP_VERSION_QUERY_KEY)\r\n\r\n if (currentVersion !== buildId) {\r\n currentUrl.searchParams.set(APP_VERSION_QUERY_KEY, buildId)\r\n window.location.replace(currentUrl.toString())\r\n return\r\n }\r\n\r\n window.location.reload()\r\n}\r\n\r\nfunction reloadTopWindow(): void {\r\n try {\r\n if (window.top && window.top !== window) {\r\n window.top.location.reload()\r\n return\r\n }\r\n } catch (error) {\r\n console.warn('[cxkit] Top window reload failed, falling back to current window', error)\r\n }\r\n\r\n window.location.reload()\r\n}\r\n\r\nexport function buildRefreshContext(\r\n buildId: string,\r\n version: string,\r\n buildTime: string | undefined,\r\n strategy: RefreshStrategy\r\n): RefreshContext {\r\n const embedded = isEmbedded()\r\n return {\r\n version,\r\n buildId,\r\n buildTime,\r\n isEmbedded: embedded,\r\n strategy: resolveRefreshStrategy(strategy, embedded)\r\n }\r\n}\r\n\r\nexport function executeRefresh(\r\n context: RefreshContext,\r\n devMock: boolean,\r\n debugLog: (message: string, payload?: unknown) => void\r\n): void {\r\n if (devMock && isDevMockEnabled()) {\r\n debugLog('Dev mock mode: intercepted real refresh', { buildId: context.buildId })\r\n return\r\n }\r\n\r\n if (context.strategy === 'custom') {\r\n console.warn('[cxkit] refreshStrategy is \"custom\" but no before-refresh handler prevented default. Falling back to auto.')\r\n if (context.isEmbedded) {\r\n reloadTopWindow()\r\n } else {\r\n reloadSelf(context.buildId)\r\n }\r\n return\r\n }\r\n\r\n if (context.strategy === 'top') {\r\n reloadTopWindow()\r\n return\r\n }\r\n\r\n reloadSelf(context.buildId)\r\n}\r\n","const DEFAULT_PREFIX = 'CXKIT_VU_'\r\n\r\nexport function getStorageKey(prefix: string | undefined, name: string): string {\r\n return `${prefix ?? DEFAULT_PREFIX}${name}`\r\n}\r\n\r\nexport function clearPrefixedStorage(prefix: string | undefined): void {\r\n const p = prefix ?? DEFAULT_PREFIX\r\n\r\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\r\n const key = localStorage.key(i)\r\n if (key && key.startsWith(p)) {\r\n localStorage.removeItem(key)\r\n }\r\n }\r\n\r\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\r\n const key = sessionStorage.key(i)\r\n if (key && key.startsWith(p)) {\r\n sessionStorage.removeItem(key)\r\n }\r\n }\r\n}\r\n\r\nexport function persistVersion(prefix: string | undefined, buildId: string): void {\r\n localStorage.setItem(getStorageKey(prefix, 'version'), buildId)\r\n document.cookie = `app_version=${buildId}; path=/; max-age=31536000`\r\n}\r\n\r\nexport function getPersistedVersion(prefix: string | undefined): string | null {\r\n return localStorage.getItem(getStorageKey(prefix, 'version'))\r\n}\r\n\r\nexport function getRemindAt(prefix: string | undefined): number {\r\n return Number(localStorage.getItem(getStorageKey(prefix, 'version_remind_at')) || '0')\r\n}\r\n\r\nexport function setRemindAt(prefix: string | undefined, timestamp: number): void {\r\n if (timestamp > 0) {\r\n localStorage.setItem(getStorageKey(prefix, 'version_remind_at'), String(timestamp))\r\n } else {\r\n localStorage.removeItem(getStorageKey(prefix, 'version_remind_at'))\r\n }\r\n}\r\n\r\nexport function getPendingVersion(prefix: string | undefined): string | null {\r\n return localStorage.getItem(getStorageKey(prefix, 'pending_version'))\r\n}\r\n\r\nexport function setPendingVersion(prefix: string | undefined, buildId: string): void {\r\n localStorage.setItem(getStorageKey(prefix, 'pending_version'), buildId)\r\n}\r\n\r\nexport function removePendingVersion(prefix: string | undefined): void {\r\n localStorage.removeItem(getStorageKey(prefix, 'pending_version'))\r\n}\r\n\r\nexport function getReloadGuard(prefix: string | undefined): string | null {\r\n return sessionStorage.getItem(getStorageKey(prefix, 'reload_guard'))\r\n}\r\n\r\nexport function setReloadGuard(prefix: string | undefined, buildId: string): void {\r\n sessionStorage.setItem(getStorageKey(prefix, 'reload_guard'), buildId)\r\n}\r\n\r\nexport function removeReloadGuard(prefix: string | undefined): void {\r\n sessionStorage.removeItem(getStorageKey(prefix, 'reload_guard'))\r\n}\r\n","import type {\r\n CheckerOptions,\r\n CheckerState,\r\n VersionChecker,\r\n VersionManifest,\r\n VersionRuntimeEnv\r\n} from './types'\r\nimport { EventEmitter } from './events'\r\nimport { resolveRuntimeEnv, fetchVersionManifest } from './fetcher'\r\nimport { buildRefreshContext, executeRefresh } from './refresh'\r\nimport {\r\n clearPrefixedStorage,\r\n persistVersion,\r\n getPersistedVersion,\r\n getRemindAt,\r\n setRemindAt,\r\n getPendingVersion,\r\n setPendingVersion,\r\n removePendingVersion,\r\n getReloadGuard,\r\n setReloadGuard,\r\n removeReloadGuard\r\n} from './storage'\r\n\r\n// ─── Defaults ───────────────────────────────────────────────────\r\n\r\nconst DEFAULT_POLL_INTERVAL = 5 * 60 * 1000\r\nconst DEFAULT_REMIND_DELAY = 10 * 60 * 1000\r\nconst DEFAULT_VERSION_URL = 'version.json'\r\n\r\n// ─── Factory ────────────────────────────────────────────────────\r\n\r\nexport function createVersionChecker(options: CheckerOptions = {}): VersionChecker {\r\n // ── Resolved options ─────────────────────────────────\r\n\r\n const opts = {\r\n pollInterval: options.pollInterval ?? DEFAULT_POLL_INTERVAL,\r\n enableFocusCheck: options.enableFocusCheck ?? true,\r\n enableVisibilityCheck: options.enableVisibilityCheck ?? true,\r\n versionUrl: options.versionUrl ?? DEFAULT_VERSION_URL,\r\n refreshStrategy: options.refreshStrategy ?? 'auto' as const,\r\n remindDelay: options.remindDelay ?? DEFAULT_REMIND_DELAY,\r\n storagePrefix: options.storagePrefix,\r\n debug: options.debug ?? false,\r\n devMock: options.devMock ?? false,\r\n timeFormatter: options.timeFormatter,\r\n runtimeEnv: { ...(options.runtimeEnv || {}) } as VersionRuntimeEnv\r\n }\r\n\r\n // ── Internal state ───────────────────────────────────\r\n\r\n const state: CheckerState = {\r\n initialized: false,\r\n checking: false,\r\n hasPendingUpdate: false,\r\n latestBuildId: '',\r\n latestVersion: '',\r\n latestBuildTime: '',\r\n remindAt: 0\r\n }\r\n\r\n const emitter = new EventEmitter()\r\n let timerId: number | null = null\r\n let focusHandler: (() => void) | null = null\r\n let visibilityHandler: (() => void) | null = null\r\n\r\n // ── Helpers ──────────────────────────────────────────\r\n\r\n function debugLog(message: string, payload?: unknown): void {\r\n if (!opts.debug) return\r\n if (payload === undefined) {\r\n console.info(`[cxkit] ${message}`)\r\n } else {\r\n console.info(`[cxkit] ${message}`, payload)\r\n }\r\n }\r\n\r\n function getEnv() {\r\n return resolveRuntimeEnv(opts.runtimeEnv, opts.devMock)\r\n }\r\n\r\n function formatBuildTime(buildTime?: string): string {\r\n if (!buildTime) return ''\r\n return opts.timeFormatter ? opts.timeFormatter(buildTime) : buildTime\r\n }\r\n\r\n function emitStateChange(): void {\r\n emitter.emit('state-change', { ...state })\r\n }\r\n\r\n function updateState(patch: Partial<CheckerState>): void {\r\n Object.assign(state, patch)\r\n emitStateChange()\r\n }\r\n\r\n // ── Storage sync ─────────────────────────────────────\r\n\r\n function syncLocalVersion(): void {\r\n const env = getEnv()\r\n if (!env.buildId) {\r\n debugLog('No current buildId, skipping local version sync')\r\n return\r\n }\r\n\r\n const oldVersion = getPersistedVersion(opts.storagePrefix)\r\n if (oldVersion === env.buildId) return\r\n\r\n clearPrefixedStorage(opts.storagePrefix)\r\n persistVersion(opts.storagePrefix, env.buildId)\r\n debugLog('Local version switched, cleared old cache', { oldVersion, currentBuildId: env.buildId })\r\n }\r\n\r\n function clearPendingState(): void {\r\n removeReloadGuard(opts.storagePrefix)\r\n removePendingVersion(opts.storagePrefix)\r\n updateState({\r\n hasPendingUpdate: false,\r\n latestBuildId: '',\r\n latestVersion: '',\r\n latestBuildTime: '',\r\n remindAt: 0\r\n })\r\n }\r\n\r\n function updatePendingState(manifest: VersionManifest): void {\r\n updateState({\r\n hasPendingUpdate: true,\r\n latestBuildId: manifest.buildId,\r\n latestVersion: manifest.version || '',\r\n latestBuildTime: formatBuildTime(manifest.buildTime)\r\n })\r\n }\r\n\r\n // ── Version check ────────────────────────────────────\r\n\r\n async function showUpdatePrompt(manifest: VersionManifest, force = false): Promise<void> {\r\n const remindAt = getRemindAt(opts.storagePrefix)\r\n state.remindAt = remindAt\r\n emitStateChange()\r\n\r\n if (!force && Date.now() < remindAt) {\r\n updatePendingState(manifest)\r\n debugLog('Remind cooldown active, keeping indicator only', { remindAt, manifest })\r\n return\r\n }\r\n\r\n updatePendingState(manifest)\r\n setPendingVersion(opts.storagePrefix, manifest.buildId)\r\n debugLog(force ? 'User triggered update panel' : 'Pending update state recorded', manifest)\r\n }\r\n\r\n async function checkVersion(): Promise<void> {\r\n if (state.checking) return\r\n\r\n const env = getEnv()\r\n if (!env.buildId) {\r\n debugLog('No current buildId, skipping version check')\r\n return\r\n }\r\n\r\n updateState({ checking: true })\r\n\r\n try {\r\n const latestManifest = await fetchVersionManifest(opts.versionUrl, env, debugLog)\r\n\r\n if (!latestManifest.buildId || latestManifest.buildId === env.buildId) {\r\n clearPendingState()\r\n debugLog('Remote version matches current, no update needed', latestManifest)\r\n return\r\n }\r\n\r\n const reloadGuard = getReloadGuard(opts.storagePrefix)\r\n updatePendingState(latestManifest)\r\n\r\n if (reloadGuard === latestManifest.buildId) {\r\n const pendingVersion = getPendingVersion(opts.storagePrefix)\r\n if (pendingVersion === latestManifest.buildId) {\r\n await showUpdatePrompt(latestManifest)\r\n }\r\n return\r\n }\r\n\r\n setReloadGuard(opts.storagePrefix, latestManifest.buildId)\r\n emitter.emit('update-detected', latestManifest)\r\n await showUpdatePrompt(latestManifest)\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error))\r\n console.error('[cxkit] Version check failed', err)\r\n emitter.emit('error', err)\r\n } finally {\r\n updateState({ checking: false })\r\n }\r\n }\r\n\r\n // ── Lifecycle ────────────────────────────────────────\r\n\r\n function bindLifecycle(): void {\r\n if (opts.enableFocusCheck) {\r\n focusHandler = () => void checkVersion()\r\n window.addEventListener('focus', focusHandler)\r\n }\r\n\r\n if (opts.enableVisibilityCheck) {\r\n visibilityHandler = () => {\r\n if (document.visibilityState === 'visible') {\r\n void checkVersion()\r\n }\r\n }\r\n document.addEventListener('visibilitychange', visibilityHandler)\r\n }\r\n\r\n if (opts.pollInterval > 0) {\r\n timerId = window.setInterval(() => void checkVersion(), opts.pollInterval)\r\n }\r\n }\r\n\r\n function clearLifecycle(): void {\r\n if (focusHandler) {\r\n window.removeEventListener('focus', focusHandler)\r\n focusHandler = null\r\n }\r\n if (visibilityHandler) {\r\n document.removeEventListener('visibilitychange', visibilityHandler)\r\n visibilityHandler = null\r\n }\r\n if (timerId !== null) {\r\n window.clearInterval(timerId)\r\n timerId = null\r\n }\r\n }\r\n\r\n // ── Public API ───────────────────────────────────────\r\n\r\n const checker: VersionChecker = {\r\n start() {\r\n if (state.initialized) {\r\n debugLog('Already initialized, ignoring duplicate start()')\r\n return\r\n }\r\n\r\n updateState({ initialized: true })\r\n\r\n debugLog('Version checker started', {\r\n pollInterval: opts.pollInterval,\r\n remindDelay: opts.remindDelay,\r\n enableFocusCheck: opts.enableFocusCheck,\r\n enableVisibilityCheck: opts.enableVisibilityCheck,\r\n refreshStrategy: opts.refreshStrategy,\r\n versionUrl: opts.versionUrl,\r\n storagePrefix: opts.storagePrefix,\r\n runtimeEnv: getEnv(),\r\n devMock: opts.devMock\r\n })\r\n\r\n syncLocalVersion()\r\n void checkVersion()\r\n bindLifecycle()\r\n },\r\n\r\n stop() {\r\n clearLifecycle()\r\n debugLog('Version checker stopped')\r\n },\r\n\r\n destroy() {\r\n clearLifecycle()\r\n updateState({ initialized: false, checking: false })\r\n emitter.removeAll()\r\n debugLog('Version checker destroyed')\r\n },\r\n\r\n async check() {\r\n await checkVersion()\r\n },\r\n\r\n async confirm() {\r\n if (!state.hasPendingUpdate || !state.latestBuildId) return\r\n\r\n const manifest: VersionManifest = {\r\n buildId: state.latestBuildId,\r\n version: state.latestVersion || undefined,\r\n buildTime: state.latestBuildTime || undefined\r\n }\r\n\r\n emitter.emit('update-confirmed', manifest)\r\n\r\n const context = buildRefreshContext(\r\n state.latestBuildId,\r\n state.latestVersion,\r\n state.latestBuildTime || undefined,\r\n opts.refreshStrategy\r\n )\r\n\r\n clearPendingState()\r\n\r\n emitter.emit('before-refresh', context)\r\n executeRefresh(context, opts.devMock, debugLog)\r\n },\r\n\r\n defer(duration?: number) {\r\n if (!state.hasPendingUpdate || !state.latestBuildId) return\r\n\r\n const d = duration ?? opts.remindDelay\r\n const remindAt = d > 0 ? Date.now() + d : 0\r\n setRemindAt(opts.storagePrefix, remindAt)\r\n updateState({ remindAt })\r\n\r\n const manifest: VersionManifest = {\r\n buildId: state.latestBuildId,\r\n version: state.latestVersion || undefined,\r\n buildTime: state.latestBuildTime || undefined\r\n }\r\n\r\n emitter.emit('update-deferred', { manifest, remindAt })\r\n },\r\n\r\n getState() {\r\n return { ...state }\r\n },\r\n\r\n on(event, handler) {\r\n return emitter.on(event, handler)\r\n },\r\n\r\n off(event, handler) {\r\n emitter.off(event, handler)\r\n },\r\n\r\n setRuntimeEnv(env) {\r\n Object.assign(opts.runtimeEnv, env)\r\n }\r\n }\r\n\r\n return checker\r\n}\r\n"],"mappings":"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","names":["DEFAULT_VERSION_URL"]} | ||
| {"version":3,"sources":["../src/index.ts","../src/events.ts","../src/fetcher.ts","../src/refresh.ts","../src/storage.ts","../src/checker.ts"],"sourcesContent":["export { createVersionChecker } from './checker'\r\nexport type {\r\n VersionManifest,\r\n VersionRuntimeEnv,\r\n RefreshStrategy,\r\n RefreshContext,\r\n CheckerOptions,\r\n CheckerState,\r\n CheckerEventMap,\r\n VersionChecker\r\n} from './types'\r\n","import type { CheckerEventMap } from './types'\r\n\r\ntype Handler<T = unknown> = (payload: T) => void\r\n\r\n/**\r\n * Lightweight typed event emitter.\r\n * No external dependencies.\r\n */\r\nexport class EventEmitter {\r\n private listeners = new Map<string, Set<Handler>>()\r\n\r\n on<E extends keyof CheckerEventMap>(event: E, handler: Handler<CheckerEventMap[E]>): () => void {\r\n if (!this.listeners.has(event)) {\r\n this.listeners.set(event, new Set())\r\n }\r\n this.listeners.get(event)!.add(handler as Handler)\r\n return () => this.off(event, handler)\r\n }\r\n\r\n off<E extends keyof CheckerEventMap>(event: E, handler: Handler<CheckerEventMap[E]>): void {\r\n this.listeners.get(event)?.delete(handler as Handler)\r\n }\r\n\r\n emit<E extends keyof CheckerEventMap>(event: E, payload: CheckerEventMap[E]): void {\r\n this.listeners.get(event)?.forEach((handler) => {\r\n try {\r\n handler(payload)\r\n } catch (err) {\r\n console.error(`[cxkit] Error in \"${event}\" handler:`, err)\r\n }\r\n })\r\n }\r\n\r\n removeAll(): void {\r\n this.listeners.clear()\r\n }\r\n}\r\n","import type { VersionManifest, VersionRuntimeEnv } from './types'\r\n\r\nconst DEV_MOCK_QUERY_KEY = '__mock_version_update'\r\n\r\nexport function isDevMockEnabled(): boolean {\r\n return new URLSearchParams(window.location.search).get(DEV_MOCK_QUERY_KEY) === '1'\r\n}\r\n\r\nexport function readGlobalString(\r\n name: '__APP_VERSION__' | '__APP_BUILD_ID__' | '__APP_BUILD_TIME__' | '__APP_BASE_URL__'\r\n): string {\r\n const value = (globalThis as Record<string, unknown>)[name]\r\n return typeof value === 'string' ? value : ''\r\n}\r\n\r\nexport function resolveRuntimeEnv(\r\n envOverride: VersionRuntimeEnv,\r\n devMock: boolean\r\n): Required<VersionRuntimeEnv> {\r\n const DEV_MOCK_BUILD_ID = 'mock-current-build'\r\n const devMockEnabled = devMock && isDevMockEnabled()\r\n\r\n return {\r\n version: envOverride.version || readGlobalString('__APP_VERSION__'),\r\n buildId: devMockEnabled\r\n ? DEV_MOCK_BUILD_ID\r\n : envOverride.buildId || readGlobalString('__APP_BUILD_ID__'),\r\n buildTime: envOverride.buildTime || readGlobalString('__APP_BUILD_TIME__'),\r\n baseUrl: envOverride.baseUrl || readGlobalString('__APP_BASE_URL__')\r\n }\r\n}\r\n\r\nexport function getActiveLocationHref(): string {\r\n const wujieLocation = (window as any).$wujie?.location\r\n if (wujieLocation && typeof wujieLocation.href === 'string') {\r\n return wujieLocation.href\r\n }\r\n return window.location.href\r\n}\r\n\r\nexport function buildVersionManifestUrl(\r\n versionUrl: string | (() => string) | undefined,\r\n env: Required<VersionRuntimeEnv>\r\n): string {\r\n const DEFAULT_VERSION_URL = 'version.json'\r\n const customVersionUrl = typeof versionUrl === 'function' ? versionUrl() : versionUrl\r\n const manifestUrl = customVersionUrl || DEFAULT_VERSION_URL\r\n const baseUrl = env.baseUrl\r\n const versionBase = baseUrl\r\n ? new URL(baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`, getActiveLocationHref())\r\n : new URL(getActiveLocationHref())\r\n const url = new URL(manifestUrl, versionBase.toString())\r\n url.searchParams.set('t', Date.now().toString())\r\n return url.toString()\r\n}\r\n\r\nexport async function fetchVersionManifest(\r\n versionUrl: string | (() => string) | undefined,\r\n env: Required<VersionRuntimeEnv>,\r\n debugLog: (message: string, payload?: unknown) => void\r\n): Promise<VersionManifest> {\r\n const requestUrl = buildVersionManifestUrl(versionUrl, env)\r\n debugLog('Requesting version manifest', { requestUrl })\r\n\r\n const response = await fetch(requestUrl, { cache: 'no-store' })\r\n\r\n if (!response.ok) {\r\n throw new Error(`Version manifest request failed: ${response.status}`)\r\n }\r\n\r\n const manifest = (await response.json()) as VersionManifest\r\n debugLog('Version manifest received', manifest)\r\n return manifest\r\n}\r\n","import type { RefreshContext, RefreshStrategy } from './types'\r\nimport { isDevMockEnabled } from './fetcher'\r\n\r\nconst APP_VERSION_QUERY_KEY = '__app_v'\r\n\r\nfunction isEmbedded(): boolean {\r\n return Boolean((window as any).$wujie)\r\n}\r\n\r\nexport function resolveRefreshStrategy(strategy: RefreshStrategy, embedded: boolean): Exclude<RefreshStrategy, 'auto'> {\r\n if (strategy === 'auto') {\r\n return embedded ? 'top' : 'self'\r\n }\r\n return strategy\r\n}\r\n\r\nfunction reloadSelf(buildId: string): void {\r\n const currentUrl = new URL(window.location.href)\r\n const currentVersion = currentUrl.searchParams.get(APP_VERSION_QUERY_KEY)\r\n\r\n if (currentVersion !== buildId) {\r\n currentUrl.searchParams.set(APP_VERSION_QUERY_KEY, buildId)\r\n window.location.replace(currentUrl.toString())\r\n return\r\n }\r\n\r\n window.location.reload()\r\n}\r\n\r\nfunction reloadTopWindow(): void {\r\n try {\r\n if (window.top && window.top !== window) {\r\n window.top.location.reload()\r\n return\r\n }\r\n } catch (error) {\r\n console.warn('[cxkit] Top window reload failed, falling back to current window', error)\r\n }\r\n\r\n window.location.reload()\r\n}\r\n\r\nexport function buildRefreshContext(\r\n buildId: string,\r\n version: string,\r\n buildTime: string | undefined,\r\n strategy: RefreshStrategy\r\n): RefreshContext {\r\n const embedded = isEmbedded()\r\n return {\r\n version,\r\n buildId,\r\n buildTime,\r\n isEmbedded: embedded,\r\n strategy: resolveRefreshStrategy(strategy, embedded)\r\n }\r\n}\r\n\r\nexport function executeRefresh(\r\n context: RefreshContext,\r\n devMock: boolean,\r\n debugLog: (message: string, payload?: unknown) => void\r\n): void {\r\n if (devMock && isDevMockEnabled()) {\r\n debugLog('Dev mock mode: intercepted real refresh', { buildId: context.buildId })\r\n return\r\n }\r\n\r\n if (context.strategy === 'custom') {\r\n console.warn('[cxkit] refreshStrategy is \"custom\" but no before-refresh handler prevented default. Falling back to auto.')\r\n if (context.isEmbedded) {\r\n reloadTopWindow()\r\n } else {\r\n reloadSelf(context.buildId)\r\n }\r\n return\r\n }\r\n\r\n if (context.strategy === 'top') {\r\n reloadTopWindow()\r\n return\r\n }\r\n\r\n reloadSelf(context.buildId)\r\n}\r\n","const DEFAULT_PREFIX = 'CXKIT_VU_'\r\n\r\nexport function getStorageKey(prefix: string | undefined, name: string): string {\r\n return `${prefix ?? DEFAULT_PREFIX}${name}`\r\n}\r\n\r\nexport function clearPrefixedStorage(prefix: string | undefined): void {\r\n const p = prefix ?? DEFAULT_PREFIX\r\n\r\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\r\n const key = localStorage.key(i)\r\n if (key && key.startsWith(p)) {\r\n localStorage.removeItem(key)\r\n }\r\n }\r\n\r\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\r\n const key = sessionStorage.key(i)\r\n if (key && key.startsWith(p)) {\r\n sessionStorage.removeItem(key)\r\n }\r\n }\r\n}\r\n\r\nexport function persistVersion(prefix: string | undefined, buildId: string): void {\r\n localStorage.setItem(getStorageKey(prefix, 'version'), buildId)\r\n document.cookie = `app_version=${buildId}; path=/; max-age=31536000`\r\n}\r\n\r\nexport function getPersistedVersion(prefix: string | undefined): string | null {\r\n return localStorage.getItem(getStorageKey(prefix, 'version'))\r\n}\r\n\r\nexport function getRemindAt(prefix: string | undefined): number {\r\n return Number(localStorage.getItem(getStorageKey(prefix, 'version_remind_at')) || '0')\r\n}\r\n\r\nexport function setRemindAt(prefix: string | undefined, timestamp: number): void {\r\n if (timestamp > 0) {\r\n localStorage.setItem(getStorageKey(prefix, 'version_remind_at'), String(timestamp))\r\n } else {\r\n localStorage.removeItem(getStorageKey(prefix, 'version_remind_at'))\r\n }\r\n}\r\n\r\nexport function getPendingVersion(prefix: string | undefined): string | null {\r\n return localStorage.getItem(getStorageKey(prefix, 'pending_version'))\r\n}\r\n\r\nexport function setPendingVersion(prefix: string | undefined, buildId: string): void {\r\n localStorage.setItem(getStorageKey(prefix, 'pending_version'), buildId)\r\n}\r\n\r\nexport function removePendingVersion(prefix: string | undefined): void {\r\n localStorage.removeItem(getStorageKey(prefix, 'pending_version'))\r\n}\r\n\r\nexport function getReloadGuard(prefix: string | undefined): string | null {\r\n return sessionStorage.getItem(getStorageKey(prefix, 'reload_guard'))\r\n}\r\n\r\nexport function setReloadGuard(prefix: string | undefined, buildId: string): void {\r\n sessionStorage.setItem(getStorageKey(prefix, 'reload_guard'), buildId)\r\n}\r\n\r\nexport function removeReloadGuard(prefix: string | undefined): void {\r\n sessionStorage.removeItem(getStorageKey(prefix, 'reload_guard'))\r\n}\r\n\r\nexport function getConfirmedVersion(prefix: string | undefined): string | null {\r\n return localStorage.getItem(getStorageKey(prefix, 'confirmed_version'))\r\n}\r\n\r\nexport function setConfirmedVersion(prefix: string | undefined, buildId: string): void {\r\n localStorage.setItem(getStorageKey(prefix, 'confirmed_version'), buildId)\r\n}\r\n\r\nexport function removeConfirmedVersion(prefix: string | undefined): void {\r\n localStorage.removeItem(getStorageKey(prefix, 'confirmed_version'))\r\n}\r\n","import type {\r\n CheckerOptions,\r\n CheckerState,\r\n VersionChecker,\r\n VersionManifest,\r\n VersionRuntimeEnv\r\n} from './types'\r\nimport { EventEmitter } from './events'\r\nimport { resolveRuntimeEnv, fetchVersionManifest } from './fetcher'\r\nimport { buildRefreshContext, executeRefresh } from './refresh'\r\nimport {\r\n clearPrefixedStorage,\r\n persistVersion,\r\n getPersistedVersion,\r\n getRemindAt,\r\n setRemindAt,\r\n getPendingVersion,\r\n setPendingVersion,\r\n removePendingVersion,\r\n getReloadGuard,\r\n setReloadGuard,\r\n removeReloadGuard,\r\n getConfirmedVersion,\r\n setConfirmedVersion,\r\n removeConfirmedVersion\r\n} from './storage'\r\n\r\n// ─── Defaults ───────────────────────────────────────────────────\r\n\r\nconst DEFAULT_POLL_INTERVAL = 5 * 60 * 1000\r\nconst DEFAULT_REMIND_DELAY = 10 * 60 * 1000\r\nconst DEFAULT_VERSION_URL = 'version.json'\r\n\r\n// ─── Factory ────────────────────────────────────────────────────\r\n\r\nexport function createVersionChecker(options: CheckerOptions = {}): VersionChecker {\r\n // ── Resolved options ─────────────────────────────────\r\n\r\n const opts = {\r\n pollInterval: options.pollInterval ?? DEFAULT_POLL_INTERVAL,\r\n enableFocusCheck: options.enableFocusCheck ?? true,\r\n enableVisibilityCheck: options.enableVisibilityCheck ?? true,\r\n versionUrl: options.versionUrl ?? DEFAULT_VERSION_URL,\r\n refreshStrategy: options.refreshStrategy ?? 'auto' as const,\r\n remindDelay: options.remindDelay ?? DEFAULT_REMIND_DELAY,\r\n storagePrefix: options.storagePrefix,\r\n debug: options.debug ?? false,\r\n devMock: options.devMock ?? false,\r\n timeFormatter: options.timeFormatter,\r\n runtimeEnv: { ...(options.runtimeEnv || {}) } as VersionRuntimeEnv\r\n }\r\n\r\n // ── Internal state ───────────────────────────────────\r\n\r\n const state: CheckerState = {\r\n initialized: false,\r\n checking: false,\r\n hasPendingUpdate: false,\r\n latestBuildId: '',\r\n latestVersion: '',\r\n latestBuildTime: '',\r\n remindAt: 0\r\n }\r\n\r\n const emitter = new EventEmitter()\r\n let timerId: number | null = null\r\n let focusHandler: (() => void) | null = null\r\n let visibilityHandler: (() => void) | null = null\r\n\r\n // ── Helpers ──────────────────────────────────────────\r\n\r\n function debugLog(message: string, payload?: unknown): void {\r\n if (!opts.debug) return\r\n if (payload === undefined) {\r\n console.info(`[cxkit] ${message}`)\r\n } else {\r\n console.info(`[cxkit] ${message}`, payload)\r\n }\r\n }\r\n\r\n function getEnv() {\r\n return resolveRuntimeEnv(opts.runtimeEnv, opts.devMock)\r\n }\r\n\r\n function formatBuildTime(buildTime?: string): string {\r\n if (!buildTime) return ''\r\n return opts.timeFormatter ? opts.timeFormatter(buildTime) : buildTime\r\n }\r\n\r\n function emitStateChange(): void {\r\n emitter.emit('state-change', { ...state })\r\n }\r\n\r\n function updateState(patch: Partial<CheckerState>): void {\r\n Object.assign(state, patch)\r\n emitStateChange()\r\n }\r\n\r\n // ── Storage sync ─────────────────────────────────────\r\n\r\n function syncLocalVersion(): void {\r\n const env = getEnv()\r\n if (!env.buildId) {\r\n debugLog('No current buildId, skipping local version sync')\r\n return\r\n }\r\n\r\n // If the confirmed version matches current buildId, the refresh succeeded — clear the marker\r\n const confirmedVersion = getConfirmedVersion(opts.storagePrefix)\r\n if (confirmedVersion && confirmedVersion === env.buildId) {\r\n removeConfirmedVersion(opts.storagePrefix)\r\n debugLog('Confirmed version matches current buildId, refresh was successful', { confirmedVersion })\r\n }\r\n\r\n const oldVersion = getPersistedVersion(opts.storagePrefix)\r\n if (oldVersion === env.buildId) return\r\n\r\n clearPrefixedStorage(opts.storagePrefix)\r\n persistVersion(opts.storagePrefix, env.buildId)\r\n debugLog('Local version switched, cleared old cache', { oldVersion, currentBuildId: env.buildId })\r\n }\r\n\r\n function clearPendingState(): void {\r\n removeReloadGuard(opts.storagePrefix)\r\n removePendingVersion(opts.storagePrefix)\r\n updateState({\r\n hasPendingUpdate: false,\r\n latestBuildId: '',\r\n latestVersion: '',\r\n latestBuildTime: '',\r\n remindAt: 0\r\n })\r\n }\r\n\r\n function updatePendingState(manifest: VersionManifest): void {\r\n updateState({\r\n hasPendingUpdate: true,\r\n latestBuildId: manifest.buildId,\r\n latestVersion: manifest.version || '',\r\n latestBuildTime: formatBuildTime(manifest.buildTime)\r\n })\r\n }\r\n\r\n // ── Version check ────────────────────────────────────\r\n\r\n async function showUpdatePrompt(manifest: VersionManifest, force = false): Promise<void> {\r\n const remindAt = getRemindAt(opts.storagePrefix)\r\n state.remindAt = remindAt\r\n emitStateChange()\r\n\r\n if (!force && Date.now() < remindAt) {\r\n updatePendingState(manifest)\r\n debugLog('Remind cooldown active, keeping indicator only', { remindAt, manifest })\r\n return\r\n }\r\n\r\n updatePendingState(manifest)\r\n setPendingVersion(opts.storagePrefix, manifest.buildId)\r\n debugLog(force ? 'User triggered update panel' : 'Pending update state recorded', manifest)\r\n }\r\n\r\n async function checkVersion(): Promise<void> {\r\n if (state.checking) return\r\n\r\n const env = getEnv()\r\n if (!env.buildId) {\r\n debugLog('No current buildId, skipping version check')\r\n return\r\n }\r\n\r\n updateState({ checking: true })\r\n\r\n try {\r\n const latestManifest = await fetchVersionManifest(opts.versionUrl, env, debugLog)\r\n\r\n if (!latestManifest.buildId || latestManifest.buildId === env.buildId) {\r\n clearPendingState()\r\n debugLog('Remote version matches current, no update needed', latestManifest)\r\n return\r\n }\r\n\r\n // ── Anti-loop guard ─────────────────────────────────\r\n // If the user already confirmed this exact buildId (clicked \"立即更新\"),\r\n // but the browser served cached JS so __APP_BUILD_ID__ is still old,\r\n // do NOT show the popup again — the user has already acted on it.\r\n const confirmedVersion = getConfirmedVersion(opts.storagePrefix)\r\n if (confirmedVersion === latestManifest.buildId) {\r\n debugLog('This buildId was already confirmed by user, suppressing popup to avoid loop', {\r\n confirmedVersion,\r\n currentBuildId: env.buildId\r\n })\r\n return\r\n }\r\n\r\n const reloadGuard = getReloadGuard(opts.storagePrefix)\r\n updatePendingState(latestManifest)\r\n\r\n if (reloadGuard === latestManifest.buildId) {\r\n const pendingVersion = getPendingVersion(opts.storagePrefix)\r\n if (pendingVersion === latestManifest.buildId) {\r\n await showUpdatePrompt(latestManifest)\r\n }\r\n return\r\n }\r\n\r\n setReloadGuard(opts.storagePrefix, latestManifest.buildId)\r\n emitter.emit('update-detected', latestManifest)\r\n await showUpdatePrompt(latestManifest)\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error))\r\n console.error('[cxkit] Version check failed', err)\r\n emitter.emit('error', err)\r\n } finally {\r\n updateState({ checking: false })\r\n }\r\n }\r\n\r\n // ── Lifecycle ────────────────────────────────────────\r\n\r\n function bindLifecycle(): void {\r\n if (opts.enableFocusCheck) {\r\n focusHandler = () => void checkVersion()\r\n window.addEventListener('focus', focusHandler)\r\n }\r\n\r\n if (opts.enableVisibilityCheck) {\r\n visibilityHandler = () => {\r\n if (document.visibilityState === 'visible') {\r\n void checkVersion()\r\n }\r\n }\r\n document.addEventListener('visibilitychange', visibilityHandler)\r\n }\r\n\r\n if (opts.pollInterval > 0) {\r\n timerId = window.setInterval(() => void checkVersion(), opts.pollInterval)\r\n }\r\n }\r\n\r\n function clearLifecycle(): void {\r\n if (focusHandler) {\r\n window.removeEventListener('focus', focusHandler)\r\n focusHandler = null\r\n }\r\n if (visibilityHandler) {\r\n document.removeEventListener('visibilitychange', visibilityHandler)\r\n visibilityHandler = null\r\n }\r\n if (timerId !== null) {\r\n window.clearInterval(timerId)\r\n timerId = null\r\n }\r\n }\r\n\r\n // ── Public API ───────────────────────────────────────\r\n\r\n const checker: VersionChecker = {\r\n start() {\r\n if (state.initialized) {\r\n debugLog('Already initialized, ignoring duplicate start()')\r\n return\r\n }\r\n\r\n updateState({ initialized: true })\r\n\r\n debugLog('Version checker started', {\r\n pollInterval: opts.pollInterval,\r\n remindDelay: opts.remindDelay,\r\n enableFocusCheck: opts.enableFocusCheck,\r\n enableVisibilityCheck: opts.enableVisibilityCheck,\r\n refreshStrategy: opts.refreshStrategy,\r\n versionUrl: opts.versionUrl,\r\n storagePrefix: opts.storagePrefix,\r\n runtimeEnv: getEnv(),\r\n devMock: opts.devMock\r\n })\r\n\r\n syncLocalVersion()\r\n void checkVersion()\r\n bindLifecycle()\r\n },\r\n\r\n stop() {\r\n clearLifecycle()\r\n debugLog('Version checker stopped')\r\n },\r\n\r\n destroy() {\r\n clearLifecycle()\r\n updateState({ initialized: false, checking: false })\r\n emitter.removeAll()\r\n debugLog('Version checker destroyed')\r\n },\r\n\r\n async check() {\r\n await checkVersion()\r\n },\r\n\r\n async confirm() {\r\n if (!state.hasPendingUpdate || !state.latestBuildId) return\r\n\r\n const manifest: VersionManifest = {\r\n buildId: state.latestBuildId,\r\n version: state.latestVersion || undefined,\r\n buildTime: state.latestBuildTime || undefined\r\n }\r\n\r\n emitter.emit('update-confirmed', manifest)\r\n\r\n // Persist confirmed buildId BEFORE refreshing so the checker\r\n // won't re-show the popup if the browser serves cached JS after reload\r\n setConfirmedVersion(opts.storagePrefix, state.latestBuildId)\r\n\r\n const context = buildRefreshContext(\r\n state.latestBuildId,\r\n state.latestVersion,\r\n state.latestBuildTime || undefined,\r\n opts.refreshStrategy\r\n )\r\n\r\n clearPendingState()\r\n\r\n emitter.emit('before-refresh', context)\r\n executeRefresh(context, opts.devMock, debugLog)\r\n },\r\n\r\n defer(duration?: number) {\r\n if (!state.hasPendingUpdate || !state.latestBuildId) return\r\n\r\n const d = duration ?? opts.remindDelay\r\n const remindAt = d > 0 ? Date.now() + d : 0\r\n setRemindAt(opts.storagePrefix, remindAt)\r\n updateState({ remindAt })\r\n\r\n const manifest: VersionManifest = {\r\n buildId: state.latestBuildId,\r\n version: state.latestVersion || undefined,\r\n buildTime: state.latestBuildTime || undefined\r\n }\r\n\r\n emitter.emit('update-deferred', { manifest, remindAt })\r\n },\r\n\r\n getState() {\r\n return { ...state }\r\n },\r\n\r\n on(event, handler) {\r\n return emitter.on(event, handler)\r\n },\r\n\r\n off(event, handler) {\r\n emitter.off(event, handler)\r\n },\r\n\r\n setRuntimeEnv(env) {\r\n Object.assign(opts.runtimeEnv, env)\r\n }\r\n }\r\n\r\n return checker\r\n}\r\n"],"mappings":"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","names":["DEFAULT_VERSION_URL"]} |
+23
-0
@@ -194,2 +194,11 @@ // src/events.ts | ||
| } | ||
| function getConfirmedVersion(prefix) { | ||
| return localStorage.getItem(getStorageKey(prefix, "confirmed_version")); | ||
| } | ||
| function setConfirmedVersion(prefix, buildId) { | ||
| localStorage.setItem(getStorageKey(prefix, "confirmed_version"), buildId); | ||
| } | ||
| function removeConfirmedVersion(prefix) { | ||
| localStorage.removeItem(getStorageKey(prefix, "confirmed_version")); | ||
| } | ||
@@ -255,2 +264,7 @@ // src/checker.ts | ||
| } | ||
| const confirmedVersion = getConfirmedVersion(opts.storagePrefix); | ||
| if (confirmedVersion && confirmedVersion === env.buildId) { | ||
| removeConfirmedVersion(opts.storagePrefix); | ||
| debugLog("Confirmed version matches current buildId, refresh was successful", { confirmedVersion }); | ||
| } | ||
| const oldVersion = getPersistedVersion(opts.storagePrefix); | ||
@@ -309,2 +323,10 @@ if (oldVersion === env.buildId) return; | ||
| } | ||
| const confirmedVersion = getConfirmedVersion(opts.storagePrefix); | ||
| if (confirmedVersion === latestManifest.buildId) { | ||
| debugLog("This buildId was already confirmed by user, suppressing popup to avoid loop", { | ||
| confirmedVersion, | ||
| currentBuildId: env.buildId | ||
| }); | ||
| return; | ||
| } | ||
| const reloadGuard = getReloadGuard(opts.storagePrefix); | ||
@@ -404,2 +426,3 @@ updatePendingState(latestManifest); | ||
| emitter.emit("update-confirmed", manifest); | ||
| setConfirmedVersion(opts.storagePrefix, state.latestBuildId); | ||
| const context = buildRefreshContext( | ||
@@ -406,0 +429,0 @@ state.latestBuildId, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/events.ts","../src/fetcher.ts","../src/refresh.ts","../src/storage.ts","../src/checker.ts"],"sourcesContent":["import type { CheckerEventMap } from './types'\r\n\r\ntype Handler<T = unknown> = (payload: T) => void\r\n\r\n/**\r\n * Lightweight typed event emitter.\r\n * No external dependencies.\r\n */\r\nexport class EventEmitter {\r\n private listeners = new Map<string, Set<Handler>>()\r\n\r\n on<E extends keyof CheckerEventMap>(event: E, handler: Handler<CheckerEventMap[E]>): () => void {\r\n if (!this.listeners.has(event)) {\r\n this.listeners.set(event, new Set())\r\n }\r\n this.listeners.get(event)!.add(handler as Handler)\r\n return () => this.off(event, handler)\r\n }\r\n\r\n off<E extends keyof CheckerEventMap>(event: E, handler: Handler<CheckerEventMap[E]>): void {\r\n this.listeners.get(event)?.delete(handler as Handler)\r\n }\r\n\r\n emit<E extends keyof CheckerEventMap>(event: E, payload: CheckerEventMap[E]): void {\r\n this.listeners.get(event)?.forEach((handler) => {\r\n try {\r\n handler(payload)\r\n } catch (err) {\r\n console.error(`[cxkit] Error in \"${event}\" handler:`, err)\r\n }\r\n })\r\n }\r\n\r\n removeAll(): void {\r\n this.listeners.clear()\r\n }\r\n}\r\n","import type { VersionManifest, VersionRuntimeEnv } from './types'\r\n\r\nconst DEV_MOCK_QUERY_KEY = '__mock_version_update'\r\n\r\nexport function isDevMockEnabled(): boolean {\r\n return new URLSearchParams(window.location.search).get(DEV_MOCK_QUERY_KEY) === '1'\r\n}\r\n\r\nexport function readGlobalString(\r\n name: '__APP_VERSION__' | '__APP_BUILD_ID__' | '__APP_BUILD_TIME__' | '__APP_BASE_URL__'\r\n): string {\r\n const value = (globalThis as Record<string, unknown>)[name]\r\n return typeof value === 'string' ? value : ''\r\n}\r\n\r\nexport function resolveRuntimeEnv(\r\n envOverride: VersionRuntimeEnv,\r\n devMock: boolean\r\n): Required<VersionRuntimeEnv> {\r\n const DEV_MOCK_BUILD_ID = 'mock-current-build'\r\n const devMockEnabled = devMock && isDevMockEnabled()\r\n\r\n return {\r\n version: envOverride.version || readGlobalString('__APP_VERSION__'),\r\n buildId: devMockEnabled\r\n ? DEV_MOCK_BUILD_ID\r\n : envOverride.buildId || readGlobalString('__APP_BUILD_ID__'),\r\n buildTime: envOverride.buildTime || readGlobalString('__APP_BUILD_TIME__'),\r\n baseUrl: envOverride.baseUrl || readGlobalString('__APP_BASE_URL__')\r\n }\r\n}\r\n\r\nexport function getActiveLocationHref(): string {\r\n const wujieLocation = (window as any).$wujie?.location\r\n if (wujieLocation && typeof wujieLocation.href === 'string') {\r\n return wujieLocation.href\r\n }\r\n return window.location.href\r\n}\r\n\r\nexport function buildVersionManifestUrl(\r\n versionUrl: string | (() => string) | undefined,\r\n env: Required<VersionRuntimeEnv>\r\n): string {\r\n const DEFAULT_VERSION_URL = 'version.json'\r\n const customVersionUrl = typeof versionUrl === 'function' ? versionUrl() : versionUrl\r\n const manifestUrl = customVersionUrl || DEFAULT_VERSION_URL\r\n const baseUrl = env.baseUrl\r\n const versionBase = baseUrl\r\n ? new URL(baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`, getActiveLocationHref())\r\n : new URL(getActiveLocationHref())\r\n const url = new URL(manifestUrl, versionBase.toString())\r\n url.searchParams.set('t', Date.now().toString())\r\n return url.toString()\r\n}\r\n\r\nexport async function fetchVersionManifest(\r\n versionUrl: string | (() => string) | undefined,\r\n env: Required<VersionRuntimeEnv>,\r\n debugLog: (message: string, payload?: unknown) => void\r\n): Promise<VersionManifest> {\r\n const requestUrl = buildVersionManifestUrl(versionUrl, env)\r\n debugLog('Requesting version manifest', { requestUrl })\r\n\r\n const response = await fetch(requestUrl, { cache: 'no-store' })\r\n\r\n if (!response.ok) {\r\n throw new Error(`Version manifest request failed: ${response.status}`)\r\n }\r\n\r\n const manifest = (await response.json()) as VersionManifest\r\n debugLog('Version manifest received', manifest)\r\n return manifest\r\n}\r\n","import type { RefreshContext, RefreshStrategy } from './types'\r\nimport { isDevMockEnabled } from './fetcher'\r\n\r\nconst APP_VERSION_QUERY_KEY = '__app_v'\r\n\r\nfunction isEmbedded(): boolean {\r\n return Boolean((window as any).$wujie)\r\n}\r\n\r\nexport function resolveRefreshStrategy(strategy: RefreshStrategy, embedded: boolean): Exclude<RefreshStrategy, 'auto'> {\r\n if (strategy === 'auto') {\r\n return embedded ? 'top' : 'self'\r\n }\r\n return strategy\r\n}\r\n\r\nfunction reloadSelf(buildId: string): void {\r\n const currentUrl = new URL(window.location.href)\r\n const currentVersion = currentUrl.searchParams.get(APP_VERSION_QUERY_KEY)\r\n\r\n if (currentVersion !== buildId) {\r\n currentUrl.searchParams.set(APP_VERSION_QUERY_KEY, buildId)\r\n window.location.replace(currentUrl.toString())\r\n return\r\n }\r\n\r\n window.location.reload()\r\n}\r\n\r\nfunction reloadTopWindow(): void {\r\n try {\r\n if (window.top && window.top !== window) {\r\n window.top.location.reload()\r\n return\r\n }\r\n } catch (error) {\r\n console.warn('[cxkit] Top window reload failed, falling back to current window', error)\r\n }\r\n\r\n window.location.reload()\r\n}\r\n\r\nexport function buildRefreshContext(\r\n buildId: string,\r\n version: string,\r\n buildTime: string | undefined,\r\n strategy: RefreshStrategy\r\n): RefreshContext {\r\n const embedded = isEmbedded()\r\n return {\r\n version,\r\n buildId,\r\n buildTime,\r\n isEmbedded: embedded,\r\n strategy: resolveRefreshStrategy(strategy, embedded)\r\n }\r\n}\r\n\r\nexport function executeRefresh(\r\n context: RefreshContext,\r\n devMock: boolean,\r\n debugLog: (message: string, payload?: unknown) => void\r\n): void {\r\n if (devMock && isDevMockEnabled()) {\r\n debugLog('Dev mock mode: intercepted real refresh', { buildId: context.buildId })\r\n return\r\n }\r\n\r\n if (context.strategy === 'custom') {\r\n console.warn('[cxkit] refreshStrategy is \"custom\" but no before-refresh handler prevented default. Falling back to auto.')\r\n if (context.isEmbedded) {\r\n reloadTopWindow()\r\n } else {\r\n reloadSelf(context.buildId)\r\n }\r\n return\r\n }\r\n\r\n if (context.strategy === 'top') {\r\n reloadTopWindow()\r\n return\r\n }\r\n\r\n reloadSelf(context.buildId)\r\n}\r\n","const DEFAULT_PREFIX = 'CXKIT_VU_'\r\n\r\nexport function getStorageKey(prefix: string | undefined, name: string): string {\r\n return `${prefix ?? DEFAULT_PREFIX}${name}`\r\n}\r\n\r\nexport function clearPrefixedStorage(prefix: string | undefined): void {\r\n const p = prefix ?? DEFAULT_PREFIX\r\n\r\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\r\n const key = localStorage.key(i)\r\n if (key && key.startsWith(p)) {\r\n localStorage.removeItem(key)\r\n }\r\n }\r\n\r\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\r\n const key = sessionStorage.key(i)\r\n if (key && key.startsWith(p)) {\r\n sessionStorage.removeItem(key)\r\n }\r\n }\r\n}\r\n\r\nexport function persistVersion(prefix: string | undefined, buildId: string): void {\r\n localStorage.setItem(getStorageKey(prefix, 'version'), buildId)\r\n document.cookie = `app_version=${buildId}; path=/; max-age=31536000`\r\n}\r\n\r\nexport function getPersistedVersion(prefix: string | undefined): string | null {\r\n return localStorage.getItem(getStorageKey(prefix, 'version'))\r\n}\r\n\r\nexport function getRemindAt(prefix: string | undefined): number {\r\n return Number(localStorage.getItem(getStorageKey(prefix, 'version_remind_at')) || '0')\r\n}\r\n\r\nexport function setRemindAt(prefix: string | undefined, timestamp: number): void {\r\n if (timestamp > 0) {\r\n localStorage.setItem(getStorageKey(prefix, 'version_remind_at'), String(timestamp))\r\n } else {\r\n localStorage.removeItem(getStorageKey(prefix, 'version_remind_at'))\r\n }\r\n}\r\n\r\nexport function getPendingVersion(prefix: string | undefined): string | null {\r\n return localStorage.getItem(getStorageKey(prefix, 'pending_version'))\r\n}\r\n\r\nexport function setPendingVersion(prefix: string | undefined, buildId: string): void {\r\n localStorage.setItem(getStorageKey(prefix, 'pending_version'), buildId)\r\n}\r\n\r\nexport function removePendingVersion(prefix: string | undefined): void {\r\n localStorage.removeItem(getStorageKey(prefix, 'pending_version'))\r\n}\r\n\r\nexport function getReloadGuard(prefix: string | undefined): string | null {\r\n return sessionStorage.getItem(getStorageKey(prefix, 'reload_guard'))\r\n}\r\n\r\nexport function setReloadGuard(prefix: string | undefined, buildId: string): void {\r\n sessionStorage.setItem(getStorageKey(prefix, 'reload_guard'), buildId)\r\n}\r\n\r\nexport function removeReloadGuard(prefix: string | undefined): void {\r\n sessionStorage.removeItem(getStorageKey(prefix, 'reload_guard'))\r\n}\r\n","import type {\r\n CheckerOptions,\r\n CheckerState,\r\n VersionChecker,\r\n VersionManifest,\r\n VersionRuntimeEnv\r\n} from './types'\r\nimport { EventEmitter } from './events'\r\nimport { resolveRuntimeEnv, fetchVersionManifest } from './fetcher'\r\nimport { buildRefreshContext, executeRefresh } from './refresh'\r\nimport {\r\n clearPrefixedStorage,\r\n persistVersion,\r\n getPersistedVersion,\r\n getRemindAt,\r\n setRemindAt,\r\n getPendingVersion,\r\n setPendingVersion,\r\n removePendingVersion,\r\n getReloadGuard,\r\n setReloadGuard,\r\n removeReloadGuard\r\n} from './storage'\r\n\r\n// ─── Defaults ───────────────────────────────────────────────────\r\n\r\nconst DEFAULT_POLL_INTERVAL = 5 * 60 * 1000\r\nconst DEFAULT_REMIND_DELAY = 10 * 60 * 1000\r\nconst DEFAULT_VERSION_URL = 'version.json'\r\n\r\n// ─── Factory ────────────────────────────────────────────────────\r\n\r\nexport function createVersionChecker(options: CheckerOptions = {}): VersionChecker {\r\n // ── Resolved options ─────────────────────────────────\r\n\r\n const opts = {\r\n pollInterval: options.pollInterval ?? DEFAULT_POLL_INTERVAL,\r\n enableFocusCheck: options.enableFocusCheck ?? true,\r\n enableVisibilityCheck: options.enableVisibilityCheck ?? true,\r\n versionUrl: options.versionUrl ?? DEFAULT_VERSION_URL,\r\n refreshStrategy: options.refreshStrategy ?? 'auto' as const,\r\n remindDelay: options.remindDelay ?? DEFAULT_REMIND_DELAY,\r\n storagePrefix: options.storagePrefix,\r\n debug: options.debug ?? false,\r\n devMock: options.devMock ?? false,\r\n timeFormatter: options.timeFormatter,\r\n runtimeEnv: { ...(options.runtimeEnv || {}) } as VersionRuntimeEnv\r\n }\r\n\r\n // ── Internal state ───────────────────────────────────\r\n\r\n const state: CheckerState = {\r\n initialized: false,\r\n checking: false,\r\n hasPendingUpdate: false,\r\n latestBuildId: '',\r\n latestVersion: '',\r\n latestBuildTime: '',\r\n remindAt: 0\r\n }\r\n\r\n const emitter = new EventEmitter()\r\n let timerId: number | null = null\r\n let focusHandler: (() => void) | null = null\r\n let visibilityHandler: (() => void) | null = null\r\n\r\n // ── Helpers ──────────────────────────────────────────\r\n\r\n function debugLog(message: string, payload?: unknown): void {\r\n if (!opts.debug) return\r\n if (payload === undefined) {\r\n console.info(`[cxkit] ${message}`)\r\n } else {\r\n console.info(`[cxkit] ${message}`, payload)\r\n }\r\n }\r\n\r\n function getEnv() {\r\n return resolveRuntimeEnv(opts.runtimeEnv, opts.devMock)\r\n }\r\n\r\n function formatBuildTime(buildTime?: string): string {\r\n if (!buildTime) return ''\r\n return opts.timeFormatter ? opts.timeFormatter(buildTime) : buildTime\r\n }\r\n\r\n function emitStateChange(): void {\r\n emitter.emit('state-change', { ...state })\r\n }\r\n\r\n function updateState(patch: Partial<CheckerState>): void {\r\n Object.assign(state, patch)\r\n emitStateChange()\r\n }\r\n\r\n // ── Storage sync ─────────────────────────────────────\r\n\r\n function syncLocalVersion(): void {\r\n const env = getEnv()\r\n if (!env.buildId) {\r\n debugLog('No current buildId, skipping local version sync')\r\n return\r\n }\r\n\r\n const oldVersion = getPersistedVersion(opts.storagePrefix)\r\n if (oldVersion === env.buildId) return\r\n\r\n clearPrefixedStorage(opts.storagePrefix)\r\n persistVersion(opts.storagePrefix, env.buildId)\r\n debugLog('Local version switched, cleared old cache', { oldVersion, currentBuildId: env.buildId })\r\n }\r\n\r\n function clearPendingState(): void {\r\n removeReloadGuard(opts.storagePrefix)\r\n removePendingVersion(opts.storagePrefix)\r\n updateState({\r\n hasPendingUpdate: false,\r\n latestBuildId: '',\r\n latestVersion: '',\r\n latestBuildTime: '',\r\n remindAt: 0\r\n })\r\n }\r\n\r\n function updatePendingState(manifest: VersionManifest): void {\r\n updateState({\r\n hasPendingUpdate: true,\r\n latestBuildId: manifest.buildId,\r\n latestVersion: manifest.version || '',\r\n latestBuildTime: formatBuildTime(manifest.buildTime)\r\n })\r\n }\r\n\r\n // ── Version check ────────────────────────────────────\r\n\r\n async function showUpdatePrompt(manifest: VersionManifest, force = false): Promise<void> {\r\n const remindAt = getRemindAt(opts.storagePrefix)\r\n state.remindAt = remindAt\r\n emitStateChange()\r\n\r\n if (!force && Date.now() < remindAt) {\r\n updatePendingState(manifest)\r\n debugLog('Remind cooldown active, keeping indicator only', { remindAt, manifest })\r\n return\r\n }\r\n\r\n updatePendingState(manifest)\r\n setPendingVersion(opts.storagePrefix, manifest.buildId)\r\n debugLog(force ? 'User triggered update panel' : 'Pending update state recorded', manifest)\r\n }\r\n\r\n async function checkVersion(): Promise<void> {\r\n if (state.checking) return\r\n\r\n const env = getEnv()\r\n if (!env.buildId) {\r\n debugLog('No current buildId, skipping version check')\r\n return\r\n }\r\n\r\n updateState({ checking: true })\r\n\r\n try {\r\n const latestManifest = await fetchVersionManifest(opts.versionUrl, env, debugLog)\r\n\r\n if (!latestManifest.buildId || latestManifest.buildId === env.buildId) {\r\n clearPendingState()\r\n debugLog('Remote version matches current, no update needed', latestManifest)\r\n return\r\n }\r\n\r\n const reloadGuard = getReloadGuard(opts.storagePrefix)\r\n updatePendingState(latestManifest)\r\n\r\n if (reloadGuard === latestManifest.buildId) {\r\n const pendingVersion = getPendingVersion(opts.storagePrefix)\r\n if (pendingVersion === latestManifest.buildId) {\r\n await showUpdatePrompt(latestManifest)\r\n }\r\n return\r\n }\r\n\r\n setReloadGuard(opts.storagePrefix, latestManifest.buildId)\r\n emitter.emit('update-detected', latestManifest)\r\n await showUpdatePrompt(latestManifest)\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error))\r\n console.error('[cxkit] Version check failed', err)\r\n emitter.emit('error', err)\r\n } finally {\r\n updateState({ checking: false })\r\n }\r\n }\r\n\r\n // ── Lifecycle ────────────────────────────────────────\r\n\r\n function bindLifecycle(): void {\r\n if (opts.enableFocusCheck) {\r\n focusHandler = () => void checkVersion()\r\n window.addEventListener('focus', focusHandler)\r\n }\r\n\r\n if (opts.enableVisibilityCheck) {\r\n visibilityHandler = () => {\r\n if (document.visibilityState === 'visible') {\r\n void checkVersion()\r\n }\r\n }\r\n document.addEventListener('visibilitychange', visibilityHandler)\r\n }\r\n\r\n if (opts.pollInterval > 0) {\r\n timerId = window.setInterval(() => void checkVersion(), opts.pollInterval)\r\n }\r\n }\r\n\r\n function clearLifecycle(): void {\r\n if (focusHandler) {\r\n window.removeEventListener('focus', focusHandler)\r\n focusHandler = null\r\n }\r\n if (visibilityHandler) {\r\n document.removeEventListener('visibilitychange', visibilityHandler)\r\n visibilityHandler = null\r\n }\r\n if (timerId !== null) {\r\n window.clearInterval(timerId)\r\n timerId = null\r\n }\r\n }\r\n\r\n // ── Public API ───────────────────────────────────────\r\n\r\n const checker: VersionChecker = {\r\n start() {\r\n if (state.initialized) {\r\n debugLog('Already initialized, ignoring duplicate start()')\r\n return\r\n }\r\n\r\n updateState({ initialized: true })\r\n\r\n debugLog('Version checker started', {\r\n pollInterval: opts.pollInterval,\r\n remindDelay: opts.remindDelay,\r\n enableFocusCheck: opts.enableFocusCheck,\r\n enableVisibilityCheck: opts.enableVisibilityCheck,\r\n refreshStrategy: opts.refreshStrategy,\r\n versionUrl: opts.versionUrl,\r\n storagePrefix: opts.storagePrefix,\r\n runtimeEnv: getEnv(),\r\n devMock: opts.devMock\r\n })\r\n\r\n syncLocalVersion()\r\n void checkVersion()\r\n bindLifecycle()\r\n },\r\n\r\n stop() {\r\n clearLifecycle()\r\n debugLog('Version checker stopped')\r\n },\r\n\r\n destroy() {\r\n clearLifecycle()\r\n updateState({ initialized: false, checking: false })\r\n emitter.removeAll()\r\n debugLog('Version checker destroyed')\r\n },\r\n\r\n async check() {\r\n await checkVersion()\r\n },\r\n\r\n async confirm() {\r\n if (!state.hasPendingUpdate || !state.latestBuildId) return\r\n\r\n const manifest: VersionManifest = {\r\n buildId: state.latestBuildId,\r\n version: state.latestVersion || undefined,\r\n buildTime: state.latestBuildTime || undefined\r\n }\r\n\r\n emitter.emit('update-confirmed', manifest)\r\n\r\n const context = buildRefreshContext(\r\n state.latestBuildId,\r\n state.latestVersion,\r\n state.latestBuildTime || undefined,\r\n opts.refreshStrategy\r\n )\r\n\r\n clearPendingState()\r\n\r\n emitter.emit('before-refresh', context)\r\n executeRefresh(context, opts.devMock, debugLog)\r\n },\r\n\r\n defer(duration?: number) {\r\n if (!state.hasPendingUpdate || !state.latestBuildId) return\r\n\r\n const d = duration ?? opts.remindDelay\r\n const remindAt = d > 0 ? Date.now() + d : 0\r\n setRemindAt(opts.storagePrefix, remindAt)\r\n updateState({ remindAt })\r\n\r\n const manifest: VersionManifest = {\r\n buildId: state.latestBuildId,\r\n version: state.latestVersion || undefined,\r\n buildTime: state.latestBuildTime || undefined\r\n }\r\n\r\n emitter.emit('update-deferred', { manifest, remindAt })\r\n },\r\n\r\n getState() {\r\n return { ...state }\r\n },\r\n\r\n on(event, handler) {\r\n return emitter.on(event, handler)\r\n },\r\n\r\n off(event, handler) {\r\n emitter.off(event, handler)\r\n },\r\n\r\n setRuntimeEnv(env) {\r\n Object.assign(opts.runtimeEnv, env)\r\n }\r\n }\r\n\r\n return checker\r\n}\r\n"],"mappings":"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","names":["DEFAULT_VERSION_URL"]} | ||
| {"version":3,"sources":["../src/events.ts","../src/fetcher.ts","../src/refresh.ts","../src/storage.ts","../src/checker.ts"],"sourcesContent":["import type { CheckerEventMap } from './types'\r\n\r\ntype Handler<T = unknown> = (payload: T) => void\r\n\r\n/**\r\n * Lightweight typed event emitter.\r\n * No external dependencies.\r\n */\r\nexport class EventEmitter {\r\n private listeners = new Map<string, Set<Handler>>()\r\n\r\n on<E extends keyof CheckerEventMap>(event: E, handler: Handler<CheckerEventMap[E]>): () => void {\r\n if (!this.listeners.has(event)) {\r\n this.listeners.set(event, new Set())\r\n }\r\n this.listeners.get(event)!.add(handler as Handler)\r\n return () => this.off(event, handler)\r\n }\r\n\r\n off<E extends keyof CheckerEventMap>(event: E, handler: Handler<CheckerEventMap[E]>): void {\r\n this.listeners.get(event)?.delete(handler as Handler)\r\n }\r\n\r\n emit<E extends keyof CheckerEventMap>(event: E, payload: CheckerEventMap[E]): void {\r\n this.listeners.get(event)?.forEach((handler) => {\r\n try {\r\n handler(payload)\r\n } catch (err) {\r\n console.error(`[cxkit] Error in \"${event}\" handler:`, err)\r\n }\r\n })\r\n }\r\n\r\n removeAll(): void {\r\n this.listeners.clear()\r\n }\r\n}\r\n","import type { VersionManifest, VersionRuntimeEnv } from './types'\r\n\r\nconst DEV_MOCK_QUERY_KEY = '__mock_version_update'\r\n\r\nexport function isDevMockEnabled(): boolean {\r\n return new URLSearchParams(window.location.search).get(DEV_MOCK_QUERY_KEY) === '1'\r\n}\r\n\r\nexport function readGlobalString(\r\n name: '__APP_VERSION__' | '__APP_BUILD_ID__' | '__APP_BUILD_TIME__' | '__APP_BASE_URL__'\r\n): string {\r\n const value = (globalThis as Record<string, unknown>)[name]\r\n return typeof value === 'string' ? value : ''\r\n}\r\n\r\nexport function resolveRuntimeEnv(\r\n envOverride: VersionRuntimeEnv,\r\n devMock: boolean\r\n): Required<VersionRuntimeEnv> {\r\n const DEV_MOCK_BUILD_ID = 'mock-current-build'\r\n const devMockEnabled = devMock && isDevMockEnabled()\r\n\r\n return {\r\n version: envOverride.version || readGlobalString('__APP_VERSION__'),\r\n buildId: devMockEnabled\r\n ? DEV_MOCK_BUILD_ID\r\n : envOverride.buildId || readGlobalString('__APP_BUILD_ID__'),\r\n buildTime: envOverride.buildTime || readGlobalString('__APP_BUILD_TIME__'),\r\n baseUrl: envOverride.baseUrl || readGlobalString('__APP_BASE_URL__')\r\n }\r\n}\r\n\r\nexport function getActiveLocationHref(): string {\r\n const wujieLocation = (window as any).$wujie?.location\r\n if (wujieLocation && typeof wujieLocation.href === 'string') {\r\n return wujieLocation.href\r\n }\r\n return window.location.href\r\n}\r\n\r\nexport function buildVersionManifestUrl(\r\n versionUrl: string | (() => string) | undefined,\r\n env: Required<VersionRuntimeEnv>\r\n): string {\r\n const DEFAULT_VERSION_URL = 'version.json'\r\n const customVersionUrl = typeof versionUrl === 'function' ? versionUrl() : versionUrl\r\n const manifestUrl = customVersionUrl || DEFAULT_VERSION_URL\r\n const baseUrl = env.baseUrl\r\n const versionBase = baseUrl\r\n ? new URL(baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`, getActiveLocationHref())\r\n : new URL(getActiveLocationHref())\r\n const url = new URL(manifestUrl, versionBase.toString())\r\n url.searchParams.set('t', Date.now().toString())\r\n return url.toString()\r\n}\r\n\r\nexport async function fetchVersionManifest(\r\n versionUrl: string | (() => string) | undefined,\r\n env: Required<VersionRuntimeEnv>,\r\n debugLog: (message: string, payload?: unknown) => void\r\n): Promise<VersionManifest> {\r\n const requestUrl = buildVersionManifestUrl(versionUrl, env)\r\n debugLog('Requesting version manifest', { requestUrl })\r\n\r\n const response = await fetch(requestUrl, { cache: 'no-store' })\r\n\r\n if (!response.ok) {\r\n throw new Error(`Version manifest request failed: ${response.status}`)\r\n }\r\n\r\n const manifest = (await response.json()) as VersionManifest\r\n debugLog('Version manifest received', manifest)\r\n return manifest\r\n}\r\n","import type { RefreshContext, RefreshStrategy } from './types'\r\nimport { isDevMockEnabled } from './fetcher'\r\n\r\nconst APP_VERSION_QUERY_KEY = '__app_v'\r\n\r\nfunction isEmbedded(): boolean {\r\n return Boolean((window as any).$wujie)\r\n}\r\n\r\nexport function resolveRefreshStrategy(strategy: RefreshStrategy, embedded: boolean): Exclude<RefreshStrategy, 'auto'> {\r\n if (strategy === 'auto') {\r\n return embedded ? 'top' : 'self'\r\n }\r\n return strategy\r\n}\r\n\r\nfunction reloadSelf(buildId: string): void {\r\n const currentUrl = new URL(window.location.href)\r\n const currentVersion = currentUrl.searchParams.get(APP_VERSION_QUERY_KEY)\r\n\r\n if (currentVersion !== buildId) {\r\n currentUrl.searchParams.set(APP_VERSION_QUERY_KEY, buildId)\r\n window.location.replace(currentUrl.toString())\r\n return\r\n }\r\n\r\n window.location.reload()\r\n}\r\n\r\nfunction reloadTopWindow(): void {\r\n try {\r\n if (window.top && window.top !== window) {\r\n window.top.location.reload()\r\n return\r\n }\r\n } catch (error) {\r\n console.warn('[cxkit] Top window reload failed, falling back to current window', error)\r\n }\r\n\r\n window.location.reload()\r\n}\r\n\r\nexport function buildRefreshContext(\r\n buildId: string,\r\n version: string,\r\n buildTime: string | undefined,\r\n strategy: RefreshStrategy\r\n): RefreshContext {\r\n const embedded = isEmbedded()\r\n return {\r\n version,\r\n buildId,\r\n buildTime,\r\n isEmbedded: embedded,\r\n strategy: resolveRefreshStrategy(strategy, embedded)\r\n }\r\n}\r\n\r\nexport function executeRefresh(\r\n context: RefreshContext,\r\n devMock: boolean,\r\n debugLog: (message: string, payload?: unknown) => void\r\n): void {\r\n if (devMock && isDevMockEnabled()) {\r\n debugLog('Dev mock mode: intercepted real refresh', { buildId: context.buildId })\r\n return\r\n }\r\n\r\n if (context.strategy === 'custom') {\r\n console.warn('[cxkit] refreshStrategy is \"custom\" but no before-refresh handler prevented default. Falling back to auto.')\r\n if (context.isEmbedded) {\r\n reloadTopWindow()\r\n } else {\r\n reloadSelf(context.buildId)\r\n }\r\n return\r\n }\r\n\r\n if (context.strategy === 'top') {\r\n reloadTopWindow()\r\n return\r\n }\r\n\r\n reloadSelf(context.buildId)\r\n}\r\n","const DEFAULT_PREFIX = 'CXKIT_VU_'\r\n\r\nexport function getStorageKey(prefix: string | undefined, name: string): string {\r\n return `${prefix ?? DEFAULT_PREFIX}${name}`\r\n}\r\n\r\nexport function clearPrefixedStorage(prefix: string | undefined): void {\r\n const p = prefix ?? DEFAULT_PREFIX\r\n\r\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\r\n const key = localStorage.key(i)\r\n if (key && key.startsWith(p)) {\r\n localStorage.removeItem(key)\r\n }\r\n }\r\n\r\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\r\n const key = sessionStorage.key(i)\r\n if (key && key.startsWith(p)) {\r\n sessionStorage.removeItem(key)\r\n }\r\n }\r\n}\r\n\r\nexport function persistVersion(prefix: string | undefined, buildId: string): void {\r\n localStorage.setItem(getStorageKey(prefix, 'version'), buildId)\r\n document.cookie = `app_version=${buildId}; path=/; max-age=31536000`\r\n}\r\n\r\nexport function getPersistedVersion(prefix: string | undefined): string | null {\r\n return localStorage.getItem(getStorageKey(prefix, 'version'))\r\n}\r\n\r\nexport function getRemindAt(prefix: string | undefined): number {\r\n return Number(localStorage.getItem(getStorageKey(prefix, 'version_remind_at')) || '0')\r\n}\r\n\r\nexport function setRemindAt(prefix: string | undefined, timestamp: number): void {\r\n if (timestamp > 0) {\r\n localStorage.setItem(getStorageKey(prefix, 'version_remind_at'), String(timestamp))\r\n } else {\r\n localStorage.removeItem(getStorageKey(prefix, 'version_remind_at'))\r\n }\r\n}\r\n\r\nexport function getPendingVersion(prefix: string | undefined): string | null {\r\n return localStorage.getItem(getStorageKey(prefix, 'pending_version'))\r\n}\r\n\r\nexport function setPendingVersion(prefix: string | undefined, buildId: string): void {\r\n localStorage.setItem(getStorageKey(prefix, 'pending_version'), buildId)\r\n}\r\n\r\nexport function removePendingVersion(prefix: string | undefined): void {\r\n localStorage.removeItem(getStorageKey(prefix, 'pending_version'))\r\n}\r\n\r\nexport function getReloadGuard(prefix: string | undefined): string | null {\r\n return sessionStorage.getItem(getStorageKey(prefix, 'reload_guard'))\r\n}\r\n\r\nexport function setReloadGuard(prefix: string | undefined, buildId: string): void {\r\n sessionStorage.setItem(getStorageKey(prefix, 'reload_guard'), buildId)\r\n}\r\n\r\nexport function removeReloadGuard(prefix: string | undefined): void {\r\n sessionStorage.removeItem(getStorageKey(prefix, 'reload_guard'))\r\n}\r\n\r\nexport function getConfirmedVersion(prefix: string | undefined): string | null {\r\n return localStorage.getItem(getStorageKey(prefix, 'confirmed_version'))\r\n}\r\n\r\nexport function setConfirmedVersion(prefix: string | undefined, buildId: string): void {\r\n localStorage.setItem(getStorageKey(prefix, 'confirmed_version'), buildId)\r\n}\r\n\r\nexport function removeConfirmedVersion(prefix: string | undefined): void {\r\n localStorage.removeItem(getStorageKey(prefix, 'confirmed_version'))\r\n}\r\n","import type {\r\n CheckerOptions,\r\n CheckerState,\r\n VersionChecker,\r\n VersionManifest,\r\n VersionRuntimeEnv\r\n} from './types'\r\nimport { EventEmitter } from './events'\r\nimport { resolveRuntimeEnv, fetchVersionManifest } from './fetcher'\r\nimport { buildRefreshContext, executeRefresh } from './refresh'\r\nimport {\r\n clearPrefixedStorage,\r\n persistVersion,\r\n getPersistedVersion,\r\n getRemindAt,\r\n setRemindAt,\r\n getPendingVersion,\r\n setPendingVersion,\r\n removePendingVersion,\r\n getReloadGuard,\r\n setReloadGuard,\r\n removeReloadGuard,\r\n getConfirmedVersion,\r\n setConfirmedVersion,\r\n removeConfirmedVersion\r\n} from './storage'\r\n\r\n// ─── Defaults ───────────────────────────────────────────────────\r\n\r\nconst DEFAULT_POLL_INTERVAL = 5 * 60 * 1000\r\nconst DEFAULT_REMIND_DELAY = 10 * 60 * 1000\r\nconst DEFAULT_VERSION_URL = 'version.json'\r\n\r\n// ─── Factory ────────────────────────────────────────────────────\r\n\r\nexport function createVersionChecker(options: CheckerOptions = {}): VersionChecker {\r\n // ── Resolved options ─────────────────────────────────\r\n\r\n const opts = {\r\n pollInterval: options.pollInterval ?? DEFAULT_POLL_INTERVAL,\r\n enableFocusCheck: options.enableFocusCheck ?? true,\r\n enableVisibilityCheck: options.enableVisibilityCheck ?? true,\r\n versionUrl: options.versionUrl ?? DEFAULT_VERSION_URL,\r\n refreshStrategy: options.refreshStrategy ?? 'auto' as const,\r\n remindDelay: options.remindDelay ?? DEFAULT_REMIND_DELAY,\r\n storagePrefix: options.storagePrefix,\r\n debug: options.debug ?? false,\r\n devMock: options.devMock ?? false,\r\n timeFormatter: options.timeFormatter,\r\n runtimeEnv: { ...(options.runtimeEnv || {}) } as VersionRuntimeEnv\r\n }\r\n\r\n // ── Internal state ───────────────────────────────────\r\n\r\n const state: CheckerState = {\r\n initialized: false,\r\n checking: false,\r\n hasPendingUpdate: false,\r\n latestBuildId: '',\r\n latestVersion: '',\r\n latestBuildTime: '',\r\n remindAt: 0\r\n }\r\n\r\n const emitter = new EventEmitter()\r\n let timerId: number | null = null\r\n let focusHandler: (() => void) | null = null\r\n let visibilityHandler: (() => void) | null = null\r\n\r\n // ── Helpers ──────────────────────────────────────────\r\n\r\n function debugLog(message: string, payload?: unknown): void {\r\n if (!opts.debug) return\r\n if (payload === undefined) {\r\n console.info(`[cxkit] ${message}`)\r\n } else {\r\n console.info(`[cxkit] ${message}`, payload)\r\n }\r\n }\r\n\r\n function getEnv() {\r\n return resolveRuntimeEnv(opts.runtimeEnv, opts.devMock)\r\n }\r\n\r\n function formatBuildTime(buildTime?: string): string {\r\n if (!buildTime) return ''\r\n return opts.timeFormatter ? opts.timeFormatter(buildTime) : buildTime\r\n }\r\n\r\n function emitStateChange(): void {\r\n emitter.emit('state-change', { ...state })\r\n }\r\n\r\n function updateState(patch: Partial<CheckerState>): void {\r\n Object.assign(state, patch)\r\n emitStateChange()\r\n }\r\n\r\n // ── Storage sync ─────────────────────────────────────\r\n\r\n function syncLocalVersion(): void {\r\n const env = getEnv()\r\n if (!env.buildId) {\r\n debugLog('No current buildId, skipping local version sync')\r\n return\r\n }\r\n\r\n // If the confirmed version matches current buildId, the refresh succeeded — clear the marker\r\n const confirmedVersion = getConfirmedVersion(opts.storagePrefix)\r\n if (confirmedVersion && confirmedVersion === env.buildId) {\r\n removeConfirmedVersion(opts.storagePrefix)\r\n debugLog('Confirmed version matches current buildId, refresh was successful', { confirmedVersion })\r\n }\r\n\r\n const oldVersion = getPersistedVersion(opts.storagePrefix)\r\n if (oldVersion === env.buildId) return\r\n\r\n clearPrefixedStorage(opts.storagePrefix)\r\n persistVersion(opts.storagePrefix, env.buildId)\r\n debugLog('Local version switched, cleared old cache', { oldVersion, currentBuildId: env.buildId })\r\n }\r\n\r\n function clearPendingState(): void {\r\n removeReloadGuard(opts.storagePrefix)\r\n removePendingVersion(opts.storagePrefix)\r\n updateState({\r\n hasPendingUpdate: false,\r\n latestBuildId: '',\r\n latestVersion: '',\r\n latestBuildTime: '',\r\n remindAt: 0\r\n })\r\n }\r\n\r\n function updatePendingState(manifest: VersionManifest): void {\r\n updateState({\r\n hasPendingUpdate: true,\r\n latestBuildId: manifest.buildId,\r\n latestVersion: manifest.version || '',\r\n latestBuildTime: formatBuildTime(manifest.buildTime)\r\n })\r\n }\r\n\r\n // ── Version check ────────────────────────────────────\r\n\r\n async function showUpdatePrompt(manifest: VersionManifest, force = false): Promise<void> {\r\n const remindAt = getRemindAt(opts.storagePrefix)\r\n state.remindAt = remindAt\r\n emitStateChange()\r\n\r\n if (!force && Date.now() < remindAt) {\r\n updatePendingState(manifest)\r\n debugLog('Remind cooldown active, keeping indicator only', { remindAt, manifest })\r\n return\r\n }\r\n\r\n updatePendingState(manifest)\r\n setPendingVersion(opts.storagePrefix, manifest.buildId)\r\n debugLog(force ? 'User triggered update panel' : 'Pending update state recorded', manifest)\r\n }\r\n\r\n async function checkVersion(): Promise<void> {\r\n if (state.checking) return\r\n\r\n const env = getEnv()\r\n if (!env.buildId) {\r\n debugLog('No current buildId, skipping version check')\r\n return\r\n }\r\n\r\n updateState({ checking: true })\r\n\r\n try {\r\n const latestManifest = await fetchVersionManifest(opts.versionUrl, env, debugLog)\r\n\r\n if (!latestManifest.buildId || latestManifest.buildId === env.buildId) {\r\n clearPendingState()\r\n debugLog('Remote version matches current, no update needed', latestManifest)\r\n return\r\n }\r\n\r\n // ── Anti-loop guard ─────────────────────────────────\r\n // If the user already confirmed this exact buildId (clicked \"立即更新\"),\r\n // but the browser served cached JS so __APP_BUILD_ID__ is still old,\r\n // do NOT show the popup again — the user has already acted on it.\r\n const confirmedVersion = getConfirmedVersion(opts.storagePrefix)\r\n if (confirmedVersion === latestManifest.buildId) {\r\n debugLog('This buildId was already confirmed by user, suppressing popup to avoid loop', {\r\n confirmedVersion,\r\n currentBuildId: env.buildId\r\n })\r\n return\r\n }\r\n\r\n const reloadGuard = getReloadGuard(opts.storagePrefix)\r\n updatePendingState(latestManifest)\r\n\r\n if (reloadGuard === latestManifest.buildId) {\r\n const pendingVersion = getPendingVersion(opts.storagePrefix)\r\n if (pendingVersion === latestManifest.buildId) {\r\n await showUpdatePrompt(latestManifest)\r\n }\r\n return\r\n }\r\n\r\n setReloadGuard(opts.storagePrefix, latestManifest.buildId)\r\n emitter.emit('update-detected', latestManifest)\r\n await showUpdatePrompt(latestManifest)\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error))\r\n console.error('[cxkit] Version check failed', err)\r\n emitter.emit('error', err)\r\n } finally {\r\n updateState({ checking: false })\r\n }\r\n }\r\n\r\n // ── Lifecycle ────────────────────────────────────────\r\n\r\n function bindLifecycle(): void {\r\n if (opts.enableFocusCheck) {\r\n focusHandler = () => void checkVersion()\r\n window.addEventListener('focus', focusHandler)\r\n }\r\n\r\n if (opts.enableVisibilityCheck) {\r\n visibilityHandler = () => {\r\n if (document.visibilityState === 'visible') {\r\n void checkVersion()\r\n }\r\n }\r\n document.addEventListener('visibilitychange', visibilityHandler)\r\n }\r\n\r\n if (opts.pollInterval > 0) {\r\n timerId = window.setInterval(() => void checkVersion(), opts.pollInterval)\r\n }\r\n }\r\n\r\n function clearLifecycle(): void {\r\n if (focusHandler) {\r\n window.removeEventListener('focus', focusHandler)\r\n focusHandler = null\r\n }\r\n if (visibilityHandler) {\r\n document.removeEventListener('visibilitychange', visibilityHandler)\r\n visibilityHandler = null\r\n }\r\n if (timerId !== null) {\r\n window.clearInterval(timerId)\r\n timerId = null\r\n }\r\n }\r\n\r\n // ── Public API ───────────────────────────────────────\r\n\r\n const checker: VersionChecker = {\r\n start() {\r\n if (state.initialized) {\r\n debugLog('Already initialized, ignoring duplicate start()')\r\n return\r\n }\r\n\r\n updateState({ initialized: true })\r\n\r\n debugLog('Version checker started', {\r\n pollInterval: opts.pollInterval,\r\n remindDelay: opts.remindDelay,\r\n enableFocusCheck: opts.enableFocusCheck,\r\n enableVisibilityCheck: opts.enableVisibilityCheck,\r\n refreshStrategy: opts.refreshStrategy,\r\n versionUrl: opts.versionUrl,\r\n storagePrefix: opts.storagePrefix,\r\n runtimeEnv: getEnv(),\r\n devMock: opts.devMock\r\n })\r\n\r\n syncLocalVersion()\r\n void checkVersion()\r\n bindLifecycle()\r\n },\r\n\r\n stop() {\r\n clearLifecycle()\r\n debugLog('Version checker stopped')\r\n },\r\n\r\n destroy() {\r\n clearLifecycle()\r\n updateState({ initialized: false, checking: false })\r\n emitter.removeAll()\r\n debugLog('Version checker destroyed')\r\n },\r\n\r\n async check() {\r\n await checkVersion()\r\n },\r\n\r\n async confirm() {\r\n if (!state.hasPendingUpdate || !state.latestBuildId) return\r\n\r\n const manifest: VersionManifest = {\r\n buildId: state.latestBuildId,\r\n version: state.latestVersion || undefined,\r\n buildTime: state.latestBuildTime || undefined\r\n }\r\n\r\n emitter.emit('update-confirmed', manifest)\r\n\r\n // Persist confirmed buildId BEFORE refreshing so the checker\r\n // won't re-show the popup if the browser serves cached JS after reload\r\n setConfirmedVersion(opts.storagePrefix, state.latestBuildId)\r\n\r\n const context = buildRefreshContext(\r\n state.latestBuildId,\r\n state.latestVersion,\r\n state.latestBuildTime || undefined,\r\n opts.refreshStrategy\r\n )\r\n\r\n clearPendingState()\r\n\r\n emitter.emit('before-refresh', context)\r\n executeRefresh(context, opts.devMock, debugLog)\r\n },\r\n\r\n defer(duration?: number) {\r\n if (!state.hasPendingUpdate || !state.latestBuildId) return\r\n\r\n const d = duration ?? opts.remindDelay\r\n const remindAt = d > 0 ? Date.now() + d : 0\r\n setRemindAt(opts.storagePrefix, remindAt)\r\n updateState({ remindAt })\r\n\r\n const manifest: VersionManifest = {\r\n buildId: state.latestBuildId,\r\n version: state.latestVersion || undefined,\r\n buildTime: state.latestBuildTime || undefined\r\n }\r\n\r\n emitter.emit('update-deferred', { manifest, remindAt })\r\n },\r\n\r\n getState() {\r\n return { ...state }\r\n },\r\n\r\n on(event, handler) {\r\n return emitter.on(event, handler)\r\n },\r\n\r\n off(event, handler) {\r\n emitter.off(event, handler)\r\n },\r\n\r\n setRuntimeEnv(env) {\r\n Object.assign(opts.runtimeEnv, env)\r\n }\r\n }\r\n\r\n return checker\r\n}\r\n"],"mappings":";AAQO,IAAM,eAAN,MAAmB;AAAA,EAChB,YAAY,oBAAI,IAA0B;AAAA,EAElD,GAAoC,OAAU,SAAkD;AAC9F,QAAI,CAAC,KAAK,UAAU,IAAI,KAAK,GAAG;AAC9B,WAAK,UAAU,IAAI,OAAO,oBAAI,IAAI,CAAC;AAAA,IACrC;AACA,SAAK,UAAU,IAAI,KAAK,EAAG,IAAI,OAAkB;AACjD,WAAO,MAAM,KAAK,IAAI,OAAO,OAAO;AAAA,EACtC;AAAA,EAEA,IAAqC,OAAU,SAA4C;AACzF,SAAK,UAAU,IAAI,KAAK,GAAG,OAAO,OAAkB;AAAA,EACtD;AAAA,EAEA,KAAsC,OAAU,SAAmC;AACjF,SAAK,UAAU,IAAI,KAAK,GAAG,QAAQ,CAAC,YAAY;AAC9C,UAAI;AACF,gBAAQ,OAAO;AAAA,MACjB,SAAS,KAAK;AACZ,gBAAQ,MAAM,qBAAqB,KAAK,cAAc,GAAG;AAAA,MAC3D;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,YAAkB;AAChB,SAAK,UAAU,MAAM;AAAA,EACvB;AACF;;;AClCA,IAAM,qBAAqB;AAEpB,SAAS,mBAA4B;AAC1C,SAAO,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAAE,IAAI,kBAAkB,MAAM;AACjF;AAEO,SAAS,iBACd,MACQ;AACR,QAAM,QAAS,WAAuC,IAAI;AAC1D,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEO,SAAS,kBACd,aACA,SAC6B;AAC7B,QAAM,oBAAoB;AAC1B,QAAM,iBAAiB,WAAW,iBAAiB;AAEnD,SAAO;AAAA,IACL,SAAS,YAAY,WAAW,iBAAiB,iBAAiB;AAAA,IAClE,SAAS,iBACL,oBACA,YAAY,WAAW,iBAAiB,kBAAkB;AAAA,IAC9D,WAAW,YAAY,aAAa,iBAAiB,oBAAoB;AAAA,IACzE,SAAS,YAAY,WAAW,iBAAiB,kBAAkB;AAAA,EACrE;AACF;AAEO,SAAS,wBAAgC;AAC9C,QAAM,gBAAiB,OAAe,QAAQ;AAC9C,MAAI,iBAAiB,OAAO,cAAc,SAAS,UAAU;AAC3D,WAAO,cAAc;AAAA,EACvB;AACA,SAAO,OAAO,SAAS;AACzB;AAEO,SAAS,wBACd,YACA,KACQ;AACR,QAAMA,uBAAsB;AAC5B,QAAM,mBAAmB,OAAO,eAAe,aAAa,WAAW,IAAI;AAC3E,QAAM,cAAc,oBAAoBA;AACxC,QAAM,UAAU,IAAI;AACpB,QAAM,cAAc,UAChB,IAAI,IAAI,QAAQ,SAAS,GAAG,IAAI,UAAU,GAAG,OAAO,KAAK,sBAAsB,CAAC,IAChF,IAAI,IAAI,sBAAsB,CAAC;AACnC,QAAM,MAAM,IAAI,IAAI,aAAa,YAAY,SAAS,CAAC;AACvD,MAAI,aAAa,IAAI,KAAK,KAAK,IAAI,EAAE,SAAS,CAAC;AAC/C,SAAO,IAAI,SAAS;AACtB;AAEA,eAAsB,qBACpB,YACA,KACA,UAC0B;AAC1B,QAAM,aAAa,wBAAwB,YAAY,GAAG;AAC1D,WAAS,+BAA+B,EAAE,WAAW,CAAC;AAEtD,QAAM,WAAW,MAAM,MAAM,YAAY,EAAE,OAAO,WAAW,CAAC;AAE9D,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,oCAAoC,SAAS,MAAM,EAAE;AAAA,EACvE;AAEA,QAAM,WAAY,MAAM,SAAS,KAAK;AACtC,WAAS,6BAA6B,QAAQ;AAC9C,SAAO;AACT;;;ACtEA,IAAM,wBAAwB;AAE9B,SAAS,aAAsB;AAC7B,SAAO,QAAS,OAAe,MAAM;AACvC;AAEO,SAAS,uBAAuB,UAA2B,UAAqD;AACrH,MAAI,aAAa,QAAQ;AACvB,WAAO,WAAW,QAAQ;AAAA,EAC5B;AACA,SAAO;AACT;AAEA,SAAS,WAAW,SAAuB;AACzC,QAAM,aAAa,IAAI,IAAI,OAAO,SAAS,IAAI;AAC/C,QAAM,iBAAiB,WAAW,aAAa,IAAI,qBAAqB;AAExE,MAAI,mBAAmB,SAAS;AAC9B,eAAW,aAAa,IAAI,uBAAuB,OAAO;AAC1D,WAAO,SAAS,QAAQ,WAAW,SAAS,CAAC;AAC7C;AAAA,EACF;AAEA,SAAO,SAAS,OAAO;AACzB;AAEA,SAAS,kBAAwB;AAC/B,MAAI;AACF,QAAI,OAAO,OAAO,OAAO,QAAQ,QAAQ;AACvC,aAAO,IAAI,SAAS,OAAO;AAC3B;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,KAAK,oEAAoE,KAAK;AAAA,EACxF;AAEA,SAAO,SAAS,OAAO;AACzB;AAEO,SAAS,oBACd,SACA,SACA,WACA,UACgB;AAChB,QAAM,WAAW,WAAW;AAC5B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,UAAU,uBAAuB,UAAU,QAAQ;AAAA,EACrD;AACF;AAEO,SAAS,eACd,SACA,SACA,UACM;AACN,MAAI,WAAW,iBAAiB,GAAG;AACjC,aAAS,2CAA2C,EAAE,SAAS,QAAQ,QAAQ,CAAC;AAChF;AAAA,EACF;AAEA,MAAI,QAAQ,aAAa,UAAU;AACjC,YAAQ,KAAK,4GAA4G;AACzH,QAAI,QAAQ,YAAY;AACtB,sBAAgB;AAAA,IAClB,OAAO;AACL,iBAAW,QAAQ,OAAO;AAAA,IAC5B;AACA;AAAA,EACF;AAEA,MAAI,QAAQ,aAAa,OAAO;AAC9B,oBAAgB;AAChB;AAAA,EACF;AAEA,aAAW,QAAQ,OAAO;AAC5B;;;ACpFA,IAAM,iBAAiB;AAEhB,SAAS,cAAc,QAA4B,MAAsB;AAC9E,SAAO,GAAG,UAAU,cAAc,GAAG,IAAI;AAC3C;AAEO,SAAS,qBAAqB,QAAkC;AACrE,QAAM,IAAI,UAAU;AAEpB,WAAS,IAAI,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;AACpD,UAAM,MAAM,aAAa,IAAI,CAAC;AAC9B,QAAI,OAAO,IAAI,WAAW,CAAC,GAAG;AAC5B,mBAAa,WAAW,GAAG;AAAA,IAC7B;AAAA,EACF;AAEA,WAAS,IAAI,eAAe,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;AACtD,UAAM,MAAM,eAAe,IAAI,CAAC;AAChC,QAAI,OAAO,IAAI,WAAW,CAAC,GAAG;AAC5B,qBAAe,WAAW,GAAG;AAAA,IAC/B;AAAA,EACF;AACF;AAEO,SAAS,eAAe,QAA4B,SAAuB;AAChF,eAAa,QAAQ,cAAc,QAAQ,SAAS,GAAG,OAAO;AAC9D,WAAS,SAAS,eAAe,OAAO;AAC1C;AAEO,SAAS,oBAAoB,QAA2C;AAC7E,SAAO,aAAa,QAAQ,cAAc,QAAQ,SAAS,CAAC;AAC9D;AAEO,SAAS,YAAY,QAAoC;AAC9D,SAAO,OAAO,aAAa,QAAQ,cAAc,QAAQ,mBAAmB,CAAC,KAAK,GAAG;AACvF;AAEO,SAAS,YAAY,QAA4B,WAAyB;AAC/E,MAAI,YAAY,GAAG;AACjB,iBAAa,QAAQ,cAAc,QAAQ,mBAAmB,GAAG,OAAO,SAAS,CAAC;AAAA,EACpF,OAAO;AACL,iBAAa,WAAW,cAAc,QAAQ,mBAAmB,CAAC;AAAA,EACpE;AACF;AAEO,SAAS,kBAAkB,QAA2C;AAC3E,SAAO,aAAa,QAAQ,cAAc,QAAQ,iBAAiB,CAAC;AACtE;AAEO,SAAS,kBAAkB,QAA4B,SAAuB;AACnF,eAAa,QAAQ,cAAc,QAAQ,iBAAiB,GAAG,OAAO;AACxE;AAEO,SAAS,qBAAqB,QAAkC;AACrE,eAAa,WAAW,cAAc,QAAQ,iBAAiB,CAAC;AAClE;AAEO,SAAS,eAAe,QAA2C;AACxE,SAAO,eAAe,QAAQ,cAAc,QAAQ,cAAc,CAAC;AACrE;AAEO,SAAS,eAAe,QAA4B,SAAuB;AAChF,iBAAe,QAAQ,cAAc,QAAQ,cAAc,GAAG,OAAO;AACvE;AAEO,SAAS,kBAAkB,QAAkC;AAClE,iBAAe,WAAW,cAAc,QAAQ,cAAc,CAAC;AACjE;AAEO,SAAS,oBAAoB,QAA2C;AAC7E,SAAO,aAAa,QAAQ,cAAc,QAAQ,mBAAmB,CAAC;AACxE;AAEO,SAAS,oBAAoB,QAA4B,SAAuB;AACrF,eAAa,QAAQ,cAAc,QAAQ,mBAAmB,GAAG,OAAO;AAC1E;AAEO,SAAS,uBAAuB,QAAkC;AACvE,eAAa,WAAW,cAAc,QAAQ,mBAAmB,CAAC;AACpE;;;AClDA,IAAM,wBAAwB,IAAI,KAAK;AACvC,IAAM,uBAAuB,KAAK,KAAK;AACvC,IAAM,sBAAsB;AAIrB,SAAS,qBAAqB,UAA0B,CAAC,GAAmB;AAGjF,QAAM,OAAO;AAAA,IACX,cAAc,QAAQ,gBAAgB;AAAA,IACtC,kBAAkB,QAAQ,oBAAoB;AAAA,IAC9C,uBAAuB,QAAQ,yBAAyB;AAAA,IACxD,YAAY,QAAQ,cAAc;AAAA,IAClC,iBAAiB,QAAQ,mBAAmB;AAAA,IAC5C,aAAa,QAAQ,eAAe;AAAA,IACpC,eAAe,QAAQ;AAAA,IACvB,OAAO,QAAQ,SAAS;AAAA,IACxB,SAAS,QAAQ,WAAW;AAAA,IAC5B,eAAe,QAAQ;AAAA,IACvB,YAAY,EAAE,GAAI,QAAQ,cAAc,CAAC,EAAG;AAAA,EAC9C;AAIA,QAAM,QAAsB;AAAA,IAC1B,aAAa;AAAA,IACb,UAAU;AAAA,IACV,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,UAAU;AAAA,EACZ;AAEA,QAAM,UAAU,IAAI,aAAa;AACjC,MAAI,UAAyB;AAC7B,MAAI,eAAoC;AACxC,MAAI,oBAAyC;AAI7C,WAAS,SAAS,SAAiB,SAAyB;AAC1D,QAAI,CAAC,KAAK,MAAO;AACjB,QAAI,YAAY,QAAW;AACzB,cAAQ,KAAK,WAAW,OAAO,EAAE;AAAA,IACnC,OAAO;AACL,cAAQ,KAAK,WAAW,OAAO,IAAI,OAAO;AAAA,IAC5C;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,WAAO,kBAAkB,KAAK,YAAY,KAAK,OAAO;AAAA,EACxD;AAEA,WAAS,gBAAgB,WAA4B;AACnD,QAAI,CAAC,UAAW,QAAO;AACvB,WAAO,KAAK,gBAAgB,KAAK,cAAc,SAAS,IAAI;AAAA,EAC9D;AAEA,WAAS,kBAAwB;AAC/B,YAAQ,KAAK,gBAAgB,EAAE,GAAG,MAAM,CAAC;AAAA,EAC3C;AAEA,WAAS,YAAY,OAAoC;AACvD,WAAO,OAAO,OAAO,KAAK;AAC1B,oBAAgB;AAAA,EAClB;AAIA,WAAS,mBAAyB;AAChC,UAAM,MAAM,OAAO;AACnB,QAAI,CAAC,IAAI,SAAS;AAChB,eAAS,iDAAiD;AAC1D;AAAA,IACF;AAGA,UAAM,mBAAmB,oBAAoB,KAAK,aAAa;AAC/D,QAAI,oBAAoB,qBAAqB,IAAI,SAAS;AACxD,6BAAuB,KAAK,aAAa;AACzC,eAAS,qEAAqE,EAAE,iBAAiB,CAAC;AAAA,IACpG;AAEA,UAAM,aAAa,oBAAoB,KAAK,aAAa;AACzD,QAAI,eAAe,IAAI,QAAS;AAEhC,yBAAqB,KAAK,aAAa;AACvC,mBAAe,KAAK,eAAe,IAAI,OAAO;AAC9C,aAAS,6CAA6C,EAAE,YAAY,gBAAgB,IAAI,QAAQ,CAAC;AAAA,EACnG;AAEA,WAAS,oBAA0B;AACjC,sBAAkB,KAAK,aAAa;AACpC,yBAAqB,KAAK,aAAa;AACvC,gBAAY;AAAA,MACV,kBAAkB;AAAA,MAClB,eAAe;AAAA,MACf,eAAe;AAAA,MACf,iBAAiB;AAAA,MACjB,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,WAAS,mBAAmB,UAAiC;AAC3D,gBAAY;AAAA,MACV,kBAAkB;AAAA,MAClB,eAAe,SAAS;AAAA,MACxB,eAAe,SAAS,WAAW;AAAA,MACnC,iBAAiB,gBAAgB,SAAS,SAAS;AAAA,IACrD,CAAC;AAAA,EACH;AAIA,iBAAe,iBAAiB,UAA2B,QAAQ,OAAsB;AACvF,UAAM,WAAW,YAAY,KAAK,aAAa;AAC/C,UAAM,WAAW;AACjB,oBAAgB;AAEhB,QAAI,CAAC,SAAS,KAAK,IAAI,IAAI,UAAU;AACnC,yBAAmB,QAAQ;AAC3B,eAAS,kDAAkD,EAAE,UAAU,SAAS,CAAC;AACjF;AAAA,IACF;AAEA,uBAAmB,QAAQ;AAC3B,sBAAkB,KAAK,eAAe,SAAS,OAAO;AACtD,aAAS,QAAQ,gCAAgC,iCAAiC,QAAQ;AAAA,EAC5F;AAEA,iBAAe,eAA8B;AAC3C,QAAI,MAAM,SAAU;AAEpB,UAAM,MAAM,OAAO;AACnB,QAAI,CAAC,IAAI,SAAS;AAChB,eAAS,4CAA4C;AACrD;AAAA,IACF;AAEA,gBAAY,EAAE,UAAU,KAAK,CAAC;AAE9B,QAAI;AACF,YAAM,iBAAiB,MAAM,qBAAqB,KAAK,YAAY,KAAK,QAAQ;AAEhF,UAAI,CAAC,eAAe,WAAW,eAAe,YAAY,IAAI,SAAS;AACrE,0BAAkB;AAClB,iBAAS,oDAAoD,cAAc;AAC3E;AAAA,MACF;AAMA,YAAM,mBAAmB,oBAAoB,KAAK,aAAa;AAC/D,UAAI,qBAAqB,eAAe,SAAS;AAC/C,iBAAS,+EAA+E;AAAA,UACtF;AAAA,UACA,gBAAgB,IAAI;AAAA,QACtB,CAAC;AACD;AAAA,MACF;AAEA,YAAM,cAAc,eAAe,KAAK,aAAa;AACrD,yBAAmB,cAAc;AAEjC,UAAI,gBAAgB,eAAe,SAAS;AAC1C,cAAM,iBAAiB,kBAAkB,KAAK,aAAa;AAC3D,YAAI,mBAAmB,eAAe,SAAS;AAC7C,gBAAM,iBAAiB,cAAc;AAAA,QACvC;AACA;AAAA,MACF;AAEA,qBAAe,KAAK,eAAe,eAAe,OAAO;AACzD,cAAQ,KAAK,mBAAmB,cAAc;AAC9C,YAAM,iBAAiB,cAAc;AAAA,IACvC,SAAS,OAAO;AACd,YAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACpE,cAAQ,MAAM,gCAAgC,GAAG;AACjD,cAAQ,KAAK,SAAS,GAAG;AAAA,IAC3B,UAAE;AACA,kBAAY,EAAE,UAAU,MAAM,CAAC;AAAA,IACjC;AAAA,EACF;AAIA,WAAS,gBAAsB;AAC7B,QAAI,KAAK,kBAAkB;AACzB,qBAAe,MAAM,KAAK,aAAa;AACvC,aAAO,iBAAiB,SAAS,YAAY;AAAA,IAC/C;AAEA,QAAI,KAAK,uBAAuB;AAC9B,0BAAoB,MAAM;AACxB,YAAI,SAAS,oBAAoB,WAAW;AAC1C,eAAK,aAAa;AAAA,QACpB;AAAA,MACF;AACA,eAAS,iBAAiB,oBAAoB,iBAAiB;AAAA,IACjE;AAEA,QAAI,KAAK,eAAe,GAAG;AACzB,gBAAU,OAAO,YAAY,MAAM,KAAK,aAAa,GAAG,KAAK,YAAY;AAAA,IAC3E;AAAA,EACF;AAEA,WAAS,iBAAuB;AAC9B,QAAI,cAAc;AAChB,aAAO,oBAAoB,SAAS,YAAY;AAChD,qBAAe;AAAA,IACjB;AACA,QAAI,mBAAmB;AACrB,eAAS,oBAAoB,oBAAoB,iBAAiB;AAClE,0BAAoB;AAAA,IACtB;AACA,QAAI,YAAY,MAAM;AACpB,aAAO,cAAc,OAAO;AAC5B,gBAAU;AAAA,IACZ;AAAA,EACF;AAIA,QAAM,UAA0B;AAAA,IAC9B,QAAQ;AACN,UAAI,MAAM,aAAa;AACrB,iBAAS,iDAAiD;AAC1D;AAAA,MACF;AAEA,kBAAY,EAAE,aAAa,KAAK,CAAC;AAEjC,eAAS,2BAA2B;AAAA,QAClC,cAAc,KAAK;AAAA,QACnB,aAAa,KAAK;AAAA,QAClB,kBAAkB,KAAK;AAAA,QACvB,uBAAuB,KAAK;AAAA,QAC5B,iBAAiB,KAAK;AAAA,QACtB,YAAY,KAAK;AAAA,QACjB,eAAe,KAAK;AAAA,QACpB,YAAY,OAAO;AAAA,QACnB,SAAS,KAAK;AAAA,MAChB,CAAC;AAED,uBAAiB;AACjB,WAAK,aAAa;AAClB,oBAAc;AAAA,IAChB;AAAA,IAEA,OAAO;AACL,qBAAe;AACf,eAAS,yBAAyB;AAAA,IACpC;AAAA,IAEA,UAAU;AACR,qBAAe;AACf,kBAAY,EAAE,aAAa,OAAO,UAAU,MAAM,CAAC;AACnD,cAAQ,UAAU;AAClB,eAAS,2BAA2B;AAAA,IACtC;AAAA,IAEA,MAAM,QAAQ;AACZ,YAAM,aAAa;AAAA,IACrB;AAAA,IAEA,MAAM,UAAU;AACd,UAAI,CAAC,MAAM,oBAAoB,CAAC,MAAM,cAAe;AAErD,YAAM,WAA4B;AAAA,QAChC,SAAS,MAAM;AAAA,QACf,SAAS,MAAM,iBAAiB;AAAA,QAChC,WAAW,MAAM,mBAAmB;AAAA,MACtC;AAEA,cAAQ,KAAK,oBAAoB,QAAQ;AAIzC,0BAAoB,KAAK,eAAe,MAAM,aAAa;AAE3D,YAAM,UAAU;AAAA,QACd,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM,mBAAmB;AAAA,QACzB,KAAK;AAAA,MACP;AAEA,wBAAkB;AAElB,cAAQ,KAAK,kBAAkB,OAAO;AACtC,qBAAe,SAAS,KAAK,SAAS,QAAQ;AAAA,IAChD;AAAA,IAEA,MAAM,UAAmB;AACvB,UAAI,CAAC,MAAM,oBAAoB,CAAC,MAAM,cAAe;AAErD,YAAM,IAAI,YAAY,KAAK;AAC3B,YAAM,WAAW,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAC1C,kBAAY,KAAK,eAAe,QAAQ;AACxC,kBAAY,EAAE,SAAS,CAAC;AAExB,YAAM,WAA4B;AAAA,QAChC,SAAS,MAAM;AAAA,QACf,SAAS,MAAM,iBAAiB;AAAA,QAChC,WAAW,MAAM,mBAAmB;AAAA,MACtC;AAEA,cAAQ,KAAK,mBAAmB,EAAE,UAAU,SAAS,CAAC;AAAA,IACxD;AAAA,IAEA,WAAW;AACT,aAAO,EAAE,GAAG,MAAM;AAAA,IACpB;AAAA,IAEA,GAAG,OAAO,SAAS;AACjB,aAAO,QAAQ,GAAG,OAAO,OAAO;AAAA,IAClC;AAAA,IAEA,IAAI,OAAO,SAAS;AAClB,cAAQ,IAAI,OAAO,OAAO;AAAA,IAC5B;AAAA,IAEA,cAAc,KAAK;AACjB,aAAO,OAAO,KAAK,YAAY,GAAG;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AACT;","names":["DEFAULT_VERSION_URL"]} |
+1
-1
| { | ||
| "name": "@cxkit/version-core", | ||
| "version": "0.0.5", | ||
| "version": "0.0.6", | ||
| "description": "Framework-agnostic runtime core for frontend version update detection and notification.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
106562
7.14%1032
4.67%