import type { PluginDefinition, PluginRuntimeFactory, PluginRuntimeSnapshot } from "./contract.ts";import { createCordisRuntime } from "./cordisRuntime.ts";import { createEffectScopeRuntime } from "./effectScopeRuntime.ts";import { createPureRuntime } from "./pureRuntime.ts"; const variants: ReadonlyArray<readonly [string, PluginRuntimeFactory]> = [ ["effect-scope", createEffectScopeRuntime], ["cordis", createCordisRuntime], ["pure-reconciler", createPureRuntime],]; const commandLabels = (snapshot: PluginRuntimeSnapshot) => snapshot.contributions.commands?.map((command) => command.label) ?? []; const database = (version: string): PluginDefinition => ({ id: "demo.database", version, provides: { "demo.database@1": { version } }, activate(context) { context.register("status", { id: "database", label: `database ${version}` }); },}); const issues: PluginDefinition = { id: "demo.issues", version: "1.0.0", requires: ["demo.database@1"], activate(context) { const service = context.resolve<{ readonly version: string }>("demo.database@1"); context.register("commands", { id: "create-issue", label: `create issue with database ${service.version}`, }); },}; const chain = (length: number): ReadonlyArray<PluginDefinition> => Array.from({ length }, (_, index) => ({ id: `benchmark.plugin.${index}`, version: "1.0.0", ...(index === 0 ? {} : { requires: [`benchmark.capability.${index - 1}`] }), provides: { [`benchmark.capability.${index}`]: index }, activate() {}, })); for (const [name, createRuntime] of variants) { const lifecycle: Array<string> = []; const runtime = createRuntime({ onLifecycle: ({ phase, pluginId }) => lifecycle.push(`${phase}:${pluginId}`), }); const initial = await runtime.reconcile([issues, database("1.0.0")]); const upgraded = await runtime.reconcile([issues, database("2.0.0")]); await runtime.reconcile([]); const benchmark = createRuntime(); const benchmarkDefinitions = chain(250); const startedAt = process.hrtime.bigint(); await benchmark.reconcile(benchmarkDefinitions); const activationMs = Number(process.hrtime.bigint() - startedAt) / 1_000_000; const noopStartedAt = process.hrtime.bigint(); await benchmark.reconcile(benchmarkDefinitions); const noopMs = Number(process.hrtime.bigint() - noopStartedAt) / 1_000_000; const upgradedDefinitions = benchmarkDefinitions.map((definition, index) => index === 0 ? { ...definition, version: "2.0.0" } : definition, ); const restartStartedAt = process.hrtime.bigint(); await benchmark.reconcile(upgradedDefinitions); const restartMs = Number(process.hrtime.bigint() - restartStartedAt) / 1_000_000; await benchmark.dispose(); process.stdout.write( `${JSON.stringify( { variant: name, initialCommands: commandLabels(initial), upgradedCommands: commandLabels(upgraded), lifecycle, chain250ActivationMs: Math.round(activationMs * 100) / 100, chain250NoopMs: Math.round(noopMs * 100) / 100, chain250RootRestartMs: Math.round(restartMs * 100) / 100, }, null, 2, )}\n`, ); await runtime.dispose();}
import type { PluginDefinition, PluginRuntimeFactory, PluginRuntimeSnapshot } from "./contract.ts";
import { createCordisRuntime } from "./cordisRuntime.ts";
import { createEffectScopeRuntime } from "./effectScopeRuntime.ts";
import { createPureRuntime } from "./pureRuntime.ts";
const variants: ReadonlyArray<readonly [string, PluginRuntimeFactory]> = [
["effect-scope", createEffectScopeRuntime],
["cordis", createCordisRuntime],
["pure-reconciler", createPureRuntime],
];
const commandLabels = (snapshot: PluginRuntimeSnapshot) =>
snapshot.contributions.commands?.map((command) => command.label) ?? [];
const database = (version: string): PluginDefinition => ({
id: "demo.database",
version,
provides: { "demo.database@1": { version } },
activate(context) {
context.register("status", { id: "database", label: `database ${version}` });
},
});
const issues: PluginDefinition = {
id: "demo.issues",
version: "1.0.0",
requires: ["demo.database@1"],
activate(context) {
const service = context.resolve<{ readonly version: string }>("demo.database@1");
context.register("commands", {
id: "create-issue",
label: `create issue with database ${service.version}`,
});
},
};
const chain = (length: number): ReadonlyArray<PluginDefinition> =>
Array.from({ length }, (_, index) => ({
id: `benchmark.plugin.${index}`,
version: "1.0.0",
...(index === 0 ? {} : { requires: [`benchmark.capability.${index - 1}`] }),
provides: { [`benchmark.capability.${index}`]: index },
activate() {},
}));
for (const [name, createRuntime] of variants) {
const lifecycle: Array<string> = [];
const runtime = createRuntime({
onLifecycle: ({ phase, pluginId }) => lifecycle.push(`${phase}:${pluginId}`),
});
const initial = await runtime.reconcile([issues, database("1.0.0")]);
const upgraded = await runtime.reconcile([issues, database("2.0.0")]);
await runtime.reconcile([]);
const benchmark = createRuntime();
const benchmarkDefinitions = chain(250);
const startedAt = process.hrtime.bigint();
await benchmark.reconcile(benchmarkDefinitions);
const activationMs = Number(process.hrtime.bigint() - startedAt) / 1_000_000;
const noopStartedAt = process.hrtime.bigint();
await benchmark.reconcile(benchmarkDefinitions);
const noopMs = Number(process.hrtime.bigint() - noopStartedAt) / 1_000_000;
const upgradedDefinitions = benchmarkDefinitions.map((definition, index) =>
index === 0 ? { ...definition, version: "2.0.0" } : definition,
);
const restartStartedAt = process.hrtime.bigint();
await benchmark.reconcile(upgradedDefinitions);
const restartMs = Number(process.hrtime.bigint() - restartStartedAt) / 1_000_000;
await benchmark.dispose();
process.stdout.write(
`${JSON.stringify(
{
variant: name,
initialCommands: commandLabels(initial),
upgradedCommands: commandLabels(upgraded),
lifecycle,
chain250ActivationMs: Math.round(activationMs * 100) / 100,
chain250NoopMs: Math.round(noopMs * 100) / 100,
chain250RootRestartMs: Math.round(restartMs * 100) / 100,
},
null,
2,
)}\n`,
);
await runtime.dispose();
}