Skip to content

Commit

Permalink
Misc
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Aug 19, 2024
1 parent 7d19426 commit db1ff14
Show file tree
Hide file tree
Showing 15 changed files with 162 additions and 126 deletions.
17 changes: 15 additions & 2 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import eslintPluginReactHooks from 'eslint-plugin-react-hooks'
import eslintPluginReactRefresh from 'eslint-plugin-react-refresh'
import eslintPluginUnicorn from 'eslint-plugin-unicorn'
import tseslint from 'typescript-eslint'
import globals from 'globals'

export default tseslint.config(
{
ignores: ['**/dist/**/*'],
ignores: [
'**/dist/**/*',
'jest.config.js',
'eslint.config.mjs',
'esbuild.mjs',
],
},
{
languageOptions: {
Expand Down Expand Up @@ -63,8 +67,17 @@ export default tseslint.config(
},
],

'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/restrict-template-expressions': 'off',
'@typescript-eslint/no-empty-function': 'off',

'unicorn/no-null': 'off',
'unicorn/prefer-spread': 'off',
'unicorn/no-useless-undefined': 'off',
'unicorn/catch-error-name': 'off',
'unicorn/filename-case': 'off',
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"prebuild": "npm run clean",
"start": "node esbuild.mjs",
"build": "tsc && NODE_ENV=production node esbuild.mjs",
"lint": "eslint --report-unused-disable-directives --max-warnings 0 src/",
"lint": "eslint --report-unused-disable-directives --max-warnings 0",
"prepack": "npm run build",
"postversion": "git push --follow-tags"
},
Expand Down
13 changes: 7 additions & 6 deletions src/AddHighlightModel/ProteinToGenomeClickHighlight.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@ const ProteinToGenomeClickHighlight = observer(function ({
}) {
const { assemblyManager, views } = getSession(model)
const { assemblyNames } = model
const p = views.find(
f => f.type === 'ProteinView',
) as JBrowsePluginProteinViewModel
const assembly = assemblyManager.get(assemblyNames[0])
const p = views.find(f => f.type === 'ProteinView') as
| JBrowsePluginProteinViewModel
| undefined
const assemblyName = assemblyNames[0]!
const assembly = assemblyManager.get(assemblyName)
return assembly ? (
<>
{p.clickGenomeHighlights.map((r, idx) => (
{p?.clickGenomeHighlights.map((r, idx) => (
<Highlight
key={`${JSON.stringify(r)}-${idx}}`}
start={r.start}
end={r.end}
refName={r.refName}
assemblyName={assemblyNames[0]}
assemblyName={assemblyName}
model={model}
/>
))}
Expand Down
13 changes: 7 additions & 6 deletions src/AddHighlightModel/ProteinToGenomeHoverHighlight.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@ const ProteinToGenomeHoverHighlight = observer(function ({
}) {
const { assemblyManager, views } = getSession(model)
const { assemblyNames } = model
const p = views.find(
f => f.type === 'ProteinView',
) as JBrowsePluginProteinViewModel
const assembly = assemblyManager.get(assemblyNames[0])
const p = views.find(f => f.type === 'ProteinView') as
| JBrowsePluginProteinViewModel
| undefined
const assemblyName = assemblyNames[0]!
const assembly = assemblyManager.get(assemblyName)
return assembly ? (
<>
{p.hoverGenomeHighlights.map((r, idx) => (
{p?.hoverGenomeHighlights.map((r, idx) => (
<Highlight
key={`${JSON.stringify(r)}-${idx}`}
start={r.start}
end={r.end}
refName={r.refName}
assemblyName={assemblyNames[0]}
assemblyName={assemblyName}
model={model}
/>
))}
Expand Down
4 changes: 1 addition & 3 deletions src/LaunchProteinView/components/UserProvidedStructure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,7 @@ const UserProvidedStructure = observer(function ({
const { seq: structureSequence2, error: error4 } =
useRemoteStructureFileSequence({ url: structureURL })
const structureName =
file?.name ??
structureURL.slice(structureURL.lastIndexOf('/') + 1) ??
'structureSequence'
file?.name ?? structureURL.slice(structureURL.lastIndexOf('/') + 1)
const structureSequence = structureSequence1 ?? structureSequence2

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function calculateProteinSequence({
let protein = ''
for (let i = 0; i < str.length; i += 3) {
// use & symbol for undefined codon, or partial slice
protein += codonTable[str.slice(i, i + 3)] || '&'
protein += codonTable[str.slice(i, i + 3)] ?? '&'
}
return protein
}
Expand Down
58 changes: 32 additions & 26 deletions src/LaunchProteinView/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,51 @@ import PluginManager from '@jbrowse/core/PluginManager'
import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'
import { PluggableElementType } from '@jbrowse/core/pluggableElementTypes'
import { IAnyModelType } from 'mobx-state-tree'
import { getSession, getContainingTrack } from '@jbrowse/core/util'
import { getSession, getContainingTrack, Feature } from '@jbrowse/core/util'

// icons
import AddIcon from '@mui/icons-material/Add'

// locals
import LaunchProteinViewDialog from './components/LaunchProteinViewDialog'
import { MenuItem } from '@jbrowse/core/ui'

function isDisplay(elt: { name: string }): elt is DisplayType {
return elt.name === 'LinearBasicDisplay'
}

function extendStateModel(stateModel: IAnyModelType) {
return stateModel.views(self => {
const superContextMenuItems = self.contextMenuItems
return {
contextMenuItems() {
const feature = self.contextMenuFeature
const track = getContainingTrack(self)
return [
...superContextMenuItems(),
...(feature
? [
{
label: 'Launch 3-D protein view',
icon: AddIcon,
onClick: () => {
getSession(track).queueDialog(handleClose => [
LaunchProteinViewDialog,
{ model: track, handleClose, feature },
])
return stateModel.views(
(self: {
contextMenuItems: () => MenuItem[]
contextMenuFeature?: Feature
}) => {
const superContextMenuItems = self.contextMenuItems
return {
contextMenuItems() {
const feature = self.contextMenuFeature
const track = getContainingTrack(self)
return [
...superContextMenuItems(),
...(feature
? [
{
label: 'Launch 3-D protein view',
icon: AddIcon,
onClick: () => {
getSession(track).queueDialog(handleClose => [
LaunchProteinViewDialog,
{ model: track, handleClose, feature },
])
},
},
},
]
: []),
]
},
}
})
]
: []),
]
},
}
},
)
}

export default function LaunchProteinViewF(pluginManager: PluginManager) {
Expand Down
11 changes: 7 additions & 4 deletions src/ProteinView/components/ProteinAlignment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ const ProteinAlignment = observer(function ({
alignmentToStructurePosition,
showHighlight,
} = model
const a0 = alignment!.alns[0].seq as string
const a1 = alignment!.alns[1].seq as string
const con = alignment!.consensus
if (!alignment) {
return <div>No alignment</div>
}
const a0 = alignment.alns[0]!.seq as string
const a1 = alignment.alns[1]!.seq as string
const con = alignment.consensus
const set = new Set<number>()
// eslint-disable-next-line unicorn/no-for-loop
for (let i = 0; i < con.length; i++) {
Expand All @@ -47,7 +50,7 @@ const ProteinAlignment = observer(function ({
}
function onClick(alignmentPos: number) {
const structureSeqPos = alignmentToStructurePosition[alignmentPos]
clickProteinToGenome({ model, structureSeqPos }).catch(e => {
clickProteinToGenome({ model, structureSeqPos }).catch((e: unknown) => {
console.error(e)
})
}
Expand Down
11 changes: 5 additions & 6 deletions src/ProteinView/components/ProteinView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@ import clearSelection from '../clearSelection'
// css
import css from '../css/molstar'

if (document.head) {
const style = document.createElement('style')
style.append(css)
document.head.append(style)
}
const style = document.createElement('style')
style.append(css)
document.head.append(style)

const ProteinView = observer(function ({
model,
Expand Down Expand Up @@ -98,9 +96,10 @@ const ProteinViewContainer = observer(function ({
}, [plugin, structure, showHighlight, structureSeqToTranscriptSeqPosition])

useEffect(() => {
if (!plugin || !structure || structureSeqHoverPos === undefined) {
if (!plugin || !structure) {
return
}

if (structureSeqHoverPos === undefined) {
console.warn('not found')
} else {
Expand Down
3 changes: 3 additions & 0 deletions src/ProteinView/launchRemotePairwiseAlignment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ async function wait({
algorithm: string
onProgress: (arg: string) => void
}) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
while (true) {
for (let i = 0; i < 10; i++) {
await timeout(1000)
Expand All @@ -87,6 +88,8 @@ async function wait({

if (result === 'FINISHED') {
break
} else if (result.includes('FAILED')) {
throw new Error('Remote returned FAILED')
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/ProteinView/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function stateModelFactory() {
/**
* #property
*/
feature: types.frozen<SimpleFeatureSerialized>(),
feature: types.frozen<SimpleFeatureSerialized | undefined>(),
/**
* #property
*/
Expand Down
7 changes: 4 additions & 3 deletions src/ProteinView/proteinToGenomeMapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function proteinToGenomeMapping({
}
const start = s0
const end = start + 3 * strand
return [Math.min(start, end), Math.max(start, end)]
return [Math.min(start, end), Math.max(start, end)] as const
}

export async function clickProteinToGenome({
Expand Down Expand Up @@ -64,7 +64,7 @@ export async function clickProteinToGenome({
`${refName}:${s1}-${s2}${strand === -1 ? '[rev]' : ''}`,
)
} else {
const assembly = assemblyManager.get(lgv.assemblyNames[0])
const assembly = assemblyManager.get(lgv.assemblyNames[0]!)
const r = assembly?.getCanonicalRefName(refName) ?? refName
lgv.centerAt(s1, r)
}
Expand All @@ -80,11 +80,12 @@ export function hoverProteinToGenome({
const session = getSession(model)
const result = proteinToGenomeMapping({ structureSeqPos, model })
const { genomeToTranscriptSeqMapping } = model
if (!genomeToTranscriptSeqMapping || !result) {
if (!genomeToTranscriptSeqMapping) {
return
}
if (!result) {
session.notify('Genome position not found')
return
}
const [s1, s2] = result
const { refName } = genomeToTranscriptSeqMapping
Expand Down
10 changes: 6 additions & 4 deletions src/ProteinView/useProteinViewClickBehavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ export default function useProteinViewClickActionBehavior({
chain,
})

clickProteinToGenome({ model, structureSeqPos: pos - 1 }).catch(e => {
console.error(e)
setError(e)
})
clickProteinToGenome({ model, structureSeqPos: pos - 1 }).catch(
(e: unknown) => {
console.error(e)
setError(e)
},
)
}
}
})
Expand Down
17 changes: 13 additions & 4 deletions src/ProteinView/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { proteinAbbreviationMapping } from './proteinAbbreviationMapping'

export function checkHovered(hovered: unknown): hovered is {
hoverFeature: Feature
hoverPosition: { coord: number; refName: string }
hoverPosition: {
coord: number
refName: string
}
} {
return (
!!hovered &&
Expand Down Expand Up @@ -43,14 +46,20 @@ export function toStr(r: {
return [
`Position: ${r.structureSeqPos}`,
r.code
? `Letter: ${r.code} (${proteinAbbreviationMapping[r.code].singleLetterCode})`
? `Letter: ${r.code} (${proteinAbbreviationMapping[r.code]?.singleLetterCode})`
: '',
r.chain ? `Chain: ${r.chain}` : '',
]
.filter(f => !!f)
.join(', ')
}

export function invertMap(arg: Record<number, number | undefined>) {
return Object.fromEntries(Object.entries(arg).map(([a, b]) => [b, a]))
export function invertMap(
arg: Record<number, number | undefined>,
): Record<number, number> {
return Object.fromEntries(
Object.entries(arg)
.map(([a, b]) => [b, a])
.filter(f => !!f[0]),
)
}
Loading

0 comments on commit db1ff14

Please sign in to comment.