Releases: electrohyun/smocket
Release list
v1.0.1
What matters in this one
Smocket 1.0.1 is a maintenance release for the synchronized smocket and smocket-client packages. The published delivery rules, public TypeScript contracts, package entry points, and Node.js >=20 requirement are unchanged from 1.0.0.
The repository toolchain now uses pnpm 12 and Vitest 5. A dedicated Vitest 4 suite continues to exercise the built packages on Node 20, and the Playwright version is aligned across the maintained examples and package consumers. Renovate now keeps unrelated pnpm and Vitest major updates in separate pull requests.
The maintained browser examples now respect reduced motion, keep the drawing canvas usable in narrow viewports, and cover SharedWorker pages restored from the browser back and forward cache. These changes affect the examples and release validation rather than the package runtime.
Install the exact pair together:
npm install -D smocket@1.0.1 smocket-client@1.0.1Published packages
The release workflow installed and exercised the exact published pair outside the repository checkout:
Full Changelog: v1.0.0...v1.0.1
v1.0.0
πsmocket 1.0: a stable Socket.IO mock
smocket 1.0.0 is the first stable release of a Socket.IO mock built for frontend development and testing without a network server.
This release stabilizes the documented in-memory delivery and routing subset, its public TypeScript contracts, and the exact-version substitution path formed by smocket and smocket-client. The same application event handlers and framework-independent domain logic can be registered with smocket during frontend development and with a real Socket.IO server when the backend is available. The bootstrap changes; the supported application event layer can stay the same.
What you can build with smocket
Applications can exercise supported connection handlers, rooms, namespaces, targeted and broadcast delivery, acknowledgements, middleware, adapters, and socket lifecycle in the same JavaScript environment as the frontend.
The React drawing game demonstrates one application running against either a real Node.js HTTP and Socket.IO server or an in-browser smocket server hosted by a SharedWorker. Its three-page flow covers distinct socket identities, sender-excluding drawing broadcasts, chat, answer acknowledgements, one shared round result, page closure, refresh, and connection cleanup.
For multi-tab development, pages with the same origin, browser profile, worker URL, and worker name can share one caller-owned in-browser server while retaining separate socket identities. Worker termination or restart loses that in-memory state.
Stable public surface and runtimes
The supported public entry points are:
smocketfor the in-process server, adapters, and server-side contracts;smocket-clientfor the application-facing client facade;smocket/shared-workerfor the worker-host bridge;smocket-client/shared-workerfor the browser page bridge.
The root package is self-contained and has no runtime, optional, peer, or bundled dependencies. The client package carries one exact-version smocket peer and no duplicate implementation. Both packages provide supported ESM and CommonJS paths with self-contained declarations.
The published Node.js runtime floor is >=20. Desktop Chromium is the maintained automated SharedWorker target. Release checks exercise the packed artifacts outside the repository across the documented module, type, browser, test-runner, and SharedWorker entry paths.
Quick Start
Install the synchronized package pair at the same exact version:
npm install -D smocket@1.0.0 smocket-client@1.0.0smocket owns the in-process server and registry. smocket-client provides the application-facing replacement for the supported socket.io-client surface.
import { Server } from 'smocket';
import { connect } from 'smocket-client';
async function main() {
const URL = 'http://localhost:3000';
const io = new Server(URL);
io.on('connection', (socket) => {
socket.on('join', async (room: string, done: () => void) => {
await socket.join(room);
done();
});
socket.on('say', (room: string, text: string) => {
socket.to(room).emit('said', text);
});
});
const alice = connect(URL);
const bob = connect(URL);
const joinLobby = (client: ReturnType<typeof connect>) =>
new Promise<void>((done) => client.emit('join', 'lobby', done));
try {
await Promise.all([joinLobby(alice), joinLobby(bob)]);
const bobHeard = new Promise<string>((done) => bob.once('said', done));
alice.emit('say', 'lobby', 'hello');
console.log(`Bob heard: ${await bobHeard}`);
} finally {
await io.close();
}
}
void main();The example prints Bob heard: hello and exits after close() disconnects both clients and releases the in-process server. No test runner is required. Existing applications can keep their socket.io-client imports and map that package name to smocket-client in the environment that uses the mock.
Support boundary and differences from Socket.IO
smocket 1.0.0 stabilizes its documented in-memory delivery and routing boundary; it does not claim complete Socket.IO compatibility or replace a production backend. Network transport, transport fallback, heartbeat, automatic network reconnection, persistence, authentication infrastructure, cross-device communication, binary encoding, and multi-server scaling remain outside that boundary.
The dual-run conformance suite compares maintained cases against real Socket.IO first and smocket second. Chromium checks cover the browser and SharedWorker paths, the drawing game covers one application workflow across real and in-memory bootstraps, and clean-consumer checks install candidate tarballs outside the workspace. An API that exists in Socket.IO but is absent from the documented boundary should not be assumed to work in smocket.
See the scope, differences, and conformance report for the exact boundary.
Upgrade from 0.5.1
Keep smocket and smocket-client on the same exact version and load both through the same module format. Applications using the documented 0.5.1 entry points should not need to rewrite their event handlers, but the following stabilized contracts may require TypeScript or edge-case updates:
- The free
connect(url, options)lookup derives its namespace from the URL.namespaceis no longer part of its publicConnectOptions. - The callable
smocket-clientlookup follows the Socket.IO client shape without accepting event-map type arguments directly. Use the exported genericSocket<ListenEvents, EmitEvents>type when an explicit client annotation is needed. - Connection auth and middleware errors now cross a payload snapshot boundary. Code that depended on later mutation of the original object will observe the captured value instead.
- Timed acknowledgements preserve all response arguments rather than only the first.
- Tests that retained callbacks across disconnect or server close should expect those callbacks to be invalidated.
- Queued delivery, reentrant middleware, and outgoing observation now follow the measured lifecycle boundaries when teardown occurs during an admitted emit.
The Node.js requirement remains >=20. Repository development uses a newer Node.js toolchain because of the pinned package manager, but that does not change the published runtime floor.
Release certification
The immutable 1.0.0 candidate passed the authoritative CI run for the exact main commit below. The publication workflow promoted that exact candidate, published both packages, and then installed and exercised the exact registry pair successfully. The v1.0.0 tag and this GitHub Release point to the certified commit.
- Certified commit:
91a9479416d7d84eaf19119171497cc20098ead6 - Exact-SHA CI run
- Publication and registry verification run
- Registry certification result:
successβ the exact published pair was installed and exercised outside the repository checkout. smocket-1.0.0.tgzβ 183,367 bytes β SHA-256aba80de8ae080f34540fb06f248fa4ff87b6e59ede9425be4f108c045bfa3841smocket-client-1.0.0.tgzβ 3,362 bytes β SHA-2563d1b609b7c925553276e6be6495b0ce7a653fa2f4e558615562f49663807c4e5
Packages and documentation
The synchronized published packages are:
The publication workflow certified this exact pair outside the repository checkout.
- Package entry-point guide
- Documentation
- Live drawing game
- Interactive case-study report
- Source repository
Thank you
smocket grew out of what I learned while developing Socket.IO services, and the wish to keep frontend work moving when the backend was not yet ready. After countless conformance cases, bug fixes, reviews, tests, documentation, community contributions, and unexpected lifecycle boundaries, smocket has reached 1.0.0.
To everyone who tested smocket, reported a problem, reviewed a change, contributed code or documentation, or followed the project on its way to its first stable release: thank you, sincerely, from the bottom of my heart.
Full Changelog: v0.5.1...v1.0.0
v0.5.1
What matters in this one
Smocket 0.5.1 adds an explicit SharedWorker path for frontend development across several browser tabs.
Pages using the same origin, browser profile, module worker URL, and worker name can share one caller-owned, in-browser Smocket server while retaining separate socket identities.
The synchronized packages add two public entry points:
attachSharedWorkerfromsmocket/shared-workerconnectSharedWorkerfromsmocket-client/shared-worker
Install the exact pair together:
npm install -D smocket@0.5.1 smocket-client@0.5.1Multi-tab frontend workflow
The new SharedWorker guide and lobby example demonstrate connection admission, rooms, broadcasts, acknowledgements, ordered delivery, explicit disconnect, page close, and participant cleanup across three Chromium pages.
The Runnable Drawing Game runs the same React game in three pages. Its framework-independent application handler is registered with either:
- one in-browser Smocket server hosted by a SharedWorker; or
- a real Node.js HTTP and Socket.IO server.
Both modes cover distinct socket ids, countdown, sender-excluded strokes, chat, guess acknowledgements, one shared round result, page close, refresh, and a repeated clean run. The browser UI, event types, game state, and application handler stay the same; only the worker/page or Socket.IO server/client bootstrap changes (#393, #395).
Corrected observable results
These corrections match results exercised against Socket.IO 4.7.5 and 4.8.3:
- Connection admission: admission hooks could begin before
connect()returned. Callback auth, dynamic namespace matching, and namespace middleware now begin after the client factory returns while queued attempts remain cancellable (cases, #362). - Repeated middleware completion: repeated calls to the same continuation were previously collapsed. Repeated acceptance now completes the lifecycle repeatedly on one server Socket, while acceptance followed by rejection preserves the observed teardown and client-error sequence (cases, #363).
- Acknowledgement teardown: retained acknowledgement callbacks could outlive a disconnected socket or closed server. Teardown now invalidates those callbacks while already queued synchronous delivery may finish during the drain (cases, #364).
- Timed callbacks: delivered timed callbacks could remain pending across disconnect paths. They now settle exactly once with the Socket.IO disconnected error, and expired buffered packets are removed instead of accumulating or being delivered later (disconnect cases, timeout cases, #365).
- Client modifiers: an outgoing observer or payload-encoding failure could consume a pending client modifier too early. The modifier now remains available until an emit is dropped as volatile, buffered, or successfully encoded and scheduled (cases, #366).
Upgrade and scope
Keep smocket and smocket-client on the same exact version. The Node.js requirement remains >=20, the existing Socket.IO compatibility promises remain in place, and public 0.5.0 TypeScript consumers compile against the 0.5.1 declarations.
The applied ADR 0019 rows are:
- A change to a smocket-only API (section B) for the compatible SharedWorker entry points, using ordinary semantic versioning.
- A correction toward measured real behaviour with an observable change for the delivery and lifecycle corrections above.
The repository's 0.x version mapping places both classifications in 0.5.1.
The SharedWorker facade is deliberately narrow. It supports in-memory frontend development within one browser profile; it does not provide production transport, authentication, persistence, automatic reconnection, database access, cross-device communication, scaling, or the complete Socket.IO Client API. Worker termination or restart loses its state.
A deployed application replaces the page bootstrap with socket.io-client and verifies its real backend separately while retaining the supported event types and application handler flow.
Published packages
The release workflow independently installed and exercised the exact published pair outside the repository checkout:
The canonical published consumer now follows the same synchronized pair.
Full Changelog: v0.5.0...v0.5.1
v0.5.0
What matters in this one
v0.5.0 is expected to be the last minor release before v1.0.0. The remaining stabilization work may produce one or two v0.5.x patch releases, but the public surface intended for 1.0.0 is now substantially in place.
This is the first synchronized release of smocket and smocket-client. The root smocket package owns the in-memory server and connection registry. The new smocket-client package preserves Socket.IO Client's package shapeβdefault, io, connect, callable CommonJS, and the client Socket typeβwhile delegating every lookup to an exact-version smocket peer. Publishing both as 0.5.0 means a test's client import and its in-memory server resolve through the same implementation and registry instead of duplicating connection state (#235, #276).
Install both packages at the same version:
npm install -D smocket smocket-clientAn application can keep its existing import:
// src/chat.ts β unchanged application code
import { io } from 'socket.io-client';
export const socket = io('http://localhost:3000');In tests, substitute that client package with smocket-client and provide the in-memory server:
// chat.test.ts
import { Server } from 'smocket';
const io = new Server('http://localhost:3000');
io.on('connection', (socket) => {
socket.on('message', (text) => socket.broadcast.emit('message', text));
});Runner-specific substitution examples live in the test-runner integration guide.
New public surface
The package boundary now matches the server/client split applications already use. smocket exports the server-side Socket type, while smocket-client exports the client-side Socket type with the correct event-map direction. The facade works through ESM, callable CommonJS, Node16 resolution, bundler resolution, and Chromium (#178, #235, #276).
Sockets gained the observable state and extension points used by real applications: connected, disconnected, recovered, mutable client auth, per-packet server middleware, complete catch-all and listener-inspection methods, and the accepted inherited emitter surface. A direct Server.connect() plus nextConnection() pair is also available for tests that already hold the server instance (#266, #267, #268, #274, #275, #277).
Namespace and broadcast coverage grew together. Dynamic namespace parents and new_namespace are supported; broadcast operators gained Promise acknowledgements, aliases, compression modifiers, local socket lookup, bulk room membership, and bulk disconnect. The built-in Adapter lifecycle is observable through its live rooms map, and deterministic tracing or dropping adapters can inspect or alter local delivery without pretending to implement multi-server scaling (#238, #261, #262, #269, #278, #322, #323, #324).
Non-binary payloads now cross the same JSON snapshot boundary measured on Socket.IO's default parser, and disconnect(true) closes every namespace socket sharing the client Manager rather than only the selected namespace (#237, #250, #254).
Corrected observable results
These corrections move the mock to the results measured on Socket.IO 4.7.5 and 4.8.3:
- Static namespaces: 0.4.2 could admit an unregistered namespace and treated equivalent namespace spellings as different keys. 0.5.0 normalizes static names and rejects an unregistered namespace with
Invalid namespacebefore a connection handler runs (case, #228). - Abandoned connections: rejected middleware could leave temporary rooms behind, and a client disconnected during pending middleware could still connect later. Rejection and cancellation now remove the attempt and a late middleware continuation cannot admit it (case, #229).
- Disconnected membership: teardown could leave an empty sid entry, and a disconnected server socket could join rooms again. The sid is now removed and later joins cannot recreate membership (case, #230).
- Reserved events: application code could emit Socket.IO lifecycle names through public emitters. Those emits now throw before peer delivery or outgoing catch-all observation (case, #232).
- Volatile and timeout modifiers: socket modifiers used reusable wrapper objects and could leak into an unrelated broadcast. They now preserve Socket identity, apply to one operation, and stay isolated from recipient sockets; narrowed broadcast operators expose
volatileas an operator again (volatile cases, timeout cases, #231, #259). - Fluent APIs: server and namespace middleware registration plus client/server connect or disconnect methods returned
void. They now return the same receiver measured on Socket.IO, preserving chaining and event maps (cases, #233). - Payload isolation: JSON-compatible payloads could cross the in-memory boundary by reference, so mutation on one side was visible on the other. They now cross a serialization snapshot while binary values retain their supported pass-through behavior (cases, #237, #250).
- Manager teardown:
disconnect(true)could leave sibling namespace sockets from the same client alive. It now closes the shared Manager group and reports each namespace lifecycle once (cases, #236, #254). - Emitter removal: the final
removeListenerobserver now follows the maintained Node and Socket.IO host behavior instead of a locally fixed bulk-removal rule (cases, #309).
Upgrade notes
The two packages must stay on the same exact version. Load both through ESM or both through CommonJS so they share one in-process registry; mixed formats can create separate root module instances.
This release includes public declaration changes that can reject TypeScript call sites accepted by 0.4.2. Code that assigned to socket.volatile, treated fluent APIs as explicitly void, or passed names outside a typed event map to listener-removal methods may need adjustment. The runtime changes generally expose the Socket.IO-compatible receiver or restriction, but helpers and type assertions written around the older declarations should be checked during the upgrade.
The Node.js floor remains >=20, and the packed root package still has zero runtime dependencies.
The governing ADR 0019 row is βa public type change that still compiles at existing call sites, else major.β Existing call sites no longer compile in the cases above, so the change is major under the stable-version rule. Before 1.0.0 that rule applies one place to the right, making 0.5.0 the required minor release. Newly covered Socket.IO surface and observable corrections also ship here, with the corrected results called out above rather than hidden in the version number.
Package adoption and release reliability
The documented Vitest and Jest substitutions now run as clean consumers outside the checkout. Candidate checks install the exact two tarballs through ESM, CommonJS, Node16, bundler, browser, and application fixtures. Release candidates also record each package's name, version, size, and SHA-256 digest so every package-level check consumes the same artifact set (#280, #281, #310).
The supported Socket.IO declarations are independently inventoried, package tarballs reject runtime dependencies, non-receipt assertions use completion markers instead of wall-clock waits, and exact published versions have a bounded registry verifier and remediation path (#273, #282, #283, #284, #310, #314, #316, #318).
What's Changed
- docs: clarify contribution paths by @electrohyun in #220
- chore: label pull requests by size by @electrohyun in #221
- chore: rename pull request size labels by @electrohyun in #222
- docs: publish the v1.0.0 roadmap by @electrohyun in #223
- docs: define the five development lenses by @electrohyun in #224
- docs: remove the post-v1 document plan by @electrohyun in #225
- docs: add the Korean README by @electrohyun in #226
- docs: expand the moderated chat room example by @electrohyun in #227
- docs: record known compatibility gaps by @electrohyun in #239
- docs: assign Socket types by package by @electrohyun in #241
- docs: update the chat room overview by @electrohyun in #242
- fix: keep socket membership empty after disconnect by @electrohyun in #243
- docs: define the cl...
v0.4.2
What matters in this one
A server can now finish the lifecycle it started. io.close(callback?) closes sockets in every namespace, reproduces the server and client disconnect reasons measured on Socket.IO 4.7 and 4.8, rejects a connection that was still being admitted, and releases smocket's origin registration so the next test starts from a real empty boundary (#193). Repeated close paths share their first completion, while an older server cannot unregister the replacement that took its URL.
The substitution seam now keeps application types. Socket.IO's four server generic slots cross the server, namespace, socket, broadcast, timeout, volatile, middleware, adapter, and test-harness contracts; event direction, acknowledgement values, reserved disconnect types, and socket.data stay intact (#171). SmocketServer also gives applications one public type that includes the smocket-only adapter and nextConnection members without widening the Socket.IO-compatible ServerContract (#188).
Emitter return values now match the real packages instead of disappearing. Client emitters and listener registration methods return the client socket for chaining, while server-side emitters return true; the timed and volatile forms preserve the same split (#189). The correction changes an observable result, but not which sockets receive an event.
The compatibility matrix now typechecks against both supported Socket.IO minors, the namespace-middleware isolation case joined the dual-run report, and the Korean contribution guide documents the path into the project (#201, #209, #211).
This release lands on three rows in ADR 0019: newly covered Socket.IO surface, public type changes that still compile at existing call sites, and a correction toward measured real behavior with an observable change. Each is minor after 1.0.0; before 1.0.0 the rules apply one place to the right, so they ship together as the 0.4.2 patch.
What's Changed
- feat: add a server type that carries the smocket-only API by @electrohyun in #188
- fix: return the socket from the client emitters and true from the server ones by @electrohyun in #189
- chore: hold the two node-floor pins against every update type by @electrohyun in #190
- docs: say why the differences list exists, and record the emitter return values by @electrohyun in #187
- docs: name the row in release notes while 0.x folds the signal by @electrohyun in #186
- docs: empty the known-gaps section now that its entry is closed by @electrohyun in #191
- docs: show a fresh server per test, and annotating the connection listener by @electrohyun in #192
- docs: judge the declared rows before the fidelity rows by @electrohyun in #196
- test: assert the client pre-connect volatile window on both targets by @electrohyun in #197
- feat: add server close lifecycle by @electrohyun in #200
- chore: typecheck socket.io compatibility matrix by @electrohyun in #202
- docs: remove stale demo status comment by @electrohyun in #203
- docs: record close return compatibility by @electrohyun in #204
- docs: show server cleanup in quick start by @electrohyun in #205
- chore: update dev tooling (patch) by @renovate[bot] in #198
- chore: update dev tooling (minor) by @renovate[bot] in #199
- test: verify namespace middleware isolation by @shaurya703 in #209
- docs: add Korean translation of contributing guide by @lee0802-120 in #211
- feat: preserve Socket.IO event maps by @electrohyun in #210
- chore: bump version to 0.4.2 by @electrohyun in #212
Full Changelog: v0.4.1...v0.4.2
v0.4.1
What matters in this one
The contract types are exported. An application that swaps socket.io-client for smocket in a test already ran, because the value side of the substitution resolved and only the type side was missing. There was no socket type to annotate with. ClientSocketContract, ServerSocketContract, ServerContract, NamespaceContract, and Handshake now leave the package under their own names, along with the nine types those five reach through their own members, so the substitution path keeps its types instead of dropping to any at the seam (#178).
The README is rewritten (#114). It opens on the problem a hand-written socket mock runs into, carries a quick start that is a real vitest file, and points at the test-runner integration guide, the conformance report, and the runnable chat room example.
Nothing else moved. dist/index.js and dist/index.cjs are byte-identical to 0.4.0 and only the declaration files grow, so there is no delivery behaviour in this upgrade to read for.
This is the first release the version rule decided rather than described. Adding an export is a public type change that still compiles at every existing call site, which is the row 0019 reads as a minor. Before 1.0.0 the rules apply one place to the right, so it ships as a patch and ^0.4.0 picks it up.
What's Changed
- chore: assert the built bundle imports nothing external by @electrohyun in #146
- chore: add codecov.yml for the PR comment layout by @electrohyun in #147
- chore: configure Renovate by @renovate[bot] in #149
- chore: set up community infrastructure by @electrohyun in #148
- chore: refine the Renovate config by @electrohyun in #153
- chore: update pnpm to v11.19.0 by @renovate[bot] in #150
- chore: update actions/checkout action to v7 by @renovate[bot] in #151
- chore: hold the typescript and node majors in Renovate by @electrohyun in #154
- chore: update actions/setup-node action to v7 by @renovate[bot] in #155
- chore: update codecov/codecov-action action to v7 by @renovate[bot] in #156
- docs: add a contributors image to the README by @electrohyun in #157
- chore: drop devEngines so packageManager sets the pnpm version by @electrohyun in #158
- chore: update pnpm/action-setup action to v6 by @renovate[bot] in #160
- chore: stop auto-merging tooling patch updates by @electrohyun in #165
- chore: fix and pin down the Renovate match rules by @electrohyun in #163
- chore: update pnpm to v11.20.0 by @renovate[bot] in #164
- chore: run the two targets as vitest projects by @electrohyun in #168
- chore: label pull requests from the title prefix by @electrohyun in #170
- chore: verify the node floor in CI by @electrohyun in #174
- chore: add Windows and macOS jobs to the CI matrix by @electrohyun in #176
- docs: record what counts as a breaking change by @electrohyun in #177
- feat: export the contract types for the substitution path by @electrohyun in #179
- docs: publish the conformance report by @electrohyun in #180
- docs: add the scope and readiness label group by @electrohyun in #182
- docs: add test-runner integration setups for vitest and jest by @electrohyun in #183
- docs: add a runnable chat room example by @electrohyun in #184
- docs: rewrite the README by @electrohyun in #181
- chore: bump version to 0.4.1 by @electrohyun in #185
New Contributors
Full Changelog: v0.4.0...v0.4.1
v0.4.0
What matters in this one
smocket did not run in a browser before this release. Every connect() threw, because newId reached for node:crypto and a bundler's Buffer shim has no base64url, so the library was unusable in the environment it exists for. It is fixed, the package now imports nothing external at all, and CI runs the suite in Chromium so the same class of break cannot pass unnoticed again (#139, #105).
The public API is close to complete. Connection middleware, acknowledgement timeouts in both the single and broadcast forms, volatile, catch-all listeners in both directions, socket.data, off with removeAllListeners, and except chaining all landed. That is the surface v1.0.0 freezes, so this is the release to break against if something is missing.
Packaging is verified rather than assumed now. publint and arethetypeswrong run on the built package, the suite runs on Node 22 and 24 and against socket.io 4.7 and 4.8, and coverage gates the run instead of only reporting it.
What's Changed
- chore: add automated pull request review with CodeRabbit by @electrohyun in #102
- chore: split the Maintenance issue template into per-type forms by @electrohyun in #120
- docs: record the volatile scope decision (0016) by @electrohyun in #121
- feat: support onAny and offAny catch-all listeners by @electrohyun in #123
- feat: support off and removeAllListeners by @electrohyun in #124
- docs: add v0.3.0 and v0.4.0 to the README roadmap, with dates by @electrohyun in #127
- fix: keep duplicate listener registrations instead of de-duplicating by @electrohyun in #128
- feat: support connection middleware with io.use() by @electrohyun in #130
- feat: support socket.timeout by @electrohyun in #129
- feat: support volatile emit, dropped only in the pre-connect window by @electrohyun in #131
- feat: support the broadcast form of socket.timeout by @electrohyun in #132
- feat: support socket.data by @electrohyun in #133
- feat: support socket.onAnyOutgoing and offAnyOutgoing by @electrohyun in #134
- feat: per-socket delivery delay for race-condition testing by @electrohyun in #135
- feat: support except chaining on the broadcast operator by @electrohyun in #138
- chore: verify packaging and supported versions by @electrohyun in #136
- fix: generate socket ids without
node:cryptoby @electrohyun in #140 - chore: run the mock target in a browser on CI by @electrohyun in #142
- chore: bump version to 0.4.0 by @electrohyun in #145
Full Changelog: v0.3.0...v0.4.0
v0.3.0
What matters in this one
An application's own code runs against smocket now. io.on('connection') and connect(url) are socket.io's and socket.io-client's own entry points, and io is exported under the name socket.io-client uses, so a test that swaps the import runs the same handlers the application already has.
Before this, reaching a server-side socket meant a helper with no counterpart in socket.io, which every reader met on the first line. That helper stays for tests that drive a connection directly, and it is no longer the way in.
connect(url, { auth, query }) carries both onto socket.handshake, including the function form of auth, so code that authenticates at connection time is exercised rather than skipped.
What's Changed
- feat: app-facing entry points (io.on('connection'), connect(url), io alias) by @electrohyun in #93
- feat: accept auth and query on connect(url), populating socket.handshake by @electrohyun in #96
- feat: accept a function-form auth on connect(url) options by @electrohyun in #97
- chore: bump version to 0.3.0 by @electrohyun in #100
Full Changelog: v0.2.1...v0.3.0
v0.2.1
What matters in this one
The usage example on the front page did not run. It is fixed here, and the release exists for that.
Nothing else about the library changed. The README also states the pre-1.0 status plainly, so a reader deciding whether to try it is told the API can still move before 1.0.0.
What's Changed
- docs: fix the README usage example so it runs by @electrohyun in #90
- docs: state the pre-1.0 project status by @electrohyun in #92
Full Changelog: v0.2.0...v0.2.1
v0.2.0
What matters in this one
The reasoning got written down. Ten decision records landed covering the principles, the public API shape, connection and delivery semantics, and the cross-cutting rules, along with a glossary, the scope boundary, the documentation conventions and the first differences.md. Before this release the answer to "why is it built this way" lived in review threads.
That is what makes the rest of the project reviewable by someone who was not there, and it is why a later change can be told it conflicts with a decision rather than argued from scratch.
The public adapter API also lands here, with a working example, so the routing decision can be replaced without touching the core. Two behaviours were corrected against measured socket.io: emitWithAck now buffers until the connection completes instead of reaching a dead socket, and a disconnect carries its reason, with socket.disconnect() available on the server side.
What's Changed
- docs: establish documentation conventions (AGENTS.md, CONTRIBUTING-docs) by @electrohyun in #69
- test: translate test descriptions to English by @electrohyun in #72
- docs: add glossary and scope reference by @electrohyun in #71
- docs: record the decisions settled in the core work (0010-0013) by @electrohyun in #73
- docs: decision records for principles and the public API by @electrohyun in #75
- docs: record cross-cutting decisions (0007-0009) by @electrohyun in #74
- docs: decision records for connection and delivery semantics (0004-0006) by @electrohyun in #76
- docs: add the differences list and the documentation index by @electrohyun in #77
- feat: public adapter registration API with a working example by @electrohyun in #79
- fix: buffer emitWithAck until (re)connect by @electrohyun in #80
- feat: report disconnect reason and add server-side socket.disconnect by @electrohyun in #82
- docs: note the injectable disconnect reason in scope.md heartbeat item by @electrohyun in #84
- test: add a connectClients multi-client helper by @electrohyun in #85
- chore: bump version to 0.2.0 by @electrohyun in #87
Full Changelog: v0.1.0...v0.2.0
