@spfn/core 0.2.0-beta.4 → 0.2.0-beta.42
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 +260 -1175
- package/dist/{boss-BO8ty33K.d.ts → boss-DI1r4kTS.d.ts} +24 -7
- package/dist/cache/index.js +32 -29
- package/dist/cache/index.js.map +1 -1
- package/dist/codegen/index.d.ts +55 -8
- package/dist/codegen/index.js +179 -5
- package/dist/codegen/index.js.map +1 -1
- package/dist/config/index.d.ts +168 -6
- package/dist/config/index.js +29 -5
- package/dist/config/index.js.map +1 -1
- package/dist/db/index.d.ts +128 -4
- package/dist/db/index.js +177 -50
- package/dist/db/index.js.map +1 -1
- package/dist/env/index.d.ts +55 -1
- package/dist/env/index.js +71 -3
- package/dist/env/index.js.map +1 -1
- package/dist/env/loader.d.ts +27 -19
- package/dist/env/loader.js +33 -25
- package/dist/env/loader.js.map +1 -1
- package/dist/event/index.d.ts +27 -1
- package/dist/event/index.js +6 -1
- package/dist/event/index.js.map +1 -1
- package/dist/event/sse/client.d.ts +77 -2
- package/dist/event/sse/client.js +87 -24
- package/dist/event/sse/client.js.map +1 -1
- package/dist/event/sse/index.d.ts +10 -4
- package/dist/event/sse/index.js +158 -12
- package/dist/event/sse/index.js.map +1 -1
- package/dist/job/index.d.ts +23 -8
- package/dist/job/index.js +96 -20
- package/dist/job/index.js.map +1 -1
- package/dist/logger/index.d.ts +5 -0
- package/dist/logger/index.js +14 -0
- package/dist/logger/index.js.map +1 -1
- package/dist/middleware/index.d.ts +23 -1
- package/dist/middleware/index.js +58 -5
- package/dist/middleware/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +2 -2
- package/dist/nextjs/index.js +77 -31
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +44 -23
- package/dist/nextjs/server.js +83 -65
- package/dist/nextjs/server.js.map +1 -1
- package/dist/route/index.d.ts +158 -4
- package/dist/route/index.js +253 -17
- package/dist/route/index.js.map +1 -1
- package/dist/server/index.d.ts +251 -16
- package/dist/server/index.js +774 -228
- package/dist/server/index.js.map +1 -1
- package/dist/{types-D_N_U-Py.d.ts → types-7Mhoxnnt.d.ts} +21 -1
- package/dist/types-DKQ90YL7.d.ts +372 -0
- package/docs/cache.md +133 -0
- package/docs/codegen.md +74 -0
- package/docs/database.md +370 -0
- package/docs/entity.md +539 -0
- package/docs/env.md +499 -0
- package/docs/errors.md +319 -0
- package/docs/event.md +443 -0
- package/docs/file-upload.md +717 -0
- package/docs/job.md +131 -0
- package/docs/logger.md +108 -0
- package/docs/middleware.md +337 -0
- package/docs/nextjs.md +247 -0
- package/docs/repository.md +496 -0
- package/docs/route.md +497 -0
- package/docs/server.md +429 -0
- package/package.json +3 -2
- package/dist/types-B-e_f2dQ.d.ts +0 -121
package/dist/server/index.d.ts
CHANGED
|
@@ -1,26 +1,41 @@
|
|
|
1
|
+
export { loadEnv } from '../env/loader.js';
|
|
1
2
|
import { MiddlewareHandler, Hono } from 'hono';
|
|
2
3
|
import { cors } from 'hono/cors';
|
|
3
4
|
import { serve } from '@hono/node-server';
|
|
4
5
|
import { NamedMiddleware, Router } from '@spfn/core/route';
|
|
5
|
-
import {
|
|
6
|
+
import { OnErrorContext } from '@spfn/core/middleware';
|
|
7
|
+
import { J as JobRouter, B as BossOptions } from '../boss-DI1r4kTS.js';
|
|
6
8
|
import { E as EventRouterDef } from '../router-Di7ENoah.js';
|
|
7
|
-
import { S as SSEHandlerConfig } from '../types-
|
|
9
|
+
import { S as SSEHandlerConfig, a as SSEAuthConfig } from '../types-DKQ90YL7.js';
|
|
8
10
|
import '@sinclair/typebox';
|
|
9
11
|
import 'pg-boss';
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
*
|
|
17
|
-
* 3. .env.{NODE_ENV}.local
|
|
18
|
-
* 4. .env.local - Local overrides (gitignored)
|
|
19
|
-
* 5. .env.{NODE_ENV}
|
|
20
|
-
* 6. .env - Defaults
|
|
14
|
+
* @deprecated Use `loadEnv` from '@spfn/core/env/loader' instead.
|
|
15
|
+
* This module will be removed in the next major version.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Use `loadEnv()` from '@spfn/core/env/loader' instead.
|
|
21
19
|
*/
|
|
22
20
|
declare function loadEnvFiles(): void;
|
|
23
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Workflow router interface for @spfn/core integration
|
|
24
|
+
*
|
|
25
|
+
* This is a minimal interface that avoids circular dependency with @spfn/workflow.
|
|
26
|
+
* The actual WorkflowRouter from @spfn/workflow implements this interface.
|
|
27
|
+
*/
|
|
28
|
+
interface WorkflowRouterLike {
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the workflow engine
|
|
31
|
+
* Called by server during infrastructure initialization
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
_init: (db: any, options?: {
|
|
36
|
+
largeOutputThreshold?: number;
|
|
37
|
+
}) => void;
|
|
38
|
+
}
|
|
24
39
|
/**
|
|
25
40
|
* CORS configuration options - inferred from hono/cors
|
|
26
41
|
*/
|
|
@@ -60,6 +75,21 @@ interface ServerConfig {
|
|
|
60
75
|
* Error handler (default: true)
|
|
61
76
|
*/
|
|
62
77
|
errorHandler?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Callback invoked when an error occurs (passed to ErrorHandler)
|
|
80
|
+
*
|
|
81
|
+
* Called asynchronously without blocking the response.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* import { createErrorSlackNotifier } from '@spfn/notification/server';
|
|
86
|
+
*
|
|
87
|
+
* middleware: {
|
|
88
|
+
* onError: createErrorSlackNotifier({ minStatusCode: 500 }),
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
onError?: (err: Error, context: OnErrorContext) => Promise<void> | void;
|
|
63
93
|
};
|
|
64
94
|
/**
|
|
65
95
|
* Additional custom middleware
|
|
@@ -282,6 +312,34 @@ interface ServerConfig {
|
|
|
282
312
|
*/
|
|
283
313
|
headers?: number;
|
|
284
314
|
};
|
|
315
|
+
/**
|
|
316
|
+
* Fetch (outbound HTTP) timeout configuration
|
|
317
|
+
* Controls Node.js undici global dispatcher timeouts for fetch() calls
|
|
318
|
+
* Applies to all outbound HTTP requests made via fetch() in this process
|
|
319
|
+
*/
|
|
320
|
+
fetchTimeout?: {
|
|
321
|
+
/**
|
|
322
|
+
* TCP connection timeout in milliseconds
|
|
323
|
+
* Time to establish socket connection to upstream server
|
|
324
|
+
* @default 10000 (10 seconds)
|
|
325
|
+
* @env FETCH_CONNECT_TIMEOUT
|
|
326
|
+
*/
|
|
327
|
+
connect?: number;
|
|
328
|
+
/**
|
|
329
|
+
* Response headers timeout in milliseconds
|
|
330
|
+
* Time to receive complete response headers after request sent
|
|
331
|
+
* @default 300000 (5 minutes)
|
|
332
|
+
* @env FETCH_HEADERS_TIMEOUT
|
|
333
|
+
*/
|
|
334
|
+
headers?: number;
|
|
335
|
+
/**
|
|
336
|
+
* Body data timeout in milliseconds
|
|
337
|
+
* Maximum time between body data chunks from upstream server
|
|
338
|
+
* @default 300000 (5 minutes)
|
|
339
|
+
* @env FETCH_BODY_TIMEOUT
|
|
340
|
+
*/
|
|
341
|
+
body?: number;
|
|
342
|
+
};
|
|
285
343
|
/**
|
|
286
344
|
* Graceful shutdown configuration
|
|
287
345
|
* Controls server shutdown behavior during SIGTERM/SIGINT signals
|
|
@@ -289,9 +347,13 @@ interface ServerConfig {
|
|
|
289
347
|
shutdown?: {
|
|
290
348
|
/**
|
|
291
349
|
* Graceful shutdown timeout in milliseconds
|
|
292
|
-
* Maximum time to wait for
|
|
293
|
-
* After timeout, forces process
|
|
294
|
-
*
|
|
350
|
+
* Maximum time to wait for in-flight operations to drain and resource cleanup
|
|
351
|
+
* After timeout, forces process.exit() before k8s SIGKILL
|
|
352
|
+
*
|
|
353
|
+
* Formula: terminationGracePeriodSeconds - preStopSleep - safetyMargin
|
|
354
|
+
* Default: 300s - 5s - 15s = 280s
|
|
355
|
+
*
|
|
356
|
+
* @default 280000 (280 seconds)
|
|
295
357
|
* @env SHUTDOWN_TIMEOUT
|
|
296
358
|
*/
|
|
297
359
|
timeout?: number;
|
|
@@ -338,6 +400,39 @@ interface ServerConfig {
|
|
|
338
400
|
*/
|
|
339
401
|
redis?: boolean;
|
|
340
402
|
};
|
|
403
|
+
/**
|
|
404
|
+
* Workflow router for workflow orchestration
|
|
405
|
+
*
|
|
406
|
+
* Automatically initializes the workflow engine after database is ready.
|
|
407
|
+
* Workflows are defined using @spfn/workflow package.
|
|
408
|
+
*
|
|
409
|
+
* @example
|
|
410
|
+
* ```typescript
|
|
411
|
+
* import { defineWorkflowRouter } from '@spfn/workflow';
|
|
412
|
+
*
|
|
413
|
+
* const workflowRouter = defineWorkflowRouter([
|
|
414
|
+
* provisionTenant,
|
|
415
|
+
* deprovisionTenant,
|
|
416
|
+
* ]);
|
|
417
|
+
*
|
|
418
|
+
* export default defineServerConfig()
|
|
419
|
+
* .workflows(workflowRouter)
|
|
420
|
+
* .build();
|
|
421
|
+
* ```
|
|
422
|
+
*/
|
|
423
|
+
workflows?: WorkflowRouterLike;
|
|
424
|
+
/**
|
|
425
|
+
* Workflow engine configuration
|
|
426
|
+
* Only used if workflows router is provided
|
|
427
|
+
*/
|
|
428
|
+
workflowsConfig?: {
|
|
429
|
+
/**
|
|
430
|
+
* Large output threshold in bytes
|
|
431
|
+
* Outputs larger than this will be stored in external storage
|
|
432
|
+
* @default 1024 * 1024 (1MB)
|
|
433
|
+
*/
|
|
434
|
+
largeOutputThreshold?: number;
|
|
435
|
+
};
|
|
341
436
|
/**
|
|
342
437
|
* Server lifecycle hooks for custom infrastructure setup and management
|
|
343
438
|
* Allows initialization of custom services and resources at different stages
|
|
@@ -517,6 +612,124 @@ declare function createServer(config?: ServerConfig): Promise<Hono>;
|
|
|
517
612
|
*/
|
|
518
613
|
declare function startServer(config?: ServerConfig): Promise<ServerInstance>;
|
|
519
614
|
|
|
615
|
+
/**
|
|
616
|
+
* Shutdown Manager
|
|
617
|
+
*
|
|
618
|
+
* Manages graceful shutdown with drain behavior.
|
|
619
|
+
* All tracked operations must complete before shutdown proceeds.
|
|
620
|
+
*
|
|
621
|
+
* Features:
|
|
622
|
+
* - Hook registry: Multiple modules can register independent cleanup handlers
|
|
623
|
+
* - Operation tracking: Long-running tasks are awaited during shutdown (drain)
|
|
624
|
+
* - State management: isShuttingDown() for rejecting new work
|
|
625
|
+
*/
|
|
626
|
+
interface ShutdownHookOptions {
|
|
627
|
+
/**
|
|
628
|
+
* Timeout for this hook in milliseconds
|
|
629
|
+
* If the hook exceeds this time, it is skipped and the next hook runs
|
|
630
|
+
* @default 10000 (10s)
|
|
631
|
+
*/
|
|
632
|
+
timeout?: number;
|
|
633
|
+
/**
|
|
634
|
+
* Execution order (lower runs first)
|
|
635
|
+
* @default 100
|
|
636
|
+
*/
|
|
637
|
+
order?: number;
|
|
638
|
+
}
|
|
639
|
+
declare class ShutdownManager {
|
|
640
|
+
private state;
|
|
641
|
+
private hooks;
|
|
642
|
+
private operations;
|
|
643
|
+
private operationCounter;
|
|
644
|
+
/**
|
|
645
|
+
* Register a shutdown hook
|
|
646
|
+
*
|
|
647
|
+
* Hooks run in order during shutdown, after all tracked operations drain.
|
|
648
|
+
* Each hook has its own timeout — failure does not block subsequent hooks.
|
|
649
|
+
*
|
|
650
|
+
* @example
|
|
651
|
+
* shutdown.onShutdown('ai-service', async () => {
|
|
652
|
+
* await aiService.cancelPending();
|
|
653
|
+
* }, { timeout: 30000, order: 10 });
|
|
654
|
+
*/
|
|
655
|
+
onShutdown(name: string, handler: () => Promise<void>, options?: ShutdownHookOptions): void;
|
|
656
|
+
/**
|
|
657
|
+
* Track a long-running operation
|
|
658
|
+
*
|
|
659
|
+
* During shutdown (drain phase), the process waits for ALL tracked
|
|
660
|
+
* operations to complete before proceeding with cleanup.
|
|
661
|
+
*
|
|
662
|
+
* If shutdown has already started, the operation is rejected immediately.
|
|
663
|
+
*
|
|
664
|
+
* @returns The operation result (pass-through)
|
|
665
|
+
*
|
|
666
|
+
* @example
|
|
667
|
+
* const result = await shutdown.trackOperation(
|
|
668
|
+
* 'ai-generate',
|
|
669
|
+
* aiService.generate(prompt)
|
|
670
|
+
* );
|
|
671
|
+
*/
|
|
672
|
+
trackOperation<T>(name: string, operation: Promise<T>): Promise<T>;
|
|
673
|
+
/**
|
|
674
|
+
* Whether the server is shutting down
|
|
675
|
+
*
|
|
676
|
+
* Use this to reject new work early (e.g., return 503 in route handlers).
|
|
677
|
+
*/
|
|
678
|
+
isShuttingDown(): boolean;
|
|
679
|
+
/**
|
|
680
|
+
* Number of currently active tracked operations
|
|
681
|
+
*/
|
|
682
|
+
getActiveOperationCount(): number;
|
|
683
|
+
/**
|
|
684
|
+
* Mark shutdown as started immediately
|
|
685
|
+
*
|
|
686
|
+
* Call this at the very beginning of the shutdown sequence so that:
|
|
687
|
+
* - Health check returns 503 right away
|
|
688
|
+
* - trackOperation() rejects new work
|
|
689
|
+
* - isShuttingDown() returns true
|
|
690
|
+
*/
|
|
691
|
+
beginShutdown(): void;
|
|
692
|
+
/**
|
|
693
|
+
* Execute the full shutdown sequence
|
|
694
|
+
*
|
|
695
|
+
* 1. State → draining (reject new operations)
|
|
696
|
+
* 2. Wait for all tracked operations to complete (drain)
|
|
697
|
+
* 3. Run shutdown hooks in order
|
|
698
|
+
* 4. State → closed
|
|
699
|
+
*
|
|
700
|
+
* @param drainTimeout - Max time to wait for operations to drain (ms)
|
|
701
|
+
*/
|
|
702
|
+
execute(drainTimeout: number): Promise<void>;
|
|
703
|
+
/**
|
|
704
|
+
* Wait for all tracked operations to complete, up to drainTimeout
|
|
705
|
+
*/
|
|
706
|
+
private drain;
|
|
707
|
+
/**
|
|
708
|
+
* Execute registered shutdown hooks in order
|
|
709
|
+
*/
|
|
710
|
+
private executeHooks;
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Get the global ShutdownManager instance
|
|
714
|
+
*
|
|
715
|
+
* Available after server starts. Use this to register shutdown hooks
|
|
716
|
+
* or track long-running operations.
|
|
717
|
+
*
|
|
718
|
+
* @example
|
|
719
|
+
* import { getShutdownManager } from '@spfn/core/server';
|
|
720
|
+
*
|
|
721
|
+
* const shutdown = getShutdownManager();
|
|
722
|
+
*
|
|
723
|
+
* // Register cleanup
|
|
724
|
+
* shutdown.onShutdown('my-service', async () => {
|
|
725
|
+
* await myService.close();
|
|
726
|
+
* });
|
|
727
|
+
*
|
|
728
|
+
* // Track long operation
|
|
729
|
+
* await shutdown.trackOperation('ai-task', longRunningPromise);
|
|
730
|
+
*/
|
|
731
|
+
declare function getShutdownManager(): ShutdownManager;
|
|
732
|
+
|
|
520
733
|
/**
|
|
521
734
|
* Server Config Builder
|
|
522
735
|
*
|
|
@@ -619,8 +832,9 @@ declare class ServerConfigBuilder {
|
|
|
619
832
|
* .events(eventRouter, { path: '/sse' })
|
|
620
833
|
* ```
|
|
621
834
|
*/
|
|
622
|
-
events
|
|
835
|
+
events<TRouter extends EventRouterDef<any>>(router: TRouter, config?: Omit<SSEHandlerConfig, 'auth'> & {
|
|
623
836
|
path?: string;
|
|
837
|
+
auth?: SSEAuthConfig<TRouter>;
|
|
624
838
|
}): this;
|
|
625
839
|
/**
|
|
626
840
|
* Enable/disable debug mode
|
|
@@ -646,6 +860,27 @@ declare class ServerConfigBuilder {
|
|
|
646
860
|
* Configure infrastructure initialization
|
|
647
861
|
*/
|
|
648
862
|
infrastructure(infrastructure: ServerConfig['infrastructure']): this;
|
|
863
|
+
/**
|
|
864
|
+
* Register workflow router for workflow orchestration
|
|
865
|
+
*
|
|
866
|
+
* Automatically initializes the workflow engine after database is ready.
|
|
867
|
+
*
|
|
868
|
+
* @example
|
|
869
|
+
* ```typescript
|
|
870
|
+
* import { defineWorkflowRouter } from '@spfn/workflow';
|
|
871
|
+
*
|
|
872
|
+
* const workflowRouter = defineWorkflowRouter([
|
|
873
|
+
* provisionTenant,
|
|
874
|
+
* deprovisionTenant,
|
|
875
|
+
* ]);
|
|
876
|
+
*
|
|
877
|
+
* export default defineServerConfig()
|
|
878
|
+
* .routes(appRouter)
|
|
879
|
+
* .workflows(workflowRouter)
|
|
880
|
+
* .build();
|
|
881
|
+
* ```
|
|
882
|
+
*/
|
|
883
|
+
workflows(router: ServerConfig['workflows'], config?: ServerConfig['workflowsConfig']): this;
|
|
649
884
|
/**
|
|
650
885
|
* Configure lifecycle hooks
|
|
651
886
|
* Can be called multiple times - hooks will be executed in registration order
|
|
@@ -685,4 +920,4 @@ declare class ServerConfigBuilder {
|
|
|
685
920
|
*/
|
|
686
921
|
declare function defineServerConfig(): ServerConfigBuilder;
|
|
687
922
|
|
|
688
|
-
export { type AppFactory, type ServerConfig, type ServerInstance, createServer, defineServerConfig, loadEnvFiles, startServer };
|
|
923
|
+
export { type AppFactory, type ServerConfig, type ServerInstance, type ShutdownHookOptions, createServer, defineServerConfig, getShutdownManager, loadEnvFiles, startServer };
|