@oscarpalmer/mora 0.12.0 → 0.13.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/array.cjs ADDED
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ var __typeError = (msg) => {
3
+ throw TypeError(msg);
4
+ };
5
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
6
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
7
+ var __privateAdd = (obj, member, value2) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value2);
8
+ var _size;
9
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
10
+ const reactive = require("./reactive.cjs");
11
+ const signal = require("./signal.cjs");
12
+ const value = require("./value.cjs");
13
+ class ReactiveArray extends reactive.Reactive {
14
+ constructor(value2) {
15
+ super(
16
+ "array",
17
+ new Proxy(value2, {
18
+ get: (target, property) => updateMethods.has(property) ? updateArray(property, target, this.state, __privateGet(this, _size)) : Reflect.get(target, property),
19
+ set: (target, property, value22) => setValue(target, property, value22, this.state, __privateGet(this, _size))
20
+ })
21
+ );
22
+ __privateAdd(this, _size, signal.signal(0));
23
+ __privateGet(this, _size).set(value2.length);
24
+ }
25
+ /**
26
+ * The length of the array
27
+ */
28
+ get length() {
29
+ return __privateGet(this, _size).get();
30
+ }
31
+ /**
32
+ * Set the length of the array
33
+ */
34
+ set length(value2) {
35
+ if (typeof value2 === "number" && value2 >= 0 && value2 !== this.state.value.length) {
36
+ this.get().length = value2;
37
+ }
38
+ }
39
+ /**
40
+ * @inheritdoc
41
+ */
42
+ get() {
43
+ return value.getValue(this.state);
44
+ }
45
+ peek(length) {
46
+ return length === true ? __privateGet(this, _size).peek() : [...this.state.value];
47
+ }
48
+ set(first, second) {
49
+ if (Array.isArray(first)) {
50
+ this.state.value.splice(0, this.state.value.length, ...first);
51
+ } else if (first === "length") {
52
+ this.length = second;
53
+ } else if (typeof first === "number") {
54
+ this.state.value[first] = second;
55
+ }
56
+ }
57
+ }
58
+ _size = new WeakMap();
59
+ function array(value2) {
60
+ return new ReactiveArray(Array.isArray(value2) ? value2 : []);
61
+ }
62
+ function emit(first, second) {
63
+ let { length } = first;
64
+ if (length !== second.length) {
65
+ return true;
66
+ }
67
+ let offset = 0;
68
+ if (length >= 100) {
69
+ offset = Math.round(length / 10);
70
+ offset = offset > 25 ? 25 : offset;
71
+ for (let index = 0; index < offset; index += 1) {
72
+ if (!Object.is(first[index], second[index])) {
73
+ return true;
74
+ }
75
+ }
76
+ }
77
+ length -= offset;
78
+ for (let index = offset; index < length; index += 1) {
79
+ if (!Object.is(first[index], second[index])) {
80
+ return true;
81
+ }
82
+ }
83
+ return false;
84
+ }
85
+ function setValue(target, property, value$1, state, length) {
86
+ const isIndex = !Number.isNaN(Number(property));
87
+ const isLength = property === "length";
88
+ if (!isIndex && !isLength) {
89
+ return Reflect.set(target, property, value$1);
90
+ }
91
+ const previous = Reflect.get(target, property);
92
+ if (Object.is(previous, value$1)) {
93
+ return true;
94
+ }
95
+ Reflect.set(target, property, value$1);
96
+ value.emitValue(state);
97
+ length.set(target.length);
98
+ return true;
99
+ }
100
+ function updateArray(type, array2, state, length) {
101
+ const affectsLength = lengthAffectingMethods.has(type);
102
+ const previousArray = affectsLength ? [] : [...array2];
103
+ const previousLength = array2.length;
104
+ return (...args) => {
105
+ const result = array2[type](
106
+ ...args
107
+ );
108
+ if (affectsLength ? array2.length !== previousLength : emit(previousArray, array2)) {
109
+ value.emitValue(state);
110
+ length.set(array2.length);
111
+ }
112
+ return result;
113
+ };
114
+ }
115
+ const lengthAffectingMethods = /* @__PURE__ */ new Set([
116
+ "pop",
117
+ "push",
118
+ "shift",
119
+ "unshift"
120
+ ]);
121
+ const updateMethods = /* @__PURE__ */ new Set([
122
+ ...lengthAffectingMethods,
123
+ "copyWithin",
124
+ "fill",
125
+ "reverse",
126
+ "sort",
127
+ "splice"
128
+ ]);
129
+ exports.ReactiveArray = ReactiveArray;
130
+ exports.array = array;
package/dist/array.js ADDED
@@ -0,0 +1,130 @@
1
+ var __typeError = (msg) => {
2
+ throw TypeError(msg);
3
+ };
4
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
+ var _size;
8
+ import { Reactive } from "./reactive.js";
9
+ import { signal } from "./signal.js";
10
+ import { getValue, emitValue } from "./value.js";
11
+ class ReactiveArray extends Reactive {
12
+ constructor(value) {
13
+ super(
14
+ "array",
15
+ new Proxy(value, {
16
+ get: (target, property) => updateMethods.has(property) ? updateArray(property, target, this.state, __privateGet(this, _size)) : Reflect.get(target, property),
17
+ set: (target, property, value2) => setValue(target, property, value2, this.state, __privateGet(this, _size))
18
+ })
19
+ );
20
+ __privateAdd(this, _size, signal(0));
21
+ __privateGet(this, _size).set(value.length);
22
+ }
23
+ /**
24
+ * The length of the array
25
+ */
26
+ get length() {
27
+ return __privateGet(this, _size).get();
28
+ }
29
+ /**
30
+ * Set the length of the array
31
+ */
32
+ set length(value) {
33
+ if (typeof value === "number" && value >= 0 && value !== this.state.value.length) {
34
+ this.get().length = value;
35
+ }
36
+ }
37
+ /**
38
+ * @inheritdoc
39
+ */
40
+ get() {
41
+ return getValue(this.state);
42
+ }
43
+ peek(length) {
44
+ return length === true ? __privateGet(this, _size).peek() : [...this.state.value];
45
+ }
46
+ set(first, second) {
47
+ if (Array.isArray(first)) {
48
+ this.state.value.splice(0, this.state.value.length, ...first);
49
+ } else if (first === "length") {
50
+ this.length = second;
51
+ } else if (typeof first === "number") {
52
+ this.state.value[first] = second;
53
+ }
54
+ }
55
+ }
56
+ _size = new WeakMap();
57
+ function array(value) {
58
+ return new ReactiveArray(Array.isArray(value) ? value : []);
59
+ }
60
+ function emit(first, second) {
61
+ let { length } = first;
62
+ if (length !== second.length) {
63
+ return true;
64
+ }
65
+ let offset = 0;
66
+ if (length >= 100) {
67
+ offset = Math.round(length / 10);
68
+ offset = offset > 25 ? 25 : offset;
69
+ for (let index = 0; index < offset; index += 1) {
70
+ if (!Object.is(first[index], second[index])) {
71
+ return true;
72
+ }
73
+ }
74
+ }
75
+ length -= offset;
76
+ for (let index = offset; index < length; index += 1) {
77
+ if (!Object.is(first[index], second[index])) {
78
+ return true;
79
+ }
80
+ }
81
+ return false;
82
+ }
83
+ function setValue(target, property, value, state, length) {
84
+ const isIndex = !Number.isNaN(Number(property));
85
+ const isLength = property === "length";
86
+ if (!isIndex && !isLength) {
87
+ return Reflect.set(target, property, value);
88
+ }
89
+ const previous = Reflect.get(target, property);
90
+ if (Object.is(previous, value)) {
91
+ return true;
92
+ }
93
+ Reflect.set(target, property, value);
94
+ emitValue(state);
95
+ length.set(target.length);
96
+ return true;
97
+ }
98
+ function updateArray(type, array2, state, length) {
99
+ const affectsLength = lengthAffectingMethods.has(type);
100
+ const previousArray = affectsLength ? [] : [...array2];
101
+ const previousLength = array2.length;
102
+ return (...args) => {
103
+ const result = array2[type](
104
+ ...args
105
+ );
106
+ if (affectsLength ? array2.length !== previousLength : emit(previousArray, array2)) {
107
+ emitValue(state);
108
+ length.set(array2.length);
109
+ }
110
+ return result;
111
+ };
112
+ }
113
+ const lengthAffectingMethods = /* @__PURE__ */ new Set([
114
+ "pop",
115
+ "push",
116
+ "shift",
117
+ "unshift"
118
+ ]);
119
+ const updateMethods = /* @__PURE__ */ new Set([
120
+ ...lengthAffectingMethods,
121
+ "copyWithin",
122
+ "fill",
123
+ "reverse",
124
+ "sort",
125
+ "splice"
126
+ ]);
127
+ export {
128
+ ReactiveArray,
129
+ array
130
+ };
package/dist/index.cjs CHANGED
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const array = require("./array.cjs");
3
4
  const batch = require("./batch.cjs");
4
5
  const computed = require("./computed.cjs");
5
6
  const effect = require("./effect.cjs");
6
7
  const is = require("./is.cjs");
7
8
  const signal = require("./signal.cjs");
9
+ exports.array = array.array;
8
10
  exports.startBatch = batch.startBatch;
9
11
  exports.stopBatch = batch.stopBatch;
10
12
  exports.computed = computed.computed;
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
+ import { array } from "./array.js";
1
2
  import { startBatch, stopBatch } from "./batch.js";
2
3
  import { computed } from "./computed.js";
3
4
  import { effect } from "./effect.js";
4
5
  import { isComputed, isEffect, isReactive, isSignal } from "./is.js";
5
6
  import { signal } from "./signal.js";
6
7
  export {
8
+ array,
7
9
  computed,
8
10
  effect,
9
11
  isComputed,
package/dist/mora.full.js CHANGED
@@ -1,3 +1,76 @@
1
+ class Subscription {
2
+ state;
3
+ callback;
4
+ constructor(state, callback) {
5
+ this.state = state;
6
+ this.callback = callback;
7
+ callback(state.value);
8
+ }
9
+ }
10
+ function noop() { }
11
+ function subscribe(state, callback) {
12
+ if (typeof callback !== 'function' || state.subscriptions.has(callback)) {
13
+ return noop;
14
+ }
15
+ state.subscriptions.set(callback, new Subscription(state, callback));
16
+ return () => {
17
+ unsubscribe(state, callback);
18
+ };
19
+ }
20
+ function unsubscribe(state, callback) {
21
+ const subscription = state.subscriptions.get(callback);
22
+ state.subscriptions.delete(callback);
23
+ if (subscription != null) {
24
+ subscription.callback = noop;
25
+ subscription.state = undefined;
26
+ }
27
+ }
28
+
29
+ class Reactive {
30
+ state = {
31
+ computeds: new Set(),
32
+ effects: new Set(),
33
+ subscriptions: new Map(),
34
+ value: undefined,
35
+ };
36
+ constructor(name, value) {
37
+ this.state.value = value;
38
+ Object.defineProperty(this, '$mora', {
39
+ value: name,
40
+ });
41
+ }
42
+ /**
43
+ * Get the value _(without reactivity)_
44
+ */
45
+ peek() {
46
+ return this.state.value;
47
+ }
48
+ /**
49
+ * Subscribe to changes
50
+ */
51
+ subscribe(callback) {
52
+ return subscribe(this.state, callback);
53
+ }
54
+ /**
55
+ * JSON representation of the value
56
+ */
57
+ toJSON() {
58
+ return this.get();
59
+ }
60
+ /**
61
+ * String representation of the value
62
+ */
63
+ toString() {
64
+ return String(this.get());
65
+ }
66
+ /**
67
+ * Unsubscribe from changes
68
+ */
69
+ unsubscribe(callback) {
70
+ unsubscribe(this.state, callback);
71
+ }
72
+ }
73
+
1
74
  class Effect {
2
75
  constructor(callback) {
3
76
  Object.defineProperty(this, '$mora', {
@@ -87,67 +160,6 @@ function stopBatch() {
87
160
  const batchedHandlers = new Set();
88
161
  let batchDepth = 0;
89
162
 
90
- class Subscription {
91
- state;
92
- callback;
93
- constructor(state, callback) {
94
- this.state = state;
95
- this.callback = callback;
96
- callback(state.value);
97
- }
98
- }
99
- function noop() { }
100
- function subscribe(state, callback) {
101
- if (typeof callback !== 'function' || state.subscriptions.has(callback)) {
102
- return noop;
103
- }
104
- state.subscriptions.set(callback, new Subscription(state, callback));
105
- return () => {
106
- unsubscribe(state, callback);
107
- };
108
- }
109
- function unsubscribe(state, callback) {
110
- const subscription = state.subscriptions.get(callback);
111
- state.subscriptions.delete(callback);
112
- if (subscription != null) {
113
- subscription.callback = noop;
114
- subscription.state = undefined;
115
- }
116
- }
117
-
118
- class Reactive {
119
- state = {
120
- computeds: new Set(),
121
- effects: new Set(),
122
- subscriptions: new Map(),
123
- value: undefined,
124
- };
125
- constructor(name, value) {
126
- this.state.value = value;
127
- Object.defineProperty(this, '$mora', {
128
- value: name,
129
- });
130
- }
131
- /**
132
- * Get the value _(without reactivity)_
133
- */
134
- peek() {
135
- return this.state.value;
136
- }
137
- /**
138
- * Subscribe to changes
139
- */
140
- subscribe(callback) {
141
- return subscribe(this.state, callback);
142
- }
143
- /**
144
- * Unsubscribe from changes
145
- */
146
- unsubscribe(callback) {
147
- unsubscribe(this.state, callback);
148
- }
149
- }
150
-
151
163
  let activeComputed;
152
164
  class Computed extends Reactive {
153
165
  effect = {
@@ -201,6 +213,37 @@ function computed(callback) {
201
213
  return new Computed(callback);
202
214
  }
203
215
 
216
+ function emitValue(state) {
217
+ for (const computed of state.computeds) {
218
+ computed.effect.dirty = true;
219
+ }
220
+ for (const effect of state.effects) {
221
+ batchedHandlers.add(effect);
222
+ }
223
+ for (const [, subscription] of state.subscriptions) {
224
+ batchedHandlers.add(subscription);
225
+ }
226
+ if (batchDepth === 0) {
227
+ flushEffects();
228
+ }
229
+ }
230
+ function getValue(state) {
231
+ if (activeComputed != null) {
232
+ state.computeds.add(activeComputed);
233
+ }
234
+ if (activeEffect != null) {
235
+ state.effects.add(activeEffect);
236
+ }
237
+ return state.value;
238
+ }
239
+ function setValue$1(state, value) {
240
+ if (Object.is(state.value, value)) {
241
+ return;
242
+ }
243
+ state.value = value;
244
+ emitValue(state);
245
+ }
246
+
204
247
  class Signal extends Reactive {
205
248
  constructor(value) {
206
249
  super('signal', value);
@@ -209,34 +252,13 @@ class Signal extends Reactive {
209
252
  * @inheritdoc
210
253
  */
211
254
  get() {
212
- if (activeComputed != null) {
213
- this.state.computeds.add(activeComputed);
214
- }
215
- if (activeEffect != null) {
216
- this.state.effects.add(activeEffect);
217
- }
218
- return this.state.value;
255
+ return getValue(this.state);
219
256
  }
220
257
  /**
221
258
  * Set the value
222
259
  */
223
260
  set(value) {
224
- if (Object.is(this.state.value, value)) {
225
- return;
226
- }
227
- this.state.value = value;
228
- for (const computed of this.state.computeds) {
229
- computed.effect.dirty = true;
230
- }
231
- for (const effect of this.state.effects) {
232
- batchedHandlers.add(effect);
233
- }
234
- for (const [, subscription] of this.state.subscriptions) {
235
- batchedHandlers.add(subscription);
236
- }
237
- if (batchDepth === 0) {
238
- flushEffects();
239
- }
261
+ setValue$1(this.state, value);
240
262
  }
241
263
  /**
242
264
  * Update the value
@@ -245,8 +267,133 @@ class Signal extends Reactive {
245
267
  this.set(callback(this.state.value));
246
268
  }
247
269
  }
270
+ /**
271
+ * Create a reactive value
272
+ */
248
273
  function signal(value) {
249
274
  return new Signal(value);
250
275
  }
251
276
 
252
- export { computed, effect, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch };
277
+ class ReactiveArray extends Reactive {
278
+ #size = signal(0);
279
+ /**
280
+ * The length of the array
281
+ */
282
+ get length() {
283
+ return this.#size.get();
284
+ }
285
+ /**
286
+ * Set the length of the array
287
+ */
288
+ set length(value) {
289
+ if (typeof value === 'number' &&
290
+ value >= 0 &&
291
+ value !== this.state.value.length) {
292
+ this.get().length = value;
293
+ }
294
+ }
295
+ constructor(value) {
296
+ super('array', new Proxy(value, {
297
+ get: (target, property) => updateMethods.has(property)
298
+ ? updateArray(property, target, this.state, this.#size)
299
+ : Reflect.get(target, property),
300
+ set: (target, property, value) => setValue(target, property, value, this.state, this.#size),
301
+ }));
302
+ this.#size.set(value.length);
303
+ }
304
+ /**
305
+ * @inheritdoc
306
+ */
307
+ get() {
308
+ return getValue(this.state);
309
+ }
310
+ peek(length) {
311
+ return length === true ? this.#size.peek() : [...this.state.value];
312
+ }
313
+ set(first, second) {
314
+ if (Array.isArray(first)) {
315
+ this.state.value.splice(0, this.state.value.length, ...first);
316
+ }
317
+ else if (first === 'length') {
318
+ this.length = second;
319
+ }
320
+ else if (typeof first === 'number') {
321
+ this.state.value[first] = second;
322
+ }
323
+ }
324
+ }
325
+ /**
326
+ * Create a reactive array
327
+ */
328
+ function array(value) {
329
+ return new ReactiveArray(Array.isArray(value) ? value : []);
330
+ }
331
+ function emit(first, second) {
332
+ let { length } = first;
333
+ if (length !== second.length) {
334
+ return true;
335
+ }
336
+ let offset = 0;
337
+ if (length >= 100) {
338
+ offset = Math.round(length / 10);
339
+ offset = offset > 25 ? 25 : offset;
340
+ for (let index = 0; index < offset; index += 1) {
341
+ if (!Object.is(first[index], second[index])) {
342
+ return true;
343
+ }
344
+ }
345
+ }
346
+ length -= offset;
347
+ for (let index = offset; index < length; index += 1) {
348
+ if (!Object.is(first[index], second[index])) {
349
+ return true;
350
+ }
351
+ }
352
+ return false;
353
+ }
354
+ function setValue(target, property, value, state, length) {
355
+ const isIndex = !Number.isNaN(Number(property));
356
+ const isLength = property === 'length';
357
+ if (!isIndex && !isLength) {
358
+ return Reflect.set(target, property, value);
359
+ }
360
+ const previous = Reflect.get(target, property);
361
+ if (Object.is(previous, value)) {
362
+ return true;
363
+ }
364
+ Reflect.set(target, property, value);
365
+ emitValue(state);
366
+ length.set(target.length);
367
+ return true;
368
+ }
369
+ function updateArray(type, array, state, length) {
370
+ const affectsLength = lengthAffectingMethods.has(type);
371
+ const previousArray = affectsLength ? [] : [...array];
372
+ const previousLength = array.length;
373
+ return (...args) => {
374
+ const result = array[type](...args);
375
+ if (affectsLength
376
+ ? array.length !== previousLength
377
+ : emit(previousArray, array)) {
378
+ emitValue(state);
379
+ length.set(array.length);
380
+ }
381
+ return result;
382
+ };
383
+ }
384
+ const lengthAffectingMethods = new Set([
385
+ 'pop',
386
+ 'push',
387
+ 'shift',
388
+ 'unshift',
389
+ ]);
390
+ const updateMethods = new Set([
391
+ ...lengthAffectingMethods,
392
+ 'copyWithin',
393
+ 'fill',
394
+ 'reverse',
395
+ 'sort',
396
+ 'splice',
397
+ ]);
398
+
399
+ export { array, computed, effect, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch };
package/dist/reactive.cjs CHANGED
@@ -29,6 +29,18 @@ class Reactive {
29
29
  subscribe(callback) {
30
30
  return subscription.subscribe(this.state, callback);
31
31
  }
32
+ /**
33
+ * JSON representation of the value
34
+ */
35
+ toJSON() {
36
+ return this.get();
37
+ }
38
+ /**
39
+ * String representation of the value
40
+ */
41
+ toString() {
42
+ return String(this.get());
43
+ }
32
44
  /**
33
45
  * Unsubscribe from changes
34
46
  */
package/dist/reactive.js CHANGED
@@ -27,6 +27,18 @@ class Reactive {
27
27
  subscribe(callback) {
28
28
  return subscribe(this.state, callback);
29
29
  }
30
+ /**
31
+ * JSON representation of the value
32
+ */
33
+ toJSON() {
34
+ return this.get();
35
+ }
36
+ /**
37
+ * String representation of the value
38
+ */
39
+ toString() {
40
+ return String(this.get());
41
+ }
30
42
  /**
31
43
  * Unsubscribe from changes
32
44
  */