diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 034f0bfb65..7bd89be58b 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -106,7 +106,34 @@ jobs: - name: Typecheck code run: pnpm typecheck - name: Run tests + id: tests run: pnpm test-ci + continue-on-error: true + - name: Upload jest image snapshot diffs to S3 + if: steps.tests.outcome == 'failure' + run: | + SNAPSHOTS_DIR="products/jbrowse-web/src/tests/__image_snapshots__/__diff_output__" + S3_PATH="s3://jbrowse.org/demos/imagediff/${{ github.run_id }}" + + if ls ${SNAPSHOTS_DIR}/*.png 1> /dev/null 2>&1; then + echo "Uploading jest image snapshot diffs to S3..." + aws s3 cp ${SNAPSHOTS_DIR}/ ${S3_PATH}/ --recursive --exclude "*" --include "*.png" + + echo "" + echo "============================================" + echo "JEST SNAPSHOT DIFF IMAGES UPLOADED TO S3" + echo "============================================" + for file in ${SNAPSHOTS_DIR}/*.png; do + filename=$(basename "$file") + echo "https://jbrowse.org/demos/imagediff/${{ github.run_id }}/${filename}" + done + echo "============================================" + else + echo "No jest snapshot diff files found" + fi + - name: Fail if tests failed + if: steps.tests.outcome == 'failure' + run: exit 1 - name: Pack artifacts for component tests run: node --experimental-strip-types scripts/pack.ts - name: Test build diff --git a/component_tests/app-vite/cypress/plugins/index.js b/component_tests/app-vite/cypress/plugins/index.mjs similarity index 95% rename from component_tests/app-vite/cypress/plugins/index.js rename to component_tests/app-vite/cypress/plugins/index.mjs index 38cbdf2021..4399850abd 100644 --- a/component_tests/app-vite/cypress/plugins/index.js +++ b/component_tests/app-vite/cypress/plugins/index.mjs @@ -16,7 +16,7 @@ * @type {Cypress.PluginConfig} */ -module.exports = (on, config) => { +export default (on, config) => { // `on` is used to hook into various events Cypress emits // `config` is the resolved Cypress config } diff --git a/component_tests/app-vite/src/main.tsx b/component_tests/app-vite/src/main.tsx index 711e6d1474..3b83bb9272 100644 --- a/component_tests/app-vite/src/main.tsx +++ b/component_tests/app-vite/src/main.tsx @@ -1,11 +1,11 @@ -import React from 'react' +import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App' const root = createRoot(document.getElementById('root')!) root.render( - + - , + , ) diff --git a/component_tests/app-vite/tsconfig.node.json b/component_tests/app-vite/tsconfig.node.json index 0d3d71446a..821cf1a225 100644 --- a/component_tests/app-vite/tsconfig.node.json +++ b/component_tests/app-vite/tsconfig.node.json @@ -6,7 +6,7 @@ "skipLibCheck": true, /* Bundler mode */ - "moduleResolution": "bundler", + "moduleResolution": "node", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", diff --git a/component_tests/cgv-vite/cypress/plugins/index.js b/component_tests/cgv-vite/cypress/plugins/index.mjs similarity index 95% rename from component_tests/cgv-vite/cypress/plugins/index.js rename to component_tests/cgv-vite/cypress/plugins/index.mjs index 38cbdf2021..4399850abd 100644 --- a/component_tests/cgv-vite/cypress/plugins/index.js +++ b/component_tests/cgv-vite/cypress/plugins/index.mjs @@ -16,7 +16,7 @@ * @type {Cypress.PluginConfig} */ -module.exports = (on, config) => { +export default (on, config) => { // `on` is used to hook into various events Cypress emits // `config` is the resolved Cypress config } diff --git a/component_tests/cgv-vite/src/main.tsx b/component_tests/cgv-vite/src/main.tsx index 711e6d1474..3b83bb9272 100644 --- a/component_tests/cgv-vite/src/main.tsx +++ b/component_tests/cgv-vite/src/main.tsx @@ -1,11 +1,11 @@ -import React from 'react' +import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App' const root = createRoot(document.getElementById('root')!) root.render( - + - , + , ) diff --git a/component_tests/cgv-vite/tsconfig.node.json b/component_tests/cgv-vite/tsconfig.node.json index 0d3d71446a..821cf1a225 100644 --- a/component_tests/cgv-vite/tsconfig.node.json +++ b/component_tests/cgv-vite/tsconfig.node.json @@ -6,7 +6,7 @@ "skipLibCheck": true, /* Bundler mode */ - "moduleResolution": "bundler", + "moduleResolution": "node", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", diff --git a/component_tests/lgv-vite/cypress/plugins/index.js b/component_tests/lgv-vite/cypress/plugins/index.mjs similarity index 95% rename from component_tests/lgv-vite/cypress/plugins/index.js rename to component_tests/lgv-vite/cypress/plugins/index.mjs index 38cbdf2021..4399850abd 100644 --- a/component_tests/lgv-vite/cypress/plugins/index.js +++ b/component_tests/lgv-vite/cypress/plugins/index.mjs @@ -16,7 +16,7 @@ * @type {Cypress.PluginConfig} */ -module.exports = (on, config) => { +export default (on, config) => { // `on` is used to hook into various events Cypress emits // `config` is the resolved Cypress config } diff --git a/component_tests/lgv-vite/src/main.tsx b/component_tests/lgv-vite/src/main.tsx index 711e6d1474..3b83bb9272 100644 --- a/component_tests/lgv-vite/src/main.tsx +++ b/component_tests/lgv-vite/src/main.tsx @@ -1,11 +1,11 @@ -import React from 'react' +import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App' const root = createRoot(document.getElementById('root')!) root.render( - + - , + , ) diff --git a/component_tests/lgv-vite/tsconfig.node.json b/component_tests/lgv-vite/tsconfig.node.json index 0d3d71446a..821cf1a225 100644 --- a/component_tests/lgv-vite/tsconfig.node.json +++ b/component_tests/lgv-vite/tsconfig.node.json @@ -6,7 +6,7 @@ "skipLibCheck": true, /* Bundler mode */ - "moduleResolution": "bundler", + "moduleResolution": "node", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", diff --git a/eslint.config.mjs b/eslint.config.mjs index 3936346194..0db6b2e6fe 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -26,6 +26,7 @@ export default defineConfig( 'babel.config.cjs', 'eslint.config.mjs', 'products/**/webpack.config.js', + 'products/**/webpack.config.mjs', '**/.storybook', '**/output-version.js', '**/umd_plugin.js', diff --git a/package.json b/package.json index 3688282bc2..d16280dbac 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,6 @@ "dotenv": "^17.2.3", "electron": "40.0.0", "electron-builder": "^25.1.8", - "electron-mock-ipc": "^0.3.14", "eslint": "^9.39.2", "eslint-plugin-import": "^2.32.0", "eslint-plugin-node": "^11.1.0", diff --git a/packages/__mocks__/electron.ts b/packages/__mocks__/electron.ts deleted file mode 100644 index aba9b89991..0000000000 --- a/packages/__mocks__/electron.ts +++ /dev/null @@ -1,12 +0,0 @@ -import createIPCMock from 'electron-mock-ipc' -const { ipcMain, ipcRenderer } = createIPCMock() - -// @ts-expect-error -window.require = () => { - return { - ipcRenderer, - ipcMain, - } -} - -export { ipcMain, ipcRenderer } diff --git a/packages/app-core/package.json b/packages/app-core/package.json index d64391cb27..ee53819d0a 100644 --- a/packages/app-core/package.json +++ b/packages/app-core/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/app-core", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 code shared between the 'full featured' apps e.g. jbrowse-web and jbrowse-desktop", "keywords": [ "jbrowse", diff --git a/packages/core/.storybook/main.js b/packages/core/.storybook/main.mjs similarity index 89% rename from packages/core/.storybook/main.js rename to packages/core/.storybook/main.mjs index 52a1d5b4b4..57ba2fde26 100644 --- a/packages/core/.storybook/main.js +++ b/packages/core/.storybook/main.mjs @@ -1,4 +1,4 @@ -module.exports = { +export default { stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|ts|tsx)'], addons: ['@storybook/addon-essentials'], framework: { @@ -14,7 +14,7 @@ module.exports = { test: /\.(ts|tsx|js|jsx)$/, use: [ { - loader: require.resolve('babel-loader'), + loader: 'babel-loader', options: { rootMode: 'upward', presets: ['@babel/preset-react'], diff --git a/packages/core/DEVELOPERS.md b/packages/core/DEVELOPERS.md new file mode 100644 index 0000000000..2274a440f5 --- /dev/null +++ b/packages/core/DEVELOPERS.md @@ -0,0 +1,88 @@ +# @jbrowse/core Developer Guide + +## Package Design + +This package has **no main entry point**. It is designed exclusively for subpath +imports: + +```typescript +// Correct usage +import PluginManager from '@jbrowse/core/PluginManager' +import { ConfigurationSchema } from '@jbrowse/core/configuration' + +// This will error - no default export +import '@jbrowse/core' // ERR_PACKAGE_PATH_NOT_EXPORTED +``` + +## package.json Structure + +This package uses a dual-mode configuration to support both monorepo development +and external consumers. + +### Exports Field + +The `exports` field defines subpath imports like `@jbrowse/core/PluginManager`. +During development, these point to source TypeScript files: + +```json +"exports": { + ".": "./src/index.ts", + "./PluginManager": "./src/PluginManager.ts" +} +``` + +### publishConfig + +When the package is published to npm, the `publishConfig` section overrides the +exports to point to compiled output: + +```json +"publishConfig": { + "exports": { + "./PluginManager": { + "types": "./esm/PluginManager.d.ts", + "import": "./esm/PluginManager.js" + } + } +} +``` + +### typesVersions (for moduleResolution "node" consumers) + +The `exports` field is only supported by TypeScript with `moduleResolution` set +to `bundler`, `node16`, or `nodenext`. For consumers using the legacy +`moduleResolution: "node"`, we include a `typesVersions` field in +`publishConfig`: + +```json +"publishConfig": { + "typesVersions": { + "*": { + "PluginManager": ["esm/PluginManager.d.ts"] + } + } +} +``` + +This tells TypeScript where to find type declarations for subpath imports even +when the `exports` field is not being read. + +## Generating Exports + +The exports, publishConfig.exports, and publishConfig.typesVersions are all +auto-generated by scanning the codebase for `@jbrowse/core/*` imports: + +```bash +pnpm generate:exports +``` + +This script (`scripts/generateExports.mjs`) finds all imports of +`@jbrowse/core/*` across the monorepo and generates the appropriate mappings. + +## Module Resolution Summary + +| Consumer Environment | How it resolves `@jbrowse/core/PluginManager` | +| ---------------------------------- | ----------------------------------------------------- | +| Monorepo (bundler mode) | Uses `exports` field pointing to `src/*.ts` | +| External (bundler/node16/nodenext) | Uses `publishConfig.exports` pointing to `esm/*.js` | +| External (node mode) | Uses `typesVersions` for types, `exports` for runtime | diff --git a/packages/core/package.json b/packages/core/package.json index 37498818ff..4e5d5333ef 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -19,10 +19,7 @@ "directory": "packages/core" }, "author": "JBrowse Team", - "main": "dist/index.js", - "types": "dist/index.d.ts", "exports": { - ".": "./src/index.ts", "./BaseFeatureWidget": "./src/BaseFeatureWidget/index.ts", "./BaseFeatureWidget/BaseFeatureDetail": "./src/BaseFeatureWidget/BaseFeatureDetail/index.tsx", "./BaseFeatureWidget/BaseFeatureDetail/Attributes": "./src/BaseFeatureWidget/BaseFeatureDetail/Attributes.tsx", @@ -169,7 +166,6 @@ "@types/file-saver-es": "^2.0.3", "canvas-sequencer-ts": "^3.1.3", "canvas2svg": "^1.0.16", - "colord": "^2.9.3", "copy-to-clipboard": "^3.3.3", "deepmerge": "^4.3.1", "detect-node": "^2.1.0", @@ -180,7 +176,6 @@ "generic-filehandle2": "^2.0.18", "idb": "^8.0.3", "librpc-web-mod": "^2.1.1", - "load-script": "^2.0.0", "mobx": "^6.15.0", "mobx-react": "^9.2.1", "react-draggable": "^4.5.0", @@ -193,13 +188,7 @@ }, "publishConfig": { "access": "public", - "main": "esm/index.js", - "types": "esm/index.d.ts", "exports": { - ".": { - "types": "./esm/index.d.ts", - "import": "./esm/index.js" - }, "./BaseFeatureWidget": { "types": "./esm/BaseFeatureWidget/index.d.ts", "import": "./esm/BaseFeatureWidget/index.js" @@ -640,6 +629,340 @@ "types": "./esm/util/fileHandleStore.d.ts", "import": "./esm/util/fileHandleStore.js" } + }, + "typesVersions": { + "*": { + "BaseFeatureWidget": [ + "esm/BaseFeatureWidget/index.d.ts" + ], + "BaseFeatureWidget/BaseFeatureDetail": [ + "esm/BaseFeatureWidget/BaseFeatureDetail/index.d.ts" + ], + "BaseFeatureWidget/BaseFeatureDetail/Attributes": [ + "esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.d.ts" + ], + "BaseFeatureWidget/BaseFeatureDetail/BaseCard": [ + "esm/BaseFeatureWidget/BaseFeatureDetail/BaseCard.d.ts" + ], + "BaseFeatureWidget/BaseFeatureDetail/FeatureDetails": [ + "esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts" + ], + "BaseFeatureWidget/BaseFeatureDetail/SimpleField": [ + "esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.d.ts" + ], + "Plugin": [ + "esm/Plugin.d.ts" + ], + "PluginLoader": [ + "esm/PluginLoader.d.ts" + ], + "PluginManager": [ + "esm/PluginManager.d.ts" + ], + "TextSearch/BaseResults": [ + "esm/TextSearch/BaseResults.d.ts" + ], + "TextSearch/TextSearchManager": [ + "esm/TextSearch/TextSearchManager.d.ts" + ], + "assemblyManager": [ + "esm/assemblyManager/index.d.ts" + ], + "assemblyManager/assembly": [ + "esm/assemblyManager/assembly.d.ts" + ], + "assemblyManager/assemblyConfigSchema": [ + "esm/assemblyManager/assemblyConfigSchema.d.ts" + ], + "configuration": [ + "esm/configuration/index.d.ts" + ], + "data_adapters/BaseAdapter": [ + "esm/data_adapters/BaseAdapter/index.d.ts" + ], + "data_adapters/BaseAdapter/BaseOptions": [ + "esm/data_adapters/BaseAdapter/BaseOptions.d.ts" + ], + "data_adapters/BaseAdapter/stats": [ + "esm/data_adapters/BaseAdapter/stats.d.ts" + ], + "data_adapters/dataAdapterCache": [ + "esm/data_adapters/dataAdapterCache.d.ts" + ], + "pluggableElementTypes": [ + "esm/pluggableElementTypes/index.d.ts" + ], + "pluggableElementTypes/AdapterType": [ + "esm/pluggableElementTypes/AdapterType.d.ts" + ], + "pluggableElementTypes/ConnectionType": [ + "esm/pluggableElementTypes/ConnectionType.d.ts" + ], + "pluggableElementTypes/DisplayType": [ + "esm/pluggableElementTypes/DisplayType.d.ts" + ], + "pluggableElementTypes/GlyphType": [ + "esm/pluggableElementTypes/GlyphType.d.ts" + ], + "pluggableElementTypes/InternetAccountType": [ + "esm/pluggableElementTypes/InternetAccountType.d.ts" + ], + "pluggableElementTypes/RpcMethodType": [ + "esm/pluggableElementTypes/RpcMethodType.d.ts" + ], + "pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions": [ + "esm/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions.d.ts" + ], + "pluggableElementTypes/TextSearchAdapterType": [ + "esm/pluggableElementTypes/TextSearchAdapterType.d.ts" + ], + "pluggableElementTypes/TrackType": [ + "esm/pluggableElementTypes/TrackType.d.ts" + ], + "pluggableElementTypes/ViewType": [ + "esm/pluggableElementTypes/ViewType.d.ts" + ], + "pluggableElementTypes/WidgetType": [ + "esm/pluggableElementTypes/WidgetType.d.ts" + ], + "pluggableElementTypes/models": [ + "esm/pluggableElementTypes/models/index.d.ts" + ], + "pluggableElementTypes/models/BaseViewModel": [ + "esm/pluggableElementTypes/models/BaseViewModel.d.ts" + ], + "pluggableElementTypes/models/baseConnectionConfig": [ + "esm/pluggableElementTypes/models/baseConnectionConfig.d.ts" + ], + "pluggableElementTypes/renderers/BoxRendererType": [ + "esm/pluggableElementTypes/renderers/BoxRendererType.d.ts" + ], + "pluggableElementTypes/renderers/CircularChordRendererType": [ + "esm/pluggableElementTypes/renderers/CircularChordRendererType.d.ts" + ], + "pluggableElementTypes/renderers/FeatureRendererType": [ + "esm/pluggableElementTypes/renderers/FeatureRendererType.d.ts" + ], + "pluggableElementTypes/renderers/LayoutSession": [ + "esm/pluggableElementTypes/renderers/LayoutSession.d.ts" + ], + "pluggableElementTypes/renderers/RendererType": [ + "esm/pluggableElementTypes/renderers/RendererType.d.ts" + ], + "pluggableElementTypes/renderers/ServerSideRendererType": [ + "esm/pluggableElementTypes/renderers/ServerSideRendererType.d.ts" + ], + "pluggableElementTypes/renderers/util": [ + "esm/pluggableElementTypes/renderers/util.d.ts" + ], + "pluggableElementTypes/renderers/util/serializableFilterChain": [ + "esm/pluggableElementTypes/renderers/util/serializableFilterChain.d.ts" + ], + "rpc/RpcManager": [ + "esm/rpc/RpcManager.d.ts" + ], + "rpc/coreRpcMethods": [ + "esm/rpc/coreRpcMethods.d.ts" + ], + "rpc/methods/util": [ + "esm/rpc/methods/util.d.ts" + ], + "ui": [ + "esm/ui/index.d.ts" + ], + "ui/AppLogo": [ + "esm/ui/AppLogo.d.ts" + ], + "ui/BaseTooltip": [ + "esm/ui/BaseTooltip.d.ts" + ], + "ui/CascadingMenuButton": [ + "esm/ui/CascadingMenuButton.d.ts" + ], + "ui/ColorPicker": [ + "esm/ui/ColorPicker.d.ts" + ], + "ui/ConfirmDialog": [ + "esm/ui/ConfirmDialog.d.ts" + ], + "ui/DataGridFlexContainer": [ + "esm/ui/DataGridFlexContainer.d.ts" + ], + "ui/Dialog": [ + "esm/ui/Dialog.d.ts" + ], + "ui/DraggableDialog": [ + "esm/ui/DraggableDialog.d.ts" + ], + "ui/DropDownMenu": [ + "esm/ui/DropDownMenu.d.ts" + ], + "ui/EditableTypography": [ + "esm/ui/EditableTypography.d.ts" + ], + "ui/ErrorBoundary": [ + "esm/ui/ErrorBoundary.d.ts" + ], + "ui/ErrorMessage": [ + "esm/ui/ErrorMessage.d.ts" + ], + "ui/ErrorMessageStackTraceDialog": [ + "esm/ui/ErrorMessageStackTraceDialog.d.ts" + ], + "ui/Icons": [ + "esm/ui/Icons.d.ts" + ], + "ui/LoadingEllipses": [ + "esm/ui/LoadingEllipses.d.ts" + ], + "ui/Logo": [ + "esm/ui/Logo.d.ts" + ], + "ui/Menu": [ + "esm/ui/Menu.d.ts" + ], + "ui/ResizeHandle": [ + "esm/ui/ResizeHandle.d.ts" + ], + "ui/SanitizedHTML": [ + "esm/ui/SanitizedHTML.d.ts" + ], + "ui/Snackbar": [ + "esm/ui/Snackbar.d.ts" + ], + "ui/SnackbarModel": [ + "esm/ui/SnackbarModel.d.ts" + ], + "ui/colors": [ + "esm/ui/colors.d.ts" + ], + "ui/theme": [ + "esm/ui/theme.d.ts" + ], + "util": [ + "esm/util/index.d.ts" + ], + "util/Base1DUtils": [ + "esm/util/Base1DUtils.d.ts" + ], + "util/Base1DViewModel": [ + "esm/util/Base1DViewModel.d.ts" + ], + "util/QuickLRU": [ + "esm/util/QuickLRU/index.d.ts" + ], + "util/TimeTraveller": [ + "esm/util/TimeTraveller.d.ts" + ], + "util/aborting": [ + "esm/util/aborting.d.ts" + ], + "util/analytics": [ + "esm/util/analytics.d.ts" + ], + "util/blockTypes": [ + "esm/util/blockTypes.d.ts" + ], + "util/calculateDynamicBlocks": [ + "esm/util/calculateDynamicBlocks.d.ts" + ], + "util/calculateStaticBlocks": [ + "esm/util/calculateStaticBlocks.d.ts" + ], + "util/color": [ + "esm/util/color/index.d.ts" + ], + "util/colord": [ + "esm/util/colord.d.ts" + ], + "util/compositeMap": [ + "esm/util/compositeMap.d.ts" + ], + "util/convertCodingSequenceToPeptides": [ + "esm/util/convertCodingSequenceToPeptides.d.ts" + ], + "util/flatbush": [ + "esm/util/flatbush/index.d.ts" + ], + "util/formatFastaStrings": [ + "esm/util/formatFastaStrings.d.ts" + ], + "util/io": [ + "esm/util/io/index.d.ts" + ], + "util/io/RemoteFileWithRangeCache": [ + "esm/util/io/RemoteFileWithRangeCache.d.ts" + ], + "util/jexlStrings": [ + "esm/util/jexlStrings.d.ts" + ], + "util/layouts": [ + "esm/util/layouts/index.d.ts" + ], + "util/layouts/BaseLayout": [ + "esm/util/layouts/BaseLayout.d.ts" + ], + "util/layouts/GranularRectLayout": [ + "esm/util/layouts/GranularRectLayout.d.ts" + ], + "util/librpc": [ + "esm/util/librpc.d.ts" + ], + "util/mst-reflection": [ + "esm/util/mst-reflection.d.ts" + ], + "util/offscreenCanvasPonyfill": [ + "esm/util/offscreenCanvasPonyfill.d.ts" + ], + "util/offscreenCanvasUtils": [ + "esm/util/offscreenCanvasUtils.d.ts" + ], + "util/parseLineByLine": [ + "esm/util/parseLineByLine.d.ts" + ], + "util/range": [ + "esm/util/range.d.ts" + ], + "util/rxjs": [ + "esm/util/rxjs.d.ts" + ], + "util/simpleFeature": [ + "esm/util/simpleFeature.d.ts" + ], + "util/stats": [ + "esm/util/stats.d.ts" + ], + "util/stopToken": [ + "esm/util/stopToken.d.ts" + ], + "util/tracks": [ + "esm/util/tracks.d.ts" + ], + "util/tss-react": [ + "esm/util/tss-react/index.d.ts" + ], + "util/types": [ + "esm/util/types/index.d.ts" + ], + "util/types/mst": [ + "esm/util/types/mst.d.ts" + ], + "util/useMeasure": [ + "esm/util/useMeasure.d.ts" + ], + "ui/ReturnToImportFormDialog": [ + "esm/ui/ReturnToImportFormDialog.d.ts" + ], + "util/nanoid": [ + "esm/util/nanoid.d.ts" + ], + "ReExports/list": [ + "esm/ReExports/list.d.ts" + ], + "util/fileHandleStore": [ + "esm/util/fileHandleStore.d.ts" + ] + } } }, "sideEffects": false diff --git a/packages/core/scripts/generateExports.mjs b/packages/core/scripts/generateExports.mjs index e52ccd4965..a575f32143 100644 --- a/packages/core/scripts/generateExports.mjs +++ b/packages/core/scripts/generateExports.mjs @@ -98,16 +98,17 @@ console.log(`Found ${imports.length} unique @jbrowse/core import paths`) // Generate dev exports (pointing to src) // Using simple string format since import/require point to same .ts file -const devExports = { - '.': './src/index.ts', -} +// Note: No "." entry - this package is designed for subpath imports only +const devExports = {} // Generate publish exports (pointing to esm) -const publishExports = { - '.': { - types: './esm/index.d.ts', - import: './esm/index.js', - }, +// Note: No "." entry - this package is designed for subpath imports only +const publishExports = {} + +// Generate typesVersions for moduleResolution "node" consumers +// This allows TypeScript to resolve subpath imports even without exports field support +const typesVersions = { + '*': {}, } for (const entry of imports) { @@ -121,6 +122,14 @@ for (const entry of imports) { types: `./esm${outPath.replace('.js', '.d.ts')}`, import: `./esm${outPath}`, } + + // typesVersions uses paths without leading './' and maps to array of paths + const typesVersionsKey = exportPath.slice(2) // remove './' + if (typesVersionsKey) { + typesVersions['*'][typesVersionsKey] = [ + `esm${outPath.replace('.js', '.d.ts')}`, + ] + } } // Read package.json @@ -135,6 +144,7 @@ if (!packageJson.publishConfig) { packageJson.publishConfig = {} } packageJson.publishConfig.exports = publishExports +packageJson.publishConfig.typesVersions = typesVersions // Write back writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`) @@ -143,3 +153,6 @@ console.log(`Generated ${Object.keys(devExports).length} dev export entries`) console.log( `Generated ${Object.keys(publishExports).length} publish export entries`, ) +console.log( + `Generated ${Object.keys(typesVersions['*']).length} typesVersions entries`, +) diff --git a/packages/core/src/PluginLoader.ts b/packages/core/src/PluginLoader.ts index 6eb4a4af65..28afadf9a8 100644 --- a/packages/core/src/PluginLoader.ts +++ b/packages/core/src/PluginLoader.ts @@ -1,5 +1,3 @@ -import domLoadScript from 'load-script' - import Plugin from './Plugin.ts' import ReExports from './ReExports/index.ts' import { isElectron } from './util/index.ts' @@ -71,14 +69,18 @@ export interface CJSPluginDefinition { } function promisifiedLoadScript(src: string) { - return new Promise((resolve, reject) => { - domLoadScript(src, (err, script) => { - if (err) { - reject(err) - } else { - resolve(script.src) - } - }) + return new Promise((resolve, reject) => { + const script = document.createElement('script') + script.type = 'text/javascript' + script.async = true + script.src = src + script.onload = () => { + resolve(script.src) + } + script.onerror = () => { + reject(new Error(`Failed to load script: ${src}`)) + } + document.head.append(script) }) } diff --git a/packages/core/src/util/IntervalTree.test.ts b/packages/core/src/util/IntervalTree.test.ts new file mode 100644 index 0000000000..fa9b5622a7 --- /dev/null +++ b/packages/core/src/util/IntervalTree.test.ts @@ -0,0 +1,243 @@ +/** + * Tests for vendored IntervalTree + * Based on tests from @flatten-js/interval-tree + */ + +import { IntervalTree } from './IntervalTree.ts' + +describe('IntervalTree', () => { + it('creates new instance', () => { + const tree = new IntervalTree() + expect(tree).toBeInstanceOf(IntervalTree) + }) + + it('inserts one entry with numeric tuple key', () => { + const tree = new IntervalTree() + tree.insert([1, 2], 'val') + expect(tree.search([1, 2])).toEqual(['val']) + }) + + it('inserts many entries', () => { + const tree = new IntervalTree() + const intervals: [number, number][] = [ + [6, 8], + [1, 4], + [5, 12], + [1, 1], + [5, 7], + ] + for (let i = 0, l = intervals.length; i < l; i++) { + tree.insert(intervals[i]!, `val${i}`) + } + // [1,1] intersects both [1,1] and [1,4] + expect(tree.search([1, 1])).toContain('val3') + expect(tree.search([1, 1])).toContain('val1') + expect(tree.search([6, 8])).toContain('val0') + }) + + it('searches interval and returns array of values', () => { + const tree = new IntervalTree() + const intervals: [number, number][] = [ + [6, 8], + [1, 4], + [5, 12], + [1, 1], + [5, 7], + ] + for (let i = 0, l = intervals.length; i < l; i++) { + tree.insert(intervals[i]!, `val${i}`) + } + expect(tree.search([2, 3])).toEqual(['val1']) + }) + + it('returns empty array when search interval does not intersect any', () => { + const tree = new IntervalTree() + const intervals: [number, number][] = [ + [6, 8], + [1, 2], + [7, 12], + [1, 1], + [5, 7], + ] + for (let i = 0, l = intervals.length; i < l; i++) { + tree.insert(intervals[i]!, `val${i}`) + } + expect(tree.search([3, 4])).toEqual([]) + }) + + it('buckets multiple values for identical keys', () => { + const tree = new IntervalTree() + tree.insert([2, 5], 10) + tree.insert([2, 5], 20) + tree.insert([2, 5], 30) + tree.insert([2, 5], 40) + tree.insert([2, 5], 50) + + const results = tree.search([2, 5]) + expect(results).toContain(10) + expect(results).toContain(20) + expect(results).toContain(30) + expect(results).toContain(40) + expect(results).toContain(50) + expect(results).toHaveLength(5) + }) + + it('handles storing 0 as a value', () => { + const tree = new IntervalTree() + tree.insert([0, 0], 0) + tree.insert([0, 0], 1) + + const results = tree.search([0, 0]) + expect(results).toEqual([0, 1]) + }) + + it('stores falsy values: 0, false, NaN, null', () => { + const tree = new IntervalTree() + tree.insert([0, 0], 0) + tree.insert([0, 0], false) + tree.insert([0, 0], NaN) + tree.insert([0, 0], null) + + const results = tree.search([0, 0]) + expect(results).toHaveLength(4) + expect(results).toContain(0) + expect(results).toContain(false) + expect(results).toContain(null) + expect(results.some(v => Number.isNaN(v))).toBe(true) + }) + + it('stores custom objects', () => { + interface Item { + name: string + value: number + } + const tree = new IntervalTree() + const data: Item[] = [ + { name: 'A', value: 111 }, + { name: 'B', value: 333 }, + { name: 'C', value: 222 }, + ] + + tree.insert([2, 5], data[0]!) + tree.insert([2, 5], data[1]!) + tree.insert([2, 5], data[2]!) + + const results = tree.search([2, 5]) + expect(results).toContain(data[0]) + expect(results).toContain(data[1]) + expect(results).toContain(data[2]) + }) + + it('normalizes reversed intervals', () => { + const tree = new IntervalTree() + tree.insert([8, 2], 'reversed') + tree.insert([2, 8], 'normal') + + // Both should be stored under [2, 8] and retrieved together + const results = tree.search([3, 5]) + expect(results).toContain('reversed') + expect(results).toContain('normal') + }) + + it('handles overlapping intervals correctly', () => { + const tree = new IntervalTree() + tree.insert([1, 5], 'a') + tree.insert([3, 8], 'b') + tree.insert([6, 10], 'c') + tree.insert([12, 15], 'd') + + expect(tree.search([4, 4])).toEqual(['a', 'b']) + expect(tree.search([7, 7])).toEqual(['b', 'c']) + expect(tree.search([11, 11])).toEqual([]) + expect(tree.search([1, 15])).toEqual(['a', 'b', 'c', 'd']) + }) + + it('works with genomic-style intervals', () => { + const tree = new IntervalTree() + tree.insert([1000, 2000], 'gene1') + tree.insert([1500, 3000], 'gene2') + tree.insert([5000, 6000], 'gene3') + + expect(tree.search([1700, 1800])).toEqual(['gene1', 'gene2']) + expect(tree.search([4000, 4500])).toEqual([]) + expect(tree.search([5500, 5600])).toEqual(['gene3']) + }) + + it('returns empty array when searching empty tree', () => { + const tree = new IntervalTree() + expect(tree.search([1, 10])).toEqual([]) + }) + + it('handles adjacent non-overlapping intervals', () => { + const tree = new IntervalTree() + tree.insert([1, 5], 'a') + tree.insert([6, 10], 'b') + + expect(tree.search([5, 5])).toEqual(['a']) + expect(tree.search([6, 6])).toEqual(['b']) + // gap between them + expect(tree.search([5.5, 5.5])).toEqual([]) + }) + + it('handles intervals that touch at exactly one point', () => { + const tree = new IntervalTree() + tree.insert([1, 5], 'a') + tree.insert([5, 10], 'b') + + // point 5 is in both intervals + expect(tree.search([5, 5])).toContain('a') + expect(tree.search([5, 5])).toContain('b') + }) + + it('handles negative coordinates', () => { + const tree = new IntervalTree() + tree.insert([-10, -5], 'neg') + tree.insert([-3, 3], 'span') + tree.insert([5, 10], 'pos') + + expect(tree.search([-7, -6])).toEqual(['neg']) + expect(tree.search([0, 0])).toEqual(['span']) + expect(tree.search([-20, 20])).toEqual(['neg', 'span', 'pos']) + }) + + it('handles nested/containing intervals', () => { + const tree = new IntervalTree() + tree.insert([1, 100], 'outer') + tree.insert([25, 75], 'middle') + tree.insert([40, 60], 'inner') + + expect(tree.search([50, 50])).toContain('outer') + expect(tree.search([50, 50])).toContain('middle') + expect(tree.search([50, 50])).toContain('inner') + expect(tree.search([10, 20])).toEqual(['outer']) + }) + + it('handles large coordinates', () => { + const tree = new IntervalTree() + tree.insert([100000000, 100001000], 'gene1') + tree.insert([200000000, 200001000], 'gene2') + + expect(tree.search([100000500, 100000600])).toEqual(['gene1']) + expect(tree.search([150000000, 150000000])).toEqual([]) + }) + + it('handles many intervals (stress test)', () => { + const tree = new IntervalTree() + // insert 1000 intervals + for (let i = 0; i < 1000; i++) { + tree.insert([i * 10, i * 10 + 5], i) + } + + expect(tree.search([500, 505])).toEqual([50]) + expect(tree.search([0, 10000])).toHaveLength(1000) + }) + + it('handles single interval tree', () => { + const tree = new IntervalTree() + tree.insert([5, 10], 'only') + + expect(tree.search([1, 4])).toEqual([]) + expect(tree.search([7, 8])).toEqual(['only']) + expect(tree.search([11, 15])).toEqual([]) + }) +}) diff --git a/packages/core/src/util/IntervalTree.ts b/packages/core/src/util/IntervalTree.ts new file mode 100644 index 0000000000..79980291a0 --- /dev/null +++ b/packages/core/src/util/IntervalTree.ts @@ -0,0 +1,312 @@ +/** + * Vendored and simplified from @flatten-js/interval-tree + * https://github.com/nickolanack/flatten-interval-tree + * License: MIT + * Created by Alex Bol on 3/31/2017. + * + * Simplified to only support numeric intervals and the subset of API we use: + * - constructor, insert, search + */ + +const RB_TREE_COLOR_RED = 1 +const RB_TREE_COLOR_BLACK = 0 +type NodeColor = typeof RB_TREE_COLOR_RED | typeof RB_TREE_COLOR_BLACK + +class Interval { + constructor( + public low: number, + public high: number, + ) {} + + lessThan(other: Interval) { + return ( + this.low < other.low || (this.low === other.low && this.high < other.high) + ) + } + + equalTo(other: Interval) { + return this.low === other.low && this.high === other.high + } + + intersects(other: Interval) { + return !(this.high < other.low || other.high < this.low) + } + + merge(other: Interval) { + return new Interval( + Math.min(this.low, other.low), + Math.max(this.high, other.high), + ) + } +} + +class Node { + left: Node | null = null + right: Node | null = null + parent: Node | null = null + color: NodeColor = RB_TREE_COLOR_BLACK + key: Interval | undefined + values: V[] = [] + max: Interval | undefined + + constructor( + key?: Interval | [number, number], + value?: V, + left?: Node | null, + right?: Node | null, + parent?: Node | null, + color?: NodeColor, + ) { + if (left !== undefined) { + this.left = left + } + if (right !== undefined) { + this.right = right + } + if (parent !== undefined) { + this.parent = parent + } + if (color !== undefined) { + this.color = color + } + if (value !== undefined) { + this.values.push(value) + } + if (key !== undefined) { + if (Array.isArray(key)) { + const [low, high] = key + this.key = + low <= high ? new Interval(low, high) : new Interval(high, low) + } else { + this.key = key + } + this.max = this.key + } + } + + lessThan(other: Node) { + return this.key!.lessThan(other.key!) + } + + equalTo(other: Node) { + return this.key!.equalTo(other.key!) + } + + intersects(other: Node) { + return this.key!.intersects(other.key!) + } + + updateMax() { + this.max = this.key + if (this.right?.max && this.max) { + this.max = this.max.merge(this.right.max) + } + if (this.left?.max && this.max) { + this.max = this.max.merge(this.left.max) + } + } + + notIntersectLeftSubtree(searchNode: Node) { + if (!this.left) { + return true + } + const high = this.left.max?.high ?? this.left.key!.high + return high < searchNode.key!.low + } + + notIntersectRightSubtree(searchNode: Node) { + if (!this.right) { + return true + } + const low = this.right.max?.low ?? this.right.key!.low + return searchNode.key!.high < low + } +} + +export class IntervalTree { + root: Node | null = null + private nilNode = new Node() + + insert(key: [number, number], value: V) { + const existing = this.treeSearch(this.root, new Node(key)) + if (existing) { + existing.values.push(value) + return existing + } + const insertNode = new Node( + key, + value, + this.nilNode, + this.nilNode, + null, + RB_TREE_COLOR_RED, + ) + this.treeInsert(insertNode) + this.recalcMax(insertNode) + return insertNode + } + + search(interval: [number, number]): V[] { + const searchNode = new Node(interval) + const resultNodes: Node[] = [] + this.treeSearchInterval(this.root, searchNode, resultNodes) + const results: V[] = [] + for (const node of resultNodes) { + for (const v of node.values) { + results.push(v) + } + } + return results + } + + private recalcMax(node: Node) { + let current = node + while (current.parent != null) { + current.parent.updateMax() + current = current.parent + } + } + + private treeInsert(insertNode: Node) { + let current: Node | null = this.root + let parent: Node | null = null + + if (this.root == null || this.root === this.nilNode) { + this.root = insertNode + } else { + while (current !== this.nilNode) { + parent = current! + current = insertNode.lessThan(current!) ? current!.left : current!.right + } + insertNode.parent = parent + if (insertNode.lessThan(parent!)) { + parent!.left = insertNode + } else { + parent!.right = insertNode + } + } + this.insertFixup(insertNode) + } + + private insertFixup(insertNode: Node) { + let current = insertNode + while ( + current !== this.root && + current.parent!.color === RB_TREE_COLOR_RED + ) { + if (current.parent === current.parent!.parent!.left) { + const uncle = current.parent!.parent!.right! + if (uncle.color === RB_TREE_COLOR_RED) { + current.parent!.color = RB_TREE_COLOR_BLACK + uncle.color = RB_TREE_COLOR_BLACK + current.parent!.parent!.color = RB_TREE_COLOR_RED + current = current.parent!.parent! + } else { + if (current === current.parent!.right) { + current = current.parent! + this.rotateLeft(current) + } + current.parent!.color = RB_TREE_COLOR_BLACK + current.parent!.parent!.color = RB_TREE_COLOR_RED + this.rotateRight(current.parent!.parent!) + } + } else { + const uncle = current.parent!.parent!.left! + if (uncle.color === RB_TREE_COLOR_RED) { + current.parent!.color = RB_TREE_COLOR_BLACK + uncle.color = RB_TREE_COLOR_BLACK + current.parent!.parent!.color = RB_TREE_COLOR_RED + current = current.parent!.parent! + } else { + if (current === current.parent!.left) { + current = current.parent! + this.rotateRight(current) + } + current.parent!.color = RB_TREE_COLOR_BLACK + current.parent!.parent!.color = RB_TREE_COLOR_RED + this.rotateLeft(current.parent!.parent!) + } + } + } + this.root!.color = RB_TREE_COLOR_BLACK + } + + private treeSearch( + node: Node | null, + searchNode: Node, + ): Node | undefined { + if (node == null || node === this.nilNode) { + return undefined + } + if (searchNode.equalTo(node)) { + return node + } + return searchNode.lessThan(node) + ? this.treeSearch(node.left, searchNode) + : this.treeSearch(node.right, searchNode) + } + + private treeSearchInterval( + node: Node | null, + searchNode: Node, + results: Node[], + ) { + if (node != null && node !== this.nilNode) { + if ( + node.left !== this.nilNode && + !node.notIntersectLeftSubtree(searchNode) + ) { + this.treeSearchInterval(node.left, searchNode, results) + } + if (node.intersects(searchNode)) { + results.push(node) + } + if ( + node.right !== this.nilNode && + !node.notIntersectRightSubtree(searchNode) + ) { + this.treeSearchInterval(node.right, searchNode, results) + } + } + } + + private rotateLeft(x: Node) { + const y = x.right! + x.right = y.left + if (y.left !== this.nilNode) { + y.left!.parent = x + } + y.parent = x.parent + if (x === this.root) { + this.root = y + } else if (x === x.parent!.left) { + x.parent!.left = y + } else { + x.parent!.right = y + } + y.left = x + x.parent = y + x.updateMax() + y.updateMax() + } + + private rotateRight(y: Node) { + const x = y.left! + y.left = x.right + if (x.right !== this.nilNode) { + x.right!.parent = y + } + x.parent = y.parent + if (y === this.root) { + this.root = x + } else if (y === y.parent!.left) { + y.parent!.left = x + } else { + y.parent!.right = x + } + x.right = y + y.parent = x + y.updateMax() + x.updateMax() + } +} diff --git a/packages/core/src/util/colord.ts b/packages/core/src/util/colord.ts index a916e42b14..f89e304eb4 100644 --- a/packages/core/src/util/colord.ts +++ b/packages/core/src/util/colord.ts @@ -1,27 +1,301 @@ -import { colord as colordOriginal, extend } from 'colord' -import mix from 'colord/plugins/mix' -import names from 'colord/plugins/names' +import { namedColorToHex } from './color/cssColorsLevel4.ts' -import type { AnyColor, Colord as ColordBase } from 'colord' +interface RGBA { + r: number + g: number + b: number + a: number +} + +interface HSLA { + h: number + s: number + l: number + a: number +} + +export interface Colord { + alpha(): number + alpha(value: number): Colord + toHex(): string + toRgbString(): string + toHsl(): HSLA + toHslString(): string + mix(color: Colord | string, ratio?: number): Colord + darken(amount?: number): Colord + lighten(amount?: number): Colord +} + +function clamp(value: number, min: number, max: number): number { + return Math.max(min, Math.min(max, value)) +} + +function round(value: number, precision = 0): number { + const mult = 10 ** precision + return Math.round(value * mult) / mult +} + +function parseHex(hex: string): RGBA | null { + const match = /^#([0-9a-f]{3,8})$/i.exec(hex) + if (!match) { + return null + } + const hexStr = match[1]! + if (hexStr.length === 3) { + return { + r: parseInt(hexStr[0]! + hexStr[0], 16), + g: parseInt(hexStr[1]! + hexStr[1], 16), + b: parseInt(hexStr[2]! + hexStr[2], 16), + a: 1, + } + } + if (hexStr.length === 4) { + return { + r: parseInt(hexStr[0]! + hexStr[0], 16), + g: parseInt(hexStr[1]! + hexStr[1], 16), + b: parseInt(hexStr[2]! + hexStr[2], 16), + a: parseInt(hexStr[3]! + hexStr[3], 16) / 255, + } + } + if (hexStr.length === 6) { + return { + r: parseInt(hexStr.slice(0, 2), 16), + g: parseInt(hexStr.slice(2, 4), 16), + b: parseInt(hexStr.slice(4, 6), 16), + a: 1, + } + } + if (hexStr.length === 8) { + return { + r: parseInt(hexStr.slice(0, 2), 16), + g: parseInt(hexStr.slice(2, 4), 16), + b: parseInt(hexStr.slice(4, 6), 16), + a: parseInt(hexStr.slice(6, 8), 16) / 255, + } + } + return null +} + +function parseRgb(str: string): RGBA | null { + const match = + /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+)\s*)?\)$/i.exec( + str, + ) + if (match) { + return { + r: parseInt(match[1]!, 10), + g: parseInt(match[2]!, 10), + b: parseInt(match[3]!, 10), + a: match[4] ? parseFloat(match[4]) : 1, + } + } + return null +} -// Extend Colord interface with mix plugin methods -export interface Colord extends ColordBase { - mix(color2: AnyColor | Colord, ratio?: number): Colord - tints(count?: number): Colord[] - shades(count?: number): Colord[] - tones(count?: number): Colord[] +function parseHsl(str: string): RGBA | null { + const match = + /^hsla?\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*(?:,\s*([\d.]+)\s*)?\)$/i.exec( + str, + ) + if (match) { + const h = parseFloat(match[1]!) + const s = parseFloat(match[2]!) / 100 + const l = parseFloat(match[3]!) / 100 + const a = match[4] ? parseFloat(match[4]) : 1 + return { ...hslToRgb(h, s, l), a } + } + return null } -let initialized = false +function hslToRgb( + h: number, + s: number, + l: number, +): { r: number; g: number; b: number } { + h = ((h % 360) + 360) % 360 + const c = (1 - Math.abs(2 * l - 1)) * s + const x = c * (1 - Math.abs(((h / 60) % 2) - 1)) + const m = l - c / 2 + + let r = 0 + let g = 0 + let b = 0 + + if (h < 60) { + r = c + g = x + } else if (h < 120) { + r = x + g = c + } else if (h < 180) { + g = c + b = x + } else if (h < 240) { + g = x + b = c + } else if (h < 300) { + r = x + b = c + } else { + r = c + b = x + } -function ensurePlugins() { - if (!initialized) { - extend([mix, names]) - initialized = true + return { + r: Math.round((r + m) * 255), + g: Math.round((g + m) * 255), + b: Math.round((b + m) * 255), } } -export function colord(input: Parameters[0]): Colord { - ensurePlugins() - return colordOriginal(input) as Colord +function rgbToHsl( + r: number, + g: number, + b: number, +): { h: number; s: number; l: number } { + r /= 255 + g /= 255 + b /= 255 + + const max = Math.max(r, g, b) + const min = Math.min(r, g, b) + const l = (max + min) / 2 + + if (max === min) { + return { h: 0, s: 0, l } + } + + const d = max - min + const s = l > 0.5 ? d / (2 - max - min) : d / (max + min) + + let h = 0 + if (max === r) { + h = ((g - b) / d + (g < b ? 6 : 0)) / 6 + } else if (max === g) { + h = ((b - r) / d + 2) / 6 + } else { + h = ((r - g) / d + 4) / 6 + } + + return { h: h * 360, s, l } +} + +function parseColor(input: string | { h: number; s: number; l: number }): RGBA { + if (typeof input === 'object') { + const { h, s, l } = input + return { ...hslToRgb(h, s / 100, l / 100), a: 1 } + } + + const str = input.trim().toLowerCase() + + const namedHex = namedColorToHex(str) + if (namedHex) { + return parseHex(namedHex)! + } + + if (str === 'transparent') { + return { r: 0, g: 0, b: 0, a: 0 } + } + + const hex = parseHex(str) + if (hex) { + return hex + } + + const rgb = parseRgb(str) + if (rgb) { + return rgb + } + + const hsl = parseHsl(str) + if (hsl) { + return hsl + } + + return { r: 0, g: 0, b: 0, a: 1 } +} + +function toHex2(n: number): string { + return Math.round(clamp(n, 0, 255)) + .toString(16) + .padStart(2, '0') +} + +function createColord(rgba: RGBA): Colord { + const obj: Colord = { + alpha(value?: number): number | Colord { + if (value === undefined) { + return rgba.a + } + return createColord({ ...rgba, a: clamp(value, 0, 1) }) + }, + + toHex(): string { + const { r, g, b, a } = rgba + if (a < 1) { + return `#${toHex2(r)}${toHex2(g)}${toHex2(b)}${toHex2(a * 255)}` + } + return `#${toHex2(r)}${toHex2(g)}${toHex2(b)}` + }, + + toRgbString(): string { + const { r, g, b, a } = rgba + if (a < 1) { + return `rgba(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)}, ${round(a, 3)})` + } + return `rgb(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)})` + }, + + toHsl(): HSLA { + const { h, s, l } = rgbToHsl(rgba.r, rgba.g, rgba.b) + return { + h: round(h, 1), + s: round(s * 100, 1), + l: round(l * 100, 1), + a: rgba.a, + } + }, + + toHslString(): string { + const { h, s, l } = rgbToHsl(rgba.r, rgba.g, rgba.b) + if (rgba.a < 1) { + return `hsla(${round(h, 1)}, ${round(s * 100, 1)}%, ${round(l * 100, 1)}%, ${round(rgba.a, 3)})` + } + return `hsl(${round(h, 1)}, ${round(s * 100, 1)}%, ${round(l * 100, 1)}%)` + }, + + mix(color2: Colord | string, ratio = 0.5): Colord { + const c2 = + typeof color2 === 'string' + ? parseColor(color2) + : parseColor(color2.toHex()) + const r = rgba.r + (c2.r - rgba.r) * ratio + const g = rgba.g + (c2.g - rgba.g) * ratio + const b = rgba.b + (c2.b - rgba.b) * ratio + const a = rgba.a + (c2.a - rgba.a) * ratio + return createColord({ r, g, b, a }) + }, + + darken(amount = 0.1): Colord { + const { h, s, l } = rgbToHsl(rgba.r, rgba.g, rgba.b) + const newL = clamp(l - amount, 0, 1) + const rgb = hslToRgb(h, s, newL) + return createColord({ ...rgb, a: rgba.a }) + }, + + lighten(amount = 0.1): Colord { + const { h, s, l } = rgbToHsl(rgba.r, rgba.g, rgba.b) + const newL = clamp(l + amount, 0, 1) + const rgb = hslToRgb(h, s, newL) + return createColord({ ...rgb, a: rgba.a }) + }, + } as Colord + + return obj +} + +export function colord( + input: string | { h: number; s: number; l: number }, +): Colord { + return createColord(parseColor(input)) } diff --git a/packages/core/src/util/crypto.ts b/packages/core/src/util/crypto.ts new file mode 100644 index 0000000000..9f956f572e --- /dev/null +++ b/packages/core/src/util/crypto.ts @@ -0,0 +1,306 @@ +// Crypto utilities using Web Crypto API +// Compatible with crypto-js OpenSSL format for AES encryption + +const SALT_PREFIX = 'Salted__' + +// MD5 implementation for EVP_BytesToKey (required for crypto-js compatibility) +function md5(data: Uint8Array): Uint8Array { + // MD5 constants + const S = [ + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, + 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, + 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, + 15, 21, + ] + const K = [ + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, + 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, + 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, + 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, + 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, + 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, + ] + + function leftRotate(x: number, c: number) { + return (x << c) | (x >>> (32 - c)) + } + + // Pre-processing: adding padding bits + const originalLength = data.length + const bitLength = originalLength * 8 + + // Append "1" bit and padding zeros + const paddingLength = (56 - ((originalLength + 1) % 64) + 64) % 64 + const padded = new Uint8Array(originalLength + 1 + paddingLength + 8) + padded.set(data) + padded[originalLength] = 0x80 + + // Append original length in bits as 64-bit little-endian + const view = new DataView(padded.buffer) + view.setUint32(padded.length - 8, bitLength >>> 0, true) + view.setUint32(padded.length - 4, Math.floor(bitLength / 0x100000000), true) + + // Initialize hash values + let a0 = 0x67452301 + let b0 = 0xefcdab89 + let c0 = 0x98badcfe + let d0 = 0x10325476 + + // Process each 512-bit chunk + for (let i = 0; i < padded.length; i += 64) { + const M = new Uint32Array(16) + for (let j = 0; j < 16; j++) { + M[j] = view.getUint32(i + j * 4, true) + } + + let A = a0 + let B = b0 + let C = c0 + let D = d0 + + for (let j = 0; j < 64; j++) { + let F: number + let g: number + + if (j < 16) { + F = (B & C) | (~B & D) + g = j + } else if (j < 32) { + F = (D & B) | (~D & C) + g = (5 * j + 1) % 16 + } else if (j < 48) { + F = B ^ C ^ D + g = (3 * j + 5) % 16 + } else { + F = C ^ (B | ~D) + g = (7 * j) % 16 + } + + F = (F + A + K[j]! + M[g]!) >>> 0 + A = D + D = C + C = B + B = (B + leftRotate(F, S[j]!)) >>> 0 + } + + a0 = (a0 + A) >>> 0 + b0 = (b0 + B) >>> 0 + c0 = (c0 + C) >>> 0 + d0 = (d0 + D) >>> 0 + } + + const result = new Uint8Array(16) + const resultView = new DataView(result.buffer) + resultView.setUint32(0, a0, true) + resultView.setUint32(4, b0, true) + resultView.setUint32(8, c0, true) + resultView.setUint32(12, d0, true) + + return result +} + +// EVP_BytesToKey - OpenSSL key derivation function used by crypto-js +function evpBytesToKey( + password: Uint8Array, + salt: Uint8Array, + keyLen: number, + ivLen: number, +): { key: Uint8Array; iv: Uint8Array } { + const result = new Uint8Array(keyLen + ivLen) + let offset = 0 + let prevHash: Uint8Array = new Uint8Array(0) + + while (offset < keyLen + ivLen) { + const data = new Uint8Array(prevHash.length + password.length + salt.length) + data.set(prevHash) + data.set(password, prevHash.length) + data.set(salt, prevHash.length + password.length) + prevHash = md5(data) + result.set( + prevHash.subarray(0, Math.min(16, keyLen + ivLen - offset)), + offset, + ) + offset += 16 + } + + return { + key: result.slice(0, keyLen), + iv: result.slice(keyLen, keyLen + ivLen), + } +} + +// PKCS7 padding +function pkcs7Pad( + data: Uint8Array, + blockSize: number, +): Uint8Array { + const padding = blockSize - (data.length % blockSize) + const padded = new Uint8Array(data.length + padding) + padded.set(data) + padded.fill(padding, data.length) + return padded +} + +function pkcs7Unpad(data: Uint8Array): Uint8Array { + const padding = data[data.length - 1]! + if (padding > 16 || padding === 0) { + throw new Error('Invalid padding') + } + return data.subarray(0, data.length - padding) +} + +// Convert string to Uint8Array (UTF-8) +function stringToBytes(str: string): Uint8Array { + const encoded = new TextEncoder().encode(str) + // Return a copy with a fresh ArrayBuffer to satisfy TypeScript's strict typing + return encoded.slice() +} + +// Convert Uint8Array to string (UTF-8) +function bytesToString(bytes: Uint8Array): string { + return new TextDecoder().decode(bytes) +} + +// Base64 encode +function base64Encode(data: Uint8Array): string { + let binary = '' + for (const byte of data) { + binary += String.fromCharCode(byte) + } + return btoa(binary) +} + +// Base64 decode +function base64Decode(str: string): Uint8Array { + const binary = atob(str) + const bytes = new Uint8Array(binary.length) + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i) + } + return bytes +} + +/** + * AES encrypt using Web Crypto API, compatible with crypto-js OpenSSL format + */ +export async function aesEncrypt( + plaintext: string, + password: string, +): Promise { + const salt = crypto.getRandomValues(new Uint8Array(8)) + const { key, iv } = evpBytesToKey(stringToBytes(password), salt, 32, 16) + + const cryptoKey = await crypto.subtle.importKey( + 'raw', + key, + { name: 'AES-CBC' }, + false, + ['encrypt'], + ) + + const paddedData = pkcs7Pad(stringToBytes(plaintext), 16) + const encrypted = await crypto.subtle.encrypt( + { name: 'AES-CBC', iv }, + cryptoKey, + paddedData, + ) + + // Format: "Salted__" + salt + ciphertext, then Base64 + const saltPrefix = stringToBytes(SALT_PREFIX) + const result = new Uint8Array( + saltPrefix.length + salt.length + encrypted.byteLength, + ) + result.set(saltPrefix) + result.set(salt, saltPrefix.length) + result.set(new Uint8Array(encrypted), saltPrefix.length + salt.length) + + return base64Encode(result) +} + +/** + * AES decrypt using Web Crypto API, compatible with crypto-js OpenSSL format + */ +export async function aesDecrypt( + ciphertext: string, + password: string, +): Promise { + const data = base64Decode(ciphertext) + + // Check for "Salted__" prefix + const saltPrefix = stringToBytes(SALT_PREFIX) + const hasSalt = + data.length > saltPrefix.length && + bytesToString(data.subarray(0, saltPrefix.length)) === SALT_PREFIX + + if (!hasSalt) { + throw new Error('Invalid encrypted data format') + } + + const salt = data.slice(saltPrefix.length, saltPrefix.length + 8) + const encrypted = data.slice(saltPrefix.length + 8) + + const { key, iv } = evpBytesToKey(stringToBytes(password), salt, 32, 16) + + const cryptoKey = await crypto.subtle.importKey( + 'raw', + key, + { name: 'AES-CBC' }, + false, + ['decrypt'], + ) + + const decrypted = await crypto.subtle.decrypt( + { name: 'AES-CBC', iv }, + cryptoKey, + encrypted, + ) + + return bytesToString(pkcs7Unpad(new Uint8Array(decrypted))) +} + +/** + * SHA256 hash using Web Crypto API + */ +export async function sha256(data: string): Promise { + const encoded = stringToBytes(data) + const hashBuffer = await crypto.subtle.digest('SHA-256', encoded) + return new Uint8Array(hashBuffer) +} + +/** + * Base64 encode a Uint8Array + */ +export function toBase64(data: Uint8Array): string { + return base64Encode(data) +} + +/** + * URL-safe Base64 encode (for OAuth PKCE) + */ +export function toBase64Url(data: Uint8Array): string { + return base64Encode(data) + .replaceAll('+', '-') + .replaceAll('/', '_') + .replaceAll('=', '') +} + +/** + * SHA256 hash and return as Base64 (for OAuth PKCE code challenge) + */ +export async function sha256Base64(data: string): Promise { + const hash = await sha256(data) + return toBase64(hash) +} + +/** + * SHA256 hash and return as URL-safe Base64 (for OAuth PKCE code challenge) + */ +export async function sha256Base64Url(data: string): Promise { + const hash = await sha256(data) + return toBase64Url(hash) +} diff --git a/packages/core/src/util/index.ts b/packages/core/src/util/index.ts index 5114cf445b..8fb61868ca 100644 --- a/packages/core/src/util/index.ts +++ b/packages/core/src/util/index.ts @@ -58,6 +58,7 @@ export * from './coarseStripHTML.ts' export * from './offscreenCanvasPonyfill.tsx' export * from './offscreenCanvasUtils.tsx' export * from './rpc.ts' +export * from './crypto.ts' // WeakMap caches for containing model lookups to avoid repeated tree traversal const containingDisplayCache = new WeakMap< @@ -1439,3 +1440,4 @@ export * from './locString.ts' export * from './stopToken.ts' export * from './tracks.ts' export * from './fileHandleStore.ts' +export { IntervalTree } from './IntervalTree.ts' diff --git a/packages/embedded-core/package.json b/packages/embedded-core/package.json index 39836b6a6c..812148b1ae 100644 --- a/packages/embedded-core/package.json +++ b/packages/embedded-core/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/embedded-core", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 code shared between embedded products", "keywords": [ "jbrowse", diff --git a/packages/product-core/package.json b/packages/product-core/package.json index 9dd68aaf69..4ba78c915e 100644 --- a/packages/product-core/package.json +++ b/packages/product-core/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/product-core", "version": "4.0.4", + "type": "module", "sideEffects": false, "description": "JBrowse 2 code shared between products but not used by plugins", "keywords": [ diff --git a/packages/sv-core/package.json b/packages/sv-core/package.json index 4219824f39..998525722b 100644 --- a/packages/sv-core/package.json +++ b/packages/sv-core/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/sv-core", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 code shared between sv type code", "keywords": [ "jbrowse", diff --git a/packages/text-indexing/package.json b/packages/text-indexing/package.json index cd6f0994a8..72570dbdb6 100644 --- a/packages/text-indexing/package.json +++ b/packages/text-indexing/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/text-indexing", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 text indexing for desktop", "keywords": [ "jbrowse", diff --git a/packages/web-core/package.json b/packages/web-core/package.json index 190fba5031..6f445c722e 100644 --- a/packages/web-core/package.json +++ b/packages/web-core/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/web-core", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 code shared between web-app type products", "keywords": [ "jbrowse", diff --git a/plugins/alignments/package.json b/plugins/alignments/package.json index 430fcf1f4c..fe0b22ce0d 100644 --- a/plugins/alignments/package.json +++ b/plugins/alignments/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-alignments", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 alignments adapters, tracks, etc.", "keywords": [ "jbrowse", diff --git a/plugins/arc/package.json b/plugins/arc/package.json index 1e74c61171..616281d188 100644 --- a/plugins/arc/package.json +++ b/plugins/arc/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-arc", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 arc adapters, tracks, etc.", "keywords": [ "jbrowse", diff --git a/plugins/authentication/package.json b/plugins/authentication/package.json index cf8df14d55..066e062ea6 100644 --- a/plugins/authentication/package.json +++ b/plugins/authentication/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-authentication", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 Authentication", "keywords": [ "jbrowse", diff --git a/plugins/authentication/src/OAuthModel/model.tsx b/plugins/authentication/src/OAuthModel/model.tsx index a0ff9d8f37..4e84c5859b 100644 --- a/plugins/authentication/src/OAuthModel/model.tsx +++ b/plugins/authentication/src/OAuthModel/model.tsx @@ -4,10 +4,10 @@ import { isElectron } from '@jbrowse/core/util' import { types } from '@jbrowse/mobx-state-tree' import { - fixup, generateChallenge, processError, processTokenResponse, + toBase64Url, } from './util.ts' import { getResponseError } from '../util.ts' @@ -15,18 +15,6 @@ import type { OAuthInternetAccountConfigModel } from './configSchema.ts' import type { UriLocation } from '@jbrowse/core/util' import type { Instance } from '@jbrowse/mobx-state-tree' -// ISC Copyright (c) 2020, Andrea Giammarchi, @WebReflection -// https://github.com/WebReflection/uint8-to-base64 -function encode(uint8array: Uint8Array) { - const output = [] - - for (let i = 0, length = uint8array.length; i < length; i++) { - output.push(String.fromCharCode(uint8array[i]!)) - } - - return btoa(output.join('')) -} - interface OAuthData { client_id: string redirect_uri: string @@ -63,7 +51,7 @@ const stateModelFactory = (configSchema: OAuthInternetAccountConfigModel) => { if (!codeVerifier) { const array = new Uint8Array(32) globalThis.crypto.getRandomValues(array) - codeVerifier = fixup(encode(array)) + codeVerifier = toBase64Url(array) } return codeVerifier }, diff --git a/plugins/authentication/src/OAuthModel/util.ts b/plugins/authentication/src/OAuthModel/util.ts index a199bfacaa..cf61c5278f 100644 --- a/plugins/authentication/src/OAuthModel/util.ts +++ b/plugins/authentication/src/OAuthModel/util.ts @@ -1,11 +1,7 @@ -export function fixup(buf: string) { - return buf.replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', '') -} +import { sha256Base64Url } from '@jbrowse/core/util' export async function generateChallenge(val: string) { - const sha256 = await import('crypto-js/sha256').then(f => f.default) - const Base64 = await import('crypto-js/enc-base64') - return fixup(Base64.stringify(sha256(val))) + return sha256Base64Url(val) } // if response is JSON, checks if it needs to remove tokens in error, or just plain throw @@ -31,3 +27,5 @@ export function processTokenResponse( } return data.access_token } + +export { toBase64Url } from '@jbrowse/core/util' diff --git a/plugins/bed/package.json b/plugins/bed/package.json index d00da7e73c..d8b9f85ca6 100644 --- a/plugins/bed/package.json +++ b/plugins/bed/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-bed", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 bed adapters, tracks, etc.", "keywords": [ "jbrowse", @@ -31,7 +32,7 @@ "dependencies": { "@flatten-js/interval-tree": "^2.0.3", "@gmod/bbi": "^8.1.1", - "@gmod/bed": "^2.1.7", + "@gmod/bed": "^2.1.10", "@gmod/tabix": "^3.2.2", "@jbrowse/core": "workspace:^", "@jbrowse/mobx-state-tree": "^5.5.0", diff --git a/plugins/bed/src/BedAdapter/BedAdapter.ts b/plugins/bed/src/BedAdapter/BedAdapter.ts index de40b8de01..cda341f714 100644 --- a/plugins/bed/src/BedAdapter/BedAdapter.ts +++ b/plugins/bed/src/BedAdapter/BedAdapter.ts @@ -1,7 +1,10 @@ -import { IntervalTree } from '@flatten-js/interval-tree' import BED from '@gmod/bed' import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter' -import { SimpleFeature, fetchAndMaybeUnzip } from '@jbrowse/core/util' +import { + IntervalTree, + SimpleFeature, + fetchAndMaybeUnzip, +} from '@jbrowse/core/util' import { openLocation } from '@jbrowse/core/util/io' import { parseLineByLine } from '@jbrowse/core/util/parseLineByLine' import { ObservableCreate } from '@jbrowse/core/util/rxjs' diff --git a/plugins/bed/src/BedGraphAdapter/BedGraphAdapter.ts b/plugins/bed/src/BedGraphAdapter/BedGraphAdapter.ts index b8dd5b8d71..cafcd325c7 100644 --- a/plugins/bed/src/BedGraphAdapter/BedGraphAdapter.ts +++ b/plugins/bed/src/BedGraphAdapter/BedGraphAdapter.ts @@ -1,6 +1,9 @@ -import { IntervalTree } from '@flatten-js/interval-tree' import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter' -import { SimpleFeature, fetchAndMaybeUnzip } from '@jbrowse/core/util' +import { + IntervalTree, + SimpleFeature, + fetchAndMaybeUnzip, +} from '@jbrowse/core/util' import { openLocation } from '@jbrowse/core/util/io' import { parseLineByLine } from '@jbrowse/core/util/parseLineByLine' import { ObservableCreate } from '@jbrowse/core/util/rxjs' diff --git a/plugins/bed/src/BedpeAdapter/BedpeAdapter.ts b/plugins/bed/src/BedpeAdapter/BedpeAdapter.ts index 55e107089a..c80fd13356 100644 --- a/plugins/bed/src/BedpeAdapter/BedpeAdapter.ts +++ b/plugins/bed/src/BedpeAdapter/BedpeAdapter.ts @@ -1,6 +1,5 @@ -import { IntervalTree } from '@flatten-js/interval-tree' import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter' -import { fetchAndMaybeUnzipText } from '@jbrowse/core/util' +import { IntervalTree, fetchAndMaybeUnzipText } from '@jbrowse/core/util' import { openLocation } from '@jbrowse/core/util/io' import { ObservableCreate } from '@jbrowse/core/util/rxjs' diff --git a/plugins/bed/src/util.ts b/plugins/bed/src/util.ts index 96523a7e2e..e5b63245b8 100644 --- a/plugins/bed/src/util.ts +++ b/plugins/bed/src/util.ts @@ -11,7 +11,7 @@ import { isUcscTranscript, } from './generateUcscTranscript.ts' -import type { MinimalFeature } from './types' +import type { MinimalFeature } from './types.ts' import type BED from '@gmod/bed' function defaultParser(fields: string[], splitLine: string[]) { diff --git a/plugins/breakpoint-split-view/package.json b/plugins/breakpoint-split-view/package.json index ce95221df2..d5e844af32 100644 --- a/plugins/breakpoint-split-view/package.json +++ b/plugins/breakpoint-split-view/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-breakpoint-split-view", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 breakpoint detail split view", "keywords": [ "jbrowse", diff --git a/plugins/canvas/package.json b/plugins/canvas/package.json index 9815423f75..be6b4748bb 100644 --- a/plugins/canvas/package.json +++ b/plugins/canvas/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-canvas", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 plugin for canvas features", "keywords": [ "jbrowse", diff --git a/plugins/circular-view/package.json b/plugins/circular-view/package.json index 7e0f098185..7154a01c9d 100644 --- a/plugins/circular-view/package.json +++ b/plugins/circular-view/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-circular-view", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 circular view", "keywords": [ "jbrowse", diff --git a/plugins/comparative-adapters/package.json b/plugins/comparative-adapters/package.json index 8f1c676336..284b27a076 100644 --- a/plugins/comparative-adapters/package.json +++ b/plugins/comparative-adapters/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-comparative-adapters", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 comparative adapters", "keywords": [ "jbrowse", diff --git a/plugins/config/package.json b/plugins/config/package.json index 7ac1d258c0..bb51c49fbe 100644 --- a/plugins/config/package.json +++ b/plugins/config/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-config", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 config utilities", "keywords": [ "jbrowse", diff --git a/plugins/data-management/package.json b/plugins/data-management/package.json index 629947f939..8b16fa2b78 100644 --- a/plugins/data-management/package.json +++ b/plugins/data-management/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-data-management", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 linear genome view", "keywords": [ "jbrowse", diff --git a/plugins/data-management/src/AddConnectionWidget/components/AddConnectionWidget.test.tsx b/plugins/data-management/src/AddConnectionWidget/components/AddConnectionWidget.test.tsx index 7526d0827f..29858f604d 100644 --- a/plugins/data-management/src/AddConnectionWidget/components/AddConnectionWidget.test.tsx +++ b/plugins/data-management/src/AddConnectionWidget/components/AddConnectionWidget.test.tsx @@ -1,8 +1,8 @@ import { ThemeProvider } from '@emotion/react' import { createJBrowseTheme } from '@jbrowse/core/ui' -import { createTestSession } from '@jbrowse/web/src/rootModel' +import { createTestSession } from '@jbrowse/web/src/rootModel/index.js' import { render } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import AddConnectionWidget2 from './AddConnectionWidget.tsx' diff --git a/plugins/data-management/src/AddTrackWidget/components/AddTrackWidget.test.tsx b/plugins/data-management/src/AddTrackWidget/components/AddTrackWidget.test.tsx index 89a83589fc..64b0b69ea3 100644 --- a/plugins/data-management/src/AddTrackWidget/components/AddTrackWidget.test.tsx +++ b/plugins/data-management/src/AddTrackWidget/components/AddTrackWidget.test.tsx @@ -1,4 +1,4 @@ -import { createTestSession } from '@jbrowse/web/src/rootModel' +import { createTestSession } from '@jbrowse/web/src/rootModel/index.js' import { fireEvent, render } from '@testing-library/react' import AddTrackWidget from './AddTrackWidget.tsx' diff --git a/plugins/data-management/src/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.test.tsx b/plugins/data-management/src/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.test.tsx index 4224432fd8..f599536f4f 100644 --- a/plugins/data-management/src/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.test.tsx +++ b/plugins/data-management/src/HierarchicalTrackSelectorWidget/components/HierarchicalTrackSelector.test.tsx @@ -1,10 +1,10 @@ import { createJBrowseTheme } from '@jbrowse/core/ui' -import { createTestSession } from '@jbrowse/web/src/rootModel' +import { createTestSession } from '@jbrowse/web/src/rootModel/index.js' import { ThemeProvider } from '@mui/material' import { fireEvent, render } from '@testing-library/react' import HierarchicalTrackSelector from './HierarchicalTrackSelector.tsx' -import conf from '../../../../../test_data/test_order/config.json' +import conf from '../../../../../test_data/test_order/config.json' with { type: 'json' } import type { HierarchicalTrackSelectorModel } from '../model.ts' diff --git a/plugins/data-management/src/PluginStoreWidget/components/PluginStoreWidget.test.tsx b/plugins/data-management/src/PluginStoreWidget/components/PluginStoreWidget.test.tsx index e4df95b3b9..d4fab82106 100644 --- a/plugins/data-management/src/PluginStoreWidget/components/PluginStoreWidget.test.tsx +++ b/plugins/data-management/src/PluginStoreWidget/components/PluginStoreWidget.test.tsx @@ -1,10 +1,10 @@ import { DialogQueue } from '@jbrowse/app-core' import { createJBrowseTheme } from '@jbrowse/core/ui' import { getParent, getRoot, getSnapshot } from '@jbrowse/mobx-state-tree' -import { createTestSession } from '@jbrowse/web/src/rootModel' +import { createTestSession } from '@jbrowse/web/src/rootModel/index.js' import { ThemeProvider } from '@mui/material' import { render, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import PluginStoreWidget from './PluginStoreWidget.tsx' diff --git a/plugins/dotplot-view/package.json b/plugins/dotplot-view/package.json index fde3836cfc..bb07530f79 100644 --- a/plugins/dotplot-view/package.json +++ b/plugins/dotplot-view/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-dotplot-view", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 dotplot view", "keywords": [ "jbrowse", diff --git a/plugins/dotplot-view/src/index.ts b/plugins/dotplot-view/src/index.ts index 2df65e6c9e..b5ce081f4f 100644 --- a/plugins/dotplot-view/src/index.ts +++ b/plugins/dotplot-view/src/index.ts @@ -13,7 +13,7 @@ import LaunchDotplotViewF from './LaunchDotplotView.ts' import type PluginManager from '@jbrowse/core/PluginManager' import type { AbstractSessionModel } from '@jbrowse/core/util' -export type { DotplotImportFormSyntenyOption } from './DotplotView/components/ImportForm/TrackSelector' +export type { DotplotImportFormSyntenyOption } from './DotplotView/components/ImportForm/TrackSelector.ts' export default class DotplotPlugin extends Plugin { name = 'DotplotPlugin' diff --git a/plugins/gccontent/package.json b/plugins/gccontent/package.json index fa073fbc5a..69c7dddf58 100644 --- a/plugins/gccontent/package.json +++ b/plugins/gccontent/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-gccontent", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 gccontent concepts", "keywords": [ "jbrowse", diff --git a/plugins/gff3/package.json b/plugins/gff3/package.json index aed481c7d7..6aa1cfc8d7 100644 --- a/plugins/gff3/package.json +++ b/plugins/gff3/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-gff3", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 gff3.", "keywords": [ "jbrowse", diff --git a/plugins/gff3/src/Gff3Adapter/Gff3Adapter.ts b/plugins/gff3/src/Gff3Adapter/Gff3Adapter.ts index 0ce1dd850a..ef7d9870e4 100644 --- a/plugins/gff3/src/Gff3Adapter/Gff3Adapter.ts +++ b/plugins/gff3/src/Gff3Adapter/Gff3Adapter.ts @@ -1,6 +1,5 @@ -import { IntervalTree } from '@flatten-js/interval-tree' import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter' -import { fetchAndMaybeUnzip } from '@jbrowse/core/util' +import { IntervalTree, fetchAndMaybeUnzip } from '@jbrowse/core/util' import { openLocation } from '@jbrowse/core/util/io' import { ObservableCreate } from '@jbrowse/core/util/rxjs' import SimpleFeature from '@jbrowse/core/util/simpleFeature' diff --git a/plugins/grid-bookmark/package.json b/plugins/grid-bookmark/package.json index 675c6811c7..5a17aa9cfd 100644 --- a/plugins/grid-bookmark/package.json +++ b/plugins/grid-bookmark/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-grid-bookmark", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 grid bookmark widget", "keywords": [ "jbrowse", diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/sessionSharing.ts b/plugins/grid-bookmark/src/GridBookmarkWidget/sessionSharing.ts index 516d5a12fa..977e1b1e99 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/sessionSharing.ts +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/sessionSharing.ts @@ -1,4 +1,6 @@ // duplicated from products/jbrowse-web/src/sessionSharing.ts ; could possibly be moved into a higher directory and shared between the two +import { aesDecrypt, aesEncrypt } from '@jbrowse/core/util' + import { toUrlSafeB64 } from './utils.ts' // from https://stackoverflow.com/questions/1349404/ @@ -13,18 +15,6 @@ function generateUID(length: number) { .slice(0, length) } -const encrypt = async (text: string, password: string) => { - const AES = await import('crypto-js/aes') - return AES.encrypt(text, password).toString() -} - -const decrypt = async (text: string, password: string) => { - const AES = await import('crypto-js/aes') - const Utf8 = await import('crypto-js/enc-utf8') - const bytes = AES.decrypt(text, password) - return bytes.toString(Utf8) -} - function getErrorMsg(err: string) { try { const obj = JSON.parse(err) @@ -41,7 +31,7 @@ export async function shareSessionToDynamo( ) { const sess = await toUrlSafeB64(JSON.stringify(session)) const password = generateUID(5) - const encryptedSession = await encrypt(sess, password) + const encryptedSession = await aesEncrypt(sess, password) const data = new FormData() data.append('session', encryptedSession) @@ -79,5 +69,5 @@ export async function readSessionFromDynamo( } const json = await response.json() - return decrypt(json.session, password) + return aesDecrypt(json.session, password) } diff --git a/plugins/gtf/package.json b/plugins/gtf/package.json index 69e2c24059..dad5e50bec 100644 --- a/plugins/gtf/package.json +++ b/plugins/gtf/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-gtf", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 gtf feature adapter", "keywords": [ "jbrowse", diff --git a/plugins/gtf/src/GtfAdapter/GtfAdapter.ts b/plugins/gtf/src/GtfAdapter/GtfAdapter.ts index ab643ea9a4..06be3f4fc4 100644 --- a/plugins/gtf/src/GtfAdapter/GtfAdapter.ts +++ b/plugins/gtf/src/GtfAdapter/GtfAdapter.ts @@ -1,6 +1,6 @@ -import { IntervalTree } from '@flatten-js/interval-tree' import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter' import { + IntervalTree, SimpleFeature, doesIntersect2, fetchAndMaybeUnzip, diff --git a/plugins/hic/package.json b/plugins/hic/package.json index 8ced7dec5a..f817e45c85 100644 --- a/plugins/hic/package.json +++ b/plugins/hic/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-hic", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 hic adapters, tracks, etc.", "keywords": [ "jbrowse", diff --git a/plugins/jobs-management/package.json b/plugins/jobs-management/package.json index af8bec6a54..bbb3790d49 100644 --- a/plugins/jobs-management/package.json +++ b/plugins/jobs-management/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-jobs-management", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 jobs management", "keywords": [ "jbrowse", diff --git a/plugins/legacy-jbrowse/package.json b/plugins/legacy-jbrowse/package.json index 48eac310db..ca772d93a9 100644 --- a/plugins/legacy-jbrowse/package.json +++ b/plugins/legacy-jbrowse/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-legacy-jbrowse", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 plugin for connecting to and reading JBrowse 1 data", "keywords": [ "jbrowse", diff --git a/plugins/legacy-jbrowse/src/JBrowse1TextSearchAdapter/HttpMap.test.ts b/plugins/legacy-jbrowse/src/JBrowse1TextSearchAdapter/HttpMap.test.ts index e5a6f07180..d4b6fb1809 100644 --- a/plugins/legacy-jbrowse/src/JBrowse1TextSearchAdapter/HttpMap.test.ts +++ b/plugins/legacy-jbrowse/src/JBrowse1TextSearchAdapter/HttpMap.test.ts @@ -1,9 +1,9 @@ import path from 'path' import HttpMap from './HttpMap.ts' -import first from '../../test_data/names/0.json' -import last from '../../test_data/names/f.json' -import meta from '../../test_data/names/meta.json' +import first from '../../test_data/names/0.json' with { type: 'json' } +import last from '../../test_data/names/f.json' with { type: 'json' } +import meta from '../../test_data/names/meta.json' with { type: 'json' } test('read from meta', async () => { const rootTemplate = path diff --git a/plugins/legacy-jbrowse/src/JBrowse1TextSearchAdapter/JBrowse1TextSearchAdapter.test.ts b/plugins/legacy-jbrowse/src/JBrowse1TextSearchAdapter/JBrowse1TextSearchAdapter.test.ts index 90f78c262e..0264dadcea 100644 --- a/plugins/legacy-jbrowse/src/JBrowse1TextSearchAdapter/JBrowse1TextSearchAdapter.test.ts +++ b/plugins/legacy-jbrowse/src/JBrowse1TextSearchAdapter/JBrowse1TextSearchAdapter.test.ts @@ -4,9 +4,9 @@ import BaseResult from '@jbrowse/core/TextSearch/BaseResults' import Adapter from './JBrowse1TextSearchAdapter.ts' import configSchema from './configSchema.ts' -import first from '../../test_data/names/0.json' -import last from '../../test_data/names/f.json' -import meta from '../../test_data/names/meta.json' +import first from '../../test_data/names/0.json' with { type: 'json' } +import last from '../../test_data/names/f.json' with { type: 'json' } +import meta from '../../test_data/names/meta.json' with { type: 'json' } function mockFetch(url: RequestInfo | URL) { let response = {} diff --git a/plugins/linear-comparative-view/package.json b/plugins/linear-comparative-view/package.json index 9c48dfc9e7..a5d53a0474 100644 --- a/plugins/linear-comparative-view/package.json +++ b/plugins/linear-comparative-view/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-linear-comparative-view", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 linear comparative view", "keywords": [ "jbrowse", diff --git a/plugins/linear-genome-view/package.json b/plugins/linear-genome-view/package.json index c5bb418847..eaef0d2c79 100644 --- a/plugins/linear-genome-view/package.json +++ b/plugins/linear-genome-view/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-linear-genome-view", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 linear genome view", "keywords": [ "jbrowse", diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/CenterLine.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/CenterLine.tsx index 0a44590bf4..8a021e1ae0 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/CenterLine.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/CenterLine.tsx @@ -3,7 +3,7 @@ import { useRef } from 'react' import { makeStyles } from '@jbrowse/core/util/tss-react' import { observer } from 'mobx-react' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/Gridlines.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/Gridlines.tsx index 1c85b6dce0..27b88e495d 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/Gridlines.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/Gridlines.tsx @@ -8,7 +8,7 @@ import { } from '../../BaseLinearDisplay/components/Block.tsx' import { makeTicks } from '../util.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { ContentBlock } from '@jbrowse/core/util/blockTypes' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/Header.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/Header.tsx index c78c2fb664..e819f0b21f 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/Header.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/Header.tsx @@ -10,7 +10,7 @@ import OverviewScalebar from './OverviewScalebar.tsx' import SearchBox from './SearchBox.tsx' import { HEADER_BAR_HEIGHT } from '../consts.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' const useStyles = makeStyles()({ headerBar: { diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderPanControls.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderPanControls.tsx index f36310c3ae..ec48c3085b 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderPanControls.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderPanControls.tsx @@ -5,7 +5,7 @@ import { Button, alpha } from '@mui/material' import { SPACING } from '../consts.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' type LGV = LinearGenomeViewModel const useStyles = makeStyles()(theme => ({ diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderRegionWidth.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderRegionWidth.tsx index b1aeca4fdd..e1111832da 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderRegionWidth.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderRegionWidth.tsx @@ -2,7 +2,7 @@ import { makeStyles } from '@jbrowse/core/util/tss-react' import { Typography } from '@mui/material' import { observer } from 'mobx-react' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' const useStyles = makeStyles()({ bp: { diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderTrackSelectorButton.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderTrackSelectorButton.tsx index a5887bbead..d904f0f0eb 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderTrackSelectorButton.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderTrackSelectorButton.tsx @@ -3,7 +3,7 @@ import { makeStyles } from '@jbrowse/core/util/tss-react' import { IconButton } from '@mui/material' import { observer } from 'mobx-react' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' const useStyles = makeStyles()(theme => ({ toggleButton: { diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderZoomControls.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderZoomControls.tsx index d358cc26f2..abe075b726 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderZoomControls.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/HeaderZoomControls.tsx @@ -9,7 +9,7 @@ import ZoomOut from '@mui/icons-material/ZoomOut' import { IconButton, Slider, Tooltip } from '@mui/material' import { observer } from 'mobx-react' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { SliderValueLabelProps } from '@mui/material' // lazies diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/ImportForm.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/ImportForm.tsx index d9012ce225..79ba2ecfbd 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/ImportForm.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/ImportForm.tsx @@ -16,7 +16,7 @@ import { observer } from 'mobx-react' import ImportFormRefNameAutocomplete from './ImportFormRefNameAutocomplete.tsx' import { handleSelectedRegion, navToOption } from '../../searchUtils.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type BaseResult from '@jbrowse/core/TextSearch/BaseResults' const useStyles = makeStyles()(theme => ({ diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/ImportFormRefNameAutocomplete.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/ImportFormRefNameAutocomplete.tsx index 5e21f19e25..c4b8100d03 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/ImportFormRefNameAutocomplete.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/ImportFormRefNameAutocomplete.tsx @@ -4,7 +4,7 @@ import { observer } from 'mobx-react' import RefNameAutocomplete from './RefNameAutocomplete/index.tsx' import { fetchResults } from './util.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type BaseResult from '@jbrowse/core/TextSearch/BaseResults' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeView.test.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeView.test.tsx index 665246e249..c0c84aed9b 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeView.test.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeView.test.tsx @@ -1,5 +1,5 @@ import { createJBrowseTheme } from '@jbrowse/core/ui' -import { createTestSession } from '@jbrowse/web/src/rootModel' +import { createTestSession } from '@jbrowse/web/src/rootModel/index.js' import { ThemeProvider } from '@mui/material' import { fireEvent, render, waitFor } from '@testing-library/react' diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeView.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeView.tsx index bfdab2e4ed..2b4578b139 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeView.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeView.tsx @@ -5,7 +5,7 @@ import { observer } from 'mobx-react' import LinearGenomeViewContainer from './LinearGenomeViewContainer.tsx' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' // lazies const ImportForm = lazy(() => import('./ImportForm.tsx')) diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeViewContainer.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeViewContainer.tsx index b1a44a5054..723d5bd6a9 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeViewContainer.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/LinearGenomeViewContainer.tsx @@ -9,7 +9,7 @@ import { observer } from 'mobx-react' import TrackContainer from './TrackContainer.tsx' import TracksContainer from './TracksContainer.tsx' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' // lazies const NoTracksActiveButton = lazy(() => import('./NoTracksActiveButton.tsx')) diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/MiniControls.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/MiniControls.tsx index 3ec47d7938..1e11225862 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/MiniControls.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/MiniControls.tsx @@ -7,7 +7,7 @@ import ZoomOut from '@mui/icons-material/ZoomOut' import { IconButton, Paper, alpha } from '@mui/material' import { observer } from 'mobx-react' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' const useStyles = makeStyles()(theme => ({ background: { diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/NoTracksActiveButton.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/NoTracksActiveButton.tsx index cfd3e84519..d5d41b2a6d 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/NoTracksActiveButton.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/NoTracksActiveButton.tsx @@ -3,7 +3,7 @@ import { makeStyles } from '@jbrowse/core/util/tss-react' import { Button, Paper, Typography } from '@mui/material' import { observer } from 'mobx-react' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' const useStyles = makeStyles()(theme => ({ note: { diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewRubberband.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewRubberband.tsx index 9f92646988..1d1527cd12 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewRubberband.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewRubberband.tsx @@ -8,7 +8,7 @@ import OverviewRubberbandHoverTooltip from './OverviewRubberbandHoverTooltip.tsx import RubberbandSpan from './RubberbandSpan.tsx' import { getRelativeX } from './util.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewRubberbandHoverTooltip.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewRubberbandHoverTooltip.tsx index 702181bf11..e298bbc098 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewRubberbandHoverTooltip.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewRubberbandHoverTooltip.tsx @@ -3,7 +3,7 @@ import { makeStyles } from '@jbrowse/core/util/tss-react' import { Tooltip } from '@mui/material' import { observer } from 'mobx-react' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebar.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebar.tsx index 4a5e6f4181..379b2447da 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebar.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebar.tsx @@ -15,7 +15,7 @@ import OverviewScalebarTickLabels from './OverviewScalebarTickLabels.tsx' import { getCytobands } from './util.ts' import { HEADER_BAR_HEIGHT, HEADER_OVERVIEW_HEIGHT } from '../consts.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel' import type { ContentBlock } from '@jbrowse/core/util/blockTypes' diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebarPolygon.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebarPolygon.tsx index ef3499fe8b..942170eb87 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebarPolygon.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebarPolygon.tsx @@ -4,7 +4,7 @@ import { observer } from 'mobx-react' import { HEADER_BAR_HEIGHT } from '../consts.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel' const OverviewScalebarPolygon = observer(function OverviewScalebarPolygon({ diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebarTickLabels.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebarTickLabels.tsx index c70a783a36..5eb6e350e4 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebarTickLabels.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebarTickLabels.tsx @@ -3,11 +3,10 @@ import { makeStyles } from '@jbrowse/core/util/tss-react' import { Typography } from '@mui/material' import { observer } from 'mobx-react' -// core import { HEADER_OVERVIEW_HEIGHT } from '../consts.ts' import { chooseGridPitch } from '../util.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel' import type { ContentBlock } from '@jbrowse/core/util/blockTypes' diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/Rubberband.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/Rubberband.tsx index 780684db4e..1854976a3e 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/Rubberband.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/Rubberband.tsx @@ -8,7 +8,7 @@ import RubberbandSpan from './RubberbandSpan.tsx' import VerticalGuide from './VerticalGuide.tsx' import { useRangeSelect } from './useRangeSelect.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/Scalebar.test.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/Scalebar.test.tsx index 8223436519..1e2986d289 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/Scalebar.test.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/Scalebar.test.tsx @@ -1,4 +1,4 @@ -import { createTestSession } from '@jbrowse/web/src/rootModel' +import { createTestSession } from '@jbrowse/web/src/rootModel/index.js' import { render, waitFor } from '@testing-library/react' import Scalebar from './Scalebar.tsx' diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/Scalebar.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/Scalebar.tsx index 582bcbf25d..d08f3b8078 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/Scalebar.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/Scalebar.tsx @@ -8,7 +8,7 @@ import Gridlines from './Gridlines.tsx' import ScalebarCoordinateLabels from './ScalebarCoordinateLabels.tsx' import ScalebarRefNameLabels from './ScalebarRefNameLabels.tsx' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/ScalebarCoordinateLabels.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/ScalebarCoordinateLabels.tsx index d58ad1a2cc..5fa93508c9 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/ScalebarCoordinateLabels.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/ScalebarCoordinateLabels.tsx @@ -4,7 +4,7 @@ import { observer } from 'mobx-react' import { makeTicks } from '../util.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { ContentBlock } from '@jbrowse/core/util/blockTypes' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/ScalebarRefNameLabels.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/ScalebarRefNameLabels.tsx index e0354395d6..4016900033 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/ScalebarRefNameLabels.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/ScalebarRefNameLabels.tsx @@ -4,7 +4,7 @@ import { Menu } from '@jbrowse/core/ui' import { makeStyles } from '@jbrowse/core/util/tss-react' import { observer } from 'mobx-react' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/TrackContainer.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/TrackContainer.tsx index 1cf87f2fe7..a7cc5f6c05 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/TrackContainer.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/TrackContainer.tsx @@ -12,7 +12,7 @@ import TrackLabelContainer from './TrackLabelContainer.tsx' import TrackRenderingContainer from './TrackRenderingContainer.tsx' import { shouldSwapTracks } from './util.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { BaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models' const useStyles = makeStyles()(theme => ({ diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabel.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabel.tsx index c1c7460195..7e7d388dc5 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabel.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabel.tsx @@ -9,7 +9,7 @@ import { observer } from 'mobx-react' import TrackLabelDragHandle from './TrackLabelDragHandle.tsx' import TrackLabelMenu from './TrackLabelMenu.tsx' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { BaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models' const useStyles = makeStyles()(theme => ({ diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabelContainer.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabelContainer.tsx index cf4eb3c6c5..66ea5ddb05 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabelContainer.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabelContainer.tsx @@ -3,7 +3,7 @@ import { observer } from 'mobx-react' import TrackLabel from './TrackLabel.tsx' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { BaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models' const useStyles = makeStyles()({ diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabelDragHandle.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabelDragHandle.tsx index e0d509bb51..771e6d57a5 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabelDragHandle.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/TrackLabelDragHandle.tsx @@ -1,7 +1,7 @@ import { makeStyles } from '@jbrowse/core/util/tss-react' import DragIcon from '@mui/icons-material/DragIndicator' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { BaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models' const useStyles = makeStyles()({ diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/TrackRenderingContainer.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/TrackRenderingContainer.tsx index e8f3e6b98f..14b3b91037 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/TrackRenderingContainer.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/TrackRenderingContainer.tsx @@ -4,7 +4,7 @@ import { LoadingEllipses } from '@jbrowse/core/ui' import { makeStyles } from '@jbrowse/core/util/tss-react' import { observer } from 'mobx-react' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { BaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models' const useStyles = makeStyles()({ diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/TracksContainer.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/TracksContainer.tsx index b8d92d814f..212e821d87 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/TracksContainer.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/TracksContainer.tsx @@ -14,7 +14,7 @@ import { useRangeSelect } from './useRangeSelect.ts' import { useSideScroll } from './useSideScroll.ts' import { useWheelScroll } from './useWheelScroll.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' const CenterLine = lazy(() => import('./CenterLine.tsx')) const Highlight = lazy(() => import('./Highlight.tsx')) diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/VerticalGuide.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/VerticalGuide.tsx index 7f1a719bb3..fc56ee123f 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/VerticalGuide.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/VerticalGuide.tsx @@ -3,7 +3,7 @@ import { makeStyles } from '@jbrowse/core/util/tss-react' import { Tooltip } from '@mui/material' import { observer } from 'mobx-react' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/useRangeSelect.ts b/plugins/linear-genome-view/src/LinearGenomeView/components/useRangeSelect.ts index bb64275c61..43e67b8662 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/useRangeSelect.ts +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/useRangeSelect.ts @@ -3,7 +3,7 @@ import { useCallback, useEffect, useState } from 'react' import { getRelativeX } from './util.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' interface AnchorPosition { offsetX: number diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/useSideScroll.ts b/plugins/linear-genome-view/src/LinearGenomeView/components/useSideScroll.ts index 83314a0dd7..7e88648fb4 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/useSideScroll.ts +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/useSideScroll.ts @@ -1,7 +1,7 @@ import type React from 'react' import { useEffect, useRef, useState } from 'react' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' export function useSideScroll(model: LinearGenomeViewModel) { const [mouseDragging, setMouseDragging] = useState(false) diff --git a/plugins/linear-genome-view/src/LinearGenomeView/index.test.ts b/plugins/linear-genome-view/src/LinearGenomeView/index.test.ts index 08c505cea3..77ff2d5eed 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/index.test.ts +++ b/plugins/linear-genome-view/src/LinearGenomeView/index.test.ts @@ -11,8 +11,8 @@ import { waitFor } from '@testing-library/react' import { stateModelFactory } from './index.ts' import { BaseLinearDisplayComponent } from '../index.ts' -import hg38Regions from './hg38DisplayedRegions.json' -import volvoxDisplayedRegions from './volvoxDisplayedRegions.json' +import hg38Regions from './hg38DisplayedRegions.json' with { type: 'json' } +import volvoxDisplayedRegions from './volvoxDisplayedRegions.json' with { type: 'json' } import { stateModelFactory as LinearBasicDisplayStateModelFactory } from '../LinearBareDisplay/index.ts' import type { LinearGenomeViewModel } from './index.ts' diff --git a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGGridlines.tsx b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGGridlines.tsx index f7d11135c6..1bcbc67883 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGGridlines.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGGridlines.tsx @@ -3,7 +3,7 @@ import { useTheme } from '@mui/material' import { makeTicks } from '../util.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGHeader.tsx b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGHeader.tsx index 9082ff1ff4..c5bcb3d30c 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGHeader.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGHeader.tsx @@ -8,7 +8,7 @@ import Cytobands from '../components/Cytobands.tsx' import OverviewScalebarPolygon from '../components/OverviewScalebarPolygon.tsx' import { HEADER_OVERVIEW_HEIGHT } from '../consts.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' export default function SVGHeader({ model, diff --git a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGLinearGenomeView.tsx b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGLinearGenomeView.tsx index 4e24f16c2d..abb3d521d8 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGLinearGenomeView.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGLinearGenomeView.tsx @@ -18,7 +18,7 @@ import SVGHeader from './SVGHeader.tsx' import SVGTracks from './SVGTracks.tsx' import { totalHeight } from './util.ts' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { ExportSvgOptions } from '../types.ts' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGRegionSeparators.tsx b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGRegionSeparators.tsx index f1ec1a0dec..d0e5e050ca 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGRegionSeparators.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGRegionSeparators.tsx @@ -1,4 +1,4 @@ -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGRuler.tsx b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGRuler.tsx index a9058fb170..de10865b66 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGRuler.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGRuler.tsx @@ -4,7 +4,7 @@ import { useTheme } from '@mui/material' import { makeTicks } from '../util.ts' import SVGRegionSeparators from './SVGRegionSeparators.tsx' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGScalebar.tsx b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGScalebar.tsx index 803e2ffcfa..b780443e34 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGScalebar.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGScalebar.tsx @@ -1,7 +1,7 @@ import { getBpDisplayStr, stripAlpha } from '@jbrowse/core/util' import { useTheme } from '@mui/material' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' type LGV = LinearGenomeViewModel diff --git a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGTracks.tsx b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGTracks.tsx index b192310e55..b7766fecfe 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGTracks.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/svgcomponents/SVGTracks.tsx @@ -4,7 +4,7 @@ import { getTrackName } from '@jbrowse/core/util/tracks' import SVGRegionSeparators from './SVGRegionSeparators.tsx' import SVGTrackLabel from './SVGTrackLabel.tsx' -import type { LinearGenomeViewModel } from '..' +import type { LinearGenomeViewModel } from '../index.ts' import type { AnyConfigurationModel } from '@jbrowse/core/configuration' type LGV = LinearGenomeViewModel diff --git a/plugins/lollipop/package.json b/plugins/lollipop/package.json index 27cb9a89f1..75b3fb54a3 100644 --- a/plugins/lollipop/package.json +++ b/plugins/lollipop/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-lollipop", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 plugin for lollipops", "keywords": [ "jbrowse", diff --git a/plugins/menus/package.json b/plugins/menus/package.json index 9b849bd063..2f59009866 100644 --- a/plugins/menus/package.json +++ b/plugins/menus/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-menus", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 basic menus", "keywords": [ "jbrowse", diff --git a/plugins/rdf/package.json b/plugins/rdf/package.json index 5531b056c3..1c018310a0 100644 --- a/plugins/rdf/package.json +++ b/plugins/rdf/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-rdf", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 RDF resources", "keywords": [ "jbrowse", diff --git a/plugins/rdf/src/SPARQLAdapter/SPARQLAdapter.test.ts b/plugins/rdf/src/SPARQLAdapter/SPARQLAdapter.test.ts index 38e7cccb2c..2312763ea4 100644 --- a/plugins/rdf/src/SPARQLAdapter/SPARQLAdapter.test.ts +++ b/plugins/rdf/src/SPARQLAdapter/SPARQLAdapter.test.ts @@ -3,9 +3,9 @@ import { toArray } from 'rxjs/operators' import Adapter from './SPARQLAdapter.ts' import configSchema from './configSchema.ts' -import emptyQueryResponse from './test_data/emptyQueryResponse.json' -import queryResponse from './test_data/queryResponse.json' -import refNamesResponse from './test_data/refNamesResponse.json' +import emptyQueryResponse from './test_data/emptyQueryResponse.json' with { type: 'json' } +import queryResponse from './test_data/queryResponse.json' with { type: 'json' } +import refNamesResponse from './test_data/refNamesResponse.json' with { type: 'json' } // window.fetch = jest.fn(url => new Promise(resolve => resolve())) diff --git a/plugins/sequence/package.json b/plugins/sequence/package.json index f70943cfad..6b53e28f3c 100644 --- a/plugins/sequence/package.json +++ b/plugins/sequence/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-sequence", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 sequence adapters, tracks, etc.", "keywords": [ "jbrowse", diff --git a/plugins/spreadsheet-view/package.json b/plugins/spreadsheet-view/package.json index ddc56bb7e2..5bdfa15fec 100644 --- a/plugins/spreadsheet-view/package.json +++ b/plugins/spreadsheet-view/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-spreadsheet-view", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 spreadsheet view", "keywords": [ "jbrowse", diff --git a/plugins/sv-inspector/package.json b/plugins/sv-inspector/package.json index a10185726c..ca8a868a58 100644 --- a/plugins/sv-inspector/package.json +++ b/plugins/sv-inspector/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-sv-inspector", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 SV inspector view", "keywords": [ "jbrowse", diff --git a/plugins/text-indexing/package.json b/plugins/text-indexing/package.json index 6f43c84d17..47be3b58a2 100644 --- a/plugins/text-indexing/package.json +++ b/plugins/text-indexing/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-text-indexing", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 text indexing rpc method", "keywords": [ "jbrowse", diff --git a/plugins/trix/package.json b/plugins/trix/package.json index e531f52e72..781e89e7ac 100644 --- a/plugins/trix/package.json +++ b/plugins/trix/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-trix", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 trix text search adapter", "keywords": [ "jbrowse", @@ -32,7 +33,7 @@ "react": ">=18.0.0" }, "dependencies": { - "@gmod/trix": "^3.0.5", + "@gmod/trix": "^3.0.9", "@jbrowse/core": "workspace:^" }, "publishConfig": { diff --git a/plugins/variants/package.json b/plugins/variants/package.json index 276998555d..fd21d4a56e 100644 --- a/plugins/variants/package.json +++ b/plugins/variants/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-variants", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 variant adapters, tracks, etc.", "keywords": [ "jbrowse", diff --git a/plugins/variants/src/VcfAdapter/VcfAdapter.ts b/plugins/variants/src/VcfAdapter/VcfAdapter.ts index 31f77fc2a4..3c9cf85e94 100644 --- a/plugins/variants/src/VcfAdapter/VcfAdapter.ts +++ b/plugins/variants/src/VcfAdapter/VcfAdapter.ts @@ -1,7 +1,6 @@ -import { IntervalTree } from '@flatten-js/interval-tree' import VcfParser from '@gmod/vcf' import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter' -import { fetchAndMaybeUnzip } from '@jbrowse/core/util' +import { IntervalTree, fetchAndMaybeUnzip } from '@jbrowse/core/util' import { openLocation } from '@jbrowse/core/util/io' import { ObservableCreate } from '@jbrowse/core/util/rxjs' diff --git a/plugins/wiggle/package.json b/plugins/wiggle/package.json index 833964fb0f..c25cbd3161 100644 --- a/plugins/wiggle/package.json +++ b/plugins/wiggle/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/plugin-wiggle", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 wiggle adapters, tracks, etc.", "keywords": [ "jbrowse", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c28fb0c725..33e4469a44 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -209,9 +209,6 @@ importers: electron-builder: specifier: ^25.1.8 version: 25.1.8(electron-builder-squirrel-windows@25.1.8) - electron-mock-ipc: - specifier: ^0.3.14 - version: 0.3.14(electron@40.0.0) eslint: specifier: ^9.39.2 version: 9.39.2 @@ -437,9 +434,6 @@ importers: canvas2svg: specifier: ^1.0.16 version: 1.0.16 - colord: - specifier: ^2.9.3 - version: 2.9.3 copy-to-clipboard: specifier: ^3.3.3 version: 3.3.3 @@ -470,9 +464,6 @@ importers: librpc-web-mod: specifier: ^2.1.1 version: 2.1.1 - load-script: - specifier: ^2.0.0 - version: 2.0.0 mobx: specifier: ^6.15.0 version: 6.15.0 @@ -765,8 +756,8 @@ importers: specifier: ^8.1.1 version: 8.1.1 '@gmod/bed': - specifier: ^2.1.7 - version: 2.1.7 + specifier: ^2.1.10 + version: 2.1.10 '@gmod/tabix': specifier: ^3.2.2 version: 3.2.2 @@ -1539,8 +1530,8 @@ importers: plugins/trix: dependencies: '@gmod/trix': - specifier: ^3.0.5 - version: 3.0.5 + specifier: ^3.0.9 + version: 3.0.9 '@jbrowse/core': specifier: workspace:^ version: link:../../packages/core @@ -1885,8 +1876,8 @@ importers: specifier: ^4.35.5 version: 4.35.5 cross-env: - specifier: ^7.0.3 - version: 7.0.3 + specifier: ^10.1.0 + version: 10.1.0 electron: specifier: 40.0.0 version: 40.0.0 @@ -1894,8 +1885,8 @@ importers: specifier: ^40.0.0 version: 40.0.0 selenium-webdriver: - specifier: ^4.39.0 - version: 4.39.0 + specifier: ^4.40.0 + version: 4.40.0 products/jbrowse-img: dependencies: @@ -3223,6 +3214,9 @@ packages: '@emotion/weak-memoize@0.4.0': resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} + '@epic-web/invariant@1.0.0': + resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} + '@esbuild/aix-ppc64@0.27.2': resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} engines: {node: '>=18'} @@ -3459,8 +3453,8 @@ packages: resolution: {integrity: sha512-Vpz/ezTAUslIsKCEvsA0zPHkobrwMCUw7E+hvAwsBP8H1BiD67Scak5hX8cJI7Sv4NRgKB/Zjvq0XfVa/wZ6KQ==} engines: {node: '>=6'} - '@gmod/bed@2.1.7': - resolution: {integrity: sha512-ddxGWgcbI984gTdsIPbrFpM2h7s7kNWWKmxD+xKtv5N+Pe4RaoPdJ6nAc33QFkUjuM2s+3QIf81qjFLDVGhLsA==} + '@gmod/bed@2.1.10': + resolution: {integrity: sha512-begb47SbolFRLXUaQA8w1yBdzPFEw+FncHvfLMxfDC0nacDeU3N72BUPhK4Dq51mi8QpN4NfT3dR8O2j2g1Lww==} engines: {node: '>=6'} '@gmod/bgzf-filehandle@6.0.10': @@ -3493,8 +3487,8 @@ packages: resolution: {integrity: sha512-lQQCuanjsnVNzH9n21LTMGykvRbpLbEQk3AL+aKnjf72gfV07mLZ116gtvDFu5huxbxWialOHGGC7iJAQDEi5Q==} engines: {node: '>=6'} - '@gmod/trix@3.0.5': - resolution: {integrity: sha512-/v8Sn9OUT5UYlhNW3GE4wedxo8gHn1Zgs9DYRwjpjsetNgFtWrEZwjTHaAkTE6HDuYd5qtEyT1C0leD3ljURoQ==} + '@gmod/trix@3.0.9': + resolution: {integrity: sha512-fOVWXVRKt+51tHo9QBk7kpwYqsoDOqtvtw/Mio+FX4JGxV6rVduCpljtSwd2sYe8GyCpmUFOJtWQMAVXdqHsHw==} engines: {node: '>=10'} '@gmod/twobit@6.0.1': @@ -5540,9 +5534,9 @@ packages: create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - cross-env@7.0.3: - resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} - engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + cross-env@10.1.0: + resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==} + engines: {node: '>=20'} hasBin: true cross-fetch@3.2.0: @@ -5954,11 +5948,6 @@ packages: electron-localshortcut@3.2.1: resolution: {integrity: sha512-DWvhKv36GsdXKnaFFhEiK8kZZA+24/yFLgtTwJJHc7AFgDjNRIBJZ/jq62Y/dWv9E4ypYwrVWN2bVrCYw1uv7Q==} - electron-mock-ipc@0.3.14: - resolution: {integrity: sha512-DouQtwlfk/lDfMQXo7ltefMoJ5t6FTUTfTh99zEJNYok+SlUMzbOFMW5cBzem20NOJ2aAD4Lrc/26CuXCWCTdw==} - peerDependencies: - electron: '>=6.0.0' - electron-publish@25.1.7: resolution: {integrity: sha512-+jbTkR9m39eDBMP4gfbqglDd6UvBC7RLh5Y0MhFSsc6UkGHj9Vj9TWobxevHYMMqmoujL11ZLjfPpMX+Pt6YEg==} @@ -7430,9 +7419,6 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - load-script@2.0.0: - resolution: {integrity: sha512-km6cyoPW4rM22JMGb+SHUKPMZVDpUaMpMAKrv8UHWllIxc/qjgMGHD91nY+5hM+/NFs310OZ2pqQeJKs7HqWPA==} - loader-runner@4.3.1: resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} engines: {node: '>=6.11.5'} @@ -8553,8 +8539,8 @@ packages: select-hose@2.0.0: resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} - selenium-webdriver@4.39.0: - resolution: {integrity: sha512-NAs9jCU+UeZ/ZmRb8R6zOp7N8eMklefdBYASnaRmCNXdgFE8w3OCxxZmLixkwqnGDHY5VF7hCulfw1Mls43N/A==} + selenium-webdriver@4.40.0: + resolution: {integrity: sha512-dU0QbnVKdPmoNP8OtMCazRdtU2Ux6Wl4FEpG1iwUbDeajJK1dBAywBLrC1D7YFRtogHzN96AbXBgBAJaarcysw==} engines: {node: '>= 20.0.0'} selfsigned@5.5.0: @@ -10676,6 +10662,8 @@ snapshots: '@emotion/weak-memoize@0.4.0': {} + '@epic-web/invariant@1.0.0': {} + '@esbuild/aix-ppc64@0.27.2': optional: true @@ -10852,7 +10840,7 @@ snapshots: pako-esm2: 2.0.2 rxjs: 7.8.2 - '@gmod/bed@2.1.7': {} + '@gmod/bed@2.1.10': {} '@gmod/bgzf-filehandle@6.0.10': dependencies: @@ -10894,7 +10882,7 @@ snapshots: '@jbrowse/quick-lru': 7.3.5 generic-filehandle2: 2.0.18 - '@gmod/trix@3.0.5': {} + '@gmod/trix@3.0.9': {} '@gmod/twobit@6.0.1': dependencies: @@ -13375,8 +13363,9 @@ snapshots: create-require@1.1.1: optional: true - cross-env@7.0.3: + cross-env@10.1.0: dependencies: + '@epic-web/invariant': 1.0.0 cross-spawn: 7.0.6 cross-fetch@3.2.0(encoding@0.1.13): @@ -13830,10 +13819,6 @@ snapshots: transitivePeerDependencies: - supports-color - electron-mock-ipc@0.3.14(electron@40.0.0): - dependencies: - electron: 40.0.0 - electron-publish@25.1.7: dependencies: '@types/fs-extra': 9.0.13 @@ -15793,8 +15778,6 @@ snapshots: lines-and-columns@1.2.4: {} - load-script@2.0.0: {} - loader-runner@4.3.1: {} locate-path@5.0.0: @@ -16958,7 +16941,7 @@ snapshots: select-hose@2.0.0: {} - selenium-webdriver@4.39.0: + selenium-webdriver@4.40.0: dependencies: '@bazel/runfiles': 6.5.0 jszip: 3.10.1 diff --git a/products/jbrowse-cli/bin/run b/products/jbrowse-cli/bin/run index b0d3354421..7071b2e935 100755 --- a/products/jbrowse-cli/bin/run +++ b/products/jbrowse-cli/bin/run @@ -1,3 +1,4 @@ #!/usr/bin/env node -require('../dist/index.js').main(process.argv.slice(2)) +import { main } from '../dist/index.js' +main(process.argv.slice(2)) diff --git a/products/jbrowse-cli/package.json b/products/jbrowse-cli/package.json index 31126a182f..cb54baa77a 100644 --- a/products/jbrowse-cli/package.json +++ b/products/jbrowse-cli/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/cli", "version": "4.0.4", + "type": "module", "description": "A command line tool for working with JBrowse 2", "keywords": [ "jbrowse", @@ -29,7 +30,7 @@ }, "scripts": { "prebuild": "pnpm clean", - "build": "tsc && webpack", + "build": "tsc && webpack -c webpack.config.mjs", "clean": "rimraf bundle", "prepack": "pnpm clean && pnpm build && pnpm generate-readme", "generate-readme": "./generate_readme.sh > README.md" diff --git a/products/jbrowse-cli/src/utils.ts b/products/jbrowse-cli/src/utils.ts index 19a8d2cb4e..fa36d1975c 100644 --- a/products/jbrowse-cli/src/utils.ts +++ b/products/jbrowse-cli/src/utils.ts @@ -198,7 +198,7 @@ function wrapText(text: string, width: number, indent: string) { } } } - return lines.join('\n' + indent) + return lines.join(`\n${indent}`) } export function printHelp({ diff --git a/products/jbrowse-cli/tsconfig.json b/products/jbrowse-cli/tsconfig.json index a7f3dea983..6d741bd82d 100644 --- a/products/jbrowse-cli/tsconfig.json +++ b/products/jbrowse-cli/tsconfig.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "module": "commonjs", "outDir": "dist", "rootDir": "src", "strict": true, diff --git a/products/jbrowse-cli/webpack.config.js b/products/jbrowse-cli/webpack.config.mjs similarity index 80% rename from products/jbrowse-cli/webpack.config.js rename to products/jbrowse-cli/webpack.config.mjs index 1065a6efd7..c627a79a58 100644 --- a/products/jbrowse-cli/webpack.config.js +++ b/products/jbrowse-cli/webpack.config.mjs @@ -1,7 +1,11 @@ -const path = require('path') -const webpack = require('webpack') +import path from 'path' +import { fileURLToPath } from 'url' -module.exports = { +import webpack from 'webpack' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) + +export default { mode: 'development', entry: './src/bin.ts', target: 'node', diff --git a/products/jbrowse-desktop/package.json b/products/jbrowse-desktop/package.json index b6554bb528..6e51cd7597 100644 --- a/products/jbrowse-desktop/package.json +++ b/products/jbrowse-desktop/package.json @@ -105,10 +105,10 @@ }, "devDependencies": { "@types/selenium-webdriver": "^4.35.5", - "cross-env": "^7.0.3", + "cross-env": "^10.1.0", "electron": "40.0.0", "electron-chromedriver": "^40.0.0", - "selenium-webdriver": "^4.39.0" + "selenium-webdriver": "^4.40.0" }, "browserslist": [ "last 1 chrome version" diff --git a/products/jbrowse-desktop/src/components/JBrowse.test.tsx b/products/jbrowse-desktop/src/components/JBrowse.test.tsx deleted file mode 100644 index 0b8ff5b96c..0000000000 --- a/products/jbrowse-desktop/src/components/JBrowse.test.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React from 'react' - -// must import first to create window.require as side effect - -import PluginManager from '@jbrowse/core/PluginManager' -import { fireEvent, render } from '@testing-library/react' - -// locals -import JBrowse from './JBrowse.tsx' -import { - ipcMain, - ipcRenderer, -} from '../../../../packages/__mocks__/electron.ts' -import configSnapshot from '../../test_data/volvox/config.json' -import corePlugins from '../corePlugins.ts' -import JBrowseRootModelFactory from '../rootModel/rootModel.ts' -import sessionModelFactory from '../sessionModel/sessionModel.ts' - -import type { SnapshotIn } from '@jbrowse/mobx-state-tree' - -jest.mock('../makeWorkerInstance', () => () => {}) - -type JBrowseRootModel = ReturnType - -function getPluginManager(initialState?: SnapshotIn) { - const pluginManager = new PluginManager( - corePlugins.map(P => new P()), - ).createPluggableElements() - - const rootModel = JBrowseRootModelFactory({ - pluginManager, - sessionModelFactory, - }).create( - { - jbrowse: initialState || { - ...configSnapshot, - configuration: { - rpc: { - defaultDriver: 'MainThreadRpcDriver', - }, - }, - }, - }, - { pluginManager }, - ) - return pluginManager.setRootModel(rootModel).configure() -} - -test('basic test of electron-mock-ipc', () => { - const testMessage = 'test' - ipcMain.once('test-event', (_ev: unknown, obj: string) => { - expect(obj).toEqual(testMessage) - }) - - ipcRenderer.send('test-event', testMessage) -}) - -xit('renders start screen', async () => { - ipcMain.handle('listSessions', () => ({})) - - const { findByText } = render() - fireEvent.click(await findByText('Empty')) - await findByText('Help') -}) diff --git a/products/jbrowse-desktop/src/components/StartScreen/Logo.tsx b/products/jbrowse-desktop/src/components/StartScreen/Logo.tsx index 23168ae2f9..4bee74d3ac 100644 --- a/products/jbrowse-desktop/src/components/StartScreen/Logo.tsx +++ b/products/jbrowse-desktop/src/components/StartScreen/Logo.tsx @@ -2,7 +2,7 @@ import { LogoFull } from '@jbrowse/core/ui/Logo' import { makeStyles } from '@jbrowse/core/util/tss-react' import { Typography } from '@mui/material' -import packageJSON from '../../../package.json' +import packageJSON from '../../../package.json' with { type: 'json' } const useStyles = makeStyles()({ logo: { diff --git a/products/jbrowse-desktop/src/rootModel/__snapshots__/rootModel.test.ts.snap b/products/jbrowse-desktop/src/rootModel/__snapshots__/rootModel.test.ts.snap deleted file mode 100644 index 322995ad78..0000000000 --- a/products/jbrowse-desktop/src/rootModel/__snapshots__/rootModel.test.ts.snap +++ /dev/null @@ -1,421 +0,0 @@ -// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing - -exports[`adds menus 1`] = ` -[ - { - "label": "File", - "menuItems": [ - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Open session...", - "onClick": [Function], - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Save session as...", - "onClick": [Function], - }, - { - "type": "divider", - }, - { - "icon": [Function], - "label": "Open assembly...", - "onClick": [Function], - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Open track...", - "onClick": [Function], - }, - { - "icon": [Function], - "label": "Open connection...", - "onClick": [Function], - }, - { - "type": "divider", - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Return to start screen", - "onClick": [Function], - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Exit", - "onClick": [Function], - }, - ], - }, - { - "label": "Add", - "menuItems": [], - }, - { - "label": "Tools", - "menuItems": [ - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Undo", - "onClick": [Function], - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Redo", - "onClick": [Function], - }, - { - "type": "divider", - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Plugin store", - "onClick": [Function], - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Preferences", - "onClick": [Function], - }, - { - "icon": [Function], - "label": "Open assembly manager", - "onClick": [Function], - }, - { - "checked": false, - "helpText": "Workspaces allow you to organize views into tabs and tiles. You can drag views between tabs or split them side-by-side.", - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Use workspaces", - "onClick": [Function], - "type": "checkbox", - }, - ], - }, -] -`; - -exports[`adds menus 2`] = ` -[ - { - "label": "File", - "menuItems": [ - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Open session...", - "onClick": [Function], - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Save session as...", - "onClick": [Function], - }, - { - "type": "divider", - }, - { - "icon": [Function], - "label": "Open assembly...", - "onClick": [Function], - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Open track...", - "onClick": [Function], - }, - { - "icon": [Function], - "label": "Open connection...", - "onClick": [Function], - }, - { - "type": "divider", - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Return to start screen", - "onClick": [Function], - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Exit", - "onClick": [Function], - }, - ], - }, - { - "label": "Add", - "menuItems": [], - }, - { - "label": "Tools", - "menuItems": [ - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Undo", - "onClick": [Function], - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Redo", - "onClick": [Function], - }, - { - "type": "divider", - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Plugin store", - "onClick": [Function], - }, - { - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Preferences", - "onClick": [Function], - }, - { - "icon": [Function], - "label": "Open assembly manager", - "onClick": [Function], - }, - { - "checked": false, - "helpText": "Workspaces allow you to organize views into tabs and tiles. You can drag views between tabs or split them side-by-side.", - "icon": { - "$$typeof": Symbol(react.memo), - "compare": null, - "type": { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, - }, - "label": "Use workspaces", - "onClick": [Function], - "type": "checkbox", - }, - ], - }, - { - "label": "Second Menu", - "menuItems": [ - { - "label": "First Menu Item", - "onClick": [Function], - }, - { - "label": "Second Menu Item", - "onClick": [Function], - }, - { - "label": "First Sub Menu", - "subMenu": [ - { - "label": "First Sub Menu Item", - "onClick": [Function], - }, - { - "label": "Second Sub Menu Item", - "onClick": [Function], - }, - ], - }, - ], - }, - { - "label": "Third Menu", - "menuItems": [], - }, -] -`; - -exports[`adds track and connection configs to an assembly 1`] = ` -{ - "aliases": [ - "assemblyA", - ], - "name": "assembly1", - "sequence": { - "adapter": { - "adapterId": "sequenceConfigAdapterId", - "features": [ - { - "end": 10, - "refName": "ctgA", - "seq": "cattgttgcg", - "start": 0, - "uniqueId": "firstId", - }, - ], - "type": "FromConfigSequenceAdapter", - }, - "displays": [ - { - "displayId": "sequenceConfigId-LinearReferenceSequenceDisplay", - "type": "LinearReferenceSequenceDisplay", - }, - { - "displayId": "sequenceConfigId-LinearGCContentDisplay", - "type": "LinearGCContentDisplay", - }, - ], - "trackId": "sequenceConfigId", - "type": "ReferenceSequenceTrack", - }, -} -`; - -exports[`adds track and connection configs to an assembly 2`] = ` -{ - "trackId": "trackId0", - "type": "FeatureTrack", -} -`; - -exports[`adds track and connection configs to an assembly 3`] = ` -{ - "connectionId": "connectionId0", - "dataDirLocation": { - "internetAccountId": undefined, - "internetAccountPreAuthorization": undefined, - "locationType": "UriLocation", - "uri": "http://mysite.com/jbrowse/data/", - }, - "type": "JBrowse1Connection", -} -`; - -exports[`creates with defaults 1`] = `{}`; diff --git a/products/jbrowse-desktop/src/rootModel/rootModel.test.ts b/products/jbrowse-desktop/src/rootModel/rootModel.test.ts deleted file mode 100644 index 0d985d9d98..0000000000 --- a/products/jbrowse-desktop/src/rootModel/rootModel.test.ts +++ /dev/null @@ -1,162 +0,0 @@ -// import electron first, important, because the electron mock creates -// window.require -import 'electron' - -// we use mainthread rpc so we mock the makeWorkerInstance to an empty file -import PluginManager from '@jbrowse/core/PluginManager' -import { getSnapshot } from '@jbrowse/mobx-state-tree' - -import corePlugins from '../corePlugins.ts' -import rootModelFactory from './rootModel.ts' -import sessionModelFactory from '../sessionModel/sessionModel.ts' - -jest.mock('../makeWorkerInstance', () => () => {}) - -function getRootModel() { - const pluginManager = new PluginManager(corePlugins.map(P => new P())) - pluginManager.createPluggableElements() - pluginManager.configure() - return rootModelFactory({ - pluginManager, - sessionModelFactory, - }) -} -afterEach(() => { - localStorage.clear() - sessionStorage.clear() -}) - -const mainThreadConfig = { - jbrowse: { - configuration: { - rpc: { - defaultDriver: 'MainThreadRpcDriver', - }, - }, - }, -} - -test('creates with defaults', () => { - const root = getRootModel().create(mainThreadConfig) - expect(root.session).toBeUndefined() - root.setDefaultSession() - expect(root.session).toBeTruthy() - expect(root.jbrowse.assemblies.length).toBe(0) - expect(getSnapshot(root.jbrowse.configuration)).toMatchSnapshot() -}) - -test('creates with a minimal session', () => { - const root = getRootModel().create({ - ...mainThreadConfig, - session: { - name: 'testSession', - }, - }) - expect(root.session).toBeTruthy() -}) - -test('activates a session snapshot', () => { - const session = { name: 'testSession' } - localStorage.setItem('localSaved-123', JSON.stringify({ session })) - Storage.prototype.getItem = jest.fn( - () => `{"session": {"name": "testSession"}}`, - ) - - const root = getRootModel().create(mainThreadConfig) - expect(root.session).toBeUndefined() - root.setSession(session) - expect(root.session).toBeTruthy() -}) - -test('adds track and connection configs to an assembly', () => { - const root = getRootModel().create({ - jbrowse: { - ...mainThreadConfig.jbrowse, - assemblies: [ - { - name: 'assembly1', - aliases: ['assemblyA'], - sequence: { - trackId: 'sequenceConfigId', - type: 'ReferenceSequenceTrack', - adapter: { - type: 'FromConfigSequenceAdapter', - adapterId: 'sequenceConfigAdapterId', - features: [ - { - refName: 'ctgA', - uniqueId: 'firstId', - start: 0, - end: 10, - seq: 'cattgttgcg', - }, - ], - }, - }, - }, - ], - }, - }) - expect(root.jbrowse.assemblies.length).toBe(1) - expect(getSnapshot(root.jbrowse.assemblies[0])).toMatchSnapshot() - const newTrackConf = root.jbrowse.addTrackConf({ - type: 'FeatureTrack', - trackId: 'trackId0', - }) - expect(newTrackConf).toMatchSnapshot() - expect(root.jbrowse.tracks.length).toBe(1) - const newConnectionConf = root.jbrowse.addConnectionConf({ - type: 'JBrowse1Connection', - connectionId: 'connectionId0', - }) - expect(getSnapshot(newConnectionConf)).toMatchSnapshot() - expect(root.jbrowse.connections.length).toBe(1) -}) - -test('throws if session is invalid', () => { - expect(() => { - getRootModel().create({ - ...mainThreadConfig, - session: {}, - }) - }).toThrow() -}) - -test('throws if session snapshot is invalid', () => { - const root = getRootModel().create(mainThreadConfig) - expect(() => { - root.setSession({}) - }).toThrow() -}) - -test('adds menus', () => { - const root = getRootModel().create(mainThreadConfig) - expect(root.menus()).toMatchSnapshot() - root.appendMenu('Third Menu') - root.insertMenu('Second Menu', -1) - root.appendToMenu('Second Menu', { - label: 'Second Menu Item', - onClick: () => {}, - }) - root.insertInMenu( - 'Second Menu', - { - label: 'First Menu Item', - onClick: () => {}, - }, - -1, - ) - root.appendToSubMenu(['Second Menu', 'First Sub Menu'], { - label: 'Second Sub Menu Item', - onClick: () => {}, - }) - root.insertInSubMenu( - ['Second Menu', 'First Sub Menu'], - { - label: 'First Sub Menu Item', - onClick: () => {}, - }, - -1, - ) - expect(root.menus()).toMatchSnapshot() -}) diff --git a/products/jbrowse-desktop/src/rootModel/rootModel.ts b/products/jbrowse-desktop/src/rootModel/rootModel.ts index b4cba9041f..b5b10d1f5d 100644 --- a/products/jbrowse-desktop/src/rootModel/rootModel.ts +++ b/products/jbrowse-desktop/src/rootModel/rootModel.ts @@ -26,7 +26,7 @@ import StorageIcon from '@mui/icons-material/Storage' import UndoIcon from '@mui/icons-material/Undo' import { DesktopSessionManagementMixin, getSaveSession } from './Sessions.ts' -import packageJSON from '../../package.json' +import packageJSON from '../../package.json' with { type: 'json' } import OpenSequenceDialog from '../components/OpenSequenceDialog.tsx' import jobsModelFactory from '../indexJobsModel.ts' import JBrowseDesktop from '../jbrowseModel.ts' diff --git a/products/jbrowse-react-linear-genome-view/.storybook/main.js b/products/jbrowse-react-app/.storybook/main.mjs similarity index 88% rename from products/jbrowse-react-linear-genome-view/.storybook/main.js rename to products/jbrowse-react-app/.storybook/main.mjs index 627b476745..1c5f4053a2 100644 --- a/products/jbrowse-react-linear-genome-view/.storybook/main.js +++ b/products/jbrowse-react-app/.storybook/main.mjs @@ -1,4 +1,4 @@ -module.exports = { +export default { stories: [ '../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)', @@ -15,7 +15,7 @@ module.exports = { test: /\.(ts|tsx|js|jsx)$/, use: [ { - loader: require.resolve('babel-loader'), + loader: 'babel-loader', options: { rootMode: 'upward', }, diff --git a/products/jbrowse-react-app/.storybook/middleware.js b/products/jbrowse-react-app/.storybook/middleware.mjs similarity index 66% rename from products/jbrowse-react-app/.storybook/middleware.js rename to products/jbrowse-react-app/.storybook/middleware.mjs index 6640c0f2ff..e0738ac898 100644 --- a/products/jbrowse-react-app/.storybook/middleware.js +++ b/products/jbrowse-react-app/.storybook/middleware.mjs @@ -1,7 +1,7 @@ -const serveStatic = require('serve-static') +import serveStatic from 'serve-static' // the default static file serving fails on vcf files due to Content-Encoding const expressMiddleWare = router => { router.use(serveStatic('public')) } -module.exports = expressMiddleWare +export default expressMiddleWare diff --git a/products/jbrowse-react-app/package.json b/products/jbrowse-react-app/package.json index 96119c9df8..5b8f648f9c 100644 --- a/products/jbrowse-react-app/package.json +++ b/products/jbrowse-react-app/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/react-app2", "version": "4.0.3", + "type": "module", "description": "JBrowse 2 app React component", "keywords": [ "jbrowse", @@ -33,7 +34,7 @@ "build": "pnpm run /^build:/", "prepublishOnly": "node output-version.js > src/version.ts && git add -A src && git commit -m '[skip ci] Bump version.ts'", "build:esm": "tsc --build tsconfig.build.esm.json", - "build:webpack": "webpack", + "build:webpack": "webpack -c webpack.config.mjs", "clean": "rimraf esm *.tsbuildinfo", "storybook": "storybook dev --port 6006", "storybook:build": "storybook build", diff --git a/products/jbrowse-react-app/stories/examples/WithImportConfigJson.tsx b/products/jbrowse-react-app/stories/examples/WithImportConfigJson.tsx index a4168b9951..e3680df81d 100644 --- a/products/jbrowse-react-app/stories/examples/WithImportConfigJson.tsx +++ b/products/jbrowse-react-app/stories/examples/WithImportConfigJson.tsx @@ -1,7 +1,7 @@ // replace with this in your code: // import {createViewState,JBrowseApp} from '@jbrowse/react-app2' import { addRelativeUris } from './util.ts' -import config from '../../public/test_data/volvox/config.json' +import config from '../../public/test_data/volvox/config.json' with { type: 'json' } import { JBrowseApp, createViewState } from '../../src/index.ts' const configPath = 'test_data/volvox/config.json' diff --git a/products/jbrowse-react-app/stories/examples/WithWebWorker.tsx b/products/jbrowse-react-app/stories/examples/WithWebWorker.tsx index 1e8c74777e..5ff4dc07ae 100644 --- a/products/jbrowse-react-app/stories/examples/WithWebWorker.tsx +++ b/products/jbrowse-react-app/stories/examples/WithWebWorker.tsx @@ -1,6 +1,6 @@ // replace with this in your code: // import {createViewState,JBrowseApp} from '@jbrowse/react-app2' -import volvoxConfig from '../../public/test_data/volvox/config.json' +import volvoxConfig from '../../public/test_data/volvox/config.json' with { type: 'json' } import { JBrowseApp, createViewState } from '../../src/index.ts' // replace with this in your code: // import makeWorkerInstance from '@jbrowse/react-app2/esm/makeWorkerInstance' diff --git a/products/jbrowse-react-app/webpack.config.js b/products/jbrowse-react-app/webpack.config.mjs similarity index 91% rename from products/jbrowse-react-app/webpack.config.js rename to products/jbrowse-react-app/webpack.config.mjs index 1416cd94d8..bc7a604f4c 100644 --- a/products/jbrowse-react-app/webpack.config.js +++ b/products/jbrowse-react-app/webpack.config.mjs @@ -1,7 +1,8 @@ -const path = require('path') -const webpack = require('webpack') +import path from 'path' -module.exports = { +import webpack from 'webpack' + +export default { mode: process.env.NODE_ENV || 'production', entry: './src/webpack.ts', devtool: 'source-map', diff --git a/products/jbrowse-react-app/.storybook/main.js b/products/jbrowse-react-circular-genome-view/.storybook/main.mjs similarity index 88% rename from products/jbrowse-react-app/.storybook/main.js rename to products/jbrowse-react-circular-genome-view/.storybook/main.mjs index 627b476745..1c5f4053a2 100644 --- a/products/jbrowse-react-app/.storybook/main.js +++ b/products/jbrowse-react-circular-genome-view/.storybook/main.mjs @@ -1,4 +1,4 @@ -module.exports = { +export default { stories: [ '../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)', @@ -15,7 +15,7 @@ module.exports = { test: /\.(ts|tsx|js|jsx)$/, use: [ { - loader: require.resolve('babel-loader'), + loader: 'babel-loader', options: { rootMode: 'upward', }, diff --git a/products/jbrowse-react-circular-genome-view/.storybook/middleware.js b/products/jbrowse-react-circular-genome-view/.storybook/middleware.mjs similarity index 66% rename from products/jbrowse-react-circular-genome-view/.storybook/middleware.js rename to products/jbrowse-react-circular-genome-view/.storybook/middleware.mjs index 6640c0f2ff..e0738ac898 100644 --- a/products/jbrowse-react-circular-genome-view/.storybook/middleware.js +++ b/products/jbrowse-react-circular-genome-view/.storybook/middleware.mjs @@ -1,7 +1,7 @@ -const serveStatic = require('serve-static') +import serveStatic from 'serve-static' // the default static file serving fails on vcf files due to Content-Encoding const expressMiddleWare = router => { router.use(serveStatic('public')) } -module.exports = expressMiddleWare +export default expressMiddleWare diff --git a/products/jbrowse-react-circular-genome-view/package.json b/products/jbrowse-react-circular-genome-view/package.json index 172eba818a..c8e8ed442e 100644 --- a/products/jbrowse-react-circular-genome-view/package.json +++ b/products/jbrowse-react-circular-genome-view/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/react-circular-genome-view2", "version": "4.0.4", + "type": "module", "description": "JBrowse 2 circular genome view React component", "keywords": [ "jbrowse", @@ -29,7 +30,7 @@ "prepublishOnly": "node output-version.js > src/version.ts && git add -A src && git commit -m '[skip ci] Bump version.ts'", "prepack": "pnpm build", "build:esm": "tsc -p tsconfig.build.esm.json", - "build:webpack": "webpack", + "build:webpack": "webpack -c webpack.config.mjs", "clean": "rimraf esm dist *.tsbuildinfo", "storybook": "storybook dev --port 6006", "storybook:build": "storybook build" diff --git a/products/jbrowse-react-circular-genome-view/webpack.config.js b/products/jbrowse-react-circular-genome-view/webpack.config.mjs similarity index 91% rename from products/jbrowse-react-circular-genome-view/webpack.config.js rename to products/jbrowse-react-circular-genome-view/webpack.config.mjs index 72a2f8b74e..14c8c373c0 100644 --- a/products/jbrowse-react-circular-genome-view/webpack.config.js +++ b/products/jbrowse-react-circular-genome-view/webpack.config.mjs @@ -1,7 +1,8 @@ -const path = require('path') -const webpack = require('webpack') +import path from 'path' -module.exports = { +import webpack from 'webpack' + +export default { mode: process.env.NODE_ENV || 'production', entry: './src/webpack.ts', devtool: 'source-map', diff --git a/products/jbrowse-react-circular-genome-view/.storybook/main.js b/products/jbrowse-react-linear-genome-view/.storybook/main.mjs similarity index 88% rename from products/jbrowse-react-circular-genome-view/.storybook/main.js rename to products/jbrowse-react-linear-genome-view/.storybook/main.mjs index 627b476745..1c5f4053a2 100644 --- a/products/jbrowse-react-circular-genome-view/.storybook/main.js +++ b/products/jbrowse-react-linear-genome-view/.storybook/main.mjs @@ -1,4 +1,4 @@ -module.exports = { +export default { stories: [ '../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)', @@ -15,7 +15,7 @@ module.exports = { test: /\.(ts|tsx|js|jsx)$/, use: [ { - loader: require.resolve('babel-loader'), + loader: 'babel-loader', options: { rootMode: 'upward', }, diff --git a/products/jbrowse-react-linear-genome-view/.storybook/middleware.js b/products/jbrowse-react-linear-genome-view/.storybook/middleware.mjs similarity index 66% rename from products/jbrowse-react-linear-genome-view/.storybook/middleware.js rename to products/jbrowse-react-linear-genome-view/.storybook/middleware.mjs index 6640c0f2ff..e0738ac898 100644 --- a/products/jbrowse-react-linear-genome-view/.storybook/middleware.js +++ b/products/jbrowse-react-linear-genome-view/.storybook/middleware.mjs @@ -1,7 +1,7 @@ -const serveStatic = require('serve-static') +import serveStatic from 'serve-static' // the default static file serving fails on vcf files due to Content-Encoding const expressMiddleWare = router => { router.use(serveStatic('public')) } -module.exports = expressMiddleWare +export default expressMiddleWare diff --git a/products/jbrowse-react-linear-genome-view/package.json b/products/jbrowse-react-linear-genome-view/package.json index 63f637c8f0..7c0032ea61 100644 --- a/products/jbrowse-react-linear-genome-view/package.json +++ b/products/jbrowse-react-linear-genome-view/package.json @@ -1,6 +1,7 @@ { "name": "@jbrowse/react-linear-genome-view2", "version": "4.0.3", + "type": "module", "description": "JBrowse 2 linear genome view React component", "keywords": [ "jbrowse", @@ -33,7 +34,7 @@ "build": "pnpm run /^build:/", "prepublishOnly": "node output-version.js > src/version.ts && git add -A src && git commit -m '[skip ci] Bump version.ts'", "build:esm": "tsc --build tsconfig.build.esm.json", - "build:webpack": "webpack", + "build:webpack": "webpack -c webpack.config.mjs", "clean": "rimraf esm *.tsbuildinfo", "storybook": "storybook dev --port 6006", "storybook:build": "storybook build", diff --git a/products/jbrowse-react-linear-genome-view/stories/examples/NextstrainExample.tsx b/products/jbrowse-react-linear-genome-view/stories/examples/NextstrainExample.tsx index e16b83d83e..e97edbda48 100644 --- a/products/jbrowse-react-linear-genome-view/stories/examples/NextstrainExample.tsx +++ b/products/jbrowse-react-linear-genome-view/stories/examples/NextstrainExample.tsx @@ -1,4 +1,4 @@ -import nextstrainConfig from '../../public/nextstrain_covid.json' +import nextstrainConfig from '../../public/nextstrain_covid.json' with { type: 'json' } // in your code // import { createViewState, loadPlugins, JBrowseLinearGenomeView } from '@jbrowse/react-linear-genome-view2' import { JBrowseLinearGenomeView, createViewState } from '../../src/index.ts' diff --git a/products/jbrowse-react-linear-genome-view/stories/examples/util.ts b/products/jbrowse-react-linear-genome-view/stories/examples/util.ts index f5e96e2928..75e50df591 100644 --- a/products/jbrowse-react-linear-genome-view/stories/examples/util.ts +++ b/products/jbrowse-react-linear-genome-view/stories/examples/util.ts @@ -1,5 +1,5 @@ // configs -import config from '../../public/test_data/volvox/config.json' +import config from '../../public/test_data/volvox/config.json' with { type: 'json' } export function addRelativeUris(config: any, baseUri: string) { if (typeof config === 'object') { diff --git a/products/jbrowse-react-linear-genome-view/webpack.config.js b/products/jbrowse-react-linear-genome-view/webpack.config.mjs similarity index 91% rename from products/jbrowse-react-linear-genome-view/webpack.config.js rename to products/jbrowse-react-linear-genome-view/webpack.config.mjs index 5d110c7e9c..97f7baff08 100644 --- a/products/jbrowse-react-linear-genome-view/webpack.config.js +++ b/products/jbrowse-react-linear-genome-view/webpack.config.mjs @@ -1,7 +1,8 @@ -const path = require('path') -const webpack = require('webpack') +import path from 'path' -module.exports = { +import webpack from 'webpack' + +export default { mode: process.env.NODE_ENV || 'production', entry: './src/webpack.ts', devtool: 'source-map', diff --git a/products/jbrowse-web/package.json b/products/jbrowse-web/package.json index bcc1afe208..b506f8048d 100644 --- a/products/jbrowse-web/package.json +++ b/products/jbrowse-web/package.json @@ -6,6 +6,10 @@ "homepage": ".", "main": "build", "dir": "src", + "exports": { + "./src/rootModel/index.js": "./src/rootModel/index.ts", + "./src/makeWorkerInstance": "./src/makeWorkerInstance.ts" + }, "scripts": { "start": "NODE_ENV=development node scripts/start.js", "build": "NODE_ENV=production node scripts/build.js", diff --git a/products/jbrowse-web/src/jbrowseModel.test.ts b/products/jbrowse-web/src/jbrowseModel.test.ts index 2012bef123..49df047cee 100644 --- a/products/jbrowse-web/src/jbrowseModel.test.ts +++ b/products/jbrowse-web/src/jbrowseModel.test.ts @@ -4,7 +4,7 @@ import { getSnapshot } from '@jbrowse/mobx-state-tree' import corePlugins from './corePlugins.ts' import jbrowseModelFactory from './jbrowseModel.ts' -import configSnapshot from '../test_data/volvox/config.json' +import configSnapshot from '../test_data/volvox/config.json' with { type: 'json' } type JBrowseModelType = ReturnType diff --git a/products/jbrowse-web/src/rootModel/index.ts b/products/jbrowse-web/src/rootModel/index.ts index 488040227f..8cab898efb 100644 --- a/products/jbrowse-web/src/rootModel/index.ts +++ b/products/jbrowse-web/src/rootModel/index.ts @@ -1,2 +1,2 @@ -export default './rootModel' +export { default } from './rootModel.ts' export { createTestSession } from './test_util.ts' diff --git a/products/jbrowse-web/src/rootModel/rootModel.ts b/products/jbrowse-web/src/rootModel/rootModel.ts index 30dd2fec6b..8ba2bcb8e8 100644 --- a/products/jbrowse-web/src/rootModel/rootModel.ts +++ b/products/jbrowse-web/src/rootModel/rootModel.ts @@ -39,7 +39,7 @@ import { formatDistanceToNow } from 'date-fns' import { openDB } from 'idb' import { autorun } from 'mobx' -import packageJSON from '../../package.json' +import packageJSON from '../../package.json' with { type: 'json' } import jbrowseWebFactory from '../jbrowseModel.ts' import makeWorkerInstance from '../makeWorkerInstance.ts' import { filterSessionInPlace } from '../util.ts' diff --git a/products/jbrowse-web/src/sessionSharing.ts b/products/jbrowse-web/src/sessionSharing.ts index cf52a46470..f2b2296b6a 100644 --- a/products/jbrowse-web/src/sessionSharing.ts +++ b/products/jbrowse-web/src/sessionSharing.ts @@ -1,3 +1,5 @@ +import { aesDecrypt, aesEncrypt } from '@jbrowse/core/util' + import { toUrlSafeB64 } from './util.ts' // from https://stackoverflow.com/questions/1349404/ @@ -12,18 +14,6 @@ function generateUID(length: number) { .slice(0, length) } -const encrypt = async (text: string, password: string) => { - const AES = await import('crypto-js/aes') - return AES.encrypt(text, password).toString() -} - -const decrypt = async (text: string, password: string) => { - const AES = await import('crypto-js/aes') - const Utf8 = await import('crypto-js/enc-utf8') - const bytes = AES.decrypt(text, password) - return bytes.toString(Utf8) -} - function getErrorMsg(err: string) { try { const obj = JSON.parse(err) @@ -40,7 +30,7 @@ export async function shareSessionToDynamo( ) { const sess = await toUrlSafeB64(JSON.stringify(session)) const password = generateUID(5) - const encryptedSession = await encrypt(sess, password) + const encryptedSession = await aesEncrypt(sess, password) const data = new FormData() data.append('session', encryptedSession) @@ -83,5 +73,5 @@ export async function readSessionFromDynamo( } const json = await response.json() - return decrypt(json.session, password) + return aesDecrypt(json.session, password) } diff --git a/products/jbrowse-web/src/tests/Alignments.test.tsx b/products/jbrowse-web/src/tests/Alignments.test.tsx index 3d3b660029..0fb9178f6a 100644 --- a/products/jbrowse-web/src/tests/Alignments.test.tsx +++ b/products/jbrowse-web/src/tests/Alignments.test.tsx @@ -1,5 +1,5 @@ import { fireEvent, within } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, diff --git a/products/jbrowse-web/src/tests/AlignmentsColorBy.test.tsx b/products/jbrowse-web/src/tests/AlignmentsColorBy.test.tsx index 06dd460a50..fa6cd879a7 100644 --- a/products/jbrowse-web/src/tests/AlignmentsColorBy.test.tsx +++ b/products/jbrowse-web/src/tests/AlignmentsColorBy.test.tsx @@ -1,5 +1,5 @@ import { screen, within } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, diff --git a/products/jbrowse-web/src/tests/AlignmentsFilters.test.tsx b/products/jbrowse-web/src/tests/AlignmentsFilters.test.tsx index 07063b693c..9ec5e4c390 100644 --- a/products/jbrowse-web/src/tests/AlignmentsFilters.test.tsx +++ b/products/jbrowse-web/src/tests/AlignmentsFilters.test.tsx @@ -1,5 +1,5 @@ import { screen, waitFor, within } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, diff --git a/products/jbrowse-web/src/tests/AlignmentsMethylation.test.tsx b/products/jbrowse-web/src/tests/AlignmentsMethylation.test.tsx index dd4a650ada..e0b6af3646 100644 --- a/products/jbrowse-web/src/tests/AlignmentsMethylation.test.tsx +++ b/products/jbrowse-web/src/tests/AlignmentsMethylation.test.tsx @@ -2,7 +2,7 @@ import path from 'path' import { testAlignmentModificationsDisplay } from './testAlignmentModificationsDisplay.tsx' import { doBeforeEach, setup } from './util.tsx' -import config from '../../test_data/methylation_test/config.json' +import config from '../../test_data/methylation_test/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/AlignmentsModifications.test.tsx b/products/jbrowse-web/src/tests/AlignmentsModifications.test.tsx index 89b9e3645d..3b61f92874 100644 --- a/products/jbrowse-web/src/tests/AlignmentsModifications.test.tsx +++ b/products/jbrowse-web/src/tests/AlignmentsModifications.test.tsx @@ -2,7 +2,7 @@ import path from 'path' import { testAlignmentModificationsDisplay } from './testAlignmentModificationsDisplay.tsx' import { doBeforeEach, setup } from './util.tsx' -import config from '../../test_data/modifications_test/config.json' +import config from '../../test_data/modifications_test/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/AlignmentsSoftClip.test.tsx b/products/jbrowse-web/src/tests/AlignmentsSoftClip.test.tsx index db36181036..ac32617881 100644 --- a/products/jbrowse-web/src/tests/AlignmentsSoftClip.test.tsx +++ b/products/jbrowse-web/src/tests/AlignmentsSoftClip.test.tsx @@ -1,5 +1,5 @@ import { screen, within } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, diff --git a/products/jbrowse-web/src/tests/AlignmentsSort.test.tsx b/products/jbrowse-web/src/tests/AlignmentsSort.test.tsx index c1f32ad5dd..dde6e2fbed 100644 --- a/products/jbrowse-web/src/tests/AlignmentsSort.test.tsx +++ b/products/jbrowse-web/src/tests/AlignmentsSort.test.tsx @@ -1,5 +1,5 @@ import { screen, within } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, diff --git a/products/jbrowse-web/src/tests/Authentication.test.tsx b/products/jbrowse-web/src/tests/Authentication.test.tsx index 1357ca4498..28c62d3e75 100644 --- a/products/jbrowse-web/src/tests/Authentication.test.tsx +++ b/products/jbrowse-web/src/tests/Authentication.test.tsx @@ -9,7 +9,7 @@ import { pv, setup, } from './util.tsx' -import config from '../../test_data/volvox/config_auth.json' +import config from '../../test_data/volvox/config_auth.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/AuthenticationHTTPBasic.test.tsx b/products/jbrowse-web/src/tests/AuthenticationHTTPBasic.test.tsx index 1286a89abd..35b10725ca 100644 --- a/products/jbrowse-web/src/tests/AuthenticationHTTPBasic.test.tsx +++ b/products/jbrowse-web/src/tests/AuthenticationHTTPBasic.test.tsx @@ -8,7 +8,7 @@ import { pv, setup, } from './util.tsx' -import config from '../../test_data/volvox/config_auth.json' +import config from '../../test_data/volvox/config_auth.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/BookmarkWidget.test.tsx b/products/jbrowse-web/src/tests/BookmarkWidget.test.tsx index 936a52c372..07d6bdee84 100644 --- a/products/jbrowse-web/src/tests/BookmarkWidget.test.tsx +++ b/products/jbrowse-web/src/tests/BookmarkWidget.test.tsx @@ -1,5 +1,5 @@ import { fireEvent, waitFor, within } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { saveAs } from 'file-saver-es' import { createView, doBeforeEach, setup } from './util.tsx' diff --git a/products/jbrowse-web/src/tests/BreakpointSplitView.test.tsx b/products/jbrowse-web/src/tests/BreakpointSplitView.test.tsx index 46ceee4c4a..6adae48a77 100644 --- a/products/jbrowse-web/src/tests/BreakpointSplitView.test.tsx +++ b/products/jbrowse-web/src/tests/BreakpointSplitView.test.tsx @@ -2,7 +2,7 @@ import '@testing-library/jest-dom' import { waitFor } from '@testing-library/react' import { createView, doBeforeEach, mockConsoleWarn, setup } from './util.tsx' -import breakpointConfig from '../../test_data/breakpoint/config.json' +import breakpointConfig from '../../test_data/breakpoint/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/BreakpointSplitViewInit1.test.tsx b/products/jbrowse-web/src/tests/BreakpointSplitViewInit1.test.tsx index 7aa80b5081..0146f14b1f 100644 --- a/products/jbrowse-web/src/tests/BreakpointSplitViewInit1.test.tsx +++ b/products/jbrowse-web/src/tests/BreakpointSplitViewInit1.test.tsx @@ -5,7 +5,7 @@ import { LocalFile } from 'generic-filehandle2' import { handleRequest } from './generateReadBuffer.ts' import { getPluginManager, setup } from './util.tsx' -import configSnapshot from '../../test_data/breakpoint/config.json' +import configSnapshot from '../../test_data/breakpoint/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/BreakpointSplitViewInit2.test.tsx b/products/jbrowse-web/src/tests/BreakpointSplitViewInit2.test.tsx index ef83502e51..2d6bff723c 100644 --- a/products/jbrowse-web/src/tests/BreakpointSplitViewInit2.test.tsx +++ b/products/jbrowse-web/src/tests/BreakpointSplitViewInit2.test.tsx @@ -5,7 +5,7 @@ import { LocalFile } from 'generic-filehandle2' import { handleRequest } from './generateReadBuffer.ts' import { getPluginManager, setup } from './util.tsx' -import configSnapshot from '../../test_data/breakpoint/config.json' +import configSnapshot from '../../test_data/breakpoint/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/BreakpointSplitViewInit3.test.tsx b/products/jbrowse-web/src/tests/BreakpointSplitViewInit3.test.tsx index c9fd03a439..b595d71168 100644 --- a/products/jbrowse-web/src/tests/BreakpointSplitViewInit3.test.tsx +++ b/products/jbrowse-web/src/tests/BreakpointSplitViewInit3.test.tsx @@ -5,7 +5,7 @@ import { LocalFile } from 'generic-filehandle2' import { handleRequest } from './generateReadBuffer.ts' import { getPluginManager, setup } from './util.tsx' -import configSnapshot from '../../test_data/breakpoint/config.json' +import configSnapshot from '../../test_data/breakpoint/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/BreakpointSplitViewInit4.test.tsx b/products/jbrowse-web/src/tests/BreakpointSplitViewInit4.test.tsx index 48bda3a934..1431b783e4 100644 --- a/products/jbrowse-web/src/tests/BreakpointSplitViewInit4.test.tsx +++ b/products/jbrowse-web/src/tests/BreakpointSplitViewInit4.test.tsx @@ -5,7 +5,7 @@ import { LocalFile } from 'generic-filehandle2' import { handleRequest } from './generateReadBuffer.ts' import { getPluginManager, setup } from './util.tsx' -import configSnapshot from '../../test_data/breakpoint/config.json' +import configSnapshot from '../../test_data/breakpoint/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/BreakpointSplitViewInit5.test.tsx b/products/jbrowse-web/src/tests/BreakpointSplitViewInit5.test.tsx index 5ff92149f6..ae0e5076a2 100644 --- a/products/jbrowse-web/src/tests/BreakpointSplitViewInit5.test.tsx +++ b/products/jbrowse-web/src/tests/BreakpointSplitViewInit5.test.tsx @@ -4,7 +4,7 @@ import { LocalFile } from 'generic-filehandle2' import { handleRequest } from './generateReadBuffer.ts' import { getPluginManager, setup } from './util.tsx' -import configSnapshot from '../../test_data/breakpoint/config.json' +import configSnapshot from '../../test_data/breakpoint/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/CircularView.test.tsx b/products/jbrowse-web/src/tests/CircularView.test.tsx index a534d99688..cec8dcb3da 100644 --- a/products/jbrowse-web/src/tests/CircularView.test.tsx +++ b/products/jbrowse-web/src/tests/CircularView.test.tsx @@ -2,7 +2,7 @@ import '@testing-library/jest-dom' import { fireEvent, waitFor } from '@testing-library/react' import { createView, doBeforeEach, hts, setup } from './util.tsx' -import configSnapshot from '../../test_data/volvox/config.json' +import configSnapshot from '../../test_data/volvox/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/CollapseIntrons.test.tsx b/products/jbrowse-web/src/tests/CollapseIntrons.test.tsx index f50222f681..88cd171c23 100644 --- a/products/jbrowse-web/src/tests/CollapseIntrons.test.tsx +++ b/products/jbrowse-web/src/tests/CollapseIntrons.test.tsx @@ -1,6 +1,6 @@ import '@testing-library/jest-dom' import { fireEvent, screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, doBeforeEach, hts, setup } from './util.tsx' diff --git a/products/jbrowse-web/src/tests/ConfigurationEditor.test.tsx b/products/jbrowse-web/src/tests/ConfigurationEditor.test.tsx index c5be159b90..bc6666ccb1 100644 --- a/products/jbrowse-web/src/tests/ConfigurationEditor.test.tsx +++ b/products/jbrowse-web/src/tests/ConfigurationEditor.test.tsx @@ -1,6 +1,6 @@ import '@testing-library/jest-dom' import { waitFor } from '@testing-library/dom' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, diff --git a/products/jbrowse-web/src/tests/Connection.test.tsx b/products/jbrowse-web/src/tests/Connection.test.tsx index 4c8a39f40d..70ca480feb 100644 --- a/products/jbrowse-web/src/tests/Connection.test.tsx +++ b/products/jbrowse-web/src/tests/Connection.test.tsx @@ -1,9 +1,9 @@ import { screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { LocalFile } from 'generic-filehandle2' import { createView, doBeforeEach, generateReadBuffer } from './util.tsx' -import configSnapshot from '../../test_data/volvox/config.json' +import configSnapshot from '../../test_data/volvox/config.json' with { type: 'json' } jest.mock('../makeWorkerInstance', () => () => {}) diff --git a/products/jbrowse-web/src/tests/CopyAndDelete.test.tsx b/products/jbrowse-web/src/tests/CopyAndDelete.test.tsx index f4427f1ae2..eedcb71172 100644 --- a/products/jbrowse-web/src/tests/CopyAndDelete.test.tsx +++ b/products/jbrowse-web/src/tests/CopyAndDelete.test.tsx @@ -10,7 +10,7 @@ import { mockConsoleWarn, setup, } from './util.tsx' -import masterConfig from '../../test_data/volvox/connection_test.json' +import masterConfig from '../../test_data/volvox/connection_test.json' with { type: 'json' } setup() beforeEach(() => { diff --git a/products/jbrowse-web/src/tests/Dotplot.test.tsx b/products/jbrowse-web/src/tests/Dotplot.test.tsx index ba93daaa55..611e72609c 100644 --- a/products/jbrowse-web/src/tests/Dotplot.test.tsx +++ b/products/jbrowse-web/src/tests/Dotplot.test.tsx @@ -1,9 +1,9 @@ import path from 'path' -import dotplotSessionFlipAxes from './dotplot_inverted_flipaxes.json' -import dotplotSession from './dotplot_inverted_test.json' +import dotplotSessionFlipAxes from './dotplot_inverted_flipaxes.json' with { type: 'json' } +import dotplotSession from './dotplot_inverted_test.json' with { type: 'json' } import { createView, doBeforeEach, expectCanvasMatch, setup } from './util.tsx' -import config from '../../test_data/config_dotplot.json' +import config from '../../test_data/config_dotplot.json' with { type: 'json' } const delay = { timeout: 50000 } const opts = [{}, delay] diff --git a/products/jbrowse-web/src/tests/DotplotOpenLinearSyntenyView.test.tsx b/products/jbrowse-web/src/tests/DotplotOpenLinearSyntenyView.test.tsx index ac6ab2689e..4b2ccb3790 100644 --- a/products/jbrowse-web/src/tests/DotplotOpenLinearSyntenyView.test.tsx +++ b/products/jbrowse-web/src/tests/DotplotOpenLinearSyntenyView.test.tsx @@ -4,7 +4,7 @@ import { configure } from 'mobx' import { handleRequest } from './generateReadBuffer.ts' import { getPluginManager, setup } from './util.tsx' -import configSnapshot from '../../test_data/grape_peach_synteny/config.json' +import configSnapshot from '../../test_data/grape_peach_synteny/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/DotplotViewInit.test.tsx b/products/jbrowse-web/src/tests/DotplotViewInit.test.tsx index c2c8187360..d93be23597 100644 --- a/products/jbrowse-web/src/tests/DotplotViewInit.test.tsx +++ b/products/jbrowse-web/src/tests/DotplotViewInit.test.tsx @@ -4,7 +4,7 @@ import { configure } from 'mobx' import { handleRequest } from './generateReadBuffer.ts' import { getPluginManager, setup } from './util.tsx' -import configSnapshot from '../../test_data/grape_peach_synteny/config.json' +import configSnapshot from '../../test_data/grape_peach_synteny/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/Empty.test.tsx b/products/jbrowse-web/src/tests/Empty.test.tsx index b34dcbd19e..052df82d2c 100644 --- a/products/jbrowse-web/src/tests/Empty.test.tsx +++ b/products/jbrowse-web/src/tests/Empty.test.tsx @@ -1,7 +1,7 @@ import { render } from '@testing-library/react' import { JBrowse, getPluginManager } from './util.tsx' -import emptyConfig from '../../test_data/empty.json' +import emptyConfig from '../../test_data/empty.json' with { type: 'json' } test('catches no assemblies with empty config', async () => { const pluginManager = getPluginManager(emptyConfig) diff --git a/products/jbrowse-web/src/tests/ErrorConditions.test.tsx b/products/jbrowse-web/src/tests/ErrorConditions.test.tsx index 6e94790602..52eea85dda 100644 --- a/products/jbrowse-web/src/tests/ErrorConditions.test.tsx +++ b/products/jbrowse-web/src/tests/ErrorConditions.test.tsx @@ -1,6 +1,6 @@ import { createViewNoWait, doBeforeEach, mockConsole } from './util.tsx' -import chromeSizesConfig from '../../test_data/404_chrom_sizes/config.json' -import wrongAssemblyTest from '../../test_data/wrong_assembly.json' +import chromeSizesConfig from '../../test_data/404_chrom_sizes/config.json' with { type: 'json' } +import wrongAssemblyTest from '../../test_data/wrong_assembly.json' with { type: 'json' } const delay = { timeout: 30000 } diff --git a/products/jbrowse-web/src/tests/ExportSession.test.tsx b/products/jbrowse-web/src/tests/ExportSession.test.tsx index ab4fe699e7..c017b04e72 100644 --- a/products/jbrowse-web/src/tests/ExportSession.test.tsx +++ b/products/jbrowse-web/src/tests/ExportSession.test.tsx @@ -1,5 +1,5 @@ import { fireEvent, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { saveAs } from 'file-saver-es' let mockCounter = 0 diff --git a/products/jbrowse-web/src/tests/ExportSvgBreakpointSplitView.test.tsx b/products/jbrowse-web/src/tests/ExportSvgBreakpointSplitView.test.tsx index e889731e1e..fdbc668da8 100644 --- a/products/jbrowse-web/src/tests/ExportSvgBreakpointSplitView.test.tsx +++ b/products/jbrowse-web/src/tests/ExportSvgBreakpointSplitView.test.tsx @@ -1,5 +1,5 @@ import { createView, doBeforeEach, exportAndVerifySvg, setup } from './util.tsx' -import breakpointConfig from '../../test_data/breakpoint/config.json' +import breakpointConfig from '../../test_data/breakpoint/config.json' with { type: 'json' } // @ts-expect-error global.Blob = (content, options) => ({ content, options }) diff --git a/products/jbrowse-web/src/tests/ExportSvgCircular.test.tsx b/products/jbrowse-web/src/tests/ExportSvgCircular.test.tsx index 397377f70e..7090952c41 100644 --- a/products/jbrowse-web/src/tests/ExportSvgCircular.test.tsx +++ b/products/jbrowse-web/src/tests/ExportSvgCircular.test.tsx @@ -7,7 +7,7 @@ import { hts, setup, } from './util.tsx' -import volvoxConfig from '../../test_data/volvox/config.json' +import volvoxConfig from '../../test_data/volvox/config.json' with { type: 'json' } // @ts-expect-error global.Blob = (content, options) => ({ content, options }) diff --git a/products/jbrowse-web/src/tests/ExportSvgDotplot.test.tsx b/products/jbrowse-web/src/tests/ExportSvgDotplot.test.tsx index fd7a9c8815..80561c9e08 100644 --- a/products/jbrowse-web/src/tests/ExportSvgDotplot.test.tsx +++ b/products/jbrowse-web/src/tests/ExportSvgDotplot.test.tsx @@ -1,5 +1,5 @@ import { createView, doBeforeEach, exportAndVerifySvg, setup } from './util.tsx' -import volvoxConfig from '../../test_data/volvox/config.json' +import volvoxConfig from '../../test_data/volvox/config.json' with { type: 'json' } // @ts-expect-error global.Blob = (content, options) => ({ content, options }) diff --git a/products/jbrowse-web/src/tests/ExportSvgLinearSyntenyView.test.tsx b/products/jbrowse-web/src/tests/ExportSvgLinearSyntenyView.test.tsx index 9ce23416a9..8f7d5d69fe 100644 --- a/products/jbrowse-web/src/tests/ExportSvgLinearSyntenyView.test.tsx +++ b/products/jbrowse-web/src/tests/ExportSvgLinearSyntenyView.test.tsx @@ -11,7 +11,7 @@ import { mockConsoleWarn, setup, } from './util.tsx' -import volvoxConfig from '../../test_data/volvox/config.json' +import volvoxConfig from '../../test_data/volvox/config.json' with { type: 'json' } // @ts-expect-error global.Blob = (content, options) => ({ content, options }) diff --git a/products/jbrowse-web/src/tests/GCContent.test.tsx b/products/jbrowse-web/src/tests/GCContent.test.tsx index 3c00f047b1..a5f1e70767 100644 --- a/products/jbrowse-web/src/tests/GCContent.test.tsx +++ b/products/jbrowse-web/src/tests/GCContent.test.tsx @@ -1,5 +1,5 @@ import { screen, within } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, diff --git a/products/jbrowse-web/src/tests/Hic.test.tsx b/products/jbrowse-web/src/tests/Hic.test.tsx index e19bb86c08..8f0a44288d 100644 --- a/products/jbrowse-web/src/tests/Hic.test.tsx +++ b/products/jbrowse-web/src/tests/Hic.test.tsx @@ -7,7 +7,7 @@ import { hts, setup, } from './util.tsx' -import hicConfig from '../../../../extra_test_data/hic_integration_test.json' +import hicConfig from '../../../../extra_test_data/hic_integration_test.json' with { type: 'json' } beforeEach(() => { doBeforeEach(url => require.resolve(`../../../../extra_test_data/${url}`)) diff --git a/products/jbrowse-web/src/tests/JBrowse.test.tsx b/products/jbrowse-web/src/tests/JBrowse.test.tsx index cfb23c3829..c6cdf5fbde 100644 --- a/products/jbrowse-web/src/tests/JBrowse.test.tsx +++ b/products/jbrowse-web/src/tests/JBrowse.test.tsx @@ -4,7 +4,7 @@ import PluginManager from '@jbrowse/core/PluginManager' import { getConf, readConfObject } from '@jbrowse/core/configuration' import { fireEvent } from '@testing-library/react' -import volvoxConfigSnapshot from '../../test_data/volvox/config.json' +import volvoxConfigSnapshot from '../../test_data/volvox/config.json' with { type: 'json' } import corePlugins from '../corePlugins.ts' import TestPlugin from './TestPlugin.ts' import { diff --git a/products/jbrowse-web/src/tests/LDDisplay.test.tsx b/products/jbrowse-web/src/tests/LDDisplay.test.tsx index c30d12b6ce..48e2da2314 100644 --- a/products/jbrowse-web/src/tests/LDDisplay.test.tsx +++ b/products/jbrowse-web/src/tests/LDDisplay.test.tsx @@ -30,6 +30,7 @@ test( fireEvent.click(await findByText('Display types', ...opts)) fireEvent.click(await findByText('LD heatmap display', ...opts)) + await new Promise(res => setTimeout(res, 3000)) expectCanvasMatch(await findByTestId('ld_canvas_done', ...opts)) }, timeout, diff --git a/products/jbrowse-web/src/tests/LGVSynteny.test.tsx b/products/jbrowse-web/src/tests/LGVSynteny.test.tsx index 22b5e58d72..a3222d536c 100644 --- a/products/jbrowse-web/src/tests/LGVSynteny.test.tsx +++ b/products/jbrowse-web/src/tests/LGVSynteny.test.tsx @@ -1,6 +1,6 @@ import { getEnv } from '@jbrowse/core/util' import { fireEvent, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, diff --git a/products/jbrowse-web/src/tests/LinearSyntenyViewInit.test.tsx b/products/jbrowse-web/src/tests/LinearSyntenyViewInit.test.tsx index 057f309f57..351a89cd27 100644 --- a/products/jbrowse-web/src/tests/LinearSyntenyViewInit.test.tsx +++ b/products/jbrowse-web/src/tests/LinearSyntenyViewInit.test.tsx @@ -4,7 +4,7 @@ import { configure } from 'mobx' import { handleRequest } from './generateReadBuffer.ts' import { getPluginManager, setup } from './util.tsx' -import configSnapshot from '../../test_data/grape_peach_synteny/config.json' +import configSnapshot from '../../test_data/grape_peach_synteny/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/NcbiAliasAdapter.test.tsx b/products/jbrowse-web/src/tests/NcbiAliasAdapter.test.tsx index 3a6e9f70b7..6396b964d1 100644 --- a/products/jbrowse-web/src/tests/NcbiAliasAdapter.test.tsx +++ b/products/jbrowse-web/src/tests/NcbiAliasAdapter.test.tsx @@ -1,5 +1,5 @@ import { createView, doBeforeEach, expectCanvasMatch, setup } from './util.tsx' -import config from '../../test_data/cfam2/config.json' +import config from '../../test_data/cfam2/config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/SNPCoverage.test.tsx b/products/jbrowse-web/src/tests/SNPCoverage.test.tsx index cdefa7bfef..93a48a99a8 100644 --- a/products/jbrowse-web/src/tests/SNPCoverage.test.tsx +++ b/products/jbrowse-web/src/tests/SNPCoverage.test.tsx @@ -1,5 +1,5 @@ import { within } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, diff --git a/products/jbrowse-web/src/tests/SaveTrackData.test.tsx b/products/jbrowse-web/src/tests/SaveTrackData.test.tsx index 06a9affa0a..1b19442f4a 100644 --- a/products/jbrowse-web/src/tests/SaveTrackData.test.tsx +++ b/products/jbrowse-web/src/tests/SaveTrackData.test.tsx @@ -2,7 +2,7 @@ import fs from 'fs' import path from 'path' import { screen, waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { saveAs } from 'file-saver-es' import { createView, doBeforeEach, hts, setup } from './util.tsx' diff --git a/products/jbrowse-web/src/tests/Spreadsheet.test.tsx b/products/jbrowse-web/src/tests/Spreadsheet.test.tsx index 149b73b6cb..c95abc7a16 100644 --- a/products/jbrowse-web/src/tests/Spreadsheet.test.tsx +++ b/products/jbrowse-web/src/tests/Spreadsheet.test.tsx @@ -1,6 +1,6 @@ import '@testing-library/jest-dom' import { screen } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { doBeforeEach, openSpreadsheetView, setup } from './util.tsx' diff --git a/products/jbrowse-web/src/tests/SubfeatureClick.test.tsx b/products/jbrowse-web/src/tests/SubfeatureClick.test.tsx index 1de18357e9..8ab869519a 100644 --- a/products/jbrowse-web/src/tests/SubfeatureClick.test.tsx +++ b/products/jbrowse-web/src/tests/SubfeatureClick.test.tsx @@ -1,6 +1,6 @@ import '@testing-library/jest-dom' import { fireEvent, screen } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, doBeforeEach, hts, setup } from './util.tsx' diff --git a/products/jbrowse-web/src/tests/SubfeatureLabels.test.tsx b/products/jbrowse-web/src/tests/SubfeatureLabels.test.tsx index 881200e786..689d458711 100644 --- a/products/jbrowse-web/src/tests/SubfeatureLabels.test.tsx +++ b/products/jbrowse-web/src/tests/SubfeatureLabels.test.tsx @@ -1,5 +1,5 @@ import { screen } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, diff --git a/products/jbrowse-web/src/tests/TextSearching.test.tsx b/products/jbrowse-web/src/tests/TextSearching.test.tsx index ed9425c5e8..11dd15eeea 100644 --- a/products/jbrowse-web/src/tests/TextSearching.test.tsx +++ b/products/jbrowse-web/src/tests/TextSearching.test.tsx @@ -1,7 +1,7 @@ import { fireEvent, waitFor, within } from '@testing-library/react' import { createView, doBeforeEach, setup } from './util.tsx' -import jb1_config from '../../test_data/volvox/volvox_jb1_text_config.json' +import jb1_config from '../../test_data/volvox/volvox_jb1_text_config.json' with { type: 'json' } setup() diff --git a/products/jbrowse-web/src/tests/TrackMenu.test.tsx b/products/jbrowse-web/src/tests/TrackMenu.test.tsx index 0a6489e3c7..b92184f15d 100644 --- a/products/jbrowse-web/src/tests/TrackMenu.test.tsx +++ b/products/jbrowse-web/src/tests/TrackMenu.test.tsx @@ -1,5 +1,5 @@ import { screen } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, doBeforeEach, hts, setup } from './util.tsx' diff --git a/products/jbrowse-web/src/tests/testLinkedReadsDisplay.tsx b/products/jbrowse-web/src/tests/testLinkedReadsDisplay.tsx index c16416990f..cfe82bf695 100644 --- a/products/jbrowse-web/src/tests/testLinkedReadsDisplay.tsx +++ b/products/jbrowse-web/src/tests/testLinkedReadsDisplay.tsx @@ -1,5 +1,5 @@ import { waitFor } from '@testing-library/react' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { createView, expectCanvasMatch, hts } from './util.tsx' diff --git a/products/jbrowse-web/src/tests/tracks.test.ts b/products/jbrowse-web/src/tests/tracks.test.ts index 324ef90ab0..7eae31ced3 100644 --- a/products/jbrowse-web/src/tests/tracks.test.ts +++ b/products/jbrowse-web/src/tests/tracks.test.ts @@ -1,5 +1,6 @@ import { guessAdapter as guessAdapter2 } from '@jbrowse/core/util/tracks' -import { createTestSession } from '@jbrowse/web/src/rootModel' + +import { createTestSession } from '../rootModel/index.ts' jest.mock('../makeWorkerInstance', () => () => {}) diff --git a/products/jbrowse-web/src/tests/util.tsx b/products/jbrowse-web/src/tests/util.tsx index 2fda46c814..81b8e80f19 100644 --- a/products/jbrowse-web/src/tests/util.tsx +++ b/products/jbrowse-web/src/tests/util.tsx @@ -12,7 +12,7 @@ import { LocalFile } from 'generic-filehandle2' import { toMatchImageSnapshot } from 'jest-image-snapshot' import { generateReadBuffer } from './generateReadBuffer.ts' -import configSnapshot from '../../test_data/volvox/config.json' +import configSnapshot from '../../test_data/volvox/config.json' with { type: 'json' } import corePlugins from '../corePlugins.ts' import JBrowse from './TestingJBrowse.tsx' import JBrowseRootModelFactory from '../rootModel/rootModel.ts' diff --git a/products/jbrowse-web/tsconfig.oauth.json b/products/jbrowse-web/tsconfig.oauth.json index d94b864fa6..2e10a2244c 100644 --- a/products/jbrowse-web/tsconfig.oauth.json +++ b/products/jbrowse-web/tsconfig.oauth.json @@ -1,6 +1,6 @@ { "include": ["src/tests/oauthServer"], "compilerOptions": { - "module": "nodenext" + "module": "esnext" } } diff --git a/scripts/pack.ts b/scripts/pack.ts index a7e0bf733b..7060aa654c 100644 --- a/scripts/pack.ts +++ b/scripts/pack.ts @@ -21,7 +21,7 @@ for (const dir of workspaceDirs) { const pkgJsonPath = path.join(pkgDir, 'package.json') if (fs.existsSync(pkgJsonPath)) { const location = pkgDir - const { signal, status } = spawn.sync('pnpm', ['pack'], { + const { signal, status } = spawn.sync('pnpm', ['pack', '--silent'], { stdio: 'inherit', cwd: location, }) diff --git a/webpack/config/webpack/persistentCache/createEnvironmentHash.js b/webpack/config/webpack/persistentCache/createEnvironmentHash.mjs similarity index 51% rename from webpack/config/webpack/persistentCache/createEnvironmentHash.js rename to webpack/config/webpack/persistentCache/createEnvironmentHash.mjs index e08ebab98c..75ad2cd0f1 100644 --- a/webpack/config/webpack/persistentCache/createEnvironmentHash.js +++ b/webpack/config/webpack/persistentCache/createEnvironmentHash.mjs @@ -1,6 +1,6 @@ -const { createHash } = require('crypto') +import { createHash } from 'crypto' -module.exports = function createEnvironmentHash(env) { +export default function createEnvironmentHash(env) { const hash = createHash('md5') hash.update(JSON.stringify(env))