@oscarpalmer/mora 0.3.0 → 0.5.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/batch.cjs ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const effect = require("./effect.cjs");
4
+ function flushEffects() {
5
+ while (effect.dirtyEffects.size > 0) {
6
+ const effects = [...effect.dirtyEffects];
7
+ effect.dirtyEffects.clear();
8
+ for (const effect$1 of effects) {
9
+ effect.runEffect(effect$1);
10
+ }
11
+ }
12
+ }
13
+ function startBatch() {
14
+ exports.batchDepth += 1;
15
+ }
16
+ function stopBatch() {
17
+ if (exports.batchDepth > 0) {
18
+ exports.batchDepth -= 1;
19
+ }
20
+ if (exports.batchDepth === 0) {
21
+ flushEffects();
22
+ }
23
+ }
24
+ exports.batchDepth = 0;
25
+ exports.flushEffects = flushEffects;
26
+ exports.startBatch = startBatch;
27
+ exports.stopBatch = stopBatch;
package/dist/batch.js ADDED
@@ -0,0 +1,28 @@
1
+ import { dirtyEffects, runEffect } from "./effect.js";
2
+ function flushEffects() {
3
+ while (dirtyEffects.size > 0) {
4
+ const effects = [...dirtyEffects];
5
+ dirtyEffects.clear();
6
+ for (const effect of effects) {
7
+ runEffect(effect);
8
+ }
9
+ }
10
+ }
11
+ function startBatch() {
12
+ batchDepth += 1;
13
+ }
14
+ function stopBatch() {
15
+ if (batchDepth > 0) {
16
+ batchDepth -= 1;
17
+ }
18
+ if (batchDepth === 0) {
19
+ flushEffects();
20
+ }
21
+ }
22
+ let batchDepth = 0;
23
+ export {
24
+ batchDepth,
25
+ flushEffects,
26
+ startBatch,
27
+ stopBatch
28
+ };
package/dist/computed.cjs CHANGED
@@ -4,28 +4,51 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
6
6
  const effect = require("./effect.cjs");
7
- class Computed extends effect.Effect {
7
+ exports.activeComputed = void 0;
8
+ class Computed {
8
9
  constructor(callback) {
9
- super();
10
- __publicField(this, "dirty", true);
11
- __publicField(this, "effects", /* @__PURE__ */ new Set());
12
- __publicField(this, "value");
13
- this.callback = () => {
14
- if (this.dirty) {
15
- this.value = callback();
16
- this.dirty = false;
17
- }
10
+ __publicField(this, "state");
11
+ this.state = {
12
+ computeds: /* @__PURE__ */ new Set(),
13
+ dirty: true,
14
+ effect: void 0,
15
+ effects: /* @__PURE__ */ new Set(),
16
+ value: void 0
18
17
  };
19
- effect.runEffect(this);
18
+ this.state.effect = effect.effect(() => {
19
+ if (this.state.dirty) {
20
+ const previousComputed = exports.activeComputed;
21
+ exports.activeComputed = this;
22
+ const value = callback();
23
+ exports.activeComputed = previousComputed;
24
+ if (!Object.is(this.state.value, value)) {
25
+ this.state.value = value;
26
+ for (const comp of this.state.computeds) {
27
+ comp.state.dirty = true;
28
+ effect.dirtyEffects.add(comp.state.effect);
29
+ }
30
+ for (const effect2 of this.state.effects) {
31
+ effect.dirtyEffects.add(effect2);
32
+ }
33
+ }
34
+ this.state.dirty = false;
35
+ }
36
+ });
20
37
  }
38
+ /**
39
+ * Get the value
40
+ */
21
41
  get() {
22
- if (effect.activeEffect != null && effect.activeEffect !== this) {
23
- this.effects.add(effect.activeEffect);
42
+ if (exports.activeComputed != null && exports.activeComputed !== this) {
43
+ this.state.computeds.add(exports.activeComputed);
44
+ }
45
+ if (effect.activeEffect != null && effect.activeEffect !== this.state.effect) {
46
+ this.state.effects.add(effect.activeEffect);
24
47
  }
25
- if (this.dirty) {
26
- effect.runEffect(this);
48
+ if (this.state.dirty) {
49
+ effect.runEffect(this.state.effect);
27
50
  }
28
- return this.value;
51
+ return this.state.value;
29
52
  }
30
53
  }
31
54
  function computed(callback) {
package/dist/computed.js CHANGED
@@ -1,29 +1,52 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { Effect, runEffect, activeEffect } from "./effect.js";
5
- class Computed extends Effect {
4
+ import { effect, dirtyEffects, activeEffect, runEffect } from "./effect.js";
5
+ let activeComputed;
6
+ class Computed {
6
7
  constructor(callback) {
7
- super();
8
- __publicField(this, "dirty", true);
9
- __publicField(this, "effects", /* @__PURE__ */ new Set());
10
- __publicField(this, "value");
11
- this.callback = () => {
12
- if (this.dirty) {
13
- this.value = callback();
14
- this.dirty = false;
15
- }
8
+ __publicField(this, "state");
9
+ this.state = {
10
+ computeds: /* @__PURE__ */ new Set(),
11
+ dirty: true,
12
+ effect: void 0,
13
+ effects: /* @__PURE__ */ new Set(),
14
+ value: void 0
16
15
  };
17
- runEffect(this);
16
+ this.state.effect = effect(() => {
17
+ if (this.state.dirty) {
18
+ const previousComputed = activeComputed;
19
+ activeComputed = this;
20
+ const value = callback();
21
+ activeComputed = previousComputed;
22
+ if (!Object.is(this.state.value, value)) {
23
+ this.state.value = value;
24
+ for (const comp of this.state.computeds) {
25
+ comp.state.dirty = true;
26
+ dirtyEffects.add(comp.state.effect);
27
+ }
28
+ for (const effect2 of this.state.effects) {
29
+ dirtyEffects.add(effect2);
30
+ }
31
+ }
32
+ this.state.dirty = false;
33
+ }
34
+ });
18
35
  }
36
+ /**
37
+ * Get the value
38
+ */
19
39
  get() {
20
- if (activeEffect != null && activeEffect !== this) {
21
- this.effects.add(activeEffect);
40
+ if (activeComputed != null && activeComputed !== this) {
41
+ this.state.computeds.add(activeComputed);
42
+ }
43
+ if (activeEffect != null && activeEffect !== this.state.effect) {
44
+ this.state.effects.add(activeEffect);
22
45
  }
23
- if (this.dirty) {
24
- runEffect(this);
46
+ if (this.state.dirty) {
47
+ runEffect(this.state.effect);
25
48
  }
26
- return this.value;
49
+ return this.state.value;
27
50
  }
28
51
  }
29
52
  function computed(callback) {
@@ -31,5 +54,6 @@ function computed(callback) {
31
54
  }
32
55
  export {
33
56
  Computed,
57
+ activeComputed,
34
58
  computed
35
59
  };
package/dist/effect.cjs CHANGED
@@ -3,32 +3,30 @@ var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
6
- exports.activeEffect = void 0;
7
6
  class Effect {
8
- constructor() {
9
- __publicField(this, "callback");
10
- __publicField(this, "signals", /* @__PURE__ */ new Set());
7
+ constructor(callback) {
8
+ __publicField(this, "state");
9
+ this.state = {
10
+ callback
11
+ };
12
+ runEffect(this);
11
13
  }
12
14
  }
13
15
  function runEffect(effect2) {
14
- for (const signal of effect2.signals) {
15
- signal.state.observers.delete(effect2);
16
- }
17
- effect2.signals.clear();
18
16
  const previousEffect = exports.activeEffect;
19
17
  exports.activeEffect = effect2;
20
18
  try {
21
- effect2.callback();
19
+ effect2.state.callback();
22
20
  } finally {
23
21
  exports.activeEffect = previousEffect;
24
22
  }
25
23
  }
26
24
  function effect(callback) {
27
- const instance = new Effect();
28
- instance.callback = callback;
29
- runEffect(instance);
30
- return instance;
25
+ return new Effect(callback);
31
26
  }
27
+ exports.activeEffect = void 0;
28
+ const dirtyEffects = /* @__PURE__ */ new Set();
32
29
  exports.Effect = Effect;
30
+ exports.dirtyEffects = dirtyEffects;
33
31
  exports.effect = effect;
34
32
  exports.runEffect = runEffect;
package/dist/effect.js CHANGED
@@ -1,35 +1,33 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- let activeEffect;
5
4
  class Effect {
6
- constructor() {
7
- __publicField(this, "callback");
8
- __publicField(this, "signals", /* @__PURE__ */ new Set());
5
+ constructor(callback) {
6
+ __publicField(this, "state");
7
+ this.state = {
8
+ callback
9
+ };
10
+ runEffect(this);
9
11
  }
10
12
  }
11
13
  function runEffect(effect2) {
12
- for (const signal of effect2.signals) {
13
- signal.state.observers.delete(effect2);
14
- }
15
- effect2.signals.clear();
16
14
  const previousEffect = activeEffect;
17
15
  activeEffect = effect2;
18
16
  try {
19
- effect2.callback();
17
+ effect2.state.callback();
20
18
  } finally {
21
19
  activeEffect = previousEffect;
22
20
  }
23
21
  }
24
22
  function effect(callback) {
25
- const instance = new Effect();
26
- instance.callback = callback;
27
- runEffect(instance);
28
- return instance;
23
+ return new Effect(callback);
29
24
  }
25
+ let activeEffect;
26
+ const dirtyEffects = /* @__PURE__ */ new Set();
30
27
  export {
31
28
  Effect,
32
29
  activeEffect,
30
+ dirtyEffects,
33
31
  effect,
34
32
  runEffect
35
33
  };
package/dist/index.cjs CHANGED
@@ -1,8 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const batch = require("./batch.cjs");
3
4
  const computed = require("./computed.cjs");
4
5
  const effect = require("./effect.cjs");
5
6
  const signal = require("./signal.cjs");
7
+ exports.startBatch = batch.startBatch;
8
+ exports.stopBatch = batch.stopBatch;
6
9
  exports.computed = computed.computed;
7
10
  exports.effect = effect.effect;
8
11
  exports.signal = signal.signal;
package/dist/index.js CHANGED
@@ -1,8 +1,11 @@
1
+ import { startBatch, stopBatch } from "./batch.js";
1
2
  import { computed } from "./computed.js";
2
3
  import { effect } from "./effect.js";
3
4
  import { signal } from "./signal.js";
4
5
  export {
5
6
  computed,
6
7
  effect,
7
- signal
8
+ signal,
9
+ startBatch,
10
+ stopBatch
8
11
  };
@@ -0,0 +1,162 @@
1
+ class Effect {
2
+ state;
3
+ constructor(callback) {
4
+ this.state = {
5
+ callback,
6
+ };
7
+ runEffect(this);
8
+ }
9
+ }
10
+ function runEffect(effect) {
11
+ const previousEffect = activeEffect;
12
+ activeEffect = effect;
13
+ try {
14
+ effect.state.callback();
15
+ }
16
+ finally {
17
+ activeEffect = previousEffect;
18
+ }
19
+ }
20
+ /**
21
+ * Create an effect
22
+ */
23
+ function effect(callback) {
24
+ return new Effect(callback);
25
+ }
26
+ let activeEffect;
27
+ const dirtyEffects = new Set();
28
+
29
+ function flushEffects() {
30
+ while (dirtyEffects.size > 0) {
31
+ const effects = [...dirtyEffects];
32
+ dirtyEffects.clear();
33
+ for (const effect of effects) {
34
+ runEffect(effect);
35
+ }
36
+ }
37
+ }
38
+ /**
39
+ * Start batching effects _(use `stopBatch` to flush and run batched effects)_
40
+ */
41
+ function startBatch() {
42
+ batchDepth += 1;
43
+ }
44
+ /**
45
+ * Stop batching effects and flush _(run)_ them
46
+ */
47
+ function stopBatch() {
48
+ if (batchDepth > 0) {
49
+ batchDepth -= 1;
50
+ }
51
+ if (batchDepth === 0) {
52
+ flushEffects();
53
+ }
54
+ }
55
+ let batchDepth = 0;
56
+
57
+ let activeComputed;
58
+ class Computed {
59
+ state;
60
+ constructor(callback) {
61
+ this.state = {
62
+ computeds: new Set(),
63
+ dirty: true,
64
+ effect: undefined,
65
+ effects: new Set(),
66
+ value: undefined,
67
+ };
68
+ this.state.effect = effect(() => {
69
+ if (this.state.dirty) {
70
+ const previousComputed = activeComputed;
71
+ activeComputed = this;
72
+ const value = callback();
73
+ activeComputed = previousComputed;
74
+ if (!Object.is(this.state.value, value)) {
75
+ this.state.value = value;
76
+ for (const comp of this.state.computeds) {
77
+ comp.state.dirty = true;
78
+ dirtyEffects.add(comp.state.effect);
79
+ }
80
+ for (const effect of this.state.effects) {
81
+ dirtyEffects.add(effect);
82
+ }
83
+ }
84
+ this.state.dirty = false;
85
+ }
86
+ });
87
+ }
88
+ /**
89
+ * Get the value
90
+ */
91
+ get() {
92
+ if (activeComputed != null && activeComputed !== this) {
93
+ this.state.computeds.add(activeComputed);
94
+ }
95
+ if (activeEffect != null && activeEffect !== this.state.effect) {
96
+ this.state.effects.add(activeEffect);
97
+ }
98
+ if (this.state.dirty) {
99
+ runEffect(this.state.effect);
100
+ }
101
+ return this.state.value;
102
+ }
103
+ }
104
+ /**
105
+ * Create a computed value
106
+ */
107
+ function computed(callback) {
108
+ return new Computed(callback);
109
+ }
110
+
111
+ class Signal {
112
+ state;
113
+ constructor(value) {
114
+ this.state = {
115
+ value,
116
+ computeds: new Set(),
117
+ effects: new Set(),
118
+ };
119
+ }
120
+ /**
121
+ * Get the value
122
+ */
123
+ get() {
124
+ if (activeComputed != null) {
125
+ this.state.computeds.add(activeComputed);
126
+ }
127
+ if (activeEffect != null) {
128
+ this.state.effects.add(activeEffect);
129
+ }
130
+ return this.state.value;
131
+ }
132
+ /**
133
+ * Set the value
134
+ */
135
+ set(value) {
136
+ if (Object.is(this.state.value, value)) {
137
+ return;
138
+ }
139
+ this.state.value = value;
140
+ for (const computed of this.state.computeds) {
141
+ computed.state.dirty = true;
142
+ dirtyEffects.add(computed.state.effect);
143
+ }
144
+ for (const effect of this.state.effects) {
145
+ dirtyEffects.add(effect);
146
+ }
147
+ if (batchDepth === 0) {
148
+ flushEffects();
149
+ }
150
+ }
151
+ /**
152
+ * Update the value
153
+ */
154
+ update(callback) {
155
+ this.set(callback(this.state.value));
156
+ }
157
+ }
158
+ function signal(value) {
159
+ return new Signal(value);
160
+ }
161
+
162
+ export { computed, effect, signal, startBatch, stopBatch };
package/dist/signal.cjs CHANGED
@@ -3,62 +3,52 @@ var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
6
+ const batch = require("./batch.cjs");
6
7
  const computed = require("./computed.cjs");
7
8
  const effect = require("./effect.cjs");
8
- const dirtyEffects = /* @__PURE__ */ new Set();
9
- let batchDepth = 0;
10
9
  class Signal {
11
10
  constructor(value) {
12
11
  __publicField(this, "state");
13
12
  this.state = {
14
13
  value,
15
- observers: /* @__PURE__ */ new Set()
14
+ computeds: /* @__PURE__ */ new Set(),
15
+ effects: /* @__PURE__ */ new Set()
16
16
  };
17
17
  }
18
+ /**
19
+ * Get the value
20
+ */
18
21
  get() {
22
+ if (computed.activeComputed != null) {
23
+ this.state.computeds.add(computed.activeComputed);
24
+ }
19
25
  if (effect.activeEffect != null) {
20
- this.state.observers.add(effect.activeEffect);
21
- effect.activeEffect.signals.add(this);
26
+ this.state.effects.add(effect.activeEffect);
22
27
  }
23
28
  return this.state.value;
24
29
  }
30
+ /**
31
+ * Set the value
32
+ */
25
33
  set(value) {
26
34
  if (Object.is(this.state.value, value)) {
27
35
  return;
28
36
  }
29
37
  this.state.value = value;
30
- const isOutermostBatch = batchDepth === 0;
31
- batchDepth += 1;
32
- try {
33
- for (const observer of this.state.observers) {
34
- if (observer instanceof computed.Computed) {
35
- observer.dirty = true;
36
- dirtyEffects.add(observer);
37
- for (const effect2 of observer.effects) {
38
- dirtyEffects.add(effect2);
39
- }
40
- } else {
41
- dirtyEffects.add(observer);
42
- }
43
- }
44
- if (isOutermostBatch) {
45
- queueMicrotask(() => {
46
- try {
47
- for (const effect$1 of dirtyEffects) {
48
- effect.runEffect(effect$1);
49
- }
50
- } finally {
51
- dirtyEffects.clear();
52
- batchDepth = 0;
53
- }
54
- });
55
- }
56
- } finally {
57
- if (isOutermostBatch) {
58
- batchDepth -= 1;
59
- }
38
+ for (const computed2 of this.state.computeds) {
39
+ computed2.state.dirty = true;
40
+ effect.dirtyEffects.add(computed2.state.effect);
41
+ }
42
+ for (const effect$1 of this.state.effects) {
43
+ effect.dirtyEffects.add(effect$1);
44
+ }
45
+ if (batch.batchDepth === 0) {
46
+ batch.flushEffects();
60
47
  }
61
48
  }
49
+ /**
50
+ * Update the value
51
+ */
62
52
  update(callback) {
63
53
  this.set(callback(this.state.value));
64
54
  }
package/dist/signal.js CHANGED
@@ -1,62 +1,52 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { Computed } from "./computed.js";
5
- import { activeEffect, runEffect } from "./effect.js";
6
- const dirtyEffects = /* @__PURE__ */ new Set();
7
- let batchDepth = 0;
4
+ import { flushEffects, batchDepth } from "./batch.js";
5
+ import { activeComputed } from "./computed.js";
6
+ import { activeEffect, dirtyEffects } from "./effect.js";
8
7
  class Signal {
9
8
  constructor(value) {
10
9
  __publicField(this, "state");
11
10
  this.state = {
12
11
  value,
13
- observers: /* @__PURE__ */ new Set()
12
+ computeds: /* @__PURE__ */ new Set(),
13
+ effects: /* @__PURE__ */ new Set()
14
14
  };
15
15
  }
16
+ /**
17
+ * Get the value
18
+ */
16
19
  get() {
20
+ if (activeComputed != null) {
21
+ this.state.computeds.add(activeComputed);
22
+ }
17
23
  if (activeEffect != null) {
18
- this.state.observers.add(activeEffect);
19
- activeEffect.signals.add(this);
24
+ this.state.effects.add(activeEffect);
20
25
  }
21
26
  return this.state.value;
22
27
  }
28
+ /**
29
+ * Set the value
30
+ */
23
31
  set(value) {
24
32
  if (Object.is(this.state.value, value)) {
25
33
  return;
26
34
  }
27
35
  this.state.value = value;
28
- const isOutermostBatch = batchDepth === 0;
29
- batchDepth += 1;
30
- try {
31
- for (const observer of this.state.observers) {
32
- if (observer instanceof Computed) {
33
- observer.dirty = true;
34
- dirtyEffects.add(observer);
35
- for (const effect of observer.effects) {
36
- dirtyEffects.add(effect);
37
- }
38
- } else {
39
- dirtyEffects.add(observer);
40
- }
41
- }
42
- if (isOutermostBatch) {
43
- queueMicrotask(() => {
44
- try {
45
- for (const effect of dirtyEffects) {
46
- runEffect(effect);
47
- }
48
- } finally {
49
- dirtyEffects.clear();
50
- batchDepth = 0;
51
- }
52
- });
53
- }
54
- } finally {
55
- if (isOutermostBatch) {
56
- batchDepth -= 1;
57
- }
36
+ for (const computed of this.state.computeds) {
37
+ computed.state.dirty = true;
38
+ dirtyEffects.add(computed.state.effect);
39
+ }
40
+ for (const effect of this.state.effects) {
41
+ dirtyEffects.add(effect);
42
+ }
43
+ if (batchDepth === 0) {
44
+ flushEffects();
58
45
  }
59
46
  }
47
+ /**
48
+ * Update the value
49
+ */
60
50
  update(callback) {
61
51
  this.set(callback(this.state.value));
62
52
  }