mirror of
https://github.com/molstar/molstar.git
synced 2026-06-04 13:30:24 +08:00
update MVS Stories app and deploy scripts (#1574)
* update MVS Stories app and deploy scripts * reorder changelog
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
build/
|
||||
deploy/
|
||||
lib/
|
||||
docs/site/
|
||||
|
||||
|
||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file, following t
|
||||
Note that since we don't clearly distinguish between a public and private interfaces there will be changes in non-major versions that are potentially breaking. If we make breaking changes to less used interfaces we will highlight it in here.
|
||||
|
||||
## [Unreleased]
|
||||
- [Breaking] Renamed some color schemes ('inferno' -> 'inferno-no-black', 'magma' -> 'magma-no-black', 'turbo' -> 'turbo-no-black', 'rainbow' -> 'simple-rainbow')
|
||||
- [Breaking] `Box3D.nearestIntersectionWithRay` -> `nearestIntersectionWithRay3D` (use `Ray3D`)
|
||||
- [Breaking] `Plane3D.distanceToSpher3D` -> `distanceToSphere3D` (fix spelling)
|
||||
- [Breaking] fix typo `MarchinCubes` -> `MarchingCubes`
|
||||
- [Breaking] `PluginContext.initViewer/initContainer/mount` are now async and have been renamed to include `Async` postfix
|
||||
- [Breaking] Add `Volume.instances` support and a `VolumeInstances` transform to dynamically assign it
|
||||
- This change is breaking because all volume objects require the `instances` field now.
|
||||
- Update production build to use `esbuild`
|
||||
- Emit explicit paths in `import`s in `lib/`
|
||||
- Fix outlines on opaque elements using illumination mode
|
||||
@@ -21,7 +28,6 @@ Note that since we don't clearly distinguish between a public and private interf
|
||||
- Support `matrix` on transform params
|
||||
- Add `instance` node type
|
||||
- Support transforming and instancing of structures, components, and volumes
|
||||
- [Breaking] Renamed some color schemes ('inferno' -> 'inferno-no-black', 'magma' -> 'magma-no-black', 'turbo' -> 'turbo-no-black', 'rainbow' -> 'simple-rainbow')
|
||||
- Added new color schemes, synchronized with D3.js ('inferno', 'magma', 'turbo', 'rainbow', 'sinebow', 'warm', 'cool', 'cubehelix-default', 'category-10', 'observable-10', 'tableau-10')
|
||||
- Snapshot Markdown improvements
|
||||
- Add `MarkdownExtensionManager` (`PluginContext.managers.markdownExtensions`)
|
||||
@@ -34,21 +40,16 @@ Note that since we don't clearly distinguish between a public and private interf
|
||||
- Fix isosurface compute shader normals when transformation matrix is applied to volume
|
||||
- Symmetry operator naming for spacegroup symmetry - parenthesize multi-character indices (1_111-1 -> 1_(11)1(-1))
|
||||
- Add `SymmetryOperator.instanceId` that corresponds to a canonical operator name (e.g. ASM-1, ASM-X0-1 for assemblies, 1_555, 1_(11)1(-1) for crystals)
|
||||
- [Breaking] `PluginContext.initViewer/initContainer/mount` are now async and have been renamed to include `Async` postfix
|
||||
- Mol2 Reader
|
||||
- Fix column count parsing
|
||||
- Add support for substructure
|
||||
- Fix shader error when clipping flags are set without clip objects present
|
||||
- [Breaking] Add `Volume.instances` support and a `VolumeInstances` transform to dynamically assign it
|
||||
- This change is breaking because all volume objects require the `instances` field now.
|
||||
- Fix wrong group count calculation on geometry update (#1562)
|
||||
- Fix wrong instance index in `calcMeshColorSmoothing`
|
||||
- Add `Ray3D` object and helpers
|
||||
- [Breaking] `Box3D.nearestIntersectionWithRay` -> `nearestIntersectionWithRay3D` (use `Ray3D`)
|
||||
- [Breaking] `Plane3D.distanceToSpher3D` -> `distanceToSphere3D` (fix spelling)
|
||||
- [Breaking] fix typo `MarchinCubes` -> `MarchingCubes`
|
||||
- Volume slice representation: add `relativeX/Y/Z` options for dimension
|
||||
- Add `StructureInstances` transform
|
||||
- Add `story-id` URL arg support to `mvs-stories` app
|
||||
|
||||
## [v4.18.0] - 2025-06-08
|
||||
- MolViewSpec extension:
|
||||
|
||||
@@ -190,9 +190,14 @@ To get syntax highlighting for shader files add the following to Visual Code's s
|
||||
npm publish
|
||||
|
||||
## Deploy
|
||||
To prepare apps and demos for https://molstar.org deploy, run:
|
||||
|
||||
npm run test
|
||||
npm run build
|
||||
node ./scripts/deploy.js # currently updates the viewer on molstar.org/viewer
|
||||
npm run deploy:local
|
||||
|
||||
To commit these changes remotely to the `molstar/molstar.github.io` repo:
|
||||
|
||||
npm run deploy:remote
|
||||
|
||||
## Contributing
|
||||
Just open an issue or make a pull request. All contributions are welcome.
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
"lint-fix": "eslint . --fix",
|
||||
"test": "npm install --no-save \"gl@^6.0.2\" && npm run lint && jest",
|
||||
"jest": "jest",
|
||||
"clean": "node ./scripts/clean.js",
|
||||
"clean": "node ./scripts/clean.js --all",
|
||||
"clean:build": "node ./scripts/clean.js --build",
|
||||
"build": "npm run build:apps && npm run build:lib",
|
||||
"build:apps": "node ./scripts/build.mjs -a -e --prd",
|
||||
"build:lib": "concurrently \"tsc --incremental\" \"tsc --build tsconfig.commonjs.json --incremental\" && npm run build:lib-extra",
|
||||
@@ -31,6 +32,8 @@
|
||||
"dev:examples": "node ./scripts/build.mjs -e",
|
||||
"dev:browser-tests": "node ./scripts/build.mjs -bt",
|
||||
"serve": "http-server -p 1338 -g",
|
||||
"deploy:local": "npm run clean:build && npm run build:apps && node ./scripts/deploy.js --local",
|
||||
"deploy:remote": "npm run clean:build && npm run build:apps && node ./scripts/deploy.js",
|
||||
"model-server": "node lib/commonjs/servers/model/server.js",
|
||||
"model-server-watch": "nodemon --watch lib lib/commonjs/servers/model/server.js",
|
||||
"volume-server-test": "node lib/commonjs/servers/volume/server.js --idMap em 'test/${id}.mdb' --defaultPort 1336",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const argparse = require('argparse');
|
||||
|
||||
function removeDir(dirPath) {
|
||||
for (const ent of fs.readdirSync(dirPath)) {
|
||||
@@ -24,11 +25,29 @@ function remove(entryPath) {
|
||||
fs.unlinkSync(entryPath);
|
||||
}
|
||||
|
||||
const toClean = [
|
||||
path.resolve(__dirname, '../build'),
|
||||
path.resolve(__dirname, '../lib'),
|
||||
path.resolve(__dirname, '../tsconfig.tsbuildinfo'),
|
||||
];
|
||||
const argParser = new argparse.ArgumentParser({
|
||||
add_help: true,
|
||||
description: 'Clean Script'
|
||||
});
|
||||
argParser.add_argument('--build', { required: false, action: 'store_true' });
|
||||
argParser.add_argument('--lib', { required: false, action: 'store_true' });
|
||||
argParser.add_argument('--all', { required: false, action: 'store_true' });
|
||||
const args = argParser.parse_args();
|
||||
|
||||
const toClean = [];
|
||||
|
||||
if (args.build || args.all) {
|
||||
toClean.push(path.resolve(__dirname, '../build'));
|
||||
toClean.push(path.resolve(__dirname, '../deploy/data'));
|
||||
}
|
||||
if (args.lib || args.all) {
|
||||
toClean.push(
|
||||
path.resolve(__dirname, '../lib'),
|
||||
path.resolve(__dirname, '../tsconfig.tsbuildinfo'),
|
||||
);
|
||||
}
|
||||
|
||||
console.log('\n###', 'cleaning', toClean.join(', '));
|
||||
|
||||
toClean.forEach(ph => {
|
||||
if (fs.existsSync(ph)) {
|
||||
|
||||
@@ -2,20 +2,24 @@
|
||||
* Copyright (c) 2019-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||
* @author David Sehnal <david.sehnal@gmail.com>
|
||||
*/
|
||||
|
||||
const git = require('simple-git');
|
||||
const path = require('path');
|
||||
const fs = require("fs");
|
||||
const fse = require("fs-extra");
|
||||
const argparse = require('argparse');
|
||||
|
||||
const VERSION = require(path.resolve(__dirname, '../package.json')).version;
|
||||
const MVS_STORIES_VERSION = require(path.resolve(__dirname, '../src/apps/mvs-stories/version.ts')).VERSION;
|
||||
|
||||
const remoteUrl = "https://github.com/molstar/molstar.github.io.git";
|
||||
const dataDir = path.resolve(__dirname, '../data/');
|
||||
const buildDir = path.resolve(__dirname, '../build/');
|
||||
const deployDir = path.resolve(buildDir, 'deploy/');
|
||||
const localPath = path.resolve(deployDir, 'molstar.github.io/');
|
||||
const deployDir = path.resolve(__dirname, '../deploy/');
|
||||
const localPath = path.resolve(deployDir, 'data/');
|
||||
const repositoryPath = path.resolve(deployDir, 'molstar.github.io/');
|
||||
|
||||
const analyticsTag = /<!-- __MOLSTAR_ANALYTICS__ -->/g;
|
||||
const analyticsCode = `<!-- Cloudflare Web Analytics --><script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "c414cbae2d284ea995171a81e4a3e721"}'></script><!-- End Cloudflare Web Analytics --><iframe src="https://web3dsurvey.com/collector-iframe.html" style="width: 1px; height: 1px;"></iframe>`;
|
||||
@@ -80,54 +84,106 @@ function copyMe() {
|
||||
addAnalytics(path.resolve(meDeployPath, 'index.html'));
|
||||
}
|
||||
|
||||
function copyMVSStories() {
|
||||
console.log('\n###', 'copy MVS stories files');
|
||||
const mvsStoriesBuildPath = path.resolve(buildDir, 'mvs-stories/');
|
||||
const mvsStoriesDeployPath = path.resolve(localPath, `stories-viewer/v${MVS_STORIES_VERSION}/`);
|
||||
fse.copySync(mvsStoriesBuildPath, mvsStoriesDeployPath, { overwrite: true });
|
||||
addAnalytics(path.resolve(mvsStoriesDeployPath, 'index.html'));
|
||||
|
||||
// TODO: add PWA
|
||||
// addManifest(path.resolve(mvsStoriesDeployPath, 'index.html'));
|
||||
// addPwa(path.resolve(mvsStoriesDeployPath, 'index.html'));
|
||||
}
|
||||
|
||||
function copyDemo(name) {
|
||||
console.log('\n###', `copy demo files for ${name}`);
|
||||
const demoBuildPath = path.resolve(buildDir, `examples/${name}/`);
|
||||
const demoDeployPath = path.resolve(localPath, `demos/${name}/`);
|
||||
fse.copySync(demoBuildPath, demoDeployPath, { overwrite: true });
|
||||
addAnalytics(path.resolve(demoDeployPath, 'index.html'));
|
||||
}
|
||||
|
||||
function copyDemos() {
|
||||
console.log('\n###', 'copy demos files');
|
||||
const lightingBuildPath = path.resolve(buildDir, 'examples/lighting/');
|
||||
const lightingDeployPath = path.resolve(localPath, 'demos/lighting/');
|
||||
fse.copySync(lightingBuildPath, lightingDeployPath, { overwrite: true });
|
||||
addAnalytics(path.resolve(lightingDeployPath, 'index.html'));
|
||||
|
||||
const orbitalsBuildPath = path.resolve(buildDir, 'examples/alpha-orbitals/');
|
||||
const orbitalsDeployPath = path.resolve(localPath, 'demos/alpha-orbitals/');
|
||||
fse.copySync(orbitalsBuildPath, orbitalsDeployPath, { overwrite: true });
|
||||
addAnalytics(path.resolve(orbitalsDeployPath, 'index.html'));
|
||||
copyDemo('lighting');
|
||||
copyDemo('alpha-orbitals');
|
||||
copyDemo('mvs-stories');
|
||||
}
|
||||
|
||||
function copyFiles() {
|
||||
try {
|
||||
copyViewer();
|
||||
copyMe();
|
||||
copyMVSStories();
|
||||
copyDemos();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
function copyToRepository() {
|
||||
console.log('\n###', 'copy repository files');
|
||||
fse.copySync(localPath, repositoryPath, { overwrite: true });
|
||||
}
|
||||
|
||||
function syncRepository() {
|
||||
console.log('\n###', 'sync repository');
|
||||
if (!fs.existsSync(path.resolve(repositoryPath, '.git/'))) {
|
||||
console.log('\n###', 'clone repository');
|
||||
git()
|
||||
.outputHandler(log)
|
||||
.clone(remoteUrl, repositoryPath)
|
||||
.fetch(['--all'])
|
||||
.exec(copyToRepository);
|
||||
} else {
|
||||
console.log('\n###', 'update repository');
|
||||
git()
|
||||
.outputHandler(log)
|
||||
.fetch(['--all'])
|
||||
.reset(['--hard', 'origin/master'])
|
||||
.exec(copyToRepository);
|
||||
}
|
||||
}
|
||||
|
||||
function commit() {
|
||||
console.log('\n###', 'commit changes');
|
||||
git()
|
||||
.outputHandler(log)
|
||||
.add(['-A'])
|
||||
.commit(`Updated Apps and Demos
|
||||
- Mol* version: ${VERSION}
|
||||
- MVS Stories version: ${MVS_STORIES_VERSION}`)
|
||||
.push();
|
||||
}
|
||||
|
||||
if (!fs.existsSync(localPath)) {
|
||||
console.log('\n###', 'create localPath');
|
||||
fs.mkdirSync(localPath, { recursive: true });
|
||||
}
|
||||
|
||||
process.chdir(localPath);
|
||||
const argParser = new argparse.ArgumentParser({
|
||||
add_help: true,
|
||||
description: 'Mol* Deploy'
|
||||
});
|
||||
argParser.add_argument('--local',{
|
||||
help: 'Do not commit to remote repository.',
|
||||
required: false,
|
||||
action: 'store_true',
|
||||
});
|
||||
const args = argParser.parse_args();
|
||||
|
||||
if (!fs.existsSync(path.resolve(localPath, '.git/'))) {
|
||||
console.log('\n###', 'clone repository');
|
||||
git()
|
||||
.outputHandler(log)
|
||||
.clone(remoteUrl, localPath)
|
||||
.fetch(['--all'])
|
||||
.exec(copyFiles)
|
||||
.add(['-A'])
|
||||
.commit('updated viewer & demos')
|
||||
.push();
|
||||
} else {
|
||||
console.log('\n###', 'update repository');
|
||||
git()
|
||||
.outputHandler(log)
|
||||
.fetch(['--all'])
|
||||
.reset(['--hard', 'origin/master'])
|
||||
.exec(copyFiles)
|
||||
.add(['-A'])
|
||||
.commit('updated viewer & demos')
|
||||
.push();
|
||||
}
|
||||
copyFiles();
|
||||
|
||||
if (args.local) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (!fs.existsSync(repositoryPath)) {
|
||||
console.log('\n###', 'create repositoryPath');
|
||||
fs.mkdirSync(repositoryPath, { recursive: true });
|
||||
}
|
||||
|
||||
process.chdir(repositoryPath);
|
||||
syncRepository();
|
||||
commit();
|
||||
@@ -76,6 +76,7 @@
|
||||
|
||||
<script>
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
var storyId = urlParams.get('story-id');
|
||||
var storyUrl = urlParams.get('story-url');
|
||||
var format = urlParams.get('data-format');
|
||||
|
||||
@@ -84,11 +85,13 @@
|
||||
// storyUrl = 'https://raw.githubusercontent.com/molstar/molstar/master/examples/mvs/kinase-story.mvsj';
|
||||
// }
|
||||
|
||||
mvsStories.loadFromURL(
|
||||
storyUrl,
|
||||
{ format: format || 'mvsj', contextName: 'story1' },
|
||||
);
|
||||
if (storyId) {
|
||||
mvsStories.loadFromID(storyId, { contextName: 'story1' });
|
||||
} else if (storyUrl) {
|
||||
mvsStories.loadFromURL(storyUrl, { format: format || 'mvsj', contextName: 'story1' });
|
||||
}
|
||||
</script>
|
||||
<!-- __MOLSTAR_ANALYTICS__ -->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -37,4 +37,15 @@ export function loadFromData(data: MVSData | string | Uint8Array, options?: { fo
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function getStoryUrlFromId(id: string, format: 'mvsx' | 'mvsj' = 'mvsj') {
|
||||
return `https://stories.molstar.org/api/story/${id}/data`;
|
||||
}
|
||||
|
||||
export function loadFromID(id: string, options?: { format?: 'mvsx' | 'mvsj', contextName?: string }) {
|
||||
loadFromURL(
|
||||
getStoryUrlFromId(id, options?.format),
|
||||
{ format: options?.format ?? 'mvsj', contextName: options?.contextName },
|
||||
);
|
||||
}
|
||||
|
||||
export { MVSData };
|
||||
7
src/apps/mvs-stories/version.ts
Normal file
7
src/apps/mvs-stories/version.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author David Sehnal <david.sehnal@gmail.com>
|
||||
*/
|
||||
|
||||
export const VERSION = 1;
|
||||
@@ -118,6 +118,7 @@
|
||||
window.initStories();
|
||||
}, 0);
|
||||
</script>
|
||||
<!-- __MOLSTAR_ANALYTICS__ -->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user