@elsium-ai/app 0.2.3 → 0.4.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 +98 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +715 -273
- package/dist/routes.d.ts.map +1 -1
- package/dist/sse.d.ts +6 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/tenant.d.ts +18 -0
- package/dist/tenant.d.ts.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -332,6 +332,104 @@ app.use('*', rateLimitMiddleware({
|
|
|
332
332
|
|
|
333
333
|
---
|
|
334
334
|
|
|
335
|
+
## SSE Utilities
|
|
336
|
+
|
|
337
|
+
Helper functions for building Server-Sent Events responses in Hono handlers.
|
|
338
|
+
|
|
339
|
+
### `sseHeaders`
|
|
340
|
+
|
|
341
|
+
A constant object containing the standard HTTP headers for SSE responses.
|
|
342
|
+
|
|
343
|
+
```ts
|
|
344
|
+
const sseHeaders: Record<string, string>
|
|
345
|
+
// { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### `formatSSE`
|
|
349
|
+
|
|
350
|
+
Formats an event name and data payload into the SSE wire format.
|
|
351
|
+
|
|
352
|
+
```ts
|
|
353
|
+
function formatSSE(event: string, data: unknown): string
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
| Parameter | Type | Description |
|
|
357
|
+
| --- | --- | --- |
|
|
358
|
+
| `event` | `string` | The SSE event name. |
|
|
359
|
+
| `data` | `unknown` | The data payload (will be JSON-stringified). |
|
|
360
|
+
|
|
361
|
+
**Returns:** A formatted SSE string (e.g., `event: text_delta\ndata: {"text":"Hello"}\n\n`).
|
|
362
|
+
|
|
363
|
+
### `streamResponse`
|
|
364
|
+
|
|
365
|
+
Converts a `ReadableStream` into a Hono `Response` with the correct SSE headers.
|
|
366
|
+
|
|
367
|
+
```ts
|
|
368
|
+
function streamResponse(stream: ReadableStream): Response
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
| Parameter | Type | Description |
|
|
372
|
+
| --- | --- | --- |
|
|
373
|
+
| `stream` | `ReadableStream` | The stream to send as the response body. |
|
|
374
|
+
|
|
375
|
+
**Returns:** A `Response` object with SSE headers.
|
|
376
|
+
|
|
377
|
+
```ts
|
|
378
|
+
import { sseHeaders, formatSSE, streamResponse } from '@elsium-ai/app'
|
|
379
|
+
|
|
380
|
+
// In a Hono route handler
|
|
381
|
+
app.post('/my-stream', (c) => {
|
|
382
|
+
const stream = new ReadableStream({
|
|
383
|
+
start(controller) {
|
|
384
|
+
controller.enqueue(new TextEncoder().encode(formatSSE('text_delta', { text: 'Hello' })))
|
|
385
|
+
controller.enqueue(new TextEncoder().encode(formatSSE('message_end', { done: true })))
|
|
386
|
+
controller.close()
|
|
387
|
+
},
|
|
388
|
+
})
|
|
389
|
+
return streamResponse(stream)
|
|
390
|
+
})
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## Tenant Budget Middleware
|
|
396
|
+
|
|
397
|
+
### `tenantBudgetMiddleware`
|
|
398
|
+
|
|
399
|
+
Creates a Hono middleware that enforces per-tenant token and cost budgets using sliding windows. Each tenant is identified from the request context and tracked independently.
|
|
400
|
+
|
|
401
|
+
```ts
|
|
402
|
+
function tenantBudgetMiddleware(config?: {
|
|
403
|
+
windowMs?: number
|
|
404
|
+
maxTokensPerWindow?: number
|
|
405
|
+
maxCostPerWindow?: number
|
|
406
|
+
}): (c: Context, next: Next) => Promise<Response | void>
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
| Parameter | Type | Default | Description |
|
|
410
|
+
| --- | --- | --- | --- |
|
|
411
|
+
| `config.windowMs` | `number` | `60_000` | Sliding window duration in milliseconds. |
|
|
412
|
+
| `config.maxTokensPerWindow` | `number` | `undefined` | Maximum tokens allowed per tenant per window. |
|
|
413
|
+
| `config.maxCostPerWindow` | `number` | `undefined` | Maximum cost (USD) allowed per tenant per window. |
|
|
414
|
+
|
|
415
|
+
**Responses on failure:**
|
|
416
|
+
- `429` with `{ error: 'Tenant budget exceeded' }` when the tenant's usage exceeds the configured limits.
|
|
417
|
+
|
|
418
|
+
```ts
|
|
419
|
+
import { tenantBudgetMiddleware } from '@elsium-ai/app'
|
|
420
|
+
import { Hono } from 'hono'
|
|
421
|
+
|
|
422
|
+
const app = new Hono()
|
|
423
|
+
|
|
424
|
+
app.use('*', tenantBudgetMiddleware({
|
|
425
|
+
windowMs: 60_000,
|
|
426
|
+
maxTokensPerWindow: 100_000,
|
|
427
|
+
maxCostPerWindow: 1.0,
|
|
428
|
+
}))
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
335
433
|
## Routes
|
|
336
434
|
|
|
337
435
|
### `createRoutes`
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
export { createApp } from './app';
|
|
2
2
|
export type { ElsiumApp } from './app';
|
|
3
|
-
export type { AppConfig, ServerConfig, CorsConfig, AuthConfig, RateLimitConfig, ChatRequest, ChatResponse, CompleteRequest, HealthResponse, MetricsResponse, } from './types';
|
|
3
|
+
export type { AppConfig, ServerConfig, CorsConfig, AuthConfig, RateLimitConfig, ChatRequest, ChatResponse, CompleteRequest, HealthResponse, MetricsResponse, StreamChatEvent, StreamCompleteEvent, } from './types';
|
|
4
|
+
export { sseHeaders, formatSSE, streamResponse } from './sse';
|
|
4
5
|
export { corsMiddleware, authMiddleware, rateLimitMiddleware, requestIdMiddleware, requestLoggerMiddleware, } from './middleware';
|
|
5
6
|
export { createRoutes } from './routes';
|
|
6
7
|
export type { RoutesDeps } from './routes';
|
|
7
8
|
export { createRBAC } from './rbac';
|
|
8
9
|
export type { Permission, Role, RBACConfig, RBAC } from './rbac';
|
|
10
|
+
export { tenantMiddleware, tenantRateLimitMiddleware, tenantBudgetMiddleware } from './tenant';
|
|
11
|
+
export type { TenantMiddlewareConfig } from './tenant';
|
|
9
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,YAAY,EACX,SAAS,EACT,YAAY,EACZ,UAAU,EACV,UAAU,EACV,eAAe,EACf,WAAW,EACX,YAAY,EACZ,eAAe,EACf,cAAc,EACd,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,YAAY,EACX,SAAS,EACT,YAAY,EACZ,UAAU,EACV,UAAU,EACV,eAAe,EACf,WAAW,EACX,YAAY,EACZ,eAAe,EACf,cAAc,EACd,eAAe,EACf,eAAe,EACf,mBAAmB,GACnB,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAG7D,OAAO,EACN,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,GACvB,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1C,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAGhE,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAC9F,YAAY,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA"}
|