mosx
Version:
Multiview observable state management engine
81 lines (63 loc) • 1.91 kB
text/typescript
import { observable, action, computed, Lambda } from "mobx"
import { MosxTracker } from "./tracker"
export interface ISyncObjectTag {
id: string,
tag: string
}
export class MosxAdmin {
public parent: MosxAdmin | null = null
public children: WeakSet<any> = new WeakSet<any>()
private $tags: Set<string> = new Set<string>()
private $tracker: MosxTracker<any> | null = null
public disposers: Lambda[] = []
get tracker(): MosxTracker | null {
return this.$tracker || this.parent && this.parent.tracker
}
set tracker(tracker: MosxTracker | null) {
this.$tracker = tracker
}
constructor(public target: any, parentNode?: MosxAdmin) {
this.setParent(parentNode || null)
// observe tags change
const tagsDispose = computed(() => this.tags).observe((change) => {
if (this.tracker) {
const { object: obj, ...rest } = change
this.tracker.tagChange(target, rest)
}
})
this.disposers.push(tagsDispose)
}
public addTag(tags: string | string[]) {
if (!Array.isArray(tags)) {
tags = [tags]
}
tags.forEach((tag) => this.$tags.add(tag))
this.tracker && this.tracker.tagChanged()
}
public deleteTag(tag: string) {
this.$tags.delete(tag)
this.tracker && this.tracker.tagChanged()
}
get tags(): Set<string> {
return new Set([...this.$tags, ...(this.parent && this.parent.tags || [])])
}
public setParent(parentNode?: MosxAdmin | null) {
if (parentNode && parentNode === this.parent) { return }
// remove object from old parent node
if (this.parent) {
this.children.delete(this.target)
}
// add object to new parent node
if (parentNode) {
parentNode.children.add(this.target)
}
// save owner
this.parent = parentNode || null
this.tracker && this.tracker.tagChanged()
}
}