@spfn/core 0.2.0-beta.9 → 0.3.0-beta.10
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/LICENSE +1 -1
- package/README.md +693 -279
- package/dist/app-config/index.d.ts +96 -0
- package/dist/app-config/index.js +58 -0
- package/dist/app-config/index.js.map +1 -0
- package/dist/authz/index.d.ts +34 -0
- package/dist/authz/index.js +430 -0
- package/dist/authz/index.js.map +1 -0
- package/dist/boss-BiDCbbAQ.d.ts +337 -0
- package/dist/cache/index.js +42 -30
- package/dist/cache/index.js.map +1 -1
- package/dist/codegen/index.d.ts +121 -13
- package/dist/codegen/index.js +212 -15
- package/dist/codegen/index.js.map +1 -1
- package/dist/config/index.d.ts +576 -30
- package/dist/config/index.js +136 -17
- package/dist/config/index.js.map +1 -1
- package/dist/contract/index.d.ts +221 -0
- package/dist/contract/index.js +558 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/db/index.d.ts +704 -94
- package/dist/db/index.js +1105 -260
- package/dist/db/index.js.map +1 -1
- package/dist/define-middleware-CVKgqo8S.d.ts +167 -0
- package/dist/env/index.d.ts +26 -2
- package/dist/env/index.js +15 -5
- package/dist/env/index.js.map +1 -1
- package/dist/env/loader.d.ts +26 -19
- package/dist/env/loader.js +55 -25
- package/dist/env/loader.js.map +1 -1
- package/dist/errors/index.d.ts +10 -0
- package/dist/errors/index.js +40 -7
- package/dist/errors/index.js.map +1 -1
- package/dist/event/index.d.ts +33 -3
- package/dist/event/index.js +24 -3
- package/dist/event/index.js.map +1 -1
- package/dist/event/sse/client.d.ts +55 -3
- package/dist/event/sse/client.js +164 -45
- package/dist/event/sse/client.js.map +1 -1
- package/dist/event/sse/index.d.ts +12 -5
- package/dist/event/sse/index.js +280 -32
- package/dist/event/sse/index.js.map +1 -1
- package/dist/event/ws/client.d.ts +59 -0
- package/dist/event/ws/client.js +273 -0
- package/dist/event/ws/client.js.map +1 -0
- package/dist/event/ws/index.d.ts +94 -0
- package/dist/event/ws/index.js +272 -0
- package/dist/event/ws/index.js.map +1 -0
- package/dist/job/index.d.ts +48 -3
- package/dist/job/index.js +265 -74
- package/dist/job/index.js.map +1 -1
- package/dist/logger/index.d.ts +5 -0
- package/dist/logger/index.js +14 -12
- package/dist/logger/index.js.map +1 -1
- package/dist/middleware/index.d.ts +352 -10
- package/dist/middleware/index.js +1079 -13
- package/dist/middleware/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +39 -3
- package/dist/nextjs/index.js +82 -29
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +69 -52
- package/dist/nextjs/server.js +140 -60
- package/dist/nextjs/server.js.map +1 -1
- package/dist/ops/index.d.ts +208 -0
- package/dist/ops/index.js +800 -0
- package/dist/ops/index.js.map +1 -0
- package/dist/route/index.d.ts +10 -694
- package/dist/route/index.js +112 -23
- package/dist/route/index.js.map +1 -1
- package/dist/route-builder-2ani2jEI.d.ts +553 -0
- package/dist/router-DJdpwuB6.d.ts +127 -0
- package/dist/security/index.d.ts +83 -0
- package/dist/security/index.js +173 -0
- package/dist/security/index.js.map +1 -0
- package/dist/server/index.d.ts +619 -31
- package/dist/server/index.js +2583 -360
- package/dist/server/index.js.map +1 -1
- package/dist/token-manager-BT5EnUAR.d.ts +278 -0
- package/dist/types-2AbaW4Ie.d.ts +205 -0
- package/dist/{types-BOPTApC2.d.ts → types-9oszaJqp.d.ts} +7 -2
- package/dist/types-ClQVomgV.d.ts +115 -0
- package/dist/types-ZQODsBft.d.ts +282 -0
- package/docs/file-upload.md +195 -333
- package/package.json +250 -208
- package/src/cache/README.md +330 -0
- package/src/codegen/README.md +516 -0
- package/src/config/README.md +326 -0
- package/src/contract/README.md +326 -0
- package/src/db/README.md +589 -0
- package/src/db/manager/README.md +500 -0
- package/src/db/schema/README.md +354 -0
- package/src/db/transaction/README.md +822 -0
- package/src/env/README.md +651 -0
- package/src/errors/README.md +429 -0
- package/src/event/README.md +741 -0
- package/src/job/README.md +613 -0
- package/src/logger/README.md +321 -0
- package/src/middleware/README.md +634 -0
- package/src/nextjs/README.md +608 -0
- package/src/route/README.md +738 -0
- package/src/security/README.md +100 -0
- package/src/server/README.md +704 -0
- package/dist/boss-DI1r4kTS.d.ts +0 -244
- package/dist/router-Di7ENoah.d.ts +0 -151
- package/dist/types-B-e_f2dQ.d.ts +0 -121
- package/docs/cache.md +0 -133
- package/docs/codegen.md +0 -74
- package/docs/database.md +0 -346
- package/docs/entity.md +0 -539
- package/docs/env.md +0 -477
- package/docs/errors.md +0 -319
- package/docs/event.md +0 -116
- package/docs/job.md +0 -131
- package/docs/logger.md +0 -108
- package/docs/middleware.md +0 -337
- package/docs/nextjs.md +0 -241
- package/docs/repository.md +0 -496
- package/docs/route.md +0 -497
- package/docs/server.md +0 -307
package/dist/boss-DI1r4kTS.d.ts
DELETED
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import { TSchema } from '@sinclair/typebox';
|
|
2
|
-
import PgBoss from 'pg-boss';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Job System Types
|
|
6
|
-
*
|
|
7
|
-
* Type definitions for the pg-boss based job system
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Job options passed to pg-boss
|
|
12
|
-
*/
|
|
13
|
-
interface JobOptions {
|
|
14
|
-
/**
|
|
15
|
-
* Maximum retry attempts
|
|
16
|
-
* @default 3
|
|
17
|
-
*/
|
|
18
|
-
retryLimit?: number;
|
|
19
|
-
/**
|
|
20
|
-
* Delay between retries in milliseconds
|
|
21
|
-
* @default 1000
|
|
22
|
-
*/
|
|
23
|
-
retryDelay?: number;
|
|
24
|
-
/**
|
|
25
|
-
* Job expiration in seconds
|
|
26
|
-
* @default 300 (5 minutes)
|
|
27
|
-
*/
|
|
28
|
-
expireInSeconds?: number;
|
|
29
|
-
/**
|
|
30
|
-
* Job priority (higher = more important)
|
|
31
|
-
* @default 0
|
|
32
|
-
*/
|
|
33
|
-
priority?: number;
|
|
34
|
-
/**
|
|
35
|
-
* Singleton key - only one job with this key can exist
|
|
36
|
-
*/
|
|
37
|
-
singletonKey?: string;
|
|
38
|
-
/**
|
|
39
|
-
* Keep completed jobs for this many seconds
|
|
40
|
-
* @default 604800 (7 days)
|
|
41
|
-
*/
|
|
42
|
-
retentionSeconds?: number;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Send options for individual job dispatch
|
|
46
|
-
*/
|
|
47
|
-
interface JobSendOptions {
|
|
48
|
-
/**
|
|
49
|
-
* Delay execution by this many seconds
|
|
50
|
-
*/
|
|
51
|
-
startAfter?: number | Date;
|
|
52
|
-
/**
|
|
53
|
-
* Singleton key for this specific job instance
|
|
54
|
-
*/
|
|
55
|
-
singletonKey?: string;
|
|
56
|
-
/**
|
|
57
|
-
* Priority override
|
|
58
|
-
*/
|
|
59
|
-
priority?: number;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Job handler function type
|
|
63
|
-
*/
|
|
64
|
-
type JobHandler<TInput, TOutput = void> = TInput extends void ? () => Promise<TOutput> : (input: TInput) => Promise<TOutput>;
|
|
65
|
-
/**
|
|
66
|
-
* Compensate handler function type (for rollback)
|
|
67
|
-
*/
|
|
68
|
-
type CompensateHandler<TInput, TOutput> = (input: TInput, output: TOutput) => Promise<void>;
|
|
69
|
-
/**
|
|
70
|
-
* Job definition interface
|
|
71
|
-
*/
|
|
72
|
-
interface JobDef<TInput = void, TOutput = void> {
|
|
73
|
-
/**
|
|
74
|
-
* Unique job name
|
|
75
|
-
*/
|
|
76
|
-
readonly name: string;
|
|
77
|
-
/**
|
|
78
|
-
* TypeBox input schema (optional)
|
|
79
|
-
*/
|
|
80
|
-
readonly inputSchema?: TSchema;
|
|
81
|
-
/**
|
|
82
|
-
* TypeBox output schema (optional, for workflow integration)
|
|
83
|
-
*/
|
|
84
|
-
readonly outputSchema?: TSchema;
|
|
85
|
-
/**
|
|
86
|
-
* Cron expression for scheduled jobs
|
|
87
|
-
*/
|
|
88
|
-
readonly cronExpression?: string;
|
|
89
|
-
/**
|
|
90
|
-
* Run once on server start
|
|
91
|
-
*/
|
|
92
|
-
readonly runOnce?: boolean;
|
|
93
|
-
/**
|
|
94
|
-
* Event name this job subscribes to
|
|
95
|
-
*/
|
|
96
|
-
readonly subscribedEvent?: string;
|
|
97
|
-
/**
|
|
98
|
-
* Event definition this job subscribes to (internal use)
|
|
99
|
-
*/
|
|
100
|
-
readonly _subscribedEventDef?: unknown;
|
|
101
|
-
/**
|
|
102
|
-
* Job options
|
|
103
|
-
*/
|
|
104
|
-
readonly options?: JobOptions;
|
|
105
|
-
/**
|
|
106
|
-
* Job handler
|
|
107
|
-
*/
|
|
108
|
-
readonly handler: JobHandler<TInput, TOutput>;
|
|
109
|
-
/**
|
|
110
|
-
* Compensate handler for rollback (optional, for workflow integration)
|
|
111
|
-
*/
|
|
112
|
-
readonly compensate?: CompensateHandler<TInput, TOutput>;
|
|
113
|
-
/**
|
|
114
|
-
* Send job to queue (returns immediately, executes in background)
|
|
115
|
-
*/
|
|
116
|
-
send: TInput extends void ? (options?: JobSendOptions) => Promise<string | null> : (input: TInput, options?: JobSendOptions) => Promise<string | null>;
|
|
117
|
-
/**
|
|
118
|
-
* Run job synchronously (for testing/debugging)
|
|
119
|
-
*/
|
|
120
|
-
run: TInput extends void ? () => Promise<TOutput> : (input: TInput) => Promise<TOutput>;
|
|
121
|
-
/**
|
|
122
|
-
* Type inference helpers
|
|
123
|
-
*/
|
|
124
|
-
_input: TInput;
|
|
125
|
-
_output: TOutput;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Job router entry - can be a job or nested router
|
|
129
|
-
*/
|
|
130
|
-
type JobRouterEntry = JobDef<any, any> | JobRouter<any>;
|
|
131
|
-
/**
|
|
132
|
-
* Job router interface
|
|
133
|
-
*/
|
|
134
|
-
interface JobRouter<TJobs extends Record<string, JobRouterEntry> = Record<string, JobRouterEntry>> {
|
|
135
|
-
readonly jobs: TJobs;
|
|
136
|
-
readonly _jobs: TJobs;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Infer input type from JobDef
|
|
140
|
-
*/
|
|
141
|
-
type InferJobInput<TJob> = TJob extends JobDef<infer TInput, any> ? TInput : never;
|
|
142
|
-
/**
|
|
143
|
-
* Infer output type from JobDef
|
|
144
|
-
*/
|
|
145
|
-
type InferJobOutput<TJob> = TJob extends JobDef<any, infer TOutput> ? TOutput : never;
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* pg-boss Wrapper
|
|
149
|
-
*
|
|
150
|
-
* Manages pg-boss instance lifecycle
|
|
151
|
-
*/
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Options for pg-boss initialization
|
|
155
|
-
*
|
|
156
|
-
* @example
|
|
157
|
-
* ```typescript
|
|
158
|
-
* await initBoss({
|
|
159
|
-
* connectionString: process.env.DATABASE_URL,
|
|
160
|
-
* schema: 'spfn_queue',
|
|
161
|
-
* clearOnStart: process.env.NODE_ENV === 'development',
|
|
162
|
-
* });
|
|
163
|
-
* ```
|
|
164
|
-
*/
|
|
165
|
-
interface BossOptions {
|
|
166
|
-
/**
|
|
167
|
-
* PostgreSQL connection string
|
|
168
|
-
*
|
|
169
|
-
* @example 'postgresql://user:password@localhost:5432/mydb'
|
|
170
|
-
*/
|
|
171
|
-
connectionString: string;
|
|
172
|
-
/**
|
|
173
|
-
* Schema name for pg-boss tables
|
|
174
|
-
*
|
|
175
|
-
* pg-boss creates its own tables in this schema.
|
|
176
|
-
*
|
|
177
|
-
* @default 'spfn_queue'
|
|
178
|
-
*/
|
|
179
|
-
schema?: string;
|
|
180
|
-
/**
|
|
181
|
-
* Maintenance interval in seconds
|
|
182
|
-
*
|
|
183
|
-
* pg-boss runs maintenance tasks (cleanup, archiving) at this interval.
|
|
184
|
-
*
|
|
185
|
-
* @default 120
|
|
186
|
-
*/
|
|
187
|
-
maintenanceIntervalSeconds?: number;
|
|
188
|
-
/**
|
|
189
|
-
* Monitor state changes interval in seconds
|
|
190
|
-
*
|
|
191
|
-
* When set, pg-boss emits state change events at this interval.
|
|
192
|
-
*
|
|
193
|
-
* @default undefined (disabled)
|
|
194
|
-
*/
|
|
195
|
-
monitorIntervalSeconds?: number;
|
|
196
|
-
/**
|
|
197
|
-
* Clear all pending/scheduled jobs on startup
|
|
198
|
-
*
|
|
199
|
-
* Useful for development mode to start with a clean queue.
|
|
200
|
-
* Should be false in production.
|
|
201
|
-
*
|
|
202
|
-
* @default false
|
|
203
|
-
*/
|
|
204
|
-
clearOnStart?: boolean;
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* @deprecated Use BossOptions instead
|
|
208
|
-
*/
|
|
209
|
-
type BossConfig = BossOptions;
|
|
210
|
-
/**
|
|
211
|
-
* Initialize pg-boss with the given configuration
|
|
212
|
-
*
|
|
213
|
-
* Must be called before registerJobs(). Typically handled by defineServerConfig().
|
|
214
|
-
*
|
|
215
|
-
* @param options - pg-boss configuration options
|
|
216
|
-
* @returns The pg-boss instance
|
|
217
|
-
*
|
|
218
|
-
* @example
|
|
219
|
-
* ```typescript
|
|
220
|
-
* const boss = await initBoss({
|
|
221
|
-
* connectionString: process.env.DATABASE_URL!,
|
|
222
|
-
* schema: 'spfn_queue',
|
|
223
|
-
* });
|
|
224
|
-
* ```
|
|
225
|
-
*/
|
|
226
|
-
declare function initBoss(options: BossOptions): Promise<PgBoss>;
|
|
227
|
-
/**
|
|
228
|
-
* Get the current pg-boss instance
|
|
229
|
-
*/
|
|
230
|
-
declare function getBoss(): PgBoss | null;
|
|
231
|
-
/**
|
|
232
|
-
* Stop pg-boss gracefully
|
|
233
|
-
*/
|
|
234
|
-
declare function stopBoss(): Promise<void>;
|
|
235
|
-
/**
|
|
236
|
-
* Check if pg-boss is initialized and running
|
|
237
|
-
*/
|
|
238
|
-
declare function isBossRunning(): boolean;
|
|
239
|
-
/**
|
|
240
|
-
* Check if jobs should be cleared on start
|
|
241
|
-
*/
|
|
242
|
-
declare function shouldClearOnStart(): boolean;
|
|
243
|
-
|
|
244
|
-
export { type BossOptions as B, type CompensateHandler as C, type InferJobInput as I, type JobRouter as J, type JobOptions as a, type JobHandler as b, type JobDef as c, type JobRouterEntry as d, type JobSendOptions as e, type InferJobOutput as f, getBoss as g, isBossRunning as h, initBoss as i, shouldClearOnStart as j, type BossConfig as k, stopBoss as s };
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { TSchema } from '@sinclair/typebox';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Event System Types
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Pub/Sub capable cache interface for multi-instance events
|
|
9
|
-
*/
|
|
10
|
-
interface PubSubCache {
|
|
11
|
-
/**
|
|
12
|
-
* Publish a message to a channel
|
|
13
|
-
*/
|
|
14
|
-
publish(channel: string, message: unknown): Promise<void>;
|
|
15
|
-
/**
|
|
16
|
-
* Subscribe to a channel
|
|
17
|
-
*/
|
|
18
|
-
subscribe(channel: string, handler: (message: unknown) => void | Promise<void>): Promise<void>;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Event handler function type
|
|
22
|
-
*/
|
|
23
|
-
type EventHandler<TPayload> = (payload: TPayload) => void | Promise<void>;
|
|
24
|
-
/**
|
|
25
|
-
* Job queue sender function type (used by job module)
|
|
26
|
-
*/
|
|
27
|
-
type JobQueueSender = (queueName: string, payload: unknown) => Promise<void>;
|
|
28
|
-
/**
|
|
29
|
-
* Event definition interface
|
|
30
|
-
*/
|
|
31
|
-
interface EventDef<TPayload = void> {
|
|
32
|
-
/**
|
|
33
|
-
* Unique event name
|
|
34
|
-
*/
|
|
35
|
-
readonly name: string;
|
|
36
|
-
/**
|
|
37
|
-
* TypeBox payload schema (optional)
|
|
38
|
-
*/
|
|
39
|
-
readonly schema?: TSchema;
|
|
40
|
-
/**
|
|
41
|
-
* Subscribe to this event (in-memory handler)
|
|
42
|
-
*/
|
|
43
|
-
subscribe: (handler: EventHandler<TPayload>) => () => void;
|
|
44
|
-
/**
|
|
45
|
-
* Unsubscribe all handlers
|
|
46
|
-
*/
|
|
47
|
-
unsubscribeAll: () => void;
|
|
48
|
-
/**
|
|
49
|
-
* Emit the event (triggers all subscribers and queued jobs)
|
|
50
|
-
*/
|
|
51
|
-
emit: TPayload extends void ? () => Promise<void> : (payload: TPayload) => Promise<void>;
|
|
52
|
-
/**
|
|
53
|
-
* Enable cache-based pub/sub for multi-instance support
|
|
54
|
-
* Must await before emitting events to ensure subscription is ready
|
|
55
|
-
*/
|
|
56
|
-
useCache: (cache: PubSubCache) => Promise<EventDef<TPayload>>;
|
|
57
|
-
/**
|
|
58
|
-
* Internal: Register a job queue to receive this event
|
|
59
|
-
* Called by job registration system
|
|
60
|
-
*/
|
|
61
|
-
_registerJobQueue: (queueName: string, sender: JobQueueSender) => void;
|
|
62
|
-
/**
|
|
63
|
-
* Type inference helper
|
|
64
|
-
*/
|
|
65
|
-
_payload: TPayload;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Infer payload type from EventDef
|
|
69
|
-
*/
|
|
70
|
-
type InferEventPayload$1<TEvent> = TEvent extends EventDef<infer TPayload> ? TPayload : never;
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Event Router
|
|
74
|
-
*
|
|
75
|
-
* Type-safe event router for SSE subscription
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* ```typescript
|
|
79
|
-
* import { defineEvent, defineEventRouter } from '@spfn/core/event';
|
|
80
|
-
* import { Type } from '@sinclair/typebox';
|
|
81
|
-
*
|
|
82
|
-
* const userCreated = defineEvent('user.created', Type.Object({
|
|
83
|
-
* userId: Type.String(),
|
|
84
|
-
* }));
|
|
85
|
-
*
|
|
86
|
-
* const orderPlaced = defineEvent('order.placed', Type.Object({
|
|
87
|
-
* orderId: Type.String(),
|
|
88
|
-
* amount: Type.Number(),
|
|
89
|
-
* }));
|
|
90
|
-
*
|
|
91
|
-
* export const eventRouter = defineEventRouter({
|
|
92
|
-
* userCreated,
|
|
93
|
-
* orderPlaced,
|
|
94
|
-
* });
|
|
95
|
-
*
|
|
96
|
-
* export type EventRouter = typeof eventRouter;
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Event Router Definition
|
|
102
|
-
*/
|
|
103
|
-
interface EventRouterDef<TEvents extends Record<string, EventDef<any>>> {
|
|
104
|
-
/**
|
|
105
|
-
* Event definitions
|
|
106
|
-
*/
|
|
107
|
-
readonly events: TEvents;
|
|
108
|
-
/**
|
|
109
|
-
* Event names as array
|
|
110
|
-
*/
|
|
111
|
-
readonly eventNames: (keyof TEvents)[];
|
|
112
|
-
/**
|
|
113
|
-
* Type inference helper - payload types by event name
|
|
114
|
-
*/
|
|
115
|
-
readonly _types: {
|
|
116
|
-
[K in keyof TEvents]: TEvents[K]['_payload'];
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Infer event names from EventRouter
|
|
121
|
-
*/
|
|
122
|
-
type InferEventNames<T> = T extends EventRouterDef<infer E> ? keyof E & string : never;
|
|
123
|
-
/**
|
|
124
|
-
* Infer payload type for specific event
|
|
125
|
-
*/
|
|
126
|
-
type InferEventPayload<T extends EventRouterDef<any>, K extends InferEventNames<T>> = T['_types'][K];
|
|
127
|
-
/**
|
|
128
|
-
* Infer all event payloads map
|
|
129
|
-
*/
|
|
130
|
-
type InferEventPayloads<T extends EventRouterDef<any>> = T['_types'];
|
|
131
|
-
/**
|
|
132
|
-
* Define an event router for SSE subscription
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* ```typescript
|
|
136
|
-
* export const eventRouter = defineEventRouter({
|
|
137
|
-
* userCreated,
|
|
138
|
-
* orderPlaced,
|
|
139
|
-
* });
|
|
140
|
-
*
|
|
141
|
-
* // Type inference
|
|
142
|
-
* type Names = InferEventNames<typeof eventRouter>;
|
|
143
|
-
* // 'userCreated' | 'orderPlaced'
|
|
144
|
-
*
|
|
145
|
-
* type Payload = InferEventPayload<typeof eventRouter, 'userCreated'>;
|
|
146
|
-
* // { userId: string }
|
|
147
|
-
* ```
|
|
148
|
-
*/
|
|
149
|
-
declare function defineEventRouter<TEvents extends Record<string, EventDef<any>>>(events: TEvents): EventRouterDef<TEvents>;
|
|
150
|
-
|
|
151
|
-
export { type EventRouterDef as E, type InferEventNames as I, type JobQueueSender as J, type PubSubCache as P, type EventDef as a, type InferEventPayload as b, type InferEventPayloads as c, defineEventRouter as d, type EventHandler as e, type InferEventPayload$1 as f };
|
package/dist/types-B-e_f2dQ.d.ts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import { E as EventRouterDef, I as InferEventNames, b as InferEventPayload } from './router-Di7ENoah.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* SSE Types
|
|
5
|
-
*
|
|
6
|
-
* Type definitions for Server-Sent Events
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* SSE message sent from server
|
|
11
|
-
*/
|
|
12
|
-
interface SSEMessage<TEvent extends string = string, TPayload = unknown> {
|
|
13
|
-
/** Event name */
|
|
14
|
-
event: TEvent;
|
|
15
|
-
/** Event payload */
|
|
16
|
-
data: TPayload;
|
|
17
|
-
/** Optional message ID for reconnection */
|
|
18
|
-
id?: string;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* SSE Handler configuration
|
|
22
|
-
*/
|
|
23
|
-
interface SSEHandlerConfig {
|
|
24
|
-
/**
|
|
25
|
-
* Keep-alive ping interval in milliseconds
|
|
26
|
-
* @default 30000
|
|
27
|
-
*/
|
|
28
|
-
pingInterval?: number;
|
|
29
|
-
/**
|
|
30
|
-
* Custom headers for SSE response
|
|
31
|
-
*/
|
|
32
|
-
headers?: Record<string, string>;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* SSE Client configuration
|
|
36
|
-
*/
|
|
37
|
-
interface SSEClientConfig {
|
|
38
|
-
/**
|
|
39
|
-
* Backend API host URL
|
|
40
|
-
* @default NEXT_PUBLIC_SPFN_API_URL || 'http://localhost:8790'
|
|
41
|
-
* @example 'http://localhost:8790'
|
|
42
|
-
* @example 'https://api.example.com'
|
|
43
|
-
*/
|
|
44
|
-
host?: string;
|
|
45
|
-
/**
|
|
46
|
-
* SSE endpoint pathname
|
|
47
|
-
* @default '/events/stream'
|
|
48
|
-
*/
|
|
49
|
-
pathname?: string;
|
|
50
|
-
/**
|
|
51
|
-
* Full URL (overrides host + pathname)
|
|
52
|
-
* @deprecated Use host and pathname instead
|
|
53
|
-
* @example 'http://localhost:8790/events/stream'
|
|
54
|
-
*/
|
|
55
|
-
url?: string;
|
|
56
|
-
/**
|
|
57
|
-
* Auto reconnect on disconnect
|
|
58
|
-
* @default true
|
|
59
|
-
*/
|
|
60
|
-
reconnect?: boolean;
|
|
61
|
-
/**
|
|
62
|
-
* Reconnect delay in milliseconds
|
|
63
|
-
* @default 3000
|
|
64
|
-
*/
|
|
65
|
-
reconnectDelay?: number;
|
|
66
|
-
/**
|
|
67
|
-
* Maximum reconnect attempts (0 = infinite)
|
|
68
|
-
* @default 0
|
|
69
|
-
*/
|
|
70
|
-
maxReconnectAttempts?: number;
|
|
71
|
-
/**
|
|
72
|
-
* Include credentials (cookies) in request
|
|
73
|
-
* @default false
|
|
74
|
-
*/
|
|
75
|
-
withCredentials?: boolean;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Event handler function
|
|
79
|
-
*/
|
|
80
|
-
type SSEEventHandler<TPayload> = (payload: TPayload) => void;
|
|
81
|
-
/**
|
|
82
|
-
* Event handlers map for EventRouter
|
|
83
|
-
*/
|
|
84
|
-
type SSEEventHandlers<TRouter extends EventRouterDef<any>> = {
|
|
85
|
-
[K in InferEventNames<TRouter>]?: SSEEventHandler<InferEventPayload<TRouter, K>>;
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* Subscription options
|
|
89
|
-
*/
|
|
90
|
-
interface SSESubscribeOptions<TRouter extends EventRouterDef<any>> {
|
|
91
|
-
/**
|
|
92
|
-
* Events to subscribe
|
|
93
|
-
*/
|
|
94
|
-
events: InferEventNames<TRouter>[];
|
|
95
|
-
/**
|
|
96
|
-
* Event handlers
|
|
97
|
-
*/
|
|
98
|
-
handlers: SSEEventHandlers<TRouter>;
|
|
99
|
-
/**
|
|
100
|
-
* Called when connection opens
|
|
101
|
-
*/
|
|
102
|
-
onOpen?: () => void;
|
|
103
|
-
/**
|
|
104
|
-
* Called on connection error
|
|
105
|
-
*/
|
|
106
|
-
onError?: (error: Event) => void;
|
|
107
|
-
/**
|
|
108
|
-
* Called when reconnecting
|
|
109
|
-
*/
|
|
110
|
-
onReconnect?: (attempt: number) => void;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* SSE connection state
|
|
114
|
-
*/
|
|
115
|
-
type SSEConnectionState = 'connecting' | 'open' | 'closed' | 'error';
|
|
116
|
-
/**
|
|
117
|
-
* Unsubscribe function
|
|
118
|
-
*/
|
|
119
|
-
type SSEUnsubscribe = () => void;
|
|
120
|
-
|
|
121
|
-
export type { SSEHandlerConfig as S, SSEMessage as a, SSEClientConfig as b, SSEEventHandler as c, SSEEventHandlers as d, SSESubscribeOptions as e, SSEConnectionState as f, SSEUnsubscribe as g };
|
package/docs/cache.md
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
# Cache
|
|
2
|
-
|
|
3
|
-
Redis caching with type-safe operations.
|
|
4
|
-
|
|
5
|
-
## Setup
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
REDIS_URL=redis://localhost:6379
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Basic Usage
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
import { cache } from '@spfn/core/cache';
|
|
15
|
-
|
|
16
|
-
// Set
|
|
17
|
-
await cache.set('user:123', { id: '123', name: 'John' });
|
|
18
|
-
await cache.set('session:abc', data, { ttl: 3600 }); // 1 hour
|
|
19
|
-
|
|
20
|
-
// Get
|
|
21
|
-
const user = await cache.get<User>('user:123');
|
|
22
|
-
|
|
23
|
-
// Delete
|
|
24
|
-
await cache.del('user:123');
|
|
25
|
-
|
|
26
|
-
// Check existence
|
|
27
|
-
const exists = await cache.exists('user:123');
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## TTL Options
|
|
31
|
-
|
|
32
|
-
```typescript
|
|
33
|
-
// Set with TTL (seconds)
|
|
34
|
-
await cache.set('key', value, { ttl: 60 }); // 1 minute
|
|
35
|
-
await cache.set('key', value, { ttl: 3600 }); // 1 hour
|
|
36
|
-
await cache.set('key', value, { ttl: 86400 }); // 1 day
|
|
37
|
-
|
|
38
|
-
// No expiration
|
|
39
|
-
await cache.set('key', value); // Permanent until deleted
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Patterns
|
|
43
|
-
|
|
44
|
-
### Cache-Aside
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
async function getUser(id: string): Promise<User>
|
|
48
|
-
{
|
|
49
|
-
const cached = await cache.get<User>(`user:${id}`);
|
|
50
|
-
if (cached)
|
|
51
|
-
{
|
|
52
|
-
return cached;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const user = await userRepo.findById(id);
|
|
56
|
-
if (user)
|
|
57
|
-
{
|
|
58
|
-
await cache.set(`user:${id}`, user, { ttl: 3600 });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return user;
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Cache Invalidation
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
async function updateUser(id: string, data: Partial<User>)
|
|
69
|
-
{
|
|
70
|
-
const user = await userRepo.update(id, data);
|
|
71
|
-
await cache.del(`user:${id}`); // Invalidate cache
|
|
72
|
-
return user;
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Cache with Prefix
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
const userCache = cache.prefix('user');
|
|
80
|
-
|
|
81
|
-
await userCache.set('123', user); // Key: user:123
|
|
82
|
-
await userCache.get('123');
|
|
83
|
-
await userCache.del('123');
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Hash Operations
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
// Set hash field
|
|
90
|
-
await cache.hset('user:123', 'name', 'John');
|
|
91
|
-
|
|
92
|
-
// Get hash field
|
|
93
|
-
const name = await cache.hget('user:123', 'name');
|
|
94
|
-
|
|
95
|
-
// Get all hash fields
|
|
96
|
-
const user = await cache.hgetall('user:123');
|
|
97
|
-
|
|
98
|
-
// Delete hash field
|
|
99
|
-
await cache.hdel('user:123', 'name');
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## List Operations
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
// Push to list
|
|
106
|
-
await cache.lpush('queue', item);
|
|
107
|
-
await cache.rpush('queue', item);
|
|
108
|
-
|
|
109
|
-
// Pop from list
|
|
110
|
-
const item = await cache.lpop('queue');
|
|
111
|
-
const item = await cache.rpop('queue');
|
|
112
|
-
|
|
113
|
-
// Get list range
|
|
114
|
-
const items = await cache.lrange('queue', 0, -1); // All items
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## Best Practices
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
// 1. Use consistent key naming
|
|
121
|
-
`user:${id}`
|
|
122
|
-
`session:${token}`
|
|
123
|
-
`cache:posts:${page}`
|
|
124
|
-
|
|
125
|
-
// 2. Set appropriate TTL
|
|
126
|
-
{ ttl: 300 } // 5 min for frequently changing data
|
|
127
|
-
{ ttl: 3600 } // 1 hour for stable data
|
|
128
|
-
{ ttl: 86400 } // 1 day for rarely changing data
|
|
129
|
-
|
|
130
|
-
// 3. Invalidate on write
|
|
131
|
-
await userRepo.update(id, data);
|
|
132
|
-
await cache.del(`user:${id}`);
|
|
133
|
-
```
|
package/docs/codegen.md
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# Codegen
|
|
2
|
-
|
|
3
|
-
Automatic API client generation from route definitions.
|
|
4
|
-
|
|
5
|
-
## Setup
|
|
6
|
-
|
|
7
|
-
### Configure Generator
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
// codegen.config.ts
|
|
11
|
-
import { defineCodegenConfig } from '@spfn/core/codegen';
|
|
12
|
-
|
|
13
|
-
export default defineCodegenConfig({
|
|
14
|
-
generators: [
|
|
15
|
-
{
|
|
16
|
-
name: 'api-client',
|
|
17
|
-
output: './src/client/api.ts',
|
|
18
|
-
router: './src/server/server.config.ts'
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
});
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Generate Client
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
# Generate once
|
|
28
|
-
pnpm spfn codegen run
|
|
29
|
-
|
|
30
|
-
# Watch mode (dev server includes this)
|
|
31
|
-
pnpm spfn:dev
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Generated Client
|
|
35
|
-
|
|
36
|
-
```typescript
|
|
37
|
-
// src/client/api.ts (generated)
|
|
38
|
-
import { createApi } from '@spfn/core/nextjs';
|
|
39
|
-
import type { AppRouter } from '@/server/server.config';
|
|
40
|
-
|
|
41
|
-
export const api = createApi<AppRouter>();
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Usage
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
import { api } from '@/client/api';
|
|
48
|
-
|
|
49
|
-
// Type-safe API calls
|
|
50
|
-
const user = await api.getUser.call({
|
|
51
|
-
params: { id: '123' }
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const users = await api.getUsers.call({
|
|
55
|
-
query: { page: 1, limit: 20 }
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const created = await api.createUser.call({
|
|
59
|
-
body: { email: 'user@example.com', name: 'User' }
|
|
60
|
-
});
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## CLI Commands
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
# Generate API client
|
|
67
|
-
pnpm spfn codegen run
|
|
68
|
-
|
|
69
|
-
# List registered generators
|
|
70
|
-
pnpm spfn codegen list
|
|
71
|
-
|
|
72
|
-
# Run specific generator
|
|
73
|
-
pnpm spfn codegen run --name api-client
|
|
74
|
-
```
|