{"version":3,"file":"single-spa-css.min.cjs","sources":["../../src/single-spa-css.ts"],"sourcesContent":["import { AppProps, LifeCycleFn } from \"single-spa\";\n\nconst defaultOptions: Required<SingleSpaCssOpts> = {\n  cssUrls: [],\n  webpackExtractedCss: false,\n  timeout: 5000,\n  shouldUnmount: true,\n  createLink: (url) => {\n    const linkEl = document.createElement(\"link\");\n    linkEl.href = url;\n    linkEl.rel = \"stylesheet\";\n    return linkEl;\n  },\n};\n\nexport default function singleSpaCss<ExtraProps>(\n  _opts: SingleSpaCssOpts,\n): CSSLifecycles<ExtraProps> {\n  if (!_opts || typeof _opts !== \"object\") {\n    throw Error(`single-spa-css: opts must be an object`);\n  }\n\n  // Requires polyfill in IE11\n  const opts: Required<SingleSpaCssOpts> = Object.assign(\n    {},\n    defaultOptions,\n    _opts,\n  );\n\n  if (!Array.isArray(opts.cssUrls)) {\n    throw Error(\"single-spa-css: cssUrls must be an array\");\n  }\n\n  const allCssUrls = opts.cssUrls;\n  if (opts.webpackExtractedCss) {\n    if (!__webpack_require__.cssAssets) {\n      throw Error(\n        \"single-spa-css: to use webpackExtractedCss, add ExposeRuntimeCssAssetsPlugin to your webpack config.\",\n      );\n    }\n\n    allCssUrls.push(\n      ...__webpack_require__.cssAssets.map(\n        (fileName) =>\n          __webpack_public_path__ +\n          __webpack_require__.cssAssetFileName(fileName),\n      ),\n    );\n  }\n\n  const linkElements: LinkElements = {};\n  let linkElementsToUnmount: ElementsToUnmount[] = [];\n\n  function bootstrap(props: AppProps) {\n    return Promise.all(\n      allCssUrls.map(\n        (cssUrl) =>\n          new Promise<void>((resolve, reject) => {\n            const [url] = extractUrl(cssUrl);\n            const preloadEl = document.querySelector(\n              `link[rel=\"preload\"][as=\"style\"][href=\"${url}\"]`,\n            );\n\n            if (!preloadEl) {\n              const linkEl = document.createElement(\"link\");\n              linkEl.rel = \"preload\";\n              linkEl.setAttribute(\"as\", \"style\");\n              linkEl.href = url;\n\n              document.head.appendChild(linkEl);\n            }\n\n            // Don't wait for preload to finish before finishing bootstrap\n            resolve();\n          }),\n      ),\n    );\n  }\n\n  function mount(props: AppProps) {\n    return Promise.all(\n      allCssUrls.map(\n        (cssUrl) =>\n          new Promise<void>((resolve, reject) => {\n            const [url, shouldUnmount] = extractUrl(cssUrl);\n\n            const existingLinkEl = document.querySelector(\n              `link[rel=\"stylesheet\"][href=\"${url}\"]`,\n            );\n\n            if (existingLinkEl) {\n              linkElements[url] = existingLinkEl as HTMLLinkElement;\n              resolve();\n            } else {\n              const timeout = setTimeout(() => {\n                reject(\n                  `single-spa-css: While mounting '${props.name}', loading CSS from URL ${linkEl.href} timed out after ${opts.timeout}ms`,\n                );\n              }, opts.timeout);\n              const linkEl = opts.createLink(url);\n              linkEl.addEventListener(\"load\", () => {\n                clearTimeout(timeout);\n                resolve();\n              });\n              linkEl.addEventListener(\"error\", () => {\n                clearTimeout(timeout);\n                reject(\n                  Error(\n                    `single-spa-css: While mounting '${props.name}', loading CSS from URL ${linkEl.href} failed.`,\n                  ),\n                );\n              });\n              linkElements[url] = linkEl;\n              document.head.appendChild(linkEl);\n\n              if (shouldUnmount) {\n                linkElementsToUnmount.push([linkEl, url]);\n              }\n            }\n          }),\n      ),\n    );\n  }\n\n  function unmount(props: AppProps) {\n    const elements = linkElementsToUnmount;\n\n    // reset this array immediately so that only one mounted instance tries to unmount\n    // the link elements at a time\n    linkElementsToUnmount = [];\n\n    return Promise.all(\n      elements.map(([linkEl, url]) =>\n        Promise.resolve().then(() => {\n          delete linkElements[url];\n          if (linkEl.parentNode) {\n            linkEl.parentNode.removeChild(linkEl);\n          }\n        }),\n      ),\n    );\n  }\n\n  function extractUrl(cssUrl: CssUrl): [string, boolean] {\n    if (typeof cssUrl === \"string\") {\n      return [cssUrl, opts.shouldUnmount];\n    } else {\n      return [\n        cssUrl.href,\n        cssUrl.hasOwnProperty(\"shouldUnmount\")\n          ? cssUrl.shouldUnmount\n          : opts.shouldUnmount,\n      ];\n    }\n  }\n\n  return { bootstrap, mount, unmount };\n}\n\ntype SingleSpaCssOpts = {\n  cssUrls: CssUrl[];\n  webpackExtractedCss?: boolean;\n  timeout?: number;\n  shouldUnmount?: boolean;\n  createLink?: (url: string) => HTMLLinkElement;\n};\n\ntype CssUrl =\n  | string\n  | {\n      href: string;\n      shouldUnmount: boolean;\n    };\n\ntype LinkElements = {\n  [url: string]: HTMLLinkElement;\n};\n\ntype ElementsToUnmount = [HTMLLinkElement, string];\n\ntype CSSLifecycles<ExtraProps> = {\n  bootstrap: LifeCycleFn<ExtraProps>;\n  mount: LifeCycleFn<ExtraProps>;\n  unmount: LifeCycleFn<ExtraProps>;\n};\n"],"names":["defaultOptions","cssUrls","webpackExtractedCss","timeout","shouldUnmount","createLink","url","linkEl","document","createElement","href","rel","_opts","Error","opts","Object","assign","Array","isArray","allCssUrls","__webpack_require__","cssAssets","push","apply","map","fileName","__webpack_public_path__","cssAssetFileName","linkElementsToUnmount","extractUrl","cssUrl","hasOwnProperty","bootstrap","props","Promise","all","resolve","reject","querySelector","concat","setAttribute","head","appendChild","mount","_a","timeout_1","setTimeout","name","linkEl_1","addEventListener","clearTimeout","unmount","elements","then","parentNode","removeChild"],"mappings":"6OAEA,IAAMA,EAA6C,CACjDC,QAAS,GACTC,qBAAqB,EACrBC,QAAS,IACTC,eAAe,EACfC,WAAY,SAACC,GACX,IAAMC,EAASC,SAASC,cAAc,QAGtC,OAFAF,EAAOG,KAAOJ,EACdC,EAAOI,IAAM,aACNJ,CACR,UAGqB,SACtBK,GAEA,IAAKA,GAA0B,iBAAVA,EACnB,MAAMC,MAAM,0CAId,IAAMC,EAAmCC,OAAOC,OAC9C,CAAA,EACAhB,EACAY,GAGF,IAAKK,MAAMC,QAAQJ,EAAKb,SACtB,MAAMY,MAAM,4CAGd,IAAMM,EAAaL,EAAKb,QACxB,GAAIa,EAAKZ,oBAAqB,CAC5B,IAAKkB,oBAAoBC,UACvB,MAAMR,MACJ,wGAIJM,EAAWG,KAAXC,MAAAJ,EACKC,oBAAoBC,UAAUG,KAC/B,SAACC,GACC,OAAAC,wBACAN,oBAAoBO,iBAAiBF,EADrC,KAOR,IAAIG,EAA6C,GA4FjD,SAASC,EAAWC,GAClB,MAAsB,iBAAXA,EACF,CAACA,EAAQhB,EAAKV,eAEd,CACL0B,EAAOpB,KACPoB,EAAOC,eAAe,iBAClBD,EAAO1B,cACPU,EAAKV,eAKf,MAAO,CAAE4B,UAvGT,SAAmBC,GACjB,OAAOC,QAAQC,IACbhB,EAAWK,KACT,SAACM,GACC,OAAA,IAAII,SAAc,SAACE,EAASC,GACnB,IAAA/B,EAAOuB,EAAWC,MAKzB,IAJkBtB,SAAS8B,cACzB,yCAAyCC,OAAAjC,EAAO,OAGlC,CACd,IAAMC,EAASC,SAASC,cAAc,QACtCF,EAAOI,IAAM,UACbJ,EAAOiC,aAAa,KAAM,SAC1BjC,EAAOG,KAAOJ,EAEdE,SAASiC,KAAKC,YAAYnC,GAI5B6B,GACF,SAkFYO,MA7EpB,SAAeV,GACb,OAAOC,QAAQC,IACbhB,EAAWK,KACT,SAACM,GACC,OAAA,IAAII,SAAc,SAACE,EAASC,GACpB,IAAAO,EAAuBf,EAAWC,GAAjCxB,EAAGsC,EAAA,GAAExC,EAAawC,EAAA,GAMzB,GAJuBpC,SAAS8B,cAC9B,gCAAgCC,OAAAjC,EAAO,OAKvC8B,QACK,CACL,IAAMS,EAAUC,YAAW,WACzBT,EACE,mCAAAE,OAAmCN,EAAMc,KAA+B,4BAAAR,OAAAS,EAAOtC,iCAAwBI,EAAKX,QAAO,MAEvH,GAAGW,EAAKX,SACF6C,EAASlC,EAAKT,WAAWC,GAC/B0C,EAAOC,iBAAiB,QAAQ,WAC9BC,aAAaL,GACbT,GACF,IACAY,EAAOC,iBAAiB,SAAS,WAC/BC,aAAaL,GACbR,EACExB,MACE,mCAAA0B,OAAmCN,EAAMc,KAA+B,4BAAAR,OAAAS,EAAOtC,KAAc,aAGnG,IAEAF,SAASiC,KAAKC,YAAYM,GAEtB5C,GACFwB,EAAsBN,KAAK,CAAC0B,EAAQ1C,IAG1C,SAqCmB6C,QAhC3B,SAAiBlB,GACf,IAAMmB,EAAWxB,EAMjB,OAFAA,EAAwB,GAEjBM,QAAQC,IACbiB,EAAS5B,KAAI,SAACoB,OAACrC,EAAMqC,EAAA,GACnB,OADwBA,EAAA,GACxBV,QAAQE,UAAUiB,MAAK,WAEjB9C,EAAO+C,YACT/C,EAAO+C,WAAWC,YAAYhD,EAElC,SAmBR"}