@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/dist/index.cjs CHANGED
@@ -24,241 +24,186 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  let _virentia_core = require("@virentia/core");
25
25
  _virentia_core = __toESM(_virentia_core, 1);
26
26
  let effector = require("effector");
27
- //#region lib/index.ts
28
- function createEffectorCompatibility(_options = {}) {
29
- const runtimes = /* @__PURE__ */ new Set();
30
- const effectorByVirentia = /* @__PURE__ */ new WeakMap();
31
- const virentiaByEffector = /* @__PURE__ */ new WeakMap();
32
- const installers = /* @__PURE__ */ new Set();
33
- return {
34
- associate,
35
- ensureAssociation(config = {}) {
36
- return ensureAssociation(config);
37
- },
38
- link(from, to, map) {
39
- const definition = {
40
- from,
41
- to,
42
- map
43
- };
44
- const installer = (runtime) => installLink(runtime, definition);
45
- return registerInstaller(installer);
46
- },
47
- asEffector: ((unit) => createEffectorAdapter(unit)),
48
- asVirentia: ((unit) => createVirentiaAdapter(unit))
49
- };
50
- function associate(config) {
51
- if (!config.virentia) throw new Error("Effector compatibility association requires a Virentia scope");
52
- if (!config.effector) throw new Error("Effector compatibility association requires an Effector scope");
53
- assertScopesAvailable(config);
54
- const existing = findRuntime(config);
55
- if (existing) {
56
- existing.assertSamePair(config);
57
- return existing;
58
- }
59
- const runtime = new EffectorRuntimeImpl({
60
- ...config,
61
- release: () => {
62
- runtimes.delete(runtime);
63
- effectorByVirentia.delete(config.virentia);
64
- virentiaByEffector.delete(config.effector);
65
- }
66
- });
67
- runtimes.add(runtime);
68
- effectorByVirentia.set(config.virentia, config.effector);
69
- virentiaByEffector.set(config.effector, config.virentia);
70
- for (const installer of installers) runtime.addInstaller(installer);
71
- return runtime;
72
- }
73
- function assertScopesAvailable(config) {
74
- const existingEffector = effectorByVirentia.get(config.virentia);
75
- if (existingEffector && existingEffector !== config.effector) throw new Error("Virentia scope is already associated with another Effector scope");
76
- const existingVirentia = virentiaByEffector.get(config.effector);
77
- if (existingVirentia && existingVirentia !== config.virentia) throw new Error("Effector scope is already associated with another Virentia scope");
27
+ //#region lib/errors.ts
28
+ function createMissingAssociationError(config) {
29
+ if (config.effector) return /* @__PURE__ */ new Error("Effector association is missing for provided Effector scope");
30
+ if (config.virentia) return /* @__PURE__ */ new Error("Effector association is missing for provided Virentia scope");
31
+ return /* @__PURE__ */ new Error("Effector association is missing. Call associate({ virentia, effector }) before using fooled units.");
32
+ }
33
+ //#endregion
34
+ //#region lib/associations.ts
35
+ const effectorAssociations = {
36
+ byVirentia: /* @__PURE__ */ new WeakMap(),
37
+ byEffector: /* @__PURE__ */ new WeakMap()
38
+ };
39
+ function associate(config) {
40
+ if (!config.virentia) throw new Error("Effector association requires a Virentia scope");
41
+ if (!config.effector) throw new Error("Effector association requires an Effector scope");
42
+ const existingByVirentia = effectorAssociations.byVirentia.get(config.virentia);
43
+ const existingByEffector = effectorAssociations.byEffector.get(config.effector);
44
+ if (existingByVirentia && existingByVirentia.effector !== config.effector) throw new Error("Virentia scope is already associated with another Effector scope");
45
+ if (existingByEffector && existingByEffector.virentia !== config.virentia) throw new Error("Effector scope is already associated with another Virentia scope");
46
+ const existing = existingByVirentia ?? existingByEffector;
47
+ if (existing) {
48
+ effectorAssociations.byVirentia.set(config.virentia, existing);
49
+ effectorAssociations.byEffector.set(config.effector, existing);
50
+ return existing;
78
51
  }
79
- function ensureAssociation(config = {}) {
80
- const runtime = findRuntime(config);
81
- if (!runtime) throw createMissingRuntimeError(config);
82
- return runtime;
52
+ const association = {
53
+ virentia: config.virentia,
54
+ effector: config.effector
55
+ };
56
+ effectorAssociations.byVirentia.set(config.virentia, association);
57
+ effectorAssociations.byEffector.set(config.effector, association);
58
+ return association;
59
+ }
60
+ function ensureAssociation(config = {}) {
61
+ const association = findAssociation(config);
62
+ if (!association) throw createMissingAssociationError(config);
63
+ return association;
64
+ }
65
+ function findAssociation(config = {}) {
66
+ let association;
67
+ if (config.virentia) {
68
+ association = effectorAssociations.byVirentia.get(config.virentia);
69
+ if (association && config.effector && association.effector !== config.effector) return null;
70
+ if (association) return association;
83
71
  }
84
- function findRuntime(config = {}) {
85
- if (config.virentia) {
86
- const effectorScope = effectorByVirentia.get(config.virentia);
87
- const runtime = effectorScope ? findRuntimeByPair(config.virentia, effectorScope) : null;
88
- if (runtime) return runtime;
89
- }
90
- if (config.effector) {
91
- const virentiaScope = virentiaByEffector.get(config.effector);
92
- const runtime = virentiaScope ? findRuntimeByPair(virentiaScope, config.effector) : null;
93
- if (runtime) return runtime;
94
- }
95
- return null;
72
+ if (config.effector) {
73
+ association = effectorAssociations.byEffector.get(config.effector);
74
+ if (association && config.virentia && association.virentia !== config.virentia) return null;
75
+ if (association) return association;
96
76
  }
97
- function findRuntimeByPair(virentiaScope, effectorScope) {
98
- for (const runtime of runtimes) if (runtime.virentia === virentiaScope && runtime.effector === effectorScope) return runtime;
99
- return null;
77
+ return null;
78
+ }
79
+ //#endregion
80
+ //#region lib/association-state.ts
81
+ const associationState = /* @__PURE__ */ new WeakMap();
82
+ function shouldSkipEffector(association, unit) {
83
+ return (getAssociationState(association).suppressedEffector.get(unit) ?? 0) > 0;
84
+ }
85
+ function shouldSkipVirentia(association, unit) {
86
+ return (getAssociationState(association).suppressedVirentia.get(unit) ?? 0) > 0;
87
+ }
88
+ function suppressEffector(association, unit, fn) {
89
+ const state = getAssociationState(association);
90
+ incrementSuppression(state.suppressedEffector, unit);
91
+ try {
92
+ return fn();
93
+ } finally {
94
+ decrementSuppression(state.suppressedEffector, unit);
100
95
  }
101
- function registerInstaller(installer) {
102
- installers.add(installer);
103
- for (const runtime of runtimes) runtime.addInstaller(installer);
104
- return () => {
105
- installers.delete(installer);
106
- for (const runtime of runtimes) runtime.removeInstaller(installer);
96
+ }
97
+ function suppressVirentia(association, unit) {
98
+ const state = getAssociationState(association);
99
+ incrementSuppression(state.suppressedVirentia, unit);
100
+ return () => {
101
+ decrementSuppression(state.suppressedVirentia, unit);
102
+ };
103
+ }
104
+ function getAssociationState(association) {
105
+ let state = associationState.get(association);
106
+ if (!state) {
107
+ state = {
108
+ suppressedEffector: /* @__PURE__ */ new Map(),
109
+ suppressedVirentia: /* @__PURE__ */ new Map()
107
110
  };
111
+ associationState.set(association, state);
108
112
  }
109
- function createEffectorAdapter(unit) {
110
- if (isEffectorUnit(unit)) return unit;
111
- if (isVirentiaEffect(unit)) {
112
- const scopeQueue = [];
113
- const adapter = (0, effector.createEffect)((payload) => {
114
- return resolveRuntimeFromEffectorScope(scopeQueue.shift()).call(unit, payload);
115
- });
116
- createEffectorScopeNode(adapter, (_payload, scope) => {
117
- scopeQueue.push(scope);
118
- });
119
- return adapter;
113
+ return state;
114
+ }
115
+ function incrementSuppression(map, unit) {
116
+ map.set(unit, (map.get(unit) ?? 0) + 1);
117
+ }
118
+ function decrementSuppression(map, unit) {
119
+ const next = (map.get(unit) ?? 0) - 1;
120
+ if (next <= 0) map.delete(unit);
121
+ else map.set(unit, next);
122
+ }
123
+ //#endregion
124
+ //#region lib/guards.ts
125
+ function isEffectorUnit(value) {
126
+ return effector.is.unit(value);
127
+ }
128
+ function isVirentiaUnit(value) {
129
+ return Boolean(value && (typeof value === "object" || typeof value === "function") && "node" in value && !isEffectorUnit(value));
130
+ }
131
+ function isVirentiaEffect(value) {
132
+ return Boolean(isVirentiaUnit(value) && "doneData" in value && "pending" in value);
133
+ }
134
+ function isObjectLike(value) {
135
+ return (typeof value === "object" || typeof value === "function") && value !== null;
136
+ }
137
+ //#endregion
138
+ //#region lib/runtime.ts
139
+ function installVirentiaToEffectorLink(from, to) {
140
+ installVirentiaToTargetLink(from, to, identity, true);
141
+ }
142
+ function installVirentiaToTargetLink(from, to, map, suppressEffectorWatch) {
143
+ const watcher = _virentia_core.reaction({
144
+ on: from,
145
+ run(payload) {
146
+ const association = resolveAssociationFromVirentiaScope();
147
+ if (shouldSkipVirentia(association, from)) return;
148
+ runBridgeTarget(association, to, map(payload), { suppressWatch: suppressEffectorWatch });
120
149
  }
121
- const adapter = (0, effector.createEvent)();
122
- createEffectorScopeNode(adapter, (payload, scope) => {
123
- const runtime = resolveRuntimeFromEffectorScope(scope);
124
- if (runtime.shouldSkipEffector(adapter)) return;
125
- runtime.emitVirentia(unit, payload, { suppressReaction: true });
126
- });
127
- registerInstaller((runtime) => installLink(runtime, {
128
- from: unit,
129
- to: adapter
130
- }));
131
- return adapter;
132
- }
133
- function createVirentiaAdapter(unit) {
134
- if (isVirentiaUnit(unit)) return unit;
135
- if (effector.is.effect(unit)) return _virentia_core.effect((payload) => {
136
- return resolveRuntimeFromVirentiaScope().call(unit, payload);
137
- });
138
- const adapter = _virentia_core.event();
139
- createEffectorScopeNode(unit, (payload, scope) => {
140
- const runtime = resolveRuntimeFromEffectorScope(scope);
141
- if (runtime.shouldSkipEffector(unit)) return;
142
- runtime.emitVirentia(adapter, payload, { suppressReaction: true });
143
- });
144
- registerInstaller((runtime) => installLink(runtime, {
145
- from: adapter,
146
- to: unit
147
- }));
148
- return adapter;
149
- }
150
- function resolveRuntimeFromEffectorScope(scope) {
151
- if (!scope) throw createMissingRuntimeError({});
152
- const runtime = ensureAssociation({ effector: scope });
153
- const activeVirentiaScope = _virentia_core.getCurrentScope();
154
- if (activeVirentiaScope && activeVirentiaScope !== runtime.virentia) throw new Error("Effector scope is associated with another Virentia scope");
155
- return runtime;
156
- }
157
- function resolveRuntimeFromVirentiaScope() {
158
- const activeVirentiaScope = _virentia_core.getCurrentScope();
159
- if (!activeVirentiaScope) throw createMissingRuntimeError({});
160
- return ensureAssociation({ virentia: activeVirentiaScope });
161
- }
150
+ });
151
+ return () => {
152
+ watcher.stop();
153
+ };
162
154
  }
163
- var EffectorRuntimeImpl = class {
164
- virentia;
165
- effector;
166
- disposed = false;
167
- cleanups = /* @__PURE__ */ new Set();
168
- cleanupByInstaller = /* @__PURE__ */ new Map();
169
- releaseAssociation;
170
- suppressedEffector = /* @__PURE__ */ new Map();
171
- suppressedVirentia = /* @__PURE__ */ new Map();
172
- constructor(config) {
173
- this.virentia = config.virentia;
174
- this.effector = config.effector;
175
- this.releaseAssociation = config.release;
155
+ function runBridgeTarget(association, to, payload, options = {}) {
156
+ if (isEffectorUnit(to)) {
157
+ launchEffector(association, to, payload, { suppressWatch: options.suppressWatch });
158
+ return;
176
159
  }
177
- async call(unit, payload) {
178
- this.assertAlive();
179
- if (isEffectorUnit(unit)) return (0, effector.allSettled)(unit, {
160
+ emitVirentia(association, to, payload, { suppressReaction: options.suppressReaction });
161
+ }
162
+ async function callAssociation(association, unit, payload) {
163
+ if (isEffectorUnit(unit)) return (0, effector.allSettled)(unit, {
164
+ params: payload,
165
+ scope: association.effector
166
+ });
167
+ if (isVirentiaEffect(unit)) return _virentia_core.scoped(association.virentia, () => unit(payload));
168
+ await _virentia_core.allSettled(unit, {
169
+ payload,
170
+ scope: association.virentia
171
+ });
172
+ }
173
+ function launchEffector(association, unit, payload, options = {}) {
174
+ const launchUnit = () => {
175
+ (0, effector.launch)({
176
+ target: unit,
180
177
  params: payload,
181
- scope: this.effector
178
+ scope: association.effector
182
179
  });
183
- if (isVirentiaEffect(unit)) return _virentia_core.scoped(this.virentia, () => unit(payload));
184
- await _virentia_core.allSettled(unit, {
185
- payload,
186
- scope: this.virentia
187
- });
188
- }
189
- trackCleanup(unsubscribe) {
190
- this.cleanups.add(unsubscribe);
191
- return () => {
192
- this.cleanups.delete(unsubscribe);
193
- unsubscribe();
194
- };
195
- }
196
- dispose() {
197
- if (this.disposed) return;
198
- this.disposed = true;
199
- for (const cleanup of [...this.cleanups]) cleanup();
200
- this.cleanups.clear();
201
- this.cleanupByInstaller.clear();
202
- this.releaseAssociation();
203
- }
204
- addInstaller(installer) {
205
- if (this.disposed || this.cleanupByInstaller.has(installer)) return;
206
- const cleanup = installer(this);
207
- this.cleanupByInstaller.set(installer, cleanup);
208
- this.cleanups.add(cleanup);
209
- }
210
- removeInstaller(installer) {
211
- const cleanup = this.cleanupByInstaller.get(installer);
212
- if (!cleanup) return;
213
- this.cleanupByInstaller.delete(installer);
214
- this.cleanups.delete(cleanup);
215
- cleanup();
216
- }
217
- assertSamePair(config) {
218
- if (config.virentia !== this.virentia || config.effector !== this.effector) throw new Error("Effector compatibility association is already bound to another scope pair");
219
- }
220
- launchEffector(unit, payload, options = {}) {
221
- this.assertAlive();
222
- if (options.suppressWatch) this.incrementSuppression(this.suppressedEffector, unit);
223
- try {
224
- (0, effector.launch)({
225
- target: unit,
226
- params: payload,
227
- scope: this.effector
228
- });
229
- } finally {
230
- if (options.suppressWatch) this.decrementSuppression(this.suppressedEffector, unit);
231
- }
232
- }
233
- emitVirentia(unit, payload, options = {}) {
234
- this.assertAlive();
235
- if (options.suppressReaction) this.incrementSuppression(this.suppressedVirentia, unit);
236
- const settled = _virentia_core.allSettled(unit, {
237
- payload,
238
- scope: this.virentia
239
- });
240
- if (options.suppressReaction) settled.finally(() => {
241
- this.decrementSuppression(this.suppressedVirentia, unit);
242
- });
243
- }
244
- shouldSkipEffector(unit) {
245
- return (this.suppressedEffector.get(unit) ?? 0) > 0;
246
- }
247
- shouldSkipVirentia(unit) {
248
- return (this.suppressedVirentia.get(unit) ?? 0) > 0;
249
- }
250
- assertAlive() {
251
- if (this.disposed) throw new Error("Effector compatibility association is disposed");
252
- }
253
- incrementSuppression(map, unit) {
254
- map.set(unit, (map.get(unit) ?? 0) + 1);
255
- }
256
- decrementSuppression(map, unit) {
257
- const next = (map.get(unit) ?? 0) - 1;
258
- if (next <= 0) map.delete(unit);
259
- else map.set(unit, next);
180
+ };
181
+ if (options.suppressWatch) {
182
+ suppressEffector(association, unit, launchUnit);
183
+ return;
260
184
  }
261
- };
185
+ launchUnit();
186
+ }
187
+ function emitVirentia(association, unit, payload, options = {}) {
188
+ const release = options.suppressReaction ? suppressVirentia(association, unit) : null;
189
+ const settled = _virentia_core.allSettled(unit, {
190
+ payload,
191
+ scope: association.virentia
192
+ });
193
+ if (release) settled.finally(release);
194
+ }
195
+ function resolveAssociationFromEffectorScope(scope) {
196
+ if (!scope) throw createMissingAssociationError({});
197
+ const association = ensureAssociation({ effector: scope });
198
+ const activeVirentiaScope = _virentia_core.getCurrentScope();
199
+ if (activeVirentiaScope && activeVirentiaScope !== association.virentia) throw new Error("Effector scope is associated with another Virentia scope");
200
+ return association;
201
+ }
202
+ function resolveAssociationFromVirentiaScope() {
203
+ const activeVirentiaScope = _virentia_core.getCurrentScope();
204
+ if (!activeVirentiaScope) throw createMissingAssociationError({});
205
+ return ensureAssociation({ virentia: activeVirentiaScope });
206
+ }
262
207
  function createEffectorScopeNode(unit, fn) {
263
208
  const node = (0, effector.createNode)({
264
209
  parent: [unit],
@@ -274,62 +219,98 @@ function createEffectorScopeNode(unit, fn) {
274
219
  (0, effector.clearNode)(node);
275
220
  };
276
221
  }
277
- function installLink(runtime, definition) {
278
- const map = definition.map ?? identity;
279
- if (isEffectorUnit(definition.from)) return toUnsubscribe((0, effector.createWatch)({
280
- unit: definition.from,
281
- scope: runtime.effector,
282
- fn(payload) {
283
- if (runtime.shouldSkipEffector(definition.from)) return;
284
- const nextPayload = map(payload);
285
- if (isEffectorUnit(definition.to)) {
286
- runtime.launchEffector(definition.to, nextPayload);
287
- return;
288
- }
289
- runtime.emitVirentia(definition.to, nextPayload, { suppressReaction: true });
290
- }
291
- }));
292
- if (isVirentiaUnit(definition.from)) {
293
- const watcher = _virentia_core.reaction({
294
- on: definition.from,
295
- scope: runtime.virentia,
296
- run(payload) {
297
- if (runtime.shouldSkipVirentia(definition.from)) return;
298
- const nextPayload = map(payload);
299
- if (isEffectorUnit(definition.to)) {
300
- runtime.launchEffector(definition.to, nextPayload, { suppressWatch: true });
301
- return;
302
- }
303
- runtime.emitVirentia(definition.to, nextPayload);
304
- }
305
- });
306
- return () => {
307
- watcher.stop();
308
- };
309
- }
310
- throw new Error("Effector compatibility link expects Effector or Virentia units");
222
+ function identity(value) {
223
+ return value;
311
224
  }
312
- function createMissingRuntimeError(config) {
313
- if (config.effector) return /* @__PURE__ */ new Error("Effector compatibility association is missing for provided Effector scope");
314
- if (config.virentia) return /* @__PURE__ */ new Error("Effector compatibility association is missing for provided Virentia scope");
315
- return /* @__PURE__ */ new Error("Effector compatibility association is missing. Call associate({ virentia, effector }) before using adapters.");
225
+ //#endregion
226
+ //#region lib/fool.ts
227
+ const fooledUnit = Symbol("virentia.effector.fooledUnit");
228
+ const fooledUnits = /* @__PURE__ */ new WeakMap();
229
+ function fool(unit) {
230
+ if (!isObjectLike(unit)) throw new Error("fool() expects an Effector or Virentia unit");
231
+ if (unit[fooledUnit]) return unit;
232
+ const cached = fooledUnits.get(unit);
233
+ if (cached) return cached;
234
+ const fooled = isEffectorUnit(unit) ? createFooledEffectorUnit(unit) : isVirentiaUnit(unit) ? createFooledVirentiaUnit(unit) : null;
235
+ if (!fooled) throw new Error("fool() expects an Effector or Virentia unit");
236
+ markFooledUnit(fooled);
237
+ fooledUnits.set(unit, fooled);
238
+ return fooled;
316
239
  }
317
- function isEffectorUnit(value) {
318
- return effector.is.unit(value);
240
+ function createFooledVirentiaUnit(unit) {
241
+ const effectorUnit = createEffectorAdapter(unit);
242
+ const base = typeof unit === "function" ? createCallableBridge((...args) => unit(...args)) : {};
243
+ copyUnitProperties(base, effectorUnit);
244
+ copyUnitProperties(base, unit);
245
+ return base;
319
246
  }
320
- function isVirentiaUnit(value) {
321
- return Boolean(value && (typeof value === "object" || typeof value === "function") && "node" in value && !isEffectorUnit(value));
247
+ function createFooledEffectorUnit(unit) {
248
+ const virentiaUnit = createVirentiaAdapter(unit);
249
+ const base = typeof unit === "function" || typeof virentiaUnit === "function" ? createCallableBridge((...args) => {
250
+ if (_virentia_core.getCurrentScope() && typeof virentiaUnit === "function") return virentiaUnit(...args);
251
+ if (typeof unit === "function") return unit(...args);
252
+ throw new Error("Effector store cannot be called");
253
+ }) : {};
254
+ copyUnitProperties(base, virentiaUnit);
255
+ copyUnitProperties(base, unit);
256
+ return base;
322
257
  }
323
- function isVirentiaEffect(value) {
324
- return Boolean(isVirentiaUnit(value) && "doneData" in value && "$pending" in value);
258
+ function createCallableBridge(call) {
259
+ return (...args) => call(...args);
325
260
  }
326
- function toUnsubscribe(subscription) {
327
- return () => {
328
- subscription.unsubscribe();
329
- };
261
+ function createEffectorAdapter(unit) {
262
+ if (isEffectorUnit(unit)) return unit;
263
+ if (isVirentiaEffect(unit)) {
264
+ const scopeQueue = [];
265
+ const adapter = (0, effector.createEffect)((payload) => {
266
+ return callAssociation(resolveAssociationFromEffectorScope(scopeQueue.shift()), unit, payload);
267
+ });
268
+ createEffectorScopeNode(adapter, (_payload, scope) => {
269
+ scopeQueue.push(scope);
270
+ });
271
+ return adapter;
272
+ }
273
+ const adapter = (0, effector.createEvent)();
274
+ createEffectorScopeNode(adapter, (payload, scope) => {
275
+ const association = resolveAssociationFromEffectorScope(scope);
276
+ if (shouldSkipEffector(association, adapter)) return;
277
+ emitVirentia(association, unit, payload, { suppressReaction: true });
278
+ });
279
+ installVirentiaToEffectorLink(unit, adapter);
280
+ return adapter;
330
281
  }
331
- function identity(value) {
332
- return value;
282
+ function createVirentiaAdapter(unit) {
283
+ if (isVirentiaUnit(unit)) return unit;
284
+ if (effector.is.effect(unit)) return _virentia_core.effect((payload) => {
285
+ return callAssociation(resolveAssociationFromVirentiaScope(), unit, payload);
286
+ });
287
+ const adapter = _virentia_core.event();
288
+ createEffectorScopeNode(unit, (payload, scope) => {
289
+ const association = resolveAssociationFromEffectorScope(scope);
290
+ if (shouldSkipEffector(association, unit)) return;
291
+ emitVirentia(association, adapter, payload, { suppressReaction: true });
292
+ });
293
+ installVirentiaToEffectorLink(adapter, unit);
294
+ return adapter;
295
+ }
296
+ function copyUnitProperties(target, source) {
297
+ for (const key of Reflect.ownKeys(source)) {
298
+ if (key === "length" || key === "name" || key === "prototype") continue;
299
+ const descriptor = Object.getOwnPropertyDescriptor(source, key);
300
+ if (!descriptor) continue;
301
+ const existing = Object.getOwnPropertyDescriptor(target, key);
302
+ if (existing && !existing.configurable) continue;
303
+ Object.defineProperty(target, key, descriptor);
304
+ }
305
+ }
306
+ function markFooledUnit(unit) {
307
+ Object.defineProperty(unit, fooledUnit, {
308
+ enumerable: false,
309
+ value: true
310
+ });
333
311
  }
334
312
  //#endregion
335
- exports.createEffectorCompatibility = createEffectorCompatibility;
313
+ exports.associate = associate;
314
+ exports.effectorAssociations = effectorAssociations;
315
+ exports.ensureAssociation = ensureAssociation;
316
+ exports.fool = fool;
package/dist/index.d.cts CHANGED
@@ -1,10 +1,7 @@
1
1
  import * as virentia from "@virentia/core";
2
2
  import { Effect, EventCallable, Scope, Unit, UnitTargetable } from "effector";
3
3
 
4
- //#region lib/index.d.ts
5
- interface EffectorCompatibilityOptions {
6
- name?: string;
7
- }
4
+ //#region lib/types.d.ts
8
5
  interface EffectorAssociationConfig {
9
6
  virentia: virentia.Scope;
10
7
  effector: Scope;
@@ -13,24 +10,31 @@ interface EffectorAssociationLookup {
13
10
  virentia?: virentia.Scope;
14
11
  effector?: Scope;
15
12
  }
16
- type EffectorPayloadMap<From, To> = (payload: From) => To;
17
- type EffectorCompatibilityUnsubscribe = () => void;
18
13
  interface EffectorAssociation {
19
- dispose(): void;
14
+ readonly virentia: virentia.Scope;
15
+ readonly effector: Scope;
20
16
  }
21
- interface EffectorCompatibility {
22
- associate(config: EffectorAssociationConfig): EffectorAssociation;
23
- ensureAssociation(config?: EffectorAssociationLookup): EffectorAssociation;
24
- link<From, To = From>(from: Unit<From> | VirentiaUnit<From>, to: UnitTargetable<To> | VirentiaTarget<To>, map?: EffectorPayloadMap<From, To>): EffectorCompatibilityUnsubscribe;
25
- asEffector<T>(unit: virentia.Effect<T, any, any>): Effect<T, any, unknown>;
26
- asEffector<T>(unit: VirentiaUnit<T>): EventCallable<T>;
27
- asEffector<T>(unit: Unit<T>): Unit<T>;
28
- asVirentia<T>(unit: VirentiaUnit<T>): VirentiaUnit<T>;
29
- asVirentia<T>(unit: Effect<T, any, any>): virentia.Effect<T, any, unknown>;
30
- asVirentia<T>(unit: Unit<T>): virentia.EventCallable<T>;
17
+ interface EffectorAssociations {
18
+ readonly byVirentia: WeakMap<virentia.Scope, EffectorAssociation>;
19
+ readonly byEffector: WeakMap<Scope, EffectorAssociation>;
31
20
  }
32
21
  type VirentiaUnit<T = unknown> = virentia.Event<T> | virentia.EventCallable<T> | virentia.Effect<T, any, any> | virentia.Store<T> | virentia.StoreWritable<T>;
33
22
  type VirentiaTarget<T = unknown> = virentia.EventCallable<T> | virentia.Effect<T, any, any> | virentia.StoreWritable<T>;
34
- declare function createEffectorCompatibility(_options?: EffectorCompatibilityOptions): EffectorCompatibility;
35
23
  //#endregion
36
- export { EffectorAssociation, EffectorAssociationConfig, EffectorAssociationLookup, EffectorCompatibility, EffectorCompatibilityOptions, EffectorCompatibilityUnsubscribe, EffectorPayloadMap, VirentiaTarget, VirentiaUnit, createEffectorCompatibility };
24
+ //#region lib/associations.d.ts
25
+ declare const effectorAssociations: EffectorAssociations;
26
+ declare function associate(config: EffectorAssociationConfig): EffectorAssociation;
27
+ declare function ensureAssociation(config?: EffectorAssociationLookup): EffectorAssociation;
28
+ //#endregion
29
+ //#region lib/fool.d.ts
30
+ declare function fool<Params, Done, Fail>(unit: virentia.Effect<Params, Done, Fail>): virentia.Effect<Params, Done, Fail> & Effect<Params, Done, Fail>;
31
+ declare function fool<T>(unit: virentia.EventCallable<T>): virentia.EventCallable<T> & EventCallable<T>;
32
+ declare function fool<T>(unit: virentia.Event<T>): virentia.Event<T> & EventCallable<T>;
33
+ declare function fool<T>(unit: virentia.StoreWritable<T>): virentia.StoreWritable<T> & EventCallable<T>;
34
+ declare function fool<T>(unit: virentia.Store<T>): virentia.Store<T> & EventCallable<T>;
35
+ declare function fool<Params, Done, Fail>(unit: Effect<Params, Done, Fail>): Effect<Params, Done, Fail> & virentia.Effect<Params, Done, Fail>;
36
+ declare function fool<T>(unit: EventCallable<T>): EventCallable<T> & virentia.EventCallable<T>;
37
+ declare function fool<T>(unit: UnitTargetable<T>): UnitTargetable<T> & virentia.EventCallable<T>;
38
+ declare function fool<T>(unit: Unit<T>): Unit<T> & virentia.EventCallable<T>;
39
+ //#endregion
40
+ export { EffectorAssociation, EffectorAssociationConfig, EffectorAssociationLookup, EffectorAssociations, VirentiaTarget, VirentiaUnit, associate, effectorAssociations, ensureAssociation, fool };