@launchmenu/core
Version:
An environment for visual keyboard controlled applets
259 lines • 20.4 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppletManager = void 0;
const hmr_1 = __importStar(require("@launchmenu/hmr"));
const model_react_1 = require("model-react");
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const createAppletResultCategory_1 = require("./createAppletResultCategory");
const withLM_1 = require("./declaration/withLM");
const JSONFile_1 = require("../../settings/storage/fileTypes/JSONFile");
/**
* A manager of applets, takes care of loading applets given their locations
*/
class AppletManager {
/**
* Creates a new applet manager instances with the given sources
* @param LM The LM instance that this applet manager is for
* @param settingsDirectory The directory to retrieve the installed applets from
* @param reloadOnChanges Whether to listen for applet code changes and update the applet when such a change occurs
*/
constructor(LM, settingsConfig, reloadOnChanges = LM.isInDevMode()) {
this.destroyed = new model_react_1.Field(false);
/** A field that can be used to dynamically add any applets to the manager (does require some manual maintenance) */
this.extraApplets = new model_react_1.Field([]); // TODO: make helper methods to manager the extra applets
/** Versions numbers of the applets, such that applets are reloaded if their version changes */
this.appletVersions = new model_react_1.Field({});
/**
* The sources in an array form
*/
this.sources = new model_react_1.DataCacher(h => {
const appletsObject = this.sourceFile.get(h);
if (appletsObject instanceof Object && !(appletsObject instanceof Array)) {
const appletSources = Object.keys(appletsObject).flatMap(ID => {
const data = appletsObject[ID];
if (typeof data == "string")
return { ID, directory: data };
else
return [];
});
return appletSources;
}
else {
console.error("No valid applets config was found");
return [];
}
});
/**
* A transformer that obtains applets from the sources, versions and whether this manager is destroyed
*/
this.applets = new model_react_1.DataCacher((h, prevApplets = []) => {
const destroyed = this.destroyed.get(h);
const sources = destroyed ? [] : this.sources.get(h);
const versions = this.appletVersions.get(h);
const sourcesWithVersions = sources.map(source => {
var _a;
return ({
...source,
version: (_a = versions[source.ID]) !== null && _a !== void 0 ? _a : 0,
});
});
// Dispose of any applets that are no longer used (or of which a new version is requested)
prevApplets.forEach(appletData => {
const stillUsed = !!sourcesWithVersions.find(source => source.ID == appletData.applet.ID &&
source.version == appletData.version);
if (!stillUsed)
this.disposeAppletData(appletData);
});
// Retrieve the new list of applets, using the previously initialized applet if available
const applets = sourcesWithVersions.flatMap(source => {
var _a, _b;
const prevApplet = prevApplets.find(({ applet, version }) => applet.ID == source.ID && version == source.version);
if (prevApplet)
return prevApplet;
// If no applet exists for this source yet, create it
try {
const applet = this.initApplet(source, source.version);
return {
applet,
category: createAppletResultCategory_1.createAppletResultCategory(applet),
version: source.version,
watcher: ((_a = applet.development) === null || _a === void 0 ? void 0 : _a.liveReload) != false && this.reloadOnChanges
? this.setupAppletWatcher(source, applet)
: undefined,
};
}
catch (e) {
console.error(e);
// If the latest version errored while loading, try to reinitialize the previous version
const prev = prevApplets.find(({ applet }) => applet.ID == source.ID);
if (prev) {
return {
...prev,
watcher: ((_b = prev.applet.development) === null || _b === void 0 ? void 0 : _b.liveReload) != false &&
this.reloadOnChanges
? this.setupAppletWatcher(source, prev.applet)
: undefined,
};
}
return [];
}
});
return applets;
});
this.LM = LM;
this.settingsConfig = settingsConfig;
this.reloadOnChanges = reloadOnChanges;
this.sourceFile = new JSONFile_1.JSONFile(path_1.default.join(settingsConfig.directory, "applets.json"));
}
/**
* Properly disposes all data associated to this applet
* @param appletData The applet data to be disposed
*/
disposeAppletData(appletData) {
var _a, _b, _c;
try {
(_b = (_a = appletData.applet).onDispose) === null || _b === void 0 ? void 0 : _b.call(_a);
}
catch (e) {
console.error(e);
}
this.settingsConfig.removeSettings(appletData.applet.ID);
(_c = appletData.watcher) === null || _c === void 0 ? void 0 : _c.destroy();
}
/**
* Disposes of all data
*/
destroy() {
this.destroyed.set(true);
// Force retrieve the applets to uninitialize old applets
this.applets.get();
this.extraApplets.set([]);
}
// Getters
/**
* Retrieves all the applets, including dynamic extra applets
* @param hook The hook to subscribe to changes
* @returns The applets data
*/
getAppletsData(hook) {
return [...this.applets.get(hook), ...this.extraApplets.get(hook)];
}
/**
* Retrieves the loaded applets
* @param hook The hook to subscribe to changes
* @returns The applets
*/
getApplets(hook) {
return this.getAppletsData(hook).map(({ applet }) => applet);
}
/**
* Retrieves the loaded applet with the given ID
* @param ID The ID of the applet to retrieve
* @param hook The hook to subscribe to changes
* @returns The applet if found
*/
getApplet(ID, hook) {
var _a;
return (((_a = this.getAppletsData(hook).find(({ applet }) => applet.ID == ID)) === null || _a === void 0 ? void 0 : _a.applet) || null);
}
/**
* Retrieves the applet and categories that items for them can be listed in
* @param hook The hook to subscribe to changes
* @returns The applets and categories
*/
getAppletCategories(hook) {
return this.getAppletsData(hook);
}
/**
* Retrieves the category for the given applet
* @param applet The applet to get the category of
* @param hook The hook to subscribe to changes
* @returns The category
*/
getAppletCategory(applet, hook) {
var _a;
return (_a = this.getAppletsData(hook).find(({ applet: { ID } }) => ID == applet.ID)) === null || _a === void 0 ? void 0 : _a.category;
}
// Applet management
/**
* Initializes an applet
* @param source The source data of the applet
* @param version The new version of the applet
* @throws An exception if no valid applet was found
* @returns The applet data
*/
initApplet({ ID, directory }, version) {
var _a;
// Obtain the module export and check if it has a valid applet export
const appletExport = hmr_1.referencelessRequire(path_1.default.isAbsolute(directory) ? directory : path_1.default.join(process.cwd(), directory));
if ((_a = appletExport === null || appletExport === void 0 ? void 0 : appletExport.default) === null || _a === void 0 ? void 0 : _a.info) {
// Load the applet if valid
const baseApplet = {
...appletExport.default,
ID,
};
const settingsTree = this.settingsConfig.getSettings(baseApplet, version);
return withLM_1.withLM(baseApplet, this.LM, settingsTree);
}
else {
// Throw an error when the module has no proper applet
throw Error(`Failed to load applet ${ID}, please make sure it has a proper default export`);
}
}
/**
* Retrieves a file watcher for a given applet
* @param source The source of the applet
* @param applet The applet to setup the watcher for
* @returns The file watcher that was created
*/
setupAppletWatcher(source, applet) {
var _a, _b;
const baseDir = source.directory;
const absoluteBaseDir = path_1.default.isAbsolute(baseDir)
? path_1.default.dirname(require.resolve(`${baseDir}/package.json`))
: path_1.default.join(process.cwd(), baseDir);
const buildDir = path_1.default.resolve(absoluteBaseDir, (_b = (_a = applet.development) === null || _a === void 0 ? void 0 : _a.watchDirectory) !== null && _b !== void 0 ? _b : "build");
const watchDir = fs_1.default.existsSync(buildDir) ? buildDir : absoluteBaseDir;
const watcher = hmr_1.default(watchDir, () => {
var _a;
try {
// Update the version number in order to force a new instance to be initialized
const oldVersions = this.appletVersions.get();
this.appletVersions.set({
...oldVersions,
[source.ID]: ((_a = oldVersions[source.ID]) !== null && _a !== void 0 ? _a : 0) + 1,
});
console.log(`%cApplet %c${source.ID} %chas been reloaded`, "color: blue;", "color: green;", "color: blue;");
}
catch (e) {
console.error(e);
}
});
return watcher;
}
}
exports.AppletManager = AppletManager;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBwbGV0TWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcHBsaWNhdGlvbi9hcHBsZXRzL0FwcGxldE1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVEQUFzRTtBQUN0RSw2Q0FBeUQ7QUFHekQsZ0RBQXdCO0FBQ3hCLDRDQUFvQjtBQUlwQiw2RUFBd0U7QUFDeEUsaURBQTRDO0FBQzVDLHdFQUFtRTtBQWNuRTs7R0FFRztBQUNILE1BQWEsYUFBYTtJQWN0Qjs7Ozs7T0FLRztJQUNILFlBQ0ksRUFBYyxFQUNkLGNBQStCLEVBQy9CLGtCQUEyQixFQUFFLENBQUMsV0FBVyxFQUFFO1FBbEJyQyxjQUFTLEdBQUcsSUFBSSxtQkFBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBR3ZDLG9IQUFvSDtRQUM3RyxpQkFBWSxHQUFHLElBQUksbUJBQUssQ0FBQyxFQUFtQixDQUFDLENBQUMsQ0FBQyx5REFBeUQ7UUFFL0csK0ZBQStGO1FBQ3JGLG1CQUFjLEdBQUcsSUFBSSxtQkFBSyxDQUFDLEVBQTRCLENBQUMsQ0FBQztRQXlLbkU7O1dBRUc7UUFDTyxZQUFPLEdBQUcsSUFBSSx3QkFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ25DLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdDLElBQUksYUFBYSxZQUFZLE1BQU0sSUFBSSxDQUFDLENBQUMsYUFBYSxZQUFZLEtBQUssQ0FBQyxFQUFFO2dCQUN0RSxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRTtvQkFDMUQsTUFBTSxJQUFJLEdBQUcsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUMvQixJQUFJLE9BQU8sSUFBSSxJQUFJLFFBQVE7d0JBQUUs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