@vlian/framework 1.2.54 → 1.2.56
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/dist/analytics.umd.js +1 -1
- package/dist/core/initialization/initialization.cjs.map +1 -1
- package/dist/core/initialization/initialization.js +3 -3
- package/dist/core/initialization/initialization.js.map +1 -1
- package/dist/core/router/validation/RouterConfigValidator.d.ts +2 -2
- package/dist/core/router/validation/schema.d.ts +3 -3
- package/dist/index.umd.js +497 -281
- package/dist/index.umd.js.map +1 -1
- package/dist/kernel/manager/i18n/I18nManager.cjs +93 -0
- package/dist/kernel/manager/i18n/I18nManager.cjs.map +1 -0
- package/dist/kernel/manager/i18n/I18nManager.d.ts +15 -0
- package/dist/kernel/manager/i18n/I18nManager.js +83 -0
- package/dist/kernel/manager/i18n/I18nManager.js.map +1 -0
- package/dist/kernel/manager/i18n/i18n.persistence.cjs +59 -0
- package/dist/kernel/manager/i18n/i18n.persistence.cjs.map +1 -0
- package/dist/kernel/manager/i18n/i18n.persistence.d.ts +5 -0
- package/dist/kernel/manager/i18n/i18n.persistence.js +38 -0
- package/dist/kernel/manager/i18n/i18n.persistence.js.map +1 -0
- package/dist/kernel/manager/i18n/i18n.schema.cjs +88 -0
- package/dist/kernel/manager/i18n/i18n.schema.cjs.map +1 -0
- package/dist/kernel/manager/i18n/i18n.schema.d.ts +6 -0
- package/dist/kernel/manager/i18n/i18n.schema.js +64 -0
- package/dist/kernel/manager/i18n/i18n.schema.js.map +1 -0
- package/dist/kernel/manager/i18n/index.cjs +13 -0
- package/dist/kernel/manager/i18n/index.cjs.map +1 -0
- package/dist/kernel/manager/i18n/index.d.ts +1 -0
- package/dist/kernel/manager/i18n/index.js +3 -0
- package/dist/kernel/manager/i18n/index.js.map +1 -0
- package/dist/kernel/manager/i18nManager.cjs +2 -77
- package/dist/kernel/manager/i18nManager.cjs.map +1 -1
- package/dist/kernel/manager/i18nManager.d.ts +1 -13
- package/dist/kernel/manager/i18nManager.js +1 -76
- package/dist/kernel/manager/i18nManager.js.map +1 -1
- package/dist/kernel/manager/logger/LoggerManager.cjs +109 -0
- package/dist/kernel/manager/logger/LoggerManager.cjs.map +1 -0
- package/dist/kernel/manager/logger/LoggerManager.d.ts +21 -0
- package/dist/kernel/manager/logger/LoggerManager.js +99 -0
- package/dist/kernel/manager/logger/LoggerManager.js.map +1 -0
- package/dist/kernel/manager/logger/index.cjs +13 -0
- package/dist/kernel/manager/logger/index.cjs.map +1 -0
- package/dist/kernel/manager/logger/index.d.ts +1 -0
- package/dist/kernel/manager/logger/index.js +3 -0
- package/dist/kernel/manager/logger/index.js.map +1 -0
- package/dist/kernel/manager/logger/logger.persistence.cjs +64 -0
- package/dist/kernel/manager/logger/logger.persistence.cjs.map +1 -0
- package/dist/kernel/manager/logger/logger.persistence.d.ts +6 -0
- package/dist/kernel/manager/logger/logger.persistence.js +43 -0
- package/dist/kernel/manager/logger/logger.persistence.js.map +1 -0
- package/dist/kernel/manager/logger/logger.schema.cjs +76 -0
- package/dist/kernel/manager/logger/logger.schema.cjs.map +1 -0
- package/dist/kernel/manager/logger/logger.schema.d.ts +8 -0
- package/dist/kernel/manager/logger/logger.schema.js +55 -0
- package/dist/kernel/manager/logger/logger.schema.js.map +1 -0
- package/dist/kernel/manager/loggerManager.cjs +2 -103
- package/dist/kernel/manager/loggerManager.cjs.map +1 -1
- package/dist/kernel/manager/loggerManager.d.ts +1 -18
- package/dist/kernel/manager/loggerManager.js +1 -102
- package/dist/kernel/manager/loggerManager.js.map +1 -1
- package/dist/kernel/manager/theme/ThemeManager.cjs +86 -0
- package/dist/kernel/manager/theme/ThemeManager.cjs.map +1 -0
- package/dist/kernel/manager/theme/ThemeManager.d.ts +16 -0
- package/dist/kernel/manager/theme/ThemeManager.js +76 -0
- package/dist/kernel/manager/theme/ThemeManager.js.map +1 -0
- package/dist/kernel/manager/theme/index.cjs +13 -0
- package/dist/kernel/manager/theme/index.cjs.map +1 -0
- package/dist/kernel/manager/theme/index.d.ts +1 -0
- package/dist/kernel/manager/theme/index.js +3 -0
- package/dist/kernel/manager/theme/index.js.map +1 -0
- package/dist/kernel/manager/theme/theme.dom.cjs +63 -0
- package/dist/kernel/manager/theme/theme.dom.cjs.map +1 -0
- package/dist/kernel/manager/theme/theme.dom.d.ts +3 -0
- package/dist/kernel/manager/theme/theme.dom.js +45 -0
- package/dist/kernel/manager/theme/theme.dom.js.map +1 -0
- package/dist/kernel/manager/theme/theme.persistence.cjs +59 -0
- package/dist/kernel/manager/theme/theme.persistence.cjs.map +1 -0
- package/dist/kernel/manager/theme/theme.persistence.d.ts +5 -0
- package/dist/kernel/manager/theme/theme.persistence.js +38 -0
- package/dist/kernel/manager/theme/theme.persistence.js.map +1 -0
- package/dist/kernel/manager/theme/theme.schema.cjs +124 -0
- package/dist/kernel/manager/theme/theme.schema.cjs.map +1 -0
- package/dist/kernel/manager/theme/theme.schema.d.ts +7 -0
- package/dist/kernel/manager/theme/theme.schema.js +97 -0
- package/dist/kernel/manager/theme/theme.schema.js.map +1 -0
- package/dist/kernel/manager/themeManager.cjs +2 -95
- package/dist/kernel/manager/themeManager.cjs.map +1 -1
- package/dist/kernel/manager/themeManager.d.ts +1 -15
- package/dist/kernel/manager/themeManager.js +1 -94
- package/dist/kernel/manager/themeManager.js.map +1 -1
- package/dist/kernel/types.d.ts +3 -3
- package/dist/kernel/types.js.map +1 -1
- package/dist/library/locale/index.cjs +8 -34
- package/dist/library/locale/index.cjs.map +1 -1
- package/dist/library/locale/index.d.ts +4 -4
- package/dist/library/locale/index.js +5 -34
- package/dist/library/locale/index.js.map +1 -1
- package/dist/state.umd.js +1 -1
- package/package.json +3 -1
package/dist/index.umd.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @vlian/framework v1.2.
|
|
2
|
+
* @vlian/framework v1.2.55
|
|
3
3
|
* Secra Framework - 一个现代化的低代码框架
|
|
4
4
|
* (c) 2026 Secra Framework Contributors
|
|
5
5
|
* Licensed under Apache-2.0
|
|
6
6
|
*/
|
|
7
7
|
(function (global, factory) {
|
|
8
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@vlian/utils'), require('@vlian/logger'), require('@vlian/monitoring'), require('react/jsx-runtime'), require('react-dom/client'), require('react'), require('react-router-dom'), require('zod'), require('i18next'), require('react-i18next'), require('@vlian/csrf')
|
|
9
|
-
typeof define === 'function' && define.amd ? define(['exports', '@vlian/utils', '@vlian/logger', '@vlian/monitoring', 'react/jsx-runtime', 'react-dom/client', 'react', 'react-router-dom', 'zod', 'i18next', 'react-i18next', '@vlian/csrf'
|
|
10
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vlianFramework = {}, global.vlianUtils, global.logger, global.monitoring, global.jsxRuntime, global.ReactDOMClient, global.React, global.ReactRouterDOM, global.z, global.i18next, global.ReactI18next, global.csrf
|
|
11
|
-
})(this, (function (exports, vlianUtils, logger, monitoring, jsxRuntime, client, React, reactRouterDom, zod, i18n, reactI18next, csrf
|
|
8
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@vlian/utils'), require('@vlian/logger'), require('@vlian/monitoring'), require('react/jsx-runtime'), require('react-dom/client'), require('react'), require('react-router-dom'), require('zod'), require('i18next'), require('react-i18next'), require('@vlian/csrf')) :
|
|
9
|
+
typeof define === 'function' && define.amd ? define(['exports', '@vlian/utils', '@vlian/logger', '@vlian/monitoring', 'react/jsx-runtime', 'react-dom/client', 'react', 'react-router-dom', 'zod', 'i18next', 'react-i18next', '@vlian/csrf'], factory) :
|
|
10
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vlianFramework = {}, global.vlianUtils, global.logger, global.monitoring, global.jsxRuntime, global.ReactDOMClient, global.React, global.ReactRouterDOM, global.z, global.i18next, global.ReactI18next, global.csrf));
|
|
11
|
+
})(this, (function (exports, vlianUtils, logger, monitoring, jsxRuntime, client, React, reactRouterDom, zod, i18n, reactI18next, csrf) { 'use strict';
|
|
12
12
|
|
|
13
13
|
function _interopNamespaceDefault(e) {
|
|
14
14
|
var n = Object.create(null);
|
|
@@ -29,84 +29,13 @@
|
|
|
29
29
|
|
|
30
30
|
var vlianUtils__namespace = /*#__PURE__*/_interopNamespaceDefault(vlianUtils);
|
|
31
31
|
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
},
|
|
36
|
-
defaultApp: {
|
|
37
|
-
title: "Welcome to Secra Framework",
|
|
38
|
-
description: "Framework has been successfully started! Please provide your app component to get started.",
|
|
39
|
-
quickStart: {
|
|
40
|
-
title: "Quick Start",
|
|
41
|
-
description: "Provide the app option in your startup configuration to render your application:",
|
|
42
|
-
code: "import { start } from '@vlian/framework';\nimport App from './App';\n\nstart({\n app: <App />,\n});"
|
|
43
|
-
},
|
|
44
|
-
nextSteps: {
|
|
45
|
-
title: "Next Steps",
|
|
46
|
-
step1: "Create your application root component (e.g., App.tsx)",
|
|
47
|
-
step2: "Pass the app option in your startup configuration",
|
|
48
|
-
step3: "Start developing your application features"
|
|
49
|
-
},
|
|
50
|
-
footer: "Secra Framework - Modern Low-Code Frontend Application Framework"
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const local = {
|
|
55
|
-
notfound: {
|
|
56
|
-
home: "回到首页"
|
|
57
|
-
},
|
|
58
|
-
defaultApp: {
|
|
59
|
-
title: "欢迎使用 Secra Framework",
|
|
60
|
-
description: "框架已成功启动!请提供您的应用组件以开始使用。",
|
|
61
|
-
quickStart: {
|
|
62
|
-
title: "快速开始",
|
|
63
|
-
description: "在启动配置中提供 app 选项来渲染您的应用:",
|
|
64
|
-
code: "import { start } from '@vlian/framework';\nimport App from './App';\n\nstart({\n app: <App />,\n});"
|
|
65
|
-
},
|
|
66
|
-
nextSteps: {
|
|
67
|
-
title: "下一步",
|
|
68
|
-
step1: "创建您的应用根组件(如 App.tsx)",
|
|
69
|
-
step2: "在启动配置中传入 app 选项",
|
|
70
|
-
step3: "开始开发您的应用功能"
|
|
71
|
-
},
|
|
72
|
-
footer: "Secra Framework - 现代化的低代码前端应用框架"
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
let setupPromise = null;
|
|
77
|
-
/** Setup plugin i18n */ function setupI18n(otherLocales = {
|
|
78
|
-
'en-US': {},
|
|
79
|
-
'zh-CN': {}
|
|
80
|
-
}) {
|
|
81
|
-
const locales = {
|
|
82
|
-
'en-US': {
|
|
83
|
-
translation: Object.assign({}, local$1, otherLocales['en-US'])
|
|
84
|
-
},
|
|
85
|
-
'zh-CN': {
|
|
86
|
-
translation: Object.assign({}, local, otherLocales['zh-CN'])
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
if (i18n.isInitialized) {
|
|
90
|
-
i18n.addResourceBundle('en-US', 'translation', locales['en-US'].translation, true, true);
|
|
91
|
-
i18n.addResourceBundle('zh-CN', 'translation', locales['zh-CN'].translation, true, true);
|
|
92
|
-
return Promise.resolve(i18n);
|
|
93
|
-
}
|
|
94
|
-
if (setupPromise) {
|
|
95
|
-
return setupPromise;
|
|
96
|
-
}
|
|
97
|
-
const initPromise = i18n.use(reactI18next.initReactI18next).init({
|
|
98
|
-
interpolation: {
|
|
99
|
-
escapeValue: false
|
|
100
|
-
},
|
|
101
|
-
lng: 'zh-CN',
|
|
102
|
-
resources: locales
|
|
103
|
-
}).then(()=>i18n);
|
|
104
|
-
setupPromise = initPromise;
|
|
105
|
-
return initPromise;
|
|
32
|
+
const reactI18nextInstance = i18n.use(reactI18next.initReactI18next);
|
|
33
|
+
/** Setup plugin i18n */ async function setupI18n(options, callback) {
|
|
34
|
+
await reactI18nextInstance.init(options, callback);
|
|
106
35
|
}
|
|
107
36
|
const $t = i18n.t;
|
|
108
|
-
function setLang(locale) {
|
|
109
|
-
i18n.changeLanguage(locale);
|
|
37
|
+
async function setLang(locale, callback) {
|
|
38
|
+
await i18n.changeLanguage(locale, callback);
|
|
110
39
|
}
|
|
111
40
|
|
|
112
41
|
function _define_property$K(obj, key, value) {
|
|
@@ -1269,13 +1198,13 @@
|
|
|
1269
1198
|
|
|
1270
1199
|
/**
|
|
1271
1200
|
* 初始化方法
|
|
1272
|
-
*
|
|
1201
|
+
*
|
|
1273
1202
|
* 这是核心的初始化逻辑,可被启动页或直接调用
|
|
1274
|
-
*
|
|
1203
|
+
*
|
|
1275
1204
|
* @param options - 初始化选项
|
|
1276
1205
|
* @param onProgress - 进度回调函数(可选)
|
|
1277
1206
|
* @returns Promise<InitializationContext>
|
|
1278
|
-
*
|
|
1207
|
+
*
|
|
1279
1208
|
* @example
|
|
1280
1209
|
* ```typescript
|
|
1281
1210
|
* const context = await initialization({
|
|
@@ -11980,7 +11909,7 @@
|
|
|
11980
11909
|
}
|
|
11981
11910
|
return window.localStorage;
|
|
11982
11911
|
}
|
|
11983
|
-
function readPersistedValue
|
|
11912
|
+
function readPersistedValue(options, defaultKey) {
|
|
11984
11913
|
if (options.enabled === false) {
|
|
11985
11914
|
return null;
|
|
11986
11915
|
}
|
|
@@ -11994,7 +11923,7 @@
|
|
|
11994
11923
|
return null;
|
|
11995
11924
|
}
|
|
11996
11925
|
}
|
|
11997
|
-
function writePersistedValue
|
|
11926
|
+
function writePersistedValue(value, options, defaultKey) {
|
|
11998
11927
|
if (options.enabled === false || !value) {
|
|
11999
11928
|
return;
|
|
12000
11929
|
}
|
|
@@ -12042,7 +11971,7 @@
|
|
|
12042
11971
|
return;
|
|
12043
11972
|
}
|
|
12044
11973
|
hydratedRef.current = true;
|
|
12045
|
-
const persistedMode = readPersistedValue
|
|
11974
|
+
const persistedMode = readPersistedValue(persistenceOptions, DEFAULT_THEME_STORAGE_KEY);
|
|
12046
11975
|
if (!persistedMode || !isThemeMode(persistedMode) || !modes.includes(persistedMode)) {
|
|
12047
11976
|
return;
|
|
12048
11977
|
}
|
|
@@ -12063,7 +11992,7 @@
|
|
|
12063
11992
|
if (!mode || lastWrittenModeRef.current === mode) {
|
|
12064
11993
|
return;
|
|
12065
11994
|
}
|
|
12066
|
-
writePersistedValue
|
|
11995
|
+
writePersistedValue(mode, persistenceOptions, DEFAULT_THEME_STORAGE_KEY);
|
|
12067
11996
|
lastWrittenModeRef.current = mode;
|
|
12068
11997
|
}, [
|
|
12069
11998
|
persistenceOptions,
|
|
@@ -12137,7 +12066,7 @@
|
|
|
12137
12066
|
return;
|
|
12138
12067
|
}
|
|
12139
12068
|
hydratedRef.current = true;
|
|
12140
|
-
const persistedLocale = readPersistedValue
|
|
12069
|
+
const persistedLocale = readPersistedValue(persistenceOptions, DEFAULT_LOCALE_STORAGE_KEY);
|
|
12141
12070
|
if (!persistedLocale || !isLocale(persistedLocale) || !locales.includes(persistedLocale)) {
|
|
12142
12071
|
return;
|
|
12143
12072
|
}
|
|
@@ -12154,7 +12083,7 @@
|
|
|
12154
12083
|
if (lastWrittenLocaleRef.current === locale) {
|
|
12155
12084
|
return;
|
|
12156
12085
|
}
|
|
12157
|
-
writePersistedValue
|
|
12086
|
+
writePersistedValue(locale, persistenceOptions, DEFAULT_LOCALE_STORAGE_KEY);
|
|
12158
12087
|
lastWrittenLocaleRef.current = locale;
|
|
12159
12088
|
}, [
|
|
12160
12089
|
locale,
|
|
@@ -12245,76 +12174,6 @@
|
|
|
12245
12174
|
}
|
|
12246
12175
|
};
|
|
12247
12176
|
|
|
12248
|
-
function resolveStorageInstance(driver) {
|
|
12249
|
-
if (driver === 'none' || typeof window === 'undefined') {
|
|
12250
|
-
return null;
|
|
12251
|
-
}
|
|
12252
|
-
const instance = driver === 'localStorage' ? storage.local : driver === 'sessionStorage' ? storage.session : storage.indexedDB;
|
|
12253
|
-
if (!instance || typeof instance.get !== 'function' || typeof instance.set !== 'function') {
|
|
12254
|
-
return null;
|
|
12255
|
-
}
|
|
12256
|
-
return instance;
|
|
12257
|
-
}
|
|
12258
|
-
async function readPersistedValue(persistence) {
|
|
12259
|
-
if (!persistence || persistence.enabled === false) {
|
|
12260
|
-
return null;
|
|
12261
|
-
}
|
|
12262
|
-
const driver = persistence.storage ?? 'localStorage';
|
|
12263
|
-
const key = persistence.key;
|
|
12264
|
-
if (!key) {
|
|
12265
|
-
return null;
|
|
12266
|
-
}
|
|
12267
|
-
const targetStorage = resolveStorageInstance(driver);
|
|
12268
|
-
if (!targetStorage) {
|
|
12269
|
-
return null;
|
|
12270
|
-
}
|
|
12271
|
-
try {
|
|
12272
|
-
const value = await targetStorage.get(key);
|
|
12273
|
-
if (value === null || value === undefined) {
|
|
12274
|
-
return null;
|
|
12275
|
-
}
|
|
12276
|
-
if (typeof value === 'string') {
|
|
12277
|
-
return value;
|
|
12278
|
-
}
|
|
12279
|
-
return JSON.stringify(value);
|
|
12280
|
-
} catch {
|
|
12281
|
-
return null;
|
|
12282
|
-
}
|
|
12283
|
-
}
|
|
12284
|
-
async function writePersistedValue(persistence, value) {
|
|
12285
|
-
if (!persistence || persistence.enabled === false) {
|
|
12286
|
-
return;
|
|
12287
|
-
}
|
|
12288
|
-
const driver = persistence.storage ?? 'localStorage';
|
|
12289
|
-
const key = persistence.key;
|
|
12290
|
-
if (!key) {
|
|
12291
|
-
return;
|
|
12292
|
-
}
|
|
12293
|
-
const targetStorage = resolveStorageInstance(driver);
|
|
12294
|
-
if (!targetStorage) {
|
|
12295
|
-
return;
|
|
12296
|
-
}
|
|
12297
|
-
try {
|
|
12298
|
-
await targetStorage.set(key, value);
|
|
12299
|
-
} catch (e) {
|
|
12300
|
-
utils$1.logger.error(e);
|
|
12301
|
-
// ignore persistence errors
|
|
12302
|
-
}
|
|
12303
|
-
}
|
|
12304
|
-
|
|
12305
|
-
function _define_property$4(obj, key, value) {
|
|
12306
|
-
if (key in obj) {
|
|
12307
|
-
Object.defineProperty(obj, key, {
|
|
12308
|
-
value: value,
|
|
12309
|
-
enumerable: true,
|
|
12310
|
-
configurable: true,
|
|
12311
|
-
writable: true
|
|
12312
|
-
});
|
|
12313
|
-
} else {
|
|
12314
|
-
obj[key] = value;
|
|
12315
|
-
}
|
|
12316
|
-
return obj;
|
|
12317
|
-
}
|
|
12318
12177
|
function normalizeLogLevel(value, fallback) {
|
|
12319
12178
|
if (typeof value === 'number' && Number.isInteger(value)) {
|
|
12320
12179
|
switch(value){
|
|
@@ -12353,26 +12212,93 @@
|
|
|
12353
12212
|
return fallback;
|
|
12354
12213
|
}
|
|
12355
12214
|
}
|
|
12215
|
+
function normalizeLoggerSnapshot(value, fallback) {
|
|
12216
|
+
if (typeof value === 'number' || typeof value === 'string') {
|
|
12217
|
+
return {
|
|
12218
|
+
level: normalizeLogLevel(value, fallback.level)
|
|
12219
|
+
};
|
|
12220
|
+
}
|
|
12221
|
+
const source = value && typeof value === 'object' ? value : {};
|
|
12222
|
+
return {
|
|
12223
|
+
level: normalizeLogLevel(source.level, fallback.level)
|
|
12224
|
+
};
|
|
12225
|
+
}
|
|
12226
|
+
function isLoggerEqual(left, right) {
|
|
12227
|
+
return left.level === right.level;
|
|
12228
|
+
}
|
|
12229
|
+
|
|
12230
|
+
const DEFAULT_LOGGER_CACHE_KEY = 'vlian:kernel:logger-level';
|
|
12231
|
+
function resolvePersistenceContext$2(persistence) {
|
|
12232
|
+
if (persistence?.enabled !== true) {
|
|
12233
|
+
return null;
|
|
12234
|
+
}
|
|
12235
|
+
return {
|
|
12236
|
+
key: persistence.key || DEFAULT_LOGGER_CACHE_KEY
|
|
12237
|
+
};
|
|
12238
|
+
}
|
|
12239
|
+
async function loadLoggerFromCache(cacheManager, persistence, fallback) {
|
|
12240
|
+
const persistenceContext = resolvePersistenceContext$2(persistence);
|
|
12241
|
+
if (!persistenceContext) {
|
|
12242
|
+
return {
|
|
12243
|
+
...fallback
|
|
12244
|
+
};
|
|
12245
|
+
}
|
|
12246
|
+
try {
|
|
12247
|
+
const cached = await cacheManager.get(persistenceContext.key, {
|
|
12248
|
+
defaultValue: fallback
|
|
12249
|
+
});
|
|
12250
|
+
return normalizeLoggerSnapshot(cached, fallback);
|
|
12251
|
+
} catch {
|
|
12252
|
+
return {
|
|
12253
|
+
...fallback
|
|
12254
|
+
};
|
|
12255
|
+
}
|
|
12256
|
+
}
|
|
12257
|
+
async function saveLoggerToCache(cacheManager, persistence, snapshot) {
|
|
12258
|
+
const persistenceContext = resolvePersistenceContext$2(persistence);
|
|
12259
|
+
if (!persistenceContext) {
|
|
12260
|
+
return;
|
|
12261
|
+
}
|
|
12262
|
+
try {
|
|
12263
|
+
await cacheManager.set(persistenceContext.key, {
|
|
12264
|
+
...snapshot
|
|
12265
|
+
});
|
|
12266
|
+
} catch {
|
|
12267
|
+
// Ignore persistence failures and keep logger updates in memory.
|
|
12268
|
+
}
|
|
12269
|
+
}
|
|
12270
|
+
|
|
12271
|
+
function _define_property$4(obj, key, value) {
|
|
12272
|
+
if (key in obj) {
|
|
12273
|
+
Object.defineProperty(obj, key, {
|
|
12274
|
+
value: value,
|
|
12275
|
+
enumerable: true,
|
|
12276
|
+
configurable: true,
|
|
12277
|
+
writable: true
|
|
12278
|
+
});
|
|
12279
|
+
} else {
|
|
12280
|
+
obj[key] = value;
|
|
12281
|
+
}
|
|
12282
|
+
return obj;
|
|
12283
|
+
}
|
|
12356
12284
|
class LoggerManager {
|
|
12357
12285
|
async initialize(context) {
|
|
12358
12286
|
this.config = context.config.logger;
|
|
12359
|
-
|
|
12360
|
-
const
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
logger.
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
12368
|
-
|
|
12369
|
-
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
logger.logger.setLevel(this.level);
|
|
12375
|
-
await writePersistedValue(this.config.persistence, String(this.level));
|
|
12287
|
+
this.cacheManager = context.cacheManager;
|
|
12288
|
+
const initialSnapshot = normalizeLoggerSnapshot({
|
|
12289
|
+
level: this.config.level
|
|
12290
|
+
}, {
|
|
12291
|
+
level: logger.LogLevel.INFO
|
|
12292
|
+
});
|
|
12293
|
+
this.snapshot = await loadLoggerFromCache(this.cacheManager, this.config.persistence, initialSnapshot);
|
|
12294
|
+
logger.logger.setLevel(this.snapshot.level);
|
|
12295
|
+
this.initialized = true;
|
|
12296
|
+
}
|
|
12297
|
+
subscribe(listener) {
|
|
12298
|
+
this.listeners.add(listener);
|
|
12299
|
+
return ()=>{
|
|
12300
|
+
this.listeners.delete(listener);
|
|
12301
|
+
};
|
|
12376
12302
|
}
|
|
12377
12303
|
debug(...args) {
|
|
12378
12304
|
logger.logger.debug(...args);
|
|
@@ -12387,18 +12313,52 @@
|
|
|
12387
12313
|
logger.logger.error(...args);
|
|
12388
12314
|
}
|
|
12389
12315
|
async setLevel(level) {
|
|
12390
|
-
this.
|
|
12391
|
-
|
|
12392
|
-
|
|
12316
|
+
this.ensureInitialized();
|
|
12317
|
+
const prevSnapshot = this.snapshot;
|
|
12318
|
+
const nextSnapshot = normalizeLoggerSnapshot({
|
|
12319
|
+
level
|
|
12320
|
+
}, prevSnapshot);
|
|
12321
|
+
if (isLoggerEqual(prevSnapshot, nextSnapshot)) {
|
|
12322
|
+
return;
|
|
12323
|
+
}
|
|
12324
|
+
this.snapshot = nextSnapshot;
|
|
12325
|
+
logger.logger.setLevel(this.snapshot.level);
|
|
12326
|
+
if (this.cacheManager) {
|
|
12327
|
+
await saveLoggerToCache(this.cacheManager, this.config.persistence, this.snapshot);
|
|
12328
|
+
}
|
|
12329
|
+
this.emit(this.snapshot, prevSnapshot);
|
|
12393
12330
|
}
|
|
12394
12331
|
getSnapshot() {
|
|
12395
12332
|
return {
|
|
12396
|
-
|
|
12333
|
+
...this.snapshot
|
|
12397
12334
|
};
|
|
12398
12335
|
}
|
|
12336
|
+
ensureInitialized() {
|
|
12337
|
+
if (!this.initialized) {
|
|
12338
|
+
throw new Error('LoggerManager must be initialized before use.');
|
|
12339
|
+
}
|
|
12340
|
+
}
|
|
12341
|
+
emit(next, prev) {
|
|
12342
|
+
for (const listener of this.listeners){
|
|
12343
|
+
try {
|
|
12344
|
+
listener({
|
|
12345
|
+
...next
|
|
12346
|
+
}, {
|
|
12347
|
+
...prev
|
|
12348
|
+
});
|
|
12349
|
+
} catch {
|
|
12350
|
+
// Keep notifying remaining listeners even if one fails.
|
|
12351
|
+
}
|
|
12352
|
+
}
|
|
12353
|
+
}
|
|
12399
12354
|
constructor(){
|
|
12400
|
-
_define_property$4(this, "
|
|
12355
|
+
_define_property$4(this, "snapshot", {
|
|
12356
|
+
level: logger.LogLevel.INFO
|
|
12357
|
+
});
|
|
12401
12358
|
_define_property$4(this, "config", DEFAULT_CONFIG.logger);
|
|
12359
|
+
_define_property$4(this, "listeners", new Set());
|
|
12360
|
+
_define_property$4(this, "cacheManager", null);
|
|
12361
|
+
_define_property$4(this, "initialized", false);
|
|
12402
12362
|
}
|
|
12403
12363
|
}
|
|
12404
12364
|
|
|
@@ -12437,6 +12397,182 @@
|
|
|
12437
12397
|
}
|
|
12438
12398
|
}
|
|
12439
12399
|
|
|
12400
|
+
function canUseDom() {
|
|
12401
|
+
return typeof document !== 'undefined';
|
|
12402
|
+
}
|
|
12403
|
+
function resolveThemeMode(theme) {
|
|
12404
|
+
if (theme.mode !== 'system') {
|
|
12405
|
+
return theme.mode;
|
|
12406
|
+
}
|
|
12407
|
+
if (typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
12408
|
+
return 'dark';
|
|
12409
|
+
}
|
|
12410
|
+
return 'light';
|
|
12411
|
+
}
|
|
12412
|
+
function applyThemeToDocument(nextTheme, prevTheme) {
|
|
12413
|
+
if (!canUseDom()) {
|
|
12414
|
+
return;
|
|
12415
|
+
}
|
|
12416
|
+
const root = document.documentElement;
|
|
12417
|
+
const nextMode = resolveThemeMode(nextTheme);
|
|
12418
|
+
const prevMode = prevTheme ? resolveThemeMode(prevTheme) : undefined;
|
|
12419
|
+
if (!prevMode || prevMode !== nextMode) {
|
|
12420
|
+
root.classList.remove('light', 'dark');
|
|
12421
|
+
root.classList.add(nextMode);
|
|
12422
|
+
}
|
|
12423
|
+
if (!prevTheme || prevTheme.primaryColor !== nextTheme.primaryColor) {
|
|
12424
|
+
if (nextTheme.primaryColor) {
|
|
12425
|
+
root.style.setProperty('--app-primary-color', nextTheme.primaryColor);
|
|
12426
|
+
} else {
|
|
12427
|
+
root.style.removeProperty('--app-primary-color');
|
|
12428
|
+
}
|
|
12429
|
+
}
|
|
12430
|
+
const prevTokens = prevTheme?.tokens || {};
|
|
12431
|
+
const nextTokens = nextTheme.tokens || {};
|
|
12432
|
+
for (const token of Object.keys(prevTokens)){
|
|
12433
|
+
if (!(token in nextTokens)) {
|
|
12434
|
+
root.style.removeProperty(`--${token}`);
|
|
12435
|
+
}
|
|
12436
|
+
}
|
|
12437
|
+
for (const [token, value] of Object.entries(nextTokens)){
|
|
12438
|
+
if (!prevTheme || prevTokens[token] !== value) {
|
|
12439
|
+
root.style.setProperty(`--${token}`, String(value));
|
|
12440
|
+
}
|
|
12441
|
+
}
|
|
12442
|
+
}
|
|
12443
|
+
|
|
12444
|
+
const VALID_THEME_MODES = new Set([
|
|
12445
|
+
'light',
|
|
12446
|
+
'dark',
|
|
12447
|
+
'system'
|
|
12448
|
+
]);
|
|
12449
|
+
const TOKEN_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
12450
|
+
function isPlainObject$1(value) {
|
|
12451
|
+
return Object.prototype.toString.call(value) === '[object Object]';
|
|
12452
|
+
}
|
|
12453
|
+
function hasOwnProperty(value, key) {
|
|
12454
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
12455
|
+
}
|
|
12456
|
+
function cloneTheme(theme) {
|
|
12457
|
+
return {
|
|
12458
|
+
...theme,
|
|
12459
|
+
...theme.tokens ? {
|
|
12460
|
+
tokens: {
|
|
12461
|
+
...theme.tokens
|
|
12462
|
+
}
|
|
12463
|
+
} : {}
|
|
12464
|
+
};
|
|
12465
|
+
}
|
|
12466
|
+
function sanitizeTokens(tokens) {
|
|
12467
|
+
if (!isPlainObject$1(tokens)) {
|
|
12468
|
+
return undefined;
|
|
12469
|
+
}
|
|
12470
|
+
const sanitizedTokens = {};
|
|
12471
|
+
for (const [token, tokenValue] of Object.entries(tokens)){
|
|
12472
|
+
if (!TOKEN_NAME_PATTERN.test(token)) {
|
|
12473
|
+
continue;
|
|
12474
|
+
}
|
|
12475
|
+
if (typeof tokenValue === 'string' || typeof tokenValue === 'number') {
|
|
12476
|
+
sanitizedTokens[token] = tokenValue;
|
|
12477
|
+
}
|
|
12478
|
+
}
|
|
12479
|
+
return Object.keys(sanitizedTokens).length > 0 ? sanitizedTokens : undefined;
|
|
12480
|
+
}
|
|
12481
|
+
function normalizeTheme(value, fallback) {
|
|
12482
|
+
const source = isPlainObject$1(value) ? value : {};
|
|
12483
|
+
const mode = VALID_THEME_MODES.has(source.mode) ? source.mode : fallback.mode;
|
|
12484
|
+
const primaryColor = typeof source.primaryColor === 'string' && source.primaryColor.trim() ? source.primaryColor : fallback.primaryColor;
|
|
12485
|
+
const fallbackTokens = sanitizeTokens(fallback.tokens);
|
|
12486
|
+
const incomingTokens = sanitizeTokens(source.tokens);
|
|
12487
|
+
return {
|
|
12488
|
+
mode,
|
|
12489
|
+
...primaryColor ? {
|
|
12490
|
+
primaryColor
|
|
12491
|
+
} : {},
|
|
12492
|
+
...incomingTokens || fallbackTokens ? {
|
|
12493
|
+
tokens: {
|
|
12494
|
+
...fallbackTokens || {},
|
|
12495
|
+
...incomingTokens || {}
|
|
12496
|
+
}
|
|
12497
|
+
} : {}
|
|
12498
|
+
};
|
|
12499
|
+
}
|
|
12500
|
+
function mergeTheme(current, next) {
|
|
12501
|
+
const mergedTheme = {
|
|
12502
|
+
mode: hasOwnProperty(next, 'mode') && VALID_THEME_MODES.has(next.mode) ? next.mode : current.mode,
|
|
12503
|
+
...hasOwnProperty(next, 'primaryColor') ? typeof next.primaryColor === 'string' && next.primaryColor.trim() ? {
|
|
12504
|
+
primaryColor: next.primaryColor
|
|
12505
|
+
} : {} : current.primaryColor ? {
|
|
12506
|
+
primaryColor: current.primaryColor
|
|
12507
|
+
} : {},
|
|
12508
|
+
...hasOwnProperty(next, 'tokens') ? sanitizeTokens(next.tokens) ? {
|
|
12509
|
+
tokens: sanitizeTokens(next.tokens)
|
|
12510
|
+
} : {} : current.tokens ? {
|
|
12511
|
+
tokens: {
|
|
12512
|
+
...current.tokens
|
|
12513
|
+
}
|
|
12514
|
+
} : {}
|
|
12515
|
+
};
|
|
12516
|
+
return normalizeTheme(mergedTheme, DEFAULT_EMPTY_THEME);
|
|
12517
|
+
}
|
|
12518
|
+
const DEFAULT_EMPTY_THEME = {
|
|
12519
|
+
mode: 'light'
|
|
12520
|
+
};
|
|
12521
|
+
function isThemeEqual(left, right) {
|
|
12522
|
+
if (left.mode !== right.mode || left.primaryColor !== right.primaryColor) {
|
|
12523
|
+
return false;
|
|
12524
|
+
}
|
|
12525
|
+
const leftTokens = left.tokens || {};
|
|
12526
|
+
const rightTokens = right.tokens || {};
|
|
12527
|
+
const leftKeys = Object.keys(leftTokens);
|
|
12528
|
+
const rightKeys = Object.keys(rightTokens);
|
|
12529
|
+
if (leftKeys.length !== rightKeys.length) {
|
|
12530
|
+
return false;
|
|
12531
|
+
}
|
|
12532
|
+
for (const key of leftKeys){
|
|
12533
|
+
if (leftTokens[key] !== rightTokens[key]) {
|
|
12534
|
+
return false;
|
|
12535
|
+
}
|
|
12536
|
+
}
|
|
12537
|
+
return true;
|
|
12538
|
+
}
|
|
12539
|
+
|
|
12540
|
+
const DEFAULT_THEME_CACHE_KEY = 'vlian:kernel:theme';
|
|
12541
|
+
function resolvePersistenceContext$1(persistence) {
|
|
12542
|
+
if (persistence?.enabled !== true) {
|
|
12543
|
+
return null;
|
|
12544
|
+
}
|
|
12545
|
+
return {
|
|
12546
|
+
key: persistence.key || DEFAULT_THEME_CACHE_KEY
|
|
12547
|
+
};
|
|
12548
|
+
}
|
|
12549
|
+
async function loadThemeFromCache(cacheManager, persistence, fallback) {
|
|
12550
|
+
const persistenceContext = resolvePersistenceContext$1(persistence);
|
|
12551
|
+
const safeFallback = cloneTheme(fallback);
|
|
12552
|
+
if (!persistenceContext) {
|
|
12553
|
+
return safeFallback;
|
|
12554
|
+
}
|
|
12555
|
+
try {
|
|
12556
|
+
const cached = await cacheManager.get(persistenceContext.key, {
|
|
12557
|
+
defaultValue: safeFallback
|
|
12558
|
+
});
|
|
12559
|
+
return normalizeTheme(cached, safeFallback);
|
|
12560
|
+
} catch {
|
|
12561
|
+
return safeFallback;
|
|
12562
|
+
}
|
|
12563
|
+
}
|
|
12564
|
+
async function saveThemeToCache(cacheManager, persistence, theme) {
|
|
12565
|
+
const persistenceContext = resolvePersistenceContext$1(persistence);
|
|
12566
|
+
if (!persistenceContext) {
|
|
12567
|
+
return;
|
|
12568
|
+
}
|
|
12569
|
+
try {
|
|
12570
|
+
await cacheManager.set(persistenceContext.key, cloneTheme(theme));
|
|
12571
|
+
} catch {
|
|
12572
|
+
// Ignore persistence failures and keep theme updates in memory.
|
|
12573
|
+
}
|
|
12574
|
+
}
|
|
12575
|
+
|
|
12440
12576
|
function _define_property$2(obj, key, value) {
|
|
12441
12577
|
if (key in obj) {
|
|
12442
12578
|
Object.defineProperty(obj, key, {
|
|
@@ -12450,49 +12586,20 @@
|
|
|
12450
12586
|
}
|
|
12451
12587
|
return obj;
|
|
12452
12588
|
}
|
|
12453
|
-
function applyThemeToDocument(theme) {
|
|
12454
|
-
if (typeof document === 'undefined') {
|
|
12455
|
-
return;
|
|
12456
|
-
}
|
|
12457
|
-
const root = document.documentElement;
|
|
12458
|
-
root.classList.remove('light', 'dark');
|
|
12459
|
-
const resolvedMode = theme.mode === 'system' ? typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' : theme.mode;
|
|
12460
|
-
root.classList.add(resolvedMode);
|
|
12461
|
-
if (theme.primaryColor) {
|
|
12462
|
-
root.style.setProperty('--app-primary-color', theme.primaryColor);
|
|
12463
|
-
}
|
|
12464
|
-
if (theme.tokens) {
|
|
12465
|
-
Object.entries(theme.tokens).forEach(([token, tokenValue])=>{
|
|
12466
|
-
root.style.setProperty(`--${token}`, String(tokenValue));
|
|
12467
|
-
});
|
|
12468
|
-
}
|
|
12469
|
-
}
|
|
12470
12589
|
class ThemeManager {
|
|
12471
12590
|
async initialize(context) {
|
|
12472
12591
|
this.config = context.config.theme;
|
|
12473
|
-
this.
|
|
12474
|
-
|
|
12475
|
-
|
|
12476
|
-
};
|
|
12477
|
-
this.cache = context.cacheManager;
|
|
12478
|
-
const { key = "vlian:kernel:theme" } = this.config.persistence || {};
|
|
12479
|
-
const persisted = await this.cache.get(key, {
|
|
12480
|
-
defaultValue: this.theme
|
|
12481
|
-
});
|
|
12482
|
-
if (persisted !== null) {
|
|
12483
|
-
this.theme = {
|
|
12484
|
-
...this.theme,
|
|
12485
|
-
...persisted
|
|
12486
|
-
};
|
|
12487
|
-
} else {
|
|
12488
|
-
await this.cache.set(key, persisted);
|
|
12489
|
-
}
|
|
12592
|
+
this.cacheManager = context.cacheManager;
|
|
12593
|
+
const initialTheme = normalizeTheme(this.config.initial || {}, DEFAULT_THEME);
|
|
12594
|
+
this.theme = await loadThemeFromCache(this.cacheManager, this.config.persistence, initialTheme);
|
|
12490
12595
|
applyThemeToDocument(this.theme);
|
|
12596
|
+
this.initialized = true;
|
|
12491
12597
|
}
|
|
12492
12598
|
getTheme() {
|
|
12493
|
-
return
|
|
12494
|
-
|
|
12495
|
-
|
|
12599
|
+
return cloneTheme(this.theme);
|
|
12600
|
+
}
|
|
12601
|
+
getSnapshot() {
|
|
12602
|
+
return this.getTheme();
|
|
12496
12603
|
}
|
|
12497
12604
|
subscribe(listener) {
|
|
12498
12605
|
this.listeners.add(listener);
|
|
@@ -12500,34 +12607,139 @@
|
|
|
12500
12607
|
this.listeners.delete(listener);
|
|
12501
12608
|
};
|
|
12502
12609
|
}
|
|
12503
|
-
emit(next, prev) {
|
|
12504
|
-
this.listeners.forEach((listener)=>{
|
|
12505
|
-
listener({
|
|
12506
|
-
...next
|
|
12507
|
-
}, {
|
|
12508
|
-
...prev
|
|
12509
|
-
});
|
|
12510
|
-
});
|
|
12511
|
-
}
|
|
12512
12610
|
async setTheme(nextTheme) {
|
|
12513
|
-
|
|
12514
|
-
this.theme
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
12521
|
-
|
|
12611
|
+
this.ensureInitialized();
|
|
12612
|
+
const prevTheme = this.theme;
|
|
12613
|
+
const mergedTheme = mergeTheme(prevTheme, nextTheme);
|
|
12614
|
+
if (isThemeEqual(prevTheme, mergedTheme)) {
|
|
12615
|
+
return;
|
|
12616
|
+
}
|
|
12617
|
+
this.theme = mergedTheme;
|
|
12618
|
+
applyThemeToDocument(this.theme, prevTheme);
|
|
12619
|
+
if (this.cacheManager) {
|
|
12620
|
+
await saveThemeToCache(this.cacheManager, this.config.persistence, this.theme);
|
|
12621
|
+
}
|
|
12622
|
+
this.emit(this.theme, prevTheme);
|
|
12522
12623
|
}
|
|
12523
|
-
|
|
12524
|
-
|
|
12624
|
+
ensureInitialized() {
|
|
12625
|
+
if (!this.initialized) {
|
|
12626
|
+
throw new Error('ThemeManager must be initialized before use.');
|
|
12627
|
+
}
|
|
12628
|
+
}
|
|
12629
|
+
emit(next, prev) {
|
|
12630
|
+
for (const listener of this.listeners){
|
|
12631
|
+
try {
|
|
12632
|
+
listener(cloneTheme(next), cloneTheme(prev));
|
|
12633
|
+
} catch {
|
|
12634
|
+
// Keep notifying remaining listeners even if one fails.
|
|
12635
|
+
}
|
|
12636
|
+
}
|
|
12525
12637
|
}
|
|
12526
12638
|
constructor(){
|
|
12527
|
-
_define_property$2(this, "theme", DEFAULT_THEME);
|
|
12639
|
+
_define_property$2(this, "theme", cloneTheme(DEFAULT_THEME));
|
|
12528
12640
|
_define_property$2(this, "config", DEFAULT_CONFIG.theme);
|
|
12529
12641
|
_define_property$2(this, "listeners", new Set());
|
|
12530
|
-
_define_property$2(this, "
|
|
12642
|
+
_define_property$2(this, "cacheManager", null);
|
|
12643
|
+
_define_property$2(this, "initialized", false);
|
|
12644
|
+
}
|
|
12645
|
+
}
|
|
12646
|
+
|
|
12647
|
+
function isPlainObject(value) {
|
|
12648
|
+
return Object.prototype.toString.call(value) === '[object Object]';
|
|
12649
|
+
}
|
|
12650
|
+
function cloneI18nSnapshot(snapshot) {
|
|
12651
|
+
const resources = snapshot.resources ? Object.fromEntries(Object.entries(snapshot.resources).map(([locale, value])=>[
|
|
12652
|
+
locale,
|
|
12653
|
+
{
|
|
12654
|
+
...value
|
|
12655
|
+
}
|
|
12656
|
+
])) : undefined;
|
|
12657
|
+
return {
|
|
12658
|
+
locale: snapshot.locale,
|
|
12659
|
+
...resources ? {
|
|
12660
|
+
resources
|
|
12661
|
+
} : {}
|
|
12662
|
+
};
|
|
12663
|
+
}
|
|
12664
|
+
function normalizeI18nSnapshot(value, fallback) {
|
|
12665
|
+
const source = isPlainObject(value) ? value : {};
|
|
12666
|
+
const locale = typeof source.locale === 'string' && source.locale.trim() ? source.locale : fallback.locale;
|
|
12667
|
+
const fallbackResources = fallback.resources;
|
|
12668
|
+
const incomingResources = isPlainObject(source.resources) ? Object.fromEntries(Object.entries(source.resources).filter(([, resourceValue])=>isPlainObject(resourceValue)).map(([locale, resourceValue])=>[
|
|
12669
|
+
locale,
|
|
12670
|
+
{
|
|
12671
|
+
...resourceValue
|
|
12672
|
+
}
|
|
12673
|
+
])) : undefined;
|
|
12674
|
+
const resources = incomingResources || fallbackResources ? {
|
|
12675
|
+
...fallbackResources || {},
|
|
12676
|
+
...incomingResources || {}
|
|
12677
|
+
} : undefined;
|
|
12678
|
+
return {
|
|
12679
|
+
locale,
|
|
12680
|
+
...resources ? {
|
|
12681
|
+
resources
|
|
12682
|
+
} : {}
|
|
12683
|
+
};
|
|
12684
|
+
}
|
|
12685
|
+
function mergeI18nSnapshot(current, next) {
|
|
12686
|
+
return normalizeI18nSnapshot({
|
|
12687
|
+
locale: next.locale ?? current.locale,
|
|
12688
|
+
resources: next.resources ?? current.resources
|
|
12689
|
+
}, current);
|
|
12690
|
+
}
|
|
12691
|
+
function isI18nEqual(left, right) {
|
|
12692
|
+
if (left.locale !== right.locale) {
|
|
12693
|
+
return false;
|
|
12694
|
+
}
|
|
12695
|
+
const leftResources = left.resources || {};
|
|
12696
|
+
const rightResources = right.resources || {};
|
|
12697
|
+
const leftLocales = Object.keys(leftResources);
|
|
12698
|
+
const rightLocales = Object.keys(rightResources);
|
|
12699
|
+
if (leftLocales.length !== rightLocales.length) {
|
|
12700
|
+
return false;
|
|
12701
|
+
}
|
|
12702
|
+
for (const locale of leftLocales){
|
|
12703
|
+
if (leftResources[locale] !== rightResources[locale]) {
|
|
12704
|
+
return false;
|
|
12705
|
+
}
|
|
12706
|
+
}
|
|
12707
|
+
return true;
|
|
12708
|
+
}
|
|
12709
|
+
|
|
12710
|
+
const DEFAULT_I18N_CACHE_KEY = 'vlian:kernel:i18n';
|
|
12711
|
+
function resolvePersistenceContext(persistence) {
|
|
12712
|
+
if (persistence?.enabled !== true) {
|
|
12713
|
+
return null;
|
|
12714
|
+
}
|
|
12715
|
+
return {
|
|
12716
|
+
key: persistence.key || DEFAULT_I18N_CACHE_KEY
|
|
12717
|
+
};
|
|
12718
|
+
}
|
|
12719
|
+
async function loadI18nFromCache(cacheManager, persistence, fallback) {
|
|
12720
|
+
const persistenceContext = resolvePersistenceContext(persistence);
|
|
12721
|
+
const safeFallback = cloneI18nSnapshot(fallback);
|
|
12722
|
+
if (!persistenceContext) {
|
|
12723
|
+
return safeFallback;
|
|
12724
|
+
}
|
|
12725
|
+
try {
|
|
12726
|
+
const cached = await cacheManager.get(persistenceContext.key, {
|
|
12727
|
+
defaultValue: safeFallback
|
|
12728
|
+
});
|
|
12729
|
+
return normalizeI18nSnapshot(cached, safeFallback);
|
|
12730
|
+
} catch {
|
|
12731
|
+
return safeFallback;
|
|
12732
|
+
}
|
|
12733
|
+
}
|
|
12734
|
+
async function saveI18nToCache(cacheManager, persistence, snapshot) {
|
|
12735
|
+
const persistenceContext = resolvePersistenceContext(persistence);
|
|
12736
|
+
if (!persistenceContext) {
|
|
12737
|
+
return;
|
|
12738
|
+
}
|
|
12739
|
+
try {
|
|
12740
|
+
await cacheManager.set(persistenceContext.key, cloneI18nSnapshot(snapshot));
|
|
12741
|
+
} catch {
|
|
12742
|
+
// Ignore persistence failures and keep i18n updates in memory.
|
|
12531
12743
|
}
|
|
12532
12744
|
}
|
|
12533
12745
|
|
|
@@ -12547,31 +12759,21 @@
|
|
|
12547
12759
|
class I18nManager {
|
|
12548
12760
|
async initialize(context) {
|
|
12549
12761
|
this.config = context.config.i18n;
|
|
12550
|
-
this.
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
} catch {
|
|
12563
|
-
// ignore parse errors
|
|
12564
|
-
}
|
|
12565
|
-
} else {
|
|
12566
|
-
await writePersistedValue(this.config.persistence, JSON.stringify(this.snapshot));
|
|
12567
|
-
}
|
|
12568
|
-
await setupI18n(this.snapshot.resources || {});
|
|
12569
|
-
setLang(this.snapshot.locale);
|
|
12762
|
+
this.cacheManager = context.cacheManager;
|
|
12763
|
+
const initialSnapshot = normalizeI18nSnapshot(this.config.initial || {}, DEFAULT_I18N);
|
|
12764
|
+
this.snapshot = await loadI18nFromCache(this.cacheManager, this.config.persistence, initialSnapshot);
|
|
12765
|
+
await setupI18n({
|
|
12766
|
+
interpolation: {
|
|
12767
|
+
escapeValue: false
|
|
12768
|
+
},
|
|
12769
|
+
lng: this.snapshot.locale || "zh-CN",
|
|
12770
|
+
resources: this.snapshot.resources
|
|
12771
|
+
});
|
|
12772
|
+
await setLang(this.snapshot.locale);
|
|
12773
|
+
this.initialized = true;
|
|
12570
12774
|
}
|
|
12571
12775
|
getSnapshot() {
|
|
12572
|
-
return
|
|
12573
|
-
...this.snapshot
|
|
12574
|
-
};
|
|
12776
|
+
return cloneI18nSnapshot(this.snapshot);
|
|
12575
12777
|
}
|
|
12576
12778
|
subscribe(listener) {
|
|
12577
12779
|
this.listeners.add(listener);
|
|
@@ -12579,29 +12781,43 @@
|
|
|
12579
12781
|
this.listeners.delete(listener);
|
|
12580
12782
|
};
|
|
12581
12783
|
}
|
|
12582
|
-
emit(next, prev) {
|
|
12583
|
-
this.listeners.forEach((listener)=>{
|
|
12584
|
-
listener({
|
|
12585
|
-
...next
|
|
12586
|
-
}, {
|
|
12587
|
-
...prev
|
|
12588
|
-
});
|
|
12589
|
-
});
|
|
12590
|
-
}
|
|
12591
12784
|
async setLocale(locale) {
|
|
12592
|
-
|
|
12593
|
-
this.snapshot
|
|
12594
|
-
|
|
12785
|
+
this.ensureInitialized();
|
|
12786
|
+
const prevSnapshot = this.snapshot;
|
|
12787
|
+
const nextSnapshot = mergeI18nSnapshot(prevSnapshot, {
|
|
12595
12788
|
locale
|
|
12596
|
-
};
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
|
|
12789
|
+
});
|
|
12790
|
+
if (isI18nEqual(prevSnapshot, nextSnapshot)) {
|
|
12791
|
+
return;
|
|
12792
|
+
}
|
|
12793
|
+
this.snapshot = nextSnapshot;
|
|
12794
|
+
// set lang
|
|
12795
|
+
await setLang(this.snapshot.locale);
|
|
12796
|
+
if (this.cacheManager) {
|
|
12797
|
+
await saveI18nToCache(this.cacheManager, this.config.persistence, this.snapshot);
|
|
12798
|
+
}
|
|
12799
|
+
this.emit(this.snapshot, prevSnapshot);
|
|
12800
|
+
}
|
|
12801
|
+
ensureInitialized() {
|
|
12802
|
+
if (!this.initialized) {
|
|
12803
|
+
throw new Error('I18nManager must be initialized before use.');
|
|
12804
|
+
}
|
|
12805
|
+
}
|
|
12806
|
+
emit(next, prev) {
|
|
12807
|
+
for (const listener of this.listeners){
|
|
12808
|
+
try {
|
|
12809
|
+
listener(cloneI18nSnapshot(next), cloneI18nSnapshot(prev));
|
|
12810
|
+
} catch {
|
|
12811
|
+
// Keep notifying remaining listeners even if one fails.
|
|
12812
|
+
}
|
|
12813
|
+
}
|
|
12600
12814
|
}
|
|
12601
12815
|
constructor(){
|
|
12602
|
-
_define_property$1(this, "snapshot", DEFAULT_I18N);
|
|
12816
|
+
_define_property$1(this, "snapshot", cloneI18nSnapshot(DEFAULT_I18N));
|
|
12603
12817
|
_define_property$1(this, "config", DEFAULT_CONFIG.i18n);
|
|
12604
12818
|
_define_property$1(this, "listeners", new Set());
|
|
12819
|
+
_define_property$1(this, "cacheManager", null);
|
|
12820
|
+
_define_property$1(this, "initialized", false);
|
|
12605
12821
|
}
|
|
12606
12822
|
}
|
|
12607
12823
|
|