@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 +10 -0
- package/dist/helpers/value.mjs +2 -1
- package/dist/mora.full.mjs +44 -22
- package/dist/value/reactive.d.mts +11 -0
- package/dist/value/reactive.mjs +5 -0
- package/package.json +6 -5
- package/src/effect.ts +10 -0
- package/src/helpers/value.ts +2 -1
- package/src/value/reactive.ts +13 -0
- package/types/constants.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/types/value/array.d.ts +1 -1
- package/types/value/computed.d.ts +0 -3
- package/types/value/signal.d.ts +1 -1
- package/types/value/store.d.ts +1 -1
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
|
}
|
package/dist/helpers/value.mjs
CHANGED
|
@@ -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 =
|
|
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
|
}
|
package/dist/mora.full.mjs
CHANGED
|
@@ -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 =
|
|
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
|
/**
|
package/dist/value/reactive.mjs
CHANGED
|
@@ -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.
|
|
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": "
|
|
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.
|
|
42
|
+
"@oscarpalmer/atoms": "^0.184"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@
|
|
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) {
|
package/src/helpers/value.ts
CHANGED
|
@@ -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 =
|
|
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) {
|
package/src/value/reactive.ts
CHANGED
|
@@ -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
|
|
package/types/constants.d.ts
CHANGED
|
@@ -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
|
|
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';
|
package/types/value/array.d.ts
CHANGED
|
@@ -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
|
|
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>;
|
package/types/value/signal.d.ts
CHANGED
|
@@ -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
|
|
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>;
|
package/types/value/store.d.ts
CHANGED
|
@@ -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
|
|
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>;
|