resonare 0.1.0 → 0.1.1

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Resonare [![Version](https://img.shields.io/npm/v/resonare.svg?labelColor=black&color=blue)](https://www.npmjs.com/package/resonare)
2
2
 
3
- A configuration-based store for restoring user preferences without flash of inaccurate styles.
3
+ A configuration-based store for restoring user preferences without a flash of incorrect styles.
4
4
 
5
5
  ## Features
6
6
 
@@ -72,7 +72,7 @@ export const themeScript = createInlineThemeScript([
72
72
 
73
73
  ### 2. Inject inline script
74
74
 
75
- Inject the script as below into the `<head>` of your HTML document. This differs by framework. See the examples below.
75
+ Inject the script into the `<head>` of your HTML document as shown below. The exact pattern differs by framework; see the examples below.
76
76
 
77
77
  ```tsx
78
78
  // React.js
@@ -221,16 +221,15 @@ const script = createInlineThemeScript([
221
221
  #### Client-side persistence
222
222
 
223
223
  ```tsx
224
- import * as React from 'react'
225
224
  import {
226
225
  createInlineThemeScript,
227
226
  createThemeStore,
228
227
  getThemesAndOptions,
229
- type ThemeStoreConfig,
228
+ type ThemeScriptParameter,
230
229
  } from 'resonare'
231
230
  import { useResonare } from 'resonare/react'
232
231
 
233
- const STORE = {
232
+ const PARAM = {
234
233
  key: 'demo',
235
234
  config: {
236
235
  colorScheme: {
@@ -263,31 +262,24 @@ const STORE = {
263
262
  document.documentElement.dataset[key] = String(value)
264
263
  })
265
264
  },
266
- } as const satisfies Parameters<typeof createInlineThemeScript>[0][number]
265
+ } as const satisfies ThemeScriptParameter
267
266
 
268
- export const themeScript = createInlineThemeScript([STORE])
267
+ export const themeScript = createInlineThemeScript([PARAM])
269
268
 
270
- const themeStore = createThemeStore(STORE.config)
269
+ const themeStore = createThemeStore(PARAM.config)
271
270
 
272
- function ThemeSelect() {
273
- const { themes, setThemes, restore, subscribe, sync } =
274
- useResonare(themeStore)
271
+ if (typeof window !== 'undefined') {
272
+ themeStore.subscribe(PARAM.handler)
275
273
 
276
- React.useEffect(() => {
277
- restore()
278
-
279
- const unsubscribe = subscribe(STORE.handler)
280
-
281
- const stopSync = sync()
274
+ themeStore.restore()
282
275
 
283
- return () => {
284
- unsubscribe()
276
+ themeStore.sync()
277
+ }
285
278
 
286
- stopSync?.()
287
- }
288
- }, [restore, subscribe, sync])
279
+ function ThemeSelect() {
280
+ const { themes, setThemes } = useResonare(themeStore)
289
281
 
290
- return getThemesAndOptions(STORE.config).map(([theme, options]) => (
282
+ return getThemesAndOptions(PARAM.config).map(([theme, options]) => (
291
283
  <div key={theme}>
292
284
  <label htmlFor={theme}>{theme}</label>
293
285
  <select
@@ -341,12 +333,9 @@ export function ThemeSelect({ persistedStateFromDb }) {
341
333
  }),
342
334
  )
343
335
 
344
- const { themes, setThemes, restore, subscribe, sync } =
345
- useResonare(themeStore)
336
+ const { themes, setThemes, subscribe, sync } = useResonare(themeStore)
346
337
 
347
338
  React.useEffect(() => {
348
- restore()
349
-
350
339
  const unsubscribe = subscribe(({ resolvedThemes }) => {
351
340
  Object.entries(resolvedThemes).forEach(([key, value]) => {
352
341
  document.documentElement.dataset[key] = String(value)
@@ -360,7 +349,7 @@ export function ThemeSelect({ persistedStateFromDb }) {
360
349
 
361
350
  stopSync?.()
362
351
  }
363
- }, [restore, subscribe, sync])
352
+ }, [subscribe, sync])
364
353
 
365
354
  return getThemesAndOptions(CONFIG).map(([theme, options]) => (
366
355
  <div key={theme}>
package/dist/index.d.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  //#region src/storage.d.ts
2
+ /**
3
+ * Pluggable persistence for `createThemeStore`.
4
+ */
2
5
  type StorageAdapter = {
3
6
  get: () => object | null;
4
- set: (value: object) => void;
5
- broadcast?: (value: object) => void;
7
+ set: (value: object) => void; /** Optional: notify other tabs/contexts after local `set` operation. */
8
+ broadcast?: (value: object) => void; /** Optional: subscribes to other tabs/contexts' updates, returns `unsubscribe` function. */
6
9
  watch?: (cb: (value: object) => void) => () => void;
7
10
  };
8
11
  type StorageAdapterCreate = ({
@@ -11,10 +14,35 @@ type StorageAdapterCreate = ({
11
14
  abortController: AbortController;
12
15
  }) => StorageAdapter;
13
16
  type StorageAdapterCreator<Options> = (options: Options) => StorageAdapterCreate;
17
+ /**
18
+ * Persists theme store in `localStorage` or `sessionStorage`.
19
+ * @example
20
+ * ```ts
21
+ * import { createThemeStore, localStorageAdapter } from 'resonare'
22
+ *
23
+ * const store = createThemeStore(
24
+ * { mode: { options: ['light', 'dark'] },
25
+ * { storage: localStorageAdapter({ key: 'app', type: 'localStorage' }) },
26
+ * )
27
+ * ```
28
+ */
14
29
  declare const localStorageAdapter: StorageAdapterCreator<{
15
30
  key: string;
16
31
  type?: 'localStorage' | 'sessionStorage';
17
32
  }>;
33
+ /**
34
+ * In-memory persistence and sync via `BroadcastChannel`.
35
+ * Useful with server-side persistence.
36
+ * @example
37
+ * ```ts
38
+ * import { createThemeStore, memoryStorageAdapter } from 'resonare'
39
+ *
40
+ * const store = createThemeStore(
41
+ * { mode: { options: ['light', 'dark'] } },
42
+ * { storage: memoryStorageAdapter({ key: 'preview' }) },
43
+ * )
44
+ * ```
45
+ */
18
46
  declare const memoryStorageAdapter: StorageAdapterCreator<{
19
47
  key: string;
20
48
  }>;
@@ -80,14 +108,37 @@ declare class ThemeStore<T extends ThemeStoreConfig> {
80
108
  restore: () => void;
81
109
  subscribe: (callback: Listener<T>) => (() => void);
82
110
  sync: () => (() => void) | undefined;
111
+ /** Clears subscribers and aborts media-query listeners tied to this store instance. */
83
112
  destroy: () => void;
84
113
  }
85
114
  declare function createThemeStore<T extends ThemeStoreConfig>(config: T, options?: ThemeStoreOptions<T>): ThemeStore<T>;
86
- declare function createInlineThemeScript(configs: Array<{
87
- key?: string;
115
+ type ThemeScriptParameter = {
116
+ /** `localStorage` key; defaults to the 'resonare'. */key?: string;
88
117
  config: ThemeStoreConfig;
89
118
  handler: Listener<ThemeStoreConfig>;
90
- }>): string;
119
+ };
120
+ /**
121
+ * Creates an IIFE script string that reads persisted themes from `localStorage` and runs your handlers immediately.
122
+ *
123
+ * Useful for avoiding flash of incorrect styles.
124
+ * @example
125
+ * ```tsx
126
+ * import { createInlineThemeScript } from 'resonare'
127
+ *
128
+ * const inlineScript = createInlineThemeScript([
129
+ * {
130
+ * key: 'my-app',
131
+ * config: { options: ['light', 'dark'] },
132
+ * handler: ({ resolvedThemes }) => {
133
+ * document.documentElement.dataset.mode = String(resolvedThemes.mode)
134
+ * },
135
+ * },
136
+ * ])
137
+ *
138
+ * <script>{inlineScript}</script>
139
+ * ```
140
+ */
141
+ declare function createInlineThemeScript(themeScriptParameters: Array<ThemeScriptParameter>): string;
91
142
  //#endregion
92
- export { StorageAdapter, StorageAdapterCreate, StorageAdapterCreator, ThemeAndOptions, type ThemeStore, ThemeStoreConfig, Themes, createInlineThemeScript, createThemeStore, getDefaultThemes, getThemesAndOptions, localStorageAdapter, memoryStorageAdapter };
143
+ export { StorageAdapter, StorageAdapterCreate, StorageAdapterCreator, ThemeAndOptions, ThemeScriptParameter, type ThemeStore, ThemeStoreConfig, Themes, createInlineThemeScript, createThemeStore, getDefaultThemes, getThemesAndOptions, localStorageAdapter, memoryStorageAdapter };
93
144
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/storage.ts","../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/storage.ts","../src/index.ts"],"mappings":"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"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["name","PACKAGE_NAME","type","StorageAdapter","get","set","value","broadcast","watch","cb","StorageAdapterCreate","abortController","AbortController","StorageAdapterCreator","options","Options","localStorageAdapter","key","JSON","parse","window","getItem","setItem","stringify","controller","addEventListener","e","storageArea","newValue","signal","AbortSignal","any","abort","memoryStorageAdapter","storage","Map","channel","BroadcastChannel","postMessage","data","name","PACKAGE_NAME","type","localStorageAdapter","StorageAdapter","StorageAdapterCreate","ThemeValue","ThemeOption","value","T","media","ThemeConfig","options","ReadonlyArray","initialValue","ThemeStoreConfig","Record","KeyedThemeStoreConfig","Themes","K","U","Listener","themes","resolvedThemes","ThemeKeysWithSystemOption","NonSystemOptionValues","SystemOptions","PersistedState","Partial","systemOptions","ThemeStoreOptions","initialState","storage","ThemeAndOptions","Array","getThemesAndOptions","config","Object","entries","map","themeKey","themeConfig","option","getDefaultThemes","fromEntries","ThemeStore","defaultThemes","currentThemes","keyedConfig","listeners","Set","mediaQueryCache","MediaQueryList","abortController","AbortController","constructor","key","hasOwn","String","getThemes","getResolvedThemes","resolveThemes","setThemes","updatedThemes","setThemesAndNotify","stateToPersist","toPersist","set","broadcast","updateSystemOption","ifMatch","ifNotMatch","restore","persistedState","get","subscribe","callback","add","delete","sync","watch","destroy","clear","abort","#setThemesAndNotify","notify","#resolveThemes","optionKey","resolveThemeOption","#resolveThemeOption","window","document","createElement","console","warn","mediaQuery","mediaQueryList","matchMedia","addEventListener","signal","matches","#notify","listener","createThemeStore","restoreThemesString","persistedThemes","JSON","parse","localStorage","getItem","reduce","acc","firstOption","mediaOption","find","Required","toString","createInlineThemeScript","configs","handler","serializedConfigs","stringify","join"],"sources":["../../package.json","../src/storage.ts","../src/index.ts"],"sourcesContent":["","import { name as PACKAGE_NAME } from '../../package.json' with { type: 'json' }\n\nexport type StorageAdapter = {\n\tget: () => object | null\n\tset: (value: object) => void\n\t// del: () => void\n\tbroadcast?: (value: object) => void\n\twatch?: (cb: (value: object) => void) => () => void\n}\n\nexport type StorageAdapterCreate = ({\n\tabortController,\n}: {\n\tabortController: AbortController\n}) => StorageAdapter\n\nexport type StorageAdapterCreator<Options> = (\n\toptions: Options,\n) => StorageAdapterCreate\n\nexport const localStorageAdapter: StorageAdapterCreator<{\n\tkey: string\n\ttype?: 'localStorage' | 'sessionStorage'\n}> = ({ key, type = 'localStorage' }) => {\n\treturn ({ abortController }) => {\n\t\treturn {\n\t\t\tget: () => {\n\t\t\t\treturn JSON.parse(window[type].getItem(key) || 'null')\n\t\t\t},\n\n\t\t\tset: (value: object) => {\n\t\t\t\twindow[type].setItem(key, JSON.stringify(value))\n\t\t\t},\n\n\t\t\t// del: () => {\n\t\t\t// \twindow[type].removeItem(key)\n\t\t\t// },\n\n\t\t\twatch: (cb) => {\n\t\t\t\tconst controller = new AbortController()\n\n\t\t\t\twindow.addEventListener(\n\t\t\t\t\t'storage',\n\t\t\t\t\t(e) => {\n\t\t\t\t\t\tif (e.storageArea !== window[type]) return\n\n\t\t\t\t\t\tif (e.key !== key) return\n\n\t\t\t\t\t\tcb(JSON.parse(e.newValue!))\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tsignal: AbortSignal.any([\n\t\t\t\t\t\t\tabortController.signal,\n\t\t\t\t\t\t\tcontroller.signal,\n\t\t\t\t\t\t]),\n\t\t\t\t\t},\n\t\t\t\t)\n\n\t\t\t\treturn () => {\n\t\t\t\t\tcontroller.abort()\n\t\t\t\t}\n\t\t\t},\n\t\t}\n\t}\n}\n\nexport const memoryStorageAdapter: StorageAdapterCreator<{\n\tkey: string\n}> = ({ key }) => {\n\treturn ({ abortController }) => {\n\t\tconst storage = new Map<string, object>()\n\t\tconst channel = new BroadcastChannel(PACKAGE_NAME)\n\n\t\treturn {\n\t\t\tget: () => {\n\t\t\t\treturn storage.get(key) || null\n\t\t\t},\n\n\t\t\tset: (value: object) => {\n\t\t\t\tstorage.set(key, value)\n\t\t\t},\n\n\t\t\t// del: () => {\n\t\t\t// \tstorage.delete(key)\n\t\t\t// },\n\n\t\t\tbroadcast: (value: object) => {\n\t\t\t\tchannel.postMessage({ key, value })\n\t\t\t},\n\n\t\t\twatch: (cb) => {\n\t\t\t\tconst controller = new AbortController()\n\n\t\t\t\tchannel.addEventListener(\n\t\t\t\t\t'message',\n\t\t\t\t\t(e) => {\n\t\t\t\t\t\tif (e.data.key !== key) return\n\n\t\t\t\t\t\tcb(e.data.value)\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tsignal: AbortSignal.any([\n\t\t\t\t\t\t\tabortController.signal,\n\t\t\t\t\t\t\tcontroller.signal,\n\t\t\t\t\t\t]),\n\t\t\t\t\t},\n\t\t\t\t)\n\n\t\t\t\treturn () => {\n\t\t\t\t\tcontroller.abort()\n\t\t\t\t}\n\t\t\t},\n\t\t}\n\t}\n}\n","import { name as PACKAGE_NAME } from '../../package.json' with { type: 'json' }\nimport {\n\tlocalStorageAdapter,\n\ttype StorageAdapter,\n\ttype StorageAdapterCreate,\n} from './storage'\n\nexport * from './storage'\n\ntype ThemeValue = string | number | boolean\n\ntype ThemeOption<T extends ThemeValue = string> = {\n\tvalue: T\n\tmedia?: [string, T, T]\n}\n\ntype ThemeConfig<T extends ThemeValue = string> =\n\t| {\n\t\t\toptions: ReadonlyArray<T | ThemeOption<T>>\n\t\t\tinitialValue?: T\n\t }\n\t| { initialValue: T; options?: never }\n\nexport type ThemeStoreConfig = Record<\n\tstring,\n\tThemeConfig<string> | ThemeConfig<number> | ThemeConfig<boolean>\n>\n\n// { [themeKey]: { [optionKey]: ThemeOption } }\ntype KeyedThemeStoreConfig<T extends ThemeStoreConfig> = {\n\t[K in keyof T]: Record<string, ThemeOption>\n}\n\nexport type Themes<T extends ThemeStoreConfig> = {\n\t[K in keyof T]: T[K] extends { options: ReadonlyArray<infer U> }\n\t\t? U extends ThemeOption\n\t\t\t? U['value']\n\t\t\t: U\n\t\t: T[K] extends { initialValue: infer U }\n\t\t\t? U extends string\n\t\t\t\t? string\n\t\t\t\t: U extends number\n\t\t\t\t\t? number\n\t\t\t\t\t: boolean\n\t\t\t: never\n}\n\ntype Listener<T extends ThemeStoreConfig> = (value: {\n\tthemes: Themes<T>\n\tresolvedThemes: Themes<T>\n}) => void\n\ntype ThemeKeysWithSystemOption<T extends ThemeStoreConfig> = {\n\t[K in keyof T]: T[K] extends { options: ReadonlyArray<infer U> }\n\t\t? U extends { media: ReadonlyArray<unknown> }\n\t\t\t? K\n\t\t\t: never\n\t\t: never\n}[keyof T]\n\ntype NonSystemOptionValues<\n\tT extends ThemeStoreConfig,\n\tK extends keyof T,\n> = T[K] extends { options: ReadonlyArray<infer U> }\n\t? U extends ThemeValue\n\t\t? U\n\t\t: U extends ThemeOption\n\t\t\t? U extends { media: [string, string, string] }\n\t\t\t\t? never\n\t\t\t\t: U['value']\n\t\t\t: never\n\t: never\n\ntype SystemOptions<T extends ThemeStoreConfig> = {\n\t[K in ThemeKeysWithSystemOption<T>]?: [\n\t\tNonSystemOptionValues<T, K>,\n\t\tNonSystemOptionValues<T, K>,\n\t]\n}\n\ntype PersistedState<T extends ThemeStoreConfig> = {\n\tthemes: Partial<Themes<T>>\n\tsystemOptions: SystemOptions<T>\n}\n\ntype ThemeStoreOptions<T extends ThemeStoreConfig> = {\n\tinitialState?: Partial<PersistedState<T>>\n\tstorage?: StorageAdapterCreate | null\n}\n\nexport type ThemeAndOptions<T extends ThemeStoreConfig> = Array<\n\t{\n\t\t[K in keyof T]: [\n\t\t\tK,\n\t\t\tArray<\n\t\t\t\tT[K] extends { options: ReadonlyArray<infer U> }\n\t\t\t\t\t? U extends ThemeOption\n\t\t\t\t\t\t? U['value']\n\t\t\t\t\t\t: U\n\t\t\t\t\t: never\n\t\t\t>,\n\t\t]\n\t}[keyof T]\n>\n\nexport function getThemesAndOptions<T extends ThemeStoreConfig>(config: T) {\n\treturn Object.entries(config).map(([themeKey, themeConfig]) => {\n\t\treturn [\n\t\t\tthemeKey,\n\t\t\t(themeConfig.options || []).map((option) =>\n\t\t\t\ttypeof option === 'object' ? option.value : option,\n\t\t\t),\n\t\t]\n\t}) as ThemeAndOptions<T>\n}\n\nexport function getDefaultThemes<T extends ThemeStoreConfig>(config: T) {\n\treturn Object.fromEntries(\n\t\tObject.entries(config).map(([themeKey, themeConfig]) => {\n\t\t\treturn [\n\t\t\t\tthemeKey,\n\t\t\t\tthemeConfig.initialValue ??\n\t\t\t\t\t(typeof themeConfig.options[0] === 'object'\n\t\t\t\t\t\t? themeConfig.options[0].value\n\t\t\t\t\t\t: themeConfig.options[0]),\n\t\t\t]\n\t\t}),\n\t) as Themes<T>\n}\n\nclass ThemeStore<T extends ThemeStoreConfig> {\n\t#defaultThemes: Themes<T>\n\t#currentThemes: Themes<T>\n\n\t#keyedConfig: KeyedThemeStoreConfig<T>\n\n\t#systemOptions: SystemOptions<T>\n\n\t#storage: StorageAdapter | null\n\n\t#listeners: Set<Listener<T>> = new Set<Listener<T>>()\n\n\t#mediaQueryCache: Record<string, MediaQueryList>\n\n\t#abortController = new AbortController()\n\n\tconstructor(\n\t\tconfig: T,\n\t\t{\n\t\t\tinitialState = {},\n\t\t\tstorage = localStorageAdapter({ key: PACKAGE_NAME }),\n\t\t}: ThemeStoreOptions<T> = {},\n\t) {\n\t\tconst systemOptions: Record<string, [ThemeValue, ThemeValue]> = {\n\t\t\t...initialState.systemOptions,\n\t\t}\n\n\t\tconst keyedConfig = Object.fromEntries(\n\t\t\tObject.entries(config).map(([themeKey, themeConfig]) => {\n\t\t\t\tconst entries = (themeConfig.options || []).map((option) => {\n\t\t\t\t\tif (typeof option === 'object') {\n\t\t\t\t\t\tif (option.media && !Object.hasOwn(systemOptions, themeKey)) {\n\t\t\t\t\t\t\tsystemOptions[themeKey] = [option.media[1], option.media[2]]\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn [String(option.value), option]\n\t\t\t\t\t}\n\n\t\t\t\t\treturn [String(option), { value: option }]\n\t\t\t\t})\n\t\t\t\treturn [themeKey, Object.fromEntries(entries)]\n\t\t\t}),\n\t\t) as KeyedThemeStoreConfig<T>\n\n\t\tthis.#keyedConfig = keyedConfig\n\n\t\tthis.#systemOptions = systemOptions as SystemOptions<T>\n\n\t\tthis.#defaultThemes = getDefaultThemes(config)\n\n\t\tthis.#currentThemes = { ...this.#defaultThemes, ...initialState.themes }\n\n\t\tthis.#storage =\n\t\t\tstorage?.({\n\t\t\t\tabortController: this.#abortController,\n\t\t\t}) ?? null\n\n\t\tthis.#mediaQueryCache = {}\n\t}\n\n\tgetThemes = (): Themes<T> => {\n\t\treturn this.#currentThemes\n\t}\n\n\tgetResolvedThemes = (): Themes<T> => {\n\t\treturn this.#resolveThemes()\n\t}\n\n\tsetThemes = (\n\t\tthemes:\n\t\t\t| Partial<Themes<T>>\n\t\t\t| ((currentThemes: Themes<T>) => Partial<Themes<T>>),\n\t): void => {\n\t\tconst updatedThemes =\n\t\t\ttypeof themes === 'function' ? themes(this.#currentThemes) : themes\n\n\t\tthis.#setThemesAndNotify({ ...this.#currentThemes, ...updatedThemes })\n\n\t\tconst stateToPersist = this.toPersist()\n\n\t\tif (this.#storage) {\n\t\t\tthis.#storage.set(stateToPersist)\n\t\t\tthis.#storage.broadcast?.(stateToPersist)\n\t\t}\n\t}\n\n\tupdateSystemOption = <K extends ThemeKeysWithSystemOption<T>>(\n\t\tthemeKey: K,\n\t\t[ifMatch, ifNotMatch]: [\n\t\t\tNonSystemOptionValues<T, K>,\n\t\t\tNonSystemOptionValues<T, K>,\n\t\t],\n\t): void => {\n\t\tthis.#systemOptions[themeKey] = [ifMatch, ifNotMatch]\n\n\t\tthis.setThemes({ ...this.#currentThemes })\n\t}\n\n\ttoPersist = (): PersistedState<T> => {\n\t\treturn {\n\t\t\tthemes: this.#currentThemes,\n\t\t\tsystemOptions: this.#systemOptions,\n\t\t}\n\t}\n\n\trestore = (): void => {\n\t\tconst persistedState = this.#storage?.get()\n\n\t\tif (!persistedState) {\n\t\t\tthis.#setThemesAndNotify({ ...this.#defaultThemes })\n\t\t\treturn\n\t\t}\n\n\t\tthis.#systemOptions = {\n\t\t\t...this.#systemOptions,\n\t\t\t...persistedState.systemOptions,\n\t\t}\n\n\t\tthis.#setThemesAndNotify({\n\t\t\t...this.#defaultThemes,\n\t\t\t...persistedState.themes,\n\t\t})\n\t}\n\n\tsubscribe = (callback: Listener<T>): (() => void) => {\n\t\tthis.#listeners.add(callback)\n\n\t\treturn () => {\n\t\t\tthis.#listeners.delete(callback)\n\t\t}\n\t}\n\n\tsync = (): (() => void) | undefined => {\n\t\tif (!this.#storage?.watch) return\n\n\t\treturn this.#storage.watch((persistedState) => {\n\t\t\tthis.#systemOptions = (persistedState as PersistedState<T>).systemOptions\n\n\t\t\tthis.#setThemesAndNotify((persistedState as PersistedState<T>).themes)\n\t\t})\n\t}\n\n\tdestroy = (): void => {\n\t\tthis.#listeners.clear()\n\t\tthis.#abortController.abort()\n\t}\n\n\t#setThemesAndNotify = (themes: Themes<T>): void => {\n\t\tthis.#currentThemes = themes\n\t\tthis.#notify()\n\t}\n\n\t#resolveThemes = (): Themes<T> => {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(this.#currentThemes).map(([themeKey, optionKey]) => {\n\t\t\t\tconst option = this.#keyedConfig[themeKey]?.[optionKey]\n\n\t\t\t\treturn [\n\t\t\t\t\tthemeKey,\n\t\t\t\t\toption ? this.#resolveThemeOption({ themeKey, option }) : optionKey,\n\t\t\t\t]\n\t\t\t}),\n\t\t) as Themes<T>\n\t}\n\n\t#resolveThemeOption = ({\n\t\tthemeKey,\n\t\toption,\n\t}: {\n\t\tthemeKey: string\n\t\toption: ThemeOption\n\t}): string => {\n\t\tif (!option.media) return option.value\n\n\t\tif (\n\t\t\t!(\n\t\t\t\ttypeof window !== 'undefined' &&\n\t\t\t\ttypeof window.document !== 'undefined' &&\n\t\t\t\ttypeof window.document.createElement !== 'undefined'\n\t\t\t)\n\t\t) {\n\t\t\tconsole.warn(\n\t\t\t\t`[${PACKAGE_NAME}] Option with key \"media\" cannot be resolved in server environment.`,\n\t\t\t)\n\n\t\t\treturn option.value\n\t\t}\n\n\t\tconst [mediaQuery] = option.media\n\n\t\tif (!this.#mediaQueryCache[mediaQuery]) {\n\t\t\tconst mediaQueryList = window.matchMedia(mediaQuery)\n\n\t\t\tthis.#mediaQueryCache[mediaQuery] = mediaQueryList\n\n\t\t\tmediaQueryList.addEventListener(\n\t\t\t\t'change',\n\t\t\t\t() => {\n\t\t\t\t\tif (this.#currentThemes[themeKey] === option.value) {\n\t\t\t\t\t\tthis.#setThemesAndNotify({ ...this.#currentThemes })\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ signal: this.#abortController.signal },\n\t\t\t)\n\t\t}\n\n\t\tconst [ifMatch, ifNotMatch] = this.#systemOptions[themeKey]!\n\n\t\treturn this.#mediaQueryCache[mediaQuery].matches ? ifMatch : ifNotMatch\n\t}\n\n\t#notify = (): void => {\n\t\tfor (const listener of this.#listeners) {\n\t\t\tlistener({\n\t\t\t\tthemes: this.#currentThemes,\n\t\t\t\tresolvedThemes: this.#resolveThemes(),\n\t\t\t})\n\t\t}\n\t}\n}\n\nexport type { ThemeStore }\n\nexport function createThemeStore<T extends ThemeStoreConfig>(\n\tconfig: T,\n\toptions: ThemeStoreOptions<T> = {},\n): ThemeStore<T> {\n\treturn new ThemeStore<T>(config, options)\n}\n\nconst restoreThemesString = (({\n\tkey,\n\tconfig,\n}: {\n\tkey: string\n\tconfig: ThemeStoreConfig\n}) => {\n\tconst persistedThemes = JSON.parse(\n\t\tlocalStorage.getItem(key) || '{\"themes\":{}}',\n\t).themes\n\n\treturn Object.entries(config).reduce<{\n\t\tthemes: Record<string, ThemeValue>\n\t\tresolvedThemes: Record<string, ThemeValue>\n\t}>(\n\t\t(acc, [themeKey, themeConfig]) => {\n\t\t\tconst options = themeConfig.options\n\n\t\t\tconst firstOption = options?.[0]\n\n\t\t\tconst initialValue =\n\t\t\t\tpersistedThemes[themeKey] ??\n\t\t\t\tthemeConfig.initialValue ??\n\t\t\t\t(typeof firstOption === 'object' ? firstOption.value : firstOption!)\n\n\t\t\tacc.themes[themeKey] = initialValue\n\n\t\t\tif (options) {\n\t\t\t\tconst mediaOption = options.find(\n\t\t\t\t\t(option): option is Required<ThemeOption> =>\n\t\t\t\t\t\ttypeof option === 'object' &&\n\t\t\t\t\t\t!!option.media &&\n\t\t\t\t\t\toption.value === initialValue,\n\t\t\t\t)\n\n\t\t\t\tif (mediaOption) {\n\t\t\t\t\tconst [mediaQuery, ifMatch, ifNotMatch] = mediaOption.media\n\n\t\t\t\t\tacc.resolvedThemes[themeKey] = matchMedia(mediaQuery).matches\n\t\t\t\t\t\t? ifMatch\n\t\t\t\t\t\t: ifNotMatch\n\t\t\t\t} else {\n\t\t\t\t\tacc.resolvedThemes[themeKey] = initialValue\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tacc.resolvedThemes[themeKey] = initialValue\n\t\t\t}\n\n\t\t\treturn acc\n\t\t},\n\t\t{\n\t\t\tthemes: {},\n\t\t\tresolvedThemes: {},\n\t\t},\n\t)\n}).toString()\n\nexport function createInlineThemeScript(\n\tconfigs: Array<{\n\t\tkey?: string\n\t\tconfig: ThemeStoreConfig\n\t\thandler: Listener<ThemeStoreConfig>\n\t}>,\n) {\n\tconst serializedConfigs = configs.map(\n\t\t({ key = PACKAGE_NAME, config, handler }) =>\n\t\t\t`{key:${JSON.stringify(key)},config:${JSON.stringify(config)},h:${handler.toString()}}`,\n\t)\n\n\treturn `(()=>{var r=${restoreThemesString};[${serializedConfigs.join(',')}].forEach((c)=>c.h(r(c)))})()`\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["name","PACKAGE_NAME","type","StorageAdapter","get","set","value","broadcast","watch","cb","StorageAdapterCreate","abortController","AbortController","StorageAdapterCreator","options","Options","localStorageAdapter","key","JSON","parse","window","getItem","setItem","stringify","controller","addEventListener","e","storageArea","newValue","signal","AbortSignal","any","abort","memoryStorageAdapter","storage","Map","channel","BroadcastChannel","postMessage","data","name","PACKAGE_NAME","type","localStorageAdapter","StorageAdapter","StorageAdapterCreate","ThemeValue","ThemeOption","value","T","media","ThemeConfig","options","ReadonlyArray","initialValue","ThemeStoreConfig","Record","KeyedThemeStoreConfig","Themes","K","U","Listener","themes","resolvedThemes","ThemeKeysWithSystemOption","NonSystemOptionValues","SystemOptions","PersistedState","Partial","systemOptions","ThemeStoreOptions","initialState","storage","ThemeAndOptions","Array","getThemesAndOptions","config","Object","entries","map","themeKey","themeConfig","option","getDefaultThemes","fromEntries","ThemeStore","defaultThemes","currentThemes","keyedConfig","listeners","Set","mediaQueryCache","MediaQueryList","abortController","AbortController","constructor","key","hasOwn","String","getThemes","getResolvedThemes","resolveThemes","setThemes","updatedThemes","setThemesAndNotify","stateToPersist","toPersist","set","broadcast","updateSystemOption","ifMatch","ifNotMatch","restore","persistedState","get","subscribe","callback","add","delete","sync","watch","destroy","clear","abort","#setThemesAndNotify","notify","#resolveThemes","optionKey","resolveThemeOption","#resolveThemeOption","window","document","createElement","console","warn","mediaQuery","mediaQueryList","matchMedia","addEventListener","signal","matches","#notify","listener","createThemeStore","restoreThemesString","persistedThemes","JSON","parse","localStorage","getItem","reduce","acc","firstOption","mediaOption","find","Required","toString","ThemeScriptParameter","handler","createInlineThemeScript","themeScriptParameters","serializedThemeScriptParameters","stringify","join"],"sources":["../../package.json","../src/storage.ts","../src/index.ts"],"sourcesContent":["","import { name as PACKAGE_NAME } from '../../package.json' with { type: 'json' }\n\n/**\n * Pluggable persistence for `createThemeStore`.\n */\nexport type StorageAdapter = {\n\tget: () => object | null\n\tset: (value: object) => void\n\t/** Optional: notify other tabs/contexts after local `set` operation. */\n\tbroadcast?: (value: object) => void\n\t/** Optional: subscribes to other tabs/contexts' updates, returns `unsubscribe` function. */\n\twatch?: (cb: (value: object) => void) => () => void\n}\n\nexport type StorageAdapterCreate = ({\n\tabortController,\n}: {\n\tabortController: AbortController\n}) => StorageAdapter\n\nexport type StorageAdapterCreator<Options> = (\n\toptions: Options,\n) => StorageAdapterCreate\n\n/**\n * Persists theme store in `localStorage` or `sessionStorage`.\n * @example\n * ```ts\n * import { createThemeStore, localStorageAdapter } from 'resonare'\n *\n * const store = createThemeStore(\n * { mode: { options: ['light', 'dark'] },\n * { storage: localStorageAdapter({ key: 'app', type: 'localStorage' }) },\n * )\n * ```\n */\nexport const localStorageAdapter: StorageAdapterCreator<{\n\tkey: string\n\ttype?: 'localStorage' | 'sessionStorage'\n}> = ({ key, type = 'localStorage' }) => {\n\treturn ({ abortController }) => {\n\t\treturn {\n\t\t\tget: () => {\n\t\t\t\treturn JSON.parse(window[type].getItem(key) || 'null')\n\t\t\t},\n\n\t\t\tset: (value: object) => {\n\t\t\t\twindow[type].setItem(key, JSON.stringify(value))\n\t\t\t},\n\n\t\t\twatch: (cb) => {\n\t\t\t\tconst controller = new AbortController()\n\n\t\t\t\twindow.addEventListener(\n\t\t\t\t\t'storage',\n\t\t\t\t\t(e) => {\n\t\t\t\t\t\tif (e.storageArea !== window[type]) return\n\n\t\t\t\t\t\tif (e.key !== key) return\n\n\t\t\t\t\t\tcb(JSON.parse(e.newValue!))\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tsignal: AbortSignal.any([\n\t\t\t\t\t\t\tabortController.signal,\n\t\t\t\t\t\t\tcontroller.signal,\n\t\t\t\t\t\t]),\n\t\t\t\t\t},\n\t\t\t\t)\n\n\t\t\t\treturn () => {\n\t\t\t\t\tcontroller.abort()\n\t\t\t\t}\n\t\t\t},\n\t\t}\n\t}\n}\n\n/**\n * In-memory persistence and sync via `BroadcastChannel`.\n * Useful with server-side persistence.\n * @example\n * ```ts\n * import { createThemeStore, memoryStorageAdapter } from 'resonare'\n *\n * const store = createThemeStore(\n * { mode: { options: ['light', 'dark'] } },\n * { storage: memoryStorageAdapter({ key: 'preview' }) },\n * )\n * ```\n */\nexport const memoryStorageAdapter: StorageAdapterCreator<{\n\tkey: string\n}> = ({ key }) => {\n\treturn ({ abortController }) => {\n\t\tconst storage = new Map<string, object>()\n\t\tconst channel = new BroadcastChannel(PACKAGE_NAME)\n\n\t\treturn {\n\t\t\tget: () => {\n\t\t\t\treturn storage.get(key) || null\n\t\t\t},\n\n\t\t\tset: (value: object) => {\n\t\t\t\tstorage.set(key, value)\n\t\t\t},\n\n\t\t\tbroadcast: (value: object) => {\n\t\t\t\tchannel.postMessage({ key, value })\n\t\t\t},\n\n\t\t\twatch: (cb) => {\n\t\t\t\tconst controller = new AbortController()\n\n\t\t\t\tchannel.addEventListener(\n\t\t\t\t\t'message',\n\t\t\t\t\t(e) => {\n\t\t\t\t\t\tif (e.data.key !== key) return\n\n\t\t\t\t\t\tcb(e.data.value)\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tsignal: AbortSignal.any([\n\t\t\t\t\t\t\tabortController.signal,\n\t\t\t\t\t\t\tcontroller.signal,\n\t\t\t\t\t\t]),\n\t\t\t\t\t},\n\t\t\t\t)\n\n\t\t\t\treturn () => {\n\t\t\t\t\tcontroller.abort()\n\t\t\t\t}\n\t\t\t},\n\t\t}\n\t}\n}\n","import { name as PACKAGE_NAME } from '../../package.json' with { type: 'json' }\nimport {\n\tlocalStorageAdapter,\n\ttype StorageAdapter,\n\ttype StorageAdapterCreate,\n} from './storage'\n\nexport * from './storage'\n\ntype ThemeValue = string | number | boolean\n\ntype ThemeOption<T extends ThemeValue = string> = {\n\tvalue: T\n\tmedia?: [string, T, T]\n}\n\ntype ThemeConfig<T extends ThemeValue = string> =\n\t| {\n\t\t\toptions: ReadonlyArray<T | ThemeOption<T>>\n\t\t\tinitialValue?: T\n\t }\n\t| { initialValue: T; options?: never }\n\nexport type ThemeStoreConfig = Record<\n\tstring,\n\tThemeConfig<string> | ThemeConfig<number> | ThemeConfig<boolean>\n>\n\n// { [themeKey]: { [optionKey]: ThemeOption } }\ntype KeyedThemeStoreConfig<T extends ThemeStoreConfig> = {\n\t[K in keyof T]: Record<string, ThemeOption>\n}\n\nexport type Themes<T extends ThemeStoreConfig> = {\n\t[K in keyof T]: T[K] extends { options: ReadonlyArray<infer U> }\n\t\t? U extends ThemeOption\n\t\t\t? U['value']\n\t\t\t: U\n\t\t: T[K] extends { initialValue: infer U }\n\t\t\t? U extends string\n\t\t\t\t? string\n\t\t\t\t: U extends number\n\t\t\t\t\t? number\n\t\t\t\t\t: boolean\n\t\t\t: never\n}\n\ntype Listener<T extends ThemeStoreConfig> = (value: {\n\tthemes: Themes<T>\n\tresolvedThemes: Themes<T>\n}) => void\n\ntype ThemeKeysWithSystemOption<T extends ThemeStoreConfig> = {\n\t[K in keyof T]: T[K] extends { options: ReadonlyArray<infer U> }\n\t\t? U extends { media: ReadonlyArray<unknown> }\n\t\t\t? K\n\t\t\t: never\n\t\t: never\n}[keyof T]\n\ntype NonSystemOptionValues<\n\tT extends ThemeStoreConfig,\n\tK extends keyof T,\n> = T[K] extends { options: ReadonlyArray<infer U> }\n\t? U extends ThemeValue\n\t\t? U\n\t\t: U extends ThemeOption\n\t\t\t? U extends { media: [string, string, string] }\n\t\t\t\t? never\n\t\t\t\t: U['value']\n\t\t\t: never\n\t: never\n\ntype SystemOptions<T extends ThemeStoreConfig> = {\n\t[K in ThemeKeysWithSystemOption<T>]?: [\n\t\tNonSystemOptionValues<T, K>,\n\t\tNonSystemOptionValues<T, K>,\n\t]\n}\n\ntype PersistedState<T extends ThemeStoreConfig> = {\n\tthemes: Partial<Themes<T>>\n\tsystemOptions: SystemOptions<T>\n}\n\ntype ThemeStoreOptions<T extends ThemeStoreConfig> = {\n\tinitialState?: Partial<PersistedState<T>>\n\tstorage?: StorageAdapterCreate | null\n}\n\nexport type ThemeAndOptions<T extends ThemeStoreConfig> = Array<\n\t{\n\t\t[K in keyof T]: [\n\t\t\tK,\n\t\t\tArray<\n\t\t\t\tT[K] extends { options: ReadonlyArray<infer U> }\n\t\t\t\t\t? U extends ThemeOption\n\t\t\t\t\t\t? U['value']\n\t\t\t\t\t\t: U\n\t\t\t\t\t: never\n\t\t\t>,\n\t\t]\n\t}[keyof T]\n>\n\nexport function getThemesAndOptions<T extends ThemeStoreConfig>(config: T) {\n\treturn Object.entries(config).map(([themeKey, themeConfig]) => {\n\t\treturn [\n\t\t\tthemeKey,\n\t\t\t(themeConfig.options || []).map((option) =>\n\t\t\t\ttypeof option === 'object' ? option.value : option,\n\t\t\t),\n\t\t]\n\t}) as ThemeAndOptions<T>\n}\n\nexport function getDefaultThemes<T extends ThemeStoreConfig>(config: T) {\n\treturn Object.fromEntries(\n\t\tObject.entries(config).map(([themeKey, themeConfig]) => {\n\t\t\treturn [\n\t\t\t\tthemeKey,\n\t\t\t\tthemeConfig.initialValue ??\n\t\t\t\t\t(typeof themeConfig.options[0] === 'object'\n\t\t\t\t\t\t? themeConfig.options[0].value\n\t\t\t\t\t\t: themeConfig.options[0]),\n\t\t\t]\n\t\t}),\n\t) as Themes<T>\n}\n\nclass ThemeStore<T extends ThemeStoreConfig> {\n\t#defaultThemes: Themes<T>\n\t#currentThemes: Themes<T>\n\n\t#keyedConfig: KeyedThemeStoreConfig<T>\n\n\t#systemOptions: SystemOptions<T>\n\n\t#storage: StorageAdapter | null\n\n\t#listeners: Set<Listener<T>> = new Set<Listener<T>>()\n\n\t#mediaQueryCache: Record<string, MediaQueryList>\n\n\t#abortController = new AbortController()\n\n\tconstructor(\n\t\tconfig: T,\n\t\t{\n\t\t\tinitialState = {},\n\t\t\tstorage = localStorageAdapter({ key: PACKAGE_NAME }),\n\t\t}: ThemeStoreOptions<T> = {},\n\t) {\n\t\tconst systemOptions: Record<string, [ThemeValue, ThemeValue]> = {\n\t\t\t...initialState.systemOptions,\n\t\t}\n\n\t\tconst keyedConfig = Object.fromEntries(\n\t\t\tObject.entries(config).map(([themeKey, themeConfig]) => {\n\t\t\t\tconst entries = (themeConfig.options || []).map((option) => {\n\t\t\t\t\tif (typeof option === 'object') {\n\t\t\t\t\t\tif (option.media && !Object.hasOwn(systemOptions, themeKey)) {\n\t\t\t\t\t\t\tsystemOptions[themeKey] = [option.media[1], option.media[2]]\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn [String(option.value), option]\n\t\t\t\t\t}\n\n\t\t\t\t\treturn [String(option), { value: option }]\n\t\t\t\t})\n\t\t\t\treturn [themeKey, Object.fromEntries(entries)]\n\t\t\t}),\n\t\t) as KeyedThemeStoreConfig<T>\n\n\t\tthis.#keyedConfig = keyedConfig\n\n\t\tthis.#systemOptions = systemOptions as SystemOptions<T>\n\n\t\tthis.#defaultThemes = getDefaultThemes(config)\n\n\t\tthis.#currentThemes = { ...this.#defaultThemes, ...initialState.themes }\n\n\t\tthis.#storage =\n\t\t\tstorage?.({\n\t\t\t\tabortController: this.#abortController,\n\t\t\t}) ?? null\n\n\t\tthis.#mediaQueryCache = {}\n\t}\n\n\tgetThemes = (): Themes<T> => {\n\t\treturn this.#currentThemes\n\t}\n\n\tgetResolvedThemes = (): Themes<T> => {\n\t\treturn this.#resolveThemes()\n\t}\n\n\tsetThemes = (\n\t\tthemes:\n\t\t\t| Partial<Themes<T>>\n\t\t\t| ((currentThemes: Themes<T>) => Partial<Themes<T>>),\n\t): void => {\n\t\tconst updatedThemes =\n\t\t\ttypeof themes === 'function' ? themes(this.#currentThemes) : themes\n\n\t\tthis.#setThemesAndNotify({ ...this.#currentThemes, ...updatedThemes })\n\n\t\tconst stateToPersist = this.toPersist()\n\n\t\tif (this.#storage) {\n\t\t\tthis.#storage.set(stateToPersist)\n\t\t\tthis.#storage.broadcast?.(stateToPersist)\n\t\t}\n\t}\n\n\tupdateSystemOption = <K extends ThemeKeysWithSystemOption<T>>(\n\t\tthemeKey: K,\n\t\t[ifMatch, ifNotMatch]: [\n\t\t\tNonSystemOptionValues<T, K>,\n\t\t\tNonSystemOptionValues<T, K>,\n\t\t],\n\t): void => {\n\t\tthis.#systemOptions[themeKey] = [ifMatch, ifNotMatch]\n\n\t\tthis.setThemes({ ...this.#currentThemes })\n\t}\n\n\ttoPersist = (): PersistedState<T> => {\n\t\treturn {\n\t\t\tthemes: this.#currentThemes,\n\t\t\tsystemOptions: this.#systemOptions,\n\t\t}\n\t}\n\n\trestore = (): void => {\n\t\tconst persistedState = this.#storage?.get()\n\n\t\tif (!persistedState) {\n\t\t\tthis.#setThemesAndNotify({ ...this.#defaultThemes })\n\t\t\treturn\n\t\t}\n\n\t\tthis.#systemOptions = {\n\t\t\t...this.#systemOptions,\n\t\t\t...persistedState.systemOptions,\n\t\t}\n\n\t\tthis.#setThemesAndNotify({\n\t\t\t...this.#defaultThemes,\n\t\t\t...persistedState.themes,\n\t\t})\n\t}\n\n\tsubscribe = (callback: Listener<T>): (() => void) => {\n\t\tthis.#listeners.add(callback)\n\n\t\treturn () => {\n\t\t\tthis.#listeners.delete(callback)\n\t\t}\n\t}\n\n\tsync = (): (() => void) | undefined => {\n\t\tif (!this.#storage?.watch) return\n\n\t\treturn this.#storage.watch((persistedState) => {\n\t\t\tthis.#systemOptions = (persistedState as PersistedState<T>).systemOptions\n\n\t\t\tthis.#setThemesAndNotify((persistedState as PersistedState<T>).themes)\n\t\t})\n\t}\n\n\t/** Clears subscribers and aborts media-query listeners tied to this store instance. */\n\tdestroy = (): void => {\n\t\tthis.#listeners.clear()\n\t\tthis.#abortController.abort()\n\t}\n\n\t#setThemesAndNotify = (themes: Themes<T>): void => {\n\t\tthis.#currentThemes = themes\n\t\tthis.#notify()\n\t}\n\n\t#resolveThemes = (): Themes<T> => {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(this.#currentThemes).map(([themeKey, optionKey]) => {\n\t\t\t\tconst option = this.#keyedConfig[themeKey]?.[optionKey]\n\n\t\t\t\treturn [\n\t\t\t\t\tthemeKey,\n\t\t\t\t\toption ? this.#resolveThemeOption({ themeKey, option }) : optionKey,\n\t\t\t\t]\n\t\t\t}),\n\t\t) as Themes<T>\n\t}\n\n\t#resolveThemeOption = ({\n\t\tthemeKey,\n\t\toption,\n\t}: {\n\t\tthemeKey: string\n\t\toption: ThemeOption\n\t}): string => {\n\t\tif (!option.media) return option.value\n\n\t\tif (\n\t\t\t!(\n\t\t\t\ttypeof window !== 'undefined' &&\n\t\t\t\ttypeof window.document !== 'undefined' &&\n\t\t\t\ttypeof window.document.createElement !== 'undefined'\n\t\t\t)\n\t\t) {\n\t\t\tconsole.warn(\n\t\t\t\t`[${PACKAGE_NAME}] Option with key \"media\" cannot be resolved in server environment.`,\n\t\t\t)\n\n\t\t\treturn option.value\n\t\t}\n\n\t\tconst [mediaQuery] = option.media\n\n\t\tif (!this.#mediaQueryCache[mediaQuery]) {\n\t\t\tconst mediaQueryList = window.matchMedia(mediaQuery)\n\n\t\t\tthis.#mediaQueryCache[mediaQuery] = mediaQueryList\n\n\t\t\tmediaQueryList.addEventListener(\n\t\t\t\t'change',\n\t\t\t\t() => {\n\t\t\t\t\tif (this.#currentThemes[themeKey] === option.value) {\n\t\t\t\t\t\tthis.#setThemesAndNotify({ ...this.#currentThemes })\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ signal: this.#abortController.signal },\n\t\t\t)\n\t\t}\n\n\t\tconst [ifMatch, ifNotMatch] = this.#systemOptions[themeKey]!\n\n\t\treturn this.#mediaQueryCache[mediaQuery].matches ? ifMatch : ifNotMatch\n\t}\n\n\t#notify = (): void => {\n\t\tfor (const listener of this.#listeners) {\n\t\t\tlistener({\n\t\t\t\tthemes: this.#currentThemes,\n\t\t\t\tresolvedThemes: this.#resolveThemes(),\n\t\t\t})\n\t\t}\n\t}\n}\n\nexport type { ThemeStore }\n\nexport function createThemeStore<T extends ThemeStoreConfig>(\n\tconfig: T,\n\toptions: ThemeStoreOptions<T> = {},\n): ThemeStore<T> {\n\treturn new ThemeStore<T>(config, options)\n}\n\nconst restoreThemesString = (({\n\tkey,\n\tconfig,\n}: {\n\tkey: string\n\tconfig: ThemeStoreConfig\n}) => {\n\tconst persistedThemes = JSON.parse(\n\t\tlocalStorage.getItem(key) || '{\"themes\":{}}',\n\t).themes\n\n\treturn Object.entries(config).reduce<{\n\t\tthemes: Record<string, ThemeValue>\n\t\tresolvedThemes: Record<string, ThemeValue>\n\t}>(\n\t\t(acc, [themeKey, themeConfig]) => {\n\t\t\tconst options = themeConfig.options\n\n\t\t\tconst firstOption = options?.[0]\n\n\t\t\tconst initialValue =\n\t\t\t\tpersistedThemes[themeKey] ??\n\t\t\t\tthemeConfig.initialValue ??\n\t\t\t\t(typeof firstOption === 'object' ? firstOption.value : firstOption!)\n\n\t\t\tacc.themes[themeKey] = initialValue\n\n\t\t\tif (options) {\n\t\t\t\tconst mediaOption = options.find(\n\t\t\t\t\t(option): option is Required<ThemeOption> =>\n\t\t\t\t\t\ttypeof option === 'object' &&\n\t\t\t\t\t\t!!option.media &&\n\t\t\t\t\t\toption.value === initialValue,\n\t\t\t\t)\n\n\t\t\t\tif (mediaOption) {\n\t\t\t\t\tconst [mediaQuery, ifMatch, ifNotMatch] = mediaOption.media\n\n\t\t\t\t\tacc.resolvedThemes[themeKey] = matchMedia(mediaQuery).matches\n\t\t\t\t\t\t? ifMatch\n\t\t\t\t\t\t: ifNotMatch\n\t\t\t\t} else {\n\t\t\t\t\tacc.resolvedThemes[themeKey] = initialValue\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tacc.resolvedThemes[themeKey] = initialValue\n\t\t\t}\n\n\t\t\treturn acc\n\t\t},\n\t\t{\n\t\t\tthemes: {},\n\t\t\tresolvedThemes: {},\n\t\t},\n\t)\n}).toString()\n\nexport type ThemeScriptParameter = {\n\t/** `localStorage` key; defaults to the 'resonare'. */\n\tkey?: string\n\tconfig: ThemeStoreConfig\n\thandler: Listener<ThemeStoreConfig>\n}\n\n/**\n * Creates an IIFE script string that reads persisted themes from `localStorage` and runs your handlers immediately.\n *\n * Useful for avoiding flash of incorrect styles.\n * @example\n * ```tsx\n * import { createInlineThemeScript } from 'resonare'\n *\n * const inlineScript = createInlineThemeScript([\n * {\n * key: 'my-app',\n * config: { options: ['light', 'dark'] },\n * handler: ({ resolvedThemes }) => {\n * document.documentElement.dataset.mode = String(resolvedThemes.mode)\n * },\n * },\n * ])\n *\n * <script>{inlineScript}</script>\n * ```\n */\nexport function createInlineThemeScript(\n\tthemeScriptParameters: Array<ThemeScriptParameter>,\n) {\n\tconst serializedThemeScriptParameters = themeScriptParameters.map(\n\t\t({ key = PACKAGE_NAME, config, handler }) =>\n\t\t\t`{key:${JSON.stringify(key)},config:${JSON.stringify(config)},h:${handler.toString()}}`,\n\t)\n\n\treturn `(()=>{var r=${restoreThemesString};[${serializedThemeScriptParameters.join(',')}].forEach((c)=>c.h(r(c)))})()`\n}\n"],"mappings":"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"}
package/dist/react.d.ts CHANGED
@@ -1,29 +1,28 @@
1
1
  import { ThemeStore, ThemeStoreConfig, Themes } from "./index.js";
2
2
 
3
3
  //#region src/react.d.ts
4
+ /**
5
+ * Subscribes a React component to a theme store.
6
+ * @example
7
+ * ```tsx
8
+ * export function ThemeToggle() {
9
+ * const { themes, resolvedThemes, setThemes } = useResonare(store)
10
+ *
11
+ * // ...
12
+ * }
13
+ * ```
14
+ */
4
15
  declare function useResonare<T extends ThemeStoreConfig>(store: ThemeStore<T>): {
5
16
  themes: Themes<T>;
6
17
  resolvedThemes: Themes<T>;
18
+ destroy: () => void;
19
+ restore: () => void;
7
20
  setThemes: (themes: Partial<Themes<T>> | ((currentThemes: Themes<T>) => Partial<Themes<T>>)) => void;
8
- updateSystemOption: <K extends { [K_1 in keyof T]: T[K_1] extends {
9
- options: ReadonlyArray<infer U>;
10
- } ? U extends {
11
- media: ReadonlyArray<unknown>;
12
- } ? K_1 : never : never }[keyof T]>(themeKey: K, [ifMatch, ifNotMatch]: [T[K] extends {
13
- options: ReadonlyArray<infer U>;
14
- } ? U extends string | number | boolean ? U : U extends {
15
- value: string;
16
- media?: [string, string, string];
17
- } ? U extends {
18
- media: [string, string, string];
19
- } ? never : U["value"] : never : never, T[K] extends {
20
- options: ReadonlyArray<infer U>;
21
- } ? U extends string | number | boolean ? U : U extends {
22
- value: string;
23
- media?: [string, string, string];
24
- } ? U extends {
25
- media: [string, string, string];
26
- } ? never : U["value"] : never : never]) => void;
21
+ subscribe: (callback: (value: {
22
+ themes: Themes<T>;
23
+ resolvedThemes: Themes<T>;
24
+ }) => void) => (() => void);
25
+ sync: () => (() => void) | undefined;
27
26
  toPersist: () => {
28
27
  themes: Partial<Themes<T>>;
29
28
  systemOptions: { [K_1 in { [K in keyof T]: T[K] extends {
@@ -46,13 +45,25 @@ declare function useResonare<T extends ThemeStoreConfig>(store: ThemeStore<T>):
46
45
  media: [string, string, string];
47
46
  } ? never : U["value"] : never : never] };
48
47
  };
49
- restore: () => void;
50
- sync: () => (() => void) | undefined;
51
- subscribe: (callback: (value: {
52
- themes: Themes<T>;
53
- resolvedThemes: Themes<T>;
54
- }) => void) => (() => void);
55
- destroy: () => void;
48
+ updateSystemOption: <K extends { [K_1 in keyof T]: T[K_1] extends {
49
+ options: ReadonlyArray<infer U>;
50
+ } ? U extends {
51
+ media: ReadonlyArray<unknown>;
52
+ } ? K_1 : never : never }[keyof T]>(themeKey: K, [ifMatch, ifNotMatch]: [T[K] extends {
53
+ options: ReadonlyArray<infer U>;
54
+ } ? U extends string | number | boolean ? U : U extends {
55
+ value: string;
56
+ media?: [string, string, string];
57
+ } ? U extends {
58
+ media: [string, string, string];
59
+ } ? never : U["value"] : never : never, T[K] extends {
60
+ options: ReadonlyArray<infer U>;
61
+ } ? U extends string | number | boolean ? U : U extends {
62
+ value: string;
63
+ media?: [string, string, string];
64
+ } ? U extends {
65
+ media: [string, string, string];
66
+ } ? never : U["value"] : never : never]) => void;
56
67
  };
57
68
  //#endregion
58
69
  export { useResonare };
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","names":[],"sources":["../src/react.ts"],"mappings":";;;iBAGgB,WAAA,WAAsB,gBAAA,CAAA,CAAkB,KAAA,EAAO,UAAA,CAAW,CAAA"}
1
+ {"version":3,"file":"react.d.ts","names":[],"sources":["../src/react.ts"],"mappings":";;;;;AAcA;;;;;;;;;iBAAgB,WAAA,WAAsB,gBAAA,CAAA,CAAkB,KAAA,EAAO,UAAA,CAAW,CAAA"}
package/dist/react.js CHANGED
@@ -1,2 +1,2 @@
1
- import{c as e}from"react-compiler-runtime";import*as t from"react";function n(n){let r=e(12),{getThemes:i,getResolvedThemes:a,setThemes:o,updateSystemOption:s,toPersist:c,restore:l,sync:u,subscribe:d,destroy:f}=n,p=t.useSyncExternalStore(d,i,i),m;r[0]===a?m=r[1]:(m=a(),r[0]=a,r[1]=m);let h;return r[2]!==f||r[3]!==l||r[4]!==o||r[5]!==d||r[6]!==u||r[7]!==m||r[8]!==p||r[9]!==c||r[10]!==s?(h={themes:p,resolvedThemes:m,setThemes:o,updateSystemOption:s,toPersist:c,restore:l,sync:u,subscribe:d,destroy:f},r[2]=f,r[3]=l,r[4]=o,r[5]=d,r[6]=u,r[7]=m,r[8]=p,r[9]=c,r[10]=s,r[11]=h):h=r[11],h}export{n as useResonare};
1
+ import{c as e}from"react-compiler-runtime";import*as t from"react";function n(n){let r=e(12),{destroy:i,getResolvedThemes:a,getThemes:o,restore:s,setThemes:c,subscribe:l,sync:u,toPersist:d,updateSystemOption:f}=n,p=t.useSyncExternalStore(l,o,o),m;r[0]===a?m=r[1]:(m=a(),r[0]=a,r[1]=m);let h;return r[2]!==i||r[3]!==s||r[4]!==c||r[5]!==l||r[6]!==u||r[7]!==m||r[8]!==p||r[9]!==d||r[10]!==f?(h={themes:p,resolvedThemes:m,destroy:i,restore:s,setThemes:c,subscribe:l,sync:u,toPersist:d,updateSystemOption:f},r[2]=i,r[3]=s,r[4]=c,r[5]=l,r[6]=u,r[7]=m,r[8]=p,r[9]=d,r[10]=f,r[11]=h):h=r[11],h}export{n as useResonare};
2
2
  //# sourceMappingURL=react.js.map
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","names":["React","ThemeStore","ThemeStoreConfig","useResonare","store","$","_c","getThemes","getResolvedThemes","setThemes","updateSystemOption","toPersist","restore","sync","subscribe","destroy","themes","useSyncExternalStore","t0","t1","resolvedThemes"],"sources":["../src/react.ts"],"sourcesContent":["import * as React from 'react'\nimport type { ThemeStore, ThemeStoreConfig } from '.'\n\nexport function useResonare<T extends ThemeStoreConfig>(store: ThemeStore<T>) {\n\tconst {\n\t\tgetThemes,\n\t\tgetResolvedThemes,\n\t\tsetThemes,\n\t\tupdateSystemOption,\n\t\ttoPersist,\n\t\trestore,\n\t\tsync,\n\t\tsubscribe,\n\t\tdestroy,\n\t} = store\n\n\tconst themes = React.useSyncExternalStore(subscribe, getThemes, getThemes)\n\n\treturn {\n\t\tthemes,\n\t\tresolvedThemes: getResolvedThemes(),\n\t\tsetThemes,\n\t\tupdateSystemOption,\n\t\ttoPersist,\n\t\trestore,\n\t\tsync,\n\t\tsubscribe,\n\t\tdestroy,\n\t}\n}\n"],"mappings":"mEAGA,SAAOG,EAAAC,EAAA,CAAA,IAAAC,EAAAC,EAAA,GAAA,CACN,CAAAC,YAAAC,oBAAAC,YAAAC,qBAAAC,YAAAC,UAAAC,OAAAC,YAAAC,WAUIX,EAEJY,EAAehB,EAAKiB,qBAAsBH,EAAWP,EAAWA,EAAU,CAAAW,EAAAb,EAAA,KAAAG,EAItCU,EAAAb,EAAA,IAAnBa,EAAAV,GAAmB,CAAAH,EAAA,GAAAG,EAAAH,EAAA,GAAAa,GAAA,IAAAC,EAQnC,OARmCd,EAAA,KAAAU,GAAAV,EAAA,KAAAO,GAAAP,EAAA,KAAAI,GAAAJ,EAAA,KAAAS,GAAAT,EAAA,KAAAQ,GAAAR,EAAA,KAAAa,GAAAb,EAAA,KAAAW,GAAAX,EAAA,KAAAM,GAAAN,EAAA,MAAAK,GAF7BS,EAAA,CAAAH,SAAAI,eAEUF,EAAmBT,YAAAC,qBAAAC,YAAAC,UAAAC,OAAAC,YAAAC,UAQnC,CAAAV,EAAA,GAAAU,EAAAV,EAAA,GAAAO,EAAAP,EAAA,GAAAI,EAAAJ,EAAA,GAAAS,EAAAT,EAAA,GAAAQ,EAAAR,EAAA,GAAAa,EAAAb,EAAA,GAAAW,EAAAX,EAAA,GAAAM,EAAAN,EAAA,IAAAK,EAAAL,EAAA,IAAAc,GAAAA,EAAAd,EAAA,IAVMc"}
1
+ {"version":3,"file":"react.js","names":["React","ThemeStore","ThemeStoreConfig","useResonare","store","$","_c","destroy","getResolvedThemes","getThemes","restore","setThemes","subscribe","sync","toPersist","updateSystemOption","themes","useSyncExternalStore","t0","t1","resolvedThemes"],"sources":["../src/react.ts"],"sourcesContent":["import * as React from 'react'\nimport type { ThemeStore, ThemeStoreConfig } from '.'\n\n/**\n * Subscribes a React component to a theme store.\n * @example\n * ```tsx\n * export function ThemeToggle() {\n * const { themes, resolvedThemes, setThemes } = useResonare(store)\n *\n * // ...\n * }\n * ```\n */\nexport function useResonare<T extends ThemeStoreConfig>(store: ThemeStore<T>) {\n\tconst {\n\t\tdestroy,\n\t\tgetResolvedThemes,\n\t\tgetThemes,\n\t\trestore,\n\t\tsetThemes,\n\t\tsubscribe,\n\t\tsync,\n\t\ttoPersist,\n\t\tupdateSystemOption,\n\t} = store\n\n\tconst themes = React.useSyncExternalStore(subscribe, getThemes, getThemes)\n\n\treturn {\n\t\tthemes,\n\t\tresolvedThemes: getResolvedThemes(),\n\t\tdestroy,\n\t\trestore,\n\t\tsetThemes,\n\t\tsubscribe,\n\t\tsync,\n\t\ttoPersist,\n\t\tupdateSystemOption,\n\t}\n}\n"],"mappings":"mEAcA,SAAOG,EAAAC,EAAA,CAAA,IAAAC,EAAAC,EAAA,GAAA,CACN,CAAAC,UAAAC,oBAAAC,YAAAC,UAAAC,YAAAC,YAAAC,OAAAC,YAAAC,sBAUIX,EAEJY,EAAehB,EAAKiB,qBAAsBL,EAAWH,EAAWA,EAAU,CAAAS,EAAAb,EAAA,KAAAG,EAItCU,EAAAb,EAAA,IAAnBa,EAAAV,GAAmB,CAAAH,EAAA,GAAAG,EAAAH,EAAA,GAAAa,GAAA,IAAAC,EAQnC,OARmCd,EAAA,KAAAE,GAAAF,EAAA,KAAAK,GAAAL,EAAA,KAAAM,GAAAN,EAAA,KAAAO,GAAAP,EAAA,KAAAQ,GAAAR,EAAA,KAAAa,GAAAb,EAAA,KAAAW,GAAAX,EAAA,KAAAS,GAAAT,EAAA,MAAAU,GAF7BI,EAAA,CAAAH,SAAAI,eAEUF,EAAmBX,UAAAG,UAAAC,YAAAC,YAAAC,OAAAC,YAAAC,qBAQnC,CAAAV,EAAA,GAAAE,EAAAF,EAAA,GAAAK,EAAAL,EAAA,GAAAM,EAAAN,EAAA,GAAAO,EAAAP,EAAA,GAAAQ,EAAAR,EAAA,GAAAa,EAAAb,EAAA,GAAAW,EAAAX,EAAA,GAAAS,EAAAT,EAAA,IAAAU,EAAAV,EAAA,IAAAc,GAAAA,EAAAd,EAAA,IAVMc"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "resonare",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Resonare",
5
5
  "keywords": [
6
6
  "theming",