UNPKG

1.63 kBJavaScriptView Raw
1import { Subject } from 'rxjs';
2import { filter, map, takeUntil } from 'rxjs/operators';
3export function syncFrom(args) {
4 const { target } = args;
5 const parent = (args.parent || '').trim();
6 if (!parent) {
7 const err = `Cannot sync: parent node not specified.`;
8 throw new Error(err);
9 }
10 if (!target.query.exists(parent)) {
11 const err = `Cannot sync: the parent node '${parent}' does not exist in tree '${target.id}'.`;
12 throw new Error(err);
13 }
14 const dispose$ = new Subject();
15 const dispose = () => {
16 dispose$.next();
17 dispose$.complete();
18 };
19 target.dispose$.subscribe(() => dispose());
20 if (args.until$) {
21 args.until$.subscribe(() => dispose());
22 }
23 const source$ = args.source$.pipe(takeUntil(dispose$), filter((e) => e.type === 'TreeState/changed'), map((e) => e.payload));
24 const change = (to) => {
25 target.change((draft, ctx) => {
26 const node = ctx.findById(parent);
27 if (node) {
28 ctx.children(node, (children) => {
29 const index = children.findIndex((child) => child.id === to.id);
30 if (index === -1) {
31 children.push(to);
32 }
33 else {
34 children[index] = to;
35 }
36 });
37 }
38 });
39 };
40 if (args.initial) {
41 change(args.initial);
42 }
43 source$.subscribe((e) => {
44 change(e.to);
45 });
46 const syncer = {
47 parent,
48 dispose$,
49 dispose,
50 };
51 return syncer;
52}