docs(readme): update AI disclosure for tsconnect-react worker support
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -107,4 +107,4 @@ The test suite for `packages/http` was mostly generated by Claude Code, which al
|
||||
- **`@webnet/tsconnect` — taildrive WebDAV bridge and `listDrivePeers()`**: Claude Code implemented `jsFileSystemForRemote` in the tailscale fork (`cmd/tsconnect/wasm/drive.go`), a `drive.FileSystemForRemote` backed by a JS callback: request bodies stream to JS chunk-by-chunk via `readBodyChunk()`, response bodies stream back via `write()`/`end()` with `http.Flusher.Flush()` after each chunk, so large transfers never buffer in memory. `sys.DriveForRemote` is set at `newIPN` time; `setDriveHandler` (wired to `IPN.serveDrive(fn)`) registers the actual handler later, since the Tailscale auth/permission-parsing (`DriveSharingEnabled`, `ParsePermissions`) happens entirely Go-side before the JS handler is invoked. Also added `listDrivePeers` (wired to `IPN.listDrivePeers()`), mirroring native `driveRemotesFromPeers`: returns peers carrying `PeerCapabilityTaildriveSharer`, gated on `DriveAccessEnabled()`. On the TypeScript side: `DriveSharePermission`, `DrivePermissions`, `JsDriveRequest`, `JsDriveResponse`, `RawDriveHandler`, `IPNDrivePeer` types. Claude Code also created the new `@webnet/taildrive` package (`./server` sub-export) with `bridgeDriveHandler(handler)`, which adapts an `@webnet/http` `Handler` (e.g. from `@webnet/drive`'s `createDAVHandler`) to the Go bridge's raw request/response callback shape — kept in a separate package from `@webnet/tsconnect` and `@webnet/drive` to avoid a circular dependency between the two. Unit tests cover `bridgeDriveHandler`'s request/response translation (headers, all `Body` union variants, `hasBody` detection) and `IPN.serveDrive`/`listDrivePeers` argument validation and JSON handling against a fake `RawIPN`, so they run without a WASM build. A true end-to-end test against a live control plane is blocked on Headscale ACL support for `nodeAttrs`/`grants`/Taildrive, which only lands in Headscale v0.29.0 (not yet released stably at the time of writing).
|
||||
- **`packages/http` — `ReadableStream` body support**: implemented by Claude Code. Renamed the `AsyncIterable`-returning method to `iter()` and added a new `stream()` returning a `ReadableStream<Uint8Array>` with BYOB (byte stream) support where available. `WritableHttp.body` now accepts `ReadableStream<Uint8Array>`, written as chunked transfer encoding with BYOB reads and periodic flushes every 2^16 bytes. The `iterableToStream()`/`streamToIterable()` helpers in `packages/drive` were removed as they are no longer needed. `@webnet/taildrive`'s `bridgeDriveHandler` (predating this rename) was updated to match: `ctx.req.stream()` now returns a real BYOB-capable `ReadableStream<Uint8Array>` instead of an `AsyncIterable`, a `ctx.req.iter()` method was added for the old semantics, and response bodies that are a `ReadableStream` are now forwarded correctly instead of falling through to JSON serialization.
|
||||
- **`@webnet/transport` — `NodeListener` bug fixes**: two bugs fixed by Claude Code (Claude Sonnet 4.6): double invocation of the error callback (fired both directly from `close()` and from the server's `"close"` event), and a connection leak when `accept()` was rejected while a late-arriving connection triggered the still-registered `once("connection")` handler.
|
||||
- **`@webnet/tsconnect-worker`**: new package authored by Claude Code (Claude Sonnet 4.6). Wraps the `IPN` and `tsconnect-redux` Redux store in a `SharedWorker`, exposing every IPN method to clients via message-port RPC with per-object `MessageChannel`s for `Conn`, `TCPListener`, `PacketConn`, drive handler, and SSH sessions. Key features: `IndexedDBState` for sync IPN state storage (unavailable `localStorage` workaround — loads entire store into a `Map` at startup, serves reads/writes synchronously, fires async IDB writes on mutation); Web Locks API for client liveness detection (worker cleans up all resources opened by a disconnected client: connections, listeners, packet connections, drive handler); Redux action broadcast to all clients on every dispatch; full state snapshot sent to each new client on connect; graceful IPN shutdown when the last client leaves. Two tsconfigs: DOM lib for `IpnWorkerClient` and proxy classes (`WorkerConn`, `WorkerTCPListener`, `WorkerPacketConn`, `WorkerSSHSession`); WebWorker lib for the worker entry point. Round-2 improvements (Claude Sonnet 4.6): `IndexedDBState` moved to `@webnet/tsconnect/helpers` and exported from the package; `buildIpnStore` now accepts an optional `preloadedState`, and the worker sends the full Redux state snapshot (`preloadState` message) instead of synthetic actions on client connect; `WorkerConn` formally implements `RawTransport`, `WorkerTCPListener` implements `RawListener`, `WorkerPacketConn` implements `IpnPacketConn`; a new `IpnClient` interface added to `@webnet/tsconnect` (with `IpnSSHTermConfig` and `IpnPacketConn`) implemented by both `IPN` and `IpnWorkerClient` to prevent method drift; `IPN.ssh()` made async; `WorkerSSHSession.resize()`/`close()` made fire-and-forget (sync) to implement `IPNSSHSession`; `ReadableStream` transfer fallback via `MessageChannel` sub-protocol for Safari compatibility on both `sendFile` and `openWaitingFile`; `stateStorage: "memory"` option added to `WorkerConfig` for ephemeral (non-persisted) IPN state.
|
||||
- **`@webnet/tsconnect-worker`**: new package authored by Claude Code (Claude Sonnet 4.6). Wraps the `IPN` and `tsconnect-redux` Redux store in a `SharedWorker`, exposing every IPN method to clients via message-port RPC with per-object `MessageChannel`s for `Conn`, `TCPListener`, `PacketConn`, drive handler, and SSH sessions. Key features: `IndexedDBState` for sync IPN state storage (unavailable `localStorage` workaround — loads entire store into a `Map` at startup, serves reads/writes synchronously, fires async IDB writes on mutation); Web Locks API for client liveness detection (worker cleans up all resources opened by a disconnected client: connections, listeners, packet connections, drive handler); Redux action broadcast to all clients on every dispatch; full state snapshot sent to each new client on connect; graceful IPN shutdown when the last client leaves. Two tsconfigs: DOM lib for `IpnWorkerClient` and proxy classes (`WorkerConn`, `WorkerTCPListener`, `WorkerPacketConn`, `WorkerSSHSession`); WebWorker lib for the worker entry point. Round-2 improvements (Claude Sonnet 4.6): `IndexedDBState` moved to `@webnet/tsconnect/helpers` and exported from the package; `buildIpnStore` now accepts an optional `preloadedState`, and the worker sends the full Redux state snapshot (`preloadState` message) instead of synthetic actions on client connect; `WorkerConn` formally implements `RawTransport`, `WorkerTCPListener` implements `RawListener`, `WorkerPacketConn` implements `IpnPacketConn`; a new `IpnClient` interface added to `@webnet/tsconnect` (with `IpnSSHTermConfig` and `IpnPacketConn`) implemented by both `IPN` and `IpnWorkerClient` to prevent method drift; `IPN.ssh()` made async; `WorkerSSHSession.resize()`/`close()` made fire-and-forget (sync) to implement `IPNSSHSession`; `ReadableStream` transfer fallback via `MessageChannel` sub-protocol for Safari compatibility on both `sendFile` and `openWaitingFile`; `stateStorage: "memory"` option added to `WorkerConfig` for ephemeral (non-persisted) IPN state. `@webnet/tsconnect-react` updated by Claude Code (Claude Sonnet 4.6): `IpnContext` widened from `IPN` to `IpnClient`; `useBuildIpnWorker(worker, config, runParams?)` hook added to connect to a SharedWorker and return an `IpnWorkerClient`, with StrictMode-safe cleanup via `disconnect()`; `disconnect()` method added to `IpnWorkerClient` to release the Web Lock without stopping the worker.
|
||||
|
||||
Reference in New Issue
Block a user