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.
- package/README.md +222 -2
- package/build/errors.d.ts +19 -3
- package/build/errors.js +54 -5
- package/build/errors.js.map +1 -1
- package/build/errors.test.js +82 -0
- package/build/errors.test.js.map +1 -1
- package/build/exports.d.ts +1 -0
- package/build/exports.js +1 -0
- package/build/exports.js.map +1 -1
- package/build/implementations/http/hono-stream/index.d.ts +92 -0
- package/build/implementations/http/hono-stream/index.js +229 -0
- package/build/implementations/http/hono-stream/index.js.map +1 -0
- package/build/implementations/http/hono-stream/index.test.d.ts +1 -0
- package/build/implementations/http/hono-stream/index.test.js +681 -0
- package/build/implementations/http/hono-stream/index.test.js.map +1 -0
- package/build/implementations/http/hono-stream/types.d.ts +24 -0
- package/build/implementations/http/hono-stream/types.js +2 -0
- package/build/implementations/http/hono-stream/types.js.map +1 -0
- package/build/implementations/types.d.ts +15 -1
- package/build/index.d.ts +62 -3
- package/build/index.js +111 -6
- package/build/index.js.map +1 -1
- package/build/index.test.js +385 -2
- package/build/index.test.js.map +1 -1
- package/build/schema/compute-schema.d.ts +9 -2
- package/build/schema/compute-schema.js +9 -3
- package/build/schema/compute-schema.js.map +1 -1
- package/build/schema/parser.d.ts +6 -0
- package/build/schema/parser.js +42 -0
- package/build/schema/parser.js.map +1 -1
- package/build/schema/types.d.ts +1 -0
- package/build/stack-utils.d.ts +25 -0
- package/build/stack-utils.js +95 -0
- package/build/stack-utils.js.map +1 -0
- package/build/stack-utils.test.d.ts +1 -0
- package/build/stack-utils.test.js +80 -0
- package/build/stack-utils.test.js.map +1 -0
- package/package.json +1 -1
- package/src/errors.test.ts +110 -0
- package/src/errors.ts +65 -3
- package/src/exports.ts +1 -0
- package/src/implementations/http/README.md +87 -55
- package/src/implementations/http/hono-stream/README.md +261 -0
- package/src/implementations/http/hono-stream/index.test.ts +1009 -0
- package/src/implementations/http/hono-stream/index.ts +327 -0
- package/src/implementations/http/hono-stream/types.ts +29 -0
- package/src/implementations/types.ts +17 -1
- package/src/index.test.ts +525 -41
- package/src/index.ts +210 -8
- package/src/schema/compute-schema.ts +15 -3
- package/src/schema/parser.ts +55 -4
- package/src/schema/types.ts +4 -0
- package/src/stack-utils.test.ts +94 -0
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
package/build/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/build/errors.test.js
CHANGED
|
@@ -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
|
package/build/errors.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.test.js","sourceRoot":"","sources":["../src/errors.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"errors.test.js","sourceRoot":"","sources":["../src/errors.test.ts"],"names":[],"mappings":"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"}
|
package/build/exports.d.ts
CHANGED
package/build/exports.js
CHANGED
package/build/exports.js.map
CHANGED
|
@@ -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
|
+
}
|