soseki 0.0.1 → 0.0.2

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.
Files changed (200) hide show
  1. package/dist/components/action-id.d.ts +19 -0
  2. package/dist/components/action-id.d.ts.map +1 -0
  3. package/dist/components/action-id.jsx +14 -0
  4. package/dist/components/browser-router.d.ts +17 -0
  5. package/dist/components/browser-router.d.ts.map +1 -0
  6. package/dist/components/browser-router.jsx +13 -0
  7. package/dist/components/hidden-input.d.ts +20 -0
  8. package/dist/components/hidden-input.d.ts.map +1 -0
  9. package/dist/components/hidden-input.jsx +8 -0
  10. package/dist/components/outlet.d.ts +8 -0
  11. package/dist/components/outlet.d.ts.map +1 -0
  12. package/dist/components/outlet.jsx +15 -0
  13. package/dist/components/router.d.ts +23 -0
  14. package/dist/components/router.d.ts.map +1 -0
  15. package/dist/components/router.jsx +128 -0
  16. package/dist/contexts/route-context.d.ts +19 -0
  17. package/dist/contexts/route-context.d.ts.map +1 -0
  18. package/dist/contexts/route-context.js +6 -0
  19. package/dist/contexts/router-context.d.ts +46 -0
  20. package/dist/contexts/router-context.d.ts.map +1 -0
  21. package/dist/contexts/router-context.js +8 -0
  22. package/dist/core/_action-id-registry.d.ts +10 -0
  23. package/dist/core/_action-id-registry.d.ts.map +1 -0
  24. package/dist/core/_action-id-registry.js +8 -0
  25. package/dist/core/_capture-stack-trace.d.ts +8 -0
  26. package/dist/core/_capture-stack-trace.d.ts.map +1 -0
  27. package/dist/core/_capture-stack-trace.js +12 -0
  28. package/dist/core/_compare-route-paths.d.ts +11 -0
  29. package/dist/core/_compare-route-paths.d.ts.map +1 -0
  30. package/dist/core/_compare-route-paths.js +80 -0
  31. package/dist/core/_create-html-form-element-form-form-data.d.ts +9 -0
  32. package/dist/core/_create-html-form-element-form-form-data.d.ts.map +1 -0
  33. package/dist/core/_create-html-form-element-form-form-data.js +27 -0
  34. package/dist/core/_encode-pathname.d.ts +10 -0
  35. package/dist/core/_encode-pathname.d.ts.map +1 -0
  36. package/dist/core/_encode-pathname.js +16 -0
  37. package/dist/core/_is-error.d.ts +3 -0
  38. package/dist/core/_is-error.d.ts.map +1 -0
  39. package/dist/core/_is-error.js +13 -0
  40. package/dist/core/_is-promise-like.d.ts +8 -0
  41. package/dist/core/_is-promise-like.d.ts.map +1 -0
  42. package/dist/core/_is-promise-like.js +12 -0
  43. package/dist/core/_match-route-path.d.ts +19 -0
  44. package/dist/core/_match-route-path.d.ts.map +1 -0
  45. package/dist/core/_match-route-path.js +22 -0
  46. package/dist/core/_process-routes.d.ts +9 -0
  47. package/dist/core/_process-routes.d.ts.map +1 -0
  48. package/dist/core/_process-routes.js +47 -0
  49. package/dist/core/_singleton.d.ts +18 -0
  50. package/dist/core/_singleton.d.ts.map +1 -0
  51. package/dist/core/_singleton.js +37 -0
  52. package/dist/core/_unreachable.d.ts +12 -0
  53. package/dist/core/_unreachable.d.ts.map +1 -0
  54. package/dist/core/_unreachable.js +8 -0
  55. package/dist/core/_use-singleton.d.ts +11 -0
  56. package/dist/core/_use-singleton.d.ts.map +1 -0
  57. package/dist/core/_use-singleton.js +21 -0
  58. package/dist/core/_valibot.d.ts +52 -0
  59. package/dist/core/_valibot.d.ts.map +1 -0
  60. package/dist/core/_valibot.js +107 -0
  61. package/dist/core/_weak-id-registry.d.ts +76 -0
  62. package/dist/core/_weak-id-registry.d.ts.map +1 -0
  63. package/dist/core/_weak-id-registry.js +67 -0
  64. package/dist/core/constants.d.ts +5 -0
  65. package/dist/core/constants.d.ts.map +1 -0
  66. package/dist/core/constants.js +4 -0
  67. package/dist/core/data-map.types.d.ts +23 -0
  68. package/dist/core/data-map.types.d.ts.map +1 -0
  69. package/dist/core/data-map.types.js +1 -0
  70. package/dist/core/data-store.types.d.ts +22 -0
  71. package/dist/core/data-store.types.d.ts.map +1 -0
  72. package/dist/core/data-store.types.js +1 -0
  73. package/dist/core/deferred-promise.d.ts +203 -0
  74. package/dist/core/deferred-promise.d.ts.map +1 -0
  75. package/dist/core/deferred-promise.js +200 -0
  76. package/dist/core/errors.d.ts +303 -0
  77. package/dist/core/errors.d.ts.map +1 -0
  78. package/dist/core/errors.js +400 -0
  79. package/dist/core/expect-history-entry.d.ts +52 -0
  80. package/dist/core/expect-history-entry.d.ts.map +1 -0
  81. package/dist/core/expect-history-entry.js +38 -0
  82. package/dist/core/history-entry-id-schema.d.ts +17 -0
  83. package/dist/core/history-entry-id-schema.d.ts.map +1 -0
  84. package/dist/core/history-entry-id-schema.js +9 -0
  85. package/dist/core/history-entry-url-schema.d.ts +20 -0
  86. package/dist/core/history-entry-url-schema.d.ts.map +1 -0
  87. package/dist/core/history-entry-url-schema.js +16 -0
  88. package/dist/core/init-loaders.d.ts +37 -0
  89. package/dist/core/init-loaders.d.ts.map +1 -0
  90. package/dist/core/init-loaders.js +38 -0
  91. package/dist/core/match-routes.d.ts +31 -0
  92. package/dist/core/match-routes.d.ts.map +1 -0
  93. package/dist/core/match-routes.js +54 -0
  94. package/dist/core/readonly-form-data.types.d.ts +32 -0
  95. package/dist/core/readonly-form-data.types.d.ts.map +1 -0
  96. package/dist/core/readonly-form-data.types.js +1 -0
  97. package/dist/core/readonly-url.types.d.ts +135 -0
  98. package/dist/core/readonly-url.types.d.ts.map +1 -0
  99. package/dist/core/readonly-url.types.js +1 -0
  100. package/dist/core/redirect-response.d.ts +29 -0
  101. package/dist/core/redirect-response.d.ts.map +1 -0
  102. package/dist/core/redirect-response.js +17 -0
  103. package/dist/core/route-request.d.ts +52 -0
  104. package/dist/core/route-request.d.ts.map +1 -0
  105. package/dist/core/route-request.js +26 -0
  106. package/dist/core/route.types.d.ts +309 -0
  107. package/dist/core/route.types.d.ts.map +1 -0
  108. package/dist/core/route.types.js +1 -0
  109. package/dist/core/start-actions.d.ts +60 -0
  110. package/dist/core/start-actions.d.ts.map +1 -0
  111. package/dist/core/start-actions.js +186 -0
  112. package/dist/core/start-loaders.d.ts +69 -0
  113. package/dist/core/start-loaders.d.ts.map +1 -0
  114. package/dist/core/start-loaders.js +154 -0
  115. package/dist/core.d.ts +29 -0
  116. package/dist/core.d.ts.map +1 -0
  117. package/dist/core.js +13 -0
  118. package/dist/engines/engine.types.d.ts +190 -0
  119. package/dist/engines/engine.types.d.ts.map +1 -0
  120. package/dist/engines/engine.types.js +1 -0
  121. package/dist/engines/navigation-api-engine.d.ts +48 -0
  122. package/dist/engines/navigation-api-engine.d.ts.map +1 -0
  123. package/dist/engines/navigation-api-engine.js +332 -0
  124. package/dist/hooks/_use-route-context.d.ts +10 -0
  125. package/dist/hooks/_use-route-context.d.ts.map +1 -0
  126. package/dist/hooks/_use-route-context.js +17 -0
  127. package/dist/hooks/_use-router-context.d.ts +10 -0
  128. package/dist/hooks/_use-router-context.d.ts.map +1 -0
  129. package/dist/hooks/_use-router-context.js +18 -0
  130. package/dist/hooks/use-action-data.d.ts +23 -0
  131. package/dist/hooks/use-action-data.d.ts.map +1 -0
  132. package/dist/hooks/use-action-data.js +16 -0
  133. package/dist/hooks/use-loader-data.d.ts +11 -0
  134. package/dist/hooks/use-loader-data.d.ts.map +1 -0
  135. package/dist/hooks/use-loader-data.js +19 -0
  136. package/dist/hooks/use-navigate.d.ts +39 -0
  137. package/dist/hooks/use-navigate.d.ts.map +1 -0
  138. package/dist/hooks/use-navigate.js +26 -0
  139. package/dist/hooks/use-params.d.ts +8 -0
  140. package/dist/hooks/use-params.d.ts.map +1 -0
  141. package/dist/hooks/use-params.js +9 -0
  142. package/dist/hooks/use-pathname.d.ts +7 -0
  143. package/dist/hooks/use-pathname.d.ts.map +1 -0
  144. package/dist/hooks/use-pathname.js +9 -0
  145. package/dist/hooks/use-submit.d.ts +66 -0
  146. package/dist/hooks/use-submit.d.ts.map +1 -0
  147. package/dist/hooks/use-submit.js +35 -0
  148. package/dist/soseki.d.ts +42 -0
  149. package/dist/soseki.d.ts.map +1 -0
  150. package/dist/soseki.js +19 -0
  151. package/dist/utils/get-action-id.d.ts +8 -0
  152. package/dist/utils/get-action-id.d.ts.map +1 -0
  153. package/dist/utils/get-action-id.js +11 -0
  154. package/dist/utils/href.d.ts +11 -0
  155. package/dist/utils/href.d.ts.map +1 -0
  156. package/dist/utils/href.js +12 -0
  157. package/dist/utils/redirect.d.ts +11 -0
  158. package/dist/utils/redirect.d.ts.map +1 -0
  159. package/dist/utils/redirect.js +12 -0
  160. package/dist/utils/route-index.d.ts +41 -0
  161. package/dist/utils/route-index.d.ts.map +1 -0
  162. package/dist/utils/route-index.js +12 -0
  163. package/dist/utils/route-route.d.ts +62 -0
  164. package/dist/utils/route-route.d.ts.map +1 -0
  165. package/dist/utils/route-route.js +25 -0
  166. package/dist/utils/set-action-id.d.ts +9 -0
  167. package/dist/utils/set-action-id.d.ts.map +1 -0
  168. package/dist/utils/set-action-id.js +12 -0
  169. package/package.json +8 -1
  170. package/.config/_is-debug-mode.ts +0 -9
  171. package/.config/dependency-cruiser.cjs +0 -408
  172. package/.config/env.d.ts +0 -8
  173. package/.config/mise.toml +0 -28
  174. package/.config/navigation-api.d.ts +0 -18
  175. package/.config/tsconfig.build.json +0 -28
  176. package/.config/tsconfig.config.json +0 -21
  177. package/.config/tsconfig.test.json +0 -26
  178. package/.config/tsconfig.web.json +0 -26
  179. package/.config/vitest.client.ts +0 -30
  180. package/tests/core/_capture-stack-trace.test.ts +0 -46
  181. package/tests/core/_compare-route-paths.test.ts +0 -134
  182. package/tests/core/_encode-pathname.test.ts +0 -77
  183. package/tests/core/_is-error.test.ts +0 -108
  184. package/tests/core/_is-promise-like.test.ts +0 -100
  185. package/tests/core/_match-route-path.test.ts +0 -74
  186. package/tests/core/_process-routes.test.ts +0 -146
  187. package/tests/core/_singleton.test.ts +0 -102
  188. package/tests/core/_unreachable.test.ts +0 -38
  189. package/tests/core/_use-singleton.test.ts +0 -47
  190. package/tests/core/_weak-id-registry.test.ts +0 -137
  191. package/tests/core/deferred-promise.test.ts +0 -218
  192. package/tests/core/expect-history-entry.test.ts +0 -112
  193. package/tests/core/init-loaders.test.ts +0 -172
  194. package/tests/core/match-routes.test.ts +0 -178
  195. package/tests/core/redirect-response.test.ts +0 -36
  196. package/tests/core/route-request.test.ts +0 -93
  197. package/tests/core/start-actions.test.ts +0 -319
  198. package/tests/core/start-loaders.test.ts +0 -276
  199. package/tests/engines/navigation-api-engine.test.ts +0 -162
  200. package/tsconfig.json +0 -7
@@ -0,0 +1,19 @@
1
+ import * as React from "react";
2
+ import type { IAction } from "../core/route.types.js";
3
+ /**
4
+ * ActionId コンポーネントのプロパティーを定義する型です。
5
+ */
6
+ export type ActionIdProps = {
7
+ /**
8
+ * 実行対象となるアクション関数です。
9
+ */
10
+ action: IAction;
11
+ };
12
+ /**
13
+ * アクションに対応する識別子を隠しフィールドとしてレンダリングするコンポーネントです。
14
+ *
15
+ * アクション関数をレジストリーに登録し、発行された ID をフォームデータとして送信可能な状態にします。
16
+ */
17
+ declare const _default: React.NamedExoticComponent<ActionIdProps>;
18
+ export default _default;
19
+ //# sourceMappingURL=action-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-id.d.ts","sourceRoot":"","sources":["../../src/components/action-id.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGtD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;GAIG;;AACH,wBAaE"}
@@ -0,0 +1,14 @@
1
+ import * as React from "react";
2
+ import actionIdRegistry from "../core/_action-id-registry.js";
3
+ import { ACTION_ID_FORM_DATA_NAME } from "../core/constants.js";
4
+ import HiddenInput from "./hidden-input.jsx";
5
+ /**
6
+ * アクションに対応する識別子を隠しフィールドとしてレンダリングするコンポーネントです。
7
+ *
8
+ * アクション関数をレジストリーに登録し、発行された ID をフォームデータとして送信可能な状態にします。
9
+ */
10
+ export default /*#__PURE__*/ React.memo(function ActionId(props) {
11
+ const { action } = props;
12
+ const id = actionIdRegistry.set(action);
13
+ return (<HiddenInput name={ACTION_ID_FORM_DATA_NAME} value={id}/>);
14
+ }, (a, b) => a.action === b.action);
@@ -0,0 +1,17 @@
1
+ import type { RouteDefinition } from "../core/route.types.js";
2
+ /**
3
+ * BrowserRouter コンポーネントに渡されるプロパティーの型定義です。
4
+ */
5
+ export type BrowserRouterProps = {
6
+ /**
7
+ * アプリケーション全体のルート定義を格納した配列です。
8
+ */
9
+ routes: readonly RouteDefinition[];
10
+ };
11
+ /**
12
+ * ブラウザー標準の Navigation API を使用してルーティングを行うためのコンポーネントです。
13
+ *
14
+ * `NavigationApiEngine` のインスタンスをシングルトンとして保持し、ルーターの基盤を提供します。
15
+ */
16
+ export default function BrowserRouter(props: BrowserRouterProps): React.ReactElement;
17
+ //# sourceMappingURL=browser-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-router.d.ts","sourceRoot":"","sources":["../../src/components/browser-router.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAI9D;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;OAEG;IACH,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;CACpC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAUnF"}
@@ -0,0 +1,13 @@
1
+ import useSingleton from "../core/_use-singleton.js";
2
+ import NavigationApiEngine from "../engines/navigation-api-engine.js";
3
+ import Router from "./router.jsx";
4
+ /**
5
+ * ブラウザー標準の Navigation API を使用してルーティングを行うためのコンポーネントです。
6
+ *
7
+ * `NavigationApiEngine` のインスタンスをシングルトンとして保持し、ルーターの基盤を提供します。
8
+ */
9
+ export default function BrowserRouter(props) {
10
+ const { routes } = props;
11
+ const engine = useSingleton(() => new NavigationApiEngine());
12
+ return (<Router engine={engine} routes={routes}/>);
13
+ }
@@ -0,0 +1,20 @@
1
+ import * as React from "react";
2
+ /**
3
+ * 隠し入力フィールド(hidden input)のプロパティーを定義する型です。
4
+ */
5
+ export type HiddenInputProps = {
6
+ /**
7
+ * フォーム送信時に使用される要素の名前です。
8
+ */
9
+ name: string;
10
+ /**
11
+ * フォーム送信時に送信される値です。
12
+ */
13
+ value: string;
14
+ };
15
+ /**
16
+ * フォーム内で非表示の状態を保持するための隠し入力コンポーネントです。
17
+ */
18
+ declare const _default: React.NamedExoticComponent<HiddenInputProps>;
19
+ export default _default;
20
+ //# sourceMappingURL=hidden-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hidden-input.d.ts","sourceRoot":"","sources":["../../src/components/hidden-input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;;AACH,wBAkBE"}
@@ -0,0 +1,8 @@
1
+ import * as React from "react";
2
+ /**
3
+ * フォーム内で非表示の状態を保持するための隠し入力コンポーネントです。
4
+ */
5
+ export default /*#__PURE__*/ React.memo(function HiddenInput(props) {
6
+ const { name, value, } = props;
7
+ return (<input type="hidden" name={name} style={{ display: "none" }} value={value} hidden/>);
8
+ }, (a, b) => a.name === b.name && a.value === b.value);
@@ -0,0 +1,8 @@
1
+ import * as React from "react";
2
+ /**
3
+ * 現在のルート階層における子ルート(アウトレット)を描画するためのコンポーネントです。
4
+ *
5
+ * ネストされたルーティングにおいて、親ルートのコンポーネント内で子ルートの挿入位置を指定するために使用します。
6
+ */
7
+ export default function Outlet(): React.ReactElement | null;
8
+ //# sourceMappingURL=outlet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outlet.d.ts","sourceRoot":"","sources":["../../src/components/outlet.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,IAAI,KAAK,CAAC,YAAY,GAAG,IAAI,CAO1D"}
@@ -0,0 +1,15 @@
1
+ import * as React from "react";
2
+ import RouteContext from "../contexts/route-context.js";
3
+ import { RouteContextMissingError } from "../core/errors.js";
4
+ /**
5
+ * 現在のルート階層における子ルート(アウトレット)を描画するためのコンポーネントです。
6
+ *
7
+ * ネストされたルーティングにおいて、親ルートのコンポーネント内で子ルートの挿入位置を指定するために使用します。
8
+ */
9
+ export default function Outlet() {
10
+ const routeContext = React.use(RouteContext);
11
+ if (!routeContext) {
12
+ throw new RouteContextMissingError();
13
+ }
14
+ return routeContext.outlet;
15
+ }
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+ import type { RouteDefinition } from "../core/route.types.js";
3
+ import type { IEngine } from "../engines/engine.types.js";
4
+ /**
5
+ * Router コンポーネントに渡されるプロパティーの型定義です。
6
+ */
7
+ export type RouterProps = {
8
+ /**
9
+ * ルーティングのロジックを制御するエンジンインスタンスです。
10
+ */
11
+ engine: IEngine;
12
+ /**
13
+ * アプリケーションのルート定義の配列です。
14
+ */
15
+ routes: readonly RouteDefinition[];
16
+ };
17
+ /**
18
+ * ルーティング機能を提供するメインのコンポーネントです。
19
+ *
20
+ * エンジンの管理、状態の同期、およびルートのレンダリングを担います。
21
+ */
22
+ export default function Router(props: RouterProps): React.JSX.Element | null;
23
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/components/router.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,OAAO,KAAK,EAAoB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,KAAK,EAAE,OAAO,EAA2B,MAAM,4BAA4B,CAAC;AAmFnF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;CACpC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,KAAK,EAAE,WAAW,4BAuHhD"}
@@ -0,0 +1,128 @@
1
+ import * as React from "react";
2
+ import RouteContext from "../contexts/route-context.js";
3
+ import RouterContext from "../contexts/router-context.js";
4
+ import processRoutes from "../core/_process-routes.js";
5
+ /**
6
+ * 個別のルートコンポーネントをレンダリングし、ルートコンテキストを提供する内部コンポーネントです。
7
+ */
8
+ function ComponentRenderer(props) {
9
+ const { route: { path, index, params, urlPath, component: Component, }, outlet, } = props;
10
+ const context = {
11
+ path,
12
+ index,
13
+ params,
14
+ outlet,
15
+ urlPath,
16
+ };
17
+ return (<RouteContext value={context}>
18
+ {Component ? <Component /> : outlet}
19
+ </RouteContext>);
20
+ }
21
+ /**
22
+ * マッチしたルートの階層を順番にレンダリングする内部コンポーネントです。
23
+ */
24
+ function RouteRenderer(props) {
25
+ const { index = 0, routes, } = props;
26
+ const route = routes[index];
27
+ const outlet = index < routes.length - 1
28
+ ? <RouteRenderer routes={routes} index={index + 1}/>
29
+ : null;
30
+ return (<ComponentRenderer route={route} outlet={outlet}/>);
31
+ }
32
+ /**
33
+ * ルーティング機能を提供するメインのコンポーネントです。
34
+ *
35
+ * エンジンの管理、状態の同期、およびルートのレンダリングを担います。
36
+ */
37
+ export default function Router(props) {
38
+ const { engine, routes: routesProp, } = props;
39
+ const routerRef = React.useRef({});
40
+ const router = React.useMemo(() => {
41
+ const actionDataStore = new Map();
42
+ const loaderDataStore = new Map();
43
+ const subscribers = new Set();
44
+ const routes = processRoutes(routesProp);
45
+ let ac = null;
46
+ function getAbortSignal() {
47
+ return (ac || (ac = new AbortController())).signal;
48
+ }
49
+ const initialState = engine.init({
50
+ routes,
51
+ getSignal: getAbortSignal,
52
+ loaderDataStore,
53
+ });
54
+ let currentRoutes = initialState?.routes;
55
+ function updateRouter(newState) {
56
+ if (newState !== undefined) {
57
+ currentRoutes = newState?.routes;
58
+ }
59
+ if (newState) {
60
+ routerRef.current.currentEntry = newState.entry;
61
+ }
62
+ // 登録されているすべてのサブスクライバーに通知します。
63
+ subscribers.forEach(notify => notify());
64
+ }
65
+ function startRouterEngine() {
66
+ const stop = engine.start({
67
+ routes,
68
+ update: updateRouter,
69
+ getSignal: getAbortSignal,
70
+ actionDataStore,
71
+ loaderDataStore,
72
+ });
73
+ return function stopRouterEngine() {
74
+ try {
75
+ // エンジンの動作を停止します。
76
+ stop?.();
77
+ }
78
+ finally {
79
+ // 進行中のすべての非同期処理を中断します。
80
+ try {
81
+ ac?.abort();
82
+ }
83
+ catch {
84
+ }
85
+ // 中断後は次回の呼び出しに備えてコントローラーを破棄します。
86
+ ac = null;
87
+ }
88
+ };
89
+ }
90
+ Object.assign(routerRef.current, {
91
+ submit(args) {
92
+ return engine.submit(args);
93
+ },
94
+ navigate(args) {
95
+ return engine.navigate(args);
96
+ },
97
+ currentEntry: initialState?.entry,
98
+ actionDataStore,
99
+ loaderDataStore,
100
+ });
101
+ return {
102
+ start: startRouterEngine,
103
+ context: {
104
+ routerRef,
105
+ subscribe(cb) {
106
+ subscribers.add(cb);
107
+ return () => {
108
+ subscribers.delete(cb);
109
+ };
110
+ },
111
+ },
112
+ getRoutes() {
113
+ return currentRoutes;
114
+ },
115
+ };
116
+ }, [
117
+ engine,
118
+ routesProp,
119
+ ]);
120
+ React.useEffect(router.start, [router]);
121
+ const routes = React.useSyncExternalStore(router.context.subscribe, router.getRoutes);
122
+ if (!routes) {
123
+ return null;
124
+ }
125
+ return (<RouterContext value={router.context}>
126
+ <RouteRenderer routes={routes.toReversed()}/>
127
+ </RouterContext>);
128
+ }
@@ -0,0 +1,19 @@
1
+ import * as React from "react";
2
+ import type { MatchedRoute } from "../core/match-routes.js";
3
+ /**
4
+ * 各ルートのコンテキストで共有される値の型定義です。
5
+ */
6
+ export type RouteContextValue = Pick<MatchedRoute, "path" | "index" | "params" | "urlPath"> & {
7
+ /**
8
+ * 子ルートを描画するための React 要素です。
9
+ *
10
+ * 子ルートが存在しない場合は `null` となります。
11
+ */
12
+ readonly outlet: React.ReactElement | null;
13
+ };
14
+ /**
15
+ * 個別のルート情報やアウトレット(子ルートの挿入場所)を保持するための React コンテキストです。
16
+ */
17
+ declare const RouteContext: React.Context<RouteContextValue | null>;
18
+ export default RouteContext;
19
+ //# sourceMappingURL=route-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-context.d.ts","sourceRoot":"","sources":["../../src/contexts/route-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC,GAAG;IAC5F;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;CAC5C,CAAC;AAEF;;GAEG;AACH,QAAA,MAAM,YAAY,yCAAoE,CAAC;AAEvF,eAAe,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ import * as React from "react";
2
+ /**
3
+ * 個別のルート情報やアウトレット(子ルートの挿入場所)を保持するための React コンテキストです。
4
+ */
5
+ const RouteContext = /*#__PURE__*/ React.createContext(null);
6
+ export default RouteContext;
@@ -0,0 +1,46 @@
1
+ import * as React from "react";
2
+ import type { IReadonlyDataStore } from "../core/data-store.types.js";
3
+ import type { HistoryEntry } from "../core/expect-history-entry.js";
4
+ import type { IAction, ILoader } from "../core/route.types.js";
5
+ import type { NavigateArgs, SubmitArgs } from "../engines/engine.types.js";
6
+ export type RouterRef = Readonly<React.RefObject<{
7
+ /**
8
+ * フォームデータやクエリー パラメーターを送信します。
9
+ *
10
+ * @param args 送信内容と送信先を含む引数です。
11
+ */
12
+ readonly submit: (args: SubmitArgs) => void;
13
+ /**
14
+ * 指定されたパスへ遷移します。
15
+ *
16
+ * @param args 遷移先と遷移オプションを含む引数です。
17
+ */
18
+ readonly navigate: (args: NavigateArgs) => void;
19
+ /**
20
+ * 現在の履歴エントリー情報(ID、URL、インデックスなど)です。
21
+ */
22
+ readonly currentEntry: HistoryEntry;
23
+ /**
24
+ * 履歴 ID ごとに管理されているアクションデータのマップです。
25
+ */
26
+ readonly actionDataStore: IReadonlyDataStore<IAction>;
27
+ /**
28
+ * 履歴 ID ごとに管理されているローダーデータのマップです。
29
+ */
30
+ readonly loaderDataStore: IReadonlyDataStore<ILoader>;
31
+ }>>;
32
+ /**
33
+ * ルーターコンテキストで共有される値の型定義です。
34
+ */
35
+ export type RouterContextValue = {
36
+ readonly routerRef: RouterRef;
37
+ readonly subscribe: (onRouterChange: () => void) => () => void;
38
+ };
39
+ /**
40
+ * ルーターの状態や操作関数をコンポーネントツリー全体で共有するための React コンテキストです。
41
+ *
42
+ * 初期値は `null` であり、通常は Provider を介して値が提供されます。
43
+ */
44
+ declare const RouterContext: React.Context<RouterContextValue | null>;
45
+ export default RouterContext;
46
+ //# sourceMappingURL=router-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router-context.d.ts","sourceRoot":"","sources":["../../src/contexts/router-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE3E,MAAM,MAAM,SAAS,GAAG,QAAQ,CAC9B,KAAK,CAAC,SAAS,CAAC;IACd;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IAE5C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAEhD;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAEpC;;OAEG;IACH,QAAQ,CAAC,eAAe,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAEtD;;OAEG;IACH,QAAQ,CAAC,eAAe,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;CACvD,CAAC,CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,CAAC,cAAc,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;CAChE,CAAC;AAEF;;;;GAIG;AACH,QAAA,MAAM,aAAa,0CAAqE,CAAC;AAEzF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,8 @@
1
+ import * as React from "react";
2
+ /**
3
+ * ルーターの状態や操作関数をコンポーネントツリー全体で共有するための React コンテキストです。
4
+ *
5
+ * 初期値は `null` であり、通常は Provider を介して値が提供されます。
6
+ */
7
+ const RouterContext = /*#__PURE__*/ React.createContext(null);
8
+ export default RouterContext;
@@ -0,0 +1,10 @@
1
+ import WeakIdRegistry from "./_weak-id-registry.js";
2
+ import type { IAction } from "./route.types.js";
3
+ /**
4
+ * `IAction` 型のオブジェクトとその識別子を管理するための、弱い参照を用いたレジストリーです。
5
+ *
6
+ * ガベージコレクションを妨げずにアクションの識別子を保持するために使用されます。
7
+ */
8
+ declare const actionIdRegistry: WeakIdRegistry<IAction<string, unknown>>;
9
+ export default actionIdRegistry;
10
+ //# sourceMappingURL=_action-id-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_action-id-registry.d.ts","sourceRoot":"","sources":["../../src/core/_action-id-registry.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;;;GAIG;AACH,QAAA,MAAM,gBAAgB,0CAAgC,CAAC;AAEvD,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import WeakIdRegistry from "./_weak-id-registry.js";
2
+ /**
3
+ * `IAction` 型のオブジェクトとその識別子を管理するための、弱い参照を用いたレジストリーです。
4
+ *
5
+ * ガベージコレクションを妨げずにアクションの識別子を保持するために使用されます。
6
+ */
7
+ const actionIdRegistry = new WeakIdRegistry();
8
+ export default actionIdRegistry;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * オブジェクトにスタックトレースをキャプチャーします。
3
+ *
4
+ * @param targetObject スタックトレースのプロパティーを追加する対象のオブジェクトです。
5
+ * @param constructorOpt スタックトレースの開始地点としてマークする関数です。
6
+ */
7
+ export default function captureStackTrace(targetObject: object, constructorOpt: Function): void;
8
+ //# sourceMappingURL=_capture-stack-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_capture-stack-trace.d.ts","sourceRoot":"","sources":["../../src/core/_capture-stack-trace.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,GAAG,IAAI,CAK9F"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * オブジェクトにスタックトレースをキャプチャーします。
3
+ *
4
+ * @param targetObject スタックトレースのプロパティーを追加する対象のオブジェクトです。
5
+ * @param constructorOpt スタックトレースの開始地点としてマークする関数です。
6
+ */
7
+ export default function captureStackTrace(targetObject, constructorOpt) {
8
+ // 実行環境(V8 エンジンなど)が Error.captureStackTrace をサポートしているか確認します。
9
+ if ("captureStackTrace" in Error && typeof Error.captureStackTrace === "function") {
10
+ Error.captureStackTrace(targetObject, constructorOpt);
11
+ }
12
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 2 つのパスを比較し、ルーティングの優先順位に基づいたソート順を決定します。
3
+ *
4
+ * より具体的で深いパスが前方に配置されるように比較を行います。
5
+ *
6
+ * @param pathA 比較対象のパス A です。
7
+ * @param pathB 比較対象のパス B です。
8
+ * @returns 比較結果を示す数値です(負数は pathA が優先、正数は pathB が優先)。
9
+ */
10
+ export default function compareRoutePaths(pathA: string, pathB: string): number;
11
+ //# sourceMappingURL=_compare-route-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_compare-route-paths.d.ts","sourceRoot":"","sources":["../../src/core/_compare-route-paths.ts"],"names":[],"mappings":"AAiDA;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CA+B9E"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * セグメントの種類に応じたスコア定数です。
3
+ *
4
+ * 数値が大きいほど優先順位(具体性)が高いです。
5
+ */
6
+ const SCORE = {
7
+ /**
8
+ * 静的なパスセグメントのスコアです。
9
+ */
10
+ STATIC: 4,
11
+ /**
12
+ * 必須のパラメーターセグメントのスコアです。
13
+ */
14
+ PARAMETER: 3,
15
+ /**
16
+ * 任意のパラメーターセグメントのスコアです。
17
+ */
18
+ OPTIONAL_PARAM: 2,
19
+ /**
20
+ * ワイルドカードセグメントのスコアです。
21
+ */
22
+ WILDCARD: 1,
23
+ };
24
+ /**
25
+ * 指定されたパスセグメントの文字列から、その種類に応じたスコアを計算します。
26
+ *
27
+ * @param s 解析対象のパスセグメント文字列です。
28
+ * @returns セグメントの種類に基づいた数値スコアを返します。
29
+ */
30
+ function getSegmentScore(s) {
31
+ if (s.includes("*")) {
32
+ return SCORE.WILDCARD;
33
+ }
34
+ if (s.startsWith(":")) {
35
+ if (s.endsWith("?")) {
36
+ return SCORE.OPTIONAL_PARAM;
37
+ }
38
+ else {
39
+ return SCORE.PARAMETER;
40
+ }
41
+ }
42
+ return SCORE.STATIC;
43
+ }
44
+ /**
45
+ * 2 つのパスを比較し、ルーティングの優先順位に基づいたソート順を決定します。
46
+ *
47
+ * より具体的で深いパスが前方に配置されるように比較を行います。
48
+ *
49
+ * @param pathA 比較対象のパス A です。
50
+ * @param pathB 比較対象のパス B です。
51
+ * @returns 比較結果を示す数値です(負数は pathA が優先、正数は pathB が優先)。
52
+ */
53
+ export default function compareRoutePaths(pathA, pathB) {
54
+ const partsA = pathA.split("/").filter(Boolean);
55
+ const partsB = pathB.split("/").filter(Boolean);
56
+ const length = Math.max(partsA.length, partsB.length);
57
+ for (let i = 0; i < length; i++) {
58
+ const a = partsA[i];
59
+ // パス A のセグメントが先に終了した場合は、パス B を優先します。
60
+ if (a === undefined) {
61
+ return 1;
62
+ }
63
+ const b = partsB[i];
64
+ // パス B のセグメントが先に終了した場合は、パス A を優先します。
65
+ if (b === undefined) {
66
+ return -1;
67
+ }
68
+ const scoreA = getSegmentScore(a);
69
+ const scoreB = getSegmentScore(b);
70
+ // スコアが異なる場合は、スコアが高い方を優先します。
71
+ if (scoreA !== scoreB) {
72
+ return scoreB - scoreA;
73
+ }
74
+ // スコアが同じ場合は、文字列の辞書順で比較します。
75
+ if (a !== b) {
76
+ return a.localeCompare(b);
77
+ }
78
+ }
79
+ return 0;
80
+ }
@@ -0,0 +1,9 @@
1
+ import type { ReadonlyFormData } from "./readonly-form-data.types.js";
2
+ /**
3
+ * ReadonlyFormData の内容から、一時的な HTMLFormElement を生成します。
4
+ *
5
+ * @param formData フォーム要素に変換する元のフォームデータです。
6
+ * @returns 生成された HTMLFormElement を返します。
7
+ */
8
+ export default function createHtmlFormElementFormFormData(formData: ReadonlyFormData): HTMLFormElement;
9
+ //# sourceMappingURL=_create-html-form-element-form-form-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_create-html-form-element-form-form-data.d.ts","sourceRoot":"","sources":["../../src/core/_create-html-form-element-form-form-data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,iCAAiC,CACvD,QAAQ,EAAE,gBAAgB,GACzB,eAAe,CAqBjB"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * ReadonlyFormData の内容から、一時的な HTMLFormElement を生成します。
3
+ *
4
+ * @param formData フォーム要素に変換する元のフォームデータです。
5
+ * @returns 生成された HTMLFormElement を返します。
6
+ */
7
+ export default function createHtmlFormElementFormFormData(formData) {
8
+ const form = document.createElement("form");
9
+ form.style.display = "none";
10
+ formData.forEach((value, name) => {
11
+ const input = document.createElement("input");
12
+ if (value instanceof File) {
13
+ input.type = "file";
14
+ input.name = name;
15
+ const dataTransfer = new DataTransfer();
16
+ dataTransfer.items.add(value);
17
+ input.files = dataTransfer.files;
18
+ }
19
+ else {
20
+ input.type = "hidden";
21
+ input.name = name;
22
+ input.value = value;
23
+ }
24
+ form.appendChild(input);
25
+ });
26
+ return form;
27
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 与えられたパス名を URL エンコードし、正規化された形式で返します。
3
+ *
4
+ * エンコードの必要がある部分のみをエンコードします。
5
+ *
6
+ * @param pathname エンコード対象となるパス名の文字列です。
7
+ * @returns 正規化およびエンコードされたパス名の文字列です。
8
+ */
9
+ export default function encodePathname(pathname: string): string;
10
+ //# sourceMappingURL=_encode-pathname.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_encode-pathname.d.ts","sourceRoot":"","sources":["../../src/core/_encode-pathname.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG/D"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 連続するスラッシュ(/)にマッチする正規表現です。
3
+ */
4
+ const MULTI_SLASH = /\/\/+/gu;
5
+ /**
6
+ * 与えられたパス名を URL エンコードし、正規化された形式で返します。
7
+ *
8
+ * エンコードの必要がある部分のみをエンコードします。
9
+ *
10
+ * @param pathname エンコード対象となるパス名の文字列です。
11
+ * @returns 正規化およびエンコードされたパス名の文字列です。
12
+ */
13
+ export default function encodePathname(pathname) {
14
+ const u = new URL("x://y" + ("/" + pathname).replace(MULTI_SLASH, "/"));
15
+ return u.pathname;
16
+ }
@@ -0,0 +1,3 @@
1
+ declare const _default: (error: unknown) => error is Error;
2
+ export default _default;
3
+ //# sourceMappingURL=_is-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_is-error.d.ts","sourceRoot":"","sources":["../../src/core/_is-error.ts"],"names":[],"mappings":";AAeA,wBAAmD"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * エラーオブジェクトのようなオブジェクトかどうか判定します。
3
+ *
4
+ * @param e 判定する値です。
5
+ * @returns 判定結果です。
6
+ */
7
+ function isError(e) {
8
+ return e instanceof Error || (e !== null
9
+ && typeof e === "object"
10
+ && ("name" in e && typeof e.name === "string")
11
+ && ("message" in e && typeof e.message === "string"));
12
+ }
13
+ export default globalThis.Error.isError || isError;