mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-08 06:29:03 +00:00
chore: ensure api is loaded before mod scripts execute
This commit is contained in:
parent
1f717b98ca
commit
ef09280f61
@ -37,11 +37,6 @@ const dependencies = {
|
|||||||
version: "0.58.5",
|
version: "0.58.5",
|
||||||
exports: ["presetUno"],
|
exports: ["presetUno"],
|
||||||
}),
|
}),
|
||||||
...esmBundle({
|
|
||||||
name: "@unocss/preset-icons",
|
|
||||||
version: "0.58.5",
|
|
||||||
exports: ["presetIcons"],
|
|
||||||
}),
|
|
||||||
"@unocss-preflight-tailwind.css":
|
"@unocss-preflight-tailwind.css":
|
||||||
"https://esm.sh/@unocss/reset@0.58.5/tailwind.css",
|
"https://esm.sh/@unocss/reset@0.58.5/tailwind.css",
|
||||||
"coloris.min.js":
|
"coloris.min.js":
|
||||||
|
@ -37,29 +37,29 @@ const sleep = async (ms) => {
|
|||||||
// supports inter-mod communication if so
|
// supports inter-mod communication if so
|
||||||
// required. caution should be used in
|
// required. caution should be used in
|
||||||
// naming keys to avoid conflicts
|
// naming keys to avoid conflicts
|
||||||
const _state = {},
|
const _subscribers = [],
|
||||||
_subscribers = [],
|
dumpState = () => (document.__enhancerState ??= {}),
|
||||||
|
getKeysFromState = (keys) => keys.map((key) => dumpState()[key]),
|
||||||
setState = (state) => {
|
setState = (state) => {
|
||||||
Object.assign(_state, state);
|
Object.assign(dumpState(), state);
|
||||||
const updates = Object.keys(state);
|
const updates = Object.keys(state);
|
||||||
_subscribers
|
_subscribers
|
||||||
.filter(([keys]) => updates.some((key) => keys.includes(key)))
|
.filter(([keys]) => updates.some((key) => keys.includes(key)))
|
||||||
.forEach(([keys, callback]) => callback(keys.map((key) => _state[key])));
|
.forEach(([keys, callback]) => callback(getKeysFromState(keys)));
|
||||||
},
|
},
|
||||||
// useState(["keyA", "keyB"]) => returns [valueA, valueB]
|
// useState(["keyA", "keyB"]) => returns [valueA, valueB]
|
||||||
// useState(["keyA", "keyB"], callback) => registers callback
|
// useState(["keyA", "keyB"], callback) => registers callback
|
||||||
// to be triggered after each update to either keyA or keyB,
|
// to be triggered after each update to either keyA or keyB,
|
||||||
// with [valueA, valueB] passed to the callback's first arg
|
// with [valueA, valueB] passed to the callback's first arg
|
||||||
useState = (keys, callback) => {
|
useState = (keys, callback) => {
|
||||||
const state = keys.map((key) => _state[key]);
|
const state = getKeysFromState(keys);
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback = debounce(callback);
|
callback = debounce(callback);
|
||||||
_subscribers.push([keys, callback]);
|
_subscribers.push([keys, callback]);
|
||||||
callback(state);
|
callback(state);
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
},
|
};
|
||||||
dumpState = () => _state;
|
|
||||||
|
|
||||||
Object.assign((globalThis.__enhancerApi ??= {}), {
|
Object.assign((globalThis.__enhancerApi ??= {}), {
|
||||||
sleep,
|
sleep,
|
||||||
|
@ -7,11 +7,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const IS_ELECTRON = typeof module !== "undefined",
|
const IS_ELECTRON = typeof module !== "undefined",
|
||||||
IS_RENDERER = IS_ELECTRON && process.type === "renderer",
|
IS_RENDERER = IS_ELECTRON && process.type === "renderer";
|
||||||
API_LOADED = new Promise((res, rej) => {
|
|
||||||
(globalThis.__enhancerApi ??= {}).__isReady = res;
|
|
||||||
}),
|
|
||||||
whenReady = (callback) => API_LOADED.then(callback);
|
|
||||||
|
|
||||||
// expected values: 'linux', 'win32', 'darwin' (== macos), 'firefox'
|
// expected values: 'linux', 'win32', 'darwin' (== macos), 'firefox'
|
||||||
// and 'chromium' (inc. chromium-based browsers like edge and brave)
|
// and 'chromium' (inc. chromium-based browsers like edge and brave)
|
||||||
@ -160,5 +156,4 @@ Object.assign((globalThis.__enhancerApi ??= {}), {
|
|||||||
readJson,
|
readJson,
|
||||||
initDatabase,
|
initDatabase,
|
||||||
reloadApp,
|
reloadApp,
|
||||||
whenReady,
|
|
||||||
});
|
});
|
||||||
|
@ -6,9 +6,8 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
module.exports = async ({ whenReady }, db) => {
|
module.exports = async (api, db) => {
|
||||||
const api = await whenReady(),
|
const { html, addMutationListener } = api,
|
||||||
{ html, addMutationListener } = api,
|
|
||||||
{ enhancerUrl, onMessage, sendMessage } = api,
|
{ enhancerUrl, onMessage, sendMessage } = api,
|
||||||
titlebarStyle = await db.get("titlebarStyle");
|
titlebarStyle = await db.get("titlebarStyle");
|
||||||
|
|
||||||
|
15
src/init.js
15
src/init.js
@ -16,16 +16,21 @@ const isElectron = () => {
|
|||||||
if (isElectron()) {
|
if (isElectron()) {
|
||||||
require("./api/system.js");
|
require("./api/system.js");
|
||||||
require("./api/registry.js");
|
require("./api/registry.js");
|
||||||
|
|
||||||
const { enhancerUrl } = globalThis.__enhancerApi,
|
const { enhancerUrl } = globalThis.__enhancerApi,
|
||||||
{ getMods, isEnabled, modDatabase } = globalThis.__enhancerApi;
|
{ getMods, isEnabled, modDatabase } = globalThis.__enhancerApi,
|
||||||
|
API_LOADED = new Promise((res, rej) => {
|
||||||
|
const onReady = globalThis.__enhancerReady;
|
||||||
|
globalThis.__enhancerReady = () => (onReady?.(), res());
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = async (target, __exports, __eval) => {
|
module.exports = async (target, __exports, __eval) => {
|
||||||
|
const __getApi = () => globalThis.__enhancerApi;
|
||||||
if (target === ".webpack/main/index") require("./worker.js");
|
if (target === ".webpack/main/index") require("./worker.js");
|
||||||
else {
|
else {
|
||||||
// expose globalThis.__enhancerApi to scripts
|
// expose globalThis.__enhancerApi to scripts
|
||||||
const { contextBridge } = require("electron"),
|
const { contextBridge } = require("electron");
|
||||||
__getEnhancerApi = () => globalThis.__enhancerApi;
|
contextBridge.exposeInMainWorld("__getEnhancerApi", __getApi);
|
||||||
contextBridge.exposeInMainWorld("__getEnhancerApi", __getEnhancerApi);
|
|
||||||
|
|
||||||
// load clientStyles, clientScripts
|
// load clientStyles, clientScripts
|
||||||
document.addEventListener("readystatechange", () => {
|
document.addEventListener("readystatechange", () => {
|
||||||
@ -44,7 +49,7 @@ if (isElectron()) {
|
|||||||
for (let [scriptTarget, script] of mod.electronScripts ?? []) {
|
for (let [scriptTarget, script] of mod.electronScripts ?? []) {
|
||||||
if (target !== scriptTarget) continue;
|
if (target !== scriptTarget) continue;
|
||||||
script = require(`./${mod._src}/${script}`);
|
script = require(`./${mod._src}/${script}`);
|
||||||
script(globalThis.__enhancerApi, db, __exports, __eval);
|
API_LOADED.then(() => script(__getApi(), db, __exports, __eval));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
30
src/load.mjs
30
src/load.mjs
@ -17,8 +17,12 @@ export default (async () => {
|
|||||||
pageLoaded = /(^\/$)|((-|\/)[0-9a-f]{32}((\?.+)|$))/.test(location.pathname),
|
pageLoaded = /(^\/$)|((-|\/)[0-9a-f]{32}((\?.+)|$))/.test(location.pathname),
|
||||||
IS_MENU = location.href.startsWith(enhancerUrl("core/menu/index.html")),
|
IS_MENU = location.href.startsWith(enhancerUrl("core/menu/index.html")),
|
||||||
IS_TABS = /\/app\/\.webpack\/renderer\/(draggable_)?tabs\/index.html$/.test(location.href),
|
IS_TABS = /\/app\/\.webpack\/renderer\/(draggable_)?tabs\/index.html$/.test(location.href),
|
||||||
IS_ELECTRON = ['linux', 'win32', 'darwin'].includes(platform);
|
IS_ELECTRON = ['linux', 'win32', 'darwin'].includes(platform),
|
||||||
if (IS_TABS) globalThis.IS_TABS = true;
|
API_LOADED = new Promise((res, rej) => {
|
||||||
|
const onReady = globalThis.__enhancerReady;
|
||||||
|
globalThis.__enhancerReady = () => (onReady?.(), res());
|
||||||
|
});
|
||||||
|
globalThis.IS_TABS = IS_TABS;
|
||||||
|
|
||||||
if (!IS_MENU && !IS_TABS) {
|
if (!IS_MENU && !IS_TABS) {
|
||||||
if (!signedIn || !pageLoaded) return;
|
if (!signedIn || !pageLoaded) return;
|
||||||
@ -42,16 +46,16 @@ export default (async () => {
|
|||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
IS_ELECTRON || import(enhancerUrl("common/registry.js")),
|
IS_ELECTRON || import(enhancerUrl("common/registry.js")),
|
||||||
(IS_ELECTRON && IS_MENU) || import(enhancerUrl("api/state.js")),
|
|
||||||
import(enhancerUrl("api/interface.mjs")),
|
import(enhancerUrl("api/interface.mjs")),
|
||||||
|
import(enhancerUrl("api/state.js")),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
globalThis.__enhancerApi.__isReady(globalThis.__enhancerApi);
|
|
||||||
const { getMods, isEnabled, modDatabase } = globalThis.__enhancerApi;
|
const { getMods, isEnabled, modDatabase } = globalThis.__enhancerApi;
|
||||||
for (const mod of await getMods()) {
|
for (const mod of await getMods()) {
|
||||||
if (!(await isEnabled(mod.id))) continue;
|
if (!(await isEnabled(mod.id))) continue;
|
||||||
const isTheme = mod._src.startsWith("themes/");
|
const isCore = mod._src === "core",
|
||||||
if (IS_MENU && !(mod._src === "core" || isTheme)) continue;
|
isTheme = mod._src.startsWith("themes/");
|
||||||
|
if (IS_MENU && !(isCore || isTheme)) continue;
|
||||||
|
|
||||||
// clientStyles
|
// clientStyles
|
||||||
for (let stylesheet of mod.clientStyles ?? []) {
|
for (let stylesheet of mod.clientStyles ?? []) {
|
||||||
@ -65,10 +69,18 @@ export default (async () => {
|
|||||||
if (IS_MENU || IS_TABS) continue;
|
if (IS_MENU || IS_TABS) continue;
|
||||||
const db = await modDatabase(mod.id);
|
const db = await modDatabase(mod.id);
|
||||||
for (let script of mod.clientScripts ?? []) {
|
for (let script of mod.clientScripts ?? []) {
|
||||||
script = await import(enhancerUrl(`${mod._src}/${script}`));
|
// execute mod scripts after core has
|
||||||
script.default(globalThis.__enhancerApi, db);
|
// loaded and api is ready to use
|
||||||
|
Promise.resolve(isCore || API_LOADED)
|
||||||
|
.then(() => import(enhancerUrl(`${mod._src}/${script}`)))
|
||||||
|
.then((script) => script.default(globalThis.__enhancerApi, db))
|
||||||
|
.then(() => !isCore || globalThis.__enhancerReady?.());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_MENU) console.log("notion-enhancer: ready");
|
if (IS_MENU || IS_TABS) globalThis.__enhancerReady?.();
|
||||||
|
return API_LOADED.then(() => {
|
||||||
|
if (IS_MENU) console.log("notion-enhancer: ready");
|
||||||
|
return globalThis.__enhancerApi;
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
26
src/vendor/@unocss-preset-icons.mjs
vendored
26
src/vendor/@unocss-preset-icons.mjs
vendored
File diff suppressed because one or more lines are too long
@ -176,3 +176,4 @@ if (IS_ELECTRON) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object.assign((globalThis.__enhancerApi ??= {}), { queryDatabase });
|
Object.assign((globalThis.__enhancerApi ??= {}), { queryDatabase });
|
||||||
|
globalThis.__enhancerReady?.();
|
||||||
|
Loading…
Reference in New Issue
Block a user