@shivaedev/effect-react 0.1.0 → 0.1.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/CHANGELOG.md +7 -0
- package/README.md +16 -16
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -6,42 +6,42 @@ This package targets Effect and `@effect/atom-react` **4.0.0-rc.112** and React
|
|
|
6
6
|
|
|
7
7
|
## Native RPC usage
|
|
8
8
|
|
|
9
|
-
Given an `Api` service constructed with native `AtomRpc.Service`, and RPCs `
|
|
9
|
+
Given an `Api` service constructed with native `AtomRpc.Service`, and RPCs `Orders` and `RenameOrder`:
|
|
10
10
|
|
|
11
11
|
```tsx
|
|
12
12
|
import { RegistryProvider } from "@effect/atom-react"
|
|
13
13
|
import { useAction, useQuery } from "@shivaedev/effect-react"
|
|
14
14
|
import { Option } from "effect"
|
|
15
15
|
|
|
16
|
-
function
|
|
17
|
-
const
|
|
18
|
-
reactivityKeys: ["
|
|
16
|
+
function Orders() {
|
|
17
|
+
const orders = useQuery(Api.query("Orders", {}, {
|
|
18
|
+
reactivityKeys: ["orders"],
|
|
19
19
|
timeToLive: "1 minute",
|
|
20
20
|
}))
|
|
21
|
-
const rename = useAction(Api.mutation("
|
|
21
|
+
const rename = useAction(Api.mutation("RenameOrder"))
|
|
22
22
|
|
|
23
23
|
function save(id: string, title: string) {
|
|
24
24
|
rename.dispatch({
|
|
25
25
|
payload: { id, title },
|
|
26
|
-
reactivityKeys: ["
|
|
26
|
+
reactivityKeys: ["orders"],
|
|
27
27
|
})
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
if (Option.isNone(
|
|
31
|
-
return Option.isSome(
|
|
32
|
-
? <button onClick={
|
|
30
|
+
if (Option.isNone(orders.data)) {
|
|
31
|
+
return Option.isSome(orders.cause)
|
|
32
|
+
? <button onClick={orders.refresh}>Retry</button>
|
|
33
33
|
: <p>Loading…</p>
|
|
34
34
|
}
|
|
35
|
-
return <
|
|
35
|
+
return <OrderList orders={orders.data.value} refreshing={orders.refreshing}
|
|
36
36
|
pending={rename.pending} onRename={save} />
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
function App() {
|
|
40
|
-
return <RegistryProvider><
|
|
40
|
+
return <RegistryProvider><Orders /></RegistryProvider>
|
|
41
41
|
}
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
`Api` and `
|
|
44
|
+
`Api` and `OrderList` above are application definitions. The hooks also accept non-RPC atoms built with `Atom.make`, `Atom.fn` or an atom runtime. Stable atom identities should be declared outside render, created with native `Atom.family`, or memoized; native `Api.query(...)` already supplies its own family.
|
|
45
45
|
|
|
46
46
|
## Editing
|
|
47
47
|
|
|
@@ -50,10 +50,10 @@ function App() {
|
|
|
50
50
|
```ts
|
|
51
51
|
const editor = useEditor({
|
|
52
52
|
query: api.get.query({ id }),
|
|
53
|
-
fields:
|
|
54
|
-
values: (
|
|
53
|
+
fields: InvoiceLineFields,
|
|
54
|
+
values: (line) => ({ name: line.name, quantity: String(line.quantity) }),
|
|
55
55
|
save: (values) => api.save.run({ id, ...values }),
|
|
56
|
-
runtime:
|
|
56
|
+
runtime: InvoiceLinesClient.runtime,
|
|
57
57
|
})
|
|
58
58
|
// editor.query: QueryState; editor.form: Form | undefined until data first arrives
|
|
59
59
|
// editor.save(), editor.saving, editor.dirty, editor.failure (non-field failures), editor.revert()
|
|
@@ -81,7 +81,7 @@ Mount `SessionBoundary` at the authenticated root. For each session key it build
|
|
|
81
81
|
|
|
82
82
|
`resumeSignal({ window, native })` is an atom that increments when the page becomes visible, when the network returns while visible, and when an injected native resume source fires. Feed it to native `Atom.makeRefreshOnSignal` or to `Atom.swr` as `focusSignal`.
|
|
83
83
|
|
|
84
|
-
State belongs to the **supplied atom in the registry**, not to an individual hook call. In particular, native `Api.mutation("
|
|
84
|
+
State belongs to the **supplied atom in the registry**, not to an individual hook call. In particular, native `Api.mutation("RenameOrder")` returns the same atom for that operation. Components using it share pending/result state and the native action's concurrency behavior. With the default native action, a later dispatch interrupts the earlier one; shared state then represents the later action. Disable duplicate submissions, or create distinct native action atoms when independent lifetimes are needed. Native registry retention and disposal govern cleanup. The package adds no optimistic policy, offline queue, form state or parallel action scheduler.
|
|
85
85
|
|
|
86
86
|
## Validation
|
|
87
87
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/effect-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "React query, action, editor and session hooks for native Effect atoms",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@effect/atom-react": "4.0.0-rc.112",
|
|
47
|
-
"@shivaedev/effect-form": "^0.1.0",
|
|
48
47
|
"effect": "4.0.0-rc.112",
|
|
49
|
-
"react": "19.2.8"
|
|
48
|
+
"react": "19.2.8",
|
|
49
|
+
"@shivaedev/effect-form": "0.1.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependenciesMeta": {
|
|
52
52
|
"@shivaedev/effect-form": {
|
|
@@ -65,11 +65,11 @@
|
|
|
65
65
|
"react-dom": "19.2.8",
|
|
66
66
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
67
67
|
"vitest": "4.1.9",
|
|
68
|
-
"@shivaedev/effect-sql": "0.1.0",
|
|
69
68
|
"@effect/sql-sqlite-node": "4.0.0-rc.112",
|
|
70
|
-
"@shivaedev/effect-
|
|
71
|
-
"@shivaedev/effect-form": "0.1.
|
|
72
|
-
"@shivaedev/effect-contract": "0.1.0"
|
|
69
|
+
"@shivaedev/effect-sql": "0.1.0",
|
|
70
|
+
"@shivaedev/effect-form": "0.1.1",
|
|
71
|
+
"@shivaedev/effect-contract": "0.1.0",
|
|
72
|
+
"@shivaedev/effect-service": "0.1.0"
|
|
73
73
|
},
|
|
74
74
|
"scripts": {
|
|
75
75
|
"build": "node --eval \"import('node:fs').then(({ rmSync }) => rmSync('dist', { force: true, recursive: true }))\" && tsc6 --project tsconfig.build.json",
|