UNPKG

@jbrowse/core

Version:

JBrowse 2 core libraries used by plugins

124 lines (123 loc) 4.41 kB
import { getSnapshot, getType, isArrayType, isLateType, isMapType, isModelType, isOptionalType, isStateTreeNode, isType, isUnionType, } from '@jbrowse/mobx-state-tree'; function isConfigSlot(slot) { return typeof slot?.getValue === 'function'; } import { getDefaultValue, getSubType, getUnionSubTypes, resolveLateType, } from "../util/mst-reflection.js"; export function readConfObject(confObject, slotPath, args = {}) { if (!slotPath) { return isStateTreeNode(confObject) ? structuredClone(getSnapshot(confObject)) : structuredClone(confObject); } else if (typeof slotPath === 'string') { let slot = confObject[slotPath]; if (!slot) { if (isStateTreeNode(confObject) && isMapType(getType(confObject))) { slot = confObject.get(slotPath); } if (!slot) { return undefined; } } const val = isConfigSlot(slot) ? slot.getValue(args) : slot; if (val === null || typeof val !== 'object') { return val; } return isStateTreeNode(val) ? structuredClone(getSnapshot(val)) : val; } else if (Array.isArray(slotPath)) { const slotName = slotPath[0]; if (slotPath.length > 1) { const newPath = slotPath.slice(1); let subConf = confObject[slotName]; if (!subConf && isStateTreeNode(confObject) && isMapType(getType(confObject))) { subConf = confObject.get(slotName); } return subConf ? readConfObject(subConf, newPath, args) : undefined; } return readConfObject(confObject, slotName, args); } throw new TypeError('slotPath must be a string or array'); } export function getConf(model, slotPath, args) { return readConfObject(model.configuration, slotPath, args); } export function getTypeNamesFromExplicitlyTypedUnion(maybeUnionType) { if (isType(maybeUnionType)) { maybeUnionType = resolveLateType(maybeUnionType); if (isUnionType(maybeUnionType)) { const typeNames = []; for (let type of getUnionSubTypes(maybeUnionType)) { type = resolveLateType(type); let typeName = getTypeNamesFromExplicitlyTypedUnion(type); if (!typeName.length) { const def = getDefaultValue(type); typeName = [def.type]; } if (!typeName[0]) { throw new Error(`invalid config schema type ${type}`); } typeNames.push(...typeName); } return typeNames; } } return []; } export function isBareConfigurationSchemaType(thing) { if (isType(thing)) { if (isModelType(thing) && ('isJBrowseConfigurationSchema' in thing || thing.name.includes('ConfigurationSchema'))) { return true; } if (isLateType(thing)) { return true; } } return false; } export function isConfigurationSchemaType(thing) { if (!isType(thing)) { return false; } else if (isBareConfigurationSchemaType(thing)) { return true; } else if (isUnionType(thing)) { return getUnionSubTypes(thing).every(t => isConfigurationSchemaType(t) || t.name === 'undefined'); } else if (isOptionalType(thing) && isConfigurationSchemaType(getSubType(thing))) { return true; } else if (isArrayType(thing) && isConfigurationSchemaType(getSubType(thing))) { return true; } else if (isMapType(thing) && isConfigurationSchemaType(getSubType(thing))) { return true; } else { return false; } } const configurationModelCache = new WeakMap(); export function isConfigurationModel(thing) { if (!thing || typeof thing !== 'object') { return false; } let cached = configurationModelCache.get(thing); if (cached === undefined) { cached = isStateTreeNode(thing) && isConfigurationSchemaType(getType(thing)); configurationModelCache.set(thing, cached); } return cached; } export function isConfigurationSlotType(thing) { return (typeof thing === 'object' && thing !== null && 'isJBrowseConfigurationSlot' in thing); }