@oscarpalmer/mora 0.8.0 → 0.9.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/computed.cjs CHANGED
@@ -9,6 +9,9 @@ exports.activeComputed = void 0;
9
9
  class Computed {
10
10
  constructor(callback) {
11
11
  __publicField(this, "state");
12
+ Object.defineProperty(this, "$mora", {
13
+ value: "computed"
14
+ });
12
15
  this.state = {
13
16
  computeds: /* @__PURE__ */ new Set(),
14
17
  dirty: true,
package/dist/computed.js CHANGED
@@ -7,6 +7,9 @@ let activeComputed;
7
7
  class Computed {
8
8
  constructor(callback) {
9
9
  __publicField(this, "state");
10
+ Object.defineProperty(this, "$mora", {
11
+ value: "computed"
12
+ });
10
13
  this.state = {
11
14
  computeds: /* @__PURE__ */ new Set(),
12
15
  dirty: true,
package/dist/effect.cjs CHANGED
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  class Effect {
4
4
  constructor(callback) {
5
+ Object.defineProperty(this, "$mora", {
6
+ value: "effect"
7
+ });
5
8
  this.state = {
6
9
  callback
7
10
  };
package/dist/effect.js CHANGED
@@ -1,5 +1,8 @@
1
1
  class Effect {
2
2
  constructor(callback) {
3
+ Object.defineProperty(this, "$mora", {
4
+ value: "effect"
5
+ });
3
6
  this.state = {
4
7
  callback
5
8
  };
package/dist/index.cjs CHANGED
@@ -3,9 +3,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const batch = require("./batch.cjs");
4
4
  const computed = require("./computed.cjs");
5
5
  const effect = require("./effect.cjs");
6
+ const is = require("./is.cjs");
6
7
  const signal = require("./signal.cjs");
7
8
  exports.startBatch = batch.startBatch;
8
9
  exports.stopBatch = batch.stopBatch;
9
10
  exports.computed = computed.computed;
10
11
  exports.effect = effect.effect;
12
+ exports.isComputed = is.isComputed;
13
+ exports.isEffect = is.isEffect;
14
+ exports.isSignal = is.isSignal;
11
15
  exports.signal = signal.signal;
package/dist/index.js CHANGED
@@ -1,10 +1,14 @@
1
1
  import { startBatch, stopBatch } from "./batch.js";
2
2
  import { computed } from "./computed.js";
3
3
  import { effect } from "./effect.js";
4
+ import { isComputed, isEffect, isSignal } from "./is.js";
4
5
  import { signal } from "./signal.js";
5
6
  export {
6
7
  computed,
7
8
  effect,
9
+ isComputed,
10
+ isEffect,
11
+ isSignal,
8
12
  signal,
9
13
  startBatch,
10
14
  stopBatch
package/dist/is.cjs ADDED
@@ -0,0 +1,17 @@
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 isSignal(value) {
13
+ return isMora(value, "signal");
14
+ }
15
+ exports.isComputed = isComputed;
16
+ exports.isEffect = isEffect;
17
+ exports.isSignal = isSignal;
package/dist/is.js ADDED
@@ -0,0 +1,17 @@
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 isSignal(value) {
11
+ return isMora(value, "signal");
12
+ }
13
+ export {
14
+ isComputed,
15
+ isEffect,
16
+ isSignal
17
+ };
package/dist/mora.full.js CHANGED
@@ -1,5 +1,8 @@
1
1
  class Effect {
2
2
  constructor(callback) {
3
+ Object.defineProperty(this, '$mora', {
4
+ value: 'effect',
5
+ });
3
6
  this.state = {
4
7
  callback,
5
8
  };
@@ -55,6 +58,9 @@ let activeComputed;
55
58
  class Computed {
56
59
  state;
57
60
  constructor(callback) {
61
+ Object.defineProperty(this, '$mora', {
62
+ value: 'computed',
63
+ });
58
64
  this.state = {
59
65
  computeds: new Set(),
60
66
  dirty: true,
@@ -110,9 +116,37 @@ function computed(callback) {
110
116
  return new Computed(callback);
111
117
  }
112
118
 
119
+ /**
120
+ * Is the value a computed signal?
121
+ */
122
+ function isComputed(value) {
123
+ return isMora(value, 'computed');
124
+ }
125
+ /**
126
+ * Is the value an effect?
127
+ */
128
+ function isEffect(value) {
129
+ return isMora(value, 'effect');
130
+ }
131
+ function isMora(value, name) {
132
+ return (typeof value === 'object' &&
133
+ value != null &&
134
+ '$mora' in value &&
135
+ value.$mora === name);
136
+ }
137
+ /**
138
+ * Is the value a signal?
139
+ */
140
+ function isSignal(value) {
141
+ return isMora(value, 'signal');
142
+ }
143
+
113
144
  class Signal {
114
145
  state;
115
146
  constructor(value) {
147
+ Object.defineProperty(this, '$mora', {
148
+ value: 'signal',
149
+ });
116
150
  this.state = {
117
151
  value,
118
152
  computeds: new Set(),
@@ -166,4 +200,4 @@ function signal(value) {
166
200
  return new Signal(value);
167
201
  }
168
202
 
169
- export { computed, effect, signal, startBatch, stopBatch };
203
+ export { computed, effect, isComputed, isEffect, isSignal, signal, startBatch, stopBatch };
package/dist/signal.cjs CHANGED
@@ -9,6 +9,9 @@ const effect = require("./effect.cjs");
9
9
  class Signal {
10
10
  constructor(value) {
11
11
  __publicField(this, "state");
12
+ Object.defineProperty(this, "$mora", {
13
+ value: "signal"
14
+ });
12
15
  this.state = {
13
16
  value,
14
17
  computeds: /* @__PURE__ */ new Set(),
package/dist/signal.js CHANGED
@@ -7,6 +7,9 @@ import { activeEffect, dirtyEffects } from "./effect.js";
7
7
  class Signal {
8
8
  constructor(value) {
9
9
  __publicField(this, "state");
10
+ Object.defineProperty(this, "$mora", {
11
+ value: "signal"
12
+ });
10
13
  this.state = {
11
14
  value,
12
15
  computeds: /* @__PURE__ */ new Set(),
package/package.json CHANGED
@@ -3,10 +3,12 @@
3
3
  "name": "Oscar Palmér",
4
4
  "url": "https://oscarpalmer.se"
5
5
  },
6
+ "dependencies": {
7
+ "@oscarpalmer/atoms": "^0.100"
8
+ },
6
9
  "description": "Signals and stuff…",
7
10
  "devDependencies": {
8
11
  "@biomejs/biome": "^1.9",
9
- "@oscarpalmer/atoms": "^0.100",
10
12
  "@rollup/plugin-node-resolve": "^16",
11
13
  "@rollup/plugin-typescript": "^12.1",
12
14
  "@types/node": "^22.15",
@@ -52,5 +54,5 @@
52
54
  },
53
55
  "type": "module",
54
56
  "types": "./types/index.d.ts",
55
- "version": "0.8.0"
57
+ "version": "0.9.0"
56
58
  }
package/src/computed.ts CHANGED
@@ -22,70 +22,76 @@ export type InternalComputed = {
22
22
  export let activeComputed: Computed<unknown> | undefined;
23
23
 
24
24
  export class Computed<Value> {
25
- private readonly state: ComputedState<Value>;
25
+ private declare readonly $mora: string;
26
26
 
27
- constructor(callback: () => Value) {
28
- this.state = {
29
- computeds: new Set(),
30
- dirty: true,
31
- effect: undefined as never,
32
- effects: new Set(),
33
- value: undefined as never,
34
- };
27
+ private readonly state: ComputedState<Value>;
35
28
 
36
- this.state.effect = effect(() => {
37
- if (this.state.dirty) {
38
- const previousComputed = activeComputed;
29
+ constructor(callback: () => Value) {
30
+ Object.defineProperty(this, '$mora', {
31
+ value: 'computed',
32
+ });
39
33
 
40
- activeComputed = this;
34
+ this.state = {
35
+ computeds: new Set(),
36
+ dirty: true,
37
+ effect: undefined as never,
38
+ effects: new Set(),
39
+ value: undefined as never,
40
+ };
41
41
 
42
- const value = callback();
42
+ this.state.effect = effect(() => {
43
+ if (this.state.dirty) {
44
+ const previousComputed = activeComputed;
43
45
 
44
- activeComputed = previousComputed;
46
+ activeComputed = this;
45
47
 
46
- if (!Object.is(this.state.value, value)) {
47
- this.state.value = value;
48
+ const value = callback();
48
49
 
49
- for (const computed of this.state.computeds) {
50
- computed.state.dirty = true;
51
- }
50
+ activeComputed = previousComputed;
51
+
52
+ if (!Object.is(this.state.value, value)) {
53
+ this.state.value = value;
52
54
 
53
- for (const effect of this.state.effects) {
54
- dirtyEffects.add(effect);
55
+ for (const computed of this.state.computeds) {
56
+ computed.state.dirty = true;
57
+ }
58
+
59
+ for (const effect of this.state.effects) {
60
+ dirtyEffects.add(effect);
61
+ }
55
62
  }
63
+
64
+ this.state.dirty = false;
56
65
  }
66
+ });
67
+ }
57
68
 
58
- this.state.dirty = false;
69
+ /**
70
+ * Get the value
71
+ */
72
+ get(): Value {
73
+ if (activeComputed != null && activeComputed !== this) {
74
+ this.state.computeds.add(activeComputed);
59
75
  }
60
- });
61
- }
62
76
 
63
- /**
64
- * Get the value
65
- */
66
- get(): Value {
67
- if (activeComputed != null && activeComputed !== this) {
68
- this.state.computeds.add(activeComputed);
69
- }
77
+ if (activeEffect != null && activeEffect !== this.state.effect) {
78
+ this.state.effects.add(activeEffect);
79
+ }
70
80
 
71
- if (activeEffect != null && activeEffect !== this.state.effect) {
72
- this.state.effects.add(activeEffect);
73
- }
81
+ if (this.state.dirty && batchDepth === 0) {
82
+ runEffect(this.state.effect);
83
+ }
74
84
 
75
- if (this.state.dirty && batchDepth === 0) {
76
- runEffect(this.state.effect);
85
+ return this.state.value;
77
86
  }
78
87
 
79
- return this.state.value;
80
- }
81
-
82
- /**
83
- * Get the value _(without reactivity)_
84
- */
85
- peek(): Value {
86
- return this.state.value;
88
+ /**
89
+ * Get the value _(without reactivity)_
90
+ */
91
+ peek(): Value {
92
+ return this.state.value;
93
+ }
87
94
  }
88
- }
89
95
 
90
96
  /**
91
97
  * Create a computed value
package/src/effect.ts CHANGED
@@ -9,16 +9,22 @@ type InternalEffect = {
9
9
  };
10
10
 
11
11
  export class Effect {
12
- private declare readonly state: EffectState;
12
+ private declare readonly $mora: string;
13
13
 
14
- constructor(callback: GenericCallback) {
15
- this.state = {
16
- callback,
17
- };
14
+ private declare readonly state: EffectState;
18
15
 
19
- runEffect(this);
16
+ constructor(callback: GenericCallback) {
17
+ Object.defineProperty(this, '$mora', {
18
+ value: 'effect',
19
+ });
20
+
21
+ this.state = {
22
+ callback,
23
+ };
24
+
25
+ runEffect(this);
26
+ }
20
27
  }
21
- }
22
28
 
23
29
  export function runEffect(effect: Effect): void {
24
30
  const previousEffect = activeEffect;
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export {startBatch, stopBatch} from './batch';
2
2
  export {computed, type Computed} from './computed';
3
3
  export {effect, type Effect} from './effect';
4
+ export {isComputed, isEffect, isSignal} from './is';
4
5
  export {signal, type Signal} from './signal';
package/src/is.ts ADDED
@@ -0,0 +1,34 @@
1
+ import type {PlainObject} from '@oscarpalmer/atoms/models';
2
+ import type {Computed} from './computed';
3
+ import type {Effect} from './effect';
4
+ import type {Signal} from './signal';
5
+
6
+ /**
7
+ * Is the value a computed signal?
8
+ */
9
+ export function isComputed(value: unknown): value is Computed<unknown> {
10
+ return isMora<Computed<unknown>>(value, 'computed');
11
+ }
12
+
13
+ /**
14
+ * Is the value an effect?
15
+ */
16
+ export function isEffect(value: unknown): value is Effect {
17
+ return isMora<Effect>(value, 'effect');
18
+ }
19
+
20
+ function isMora<T>(value: unknown, name: string): value is T {
21
+ return (
22
+ typeof value === 'object' &&
23
+ value != null &&
24
+ '$mora' in value &&
25
+ (value as PlainObject).$mora === name
26
+ );
27
+ }
28
+
29
+ /**
30
+ * Is the value a signal?
31
+ */
32
+ export function isSignal(value: unknown): value is Signal<unknown> {
33
+ return isMora<Signal<unknown>>(value, 'signal');
34
+ }
package/src/signal.ts CHANGED
@@ -9,68 +9,74 @@ type SignalState<Value> = {
9
9
  };
10
10
 
11
11
  export class Signal<Value> {
12
- private readonly state: SignalState<Value>;
13
-
14
- constructor(value: Value) {
15
- this.state = {
16
- value,
17
- computeds: new Set(),
18
- effects: new Set(),
19
- };
20
- }
12
+ private declare readonly $mora: string;
21
13
 
22
- /**
23
- * Get the value
24
- */
25
- get(): Value {
26
- if (activeComputed != null) {
27
- this.state.computeds.add(activeComputed);
28
- }
14
+ private readonly state: SignalState<Value>;
29
15
 
30
- if (activeEffect != null) {
31
- this.state.effects.add(activeEffect);
16
+ constructor(value: Value) {
17
+ Object.defineProperty(this, '$mora', {
18
+ value: 'signal',
19
+ });
20
+
21
+ this.state = {
22
+ value,
23
+ computeds: new Set(),
24
+ effects: new Set(),
25
+ };
32
26
  }
33
27
 
34
- return this.state.value;
35
- }
28
+ /**
29
+ * Get the value
30
+ */
31
+ get(): Value {
32
+ if (activeComputed != null) {
33
+ this.state.computeds.add(activeComputed);
34
+ }
36
35
 
37
- /**
38
- * Get the value _(without reactivity)_
39
- */
40
- peek(): Value {
41
- return this.state.value;
42
- }
36
+ if (activeEffect != null) {
37
+ this.state.effects.add(activeEffect);
38
+ }
43
39
 
44
- /**
45
- * Set the value
46
- */
47
- set(value: Value): void {
48
- if (Object.is(this.state.value, value)) {
49
- return;
40
+ return this.state.value;
50
41
  }
51
42
 
52
- this.state.value = value;
53
-
54
- for (const computed of this.state.computeds) {
55
- (computed as unknown as InternalComputed).state.dirty = true;
43
+ /**
44
+ * Get the value _(without reactivity)_
45
+ */
46
+ peek(): Value {
47
+ return this.state.value;
56
48
  }
57
49
 
58
- for (const effect of this.state.effects) {
59
- dirtyEffects.add(effect);
60
- }
50
+ /**
51
+ * Set the value
52
+ */
53
+ set(value: Value): void {
54
+ if (Object.is(this.state.value, value)) {
55
+ return;
56
+ }
61
57
 
62
- if (batchDepth === 0) {
63
- flushEffects();
58
+ this.state.value = value;
59
+
60
+ for (const computed of this.state.computeds) {
61
+ (computed as unknown as InternalComputed).state.dirty = true;
62
+ }
63
+
64
+ for (const effect of this.state.effects) {
65
+ dirtyEffects.add(effect);
66
+ }
67
+
68
+ if (batchDepth === 0) {
69
+ flushEffects();
70
+ }
64
71
  }
65
- }
66
72
 
67
- /**
68
- * Update the value
69
- */
70
- update(callback: (value: Value) => Value): void {
71
- this.set(callback(this.state.value));
73
+ /**
74
+ * Update the value
75
+ */
76
+ update(callback: (value: Value) => Value): void {
77
+ this.set(callback(this.state.value));
78
+ }
72
79
  }
73
- }
74
80
 
75
81
  export function signal<Value>(value: Value): Signal<Value> {
76
82
  return new Signal(value);
@@ -2,6 +2,7 @@
2
2
 
3
3
  export type GenericCallback = (...args: any[]) => any;
4
4
  declare class Effect {
5
+ private readonly $mora;
5
6
  private readonly state;
6
7
  constructor(callback: GenericCallback);
7
8
  }
@@ -17,6 +18,7 @@ export type InternalComputed = {
17
18
  };
18
19
  export declare let activeComputed: Computed<unknown> | undefined;
19
20
  export declare class Computed<Value> {
21
+ private readonly $mora;
20
22
  private readonly state;
21
23
  constructor(callback: () => Value);
22
24
  /**
@@ -11,6 +11,7 @@ export type InternalComputed = {
11
11
  };
12
12
  export declare let activeComputed: Computed<unknown> | undefined;
13
13
  export declare class Computed<Value> {
14
+ private readonly $mora;
14
15
  private readonly state;
15
16
  constructor(callback: () => Value);
16
17
  /**
@@ -2,6 +2,7 @@
2
2
 
3
3
  export type GenericCallback = (...args: any[]) => any;
4
4
  export declare class Effect {
5
+ private readonly $mora;
5
6
  private readonly state;
6
7
  constructor(callback: GenericCallback);
7
8
  }
package/types/effect.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { GenericCallback } from '@oscarpalmer/atoms/models';
2
2
  export declare class Effect {
3
+ private readonly $mora;
3
4
  private readonly state;
4
5
  constructor(callback: GenericCallback);
5
6
  }
package/types/index.d.cts CHANGED
@@ -1,6 +1,7 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
3
  export declare class Signal<Value> {
4
+ private readonly $mora;
4
5
  private readonly state;
5
6
  constructor(value: Value);
6
7
  /**
@@ -21,16 +22,9 @@ export declare class Signal<Value> {
21
22
  update(callback: (value: Value) => Value): void;
22
23
  }
23
24
  export declare function signal<Value>(value: Value): Signal<Value>;
24
- /**
25
- * Start batching effects _(use `stopBatch` to flush and run batched effects)_
26
- */
27
- export declare function startBatch(): void;
28
- /**
29
- * Stop batching effects and flush _(run)_ them
30
- */
31
- export declare function stopBatch(): void;
32
25
  export type GenericCallback = (...args: any[]) => any;
33
26
  export declare class Effect {
27
+ private readonly $mora;
34
28
  private readonly state;
35
29
  constructor(callback: GenericCallback);
36
30
  }
@@ -39,6 +33,7 @@ export declare class Effect {
39
33
  */
40
34
  export declare function effect(callback: GenericCallback): Effect;
41
35
  export declare class Computed<Value> {
36
+ private readonly $mora;
42
37
  private readonly state;
43
38
  constructor(callback: () => Value);
44
39
  /**
@@ -54,5 +49,25 @@ export declare class Computed<Value> {
54
49
  * Create a computed value
55
50
  */
56
51
  export declare function computed<Value>(callback: () => Value): Computed<Value>;
52
+ /**
53
+ * Is the value a computed signal?
54
+ */
55
+ export declare function isComputed(value: unknown): value is Computed<unknown>;
56
+ /**
57
+ * Is the value an effect?
58
+ */
59
+ export declare function isEffect(value: unknown): value is Effect;
60
+ /**
61
+ * Is the value a signal?
62
+ */
63
+ export declare function isSignal(value: unknown): value is Signal<unknown>;
64
+ /**
65
+ * Start batching effects _(use `stopBatch` to flush and run batched effects)_
66
+ */
67
+ export declare function startBatch(): void;
68
+ /**
69
+ * Stop batching effects and flush _(run)_ them
70
+ */
71
+ export declare function stopBatch(): void;
57
72
 
58
73
  export {};
package/types/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { startBatch, stopBatch } from './batch';
2
2
  export { computed, type Computed } from './computed';
3
3
  export { effect, type Effect } from './effect';
4
+ export { isComputed, isEffect, isSignal } from './is';
4
5
  export { signal, type Signal } from './signal';
package/types/is.d.cts ADDED
@@ -0,0 +1,56 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ declare class Signal<Value> {
4
+ private readonly $mora;
5
+ private readonly state;
6
+ constructor(value: Value);
7
+ /**
8
+ * Get the value
9
+ */
10
+ get(): Value;
11
+ /**
12
+ * Get the value _(without reactivity)_
13
+ */
14
+ peek(): Value;
15
+ /**
16
+ * Set the value
17
+ */
18
+ set(value: Value): void;
19
+ /**
20
+ * Update the value
21
+ */
22
+ update(callback: (value: Value) => Value): void;
23
+ }
24
+ export type GenericCallback = (...args: any[]) => any;
25
+ declare class Effect {
26
+ private readonly $mora;
27
+ private readonly state;
28
+ constructor(callback: GenericCallback);
29
+ }
30
+ declare class Computed<Value> {
31
+ private readonly $mora;
32
+ private readonly state;
33
+ constructor(callback: () => Value);
34
+ /**
35
+ * Get the value
36
+ */
37
+ get(): Value;
38
+ /**
39
+ * Get the value _(without reactivity)_
40
+ */
41
+ peek(): Value;
42
+ }
43
+ /**
44
+ * Is the value a computed signal?
45
+ */
46
+ export declare function isComputed(value: unknown): value is Computed<unknown>;
47
+ /**
48
+ * Is the value an effect?
49
+ */
50
+ export declare function isEffect(value: unknown): value is Effect;
51
+ /**
52
+ * Is the value a signal?
53
+ */
54
+ export declare function isSignal(value: unknown): value is Signal<unknown>;
55
+
56
+ export {};
package/types/is.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import type { Computed } from './computed';
2
+ import type { Effect } from './effect';
3
+ import type { Signal } from './signal';
4
+ /**
5
+ * Is the value a computed signal?
6
+ */
7
+ export declare function isComputed(value: unknown): value is Computed<unknown>;
8
+ /**
9
+ * Is the value an effect?
10
+ */
11
+ export declare function isEffect(value: unknown): value is Effect;
12
+ /**
13
+ * Is the value a signal?
14
+ */
15
+ export declare function isSignal(value: unknown): value is Signal<unknown>;
@@ -1,6 +1,7 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
3
  export declare class Signal<Value> {
4
+ private readonly $mora;
4
5
  private readonly state;
5
6
  constructor(value: Value);
6
7
  /**
package/types/signal.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export declare class Signal<Value> {
2
+ private readonly $mora;
2
3
  private readonly state;
3
4
  constructor(value: Value);
4
5
  /**