@furystack/utils 5.0.0 → 6.0.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.
@@ -1,4 +1,5 @@
1
1
  import type { Disposable } from './disposable.js';
2
+ import type { ValueObserverOptions } from './value-observer.js';
2
3
  import { ValueObserver } from './value-observer.js';
3
4
  /**
4
5
  * Error thrown when you try to retrieve or set an observable value that is already disposed.
@@ -10,6 +11,15 @@ export declare class ObservableAlreadyDisposedError extends Error {
10
11
  * Callback type for observable value changes
11
12
  */
12
13
  export type ValueChangeCallback<T> = (next: T) => void;
14
+ export type ObservableValueOptions<T> = {
15
+ /**
16
+ * Defines a custom compare function to determine if the value should be updated and the observers should be notified
17
+ * @param lastValue the last value
18
+ * @param nextValue the next value
19
+ * @returns if the value should be updated and the observers should be notified
20
+ */
21
+ compare: (lastValue: T, nextValue: T) => boolean;
22
+ };
13
23
  /**
14
24
  * Defines an ObservableValue value object.
15
25
  *
@@ -42,10 +52,10 @@ export declare class ObservableValue<T> implements Disposable {
42
52
  /**
43
53
  * Subscribes to a value changes
44
54
  * @param callback The callback method that will be called on each change
45
- * @param getLast Will call the callback with the last known value right after subscription
55
+ * @param options Additional ObservableValue options
46
56
  * @returns The ValueObserver instance
47
57
  */
48
- subscribe(callback: ValueChangeCallback<T>, getLast?: boolean): ValueObserver<T>;
58
+ subscribe(callback: ValueChangeCallback<T>, options?: ValueObserverOptions<T>): ValueObserver<T>;
49
59
  /**
50
60
  * The observer will unsubscribe from the Observable
51
61
  * @param observer The ValueObserver instance
@@ -67,9 +77,11 @@ export declare class ObservableValue<T> implements Disposable {
67
77
  * @returns The subscribed observers
68
78
  */
69
79
  getObservers(): readonly ValueObserver<T>[];
80
+ private readonly options;
70
81
  /**
71
82
  * @param initialValue Optional initial value
83
+ * @param options Additional options
72
84
  */
73
- constructor(initialValue: T);
85
+ constructor(initialValue: T, options?: Partial<ObservableValueOptions<T>>);
74
86
  }
75
87
  //# sourceMappingURL=observable-value.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observable-value.d.ts","sourceRoot":"","sources":["../src/observable-value.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD;;GAEG;AACH,qBAAa,8BAA+B,SAAQ,KAAK;;CAIxD;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAA;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,eAAe,CAAC,CAAC,CAAE,YAAW,UAAU;IACnD,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED,OAAO,CAAC,WAAW,CAAQ;IAE3B;;OAEG;IACI,OAAO;IAId,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,YAAY,CAAG;IAEvB;;;;;OAKG;IACI,SAAS,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAAE,OAAO,UAAQ;IAYlE;;;;OAIG;IACI,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;IAI7C;;;OAGG;IACI,QAAQ,IAAI,CAAC;IAOpB;;;OAGG;IACI,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAY3B;;;OAGG;IACI,YAAY;IAInB;;OAEG;gBACS,YAAY,EAAE,CAAC;CAG5B"}
1
+ {"version":3,"file":"observable-value.d.ts","sourceRoot":"","sources":["../src/observable-value.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD;;GAEG;AACH,qBAAa,8BAA+B,SAAQ,KAAK;;CAIxD;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAA;AAEtD,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI;IACtC;;;;;OAKG;IACH,OAAO,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,KAAK,OAAO,CAAA;CACjD,CAAA;AAID;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,eAAe,CAAC,CAAC,CAAE,YAAW,UAAU;IACnD,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED,OAAO,CAAC,WAAW,CAAQ;IAE3B;;OAEG;IACI,OAAO;IAMd,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,YAAY,CAAG;IAEvB;;;;;OAKG;IACI,SAAS,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC;IASpF;;;;OAIG;IACI,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;IAI7C;;;OAGG;IACI,QAAQ,IAAI,CAAC;IAOpB;;;OAGG;IACI,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAc3B;;;OAGG;IACI,YAAY;IAInB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IAEnD;;;OAGG;gBACS,YAAY,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;CAO1E"}
@@ -7,6 +7,7 @@ export class ObservableAlreadyDisposedError extends Error {
7
7
  super('Observable already disposed');
8
8
  }
9
9
  }
10
+ const defaultComparer = (a, b) => a !== b;
10
11
  /**
11
12
  * Defines an ObservableValue value object.
12
13
  *
@@ -38,24 +39,23 @@ export class ObservableValue {
38
39
  dispose() {
39
40
  this.observers.clear();
40
41
  this._isDisposed = true;
42
+ // @ts-expect-error getting currentValue after disposing is not allowed
43
+ this.currentValue = null;
41
44
  }
42
45
  observers = new Set();
43
46
  currentValue;
44
47
  /**
45
48
  * Subscribes to a value changes
46
49
  * @param callback The callback method that will be called on each change
47
- * @param getLast Will call the callback with the last known value right after subscription
50
+ * @param options Additional ObservableValue options
48
51
  * @returns The ValueObserver instance
49
52
  */
50
- subscribe(callback, getLast = false) {
53
+ subscribe(callback, options) {
51
54
  if (this._isDisposed) {
52
55
  throw new ObservableAlreadyDisposedError();
53
56
  }
54
- const observer = new ValueObserver(this, callback);
57
+ const observer = new ValueObserver(this, callback, options);
55
58
  this.observers.add(observer);
56
- if (getLast) {
57
- callback(this.currentValue);
58
- }
59
59
  return observer;
60
60
  }
61
61
  /**
@@ -84,11 +84,13 @@ export class ObservableValue {
84
84
  if (this._isDisposed) {
85
85
  throw new ObservableAlreadyDisposedError();
86
86
  }
87
- if (this.currentValue !== newValue) {
87
+ if (this.options.compare(this.currentValue, newValue)) {
88
88
  this.currentValue = newValue;
89
- for (const subscription of this.observers) {
90
- subscription.callback(newValue);
91
- }
89
+ this.observers.forEach((observer) => {
90
+ if (observer.options?.filter?.(this.currentValue, newValue) !== false) {
91
+ observer.callback(newValue);
92
+ }
93
+ });
92
94
  }
93
95
  }
94
96
  /**
@@ -98,10 +100,16 @@ export class ObservableValue {
98
100
  getObservers() {
99
101
  return [...this.observers];
100
102
  }
103
+ options;
101
104
  /**
102
105
  * @param initialValue Optional initial value
106
+ * @param options Additional options
103
107
  */
104
- constructor(initialValue) {
108
+ constructor(initialValue, options) {
109
+ this.options = {
110
+ compare: defaultComparer,
111
+ ...options,
112
+ };
105
113
  this.currentValue = initialValue;
106
114
  }
107
115
  }
@@ -1 +1 @@
1
- {"version":3,"file":"observable-value.js","sourceRoot":"","sources":["../src/observable-value.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD;;GAEG;AACH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IACvD;QACE,KAAK,CAAC,6BAA6B,CAAC,CAAA;IACtC,CAAC;CACF;AAOD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,eAAe;IAC1B,IAAW,UAAU;QACnB,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;IAEO,WAAW,GAAG,KAAK,CAAA;IAE3B;;OAEG;IACI,OAAO;QACZ,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA;QACtB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;IACzB,CAAC;IACO,SAAS,GAA0B,IAAI,GAAG,EAAE,CAAA;IAC5C,YAAY,CAAG;IAEvB;;;;;OAKG;IACI,SAAS,CAAC,QAAgC,EAAE,OAAO,GAAG,KAAK;QAChE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,IAAI,8BAA8B,EAAE,CAAA;QAC5C,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAI,IAAI,EAAE,QAAQ,CAAC,CAAA;QACrD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC5B,IAAI,OAAO,EAAE,CAAC;YACZ,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAC7B,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,QAA0B;QAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACxC,CAAC;IAED;;;OAGG;IACI,QAAQ;QACb,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,IAAI,8BAA8B,EAAE,CAAA;QAC5C,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAA;IAC1B,CAAC;IAED;;;OAGG;IACI,QAAQ,CAAC,QAAW;QACzB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,IAAI,8BAA8B,EAAE,CAAA;QAC5C,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAA;YAC5B,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBAC1C,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,YAAY;QACjB,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAoC,CAAA;IAC/D,CAAC;IAED;;OAEG;IACH,YAAY,YAAe;QACzB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;CACF"}
1
+ {"version":3,"file":"observable-value.js","sourceRoot":"","sources":["../src/observable-value.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD;;GAEG;AACH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IACvD;QACE,KAAK,CAAC,6BAA6B,CAAC,CAAA;IACtC,CAAC;CACF;AAiBD,MAAM,eAAe,GAAG,CAAI,CAAI,EAAE,CAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;AAElD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,eAAe;IAC1B,IAAW,UAAU;QACnB,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;IAEO,WAAW,GAAG,KAAK,CAAA;IAE3B;;OAEG;IACI,OAAO;QACZ,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA;QACtB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QACvB,uEAAuE;QACvE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;IAC1B,CAAC;IACO,SAAS,GAA0B,IAAI,GAAG,EAAE,CAAA;IAC5C,YAAY,CAAG;IAEvB;;;;;OAKG;IACI,SAAS,CAAC,QAAgC,EAAE,OAAiC;QAClF,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,IAAI,8BAA8B,EAAE,CAAA;QAC5C,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAI,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;QAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC5B,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,QAA0B;QAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACxC,CAAC;IAED;;;OAGG;IACI,QAAQ;QACb,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,IAAI,8BAA8B,EAAE,CAAA;QAC5C,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAA;IAC1B,CAAC;IAED;;;OAGG;IACI,QAAQ,CAAC,QAAW;QACzB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,IAAI,8BAA8B,EAAE,CAAA;QAC5C,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAA;YAC5B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;gBAClC,IAAI,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,KAAK,KAAK,EAAE,CAAC;oBACtE,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;gBAC7B,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,YAAY;QACjB,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAoC,CAAA;IAC/D,CAAC;IAEgB,OAAO,CAA2B;IAEnD;;;OAGG;IACH,YAAY,YAAe,EAAE,OAA4C;QACvE,IAAI,CAAC,OAAO,GAAG;YACb,OAAO,EAAE,eAAe;YACxB,GAAG,OAAO;SACX,CAAA;QACD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"observable-value.spec.d.ts","sourceRoot":"","sources":["../src/observable-value.spec.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,eAAe,qCAyI1B,CAAA"}
1
+ {"version":3,"file":"observable-value.spec.d.ts","sourceRoot":"","sources":["../src/observable-value.spec.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,eAAe,qCA6K1B,CAAA"}
@@ -6,22 +6,12 @@ import { ObservableValue } from './observable-value.js';
6
6
  export const observableTests = describe('Observable', () => {
7
7
  it('should be constructed with an undefined initial value', () => {
8
8
  const v = new ObservableValue(undefined);
9
- const doneCallback = vi.fn();
10
- v.subscribe(() => {
11
- expect(v.getValue()).toBe(undefined);
12
- doneCallback();
13
- }, true);
14
9
  expect(v).toBeInstanceOf(ObservableValue);
15
- expect(doneCallback).toBeCalled();
10
+ expect(v.getValue()).toBe(undefined);
16
11
  });
17
12
  it('should be constructed with initial value', () => {
18
13
  const v = new ObservableValue(1);
19
- const doneCallback = vi.fn();
20
- v.subscribe(() => {
21
- expect(v.getValue()).toBe(1);
22
- doneCallback();
23
- }, true);
24
- expect(doneCallback).toBeCalled();
14
+ expect(v.getValue()).toBe(1);
25
15
  });
26
16
  describe('Subscription callback', () => {
27
17
  it('should be triggered only when a value is changed', () => {
@@ -30,19 +20,19 @@ export const observableTests = describe('Observable', () => {
30
20
  v.subscribe(() => {
31
21
  expect(v.getValue()).toBe(2);
32
22
  doneCallback();
33
- }, false);
23
+ });
34
24
  v.setValue(1);
35
25
  v.setValue(1);
36
26
  v.setValue(2);
37
27
  expect(doneCallback).toBeCalledTimes(1);
38
28
  });
39
- it('should be triggered only on change when getLast is false', () => {
29
+ it('should be triggered only on change', () => {
40
30
  const v = new ObservableValue(1);
41
31
  const doneCallback = vi.fn();
42
32
  v.subscribe((value) => {
43
33
  expect(value).toBe(2);
44
34
  doneCallback();
45
- }, false);
35
+ });
46
36
  v.setValue(2);
47
37
  expect(doneCallback).toBeCalledTimes(1);
48
38
  });
@@ -119,5 +109,41 @@ export const observableTests = describe('Observable', () => {
119
109
  expect(doneCallback).toBeCalledTimes(1);
120
110
  });
121
111
  });
112
+ describe('Custom Compare function', () => {
113
+ it('Should compare the values with the custom compare function', () => {
114
+ const v = new ObservableValue({ value: 2 }, {
115
+ compare: (a, b) => a.value !== b.value,
116
+ });
117
+ const onChange = vi.fn();
118
+ v.subscribe(onChange);
119
+ v.setValue({ value: 2 });
120
+ expect(v.getValue()).toEqual({ value: 2 });
121
+ expect(onChange).not.toBeCalled();
122
+ v.setValue({ value: 3 });
123
+ expect(v.getValue()).toEqual({ value: 3 });
124
+ expect(onChange).toBeCalledTimes(1);
125
+ expect(onChange).toBeCalledWith({ value: 3 });
126
+ v.setValue({ value: 3 });
127
+ expect(v.getValue()).toEqual({ value: 3 });
128
+ expect(onChange).toBeCalledTimes(1);
129
+ });
130
+ });
131
+ describe('Filtered subscriptions', () => {
132
+ it('should not trigger the callback if the filter returns false', () => {
133
+ const v = new ObservableValue({ shouldNotify: true, value: 1 });
134
+ const onChange = vi.fn();
135
+ v.subscribe(onChange, {
136
+ filter: (nextValue) => nextValue.shouldNotify,
137
+ });
138
+ v.setValue({ shouldNotify: false, value: 1 });
139
+ expect(onChange).not.toBeCalled();
140
+ v.setValue({ shouldNotify: false, value: 2 });
141
+ expect(onChange).not.toBeCalled();
142
+ expect(v.getValue()).toEqual({ shouldNotify: false, value: 2 });
143
+ v.setValue({ shouldNotify: true, value: 3 });
144
+ expect(onChange).toBeCalledTimes(1);
145
+ expect(onChange).toBeCalledWith({ shouldNotify: true, value: 3 });
146
+ });
147
+ });
122
148
  });
123
149
  //# sourceMappingURL=observable-value.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"observable-value.spec.js","sourceRoot":"","sources":["../src/observable-value.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"observable-value.spec.js","sourceRoot":"","sources":["../src/observable-value.spec.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,8 @@
1
1
  import type { Disposable } from './disposable.js';
2
2
  import type { ObservableValue, ValueChangeCallback } from './observable-value.js';
3
+ export type ValueObserverOptions<T> = {
4
+ filter?: (nextValue: T, lastValue: T) => boolean;
5
+ };
3
6
  /**
4
7
  * Defines a generic ValueObserver instance
5
8
  *
@@ -25,6 +28,7 @@ import type { ObservableValue, ValueChangeCallback } from './observable-value.js
25
28
  export declare class ValueObserver<T> implements Disposable {
26
29
  readonly observable: ObservableValue<T>;
27
30
  callback: ValueChangeCallback<T>;
31
+ readonly options?: ValueObserverOptions<T> | undefined;
28
32
  /**
29
33
  * Disposes the ValueObserver instance. Unsubscribes from the observable
30
34
  */
@@ -33,7 +37,8 @@ export declare class ValueObserver<T> implements Disposable {
33
37
  * @constructs ValueObserver<T> the ValueObserver instance
34
38
  * @param observable The related Observable object
35
39
  * @param callback The callback that will be fired on change
40
+ * @param options Additional options
36
41
  */
37
- constructor(observable: ObservableValue<T>, callback: ValueChangeCallback<T>);
42
+ constructor(observable: ObservableValue<T>, callback: ValueChangeCallback<T>, options?: ValueObserverOptions<T> | undefined);
38
43
  }
39
44
  //# sourceMappingURL=value-observer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"value-observer.d.ts","sourceRoot":"","sources":["../src/value-observer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAEjF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,aAAa,CAAC,CAAC,CAAE,YAAW,UAAU;aAc/B,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC;IACvC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAdzC;;OAEG;IACI,OAAO;IAId;;;;OAIG;gBAEe,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC,EACvC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC;CAE1C"}
1
+ {"version":3,"file":"value-observer.d.ts","sourceRoot":"","sources":["../src/value-observer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAEjF,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI;IACpC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,KAAK,OAAO,CAAA;CACjD,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,aAAa,CAAC,CAAC,CAAE,YAAW,UAAU;aAe/B,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC;IACvC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC;aACvB,OAAO,CAAC;IAhB1B;;OAEG;IACI,OAAO;IAId;;;;;OAKG;gBAEe,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC,EACvC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,EACvB,OAAO,CAAC,qCAAyB;CAEpD"}
@@ -23,6 +23,7 @@
23
23
  export class ValueObserver {
24
24
  observable;
25
25
  callback;
26
+ options;
26
27
  /**
27
28
  * Disposes the ValueObserver instance. Unsubscribes from the observable
28
29
  */
@@ -33,10 +34,12 @@ export class ValueObserver {
33
34
  * @constructs ValueObserver<T> the ValueObserver instance
34
35
  * @param observable The related Observable object
35
36
  * @param callback The callback that will be fired on change
37
+ * @param options Additional options
36
38
  */
37
- constructor(observable, callback) {
39
+ constructor(observable, callback, options) {
38
40
  this.observable = observable;
39
41
  this.callback = callback;
42
+ this.options = options;
40
43
  }
41
44
  }
42
45
  //# sourceMappingURL=value-observer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"value-observer.js","sourceRoot":"","sources":["../src/value-observer.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,OAAO,aAAa;IAcN;IACT;IAdT;;OAEG;IACI,OAAO;QACZ,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;IACnC,CAAC;IAED;;;;OAIG;IACH,YACkB,UAA8B,EACvC,QAAgC;QADvB,eAAU,GAAV,UAAU,CAAoB;QACvC,aAAQ,GAAR,QAAQ,CAAwB;IACtC,CAAC;CACL"}
1
+ {"version":3,"file":"value-observer.js","sourceRoot":"","sources":["../src/value-observer.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,OAAO,aAAa;IAeN;IACT;IACS;IAhBlB;;OAEG;IACI,OAAO;QACZ,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;IACnC,CAAC;IAED;;;;;OAKG;IACH,YACkB,UAA8B,EACvC,QAAgC,EACvB,OAAiC;QAFjC,eAAU,GAAV,UAAU,CAAoB;QACvC,aAAQ,GAAR,QAAQ,CAAwB;QACvB,YAAO,GAAP,OAAO,CAA0B;IAChD,CAAC;CACL"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@furystack/utils",
3
- "version": "5.0.0",
3
+ "version": "6.0.0",
4
4
  "description": "General utilities",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -7,24 +7,13 @@ import { ObservableValue } from './observable-value.js'
7
7
  export const observableTests = describe('Observable', () => {
8
8
  it('should be constructed with an undefined initial value', () => {
9
9
  const v = new ObservableValue(undefined)
10
- const doneCallback = vi.fn()
11
- v.subscribe(() => {
12
- expect(v.getValue()).toBe(undefined)
13
- doneCallback()
14
- }, true)
15
10
  expect(v).toBeInstanceOf(ObservableValue)
16
- expect(doneCallback).toBeCalled()
11
+ expect(v.getValue()).toBe(undefined)
17
12
  })
18
13
 
19
14
  it('should be constructed with initial value', () => {
20
15
  const v = new ObservableValue(1)
21
- const doneCallback = vi.fn()
22
-
23
- v.subscribe(() => {
24
- expect(v.getValue()).toBe(1)
25
- doneCallback()
26
- }, true)
27
- expect(doneCallback).toBeCalled()
16
+ expect(v.getValue()).toBe(1)
28
17
  })
29
18
 
30
19
  describe('Subscription callback', () => {
@@ -35,21 +24,21 @@ export const observableTests = describe('Observable', () => {
35
24
  v.subscribe(() => {
36
25
  expect(v.getValue()).toBe(2)
37
26
  doneCallback()
38
- }, false)
27
+ })
39
28
  v.setValue(1)
40
29
  v.setValue(1)
41
30
  v.setValue(2)
42
31
  expect(doneCallback).toBeCalledTimes(1)
43
32
  })
44
33
 
45
- it('should be triggered only on change when getLast is false', () => {
34
+ it('should be triggered only on change', () => {
46
35
  const v = new ObservableValue(1)
47
36
  const doneCallback = vi.fn()
48
37
 
49
38
  v.subscribe((value) => {
50
39
  expect(value).toBe(2)
51
40
  doneCallback()
52
- }, false)
41
+ })
53
42
  v.setValue(2)
54
43
  expect(doneCallback).toBeCalledTimes(1)
55
44
  })
@@ -141,4 +130,51 @@ export const observableTests = describe('Observable', () => {
141
130
  expect(doneCallback).toBeCalledTimes(1)
142
131
  })
143
132
  })
133
+
134
+ describe('Custom Compare function', () => {
135
+ it('Should compare the values with the custom compare function', () => {
136
+ const v = new ObservableValue(
137
+ { value: 2 },
138
+ {
139
+ compare: (a, b) => a.value !== b.value,
140
+ },
141
+ )
142
+ const onChange = vi.fn()
143
+ v.subscribe(onChange)
144
+
145
+ v.setValue({ value: 2 })
146
+ expect(v.getValue()).toEqual({ value: 2 })
147
+ expect(onChange).not.toBeCalled()
148
+
149
+ v.setValue({ value: 3 })
150
+ expect(v.getValue()).toEqual({ value: 3 })
151
+ expect(onChange).toBeCalledTimes(1)
152
+ expect(onChange).toBeCalledWith({ value: 3 })
153
+
154
+ v.setValue({ value: 3 })
155
+ expect(v.getValue()).toEqual({ value: 3 })
156
+ expect(onChange).toBeCalledTimes(1)
157
+ })
158
+ })
159
+
160
+ describe('Filtered subscriptions', () => {
161
+ it('should not trigger the callback if the filter returns false', () => {
162
+ const v = new ObservableValue({ shouldNotify: true, value: 1 })
163
+ const onChange = vi.fn()
164
+ v.subscribe(onChange, {
165
+ filter: (nextValue) => nextValue.shouldNotify,
166
+ })
167
+
168
+ v.setValue({ shouldNotify: false, value: 1 })
169
+ expect(onChange).not.toBeCalled()
170
+
171
+ v.setValue({ shouldNotify: false, value: 2 })
172
+ expect(onChange).not.toBeCalled()
173
+ expect(v.getValue()).toEqual({ shouldNotify: false, value: 2 })
174
+
175
+ v.setValue({ shouldNotify: true, value: 3 })
176
+ expect(onChange).toBeCalledTimes(1)
177
+ expect(onChange).toBeCalledWith({ shouldNotify: true, value: 3 })
178
+ })
179
+ })
144
180
  })
@@ -1,4 +1,5 @@
1
1
  import type { Disposable } from './disposable.js'
2
+ import type { ValueObserverOptions } from './value-observer.js'
2
3
  import { ValueObserver } from './value-observer.js'
3
4
 
4
5
  /**
@@ -15,6 +16,18 @@ export class ObservableAlreadyDisposedError extends Error {
15
16
  */
16
17
  export type ValueChangeCallback<T> = (next: T) => void
17
18
 
19
+ export type ObservableValueOptions<T> = {
20
+ /**
21
+ * Defines a custom compare function to determine if the value should be updated and the observers should be notified
22
+ * @param lastValue the last value
23
+ * @param nextValue the next value
24
+ * @returns if the value should be updated and the observers should be notified
25
+ */
26
+ compare: (lastValue: T, nextValue: T) => boolean
27
+ }
28
+
29
+ const defaultComparer = <T>(a: T, b: T) => a !== b
30
+
18
31
  /**
19
32
  * Defines an ObservableValue value object.
20
33
  *
@@ -48,6 +61,8 @@ export class ObservableValue<T> implements Disposable {
48
61
  public dispose() {
49
62
  this.observers.clear()
50
63
  this._isDisposed = true
64
+ // @ts-expect-error getting currentValue after disposing is not allowed
65
+ this.currentValue = null
51
66
  }
52
67
  private observers: Set<ValueObserver<T>> = new Set()
53
68
  private currentValue: T
@@ -55,18 +70,15 @@ export class ObservableValue<T> implements Disposable {
55
70
  /**
56
71
  * Subscribes to a value changes
57
72
  * @param callback The callback method that will be called on each change
58
- * @param getLast Will call the callback with the last known value right after subscription
73
+ * @param options Additional ObservableValue options
59
74
  * @returns The ValueObserver instance
60
75
  */
61
- public subscribe(callback: ValueChangeCallback<T>, getLast = false) {
76
+ public subscribe(callback: ValueChangeCallback<T>, options?: ValueObserverOptions<T>) {
62
77
  if (this._isDisposed) {
63
78
  throw new ObservableAlreadyDisposedError()
64
79
  }
65
- const observer = new ValueObserver<T>(this, callback)
80
+ const observer = new ValueObserver<T>(this, callback, options)
66
81
  this.observers.add(observer)
67
- if (getLast) {
68
- callback(this.currentValue)
69
- }
70
82
  return observer
71
83
  }
72
84
 
@@ -98,11 +110,13 @@ export class ObservableValue<T> implements Disposable {
98
110
  if (this._isDisposed) {
99
111
  throw new ObservableAlreadyDisposedError()
100
112
  }
101
- if (this.currentValue !== newValue) {
113
+ if (this.options.compare(this.currentValue, newValue)) {
102
114
  this.currentValue = newValue
103
- for (const subscription of this.observers) {
104
- subscription.callback(newValue)
105
- }
115
+ this.observers.forEach((observer) => {
116
+ if (observer.options?.filter?.(this.currentValue, newValue) !== false) {
117
+ observer.callback(newValue)
118
+ }
119
+ })
106
120
  }
107
121
  }
108
122
 
@@ -114,10 +128,17 @@ export class ObservableValue<T> implements Disposable {
114
128
  return [...this.observers] as ReadonlyArray<ValueObserver<T>>
115
129
  }
116
130
 
131
+ private readonly options: ObservableValueOptions<T>
132
+
117
133
  /**
118
134
  * @param initialValue Optional initial value
135
+ * @param options Additional options
119
136
  */
120
- constructor(initialValue: T) {
137
+ constructor(initialValue: T, options?: Partial<ObservableValueOptions<T>>) {
138
+ this.options = {
139
+ compare: defaultComparer,
140
+ ...options,
141
+ }
121
142
  this.currentValue = initialValue
122
143
  }
123
144
  }
@@ -1,6 +1,10 @@
1
1
  import type { Disposable } from './disposable.js'
2
2
  import type { ObservableValue, ValueChangeCallback } from './observable-value.js'
3
3
 
4
+ export type ValueObserverOptions<T> = {
5
+ filter?: (nextValue: T, lastValue: T) => boolean
6
+ }
7
+
4
8
  /**
5
9
  * Defines a generic ValueObserver instance
6
10
  *
@@ -35,9 +39,11 @@ export class ValueObserver<T> implements Disposable {
35
39
  * @constructs ValueObserver<T> the ValueObserver instance
36
40
  * @param observable The related Observable object
37
41
  * @param callback The callback that will be fired on change
42
+ * @param options Additional options
38
43
  */
39
44
  constructor(
40
45
  public readonly observable: ObservableValue<T>,
41
46
  public callback: ValueChangeCallback<T>,
47
+ public readonly options?: ValueObserverOptions<T>,
42
48
  ) {}
43
49
  }