@oscarpalmer/mora 0.31.0 → 0.32.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.
Files changed (54) hide show
  1. package/dist/batch.d.mts +4 -5
  2. package/dist/batch.mjs +4 -2
  3. package/dist/constants.d.mts +29 -19
  4. package/dist/constants.mjs +17 -2
  5. package/dist/effect.d.mts +4 -5
  6. package/dist/effect.mjs +2 -2
  7. package/dist/helpers/is.d.mts +14 -9
  8. package/dist/helpers/is.mjs +6 -0
  9. package/dist/helpers/proxy.d.mts +12 -10
  10. package/dist/helpers/proxy.mjs +32 -14
  11. package/dist/helpers/subscription.d.mts +8 -0
  12. package/dist/helpers/subscription.mjs +27 -0
  13. package/dist/helpers/value.d.mts +8 -6
  14. package/dist/helpers/value.mjs +30 -4
  15. package/dist/index.d.mts +3 -2
  16. package/dist/models.d.mts +45 -87
  17. package/dist/mora.full.mjs +461 -285
  18. package/dist/value/array.d.mts +4 -5
  19. package/dist/value/array.mjs +22 -69
  20. package/dist/value/computed.d.mts +3 -4
  21. package/dist/value/computed.mjs +14 -14
  22. package/dist/value/reactive.d.mts +2 -3
  23. package/dist/value/reactive.mjs +0 -1
  24. package/dist/value/readonly.d.mts +3 -5
  25. package/dist/value/readonly.mjs +15 -19
  26. package/dist/value/signal.d.mts +4 -5
  27. package/dist/value/signal.mjs +9 -22
  28. package/dist/value/store.d.mts +4 -5
  29. package/dist/value/store.mjs +16 -56
  30. package/package.json +6 -6
  31. package/src/batch.ts +15 -5
  32. package/src/constants.ts +32 -2
  33. package/src/effect.ts +6 -2
  34. package/src/helpers/is.ts +10 -0
  35. package/src/helpers/proxy.ts +99 -49
  36. package/src/helpers/subscription.ts +78 -0
  37. package/src/helpers/value.ts +69 -4
  38. package/src/index.ts +1 -1
  39. package/src/models.ts +38 -81
  40. package/src/value/array.ts +61 -150
  41. package/src/value/computed.ts +36 -13
  42. package/src/value/reactive.ts +8 -5
  43. package/src/value/readonly.ts +26 -25
  44. package/src/value/signal.ts +19 -22
  45. package/src/value/store.ts +35 -114
  46. package/types/constants.d.ts +1 -1
  47. package/types/index.d.ts +1 -1
  48. package/types/value/array.d.ts +1 -1
  49. package/types/value/computed.d.ts +0 -3
  50. package/types/value/signal.d.ts +1 -1
  51. package/types/value/store.d.ts +1 -1
  52. package/dist/subscription.d.mts +0 -7
  53. package/dist/subscription.mjs +0 -27
  54. package/src/subscription.ts +0 -45
@@ -1,14 +1,15 @@
1
- import {isKey, isPlainObject} from '@oscarpalmer/atoms/is';
2
- import type {GenericCallback, Key, PlainObject} from '@oscarpalmer/atoms/models';
1
+ import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
3
2
  import {startBatch, stopBatch} from '../batch';
4
3
  import {NAME_MORA, NAME_STORE} from '../constants';
5
4
  import {
6
- emityProxyValues,
7
- getReactiveValueInProxy,
5
+ emitProxyValues,
6
+ getValueInProxy,
7
+ peekValueInProxy,
8
8
  setProxyValue,
9
9
  setValueInProxy,
10
+ updateProxyValue,
10
11
  } from '../helpers/proxy';
11
- import {getSimpleValue} from '../helpers/value';
12
+ import {subscribeToProxy} from '../helpers/subscription';
12
13
  import type {
13
14
  Computed,
14
15
  ComputedEffect,
@@ -16,17 +17,24 @@ import type {
16
17
  ReactiveState,
17
18
  ReactiveStore,
18
19
  ReadonlyInstances,
19
- Unsubscribe,
20
20
  } from '../models';
21
- import {noop, subscribe, unsubscribe} from '../subscription';
22
21
  import {reactive} from './reactive';
23
22
  import {getReadonlyInstance} from './readonly';
24
23
 
25
- function isStoreObject<Value extends PlainObject>(value: unknown): value is Value | undefined {
26
- return value == null || isPlainObject(value);
24
+ // #region Functions
25
+
26
+ function setPropertyValue<Value extends PlainObject, Item = Value>(
27
+ state: ReactiveState<Value, Item>,
28
+ key: unknown,
29
+ value: unknown,
30
+ ): void {
31
+ (state.value as PlainObject)[key as Key] = value;
27
32
  }
28
33
 
29
- function setObject(state: ReactiveState<PlainObject, never>, value: PlainObject | undefined): void {
34
+ function setStoreValue<Value extends PlainObject, Item = Value>(
35
+ state: ReactiveState<Value, Item>,
36
+ value: PlainObject | undefined,
37
+ ): void {
30
38
  startBatch();
31
39
 
32
40
  const actual = value ?? {};
@@ -58,42 +66,6 @@ function setObject(state: ReactiveState<PlainObject, never>, value: PlainObject
58
66
  stopBatch();
59
67
  }
60
68
 
61
- function peekStoreValue<Value extends PlainObject>(
62
- state: ReactiveState<Value, Value>,
63
- first?: unknown,
64
- second?: boolean,
65
- ): unknown {
66
- let value: unknown;
67
-
68
- if (isKey(first)) {
69
- value = state.value[first];
70
- } else {
71
- value = state.value;
72
- }
73
-
74
- if (!(first === true || second === true)) {
75
- return value;
76
- }
77
-
78
- if (Array.isArray(value)) {
79
- return value.slice();
80
- }
81
-
82
- if (isPlainObject(value)) {
83
- return {...value};
84
- }
85
-
86
- return value;
87
- }
88
-
89
- function setProperty<Value extends PlainObject>(
90
- state: ReactiveState<Value, Value>,
91
- key: unknown,
92
- value: unknown,
93
- ): void {
94
- (state.value as PlainObject)[key as Key] = value;
95
- }
96
-
97
69
  /**
98
70
  * Create a reactive store from a function result
99
71
  *
@@ -136,86 +108,35 @@ export function store<Value extends PlainObject>(
136
108
  ): ReactiveStore<Value> {
137
109
  const [rx, state] = reactive<Value>(undefined as never, options);
138
110
 
111
+ const isArray = false;
139
112
  const keyed = new Map<Key, [Computed<unknown>, ComputedEffect]>();
140
113
  const readonlies: ReadonlyInstances<Value> = {};
141
114
 
142
- let instance: Record<string, GenericCallback> = {};
143
-
144
115
  state.value = new Proxy({} as Value, {
145
- set: (target: Value, property: PropertyKey, value: unknown) =>
146
- setValueInProxy({
147
- target,
148
- property,
149
- state,
150
- value,
151
- isArray: false,
152
- }),
116
+ set: (target, property, value) => setValueInProxy(isArray, state, target, property, value),
153
117
  });
154
118
 
155
- const handlers = {
119
+ const instance = {
156
120
  ...rx,
157
- get: (value?: unknown): unknown =>
158
- isKey(value)
159
- ? getReactiveValueInProxy(instance as ReactiveStore<Value>, keyed, value, false).get()
160
- : getSimpleValue(state),
161
- peek: (first?: unknown, second?: boolean): unknown => peekStoreValue(state, first, second),
162
- subscribe: (first: Key | GenericCallback, second?: GenericCallback): Unsubscribe => {
163
- if (isKey(first) && typeof second === 'function') {
164
- return getReactiveValueInProxy(
165
- instance as ReactiveStore<Value>,
166
- keyed,
167
- first,
168
- false,
169
- ).subscribe(second);
170
- }
171
-
172
- return typeof first === 'function' ? subscribe(state, first) : noop;
173
- },
174
- unsubscribe: (first: Key | GenericCallback, second?: GenericCallback) => {
175
- if (isKey(first) && typeof second === 'function') {
176
- getReactiveValueInProxy(instance as ReactiveStore<Value>, keyed, first, false)?.unsubscribe(
177
- second,
178
- );
179
- } else if (typeof first === 'function') {
180
- unsubscribe(state, first);
181
- }
182
- },
183
- };
184
-
185
- instance = {
186
- ...handlers,
187
- asReadonly: (frozen?: unknown) =>
188
- getReadonlyInstance(state, readonlies, handlers, frozen === true),
189
- notify(): void {
190
- emityProxyValues(state, keyed);
191
- },
192
- set: (first?: unknown, second?: unknown) => {
193
- setProxyValue<Value>(
194
- false,
195
- state,
196
- isStoreObject,
197
- isKey,
198
- setObject,
199
- setProperty,
200
- first,
201
- second,
202
- );
203
- },
204
- update: (callback: (value: Value) => Value) => {
205
- const updated = callback(state.value);
206
-
207
- if (updated == null || isPlainObject(updated)) {
208
- setObject(state, updated);
209
- }
210
- },
121
+ asReadonly: (frozen?: never) => getReadonlyInstance(state, readonlies, frozen === true),
122
+ get: (value?: never) => getValueInProxy(isArray, instance as never, state, keyed, value),
123
+ notify: () => emitProxyValues(state, keyed),
124
+ peek: (first?: never, second?: never) => peekValueInProxy(isArray, state, first, second),
125
+ set: (first?: never, second?: never) =>
126
+ setProxyValue<Value>(isArray, state, setStoreValue, setPropertyValue, first, second),
127
+ subscribe: (first: never, second?: never, third?: never) =>
128
+ subscribeToProxy(isArray, instance as never, state, keyed, first, second, third),
129
+ update: (callback: never) =>
130
+ updateProxyValue(isArray, state, setStoreValue, setPropertyValue, callback),
211
131
  };
212
132
 
213
133
  Object.defineProperty(instance, NAME_MORA, {
214
- enumerable: false,
215
134
  value: NAME_STORE,
216
135
  });
217
136
 
218
- instance.set(value);
137
+ instance.set(value as never);
219
138
 
220
- return Object.freeze(instance) as ReactiveStore<Value>;
139
+ return Object.freeze(instance) as never;
221
140
  }
141
+
142
+ // #endregion
@@ -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>;
@@ -1,7 +0,0 @@
1
- import { ReactiveState, Unsubscribe } from "./models.mjs";
2
- //#region src/subscription.d.ts
3
- declare function noop(): void;
4
- declare function subscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): Unsubscribe;
5
- declare function unsubscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): void;
6
- //#endregion
7
- export { noop, subscribe, unsubscribe };
@@ -1,27 +0,0 @@
1
- //#region src/subscription.ts
2
- function noop() {}
3
- function subscribe(state, callback) {
4
- if (typeof callback !== "function" || state.subscriptions.has(callback)) return noop;
5
- state.subscriptions.set(callback, subscription(state, callback));
6
- return () => {
7
- unsubscribe(state, callback);
8
- };
9
- }
10
- function subscription(state, callback) {
11
- const instance = {
12
- callback,
13
- state,
14
- destroy: () => {
15
- instance.callback = noop;
16
- instance.state = void 0;
17
- }
18
- };
19
- callback(state.value);
20
- return instance;
21
- }
22
- function unsubscribe(state, callback) {
23
- state.subscriptions.get(callback)?.destroy();
24
- state.subscriptions.delete(callback);
25
- }
26
- //#endregion
27
- export { noop, subscribe, unsubscribe };
@@ -1,45 +0,0 @@
1
- import type {ReactiveState, Subscription, Unsubscribe} from './models';
2
-
3
- export function noop(): void {}
4
-
5
- export function subscribe<Value>(
6
- state: ReactiveState<Value, never>,
7
- callback: (value: Value) => void,
8
- ): Unsubscribe {
9
- if (typeof callback !== 'function' || state.subscriptions.has(callback)) {
10
- return noop;
11
- }
12
-
13
- state.subscriptions.set(callback, subscription(state, callback));
14
-
15
- return () => {
16
- unsubscribe(state, callback);
17
- };
18
- }
19
-
20
- function subscription<Value>(
21
- state: ReactiveState<Value, never>,
22
- callback: (value: Value) => void,
23
- ): Subscription {
24
- const instance: Subscription = {
25
- callback,
26
- state,
27
- destroy: () => {
28
- instance.callback = noop;
29
- instance.state = undefined as never;
30
- },
31
- };
32
-
33
- callback(state.value);
34
-
35
- return instance;
36
- }
37
-
38
- export function unsubscribe<Value>(
39
- state: ReactiveState<Value, never>,
40
- callback: (value: Value) => void,
41
- ): void {
42
- state.subscriptions.get(callback)?.destroy();
43
-
44
- state.subscriptions.delete(callback);
45
- }