@uploadista/server 0.0.7 → 0.0.9

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 (37) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/dist/auth/index.d.mts +2 -0
  3. package/dist/auth/index.mjs +1 -0
  4. package/dist/{auth-C77S4vQd.js → auth-BqArZeGK.mjs} +1 -1
  5. package/dist/auth-BqArZeGK.mjs.map +1 -0
  6. package/dist/{index-CvDNB1lJ.d.ts → index--Lny6VJP.d.mts} +1 -1
  7. package/dist/index--Lny6VJP.d.mts.map +1 -0
  8. package/dist/index.cjs +1 -1
  9. package/dist/index.d.cts +735 -12
  10. package/dist/index.d.cts.map +1 -1
  11. package/dist/index.d.mts +1343 -0
  12. package/dist/index.d.mts.map +1 -0
  13. package/dist/index.mjs +2 -0
  14. package/dist/index.mjs.map +1 -0
  15. package/package.json +10 -7
  16. package/src/adapter/index.ts +10 -0
  17. package/src/adapter/types.ts +229 -0
  18. package/src/core/http-handlers/flow-http-handlers.ts +245 -0
  19. package/src/core/http-handlers/http-handlers.ts +72 -0
  20. package/src/core/http-handlers/upload-http-handlers.ts +168 -0
  21. package/src/core/index.ts +12 -0
  22. package/src/core/routes.ts +188 -0
  23. package/src/core/server.ts +327 -0
  24. package/src/core/types.ts +322 -0
  25. package/src/core/websocket-handlers/flow-websocket-handlers.ts +47 -0
  26. package/src/core/websocket-handlers/upload-websocket-handlers.ts +47 -0
  27. package/src/core/websocket-handlers/websocket-handlers.ts +151 -0
  28. package/src/core/websocket-routes.ts +136 -0
  29. package/src/index.ts +2 -0
  30. package/dist/auth/index.d.ts +0 -2
  31. package/dist/auth/index.js +0 -1
  32. package/dist/auth-C77S4vQd.js.map +0 -1
  33. package/dist/index-CvDNB1lJ.d.ts.map +0 -1
  34. package/dist/index.d.ts +0 -620
  35. package/dist/index.d.ts.map +0 -1
  36. package/dist/index.js +0 -2
  37. package/dist/index.js.map +0 -1
package/dist/index.d.cts CHANGED
@@ -1,14 +1,96 @@
1
1
  import { n as getAuthCredentials, t as AuthCredentialsResponse } from "./index-50KlDIjc.cjs";
2
+ import { DataStoreCapabilities, Flow, FlowData, FlowJob, FlowServer, UploadEvent, UploadFile, UploadServer, UploadistaError } from "@uploadista/core";
2
3
  import { Context, Effect, Layer } from "effect";
3
- import { UploadistaError } from "@uploadista/core/errors";
4
- import * as _uploadista_core0 from "@uploadista/core";
5
- import { Flow, UploadServer } from "@uploadista/core";
6
- import { FlowProvider } from "@uploadista/core/flow";
7
- import { BaseEventEmitterService, BaseKvStoreService, UploadFileDataStore, UploadFileDataStores, UploadFileKVStore } from "@uploadista/core/types";
8
- import { UploadServer as UploadServer$1 } from "@uploadista/core/upload";
4
+ import { Flow as Flow$1, FlowProvider, FlowServerShape } from "@uploadista/core/flow";
5
+ import { BaseEventEmitterService, BaseKvStoreService, DataStoreConfig, EventBroadcasterService, UploadFileDataStore, UploadFileDataStores, UploadFileKVStore } from "@uploadista/core/types";
9
6
  import { GenerateId } from "@uploadista/core/utils";
10
- import z from "zod";
7
+ import z$1, { z } from "zod";
8
+ import { UploadServer as UploadServer$1, UploadServerShape } from "@uploadista/core/upload";
9
+ import { UploadistaError as UploadistaError$1 } from "@uploadista/core/errors";
11
10
 
11
+ //#region src/core/routes.d.ts
12
+ type UploadistaRouteType = "create-upload" | "get-capabilities" | "get-upload" | "upload-chunk" | "get-flow" | "run-flow" | "job-status" | "resume-flow" | "pause-flow" | "cancel-flow" | "not-found" | "bad-request" | "method-not-allowed" | "unsupported-content-type";
13
+ type UploadistaRoute<T extends UploadistaRouteType> = {
14
+ type: T;
15
+ };
16
+ type UploadistaStandardResponse<T extends UploadistaRouteType, ResponseBody, Status extends number = 200> = UploadistaRoute<T> & {
17
+ status: Status;
18
+ headers: {
19
+ "Content-Type": "application/json";
20
+ };
21
+ body: ResponseBody;
22
+ };
23
+ type NotFoundRequest = UploadistaRoute<"not-found">;
24
+ type NotFoundResponse = UploadistaStandardResponse<"not-found", {
25
+ error: "Not found";
26
+ }, 404>;
27
+ type MethodNotAllowedRequest = UploadistaRoute<"method-not-allowed">;
28
+ type MethodNotAllowedResponse = UploadistaStandardResponse<"method-not-allowed", {
29
+ error: "Method not allowed";
30
+ }, 405>;
31
+ type BadRequestRequest = UploadistaRoute<"bad-request"> & {
32
+ message: string;
33
+ };
34
+ type BadRequestResponse = UploadistaStandardResponse<"bad-request", {
35
+ error: "Bad request";
36
+ message: string;
37
+ }, 400>;
38
+ type UnsupportedContentTypeRequest = UploadistaRoute<"unsupported-content-type">;
39
+ type UnsupportedContentTypeResponse = UploadistaStandardResponse<"unsupported-content-type", {
40
+ error: "Unsupported content type";
41
+ }, 415>;
42
+ type CreateUploadRequest = UploadistaRoute<"create-upload"> & {
43
+ data: unknown;
44
+ };
45
+ type CreateUploadResponse = UploadistaStandardResponse<"create-upload", UploadFile>;
46
+ type GetCapabilitiesRequest = UploadistaRoute<"get-capabilities"> & {
47
+ storageId: string;
48
+ };
49
+ type GetCapabilitiesResponse = UploadistaStandardResponse<"get-capabilities", {
50
+ storageId: string;
51
+ capabilities: DataStoreCapabilities;
52
+ timestamp: string;
53
+ }>;
54
+ type GetUploadRequest = UploadistaRoute<"get-upload"> & {
55
+ uploadId: string;
56
+ };
57
+ type GetUploadResponse = UploadistaStandardResponse<"get-upload", UploadFile>;
58
+ type UploadChunkRequest = UploadistaRoute<"upload-chunk"> & {
59
+ uploadId: string;
60
+ data: ReadableStream;
61
+ };
62
+ type UploadChunkResponse = UploadistaStandardResponse<"upload-chunk", UploadFile>;
63
+ type GetFlowRequest = UploadistaRoute<"get-flow"> & {
64
+ flowId: string;
65
+ };
66
+ type GetFlowResponse = UploadistaStandardResponse<"get-flow", FlowData>;
67
+ type RunFlowRequest = UploadistaRoute<"run-flow"> & {
68
+ flowId: string;
69
+ storageId: string;
70
+ inputs: Record<string, unknown>;
71
+ };
72
+ type RunFlowResponse = UploadistaStandardResponse<"run-flow", FlowJob>;
73
+ type GetJobStatusRequest = UploadistaRoute<"job-status"> & {
74
+ jobId: string;
75
+ };
76
+ type GetJobStatusResponse = UploadistaStandardResponse<"job-status", FlowJob>;
77
+ type ResumeFlowRequest = UploadistaRoute<"resume-flow"> & {
78
+ jobId: string;
79
+ nodeId: string;
80
+ newData: unknown;
81
+ };
82
+ type ResumeFlowResponse = UploadistaStandardResponse<"resume-flow", FlowJob>;
83
+ type PauseFlowRequest = UploadistaRoute<"pause-flow"> & {
84
+ jobId: string;
85
+ };
86
+ type PauseFlowResponse = UploadistaStandardResponse<"pause-flow", FlowJob>;
87
+ type CancelFlowRequest = UploadistaRoute<"cancel-flow"> & {
88
+ jobId: string;
89
+ };
90
+ type CancelFlowResponse = UploadistaStandardResponse<"cancel-flow", FlowJob>;
91
+ type UploadistaRequest = CreateUploadRequest | GetCapabilitiesRequest | GetUploadRequest | UploadChunkRequest | GetFlowRequest | RunFlowRequest | GetJobStatusRequest | ResumeFlowRequest | PauseFlowRequest | CancelFlowRequest | NotFoundRequest | BadRequestRequest | MethodNotAllowedRequest | UnsupportedContentTypeRequest;
92
+ type UploadistaResponse = CreateUploadResponse | GetCapabilitiesResponse | GetUploadResponse | UploadChunkResponse | GetFlowResponse | RunFlowResponse | GetJobStatusResponse | ResumeFlowResponse | PauseFlowResponse | CancelFlowResponse | NotFoundResponse | BadRequestResponse | MethodNotAllowedResponse | UnsupportedContentTypeResponse | StandardResponse;
93
+ //#endregion
12
94
  //#region src/types.d.ts
13
95
  /**
14
96
  * Authentication context containing user identity and authorization metadata.
@@ -48,6 +130,210 @@ type AuthContext = {
48
130
  */
49
131
  type AuthResult = AuthContext | null;
50
132
  //#endregion
133
+ //#region src/adapter/types.d.ts
134
+ /**
135
+ * Standard request representation extracted from framework-specific request objects.
136
+ *
137
+ * This interface provides a framework-agnostic way to represent HTTP requests,
138
+ * allowing the core server logic to work uniformly across Hono, Express, Fastify,
139
+ * and other frameworks.
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * const standardRequest: StandardRequest = {
144
+ * method: "POST",
145
+ * url: new URL("https://example.com/uploadista/api/upload"),
146
+ * headers: { "content-type": "application/json" },
147
+ * body: { file: "data" }
148
+ * };
149
+ * ```
150
+ */
151
+ interface StandardRequest {
152
+ /**
153
+ * HTTP method (GET, POST, PATCH, etc.)
154
+ */
155
+ method: string;
156
+ /**
157
+ * Full URL of the request including protocol, host, path, and query parameters
158
+ */
159
+ url: URL;
160
+ /**
161
+ * Request headers as key-value pairs
162
+ */
163
+ headers: Record<string, string>;
164
+ /**
165
+ * Optional request body (parsed or raw)
166
+ */
167
+ body?: unknown;
168
+ }
169
+ /**
170
+ * Standard response representation to be sent by framework-specific adapters.
171
+ *
172
+ * The core server produces StandardResponse objects, which adapters then
173
+ * translate into framework-specific response formats.
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * const standardResponse: StandardResponse = {
178
+ * status: 200,
179
+ * headers: { "content-type": "application/json" },
180
+ * body: { uploadId: "abc123" }
181
+ * };
182
+ * ```
183
+ */
184
+ interface StandardResponse {
185
+ /**
186
+ * HTTP status code (200, 404, 500, etc.)
187
+ */
188
+ status: number;
189
+ /**
190
+ * Optional response headers as key-value pairs
191
+ */
192
+ headers?: Record<string, string>;
193
+ /**
194
+ * Optional response body (will be JSON-stringified if object)
195
+ */
196
+ body?: unknown;
197
+ }
198
+ /**
199
+ * WebSocket handler interface for framework-agnostic WebSocket management.
200
+ *
201
+ * This interface allows the core server to interact with WebSocket connections
202
+ * without needing to know about framework-specific WebSocket APIs.
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * const wsHandler: WebSocketHandler = {
207
+ * onMessage: (message) => console.log("Received:", message),
208
+ * onClose: () => console.log("Connection closed"),
209
+ * onError: (error) => console.error("WebSocket error:", error)
210
+ * };
211
+ * ```
212
+ */
213
+ interface WebSocketHandler {
214
+ /**
215
+ * Callback invoked when a message is received from the client
216
+ *
217
+ * @param message - The message string received
218
+ */
219
+ onMessage: (message: string) => void;
220
+ /**
221
+ * Callback invoked when the WebSocket connection is closed
222
+ */
223
+ onClose: () => void;
224
+ /**
225
+ * Callback invoked when a WebSocket error occurs
226
+ *
227
+ * @param error - The error that occurred
228
+ */
229
+ onError: (error: Error) => void;
230
+ }
231
+ /**
232
+ * ServerAdapter interface that framework adapters must implement.
233
+ *
234
+ * This interface defines the contract between the core server (framework-agnostic)
235
+ * and framework-specific adapters (Hono, Express, Fastify, etc.).
236
+ *
237
+ * Each adapter translates between framework-specific request/response types
238
+ * and the standard types used by the core server.
239
+ *
240
+ * @template TRequest - Framework-specific request type (e.g., Context for Hono, Request for Express)
241
+ * @template TResponse - Framework-specific response type (e.g., Context for Hono, Response for Express)
242
+ * @template TWebSocket - Framework-specific WebSocket type (optional, defaults to unknown)
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * // Hono adapter example
247
+ * const honoAdapter: ServerAdapter<Context, Context, WSEvents> = {
248
+ * extractRequest: (c) => Effect.succeed({
249
+ * method: c.req.raw.method,
250
+ * url: new URL(c.req.raw.url),
251
+ * headers: Object.fromEntries(c.req.raw.headers.entries()),
252
+ * body: c.req.raw.body
253
+ * }),
254
+ * sendResponse: (c, response) => Effect.sync(() =>
255
+ * new Response(JSON.stringify(response.body), {
256
+ * status: response.status,
257
+ * headers: response.headers
258
+ * })
259
+ * ),
260
+ * runAuthMiddleware: (c) => Effect.tryPromise(() => authMiddleware(c)),
261
+ * createWebSocketHandler: (ws) => ({ ... })
262
+ * };
263
+ * ```
264
+ */
265
+ interface ServerAdapter<TContext, TResponse, TWebSocketHandler = unknown> {
266
+ /**
267
+ * Extract standard request details from framework-specific request.
268
+ *
269
+ * This method converts the framework's native request object into a
270
+ * UploadistaRequest that the core server can process uniformly.
271
+ *
272
+ * @param req - Framework-specific request object
273
+ * @returns Effect that produces UploadistaRequest on success
274
+ */
275
+ extractRequest(req: TContext, {
276
+ baseUrl
277
+ }: {
278
+ baseUrl: string;
279
+ }): Effect.Effect<UploadistaRequest, never, never>;
280
+ /**
281
+ * Send standard response using framework-specific response object.
282
+ *
283
+ * This method converts a UploadistaResponse from the core server into
284
+ * the format required by the framework (e.g., Web API Response, Express res.json()).
285
+ *
286
+ * @param response - Standard response to send
287
+ * @returns Effect that completes when response is sent
288
+ */
289
+ sendResponse(response: UploadistaResponse, context: TContext): Effect.Effect<TResponse, never, never>;
290
+ /**
291
+ * Optional: Run framework-specific auth middleware.
292
+ *
293
+ * If provided, this method is called before each request is processed.
294
+ * It should execute the framework's authentication middleware and return
295
+ * an AuthResult (AuthContext on success, null on failure).
296
+ *
297
+ * If not provided, the adapter assumes no authentication is required.
298
+ *
299
+ * @param ctx - Framework-specific context object
300
+ * @param res - Framework-specific response object
301
+ * @returns Effect that produces AuthResult (AuthContext or null)
302
+ */
303
+ runAuthMiddleware?(ctx: TContext): Effect.Effect<AuthResult, never, never>;
304
+ /**
305
+ * Optional: Create WebSocket handler for real-time updates.
306
+ *
307
+ * Only needed if the framework supports WebSocket connections for
308
+ * real-time upload progress and flow status updates.
309
+ *
310
+ * @param ws - Framework-specific WebSocket object
311
+ * @param ctx - Framework-specific context object (for initial handshake)
312
+ * @param context - Server context with baseUrl, uploadServer, and flowServer
313
+ * @returns WebSocketHandler with callbacks for message, close, and error events
314
+ */
315
+ webSocketHandler(context: {
316
+ baseUrl: string;
317
+ }): Effect.Effect<TWebSocketHandler, never, UploadServer | FlowServer>;
318
+ /**
319
+ * Optional: Extract waitUntil callback from the framework context.
320
+ *
321
+ * When provided, allows flows to execute beyond the HTTP response lifecycle.
322
+ * This function is called per-request to extract the waitUntil callback from
323
+ * the framework-specific context.
324
+ *
325
+ * @param ctx - Framework-specific context object
326
+ * @returns The waitUntil callback or undefined if not available
327
+ *
328
+ * @example
329
+ * ```typescript
330
+ * // Cloudflare Workers with Hono:
331
+ * extractWaitUntil: (c) => c.executionCtx.waitUntil.bind(c.executionCtx)
332
+ * ```
333
+ */
334
+ extractWaitUntil?: (ctx: TContext) => ((promise: Promise<unknown>) => void) | undefined;
335
+ }
336
+ //#endregion
51
337
  //#region src/cache.d.ts
52
338
  /**
53
339
  * Configuration options for the auth cache.
@@ -132,6 +418,443 @@ declare const AuthCacheServiceLive: (config?: AuthCacheConfig) => Layer.Layer<Au
132
418
  */
133
419
  declare const NoAuthCacheServiceLive: Layer.Layer<AuthCacheService>;
134
420
  //#endregion
421
+ //#region src/core/types.d.ts
422
+ /**
423
+ * Function type for retrieving flows based on flow ID and client ID.
424
+ *
425
+ * This function is called by the core server when a flow needs to be executed.
426
+ * It should return an Effect that resolves to the requested Flow or fails with
427
+ * an UploadistaError if the flow is not found or not authorized.
428
+ *
429
+ * @param flowId - The unique identifier of the flow to retrieve
430
+ * @param clientId - The authenticated client ID (null if not authenticated)
431
+ * @returns Effect that produces the Flow or fails with an error
432
+ *
433
+ * @example
434
+ * ```typescript
435
+ * const flows: FlowsFunction = (flowId, clientId) =>
436
+ * Effect.gen(function* () {
437
+ * if (flowId === "image-resize") {
438
+ * return imageResizeFlow;
439
+ * }
440
+ * return yield* Effect.fail(
441
+ * new UploadistaError({ code: "FLOW_NOT_FOUND", status: 404 })
442
+ * );
443
+ * });
444
+ * ```
445
+ */
446
+ type FlowsFunction = (flowId: string, clientId: string | null) => Effect.Effect<Flow$1<z.ZodSchema<unknown>, z.ZodSchema<unknown>, unknown>, UploadistaError, unknown>;
447
+ /**
448
+ * Configuration for creating the unified Uploadista server.
449
+ *
450
+ * This configuration is framework-agnostic and contains all the business logic
451
+ * configuration. Framework-specific details are provided via the `adapter` field.
452
+ *
453
+ * @template TRequest - Framework-specific request type
454
+ * @template TResponse - Framework-specific response type
455
+ * @template TWebSocket - Framework-specific WebSocket type (optional)
456
+ *
457
+ * @example
458
+ * ```typescript
459
+ * import { createUploadistaServer, honoAdapter } from "@uploadista/server";
460
+ *
461
+ * const config: UploadistaServerConfig<Context, Context, WSEvents> = {
462
+ * // Core business logic configuration
463
+ * flows: getFlowById,
464
+ * dataStore: { type: "s3", config: { bucket: "my-bucket" } },
465
+ * kvStore: redisKvStore,
466
+ * baseUrl: "/uploadista",
467
+ *
468
+ * // Framework-specific adapter
469
+ * adapter: honoAdapter({
470
+ * authMiddleware: async (c) => {
471
+ * // Hono-specific auth logic
472
+ * return { clientId: "user-123" };
473
+ * },
474
+ * }),
475
+ * };
476
+ *
477
+ * const server = await createUploadistaServer(config);
478
+ * ```
479
+ */
480
+ interface UploadistaServerConfig<TRequest, TResponse, TWebSocket = unknown> {
481
+ /**
482
+ * Function for retrieving flows by ID.
483
+ *
484
+ * This function is called when a flow execution is requested.
485
+ * It receives the flow ID and client ID (from auth context) and should
486
+ * return an Effect that resolves to the Flow definition.
487
+ *
488
+ * @example
489
+ * ```typescript
490
+ * flows: (flowId, clientId) => Effect.succeed(myFlows[flowId])
491
+ * ```
492
+ */
493
+ flows: FlowsFunction;
494
+ /**
495
+ * Data store configuration for file storage.
496
+ *
497
+ * Specifies where uploaded files should be stored (S3, Azure, GCS, filesystem).
498
+ * The core server creates the appropriate data store layer from this configuration.
499
+ *
500
+ * @example
501
+ * ```typescript
502
+ * dataStore: {
503
+ * type: "s3",
504
+ * config: {
505
+ * bucket: "my-uploads",
506
+ * region: "us-east-1"
507
+ * }
508
+ * }
509
+ * ```
510
+ */
511
+ dataStore: DataStoreConfig;
512
+ /**
513
+ * Key-value store layer for metadata storage.
514
+ *
515
+ * Used for storing upload metadata, flow job state, and other persistent data.
516
+ * Can be Redis, Cloudflare KV, in-memory, or any implementation of BaseKvStoreService.
517
+ *
518
+ * @example
519
+ * ```typescript
520
+ * import { redisKvStore } from "@uploadista/kv-store-redis";
521
+ *
522
+ * kvStore: redisKvStore({ url: "redis://localhost:6379" })
523
+ * ```
524
+ */
525
+ kvStore: Layer.Layer<BaseKvStoreService>;
526
+ /**
527
+ * Optional: Plugins to extend functionality.
528
+ *
529
+ * Plugins are Effect layers that add additional capabilities to the upload
530
+ * and flow servers. They are merged into the server layer composition.
531
+ *
532
+ * @example
533
+ * ```typescript
534
+ * plugins: [imageProcessingPlugin, virusScanPlugin]
535
+ * ```
536
+ */
537
+ plugins?: readonly Layer.Layer<any, never, never>[];
538
+ /**
539
+ * Optional: Event emitter layer for progress notifications.
540
+ *
541
+ * Used to emit upload progress, flow status updates, and other events.
542
+ * Defaults to in-memory event emitter if not provided.
543
+ *
544
+ * @example
545
+ * ```typescript
546
+ * import { webSocketEventEmitter } from "@uploadista/event-emitter-websocket";
547
+ *
548
+ * eventEmitter: webSocketEventEmitter()
549
+ * ```
550
+ */
551
+ eventEmitter?: Layer.Layer<BaseEventEmitterService>;
552
+ /**
553
+ * Optional: Event broadcaster layer for real-time updates.
554
+ *
555
+ * Used to broadcast events to multiple subscribers (e.g., WebSocket connections).
556
+ * Defaults to in-memory broadcaster if not provided.
557
+ *
558
+ * @example
559
+ * ```typescript
560
+ * import { memoryEventBroadcaster } from "@uploadista/event-broadcaster-memory";
561
+ *
562
+ * eventBroadcaster: memoryEventBroadcaster()
563
+ * ```
564
+ */
565
+ eventBroadcaster?: Layer.Layer<EventBroadcasterService>;
566
+ /**
567
+ * Optional: Base URL path for Uploadista endpoints.
568
+ *
569
+ * All Uploadista routes will be prefixed with `{baseUrl}/api/`.
570
+ * For example, with baseUrl="/uploadista", routes become:
571
+ * - POST /uploadista/api/upload
572
+ * - POST /uploadista/api/flow/{flowId}/{storageId}
573
+ *
574
+ * @default "" (no prefix, routes start with /api/)
575
+ */
576
+ baseUrl?: string;
577
+ /**
578
+ * Optional: Custom ID generator layer.
579
+ *
580
+ * Used for generating upload IDs, job IDs, and other unique identifiers.
581
+ * Defaults to built-in ID generator if not provided.
582
+ *
583
+ * @example
584
+ * ```typescript
585
+ * import { nanoidGenerator } from "@uploadista/utils";
586
+ *
587
+ * generateId: nanoidGenerator()
588
+ * ```
589
+ */
590
+ generateId?: Layer.Layer<GenerateId>;
591
+ /**
592
+ * Optional: Enable distributed tracing with OpenTelemetry.
593
+ *
594
+ * When true, Effect programs run with OpenTelemetry tracing enabled,
595
+ * allowing observability into upload and flow execution.
596
+ *
597
+ * @default false
598
+ */
599
+ withTracing?: boolean;
600
+ /**
601
+ * Optional: Metrics layer for observability.
602
+ *
603
+ * Used to collect metrics about upload/flow performance, errors, and usage.
604
+ * Defaults to NoOp metrics if not provided.
605
+ *
606
+ * @example
607
+ * ```typescript
608
+ * import { prometheusMetrics } from "@uploadista/observability";
609
+ *
610
+ * metricsLayer: prometheusMetrics()
611
+ * ```
612
+ */
613
+ metricsLayer?: Layer.Layer<any, never, never>;
614
+ /**
615
+ * Optional: Buffered data store layer for performance optimization.
616
+ *
617
+ * Provides in-memory buffering for frequently accessed data,
618
+ * reducing latency for chunk uploads and reads.
619
+ *
620
+ * @example
621
+ * ```typescript
622
+ * import { bufferedDataStore } from "@uploadista/core/data-store";
623
+ *
624
+ * bufferedDataStore: bufferedDataStore({ maxSize: 1024 * 1024 * 10 })
625
+ * ```
626
+ */
627
+ bufferedDataStore?: Layer.Layer<UploadFileDataStore, never, UploadFileKVStore>;
628
+ /**
629
+ * Framework-specific adapter.
630
+ *
631
+ * The adapter provides the bridge between framework-specific request/response
632
+ * types and the standard types used by the core server. Each framework
633
+ * (Hono, Express, Fastify) has its own adapter implementation.
634
+ *
635
+ * @example
636
+ * ```typescript
637
+ * import { honoAdapter } from "@uploadista/adapters-hono";
638
+ *
639
+ * adapter: honoAdapter({
640
+ * authMiddleware: async (c) => ({ clientId: "user-123" })
641
+ * })
642
+ * ```
643
+ */
644
+ adapter: ServerAdapter<TRequest, TResponse, TWebSocket>;
645
+ /**
646
+ * Optional: Configuration for auth context caching.
647
+ *
648
+ * Caching allows subsequent requests (chunk uploads, flow continuations) to
649
+ * reuse the auth context from the initial request without re-authenticating.
650
+ *
651
+ * @example
652
+ * ```typescript
653
+ * authCacheConfig: {
654
+ * maxSize: 10000,
655
+ * ttl: 3600000 // 1 hour
656
+ * }
657
+ * ```
658
+ */
659
+ authCacheConfig?: AuthCacheConfig;
660
+ }
661
+ /**
662
+ * Return type from createUploadistaServer.
663
+ *
664
+ * Contains the handler function and exposed server layers for framework-specific routing.
665
+ *
666
+ * @template TRequest - Framework-specific request type
667
+ * @template TResponse - Framework-specific response type
668
+ * @template TWebSocket - Framework-specific WebSocket type (optional)
669
+ */
670
+ interface UploadistaServer<TRequest, TResponse, TWebSocketHandler = unknown> {
671
+ /**
672
+ * Main request handler that processes HTTP requests through the adapter.
673
+ */
674
+ handler: (req: TRequest) => Promise<TResponse>;
675
+ /**
676
+ * Optional WebSocket handler if the adapter supports WebSocket connections.
677
+ */
678
+ websocketHandler: TWebSocketHandler;
679
+ /**
680
+ * Base URL path for Uploadista endpoints.
681
+ */
682
+ baseUrl: string;
683
+ /**
684
+ * Dispose function for graceful shutdown.
685
+ * Cleans up all resources associated with the managed runtime.
686
+ * Should be called when the server is shutting down.
687
+ */
688
+ dispose: () => Promise<void>;
689
+ }
690
+ //#endregion
691
+ //#region src/core/server.d.ts
692
+ /**
693
+ * Creates the unified Uploadista server with framework-specific adapter.
694
+ *
695
+ * This function composes all layers (upload server, flow server, auth, metrics)
696
+ * and returns a handler that works with any framework via the provided adapter.
697
+ *
698
+ * The core server handles:
699
+ * - Route parsing and matching
700
+ * - Auth middleware execution with timeout protection
701
+ * - Layer composition (upload/flow servers, auth cache, metrics)
702
+ * - Error handling and response formatting
703
+ * - Effect program execution with optional tracing
704
+ *
705
+ * @param config - Server configuration including adapter and business logic
706
+ * @returns Object with handler function, optional WebSocket handler, and base URL
707
+ *
708
+ * @example
709
+ * ```typescript
710
+ * import { createUploadistaServer, honoAdapter } from "@uploadista/server";
711
+ *
712
+ * const server = await createUploadistaServer({
713
+ * flows: getFlowById,
714
+ * dataStore: { type: "s3", config: { bucket: "uploads" } },
715
+ * kvStore: redisKvStore,
716
+ * adapter: honoAdapter({
717
+ * authMiddleware: async (c) => ({ clientId: "user-123" })
718
+ * })
719
+ * });
720
+ *
721
+ * // Use with Hono
722
+ * app.all("/uploadista/*", server.handler);
723
+ * ```
724
+ */
725
+ declare const createUploadistaServer: <TContext, TResponse, TWebSocketHandler = unknown>({
726
+ flows,
727
+ dataStore,
728
+ kvStore,
729
+ plugins,
730
+ eventEmitter,
731
+ eventBroadcaster,
732
+ withTracing,
733
+ baseUrl: configBaseUrl,
734
+ generateId,
735
+ metricsLayer,
736
+ bufferedDataStore,
737
+ adapter,
738
+ authCacheConfig
739
+ }: UploadistaServerConfig<TContext, TResponse, TWebSocketHandler>) => Promise<UploadistaServer<TContext, TResponse, TWebSocketHandler>>;
740
+ //#endregion
741
+ //#region src/core/websocket-routes.d.ts
742
+ /**
743
+ * Framework-agnostic WebSocket connection interface
744
+ * Adapters should wrap their native WebSocket implementations to match this interface
745
+ */
746
+ type WebSocketConnection = {
747
+ id: string;
748
+ send: (data: string) => void;
749
+ close: (code?: number, reason?: string) => void;
750
+ readyState: number;
751
+ };
752
+ /**
753
+ * WebSocket event types for real-time communication
754
+ */
755
+ type WebSocketEventType = "subscribe-upload" | "subscribe-flow" | "unsubscribe-upload" | "unsubscribe-flow" | "ping" | "connection" | "upload-event" | "flow-event" | "error" | "invalid-path" | "auth-failed";
756
+ /**
757
+ * Base WebSocket event structure
758
+ */
759
+ type WebSocketEvent<T extends WebSocketEventType> = {
760
+ type: T;
761
+ };
762
+ /**
763
+ * Incoming WebSocket messages (client -> server)
764
+ */
765
+ type SubscribeUploadEvent = WebSocketEvent<"subscribe-upload"> & {
766
+ uploadId: string;
767
+ };
768
+ type SubscribeFlowEvent = WebSocketEvent<"subscribe-flow"> & {
769
+ jobId: string;
770
+ };
771
+ type UnsubscribeUploadEvent = WebSocketEvent<"unsubscribe-upload"> & {
772
+ uploadId: string;
773
+ };
774
+ type UnsubscribeFlowEvent = WebSocketEvent<"unsubscribe-flow"> & {
775
+ jobId: string;
776
+ };
777
+ type PingEvent = WebSocketEvent<"ping">;
778
+ type WebSocketIncomingEvent = SubscribeUploadEvent | SubscribeFlowEvent | UnsubscribeUploadEvent | UnsubscribeFlowEvent | PingEvent;
779
+ /**
780
+ * Outgoing WebSocket messages (server -> client)
781
+ */
782
+ type ConnectionEvent = WebSocketEvent<"connection"> & {
783
+ message: string;
784
+ id?: string;
785
+ jobId?: string;
786
+ uploadId?: string;
787
+ timestamp: string;
788
+ };
789
+ type UploadEventMessage = WebSocketEvent<"upload-event"> & {
790
+ uploadId: string;
791
+ event: UploadEvent;
792
+ timestamp: string;
793
+ };
794
+ type FlowEventMessage = WebSocketEvent<"flow-event"> & {
795
+ jobId: string;
796
+ event: unknown;
797
+ timestamp: string;
798
+ };
799
+ type ErrorEvent = WebSocketEvent<"error"> & {
800
+ message: string;
801
+ code?: string;
802
+ };
803
+ type InvalidPathEvent = WebSocketEvent<"invalid-path"> & {
804
+ message: string;
805
+ expectedPrefix: string;
806
+ };
807
+ type AuthFailedEvent = WebSocketEvent<"auth-failed"> & {
808
+ message: string;
809
+ authMethod: "token" | "cookies";
810
+ };
811
+ type WebSocketOutgoingEvent = ConnectionEvent | UploadEventMessage | FlowEventMessage | ErrorEvent | InvalidPathEvent | AuthFailedEvent;
812
+ /**
813
+ * WebSocket connection request with routing information
814
+ * Extracted from the WebSocket URL and query parameters
815
+ */
816
+ type WebSocketConnectionRequest = {
817
+ /** Base URL prefix for WebSocket connections */
818
+ baseUrl: string;
819
+ /** Full pathname from the URL */
820
+ pathname: string;
821
+ /** Parsed route segments after baseUrl/ws/ */
822
+ routeSegments: string[];
823
+ /** Whether this is an upload route */
824
+ isUploadRoute: boolean;
825
+ /** Whether this is a flow route */
826
+ isFlowRoute: boolean;
827
+ /** Job ID (for flows) */
828
+ jobId?: string;
829
+ /** Upload ID (for uploads) */
830
+ uploadId?: string;
831
+ /** Event ID (jobId or uploadId) */
832
+ eventId?: string;
833
+ /** WebSocket connection instance */
834
+ connection: WebSocketConnection;
835
+ };
836
+ //#endregion
837
+ //#region src/core/websocket-handlers/websocket-handlers.d.ts
838
+ /**
839
+ * Handles WebSocket connection opening
840
+ * Subscribes to the appropriate events based on the connection request
841
+ */
842
+ declare const handleWebSocketOpen: (request: WebSocketConnectionRequest, uploadServer: UploadServerShape, flowServer: FlowServerShape) => Effect.Effect<void, never, unknown>;
843
+ /**
844
+ * Handles incoming WebSocket messages
845
+ * Currently supports ping/pong for connection keep-alive
846
+ */
847
+ declare const handleWebSocketMessage: (message: string, connection: WebSocketConnection) => Effect.Effect<void, never, never>;
848
+ /**
849
+ * Handles WebSocket connection closing
850
+ * Unsubscribes from all events and cleans up resources
851
+ */
852
+ declare const handleWebSocketClose: (request: WebSocketConnectionRequest, uploadServer: UploadServerShape, flowServer: FlowServerShape) => Effect.Effect<void, never, unknown>;
853
+ /**
854
+ * Handles WebSocket errors
855
+ */
856
+ declare const handleWebSocketError: (error: unknown, eventId?: string) => Effect.Effect<void, never, never>;
857
+ //#endregion
135
858
  //#region src/error-types.d.ts
136
859
  /**
137
860
  * Base adapter error class for HTTP adapters.
@@ -237,7 +960,7 @@ declare const createErrorResponseBody: (error: AdapterError) => {
237
960
  * }
238
961
  * ```
239
962
  */
240
- declare const createUploadistaErrorResponseBody: (error: UploadistaError) => {
963
+ declare const createUploadistaErrorResponseBody: (error: UploadistaError$1) => {
241
964
  error: string;
242
965
  code: string;
243
966
  timestamp: string;
@@ -510,7 +1233,7 @@ declare const createUploadServerLayer: ({
510
1233
  dataStore,
511
1234
  bufferedDataStore,
512
1235
  generateId
513
- }: UploadServerLayerConfig) => Layer.Layer<UploadServer$1, never, never>;
1236
+ }: UploadServerLayerConfig) => Layer.Layer<unknown, unknown, any>;
514
1237
  /**
515
1238
  * Creates the flow server layer with all dependencies composed.
516
1239
  * This layer handles file processing workflows with multi-stage pipelines.
@@ -545,12 +1268,12 @@ declare const createFlowServerLayer: ({
545
1268
  eventEmitter,
546
1269
  flowProvider,
547
1270
  uploadServer
548
- }: FlowServerLayerConfig) => Layer.Layer<_uploadista_core0.FlowServer, never, never>;
1271
+ }: FlowServerLayerConfig) => Layer.Layer<unknown, unknown, any>;
549
1272
  //#endregion
550
1273
  //#region src/plugins-typing.d.ts
551
1274
  type LayerSuccessUnion<Layers extends readonly Layer.Layer<any, never, never>[]> = Layers[number] extends Layer.Layer<infer Success, never, never> ? Success : never;
552
1275
  type FlowSuccess<TFlows extends (flowId: string, clientId: string | null) => Effect.Effect<unknown, unknown, unknown>> = ReturnType<TFlows> extends Effect.Effect<infer Success, unknown, unknown> ? Success : never;
553
- type FlowRequirementsOf<TFlows extends (flowId: string, clientId: string | null) => Effect.Effect<unknown, unknown, unknown>> = FlowSuccess<TFlows> extends Flow<z.ZodSchema<unknown>, z.ZodSchema<unknown>, infer R> ? Exclude<R, UploadServer> : never;
1276
+ type FlowRequirementsOf<TFlows extends (flowId: string, clientId: string | null) => Effect.Effect<unknown, unknown, unknown>> = FlowSuccess<TFlows> extends Flow<z$1.ZodSchema<unknown>, z$1.ZodSchema<unknown>, infer R> ? Exclude<R, UploadServer> : never;
554
1277
  type RequiredPluginsOf<TFlows extends (flowId: string, clientId: string | null) => Effect.Effect<unknown, unknown, unknown>> = Exclude<FlowRequirementsOf<TFlows>, UploadServer>;
555
1278
  type PluginAssertion<TFlows extends (flowId: string, clientId: string | null) => Effect.Effect<unknown, unknown, unknown>, TPlugins extends readonly Layer.Layer<any, never, never>[]> = Exclude<RequiredPluginsOf<TFlows>, LayerSuccessUnion<TPlugins>> extends never ? unknown : {
556
1279
  __missingPlugins: Exclude<RequiredPluginsOf<TFlows>, LayerSuccessUnion<TPlugins>>;
@@ -616,5 +1339,5 @@ declare const AuthContextServiceLive: (authContext: AuthContext | null) => Layer
616
1339
  */
617
1340
  declare const NoAuthContextServiceLive: Layer.Layer<AuthContextService>;
618
1341
  //#endregion
619
- export { AdapterError, AuthCacheConfig, AuthCacheService, AuthCacheServiceLive, AuthContext, AuthContextService, AuthContextServiceLive, AuthCredentialsResponse, AuthResult, BadRequestError, FlowRequirementsOf, FlowServerLayerConfig, FlowSuccess, LayerSuccessUnion, NoAuthCacheServiceLive, NoAuthContextServiceLive, NotFoundError, PluginAssertion, RequiredPluginsOf, UploadServerLayerConfig, ValidationError, createErrorResponseBody, createFlowServerLayer, createGenericErrorResponseBody, createUploadServerLayer, createUploadistaErrorResponseBody, extractFlowAndStorageId, extractJobAndNodeId, extractJobIdFromStatus, getAuthCredentials, getLastSegment, getRouteSegments, handleFlowError, hasBasePath, parseUrlSegments };
1342
+ export { AdapterError, AuthCacheConfig, AuthCacheService, AuthCacheServiceLive, AuthContext, AuthContextService, AuthContextServiceLive, AuthCredentialsResponse, AuthFailedEvent, AuthResult, BadRequestError, BadRequestRequest, BadRequestResponse, CancelFlowRequest, CancelFlowResponse, ConnectionEvent, CreateUploadRequest, CreateUploadResponse, ErrorEvent, FlowEventMessage, FlowRequirementsOf, FlowServerLayerConfig, FlowSuccess, FlowsFunction, GetCapabilitiesRequest, GetCapabilitiesResponse, GetFlowRequest, GetFlowResponse, GetJobStatusRequest, GetJobStatusResponse, GetUploadRequest, GetUploadResponse, InvalidPathEvent, LayerSuccessUnion, MethodNotAllowedRequest, MethodNotAllowedResponse, NoAuthCacheServiceLive, NoAuthContextServiceLive, NotFoundError, NotFoundRequest, NotFoundResponse, PauseFlowRequest, PauseFlowResponse, PingEvent, PluginAssertion, RequiredPluginsOf, ResumeFlowRequest, ResumeFlowResponse, RunFlowRequest, RunFlowResponse, ServerAdapter, StandardRequest, StandardResponse, SubscribeFlowEvent, SubscribeUploadEvent, UnsubscribeFlowEvent, UnsubscribeUploadEvent, UnsupportedContentTypeRequest, UnsupportedContentTypeResponse, UploadChunkRequest, UploadChunkResponse, UploadEventMessage, UploadServerLayerConfig, UploadistaRequest, UploadistaResponse, UploadistaRoute, UploadistaRouteType, UploadistaServer, UploadistaServerConfig, UploadistaStandardResponse, ValidationError, type WebSocketConnection, type WebSocketConnectionRequest, WebSocketEvent, WebSocketEventType, WebSocketHandler, WebSocketIncomingEvent, WebSocketOutgoingEvent, createErrorResponseBody, createFlowServerLayer, createGenericErrorResponseBody, createUploadServerLayer, createUploadistaErrorResponseBody, createUploadistaServer, extractFlowAndStorageId, extractJobAndNodeId, extractJobIdFromStatus, getAuthCredentials, getLastSegment, getRouteSegments, handleFlowError, handleWebSocketClose, handleWebSocketError, handleWebSocketMessage, handleWebSocketOpen, hasBasePath, parseUrlSegments };
620
1343
  //# sourceMappingURL=index.d.cts.map