mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-04 12:49:03 +00:00
feat(desktop): use sqlite3 db
should fix the occasional db resets on concurrent read/write ops experienced with the json db
This commit is contained in:
parent
73e3c7c3a9
commit
44702af188
31
bin.mjs
31
bin.mjs
@ -13,14 +13,14 @@ import { createRequire } from "node:module";
|
||||
import {
|
||||
getAppPath,
|
||||
getBackupPath,
|
||||
getCachePath,
|
||||
getConfigPath,
|
||||
checkEnhancementVersion,
|
||||
setNotionPath,
|
||||
unpackApp,
|
||||
applyEnhancements,
|
||||
takeBackup,
|
||||
restoreBackup,
|
||||
removeCache,
|
||||
removeConfig,
|
||||
} from "./scripts/enhance-desktop-app.mjs";
|
||||
import { existsSync } from "node:fs";
|
||||
const nodeRequire = createRequire(import.meta.url),
|
||||
@ -201,7 +201,7 @@ try {
|
||||
|
||||
const appPath = getAppPath(),
|
||||
backupPath = getBackupPath(),
|
||||
cachePath = getCachePath(),
|
||||
configPath = getConfigPath(),
|
||||
insertVersion = checkEnhancementVersion();
|
||||
|
||||
const messages = {
|
||||
@ -223,9 +223,9 @@ try {
|
||||
then install a vanilla version of the app from https://www.notion.so/desktop (mac,
|
||||
windows) or ${manifest.homepage}/getting-started/installation (linux)`,
|
||||
|
||||
"cache-found": `cache found`,
|
||||
"cache-not-found": `cache not found: nothing to remove`,
|
||||
"prompt-cache-removal": `remove?`,
|
||||
"config-found": `config found`,
|
||||
"config-not-found": `config not found: nothing to remove`,
|
||||
"prompt-config-removal": `remove?`,
|
||||
};
|
||||
const SUCCESS = chalk`{bold.whiteBright SUCCESS} {green ✔}`,
|
||||
FAILURE = chalk`{bold.whiteBright FAILURE} {red ✘}`,
|
||||
@ -309,17 +309,16 @@ try {
|
||||
print` {grey * ${messages["notion-found"]}: ${messages["not-applied"]}}\n`;
|
||||
return SUCCESS;
|
||||
},
|
||||
promptCacheRemoval = async () => {
|
||||
// optionally remove ~/.notion-enhancer
|
||||
if (existsSync(cachePath)) {
|
||||
print` {grey * ${messages["cache-found"]}: ${cachePath}}\n`;
|
||||
if (["Y", "y"].includes(await promptConfirmation(messages["prompt-cache-removal"]))) {
|
||||
promptConfigRemoval = async () => {
|
||||
if (existsSync(configPath)) {
|
||||
print` {grey * ${messages["config-found"]}: ${configPath}}\n`;
|
||||
if (["Y", "y"].includes(await promptConfirmation(messages["prompt-config-removal"]))) {
|
||||
print` `;
|
||||
startSpinner();
|
||||
await removeCache();
|
||||
await removeConfig();
|
||||
stopSpinner();
|
||||
} else print`\n`;
|
||||
} else print` {grey * ${messages["cache-not-found"]}}\n`;
|
||||
} else print` {grey * ${messages["config-not-found"]}}\n`;
|
||||
};
|
||||
|
||||
switch (args["_"][0]) {
|
||||
@ -333,7 +332,7 @@ try {
|
||||
case "remove": {
|
||||
print`{bold.whiteBright [NOTION-ENHANCER] REMOVE}\n`;
|
||||
const res = await interactiveRemoveEnhancements();
|
||||
await promptCacheRemoval();
|
||||
await promptConfigRemoval();
|
||||
print`${res}\n`;
|
||||
break;
|
||||
}
|
||||
@ -342,8 +341,8 @@ try {
|
||||
printObject({
|
||||
appPath,
|
||||
backupPath,
|
||||
cachePath,
|
||||
cacheExists: existsSync(cachePath),
|
||||
configPath,
|
||||
configExists: existsSync(configPath),
|
||||
insertVersion,
|
||||
currentVersion: manifest.version,
|
||||
});
|
||||
|
@ -15,7 +15,7 @@ import { createRequire } from "node:module";
|
||||
|
||||
import patch from "./patch-desktop-app.mjs";
|
||||
|
||||
let __notionResources, __enhancerCache;
|
||||
let __notionResources, __enhancerConfig;
|
||||
const nodeRequire = createRequire(import.meta.url),
|
||||
manifest = nodeRequire("../package.json"),
|
||||
platform =
|
||||
@ -89,11 +89,11 @@ const setNotionPath = (path) => {
|
||||
// prefer unpacked if both exist
|
||||
getAppPath = () => ["app", "app.asar"].map(getResourcePath).find(existsSync),
|
||||
getBackupPath = () => ["app.bak", "app.asar.bak"].map(getResourcePath).find(existsSync),
|
||||
getCachePath = () => {
|
||||
if (__enhancerCache) return __enhancerCache;
|
||||
getConfigPath = () => {
|
||||
if (__enhancerConfig) return __enhancerConfig;
|
||||
const home = platform === "wsl" ? polyfillWslEnv("HOMEPATH") : os.homedir();
|
||||
__enhancerCache = resolve(`${home}/.notion-enhancer`);
|
||||
return __enhancerCache;
|
||||
__enhancerConfig = resolve(`${home}/.notion-enhancer.db`);
|
||||
return __enhancerConfig;
|
||||
},
|
||||
checkEnhancementVersion = () => {
|
||||
const manifestPath = getResourcePath("app/node_modules/notion-enhancer/package.json");
|
||||
@ -172,9 +172,9 @@ const unpackApp = async () => {
|
||||
if (destPath !== appPath) await fsp.rm(appPath, { recursive: true });
|
||||
return true;
|
||||
},
|
||||
removeCache = async () => {
|
||||
if (!existsSync(getCachePath())) return;
|
||||
await fsp.rm(getCachePath());
|
||||
removeConfig = async () => {
|
||||
if (!existsSync(getConfigPath())) return;
|
||||
await fsp.rm(getConfigPath());
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -182,12 +182,12 @@ export {
|
||||
getResourcePath,
|
||||
getAppPath,
|
||||
getBackupPath,
|
||||
getCachePath,
|
||||
getConfigPath,
|
||||
checkEnhancementVersion,
|
||||
setNotionPath,
|
||||
unpackApp,
|
||||
applyEnhancements,
|
||||
takeBackup,
|
||||
restoreBackup,
|
||||
removeCache,
|
||||
removeConfig,
|
||||
};
|
||||
|
@ -1,169 +0,0 @@
|
||||
/**
|
||||
* notion-enhancer
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const os = require('os'),
|
||||
path = require('path'),
|
||||
fs = require('fs'),
|
||||
_cacheFile = path.resolve(`${os.homedir()}/.notion-enhancer`),
|
||||
_fsQueue = new Set(),
|
||||
_onDbChangeListeners = [];
|
||||
|
||||
// handle leftover cache from prev versions
|
||||
if (fs.existsSync(_cacheFile) && fs.lstatSync(_cacheFile).isDirectory()) {
|
||||
fs.rmdirSync(_cacheFile);
|
||||
}
|
||||
|
||||
const isRenderer = process && process.type === 'renderer';
|
||||
|
||||
// things are a little weird here:
|
||||
// multiple processes performing file ops at once
|
||||
// (e.g. when too many windows/tabs are open)
|
||||
// = an empty string is returned the cache contents
|
||||
// and the db is reset. this loop roughly addresses that.
|
||||
|
||||
// a "real" db might be better, but sql or query-based
|
||||
// would be incompatible with the chrome ext.
|
||||
// -- lowdb might have been a nice flat/json db,
|
||||
// but unfortunately it is esm only
|
||||
|
||||
const getData = async () => {
|
||||
if (!fs.existsSync(_cacheFile)) {
|
||||
fs.writeFileSync(_cacheFile, '{}', 'utf8');
|
||||
return {};
|
||||
}
|
||||
|
||||
let cacheBuffer = '',
|
||||
jsonData = {},
|
||||
attemptsRemaining = 3;
|
||||
while (attemptsRemaining) {
|
||||
cacheBuffer = fs.readFileSync(_cacheFile);
|
||||
if (cacheBuffer) {
|
||||
try {
|
||||
jsonData = JSON.parse(cacheBuffer);
|
||||
break;
|
||||
} catch {
|
||||
jsonData = {};
|
||||
}
|
||||
}
|
||||
--attemptsRemaining || (await new Promise((res, rej) => setTimeout(res, 50)));
|
||||
}
|
||||
return jsonData;
|
||||
},
|
||||
saveData = (data) => fs.writeFileSync(_cacheFile, JSON.stringify(data)),
|
||||
performFsOperation = async (callback) => {
|
||||
while (_fsQueue.size) await new Promise(requestIdleCallback);
|
||||
const op = Symbol();
|
||||
_fsQueue.add(op);
|
||||
const res = await callback();
|
||||
_fsQueue.delete(op);
|
||||
return res;
|
||||
};
|
||||
|
||||
const db = {
|
||||
get: async (path, fallback = undefined) => {
|
||||
if (!path.length) return fallback;
|
||||
while (_fsQueue.size) await new Promise(requestIdleCallback);
|
||||
const values = await getData();
|
||||
let value = values;
|
||||
while (path.length) {
|
||||
if (value === undefined) {
|
||||
value = fallback;
|
||||
break;
|
||||
}
|
||||
value = value[path.shift()];
|
||||
}
|
||||
return value ?? fallback;
|
||||
},
|
||||
set: async (path, value) => {
|
||||
if (!path.length) return undefined;
|
||||
return await performFsOperation(async () => {
|
||||
const pathClone = [...path],
|
||||
values = await getData();
|
||||
let pointer = values,
|
||||
old;
|
||||
while (path.length) {
|
||||
const key = path.shift();
|
||||
if (!path.length) {
|
||||
old = pointer[key];
|
||||
pointer[key] = value;
|
||||
break;
|
||||
}
|
||||
pointer[key] = pointer[key] ?? {};
|
||||
pointer = pointer[key];
|
||||
}
|
||||
saveData(values);
|
||||
_onDbChangeListeners.forEach((listener) =>
|
||||
listener({ path: pathClone, new: value, old })
|
||||
);
|
||||
return value;
|
||||
});
|
||||
},
|
||||
addChangeListener: (callback) => {
|
||||
_onDbChangeListeners.push(callback);
|
||||
},
|
||||
removeChangeListener: (callback) => {
|
||||
_onDbChangeListeners = _onDbChangeListeners.filter((listener) => listener !== callback);
|
||||
},
|
||||
};
|
||||
|
||||
const ipcRenderer = {
|
||||
sendMessage: (channel, data = undefined, namespace = 'notion-enhancer') => {
|
||||
const { ipcRenderer } = require('electron');
|
||||
channel = namespace ? `${namespace}:${channel}` : channel;
|
||||
ipcRenderer.send(channel, data);
|
||||
},
|
||||
sendMessageToHost: (channel, data = undefined, namespace = 'notion-enhancer') => {
|
||||
const { ipcRenderer } = require('electron');
|
||||
channel = namespace ? `${namespace}:${channel}` : channel;
|
||||
ipcRenderer.sendToHost(channel, data);
|
||||
},
|
||||
onMessage: (channel, callback, namespace = 'notion-enhancer') => {
|
||||
const { ipcRenderer } = require('electron');
|
||||
channel = namespace ? `${namespace}:${channel}` : channel;
|
||||
ipcRenderer.on(channel, callback);
|
||||
},
|
||||
};
|
||||
|
||||
globalThis.__enhancerElectronApi = {
|
||||
platform: process.platform,
|
||||
version: require('notion-enhancer/package.json').version,
|
||||
db,
|
||||
|
||||
browser: isRenderer ? require('electron').remote.getCurrentWindow() : {},
|
||||
webFrame: isRenderer ? require('electron').webFrame : {},
|
||||
notionRequire: (path) => require(`../../${path}`),
|
||||
notionPath: (path) => require('path').resolve(`${__dirname}/../../${path}`),
|
||||
nodeRequire: (path) => require(path),
|
||||
|
||||
focusMenu: () => {
|
||||
if (isRenderer) return ipcRenderer.sendMessage('focusMenu');
|
||||
const { focusMenu } = require('notion-enhancer/worker.cjs');
|
||||
return focusMenu();
|
||||
},
|
||||
focusNotion: () => {
|
||||
if (isRenderer) return ipcRenderer.sendMessage('focusNotion');
|
||||
const { focusNotion } = require('notion-enhancer/worker.cjs');
|
||||
return focusNotion();
|
||||
},
|
||||
reload: () => {
|
||||
if (isRenderer) return ipcRenderer.sendMessage('reload');
|
||||
const { reload } = require('notion-enhancer/worker.cjs');
|
||||
return reload();
|
||||
},
|
||||
|
||||
getNotionWindows: () => {
|
||||
const { getNotionWindows } = require('notion-enhancer/worker.cjs');
|
||||
return getNotionWindows();
|
||||
},
|
||||
getFocusedNotionWindow: () => {
|
||||
const { getFocusedNotionWindow } = require('notion-enhancer/worker.cjs');
|
||||
return getFocusedNotionWindow();
|
||||
},
|
||||
|
||||
ipcRenderer,
|
||||
};
|
41
src/electron/env/env.mjs
vendored
41
src/electron/env/env.mjs
vendored
@ -1,41 +0,0 @@
|
||||
/**
|
||||
* notion-enhancer: api
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/** environment-specific methods and constants */
|
||||
|
||||
/**
|
||||
* the environment/platform name code is currently being executed in
|
||||
* @constant
|
||||
* @type {string}
|
||||
*/
|
||||
export const name = globalThis.__enhancerElectronApi.platform;
|
||||
|
||||
/**
|
||||
* the current version of the enhancer
|
||||
* @constant
|
||||
* @type {string}
|
||||
*/
|
||||
export const version = globalThis.__enhancerElectronApi.version;
|
||||
|
||||
/**
|
||||
* open the enhancer's menu
|
||||
* @type {function}
|
||||
*/
|
||||
export const focusMenu = globalThis.__enhancerElectronApi.focusMenu;
|
||||
|
||||
/**
|
||||
* focus an active notion tab
|
||||
* @type {function}
|
||||
*/
|
||||
export const focusNotion = globalThis.__enhancerElectronApi.focusNotion;
|
||||
|
||||
/**
|
||||
* reload all notion and enhancer menu tabs to apply changes
|
||||
* @type {function}
|
||||
*/
|
||||
export const reload = globalThis.__enhancerElectronApi.reload;
|
81
src/electron/env/fs.mjs
vendored
81
src/electron/env/fs.mjs
vendored
@ -1,81 +0,0 @@
|
||||
/**
|
||||
* notion-enhancer: api
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/** environment-specific file reading */
|
||||
|
||||
/**
|
||||
* get an absolute path to files within notion
|
||||
* @param {string} path - relative to the root notion/resources/app/ e.g. renderer/search.js
|
||||
* @process electron
|
||||
*/
|
||||
export const notionPath = globalThis.__enhancerElectronApi.notionPath;
|
||||
|
||||
/**
|
||||
* transform a path relative to the enhancer root directory into an absolute path
|
||||
* @param {string} path - a url or within-the-enhancer filepath
|
||||
* @returns {string} an absolute filepath
|
||||
*/
|
||||
export const localPath = (path) => `notion://www.notion.so/__notion-enhancer/${path}`;
|
||||
|
||||
/**
|
||||
* fetch and parse a json file's contents
|
||||
* @param {string} path - a url or within-the-enhancer filepath
|
||||
* @param {object=} opts - the second argument of a fetch() request
|
||||
* @returns {object} the json value of the requested file as a js object
|
||||
*/
|
||||
export const getJSON = (path, opts = {}) => {
|
||||
path = path.replace(/^https:\/\/www\.notion\.so\//, 'notion://www.notion.so/');
|
||||
const networkPath = path.startsWith('http') || path.startsWith('notion://');
|
||||
if (networkPath) return fetch(path, opts).then((res) => res.json());
|
||||
try {
|
||||
return globalThis.__enhancerElectronApi.nodeRequire(`notion-enhancer/${path}`);
|
||||
} catch {
|
||||
return fetch(localPath(path), opts).then((res) => res.json());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* fetch a text file's contents
|
||||
* @param {string} path - a url or within-the-enhancer filepath
|
||||
* @param {object=} opts - the second argument of a fetch() request
|
||||
* @returns {string} the text content of the requested file
|
||||
*/
|
||||
export const getText = (path, opts = {}) => {
|
||||
path = path.replace(/^https:\/\/www\.notion\.so\//, 'notion://www.notion.so/');
|
||||
const networkPath = path.startsWith('http') || path.startsWith('notion://');
|
||||
if (networkPath) return fetch(path, opts).then((res) => res.text());
|
||||
try {
|
||||
const fs = globalThis.__enhancerElectronApi.nodeRequire('fs');
|
||||
return fs.readFileSync(notionPath(`notion-enhancer/${path}`));
|
||||
} catch {
|
||||
return fetch(localPath(path), opts).then((res) => res.text());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* check if a file exists
|
||||
* @param {string} path - a url or within-the-enhancer filepath
|
||||
* @returns {boolean} whether or not the file exists
|
||||
*/
|
||||
export const isFile = async (path) => {
|
||||
try {
|
||||
const fs = globalThis.__enhancerElectronApi.nodeRequire('fs');
|
||||
if (path.startsWith('http')) {
|
||||
await fetch(path);
|
||||
} else {
|
||||
try {
|
||||
fs.existsSync(notionPath(`notion-enhancer/${path}`));
|
||||
} catch {
|
||||
await fetch(localPath(path));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
69
src/electron/env/storage.mjs
vendored
69
src/electron/env/storage.mjs
vendored
@ -1,69 +0,0 @@
|
||||
/**
|
||||
* notion-enhancer: api
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/** environment-specific data persistence */
|
||||
|
||||
/**
|
||||
* get persisted data
|
||||
* @param {string[]} path - the path of keys to the value being fetched
|
||||
* @param {unknown=} fallback - a default value if the path is not matched
|
||||
* @returns {Promise} value ?? fallback
|
||||
*/
|
||||
export const get = (path, fallback = undefined) => {
|
||||
return globalThis.__enhancerElectronApi.db.get(path, fallback);
|
||||
};
|
||||
|
||||
/**
|
||||
* persist data
|
||||
* @param {string[]} path - the path of keys to the value being set
|
||||
* @param {unknown} value - the data to save
|
||||
* @returns {Promise} resolves when data has been saved
|
||||
*/
|
||||
export const set = (path, value) => {
|
||||
return globalThis.__enhancerElectronApi.db.set(path, value);
|
||||
};
|
||||
|
||||
/**
|
||||
* create a wrapper for accessing a partition of the storage
|
||||
* @param {string[]} namespace - the path of keys to prefix all storage requests with
|
||||
* @param {function=} get - the storage get function to be wrapped
|
||||
* @param {function=} set - the storage set function to be wrapped
|
||||
* @returns {object} an object with the wrapped get/set functions
|
||||
*/
|
||||
export const db = (namespace, getFunc = get, setFunc = set) => {
|
||||
if (typeof namespace === 'string') namespace = [namespace];
|
||||
return {
|
||||
get: (path = [], fallback = undefined) => getFunc([...namespace, ...path], fallback),
|
||||
set: (path, value) => setFunc([...namespace, ...path], value),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* add an event listener for changes in storage
|
||||
* @param {onStorageChangeCallback} callback - called whenever a change in
|
||||
* storage is initiated from the current process
|
||||
*/
|
||||
export const addChangeListener = (callback) => {
|
||||
return globalThis.__enhancerElectronApi.db.addChangeListener(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* remove a listener added with storage.addChangeListener
|
||||
* @param {onStorageChangeCallback} callback
|
||||
*/
|
||||
export const removeChangeListener = (callback) => {
|
||||
return globalThis.__enhancerElectronApi.db.removeChangeListener(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* @callback onStorageChangeCallback
|
||||
* @param {object} event
|
||||
* @param {string} event.path- the path of keys to the changed value
|
||||
* @param {string=} event.new - the new value being persisted to the store
|
||||
* @param {string=} event.old - the previous value associated with the key
|
||||
*/
|
@ -1,28 +0,0 @@
|
||||
/**
|
||||
* notion-enhancer
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(async () => {
|
||||
const api = await import('./api/index.mjs'),
|
||||
{ fs, registry, web } = api;
|
||||
|
||||
for (const mod of await registry.list((mod) => registry.enabled(mod.id))) {
|
||||
for (const sheet of mod.css?.frame || []) {
|
||||
web.loadStylesheet(`repo/${mod._dir}/${sheet}`);
|
||||
}
|
||||
for (let script of mod.js?.frame || []) {
|
||||
script = await import(fs.localPath(`repo/${mod._dir}/${script}`));
|
||||
script.default(api, await registry.db(mod.id));
|
||||
}
|
||||
|
||||
const errors = await registry.errors();
|
||||
if (errors.length) {
|
||||
console.error('[notion-enhancer] registry errors:');
|
||||
console.table(errors);
|
||||
}
|
||||
}
|
||||
})();
|
@ -1,46 +1,50 @@
|
||||
/**
|
||||
* notion-enhancer
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (c) 2022 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
module.exports = async function (target, __exports, __eval) {
|
||||
require("notion-enhancer/electronApi.cjs");
|
||||
const api = require("notion-enhancer/api/index.cjs"),
|
||||
{ registry } = api;
|
||||
module.exports = async (target, __exports, __eval) => {
|
||||
// if (target === "renderer/preload") {
|
||||
const { initDatabase } = require("./node.cjs");
|
||||
|
||||
if (target === "renderer/index") {
|
||||
document.addEventListener("readystatechange", (event) => {
|
||||
if (document.readyState !== "complete") return false;
|
||||
const script = document.createElement("script");
|
||||
script.type = "module";
|
||||
script.src = api.fs.localPath("frame.mjs");
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
// require("notion-enhancer/electronApi.cjs");
|
||||
// const api = require("notion-enhancer/api/index.cjs"),
|
||||
// { registry } = api;
|
||||
|
||||
if (target === "renderer/preload") {
|
||||
document.addEventListener("readystatechange", (event) => {
|
||||
if (document.readyState !== "complete") return false;
|
||||
const script = document.createElement("script");
|
||||
script.type = "module";
|
||||
script.src = api.fs.localPath("client.mjs");
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
// if (target === "renderer/index") {
|
||||
// document.addEventListener("readystatechange", (event) => {
|
||||
// if (document.readyState !== "complete") return false;
|
||||
// const script = document.createElement("script");
|
||||
// script.type = "module";
|
||||
// script.src = api.fs.localPath("frame.mjs");
|
||||
// document.head.appendChild(script);
|
||||
// });
|
||||
// }
|
||||
|
||||
if (target === "main/main") {
|
||||
const { app } = require("electron");
|
||||
app.whenReady().then(require("notion-enhancer/worker.cjs").listen);
|
||||
}
|
||||
// if (target === "renderer/preload") {
|
||||
const db = initDatabase("config");
|
||||
// document.addEventListener("readystatechange", (event) => {
|
||||
// if (document.readyState !== "complete") return false;
|
||||
// const script = document.createElement("script");
|
||||
// script.type = "module";
|
||||
// script.src = api.fs.localPath("client.mjs");
|
||||
// document.head.appendChild(script);
|
||||
// });
|
||||
// }
|
||||
|
||||
for (const mod of await registry.list((mod) => registry.enabled(mod.id))) {
|
||||
for (const { source, target: scriptTarget } of (mod.js ? mod.js.electron : []) || []) {
|
||||
if (`${target}.js` !== scriptTarget) continue;
|
||||
const script = require(`notion-enhancer/repo/${mod._dir}/${source}`);
|
||||
script(api, await registry.db(mod.id), __exports, __eval);
|
||||
}
|
||||
}
|
||||
// if (target === "main/main") {
|
||||
// const { app } = require("electron");
|
||||
// app.whenReady().then(require("notion-enhancer/worker.cjs").listen);
|
||||
// }
|
||||
|
||||
// for (const mod of await registry.list((mod) => registry.enabled(mod.id))) {
|
||||
// for (const { source, target: scriptTarget } of (mod.js ? mod.js.electron : []) || []) {
|
||||
// if (`${target}.js` !== scriptTarget) continue;
|
||||
// const script = require(`notion-enhancer/repo/${mod._dir}/${source}`);
|
||||
// script(api, await registry.db(mod.id), __exports, __eval);
|
||||
// }
|
||||
// }
|
||||
};
|
||||
|
67
src/electron/node.cjs
Normal file
67
src/electron/node.cjs
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* notion-enhancer
|
||||
* (c) 2022 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const os = require("os"),
|
||||
path = require("path"),
|
||||
electron = require("electron"),
|
||||
sqlite = require("better-sqlite3");
|
||||
|
||||
const notionRequire = (target) => require(`../../../${target}`),
|
||||
notionPath = (target) => path.resolve(`${__dirname}/../../../${target}`),
|
||||
notionPlatform = process.platform;
|
||||
|
||||
const enhancerRequire = (target) => require(`../${target}`),
|
||||
enhancerPath = (target) => path.resolve(`${__dirname}/../${target}`),
|
||||
enhancerUrl = (target) => `notion://www.notion.so/__notion-enhancer/${target}`,
|
||||
enhancerVersion = enhancerRequire("package.json").version,
|
||||
enhancerConfig = path.resolve(`${os.homedir()}/.notion-enhancer.db`);
|
||||
|
||||
const reloadApp = () => {
|
||||
const args = process.argv.slice(1).filter((arg) => arg !== "--startup");
|
||||
electron.app.relaunch({ args });
|
||||
electron.app.exit();
|
||||
};
|
||||
|
||||
let __db;
|
||||
const initDatabase = (table) => {
|
||||
const db = __db ?? sqlite(enhancerConfig),
|
||||
init = db.prepare(`CREATE TABLE IF NOT EXISTS ${table} (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT,
|
||||
mtime INTEGER
|
||||
)`);
|
||||
init.run();
|
||||
__db = db;
|
||||
|
||||
const insert = db.prepare(`INSERT INTO ${table} (key, value, mtime) VALUES (?, ?, ?)`),
|
||||
update = db.prepare(`UPDATE ${table} SET value = ?, mtime = ? WHERE key = ?`),
|
||||
select = db.prepare(`SELECT * FROM ${table} WHERE key = ? LIMIT 1`),
|
||||
dump = db.prepare(`SELECT * FROM ${table}`);
|
||||
|
||||
return {
|
||||
get: (key) => select.get(key)?.value,
|
||||
set: (key, value) => {
|
||||
if (select.get(key)) return update.run(value, key, Date.now());
|
||||
else return insert.run(key, value, Date.now());
|
||||
},
|
||||
dump: () => dump.all(),
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
notionRequire,
|
||||
notionPath,
|
||||
notionPlatform,
|
||||
enhancerRequire,
|
||||
enhancerPath,
|
||||
enhancerUrl,
|
||||
enhancerVersion,
|
||||
enhancerConfig,
|
||||
reloadApp,
|
||||
initDatabase,
|
||||
};
|
29
src/mods/.github/workflows/update-parents.yml
vendored
29
src/mods/.github/workflows/update-parents.yml
vendored
@ -1,29 +0,0 @@
|
||||
name: 'update parent repositories'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
name: update parent
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
repo: ['notion-enhancer/extension', 'notion-enhancer/desktop']
|
||||
steps:
|
||||
- name: checkout repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.CI_TOKEN }}
|
||||
submodules: true
|
||||
repository: ${{ matrix.repo }}
|
||||
- name: pull updates
|
||||
run: |
|
||||
git pull --recurse-submodules
|
||||
git submodule update --remote --recursive
|
||||
- name: commit changes
|
||||
uses: stefanzweifel/git-auto-commit-action@v4
|
||||
with:
|
||||
commit_message: '[${{ github.event.repository.name }}] ${{ github.event.head_commit.message }}'
|
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,5 +0,0 @@
|
||||
# notion-enhancer/repo
|
||||
|
||||
the collection of mods run by the notion-enhancer
|
||||
|
||||
[read the docs online](https://notion-enhancer.github.io/getting-started/features)
|
Loading…
Reference in New Issue
Block a user