@mochabug/adapt-sdk 0.1.5 → 0.1.7

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.
@@ -1,2 +1,2 @@
1
- "use strict";var s=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var w=Object.prototype.hasOwnProperty;var d=(e,n)=>{for(var o in n)s(e,o,{get:n[o],enumerable:!0})},u=(e,n,o,a)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of f(n))!w.call(e,t)&&t!==o&&s(e,t,{get:()=>n[t],enumerable:!(a=c(n,t))||a.enumerable});return e};var k=e=>u(s({},"__esModule",{value:!0}),e);var y={};d(y,{getToken:()=>g});module.exports=k(y);var r=null;function g(e=!1){if(e)return"dev-token";if(r!==null)return r;let n="mb_token";if(typeof globalThis.window>"u"||typeof globalThis.location>"u")throw new Error("getToken() is only available in browser environments");let o=globalThis,a=o.location.hash.slice(1);if(!a)throw new Error("No token found in URL hash");let t=new URLSearchParams(a),i=t.get(n);if(!i)throw new Error('Token "mb_token" not found in URL hash');r=decodeURIComponent(i),t.delete(n);let l=t.toString(),h=o.location.pathname+o.location.search+(l?"#"+l:"");return o.history.replaceState(null,"",h),r}0&&(module.exports={getToken});
1
+ "use strict";var u=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var v=(e,t)=>{for(var n in t)u(e,n,{get:t[n],enumerable:!0})},E=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of y(t))!k.call(e,r)&&r!==n&&u(e,r,{get:()=>t[r],enumerable:!(o=M(t,r))||o.enumerable});return e};var R=e=>E(u({},"__esModule",{value:!0}),e);var W={};v(W,{getDarkMode:()=>L,getToken:()=>T,listenDarkMode:()=>D});module.exports=R(W);var i=null;function T(e=!1){if(e)return"dev-token";if(i!==null)return i;if(typeof window>"u"||typeof location>"u")throw new Error("getToken() is only available in browser environments");let t=location.hash.slice(1);if(!t)throw new Error("No token found in URL hash");let n=new URLSearchParams(t).get("mb_token");if(!n)throw new Error('Token "mb_token" not found in URL hash');return i=decodeURIComponent(n),i}var d=null,f=new Set;function L(){return d}function D(e){if(f.add(e),d!==null)try{e(d)}catch{}return()=>{f.delete(e)}}function b(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function z(e){return b(e)&&e.type==="adapt-darkMode"&&typeof e.darkMode=="boolean"}function h(e){return Number.isFinite(e)&&e>=1}function O(e){return b(e)&&typeof e.postMessage=="function"}function a(){return typeof window<"u"&&typeof document<"u"&&typeof window.postMessage=="function"}function g(){if(!a())return!1;try{return window.self!==window.top}catch{return!0}}var m=-1,w=-1,l=null,H=16;function S(){let{body:e,documentElement:t}=document;if(!e||!t)return null;let n=Math.max(e.scrollHeight,e.offsetHeight,t.clientHeight,t.scrollHeight,t.offsetHeight),o=Math.max(e.scrollWidth,e.offsetWidth,t.clientWidth,t.scrollWidth,t.offsetWidth);return!h(o)||!h(n)?null:{width:o,height:n}}function s(){if(!a()||!g())return;let e=window.parent;if(!O(e))return;let t=S();if(!t)return;let{width:n,height:o}=t;if(!(n===m&&o===w)){m=n,w=o;try{e.postMessage({type:"adapt-resize",width:n,height:o},"*")}catch{}}}function c(){l===null&&(l=setTimeout(()=>{l=null,s()},H))}function A(e){let t;try{t=e.data}catch{return}if(z(t)){d=t.darkMode;for(let n of f)try{n(t.darkMode)}catch{}}}function p(){if(!a()||!g())return;window.addEventListener("message",A);let e=new ResizeObserver(c);document.body&&e.observe(document.body),document.documentElement&&e.observe(document.documentElement),document.body&&new MutationObserver(c).observe(document.body,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),document.addEventListener("load",c,!0),document.fonts?.ready?.then(()=>{s()}),document.readyState==="complete"?s():window.addEventListener("load",()=>{s()})}a()&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",p):p());0&&(module.exports={getDarkMode,getToken,listenDarkMode});
2
2
  //# sourceMappingURL=frontend.cjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/frontend.ts"],
4
- "sourcesContent": ["/**\n * Simple token utility for waiting on hash-based tokens\n */\n\n/**\n * Simple token utility for waiting on hash-based tokens\n */\n\nlet cachedToken: string | null = null;\n\n/**\n * Gets the token from URL hash (first call) or returns cached value (subsequent calls)\n * @param isDevelopment - If true, returns 'dev-token' for local development\n * @returns The token string\n */\nexport function getToken(isDevelopment = false): string {\n // Development mode - return immediately\n if (isDevelopment) {\n return 'dev-token';\n }\n\n // Return cached token if already retrieved\n if (cachedToken !== null) {\n return cachedToken;\n }\n\n const tokenKey = 'mb_token';\n\n // Non-browser environment - throw error\n if (\n typeof (globalThis as any).window === 'undefined' ||\n typeof (globalThis as any).location === 'undefined'\n ) {\n throw new Error('getToken() is only available in browser environments');\n }\n\n const win = globalThis as any;\n\n const hash = win.location.hash.slice(1);\n if (!hash) {\n throw new Error('No token found in URL hash');\n }\n\n const params = new URLSearchParams(hash);\n const token = params.get(tokenKey);\n if (!token) {\n throw new Error('Token \"mb_token\" not found in URL hash');\n }\n\n // Cache the token BEFORE removing from URL\n cachedToken = decodeURIComponent(token);\n\n // Clean URL\n params.delete(tokenKey);\n const newHash = params.toString();\n const newUrl =\n win.location.pathname +\n win.location.search +\n (newHash ? '#' + newHash : '');\n win.history.replaceState(null, '', newUrl);\n\n return cachedToken;\n}\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,cAAAE,IAAA,eAAAC,EAAAH,GAQA,IAAII,EAA6B,KAO1B,SAASF,EAASG,EAAgB,GAAe,CAEtD,GAAIA,EACF,MAAO,YAIT,GAAID,IAAgB,KAClB,OAAOA,EAGT,IAAME,EAAW,WAGjB,GACE,OAAQ,WAAmB,OAAW,KACtC,OAAQ,WAAmB,SAAa,IAExC,MAAM,IAAI,MAAM,sDAAsD,EAGxE,IAAMC,EAAM,WAENC,EAAOD,EAAI,SAAS,KAAK,MAAM,CAAC,EACtC,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,4BAA4B,EAG9C,IAAMC,EAAS,IAAI,gBAAgBD,CAAI,EACjCE,EAAQD,EAAO,IAAIH,CAAQ,EACjC,GAAI,CAACI,EACH,MAAM,IAAI,MAAM,wCAAwC,EAI1DN,EAAc,mBAAmBM,CAAK,EAGtCD,EAAO,OAAOH,CAAQ,EACtB,IAAMK,EAAUF,EAAO,SAAS,EAC1BG,EACJL,EAAI,SAAS,SACbA,EAAI,SAAS,QACZI,EAAU,IAAMA,EAAU,IAC7B,OAAAJ,EAAI,QAAQ,aAAa,KAAM,GAAIK,CAAM,EAElCR,CACT",
6
- "names": ["frontend_exports", "__export", "getToken", "__toCommonJS", "cachedToken", "isDevelopment", "tokenKey", "win", "hash", "params", "token", "newHash", "newUrl"]
4
+ "sourcesContent": ["/**\n * Frontend utilities for Adapt plugins running in browser/iframe contexts\n *\n * Iframe resizing is handled automatically - no initialization required.\n * Just import the functions you need and the resize communication starts automatically.\n */\n\n// =============================================================================\n// Token Management\n// =============================================================================\n\nlet cachedToken: string | null = null;\n\n/**\n * Get the authentication token from the URL hash.\n * @param isDevelopment If true, returns a dev token for local development\n */\nexport function getToken(isDevelopment = false): string {\n if (isDevelopment) return 'dev-token';\n if (cachedToken !== null) return cachedToken;\n\n if (typeof window === 'undefined' || typeof location === 'undefined') {\n throw new Error('getToken() is only available in browser environments');\n }\n\n const hash = location.hash.slice(1);\n if (!hash) throw new Error('No token found in URL hash');\n\n const token = new URLSearchParams(hash).get('mb_token');\n if (!token) throw new Error('Token \"mb_token\" not found in URL hash');\n\n cachedToken = decodeURIComponent(token);\n return cachedToken;\n}\n\n// =============================================================================\n// Dark Mode\n// =============================================================================\n\nlet currentDarkMode: boolean | null = null;\nconst darkModeListeners = new Set<(darkMode: boolean) => void>();\n\n/**\n * Get the current dark mode state.\n * Returns null if dark mode state hasn't been received from parent yet.\n */\nexport function getDarkMode(): boolean | null {\n return currentDarkMode;\n}\n\n/**\n * Listen for dark mode changes from the parent window.\n * Returns an unsubscribe function.\n * @param callback Called immediately with current state (if known) and on every change\n */\nexport function listenDarkMode(\n callback: (darkMode: boolean) => void\n): () => void {\n darkModeListeners.add(callback);\n\n // Call immediately with current value if we have one\n if (currentDarkMode !== null) {\n try {\n callback(currentDarkMode);\n } catch {}\n }\n\n return () => {\n darkModeListeners.delete(callback);\n };\n}\n\n// =============================================================================\n// Internal: Message Types and Type Guards\n// =============================================================================\n\ninterface AdaptResizeMessage {\n type: 'adapt-resize';\n width: number;\n height: number;\n}\n\ninterface AdaptDarkModeMessage {\n type: 'adapt-darkMode';\n darkMode: boolean;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isDarkModeMessage(data: unknown): data is AdaptDarkModeMessage {\n return (\n isObject(data) &&\n data.type === 'adapt-darkMode' &&\n typeof data.darkMode === 'boolean'\n );\n}\n\nfunction isValidDimension(value: number): boolean {\n return Number.isFinite(value) && value >= 1;\n}\n\nfunction hasPostMessage(\n obj: unknown\n): obj is { postMessage: typeof postMessage } {\n return isObject(obj) && typeof obj.postMessage === 'function';\n}\n\n// =============================================================================\n// Internal: Environment Detection\n// =============================================================================\n\nfunction isBrowser(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined' &&\n typeof window.postMessage === 'function'\n );\n}\n\nfunction isInIframe(): boolean {\n if (!isBrowser()) return false;\n try {\n return window.self !== window.top;\n } catch {\n return true;\n }\n}\n\n// =============================================================================\n// Internal: Resize Logic\n// =============================================================================\n\nlet lastSentWidth = -1;\nlet lastSentHeight = -1;\nlet throttleTimer: ReturnType<typeof setTimeout> | null = null;\nconst THROTTLE_MS = 16;\n\nfunction getContentDimensions(): { width: number; height: number } | null {\n const { body, documentElement: html } = document;\n if (!body || !html) return null;\n\n const height = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n const width = Math.max(\n body.scrollWidth,\n body.offsetWidth,\n html.clientWidth,\n html.scrollWidth,\n html.offsetWidth\n );\n\n if (!isValidDimension(width) || !isValidDimension(height)) return null;\n\n return { width, height };\n}\n\nfunction sendResizeImmediate(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n const parent = window.parent;\n if (!hasPostMessage(parent)) return;\n\n const dims = getContentDimensions();\n if (!dims) return;\n\n const { width, height } = dims;\n if (width === lastSentWidth && height === lastSentHeight) return;\n\n lastSentWidth = width;\n lastSentHeight = height;\n\n try {\n parent.postMessage(\n { type: 'adapt-resize', width, height } satisfies AdaptResizeMessage,\n '*'\n );\n } catch {}\n}\n\nfunction sendResizeThrottled(): void {\n if (throttleTimer !== null) return;\n\n throttleTimer = setTimeout(() => {\n throttleTimer = null;\n sendResizeImmediate();\n }, THROTTLE_MS);\n}\n\n// =============================================================================\n// Internal: Message Handling\n// =============================================================================\n\nfunction handleMessage(event: MessageEvent): void {\n let data: unknown;\n try {\n data = event.data;\n } catch {\n return;\n }\n\n if (isDarkModeMessage(data)) {\n currentDarkMode = data.darkMode;\n for (const listener of darkModeListeners) {\n try {\n listener(data.darkMode);\n } catch {}\n }\n }\n}\n\n// =============================================================================\n// Internal: Auto-initialization\n// =============================================================================\n\nfunction autoInit(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n // Listen for messages from parent\n window.addEventListener('message', handleMessage);\n\n // Set up resize observation\n const resizeObserver = new ResizeObserver(sendResizeThrottled);\n if (document.body) resizeObserver.observe(document.body);\n if (document.documentElement)\n resizeObserver.observe(document.documentElement);\n\n // Set up mutation observation for DOM changes\n if (document.body) {\n const mutationObserver = new MutationObserver(sendResizeThrottled);\n mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true\n });\n }\n\n // Capture load events on resources (images, iframes, etc.)\n document.addEventListener('load', sendResizeThrottled, true);\n\n // Wait for fonts to load\n document.fonts?.ready?.then(() => {\n sendResizeImmediate();\n });\n\n // Send initial size when fully loaded\n if (document.readyState === 'complete') {\n // Already loaded, send immediately\n sendResizeImmediate();\n } else {\n // Wait for full load\n window.addEventListener('load', () => {\n sendResizeImmediate();\n });\n }\n}\n\n// Run initialization when DOM is ready\nif (isBrowser()) {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', autoInit);\n } else {\n // DOM already ready, init now\n autoInit();\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["frontend_exports", "__export", "getDarkMode", "getToken", "listenDarkMode", "__toCommonJS", "cachedToken", "isDevelopment", "hash", "token", "currentDarkMode", "darkModeListeners", "callback", "isObject", "value", "isDarkModeMessage", "data", "isValidDimension", "hasPostMessage", "obj", "isBrowser", "isInIframe", "lastSentWidth", "lastSentHeight", "throttleTimer", "THROTTLE_MS", "getContentDimensions", "body", "html", "height", "width", "sendResizeImmediate", "parent", "dims", "sendResizeThrottled", "handleMessage", "event", "listener", "autoInit", "resizeObserver"]
7
7
  }