UNPKG

@platform/state

Version:

A small, simple, strongly typed, [rx/observable] state-machine.

56 lines (55 loc) 1.7 kB
import { Subject } from 'rxjs'; import { filter, map, takeUntil } from 'rxjs/operators'; export function syncFrom(args) { const { target } = args; const parent = (args.parent || '').trim(); if (!parent) { const err = `Cannot sync: parent node not specified.`; throw new Error(err); } if (!target.query.exists(parent)) { const err = `Cannot sync: the parent node '${parent}' does not exist in tree '${target.id}'.`; throw new Error(err); } const dispose$ = new Subject(); const dispose = () => { dispose$.next(); dispose$.complete(); }; target.dispose$.subscribe(() => dispose()); if (args.until$) { args.until$.subscribe(() => dispose()); } const source$ = args.source$.pipe(takeUntil(dispose$), filter((e) => e.type === 'TreeState/changed'), map((e) => e.payload)); const change = (to) => { target.change((draft, ctx) => { const node = ctx.findById(parent); if (node) { ctx.children(node, (children) => { const index = children.findIndex((child) => child.id === to.id); if (index === -1) { children.push(to); } else { children[index] = to; } }); } }); }; if (args.initial) { change(args.initial); } source$.subscribe((e) => { change(e.to); }); const syncer = { parent, get isDisposed() { return dispose$.isStopped; }, dispose$, dispose, }; return syncer; }