From b4cbba1e9aaded4c560ce7f652b8b9010ad12fbd Mon Sep 17 00:00:00 2001 From: bbassie <17990055+bbassie@users.noreply.github.com> Date: Thu, 8 Oct 2026 15:19:19 +0000 Subject: [PATCH] Attach hooks in fromContext and export it as the entrypoint Co-Authored-By: Claude Opus 5.5 --- docs/devs/plugin-migration-to-2.0.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/devs/plugin-migration-to-2.0.md b/docs/devs/plugin-migration-to-2.0.md index c19a27ac..4faec692 100644 --- a/docs/devs/plugin-migration-to-2.0.md +++ b/docs/devs/plugin-migration-to-2.0.md @@ -130,8 +130,8 @@ The context types are `ControllerPluginContext`, `HostPluginContext`, `InstanceP ### Keeping a class for state -If the plugin has enough state that a class is still the better fit, give the class a private constructor and an async `static fromContext` that creates it from the context. -The entrypoint calls `fromContext` and attaches the hooks to methods on the returned object. +If the plugin has enough state that a class is still the better fit, give the class a private constructor and an async `static fromContext` that creates it from the context and attaches its hooks. +`fromContext` can then be the default export of the entrypoint. Instances are kept in a static `WeakMap` keyed by the controller, host or instance they belong to, which lets other code look them up without holding a reference to them. ```ts @@ -150,6 +150,7 @@ export class Frobber { static async fromContext(context: ControllerPluginContext) { const frobber = new Frobber(context.controller, context.logger); await frobber.load(); + context.controller.hooks.save.attach(context.plugin.name, () => frobber.save()); Frobber.instances.set(context.controller, frobber); return frobber; } @@ -162,12 +163,10 @@ export class Frobber { async save() { /* ... */ } } -export default async function(context: ControllerPluginContext) { - const frobber = await Frobber.fromContext(context); - context.controller.hooks.save.attach(context.plugin.name, () => frobber.save()); -} +export default Frobber.fromContext; ``` +The loader calls the default export without `this`, so refer to the class by name inside `fromContext` rather than using `this`. Don't extend the deprecated base classes for this, they attach `on*` methods to hooks themselves and log a warning.