resonare 0.0.12 → 0.0.14

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,16 +1,18 @@
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 theme store for building deeply personal user interfaces.
3
+ A configuration-based store for restoring user preferences without flash of inaccurate styles.
4
4
 
5
5
  ## Features
6
6
 
7
- - Define and manage multi-dimensional themes, e.g.:
7
+ - Define and manage user preferences, e.g.:
8
8
  - Color scheme: system, light, dark
9
9
  - Contrast preference: standard, high
10
10
  - Spacing: compact, comfortable, spacious
11
+ - Showing/hiding sections
12
+ - Sidebar width
11
13
  - etc.
12
14
  - Framework-agnostic
13
- - Prevent theme flicker on page load
15
+ - Prevent flicker on page load
14
16
  - Honor system preferences
15
17
  - Create sections with independent theming
16
18
  - Sync theme selection across tabs and windows
@@ -35,7 +37,9 @@ pnpm add resonare
35
37
 
36
38
  ## Basic Usage
37
39
 
38
- It's recommended to initialize Resonare in a synchronous script to avoid theme flicker on page load. Load via CDN or inline the stringified version to reduce the number of HTTP requests.
40
+ It's recommended to initialize Resonare in a synchronous script to avoid flicker on page load.
41
+
42
+ Load via CDN:
39
43
 
40
44
  ```html
41
45
  <script src="https://unpkg.com/resonare"></script>
@@ -66,13 +70,16 @@ It's recommended to initialize Resonare in a synchronous script to avoid theme f
66
70
  })
67
71
 
68
72
  themeStore.restore()
73
+
69
74
  themeStore.sync()
70
75
  })()
71
76
  </script>
72
77
  ```
73
78
 
79
+ Alternatively, inline the stringified version to reduce the number of HTTP requests:
80
+
74
81
  ```ts
75
- import { type ThemeConfig, type ThemeStore } from 'resonare'
82
+ import type { ThemeStore, ThemeStoreConfig } from 'resonare'
76
83
  import { resonareInlineScript } from 'resonare/inline-script'
77
84
 
78
85
  const themeConfig = {
@@ -86,7 +93,7 @@ const themeConfig = {
86
93
  'dark',
87
94
  ],
88
95
  },
89
- } as const satisfies ThemeConfig
96
+ } as const satisfies ThemeStoreConfig
90
97
 
91
98
  declare module 'resonare' {
92
99
  interface ThemeStoreRegistry {
@@ -94,7 +101,7 @@ declare module 'resonare' {
94
101
  }
95
102
  }
96
103
 
97
- function initTheme({ config }: { config: ThemeConfig }) {
104
+ function initTheme({ config }: { config: ThemeStoreConfig }) {
98
105
  const themeStore = window.resonare.createThemeStore({ config })
99
106
 
100
107
  themeStore.subscribe(({ resolvedThemes }) => {
@@ -104,6 +111,7 @@ function initTheme({ config }: { config: ThemeConfig }) {
104
111
  })
105
112
 
106
113
  themeStore.restore()
114
+
107
115
  themeStore.sync()
108
116
  }
109
117
 
@@ -122,7 +130,7 @@ Add a triple-slash directive to any `.d.ts` file in your project (e.g. `env.d.ts
122
130
  ### `createThemeStore`
123
131
 
124
132
  ```ts
125
- import { createThemeStore, type ThemeConfig, type ThemeStore } from 'resonare'
133
+ import { createThemeStore, type ThemeStore, type ThemeStoreConfig } from 'resonare'
126
134
 
127
135
  const themeConfig = {
128
136
  colorScheme: {
@@ -150,7 +158,8 @@ const themeConfig = {
150
158
  ],
151
159
  initialValue: 'standard',
152
160
  },
153
- } as const satisfies ThemeConfig
161
+ sidebarWidth: 240,
162
+ } as const satisfies ThemeStoreConfig
154
163
 
155
164
  declare module 'resonare' {
156
165
  interface ThemeStoreRegistry {
@@ -204,6 +213,38 @@ const themeStore = createThemeStore({
204
213
  },
205
214
  })
206
215
  })
216
+
217
+ // get current theme selection
218
+ // e.g.: { colorScheme: 'system', contrast: 'standard', sidebarWidth: 240 }
219
+ themeStore.getThemes()
220
+
221
+ // get resolved theme selection (after media queries)
222
+ // e.g.: { colorScheme: 'dark', contrast: 'standard', sidebarWidth: 240 }
223
+ themeStore.getResolvedThemes()
224
+
225
+ // update theme
226
+ themeStore.setThemes({ colorScheme: 'light', sidebarWidth: 280 })
227
+
228
+ // get state to persist, useful for server-side persistence
229
+ // to restore, pass the returned object to createThemeStore's initialState
230
+ themeStore.toPersist()
231
+
232
+ // restore persisted state from client-side storage
233
+ themeStore.restore()
234
+
235
+ // sync theme selection across tabs/windows if supported by the storage adapter
236
+ themeStore.sync()
237
+
238
+ // subscribe to theme changes
239
+ themeStore.subscribe(({ themes, resolvedThemes }) => {
240
+ for (const [key, value] of Object.entries(resolvedThemes)) {
241
+ if (key === 'sidebarWidth') {
242
+ document.documentElement.style.setProperty('--sidebar-width', `${value}px`)
243
+ } else {
244
+ document.documentElement.dataset[key] = value
245
+ }
246
+ }
247
+ })
207
248
  ```
208
249
 
209
250
  ### `getThemeStore`
@@ -224,43 +265,6 @@ import { destroyThemeStore } from 'resonare'
224
265
  destroyThemeStore('resonare')
225
266
  ```
226
267
 
227
- ### ThemeStore Methods
228
-
229
- ```ts
230
- interface ThemeStore<T> {
231
- // get current theme selection
232
- getThemes(): Record<string, string>
233
-
234
- // get resolved theme selection (after media queries)
235
- getResolvedThemes(): Record<string, string>
236
-
237
- // update theme
238
- setThemes(themes: Partial<Record<string, string>>): void
239
-
240
- // get state to persist, useful for server-side persistence
241
- // to restore, pass the returned object to createThemeStore's initialState
242
- toPersist(): object
243
-
244
- // restore persisted state from client-side storage
245
- restore(): void
246
-
247
- // sync theme selection across tabs/windows
248
- sync(): () => void
249
-
250
- // subscribe to theme changes
251
- subscribe(
252
- callback: ({
253
- themes,
254
- resolvedThemes,
255
- }: {
256
- themes: Record<string, string>
257
- resolvedThemes: Record<string, string>
258
- }) => void,
259
- options?: { immediate?: boolean }
260
- ): () => void
261
- }
262
- ```
263
-
264
268
  ## Framework Integrations
265
269
 
266
270
  ### React
@@ -269,7 +273,7 @@ Ensure that you have initialized Resonare as per instructions under [Basic Usage
269
273
 
270
274
  ```tsx
271
275
  import * as React from 'react'
272
- import { getThemesAndOptions, type ThemeConfig } from 'resonare'
276
+ import { getThemesAndOptions, type ThemeStoreConfig } from 'resonare'
273
277
  import { useResonare } from 'resonare/react'
274
278
 
275
279
  const themeConfig = {
@@ -283,7 +287,7 @@ const themeConfig = {
283
287
  'dark',
284
288
  ],
285
289
  },
286
- } as const satisfies ThemeConfig
290
+ } as const satisfies ThemeStoreConfig
287
291
 
288
292
  function ThemeSelect() {
289
293
  const { themes, setThemes } = useResonare(() =>
@@ -321,7 +325,7 @@ import {
321
325
  createThemeStore,
322
326
  getThemesAndOptions,
323
327
  memoryStorageAdapter,
324
- type ThemeConfig,
328
+ type ThemeStoreConfig,
325
329
  } from 'resonare'
326
330
  import { useResonare } from 'resonare/react'
327
331
  import * as React from 'react'
@@ -333,7 +337,7 @@ const themeConfig = {
333
337
  contrast: {
334
338
  options: ['standard', 'high'],
335
339
  },
336
- } as const satisfies ThemeConfig
340
+ } as const satisfies ThemeStoreConfig
337
341
 
338
342
  export function ThemeSelect({ persistedStateFromDb }) {
339
343
  const [themeStore] = React.useState(() =>
@@ -357,6 +361,7 @@ export function ThemeSelect({ persistedStateFromDb }) {
357
361
  onChange={async (e) => {
358
362
  setThemes({ [theme]: e.target.value })
359
363
 
364
+ // save to server-side storage
360
365
  await saveToDb(themeStore.toPersist())
361
366
  }}
362
367
  value={themes[theme]}
package/dist/index.d.ts CHANGED
@@ -17,62 +17,58 @@ declare const localStorageAdapter: StorageAdapterCreator<{
17
17
  declare const memoryStorageAdapter: StorageAdapterCreator<never>;
18
18
  //#endregion
19
19
  //#region src/index.d.ts
20
- type ThemeOptionValue = string | number | boolean;
21
- type ThemeOption<T extends ThemeOptionValue = string> = {
20
+ type ThemeValue = string | number | boolean;
21
+ type ThemeOption<T extends ThemeValue = string> = {
22
22
  value: T;
23
23
  media?: [string, T, T];
24
24
  };
25
- type ThemeOptions<T extends ThemeOptionValue = string> = {
25
+ type ThemeConfig<T extends ThemeValue = string> = {
26
26
  options: [T | ThemeOption<T>, T | ThemeOption<T>, ...ReadonlyArray<T | ThemeOption<T>>];
27
27
  initialValue?: T;
28
- } | {
29
- initialValue: T;
30
- };
31
- type ThemeConfig = Record<string, ThemeOptions<string> | ThemeOptions<number> | ThemeOptions<boolean>>;
32
- type Themes<T extends ThemeConfig> = { [K in keyof T]: T[K] extends {
28
+ } | T;
29
+ type ThemeStoreConfig = Record<string, ThemeConfig<string> | ThemeConfig<number> | ThemeConfig<boolean>>;
30
+ type Themes<T extends ThemeStoreConfig> = { [K in keyof T]: T[K] extends {
33
31
  options: ReadonlyArray<infer U>;
34
- } ? U extends ThemeOption ? U['value'] : U : T[K] extends {
35
- initialValue: infer U;
36
- } ? U extends string ? string : U extends number ? number : boolean : never };
37
- type Listener<T extends ThemeConfig> = (value: {
32
+ } ? U extends ThemeOption ? U['value'] : U : T[K] extends infer U ? U extends string ? string : U extends number ? number : boolean : never };
33
+ type Listener<T extends ThemeStoreConfig> = (value: {
38
34
  themes: Themes<T>;
39
35
  resolvedThemes: Themes<T>;
40
36
  }) => void;
41
- type ThemeKeysWithSystemOption<T extends ThemeConfig> = { [K in keyof T]: T[K] extends {
37
+ type ThemeKeysWithSystemOption<T extends ThemeStoreConfig> = { [K in keyof T]: T[K] extends {
42
38
  options: ReadonlyArray<infer U>;
43
39
  } ? U extends {
44
40
  media: ReadonlyArray<unknown>;
45
41
  } ? K : never : never }[keyof T];
46
- type NonSystemOptionValues<T extends ThemeConfig, K extends keyof T> = T[K] extends {
42
+ type NonSystemOptionValues<T extends ThemeStoreConfig, K extends keyof T> = T[K] extends {
47
43
  options: ReadonlyArray<infer U>;
48
- } ? U extends ThemeOptionValue ? U : U extends ThemeOption ? U extends {
44
+ } ? U extends ThemeValue ? U : U extends ThemeOption ? U extends {
49
45
  media: [string, string, string];
50
46
  } ? never : U['value'] : never : never;
51
- type SystemOptions<T extends ThemeConfig> = { [K in ThemeKeysWithSystemOption<T>]?: [NonSystemOptionValues<T, K>, NonSystemOptionValues<T, K>] };
52
- type PersistedState<T extends ThemeConfig> = {
47
+ type SystemOptions<T extends ThemeStoreConfig> = { [K in ThemeKeysWithSystemOption<T>]?: [NonSystemOptionValues<T, K>, NonSystemOptionValues<T, K>] };
48
+ type PersistedState<T extends ThemeStoreConfig> = {
53
49
  version: 1;
54
50
  themes: Partial<Themes<T>>;
55
51
  systemOptions: SystemOptions<T>;
56
52
  };
57
- type ThemeStoreOptions<T extends ThemeConfig> = {
53
+ type ThemeStoreConstructor<T extends ThemeStoreConfig> = {
58
54
  key?: string;
59
55
  config: T;
60
56
  initialState?: Partial<PersistedState<T>>;
61
57
  storage?: StorageAdapterCreate | null;
62
58
  };
63
- type ThemeAndOptions<T extends ThemeConfig> = Array<{ [K in keyof T]: [K, Array<T[K] extends {
59
+ type ThemeAndOptions<T extends ThemeStoreConfig> = Array<{ [K in keyof T]: [K, Array<T[K] extends {
64
60
  options: ReadonlyArray<infer U>;
65
61
  } ? U extends ThemeOption ? U['value'] : U : never>] }[keyof T]>;
66
- declare function getThemesAndOptions<T extends ThemeConfig>(config: T): ThemeAndOptions<T>;
67
- declare function getDefaultThemes<T extends ThemeConfig>(config: T): Themes<T>;
68
- declare class ThemeStore<T extends ThemeConfig> {
62
+ declare function getThemesAndOptions<T extends ThemeStoreConfig>(config: T): ThemeAndOptions<T>;
63
+ declare function getDefaultThemes<T extends ThemeStoreConfig>(config: T): Themes<T>;
64
+ declare class ThemeStore<T extends ThemeStoreConfig> {
69
65
  #private;
70
66
  constructor({
71
67
  key,
72
68
  config,
73
69
  initialState,
74
70
  storage
75
- }: ThemeStoreOptions<T>);
71
+ }: ThemeStoreConstructor<T>);
76
72
  getThemes: () => Themes<T>;
77
73
  getResolvedThemes: () => Themes<T>;
78
74
  setThemes: (themes: Partial<Themes<T>> | ((currentThemes: Themes<T>) => Partial<Themes<T>>)) => void;
@@ -87,10 +83,10 @@ declare class ThemeStore<T extends ThemeConfig> {
87
83
  sync: () => (() => void) | undefined;
88
84
  ___destroy: () => void;
89
85
  }
90
- declare const createThemeStore: <T extends ThemeConfig>(options: ThemeStoreOptions<T>) => ThemeStore<T>;
86
+ declare const createThemeStore: <T extends ThemeStoreConfig>(params: ThemeStoreConstructor<T>) => ThemeStore<T>;
91
87
  declare const getThemeStore: <T extends keyof ThemeStoreRegistry>(key?: T | undefined) => ThemeStoreRegistry[T];
92
88
  declare const destroyThemeStore: <T extends keyof ThemeStoreRegistry>(key?: T | undefined) => void;
93
89
  interface ThemeStoreRegistry {}
94
90
  //#endregion
95
- export { StorageAdapter, StorageAdapterCreate, StorageAdapterCreator, ThemeAndOptions, ThemeConfig, ThemeStore, ThemeStoreOptions, ThemeStoreRegistry, Themes, createThemeStore, destroyThemeStore, getDefaultThemes, getThemeStore, getThemesAndOptions, localStorageAdapter, memoryStorageAdapter };
91
+ export { StorageAdapter, StorageAdapterCreate, StorageAdapterCreator, ThemeAndOptions, ThemeStore, ThemeStoreConfig, ThemeStoreRegistry, Themes, createThemeStore, destroyThemeStore, getDefaultThemes, getThemeStore, getThemesAndOptions, localStorageAdapter, memoryStorageAdapter };
96
92
  //# 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 CHANGED
@@ -1,6 +1,5 @@
1
1
  //#region package.json
2
2
  var name = "resonare";
3
-
4
3
  //#endregion
5
4
  //#region src/storage.ts
6
5
  const localStorageAdapter = ({ type = "localStorage" } = {}) => {
@@ -54,17 +53,17 @@ const memoryStorageAdapter = () => {
54
53
  };
55
54
  };
56
55
  };
57
-
58
56
  //#endregion
59
57
  //#region src/index.ts
60
58
  function getThemesAndOptions(config) {
61
- return Object.entries(config).map(([themeKey, themeOptions]) => {
62
- return [themeKey, "options" in themeOptions ? themeOptions.options.map((option) => typeof option === "string" ? option : option.value) : []];
59
+ return Object.entries(config).map(([themeKey, themeConfig]) => {
60
+ return [themeKey, typeof themeConfig === "object" ? themeConfig.options.map((option) => typeof option === "object" ? option.value : option) : []];
63
61
  });
64
62
  }
65
63
  function getDefaultThemes(config) {
66
- return Object.fromEntries(Object.entries(config).map(([themeKey, themeOptions]) => {
67
- return [themeKey, themeOptions.initialValue ?? themeOptions.options[0].value ?? themeOptions.options[0]];
64
+ return Object.fromEntries(Object.entries(config).map(([themeKey, themeConfig]) => {
65
+ if (typeof themeConfig === "object") return [themeKey, themeConfig.initialValue ?? (typeof themeConfig.options[0] === "object" ? themeConfig.options[0].value : themeConfig.options[0])];
66
+ else return [themeKey, themeConfig];
68
67
  }));
69
68
  }
70
69
  var ThemeStore = class {
@@ -77,20 +76,19 @@ var ThemeStore = class {
77
76
  #mediaQueryCache;
78
77
  #abortController = new AbortController();
79
78
  constructor({ key = name, config, initialState = {}, storage = localStorageAdapter() }) {
80
- const keyedConfig = {};
81
79
  const systemOptions = { ...initialState.systemOptions };
82
- Object.entries(config).forEach(([themeKey, themeOptions]) => {
83
- keyedConfig[themeKey] = {};
84
- if ("options" in themeOptions) themeOptions.options.forEach((option) => {
85
- if (typeof option === "object") {
86
- if (option.media && !Object.hasOwn(systemOptions, themeKey)) systemOptions[themeKey] = [option.media[1], option.media[2]];
87
- keyedConfig[themeKey][String(option.value)] = option;
88
- } else keyedConfig[themeKey][String(option)] = { value: option };
89
- });
90
- });
91
80
  this.#options = {
92
81
  key,
93
- config: keyedConfig
82
+ config: Object.fromEntries(Object.entries(config).map(([themeKey, themeConfig]) => {
83
+ const entries = typeof themeConfig === "object" ? themeConfig.options.map((option) => {
84
+ if (typeof option === "object") {
85
+ if (option.media && !Object.hasOwn(systemOptions, themeKey)) systemOptions[themeKey] = [option.media[1], option.media[2]];
86
+ return [String(option.value), option];
87
+ }
88
+ return [String(option), { value: option }];
89
+ }) : [];
90
+ return [themeKey, Object.fromEntries(entries)];
91
+ }))
94
92
  };
95
93
  this.#systemOptions = systemOptions;
96
94
  this.#defaultThemes = getDefaultThemes(config);
@@ -211,11 +209,11 @@ var ThemeStore = class {
211
209
  };
212
210
  var Registry = class {
213
211
  #registry = /* @__PURE__ */ new Map();
214
- create = (options) => {
215
- const storeKey = options.key || name;
212
+ create = (params) => {
213
+ const storeKey = params.key || name;
216
214
  let themeStore = this.#registry.get(storeKey);
217
215
  if (!themeStore) {
218
- themeStore = new ThemeStore(options);
216
+ themeStore = new ThemeStore(params);
219
217
  this.#registry.set(storeKey, themeStore);
220
218
  }
221
219
  return themeStore;
@@ -236,7 +234,7 @@ const registry = new Registry();
236
234
  const createThemeStore = registry.create;
237
235
  const getThemeStore = registry.get;
238
236
  const destroyThemeStore = registry.destroy;
239
-
240
237
  //#endregion
241
238
  export { ThemeStore, createThemeStore, destroyThemeStore, getDefaultThemes, getThemeStore, getThemesAndOptions, localStorageAdapter, memoryStorageAdapter };
239
+
242
240
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["name","PACKAGE_NAME","type","StorageAdapter","get","key","set","value","broadcast","watch","cb","StorageAdapterCreate","abortController","AbortController","StorageAdapterCreator","options","Options","localStorageAdapter","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","ThemeOptionValue","ThemeOption","value","T","media","ThemeOptions","options","ReadonlyArray","initialValue","ThemeConfig","Record","KeyedThemeConfig","Themes","K","U","Listener","themes","resolvedThemes","ThemeKeysWithSystemOption","NonSystemOptionValues","SystemOptions","PersistedState","version","Partial","systemOptions","ThemeStoreOptions","key","config","initialState","storage","ThemeAndOptions","Array","getThemesAndOptions","Object","entries","map","themeKey","themeOptions","option","getDefaultThemes","fromEntries","defaultValue","ThemeStore","defaultThemes","currentThemes","listeners","Set","mediaQueryCache","MediaQueryList","abortController","AbortController","constructor","keyedConfig","forEach","hasOwn","String","getThemes","getResolvedThemes","resolveThemes","setThemes","updatedThemes","setThemesAndNotify","stateToPersist","toPersist","set","broadcast","updateSystemOption","ifMatch","ifNotMatch","restore","persistedState","get","subscribe","callback","immediate","add","delete","sync","watch","___destroy","clear","abort","#setThemesAndNotify","notify","#resolveThemes","optionKey","resolveThemeOption","#resolveThemeOption","IIFE","window","document","createElement","console","warn","mediaQuery","mediaQueryList","matchMedia","addEventListener","signal","matches","#notify","listener","Registry","registry","Map","create","storeKey","themeStore","ThemeStoreRegistry","has","Error","destroy","createThemeStore","getThemeStore","destroyThemeStore"],"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: (key: string) => object | null\n\tset: (key: string, value: object) => void\n\t// del: (key: string) => void\n\tbroadcast?: (key: string, value: object) => void\n\twatch?: (cb: (key: string | null, 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\ttype?: 'localStorage' | 'sessionStorage'\n}> = ({ type = 'localStorage' } = {}) => {\n\treturn ({ abortController }) => {\n\t\treturn {\n\t\t\tget: (key: string) => {\n\t\t\t\treturn JSON.parse(window[type].getItem(key) || 'null')\n\t\t\t},\n\n\t\t\tset: (key: string, value: object) => {\n\t\t\t\twindow[type].setItem(key, JSON.stringify(value))\n\t\t\t},\n\n\t\t\t// del: (key: string) => {\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\tcb(e.key, 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<never> = () => {\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: (key: string) => {\n\t\t\t\treturn storage.get(key) || null\n\t\t\t},\n\n\t\t\tset: (key: string, value: object) => {\n\t\t\t\tstorage.set(key, value)\n\t\t\t},\n\n\t\t\t// del: (key: string) => {\n\t\t\t// \tstorage.delete(key)\n\t\t\t// },\n\n\t\t\tbroadcast: (key: string, 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\tcb(e.data.key, 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\ntype ThemeOptionValue = string | number | boolean\n\ntype ThemeOption<T extends ThemeOptionValue = string> = {\n\tvalue: T\n\tmedia?: [string, T, T]\n}\n\ntype ThemeOptions<T extends ThemeOptionValue = string> =\n\t| {\n\t\t\toptions: [\n\t\t\t\tT | ThemeOption<T>,\n\t\t\t\tT | ThemeOption<T>,\n\t\t\t\t...ReadonlyArray<T | ThemeOption<T>>,\n\t\t\t]\n\t\t\tinitialValue?: T\n\t }\n\t| {\n\t\t\tinitialValue: T\n\t }\n\nexport type ThemeConfig = Record<\n\tstring,\n\tThemeOptions<string> | ThemeOptions<number> | ThemeOptions<boolean>\n>\n\n// { [themeKey]: { [optionKey]: ThemeOption } }\ntype KeyedThemeConfig<T extends ThemeConfig> = {\n\t[K in keyof T]: Record<string, ThemeOption>\n}\n\nexport type Themes<T extends ThemeConfig> = {\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 ThemeConfig> = (value: {\n\tthemes: Themes<T>\n\tresolvedThemes: Themes<T>\n}) => void\n\ntype ThemeKeysWithSystemOption<T extends ThemeConfig> = {\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 ThemeConfig,\n\tK extends keyof T,\n> = T[K] extends { options: ReadonlyArray<infer U> }\n\t? U extends ThemeOptionValue\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 ThemeConfig> = {\n\t[K in ThemeKeysWithSystemOption<T>]?: [\n\t\tNonSystemOptionValues<T, K>,\n\t\tNonSystemOptionValues<T, K>,\n\t]\n}\n\ntype PersistedState<T extends ThemeConfig> = {\n\tversion: 1\n\tthemes: Partial<Themes<T>>\n\tsystemOptions: SystemOptions<T>\n}\n\nexport type ThemeStoreOptions<T extends ThemeConfig> = {\n\tkey?: string\n\tconfig: T\n\tinitialState?: Partial<PersistedState<T>>\n\tstorage?: StorageAdapterCreate | null\n}\n\nexport type ThemeAndOptions<T extends ThemeConfig> = 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 ThemeConfig>(config: T) {\n\treturn Object.entries(config).map(([themeKey, themeOptions]) => {\n\t\treturn [\n\t\t\tthemeKey,\n\t\t\t'options' in themeOptions\n\t\t\t\t? themeOptions.options.map((option) =>\n\t\t\t\t\t\ttypeof option === 'string' ? option : option.value,\n\t\t\t\t\t)\n\t\t\t\t: [],\n\t\t]\n\t}) as ThemeAndOptions<T>\n}\n\nexport function getDefaultThemes<T extends ThemeConfig>(config: T) {\n\treturn Object.fromEntries(\n\t\tObject.entries(config).map(([themeKey, themeOptions]) => {\n\t\t\tconst defaultValue =\n\t\t\t\tthemeOptions.initialValue ??\n\t\t\t\tthemeOptions.options[0].value ??\n\t\t\t\tthemeOptions.options[0]\n\n\t\t\treturn [themeKey, defaultValue]\n\t\t}),\n\t) as Themes<T>\n}\n\nexport class ThemeStore<T extends ThemeConfig> {\n\t#defaultThemes: Themes<T>\n\t#currentThemes: Themes<T>\n\n\t#options: {\n\t\tkey: string\n\t\tconfig: KeyedThemeConfig<T>\n\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\tkey = PACKAGE_NAME,\n\t\tconfig,\n\t\tinitialState = {},\n\t\tstorage = localStorageAdapter(),\n\t}: ThemeStoreOptions<T>) {\n\t\tconst keyedConfig: Record<string, Record<string, ThemeOption<any>>> = {}\n\t\tconst systemOptions: Record<string, [ThemeOptionValue, ThemeOptionValue]> =\n\t\t\t{\n\t\t\t\t...initialState.systemOptions,\n\t\t\t}\n\n\t\tObject.entries(config).forEach(([themeKey, themeOptions]) => {\n\t\t\tkeyedConfig[themeKey] = {}\n\n\t\t\tif ('options' in themeOptions) {\n\t\t\t\tthemeOptions.options.forEach((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\tkeyedConfig[themeKey]![String(option.value)] = option\n\t\t\t\t\t} else {\n\t\t\t\t\t\tkeyedConfig[themeKey]![String(option)] = { value: option }\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\n\t\tthis.#options = {\n\t\t\tkey,\n\t\t\tconfig: keyedConfig as KeyedThemeConfig<T>,\n\t\t}\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(this.#options.key, stateToPersist)\n\t\t\tthis.#storage.broadcast?.(this.#options.key, 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) => {\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\tversion: 1,\n\t\t\tthemes: this.#currentThemes,\n\t\t\tsystemOptions: this.#systemOptions,\n\t\t}\n\t}\n\n\trestore = (): void => {\n\t\tlet persistedState = this.#storage?.get(this.#options.key)\n\n\t\tif (!persistedState) {\n\t\t\tthis.#setThemesAndNotify({ ...this.#defaultThemes })\n\t\t\treturn\n\t\t}\n\n\t\t// for backward compatibility\n\t\tif (!Object.hasOwn(persistedState, 'version')) {\n\t\t\tpersistedState = {\n\t\t\t\tversion: 1,\n\t\t\t\tthemes: persistedState,\n\t\t\t\tsystemOptions: this.#systemOptions,\n\t\t\t}\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 = (\n\t\tcallback: Listener<T>,\n\t\t{ immediate = false }: { immediate?: boolean } = {},\n\t): (() => void) => {\n\t\tif (immediate) {\n\t\t\tcallback({\n\t\t\t\tthemes: this.#currentThemes,\n\t\t\t\tresolvedThemes: this.#resolveThemes(),\n\t\t\t})\n\t\t}\n\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) {\n\t\t\t// if (this.#storage) {\n\t\t\t// \tconsole.warn(\n\t\t\t// \t\t`[${PACKAGE_NAME}] No watch method was provided for storage.`,\n\t\t\t// \t)\n\t\t\t// } else {\n\t\t\t// \tconsole.warn(`[${PACKAGE_NAME}] No storage was provided.`)\n\t\t\t// }\n\n\t\t\treturn\n\t\t}\n\n\t\treturn this.#storage.watch((key, persistedState) => {\n\t\t\tif (key !== this.#options.key) return\n\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___destroy = (): 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.#options.config[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 (!IIFE) {\n\t\t\tif (\n\t\t\t\t!(\n\t\t\t\t\ttypeof window !== 'undefined' &&\n\t\t\t\t\ttypeof window.document !== 'undefined' &&\n\t\t\t\t\ttypeof window.document.createElement !== 'undefined'\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[${PACKAGE_NAME}] Option with key \"media\" cannot be resolved in server environment.`,\n\t\t\t\t)\n\n\t\t\t\treturn option.value\n\t\t\t}\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\nclass Registry {\n\t#registry = new Map<string, ThemeStore<ThemeConfig>>()\n\n\tcreate = <T extends ThemeConfig>(\n\t\toptions: ThemeStoreOptions<T>,\n\t): ThemeStore<T> => {\n\t\tconst storeKey = options.key || PACKAGE_NAME\n\n\t\tlet themeStore = this.#registry.get(storeKey) as ThemeStore<T>\n\n\t\tif (!themeStore) {\n\t\t\tthemeStore = new ThemeStore<T>(options)\n\t\t\tthis.#registry.set(storeKey, themeStore as ThemeStore<ThemeConfig>)\n\t\t}\n\n\t\treturn themeStore\n\t}\n\n\tget = <T extends keyof ThemeStoreRegistry>(key?: T) => {\n\t\tconst storeKey = key || PACKAGE_NAME\n\n\t\tif (!this.#registry.has(storeKey)) {\n\t\t\tif (IIFE) {\n\t\t\t\tthrow new Error(`Theme store '${storeKey}' not found.`)\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`[${PACKAGE_NAME}] Theme store with key '${storeKey}' could not be found. Please run \\`createThemeStore\\` with key '${storeKey}' first.`,\n\t\t\t)\n\t\t}\n\n\t\treturn this.#registry.get(storeKey)! as ThemeStoreRegistry[T]\n\t}\n\n\tdestroy = <T extends keyof ThemeStoreRegistry>(key?: T) => {\n\t\tconst storeKey = key || PACKAGE_NAME\n\n\t\tif (!this.#registry.has(storeKey)) return\n\n\t\tthis.#registry.get(storeKey)!.___destroy()\n\t\tthis.#registry.delete(storeKey)\n\t}\n}\n\nconst registry = new Registry()\n\nexport const createThemeStore = registry.create\nexport const getThemeStore = registry.get\nexport const destroyThemeStore = registry.destroy\n\nexport * from './storage'\n\nexport interface ThemeStoreRegistry {}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["name","PACKAGE_NAME","type","StorageAdapter","get","key","set","value","broadcast","watch","cb","StorageAdapterCreate","abortController","AbortController","StorageAdapterCreator","options","Options","localStorageAdapter","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","version","Partial","systemOptions","ThemeStoreConstructor","key","config","initialState","storage","ThemeAndOptions","Array","getThemesAndOptions","Object","entries","map","themeKey","themeConfig","option","getDefaultThemes","fromEntries","ThemeStore","defaultThemes","currentThemes","listeners","Set","mediaQueryCache","MediaQueryList","abortController","AbortController","constructor","keyedConfig","hasOwn","String","getThemes","getResolvedThemes","resolveThemes","setThemes","updatedThemes","setThemesAndNotify","stateToPersist","toPersist","set","broadcast","updateSystemOption","ifMatch","ifNotMatch","restore","persistedState","get","subscribe","callback","immediate","add","delete","sync","watch","___destroy","clear","abort","#setThemesAndNotify","notify","#resolveThemes","optionKey","resolveThemeOption","#resolveThemeOption","IIFE","window","document","createElement","console","warn","mediaQuery","mediaQueryList","matchMedia","addEventListener","signal","matches","#notify","listener","Registry","registry","Map","create","params","storeKey","themeStore","ThemeStoreRegistry","has","Error","destroy","createThemeStore","getThemeStore","destroyThemeStore"],"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: (key: string) => object | null\n\tset: (key: string, value: object) => void\n\t// del: (key: string) => void\n\tbroadcast?: (key: string, value: object) => void\n\twatch?: (cb: (key: string | null, 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\ttype?: 'localStorage' | 'sessionStorage'\n}> = ({ type = 'localStorage' } = {}) => {\n\treturn ({ abortController }) => {\n\t\treturn {\n\t\t\tget: (key: string) => {\n\t\t\t\treturn JSON.parse(window[type].getItem(key) || 'null')\n\t\t\t},\n\n\t\t\tset: (key: string, value: object) => {\n\t\t\t\twindow[type].setItem(key, JSON.stringify(value))\n\t\t\t},\n\n\t\t\t// del: (key: string) => {\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\tcb(e.key, 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<never> = () => {\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: (key: string) => {\n\t\t\t\treturn storage.get(key) || null\n\t\t\t},\n\n\t\t\tset: (key: string, value: object) => {\n\t\t\t\tstorage.set(key, value)\n\t\t\t},\n\n\t\t\t// del: (key: string) => {\n\t\t\t// \tstorage.delete(key)\n\t\t\t// },\n\n\t\t\tbroadcast: (key: string, 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\tcb(e.data.key, 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\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: [\n\t\t\t\tT | ThemeOption<T>,\n\t\t\t\tT | ThemeOption<T>,\n\t\t\t\t...ReadonlyArray<T | ThemeOption<T>>,\n\t\t\t]\n\t\t\tinitialValue?: T\n\t }\n\t| T\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 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\tversion: 1\n\tthemes: Partial<Themes<T>>\n\tsystemOptions: SystemOptions<T>\n}\n\ntype ThemeStoreConstructor<T extends ThemeStoreConfig> = {\n\tkey?: string\n\tconfig: T\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\ttypeof themeConfig === 'object'\n\t\t\t\t? themeConfig.options.map((option) =>\n\t\t\t\t\t\ttypeof option === 'object' ? option.value : option,\n\t\t\t\t\t)\n\t\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\tif (typeof themeConfig === 'object') {\n\t\t\t\treturn [\n\t\t\t\t\tthemeKey,\n\t\t\t\t\tthemeConfig.initialValue ??\n\t\t\t\t\t\t(typeof themeConfig.options[0] === 'object'\n\t\t\t\t\t\t\t? themeConfig.options[0].value\n\t\t\t\t\t\t\t: themeConfig.options[0]),\n\t\t\t\t]\n\t\t\t} else {\n\t\t\t\treturn [themeKey, themeConfig]\n\t\t\t}\n\t\t}),\n\t) as Themes<T>\n}\n\nexport class ThemeStore<T extends ThemeStoreConfig> {\n\t#defaultThemes: Themes<T>\n\t#currentThemes: Themes<T>\n\n\t#options: {\n\t\tkey: string\n\t\tconfig: KeyedThemeStoreConfig<T>\n\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\tkey = PACKAGE_NAME,\n\t\tconfig,\n\t\tinitialState = {},\n\t\tstorage = localStorageAdapter(),\n\t}: ThemeStoreConstructor<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 =\n\t\t\t\t\ttypeof themeConfig === 'object'\n\t\t\t\t\t\t? themeConfig.options.map((option) => {\n\t\t\t\t\t\t\t\tif (typeof option === 'object') {\n\t\t\t\t\t\t\t\t\tif (option.media && !Object.hasOwn(systemOptions, themeKey)) {\n\t\t\t\t\t\t\t\t\t\tsystemOptions[themeKey] = [option.media[1], option.media[2]]\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn [String(option.value), option]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn [String(option), { value: option }]\n\t\t\t\t\t\t\t})\n\t\t\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.#options = {\n\t\t\tkey,\n\t\t\tconfig: keyedConfig,\n\t\t}\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(this.#options.key, stateToPersist)\n\t\t\tthis.#storage.broadcast?.(this.#options.key, 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\tversion: 1,\n\t\t\tthemes: this.#currentThemes,\n\t\t\tsystemOptions: this.#systemOptions,\n\t\t}\n\t}\n\n\trestore = (): void => {\n\t\tlet persistedState = this.#storage?.get(this.#options.key)\n\n\t\tif (!persistedState) {\n\t\t\tthis.#setThemesAndNotify({ ...this.#defaultThemes })\n\t\t\treturn\n\t\t}\n\n\t\t// for backward compatibility\n\t\tif (!Object.hasOwn(persistedState, 'version')) {\n\t\t\tpersistedState = {\n\t\t\t\tversion: 1,\n\t\t\t\tthemes: persistedState,\n\t\t\t\tsystemOptions: this.#systemOptions,\n\t\t\t}\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 = (\n\t\tcallback: Listener<T>,\n\t\t{ immediate = false }: { immediate?: boolean } = {},\n\t): (() => void) => {\n\t\tif (immediate) {\n\t\t\tcallback({\n\t\t\t\tthemes: this.#currentThemes,\n\t\t\t\tresolvedThemes: this.#resolveThemes(),\n\t\t\t})\n\t\t}\n\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) {\n\t\t\t// if (this.#storage) {\n\t\t\t// \tconsole.warn(\n\t\t\t// \t\t`[${PACKAGE_NAME}] No watch method was provided for storage.`,\n\t\t\t// \t)\n\t\t\t// } else {\n\t\t\t// \tconsole.warn(`[${PACKAGE_NAME}] No storage was provided.`)\n\t\t\t// }\n\n\t\t\treturn\n\t\t}\n\n\t\treturn this.#storage.watch((key, persistedState) => {\n\t\t\tif (key !== this.#options.key) return\n\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___destroy = (): 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.#options.config[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 (!IIFE) {\n\t\t\tif (\n\t\t\t\t!(\n\t\t\t\t\ttypeof window !== 'undefined' &&\n\t\t\t\t\ttypeof window.document !== 'undefined' &&\n\t\t\t\t\ttypeof window.document.createElement !== 'undefined'\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[${PACKAGE_NAME}] Option with key \"media\" cannot be resolved in server environment.`,\n\t\t\t\t)\n\n\t\t\t\treturn option.value\n\t\t\t}\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\nclass Registry {\n\t#registry = new Map<string, ThemeStore<ThemeStoreConfig>>()\n\n\tcreate = <T extends ThemeStoreConfig>(\n\t\tparams: ThemeStoreConstructor<T>,\n\t): ThemeStore<T> => {\n\t\tconst storeKey = params.key || PACKAGE_NAME\n\n\t\tlet themeStore = this.#registry.get(storeKey) as ThemeStore<T>\n\n\t\tif (!themeStore) {\n\t\t\tthemeStore = new ThemeStore<T>(params)\n\t\t\tthis.#registry.set(storeKey, themeStore as ThemeStore<ThemeStoreConfig>)\n\t\t}\n\n\t\treturn themeStore\n\t}\n\n\tget = <T extends keyof ThemeStoreRegistry>(key?: T) => {\n\t\tconst storeKey = key || PACKAGE_NAME\n\n\t\tif (!this.#registry.has(storeKey)) {\n\t\t\tif (IIFE) {\n\t\t\t\tthrow new Error(`Theme store '${storeKey}' not found.`)\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`[${PACKAGE_NAME}] Theme store with key '${storeKey}' could not be found. Please run \\`createThemeStore\\` with key '${storeKey}' first.`,\n\t\t\t)\n\t\t}\n\n\t\treturn this.#registry.get(storeKey)! as ThemeStoreRegistry[T]\n\t}\n\n\tdestroy = <T extends keyof ThemeStoreRegistry>(key?: T) => {\n\t\tconst storeKey = key || PACKAGE_NAME\n\n\t\tif (!this.#registry.has(storeKey)) return\n\n\t\tthis.#registry.get(storeKey)!.___destroy()\n\t\tthis.#registry.delete(storeKey)\n\t}\n}\n\nconst registry = new Registry()\n\nexport const createThemeStore = registry.create\nexport const getThemeStore = registry.get\nexport const destroyThemeStore = registry.destroy\n\nexport * from './storage'\n\nexport interface ThemeStoreRegistry {}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- export const resonareInlineScript = "/**\n* resonare v0.0.12\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\nvar resonare=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=`resonare`;let n=({type:e=`localStorage`}={})=>({abortController:t})=>({get:t=>JSON.parse(window[e].getItem(t)||`null`),set:(t,n)=>{window[e].setItem(t,JSON.stringify(n))},watch:n=>{let r=new AbortController;return window.addEventListener(`storage`,t=>{t.storageArea===window[e]&&n(t.key,JSON.parse(t.newValue))},{signal:AbortSignal.any([t.signal,r.signal])}),()=>{r.abort()}}});function r(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,t.initialValue??t.options[0].value??t.options[0]]))}var i=class{#e;#t;#n;#r;#i;#a=new Set;#o;#s=new AbortController;constructor({key:e=t,config:i,initialState:a={},storage:o=n()}){let s={},c={...a.systemOptions};Object.entries(i).forEach(([e,t])=>{s[e]={},`options`in t&&t.options.forEach(t=>{typeof t==`object`?(t.media&&!Object.hasOwn(c,e)&&(c[e]=[t.media[1],t.media[2]]),s[e][String(t.value)]=t):s[e][String(t)]={value:t}})}),this.#n={key:e,config:s},this.#r=c,this.#e=r(i),this.#t={...this.#e,...a.themes},this.#i=o?.({abortController:this.#s})??null,this.#o={}}getThemes=()=>this.#t;getResolvedThemes=()=>this.#l();setThemes=e=>{let t=typeof e==`function`?e(this.#t):e;this.#c({...this.#t,...t});let n=this.toPersist();this.#i&&(this.#i.set(this.#n.key,n),this.#i.broadcast?.(this.#n.key,n))};updateSystemOption=(e,[t,n])=>{this.#r[e]=[t,n],this.setThemes({...this.#t})};toPersist=()=>({version:1,themes:this.#t,systemOptions:this.#r});restore=()=>{let e=this.#i?.get(this.#n.key);if(!e){this.#c({...this.#e});return}Object.hasOwn(e,`version`)||(e={version:1,themes:e,systemOptions:this.#r}),this.#r={...this.#r,...e.systemOptions},this.#c({...this.#e,...e.themes})};subscribe=(e,{immediate:t=!1}={})=>(t&&e({themes:this.#t,resolvedThemes:this.#l()}),this.#a.add(e),()=>{this.#a.delete(e)});sync=()=>{if(this.#i?.watch)return this.#i.watch((e,t)=>{e===this.#n.key&&(this.#r=t.systemOptions,this.#c(t.themes))})};___destroy=()=>{this.#a.clear(),this.#s.abort()};#c=e=>{this.#t=e,this.#d()};#l=()=>Object.fromEntries(Object.entries(this.#t).map(([e,t])=>{let n=this.#n.config[e]?.[t];return[e,n?this.#u({themeKey:e,option:n}):t]}));#u=({themeKey:e,option:t})=>{if(!t.media)return t.value;let[n]=t.media;if(!this.#o[n]){let r=window.matchMedia(n);this.#o[n]=r,r.addEventListener(`change`,()=>{this.#t[e]===t.value&&this.#c({...this.#t})},{signal:this.#s.signal})}let[r,i]=this.#r[e];return this.#o[n].matches?r:i};#d=()=>{for(let e of this.#a)e({themes:this.#t,resolvedThemes:this.#l()})}};let a=new class{#e=new Map;create=e=>{let n=e.key||t,r=this.#e.get(n);return r||(r=new i(e),this.#e.set(n,r)),r};get=e=>{let n=e||t;if(!this.#e.has(n))throw Error(`Theme store '${n}' not found.`);return this.#e.get(n)};destroy=e=>{let n=e||t;this.#e.has(n)&&(this.#e.get(n).___destroy(),this.#e.delete(n))}},o=a.create,s=a.get,c=a.destroy;return e.createThemeStore=o,e.destroyThemeStore=c,e.getThemeStore=s,e})({});"
1
+ export const resonareInlineScript = "/**\n* resonare v0.0.14\n*\n* This source code is licensed under the MIT license found in the\n* LICENSE file in the root directory of this source tree.\n*/\nvar resonare=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=`resonare`;let n=({type:e=`localStorage`}={})=>({abortController:t})=>({get:t=>JSON.parse(window[e].getItem(t)||`null`),set:(t,n)=>{window[e].setItem(t,JSON.stringify(n))},watch:n=>{let r=new AbortController;return window.addEventListener(`storage`,t=>{t.storageArea===window[e]&&n(t.key,JSON.parse(t.newValue))},{signal:AbortSignal.any([t.signal,r.signal])}),()=>{r.abort()}}});function r(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>typeof t==`object`?[e,t.initialValue??(typeof t.options[0]==`object`?t.options[0].value:t.options[0])]:[e,t]))}var i=class{#e;#t;#n;#r;#i;#a=new Set;#o;#s=new AbortController;constructor({key:e=t,config:i,initialState:a={},storage:o=n()}){let s={...a.systemOptions};this.#n={key:e,config:Object.fromEntries(Object.entries(i).map(([e,t])=>{let n=typeof t==`object`?t.options.map(t=>typeof t==`object`?(t.media&&!Object.hasOwn(s,e)&&(s[e]=[t.media[1],t.media[2]]),[String(t.value),t]):[String(t),{value:t}]):[];return[e,Object.fromEntries(n)]}))},this.#r=s,this.#e=r(i),this.#t={...this.#e,...a.themes},this.#i=o?.({abortController:this.#s})??null,this.#o={}}getThemes=()=>this.#t;getResolvedThemes=()=>this.#l();setThemes=e=>{let t=typeof e==`function`?e(this.#t):e;this.#c({...this.#t,...t});let n=this.toPersist();this.#i&&(this.#i.set(this.#n.key,n),this.#i.broadcast?.(this.#n.key,n))};updateSystemOption=(e,[t,n])=>{this.#r[e]=[t,n],this.setThemes({...this.#t})};toPersist=()=>({version:1,themes:this.#t,systemOptions:this.#r});restore=()=>{let e=this.#i?.get(this.#n.key);if(!e){this.#c({...this.#e});return}Object.hasOwn(e,`version`)||(e={version:1,themes:e,systemOptions:this.#r}),this.#r={...this.#r,...e.systemOptions},this.#c({...this.#e,...e.themes})};subscribe=(e,{immediate:t=!1}={})=>(t&&e({themes:this.#t,resolvedThemes:this.#l()}),this.#a.add(e),()=>{this.#a.delete(e)});sync=()=>{if(this.#i?.watch)return this.#i.watch((e,t)=>{e===this.#n.key&&(this.#r=t.systemOptions,this.#c(t.themes))})};___destroy=()=>{this.#a.clear(),this.#s.abort()};#c=e=>{this.#t=e,this.#d()};#l=()=>Object.fromEntries(Object.entries(this.#t).map(([e,t])=>{let n=this.#n.config[e]?.[t];return[e,n?this.#u({themeKey:e,option:n}):t]}));#u=({themeKey:e,option:t})=>{if(!t.media)return t.value;let[n]=t.media;if(!this.#o[n]){let r=window.matchMedia(n);this.#o[n]=r,r.addEventListener(`change`,()=>{this.#t[e]===t.value&&this.#c({...this.#t})},{signal:this.#s.signal})}let[r,i]=this.#r[e];return this.#o[n].matches?r:i};#d=()=>{for(let e of this.#a)e({themes:this.#t,resolvedThemes:this.#l()})}};let a=new class{#e=new Map;create=e=>{let n=e.key||t,r=this.#e.get(n);return r||(r=new i(e),this.#e.set(n,r)),r};get=e=>{let n=e||t;if(!this.#e.has(n))throw Error(`Theme store '${n}' not found.`);return this.#e.get(n)};destroy=e=>{let n=e||t;this.#e.has(n)&&(this.#e.get(n).___destroy(),this.#e.delete(n))}},o=a.create,s=a.get,c=a.destroy;return e.createThemeStore=o,e.destroyThemeStore=c,e.getThemeStore=s,e})({});"
package/dist/react.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { ThemeConfig, ThemeStore, Themes } from "./index.js";
1
+ import { ThemeStore, ThemeStoreConfig, Themes } from "./index.js";
2
2
 
3
3
  //#region src/react.d.ts
4
- declare function useResonare<T extends ThemeConfig>(getStore: () => ThemeStore<T>, {
4
+ declare function useResonare<T extends ThemeStoreConfig>(getStore: () => ThemeStore<T>, {
5
5
  initOnMount
6
6
  }?: {
7
7
  initOnMount?: boolean | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","names":[],"sources":["../src/react.ts"],"mappings":";;;iBAkBgB,WAAA,WAAsB,WAAA,CAAA,CACrC,QAAA,QAAgB,UAAA,CAAW,CAAA;EACzB;AAAA"}
1
+ {"version":3,"file":"react.d.ts","names":[],"sources":["../src/react.ts"],"mappings":";;;iBAkBgB,WAAA,WAAsB,gBAAA,CAAA,CACrC,QAAA,QAAgB,UAAA,CAAW,CAAA;EACzB;AAAA"}
package/dist/react.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { c } from "react-compiler-runtime";
2
2
  import * as React from "react";
3
-
4
3
  //#region src/react.ts
5
4
  function noop() {}
6
5
  const emptyObject = {};
@@ -66,7 +65,7 @@ function useResonare(getStore, t0) {
66
65
  } else t6 = $[12];
67
66
  return t6;
68
67
  }
69
-
70
68
  //#endregion
71
69
  export { useResonare };
70
+
72
71
  //# sourceMappingURL=react.js.map
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","names":["React","ThemeConfig","ThemeStore","noop","emptyObject","emptyStore","getThemes","getResolvedThemes","setThemes","updateSystemOption","toPersist","restore","sync","subscribe","useResonare","getStore","t0","$","_c","t1","undefined","initOnMount","t2","isMounted","setIsMounted","useState","t3","t4","Symbol","for","useEffect","T","themes","useSyncExternalStore","t5","t6","resolvedThemes"],"sources":["../src/react.ts"],"sourcesContent":["import * as React from 'react'\nimport type { ThemeConfig, ThemeStore } from '.'\n\nfunction noop() {}\nconst emptyObject = {}\n\nconst emptyStore = {\n\tgetThemes: () => emptyObject,\n\tgetResolvedThemes: () => emptyObject,\n\tsetThemes: noop,\n\tupdateSystemOption: noop,\n\ttoPersist: noop,\n\trestore: noop,\n\tsync: noop,\n\t// clear: noop,\n\tsubscribe: () => noop,\n}\n\nexport function useResonare<T extends ThemeConfig>(\n\tgetStore: () => ThemeStore<T>,\n\t{ initOnMount = false } = {},\n) {\n\tconst [isMounted, setIsMounted] = React.useState(initOnMount)\n\n\tReact.useEffect(() => {\n\t\tsetIsMounted(true)\n\t}, [])\n\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\t// clear,\n\t\tsubscribe,\n\t} = isMounted ? getStore() : (emptyStore as unknown as ThemeStore<T>)\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\t// clear,\n\t\tsubscribe,\n\t}\n}\n"],"mappings":";;;;AAGA,SAASG,OAAO;AAChB,MAAMC,cAAc,EAAE;AAEtB,MAAMC,aAAa;CAClBC,iBAAiBF;CACjBG,yBAAyBH;CACzBI,WAAWL;CACXM,oBAAoBN;CACpBO,WAAWP;CACXQ,SAASR;CACTS,MAAMT;CAENU,iBAAiBV;CACjB;AAED,SAAOW,YAAAC,UAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,IAAA;AAENG,OAAAH,OAAAI,SAAA,EAA4B,GAA5BJ;AAA4BC,IAAA,KAAAD;AAAAC,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAA5B,MAAA,EAAAI,aAAAC,OAAAH;CAAE,MAAAE,cAAAC,OAAAF,SAAA,QAAAE;CAEF,MAAA,CAAAC,WAAAC,gBAAkCxB,MAAKyB,SAAUJ,YAAY;CAAA,IAAAK;CAAA,IAAAC;AAAA,KAAAV,EAAA,OAAAW,OAAAC,IAAA,4BAAA,EAAA;AAE7CH,aAAA;AACfF,gBAAa,KAAK;;AAChBG,OAAA,EAAE;AAAAV,IAAA,KAAAS;AAAAT,IAAA,KAAAU;QAAA;AAAAD,OAAAT,EAAA;AAAAU,OAAAV,EAAA;;AAFLjB,OAAK8B,UAAWJ,IAEbC,GAAG;CAEN,MAAA,EAAArB,WAAAC,mBAAAC,WAAAC,oBAAAC,WAAAC,SAAAC,MAAAC,cAUIU,YAAYR,UAAqD,GAAvCV;CAE9B,MAAA2B,SAAehC,MAAKiC,qBAAsBpB,WAAWP,WAAWA,UAAU;CAIzD,MAAA4B,KAAA3B,mBAAmB;CAAA,IAAA4B;AAAA,KAAAlB,EAAA,OAAAN,WAAAM,EAAA,OAAAT,aAAAS,EAAA,OAAAJ,aAAAI,EAAA,OAAAL,QAAAK,EAAA,OAAAiB,MAAAjB,EAAA,OAAAe,UAAAf,EAAA,QAAAP,aAAAO,EAAA,QAAAR,oBAAA;AAF7B0B,OAAA;GAAAH;GAAAI,gBAEUF;GAAmB1B;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC;GAQnC;AAAAI,IAAA,KAAAN;AAAAM,IAAA,KAAAT;AAAAS,IAAA,KAAAJ;AAAAI,IAAA,KAAAL;AAAAK,IAAA,KAAAiB;AAAAjB,IAAA,KAAAe;AAAAf,IAAA,MAAAP;AAAAO,IAAA,MAAAR;AAAAQ,IAAA,MAAAkB;OAAAA,MAAAlB,EAAA;AAAA,QAVMkB"}
1
+ {"version":3,"file":"react.js","names":["React","ThemeStore","ThemeStoreConfig","noop","emptyObject","emptyStore","getThemes","getResolvedThemes","setThemes","updateSystemOption","toPersist","restore","sync","subscribe","useResonare","getStore","t0","$","_c","t1","undefined","initOnMount","t2","isMounted","setIsMounted","useState","t3","t4","Symbol","for","useEffect","T","themes","useSyncExternalStore","t5","t6","resolvedThemes"],"sources":["../src/react.ts"],"sourcesContent":["import * as React from 'react'\nimport type { ThemeStore, ThemeStoreConfig } from '.'\n\nfunction noop() {}\nconst emptyObject = {}\n\nconst emptyStore = {\n\tgetThemes: () => emptyObject,\n\tgetResolvedThemes: () => emptyObject,\n\tsetThemes: noop,\n\tupdateSystemOption: noop,\n\ttoPersist: noop,\n\trestore: noop,\n\tsync: noop,\n\t// clear: noop,\n\tsubscribe: () => noop,\n}\n\nexport function useResonare<T extends ThemeStoreConfig>(\n\tgetStore: () => ThemeStore<T>,\n\t{ initOnMount = false } = {},\n) {\n\tconst [isMounted, setIsMounted] = React.useState(initOnMount)\n\n\tReact.useEffect(() => {\n\t\tsetIsMounted(true)\n\t}, [])\n\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\t// clear,\n\t\tsubscribe,\n\t} = isMounted ? getStore() : (emptyStore as unknown as ThemeStore<T>)\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\t// clear,\n\t\tsubscribe,\n\t}\n}\n"],"mappings":";;;AAGA,SAASG,OAAO;AAChB,MAAMC,cAAc,EAAE;AAEtB,MAAMC,aAAa;CAClBC,iBAAiBF;CACjBG,yBAAyBH;CACzBI,WAAWL;CACXM,oBAAoBN;CACpBO,WAAWP;CACXQ,SAASR;CACTS,MAAMT;CAENU,iBAAiBV;CACjB;AAED,SAAOW,YAAAC,UAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,IAAA;AAENG,OAAAH,OAAAI,KAAAA,IAAA,EAA4B,GAA5BJ;AAA4BC,IAAA,KAAAD;AAAAC,IAAA,KAAAE;OAAAA,MAAAF,EAAA;CAA5B,MAAA,EAAAI,aAAAC,OAAAH;CAAE,MAAAE,cAAAC,OAAAF,KAAAA,IAAA,QAAAE;CAEF,MAAA,CAAAC,WAAAC,gBAAkCxB,MAAKyB,SAAUJ,YAAY;CAAA,IAAAK;CAAA,IAAAC;AAAA,KAAAV,EAAA,OAAAW,OAAAC,IAAA,4BAAA,EAAA;AAE7CH,aAAA;AACfF,gBAAa,KAAK;;AAChBG,OAAA,EAAE;AAAAV,IAAA,KAAAS;AAAAT,IAAA,KAAAU;QAAA;AAAAD,OAAAT,EAAA;AAAAU,OAAAV,EAAA;;AAFLjB,OAAK8B,UAAWJ,IAEbC,GAAG;CAEN,MAAA,EAAArB,WAAAC,mBAAAC,WAAAC,oBAAAC,WAAAC,SAAAC,MAAAC,cAUIU,YAAYR,UAAqD,GAAvCV;CAE9B,MAAA2B,SAAehC,MAAKiC,qBAAsBpB,WAAWP,WAAWA,UAAU;CAIzD,MAAA4B,KAAA3B,mBAAmB;CAAA,IAAA4B;AAAA,KAAAlB,EAAA,OAAAN,WAAAM,EAAA,OAAAT,aAAAS,EAAA,OAAAJ,aAAAI,EAAA,OAAAL,QAAAK,EAAA,OAAAiB,MAAAjB,EAAA,OAAAe,UAAAf,EAAA,QAAAP,aAAAO,EAAA,QAAAR,oBAAA;AAF7B0B,OAAA;GAAAH;GAAAI,gBAEUF;GAAmB1B;GAAAC;GAAAC;GAAAC;GAAAC;GAAAC;GAQnC;AAAAI,IAAA,KAAAN;AAAAM,IAAA,KAAAT;AAAAS,IAAA,KAAAJ;AAAAI,IAAA,KAAAL;AAAAK,IAAA,KAAAiB;AAAAjB,IAAA,KAAAe;AAAAf,IAAA,MAAAP;AAAAO,IAAA,MAAAR;AAAAQ,IAAA,MAAAkB;OAAAA,MAAAlB,EAAA;AAAA,QAVMkB"}
@@ -1,7 +1,7 @@
1
1
  /**
2
- * resonare v0.0.12
2
+ * resonare v0.0.14
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- var resonare=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=`resonare`;let n=({type:e=`localStorage`}={})=>({abortController:t})=>({get:t=>JSON.parse(window[e].getItem(t)||`null`),set:(t,n)=>{window[e].setItem(t,JSON.stringify(n))},watch:n=>{let r=new AbortController;return window.addEventListener(`storage`,t=>{t.storageArea===window[e]&&n(t.key,JSON.parse(t.newValue))},{signal:AbortSignal.any([t.signal,r.signal])}),()=>{r.abort()}}});function r(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,t.initialValue??t.options[0].value??t.options[0]]))}var i=class{#e;#t;#n;#r;#i;#a=new Set;#o;#s=new AbortController;constructor({key:e=t,config:i,initialState:a={},storage:o=n()}){let s={},c={...a.systemOptions};Object.entries(i).forEach(([e,t])=>{s[e]={},`options`in t&&t.options.forEach(t=>{typeof t==`object`?(t.media&&!Object.hasOwn(c,e)&&(c[e]=[t.media[1],t.media[2]]),s[e][String(t.value)]=t):s[e][String(t)]={value:t}})}),this.#n={key:e,config:s},this.#r=c,this.#e=r(i),this.#t={...this.#e,...a.themes},this.#i=o?.({abortController:this.#s})??null,this.#o={}}getThemes=()=>this.#t;getResolvedThemes=()=>this.#l();setThemes=e=>{let t=typeof e==`function`?e(this.#t):e;this.#c({...this.#t,...t});let n=this.toPersist();this.#i&&(this.#i.set(this.#n.key,n),this.#i.broadcast?.(this.#n.key,n))};updateSystemOption=(e,[t,n])=>{this.#r[e]=[t,n],this.setThemes({...this.#t})};toPersist=()=>({version:1,themes:this.#t,systemOptions:this.#r});restore=()=>{let e=this.#i?.get(this.#n.key);if(!e){this.#c({...this.#e});return}Object.hasOwn(e,`version`)||(e={version:1,themes:e,systemOptions:this.#r}),this.#r={...this.#r,...e.systemOptions},this.#c({...this.#e,...e.themes})};subscribe=(e,{immediate:t=!1}={})=>(t&&e({themes:this.#t,resolvedThemes:this.#l()}),this.#a.add(e),()=>{this.#a.delete(e)});sync=()=>{if(this.#i?.watch)return this.#i.watch((e,t)=>{e===this.#n.key&&(this.#r=t.systemOptions,this.#c(t.themes))})};___destroy=()=>{this.#a.clear(),this.#s.abort()};#c=e=>{this.#t=e,this.#d()};#l=()=>Object.fromEntries(Object.entries(this.#t).map(([e,t])=>{let n=this.#n.config[e]?.[t];return[e,n?this.#u({themeKey:e,option:n}):t]}));#u=({themeKey:e,option:t})=>{if(!t.media)return t.value;let[n]=t.media;if(!this.#o[n]){let r=window.matchMedia(n);this.#o[n]=r,r.addEventListener(`change`,()=>{this.#t[e]===t.value&&this.#c({...this.#t})},{signal:this.#s.signal})}let[r,i]=this.#r[e];return this.#o[n].matches?r:i};#d=()=>{for(let e of this.#a)e({themes:this.#t,resolvedThemes:this.#l()})}};let a=new class{#e=new Map;create=e=>{let n=e.key||t,r=this.#e.get(n);return r||(r=new i(e),this.#e.set(n,r)),r};get=e=>{let n=e||t;if(!this.#e.has(n))throw Error(`Theme store '${n}' not found.`);return this.#e.get(n)};destroy=e=>{let n=e||t;this.#e.has(n)&&(this.#e.get(n).___destroy(),this.#e.delete(n))}},o=a.create,s=a.get,c=a.destroy;return e.createThemeStore=o,e.destroyThemeStore=c,e.getThemeStore=s,e})({});
7
+ var resonare=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=`resonare`;let n=({type:e=`localStorage`}={})=>({abortController:t})=>({get:t=>JSON.parse(window[e].getItem(t)||`null`),set:(t,n)=>{window[e].setItem(t,JSON.stringify(n))},watch:n=>{let r=new AbortController;return window.addEventListener(`storage`,t=>{t.storageArea===window[e]&&n(t.key,JSON.parse(t.newValue))},{signal:AbortSignal.any([t.signal,r.signal])}),()=>{r.abort()}}});function r(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>typeof t==`object`?[e,t.initialValue??(typeof t.options[0]==`object`?t.options[0].value:t.options[0])]:[e,t]))}var i=class{#e;#t;#n;#r;#i;#a=new Set;#o;#s=new AbortController;constructor({key:e=t,config:i,initialState:a={},storage:o=n()}){let s={...a.systemOptions};this.#n={key:e,config:Object.fromEntries(Object.entries(i).map(([e,t])=>{let n=typeof t==`object`?t.options.map(t=>typeof t==`object`?(t.media&&!Object.hasOwn(s,e)&&(s[e]=[t.media[1],t.media[2]]),[String(t.value),t]):[String(t),{value:t}]):[];return[e,Object.fromEntries(n)]}))},this.#r=s,this.#e=r(i),this.#t={...this.#e,...a.themes},this.#i=o?.({abortController:this.#s})??null,this.#o={}}getThemes=()=>this.#t;getResolvedThemes=()=>this.#l();setThemes=e=>{let t=typeof e==`function`?e(this.#t):e;this.#c({...this.#t,...t});let n=this.toPersist();this.#i&&(this.#i.set(this.#n.key,n),this.#i.broadcast?.(this.#n.key,n))};updateSystemOption=(e,[t,n])=>{this.#r[e]=[t,n],this.setThemes({...this.#t})};toPersist=()=>({version:1,themes:this.#t,systemOptions:this.#r});restore=()=>{let e=this.#i?.get(this.#n.key);if(!e){this.#c({...this.#e});return}Object.hasOwn(e,`version`)||(e={version:1,themes:e,systemOptions:this.#r}),this.#r={...this.#r,...e.systemOptions},this.#c({...this.#e,...e.themes})};subscribe=(e,{immediate:t=!1}={})=>(t&&e({themes:this.#t,resolvedThemes:this.#l()}),this.#a.add(e),()=>{this.#a.delete(e)});sync=()=>{if(this.#i?.watch)return this.#i.watch((e,t)=>{e===this.#n.key&&(this.#r=t.systemOptions,this.#c(t.themes))})};___destroy=()=>{this.#a.clear(),this.#s.abort()};#c=e=>{this.#t=e,this.#d()};#l=()=>Object.fromEntries(Object.entries(this.#t).map(([e,t])=>{let n=this.#n.config[e]?.[t];return[e,n?this.#u({themeKey:e,option:n}):t]}));#u=({themeKey:e,option:t})=>{if(!t.media)return t.value;let[n]=t.media;if(!this.#o[n]){let r=window.matchMedia(n);this.#o[n]=r,r.addEventListener(`change`,()=>{this.#t[e]===t.value&&this.#c({...this.#t})},{signal:this.#s.signal})}let[r,i]=this.#r[e];return this.#o[n].matches?r:i};#d=()=>{for(let e of this.#a)e({themes:this.#t,resolvedThemes:this.#l()})}};let a=new class{#e=new Map;create=e=>{let n=e.key||t,r=this.#e.get(n);return r||(r=new i(e),this.#e.set(n,r)),r};get=e=>{let n=e||t;if(!this.#e.has(n))throw Error(`Theme store '${n}' not found.`);return this.#e.get(n)};destroy=e=>{let n=e||t;this.#e.has(n)&&(this.#e.get(n).___destroy(),this.#e.delete(n))}},o=a.create,s=a.get,c=a.destroy;return e.createThemeStore=o,e.destroyThemeStore=c,e.getThemeStore=s,e})({});
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "resonare",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "description": "Resonare",
5
5
  "keywords": [
6
- "theming"
6
+ "theming",
7
+ "dark mode",
8
+ "user preferences"
7
9
  ],
8
10
  "repository": {
9
11
  "type": "git",
@@ -41,18 +43,21 @@
41
43
  "react-compiler-runtime": "1.0.0"
42
44
  },
43
45
  "devDependencies": {
44
- "@size-limit/preset-small-lib": "12.0.0",
46
+ "@rolldown/plugin-babel": "0.2.2",
47
+ "@size-limit/preset-small-lib": "12.0.1",
48
+ "@types/node": "25.5.0",
45
49
  "@types/react": "19.2.14",
46
- "@vitejs/plugin-react": "5.1.4",
50
+ "@vitejs/plugin-react": "6.0.1",
47
51
  "babel-plugin-react-compiler": "1.0.0",
48
52
  "cross-env": "10.1.0",
49
- "jsdom": "28.1.0",
53
+ "jsdom": "29.0.1",
50
54
  "react": "19.2.4",
51
55
  "react-dom": "19.2.4",
52
- "size-limit": "12.0.0",
53
- "tsdown": "0.20.3",
56
+ "size-limit": "12.0.1",
57
+ "tsdown": "0.21.4",
54
58
  "typescript": "5.9.3",
55
- "vitest": "4.0.18"
59
+ "vite": "8.0.1",
60
+ "vitest": "4.1.0"
56
61
  },
57
62
  "peerDependencies": {
58
63
  "react": "^18.0.0 || ^19.0.0"