diff options
| author | misskey-release-bot[bot] <157398866+misskey-release-bot[bot]@users.noreply.github.com> | 2025-08-31 08:42:43 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-31 08:42:43 +0000 |
| commit | ec21336d45e6e3bb26a0225fc0aa57ac98d5be4b (patch) | |
| tree | 2c7aef5ba1626009377faf96941a57411dd619e5 /packages/frontend/src/plugin.ts | |
| parent | Merge pull request #16244 from misskey-dev/develop (diff) | |
| parent | Release: 2025.8.0 (diff) | |
| download | misskey-ec21336d45e6e3bb26a0225fc0aa57ac98d5be4b.tar.gz misskey-ec21336d45e6e3bb26a0225fc0aa57ac98d5be4b.tar.bz2 misskey-ec21336d45e6e3bb26a0225fc0aa57ac98d5be4b.zip | |
Merge pull request #16335 from misskey-dev/develop
Release: 2025.8.0
Diffstat (limited to 'packages/frontend/src/plugin.ts')
| -rw-r--r-- | packages/frontend/src/plugin.ts | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/packages/frontend/src/plugin.ts b/packages/frontend/src/plugin.ts index d6007a27ed..346e275575 100644 --- a/packages/frontend/src/plugin.ts +++ b/packages/frontend/src/plugin.ts @@ -3,18 +3,18 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { ref, defineAsyncComponent } from 'vue'; -import { Interpreter, Parser, utils, values } from '@syuilo/aiscript'; +import { ref } from 'vue'; import { compareVersions } from 'compare-versions'; -import { genId } from '@/utility/id.js'; +import { isSafeMode } from '@@/js/config.js'; import * as Misskey from 'misskey-js'; -import { aiScriptReadline, createAiScriptEnv } from '@/aiscript/api.js'; +import type { Parser, Interpreter, values } from '@syuilo/aiscript'; +import type { FormWithDefault } from '@/utility/form.js'; +import { genId } from '@/utility/id.js'; import { store } from '@/store.js'; import * as os from '@/os.js'; import { misskeyApi } from '@/utility/misskey-api.js'; import { i18n } from '@/i18n.js'; import { prefer } from '@/preferences.js'; -import type { FormWithDefault } from '@/utility/form.js'; export type Plugin = { installId: string; @@ -38,7 +38,13 @@ export type AiScriptPluginMeta = { config?: Record<string, any>; }; -const parser = new Parser(); +let _parser: Parser | null = null; + +async function getParser(): Promise<Parser> { + const { Parser } = await import('@syuilo/aiscript'); + _parser ??= new Parser(); + return _parser; +} export function isSupportedAiScriptVersion(version: string): boolean { try { @@ -53,6 +59,8 @@ export async function parsePluginMeta(code: string): Promise<AiScriptPluginMeta> throw new Error('code is required'); } + const { Interpreter, utils } = await import('@syuilo/aiscript'); + const lv = utils.getLangVersion(code); if (lv == null) { throw new Error('No language version annotation found'); @@ -62,6 +70,7 @@ export async function parsePluginMeta(code: string): Promise<AiScriptPluginMeta> let ast; try { + const parser = await getParser(); ast = parser.parse(code); } catch (err) { throw new Error('Aiscript syntax error'); @@ -224,14 +233,17 @@ function addPluginHandler<K extends keyof HandlerDef>(installId: Plugin['install } export function launchPlugins() { - for (const plugin of prefer.s.plugins) { + return Promise.all(prefer.s.plugins.map(plugin => { if (plugin.active) { - launchPlugin(plugin.installId); + return launchPlugin(plugin.installId); + } else { + return Promise.resolve(); } - } + })); } async function launchPlugin(id: Plugin['installId']): Promise<void> { + if (isSafeMode) return; const plugin = prefer.s.plugins.find(x => x.installId === id); if (!plugin) return; @@ -253,7 +265,10 @@ async function launchPlugin(id: Plugin['installId']): Promise<void> { await authorizePlugin(plugin); - const aiscript = new Interpreter(createPluginEnv({ + const { Interpreter, utils } = await import('@syuilo/aiscript'); + const { aiScriptReadline } = await import('@/aiscript/api.js'); + + const aiscript = new Interpreter(await createPluginEnv({ plugin: plugin, storageKey: 'plugins:' + plugin.installId, }), { @@ -278,7 +293,8 @@ async function launchPlugin(id: Plugin['installId']): Promise<void> { pluginContexts.set(plugin.installId, aiscript); - aiscript.exec(parser.parse(plugin.src)).then( + const parser = await getParser(); + await aiscript.exec(parser.parse(plugin.src)).then( () => { console.info('Plugin installed:', plugin.name, 'v' + plugin.version); systemLog('Plugin started'); @@ -334,9 +350,12 @@ export function changePluginActive(plugin: Plugin, active: boolean) { } } -function createPluginEnv(opts: { plugin: Plugin; storageKey: string }): Record<string, values.Value> { +async function createPluginEnv(opts: { plugin: Plugin; storageKey: string }): Promise<Record<string, values.Value>> { const id = opts.plugin.installId; + const { utils, values } = await import('@syuilo/aiscript'); + const { createAiScriptEnv } = await import('@/aiscript/api.js'); + const config = new Map<string, values.Value>(); for (const [k, v] of Object.entries(opts.plugin.config ?? {})) { config.set(k, utils.jsToVal(typeof opts.plugin.configData[k] !== 'undefined' ? opts.plugin.configData[k] : v.default)); @@ -392,8 +411,8 @@ function createPluginEnv(opts: { plugin: Plugin; storageKey: string }): Record<s 'Plugin:register:note_view_interruptor': values.FN_NATIVE(([handler]) => { utils.assertFunction(handler); addPluginHandler(id, 'note_view_interruptor', { - handler: withContext(ctx => async (note) => { - return utils.valToJs(await ctx.execFn(handler, [utils.jsToVal(note)])); + handler: withContext(ctx => (note) => { + return utils.valToJs(ctx.execFnSync(handler, [utils.jsToVal(note)])); }), }); }), |