@weftui/router 0.27.0 → 0.27.1
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/README.md +3 -1
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +2 -2
- package/dist/{compile-DWdMZiMt.d.ts → compile-BJFIgBbE.d.ts} +9 -9
- package/dist/{href-DD8PoCGO.js → href-uvJ6b7zz.js} +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{outlet-ty5ZYKBW.js → outlet-C9N4a4_F.js} +2 -2
- package/dist/{outlet-BiFb5gdK.d.ts → outlet-eoUQ-W0k.d.ts} +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/docs/explanation/boundaries-and-suspense.md +2 -2
- package/docs/explanation/services-and-context.md +1 -1
- package/docs/how-to/add-routing.md +1 -1
- package/docs/how-to/provide-services.md +1 -1
- package/docs/reference/router.md +1 -1
- package/docs/tutorial/01-your-first-app.md +3 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -9,9 +9,11 @@ Three entry points mirror `@weftui/dom`: `@weftui/router` (authoring + universal
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npm install @weftui/core @weftui/dom @weftui/router effect
|
|
12
|
+
npm install @weftui/core @weftui/dom @weftui/router effect@beta
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
Weft tracks Effect 4's beta line. This release is built and tested against `effect@4.0.0-beta.98`; the peer range accepts newer 4.0 betas, which may contain upstream breaking changes.
|
|
16
|
+
|
|
15
17
|
`effect` is a peer dependency; `@weftui/core` and `@weftui/dom` provide the tree and renderer.
|
|
16
18
|
|
|
17
19
|
## Key exports
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as Router, b as NavState, i as RouterDef, m as RouteNode, u as Fields, x as NavigateOptions } from "../compile-
|
|
2
|
-
import { n as outletNode, r as HrefArgs, t as RouterApp } from "../outlet-
|
|
1
|
+
import { S as Router, b as NavState, i as RouterDef, m as RouteNode, u as Fields, x as NavigateOptions } from "../compile-BJFIgBbE.js";
|
|
2
|
+
import { n as outletNode, r as HrefArgs, t as RouterApp } from "../outlet-eoUQ-W0k.js";
|
|
3
3
|
import { Effect, Layer, Scope } from "effect";
|
|
4
4
|
import { AppRpcClientTag } from "@weftui/core";
|
|
5
5
|
import { RpcGroup } from "effect/unstable/rpc";
|
package/dist/client/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as Router, i as setResolvedCommit, n as outletNode, o as getPreload, r as preRunLeaf, t as RouterApp } from "../outlet-
|
|
2
|
-
import { r as match, t as href } from "../href-
|
|
1
|
+
import { a as Router, i as setResolvedCommit, n as outletNode, o as getPreload, r as preRunLeaf, t as RouterApp } from "../outlet-C9N4a4_F.js";
|
|
2
|
+
import { r as match, t as href } from "../href-uvJ6b7zz.js";
|
|
3
3
|
import { HttpApiClient } from "effect/unstable/httpapi";
|
|
4
4
|
import { Context, Effect, Exit, Fiber, Layer, Option, Schema, Scope, Stream, SubscriptionRef } from "effect";
|
|
5
5
|
import { AppRpcClientTag, Subscribable } from "@weftui/core";
|
|
@@ -66,9 +66,9 @@ interface MatcherEntry {
|
|
|
66
66
|
readonly leaf: CompiledLeaf;
|
|
67
67
|
readonly regex: RegExp;
|
|
68
68
|
readonly paramNames: readonly string[];
|
|
69
|
-
/** Path-param schema, read from the endpoint's `
|
|
69
|
+
/** Path-param schema, read from the endpoint's `params` slot. */
|
|
70
70
|
readonly pathSchema: ParamSchema;
|
|
71
|
-
/** Query schema, read from the endpoint's `
|
|
71
|
+
/** Query schema, read from the endpoint's `query` slot. */
|
|
72
72
|
readonly querySchema: ParamSchema;
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
@@ -111,7 +111,7 @@ declare function match(def: RouterDef, url: string): RouteMatch;
|
|
|
111
111
|
*/
|
|
112
112
|
/**
|
|
113
113
|
* The platform `HttpApiClient` derived from a router's `HttpApi` spine. Typed
|
|
114
|
-
* opaquely (`Client<any, …>`) because the spine is `HttpApi.
|
|
114
|
+
* opaquely (`Client<any, …>`) because the spine is `HttpApi.Top` — its
|
|
115
115
|
* group/endpoint shapes are assembled in a runtime loop by `buildHttpApi`, so a
|
|
116
116
|
* precise client type is not recoverable. Present (`Option.some`) on the client
|
|
117
117
|
* (`RouterLive`), absent (`Option.none`) on the server, which is itself the origin.
|
|
@@ -452,14 +452,14 @@ interface CompiledLeaf {
|
|
|
452
452
|
/**
|
|
453
453
|
* Path-param schema. Its **encoded** side is typed string-encodeable
|
|
454
454
|
* (`Record<string, string | undefined>`) so it satisfies platform's
|
|
455
|
-
* `HttpApiEndpoint
|
|
455
|
+
* `HttpApiEndpoint` `params` constraint without an `as any` cast — param schemas
|
|
456
456
|
* round-trip strings, so the `Schema.Struct` value is asserted to this shape.
|
|
457
457
|
*/
|
|
458
458
|
readonly pathSchema: Schema.Codec<Record<string, unknown>, Readonly<Record<string, string | undefined>>>;
|
|
459
459
|
/**
|
|
460
460
|
* Query schema. Its **encoded** side is typed string-encodeable
|
|
461
461
|
* (`Record<string, string | ReadonlyArray<string> | undefined>`) so it satisfies
|
|
462
|
-
* platform's `HttpApiEndpoint
|
|
462
|
+
* platform's `HttpApiEndpoint` `query` constraint without a cast.
|
|
463
463
|
*/
|
|
464
464
|
readonly querySchema: Schema.Codec<Record<string, unknown>, Readonly<Record<string, string | ReadonlyArray<string> | undefined>>>;
|
|
465
465
|
/** The page's component slot; invoked per render, reads params via `Router.params` / `Router.query`. */
|
|
@@ -489,7 +489,7 @@ interface RouterDef<E = any, R = any> {
|
|
|
489
489
|
* nesting/render metadata platform's flat API can't represent. Built by
|
|
490
490
|
* {@link buildHttpApi} during {@link makeRouter}.
|
|
491
491
|
*/
|
|
492
|
-
readonly httpApi: HttpApi.
|
|
492
|
+
readonly httpApi: HttpApi.Top;
|
|
493
493
|
/**
|
|
494
494
|
* Phantom marker for the tree's aggregate error channel. Covariant (stores `E`
|
|
495
495
|
* directly) so a fully-static `RouterDef<never, never>` stays assignable to the
|
|
@@ -527,20 +527,20 @@ declare function compile(def: {
|
|
|
527
527
|
/**
|
|
528
528
|
* Builds the authoritative `HttpApi` for a compiled tree (S4): a single `"pages"`
|
|
529
529
|
* group whose endpoints are GET endpoints — one per leaf — at each leaf's full path
|
|
530
|
-
* pattern, carrying `
|
|
530
|
+
* pattern, carrying `params: pathSchema`, `query: querySchema`, a
|
|
531
531
|
* `Schema.String` (text/HTML) success, and a `RouterNotFound → 404` error. The tree
|
|
532
532
|
* (not `HttpApi`) is the authoring surface; this is the single source of truth the
|
|
533
533
|
* server dispatch (`HttpApiBuilder`) and the client matcher / derived `HttpApiClient`
|
|
534
534
|
* read from, so both sides agree on paths and schemas.
|
|
535
535
|
*
|
|
536
536
|
* Each leaf's `pathSchema`/`querySchema` are typed string-encodeable (see
|
|
537
|
-
* {@link CompiledLeaf}), so `
|
|
537
|
+
* {@link CompiledLeaf}), so the `params`/`query` options need no `as any` casts.
|
|
538
538
|
*
|
|
539
539
|
* `Boundary.rpc` data no longer rides this spine: it resolves through the app's
|
|
540
540
|
* merged `RpcGroup` over the ambient `AppRpcClient` (`POST /_eui/rpc`), wired
|
|
541
541
|
* explicitly into `RouterServer`/`RouterLive`. The matcher reads only `"pages"`.
|
|
542
542
|
*/
|
|
543
|
-
declare function buildHttpApi(leaves: readonly CompiledLeaf[]): HttpApi.
|
|
543
|
+
declare function buildHttpApi(leaves: readonly CompiledLeaf[]): HttpApi.Top;
|
|
544
544
|
/**
|
|
545
545
|
* Seals a route tree into a {@link RouterDef}, compiling it eagerly (so leaf
|
|
546
546
|
* references are stamped for `href`), building its authoritative {@link buildHttpApi}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { l as leafRegistry } from "./outlet-
|
|
1
|
+
import { l as leafRegistry } from "./outlet-C9N4a4_F.js";
|
|
2
2
|
import { Result, Schema } from "effect";
|
|
3
3
|
//#region src/matcher.ts
|
|
4
4
|
/** Escapes a literal path segment for inclusion in a `RegExp`. */
|
|
@@ -50,7 +50,7 @@ function compileMatchers(def) {
|
|
|
50
50
|
const endpoints = def.httpApi.groups["pages"]?.endpoints ?? {};
|
|
51
51
|
const entries = [];
|
|
52
52
|
for (const endpoint of Object.values(endpoints)) {
|
|
53
|
-
const leaf = leafById.get(endpoint.
|
|
53
|
+
const leaf = leafById.get(endpoint.identifier);
|
|
54
54
|
if (leaf === void 0) continue;
|
|
55
55
|
entries.push({
|
|
56
56
|
leaf,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as notFound, C as RouterHttpApiClient, D as RouterNotFound, E as match, O as RouterParamsError, S as Router, T as compileMatchers, _ as TreeE, a as RouterOptions, b as NavState, c as leafRegistry, d as FieldsType, f as LayoutNode, g as SubtreeR, h as SubtreeE, i as RouterDef, k as isRouterNotFound, l as ComponentSlot, m as RouteNode, n as CompiledLayout, o as buildHttpApi, p as RouteHandlerProps, r as CompiledLeaf, s as compile, t as Compiled, u as Fields, v as TreeNode, w as RouteMatch, x as NavigateOptions, y as TreeR } from "./compile-
|
|
2
|
-
import { i as href, n as outletNode, r as HrefArgs, t as RouterApp } from "./outlet-
|
|
1
|
+
import { A as notFound, C as RouterHttpApiClient, D as RouterNotFound, E as match, O as RouterParamsError, S as Router, T as compileMatchers, _ as TreeE, a as RouterOptions, b as NavState, c as leafRegistry, d as FieldsType, f as LayoutNode, g as SubtreeR, h as SubtreeE, i as RouterDef, k as isRouterNotFound, l as ComponentSlot, m as RouteNode, n as CompiledLayout, o as buildHttpApi, p as RouteHandlerProps, r as CompiledLeaf, s as compile, t as Compiled, u as Fields, v as TreeNode, w as RouteMatch, x as NavigateOptions, y as TreeR } from "./compile-BJFIgBbE.js";
|
|
2
|
+
import { i as href, n as outletNode, r as HrefArgs, t as RouterApp } from "./outlet-eoUQ-W0k.js";
|
|
3
3
|
export { type Compiled, type CompiledLayout, type CompiledLeaf, type ComponentSlot, type Fields, type FieldsType, type HrefArgs, type LayoutNode, type NavState, type NavigateOptions, type RouteHandlerProps, type RouteMatch, type RouteNode, Router, RouterApp, type RouterDef, type RouterHttpApiClient, RouterNotFound, type RouterOptions, RouterParamsError, type SubtreeE, type SubtreeR, type TreeE, type TreeNode, type TreeR, buildHttpApi, compile, compileMatchers, href, isRouterNotFound, leafRegistry, match, notFound, outletNode };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as Router, c as compile, d as RouterParamsError, f as isRouterNotFound, l as leafRegistry, n as outletNode, p as notFound, s as buildHttpApi, t as RouterApp, u as RouterNotFound } from "./outlet-
|
|
2
|
-
import { n as compileMatchers, r as match, t as href } from "./href-
|
|
1
|
+
import { a as Router, c as compile, d as RouterParamsError, f as isRouterNotFound, l as leafRegistry, n as outletNode, p as notFound, s as buildHttpApi, t as RouterApp, u as RouterNotFound } from "./outlet-C9N4a4_F.js";
|
|
2
|
+
import { n as compileMatchers, r as match, t as href } from "./href-uvJ6b7zz.js";
|
|
3
3
|
export { Router, RouterApp, RouterNotFound, RouterParamsError, buildHttpApi, compile, compileMatchers, href, isRouterNotFound, leafRegistry, match, notFound, outletNode };
|
|
@@ -157,14 +157,14 @@ function compile(def) {
|
|
|
157
157
|
/**
|
|
158
158
|
* Builds the authoritative `HttpApi` for a compiled tree (S4): a single `"pages"`
|
|
159
159
|
* group whose endpoints are GET endpoints — one per leaf — at each leaf's full path
|
|
160
|
-
* pattern, carrying `
|
|
160
|
+
* pattern, carrying `params: pathSchema`, `query: querySchema`, a
|
|
161
161
|
* `Schema.String` (text/HTML) success, and a `RouterNotFound → 404` error. The tree
|
|
162
162
|
* (not `HttpApi`) is the authoring surface; this is the single source of truth the
|
|
163
163
|
* server dispatch (`HttpApiBuilder`) and the client matcher / derived `HttpApiClient`
|
|
164
164
|
* read from, so both sides agree on paths and schemas.
|
|
165
165
|
*
|
|
166
166
|
* Each leaf's `pathSchema`/`querySchema` are typed string-encodeable (see
|
|
167
|
-
* {@link CompiledLeaf}), so `
|
|
167
|
+
* {@link CompiledLeaf}), so the `params`/`query` options need no `as any` casts.
|
|
168
168
|
*
|
|
169
169
|
* `Boundary.rpc` data no longer rides this spine: it resolves through the app's
|
|
170
170
|
* merged `RpcGroup` over the ambient `AppRpcClient` (`POST /_eui/rpc`), wired
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as RouterNotFound, S as Router, d as FieldsType, i as RouterDef, m as RouteNode, u as Fields } from "./compile-
|
|
1
|
+
import { D as RouterNotFound, S as Router, d as FieldsType, i as RouterDef, m as RouteNode, u as Fields } from "./compile-BJFIgBbE.js";
|
|
2
2
|
import { Node } from "@weftui/core";
|
|
3
3
|
|
|
4
4
|
//#region src/href.d.ts
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as Router, i as RouterDef, l as ComponentSlot } from "../compile-
|
|
1
|
+
import { S as Router, i as RouterDef, l as ComponentSlot } from "../compile-BJFIgBbE.js";
|
|
2
2
|
import { Effect, Layer } from "effect";
|
|
3
3
|
import { AppRpcClientTag } from "@weftui/core";
|
|
4
4
|
import { RpcGroup } from "effect/unstable/rpc";
|
package/dist/server/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Router, f as isRouterNotFound, n as outletNode, u as RouterNotFound } from "../outlet-
|
|
1
|
+
import { a as Router, f as isRouterNotFound, n as outletNode, u as RouterNotFound } from "../outlet-C9N4a4_F.js";
|
|
2
2
|
import { HttpApiBuilder, HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi";
|
|
3
3
|
import { Cause, Effect, Exit, Layer, Option, Schema, Scope, Stream } from "effect";
|
|
4
4
|
import { AppRpcClientTag, Subscribable } from "@weftui/core";
|
|
@@ -38,9 +38,9 @@ The channel algebra is the whole reason they exist: `catchTag("Foo", …)` remov
|
|
|
38
38
|
|
|
39
39
|
The routing above describes what happens while a node is being built. Once mounted, a reactive region — an attribute, child, or list stream, or a hydrated equivalent — keeps running for the lifetime of its scope, and it can still fail later: a `Stream` backing a `Boundary.rpc` resource might raise `RouterNotFound` after a client-side navigation, for instance. If a `BoundaryContext` encloses the region, the failure routes to it exactly as above, and the boundary's fallback swaps in.
|
|
40
40
|
|
|
41
|
-
If no boundary encloses it, there is nothing to swap to. Weft does not synthesize one: the region's DOM keeps its last rendered content, and
|
|
41
|
+
If no boundary encloses it, there is nothing to swap to. Weft does not synthesize one: the region's DOM keeps its last rendered content, and a watcher fiber — forked into the same scope alongside the subscription itself — observes its exit directly. When that exit is a failure whose cause is not interruption-only, Weft reports it explicitly via `Effect.logError(exit.cause)`, annotated with `weft.region` to identify the failing region by kind and identity (e.g. `attribute:class`, `child:stream-3`, `list:stream-2`, `hydrate:stream-1 (/products/42)`). This fires for typed failures and defects alike, in both dev and prod, exactly once per failing region, at the `"Error"` level. Interruption — the ordinary case of unmount tearing down the region's scope — is never reported; only genuine failures are.
|
|
42
42
|
|
|
43
|
-
This is deliberate: rather than
|
|
43
|
+
This is deliberate: rather than leaving the failure to whatever the Effect runtime would otherwise do with an unobserved fiber exit, Weft observes and logs it itself, so visibility is controlled by the same knobs any Effect program uses — `References.MinimumLogLevel` (provided via `Effect.provideService`) to filter it, or a custom `Logger` to route it elsewhere. A stream that can fail and has no enclosing boundary is a stream whose failures you've chosen not to route into the UI — the log is what tells you that decision has consequences at runtime.
|
|
44
44
|
|
|
45
45
|
## Suspense boundaries
|
|
46
46
|
|
|
@@ -29,7 +29,7 @@ Services flow **down** from that provide point to every reader, including across
|
|
|
29
29
|
|
|
30
30
|
## Layer lifetime at the mount
|
|
31
31
|
|
|
32
|
-
The `ThemeServiceLive` example above works because `mount`'s effect and the service's lifetime coincide by accident: `ThemeServiceLive` is a plain value layer with nothing to release, so it makes no difference whether it is "alive" for one tick or the whole session. That accident stops holding the moment the layer is **scoped** — built
|
|
32
|
+
The `ThemeServiceLive` example above works because `mount`'s effect and the service's lifetime coincide by accident: `ThemeServiceLive` is a plain value layer with nothing to release, so it makes no difference whether it is "alive" for one tick or the whole session. That accident stops holding the moment the layer is **scoped** — built from an `acquireRelease`-backed `Layer.effect` — because `mount`'s effect resolves right after the tree's **initial render**, not when the app stops running. Streams, event handlers, and forked work all keep running on the mount's runtime long after that Effect has settled.
|
|
33
33
|
|
|
34
34
|
`Effect.provide(scopedLayer)` is `acquireUseRelease` sugar: acquire, run the wrapped effect, then release **when that effect completes**. Wrap it directly around `mount`, and the release runs at mount-resolve — while the mounted tree is still reading from the now-disposed service:
|
|
35
35
|
|
|
@@ -280,7 +280,7 @@ export const handler = RouterServer.toWebHandler(App, { document: documentShell
|
|
|
280
280
|
|
|
281
281
|
### `effect/unstable/httpapi` is the spine
|
|
282
282
|
|
|
283
|
-
The tree is the authoring surface, but `effect/unstable/httpapi`'s `HttpApi` is the **single source of truth** for paths and schemas. Sealing the tree with `Router.router(...)` builds it once (`buildHttpApi`) and stamps it onto `def.httpApi`: a single `"pages"` group with one GET endpoint per leaf at its full path pattern, carrying `
|
|
283
|
+
The tree is the authoring surface, but `effect/unstable/httpapi`'s `HttpApi` is the **single source of truth** for paths and schemas. Sealing the tree with `Router.router(...)` builds it once (`buildHttpApi`) and stamps it onto `def.httpApi`: a single `"pages"` group with one GET endpoint per leaf at its full path pattern, carrying `params: pathSchema`, `query: querySchema`, and a `RouterNotFound → 404` error. Both sides read that one definition, so they always agree:
|
|
284
284
|
|
|
285
285
|
- **Server** — `RouterServer` dispatches through `HttpApiBuilder` (platform owns request→leaf matching, path/query decode, and the 404 status).
|
|
286
286
|
- **Client** — `RouterLive` derives a real `HttpApiClient` from the same `def.httpApi` (exposed as `Router.httpApiClient`) for network work. SPA URL→leaf resolution stays **local** (there is no public client-side "match this URL against my `HttpApi`" utility in platform), fed from the same endpoint definitions so it never drifts from the server.
|
|
@@ -9,7 +9,7 @@ description: Provide plain and scoped Layers to a mounted app — the direct mou
|
|
|
9
9
|
|
|
10
10
|
**Goal:** provide a `Layer` to the mounted app so its components can read services with `yield* Service`.
|
|
11
11
|
|
|
12
|
-
Which recipe to reach for depends on whether the layer has anything to release. A plain value layer (`Layer.succeed`, `Layer.effect`
|
|
12
|
+
Which recipe to reach for depends on whether the layer has anything to release. Both plain and scoped layers are built with `Layer.succeed` or `Layer.effect` — the distinction is whether the layer's effect acquires releasable resources (`acquireRelease`, or a scope finalizer added directly). A plain value layer (`Layer.succeed`, or `Layer.effect` whose effect has no `acquireRelease`) can be provided directly at the mount — there is nothing to leak. A **scoped** layer (`Layer.effect` whose effect is backed by `acquireRelease`) needs the mount to outlive the effect's own resolution — see [Layer lifetime at the mount](https://weftui.dev/docs/explanation/services-and-context#layer-lifetime-at-the-mount) for why.
|
|
13
13
|
|
|
14
14
|
## Recipe 1 — plain value layers with `mount`
|
|
15
15
|
|
package/docs/reference/router.md
CHANGED
|
@@ -323,7 +323,7 @@ These power the runtime and are exported for tooling/tests; most apps never touc
|
|
|
323
323
|
| Export | Description |
|
|
324
324
|
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
325
325
|
| `compile(def)` | Walks a tree into flat `CompiledLeaf`s with merged path/query schemas and layout chains. |
|
|
326
|
-
| `buildHttpApi(leaves)` | Builds the authoritative `HttpApi` (one `"pages"` group, a GET endpoint per leaf with `
|
|
326
|
+
| `buildHttpApi(leaves)` | Builds the authoritative `HttpApi` (one `"pages"` group, a GET endpoint per leaf with `params`/`query` schemas + 404). Called by `Router.router`; the result is `def.httpApi`. |
|
|
327
327
|
| `leafRegistry` | `WeakMap<RouteNode, CompiledLeaf>` read by `href` to resolve a leaf's pattern/schemas. |
|
|
328
328
|
| `match(compiled, url)` | Resolves a URL to a `RouteMatch` (`Matched` with decoded `path`/`query`, or `NotFound`). |
|
|
329
329
|
| `compileMatchers(compiled)` | Precompiles per-leaf regex matchers. |
|
|
@@ -14,9 +14,11 @@ We assume you know [Effect](https://effect.website/docs/getting-started/introduc
|
|
|
14
14
|
## Install
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
npm install @weftui/core @weftui/dom effect
|
|
17
|
+
npm install @weftui/core @weftui/dom effect@beta
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
Weft tracks Effect 4's beta line. This release is built and tested against `effect@4.0.0-beta.98`; the peer range accepts newer 4.0 betas, which may contain upstream breaking changes.
|
|
21
|
+
|
|
20
22
|
`@weftui/core` gives you the element builders and combinators; `@weftui/dom` renders them (its `./client` entry mounts in the browser). `effect` is the peer everything is built on.
|
|
21
23
|
|
|
22
24
|
## Build a component
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weftui/router",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.1",
|
|
4
4
|
"description": "Universal nested router for Weft — one route tree, server and client, with type-safe params and href",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"effect",
|
|
@@ -44,13 +44,13 @@
|
|
|
44
44
|
"access": "public"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@weftui/core": "0.27.
|
|
48
|
-
"@weftui/dom": "0.27.
|
|
47
|
+
"@weftui/core": "0.27.1",
|
|
48
|
+
"@weftui/dom": "0.27.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/jsdom": "^28.0.3",
|
|
52
52
|
"@types/node": "^25.9.2",
|
|
53
|
-
"effect": "4.0.0-beta.
|
|
53
|
+
"effect": "4.0.0-beta.98",
|
|
54
54
|
"jsdom": "^29.1.1",
|
|
55
55
|
"tsx": "^4.22.4",
|
|
56
56
|
"typescript": "^6.0.3",
|
|
@@ -58,6 +58,6 @@
|
|
|
58
58
|
"vite-plus": "0.2.2"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"effect": "4.0.0-beta.
|
|
61
|
+
"effect": ">=4.0.0-beta.98 <4.0.0"
|
|
62
62
|
}
|
|
63
63
|
}
|