From 70b68c5b162a9cd302154f99a5e4fe7174cc5a4e Mon Sep 17 00:00:00 2001 From: Isaiah Becker-Mayer Date: Tue, 26 Jul 2022 22:14:14 -0700 Subject: [PATCH] found a more clever way to do this which eliminates boilerplate --- src/observable/map/ApplyMap.ts | 26 +------------ src/observable/map/BaseObservableMap.ts | 37 +++++++++++++------ .../map/BaseObservableMapDefaults.ts | 5 +-- src/observable/map/FilteredMap.ts | 25 ++----------- src/observable/map/JoinedMap.ts | 25 +------------ src/observable/map/LogMap.ts | 27 ++------------ src/observable/map/MappedMap.ts | 25 ++----------- src/observable/map/ObservableMap.ts | 25 +------------ 8 files changed, 42 insertions(+), 153 deletions(-) diff --git a/src/observable/map/ApplyMap.ts b/src/observable/map/ApplyMap.ts index f8d09914..1786873a 100644 --- a/src/observable/map/ApplyMap.ts +++ b/src/observable/map/ApplyMap.ts @@ -16,22 +16,17 @@ limitations under the License. import {BaseObservableMap} from "./BaseObservableMap"; import {SubscriptionHandle} from "../BaseObservable"; -import {BaseObservableMapDefaults, Mapper, Updater, Comparator, Filter} from "./BaseObservableMapDefaults"; -import {JoinedMap} from "./JoinedMap"; -import {MappedMap} from "./MappedMap"; -import {FilteredMap} from "./FilteredMap"; -import {SortedMapList} from "../list/SortedMapList.js"; +import {BaseObservableMapDefaults} from "./BaseObservableMapDefaults"; export class ApplyMap extends BaseObservableMap { - private _defaults = new BaseObservableMapDefaults(); private _source: BaseObservableMap; private _subscription?: SubscriptionHandle; private _apply?: Apply; constructor(source: BaseObservableMap, apply?: Apply) { - super(); + super(new BaseObservableMapDefaults()); this._source = source; this._apply = apply; } @@ -103,23 +98,6 @@ export class ApplyMap extends BaseObservableMap { get(key: K): V | undefined { return this._source.get(key); } - - join(...otherMaps: Array): JoinedMap { - return this._defaults.join(this, ...otherMaps); - } - - mapValues(mapper: Mapper, updater?: Updater): MappedMap { - return this._defaults.mapValues(this, mapper, updater); - } - - sortValues(comparator: Comparator): SortedMapList { - return this._defaults.sortValues(this, comparator); - } - - filterValues(filter: Filter): FilteredMap { - return this._defaults.filterValues(this, filter); - } - } type Apply = (key: K, value: V, params?: any) => void; \ No newline at end of file diff --git a/src/observable/map/BaseObservableMap.ts b/src/observable/map/BaseObservableMap.ts index 02dedce5..86300439 100644 --- a/src/observable/map/BaseObservableMap.ts +++ b/src/observable/map/BaseObservableMap.ts @@ -19,7 +19,8 @@ import {JoinedMap} from "../map/JoinedMap"; import {MappedMap} from "../map/MappedMap"; import {FilteredMap} from "../map/FilteredMap"; import {SortedMapList} from "../list/SortedMapList.js"; -import {Mapper, Updater, Comparator, Filter} from "./BaseObservableMapDefaults"; +import type {BaseObservableMapDefaults, Mapper, Updater, Comparator, Filter} from "./BaseObservableMapDefaults"; + export interface IMapObserver { onReset(): void; @@ -29,6 +30,13 @@ export interface IMapObserver { } export abstract class BaseObservableMap extends BaseObservable> { + private _defaults: BaseObservableMapDefaults; + + constructor(defaults: BaseObservableMapDefaults) { + super(); + this._defaults = defaults; + } + emitReset(): void { for(let h of this._handlers) { h.onReset(); @@ -54,17 +62,22 @@ export abstract class BaseObservableMap extends BaseObservable): JoinedMap; - abstract mapValues(mapper: Mapper, updater?: Updater): MappedMap; - abstract sortValues(comparator: Comparator): SortedMapList; - abstract filterValues(filter: Filter): FilteredMap; + join(...otherMaps: Array): JoinedMap { + return this._defaults.join(this, ...otherMaps); + } + + mapValues(mapper: Mapper, updater?: Updater): MappedMap { + return this._defaults.mapValues(this, mapper, updater); + } + + sortValues(comparator: Comparator): SortedMapList { + return this._defaults.sortValues(this, comparator); + } + + filterValues(filter: Filter): FilteredMap { + return this._defaults.filterValues(this, filter); + } + abstract [Symbol.iterator](): Iterator<[K, V]>; abstract get size(): number; diff --git a/src/observable/map/BaseObservableMapDefaults.ts b/src/observable/map/BaseObservableMapDefaults.ts index 46d9148e..444b8640 100644 --- a/src/observable/map/BaseObservableMapDefaults.ts +++ b/src/observable/map/BaseObservableMapDefaults.ts @@ -13,15 +13,14 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import {BaseObservableMap} from "./BaseObservableMap"; +import type {BaseObservableMap} from "./BaseObservableMap"; import {FilteredMap} from "./FilteredMap"; import {MappedMap} from "./MappedMap"; import {JoinedMap} from "./JoinedMap"; import {SortedMapList} from "../list/SortedMapList.js"; -// This class is used as a default implementation of -// the respective abstract functions in BaseObservableMap. +// This class provides implementations of functions that are part of BaseObservableMap. // It is kept as its own class in its own file in order to avoid a circular // dependency between the classes that extend BaseObservableMap which are // instantiated here (i.e. `new JoinedMap()`). diff --git a/src/observable/map/FilteredMap.ts b/src/observable/map/FilteredMap.ts index b0ed2e82..267d0d35 100644 --- a/src/observable/map/FilteredMap.ts +++ b/src/observable/map/FilteredMap.ts @@ -16,20 +16,17 @@ limitations under the License. import {BaseObservableMap} from "./BaseObservableMap"; import {SubscriptionHandle} from "../BaseObservable"; -import {BaseObservableMapDefaults, Mapper, Updater, Comparator, Filter} from "./BaseObservableMapDefaults"; -import {JoinedMap} from "./JoinedMap"; -import {MappedMap} from "./MappedMap"; -import {SortedMapList} from "../list/SortedMapList.js"; +import {BaseObservableMapDefaults, Filter} from "./BaseObservableMapDefaults"; + export class FilteredMap extends BaseObservableMap { - private _defaults = new BaseObservableMapDefaults(); private _source: BaseObservableMap; private _filter: Filter; private _included?: Map; private _subscription?: SubscriptionHandle; constructor(source: BaseObservableMap, filter: Filter) { - super(); + super(new BaseObservableMapDefaults()); this._source = source; this._filter = filter; } @@ -162,22 +159,6 @@ export class FilteredMap extends BaseObservableMap { return value; } } - - join(...otherMaps: Array): JoinedMap { - return this._defaults.join(this, ...otherMaps); - } - - mapValues(mapper: Mapper, updater?: Updater): MappedMap{ - return this._defaults.mapValues(this, mapper, updater); - } - - sortValues(comparator: Comparator): SortedMapList { - return this._defaults.sortValues(this, comparator); - } - - filterValues(filter: Filter): FilteredMap { - return this._defaults.filterValues(this, filter); - } } class FilterIterator { diff --git a/src/observable/map/JoinedMap.ts b/src/observable/map/JoinedMap.ts index d4164f79..b343d22f 100644 --- a/src/observable/map/JoinedMap.ts +++ b/src/observable/map/JoinedMap.ts @@ -15,20 +15,16 @@ limitations under the License. */ import {BaseObservableMap} from "./BaseObservableMap"; -import {BaseObservableMapDefaults, Mapper, Updater, Comparator, Filter} from "./BaseObservableMapDefaults"; -import {FilteredMap} from "./FilteredMap"; -import {MappedMap} from "./MappedMap"; -import {SortedMapList} from "../list/SortedMapList.js"; +import {BaseObservableMapDefaults} from "./BaseObservableMapDefaults"; import {SubscriptionHandle} from "../BaseObservable"; export class JoinedMap extends BaseObservableMap { - private _defaults = new BaseObservableMapDefaults(); protected _sources: BaseObservableMap[]; private _subscriptions?: SourceSubscriptionHandler[]; constructor(sources: BaseObservableMap[]) { - super(); + super(new BaseObservableMapDefaults()); this._sources = sources; } @@ -133,23 +129,6 @@ export class JoinedMap extends BaseObservableMap { } return undefined; } - - join(...otherMaps: Array): JoinedMap { - return this._defaults.join(this, ...otherMaps); - } - - mapValues(mapper: Mapper, updater?: Updater): MappedMap { - return this._defaults.mapValues(this, mapper, updater); - } - - sortValues(comparator: Comparator): SortedMapList { - return this._defaults.sortValues(this, comparator); - } - - filterValues(filter: Filter): FilteredMap { - return this._defaults.filterValues(this, filter); - } - } class JoinedIterator implements Iterator<[K, V]> { diff --git a/src/observable/map/LogMap.ts b/src/observable/map/LogMap.ts index 7b857678..6db70f01 100644 --- a/src/observable/map/LogMap.ts +++ b/src/observable/map/LogMap.ts @@ -15,23 +15,19 @@ limitations under the License. */ import {BaseObservableMap} from "./BaseObservableMap"; -import {BaseObservableMapDefaults, Mapper, Updater, Comparator, Filter} from "./BaseObservableMapDefaults"; -import {FilteredMap} from "./FilteredMap"; -import {MappedMap} from "./MappedMap"; -import {JoinedMap} from "./JoinedMap"; -import {SortedMapList} from "../list/SortedMapList.js"; +import {BaseObservableMapDefaults} from "./BaseObservableMapDefaults"; import {SubscriptionHandle} from "../BaseObservable"; import {ILogItem, LabelOrValues} from "../../logging/types"; import {LogLevel} from "../../logging/LogFilter"; + export class LogMap extends BaseObservableMap { - private _defaults = new BaseObservableMapDefaults(); private _source: BaseObservableMap; private _subscription?: SubscriptionHandle; private _log: ILogItem; constructor(source: BaseObservableMap, log: ILogItem) { - super(); + super(new BaseObservableMapDefaults()); this._source = source; this._log = log; } @@ -84,21 +80,4 @@ export class LogMap extends BaseObservableMap { get(key: K): V | undefined{ return this._source.get(key); } - - join(...otherMaps: Array): JoinedMap { - return this._defaults.join(this, ...otherMaps); - } - - mapValues(mapper: Mapper, updater?: Updater): MappedMap { - return this._defaults.mapValues(this, mapper, updater); - } - - sortValues(comparator: Comparator): SortedMapList { - return this._defaults.sortValues(this, comparator); - } - - filterValues(filter: Filter): FilteredMap { - return this._defaults.filterValues(this, filter); - } - } diff --git a/src/observable/map/MappedMap.ts b/src/observable/map/MappedMap.ts index 3d9e3a3c..72115d84 100644 --- a/src/observable/map/MappedMap.ts +++ b/src/observable/map/MappedMap.ts @@ -15,18 +15,15 @@ limitations under the License. */ import {BaseObservableMap} from "./BaseObservableMap"; -import {BaseObservableMapDefaults, Mapper, Updater, Comparator, Filter} from "./BaseObservableMapDefaults"; -import {JoinedMap} from "./JoinedMap"; -import {FilteredMap} from "./FilteredMap"; -import {SortedMapList} from "../list/SortedMapList.js"; +import {BaseObservableMapDefaults, Mapper, Updater} from "./BaseObservableMapDefaults"; import {SubscriptionHandle} from "../BaseObservable"; + /* so a mapped value can emit updates on it's own with this._emitSpontaneousUpdate that is passed in the mapping function how should the mapped value be notified of an update though? and can it then decide to not propagate the update? */ export class MappedMap extends BaseObservableMap { - private _defaults = new BaseObservableMapDefaults(); private _source: BaseObservableMap; private _mapper: Mapper; private _updater?: Updater; @@ -39,7 +36,7 @@ export class MappedMap extends BaseObservableMap { mapper: Mapper, updater?: Updater ) { - super(); + super(new BaseObservableMapDefaults()); this._source = source; this._mapper = mapper; this._updater = updater; @@ -113,20 +110,4 @@ export class MappedMap extends BaseObservableMap { get(key: K): V | undefined { return this._mappedValues.get(key); } - - join(...otherMaps: Array): JoinedMap { - return this._defaults.join(this, ...otherMaps); - } - - mapValues(mapper: Mapper, updater?: Updater): MappedMap{ - return this._defaults.mapValues(this, mapper, updater); - } - - sortValues(comparator: Comparator): SortedMapList { - return this._defaults.sortValues(this, comparator); - } - - filterValues(filter: Filter): FilteredMap { - return this._defaults.filterValues(this, filter); - } } \ No newline at end of file diff --git a/src/observable/map/ObservableMap.ts b/src/observable/map/ObservableMap.ts index 4b98c089..9527ffdd 100644 --- a/src/observable/map/ObservableMap.ts +++ b/src/observable/map/ObservableMap.ts @@ -15,19 +15,14 @@ limitations under the License. */ import {BaseObservableMap} from "./BaseObservableMap"; -import {BaseObservableMapDefaults, Mapper, Updater, Comparator, Filter} from "./BaseObservableMapDefaults"; -import {JoinedMap} from "./JoinedMap"; -import {MappedMap} from "./MappedMap"; -import {FilteredMap} from "./FilteredMap"; -import {SortedMapList} from "../list/SortedMapList.js"; +import {BaseObservableMapDefaults} from "./BaseObservableMapDefaults"; export class ObservableMap extends BaseObservableMap { - private _defaults = new BaseObservableMapDefaults(); private readonly _values: Map; constructor(initialValues?: (readonly [K, V])[]) { - super(); + super(new BaseObservableMapDefaults()); this._values = new Map(initialValues); } @@ -98,22 +93,6 @@ export class ObservableMap extends BaseObservableMap { keys(): Iterator { return this._values.keys(); } - - join(...otherMaps: Array): JoinedMap { - return this._defaults.join(this, ...otherMaps); - } - - mapValues(mapper: Mapper, updater?: Updater): MappedMap { - return this._defaults.mapValues(this, mapper, updater); - } - - sortValues(comparator: Comparator): SortedMapList { - return this._defaults.sortValues(this, comparator); - } - - filterValues(filter: Filter): FilteredMap { - return this._defaults.filterValues(this, filter); - } }; // eslint-disable-next-line @typescript-eslint/explicit-function-return-type