nexa-reactivity 0.5.2 → 0.6.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/batch.d.ts CHANGED
@@ -1,2 +1 @@
1
1
  export declare function batch(fn: () => void): void;
2
- //# sourceMappingURL=batch.d.ts.map
package/dist/batch.js CHANGED
@@ -8,4 +8,3 @@ export function batch(fn) {
8
8
  endBatch();
9
9
  }
10
10
  }
11
- //# sourceMappingURL=batch.js.map
@@ -1,3 +1,2 @@
1
1
  import { type Signal } from './signal';
2
2
  export declare function computed<T>(fn: () => T): Signal<T>;
3
- //# sourceMappingURL=computed.d.ts.map
package/dist/computed.js CHANGED
@@ -37,4 +37,3 @@ export function computed(fn) {
37
37
  };
38
38
  return comp;
39
39
  }
40
- //# sourceMappingURL=computed.js.map
package/dist/core.d.ts CHANGED
@@ -1,16 +1,33 @@
1
+ export interface NexaReactivityState {
2
+ activeEffect: Effect | null;
3
+ batchDepth: number;
4
+ pendingEffects: Set<Effect>;
5
+ targetToEffectsMap: WeakMap<object, Map<number | string | symbol, Set<Effect>>>;
6
+ postFlushCallback: (() => void) | null;
7
+ }
1
8
  export declare class Effect {
2
- private fn;
9
+ fn: () => any;
3
10
  deps: Set<Effect>[];
4
11
  scheduler: (() => void) | null;
5
- constructor(fn: () => void, scheduler?: () => void);
6
- run(): void;
12
+ active: boolean;
13
+ priority: number;
14
+ isQueued: boolean;
15
+ constructor(fn: () => any, scheduler?: () => void);
16
+ run(): any;
7
17
  dispose(): void;
8
18
  }
9
- export declare function getActiveEffect(): Effect | null;
10
- export declare function setActiveEffect(effect: Effect | null): void;
11
- export declare function track(target: object, key: number | string | symbol): void;
12
- export declare function trigger(target: object, key: number | string | symbol): void;
19
+ export declare function effect(fn: () => void, options?: {
20
+ scheduler?: () => void;
21
+ }): Effect;
13
22
  export declare function isBatching(): boolean;
14
- export declare function beginBatch(): void;
15
- export declare function endBatch(): boolean;
16
- //# sourceMappingURL=core.d.ts.map
23
+ export declare function batch(fn: () => void): void;
24
+ export declare function track(target: object, key: string | symbol): void;
25
+ export declare function trigger(target: object, key: string | symbol): void;
26
+ export declare function untracked<T>(fn: () => T): T;
27
+ export interface Signal<T = any> {
28
+ value: T;
29
+ peek(): T;
30
+ }
31
+ export declare function signal<T>(value: T, label?: string): Signal<T>;
32
+ export declare function computed<T>(fn: () => T): Signal<T>;
33
+ export declare function setPostFlushCallback(cb: () => void): void;
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAyBA,qBAAa,MAAM;IAKf,OAAO,CAAC,EAAE;IAJL,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAK;IACxB,SAAS,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAA;gBAG3B,EAAE,EAAE,MAAM,IAAI,EACtB,SAAS,CAAC,EAAE,MAAM,IAAI;IAKxB,GAAG,IAAI,IAAI;IAWX,OAAO,IAAI,IAAI;CAGhB;AASD,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAE3D;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBzE;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAsB3E;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAED,wBAAgB,QAAQ,IAAI,OAAO,CAQlC"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAkCA,qBAAa,MAAM;IAKf,OAAO,CAAC,EAAE;IAJL,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAK;IACxB,SAAS,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAA;gBAG3B,EAAE,EAAE,MAAM,IAAI,EACtB,SAAS,CAAC,EAAE,MAAM,IAAI;IAKxB,GAAG,IAAI,IAAI;IAWX,OAAO,IAAI,IAAI;CAGhB;AASD,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAE3D;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBzE;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CA0B3E;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAED,wBAAgB,QAAQ,IAAI,OAAO,CAQlC;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAElE"}
package/dist/core.js CHANGED
@@ -3,13 +3,13 @@ const globalObj = (typeof globalThis !== 'undefined'
3
3
  : (typeof window !== 'undefined'
4
4
  ? window
5
5
  : (typeof self !== 'undefined' ? self : {})));
6
- // Initialize shared state if not present
7
6
  if (!globalObj.__NEXA_REACTIVITY_STATE__) {
8
7
  globalObj.__NEXA_REACTIVITY_STATE__ = {
9
8
  activeEffect: null,
10
9
  batchDepth: 0,
11
10
  pendingEffects: new Set(),
12
- targetToEffectsMap: new WeakMap()
11
+ targetToEffectsMap: new WeakMap(),
12
+ postFlushCallback: null
13
13
  };
14
14
  }
15
15
  const state = globalObj.__NEXA_REACTIVITY_STATE__;
@@ -17,36 +17,93 @@ export class Effect {
17
17
  fn;
18
18
  deps = [];
19
19
  scheduler;
20
+ active = true;
21
+ priority = 100;
22
+ isQueued = false;
20
23
  constructor(fn, scheduler) {
21
24
  this.fn = fn;
22
25
  this.scheduler = scheduler ?? null;
23
26
  }
24
27
  run() {
28
+ if (!this.active)
29
+ return this.fn();
25
30
  cleanupDeps(this);
26
31
  const prev = state.activeEffect;
27
32
  state.activeEffect = this;
28
33
  try {
29
- this.fn();
34
+ return this.fn();
30
35
  }
31
36
  finally {
32
37
  state.activeEffect = prev;
33
38
  }
34
39
  }
35
40
  dispose() {
36
- cleanupDeps(this);
41
+ if (this.active) {
42
+ cleanupDeps(this);
43
+ this.active = false;
44
+ }
37
45
  }
38
46
  }
39
47
  function cleanupDeps(effect) {
40
- for (const depSet of effect.deps) {
41
- depSet.delete(effect);
48
+ const { deps } = effect;
49
+ if (deps.length) {
50
+ for (let i = 0; i < deps.length; i++) {
51
+ deps[i].delete(effect);
52
+ }
53
+ deps.length = 0;
54
+ }
55
+ }
56
+ let isFlushing = false;
57
+ function flushEffects() {
58
+ if (isFlushing || state.batchDepth > 0)
59
+ return;
60
+ isFlushing = true;
61
+ try {
62
+ while (state.pendingEffects.size > 0) {
63
+ const effects = Array.from(state.pendingEffects);
64
+ state.pendingEffects.clear();
65
+ // Sort by priority (lower number = higher priority)
66
+ effects.sort((a, b) => a.priority - b.priority);
67
+ for (const e of effects) {
68
+ e.isQueued = false; // Mark as no longer in queue right before running
69
+ if (e.active) {
70
+ if (e.scheduler) {
71
+ e.scheduler();
72
+ }
73
+ else {
74
+ e.run();
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ finally {
81
+ isFlushing = false;
82
+ if (state.postFlushCallback) {
83
+ state.postFlushCallback();
84
+ }
42
85
  }
43
- effect.deps = [];
44
86
  }
45
- export function getActiveEffect() {
46
- return state.activeEffect;
87
+ export function effect(fn, options) {
88
+ const e = new Effect(fn, options?.scheduler);
89
+ e.priority = 200;
90
+ e.run();
91
+ return e;
47
92
  }
48
- export function setActiveEffect(effect) {
49
- state.activeEffect = effect;
93
+ export function isBatching() {
94
+ return state.batchDepth > 0;
95
+ }
96
+ export function batch(fn) {
97
+ state.batchDepth++;
98
+ try {
99
+ fn();
100
+ }
101
+ finally {
102
+ state.batchDepth--;
103
+ if (state.batchDepth === 0) {
104
+ flushEffects();
105
+ }
106
+ }
50
107
  }
51
108
  export function track(target, key) {
52
109
  if (!state.activeEffect)
@@ -56,13 +113,15 @@ export function track(target, key) {
56
113
  depsMap = new Map();
57
114
  state.targetToEffectsMap.set(target, depsMap);
58
115
  }
59
- let deps = depsMap.get(key);
60
- if (!deps) {
61
- deps = new Set();
62
- depsMap.set(key, deps);
116
+ let dep = depsMap.get(key);
117
+ if (!dep) {
118
+ dep = new Set();
119
+ depsMap.set(key, dep);
120
+ }
121
+ if (!dep.has(state.activeEffect)) {
122
+ dep.add(state.activeEffect);
123
+ state.activeEffect.deps.push(dep);
63
124
  }
64
- deps.add(state.activeEffect);
65
- state.activeEffect.deps.push(deps);
66
125
  }
67
126
  export function trigger(target, key) {
68
127
  const depsMap = state.targetToEffectsMap.get(target);
@@ -71,46 +130,81 @@ export function trigger(target, key) {
71
130
  const deps = depsMap.get(key);
72
131
  if (!deps)
73
132
  return;
74
- const effects = new Set(deps);
75
- for (const effect of effects) {
76
- if (isBatching()) {
77
- if (effect.scheduler) {
78
- effect.scheduler();
79
- }
80
- state.pendingEffects.add(effect);
81
- }
82
- else {
83
- if (effect.scheduler) {
84
- effect.scheduler();
85
- }
86
- else {
87
- effect.run();
88
- }
133
+ for (const e of deps) {
134
+ if (e !== state.activeEffect && !e.isQueued) {
135
+ e.isQueued = true;
136
+ state.pendingEffects.add(e);
89
137
  }
90
138
  }
139
+ if (state.batchDepth === 0) {
140
+ flushEffects();
141
+ }
91
142
  }
92
- export function isBatching() {
93
- return state.batchDepth > 0;
94
- }
95
- export function beginBatch() {
96
- state.batchDepth++;
97
- }
98
- export function endBatch() {
99
- state.batchDepth--;
100
- if (state.batchDepth <= 0) {
101
- state.batchDepth = 0;
102
- flushPending();
103
- return true;
104
- }
105
- return false;
143
+ export function untracked(fn) {
144
+ const prev = state.activeEffect;
145
+ state.activeEffect = null;
146
+ try {
147
+ return fn();
148
+ }
149
+ finally {
150
+ state.activeEffect = prev;
151
+ }
106
152
  }
107
- function flushPending() {
108
- const effects = new Set(state.pendingEffects);
109
- state.pendingEffects.clear();
110
- for (const effect of effects) {
111
- if (!effect.scheduler) {
112
- effect.run();
153
+ export function signal(value, label) {
154
+ const obj = {
155
+ _nexa_label: label,
156
+ get value() {
157
+ track(obj, 'value');
158
+ return value;
159
+ },
160
+ set value(newValue) {
161
+ if (!Object.is(value, newValue)) {
162
+ value = newValue;
163
+ trigger(obj, 'value');
164
+ }
165
+ },
166
+ peek() {
167
+ return value;
168
+ }
169
+ };
170
+ try {
171
+ const devtools = typeof window !== 'undefined' && window.__NEXA_DEVTOOLS__;
172
+ if (devtools?.registerSignal) {
173
+ devtools.registerSignal(obj, label);
113
174
  }
114
175
  }
176
+ catch { }
177
+ return obj;
178
+ }
179
+ export function computed(fn) {
180
+ let cachedValue;
181
+ let dirty = true;
182
+ const runner = new Effect(fn, () => {
183
+ if (!dirty) {
184
+ dirty = true;
185
+ trigger(wrapper, 'value');
186
+ }
187
+ });
188
+ runner.priority = 100;
189
+ const wrapper = {
190
+ get value() {
191
+ track(wrapper, 'value');
192
+ if (dirty) {
193
+ cachedValue = runner.run();
194
+ dirty = false;
195
+ }
196
+ return cachedValue;
197
+ },
198
+ peek() {
199
+ if (dirty) {
200
+ cachedValue = runner.run();
201
+ dirty = false;
202
+ }
203
+ return cachedValue;
204
+ }
205
+ };
206
+ return wrapper;
207
+ }
208
+ export function setPostFlushCallback(cb) {
209
+ state.postFlushCallback = cb;
115
210
  }
116
- //# sourceMappingURL=core.js.map
package/dist/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAOA,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,KAAK,WAAW;IAClD,CAAC,CAAC,UAAU;IACZ,CAAC,CAAC,CAAC,OAAO,MAAM,KAAK,WAAW;QAC9B,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,CAAC,OAAO,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAQ,CAAA;AAExD,yCAAyC;AACzC,IAAI,CAAC,SAAS,CAAC,yBAAyB,EAAE,CAAC;IACzC,SAAS,CAAC,yBAAyB,GAAG;QACpC,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,CAAC;QACb,cAAc,EAAE,IAAI,GAAG,EAAU;QACjC,kBAAkB,EAAE,IAAI,OAAO,EAAE;KAClC,CAAA;AACH,CAAC;AAED,MAAM,KAAK,GAAwB,SAAS,CAAC,yBAAyB,CAAA;AAEtE,MAAM,OAAO,MAAM;IAKP;IAJH,IAAI,GAAkB,EAAE,CAAA;IACxB,SAAS,CAAqB;IAErC,YACU,EAAc,EACtB,SAAsB;QADd,OAAE,GAAF,EAAE,CAAY;QAGtB,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,IAAI,CAAA;IACpC,CAAC;IAED,GAAG;QACD,WAAW,CAAC,IAAI,CAAC,CAAA;QACjB,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,CAAA;QAC/B,KAAK,CAAC,YAAY,GAAG,IAAI,CAAA;QACzB,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,EAAE,CAAA;QACX,CAAC;gBAAS,CAAC;YACT,KAAK,CAAC,YAAY,GAAG,IAAI,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,OAAO;QACL,WAAW,CAAC,IAAI,CAAC,CAAA;IACnB,CAAC;CACF;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACvB,CAAC;IACD,MAAM,CAAC,IAAI,GAAG,EAAE,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,KAAK,CAAC,YAAY,CAAA;AAC3B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAqB;IACnD,KAAK,CAAC,YAAY,GAAG,MAAM,CAAA;AAC7B,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,MAAc,EAAE,GAA6B;IACjE,IAAI,CAAC,KAAK,CAAC,YAAY;QAAE,OAAM;IAE/B,IAAI,OAAO,GAAG,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAClD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,GAAG,EAAE,CAAA;QACnB,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/C,CAAC;IAED,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC3B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG,IAAI,GAAG,EAAE,CAAA;QAChB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACxB,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAC5B,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAmB,CAAC,CAAA;AACnD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,MAAc,EAAE,GAA6B;IACnE,MAAM,OAAO,GAAG,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACpD,IAAI,CAAC,OAAO;QAAE,OAAM;IAEpB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC7B,IAAI,CAAC,IAAI;QAAE,OAAM;IAEjB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAA;IAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,MAAM,CAAC,SAAS,EAAE,CAAA;YACpB,CAAC;YACD,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAClC,CAAC;aAAM,CAAC;YACN,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,MAAM,CAAC,SAAS,EAAE,CAAA;YACpB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,EAAE,CAAA;YACd,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,KAAK,CAAC,UAAU,GAAG,CAAC,CAAA;AAC7B,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,KAAK,CAAC,UAAU,EAAE,CAAA;AACpB,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,KAAK,CAAC,UAAU,EAAE,CAAA;IAClB,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,UAAU,GAAG,CAAC,CAAA;QACpB,YAAY,EAAE,CAAA;QACd,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;IAC7C,KAAK,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;IAC5B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,EAAE,CAAA;QACd,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
package/dist/effect.d.ts CHANGED
@@ -1,3 +1,5 @@
1
- export declare function effect(fn: () => void): () => void;
1
+ export type EffectOptions = {
2
+ scheduler?: () => void;
3
+ };
4
+ export declare function effect(fn: () => void, options?: EffectOptions): () => void;
2
5
  export declare function untracked<T>(fn: () => T): T;
3
- //# sourceMappingURL=effect.d.ts.map
package/dist/effect.js CHANGED
@@ -1,6 +1,9 @@
1
1
  import { Effect, getActiveEffect, setActiveEffect } from './core';
2
- export function effect(fn) {
2
+ export function effect(fn, options) {
3
3
  const eff = new Effect(fn);
4
+ if (options?.scheduler) {
5
+ eff.scheduler = options.scheduler;
6
+ }
4
7
  eff.run();
5
8
  return () => eff.dispose();
6
9
  }
@@ -14,4 +17,3 @@ export function untracked(fn) {
14
17
  setActiveEffect(prev);
15
18
  }
16
19
  }
17
- //# sourceMappingURL=effect.js.map
package/dist/index.d.ts CHANGED
@@ -1,6 +1 @@
1
- export { signal } from './signal';
2
- export type { Signal } from './signal';
3
- export { computed } from './computed';
4
- export { effect, untracked } from './effect';
5
- export { batch } from './batch';
6
- //# sourceMappingURL=index.d.ts.map
1
+ export * from './core';
package/dist/index.js CHANGED
@@ -1,5 +1 @@
1
- export { signal } from './signal';
2
- export { computed } from './computed';
3
- export { effect, untracked } from './effect';
4
- export { batch } from './batch';
5
- //# sourceMappingURL=index.js.map
1
+ export * from './core';
package/dist/signal.d.ts CHANGED
@@ -5,4 +5,3 @@ export interface Signal<T = any> {
5
5
  toJSON(): T;
6
6
  }
7
7
  export declare function signal<T>(initial: T): Signal<T>;
8
- //# sourceMappingURL=signal.d.ts.map
package/dist/signal.js CHANGED
@@ -24,4 +24,3 @@ class SignalImpl {
24
24
  export function signal(initial) {
25
25
  return new SignalImpl(initial);
26
26
  }
27
- //# sourceMappingURL=signal.js.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import { signal, computed, effect, batch } from './core';
2
+ console.log('--- Nexa Reactivity Stress Test ---');
3
+ const count = signal(0);
4
+ const double = computed(() => count.value * 2);
5
+ let effectCount = 0;
6
+ effect(() => {
7
+ console.log(`Effect: count=${count.value}, double=${double.value}`);
8
+ effectCount++;
9
+ });
10
+ console.log('Update 1 (count=1)');
11
+ count.value = 1;
12
+ console.log('Update 2 (count=5)');
13
+ count.value = 5;
14
+ console.log('Update 3 (count=10)');
15
+ count.value = 10;
16
+ console.log('--- Batch Test ---');
17
+ batch(() => {
18
+ count.value = 20;
19
+ count.value = 30;
20
+ });
21
+ if (effectCount === 5) {
22
+ console.log('SUCCESS: All updates tracked correctly.');
23
+ }
24
+ else {
25
+ console.error(`FAILURE: Expected 5 effect runs, got ${effectCount}`);
26
+ process.exit(1);
27
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexa-reactivity",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AAEA,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAO1C"}
package/dist/batch.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"batch.js","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAE7C,MAAM,UAAU,KAAK,CAAC,EAAc;IAClC,UAAU,EAAE,CAAA;IACZ,IAAI,CAAC;QACH,EAAE,EAAE,CAAA;IACN,CAAC;YAAS,CAAC;QACT,QAAQ,EAAE,CAAA;IACZ,CAAC;AACH,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"computed.d.ts","sourceRoot":"","sources":["../src/computed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,UAAU,CAAA;AAGtC,wBAAgB,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAuClD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"computed.js","sourceRoot":"","sources":["../src/computed.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAE/C,MAAM,UAAU,QAAQ,CAAI,EAAW;IACrC,IAAI,MAAU,CAAA;IACd,IAAI,KAAK,GAAG,IAAI,CAAA;IAEhB,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,GAAG,EAAE;QAC1B,IAAI,CAAC,KAAK;YAAE,OAAM;QAClB,MAAM,GAAG,EAAE,EAAE,CAAA;QACb,KAAK,GAAG,KAAK,CAAA;IACf,CAAC,EAAE,GAAG,EAAE;QACN,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,IAAI,CAAA;YACZ,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACxB,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,IAAI,GAAc;QACtB,IAAI,KAAK;YACP,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YACpB,IAAI,KAAK,EAAE,CAAC;gBACV,GAAG,CAAC,GAAG,EAAE,CAAA;YACX,CAAC;YACD,OAAO,MAAM,CAAA;QACf,CAAC;QACD,IAAI,KAAK,CAAC,IAAO;YACf,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAA;QAC7C,CAAC;QACD,IAAI;YACF,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,GAAG,EAAE,EAAE,CAAA;gBACb,KAAK,GAAG,KAAK,CAAA;YACf,CAAC;YACD,OAAO,MAAM,CAAA;QACf,CAAC;QACD,MAAM;YACJ,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;QACpB,CAAC;KACF,CAAA;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAIjD;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAQ3C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"effect.js","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AAEjE,MAAM,UAAU,MAAM,CAAC,EAAc;IACnC,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,EAAE,CAAC,CAAA;IAC1B,GAAG,CAAC,GAAG,EAAE,CAAA;IACT,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAA;AAC5B,CAAC;AAED,MAAM,UAAU,SAAS,CAAI,EAAW;IACtC,MAAM,IAAI,GAAG,eAAe,EAAE,CAAA;IAC9B,eAAe,CAAC,IAAI,CAAC,CAAA;IACrB,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAA;IACb,CAAC;YAAS,CAAC;QACT,eAAe,CAAC,IAAI,CAAC,CAAA;IACvB,CAAC;AACH,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../src/signal.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,MAAM,CAAC,CAAC,GAAG,GAAG;IAC7B,IAAI,KAAK,IAAI,CAAC,CAAA;IACd,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC,EAAC;IACjB,IAAI,IAAI,CAAC,CAAA;IACT,MAAM,IAAI,CAAC,CAAA;CACZ;AA6BD,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAE/C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"signal.js","sourceRoot":"","sources":["../src/signal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AASvC,MAAM,UAAU;IACN,MAAM,CAAG;IAEjB,YAAY,OAAU;QACpB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAA;IACvB,CAAC;IAED,IAAI,KAAK;QACP,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACpB,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IAED,IAAI,KAAK,CAAC,QAAW;QACnB,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC;YAAE,OAAM;QAC5C,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAA;QACtB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACxB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;CACF;AAED,MAAM,UAAU,MAAM,CAAI,OAAU;IAClC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;AAChC,CAAC"}