@nifrajs/web-solid 5.5.0 → 5.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +107 -0
- package/dist/client.js +2 -2
- package/dist/client.js.map +1 -1
- package/dist/content.d.ts +1 -1
- package/dist/content.js +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -2
- package/dist/index.js.map +1 -1
- package/dist/keep-alive-view.d.ts +35 -0
- package/dist/keep-alive-view.d.ts.map +1 -0
- package/dist/keep-alive-view.js +135 -0
- package/dist/keep-alive-view.js.map +1 -0
- package/dist/keep-alive.d.ts +25 -0
- package/dist/keep-alive.d.ts.map +1 -0
- package/dist/keep-alive.js +51 -0
- package/dist/keep-alive.js.map +1 -0
- package/dist/mdx.d.ts.map +1 -1
- package/dist/mdx.js +5 -16
- package/dist/mdx.js.map +1 -1
- package/dist/page-visibility.d.ts +28 -0
- package/dist/page-visibility.d.ts.map +1 -0
- package/dist/page-visibility.js +42 -0
- package/dist/page-visibility.js.map +1 -0
- package/dist/ppr-client.d.ts +9 -0
- package/dist/ppr-client.d.ts.map +1 -0
- package/dist/ppr-client.js +63 -0
- package/dist/ppr-client.js.map +1 -0
- package/dist/ppr.d.ts +37 -0
- package/dist/ppr.d.ts.map +1 -0
- package/dist/ppr.js +61 -0
- package/dist/ppr.js.map +1 -0
- package/dist/query.d.ts +4 -3
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +7 -8
- package/dist/query.js.map +1 -1
- package/dist/route-props.d.ts +5 -2
- package/dist/route-props.d.ts.map +1 -1
- package/dist/route-props.js +16 -7
- package/dist/route-props.js.map +1 -1
- package/dist/router.d.ts +3 -2
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +7 -3
- package/dist/router.js.map +1 -1
- package/dist/server-components/Outlet.jsx +1 -1
- package/dist/server-components/Outlet.jsx.map +1 -1
- package/package.json +16 -5
- package/src/client.ts +2 -2
- package/src/content.ts +1 -1
- package/src/index.ts +48 -4
- package/src/keep-alive-view.ts +202 -0
- package/src/keep-alive.ts +76 -0
- package/src/mdx.ts +5 -9
- package/src/page-visibility.ts +53 -0
- package/src/ppr-client.ts +77 -0
- package/src/ppr.ts +86 -0
- package/src/query.ts +13 -8
- package/src/route-props.ts +16 -6
- package/src/router.ts +8 -3
- package/src/server-components/Outlet.tsx +1 -1
package/src/route-props.ts
CHANGED
|
@@ -5,16 +5,22 @@ import { searchOfChain } from "@nifrajs/web/client"
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The client half of the server's `RenderProps`, as getters so a settle re-renders only what reads the
|
|
8
|
-
* changed field.
|
|
8
|
+
* changed field. `derive` is `createMemo` on the client mount: `data` and `layoutData` then notify only
|
|
9
|
+
* when they change identity, so a reload that kept them (the router shares what it did not change)
|
|
10
|
+
* re-runs nothing that reads them - a `<For>` keeps its rows. Cast: a getter always exists where
|
|
11
|
+
* `exactOptionalPropertyTypes` expects absence.
|
|
9
12
|
*/
|
|
10
13
|
export function routeProps(
|
|
11
14
|
snapshot: () => RouterState,
|
|
12
15
|
searchSchemas: MountRouterOptions["searchSchemas"],
|
|
13
16
|
matchChains?: MountRouterOptions["matchChains"],
|
|
17
|
+
derive: <T>(read: () => T) => () => T = (read) => read,
|
|
14
18
|
): RenderProps {
|
|
19
|
+
const data = derive(() => snapshot().data)
|
|
20
|
+
const layoutData = derive(() => snapshot().layoutData)
|
|
15
21
|
return {
|
|
16
22
|
get data() {
|
|
17
|
-
return
|
|
23
|
+
return data()
|
|
18
24
|
},
|
|
19
25
|
// Each layout's own loader data. Without it a layout renders `data: null` on the client while the
|
|
20
26
|
// server rendered it with its data.
|
|
@@ -22,7 +28,7 @@ export function routeProps(
|
|
|
22
28
|
return snapshot().serverComponents
|
|
23
29
|
},
|
|
24
30
|
get layoutData() {
|
|
25
|
-
return
|
|
31
|
+
return layoutData()
|
|
26
32
|
},
|
|
27
33
|
get actionData() {
|
|
28
34
|
return snapshot().actionData
|
|
@@ -34,15 +40,19 @@ export function routeProps(
|
|
|
34
40
|
get params() {
|
|
35
41
|
return snapshot().params
|
|
36
42
|
},
|
|
43
|
+
// While an intercept boundary holds a target the URL is the target's; the route's props describe
|
|
44
|
+
// the page underneath, so they read the page's own path.
|
|
37
45
|
get path() {
|
|
38
|
-
|
|
46
|
+
const s = snapshot()
|
|
47
|
+
return s.intercepted?.pagePath ?? s.path
|
|
39
48
|
},
|
|
40
49
|
get search() {
|
|
41
50
|
// The SAME searchOfChain the server ran, over this snapshot's URL - a same-route search change
|
|
42
51
|
// updates in place (fine-grained), matching the SSR value on hydration.
|
|
43
52
|
const s = snapshot()
|
|
44
|
-
const
|
|
45
|
-
|
|
53
|
+
const path = s.intercepted?.pagePath ?? s.path
|
|
54
|
+
const idx = path.indexOf("?")
|
|
55
|
+
return searchOfChain(searchSchemas?.[s.routeId] ?? [], idx === -1 ? "" : path.slice(idx))
|
|
46
56
|
},
|
|
47
57
|
get submission() {
|
|
48
58
|
return snapshot().submission
|
package/src/router.ts
CHANGED
|
@@ -38,7 +38,9 @@ import {
|
|
|
38
38
|
onCleanup,
|
|
39
39
|
useContext,
|
|
40
40
|
} from "solid-js"
|
|
41
|
+
import { PageContext } from "./page-visibility.ts"
|
|
41
42
|
|
|
43
|
+
export { onPageHide, onPageShow, usePageVisibility } from "./page-visibility.ts"
|
|
42
44
|
export type { Blocker, BlockerFunction, BlockerState, NavigateFunction, UIMatch }
|
|
43
45
|
|
|
44
46
|
// Frozen empty search + a stable accessor for a `useSearch` used outside a nifra route tree.
|
|
@@ -126,17 +128,20 @@ export function useNavigate(): NavigateFunction {
|
|
|
126
128
|
* predicate, and get back a reactive {@link Blocker} accessor. When a navigation (an anchor click,
|
|
127
129
|
* `useNavigate`, or a browser back/forward) is intercepted, `blocker().state` becomes `"blocked"` and
|
|
128
130
|
* `proceed`/`reset` go live - show a dialog and call `proceed()` to continue or `reset()` to stay put.
|
|
129
|
-
* It also arms the browser's native "Leave site?" prompt on tab close / reload. Idle on the server
|
|
130
|
-
* before hydration.
|
|
131
|
+
* It also arms the browser's native "Leave site?" prompt on tab close / reload. Idle on the server,
|
|
132
|
+
* before hydration, and while a `keepAlive` page is hidden.
|
|
131
133
|
*
|
|
132
134
|
* The component body runs once, so to track a CHANGING flag pass a function -
|
|
133
135
|
* `useBlocker(() => isDirty())` - not a bare signal accessor's current value. A constant boolean is fine.
|
|
134
136
|
*/
|
|
135
137
|
export function useBlocker(shouldBlock: boolean | BlockerFunction): Accessor<Blocker> {
|
|
136
138
|
const [blocker, setBlocker] = createSignal<Blocker>(IDLE_BLOCKER)
|
|
139
|
+
const slot = useContext(PageContext)
|
|
137
140
|
onCleanup(
|
|
138
141
|
registerBlocker(
|
|
139
|
-
(args) =>
|
|
142
|
+
(args) =>
|
|
143
|
+
slot?.hidden() !== true &&
|
|
144
|
+
(typeof shouldBlock === "function" ? shouldBlock(args) : shouldBlock),
|
|
140
145
|
setBlocker,
|
|
141
146
|
),
|
|
142
147
|
)
|
|
@@ -61,7 +61,7 @@ function Range(props: {
|
|
|
61
61
|
if (controller !== undefined)
|
|
62
62
|
void (props.controller === undefined
|
|
63
63
|
? controller.dispose()
|
|
64
|
-
: controller.unmount(record.instance))
|
|
64
|
+
: controller.unmount(record.instance, host))
|
|
65
65
|
})
|
|
66
66
|
createEffect(() => {
|
|
67
67
|
const state = props.state
|