@vlian/framework 1.2.45 → 1.2.47

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.
@@ -53,17 +53,35 @@ let I18nManager = class I18nManager {
53
53
  ...this.snapshot
54
54
  };
55
55
  }
56
+ subscribe(listener) {
57
+ this.listeners.add(listener);
58
+ return ()=>{
59
+ this.listeners.delete(listener);
60
+ };
61
+ }
62
+ emit(next, prev) {
63
+ this.listeners.forEach((listener)=>{
64
+ listener({
65
+ ...next
66
+ }, {
67
+ ...prev
68
+ });
69
+ });
70
+ }
56
71
  async setLocale(locale) {
72
+ const prev = this.snapshot;
57
73
  this.snapshot = {
58
74
  ...this.snapshot,
59
75
  locale
60
76
  };
61
77
  (0, _library.setLang)(locale);
62
78
  await (0, _persistence.writePersistedValue)(this.config.persistence, JSON.stringify(this.snapshot));
79
+ this.emit(this.snapshot, prev);
63
80
  }
64
81
  constructor(){
65
82
  _define_property(this, "snapshot", _constants.DEFAULT_I18N);
66
83
  _define_property(this, "config", _constants.DEFAULT_CONFIG.i18n);
84
+ _define_property(this, "listeners", new Set());
67
85
  }
68
86
  };
69
87
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/kernel/manager/i18nManager.ts"],"sourcesContent":["import { setupI18n, setLang } from '../../library';\nimport type { I18nSnapshot, KernelConfig, KernelManager, KernelManagerContext } from '../types';\nimport { DEFAULT_CONFIG, DEFAULT_I18N } from '../constants';\nimport { readPersistedValue, writePersistedValue } from './persistence';\n\nexport class I18nManager implements KernelManager<I18nSnapshot> {\n private snapshot: I18nSnapshot = DEFAULT_I18N;\n private config: KernelConfig['i18n'] = DEFAULT_CONFIG.i18n;\n\n public async initialize(context: KernelManagerContext): Promise<void> {\n this.config = context.config.i18n;\n this.snapshot = { ...DEFAULT_I18N, ...(this.config.initial || {}) };\n\n const persisted = await readPersistedValue(this.config.persistence);\n if (persisted !== null) {\n try {\n const parsed = JSON.parse(persisted) as Partial<I18nSnapshot>;\n this.snapshot = { ...this.snapshot, ...parsed };\n } catch {\n // ignore parse errors\n }\n } else {\n await writePersistedValue(this.config.persistence, JSON.stringify(this.snapshot));\n }\n\n setupI18n((this.snapshot.resources || {}) as any);\n setLang(this.snapshot.locale);\n }\n\n public getSnapshot(): I18nSnapshot {\n return { ...this.snapshot };\n }\n\n public async setLocale(locale: I18nSnapshot['locale']): Promise<void> {\n this.snapshot = { ...this.snapshot, locale };\n setLang(locale);\n await writePersistedValue(this.config.persistence, JSON.stringify(this.snapshot));\n }\n}\n"],"names":["I18nManager","initialize","context","config","i18n","snapshot","DEFAULT_I18N","initial","persisted","readPersistedValue","persistence","parsed","JSON","parse","writePersistedValue","stringify","setupI18n","resources","setLang","locale","getSnapshot","setLocale","DEFAULT_CONFIG"],"mappings":";;;;+BAKaA;;;eAAAA;;;yBALsB;2BAEU;6BACW;;;;;;;;;;;;;;AAEjD,IAAA,AAAMA,cAAN,MAAMA;IAIX,MAAaC,WAAWC,OAA6B,EAAiB;QACpE,IAAI,CAACC,MAAM,GAAGD,QAAQC,MAAM,CAACC,IAAI;QACjC,IAAI,CAACC,QAAQ,GAAG;YAAE,GAAGC,uBAAY;YAAE,GAAI,IAAI,CAACH,MAAM,CAACI,OAAO,IAAI,CAAC,CAAC;QAAE;QAElE,MAAMC,YAAY,MAAMC,IAAAA,+BAAkB,EAAC,IAAI,CAACN,MAAM,CAACO,WAAW;QAClE,IAAIF,cAAc,MAAM;YACtB,IAAI;gBACF,MAAMG,SAASC,KAAKC,KAAK,CAACL;gBAC1B,IAAI,CAACH,QAAQ,GAAG;oBAAE,GAAG,IAAI,CAACA,QAAQ;oBAAE,GAAGM,MAAM;gBAAC;YAChD,EAAE,OAAM;YACN,sBAAsB;YACxB;QACF,OAAO;YACL,MAAMG,IAAAA,gCAAmB,EAAC,IAAI,CAACX,MAAM,CAACO,WAAW,EAAEE,KAAKG,SAAS,CAAC,IAAI,CAACV,QAAQ;QACjF;QAEAW,IAAAA,kBAAS,EAAE,IAAI,CAACX,QAAQ,CAACY,SAAS,IAAI,CAAC;QACvCC,IAAAA,gBAAO,EAAC,IAAI,CAACb,QAAQ,CAACc,MAAM;IAC9B;IAEOC,cAA4B;QACjC,OAAO;YAAE,GAAG,IAAI,CAACf,QAAQ;QAAC;IAC5B;IAEA,MAAagB,UAAUF,MAA8B,EAAiB;QACpE,IAAI,CAACd,QAAQ,GAAG;YAAE,GAAG,IAAI,CAACA,QAAQ;YAAEc;QAAO;QAC3CD,IAAAA,gBAAO,EAACC;QACR,MAAML,IAAAA,gCAAmB,EAAC,IAAI,CAACX,MAAM,CAACO,WAAW,EAAEE,KAAKG,SAAS,CAAC,IAAI,CAACV,QAAQ;IACjF;;QA/BA,uBAAQA,YAAyBC,uBAAY;QAC7C,uBAAQH,UAA+BmB,yBAAc,CAAClB,IAAI;;AA+B5D"}
1
+ {"version":3,"sources":["../../../src/kernel/manager/i18nManager.ts"],"sourcesContent":["import { setupI18n, setLang } from '../../library';\nimport type { I18nSnapshot, KernelConfig, KernelManager, KernelManagerContext } from '../types';\nimport { DEFAULT_CONFIG, DEFAULT_I18N } from '../constants';\nimport { readPersistedValue, writePersistedValue } from './persistence';\n\ntype I18nListener = (next: I18nSnapshot, prev: I18nSnapshot) => void;\n\nexport class I18nManager implements KernelManager<I18nSnapshot> {\n private snapshot: I18nSnapshot = DEFAULT_I18N;\n private config: KernelConfig['i18n'] = DEFAULT_CONFIG.i18n;\n private listeners = new Set<I18nListener>();\n\n public async initialize(context: KernelManagerContext): Promise<void> {\n this.config = context.config.i18n;\n this.snapshot = { ...DEFAULT_I18N, ...(this.config.initial || {}) };\n\n const persisted = await readPersistedValue(this.config.persistence);\n if (persisted !== null) {\n try {\n const parsed = JSON.parse(persisted) as Partial<I18nSnapshot>;\n this.snapshot = { ...this.snapshot, ...parsed };\n } catch {\n // ignore parse errors\n }\n } else {\n await writePersistedValue(this.config.persistence, JSON.stringify(this.snapshot));\n }\n\n setupI18n((this.snapshot.resources || {}) as any);\n setLang(this.snapshot.locale);\n }\n\n public getSnapshot(): I18nSnapshot {\n return { ...this.snapshot };\n }\n\n public subscribe(listener: I18nListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private emit(next: I18nSnapshot, prev: I18nSnapshot): void {\n this.listeners.forEach((listener) => {\n listener({ ...next }, { ...prev });\n });\n }\n\n public async setLocale(locale: I18nSnapshot['locale']): Promise<void> {\n const prev = this.snapshot;\n this.snapshot = { ...this.snapshot, locale };\n setLang(locale);\n await writePersistedValue(this.config.persistence, JSON.stringify(this.snapshot));\n this.emit(this.snapshot, prev);\n }\n}\n"],"names":["I18nManager","initialize","context","config","i18n","snapshot","DEFAULT_I18N","initial","persisted","readPersistedValue","persistence","parsed","JSON","parse","writePersistedValue","stringify","setupI18n","resources","setLang","locale","getSnapshot","subscribe","listener","listeners","add","delete","emit","next","prev","forEach","setLocale","DEFAULT_CONFIG","Set"],"mappings":";;;;+BAOaA;;;eAAAA;;;yBAPsB;2BAEU;6BACW;;;;;;;;;;;;;;AAIjD,IAAA,AAAMA,cAAN,MAAMA;IAKX,MAAaC,WAAWC,OAA6B,EAAiB;QACpE,IAAI,CAACC,MAAM,GAAGD,QAAQC,MAAM,CAACC,IAAI;QACjC,IAAI,CAACC,QAAQ,GAAG;YAAE,GAAGC,uBAAY;YAAE,GAAI,IAAI,CAACH,MAAM,CAACI,OAAO,IAAI,CAAC,CAAC;QAAE;QAElE,MAAMC,YAAY,MAAMC,IAAAA,+BAAkB,EAAC,IAAI,CAACN,MAAM,CAACO,WAAW;QAClE,IAAIF,cAAc,MAAM;YACtB,IAAI;gBACF,MAAMG,SAASC,KAAKC,KAAK,CAACL;gBAC1B,IAAI,CAACH,QAAQ,GAAG;oBAAE,GAAG,IAAI,CAACA,QAAQ;oBAAE,GAAGM,MAAM;gBAAC;YAChD,EAAE,OAAM;YACN,sBAAsB;YACxB;QACF,OAAO;YACL,MAAMG,IAAAA,gCAAmB,EAAC,IAAI,CAACX,MAAM,CAACO,WAAW,EAAEE,KAAKG,SAAS,CAAC,IAAI,CAACV,QAAQ;QACjF;QAEAW,IAAAA,kBAAS,EAAE,IAAI,CAACX,QAAQ,CAACY,SAAS,IAAI,CAAC;QACvCC,IAAAA,gBAAO,EAAC,IAAI,CAACb,QAAQ,CAACc,MAAM;IAC9B;IAEOC,cAA4B;QACjC,OAAO;YAAE,GAAG,IAAI,CAACf,QAAQ;QAAC;IAC5B;IAEOgB,UAAUC,QAAsB,EAAc;QACnD,IAAI,CAACC,SAAS,CAACC,GAAG,CAACF;QACnB,OAAO;YACL,IAAI,CAACC,SAAS,CAACE,MAAM,CAACH;QACxB;IACF;IAEQI,KAAKC,IAAkB,EAAEC,IAAkB,EAAQ;QACzD,IAAI,CAACL,SAAS,CAACM,OAAO,CAAC,CAACP;YACtBA,SAAS;gBAAE,GAAGK,IAAI;YAAC,GAAG;gBAAE,GAAGC,IAAI;YAAC;QAClC;IACF;IAEA,MAAaE,UAAUX,MAA8B,EAAiB;QACpE,MAAMS,OAAO,IAAI,CAACvB,QAAQ;QAC1B,IAAI,CAACA,QAAQ,GAAG;YAAE,GAAG,IAAI,CAACA,QAAQ;YAAEc;QAAO;QAC3CD,IAAAA,gBAAO,EAACC;QACR,MAAML,IAAAA,gCAAmB,EAAC,IAAI,CAACX,MAAM,CAACO,WAAW,EAAEE,KAAKG,SAAS,CAAC,IAAI,CAACV,QAAQ;QAC/E,IAAI,CAACqB,IAAI,CAAC,IAAI,CAACrB,QAAQ,EAAEuB;IAC3B;;QA/CA,uBAAQvB,YAAyBC,uBAAY;QAC7C,uBAAQH,UAA+B4B,yBAAc,CAAC3B,IAAI;QAC1D,uBAAQmB,aAAY,IAAIS;;AA8C1B"}
@@ -1,8 +1,13 @@
1
1
  import type { I18nSnapshot, KernelManager, KernelManagerContext } from '../types';
2
+ type I18nListener = (next: I18nSnapshot, prev: I18nSnapshot) => void;
2
3
  export declare class I18nManager implements KernelManager<I18nSnapshot> {
3
4
  private snapshot;
4
5
  private config;
6
+ private listeners;
5
7
  initialize(context: KernelManagerContext): Promise<void>;
6
8
  getSnapshot(): I18nSnapshot;
9
+ subscribe(listener: I18nListener): () => void;
10
+ private emit;
7
11
  setLocale(locale: I18nSnapshot['locale']): Promise<void>;
8
12
  }
13
+ export {};
@@ -43,17 +43,35 @@ export class I18nManager {
43
43
  ...this.snapshot
44
44
  };
45
45
  }
46
+ subscribe(listener) {
47
+ this.listeners.add(listener);
48
+ return ()=>{
49
+ this.listeners.delete(listener);
50
+ };
51
+ }
52
+ emit(next, prev) {
53
+ this.listeners.forEach((listener)=>{
54
+ listener({
55
+ ...next
56
+ }, {
57
+ ...prev
58
+ });
59
+ });
60
+ }
46
61
  async setLocale(locale) {
62
+ const prev = this.snapshot;
47
63
  this.snapshot = {
48
64
  ...this.snapshot,
49
65
  locale
50
66
  };
51
67
  setLang(locale);
52
68
  await writePersistedValue(this.config.persistence, JSON.stringify(this.snapshot));
69
+ this.emit(this.snapshot, prev);
53
70
  }
54
71
  constructor(){
55
72
  _define_property(this, "snapshot", DEFAULT_I18N);
56
73
  _define_property(this, "config", DEFAULT_CONFIG.i18n);
74
+ _define_property(this, "listeners", new Set());
57
75
  }
58
76
  }
59
77
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/kernel/manager/i18nManager.ts"],"sourcesContent":["import { setupI18n, setLang } from '../../library';\nimport type { I18nSnapshot, KernelConfig, KernelManager, KernelManagerContext } from '../types';\nimport { DEFAULT_CONFIG, DEFAULT_I18N } from '../constants';\nimport { readPersistedValue, writePersistedValue } from './persistence';\n\nexport class I18nManager implements KernelManager<I18nSnapshot> {\n private snapshot: I18nSnapshot = DEFAULT_I18N;\n private config: KernelConfig['i18n'] = DEFAULT_CONFIG.i18n;\n\n public async initialize(context: KernelManagerContext): Promise<void> {\n this.config = context.config.i18n;\n this.snapshot = { ...DEFAULT_I18N, ...(this.config.initial || {}) };\n\n const persisted = await readPersistedValue(this.config.persistence);\n if (persisted !== null) {\n try {\n const parsed = JSON.parse(persisted) as Partial<I18nSnapshot>;\n this.snapshot = { ...this.snapshot, ...parsed };\n } catch {\n // ignore parse errors\n }\n } else {\n await writePersistedValue(this.config.persistence, JSON.stringify(this.snapshot));\n }\n\n setupI18n((this.snapshot.resources || {}) as any);\n setLang(this.snapshot.locale);\n }\n\n public getSnapshot(): I18nSnapshot {\n return { ...this.snapshot };\n }\n\n public async setLocale(locale: I18nSnapshot['locale']): Promise<void> {\n this.snapshot = { ...this.snapshot, locale };\n setLang(locale);\n await writePersistedValue(this.config.persistence, JSON.stringify(this.snapshot));\n }\n}\n"],"names":["setupI18n","setLang","DEFAULT_CONFIG","DEFAULT_I18N","readPersistedValue","writePersistedValue","I18nManager","initialize","context","config","i18n","snapshot","initial","persisted","persistence","parsed","JSON","parse","stringify","resources","locale","getSnapshot","setLocale"],"mappings":";;;;;;;;;;;;;AAAA,SAASA,SAAS,EAAEC,OAAO,QAAQ,gBAAgB;AAEnD,SAASC,cAAc,EAAEC,YAAY,QAAQ,eAAe;AAC5D,SAASC,kBAAkB,EAAEC,mBAAmB,QAAQ,gBAAgB;AAExE,OAAO,MAAMC;IAIX,MAAaC,WAAWC,OAA6B,EAAiB;QACpE,IAAI,CAACC,MAAM,GAAGD,QAAQC,MAAM,CAACC,IAAI;QACjC,IAAI,CAACC,QAAQ,GAAG;YAAE,GAAGR,YAAY;YAAE,GAAI,IAAI,CAACM,MAAM,CAACG,OAAO,IAAI,CAAC,CAAC;QAAE;QAElE,MAAMC,YAAY,MAAMT,mBAAmB,IAAI,CAACK,MAAM,CAACK,WAAW;QAClE,IAAID,cAAc,MAAM;YACtB,IAAI;gBACF,MAAME,SAASC,KAAKC,KAAK,CAACJ;gBAC1B,IAAI,CAACF,QAAQ,GAAG;oBAAE,GAAG,IAAI,CAACA,QAAQ;oBAAE,GAAGI,MAAM;gBAAC;YAChD,EAAE,OAAM;YACN,sBAAsB;YACxB;QACF,OAAO;YACL,MAAMV,oBAAoB,IAAI,CAACI,MAAM,CAACK,WAAW,EAAEE,KAAKE,SAAS,CAAC,IAAI,CAACP,QAAQ;QACjF;QAEAX,UAAW,IAAI,CAACW,QAAQ,CAACQ,SAAS,IAAI,CAAC;QACvClB,QAAQ,IAAI,CAACU,QAAQ,CAACS,MAAM;IAC9B;IAEOC,cAA4B;QACjC,OAAO;YAAE,GAAG,IAAI,CAACV,QAAQ;QAAC;IAC5B;IAEA,MAAaW,UAAUF,MAA8B,EAAiB;QACpE,IAAI,CAACT,QAAQ,GAAG;YAAE,GAAG,IAAI,CAACA,QAAQ;YAAES;QAAO;QAC3CnB,QAAQmB;QACR,MAAMf,oBAAoB,IAAI,CAACI,MAAM,CAACK,WAAW,EAAEE,KAAKE,SAAS,CAAC,IAAI,CAACP,QAAQ;IACjF;;QA/BA,uBAAQA,YAAyBR;QACjC,uBAAQM,UAA+BP,eAAeQ,IAAI;;AA+B5D"}
1
+ {"version":3,"sources":["../../../src/kernel/manager/i18nManager.ts"],"sourcesContent":["import { setupI18n, setLang } from '../../library';\nimport type { I18nSnapshot, KernelConfig, KernelManager, KernelManagerContext } from '../types';\nimport { DEFAULT_CONFIG, DEFAULT_I18N } from '../constants';\nimport { readPersistedValue, writePersistedValue } from './persistence';\n\ntype I18nListener = (next: I18nSnapshot, prev: I18nSnapshot) => void;\n\nexport class I18nManager implements KernelManager<I18nSnapshot> {\n private snapshot: I18nSnapshot = DEFAULT_I18N;\n private config: KernelConfig['i18n'] = DEFAULT_CONFIG.i18n;\n private listeners = new Set<I18nListener>();\n\n public async initialize(context: KernelManagerContext): Promise<void> {\n this.config = context.config.i18n;\n this.snapshot = { ...DEFAULT_I18N, ...(this.config.initial || {}) };\n\n const persisted = await readPersistedValue(this.config.persistence);\n if (persisted !== null) {\n try {\n const parsed = JSON.parse(persisted) as Partial<I18nSnapshot>;\n this.snapshot = { ...this.snapshot, ...parsed };\n } catch {\n // ignore parse errors\n }\n } else {\n await writePersistedValue(this.config.persistence, JSON.stringify(this.snapshot));\n }\n\n setupI18n((this.snapshot.resources || {}) as any);\n setLang(this.snapshot.locale);\n }\n\n public getSnapshot(): I18nSnapshot {\n return { ...this.snapshot };\n }\n\n public subscribe(listener: I18nListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private emit(next: I18nSnapshot, prev: I18nSnapshot): void {\n this.listeners.forEach((listener) => {\n listener({ ...next }, { ...prev });\n });\n }\n\n public async setLocale(locale: I18nSnapshot['locale']): Promise<void> {\n const prev = this.snapshot;\n this.snapshot = { ...this.snapshot, locale };\n setLang(locale);\n await writePersistedValue(this.config.persistence, JSON.stringify(this.snapshot));\n this.emit(this.snapshot, prev);\n }\n}\n"],"names":["setupI18n","setLang","DEFAULT_CONFIG","DEFAULT_I18N","readPersistedValue","writePersistedValue","I18nManager","initialize","context","config","i18n","snapshot","initial","persisted","persistence","parsed","JSON","parse","stringify","resources","locale","getSnapshot","subscribe","listener","listeners","add","delete","emit","next","prev","forEach","setLocale","Set"],"mappings":";;;;;;;;;;;;;AAAA,SAASA,SAAS,EAAEC,OAAO,QAAQ,gBAAgB;AAEnD,SAASC,cAAc,EAAEC,YAAY,QAAQ,eAAe;AAC5D,SAASC,kBAAkB,EAAEC,mBAAmB,QAAQ,gBAAgB;AAIxE,OAAO,MAAMC;IAKX,MAAaC,WAAWC,OAA6B,EAAiB;QACpE,IAAI,CAACC,MAAM,GAAGD,QAAQC,MAAM,CAACC,IAAI;QACjC,IAAI,CAACC,QAAQ,GAAG;YAAE,GAAGR,YAAY;YAAE,GAAI,IAAI,CAACM,MAAM,CAACG,OAAO,IAAI,CAAC,CAAC;QAAE;QAElE,MAAMC,YAAY,MAAMT,mBAAmB,IAAI,CAACK,MAAM,CAACK,WAAW;QAClE,IAAID,cAAc,MAAM;YACtB,IAAI;gBACF,MAAME,SAASC,KAAKC,KAAK,CAACJ;gBAC1B,IAAI,CAACF,QAAQ,GAAG;oBAAE,GAAG,IAAI,CAACA,QAAQ;oBAAE,GAAGI,MAAM;gBAAC;YAChD,EAAE,OAAM;YACN,sBAAsB;YACxB;QACF,OAAO;YACL,MAAMV,oBAAoB,IAAI,CAACI,MAAM,CAACK,WAAW,EAAEE,KAAKE,SAAS,CAAC,IAAI,CAACP,QAAQ;QACjF;QAEAX,UAAW,IAAI,CAACW,QAAQ,CAACQ,SAAS,IAAI,CAAC;QACvClB,QAAQ,IAAI,CAACU,QAAQ,CAACS,MAAM;IAC9B;IAEOC,cAA4B;QACjC,OAAO;YAAE,GAAG,IAAI,CAACV,QAAQ;QAAC;IAC5B;IAEOW,UAAUC,QAAsB,EAAc;QACnD,IAAI,CAACC,SAAS,CAACC,GAAG,CAACF;QACnB,OAAO;YACL,IAAI,CAACC,SAAS,CAACE,MAAM,CAACH;QACxB;IACF;IAEQI,KAAKC,IAAkB,EAAEC,IAAkB,EAAQ;QACzD,IAAI,CAACL,SAAS,CAACM,OAAO,CAAC,CAACP;YACtBA,SAAS;gBAAE,GAAGK,IAAI;YAAC,GAAG;gBAAE,GAAGC,IAAI;YAAC;QAClC;IACF;IAEA,MAAaE,UAAUX,MAA8B,EAAiB;QACpE,MAAMS,OAAO,IAAI,CAAClB,QAAQ;QAC1B,IAAI,CAACA,QAAQ,GAAG;YAAE,GAAG,IAAI,CAACA,QAAQ;YAAES;QAAO;QAC3CnB,QAAQmB;QACR,MAAMf,oBAAoB,IAAI,CAACI,MAAM,CAACK,WAAW,EAAEE,KAAKE,SAAS,CAAC,IAAI,CAACP,QAAQ;QAC/E,IAAI,CAACgB,IAAI,CAAC,IAAI,CAAChB,QAAQ,EAAEkB;IAC3B;;QA/CA,uBAAQlB,YAAyBR;QACjC,uBAAQM,UAA+BP,eAAeQ,IAAI;QAC1D,uBAAQc,aAAY,IAAIQ;;AA8C1B"}
@@ -68,12 +68,29 @@ let ThemeManager = class ThemeManager {
68
68
  ...this.theme
69
69
  };
70
70
  }
71
+ subscribe(listener) {
72
+ this.listeners.add(listener);
73
+ return ()=>{
74
+ this.listeners.delete(listener);
75
+ };
76
+ }
77
+ emit(next, prev) {
78
+ this.listeners.forEach((listener)=>{
79
+ listener({
80
+ ...next
81
+ }, {
82
+ ...prev
83
+ });
84
+ });
85
+ }
71
86
  async setTheme(nextTheme) {
87
+ const prev = this.theme;
72
88
  this.theme = {
73
89
  ...nextTheme
74
90
  };
75
91
  applyThemeToDocument(this.theme);
76
92
  await (0, _persistence.writePersistedValue)(this.config.persistence, JSON.stringify(this.theme));
93
+ this.emit(this.theme, prev);
77
94
  }
78
95
  getSnapshot() {
79
96
  return this.getTheme();
@@ -81,6 +98,7 @@ let ThemeManager = class ThemeManager {
81
98
  constructor(){
82
99
  _define_property(this, "theme", _constants.DEFAULT_THEME);
83
100
  _define_property(this, "config", _constants.DEFAULT_CONFIG.theme);
101
+ _define_property(this, "listeners", new Set());
84
102
  }
85
103
  };
86
104
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/kernel/manager/themeManager.ts"],"sourcesContent":["import type { KernelConfig, KernelManager, KernelManagerContext, ThemeSnapshot } from '../types';\nimport { DEFAULT_CONFIG, DEFAULT_THEME } from '../constants';\nimport { readPersistedValue, writePersistedValue } from './persistence';\n\nfunction applyThemeToDocument(theme: ThemeSnapshot): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n const root = document.documentElement;\n root.classList.remove('light', 'dark');\n\n const resolvedMode = theme.mode === 'system'\n ? (typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light')\n : theme.mode;\n\n root.classList.add(resolvedMode);\n\n if (theme.primaryColor) {\n root.style.setProperty('--app-primary-color', theme.primaryColor);\n }\n\n if (theme.tokens) {\n Object.entries(theme.tokens).forEach(([token, tokenValue]) => {\n root.style.setProperty(`--${token}`, String(tokenValue));\n });\n }\n}\n\nexport class ThemeManager implements KernelManager<ThemeSnapshot> {\n private theme: ThemeSnapshot = DEFAULT_THEME;\n private config: KernelConfig['theme'] = DEFAULT_CONFIG.theme;\n\n public async initialize(context: KernelManagerContext): Promise<void> {\n this.config = context.config.theme;\n this.theme = { ...DEFAULT_THEME, ...(this.config.initial || {}) };\n\n const persisted = await readPersistedValue(this.config.persistence);\n if (persisted !== null) {\n try {\n const parsed = JSON.parse(persisted) as Partial<ThemeSnapshot>;\n this.theme = { ...this.theme, ...parsed };\n } catch {\n // ignore parse errors\n }\n } else {\n await writePersistedValue(this.config.persistence, JSON.stringify(this.theme));\n }\n\n applyThemeToDocument(this.theme);\n }\n\n public getTheme(): ThemeSnapshot {\n return { ...this.theme };\n }\n\n public async setTheme(nextTheme: ThemeSnapshot): Promise<void> {\n this.theme = { ...nextTheme };\n applyThemeToDocument(this.theme);\n await writePersistedValue(this.config.persistence, JSON.stringify(this.theme));\n }\n\n public getSnapshot(): ThemeSnapshot {\n return this.getTheme();\n }\n}\n"],"names":["ThemeManager","applyThemeToDocument","theme","document","root","documentElement","classList","remove","resolvedMode","mode","window","matchMedia","matches","add","primaryColor","style","setProperty","tokens","Object","entries","forEach","token","tokenValue","String","initialize","context","config","DEFAULT_THEME","initial","persisted","readPersistedValue","persistence","parsed","JSON","parse","writePersistedValue","stringify","getTheme","setTheme","nextTheme","getSnapshot","DEFAULT_CONFIG"],"mappings":";;;;+BA+BaA;;;eAAAA;;;2BA9BiC;6BACU;;;;;;;;;;;;;;AAExD,SAASC,qBAAqBC,KAAoB;IAChD,IAAI,OAAOC,aAAa,aAAa;QACnC;IACF;IAEA,MAAMC,OAAOD,SAASE,eAAe;IACrCD,KAAKE,SAAS,CAACC,MAAM,CAAC,SAAS;IAE/B,MAAMC,eAAeN,MAAMO,IAAI,KAAK,WAC/B,OAAOC,WAAW,eAAeA,OAAOC,UAAU,CAAC,gCAAgCC,OAAO,GACzF,SACA,UACFV,MAAMO,IAAI;IAEdL,KAAKE,SAAS,CAACO,GAAG,CAACL;IAEnB,IAAIN,MAAMY,YAAY,EAAE;QACtBV,KAAKW,KAAK,CAACC,WAAW,CAAC,uBAAuBd,MAAMY,YAAY;IAClE;IAEA,IAAIZ,MAAMe,MAAM,EAAE;QAChBC,OAAOC,OAAO,CAACjB,MAAMe,MAAM,EAAEG,OAAO,CAAC,CAAC,CAACC,OAAOC,WAAW;YACvDlB,KAAKW,KAAK,CAACC,WAAW,CAAC,CAAC,EAAE,EAAEK,OAAO,EAAEE,OAAOD;QAC9C;IACF;AACF;AAEO,IAAA,AAAMtB,eAAN,MAAMA;IAIX,MAAawB,WAAWC,OAA6B,EAAiB;QACpE,IAAI,CAACC,MAAM,GAAGD,QAAQC,MAAM,CAACxB,KAAK;QAClC,IAAI,CAACA,KAAK,GAAG;YAAE,GAAGyB,wBAAa;YAAE,GAAI,IAAI,CAACD,MAAM,CAACE,OAAO,IAAI,CAAC,CAAC;QAAE;QAEhE,MAAMC,YAAY,MAAMC,IAAAA,+BAAkB,EAAC,IAAI,CAACJ,MAAM,CAACK,WAAW;QAClE,IAAIF,cAAc,MAAM;YACtB,IAAI;gBACF,MAAMG,SAASC,KAAKC,KAAK,CAACL;gBAC1B,IAAI,CAAC3B,KAAK,GAAG;oBAAE,GAAG,IAAI,CAACA,KAAK;oBAAE,GAAG8B,MAAM;gBAAC;YAC1C,EAAE,OAAM;YACN,sBAAsB;YACxB;QACF,OAAO;YACL,MAAMG,IAAAA,gCAAmB,EAAC,IAAI,CAACT,MAAM,CAACK,WAAW,EAAEE,KAAKG,SAAS,CAAC,IAAI,CAAClC,KAAK;QAC9E;QAEAD,qBAAqB,IAAI,CAACC,KAAK;IACjC;IAEOmC,WAA0B;QAC/B,OAAO;YAAE,GAAG,IAAI,CAACnC,KAAK;QAAC;IACzB;IAEA,MAAaoC,SAASC,SAAwB,EAAiB;QAC7D,IAAI,CAACrC,KAAK,GAAG;YAAE,GAAGqC,SAAS;QAAC;QAC5BtC,qBAAqB,IAAI,CAACC,KAAK;QAC/B,MAAMiC,IAAAA,gCAAmB,EAAC,IAAI,CAACT,MAAM,CAACK,WAAW,EAAEE,KAAKG,SAAS,CAAC,IAAI,CAAClC,KAAK;IAC9E;IAEOsC,cAA6B;QAClC,OAAO,IAAI,CAACH,QAAQ;IACtB;;QAlCA,uBAAQnC,SAAuByB,wBAAa;QAC5C,uBAAQD,UAAgCe,yBAAc,CAACvC,KAAK;;AAkC9D"}
1
+ {"version":3,"sources":["../../../src/kernel/manager/themeManager.ts"],"sourcesContent":["import type { KernelConfig, KernelManager, KernelManagerContext, ThemeSnapshot } from '../types';\nimport { DEFAULT_CONFIG, DEFAULT_THEME } from '../constants';\nimport { readPersistedValue, writePersistedValue } from './persistence';\n\ntype ThemeListener = (next: ThemeSnapshot, prev: ThemeSnapshot) => void;\n\nfunction applyThemeToDocument(theme: ThemeSnapshot): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n const root = document.documentElement;\n root.classList.remove('light', 'dark');\n\n const resolvedMode = theme.mode === 'system'\n ? (typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light')\n : theme.mode;\n\n root.classList.add(resolvedMode);\n\n if (theme.primaryColor) {\n root.style.setProperty('--app-primary-color', theme.primaryColor);\n }\n\n if (theme.tokens) {\n Object.entries(theme.tokens).forEach(([token, tokenValue]) => {\n root.style.setProperty(`--${token}`, String(tokenValue));\n });\n }\n}\n\nexport class ThemeManager implements KernelManager<ThemeSnapshot> {\n private theme: ThemeSnapshot = DEFAULT_THEME;\n private config: KernelConfig['theme'] = DEFAULT_CONFIG.theme;\n private listeners = new Set<ThemeListener>();\n\n public async initialize(context: KernelManagerContext): Promise<void> {\n this.config = context.config.theme;\n this.theme = { ...DEFAULT_THEME, ...(this.config.initial || {}) };\n\n const persisted = await readPersistedValue(this.config.persistence);\n if (persisted !== null) {\n try {\n const parsed = JSON.parse(persisted) as Partial<ThemeSnapshot>;\n this.theme = { ...this.theme, ...parsed };\n } catch {\n // ignore parse errors\n }\n } else {\n await writePersistedValue(this.config.persistence, JSON.stringify(this.theme));\n }\n\n applyThemeToDocument(this.theme);\n }\n\n public getTheme(): ThemeSnapshot {\n return { ...this.theme };\n }\n\n public subscribe(listener: ThemeListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private emit(next: ThemeSnapshot, prev: ThemeSnapshot): void {\n this.listeners.forEach((listener) => {\n listener({ ...next }, { ...prev });\n });\n }\n\n public async setTheme(nextTheme: ThemeSnapshot): Promise<void> {\n const prev = this.theme;\n this.theme = { ...nextTheme };\n applyThemeToDocument(this.theme);\n await writePersistedValue(this.config.persistence, JSON.stringify(this.theme));\n this.emit(this.theme, prev);\n }\n\n public getSnapshot(): ThemeSnapshot {\n return this.getTheme();\n }\n}\n"],"names":["ThemeManager","applyThemeToDocument","theme","document","root","documentElement","classList","remove","resolvedMode","mode","window","matchMedia","matches","add","primaryColor","style","setProperty","tokens","Object","entries","forEach","token","tokenValue","String","initialize","context","config","DEFAULT_THEME","initial","persisted","readPersistedValue","persistence","parsed","JSON","parse","writePersistedValue","stringify","getTheme","subscribe","listener","listeners","delete","emit","next","prev","setTheme","nextTheme","getSnapshot","DEFAULT_CONFIG","Set"],"mappings":";;;;+BAiCaA;;;eAAAA;;;2BAhCiC;6BACU;;;;;;;;;;;;;;AAIxD,SAASC,qBAAqBC,KAAoB;IAChD,IAAI,OAAOC,aAAa,aAAa;QACnC;IACF;IAEA,MAAMC,OAAOD,SAASE,eAAe;IACrCD,KAAKE,SAAS,CAACC,MAAM,CAAC,SAAS;IAE/B,MAAMC,eAAeN,MAAMO,IAAI,KAAK,WAC/B,OAAOC,WAAW,eAAeA,OAAOC,UAAU,CAAC,gCAAgCC,OAAO,GACzF,SACA,UACFV,MAAMO,IAAI;IAEdL,KAAKE,SAAS,CAACO,GAAG,CAACL;IAEnB,IAAIN,MAAMY,YAAY,EAAE;QACtBV,KAAKW,KAAK,CAACC,WAAW,CAAC,uBAAuBd,MAAMY,YAAY;IAClE;IAEA,IAAIZ,MAAMe,MAAM,EAAE;QAChBC,OAAOC,OAAO,CAACjB,MAAMe,MAAM,EAAEG,OAAO,CAAC,CAAC,CAACC,OAAOC,WAAW;YACvDlB,KAAKW,KAAK,CAACC,WAAW,CAAC,CAAC,EAAE,EAAEK,OAAO,EAAEE,OAAOD;QAC9C;IACF;AACF;AAEO,IAAA,AAAMtB,eAAN,MAAMA;IAKX,MAAawB,WAAWC,OAA6B,EAAiB;QACpE,IAAI,CAACC,MAAM,GAAGD,QAAQC,MAAM,CAACxB,KAAK;QAClC,IAAI,CAACA,KAAK,GAAG;YAAE,GAAGyB,wBAAa;YAAE,GAAI,IAAI,CAACD,MAAM,CAACE,OAAO,IAAI,CAAC,CAAC;QAAE;QAEhE,MAAMC,YAAY,MAAMC,IAAAA,+BAAkB,EAAC,IAAI,CAACJ,MAAM,CAACK,WAAW;QAClE,IAAIF,cAAc,MAAM;YACtB,IAAI;gBACF,MAAMG,SAASC,KAAKC,KAAK,CAACL;gBAC1B,IAAI,CAAC3B,KAAK,GAAG;oBAAE,GAAG,IAAI,CAACA,KAAK;oBAAE,GAAG8B,MAAM;gBAAC;YAC1C,EAAE,OAAM;YACN,sBAAsB;YACxB;QACF,OAAO;YACL,MAAMG,IAAAA,gCAAmB,EAAC,IAAI,CAACT,MAAM,CAACK,WAAW,EAAEE,KAAKG,SAAS,CAAC,IAAI,CAAClC,KAAK;QAC9E;QAEAD,qBAAqB,IAAI,CAACC,KAAK;IACjC;IAEOmC,WAA0B;QAC/B,OAAO;YAAE,GAAG,IAAI,CAACnC,KAAK;QAAC;IACzB;IAEOoC,UAAUC,QAAuB,EAAc;QACpD,IAAI,CAACC,SAAS,CAAC3B,GAAG,CAAC0B;QACnB,OAAO;YACL,IAAI,CAACC,SAAS,CAACC,MAAM,CAACF;QACxB;IACF;IAEQG,KAAKC,IAAmB,EAAEC,IAAmB,EAAQ;QAC3D,IAAI,CAACJ,SAAS,CAACpB,OAAO,CAAC,CAACmB;YACtBA,SAAS;gBAAE,GAAGI,IAAI;YAAC,GAAG;gBAAE,GAAGC,IAAI;YAAC;QAClC;IACF;IAEA,MAAaC,SAASC,SAAwB,EAAiB;QAC7D,MAAMF,OAAO,IAAI,CAAC1C,KAAK;QACvB,IAAI,CAACA,KAAK,GAAG;YAAE,GAAG4C,SAAS;QAAC;QAC5B7C,qBAAqB,IAAI,CAACC,KAAK;QAC/B,MAAMiC,IAAAA,gCAAmB,EAAC,IAAI,CAACT,MAAM,CAACK,WAAW,EAAEE,KAAKG,SAAS,CAAC,IAAI,CAAClC,KAAK;QAC5E,IAAI,CAACwC,IAAI,CAAC,IAAI,CAACxC,KAAK,EAAE0C;IACxB;IAEOG,cAA6B;QAClC,OAAO,IAAI,CAACV,QAAQ;IACtB;;QAlDA,uBAAQnC,SAAuByB,wBAAa;QAC5C,uBAAQD,UAAgCsB,yBAAc,CAAC9C,KAAK;QAC5D,uBAAQsC,aAAY,IAAIS;;AAiD1B"}
@@ -1,9 +1,14 @@
1
1
  import type { KernelManager, KernelManagerContext, ThemeSnapshot } from '../types';
2
+ type ThemeListener = (next: ThemeSnapshot, prev: ThemeSnapshot) => void;
2
3
  export declare class ThemeManager implements KernelManager<ThemeSnapshot> {
3
4
  private theme;
4
5
  private config;
6
+ private listeners;
5
7
  initialize(context: KernelManagerContext): Promise<void>;
6
8
  getTheme(): ThemeSnapshot;
9
+ subscribe(listener: ThemeListener): () => void;
10
+ private emit;
7
11
  setTheme(nextTheme: ThemeSnapshot): Promise<void>;
8
12
  getSnapshot(): ThemeSnapshot;
9
13
  }
14
+ export {};
@@ -58,12 +58,29 @@ export class ThemeManager {
58
58
  ...this.theme
59
59
  };
60
60
  }
61
+ subscribe(listener) {
62
+ this.listeners.add(listener);
63
+ return ()=>{
64
+ this.listeners.delete(listener);
65
+ };
66
+ }
67
+ emit(next, prev) {
68
+ this.listeners.forEach((listener)=>{
69
+ listener({
70
+ ...next
71
+ }, {
72
+ ...prev
73
+ });
74
+ });
75
+ }
61
76
  async setTheme(nextTheme) {
77
+ const prev = this.theme;
62
78
  this.theme = {
63
79
  ...nextTheme
64
80
  };
65
81
  applyThemeToDocument(this.theme);
66
82
  await writePersistedValue(this.config.persistence, JSON.stringify(this.theme));
83
+ this.emit(this.theme, prev);
67
84
  }
68
85
  getSnapshot() {
69
86
  return this.getTheme();
@@ -71,6 +88,7 @@ export class ThemeManager {
71
88
  constructor(){
72
89
  _define_property(this, "theme", DEFAULT_THEME);
73
90
  _define_property(this, "config", DEFAULT_CONFIG.theme);
91
+ _define_property(this, "listeners", new Set());
74
92
  }
75
93
  }
76
94
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/kernel/manager/themeManager.ts"],"sourcesContent":["import type { KernelConfig, KernelManager, KernelManagerContext, ThemeSnapshot } from '../types';\nimport { DEFAULT_CONFIG, DEFAULT_THEME } from '../constants';\nimport { readPersistedValue, writePersistedValue } from './persistence';\n\nfunction applyThemeToDocument(theme: ThemeSnapshot): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n const root = document.documentElement;\n root.classList.remove('light', 'dark');\n\n const resolvedMode = theme.mode === 'system'\n ? (typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light')\n : theme.mode;\n\n root.classList.add(resolvedMode);\n\n if (theme.primaryColor) {\n root.style.setProperty('--app-primary-color', theme.primaryColor);\n }\n\n if (theme.tokens) {\n Object.entries(theme.tokens).forEach(([token, tokenValue]) => {\n root.style.setProperty(`--${token}`, String(tokenValue));\n });\n }\n}\n\nexport class ThemeManager implements KernelManager<ThemeSnapshot> {\n private theme: ThemeSnapshot = DEFAULT_THEME;\n private config: KernelConfig['theme'] = DEFAULT_CONFIG.theme;\n\n public async initialize(context: KernelManagerContext): Promise<void> {\n this.config = context.config.theme;\n this.theme = { ...DEFAULT_THEME, ...(this.config.initial || {}) };\n\n const persisted = await readPersistedValue(this.config.persistence);\n if (persisted !== null) {\n try {\n const parsed = JSON.parse(persisted) as Partial<ThemeSnapshot>;\n this.theme = { ...this.theme, ...parsed };\n } catch {\n // ignore parse errors\n }\n } else {\n await writePersistedValue(this.config.persistence, JSON.stringify(this.theme));\n }\n\n applyThemeToDocument(this.theme);\n }\n\n public getTheme(): ThemeSnapshot {\n return { ...this.theme };\n }\n\n public async setTheme(nextTheme: ThemeSnapshot): Promise<void> {\n this.theme = { ...nextTheme };\n applyThemeToDocument(this.theme);\n await writePersistedValue(this.config.persistence, JSON.stringify(this.theme));\n }\n\n public getSnapshot(): ThemeSnapshot {\n return this.getTheme();\n }\n}\n"],"names":["DEFAULT_CONFIG","DEFAULT_THEME","readPersistedValue","writePersistedValue","applyThemeToDocument","theme","document","root","documentElement","classList","remove","resolvedMode","mode","window","matchMedia","matches","add","primaryColor","style","setProperty","tokens","Object","entries","forEach","token","tokenValue","String","ThemeManager","initialize","context","config","initial","persisted","persistence","parsed","JSON","parse","stringify","getTheme","setTheme","nextTheme","getSnapshot"],"mappings":";;;;;;;;;;;;;AACA,SAASA,cAAc,EAAEC,aAAa,QAAQ,eAAe;AAC7D,SAASC,kBAAkB,EAAEC,mBAAmB,QAAQ,gBAAgB;AAExE,SAASC,qBAAqBC,KAAoB;IAChD,IAAI,OAAOC,aAAa,aAAa;QACnC;IACF;IAEA,MAAMC,OAAOD,SAASE,eAAe;IACrCD,KAAKE,SAAS,CAACC,MAAM,CAAC,SAAS;IAE/B,MAAMC,eAAeN,MAAMO,IAAI,KAAK,WAC/B,OAAOC,WAAW,eAAeA,OAAOC,UAAU,CAAC,gCAAgCC,OAAO,GACzF,SACA,UACFV,MAAMO,IAAI;IAEdL,KAAKE,SAAS,CAACO,GAAG,CAACL;IAEnB,IAAIN,MAAMY,YAAY,EAAE;QACtBV,KAAKW,KAAK,CAACC,WAAW,CAAC,uBAAuBd,MAAMY,YAAY;IAClE;IAEA,IAAIZ,MAAMe,MAAM,EAAE;QAChBC,OAAOC,OAAO,CAACjB,MAAMe,MAAM,EAAEG,OAAO,CAAC,CAAC,CAACC,OAAOC,WAAW;YACvDlB,KAAKW,KAAK,CAACC,WAAW,CAAC,CAAC,EAAE,EAAEK,OAAO,EAAEE,OAAOD;QAC9C;IACF;AACF;AAEA,OAAO,MAAME;IAIX,MAAaC,WAAWC,OAA6B,EAAiB;QACpE,IAAI,CAACC,MAAM,GAAGD,QAAQC,MAAM,CAACzB,KAAK;QAClC,IAAI,CAACA,KAAK,GAAG;YAAE,GAAGJ,aAAa;YAAE,GAAI,IAAI,CAAC6B,MAAM,CAACC,OAAO,IAAI,CAAC,CAAC;QAAE;QAEhE,MAAMC,YAAY,MAAM9B,mBAAmB,IAAI,CAAC4B,MAAM,CAACG,WAAW;QAClE,IAAID,cAAc,MAAM;YACtB,IAAI;gBACF,MAAME,SAASC,KAAKC,KAAK,CAACJ;gBAC1B,IAAI,CAAC3B,KAAK,GAAG;oBAAE,GAAG,IAAI,CAACA,KAAK;oBAAE,GAAG6B,MAAM;gBAAC;YAC1C,EAAE,OAAM;YACN,sBAAsB;YACxB;QACF,OAAO;YACL,MAAM/B,oBAAoB,IAAI,CAAC2B,MAAM,CAACG,WAAW,EAAEE,KAAKE,SAAS,CAAC,IAAI,CAAChC,KAAK;QAC9E;QAEAD,qBAAqB,IAAI,CAACC,KAAK;IACjC;IAEOiC,WAA0B;QAC/B,OAAO;YAAE,GAAG,IAAI,CAACjC,KAAK;QAAC;IACzB;IAEA,MAAakC,SAASC,SAAwB,EAAiB;QAC7D,IAAI,CAACnC,KAAK,GAAG;YAAE,GAAGmC,SAAS;QAAC;QAC5BpC,qBAAqB,IAAI,CAACC,KAAK;QAC/B,MAAMF,oBAAoB,IAAI,CAAC2B,MAAM,CAACG,WAAW,EAAEE,KAAKE,SAAS,CAAC,IAAI,CAAChC,KAAK;IAC9E;IAEOoC,cAA6B;QAClC,OAAO,IAAI,CAACH,QAAQ;IACtB;;QAlCA,uBAAQjC,SAAuBJ;QAC/B,uBAAQ6B,UAAgC9B,eAAeK,KAAK;;AAkC9D"}
1
+ {"version":3,"sources":["../../../src/kernel/manager/themeManager.ts"],"sourcesContent":["import type { KernelConfig, KernelManager, KernelManagerContext, ThemeSnapshot } from '../types';\nimport { DEFAULT_CONFIG, DEFAULT_THEME } from '../constants';\nimport { readPersistedValue, writePersistedValue } from './persistence';\n\ntype ThemeListener = (next: ThemeSnapshot, prev: ThemeSnapshot) => void;\n\nfunction applyThemeToDocument(theme: ThemeSnapshot): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n const root = document.documentElement;\n root.classList.remove('light', 'dark');\n\n const resolvedMode = theme.mode === 'system'\n ? (typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light')\n : theme.mode;\n\n root.classList.add(resolvedMode);\n\n if (theme.primaryColor) {\n root.style.setProperty('--app-primary-color', theme.primaryColor);\n }\n\n if (theme.tokens) {\n Object.entries(theme.tokens).forEach(([token, tokenValue]) => {\n root.style.setProperty(`--${token}`, String(tokenValue));\n });\n }\n}\n\nexport class ThemeManager implements KernelManager<ThemeSnapshot> {\n private theme: ThemeSnapshot = DEFAULT_THEME;\n private config: KernelConfig['theme'] = DEFAULT_CONFIG.theme;\n private listeners = new Set<ThemeListener>();\n\n public async initialize(context: KernelManagerContext): Promise<void> {\n this.config = context.config.theme;\n this.theme = { ...DEFAULT_THEME, ...(this.config.initial || {}) };\n\n const persisted = await readPersistedValue(this.config.persistence);\n if (persisted !== null) {\n try {\n const parsed = JSON.parse(persisted) as Partial<ThemeSnapshot>;\n this.theme = { ...this.theme, ...parsed };\n } catch {\n // ignore parse errors\n }\n } else {\n await writePersistedValue(this.config.persistence, JSON.stringify(this.theme));\n }\n\n applyThemeToDocument(this.theme);\n }\n\n public getTheme(): ThemeSnapshot {\n return { ...this.theme };\n }\n\n public subscribe(listener: ThemeListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private emit(next: ThemeSnapshot, prev: ThemeSnapshot): void {\n this.listeners.forEach((listener) => {\n listener({ ...next }, { ...prev });\n });\n }\n\n public async setTheme(nextTheme: ThemeSnapshot): Promise<void> {\n const prev = this.theme;\n this.theme = { ...nextTheme };\n applyThemeToDocument(this.theme);\n await writePersistedValue(this.config.persistence, JSON.stringify(this.theme));\n this.emit(this.theme, prev);\n }\n\n public getSnapshot(): ThemeSnapshot {\n return this.getTheme();\n }\n}\n"],"names":["DEFAULT_CONFIG","DEFAULT_THEME","readPersistedValue","writePersistedValue","applyThemeToDocument","theme","document","root","documentElement","classList","remove","resolvedMode","mode","window","matchMedia","matches","add","primaryColor","style","setProperty","tokens","Object","entries","forEach","token","tokenValue","String","ThemeManager","initialize","context","config","initial","persisted","persistence","parsed","JSON","parse","stringify","getTheme","subscribe","listener","listeners","delete","emit","next","prev","setTheme","nextTheme","getSnapshot","Set"],"mappings":";;;;;;;;;;;;;AACA,SAASA,cAAc,EAAEC,aAAa,QAAQ,eAAe;AAC7D,SAASC,kBAAkB,EAAEC,mBAAmB,QAAQ,gBAAgB;AAIxE,SAASC,qBAAqBC,KAAoB;IAChD,IAAI,OAAOC,aAAa,aAAa;QACnC;IACF;IAEA,MAAMC,OAAOD,SAASE,eAAe;IACrCD,KAAKE,SAAS,CAACC,MAAM,CAAC,SAAS;IAE/B,MAAMC,eAAeN,MAAMO,IAAI,KAAK,WAC/B,OAAOC,WAAW,eAAeA,OAAOC,UAAU,CAAC,gCAAgCC,OAAO,GACzF,SACA,UACFV,MAAMO,IAAI;IAEdL,KAAKE,SAAS,CAACO,GAAG,CAACL;IAEnB,IAAIN,MAAMY,YAAY,EAAE;QACtBV,KAAKW,KAAK,CAACC,WAAW,CAAC,uBAAuBd,MAAMY,YAAY;IAClE;IAEA,IAAIZ,MAAMe,MAAM,EAAE;QAChBC,OAAOC,OAAO,CAACjB,MAAMe,MAAM,EAAEG,OAAO,CAAC,CAAC,CAACC,OAAOC,WAAW;YACvDlB,KAAKW,KAAK,CAACC,WAAW,CAAC,CAAC,EAAE,EAAEK,OAAO,EAAEE,OAAOD;QAC9C;IACF;AACF;AAEA,OAAO,MAAME;IAKX,MAAaC,WAAWC,OAA6B,EAAiB;QACpE,IAAI,CAACC,MAAM,GAAGD,QAAQC,MAAM,CAACzB,KAAK;QAClC,IAAI,CAACA,KAAK,GAAG;YAAE,GAAGJ,aAAa;YAAE,GAAI,IAAI,CAAC6B,MAAM,CAACC,OAAO,IAAI,CAAC,CAAC;QAAE;QAEhE,MAAMC,YAAY,MAAM9B,mBAAmB,IAAI,CAAC4B,MAAM,CAACG,WAAW;QAClE,IAAID,cAAc,MAAM;YACtB,IAAI;gBACF,MAAME,SAASC,KAAKC,KAAK,CAACJ;gBAC1B,IAAI,CAAC3B,KAAK,GAAG;oBAAE,GAAG,IAAI,CAACA,KAAK;oBAAE,GAAG6B,MAAM;gBAAC;YAC1C,EAAE,OAAM;YACN,sBAAsB;YACxB;QACF,OAAO;YACL,MAAM/B,oBAAoB,IAAI,CAAC2B,MAAM,CAACG,WAAW,EAAEE,KAAKE,SAAS,CAAC,IAAI,CAAChC,KAAK;QAC9E;QAEAD,qBAAqB,IAAI,CAACC,KAAK;IACjC;IAEOiC,WAA0B;QAC/B,OAAO;YAAE,GAAG,IAAI,CAACjC,KAAK;QAAC;IACzB;IAEOkC,UAAUC,QAAuB,EAAc;QACpD,IAAI,CAACC,SAAS,CAACzB,GAAG,CAACwB;QACnB,OAAO;YACL,IAAI,CAACC,SAAS,CAACC,MAAM,CAACF;QACxB;IACF;IAEQG,KAAKC,IAAmB,EAAEC,IAAmB,EAAQ;QAC3D,IAAI,CAACJ,SAAS,CAAClB,OAAO,CAAC,CAACiB;YACtBA,SAAS;gBAAE,GAAGI,IAAI;YAAC,GAAG;gBAAE,GAAGC,IAAI;YAAC;QAClC;IACF;IAEA,MAAaC,SAASC,SAAwB,EAAiB;QAC7D,MAAMF,OAAO,IAAI,CAACxC,KAAK;QACvB,IAAI,CAACA,KAAK,GAAG;YAAE,GAAG0C,SAAS;QAAC;QAC5B3C,qBAAqB,IAAI,CAACC,KAAK;QAC/B,MAAMF,oBAAoB,IAAI,CAAC2B,MAAM,CAACG,WAAW,EAAEE,KAAKE,SAAS,CAAC,IAAI,CAAChC,KAAK;QAC5E,IAAI,CAACsC,IAAI,CAAC,IAAI,CAACtC,KAAK,EAAEwC;IACxB;IAEOG,cAA6B;QAClC,OAAO,IAAI,CAACV,QAAQ;IACtB;;QAlDA,uBAAQjC,SAAuBJ;QAC/B,uBAAQ6B,UAAgC9B,eAAeK,KAAK;QAC5D,uBAAQoC,aAAY,IAAIQ;;AAiD1B"}
package/dist/state.umd.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @vlian/framework v1.2.44
2
+ * @vlian/framework v1.2.46
3
3
  * Secra Framework - 一个现代化的低代码框架
4
4
  * (c) 2026 Secra Framework Contributors
5
5
  * Licensed under Apache-2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vlian/framework",
3
- "version": "1.2.45",
3
+ "version": "1.2.47",
4
4
  "private": false,
5
5
  "packageManager": "pnpm@10.27.0",
6
6
  "description": "Secra Framework - 一个现代化的低代码框架",