@virentia/effector 0.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/README.md +61 -0
- package/dist/index.cjs +537 -0
- package/dist/index.d.cts +188 -0
- package/dist/index.d.mts +188 -0
- package/dist/index.mjs +499 -0
- package/package.json +42 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import * as core from "@virentia/core";
|
|
2
|
+
//#region lib/types.ts
|
|
3
|
+
const unitKind = Symbol("virentia.effector.unit");
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region lib/guards.ts
|
|
6
|
+
const is = {
|
|
7
|
+
unit(value) {
|
|
8
|
+
return isUnit(value);
|
|
9
|
+
},
|
|
10
|
+
event(value) {
|
|
11
|
+
return isEvent(value);
|
|
12
|
+
},
|
|
13
|
+
store(value) {
|
|
14
|
+
return isStore(value);
|
|
15
|
+
},
|
|
16
|
+
effect(value) {
|
|
17
|
+
return isEffect(value);
|
|
18
|
+
},
|
|
19
|
+
targetable(value) {
|
|
20
|
+
return isTargetable(value);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
function isUnit(value) {
|
|
24
|
+
return Boolean(value && (typeof value === "object" || typeof value === "function") && unitKind in value);
|
|
25
|
+
}
|
|
26
|
+
function isEvent(value) {
|
|
27
|
+
return isUnit(value) && value[unitKind] === "event";
|
|
28
|
+
}
|
|
29
|
+
function isStore(value) {
|
|
30
|
+
return isUnit(value) && value[unitKind] === "store";
|
|
31
|
+
}
|
|
32
|
+
function isEffect(value) {
|
|
33
|
+
return isUnit(value) && value[unitKind] === "effect";
|
|
34
|
+
}
|
|
35
|
+
function isTargetable(value) {
|
|
36
|
+
return isEvent(value) || isEffect(value) || isStore(value) && typeof value.setState === "function";
|
|
37
|
+
}
|
|
38
|
+
function isScope(value) {
|
|
39
|
+
return Boolean(value && typeof value === "object" && "__core" in value && !(unitKind in value));
|
|
40
|
+
}
|
|
41
|
+
function isScopeError(error) {
|
|
42
|
+
return error instanceof Error && error.message === "Scope is required";
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region lib/shared.ts
|
|
46
|
+
const defaultScope = core.scope();
|
|
47
|
+
const compatScopes = /* @__PURE__ */ new WeakMap();
|
|
48
|
+
const storesBySid = /* @__PURE__ */ new Map();
|
|
49
|
+
const nativeStoreKeys = new Set([
|
|
50
|
+
"node",
|
|
51
|
+
"writable",
|
|
52
|
+
"subscribe",
|
|
53
|
+
"map",
|
|
54
|
+
"filter",
|
|
55
|
+
"filterMap"
|
|
56
|
+
]);
|
|
57
|
+
function createCompatScope(scope) {
|
|
58
|
+
const existing = compatScopes.get(scope);
|
|
59
|
+
if (existing) return existing;
|
|
60
|
+
const compatScope = {
|
|
61
|
+
__core: scope,
|
|
62
|
+
__changedSids: /* @__PURE__ */ new Set(),
|
|
63
|
+
getState(store) {
|
|
64
|
+
return store.getState(this);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
compatScopes.set(scope, compatScope);
|
|
68
|
+
return compatScope;
|
|
69
|
+
}
|
|
70
|
+
function inScope(scope, fn) {
|
|
71
|
+
if (scope) return core.scoped(scope.__core, fn);
|
|
72
|
+
try {
|
|
73
|
+
return fn();
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (!isScopeError(error)) throw error;
|
|
76
|
+
return core.scoped(defaultScope, fn);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function callWithFallback(unit) {
|
|
80
|
+
return ((...args) => {
|
|
81
|
+
try {
|
|
82
|
+
return unit(...args).catch((error) => {
|
|
83
|
+
if (!isScopeError(error)) throw error;
|
|
84
|
+
return core.scoped(defaultScope, () => unit(...args));
|
|
85
|
+
});
|
|
86
|
+
} catch (error) {
|
|
87
|
+
if (!isScopeError(error)) throw error;
|
|
88
|
+
return core.scoped(defaultScope, () => unit(...args));
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function readSource(source) {
|
|
93
|
+
if (isStore(source)) return source.getState();
|
|
94
|
+
if (Array.isArray(source)) return source.map((store) => store.getState());
|
|
95
|
+
return Object.fromEntries(Object.entries(source).map(([key, store]) => [key, store.getState()]));
|
|
96
|
+
}
|
|
97
|
+
function sourceToClock(source) {
|
|
98
|
+
if (!source) throw new Error("sample: clock or source is required");
|
|
99
|
+
if (isStore(source)) return source;
|
|
100
|
+
return Object.values(source);
|
|
101
|
+
}
|
|
102
|
+
function passesFilter(filter, source, clock) {
|
|
103
|
+
if (!filter) return true;
|
|
104
|
+
if (isStore(filter)) return filter.getState();
|
|
105
|
+
return filter(source, clock);
|
|
106
|
+
}
|
|
107
|
+
function launchTarget(target, payload) {
|
|
108
|
+
for (const unit of toArray(target)) if (isStore(unit)) unit.setState(payload);
|
|
109
|
+
else unit(payload);
|
|
110
|
+
}
|
|
111
|
+
function computeCombined(shape, fn) {
|
|
112
|
+
const value = readSource(shape);
|
|
113
|
+
return fn ? fn(value) : value;
|
|
114
|
+
}
|
|
115
|
+
function registerStore(store) {
|
|
116
|
+
if (store.sid) storesBySid.set(store.sid, store);
|
|
117
|
+
}
|
|
118
|
+
function markScopeChanged(scope, sid) {
|
|
119
|
+
if (sid) createCompatScope(scope ?? defaultScope).__changedSids.add(sid);
|
|
120
|
+
}
|
|
121
|
+
function applyStoreValues(scope, values) {
|
|
122
|
+
if (Array.isArray(values)) {
|
|
123
|
+
for (const [store, value] of values) store.setState(value, scope);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (values instanceof Map) {
|
|
127
|
+
for (const [store, value] of values) applyStoreValue(scope, store, value);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
for (const [sid, value] of Object.entries(values)) applyStoreValue(scope, sid, value);
|
|
131
|
+
}
|
|
132
|
+
function getName(input) {
|
|
133
|
+
if (typeof input === "string") return input;
|
|
134
|
+
if (input && (typeof input === "object" || typeof input === "function") && "shortName" in input) return String(input.shortName ?? "unit");
|
|
135
|
+
if (input && (typeof input === "object" || typeof input === "function") && "name" in input) return String(input.name ?? "unit");
|
|
136
|
+
return "unit";
|
|
137
|
+
}
|
|
138
|
+
function toArray(value) {
|
|
139
|
+
return Array.isArray(value) ? value : [value];
|
|
140
|
+
}
|
|
141
|
+
function applyStoreValue(scope, storeOrSid, value) {
|
|
142
|
+
if (typeof storeOrSid === "string") {
|
|
143
|
+
storesBySid.get(storeOrSid)?.setState(value, scope);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
storeOrSid.setState(value, scope);
|
|
147
|
+
}
|
|
148
|
+
//#endregion
|
|
149
|
+
//#region lib/store.ts
|
|
150
|
+
function createStore(defaultState, config) {
|
|
151
|
+
const box = core.store({ value: defaultState });
|
|
152
|
+
const updates = createEvent({ name: `${config?.name ?? "store"} updates` });
|
|
153
|
+
const store = createStoreFromBox(box, updates, defaultState, config?.name, config?.sid);
|
|
154
|
+
registerStore(store);
|
|
155
|
+
box.subscribe((next, scope) => {
|
|
156
|
+
markScopeChanged(scope, store.sid);
|
|
157
|
+
core.run({
|
|
158
|
+
unit: updates.__core.node,
|
|
159
|
+
payload: next.value,
|
|
160
|
+
scope
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
return store;
|
|
164
|
+
}
|
|
165
|
+
function createStoreFromBox(box, updates, defaultState, name = "store", sid) {
|
|
166
|
+
const result = {
|
|
167
|
+
[unitKind]: "store",
|
|
168
|
+
__box: box,
|
|
169
|
+
__core: updates,
|
|
170
|
+
node: updates.__core.node,
|
|
171
|
+
shortName: name,
|
|
172
|
+
sid,
|
|
173
|
+
defaultState,
|
|
174
|
+
updates,
|
|
175
|
+
getType: () => name,
|
|
176
|
+
getState(scope) {
|
|
177
|
+
return readBox(box, scope);
|
|
178
|
+
},
|
|
179
|
+
setState(value, scope) {
|
|
180
|
+
writeBox(box, value, scope);
|
|
181
|
+
},
|
|
182
|
+
watch(fn) {
|
|
183
|
+
fn(readBox(box));
|
|
184
|
+
return box.subscribe((next) => {
|
|
185
|
+
fn(next.value);
|
|
186
|
+
});
|
|
187
|
+
},
|
|
188
|
+
map(fn) {
|
|
189
|
+
const mapped = createStore(fn(result.getState()));
|
|
190
|
+
core.scoped(defaultScope, () => {
|
|
191
|
+
core.reaction(() => {
|
|
192
|
+
mapped.setState(fn(result.getState()));
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
return mapped;
|
|
196
|
+
},
|
|
197
|
+
on(trigger, reducer) {
|
|
198
|
+
core.reaction({
|
|
199
|
+
on: trigger,
|
|
200
|
+
run: (payload) => {
|
|
201
|
+
result.setState(reducer(result.getState(), payload));
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
return result;
|
|
205
|
+
},
|
|
206
|
+
reset(trigger) {
|
|
207
|
+
for (const unit of toArray(trigger)) core.reaction({
|
|
208
|
+
on: unit,
|
|
209
|
+
run: () => {
|
|
210
|
+
result.setState(defaultState);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
return result;
|
|
217
|
+
}
|
|
218
|
+
function wrapNativeStore(store, defaultState, name) {
|
|
219
|
+
const updates = createEvent(`${name}.updates`);
|
|
220
|
+
const result = {
|
|
221
|
+
[unitKind]: "store",
|
|
222
|
+
__core: updates,
|
|
223
|
+
node: updates.__core.node,
|
|
224
|
+
shortName: name,
|
|
225
|
+
defaultState,
|
|
226
|
+
updates,
|
|
227
|
+
getType: () => name,
|
|
228
|
+
getState(scope) {
|
|
229
|
+
return readNativeStore(store, scope);
|
|
230
|
+
},
|
|
231
|
+
watch(fn) {
|
|
232
|
+
fn(readNativeStore(store));
|
|
233
|
+
return store.subscribe((next) => {
|
|
234
|
+
fn(next);
|
|
235
|
+
});
|
|
236
|
+
},
|
|
237
|
+
map(fn) {
|
|
238
|
+
const mapped = createStore(fn(result.getState()));
|
|
239
|
+
core.scoped(defaultScope, () => {
|
|
240
|
+
core.reaction(() => {
|
|
241
|
+
mapped.setState(fn(result.getState()));
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
return mapped;
|
|
245
|
+
},
|
|
246
|
+
on() {
|
|
247
|
+
throw new Error("Store is read-only");
|
|
248
|
+
},
|
|
249
|
+
reset() {
|
|
250
|
+
throw new Error("Store is read-only");
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
store.subscribe((next, scope) => {
|
|
254
|
+
core.run({
|
|
255
|
+
unit: updates.__core.node,
|
|
256
|
+
payload: next,
|
|
257
|
+
scope
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
function readBox(box, scope) {
|
|
263
|
+
return inScope(scope, () => box.value);
|
|
264
|
+
}
|
|
265
|
+
function writeBox(box, value, scope) {
|
|
266
|
+
inScope(scope, () => {
|
|
267
|
+
box.value = value;
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
function readNativeStore(store, scope) {
|
|
271
|
+
return inScope(scope, () => {
|
|
272
|
+
const keys = Reflect.ownKeys(store).filter((key) => !nativeStoreKeys.has(key));
|
|
273
|
+
if (keys.length === 1 && keys[0] === "value") return Reflect.get(store, "value");
|
|
274
|
+
return Object.fromEntries(keys.map((key) => [key, Reflect.get(store, key)]));
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region lib/operators.ts
|
|
279
|
+
function sample(config) {
|
|
280
|
+
const target = config.target ?? createEvent();
|
|
281
|
+
const clocks = toArray(config.clock ?? sourceToClock(config.source));
|
|
282
|
+
for (const clock of clocks) core.reaction({
|
|
283
|
+
on: clock,
|
|
284
|
+
run: (clockPayload) => {
|
|
285
|
+
const sourceValue = config.source === void 0 ? void 0 : readSource(config.source);
|
|
286
|
+
if (!passesFilter(config.filter, sourceValue, clockPayload)) return;
|
|
287
|
+
launchTarget(target, config.fn ? config.source === void 0 ? config.fn(clockPayload, clockPayload) : config.fn(sourceValue, clockPayload) : config.source === void 0 ? clockPayload : sourceValue);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
return Array.isArray(target) ? target[0] : target;
|
|
291
|
+
}
|
|
292
|
+
function combine(...args) {
|
|
293
|
+
const fn = typeof args[args.length - 1] === "function" ? args.pop() : void 0;
|
|
294
|
+
const shape = args.length === 1 ? args[0] : args;
|
|
295
|
+
const result = createStore(computeCombined(shape, fn));
|
|
296
|
+
core.scoped(defaultScope, () => {
|
|
297
|
+
core.reaction(() => {
|
|
298
|
+
result.setState(computeCombined(shape, fn));
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
function split(sourceOrConfig, maybeCases) {
|
|
304
|
+
const source = "source" in sourceOrConfig ? sourceOrConfig.source : sourceOrConfig;
|
|
305
|
+
const match = "source" in sourceOrConfig ? sourceOrConfig.match : maybeCases ?? {};
|
|
306
|
+
const result = {};
|
|
307
|
+
if (typeof match === "function") {
|
|
308
|
+
const configuredCases = "source" in sourceOrConfig ? sourceOrConfig.cases ?? {} : {};
|
|
309
|
+
for (const key of Object.keys(configuredCases)) result[key] = configuredCases[key] ?? createEvent();
|
|
310
|
+
} else for (const key of Object.keys(match)) result[key] = createEvent();
|
|
311
|
+
result.__ = createEvent();
|
|
312
|
+
core.reaction({
|
|
313
|
+
on: source,
|
|
314
|
+
run: (payload) => {
|
|
315
|
+
launchTarget(result[(typeof match === "function" ? match(payload) : Object.keys(match).find((caseName) => match[caseName](payload))) ?? "__"] ?? result.__, payload);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
return result;
|
|
319
|
+
}
|
|
320
|
+
function createApi(store, reducers) {
|
|
321
|
+
const result = {};
|
|
322
|
+
for (const key of Object.keys(reducers)) {
|
|
323
|
+
const event = createEvent(String(key));
|
|
324
|
+
store.on(event, reducers[key]);
|
|
325
|
+
result[key] = event;
|
|
326
|
+
}
|
|
327
|
+
return result;
|
|
328
|
+
}
|
|
329
|
+
function restore(unit, defaultState) {
|
|
330
|
+
const store = createStore(defaultState);
|
|
331
|
+
const source = isEffect(unit) ? unit.doneData : unit;
|
|
332
|
+
store.on(source, (_, payload) => payload);
|
|
333
|
+
return store;
|
|
334
|
+
}
|
|
335
|
+
//#endregion
|
|
336
|
+
//#region lib/watch.ts
|
|
337
|
+
function watchUnit(unit, fn) {
|
|
338
|
+
const subscription = core.reaction({
|
|
339
|
+
on: unit,
|
|
340
|
+
run: fn
|
|
341
|
+
});
|
|
342
|
+
return () => subscription.stop();
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
345
|
+
//#region lib/event.ts
|
|
346
|
+
function createEvent(nameOrConfig) {
|
|
347
|
+
const name = typeof nameOrConfig === "string" ? nameOrConfig : nameOrConfig?.name ?? "unit";
|
|
348
|
+
return wrapEvent(core.event(), name);
|
|
349
|
+
}
|
|
350
|
+
function wrapEvent(event, name = "event") {
|
|
351
|
+
const result = callWithFallback(typeof event === "function" ? event : ((...payload) => core.allSettled(event, { payload: payload[0] })));
|
|
352
|
+
Object.assign(result, {
|
|
353
|
+
[unitKind]: "event",
|
|
354
|
+
__core: event,
|
|
355
|
+
node: event.node,
|
|
356
|
+
shortName: name,
|
|
357
|
+
getType: () => name,
|
|
358
|
+
watch(fn) {
|
|
359
|
+
return watchUnit(result, fn);
|
|
360
|
+
},
|
|
361
|
+
map(fn) {
|
|
362
|
+
return wrapEvent(event.map(fn));
|
|
363
|
+
},
|
|
364
|
+
filter(config) {
|
|
365
|
+
const fn = typeof config === "function" ? config : config.fn;
|
|
366
|
+
return wrapEvent(event.filter(fn));
|
|
367
|
+
},
|
|
368
|
+
filterMap(fn) {
|
|
369
|
+
return wrapEvent(event.filterMap(fn));
|
|
370
|
+
},
|
|
371
|
+
prepend(fn) {
|
|
372
|
+
const prepended = createEvent();
|
|
373
|
+
sample({
|
|
374
|
+
clock: prepended,
|
|
375
|
+
fn,
|
|
376
|
+
target: result
|
|
377
|
+
});
|
|
378
|
+
return prepended;
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
return result;
|
|
382
|
+
}
|
|
383
|
+
//#endregion
|
|
384
|
+
//#region lib/effect.ts
|
|
385
|
+
function createEffect(handlerOrConfig) {
|
|
386
|
+
let handler = typeof handlerOrConfig === "function" ? handlerOrConfig : handlerOrConfig?.handler;
|
|
387
|
+
const effectName = getName(handlerOrConfig);
|
|
388
|
+
const fx = core.effect((params) => {
|
|
389
|
+
if (!handler) throw new Error("Effect handler is not defined");
|
|
390
|
+
return handler(params);
|
|
391
|
+
});
|
|
392
|
+
const result = callWithFallback(((...params) => fx(...params)));
|
|
393
|
+
Object.assign(result, {
|
|
394
|
+
[unitKind]: "effect",
|
|
395
|
+
__core: fx,
|
|
396
|
+
node: fx.node,
|
|
397
|
+
shortName: effectName,
|
|
398
|
+
getType: () => effectName,
|
|
399
|
+
watch(fn) {
|
|
400
|
+
return watchUnit(wrapEvent(fx.started), fn);
|
|
401
|
+
},
|
|
402
|
+
done: wrapEvent(fx.done),
|
|
403
|
+
fail: wrapEvent(fx.fail),
|
|
404
|
+
finally: wrapEvent(fx.finally),
|
|
405
|
+
doneData: wrapEvent(fx.doneData),
|
|
406
|
+
failData: wrapEvent(fx.failData),
|
|
407
|
+
pending: wrapNativeStore(fx.$pending, false, `${effectName}.pending`),
|
|
408
|
+
inFlight: wrapNativeStore(fx.$inFlight, 0, `${effectName}.inFlight`),
|
|
409
|
+
prepend(fn) {
|
|
410
|
+
const prepended = createEvent();
|
|
411
|
+
sample({
|
|
412
|
+
clock: prepended,
|
|
413
|
+
fn,
|
|
414
|
+
target: result
|
|
415
|
+
});
|
|
416
|
+
return prepended;
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
const use = ((nextHandler) => {
|
|
420
|
+
handler = nextHandler;
|
|
421
|
+
return result;
|
|
422
|
+
});
|
|
423
|
+
use.getCurrent = () => {
|
|
424
|
+
if (!handler) throw new Error("Effect handler is not defined");
|
|
425
|
+
return handler;
|
|
426
|
+
};
|
|
427
|
+
result.use = use;
|
|
428
|
+
return result;
|
|
429
|
+
}
|
|
430
|
+
//#endregion
|
|
431
|
+
//#region lib/attach.ts
|
|
432
|
+
function attach(config) {
|
|
433
|
+
return createEffect({
|
|
434
|
+
name: config.name ?? getName(config.effect),
|
|
435
|
+
handler: (params) => {
|
|
436
|
+
const hasSource = config.source !== void 0;
|
|
437
|
+
const sourceValue = hasSource ? readSource(config.source) : void 0;
|
|
438
|
+
if (isEffect(config.effect)) {
|
|
439
|
+
const nextParams = config.mapParams ? config.mapParams(params, sourceValue) : params;
|
|
440
|
+
return config.effect.use.getCurrent()(nextParams);
|
|
441
|
+
}
|
|
442
|
+
return hasSource ? config.effect(sourceValue, params) : config.effect(params);
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
//#endregion
|
|
447
|
+
//#region lib/persistence.ts
|
|
448
|
+
function serialize(scope, config = {}) {
|
|
449
|
+
const compatScope = createCompatScope(scope.__core);
|
|
450
|
+
const onlyChanges = config.onlyChanges ?? true;
|
|
451
|
+
const ignored = new Set((config.ignore ?? []).map((item) => typeof item === "string" ? item : item.sid).filter((sid) => typeof sid === "string"));
|
|
452
|
+
const result = {};
|
|
453
|
+
for (const [sid, store] of storesBySid) {
|
|
454
|
+
if (ignored.has(sid)) continue;
|
|
455
|
+
if (onlyChanges && !compatScope.__changedSids.has(sid)) continue;
|
|
456
|
+
result[sid] = store.getState(compatScope);
|
|
457
|
+
}
|
|
458
|
+
return result;
|
|
459
|
+
}
|
|
460
|
+
function hydrate(scope, config) {
|
|
461
|
+
applyStoreValues(scope, config.values);
|
|
462
|
+
}
|
|
463
|
+
//#endregion
|
|
464
|
+
//#region lib/scope.ts
|
|
465
|
+
function fork(config) {
|
|
466
|
+
const nextScope = createCompatScope(core.scope());
|
|
467
|
+
if (config?.values) hydrate(nextScope, { values: config.values });
|
|
468
|
+
return nextScope;
|
|
469
|
+
}
|
|
470
|
+
async function allSettled(unitOrScope, options = {}) {
|
|
471
|
+
if (isScope(unitOrScope)) return;
|
|
472
|
+
const scope = options.scope ?? createCompatScope(defaultScope);
|
|
473
|
+
const unit = unitOrScope;
|
|
474
|
+
if (isStore(unit)) {
|
|
475
|
+
unit.setState(options.params, scope);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
if (isEffect(unit)) try {
|
|
479
|
+
return {
|
|
480
|
+
status: "done",
|
|
481
|
+
value: await core.scoped(scope.__core, () => unit(options.params))
|
|
482
|
+
};
|
|
483
|
+
} catch (value) {
|
|
484
|
+
return {
|
|
485
|
+
status: "fail",
|
|
486
|
+
value
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
await core.allSettled(unit.__core, {
|
|
490
|
+
scope: scope.__core,
|
|
491
|
+
payload: options.params
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
function scopeBind(unit, config) {
|
|
495
|
+
const scope = config?.scope ?? createCompatScope(defaultScope);
|
|
496
|
+
return (...payload) => core.scoped(scope.__core, () => unit(...payload));
|
|
497
|
+
}
|
|
498
|
+
//#endregion
|
|
499
|
+
export { allSettled, attach, combine, createApi, createEffect, createEvent, createStore, fork, hydrate, is, restore, sample, scopeBind, serialize, split };
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@virentia/effector",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Effector-compatible facade powered by @virentia/core",
|
|
5
|
+
"keywords": [],
|
|
6
|
+
"homepage": "https://movpushmov.dev/virentia/effector/",
|
|
7
|
+
"bugs": {
|
|
8
|
+
"url": "https://github.com/movpushmov/virentia/issues"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"author": "movpushmov",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/movpushmov/virentia.git",
|
|
15
|
+
"directory": "packages/effector"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"main": "./dist/index.cjs",
|
|
22
|
+
"module": "./dist/index.mjs",
|
|
23
|
+
"types": "./dist/index.d.mts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.mts",
|
|
27
|
+
"import": "./dist/index.mjs",
|
|
28
|
+
"require": "./dist/index.cjs"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@virentia/core": "0.1.0"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsdown",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"test:watch": "vitest"
|
|
41
|
+
}
|
|
42
|
+
}
|