@real-router/solid 0.14.1 → 0.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +0 -0
- package/dist/esm/index.mjs +0 -0
- package/dist/types/dom-utils/link-utils.d.ts.map +1 -1
- package/dist/types/dom-utils/scroll-spy.d.ts.map +1 -1
- package/package.json +9 -10
- package/src/RouterProvider.tsx +0 -112
- package/src/components/Await.tsx +0 -56
- package/src/components/ClientOnly.tsx +0 -20
- package/src/components/HttpStatusCode.tsx +0 -65
- package/src/components/HttpStatusProvider.tsx +0 -21
- package/src/components/Link.tsx +0 -140
- package/src/components/RouteView/RouteView.tsx +0 -59
- package/src/components/RouteView/components.tsx +0 -85
- package/src/components/RouteView/helpers.tsx +0 -0
- package/src/components/RouteView/index.ts +0 -8
- package/src/components/RouteView/types.ts +0 -24
- package/src/components/RouterErrorBoundary.tsx +0 -45
- package/src/components/ServerOnly.tsx +0 -20
- package/src/components/Streamed.tsx +0 -23
- package/src/constants.ts +0 -27
- package/src/context.ts +0 -35
- package/src/createSignalFromSource.ts +0 -71
- package/src/createStoreFromSource.ts +0 -65
- package/src/directives/link.tsx +0 -111
- package/src/directives.d.ts +0 -10
- package/src/hooks/useDeferred.tsx +0 -36
- package/src/hooks/useNavigator.tsx +0 -6
- package/src/hooks/useRoute.tsx +0 -27
- package/src/hooks/useRouteEnter.tsx +0 -121
- package/src/hooks/useRouteExit.tsx +0 -123
- package/src/hooks/useRouteNode.tsx +0 -13
- package/src/hooks/useRouteNodeStore.tsx +0 -12
- package/src/hooks/useRouteStore.tsx +0 -12
- package/src/hooks/useRouteUtils.tsx +0 -50
- package/src/hooks/useRouter.tsx +0 -6
- package/src/hooks/useRouterTransition.tsx +0 -14
- package/src/index.tsx +0 -66
- package/src/ssr.tsx +0 -39
- package/src/types.ts +0 -28
- package/src/utils/createHttpStatusSink.ts +0 -31
- package/src/utils/createMountedSignal.ts +0 -26
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { onCleanup } from "solid-js";
|
|
2
|
-
|
|
3
|
-
import { useRouter } from "./useRouter";
|
|
4
|
-
|
|
5
|
-
import type { State } from "@real-router/core";
|
|
6
|
-
|
|
7
|
-
export interface RouteExitContext {
|
|
8
|
-
/** The route being left. */
|
|
9
|
-
route: State;
|
|
10
|
-
/** The route being navigated to. */
|
|
11
|
-
nextRoute: State;
|
|
12
|
-
/**
|
|
13
|
-
* AbortSignal that fires when this navigation is superseded by a later
|
|
14
|
-
* one (rapid clicks). Already filtered: when the handler runs,
|
|
15
|
-
* `signal.aborted` is guaranteed to be `false`. Use
|
|
16
|
-
* `signal.addEventListener("abort", cleanup, { once: true })` for
|
|
17
|
-
* cleanup that must run on cancellation.
|
|
18
|
-
*/
|
|
19
|
-
signal: AbortSignal;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface UseRouteExitOptions {
|
|
23
|
-
/**
|
|
24
|
-
* Skip the handler when `route.name === nextRoute.name`
|
|
25
|
-
* (sort/filter/query-only navigations on the same route). Default:
|
|
26
|
-
* `true`.
|
|
27
|
-
*/
|
|
28
|
-
skipSameRoute?: boolean;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export type RouteExitHandler = (
|
|
32
|
-
context: RouteExitContext,
|
|
33
|
-
) => void | Promise<void>;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Subscribe to the router's leave-window with the universal guards baked
|
|
37
|
-
* in. Wraps `router.subscribeLeave` so consumers don't repeat the same
|
|
38
|
-
* boilerplate every time:
|
|
39
|
-
*
|
|
40
|
-
* - **Reentrant abort pre-check**: if `signal.aborted` is already `true`
|
|
41
|
-
* when the handler would run (rapid navigation superseded a slower
|
|
42
|
-
* one), the handler is skipped entirely. `signal.addEventListener(
|
|
43
|
-
* "abort", ...)` does not fire retroactively, so without this guard
|
|
44
|
-
* downstream cleanup would never trigger.
|
|
45
|
-
* - **Same-route skip**: by default, `route.name === nextRoute.name`
|
|
46
|
-
* short-circuits the handler — query-only navigations (sort, filter,
|
|
47
|
-
* pagination) skip the work. Opt out with `skipSameRoute: false`.
|
|
48
|
-
*
|
|
49
|
-
* Returns nothing — the subscription's lifecycle is bound to the
|
|
50
|
-
* component via `onCleanup`.
|
|
51
|
-
*
|
|
52
|
-
* If the handler returns a Promise, the router blocks on it. If the
|
|
53
|
-
* Promise resolves, navigation proceeds. If it rejects, the router emits
|
|
54
|
-
* `TRANSITION_CANCELLED`.
|
|
55
|
-
*
|
|
56
|
-
* **Handler reactivity (Solid)**: Solid components run **once** at mount;
|
|
57
|
-
* `handler` is captured in closure at the call site. If you need
|
|
58
|
-
* different behavior across renders, derive it from a signal inside the
|
|
59
|
-
* handler body — do not rely on swapping the handler reference.
|
|
60
|
-
*
|
|
61
|
-
* @example Animation
|
|
62
|
-
* ```tsx
|
|
63
|
-
* let ref: HTMLDivElement | undefined;
|
|
64
|
-
*
|
|
65
|
-
* useRouteExit(async ({ signal }) => {
|
|
66
|
-
* const el = ref;
|
|
67
|
-
* if (!el) return;
|
|
68
|
-
* el.classList.add("fade-out");
|
|
69
|
-
* const cleanup = () => el.classList.remove("fade-out");
|
|
70
|
-
* signal.addEventListener("abort", cleanup, { once: true });
|
|
71
|
-
* try {
|
|
72
|
-
* el.getBoundingClientRect(); // style flush
|
|
73
|
-
* await Promise.allSettled(el.getAnimations().map((a) => a.finished));
|
|
74
|
-
* } finally {
|
|
75
|
-
* cleanup();
|
|
76
|
-
* }
|
|
77
|
-
* });
|
|
78
|
-
* ```
|
|
79
|
-
*
|
|
80
|
-
* @example Auto-save form draft
|
|
81
|
-
* ```tsx
|
|
82
|
-
* useRouteExit(async ({ signal }) => {
|
|
83
|
-
* if (formState.dirty) await api.saveDraft(formState, { signal });
|
|
84
|
-
* });
|
|
85
|
-
* ```
|
|
86
|
-
*
|
|
87
|
-
* @example Reading rich transition metadata via `nextRoute.transition`
|
|
88
|
-
* ```tsx
|
|
89
|
-
* useRouteExit(({ route, nextRoute }) => {
|
|
90
|
-
* if (nextRoute.transition.segments.deactivated.includes("products")) {
|
|
91
|
-
* productCache.clear();
|
|
92
|
-
* }
|
|
93
|
-
* if (nextRoute.transition.redirected) {
|
|
94
|
-
* return;
|
|
95
|
-
* }
|
|
96
|
-
* });
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
|
-
export function useRouteExit(
|
|
100
|
-
handler: RouteExitHandler,
|
|
101
|
-
options?: UseRouteExitOptions,
|
|
102
|
-
): void {
|
|
103
|
-
const router = useRouter();
|
|
104
|
-
const skipSameRoute = options?.skipSameRoute ?? true;
|
|
105
|
-
|
|
106
|
-
const off = router.subscribeLeave(({ route, nextRoute, signal }) => {
|
|
107
|
-
if (skipSameRoute && route.name === nextRoute.name) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Reentrant abort: signal is already aborted when listener fires
|
|
112
|
-
// (e.g. a newer navigate superseded this one before subscribeLeave
|
|
113
|
-
// even ran). addEventListener("abort", ...) does not fire
|
|
114
|
-
// retroactively, so we skip the handler entirely.
|
|
115
|
-
if (signal.aborted) {
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return handler({ route, nextRoute, signal });
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
onCleanup(off);
|
|
123
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { createRouteNodeSource } from "@real-router/sources";
|
|
2
|
-
|
|
3
|
-
import { createSignalFromSource } from "../createSignalFromSource";
|
|
4
|
-
import { useRouter } from "./useRouter";
|
|
5
|
-
|
|
6
|
-
import type { RouteState } from "../types";
|
|
7
|
-
import type { Accessor } from "solid-js";
|
|
8
|
-
|
|
9
|
-
export function useRouteNode(nodeName: string): Accessor<RouteState> {
|
|
10
|
-
const router = useRouter();
|
|
11
|
-
|
|
12
|
-
return createSignalFromSource(createRouteNodeSource(router, nodeName));
|
|
13
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { createRouteNodeSource } from "@real-router/sources";
|
|
2
|
-
|
|
3
|
-
import { createStoreFromSource } from "../createStoreFromSource";
|
|
4
|
-
import { useRouter } from "./useRouter";
|
|
5
|
-
|
|
6
|
-
import type { RouteState } from "../types";
|
|
7
|
-
|
|
8
|
-
export function useRouteNodeStore(nodeName: string): RouteState {
|
|
9
|
-
const router = useRouter();
|
|
10
|
-
|
|
11
|
-
return createStoreFromSource(createRouteNodeSource(router, nodeName));
|
|
12
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { createRouteSource } from "@real-router/sources";
|
|
2
|
-
|
|
3
|
-
import { createStoreFromSource } from "../createStoreFromSource";
|
|
4
|
-
import { useRouter } from "./useRouter";
|
|
5
|
-
|
|
6
|
-
import type { RouteState } from "../types";
|
|
7
|
-
|
|
8
|
-
export function useRouteStore(): RouteState {
|
|
9
|
-
const router = useRouter();
|
|
10
|
-
|
|
11
|
-
return createStoreFromSource(createRouteSource(router));
|
|
12
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { getPluginApi } from "@real-router/core/api";
|
|
2
|
-
import { getRouteUtils } from "@real-router/route-utils";
|
|
3
|
-
|
|
4
|
-
import { useRouter } from "./useRouter";
|
|
5
|
-
|
|
6
|
-
import type { Router } from "@real-router/core";
|
|
7
|
-
import type { RouteUtils } from "@real-router/route-utils";
|
|
8
|
-
|
|
9
|
-
// §8.1 audit fix (MED) — cache the `RouteUtils` per (router, tree) so N
|
|
10
|
-
// components calling `useRouteUtils()` against the same router share ONE
|
|
11
|
-
// chain through `getPluginApi(router).getTree()` + `getRouteUtils(tree)`.
|
|
12
|
-
//
|
|
13
|
-
// Why two-level (router + tree) and not just router:
|
|
14
|
-
// `getRouteUtils` is WeakMap-cached by tree root, BUT a RouteUtils
|
|
15
|
-
// instance is built FROM the tree at construction time — its internal
|
|
16
|
-
// `getChain`/`getSiblings` caches are pre-computed Object.freeze'd arrays
|
|
17
|
-
// (see `@real-router/route-utils` CLAUDE.md). If the router replaces its
|
|
18
|
-
// tree (e.g. `routesApi.replace([...])`), the old RouteUtils is stale.
|
|
19
|
-
// Caching only by router would serve the stale instance.
|
|
20
|
-
//
|
|
21
|
-
// Storing `{ tree, utils }` per router lets us detect tree replacement and
|
|
22
|
-
// recompute. In the steady state (no tree mutation), this is a cheap
|
|
23
|
-
// reference compare; under tree replacement, the cache self-heals on the
|
|
24
|
-
// next call.
|
|
25
|
-
//
|
|
26
|
-
// WeakMap keys on the router — entries are released automatically when the
|
|
27
|
-
// router is garbage-collected.
|
|
28
|
-
interface CachedEntry {
|
|
29
|
-
tree: unknown;
|
|
30
|
-
utils: RouteUtils;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const routeUtilsCache = new WeakMap<Router, CachedEntry>();
|
|
34
|
-
|
|
35
|
-
export const useRouteUtils = (): RouteUtils => {
|
|
36
|
-
const router = useRouter();
|
|
37
|
-
const tree = getPluginApi(router).getTree();
|
|
38
|
-
|
|
39
|
-
const cached = routeUtilsCache.get(router);
|
|
40
|
-
|
|
41
|
-
if (cached?.tree === tree) {
|
|
42
|
-
return cached.utils;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const utils = getRouteUtils(tree);
|
|
46
|
-
|
|
47
|
-
routeUtilsCache.set(router, { tree, utils });
|
|
48
|
-
|
|
49
|
-
return utils;
|
|
50
|
-
};
|
package/src/hooks/useRouter.tsx
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { getTransitionSource } from "@real-router/sources";
|
|
2
|
-
|
|
3
|
-
import { createSignalFromSource } from "../createSignalFromSource";
|
|
4
|
-
import { useRouter } from "./useRouter";
|
|
5
|
-
|
|
6
|
-
import type { RouterTransitionSnapshot } from "@real-router/sources";
|
|
7
|
-
import type { Accessor } from "solid-js";
|
|
8
|
-
|
|
9
|
-
export function useRouterTransition(): Accessor<RouterTransitionSnapshot> {
|
|
10
|
-
const router = useRouter();
|
|
11
|
-
const source = getTransitionSource(router);
|
|
12
|
-
|
|
13
|
-
return createSignalFromSource(source);
|
|
14
|
-
}
|
package/src/index.tsx
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
export { RouteView } from "./components/RouteView";
|
|
2
|
-
|
|
3
|
-
export { Link } from "./components/Link";
|
|
4
|
-
|
|
5
|
-
export { RouterErrorBoundary } from "./components/RouterErrorBoundary";
|
|
6
|
-
|
|
7
|
-
export { link } from "./directives/link";
|
|
8
|
-
|
|
9
|
-
export { useRouter } from "./hooks/useRouter";
|
|
10
|
-
|
|
11
|
-
export { useNavigator } from "./hooks/useNavigator";
|
|
12
|
-
|
|
13
|
-
export { useRouteUtils } from "./hooks/useRouteUtils";
|
|
14
|
-
|
|
15
|
-
export { useRoute } from "./hooks/useRoute";
|
|
16
|
-
|
|
17
|
-
export { useRouteNode } from "./hooks/useRouteNode";
|
|
18
|
-
|
|
19
|
-
export { useRouteStore } from "./hooks/useRouteStore";
|
|
20
|
-
|
|
21
|
-
export { useRouteNodeStore } from "./hooks/useRouteNodeStore";
|
|
22
|
-
|
|
23
|
-
export { useRouterTransition } from "./hooks/useRouterTransition";
|
|
24
|
-
|
|
25
|
-
export { useRouteExit } from "./hooks/useRouteExit";
|
|
26
|
-
|
|
27
|
-
export { useRouteEnter } from "./hooks/useRouteEnter";
|
|
28
|
-
|
|
29
|
-
export { RouterProvider } from "./RouterProvider";
|
|
30
|
-
|
|
31
|
-
export { RouterContext, RouteContext } from "./context";
|
|
32
|
-
|
|
33
|
-
export type { RouterContextValue } from "./context";
|
|
34
|
-
|
|
35
|
-
export { createSignalFromSource } from "./createSignalFromSource";
|
|
36
|
-
|
|
37
|
-
export { createStoreFromSource } from "./createStoreFromSource";
|
|
38
|
-
|
|
39
|
-
export type { LinkProps, RouteState } from "./types";
|
|
40
|
-
|
|
41
|
-
export type { RouterErrorBoundaryProps } from "./components/RouterErrorBoundary";
|
|
42
|
-
|
|
43
|
-
export type { LinkDirectiveOptions } from "./directives/link";
|
|
44
|
-
|
|
45
|
-
export type {
|
|
46
|
-
RouteViewProps,
|
|
47
|
-
RouteViewMatchProps,
|
|
48
|
-
RouteViewSelfProps,
|
|
49
|
-
RouteViewNotFoundProps,
|
|
50
|
-
} from "./components/RouteView";
|
|
51
|
-
|
|
52
|
-
export type {
|
|
53
|
-
RouteExitContext,
|
|
54
|
-
RouteExitHandler,
|
|
55
|
-
UseRouteExitOptions,
|
|
56
|
-
} from "./hooks/useRouteExit";
|
|
57
|
-
|
|
58
|
-
export type {
|
|
59
|
-
RouteEnterContext,
|
|
60
|
-
RouteEnterHandler,
|
|
61
|
-
UseRouteEnterOptions,
|
|
62
|
-
} from "./hooks/useRouteEnter";
|
|
63
|
-
|
|
64
|
-
export type { Navigator } from "@real-router/core";
|
|
65
|
-
|
|
66
|
-
export type { RouterTransitionSnapshot } from "@real-router/sources";
|
package/src/ssr.tsx
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
// SSR-feature entry — Solid 1.7+
|
|
2
|
-
//
|
|
3
|
-
// Server-side and SSR-aware components/hooks. Mirror of `@real-router/react/ssr`
|
|
4
|
-
// — same exports, Solid-native idioms (Accessor returns, createResource-backed
|
|
5
|
-
// Await, native Suspense for Streamed).
|
|
6
|
-
|
|
7
|
-
// Components
|
|
8
|
-
export { ClientOnly } from "./components/ClientOnly";
|
|
9
|
-
|
|
10
|
-
export { ServerOnly } from "./components/ServerOnly";
|
|
11
|
-
|
|
12
|
-
export { Await } from "./components/Await";
|
|
13
|
-
|
|
14
|
-
export { Streamed } from "./components/Streamed";
|
|
15
|
-
|
|
16
|
-
export { HttpStatusCode } from "./components/HttpStatusCode";
|
|
17
|
-
|
|
18
|
-
export { HttpStatusProvider } from "./components/HttpStatusProvider";
|
|
19
|
-
|
|
20
|
-
// Hooks
|
|
21
|
-
export { useDeferred } from "./hooks/useDeferred";
|
|
22
|
-
|
|
23
|
-
// Utilities
|
|
24
|
-
export { createHttpStatusSink } from "./utils/createHttpStatusSink";
|
|
25
|
-
|
|
26
|
-
// Types
|
|
27
|
-
export type { ClientOnlyProps } from "./components/ClientOnly";
|
|
28
|
-
|
|
29
|
-
export type { ServerOnlyProps } from "./components/ServerOnly";
|
|
30
|
-
|
|
31
|
-
export type { AwaitProps } from "./components/Await";
|
|
32
|
-
|
|
33
|
-
export type { StreamedProps } from "./components/Streamed";
|
|
34
|
-
|
|
35
|
-
export type { HttpStatusCodeProps } from "./components/HttpStatusCode";
|
|
36
|
-
|
|
37
|
-
export type { HttpStatusProviderProps } from "./components/HttpStatusProvider";
|
|
38
|
-
|
|
39
|
-
export type { HttpStatusSink } from "./utils/createHttpStatusSink";
|
package/src/types.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { NavigationOptions, Params, State } from "@real-router/core";
|
|
2
|
-
import type { JSX } from "solid-js";
|
|
3
|
-
|
|
4
|
-
export interface RouteState<P extends Params = Params> {
|
|
5
|
-
route: State<P> | undefined;
|
|
6
|
-
previousRoute?: State | undefined;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface LinkProps<P extends Params = Params> extends Omit<
|
|
10
|
-
JSX.HTMLAttributes<HTMLAnchorElement>,
|
|
11
|
-
"onClick"
|
|
12
|
-
> {
|
|
13
|
-
routeName: string;
|
|
14
|
-
routeParams?: P;
|
|
15
|
-
routeOptions?: NavigationOptions;
|
|
16
|
-
activeClassName?: string;
|
|
17
|
-
activeStrict?: boolean;
|
|
18
|
-
ignoreQueryParams?: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* URL fragment (decoded form, no leading "#") (#532).
|
|
21
|
-
* - omitted/`undefined` → preserve current fragment on same-route navigation
|
|
22
|
-
* - `""` → clear fragment
|
|
23
|
-
* - non-empty → set fragment
|
|
24
|
-
*/
|
|
25
|
-
hash?: string;
|
|
26
|
-
target?: string;
|
|
27
|
-
onClick?: (evt: MouseEvent) => void;
|
|
28
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Render-scoped HTTP status sink. Created per request on the server, passed to
|
|
3
|
-
* `<HttpStatusProvider sink={...}>`, and read after `renderToString` /
|
|
4
|
-
* `renderToStream` to apply the value to the HTTP response.
|
|
5
|
-
*
|
|
6
|
-
* Last write wins: if the rendered tree mounts more than one
|
|
7
|
-
* `<HttpStatusCode />`, the value reflects the last component that ran during
|
|
8
|
-
* the render pass.
|
|
9
|
-
*
|
|
10
|
-
* No-op on the client — `<HttpStatusCode />` reads the optional context and
|
|
11
|
-
* skips the write when no provider is mounted, so the same component tree can
|
|
12
|
-
* be hydrated without changing behaviour.
|
|
13
|
-
*
|
|
14
|
-
* Constraints:
|
|
15
|
-
* - **Per-request only.** Don't share a sink across requests; the rendered
|
|
16
|
-
* tree mutates `code` in place. Module-level singletons leak status
|
|
17
|
-
* between concurrent requests.
|
|
18
|
-
* - **Don't `Object.freeze` the sink.** The component writes to `.code`;
|
|
19
|
-
* freezing makes the assignment throw under ESM strict mode.
|
|
20
|
-
* - **Hydration symmetry:** mount `<HttpStatusProvider>` on both server and
|
|
21
|
-
* client (with a throwaway client sink). Solid emits `data-hk` markers
|
|
22
|
-
* per component boundary; an extra provider on one side desyncs the
|
|
23
|
-
* counter and breaks the hydration walker.
|
|
24
|
-
*/
|
|
25
|
-
export interface HttpStatusSink {
|
|
26
|
-
code: number | undefined;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function createHttpStatusSink(): HttpStatusSink {
|
|
30
|
-
return { code: undefined };
|
|
31
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { createSignal, onMount } from "solid-js";
|
|
2
|
-
|
|
3
|
-
import type { Accessor } from "solid-js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Returns a boolean accessor that is `false` during initial render (SSR
|
|
7
|
-
* and the first client paint) and flips to `true` once the component
|
|
8
|
-
* has mounted in the browser.
|
|
9
|
-
*
|
|
10
|
-
* Solid guarantees that `onMount` does NOT fire during `renderToString` /
|
|
11
|
-
* `renderToStream`, so the accessor stays `false` server-side — this is
|
|
12
|
-
* the building block for SSR boundary components (`<ClientOnly>` /
|
|
13
|
-
* `<ServerOnly>`).
|
|
14
|
-
*
|
|
15
|
-
* Consolidates the identical `createSignal(false) + onMount(setMounted)`
|
|
16
|
-
* pattern across the two boundary components (§8a Q15).
|
|
17
|
-
*/
|
|
18
|
-
export function createMountedSignal(): Accessor<boolean> {
|
|
19
|
-
const [mounted, setMounted] = createSignal(false);
|
|
20
|
-
|
|
21
|
-
onMount(() => {
|
|
22
|
-
setMounted(true);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
return mounted;
|
|
26
|
-
}
|