@oscarpalmer/mora 0.13.0 → 0.15.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 (62) 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 +200 -140
  14. package/dist/value/array.cjs +161 -0
  15. package/dist/{array.js → value/array.js} +62 -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} +75 -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} +85 -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 +74 -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/{array.d.cts → value/array.d.cts} +41 -9
  46. package/types/value/array.d.ts +74 -0
  47. package/types/{computed.d.ts → value/computed.d.ts} +1 -1
  48. package/types/{reactive.d.ts → value/reactive.d.ts} +2 -2
  49. package/dist/array.cjs +0 -130
  50. package/dist/is.cjs +0 -21
  51. package/dist/is.js +0 -21
  52. package/dist/signal.cjs +0 -32
  53. package/dist/value.cjs +0 -38
  54. package/dist/value.js +0 -38
  55. package/src/is.ts +0 -39
  56. package/src/value.ts +0 -47
  57. package/types/array.d.ts +0 -41
  58. package/types/is.d.ts +0 -17
  59. package/types/{computed.d.cts → value/computed.d.cts} +9 -9
  60. package/types/{reactive.d.cts → value/reactive.d.cts} +9 -9
  61. package/types/{signal.d.cts → value/signal.d.cts} +9 -9
  62. /package/types/{signal.d.ts → value/signal.d.ts} +0 -0
@@ -0,0 +1,74 @@
1
+ import { type Computed } from './computed';
2
+ import { Reactive } from './reactive';
3
+ export declare class ReactiveArray<Item> extends Reactive<Item[]> {
4
+ #private;
5
+ /**
6
+ * The length of the array
7
+ */
8
+ get length(): number;
9
+ /**
10
+ * Set the length of the array
11
+ */
12
+ set length(value: number);
13
+ constructor(value: Item[]);
14
+ /**
15
+ * Get an indexed item
16
+ */
17
+ at(index: number): Item | undefined;
18
+ /**
19
+ * @inheritdoc
20
+ */
21
+ get(): Item[];
22
+ /**
23
+ * Create a computed, filtered array
24
+ */
25
+ filter(callback: (item: Item, index: number, array: Item[]) => boolean): Computed<Item[]>;
26
+ /**
27
+ * Create a computed, mapped array
28
+ */
29
+ map<Mapped>(callback: (item: Item, index: number, array: Item[]) => Mapped): Computed<Mapped[]>;
30
+ /**
31
+ * @inheritdoc
32
+ */
33
+ peek(): Item[];
34
+ /**
35
+ * Get the length of the array _(without reactivity)_
36
+ */
37
+ peek(length: true): number;
38
+ /**
39
+ * Remove and return the last item of the array
40
+ */
41
+ pop(): Item | undefined;
42
+ /**
43
+ * Add items to the end of the array
44
+ */
45
+ push(...items: Item[]): number;
46
+ /**
47
+ * Set the value
48
+ */
49
+ set(value: Item[]): void;
50
+ /**
51
+ * Set the value at an index
52
+ */
53
+ set(index: number, value: Item): void;
54
+ /**
55
+ * Set the length of the array
56
+ */
57
+ set(property: 'length', value: number): void;
58
+ /**
59
+ * Remove and return the first item of the array
60
+ */
61
+ shift(): Item | undefined;
62
+ /**
63
+ * Remove and return items from the array _(and optionally add new items)_
64
+ */
65
+ splice(from: number, to?: number, ...items: Item[]): Item[];
66
+ /**
67
+ * Add items to the beginning of the array
68
+ */
69
+ unshift(...items: Item[]): number;
70
+ }
71
+ /**
72
+ * Create a reactive array
73
+ */
74
+ export declare function array<Item>(value: Item[]): ReactiveArray<Item>;
@@ -1,4 +1,4 @@
1
- import { type Effect } from './effect';
1
+ import { type Effect } from '../effect';
2
2
  import { Reactive, type ReactiveState } from './reactive';
3
3
  type ComputedEffect = {
4
4
  dirty: boolean;
@@ -1,6 +1,6 @@
1
+ import type { Effect } from '../effect';
2
+ import { type Subscription, type Unsubscribe } from '../subscription';
1
3
  import type { Computed } from './computed';
2
- import type { Effect } from './effect';
3
- import { type Subscription, type Unsubscribe } from './subscription';
4
4
  export declare abstract class Reactive<Value> {
5
5
  protected readonly state: ReactiveState<Value>;
6
6
  constructor(name: string, value: Value);
package/dist/array.cjs DELETED
@@ -1,130 +0,0 @@
1
- "use strict";
2
- var __typeError = (msg) => {
3
- throw TypeError(msg);
4
- };
5
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
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);
8
- var _size;
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) {
15
- super(
16
- "array",
17
- new Proxy(value2, {
18
- 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))
20
- })
21
- );
22
- __privateAdd(this, _size, signal.signal(0));
23
- __privateGet(this, _size).set(value2.length);
24
- }
25
- /**
26
- * The length of the array
27
- */
28
- get length() {
29
- return __privateGet(this, _size).get();
30
- }
31
- /**
32
- * Set the length of the array
33
- */
34
- set length(value2) {
35
- if (typeof value2 === "number" && value2 >= 0 && value2 !== this.state.value.length) {
36
- this.get().length = value2;
37
- }
38
- }
39
- /**
40
- * @inheritdoc
41
- */
42
- get() {
43
- return value.getValue(this.state);
44
- }
45
- peek(length) {
46
- return length === true ? __privateGet(this, _size).peek() : [...this.state.value];
47
- }
48
- set(first, second) {
49
- if (Array.isArray(first)) {
50
- this.state.value.splice(0, this.state.value.length, ...first);
51
- } else if (first === "length") {
52
- this.length = second;
53
- } else if (typeof first === "number") {
54
- this.state.value[first] = second;
55
- }
56
- }
57
- }
58
- _size = new WeakMap();
59
- function array(value2) {
60
- return new ReactiveArray(Array.isArray(value2) ? value2 : []);
61
- }
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) {
86
- const isIndex = !Number.isNaN(Number(property));
87
- const isLength = property === "length";
88
- if (!isIndex && !isLength) {
89
- return Reflect.set(target, property, value$1);
90
- }
91
- const previous = Reflect.get(target, property);
92
- if (Object.is(previous, value$1)) {
93
- return true;
94
- }
95
- Reflect.set(target, property, value$1);
96
- value.emitValue(state);
97
- length.set(target.length);
98
- return true;
99
- }
100
- function updateArray(type, array2, state, length) {
101
- const affectsLength = lengthAffectingMethods.has(type);
102
- const previousArray = affectsLength ? [] : [...array2];
103
- const previousLength = array2.length;
104
- return (...args) => {
105
- const result = array2[type](
106
- ...args
107
- );
108
- if (affectsLength ? array2.length !== previousLength : emit(previousArray, array2)) {
109
- value.emitValue(state);
110
- length.set(array2.length);
111
- }
112
- return result;
113
- };
114
- }
115
- const lengthAffectingMethods = /* @__PURE__ */ new Set([
116
- "pop",
117
- "push",
118
- "shift",
119
- "unshift"
120
- ]);
121
- const updateMethods = /* @__PURE__ */ new Set([
122
- ...lengthAffectingMethods,
123
- "copyWithin",
124
- "fill",
125
- "reverse",
126
- "sort",
127
- "splice"
128
- ]);
129
- exports.ReactiveArray = ReactiveArray;
130
- exports.array = array;
package/dist/is.cjs DELETED
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- function isComputed(value) {
4
- return isMora(value, "computed");
5
- }
6
- function isEffect(value) {
7
- return isMora(value, "effect");
8
- }
9
- function isMora(value, name) {
10
- return typeof value === "object" && value != null && "$mora" in value && value.$mora === name;
11
- }
12
- function isReactive(value) {
13
- return isComputed(value) || isSignal(value);
14
- }
15
- function isSignal(value) {
16
- return isMora(value, "signal");
17
- }
18
- exports.isComputed = isComputed;
19
- exports.isEffect = isEffect;
20
- exports.isReactive = isReactive;
21
- exports.isSignal = isSignal;
package/dist/is.js DELETED
@@ -1,21 +0,0 @@
1
- function isComputed(value) {
2
- return isMora(value, "computed");
3
- }
4
- function isEffect(value) {
5
- return isMora(value, "effect");
6
- }
7
- function isMora(value, name) {
8
- return typeof value === "object" && value != null && "$mora" in value && value.$mora === name;
9
- }
10
- function isReactive(value) {
11
- return isComputed(value) || isSignal(value);
12
- }
13
- function isSignal(value) {
14
- return isMora(value, "signal");
15
- }
16
- export {
17
- isComputed,
18
- isEffect,
19
- isReactive,
20
- isSignal
21
- };
package/dist/signal.cjs DELETED
@@ -1,32 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const reactive = require("./reactive.cjs");
4
- const value = require("./value.cjs");
5
- class Signal extends reactive.Reactive {
6
- constructor(value2) {
7
- super("signal", value2);
8
- }
9
- /**
10
- * @inheritdoc
11
- */
12
- get() {
13
- return value.getValue(this.state);
14
- }
15
- /**
16
- * Set the value
17
- */
18
- set(value$1) {
19
- value.setValue(this.state, value$1);
20
- }
21
- /**
22
- * Update the value
23
- */
24
- update(callback) {
25
- this.set(callback(this.state.value));
26
- }
27
- }
28
- function signal(value2) {
29
- return new Signal(value2);
30
- }
31
- exports.Signal = Signal;
32
- exports.signal = signal;
package/dist/value.cjs DELETED
@@ -1,38 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const batch = require("./batch.cjs");
4
- const computed = require("./computed.cjs");
5
- const effect = require("./effect.cjs");
6
- function emitValue(state) {
7
- for (const computed2 of state.computeds) {
8
- computed2.effect.dirty = true;
9
- }
10
- for (const effect2 of state.effects) {
11
- batch.batchedHandlers.add(effect2);
12
- }
13
- for (const [, subscription] of state.subscriptions) {
14
- batch.batchedHandlers.add(subscription);
15
- }
16
- if (batch.batchDepth === 0) {
17
- batch.flushEffects();
18
- }
19
- }
20
- function getValue(state) {
21
- if (computed.activeComputed != null) {
22
- state.computeds.add(computed.activeComputed);
23
- }
24
- if (effect.activeEffect != null) {
25
- state.effects.add(effect.activeEffect);
26
- }
27
- return state.value;
28
- }
29
- function setValue(state, value) {
30
- if (Object.is(state.value, value)) {
31
- return;
32
- }
33
- state.value = value;
34
- emitValue(state);
35
- }
36
- exports.emitValue = emitValue;
37
- exports.getValue = getValue;
38
- exports.setValue = setValue;
package/dist/value.js DELETED
@@ -1,38 +0,0 @@
1
- import { batchedHandlers, flushEffects, batchDepth } from "./batch.js";
2
- import { activeComputed } from "./computed.js";
3
- import { activeEffect } from "./effect.js";
4
- function emitValue(state) {
5
- for (const computed of state.computeds) {
6
- computed.effect.dirty = true;
7
- }
8
- for (const effect of state.effects) {
9
- batchedHandlers.add(effect);
10
- }
11
- for (const [, subscription] of state.subscriptions) {
12
- batchedHandlers.add(subscription);
13
- }
14
- if (batchDepth === 0) {
15
- flushEffects();
16
- }
17
- }
18
- function getValue(state) {
19
- if (activeComputed != null) {
20
- state.computeds.add(activeComputed);
21
- }
22
- if (activeEffect != null) {
23
- state.effects.add(activeEffect);
24
- }
25
- return state.value;
26
- }
27
- function setValue(state, value) {
28
- if (Object.is(state.value, value)) {
29
- return;
30
- }
31
- state.value = value;
32
- emitValue(state);
33
- }
34
- export {
35
- emitValue,
36
- getValue,
37
- setValue
38
- };
package/src/is.ts DELETED
@@ -1,39 +0,0 @@
1
- import type {PlainObject} from '@oscarpalmer/atoms/models';
2
- import type {Computed} from './computed';
3
- import type {Effect} from './effect';
4
- import type {Reactive} from './reactive';
5
- import type {Signal} from './signal';
6
-
7
- /**
8
- * Is the value a computed signal?
9
- */
10
- export function isComputed(value: unknown): value is Computed<unknown> {
11
- return isMora<Computed<unknown>>(value, 'computed');
12
- }
13
-
14
- /**
15
- * Is the value an effect?
16
- */
17
- export function isEffect(value: unknown): value is Effect {
18
- return isMora<Effect>(value, 'effect');
19
- }
20
-
21
- function isMora<T>(value: unknown, name: string): value is T {
22
- return (
23
- typeof value === 'object' &&
24
- value != null &&
25
- '$mora' in value &&
26
- (value as PlainObject).$mora === name
27
- );
28
- }
29
-
30
- export function isReactive(value: unknown): value is Reactive<unknown> {
31
- return isComputed(value) || isSignal(value);
32
- }
33
-
34
- /**
35
- * Is the value a signal?
36
- */
37
- export function isSignal(value: unknown): value is Signal<unknown> {
38
- return isMora<Signal<unknown>>(value, 'signal');
39
- }
package/src/value.ts DELETED
@@ -1,47 +0,0 @@
1
- import {batchDepth, batchedHandlers, flushEffects} from './batch';
2
- import {type InternalComputed, activeComputed} from './computed';
3
- import {activeEffect} from './effect';
4
- import type {ReactiveState} from './reactive';
5
-
6
- export function emitValue<Value>(state: ReactiveState<Value>): void {
7
- for (const computed of state.computeds) {
8
- (computed as unknown as InternalComputed).effect.dirty = true;
9
- }
10
-
11
- for (const effect of state.effects) {
12
- batchedHandlers.add(effect);
13
- }
14
-
15
- for (const [, subscription] of state.subscriptions) {
16
- batchedHandlers.add(subscription as never);
17
- }
18
-
19
- if (batchDepth === 0) {
20
- flushEffects();
21
- }
22
- }
23
-
24
- export function getValue<Value>(state: ReactiveState<Value>): Value {
25
- if (activeComputed != null) {
26
- state.computeds.add(activeComputed);
27
- }
28
-
29
- if (activeEffect != null) {
30
- state.effects.add(activeEffect);
31
- }
32
-
33
- return state.value;
34
- }
35
-
36
- export function setValue<Value>(
37
- state: ReactiveState<Value>,
38
- value: Value,
39
- ): void {
40
- if (Object.is(state.value, value)) {
41
- return;
42
- }
43
-
44
- state.value = value;
45
-
46
- emitValue(state);
47
- }
package/types/array.d.ts DELETED
@@ -1,41 +0,0 @@
1
- import { Reactive } from './reactive';
2
- export declare class ReactiveArray<Item> extends Reactive<Item[]> {
3
- #private;
4
- /**
5
- * The length of the array
6
- */
7
- get length(): number;
8
- /**
9
- * Set the length of the array
10
- */
11
- set length(value: number);
12
- constructor(value: Item[]);
13
- /**
14
- * @inheritdoc
15
- */
16
- get(): Item[];
17
- /**
18
- * @inheritdoc
19
- */
20
- peek(): Item[];
21
- /**
22
- * Get the length of the array _(without reactivity)_
23
- */
24
- peek(length: true): number;
25
- /**
26
- * Set the value
27
- */
28
- set(value: Item[]): void;
29
- /**
30
- * Set the value at an index
31
- */
32
- set(index: number, value: Item): void;
33
- /**
34
- * Set the length of the array
35
- */
36
- set(property: 'length', value: number): void;
37
- }
38
- /**
39
- * Create a reactive array
40
- */
41
- export declare function array<Item>(value: Item[]): ReactiveArray<Item>;
package/types/is.d.ts DELETED
@@ -1,17 +0,0 @@
1
- import type { Computed } from './computed';
2
- import type { Effect } from './effect';
3
- import type { Reactive } from './reactive';
4
- import type { Signal } from './signal';
5
- /**
6
- * Is the value a computed signal?
7
- */
8
- export declare function isComputed(value: unknown): value is Computed<unknown>;
9
- /**
10
- * Is the value an effect?
11
- */
12
- export declare function isEffect(value: unknown): value is Effect;
13
- export declare function isReactive(value: unknown): value is Reactive<unknown>;
14
- /**
15
- * Is the value a signal?
16
- */
17
- export declare function isSignal(value: unknown): value is Signal<unknown>;
@@ -27,15 +27,6 @@ export declare class Computed<Value> extends Reactive<Value> {
27
27
  * Create a computed value
28
28
  */
29
29
  export declare function computed<Value>(callback: () => Value): Computed<Value>;
30
- declare class Subscription<Value> {
31
- state: ReactiveState<Value>;
32
- callback: GenericCallback;
33
- constructor(state: ReactiveState<Value>, callback: GenericCallback);
34
- }
35
- /**
36
- * Unsubscribe from changes
37
- */
38
- export type Unsubscribe = () => void;
39
30
  declare abstract class Reactive<Value> {
40
31
  protected readonly state: ReactiveState<Value>;
41
32
  constructor(name: string, value: Value);
@@ -70,5 +61,14 @@ export type ReactiveState<Value> = {
70
61
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
71
62
  value: Value;
72
63
  };
64
+ declare class Subscription<Value> {
65
+ state: ReactiveState<Value>;
66
+ callback: GenericCallback;
67
+ constructor(state: ReactiveState<Value>, callback: GenericCallback);
68
+ }
69
+ /**
70
+ * Unsubscribe from changes
71
+ */
72
+ export type Unsubscribe = () => void;
73
73
 
74
74
  export {};
@@ -14,15 +14,6 @@ declare class Computed<Value> extends Reactive<Value> {
14
14
  */
15
15
  get(): Value;
16
16
  }
17
- declare class Subscription<Value> {
18
- state: ReactiveState<Value>;
19
- callback: GenericCallback;
20
- constructor(state: ReactiveState<Value>, callback: GenericCallback);
21
- }
22
- /**
23
- * Unsubscribe from changes
24
- */
25
- export type Unsubscribe = () => void;
26
17
  export declare abstract class Reactive<Value> {
27
18
  protected readonly state: ReactiveState<Value>;
28
19
  constructor(name: string, value: Value);
@@ -57,5 +48,14 @@ export type ReactiveState<Value> = {
57
48
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
58
49
  value: Value;
59
50
  };
51
+ declare class Subscription<Value> {
52
+ state: ReactiveState<Value>;
53
+ callback: GenericCallback;
54
+ constructor(state: ReactiveState<Value>, callback: GenericCallback);
55
+ }
56
+ /**
57
+ * Unsubscribe from changes
58
+ */
59
+ export type Unsubscribe = () => void;
60
60
 
61
61
  export {};
@@ -14,15 +14,6 @@ declare class Computed<Value> extends Reactive<Value> {
14
14
  */
15
15
  get(): Value;
16
16
  }
17
- declare class Subscription<Value> {
18
- state: ReactiveState<Value>;
19
- callback: GenericCallback;
20
- constructor(state: ReactiveState<Value>, callback: GenericCallback);
21
- }
22
- /**
23
- * Unsubscribe from changes
24
- */
25
- export type Unsubscribe = () => void;
26
17
  declare abstract class Reactive<Value> {
27
18
  protected readonly state: ReactiveState<Value>;
28
19
  constructor(name: string, value: Value);
@@ -57,6 +48,15 @@ export type ReactiveState<Value> = {
57
48
  subscriptions: Map<(value: Value) => void, Subscription<Value>>;
58
49
  value: Value;
59
50
  };
51
+ declare class Subscription<Value> {
52
+ state: ReactiveState<Value>;
53
+ callback: GenericCallback;
54
+ constructor(state: ReactiveState<Value>, callback: GenericCallback);
55
+ }
56
+ /**
57
+ * Unsubscribe from changes
58
+ */
59
+ export type Unsubscribe = () => void;
60
60
  export declare class Signal<Value> extends Reactive<Value> {
61
61
  constructor(value: Value);
62
62
  /**
File without changes