ソースを参照

split plugin context (wip)

dsehnal 4 年 前
コミット
acf13fa46f

+ 374 - 8
package-lock.json

@@ -5,7 +5,7 @@
   "requires": true,
   "packages": {
     "": {
-      "version": "2.0.0-dev.3",
+      "version": "2.0.0-dev.4",
       "license": "MIT",
       "dependencies": {
         "@types/argparse": "^1.0.38",
@@ -31,7 +31,7 @@
         "react-dom": "^17.0.1",
         "rxjs": "^6.6.3",
         "swagger-ui-dist": "^3.37.2",
-        "tslib": "^2.0.3",
+        "tslib": "^2.1.0",
         "util.promisify": "^1.0.1",
         "xhr2": "^0.2.0"
       },
@@ -92,6 +92,12 @@
         "node": ">=8"
       }
     },
+    "node_modules/@ardatan/aggregate-error/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@babel/code-frame": {
       "version": "7.10.4",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
@@ -1217,6 +1223,12 @@
         "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-codegen/add/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-codegen/cli": {
       "version": "1.19.4",
       "resolved": "https://registry.npmjs.org/@graphql-codegen/cli/-/cli-1.19.4.tgz",
@@ -1324,6 +1336,12 @@
       "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
       "dev": true
     },
+    "node_modules/@graphql-codegen/cli/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-codegen/core": {
       "version": "1.17.9",
       "resolved": "https://registry.npmjs.org/@graphql-codegen/core/-/core-1.17.9.tgz",
@@ -1339,6 +1357,12 @@
         "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-codegen/core/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-codegen/plugin-helpers": {
       "version": "1.18.2",
       "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.18.2.tgz",
@@ -1408,6 +1432,12 @@
       "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
       "dev": true
     },
+    "node_modules/@graphql-codegen/plugin-helpers/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-codegen/time": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/@graphql-codegen/time/-/time-2.0.2.tgz",
@@ -1449,6 +1479,12 @@
         "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-codegen/typescript-graphql-files-modules/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-codegen/typescript-graphql-request": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-graphql-request/-/typescript-graphql-request-2.0.3.tgz",
@@ -1465,6 +1501,12 @@
         "graphql-tag": "^2.0.0"
       }
     },
+    "node_modules/@graphql-codegen/typescript-graphql-request/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-codegen/typescript-operations": {
       "version": "1.17.12",
       "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-operations/-/typescript-operations-1.17.12.tgz",
@@ -1481,6 +1523,18 @@
         "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-codegen/typescript-operations/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
+    "node_modules/@graphql-codegen/typescript/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-codegen/visitor-plugin-common": {
       "version": "1.17.21",
       "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.17.21.tgz",
@@ -1518,6 +1572,12 @@
       "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
       "dev": true
     },
+    "node_modules/@graphql-codegen/visitor-plugin-common/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/apollo-engine-loader": {
       "version": "6.2.5",
       "resolved": "https://registry.npmjs.org/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-6.2.5.tgz",
@@ -1546,6 +1606,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/apollo-engine-loader/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/batch-execute": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/@graphql-tools/batch-execute/-/batch-execute-7.0.0.tgz",
@@ -1575,6 +1641,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/batch-execute/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/code-file-loader": {
       "version": "6.2.6",
       "resolved": "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-6.2.6.tgz",
@@ -1603,6 +1675,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/code-file-loader/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/delegate": {
       "version": "7.0.7",
       "resolved": "https://registry.npmjs.org/@graphql-tools/delegate/-/delegate-7.0.7.tgz",
@@ -1635,6 +1713,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/delegate/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/git-loader": {
       "version": "6.2.5",
       "resolved": "https://registry.npmjs.org/@graphql-tools/git-loader/-/git-loader-6.2.5.tgz",
@@ -1663,6 +1747,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/git-loader/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/github-loader": {
       "version": "6.2.5",
       "resolved": "https://registry.npmjs.org/@graphql-tools/github-loader/-/github-loader-6.2.5.tgz",
@@ -1692,6 +1782,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/github-loader/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/graphql-file-loader": {
       "version": "6.2.6",
       "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-file-loader/-/graphql-file-loader-6.2.6.tgz",
@@ -1720,6 +1816,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/graphql-file-loader/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/graphql-tag-pluck": {
       "version": "6.3.0",
       "resolved": "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-6.3.0.tgz",
@@ -1754,6 +1856,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/graphql-tag-pluck/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/import": {
       "version": "6.2.5",
       "resolved": "https://registry.npmjs.org/@graphql-tools/import/-/import-6.2.5.tgz",
@@ -1767,6 +1875,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/import/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/json-file-loader": {
       "version": "6.2.6",
       "resolved": "https://registry.npmjs.org/@graphql-tools/json-file-loader/-/json-file-loader-6.2.6.tgz",
@@ -1794,6 +1908,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/json-file-loader/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/load": {
       "version": "6.2.5",
       "resolved": "https://registry.npmjs.org/@graphql-tools/load/-/load-6.2.5.tgz",
@@ -1828,6 +1948,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/load/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/merge": {
       "version": "6.2.6",
       "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-6.2.6.tgz",
@@ -1856,6 +1982,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/merge/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/optimize": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@graphql-tools/optimize/-/optimize-1.0.1.tgz",
@@ -1868,6 +2000,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/optimize/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/prisma-loader": {
       "version": "6.2.7",
       "resolved": "https://registry.npmjs.org/@graphql-tools/prisma-loader/-/prisma-loader-6.2.7.tgz",
@@ -1916,6 +2054,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/prisma-loader/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/relay-operation-optimizer": {
       "version": "6.3.0",
       "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.3.0.tgz",
@@ -1944,6 +2088,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/relay-operation-optimizer/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/schema": {
       "version": "7.1.2",
       "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-7.1.2.tgz",
@@ -1971,6 +2121,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/schema/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/url-loader": {
       "version": "6.6.0",
       "resolved": "https://registry.npmjs.org/@graphql-tools/url-loader/-/url-loader-6.6.0.tgz",
@@ -2013,6 +2169,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/url-loader/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/utils": {
       "version": "6.2.4",
       "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-6.2.4.tgz",
@@ -2043,6 +2205,12 @@
       "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
       "dev": true
     },
+    "node_modules/@graphql-tools/utils/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@graphql-tools/wrap": {
       "version": "7.0.4",
       "resolved": "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-7.0.4.tgz",
@@ -2073,6 +2241,12 @@
         "graphql": "^14.0.0 || ^15.0.0"
       }
     },
+    "node_modules/@graphql-tools/wrap/node_modules/tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+      "dev": true
+    },
     "node_modules/@iarna/toml": {
       "version": "2.2.5",
       "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz",
@@ -15663,9 +15837,9 @@
       }
     },
     "node_modules/tslib": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
-      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
+      "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
     },
     "node_modules/tsutils": {
       "version": "3.17.1",
@@ -17571,6 +17745,14 @@
       "dev": true,
       "requires": {
         "tslib": "~2.0.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
+        }
       }
     },
     "@babel/code-frame": {
@@ -18522,6 +18704,14 @@
       "requires": {
         "@graphql-codegen/plugin-helpers": "^1.18.2",
         "tslib": "~2.0.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
+        }
       }
     },
     "@graphql-codegen/cli": {
@@ -18628,6 +18818,12 @@
               "dev": true
             }
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -18641,6 +18837,14 @@
         "@graphql-tools/merge": "^6",
         "@graphql-tools/utils": "^6",
         "tslib": "~2.0.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
+        }
       }
     },
     "@graphql-codegen/plugin-helpers": {
@@ -18714,6 +18918,12 @@
               "dev": true
             }
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -18737,6 +18947,14 @@
         "@graphql-codegen/visitor-plugin-common": "^1.17.21",
         "auto-bind": "~4.0.0",
         "tslib": "~2.0.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
+        }
       }
     },
     "@graphql-codegen/typescript-graphql-files-modules": {
@@ -18747,6 +18965,14 @@
       "requires": {
         "@graphql-codegen/plugin-helpers": "^1.18.2",
         "tslib": "~2.0.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
+        }
       }
     },
     "@graphql-codegen/typescript-graphql-request": {
@@ -18759,6 +18985,14 @@
         "@graphql-codegen/visitor-plugin-common": "^1.17.20",
         "auto-bind": "~4.0.0",
         "tslib": "~2.0.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
+        }
       }
     },
     "@graphql-codegen/typescript-operations": {
@@ -18772,6 +19006,14 @@
         "@graphql-codegen/visitor-plugin-common": "^1.17.20",
         "auto-bind": "~4.0.0",
         "tslib": "~2.0.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
+        }
       }
     },
     "@graphql-codegen/visitor-plugin-common": {
@@ -18809,6 +19051,12 @@
               "dev": true
             }
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -18833,6 +19081,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -18858,6 +19112,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -18882,6 +19142,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -18910,6 +19176,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -18934,6 +19206,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -18959,6 +19237,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -18983,6 +19267,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -19010,6 +19300,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -19021,6 +19317,14 @@
       "requires": {
         "resolve-from": "5.0.0",
         "tslib": "~2.0.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
+        }
       }
     },
     "@graphql-tools/json-file-loader": {
@@ -19043,6 +19347,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -19073,6 +19383,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -19097,6 +19413,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -19107,6 +19429,14 @@
       "dev": true,
       "requires": {
         "tslib": "~2.0.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
+        }
       }
     },
     "@graphql-tools/prisma-loader": {
@@ -19150,6 +19480,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -19174,6 +19510,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -19197,6 +19539,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -19235,6 +19583,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -19266,6 +19620,12 @@
               "dev": true
             }
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -19292,6 +19652,12 @@
             "camel-case": "4.1.2",
             "tslib": "~2.0.1"
           }
+        },
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==",
+          "dev": true
         }
       }
     },
@@ -30176,9 +30542,9 @@
       }
     },
     "tslib": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
-      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
+      "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
     },
     "tsutils": {
       "version": "3.17.1",

+ 1 - 1
package.json

@@ -144,7 +144,7 @@
     "react-dom": "^17.0.1",
     "rxjs": "^6.6.3",
     "swagger-ui-dist": "^3.37.2",
-    "tslib": "^2.0.3",
+    "tslib": "^2.1.0",
     "util.promisify": "^1.0.1",
     "xhr2": "^0.2.0"
   }

+ 28 - 28
src/apps/docking-viewer/index.ts

@@ -5,31 +5,32 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import '../../mol-util/polyfill';
-import { createPlugin } from '../../mol-plugin';
-import { DefaultPluginSpec } from '../../mol-plugin/spec';
-import './index.html';
-import { PluginContext } from '../../mol-plugin/context';
+import { Structure } from '../../mol-model/structure';
+import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
+import { PluginStateObject as PSO, PluginStateTransform } from '../../mol-plugin-state/objects';
+import { createPlugin } from '../../mol-plugin-ui';
+import { PluginUIContext } from '../../mol-plugin-ui/context';
+import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout';
+import { DefaultPluginUISpec, PluginUISpec } from '../../mol-plugin-ui/spec';
+import { PluginBehaviors } from '../../mol-plugin/behavior';
 import { PluginCommands } from '../../mol-plugin/commands';
-import { PluginSpec } from '../../mol-plugin/spec';
 import { PluginConfig } from '../../mol-plugin/config';
-import { ObjectKeys } from '../../mol-util/type-helpers';
-import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout';
-import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
-import { Structure } from '../../mol-model/structure';
-import { PluginStateTransform, PluginStateObject as PSO } from '../../mol-plugin-state/objects';
-import { ParamDefinition as PD } from '../../mol-util/param-definition';
-import { Task } from '../../mol-task';
+import { PluginSpec } from '../../mol-plugin/spec';
 import { StateObject } from '../../mol-state';
-import { ViewportComponent, StructurePreset, ShowButtons } from './viewport';
-import { PluginBehaviors } from '../../mol-plugin/behavior';
-import { ColorNames } from '../../mol-util/color/names';
+import { Task } from '../../mol-task';
 import { Color } from '../../mol-util/color';
+import { ColorNames } from '../../mol-util/color/names';
+import { ParamDefinition as PD } from '../../mol-util/param-definition';
+import '../../mol-util/polyfill';
+import { ObjectKeys } from '../../mol-util/type-helpers';
+import './index.html';
+import { ShowButtons, StructurePreset, ViewportComponent } from './viewport';
 
 require('mol-plugin-ui/skin/light.scss');
 
 export { PLUGIN_VERSION as version } from '../../mol-plugin/version';
-export { setProductionMode, setDebugMode } from '../../mol-util/debug';
+export { setDebugMode, setProductionMode } from '../../mol-util/debug';
+export { Viewer as DockingViewer };
 
 const DefaultViewerOptions = {
     extensions: ObjectKeys({}),
@@ -53,7 +54,7 @@ const DefaultViewerOptions = {
 };
 
 class Viewer {
-    plugin: PluginContext
+    plugin: PluginUIContext
 
     constructor(elementOrId: string | HTMLElement, colors = [Color(0x992211), Color(0xDDDDDD)], showButtons = true) {
         const o = { ...DefaultViewerOptions, ...{
@@ -70,10 +71,10 @@ class Viewer {
             viewportShowSelectionMode: false,
             viewportShowAnimation: false,
         } };
-        const defaultSpec = DefaultPluginSpec();
+        const defaultSpec = DefaultPluginUISpec();
 
-        const spec: PluginSpec = {
-            actions: [...defaultSpec.actions],
+        const spec: PluginUISpec = {
+            actions: defaultSpec.actions,
             behaviors: [
                 PluginSpec.Behavior(PluginBehaviors.Representation.HighlightLoci, { mark: false }),
                 PluginSpec.Behavior(PluginBehaviors.Representation.DefaultLociLabelProvider),
@@ -83,7 +84,7 @@ class Viewer {
                 PluginSpec.Behavior(PluginBehaviors.CustomProps.Interactions),
                 PluginSpec.Behavior(PluginBehaviors.CustomProps.SecondaryStructure),
             ],
-            animations: [...defaultSpec.animations || []],
+            animations: defaultSpec.animations,
             customParamEditors: defaultSpec.customParamEditors,
             layout: {
                 initial: {
@@ -91,15 +92,15 @@ class Viewer {
                     showControls: o.layoutShowControls,
                     controlsDisplay: o.layoutControlsDisplay,
                 },
+            },
+            components: {
+                ...defaultSpec.components,
                 controls: {
-                    ...defaultSpec.layout && defaultSpec.layout.controls,
+                    ...defaultSpec.components?.controls,
                     top: o.layoutShowSequence ? undefined : 'none',
                     bottom: o.layoutShowLog ? undefined : 'none',
                     left: o.layoutShowLeftPanel ? undefined : 'none',
-                }
-            },
-            components: {
-                ...defaultSpec.components,
+                },
                 remoteState: o.layoutShowRemoteState ? 'default' : 'none',
                 viewport: {
                     view: ViewportComponent
@@ -210,4 +211,3 @@ const MergeStructures = PluginStateTransform.BuiltIn({
 });
 
 (window as any).DockingViewer = Viewer;
-export { Viewer as DockingViewer };

+ 35 - 35
src/apps/viewer/index.ts

@@ -5,43 +5,43 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import '../../mol-util/polyfill';
-import { createPlugin } from '../../mol-plugin';
-import { DefaultPluginSpec } from '../../mol-plugin/spec';
-import './index.html';
-import './embedded.html';
-import './favicon.ico';
-import { PluginContext } from '../../mol-plugin/context';
-import { PluginCommands } from '../../mol-plugin/commands';
-import { PluginSpec } from '../../mol-plugin/spec';
-import { DownloadStructure, PdbDownloadProvider } from '../../mol-plugin-state/actions/structure';
-import { PluginConfig } from '../../mol-plugin/config';
-import { CellPack } from '../../extensions/cellpack';
-import { RCSBAssemblySymmetry, RCSBValidationReport } from '../../extensions/rcsb';
-import { PDBeStructureQualityReport } from '../../extensions/pdbe';
-import { Asset } from '../../mol-util/assets';
-import { ObjectKeys } from '../../mol-util/type-helpers';
-import { PluginState } from '../../mol-plugin/state';
-import { DownloadDensity } from '../../mol-plugin-state/actions/volume';
-import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout';
-import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
 import { ANVILMembraneOrientation } from '../../extensions/anvil/behavior';
+import { CellPack } from '../../extensions/cellpack';
 import { DnatcoConfalPyramids } from '../../extensions/dnatco';
 import { G3DFormat, G3dProvider } from '../../extensions/g3d/format';
+import { Mp4Export } from '../../extensions/mp4-export';
+import { PDBeStructureQualityReport } from '../../extensions/pdbe';
+import { RCSBAssemblySymmetry, RCSBValidationReport } from '../../extensions/rcsb';
+import { DownloadStructure, PdbDownloadProvider } from '../../mol-plugin-state/actions/structure';
+import { DownloadDensity } from '../../mol-plugin-state/actions/volume';
+import { StructureRepresentationPresetProvider } from '../../mol-plugin-state/builder/structure/representation-preset';
 import { DataFormatProvider } from '../../mol-plugin-state/formats/provider';
+import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
 import { BuildInVolumeFormat } from '../../mol-plugin-state/formats/volume';
-import { Color } from '../../mol-util/color';
-import { StateObjectSelector } from '../../mol-state';
+import { createVolumeRepresentationParams } from '../../mol-plugin-state/helpers/volume-representation-params';
 import { PluginStateObject } from '../../mol-plugin-state/objects';
 import { StateTransforms } from '../../mol-plugin-state/transforms';
-import { createVolumeRepresentationParams } from '../../mol-plugin-state/helpers/volume-representation-params';
-import { Mp4Export } from '../../extensions/mp4-export';
-import { StructureRepresentationPresetProvider } from '../../mol-plugin-state/builder/structure/representation-preset';
+import { createPlugin } from '../../mol-plugin-ui';
+import { PluginUIContext } from '../../mol-plugin-ui/context';
+import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout';
+import { DefaultPluginUISpec, PluginUISpec } from '../../mol-plugin-ui/spec';
+import { PluginCommands } from '../../mol-plugin/commands';
+import { PluginConfig } from '../../mol-plugin/config';
+import { PluginSpec } from '../../mol-plugin/spec';
+import { PluginState } from '../../mol-plugin/state';
+import { StateObjectSelector } from '../../mol-state';
+import { Asset } from '../../mol-util/assets';
+import { Color } from '../../mol-util/color';
+import '../../mol-util/polyfill';
+import { ObjectKeys } from '../../mol-util/type-helpers';
+import './embedded.html';
+import './favicon.ico';
+import './index.html';
 
 require('mol-plugin-ui/skin/light.scss');
 
 export { PLUGIN_VERSION as version } from '../../mol-plugin/version';
-export { setProductionMode, setDebugMode } from '../../mol-util/debug';
+export { setDebugMode, setProductionMode } from '../../mol-util/debug';
 
 const CustomFormats = [
     ['g3d', G3dProvider] as const
@@ -86,14 +86,14 @@ const DefaultViewerOptions = {
 type ViewerOptions = typeof DefaultViewerOptions;
 
 export class Viewer {
-    plugin: PluginContext
+    plugin: PluginUIContext
 
     constructor(elementOrId: string | HTMLElement, options: Partial<ViewerOptions> = {}) {
         const o = { ...DefaultViewerOptions, ...options };
-        const defaultSpec = DefaultPluginSpec();
+        const defaultSpec = DefaultPluginUISpec();
 
-        const spec: PluginSpec = {
-            actions: [...defaultSpec.actions],
+        const spec: PluginUISpec = {
+            actions: defaultSpec.actions,
             behaviors: [
                 ...defaultSpec.behaviors,
                 ...o.extensions.map(e => Extensions[e]),
@@ -107,15 +107,15 @@ export class Viewer {
                     showControls: o.layoutShowControls,
                     controlsDisplay: o.layoutControlsDisplay,
                 },
+            },
+            components: {
+                ...defaultSpec.components,
                 controls: {
-                    ...defaultSpec.layout && defaultSpec.layout.controls,
+                    ...defaultSpec.components?.controls,
                     top: o.layoutShowSequence ? undefined : 'none',
                     bottom: o.layoutShowLog ? undefined : 'none',
                     left: o.layoutShowLeftPanel ? undefined : 'none',
-                }
-            },
-            components: {
-                ...defaultSpec.components,
+                },
                 remoteState: o.layoutShowRemoteState ? 'default' : 'none',
             },
             config: [

+ 0 - 1
src/cli/state-docs/index.ts

@@ -18,7 +18,6 @@ _.StateTransforms.Data.Download.id;
 
 // Empty plugin context
 const ctx = new PluginContext({
-    actions: [],
     behaviors: []
 });
 

+ 15 - 17
src/examples/alpha-orbitals/index.ts

@@ -4,25 +4,25 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
+import { BehaviorSubject } from 'rxjs';
+import { debounceTime, skip } from 'rxjs/operators';
+import { AlphaOrbital, Basis } from '../../extensions/alpha-orbitals/data-model';
 import { SphericalBasisOrder } from '../../extensions/alpha-orbitals/spherical-functions';
 import { BasisAndOrbitals, CreateOrbitalDensityVolume, CreateOrbitalRepresentation3D, CreateOrbitalVolume, StaticBasisAndOrbitals } from '../../extensions/alpha-orbitals/transforms';
-import { createPluginAsync } from '../../mol-plugin';
-import { DefaultPluginSpec } from '../../mol-plugin/spec';
+import { canComputeGrid3dOnGPU } from '../../mol-gl/compute/grid3d';
 import { PluginStateObject } from '../../mol-plugin-state/objects';
+import { createPluginAsync } from '../../mol-plugin-ui';
+import { PluginUIContext } from '../../mol-plugin-ui/context';
+import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec';
+import { PluginCommands } from '../../mol-plugin/commands';
 import { PluginConfig } from '../../mol-plugin/config';
-import { PluginContext } from '../../mol-plugin/context';
 import { StateObjectSelector, StateTransformer } from '../../mol-state';
 import { Color } from '../../mol-util/color';
 import { ColorNames } from '../../mol-util/color/names';
 import { ParamDefinition } from '../../mol-util/param-definition';
 import { mountControls } from './controls';
 import { DemoMoleculeSDF, DemoOrbitals } from './example-data';
-import { BehaviorSubject } from 'rxjs';
-import { debounceTime, skip } from 'rxjs/operators';
 import './index.html';
-import { Basis, AlphaOrbital } from '../../extensions/alpha-orbitals/data-model';
-import { PluginCommands } from '../../mol-plugin/commands';
-import { canComputeGrid3dOnGPU } from '../../mol-gl/compute/grid3d';
 require('mol-plugin-ui/skin/light.scss');
 
 interface DemoInput {
@@ -50,10 +50,10 @@ type Selectors = {
 }
 
 export class AlphaOrbitalsExample {
-    plugin: PluginContext;
+    plugin: PluginUIContext;
 
     async init(target: string | HTMLElement) {
-        const defaultSpec = DefaultPluginSpec();
+        const defaultSpec = DefaultPluginUISpec();
         this.plugin = await createPluginAsync(typeof target === 'string' ? document.getElementById(target)! : target, {
             ...defaultSpec,
             layout: {
@@ -61,15 +61,13 @@ export class AlphaOrbitalsExample {
                     isExpanded: false,
                     showControls: false
                 },
-                controls: { left: 'none', right: 'none', top: 'none', bottom: 'none' },
             },
             components: {
-                viewport: {
-                    canvas3d: {
-                        camera: {
-                            helper: { axes: { name: 'off', params: { } } }
-                        }
-                    }
+                controls: { left: 'none', right: 'none', top: 'none', bottom: 'none' },
+            },
+            canvas3d: {
+                camera: {
+                    helper: { axes: { name: 'off', params: { } } }
                 }
             },
             config: [

+ 7 - 10
src/examples/basic-wrapper/index.ts

@@ -4,39 +4,36 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
+import { PDBeStructureQualityReport } from '../../extensions/pdbe';
 import { EmptyLoci } from '../../mol-model/loci';
 import { StructureSelection } from '../../mol-model/structure';
-import { createPlugin } from '../../mol-plugin';
-import { DefaultPluginSpec } from '../../mol-plugin/spec';
 import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in/model-index';
 import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
+import { createPlugin } from '../../mol-plugin-ui';
+import { PluginUIContext } from '../../mol-plugin-ui/context';
+import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec';
 import { PluginCommands } from '../../mol-plugin/commands';
-import { PluginContext } from '../../mol-plugin/context';
 import { Script } from '../../mol-script/script';
+import { Asset } from '../../mol-util/assets';
 import { Color } from '../../mol-util/color';
 import { StripedResidues } from './coloring';
 import { CustomToastMessage } from './controls';
 import './index.html';
 import { buildStaticSuperposition, dynamicSuperpositionTest, StaticSuperpositionTestData } from './superposition';
-import { PDBeStructureQualityReport } from '../../extensions/pdbe';
-import { Asset } from '../../mol-util/assets';
 require('mol-plugin-ui/skin/light.scss');
 
 type LoadParams = { url: string, format?: BuiltInTrajectoryFormat, isBinary?: boolean, assemblyId?: string }
 
 class BasicWrapper {
-    plugin: PluginContext;
+    plugin: PluginUIContext;
 
     init(target: string | HTMLElement) {
         this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
-            ...DefaultPluginSpec(),
+            ...DefaultPluginUISpec(),
             layout: {
                 initial: {
                     isExpanded: false,
                     showControls: false
-                },
-                controls: {
-                    // left: 'none'
                 }
             },
             components: {

+ 8 - 6
src/examples/lighting/index.ts

@@ -5,13 +5,13 @@
  */
 
 import { Canvas3DProps } from '../../mol-canvas3d/canvas3d';
-import { createPlugin } from '../../mol-plugin';
-import { DefaultPluginSpec } from '../../mol-plugin/spec';
 import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
+import { createPlugin } from '../../mol-plugin-ui';
+import { PluginUIContext } from '../../mol-plugin-ui/context';
+import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec';
 import { PluginCommands } from '../../mol-plugin/commands';
-import { PluginContext } from '../../mol-plugin/context';
-import './index.html';
 import { Asset } from '../../mol-util/assets';
+import './index.html';
 require('mol-plugin-ui/skin/light.scss');
 
 type LoadParams = { url: string, format?: BuiltInTrajectoryFormat, isBinary?: boolean, assemblyId?: string }
@@ -62,7 +62,7 @@ const Canvas3DPresets = {
 type Canvas3DPreset = keyof typeof Canvas3DPresets
 
 class LightingDemo {
-    plugin: PluginContext;
+    plugin: PluginUIContext;
 
     private radius = 5;
     private bias = 1.1;
@@ -70,12 +70,14 @@ class LightingDemo {
 
     init(target: string | HTMLElement) {
         this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
-            ...DefaultPluginSpec(),
+            ...DefaultPluginUISpec(),
             layout: {
                 initial: {
                     isExpanded: false,
                     showControls: false
                 },
+            },
+            components: {
                 controls: { left: 'none', right: 'none', top: 'none', bottom: 'none' }
             }
         });

+ 5 - 5
src/examples/proteopedia-wrapper/index.ts

@@ -6,15 +6,15 @@
 
 import * as ReactDOM from 'react-dom';
 import { Canvas3DProps, DefaultCanvas3DParams } from '../../mol-canvas3d/canvas3d';
-import { createPlugin } from '../../mol-plugin';
-import { DefaultPluginSpec } from '../../mol-plugin/spec';
 import { AnimateModelIndex } from '../../mol-plugin-state/animation/built-in/model-index';
 import { createStructureRepresentationParams } from '../../mol-plugin-state/helpers/structure-representation-params';
 import { PluginStateObject, PluginStateObject as PSO } from '../../mol-plugin-state/objects';
 import { StateTransforms } from '../../mol-plugin-state/transforms';
+import { createPlugin } from '../../mol-plugin-ui';
+import { PluginUIContext } from '../../mol-plugin-ui/context';
+import { DefaultPluginUISpec } from '../../mol-plugin-ui/spec';
 import { CreateVolumeStreamingInfo, InitVolumeStreaming } from '../../mol-plugin/behavior/dynamic/volume-streaming/transformers';
 import { PluginCommands } from '../../mol-plugin/commands';
-import { PluginContext } from '../../mol-plugin/context';
 import { PluginState } from '../../mol-plugin/state';
 import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
 import { StateBuilder, StateObject, StateSelection } from '../../mol-state';
@@ -41,13 +41,13 @@ class MolStarProteopediaWrapper {
         modelInfo: this._ev<ModelInfo>()
     };
 
-    plugin: PluginContext;
+    plugin: PluginUIContext;
 
     init(target: string | HTMLElement, options?: {
         customColorList?: number[]
     }) {
         this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
-            ...DefaultPluginSpec(),
+            ...DefaultPluginUISpec(),
             animations: [
                 AnimateModelIndex
             ],

+ 2 - 2
src/examples/proteopedia-wrapper/ui/controls.tsx

@@ -6,12 +6,12 @@
 
 import * as React from 'react';
 import * as ReactDOM from 'react-dom';
+import { PluginUIContext } from '../../../mol-plugin-ui/context';
 import { PluginContextContainer } from '../../../mol-plugin-ui/plugin';
 import { TransformUpdaterControl } from '../../../mol-plugin-ui/state/update-transform';
-import { PluginContext } from '../../../mol-plugin/context';
 import { StateElements } from '../helpers';
 
-export function volumeStreamingControls(plugin: PluginContext, parent: Element) {
+export function volumeStreamingControls(plugin: PluginUIContext, parent: Element) {
     ReactDOM.render(<PluginContextContainer plugin={plugin}>
         <TransformUpdaterControl nodeRef={StateElements.VolumeStreaming} />
     </PluginContextContainer>, parent);

+ 5 - 5
src/mol-plugin-ui/base.tsx

@@ -7,15 +7,15 @@
 
 import * as React from 'react';
 import { Observable, Subscription } from 'rxjs';
-import { PluginContext } from '../mol-plugin/context';
+import { PluginUIContext } from './context';
 import { Button, ColorAccent } from './controls/common';
 import { Icon, ArrowRightSvg, ArrowDropDownSvg } from './controls/icons';
 
-export const PluginReactContext = React.createContext(void 0 as any as PluginContext);
+export const PluginReactContext = React.createContext(void 0 as any as PluginUIContext);
 
 export abstract class PluginUIComponent<P = {}, S = {}, SS = {}> extends React.Component<P, S, SS> {
     static contextType = PluginReactContext;
-    readonly plugin: PluginContext;
+    readonly plugin: PluginUIContext;
 
     private subs: Subscription[] | undefined = void 0;
 
@@ -33,7 +33,7 @@ export abstract class PluginUIComponent<P = {}, S = {}, SS = {}> extends React.C
     protected init?(): void;
 
     constructor(props: P, context?: any) {
-        super(props, context);
+        super(props);
         this.plugin = context;
         if (this.init) this.init();
     }
@@ -41,7 +41,7 @@ export abstract class PluginUIComponent<P = {}, S = {}, SS = {}> extends React.C
 
 export abstract class PurePluginUIComponent<P = {}, S = {}, SS = {}> extends React.PureComponent<P, S, SS> {
     static contextType = PluginReactContext;
-    readonly plugin: PluginContext;
+    readonly plugin: PluginUIContext;
 
     private subs: Subscription[] | undefined = void 0;
 

+ 40 - 0
src/mol-plugin-ui/context.ts

@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+
+import { PluginContext } from '../mol-plugin/context';
+import { PluginUISpec } from './spec';
+import { StateTransformParameters } from './state/common';
+
+export class PluginUIContext extends PluginContext {
+    readonly customParamEditors = new Map<string, StateTransformParameters.Class>();
+
+    private initDataActions() {
+        for (const a of this.spec.actions) {
+            this.state.data.actions.add(a.action);
+        }
+    }
+
+    private initCustomParamEditors() {
+        if (!this.spec.customParamEditors) return;
+
+        for (const [t, e] of this.spec.customParamEditors) {
+            this.customParamEditors.set(t.id, e);
+        }
+    }
+
+    dispose(options?: { doNotForceWebGLContextLoss?: boolean }) {
+        super.dispose(options);
+        this.layout.dispose();
+    }
+
+    constructor(public spec: PluginUISpec) {
+        super(spec);
+
+        this.initDataActions();
+        this.initCustomParamEditors();
+    }
+}

+ 2 - 2
src/mol-plugin-ui/controls/parameters.tsx

@@ -7,7 +7,6 @@
 
 import * as React from 'react';
 import { Mat4, Vec2, Vec3 } from '../../mol-math/linear-algebra';
-import { PluginContext } from '../../mol-plugin/context';
 import { Color } from '../../mol-util/color';
 import { ColorListName, ColorListOptions, ColorListOptionsScale, ColorListOptionsSet, getColorListFromName } from '../../mol-util/color/lists';
 import { Legend as LegendData } from '../../mol-util/legend';
@@ -26,6 +25,7 @@ import { LineGraphComponent } from './line-graph/line-graph-component';
 import { Slider, Slider2 } from './slider';
 import { Asset } from '../../mol-util/assets';
 import { ColorListEntry } from '../../mol-util/color/color';
+import { PluginUIContext } from '../context';
 
 export type ParameterControlsCategoryFilter = string | null | (string | null)[]
 
@@ -104,7 +104,7 @@ export class ParameterControls<P extends PD.Params> extends React.PureComponent<
     }
 }
 
-export class ParameterMappingControl<S, T> extends PluginUIComponent<{ mapping: ParamMapping<S, T, PluginContext> }> {
+export class ParameterMappingControl<S, T> extends PluginUIComponent<{ mapping: ParamMapping<S, T, PluginUIContext> }> {
     setSettings = (p: { param: PD.Base<any>, name: string, value: any }, old: any) => {
         const values = { ...old, [p.name]: p.value };
         const t = this.props.mapping.update(values, this.plugin);

+ 7 - 7
src/mol-plugin/index.ts → src/mol-plugin-ui/index.ts

@@ -7,20 +7,20 @@
 
 import * as React from 'react';
 import * as ReactDOM from 'react-dom';
-import { Plugin } from '../mol-plugin-ui/plugin';
-import { PluginContext } from './context';
-import { DefaultPluginSpec, PluginSpec } from './spec';
+import { Plugin } from './plugin';
+import { PluginUIContext } from './context';
+import { DefaultPluginUISpec, PluginUISpec } from './spec';
 
-export function createPlugin(target: HTMLElement, spec?: PluginSpec): PluginContext {
-    const ctx = new PluginContext(spec || DefaultPluginSpec());
+export function createPlugin(target: HTMLElement, spec?: PluginUISpec): PluginUIContext {
+    const ctx = new PluginUIContext(spec || DefaultPluginUISpec());
     ctx.init();
     ReactDOM.render(React.createElement(Plugin, { plugin: ctx }), target);
     return ctx;
 }
 
 /** Returns the instance of the plugin after all behaviors have been initialized */
-export async function createPluginAsync(target: HTMLElement, spec?: PluginSpec) {
-    const ctx = new PluginContext(spec || DefaultPluginSpec());
+export async function createPluginAsync(target: HTMLElement, spec?: PluginUISpec) {
+    const ctx = new PluginUIContext(spec || DefaultPluginUISpec());
     const init = ctx.init();
     ReactDOM.render(React.createElement(Plugin, { plugin: ctx }), target);
     await init;

+ 5 - 6
src/mol-plugin-ui/plugin.tsx

@@ -7,7 +7,6 @@
 
 import { List } from 'immutable';
 import * as React from 'react';
-import { PluginContext } from '../mol-plugin/context';
 import { formatTime } from '../mol-util';
 import { LogEntry } from '../mol-util/log-entry';
 import { PluginReactContext, PluginUIComponent } from './base';
@@ -18,8 +17,9 @@ import { BackgroundTaskProgress, OverlayTaskProgress } from './task';
 import { Toasts } from './toast';
 import { Viewport, ViewportControls } from './viewport';
 import { PluginCommands } from '../mol-plugin/commands';
+import { PluginUIContext } from './context';
 
-export class Plugin extends React.Component<{ plugin: PluginContext }, {}> {
+export class Plugin extends React.Component<{ plugin: PluginUIContext }, {}> {
     region(kind: 'left' | 'right' | 'bottom' | 'main', element: JSX.Element) {
         return <div className={`msp-layout-region msp-layout-${kind}`}>
             <div className='msp-layout-static'>
@@ -35,7 +35,7 @@ export class Plugin extends React.Component<{ plugin: PluginContext }, {}> {
     }
 }
 
-export class PluginContextContainer extends React.Component<{ plugin: PluginContext }> {
+export class PluginContextContainer extends React.Component<{ plugin: PluginUIContext }> {
     render() {
         return <PluginReactContext.Provider value={this.props.plugin}>
             <div className='msp-plugin'>
@@ -62,7 +62,7 @@ class Layout extends PluginUIComponent {
 
     get layoutVisibilityClassName() {
         const layout = this.plugin.layout.state;
-        const controls = (this.plugin.spec.layout && this.plugin.spec.layout.controls) || {};
+        const controls = this.plugin.spec.components?.controls ?? {};
 
         const classList: string[] = [];
         if (controls.top === 'none' || !layout.showControls || layout.regionState.top === 'hidden') {
@@ -127,7 +127,7 @@ class Layout extends PluginUIComponent {
 
     render() {
         const layout = this.plugin.layout.state;
-        const controls = this.plugin.spec.layout?.controls || {};
+        const controls = this.plugin.spec.components?.controls || {};
         const viewport = this.plugin.spec.components?.viewport?.view || DefaultViewport;
 
         return <div className='msp-plugin' onDrop={this.onDrop} onDragOver={this.onDragOver}>
@@ -149,7 +149,6 @@ export class ControlsWrapper extends PluginUIComponent {
     render() {
         const StructureTools = this.plugin.spec.components?.structureTools || DefaultStructureTools;
         return <div className='msp-scrollable-container'>
-            {/* <CurrentObject /> */}
             <StructureTools />
         </div>;
     }

+ 100 - 0
src/mol-plugin-ui/spec.ts

@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { StateActions } from '../mol-plugin-state/actions';
+import { AssignColorVolume } from '../mol-plugin-state/actions/volume';
+import { StateTransforms } from '../mol-plugin-state/transforms';
+import { StateTransformParameters } from '../mol-plugin-ui/state/common';
+import { DefaultPluginSpec, PluginSpec } from '../mol-plugin/spec';
+import { StateAction, StateTransformer } from '../mol-state';
+import { BoxifyVolumeStreaming, CreateVolumeStreamingBehavior, InitVolumeStreaming } from '../mol-plugin/behavior/dynamic/volume-streaming/transformers';
+
+export { PluginUISpec };
+
+interface PluginUISpec extends PluginSpec {
+    actions: PluginUISpec.Action[],
+    customParamEditors?: [StateAction | StateTransformer, StateTransformParameters.Class][],
+    components?: {
+        controls?: PluginUISpec.LayoutControls
+        remoteState?: 'none' | 'default',
+        structureTools?: React.ComponentClass,
+        viewport?: {
+            view?: React.ComponentClass,
+            controls?: React.ComponentClass
+        },
+        hideTaskOverlay?: boolean
+    },
+}
+
+namespace PluginUISpec {
+    export interface Action {
+        action: StateAction | StateTransformer,
+        customControl?: StateTransformParameters.Class,
+        autoUpdate?: boolean
+    }
+
+    export function Action(action: StateAction | StateTransformer, params?: { customControl?: StateTransformParameters.Class, autoUpdate?: boolean }): Action {
+        return { action, customControl: params && params.customControl, autoUpdate: params && params.autoUpdate };
+    }
+
+    export interface LayoutControls {
+        top?: React.ComponentClass | 'none',
+        left?: React.ComponentClass | 'none',
+        right?: React.ComponentClass | 'none',
+        bottom?: React.ComponentClass | 'none'
+    }
+}
+
+export const DefaultPluginUISpec = (): PluginUISpec => ({
+    ...DefaultPluginSpec(),
+    actions: [
+        PluginUISpec.Action(StateActions.Structure.DownloadStructure),
+        PluginUISpec.Action(StateActions.Structure.AddTrajectory),
+        PluginUISpec.Action(StateActions.Volume.DownloadDensity),
+        PluginUISpec.Action(StateActions.DataFormat.DownloadFile),
+        PluginUISpec.Action(StateActions.DataFormat.OpenFiles),
+        PluginUISpec.Action(StateActions.Structure.EnableModelCustomProps),
+        PluginUISpec.Action(StateActions.Structure.EnableStructureCustomProps),
+
+        // Volume streaming
+        PluginUISpec.Action(InitVolumeStreaming),
+        PluginUISpec.Action(BoxifyVolumeStreaming),
+        PluginUISpec.Action(CreateVolumeStreamingBehavior),
+
+        PluginUISpec.Action(StateTransforms.Data.Download),
+        PluginUISpec.Action(StateTransforms.Data.ParseCif),
+        PluginUISpec.Action(StateTransforms.Data.ParseCcp4),
+        PluginUISpec.Action(StateTransforms.Data.ParseDsn6),
+
+        PluginUISpec.Action(StateTransforms.Model.TrajectoryFromMmCif),
+        PluginUISpec.Action(StateTransforms.Model.TrajectoryFromCifCore),
+        PluginUISpec.Action(StateTransforms.Model.TrajectoryFromPDB),
+        PluginUISpec.Action(StateTransforms.Model.TransformStructureConformation),
+        PluginUISpec.Action(StateTransforms.Model.StructureFromModel),
+        PluginUISpec.Action(StateTransforms.Model.StructureFromTrajectory),
+        PluginUISpec.Action(StateTransforms.Model.ModelFromTrajectory),
+        PluginUISpec.Action(StateTransforms.Model.StructureSelectionFromScript),
+        PluginUISpec.Action(StateTransforms.Representation.StructureRepresentation3D),
+        PluginUISpec.Action(StateTransforms.Representation.StructureSelectionsDistance3D),
+        PluginUISpec.Action(StateTransforms.Representation.StructureSelectionsAngle3D),
+        PluginUISpec.Action(StateTransforms.Representation.StructureSelectionsDihedral3D),
+        PluginUISpec.Action(StateTransforms.Representation.StructureSelectionsLabel3D),
+        PluginUISpec.Action(StateTransforms.Representation.StructureSelectionsOrientation3D),
+        PluginUISpec.Action(StateTransforms.Representation.ModelUnitcell3D),
+        PluginUISpec.Action(StateTransforms.Representation.ExplodeStructureRepresentation3D),
+        PluginUISpec.Action(StateTransforms.Representation.UnwindStructureAssemblyRepresentation3D),
+        PluginUISpec.Action(StateTransforms.Representation.OverpaintStructureRepresentation3DFromScript),
+        PluginUISpec.Action(StateTransforms.Representation.TransparencyStructureRepresentation3DFromScript),
+
+        PluginUISpec.Action(AssignColorVolume),
+        PluginUISpec.Action(StateTransforms.Volume.VolumeFromCcp4),
+        PluginUISpec.Action(StateTransforms.Volume.VolumeFromDsn6),
+        PluginUISpec.Action(StateTransforms.Volume.VolumeFromCube),
+        PluginUISpec.Action(StateTransforms.Volume.VolumeFromDx),
+        PluginUISpec.Action(StateTransforms.Representation.VolumeRepresentation3D),
+    ]
+});

+ 5 - 5
src/mol-plugin-ui/viewport/simple-settings.tsx

@@ -9,13 +9,13 @@ import { produce } from 'immer';
 import * as React from 'react';
 import { Canvas3DParams, Canvas3DProps } from '../../mol-canvas3d/canvas3d';
 import { PluginCommands } from '../../mol-plugin/commands';
-import { PluginContext } from '../../mol-plugin/context';
 import { StateTransform } from '../../mol-state';
 import { Color } from '../../mol-util/color';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { ParamMapping } from '../../mol-util/param-mapping';
 import { Mutable } from '../../mol-util/type-helpers';
 import { PluginUIComponent } from '../base';
+import { PluginUIContext } from '../context';
 import { ParameterMappingControl } from '../controls/parameters';
 import { ViewportHelpContent } from './help';
 
@@ -71,9 +71,9 @@ const SimpleSettingsParams = {
 
 type SimpleSettingsParams = typeof SimpleSettingsParams
 const SimpleSettingsMapping = ParamMapping({
-    params: (ctx: PluginContext) => {
+    params: (ctx: PluginUIContext) => {
         const params = PD.clone(SimpleSettingsParams);
-        const controls = ctx.spec.layout?.controls;
+        const controls = ctx.spec.components?.controls;
         if (controls) {
             const options: [LayoutOptions, string][] = [];
             if (controls.top !== 'none') options.push(['sequence', LayoutOptions.sequence]);
@@ -83,8 +83,8 @@ const SimpleSettingsMapping = ParamMapping({
         }
         return params;
     },
-    target(ctx: PluginContext) {
-        const c = ctx.spec.layout?.controls;
+    target(ctx: PluginUIContext) {
+        const c = ctx.spec.components?.controls;
         const r = ctx.layout.state.regionState;
         const layout: SimpleSettingsParams['layout']['defaultValue'] = [];
         if (r.top !== 'hidden' && (!c || c.top !== 'none')) layout.push('sequence');

+ 15 - 35
src/mol-plugin/context.ts

@@ -8,44 +8,51 @@
 import produce, { setAutoFreeze } from 'immer';
 import { List } from 'immutable';
 import { merge, Subscription } from 'rxjs';
+import { filter, take } from 'rxjs/operators';
 import { Canvas3D, Canvas3DContext, DefaultCanvas3DParams } from '../mol-canvas3d/canvas3d';
+import { resizeCanvas } from '../mol-canvas3d/util';
+import { Vec2 } from '../mol-math/linear-algebra';
 import { CustomProperty } from '../mol-model-props/common/custom-property';
 import { Model, Structure } from '../mol-model/structure';
 import { DataBuilder } from '../mol-plugin-state/builder/data';
 import { StructureBuilder } from '../mol-plugin-state/builder/structure';
 import { DataFormatRegistry } from '../mol-plugin-state/formats/registry';
 import { StructureSelectionQueryRegistry } from '../mol-plugin-state/helpers/structure-selection-query';
+import { PluginAnimationManager } from '../mol-plugin-state/manager/animation';
 import { CameraManager } from '../mol-plugin-state/manager/camera';
 import { InteractivityManager } from '../mol-plugin-state/manager/interactivity';
 import { LociLabel, LociLabelManager } from '../mol-plugin-state/manager/loci-label';
+import { PluginStateSnapshotManager } from '../mol-plugin-state/manager/snapshots';
 import { StructureComponentManager } from '../mol-plugin-state/manager/structure/component';
 import { StructureFocusManager } from '../mol-plugin-state/manager/structure/focus';
 import { StructureHierarchyManager } from '../mol-plugin-state/manager/structure/hierarchy';
 import { StructureHierarchyRef } from '../mol-plugin-state/manager/structure/hierarchy-state';
 import { StructureMeasurementManager } from '../mol-plugin-state/manager/structure/measurement';
 import { StructureSelectionManager } from '../mol-plugin-state/manager/structure/selection';
-import { PluginUIComponent } from '../mol-plugin-ui/base';
-import { StateTransformParameters } from '../mol-plugin-ui/state/common';
+import { VolumeHierarchyManager } from '../mol-plugin-state/manager/volume/hierarchy';
+import { LeftPanelTabName, PluginLayout } from './layout';
 import { Representation } from '../mol-repr/representation';
 import { StructureRepresentationRegistry } from '../mol-repr/structure/registry';
 import { VolumeRepresentationRegistry } from '../mol-repr/volume/registry';
 import { StateTransform } from '../mol-state';
-import { Task, RuntimeContext } from '../mol-task';
+import { RuntimeContext, Task } from '../mol-task';
 import { ColorTheme } from '../mol-theme/color';
 import { SizeTheme } from '../mol-theme/size';
 import { ThemeRegistryContext } from '../mol-theme/theme';
+import { AssetManager } from '../mol-util/assets';
 import { Color } from '../mol-util/color';
 import { ajaxGet } from '../mol-util/data-source';
 import { isDebugMode, isProductionMode } from '../mol-util/debug';
 import { ModifiersKeys } from '../mol-util/input/input-observer';
 import { LogEntry } from '../mol-util/log-entry';
+import { objectForEach } from '../mol-util/object';
 import { RxEventHelper } from '../mol-util/rx-event-helper';
+import { PluginAnimationLoop } from './animation-loop';
 import { BuiltInPluginBehaviors } from './behavior';
 import { PluginBehavior } from './behavior/behavior';
 import { PluginCommandManager } from './command';
 import { PluginCommands } from './commands';
 import { PluginConfig, PluginConfigManager } from './config';
-import { LeftPanelTabName, PluginLayout } from './layout';
 import { PluginSpec } from './spec';
 import { PluginState } from './state';
 import { SubstructureParentHelper } from './util/substructure-parent-helper';
@@ -53,15 +60,6 @@ import { TaskManager } from './util/task-manager';
 import { PluginToastManager } from './util/toast';
 import { ViewportScreenshotHelper } from './util/viewport-screenshot';
 import { PLUGIN_VERSION, PLUGIN_VERSION_DATE } from './version';
-import { AssetManager } from '../mol-util/assets';
-import { PluginStateSnapshotManager } from '../mol-plugin-state/manager/snapshots';
-import { PluginAnimationManager } from '../mol-plugin-state/manager/animation';
-import { objectForEach } from '../mol-util/object';
-import { VolumeHierarchyManager } from '../mol-plugin-state/manager/volume/hierarchy';
-import { filter, take } from 'rxjs/operators';
-import { Vec2 } from '../mol-math/linear-algebra';
-import { PluginAnimationLoop } from './animation-loop';
-import { resizeCanvas } from '../mol-canvas3d/util';
 
 export class PluginContext {
     runTask = <T>(task: Task<T>, params?: { useOverlay?: boolean }) => this.managers.task.run(task, params);
@@ -71,7 +69,7 @@ export class PluginContext {
         return object;
     }
 
-    private subs: Subscription[] = [];
+    protected subs: Subscription[] = [];
 
     private disposed = false;
     private ev = RxEventHelper.create();
@@ -109,8 +107,8 @@ export class PluginContext {
 
     readonly canvas3dContext: Canvas3DContext | undefined;
     readonly canvas3d: Canvas3D | undefined;
-    readonly animationLoop = new PluginAnimationLoop(this);
     readonly layout = new PluginLayout(this);
+    readonly animationLoop = new PluginAnimationLoop(this);
 
     readonly representation = {
         structure: {
@@ -176,9 +174,8 @@ export class PluginContext {
 
     readonly customModelProperties = new CustomProperty.Registry<Model>();
     readonly customStructureProperties = new CustomProperty.Registry<Structure>();
-    readonly customParamEditors = new Map<string, StateTransformParameters.Class>();
 
-    readonly customStructureControls = new Map<string, { new(): PluginUIComponent<any, any, any> }>();
+    readonly customStructureControls = new Map<string, { new(): any /* contructible react components */ }>();
     readonly genericRepresentationControls = new Map<string, (selection: StructureHierarchyManager['selection']) => [StructureHierarchyRef[], string]>();
 
     /**
@@ -200,7 +197,7 @@ export class PluginContext {
             (this.canvas3dContext as Canvas3DContext) = Canvas3DContext.fromCanvas(canvas, { antialias, preserveDrawingBuffer, pixelScale, pickScale, enableWboit });
             (this.canvas3d as Canvas3D) = Canvas3D.create(this.canvas3dContext!);
             this.canvas3dInit.next(true);
-            let props = this.spec.components?.viewport?.canvas3d;
+            let props = this.spec.canvas3d;
 
             const backgroundColor = Color(0xFCFBF9);
             if (!props) {
@@ -294,7 +291,6 @@ export class PluginContext {
         this.ev.dispose();
         this.state.dispose();
         this.managers.task.dispose();
-        this.layout.dispose();
         this.helpers.substructureParent.dispose();
 
         objectForEach(this.managers, m => (m as any)?.dispose?.());
@@ -385,12 +381,6 @@ export class PluginContext {
         }
     }
 
-    private initDataActions() {
-        for (const a of this.spec.actions) {
-            this.state.data.actions.add(a.action);
-        }
-    }
-
     private initAnimations() {
         if (!this.spec.animations) return;
         for (const anim of this.spec.animations) {
@@ -398,14 +388,6 @@ export class PluginContext {
         }
     }
 
-    private initCustomParamEditors() {
-        if (!this.spec.customParamEditors) return;
-
-        for (const [t, e] of this.spec.customParamEditors) {
-            this.customParamEditors.set(t.id, e);
-        }
-    }
-
     async init() {
         this.subs.push(this.events.log.subscribe(e => this.log.entries = this.log.entries.push(e)));
 
@@ -417,9 +399,7 @@ export class PluginContext {
         (this.managers.lociLabels as LociLabelManager) = new LociLabelManager(this);
         (this.builders.structure as StructureBuilder) = new StructureBuilder(this);
 
-        this.initDataActions();
         this.initAnimations();
-        this.initCustomParamEditors();
 
         await this.initBehaviors();
 

+ 2 - 2
src/mol-plugin/layout.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -7,8 +7,8 @@
 
 import { ParamDefinition as PD } from '../mol-util/param-definition';
 import { StatefulPluginComponent } from '../mol-plugin-state/component';
-import { PluginContext } from './context';
 import { PluginCommands } from './commands';
+import { PluginContext } from './context';
 
 const regionStateOptions = [
     ['full', 'Full'],

+ 11 - 95
src/mol-plugin/spec.ts

@@ -1,65 +1,37 @@
 /**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { StateTransformer, StateAction } from '../mol-state';
-import { StateTransformParameters } from '../mol-plugin-ui/state/common';
-import { PluginLayoutStateProps } from './layout';
-import { PluginStateAnimation } from '../mol-plugin-state/animation/model';
-import { PluginConfigItem } from './config';
 import { PartialCanvas3DProps } from '../mol-canvas3d/canvas3d';
-import { DataFormatProvider } from '../mol-plugin-state/formats/provider';
-import { StateActions } from '../mol-plugin-state/actions';
-import { StateTransforms } from '../mol-plugin-state/transforms';
-import { VolumeStreamingCustomControls } from '../mol-plugin-ui/custom/volume';
-import { PluginBehaviors } from './behavior';
-import { StructureFocusRepresentation } from './behavior/dynamic/selection/structure-focus-representation';
-import { BoxifyVolumeStreaming, CreateVolumeStreamingBehavior, InitVolumeStreaming } from './behavior/dynamic/volume-streaming/transformers';
-import { AssignColorVolume } from '../mol-plugin-state/actions/volume';
-import { AnimateModelIndex } from '../mol-plugin-state/animation/built-in/model-index';
 import { AnimateAssemblyUnwind } from '../mol-plugin-state/animation/built-in/assembly-unwind';
 import { AnimateCameraSpin } from '../mol-plugin-state/animation/built-in/camera-spin';
+import { AnimateModelIndex } from '../mol-plugin-state/animation/built-in/model-index';
 import { AnimateStateSnapshots } from '../mol-plugin-state/animation/built-in/state-snapshots';
+import { PluginStateAnimation } from '../mol-plugin-state/animation/model';
+import { DataFormatProvider } from '../mol-plugin-state/formats/provider';
+import { StateTransformer } from '../mol-state';
+import { PluginBehaviors } from './behavior';
+import { StructureFocusRepresentation } from './behavior/dynamic/selection/structure-focus-representation';
+import { PluginConfigItem } from './config';
+import { PluginLayoutStateProps } from './layout';
 
 export { PluginSpec };
 
 interface PluginSpec {
-    actions: PluginSpec.Action[],
     behaviors: PluginSpec.Behavior[],
     animations?: PluginStateAnimation[],
-    customParamEditors?: [StateAction | StateTransformer, StateTransformParameters.Class][],
-    customFormats?: [string, DataFormatProvider][]
+    customFormats?: [string, DataFormatProvider][],
+    canvas3d?: PartialCanvas3DProps,
     layout?: {
         initial?: Partial<PluginLayoutStateProps>,
-        controls?: PluginSpec.LayoutControls
-    },
-    components?: {
-        remoteState?: 'none' | 'default',
-        structureTools?: React.ComponentClass,
-        viewport?: {
-            view?: React.ComponentClass,
-            controls?: React.ComponentClass,
-            canvas3d?: PartialCanvas3DProps
-        },
-        hideTaskOverlay?: boolean
     },
     config?: [PluginConfigItem, unknown][]
 }
 
 namespace PluginSpec {
-    export interface Action {
-        action: StateAction | StateTransformer,
-        customControl?: StateTransformParameters.Class,
-        autoUpdate?: boolean
-    }
-
-    export function Action(action: StateAction | StateTransformer, params?: { customControl?: StateTransformParameters.Class, autoUpdate?: boolean }): Action {
-        return { action, customControl: params && params.customControl, autoUpdate: params && params.autoUpdate };
-    }
-
     export interface Behavior {
         transformer: StateTransformer,
         defaultParams?: any
@@ -68,62 +40,9 @@ namespace PluginSpec {
     export function Behavior<T extends StateTransformer>(transformer: T, defaultParams: Partial<StateTransformer.Params<T>> = {}): Behavior {
         return { transformer, defaultParams };
     }
-
-    export interface LayoutControls {
-        top?: React.ComponentClass | 'none',
-        left?: React.ComponentClass | 'none',
-        right?: React.ComponentClass | 'none',
-        bottom?: React.ComponentClass | 'none'
-    }
 }
 
 export const DefaultPluginSpec = (): PluginSpec => ({
-    actions: [
-        PluginSpec.Action(StateActions.Structure.DownloadStructure),
-        PluginSpec.Action(StateActions.Structure.AddTrajectory),
-        PluginSpec.Action(StateActions.Volume.DownloadDensity),
-        PluginSpec.Action(StateActions.DataFormat.DownloadFile),
-        PluginSpec.Action(StateActions.DataFormat.OpenFiles),
-        PluginSpec.Action(StateActions.Structure.EnableModelCustomProps),
-        PluginSpec.Action(StateActions.Structure.EnableStructureCustomProps),
-
-        // Volume streaming
-        PluginSpec.Action(InitVolumeStreaming),
-        PluginSpec.Action(BoxifyVolumeStreaming),
-        PluginSpec.Action(CreateVolumeStreamingBehavior),
-
-        PluginSpec.Action(StateTransforms.Data.Download),
-        PluginSpec.Action(StateTransforms.Data.ParseCif),
-        PluginSpec.Action(StateTransforms.Data.ParseCcp4),
-        PluginSpec.Action(StateTransforms.Data.ParseDsn6),
-
-        PluginSpec.Action(StateTransforms.Model.TrajectoryFromMmCif),
-        PluginSpec.Action(StateTransforms.Model.TrajectoryFromCifCore),
-        PluginSpec.Action(StateTransforms.Model.TrajectoryFromPDB),
-        PluginSpec.Action(StateTransforms.Model.TransformStructureConformation),
-        PluginSpec.Action(StateTransforms.Model.StructureFromModel),
-        PluginSpec.Action(StateTransforms.Model.StructureFromTrajectory),
-        PluginSpec.Action(StateTransforms.Model.ModelFromTrajectory),
-        PluginSpec.Action(StateTransforms.Model.StructureSelectionFromScript),
-        PluginSpec.Action(StateTransforms.Representation.StructureRepresentation3D),
-        PluginSpec.Action(StateTransforms.Representation.StructureSelectionsDistance3D),
-        PluginSpec.Action(StateTransforms.Representation.StructureSelectionsAngle3D),
-        PluginSpec.Action(StateTransforms.Representation.StructureSelectionsDihedral3D),
-        PluginSpec.Action(StateTransforms.Representation.StructureSelectionsLabel3D),
-        PluginSpec.Action(StateTransforms.Representation.StructureSelectionsOrientation3D),
-        PluginSpec.Action(StateTransforms.Representation.ModelUnitcell3D),
-        PluginSpec.Action(StateTransforms.Representation.ExplodeStructureRepresentation3D),
-        PluginSpec.Action(StateTransforms.Representation.UnwindStructureAssemblyRepresentation3D),
-        PluginSpec.Action(StateTransforms.Representation.OverpaintStructureRepresentation3DFromScript),
-        PluginSpec.Action(StateTransforms.Representation.TransparencyStructureRepresentation3DFromScript),
-
-        PluginSpec.Action(AssignColorVolume),
-        PluginSpec.Action(StateTransforms.Volume.VolumeFromCcp4),
-        PluginSpec.Action(StateTransforms.Volume.VolumeFromDsn6),
-        PluginSpec.Action(StateTransforms.Volume.VolumeFromCube),
-        PluginSpec.Action(StateTransforms.Volume.VolumeFromDx),
-        PluginSpec.Action(StateTransforms.Representation.VolumeRepresentation3D),
-    ],
     behaviors: [
         PluginSpec.Behavior(PluginBehaviors.Representation.HighlightLoci),
         PluginSpec.Behavior(PluginBehaviors.Representation.SelectLoci),
@@ -139,9 +58,6 @@ export const DefaultPluginSpec = (): PluginSpec => ({
         PluginSpec.Behavior(PluginBehaviors.CustomProps.ValenceModel),
         PluginSpec.Behavior(PluginBehaviors.CustomProps.CrossLinkRestraint),
     ],
-    customParamEditors: [
-        [CreateVolumeStreamingBehavior, VolumeStreamingCustomControls]
-    ],
     animations: [
         AnimateModelIndex,
         AnimateCameraSpin,

+ 3 - 3
src/mol-plugin/util/toast.ts

@@ -14,9 +14,9 @@ import { PluginCommands } from '../commands';
 export interface PluginToast {
     title: string,
     /**
-     * The message can be either a string, html string, or an arbitrary React component.
+     * The message can be either a string, html string, or an arbitrary React (Function) component.
      */
-    message: string | React.ComponentClass,
+    message: string | Function,
     /**
      * Only one message with a given key can be shown.
      */
@@ -103,7 +103,7 @@ export namespace PluginToastManager {
         serialNumber: number,
         key?: string,
         title: string,
-        message: string | React.ComponentClass,
+        message: string | Function,
         hide: () => void,
         timeout?: number
     }