@procedures/peer 0.0.0-stage → 0.1.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.
Files changed (135) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/LICENSE +21 -0
  3. package/README.md +725 -2
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/connection/index.d.ts +45 -0
  6. package/dist/connection/index.d.ts.map +1 -0
  7. package/dist/connection/index.js +148 -0
  8. package/dist/connection/index.js.map +1 -0
  9. package/dist/discovery/index.d.ts +30 -0
  10. package/dist/discovery/index.d.ts.map +1 -0
  11. package/dist/discovery/index.js +101 -0
  12. package/dist/discovery/index.js.map +1 -0
  13. package/dist/expose.d.ts +14 -0
  14. package/dist/expose.d.ts.map +1 -0
  15. package/dist/expose.js +16 -0
  16. package/dist/expose.js.map +1 -0
  17. package/dist/index.d.ts +15 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +20 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/input-schemas.d.ts +21 -0
  22. package/dist/input-schemas.d.ts.map +1 -0
  23. package/dist/input-schemas.js +80 -0
  24. package/dist/input-schemas.js.map +1 -0
  25. package/dist/lockfile.d.ts +48 -0
  26. package/dist/lockfile.d.ts.map +1 -0
  27. package/dist/lockfile.js +115 -0
  28. package/dist/lockfile.js.map +1 -0
  29. package/dist/manifest/index.d.ts +8 -0
  30. package/dist/manifest/index.d.ts.map +1 -0
  31. package/dist/manifest/index.js +8 -0
  32. package/dist/manifest/index.js.map +1 -0
  33. package/dist/manifest/json.d.ts +27 -0
  34. package/dist/manifest/json.d.ts.map +1 -0
  35. package/dist/manifest/json.js +24 -0
  36. package/dist/manifest/json.js.map +1 -0
  37. package/dist/manifest/typescript.d.ts +17 -0
  38. package/dist/manifest/typescript.d.ts.map +1 -0
  39. package/dist/manifest/typescript.js +123 -0
  40. package/dist/manifest/typescript.js.map +1 -0
  41. package/dist/module.d.ts +20 -0
  42. package/dist/module.d.ts.map +1 -0
  43. package/dist/module.js +42 -0
  44. package/dist/module.js.map +1 -0
  45. package/dist/output-schemas.d.ts +21 -0
  46. package/dist/output-schemas.d.ts.map +1 -0
  47. package/dist/output-schemas.js +85 -0
  48. package/dist/output-schemas.js.map +1 -0
  49. package/dist/peer/index.d.ts +47 -0
  50. package/dist/peer/index.d.ts.map +1 -0
  51. package/dist/peer/index.js +234 -0
  52. package/dist/peer/index.js.map +1 -0
  53. package/dist/peer/security.d.ts +25 -0
  54. package/dist/peer/security.d.ts.map +1 -0
  55. package/dist/peer/security.js +58 -0
  56. package/dist/peer/security.js.map +1 -0
  57. package/dist/procedures/index.d.ts +24 -0
  58. package/dist/procedures/index.d.ts.map +1 -0
  59. package/dist/procedures/index.js +15 -0
  60. package/dist/procedures/index.js.map +1 -0
  61. package/dist/procedures/manifest.generate.d.ts +11 -0
  62. package/dist/procedures/manifest.generate.d.ts.map +1 -0
  63. package/dist/procedures/manifest.generate.js +97 -0
  64. package/dist/procedures/manifest.generate.js.map +1 -0
  65. package/dist/procedures/server.call.d.ts +30 -0
  66. package/dist/procedures/server.call.d.ts.map +1 -0
  67. package/dist/procedures/server.call.js +60 -0
  68. package/dist/procedures/server.call.js.map +1 -0
  69. package/dist/procedures/server.connect.d.ts +11 -0
  70. package/dist/procedures/server.connect.d.ts.map +1 -0
  71. package/dist/procedures/server.connect.js +35 -0
  72. package/dist/procedures/server.connect.js.map +1 -0
  73. package/dist/procedures/server.connections.d.ts +22 -0
  74. package/dist/procedures/server.connections.d.ts.map +1 -0
  75. package/dist/procedures/server.connections.js +38 -0
  76. package/dist/procedures/server.connections.js.map +1 -0
  77. package/dist/procedures/server.create.d.ts +20 -0
  78. package/dist/procedures/server.create.d.ts.map +1 -0
  79. package/dist/procedures/server.create.js +64 -0
  80. package/dist/procedures/server.create.js.map +1 -0
  81. package/dist/procedures/server.disconnect.d.ts +11 -0
  82. package/dist/procedures/server.disconnect.d.ts.map +1 -0
  83. package/dist/procedures/server.disconnect.js +22 -0
  84. package/dist/procedures/server.disconnect.js.map +1 -0
  85. package/dist/procedures/server.start.d.ts +13 -0
  86. package/dist/procedures/server.start.d.ts.map +1 -0
  87. package/dist/procedures/server.start.js +179 -0
  88. package/dist/procedures/server.start.js.map +1 -0
  89. package/dist/procedures/server.status.d.ts +12 -0
  90. package/dist/procedures/server.status.d.ts.map +1 -0
  91. package/dist/procedures/server.status.js +116 -0
  92. package/dist/procedures/server.status.js.map +1 -0
  93. package/dist/procedures/server.stop.d.ts +11 -0
  94. package/dist/procedures/server.stop.d.ts.map +1 -0
  95. package/dist/procedures/server.stop.js +96 -0
  96. package/dist/procedures/server.stop.js.map +1 -0
  97. package/dist/register.d.ts +8 -0
  98. package/dist/register.d.ts.map +1 -0
  99. package/dist/register.js +14 -0
  100. package/dist/register.js.map +1 -0
  101. package/dist/schema.d.ts +14 -0
  102. package/dist/schema.d.ts.map +1 -0
  103. package/dist/schema.js +14 -0
  104. package/dist/schema.js.map +1 -0
  105. package/dist/types.d.ts +192 -0
  106. package/dist/types.d.ts.map +1 -0
  107. package/dist/types.js +5 -0
  108. package/dist/types.js.map +1 -0
  109. package/package.json +87 -3
  110. package/src/connection/index.ts +219 -0
  111. package/src/discovery/index.ts +137 -0
  112. package/src/expose.ts +17 -0
  113. package/src/index.ts +69 -0
  114. package/src/input-schemas.ts +121 -0
  115. package/src/lockfile.ts +129 -0
  116. package/src/manifest/index.ts +8 -0
  117. package/src/manifest/json.ts +39 -0
  118. package/src/manifest/typescript.ts +148 -0
  119. package/src/module.ts +46 -0
  120. package/src/output-schemas.ts +110 -0
  121. package/src/peer/index.ts +325 -0
  122. package/src/peer/security.ts +58 -0
  123. package/src/procedures/index.ts +32 -0
  124. package/src/procedures/manifest.generate.ts +113 -0
  125. package/src/procedures/server.call.ts +96 -0
  126. package/src/procedures/server.connect.ts +45 -0
  127. package/src/procedures/server.connections.ts +64 -0
  128. package/src/procedures/server.create.ts +84 -0
  129. package/src/procedures/server.disconnect.ts +31 -0
  130. package/src/procedures/server.start.ts +209 -0
  131. package/src/procedures/server.status.ts +139 -0
  132. package/src/procedures/server.stop.ts +121 -0
  133. package/src/register.ts +17 -0
  134. package/src/schema.ts +15 -0
  135. package/src/types.ts +257 -0
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Type definitions for client-server procedures
3
+ */
4
+ export type TransportType = "http" | "websocket" | "local";
5
+ export interface HttpTransportConfig {
6
+ type: "http";
7
+ port?: number | undefined;
8
+ host?: string | undefined;
9
+ basePath?: string | undefined;
10
+ /** Send CORS headers. The default is false: only `corsOrigins` (or loopback pages) are served to browsers. */
11
+ cors?: boolean | undefined;
12
+ /** Browser origins that may call the peer, besides loopback origins */
13
+ corsOrigins?: string[] | undefined;
14
+ /** URL strategy: "rest" (default) or "rpc" for /rpc/service/operation format */
15
+ urlStrategy?: "rest" | "rpc" | undefined;
16
+ /** A secret that every request must send as `Authorization: Bearer <token>` */
17
+ token?: string | undefined;
18
+ }
19
+ export interface WebSocketTransportConfig {
20
+ type: "websocket";
21
+ port?: number | undefined;
22
+ host?: string | undefined;
23
+ path?: string | undefined;
24
+ /** Browser origins that may connect, besides loopback origins */
25
+ origins?: string[] | undefined;
26
+ /** A secret that every connection must send as `?token=<token>` (or a bearer header) */
27
+ token?: string | undefined;
28
+ }
29
+ export interface LocalTransportConfig {
30
+ type: "local";
31
+ }
32
+ export type TransportConfig = HttpTransportConfig | WebSocketTransportConfig | LocalTransportConfig;
33
+ export interface ServerCreateInput {
34
+ /** Transports to enable */
35
+ transports?: TransportConfig[] | undefined;
36
+ /** Auto-register all procedures from registry */
37
+ autoRegister?: boolean | undefined;
38
+ /** A secret that every request must carry (each transport that has no token of its own gets this one) */
39
+ token?: string | undefined;
40
+ /** The procedures to serve: exact keys (`git.status`) or prefixes (`git.*`). Default: every procedure */
41
+ expose?: string[] | undefined;
42
+ }
43
+ export interface ServerCreateOutput {
44
+ /** Server ID for reference */
45
+ serverId: string;
46
+ /** Active transport endpoints */
47
+ endpoints: Array<{
48
+ type: TransportType;
49
+ address: string;
50
+ }>;
51
+ /** Number of registered procedures */
52
+ procedureCount: number;
53
+ }
54
+ export interface ServerConnectInput {
55
+ /** Remote server address */
56
+ address: string;
57
+ /** Transport type to use */
58
+ transport?: TransportType | undefined;
59
+ /** Connection timeout in ms */
60
+ timeout?: number | undefined;
61
+ }
62
+ export interface ProcedureInfo {
63
+ /** Procedure path */
64
+ path: string[];
65
+ /** Description from metadata */
66
+ description?: string | undefined;
67
+ /** Input schema as JSON schema */
68
+ inputSchema?: Record<string, unknown> | undefined;
69
+ /** Output schema as JSON schema */
70
+ outputSchema?: Record<string, unknown> | undefined;
71
+ }
72
+ export interface ServerConnectOutput {
73
+ /** Connection ID */
74
+ connectionId: string;
75
+ /** Remote peer ID */
76
+ remotePeerId: string;
77
+ /** Procedures available on remote */
78
+ remoteProcedures: ProcedureInfo[];
79
+ }
80
+ export interface ServerDisconnectInput {
81
+ /** Connection ID to disconnect */
82
+ connectionId: string;
83
+ }
84
+ export interface ServerDisconnectOutput {
85
+ /** Whether disconnect succeeded */
86
+ success: boolean;
87
+ }
88
+ export type ManifestFormat = "json" | "typescript";
89
+ export interface ManifestGenerateInput {
90
+ /** Output formats to generate */
91
+ formats?: ManifestFormat[] | undefined;
92
+ /** Namespace filter (only include procedures under this path) */
93
+ namespace?: string[] | undefined;
94
+ /** Output directory for files */
95
+ outputDir?: string | undefined;
96
+ }
97
+ export interface ManifestGenerateOutput {
98
+ /** Generated JSON manifest */
99
+ json?: {
100
+ procedures: ProcedureInfo[];
101
+ generatedAt: string;
102
+ version: string;
103
+ } | undefined;
104
+ /** Generated TypeScript declaration */
105
+ typescript?: string | undefined;
106
+ /** Files written if outputDir provided */
107
+ filesWritten?: string[] | undefined;
108
+ }
109
+ export interface PeerConnection {
110
+ /** Unique connection ID */
111
+ id: string;
112
+ /** Remote peer ID */
113
+ remotePeerId: string;
114
+ /** Transport type used */
115
+ transport: TransportType;
116
+ /** Connection state */
117
+ state: "connecting" | "connected" | "disconnected" | "error";
118
+ /** Remote procedures */
119
+ remoteProcedures: ProcedureInfo[];
120
+ /** When connection was established */
121
+ connectedAt?: Date;
122
+ }
123
+ export interface ProcedureAnnounceMessage {
124
+ type: "procedure-announce";
125
+ peerId: string;
126
+ procedures: ProcedureInfo[];
127
+ }
128
+ export interface ProcedureUpdateMessage {
129
+ type: "procedure-update";
130
+ peerId: string;
131
+ added?: ProcedureInfo[];
132
+ removed?: string[];
133
+ }
134
+ export interface ServerStartInput {
135
+ /** Port to listen on */
136
+ port?: number | undefined;
137
+ /** Host to bind to */
138
+ host?: string | undefined;
139
+ /** Transport type */
140
+ transport?: "http" | "websocket" | "both" | undefined;
141
+ }
142
+ export interface ServerStartOutput {
143
+ /** Whether start succeeded */
144
+ success: boolean;
145
+ /** Process ID of server */
146
+ pid?: number | undefined;
147
+ /** Port server is running on */
148
+ port?: number | undefined;
149
+ /** Endpoint URL */
150
+ endpoint?: string | undefined;
151
+ /** Log file path */
152
+ logFile?: string | undefined;
153
+ /** Status message */
154
+ message: string;
155
+ }
156
+ export interface ServerStopInput {
157
+ /** Port of server to stop (stops all if omitted) */
158
+ port?: number | undefined;
159
+ /** Force kill with SIGKILL instead of SIGTERM */
160
+ force?: boolean | undefined;
161
+ }
162
+ export interface ServerStopOutput {
163
+ /** Whether stop succeeded */
164
+ success: boolean;
165
+ /** Status message */
166
+ message: string;
167
+ }
168
+ export interface ServerStatusInput {
169
+ /** Port to check (shows all if omitted) */
170
+ port?: number | undefined;
171
+ }
172
+ export interface ServerStatusOutput {
173
+ /** Whether server is running */
174
+ running: boolean;
175
+ /** Process ID */
176
+ pid?: number | undefined;
177
+ /** Port */
178
+ port?: number | undefined;
179
+ /** Endpoint URL */
180
+ endpoint?: string | undefined;
181
+ /** Transport type */
182
+ transport?: string | undefined;
183
+ /** When server started (ISO string) */
184
+ startedAt?: string | undefined;
185
+ /** Human-readable uptime */
186
+ uptime?: string | undefined;
187
+ /** Log file path */
188
+ logFile?: string | undefined;
189
+ /** Status message */
190
+ message: string;
191
+ }
192
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Type definitions for client-server procedures
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json CHANGED
@@ -1,6 +1,90 @@
1
1
  {
2
+ "$schema": "https://json.schemastore.org/package",
2
3
  "name": "@procedures/peer",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
4
+ "version": "0.1.0",
5
+ "description": "Serve procedures: HTTP and WebSocket peers with token authentication, browser checks, an expose list, server.create, status and stop, and manifests.",
6
+ "keywords": [
7
+ "server",
8
+ "rpc",
9
+ "http",
10
+ "websocket",
11
+ "peer",
12
+ "authentication",
13
+ "procedures"
14
+ ],
15
+ "homepage": "https://mark1russell7.github.io/client/",
16
+ "bugs": {
17
+ "url": "https://github.com/mark1russell7/client/issues"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/mark1russell7/client.git",
22
+ "directory": "packages/client-server"
23
+ },
24
+ "license": "MIT",
25
+ "author": "Mark Russell (https://github.com/mark1russell7)",
26
+ "type": "module",
27
+ "main": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.js"
33
+ },
34
+ "./module": {
35
+ "types": "./dist/module.d.ts",
36
+ "import": "./dist/module.js"
37
+ },
38
+ "./procedures": {
39
+ "types": "./dist/procedures/index.d.ts",
40
+ "import": "./dist/procedures/index.js"
41
+ },
42
+ "./lockfile": {
43
+ "types": "./dist/lockfile.d.ts",
44
+ "import": "./dist/lockfile.js"
45
+ }
46
+ },
47
+ "files": [
48
+ "dist",
49
+ "src",
50
+ "!src/**/*.test.ts",
51
+ "!src/**/*.test.tsx",
52
+ "!src/**/__tests__",
53
+ "CHANGELOG.md"
54
+ ],
55
+ "sideEffects": [
56
+ "./dist/index.js",
57
+ "./dist/register.js"
58
+ ],
59
+ "engines": {
60
+ "node": ">=22"
61
+ },
62
+ "publishConfig": {
63
+ "access": "public",
64
+ "provenance": true
65
+ },
66
+ "devDependencies": {
67
+ "typescript": "^7.0.2",
68
+ "@types/node": "^22.0.0",
69
+ "@mark1russell7/cue": "^1.0.0",
70
+ "vitest": "^5.0.3",
71
+ "@types/express": "^5.0.6"
72
+ },
73
+ "client": {
74
+ "procedures": "./dist/register.js"
75
+ },
76
+ "dependencies": {
77
+ "@procedures/client": "0.1.0",
78
+ "zod": "^4.6.5"
79
+ },
80
+ "optionalDependencies": {
81
+ "express": "^5.0.0"
82
+ },
83
+ "scripts": {
84
+ "build": "tsc -b",
85
+ "typecheck": "tsc --noEmit",
86
+ "clean": "rm -rf dist .tsbuildinfo",
87
+ "test": "vitest run",
88
+ "test:watch": "vitest"
89
+ }
6
90
  }
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Connection Module
3
+ *
4
+ * Manages outbound connections to remote peers.
5
+ * Uses Client + Transport for bidirectional RPC.
6
+ */
7
+
8
+ import {
9
+ Client,
10
+ HttpTransport,
11
+ WebSocketTransport,
12
+ defaultUrlPattern,
13
+ postOnlyStrategy,
14
+ type HttpTransportOptions,
15
+ } from "@procedures/client";
16
+ import type {
17
+ TransportType,
18
+ PeerConnection,
19
+ ProcedureInfo,
20
+ ProcedureAnnounceMessage,
21
+ } from "../types.js";
22
+
23
+ // =============================================================================
24
+ // Types
25
+ // =============================================================================
26
+
27
+ export interface ConnectOptions {
28
+ /** Remote address (URL) */
29
+ address: string;
30
+ /** Transport type (auto-detected from URL if not specified) */
31
+ transport?: TransportType;
32
+ /** Connection timeout in ms */
33
+ timeout?: number;
34
+ /** Local peer ID to identify ourselves */
35
+ localPeerId?: string;
36
+ }
37
+
38
+ export interface Connection {
39
+ /** Connection ID */
40
+ id: string;
41
+ /** Remote peer info */
42
+ remote: PeerConnection;
43
+ /** Client for calling remote procedures */
44
+ client: Client;
45
+ /** Disconnect */
46
+ disconnect(): Promise<void>;
47
+ }
48
+
49
+ // =============================================================================
50
+ // Connection Manager
51
+ // =============================================================================
52
+
53
+ /** Active connections */
54
+ const connections = new Map<string, Connection>();
55
+
56
+ /**
57
+ * Connect to a remote peer
58
+ */
59
+ export async function connect(options: ConnectOptions): Promise<Connection> {
60
+ const connectionId = `conn-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
61
+
62
+ // Detect transport type from URL if not specified
63
+ const transport = options.transport ?? detectTransport(options.address);
64
+
65
+ // Create appropriate client transport
66
+ const client = createClient(options.address, transport, options.timeout);
67
+
68
+ // Discover remote procedures
69
+ const remoteProcedures = await discoverProcedures(client, options.localPeerId);
70
+
71
+ // Create connection object
72
+ const connection: Connection = {
73
+ id: connectionId,
74
+ remote: {
75
+ id: connectionId,
76
+ remotePeerId: remoteProcedures.peerId,
77
+ transport,
78
+ state: "connected",
79
+ remoteProcedures: remoteProcedures.procedures,
80
+ connectedAt: new Date(),
81
+ },
82
+ client,
83
+ async disconnect() {
84
+ await client.close();
85
+ connections.delete(connectionId);
86
+ },
87
+ };
88
+
89
+ connections.set(connectionId, connection);
90
+ return connection;
91
+ }
92
+
93
+ /**
94
+ * Get connection by ID
95
+ */
96
+ export function getConnection(connectionId: string): Connection | undefined {
97
+ return connections.get(connectionId);
98
+ }
99
+
100
+ /**
101
+ * Disconnect a connection
102
+ */
103
+ export async function disconnect(connectionId: string): Promise<boolean> {
104
+ const connection = connections.get(connectionId);
105
+ if (!connection) {
106
+ return false;
107
+ }
108
+ await connection.disconnect();
109
+ return true;
110
+ }
111
+
112
+ /**
113
+ * Get all active connection IDs
114
+ */
115
+ export function getConnectionIds(): string[] {
116
+ return Array.from(connections.keys());
117
+ }
118
+
119
+ // =============================================================================
120
+ // Helpers
121
+ // =============================================================================
122
+
123
+ /**
124
+ * Detect transport type from URL
125
+ */
126
+ function detectTransport(address: string): TransportType {
127
+ if (address.startsWith("ws://") || address.startsWith("wss://")) {
128
+ return "websocket";
129
+ }
130
+ if (address.startsWith("http://") || address.startsWith("https://")) {
131
+ return "http";
132
+ }
133
+ if (address.startsWith("local://")) {
134
+ return "local";
135
+ }
136
+ // Default to HTTP
137
+ return "http";
138
+ }
139
+
140
+ /**
141
+ * Create client with appropriate transport
142
+ */
143
+ function createClient(
144
+ address: string,
145
+ transport: TransportType,
146
+ timeout?: number
147
+ ): Client {
148
+ switch (transport) {
149
+ case "http": {
150
+ const httpOptions: HttpTransportOptions = {
151
+ baseUrl: address,
152
+ urlStrategy: defaultUrlPattern.format,
153
+ httpMethodStrategy: postOnlyStrategy,
154
+ };
155
+ if (timeout !== undefined) {
156
+ httpOptions.timeout = timeout;
157
+ }
158
+ return new Client({
159
+ transport: new HttpTransport(httpOptions),
160
+ });
161
+ }
162
+
163
+ case "websocket":
164
+ return new Client({
165
+ transport: new WebSocketTransport({
166
+ url: address,
167
+ connectionTimeout: timeout ?? 10000,
168
+ reconnect: {
169
+ enabled: true,
170
+ maxAttempts: 3,
171
+ },
172
+ }),
173
+ });
174
+
175
+ case "local":
176
+ throw new Error("Local transport for outbound connections not yet implemented");
177
+
178
+ default:
179
+ throw new Error(`Unknown transport type: ${transport}`);
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Discover procedures on remote peer
185
+ */
186
+ async function discoverProcedures(
187
+ client: Client,
188
+ localPeerId?: string
189
+ ): Promise<{ peerId: string; procedures: ProcedureInfo[] }> {
190
+ try {
191
+ // Build payload - only include peerId if defined
192
+ const payload: { peerId?: string } = {};
193
+ if (localPeerId !== undefined) {
194
+ payload.peerId = localPeerId;
195
+ }
196
+
197
+ // Call the discovery endpoint
198
+ const response = await client.call<
199
+ { peerId?: string },
200
+ ProcedureAnnounceMessage
201
+ >(
202
+ { service: "_discovery", operation: "announce" },
203
+ payload
204
+ );
205
+
206
+ return {
207
+ peerId: response.peerId,
208
+ procedures: response.procedures,
209
+ };
210
+ } catch (error) {
211
+ // If discovery fails, return empty procedures
212
+ // The connection is still valid, just no auto-discovery
213
+ console.warn("Procedure discovery failed:", error);
214
+ return {
215
+ peerId: "unknown",
216
+ procedures: [],
217
+ };
218
+ }
219
+ }
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Discovery Module
3
+ *
4
+ * Implements procedure discovery protocol for peers.
5
+ * Peers exchange procedure manifests on connection.
6
+ */
7
+
8
+ import {
9
+ createProcedure,
10
+ type Procedure,
11
+ PROCEDURE_REGISTRY,
12
+ } from "@procedures/client";
13
+ import { schema } from "../schema.js";
14
+ import type {
15
+ ProcedureInfo,
16
+ ProcedureAnnounceMessage,
17
+ } from "../types.js";
18
+
19
+ // =============================================================================
20
+ // Types
21
+ // =============================================================================
22
+
23
+ interface DiscoveryAnnounceInput {
24
+ /** Optional peer ID of the connecting peer */
25
+ peerId?: string;
26
+ }
27
+
28
+ // =============================================================================
29
+ // Discovery Procedure
30
+ // =============================================================================
31
+
32
+ const discoveryAnnounceInputSchema = schema<DiscoveryAnnounceInput>();
33
+ const discoveryAnnounceOutputSchema = schema<ProcedureAnnounceMessage>();
34
+
35
+ /**
36
+ * Internal procedure for procedure discovery
37
+ * Exposed at _discovery.announce
38
+ */
39
+ export const discoveryAnnounceProcedure: Procedure<
40
+ DiscoveryAnnounceInput,
41
+ ProcedureAnnounceMessage,
42
+ { description: string; internal: boolean }
43
+ > = createProcedure()
44
+ .path(["_discovery", "announce"])
45
+ .input(discoveryAnnounceInputSchema)
46
+ .output(discoveryAnnounceOutputSchema)
47
+ .meta({
48
+ description: "Exchange procedure manifests for discovery",
49
+ internal: true,
50
+ })
51
+ .handler(async (_input: DiscoveryAnnounceInput) => {
52
+ // Get all registered procedures
53
+ const procedures = PROCEDURE_REGISTRY.getAll();
54
+
55
+ // Convert to ProcedureInfo format
56
+ const procedureInfos: ProcedureInfo[] = procedures
57
+ .filter((proc) => {
58
+ // Skip internal procedures in discovery
59
+ const meta = proc.metadata as { internal?: boolean } | undefined;
60
+ return !meta?.internal;
61
+ })
62
+ .map((proc) => {
63
+ const meta = proc.metadata as { description?: string } | undefined;
64
+ const info: ProcedureInfo = {
65
+ path: proc.path,
66
+ };
67
+ if (meta?.description !== undefined) {
68
+ info.description = meta.description;
69
+ }
70
+ // TODO: Generate JSON schema from input/output schemas
71
+ return info;
72
+ });
73
+
74
+ // Generate a peer ID based on process (could be configured)
75
+ const peerId = `peer-${process.pid}-${Date.now().toString(36)}`;
76
+
77
+ return {
78
+ type: "procedure-announce" as const,
79
+ peerId,
80
+ procedures: procedureInfos,
81
+ };
82
+ })
83
+ .build();
84
+
85
+ // =============================================================================
86
+ // Utility Functions
87
+ // =============================================================================
88
+
89
+ /**
90
+ * Get procedure info for all registered procedures
91
+ */
92
+ export function getProcedureInfos(): ProcedureInfo[] {
93
+ const procedures = PROCEDURE_REGISTRY.getAll();
94
+
95
+ return procedures
96
+ .filter((proc) => proc.handler !== undefined)
97
+ .map((proc) => {
98
+ const meta = proc.metadata as { description?: string } | undefined;
99
+ const info: ProcedureInfo = {
100
+ path: proc.path,
101
+ };
102
+ if (meta?.description !== undefined) {
103
+ info.description = meta.description;
104
+ }
105
+ return info;
106
+ });
107
+ }
108
+
109
+ /**
110
+ * Watch for procedure changes
111
+ */
112
+ export function watchProcedures(
113
+ callback: (event: "register" | "unregister", info: ProcedureInfo) => void
114
+ ): () => void {
115
+ const createHandler = (eventType: "register" | "unregister") => {
116
+ return (proc: { path: string[]; metadata?: { description?: string } }) => {
117
+ const info: ProcedureInfo = {
118
+ path: proc.path,
119
+ };
120
+ if (proc.metadata?.description !== undefined) {
121
+ info.description = proc.metadata.description;
122
+ }
123
+ callback(eventType, info);
124
+ };
125
+ };
126
+
127
+ const registerHandler = createHandler("register");
128
+ const unregisterHandler = createHandler("unregister");
129
+
130
+ PROCEDURE_REGISTRY.on("register", registerHandler);
131
+ PROCEDURE_REGISTRY.on("unregister", unregisterHandler);
132
+
133
+ return () => {
134
+ PROCEDURE_REGISTRY.off("register", registerHandler);
135
+ PROCEDURE_REGISTRY.off("unregister", unregisterHandler);
136
+ };
137
+ }
package/src/expose.ts ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The expose rule of a server, from a list of patterns.
3
+ *
4
+ * A pattern is an exact procedure key (`git.status`), a prefix with `.*` (`git.*`: every
5
+ * procedure under `git`, at any depth), or `*` (every procedure). A server without a list
6
+ * serves every procedure of its registry.
7
+ *
8
+ * The rule is `exposePatterns()` of the core host policy (roadmap 2.3); this name stays for the
9
+ * callers of `client-server`.
10
+ */
11
+
12
+ import { exposePatterns, type ProcedurePath } from "@procedures/client";
13
+
14
+ /** This function gives the rule of `ProcedureServer` for a list of patterns. */
15
+ export function exposeRule(patterns: readonly string[]): (path: ProcedurePath) => boolean {
16
+ return exposePatterns(patterns);
17
+ }