File size: 4,886 Bytes
bc20498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { writable, get } from 'svelte/store';
import { adoptUserNodes, updateConnectionLookup, infiniteExtent } from '@xyflow/system';
// we need to sync the user nodes and the internal nodes so that the user can receive the updates
// made by Svelte Flow (like dragging or selecting a node).
export function syncNodeStores(nodesStore, userNodesStore) {
    const nodesStoreSetter = nodesStore.set;
    const userNodesStoreSetter = userNodesStore.set;
    const currentNodesStore = get(nodesStore);
    const currentUserNodesStore = get(userNodesStore);
    // depending how the user initializes the nodes, we need to decide if we want to use
    // the user nodes or the internal nodes for initialization. A user can use a SvelteFlowProvider
    // without providing any nodes, in that case we want to use the nodes passed by the user.
    // By default we are using the store nodes, because they already have the absolute positions.
    const initWithUserNodes = currentNodesStore.length === 0 && currentUserNodesStore.length > 0;
    let val = initWithUserNodes ? currentUserNodesStore : currentNodesStore;
    nodesStore.set(val);
    const _set = (nds) => {
        const updatedNodes = nodesStoreSetter(nds);
        val = updatedNodes;
        userNodesStoreSetter(val);
        return updatedNodes;
    };
    nodesStore.set = userNodesStore.set = _set;
    nodesStore.update = userNodesStore.update = (fn) => _set(fn(val));
}
// same for edges
export function syncEdgeStores(edgesStore, userEdgesStore) {
    const nodesStoreSetter = edgesStore.set;
    const userEdgesStoreSetter = userEdgesStore.set;
    let val = get(userEdgesStore);
    edgesStore.set(val);
    const _set = (eds) => {
        nodesStoreSetter(eds);
        userEdgesStoreSetter(eds);
        val = eds;
    };
    edgesStore.set = userEdgesStore.set = _set;
    edgesStore.update = userEdgesStore.update = (fn) => _set(fn(val));
}
// it is possible to pass a viewport store to SvelteFlow for having more control
// if that's the case we need to sync the internal viewport with the user viewport
export const syncViewportStores = (panZoomStore, viewportStore, userViewportStore) => {
    if (!userViewportStore) {
        return;
    }
    const panZoom = get(panZoomStore);
    const viewportStoreSetter = viewportStore.set;
    const userViewportStoreSetter = userViewportStore.set;
    let val = userViewportStore ? get(userViewportStore) : { x: 0, y: 0, zoom: 1 };
    viewportStore.set(val);
    viewportStore.set = (vp) => {
        viewportStoreSetter(vp);
        userViewportStoreSetter(vp);
        val = vp;
        return vp;
    };
    userViewportStore.set = (vp) => {
        panZoom?.syncViewport(vp);
        viewportStoreSetter(vp);
        userViewportStoreSetter(vp);
        val = vp;
        return vp;
    };
    viewportStore.update = (fn) => {
        viewportStore.set(fn(val));
    };
    userViewportStore.update = (fn) => {
        userViewportStore.set(fn(val));
    };
};
// we are creating a custom store for the internals nodes in order to update the zIndex and positionAbsolute.
// The user only passes in relative positions, so we need to calculate the absolute positions based on the parent nodes.
export const createNodesStore = (nodes, nodeLookup, parentLookup, nodeOrigin = [0, 0], nodeExtent = infiniteExtent) => {
    const { subscribe, set, update } = writable([]);
    let value = nodes;
    let defaults = {};
    let elevateNodesOnSelect = true;
    const _set = (nds) => {
        adoptUserNodes(nds, nodeLookup, parentLookup, {
            elevateNodesOnSelect,
            nodeOrigin,
            nodeExtent,
            defaults,
            checkEquality: false
        });
        value = nds;
        set(value);
        return value;
    };
    const _update = (fn) => _set(fn(value));
    const setDefaultOptions = (options) => {
        defaults = options;
    };
    const setOptions = (options) => {
        elevateNodesOnSelect = options.elevateNodesOnSelect ?? elevateNodesOnSelect;
    };
    _set(value);
    return {
        subscribe,
        set: _set,
        update: _update,
        setDefaultOptions,
        setOptions
    };
};
export const createEdgesStore = (edges, connectionLookup, edgeLookup, defaultOptions) => {
    const { subscribe, set, update } = writable([]);
    let value = edges;
    let defaults = defaultOptions || {};
    const _set = (eds) => {
        const nextEdges = defaults ? eds.map((edge) => ({ ...defaults, ...edge })) : eds;
        updateConnectionLookup(connectionLookup, edgeLookup, nextEdges);
        value = nextEdges;
        set(value);
    };
    const _update = (fn) => _set(fn(value));
    const setDefaultOptions = (options) => {
        defaults = options;
    };
    _set(value);
    return {
        subscribe,
        set: _set,
        update: _update,
        setDefaultOptions
    };
};