Skip to content

v0.2.0

Choose a tag to compare

@JumpLink JumpLink released this 01 May 21:30
· 2272 commits to main since this release
52f2bd2

0.2.0 (2026-05-01)

gjsify v0.2.0 is the most comprehensive release to date and marks a major milestone on the road to full Node.js compatibility on GJS.

The @gjsify/fs module is now nearly complete: four consecutive PRs landed cp, opendir, glob, watchFile, statfs, utimes, lchown, FileHandle, and an AsyncIterableIterator-based fs.promises.watch() stream. The WebSocket server implementation is equally complete — with verifyClient, handleProtocols, noServer/handleUpgrade, permessage-deflate, and full Autobahn testsuite coverage. socket.io now runs 20/20 tests on GJS, a direct result of root-cause fixes across events, fetch, http, and stream.

New additions include: MCP support (Model Context Protocol) with server, client, and Streamable HTTP examples; the first phases of ts-for-gir integration, making @ts-for-gir/cli run fully on GJS for the first time; a new framework pillar with @gjsify/adw-app; GstHTMLVideoElement for GStreamer-backed video playback; and Playwright-based browser tests for Web/DOM packages.

On the performance side, per-frame GC allocations in the WebGL stack and the Excalibur demo have been significantly reduced.

Features

  • @gjsify/fetch + integration: axios integration suite + double-decompression fix (#54) (a09bf9b)
  • @gjsify/fs: add fs.promises.watch() as AsyncIterableIterator (#51) (f2ef61d)
  • @gjsify/fs: add watchFile/unwatchFile and statfsSync/statfs/promises.statfs (#52) (5fe86ed)
  • @gjsify/fs: complete fs — utimes/lutimes/lchown/lchmod, all fd-ops, FileHandle stubs (#53) (2908669)
  • @gjsify/fs: implement cp, Dir/opendir, and globSync/glob/promises.glob (#50) (4975f89)
  • @gjsify/v8: promote Stub → Partial with real heap stats and V8 wire-format serdes (#54) (e9e92fe)
  • deps: add @gjsify/crypto workspace dependency (8f03007)
  • example/cli-axios-http-client: rewrite around jsonplaceholder.typicode.com (real HTTPS) (ce9a512)
  • examples: add MCP server and client examples (61336ef)
  • examples: add SQLite todo store cross-validated on GJS and Node.js (6803555)
  • examples: socket.io ping-pong + chat-server examples + fix zlib TS errors (26d9553)
  • framework: new packages/framework pillar + @gjsify/adw-app (252386a)
  • http-soup-bridge: new Vala bridge package wrapping Soup.Server (eea4862)
  • http2: implement Soup 3.0-backed compat + session API (Phase 1) (a271401)
  • http2: update yarn.lock with new @girs dependencies for compatibility (e4a31ce)
  • integration/mcp: add Streamable HTTP transport tests (73dd84b)
  • integration/ts-for-gir: @ts-for-gir/cli@4.0.0-rc.8 on GJS via async-safe @gjsify/process.exit (#58) (24414f3)
  • integration/ts-for-gir: Phase 1 — @gi.ts/parser on GJS (#55) (f26a61f)
  • integration/ts-for-gir: Phase 4a — non-interactive @ts-for-gir/cli on Node + supporting infra (#57) (7973f3d)
  • integration/ts-for-gir: Phases 2+3 — @ts-for-gir/lib type system + generator pipeline on GJS (#56) (066e431)
  • integration: add MCP TypeScript SDK integration tests (757697c)
  • integration: socket.io 20/20 on GJS + 3 root-cause fixes in events/fetch/http/stream (97dcc7f)
  • integration: webtorrent integration test pillar + 3 root-cause fixes (b571b53)
  • node/ws: drop-in @gjsify/ws wrapper over Soup WebsocketConnection (b11304c)
  • socket.io-examples: enable WebSocket transport + add READMEs (706de51)
  • socket.io: port socket.spec.ts + namespaces.spec.ts; fix WebSocket-only transport (83f2db5)
  • tests-integration,websocket: Autobahn Testsuite pillar + /register subpath (221db35)
  • tests-integration: enable Autobahn 9.* performance suite (720ed04)
  • tests/browser: add browser tests for dom-elements and canvas2d-core (7a843f4)
  • tests/browser: add Playwright browser test infrastructure for Web/DOM packages (5506b60)
  • tests: add streamx integration test suite (155 Node + 156 GJS tests) (a975669)
  • video: GstHTMLVideoElement + VideoBridge controls + two new examples (#24) (82e32b5), closes #0 #1 #2 #18
  • websocket,tests-integration: permessage-deflate + Autobahn baseline expansion (74487bc), closes #30
  • websocket: implement headers, origin, handshakeTimeout client options (a2bb775)
  • ws,net,http: WebSocket server Phase 3 — noServer+handleUpgrade+'headers' event (93f4980)
  • ws: implement createWebSocketStream + update docs (09249a3)
  • ws: WebSocket server hooks Phase 2 — verifyClient, handleProtocols, { server } mode (a11a041)

Bug Fixes

  • @gjsify/unit: add browserSignalDone — 13/13 browser tests green (#48) (0a81e1f)
  • child_process: add ensureMainLoop() to spawn/exec/execFile — fix GJS-from-GJS subprocess deadlock (Phase 5) (#59) (2f04633)
  • child_process: spawn() sets child.stdout/stderr as GioInputStreamReadable (#49) (8b3feac)
  • ci: upgrade riscv64 base image to ubuntu:26.04 (9484cf3)
  • dgram: reject mismatched-family sends with EINVAL before hitting Gio (280bbfa)
  • esbuild-plugin-gjsify: add resolveDir to __dirname onLoad result (eec66e9)
  • esbuild-plugin-gjsify: fix random-access-file 'not a directory' build error (5105dfa)
  • esbuild-plugin-gjsify: inject __dirname/__filename for CJS node_modules (d2471c0)
  • esbuild-plugin-gjsify: use build.resolve for random-access-file redirect (79e3009)
  • example/cli-axios-http-client: explicit process.exit(0) so GJS returns to shell (d1a8b45)
  • examples/mcp: fix net-mcp-server session handling (eb235f8)
  • examples/mcp: fix TS2339 union type in cli-mcp-client (55c2eb4)
  • examples/mcp: hold McpServer per session and use explicit resource path (05b66cb)
  • examples: chat-server use CDN for socket.io client, serveClient: false (eed71a3)
  • fetch,url,webrtc,webaudio: XHR responseType + URL.createObjectURL at the source (unblocks Excalibur showcase audio) (604f6fa)
  • fetch: xhr.ts pass headersInit record directly, remove unused Headers import (0557244)
  • fs,stream: serialize concurrent I/O to clear GIO_ERROR_PENDING (2ad9471)
  • fs: convert ReadStream and FileHandle to async Gio I/O (c74c34a)
  • fs: use _construct() for async ReadStream file open; add regression tests (e75fab7)
  • globals: inject timer override into bundles via auto-globals (0a4af05)
  • http-soup-bridge: hand-written ambient types instead of @girs/ (4f42cc8)
  • http-soup-bridge: throw GLib.Error from listen() so JS gets EADDRINUSE (fc73142), closes #44
  • http,net,fetch: make HTTP server lifecycle GJS-GC-safe and Hono-compatible (ff4959f)
  • http2: use npm version ranges for @girs/* deps (not workspace:^) (60c5055)
  • http: map Gio listen errors to EADDRINUSE + default start to GJS (8374b34)
  • http: restore broad upgrade-intercept condition, keep req.socket before block (4675156)
  • integration/mcp: fix API signatures and GJS URL normalization (d94324f)
  • integration/mcp: fix TS2339 union type access on resource contents (28edde7)
  • net-ws-server: correct subprotocol to chat.v1, fix build:public idempotency (4e29eb3)
  • net: yield to GLib idle between socket reads to prevent GTK freeze (03f9389)
  • process: revert nextTick to microtask semantics (cc953c7)
  • remove surplus null arg from GLib.timeout_add calls in excalibur tests (496fa78)
  • remove surplus null user_data arg from GLib.timeout_add/idle_add calls (ba8aa76)
  • replace (globalThis as any).X with direct imports in impl code (40f7ea1)
  • stream,fetch: implement Readable.toWeb/fromWeb + fix fetch Content-Type (6f422c6)
  • stream: drain write buffer synchronously when _write completes sync (b7f6d5b)
  • stream: preserve FIFO write order across drain emit re-entry (d85eff4), closes #0
  • stream: store _err on destroy(), fix finished() for already-destroyed streams (9cb6c42)
  • tests/browser: exclude test.browser.mts from tsc in dom packages (91156f1)
  • tests/browser: pass DOMMatrix2DInit with 2D-only props to setTransform (4ca4d35)
  • utils,process: route nextTick through GLib idle to unfreeze GTK window (9f077ca)
  • utils: batch nextTick bursts to keep GTK input events dispatching (c9febdc)
  • utils: point GJS crash hint at GitHub issues, not internal STATUS.md (4c7dbca)
  • utils: print G_DEBUG advisory at GJS HTTP startup; document MainContext race (de5cd8d)
  • web-streams: use queueMicrotask instead of nextTick for pipeTo scheduling (fec7abb)
  • webgl: cast TypedArray to number[] for @girs/gwebgl-0.1 compat (509b6f1)
  • webgl: remove stale dom/webgl/prebuilds after move to framework/ (dba474d)
  • webrtc-native,webgl: remove build:meson from default build script (8f74ca2)
  • websocket: make perMessageDeflate opt-in to fix unit test regressions (dbdf236)
  • websocket: preserve NUL bytes in text-frame sends (0b548bf)
  • websocket: set max_incoming_payload_size to 100 MB + refresh Autobahn baselines (cf1fd74)
  • ws,net-ws-server: remove double 'connection' emit in handleUpgrade path (c5c12e0)
  • ws: replace @gjsify/http import type with local structural interface (a4157a9)
  • yarn: add workspace reference for @gjsify/buffer (9cfdea3)

Performance Improvements

  • excalibur-jelly-jumper: add performance profiling + GJS vs browser comparison (a5bd29d)
  • excalibur-jelly-jumper: finalize GJS config after A/B tests (6cf9eb1)
  • excalibur-jelly-jumper: fix HUD visibility + reduce physics cascade (5e1a55d)
  • excalibur-jelly-jumper: improve comparison script hints based on real data (5ad2b62)
  • excalibur-jelly-jumper: reduce per-frame GC allocations (0415007)
  • excalibur-jelly-jumper: tie [PERF] logging to F1 toggle (ca6877d)
  • excalibur-jelly-jumper: use black HUD text (green bg) (312c5cc)
  • webgl,excalibur-jelly-jumper: final allocation fixes (9a78eaa)
  • webgl,webaudio: eliminate per-frame GLib.Source + defer audio pipeline teardown (d66a44f)
  • webgl: eliminate Vala GLenum[] conversion loops + cache VariantType (0ee028a)