@virentia/effector 0.2.0 → 0.3.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 +113 -25
- package/dist/index.cjs +255 -274
- package/dist/index.d.cts +23 -19
- package/dist/index.d.mts +23 -19
- package/dist/index.mjs +253 -275
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -10,53 +10,141 @@ Use this package when Virentia models need to call Effector units, or existing E
|
|
|
10
10
|
pnpm add @virentia/effector effector @virentia/core
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Associate scopes
|
|
14
14
|
|
|
15
15
|
```ts
|
|
16
|
-
import { scope
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
16
|
+
import { scope } from "@virentia/core";
|
|
17
|
+
import { associate } from "@virentia/effector";
|
|
18
|
+
import { fork } from "effector";
|
|
19
19
|
|
|
20
|
-
const effector = createEffectorCompatibility();
|
|
21
20
|
const virentiaScope = scope();
|
|
22
21
|
const effectorScope = fork();
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
associate({
|
|
25
24
|
virentia: virentiaScope,
|
|
26
25
|
effector: effectorScope,
|
|
27
26
|
});
|
|
28
27
|
```
|
|
29
28
|
|
|
30
|
-
A Virentia scope and an Effector scope are
|
|
29
|
+
A Virentia scope and an Effector scope are associated globally through weak maps.
|
|
30
|
+
The examples below use these associated scopes.
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## Universal Ports
|
|
33
|
+
|
|
34
|
+
Use `fool(unit)` at feature boundaries. The result is a pass-through unit for one direction: one feature writes to the port, another feature reads from it. Effector features can read or write that port as `clock`, `source`, or `target`; Virentia features can read it as `on` or call it from `run`/`scoped`.
|
|
35
|
+
|
|
36
|
+
The unit keeps the natural call style of the system it came from. A port created from `event()` is called like a Virentia event. A port created from `createEvent()` is launched like an Effector event.
|
|
37
|
+
|
|
38
|
+
## Virentia Feature To Effector Feature
|
|
33
39
|
|
|
34
40
|
```ts
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
import { event, scoped } from "@virentia/core";
|
|
42
|
+
import { fool } from "@virentia/effector";
|
|
43
|
+
import { createEvent, createStore, sample } from "effector";
|
|
44
|
+
|
|
45
|
+
const checkoutRequested = fool(event<{ orderId: string }>());
|
|
46
|
+
|
|
47
|
+
function createVirentiaCheckoutFeature() {
|
|
48
|
+
return {
|
|
49
|
+
requestCheckout: checkoutRequested,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function createEffectorBillingFeature() {
|
|
54
|
+
const $session = createStore({ token: "session-token" });
|
|
55
|
+
const billingStarted = createEvent<{ orderId: string; token: string }>();
|
|
56
|
+
const $startedOrders = createStore<string[]>([]).on(billingStarted, (orders, order) => [
|
|
57
|
+
...orders,
|
|
58
|
+
order.orderId,
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
sample({
|
|
62
|
+
clock: checkoutRequested,
|
|
63
|
+
source: $session,
|
|
64
|
+
fn: (session, request) => ({
|
|
65
|
+
orderId: request.orderId,
|
|
66
|
+
token: session.token,
|
|
67
|
+
}),
|
|
68
|
+
target: billingStarted,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
$startedOrders,
|
|
73
|
+
billingStarted,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const billing = createEffectorBillingFeature();
|
|
78
|
+
const checkout = createVirentiaCheckoutFeature();
|
|
79
|
+
|
|
80
|
+
await scoped(virentiaScope, async () => {
|
|
81
|
+
await checkout.requestCheckout({ orderId: "order:1" });
|
|
82
|
+
});
|
|
43
83
|
```
|
|
44
84
|
|
|
45
|
-
The
|
|
85
|
+
The Virentia feature owns the command and calls it naturally. The Effector feature consumes that one pass-through port as its `clock`, then keeps its own output and state in `billing`.
|
|
46
86
|
|
|
47
|
-
## Effector
|
|
87
|
+
## Effector Feature To Virentia Feature
|
|
48
88
|
|
|
49
89
|
```ts
|
|
50
|
-
import {
|
|
51
|
-
|
|
52
|
-
sample
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
90
|
+
import { event, reaction, store } from "@virentia/core";
|
|
91
|
+
import { fool } from "@virentia/effector";
|
|
92
|
+
import { allSettled, createEvent, sample } from "effector";
|
|
93
|
+
|
|
94
|
+
const routeOpened = fool(createEvent<string>());
|
|
95
|
+
|
|
96
|
+
function createEffectorRoutesFeature() {
|
|
97
|
+
const profileClicked = createEvent<string>();
|
|
98
|
+
|
|
99
|
+
sample({
|
|
100
|
+
clock: profileClicked,
|
|
101
|
+
target: routeOpened,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
profileClicked,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function createVirentiaProfileFeature() {
|
|
110
|
+
const profileLoaded = event<{ userId: string; name: string }>();
|
|
111
|
+
const loadedCount = store(0);
|
|
112
|
+
|
|
113
|
+
reaction({
|
|
114
|
+
on: routeOpened,
|
|
115
|
+
run(userId) {
|
|
116
|
+
profileLoaded({
|
|
117
|
+
userId,
|
|
118
|
+
name: "Ada",
|
|
119
|
+
});
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
reaction({
|
|
124
|
+
on: profileLoaded,
|
|
125
|
+
run() {
|
|
126
|
+
loadedCount.value += 1;
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
loadedCount,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const routes = createEffectorRoutesFeature();
|
|
136
|
+
createVirentiaProfileFeature();
|
|
137
|
+
|
|
138
|
+
await allSettled(routes.profileClicked, {
|
|
139
|
+
scope: effectorScope,
|
|
140
|
+
params: "user:1",
|
|
57
141
|
});
|
|
58
142
|
```
|
|
59
143
|
|
|
144
|
+
The Effector feature owns navigation and launches its own event naturally. The Virentia feature listens to that universal port with `on`, then calls its own Virentia port from `run`.
|
|
145
|
+
|
|
146
|
+
Use `scoped`, Effector `allSettled`, `scopeBind`, or UI Providers to choose scopes.
|
|
147
|
+
|
|
60
148
|
## Tests
|
|
61
149
|
|
|
62
150
|
```sh
|