Skip to content

Commit

Permalink
Squash updates
Browse files Browse the repository at this point in the history
Remove clone. It seems to be unneeded, even though it will mutate the original object, this doesn't seem like it should matter

Another optimization to the track selector

Use structuredClone

Misc lint fixes

Misc
  • Loading branch information
cmdcolin committed Oct 22, 2024
1 parent 4608823 commit 364511f
Show file tree
Hide file tree
Showing 30 changed files with 368 additions and 289 deletions.
8 changes: 7 additions & 1 deletion packages/app-core/src/JBrowseConfig/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ import { types } from 'mobx-state-tree'
export function JBrowseConfigF({
pluginManager,
assemblyConfigSchema,
adminMode,
}: {
pluginManager: PluginManager
assemblyConfigSchema: AnyConfigurationSchemaType
adminMode: boolean
}) {
return types.model('JBrowseConfig', {
configuration: ConfigurationSchema('Root', {
Expand Down Expand Up @@ -121,7 +123,11 @@ export function JBrowseConfigF({
* track configuration is an array of track config schemas. multiple
* instances of a track can exist that use the same configuration
*/
tracks: types.array(pluginManager.pluggableConfigSchemaType('track')),
tracks:
// @ts-expect-error
adminMode || globalThis.disableFrozenTracks
? types.array(pluginManager.pluggableConfigSchemaType('track'))
: types.frozen([] as { trackId: string; [key: string]: unknown }[]),
/**
* #slot
* configuration for internet accounts, see InternetAccounts
Expand Down
23 changes: 17 additions & 6 deletions packages/app-core/src/JBrowseModel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ import { JBrowseConfigF } from '../JBrowseConfig'
*/
export function JBrowseModelF({
adminMode,
pluginManager,
assemblyConfigSchema,
}: {
adminMode: boolean
pluginManager: PluginManager
assemblyConfigSchema: BaseAssemblyConfigSchema
}) {
return JBrowseConfigF({ pluginManager, assemblyConfigSchema })
return JBrowseConfigF({ pluginManager, assemblyConfigSchema, adminMode })
.views(self => ({
/**
* #getter
Expand Down Expand Up @@ -81,13 +83,17 @@ export function JBrowseModelF({
/**
* #action
*/
addTrackConf(trackConf: AnyConfigurationModel) {
addTrackConf(trackConf: { trackId: string; type: string }) {
const { type } = trackConf
if (!type) {
throw new Error(`unknown track type ${type}`)
}
const length = self.tracks.push(trackConf)
return self.tracks[length - 1]
if (adminMode) {
self.tracks.push(trackConf)
} else {
self.tracks = [...self.tracks, trackConf]
}
return self.tracks.at(-1)
},
/**
* #action
Expand All @@ -111,8 +117,13 @@ export function JBrowseModelF({
* #action
*/
deleteTrackConf(trackConf: AnyConfigurationModel) {
const elt = self.tracks.find(t => t.trackId === trackConf.trackId)
return self.tracks.remove(elt)
if (adminMode) {
const elt = self.tracks.find(t => t.trackId === trackConf.trackId)
// @ts-expect-error
return self.tracks.remove(elt)
} else {
return self.tracks.filter(f => f.trackId !== trackConf.trackId)
}
},
/**
* #action
Expand Down
50 changes: 50 additions & 0 deletions packages/core/configuration/configurationSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ import {
getSnapshot,
IAnyType,
SnapshotOut,
getEnv,
getRoot,
resolveIdentifier,
} from 'mobx-state-tree'

import { ElementId } from '../util/types/mst'

import ConfigSlot, { ConfigSlotDefinition } from './configurationSlot'
import { isConfigurationSchemaType } from './util'
import { AnyConfigurationSchemaType } from './types'
import { getContainingTrack, getSession } from '../util'

export type {
AnyConfigurationSchemaType,
Expand Down Expand Up @@ -276,9 +280,55 @@ export function ConfigurationSchema<
return schemaType
}

export function TrackConfigurationReference(schemaType: IAnyType) {
const trackRef = types.reference(schemaType, {
get(id, parent) {
let ret = getSession(parent).tracksById[id]
if (!ret) {
// @ts-expect-error
ret = resolveIdentifier(schemaType, getRoot(parent), id)
}
if (!ret) {
throw new Error(`${id} not found`)
}
return isStateTreeNode(ret) ? ret : schemaType.create(ret, getEnv(parent))
},
set(value) {
return value.trackId
},
})
return types.union(trackRef, schemaType)
}

export function DisplayConfigurationReference(schemaType: IAnyType) {
const displayRef = types.reference(schemaType, {
get(id, parent) {
const track = getContainingTrack(parent)
let ret = track.configuration.displays.find(u => u.displayId === id)
if (!ret) {
// @ts-expect-error
ret = resolveIdentifier(schemaType, getRoot(parent), id)
}
if (!ret) {
throw new Error(`${id} not found`)
}
return ret
},
set(value) {
return value.displayId
},
})
return types.union(displayRef, schemaType)
}

export function ConfigurationReference<
SCHEMATYPE extends AnyConfigurationSchemaType,
>(schemaType: SCHEMATYPE) {
if (schemaType.name.endsWith('TrackConfigurationSchema')) {
return TrackConfigurationReference(schemaType)
} else if (schemaType.name.endsWith('DisplayConfigurationSchema')) {
return DisplayConfigurationReference(schemaType)
}
// we cast this to SCHEMATYPE, because the reference *should* behave just
// like the object it points to. It won't be undefined (this is a
// `reference`, not a `safeReference`)
Expand Down
103 changes: 102 additions & 1 deletion packages/core/util/tracks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { getParent, isRoot, IAnyStateTreeNode } from 'mobx-state-tree'
import {
getParent,
getRoot,
isRoot,
resolveIdentifier,
types,
IAnyStateTreeNode,
Instance,
IAnyType,
} from 'mobx-state-tree'
import { getSession, objectHash, getEnv } from './index'
import { PreFileLocation, FileLocation } from './types'
import { readConfObject, AnyConfigurationModel } from '../configuration'
Expand Down Expand Up @@ -268,3 +277,95 @@ export function getTrackName(
}
return trackName
}

type MSTArray<T extends IAnyType> = Instance<ReturnType<typeof types.array<T>>>

interface MinimalTrack extends IAnyType {
configuration: { trackId: string }
}

interface GenericView {
type: string
tracks: MSTArray<MinimalTrack>
}

export function showTrackGeneric(
self: GenericView,
trackId: string,
initialSnapshot = {},
displayInitialSnapshot = {},
) {
const { pluginManager } = getEnv(self)
const session = getSession(self)
let conf = session.tracks.find(t => t.trackId === trackId)
if (!conf) {
const schema = pluginManager.pluggableConfigSchemaType('track')
conf = resolveIdentifier(schema, getRoot(self), trackId)
}
if (!conf) {
throw new Error(`Could not resolve identifier "${trackId}"`)
}
const trackType = pluginManager.getTrackType(conf.type)
if (!trackType) {
throw new Error(`Unknown track type ${conf.type}`)
}
const viewType = pluginManager.getViewType(self.type)!
const supportedDisplays = new Set(viewType.displayTypes.map(d => d.name))

const { displays = [] } = conf
const displayTypes = new Set()

displays.forEach((d: any) => d && displayTypes.add(d.type))
trackType.displayTypes.forEach(displayType => {
if (!displayTypes.has(displayType.name)) {
displays.push({
displayId: `${trackId}-${displayType.name}`,
type: displayType.name,
})
}
})

const displayConf = displays?.find((d: AnyConfigurationModel) =>
supportedDisplays.has(d.type),
)
if (!displayConf) {
throw new Error(
`Could not find a compatible display for view type ${self.type}`,
)
}

const found = self.tracks.find(t => t.configuration.trackId === trackId)
if (!found) {
const track = trackType.stateModel.create({
...initialSnapshot,
type: conf.type,
configuration: conf,
displays: [
{
type: displayConf.type,
configuration: displayConf,
...displayInitialSnapshot,
},
],
})
self.tracks.push(track)
return track
}
return found
}

export function hideTrackGeneric(self: GenericView, trackId: string) {
const t = self.tracks.find(t => t.configuration.trackId === trackId)
if (t) {
self.tracks.remove(t)
return 1
}
return 0
}

export function toggleTrackGeneric(self: GenericView, trackId: string) {
const hiddenCount = hideTrackGeneric(self, trackId)
if (!hiddenCount) {
showTrackGeneric(self, trackId)
}
}
5 changes: 4 additions & 1 deletion packages/core/util/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export type DialogComponentType =

/** minimum interface that all session state models must implement */
export interface AbstractSessionModel extends AbstractViewContainer {
tracksById: Record<string, AnyConfigurationModel>
jbrowse: IAnyStateTreeNode
drawerPosition?: string
configuration: AnyConfigurationModel
Expand Down Expand Up @@ -295,9 +296,11 @@ export function isViewModel(thing: unknown): thing is AbstractViewModel {
)
}

type Display = { displayId: string } & AnyConfigurationModel

export interface AbstractTrackModel {
displays: AbstractDisplayModel[]
configuration: AnyConfigurationModel
configuration: AnyConfigurationModel & { displays: Display[] }
}

export function isTrackModel(thing: unknown): thing is AbstractTrackModel {
Expand Down
7 changes: 7 additions & 0 deletions packages/product-core/src/Session/Tracks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ export function TracksManagerSessionMixin(pluginManager: PluginManager) {
get tracks(): AnyConfigurationModel[] {
return self.jbrowse.tracks
},

/**
* #getter
*/
get tracksById(): Record<string, AnyConfigurationModel> {
return Object.fromEntries(this.tracks.map(t => [t.trackId, t]))
},
}))
.actions(self => ({
/**
Expand Down
14 changes: 10 additions & 4 deletions packages/product-core/src/ui/AboutDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
import React from 'react'
import { AnyConfigurationModel } from '@jbrowse/core/configuration'
import Dialog from '@jbrowse/core/ui/Dialog'
import { getSession, getEnv } from '@jbrowse/core/util'
import { getEnv, AbstractSessionModel } from '@jbrowse/core/util'
import { getTrackName } from '@jbrowse/core/util/tracks'

// locals
import AboutContents from './AboutDialogContents'

export function AboutDialog({
config,
session,
handleClose,
}: {
config: AnyConfigurationModel
session: AbstractSessionModel
handleClose: () => void
}) {
const session = getSession(config)
const trackName = getTrackName(config, session)
const { pluginManager } = getEnv(session)

const AboutComponent = pluginManager.evaluateExtensionPoint(
'Core-replaceAbout',
AboutContents,
{ session, config },
) as React.FC<any>
) as React.FC<{
config: AnyConfigurationModel
session: AbstractSessionModel
}>

return (
<Dialog open onClose={handleClose} title={trackName} maxWidth="xl">
<AboutComponent config={config} />
<AboutComponent config={config} session={session} />
</Dialog>
)
}
11 changes: 7 additions & 4 deletions packages/product-core/src/ui/AboutDialogContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import {
readConfObject,
AnyConfigurationModel,
} from '@jbrowse/core/configuration'
import { getSession, getEnv } from '@jbrowse/core/util'
import { getEnv, AbstractSessionModel } from '@jbrowse/core/util'
import {
BaseCard,
Attributes,
} from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
import FileInfoPanel from './FileInfoPanel'
import RefNameInfoDialog from './RefNameInfoDialog'
import { isStateTreeNode } from 'mobx-state-tree'

const useStyles = makeStyles()({
content: {
Expand All @@ -39,12 +40,13 @@ function removeAttr(obj: Record<string, unknown>, attr: string) {

const AboutDialogContents = observer(function ({
config,
session,
}: {
config: AnyConfigurationModel
session: AbstractSessionModel
}) {
const [copied, setCopied] = useState(false)
const conf = readConfObject(config)
const session = getSession(config)
const conf = isStateTreeNode(config) ? readConfObject(config) : config
const { classes } = useStyles()
const [showRefNames, setShowRefNames] = useState(false)

Expand Down Expand Up @@ -112,9 +114,10 @@ const AboutDialogContents = observer(function ({
<ExtraPanel.Component config={config} />
</BaseCard>
) : null}
<FileInfoPanel config={config} />
<FileInfoPanel config={config} session={session} />
{showRefNames ? (
<RefNameInfoDialog
session={session}
config={config}
onClose={() => {
setShowRefNames(false)
Expand Down
Loading

0 comments on commit 364511f

Please sign in to comment.