viewlogic 1.1.2 β 1.1.3
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
|
@@ -260,6 +260,75 @@ const config = {
|
|
|
260
260
|
};
|
|
261
261
|
```
|
|
262
262
|
|
|
263
|
+
### ποΈ Subfolder Deployment Support
|
|
264
|
+
|
|
265
|
+
ViewLogic Router supports deployment in subfolders with smart path resolution:
|
|
266
|
+
|
|
267
|
+
```javascript
|
|
268
|
+
// Root deployment: https://example.com/
|
|
269
|
+
ViewLogicRouter({
|
|
270
|
+
basePath: '/src', // β https://example.com/src
|
|
271
|
+
routesPath: '/routes', // β https://example.com/routes
|
|
272
|
+
i18nPath: '/i18n' // β https://example.com/i18n
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Subfolder deployment: https://example.com/myapp/
|
|
276
|
+
ViewLogicRouter({
|
|
277
|
+
basePath: 'src', // β https://example.com/myapp/src (relative)
|
|
278
|
+
routesPath: 'routes', // β https://example.com/myapp/routes (relative)
|
|
279
|
+
i18nPath: 'i18n', // β https://example.com/myapp/i18n (relative)
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// Mixed paths: https://example.com/projects/myapp/
|
|
283
|
+
ViewLogicRouter({
|
|
284
|
+
basePath: './src', // β https://example.com/projects/myapp/src
|
|
285
|
+
routesPath: '../shared/routes', // β https://example.com/projects/shared/routes
|
|
286
|
+
i18nPath: '/global/i18n' // β https://example.com/global/i18n (absolute)
|
|
287
|
+
});
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**Path Resolution Rules:**
|
|
291
|
+
- **Absolute paths** (`/path`) β `https://domain.com/path`
|
|
292
|
+
- **Relative paths** (`path`, `./path`) β Resolved from current page location
|
|
293
|
+
- **Parent paths** (`../path`) β Navigate up directory levels
|
|
294
|
+
- **HTTP URLs** β Used as-is (no processing)
|
|
295
|
+
|
|
296
|
+
### π Hash vs History Mode in Subfolders
|
|
297
|
+
|
|
298
|
+
Both routing modes work seamlessly in subfolder deployments:
|
|
299
|
+
|
|
300
|
+
```javascript
|
|
301
|
+
// Hash Mode (recommended for subfolders)
|
|
302
|
+
// URL: https://example.com/myapp/#/products?id=123
|
|
303
|
+
ViewLogicRouter({
|
|
304
|
+
mode: 'hash' // Works anywhere, no server config needed
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// History Mode (requires server configuration)
|
|
308
|
+
// URL: https://example.com/myapp/products?id=123
|
|
309
|
+
ViewLogicRouter({
|
|
310
|
+
mode: 'history' // Cleaner URLs, needs server setup
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**History Mode Server Configuration:**
|
|
315
|
+
```nginx
|
|
316
|
+
# Nginx - redirect all subfolder requests to index.html
|
|
317
|
+
location /myapp/ {
|
|
318
|
+
try_files $uri $uri/ /myapp/index.html;
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
```apache
|
|
323
|
+
# Apache .htaccess in /myapp/ folder
|
|
324
|
+
RewriteEngine On
|
|
325
|
+
RewriteBase /myapp/
|
|
326
|
+
RewriteRule ^index\.html$ - [L]
|
|
327
|
+
RewriteCond %{REQUEST_FILENAME} !-f
|
|
328
|
+
RewriteCond %{REQUEST_FILENAME} !-d
|
|
329
|
+
RewriteRule . /myapp/index.html [L]
|
|
330
|
+
```
|
|
331
|
+
|
|
263
332
|
## π Complete API Documentation
|
|
264
333
|
|
|
265
334
|
For comprehensive API documentation including all methods, configuration options, and detailed examples, see:
|
package/dist/viewlogic-router.js
CHANGED
|
@@ -42,6 +42,8 @@ var I18nManager = class {
|
|
|
42
42
|
await this.loadMessages(this.currentLanguage);
|
|
43
43
|
} catch (error) {
|
|
44
44
|
this.log("error", "Failed to load initial language file:", error);
|
|
45
|
+
this.messages.set(this.currentLanguage, {});
|
|
46
|
+
this.log("info", "Using empty message object as fallback");
|
|
45
47
|
}
|
|
46
48
|
} else {
|
|
47
49
|
this.log("debug", "Language messages already loaded:", this.currentLanguage);
|
|
@@ -98,9 +100,17 @@ var I18nManager = class {
|
|
|
98
100
|
this.log("info", "Language changed successfully", { from: oldLanguage, to: language });
|
|
99
101
|
return true;
|
|
100
102
|
} catch (error) {
|
|
101
|
-
this.
|
|
102
|
-
this.
|
|
103
|
-
|
|
103
|
+
this.log("error", "Failed to load messages for language change, using empty messages:", error);
|
|
104
|
+
this.messages.set(language, {});
|
|
105
|
+
this.saveLanguageToCache(language);
|
|
106
|
+
this.emit("languageChanged", {
|
|
107
|
+
from: oldLanguage,
|
|
108
|
+
to: language,
|
|
109
|
+
messages: {},
|
|
110
|
+
error: true
|
|
111
|
+
});
|
|
112
|
+
this.log("warn", "Language changed with empty messages", { from: oldLanguage, to: language });
|
|
113
|
+
return true;
|
|
104
114
|
}
|
|
105
115
|
}
|
|
106
116
|
/**
|
|
@@ -136,7 +146,10 @@ var I18nManager = class {
|
|
|
136
146
|
return messages;
|
|
137
147
|
} catch (error) {
|
|
138
148
|
this.loadPromises.delete(language);
|
|
139
|
-
|
|
149
|
+
this.log("error", "Failed to load messages, using empty fallback for:", language, error);
|
|
150
|
+
const emptyMessages = {};
|
|
151
|
+
this.messages.set(language, emptyMessages);
|
|
152
|
+
return emptyMessages;
|
|
140
153
|
}
|
|
141
154
|
}
|
|
142
155
|
/**
|
|
@@ -165,9 +178,15 @@ var I18nManager = class {
|
|
|
165
178
|
this.log("error", "Failed to load messages file for:", language, error);
|
|
166
179
|
if (language !== this.config.fallbackLanguage) {
|
|
167
180
|
this.log("info", "Trying fallback language:", this.config.fallbackLanguage);
|
|
168
|
-
|
|
181
|
+
try {
|
|
182
|
+
return await this._loadMessagesFromFile(this.config.fallbackLanguage);
|
|
183
|
+
} catch (fallbackError) {
|
|
184
|
+
this.log("error", "Fallback language also failed:", fallbackError);
|
|
185
|
+
return {};
|
|
186
|
+
}
|
|
169
187
|
}
|
|
170
|
-
|
|
188
|
+
this.log("warn", `No messages available for language: ${language}, using empty fallback`);
|
|
189
|
+
return {};
|
|
171
190
|
}
|
|
172
191
|
}
|
|
173
192
|
/**
|
|
@@ -352,7 +371,8 @@ var I18nManager = class {
|
|
|
352
371
|
return true;
|
|
353
372
|
} catch (error) {
|
|
354
373
|
this.log("error", "I18n initialization failed:", error);
|
|
355
|
-
|
|
374
|
+
this.log("info", "I18n system ready with fallback behavior");
|
|
375
|
+
return true;
|
|
356
376
|
}
|
|
357
377
|
}
|
|
358
378
|
/**
|
|
@@ -413,7 +433,8 @@ var I18nManager = class {
|
|
|
413
433
|
return true;
|
|
414
434
|
} catch (error) {
|
|
415
435
|
this.log("error", "Failed to initialize I18n system:", error);
|
|
416
|
-
|
|
436
|
+
this.log("info", "I18n system will continue with fallback behavior");
|
|
437
|
+
return true;
|
|
417
438
|
}
|
|
418
439
|
}
|
|
419
440
|
};
|
|
@@ -972,6 +993,7 @@ var CacheManager = class {
|
|
|
972
993
|
this.cacheTimestamps.clear();
|
|
973
994
|
this.lruOrder = [];
|
|
974
995
|
this.log(`\u{1F525} Cleared all cache (${size} entries)`);
|
|
996
|
+
return size;
|
|
975
997
|
}
|
|
976
998
|
/**
|
|
977
999
|
* λ§λ£λ μΊμ νλͺ©λ€ μ 리
|
|
@@ -1464,8 +1486,10 @@ var QueryManager = class {
|
|
|
1464
1486
|
var RouteLoader = class {
|
|
1465
1487
|
constructor(router, options = {}) {
|
|
1466
1488
|
this.config = {
|
|
1467
|
-
|
|
1468
|
-
|
|
1489
|
+
srcPath: options.srcPath || router.config.srcPath || "/src",
|
|
1490
|
+
// μμ€ νμΌ κ²½λ‘
|
|
1491
|
+
routesPath: options.routesPath || router.config.routesPath || "/routes",
|
|
1492
|
+
// νλ‘λμ
λΌμ°νΈ κ²½λ‘
|
|
1469
1493
|
environment: options.environment || "development",
|
|
1470
1494
|
useLayout: options.useLayout !== false,
|
|
1471
1495
|
defaultLayout: options.defaultLayout || "default",
|
|
@@ -1487,7 +1511,7 @@ var RouteLoader = class {
|
|
|
1487
1511
|
const module = await import(importPath);
|
|
1488
1512
|
script = module.default;
|
|
1489
1513
|
} else {
|
|
1490
|
-
const importPath = `${this.config.
|
|
1514
|
+
const importPath = `${this.config.srcPath}/logic/${routeName}.js`;
|
|
1491
1515
|
this.log("debug", `Loading development route: ${importPath}`);
|
|
1492
1516
|
const module = await import(importPath);
|
|
1493
1517
|
script = module.default;
|
|
@@ -1508,7 +1532,7 @@ var RouteLoader = class {
|
|
|
1508
1532
|
*/
|
|
1509
1533
|
async loadTemplate(routeName) {
|
|
1510
1534
|
try {
|
|
1511
|
-
const templatePath = `${this.config.
|
|
1535
|
+
const templatePath = `${this.config.srcPath}/views/${routeName}.html`;
|
|
1512
1536
|
const response = await fetch(templatePath);
|
|
1513
1537
|
if (!response.ok) throw new Error(`Template not found: ${response.status}`);
|
|
1514
1538
|
const template = await response.text();
|
|
@@ -1524,7 +1548,7 @@ var RouteLoader = class {
|
|
|
1524
1548
|
*/
|
|
1525
1549
|
async loadStyle(routeName) {
|
|
1526
1550
|
try {
|
|
1527
|
-
const stylePath = `${this.config.
|
|
1551
|
+
const stylePath = `${this.config.srcPath}/styles/${routeName}.css`;
|
|
1528
1552
|
const response = await fetch(stylePath);
|
|
1529
1553
|
if (!response.ok) throw new Error(`Style not found: ${response.status}`);
|
|
1530
1554
|
const style = await response.text();
|
|
@@ -1540,7 +1564,7 @@ var RouteLoader = class {
|
|
|
1540
1564
|
*/
|
|
1541
1565
|
async loadLayout(layoutName) {
|
|
1542
1566
|
try {
|
|
1543
|
-
const layoutPath = `${this.config.
|
|
1567
|
+
const layoutPath = `${this.config.srcPath}/layouts/${layoutName}.html`;
|
|
1544
1568
|
const response = await fetch(layoutPath);
|
|
1545
1569
|
if (!response.ok) throw new Error(`Layout not found: ${response.status}`);
|
|
1546
1570
|
const layout = await response.text();
|
|
@@ -1618,7 +1642,14 @@ ${template}`;
|
|
|
1618
1642
|
...originalData,
|
|
1619
1643
|
currentRoute: routeName,
|
|
1620
1644
|
$query: router.queryManager?.getQueryParams() || {},
|
|
1621
|
-
$lang:
|
|
1645
|
+
$lang: (() => {
|
|
1646
|
+
try {
|
|
1647
|
+
return router.i18nManager?.getCurrentLanguage() || router.config.i18nDefaultLanguage || router.config.defaultLanguage || "ko";
|
|
1648
|
+
} catch (error) {
|
|
1649
|
+
if (router.errorHandler) router.errorHandler.warn("RouteLoader", "Failed to get current language:", error);
|
|
1650
|
+
return router.config.defaultLanguage || "ko";
|
|
1651
|
+
}
|
|
1652
|
+
})(),
|
|
1622
1653
|
$dataLoading: false
|
|
1623
1654
|
};
|
|
1624
1655
|
return commonData;
|
|
@@ -1652,8 +1683,15 @@ ${template}`;
|
|
|
1652
1683
|
// ν΅ν©λ νλΌλ―Έν° κ΄λ¦¬ (λΌμ°ν
+ 쿼리 νλΌλ―Έν°)
|
|
1653
1684
|
getParams: () => router.queryManager?.getAllParams() || {},
|
|
1654
1685
|
getParam: (key, defaultValue) => router.queryManager?.getParam(key, defaultValue),
|
|
1655
|
-
// i18n κ΄λ ¨
|
|
1656
|
-
$t: (key, params) =>
|
|
1686
|
+
// i18n κ΄λ ¨ (resilient - i18n μ€ν¨ν΄λ key λ°ν)
|
|
1687
|
+
$t: (key, params) => {
|
|
1688
|
+
try {
|
|
1689
|
+
return router.i18nManager?.t(key, params) || key;
|
|
1690
|
+
} catch (error) {
|
|
1691
|
+
if (router.errorHandler) router.errorHandler.warn("RouteLoader", "i18n translation failed, returning key:", error);
|
|
1692
|
+
return key;
|
|
1693
|
+
}
|
|
1694
|
+
},
|
|
1657
1695
|
// μΈμ¦ κ΄λ ¨
|
|
1658
1696
|
$isAuthenticated: () => router.authManager?.isUserAuthenticated() || false,
|
|
1659
1697
|
$logout: () => router.authManager ? router.navigateTo(router.authManager.handleLogout()) : null,
|
|
@@ -1968,7 +2006,7 @@ ${template}`;
|
|
|
1968
2006
|
getStats() {
|
|
1969
2007
|
return {
|
|
1970
2008
|
environment: this.config.environment,
|
|
1971
|
-
|
|
2009
|
+
srcPath: this.config.srcPath,
|
|
1972
2010
|
routesPath: this.config.routesPath,
|
|
1973
2011
|
useLayout: this.config.useLayout,
|
|
1974
2012
|
useComponents: this.config.useComponents
|
|
@@ -2272,7 +2310,8 @@ var ErrorHandler = class {
|
|
|
2272
2310
|
var ComponentLoader = class {
|
|
2273
2311
|
constructor(router = null, options = {}) {
|
|
2274
2312
|
this.config = {
|
|
2275
|
-
|
|
2313
|
+
componentsPath: options.componentsPath || "/components",
|
|
2314
|
+
// srcPath κΈ°μ€ μλ κ²½λ‘
|
|
2276
2315
|
debug: options.debug || false,
|
|
2277
2316
|
environment: options.environment || "development",
|
|
2278
2317
|
...options
|
|
@@ -2314,7 +2353,20 @@ var ComponentLoader = class {
|
|
|
2314
2353
|
* νμΌμμ μ»΄ν¬λνΈ λ‘λ
|
|
2315
2354
|
*/
|
|
2316
2355
|
async _loadComponentFromFile(componentName) {
|
|
2317
|
-
const
|
|
2356
|
+
const componentRelativePath = `${this.config.componentsPath}/${componentName}.js`;
|
|
2357
|
+
let componentPath;
|
|
2358
|
+
if (this.router && this.router.config.srcPath) {
|
|
2359
|
+
const srcPath = this.router.config.srcPath;
|
|
2360
|
+
if (srcPath.startsWith("http")) {
|
|
2361
|
+
const cleanSrcPath = srcPath.endsWith("/") ? srcPath.slice(0, -1) : srcPath;
|
|
2362
|
+
const cleanComponentPath = componentRelativePath.startsWith("/") ? componentRelativePath : `/${componentRelativePath}`;
|
|
2363
|
+
componentPath = `${cleanSrcPath}${cleanComponentPath}`;
|
|
2364
|
+
} else {
|
|
2365
|
+
componentPath = this.router.resolvePath(`${srcPath}${componentRelativePath}`);
|
|
2366
|
+
}
|
|
2367
|
+
} else {
|
|
2368
|
+
componentPath = this.router ? this.router.resolvePath(`/src${componentRelativePath}`) : `/src${componentRelativePath}`;
|
|
2369
|
+
}
|
|
2318
2370
|
try {
|
|
2319
2371
|
const module = await import(componentPath);
|
|
2320
2372
|
const component = module.default;
|
|
@@ -2357,7 +2409,7 @@ var ComponentLoader = class {
|
|
|
2357
2409
|
*/
|
|
2358
2410
|
async _loadProductionComponents() {
|
|
2359
2411
|
try {
|
|
2360
|
-
const componentsPath = `${this.config
|
|
2412
|
+
const componentsPath = `${this.router?.config?.routesPath || "/routes"}/_components.js`;
|
|
2361
2413
|
this.log("info", "[PRODUCTION] Loading unified components from:", componentsPath);
|
|
2362
2414
|
const componentsModule = await import(componentsPath);
|
|
2363
2415
|
if (typeof componentsModule.registerComponents === "function") {
|
|
@@ -2445,7 +2497,10 @@ var ViewLogicRouter = class {
|
|
|
2445
2497
|
_buildConfig(options) {
|
|
2446
2498
|
const currentOrigin = window.location.origin;
|
|
2447
2499
|
const defaults = {
|
|
2448
|
-
basePath:
|
|
2500
|
+
basePath: "/",
|
|
2501
|
+
// μ ν리μΌμ΄μ
κΈ°λ³Έ κ²½λ‘ (μλΈν΄λ λ°°ν¬μ©)
|
|
2502
|
+
srcPath: "/src",
|
|
2503
|
+
// μμ€ νμΌ κ²½λ‘
|
|
2449
2504
|
mode: "hash",
|
|
2450
2505
|
cacheMode: "memory",
|
|
2451
2506
|
cacheTTL: 3e5,
|
|
@@ -2453,13 +2508,15 @@ var ViewLogicRouter = class {
|
|
|
2453
2508
|
useLayout: true,
|
|
2454
2509
|
defaultLayout: "default",
|
|
2455
2510
|
environment: "development",
|
|
2456
|
-
routesPath:
|
|
2511
|
+
routesPath: "/routes",
|
|
2512
|
+
// νλ‘λμ
λΌμ°νΈ κ²½λ‘
|
|
2457
2513
|
enableErrorReporting: true,
|
|
2458
2514
|
useComponents: true,
|
|
2459
2515
|
componentNames: ["Button", "Modal", "Card", "Toast", "Input", "Tabs", "Checkbox", "Alert", "DynamicInclude", "HtmlInclude"],
|
|
2460
|
-
useI18n:
|
|
2516
|
+
useI18n: false,
|
|
2461
2517
|
defaultLanguage: "ko",
|
|
2462
|
-
i18nPath:
|
|
2518
|
+
i18nPath: "/i18n",
|
|
2519
|
+
// λ€κ΅μ΄ νμΌ κ²½λ‘
|
|
2463
2520
|
logLevel: "info",
|
|
2464
2521
|
authEnabled: false,
|
|
2465
2522
|
loginRoute: "login",
|
|
@@ -2481,17 +2538,56 @@ var ViewLogicRouter = class {
|
|
|
2481
2538
|
logSecurityWarnings: true
|
|
2482
2539
|
};
|
|
2483
2540
|
const config = { ...defaults, ...options };
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
if (options.routesPath && !options.routesPath.startsWith("http")) {
|
|
2488
|
-
config.routesPath = `${currentOrigin}${options.routesPath}`;
|
|
2489
|
-
}
|
|
2490
|
-
if (options.i18nPath && !options.i18nPath.startsWith("http")) {
|
|
2491
|
-
config.i18nPath = `${currentOrigin}${options.i18nPath}`;
|
|
2492
|
-
}
|
|
2541
|
+
config.srcPath = this.resolvePath(config.srcPath, config.basePath);
|
|
2542
|
+
config.routesPath = this.resolvePath(config.routesPath, config.basePath);
|
|
2543
|
+
config.i18nPath = this.resolvePath(config.i18nPath, config.basePath);
|
|
2493
2544
|
return config;
|
|
2494
2545
|
}
|
|
2546
|
+
/**
|
|
2547
|
+
* ν΅ν© κ²½λ‘ ν΄κ²° - μλΈν΄λ λ°°ν¬ λ° basePath μ§μ
|
|
2548
|
+
*/
|
|
2549
|
+
resolvePath(path, basePath = null) {
|
|
2550
|
+
const currentOrigin = window.location.origin;
|
|
2551
|
+
if (path.startsWith("http")) {
|
|
2552
|
+
return path;
|
|
2553
|
+
}
|
|
2554
|
+
if (path.startsWith("/")) {
|
|
2555
|
+
if (basePath && basePath !== "/") {
|
|
2556
|
+
const cleanBasePath = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
|
|
2557
|
+
const cleanPath = path.startsWith("/") ? path : `/${path}`;
|
|
2558
|
+
const fullPath = `${cleanBasePath}${cleanPath}`;
|
|
2559
|
+
const fullUrl2 = `${currentOrigin}${fullPath}`;
|
|
2560
|
+
return fullUrl2.replace(/([^:])\/{2,}/g, "$1/");
|
|
2561
|
+
}
|
|
2562
|
+
return `${currentOrigin}${path}`;
|
|
2563
|
+
}
|
|
2564
|
+
const currentPathname = window.location.pathname;
|
|
2565
|
+
const currentBase = currentPathname.endsWith("/") ? currentPathname : currentPathname.substring(0, currentPathname.lastIndexOf("/") + 1);
|
|
2566
|
+
const resolvedPath = this.normalizePath(currentBase + path);
|
|
2567
|
+
const fullUrl = `${currentOrigin}${resolvedPath}`;
|
|
2568
|
+
return fullUrl.replace(/([^:])\/{2,}/g, "$1/");
|
|
2569
|
+
}
|
|
2570
|
+
/**
|
|
2571
|
+
* URL κ²½λ‘ μ κ·ν (μ΄μ€ μ¬λμ μ κ±° λ° ../, ./ μ²λ¦¬)
|
|
2572
|
+
*/
|
|
2573
|
+
normalizePath(path) {
|
|
2574
|
+
path = path.replace(/\/+/g, "/");
|
|
2575
|
+
const parts = path.split("/").filter((part) => part !== "" && part !== ".");
|
|
2576
|
+
const stack = [];
|
|
2577
|
+
for (const part of parts) {
|
|
2578
|
+
if (part === "..") {
|
|
2579
|
+
if (stack.length > 0 && stack[stack.length - 1] !== "..") {
|
|
2580
|
+
stack.pop();
|
|
2581
|
+
} else if (!path.startsWith("/")) {
|
|
2582
|
+
stack.push(part);
|
|
2583
|
+
}
|
|
2584
|
+
} else {
|
|
2585
|
+
stack.push(part);
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
const normalized = "/" + stack.join("/");
|
|
2589
|
+
return normalized === "/" ? "/" : normalized;
|
|
2590
|
+
}
|
|
2495
2591
|
/**
|
|
2496
2592
|
* λ‘κΉ
λνΌ λ©μλ
|
|
2497
2593
|
*/
|
|
@@ -2510,9 +2606,16 @@ var ViewLogicRouter = class {
|
|
|
2510
2606
|
this.queryManager = new QueryManager(this, this.config);
|
|
2511
2607
|
this.errorHandler = new ErrorHandler(this, this.config);
|
|
2512
2608
|
if (this.config.useI18n) {
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2609
|
+
try {
|
|
2610
|
+
this.i18nManager = new I18nManager(this, this.config);
|
|
2611
|
+
if (this.i18nManager.initPromise) {
|
|
2612
|
+
await this.i18nManager.initPromise;
|
|
2613
|
+
}
|
|
2614
|
+
this.log("info", "I18nManager initialized successfully");
|
|
2615
|
+
} catch (i18nError) {
|
|
2616
|
+
this.log("warn", "I18nManager initialization failed, continuing without i18n:", i18nError.message);
|
|
2617
|
+
this.i18nManager = null;
|
|
2618
|
+
this.config.useI18n = false;
|
|
2516
2619
|
}
|
|
2517
2620
|
}
|
|
2518
2621
|
if (this.config.authEnabled) {
|
|
@@ -2596,8 +2699,17 @@ var ViewLogicRouter = class {
|
|
|
2596
2699
|
queryParams: this.queryManager?.parseQueryString(queryPart || window.location.search.slice(1)) || {}
|
|
2597
2700
|
};
|
|
2598
2701
|
} else {
|
|
2702
|
+
const fullPath = window.location.pathname;
|
|
2703
|
+
const basePath = this.config.basePath || "/";
|
|
2704
|
+
let route = fullPath;
|
|
2705
|
+
if (basePath !== "/" && fullPath.startsWith(basePath)) {
|
|
2706
|
+
route = fullPath.slice(basePath.length);
|
|
2707
|
+
}
|
|
2708
|
+
if (route.startsWith("/")) {
|
|
2709
|
+
route = route.slice(1);
|
|
2710
|
+
}
|
|
2599
2711
|
return {
|
|
2600
|
-
route:
|
|
2712
|
+
route: route || "home",
|
|
2601
2713
|
queryParams: this.queryManager?.parseQueryString(window.location.search.slice(1)) || {}
|
|
2602
2714
|
};
|
|
2603
2715
|
}
|
|
@@ -2730,7 +2842,10 @@ var ViewLogicRouter = class {
|
|
|
2730
2842
|
const queryParams = params || this.queryManager?.getQueryParams() || {};
|
|
2731
2843
|
const queryString = this.queryManager?.buildQueryString(queryParams) || "";
|
|
2732
2844
|
const buildURL = (route2, queryString2, isHash = true) => {
|
|
2733
|
-
|
|
2845
|
+
let base = route2 === "home" ? "/" : `/${route2}`;
|
|
2846
|
+
if (!isHash && this.config.basePath && this.config.basePath !== "/") {
|
|
2847
|
+
base = `${this.config.basePath}${base}`;
|
|
2848
|
+
}
|
|
2734
2849
|
const url = queryString2 ? `${base}?${queryString2}` : base;
|
|
2735
2850
|
return isHash ? `#${url}` : url;
|
|
2736
2851
|
};
|
|
@@ -2741,7 +2856,11 @@ var ViewLogicRouter = class {
|
|
|
2741
2856
|
}
|
|
2742
2857
|
} else {
|
|
2743
2858
|
const newPath = buildURL(route, queryString, false);
|
|
2744
|
-
|
|
2859
|
+
let expectedPath = route === "home" ? "/" : `/${route}`;
|
|
2860
|
+
if (this.config.basePath && this.config.basePath !== "/") {
|
|
2861
|
+
expectedPath = `${this.config.basePath}${expectedPath}`;
|
|
2862
|
+
}
|
|
2863
|
+
const isSameRoute = window.location.pathname === expectedPath;
|
|
2745
2864
|
if (isSameRoute) {
|
|
2746
2865
|
window.history.replaceState({}, "", newPath);
|
|
2747
2866
|
} else {
|