Journey functionality
This commit is contained in:
@@ -20,6 +20,8 @@
|
||||
"devDependencies": {
|
||||
"@floating-ui/core": "^1.2.6",
|
||||
"@floating-ui/dom": "^1.2.8",
|
||||
"@types/cytoscape": "^3.19.9",
|
||||
"@types/dompurify": "^3.0.2",
|
||||
"@zerodevx/svelte-toast": "^0.9.3",
|
||||
"eslint": "^8.37.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
@@ -34,8 +36,6 @@
|
||||
"svelte-check": "^3.2.0",
|
||||
"svelte-dnd-action": "^0.9.22",
|
||||
"typescript": "^5.0.3",
|
||||
"@types/cytoscape": "^3.19.9",
|
||||
"@types/dompurify": "^3.0.2",
|
||||
"vite": "^4.3.8",
|
||||
"vite-plugin-glsl": "^1.1.2",
|
||||
"vite-plugin-static-copy": "^0.14.0",
|
||||
@@ -84,6 +84,7 @@
|
||||
"csv-parse": "^5.3.10",
|
||||
"cytoscape": "^3.25.0",
|
||||
"cytoscape-dagre": "^2.5.0",
|
||||
"deep-equal": "^2.2.1",
|
||||
"dompurify": "^3.0.3",
|
||||
"events": "^3.3.0",
|
||||
"framework7": "^8.0.3",
|
||||
|
||||
286
pnpm-lock.yaml
generated
286
pnpm-lock.yaml
generated
@@ -121,6 +121,9 @@ importers:
|
||||
cytoscape-dagre:
|
||||
specifier: ^2.5.0
|
||||
version: 2.5.0(cytoscape@3.25.0)
|
||||
deep-equal:
|
||||
specifier: ^2.2.1
|
||||
version: 2.2.1
|
||||
dompurify:
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3
|
||||
@@ -1372,7 +1375,6 @@ packages:
|
||||
'@codemirror/language': ^6.0.0
|
||||
'@codemirror/state': ^6.0.0
|
||||
'@codemirror/view': ^6.0.0
|
||||
'@lezer/common': ^1.0.0
|
||||
dependencies:
|
||||
'@codemirror/language': 6.6.0
|
||||
'@codemirror/state': 6.2.0
|
||||
@@ -2715,6 +2717,13 @@ packages:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
dev: true
|
||||
|
||||
/array-buffer-byte-length@1.0.0:
|
||||
resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
is-array-buffer: 3.0.2
|
||||
dev: false
|
||||
|
||||
/array-union@2.1.0:
|
||||
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -2765,6 +2774,11 @@ packages:
|
||||
postcss-value-parser: 4.2.0
|
||||
dev: true
|
||||
|
||||
/available-typed-arrays@1.0.5:
|
||||
resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: false
|
||||
|
||||
/aws-sign2@0.7.0:
|
||||
resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==}
|
||||
dev: false
|
||||
@@ -3131,8 +3145,6 @@ packages:
|
||||
'@codemirror/search': 6.4.0
|
||||
'@codemirror/state': 6.2.0
|
||||
'@codemirror/view': 6.11.0
|
||||
transitivePeerDependencies:
|
||||
- '@lezer/common'
|
||||
dev: false
|
||||
|
||||
/codemirror@6.0.1(@lezer/common@1.0.2):
|
||||
@@ -3576,6 +3588,29 @@ packages:
|
||||
dependencies:
|
||||
type-detect: 4.0.8
|
||||
|
||||
/deep-equal@2.2.1:
|
||||
resolution: {integrity: sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ==}
|
||||
dependencies:
|
||||
array-buffer-byte-length: 1.0.0
|
||||
call-bind: 1.0.2
|
||||
es-get-iterator: 1.1.3
|
||||
get-intrinsic: 1.2.0
|
||||
is-arguments: 1.1.1
|
||||
is-array-buffer: 3.0.2
|
||||
is-date-object: 1.0.5
|
||||
is-regex: 1.1.4
|
||||
is-shared-array-buffer: 1.0.2
|
||||
isarray: 2.0.5
|
||||
object-is: 1.1.5
|
||||
object-keys: 1.1.1
|
||||
object.assign: 4.1.4
|
||||
regexp.prototype.flags: 1.5.0
|
||||
side-channel: 1.0.4
|
||||
which-boxed-primitive: 1.0.2
|
||||
which-collection: 1.0.1
|
||||
which-typed-array: 1.1.9
|
||||
dev: false
|
||||
|
||||
/deep-is@0.1.4:
|
||||
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
|
||||
dev: true
|
||||
@@ -3589,6 +3624,14 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/define-properties@1.2.0:
|
||||
resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
has-property-descriptors: 1.0.0
|
||||
object-keys: 1.1.1
|
||||
dev: false
|
||||
|
||||
/delaunator@5.0.0:
|
||||
resolution: {integrity: sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==}
|
||||
dependencies:
|
||||
@@ -3690,6 +3733,20 @@ packages:
|
||||
is-arrayish: 0.2.1
|
||||
dev: true
|
||||
|
||||
/es-get-iterator@1.1.3:
|
||||
resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
get-intrinsic: 1.2.0
|
||||
has-symbols: 1.0.3
|
||||
is-arguments: 1.1.1
|
||||
is-map: 2.0.2
|
||||
is-set: 2.0.2
|
||||
is-string: 1.0.7
|
||||
isarray: 2.0.5
|
||||
stop-iteration-iterator: 1.0.0
|
||||
dev: false
|
||||
|
||||
/es6-promise@3.3.1:
|
||||
resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
|
||||
|
||||
@@ -4295,6 +4352,12 @@ packages:
|
||||
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
|
||||
dev: true
|
||||
|
||||
/for-each@0.3.3:
|
||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||
dependencies:
|
||||
is-callable: 1.2.7
|
||||
dev: false
|
||||
|
||||
/forever-agent@0.6.1:
|
||||
resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==}
|
||||
dev: false
|
||||
@@ -4385,6 +4448,10 @@ packages:
|
||||
/function-bind@1.1.1:
|
||||
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
|
||||
|
||||
/functions-have-names@1.2.3:
|
||||
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
|
||||
dev: false
|
||||
|
||||
/gensync@1.0.0-beta.2:
|
||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -4495,6 +4562,12 @@ packages:
|
||||
resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
|
||||
dev: true
|
||||
|
||||
/gopd@1.0.1:
|
||||
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
|
||||
dependencies:
|
||||
get-intrinsic: 1.2.0
|
||||
dev: false
|
||||
|
||||
/graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
|
||||
@@ -4533,6 +4606,10 @@ packages:
|
||||
har-schema: 2.0.0
|
||||
dev: false
|
||||
|
||||
/has-bigints@1.0.2:
|
||||
resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
|
||||
dev: false
|
||||
|
||||
/has-flag@3.0.0:
|
||||
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -4543,11 +4620,24 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/has-property-descriptors@1.0.0:
|
||||
resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
|
||||
dependencies:
|
||||
get-intrinsic: 1.2.0
|
||||
dev: false
|
||||
|
||||
/has-symbols@1.0.3:
|
||||
resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: false
|
||||
|
||||
/has-tostringtag@1.0.0:
|
||||
resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
has-symbols: 1.0.3
|
||||
dev: false
|
||||
|
||||
/has@1.0.3:
|
||||
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
|
||||
engines: {node: '>= 0.4.0'}
|
||||
@@ -4686,26 +4776,77 @@ packages:
|
||||
/inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
|
||||
/internal-slot@1.0.5:
|
||||
resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
get-intrinsic: 1.2.0
|
||||
has: 1.0.3
|
||||
side-channel: 1.0.4
|
||||
dev: false
|
||||
|
||||
/internmap@2.0.3:
|
||||
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
||||
engines: {node: '>=12'}
|
||||
dev: false
|
||||
|
||||
/is-arguments@1.1.1:
|
||||
resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
has-tostringtag: 1.0.0
|
||||
dev: false
|
||||
|
||||
/is-array-buffer@3.0.2:
|
||||
resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
get-intrinsic: 1.2.0
|
||||
is-typed-array: 1.1.10
|
||||
dev: false
|
||||
|
||||
/is-arrayish@0.2.1:
|
||||
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
|
||||
dev: true
|
||||
|
||||
/is-bigint@1.0.4:
|
||||
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
|
||||
dependencies:
|
||||
has-bigints: 1.0.2
|
||||
dev: false
|
||||
|
||||
/is-binary-path@2.1.0:
|
||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
binary-extensions: 2.2.0
|
||||
|
||||
/is-boolean-object@1.1.2:
|
||||
resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
has-tostringtag: 1.0.0
|
||||
dev: false
|
||||
|
||||
/is-callable@1.2.7:
|
||||
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: false
|
||||
|
||||
/is-core-module@2.12.0:
|
||||
resolution: {integrity: sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==}
|
||||
dependencies:
|
||||
has: 1.0.3
|
||||
|
||||
/is-date-object@1.0.5:
|
||||
resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
has-tostringtag: 1.0.0
|
||||
dev: false
|
||||
|
||||
/is-docker@2.2.1:
|
||||
resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -4732,6 +4873,17 @@ packages:
|
||||
dependencies:
|
||||
is-extglob: 2.1.1
|
||||
|
||||
/is-map@2.0.2:
|
||||
resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==}
|
||||
dev: false
|
||||
|
||||
/is-number-object@1.0.7:
|
||||
resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
has-tostringtag: 1.0.0
|
||||
dev: false
|
||||
|
||||
/is-number@7.0.0:
|
||||
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
@@ -4745,15 +4897,69 @@ packages:
|
||||
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
|
||||
dev: true
|
||||
|
||||
/is-regex@1.1.4:
|
||||
resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
has-tostringtag: 1.0.0
|
||||
dev: false
|
||||
|
||||
/is-set@2.0.2:
|
||||
resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==}
|
||||
dev: false
|
||||
|
||||
/is-shared-array-buffer@1.0.2:
|
||||
resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
dev: false
|
||||
|
||||
/is-stream@2.0.1:
|
||||
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/is-string@1.0.7:
|
||||
resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
has-tostringtag: 1.0.0
|
||||
dev: false
|
||||
|
||||
/is-symbol@1.0.4:
|
||||
resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
has-symbols: 1.0.3
|
||||
dev: false
|
||||
|
||||
/is-typed-array@1.1.10:
|
||||
resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
available-typed-arrays: 1.0.5
|
||||
call-bind: 1.0.2
|
||||
for-each: 0.3.3
|
||||
gopd: 1.0.1
|
||||
has-tostringtag: 1.0.0
|
||||
dev: false
|
||||
|
||||
/is-typedarray@1.0.0:
|
||||
resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
|
||||
dev: false
|
||||
|
||||
/is-weakmap@2.0.1:
|
||||
resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==}
|
||||
dev: false
|
||||
|
||||
/is-weakset@2.0.2:
|
||||
resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
get-intrinsic: 1.2.0
|
||||
dev: false
|
||||
|
||||
/is-wsl@2.2.0:
|
||||
resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -4765,6 +4971,10 @@ packages:
|
||||
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
|
||||
dev: false
|
||||
|
||||
/isarray@2.0.5:
|
||||
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
|
||||
dev: false
|
||||
|
||||
/isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
dev: true
|
||||
@@ -5763,6 +5973,29 @@ packages:
|
||||
resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
|
||||
dev: false
|
||||
|
||||
/object-is@1.1.5:
|
||||
resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.2.0
|
||||
dev: false
|
||||
|
||||
/object-keys@1.1.1:
|
||||
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: false
|
||||
|
||||
/object.assign@4.1.4:
|
||||
resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.2.0
|
||||
has-symbols: 1.0.3
|
||||
object-keys: 1.1.1
|
||||
dev: false
|
||||
|
||||
/once@1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
dependencies:
|
||||
@@ -6182,6 +6415,15 @@ packages:
|
||||
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
|
||||
dev: false
|
||||
|
||||
/regexp.prototype.flags@1.5.0:
|
||||
resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
call-bind: 1.0.2
|
||||
define-properties: 1.2.0
|
||||
functions-have-names: 1.2.3
|
||||
dev: false
|
||||
|
||||
/request@2.88.2:
|
||||
resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==}
|
||||
engines: {node: '>= 6'}
|
||||
@@ -6554,6 +6796,13 @@ packages:
|
||||
/std-env@3.3.3:
|
||||
resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==}
|
||||
|
||||
/stop-iteration-iterator@1.0.0:
|
||||
resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
internal-slot: 1.0.5
|
||||
dev: false
|
||||
|
||||
/stream-transform@3.2.6:
|
||||
resolution: {integrity: sha512-/pyOvaCQFqYTmrFhmMbnAEVo3SsTx1H39eUVPOtYeAgbEUc+rDo7GoP8LbHJgU83mKtzJe/7Nq/ipaAnUOHgJQ==}
|
||||
dev: false
|
||||
@@ -8408,6 +8657,37 @@ packages:
|
||||
webidl-conversions: 3.0.1
|
||||
dev: false
|
||||
|
||||
/which-boxed-primitive@1.0.2:
|
||||
resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
|
||||
dependencies:
|
||||
is-bigint: 1.0.4
|
||||
is-boolean-object: 1.1.2
|
||||
is-number-object: 1.0.7
|
||||
is-string: 1.0.7
|
||||
is-symbol: 1.0.4
|
||||
dev: false
|
||||
|
||||
/which-collection@1.0.1:
|
||||
resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==}
|
||||
dependencies:
|
||||
is-map: 2.0.2
|
||||
is-set: 2.0.2
|
||||
is-weakmap: 2.0.1
|
||||
is-weakset: 2.0.2
|
||||
dev: false
|
||||
|
||||
/which-typed-array@1.1.9:
|
||||
resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
dependencies:
|
||||
available-typed-arrays: 1.0.5
|
||||
call-bind: 1.0.2
|
||||
for-each: 0.3.3
|
||||
gopd: 1.0.1
|
||||
has-tostringtag: 1.0.0
|
||||
is-typed-array: 1.1.10
|
||||
dev: false
|
||||
|
||||
/which@2.0.2:
|
||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
import type ComfyApp from './ComfyApp';
|
||||
import type { ComfyBoxWorkflow } from '$lib/stores/workflowState';
|
||||
import workflowState from '$lib/stores/workflowState';
|
||||
import type { WritableJourneyStateStore } from '$lib/stores/journeyStates';
|
||||
import { calculateWorkflowParamsPatch, resolvePatch, type JourneyPatchNode, type WritableJourneyStateStore } from '$lib/stores/journeyStates';
|
||||
import JourneyRenderer from './JourneyRenderer.svelte';
|
||||
import { Plus } from "svelte-bootstrap-icons";
|
||||
import { getWorkflowRestoreParams, getWorkflowRestoreParamsFromWorkflow } from '$lib/restoreParameters';
|
||||
import notify from '$lib/notify';
|
||||
import selectionState from '$lib/stores/selectionState';
|
||||
|
||||
export let app: ComfyApp;
|
||||
|
||||
@@ -27,20 +28,86 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const nodes = Array.from(journey.iterateBreadthFirst());
|
||||
let parent = null;
|
||||
if (nodes.length > 0)
|
||||
parent = nodes[nodes.length - 1]
|
||||
const workflowParams = getWorkflowRestoreParamsFromWorkflow(workflow)
|
||||
journey.addNode(workflowParams, parent?.id);
|
||||
const activeNode = journey.getActiveNode();
|
||||
|
||||
let journeyNode
|
||||
|
||||
if (activeNode == null) {
|
||||
// add root node
|
||||
if ($journey.root != null) {
|
||||
return;
|
||||
}
|
||||
journeyNode = journey.addNode(workflowParams, null);
|
||||
notify("Pushed a new base workflow state.", { type: "info" })
|
||||
}
|
||||
else {
|
||||
// add patch node
|
||||
const patch = calculateWorkflowParamsPatch(activeNode, workflowParams);
|
||||
const patchedCount = Object.keys(patch).length;
|
||||
if (patchedCount === 0) {
|
||||
notify("No changes were made to active parameters yet.", { type: "warning" })
|
||||
return;
|
||||
}
|
||||
journeyNode = journey.addNode(patch, activeNode);
|
||||
notify(`Pushed new state with ${patchedCount} changes.`, { type: "info" })
|
||||
}
|
||||
|
||||
if (journeyNode != null) {
|
||||
journey.selectNode(journeyNode);
|
||||
}
|
||||
}
|
||||
|
||||
function onSelectNode(e: CustomEvent<{ cyto: cytoscape.Core, node: cytoscape.NodeSingular }>) {
|
||||
const { node } = e.detail;
|
||||
|
||||
const id = node.id();
|
||||
const journeyNode = $journey.nodesByID[id];
|
||||
if (journeyNode == null) {
|
||||
console.error("[ComfyJourneyView] Missing journey node!", id)
|
||||
return;
|
||||
}
|
||||
|
||||
const patch = resolvePatch(journeyNode);
|
||||
|
||||
// ensure reactive state is updated
|
||||
workflow.applyParamsPatch(patch);
|
||||
$workflowState = $workflowState
|
||||
}
|
||||
|
||||
function onHoverNode(e: CustomEvent<{ cyto: cytoscape.Core, node: cytoscape.NodeSingular }>) {
|
||||
const { node } = e.detail;
|
||||
|
||||
const id = node.id();
|
||||
const journeyNode = $journey.nodesByID[id];
|
||||
if (journeyNode == null) {
|
||||
console.error("[ComfyJourneyView] Missing journey node!", id)
|
||||
return;
|
||||
}
|
||||
|
||||
if (journeyNode.type === "patch") {
|
||||
$selectionState.currentPatchHoveredNodes = new Set(Object.keys((journeyNode as JourneyPatchNode).patch))
|
||||
}
|
||||
else {
|
||||
$selectionState.currentPatchHoveredNodes = new Set();
|
||||
}
|
||||
}
|
||||
|
||||
function onHoverNodeOut(e: CustomEvent<{ cyto: cytoscape.Core, node: cytoscape.NodeSingular }>) {
|
||||
$selectionState.currentPatchHoveredNodes = new Set();
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="journey-view">
|
||||
<JourneyRenderer {workflow} {journey} />
|
||||
<JourneyRenderer {workflow} {journey}
|
||||
on:select_node={onSelectNode}
|
||||
on:hover_node={onHoverNode}
|
||||
on:hover_node_out={onHoverNodeOut}
|
||||
/>
|
||||
<div class="bottom">
|
||||
<button class="mode-button ternary"
|
||||
title={"Add new"}
|
||||
disabled={$journey.activeNodeID === null && $journey.root !== null}
|
||||
on:click={doAdd}>
|
||||
<Plus width="100%" height="100%" />
|
||||
</button>
|
||||
|
||||
@@ -4,34 +4,19 @@
|
||||
import { get } from 'svelte/store';
|
||||
import Graph from './graph/Graph.svelte'
|
||||
import type { NodeDataDefinition, EdgeDataDefinition } from 'cytoscape';
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import selectionState from '$lib/stores/selectionState';
|
||||
|
||||
export let workflow: ComfyBoxWorkflow | null = null
|
||||
export let journey: WritableJourneyStateStore | null = null
|
||||
//
|
||||
// const nodes: NodeDataDefinition[] = [
|
||||
// //{ id: 'N1', label: 'Start' },
|
||||
// //{ id: 'N2', label: '4' },
|
||||
// //{ id: 'N4', label: '8' },
|
||||
// //{ id: 'N5', label: '15' },
|
||||
// //{ id: 'N3', label: '16' },
|
||||
// //{ id: 'N6', label: '23' },
|
||||
// //{ id: 'N7', label: '42' },
|
||||
// //{ id: 'N8', label: 'End' }
|
||||
// ]
|
||||
//
|
||||
// const edges: EdgeDataDefinition[] = [
|
||||
// //{ id: 'E1', source: 'N1', target: 'N2' },
|
||||
// //{ id: 'E2', source: 'N2', target: 'N3' },
|
||||
// //{ id: 'E3', source: 'N3', target: 'N6' },
|
||||
// //{ id: 'E4', source: 'N2', target: 'N4' },
|
||||
// //{ id: 'E5', source: 'N4', target: 'N5' },
|
||||
// //{ id: 'E6', source: 'N5', target: 'N4', label: '2' },
|
||||
// //{ id: 'E7', source: 'N5', target: 'N6' },
|
||||
// //{ id: 'E8', source: 'N6', target: 'N7' },
|
||||
// //{ id: 'E9', source: 'N7', target: 'N7', label: '3' },
|
||||
// //{ id: 'E10', source: 'N7', target: 'N8' }
|
||||
// ]
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
select_node: { cyto: cytoscape.Core, node: cytoscape.NodeSingular };
|
||||
hover_node: { cyto: cytoscape.Core, node: cytoscape.NodeSingular };
|
||||
hover_node_out: { cyto: cytoscape.Core, node: cytoscape.NodeSingular };
|
||||
}>();
|
||||
|
||||
let lastSelected = null;
|
||||
|
||||
let lastVersion = -1;
|
||||
|
||||
@@ -48,6 +33,7 @@
|
||||
}
|
||||
|
||||
const journeyState = get(journey);
|
||||
lastSelected = journeyState.activeNodeID;
|
||||
|
||||
const nodes: NodeDataDefinition[] = []
|
||||
const edges: EdgeDataDefinition[] = []
|
||||
@@ -86,17 +72,48 @@
|
||||
|
||||
function onNodeSelected(e: cytoscape.InputEventObject) {
|
||||
console.warn("SELECT", e)
|
||||
const node = e.target;
|
||||
const node = e.target as cytoscape.NodeSingular;
|
||||
journey.selectNode(node.id());
|
||||
|
||||
e.cy.animate({
|
||||
center: { eles: node }
|
||||
}, {
|
||||
duration: 400,
|
||||
easing: "ease-in-out-quad"
|
||||
});
|
||||
|
||||
e.cy.center(node)
|
||||
|
||||
dispatch("select_node", { cyto: e.cy, node })
|
||||
}
|
||||
|
||||
function onNodeHovered(e: cytoscape.InputEventObject) {
|
||||
const node = e.target as cytoscape.NodeSingular;
|
||||
dispatch("hover_node", { cyto: e.cy, node })
|
||||
}
|
||||
|
||||
function onNodeHoveredOut(e: cytoscape.InputEventObject) {
|
||||
const node = e.target as cytoscape.NodeSingular;
|
||||
dispatch("hover_node_out", { cyto: e.cy, node })
|
||||
}
|
||||
|
||||
function onRebuilt(e: CustomEvent<{cyto: cytoscape.Core}>) {
|
||||
const { cyto } = e.detail;
|
||||
|
||||
for (const node of cyto.nodes().components()) {
|
||||
if (node.id() === lastSelected) {
|
||||
// why doesn't passing `selected` work in the ctor?
|
||||
node.select();
|
||||
}
|
||||
}
|
||||
|
||||
$selectionState.currentPatchHoveredNodes = new Set()
|
||||
|
||||
cyto.nodes()
|
||||
.lock()
|
||||
.on("select", onNodeSelected)
|
||||
.on("mouseover", onNodeHovered)
|
||||
.on("mouseout", onNodeHoveredOut)
|
||||
|
||||
const nodes = Array.from(journey.iterateBreadthFirst());
|
||||
if (nodes.length > 0) {
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
class:edit={edit}
|
||||
class:hovered
|
||||
class:selected
|
||||
class:patch-affected={$selectionState.currentPatchHoveredNodes.has(widget.node.id)}
|
||||
class:is-executing={$queueState.runningNodeID && $queueState.runningNodeID == widget.node.id}
|
||||
class:hidden={hidden}
|
||||
>
|
||||
@@ -112,6 +113,10 @@
|
||||
&.selected {
|
||||
background: var(--comfy-widget-selected-background-fill);
|
||||
}
|
||||
|
||||
&.patch-affected {
|
||||
background: var(--secondary-500);
|
||||
}
|
||||
}
|
||||
|
||||
.is-executing {
|
||||
|
||||
@@ -30,9 +30,6 @@
|
||||
cyInstance = null;
|
||||
}
|
||||
|
||||
let _nodes: any[];
|
||||
let _edges: any[];
|
||||
|
||||
function rebuildGraph() {
|
||||
cytoscape.use(dagre)
|
||||
|
||||
@@ -41,6 +38,7 @@
|
||||
style: GraphStyles,
|
||||
wheelSensitivity: 0.1,
|
||||
maxZoom: 1,
|
||||
minZoom: 0.5,
|
||||
})
|
||||
|
||||
cyInstance.on("add", () => {
|
||||
@@ -74,8 +72,7 @@
|
||||
let cyInstance: cytoscape.Core = null
|
||||
</script>
|
||||
|
||||
<div class="cy-graph" {style} bind:this={refElement}>
|
||||
</div>
|
||||
<div class="cy-graph" {style} bind:this={refElement} />
|
||||
|
||||
<style lang="scss">
|
||||
.cy-graph {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { get, writable } from 'svelte/store';
|
||||
import type { Readable, Writable } from 'svelte/store';
|
||||
import type { DragItemID, IDragItem } from './layoutStates';
|
||||
import type { LGraphNode, NodeID, UUID } from '@litegraph-ts/core';
|
||||
import { LiteGraph, type LGraphNode, type NodeID, type UUID } from '@litegraph-ts/core';
|
||||
import type { SerializedAppState } from '$lib/components/ComfyApp';
|
||||
import type { RestoreParamTargets, RestoreParamWorkflowNodeTargets } from '$lib/restoreParameters';
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import deepEqual from "deep-equal";
|
||||
|
||||
export type JourneyNodeType = "root" | "patch";
|
||||
|
||||
@@ -55,7 +56,7 @@ function diffParams(base: RestoreParamWorkflowNodeTargets, updated: RestoreParam
|
||||
const result = {}
|
||||
|
||||
for (const [k, v] of Object.entries(updated)) {
|
||||
if (!(k in base) || base[k].finalValue !== v) {
|
||||
if (!(k in base) || !deepEqual(base[k].finalValue, v.finalValue, { strict: true })) {
|
||||
result[k] = v
|
||||
}
|
||||
}
|
||||
@@ -63,7 +64,7 @@ function diffParams(base: RestoreParamWorkflowNodeTargets, updated: RestoreParam
|
||||
return result;
|
||||
}
|
||||
|
||||
function calculatePatch(parent: JourneyNode, newParams: RestoreParamWorkflowNodeTargets): RestoreParamWorkflowNodeTargets {
|
||||
export function calculateWorkflowParamsPatch(parent: JourneyNode, newParams: RestoreParamWorkflowNodeTargets): RestoreParamWorkflowNodeTargets {
|
||||
const patch = resolvePatch(parent);
|
||||
const diff = diffParams(patch, newParams)
|
||||
return diff;
|
||||
@@ -87,8 +88,9 @@ export type JourneyState = {
|
||||
|
||||
type JourneyStateOps = {
|
||||
clear: () => void,
|
||||
addNode: (params: RestoreParamWorkflowNodeTargets, parent?: JourneyNodeID) => JourneyNode,
|
||||
selectNode: (id?: JourneyNodeID) => void,
|
||||
getActiveNode: () => JourneyNode | null,
|
||||
addNode: (params: RestoreParamWorkflowNodeTargets, parent?: JourneyNodeID | JourneyNode) => JourneyNode,
|
||||
selectNode: (id?: JourneyNodeID | JourneyNode) => void,
|
||||
iterateBreadthFirst: (id?: JourneyNodeID | null) => Iterable<JourneyNode>
|
||||
}
|
||||
|
||||
@@ -112,15 +114,28 @@ function create() {
|
||||
})
|
||||
}
|
||||
|
||||
function getActiveNode(): JourneyNode | null {
|
||||
const state = get(store)
|
||||
if (state.activeNodeID === null)
|
||||
return null;
|
||||
const active = state.nodesByID[state.activeNodeID]
|
||||
if (active == null) {
|
||||
console.error("[journeyStates] Active node not found in graph!", state.activeNodeID);
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
/*
|
||||
* params: full state of widgets in the UI
|
||||
* params: full state or state patch of widgets in the UI
|
||||
* parent: parent node to patch against
|
||||
*/
|
||||
function addNode(params: RestoreParamWorkflowNodeTargets, parent?: JourneyNodeID): JourneyNode {
|
||||
function addNode(params: RestoreParamWorkflowNodeTargets, parent?: JourneyNodeID | JourneyNode): JourneyNode {
|
||||
let _node: JourneyRootNode | JourneyPatchNode;
|
||||
store.update(s => {
|
||||
let parentNode: JourneyNode | null = null
|
||||
if (parent != null) {
|
||||
if (typeof parent === "object")
|
||||
parent = parent.id;
|
||||
parentNode = s.nodesByID[parent];
|
||||
if (parentNode == null) {
|
||||
throw new Error(`Could not find parent node ${parent} to insert into!`)
|
||||
@@ -141,7 +156,7 @@ function create() {
|
||||
type: "patch",
|
||||
parent: parentNode,
|
||||
children: [],
|
||||
patch: calculatePatch(parentNode, params)
|
||||
patch: params,
|
||||
}
|
||||
parentNode.children.push(_node);
|
||||
}
|
||||
@@ -152,9 +167,12 @@ function create() {
|
||||
return _node;
|
||||
}
|
||||
|
||||
function selectNode(id?: JourneyNodeID) {
|
||||
function selectNode(obj?: JourneyNodeID | JourneyNode) {
|
||||
store.update(s => {
|
||||
s.activeNodeID = id;
|
||||
if (typeof obj === "string")
|
||||
s.activeNodeID = obj;
|
||||
else
|
||||
s.activeNodeID = obj.id;
|
||||
return s;
|
||||
})
|
||||
}
|
||||
@@ -201,6 +219,7 @@ function create() {
|
||||
|
||||
return {
|
||||
...store,
|
||||
getActiveNode,
|
||||
clear,
|
||||
addNode,
|
||||
selectNode,
|
||||
|
||||
@@ -24,7 +24,12 @@ export type SelectionState = {
|
||||
/*
|
||||
* Currently hovered nodes.
|
||||
*/
|
||||
currentHoveredNodes: Set<NodeID>
|
||||
currentHoveredNodes: Set<NodeID>,
|
||||
|
||||
/*
|
||||
* Nodes affected by the patch hovered in the journey pane
|
||||
*/
|
||||
currentPatchHoveredNodes: Set<NodeID>
|
||||
}
|
||||
|
||||
type SelectionStateOps = {
|
||||
@@ -38,6 +43,7 @@ const store: Writable<SelectionState> = writable(
|
||||
currentSelectionNodes: [],
|
||||
currentHovered: new Set(),
|
||||
currentHoveredNodes: new Set(),
|
||||
currentPatchHoveredNodes: new Set(),
|
||||
})
|
||||
|
||||
function clear() {
|
||||
@@ -46,12 +52,13 @@ function clear() {
|
||||
currentSelectionNodes: [],
|
||||
currentHovered: new Set(),
|
||||
currentHoveredNodes: new Set(),
|
||||
currentPatchHoveredNodes: new Set(),
|
||||
})
|
||||
}
|
||||
|
||||
const uiStateStore: WritableSelectionStateStore =
|
||||
const selectionStateStore: WritableSelectionStateStore =
|
||||
{
|
||||
...store,
|
||||
clear
|
||||
}
|
||||
export default uiStateStore;
|
||||
export default selectionStateStore;
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { SerializedGraphCanvasState } from '$lib/ComfyGraphCanvas';
|
||||
import { clamp, LGraphNode, type LGraphCanvas, type NodeID, type SerializedLGraph, type UUID, LGraph, LiteGraph, type SlotType, NodeMode } from '@litegraph-ts/core';
|
||||
import { get, writable } from 'svelte/store';
|
||||
import type { Readable, Writable } from 'svelte/store';
|
||||
import { defaultWorkflowAttributes, type SerializedLayoutState, type WritableLayoutStateStore } from './layoutStates';
|
||||
import { defaultWorkflowAttributes, isComfyWidgetNode, type SerializedLayoutState, type WritableLayoutStateStore } from './layoutStates';
|
||||
import ComfyGraph from '$lib/ComfyGraph';
|
||||
import layoutStates from './layoutStates';
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
@@ -14,6 +14,7 @@ import type { ComfyBoxPromptExtraData, PromptID } from '$lib/api';
|
||||
import type { ComfyAPIPromptErrorResponse, ComfyExecutionError } from '$lib/apiErrors';
|
||||
import type { WritableJourneyStateStore } from './journeyState';
|
||||
import journeyStates from './journeyStates';
|
||||
import type { RestoreParamWorkflowNodeTargets } from '$lib/restoreParameters';
|
||||
|
||||
type ActiveCanvas = {
|
||||
canvas: LGraphCanvas | null;
|
||||
@@ -212,6 +213,21 @@ export class ComfyBoxWorkflow {
|
||||
}
|
||||
}
|
||||
|
||||
applyParamsPatch(patch: RestoreParamWorkflowNodeTargets) {
|
||||
for (const [nodeId, source] of Object.entries(patch)) {
|
||||
const node = this.graph.getNodeByIdRecursive(nodeId);
|
||||
if (node == null) {
|
||||
console.error("[applyParamsPatch] Node was missing in patch!!", nodeId, source)
|
||||
continue;
|
||||
}
|
||||
if (!isComfyWidgetNode(node)) {
|
||||
console.error("[applyParamsPatch] Node was not ComfyWidgetNode!!", nodeId, source)
|
||||
continue;
|
||||
}
|
||||
node.setValue(source.finalValue);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a workflow and layout.
|
||||
*
|
||||
|
||||
71
src/tests/stores/journeyStatesTests.ts
Normal file
71
src/tests/stores/journeyStatesTests.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { get } from "svelte/store";
|
||||
import journeyState, { type JourneyState } from "$lib/stores/journeyState"
|
||||
import { expect } from 'vitest';
|
||||
import UnitTest from "../UnitTest";
|
||||
import { Watch } from "@litegraph-ts/nodes-basic";
|
||||
import { ComfyBoxWorkflow } from "$lib/stores/workflowState";
|
||||
import { ComfyNumberNode } from "$lib/nodes/widgets";
|
||||
import { LiteGraph } from "@litegraph-ts/core";
|
||||
import { getWorkflowRestoreParamsFromWorkflow } from "$lib/restoreParameters";
|
||||
import { calculateWorkflowParamsPatch } from "$lib/stores/journeyStates";
|
||||
|
||||
export default class journeyStateTests extends UnitTest {
|
||||
test__patches() {
|
||||
const [workflow, layoutState] = ComfyBoxWorkflow.create()
|
||||
const { graph, journey } = workflow;
|
||||
layoutState.initDefaultLayout() // adds 3 containers
|
||||
|
||||
const widget1 = LiteGraph.createNode(ComfyNumberNode);
|
||||
const widget2 = LiteGraph.createNode(ComfyNumberNode);
|
||||
const watch1 = LiteGraph.createNode(Watch);
|
||||
const watch2 = LiteGraph.createNode(Watch);
|
||||
|
||||
graph.add(widget1)
|
||||
graph.add(watch1)
|
||||
graph.add(widget2)
|
||||
graph.add(watch2)
|
||||
|
||||
widget1.connect(0, watch1, 0);
|
||||
widget2.connect(0, watch2, 0);
|
||||
widget1.setValue(0)
|
||||
widget2.setValue(0)
|
||||
|
||||
let workflowParams = getWorkflowRestoreParamsFromWorkflow(workflow)
|
||||
const root = journey.addNode(workflowParams, null);
|
||||
|
||||
expect(root).toEqual({
|
||||
id: root.id,
|
||||
type: "root",
|
||||
children: [],
|
||||
base: {
|
||||
[widget1.id]: {
|
||||
type: "workflow",
|
||||
finalValue: 0,
|
||||
},
|
||||
[widget2.id]: {
|
||||
type: "workflow",
|
||||
finalValue: 0,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
widget1.setValue(5)
|
||||
|
||||
workflowParams = getWorkflowRestoreParamsFromWorkflow(workflow)
|
||||
const patchParams = calculateWorkflowParamsPatch(root, workflowParams)
|
||||
const patch = journey.addNode(patchParams, root.id);
|
||||
|
||||
expect(patch).toEqual({
|
||||
id: patch.id,
|
||||
type: "patch",
|
||||
parent: root,
|
||||
children: [],
|
||||
patch: {
|
||||
[widget1.id]: {
|
||||
type: "workflow",
|
||||
finalValue: 5
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -4,3 +4,4 @@ export { default as parseA1111Tests } from "./parseA1111Tests"
|
||||
export { default as convertA1111ToStdPromptTests } from "./convertA1111ToStdPromptTests"
|
||||
export { default as convertVanillaWorkflowTest } from "./convertVanillaWorkflowTests"
|
||||
export { default as configStateTests } from "./stores/configStateTests"
|
||||
export { default as journeyStates } from "./stores/journeyStatesTests"
|
||||
|
||||
Reference in New Issue
Block a user