@humanfirst-chat/js 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -182,6 +182,7 @@ var HFChat = new Proxy(
|
|
|
182
182
|
if (typeof window === "undefined") return () => {
|
|
183
183
|
};
|
|
184
184
|
if (prop === "__HFCHAT_INSTANCE__") return void 0;
|
|
185
|
+
if (prop === "then") return void 0;
|
|
185
186
|
if (prop === "ready") {
|
|
186
187
|
const api = getRealApi(HFChat);
|
|
187
188
|
return !!api?.ready;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Re-export public types for consumers\nexport type {\n HFChatLogLevel,\n HFChatConfig,\n HFChatWidgetSettings,\n HFChatIdentifyMeta,\n HFChatOpenOptions,\n HFChatAPI,\n} from './types'\n\nimport type { HFChatConfig, HFChatAPI, HFChatLogLevel } from './types'\n\n// Extended config for the JS SDK loader (adds scriptSrc option)\nexport type HFChatLoaderConfig = HFChatConfig & {\n /** Override widget script source (for self-hosting / testing) */\n scriptSrc?: string\n}\n\nexport type HFChatGlobal = HFChatAPI & {\n /**\n * Load the widget script and initialize the widget.\n */\n init(opts?: HFChatLoaderConfig): Promise<HFChatAPI>\n}\n\ndeclare global {\n interface Window {\n HFChat?: HFChatAPI\n HumanFirstChat?: {\n init: (opts: unknown) => HFChatAPI\n }\n __HFCHAT_DISABLE_AUTO_INIT?: boolean\n }\n}\n\nconst DEFAULT_SCRIPT_SRC = 'https://humanfirst.chat/widget.js'\nconst SCRIPT_DATA_ATTR = 'data-hfchat-widget'\n\n// Logging configuration\nlet logLevel: HFChatLogLevel = 'none'\n\nfunction log(message: string, ...args: unknown[]) {\n if (logLevel === 'none') return\n console.log(`[HFChat SDK] ${message}`, ...args)\n}\n\nfunction logFull(message: string, ...args: unknown[]) {\n if (logLevel !== 'full') return\n console.log(`[HFChat SDK] ${message}`, ...args)\n}\n\nfunction logError(message: string, ...args: unknown[]) {\n if (logLevel === 'none') return\n console.error(`[HFChat SDK] ${message}`, ...args)\n}\n\nlet loaderPromise: Promise<HFChatAPI> | null = null\nlet lastInitOpts: HFChatLoaderConfig | undefined\n\nfunction getRealApi(selfProxy: HFChatGlobal): HFChatAPI | null {\n if (typeof window === 'undefined') return null\n const candidate = window.HFChat\n if (!candidate) return null\n // Check if candidate is the proxy (same reference) - if so, real API not yet available\n if (candidate === selfProxy) return null\n // Check if candidate has the real instance marker\n if ((candidate as any).__HFCHAT_INSTANCE__ === true) return candidate\n return null\n}\n\nfunction injectScript(src: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof document === 'undefined') return resolve()\n if (window.HumanFirstChat) {\n logFull('HumanFirstChat already exists, skipping script injection')\n return resolve()\n }\n\n const existing = document.querySelector(\n `script[${SCRIPT_DATA_ATTR}=\"1\"]`\n ) as HTMLScriptElement | null\n if (existing) {\n logFull('Widget script already in DOM, waiting for load')\n existing.addEventListener('load', () => resolve(), { once: true })\n existing.addEventListener(\n 'error',\n () => reject(new Error('Failed to load widget script')),\n { once: true }\n )\n return\n }\n\n log('Injecting widget script:', src)\n window.__HFCHAT_DISABLE_AUTO_INIT = true\n const script = document.createElement('script')\n script.async = true\n script.src = src\n script.setAttribute(SCRIPT_DATA_ATTR, '1')\n script.setAttribute('data-auto-init', 'false')\n script.onerror = () => {\n logError('Failed to load widget script:', src)\n reject(new Error(`Failed to load widget script: ${src}`))\n }\n script.onload = () => {\n setTimeout(() => {\n if (window.HumanFirstChat) {\n log('Widget script loaded successfully')\n resolve()\n } else {\n logError('Widget script loaded but HumanFirstChat not found')\n reject(new Error('Widget did not attach to window.HumanFirstChat'))\n }\n }, 0)\n }\n document.head.appendChild(script)\n })\n}\n\nasync function loadWidget(opts: HFChatLoaderConfig = {}): Promise<HFChatAPI> {\n if (typeof window === 'undefined') return {} as HFChatAPI\n\n const scriptSrc = opts.scriptSrc ?? DEFAULT_SCRIPT_SRC\n logFull('loadWidget starting with options:', { siteId: opts.siteId, scriptSrc })\n\n await injectScript(scriptSrc)\n\n if (!window.HumanFirstChat?.init) {\n throw new Error('HumanFirstChat.init is not available after script load')\n }\n\n log('Calling HumanFirstChat.init()')\n const api = window.HumanFirstChat.init({\n siteId: opts.siteId,\n hidden: opts.hidden,\n hideOnClose: opts.hideOnClose,\n logs: opts.logs,\n baseURL: opts.baseURL,\n host: opts.host,\n })\n\n logFull('HumanFirstChat.init() returned:', { hasInstance: (api as any)?.__HFCHAT_INSTANCE__ })\n return api\n}\n\nasync function init(opts: HFChatLoaderConfig = {}): Promise<HFChatAPI> {\n // Update log level from options\n if (opts.logs) {\n logLevel = opts.logs\n }\n\n lastInitOpts = { ...lastInitOpts, ...opts }\n log('init() called with options:', { siteId: opts.siteId, logs: opts.logs })\n\n const existingApi = getRealApi(HFChat)\n if (existingApi) {\n log('Returning existing real API')\n return existingApi\n }\n\n if (loaderPromise) {\n logFull('Returning existing loader promise')\n return loaderPromise\n }\n\n log('Starting widget load...')\n loaderPromise = loadWidget(lastInitOpts)\n return loaderPromise\n}\n\nasync function waitForMethod(methodName: string): Promise<HFChatAPI> {\n logFull(`waitForMethod('${methodName}') starting...`)\n\n // Ensure init is called (may already be in progress)\n await init()\n logFull(`init() completed, checking for '${methodName}'`)\n\n // Check if real API is already available\n const existing = getRealApi(HFChat)\n logFull('getRealApi returned:', existing ? 'real API found' : 'null')\n\n if (existing && typeof (existing as any)[methodName] === 'function') {\n log(`Method '${methodName}' available immediately`)\n return existing\n }\n\n // Poll for the real API to become available\n logFull(`Polling for '${methodName}'...`)\n return new Promise((resolve, reject) => {\n let attempts = 0\n const maxAttempts = 50 // 5 seconds total\n\n const checkMethod = () => {\n const api = getRealApi(HFChat)\n const fn = api ? (api as any)[methodName] : null\n\n // Log every 10 attempts (1 second)\n if (attempts % 10 === 0 && attempts > 0) {\n logFull(`Polling attempt ${attempts}/50 for '${methodName}':`, {\n hasApi: !!api,\n hasMethod: !!fn,\n windowHFChat: typeof window.HFChat,\n isProxy: window.HFChat === HFChat\n })\n }\n\n if (api && typeof fn === 'function') {\n log(`Method '${methodName}' found after ${attempts} attempts`)\n resolve(api)\n return\n }\n\n if (attempts < maxAttempts) {\n attempts += 1\n setTimeout(checkMethod, 100)\n return\n }\n\n logError(`Timeout: '${methodName}' not available after 5 seconds`)\n reject(new Error(`HFChat method '${methodName}' not available after 5 seconds`))\n }\n\n setTimeout(checkMethod, 100)\n })\n}\n\nexport const HFChat: HFChatGlobal = new Proxy(\n {},\n {\n get(_target, prop) {\n // Handle init specially - it's the entry point\n if (prop === 'init') return init\n\n // Server-side rendering guard\n if (typeof window === 'undefined') return () => {}\n\n // Handle __HFCHAT_INSTANCE__ check - return undefined so proxy isn't mistaken for real instance\n if (prop === '__HFCHAT_INSTANCE__') return undefined\n\n // Handle ready property\n if (prop === 'ready') {\n const api = getRealApi(HFChat)\n return !!api?.ready\n }\n\n // Handle isOpen method\n if (prop === 'isOpen') {\n return () => {\n const api = getRealApi(HFChat)\n return api?.isOpen?.() ?? false\n }\n }\n\n // For all other methods, queue them until the real API is ready\n return (...args: unknown[]) => {\n const methodName = String(prop)\n logFull(`Proxy: '${methodName}' called, forwarding to waitForMethod`)\n\n waitForMethod(methodName)\n .then((api) => {\n const fn = (api as any)[methodName]\n if (typeof fn === 'function') {\n logFull(`Proxy: executing '${methodName}' on real API`)\n fn.apply(api, args)\n } else {\n logError(`Method '${methodName}' not found on real API`)\n }\n })\n .catch((error) => {\n logError(error instanceof Error ? error.message : String(error))\n })\n }\n },\n }\n) as HFChatGlobal\n\nif (typeof window !== 'undefined') {\n // Expose a stable global singleton, without breaking when the real widget assigns window.HFChat\n if (!window.HFChat) {\n window.HFChat = HFChat\n }\n}\n\nexport default HFChat\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Re-export public types for consumers\nexport type {\n HFChatLogLevel,\n HFChatConfig,\n HFChatWidgetSettings,\n HFChatIdentifyMeta,\n HFChatOpenOptions,\n HFChatAPI,\n} from './types'\n\nimport type { HFChatConfig, HFChatAPI, HFChatLogLevel } from './types'\n\n// Extended config for the JS SDK loader (adds scriptSrc option)\nexport type HFChatLoaderConfig = HFChatConfig & {\n /** Override widget script source (for self-hosting / testing) */\n scriptSrc?: string\n}\n\nexport type HFChatGlobal = HFChatAPI & {\n /**\n * Load the widget script and initialize the widget.\n */\n init(opts?: HFChatLoaderConfig): Promise<HFChatAPI>\n}\n\ndeclare global {\n interface Window {\n HFChat?: HFChatAPI\n HumanFirstChat?: {\n init: (opts: unknown) => HFChatAPI\n }\n __HFCHAT_DISABLE_AUTO_INIT?: boolean\n }\n}\n\nconst DEFAULT_SCRIPT_SRC = 'https://humanfirst.chat/widget.js'\nconst SCRIPT_DATA_ATTR = 'data-hfchat-widget'\n\n// Logging configuration\nlet logLevel: HFChatLogLevel = 'none'\n\nfunction log(message: string, ...args: unknown[]) {\n if (logLevel === 'none') return\n console.log(`[HFChat SDK] ${message}`, ...args)\n}\n\nfunction logFull(message: string, ...args: unknown[]) {\n if (logLevel !== 'full') return\n console.log(`[HFChat SDK] ${message}`, ...args)\n}\n\nfunction logError(message: string, ...args: unknown[]) {\n if (logLevel === 'none') return\n console.error(`[HFChat SDK] ${message}`, ...args)\n}\n\nlet loaderPromise: Promise<HFChatAPI> | null = null\nlet lastInitOpts: HFChatLoaderConfig | undefined\n\nfunction getRealApi(selfProxy: HFChatGlobal): HFChatAPI | null {\n if (typeof window === 'undefined') return null\n const candidate = window.HFChat\n if (!candidate) return null\n // Check if candidate is the proxy (same reference) - if so, real API not yet available\n if (candidate === selfProxy) return null\n // Check if candidate has the real instance marker\n if ((candidate as any).__HFCHAT_INSTANCE__ === true) return candidate\n return null\n}\n\nfunction injectScript(src: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof document === 'undefined') return resolve()\n if (window.HumanFirstChat) {\n logFull('HumanFirstChat already exists, skipping script injection')\n return resolve()\n }\n\n const existing = document.querySelector(\n `script[${SCRIPT_DATA_ATTR}=\"1\"]`\n ) as HTMLScriptElement | null\n if (existing) {\n logFull('Widget script already in DOM, waiting for load')\n existing.addEventListener('load', () => resolve(), { once: true })\n existing.addEventListener(\n 'error',\n () => reject(new Error('Failed to load widget script')),\n { once: true }\n )\n return\n }\n\n log('Injecting widget script:', src)\n window.__HFCHAT_DISABLE_AUTO_INIT = true\n const script = document.createElement('script')\n script.async = true\n script.src = src\n script.setAttribute(SCRIPT_DATA_ATTR, '1')\n script.setAttribute('data-auto-init', 'false')\n script.onerror = () => {\n logError('Failed to load widget script:', src)\n reject(new Error(`Failed to load widget script: ${src}`))\n }\n script.onload = () => {\n setTimeout(() => {\n if (window.HumanFirstChat) {\n log('Widget script loaded successfully')\n resolve()\n } else {\n logError('Widget script loaded but HumanFirstChat not found')\n reject(new Error('Widget did not attach to window.HumanFirstChat'))\n }\n }, 0)\n }\n document.head.appendChild(script)\n })\n}\n\nasync function loadWidget(opts: HFChatLoaderConfig = {}): Promise<HFChatAPI> {\n if (typeof window === 'undefined') return {} as HFChatAPI\n\n const scriptSrc = opts.scriptSrc ?? DEFAULT_SCRIPT_SRC\n logFull('loadWidget starting with options:', { siteId: opts.siteId, scriptSrc })\n\n await injectScript(scriptSrc)\n\n if (!window.HumanFirstChat?.init) {\n throw new Error('HumanFirstChat.init is not available after script load')\n }\n\n log('Calling HumanFirstChat.init()')\n const api = window.HumanFirstChat.init({\n siteId: opts.siteId,\n hidden: opts.hidden,\n hideOnClose: opts.hideOnClose,\n logs: opts.logs,\n baseURL: opts.baseURL,\n host: opts.host,\n })\n\n logFull('HumanFirstChat.init() returned:', { hasInstance: (api as any)?.__HFCHAT_INSTANCE__ })\n return api\n}\n\nasync function init(opts: HFChatLoaderConfig = {}): Promise<HFChatAPI> {\n // Update log level from options\n if (opts.logs) {\n logLevel = opts.logs\n }\n\n lastInitOpts = { ...lastInitOpts, ...opts }\n log('init() called with options:', { siteId: opts.siteId, logs: opts.logs })\n\n const existingApi = getRealApi(HFChat)\n if (existingApi) {\n log('Returning existing real API')\n return existingApi\n }\n\n if (loaderPromise) {\n logFull('Returning existing loader promise')\n return loaderPromise\n }\n\n log('Starting widget load...')\n loaderPromise = loadWidget(lastInitOpts)\n return loaderPromise\n}\n\nasync function waitForMethod(methodName: string): Promise<HFChatAPI> {\n logFull(`waitForMethod('${methodName}') starting...`)\n\n // Ensure init is called (may already be in progress)\n await init()\n logFull(`init() completed, checking for '${methodName}'`)\n\n // Check if real API is already available\n const existing = getRealApi(HFChat)\n logFull('getRealApi returned:', existing ? 'real API found' : 'null')\n\n if (existing && typeof (existing as any)[methodName] === 'function') {\n log(`Method '${methodName}' available immediately`)\n return existing\n }\n\n // Poll for the real API to become available\n logFull(`Polling for '${methodName}'...`)\n return new Promise((resolve, reject) => {\n let attempts = 0\n const maxAttempts = 50 // 5 seconds total\n\n const checkMethod = () => {\n const api = getRealApi(HFChat)\n const fn = api ? (api as any)[methodName] : null\n\n // Log every 10 attempts (1 second)\n if (attempts % 10 === 0 && attempts > 0) {\n logFull(`Polling attempt ${attempts}/50 for '${methodName}':`, {\n hasApi: !!api,\n hasMethod: !!fn,\n windowHFChat: typeof window.HFChat,\n isProxy: window.HFChat === HFChat\n })\n }\n\n if (api && typeof fn === 'function') {\n log(`Method '${methodName}' found after ${attempts} attempts`)\n resolve(api)\n return\n }\n\n if (attempts < maxAttempts) {\n attempts += 1\n setTimeout(checkMethod, 100)\n return\n }\n\n logError(`Timeout: '${methodName}' not available after 5 seconds`)\n reject(new Error(`HFChat method '${methodName}' not available after 5 seconds`))\n }\n\n setTimeout(checkMethod, 100)\n })\n}\n\nexport const HFChat: HFChatGlobal = new Proxy(\n {},\n {\n get(_target, prop) {\n // Handle init specially - it's the entry point\n if (prop === 'init') return init\n\n // Server-side rendering guard\n if (typeof window === 'undefined') return () => {}\n\n // Handle __HFCHAT_INSTANCE__ check - return undefined so proxy isn't mistaken for real instance\n if (prop === '__HFCHAT_INSTANCE__') return undefined\n\n // Handle 'then' - return undefined so proxy isn't treated as a thenable/Promise\n // This is critical because await/Promise.resolve() check for .then()\n if (prop === 'then') return undefined\n\n // Handle ready property\n if (prop === 'ready') {\n const api = getRealApi(HFChat)\n return !!api?.ready\n }\n\n // Handle isOpen method\n if (prop === 'isOpen') {\n return () => {\n const api = getRealApi(HFChat)\n return api?.isOpen?.() ?? false\n }\n }\n\n // For all other methods, queue them until the real API is ready\n return (...args: unknown[]) => {\n const methodName = String(prop)\n logFull(`Proxy: '${methodName}' called, forwarding to waitForMethod`)\n\n waitForMethod(methodName)\n .then((api) => {\n const fn = (api as any)[methodName]\n if (typeof fn === 'function') {\n logFull(`Proxy: executing '${methodName}' on real API`)\n fn.apply(api, args)\n } else {\n logError(`Method '${methodName}' not found on real API`)\n }\n })\n .catch((error) => {\n logError(error instanceof Error ? error.message : String(error))\n })\n }\n },\n }\n) as HFChatGlobal\n\nif (typeof window !== 'undefined') {\n // Expose a stable global singleton, without breaking when the real widget assigns window.HFChat\n if (!window.HFChat) {\n window.HFChat = HFChat\n }\n}\n\nexport default HFChat\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -157,6 +157,7 @@ var HFChat = new Proxy(
|
|
|
157
157
|
if (typeof window === "undefined") return () => {
|
|
158
158
|
};
|
|
159
159
|
if (prop === "__HFCHAT_INSTANCE__") return void 0;
|
|
160
|
+
if (prop === "then") return void 0;
|
|
160
161
|
if (prop === "ready") {
|
|
161
162
|
const api = getRealApi(HFChat);
|
|
162
163
|
return !!api?.ready;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Re-export public types for consumers\nexport type {\n HFChatLogLevel,\n HFChatConfig,\n HFChatWidgetSettings,\n HFChatIdentifyMeta,\n HFChatOpenOptions,\n HFChatAPI,\n} from './types'\n\nimport type { HFChatConfig, HFChatAPI, HFChatLogLevel } from './types'\n\n// Extended config for the JS SDK loader (adds scriptSrc option)\nexport type HFChatLoaderConfig = HFChatConfig & {\n /** Override widget script source (for self-hosting / testing) */\n scriptSrc?: string\n}\n\nexport type HFChatGlobal = HFChatAPI & {\n /**\n * Load the widget script and initialize the widget.\n */\n init(opts?: HFChatLoaderConfig): Promise<HFChatAPI>\n}\n\ndeclare global {\n interface Window {\n HFChat?: HFChatAPI\n HumanFirstChat?: {\n init: (opts: unknown) => HFChatAPI\n }\n __HFCHAT_DISABLE_AUTO_INIT?: boolean\n }\n}\n\nconst DEFAULT_SCRIPT_SRC = 'https://humanfirst.chat/widget.js'\nconst SCRIPT_DATA_ATTR = 'data-hfchat-widget'\n\n// Logging configuration\nlet logLevel: HFChatLogLevel = 'none'\n\nfunction log(message: string, ...args: unknown[]) {\n if (logLevel === 'none') return\n console.log(`[HFChat SDK] ${message}`, ...args)\n}\n\nfunction logFull(message: string, ...args: unknown[]) {\n if (logLevel !== 'full') return\n console.log(`[HFChat SDK] ${message}`, ...args)\n}\n\nfunction logError(message: string, ...args: unknown[]) {\n if (logLevel === 'none') return\n console.error(`[HFChat SDK] ${message}`, ...args)\n}\n\nlet loaderPromise: Promise<HFChatAPI> | null = null\nlet lastInitOpts: HFChatLoaderConfig | undefined\n\nfunction getRealApi(selfProxy: HFChatGlobal): HFChatAPI | null {\n if (typeof window === 'undefined') return null\n const candidate = window.HFChat\n if (!candidate) return null\n // Check if candidate is the proxy (same reference) - if so, real API not yet available\n if (candidate === selfProxy) return null\n // Check if candidate has the real instance marker\n if ((candidate as any).__HFCHAT_INSTANCE__ === true) return candidate\n return null\n}\n\nfunction injectScript(src: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof document === 'undefined') return resolve()\n if (window.HumanFirstChat) {\n logFull('HumanFirstChat already exists, skipping script injection')\n return resolve()\n }\n\n const existing = document.querySelector(\n `script[${SCRIPT_DATA_ATTR}=\"1\"]`\n ) as HTMLScriptElement | null\n if (existing) {\n logFull('Widget script already in DOM, waiting for load')\n existing.addEventListener('load', () => resolve(), { once: true })\n existing.addEventListener(\n 'error',\n () => reject(new Error('Failed to load widget script')),\n { once: true }\n )\n return\n }\n\n log('Injecting widget script:', src)\n window.__HFCHAT_DISABLE_AUTO_INIT = true\n const script = document.createElement('script')\n script.async = true\n script.src = src\n script.setAttribute(SCRIPT_DATA_ATTR, '1')\n script.setAttribute('data-auto-init', 'false')\n script.onerror = () => {\n logError('Failed to load widget script:', src)\n reject(new Error(`Failed to load widget script: ${src}`))\n }\n script.onload = () => {\n setTimeout(() => {\n if (window.HumanFirstChat) {\n log('Widget script loaded successfully')\n resolve()\n } else {\n logError('Widget script loaded but HumanFirstChat not found')\n reject(new Error('Widget did not attach to window.HumanFirstChat'))\n }\n }, 0)\n }\n document.head.appendChild(script)\n })\n}\n\nasync function loadWidget(opts: HFChatLoaderConfig = {}): Promise<HFChatAPI> {\n if (typeof window === 'undefined') return {} as HFChatAPI\n\n const scriptSrc = opts.scriptSrc ?? DEFAULT_SCRIPT_SRC\n logFull('loadWidget starting with options:', { siteId: opts.siteId, scriptSrc })\n\n await injectScript(scriptSrc)\n\n if (!window.HumanFirstChat?.init) {\n throw new Error('HumanFirstChat.init is not available after script load')\n }\n\n log('Calling HumanFirstChat.init()')\n const api = window.HumanFirstChat.init({\n siteId: opts.siteId,\n hidden: opts.hidden,\n hideOnClose: opts.hideOnClose,\n logs: opts.logs,\n baseURL: opts.baseURL,\n host: opts.host,\n })\n\n logFull('HumanFirstChat.init() returned:', { hasInstance: (api as any)?.__HFCHAT_INSTANCE__ })\n return api\n}\n\nasync function init(opts: HFChatLoaderConfig = {}): Promise<HFChatAPI> {\n // Update log level from options\n if (opts.logs) {\n logLevel = opts.logs\n }\n\n lastInitOpts = { ...lastInitOpts, ...opts }\n log('init() called with options:', { siteId: opts.siteId, logs: opts.logs })\n\n const existingApi = getRealApi(HFChat)\n if (existingApi) {\n log('Returning existing real API')\n return existingApi\n }\n\n if (loaderPromise) {\n logFull('Returning existing loader promise')\n return loaderPromise\n }\n\n log('Starting widget load...')\n loaderPromise = loadWidget(lastInitOpts)\n return loaderPromise\n}\n\nasync function waitForMethod(methodName: string): Promise<HFChatAPI> {\n logFull(`waitForMethod('${methodName}') starting...`)\n\n // Ensure init is called (may already be in progress)\n await init()\n logFull(`init() completed, checking for '${methodName}'`)\n\n // Check if real API is already available\n const existing = getRealApi(HFChat)\n logFull('getRealApi returned:', existing ? 'real API found' : 'null')\n\n if (existing && typeof (existing as any)[methodName] === 'function') {\n log(`Method '${methodName}' available immediately`)\n return existing\n }\n\n // Poll for the real API to become available\n logFull(`Polling for '${methodName}'...`)\n return new Promise((resolve, reject) => {\n let attempts = 0\n const maxAttempts = 50 // 5 seconds total\n\n const checkMethod = () => {\n const api = getRealApi(HFChat)\n const fn = api ? (api as any)[methodName] : null\n\n // Log every 10 attempts (1 second)\n if (attempts % 10 === 0 && attempts > 0) {\n logFull(`Polling attempt ${attempts}/50 for '${methodName}':`, {\n hasApi: !!api,\n hasMethod: !!fn,\n windowHFChat: typeof window.HFChat,\n isProxy: window.HFChat === HFChat\n })\n }\n\n if (api && typeof fn === 'function') {\n log(`Method '${methodName}' found after ${attempts} attempts`)\n resolve(api)\n return\n }\n\n if (attempts < maxAttempts) {\n attempts += 1\n setTimeout(checkMethod, 100)\n return\n }\n\n logError(`Timeout: '${methodName}' not available after 5 seconds`)\n reject(new Error(`HFChat method '${methodName}' not available after 5 seconds`))\n }\n\n setTimeout(checkMethod, 100)\n })\n}\n\nexport const HFChat: HFChatGlobal = new Proxy(\n {},\n {\n get(_target, prop) {\n // Handle init specially - it's the entry point\n if (prop === 'init') return init\n\n // Server-side rendering guard\n if (typeof window === 'undefined') return () => {}\n\n // Handle __HFCHAT_INSTANCE__ check - return undefined so proxy isn't mistaken for real instance\n if (prop === '__HFCHAT_INSTANCE__') return undefined\n\n // Handle ready property\n if (prop === 'ready') {\n const api = getRealApi(HFChat)\n return !!api?.ready\n }\n\n // Handle isOpen method\n if (prop === 'isOpen') {\n return () => {\n const api = getRealApi(HFChat)\n return api?.isOpen?.() ?? false\n }\n }\n\n // For all other methods, queue them until the real API is ready\n return (...args: unknown[]) => {\n const methodName = String(prop)\n logFull(`Proxy: '${methodName}' called, forwarding to waitForMethod`)\n\n waitForMethod(methodName)\n .then((api) => {\n const fn = (api as any)[methodName]\n if (typeof fn === 'function') {\n logFull(`Proxy: executing '${methodName}' on real API`)\n fn.apply(api, args)\n } else {\n logError(`Method '${methodName}' not found on real API`)\n }\n })\n .catch((error) => {\n logError(error instanceof Error ? error.message : String(error))\n })\n }\n },\n }\n) as HFChatGlobal\n\nif (typeof window !== 'undefined') {\n // Expose a stable global singleton, without breaking when the real widget assigns window.HFChat\n if (!window.HFChat) {\n window.HFChat = HFChat\n }\n}\n\nexport default HFChat\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Re-export public types for consumers\nexport type {\n HFChatLogLevel,\n HFChatConfig,\n HFChatWidgetSettings,\n HFChatIdentifyMeta,\n HFChatOpenOptions,\n HFChatAPI,\n} from './types'\n\nimport type { HFChatConfig, HFChatAPI, HFChatLogLevel } from './types'\n\n// Extended config for the JS SDK loader (adds scriptSrc option)\nexport type HFChatLoaderConfig = HFChatConfig & {\n /** Override widget script source (for self-hosting / testing) */\n scriptSrc?: string\n}\n\nexport type HFChatGlobal = HFChatAPI & {\n /**\n * Load the widget script and initialize the widget.\n */\n init(opts?: HFChatLoaderConfig): Promise<HFChatAPI>\n}\n\ndeclare global {\n interface Window {\n HFChat?: HFChatAPI\n HumanFirstChat?: {\n init: (opts: unknown) => HFChatAPI\n }\n __HFCHAT_DISABLE_AUTO_INIT?: boolean\n }\n}\n\nconst DEFAULT_SCRIPT_SRC = 'https://humanfirst.chat/widget.js'\nconst SCRIPT_DATA_ATTR = 'data-hfchat-widget'\n\n// Logging configuration\nlet logLevel: HFChatLogLevel = 'none'\n\nfunction log(message: string, ...args: unknown[]) {\n if (logLevel === 'none') return\n console.log(`[HFChat SDK] ${message}`, ...args)\n}\n\nfunction logFull(message: string, ...args: unknown[]) {\n if (logLevel !== 'full') return\n console.log(`[HFChat SDK] ${message}`, ...args)\n}\n\nfunction logError(message: string, ...args: unknown[]) {\n if (logLevel === 'none') return\n console.error(`[HFChat SDK] ${message}`, ...args)\n}\n\nlet loaderPromise: Promise<HFChatAPI> | null = null\nlet lastInitOpts: HFChatLoaderConfig | undefined\n\nfunction getRealApi(selfProxy: HFChatGlobal): HFChatAPI | null {\n if (typeof window === 'undefined') return null\n const candidate = window.HFChat\n if (!candidate) return null\n // Check if candidate is the proxy (same reference) - if so, real API not yet available\n if (candidate === selfProxy) return null\n // Check if candidate has the real instance marker\n if ((candidate as any).__HFCHAT_INSTANCE__ === true) return candidate\n return null\n}\n\nfunction injectScript(src: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof document === 'undefined') return resolve()\n if (window.HumanFirstChat) {\n logFull('HumanFirstChat already exists, skipping script injection')\n return resolve()\n }\n\n const existing = document.querySelector(\n `script[${SCRIPT_DATA_ATTR}=\"1\"]`\n ) as HTMLScriptElement | null\n if (existing) {\n logFull('Widget script already in DOM, waiting for load')\n existing.addEventListener('load', () => resolve(), { once: true })\n existing.addEventListener(\n 'error',\n () => reject(new Error('Failed to load widget script')),\n { once: true }\n )\n return\n }\n\n log('Injecting widget script:', src)\n window.__HFCHAT_DISABLE_AUTO_INIT = true\n const script = document.createElement('script')\n script.async = true\n script.src = src\n script.setAttribute(SCRIPT_DATA_ATTR, '1')\n script.setAttribute('data-auto-init', 'false')\n script.onerror = () => {\n logError('Failed to load widget script:', src)\n reject(new Error(`Failed to load widget script: ${src}`))\n }\n script.onload = () => {\n setTimeout(() => {\n if (window.HumanFirstChat) {\n log('Widget script loaded successfully')\n resolve()\n } else {\n logError('Widget script loaded but HumanFirstChat not found')\n reject(new Error('Widget did not attach to window.HumanFirstChat'))\n }\n }, 0)\n }\n document.head.appendChild(script)\n })\n}\n\nasync function loadWidget(opts: HFChatLoaderConfig = {}): Promise<HFChatAPI> {\n if (typeof window === 'undefined') return {} as HFChatAPI\n\n const scriptSrc = opts.scriptSrc ?? DEFAULT_SCRIPT_SRC\n logFull('loadWidget starting with options:', { siteId: opts.siteId, scriptSrc })\n\n await injectScript(scriptSrc)\n\n if (!window.HumanFirstChat?.init) {\n throw new Error('HumanFirstChat.init is not available after script load')\n }\n\n log('Calling HumanFirstChat.init()')\n const api = window.HumanFirstChat.init({\n siteId: opts.siteId,\n hidden: opts.hidden,\n hideOnClose: opts.hideOnClose,\n logs: opts.logs,\n baseURL: opts.baseURL,\n host: opts.host,\n })\n\n logFull('HumanFirstChat.init() returned:', { hasInstance: (api as any)?.__HFCHAT_INSTANCE__ })\n return api\n}\n\nasync function init(opts: HFChatLoaderConfig = {}): Promise<HFChatAPI> {\n // Update log level from options\n if (opts.logs) {\n logLevel = opts.logs\n }\n\n lastInitOpts = { ...lastInitOpts, ...opts }\n log('init() called with options:', { siteId: opts.siteId, logs: opts.logs })\n\n const existingApi = getRealApi(HFChat)\n if (existingApi) {\n log('Returning existing real API')\n return existingApi\n }\n\n if (loaderPromise) {\n logFull('Returning existing loader promise')\n return loaderPromise\n }\n\n log('Starting widget load...')\n loaderPromise = loadWidget(lastInitOpts)\n return loaderPromise\n}\n\nasync function waitForMethod(methodName: string): Promise<HFChatAPI> {\n logFull(`waitForMethod('${methodName}') starting...`)\n\n // Ensure init is called (may already be in progress)\n await init()\n logFull(`init() completed, checking for '${methodName}'`)\n\n // Check if real API is already available\n const existing = getRealApi(HFChat)\n logFull('getRealApi returned:', existing ? 'real API found' : 'null')\n\n if (existing && typeof (existing as any)[methodName] === 'function') {\n log(`Method '${methodName}' available immediately`)\n return existing\n }\n\n // Poll for the real API to become available\n logFull(`Polling for '${methodName}'...`)\n return new Promise((resolve, reject) => {\n let attempts = 0\n const maxAttempts = 50 // 5 seconds total\n\n const checkMethod = () => {\n const api = getRealApi(HFChat)\n const fn = api ? (api as any)[methodName] : null\n\n // Log every 10 attempts (1 second)\n if (attempts % 10 === 0 && attempts > 0) {\n logFull(`Polling attempt ${attempts}/50 for '${methodName}':`, {\n hasApi: !!api,\n hasMethod: !!fn,\n windowHFChat: typeof window.HFChat,\n isProxy: window.HFChat === HFChat\n })\n }\n\n if (api && typeof fn === 'function') {\n log(`Method '${methodName}' found after ${attempts} attempts`)\n resolve(api)\n return\n }\n\n if (attempts < maxAttempts) {\n attempts += 1\n setTimeout(checkMethod, 100)\n return\n }\n\n logError(`Timeout: '${methodName}' not available after 5 seconds`)\n reject(new Error(`HFChat method '${methodName}' not available after 5 seconds`))\n }\n\n setTimeout(checkMethod, 100)\n })\n}\n\nexport const HFChat: HFChatGlobal = new Proxy(\n {},\n {\n get(_target, prop) {\n // Handle init specially - it's the entry point\n if (prop === 'init') return init\n\n // Server-side rendering guard\n if (typeof window === 'undefined') return () => {}\n\n // Handle __HFCHAT_INSTANCE__ check - return undefined so proxy isn't mistaken for real instance\n if (prop === '__HFCHAT_INSTANCE__') return undefined\n\n // Handle 'then' - return undefined so proxy isn't treated as a thenable/Promise\n // This is critical because await/Promise.resolve() check for .then()\n if (prop === 'then') return undefined\n\n // Handle ready property\n if (prop === 'ready') {\n const api = getRealApi(HFChat)\n return !!api?.ready\n }\n\n // Handle isOpen method\n if (prop === 'isOpen') {\n return () => {\n const api = getRealApi(HFChat)\n return api?.isOpen?.() ?? false\n }\n }\n\n // For all other methods, queue them until the real API is ready\n return (...args: unknown[]) => {\n const methodName = String(prop)\n logFull(`Proxy: '${methodName}' called, forwarding to waitForMethod`)\n\n waitForMethod(methodName)\n .then((api) => {\n const fn = (api as any)[methodName]\n if (typeof fn === 'function') {\n logFull(`Proxy: executing '${methodName}' on real API`)\n fn.apply(api, args)\n } else {\n logError(`Method '${methodName}' not found on real API`)\n }\n })\n .catch((error) => {\n logError(error instanceof Error ? error.message : String(error))\n })\n }\n },\n }\n) as HFChatGlobal\n\nif (typeof window !== 'undefined') {\n // Expose a stable global singleton, without breaking when the real widget assigns window.HFChat\n if (!window.HFChat) {\n window.HFChat = HFChat\n }\n}\n\nexport default HFChat\n"],"mappings":"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","names":[]}
|