{"mappings":"AAEA,OAAO,cAAM;UACX,QAAQ;UACR,QAAQ;UACR,QAAQ;UACR,SAAS;;AAKX,uBAAe,mBAAmB;CAChC,UAAU;CACV,UAAU;CAEV,SAAS;CAET,UAAU;CAgBV,UAAU;;AAMZ,OAAO,cAAM,sBAAsB,mBAAmB;CACpD,WAAW;CACX,OAAO;CACP,OAAO,YAAY;EAAE;EAAa;;CAElC,YAAY,WAAW;CAQvB,IAAI,aAAa;CAUjB,OAAO;CAYP,KAAK;CAIL,QAAQ,iBAAiB,UAAU,cAAc;EAAE;EAAa,cAAc,QAAQ;GAAE;;;CAiBxF,WAAW,aAAa,EAAE,QAAa;EAAE;;CAOzC;CAMA;;AAKF,OAAO,cAAM,uBAAuB,mBAAmB;CACrD,WAAW;CACX;CACA,QAAQ;CACR;CAEA,YAAY,WAAW;CAKvB,QAAQ,iBAAiB,UAAU,cAAc;EAAE;EAAa,eAAe,QAAQ;;CAQvF,WAAW,aAAa,EAAE,UAAS;EAAE;;CAWrC;CAWA;;AAgBF,OAAO,cAAM,sBAAsB,mBAAmB;CACpD,WAAW;CACX,OAAO;CACP;CAEA,YAAY,WAAW;CAOvB,QAAQ,iBAAiB,UAAU,cAAc;EAAE;EAAa,eAAe,QAAQ;;CAQvF,WAAW,aAAa;CAQxB;CAMA","names":[],"sources":["../../../src/lib/manager.ts"],"version":3,"sourcesContent":["import hash from \"./hash.ts\";\n\nexport const managerTypes = {\n  inline: \"inline\",\n  scoped: \"scoped\",\n  global: \"global\",\n  adopted: \"adopted\",\n} as const;\n\nconst createStyleElement = () => document.createElement(\"style\");\n\nabstract class MicrotaskScheduler {\n  protected needsUpdate: boolean = false;\n  protected isScheduled: boolean = false;\n\n  abstract update(): void;\n\n  protected scheduleUpdate(): void {\n    this.needsUpdate = true;\n    if (this.isScheduled) {\n      return;\n    }\n    this.isScheduled = true;\n\n    queueMicrotask(() => {\n      if (this.needsUpdate) {\n        this.update();\n        this.needsUpdate = false;\n      }\n      this.isScheduled = false;\n    });\n  }\n\n  protected cancelPendingUpdate(): void {\n    this.needsUpdate = false;\n    this.isScheduled = false;\n  }\n}\n\nexport class GlobalManager extends MicrotaskScheduler {\n  container: HTMLElement;\n  style: HTMLStyleElement;\n  cache: Map<string, { css: string; refCount: number }>;\n\n  constructor(container: HTMLElement) {\n    super();\n    this.container = container;\n    this.style = createStyleElement();\n    this.container.appendChild(this.style);\n    this.cache = new Map();\n  }\n\n  set(key: string, css: string): void {\n    const existValue = this.cache.get(key);\n    if (existValue) {\n      existValue.refCount++;\n    } else {\n      this.cache.set(key, { css, refCount: 1 });\n      this.scheduleUpdate();\n    }\n  }\n\n  delete(key: string): void {\n    const existValue = this.cache.get(key);\n    if (!existValue) {\n      return;\n    }\n    existValue.refCount--;\n    if (existValue.refCount === 0) {\n      this.cache.delete(key);\n      this.scheduleUpdate();\n    }\n  }\n\n  hash(str: string): string {\n    return hash(str).toString(16).padStart(8, \"0\");\n  }\n\n  prepare(cssText: string, element?: HTMLElement): { css: string; applyOptions: false | { key: string } } {\n    const key = this.hash(cssText);\n    const selector = `[data-ps=\"${key}\"]`;\n    const css = `${selector}{${cssText}}`;\n    let applyOptions: boolean | { key: string };\n    element.dataset.ps = key;\n    if (this.cache.has(key)) {\n      applyOptions = false;\n    } else {\n      applyOptions = { key };\n    }\n    return {\n      css,\n      applyOptions,\n    };\n  }\n\n  applyStyle(css: string, { key = css }: { key?: string } = {}): void {\n    if (this.cache.has(key)) {\n      return;\n    }\n    this.set(key, css);\n  }\n\n  clear(): void {\n    this.cancelPendingUpdate();\n    this.style.textContent = \"\";\n    this.cache.clear();\n  }\n\n  update(): void {\n    this.style.textContent = [...this.cache.values().map((v) => v.css)].join(\"\");\n  }\n}\n\nexport class AdoptedManager extends MicrotaskScheduler {\n  container: HTMLElement;\n  index?: number;\n  sheet?: CSSStyleSheet;\n  current: string = \"\";\n\n  constructor(container: HTMLElement) {\n    super();\n    this.container = container;\n  }\n\n  prepare(cssText: string, element?: HTMLElement): { css: string; applyOptions?: false | {} } {\n    const css = `:host{${cssText}}`;\n    return {\n      css,\n      applyOptions: this.current === css ? false : {},\n    };\n  }\n\n  applyStyle(css: string, { index }: { index?: number } = {}): void {\n    if (this.current === css) {\n      return;\n    }\n    this.current = css;\n    if (index !== undefined && this.index === undefined) {\n      this.index = index;\n    }\n    this.scheduleUpdate();\n  }\n\n  clear(): void {\n    this.cancelPendingUpdate();\n    this.current = \"\";\n    if (this.sheet && this.index !== undefined) {\n      const sheets = this.container.shadowRoot.adoptedStyleSheets;\n      this.container.shadowRoot.adoptedStyleSheets = [...sheets.slice(0, this.index), ...sheets.slice(this.index + 1)];\n      this.sheet = undefined;\n      this.index = undefined;\n    }\n  }\n\n  update(): void {\n    if (!this.current) {\n      return;\n    }\n    if (this.sheet) {\n      this.sheet.replaceSync(this.current);\n      return;\n    }\n    this.sheet = new CSSStyleSheet();\n    this.sheet.replaceSync(this.current);\n    const sheets = this.container.shadowRoot.adoptedStyleSheets;\n    const finalIndex = this.index ?? sheets.length;\n    this.container.shadowRoot.adoptedStyleSheets = [...sheets.slice(0, finalIndex), this.sheet, ...sheets.slice(finalIndex)];\n  }\n}\n\nexport class ScopedManager extends MicrotaskScheduler {\n  container: HTMLElement;\n  style: HTMLStyleElement;\n  current: string = \"\";\n\n  constructor(container: HTMLElement) {\n    super();\n    this.container = container;\n    this.style = createStyleElement();\n    this.container.insertBefore(this.style, this.container.firstChild);\n  }\n\n  prepare(cssText: string, element?: HTMLElement): { css: string; applyOptions?: false | {} } {\n    const css = `@scope{:scope{${cssText}}}`;\n    return {\n      css,\n      applyOptions: this.current === css ? false : {},\n    };\n  }\n\n  applyStyle(css: string, _?: any): void {\n    if (this.current === css) {\n      return;\n    }\n    this.current = css;\n    this.scheduleUpdate();\n  }\n\n  clear(): void {\n    this.cancelPendingUpdate();\n    this.style.textContent = \"\";\n    this.current = \"\";\n  }\n\n  update(): void {\n    this.style.textContent = this.current;\n  }\n}\n"],"file":"manager.d.ts"}