Skip to content

feat(extension): make defineExtension single-use, like the host it serves - #48

Merged
kkdev92 merged 1 commit into
mainfrom
feat/single-use-extension-4.1.0
Aug 29, 2026
Merged

feat(extension): make defineExtension single-use, like the host it serves#48
kkdev92 merged 1 commit into
mainfrom
feat/single-use-extension-4.1.0

Conversation

@kkdev92

@kkdev92 kkdev92 commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Summary

defineExtension now describes one application, and behaves like it.

A second activate on the same result used to build a second application from scratch — a new log channel VS Code never saw closed, new registrations the first application's failsafe knew nothing about, and the first application left behind still owning what it had registered. The host underneath has always been single-flight and single-use; the facade hid that by starting over.

Now:

Second activate arrives while… Result
the first is starting joins the start in flight; both resolve to the same value
the application is running resolves to the same value; nothing is created
deactivate is pending, or after it settled rejects: FrameworkError, kind activation, code EXTENSION_NOT_RESTARTABLE, details.state = 'stopping' / 'stopped'
the first start failed rejects the same way, details.state = 'failed'

The refusal never opens a channel or touches VS Code. The host's own InvalidHostStateError stays internal; the facade translates it into the error type consumers already handle.

Compatibility

This is a behaviour change, and it is listed under Changed.

It cannot be observed in the editor: VS Code activates an extension once per session, and a reload re-imports the entry module, which yields a fresh definition. It can be observed in a test that activates one defineExtension result twice across cases — that test now fails on the second activation with a clear code instead of passing against a second, hidden application. The guide's advice already covers it: build one definition per test, or run the plan through createTestHost, which is what it exists for.

A published extension built on this package activates once in beforeAll and deactivates once in afterAll; its type-check, lint and 271 tests pass against this build unchanged.

Verification

npm run quality (1063 tests) and npm run verify:package pass.

Five new cases in the composition-root suite cover the four rows above and the failed-start case, asserting the value identity on the joined and running paths, the error kind, code and state on the refusing paths, and that exactly one log channel ever existed.

🤖 Generated with Claude Code

…rves

A second `activate` on one `defineExtension` result used to build a second
application from scratch: a new log channel VS Code never saw closed, new
registrations the first application's failsafe knew nothing about, and the
first application left behind, still owning what it had registered. The host
underneath is single-flight and single-use -- a start in flight is joined, and
a stopped or failed host refuses to start again -- but the facade was hiding
that by starting over.

Now the facade keeps one application. A second `activate` while the first is
starting or running joins it and resolves to the same value; after
`deactivate`, or after a start that failed, it rejects with a `FrameworkError`
of kind `activation` (code `EXTENSION_NOT_RESTARTABLE`, `details.state` naming
the host state) rather than rebuilding anything. The host's own
`InvalidHostStateError` stays internal; the facade translates it into the
vocabulary a consumer already handles.

VS Code activates an extension once per session, so nothing changes in the
editor. The change is visible only to a test that activates one definition
twice, which the guide already steers away from: build one per test, or run
the plan through `createTestHost`.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kkdev92
kkdev92 merged commit 32933d3 into main Aug 29, 2026
10 checks passed
@kkdev92 kkdev92 mentioned this pull request Aug 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant