From 9e064cb6b089621dfa30e296ccc4ef4c16068abb Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Fri, 11 Sep 2026 22:45:15 +0100 Subject: [PATCH] build: publish the core package as wire-mesh-core, unscoped Trusted publishing on npm is configured for the unscoped wire-mesh-core package name, not the @exadev scope this package originally declared. Renamed package.json and every consumer's dependency entry and import path (cloudflare-hub, node, web-console) to match, since a pnpm workspace resolves internal dependencies by package name. --- .github/workflows/ci.yml | 2 +- ts/packages/cloudflare-hub/README.md | 2 +- ts/packages/cloudflare-hub/package.json | 2 +- .../src/adapters/web-crypto-identity.ts | 7 ++----- .../src/adapters/websocket-transport.ts | 7 ++----- ts/packages/cloudflare-hub/src/worker.ts | 5 +---- ts/packages/cloudflare-hub/test/hub.test.ts | 9 +++------ .../test/web-crypto-identity.test.ts | 2 +- .../test/websocket-transport.test.ts | 2 +- ts/packages/core/README.md | 4 ++-- ts/packages/core/package.json | 2 +- ts/packages/node/README.md | 4 ++-- ts/packages/node/package.json | 2 +- .../src/adapters/node-websocket-transport.ts | 7 ++----- ts/packages/node/src/server.ts | 4 ++-- .../node/test/node-websocket-transport.test.ts | 2 +- ts/packages/node/test/relay-end-to-end.test.ts | 7 ++----- ts/packages/web-console/live-check/harness.ts | 6 +++--- ts/packages/web-console/package.json | 2 +- .../src/adapters/indexeddb-storage.ts | 2 +- .../src/adapters/web-crypto-identity.ts | 9 +++------ .../src/adapters/webrtc-transport.ts | 6 +++--- .../src/adapters/websocket-transport.ts | 6 +++--- ts/packages/web-console/src/main.ts | 6 +++--- .../web-console/src/webrtc-negotiation.ts | 14 +++++++------- .../test/web-crypto-identity.test.ts | 2 +- .../test/webrtc-negotiation.test.ts | 10 +++++----- .../web-console/test/webrtc-transport.test.ts | 4 ++-- .../test/websocket-transport.test.ts | 4 ++-- ts/pnpm-lock.yaml | 18 +++++++++--------- 30 files changed, 69 insertions(+), 90 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b33f67..e5f01f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -233,7 +233,7 @@ jobs: fi release-core: - name: Release @exadev/wire-mesh-core + name: Release wire-mesh-core if: github.ref == 'refs/heads/main' && github.event_name == 'push' needs: [required-checks] runs-on: ubuntu-latest diff --git a/ts/packages/cloudflare-hub/README.md b/ts/packages/cloudflare-hub/README.md index 20ddcae..05595b2 100644 --- a/ts/packages/cloudflare-hub/README.md +++ b/ts/packages/cloudflare-hub/README.md @@ -1,6 +1,6 @@ # @exadev/wire-mesh-cloudflare-hub -A reference deployment of a wire-mesh hub node on Cloudflare Workers: a public, always-on node other peers dial into, serving the relay role the repo README names for this package (transport.cddl's `relay-offer`/`relay-connect`/`relay-data`/`relay-inbound` — an opaque byte pipe when two peers can't connect directly, with device discovery over gossip). It depends on `@exadev/wire-mesh-core` as an ordinary workspace consumer and reinvents nothing the core owns: all protocol logic is core's, reached through its ports. +A reference deployment of a wire-mesh hub node on Cloudflare Workers: a public, always-on node other peers dial into, serving the relay role the repo README names for this package (transport.cddl's `relay-offer`/`relay-connect`/`relay-data`/`relay-inbound` — an opaque byte pipe when two peers can't connect directly, with device discovery over gossip). It depends on `wire-mesh-core` as an ordinary workspace consumer and reinvents nothing the core owns: all protocol logic is core's, reached through its ports. ## Why the hub lives in a Durable Object diff --git a/ts/packages/cloudflare-hub/package.json b/ts/packages/cloudflare-hub/package.json index d715b1a..0b1f5fb 100644 --- a/ts/packages/cloudflare-hub/package.json +++ b/ts/packages/cloudflare-hub/package.json @@ -16,7 +16,7 @@ "_lint": "eslint . --fix --cache --max-warnings 0" }, "dependencies": { - "@exadev/wire-mesh-core": "workspace:*", + "wire-mesh-core": "workspace:*", "cbor2": "2.3.0" }, "devDependencies": { diff --git a/ts/packages/cloudflare-hub/src/adapters/web-crypto-identity.ts b/ts/packages/cloudflare-hub/src/adapters/web-crypto-identity.ts index 594818f..635dad3 100644 --- a/ts/packages/cloudflare-hub/src/adapters/web-crypto-identity.ts +++ b/ts/packages/cloudflare-hub/src/adapters/web-crypto-identity.ts @@ -1,10 +1,7 @@ // A Worker-runtime IdentityPort implementation using the standard Web Crypto API (globalThis.crypto.subtle), which exists identically in Cloudflare Workers and in Node >= 19 -- mirroring core's node-identity adapter's algorithm coverage (ES256 P-256 and Ed25519, the two algorithms identity-key.alg carries in the spec's own conformance vectors) so the two adapters are drop-in substitutes for each other behind the same port. -import type { - DeviceId, - IdentityKey, -} from "@exadev/wire-mesh-core/generated/protocol"; -import type { IdentityPort } from "@exadev/wire-mesh-core/ports/identity"; +import type { DeviceId, IdentityKey } from "wire-mesh-core/generated/protocol"; +import type { IdentityPort } from "wire-mesh-core/ports/identity"; const ES256 = -7; const EDDSA = -8; diff --git a/ts/packages/cloudflare-hub/src/adapters/websocket-transport.ts b/ts/packages/cloudflare-hub/src/adapters/websocket-transport.ts index 42c0040..9b7b0ee 100644 --- a/ts/packages/cloudflare-hub/src/adapters/websocket-transport.ts +++ b/ts/packages/cloudflare-hub/src/adapters/websocket-transport.ts @@ -1,11 +1,8 @@ // A Worker-runtime Connection implementation over WebSocket messages, driven directly by the Durable Object entry (worker.ts's RelayHubDurableObject): the DO accepts the server side of the runtime's WebSocketPair and hands it here. Unlike the TCP adapter -- a stream, needing a length prefix to delimit frames -- each WebSocket binary message is already self-delimiting, so one message carries exactly one CBOR-encoded frame and no prefix is needed. Undecodable bytes are a connection-level failure (the receive iteration rejects and the socket closes), matching the TCP adapter's treatment of hostile wire input; a decodable frame that fails schema validation is dropped rather than disconnecting -- an unrecognised frame from a newer peer is what version negotiation exists to tolerate. import { cdeDecodeOptions, cdeEncodeOptions, decode, encode } from "cbor2"; -import { - frameSchema, - type Frame, -} from "@exadev/wire-mesh-core/generated/protocol"; -import type { Connection } from "@exadev/wire-mesh-core/ports/transport"; +import { frameSchema, type Frame } from "wire-mesh-core/generated/protocol"; +import type { Connection } from "wire-mesh-core/ports/transport"; // RFC 6455 close codes, named rather than bare: 1000 normal closure, 1002 protocol error. const CLOSE_NORMAL = 1000; diff --git a/ts/packages/cloudflare-hub/src/worker.ts b/ts/packages/cloudflare-hub/src/worker.ts index e64ab1e..280c3b5 100644 --- a/ts/packages/cloudflare-hub/src/worker.ts +++ b/ts/packages/cloudflare-hub/src/worker.ts @@ -1,10 +1,7 @@ // The Worker entry. The Durable Object class must be exported from this entrypoint file for wrangler to bind it (wrangler.toml names this export), so it is defined here directly rather than re-exported from a sibling module. A plain Worker's request context cannot host the hub's long-lived per-connection loops -- workerd's hang detection cancels any request whose promise chain parks on a pure-JS waiter (the pull-based receive() iteration), which is exactly what the relay loop does; a Durable Object is the documented home for that shape, its lifetime tied to the accepted WebSockets rather than to a single fetch. The DO keeps connections alive for its own lifetime; the hibernation API (state.acceptWebSocket + webSocketMessage handlers) is the idle-cost follow-up noted in README.md, not a correctness requirement. import { DurableObject } from "cloudflare:workers"; -import { - createRelayHub, - type RelayHub, -} from "@exadev/wire-mesh-core/domain/relay-hub"; +import { createRelayHub, type RelayHub } from "wire-mesh-core/domain/relay-hub"; import { wrapWebSocket } from "./adapters/websocket-transport.js"; export function healthResponse(): Response { diff --git a/ts/packages/cloudflare-hub/test/hub.test.ts b/ts/packages/cloudflare-hub/test/hub.test.ts index 6e68c72..614b459 100644 --- a/ts/packages/cloudflare-hub/test/hub.test.ts +++ b/ts/packages/cloudflare-hub/test/hub.test.ts @@ -1,11 +1,8 @@ import { describe, expect, it } from "vitest"; import { decode } from "cbor2"; -import type { - DeviceId, - Frame, -} from "@exadev/wire-mesh-core/generated/protocol"; -import type { Connection } from "@exadev/wire-mesh-core/ports/transport"; -import { createRelayHub } from "@exadev/wire-mesh-core/domain/relay-hub"; +import type { DeviceId, Frame } from "wire-mesh-core/generated/protocol"; +import type { Connection } from "wire-mesh-core/ports/transport"; +import { createRelayHub } from "wire-mesh-core/domain/relay-hub"; import { messageFromFrame, wrapWebSocket, diff --git a/ts/packages/cloudflare-hub/test/web-crypto-identity.test.ts b/ts/packages/cloudflare-hub/test/web-crypto-identity.test.ts index 968b7ef..1096c28 100644 --- a/ts/packages/cloudflare-hub/test/web-crypto-identity.test.ts +++ b/ts/packages/cloudflare-hub/test/web-crypto-identity.test.ts @@ -8,7 +8,7 @@ import { import { createNodeIdentity, verifyWithPublicKey as verifyWithNodeIdentity, -} from "@exadev/wire-mesh-core/adapters/node-identity"; +} from "wire-mesh-core/adapters/node-identity"; import { bytesFromHex } from "./hex.js"; const ES256 = -7; diff --git a/ts/packages/cloudflare-hub/test/websocket-transport.test.ts b/ts/packages/cloudflare-hub/test/websocket-transport.test.ts index e58a490..ed42666 100644 --- a/ts/packages/cloudflare-hub/test/websocket-transport.test.ts +++ b/ts/packages/cloudflare-hub/test/websocket-transport.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; import { decode, encode } from "cbor2"; -import type { Frame } from "@exadev/wire-mesh-core/generated/protocol"; +import type { Frame } from "wire-mesh-core/generated/protocol"; import { messageFromFrame, wrapWebSocket, diff --git a/ts/packages/core/README.md b/ts/packages/core/README.md index 21c0fc5..bba3b23 100644 --- a/ts/packages/core/README.md +++ b/ts/packages/core/README.md @@ -1,4 +1,4 @@ -# @exadev/wire-mesh-core +# wire-mesh-core The TypeScript implementation of wire-mesh's protocol, built ports/adapters: domain logic (`src/domain/`) depends only on port contracts (`src/ports/`) and the [cddl.js](https://github.com/ExaDev/cddl.js)-generated Zod schemas (`src/generated/protocol.ts`, regenerated from `../../../spec/protocol.cddl` via `generate.ts` -- never edited by hand), never on a specific adapter's own imports. @@ -29,4 +29,4 @@ CI regenerates and diffs against the committed file, the same way `conformance/` ## Publishing -Published to npm as [`@exadev/wire-mesh-core`](https://www.npmjs.com/package/@exadev/wire-mesh-core). A push to `main` runs `semantic-release` (`ts/packages/core/release.config.ts`, tagged `core-v*` to keep this package's releases distinct from any other publishable package in the workspace), which versions from conventional-commit messages, builds `dist/` fresh, and publishes it -- `dist/` itself is never committed to the repo. +Published to npm as [`wire-mesh-core`](https://www.npmjs.com/package/wire-mesh-core). A push to `main` runs `semantic-release` (`ts/packages/core/release.config.ts`, tagged `core-v*` to keep this package's releases distinct from any other publishable package in the workspace), which versions from conventional-commit messages, builds `dist/` fresh, and publishes it -- `dist/` itself is never committed to the repo. diff --git a/ts/packages/core/package.json b/ts/packages/core/package.json index ac1efcf..d67e699 100644 --- a/ts/packages/core/package.json +++ b/ts/packages/core/package.json @@ -1,5 +1,5 @@ { - "name": "@exadev/wire-mesh-core", + "name": "wire-mesh-core", "version": "0.0.0", "type": "module", "packageManager": "pnpm@10.33.0", diff --git a/ts/packages/node/README.md b/ts/packages/node/README.md index 006346f..b5dd26d 100644 --- a/ts/packages/node/README.md +++ b/ts/packages/node/README.md @@ -8,7 +8,7 @@ A self-hostable, no-cloud LAN counterpart to `@exadev/wire-mesh-cloudflare-hub`: ## How it maps onto core's ports -The relay/pairing/gossip-registry domain logic itself is not duplicated here — it is `@exadev/wire-mesh-core`'s `./domain/relay-hub` export, the same module `cloudflare-hub` consumes, proven transport-agnostic by running against core's TCP adapter, `cloudflare-hub`'s WebSocket adapter, and this package's own adapter alike. This package supplies exactly one new thing: a **Connection**/**Transport** port implementation over the `ws` npm package (`src/adapters/node-websocket-transport.ts`) — the same one-CBOR-frame-per-binary-message convention as the hub's and web-console's own WebSocket adapters, but driven through `ws`'s idiomatic Node `EventEmitter` API (`.on`, not `.addEventListener`) rather than the platform `WebSocket` those two wrap. Unlike the browser adapter, whose `listen()` always rejects (a browser tab can never accept inbound connections), and unlike `cloudflare-hub`'s adapter, which has no `listen()` at all (ingress arrives through the Durable Object's own upgrade handling), this adapter's `listen()` is a real implementation: this package's entire reason to exist is being reachable on a LAN. +The relay/pairing/gossip-registry domain logic itself is not duplicated here — it is `wire-mesh-core`'s `./domain/relay-hub` export, the same module `cloudflare-hub` consumes, proven transport-agnostic by running against core's TCP adapter, `cloudflare-hub`'s WebSocket adapter, and this package's own adapter alike. This package supplies exactly one new thing: a **Connection**/**Transport** port implementation over the `ws` npm package (`src/adapters/node-websocket-transport.ts`) — the same one-CBOR-frame-per-binary-message convention as the hub's and web-console's own WebSocket adapters, but driven through `ws`'s idiomatic Node `EventEmitter` API (`.on`, not `.addEventListener`) rather than the platform `WebSocket` those two wrap. Unlike the browser adapter, whose `listen()` always rejects (a browser tab can never accept inbound connections), and unlike `cloudflare-hub`'s adapter, which has no `listen()` at all (ingress arrives through the Durable Object's own upgrade handling), this adapter's `listen()` is a real implementation: this package's entire reason to exist is being reachable on a LAN. `src/server.ts` is the CLI entrypoint: it wires `createRelayHub()` over `createNodeWebSocketTransport()`, answering any plain (non-Upgrade) HTTP request on the same listener with a small JSON health response, the same shape `cloudflare-hub`'s own `healthResponse()` returns. @@ -49,4 +49,4 @@ Deferred deliberately, matching `cloudflare-hub`'s own list: ## Type environment -`src/` is plain Node code, typechecked against `@types/node` and `@types/ws` — no DOM lib, no Worker types, matching `@exadev/wire-mesh-core`'s own type environment exactly (the closest precedent this package's scaffolding mirrors). +`src/` is plain Node code, typechecked against `@types/node` and `@types/ws` — no DOM lib, no Worker types, matching `wire-mesh-core`'s own type environment exactly (the closest precedent this package's scaffolding mirrors). diff --git a/ts/packages/node/package.json b/ts/packages/node/package.json index 07b14cb..aeeacc9 100644 --- a/ts/packages/node/package.json +++ b/ts/packages/node/package.json @@ -22,7 +22,7 @@ "_lint": "eslint . --fix --cache --max-warnings 0" }, "dependencies": { - "@exadev/wire-mesh-core": "workspace:*", + "wire-mesh-core": "workspace:*", "cbor2": "2.3.0", "ws": "8.21.3" }, diff --git a/ts/packages/node/src/adapters/node-websocket-transport.ts b/ts/packages/node/src/adapters/node-websocket-transport.ts index 4a9d161..3448b52 100644 --- a/ts/packages/node/src/adapters/node-websocket-transport.ts +++ b/ts/packages/node/src/adapters/node-websocket-transport.ts @@ -6,15 +6,12 @@ import { type ServerResponse, } from "node:http"; import { cdeDecodeOptions, cdeEncodeOptions, decode, encode } from "cbor2"; -import { - frameSchema, - type Frame, -} from "@exadev/wire-mesh-core/generated/protocol"; +import { frameSchema, type Frame } from "wire-mesh-core/generated/protocol"; import type { Connection, Listener, Transport, -} from "@exadev/wire-mesh-core/ports/transport"; +} from "wire-mesh-core/ports/transport"; import { WebSocket, WebSocketServer, type RawData } from "ws"; // RFC 6455 close codes, named rather than bare: 1000 normal closure, 1002 protocol error. diff --git a/ts/packages/node/src/server.ts b/ts/packages/node/src/server.ts index 0655a08..05118bf 100644 --- a/ts/packages/node/src/server.ts +++ b/ts/packages/node/src/server.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node -// The wire-mesh-node CLI entrypoint: a self-hostable, no-cloud LAN counterpart to cloudflare-hub, wiring the same shared relay-hub domain logic from @exadev/wire-mesh-core over a real Node WebSocket + http server instead of a Cloudflare Durable Object. Default bind address is 0.0.0.0, not loopback -- the whole point of this package is LAN reachability, unlike a dev-server tool's usual loopback-only default. +// The wire-mesh-node CLI entrypoint: a self-hostable, no-cloud LAN counterpart to cloudflare-hub, wiring the same shared relay-hub domain logic from wire-mesh-core over a real Node WebSocket + http server instead of a Cloudflare Durable Object. Default bind address is 0.0.0.0, not loopback -- the whole point of this package is LAN reachability, unlike a dev-server tool's usual loopback-only default. -import { createRelayHub } from "@exadev/wire-mesh-core/domain/relay-hub"; +import { createRelayHub } from "wire-mesh-core/domain/relay-hub"; import { createNodeWebSocketTransport } from "./adapters/node-websocket-transport.js"; export function healthResponse(): { ok: true; node: string; roles: string[] } { diff --git a/ts/packages/node/test/node-websocket-transport.test.ts b/ts/packages/node/test/node-websocket-transport.test.ts index a3e9280..66f2f92 100644 --- a/ts/packages/node/test/node-websocket-transport.test.ts +++ b/ts/packages/node/test/node-websocket-transport.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; import { encode } from "cbor2"; -import type { Frame } from "@exadev/wire-mesh-core/generated/protocol"; +import type { Frame } from "wire-mesh-core/generated/protocol"; import type { WebSocket } from "ws"; import { createNodeWebSocketTransport, diff --git a/ts/packages/node/test/relay-end-to-end.test.ts b/ts/packages/node/test/relay-end-to-end.test.ts index a8002c9..cb19468 100644 --- a/ts/packages/node/test/relay-end-to-end.test.ts +++ b/ts/packages/node/test/relay-end-to-end.test.ts @@ -1,11 +1,8 @@ // Real, in-suite equivalent of cloudflare-hub/scripts/live-check.mjs: two genuine wire-mesh-node clients gossiping, relay-connecting, and exchanging relay-data through a real createRelayHub() wired over a real createNodeWebSocketTransport() listener -- the same health-check wiring server.ts itself uses, so this test also proves the plain-HTTP health path works on the same listener a WebSocket client connects to. import { describe, expect, it } from "vitest"; -import { createRelayHub } from "@exadev/wire-mesh-core/domain/relay-hub"; -import type { - DeviceId, - Frame, -} from "@exadev/wire-mesh-core/generated/protocol"; +import { createRelayHub } from "wire-mesh-core/domain/relay-hub"; +import type { DeviceId, Frame } from "wire-mesh-core/generated/protocol"; import { createNodeWebSocketTransport } from "../src/adapters/node-websocket-transport.js"; import { healthResponse } from "../src/server.js"; import { bytesFromHex, deviceIdFromFillHex } from "./hex.js"; diff --git a/ts/packages/web-console/live-check/harness.ts b/ts/packages/web-console/live-check/harness.ts index d6e1c8b..a4f07c5 100644 --- a/ts/packages/web-console/live-check/harness.ts +++ b/ts/packages/web-console/live-check/harness.ts @@ -5,14 +5,14 @@ import type { CapabilityToken, Frame, TokenClaims, -} from "@exadev/wire-mesh-core/generated/protocol"; -import type { Connection } from "@exadev/wire-mesh-core/ports/transport"; +} from "wire-mesh-core/generated/protocol"; +import type { Connection } from "wire-mesh-core/ports/transport"; import { createWebCryptoIdentity } from "../src/adapters/web-crypto-identity.js"; import { createBrowserTransport } from "../src/adapters/websocket-transport.js"; import { createMeshSession, type SessionEvent, -} from "@exadev/wire-mesh-core/domain/mesh-session"; +} from "wire-mesh-core/domain/mesh-session"; import { WEBRTC_SIGNAL_SCOPE, WEBRTC_SIGNAL_VERB, diff --git a/ts/packages/web-console/package.json b/ts/packages/web-console/package.json index dd010e0..58554b2 100644 --- a/ts/packages/web-console/package.json +++ b/ts/packages/web-console/package.json @@ -18,7 +18,7 @@ "_lint": "eslint . --fix --cache --max-warnings 0" }, "dependencies": { - "@exadev/wire-mesh-core": "workspace:*", + "wire-mesh-core": "workspace:*", "cbor2": "2.3.0" }, "devDependencies": { diff --git a/ts/packages/web-console/src/adapters/indexeddb-storage.ts b/ts/packages/web-console/src/adapters/indexeddb-storage.ts index b7d258f..a9a907c 100644 --- a/ts/packages/web-console/src/adapters/indexeddb-storage.ts +++ b/ts/packages/web-console/src/adapters/indexeddb-storage.ts @@ -1,6 +1,6 @@ // A browser KeyValueStorage implementation over IndexedDB -- the one storage the console has that survives a reload, unlike an in-process Map. One object store holds opaque Uint8Array values keyed by string, matching the port's contract exactly; nothing here interprets what's stored. -import type { KeyValueStorage } from "@exadev/wire-mesh-core/ports/storage"; +import type { KeyValueStorage } from "wire-mesh-core/ports/storage"; export interface IndexedDbStorageOptions { dbName?: string; diff --git a/ts/packages/web-console/src/adapters/web-crypto-identity.ts b/ts/packages/web-console/src/adapters/web-crypto-identity.ts index 37f21b9..aa0c1b5 100644 --- a/ts/packages/web-console/src/adapters/web-crypto-identity.ts +++ b/ts/packages/web-console/src/adapters/web-crypto-identity.ts @@ -1,12 +1,9 @@ // A Worker-runtime IdentityPort implementation using the standard Web Crypto API (globalThis.crypto.subtle), which exists identically in Cloudflare Workers and in Node >= 19 -- mirroring core's node-identity adapter's algorithm coverage (ES256 P-256 and Ed25519, the two algorithms identity-key.alg carries in the spec's own conformance vectors) so the two adapters are drop-in substitutes for each other behind the same port. import { cdeDecodeOptions, cdeEncodeOptions, decode, encode } from "cbor2"; -import type { - DeviceId, - IdentityKey, -} from "@exadev/wire-mesh-core/generated/protocol"; -import type { IdentityPort } from "@exadev/wire-mesh-core/ports/identity"; -import type { KeyValueStorage } from "@exadev/wire-mesh-core/ports/storage"; +import type { DeviceId, IdentityKey } from "wire-mesh-core/generated/protocol"; +import type { IdentityPort } from "wire-mesh-core/ports/identity"; +import type { KeyValueStorage } from "wire-mesh-core/ports/storage"; const ES256 = -7; const EDDSA = -8; diff --git a/ts/packages/web-console/src/adapters/webrtc-transport.ts b/ts/packages/web-console/src/adapters/webrtc-transport.ts index b12e445..8825163 100644 --- a/ts/packages/web-console/src/adapters/webrtc-transport.ts +++ b/ts/packages/web-console/src/adapters/webrtc-transport.ts @@ -2,13 +2,13 @@ // // Exactly like createBrowserTransport's connect() sets ws.binaryType before calling wrapWebSocket, the caller here (webrtc-negotiation.ts) must set channel.binaryType = "arraybuffer" explicitly -- not relied on as an unstated default -- on the still-mutable channel before handing it to wrapRtcDataChannel. This adapter takes a Readonly channel and never mutates it itself. -import type { Frame } from "@exadev/wire-mesh-core/generated/protocol"; -import type { Connection } from "@exadev/wire-mesh-core/ports/transport"; +import type { Frame } from "wire-mesh-core/generated/protocol"; +import type { Connection } from "wire-mesh-core/ports/transport"; import { SchemaInvalidFrameError, decodeMessage, messageFromFrame, -} from "@exadev/wire-mesh-core/adapters/frame-codec"; +} from "wire-mesh-core/adapters/frame-codec"; export function wrapRtcDataChannel( channel: Readonly, diff --git a/ts/packages/web-console/src/adapters/websocket-transport.ts b/ts/packages/web-console/src/adapters/websocket-transport.ts index 0732d92..0092747 100644 --- a/ts/packages/web-console/src/adapters/websocket-transport.ts +++ b/ts/packages/web-console/src/adapters/websocket-transport.ts @@ -1,16 +1,16 @@ // A browser Transport implementation over native WebSocket messages, the same convention as the hub's Worker-side adapter: each binary WebSocket message is already self-delimiting, so one message carries exactly one CBOR-encoded frame with no length prefix. Undecodable bytes are a connection-level failure (the receive iteration rejects and the socket closes), matching core's adapters' treatment of hostile wire input; a decodable frame that fails schema validation is dropped rather than disconnecting -- an unrecognised frame from a newer peer is what version negotiation exists to tolerate. -import type { Frame } from "@exadev/wire-mesh-core/generated/protocol"; +import type { Frame } from "wire-mesh-core/generated/protocol"; import type { Connection, Listener, Transport, -} from "@exadev/wire-mesh-core/ports/transport"; +} from "wire-mesh-core/ports/transport"; import { SchemaInvalidFrameError, decodeMessage, messageFromFrame, -} from "@exadev/wire-mesh-core/adapters/frame-codec"; +} from "wire-mesh-core/adapters/frame-codec"; // RFC 6455 close codes, named rather than bare: 1000 normal closure, 1002 protocol error. const CLOSE_NORMAL = 1000; diff --git a/ts/packages/web-console/src/main.ts b/ts/packages/web-console/src/main.ts index c0f5667..6041a82 100644 --- a/ts/packages/web-console/src/main.ts +++ b/ts/packages/web-console/src/main.ts @@ -1,13 +1,13 @@ -// The console's DOM wiring: one MeshSession per open connection, rendering each session's SessionEvent into its own status line, peer directory table, and frame log. Kept thin on purpose -- everything with behaviour lives in @exadev/wire-mesh-core's own mesh-session domain module so it can be tested without a browser. +// The console's DOM wiring: one MeshSession per open connection, rendering each session's SessionEvent into its own status line, peer directory table, and frame log. Kept thin on purpose -- everything with behaviour lives in wire-mesh-core's own mesh-session domain module so it can be tested without a browser. import { createIndexedDbStorage } from "./adapters/indexeddb-storage.js"; import { createPersistedWebCryptoIdentity } from "./adapters/web-crypto-identity.js"; import { createBrowserTransport } from "./adapters/websocket-transport.js"; -import { createMeshSession } from "@exadev/wire-mesh-core/domain/mesh-session"; +import { createMeshSession } from "wire-mesh-core/domain/mesh-session"; import type { ReconnectPolicy, SessionEvent, -} from "@exadev/wire-mesh-core/domain/mesh-session"; +} from "wire-mesh-core/domain/mesh-session"; // Passing the constructor rather than asserting: T appears in both the parameter and return, and the instanceof check makes the lookup self-verifying at runtime. function requireElement( diff --git a/ts/packages/web-console/src/webrtc-negotiation.ts b/ts/packages/web-console/src/webrtc-negotiation.ts index 4401b9a..58fb362 100644 --- a/ts/packages/web-console/src/webrtc-negotiation.ts +++ b/ts/packages/web-console/src/webrtc-negotiation.ts @@ -1,13 +1,13 @@ -// Drives a real RTCPeerConnection through the core/webrtc signaling exchange over an existing MeshSession's sendManageRequest/incomingManageRequests plumbing -- the one place in this package that both consumes the browser's WebRTC API and speaks the wire protocol, so it lives beside the adapters rather than in @exadev/wire-mesh-core's own mesh-session domain module (protocol-generic) or main.ts (DOM-only). One negotiator is constructed per session and, from construction, both offers new negotiations and answers incoming ones on that same session. The protocol itself carries no target-device field (a webrtc-offer's scope is "this node's own signaling", not a routed resource) -- addressing a specific peer when this session's own Connection is to a relay hub rather than to the peer directly is a MeshSession.sendManageRequest concern (its own targetDevice parameter), not something this module encodes on the wire. +// Drives a real RTCPeerConnection through the core/webrtc signaling exchange over an existing MeshSession's sendManageRequest/incomingManageRequests plumbing -- the one place in this package that both consumes the browser's WebRTC API and speaks the wire protocol, so it lives beside the adapters rather than in wire-mesh-core's own mesh-session domain module (protocol-generic) or main.ts (DOM-only). One negotiator is constructed per session and, from construction, both offers new negotiations and answers incoming ones on that same session. The protocol itself carries no target-device field (a webrtc-offer's scope is "this node's own signaling", not a routed resource) -- addressing a specific peer when this session's own Connection is to a relay hub rather than to the peer directly is a MeshSession.sendManageRequest concern (its own targetDevice parameter), not something this module encodes on the wire. -import type { Connection } from "@exadev/wire-mesh-core/ports/transport"; -import type { IdentityPort } from "@exadev/wire-mesh-core/ports/identity"; -import type { Clock } from "@exadev/wire-mesh-core/ports/clock"; +import type { Connection } from "wire-mesh-core/ports/transport"; +import type { IdentityPort } from "wire-mesh-core/ports/identity"; +import type { Clock } from "wire-mesh-core/ports/clock"; import { verifyCapabilityToken, type RevocationCheck, type VerifyCapabilityTokenOptions, -} from "@exadev/wire-mesh-core/domain/tokens"; +} from "wire-mesh-core/domain/tokens"; import type { CapabilityScope, DeviceId, @@ -17,11 +17,11 @@ import type { WebrtcAnswer, WebrtcIceCandidate, WebrtcOffer, -} from "@exadev/wire-mesh-core/generated/protocol"; +} from "wire-mesh-core/generated/protocol"; import type { IncomingManageRequest, MeshSession, -} from "@exadev/wire-mesh-core/domain/mesh-session"; +} from "wire-mesh-core/domain/mesh-session"; import { wrapRtcDataChannel } from "./adapters/webrtc-transport.js"; /** The one capability verb gating every core/webrtc message shape -- an authority over this node's own signaling as a whole, not three separate resources, mirroring how core/exec's exec:pty gates all of its own inner verbs. */ diff --git a/ts/packages/web-console/test/web-crypto-identity.test.ts b/ts/packages/web-console/test/web-crypto-identity.test.ts index 96cb617..8731407 100644 --- a/ts/packages/web-console/test/web-crypto-identity.test.ts +++ b/ts/packages/web-console/test/web-crypto-identity.test.ts @@ -12,7 +12,7 @@ import { createIndexedDbStorage } from "../src/adapters/indexeddb-storage.js"; import { createNodeIdentity, verifyWithPublicKey as verifyWithNodeIdentity, -} from "@exadev/wire-mesh-core/adapters/node-identity"; +} from "wire-mesh-core/adapters/node-identity"; import { bytesFromHex } from "./hex.js"; const ES256 = -7; diff --git a/ts/packages/web-console/test/webrtc-negotiation.test.ts b/ts/packages/web-console/test/webrtc-negotiation.test.ts index 6be660d..f1cfb66 100644 --- a/ts/packages/web-console/test/webrtc-negotiation.test.ts +++ b/ts/packages/web-console/test/webrtc-negotiation.test.ts @@ -7,12 +7,12 @@ import type { IceCandidateInit, ManageCommand, TokenClaims, -} from "@exadev/wire-mesh-core/generated/protocol"; -import type { IdentityPort } from "@exadev/wire-mesh-core/ports/identity"; -import type { Clock } from "@exadev/wire-mesh-core/ports/clock"; -import type { RevocationCheck } from "@exadev/wire-mesh-core/domain/tokens"; +} from "wire-mesh-core/generated/protocol"; +import type { IdentityPort } from "wire-mesh-core/ports/identity"; +import type { Clock } from "wire-mesh-core/ports/clock"; +import type { RevocationCheck } from "wire-mesh-core/domain/tokens"; import { createWebCryptoIdentity } from "../src/adapters/web-crypto-identity.js"; -import type { IncomingManageRequest } from "@exadev/wire-mesh-core/domain/mesh-session"; +import type { IncomingManageRequest } from "wire-mesh-core/domain/mesh-session"; import { WEBRTC_SIGNAL_SCOPE, WEBRTC_SIGNAL_VERB, diff --git a/ts/packages/web-console/test/webrtc-transport.test.ts b/ts/packages/web-console/test/webrtc-transport.test.ts index a4ef313..4e4da38 100644 --- a/ts/packages/web-console/test/webrtc-transport.test.ts +++ b/ts/packages/web-console/test/webrtc-transport.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it } from "vitest"; import { encode } from "cbor2"; -import type { Frame } from "@exadev/wire-mesh-core/generated/protocol"; +import type { Frame } from "wire-mesh-core/generated/protocol"; import { wrapRtcDataChannel } from "../src/adapters/webrtc-transport.js"; -import { messageFromFrame } from "@exadev/wire-mesh-core/adapters/frame-codec"; +import { messageFromFrame } from "wire-mesh-core/adapters/frame-codec"; import { FakeRtcDataChannel } from "./fake-rtc-data-channel.js"; import { bytesFromHex } from "./hex.js"; diff --git a/ts/packages/web-console/test/websocket-transport.test.ts b/ts/packages/web-console/test/websocket-transport.test.ts index 30e893f..a5b0172 100644 --- a/ts/packages/web-console/test/websocket-transport.test.ts +++ b/ts/packages/web-console/test/websocket-transport.test.ts @@ -1,11 +1,11 @@ import { describe, expect, it } from "vitest"; import { encode } from "cbor2"; -import type { Frame } from "@exadev/wire-mesh-core/generated/protocol"; +import type { Frame } from "wire-mesh-core/generated/protocol"; import { createBrowserTransport, wrapWebSocket, } from "../src/adapters/websocket-transport.js"; -import { messageFromFrame } from "@exadev/wire-mesh-core/adapters/frame-codec"; +import { messageFromFrame } from "wire-mesh-core/adapters/frame-codec"; import { FakeWebSocket } from "./fake-websocket.js"; import { bytesFromHex } from "./hex.js"; diff --git a/ts/pnpm-lock.yaml b/ts/pnpm-lock.yaml index d10e831..58b51a9 100644 --- a/ts/pnpm-lock.yaml +++ b/ts/pnpm-lock.yaml @@ -14,12 +14,12 @@ importers: packages/cloudflare-hub: dependencies: - '@exadev/wire-mesh-core': - specifier: workspace:* - version: link:../core cbor2: specifier: 2.3.0 version: 2.3.0 + wire-mesh-core: + specifier: workspace:* + version: link:../core devDependencies: '@cloudflare/workers-types': specifier: 5.20260905.1 @@ -136,12 +136,12 @@ importers: packages/node: dependencies: - '@exadev/wire-mesh-core': - specifier: workspace:* - version: link:../core cbor2: specifier: 2.3.0 version: 2.3.0 + wire-mesh-core: + specifier: workspace:* + version: link:../core ws: specifier: 8.21.3 version: 8.21.3 @@ -191,12 +191,12 @@ importers: packages/web-console: dependencies: - '@exadev/wire-mesh-core': - specifier: workspace:* - version: link:../core cbor2: specifier: 2.3.0 version: 2.3.0 + wire-mesh-core: + specifier: workspace:* + version: link:../core devDependencies: '@exadev/eslint-config': specifier: 2.10.6