UNPKG

sdj-esm

Version:
255 lines (254 loc) 8.88 kB
/* Copyright (c) 2023-2024 Will Rudolph <@willrudolph.com> This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { SdjDescription } from "../classes/description.js"; import { DESC_ALT, ESDJ_CLASS, ESDJ_LOG } from "../core/statics.js"; import { SdjLexicons } from "./lexicons.js"; import { SdjEntity } from "../classes/entity.js"; import { SdjItem } from "../classes/item.js"; import { SdjData } from "../classes/data.js"; import { each, isEqual, isFunction } from "lodash-es"; import { SdjSearch } from "./search.js"; import { LogManager } from "../util/log.js"; import { freezeDescription } from "../util/general.js"; class EmptySdjLibrary { init() { } getDescList() { return []; } getDescByName() { return undefined; } storeDesc() { return false; } removeDesc() { return false; } } class IntSingletonLock { constructor() { // console.log("IntSingletonLock"); } } export class SdjHost { // eslint-disable-next-line no-use-before-define static _instance; gLog; _lexicons; _library; _search; _logs; constructor(lockCon, initialSet) { if (!(lockCon instanceof IntSingletonLock)) { throw new Error("[SDJ] Illegal attempt create SdjHost"); } this.initLogs(initialSet?.options); this.gLog = this._logs.getLogFunc("ISdjHost"); this._lexicons = new SdjLexicons(this, initialSet?.lexicons); this._search = new SdjSearch(this); if (initialSet?.options?.logMode && initialSet.options.logMode !== ESDJ_LOG.PROD) { this.gLog("Set logMode:" + initialSet.options.logMode); } if (initialSet?.library) { this.verifyLibrary(initialSet.library); this._library = initialSet.library; this._library.init(this._logs.getLogFunc("ISdjLibrary"), this); } else { this._library = new EmptySdjLibrary(); } } get library() { return this._library; } get lexiconMgr() { return this._lexicons; } get searchMgr() { return this._search; } get logs() { return this._logs; } makeDescript(descJI, unlocked = false) { let rtnDesc = this._library.getDescByName(descJI.sdInfo.name), expDesc, newDesc; if (rtnDesc) { if (!isEqual(descJI, rtnDesc.genJI())) { descJI.sdInfo.name += DESC_ALT; } else { return rtnDesc; } } const thisHost = SdjHost.getHost(); newDesc = new SdjDescription(descJI, thisHost); if (this._library.storeDesc(newDesc)) { rtnDesc = this._library.getDescByName(descJI.sdInfo.name); if (rtnDesc) { expDesc = rtnDesc; } else { this.gLog("Error on unsuccessful add description to library;", 3); expDesc = newDesc; } } else { expDesc = newDesc; } if (!unlocked) { freezeDescription(expDesc); } return expDesc; } fullDescription(inDescJI) { if (inDescJI.lexicons && this.lexiconMgr.names.length > 0) { if (!this.lexiconMgr.validateRequires(inDescJI)) { throw new Error("[SDJ] There has been an unknown lexicon error"); } } inDescJI.items = this.lexiconMgr.fullItemJI(inDescJI); inDescJI.graph = this.lexiconMgr.fullGraphJI(inDescJI); if (!this.lexiconMgr.validateGraph(inDescJI)) { throw new Error("[SDJ] There has been an unknown lexicon error"); } return inDescJI; } getLogFunc(name) { return this._logs.getLogFunc(name); } // Given the validation rules some JIs can look like each other; // This function is to lock out/check for strange loading of Sdj Class objects that // are code masquerading themselves or other strangeness. checkClassInst(ji, jiType, isClass = false) { let isInst; switch (jiType) { case ESDJ_CLASS.DESCRIPTION: isInst = (ji instanceof SdjDescription); break; case ESDJ_CLASS.HOST: isInst = (ji instanceof SdjHost); break; case ESDJ_CLASS.DATA: isInst = (ji instanceof SdjData); break; case ESDJ_CLASS.ITEM: isInst = (ji instanceof SdjItem); break; case ESDJ_CLASS.ENTITY: isInst = (ji instanceof SdjEntity); break; default: throw new Error(`[SDJ] in checkClassInst jiType must match ESDJ_CLASS types, value is '${jiType}'`); } if (isClass && !isInst) { throw new Error(`[SDJ] input value is required to be class '${jiType}';`); } else if (!isClass && isInst) { throw new Error(`[SDJ] input JI value cannot be of class '${jiType}';`); } } verifyJIbyType(ji, jiType, strict = false) { let rtnVal = true, ogError; try { switch (jiType) { case ESDJ_CLASS.DESCRIPTION: SdjDescription.VerifyJI(ji); break; case ESDJ_CLASS.DATA: SdjData.VerifyJI(ji); break; case ESDJ_CLASS.ITEM: SdjItem.VerifyJI(ji); break; case ESDJ_CLASS.ENTITY: SdjEntity.VerifyJI(ji); break; default: // no default } } catch (verifyError) { ogError = verifyError; rtnVal = false; } if (strict) { if (!rtnVal) { throw new Error(`[SDJ] verifyJI '${jiType}' failed: ${ogError}`); } } return rtnVal; } createDescription(descJI) { let rtnDesc = this._library.getDescByName(descJI.sdInfo.name); if (rtnDesc) { if (!isEqual(descJI, rtnDesc.genJI())) { descJI.sdInfo.name += DESC_ALT; } else { return rtnDesc; } } rtnDesc = new SdjDescription(descJI, SdjHost.getHost()); this._library.storeDesc(rtnDesc); return rtnDesc; } initLogs(options) { if (options?.loggerStore && options?.logManager) { throw new Error("[SDJ] Create a custom ILogManager or alternate loggerStore, not both;"); } else if (options?.logManager) { if (!isFunction(options.logManager.getLogFunc)) { throw new Error("[SDJ] custom ILogManager missing getLogFunc"); } else { this._logs = options.logManager; } } else { const logMode = (options?.logMode) ? options.logMode : ESDJ_LOG.PROD; this._logs = new LogManager(logMode, options?.loggerStore); } } verifyLibrary(inLib) { const vfList = [inLib.init, inLib.getDescByName, inLib.getDescList, inLib.storeDesc, inLib.removeDesc]; each(vfList, (testFunc) => { if (!isFunction(testFunc)) { throw new Error("[SDJ] Illegal ISdjLibrary assignment, does not include all functions;"); } }); } // This is for testing purposes commented out on initial release // builds static setTestingInstance(testInstance) { this._instance = testInstance; } // Primary static external access point static getISdjHost(options) { if (this._instance && options) { throw new Error("[SDJ] Illegal attempt to change SDJ after initialization;"); } else if (!this._instance) { this._instance = new SdjHost(new IntSingletonLock(), options); } return this._instance; } // Sdj Library is built to allow initialization ONCE, and will error on second+ attempts. // // Use of either top-level library classes (Description, Json) before an initialization setup // will lock the system to defaults; This entry point is only meant for those classes. // Independently created Entities, Items and Data are exempt. // // Use of this entry point does allow access to core SdjHost functionality; if needed. // static getHost() { if (!this._instance) { this._instance = new SdjHost(new IntSingletonLock()); } return this._instance; } } //# sourceMappingURL=host.js.map