anchordb-relay 1.0.6 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,22 +1,76 @@
1
1
  # anchordb-relay
2
2
 
3
- Development-only relay that connects an app running [AnchorDB](https://www.npmjs.com/package/anchordb)
4
- to Anchor Lens.
3
+ Development-only relay that lets Anchor Lens open the database of an app running
4
+ [AnchorDB](https://www.npmjs.com/package/anchordb) on a phone, an emulator or a browser.
5
5
 
6
6
  ```bash
7
- npx anchor-relay
7
+ npx anchor-relay --host 0.0.0.0 --room my-app
8
8
  ```
9
9
 
10
10
  ```
11
11
  Anchor Inspector Relay
12
12
  ──────────────────────
13
- listening ws://127.0.0.1:9440
14
- room k3Jf9Xq2mNp4
15
- agent URL ws://127.0.0.1:9440/relay?room=k3Jf9Xq2mNp4&role=agent
16
- Lens link anchor-lens://connect?relay=...&room=k3Jf9Xq2mNp4
17
- MongoDB off — start with --mongo-bridge to sync collections to a real MongoDB
13
+ listening ws://0.0.0.0:9440
14
+ room my-app
15
+
16
+ The app — inspector.relayUrl, or connectInspectorToRelay({ relayUrl }):
17
+ ws://192.168.1.24:9440/relay?room=my-app&role=agent
18
+
19
+ Anchor Lens — scan, or paste the link:
20
+ ▄▄▄▄▄▄▄ ▄▄▄ ▄ ▄▄▄▄▄▄▄
21
+ █ ▄▄▄ █ …QR code… █
22
+ anchor-lens://connect?relay=ws%3A%2F%2F192.168.1.24%3A9440%2Frelay%3Froom%3Dmy-app%26role%3Dclient&room=my-app
23
+ ```
24
+
25
+ ## Open an app in Lens
26
+
27
+ **1. Run the relay** where the phone can reach it — same Wi-Fi, and `--host 0.0.0.0`. The default
28
+ `127.0.0.1` is reachable only from the computer itself.
29
+
30
+ **2. Publish the app's database** with the agent URL the relay printed:
31
+
32
+ ```ts
33
+ export const db = createAnchorDB({
34
+ name: "my-app",
35
+ inspector: {
36
+ enabled: true,
37
+ relayUrl: "ws://192.168.1.24:9440/relay?room=my-app&role=agent",
38
+ onPairing: ({ code }) => showPairingCode(code), // or listen for the "inspector:pairing" event
39
+ },
40
+ });
41
+ ```
42
+
43
+ The database connects on construction, stays connected, and reconnects when the phone sleeps or the
44
+ relay restarts. To connect later instead — from a settings screen, say — call
45
+ `connectInspectorToRelay(db, { relayUrl, onPairing })` from `anchordb`.
46
+
47
+ **3. In Lens, scan the QR code**, then type the pairing code the app is showing. Nothing else is typed:
48
+ the challenge the code is signed against arrives from the app.
49
+
50
+ `--room` keeps the room the same across restarts, so the URL built into the app keeps working. Without
51
+ it the room is random each time.
52
+
53
+ ### Android release builds
54
+
55
+ The relay speaks plain `ws://`, which Android blocks in release builds. Allow it in a build meant for
56
+ inspection — in Expo, with `expo-build-properties`:
57
+
58
+ ```json
59
+ ["expo-build-properties", { "android": { "usesCleartextTraffic": true } }]
18
60
  ```
19
61
 
62
+ A release build also refuses to start the inspector unless `allowInProduction: true` is set, so an
63
+ inspector left on cannot ship by accident.
64
+
65
+ ## Options
66
+
67
+ | Flag | Default | |
68
+ | --- | --- | --- |
69
+ | `--host` | `127.0.0.1` | `0.0.0.0` to reach it from a phone |
70
+ | `--port` | `9440` | |
71
+ | `--room` | random | a fixed room id, 4–64 letters, digits, `_` or `-` |
72
+ | `--mongo-bridge` | off | see below |
73
+
20
74
  ## Why a relay exists
21
75
 
22
76
  React Native and browsers can open a WebSocket **client** but cannot **listen** without a native TCP
@@ -28,12 +82,13 @@ without the relay ever needing an update.
28
82
 
29
83
  ## What it deliberately does not do
30
84
 
31
- It **does not authenticate the inspector session.** Pairing is end-to-end between the app and Lens
32
- (an HMAC over a challenge), so a compromised or malicious relay still cannot issue itself a session.
33
- The room id only decides who is connected to whom; it is not the security boundary.
85
+ It **does not authenticate the inspector session.** Pairing is end-to-end between the app and Lens:
86
+ Lens proves it knows the code with an HMAC over the app's challenge. The code is never sent, so a
87
+ compromised or malicious relay still cannot issue itself a session, and the room id only decides who
88
+ is connected to whom.
34
89
 
35
- The QR payload carries the relay address and room — **never the pairing code**, which the app
36
- displays separately. Photographing the screen is therefore not enough to pair.
90
+ The QR payload carries the relay address and room — **never the pairing code**, which only the app
91
+ displays. Photographing the screen is therefore not enough to pair.
37
92
 
38
93
  ## The MongoDB bridge
39
94
 
@@ -52,20 +107,16 @@ driver runs here, and Lens drives it over `/bridge`:
52
107
  ```
53
108
 
54
109
  Both hops carry Extended JSON — the interchange format `anchordb` already cross-validates
55
- against the official `bson` package — so an ObjectId is still an ObjectId at the far end. Anchor's
56
- codec encodes on the Anchor side and MongoDB's own codec decodes on the MongoDB side; there is no
57
- third interpretation anywhere.
110
+ against the official `bson` package — so an ObjectId is still an ObjectId at the far end.
58
111
 
59
112
  ### Three restrictions, and why
60
113
 
61
114
  - **Off unless you ask for it.** A relay that will dial any MongoDB on request is a confused deputy:
62
115
  every process on the machine could use it to reach a database it has no credentials for.
63
- `--mongo-bridge` is the opt-in.
64
- - **The room is the token.** A bridge socket must present the room id the relay printed, so knowing
65
- the port is not enough.
116
+ - **The room is the token.** A bridge socket must present the room id the relay printed.
66
117
  - **The connection string is never stored and never logged.** It lives in one `MongoClient` for the
67
- life of one socket and dies with it. Every log line and every error message including connection
68
- failures, where a URI is most likely to escape — goes through `redactMongoUri`.
118
+ life of one socket and dies with it, and every log line and error message goes through
119
+ `redactMongoUri`.
69
120
 
70
121
  `--host 0.0.0.0` together with `--mongo-bridge` is a combination worth thinking twice about.
71
122
 
@@ -81,8 +132,8 @@ Development only. Never run this in production.
81
132
  ```ts
82
133
  import { InspectorRelay, startRelayServer } from "anchordb-relay";
83
134
 
84
- const server = await startRelayServer({ port: 9440 });
85
- const room = server.relay.createRoom("MyApp");
135
+ const server = await startRelayServer({ port: 9440, host: "0.0.0.0" });
136
+ const room = server.relay.createRoom("MyApp", { id: "my-app", keep: true });
86
137
  ```
87
138
 
88
139
  `InspectorRelay` is transport-agnostic and has no `ws` dependency, so the routing logic can be
@@ -90,15 +141,12 @@ driven by any socket implementation — or tested without opening a port.
90
141
 
91
142
  ## Status
92
143
 
93
- **1.0.0.** MIT.
94
-
95
- **37 tests.** Room routing and isolation, frame limits, and the MongoDB bridge: access control,
96
- streamed reads, all three write modes, session lifetime, and that a password reaches neither a log
97
- line nor an error message.
144
+ **1.2.0.** MIT.
98
145
 
99
- The bridge is tested against an injected fake driver that seam is why `MongoDriver` exists.
100
- Everything above the driver is exercised for real; **the driver calls themselves have never run
101
- against a live MongoDB**, because there is none on the machine this was built on.
146
+ Tested: room routing and isolation, frame limits, kept and chosen rooms, and a whole session over
147
+ real sockets a relay server, an app publishing itself, and a Lens client that pairs with only the
148
+ code, reads and writes, then shuts down cleanly. The MongoDB bridge is tested against an injected fake
149
+ driver; **its driver calls have never run against a live MongoDB.**
102
150
 
103
151
  ## The AnchorDB family
104
152
 
package/dist/cjs/cli.js CHANGED
@@ -1,13 +1,52 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
3
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
+ const node_os_1 = require("node:os");
4
38
  const server_ts_1 = require("./server.js");
5
39
  /**
6
40
  * `npx anchor-relay`
7
41
  *
8
- * Prints the room and the QR payload a developer scans. Binds to 127.0.0.1 by default: a relay
9
- * reachable from the whole network is a database reachable from the whole network, so opening it
10
- * up has to be a deliberate `--host 0.0.0.0`.
42
+ * Prints what each side needs: the app gets an agent URL, Lens gets a QR code to scan. Binds to
43
+ * 127.0.0.1 by default — a relay reachable from the whole network is a database reachable from the
44
+ * whole network so reaching it from a phone takes a deliberate `--host 0.0.0.0`.
45
+ *
46
+ * --host <addr> where to listen (default 127.0.0.1; use 0.0.0.0 for a phone)
47
+ * --port <n> default 9440
48
+ * --room <id> a fixed room, so an app's configured relay URL survives restarts
49
+ * --mongo-bridge enable the MongoDB bridge
11
50
  */
12
51
  const args = process.argv.slice(2);
13
52
  const readFlag = (name, fallback) => {
@@ -17,29 +56,72 @@ const readFlag = (name, fallback) => {
17
56
  const readSwitch = (name) => args.includes(`--${name}`);
18
57
  const port = Number(readFlag("port", "9440"));
19
58
  const host = readFlag("host", "127.0.0.1");
59
+ const roomFlag = readFlag("room", "");
20
60
  const mongoBridge = readSwitch("mongo-bridge");
61
+ /**
62
+ * Addresses a device can dial.
63
+ *
64
+ * Printing `ws://0.0.0.0:9440` — what the relay used to print when bound to every interface — gave the
65
+ * developer an address no phone can connect to. 0.0.0.0 is where the relay listens; the machine's
66
+ * network addresses are where it is reached.
67
+ */
68
+ function reachableHosts(bound) {
69
+ if (bound !== "0.0.0.0" && bound !== "::")
70
+ return [bound];
71
+ const found = [];
72
+ for (const entries of Object.values((0, node_os_1.networkInterfaces)())) {
73
+ for (const entry of entries ?? []) {
74
+ if (entry.family === "IPv4" && !entry.internal)
75
+ found.push(entry.address);
76
+ }
77
+ }
78
+ return found.length > 0 ? found : ["127.0.0.1"];
79
+ }
80
+ /** The QR code for Lens to scan. The link printed below it works without one. */
81
+ async function printQr(text) {
82
+ try {
83
+ const mod = (await Promise.resolve().then(() => __importStar(require("qrcode-terminal"))));
84
+ // Called as a method. generate reads its error-correction level from `this`, so a detached
85
+ // reference throws "bad rs block" — which is how the first version printed no code at all.
86
+ const renderer = mod.default ?? mod;
87
+ renderer.generate(text, { small: true }, (output) => console.log(output.replace(/^/gm, " ")));
88
+ }
89
+ catch (err) {
90
+ // Said out loud: a silently missing QR code looks like a relay that is not working.
91
+ console.log(` (QR code unavailable: ${err.message} — paste the link below instead)`);
92
+ }
93
+ }
21
94
  // Wrapped in a function rather than using top-level await: this file is emitted as both ESM and
22
95
  // CommonJS, and top-level await cannot be expressed in CJS at all.
23
96
  async function main() {
24
97
  const server = await (0, server_ts_1.startRelayServer)({ port, host, mongoBridge, onLog: (m) => console.log(` ${m}`) });
25
- const room = server.relay.createRoom("AnchorDB");
26
- const info = server.relay.connectionInfo(host, port, room);
98
+ const room = server.relay.createRoom("AnchorDB", { ...(roomFlag ? { id: roomFlag } : {}), keep: true });
99
+ const hosts = reachableHosts(host);
100
+ const primary = hosts[0];
101
+ const info = server.relay.connectionInfo(primary, port, room);
27
102
  console.log("\nAnchor Inspector Relay");
28
103
  console.log("──────────────────────");
29
104
  console.log(` listening ws://${host}:${port}`);
30
105
  console.log(` room ${room}`);
31
- console.log(` agent URL ws://${host}:${port}/relay?room=${room}&role=agent`);
32
- console.log(` Lens link ${info.deepLink}`);
106
+ console.log("\n The app — inspector.relayUrl, or connectInspectorToRelay({ relayUrl }):");
107
+ for (const address of hosts)
108
+ console.log(` ws://${address}:${port}/relay?room=${room}&role=agent`);
109
+ console.log("\n Anchor Lens — scan, or paste the link:");
110
+ await printQr(info.deepLink);
111
+ console.log(` ${info.deepLink}`);
33
112
  if (mongoBridge) {
34
- console.log(` MongoDB ws://${host}:${port}/bridge?room=${room}`);
35
- console.log("\n \x1b[33m! The MongoDB bridge is ON. Anything that can reach this relay and knows the\x1b[0m");
113
+ console.log(`\n MongoDB ws://${primary}:${port}/bridge?room=${room}`);
114
+ console.log(" \x1b[33m! The MongoDB bridge is ON. Anything that can reach this relay and knows the\x1b[0m");
36
115
  console.log(" \x1b[33m room can use this machine to reach a database you connect to.\x1b[0m");
37
116
  console.log(" Connection strings are never stored or logged — they live only while Lens is connected.");
38
117
  }
39
118
  else {
40
- console.log(" MongoDB off — start with --mongo-bridge to sync collections to a real MongoDB");
119
+ console.log("\n MongoDB off — start with --mongo-bridge to sync collections to a real MongoDB");
120
+ }
121
+ if (host === "127.0.0.1" || host === "localhost") {
122
+ console.log("\n \x1b[33m! Listening on 127.0.0.1 only: a phone cannot reach it. Restart with --host 0.0.0.0.\x1b[0m");
41
123
  }
42
- if (host !== "127.0.0.1") {
124
+ else {
43
125
  console.log("\n \x1b[33m! Bound beyond localhost — anyone on this network can reach the relay.\x1b[0m");
44
126
  }
45
127
  console.log("\n The pairing code is shown by the APP, not here: the QR alone must not be enough to pair.\n");
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -49,8 +49,19 @@ export declare class InspectorRelay {
49
49
  private readonly rooms;
50
50
  private readonly opts;
51
51
  constructor(options?: RelayOptions);
52
- /** Create a room for an app to publish itself into. The id goes into the QR code. */
53
- createRoom(agentName?: string): string;
52
+ /**
53
+ * Create a room for an app to publish itself into. The id goes into the QR code.
54
+ *
55
+ * `id` chooses the room, so an app configured with the agent URL keeps working across relay
56
+ * restarts. The default stays random: the room decides who is connected to whom, and a guessable one
57
+ * on a shared network lets a stranger reach the pairing step (though never past it without the code).
58
+ * `keep` exempts the room from reclamation — the room the CLI prints at startup must still exist
59
+ * when the app connects an hour later.
60
+ */
61
+ createRoom(agentName?: string, options?: {
62
+ id?: string;
63
+ keep?: boolean;
64
+ }): string;
54
65
  /** Does this room exist? The bridge uses it as an access token. */
55
66
  hasRoom(id: string): boolean;
56
67
  rooms_(): RoomInfo[];
@@ -1 +1 @@
1
- {"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/relay.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IAC7D,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC9C,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;CACzD;AAUD,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyE;gBAElF,OAAO,GAAE,YAAiB;IAQtC,qFAAqF;IACrF,UAAU,CAAC,SAAS,SAAa,GAAG,MAAM;IAQ1C,mEAAmE;IACnE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAK5B,MAAM,IAAI,QAAQ,EAAE;IAWpB;;;;;OAKG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAqCxG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ/B,OAAO,CAAC,IAAI;IAQZ,0FAA0F;IAC1F,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;QAC1D,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB;CAaF"}
1
+ {"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/relay.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IAC7D,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC9C,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;CACzD;AAYD,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyE;gBAElF,OAAO,GAAE,YAAiB;IAQtC;;;;;;;;OAQG;IACH,UAAU,CAAC,SAAS,SAAa,EAAE,OAAO,GAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,MAAM;IAYzF,mEAAmE;IACnE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAK5B,MAAM,IAAI,QAAQ,EAAE;IAWpB;;;;;OAKG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAqCxG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ/B,OAAO,CAAC,IAAI;IAQZ,0FAA0F;IAC1F,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;QAC1D,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB;CAaF"}
package/dist/cjs/relay.js CHANGED
@@ -17,11 +17,24 @@ class InspectorRelay {
17
17
  onLog: options.onLog ?? (() => undefined),
18
18
  };
19
19
  }
20
- /** Create a room for an app to publish itself into. The id goes into the QR code. */
21
- createRoom(agentName = "AnchorDB") {
20
+ /**
21
+ * Create a room for an app to publish itself into. The id goes into the QR code.
22
+ *
23
+ * `id` chooses the room, so an app configured with the agent URL keeps working across relay
24
+ * restarts. The default stays random: the room decides who is connected to whom, and a guessable one
25
+ * on a shared network lets a stranger reach the pairing step (though never past it without the code).
26
+ * `keep` exempts the room from reclamation — the room the CLI prints at startup must still exist
27
+ * when the app connects an hour later.
28
+ */
29
+ createRoom(agentName = "AnchorDB", options = {}) {
22
30
  this.reap();
23
- const id = (0, node_crypto_1.randomBytes)(9).toString("base64url");
24
- this.rooms.set(id, { id, agent: null, client: null, createdAt: Date.now(), agentName });
31
+ if (options.id !== undefined && !/^[A-Za-z0-9_-]{4,64}$/.test(options.id)) {
32
+ throw new Error(`Room id "${options.id}" must be 4 to 64 letters, digits, "_" or "-".`);
33
+ }
34
+ if (options.id !== undefined && this.rooms.has(options.id))
35
+ return options.id;
36
+ const id = options.id ?? (0, node_crypto_1.randomBytes)(9).toString("base64url");
37
+ this.rooms.set(id, { id, agent: null, client: null, createdAt: Date.now(), agentName, keep: options.keep ?? false });
25
38
  this.opts.onLog(`room ${id} created for "${agentName}"`);
26
39
  return id;
27
40
  }
@@ -94,7 +107,7 @@ class InspectorRelay {
94
107
  const now = Date.now();
95
108
  for (const [id, room] of this.rooms) {
96
109
  const stale = now - room.createdAt > this.opts.roomTtlMs;
97
- if (stale && !room.agent && !room.client)
110
+ if (stale && !room.keep && !room.agent && !room.client)
98
111
  this.rooms.delete(id);
99
112
  }
100
113
  }
@@ -1 +1 @@
1
- {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/relay.ts"],"names":[],"mappings":";;;AAAA,6CAA0C;AAwD1C;;;;;GAKG;AACH,MAAa,cAAc;IAIzB,YAAY,UAAwB,EAAE;QAHrB,UAAK,GAAG,IAAI,GAAG,EAAgB,CAAC;QAI/C,IAAI,CAAC,IAAI,GAAG;YACV,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE,GAAG,MAAM;YAC3C,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;YACvD,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC;SAC1C,CAAC;IACJ,CAAC;IAED,qFAAqF;IACrF,UAAU,CAAC,SAAS,GAAG,UAAU;QAC/B,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,MAAM,EAAE,GAAG,IAAA,yBAAW,EAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QACxF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,iBAAiB,SAAS,GAAG,CAAC,CAAC;QACzD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,mEAAmE;IACnE,OAAO,CAAC,EAAU;QAChB,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1C,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,cAAc,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI;YAChC,eAAe,EAAE,CAAC,CAAC,MAAM,KAAK,IAAI;YAClC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS;SAChC,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;;;;OAKG;IACH,IAAI,CAAC,MAAc,EAAE,IAAe,EAAE,MAAmB;QACvD,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QACxD,IAAI,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,oCAAoC,EAAE,CAAC;QAE5F,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,MAAM,KAAK,IAAI,SAAS,CAAC,CAAC;QAElD,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;YAC5B,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC7D,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;gBAC3C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,MAAM,cAAc,KAAK,CAAC,MAAM,gBAAgB,CAAC,CAAC;gBAC1E,OAAO;YACT,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACzD,sEAAsE;YACtE,IAAI,IAAI;gBAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACtB,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,MAAM;gBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YAC7C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,MAAM,KAAK,IAAI,OAAO,CAAC,CAAC;YAChD,4FAA4F;YAC5F,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACpC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;gBAC9C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACrB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACtB,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,MAAM;gBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,SAAS,CAAC,MAAc;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAEO,IAAI;QACV,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;YACzD,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,0FAA0F;IAC1F,cAAc,CAAC,IAAY,EAAE,IAAY,EAAE,MAAc;QAKvD,MAAM,GAAG,GAAG,QAAQ,IAAI,IAAI,IAAI,eAAe,MAAM,cAAc,CAAC;QACpE,OAAO;YACL,GAAG;YACH,IAAI,EAAE,MAAM;YACZ;;;;eAIG;YACH,QAAQ,EAAE,+BAA+B,kBAAkB,CAAC,GAAG,CAAC,SAAS,MAAM,EAAE;SAClF,CAAC;IACJ,CAAC;CACF;AAnHD,wCAmHC"}
1
+ {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/relay.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAoB,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;;;GAKG;AACH,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,CAoE7F"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAoB,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;;;GAKG;AACH,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,CA2E7F"}
@@ -90,7 +90,14 @@ async function startRelayServer(options = {}) {
90
90
  port,
91
91
  host,
92
92
  close: () => new Promise((resolve) => {
93
- wss.close(() => http.close(() => resolve()));
93
+ // Neither wss.close nor http.close ends established connections, so with an app or Lens
94
+ // attached the relay never finished closing — Ctrl+C hung. End them explicitly.
95
+ for (const client of wss.clients)
96
+ client.terminate();
97
+ wss.close(() => {
98
+ http.close(() => resolve());
99
+ http.closeAllConnections();
100
+ });
94
101
  }),
95
102
  };
96
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
package/dist/esm/cli.js CHANGED
@@ -1,11 +1,17 @@
1
1
  #!/usr/bin/env node
2
+ import { networkInterfaces } from "node:os";
2
3
  import { startRelayServer } from "./server.js";
3
4
  /**
4
5
  * `npx anchor-relay`
5
6
  *
6
- * Prints the room and the QR payload a developer scans. Binds to 127.0.0.1 by default: a relay
7
- * reachable from the whole network is a database reachable from the whole network, so opening it
8
- * up has to be a deliberate `--host 0.0.0.0`.
7
+ * Prints what each side needs: the app gets an agent URL, Lens gets a QR code to scan. Binds to
8
+ * 127.0.0.1 by default — a relay reachable from the whole network is a database reachable from the
9
+ * whole network so reaching it from a phone takes a deliberate `--host 0.0.0.0`.
10
+ *
11
+ * --host <addr> where to listen (default 127.0.0.1; use 0.0.0.0 for a phone)
12
+ * --port <n> default 9440
13
+ * --room <id> a fixed room, so an app's configured relay URL survives restarts
14
+ * --mongo-bridge enable the MongoDB bridge
9
15
  */
10
16
  const args = process.argv.slice(2);
11
17
  const readFlag = (name, fallback) => {
@@ -15,29 +21,72 @@ const readFlag = (name, fallback) => {
15
21
  const readSwitch = (name) => args.includes(`--${name}`);
16
22
  const port = Number(readFlag("port", "9440"));
17
23
  const host = readFlag("host", "127.0.0.1");
24
+ const roomFlag = readFlag("room", "");
18
25
  const mongoBridge = readSwitch("mongo-bridge");
26
+ /**
27
+ * Addresses a device can dial.
28
+ *
29
+ * Printing `ws://0.0.0.0:9440` — what the relay used to print when bound to every interface — gave the
30
+ * developer an address no phone can connect to. 0.0.0.0 is where the relay listens; the machine's
31
+ * network addresses are where it is reached.
32
+ */
33
+ function reachableHosts(bound) {
34
+ if (bound !== "0.0.0.0" && bound !== "::")
35
+ return [bound];
36
+ const found = [];
37
+ for (const entries of Object.values(networkInterfaces())) {
38
+ for (const entry of entries ?? []) {
39
+ if (entry.family === "IPv4" && !entry.internal)
40
+ found.push(entry.address);
41
+ }
42
+ }
43
+ return found.length > 0 ? found : ["127.0.0.1"];
44
+ }
45
+ /** The QR code for Lens to scan. The link printed below it works without one. */
46
+ async function printQr(text) {
47
+ try {
48
+ const mod = (await import("qrcode-terminal"));
49
+ // Called as a method. generate reads its error-correction level from `this`, so a detached
50
+ // reference throws "bad rs block" — which is how the first version printed no code at all.
51
+ const renderer = mod.default ?? mod;
52
+ renderer.generate(text, { small: true }, (output) => console.log(output.replace(/^/gm, " ")));
53
+ }
54
+ catch (err) {
55
+ // Said out loud: a silently missing QR code looks like a relay that is not working.
56
+ console.log(` (QR code unavailable: ${err.message} — paste the link below instead)`);
57
+ }
58
+ }
19
59
  // Wrapped in a function rather than using top-level await: this file is emitted as both ESM and
20
60
  // CommonJS, and top-level await cannot be expressed in CJS at all.
21
61
  async function main() {
22
62
  const server = await startRelayServer({ port, host, mongoBridge, onLog: (m) => console.log(` ${m}`) });
23
- const room = server.relay.createRoom("AnchorDB");
24
- const info = server.relay.connectionInfo(host, port, room);
63
+ const room = server.relay.createRoom("AnchorDB", { ...(roomFlag ? { id: roomFlag } : {}), keep: true });
64
+ const hosts = reachableHosts(host);
65
+ const primary = hosts[0];
66
+ const info = server.relay.connectionInfo(primary, port, room);
25
67
  console.log("\nAnchor Inspector Relay");
26
68
  console.log("──────────────────────");
27
69
  console.log(` listening ws://${host}:${port}`);
28
70
  console.log(` room ${room}`);
29
- console.log(` agent URL ws://${host}:${port}/relay?room=${room}&role=agent`);
30
- console.log(` Lens link ${info.deepLink}`);
71
+ console.log("\n The app — inspector.relayUrl, or connectInspectorToRelay({ relayUrl }):");
72
+ for (const address of hosts)
73
+ console.log(` ws://${address}:${port}/relay?room=${room}&role=agent`);
74
+ console.log("\n Anchor Lens — scan, or paste the link:");
75
+ await printQr(info.deepLink);
76
+ console.log(` ${info.deepLink}`);
31
77
  if (mongoBridge) {
32
- console.log(` MongoDB ws://${host}:${port}/bridge?room=${room}`);
33
- console.log("\n \x1b[33m! The MongoDB bridge is ON. Anything that can reach this relay and knows the\x1b[0m");
78
+ console.log(`\n MongoDB ws://${primary}:${port}/bridge?room=${room}`);
79
+ console.log(" \x1b[33m! The MongoDB bridge is ON. Anything that can reach this relay and knows the\x1b[0m");
34
80
  console.log(" \x1b[33m room can use this machine to reach a database you connect to.\x1b[0m");
35
81
  console.log(" Connection strings are never stored or logged — they live only while Lens is connected.");
36
82
  }
37
83
  else {
38
- console.log(" MongoDB off — start with --mongo-bridge to sync collections to a real MongoDB");
84
+ console.log("\n MongoDB off — start with --mongo-bridge to sync collections to a real MongoDB");
39
85
  }
40
- if (host !== "127.0.0.1") {
86
+ if (host === "127.0.0.1" || host === "localhost") {
87
+ console.log("\n \x1b[33m! Listening on 127.0.0.1 only: a phone cannot reach it. Restart with --host 0.0.0.0.\x1b[0m");
88
+ }
89
+ else {
41
90
  console.log("\n \x1b[33m! Bound beyond localhost — anyone on this network can reach the relay.\x1b[0m");
42
91
  }
43
92
  console.log("\n The pairing code is shown by the APP, not here: the QR alone must not be enough to pair.\n");
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -49,8 +49,19 @@ export declare class InspectorRelay {
49
49
  private readonly rooms;
50
50
  private readonly opts;
51
51
  constructor(options?: RelayOptions);
52
- /** Create a room for an app to publish itself into. The id goes into the QR code. */
53
- createRoom(agentName?: string): string;
52
+ /**
53
+ * Create a room for an app to publish itself into. The id goes into the QR code.
54
+ *
55
+ * `id` chooses the room, so an app configured with the agent URL keeps working across relay
56
+ * restarts. The default stays random: the room decides who is connected to whom, and a guessable one
57
+ * on a shared network lets a stranger reach the pairing step (though never past it without the code).
58
+ * `keep` exempts the room from reclamation — the room the CLI prints at startup must still exist
59
+ * when the app connects an hour later.
60
+ */
61
+ createRoom(agentName?: string, options?: {
62
+ id?: string;
63
+ keep?: boolean;
64
+ }): string;
54
65
  /** Does this room exist? The bridge uses it as an access token. */
55
66
  hasRoom(id: string): boolean;
56
67
  rooms_(): RoomInfo[];
@@ -1 +1 @@
1
- {"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/relay.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IAC7D,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC9C,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;CACzD;AAUD,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyE;gBAElF,OAAO,GAAE,YAAiB;IAQtC,qFAAqF;IACrF,UAAU,CAAC,SAAS,SAAa,GAAG,MAAM;IAQ1C,mEAAmE;IACnE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAK5B,MAAM,IAAI,QAAQ,EAAE;IAWpB;;;;;OAKG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAqCxG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ/B,OAAO,CAAC,IAAI;IAQZ,0FAA0F;IAC1F,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;QAC1D,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB;CAaF"}
1
+ {"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/relay.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IAC7D,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC9C,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;CACzD;AAYD,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyE;gBAElF,OAAO,GAAE,YAAiB;IAQtC;;;;;;;;OAQG;IACH,UAAU,CAAC,SAAS,SAAa,EAAE,OAAO,GAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,MAAM;IAYzF,mEAAmE;IACnE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAK5B,MAAM,IAAI,QAAQ,EAAE;IAWpB;;;;;OAKG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAqCxG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ/B,OAAO,CAAC,IAAI;IAQZ,0FAA0F;IAC1F,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;QAC1D,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB;CAaF"}
package/dist/esm/relay.js CHANGED
@@ -14,11 +14,24 @@ export class InspectorRelay {
14
14
  onLog: options.onLog ?? (() => undefined),
15
15
  };
16
16
  }
17
- /** Create a room for an app to publish itself into. The id goes into the QR code. */
18
- createRoom(agentName = "AnchorDB") {
17
+ /**
18
+ * Create a room for an app to publish itself into. The id goes into the QR code.
19
+ *
20
+ * `id` chooses the room, so an app configured with the agent URL keeps working across relay
21
+ * restarts. The default stays random: the room decides who is connected to whom, and a guessable one
22
+ * on a shared network lets a stranger reach the pairing step (though never past it without the code).
23
+ * `keep` exempts the room from reclamation — the room the CLI prints at startup must still exist
24
+ * when the app connects an hour later.
25
+ */
26
+ createRoom(agentName = "AnchorDB", options = {}) {
19
27
  this.reap();
20
- const id = randomBytes(9).toString("base64url");
21
- this.rooms.set(id, { id, agent: null, client: null, createdAt: Date.now(), agentName });
28
+ if (options.id !== undefined && !/^[A-Za-z0-9_-]{4,64}$/.test(options.id)) {
29
+ throw new Error(`Room id "${options.id}" must be 4 to 64 letters, digits, "_" or "-".`);
30
+ }
31
+ if (options.id !== undefined && this.rooms.has(options.id))
32
+ return options.id;
33
+ const id = options.id ?? randomBytes(9).toString("base64url");
34
+ this.rooms.set(id, { id, agent: null, client: null, createdAt: Date.now(), agentName, keep: options.keep ?? false });
22
35
  this.opts.onLog(`room ${id} created for "${agentName}"`);
23
36
  return id;
24
37
  }
@@ -91,7 +104,7 @@ export class InspectorRelay {
91
104
  const now = Date.now();
92
105
  for (const [id, room] of this.rooms) {
93
106
  const stale = now - room.createdAt > this.opts.roomTtlMs;
94
- if (stale && !room.agent && !room.client)
107
+ if (stale && !room.keep && !room.agent && !room.client)
95
108
  this.rooms.delete(id);
96
109
  }
97
110
  }
@@ -1 +1 @@
1
- {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/relay.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/relay.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAoB,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;;;GAKG;AACH,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,CAoE7F"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAoB,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;;;GAKG;AACH,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,CA2E7F"}
@@ -54,7 +54,14 @@ export async function startRelayServer(options = {}) {
54
54
  port,
55
55
  host,
56
56
  close: () => new Promise((resolve) => {
57
- wss.close(() => http.close(() => resolve()));
57
+ // Neither wss.close nor http.close ends established connections, so with an app or Lens
58
+ // attached the relay never finished closing — Ctrl+C hung. End them explicitly.
59
+ for (const client of wss.clients)
60
+ client.terminate();
61
+ wss.close(() => {
62
+ http.close(() => resolve());
63
+ http.closeAllConnections();
64
+ });
58
65
  }),
59
66
  };
60
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anchordb-relay",
3
- "version": "1.0.6",
3
+ "version": "1.2.0",
4
4
  "description": "Development-only relay that brokers Anchor Inspector connections between a mobile app and Anchor Lens.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -39,7 +39,8 @@
39
39
  "prepublishOnly": "npm run typecheck && npm run build"
40
40
  },
41
41
  "dependencies": {
42
- "anchordb": "^1.0.6",
42
+ "anchordb": "^1.2.0",
43
+ "qrcode-terminal": "^0.12.0",
43
44
  "ws": "^8.18.0"
44
45
  },
45
46
  "devDependencies": {