@claxedo/workspace-relay 0.7.0 → 0.8.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.
@@ -100,8 +100,16 @@ export type WorkspaceRelayDurableObjectRoomOptions = WorkspaceRelayOptions & {
100
100
  /**
101
101
  * Interval for the alarm-based revocation re-check that covers hibernated
102
102
  * connections, where `setInterval` watchers cannot survive. 0 disables it.
103
+ * The hibernated host-generation check rides the same alarm.
103
104
  */
104
105
  hibernatedRevocationCheckIntervalMs?: number;
106
+ /**
107
+ * How often an established host tunnel's serving generation is re-checked
108
+ * against `resolveHostGeneration` on the non-hibernating path. Defaults to
109
+ * 30s; 0 disables it. The lookup may answer from its cache, so a superseded
110
+ * tunnel closes within this interval plus the lookup's cache TTL.
111
+ */
112
+ hostGenerationCheckIntervalMs?: number;
105
113
  /**
106
114
  * Durable Object alarm surface, supplied by the Worker (`state.storage`) so the
107
115
  * room can schedule the hibernation-safe revocation re-check. Absent on the
@@ -146,6 +154,11 @@ export type WorkspaceRelaySocketAttachment = {
146
154
  hostId: string;
147
155
  workspaceIds: string[];
148
156
  connectedAt: number;
157
+ /** Fence pair from the admitting Host Tunnel Token; absent on sockets attached before the fence existed. */
158
+ enrollmentId?: string;
159
+ generation?: number;
160
+ /** Consecutive unavailable generation lookups, persisted so hibernation cannot reset the outage grace. */
161
+ generationCheckFailures?: number;
149
162
  } | {
150
163
  kind: "user-hosted-client";
151
164
  channelId: string;
@@ -201,7 +214,7 @@ export declare function createWorkspaceRelayDurableObjectRoom(options: Workspace
201
214
  webSocketMessage(socket: WorkspaceRelayDurableObjectSocket, message: string | ArrayBuffer): Promise<void>;
202
215
  /**
203
216
  * Durable Object alarm entry point. Runs the hibernation-safe revocation
204
- * sweep (W6b.2). The Worker must forward `alarm()` here.
217
+ * sweep. The Worker must forward `alarm()` here.
205
218
  */
206
219
  alarm(): Promise<void>;
207
220
  webSocketClose(socket: WorkspaceRelayDurableObjectSocket, code: number, reason: string): void;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * One tunnel's presence, recorded once per workspace it serves. `workspaceIds`
3
+ * is the full set that tunnel registered, so a reader that found the entry
4
+ * through one workspace still sees the others.
5
+ */
1
6
  export type HostTunnelPresence = {
2
7
  hostId: string;
3
8
  workspaceIds: string[];
@@ -5,13 +10,21 @@ export type HostTunnelPresence = {
5
10
  lastPongAt: number;
6
11
  expiresAt: number;
7
12
  };
13
+ /**
14
+ * Presence is keyed by (host, workspace): one host may hold a separate tunnel
15
+ * per workspace on a Bun relay, and a later registration for a workspace takes
16
+ * that workspace over without touching the host's other entries. `recordPong`
17
+ * and `disconnectHost` take the optional workspace set for the same reason —
18
+ * without it they act on every entry of the host, which is what a
19
+ * single-workspace Cloudflare room wants.
20
+ */
8
21
  export type WorkspaceRelayDirectory = {
9
22
  registerHostTunnel(input: {
10
23
  hostId: string;
11
24
  workspaceIds: string[];
12
25
  }): HostTunnelPresence;
13
- recordPong(hostId: string): HostTunnelPresence | undefined;
14
- disconnectHost(hostId: string): void;
26
+ recordPong(hostId: string, workspaceIds?: string[]): HostTunnelPresence | undefined;
27
+ disconnectHost(hostId: string, workspaceIds?: string[]): void;
15
28
  activeHost(input: {
16
29
  hostId: string;
17
30
  workspaceId: string;
@@ -29,10 +42,8 @@ export type WorkspaceRelayDirectory = {
29
42
  */
30
43
  dispose(): void;
31
44
  /**
32
- * T31: count of currently-active (non-expired) host presence entries.
33
- * Equivalent to running `sweep()` then returning the residual map size, but
34
- * implemented as a single pass without mutating eviction state when the
35
- * caller only wants a snapshot. Surfaced via the `/metrics` endpoint as
45
+ * Count of hosts with at least one non-expired presence entry, taken as a
46
+ * snapshot without evicting. Surfaced via `/metrics` as
36
47
  * `directory.activeHostCount`.
37
48
  */
38
49
  size(): number;
package/dist/http.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export declare function bearerToken(header: string | null | undefined): string | undefined;
1
+ import { bearerToken } from "@claxedo/helpers/string";
2
+ export { bearerToken };
2
3
  export declare function errorBody(code: string, message: string): {
3
4
  error: {
4
5
  code: string;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from "./auth";
2
- export * from "./bun";
3
2
  export * from "./cloudflare";
4
3
  export * from "./cors-origins";
5
4
  export * from "./directory";