@oscarpalmer/mora 0.24.0 → 0.26.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/package.json CHANGED
@@ -4,20 +4,19 @@
4
4
  "url": "https://oscarpalmer.se"
5
5
  },
6
6
  "dependencies": {
7
- "@oscarpalmer/atoms": "^0.114"
7
+ "@oscarpalmer/atoms": "^0.124"
8
8
  },
9
9
  "description": "Signals and stuff…",
10
10
  "devDependencies": {
11
- "@biomejs/biome": "^2.3",
12
- "@rollup/plugin-node-resolve": "^16",
13
- "@rollup/plugin-typescript": "^12.3",
14
- "@types/node": "^24.10",
11
+ "@types/node": "^25",
15
12
  "@vitest/coverage-istanbul": "^4",
16
- "jsdom": "^27.2",
17
- "rollup": "^4.53",
13
+ "jsdom": "^27.3",
14
+ "oxfmt": "^0.21",
15
+ "oxlint": "^1.36",
16
+ "rolldown": "1.0.0-beta.58",
18
17
  "tslib": "^2.8",
19
18
  "typescript": "^5.9",
20
- "vite": "npm:rolldown-vite@latest",
19
+ "vite": "8.0.0-beta.5",
21
20
  "vitest": "^4"
22
21
  },
23
22
  "exports": {
@@ -37,14 +36,14 @@
37
36
  "url": "git+https://github.com/oscarpalmer/mora.git"
38
37
  },
39
38
  "scripts": {
40
- "build": "npm run clean && npx vite build && npm run rollup:build && npx tsc",
39
+ "build": "npm run clean && npx vite build && npm run rolldown:build && npx tsc",
41
40
  "clean": "rm -rf ./dist && rm -rf ./types && rm -f ./tsconfig.tsbuildinfo",
42
- "rollup:build": "npx rollup -c",
43
- "rollup:watch": "npx rollup -c --watch",
41
+ "rolldown:build": "npx rolldown -c",
42
+ "rolldown:watch": "npx rolldown -c --watch",
44
43
  "test": "npx vitest --coverage",
45
44
  "watch": "npx vite build --watch"
46
45
  },
47
46
  "type": "module",
48
47
  "types": "./types/index.d.ts",
49
- "version": "0.24.0"
48
+ "version": "0.26.0"
50
49
  }
package/src/batch.ts CHANGED
@@ -20,7 +20,7 @@ export function flushHandlers(): void {
20
20
 
21
21
  /**
22
22
  * Start batching effects
23
- *
23
+ *
24
24
  * _(Use {@link stopBatch} to flush and run batched effects)_
25
25
  */
26
26
  export function startBatch(): void {
package/src/constants.ts CHANGED
@@ -15,14 +15,14 @@ export const BATCH: Batch = {
15
15
  handlers: new Set<Effect | Subscription>(),
16
16
  };
17
17
 
18
- export const METHODS_AFFECTING_LENGTH: Set<string> = new Set<string>([
18
+ export const METHODS_AFFECTING_LENGTH = new Set<string>([
19
19
  'pop',
20
20
  'push',
21
21
  'shift',
22
22
  'unshift',
23
23
  ]);
24
24
 
25
- export const METHODS_UPDATE: Set<string> = new Set<string>([
25
+ export const METHODS_UPDATE = new Set<string>([
26
26
  ...METHODS_AFFECTING_LENGTH,
27
27
  'copyWithin',
28
28
  'fill',
@@ -43,11 +43,6 @@ export const NAME_SIGNAL = 'signal';
43
43
 
44
44
  export const NAME_STORE = 'store';
45
45
 
46
- export const NAMES: Set<string> = new Set([
47
- NAME_ARRAY,
48
- NAME_COMPUTED,
49
- NAME_SIGNAL,
50
- NAME_STORE,
51
- ]);
46
+ export const NAME_ALL = new Set([NAME_ARRAY, NAME_COMPUTED, NAME_SIGNAL, NAME_STORE]);
52
47
 
53
48
  export const PROPERTY_LENGTH = 'length';
package/src/effect.ts CHANGED
@@ -3,9 +3,9 @@ import {ACTIVE, NAME_EFFECT, NAME_MORA} from './constants';
3
3
  import type {EffectState, InternalEffect} from './models';
4
4
 
5
5
  export class Effect {
6
- private declare readonly $mora: string;
6
+ declare private readonly $mora: string;
7
7
 
8
- private declare readonly state: EffectState;
8
+ declare private readonly state: EffectState;
9
9
 
10
10
  constructor(callback: GenericCallback) {
11
11
  Object.defineProperty(this, NAME_MORA, {
@@ -38,7 +38,5 @@ export function runEffect(effect: Effect): void {
38
38
  * @returns Effect
39
39
  */
40
40
  export function effect(callback: GenericCallback): Effect {
41
- return typeof callback === 'function'
42
- ? new Effect(callback)
43
- : (undefined as never);
41
+ return typeof callback === 'function' ? new Effect(callback) : (undefined as never);
44
42
  }
package/src/helpers/is.ts CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  NAME_MORA,
7
7
  NAME_SIGNAL,
8
8
  NAME_STORE,
9
- NAMES,
9
+ NAME_ALL,
10
10
  } from '../constants';
11
11
  import type {Effect} from '../effect';
12
12
  import type {ReactiveArray} from '../value/array';
@@ -58,10 +58,8 @@ function isMora<T>(value: unknown, name: string | Set<string>): value is T {
58
58
  * @param value Value to check
59
59
  * @returns True if value is a {@link Reactive}
60
60
  */
61
- export function isReactive<Value, Equal = Value>(
62
- value: unknown,
63
- ): value is Reactive<Value, Equal> {
64
- return isMora<Reactive<Value, Equal>>(value, NAMES);
61
+ export function isReactive<Value, Equal = Value>(value: unknown): value is Reactive<Value, Equal> {
62
+ return isMora<Reactive<Value, Equal>>(value, NAME_ALL);
65
63
  }
66
64
 
67
65
  /**
@@ -78,8 +76,6 @@ export function isSignal<Value>(value: unknown): value is Signal<Value> {
78
76
  * @param value Value to check
79
77
  * @returns True if value is a {@link Store}
80
78
  */
81
- export function isStore<Value extends PlainObject>(
82
- value: unknown,
83
- ): value is Store<Value> {
79
+ export function isStore<Value extends PlainObject>(value: unknown): value is Store<Value> {
84
80
  return isMora<Store<Value>>(value, NAME_STORE);
85
81
  }
@@ -1,15 +1,7 @@
1
- import type {
2
- ArrayOrPlainObject,
3
- Key,
4
- PlainObject,
5
- } from '@oscarpalmer/atoms/models';
1
+ import type {ArrayOrPlainObject, Key, PlainObject} from '@oscarpalmer/atoms/models';
6
2
  import {startBatch, stopBatch} from '../batch';
7
3
  import {PROPERTY_LENGTH} from '../constants';
8
- import type {
9
- InternalComputed,
10
- ReactiveState,
11
- SetValueInProxyParameters,
12
- } from '../models';
4
+ import type {InternalComputed, ReactiveState, SetValueInProxyParameters} from '../models';
13
5
  import type {ReactiveArray} from '../value/array';
14
6
  import {type Computed, computed} from '../value/computed';
15
7
  import type {Store} from '../value/store';
@@ -74,10 +66,7 @@ export function getReactiveValueInProxy(
74
66
  return item;
75
67
  }
76
68
 
77
- export function setProxyValue(
78
- proxy: ArrayOrPlainObject,
79
- value: ArrayOrPlainObject,
80
- ): void {
69
+ export function setProxyValue(proxy: ArrayOrPlainObject, value: ArrayOrPlainObject): void {
81
70
  startBatch();
82
71
 
83
72
  const proxyKeys = Object.keys(proxy);
@@ -88,9 +77,7 @@ export function setProxyValue(
88
77
  for (let index = 0; index < length; index += 1) {
89
78
  const key = proxyKeys[index];
90
79
 
91
- (proxy as PlainObject)[key] = valueKeys.includes(key)
92
- ? (value as PlainObject)[key]
93
- : undefined;
80
+ (proxy as PlainObject)[key] = valueKeys.includes(key) ? (value as PlainObject)[key] : undefined;
94
81
  }
95
82
 
96
83
  length = valueKeys.length;
@@ -1,11 +1,5 @@
1
1
  import {flushHandlers} from '../batch';
2
- import {
3
- ACTIVE,
4
- ARRAY_OFFSET,
5
- ARRAY_PEEK,
6
- ARRAY_THRESHOLD,
7
- BATCH,
8
- } from '../constants';
2
+ import {ACTIVE, ARRAY_OFFSET, ARRAY_PEEK, ARRAY_THRESHOLD, BATCH} from '../constants';
9
3
  import type {InternalComputed, ReactiveState} from '../models';
10
4
 
11
5
  export function emitValue<Value>(state: ReactiveState<Value, never>): void {
package/src/index.ts CHANGED
@@ -1,12 +1,6 @@
1
1
  export {startBatch, stopBatch} from './batch';
2
2
  export {effect, type Effect} from './effect';
3
- export {
4
- isArray,
5
- isComputed,
6
- isEffect,
7
- isReactive,
8
- isSignal,
9
- } from './helpers/is';
3
+ export {isArray, isComputed, isEffect, isReactive, isSignal} from './helpers/is';
10
4
  export type {Unsubscribe} from './models';
11
5
  export {array, type ReactiveArray} from './value/array';
12
6
  export {computed, type Computed} from './value/computed';
@@ -1,10 +1,5 @@
1
1
  import type {GenericCallback} from '@oscarpalmer/atoms/models';
2
- import {
3
- METHODS_AFFECTING_LENGTH,
4
- METHODS_UPDATE,
5
- NAME_ARRAY,
6
- PROPERTY_LENGTH,
7
- } from '../constants';
2
+ import {METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ARRAY, PROPERTY_LENGTH} from '../constants';
8
3
  import {emityProxyValues, getReactiveValueInProxy, setValueInProxy} from '../helpers/proxy';
9
4
  import {emitValue, equalArrays, getValue} from '../helpers/value';
10
5
  import type {ReactiveOptions, ReactiveState, Unsubscribe} from '../models';
@@ -29,11 +24,7 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
29
24
  * Set the length of the array
30
25
  */
31
26
  set length(value: number) {
32
- if (
33
- typeof value === 'number' &&
34
- value >= 0 &&
35
- value !== this.state.value.length
36
- ) {
27
+ if (typeof value === 'number' && value >= 0 && value !== this.state.value.length) {
37
28
  this.get().length = value;
38
29
  }
39
30
  }
@@ -74,9 +65,7 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
74
65
  * @param callback Callback to evaluate each item
75
66
  * @return Computed array of filtered items
76
67
  */
77
- filter(
78
- callback: (item: Item, index: number, array: Item[]) => boolean,
79
- ): Computed<Item[]> {
68
+ filter(callback: (item: Item, index: number, array: Item[]) => boolean): Computed<Item[]> {
80
69
  return computed(() => this.get().filter(callback));
81
70
  }
82
71
 
@@ -111,9 +100,7 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
111
100
  * @param callback Callback to transform each item
112
101
  * @return Computed array of mapped items
113
102
  */
114
- map<Mapped>(
115
- callback: (item: Item, index: number, array: Item[]) => Mapped,
116
- ): Computed<Mapped[]> {
103
+ map<Mapped>(callback: (item: Item, index: number, array: Item[]) => Mapped): Computed<Mapped[]> {
117
104
  return computed(() => this.get().map(callback));
118
105
  }
119
106
 
@@ -130,29 +117,27 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
130
117
  /**
131
118
  * @inheritdoc
132
119
  */
133
- peek(): Item[];
120
+ override peek(): Item[];
134
121
 
135
122
  /**
136
123
  * Get the value at an index _(without reactivity)_
137
124
  * @param index Index of item to get _(if negative, starts from the end)_
138
125
  * @returns Item at index, or `undefined` if it doesn't exist
139
126
  */
140
- peek(index: number): Item | undefined;
127
+ override peek(index: number): Item | undefined;
141
128
 
142
129
  /**
143
130
  * Get the length of the array _(without reactivity)_
144
131
  * @returns Length of the array
145
132
  */
146
- peek(property: 'length'): number;
133
+ override peek(property: 'length'): number;
147
134
 
148
- peek(value?: unknown): unknown {
135
+ override peek(value?: unknown): unknown {
149
136
  if (value === 'length') {
150
137
  return this.#size.peek();
151
138
  }
152
139
 
153
- return typeof value === 'number'
154
- ? this.state.value.at(value)
155
- : [...this.state.value];
140
+ return typeof value === 'number' ? this.state.value.at(value) : [...this.state.value];
156
141
  }
157
142
 
158
143
  /**
@@ -217,17 +202,13 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
217
202
  * @returns Removed items
218
203
  */
219
204
  splice(from: number, to?: number, ...items: Item[]): Item[] {
220
- return this.state.value.splice(
221
- from,
222
- to ?? this.state.value.length,
223
- ...items,
224
- );
205
+ return this.state.value.splice(from, to ?? this.state.value.length, ...items);
225
206
  }
226
207
 
227
208
  /**
228
209
  * @inheritdoc
229
210
  */
230
- subscribe(callback: (value: Item[]) => void): Unsubscribe;
211
+ override subscribe(callback: (value: Item[]) => void): Unsubscribe;
231
212
 
232
213
  /**
233
214
  * Subscribe to changes at a specific index
@@ -235,22 +216,11 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
235
216
  * @param callback Callback for changes
236
217
  * @returns Unsubscribe callback
237
218
  */
238
- subscribe(
239
- index: number,
240
- callback: (value: Item | undefined) => void,
241
- ): Unsubscribe;
242
-
243
- subscribe(
244
- first: number | GenericCallback,
245
- second?: GenericCallback,
246
- ): Unsubscribe {
219
+ override subscribe(index: number, callback: (value: Item | undefined) => void): Unsubscribe;
220
+
221
+ override subscribe(first: number | GenericCallback, second?: GenericCallback): Unsubscribe {
247
222
  if (typeof first === 'number' && typeof second === 'function') {
248
- return getReactiveValueInProxy(
249
- this,
250
- this.#indiced,
251
- first,
252
- true,
253
- ).subscribe(second);
223
+ return getReactiveValueInProxy(this, this.#indiced, first, true).subscribe(second);
254
224
  }
255
225
 
256
226
  return typeof first === 'function' ? subscribe(this.state, first) : noop;
@@ -281,13 +251,10 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
281
251
  /**
282
252
  * Create a reactive array
283
253
  * @param value Initial array of items
284
- * @param options Optional reactivity options
254
+ * @param options Reactivity options
285
255
  * @returns Reactive array
286
256
  */
287
- export function array<Item>(
288
- value: Item[],
289
- options?: ReactiveOptions<Item>,
290
- ): ReactiveArray<Item> {
257
+ export function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item> {
291
258
  return new ReactiveArray(Array.isArray(value) ? value : [], options);
292
259
  }
293
260
 
@@ -302,14 +269,10 @@ function updateArray<Item>(
302
269
  const previousLength = array.length;
303
270
 
304
271
  return (...args: unknown[]): unknown => {
305
- const result = (array[type as never] as (...args: unknown[]) => unknown)(
306
- ...args,
307
- );
272
+ const result = (array[type as never] as (...args: unknown[]) => unknown)(...args);
308
273
 
309
274
  if (
310
- affectsLength
311
- ? array.length !== previousLength
312
- : !equalArrays(state, previousArray, array)
275
+ affectsLength ? array.length !== previousLength : !equalArrays(state, previousArray, array)
313
276
  ) {
314
277
  emitValue(state);
315
278
 
@@ -67,6 +67,9 @@ export class Computed<Value> extends Reactive<Value> {
67
67
 
68
68
  /**
69
69
  * Create a computed value
70
+ * @param callback Callback to compute the value
71
+ * @param options Reactivity options
72
+ * @returns Computed value
70
73
  */
71
74
  export function computed<Value>(
72
75
  callback: () => Value,
@@ -39,12 +39,9 @@ export class Signal<Value> extends Reactive<Value> {
39
39
  /**
40
40
  * Create a reactive value
41
41
  * @param value Initial value
42
- * @param options Optional reactivity options
42
+ * @param options Reactivity options
43
43
  * @returns Reactive value
44
44
  */
45
- export function signal<Value>(
46
- value: Value,
47
- options?: ReactiveOptions<Value>,
48
- ): Signal<Value> {
45
+ export function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value> {
49
46
  return new Signal<Value>(value, options);
50
47
  }
@@ -1,9 +1,5 @@
1
1
  import {isKey, isPlainObject} from '@oscarpalmer/atoms/is';
2
- import type {
3
- GenericCallback,
4
- Key,
5
- PlainObject,
6
- } from '@oscarpalmer/atoms/models';
2
+ import type {GenericCallback, Key, PlainObject} from '@oscarpalmer/atoms/models';
7
3
  import {NAME_STORE} from '../constants';
8
4
  import {
9
5
  getReactiveValueInProxy,
@@ -11,8 +7,8 @@ import {
11
7
  setProxyValue,
12
8
  setValueInProxy,
13
9
  } from '../helpers/proxy';
14
- import {emitValue, getValue} from '../helpers/value';
15
- import type {InternalComputed, ReactiveOptions, Unsubscribe} from '../models';
10
+ import {getValue} from '../helpers/value';
11
+ import type {ReactiveOptions, Unsubscribe} from '../models';
16
12
  import {noop, subscribe} from '../subscription';
17
13
  import type {Computed} from './computed';
18
14
  import {Reactive} from './reactive';
@@ -76,23 +72,23 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
76
72
  * Get the value _(without reactivity)_
77
73
  * @returns The current value
78
74
  */
79
- peek(): Value;
75
+ override peek(): Value;
80
76
 
81
77
  /**
82
78
  * Get a value by key _(without reactivity)_
83
79
  * @param key Key of the value to get
84
80
  * @returns Value for the specified key, or `undefined` if it doesn't exist
85
81
  */
86
- peek<Key extends keyof Value>(key: Key): Value[Key];
82
+ override peek<Key extends keyof Value>(key: Key): Value[Key];
87
83
 
88
84
  /**
89
85
  * Get a value by key _(without reactivity)_
90
86
  * @param key Key of the value to get
91
87
  * @returns Value for the specified key, or `undefined` if it doesn't exist
92
88
  */
93
- peek(key: Key): unknown;
89
+ override peek(key: Key): unknown;
94
90
 
95
- peek(key?: unknown): unknown {
91
+ override peek(key?: unknown): unknown {
96
92
  return isKey(key) ? this.state.value[key] : {...this.state.value};
97
93
  }
98
94
 
@@ -127,7 +123,7 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
127
123
  /**
128
124
  * @inheritdoc
129
125
  */
130
- subscribe(callback: (value: Value) => void): Unsubscribe;
126
+ override subscribe(callback: (value: Value) => void): Unsubscribe;
131
127
 
132
128
  /**
133
129
  * Subscribe to changes for a specific key
@@ -135,7 +131,7 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
135
131
  * @param callback Callback for changes
136
132
  * @returns Unsubscribe callback
137
133
  */
138
- subscribe<Key extends keyof Value>(
134
+ override subscribe<Key extends keyof Value>(
139
135
  key: Key,
140
136
  callback: (value: Value[Key] | undefined) => void,
141
137
  ): Unsubscribe;
@@ -146,16 +142,11 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
146
142
  * @param callback Callback for changes
147
143
  * @returns Unsubscribe callback
148
144
  */
149
- subscribe(key: Key, callback: (value: unknown) => void): Unsubscribe;
145
+ override subscribe(key: Key, callback: (value: unknown) => void): Unsubscribe;
150
146
 
151
- subscribe(
152
- first: Key | GenericCallback,
153
- second?: GenericCallback,
154
- ): Unsubscribe {
147
+ override subscribe(first: Key | GenericCallback, second?: GenericCallback): Unsubscribe {
155
148
  if (isKey(first) && typeof second === 'function') {
156
- return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(
157
- second,
158
- );
149
+ return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
159
150
  }
160
151
 
161
152
  return typeof first === 'function' ? subscribe(this.state, first) : noop;
@@ -177,7 +168,7 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
177
168
  /**
178
169
  * Create a reactive store
179
170
  * @param value Initial object value
180
- * @param options Optional reactivity options
171
+ * @param options Reactivity options
181
172
  * @returns Reactive store
182
173
  */
183
174
  export function store<Value extends PlainObject>(
@@ -12,5 +12,5 @@ export declare const NAME_EFFECT = "effect";
12
12
  export declare const NAME_MORA = "$mora";
13
13
  export declare const NAME_SIGNAL = "signal";
14
14
  export declare const NAME_STORE = "store";
15
- export declare const NAMES: Set<string>;
15
+ export declare const NAME_ALL: Set<string>;
16
16
  export declare const PROPERTY_LENGTH = "length";
package/types/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { startBatch, stopBatch } from './batch';
2
2
  export { effect, type Effect } from './effect';
3
- export { isArray, isComputed, isEffect, isReactive, isSignal, } from './helpers/is';
3
+ export { isArray, isComputed, isEffect, isReactive, isSignal } from './helpers/is';
4
4
  export type { Unsubscribe } from './models';
5
5
  export { array, type ReactiveArray } from './value/array';
6
6
  export { computed, type Computed } from './value/computed';
@@ -131,7 +131,7 @@ export declare class ReactiveArray<Item> extends Reactive<Item[], Item> {
131
131
  /**
132
132
  * Create a reactive array
133
133
  * @param value Initial array of items
134
- * @param options Optional reactivity options
134
+ * @param options Reactivity options
135
135
  * @returns Reactive array
136
136
  */
137
137
  export declare function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item>;
@@ -10,5 +10,8 @@ export declare class Computed<Value> extends Reactive<Value> {
10
10
  }
11
11
  /**
12
12
  * Create a computed value
13
+ * @param callback Callback to compute the value
14
+ * @param options Reactivity options
15
+ * @returns Computed value
13
16
  */
14
17
  export declare function computed<Value>(callback: () => Value, options?: ReactiveOptions<Value>): Computed<Value>;
@@ -20,7 +20,7 @@ export declare class Signal<Value> extends Reactive<Value> {
20
20
  /**
21
21
  * Create a reactive value
22
22
  * @param value Initial value
23
- * @param options Optional reactivity options
23
+ * @param options Reactivity options
24
24
  * @returns Reactive value
25
25
  */
26
26
  export declare function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value>;
@@ -88,7 +88,7 @@ export declare class Store<Value extends PlainObject> extends Reactive<Value, Va
88
88
  /**
89
89
  * Create a reactive store
90
90
  * @param value Initial object value
91
- * @param options Optional reactivity options
91
+ * @param options Reactivity options
92
92
  * @returns Reactive store
93
93
  */
94
94
  export declare function store<Value extends PlainObject>(value: Value, options?: ReactiveOptions<Value>): Store<Value>;