soseki 0.0.8 → 0.0.10
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/src/components/browser-router.d.ts +2 -2
- package/dist/src/components/browser-router.d.ts.map +1 -1
- package/dist/src/components/router.d.ts +32 -2
- package/dist/src/components/router.d.ts.map +1 -1
- package/dist/src/core/match-route-path.d.ts +46 -0
- package/dist/src/core/match-route-path.d.ts.map +1 -0
- package/dist/src/core/match-route-path.js +16 -0
- package/dist/src/core/route-path.d.ts +46 -8
- package/dist/src/core/route-path.d.ts.map +1 -1
- package/dist/src/core/route-path.js +42 -14
- package/dist/src/core.d.ts +5 -0
- package/dist/src/core.d.ts.map +1 -1
- package/dist/src/core.js +2 -0
- package/dist/src/engines/engine.types.d.ts +8 -13
- package/dist/src/engines/engine.types.d.ts.map +1 -1
- package/dist/src/engines/navigation-api-engine.d.ts.map +1 -1
- package/dist/src/engines/navigation-api-engine.js +14 -23
- package/dist/src/hooks/use-navigate.d.ts +8 -0
- package/dist/src/hooks/use-navigate.d.ts.map +1 -1
- package/dist/src/hooks/use-navigate.js +25 -3
- package/dist/src/hooks/use-route-path.d.ts +3 -0
- package/dist/src/hooks/use-route-path.d.ts.map +1 -0
- package/dist/src/hooks/use-route-path.js +8 -0
- package/dist/src/soseki.d.ts +4 -0
- package/dist/src/soseki.d.ts.map +1 -1
- package/dist/src/soseki.js +2 -0
- package/package.json +1 -1
- package/src/components/browser-router.tsx +2 -3
- package/src/components/router.tsx +24 -2
- package/src/core/match-route-path.ts +78 -0
- package/src/core/route-path.ts +68 -16
- package/src/core.ts +8 -0
- package/src/engines/engine.types.ts +8 -15
- package/src/engines/navigation-api-engine.ts +14 -24
- package/src/hooks/use-navigate.ts +33 -4
- package/src/hooks/use-route-path.ts +11 -0
- package/src/soseki.ts +6 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type RouterRouteDefinition } from "./router.jsx";
|
|
2
2
|
/**
|
|
3
3
|
* `BrowserRouter` コンポーネントに引き渡すプロパティーの型定義です。
|
|
4
4
|
*/
|
|
@@ -6,7 +6,7 @@ export type BrowserRouterProps = {
|
|
|
6
6
|
/**
|
|
7
7
|
* アプリケーション全体の画面構造を定義したルート定義の配列です。
|
|
8
8
|
*/
|
|
9
|
-
routes: readonly
|
|
9
|
+
routes: readonly RouterRouteDefinition[];
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
12
|
* ブラウザー環境における SPA ルーティングを開始するための、最上位エントリーポイントコンポーネントです。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-router.d.ts","sourceRoot":"","sources":["../../../src/components/browser-router.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser-router.d.ts","sourceRoot":"","sources":["../../../src/components/browser-router.tsx"],"names":[],"mappings":"AAEA,OAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;OAEG;IACH,MAAM,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC1C,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAKnF"}
|
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import type { RouteDefinition } from "../core/route.types.js";
|
|
3
2
|
import type { IEngine } from "../engines/engine.types.js";
|
|
3
|
+
export type RouterRouteDefinitionObject = {
|
|
4
|
+
readonly path: string;
|
|
5
|
+
readonly index?: boolean | undefined;
|
|
6
|
+
readonly action?: {
|
|
7
|
+
(args: any): unknown;
|
|
8
|
+
} | undefined;
|
|
9
|
+
readonly shouldReload?: {
|
|
10
|
+
(args: any): boolean;
|
|
11
|
+
} | undefined;
|
|
12
|
+
readonly loader?: {
|
|
13
|
+
(args: any): unknown;
|
|
14
|
+
} | undefined;
|
|
15
|
+
readonly component?: React.ComponentType<{}> | undefined;
|
|
16
|
+
};
|
|
17
|
+
export type RouterRouteDefinitionModule = {
|
|
18
|
+
readonly path: string;
|
|
19
|
+
readonly index?: boolean | undefined;
|
|
20
|
+
readonly action?: {
|
|
21
|
+
(args: any): unknown;
|
|
22
|
+
} | undefined;
|
|
23
|
+
readonly shouldReload?: {
|
|
24
|
+
(args: any): boolean;
|
|
25
|
+
} | undefined;
|
|
26
|
+
readonly loader?: {
|
|
27
|
+
(args: any): unknown;
|
|
28
|
+
} | undefined;
|
|
29
|
+
readonly component?: React.ComponentType<{}> | undefined;
|
|
30
|
+
readonly default?: React.ComponentType<{}> | undefined;
|
|
31
|
+
get [Symbol.toStringTag](): string;
|
|
32
|
+
};
|
|
33
|
+
export type RouterRouteDefinition = RouterRouteDefinitionObject | RouterRouteDefinitionModule;
|
|
4
34
|
/**
|
|
5
35
|
* `Router` コンポーネントに渡されるルートプロパティーの型定義です。
|
|
6
36
|
*/
|
|
@@ -12,7 +42,7 @@ export type RouterProps = {
|
|
|
12
42
|
/**
|
|
13
43
|
* ユーザーがアプリケーションに定義したルート定義の配列です。
|
|
14
44
|
*/
|
|
15
|
-
routes: readonly
|
|
45
|
+
routes: readonly RouterRouteDefinition[];
|
|
16
46
|
};
|
|
17
47
|
/**
|
|
18
48
|
* 宣言的なルート定義と、命令的なルーティング実行エンジンを仲介・統合し、アプリケーションの最上位でルーティングのライフサイクルと状態管理を司るプロバイダーコンポーネントです。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/components/router.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/components/router.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAY/B,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,4BAA4B,CAAC;AAkEvE,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,YAAY,CAAC,EAAE;QAAE,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,YAAY,CAAC,EAAE;QAAE,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,2BAA2B,GAAG,2BAA2B,CAAC;AAE9F;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC1C,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,KAAK,EAAE,WAAW,4BAkIhD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ルーティングの照合対象となる URL 情報を表すインターフェースです。
|
|
3
|
+
*/
|
|
4
|
+
export interface MatchRoutePathTargetURL {
|
|
5
|
+
/**
|
|
6
|
+
* 照合対象のパス名です。
|
|
7
|
+
*/
|
|
8
|
+
readonly pathname: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* `matchRoutePath` 関数の動作を設定するための型定義です。
|
|
12
|
+
*/
|
|
13
|
+
export type MatchRoutePathOptions = {
|
|
14
|
+
/**
|
|
15
|
+
* 照合の基準となるルーティングのパターン文字列です。
|
|
16
|
+
*/
|
|
17
|
+
readonly pattern: string;
|
|
18
|
+
/**
|
|
19
|
+
* 照合対象とする文字列または URL オブジェクトです。
|
|
20
|
+
*/
|
|
21
|
+
readonly target: string | MatchRoutePathTargetURL;
|
|
22
|
+
/**
|
|
23
|
+
* 子ディレクトリーへの前方一致を許可するかどうかを制御するフラグです。
|
|
24
|
+
*
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
readonly allowChild?: boolean | undefined;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* 指定されたパターンと対象のパス名が一致するかどうかを判定します。
|
|
31
|
+
*
|
|
32
|
+
* @param options パターン、対象、および一致条件を含む設定オブジェクトです。
|
|
33
|
+
* @returns パターンに一致した場合は `true` を、一致しない場合は `false` を返します。
|
|
34
|
+
*/
|
|
35
|
+
declare function matchRoutePath(options: MatchRoutePathOptions): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* 指定されたパターンと対象のパス名が一致するかどうかを判定します。
|
|
38
|
+
*
|
|
39
|
+
* @param pattern 照合の基準となるルーティングのパターン文字列です。
|
|
40
|
+
* @param target 照合対象とする文字列または URL オブジェクトです。
|
|
41
|
+
* @param options オプションです。
|
|
42
|
+
* @returns パターンに一致した場合は `true` を、一致しない場合は `false` を返します。
|
|
43
|
+
*/
|
|
44
|
+
declare function matchRoutePath(pattern: MatchRoutePathOptions["pattern"], target: MatchRoutePathOptions["target"], options?: Omit<MatchRoutePathOptions, "pattern" | "target">): boolean;
|
|
45
|
+
export default matchRoutePath;
|
|
46
|
+
//# sourceMappingURL=match-route-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"match-route-path.d.ts","sourceRoot":"","sources":["../../../src/core/match-route-path.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,CAAC;IAElD;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF;;;;;GAKG;AACH,iBAAS,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC;AAEjE;;;;;;;GAOG;AACH,iBAAS,cAAc,CACrB,OAAO,EAAE,qBAAqB,CAAC,SAAS,CAAC,EACzC,MAAM,EAAE,qBAAqB,CAAC,QAAQ,CAAC,EACvC,OAAO,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,QAAQ,CAAC,GAC1D,OAAO,CAAC;AAqBX,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { parse } from "regexparam";
|
|
2
|
+
import RoutePath from "./route-path.js";
|
|
3
|
+
function matchRoutePath(...args) {
|
|
4
|
+
const { target, pattern, allowChild = false, } = typeof args[0] !== "string"
|
|
5
|
+
? args[0]
|
|
6
|
+
: {
|
|
7
|
+
...args[2],
|
|
8
|
+
target: args[1],
|
|
9
|
+
pattern: args[0],
|
|
10
|
+
};
|
|
11
|
+
const patternPathname = new RoutePath(pattern).pathname;
|
|
12
|
+
const targetPathname = typeof target === "string" ? target : target.pathname;
|
|
13
|
+
const patternRegex = parse(patternPathname, allowChild).pattern;
|
|
14
|
+
return patternRegex.test(targetPathname);
|
|
15
|
+
}
|
|
16
|
+
export default matchRoutePath;
|
|
@@ -1,10 +1,48 @@
|
|
|
1
|
-
import type { ReadonlyURL } from "./readonly-url.types.js";
|
|
1
|
+
import type { ReadonlyURL, ReadonlyURLSearchParams } from "./readonly-url.types.js";
|
|
2
2
|
/**
|
|
3
3
|
* アプリケーション内のルーティングにおけるパスを安全に構築・解析・操作するためのクラスです。
|
|
4
4
|
*
|
|
5
5
|
* 内包するホストやプロトコルといった余分な情報を排除し、パス、クエリー、ハッシュのみを一貫した規則で管理します。
|
|
6
6
|
*/
|
|
7
|
-
export
|
|
7
|
+
export interface ReadonlyRoutePath {
|
|
8
|
+
/**
|
|
9
|
+
* 正規化されたパス部分の文字列です。
|
|
10
|
+
*/
|
|
11
|
+
readonly pathname: string;
|
|
12
|
+
/**
|
|
13
|
+
* 先頭に `?` を含むクエリー文字列です。
|
|
14
|
+
*
|
|
15
|
+
* 常にソートされます。
|
|
16
|
+
*/
|
|
17
|
+
readonly search: string;
|
|
18
|
+
/**
|
|
19
|
+
* 内部の `URL` インスタンスが保持する、クエリーパラメーターを操作するための `URLSearchParams` オブジェクトを取得します。
|
|
20
|
+
*/
|
|
21
|
+
readonly searchParams: ReadonlyURLSearchParams;
|
|
22
|
+
/**
|
|
23
|
+
* 先頭に `#` を含むハッシュ文字列を取得します。
|
|
24
|
+
*/
|
|
25
|
+
readonly hash: string;
|
|
26
|
+
/**
|
|
27
|
+
* 現在保持しているすべてのコンポーネントを結合し、ルーティング用のパス文字列として出力します。
|
|
28
|
+
*
|
|
29
|
+
* @returns ソート済みのクエリーおよびハッシュを含んだ、正規化されたパス全体の文字列を返します。
|
|
30
|
+
*/
|
|
31
|
+
toString(): string;
|
|
32
|
+
/**
|
|
33
|
+
* このインスタンスを複製し、上書き可能な形式で取得します。
|
|
34
|
+
*
|
|
35
|
+
* @returns 上書き可能な {@link RoutePath|`RoutePath`} インスタンスです。
|
|
36
|
+
*/
|
|
37
|
+
clone(): RoutePath;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* アプリケーション内のルーティングにおけるパスを安全に構築・解析・操作するためのクラスです。
|
|
41
|
+
*
|
|
42
|
+
* 内包するホストやプロトコルといった余分な情報を排除し、パス、クエリー、ハッシュのみを一貫した規則で管理します。
|
|
43
|
+
*/
|
|
44
|
+
export default class RoutePath implements ReadonlyRoutePath {
|
|
45
|
+
#private;
|
|
8
46
|
/**
|
|
9
47
|
* 与えられた文字列または URL オブジェクトから、正規化されたパス文字列を即座に生成する静的メソッドです。
|
|
10
48
|
*
|
|
@@ -12,12 +50,6 @@ export default class RoutePath {
|
|
|
12
50
|
* @returns 冗長なスラッシュや末尾のスラッシュが取り除かれた、結合済みのパス文字列を返します。
|
|
13
51
|
*/
|
|
14
52
|
static encode(path: string | Pick<ReadonlyURL, "pathname" | "search" | "hash">): string;
|
|
15
|
-
/**
|
|
16
|
-
* 内部でパスコンポーネントの解析と検証を委譲するために保持する、組み込みの `URL` インスタンスです。
|
|
17
|
-
*
|
|
18
|
-
* 基底となる仮想的なオリジンと結合して管理されます。
|
|
19
|
-
*/
|
|
20
|
-
private url;
|
|
21
53
|
/**
|
|
22
54
|
* 新しい `RoutePath` インスタンスを初期化します。
|
|
23
55
|
*
|
|
@@ -53,5 +85,11 @@ export default class RoutePath {
|
|
|
53
85
|
* @returns ソート済みのクエリーおよびハッシュを含んだ、正規化されたパス全体の文字列を返します。
|
|
54
86
|
*/
|
|
55
87
|
toString(): string;
|
|
88
|
+
/**
|
|
89
|
+
* このインスタンスを複製し、上書き可能な形式で取得します。
|
|
90
|
+
*
|
|
91
|
+
* @returns 上書き可能な {@link RoutePath|`RoutePath`} インスタンスです。
|
|
92
|
+
*/
|
|
93
|
+
clone(): RoutePath;
|
|
56
94
|
}
|
|
57
95
|
//# sourceMappingURL=route-path.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-path.d.ts","sourceRoot":"","sources":["../../../src/core/route-path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"route-path.d.ts","sourceRoot":"","sources":["../../../src/core/route-path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAOpF;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,uBAAuB,CAAC;IAE/C;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,QAAQ,IAAI,MAAM,CAAC;IAEnB;;;;OAIG;IACH,KAAK,IAAI,SAAS,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,SAAU,YAAW,iBAAiB;;IACzD;;;;;OAKG;WACW,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC,GAAG,MAAM;IAW9F;;;;;;OAMG;gBACgB,IAAI,GAAE,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAM;IAkBxF;;OAEG;IACH,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAED,IAAW,QAAQ,CAAC,KAAK,EAAE,MAAM,EAQhC;IAED;;;;OAIG;IACH,IAAW,MAAM,IAAI,MAAM,CAG1B;IAED,IAAW,MAAM,CAAC,KAAK,EAAE,MAAM,EAE9B;IAED;;OAEG;IACH,IAAW,YAAY,IAAI,eAAe,CAEzC;IAED;;OAEG;IACH,IAAW,IAAI,IAAI,MAAM,CAExB;IAED,IAAW,IAAI,CAAC,KAAK,EAAE,MAAM,EAE5B;IAED;;;;OAIG;IACI,QAAQ,IAAI,MAAM;IAKzB;;;;OAIG;IACI,KAAK,IAAI,SAAS;CAG1B"}
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _RoutePath_url;
|
|
1
13
|
/**
|
|
2
14
|
* 連続する複数のスラッシュを検出するための正規表現です。
|
|
3
15
|
*/
|
|
@@ -7,7 +19,7 @@ const MULTI_SLASH = /\/\/+/gu;
|
|
|
7
19
|
*
|
|
8
20
|
* 内包するホストやプロトコルといった余分な情報を排除し、パス、クエリー、ハッシュのみを一貫した規則で管理します。
|
|
9
21
|
*/
|
|
10
|
-
|
|
22
|
+
class RoutePath {
|
|
11
23
|
/**
|
|
12
24
|
* 与えられた文字列または URL オブジェクトから、正規化されたパス文字列を即座に生成する静的メソッドです。
|
|
13
25
|
*
|
|
@@ -25,6 +37,12 @@ export default class RoutePath {
|
|
|
25
37
|
* @param path 初期化に使用するパス文字列、または `ReadonlyURL` の一部のプロパティーを持つオブジェクトです。既定値は空文字列です。
|
|
26
38
|
*/
|
|
27
39
|
constructor(path = "") {
|
|
40
|
+
/**
|
|
41
|
+
* 内部でパスコンポーネントの解析と検証を委譲するために保持する、組み込みの `URL` インスタンスです。
|
|
42
|
+
*
|
|
43
|
+
* 基底となる仮想的なオリジンと結合して管理されます。
|
|
44
|
+
*/
|
|
45
|
+
_RoutePath_url.set(this, void 0);
|
|
28
46
|
if (typeof path === "string") {
|
|
29
47
|
path = ("/" + path).replace(MULTI_SLASH, "/");
|
|
30
48
|
}
|
|
@@ -33,25 +51,25 @@ export default class RoutePath {
|
|
|
33
51
|
path = ("/" + pathname).replace(MULTI_SLASH, "/") + search + hash;
|
|
34
52
|
}
|
|
35
53
|
// 組み込みの URL クラスによる厳密な解析機能を利用するため、仮想のプロトコルとホストを前置きして初期化します。
|
|
36
|
-
this
|
|
54
|
+
__classPrivateFieldSet(this, _RoutePath_url, new URL("x://y" + path), "f");
|
|
37
55
|
// ルートパス(/)単体である場合を除き、末尾に存在する不要なスラッシュを削除して一貫性を保ちます。
|
|
38
|
-
const { pathname } = this
|
|
56
|
+
const { pathname } = __classPrivateFieldGet(this, _RoutePath_url, "f");
|
|
39
57
|
if (pathname !== "/" && pathname.endsWith("/")) {
|
|
40
|
-
this.
|
|
58
|
+
__classPrivateFieldGet(this, _RoutePath_url, "f").pathname = pathname.substring(0, pathname.length - 1);
|
|
41
59
|
}
|
|
42
60
|
}
|
|
43
61
|
/**
|
|
44
62
|
* 正規化されたパス部分の文字列です。
|
|
45
63
|
*/
|
|
46
64
|
get pathname() {
|
|
47
|
-
return this.
|
|
65
|
+
return __classPrivateFieldGet(this, _RoutePath_url, "f").pathname;
|
|
48
66
|
}
|
|
49
67
|
set pathname(value) {
|
|
50
|
-
this.
|
|
68
|
+
__classPrivateFieldGet(this, _RoutePath_url, "f").pathname = value;
|
|
51
69
|
// ルートパス(/)単体である場合を除き、末尾に存在する不要なスラッシュを削除して一貫性を保ちます。
|
|
52
|
-
const pathname = ("/" + this.
|
|
70
|
+
const pathname = ("/" + __classPrivateFieldGet(this, _RoutePath_url, "f").pathname).replace(MULTI_SLASH, "/");
|
|
53
71
|
if (pathname !== "/" && pathname.endsWith("/")) {
|
|
54
|
-
this.
|
|
72
|
+
__classPrivateFieldGet(this, _RoutePath_url, "f").pathname = pathname.substring(0, pathname.length - 1);
|
|
55
73
|
}
|
|
56
74
|
}
|
|
57
75
|
/**
|
|
@@ -60,26 +78,26 @@ export default class RoutePath {
|
|
|
60
78
|
* 常にソートされます。
|
|
61
79
|
*/
|
|
62
80
|
get search() {
|
|
63
|
-
this.
|
|
64
|
-
return this.
|
|
81
|
+
__classPrivateFieldGet(this, _RoutePath_url, "f").searchParams.sort();
|
|
82
|
+
return __classPrivateFieldGet(this, _RoutePath_url, "f").search;
|
|
65
83
|
}
|
|
66
84
|
set search(value) {
|
|
67
|
-
this.
|
|
85
|
+
__classPrivateFieldGet(this, _RoutePath_url, "f").search = value;
|
|
68
86
|
}
|
|
69
87
|
/**
|
|
70
88
|
* 内部の `URL` インスタンスが保持する、クエリーパラメーターを操作するための `URLSearchParams` オブジェクトを取得します。
|
|
71
89
|
*/
|
|
72
90
|
get searchParams() {
|
|
73
|
-
return this.
|
|
91
|
+
return __classPrivateFieldGet(this, _RoutePath_url, "f").searchParams;
|
|
74
92
|
}
|
|
75
93
|
/**
|
|
76
94
|
* 先頭に `#` を含むハッシュ文字列を取得します。
|
|
77
95
|
*/
|
|
78
96
|
get hash() {
|
|
79
|
-
return this.
|
|
97
|
+
return __classPrivateFieldGet(this, _RoutePath_url, "f").hash;
|
|
80
98
|
}
|
|
81
99
|
set hash(value) {
|
|
82
|
-
this.
|
|
100
|
+
__classPrivateFieldGet(this, _RoutePath_url, "f").hash = value;
|
|
83
101
|
}
|
|
84
102
|
/**
|
|
85
103
|
* 現在保持しているすべてのコンポーネントを結合し、ルーティング用のパス文字列として出力します。
|
|
@@ -90,4 +108,14 @@ export default class RoutePath {
|
|
|
90
108
|
const { hash, search, pathname } = this;
|
|
91
109
|
return pathname + search + hash;
|
|
92
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* このインスタンスを複製し、上書き可能な形式で取得します。
|
|
113
|
+
*
|
|
114
|
+
* @returns 上書き可能な {@link RoutePath|`RoutePath`} インスタンスです。
|
|
115
|
+
*/
|
|
116
|
+
clone() {
|
|
117
|
+
return new RoutePath(this.toString());
|
|
118
|
+
}
|
|
93
119
|
}
|
|
120
|
+
_RoutePath_url = new WeakMap();
|
|
121
|
+
export default RoutePath;
|
package/dist/src/core.d.ts
CHANGED
|
@@ -22,4 +22,9 @@ export type * from "./core/start-action.js";
|
|
|
22
22
|
export { default as startAction } from "./core/start-action.js";
|
|
23
23
|
export type * from "./core/start-loaders.js";
|
|
24
24
|
export { default as startLoaders } from "./core/start-loaders.js";
|
|
25
|
+
/**************************************************************************************************/
|
|
26
|
+
export type * from "./hooks/use-route-context.js";
|
|
27
|
+
export { default as useRouteContext } from "./hooks/use-route-context.js";
|
|
28
|
+
export type * from "./hooks/use-router-context.js";
|
|
29
|
+
export { default as useRouterContext } from "./hooks/use-router-context.js";
|
|
25
30
|
//# sourceMappingURL=core.d.ts.map
|
package/dist/src/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"AAAA,mBAAmB,yBAAyB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAE5D,oGAAoG;AAEpG,mBAAmB,6BAA6B,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEtE,mBAAmB,8BAA8B,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAExE,oGAAoG;AAEpG,mBAAmB,gCAAgC,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAE/E,mBAAmB,mCAAmC,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEpF,mBAAmB,oCAAoC,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAEtF,mBAAmB,wBAAwB,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEhE,mBAAmB,wBAAwB,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEhE,mBAAmB,sBAAsB,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAE5D,mBAAmB,wBAAwB,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEhE,mBAAmB,yBAAyB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"AAAA,mBAAmB,yBAAyB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAE5D,oGAAoG;AAEpG,mBAAmB,6BAA6B,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEtE,mBAAmB,8BAA8B,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAExE,oGAAoG;AAEpG,mBAAmB,gCAAgC,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAE/E,mBAAmB,mCAAmC,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEpF,mBAAmB,oCAAoC,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAEtF,mBAAmB,wBAAwB,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEhE,mBAAmB,wBAAwB,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEhE,mBAAmB,sBAAsB,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAE5D,mBAAmB,wBAAwB,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEhE,mBAAmB,yBAAyB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAElE,oGAAoG;AAEpG,mBAAmB,8BAA8B,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE1E,mBAAmB,+BAA+B,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,+BAA+B,CAAC"}
|
package/dist/src/core.js
CHANGED
|
@@ -9,3 +9,5 @@ export { default as matchRoutes } from "./core/match-routes.js";
|
|
|
9
9
|
export { default as RoutePath } from "./core/route-path.js";
|
|
10
10
|
export { default as startAction } from "./core/start-action.js";
|
|
11
11
|
export { default as startLoaders } from "./core/start-loaders.js";
|
|
12
|
+
export { default as useRouteContext } from "./hooks/use-route-context.js";
|
|
13
|
+
export { default as useRouterContext } from "./hooks/use-router-context.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NinjaPromise } from "ninja-promise";
|
|
2
|
+
import type { RoutePath } from "../core.js";
|
|
2
3
|
import type { HistoryEntry } from "../core/expect-history-entry.js";
|
|
3
4
|
import type { HistoryEntryId } from "../core/history-entry-id-schema.js";
|
|
4
5
|
import type { MatchedRoute } from "../core/match-routes.js";
|
|
@@ -151,28 +152,22 @@ export declare namespace IEngine {
|
|
|
151
152
|
/**
|
|
152
153
|
* URL パスで前方移動する形式です。
|
|
153
154
|
*/
|
|
154
|
-
type: "
|
|
155
|
+
type: "STATIC";
|
|
155
156
|
/**
|
|
156
157
|
* URL パスです。
|
|
157
158
|
*/
|
|
158
159
|
path: string;
|
|
159
160
|
} | {
|
|
160
161
|
/**
|
|
161
|
-
* URL
|
|
162
|
+
* URL の各コンポーネントを関数形式で個別に指定する形式です。
|
|
162
163
|
*/
|
|
163
|
-
type: "
|
|
164
|
+
type: "DYNAMIC";
|
|
164
165
|
/**
|
|
165
|
-
*
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* 先頭のクエスチョンマーク `?` を含む URL のクエリー文字列です。
|
|
170
|
-
*/
|
|
171
|
-
search?: string | undefined;
|
|
172
|
-
/**
|
|
173
|
-
* URL のハッシュ(シャープ記号 `#` を含むフラグメント識別子)です。
|
|
166
|
+
* 動的にパッチを適用する関数です。
|
|
167
|
+
*
|
|
168
|
+
* @param path アプリケーション内のルーティングにおけるパスを安全に構築・解析・操作するためのオブジェクトです。
|
|
174
169
|
*/
|
|
175
|
-
|
|
170
|
+
patch(path: RoutePath): void;
|
|
176
171
|
};
|
|
177
172
|
/**
|
|
178
173
|
* 履歴スタックへの追加方法を指定します。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.types.d.ts","sourceRoot":"","sources":["../../../src/engines/engine.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEpF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,KAAK,EAAE,YAAY,CAAC;IAEpB;;OAEG;IACH,MAAM,EAAE,SAAS,CAAC,YAAY,EAAE,GAAG,YAAY,EAAE,CAAC,CAAC;CACpD,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,IAAI,CAAC;CACV;AAED;;GAEG;AACH,yBAAiB,OAAO,CAAC;IACvB;;OAEG;IACH,KAAY,QAAQ,GAAG;QACrB;;WAEG;QACH,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;QAEzB;;WAEG;QACH,eAAe,EAAE,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAEjF;;WAEG;QACH,SAAS,EAAE,MAAM,WAAW,CAAC;KAC9B,CAAC;IAEF;;;;OAIG;IACH,KAAY,UAAU,GAAG,WAAW,GAAG,IAAI,CAAC;IAE5C;;;;OAIG;IACH,KAAY,SAAS,GAAG;QACtB;;WAEG;QACH,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;QAEzB;;WAEG;QACH,eAAe,EAAE,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAEjF;;WAEG;QACH,eAAe,EAAE,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAEjF;;;;WAIG;QACH,MAAM,EAAE;YACN;;eAEG;YACH,IAAI,IAAI,CAAC;YAET;;;;eAIG;YACH,CAAC,cAAc,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;SAC5C,CAAC;QAEF;;WAEG;QACH,SAAS,EAAE,MAAM,WAAW,CAAC;KAC9B,CAAC;IAEF;;;;OAIG;IACH,KAAY,WAAW,GAAG,WAAW,GAAG,IAAI,CAAC;IAE7C;;OAEG;IACH,KAAY,UAAU,GAClB;QACE;;WAEG;QACH,IAAI,EAAE,WAAW,CAAC;QAElB;;WAEG;QACH,MAAM,EAAE,gBAAgB,CAAC;QAEzB;;WAEG;QACH,MAAM,EAAE,MAAM,CAAC;KAChB,GACD;QACE;;WAEG;QACH,IAAI,EAAE,mBAAmB,CAAC;QAE1B;;WAEG;QACH,MAAM,EAAE,uBAAuB,CAAC;QAEhC;;WAEG;QACH,MAAM,EAAE,MAAM,CAAC;QAEf;;;;;WAKG;QACH,OAAO,EAAE,SAAS,GAAG,MAAM,CAAC;KAC7B,CAAC;IAEN;;;;OAIG;IACH,KAAY,YAAY,GACpB;QACE;;WAEG;QACH,IAAI,EAAE,MAAM,CAAC;QAEb;;WAEG;QACH,EAAE,EACE;YACE;;eAEG;YACH,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"engine.types.d.ts","sourceRoot":"","sources":["../../../src/engines/engine.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-api-engine.d.ts","sourceRoot":"","sources":["../../../src/engines/navigation-api-engine.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAoB,YAAW,OAAO;IACzD;;OAEG;IACH,OAAO,CAAC,UAAU,CAAa;IAE/B;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAsB;IAEhD;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAyB;IAEnD;;;;OAIG;;IAwBH;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,UAAU;IA2BhD;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"navigation-api-engine.d.ts","sourceRoot":"","sources":["../../../src/engines/navigation-api-engine.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAoB,YAAW,OAAO;IACzD;;OAEG;IACH,OAAO,CAAC,UAAU,CAAa;IAE/B;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAsB;IAEhD;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAyB;IAEnD;;;;OAIG;;IAwBH;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,UAAU;IA2BhD;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,WAAW;IA8RnD;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,GAAG,IAAI;IAkCtC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,GAAG,IAAI;CAgE3C"}
|
|
@@ -78,8 +78,7 @@ export default class NavigationApiEngine {
|
|
|
78
78
|
* ユーザーのアクションによって発生したすべての遷移要求をインターセプトして処理する、ルーティングの中枢ハンドラーです。
|
|
79
79
|
*/
|
|
80
80
|
const handleNavigate = (event) => {
|
|
81
|
-
//
|
|
82
|
-
// 標準の挙動を妨げないようにインターセプトせず即座にスルーします。
|
|
81
|
+
// 処理すべきでない通常のブラウザー固有のナビゲーション(ハッシュ変更、ファイルのダウンロードなど)は、標準の挙動を妨げないようにインターセプトせず即座にスルーします。
|
|
83
82
|
// 参照: https://developer.mozilla.org/docs/Web/API/Navigation_API#handling_a_navigation_using_intercept
|
|
84
83
|
if (!event.isTrusted ||
|
|
85
84
|
!event.canIntercept ||
|
|
@@ -146,19 +145,18 @@ export default class NavigationApiEngine {
|
|
|
146
145
|
switch (action.data.status) {
|
|
147
146
|
case "rejected": {
|
|
148
147
|
// アクションがエラーで失敗した場合は、URL を変更せず現在の元のページに強制リダイレクトさせます。
|
|
149
|
-
|
|
150
|
-
controller.redirect(pathname + search + hash);
|
|
148
|
+
controller.redirect(RoutePath.encode(currentEntry.url));
|
|
151
149
|
break;
|
|
152
150
|
}
|
|
153
151
|
case "fulfilled": {
|
|
154
152
|
// アクションが正常終了した場合、返り値にリダイレクト指示が含まれていればその目的地へ遷移させます。
|
|
155
153
|
// リダイレクトがなければそのまま本来の目的地へとブラウザーのコミット先を書き換えます。
|
|
156
154
|
const { redirectTo = currentEntry.url } = actionResponse;
|
|
157
|
-
const
|
|
158
|
-
controller.redirect(
|
|
159
|
-
redirectUrl.pathname = pathname;
|
|
160
|
-
redirectUrl.search = search;
|
|
161
|
-
redirectUrl.hash = hash;
|
|
155
|
+
const redirectPath = new RoutePath(redirectTo);
|
|
156
|
+
controller.redirect(redirectPath.toString());
|
|
157
|
+
redirectUrl.pathname = redirectPath.pathname;
|
|
158
|
+
redirectUrl.search = redirectPath.search;
|
|
159
|
+
redirectUrl.hash = redirectPath.hash;
|
|
162
160
|
break;
|
|
163
161
|
}
|
|
164
162
|
default:
|
|
@@ -356,28 +354,21 @@ export default class NavigationApiEngine {
|
|
|
356
354
|
case "LINK": {
|
|
357
355
|
const { to, history } = args;
|
|
358
356
|
switch (to.type) {
|
|
359
|
-
case "
|
|
357
|
+
case "STATIC": {
|
|
360
358
|
// 完全なパス文字列の余分なスラッシュなどをエンコードして直接遷移します。
|
|
361
359
|
const path = RoutePath.encode(to.path);
|
|
362
360
|
this.navigation.navigate(path, { history });
|
|
363
361
|
break;
|
|
364
362
|
}
|
|
365
|
-
case "
|
|
366
|
-
//
|
|
363
|
+
case "DYNAMIC": {
|
|
364
|
+
// 現在のロケーション情報をベースに、指定されたパーツ(パス名、クエリー、ハッシュのみなど)を部分的に上書きしたマージ URL を算出します。
|
|
367
365
|
const currentPath = new RoutePath(window.location);
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
if (typeof to.search === "string") {
|
|
373
|
-
nextPath.search = to.search;
|
|
374
|
-
}
|
|
375
|
-
if (typeof to.hash === "string") {
|
|
376
|
-
nextPath.hash = to.hash;
|
|
377
|
-
}
|
|
366
|
+
const currentPathString = currentPath.toString();
|
|
367
|
+
const nextPath = currentPath;
|
|
368
|
+
to.patch(nextPath);
|
|
378
369
|
const nextPathString = nextPath.toString();
|
|
379
370
|
// 無駄な遷移履歴を作らないように、URL に実際の変化がある場合のみ navigate を実行します。
|
|
380
|
-
if (nextPathString !==
|
|
371
|
+
if (nextPathString !== currentPathString) {
|
|
381
372
|
this.navigation.navigate(nextPathString, { history });
|
|
382
373
|
}
|
|
383
374
|
break;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RoutePath } from "../core.js";
|
|
1
2
|
/**
|
|
2
3
|
* 遷移先のアドレスを指定するための表現型です。
|
|
3
4
|
*
|
|
@@ -16,6 +17,13 @@ export type NavigateTo = string | {
|
|
|
16
17
|
* 遷移先に付与するハッシュフラグメント(例: `"#profile"`)です。
|
|
17
18
|
*/
|
|
18
19
|
readonly hash?: string | undefined;
|
|
20
|
+
} | {
|
|
21
|
+
/**
|
|
22
|
+
* 動的にパッチを適用します。
|
|
23
|
+
*
|
|
24
|
+
* @param path アプリケーション内のルーティングにおけるパスを安全に構築・解析・操作するためのオブジェクトです。
|
|
25
|
+
*/
|
|
26
|
+
(route: RoutePath): void;
|
|
19
27
|
};
|
|
20
28
|
/**
|
|
21
29
|
* 画面遷移の挙動をカスタマイズするためのオプション型です。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-navigate.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-navigate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-navigate.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-navigate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB,MAAM,GACN;IACE;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEvC;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAErC;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC,GACD;IACE;;;;OAIG;IACH,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEN;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAElD;;;;OAIG;IACH,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,WAAW,IAAI,gBAAgB,CA6DtD"}
|
|
@@ -23,7 +23,27 @@ export default function useNavigate() {
|
|
|
23
23
|
return routerNavigate({
|
|
24
24
|
to: {
|
|
25
25
|
path: to,
|
|
26
|
-
type: "
|
|
26
|
+
type: "STATIC",
|
|
27
|
+
},
|
|
28
|
+
type: "LINK",
|
|
29
|
+
history,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else if (typeof to === "object") {
|
|
33
|
+
return routerNavigate({
|
|
34
|
+
to: {
|
|
35
|
+
type: "DYNAMIC",
|
|
36
|
+
patch(path) {
|
|
37
|
+
if (typeof to.pathname === "string") {
|
|
38
|
+
path.pathname = to.pathname;
|
|
39
|
+
}
|
|
40
|
+
if (typeof to.search === "string") {
|
|
41
|
+
path.search = to.search;
|
|
42
|
+
}
|
|
43
|
+
if (typeof to.hash === "string") {
|
|
44
|
+
path.hash = to.hash;
|
|
45
|
+
}
|
|
46
|
+
},
|
|
27
47
|
},
|
|
28
48
|
type: "LINK",
|
|
29
49
|
history,
|
|
@@ -32,8 +52,10 @@ export default function useNavigate() {
|
|
|
32
52
|
else {
|
|
33
53
|
return routerNavigate({
|
|
34
54
|
to: {
|
|
35
|
-
|
|
36
|
-
|
|
55
|
+
type: "DYNAMIC",
|
|
56
|
+
patch(path) {
|
|
57
|
+
to(path);
|
|
58
|
+
},
|
|
37
59
|
},
|
|
38
60
|
type: "LINK",
|
|
39
61
|
history,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-route-path.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-route-path.ts"],"names":[],"mappings":"AAEA,OAAkB,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG1E,MAAM,CAAC,OAAO,UAAU,YAAY,IAAI,iBAAiB,CAKxD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import RoutePath from "../core/route-path.js";
|
|
3
|
+
import useRouterContext from "./use-router-context.js";
|
|
4
|
+
export default function useRoutePath() {
|
|
5
|
+
const url = useRouterContext((router) => router.currentEntry.url);
|
|
6
|
+
const path = React.useMemo(() => new RoutePath(url), [url]);
|
|
7
|
+
return path;
|
|
8
|
+
}
|
package/dist/src/soseki.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export { default as Outlet } from "./components/outlet.jsx";
|
|
|
5
5
|
/**************************************************************************************************/
|
|
6
6
|
export type { Issue, UnreachableErrorArgs, UnreachableErrorMeta, LoaderConditionErrorArgs, LoaderConditionErrorMeta, LoaderDataNotFoundErrorArgs, LoaderDataNotFoundErrorMeta, UnexpectedValidationErrorArgs, UnexpectedValidationErrorMeta, } from "./core/errors.js";
|
|
7
7
|
export { ErrorBase, setErrorMessage, UnreachableError, ValidationErrorBase, LoaderConditionError, LoaderDataNotFoundError, RouteContextMissingError, RouterContextMissingError, UnexpectedValidationError, NavigationApiNotSupportedError, } from "./core/errors.js";
|
|
8
|
+
export type * from "./core/match-route-path.js";
|
|
9
|
+
export { default as matchRoutePath } from "./core/match-route-path.js";
|
|
8
10
|
export type * from "./core/readonly-form-data.types.js";
|
|
9
11
|
export type * from "./core/readonly-url.types.js";
|
|
10
12
|
export type * from "./core/redirect-response.js";
|
|
@@ -23,6 +25,8 @@ export type * from "./hooks/use-navigate.js";
|
|
|
23
25
|
export { default as useNavigate } from "./hooks/use-navigate.js";
|
|
24
26
|
export type * from "./hooks/use-params.js";
|
|
25
27
|
export { default as useParams } from "./hooks/use-params.js";
|
|
28
|
+
export type * from "./hooks/use-route-path.js";
|
|
29
|
+
export { default as useRoutePath } from "./hooks/use-route-path.js";
|
|
26
30
|
export type * from "./hooks/use-submit.js";
|
|
27
31
|
export { default as useSubmit } from "./hooks/use-submit.js";
|
|
28
32
|
/**************************************************************************************************/
|
package/dist/src/soseki.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"soseki.d.ts","sourceRoot":"","sources":["../../src/soseki.ts"],"names":[],"mappings":"AAAA,mBAAmB,iCAAiC,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAE3E,mBAAmB,yBAAyB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAE5D,oGAAoG;AAEpG,YAAY,EACV,KAAK,EACL,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,8BAA8B,GAC/B,MAAM,kBAAkB,CAAC;AAE1B,mBAAmB,oCAAoC,CAAC;AAExD,mBAAmB,8BAA8B,CAAC;AAElD,mBAAmB,6BAA6B,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,mBAAmB,yBAAyB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAElE,mBAAmB,uBAAuB,CAAC;AAE3C,oGAAoG;AAEpG,mBAAmB,4BAA4B,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEtE,mBAAmB,4BAA4B,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEtE,mBAAmB,4BAA4B,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEtE,mBAAmB,yBAAyB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEjE,mBAAmB,uBAAuB,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE7D,mBAAmB,uBAAuB,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE7D,oGAAoG;AAEpG,mBAAmB,qBAAqB,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"soseki.d.ts","sourceRoot":"","sources":["../../src/soseki.ts"],"names":[],"mappings":"AAAA,mBAAmB,iCAAiC,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAE3E,mBAAmB,yBAAyB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAE5D,oGAAoG;AAEpG,YAAY,EACV,KAAK,EACL,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,8BAA8B,GAC/B,MAAM,kBAAkB,CAAC;AAE1B,mBAAmB,4BAA4B,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAEvE,mBAAmB,oCAAoC,CAAC;AAExD,mBAAmB,8BAA8B,CAAC;AAElD,mBAAmB,6BAA6B,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,mBAAmB,yBAAyB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAElE,mBAAmB,uBAAuB,CAAC;AAE3C,oGAAoG;AAEpG,mBAAmB,4BAA4B,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEtE,mBAAmB,4BAA4B,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEtE,mBAAmB,4BAA4B,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEtE,mBAAmB,yBAAyB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEjE,mBAAmB,uBAAuB,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE7D,mBAAmB,2BAA2B,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEpE,mBAAmB,uBAAuB,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE7D,oGAAoG;AAEpG,mBAAmB,qBAAqB,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/src/soseki.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { default as BrowserRouter } from "./components/browser-router.jsx";
|
|
2
2
|
export { default as Outlet } from "./components/outlet.jsx";
|
|
3
3
|
export { ErrorBase, setErrorMessage, UnreachableError, ValidationErrorBase, LoaderConditionError, LoaderDataNotFoundError, RouteContextMissingError, RouterContextMissingError, UnexpectedValidationError, NavigationApiNotSupportedError, } from "./core/errors.js";
|
|
4
|
+
export { default as matchRoutePath } from "./core/match-route-path.js";
|
|
4
5
|
export { default as RedirectResponse } from "./core/redirect-response.js";
|
|
5
6
|
export { default as RouteRequest } from "./core/route-request.js";
|
|
6
7
|
export { default as useActionData } from "./hooks/use-action-data.js";
|
|
@@ -8,5 +9,6 @@ export { default as useFormAction } from "./hooks/use-form-action.js";
|
|
|
8
9
|
export { default as useLoaderData } from "./hooks/use-loader-data.js";
|
|
9
10
|
export { default as useNavigate } from "./hooks/use-navigate.js";
|
|
10
11
|
export { default as useParams } from "./hooks/use-params.js";
|
|
12
|
+
export { default as useRoutePath } from "./hooks/use-route-path.js";
|
|
11
13
|
export { default as useSubmit } from "./hooks/use-submit.js";
|
|
12
14
|
export { default as redirect } from "./utils/redirect.js";
|
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { RouteDefinition } from "../core/route.types.js";
|
|
2
1
|
import NavigationApiEngine from "../engines/navigation-api-engine.js";
|
|
3
2
|
import useSingleton from "../hooks/_use-singleton.js";
|
|
4
|
-
import Router from "./router.jsx";
|
|
3
|
+
import Router, { type RouterRouteDefinition } from "./router.jsx";
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* `BrowserRouter` コンポーネントに引き渡すプロパティーの型定義です。
|
|
@@ -10,7 +9,7 @@ export type BrowserRouterProps = {
|
|
|
10
9
|
/**
|
|
11
10
|
* アプリケーション全体の画面構造を定義したルート定義の配列です。
|
|
12
11
|
*/
|
|
13
|
-
routes: readonly
|
|
12
|
+
routes: readonly RouterRouteDefinition[];
|
|
14
13
|
};
|
|
15
14
|
|
|
16
15
|
/**
|
|
@@ -10,7 +10,7 @@ import processRoutes from "../core/_process-routes.js";
|
|
|
10
10
|
import type { HistoryEntry } from "../core/expect-history-entry.js";
|
|
11
11
|
import type { HistoryEntryId } from "../core/history-entry-id-schema.js";
|
|
12
12
|
import type { MatchedRoute } from "../core/match-routes.js";
|
|
13
|
-
import type { ActionFunction, LoaderFunction
|
|
13
|
+
import type { ActionFunction, LoaderFunction } from "../core/route.types.js";
|
|
14
14
|
import type { IEngine, RouterState } from "../engines/engine.types.js";
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -77,6 +77,28 @@ function RouteRenderer(props: RouteRendererProps): React.ReactElement {
|
|
|
77
77
|
return <ComponentRenderer route={route} outlet={outlet} />;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
export type RouterRouteDefinitionObject = {
|
|
81
|
+
readonly path: string;
|
|
82
|
+
readonly index?: boolean | undefined;
|
|
83
|
+
readonly action?: { (args: any): unknown } | undefined;
|
|
84
|
+
readonly shouldReload?: { (args: any): boolean } | undefined;
|
|
85
|
+
readonly loader?: { (args: any): unknown } | undefined;
|
|
86
|
+
readonly component?: React.ComponentType<{}> | undefined;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export type RouterRouteDefinitionModule = {
|
|
90
|
+
readonly path: string;
|
|
91
|
+
readonly index?: boolean | undefined;
|
|
92
|
+
readonly action?: { (args: any): unknown } | undefined;
|
|
93
|
+
readonly shouldReload?: { (args: any): boolean } | undefined;
|
|
94
|
+
readonly loader?: { (args: any): unknown } | undefined;
|
|
95
|
+
readonly component?: React.ComponentType<{}> | undefined;
|
|
96
|
+
readonly default?: React.ComponentType<{}> | undefined;
|
|
97
|
+
get [Symbol.toStringTag](): string;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export type RouterRouteDefinition = RouterRouteDefinitionObject | RouterRouteDefinitionModule;
|
|
101
|
+
|
|
80
102
|
/**
|
|
81
103
|
* `Router` コンポーネントに渡されるルートプロパティーの型定義です。
|
|
82
104
|
*/
|
|
@@ -89,7 +111,7 @@ export type RouterProps = {
|
|
|
89
111
|
/**
|
|
90
112
|
* ユーザーがアプリケーションに定義したルート定義の配列です。
|
|
91
113
|
*/
|
|
92
|
-
routes: readonly
|
|
114
|
+
routes: readonly RouterRouteDefinition[];
|
|
93
115
|
};
|
|
94
116
|
|
|
95
117
|
/**
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { parse } from "regexparam";
|
|
2
|
+
|
|
3
|
+
import RoutePath from "./route-path.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ルーティングの照合対象となる URL 情報を表すインターフェースです。
|
|
7
|
+
*/
|
|
8
|
+
export interface MatchRoutePathTargetURL {
|
|
9
|
+
/**
|
|
10
|
+
* 照合対象のパス名です。
|
|
11
|
+
*/
|
|
12
|
+
readonly pathname: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* `matchRoutePath` 関数の動作を設定するための型定義です。
|
|
17
|
+
*/
|
|
18
|
+
export type MatchRoutePathOptions = {
|
|
19
|
+
/**
|
|
20
|
+
* 照合の基準となるルーティングのパターン文字列です。
|
|
21
|
+
*/
|
|
22
|
+
readonly pattern: string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 照合対象とする文字列または URL オブジェクトです。
|
|
26
|
+
*/
|
|
27
|
+
readonly target: string | MatchRoutePathTargetURL;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 子ディレクトリーへの前方一致を許可するかどうかを制御するフラグです。
|
|
31
|
+
*
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
readonly allowChild?: boolean | undefined;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 指定されたパターンと対象のパス名が一致するかどうかを判定します。
|
|
39
|
+
*
|
|
40
|
+
* @param options パターン、対象、および一致条件を含む設定オブジェクトです。
|
|
41
|
+
* @returns パターンに一致した場合は `true` を、一致しない場合は `false` を返します。
|
|
42
|
+
*/
|
|
43
|
+
function matchRoutePath(options: MatchRoutePathOptions): boolean;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 指定されたパターンと対象のパス名が一致するかどうかを判定します。
|
|
47
|
+
*
|
|
48
|
+
* @param pattern 照合の基準となるルーティングのパターン文字列です。
|
|
49
|
+
* @param target 照合対象とする文字列または URL オブジェクトです。
|
|
50
|
+
* @param options オプションです。
|
|
51
|
+
* @returns パターンに一致した場合は `true` を、一致しない場合は `false` を返します。
|
|
52
|
+
*/
|
|
53
|
+
function matchRoutePath(
|
|
54
|
+
pattern: MatchRoutePathOptions["pattern"],
|
|
55
|
+
target: MatchRoutePathOptions["target"],
|
|
56
|
+
options?: Omit<MatchRoutePathOptions, "pattern" | "target">,
|
|
57
|
+
): boolean;
|
|
58
|
+
|
|
59
|
+
function matchRoutePath(...args: any): boolean {
|
|
60
|
+
const {
|
|
61
|
+
target,
|
|
62
|
+
pattern,
|
|
63
|
+
allowChild = false,
|
|
64
|
+
}: MatchRoutePathOptions = typeof args[0] !== "string"
|
|
65
|
+
? args[0]
|
|
66
|
+
: {
|
|
67
|
+
...args[2],
|
|
68
|
+
target: args[1],
|
|
69
|
+
pattern: args[0],
|
|
70
|
+
};
|
|
71
|
+
const patternPathname = new RoutePath(pattern).pathname;
|
|
72
|
+
const targetPathname = typeof target === "string" ? target : target.pathname;
|
|
73
|
+
const patternRegex = parse(patternPathname, allowChild).pattern;
|
|
74
|
+
|
|
75
|
+
return patternRegex.test(targetPathname);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export default matchRoutePath;
|
package/src/core/route-path.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReadonlyURL } from "./readonly-url.types.js";
|
|
1
|
+
import type { ReadonlyURL, ReadonlyURLSearchParams } from "./readonly-url.types.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 連続する複数のスラッシュを検出するための正規表現です。
|
|
@@ -10,7 +10,50 @@ const MULTI_SLASH = /\/\/+/gu;
|
|
|
10
10
|
*
|
|
11
11
|
* 内包するホストやプロトコルといった余分な情報を排除し、パス、クエリー、ハッシュのみを一貫した規則で管理します。
|
|
12
12
|
*/
|
|
13
|
-
export
|
|
13
|
+
export interface ReadonlyRoutePath {
|
|
14
|
+
/**
|
|
15
|
+
* 正規化されたパス部分の文字列です。
|
|
16
|
+
*/
|
|
17
|
+
readonly pathname: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 先頭に `?` を含むクエリー文字列です。
|
|
21
|
+
*
|
|
22
|
+
* 常にソートされます。
|
|
23
|
+
*/
|
|
24
|
+
readonly search: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 内部の `URL` インスタンスが保持する、クエリーパラメーターを操作するための `URLSearchParams` オブジェクトを取得します。
|
|
28
|
+
*/
|
|
29
|
+
readonly searchParams: ReadonlyURLSearchParams;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 先頭に `#` を含むハッシュ文字列を取得します。
|
|
33
|
+
*/
|
|
34
|
+
readonly hash: string;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 現在保持しているすべてのコンポーネントを結合し、ルーティング用のパス文字列として出力します。
|
|
38
|
+
*
|
|
39
|
+
* @returns ソート済みのクエリーおよびハッシュを含んだ、正規化されたパス全体の文字列を返します。
|
|
40
|
+
*/
|
|
41
|
+
toString(): string;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* このインスタンスを複製し、上書き可能な形式で取得します。
|
|
45
|
+
*
|
|
46
|
+
* @returns 上書き可能な {@link RoutePath|`RoutePath`} インスタンスです。
|
|
47
|
+
*/
|
|
48
|
+
clone(): RoutePath;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* アプリケーション内のルーティングにおけるパスを安全に構築・解析・操作するためのクラスです。
|
|
53
|
+
*
|
|
54
|
+
* 内包するホストやプロトコルといった余分な情報を排除し、パス、クエリー、ハッシュのみを一貫した規則で管理します。
|
|
55
|
+
*/
|
|
56
|
+
export default class RoutePath implements ReadonlyRoutePath {
|
|
14
57
|
/**
|
|
15
58
|
* 与えられた文字列または URL オブジェクトから、正規化されたパス文字列を即座に生成する静的メソッドです。
|
|
16
59
|
*
|
|
@@ -26,7 +69,7 @@ export default class RoutePath {
|
|
|
26
69
|
*
|
|
27
70
|
* 基底となる仮想的なオリジンと結合して管理されます。
|
|
28
71
|
*/
|
|
29
|
-
|
|
72
|
+
readonly #url: URL;
|
|
30
73
|
|
|
31
74
|
/**
|
|
32
75
|
* 新しい `RoutePath` インスタンスを初期化します。
|
|
@@ -44,12 +87,12 @@ export default class RoutePath {
|
|
|
44
87
|
}
|
|
45
88
|
|
|
46
89
|
// 組み込みの URL クラスによる厳密な解析機能を利用するため、仮想のプロトコルとホストを前置きして初期化します。
|
|
47
|
-
this
|
|
90
|
+
this.#url = new URL("x://y" + path);
|
|
48
91
|
|
|
49
92
|
// ルートパス(/)単体である場合を除き、末尾に存在する不要なスラッシュを削除して一貫性を保ちます。
|
|
50
|
-
const { pathname } = this
|
|
93
|
+
const { pathname } = this.#url;
|
|
51
94
|
if (pathname !== "/" && pathname.endsWith("/")) {
|
|
52
|
-
this
|
|
95
|
+
this.#url.pathname = pathname.substring(0, pathname.length - 1);
|
|
53
96
|
}
|
|
54
97
|
}
|
|
55
98
|
|
|
@@ -57,16 +100,16 @@ export default class RoutePath {
|
|
|
57
100
|
* 正規化されたパス部分の文字列です。
|
|
58
101
|
*/
|
|
59
102
|
public get pathname(): string {
|
|
60
|
-
return this
|
|
103
|
+
return this.#url.pathname;
|
|
61
104
|
}
|
|
62
105
|
|
|
63
106
|
public set pathname(value: string) {
|
|
64
|
-
this
|
|
107
|
+
this.#url.pathname = value;
|
|
65
108
|
|
|
66
109
|
// ルートパス(/)単体である場合を除き、末尾に存在する不要なスラッシュを削除して一貫性を保ちます。
|
|
67
|
-
const pathname = ("/" + this
|
|
110
|
+
const pathname = ("/" + this.#url.pathname).replace(MULTI_SLASH, "/");
|
|
68
111
|
if (pathname !== "/" && pathname.endsWith("/")) {
|
|
69
|
-
this
|
|
112
|
+
this.#url.pathname = pathname.substring(0, pathname.length - 1);
|
|
70
113
|
}
|
|
71
114
|
}
|
|
72
115
|
|
|
@@ -76,30 +119,30 @@ export default class RoutePath {
|
|
|
76
119
|
* 常にソートされます。
|
|
77
120
|
*/
|
|
78
121
|
public get search(): string {
|
|
79
|
-
this
|
|
80
|
-
return this
|
|
122
|
+
this.#url.searchParams.sort();
|
|
123
|
+
return this.#url.search;
|
|
81
124
|
}
|
|
82
125
|
|
|
83
126
|
public set search(value: string) {
|
|
84
|
-
this
|
|
127
|
+
this.#url.search = value;
|
|
85
128
|
}
|
|
86
129
|
|
|
87
130
|
/**
|
|
88
131
|
* 内部の `URL` インスタンスが保持する、クエリーパラメーターを操作するための `URLSearchParams` オブジェクトを取得します。
|
|
89
132
|
*/
|
|
90
133
|
public get searchParams(): URLSearchParams {
|
|
91
|
-
return this
|
|
134
|
+
return this.#url.searchParams;
|
|
92
135
|
}
|
|
93
136
|
|
|
94
137
|
/**
|
|
95
138
|
* 先頭に `#` を含むハッシュ文字列を取得します。
|
|
96
139
|
*/
|
|
97
140
|
public get hash(): string {
|
|
98
|
-
return this
|
|
141
|
+
return this.#url.hash;
|
|
99
142
|
}
|
|
100
143
|
|
|
101
144
|
public set hash(value: string) {
|
|
102
|
-
this
|
|
145
|
+
this.#url.hash = value;
|
|
103
146
|
}
|
|
104
147
|
|
|
105
148
|
/**
|
|
@@ -111,4 +154,13 @@ export default class RoutePath {
|
|
|
111
154
|
const { hash, search, pathname } = this;
|
|
112
155
|
return pathname + search + hash;
|
|
113
156
|
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* このインスタンスを複製し、上書き可能な形式で取得します。
|
|
160
|
+
*
|
|
161
|
+
* @returns 上書き可能な {@link RoutePath|`RoutePath`} インスタンスです。
|
|
162
|
+
*/
|
|
163
|
+
public clone(): RoutePath {
|
|
164
|
+
return new RoutePath(this.toString());
|
|
165
|
+
}
|
|
114
166
|
}
|
package/src/core.ts
CHANGED
|
@@ -34,3 +34,11 @@ export { default as startAction } from "./core/start-action.js";
|
|
|
34
34
|
|
|
35
35
|
export type * from "./core/start-loaders.js";
|
|
36
36
|
export { default as startLoaders } from "./core/start-loaders.js";
|
|
37
|
+
|
|
38
|
+
/**************************************************************************************************/
|
|
39
|
+
|
|
40
|
+
export type * from "./hooks/use-route-context.js";
|
|
41
|
+
export { default as useRouteContext } from "./hooks/use-route-context.js";
|
|
42
|
+
|
|
43
|
+
export type * from "./hooks/use-router-context.js";
|
|
44
|
+
export { default as useRouterContext } from "./hooks/use-router-context.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { NinjaPromise } from "ninja-promise";
|
|
2
2
|
|
|
3
|
+
import type { RoutePath } from "../core.js";
|
|
3
4
|
import type { HistoryEntry } from "../core/expect-history-entry.js";
|
|
4
5
|
import type { HistoryEntryId } from "../core/history-entry-id-schema.js";
|
|
5
6
|
import type { MatchedRoute } from "../core/match-routes.js";
|
|
@@ -178,7 +179,7 @@ export namespace IEngine {
|
|
|
178
179
|
/**
|
|
179
180
|
* URL パスで前方移動する形式です。
|
|
180
181
|
*/
|
|
181
|
-
type: "
|
|
182
|
+
type: "STATIC";
|
|
182
183
|
|
|
183
184
|
/**
|
|
184
185
|
* URL パスです。
|
|
@@ -187,24 +188,16 @@ export namespace IEngine {
|
|
|
187
188
|
}
|
|
188
189
|
| {
|
|
189
190
|
/**
|
|
190
|
-
* URL
|
|
191
|
+
* URL の各コンポーネントを関数形式で個別に指定する形式です。
|
|
191
192
|
*/
|
|
192
|
-
type: "
|
|
193
|
+
type: "DYNAMIC";
|
|
193
194
|
|
|
194
195
|
/**
|
|
195
|
-
*
|
|
196
|
+
* 動的にパッチを適用する関数です。
|
|
197
|
+
*
|
|
198
|
+
* @param path アプリケーション内のルーティングにおけるパスを安全に構築・解析・操作するためのオブジェクトです。
|
|
196
199
|
*/
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* 先頭のクエスチョンマーク `?` を含む URL のクエリー文字列です。
|
|
201
|
-
*/
|
|
202
|
-
search?: string | undefined;
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* URL のハッシュ(シャープ記号 `#` を含むフラグメント識別子)です。
|
|
206
|
-
*/
|
|
207
|
-
hash?: string | undefined;
|
|
200
|
+
patch(path: RoutePath): void;
|
|
208
201
|
};
|
|
209
202
|
|
|
210
203
|
/**
|
|
@@ -105,8 +105,7 @@ export default class NavigationApiEngine implements IEngine {
|
|
|
105
105
|
* ユーザーのアクションによって発生したすべての遷移要求をインターセプトして処理する、ルーティングの中枢ハンドラーです。
|
|
106
106
|
*/
|
|
107
107
|
const handleNavigate = (event: NavigateEvent): void => {
|
|
108
|
-
//
|
|
109
|
-
// 標準の挙動を妨げないようにインターセプトせず即座にスルーします。
|
|
108
|
+
// 処理すべきでない通常のブラウザー固有のナビゲーション(ハッシュ変更、ファイルのダウンロードなど)は、標準の挙動を妨げないようにインターセプトせず即座にスルーします。
|
|
110
109
|
// 参照: https://developer.mozilla.org/docs/Web/API/Navigation_API#handling_a_navigation_using_intercept
|
|
111
110
|
if (
|
|
112
111
|
!event.isTrusted ||
|
|
@@ -187,8 +186,7 @@ export default class NavigationApiEngine implements IEngine {
|
|
|
187
186
|
switch (action.data.status) {
|
|
188
187
|
case "rejected": {
|
|
189
188
|
// アクションがエラーで失敗した場合は、URL を変更せず現在の元のページに強制リダイレクトさせます。
|
|
190
|
-
|
|
191
|
-
controller.redirect(pathname + search + hash);
|
|
189
|
+
controller.redirect(RoutePath.encode(currentEntry.url));
|
|
192
190
|
|
|
193
191
|
break;
|
|
194
192
|
}
|
|
@@ -197,12 +195,12 @@ export default class NavigationApiEngine implements IEngine {
|
|
|
197
195
|
// アクションが正常終了した場合、返り値にリダイレクト指示が含まれていればその目的地へ遷移させます。
|
|
198
196
|
// リダイレクトがなければそのまま本来の目的地へとブラウザーのコミット先を書き換えます。
|
|
199
197
|
const { redirectTo = currentEntry.url } = actionResponse;
|
|
200
|
-
const
|
|
201
|
-
controller.redirect(
|
|
198
|
+
const redirectPath = new RoutePath(redirectTo);
|
|
199
|
+
controller.redirect(redirectPath.toString());
|
|
202
200
|
|
|
203
|
-
redirectUrl.pathname = pathname;
|
|
204
|
-
redirectUrl.search = search;
|
|
205
|
-
redirectUrl.hash = hash;
|
|
201
|
+
redirectUrl.pathname = redirectPath.pathname;
|
|
202
|
+
redirectUrl.search = redirectPath.search;
|
|
203
|
+
redirectUrl.hash = redirectPath.hash;
|
|
206
204
|
|
|
207
205
|
break;
|
|
208
206
|
}
|
|
@@ -435,7 +433,7 @@ export default class NavigationApiEngine implements IEngine {
|
|
|
435
433
|
case "LINK": {
|
|
436
434
|
const { to, history } = args;
|
|
437
435
|
switch (to.type) {
|
|
438
|
-
case "
|
|
436
|
+
case "STATIC": {
|
|
439
437
|
// 完全なパス文字列の余分なスラッシュなどをエンコードして直接遷移します。
|
|
440
438
|
|
|
441
439
|
const path = RoutePath.encode(to.path);
|
|
@@ -444,25 +442,17 @@ export default class NavigationApiEngine implements IEngine {
|
|
|
444
442
|
break;
|
|
445
443
|
}
|
|
446
444
|
|
|
447
|
-
case "
|
|
448
|
-
//
|
|
445
|
+
case "DYNAMIC": {
|
|
446
|
+
// 現在のロケーション情報をベースに、指定されたパーツ(パス名、クエリー、ハッシュのみなど)を部分的に上書きしたマージ URL を算出します。
|
|
449
447
|
|
|
450
448
|
const currentPath = new RoutePath(window.location);
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
}
|
|
455
|
-
if (typeof to.search === "string") {
|
|
456
|
-
nextPath.search = to.search;
|
|
457
|
-
}
|
|
458
|
-
if (typeof to.hash === "string") {
|
|
459
|
-
nextPath.hash = to.hash;
|
|
460
|
-
}
|
|
461
|
-
|
|
449
|
+
const currentPathString = currentPath.toString();
|
|
450
|
+
const nextPath = currentPath;
|
|
451
|
+
to.patch(nextPath);
|
|
462
452
|
const nextPathString = nextPath.toString();
|
|
463
453
|
|
|
464
454
|
// 無駄な遷移履歴を作らないように、URL に実際の変化がある場合のみ navigate を実行します。
|
|
465
|
-
if (nextPathString !==
|
|
455
|
+
if (nextPathString !== currentPathString) {
|
|
466
456
|
this.navigation.navigate(nextPathString, { history });
|
|
467
457
|
}
|
|
468
458
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
import type {} from "../
|
|
3
|
+
import type { RoutePath } from "../core.js";
|
|
4
4
|
import useRouterContext from "./use-router-context.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -25,6 +25,14 @@ export type NavigateTo =
|
|
|
25
25
|
* 遷移先に付与するハッシュフラグメント(例: `"#profile"`)です。
|
|
26
26
|
*/
|
|
27
27
|
readonly hash?: string | undefined;
|
|
28
|
+
}
|
|
29
|
+
| {
|
|
30
|
+
/**
|
|
31
|
+
* 動的にパッチを適用します。
|
|
32
|
+
*
|
|
33
|
+
* @param path アプリケーション内のルーティングにおけるパスを安全に構築・解析・操作するためのオブジェクトです。
|
|
34
|
+
*/
|
|
35
|
+
(route: RoutePath): void;
|
|
28
36
|
};
|
|
29
37
|
|
|
30
38
|
/**
|
|
@@ -84,7 +92,26 @@ export default function useNavigate(): NavigateFunction {
|
|
|
84
92
|
return routerNavigate({
|
|
85
93
|
to: {
|
|
86
94
|
path: to,
|
|
87
|
-
type: "
|
|
95
|
+
type: "STATIC",
|
|
96
|
+
},
|
|
97
|
+
type: "LINK",
|
|
98
|
+
history,
|
|
99
|
+
});
|
|
100
|
+
} else if (typeof to === "object") {
|
|
101
|
+
return routerNavigate({
|
|
102
|
+
to: {
|
|
103
|
+
type: "DYNAMIC",
|
|
104
|
+
patch(path) {
|
|
105
|
+
if (typeof to.pathname === "string") {
|
|
106
|
+
path.pathname = to.pathname;
|
|
107
|
+
}
|
|
108
|
+
if (typeof to.search === "string") {
|
|
109
|
+
path.search = to.search;
|
|
110
|
+
}
|
|
111
|
+
if (typeof to.hash === "string") {
|
|
112
|
+
path.hash = to.hash;
|
|
113
|
+
}
|
|
114
|
+
},
|
|
88
115
|
},
|
|
89
116
|
type: "LINK",
|
|
90
117
|
history,
|
|
@@ -92,8 +119,10 @@ export default function useNavigate(): NavigateFunction {
|
|
|
92
119
|
} else {
|
|
93
120
|
return routerNavigate({
|
|
94
121
|
to: {
|
|
95
|
-
|
|
96
|
-
|
|
122
|
+
type: "DYNAMIC",
|
|
123
|
+
patch(path) {
|
|
124
|
+
to(path);
|
|
125
|
+
},
|
|
97
126
|
},
|
|
98
127
|
type: "LINK",
|
|
99
128
|
history,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import RoutePath, { type ReadonlyRoutePath } from "../core/route-path.js";
|
|
4
|
+
import useRouterContext from "./use-router-context.js";
|
|
5
|
+
|
|
6
|
+
export default function useRoutePath(): ReadonlyRoutePath {
|
|
7
|
+
const url = useRouterContext((router) => router.currentEntry.url);
|
|
8
|
+
const path = React.useMemo(() => new RoutePath(url), [url]);
|
|
9
|
+
|
|
10
|
+
return path;
|
|
11
|
+
}
|
package/src/soseki.ts
CHANGED
|
@@ -30,6 +30,9 @@ export {
|
|
|
30
30
|
NavigationApiNotSupportedError,
|
|
31
31
|
} from "./core/errors.js";
|
|
32
32
|
|
|
33
|
+
export type * from "./core/match-route-path.js";
|
|
34
|
+
export { default as matchRoutePath } from "./core/match-route-path.js";
|
|
35
|
+
|
|
33
36
|
export type * from "./core/readonly-form-data.types.js";
|
|
34
37
|
|
|
35
38
|
export type * from "./core/readonly-url.types.js";
|
|
@@ -59,6 +62,9 @@ export { default as useNavigate } from "./hooks/use-navigate.js";
|
|
|
59
62
|
export type * from "./hooks/use-params.js";
|
|
60
63
|
export { default as useParams } from "./hooks/use-params.js";
|
|
61
64
|
|
|
65
|
+
export type * from "./hooks/use-route-path.js";
|
|
66
|
+
export { default as useRoutePath } from "./hooks/use-route-path.js";
|
|
67
|
+
|
|
62
68
|
export type * from "./hooks/use-submit.js";
|
|
63
69
|
export { default as useSubmit } from "./hooks/use-submit.js";
|
|
64
70
|
|