@volter/teams 0.2.50 → 0.2.52

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/board-owner.mjs CHANGED
@@ -1,7 +1,8 @@
1
1
  // A home's board owner (`supercode workflow serve`, one per install: D152) answers every card verb on that home's boards
2
2
  // over one local socket. The CLI and the machine daemon's board door hold nothing: each sends the verb here and renders
3
3
  // the answer. The socket is the home's own (`<home>/board.sock`, beside the owner's lock `<home>/board.lock`), by the
4
- // home's real path, so every process naming the home reaches the one owner whatever its environment.
4
+ // home's real path, so every process naming the home reaches the one owner whatever its environment. On Windows, where
5
+ // Node listens only on named pipes, it is the pipe named by that path.
5
6
  //
6
7
  // request: one JSON line { v: 1, argv | tool, board, caller, session, facts, cwd, stdin }
7
8
  // argv the verb and its arguments, without --root or --board
@@ -19,6 +20,7 @@
19
20
  import { existsSync, realpathSync } from 'node:fs';
20
21
  import { connect } from 'node:net';
21
22
  import { join, resolve } from 'node:path';
23
+ import { shortSocketPath } from './home.mjs';
22
24
 
23
25
  /** A Unix socket's path is at most 104 bytes on macOS (108 on Linux), terminator included. */
24
26
  const SOCKET_PATH_MAX = 103;
@@ -30,6 +32,9 @@ export function boardHome(root) {
30
32
 
31
33
  /** The owner's socket for the home at `root`: the home's own, by its real path. */
32
34
  export function boardOwnerSocket(root) {
35
+ // Node on Windows listens only on named pipes (on a socket path it is refused, EACCES): there the owner's door is the
36
+ // pipe named by that path, as the machine daemon's is
37
+ if (process.platform === 'win32') return shortSocketPath(boardHome(root), 'board.sock');
33
38
  const path = join(boardHome(root), 'board.sock');
34
39
  if (Buffer.byteLength(path) > SOCKET_PATH_MAX) throw new Error(`the home's board socket ${path} is longer than a Unix socket path may be (${SOCKET_PATH_MAX} bytes); keep the home at a shorter path`);
35
40
  return path;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/teams",
3
- "version": "0.2.50",
3
+ "version": "0.2.52",
4
4
  "type": "module",
5
5
  "description": "Volter Teams, the neutral team plane: machine identity and daemon core, the local door and server link, admission from machine grants, product doors, and the Teams server's neutral routes (company RFC 0008).",
6
6
  "license": "MIT",
@@ -2,6 +2,11 @@
2
2
  // the hosted viewer uses, exported so a workplace that draws the session itself (RH2's Conversation, supercode-ui in
3
3
  // its own tree) reads and labels it the same way. No imports: it runs as the viewer's own module and in a host's bundle.
4
4
 
5
+ // A signal that aborts `ms` from now, for use inside AbortSignal.any(). Its timer holds its controller, so it fires
6
+ // whatever the garbage collector does. AbortSignal.timeout() inside AbortSignal.any() does not on Node 23.9: the timeout
7
+ // signal is collected, the combined signal never aborts, and a request to a server that went quiet never ends.
8
+ const timeoutSignal=ms=>{const controller=new AbortController(),timer=setTimeout(()=>controller.abort(new DOMException('The operation was aborted due to timeout','TimeoutError')),ms);timer.unref?.();return controller.signal;};
9
+
5
10
  /**
6
11
  * Follow one session: its snapshot read whole (`/messages?tail=`, a busy session's is over the follow stream's 1 MB
7
12
  * buffer), then its follow stream from that snapshot's cursor, each change meaning "read again". The stream ends when
@@ -25,7 +30,7 @@ export function followTeamSession({ origin, teamId, sessionId, token, tail = 300
25
30
  let snapshot;
26
31
  do {
27
32
  requested = false;
28
- const response = await fetchImpl(`${base}/messages?tail=${tail}`, { headers: await headers(), signal: AbortSignal.any([controller.signal, AbortSignal.timeout(15000)]) });
33
+ const response = await fetchImpl(`${base}/messages?tail=${tail}`, { headers: await headers(), signal: AbortSignal.any([controller.signal, timeoutSignal(15000)]) });
29
34
  if (!response.ok) throw failure('read', response.status, `reading the session failed (${response.status})`);
30
35
  const body = await response.json();
31
36
  if (controller.signal.aborted) throw new DOMException('Session follow stopped', 'AbortError');