@oscarpalmer/mora 0.28.0 → 0.29.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/effect.d.mts CHANGED
@@ -2,7 +2,17 @@ import { GenericCallback } from "@oscarpalmer/atoms/models";
2
2
 
3
3
  //#region src/effect.d.ts
4
4
  declare class Effect {
5
+ /**
6
+ * Internal name of the effect
7
+ *
8
+ * @internal
9
+ */
5
10
  private readonly $mora;
11
+ /**
12
+ * Internal state of the effect
13
+ *
14
+ * @internal
15
+ */
6
16
  private readonly state;
7
17
  constructor(callback: GenericCallback);
8
18
  }
@@ -1,5 +1,6 @@
1
1
  import { ACTIVE, BATCH } from "../constants.mjs";
2
2
  import { flushHandlers } from "../batch.mjs";
3
+ import { round } from "@oscarpalmer/atoms/math";
3
4
  //#region src/helpers/value.ts
4
5
  function emitValue(state) {
5
6
  for (const computed of state.computeds) computed.effect.dirty = true;
@@ -12,7 +13,7 @@ function equalArrays(state, first, second) {
12
13
  if (length !== second.length) return false;
13
14
  let offset = 0;
14
15
  if (length >= 100) {
15
- offset = Math.round(length / 10);
16
+ offset = round(length / 10);
16
17
  offset = offset > 25 ? 25 : offset;
17
18
  for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
18
19
  }
@@ -156,6 +156,11 @@ function unsubscribe(state, callback) {
156
156
  //#endregion
157
157
  //#region src/value/reactive.ts
158
158
  var Reactive = class {
159
+ /**
160
+ * Internal state of the reactive value
161
+ *
162
+ * @internal
163
+ */
159
164
  state = {
160
165
  computeds: /* @__PURE__ */ new Set(),
161
166
  effects: /* @__PURE__ */ new Set(),
@@ -269,6 +274,44 @@ function setValue$1(instance, state, callback) {
269
274
  }
270
275
  }
271
276
  //#endregion
277
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
278
+ /**
279
+ * Is the value a key?
280
+ * @param value Value to check
281
+ * @returns `true` if the value is a `Key` _(`number` or `string`)_, otherwise `false`
282
+ */
283
+ function isKey(value) {
284
+ return typeof value === "number" || typeof value === "string";
285
+ }
286
+ /**
287
+ * Is the value a plain object?
288
+ * @param value Value to check
289
+ * @returns `true` if the value is a plain object, otherwise `false`
290
+ */
291
+ function isPlainObject(value) {
292
+ if (value === null || typeof value !== "object") return false;
293
+ if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
294
+ const prototype = Object.getPrototypeOf(value);
295
+ return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
296
+ }
297
+ //#endregion
298
+ //#region node_modules/@oscarpalmer/atoms/dist/math.mjs
299
+ /**
300
+ * Round a number
301
+ * @param value Number to round
302
+ * @param decimals Number of decimal places to round to _(defaults to `0`)_
303
+ * @returns Rounded number, or `NaN` if the value if unable to be rounded
304
+ */
305
+ function round(value, decimals) {
306
+ return roundNumber(Math.round, value, decimals);
307
+ }
308
+ function roundNumber(callback, value, decimals) {
309
+ if (typeof value !== "number") return NaN;
310
+ if (typeof decimals !== "number" || decimals < 1) return callback(value);
311
+ const mod = 10 ** decimals;
312
+ return callback((value + Number.EPSILON) * mod) / mod;
313
+ }
314
+ //#endregion
272
315
  //#region src/helpers/value.ts
273
316
  function emitValue(state) {
274
317
  for (const computed of state.computeds) computed.effect.dirty = true;
@@ -281,7 +324,7 @@ function equalArrays(state, first, second) {
281
324
  if (length !== second.length) return false;
282
325
  let offset = 0;
283
326
  if (length >= 100) {
284
- offset = Math.round(length / 10);
327
+ offset = round(length / 10);
285
328
  offset = offset > 25 ? 25 : offset;
286
329
  for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
287
330
  }
@@ -575,27 +618,6 @@ function setAtIndex(state, index, value) {
575
618
  if (actual > -1) state.value[actual] = value;
576
619
  }
577
620
  //#endregion
578
- //#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
579
- /**
580
- * Is the value a key?
581
- * @param value Value to check
582
- * @returns `true` if the value is a `Key` _(`number` or `string`)_, otherwise `false`
583
- */
584
- function isKey(value) {
585
- return typeof value === "number" || typeof value === "string";
586
- }
587
- /**
588
- * Is the value a plain object?
589
- * @param value Value to check
590
- * @returns `true` if the value is a plain object, otherwise `false`
591
- */
592
- function isPlainObject(value) {
593
- if (value === null || typeof value !== "object") return false;
594
- if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
595
- const prototype = Object.getPrototypeOf(value);
596
- return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
597
- }
598
- //#endregion
599
621
  //#region src/value/store.ts
600
622
  var Store = class extends Reactive {
601
623
  #keyed = /* @__PURE__ */ new Map();
@@ -2,6 +2,17 @@ import { ReactiveOptions, ReactiveState, Unsubscribe } from "../models.mjs";
2
2
 
3
3
  //#region src/value/reactive.d.ts
4
4
  declare abstract class Reactive<Value, Equal = Value> {
5
+ /**
6
+ * Internal name of the reactive value
7
+ *
8
+ * @internal
9
+ */
10
+ protected readonly $mora: string;
11
+ /**
12
+ * Internal state of the reactive value
13
+ *
14
+ * @internal
15
+ */
5
16
  protected readonly state: ReactiveState<Value, Equal>;
6
17
  constructor(name: string, value: Value, options?: ReactiveOptions<Equal>);
7
18
  /**
@@ -2,6 +2,11 @@ import { NAME_MORA } from "../constants.mjs";
2
2
  import { subscribe, unsubscribe } from "../subscription.mjs";
3
3
  //#region src/value/reactive.ts
4
4
  var Reactive = class {
5
+ /**
6
+ * Internal state of the reactive value
7
+ *
8
+ * @internal
9
+ */
5
10
  state = {
6
11
  computeds: /* @__PURE__ */ new Set(),
7
12
  effects: /* @__PURE__ */ new Set(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/mora",
3
- "version": "0.28.0",
3
+ "version": "0.29.0",
4
4
  "description": "Signals and stuff…",
5
5
  "keywords": [
6
6
  "reactive",
@@ -35,16 +35,17 @@
35
35
  "build": "vpx vp run tsdown:build && vpx vp pack",
36
36
  "tsdown:build": "vpx tsdown -c ./tsdown.config.ts",
37
37
  "tsdown:watch": "vpx tsdown -c ./tsdown.config.ts --watch",
38
- "test": "vpx vp test run --coverage",
38
+ "test": "npx vp test run --coverage",
39
39
  "test:leak": "vpx vp test run --detect-async-leaks --coverage"
40
40
  },
41
41
  "dependencies": {
42
- "@oscarpalmer/atoms": "^0.172"
42
+ "@oscarpalmer/atoms": "^0.184"
43
43
  },
44
44
  "devDependencies": {
45
- "@types/node": "^25.5",
45
+ "@oxlint/plugins": "^1.62",
46
+ "@types/node": "^25.6",
46
47
  "@vitest/coverage-istanbul": "^4.1",
47
- "jsdom": "^29",
48
+ "jsdom": "^29.1",
48
49
  "tsdown": "^0.21",
49
50
  "typescript": "^5.9",
50
51
  "vite": "npm:@voidzero-dev/vite-plus-core@latest",
package/src/effect.ts CHANGED
@@ -3,8 +3,18 @@ import {ACTIVE, NAME_EFFECT, NAME_MORA} from './constants';
3
3
  import type {EffectState, InternalEffect} from './models';
4
4
 
5
5
  export class Effect {
6
+ /**
7
+ * Internal name of the effect
8
+ *
9
+ * @internal
10
+ */
6
11
  declare private readonly $mora: string;
7
12
 
13
+ /**
14
+ * Internal state of the effect
15
+ *
16
+ * @internal
17
+ */
8
18
  declare private readonly state: EffectState;
9
19
 
10
20
  constructor(callback: GenericCallback) {
@@ -1,3 +1,4 @@
1
+ import {round} from '@oscarpalmer/atoms/math';
1
2
  import {flushHandlers} from '../batch';
2
3
  import {ACTIVE, ARRAY_OFFSET, ARRAY_PEEK, ARRAY_THRESHOLD, BATCH} from '../constants';
3
4
  import type {InternalComputed, ReactiveState} from '../models';
@@ -34,7 +35,7 @@ export function equalArrays<Value>(
34
35
  let offset = 0;
35
36
 
36
37
  if (length >= ARRAY_THRESHOLD) {
37
- offset = Math.round(length / ARRAY_PEEK);
38
+ offset = round(length / ARRAY_PEEK);
38
39
  offset = offset > ARRAY_OFFSET ? ARRAY_OFFSET : offset;
39
40
 
40
41
  for (let index = 0; index < offset; index += 1) {
@@ -3,6 +3,18 @@ import type {ReactiveOptions, ReactiveState, Unsubscribe} from '../models';
3
3
  import {subscribe, unsubscribe} from '../subscription';
4
4
 
5
5
  export abstract class Reactive<Value, Equal = Value> {
6
+ /**
7
+ * Internal name of the reactive value
8
+ *
9
+ * @internal
10
+ */
11
+ declare protected readonly $mora: string;
12
+
13
+ /**
14
+ * Internal state of the reactive value
15
+ *
16
+ * @internal
17
+ */
6
18
  protected readonly state: ReactiveState<Value, Equal> = {
7
19
  computeds: new Set(),
8
20
  effects: new Set(),
@@ -59,6 +71,7 @@ export abstract class Reactive<Value, Equal = Value> {
59
71
  * @return Value as string
60
72
  */
61
73
  toString(): string {
74
+ // oxlint-disable-next-line @oscarpalmer/atoms/string.getString: base toString is expected; allow custom toString in options?
62
75
  return String(this.get());
63
76
  }
64
77
 
@@ -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 NAME_ALL: Set<string>;
15
+ export declare const NAMES: 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 Reactivity options
134
+ * @param options Optional reactivity options
135
135
  * @returns Reactive array
136
136
  */
137
137
  export declare function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item>;
@@ -10,8 +10,5 @@ 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
16
13
  */
17
14
  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 Reactivity options
23
+ * @param options Optional 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 Reactivity options
91
+ * @param options Optional 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>;