@soulcraft/sdk 1.7.0 → 2.0.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 (166) hide show
  1. package/dist/client/create-client-sdk.d.ts +16 -2
  2. package/dist/client/create-client-sdk.d.ts.map +1 -1
  3. package/dist/client/create-client-sdk.js +2 -7
  4. package/dist/client/create-client-sdk.js.map +1 -1
  5. package/dist/client/index.d.ts +44 -37
  6. package/dist/client/index.d.ts.map +1 -1
  7. package/dist/client/index.js +59 -44
  8. package/dist/client/index.js.map +1 -1
  9. package/dist/client/namespace-proxy.d.ts +108 -0
  10. package/dist/client/namespace-proxy.d.ts.map +1 -0
  11. package/dist/client/namespace-proxy.js +151 -0
  12. package/dist/client/namespace-proxy.js.map +1 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/modules/app-context/index.d.ts +15 -15
  16. package/dist/modules/app-context/index.d.ts.map +1 -1
  17. package/dist/modules/app-context/index.js +17 -17
  18. package/dist/modules/app-context/index.js.map +1 -1
  19. package/dist/namespaces.d.ts +2942 -0
  20. package/dist/namespaces.d.ts.map +1 -0
  21. package/dist/namespaces.js +37 -0
  22. package/dist/namespaces.js.map +1 -0
  23. package/dist/rpc.d.ts +156 -0
  24. package/dist/rpc.d.ts.map +1 -0
  25. package/dist/rpc.js +26 -0
  26. package/dist/rpc.js.map +1 -0
  27. package/dist/server/create-sdk.d.ts.map +1 -1
  28. package/dist/server/create-sdk.js +3 -13
  29. package/dist/server/create-sdk.js.map +1 -1
  30. package/dist/server/handlers/annotations.d.ts +52 -0
  31. package/dist/server/handlers/annotations.d.ts.map +1 -0
  32. package/dist/server/handlers/annotations.js +204 -0
  33. package/dist/server/handlers/annotations.js.map +1 -0
  34. package/dist/server/handlers/auth.d.ts +53 -0
  35. package/dist/server/handlers/auth.d.ts.map +1 -0
  36. package/dist/server/handlers/auth.js +66 -0
  37. package/dist/server/handlers/auth.js.map +1 -0
  38. package/dist/server/handlers/certification.d.ts +32 -0
  39. package/dist/server/handlers/certification.d.ts.map +1 -0
  40. package/dist/server/handlers/certification.js +253 -0
  41. package/dist/server/handlers/certification.js.map +1 -0
  42. package/dist/server/handlers/chat/conversations.d.ts +91 -0
  43. package/dist/server/handlers/chat/conversations.d.ts.map +1 -0
  44. package/dist/server/handlers/chat/conversations.js +314 -0
  45. package/dist/server/handlers/chat/conversations.js.map +1 -0
  46. package/dist/server/handlers/chat/delegator.d.ts +144 -0
  47. package/dist/server/handlers/chat/delegator.d.ts.map +1 -0
  48. package/dist/server/handlers/chat/delegator.js +431 -0
  49. package/dist/server/handlers/chat/delegator.js.map +1 -0
  50. package/dist/server/handlers/chat/engine.d.ts +81 -0
  51. package/dist/server/handlers/chat/engine.d.ts.map +1 -0
  52. package/dist/server/handlers/chat/engine.js +442 -0
  53. package/dist/server/handlers/chat/engine.js.map +1 -0
  54. package/dist/server/handlers/chat/executor.d.ts +65 -0
  55. package/dist/server/handlers/chat/executor.d.ts.map +1 -0
  56. package/dist/server/handlers/chat/executor.js +375 -0
  57. package/dist/server/handlers/chat/executor.js.map +1 -0
  58. package/dist/server/handlers/chat/index.d.ts +62 -0
  59. package/dist/server/handlers/chat/index.d.ts.map +1 -0
  60. package/dist/server/handlers/chat/index.js +182 -0
  61. package/dist/server/handlers/chat/index.js.map +1 -0
  62. package/dist/server/handlers/chat/memory.d.ts +91 -0
  63. package/dist/server/handlers/chat/memory.d.ts.map +1 -0
  64. package/dist/server/handlers/chat/memory.js +293 -0
  65. package/dist/server/handlers/chat/memory.js.map +1 -0
  66. package/dist/server/handlers/chat/models.d.ts +180 -0
  67. package/dist/server/handlers/chat/models.d.ts.map +1 -0
  68. package/dist/server/handlers/chat/models.js +304 -0
  69. package/dist/server/handlers/chat/models.js.map +1 -0
  70. package/dist/server/handlers/chat/planner.d.ts +116 -0
  71. package/dist/server/handlers/chat/planner.d.ts.map +1 -0
  72. package/dist/server/handlers/chat/planner.js +344 -0
  73. package/dist/server/handlers/chat/planner.js.map +1 -0
  74. package/dist/server/handlers/chat/types.d.ts +500 -0
  75. package/dist/server/handlers/chat/types.d.ts.map +1 -0
  76. package/dist/server/handlers/chat/types.js +11 -0
  77. package/dist/server/handlers/chat/types.js.map +1 -0
  78. package/dist/server/handlers/collections.d.ts +67 -0
  79. package/dist/server/handlers/collections.d.ts.map +1 -0
  80. package/dist/server/handlers/collections.js +484 -0
  81. package/dist/server/handlers/collections.js.map +1 -0
  82. package/dist/server/handlers/commerce.d.ts +106 -0
  83. package/dist/server/handlers/commerce.d.ts.map +1 -0
  84. package/dist/server/handlers/commerce.js +62 -0
  85. package/dist/server/handlers/commerce.js.map +1 -0
  86. package/dist/server/handlers/config.d.ts +112 -0
  87. package/dist/server/handlers/config.d.ts.map +1 -0
  88. package/dist/server/handlers/config.js +122 -0
  89. package/dist/server/handlers/config.js.map +1 -0
  90. package/dist/server/handlers/export.d.ts +72 -0
  91. package/dist/server/handlers/export.d.ts.map +1 -0
  92. package/dist/server/handlers/export.js +175 -0
  93. package/dist/server/handlers/export.js.map +1 -0
  94. package/dist/server/handlers/formats.d.ts +77 -0
  95. package/dist/server/handlers/formats.d.ts.map +1 -0
  96. package/dist/server/handlers/formats.js +65 -0
  97. package/dist/server/handlers/formats.js.map +1 -0
  98. package/dist/server/handlers/graph.d.ts +31 -0
  99. package/dist/server/handlers/graph.d.ts.map +1 -0
  100. package/dist/server/handlers/graph.js +490 -0
  101. package/dist/server/handlers/graph.js.map +1 -0
  102. package/dist/server/handlers/import.d.ts +96 -0
  103. package/dist/server/handlers/import.d.ts.map +1 -0
  104. package/dist/server/handlers/import.js +108 -0
  105. package/dist/server/handlers/import.js.map +1 -0
  106. package/dist/server/handlers/index.d.ts +68 -0
  107. package/dist/server/handlers/index.d.ts.map +1 -0
  108. package/dist/server/handlers/index.js +71 -0
  109. package/dist/server/handlers/index.js.map +1 -0
  110. package/dist/server/handlers/media.d.ts +76 -0
  111. package/dist/server/handlers/media.d.ts.map +1 -0
  112. package/dist/server/handlers/media.js +53 -0
  113. package/dist/server/handlers/media.js.map +1 -0
  114. package/dist/server/handlers/project.d.ts +45 -0
  115. package/dist/server/handlers/project.d.ts.map +1 -0
  116. package/dist/server/handlers/project.js +181 -0
  117. package/dist/server/handlers/project.js.map +1 -0
  118. package/dist/server/handlers/publish.d.ts +102 -0
  119. package/dist/server/handlers/publish.d.ts.map +1 -0
  120. package/dist/server/handlers/publish.js +130 -0
  121. package/dist/server/handlers/publish.js.map +1 -0
  122. package/dist/server/handlers/pulse.d.ts +39 -0
  123. package/dist/server/handlers/pulse.d.ts.map +1 -0
  124. package/dist/server/handlers/pulse.js +78 -0
  125. package/dist/server/handlers/pulse.js.map +1 -0
  126. package/dist/server/handlers/realtime.d.ts +55 -0
  127. package/dist/server/handlers/realtime.d.ts.map +1 -0
  128. package/dist/server/handlers/realtime.js +49 -0
  129. package/dist/server/handlers/realtime.js.map +1 -0
  130. package/dist/server/handlers/search.d.ts +21 -0
  131. package/dist/server/handlers/search.d.ts.map +1 -0
  132. package/dist/server/handlers/search.js +237 -0
  133. package/dist/server/handlers/search.js.map +1 -0
  134. package/dist/server/handlers/session.d.ts +47 -0
  135. package/dist/server/handlers/session.d.ts.map +1 -0
  136. package/dist/server/handlers/session.js +286 -0
  137. package/dist/server/handlers/session.js.map +1 -0
  138. package/dist/server/handlers/settings.d.ts +97 -0
  139. package/dist/server/handlers/settings.d.ts.map +1 -0
  140. package/dist/server/handlers/settings.js +131 -0
  141. package/dist/server/handlers/settings.js.map +1 -0
  142. package/dist/server/handlers/workspace.d.ts +78 -0
  143. package/dist/server/handlers/workspace.d.ts.map +1 -0
  144. package/dist/server/handlers/workspace.js +270 -0
  145. package/dist/server/handlers/workspace.js.map +1 -0
  146. package/dist/server/hono-router.d.ts +66 -0
  147. package/dist/server/hono-router.d.ts.map +1 -0
  148. package/dist/server/hono-router.js +203 -0
  149. package/dist/server/hono-router.js.map +1 -0
  150. package/dist/server/index.d.ts +27 -19
  151. package/dist/server/index.d.ts.map +1 -1
  152. package/dist/server/index.js +30 -18
  153. package/dist/server/index.js.map +1 -1
  154. package/dist/server/namespace-router.d.ts +204 -0
  155. package/dist/server/namespace-router.d.ts.map +1 -0
  156. package/dist/server/namespace-router.js +262 -0
  157. package/dist/server/namespace-router.js.map +1 -0
  158. package/dist/transports/http-namespace.d.ts +210 -0
  159. package/dist/transports/http-namespace.d.ts.map +1 -0
  160. package/dist/transports/http-namespace.js +514 -0
  161. package/dist/transports/http-namespace.js.map +1 -0
  162. package/dist/types.d.ts +59 -65
  163. package/dist/types.d.ts.map +1 -1
  164. package/dist/types.js +7 -3
  165. package/dist/types.js.map +1 -1
  166. package/package.json +1 -1
@@ -0,0 +1,262 @@
1
+ /**
2
+ * @module server/namespace-router
3
+ * @description Universal namespace-aware RPC dispatcher for the Soulcraft SDK.
4
+ *
5
+ * Receives requests in the {@link SoulcraftRPC} envelope format, authenticates the
6
+ * caller, resolves the target namespace, and dispatches to the appropriate handler.
7
+ *
8
+ * ## Dispatch model
9
+ *
10
+ * - `brainy` / `brainy.vfs` / `brainy.versions` → {@link LocalTransport} dispatch
11
+ * against the resolved Brainy instance (same proven RPC path as SDK 1.x).
12
+ * - All other namespaces → provider-based dispatch. Each namespace's provider is a
13
+ * plain object whose methods match the namespace contract in `namespaces.ts`.
14
+ *
15
+ * ## Streaming
16
+ *
17
+ * When `stream: true` is set on the request, the handler is expected to return an
18
+ * `AsyncIterable`. The router converts each yielded value into a
19
+ * {@link SoulcraftRPCStream} frame and delivers it via the transport-appropriate
20
+ * mechanism (SSE, PostMessage chunks, or WebSocket frames).
21
+ *
22
+ * ## Error handling
23
+ *
24
+ * All errors are caught at the dispatch level and returned as `SoulcraftRPCResponse`
25
+ * with an `error` field. Handler code does not need to wrap logic in try/catch.
26
+ *
27
+ * @example Hono integration
28
+ * ```typescript
29
+ * import { createNamespaceRouter } from '@soulcraft/sdk/server'
30
+ *
31
+ * const router = createNamespaceRouter({
32
+ * resolveBrain: async (ctx) => pool.forUser(ctx.userId, ctx.workspaceId),
33
+ * authenticate: async (ctx) => verifySession(ctx.request),
34
+ * providers: { chat: chatProvider, graph: graphProvider },
35
+ * })
36
+ *
37
+ * const response = await router.dispatch({ ns: 'brainy', method: 'find', args: [...] }, requestContext)
38
+ * ```
39
+ */
40
+ import { LocalTransport } from '../transports/local.js';
41
+ // ─────────────────────────────────────────────────────────────────────────────
42
+ // Brainy namespace prefixes
43
+ // ─────────────────────────────────────────────────────────────────────────────
44
+ /** Namespaces dispatched directly to Brainy via LocalTransport. */
45
+ const BRAINY_NAMESPACES = new Set(['brainy', 'brainy.vfs', 'brainy.versions']);
46
+ /**
47
+ * Checks if a namespace should be dispatched to Brainy's LocalTransport.
48
+ *
49
+ * @param ns - The namespace string.
50
+ * @returns `true` if the namespace is a Brainy sub-namespace.
51
+ */
52
+ function isBrainyNamespace(ns) {
53
+ return BRAINY_NAMESPACES.has(ns) || ns.startsWith('brainy.');
54
+ }
55
+ // ─────────────────────────────────────────────────────────────────────────────
56
+ // Factory
57
+ // ─────────────────────────────────────────────────────────────────────────────
58
+ /**
59
+ * Creates a namespace-aware RPC router that dispatches to Brainy or provider
60
+ * handler methods based on the `ns` field in the request.
61
+ *
62
+ * @param config - Router configuration.
63
+ * @returns A {@link NamespaceRouter} with a `dispatch()` method.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const router = createNamespaceRouter({
68
+ * resolveBrain: (ctx) => pool.forUser(ctx.user!.emailHash, ctx.workspaceId),
69
+ * authenticate: (ctx) => verifySession(ctx.request),
70
+ * providers: {
71
+ * chat: chatHandler,
72
+ * graph: graphHandler,
73
+ * },
74
+ * })
75
+ *
76
+ * const result = await router.dispatch(
77
+ * { id: '1', ns: 'brainy', method: 'find', args: [{ query: 'test' }] },
78
+ * request,
79
+ * )
80
+ * ```
81
+ */
82
+ export function createNamespaceRouter(config) {
83
+ const { resolveBrain, authenticate, authorize, providers, blockedBrainyMethods = [], } = config;
84
+ return {
85
+ async dispatch(rpc, request) {
86
+ const { id, ns, method, args, stream } = rpc;
87
+ // ── Extract workspace ID ──────────────────────────────────────────
88
+ const workspaceId = _extractWorkspaceId(request);
89
+ // ── Build request context ──────────────────────────────────────────
90
+ const ctx = { request, user: null, workspaceId };
91
+ // ── Authenticate ──────────────────────────────────────────────────
92
+ try {
93
+ const user = await authenticate(ctx);
94
+ if (!user) {
95
+ return _errorResponse(id, 401, 'UNAUTHORIZED', 'Authentication required');
96
+ }
97
+ ctx.user = user;
98
+ }
99
+ catch (err) {
100
+ console.error('[SDK/router] authenticate threw:', err);
101
+ return _errorResponse(id, 401, 'AUTH_ERROR', 'Authentication failed');
102
+ }
103
+ // ── Authorize ─────────────────────────────────────────────────────
104
+ if (authorize) {
105
+ try {
106
+ const allowed = await authorize(ns, method, args, ctx.user);
107
+ if (!allowed) {
108
+ return _errorResponse(id, 403, 'FORBIDDEN', `Not authorized: ${ns}.${method}`);
109
+ }
110
+ }
111
+ catch (err) {
112
+ console.error('[SDK/router] authorize threw:', err);
113
+ return _errorResponse(id, 403, 'FORBIDDEN', 'Authorization check failed');
114
+ }
115
+ }
116
+ // ── Dispatch: Brainy namespaces ───────────────────────────────────
117
+ if (isBrainyNamespace(ns)) {
118
+ return _dispatchBrainy(id, ns, method, args, ctx, resolveBrain, blockedBrainyMethods);
119
+ }
120
+ // ── Dispatch: Provider namespaces ──────────────────────────────────
121
+ const provider = providers[ns];
122
+ if (!provider) {
123
+ return _errorResponse(id, 404, 'NAMESPACE_NOT_FOUND', `Namespace '${ns}' is not registered`);
124
+ }
125
+ const handlerFn = provider[method];
126
+ if (typeof handlerFn !== 'function') {
127
+ return _errorResponse(id, 404, 'METHOD_NOT_FOUND', `Method '${ns}.${method}' does not exist`);
128
+ }
129
+ // Build handler context for the provider method
130
+ let brain;
131
+ try {
132
+ brain = await resolveBrain(ctx);
133
+ }
134
+ catch (err) {
135
+ console.error('[SDK/router] resolveBrain threw for provider dispatch:', err);
136
+ return _errorResponse(id, 503, 'BRAIN_UNAVAILABLE', 'Brainy instance not available');
137
+ }
138
+ const handlerCtx = {
139
+ user: ctx.user,
140
+ workspaceId,
141
+ brain,
142
+ request,
143
+ };
144
+ try {
145
+ // Invoke the provider method with the RPC args + handler context.
146
+ // The handler context is always the last argument.
147
+ const result = await handlerFn(...args, handlerCtx);
148
+ // Check if the result is an async iterable (streaming response).
149
+ if (stream && result != null && typeof result === 'object' && Symbol.asyncIterator in result) {
150
+ return {
151
+ type: 'stream',
152
+ id,
153
+ iterable: result,
154
+ };
155
+ }
156
+ return {
157
+ type: 'response',
158
+ response: { id, result },
159
+ };
160
+ }
161
+ catch (err) {
162
+ const message = err instanceof Error ? err.message : String(err);
163
+ console.error(`[SDK/router] ${ns}.${method} threw:`, err);
164
+ return _errorResponse(id, 500, 'RPC_ERROR', message);
165
+ }
166
+ },
167
+ };
168
+ }
169
+ // ─────────────────────────────────────────────────────────────────────────────
170
+ // Brainy dispatch
171
+ // ─────────────────────────────────────────────────────────────────────────────
172
+ /**
173
+ * Dispatches a request to the Brainy namespace via LocalTransport.
174
+ *
175
+ * The method path is constructed by stripping the `brainy` prefix and prepending
176
+ * the sub-namespace. For example:
177
+ * - `ns: 'brainy'`, `method: 'find'` → `transport.call('find', args)`
178
+ * - `ns: 'brainy.vfs'`, `method: 'readdir'` → `transport.call('vfs.readdir', args)`
179
+ *
180
+ * @param id - Request ID for the response.
181
+ * @param ns - The Brainy namespace (e.g. `'brainy'`, `'brainy.vfs'`).
182
+ * @param method - The method within the namespace.
183
+ * @param args - Positional arguments.
184
+ * @param ctx - The request context with authenticated user.
185
+ * @param resolveBrain - Callback to resolve the Brainy instance.
186
+ * @param blockedMethods - Methods that are blocked.
187
+ * @returns A dispatch result.
188
+ */
189
+ async function _dispatchBrainy(id, ns, method, args, ctx, resolveBrain, blockedMethods) {
190
+ // Build the full method path for LocalTransport.
191
+ // 'brainy' → method as-is (e.g. 'find')
192
+ // 'brainy.vfs' → 'vfs.{method}' (e.g. 'vfs.readdir')
193
+ // 'brainy.versions' → 'versions.{method}'
194
+ const subNs = ns === 'brainy' ? '' : ns.slice('brainy.'.length);
195
+ const transportMethod = subNs ? `${subNs}.${method}` : method;
196
+ // Check blocklist
197
+ if (blockedMethods.includes(transportMethod)) {
198
+ return _errorResponse(id, 403, 'FORBIDDEN', `Method '${transportMethod}' is not available via RPC`);
199
+ }
200
+ // Resolve Brainy instance
201
+ let brain;
202
+ try {
203
+ brain = await resolveBrain(ctx);
204
+ }
205
+ catch (err) {
206
+ console.error('[SDK/router] resolveBrain threw:', err);
207
+ return _errorResponse(id, 503, 'BRAIN_UNAVAILABLE', 'Brainy instance not available');
208
+ }
209
+ // Dispatch via LocalTransport (same proven path as SDK 1.x)
210
+ const transport = new LocalTransport(brain);
211
+ try {
212
+ const result = await transport.call(transportMethod, args);
213
+ return {
214
+ type: 'response',
215
+ response: { id, result },
216
+ };
217
+ }
218
+ catch (err) {
219
+ const message = err instanceof Error ? err.message : String(err);
220
+ return _errorResponse(id, 500, 'RPC_ERROR', message);
221
+ }
222
+ }
223
+ // ─────────────────────────────────────────────────────────────────────────────
224
+ // Helpers
225
+ // ─────────────────────────────────────────────────────────────────────────────
226
+ /**
227
+ * Builds an error dispatch result.
228
+ *
229
+ * @param id - Request ID.
230
+ * @param _status - HTTP-like status code (for logging; not in the envelope).
231
+ * @param code - Machine-readable error code.
232
+ * @param message - Human-readable error description.
233
+ * @returns A response dispatch result with the error.
234
+ */
235
+ function _errorResponse(id, _status, code, message) {
236
+ return {
237
+ type: 'response',
238
+ response: { id, error: { code, message } },
239
+ };
240
+ }
241
+ /**
242
+ * Extracts the workspace ID from the request.
243
+ *
244
+ * Checks the `X-Workspace-Id` header first, then falls back to the `workspaceId`
245
+ * query parameter (necessary for SSE which doesn't support custom headers).
246
+ *
247
+ * @param request - The incoming HTTP request.
248
+ * @returns The workspace ID, or empty string if not present.
249
+ */
250
+ function _extractWorkspaceId(request) {
251
+ const fromHeader = request.headers.get('x-workspace-id');
252
+ if (fromHeader)
253
+ return fromHeader;
254
+ try {
255
+ const url = new URL(request.url);
256
+ return url.searchParams.get('workspaceId') ?? '';
257
+ }
258
+ catch {
259
+ return '';
260
+ }
261
+ }
262
+ //# sourceMappingURL=namespace-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"namespace-router.js","sourceRoot":"","sources":["../../src/server/namespace-router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,210 @@
1
+ /**
2
+ * @module transports/http-namespace
3
+ * @description Namespace-aware HTTP transport — sends RPC calls as JSON POST to `/api/rpc`
4
+ * with the unified `{ ns, method, args }` envelope.
5
+ *
6
+ * This is the Symmetrical SDK 2.0 replacement for {@link HttpTransport}, which
7
+ * only supports the `brainy` namespace via `{ method, args }` at `/api/brainy/rpc`.
8
+ *
9
+ * For streaming responses, the transport reads the response as SSE
10
+ * (`text/event-stream`) and yields each `data:` line as a chunk.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { HttpNamespaceTransport } from '@soulcraft/sdk/client'
15
+ * import { createSoulcraftProxy } from '@soulcraft/sdk/client'
16
+ *
17
+ * const transport = new HttpNamespaceTransport('https://workshop.soulcraft.com', {
18
+ * credentials: true,
19
+ * })
20
+ * const soulcraft = createSoulcraftProxy(transport)
21
+ *
22
+ * const graph = await soulcraft.graph.getData()
23
+ * const results = await soulcraft.brainy.find({ query: 'candles' })
24
+ * ```
25
+ */
26
+ import type { NamespaceTransport } from '../client/namespace-proxy.js';
27
+ /**
28
+ * Options for {@link HttpNamespaceTransport}.
29
+ */
30
+ export interface HttpNamespaceTransportOptions {
31
+ /**
32
+ * Optional capability token sent as `Authorization: Bearer <token>`.
33
+ * Mutually exclusive with `credentials: true` (cookie auth).
34
+ */
35
+ authToken?: string | undefined;
36
+ /**
37
+ * If `true`, include cookies with each request (same-origin browser use).
38
+ *
39
+ * @default false
40
+ */
41
+ credentials?: boolean | undefined;
42
+ /**
43
+ * Per-request timeout in milliseconds.
44
+ *
45
+ * @default 30000
46
+ */
47
+ timeoutMs?: number | undefined;
48
+ /**
49
+ * Custom headers to include with every request (e.g. `X-Workspace-Id`).
50
+ */
51
+ headers?: Record<string, string> | undefined;
52
+ }
53
+ /**
54
+ * Namespace-aware HTTP transport for Soulcraft SDK 2.0.
55
+ *
56
+ * Posts to `{baseUrl}/api/rpc` with the unified RPC envelope.
57
+ * Supports both JSON responses and SSE streaming.
58
+ */
59
+ export declare class HttpNamespaceTransport implements NamespaceTransport {
60
+ private readonly _rpcUrl;
61
+ private readonly _authToken;
62
+ private readonly _credentials;
63
+ private readonly _timeoutMs;
64
+ private readonly _headers;
65
+ private _closed;
66
+ /**
67
+ * @param baseUrl - Base URL of the Soulcraft server (e.g. `'https://workshop.soulcraft.com'`).
68
+ * @param options - Transport options.
69
+ */
70
+ constructor(baseUrl: string, options?: HttpNamespaceTransportOptions);
71
+ /**
72
+ * Dispatch a namespace-aware RPC call over HTTP POST.
73
+ *
74
+ * @param ns - Target namespace.
75
+ * @param method - Method within the namespace.
76
+ * @param args - Positional arguments.
77
+ * @returns The handler's return value.
78
+ */
79
+ callNs(ns: string, method: string, args: unknown[]): Promise<unknown>;
80
+ /**
81
+ * Dispatch a streaming namespace-aware RPC call.
82
+ *
83
+ * Sends the request with `stream: true` and reads the response as SSE.
84
+ *
85
+ * @param ns - Target namespace.
86
+ * @param method - Method within the namespace.
87
+ * @param args - Positional arguments.
88
+ * @returns An async iterable of response chunks.
89
+ */
90
+ callNsStream(ns: string, method: string, args: unknown[]): AsyncIterable<unknown>;
91
+ /** Returns `true` when the transport is open. */
92
+ isAlive(): boolean;
93
+ /** Close the transport. Further calls throw `SDKDisconnectedError`. */
94
+ close(): Promise<void>;
95
+ }
96
+ /**
97
+ * Namespace-aware PostMessage transport for kit apps in WebContainer iframes.
98
+ *
99
+ * Uses the unified `soulcraft:request` / `soulcraft:response` / `soulcraft:stream`
100
+ * wire protocol instead of the legacy `brainy:request` + `workshop:request` split.
101
+ */
102
+ export declare class PostMessageNamespaceTransport implements NamespaceTransport {
103
+ private readonly _targetOrigin;
104
+ private readonly _timeoutMs;
105
+ private readonly _pending;
106
+ private readonly _pendingStreams;
107
+ private _closed;
108
+ private readonly _messageListener;
109
+ private readonly _listenerWindow;
110
+ private readonly _parentWindow;
111
+ /**
112
+ * @param targetOrigin - The parent frame's origin for security.
113
+ * @param timeoutMs - Per-call timeout. Default: 60 000.
114
+ * @param listenerWindow - Window for message events. Defaults to `window`.
115
+ * @param parentWindow - Window to post messages to. Defaults to `window.parent`.
116
+ */
117
+ constructor(targetOrigin: string, timeoutMs?: number, listenerWindow?: {
118
+ addEventListener: Function;
119
+ removeEventListener: Function;
120
+ }, parentWindow?: {
121
+ postMessage: Function;
122
+ });
123
+ private _handleMessage;
124
+ private _streamTimeout;
125
+ /**
126
+ * Dispatch a namespace-aware RPC call via PostMessage.
127
+ *
128
+ * Posts a `soulcraft:request` message to the parent window and waits for a
129
+ * matching `soulcraft:response` message keyed by request ID.
130
+ *
131
+ * @param ns - Target namespace (e.g. `'brainy'`, `'chat'`).
132
+ * @param method - Method within the namespace.
133
+ * @param args - Positional arguments.
134
+ * @returns The handler's return value from the parent frame.
135
+ * @throws {SDKDisconnectedError} If the transport is closed.
136
+ * @throws {SDKTimeoutError} If no response arrives within `timeoutMs`.
137
+ * @throws {SDKRpcError} If the parent frame returns an error.
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * const graph = await transport.callNs('graph', 'getData', [])
142
+ * ```
143
+ */
144
+ callNs(ns: string, method: string, args: unknown[]): Promise<unknown>;
145
+ /**
146
+ * Dispatch a streaming namespace-aware RPC call via PostMessage.
147
+ *
148
+ * Posts a `soulcraft:request` message with `stream: true`. The parent frame
149
+ * responds with a series of `soulcraft:stream` messages, each containing a
150
+ * `chunk`, `done`, or `error` field. Chunks are buffered and yielded through
151
+ * the returned async iterable.
152
+ *
153
+ * @param ns - Target namespace.
154
+ * @param method - Method within the namespace.
155
+ * @param args - Positional arguments.
156
+ * @returns An async iterable that yields response chunks.
157
+ * @throws {SDKDisconnectedError} If the transport is closed.
158
+ * @throws {SDKRpcError} If the stream receives an error frame.
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * for await (const chunk of transport.callNsStream('chat', 'sendStreaming', [msg])) {
163
+ * process.stdout.write(chunk.text)
164
+ * }
165
+ * ```
166
+ */
167
+ callNsStream(ns: string, method: string, args: unknown[]): AsyncIterable<unknown>;
168
+ /**
169
+ * Returns `true` when the transport has an active connection.
170
+ *
171
+ * Once {@link close} is called, this returns `false` permanently.
172
+ */
173
+ isAlive(): boolean;
174
+ /**
175
+ * Close the transport and clean up all pending calls.
176
+ *
177
+ * Removes the global `message` event listener, rejects all pending call
178
+ * promises with {@link SDKDisconnectedError}, and terminates all active
179
+ * streams. Further calls to {@link callNs} or {@link callNsStream} will
180
+ * throw immediately.
181
+ */
182
+ close(): Promise<void>;
183
+ }
184
+ /**
185
+ * @description SDK 2.0 canonical HTTP transport. Alias for {@link HttpNamespaceTransport}.
186
+ *
187
+ * Sends RPC calls as JSON POST to `/api/rpc` with the unified `{ ns, method, args }` envelope.
188
+ * Supports streaming via SSE.
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * import { HttpTransport, createSoulcraftProxy } from '@soulcraft/sdk/client'
193
+ * const sdk = createSoulcraftProxy(new HttpTransport('/api'))
194
+ * ```
195
+ */
196
+ export { HttpNamespaceTransport as HttpRpcTransport };
197
+ /**
198
+ * @description SDK 2.0 canonical PostMessage transport. Alias for {@link PostMessageNamespaceTransport}.
199
+ *
200
+ * Uses the unified `soulcraft:request` / `soulcraft:response` / `soulcraft:stream`
201
+ * wire protocol for kit apps in WebContainer iframes.
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * import { PostMessageRpcTransport, createSoulcraftProxy } from '@soulcraft/sdk/client'
206
+ * const sdk = createSoulcraftProxy(new PostMessageRpcTransport(parentOrigin))
207
+ * ```
208
+ */
209
+ export { PostMessageNamespaceTransport as PostMessageRpcTransport };
210
+ //# sourceMappingURL=http-namespace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-namespace.d.ts","sourceRoot":"","sources":["../../src/transports/http-namespace.ts"],"names":[],"mappings":"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"}