forked from mystiq/hydrogen-web
playing around with live collections
This commit is contained in:
parent
07fed669f6
commit
e49c416fae
1 changed files with 191 additions and 0 deletions
191
src/live-collections/live-map.js
Normal file
191
src/live-collections/live-map.js
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
import EventEmitter from "./event-emitter.js";
|
||||||
|
|
||||||
|
class LiveMap {
|
||||||
|
constructor() {
|
||||||
|
this._handlers = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
emitReset() {
|
||||||
|
for(let h of this._handlers) {
|
||||||
|
h.onReset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// we need batch events, mostly on index based collection though?
|
||||||
|
// maybe we should get started without?
|
||||||
|
emitAdd(key, value) {
|
||||||
|
for(let h of this._handlers) {
|
||||||
|
h.onAdd(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emitChange(key, value, ...params) {
|
||||||
|
for(let h of this._handlers) {
|
||||||
|
h.onChange(key, value, ...params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emitRemove(key, value) {
|
||||||
|
for(let h of this._handlers) {
|
||||||
|
h.onRemove(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribe(handler) {
|
||||||
|
this._handlers.add(handler);
|
||||||
|
return () => {
|
||||||
|
if (handler) {
|
||||||
|
this._handlers.delete(this._handler);
|
||||||
|
handler = null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Symbol.iterator]() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Operator extends LiveMap {
|
||||||
|
constructor(source) {
|
||||||
|
super();
|
||||||
|
this._source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribe(handler) {
|
||||||
|
this.onSubscribe(this._source);
|
||||||
|
let subscription = super.subscribe(handler);
|
||||||
|
let sourceSubscription = this._source.subscribe(this);
|
||||||
|
return () => {
|
||||||
|
sourceSubscription = sourceSubscription && sourceSubscription();
|
||||||
|
subscription = subscription && subscription();
|
||||||
|
// this.onUnsubscribe(); ?
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubscribe() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemove(key, value) {}
|
||||||
|
onAdd(key, value) {}
|
||||||
|
onChange(key, value, params) {}
|
||||||
|
onReset() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class LiveMapCollection extends LiveMap {
|
||||||
|
constructor(initialValues) {
|
||||||
|
super();
|
||||||
|
this._values = new Map(initialValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
updated(key, params) {
|
||||||
|
const value = this._values.get(key);
|
||||||
|
if (value !== undefined) {
|
||||||
|
this._values.add(key, value);
|
||||||
|
this.emitChange(key, value, params);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // or return existing value?
|
||||||
|
}
|
||||||
|
|
||||||
|
add(key, value) {
|
||||||
|
if (!this._values.has(key)) {
|
||||||
|
this._values.add(key, value);
|
||||||
|
this.emitAdd(key, value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false; // or return existing value?
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(key) {
|
||||||
|
const value = this._values.get(key);
|
||||||
|
if (value !== undefined) {
|
||||||
|
this._values.delete(key);
|
||||||
|
this.emitRemove(key, value);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this._values.clear();
|
||||||
|
this.emitReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
get(key) {
|
||||||
|
return this._values.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Symbol.iterator]() {
|
||||||
|
return this._values.entries()[Symbol.iterator];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LiveMapOperator extends Operator {
|
||||||
|
constructor(source, mapper, updater) {
|
||||||
|
super(source);
|
||||||
|
this._mapper = mapper;
|
||||||
|
this._updater = updater;
|
||||||
|
this._mappedValues = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubscribe(source) {
|
||||||
|
for (let [key, value] of source) {
|
||||||
|
const mappedValue = this._mapper(value);
|
||||||
|
this._mappedValues.set(key, mappedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAdd(key, value) {
|
||||||
|
const mappedValue = this._mapper(value);
|
||||||
|
this._mappedValues.set(key, mappedValue);
|
||||||
|
this.emitAdd(key, mappedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemove(key, _value) {
|
||||||
|
const mappedValue = this._mappedValues.get(key);
|
||||||
|
if (this._mappedValues.delete(key)) {
|
||||||
|
this.emitRemove(key, mappedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange(key, value, params) {
|
||||||
|
const mappedValue = this._mappedValues.get(key);
|
||||||
|
if (mappedValue !== undefined) {
|
||||||
|
const newParams = this._updater(value, params);
|
||||||
|
if (newParams !== undefined) {
|
||||||
|
this.emitChange(key, mappedValue, newParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onReset() {
|
||||||
|
this._mappedValues.clear();
|
||||||
|
this.emitReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Symbol.iterator]() {
|
||||||
|
return this._mappedValues.entries()[Symbol.iterator];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FilterOperator extends LiveMapOperator {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class SortSet {
|
||||||
|
constructor(liveMap) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tests() {
|
||||||
|
return {
|
||||||
|
test_for_of(assert) {
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue