Skip to content

Fix client/server lifecycle bugs, modernize tooling, and release 0.7.0 - #35

Merged
knowledgecode merged 13 commits into
masterfrom
develop
Oct 18, 2026
Merged

knowledgecode merged 13 commits into
masterfrom
develop

Conversation

@knowledgecode

Copy link
Copy Markdown
Owner

Summary

Clears the Vite warning in the test run, removes config left over from older setups, fixes long-standing client/server bugs, and rewrites the tests so they actually check what they claim to. Bumps the version to 0.7.0 because disconnect() now rejects promises that used to stay pending forever.

Bug fixes

  • Synchronous handler errors - a bind() handler that threw synchronously escaped the promise chain, so the request never got a reply. The error is now sent back as an error reply.
  • Pending work on disconnect() - pending req() calls and a connect() still waiting for its ack were never settled. They are now rejected with Disconnected..
  • Reconnect after disconnect() - calling disconnect() before the ack arrived left the port open, so a late ack re-established the connection. The port is now always closed.
  • unsubscribe() - the server was never told, so it kept publishing to the client. The client now sends unsubscribe once a topic has no listeners left. The server already handled this packet, so mixing old and new clients and servers is safe.

API / types

  • send(topic, data?) - data is now optional, matching req() and publish().
  • _listener / _postMessage are now private, so they are no longer in the published index.d.ts.

Tooling

  • Dev dependencies updated: Vitest 5, ESLint 10.13, Playwright 1.64, Rollup 4.64. The allowScripts pins match the lockfile again.
  • vitest.config.js uses import.meta.dirname. This removes the Vite native config loader warning.
  • Removed .npmignore. It had no effect because package.json has a files list.
  • .vscode and CLAUDE.md are now in .gitignore, and .vscode is no longer tracked.
  • New npm run typecheck (tsc --noEmit), also run in CI. Before this, CI never type-checked.

Tests

  • The fixture servers bind greet, which publishes before it replies. Subscribe tests now await req('greet') instead of a timer and check the data they receive. Conditional assertions were made unconditional, workers are terminated after each test, and the 500 ms teardown delays are gone (suite time about 6.6 s -> 0.65 s).
  • New tests/same_context_test.ts covers each fix above. Its four regression tests fail on the code before the fixes.

Behavior changes for users

  • disconnect() now rejects a pending connect() / req() with Error('Disconnected.'). Code that does not handle that rejection will start seeing unhandled rejections.
  • Code that called _listener / _postMessage will no longer type-check.

Verification

Every commit passes npm run lint, tsc --noEmit and npm test on its own (28 tests, then 34 once the regression tests are added). On the head commit, npm run build succeeds, and npm pack --dry-run lists the same six files as before.

Move to Vitest 5, ESLint 10.13, Playwright 1.64 and Rollup 4.64, and refresh the allowScripts pins to the versions now in the lockfile.
Vite's native config loader does not support __dirname and printed a warning on every test run.
The "files" field in package.json already whitelists what gets published, so .npmignore had no effect, and its entries still referred to the removed Karma setup.
Ignore .vscode and CLAUDE.md, which hold per-developer configuration.
The bound listener ran outside the promise chain, so a synchronous throw escaped the message handler and the request never got a reply. Running it inside a Promise executor turns the throw into an error reply.
disconnect() left pending req() promises and an unacknowledged connect() unsettled forever. It now rejects them with "Disconnected." and closes the port even before the ack arrives, so a late ack can no longer re-establish the connection.
unsubscribe() only updated the local listener map, so the server kept publishing to the client. It now posts an unsubscribe packet once a topic has no listeners left.
send() now matches req() and publish(), which already accept a missing payload. _listener and _postMessage become private so they no longer appear in the published type declarations.
The fixture servers publish from a bound 'greet' handler instead of a timer, so subscribe tests await req('greet') and actually assert the delivered data. Server-side tests now assert unconditionally, the publish test waits for the client's acknowledgement, workers are terminated after each test, and the fixed 500 ms teardown delays are gone.
Run client and server in the test window itself to cover synchronous handler errors, pending requests and connects on disconnect, and server-side unsubscribe.
The build strips types with esbuild without checking them, and CI only ran lint and tests.
@knowledgecode
knowledgecode merged commit c2f13b1 into master Oct 18, 2026
2 checks passed
@knowledgecode
knowledgecode deleted the develop branch October 18, 2026 01:14
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