Skip to content

Commit

Permalink
[skip ci] Misc
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Dec 7, 2024
1 parent deaf72a commit 070386c
Show file tree
Hide file tree
Showing 51 changed files with 1,124 additions and 1,131 deletions.
61 changes: 27 additions & 34 deletions packages/core/configuration/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ export function readConfObject<CONFMODEL extends AnyConfigurationModel>(
args: Record<string, unknown> = {},
): any {
if (!slotPath) {
return JSON.parse(JSON.stringify(getSnapshot(confObject)))
}
if (typeof slotPath === 'string') {
return structuredClone(getSnapshot(confObject))
} else if (typeof slotPath === 'string') {
let slot = confObject[slotPath]
// check for the subconf being a map if we don't find it immediately
if (
Expand All @@ -66,15 +65,13 @@ export function readConfObject<CONFMODEL extends AnyConfigurationModel>(
// schemaType.name
// })`,
// )
} else {
const val = slot.expr ? slot.expr.evalSync(args) : slot
return isStateTreeNode(val)
? JSON.parse(JSON.stringify(getSnapshot(val)))
: val
}

const val = slot.expr ? slot.expr.evalSync(args) : slot
return isStateTreeNode(val)
? JSON.parse(JSON.stringify(getSnapshot(val)))
: val
}

if (Array.isArray(slotPath)) {
} else if (Array.isArray(slotPath)) {
const slotName = slotPath[0]!
if (slotPath.length > 1) {
const newPath = slotPath.slice(1)
Expand Down Expand Up @@ -172,39 +169,35 @@ export function isBareConfigurationSchemaType(
export function isConfigurationSchemaType(
thing: unknown,
): thing is AnyConfigurationSchemaType {
if (!isType(thing)) {
return false
}

// written as a series of if-statements instead of a big logical OR
// because this construction gives much better debugging backtraces.
// written as a series of if-statements instead of a big logical because this
// construction gives much better debugging backtraces.

// also, note that the order of these statements matters, because
// for example some union types are also optional types
// also, note that the order of these statements matters, because for example
// some union types are also optional types

if (isBareConfigurationSchemaType(thing)) {
if (!isType(thing)) {
return false
} else if (isBareConfigurationSchemaType(thing)) {
return true
}

if (isUnionType(thing)) {
} else if (isUnionType(thing)) {
return getUnionSubTypes(thing).every(
t => isConfigurationSchemaType(t) || t.name === 'undefined',
)
}

if (isOptionalType(thing) && isConfigurationSchemaType(getSubType(thing))) {
} else if (
isOptionalType(thing) &&
isConfigurationSchemaType(getSubType(thing))
) {
return true
}

if (isArrayType(thing) && isConfigurationSchemaType(getSubType(thing))) {
} else if (
isArrayType(thing) &&
isConfigurationSchemaType(getSubType(thing))
) {
return true
}

if (isMapType(thing) && isConfigurationSchemaType(getSubType(thing))) {
} else if (isMapType(thing) && isConfigurationSchemaType(getSubType(thing))) {
return true
} else {
return false
}

return false
}

export function isConfigurationModel(
Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
},
"dependencies": {
"@babel/runtime": "^7.17.9",
"@floating-ui/react": "^0.27.0",
"@gmod/abortable-promise-cache": "^2.0.0",
"@gmod/bgzf-filehandle": "^1.4.3",
"@gmod/http-range-fetcher": "^3.0.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import RpcMethodType from './RpcMethodType'
import { renameRegionsIfNeeded } from '../util'
import SerializableFilterChain from './renderers/util/serializableFilterChain'

import type { RenderArgs } from '@jbrowse/core/rpc/coreRpcMethods'

export default abstract class RpcMethodTypeWithFiltersAndRenameRegions extends RpcMethodType {
async deserializeArguments(args: any, rpcDriverClassName: string) {
const l = await super.deserializeArguments(args, rpcDriverClassName)
return {
...l,
filters: args.filters
? new SerializableFilterChain({
filters: args.filters,
})
: undefined,
}
}

async serializeArguments(
args: RenderArgs & {
stopToken?: string
statusCallback?: (arg: string) => void
},
rpcDriverClassName: string,
) {
const pm = this.pluginManager
const assemblyManager = pm.rootModel?.session?.assemblyManager
if (!assemblyManager) {
throw new Error('no assembly manager')
}

const renamedArgs = await renameRegionsIfNeeded(assemblyManager, {
...args,
filters: args.filters?.toJSON().filters,
})

return super.serializeArguments(renamedArgs, rpcDriverClassName)
}
}
41 changes: 6 additions & 35 deletions packages/core/rpc/BaseRpcDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ export default abstract class BaseRpcDriver {
if (!sessionId) {
throw new TypeError('sessionId is required')
}
let done = false
const unextendedWorker = await this.getWorker(sessionId)
const worker = pluginManager.evaluateExtensionPoint(
'Core-extendWorker',
Expand All @@ -172,41 +171,13 @@ export default abstract class BaseRpcDriver {
const filteredAndSerializedArgs = this.filterArgs(serializedArgs, sessionId)

// now actually call the worker
const callP = worker
.call(functionName, filteredAndSerializedArgs, {
timeout: 5 * 60 * 1000, // 5 minutes
statusCallback: args.statusCallback,
rpcDriverClassName: this.name,
...options,
})
.finally(() => {
done = true
})

// check every 5 seconds to see if the worker has been killed, and reject
// the killedP promise if it has
let killedCheckInterval: ReturnType<typeof setInterval>
const killedP = new Promise((resolve, reject) => {
killedCheckInterval = setInterval(() => {
// must've been killed
if (worker.status === 'killed') {
reject(
new Error(
`operation timed out, worker process stopped responding, ${worker.error}`,
),
)
} else if (done) {
resolve(true)
}
}, this.workerCheckFrequency)
}).finally(() => {
clearInterval(killedCheckInterval)
const call = await worker.call(functionName, filteredAndSerializedArgs, {
timeout: 5 * 60 * 1000, // 5 minutes
statusCallback: args.statusCallback,
rpcDriverClassName: this.name,
...options,
})

// the result is a race between the actual result promise, and the "killed"
// promise. the killed promise will only actually win if the worker was
// killed before the call could return
const resultP = Promise.race([callP, killedP])
return rpcMethod.deserializeReturn(resultP, args, this.name)
return rpcMethod.deserializeReturn(call, args, this.name)
}
}
8 changes: 6 additions & 2 deletions packages/core/ui/LoadingEllipses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,13 @@ export default function LoadingEllipses({
variant = 'body2',
...rest
}: Props) {
const { classes } = useStyles()
const { cx, classes } = useStyles()
return (
<Typography className={classes.dots} {...rest} variant={variant}>
<Typography
className={cx(classes.dots, rest.className)}
{...rest}
variant={variant}
>
{message || 'Loading'}
</Typography>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
} from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
import { Paper } from '@mui/material'
import { observer } from 'mobx-react'
import { SimpleFeatureSerialized } from '@jbrowse/core/util'

import type { SimpleFeatureSerialized } from '@jbrowse/core/util'

const BreakpointAlignmentsFeatureDetail = observer(function ({
model,
Expand Down
1 change: 0 additions & 1 deletion plugins/dotplot-view/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"clean": "rimraf dist esm *.tsbuildinfo"
},
"dependencies": {
"@floating-ui/react": "^0.26.3",
"@mui/icons-material": "^6.0.0",
"@mui/x-data-grid": "^7.0.0",
"@types/file-saver": "^2.0.1",
Expand Down
5 changes: 0 additions & 5 deletions plugins/dotplot-view/src/ComparativeRenderer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ interface RenderArgsSerialized extends ComparativeRenderArgsSerialized {
rendererType: string
}

/**
* call a synteny renderer with the given args
* param views: a set of views that each contain a set of regions
* used instead of passing regions directly as in render()
*/
export default class ComparativeRender extends RpcMethodType {
name = 'ComparativeRender'

Expand Down
1 change: 0 additions & 1 deletion plugins/linear-comparative-view/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"clean": "rimraf dist esm *.tsbuildinfo"
},
"dependencies": {
"@floating-ui/react": "^0.26.3",
"@mui/icons-material": "^6.0.0",
"copy-to-clipboard": "^3.3.1",
"file-saver": "^2.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@ import { ConfigurationSchema } from '@jbrowse/core/configuration'
import { linearPileupDisplayConfigSchemaFactory } from '@jbrowse/plugin-alignments'

import type PluginManager from '@jbrowse/core/PluginManager'
import type { Feature } from '@jbrowse/core/util'

/**
* #config LGVSyntenyDisplay
* extends config
* - [LinearPileupDisplay](../linearpileupdisplay)
*/
function configSchemaF(pluginManager: PluginManager) {
pluginManager.jexl.addFunction('lgvSyntenyTooltip', (f: Feature) => {
const m = f.get('mate')
return [f.get('name') || f.get('id'), m?.name || m?.id]
.filter(f => !!f)
.join('<br/>')
})
return ConfigurationSchema(
'LGVSyntenyDisplay',
{
mouseover: {
type: 'string',
defaultValue:
'jexl:(get(feature,"name")||"")+ "<br/>" + (get(feature,"mate").name||"")',
defaultValue: 'jexl:lgvSyntenyTooltip(feature)',
},
},
{
Expand Down
1 change: 0 additions & 1 deletion plugins/linear-genome-view/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"useSrc": "node ../../scripts/useSrc.js"
},
"dependencies": {
"@floating-ui/react": "^0.26.3",
"@mui/icons-material": "^6.0.0",
"@types/file-saver": "^2.0.1",
"copy-to-clipboard": "^3.3.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react'

import ErrorMessageStackTraceDialog from '@jbrowse/core/ui/ErrorMessageStackTraceDialog'
import { getSession } from '@jbrowse/core/util'
import RefreshIcon from '@mui/icons-material/Refresh'
import ReportIcon from '@mui/icons-material/Report'
import { IconButton, Tooltip } from '@mui/material'
import { observer } from 'mobx-react'

import BlockMsg from './BlockMsg'

const BlockError = observer(function ({ model }: { model: any }) {
return (
<BlockMsg
message={`${model.error}`}
severity="error"
action={
<>
<Tooltip title="Reload track">
<IconButton
data-testid="reload_button"
onClick={() => {
model.reload()
}}
>
<RefreshIcon />
</IconButton>
</Tooltip>
<Tooltip title="Show stack trace">
<IconButton
onClick={() => {
getSession(model).queueDialog(onClose => [
ErrorMessageStackTraceDialog,
{ onClose, error: model.error as Error },
])
}}
>
<ReportIcon />
</IconButton>
</Tooltip>
</>
}
/>
)
})

export default BlockError
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ export default function BlockMsg({
const { classes } = useStyles()
return (
<Alert
onClick={event => {
event.stopPropagation()
}}
severity={severity}
action={action}
classes={{ message: classes.ellipses }}
Expand Down
Loading

0 comments on commit 070386c

Please sign in to comment.