Skip to content

feat: bring TypeScript SDK to parity with Rust client API (#3801)#67

Merged
iduartgomez merged 13 commits intomainfrom
feat/update-typescript-stdlib
Apr 21, 2026
Merged

feat: bring TypeScript SDK to parity with Rust client API (#3801)#67
iduartgomez merged 13 commits intomainfrom
feat/update-typescript-stdlib

Conversation

@netsirius
Copy link
Copy Markdown
Contributor

@netsirius netsirius commented Apr 18, 2026

Summary

Brings the TypeScript SDK (@freenetorg/freenet-stdlib) from a broken v0.0.9 state to a functional v0.1.0 that can reliably communicate with a current Freenet node. Implements phases 1-3 and 5-6 from #3801.

  • Fix critical bugs in put()/get() that sent wrong request types when subscribe flag was set
  • Fix UpdateNotification silently losing the contract code hash on key reconstruction
  • Add full streaming protocol support (inbound reassembly + outbound chunking)
  • Add promise-based API: const response = await api.get(key) instead of callback-only
  • Add Node.js compatibility (universal WebSocket, document guard)
  • Update FlatBuffers schema with SubscribeResponse and regenerate types
  • Update all dependencies to latest stable versions

What changed

Phase 1 - Critical bug fixes:

  • put() and get() now correctly send ContractRequestType.Put/Get (previously sent Subscribe when the subscribe flag was set)
  • UpdateNotification now passes the code field when reconstructing ContractKey
  • Added blockingSubscribe field to Put and Get requests
  • Updated FlatBuffers to v25.9.23, regenerated all TypeScript types

Phase 2 - Complete response handling:

  • Added NotFound response type with onContractNotFound callback
  • Added SubscribeResponse to FlatBuffers schema (host_response.fbs), regenerated types, wired onSubscribeResponse callback
  • Added Error response routing to onErr handler
  • Added onClose callback for WebSocket disconnection

Phase 3 - Streaming protocol:

  • Ported ReassemblyBuffer from Rust SDK for inbound stream reassembly (chunk validation, TTL eviction, out-of-order support)
  • Implemented outbound chunking via sendChunked() - payloads exceeding 512KB are automatically split into 256KB StreamChunk messages
  • Centralized all serialization into sendRequest() (6 duplicate code paths reduced to 1)

Phase 5 - Developer experience:

  • Promise-based API: get(), put(), update() now return typed promises (Promise<GetResponse>, etc.) that resolve on response, reject on error/timeout/close
  • Node.js support: resolveWebSocket() detects environment, falls back to ws package. document.cookie guarded for non-browser contexts
  • ws added as optional dependency
  • Request timeout (30s) with automatic promise rejection
  • Connection close rejects all pending promises

Phase 6 - Cleanup:

  • Exported missing public types (UpdateDataType, ContractType)
  • Version bump to 0.1.0
  • Updated all dependencies (TypeScript 5.9.3, Jest 30.3.0, ts-jest 29.4.9, etc.)
  • Added @types/node for Node.js type support
  • Removed dead code (unused constants)

Not included (out of scope)

  • Phase 4 (Node queries): ConnectedPeers, NodeDiagnostics, etc. are not in the FlatBuffers schema and the Rust serialization for QueryResponse is unimplemented!(). Cannot cross the wire yet.
  • Auto-reconnect: Intentionally left to the application layer. The SDK provides onClose callback; the app decides reconnection strategy.
  • number[] to Uint8Array consistency: Requires FlatBuffers codegen changes or extensive wrapper refactoring. Developers use new Uint8Array(state) as workaround.
  • TypeScript 6: ts-jest has runtime incompatibilities with TS6. Pinned to TS 5.9.3 (latest 5.x).

Test plan

  • All 30 tests pass (npx jest)
  • TypeScript compiles with no errors (npx tsc --noEmit)
  • Promise API: get(), put(), update() resolve with correct response data
  • NotFound: callback fires with correct instance ID, pending get promise rejects
  • SubscribeResponse: callback fires with correct key and subscribed flag
  • Error handling: onErr fires and all pending promises reject
  • Connection close: all pending promises reject
  • Outbound chunking: large put (600KB) splits into sequential StreamChunk messages
  • Inbound reassembly: ReassemblyBuffer handles single/multi/out-of-order chunks and all error cases (11 unit tests)
  • Subscribe/Disconnect: requests serialize correctly
  • Backward compatibility: callback and promise both fire for the same response
  • Integration: test SDK against freenet-microblogging app to verify real-world usage

@netsirius netsirius force-pushed the feat/update-typescript-stdlib branch from eee0604 to 6b47e80 Compare April 18, 2026 18:33
@netsirius netsirius requested a review from iduartgomez April 21, 2026 17:37
@iduartgomez iduartgomez merged commit b80bf47 into main Apr 21, 2026
10 checks passed
@iduartgomez iduartgomez deleted the feat/update-typescript-stdlib branch April 21, 2026 17:40
iduartgomez added a commit that referenced this pull request Apr 23, 2026
* chore(typescript): add release script, bump to 0.2.0

Add scripts/release-typescript-ver.sh with --dry-run support. Tightens
package.json files globs to dist/src/** to avoid shipping compiled
tests. Bump to 0.2.0 for SDK parity work (#67) and breaking wire
changes (#65, #66).

* chore(release): add non-interactive flags and release-typescript skill

Release scripts now support --yes and --otp flags so they work under
tools that cannot drive interactive prompts. Rust script gains --yes
and package-skip flags for symmetry. Add .claude/skills/release-typescript
skill documenting the end-to-end TS release flow.

* chore(release): support npm access tokens in typescript release script

Adds --token flag and NPM_TOKEN env support. Token is written to a
temp userconfig (chmod 600, cleaned via trap) so no credentials land
in ~/.npmrc or the repo. Skill doc updated to prefer tokens.
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.

2 participants