@nifrajs/cli 2.14.1 → 3.1.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/dist/check.d.ts.map +1 -1
- package/dist/check.js +27 -7
- package/dist/check.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +40 -2
- package/dist/cli.js.map +1 -1
- package/dist/command-catalog.d.ts +6 -0
- package/dist/command-catalog.d.ts.map +1 -1
- package/dist/command-catalog.js +20 -2
- package/dist/command-catalog.js.map +1 -1
- package/dist/doctor.d.ts +42 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +64 -7
- package/dist/doctor.js.map +1 -1
- package/dist/env-file.d.ts +17 -0
- package/dist/env-file.d.ts.map +1 -0
- package/dist/env-file.js +113 -0
- package/dist/env-file.js.map +1 -0
- package/dist/fix-recipes.d.ts.map +1 -1
- package/dist/fix-recipes.js +91 -15
- package/dist/fix-recipes.js.map +1 -1
- package/dist/internal/reserved-segment-codemod.d.ts +36 -0
- package/dist/internal/reserved-segment-codemod.d.ts.map +1 -0
- package/dist/internal/reserved-segment-codemod.js +134 -0
- package/dist/internal/reserved-segment-codemod.js.map +1 -0
- package/dist/internal/typescript-import.d.ts +1 -1
- package/dist/internal/typescript-import.d.ts.map +1 -1
- package/dist/internal/typescript-import.js +62 -11
- package/dist/internal/typescript-import.js.map +1 -1
- package/dist/introspect.d.ts +26 -1
- package/dist/introspect.d.ts.map +1 -1
- package/dist/introspect.js +74 -24
- package/dist/introspect.js.map +1 -1
- package/dist/mcp-http.js +1 -1
- package/dist/mcp-http.js.map +1 -1
- package/dist/mcp.d.ts +8 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +68 -6
- package/dist/mcp.js.map +1 -1
- package/dist/recipes/3.0.0.d.ts +10 -0
- package/dist/recipes/3.0.0.d.ts.map +1 -0
- package/dist/recipes/3.0.0.js +23 -0
- package/dist/recipes/3.0.0.js.map +1 -0
- package/dist/recipes/index.d.ts.map +1 -1
- package/dist/recipes/index.js +2 -0
- package/dist/recipes/index.js.map +1 -1
- package/dist/release-verification.d.ts.map +1 -1
- package/dist/release-verification.js +15 -0
- package/dist/release-verification.js.map +1 -1
- package/dist/rules/routes.d.ts.map +1 -1
- package/dist/rules/routes.js +17 -30
- package/dist/rules/routes.js.map +1 -1
- package/dist/workspace-link.d.ts +37 -0
- package/dist/workspace-link.d.ts.map +1 -0
- package/dist/workspace-link.js +72 -0
- package/dist/workspace-link.js.map +1 -0
- package/docs/examples.json +1 -1
- package/docs/llms-full.txt +362 -20
- package/docs/types.json +933 -46
- package/package.json +9 -9
- package/src/check.ts +28 -7
- package/src/cli.ts +41 -2
- package/src/command-catalog.ts +22 -2
- package/src/doctor.ts +99 -8
- package/src/env-file.ts +121 -0
- package/src/fix-recipes.ts +101 -15
- package/src/internal/reserved-segment-codemod.ts +150 -0
- package/src/internal/typescript-import.ts +61 -11
- package/src/introspect.ts +82 -21
- package/src/mcp-http.ts +1 -1
- package/src/mcp.ts +81 -6
- package/src/recipes/3.0.0.ts +24 -0
- package/src/recipes/index.ts +2 -0
- package/src/release-verification.ts +17 -0
- package/src/rules/routes.ts +17 -30
- package/src/workspace-link.ts +80 -0
package/docs/llms-full.txt
CHANGED
|
@@ -320,7 +320,7 @@ renders in its place, wrapped by the layouts at/above that segment, at status 50
|
|
|
320
320
|
non-hydrated). On the **client** - a render error during navigation/interaction is caught by
|
|
321
321
|
the nearest boundary, which renders `_error` in place (all five adapters). It
|
|
322
322
|
receives the serialized error as `{ data: { name, message } }` (never the
|
|
323
|
-
stack); a thrown
|
|
323
|
+
stack); a thrown control-flow value (e.g. a guard `redirect`) passes through.
|
|
324
324
|
|
|
325
325
|
```ts
|
|
326
326
|
routes/
|
|
@@ -1607,6 +1607,8 @@ Node against the outcome's plain header record on the **direct socket writer**,
|
|
|
1607
1607
|
ever materializing Web `Request`/`Response` objects:
|
|
1608
1608
|
|
|
1609
1609
|
```ts
|
|
1610
|
+
import { responseObserver } from "@nifrajs/core/response-observer"
|
|
1611
|
+
import { server } from "@nifrajs/core/server"
|
|
1610
1612
|
import type { Middleware } from "@nifrajs/core/server"
|
|
1611
1613
|
|
|
1612
1614
|
// ONE implementation, fast on every runtime: on Bun/Deno it mutates the
|
|
@@ -1619,6 +1621,8 @@ export function serverName(value: string): Middleware {
|
|
|
1619
1621
|
},
|
|
1620
1622
|
}
|
|
1621
1623
|
}
|
|
1624
|
+
|
|
1625
|
+
const app = server().use(responseObserver()).use(serverName("nifra"))
|
|
1622
1626
|
```
|
|
1623
1627
|
|
|
1624
1628
|
Why this matters on Node: a full `onResponse(res: Response)` hook needs real Web
|
|
@@ -2799,9 +2803,10 @@ createWebApp({ /* … */ api: sessions }) // inject the manager
|
|
|
2799
2803
|
|
|
2800
2804
|
### Guard a route
|
|
2801
2805
|
|
|
2802
|
-
`requireSession` / `requireUser` throw a `
|
|
2803
|
-
`redirectTo`, or a 401) when the session is missing - Nifra
|
|
2804
|
-
as-is, so the guard short-circuits the loader.
|
|
2806
|
+
`requireSession` / `requireUser` throw a `status(...)` render
|
|
2807
|
+
(a 302 to `redirectTo`, or a 401) when the session is missing - Nifra renders a
|
|
2808
|
+
thrown control-flow value as-is, so the guard short-circuits the loader. It is plain data, not
|
|
2809
|
+
a `Response`: same bytes on the wire, on the lane an ordinary return takes.
|
|
2805
2810
|
|
|
2806
2811
|
```ts
|
|
2807
2812
|
// doc-check: skip - fragment: `api` is the session manager createWebApp injected (see setup above).
|
|
@@ -3422,6 +3427,28 @@ app.ws("/chat", {
|
|
|
3422
3427
|
})
|
|
3423
3428
|
```
|
|
3424
3429
|
|
|
3430
|
+
### Optional outbound validation
|
|
3431
|
+
|
|
3432
|
+
`sendSchema` is type-level by default: it documents and types what the client
|
|
3433
|
+
receives with no runtime cost. Set `validateSend: true` to check server-sent JSON
|
|
3434
|
+
text and UTF-8 binary frames before the native socket sends them. Invalid frames and async
|
|
3435
|
+
validators fail closed and route a diagnostic to `error` when present. This is a
|
|
3436
|
+
contract check for your own output, not an inbound security boundary; the flag requires a
|
|
3437
|
+
`sendSchema` and is intentionally off by default.
|
|
3438
|
+
|
|
3439
|
+
```ts
|
|
3440
|
+
// doc-check: skip - illustrative: outbound contract on an existing app.
|
|
3441
|
+
import { t } from "@nifrajs/schema"
|
|
3442
|
+
|
|
3443
|
+
app.ws("/events", {
|
|
3444
|
+
sendSchema: t.Object({ kind: t.Literal("ready"), id: t.String() }),
|
|
3445
|
+
validateSend: true, // opt in; default remains type-level only
|
|
3446
|
+
open(ws) {
|
|
3447
|
+
ws.send(JSON.stringify({ kind: "ready", id: "evt-1" }))
|
|
3448
|
+
},
|
|
3449
|
+
})
|
|
3450
|
+
```
|
|
3451
|
+
|
|
3425
3452
|
### Pub/sub - app.publish
|
|
3426
3453
|
|
|
3427
3454
|
`ws.subscribe(topic)` joins a topic; `app.publish(topic, data)`
|
|
@@ -4654,9 +4681,9 @@ global state; a second copy nulls it out and every hook throws.
|
|
|
4654
4681
|
|
|
4655
4682
|
Nifra **dedupes React** in both the production build and the Vite dev server, so
|
|
4656
4683
|
the framework itself won't load two copies. The usual culprit is a
|
|
4657
|
-
**`file:`-linked package** (a local component
|
|
4658
|
-
`bun link` or reference with `
|
|
4659
|
-
its own `node_modules
|
|
4684
|
+
**`file:`- or `link:`-linked package** (a local component
|
|
4685
|
+
library you `bun link` or reference with `link:../lib`) that bundles its
|
|
4686
|
+
own React in its own `node_modules`. Fix the install first, if you can:
|
|
4660
4687
|
|
|
4661
4688
|
-
|
|
4662
4689
|
Make React a **peer dependency** of the linked package (not a regular
|
|
@@ -4672,6 +4699,70 @@ copy.
|
|
|
4672
4699
|
Delete the linked package's nested `node_modules/react` after linking if your
|
|
4673
4700
|
package manager duplicated it.
|
|
4674
4701
|
|
|
4702
|
+
#### When the duplicate can't be installed away: declare it single-copy
|
|
4703
|
+
|
|
4704
|
+
A `link:` dependency on a **separate checkout** is the case none of the
|
|
4705
|
+
above reaches. The linked package's files live in the other repo, so Node and Bun resolve their
|
|
4706
|
+
imports from _that_ repo's real path - and that repo's install owns its
|
|
4707
|
+
`node_modules`. Peer deps don't help (the copy is already installed there),
|
|
4708
|
+
`overrides` don't help (they govern your install, not theirs), and deleting the
|
|
4709
|
+
nested copy is undone by the next install in the sibling repo. Only a resolver can answer this:
|
|
4710
|
+
the walk has to be intercepted, not rearranged.
|
|
4711
|
+
|
|
4712
|
+
Declare the packages in your app's `package.json`. It is a **static**
|
|
4713
|
+
declaration on purpose - `nifra check` reads it without importing your config, so
|
|
4714
|
+
the preflight never executes app code:
|
|
4715
|
+
|
|
4716
|
+
```ts
|
|
4717
|
+
{
|
|
4718
|
+
"name": "my-app",
|
|
4719
|
+
"dependencies": {
|
|
4720
|
+
"react": "19.2.8",
|
|
4721
|
+
"@example/ui": "link:../design-system/packages/ui"
|
|
4722
|
+
},
|
|
4723
|
+
"nifra": {
|
|
4724
|
+
"singleCopy": ["react", "react-dom", "@nifrajs/*"]
|
|
4725
|
+
}
|
|
4726
|
+
}
|
|
4727
|
+
```
|
|
4728
|
+
|
|
4729
|
+
`"singleCopy": true` is shorthand for Nifra's built-in identity-sensitive set:
|
|
4730
|
+
`@nifrajs/*`, `react`, `react-dom`, `preact`,
|
|
4731
|
+
`solid-js`, `svelte`, `vue`. Entries may be exact names or a
|
|
4732
|
+
`@scope/*` pattern. `@nifrajs/*` belongs in this set for the same reason
|
|
4733
|
+
React does: two copies of `@nifrajs/core` are two distinct `Server`
|
|
4734
|
+
classes, so `.merge()` stops accepting an app built against the other one.
|
|
4735
|
+
|
|
4736
|
+
**The build honours the declaration on its own** -
|
|
4737
|
+
`buildClient` and `buildServer` inject the resolver, so bundled output
|
|
4738
|
+
already loads one copy. Unbundled phases do not: Bun's _runtime_ resolver never offers a
|
|
4739
|
+
bare specifier to a plugin, so `bun test`, `bun run`, and preloaded
|
|
4740
|
+
scripts still load both copies unless you preload the registrar:
|
|
4741
|
+
|
|
4742
|
+
```ts
|
|
4743
|
+
# bunfig.toml
|
|
4744
|
+
preload = ["@nifrajs/core/single-copy/register"]
|
|
4745
|
+
|
|
4746
|
+
[test]
|
|
4747
|
+
preload = ["@nifrajs/core/single-copy/register"]
|
|
4748
|
+
```
|
|
4749
|
+
|
|
4750
|
+
Both sections matter, and they are independent: `preload` covers
|
|
4751
|
+
`bun run`, `[test].preload` covers `bun test`. Declaring
|
|
4752
|
+
without preloading is a real state, not a mistake -
|
|
4753
|
+
`nifra check` reports it and names the phase left uncovered.
|
|
4754
|
+
|
|
4755
|
+
**What it will not do:** redirect across _versions_. If the two copies are
|
|
4756
|
+
`19.2.7` and `19.2.8`, the redirect is skipped and
|
|
4757
|
+
`nifra check` still fails with `version-skew`. Silently collapsing a
|
|
4758
|
+
version difference would trade a loud install problem for a quiet behavioural one; align the
|
|
4759
|
+
ranges instead.
|
|
4760
|
+
|
|
4761
|
+
A declared duplicate is **reported, not suppressed**.
|
|
4762
|
+
`nifra check` keeps printing the copies as a warning and
|
|
4763
|
+
`nifra doctor` lists them under "deduplicated by declaration", so the topology stays
|
|
4764
|
+
visible - it just stops being fatal.
|
|
4765
|
+
|
|
4675
4766
|
[!NOTE]
|
|
4676
4767
|
|
|
4677
4768
|
This applies to every framework with module-global render state, not just React (Preact,
|
|
@@ -5339,9 +5430,9 @@ export const hydrate = false // opt out of full-document hydration (static / i
|
|
|
5339
5430
|
export default function User(props) { /* props.data, props.actionData, props.params */ }
|
|
5340
5431
|
```
|
|
5341
5432
|
|
|
5342
|
-
[!NOTE] An `action` may return a
|
|
5343
|
-
|
|
5344
|
-
`actionData`.
|
|
5433
|
+
[!NOTE] An `action` may return a control-flow value - a `redirect()` or a
|
|
5434
|
+
`status(...)` render, or a hand-rolled `Response` - and it's passed
|
|
5435
|
+
through untouched. Any other return is serialized as `actionData`.
|
|
5345
5436
|
|
|
5346
5437
|
### Two ways to handle a request
|
|
5347
5438
|
|
|
@@ -6434,6 +6525,94 @@ If capabilities are configured, review a new snapshot and run
|
|
|
6434
6525
|
Exercise authentication, redirects, backend mounting, SSE/WebSocket routes, and each deploy
|
|
6435
6526
|
adapter the application uses.
|
|
6436
6527
|
|
|
6528
|
+
## Nifra 3.0 migration guide - upgrade from 2.x
|
|
6529
|
+
|
|
6530
|
+
> Upgrade a Nifra 2.x application to 3.0: automated dependency pins, the plain-data redirect return value, the frozen reserved typed-client segment keys and their codemod, the Node proxy transport default, and the release gates.
|
|
6531
|
+
|
|
6532
|
+
Nifra 3.0 makes a redirect the same plain-data value an ordinary return is, and freezes the
|
|
6533
|
+
reserved typed-client segment keys into a published contract. The upgrade command handles the
|
|
6534
|
+
deterministic dependency pins; this guide covers the two structural changes it deliberately
|
|
6535
|
+
cannot guess, plus the Node proxy transport default.
|
|
6536
|
+
|
|
6537
|
+
### 1. Run the executable upgrade
|
|
6538
|
+
|
|
6539
|
+
```ts
|
|
6540
|
+
|
|
6541
|
+
```
|
|
6542
|
+
|
|
6543
|
+
The command pins every matching `@nifrajs/*`, `Nifra`, and
|
|
6544
|
+
`create-nifra` dependency to `3.0.0` while preserving
|
|
6545
|
+
caret/tilde/exact style. No package is removed and no import specifier moves this release, so
|
|
6546
|
+
the runner only pins. Dry-run is the default; `--write` applies and verifies with
|
|
6547
|
+
`nifra check`.
|
|
6548
|
+
|
|
6549
|
+
### 2. Read redirects as plain data
|
|
6550
|
+
|
|
6551
|
+
`redirect(...)` now returns the same plain render value `status(...)`
|
|
6552
|
+
produces, not a Web `Response`. Same bytes on the wire, now with a
|
|
6553
|
+
`content-length` on Node instead of a chunked empty body. It is still returned or
|
|
6554
|
+
thrown from the same places - loader, action, layout gate - and `return redirect()`
|
|
6555
|
+
/ `throw redirect()` stay interchangeable, including the client-submit conversion to
|
|
6556
|
+
a 204 with `X-Nifra-Redirect`.
|
|
6557
|
+
|
|
6558
|
+
**Breaking:** the value is no longer a `Response`, so
|
|
6559
|
+
`.status`, `.headers`, and `instanceof Response` are gone from
|
|
6560
|
+
it. Read `.plain`, build one with `toResponse()` when needed, pass headers
|
|
6561
|
+
through the second argument, and assert on `.plain` in tests. A hand-rolled
|
|
6562
|
+
`Response` from a loader or action is untouched - only what `redirect()`
|
|
6563
|
+
itself returns changed.
|
|
6564
|
+
|
|
6565
|
+
```ts
|
|
6566
|
+
|
|
6567
|
+
```
|
|
6568
|
+
|
|
6569
|
+
### 3. Fix reserved typed-client segments
|
|
6570
|
+
|
|
6571
|
+
The reserved proxy keys are now a frozen, published contract. A route whose static path
|
|
6572
|
+
segment spells one of them - an HTTP verb in any casing, or `subscribe`,
|
|
6573
|
+
`ws`, `index`, `then` - is unreachable by property access,
|
|
6574
|
+
because the proxy resolves the reserved key before a path segment. The types now reject that
|
|
6575
|
+
access at compile time instead of silently reaching the wrong node.
|
|
6576
|
+
|
|
6577
|
+
```ts
|
|
6578
|
+
|
|
6579
|
+
```
|
|
6580
|
+
|
|
6581
|
+
Run `nifra fix --code NF-C018` to rewrite the affected call sites. It reads them
|
|
6582
|
+
from the compiler rather than a text search, so it finds every one and never mistakes a real
|
|
6583
|
+
`.delete` verb call for a path segment; a site it cannot rewrite confidently
|
|
6584
|
+
(bracket access, a node held in a variable) is reported and left alone.
|
|
6585
|
+
`nifra routes` annotates a colliding route with the spelling that reaches it, in
|
|
6586
|
+
both the table and `--json`. The set is exported as the one place it is written down.
|
|
6587
|
+
|
|
6588
|
+
```ts
|
|
6589
|
+
|
|
6590
|
+
```
|
|
6591
|
+
|
|
6592
|
+
### 4. Review the Node proxy transport (only if you use it)
|
|
6593
|
+
|
|
6594
|
+
On Node, `@nifrajs/proxy` now defaults to the undici transport, shipped from the new
|
|
6595
|
+
`@nifrajs/proxy/undici` subpath. Pass an explicit `transport` to
|
|
6596
|
+
`createProxy` to override it.
|
|
6597
|
+
|
|
6598
|
+
```ts
|
|
6599
|
+
|
|
6600
|
+
```
|
|
6601
|
+
|
|
6602
|
+
### 5. Run the release gates
|
|
6603
|
+
|
|
6604
|
+
-
|
|
6605
|
+
Run `nifra check --json` and fix every error, including any remaining NF-C018.
|
|
6606
|
+
|
|
6607
|
+
-
|
|
6608
|
+
If the project has `nifra.assurance.ts`, run `nifra assure --json`.
|
|
6609
|
+
|
|
6610
|
+
- Run the application test suite and a production build.
|
|
6611
|
+
|
|
6612
|
+
-
|
|
6613
|
+
Exercise every redirect path - loader, action, and layout gate - and, if the app proxies,
|
|
6614
|
+
each deploy adapter it uses.
|
|
6615
|
+
|
|
6437
6616
|
## Nifra - Migrating from Express, Hono, Fastify & Elysia
|
|
6438
6617
|
|
|
6439
6618
|
> Move a backend to Nifra: routing, middleware, validation, and body parsing map directly from Express, Hono, Fastify, and Elysia - and you gain a typed client, multi-runtime deploy, and optional SSR.
|
|
@@ -7691,8 +7870,8 @@ app.get("/me", async (c) => {
|
|
|
7691
7870
|
|
|
7692
7871
|
## Protect a route
|
|
7693
7872
|
|
|
7694
|
-
`requireSession(auth, request, options?)` returns the non-null session or **throws a `
|
|
7695
|
-
nifra
|
|
7873
|
+
`requireSession(auth, request, options?)` returns the non-null session or **throws a Nifra `ResponseResult`** -
|
|
7874
|
+
nifra handles the thrown `ResponseResult` as control flow, short-circuiting the handler:
|
|
7696
7875
|
|
|
7697
7876
|
```ts
|
|
7698
7877
|
import { requireSession } from "@nifrajs/better-auth"
|
|
@@ -7716,7 +7895,7 @@ export const loader = async ({ request }) => {
|
|
|
7716
7895
|
| --- | --- |
|
|
7717
7896
|
| `betterAuth(auth, options?)` | Plugin that mounts better-auth's handler at `${basePath}/*` for GET + POST. |
|
|
7718
7897
|
| `getSession(auth, request)` | `Promise<SessionOf<A> \| null>` - typed wrapper over `auth.api.getSession`. |
|
|
7719
|
-
| `requireSession(auth, request, options?)` | Returns the session or throws a `
|
|
7898
|
+
| `requireSession(auth, request, options?)` | Returns the session or throws a Nifra `ResponseResult` (302 `redirectTo` / 401). |
|
|
7720
7899
|
| `SessionOf<A>` | The non-null session payload type inferred from your `auth`. |
|
|
7721
7900
|
| `BetterAuthLike` | The structural contract a better-auth instance satisfies. |
|
|
7722
7901
|
|
|
@@ -8013,6 +8192,31 @@ bun add @nifrajs/content
|
|
|
8013
8192
|
- Reference: <https://nifra.dev/docs>
|
|
8014
8193
|
- AI-readable: <https://nifra.dev/llms.txt>
|
|
8015
8194
|
|
|
8195
|
+
## Typed indexes and joins
|
|
8196
|
+
|
|
8197
|
+
Build an equality lookup and deterministic query index from a baked collection. `where` is field
|
|
8198
|
+
equality, `range` supports typed string/number comparisons, sorting is stable (slug is the tie-breaker),
|
|
8199
|
+
and pages use an opaque cursor rather than an offset:
|
|
8200
|
+
|
|
8201
|
+
```ts
|
|
8202
|
+
const posts = indexCollection(await bakeCollection(blog), {
|
|
8203
|
+
by: "section",
|
|
8204
|
+
sort: { field: "publishedAt", dir: "desc" },
|
|
8205
|
+
})
|
|
8206
|
+
|
|
8207
|
+
const page = posts.query({ where: { section: "news" }, limit: 20 })
|
|
8208
|
+
const next = page.nextCursor === undefined
|
|
8209
|
+
? undefined
|
|
8210
|
+
: posts.query({ where: { section: "news" }, cursor: page.nextCursor, limit: 20 })
|
|
8211
|
+
```
|
|
8212
|
+
|
|
8213
|
+
`posts.baked` is JSON-safe and can be serialized into an edge bundle; `fromBakedIndex` rehydrates it
|
|
8214
|
+
without filesystem access. `joinCollections(left, right, "id")` gives one-to-many rows by default.
|
|
8215
|
+
Pass `{ cardinality: "one-to-one" }` to require unique right-side keys; duplicate right keys fail the
|
|
8216
|
+
build loudly. The join key must exist on both frontmatter types with the same TypeScript value type.
|
|
8217
|
+
These APIs index only validated local/baked content; credentialed CMS ingestion and tenant data remain
|
|
8218
|
+
outside this public package.
|
|
8219
|
+
|
|
8016
8220
|
MIT
|
|
8017
8221
|
|
|
8018
8222
|
## For AI agents
|
|
@@ -8069,6 +8273,10 @@ import { defineChannel, memoryChannelHub } from "@nifrajs/core/channel"
|
|
|
8069
8273
|
- **Lifecycle middleware.** `derive`/`decorate` extend the typed context;
|
|
8070
8274
|
`onRequest`/`beforeHandle`/`afterHandle`/`onResponse`/`onError` run around handlers;
|
|
8071
8275
|
`use(middleware)` applies a bundle.
|
|
8276
|
+
- **Portable response observation.** The header/body/raw observer methods are opt-in so ordinary
|
|
8277
|
+
servers stay lean: add `responseObserver()` from `@nifrajs/core/response-observer` before calling
|
|
8278
|
+
`onResponseHeaders`, `onResponseBody`, or `onResponseRaw`. Official middleware that uses these
|
|
8279
|
+
tiers installs the compatibility runtime automatically.
|
|
8072
8280
|
- **Hardening built in.** `stop({ drainMs })` graceful shutdown (+ opt-in SIGTERM/
|
|
8073
8281
|
SIGINT), `requestTimeoutMs` (+ `ctx.signal` and `ctx.budget`), a streaming body-size cap, and a
|
|
8074
8282
|
redacting structured `Logger`.
|
|
@@ -8283,6 +8491,98 @@ one cheap read instead of the whole corpus. For the wider framework: the repo's
|
|
|
8283
8491
|
[`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
|
|
8284
8492
|
done-gate, or `nifra mcp` to give the agent live project tools.
|
|
8285
8493
|
|
|
8494
|
+
## @nifrajs/edge
|
|
8495
|
+
|
|
8496
|
+
Compact fetch-handler server for edge and serverless runtimes - Cloudflare Workers, Vercel Edge, Deno Deploy, Bun. Keeps the `server().get().post()` DX and the full request trust boundary (bounded body read, Content-Length pre-reject, prototype-pollution guard, JSON / urlencoded framing) in a fraction of the bundle. Zero runtime dependencies beyond `@nifrajs/core`.
|
|
8497
|
+
|
|
8498
|
+
Part of the **[nifra](https://nifra.dev)** full-stack TypeScript framework - one core, five UI libraries, every runtime. Scaffold a new app with `bun create nifra`.
|
|
8499
|
+
|
|
8500
|
+
## Why
|
|
8501
|
+
|
|
8502
|
+
`@nifrajs/core`'s `server()` carries lifecycle hooks, cookies, response contracts, deadlines, WebSockets, and a plugin system. On an edge worker you often want none of that - just typed routing and a safe body. `@nifrajs/edge` is that subset: the same routing DX, the *same* body trust boundary (imported from core, never re-derived, so there is no second copy of the security contract to drift), and nothing else.
|
|
8503
|
+
|
|
8504
|
+
The rejection envelopes are byte-for-byte the full Server's - so an app can start on `@nifrajs/edge` and graduate to `@nifrajs/core`'s `server()` without its clients noticing.
|
|
8505
|
+
|
|
8506
|
+
## Install
|
|
8507
|
+
|
|
8508
|
+
```sh
|
|
8509
|
+
bun add @nifrajs/edge @nifrajs/core
|
|
8510
|
+
```
|
|
8511
|
+
|
|
8512
|
+
## Use
|
|
8513
|
+
|
|
8514
|
+
```ts
|
|
8515
|
+
// worker.ts
|
|
8516
|
+
import { server, type StandardSchemaV1 } from "@nifrajs/edge"
|
|
8517
|
+
|
|
8518
|
+
const createUser: StandardSchemaV1<{ name: string; age: number }> = /* zod, valibot, arktype, ... */
|
|
8519
|
+
|
|
8520
|
+
const app = server()
|
|
8521
|
+
.get("/users/:id", (c) => ({ id: c.params.id }))
|
|
8522
|
+
.post("/users", { body: createUser }, (c) => ({ created: c.body.name, age: c.body.age }))
|
|
8523
|
+
|
|
8524
|
+
export default app // { fetch } - a module worker handler
|
|
8525
|
+
```
|
|
8526
|
+
|
|
8527
|
+
`c.params` is typed from the route pattern. `c.body` is narrowed to the schema's output. Return a value (rendered as JSON) or a `Response` for full control. Throw a `Response` for an early exit; any other throw becomes a flat `500`.
|
|
8528
|
+
|
|
8529
|
+
## Context
|
|
8530
|
+
|
|
8531
|
+
| Member | What |
|
|
8532
|
+
| --- | --- |
|
|
8533
|
+
| `c.request` | the raw `Request` |
|
|
8534
|
+
| `c.params` | path params, typed from the pattern (`/users/:id` -> `{ id: string }`) |
|
|
8535
|
+
| `c.body` | parsed, schema-validated body (`undefined` on a body-less route) |
|
|
8536
|
+
| `c.query()` | query string parsed to an object, on demand |
|
|
8537
|
+
| `c.header(name)` | a request header (case-insensitive), or `null` |
|
|
8538
|
+
|
|
8539
|
+
## Options
|
|
8540
|
+
|
|
8541
|
+
```ts
|
|
8542
|
+
server({ maxBodyBytes: 256_000, protoPoisoning: "strip" })
|
|
8543
|
+
```
|
|
8544
|
+
|
|
8545
|
+
| Option | Default | What |
|
|
8546
|
+
| --- | --- | --- |
|
|
8547
|
+
| `maxBodyBytes` | `1_000_000` | body-size cap before a `413`, matching core |
|
|
8548
|
+
| `protoPoisoning` | `"reject"` | `__proto__` policy for JSON bodies: `"reject"` \| `"strip"` \| `"ignore"`, matching core |
|
|
8549
|
+
|
|
8550
|
+
## Security
|
|
8551
|
+
|
|
8552
|
+
The body trust boundary is on by default and imported from `@nifrajs/core` - the same lane the full Server runs, so there is one implementation, never a trimmed copy that could drift. On every body-bearing route it enforces:
|
|
8553
|
+
|
|
8554
|
+
| Guard | Effect |
|
|
8555
|
+
| --- | --- |
|
|
8556
|
+
| Streaming byte cap | a length-less (chunked) body is drained under `maxBodyBytes`; once over, the stream is **cancelled** and rejected `413` - it is never buffered whole |
|
|
8557
|
+
| Content-Length pre-reject | a declared length over `maxBodyBytes` is `413` before a byte is read; a malformed length is `400` |
|
|
8558
|
+
| Prototype-pollution guard | an own `__proto__` key (or a poisoning-shaped `constructor.prototype`) in a JSON body is rejected (`"reject"`, default) or removed (`"strip"`) before it reaches your handler |
|
|
8559
|
+
| Media-type framing | JSON and urlencoded bodies are framed and capped; other content types get `415` |
|
|
8560
|
+
|
|
8561
|
+
Rejection envelopes are byte-for-byte the full Server's.
|
|
8562
|
+
|
|
8563
|
+
**Whether you need this depends on the runtime:**
|
|
8564
|
+
|
|
8565
|
+
- **Stream runtimes** (Cloudflare Workers, Deno Deploy, Bun): the runtime hands your worker a live request stream with no size ceiling below its own memory limit. A single length-less request into an unguarded `.json()` buffers unbounded and can cross the isolate memory limit (~128 MB on Workers) - one request, one killed worker (and on auto-scaling platforms, a metered bill). Here the byte cap is **load-bearing**, not optional.
|
|
8566
|
+
- **Pre-capped serverless** (Vercel Edge ~4.5 MB, AWS API Gateway 6-10 MB, GCP 10-32 MB, Azure ~30 MB default): the platform already bounds the body at its edge, so the crash case is largely its job. The cap still earns its place by tightening that platform ceiling to your app's real intent and returning a consistent `413`. (Platform limits are documented ceilings - check current docs for your plan.)
|
|
8567
|
+
|
|
8568
|
+
The prototype-pollution guard is **platform-independent**: no runtime guards `JSON.parse` for you, and a `__proto__`-bearing object becomes pollution the moment downstream code merges it. The guard stops it at ingress. Both defenses tune via [Options](#options).
|
|
8569
|
+
|
|
8570
|
+
## Not included
|
|
8571
|
+
|
|
8572
|
+
By design: no lifecycle / `around` hooks, cookies, response contracts, deadlines, WebSockets, or plugins. Reach for `@nifrajs/core`'s `server()` when an app needs those.
|
|
8573
|
+
|
|
8574
|
+
## License
|
|
8575
|
+
|
|
8576
|
+
MIT
|
|
8577
|
+
|
|
8578
|
+
## For AI agents
|
|
8579
|
+
|
|
8580
|
+
Start with [`LLM.md`](./LLM.md) - this package's contract card (the exports you call + its footguns),
|
|
8581
|
+
one cheap read instead of the whole corpus. For the wider framework: the repo's
|
|
8582
|
+
[`AGENTS.md`](../../AGENTS.md) is the copy-paste quick reference, and
|
|
8583
|
+
[`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
|
|
8584
|
+
done-gate, or `nifra mcp` to give the agent live project tools.
|
|
8585
|
+
|
|
8286
8586
|
## @nifrajs/env
|
|
8287
8587
|
|
|
8288
8588
|
Typed, validated environment variables. Define a schema once at startup; get a **frozen, typed**
|
|
@@ -8463,6 +8763,32 @@ one cheap read instead of the whole corpus. For the wider framework: the repo's
|
|
|
8463
8763
|
[`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
|
|
8464
8764
|
done-gate, or `nifra mcp` to give the agent live project tools.
|
|
8465
8765
|
|
|
8766
|
+
## @nifrajs/island-trigger
|
|
8767
|
+
|
|
8768
|
+
Framework-neutral, browser-side trigger scheduling shared by Nifra’s two island runtimes:
|
|
8769
|
+
`@nifrajs/web/islands` and `@nifrajs/islets`.
|
|
8770
|
+
|
|
8771
|
+
It has no DOM or UI-framework dependency. The public contract is the small `scheduleTrigger`
|
|
8772
|
+
primitive with these strategies:
|
|
8773
|
+
|
|
8774
|
+
```ts
|
|
8775
|
+
import { scheduleTrigger } from "@nifrajs/island-trigger"
|
|
8776
|
+
|
|
8777
|
+
const dispose = scheduleTrigger({ media: "(min-width: 768px)" }, () => {
|
|
8778
|
+
// Activate the island.
|
|
8779
|
+
})
|
|
8780
|
+
|
|
8781
|
+
dispose() // cancel before the trigger fires
|
|
8782
|
+
```
|
|
8783
|
+
|
|
8784
|
+
`load`, `idle`, `visible`, and media-query triggers are one-shot. Idle and visibility strategies
|
|
8785
|
+
fall back safely when the browser capability is unavailable; malformed or oversized media queries
|
|
8786
|
+
remain inert. The package only schedules the callback - each island runtime owns its own markers,
|
|
8787
|
+
registry, signals, and framework integration.
|
|
8788
|
+
|
|
8789
|
+
For AI agents, see [`LLM.md`](./LLM.md). The wider reference is in
|
|
8790
|
+
[`llms-full.txt`](../../llms-full.txt).
|
|
8791
|
+
|
|
8466
8792
|
## @nifrajs/islets
|
|
8467
8793
|
|
|
8468
8794
|
Fine-grained signals + declarative DOM bindings for islands - **interactivity in ~1.4 KB gz**, no
|
|
@@ -8779,7 +9105,9 @@ Bun GET, byte-identical on the wire). They are defaults - anything the request p
|
|
|
8779
9105
|
`securityHeaders` and the default `poweredBy` ship this way.
|
|
8780
9106
|
|
|
8781
9107
|
A middleware whose response hook only reads/writes **headers** but needs the request should use the
|
|
8782
|
-
portable `onResponseHeaders` hook -
|
|
9108
|
+
portable `onResponseHeaders` hook - enable the observer surface with
|
|
9109
|
+
`app.use(responseObserver())` from `@nifrajs/core/response-observer` before registering a custom
|
|
9110
|
+
hook. It remains one implementation, fast on every runtime: it mutates the
|
|
8783
9111
|
response's own `Headers` on Bun/Deno and the outcome record on Node's direct socket writer, never
|
|
8784
9112
|
materializing Web `Request`/`Response` objects. `cors` (origin reflection), static `cacheControl`,
|
|
8785
9113
|
`language`, and `poweredBy({ respectExisting: false })` are built on it. Stateful middleware (`rateLimit` with the built-in key derivation,
|
|
@@ -8898,7 +9226,13 @@ authority. If neither option is set, treat the host in `request.url` as client-c
|
|
|
8898
9226
|
|
|
8899
9227
|
The optional `static` root is served before `app.fetch` for GET and HEAD requests. It is a
|
|
8900
9228
|
public asset directory and must contain nothing private: no secrets, source maps, build
|
|
8901
|
-
metadata, or user uploads.
|
|
9229
|
+
metadata, or user uploads. The directory and its ancestor path must be read-only and owned by
|
|
9230
|
+
the service (or otherwise protected from untrusted local writers). Nifra resolves and confines
|
|
9231
|
+
the file before opening it and refuses symlinked final files, but Node does not expose a native
|
|
9232
|
+
per-component `openat` primitive; a process that can mutate the tree concurrently can still
|
|
9233
|
+
create a local TOCTOU race. Mutable or attacker-writable static trees are therefore outside the
|
|
9234
|
+
adapter's guarantee. Store user-controlled files outside the static root and serve them through
|
|
9235
|
+
an application or object-storage path with its own validation policy.
|
|
8902
9236
|
|
|
8903
9237
|
## Graceful shutdown on signals
|
|
8904
9238
|
|
|
@@ -9929,11 +10263,11 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
9929
10263
|
|
|
9930
10264
|
## @nifrajs/client
|
|
9931
10265
|
|
|
9932
|
-
`ActionArgs`, `ActionData`, `ApiError`, `ApiProxy`, `client`, `ClientOptions`, `ClientRetryOptions`, `FetchFn`, `inProcessClient`, `InProcessClient`, `InProcessClientOptions`, `Jsonify`, `LoaderArgs`, `LoaderData`, `RegistryOf`, `ResponseContractViolation`, `Result`, `SubscribeOptions`, `Subscription`, `testClient`, `Treaty`, `TreatyFromRegistry`, `WsCallOptions`, `WsHandle`
|
|
10266
|
+
`ActionArgs`, `ActionData`, `ApiError`, `ApiProxy`, `client`, `ClientOptions`, `ClientRetryOptions`, `FetchFn`, `inProcessClient`, `InProcessClient`, `InProcessClientOptions`, `Jsonify`, `LoaderArgs`, `LoaderData`, `RegistryOf`, `RESERVED_EXACT_KEYS`, `RESERVED_KEY_READOUT`, `RESERVED_VERB_KEYS`, `reservedKeyFor`, `ResponseContractViolation`, `Result`, `SubscribeOptions`, `Subscription`, `testClient`, `Treaty`, `TreatyFromRegistry`, `WsCallOptions`, `WsHandle`
|
|
9933
10267
|
|
|
9934
10268
|
## @nifrajs/content
|
|
9935
10269
|
|
|
9936
|
-
`bakeCollection`, `BakedCollection`, `Entry`, `fromBaked`, `InferSchema`, `parseEntry`, `ParseEntryOptions`, `parseFrontmatter`, `StandardSchemaV1`, `StaticCollection`
|
|
10270
|
+
`bakeCollection`, `BakedCollection`, `BakedCollectionIndex`, `BakedCollectionJoin`, `BakedIndexBucket`, `ContentFieldKey`, `Entry`, `fromBaked`, `fromBakedIndex`, `fromBakedJoin`, `indexCollection`, `IndexedCollection`, `IndexedJoin`, `IndexOptions`, `IndexPage`, `IndexQueryOptions`, `IndexRange`, `IndexRanges`, `IndexSort`, `IndexWhere`, `InferSchema`, `JoinCardinality`, `joinCollections`, `JoinedRow`, `parseEntry`, `ParseEntryOptions`, `parseFrontmatter`, `SharedKey`, `StandardSchemaV1`, `StaticCollection`
|
|
9937
10271
|
|
|
9938
10272
|
## @nifrajs/core
|
|
9939
10273
|
|
|
@@ -9951,6 +10285,10 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
9951
10285
|
|
|
9952
10286
|
`devtools`, `DevToolsClientOptions`, `devtoolsClientScript`, `DevToolsEvent`, `DevToolsOptions`, `DevToolsQuery`, `filterDevToolsEvents`
|
|
9953
10287
|
|
|
10288
|
+
## @nifrajs/edge
|
|
10289
|
+
|
|
10290
|
+
`EdgeContext`, `EdgeHandler`, `EdgeOptions`, `EdgeServer`, `Method`, `Params`, `QueryValue`, `server`, `StandardSchemaV1`, `toFetchHandler`
|
|
10291
|
+
|
|
9954
10292
|
## @nifrajs/env
|
|
9955
10293
|
|
|
9956
10294
|
`boolean`, `defineEnv`, `DefineEnvOptions`, `enumValue`, `env`, `EnvResult`, `EnvShape`, `InferOutput`, `number`, `port`, `StandardResult`, `StandardSchemaV1`, `string`, `url`
|
|
@@ -9967,9 +10305,13 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
9967
10305
|
|
|
9968
10306
|
`cloudflareLoader`, `CloudflareLoaderOptions`, `createPngRasterizer`, `createResvgRasterizer`, `HtmlImageAttrs`, `identityLoader`, `imageDimensions`, `ImageFormat`, `ImageInfo`, `ImageLoader`, `ImageProps`, `OgImageOptions`, `OgImageRasterized`, `OgImageRasterizer`, `ogImageResponse`, `PngRenderer`, `readImageDimensions`, `renderOgImage`, `ResolvedImage`, `resolveImage`, `ResvgConstructor`, `ResvgRenderer`, `selfHostedLoader`, `SelfHostedLoaderOptions`, `signImageUrl`, `SignImageUrlOptions`, `toHtmlAttrs`
|
|
9969
10307
|
|
|
10308
|
+
## @nifrajs/island-trigger
|
|
10309
|
+
|
|
10310
|
+
`IslandStrategy`, `MAX_MEDIA_QUERY_LENGTH`, `scheduleTrigger`, `TriggerOptions`
|
|
10311
|
+
|
|
9970
10312
|
## @nifrajs/islets
|
|
9971
10313
|
|
|
9972
|
-
`batch`, `BindableElement`, `BindableRoot`, `bindScope`, `computed`, `effect`, `island`, `IslandContext`, `IslandHost`, `IslandScope`, `IslandSetup`, `islandState`, `mountIslands`, `signal`, `Signal`
|
|
10314
|
+
`batch`, `BindableElement`, `BindableRoot`, `bindScope`, `computed`, `effect`, `island`, `IslandContext`, `IslandHost`, `IslandScope`, `IslandSetup`, `islandState`, `IslandStrategy`, `MountIslandOptions`, `mountIslands`, `signal`, `Signal`
|
|
9973
10315
|
|
|
9974
10316
|
## @nifrajs/jobs
|
|
9975
10317
|
|
|
@@ -10005,7 +10347,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
10005
10347
|
|
|
10006
10348
|
## @nifrajs/proxy
|
|
10007
10349
|
|
|
10008
|
-
`createProxy`, `ProxyContext`, `ProxyHandler`, `ProxyOptions`
|
|
10350
|
+
`createProxy`, `fetchTransport`, `FetchTransportOptions`, `NativeProxyTransport`, `NativeProxyTransportRequest`, `NativeProxyUpstreamResponse`, `NodeNativeProxyRequest`, `NodeNativeProxyResponse`, `ProxyContext`, `ProxyHandler`, `ProxyOptions`, `ProxyTransport`, `ProxyUpstreamRequest`, `ProxyUpstreamResponse`
|
|
10009
10351
|
|
|
10010
10352
|
## @nifrajs/runner
|
|
10011
10353
|
|
|
@@ -10033,7 +10375,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
10033
10375
|
|
|
10034
10376
|
## @nifrajs/web
|
|
10035
10377
|
|
|
10036
|
-
`Action`, `ACTION_GLOBAL`, `apiKey`, `assertRenderAdapterConformance`, `Blocker`, `BlockerController`, `BlockerFunction`, `BlockerLocation`, `BlockerState`, `BrowserNavigate`, `buildManifest`, `CachedResponse`, `CacheStore`, `canonical`, `clientEntry`, `ClientRouter`, `ClientRouterOptions`, `createClientRouter`, `createMatcher`, `createMutation`, `createQueryClient`, `createWebApp`, `CreateWebAppOptions`, `DATA_GLOBAL`, `DATA_HEADER`, `DEFAULT_DEV_PORT`, `defer`, `Deferred`, `DehydratedState`, `disableDraft`, `DRAFT_COOKIE`, `DraftCookieControls`, `enableDraft`, `EnableDraftOptions`, `enumerateStaticRoutes`, `Fetcher`, `FetcherState`, `FetchRouteData`, `filePathToPattern`, `filePathToPatterns`, `FontDisplay`, `fontFace`, `FontFace`, `fontPreload`, `FontPreloadInput`, `FontSource`, `gate`, `generateClientEntry`, `GenerateClientEntryOptions`, `generateRouteSearchTypes`, `GenerateRouteSearchTypesOptions`, `generateServerManifest`, `GenerateServerManifestOptions`, `getBrowserNavigate`, `GetStaticPaths`, `gone`, `hashQueryKey`, `IDLE_BLOCKER`, `InertScriptType`, `InfiniteData`, `InfiniteQueryHandle`, `InfiniteQueryOptions`, `isDraftEnabled`, `ISR_REVALIDATE_HEADER`, `ISR_REVALIDATE_TAGS_HEADER`, `ISR_STATUS_HEADER`, `ISRApp`, `ISROptions`, `ISRPlatform`, `jsonLd`, `KVCacheStore`, `KVCacheStoreOptions`, `KVNamespaceLike`, `LAYOUT_DATA_GLOBAL`, `LayoutEntry`, `LinkDescriptor`, `Loader`, `LoaderContext`, `manifest`, `Manifest`, `MemoryCacheStore`, `MemoryCacheStoreOptions`, `mergeHeads`, `meta`, `Meta`, `MetaArgs`, `MetaDescriptor`, `MetaInput`, `MountRouterOptions`, `MutationCallbacks`, `MutationHandle`, `MutationState`, `MutationStatus`, `NAV_FROM_HEADER`, `NavigateFunction`, `NavigateOptions`, `NavigateSearchOf`, `NavigateTargetInput`, `notFound`, `openGraph`, `OpenGraphInput`, `PRE_HYDRATION_GUARD`, `previewEndpoint`, `PreviewEndpointOptions`, `PublicDirCache`, `QueryClient`, `QueryClientOptions`, `QueryHandle`, `QueryOptions`, `QueryState`, `QueryStatus`, `redirect`, `REDIRECT_HEADER`, `RedirectOptions`, `registerBlocker`, `RenderAdapter`, `RenderAdapterConformanceError`, `RenderAdapterConformanceFixture`, `RenderAssemblyCache`, `RenderedPage`, `renderPage`, `RenderPageInput`, `RenderPageOptions`, `renderPageResult`, `RenderProps`, `resolveMeta`, `resolveNavigate`, `resolvePublicPath`, `RETAIN_HEADER`, `revalidate`, `REVALIDATE_HEADER`, `revalidateEndpoint`, `RevalidateEndpointOptions`, `RevalidateResult`, `ROOT_ATTRIBUTE`, `ROUTE_GLOBAL`, `RouteEntry`, `RouteMatch`, `RouteModule`, `RoutePattern`, `RouterState`, `RouteSearch`, `routeStyles`, `ScriptDescriptor`, `searchOf`, `SearchOf`, `searchOfChain`, `serializeData`, `serializeSearch`, `servePublicDir`, `ServePublicDirOptions`, `SERVER_FN_MODULE`, `SERVER_ONLY_MODULE`, `ServerOnly`, `setBlockerController`, `setBrowserNavigate`, `setSsrModuleLoader`, `ssrModuleLoader`, `SsrModuleLoader`, `StaticPath`, `StaticPaths`, `StaticRoutes`, `STATUS_HEADER`, `statusPage`, `StatusPageOptions`, `styles`, `Submission`, `SubmitOptions`, `unsafeInlineScript`, `UnsafeScriptDescriptor`, `withISR`
|
|
10378
|
+
`Action`, `ACTION_GLOBAL`, `apiKey`, `assertRenderAdapterConformance`, `assertStaticBoundaryImports`, `Blocker`, `BlockerController`, `BlockerFunction`, `BlockerLocation`, `BlockerState`, `Boundary`, `BOUNDARY_GLOBAL`, `BoundaryDescriptor`, `boundaryDescriptors`, `BoundaryError`, `BoundaryMode`, `boundaryModeKey`, `BoundaryRegistration`, `BoundaryRequestCtx`, `BoundaryState`, `BoundaryStates`, `BoundaryStatus`, `BrowserNavigate`, `buildManifest`, `CachedResponse`, `CacheStore`, `canonical`, `ClientAction`, `ClientActionArgs`, `ClientActionResult`, `clientEntry`, `ClientLoader`, `ClientLoaderArgs`, `ClientRequestBody`, `ClientRouteHooks`, `ClientRouter`, `ClientRouterOptions`, `createClientRouter`, `createMatcher`, `createMutation`, `createQueryClient`, `createWebApp`, `CreateWebAppOptions`, `DATA_GLOBAL`, `DATA_HEADER`, `DEFAULT_DEV_PORT`, `defer`, `Deferred`, `DehydratedState`, `disableDraft`, `DRAFT_COOKIE`, `DraftCookieControls`, `DynamicBoundary`, `DynamicBoundaryBatch`, `enableDraft`, `EnableDraftOptions`, `enumerateStaticRoutes`, `Fetcher`, `FetcherState`, `FetchRouteData`, `filePathToPattern`, `filePathToPatterns`, `FontDisplay`, `fontFace`, `FontFace`, `fontPreload`, `FontPreloadInput`, `FontSource`, `gate`, `generateClientEntry`, `GenerateClientEntryOptions`, `generateRouteSearchTypes`, `GenerateRouteSearchTypesOptions`, `generateServerManifest`, `GenerateServerManifestOptions`, `getBrowserNavigate`, `GetStaticPaths`, `gone`, `hashQueryKey`, `IDLE_BLOCKER`, `InertScriptType`, `InfiniteData`, `InfiniteQueryHandle`, `InfiniteQueryOptions`, `InterceptBoundary`, `isDraftEnabled`, `ISR_REVALIDATE_HEADER`, `ISR_REVALIDATE_TAGS_HEADER`, `ISR_STATUS_HEADER`, `ISRApp`, `ISROptions`, `ISRPlatform`, `jsonLd`, `KVCacheStore`, `KVCacheStoreOptions`, `KVNamespaceLike`, `LAYOUT_DATA_GLOBAL`, `LayoutEntry`, `LinkDescriptor`, `Loader`, `LoaderContext`, `manifest`, `Manifest`, `MemoryCacheStore`, `MemoryCacheStoreOptions`, `MemoryStaticBoundaryCache`, `mergeHeads`, `meta`, `Meta`, `MetaArgs`, `MetaDescriptor`, `MetaInput`, `MountRouterOptions`, `MutationCallbacks`, `MutationHandle`, `MutationState`, `MutationStatus`, `NAV_FROM_HEADER`, `NavigateFunction`, `NavigateOptions`, `NavigateSearchOf`, `NavigateTargetInput`, `notFound`, `openGraph`, `OpenGraphInput`, `PendingBoundary`, `PRE_HYDRATION_GUARD`, `previewEndpoint`, `PreviewEndpointOptions`, `PublicDirCache`, `QueryClient`, `QueryClientOptions`, `QueryHandle`, `QueryOptions`, `QueryState`, `QueryStatus`, `redirect`, `REDIRECT_HEADER`, `RedirectOptions`, `registerBlocker`, `RenderAdapter`, `RenderAdapterConformanceError`, `RenderAdapterConformanceFixture`, `RenderAssemblyCache`, `RenderedPage`, `renderPage`, `RenderPageInput`, `RenderPageOptions`, `renderPageResult`, `RenderProps`, `resolveDynamicBoundaries`, `resolveMeta`, `resolveNavigate`, `resolvePublicPath`, `resolveStaticBoundaries`, `RETAIN_HEADER`, `revalidate`, `REVALIDATE_HEADER`, `revalidateEndpoint`, `RevalidateEndpointOptions`, `RevalidateResult`, `ROOT_ATTRIBUTE`, `ROUTE_GLOBAL`, `RouteEntry`, `RouteMatch`, `RouteModule`, `RoutePattern`, `RouterState`, `RouteSearch`, `routeStyles`, `ScriptDescriptor`, `searchOf`, `SearchOf`, `searchOfChain`, `serializeData`, `serializeSearch`, `servePublicDir`, `ServePublicDirOptions`, `SERVER_FN_MODULE`, `SERVER_ONLY_MODULE`, `ServerOnly`, `setBlockerController`, `setBrowserNavigate`, `setSsrModuleLoader`, `ssrModuleLoader`, `SsrModuleLoader`, `startDynamicBoundaries`, `StaticBoundary`, `StaticBoundaryCache`, `StaticBoundaryImportEdge`, `StaticBoundaryRoot`, `StaticCtx`, `StaticPath`, `StaticPaths`, `StaticRoutes`, `STATUS_HEADER`, `statusPage`, `StatusPageOptions`, `styles`, `Submission`, `SubmitOptions`, `unsafeInlineScript`, `UnsafeScriptDescriptor`, `withISR`
|
|
10037
10379
|
|
|
10038
10380
|
## @nifrajs/web-preact
|
|
10039
10381
|
|