{"version":3,"file":"GlobalSettings.js","sourceRoot":"../src/","sources":["GlobalSettings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;GAOG;AAEH,IAAM,yBAAyB,GAAG,oBAAoB,CAAC;AACvD,IAAM,wBAAwB,GAAG,eAAe,CAAC;AAEjD,IAAI,QAAQ,GAAG,CAAC,CAAC;AA2BjB;;;;;;;GAOG;AACH;IAAA;IAoDA,CAAC;IAnDe,uBAAQ,GAAtB,UAA0B,GAAW,EAAE,YAA4B;QACjE,IAAM,cAAc,GAAG,kBAAkB,EAAE,CAAC;QAE5C,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;YACrC,cAAc,CAAC,GAAG,CAAC,GAAG,OAAO,YAAY,KAAK,UAAU,CAAC,CAAC,CAAE,YAAyB,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;SACxG;QAED,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAEa,uBAAQ,GAAtB,UAA0B,GAAW,EAAE,KAAQ;QAC7C,IAAM,cAAc,GAAG,kBAAkB,EAAE,CAAC;QAC5C,IAAM,SAAS,GAAG,cAAc,CAAC,wBAAwB,CAAC,CAAC;QAC3D,IAAI,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QAEnC,IAAI,KAAK,KAAK,QAAQ,EAAE;YACtB,cAAc,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAE5B,IAAI,iBAAiB,GAAG;gBACtB,QAAQ,UAAA;gBACR,KAAK,OAAA;gBACL,GAAG,KAAA;aACJ,CAAC;YAEF,KAAK,IAAI,EAAE,IAAI,SAAS,EAAE;gBACxB,IAAI,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE;oBAChC,SAAS,CAAC,EAAE,CAAC,CAAC,iBAAiB,CAAC,CAAC;iBAClC;aACF;SACF;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEa,gCAAiB,GAA/B,UAAgC,EAAwB;QACtD,yGAAyG;QACzG,kGAAkG;QAClG,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC;QACnB,IAAM,SAAS,GAAG,aAAa,EAAE,CAAC;QAElC,IAAI,CAAC,EAAE,EAAE;YACP,EAAE,GAAG,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;SACrC;QAED,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;IAEa,mCAAoB,GAAlC,UAAmC,EAAwB;QACzD,IAAM,SAAS,GAAG,aAAa,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC,EAAE,CAAC,MAAgB,CAAC,CAAC;IACxC,CAAC;IACH,qBAAC;AAAD,CAAC,AApDD,IAoDC;;AAED,8DAA8D;AAC9D,SAAS,kBAAkB;;IACzB,IAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,8DAA8D;IAC9D,IAAM,SAAS,GAA2B,GAAG,IAAI,EAAE,CAAC;IAEpD,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,EAAE;QACzC,SAAS,CAAC,yBAAyB,CAAC;YAClC,GAAC,wBAAwB,IAAG,EAAE;eAC/B,CAAC;KACH;IAED,OAAO,SAAS,CAAC,yBAAyB,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,aAAa;IACpB,IAAM,cAAc,GAAG,kBAAkB,EAAE,CAAC;IAC5C,OAAO,cAAc,CAAC,wBAAwB,CAAC,CAAC;AAClD,CAAC","sourcesContent":["import { getWindow } from './dom/getWindow';\n\n/**\n * Storing global state in local module variables has issues when more than one copy\n * if the module gets loaded on the page (due to a bundling error or simply by consuming\n * a prebundled script.)\n *\n * This file contains helpers to deal with the getting and setting local state, and allows\n * callers to get called back when it mutates.\n */\n\nconst GLOBAL_SETTINGS_PROP_NAME = '__globalSettings__';\nconst CALLBACK_STATE_PROP_NAME = '__callbacks__';\n\nlet _counter = 0;\n\n/**\n * Change description used for change callbacks in GlobalSettings.\n *\n * @public\n * {@docCategory IChangeDescription}\n */\nexport interface IChangeDescription {\n  key: string;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  oldValue: any;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  value: any;\n}\n\n/**\n * Change event callback.\n *\n * @public\n * {@docCategory IChangeEventCallback}\n */\nexport interface IChangeEventCallback {\n  __id__?: string;\n  (changeDescription?: IChangeDescription): void;\n}\n\n/**\n * Global settings helper, which stores settings in the global (window) namespace.\n * If window is not provided, it will store settings in module scope. Provides a\n * way to observe changes as well when their values change.\n *\n * @public\n * {@docCategory GlobalSettings}\n */\nexport class GlobalSettings {\n  public static getValue<T>(key: string, defaultValue?: T | (() => T)): T {\n    const globalSettings = _getGlobalSettings();\n\n    if (globalSettings[key] === undefined) {\n      globalSettings[key] = typeof defaultValue === 'function' ? (defaultValue as Function)() : defaultValue;\n    }\n\n    return globalSettings[key];\n  }\n\n  public static setValue<T>(key: string, value: T): T {\n    const globalSettings = _getGlobalSettings();\n    const callbacks = globalSettings[CALLBACK_STATE_PROP_NAME];\n    let oldValue = globalSettings[key];\n\n    if (value !== oldValue) {\n      globalSettings[key] = value;\n\n      let changeDescription = {\n        oldValue,\n        value,\n        key,\n      };\n\n      for (let id in callbacks) {\n        if (callbacks.hasOwnProperty(id)) {\n          callbacks[id](changeDescription);\n        }\n      }\n    }\n\n    return value;\n  }\n\n  public static addChangeListener(cb: IChangeEventCallback): void {\n    // Note: we use generated ids on the callbacks to create a map of the callbacks, which optimizes removal.\n    // (It's faster to delete a key than it is to look up the index of an object and splice an array.)\n    let id = cb.__id__;\n    const callbacks = _getCallbacks();\n\n    if (!id) {\n      id = cb.__id__ = String(_counter++);\n    }\n\n    callbacks[id] = cb;\n  }\n\n  public static removeChangeListener(cb: IChangeEventCallback): void {\n    const callbacks = _getCallbacks();\n    delete callbacks[cb.__id__ as string];\n  }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction _getGlobalSettings(): { [key: string]: any } {\n  const win = getWindow();\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const globalObj: { [key: string]: any } = win || {};\n\n  if (!globalObj[GLOBAL_SETTINGS_PROP_NAME]) {\n    globalObj[GLOBAL_SETTINGS_PROP_NAME] = {\n      [CALLBACK_STATE_PROP_NAME]: {},\n    };\n  }\n\n  return globalObj[GLOBAL_SETTINGS_PROP_NAME];\n}\n\nfunction _getCallbacks(): { [key: string]: () => void } {\n  const globalSettings = _getGlobalSettings();\n  return globalSettings[CALLBACK_STATE_PROP_NAME];\n}\n"]}