{"version":3,"file":"index.cjs","names":[],"sources":["../src/lib/load-formbricks.ts","../src/index.ts"],"sourcesContent":["import type { TFormbricks, TSetupConfig } from \"../types/formbricks\";\n\ntype Result<T, E = Error> = { ok: true; data: T } | { ok: false; error: E };\n\nlet coreInstance: TFormbricks | null = null;\nlet isInitializing = false;\nconst queue: { method: string; args: unknown[] }[] = [];\n\nconst loadFormbricksSDK = async (appUrl: string): Promise<Result<void>> => {\n  if ((globalThis as unknown as Record<string, unknown>).formbricks) {\n    return { ok: true, data: undefined };\n  }\n\n  const scriptSrc = `${appUrl}/js/formbricks.umd.cjs`;\n\n  // Remove any previously appended script to prevent duplicates on retry\n  const existingScript = document.querySelector(`script[src=\"${scriptSrc}\"]`);\n  if (existingScript) {\n    existingScript.remove();\n  }\n\n  const script = document.createElement(\"script\");\n  script.type = \"text/javascript\";\n  script.src = scriptSrc;\n  script.async = true;\n\n  const loadPromise = new Promise<Result<void>>((resolve) => {\n    const timeoutId = setTimeout(() => {\n      resolve({\n        ok: false,\n        error: new Error(\"Formbricks SDK loading timed out\"),\n      });\n    }, 10000);\n\n    script.onload = () => {\n      clearTimeout(timeoutId);\n\n      // UMD should set globalThis.formbricks synchronously on execution.\n      // Poll briefly as a fallback in case UMD environment detection was\n      // fooled (e.g. a leaked `exports` global) and the assignment was\n      // routed to module.exports instead of globalThis.\n      if ((globalThis as unknown as Record<string, unknown>).formbricks) {\n        resolve({ ok: true, data: undefined });\n        return;\n      }\n\n      let attempts = 0;\n      const poll = setInterval(() => {\n        if ((globalThis as unknown as Record<string, unknown>).formbricks) {\n          clearInterval(poll);\n          resolve({ ok: true, data: undefined });\n        } else if (++attempts >= 50) {\n          clearInterval(poll);\n          resolve({\n            ok: false,\n            error: new Error(\n              \"Formbricks SDK loaded but not available on globalThis\",\n            ),\n          });\n        }\n      }, 10);\n    };\n\n    script.onerror = () => {\n      clearTimeout(timeoutId);\n      resolve({\n        ok: false,\n        error: new Error(\"Failed to load Formbricks SDK\"),\n      });\n    };\n  });\n\n  // Register handlers above BEFORE appending to DOM so that a cached\n  // script whose onload fires on the next microtask is always caught.\n  document.head.appendChild(script);\n  return loadPromise;\n};\n\nconst validateSetupArgs = (config: TSetupConfig): TSetupConfig | null => {\n  const { appUrl, environmentId, workspaceId } = config;\n\n  if (!appUrl) {\n    console.error(\"🧱 Formbricks - Error: appUrl is required\");\n    return null;\n  }\n\n  if (!workspaceId && !environmentId) {\n    console.error(\n      \"🧱 Formbricks - Error: workspaceId or environmentId is required\",\n    );\n    return null;\n  }\n\n  if (environmentId && !workspaceId) {\n    console.warn(\n      \"🧱 Formbricks - Warning: environmentId is deprecated and will be removed in a future version. Please use workspaceId instead.\",\n    );\n  }\n\n  // Removing trailing slash\n  const appUrlWithoutTrailingSlash = appUrl.endsWith(\"/\")\n    ? appUrl.slice(0, -1)\n    : appUrl;\n\n  if (workspaceId) {\n    return {\n      appUrl: appUrlWithoutTrailingSlash,\n      workspaceId,\n      ...(environmentId ? { environmentId } : {}),\n    };\n  }\n\n  return {\n    appUrl: appUrlWithoutTrailingSlash,\n    environmentId: environmentId as string,\n  };\n};\n\nconst processQueue = (): void => {\n  while (queue.length > 0) {\n    const entry = queue.shift();\n    // Should never happen as we check for length above\n    if (!entry) break;\n    if (!coreInstance) break;\n\n    if (\n      typeof coreInstance[entry.method as keyof typeof coreInstance] !==\n      \"function\"\n    ) {\n      console.error(\n        `🧱 Formbricks - Error: Method ${entry.method} does not exist on formbricks`,\n      );\n      continue;\n    }\n\n    // @ts-expect-error -- Required for dynamic function calls\n    (coreInstance[entry.method as keyof typeof coreInstance] as unknown)(\n      ...entry.args,\n    );\n  }\n};\n\nexport const setup = async (config: TSetupConfig): Promise<void> => {\n  if (isInitializing) {\n    console.warn(\n      \"🧱 Formbricks - Warning: Formbricks is already initializing.\",\n    );\n    return;\n  }\n\n  const validatedArgs = validateSetupArgs(config);\n  if (!validatedArgs) return;\n\n  isInitializing = true;\n  try {\n    const loadResult = await loadFormbricksSDK(validatedArgs.appUrl);\n    const instance = (globalThis as unknown as Record<string, unknown>)\n      .formbricks as TFormbricks | undefined;\n\n    if (!loadResult.ok || !instance) {\n      console.error(\"🧱 Formbricks - Error: Failed to load Formbricks SDK\");\n      return;\n    }\n\n    await instance.setup({ ...validatedArgs });\n    coreInstance = instance;\n    processQueue();\n  } catch (err) {\n    coreInstance = null;\n    console.error(\"🧱 Formbricks - Error: setup failed\", err);\n  } finally {\n    isInitializing = false;\n  }\n};\n\nexport const callMethod = async (\n  method: string,\n  ...args: unknown[]\n): Promise<void> => {\n  if (coreInstance) {\n    // @ts-expect-error -- Required for dynamic function calls\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n    await coreInstance[method](...args);\n  } else {\n    console.warn(\n      \"🧱 Formbricks - Warning: Formbricks not initialized. This method will be queued and executed after initialization.\",\n    );\n    queue.push({ method, args });\n  }\n};\n","import { callMethod, setup } from \"./lib/load-formbricks\";\nimport type { TFormbricks } from \"./types/formbricks\";\n\ndeclare global {\n  interface Window {\n    formbricks: TFormbricks | undefined;\n  }\n}\n\nconst formbricks: TFormbricks = {\n  setup: (setupConfig) => setup(setupConfig),\n  setEmail: (email) => callMethod(\"setEmail\", email),\n  setAttribute: (key, value) => callMethod(\"setAttribute\", key, value),\n  setAttributes: (attributes) => callMethod(\"setAttributes\", attributes),\n  setLanguage: (language) => callMethod(\"setLanguage\", language),\n  setUserId: (userId) => callMethod(\"setUserId\", userId),\n  setNonce: (nonce) => callMethod(\"setNonce\", nonce),\n  track: (code, properties) => callMethod(\"track\", code, properties),\n  logout: () => callMethod(\"logout\"),\n  registerRouteChange: () => callMethod(\"registerRouteChange\"),\n};\n\nexport default formbricks;\n"],"mappings":"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"}