@silkweave/nestjs 1.9.1 → 1.10.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.
@@ -1,17 +1,17 @@
1
-
2
- $ tsdown
3
- ℹ tsdown v0.21.10 powered by rolldown v1.0.0-rc.17
4
- ℹ config file: /Users/atomic/projects/silkweave/silkweave/packages/nestjs/tsdown.config.ts
5
- ℹ entry: src/index.ts
6
- ℹ tsconfig: tsconfig.json
7
- ℹ Build start
8
- ℹ Hint: consider adding deps.onlyBundle option to avoid unintended bundling of dependencies, or set deps.onlyBundle: false to disable this hint.
9
- See more at https://tsdown.dev/options/dependencies#deps-onlybundle
10
- Detected dependencies in bundle:
11
- - rxjs
12
- ℹ build/index.mjs 337.24 kB │ gzip: 49.36 kB
13
- ℹ build/index.mjs.map 574.64 kB │ gzip: 86.89 kB
14
- ℹ build/index.d.mts.map  2.92 kB │ gzip: 1.06 kB
15
- ℹ build/index.d.mts  15.61 kB │ gzip: 5.45 kB
16
- ℹ 4 files, total: 930.42 kB
17
- ✔ Build complete in 1171ms
1
+ $ tsdown
2
+ ℹ tsdown v0.21.10 powered by rolldown v1.0.0-rc.17
3
+ ℹ config file: /Users/atomic/projects/silkweave/silkweave/packages/nestjs/tsdown.config.ts
4
+ ℹ entry: src/index.ts
5
+ ℹ tsconfig: tsconfig.json
6
+ ℹ Build start
7
+ ℹ Cleaning 4 files
8
+ ℹ Hint: consider adding deps.onlyBundle option to avoid unintended bundling of dependencies, or set deps.onlyBundle: false to disable this hint.
9
+ See more at https://tsdown.dev/options/dependencies#deps-onlybundle
10
+ Detected dependencies in bundle:
11
+ - rxjs
12
+ ℹ build/index.mjs 337.92 kB │ gzip: 49.52 kB
13
+ ℹ build/index.mjs.map 576.49 kB │ gzip: 87.36 kB
14
+ ℹ build/index.d.mts.map  2.98 kB │ gzip: 1.07 kB
15
+ ℹ build/index.d.mts  15.96 kB │ gzip: 5.58 kB
16
+ ℹ 4 files, total: 933.34 kB
17
+ ✔ Build complete in 1110ms
@@ -11,9 +11,9 @@
11
11
  See more at https://tsdown.dev/options/dependencies#deps-onlybundle
12
12
  Detected dependencies in bundle:
13
13
  - rxjs
14
- ℹ build/index.mjs 337.24 kB │ gzip: 49.36 kB
15
- ℹ build/index.mjs.map 574.64 kB │ gzip: 86.89 kB
16
- ℹ build/index.d.mts.map  2.92 kB │ gzip: 1.06 kB
17
- ℹ build/index.d.mts  15.61 kB │ gzip: 5.45 kB
18
- ℹ 4 files, total: 930.42 kB
19
- ✔ Build complete in 831ms
14
+ ℹ build/index.mjs 337.92 kB │ gzip: 49.52 kB
15
+ ℹ build/index.mjs.map 576.49 kB │ gzip: 87.36 kB
16
+ ℹ build/index.d.mts.map  2.98 kB │ gzip: 1.07 kB
17
+ ℹ build/index.d.mts  15.96 kB │ gzip: 5.58 kB
18
+ ℹ 4 files, total: 933.34 kB
19
+ ✔ Build complete in 828ms
package/README.md CHANGED
@@ -110,6 +110,7 @@ The `users.list` and `users.get` actions are now reachable via:
110
110
  | `description` | `string` | *required* | Human-readable summary. Used as MCP tool description |
111
111
  | `input` | `z.ZodObject` | *required* | Zod object schema for the action's input |
112
112
  | `output` | `z.ZodObject` | - | Optional output schema (used by tRPC type inference) |
113
+ | `chunk` | `z.ZodType` | - | Schema for chunks yielded by a streaming (`async function*`) method. **Required** when the method is an async generator |
113
114
  | `kind` | `'query' \| 'mutation'` | `'mutation'` | `'query'` → GET in REST, `.query()` in tRPC. `'mutation'` → POST / `.mutation()` |
114
115
  | `transports` | `('rest' \| 'trpc' \| 'mcp')[]` | all | Allowlist of transports that expose this action |
115
116
  | `isEnabled` | `(ctx) => boolean` | - | Dynamic gate (AND-combined with `transports`) |
@@ -158,6 +159,24 @@ Mounts a tRPC HTTP handler built from `@silkweave/trpc`'s `buildRouter`.
158
159
 
159
160
  Action names with dots (e.g. `users.list`) collapse to camelCase procedure keys (`usersList`) - flat router in v1.
160
161
 
162
+ **Streaming.** An `@Action` method declared as an `async function*` (with a `chunk` schema) is registered as a tRPC **subscription** that streams each yielded chunk over SSE - exactly like a standalone `createAction({ chunk, run: async function*(){…} })`. `@UseGuards()` guards still run before the first chunk. This is what `useChat` + `@silkweave/ai`'s `silkweaveTransport()` consume.
163
+
164
+ ```ts
165
+ @Action({
166
+ description: 'Stream a countdown',
167
+ input: z.object({ from: z.number().int() }),
168
+ chunk: z.object({ n: z.number().int() })
169
+ })
170
+ async *countdown(input: { from: number }) {
171
+ for (let n = input.from; n >= 0; n -= 1) {
172
+ await new Promise((r) => setTimeout(r, 200))
173
+ yield { n }
174
+ }
175
+ }
176
+ ```
177
+
178
+ Declaring an async-generator method without a `chunk` schema throws at discovery time - the schema is required for typegen/tRPC to expose the subscription.
179
+
161
180
  ### `mcp(options?)`
162
181
 
163
182
  Mounts the MCP Streamable HTTP transport directly at `basePath`, with sideload (`{basePath}/resource/:id`), well-known auth metadata (`{basePath}/.well-known/...`), and the OAuth proxy routes (`{basePath}/authorize`, `/token`, `/register`, `/auth/callback`) namespaced under the same prefix. Composes the handler primitives from `@silkweave/mcp` - no Express sub-app.
package/build/index.d.mts CHANGED
@@ -157,7 +157,7 @@ declare function typegen(options: TypegenAdapterOptions): NestSilkweaveAdapter;
157
157
  declare const ACTION_METADATA = "__silkweave_action__";
158
158
  declare const ACTIONS_METADATA = "__silkweave_actions__";
159
159
  type Transport = 'rest' | 'trpc' | 'mcp';
160
- interface ActionMetadata<I extends object = object, O extends object = object> {
160
+ interface ActionMetadata<I extends object = object, O extends object = object, C = unknown> {
161
161
  /** Action name. Defaults to the kebab-cased method name. */
162
162
  name?: string;
163
163
  /** Human-readable description. Becomes the MCP tool description and REST OpenAPI summary. */
@@ -170,6 +170,13 @@ interface ActionMetadata<I extends object = object, O extends object = object> {
170
170
  output?: z$1.ZodType<O> & {
171
171
  shape: Record<string, z$1.ZodTypeAny>;
172
172
  };
173
+ /**
174
+ * Zod schema for individual chunks yielded by a streaming (async-generator)
175
+ * action method. Required when the decorated method is an `async function*`.
176
+ * Mirrors `Action.chunk` in @silkweave/core; typegen/trpc use it to expose
177
+ * the action as a tRPC subscription.
178
+ */
179
+ chunk?: z$1.ZodType<C>;
173
180
  /** `'query'` (GET in REST, `.query()` in tRPC) or `'mutation'` (POST in REST, `.mutation()` in tRPC). Default: `'mutation'`. */
174
181
  kind?: ActionKind;
175
182
  /** Allowlist of transports that should expose this action. Default: all registered transports. */
@@ -226,7 +233,7 @@ declare const ACTION_RESPONSE_KEY = "__silkweave_response__";
226
233
  * }
227
234
  * ```
228
235
  */
229
- declare function Action<I extends object = object, O extends object = object>(options: ActionMetadata<I, O>): MethodDecorator;
236
+ declare function Action<I extends object = object, O extends object = object, C = unknown>(options: ActionMetadata<I, O, C>): MethodDecorator;
230
237
  //#endregion
231
238
  //#region src/decorator/actions.d.ts
232
239
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/lib/types.ts","../src/adapter/mcp.ts","../src/adapter/rest.ts","../src/adapter/trpc.ts","../src/adapter/typegen.ts","../src/lib/metadata.ts","../src/decorator/action.ts","../src/decorator/actions.ts","../src/lib/discovery.ts","../src/lib/filter.ts","../src/lib/guards.ts","../src/lib/silkweave.module.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/lib/types.ts","../src/adapter/mcp.ts","../src/adapter/rest.ts","../src/adapter/trpc.ts","../src/adapter/typegen.ts","../src/lib/metadata.ts","../src/decorator/action.ts","../src/decorator/actions.ts","../src/lib/discovery.ts","../src/lib/filter.ts","../src/lib/guards.ts","../src/lib/silkweave.module.ts"],"mappings":"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"}
package/build/index.mjs CHANGED
@@ -9116,6 +9116,31 @@ let ActionDiscovery = class ActionDiscovery {
9116
9116
  const guards = collectGuards(this.reflector, d.classRef, d.method);
9117
9117
  const moduleRef = this.moduleRef;
9118
9118
  const reflector = this.reflector;
9119
+ const applyGuards = async (context) => {
9120
+ if (guards.length === 0) return;
9121
+ const request = context.getOptional("request");
9122
+ const response = context.getOptional("response");
9123
+ await runGuards(guards, moduleRef, reflector, d.classRef, d.method, request, response);
9124
+ };
9125
+ if (d.method.constructor?.name === "AsyncGeneratorFunction") {
9126
+ if (!d.meta.chunk) throw new Error(`@Action "${name}" is an async generator but has no \`chunk\` schema`);
9127
+ const method = d.method;
9128
+ const instance = d.instance;
9129
+ return createAction({
9130
+ name,
9131
+ description: d.meta.description,
9132
+ input: d.meta.input,
9133
+ chunk: d.meta.chunk,
9134
+ kind: d.meta.kind ?? "mutation",
9135
+ args: d.meta.args,
9136
+ isEnabled,
9137
+ toolResult: d.meta.toolResult,
9138
+ run: async function* (input, context) {
9139
+ await applyGuards(context);
9140
+ yield* method.call(instance, input, context);
9141
+ }
9142
+ });
9143
+ }
9119
9144
  return createAction({
9120
9145
  name,
9121
9146
  description: d.meta.description,
@@ -9126,11 +9151,7 @@ let ActionDiscovery = class ActionDiscovery {
9126
9151
  isEnabled,
9127
9152
  toolResult: d.meta.toolResult,
9128
9153
  run: async (input, context) => {
9129
- if (guards.length > 0) {
9130
- const request = context.getOptional("request");
9131
- const response = context.getOptional("response");
9132
- await runGuards(guards, moduleRef, reflector, d.classRef, d.method, request, response);
9133
- }
9154
+ await applyGuards(context);
9134
9155
  return await d.method.call(d.instance, input, context);
9135
9156
  }
9136
9157
  });