@iyulab/router 0.9.1 → 0.9.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/CHANGELOG.md +13 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19 -11
- package/dist/react.js +1 -1
- package/dist/{share-CUGwxZKa.js → share-DC0R4F2d.js} +2 -2
- package/package.json +3 -3
- package/skills/iyulab-router/SKILL.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.3] - 2026-04-24
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Document click handler now scopes interception to the router's `_rootElement` instead of `document`, preventing accidental capture of clicks outside the router's DOM subtree
|
|
7
|
+
- Click handler no longer intercepts same-origin anchors pointing outside `basepath` — when `basepath` is not `/`, links targeting paths outside the basepath are passed through to browser navigation instead of falling through to the fallback route
|
|
8
|
+
|
|
9
|
+
## [0.9.2] - 2026-04-13
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- Nested route rendering now waits for child outlet readiness after parent render, preventing children from being rendered into the previous outlet when the next `<u-outlet>` is created inside a component shadow root
|
|
13
|
+
- `Router.go()` now awaits `UOutlet.render()` before resolving the next outlet in the matched route chain
|
|
14
|
+
- `waitOutlet()` now prefers component lifecycle-aware readiness checks (`customElements.whenDefined`, `updateComplete`, next animation frame) during outlet discovery
|
|
15
|
+
|
|
3
16
|
## [0.9.1] - 2026-04-08
|
|
4
17
|
|
|
5
18
|
### Fixed
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as isExternalUrl, i as absolutePath, n as __decorate, o as parseUrl, r as __decorateMetadata, s as UOutlet, t as ULink } from "./share-
|
|
1
|
+
import { a as isExternalUrl, i as absolutePath, n as __decorate, o as parseUrl, r as __decorateMetadata, s as UOutlet, t as ULink } from "./share-DC0R4F2d.js";
|
|
2
2
|
import { LitElement, css, html } from "lit";
|
|
3
3
|
import { customElement, property } from "lit/decorators.js";
|
|
4
4
|
//#region src/types/RouteError.ts
|
|
@@ -240,11 +240,13 @@ function findOutlet(element, skip = false) {
|
|
|
240
240
|
* `u-outlet` 엘리먼트를 찾아 반환합니다. 없으면 에러를 던집니다.
|
|
241
241
|
*
|
|
242
242
|
* @param element 검색을 시작할 HTMLElement
|
|
243
|
+
* @param skip element 자신을 검사에서 제외할지 여부 (기본값: false)
|
|
244
|
+
*
|
|
243
245
|
* @returns 찾은 UOutlet 엘리먼트
|
|
244
246
|
* @throws OutletMissingError `u-outlet` 엘리먼트를 찾지 못한 경우
|
|
245
247
|
*/
|
|
246
|
-
function findOutletOrThrow(element) {
|
|
247
|
-
const outlet = findOutlet(element);
|
|
248
|
+
function findOutletOrThrow(element, skip = false) {
|
|
249
|
+
const outlet = findOutlet(element, skip);
|
|
248
250
|
if (!outlet) throw new OutletMissingError();
|
|
249
251
|
return outlet;
|
|
250
252
|
}
|
|
@@ -253,14 +255,18 @@ function findOutletOrThrow(element) {
|
|
|
253
255
|
*
|
|
254
256
|
* @param element 대기할 엘리먼트
|
|
255
257
|
* @param timeout 타임아웃 시간(밀리초, 기본값: 10_000ms)
|
|
258
|
+
* @param skip element 자신을 검사에서 제외할지 여부 (기본값: false)
|
|
259
|
+
*
|
|
256
260
|
* @returns 준비된 `u-outlet` 엘리먼트
|
|
257
261
|
*/
|
|
258
|
-
async function waitOutlet(element, timeout = 1e4) {
|
|
262
|
+
async function waitOutlet(element, timeout = 1e4, skip = false) {
|
|
259
263
|
const start = performance.now();
|
|
260
264
|
while (performance.now() - start < timeout) {
|
|
261
|
-
const outlet = findOutlet(element);
|
|
265
|
+
const outlet = findOutlet(element, skip);
|
|
262
266
|
if (outlet) return outlet;
|
|
263
|
-
|
|
267
|
+
if (element.localName.includes("-")) await customElements.whenDefined(element.localName);
|
|
268
|
+
if ("updateComplete" in element) await element.updateComplete;
|
|
269
|
+
await new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
|
264
270
|
}
|
|
265
271
|
throw new Error(`Timed out waiting for <u-outlet> inside <${element.tagName.toLowerCase()}>. Ensure that the router root element contains a <u-outlet> child.`);
|
|
266
272
|
}
|
|
@@ -384,7 +390,7 @@ var Router = class {
|
|
|
384
390
|
this.handleWindowPopstate = async (_) => {
|
|
385
391
|
await this.go(window.location.href);
|
|
386
392
|
};
|
|
387
|
-
this.
|
|
393
|
+
this.handleRootElementClick = async (e) => {
|
|
388
394
|
try {
|
|
389
395
|
if (e.defaultPrevented) return;
|
|
390
396
|
if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey) return;
|
|
@@ -396,6 +402,7 @@ var Router = class {
|
|
|
396
402
|
if (anchor.hasAttribute("download")) return;
|
|
397
403
|
if (anchor.getAttribute("rel") === "external") return;
|
|
398
404
|
if (anchor.target && anchor.target !== "") return;
|
|
405
|
+
if (this._basepath !== "/" && !new URL(anchor.href).pathname.startsWith(this._basepath)) return;
|
|
399
406
|
e.preventDefault();
|
|
400
407
|
await this.go(anchor.href);
|
|
401
408
|
} catch {}
|
|
@@ -407,7 +414,7 @@ var Router = class {
|
|
|
407
414
|
this._fallback = config.fallback;
|
|
408
415
|
this._enter = config.enter;
|
|
409
416
|
window.addEventListener("popstate", this.handleWindowPopstate);
|
|
410
|
-
if (config.useIntercept !== false)
|
|
417
|
+
if (config.useIntercept !== false) this._rootElement.addEventListener("click", this.handleRootElementClick);
|
|
411
418
|
if (config.initialLoad !== false) waitOutlet(this._rootElement).then(() => {
|
|
412
419
|
this.go(window.location.href);
|
|
413
420
|
});
|
|
@@ -415,7 +422,7 @@ var Router = class {
|
|
|
415
422
|
/** 객체를 정리하고 이벤트 리스너를 제거합니다. */
|
|
416
423
|
destroy() {
|
|
417
424
|
window.removeEventListener("popstate", this.handleWindowPopstate);
|
|
418
|
-
|
|
425
|
+
this._rootElement?.removeEventListener("click", this.handleRootElementClick);
|
|
419
426
|
this._requestID = void 0;
|
|
420
427
|
this._context = void 0;
|
|
421
428
|
}
|
|
@@ -491,14 +498,15 @@ var Router = class {
|
|
|
491
498
|
throw new ContentLoadError(e);
|
|
492
499
|
}
|
|
493
500
|
try {
|
|
494
|
-
outlet.render(content, {
|
|
501
|
+
await outlet.render(content, {
|
|
495
502
|
id: route.id,
|
|
496
503
|
force: route.force
|
|
497
504
|
});
|
|
498
505
|
} catch (e) {
|
|
499
506
|
throw new ContentRenderError(e);
|
|
500
507
|
}
|
|
501
|
-
outlet =
|
|
508
|
+
if ("children" in route && route.children && route.children.length > 0) outlet = await waitOutlet(outlet, 2e3, true);
|
|
509
|
+
else outlet = findOutlet(outlet, true) || outlet;
|
|
502
510
|
title = route.title || title;
|
|
503
511
|
}
|
|
504
512
|
window.dispatchEvent(new RouteDoneEvent(context));
|
package/dist/react.js
CHANGED
|
@@ -126,12 +126,12 @@ function catchBasepath(basepath) {
|
|
|
126
126
|
return basepath;
|
|
127
127
|
}
|
|
128
128
|
//#endregion
|
|
129
|
-
//#region \0@oxc-project+runtime@0.
|
|
129
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/decorateMetadata.js
|
|
130
130
|
function __decorateMetadata(k, v) {
|
|
131
131
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
132
132
|
}
|
|
133
133
|
//#endregion
|
|
134
|
-
//#region \0@oxc-project+runtime@0.
|
|
134
|
+
//#region \0@oxc-project+runtime@0.127.0/helpers/decorate.js
|
|
135
135
|
function __decorate(decorators, target, key, desc) {
|
|
136
136
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
137
137
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/router",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "A modern client-side router for web applications with support for Lit and React components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lit",
|
|
@@ -58,11 +58,11 @@
|
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@types/node": "^25.
|
|
61
|
+
"@types/node": "^25.6.0",
|
|
62
62
|
"@types/react": "^19.2.14",
|
|
63
63
|
"@types/react-dom": "^19.2.3",
|
|
64
64
|
"typescript": "^5.9.3",
|
|
65
|
-
"vite": "^8.0.
|
|
65
|
+
"vite": "^8.0.8",
|
|
66
66
|
"vite-plugin-dts": "^4.5.4"
|
|
67
67
|
}
|
|
68
68
|
}
|