Skip to content

Revamp networking api with epoxy try 2 - #3476

Open
r58Playz wants to merge 6 commits into
HeyPuter:mainfrom
r58Playz:epoxy
Open

Revamp networking api with epoxy try 2#3476
r58Playz wants to merge 6 commits into
HeyPuter:mainfrom
r58Playz:epoxy

Conversation

@r58Playz

Copy link
Copy Markdown
Member

No description provided.

r58Playz and others added 6 commits July 29, 2026 15:47
main tightened the socket error contract to pass an Error (see
types/modules/networking.d.ts, which documents the reason as
`error.message`); the epoxy rewrite still emitted a bare string,
matching the older `(reason: string)` declaration.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replaces the coverage lost when the wisp implementation was removed:
PSocket.test.js and PWispHandler.test.js were bound to PWispHandler,
parsers.js, and wispInfo, none of which survive the epoxy rewrite.

  PSocket.test.js  - connect/retry, inbound data, write normalisation,
                     close, and the TLS event remapping. Driven through
                     real ReadableStream/WritableStream pairs so
                     reader locking, cancel, and abort behave as they
                     do in the browser.
  index.test.js    - relay-token exchange (auth header, 401 re-auth and
                     retry, malformed responses) and the epoxy client
                     cache (keying, refresh, in-flight sharing).
  requests.test.js - pFetch delegation, cache invalidation, and the
                     api call logger's request description.
  epoxy.test.js    - the hand-packed wisp password extension payload.

The wasm runtime loader is left to integration coverage; it needs a
network fetch and a browser. createPuterPasswordBuilder is exported so
the byte layout can be tested against an injected fake runtime.

One skipped test records a pre-existing defect: on a failed write,
#readLoop's normal-termination path races #closeStreams and emits
close(false) after an error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PSocket #readLoop raced the teardown it was being torn down by. A failed
write sets #closing and hands the close event to #closeStreams, which has
to await reader.cancel() and writer.close() before emitting close(true).
That cancel resolves the loop's pending read with {done: true}, so the
loop broke, reached its own #emitClose(false), and set #closed first --
callers were told the socket shut down cleanly right after an error.
The loop now defers the close event whenever a teardown is under way, in
both its normal and its throwing path, and #closeStreams always emits.

getEpoxyClient swallowed every init failure and resolved undefined, so a
dead relay reached callers as "cannot read properties of undefined
(reading 'connect')" instead of its cause. It now re-throws, still
without caching the failed attempt. A socket reports "wasm unavailable"
or "Failed to create relay token (HTTP 503 ...)" and closes with the
error flag set.

Two related cache faults fell out of that rewrite: the in-flight
early-return ignored `refresh`, handing a caller the very attempt it
asked to replace, and it ignored the cache key, so an attempt started
before a token change satisfied a request made after it. Reuse is now
conditional on both.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the previous Wisp/WebSocket-based networking implementation in puter.js with an Epoxy-backed client (WASM runtime + Wisp provider), centralizing the SDK’s networking surface behind src/puter-js/src/modules/networking/index.js.

Changes:

  • Introduces an Epoxy runtime loader plus a cached Epoxy client keyed by APIOrigin and auth token, including relay-token minting and retry-on-401 behavior.
  • Rewrites PSocket/PTLSSocket and pFetch to delegate transport and fetch behavior to the Epoxy client, including cache invalidation on failures and request logging.
  • Removes the legacy Wisp v1 packet parser, handler, and TLS socket implementation; adds broad Vitest coverage for the new behavior.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/puter-js/src/modules/networking/requests.test.js New unit tests for pFetch delegation, failure behavior, cache invalidation, and logging payloads.
src/puter-js/src/modules/networking/requests.js Replaces the custom HTTP-over-sockets fetch with Epoxy client.fetch(...) plus structured apiCallLogger logging.
src/puter-js/src/modules/networking/PWispHandler.test.js Removes tests for the legacy Wisp relay WebSocket handler (no longer used).
src/puter-js/src/modules/networking/PWispHandler.js Removes the legacy Wisp relay WebSocket handler implementation.
src/puter-js/src/modules/networking/PTLS.js Removes the legacy rustls-wasm based TLS socket implementation.
src/puter-js/src/modules/networking/PSocket.test.js Replaces handshake-based tests with Epoxy stream-based tests (connect/read/write/close/error, TLS remapping).
src/puter-js/src/modules/networking/PSocket.js Reimplements sockets on top of Epoxy client streams, including pending-write buffering and teardown semantics.
src/puter-js/src/modules/networking/parsers.js Removes legacy Wisp v1 packet parsing/creation utilities.
src/puter-js/src/modules/networking/index.test.js New tests for relay-token exchange, Epoxy client caching/concurrency, and public netAPI surface.
src/puter-js/src/modules/networking/index.js New entry point: relay credential fetch, Epoxy client cache, and exported netAPI surface.
src/puter-js/src/modules/networking/epoxy.test.js New tests for the custom “puter password” protocol extension byte layout.
src/puter-js/src/modules/networking/epoxy.js New Epoxy WASM runtime loader and Epoxy client initialization wired to Wisp + password extension.
src/puter-js/src/index.js Switches puter.net initialization to the new netAPI module instead of constructing the surface inline.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +153 to +161
try {
await this.#writer.write(payload);
if ( callback ) {
callback();
}
} catch ( error ) {
clearEpoxyClientCache();
this.#emitErrorAndClose(error);
}
return new Error(String(reason));
}

export class PSocket extends EventListener {
});
}
rej(e);
export async function pFetch (...args) {
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