UNPKG

@jbrowse/core

Version:

JBrowse 2 core libraries used by plugins

175 lines (174 loc) 7.36 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfigurationSchema = ConfigurationSchema; exports.ConfigurationReference = ConfigurationReference; const mobx_state_tree_1 = require("mobx-state-tree"); const configurationSlot_1 = __importDefault(require("./configurationSlot")); const util_1 = require("./util"); const mst_1 = require("../util/types/mst"); function isEmptyObject(thing) { return (typeof thing === 'object' && !Array.isArray(thing) && thing !== null && Object.keys(thing).length === 0); } function isEmptyArray(thing) { return Array.isArray(thing) && thing.length === 0; } function preprocessConfigurationSchemaArguments(modelName, inputSchemaDefinition, inputOptions = {}) { var _a; if (typeof modelName !== 'string') { throw new Error('first arg must be string name of the model that this config schema goes with'); } let schemaDefinition = inputSchemaDefinition; let options = inputOptions; if ((_a = inputOptions.baseConfiguration) === null || _a === void 0 ? void 0 : _a.jbrowseSchemaDefinition) { schemaDefinition = { ...inputOptions.baseConfiguration.jbrowseSchemaDefinition, ...schemaDefinition, }; options = { ...inputOptions.baseConfiguration.jbrowseSchemaOptions, ...inputOptions, }; options.baseConfiguration = undefined; } return { schemaDefinition, options }; } function makeConfigurationSchemaModel(modelName, schemaDefinition, options) { const modelDefinition = {}; let identifier; if (options.explicitlyTyped) { modelDefinition.type = mobx_state_tree_1.types.optional(mobx_state_tree_1.types.literal(modelName), modelName); } if (options.explicitIdentifier && options.implicitIdentifier) { throw new Error(`Cannot have both explicit and implicit identifiers in ${modelName}`); } if (options.explicitIdentifier) { if (typeof options.explicitIdentifier === 'string') { modelDefinition[options.explicitIdentifier] = mobx_state_tree_1.types.identifier; identifier = options.explicitIdentifier; } else { modelDefinition.id = mobx_state_tree_1.types.identifier; identifier = 'id'; } } else if (options.implicitIdentifier) { if (typeof options.implicitIdentifier === 'string') { modelDefinition[options.implicitIdentifier] = mst_1.ElementId; identifier = options.implicitIdentifier; } else { modelDefinition.id = mst_1.ElementId; identifier = 'id'; } } const volatileConstants = { isJBrowseConfigurationSchema: true, jbrowseSchema: { modelName, definition: schemaDefinition, options, }, }; for (const [slotName, slotDefinition] of Object.entries(schemaDefinition)) { if (((0, mobx_state_tree_1.isType)(slotDefinition) && (0, mobx_state_tree_1.isLateType)(slotDefinition)) || (0, util_1.isConfigurationSchemaType)(slotDefinition)) { modelDefinition[slotName] = slotDefinition; } else if (typeof slotDefinition === 'string' || typeof slotDefinition === 'number') { volatileConstants[slotName] = slotDefinition; } else if (typeof slotDefinition === 'object') { if (!slotDefinition.type) { throw new Error(`no type set for config slot ${modelName}.${slotName}`); } try { modelDefinition[slotName] = (0, configurationSlot_1.default)(slotName, slotDefinition); } catch (e) { throw new Error(`invalid config slot definition for ${modelName}.${slotName}: ${e}`); } } else { throw new Error(`invalid configuration schema definition, "${slotName}" must be either a valid configuration slot definition, a constant, or a nested configuration schema`); } } let completeModel = mobx_state_tree_1.types .model(`${modelName}ConfigurationSchema`, modelDefinition) .actions(self => ({ setSubschema(slotName, data) { if (!(0, util_1.isConfigurationSchemaType)(modelDefinition[slotName])) { throw new Error(`${slotName} is not a subschema, cannot replace`); } const newSchema = (0, mobx_state_tree_1.isStateTreeNode)(data) ? data : modelDefinition[slotName].create(data); self[slotName] = newSchema; return newSchema; }, })); if (Object.keys(volatileConstants).length) { completeModel = completeModel.volatile(() => volatileConstants); } if (options.actions) { completeModel = completeModel.actions(options.actions); } if (options.views) { completeModel = completeModel.views(options.views); } if (options.extend) { completeModel = completeModel.extend(options.extend); } const identifierDefault = identifier ? { [identifier]: 'placeholderId' } : {}; const modelDefault = options.explicitlyTyped ? { type: modelName, ...identifierDefault } : identifierDefault; const defaultSnap = (0, mobx_state_tree_1.getSnapshot)(completeModel.create(modelDefault)); completeModel = completeModel.postProcessSnapshot(snap => { const newSnap = {}; let matchesDefault = true; for (const [key, value] of Object.entries(snap)) { if (matchesDefault) { if (typeof defaultSnap[key] === 'object' && typeof value === 'object') { if (JSON.stringify(defaultSnap[key]) !== JSON.stringify(value)) { matchesDefault = false; } } else if (defaultSnap[key] !== value) { matchesDefault = false; } } if (value !== undefined && volatileConstants[key] === undefined && !isEmptyObject(value) && !isEmptyArray(value)) { newSnap[key] = value; } } if (matchesDefault) { return {}; } return newSnap; }); if (options.preProcessSnapshot) { completeModel = completeModel.preProcessSnapshot(options.preProcessSnapshot); } return mobx_state_tree_1.types.optional(completeModel, modelDefault); } function ConfigurationSchema(modelName, inputSchemaDefinition, inputOptions) { const { schemaDefinition, options } = preprocessConfigurationSchemaArguments(modelName, inputSchemaDefinition, inputOptions); const schemaType = makeConfigurationSchemaModel(modelName, schemaDefinition, options); schemaType.isJBrowseConfigurationSchema = true; schemaType.jbrowseSchemaDefinition = schemaDefinition; schemaType.jbrowseSchemaOptions = options; return schemaType; } function ConfigurationReference(schemaType) { return mobx_state_tree_1.types.union(mobx_state_tree_1.types.reference(schemaType), schemaType); }