ts-procedures 3.1.0 → 3.3.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 (54) hide show
  1. package/README.md +222 -2
  2. package/build/errors.d.ts +19 -3
  3. package/build/errors.js +54 -5
  4. package/build/errors.js.map +1 -1
  5. package/build/errors.test.js +82 -0
  6. package/build/errors.test.js.map +1 -1
  7. package/build/exports.d.ts +1 -0
  8. package/build/exports.js +1 -0
  9. package/build/exports.js.map +1 -1
  10. package/build/implementations/http/hono-stream/index.d.ts +92 -0
  11. package/build/implementations/http/hono-stream/index.js +229 -0
  12. package/build/implementations/http/hono-stream/index.js.map +1 -0
  13. package/build/implementations/http/hono-stream/index.test.d.ts +1 -0
  14. package/build/implementations/http/hono-stream/index.test.js +681 -0
  15. package/build/implementations/http/hono-stream/index.test.js.map +1 -0
  16. package/build/implementations/http/hono-stream/types.d.ts +24 -0
  17. package/build/implementations/http/hono-stream/types.js +2 -0
  18. package/build/implementations/http/hono-stream/types.js.map +1 -0
  19. package/build/implementations/types.d.ts +15 -1
  20. package/build/index.d.ts +62 -3
  21. package/build/index.js +111 -6
  22. package/build/index.js.map +1 -1
  23. package/build/index.test.js +385 -2
  24. package/build/index.test.js.map +1 -1
  25. package/build/schema/compute-schema.d.ts +9 -2
  26. package/build/schema/compute-schema.js +9 -3
  27. package/build/schema/compute-schema.js.map +1 -1
  28. package/build/schema/parser.d.ts +6 -0
  29. package/build/schema/parser.js +42 -0
  30. package/build/schema/parser.js.map +1 -1
  31. package/build/schema/types.d.ts +1 -0
  32. package/build/stack-utils.d.ts +25 -0
  33. package/build/stack-utils.js +95 -0
  34. package/build/stack-utils.js.map +1 -0
  35. package/build/stack-utils.test.d.ts +1 -0
  36. package/build/stack-utils.test.js +80 -0
  37. package/build/stack-utils.test.js.map +1 -0
  38. package/package.json +1 -1
  39. package/src/errors.test.ts +110 -0
  40. package/src/errors.ts +65 -3
  41. package/src/exports.ts +1 -0
  42. package/src/implementations/http/README.md +87 -55
  43. package/src/implementations/http/hono-stream/README.md +261 -0
  44. package/src/implementations/http/hono-stream/index.test.ts +1009 -0
  45. package/src/implementations/http/hono-stream/index.ts +327 -0
  46. package/src/implementations/http/hono-stream/types.ts +29 -0
  47. package/src/implementations/types.ts +17 -1
  48. package/src/index.test.ts +525 -41
  49. package/src/index.ts +210 -8
  50. package/src/schema/compute-schema.ts +15 -3
  51. package/src/schema/parser.ts +55 -4
  52. package/src/schema/types.ts +4 -0
  53. package/src/stack-utils.test.ts +94 -0
  54. package/src/stack-utils.ts +129 -0
package/README.md CHANGED
@@ -71,6 +71,34 @@ Create(name, config, handler)
71
71
  - `procedure` - Generic reference to the handler
72
72
  - `info` - Procedure meta (name, description, schema, `TExtendedConfig` properties, etc.)
73
73
 
74
+ ### CreateStream Function
75
+
76
+ The `CreateStream` function defines streaming procedures that yield values over time using async generators:
77
+
78
+ ```typescript
79
+ CreateStream(name, config, handler)
80
+ ```
81
+
82
+ **Config Options:**
83
+ - `schema.params` - Input parameter schema (validated at runtime)
84
+ - `schema.yieldType` - Schema for each yielded value (validated if `validateYields: true`)
85
+ - `schema.returnType` - Schema for final return value (documentation only)
86
+ - `validateYields` - Enable runtime validation of yielded values (default: `false`)
87
+
88
+ **Handler Signature:**
89
+ ```typescript
90
+ async function* (ctx, params) => AsyncGenerator<TYield, TReturn | void>
91
+ ```
92
+
93
+ **Context Extensions:**
94
+ - `ctx.error(message, meta?)` - Create a ProcedureError
95
+ - `ctx.signal` - AbortSignal for cancellation support
96
+
97
+ **Returns:**
98
+ - `{ [name]: handler }` - Named generator export
99
+ - `procedure` - Generic reference to the generator
100
+ - `info` - Procedure meta with `isStream: true`
101
+
74
102
  ## Using Generics
75
103
 
76
104
  ### Base Context
@@ -237,6 +265,193 @@ AJV is configured with:
237
265
 
238
266
  **Note:** `schema.params` is validated at runtime. `schema.returnType` is for documentation/introspection only.
239
267
 
268
+ ## Streaming Procedures
269
+
270
+ Streaming procedures use async generators to yield values over time, enabling SSE (Server-Sent Events), HTTP streaming, and real-time data feeds.
271
+
272
+ ### Basic Streaming
273
+
274
+ ```typescript
275
+ import { Procedures } from 'ts-procedures'
276
+ import { v } from 'suretype'
277
+
278
+ const { CreateStream } = Procedures<{ userId: string }>()
279
+
280
+ const { StreamUpdates } = CreateStream(
281
+ 'StreamUpdates',
282
+ {
283
+ description: 'Stream real-time updates',
284
+ schema: {
285
+ params: v.object({ topic: v.string().required() }),
286
+ yieldType: v.object({
287
+ id: v.string().required(),
288
+ message: v.string().required(),
289
+ timestamp: v.number().required(),
290
+ }),
291
+ },
292
+ },
293
+ async function* (ctx, params) {
294
+ // Types are inferred from schema:
295
+ // - params.topic: string
296
+ // - yield value must match { id, message, timestamp }
297
+ // - ctx.signal: AbortSignal for cancellation
298
+
299
+ let counter = 0
300
+ while (!ctx.signal.aborted) {
301
+ yield {
302
+ id: `${counter++}`,
303
+ message: `Update for ${params.topic}`,
304
+ timestamp: Date.now(),
305
+ }
306
+ await new Promise(r => setTimeout(r, 1000))
307
+ }
308
+ },
309
+ )
310
+
311
+ // Consume the stream
312
+ for await (const update of StreamUpdates({ userId: 'user-123' }, { topic: 'news' })) {
313
+ console.log(update.message)
314
+ }
315
+ ```
316
+
317
+ ### Yield Validation
318
+
319
+ By default, yielded values are not validated for performance. Enable validation with `validateYields: true`:
320
+
321
+ ```typescript
322
+ const { ValidatedStream } = CreateStream(
323
+ 'ValidatedStream',
324
+ {
325
+ schema: {
326
+ yieldType: v.object({ count: v.number().required() }),
327
+ },
328
+ validateYields: true, // Enable runtime validation of each yield
329
+ },
330
+ async function* () {
331
+ yield { count: 1 } // Valid
332
+ yield { count: 2 } // Valid
333
+ // yield { count: 'invalid' } // Would throw ProcedureYieldValidationError
334
+ },
335
+ )
336
+ ```
337
+
338
+ ### Abort Signal Integration
339
+
340
+ The `ctx.signal` allows handlers to detect when consumers stop iterating:
341
+
342
+ ```typescript
343
+ const { CancellableStream } = CreateStream(
344
+ 'CancellableStream',
345
+ {},
346
+ async function* (ctx) {
347
+ try {
348
+ while (!ctx.signal.aborted) {
349
+ yield await fetchNextItem()
350
+ }
351
+ } finally {
352
+ // Cleanup when stream ends (consumer stopped or completed)
353
+ await cleanup()
354
+ }
355
+ },
356
+ )
357
+
358
+ // Consumer can break early - signal.aborted becomes true
359
+ for await (const item of CancellableStream({}, {})) {
360
+ if (shouldStop) break // Triggers abort
361
+ }
362
+ ```
363
+
364
+ ### SSE Integration Example
365
+
366
+ ```typescript
367
+ import express from 'express'
368
+ import { Procedures } from 'ts-procedures'
369
+
370
+ const app = express()
371
+
372
+ const { CreateStream, getProcedures } = Procedures<{ req: express.Request }>({
373
+ onCreate: (proc) => {
374
+ if (proc.isStream) {
375
+ // Register streaming procedures as SSE endpoints
376
+ app.get(`/stream/${proc.name}`, async (req, res) => {
377
+ res.writeHead(200, {
378
+ 'Content-Type': 'text/event-stream',
379
+ 'Cache-Control': 'no-cache',
380
+ 'Connection': 'keep-alive',
381
+ })
382
+
383
+ const generator = proc.handler({ req }, req.query)
384
+
385
+ req.on('close', async () => {
386
+ // Client disconnected - stop the generator
387
+ await generator.return(undefined)
388
+ })
389
+
390
+ try {
391
+ for await (const data of generator) {
392
+ res.write(`data: ${JSON.stringify(data)}\n\n`)
393
+ }
394
+ } finally {
395
+ res.end()
396
+ }
397
+ })
398
+ }
399
+ },
400
+ })
401
+
402
+ // Define a streaming procedure
403
+ CreateStream(
404
+ 'LiveFeed',
405
+ {
406
+ schema: {
407
+ params: v.object({ channel: v.string() }),
408
+ yieldType: v.object({ event: v.string(), data: v.any() }),
409
+ },
410
+ },
411
+ async function* (ctx, params) {
412
+ while (!ctx.signal.aborted) {
413
+ const event = await pollForEvent(params.channel)
414
+ yield event
415
+ }
416
+ },
417
+ )
418
+
419
+ app.listen(3000)
420
+ // SSE endpoint: GET /stream/LiveFeed?channel=updates
421
+ ```
422
+
423
+ ### Stream Errors
424
+
425
+ Streaming procedures support the same error handling as regular procedures:
426
+
427
+ ```typescript
428
+ const { StreamWithErrors } = CreateStream(
429
+ 'StreamWithErrors',
430
+ {},
431
+ async function* (ctx) {
432
+ yield { status: 'starting' }
433
+
434
+ const data = await fetchData()
435
+ if (!data) {
436
+ throw ctx.error('No data available', { code: 'NO_DATA' })
437
+ }
438
+
439
+ yield { status: 'complete', data }
440
+ },
441
+ )
442
+
443
+ try {
444
+ for await (const item of StreamWithErrors({}, {})) {
445
+ console.log(item)
446
+ }
447
+ } catch (e) {
448
+ if (e instanceof ProcedureError) {
449
+ console.log(e.message) // 'No data available'
450
+ console.log(e.meta) // { code: 'NO_DATA' }
451
+ }
452
+ }
453
+ ```
454
+
240
455
  ## Error Handling
241
456
 
242
457
  ### Using ctx.error()
@@ -262,7 +477,8 @@ Create(
262
477
  | Error Class | Trigger |
263
478
  |-------------|---------|
264
479
  | ProcedureError | `ctx.error()` in handlers |
265
- | ProcedureValidationError | Schema validation failure |
480
+ | ProcedureValidationError | Schema validation failure (params) |
481
+ | ProcedureYieldValidationError | Yield validation failure (streaming with `validateYields: true`) |
266
482
  | ProcedureRegistrationError | Invalid schema at registration |
267
483
 
268
484
  ### Error Properties
@@ -470,10 +686,13 @@ import {
470
686
  ProcedureError,
471
687
  ProcedureValidationError,
472
688
  ProcedureRegistrationError,
473
-
689
+ ProcedureYieldValidationError, // For streaming yield validation
690
+
474
691
  // Types
475
692
  TLocalContext,
693
+ TStreamContext, // Streaming context with AbortSignal
476
694
  TProcedureRegistration,
695
+ TStreamProcedureRegistration, // Streaming procedure registration
477
696
  TNoContextProvided,
478
697
 
479
698
  // Schema utilities
@@ -485,6 +704,7 @@ import {
485
704
  // Schema types
486
705
  TJSONSchema,
487
706
  TSchemaLib,
707
+ TSchemaLibGenerator, // AsyncGenerator type utility
488
708
  TSchemaParsed,
489
709
  TSchemaValidationError,
490
710
  Prettify,
package/build/errors.d.ts CHANGED
@@ -1,17 +1,33 @@
1
1
  import { TSchemaValidationError } from './schema/parser.js';
2
+ import { DefinitionInfo, DefinitionLocation } from './stack-utils.js';
2
3
  export declare class ProcedureError extends Error {
3
4
  readonly procedureName: string;
4
5
  readonly message: string;
5
6
  readonly meta?: object | undefined;
6
7
  cause?: unknown;
7
- constructor(procedureName: string, message: string, meta?: object | undefined);
8
+ readonly definedAt?: DefinitionLocation;
9
+ readonly definitionStack?: string;
10
+ constructor(procedureName: string, message: string, meta?: object | undefined, definitionInfo?: DefinitionInfo);
11
+ /**
12
+ * Returns a formatted string showing where the procedure was defined.
13
+ */
14
+ getDefinitionLocation(): string | undefined;
15
+ /**
16
+ * Enhances the error stack with definition location information.
17
+ */
18
+ private enhanceStack;
8
19
  }
9
20
  export declare class ProcedureValidationError extends ProcedureError {
10
21
  readonly procedureName: string;
11
22
  readonly errors?: TSchemaValidationError[] | undefined;
12
- constructor(procedureName: string, message: string, errors?: TSchemaValidationError[] | undefined);
23
+ constructor(procedureName: string, message: string, errors?: TSchemaValidationError[] | undefined, definitionInfo?: DefinitionInfo);
13
24
  }
14
25
  export declare class ProcedureRegistrationError extends ProcedureError {
15
26
  readonly procedureName: string;
16
- constructor(procedureName: string, message: string);
27
+ constructor(procedureName: string, message: string, definitionInfo?: DefinitionInfo);
28
+ }
29
+ export declare class ProcedureYieldValidationError extends ProcedureError {
30
+ readonly procedureName: string;
31
+ readonly errors?: TSchemaValidationError[] | undefined;
32
+ constructor(procedureName: string, message: string, errors?: TSchemaValidationError[] | undefined, definitionInfo?: DefinitionInfo);
17
33
  }
package/build/errors.js CHANGED
@@ -1,23 +1,56 @@
1
+ import { formatDefinitionInfo } from './stack-utils.js';
1
2
  export class ProcedureError extends Error {
2
3
  procedureName;
3
4
  message;
4
5
  meta;
5
6
  cause;
6
- constructor(procedureName, message, meta) {
7
+ definedAt;
8
+ definitionStack;
9
+ constructor(procedureName, message, meta,
10
+ // Used for error stack trace details
11
+ definitionInfo) {
7
12
  super(message);
8
13
  this.procedureName = procedureName;
9
14
  this.message = message;
10
15
  this.meta = meta;
11
16
  this.name = 'ProcedureError';
17
+ if (definitionInfo) {
18
+ this.definedAt = definitionInfo.definedAt;
19
+ this.definitionStack = definitionInfo.definitionStack;
20
+ this.enhanceStack();
21
+ }
12
22
  // https://www.dannyguo.com/blog/how-to-fix-instanceof-not-working-for-custom-errors-in-typescript/
13
23
  Object.setPrototypeOf(this, ProcedureError.prototype);
14
24
  }
25
+ /**
26
+ * Returns a formatted string showing where the procedure was defined.
27
+ */
28
+ getDefinitionLocation() {
29
+ if (!this.definedAt) {
30
+ return undefined;
31
+ }
32
+ return `${this.definedAt.file}:${this.definedAt.line}:${this.definedAt.column}`;
33
+ }
34
+ /**
35
+ * Enhances the error stack with definition location information.
36
+ */
37
+ enhanceStack() {
38
+ if (!this.stack || !this.definedAt) {
39
+ return;
40
+ }
41
+ const definitionSection = formatDefinitionInfo({ definedAt: this.definedAt, definitionStack: this.definitionStack }, this.procedureName);
42
+ if (definitionSection) {
43
+ this.stack = this.stack + definitionSection;
44
+ }
45
+ }
15
46
  }
16
47
  export class ProcedureValidationError extends ProcedureError {
17
48
  procedureName;
18
49
  errors;
19
- constructor(procedureName, message, errors) {
20
- super(procedureName, message);
50
+ constructor(procedureName, message, errors,
51
+ // Used for error stack trace details
52
+ definitionInfo) {
53
+ super(procedureName, message, undefined, definitionInfo);
21
54
  this.procedureName = procedureName;
22
55
  this.errors = errors;
23
56
  this.name = 'ProcedureValidationError';
@@ -27,12 +60,28 @@ export class ProcedureValidationError extends ProcedureError {
27
60
  }
28
61
  export class ProcedureRegistrationError extends ProcedureError {
29
62
  procedureName;
30
- constructor(procedureName, message) {
31
- super(procedureName, message);
63
+ constructor(procedureName, message,
64
+ // Used for error stack trace details
65
+ definitionInfo) {
66
+ super(procedureName, message, undefined, definitionInfo);
32
67
  this.procedureName = procedureName;
33
68
  this.name = 'ProcedureRegistrationError';
34
69
  // https://www.dannyguo.com/blog/how-to-fix-instanceof-not-working-for-custom-errors-in-typescript/
35
70
  Object.setPrototypeOf(this, ProcedureRegistrationError.prototype);
36
71
  }
37
72
  }
73
+ export class ProcedureYieldValidationError extends ProcedureError {
74
+ procedureName;
75
+ errors;
76
+ constructor(procedureName, message, errors,
77
+ // Used for error stack trace details
78
+ definitionInfo) {
79
+ super(procedureName, message, undefined, definitionInfo);
80
+ this.procedureName = procedureName;
81
+ this.errors = errors;
82
+ this.name = 'ProcedureYieldValidationError';
83
+ // https://www.dannyguo.com/blog/how-to-fix-instanceof-not-working-for-custom-errors-in-typescript/
84
+ Object.setPrototypeOf(this, ProcedureYieldValidationError.prototype);
85
+ }
86
+ }
38
87
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,cAAe,SAAQ,KAAK;IAI5B;IACA;IACA;IALX,KAAK,CAAU;IAEf,YACW,aAAqB,EACrB,OAAe,EACf,IAAa;QAEtB,KAAK,CAAC,OAAO,CAAC,CAAA;QAJL,kBAAa,GAAb,aAAa,CAAQ;QACrB,YAAO,GAAP,OAAO,CAAQ;QACf,SAAI,GAAJ,IAAI,CAAS;QAGtB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;QAE5B,mGAAmG;QACnG,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,cAAc,CAAC,SAAS,CAAC,CAAA;IACvD,CAAC;CACF;AAED,MAAM,OAAO,wBAAyB,SAAQ,cAAc;IAE/C;IAEA;IAHX,YACW,aAAqB,EAC9B,OAAe,EACN,MAAiC;QAE1C,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,CAAA;QAJpB,kBAAa,GAAb,aAAa,CAAQ;QAErB,WAAM,GAAN,MAAM,CAA2B;QAG1C,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAA;QAEtC,mGAAmG;QACnG,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,wBAAwB,CAAC,SAAS,CAAC,CAAA;IACjE,CAAC;CACF;AAED,MAAM,OAAO,0BAA2B,SAAQ,cAAc;IACvC;IAArB,YAAqB,aAAqB,EAAE,OAAe;QACzD,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,CAAA;QADV,kBAAa,GAAb,aAAa,CAAQ;QAExC,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAA;QAExC,mGAAmG;QACnG,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,0BAA0B,CAAC,SAAS,CAAC,CAAA;IACnE,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -37,4 +37,86 @@ describe('Error Classes', () => {
37
37
  expect(registrationErr.procedureName).toBe('Proc3');
38
38
  });
39
39
  });
40
+ describe('Error Classes - Definition Info', () => {
41
+ const mockDefinitionInfo = {
42
+ definedAt: {
43
+ file: '/app/procedures/user.ts',
44
+ line: 25,
45
+ column: 3,
46
+ raw: 'at Object.<anonymous> (/app/procedures/user.ts:25:3)',
47
+ },
48
+ definitionStack: 'Error\n at Object.<anonymous> (/app/procedures/user.ts:25:3)',
49
+ };
50
+ test('ProcedureError includes definedAt when provided', () => {
51
+ const err = new ProcedureError('TestProc', 'Something failed', undefined, mockDefinitionInfo);
52
+ expect(err.definedAt).toBeDefined();
53
+ expect(err.definedAt?.file).toBe('/app/procedures/user.ts');
54
+ expect(err.definedAt?.line).toBe(25);
55
+ expect(err.definedAt?.column).toBe(3);
56
+ });
57
+ test('ProcedureError includes definitionStack when provided', () => {
58
+ const err = new ProcedureError('TestProc', 'Something failed', undefined, mockDefinitionInfo);
59
+ expect(err.definitionStack).toBeDefined();
60
+ expect(err.definitionStack).toContain('/app/procedures/user.ts');
61
+ });
62
+ test('ProcedureError works without definitionInfo (backward compat)', () => {
63
+ const err = new ProcedureError('TestProc', 'Something failed', { code: 123 });
64
+ expect(err.definedAt).toBeUndefined();
65
+ expect(err.definitionStack).toBeUndefined();
66
+ expect(err.procedureName).toBe('TestProc');
67
+ expect(err.message).toBe('Something failed');
68
+ expect(err.meta).toEqual({ code: 123 });
69
+ });
70
+ test('ProcedureValidationError includes definedAt when provided', () => {
71
+ const err = new ProcedureValidationError('TestProc', 'Validation failed', [], mockDefinitionInfo);
72
+ expect(err.definedAt).toBeDefined();
73
+ expect(err.definedAt?.file).toBe('/app/procedures/user.ts');
74
+ expect(err.definedAt?.line).toBe(25);
75
+ });
76
+ test('ProcedureValidationError works without definitionInfo (backward compat)', () => {
77
+ const err = new ProcedureValidationError('TestProc', 'Validation failed', []);
78
+ expect(err.definedAt).toBeUndefined();
79
+ expect(err.definitionStack).toBeUndefined();
80
+ expect(err.name).toBe('ProcedureValidationError');
81
+ });
82
+ test('ProcedureRegistrationError includes definedAt when provided', () => {
83
+ const err = new ProcedureRegistrationError('TestProc', 'Registration failed', mockDefinitionInfo);
84
+ expect(err.definedAt).toBeDefined();
85
+ expect(err.definedAt?.file).toBe('/app/procedures/user.ts');
86
+ });
87
+ test('ProcedureRegistrationError works without definitionInfo (backward compat)', () => {
88
+ const err = new ProcedureRegistrationError('TestProc', 'Registration failed');
89
+ expect(err.definedAt).toBeUndefined();
90
+ expect(err.definitionStack).toBeUndefined();
91
+ expect(err.name).toBe('ProcedureRegistrationError');
92
+ });
93
+ test('getDefinitionLocation returns formatted location string', () => {
94
+ const err = new ProcedureError('TestProc', 'Something failed', undefined, mockDefinitionInfo);
95
+ const location = err.getDefinitionLocation();
96
+ expect(location).toBe('/app/procedures/user.ts:25:3');
97
+ });
98
+ test('getDefinitionLocation returns undefined when no definedAt', () => {
99
+ const err = new ProcedureError('TestProc', 'Something failed');
100
+ const location = err.getDefinitionLocation();
101
+ expect(location).toBeUndefined();
102
+ });
103
+ test('enhanced stack contains definition location', () => {
104
+ const err = new ProcedureError('TestProc', 'Something failed', undefined, mockDefinitionInfo);
105
+ expect(err.stack).toContain('--- Procedure "TestProc" defined at ---');
106
+ expect(err.stack).toContain('/app/procedures/user.ts:25:3');
107
+ });
108
+ test('stack is not modified when no definitionInfo', () => {
109
+ const err = new ProcedureError('TestProc', 'Something failed');
110
+ expect(err.stack).toBeDefined();
111
+ expect(err.stack).not.toContain('--- Procedure');
112
+ });
113
+ test('all error types enhance stack with definition location', () => {
114
+ const baseErr = new ProcedureError('Proc1', 'message', undefined, mockDefinitionInfo);
115
+ const validationErr = new ProcedureValidationError('Proc2', 'message', [], mockDefinitionInfo);
116
+ const registrationErr = new ProcedureRegistrationError('Proc3', 'message', mockDefinitionInfo);
117
+ expect(baseErr.stack).toContain('--- Procedure "Proc1" defined at ---');
118
+ expect(validationErr.stack).toContain('--- Procedure "Proc2" defined at ---');
119
+ expect(registrationErr.stack).toContain('--- Procedure "Proc3" defined at ---');
120
+ });
121
+ });
40
122
  //# sourceMappingURL=errors.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.test.js","sourceRoot":"","sources":["../src/errors.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.test.js","sourceRoot":"","sources":["../src/errors.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  export * from './index.js';
2
2
  export * from './errors.js';
3
+ export * from './stack-utils.js';
3
4
  export * from './schema/extract-json-schema.js';
4
5
  export * from './schema/parser.js';
5
6
  export * from './schema/resolve-schema-lib.js';
package/build/exports.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './index.js';
2
2
  export * from './errors.js';
3
+ export * from './stack-utils.js';
3
4
  export * from './schema/extract-json-schema.js';
4
5
  export * from './schema/parser.js';
5
6
  export * from './schema/resolve-schema-lib.js';
@@ -1 +1 @@
1
- {"version":3,"file":"exports.js","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,iCAAiC,CAAA;AAC/C,cAAc,oBAAoB,CAAA;AAClC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,mBAAmB,CAAA"}
1
+ {"version":3,"file":"exports.js","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,oBAAoB,CAAA;AAClC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,mBAAmB,CAAA"}
@@ -0,0 +1,92 @@
1
+ import { Hono, Context } from 'hono';
2
+ import { TStreamProcedureRegistration } from '../../../index.js';
3
+ import { ExtractConfig, ExtractContext, ProceduresFactory, RPCConfig } from '../../types.js';
4
+ import { StreamHttpRouteDoc, StreamMode } from './types.js';
5
+ export type { StreamHttpRouteDoc, StreamMode };
6
+ export type HonoStreamAppBuilderConfig = {
7
+ /**
8
+ * An existing Hono application instance to use.
9
+ * If not provided, a new instance will be created.
10
+ */
11
+ app?: Hono;
12
+ /** Optional path prefix for all stream routes. */
13
+ pathPrefix?: string;
14
+ /** Default stream mode for all routes. Defaults to 'sse'. */
15
+ defaultStreamMode?: StreamMode;
16
+ onRequestStart?: (c: Context) => void;
17
+ onRequestEnd?: (c: Context) => void;
18
+ onStreamStart?: (procedure: TStreamProcedureRegistration, c: Context) => void;
19
+ onStreamEnd?: (procedure: TStreamProcedureRegistration, c: Context) => void;
20
+ /**
21
+ * Error handler called when a streaming procedure throws an error.
22
+ */
23
+ onStreamError?: (procedure: TStreamProcedureRegistration, c: Context, error: Error) => Response | Promise<Response>;
24
+ };
25
+ /**
26
+ * Builder class for creating a Hono application with streaming RPC routes.
27
+ *
28
+ * Usage:
29
+ * const StreamRPC = Procedures<StreamContext, RPCConfig>()
30
+ *
31
+ * const streamApp = new HonoStreamAppBuilder()
32
+ * .register(StreamRPC, (c): Promise<StreamContext> => { /* context resolution logic * / })
33
+ * .build();
34
+ *
35
+ * const app = streamApp.app; // Hono application
36
+ * const docs = streamApp.docs; // Stream route documentation
37
+ */
38
+ export declare class HonoStreamAppBuilder {
39
+ readonly config?: HonoStreamAppBuilderConfig | undefined;
40
+ /**
41
+ * Constructor for HonoStreamAppBuilder.
42
+ */
43
+ constructor(config?: HonoStreamAppBuilderConfig | undefined);
44
+ /**
45
+ * Generates the stream route path based on the RPC configuration.
46
+ */
47
+ static makeStreamHttpRoutePath({ name, config, prefix, }: {
48
+ name: string;
49
+ prefix?: string;
50
+ config: RPCConfig;
51
+ }): string;
52
+ /**
53
+ * Instance method wrapper for makeStreamHttpRoutePath that uses the builder's pathPrefix.
54
+ */
55
+ makeStreamHttpRoutePath(name: string, config: RPCConfig): string;
56
+ private factories;
57
+ private _app;
58
+ private _docs;
59
+ get app(): Hono;
60
+ get docs(): StreamHttpRouteDoc[];
61
+ /**
62
+ * Registers a procedure factory with its context.
63
+ * Only streaming procedures (created with CreateStream) will be registered.
64
+ */
65
+ register<TFactory extends ProceduresFactory>(factory: TFactory, factoryContext: ExtractContext<TFactory> | ((c: Context) => ExtractContext<TFactory> | Promise<ExtractContext<TFactory>>), options?: {
66
+ streamMode?: StreamMode;
67
+ extendProcedureDoc?: (params: {
68
+ base: StreamHttpRouteDoc;
69
+ procedure: TStreamProcedureRegistration<any, ExtractConfig<TFactory>>;
70
+ }) => Record<string, any>;
71
+ }): this;
72
+ /**
73
+ * Creates a route handler for streaming procedures.
74
+ */
75
+ private createStreamHandler;
76
+ /**
77
+ * Handles SSE streaming mode.
78
+ */
79
+ private handleSSEStream;
80
+ /**
81
+ * Handles text streaming mode.
82
+ */
83
+ private handleTextStream;
84
+ /**
85
+ * Builds and returns the Hono application with registered streaming routes.
86
+ */
87
+ build(): Hono;
88
+ /**
89
+ * Generates the Stream HTTP route documentation for the given procedure.
90
+ */
91
+ private buildStreamHttpRouteDoc;
92
+ }