@nifrajs/web-solid 5.9.0 → 5.10.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 +41 -0
- package/dist/compose.d.ts.map +1 -1
- package/dist/compose.js +3 -1
- package/dist/compose.js.map +1 -1
- package/dist/image.d.ts +4 -3
- package/dist/image.d.ts.map +1 -1
- package/dist/image.js +16 -6
- package/dist/image.js.map +1 -1
- package/dist/ppr.d.ts +1 -1
- package/dist/ppr.js +1 -1
- package/dist/query.d.ts +43 -4
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +73 -5
- package/dist/query.js.map +1 -1
- package/dist/router.d.ts +2 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +2 -1
- package/dist/router.js.map +1 -1
- package/package.json +5 -5
- package/src/compose.ts +3 -1
- package/src/image.ts +28 -7
- package/src/ppr.ts +1 -1
- package/src/query.ts +145 -6
- package/src/router.ts +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @nifrajs/web-solid
|
|
2
2
|
|
|
3
|
+
## 5.10.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 611a3be: Expose mutation and infinite-query bindings across the framework adapters, with request-scoped query-client providers and SSR cache hydration. Mutation functions and callbacks receive a cooperative abort signal, and identity changes cancel pending work across tabs. `dehydrate` can filter regular and infinite query values before they are serialized to the browser.
|
|
8
|
+
- d2066e0: Add opt-in local `?image` metadata imports and content-hashed build-time responsive variants using the existing injectable image backends. Emit images with client, SSR and static builds, and infer imported dimensions in all five UI adapters. String image URLs retain their existing dimension requirements.
|
|
9
|
+
|
|
10
|
+
Add explicit static translated-path mappings to i18n routing, with reciprocal URL/SEO helpers, availability-aware redirects and static-path enumeration. These mappings do not implicitly create filesystem route aliases.
|
|
11
|
+
|
|
12
|
+
Add `vercelRuntime: "node"` for ordinary SSR Vercel builds through both bundlers, using a shared streaming Node request bridge. Vercel Edge remains the default.
|
|
13
|
+
- 824a75e: Partial prerendering is no longer experimental. `createWebApp` takes it as `ppr`, where it was `experimental.ppr`, and the `experimental` option is gone: passing it throws a `TypeError` that names `ppr`, and the startup errors name `ppr.origin`, `ppr.deployment` and `ppr.store`. `nifra upgrade` moves `experimental: { ppr }` to `ppr` in a `createWebApp` options literal and lists any other `experimental` shape it finds there by line (options spread in, or built in another file, are yours to check). `nifra scaffold` is stable.
|
|
14
|
+
- 1faf86c: `href({ to, params, search, hash })` builds an in-app URL from a route pattern and returns an `Href`; `rawHref(path)` returns one for a same-origin path built elsewhere (a CMS link, `/llms.txt`). `to` is a key of the generated `RouteTable`, so a misspelt route, a missing, misspelt or extra param, and a `search` that breaks the route's schema are compile errors. A route without a `searchSchema` takes any `search`. Each param is encoded as one path segment, so a value such as `a/b` or `//evil.com` cannot change where the URL goes; a param that is missing, empty, `.`, `..` or an unpaired surrogate throws a `TypeError` naming it and the pattern. `rawHref` throws a `TypeError` unless `isSameOriginPath` accepts the path. Both are exported by `@nifrajs/web` and by the `/router` entry of every adapter.
|
|
15
|
+
|
|
16
|
+
`navigate` takes an `Href` or a history delta. A string, a template literal and the `{ to, search }` object form are compile errors, and a value forged past the types is still held to the same-origin check the browser navigate makes. `<Navigate to>` and the `useSearchParams` setter in `@nifrajs/web-react` pass their path through `rawHref`, so an off-origin `to` throws instead of doing nothing. `isSameOriginPath` is exported from `@nifrajs/core/pattern` as well as `@nifrajs/core/server`.
|
|
17
|
+
|
|
18
|
+
Upgrade: `navigate("/users/7")` becomes `navigate(href({ to: "/users/:id", params: { id: "7" } }))`, `navigate({ to, search, replace: true })` becomes `navigate(href({ to, search }), { replace: true })`, and a path built elsewhere is `navigate(rawHref(path))`. `resolveNavigate`, `NavigateTargetInput` and `NavigateSearchOf` are removed from `@nifrajs/web`.
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- 2c361be: Opening a modal route on a Solid page no longer rebuilds the page. A layout was handed the `boundaries` value rather than a getter over it, so an intercept boundary taking its target re-ran the whole chain: a typed input lost its text and every component remounted. The page now stays mounted underneath, as the other adapters keep it.
|
|
23
|
+
- Updated dependencies [535c4e5]
|
|
24
|
+
- Updated dependencies [87e7fd9]
|
|
25
|
+
- Updated dependencies [611a3be]
|
|
26
|
+
- Updated dependencies [7f32bb2]
|
|
27
|
+
- Updated dependencies [0aa10d0]
|
|
28
|
+
- Updated dependencies [ab69ee6]
|
|
29
|
+
- Updated dependencies [548bade]
|
|
30
|
+
- Updated dependencies [d2066e0]
|
|
31
|
+
- Updated dependencies [7e292dd]
|
|
32
|
+
- Updated dependencies [a6af4c9]
|
|
33
|
+
- Updated dependencies [e465ed5]
|
|
34
|
+
- Updated dependencies [683c3d6]
|
|
35
|
+
- Updated dependencies [824a75e]
|
|
36
|
+
- Updated dependencies [d2066e0]
|
|
37
|
+
- Updated dependencies [5845e1c]
|
|
38
|
+
- Updated dependencies [5d1be78]
|
|
39
|
+
- Updated dependencies [1faf86c]
|
|
40
|
+
- Updated dependencies [950996b]
|
|
41
|
+
- @nifrajs/web@5.10.0
|
|
42
|
+
- @nifrajs/core@5.10.0
|
|
43
|
+
|
|
3
44
|
## 5.9.0
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
package/dist/compose.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAmC,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAMpE;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAmC,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAMpE;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,CAAC,OAAO,CAqCxF"}
|
package/dist/compose.js
CHANGED
|
@@ -25,7 +25,9 @@ export function compose(chain, props) {
|
|
|
25
25
|
get data() {
|
|
26
26
|
return props.layoutData?.[i] ?? null;
|
|
27
27
|
},
|
|
28
|
-
|
|
28
|
+
get boundaries() {
|
|
29
|
+
return props.boundaries;
|
|
30
|
+
},
|
|
29
31
|
children: child(),
|
|
30
32
|
});
|
|
31
33
|
}
|
package/dist/compose.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,eAAe,EAAY,MAAM,UAAU,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE/D,sFAAsF;AACtF,MAAM,YAAY,GAAsC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAEzE;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,KAAyB,EAAE,KAAkB;IACnE,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IAC7B,IAAI,IAAI,GAAsB,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAA2B,EAAE,KAAK,CAAC,CAAA;IACjG,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAyC,CAAA;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAA;QAClB,6FAA6F;QAC7F,mGAAmG;QACnG,kEAAkE;QAClE,0FAA0F;QAC1F,6EAA6E;QAC7E,IAAI,GAAG,GAAG,EAAE,CACV,eAAe,CAAC,MAAM,EAAE;YACtB,IAAI,IAAI;gBACN,OAAO,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAA;YACtC,CAAC;YACD,
|
|
1
|
+
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,eAAe,EAAY,MAAM,UAAU,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE/D,sFAAsF;AACtF,MAAM,YAAY,GAAsC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAEzE;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,KAAyB,EAAE,KAAkB;IACnE,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IAC7B,IAAI,IAAI,GAAsB,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAA2B,EAAE,KAAK,CAAC,CAAA;IACjG,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAyC,CAAA;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAA;QAClB,6FAA6F;QAC7F,mGAAmG;QACnG,kEAAkE;QAClE,0FAA0F;QAC1F,6EAA6E;QAC7E,IAAI,GAAG,GAAG,EAAE,CACV,eAAe,CAAC,MAAM,EAAE;YACtB,IAAI,IAAI;gBACN,OAAO,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAA;YACtC,CAAC;YACD,IAAI,UAAU;gBACZ,OAAO,KAAK,CAAC,UAAU,CAAA;YACzB,CAAC;YACD,QAAQ,EAAE,KAAK,EAAE;SAClB,CAAC,CAAA;IACN,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAA;IAClB,qGAAqG;IACrG,sFAAsF;IACtF,OAAO,GAAG,EAAE,CACV,eAAe,CAAC,aAAa,CAAC,QAAQ,EAAE;QACtC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,YAAY,CAA4B;QACtE,IAAI,QAAQ;YACV,OAAO,eAAe,CAAC,kBAAkB,CAAC,QAAQ,EAAE;gBAClD,KAAK,EAAE,KAAK;gBACZ,IAAI,QAAQ;oBACV,OAAO,KAAK,EAAE,CAAA;gBAChB,CAAC;aACF,CAAC,CAAA;QACJ,CAAC;KACF,CAAC,CAAA;AACN,CAAC"}
|
package/dist/image.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* reactively (`splitProps`/`mergeProps`). Resizing is delegated to the `loader`; nifra bundles no codec.
|
|
7
7
|
* No JSX (`createComponent`/`Dynamic`), so the package builds with plain `tsc`.
|
|
8
8
|
*/
|
|
9
|
-
import { type ImageLoader, type ImageProps } from "@nifrajs/image";
|
|
9
|
+
import { type ImageLoader, type ImageProps, type StaticImageProps } from "@nifrajs/image";
|
|
10
10
|
import { type JSX } from "solid-js";
|
|
11
11
|
/** Attributes `resolveImage` computes - callers can't override them via DOM passthrough. */
|
|
12
12
|
type ComputedAttrs = "src" | "srcset" | "sizes" | "width" | "height" | "alt" | "loading" | "decoding" | "fetchpriority";
|
|
@@ -14,10 +14,11 @@ export interface ImageComponentProps extends ImageProps, Omit<JSX.ImgHTMLAttribu
|
|
|
14
14
|
/** CDN URL builder. Defaults to the identity loader (no transform - still CLS-safe + lazy). */
|
|
15
15
|
readonly loader?: ImageLoader;
|
|
16
16
|
}
|
|
17
|
+
export type StaticImageComponentProps = StaticImageProps & Omit<ImageComponentProps, "src" | "width" | "height">;
|
|
17
18
|
/**
|
|
18
|
-
* Render a responsive, CLS-safe `<img>`.
|
|
19
|
+
* Render a responsive, CLS-safe `<img>`. String URLs require dimensions; asset imports infer them;
|
|
19
20
|
* `priority` marks the LCP image (`eager` + `fetchpriority="high"`). Extra DOM props pass through.
|
|
20
21
|
*/
|
|
21
|
-
export declare function Image(props: ImageComponentProps): JSX.Element;
|
|
22
|
+
export declare function Image(props: ImageComponentProps | StaticImageComponentProps): JSX.Element;
|
|
22
23
|
export {};
|
|
23
24
|
//# sourceMappingURL=image.d.ts.map
|
package/dist/image.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,UAAU,EAEf,KAAK,gBAAgB,EAEtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAmB,KAAK,GAAG,EAA0B,MAAM,UAAU,CAAA;AAG5E,4FAA4F;AAC5F,KAAK,aAAa,GACd,KAAK,GACL,QAAQ,GACR,OAAO,GACP,OAAO,GACP,QAAQ,GACR,KAAK,GACL,SAAS,GACT,UAAU,GACV,eAAe,CAAA;AAEnB,MAAM,WAAW,mBACf,SAAQ,UAAU,EAChB,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,EAAE,aAAa,GAAG,MAAM,UAAU,CAAC;IACjF,+FAA+F;IAC/F,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B;AAED,MAAM,MAAM,yBAAyB,GAAG,gBAAgB,GACtD,IAAI,CAAC,mBAAmB,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAA;AAEvD;;;GAGG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,mBAAmB,GAAG,yBAAyB,GAAG,GAAG,CAAC,OAAO,CA2CzF"}
|
package/dist/image.js
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
* reactively (`splitProps`/`mergeProps`). Resizing is delegated to the `loader`; nifra bundles no codec.
|
|
7
7
|
* No JSX (`createComponent`/`Dynamic`), so the package builds with plain `tsc`.
|
|
8
8
|
*/
|
|
9
|
-
import { resolveImage, toHtmlAttrs } from "@nifrajs/image";
|
|
9
|
+
import { resolveImage, toHtmlAttrs, } from "@nifrajs/image";
|
|
10
10
|
import { createComponent, mergeProps, splitProps } from "solid-js";
|
|
11
11
|
import { Dynamic } from "solid-js/web";
|
|
12
12
|
/**
|
|
13
|
-
* Render a responsive, CLS-safe `<img>`.
|
|
13
|
+
* Render a responsive, CLS-safe `<img>`. String URLs require dimensions; asset imports infer them;
|
|
14
14
|
* `priority` marks the LCP image (`eager` + `fetchpriority="high"`). Extra DOM props pass through.
|
|
15
15
|
*/
|
|
16
16
|
export function Image(props) {
|
|
@@ -31,10 +31,7 @@ export function Image(props) {
|
|
|
31
31
|
const attrs = () => {
|
|
32
32
|
// Build ImageProps via conditional spreads (exactOptionalPropertyTypes: an unset optional is
|
|
33
33
|
// absent, not `undefined`). resolveImage validates width/height > 0 (CLS contract).
|
|
34
|
-
const
|
|
35
|
-
src: props.src,
|
|
36
|
-
width: props.width,
|
|
37
|
-
height: props.height,
|
|
34
|
+
const common = {
|
|
38
35
|
alt: props.alt,
|
|
39
36
|
...(props.sizes !== undefined ? { sizes: props.sizes } : {}),
|
|
40
37
|
...(props.widths !== undefined ? { widths: props.widths } : {}),
|
|
@@ -42,6 +39,19 @@ export function Image(props) {
|
|
|
42
39
|
...(props.loading !== undefined ? { loading: props.loading } : {}),
|
|
43
40
|
...(props.priority !== undefined ? { priority: props.priority } : {}),
|
|
44
41
|
};
|
|
42
|
+
const input = typeof props.src === "string"
|
|
43
|
+
? {
|
|
44
|
+
...common,
|
|
45
|
+
src: props.src,
|
|
46
|
+
width: props.width ?? Number.NaN,
|
|
47
|
+
height: props.height ?? Number.NaN,
|
|
48
|
+
}
|
|
49
|
+
: {
|
|
50
|
+
...common,
|
|
51
|
+
src: props.src,
|
|
52
|
+
...(props.width !== undefined ? { width: props.width } : {}),
|
|
53
|
+
...(props.height !== undefined ? { height: props.height } : {}),
|
|
54
|
+
};
|
|
45
55
|
return toHtmlAttrs(resolveImage(input, props.loader));
|
|
46
56
|
};
|
|
47
57
|
return createComponent(Dynamic, mergeProps(rest, attrs, { component: "img" }));
|
package/dist/image.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.js","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAIL,YAAY,EAEZ,WAAW,GACZ,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,eAAe,EAAY,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAwBtC;;;GAGG;AACH,MAAM,UAAU,KAAK,CAAC,KAAsD;IAC1E,sGAAsG;IACtG,iGAAiG;IACjG,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE;QACjC,QAAQ;QACR,QAAQ;QACR,SAAS;QACT,UAAU;QACV,KAAK;QACL,OAAO;QACP,QAAQ;QACR,KAAK;QACL,OAAO;QACP,SAAS;KACV,CAAC,CAAA;IACF,MAAM,KAAK,GAAG,GAAmC,EAAE;QACjD,6FAA6F;QAC7F,oFAAoF;QACpF,MAAM,MAAM,GAAG;YACb,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5D,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/D,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtE,CAAA;QACD,MAAM,KAAK,GACT,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;YAC3B,CAAC,CAAC;gBACE,GAAG,MAAM;gBACT,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,GAAG;gBAChC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG;aACnC;YACH,CAAC,CAAC;gBACE,GAAG,MAAM;gBACT,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5D,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChE,CAAA;QACP,OAAO,WAAW,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;IACvD,CAAC,CAAA;IACD,OAAO,eAAe,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;AAChF,CAAC"}
|
package/dist/ppr.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface HoleProps<Data> {
|
|
|
17
17
|
readonly error?: JSX.Element;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* One `dynamic` or `shared` boundary of a partially prerendered page.
|
|
21
21
|
*
|
|
22
22
|
* In a shared shell the hole is an empty host Solid never fills: the PPR runtime puts the server's
|
|
23
23
|
* HTML into it, and an interactive hole then hydrates as its own root from the frame's props. When the
|
package/dist/ppr.js
CHANGED
|
@@ -18,7 +18,7 @@ function openHost(hole, fill) {
|
|
|
18
18
|
return clientHost(hole.name, hole.render, hole.interactive === true, attributes, fill);
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* One `dynamic` or `shared` boundary of a partially prerendered page.
|
|
22
22
|
*
|
|
23
23
|
* In a shared shell the hole is an empty host Solid never fills: the PPR runtime puts the server's
|
|
24
24
|
* HTML into it, and an interactive hole then hydrates as its own root from the frame's props. When the
|
package/dist/query.d.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
import type { QueryClient, QueryOptions, QueryState } from "@nifrajs/web";
|
|
1
|
+
import type { DehydratedState, InfiniteData, InfiniteQueryOptions, MutationCallbacks, MutationContext, MutationState, QueryClient, QueryOptions, QueryState } from "@nifrajs/web";
|
|
2
2
|
/**
|
|
3
3
|
* `@nifrajs/web-solid/query` - Solid bindings for the keyed query-cache. `createQuery(key, fn)` bridges a
|
|
4
4
|
* query's `subscribe`/`snapshot` store into a Solid signal and fetches on mount; `useQueryClient`
|
|
5
5
|
* exposes `invalidateQueries` for after a mutation. Imports only `solid-js` + `@nifrajs/web` (never
|
|
6
6
|
* `solid-js/web`), so route components use it on the server *and* client. No JSX.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* accessor returns
|
|
8
|
+
* Without a provider, the query client is created lazily **client-side only** (`typeof window`) - on
|
|
9
|
+
* the server the accessor returns idle state and route loaders remain the data source. A
|
|
10
|
+
* `QueryClientProvider` can supply a request-scoped hydrated client.
|
|
10
11
|
* The `key` is captured once (Solid setup runs once); a reactive key is a documented future enhancement.
|
|
11
12
|
*/
|
|
12
|
-
import { type Accessor } from "solid-js";
|
|
13
|
+
import { type Accessor, type JSX } from "solid-js";
|
|
14
|
+
/** Provide a request-scoped client and optionally seed it before descendants run. */
|
|
15
|
+
export declare function QueryClientProvider(props: {
|
|
16
|
+
readonly client: QueryClient;
|
|
17
|
+
readonly state?: DehydratedState;
|
|
18
|
+
readonly children?: JSX.Element;
|
|
19
|
+
}): JSX.Element;
|
|
13
20
|
/** Access the query client to imperatively `invalidateQueries(keyOrPrefix)` (e.g. after a mutation). */
|
|
14
21
|
export declare function useQueryClient(): Pick<QueryClient, "invalidateQueries">;
|
|
15
22
|
/** A query's reactive state accessor plus `refetch`. */
|
|
@@ -26,4 +33,36 @@ export interface CreateQueryResult<T> {
|
|
|
26
33
|
* the live keys that refetch it.
|
|
27
34
|
*/
|
|
28
35
|
export declare function createQuery<T>(key: unknown, fn: () => Promise<T>, options?: QueryOptions): CreateQueryResult<T>;
|
|
36
|
+
/** A mutation result expressed as Solid accessors and imperative controls. */
|
|
37
|
+
export interface CreateMutationResult<TData, TVariables> {
|
|
38
|
+
readonly state: Accessor<MutationState<TData, TVariables>>;
|
|
39
|
+
readonly isIdle: Accessor<boolean>;
|
|
40
|
+
readonly isPending: Accessor<boolean>;
|
|
41
|
+
readonly isError: Accessor<boolean>;
|
|
42
|
+
readonly isSuccess: Accessor<boolean>;
|
|
43
|
+
readonly mutate: (variables: TVariables) => void;
|
|
44
|
+
readonly mutateAsync: (variables: TVariables) => Promise<TData>;
|
|
45
|
+
readonly reset: () => void;
|
|
46
|
+
readonly cancel: () => void;
|
|
47
|
+
}
|
|
48
|
+
/** Bind a mutation to a Solid owner. Identity changes discard late results and callbacks. */
|
|
49
|
+
export declare function createMutation<TData, TVariables = void>(fn: (variables: TVariables, context: MutationContext) => Promise<TData>, callbacks?: MutationCallbacks<TData, TVariables>): CreateMutationResult<TData, TVariables>;
|
|
50
|
+
/** Options for a Solid infinite query. */
|
|
51
|
+
export interface CreateInfiniteQueryOptions<T, P> extends InfiniteQueryOptions<T, P> {
|
|
52
|
+
readonly enabled?: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** Infinite-query state and page controls expressed as Solid accessors. */
|
|
55
|
+
export interface CreateInfiniteQueryResult<T, P> {
|
|
56
|
+
readonly state: Accessor<QueryState<InfiniteData<T, P>>>;
|
|
57
|
+
readonly isPending: Accessor<boolean>;
|
|
58
|
+
readonly isError: Accessor<boolean>;
|
|
59
|
+
readonly isSuccess: Accessor<boolean>;
|
|
60
|
+
readonly hasNextPage: Accessor<boolean>;
|
|
61
|
+
readonly hasPreviousPage: Accessor<boolean>;
|
|
62
|
+
readonly fetchNextPage: () => Promise<InfiniteData<T, P>>;
|
|
63
|
+
readonly fetchPreviousPage: () => Promise<InfiniteData<T, P>>;
|
|
64
|
+
readonly refetch: () => Promise<InfiniteData<T, P>>;
|
|
65
|
+
}
|
|
66
|
+
/** Bind a paged query to a Solid owner and fetch its first page on mount. */
|
|
67
|
+
export declare function createInfiniteQuery<T, P>(key: unknown, fn: (pageParam: P) => Promise<T>, options: CreateInfiniteQueryOptions<T, P>): CreateInfiniteQueryResult<T, P>;
|
|
29
68
|
//# sourceMappingURL=query.d.ts.map
|
package/dist/query.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
|
package/dist/query.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createMutation as createMutationHandle } from "@nifrajs/web/client";
|
|
1
2
|
import { createNoClientRefetch, fetchOnMount, getQueryClientSingleton, IDLE_QUERY_STATE, noop, } from "@nifrajs/web/internal/query-runtime";
|
|
2
3
|
/**
|
|
3
4
|
* `@nifrajs/web-solid/query` - Solid bindings for the keyed query-cache. `createQuery(key, fn)` bridges a
|
|
@@ -5,14 +6,30 @@ import { createNoClientRefetch, fetchOnMount, getQueryClientSingleton, IDLE_QUER
|
|
|
5
6
|
* exposes `invalidateQueries` for after a mutation. Imports only `solid-js` + `@nifrajs/web` (never
|
|
6
7
|
* `solid-js/web`), so route components use it on the server *and* client. No JSX.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
* accessor returns
|
|
9
|
+
* Without a provider, the query client is created lazily **client-side only** (`typeof window`) - on
|
|
10
|
+
* the server the accessor returns idle state and route loaders remain the data source. A
|
|
11
|
+
* `QueryClientProvider` can supply a request-scoped hydrated client.
|
|
10
12
|
* The `key` is captured once (Solid setup runs once); a reactive key is a documented future enhancement.
|
|
11
13
|
*/
|
|
12
|
-
import { createSignal, onCleanup, onMount } from "solid-js";
|
|
14
|
+
import { createComponent, createContext, createSignal, onCleanup, onMount, useContext, } from "solid-js";
|
|
15
|
+
const QueryClientContext = createContext();
|
|
16
|
+
function queryClientForCurrentTree() {
|
|
17
|
+
return useContext(QueryClientContext) ?? getQueryClientSingleton();
|
|
18
|
+
}
|
|
19
|
+
/** Provide a request-scoped client and optionally seed it before descendants run. */
|
|
20
|
+
export function QueryClientProvider(props) {
|
|
21
|
+
if (props.state !== undefined)
|
|
22
|
+
props.client.hydrate(props.state);
|
|
23
|
+
return createComponent(QueryClientContext.Provider, {
|
|
24
|
+
value: props.client,
|
|
25
|
+
get children() {
|
|
26
|
+
return props.children;
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
13
30
|
/** Access the query client to imperatively `invalidateQueries(keyOrPrefix)` (e.g. after a mutation). */
|
|
14
31
|
export function useQueryClient() {
|
|
15
|
-
return
|
|
32
|
+
return queryClientForCurrentTree() ?? { invalidateQueries: noop };
|
|
16
33
|
}
|
|
17
34
|
/**
|
|
18
35
|
* Bind the keyed query for `key`, fetched via `fn`. Returns a reactive `state()` accessor + `refetch`.
|
|
@@ -21,7 +38,7 @@ export function useQueryClient() {
|
|
|
21
38
|
* the live keys that refetch it.
|
|
22
39
|
*/
|
|
23
40
|
export function createQuery(key, fn, options) {
|
|
24
|
-
const handle =
|
|
41
|
+
const handle = queryClientForCurrentTree()?.query(key, fn, options);
|
|
25
42
|
const [state, setState] = createSignal(handle ? handle.snapshot() : IDLE_QUERY_STATE);
|
|
26
43
|
if (handle !== undefined) {
|
|
27
44
|
onCleanup(handle.subscribe(() => setState(() => handle.snapshot())));
|
|
@@ -33,4 +50,55 @@ export function createQuery(key, fn, options) {
|
|
|
33
50
|
refetch: createNoClientRefetch("[nifra/web-solid]", "createQuery.refetch"),
|
|
34
51
|
};
|
|
35
52
|
}
|
|
53
|
+
/** Bind a mutation to a Solid owner. Identity changes discard late results and callbacks. */
|
|
54
|
+
export function createMutation(fn, callbacks = {}) {
|
|
55
|
+
const handle = createMutationHandle(fn, callbacks);
|
|
56
|
+
const [state, setState] = createSignal(handle.snapshot());
|
|
57
|
+
onCleanup(handle.subscribe(() => setState(() => handle.snapshot())));
|
|
58
|
+
return {
|
|
59
|
+
state,
|
|
60
|
+
isIdle: () => state().status === "idle",
|
|
61
|
+
isPending: () => state().status === "pending",
|
|
62
|
+
isError: () => state().status === "error",
|
|
63
|
+
isSuccess: () => state().status === "success",
|
|
64
|
+
mutate: (variables) => {
|
|
65
|
+
handle.mutate(variables).catch(noop);
|
|
66
|
+
},
|
|
67
|
+
mutateAsync: handle.mutate,
|
|
68
|
+
reset: handle.reset,
|
|
69
|
+
cancel: handle.cancel,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** Bind a paged query to a Solid owner and fetch its first page on mount. */
|
|
73
|
+
export function createInfiniteQuery(key, fn, options) {
|
|
74
|
+
const client = queryClientForCurrentTree();
|
|
75
|
+
const enabled = options.enabled !== false;
|
|
76
|
+
const handle = client?.infiniteQuery(key, fn, options);
|
|
77
|
+
const [state, setState] = createSignal(handle
|
|
78
|
+
? handle.snapshot()
|
|
79
|
+
: // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: An idle query has no generic page data; the provider supplies the typed state before use.
|
|
80
|
+
IDLE_QUERY_STATE);
|
|
81
|
+
if (handle) {
|
|
82
|
+
onCleanup(handle.subscribe(() => setState(() => handle.snapshot())));
|
|
83
|
+
onMount(fetchOnMount(enabled ? handle : undefined));
|
|
84
|
+
}
|
|
85
|
+
const noClientAction = createNoClientRefetch("[nifra/web-solid]", "infinite query action");
|
|
86
|
+
return {
|
|
87
|
+
state,
|
|
88
|
+
isPending: () => state().status === "pending",
|
|
89
|
+
isError: () => state().status === "error",
|
|
90
|
+
isSuccess: () => state().status === "success",
|
|
91
|
+
hasNextPage: () => {
|
|
92
|
+
state();
|
|
93
|
+
return handle?.hasNextPage() ?? false;
|
|
94
|
+
},
|
|
95
|
+
hasPreviousPage: () => {
|
|
96
|
+
state();
|
|
97
|
+
return handle?.hasPreviousPage() ?? false;
|
|
98
|
+
},
|
|
99
|
+
fetchNextPage: handle?.fetchNextPage ?? noClientAction,
|
|
100
|
+
fetchPreviousPage: handle?.fetchPreviousPage ?? noClientAction,
|
|
101
|
+
refetch: handle?.refetch ?? noClientAction,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
36
104
|
//# sourceMappingURL=query.js.map
|
package/dist/query.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
|
package/dist/router.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type { Blocker, BlockerFunction, BlockerState, NavigateFunction, RenderPr
|
|
|
8
8
|
* reads the accessor `compose` provides on SSR + client mount alike. Imports only `solid-js`. No JSX.
|
|
9
9
|
*/
|
|
10
10
|
import { type Accessor, type Context } from "solid-js";
|
|
11
|
+
export { href, rawHref } from "@nifrajs/web/client";
|
|
11
12
|
export { onPageHide, onPageShow, usePageVisibility } from "./page-visibility.js";
|
|
12
13
|
export type { Blocker, BlockerFunction, BlockerState, NavigateFunction, UIMatch };
|
|
13
14
|
export declare const SearchContext: Context<Accessor<Record<string, unknown>> | undefined>;
|
|
@@ -38,7 +39,7 @@ export declare function useMatches(): Accessor<readonly UIMatch[]>;
|
|
|
38
39
|
* ```
|
|
39
40
|
*/
|
|
40
41
|
export declare function useSearch<Schema extends StandardSchemaV1 | undefined = undefined>(): Accessor<Schema extends StandardSchemaV1 ? InferOutput<Schema> : Record<string, unknown>>;
|
|
41
|
-
/** Get the {@link NavigateFunction} (
|
|
42
|
+
/** Get the {@link NavigateFunction} (an `Href` from `href()` or `rawHref()`, or a history delta).
|
|
42
43
|
* Resolves the browser navigate at call time, so it works as soon as `installHistory` has run and no-ops
|
|
43
44
|
* before then / on the server. */
|
|
44
45
|
export declare function useNavigate(): NavigateFunction;
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAIzE,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,OAAO,EACR,MAAM,cAAc,CAAA;AAOrB;;;;;;GAMG;AACH,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,OAAO,EAMb,MAAM,UAAU,CAAA;AAGjB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAChF,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAA;AAiBjF,eAAO,MAAM,aAAa,wDACoE,CAAA;AAO9F,eAAO,MAAM,kBAAkB,kCACuC,CAAA;AAKtE;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,IAAI,QAAQ,CAAC,SAAS,OAAO,EAAE,CAAC,CAIzD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,MAAM,SAAS,gBAAgB,GAAG,SAAS,GAAG,SAAS,KAAK,QAAQ,CAC5F,MAAM,SAAS,gBAAgB,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAChF,CAIA;AAED;;kCAEkC;AAClC,wBAAgB,WAAW,IAAI,gBAAgB,CAE9C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,OAAO,GAAG,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,CAYpF"}
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAIzE,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,OAAO,EACR,MAAM,cAAc,CAAA;AAOrB;;;;;;GAMG;AACH,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,OAAO,EAMb,MAAM,UAAU,CAAA;AAGjB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAChF,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAA;AAiBjF,eAAO,MAAM,aAAa,wDACoE,CAAA;AAO9F,eAAO,MAAM,kBAAkB,kCACuC,CAAA;AAKtE;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,IAAI,QAAQ,CAAC,SAAS,OAAO,EAAE,CAAC,CAIzD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,MAAM,SAAS,gBAAgB,GAAG,SAAS,GAAG,SAAS,KAAK,QAAQ,CAC5F,MAAM,SAAS,gBAAgB,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAChF,CAIA;AAED;;kCAEkC;AAClC,wBAAgB,WAAW,IAAI,gBAAgB,CAE9C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,OAAO,GAAG,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,CAYpF"}
|
package/dist/router.js
CHANGED
|
@@ -13,6 +13,7 @@ import { navigateNow } from "@nifrajs/web/internal/navigate-runtime";
|
|
|
13
13
|
*/
|
|
14
14
|
import { createContext, createMemo, createSignal, onCleanup, useContext, } from "solid-js";
|
|
15
15
|
import { PageContext } from "./page-visibility.js";
|
|
16
|
+
export { href, rawHref } from "@nifrajs/web/client";
|
|
16
17
|
export { onPageHide, onPageShow, usePageVisibility } from "./page-visibility.js";
|
|
17
18
|
// Frozen empty search + a stable accessor for a `useSearch` used outside a nifra route tree.
|
|
18
19
|
const EMPTY_SEARCH = Object.freeze({});
|
|
@@ -68,7 +69,7 @@ export function useMatches() {
|
|
|
68
69
|
export function useSearch() {
|
|
69
70
|
return (useContext(SearchContext) ?? EMPTY_SEARCH_ACCESSOR);
|
|
70
71
|
}
|
|
71
|
-
/** Get the {@link NavigateFunction} (
|
|
72
|
+
/** Get the {@link NavigateFunction} (an `Href` from `href()` or `rawHref()`, or a history delta).
|
|
72
73
|
* Resolves the browser navigate at call time, so it works as soon as `installHistory` has run and no-ops
|
|
73
74
|
* before then / on the server. */
|
|
74
75
|
export function useNavigate() {
|
package/dist/router.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAYA,mFAAmF;AACnF,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACnE,6EAA6E;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AACpE;;;;;;GAMG;AACH,OAAO,EAGL,aAAa,EACb,UAAU,EACV,YAAY,EACZ,SAAS,EACT,UAAU,GACX,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAElD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAGhF,6FAA6F;AAC7F,MAAM,YAAY,GAAsC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AACzE,MAAM,qBAAqB,GAAsC,GAAG,EAAE,CAAC,YAAY,CAAA;AAEnF;;;;;;2BAM2B;AAC3B,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;AACxE,MAAM,iBAAiB,GAAG,UAEzB,CAAA;AACD,MAAM,CAAC,MAAM,aAAa,GACxB,iBAAiB,CAAC,mBAAmB,CAAC,IAAI,aAAa,EAAqC,CAAA;AAC9F,iBAAiB,CAAC,mBAAmB,CAAC,GAAG,aAAa,CAAA;AAEtD;sGACsG;AACtG,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA;AACtE,MAAM,gBAAgB,GAAG,UAAyE,CAAA;AAClG,MAAM,CAAC,MAAM,kBAAkB,GAC7B,gBAAgB,CAAC,kBAAkB,CAAC,IAAI,aAAa,EAAe,CAAA;AACtE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAA;AAEzD,MAAM,UAAU,GAAuB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAExD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,KAAK,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAA;IAC5C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,GAAG,EAAE,CAAC,UAAU,CAAA;IAChD,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAA;AAC9C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS;IAGvB,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAEzD,CAAA;AACH,CAAC;AAED;;kCAEkC;AAClC,MAAM,UAAU,WAAW;IACzB,OAAO,WAAW,CAAA;AACpB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,WAAsC;IAC/D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,YAAY,CAAU,YAAY,CAAC,CAAA;IACjE,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IACpC,SAAS,CACP,eAAe,CACb,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI;QACvB,CAAC,OAAO,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EACvE,UAAU,CACX,CACF,CAAA;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAYA,mFAAmF;AACnF,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACnE,6EAA6E;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AACpE;;;;;;GAMG;AACH,OAAO,EAGL,aAAa,EACb,UAAU,EACV,YAAY,EACZ,SAAS,EACT,UAAU,GACX,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAElD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAGhF,6FAA6F;AAC7F,MAAM,YAAY,GAAsC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AACzE,MAAM,qBAAqB,GAAsC,GAAG,EAAE,CAAC,YAAY,CAAA;AAEnF;;;;;;2BAM2B;AAC3B,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;AACxE,MAAM,iBAAiB,GAAG,UAEzB,CAAA;AACD,MAAM,CAAC,MAAM,aAAa,GACxB,iBAAiB,CAAC,mBAAmB,CAAC,IAAI,aAAa,EAAqC,CAAA;AAC9F,iBAAiB,CAAC,mBAAmB,CAAC,GAAG,aAAa,CAAA;AAEtD;sGACsG;AACtG,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA;AACtE,MAAM,gBAAgB,GAAG,UAAyE,CAAA;AAClG,MAAM,CAAC,MAAM,kBAAkB,GAC7B,gBAAgB,CAAC,kBAAkB,CAAC,IAAI,aAAa,EAAe,CAAA;AACtE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAA;AAEzD,MAAM,UAAU,GAAuB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAExD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,KAAK,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAA;IAC5C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,GAAG,EAAE,CAAC,UAAU,CAAA;IAChD,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAA;AAC9C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS;IAGvB,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,qBAAqB,CAEzD,CAAA;AACH,CAAC;AAED;;kCAEkC;AAClC,MAAM,UAAU,WAAW;IACzB,OAAO,WAAW,CAAA;AACpB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,WAAsC;IAC/D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,YAAY,CAAU,YAAY,CAAC,CAAA;IACjE,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IACpC,SAAS,CACP,eAAe,CACb,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI;QACvB,CAAC,OAAO,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EACvE,UAAU,CACX,CACF,CAAA;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nifrajs/web-solid",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.10.0",
|
|
4
4
|
"description": "Solid render adapter for @nifrajs/web - SSR + hydration, with the Solid Babel build plugin (@nifrajs/web-solid/plugin).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -132,16 +132,16 @@
|
|
|
132
132
|
"dependencies": {
|
|
133
133
|
"@babel/core": "^7.26.0",
|
|
134
134
|
"@babel/preset-typescript": "^7.26.0",
|
|
135
|
-
"@nifrajs/core": "5.
|
|
136
|
-
"@nifrajs/web": "5.
|
|
135
|
+
"@nifrajs/core": "5.10.0",
|
|
136
|
+
"@nifrajs/web": "5.10.0",
|
|
137
137
|
"babel-preset-solid": "^1.9.3",
|
|
138
138
|
"solid-refresh": "^0.7.8"
|
|
139
139
|
},
|
|
140
140
|
"peerDependencies": {
|
|
141
141
|
"@mdx-js/mdx": "^3",
|
|
142
142
|
"solid-js": "^1.9.0",
|
|
143
|
-
"@nifrajs/i18n": "^5.
|
|
144
|
-
"@nifrajs/image": "^5.
|
|
143
|
+
"@nifrajs/i18n": "^5.10.0",
|
|
144
|
+
"@nifrajs/image": "^5.10.0"
|
|
145
145
|
},
|
|
146
146
|
"peerDependenciesMeta": {
|
|
147
147
|
"@mdx-js/mdx": {
|
package/src/compose.ts
CHANGED
|
@@ -29,7 +29,9 @@ export function compose(chain: readonly unknown[], props: RenderProps): () => JS
|
|
|
29
29
|
get data() {
|
|
30
30
|
return props.layoutData?.[i] ?? null
|
|
31
31
|
},
|
|
32
|
-
|
|
32
|
+
get boundaries() {
|
|
33
|
+
return props.boundaries
|
|
34
|
+
},
|
|
33
35
|
children: child(),
|
|
34
36
|
})
|
|
35
37
|
}
|
package/src/image.ts
CHANGED
|
@@ -6,7 +6,14 @@
|
|
|
6
6
|
* reactively (`splitProps`/`mergeProps`). Resizing is delegated to the `loader`; nifra bundles no codec.
|
|
7
7
|
* No JSX (`createComponent`/`Dynamic`), so the package builds with plain `tsc`.
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
type ImageInputProps,
|
|
11
|
+
type ImageLoader,
|
|
12
|
+
type ImageProps,
|
|
13
|
+
resolveImage,
|
|
14
|
+
type StaticImageProps,
|
|
15
|
+
toHtmlAttrs,
|
|
16
|
+
} from "@nifrajs/image"
|
|
10
17
|
import { createComponent, type JSX, mergeProps, splitProps } from "solid-js"
|
|
11
18
|
import { Dynamic } from "solid-js/web"
|
|
12
19
|
|
|
@@ -29,11 +36,14 @@ export interface ImageComponentProps
|
|
|
29
36
|
readonly loader?: ImageLoader
|
|
30
37
|
}
|
|
31
38
|
|
|
39
|
+
export type StaticImageComponentProps = StaticImageProps &
|
|
40
|
+
Omit<ImageComponentProps, "src" | "width" | "height">
|
|
41
|
+
|
|
32
42
|
/**
|
|
33
|
-
* Render a responsive, CLS-safe `<img>`.
|
|
43
|
+
* Render a responsive, CLS-safe `<img>`. String URLs require dimensions; asset imports infer them;
|
|
34
44
|
* `priority` marks the LCP image (`eager` + `fetchpriority="high"`). Extra DOM props pass through.
|
|
35
45
|
*/
|
|
36
|
-
export function Image(props: ImageComponentProps): JSX.Element {
|
|
46
|
+
export function Image(props: ImageComponentProps | StaticImageComponentProps): JSX.Element {
|
|
37
47
|
// Separate the nifra-only props (not valid DOM attributes) from the DOM passthrough (`rest`), keeping
|
|
38
48
|
// both reactive. `rest` carries class/style/id/handlers; the computed attrs are layered over it.
|
|
39
49
|
const [, rest] = splitProps(props, [
|
|
@@ -51,10 +61,7 @@ export function Image(props: ImageComponentProps): JSX.Element {
|
|
|
51
61
|
const attrs = (): ReturnType<typeof toHtmlAttrs> => {
|
|
52
62
|
// Build ImageProps via conditional spreads (exactOptionalPropertyTypes: an unset optional is
|
|
53
63
|
// absent, not `undefined`). resolveImage validates width/height > 0 (CLS contract).
|
|
54
|
-
const
|
|
55
|
-
src: props.src,
|
|
56
|
-
width: props.width,
|
|
57
|
-
height: props.height,
|
|
64
|
+
const common = {
|
|
58
65
|
alt: props.alt,
|
|
59
66
|
...(props.sizes !== undefined ? { sizes: props.sizes } : {}),
|
|
60
67
|
...(props.widths !== undefined ? { widths: props.widths } : {}),
|
|
@@ -62,6 +69,20 @@ export function Image(props: ImageComponentProps): JSX.Element {
|
|
|
62
69
|
...(props.loading !== undefined ? { loading: props.loading } : {}),
|
|
63
70
|
...(props.priority !== undefined ? { priority: props.priority } : {}),
|
|
64
71
|
}
|
|
72
|
+
const input: ImageInputProps =
|
|
73
|
+
typeof props.src === "string"
|
|
74
|
+
? {
|
|
75
|
+
...common,
|
|
76
|
+
src: props.src,
|
|
77
|
+
width: props.width ?? Number.NaN,
|
|
78
|
+
height: props.height ?? Number.NaN,
|
|
79
|
+
}
|
|
80
|
+
: {
|
|
81
|
+
...common,
|
|
82
|
+
src: props.src,
|
|
83
|
+
...(props.width !== undefined ? { width: props.width } : {}),
|
|
84
|
+
...(props.height !== undefined ? { height: props.height } : {}),
|
|
85
|
+
}
|
|
65
86
|
return toHtmlAttrs(resolveImage(input, props.loader))
|
|
66
87
|
}
|
|
67
88
|
return createComponent(Dynamic, mergeProps(rest, attrs, { component: "img" }))
|
package/src/ppr.ts
CHANGED
|
@@ -38,7 +38,7 @@ function openHost<Data>(hole: HoleDefinition<Data>, fill: () => unknown): JSX.El
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
41
|
+
* One `dynamic` or `shared` boundary of a partially prerendered page.
|
|
42
42
|
*
|
|
43
43
|
* In a shared shell the hole is an empty host Solid never fills: the PPR runtime puts the server's
|
|
44
44
|
* HTML into it, and an interactive hole then hydrates as its own root from the frame's props. When the
|
package/src/query.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
DehydratedState,
|
|
3
|
+
InfiniteData,
|
|
4
|
+
InfiniteQueryOptions,
|
|
5
|
+
MutationCallbacks,
|
|
6
|
+
MutationContext,
|
|
7
|
+
MutationHandle,
|
|
8
|
+
MutationState,
|
|
9
|
+
QueryClient,
|
|
10
|
+
QueryOptions,
|
|
11
|
+
QueryState,
|
|
12
|
+
} from "@nifrajs/web"
|
|
13
|
+
import { createMutation as createMutationHandle } from "@nifrajs/web/client"
|
|
2
14
|
import {
|
|
3
15
|
createNoClientRefetch,
|
|
4
16
|
fetchOnMount,
|
|
@@ -12,15 +24,46 @@ import {
|
|
|
12
24
|
* exposes `invalidateQueries` for after a mutation. Imports only `solid-js` + `@nifrajs/web` (never
|
|
13
25
|
* `solid-js/web`), so route components use it on the server *and* client. No JSX.
|
|
14
26
|
*
|
|
15
|
-
*
|
|
16
|
-
* accessor returns
|
|
27
|
+
* Without a provider, the query client is created lazily **client-side only** (`typeof window`) - on
|
|
28
|
+
* the server the accessor returns idle state and route loaders remain the data source. A
|
|
29
|
+
* `QueryClientProvider` can supply a request-scoped hydrated client.
|
|
17
30
|
* The `key` is captured once (Solid setup runs once); a reactive key is a documented future enhancement.
|
|
18
31
|
*/
|
|
19
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
type Accessor,
|
|
34
|
+
createComponent,
|
|
35
|
+
createContext,
|
|
36
|
+
createSignal,
|
|
37
|
+
type JSX,
|
|
38
|
+
onCleanup,
|
|
39
|
+
onMount,
|
|
40
|
+
useContext,
|
|
41
|
+
} from "solid-js"
|
|
42
|
+
|
|
43
|
+
const QueryClientContext = createContext<QueryClient>()
|
|
44
|
+
|
|
45
|
+
function queryClientForCurrentTree(): QueryClient | undefined {
|
|
46
|
+
return useContext(QueryClientContext) ?? getQueryClientSingleton()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Provide a request-scoped client and optionally seed it before descendants run. */
|
|
50
|
+
export function QueryClientProvider(props: {
|
|
51
|
+
readonly client: QueryClient
|
|
52
|
+
readonly state?: DehydratedState
|
|
53
|
+
readonly children?: JSX.Element
|
|
54
|
+
}): JSX.Element {
|
|
55
|
+
if (props.state !== undefined) props.client.hydrate(props.state)
|
|
56
|
+
return createComponent(QueryClientContext.Provider, {
|
|
57
|
+
value: props.client,
|
|
58
|
+
get children() {
|
|
59
|
+
return props.children
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
}
|
|
20
63
|
|
|
21
64
|
/** Access the query client to imperatively `invalidateQueries(keyOrPrefix)` (e.g. after a mutation). */
|
|
22
65
|
export function useQueryClient(): Pick<QueryClient, "invalidateQueries"> {
|
|
23
|
-
return
|
|
66
|
+
return queryClientForCurrentTree() ?? { invalidateQueries: noop }
|
|
24
67
|
}
|
|
25
68
|
|
|
26
69
|
/** A query's reactive state accessor plus `refetch`. */
|
|
@@ -42,7 +85,7 @@ export function createQuery<T>(
|
|
|
42
85
|
fn: () => Promise<T>,
|
|
43
86
|
options?: QueryOptions,
|
|
44
87
|
): CreateQueryResult<T> {
|
|
45
|
-
const handle =
|
|
88
|
+
const handle = queryClientForCurrentTree()?.query<T>(key, fn, options)
|
|
46
89
|
const [state, setState] = createSignal<QueryState<T>>(
|
|
47
90
|
handle ? handle.snapshot() : IDLE_QUERY_STATE,
|
|
48
91
|
)
|
|
@@ -56,3 +99,99 @@ export function createQuery<T>(
|
|
|
56
99
|
refetch: createNoClientRefetch<T>("[nifra/web-solid]", "createQuery.refetch"),
|
|
57
100
|
}
|
|
58
101
|
}
|
|
102
|
+
|
|
103
|
+
/** A mutation result expressed as Solid accessors and imperative controls. */
|
|
104
|
+
export interface CreateMutationResult<TData, TVariables> {
|
|
105
|
+
readonly state: Accessor<MutationState<TData, TVariables>>
|
|
106
|
+
readonly isIdle: Accessor<boolean>
|
|
107
|
+
readonly isPending: Accessor<boolean>
|
|
108
|
+
readonly isError: Accessor<boolean>
|
|
109
|
+
readonly isSuccess: Accessor<boolean>
|
|
110
|
+
readonly mutate: (variables: TVariables) => void
|
|
111
|
+
readonly mutateAsync: (variables: TVariables) => Promise<TData>
|
|
112
|
+
readonly reset: () => void
|
|
113
|
+
readonly cancel: () => void
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Bind a mutation to a Solid owner. Identity changes discard late results and callbacks. */
|
|
117
|
+
export function createMutation<TData, TVariables = void>(
|
|
118
|
+
fn: (variables: TVariables, context: MutationContext) => Promise<TData>,
|
|
119
|
+
callbacks: MutationCallbacks<TData, TVariables> = {},
|
|
120
|
+
): CreateMutationResult<TData, TVariables> {
|
|
121
|
+
const handle: MutationHandle<TData, TVariables> = createMutationHandle(fn, callbacks)
|
|
122
|
+
const [state, setState] = createSignal(handle.snapshot())
|
|
123
|
+
onCleanup(handle.subscribe(() => setState(() => handle.snapshot())))
|
|
124
|
+
return {
|
|
125
|
+
state,
|
|
126
|
+
isIdle: () => state().status === "idle",
|
|
127
|
+
isPending: () => state().status === "pending",
|
|
128
|
+
isError: () => state().status === "error",
|
|
129
|
+
isSuccess: () => state().status === "success",
|
|
130
|
+
mutate: (variables) => {
|
|
131
|
+
handle.mutate(variables).catch(noop)
|
|
132
|
+
},
|
|
133
|
+
mutateAsync: handle.mutate,
|
|
134
|
+
reset: handle.reset,
|
|
135
|
+
cancel: handle.cancel,
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Options for a Solid infinite query. */
|
|
140
|
+
export interface CreateInfiniteQueryOptions<T, P> extends InfiniteQueryOptions<T, P> {
|
|
141
|
+
readonly enabled?: boolean
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Infinite-query state and page controls expressed as Solid accessors. */
|
|
145
|
+
export interface CreateInfiniteQueryResult<T, P> {
|
|
146
|
+
readonly state: Accessor<QueryState<InfiniteData<T, P>>>
|
|
147
|
+
readonly isPending: Accessor<boolean>
|
|
148
|
+
readonly isError: Accessor<boolean>
|
|
149
|
+
readonly isSuccess: Accessor<boolean>
|
|
150
|
+
readonly hasNextPage: Accessor<boolean>
|
|
151
|
+
readonly hasPreviousPage: Accessor<boolean>
|
|
152
|
+
readonly fetchNextPage: () => Promise<InfiniteData<T, P>>
|
|
153
|
+
readonly fetchPreviousPage: () => Promise<InfiniteData<T, P>>
|
|
154
|
+
readonly refetch: () => Promise<InfiniteData<T, P>>
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Bind a paged query to a Solid owner and fetch its first page on mount. */
|
|
158
|
+
export function createInfiniteQuery<T, P>(
|
|
159
|
+
key: unknown,
|
|
160
|
+
fn: (pageParam: P) => Promise<T>,
|
|
161
|
+
options: CreateInfiniteQueryOptions<T, P>,
|
|
162
|
+
): CreateInfiniteQueryResult<T, P> {
|
|
163
|
+
const client = queryClientForCurrentTree()
|
|
164
|
+
const enabled = options.enabled !== false
|
|
165
|
+
const handle = client?.infiniteQuery<T, P>(key, fn, options)
|
|
166
|
+
const [state, setState] = createSignal<QueryState<InfiniteData<T, P>>>(
|
|
167
|
+
handle
|
|
168
|
+
? handle.snapshot()
|
|
169
|
+
: // biome-ignore lint/plugin/requireSafetyCommentForTypeAssertion: An idle query has no generic page data; the provider supplies the typed state before use.
|
|
170
|
+
(IDLE_QUERY_STATE as QueryState<InfiniteData<T, P>>),
|
|
171
|
+
)
|
|
172
|
+
if (handle) {
|
|
173
|
+
onCleanup(handle.subscribe(() => setState(() => handle.snapshot())))
|
|
174
|
+
onMount(fetchOnMount(enabled ? handle : undefined))
|
|
175
|
+
}
|
|
176
|
+
const noClientAction = createNoClientRefetch<InfiniteData<T, P>>(
|
|
177
|
+
"[nifra/web-solid]",
|
|
178
|
+
"infinite query action",
|
|
179
|
+
)
|
|
180
|
+
return {
|
|
181
|
+
state,
|
|
182
|
+
isPending: () => state().status === "pending",
|
|
183
|
+
isError: () => state().status === "error",
|
|
184
|
+
isSuccess: () => state().status === "success",
|
|
185
|
+
hasNextPage: () => {
|
|
186
|
+
state()
|
|
187
|
+
return handle?.hasNextPage() ?? false
|
|
188
|
+
},
|
|
189
|
+
hasPreviousPage: () => {
|
|
190
|
+
state()
|
|
191
|
+
return handle?.hasPreviousPage() ?? false
|
|
192
|
+
},
|
|
193
|
+
fetchNextPage: handle?.fetchNextPage ?? noClientAction,
|
|
194
|
+
fetchPreviousPage: handle?.fetchPreviousPage ?? noClientAction,
|
|
195
|
+
refetch: handle?.refetch ?? noClientAction,
|
|
196
|
+
}
|
|
197
|
+
}
|
package/src/router.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { InferOutput, StandardSchemaV1 } from "@nifrajs/core/server"
|
|
2
2
|
// `import type` + a local re-export, NOT `export type { … } from "@nifrajs/web"`: that form leaves a
|
|
3
3
|
// bare `import "@nifrajs/web"` in the output, which pulls the server graph into the browser under
|
|
4
|
-
// Vite's dev server. Sourced from the ROOT so the generated `
|
|
4
|
+
// Vite's dev server. Sourced from the ROOT so the generated `RouteTable` augmentation applies.
|
|
5
5
|
import type {
|
|
6
6
|
Blocker,
|
|
7
7
|
BlockerFunction,
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
} from "solid-js"
|
|
35
35
|
import { PageContext } from "./page-visibility.ts"
|
|
36
36
|
|
|
37
|
+
export { href, rawHref } from "@nifrajs/web/client"
|
|
37
38
|
export { onPageHide, onPageShow, usePageVisibility } from "./page-visibility.ts"
|
|
38
39
|
export type { Blocker, BlockerFunction, BlockerState, NavigateFunction, UIMatch }
|
|
39
40
|
|
|
@@ -104,7 +105,7 @@ export function useSearch<Schema extends StandardSchemaV1 | undefined = undefine
|
|
|
104
105
|
>
|
|
105
106
|
}
|
|
106
107
|
|
|
107
|
-
/** Get the {@link NavigateFunction} (
|
|
108
|
+
/** Get the {@link NavigateFunction} (an `Href` from `href()` or `rawHref()`, or a history delta).
|
|
108
109
|
* Resolves the browser navigate at call time, so it works as soon as `installHistory` has run and no-ops
|
|
109
110
|
* before then / on the server. */
|
|
110
111
|
export function useNavigate(): NavigateFunction {
|