Files
AFFiNE/apps/core/src/bootstrap/register-plugins.ts
2023-07-31 06:52:11 +00:00

81 lines
2.5 KiB
TypeScript

import { DebugLogger } from '@affine/debug';
import {
registeredPluginAtom,
rootStore,
} from '@toeverything/plugin-infra/atom';
import { evaluatePluginEntry, setupPluginCode } from './plugins/setup';
const builtinPluginUrl = new Set([
'/plugins/bookmark',
'/plugins/copilot',
'/plugins/hello-world',
'/plugins/image-preview',
]);
const logger = new DebugLogger('register-plugins');
declare global {
// eslint-disable-next-line no-var
var __pluginPackageJson__: unknown[];
}
globalThis.__pluginPackageJson__ = [];
Promise.all(
[...builtinPluginUrl].map(url => {
return fetch(`${url}/package.json`)
.then(async res => {
const packageJson = await res.json();
const {
name: pluginName,
affinePlugin: {
release,
entry: { core },
assets,
},
} = packageJson;
globalThis.__pluginPackageJson__.push(packageJson);
logger.debug(`registering plugin ${pluginName}`);
logger.debug(`package.json: ${packageJson}`);
if (!release && !runtimeConfig.enablePlugin) {
return Promise.resolve();
}
const baseURL = url;
const entryURL = `${baseURL}/${core}`;
rootStore.set(registeredPluginAtom, prev => [...prev, pluginName]);
await setupPluginCode(baseURL, pluginName, core);
console.log(`prepareImports for ${pluginName} done`);
await fetch(entryURL).then(async () => {
if (assets.length > 0) {
await Promise.all(
assets.map(async (asset: string) => {
if (asset.endsWith('.css')) {
const res = await fetch(`${baseURL}/${asset}`);
if (res.ok) {
// todo: how to put css file into sandbox?
return res.text().then(text => {
const style = document.createElement('style');
style.setAttribute('plugin-id', pluginName);
style.textContent = text;
document.head.appendChild(style);
});
}
return null;
} else {
return Promise.resolve();
}
})
);
}
evaluatePluginEntry(pluginName);
});
})
.catch(e => {
console.error(`error when fetch plugin from ${url}`, e);
});
})
).then(() => {
console.info('All plugins loaded');
});