soseki 0.0.5 → 0.0.6
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/LICENSE +21 -0
- package/dist/src/components/browser-router.d.ts +19 -0
- package/dist/src/components/browser-router.d.ts.map +1 -0
- package/dist/src/components/browser-router.jsx +15 -0
- package/dist/src/components/outlet.d.ts +8 -0
- package/dist/src/components/outlet.d.ts.map +1 -0
- package/dist/src/components/outlet.jsx +15 -0
- package/dist/src/components/router.d.ts +21 -0
- package/dist/src/components/router.d.ts.map +1 -0
- package/dist/src/components/router.jsx +138 -0
- package/dist/src/contexts/route-context.d.ts +19 -0
- package/dist/src/contexts/route-context.d.ts.map +1 -0
- package/dist/src/contexts/route-context.js +6 -0
- package/dist/src/contexts/router-context.d.ts +55 -0
- package/dist/src/contexts/router-context.d.ts.map +1 -0
- package/dist/src/contexts/router-context.js +8 -0
- package/dist/src/core/_compare-route-paths.d.ts +11 -0
- package/dist/src/core/_compare-route-paths.d.ts.map +1 -0
- package/dist/src/core/_compare-route-paths.js +92 -0
- package/dist/src/core/_match-route-path.d.ts +22 -0
- package/dist/src/core/_match-route-path.d.ts.map +1 -0
- package/dist/src/core/_match-route-path.js +26 -0
- package/dist/src/core/_process-routes.d.ts +14 -0
- package/dist/src/core/_process-routes.d.ts.map +1 -0
- package/dist/src/core/_process-routes.js +45 -0
- package/dist/src/core/_singleton.d.ts +12 -0
- package/dist/src/core/_singleton.d.ts.map +1 -0
- package/dist/src/core/_singleton.js +18 -0
- package/dist/src/core/_unreachable.d.ts +16 -0
- package/dist/src/core/_unreachable.d.ts.map +1 -0
- package/dist/src/core/_unreachable.js +8 -0
- package/dist/src/core/_valibot.d.ts +25 -0
- package/dist/src/core/_valibot.d.ts.map +1 -0
- package/dist/src/core/_valibot.js +30 -0
- package/dist/src/core/errors.d.ts +182 -0
- package/dist/src/core/errors.d.ts.map +1 -0
- package/dist/src/core/errors.js +166 -0
- package/dist/src/core/expect-history-entry.d.ts +59 -0
- package/dist/src/core/expect-history-entry.d.ts.map +1 -0
- package/dist/src/core/expect-history-entry.js +42 -0
- package/dist/src/core/form-data-to-html-form-element.d.ts +11 -0
- package/dist/src/core/form-data-to-html-form-element.d.ts.map +1 -0
- package/dist/src/core/form-data-to-html-form-element.js +31 -0
- package/dist/src/core/history-entry-id-schema.d.ts +17 -0
- package/dist/src/core/history-entry-id-schema.d.ts.map +1 -0
- package/dist/src/core/history-entry-id-schema.js +9 -0
- package/dist/src/core/history-entry-url-schema.d.ts +18 -0
- package/dist/src/core/history-entry-url-schema.d.ts.map +1 -0
- package/dist/src/core/history-entry-url-schema.js +20 -0
- package/dist/src/core/init-loaders.d.ts +28 -0
- package/dist/src/core/init-loaders.d.ts.map +1 -0
- package/dist/src/core/init-loaders.js +30 -0
- package/dist/src/core/match-routes.d.ts +28 -0
- package/dist/src/core/match-routes.d.ts.map +1 -0
- package/dist/src/core/match-routes.js +31 -0
- package/dist/src/core/readonly-form-data.types.d.ts +74 -0
- package/dist/src/core/readonly-form-data.types.d.ts.map +1 -0
- package/dist/src/core/readonly-url.types.d.ts +164 -0
- package/dist/src/core/readonly-url.types.d.ts.map +1 -0
- package/dist/src/core/redirect-response.d.ts +37 -0
- package/dist/src/core/redirect-response.d.ts.map +1 -0
- package/dist/src/core/redirect-response.js +19 -0
- package/dist/src/core/route-path.d.ts +57 -0
- package/dist/src/core/route-path.d.ts.map +1 -0
- package/dist/src/core/route-path.js +93 -0
- package/dist/src/core/route-request.d.ts +149 -0
- package/dist/src/core/route-request.d.ts.map +1 -0
- package/dist/src/core/route-request.js +41 -0
- package/dist/src/core/route.types.d.ts +296 -0
- package/dist/src/core/route.types.d.ts.map +1 -0
- package/dist/src/core/start-action.d.ts +53 -0
- package/dist/src/core/start-action.d.ts.map +1 -0
- package/dist/src/core/start-action.js +95 -0
- package/dist/src/core/start-loaders.d.ts +63 -0
- package/dist/src/core/start-loaders.d.ts.map +1 -0
- package/dist/src/core/start-loaders.js +138 -0
- package/dist/{core.d.ts → src/core.d.ts} +7 -11
- package/dist/src/core.d.ts.map +1 -0
- package/dist/{core.js → src/core.js} +2 -4
- package/dist/src/engines/engine.types.d.ts +216 -0
- package/dist/src/engines/engine.types.d.ts.map +1 -0
- package/dist/src/engines/navigation-api-engine.d.ts +50 -0
- package/dist/src/engines/navigation-api-engine.d.ts.map +1 -0
- package/dist/src/engines/navigation-api-engine.js +411 -0
- package/dist/src/engines.d.ts +4 -0
- package/dist/src/engines.d.ts.map +1 -0
- package/dist/src/engines.js +1 -0
- package/dist/src/hooks/_use-singleton.d.ts +11 -0
- package/dist/src/hooks/_use-singleton.d.ts.map +1 -0
- package/dist/src/hooks/_use-singleton.js +26 -0
- package/dist/src/hooks/use-action-data.d.ts +17 -0
- package/dist/src/hooks/use-action-data.d.ts.map +1 -0
- package/dist/src/hooks/use-action-data.js +16 -0
- package/dist/src/hooks/use-form-action.d.ts +7 -0
- package/dist/src/hooks/use-form-action.d.ts.map +1 -0
- package/dist/src/hooks/use-form-action.js +9 -0
- package/dist/src/hooks/use-loader-data.d.ts +9 -0
- package/dist/src/hooks/use-loader-data.d.ts.map +1 -0
- package/dist/src/hooks/use-loader-data.js +20 -0
- package/dist/src/hooks/use-navigate.d.ts +53 -0
- package/dist/src/hooks/use-navigate.d.ts.map +1 -0
- package/dist/src/hooks/use-navigate.js +43 -0
- package/dist/{hooks → src/hooks}/use-params.d.ts +2 -2
- package/dist/src/hooks/use-params.d.ts.map +1 -0
- package/dist/{hooks → src/hooks}/use-params.js +1 -1
- package/dist/src/hooks/use-route-context.d.ts +10 -0
- package/dist/src/hooks/use-route-context.d.ts.map +1 -0
- package/dist/src/hooks/use-route-context.js +17 -0
- package/dist/src/hooks/use-router-context.d.ts +12 -0
- package/dist/src/hooks/use-router-context.d.ts.map +1 -0
- package/dist/src/hooks/use-router-context.js +20 -0
- package/dist/src/hooks/use-submit.d.ts +59 -0
- package/dist/src/hooks/use-submit.d.ts.map +1 -0
- package/dist/src/hooks/use-submit.js +38 -0
- package/dist/src/soseki.d.ts +31 -0
- package/dist/src/soseki.d.ts.map +1 -0
- package/dist/src/soseki.js +12 -0
- package/dist/src/utils/redirect.d.ts +11 -0
- package/dist/src/utils/redirect.d.ts.map +1 -0
- package/dist/src/utils/redirect.js +12 -0
- package/package.json +47 -40
- package/src/components/browser-router.tsx +8 -11
- package/src/components/outlet.tsx +3 -2
- package/src/components/router.tsx +139 -145
- package/src/contexts/route-context.ts +6 -5
- package/src/contexts/router-context.ts +36 -19
- package/src/core/_compare-route-paths.ts +48 -34
- package/src/core/_match-route-path.ts +21 -15
- package/src/core/_process-routes.ts +44 -46
- package/src/core/_singleton.ts +13 -38
- package/src/core/_unreachable.ts +12 -7
- package/src/core/_valibot.ts +19 -116
- package/src/core/errors.ts +150 -495
- package/src/core/expect-history-entry.ts +40 -41
- package/src/core/form-data-to-html-form-element.ts +37 -0
- package/src/core/history-entry-id-schema.ts +6 -11
- package/src/core/history-entry-url-schema.ts +25 -18
- package/src/core/init-loaders.ts +35 -57
- package/src/core/match-routes.ts +33 -65
- package/src/core/readonly-form-data.types.ts +48 -28
- package/src/core/readonly-url.types.ts +57 -28
- package/src/core/redirect-response.ts +26 -15
- package/src/core/route-path.ts +114 -0
- package/src/core/route-request.ts +144 -32
- package/src/core/route.types.ts +250 -226
- package/src/core/start-action.ts +164 -0
- package/src/core/start-loaders.ts +190 -212
- package/src/core.ts +8 -15
- package/src/engines/engine.types.ts +204 -166
- package/src/engines/navigation-api-engine.ts +332 -233
- package/src/engines.ts +4 -0
- package/src/hooks/_use-singleton.ts +30 -0
- package/src/hooks/use-action-data.ts +21 -26
- package/src/hooks/use-form-action.ts +4 -5
- package/src/hooks/use-loader-data.ts +16 -18
- package/src/hooks/use-navigate.ts +69 -28
- package/src/hooks/use-params.ts +4 -4
- package/src/hooks/use-route-context.ts +20 -0
- package/src/hooks/use-router-context.ts +25 -0
- package/src/hooks/use-submit.ts +48 -53
- package/src/soseki.ts +27 -34
- package/src/utils/redirect.ts +5 -5
- package/dist/components/action-id.d.ts +0 -19
- package/dist/components/action-id.d.ts.map +0 -1
- package/dist/components/action-id.jsx +0 -14
- package/dist/components/browser-router.d.ts +0 -17
- package/dist/components/browser-router.d.ts.map +0 -1
- package/dist/components/browser-router.jsx +0 -13
- package/dist/components/hidden-input.d.ts +0 -20
- package/dist/components/hidden-input.d.ts.map +0 -1
- package/dist/components/hidden-input.jsx +0 -8
- package/dist/components/outlet.d.ts +0 -8
- package/dist/components/outlet.d.ts.map +0 -1
- package/dist/components/outlet.jsx +0 -15
- package/dist/components/router.d.ts +0 -23
- package/dist/components/router.d.ts.map +0 -1
- package/dist/components/router.jsx +0 -128
- package/dist/contexts/route-context.d.ts +0 -19
- package/dist/contexts/route-context.d.ts.map +0 -1
- package/dist/contexts/route-context.js +0 -6
- package/dist/contexts/router-context.d.ts +0 -46
- package/dist/contexts/router-context.d.ts.map +0 -1
- package/dist/contexts/router-context.js +0 -8
- package/dist/core/_action-id-registry.d.ts +0 -10
- package/dist/core/_action-id-registry.d.ts.map +0 -1
- package/dist/core/_action-id-registry.js +0 -8
- package/dist/core/_capture-stack-trace.d.ts +0 -8
- package/dist/core/_capture-stack-trace.d.ts.map +0 -1
- package/dist/core/_capture-stack-trace.js +0 -12
- package/dist/core/_compare-route-paths.d.ts +0 -11
- package/dist/core/_compare-route-paths.d.ts.map +0 -1
- package/dist/core/_compare-route-paths.js +0 -80
- package/dist/core/_create-html-form-element-form-form-data.d.ts +0 -9
- package/dist/core/_create-html-form-element-form-form-data.d.ts.map +0 -1
- package/dist/core/_create-html-form-element-form-form-data.js +0 -27
- package/dist/core/_encode-pathname.d.ts +0 -10
- package/dist/core/_encode-pathname.d.ts.map +0 -1
- package/dist/core/_encode-pathname.js +0 -16
- package/dist/core/_is-error.d.ts +0 -3
- package/dist/core/_is-error.d.ts.map +0 -1
- package/dist/core/_is-error.js +0 -13
- package/dist/core/_is-promise-like.d.ts +0 -8
- package/dist/core/_is-promise-like.d.ts.map +0 -1
- package/dist/core/_is-promise-like.js +0 -12
- package/dist/core/_match-route-path.d.ts +0 -19
- package/dist/core/_match-route-path.d.ts.map +0 -1
- package/dist/core/_match-route-path.js +0 -22
- package/dist/core/_process-routes.d.ts +0 -9
- package/dist/core/_process-routes.d.ts.map +0 -1
- package/dist/core/_process-routes.js +0 -47
- package/dist/core/_singleton.d.ts +0 -18
- package/dist/core/_singleton.d.ts.map +0 -1
- package/dist/core/_singleton.js +0 -37
- package/dist/core/_unreachable.d.ts +0 -12
- package/dist/core/_unreachable.d.ts.map +0 -1
- package/dist/core/_unreachable.js +0 -8
- package/dist/core/_use-singleton.d.ts +0 -11
- package/dist/core/_use-singleton.d.ts.map +0 -1
- package/dist/core/_use-singleton.js +0 -21
- package/dist/core/_valibot.d.ts +0 -52
- package/dist/core/_valibot.d.ts.map +0 -1
- package/dist/core/_valibot.js +0 -107
- package/dist/core/_weak-id-registry.d.ts +0 -76
- package/dist/core/_weak-id-registry.d.ts.map +0 -1
- package/dist/core/_weak-id-registry.js +0 -67
- package/dist/core/constants.d.ts +0 -5
- package/dist/core/constants.d.ts.map +0 -1
- package/dist/core/constants.js +0 -4
- package/dist/core/data-map.types.d.ts +0 -23
- package/dist/core/data-map.types.d.ts.map +0 -1
- package/dist/core/data-map.types.js +0 -1
- package/dist/core/data-store.types.d.ts +0 -22
- package/dist/core/data-store.types.d.ts.map +0 -1
- package/dist/core/data-store.types.js +0 -1
- package/dist/core/deferred-promise.d.ts +0 -203
- package/dist/core/deferred-promise.d.ts.map +0 -1
- package/dist/core/deferred-promise.js +0 -200
- package/dist/core/errors.d.ts +0 -303
- package/dist/core/errors.d.ts.map +0 -1
- package/dist/core/errors.js +0 -400
- package/dist/core/expect-history-entry.d.ts +0 -52
- package/dist/core/expect-history-entry.d.ts.map +0 -1
- package/dist/core/expect-history-entry.js +0 -38
- package/dist/core/history-entry-id-schema.d.ts +0 -17
- package/dist/core/history-entry-id-schema.d.ts.map +0 -1
- package/dist/core/history-entry-id-schema.js +0 -9
- package/dist/core/history-entry-url-schema.d.ts +0 -20
- package/dist/core/history-entry-url-schema.d.ts.map +0 -1
- package/dist/core/history-entry-url-schema.js +0 -16
- package/dist/core/init-loaders.d.ts +0 -37
- package/dist/core/init-loaders.d.ts.map +0 -1
- package/dist/core/init-loaders.js +0 -38
- package/dist/core/match-routes.d.ts +0 -31
- package/dist/core/match-routes.d.ts.map +0 -1
- package/dist/core/match-routes.js +0 -54
- package/dist/core/readonly-form-data.types.d.ts +0 -32
- package/dist/core/readonly-form-data.types.d.ts.map +0 -1
- package/dist/core/readonly-url.types.d.ts +0 -135
- package/dist/core/readonly-url.types.d.ts.map +0 -1
- package/dist/core/redirect-response.d.ts +0 -29
- package/dist/core/redirect-response.d.ts.map +0 -1
- package/dist/core/redirect-response.js +0 -17
- package/dist/core/route-request.d.ts +0 -52
- package/dist/core/route-request.d.ts.map +0 -1
- package/dist/core/route-request.js +0 -26
- package/dist/core/route.types.d.ts +0 -309
- package/dist/core/route.types.d.ts.map +0 -1
- package/dist/core/start-actions.d.ts +0 -60
- package/dist/core/start-actions.d.ts.map +0 -1
- package/dist/core/start-actions.js +0 -186
- package/dist/core/start-loaders.d.ts +0 -69
- package/dist/core/start-loaders.d.ts.map +0 -1
- package/dist/core/start-loaders.js +0 -154
- package/dist/core.d.ts.map +0 -1
- package/dist/engines/engine.types.d.ts +0 -190
- package/dist/engines/engine.types.d.ts.map +0 -1
- package/dist/engines/navigation-api-engine.d.ts +0 -48
- package/dist/engines/navigation-api-engine.d.ts.map +0 -1
- package/dist/engines/navigation-api-engine.js +0 -332
- package/dist/hooks/_use-route-context.d.ts +0 -10
- package/dist/hooks/_use-route-context.d.ts.map +0 -1
- package/dist/hooks/_use-route-context.js +0 -17
- package/dist/hooks/_use-router-context.d.ts +0 -10
- package/dist/hooks/_use-router-context.d.ts.map +0 -1
- package/dist/hooks/_use-router-context.js +0 -18
- package/dist/hooks/use-action-data.d.ts +0 -23
- package/dist/hooks/use-action-data.d.ts.map +0 -1
- package/dist/hooks/use-action-data.js +0 -16
- package/dist/hooks/use-form-action.d.ts +0 -7
- package/dist/hooks/use-form-action.d.ts.map +0 -1
- package/dist/hooks/use-form-action.js +0 -10
- package/dist/hooks/use-loader-data.d.ts +0 -11
- package/dist/hooks/use-loader-data.d.ts.map +0 -1
- package/dist/hooks/use-loader-data.js +0 -19
- package/dist/hooks/use-navigate.d.ts +0 -39
- package/dist/hooks/use-navigate.d.ts.map +0 -1
- package/dist/hooks/use-navigate.js +0 -26
- package/dist/hooks/use-params.d.ts.map +0 -1
- package/dist/hooks/use-pathname.d.ts +0 -7
- package/dist/hooks/use-pathname.d.ts.map +0 -1
- package/dist/hooks/use-pathname.js +0 -9
- package/dist/hooks/use-submit.d.ts +0 -66
- package/dist/hooks/use-submit.d.ts.map +0 -1
- package/dist/hooks/use-submit.js +0 -35
- package/dist/soseki.d.ts +0 -42
- package/dist/soseki.d.ts.map +0 -1
- package/dist/soseki.js +0 -19
- package/dist/utils/get-action-id.d.ts +0 -8
- package/dist/utils/get-action-id.d.ts.map +0 -1
- package/dist/utils/get-action-id.js +0 -11
- package/dist/utils/href.d.ts +0 -11
- package/dist/utils/href.d.ts.map +0 -1
- package/dist/utils/href.js +0 -12
- package/dist/utils/redirect.d.ts +0 -11
- package/dist/utils/redirect.d.ts.map +0 -1
- package/dist/utils/redirect.js +0 -12
- package/dist/utils/route-index.d.ts +0 -41
- package/dist/utils/route-index.d.ts.map +0 -1
- package/dist/utils/route-index.js +0 -12
- package/dist/utils/route-route.d.ts +0 -62
- package/dist/utils/route-route.d.ts.map +0 -1
- package/dist/utils/route-route.js +0 -25
- package/dist/utils/set-action-id.d.ts +0 -9
- package/dist/utils/set-action-id.d.ts.map +0 -1
- package/dist/utils/set-action-id.js +0 -12
- package/src/components/action-id.tsx +0 -35
- package/src/components/hidden-input.tsx +0 -39
- package/src/core/_action-id-registry.ts +0 -11
- package/src/core/_capture-stack-trace.ts +0 -12
- package/src/core/_create-html-form-element-form-form-data.ts +0 -32
- package/src/core/_encode-pathname.ts +0 -17
- package/src/core/_is-error.ts +0 -16
- package/src/core/_is-promise-like.ts +0 -14
- package/src/core/_use-singleton.ts +0 -24
- package/src/core/_weak-id-registry.ts +0 -125
- package/src/core/constants.ts +0 -4
- package/src/core/data-map.types.ts +0 -28
- package/src/core/data-store.types.ts +0 -25
- package/src/core/deferred-promise.ts +0 -408
- package/src/core/start-actions.ts +0 -274
- package/src/hooks/_use-route-context.ts +0 -19
- package/src/hooks/_use-router-context.ts +0 -25
- package/src/hooks/use-pathname.ts +0 -10
- package/src/utils/get-action-id.ts +0 -12
- package/src/utils/href.ts +0 -17
- package/src/utils/route-index.ts +0 -70
- package/src/utils/route-route.ts +0 -111
- package/src/utils/set-action-id.ts +0 -14
- /package/dist/{core → src/core}/readonly-form-data.types.js +0 -0
- /package/dist/{core → src/core}/readonly-url.types.js +0 -0
- /package/dist/{core → src/core}/route.types.js +0 -0
- /package/dist/{engines → src/engines}/engine.types.js +0 -0
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 初期化が一度だけ実行されることを保証するための特殊なシンボルです。`ref.current` の初期値として使用され、値がまだ設定されていない状態を示します。
|
|
5
|
-
*/
|
|
6
|
-
const NONE = Symbol.for("soseki/none");
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* コンポーネントのライフサイクルを通じて、初期化関数 (`fn`) を一度だけ実行し、その結果を保持し続けるカスタムフックです。
|
|
10
|
-
*
|
|
11
|
-
* `useMemo` と異なり、依存配列が存在しないため、再レンダリングやフックの呼び出し順序に関係なく、最初のレンダリング時にのみ初期化が実行されることを保証します。
|
|
12
|
-
*
|
|
13
|
-
* @template T 初期化関数が返す値の型です。
|
|
14
|
-
* @param fn 一度だけ実行される初期化関数です。引数は取りません。
|
|
15
|
-
* @returns 初期化関数が返した、シングルトンとして保持される値です。
|
|
16
|
-
*/
|
|
17
|
-
export default function useSingleton<T>(fn: () => T): T {
|
|
18
|
-
const ref = React.useRef<T | typeof NONE>(NONE);
|
|
19
|
-
if (ref.current === NONE) {
|
|
20
|
-
ref.current = fn();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return ref.current;
|
|
24
|
-
}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import unreachable from "./_unreachable.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 識別子(ID)の型エイリアスです。
|
|
5
|
-
*
|
|
6
|
-
* ID は増分カウンターを36進数エンコードしたものです。
|
|
7
|
-
*/
|
|
8
|
-
export type Id = string;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* `WeakIdRegistry` クラスは、オブジェクトに対する ID の割り当てと管理を行います。
|
|
12
|
-
*
|
|
13
|
-
* オブジェクト自体は `WeakMap` と `WeakRef` を使用して保持されるため、参照がなくなったオブジェクトはガベージコレクション(GC)の対象になります。
|
|
14
|
-
*
|
|
15
|
-
* @template TValue ID を割り当てる対象となるオブジェクトの型です。`object` 型のサブタイプである必要があります。
|
|
16
|
-
*/
|
|
17
|
-
export default class WeakIdRegistry<TValue extends object> {
|
|
18
|
-
/**
|
|
19
|
-
* ID 生成のための内部カウンターです。BigInt を使用することで、非常に大きな数値まで ID を生成できます。
|
|
20
|
-
*/
|
|
21
|
-
private counter: bigint;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* オブジェクト (関数を含む) から、割り当てられた ID へのマッピングを保持する `WeakMap` です。
|
|
25
|
-
*
|
|
26
|
-
* `WeakMap` を使用することで、キーであるオブジェクトが他の場所から参照されなくなった場合、このマッピングも自動的に破棄され、GC が可能になります。
|
|
27
|
-
*/
|
|
28
|
-
private readonly v2id: WeakMap<TValue, Id>;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* ID から、対応するオブジェクトへの弱い参照 (`WeakRef`) のマッピングを保持する `Map` です。
|
|
32
|
-
*
|
|
33
|
-
* オブジェクト自体が GC される可能性があるため、`WeakRef` を使用しています。
|
|
34
|
-
*/
|
|
35
|
-
private readonly id2v: Map<Id, WeakRef<TValue>>;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* オブジェクトが GC されたときに実行されるコールバックを登録するための `FinalizationRegistry` です。
|
|
39
|
-
*
|
|
40
|
-
* オブジェクトが GC されると、登録された ID がコールバックに渡され、その ID に対応するエントリーを `id2v` マップから削除するために使用されます。
|
|
41
|
-
*/
|
|
42
|
-
private readonly gc: FinalizationRegistry<Id>;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* `WeakIdRegistry` クラスの新しいインスタンスを作成します。
|
|
46
|
-
*/
|
|
47
|
-
public constructor() {
|
|
48
|
-
this.counter = 0n;
|
|
49
|
-
this.v2id = new WeakMap();
|
|
50
|
-
this.id2v = new Map();
|
|
51
|
-
this.gc = new FinalizationRegistry(id => {
|
|
52
|
-
this.id2v.delete(id);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* 指定されたオブジェクトに一意の ID を割り当てて登録します。
|
|
58
|
-
*
|
|
59
|
-
* すでに ID が割り当てられているオブジェクトであれば、既存の ID を返します。
|
|
60
|
-
*
|
|
61
|
-
* @param value ID を割り当てる対象のオブジェクトです。
|
|
62
|
-
* @returns 割り当てられた、または既存の一意の ID です。
|
|
63
|
-
*/
|
|
64
|
-
public set(value: TValue): Id {
|
|
65
|
-
if (!this.v2id.has(value)) {
|
|
66
|
-
const id = (this.counter++).toString(36);
|
|
67
|
-
this.v2id.set(value, id);
|
|
68
|
-
this.id2v.set(id, new WeakRef(value));
|
|
69
|
-
// `FinalizationRegistry` にオブジェクトとそれに対応する ID を登録します。
|
|
70
|
-
// これにより、オブジェクトが GC されたときに `id2v` からエントリーが削除されます。
|
|
71
|
-
this.gc.register(value, id);
|
|
72
|
-
|
|
73
|
-
return id;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const id = this.v2id.get(value)!;
|
|
77
|
-
switch (typeof id) {
|
|
78
|
-
case "string":
|
|
79
|
-
return id;
|
|
80
|
-
default:
|
|
81
|
-
// `id` は必ず文字列になるはずです。
|
|
82
|
-
unreachable(id);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 指定されたオブジェクトに ID が割り当てられているかどうかを確認します。
|
|
88
|
-
*
|
|
89
|
-
* @param value 確認するオブジェクトです。
|
|
90
|
-
* @returns ID が割り当てられていれば `true`、そうでなければ `false` を返します。
|
|
91
|
-
*/
|
|
92
|
-
public has(value: TValue): boolean {
|
|
93
|
-
return this.v2id.has(value);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* 指定されたオブジェクトに対応する ID を取得します。
|
|
98
|
-
*
|
|
99
|
-
* オブジェクトが未登録の場合は `undefined` を返します。
|
|
100
|
-
*
|
|
101
|
-
* @param value 取得したい ID のオブジェクトです。
|
|
102
|
-
* @returns 対応する ID、またはオブジェクトが未登録の場合は `undefined` を返します。
|
|
103
|
-
*/
|
|
104
|
-
public get(value: TValue): Id | undefined;
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* 指定された ID に対応するオブジェクトを取得します。
|
|
108
|
-
*
|
|
109
|
-
* オブジェクトが既に GC されている場合は `undefined` を返します。
|
|
110
|
-
*
|
|
111
|
-
* @param id 取得したいオブジェクトの ID です。
|
|
112
|
-
* @returns 対応するオブジェクト、またはオブジェクトが GC されている場合は `undefined` を返します。
|
|
113
|
-
*/
|
|
114
|
-
public get(id: Id): TValue | undefined;
|
|
115
|
-
|
|
116
|
-
public get(idOrValue: Id | TValue): unknown {
|
|
117
|
-
if (typeof idOrValue === "string") {
|
|
118
|
-
const id = idOrValue;
|
|
119
|
-
return this.id2v.get(id)?.deref();
|
|
120
|
-
} else {
|
|
121
|
-
const value = idOrValue;
|
|
122
|
-
return this.v2id.get(value);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
package/src/core/constants.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type DeferredPromise from "./deferred-promise.js";
|
|
2
|
-
import type { IAction, ILoader } from "./route.types.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 読み取り専用のデータマップを表すインターフェースです。
|
|
6
|
-
*
|
|
7
|
-
* ルートに関連付けられたアクションやローダーの関数をキーとし、その実行結果を値として保持します。
|
|
8
|
-
*
|
|
9
|
-
* @template TDataFunction アクションまたはローダーの型定義です。デフォルトは `IAction | ILoader` です。
|
|
10
|
-
* @template TData 遅延評価されるプロミスの型定義です。デフォルトは `DeferredPromise<unknown>` です。
|
|
11
|
-
*/
|
|
12
|
-
export interface IReadonlyDataMap<
|
|
13
|
-
TDataFunction extends IAction | ILoader = IAction | ILoader,
|
|
14
|
-
TData = DeferredPromise<unknown>,
|
|
15
|
-
> extends ReadonlyMap<TDataFunction, TData> {}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 書き込み可能なデータマップを表すインターフェースです。
|
|
19
|
-
*
|
|
20
|
-
* ルートに関連付けられたアクションやローダーの関数をキーとし、その実行結果を値として保持・操作します。
|
|
21
|
-
*
|
|
22
|
-
* @template TDataFunction アクションまたはローダーの型定義です。デフォルトは `IAction | ILoader` です。
|
|
23
|
-
* @template TData 遅延評価されるプロミスの型定義です。デフォルトは `DeferredPromise<unknown>` です。
|
|
24
|
-
*/
|
|
25
|
-
export interface IDataMap<
|
|
26
|
-
TDataFunction extends IAction | ILoader = IAction | ILoader,
|
|
27
|
-
TData = DeferredPromise<unknown>,
|
|
28
|
-
> extends Map<TDataFunction, TData> {}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { IDataMap } from "./data-map.types.js";
|
|
2
|
-
import type { HistoryEntryId } from "./history-entry-id-schema.js";
|
|
3
|
-
import type { IAction, ILoader } from "./route.types.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 読み取り専用のデータストアを表すインターフェースです。
|
|
7
|
-
*
|
|
8
|
-
* 履歴エントリーの ID をキーとし、それに関連付けられたデータマップを値として管理します。
|
|
9
|
-
*
|
|
10
|
-
* @template TDataFunction データマップ内で使用されるアクションまたはローダーの型定義です。
|
|
11
|
-
*/
|
|
12
|
-
export interface IReadonlyDataStore<TDataFunction extends IAction | ILoader = IAction | ILoader>
|
|
13
|
-
extends Readonly<Map<HistoryEntryId, IDataMap<TDataFunction>>>
|
|
14
|
-
{}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 書き込み可能なデータストアを表すインターフェースです。
|
|
18
|
-
*
|
|
19
|
-
* 履歴エントリーの ID ごとに、ルートに関連するデータの読み書きを行います。
|
|
20
|
-
*
|
|
21
|
-
* @template TDataFunction データマップ内で使用されるアクションまたはローダーの型定義です。
|
|
22
|
-
*/
|
|
23
|
-
export interface IDataStore<TDataFunction extends IAction | ILoader = IAction | ILoader>
|
|
24
|
-
extends Map<HistoryEntryId, IDataMap<TDataFunction>>
|
|
25
|
-
{}
|
|
@@ -1,408 +0,0 @@
|
|
|
1
|
-
import isPromiseLike from "./_is-promise-like.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* DeferredPromise の基本型です。
|
|
5
|
-
*
|
|
6
|
-
* @template T 非同期処理の結果として返される値の型です。
|
|
7
|
-
*/
|
|
8
|
-
interface DeferredPromiseLike<T> {
|
|
9
|
-
/**
|
|
10
|
-
* Promise が解決または拒否された際のコールバックを登録します。
|
|
11
|
-
*
|
|
12
|
-
* @template TResult1 解決時コールバックの戻り値の型です。
|
|
13
|
-
* @template TResult2 拒否時コールバックの戻り値の型です。
|
|
14
|
-
* @param onfulfilled 解決時に実行されるコールバックです。
|
|
15
|
-
* @param onrejected 拒否時に実行されるコールバックです。
|
|
16
|
-
* @returns 新しい DeferredPromise インスタンスです。
|
|
17
|
-
*/
|
|
18
|
-
then<TResult1 = T, TResult2 = never>(
|
|
19
|
-
onfulfilled?:
|
|
20
|
-
| ((value: T) => TResult1 | PromiseLike<TResult1>)
|
|
21
|
-
| null
|
|
22
|
-
| undefined,
|
|
23
|
-
onrejected?:
|
|
24
|
-
| ((reason: unknown) => TResult2 | PromiseLike<TResult2>)
|
|
25
|
-
| null
|
|
26
|
-
| undefined,
|
|
27
|
-
): DeferredPromise<TResult1 | TResult2>;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 待機状態(pending)にある DeferredPromise を表すインターフェースです。
|
|
32
|
-
*
|
|
33
|
-
* @template T 非同期処理の結果として返される値の型です。
|
|
34
|
-
*/
|
|
35
|
-
export interface PendingDeferredPromise<T> extends DeferredPromiseLike<T> {
|
|
36
|
-
/**
|
|
37
|
-
* 現在の状態を示します。
|
|
38
|
-
*/
|
|
39
|
-
status: "pending";
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* 完了状態(fulfilled)にある DeferredPromise を表すインターフェースです。
|
|
44
|
-
*
|
|
45
|
-
* @template T 非同期処理の結果として返される値の型です。
|
|
46
|
-
*/
|
|
47
|
-
export interface FulfilledDeferredPromise<T> extends DeferredPromiseLike<T> {
|
|
48
|
-
/**
|
|
49
|
-
* 現在の状態を示します。
|
|
50
|
-
*/
|
|
51
|
-
status: "fulfilled";
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* 解決された値です。
|
|
55
|
-
*/
|
|
56
|
-
value: T;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* 拒否状態(rejected)にある DeferredPromise を表すインターフェースです。
|
|
61
|
-
*
|
|
62
|
-
* @template T 非同期処理の結果として期待されていた値の型です。
|
|
63
|
-
*/
|
|
64
|
-
export interface RejectedDeferredPromise<T> extends DeferredPromiseLike<T> {
|
|
65
|
-
/**
|
|
66
|
-
* 現在の状態を示します。
|
|
67
|
-
*/
|
|
68
|
-
status: "rejected";
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* 拒否された理由(エラー内容)です。
|
|
72
|
-
*/
|
|
73
|
-
reason: unknown;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Promise の状態を外部から同期的に参照できるようにしたクラスです。
|
|
78
|
-
*
|
|
79
|
-
* PromiseLike を実装しています。このクラスは主に `React.use` で使うことを想定して実装されています。
|
|
80
|
-
*
|
|
81
|
-
* @template T 非同期処理の結果として返される値の型です。
|
|
82
|
-
*/
|
|
83
|
-
type DeferredPromise<T> =
|
|
84
|
-
| PendingDeferredPromise<T>
|
|
85
|
-
| FulfilledDeferredPromise<T>
|
|
86
|
-
| RejectedDeferredPromise<T>;
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* 外部から解決または拒否が可能な DeferredPromise のリゾルバー群を表すインターフェースです。
|
|
90
|
-
*
|
|
91
|
-
* @template T DeferredPromise が解決された際の値の型です。
|
|
92
|
-
*/
|
|
93
|
-
export interface DeferredPromiseWithResolvers<T> {
|
|
94
|
-
/**
|
|
95
|
-
* 現在のステータスを持つ DeferredPromise オブジェクトです。
|
|
96
|
-
*/
|
|
97
|
-
promise: DeferredPromise<T>;
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* DeferredPromise を解決(resolve)させる関数です。
|
|
101
|
-
*
|
|
102
|
-
* @param value 解決に用いる値です。
|
|
103
|
-
*/
|
|
104
|
-
resolve(value: T | PromiseLike<T>): void;
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* DeferredPromise を拒否(reject)させる関数です。
|
|
108
|
-
*
|
|
109
|
-
* @param reason 拒否の理由です。
|
|
110
|
-
*/
|
|
111
|
-
reject(reason?: unknown): void;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* DeferredPromise が取り得る状態のユニオン型です。
|
|
116
|
-
*/
|
|
117
|
-
type DeferredPromiseState = "pending" | "fulfilled" | "rejected";
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* then メソッドで登録されるコールバックと、それに関連する解決・拒否関数を保持する型です。
|
|
121
|
-
*
|
|
122
|
-
* @template T 元の Promise が解決された際の値の型です。
|
|
123
|
-
* @template TResult コールバックの実行結果として返される値の型です。
|
|
124
|
-
*/
|
|
125
|
-
type PromiseCallback<T, TResult> = {
|
|
126
|
-
/**
|
|
127
|
-
* 後続の Promise を拒否するための関数です。
|
|
128
|
-
*/
|
|
129
|
-
readonly reject: (reason?: unknown) => void;
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* 後続の Promise を解決するための関数です。
|
|
133
|
-
*/
|
|
134
|
-
readonly resolve: (value: TResult) => void;
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* 拒否時に実行されるユーザー定義のコールバックです。
|
|
138
|
-
*/
|
|
139
|
-
readonly onRejected:
|
|
140
|
-
| ((reason: unknown) => TResult | PromiseLike<TResult>)
|
|
141
|
-
| null
|
|
142
|
-
| undefined;
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* 解決時に実行されるユーザー定義のコールバックです。
|
|
146
|
-
*/
|
|
147
|
-
readonly onFulfilled:
|
|
148
|
-
| ((value: T) => TResult | PromiseLike<TResult>)
|
|
149
|
-
| null
|
|
150
|
-
| undefined;
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* 動的に解決された値や拒否理由を保持するためのベースクラスを生成する定数です。
|
|
155
|
-
*/
|
|
156
|
-
const Options = (class {}) as {
|
|
157
|
-
new<T>(): {
|
|
158
|
-
/**
|
|
159
|
-
* 解決された値です。
|
|
160
|
-
*/
|
|
161
|
-
value?: T;
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* 拒否された理由(エラー内容)です。
|
|
165
|
-
*/
|
|
166
|
-
reason?: unknown;
|
|
167
|
-
};
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
const DeferredPromise = class DeferredPromise_<T> extends Options<T> implements PromiseLike<T> {
|
|
171
|
-
/**
|
|
172
|
-
* 指定された関数を実行し、その結果を DeferredPromise として返します。
|
|
173
|
-
* 関数が同期的に例外を投げた場合、拒否状態の Promise を返します。
|
|
174
|
-
*
|
|
175
|
-
* @template T 関数の戻り値の型です。
|
|
176
|
-
* @template TArgs 関数に渡す引数の型配列です。
|
|
177
|
-
* @param callbackFn 実行するコールバック関数です。
|
|
178
|
-
* @param args 関数に渡す引数です。
|
|
179
|
-
* @returns 実行結果をラップした DeferredPromise です。
|
|
180
|
-
*/
|
|
181
|
-
public static try<T, TArgs extends unknown[]>(
|
|
182
|
-
callbackFn: (...args: TArgs) => T | PromiseLike<T>,
|
|
183
|
-
...args: TArgs
|
|
184
|
-
): DeferredPromise<Awaited<T>> {
|
|
185
|
-
let value;
|
|
186
|
-
try {
|
|
187
|
-
value = callbackFn(...args);
|
|
188
|
-
if (!isPromiseLike(value)) {
|
|
189
|
-
return this.resolve(value) as DeferredPromise<Awaited<T>>;
|
|
190
|
-
}
|
|
191
|
-
} catch (ex) {
|
|
192
|
-
return this.reject<T>(ex) as DeferredPromise<Awaited<T>>;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const {
|
|
196
|
-
reject,
|
|
197
|
-
resolve,
|
|
198
|
-
promise,
|
|
199
|
-
} = this.withResolvers<Awaited<T>>();
|
|
200
|
-
(async function runDeferredPromise() {
|
|
201
|
-
try {
|
|
202
|
-
resolve(await value);
|
|
203
|
-
} catch (ex) {
|
|
204
|
-
reject(ex);
|
|
205
|
-
}
|
|
206
|
-
})();
|
|
207
|
-
|
|
208
|
-
return promise as DeferredPromise<Awaited<T>>;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* 既に拒否状態となっている DeferredPromise インスタンスを生成します。
|
|
213
|
-
*
|
|
214
|
-
* @template T DeferredPromise が期待していた値の型です。
|
|
215
|
-
* @param reason 拒否の理由です。
|
|
216
|
-
* @returns 拒否状態の DeferredPromise です。
|
|
217
|
-
*/
|
|
218
|
-
public static reject<T = never>(reason?: unknown): RejectedDeferredPromise<T> {
|
|
219
|
-
const promise = new DeferredPromise_<T>();
|
|
220
|
-
promise.#reject(reason);
|
|
221
|
-
|
|
222
|
-
return promise as RejectedDeferredPromise<T>;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* 既に解決状態となっている DeferredPromise インスタンスを生成します。
|
|
227
|
-
*
|
|
228
|
-
* @template T 解決される値の型です。
|
|
229
|
-
* @param value 解決に用いる値です。
|
|
230
|
-
* @returns 解決状態の DeferredPromise です。
|
|
231
|
-
*/
|
|
232
|
-
public static resolve<T>(value: T): FulfilledDeferredPromise<T> {
|
|
233
|
-
const promise = new DeferredPromise_<T>();
|
|
234
|
-
promise.#resolve(value);
|
|
235
|
-
|
|
236
|
-
return promise as FulfilledDeferredPromise<T>;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* DeferredPromise と、それを外部から制御するためのリゾルバー(resolve/reject)を生成します。
|
|
241
|
-
*
|
|
242
|
-
* @template T DeferredPromise が解決された際の値の型です。
|
|
243
|
-
* @returns DeferredPromise とリゾルバーを含むオブジェクトです。
|
|
244
|
-
*/
|
|
245
|
-
public static withResolvers<T>(): DeferredPromiseWithResolvers<T> {
|
|
246
|
-
const promise = new DeferredPromise_<T>();
|
|
247
|
-
|
|
248
|
-
return {
|
|
249
|
-
reject(reason) {
|
|
250
|
-
promise.#reject(reason);
|
|
251
|
-
},
|
|
252
|
-
resolve(value) {
|
|
253
|
-
promise.#resolve(value);
|
|
254
|
-
},
|
|
255
|
-
// @ts-expect-error
|
|
256
|
-
promise,
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* 解決または拒否を待機しているコールバックのキューです。
|
|
262
|
-
*/
|
|
263
|
-
readonly #queue: PromiseCallback<T, any>[] = [];
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* 内部的に Promise を拒否状態に遷移させます。
|
|
267
|
-
*
|
|
268
|
-
* @param reason 拒否の理由です。
|
|
269
|
-
*/
|
|
270
|
-
#reject(reason?: unknown): void {
|
|
271
|
-
if (this.status !== "pending") {
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
this.status = "rejected";
|
|
276
|
-
this.reason = reason;
|
|
277
|
-
this.#processQueue();
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* 内部的に Promise を解決状態に遷移させます。
|
|
282
|
-
*
|
|
283
|
-
* 引数が PromiseLike の場合は、その状態を継承します。
|
|
284
|
-
*
|
|
285
|
-
* @param value 解決に用いる値、または PromiseLike オブジェクトです。
|
|
286
|
-
*/
|
|
287
|
-
#resolve(value: T | PromiseLike<T>): void {
|
|
288
|
-
if (this.status !== "pending") {
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (!isPromiseLike(value)) {
|
|
293
|
-
// 値による解決を行います。
|
|
294
|
-
this.status = "fulfilled";
|
|
295
|
-
this.value = value;
|
|
296
|
-
this.#processQueue();
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// 受け取った値が PromiseLike だった場合、その状態を継承します。
|
|
301
|
-
try {
|
|
302
|
-
// 再帰的に待機します。
|
|
303
|
-
value.then.call(
|
|
304
|
-
value,
|
|
305
|
-
(y: T) => this.#resolve(y),
|
|
306
|
-
(r: unknown) => this.#reject(r),
|
|
307
|
-
);
|
|
308
|
-
} catch (ex) {
|
|
309
|
-
this.#reject(ex);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* キューに積まれたコールバックを順次実行します。
|
|
315
|
-
*
|
|
316
|
-
* ステータスが確定していない場合は何もしません。
|
|
317
|
-
*/
|
|
318
|
-
#processQueue(): void {
|
|
319
|
-
if (this.status === "pending") {
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// Promise の仕様に従い、マイクロタスクに入れて非同期実行を保証します。
|
|
324
|
-
queueMicrotask(() => {
|
|
325
|
-
while (this.#queue.length > 0) {
|
|
326
|
-
const callback = this.#queue.shift();
|
|
327
|
-
if (!callback) {
|
|
328
|
-
continue;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
const {
|
|
332
|
-
reject,
|
|
333
|
-
resolve,
|
|
334
|
-
onRejected,
|
|
335
|
-
onFulfilled,
|
|
336
|
-
} = callback;
|
|
337
|
-
try {
|
|
338
|
-
if (this.status === "fulfilled") {
|
|
339
|
-
if (typeof onFulfilled === "function") {
|
|
340
|
-
const result = onFulfilled(this.value!);
|
|
341
|
-
resolve(result);
|
|
342
|
-
} else {
|
|
343
|
-
// コールバックがない場合は値を透過させます。
|
|
344
|
-
resolve(this.value);
|
|
345
|
-
}
|
|
346
|
-
} else if (this.status === "rejected") {
|
|
347
|
-
if (typeof onRejected === "function") {
|
|
348
|
-
const result = onRejected(this.reason);
|
|
349
|
-
resolve(result); // エラーハンドリング成功時は次の Promise は resolve されます。
|
|
350
|
-
} else {
|
|
351
|
-
// コールバックがない場合はエラーを透過させます。
|
|
352
|
-
reject(this.reason);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
} catch (ex) {
|
|
356
|
-
// コールバック実行中にエラーが発生した場合は、後続の Promise を拒否します。
|
|
357
|
-
reject(ex);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* 現在の Promise の状態です。
|
|
365
|
-
*/
|
|
366
|
-
public status: DeferredPromiseState = "pending";
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Promise が解決または拒否された際のコールバックを登録します。
|
|
370
|
-
*
|
|
371
|
-
* @template TResult1 解決時コールバックの戻り値の型です。
|
|
372
|
-
* @template TResult2 拒否時コールバックの戻り値の型です。
|
|
373
|
-
* @param onfulfilled 解決時に実行されるコールバックです。
|
|
374
|
-
* @param onrejected 拒否時に実行されるコールバックです。
|
|
375
|
-
* @returns 新しい DeferredPromise インスタンスです。
|
|
376
|
-
*/
|
|
377
|
-
public then<TResult1 = T, TResult2 = never>(
|
|
378
|
-
onfulfilled?:
|
|
379
|
-
| ((value: T) => TResult1 | PromiseLike<TResult1>)
|
|
380
|
-
| null
|
|
381
|
-
| undefined,
|
|
382
|
-
onrejected?:
|
|
383
|
-
| ((reason: unknown) => TResult2 | PromiseLike<TResult2>)
|
|
384
|
-
| null
|
|
385
|
-
| undefined,
|
|
386
|
-
): DeferredPromise<TResult1 | TResult2> {
|
|
387
|
-
// 新しい DeferredPromise を作成してチェーンをつなぎます。
|
|
388
|
-
const nextPromise = new DeferredPromise_<TResult1 | TResult2>();
|
|
389
|
-
|
|
390
|
-
this.#queue.push({
|
|
391
|
-
reject(reason) {
|
|
392
|
-
nextPromise.#reject(reason);
|
|
393
|
-
},
|
|
394
|
-
resolve(value) {
|
|
395
|
-
nextPromise.#resolve(value);
|
|
396
|
-
},
|
|
397
|
-
onRejected: onrejected,
|
|
398
|
-
onFulfilled: onfulfilled,
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
// すでに解決/拒否済みかもしれないのでキュー処理を試行します。
|
|
402
|
-
this.#processQueue();
|
|
403
|
-
|
|
404
|
-
return nextPromise as DeferredPromise<TResult1 | TResult2>;
|
|
405
|
-
}
|
|
406
|
-
};
|
|
407
|
-
|
|
408
|
-
export default DeferredPromise;
|