@oscarpalmer/mora 0.13.0 → 0.14.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.
Files changed (60) hide show
  1. package/dist/batch.cjs +2 -2
  2. package/dist/batch.js +1 -1
  3. package/dist/effect.cjs +2 -1
  4. package/dist/effect.js +2 -1
  5. package/dist/helpers/emit.cjs +42 -0
  6. package/dist/helpers/emit.js +42 -0
  7. package/dist/helpers/is.cjs +34 -0
  8. package/dist/helpers/is.js +34 -0
  9. package/dist/helpers/value.cjs +22 -0
  10. package/dist/helpers/value.js +22 -0
  11. package/dist/index.cjs +12 -11
  12. package/dist/index.js +5 -4
  13. package/dist/mora.full.js +152 -140
  14. package/dist/{array.cjs → value/array.cjs} +27 -49
  15. package/dist/{array.js → value/array.js} +9 -31
  16. package/dist/{computed.cjs → value/computed.cjs} +6 -5
  17. package/dist/{computed.js → value/computed.js} +4 -3
  18. package/dist/{reactive.cjs → value/reactive.cjs} +1 -1
  19. package/dist/{reactive.js → value/reactive.js} +1 -1
  20. package/dist/value/signal.cjs +33 -0
  21. package/dist/{signal.js → value/signal.js} +3 -2
  22. package/package.json +1 -1
  23. package/src/batch.ts +1 -1
  24. package/src/effect.ts +12 -11
  25. package/src/helpers/emit.ts +52 -0
  26. package/src/helpers/is.ts +56 -0
  27. package/src/helpers/value.ts +27 -0
  28. package/src/index.ts +11 -5
  29. package/src/subscription.ts +1 -1
  30. package/src/{array.ts → value/array.ts} +10 -41
  31. package/src/{computed.ts → value/computed.ts} +4 -3
  32. package/src/{reactive.ts → value/reactive.ts} +3 -3
  33. package/src/{signal.ts → value/signal.ts} +3 -2
  34. package/types/batch.d.cts +9 -9
  35. package/types/helpers/emit.d.cts +63 -0
  36. package/types/helpers/emit.d.ts +3 -0
  37. package/types/{is.d.cts → helpers/is.d.cts} +53 -9
  38. package/types/helpers/is.d.ts +26 -0
  39. package/types/{value.d.cts → helpers/value.d.cts} +9 -10
  40. package/types/{value.d.ts → helpers/value.d.ts} +1 -2
  41. package/types/index.d.cts +42 -38
  42. package/types/index.d.ts +5 -5
  43. package/types/subscription.d.cts +12 -12
  44. package/types/subscription.d.ts +1 -1
  45. package/types/{computed.d.ts → value/computed.d.ts} +1 -1
  46. package/types/{reactive.d.ts → value/reactive.d.ts} +2 -2
  47. package/dist/is.cjs +0 -21
  48. package/dist/is.js +0 -21
  49. package/dist/signal.cjs +0 -32
  50. package/dist/value.cjs +0 -38
  51. package/dist/value.js +0 -38
  52. package/src/is.ts +0 -39
  53. package/src/value.ts +0 -47
  54. package/types/is.d.ts +0 -17
  55. package/types/{array.d.cts → value/array.d.cts} +9 -9
  56. package/types/{array.d.ts → value/array.d.ts} +0 -0
  57. package/types/{computed.d.cts → value/computed.d.cts} +9 -9
  58. package/types/{reactive.d.cts → value/reactive.d.cts} +9 -9
  59. package/types/{signal.d.cts → value/signal.d.cts} +9 -9
  60. /package/types/{signal.d.ts → value/signal.d.ts} +0 -0
@@ -4,23 +4,25 @@ var __typeError = (msg) => {
4
4
  };
5
5
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
6
6
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
7
- var __privateAdd = (obj, member, value2) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value2);
7
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
8
8
  var _size;
9
9
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
10
- const reactive = require("./reactive.cjs");
11
- const signal = require("./signal.cjs");
12
- const value = require("./value.cjs");
13
- class ReactiveArray extends reactive.Reactive {
14
- constructor(value2) {
10
+ const helpers_emit = require("../helpers/emit.cjs");
11
+ const helpers_is = require("../helpers/is.cjs");
12
+ const helpers_value = require("../helpers/value.cjs");
13
+ const value_reactive = require("./reactive.cjs");
14
+ const value_signal = require("./signal.cjs");
15
+ class ReactiveArray extends value_reactive.Reactive {
16
+ constructor(value) {
15
17
  super(
16
- "array",
17
- new Proxy(value2, {
18
+ helpers_is.arrayName,
19
+ new Proxy(value, {
18
20
  get: (target, property) => updateMethods.has(property) ? updateArray(property, target, this.state, __privateGet(this, _size)) : Reflect.get(target, property),
19
- set: (target, property, value22) => setValue(target, property, value22, this.state, __privateGet(this, _size))
21
+ set: (target, property, value2) => setValue(target, property, value2, this.state, __privateGet(this, _size))
20
22
  })
21
23
  );
22
- __privateAdd(this, _size, signal.signal(0));
23
- __privateGet(this, _size).set(value2.length);
24
+ __privateAdd(this, _size, value_signal.signal(0));
25
+ __privateGet(this, _size).set(value.length);
24
26
  }
25
27
  /**
26
28
  * The length of the array
@@ -31,16 +33,16 @@ class ReactiveArray extends reactive.Reactive {
31
33
  /**
32
34
  * Set the length of the array
33
35
  */
34
- set length(value2) {
35
- if (typeof value2 === "number" && value2 >= 0 && value2 !== this.state.value.length) {
36
- this.get().length = value2;
36
+ set length(value) {
37
+ if (typeof value === "number" && value >= 0 && value !== this.state.value.length) {
38
+ this.get().length = value;
37
39
  }
38
40
  }
39
41
  /**
40
42
  * @inheritdoc
41
43
  */
42
44
  get() {
43
- return value.getValue(this.state);
45
+ return helpers_value.getValue(this.state);
44
46
  }
45
47
  peek(length) {
46
48
  return length === true ? __privateGet(this, _size).peek() : [...this.state.value];
@@ -56,45 +58,21 @@ class ReactiveArray extends reactive.Reactive {
56
58
  }
57
59
  }
58
60
  _size = new WeakMap();
59
- function array(value2) {
60
- return new ReactiveArray(Array.isArray(value2) ? value2 : []);
61
+ function array(value) {
62
+ return new ReactiveArray(Array.isArray(value) ? value : []);
61
63
  }
62
- function emit(first, second) {
63
- let { length } = first;
64
- if (length !== second.length) {
65
- return true;
66
- }
67
- let offset = 0;
68
- if (length >= 100) {
69
- offset = Math.round(length / 10);
70
- offset = offset > 25 ? 25 : offset;
71
- for (let index = 0; index < offset; index += 1) {
72
- if (!Object.is(first[index], second[index])) {
73
- return true;
74
- }
75
- }
76
- }
77
- length -= offset;
78
- for (let index = offset; index < length; index += 1) {
79
- if (!Object.is(first[index], second[index])) {
80
- return true;
81
- }
82
- }
83
- return false;
84
- }
85
- function setValue(target, property, value$1, state, length) {
64
+ function setValue(target, property, value, state, length) {
86
65
  const isIndex = !Number.isNaN(Number(property));
87
66
  const isLength = property === "length";
88
67
  if (!isIndex && !isLength) {
89
- return Reflect.set(target, property, value$1);
68
+ return Reflect.set(target, property, value);
90
69
  }
91
70
  const previous = Reflect.get(target, property);
92
- if (Object.is(previous, value$1)) {
93
- return true;
71
+ if (!Object.is(previous, value)) {
72
+ Reflect.set(target, property, value);
73
+ helpers_emit.emitValue(state);
74
+ length.set(target.length);
94
75
  }
95
- Reflect.set(target, property, value$1);
96
- value.emitValue(state);
97
- length.set(target.length);
98
76
  return true;
99
77
  }
100
78
  function updateArray(type, array2, state, length) {
@@ -105,8 +83,8 @@ function updateArray(type, array2, state, length) {
105
83
  const result = array2[type](
106
84
  ...args
107
85
  );
108
- if (affectsLength ? array2.length !== previousLength : emit(previousArray, array2)) {
109
- value.emitValue(state);
86
+ if (affectsLength ? array2.length !== previousLength : helpers_emit.emitArrayChanges(previousArray, array2)) {
87
+ helpers_emit.emitValue(state);
110
88
  length.set(array2.length);
111
89
  }
112
90
  return result;
@@ -5,13 +5,15 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
5
5
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
6
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
7
  var _size;
8
+ import { emitValue, emitArrayChanges } from "../helpers/emit.js";
9
+ import { arrayName } from "../helpers/is.js";
10
+ import { getValue } from "../helpers/value.js";
8
11
  import { Reactive } from "./reactive.js";
9
12
  import { signal } from "./signal.js";
10
- import { getValue, emitValue } from "./value.js";
11
13
  class ReactiveArray extends Reactive {
12
14
  constructor(value) {
13
15
  super(
14
- "array",
16
+ arrayName,
15
17
  new Proxy(value, {
16
18
  get: (target, property) => updateMethods.has(property) ? updateArray(property, target, this.state, __privateGet(this, _size)) : Reflect.get(target, property),
17
19
  set: (target, property, value2) => setValue(target, property, value2, this.state, __privateGet(this, _size))
@@ -57,29 +59,6 @@ _size = new WeakMap();
57
59
  function array(value) {
58
60
  return new ReactiveArray(Array.isArray(value) ? value : []);
59
61
  }
60
- function emit(first, second) {
61
- let { length } = first;
62
- if (length !== second.length) {
63
- return true;
64
- }
65
- let offset = 0;
66
- if (length >= 100) {
67
- offset = Math.round(length / 10);
68
- offset = offset > 25 ? 25 : offset;
69
- for (let index = 0; index < offset; index += 1) {
70
- if (!Object.is(first[index], second[index])) {
71
- return true;
72
- }
73
- }
74
- }
75
- length -= offset;
76
- for (let index = offset; index < length; index += 1) {
77
- if (!Object.is(first[index], second[index])) {
78
- return true;
79
- }
80
- }
81
- return false;
82
- }
83
62
  function setValue(target, property, value, state, length) {
84
63
  const isIndex = !Number.isNaN(Number(property));
85
64
  const isLength = property === "length";
@@ -87,12 +66,11 @@ function setValue(target, property, value, state, length) {
87
66
  return Reflect.set(target, property, value);
88
67
  }
89
68
  const previous = Reflect.get(target, property);
90
- if (Object.is(previous, value)) {
91
- return true;
69
+ if (!Object.is(previous, value)) {
70
+ Reflect.set(target, property, value);
71
+ emitValue(state);
72
+ length.set(target.length);
92
73
  }
93
- Reflect.set(target, property, value);
94
- emitValue(state);
95
- length.set(target.length);
96
74
  return true;
97
75
  }
98
76
  function updateArray(type, array2, state, length) {
@@ -103,7 +81,7 @@ function updateArray(type, array2, state, length) {
103
81
  const result = array2[type](
104
82
  ...args
105
83
  );
106
- if (affectsLength ? array2.length !== previousLength : emit(previousArray, array2)) {
84
+ if (affectsLength ? array2.length !== previousLength : emitArrayChanges(previousArray, array2)) {
107
85
  emitValue(state);
108
86
  length.set(array2.length);
109
87
  }
@@ -3,13 +3,14 @@ var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
6
- const batch = require("./batch.cjs");
7
- const effect = require("./effect.cjs");
8
- const reactive = require("./reactive.cjs");
6
+ const batch = require("../batch.cjs");
7
+ const effect = require("../effect.cjs");
8
+ const helpers_is = require("../helpers/is.cjs");
9
+ const value_reactive = require("./reactive.cjs");
9
10
  exports.activeComputed = void 0;
10
- class Computed extends reactive.Reactive {
11
+ class Computed extends value_reactive.Reactive {
11
12
  constructor(callback) {
12
- super("computed", void 0);
13
+ super(helpers_is.computedName, void 0);
13
14
  __publicField(this, "effect", {
14
15
  dirty: true,
15
16
  instance: void 0
@@ -1,13 +1,14 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { batchedHandlers, batchDepth } from "./batch.js";
5
- import { effect, activeEffect, runEffect } from "./effect.js";
4
+ import { batchedHandlers, batchDepth } from "../batch.js";
5
+ import { effect, activeEffect, runEffect } from "../effect.js";
6
+ import { computedName } from "../helpers/is.js";
6
7
  import { Reactive } from "./reactive.js";
7
8
  let activeComputed;
8
9
  class Computed extends Reactive {
9
10
  constructor(callback) {
10
- super("computed", void 0);
11
+ super(computedName, void 0);
11
12
  __publicField(this, "effect", {
12
13
  dirty: true,
13
14
  instance: void 0
@@ -3,7 +3,7 @@ var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
6
- const subscription = require("./subscription.cjs");
6
+ const subscription = require("../subscription.cjs");
7
7
  class Reactive {
8
8
  constructor(name, value) {
9
9
  __publicField(this, "state", {
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { subscribe, unsubscribe } from "./subscription.js";
4
+ import { subscribe, unsubscribe } from "../subscription.js";
5
5
  class Reactive {
6
6
  constructor(name, value) {
7
7
  __publicField(this, "state", {
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const helpers_is = require("../helpers/is.cjs");
4
+ const helpers_value = require("../helpers/value.cjs");
5
+ const value_reactive = require("./reactive.cjs");
6
+ class Signal extends value_reactive.Reactive {
7
+ constructor(value) {
8
+ super(helpers_is.signalName, value);
9
+ }
10
+ /**
11
+ * @inheritdoc
12
+ */
13
+ get() {
14
+ return helpers_value.getValue(this.state);
15
+ }
16
+ /**
17
+ * Set the value
18
+ */
19
+ set(value) {
20
+ helpers_value.setValue(this.state, value);
21
+ }
22
+ /**
23
+ * Update the value
24
+ */
25
+ update(callback) {
26
+ this.set(callback(this.state.value));
27
+ }
28
+ }
29
+ function signal(value) {
30
+ return new Signal(value);
31
+ }
32
+ exports.Signal = Signal;
33
+ exports.signal = signal;
@@ -1,8 +1,9 @@
1
+ import { signalName } from "../helpers/is.js";
2
+ import { getValue, setValue } from "../helpers/value.js";
1
3
  import { Reactive } from "./reactive.js";
2
- import { getValue, setValue } from "./value.js";
3
4
  class Signal extends Reactive {
4
5
  constructor(value) {
5
- super("signal", value);
6
+ super(signalName, value);
6
7
  }
7
8
  /**
8
9
  * @inheritdoc
package/package.json CHANGED
@@ -54,5 +54,5 @@
54
54
  },
55
55
  "type": "module",
56
56
  "types": "./types/index.d.ts",
57
- "version": "0.13.0"
57
+ "version": "0.14.0"
58
58
  }
package/src/batch.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import {type Effect, runEffect} from './effect';
2
- import {isEffect} from './is';
2
+ import {isEffect} from './helpers/is';
3
3
  import type {Subscription} from './subscription';
4
4
 
5
5
  export function flushEffects(): void {
package/src/effect.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type {GenericCallback} from '@oscarpalmer/atoms/models';
2
+ import {effectName} from './helpers/is';
2
3
 
3
4
  type EffectState = {
4
5
  callback: GenericCallback;
@@ -9,22 +10,22 @@ type InternalEffect = {
9
10
  };
10
11
 
11
12
  export class Effect {
12
- private declare readonly $mora: string;
13
+ private declare readonly $mora: string;
13
14
 
14
- private declare readonly state: EffectState;
15
+ private declare readonly state: EffectState;
15
16
 
16
- constructor(callback: GenericCallback) {
17
- Object.defineProperty(this, '$mora', {
18
- value: 'effect',
19
- });
17
+ constructor(callback: GenericCallback) {
18
+ Object.defineProperty(this, '$mora', {
19
+ value: effectName,
20
+ });
20
21
 
21
- this.state = {
22
- callback,
23
- };
22
+ this.state = {
23
+ callback,
24
+ };
24
25
 
25
- runEffect(this);
26
- }
26
+ runEffect(this);
27
27
  }
28
+ }
28
29
 
29
30
  export function runEffect(effect: Effect): void {
30
31
  const previousEffect = activeEffect;
@@ -0,0 +1,52 @@
1
+ import {batchDepth, batchedHandlers, flushEffects} from '../batch';
2
+ import type {InternalComputed} from '../value/computed';
3
+ import type {ReactiveState} from '../value/reactive';
4
+
5
+ export function emitArrayChanges(first: unknown[], second: unknown[]): boolean {
6
+ let {length} = first;
7
+
8
+ if (length !== second.length) {
9
+ return true;
10
+ }
11
+
12
+ let offset = 0;
13
+
14
+ if (length >= 100) {
15
+ offset = Math.round(length / 10);
16
+ offset = offset > 25 ? 25 : offset;
17
+
18
+ for (let index = 0; index < offset; index += 1) {
19
+ if (!Object.is(first[index], second[index])) {
20
+ return true;
21
+ }
22
+ }
23
+ }
24
+
25
+ length -= offset;
26
+
27
+ for (let index = offset; index < length; index += 1) {
28
+ if (!Object.is(first[index], second[index])) {
29
+ return true;
30
+ }
31
+ }
32
+
33
+ return false;
34
+ }
35
+
36
+ export function emitValue<Value>(state: ReactiveState<Value>): void {
37
+ for (const computed of state.computeds) {
38
+ (computed as unknown as InternalComputed).effect.dirty = true;
39
+ }
40
+
41
+ for (const effect of state.effects) {
42
+ batchedHandlers.add(effect);
43
+ }
44
+
45
+ for (const [, subscription] of state.subscriptions) {
46
+ batchedHandlers.add(subscription as never);
47
+ }
48
+
49
+ if (batchDepth === 0) {
50
+ flushEffects();
51
+ }
52
+ }
@@ -0,0 +1,56 @@
1
+ import type {PlainObject} from '@oscarpalmer/atoms/models';
2
+ import type {Effect} from '../effect';
3
+ import type {ReactiveArray} from '../value/array';
4
+ import type {Computed} from '../value/computed';
5
+ import type {Reactive} from '../value/reactive';
6
+ import {signal, type Signal} from '../value/signal';
7
+
8
+ /**
9
+ * Is the value a reactive array?
10
+ */
11
+ export function isArray(value: unknown): value is ReactiveArray<unknown> {
12
+ return isMora<ReactiveArray<unknown>>(value, arrayName);
13
+ }
14
+
15
+ /**
16
+ * Is the value a computed signal?
17
+ */
18
+ export function isComputed(value: unknown): value is Computed<unknown> {
19
+ return isMora<Computed<unknown>>(value, computedName);
20
+ }
21
+
22
+ /**
23
+ * Is the value an effect?
24
+ */
25
+ export function isEffect(value: unknown): value is Effect {
26
+ return isMora<Effect>(value, effectName);
27
+ }
28
+
29
+ function isMora<T>(value: unknown, name: string | Set<string>): value is T {
30
+ return (
31
+ typeof value === 'object' &&
32
+ value != null &&
33
+ '$mora' in value &&
34
+ (typeof name === 'string'
35
+ ? (value as PlainObject).$mora === name
36
+ : name.has((value as PlainObject).$mora as never))
37
+ );
38
+ }
39
+
40
+ export function isReactive(value: unknown): value is Reactive<unknown> {
41
+ return isMora<Reactive<unknown>>(value, reactiveNames);
42
+ }
43
+
44
+ /**
45
+ * Is the value a signal?
46
+ */
47
+ export function isSignal(value: unknown): value is Signal<unknown> {
48
+ return isMora<Signal<unknown>>(value, signalName);
49
+ }
50
+
51
+ export const arrayName = 'array';
52
+ export const computedName = 'computed';
53
+ export const effectName = 'effect';
54
+ export const signalName = 'signal';
55
+
56
+ const reactiveNames = new Set([arrayName, computedName, signalName]);
@@ -0,0 +1,27 @@
1
+ import {activeEffect} from '../effect';
2
+ import {activeComputed} from '../value/computed';
3
+ import type {ReactiveState} from '../value/reactive';
4
+ import {emitValue} from './emit';
5
+
6
+ export function getValue<Value>(state: ReactiveState<Value>): Value {
7
+ if (activeComputed != null) {
8
+ state.computeds.add(activeComputed);
9
+ }
10
+
11
+ if (activeEffect != null) {
12
+ state.effects.add(activeEffect);
13
+ }
14
+
15
+ return state.value;
16
+ }
17
+
18
+ export function setValue<Value>(
19
+ state: ReactiveState<Value>,
20
+ value: Value,
21
+ ): void {
22
+ if (!Object.is(state.value, value)) {
23
+ state.value = value;
24
+
25
+ emitValue(state);
26
+ }
27
+ }
package/src/index.ts CHANGED
@@ -1,7 +1,13 @@
1
- export {array, type ReactiveArray} from './array';
2
1
  export {startBatch, stopBatch} from './batch';
3
- export {computed, type Computed} from './computed';
4
2
  export {effect, type Effect} from './effect';
5
- export {isComputed, isEffect, isReactive, isSignal} from './is';
6
- export type {Reactive} from './reactive';
7
- export {signal, type Signal} from './signal';
3
+ export {
4
+ isArray,
5
+ isComputed,
6
+ isEffect,
7
+ isReactive,
8
+ isSignal,
9
+ } from './helpers/is';
10
+ export {array, type ReactiveArray} from './value/array';
11
+ export {computed, type Computed} from './value/computed';
12
+ export type {Reactive} from './value/reactive';
13
+ export {signal, type Signal} from './value/signal';
@@ -1,5 +1,5 @@
1
1
  import type {GenericCallback} from '@oscarpalmer/atoms/models';
2
- import type {ReactiveState} from './reactive';
2
+ import type {ReactiveState} from './value/reactive';
3
3
 
4
4
  export class Subscription<Value> {
5
5
  constructor(
@@ -1,6 +1,8 @@
1
+ import {emitArrayChanges, emitValue} from '../helpers/emit';
2
+ import {arrayName} from '../helpers/is';
3
+ import {getValue} from '../helpers/value';
1
4
  import {Reactive, type ReactiveState} from './reactive';
2
5
  import {type Signal, signal} from './signal';
3
- import {emitValue, getValue} from './value';
4
6
 
5
7
  export class ReactiveArray<Item> extends Reactive<Item[]> {
6
8
  #size = signal(0);
@@ -27,7 +29,7 @@ export class ReactiveArray<Item> extends Reactive<Item[]> {
27
29
 
28
30
  constructor(value: Item[]) {
29
31
  super(
30
- 'array',
32
+ arrayName,
31
33
  new Proxy(value, {
32
34
  get: (target, property) =>
33
35
  updateMethods.has(property as string)
@@ -95,37 +97,6 @@ export function array<Item>(value: Item[]): ReactiveArray<Item> {
95
97
  return new ReactiveArray(Array.isArray(value) ? value : []);
96
98
  }
97
99
 
98
- function emit(first: unknown[], second: unknown[]): boolean {
99
- let {length} = first;
100
-
101
- if (length !== second.length) {
102
- return true;
103
- }
104
-
105
- let offset = 0;
106
-
107
- if (length >= 100) {
108
- offset = Math.round(length / 10);
109
- offset = offset > 25 ? 25 : offset;
110
-
111
- for (let index = 0; index < offset; index += 1) {
112
- if (!Object.is(first[index], second[index])) {
113
- return true;
114
- }
115
- }
116
- }
117
-
118
- length -= offset;
119
-
120
- for (let index = offset; index < length; index += 1) {
121
- if (!Object.is(first[index], second[index])) {
122
- return true;
123
- }
124
- }
125
-
126
- return false;
127
- }
128
-
129
100
  function setValue<Item>(
130
101
  target: Item[],
131
102
  property: PropertyKey,
@@ -142,15 +113,13 @@ function setValue<Item>(
142
113
 
143
114
  const previous = Reflect.get(target, property);
144
115
 
145
- if (Object.is(previous, value)) {
146
- return true;
147
- }
148
-
149
- Reflect.set(target, property, value);
116
+ if (!Object.is(previous, value)) {
117
+ Reflect.set(target, property, value);
150
118
 
151
- emitValue(state);
119
+ emitValue(state);
152
120
 
153
- length.set(target.length);
121
+ length.set(target.length);
122
+ }
154
123
 
155
124
  return true;
156
125
  }
@@ -173,7 +142,7 @@ function updateArray<Item>(
173
142
  if (
174
143
  affectsLength
175
144
  ? array.length !== previousLength
176
- : emit(previousArray, array)
145
+ : emitArrayChanges(previousArray, array)
177
146
  ) {
178
147
  emitValue(state);
179
148
 
@@ -1,5 +1,6 @@
1
- import {batchDepth, batchedHandlers} from './batch';
2
- import {type Effect, activeEffect, effect, runEffect} from './effect';
1
+ import {batchDepth, batchedHandlers} from '../batch';
2
+ import {type Effect, activeEffect, effect, runEffect} from '../effect';
3
+ import {computedName} from '../helpers/is';
3
4
  import {Reactive, type ReactiveState} from './reactive';
4
5
 
5
6
  type ComputedEffect = {
@@ -21,7 +22,7 @@ export class Computed<Value> extends Reactive<Value> {
21
22
  };
22
23
 
23
24
  constructor(callback: () => Value) {
24
- super('computed', undefined as never);
25
+ super(computedName, undefined as never);
25
26
 
26
27
  this.effect.instance = effect(() => {
27
28
  if (this.effect.dirty) {
@@ -1,11 +1,11 @@
1
- import type {Computed} from './computed';
2
- import type {Effect} from './effect';
1
+ import type {Effect} from '../effect';
3
2
  import {
4
3
  type Subscription,
5
4
  type Unsubscribe,
6
5
  subscribe,
7
6
  unsubscribe,
8
- } from './subscription';
7
+ } from '../subscription';
8
+ import type {Computed} from './computed';
9
9
 
10
10
  export abstract class Reactive<Value> {
11
11
  protected readonly state: ReactiveState<Value> = {
@@ -1,9 +1,10 @@
1
+ import {signalName} from '../helpers/is';
2
+ import {getValue, setValue} from '../helpers/value';
1
3
  import {Reactive} from './reactive';
2
- import {getValue, setValue} from './value';
3
4
 
4
5
  export class Signal<Value> extends Reactive<Value> {
5
6
  constructor(value: Value) {
6
- super('signal', value);
7
+ super(signalName, value);
7
8
  }
8
9
 
9
10
  /**