@weftui/core 0.26.2 → 0.27.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/README.md +9 -9
- package/dist/{index-B8idtfB3.d.ts → index-DMNuAQXj.d.ts} +70 -9
- package/dist/index.d.ts +250 -230
- package/dist/index.js +1 -1
- package/dist/rolldown-runtime-DK3Fl9T5.js +1 -0
- package/dist/types/index.d.ts +1 -1
- package/docs/explanation/boundaries-and-suspense.md +8 -8
- package/docs/explanation/reactive-primitives.md +13 -11
- package/docs/explanation/rendering-model.md +1 -1
- package/docs/explanation/services-and-context.md +3 -3
- package/docs/how-to/add-routing.md +17 -5
- package/docs/how-to/author-components.md +5 -5
- package/docs/how-to/handle-forms.md +10 -10
- package/docs/how-to/load-async-data.md +4 -4
- package/docs/how-to/load-data-with-rpc.md +5 -5
- package/docs/how-to/provide-services.md +1 -1
- package/docs/how-to/use-element-refs.md +5 -5
- package/docs/reference/core.md +31 -20
- package/docs/reference/router.md +9 -5
- package/docs/tutorial/02-reactivity.md +6 -6
- package/docs/tutorial/03-services-and-async.md +3 -4
- package/docs/tutorial/04-errors-and-server.md +2 -2
- package/package.json +3 -5
|
@@ -11,7 +11,7 @@ description: Add component-local state with SubscriptionRef and weave its stream
|
|
|
11
11
|
|
|
12
12
|
## Local state with `SubscriptionRef`
|
|
13
13
|
|
|
14
|
-
Use Effect's `SubscriptionRef` for component-local state.
|
|
14
|
+
Use Effect's `SubscriptionRef` for component-local state. `SubscriptionRef.changes(ref)` returns a `Stream` that emits the current value and then every update. Pass that stream as a child or prop and the DOM at that spot becomes live:
|
|
15
15
|
|
|
16
16
|
```typescript
|
|
17
17
|
import { h } from "@weftui/core";
|
|
@@ -23,7 +23,7 @@ const Counter = () =>
|
|
|
23
23
|
const count = yield* SubscriptionRef.make(0);
|
|
24
24
|
|
|
25
25
|
return yield* h.div([
|
|
26
|
-
h.span([
|
|
26
|
+
h.span([SubscriptionRef.changes(count)]),
|
|
27
27
|
h.button({ onclick: () => SubscriptionRef.update(count, (n) => n + 1) }, "+"),
|
|
28
28
|
h.button({ onclick: () => SubscriptionRef.update(count, (n) => n - 1) }, "-"),
|
|
29
29
|
]);
|
|
@@ -36,18 +36,18 @@ void Effect.runPromise(mount(Counter(), document.getElementById("root")!));
|
|
|
36
36
|
|
|
37
37
|
## The key idea: the body runs once
|
|
38
38
|
|
|
39
|
-
The `Counter` function runs **exactly once**. It creates the ref, builds the tree, and returns. After that, nothing re-invokes it — the only thing that changes the DOM is the `
|
|
39
|
+
The `Counter` function runs **exactly once**. It creates the ref, builds the tree, and returns. After that, nothing re-invokes it — the only thing that changes the DOM is the `SubscriptionRef.changes(count)` stream woven into the `h.span`. When you click `+`, `SubscriptionRef.update` pushes a new value, the stream emits, and the renderer patches _just that span's text_ in place. No diff, no re-render, no sibling touched.
|
|
40
40
|
|
|
41
41
|
This is what "streams are the weft" means in practice: reactivity is local to exactly where you thread a stream. Everything else is static. The full model is [The Rendering Model](https://weftui.dev/docs/explanation/rendering-model); the vocabulary of stream-shaped values is [Reactive Primitives](https://weftui.dev/docs/explanation/reactive-primitives).
|
|
42
42
|
|
|
43
|
-
> **Note.** `[
|
|
43
|
+
> **Note.** `[SubscriptionRef.changes(count)]` — the stream is passed as a child array. Static values (`"Hello"`, `5`) work in the same position and simply never change. The rule is uniform: a plain value is static, a stream-shaped value is reactive.
|
|
44
44
|
|
|
45
45
|
## Deriving values
|
|
46
46
|
|
|
47
|
-
Because
|
|
47
|
+
Because `SubscriptionRef.changes(count)` returns a `Stream`, you shape reactive text with ordinary stream operators:
|
|
48
48
|
|
|
49
49
|
```typescript
|
|
50
|
-
h.span([Stream.map(
|
|
50
|
+
h.span([Stream.map(SubscriptionRef.changes(count), (n) => `Count: ${n}`)]);
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
Anywhere you would compute a derived value, map the stream instead — the derivation stays reactive.
|
|
@@ -18,10 +18,9 @@ import { h } from "@weftui/core";
|
|
|
18
18
|
import { mount } from "@weftui/dom/client";
|
|
19
19
|
import { Context, Effect, Layer, pipe } from "effect";
|
|
20
20
|
|
|
21
|
-
class Logger extends Context.
|
|
22
|
-
Logger,
|
|
23
|
-
|
|
24
|
-
>() {}
|
|
21
|
+
class Logger extends Context.Service<Logger, { log: (message: string) => Effect.Effect<void> }>()(
|
|
22
|
+
"Logger",
|
|
23
|
+
) {}
|
|
25
24
|
|
|
26
25
|
const LoggerLive = Layer.succeed(Logger, {
|
|
27
26
|
log: (message) => Effect.sync(() => console.log(message)),
|
|
@@ -20,12 +20,12 @@ import { Data, Effect } from "effect";
|
|
|
20
20
|
class ApiError extends Data.TaggedError("ApiError")<{ status: number }> {}
|
|
21
21
|
|
|
22
22
|
const SafeWidget = () =>
|
|
23
|
-
Boundary.
|
|
23
|
+
Boundary.catch({ fallback: (e) => h.div({ class: "error" }, `Request failed: ${e.status}`) }, [
|
|
24
24
|
Effect.fail(new ApiError({ status: 503 })),
|
|
25
25
|
]);
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
There are six failure-catch variants — `
|
|
28
|
+
There are six failure-catch variants — `catch`, `catchCause`, `catchTag`, `catchTags`, `catchFilter`, `catchIf` — mirroring Effect's own error operators. A failure that a boundary does not match re-raises to the **nearest enclosing** boundary; if none catches it, the mount fails. The conceptual model (and why the boundary's type reflects exactly which failures are handled) is [Boundaries and Suspense](https://weftui.dev/docs/explanation/boundaries-and-suspense).
|
|
29
29
|
|
|
30
30
|
## Render on the server
|
|
31
31
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weftui/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "Element builders and combinators for Weft — reactive UI, woven from Effect",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"combinators",
|
|
@@ -41,17 +41,15 @@
|
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@effect/rpc": "^0.75.1",
|
|
45
44
|
"@types/node": "^25.9.2",
|
|
46
45
|
"csstype": "^3.2.3",
|
|
47
|
-
"effect": "
|
|
46
|
+
"effect": "4.0.0-beta.93",
|
|
48
47
|
"tsx": "^4.22.4",
|
|
49
48
|
"typescript": "^6.0.3",
|
|
50
49
|
"vite": "npm:@voidzero-dev/vite-plus-core@0.2.2",
|
|
51
50
|
"vite-plus": "0.2.2"
|
|
52
51
|
},
|
|
53
52
|
"peerDependencies": {
|
|
54
|
-
"
|
|
55
|
-
"effect": "^3.21"
|
|
53
|
+
"effect": "4.0.0-beta.93"
|
|
56
54
|
}
|
|
57
55
|
}
|