@uploadista/server 0.0.20-beta.6 → 0.0.20-beta.8
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 +16 -16
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +188 -188
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +188 -188
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -12
- package/src/adapter/types.ts +3 -3
- package/src/core/http-handlers/flow-http-handlers.ts +14 -14
- package/src/core/http-handlers/upload-http-handlers.ts +16 -9
- package/src/core/plugin-types.ts +10 -10
- package/src/core/routes.ts +4 -1
- package/src/core/server.ts +7 -9
- package/src/core/websocket-handlers/flow-websocket-handlers.ts +5 -5
- package/src/core/websocket-handlers/upload-websocket-handlers.ts +5 -5
- package/src/core/websocket-handlers/websocket-handlers.ts +10 -10
- package/src/error-types.ts +1 -1
- package/src/layer-utils.ts +24 -24
- package/src/permissions/errors.ts +3 -1
- package/src/permissions/index.ts +2 -2
- package/src/permissions/types.ts +3 -12
- package/src/plugins-typing.ts +15 -13
- package/src/service.ts +9 -4
- package/src/usage-hooks/index.ts +1 -1
- package/src/usage-hooks/service.ts +51 -59
- package/src/usage-hooks/types.ts +2 -4
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uploadista/server",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.20-beta.
|
|
4
|
+
"version": "0.0.20-beta.8",
|
|
5
5
|
"description": "Core Server package for Uploadista",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Uploadista",
|
|
@@ -20,23 +20,23 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@uploadista/core": "0.0.20-beta.
|
|
24
|
-
"@uploadista/
|
|
25
|
-
"@uploadista/
|
|
26
|
-
"@uploadista/event-
|
|
23
|
+
"@uploadista/core": "0.0.20-beta.8",
|
|
24
|
+
"@uploadista/observability": "0.0.20-beta.8",
|
|
25
|
+
"@uploadista/event-broadcaster-memory": "0.0.20-beta.8",
|
|
26
|
+
"@uploadista/event-emitter-websocket": "0.0.20-beta.8"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@cloudflare/workers-types": "4.
|
|
29
|
+
"@cloudflare/workers-types": "4.20251213.0",
|
|
30
30
|
"@effect/vitest": "0.27.0",
|
|
31
31
|
"@types/express": "^5.0.0",
|
|
32
|
-
"@types/node": "24.10.
|
|
33
|
-
"effect": "3.19.
|
|
32
|
+
"@types/node": "24.10.4",
|
|
33
|
+
"effect": "3.19.12",
|
|
34
34
|
"tsd": "0.33.0",
|
|
35
|
-
"tsdown": "0.
|
|
35
|
+
"tsdown": "0.18.0",
|
|
36
36
|
"typescript": "5.9.3",
|
|
37
37
|
"vitest": "4.0.15",
|
|
38
|
-
"zod": "4.
|
|
39
|
-
"@uploadista/typescript-config": "0.0.20-beta.
|
|
38
|
+
"zod": "4.2.0",
|
|
39
|
+
"@uploadista/typescript-config": "0.0.20-beta.8"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"effect": "^3.0.0",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"zod": "^4.0.0"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
|
-
"build": "tsdown",
|
|
48
|
+
"build": "tsc --noEmit && tsdown",
|
|
49
49
|
"format": "biome format --write ./src",
|
|
50
50
|
"lint": "biome lint --write ./src",
|
|
51
51
|
"check": "biome check --write ./src",
|
package/src/adapter/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FlowEngine, UploadEngine } from "@uploadista/core";
|
|
2
2
|
import type { Effect } from "effect";
|
|
3
3
|
import type { UploadistaRequest, UploadistaResponse } from "../core/routes";
|
|
4
4
|
import type { AuthResult } from "../types";
|
|
@@ -200,12 +200,12 @@ export interface ServerAdapter<
|
|
|
200
200
|
*
|
|
201
201
|
* @param ws - Framework-specific WebSocket object
|
|
202
202
|
* @param ctx - Framework-specific context object (for initial handshake)
|
|
203
|
-
* @param context - Server context with baseUrl,
|
|
203
|
+
* @param context - Server context with baseUrl, uploadEngine, and flowServer
|
|
204
204
|
* @returns WebSocketHandler with callbacks for message, close, and error events
|
|
205
205
|
*/
|
|
206
206
|
webSocketHandler(context: {
|
|
207
207
|
baseUrl: string;
|
|
208
|
-
}): Effect.Effect<TWebSocketHandler, never,
|
|
208
|
+
}): Effect.Effect<TWebSocketHandler, never, UploadEngine | FlowEngine>;
|
|
209
209
|
|
|
210
210
|
/**
|
|
211
211
|
* Optional: Extract waitUntil callback from the framework context.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FlowEngine } from "@uploadista/core/flow";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
import { AuthCacheService } from "../../cache";
|
|
4
|
-
import { PERMISSIONS } from "../../permissions/types";
|
|
5
4
|
import { QuotaExceededError } from "../../permissions/errors";
|
|
5
|
+
import { PERMISSIONS } from "../../permissions/types";
|
|
6
6
|
import { AuthContextService } from "../../service";
|
|
7
7
|
import { UsageHookService } from "../../usage-hooks/service";
|
|
8
8
|
import type {
|
|
@@ -22,7 +22,7 @@ import type {
|
|
|
22
22
|
|
|
23
23
|
export const handleGetFlow = ({ flowId }: GetFlowRequest) => {
|
|
24
24
|
return Effect.gen(function* () {
|
|
25
|
-
const
|
|
25
|
+
const flowEngine = yield* FlowEngine;
|
|
26
26
|
const authService = yield* AuthContextService;
|
|
27
27
|
const clientId = yield* authService.getClientId();
|
|
28
28
|
|
|
@@ -35,7 +35,7 @@ export const handleGetFlow = ({ flowId }: GetFlowRequest) => {
|
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const flowData = yield*
|
|
38
|
+
const flowData = yield* flowEngine.getFlowData(flowId, clientId);
|
|
39
39
|
|
|
40
40
|
return {
|
|
41
41
|
status: 200,
|
|
@@ -50,7 +50,7 @@ export const handleRunFlow = <TRequirements>({
|
|
|
50
50
|
inputs,
|
|
51
51
|
}: RunFlowRequest) => {
|
|
52
52
|
return Effect.gen(function* () {
|
|
53
|
-
const
|
|
53
|
+
const flowEngine = yield* FlowEngine;
|
|
54
54
|
const authService = yield* AuthContextService;
|
|
55
55
|
const authCache = yield* AuthCacheService;
|
|
56
56
|
const usageHookService = yield* UsageHookService;
|
|
@@ -96,7 +96,7 @@ export const handleRunFlow = <TRequirements>({
|
|
|
96
96
|
// Run flow returns immediately with jobId
|
|
97
97
|
const startTime = Date.now();
|
|
98
98
|
yield* Effect.logInfo(`[Flow] Calling flowServer.runFlow...`);
|
|
99
|
-
const result = yield*
|
|
99
|
+
const result = yield* flowEngine
|
|
100
100
|
.runFlow<TRequirements>({
|
|
101
101
|
flowId,
|
|
102
102
|
storageId,
|
|
@@ -133,7 +133,7 @@ export const handleRunFlow = <TRequirements>({
|
|
|
133
133
|
|
|
134
134
|
export const handleJobStatus = ({ jobId }: GetJobStatusRequest) => {
|
|
135
135
|
return Effect.gen(function* () {
|
|
136
|
-
const
|
|
136
|
+
const flowEngine = yield* FlowEngine;
|
|
137
137
|
const authService = yield* AuthContextService;
|
|
138
138
|
const authCache = yield* AuthCacheService;
|
|
139
139
|
const clientId = yield* authService.getClientId();
|
|
@@ -151,7 +151,7 @@ export const handleJobStatus = ({ jobId }: GetJobStatusRequest) => {
|
|
|
151
151
|
);
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
const result = yield*
|
|
154
|
+
const result = yield* flowEngine.getJobStatus(jobId);
|
|
155
155
|
|
|
156
156
|
// Clear cache if flow is completed or failed
|
|
157
157
|
if (result.status === "completed" || result.status === "failed") {
|
|
@@ -176,7 +176,7 @@ export const handleResumeFlow = <TRequirements>({
|
|
|
176
176
|
newData,
|
|
177
177
|
}: ResumeFlowRequest) => {
|
|
178
178
|
return Effect.gen(function* () {
|
|
179
|
-
const
|
|
179
|
+
const flowEngine = yield* FlowEngine;
|
|
180
180
|
const authService = yield* AuthContextService;
|
|
181
181
|
const authCache = yield* AuthCacheService;
|
|
182
182
|
|
|
@@ -200,7 +200,7 @@ export const handleResumeFlow = <TRequirements>({
|
|
|
200
200
|
throw new Error("Missing newData");
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
const result = yield*
|
|
203
|
+
const result = yield* flowEngine.resumeFlow<TRequirements>({
|
|
204
204
|
jobId,
|
|
205
205
|
nodeId,
|
|
206
206
|
newData,
|
|
@@ -226,7 +226,7 @@ export const handleResumeFlow = <TRequirements>({
|
|
|
226
226
|
|
|
227
227
|
export const handlePauseFlow = ({ jobId }: PauseFlowRequest) => {
|
|
228
228
|
return Effect.gen(function* () {
|
|
229
|
-
const
|
|
229
|
+
const flowEngine = yield* FlowEngine;
|
|
230
230
|
const authService = yield* AuthContextService;
|
|
231
231
|
const authCache = yield* AuthCacheService;
|
|
232
232
|
|
|
@@ -246,7 +246,7 @@ export const handlePauseFlow = ({ jobId }: PauseFlowRequest) => {
|
|
|
246
246
|
);
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
const result = yield*
|
|
249
|
+
const result = yield* flowEngine.pauseFlow(jobId, clientId);
|
|
250
250
|
|
|
251
251
|
if (clientId) {
|
|
252
252
|
yield* Effect.logInfo(
|
|
@@ -263,7 +263,7 @@ export const handlePauseFlow = ({ jobId }: PauseFlowRequest) => {
|
|
|
263
263
|
|
|
264
264
|
export const handleCancelFlow = ({ jobId }: CancelFlowRequest) => {
|
|
265
265
|
return Effect.gen(function* () {
|
|
266
|
-
const
|
|
266
|
+
const flowEngine = yield* FlowEngine;
|
|
267
267
|
const authService = yield* AuthContextService;
|
|
268
268
|
const authCache = yield* AuthCacheService;
|
|
269
269
|
const usageHookService = yield* UsageHookService;
|
|
@@ -288,7 +288,7 @@ export const handleCancelFlow = ({ jobId }: CancelFlowRequest) => {
|
|
|
288
288
|
);
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
const result = yield*
|
|
291
|
+
const result = yield* flowEngine.cancelFlow(jobId, clientId);
|
|
292
292
|
|
|
293
293
|
// Clear cache since flow is cancelled
|
|
294
294
|
yield* authCache.delete(jobId);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { inputFileSchema } from "@uploadista/core/types";
|
|
2
|
-
import {
|
|
2
|
+
import { UploadEngine } from "@uploadista/core/upload";
|
|
3
3
|
import { isSupportedAlgorithm } from "@uploadista/core/utils";
|
|
4
4
|
import { MetricsService } from "@uploadista/observability";
|
|
5
5
|
import { Effect } from "effect";
|
|
@@ -22,7 +22,7 @@ import type {
|
|
|
22
22
|
|
|
23
23
|
export const handleCreateUpload = (req: CreateUploadRequest) =>
|
|
24
24
|
Effect.gen(function* () {
|
|
25
|
-
const
|
|
25
|
+
const uploadEngine = yield* UploadEngine;
|
|
26
26
|
const authService = yield* AuthContextService;
|
|
27
27
|
const authCache = yield* AuthCacheService;
|
|
28
28
|
const usageHookService = yield* UsageHookService;
|
|
@@ -79,7 +79,7 @@ export const handleCreateUpload = (req: CreateUploadRequest) =>
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
const fileCreated = yield*
|
|
82
|
+
const fileCreated = yield* uploadEngine.createUpload(
|
|
83
83
|
parsedInputFile.data,
|
|
84
84
|
clientId,
|
|
85
85
|
);
|
|
@@ -104,14 +104,17 @@ export const handleCreateUpload = (req: CreateUploadRequest) =>
|
|
|
104
104
|
|
|
105
105
|
export const handleGetCapabilities = ({ storageId }: GetCapabilitiesRequest) =>
|
|
106
106
|
Effect.gen(function* () {
|
|
107
|
-
const
|
|
107
|
+
const uploadEngine = yield* UploadEngine;
|
|
108
108
|
const authService = yield* AuthContextService;
|
|
109
109
|
const clientId = yield* authService.getClientId();
|
|
110
110
|
|
|
111
111
|
// Check permission for reading upload capabilities
|
|
112
112
|
yield* authService.requirePermission(PERMISSIONS.UPLOAD.READ);
|
|
113
113
|
|
|
114
|
-
const capabilities = yield*
|
|
114
|
+
const capabilities = yield* uploadEngine.getCapabilities(
|
|
115
|
+
storageId,
|
|
116
|
+
clientId,
|
|
117
|
+
);
|
|
115
118
|
|
|
116
119
|
return {
|
|
117
120
|
status: 200,
|
|
@@ -125,13 +128,13 @@ export const handleGetCapabilities = ({ storageId }: GetCapabilitiesRequest) =>
|
|
|
125
128
|
|
|
126
129
|
export const handleGetUpload = ({ uploadId }: GetUploadRequest) =>
|
|
127
130
|
Effect.gen(function* () {
|
|
128
|
-
const
|
|
131
|
+
const uploadEngine = yield* UploadEngine;
|
|
129
132
|
const authService = yield* AuthContextService;
|
|
130
133
|
|
|
131
134
|
// Check permission for reading upload status
|
|
132
135
|
yield* authService.requirePermission(PERMISSIONS.UPLOAD.READ);
|
|
133
136
|
|
|
134
|
-
const fileResult = yield*
|
|
137
|
+
const fileResult = yield* uploadEngine.getUpload(uploadId);
|
|
135
138
|
|
|
136
139
|
return {
|
|
137
140
|
status: 200,
|
|
@@ -141,7 +144,7 @@ export const handleGetUpload = ({ uploadId }: GetUploadRequest) =>
|
|
|
141
144
|
|
|
142
145
|
export const handleUploadChunk = (req: UploadChunkRequest) =>
|
|
143
146
|
Effect.gen(function* () {
|
|
144
|
-
const
|
|
147
|
+
const uploadEngine = yield* UploadEngine;
|
|
145
148
|
const authService = yield* AuthContextService;
|
|
146
149
|
const authCache = yield* AuthCacheService;
|
|
147
150
|
const metricsService = yield* MetricsService;
|
|
@@ -168,7 +171,11 @@ export const handleUploadChunk = (req: UploadChunkRequest) =>
|
|
|
168
171
|
}
|
|
169
172
|
|
|
170
173
|
const startTime = Date.now();
|
|
171
|
-
const fileResult = yield*
|
|
174
|
+
const fileResult = yield* uploadEngine.uploadChunk(
|
|
175
|
+
uploadId,
|
|
176
|
+
clientId,
|
|
177
|
+
data,
|
|
178
|
+
);
|
|
172
179
|
|
|
173
180
|
// Clear cache and record metrics if upload is complete
|
|
174
181
|
if (fileResult.size && fileResult.offset >= fileResult.size) {
|
package/src/core/plugin-types.ts
CHANGED
|
@@ -166,7 +166,7 @@ export type TypeSafePluginConfig<
|
|
|
166
166
|
* Extracts plugin requirements from a flow function type.
|
|
167
167
|
*
|
|
168
168
|
* This navigates through the flow function signature to extract the requirements
|
|
169
|
-
* from the Flow type it returns, excluding
|
|
169
|
+
* from the Flow type it returns, excluding UploadEngine (provided by runtime).
|
|
170
170
|
*
|
|
171
171
|
* @template TFlowFn - The flow function type to extract requirements from
|
|
172
172
|
*
|
|
@@ -187,12 +187,13 @@ export type ExtractFlowPluginRequirements<
|
|
|
187
187
|
clientId: string | null,
|
|
188
188
|
) => Effect.Effect<unknown, unknown, unknown>,
|
|
189
189
|
// biome-ignore lint/suspicious/noExplicitAny: Conditional type inference requires any for error and requirements parameters
|
|
190
|
-
> =
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
190
|
+
> =
|
|
191
|
+
ReturnType<TFlowFn> extends Effect.Effect<infer TFlow, any, any>
|
|
192
|
+
? // biome-ignore lint/suspicious/noExplicitAny: Conditional type inference requires any for input and output schema parameters
|
|
193
|
+
TFlow extends Flow<any, any, infer TRequirements>
|
|
194
|
+
? Exclude<TRequirements, never> // Exclude UploadEngine is handled by FlowPluginRequirements in core
|
|
195
|
+
: never
|
|
196
|
+
: never;
|
|
196
197
|
|
|
197
198
|
/**
|
|
198
199
|
* Helper type to infer plugin requirements from a flow function.
|
|
@@ -204,9 +205,8 @@ export type ExtractFlowPluginRequirements<
|
|
|
204
205
|
* // Requirements = ImagePlugin | ZipPlugin
|
|
205
206
|
* ```
|
|
206
207
|
*/
|
|
207
|
-
export type InferFlowRequirements<T> =
|
|
208
|
-
? R
|
|
209
|
-
: never;
|
|
208
|
+
export type InferFlowRequirements<T> =
|
|
209
|
+
T extends TypeSafeFlowFunction<infer R> ? R : never;
|
|
210
210
|
|
|
211
211
|
/**
|
|
212
212
|
* Converts PluginLayer types to Layer.Layer<any, never, any> for runtime use.
|
package/src/core/routes.ts
CHANGED
|
@@ -190,7 +190,10 @@ export type DlqListResponse = UploadistaStandardResponse<
|
|
|
190
190
|
export type DlqGetRequest = UploadistaRoute<"dlq-get"> & {
|
|
191
191
|
itemId: string;
|
|
192
192
|
};
|
|
193
|
-
export type DlqGetResponse = UploadistaStandardResponse<
|
|
193
|
+
export type DlqGetResponse = UploadistaStandardResponse<
|
|
194
|
+
"dlq-get",
|
|
195
|
+
DeadLetterItem
|
|
196
|
+
>;
|
|
194
197
|
|
|
195
198
|
export type DlqRetryRequest = UploadistaRoute<"dlq-retry"> & {
|
|
196
199
|
itemId: string;
|
package/src/core/server.ts
CHANGED
|
@@ -21,7 +21,7 @@ import type { z } from "zod";
|
|
|
21
21
|
import type { StandardResponse } from "../adapter";
|
|
22
22
|
import { AuthCacheServiceLive } from "../cache";
|
|
23
23
|
import { handleFlowError } from "../http-utils";
|
|
24
|
-
import {
|
|
24
|
+
import { createFlowEngineLayer, createUploadEngineLayer } from "../layer-utils";
|
|
25
25
|
import { AuthContextServiceLive } from "../service";
|
|
26
26
|
import type { AuthContext } from "../types";
|
|
27
27
|
import { UsageHookServiceLive } from "../usage-hooks/service";
|
|
@@ -252,7 +252,7 @@ export const createUploadistaServer = async <
|
|
|
252
252
|
> = await createDataStoreLayer(dataStore);
|
|
253
253
|
|
|
254
254
|
// Create upload server layer
|
|
255
|
-
const
|
|
255
|
+
const uploadEngineLayer = createUploadEngineLayer({
|
|
256
256
|
kvStore,
|
|
257
257
|
eventEmitter: finalEventEmitter,
|
|
258
258
|
dataStore: dataStoreLayer,
|
|
@@ -261,11 +261,11 @@ export const createUploadistaServer = async <
|
|
|
261
261
|
});
|
|
262
262
|
|
|
263
263
|
// Create flow server layer
|
|
264
|
-
const
|
|
264
|
+
const flowEngineLayer = createFlowEngineLayer({
|
|
265
265
|
kvStore,
|
|
266
266
|
eventEmitter: finalEventEmitter,
|
|
267
267
|
flowProvider: flowProviderLayer,
|
|
268
|
-
|
|
268
|
+
uploadEngine: uploadEngineLayer,
|
|
269
269
|
});
|
|
270
270
|
|
|
271
271
|
// Create auth cache layer (always present, even if auth is not enabled)
|
|
@@ -299,8 +299,8 @@ export const createUploadistaServer = async <
|
|
|
299
299
|
* with user-provided plugin layers.
|
|
300
300
|
*/
|
|
301
301
|
const serverLayerRaw = Layer.mergeAll(
|
|
302
|
-
|
|
303
|
-
|
|
302
|
+
uploadEngineLayer,
|
|
303
|
+
flowEngineLayer,
|
|
304
304
|
effectiveMetricsLayer,
|
|
305
305
|
authCacheLayer,
|
|
306
306
|
usageHookLayer,
|
|
@@ -314,9 +314,7 @@ export const createUploadistaServer = async <
|
|
|
314
314
|
* This must be included in the runtime layer (not per-request) so that the
|
|
315
315
|
* BatchSpanProcessor can aggregate spans across requests and flush them properly.
|
|
316
316
|
*/
|
|
317
|
-
const tracingLayer = withTracing
|
|
318
|
-
? observabilityLayer ?? NodeSdkLive
|
|
319
|
-
: null;
|
|
317
|
+
const tracingLayer = withTracing ? (observabilityLayer ?? NodeSdkLive) : null;
|
|
320
318
|
|
|
321
319
|
/**
|
|
322
320
|
* Type Casting Rationale for Plugin System
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FlowEngineShape } from "@uploadista/core/flow";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
import type { WebSocketConnection } from "../websocket-routes";
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ import type { WebSocketConnection } from "../websocket-routes";
|
|
|
7
7
|
* Subscribes the WebSocket connection to receive real-time flow execution events
|
|
8
8
|
*/
|
|
9
9
|
export const handleSubscribeToFlowEvents = (
|
|
10
|
-
|
|
10
|
+
flowEngine: FlowEngineShape,
|
|
11
11
|
jobId: string | undefined,
|
|
12
12
|
connection: WebSocketConnection,
|
|
13
13
|
) => {
|
|
@@ -25,7 +25,7 @@ export const handleSubscribeToFlowEvents = (
|
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
yield*
|
|
28
|
+
yield* flowEngine.subscribeToFlowEvents(jobId, connection);
|
|
29
29
|
});
|
|
30
30
|
};
|
|
31
31
|
|
|
@@ -34,7 +34,7 @@ export const handleSubscribeToFlowEvents = (
|
|
|
34
34
|
* Removes the WebSocket connection from receiving flow events
|
|
35
35
|
*/
|
|
36
36
|
export const handleUnsubscribeFromFlowEvents = (
|
|
37
|
-
|
|
37
|
+
flowEngine: FlowEngineShape,
|
|
38
38
|
jobId: string | undefined,
|
|
39
39
|
) => {
|
|
40
40
|
return Effect.gen(function* () {
|
|
@@ -42,6 +42,6 @@ export const handleUnsubscribeFromFlowEvents = (
|
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
yield*
|
|
45
|
+
yield* flowEngine.unsubscribeFromFlowEvents(jobId);
|
|
46
46
|
});
|
|
47
47
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UploadEngineShape } from "@uploadista/core/upload";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
import type { WebSocketConnection } from "../websocket-routes";
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ import type { WebSocketConnection } from "../websocket-routes";
|
|
|
7
7
|
* Subscribes the WebSocket connection to receive real-time upload progress events
|
|
8
8
|
*/
|
|
9
9
|
export const handleSubscribeToUploadEvents = (
|
|
10
|
-
|
|
10
|
+
uploadEngine: UploadEngineShape,
|
|
11
11
|
uploadId: string | undefined,
|
|
12
12
|
connection: WebSocketConnection,
|
|
13
13
|
) => {
|
|
@@ -25,7 +25,7 @@ export const handleSubscribeToUploadEvents = (
|
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
yield*
|
|
28
|
+
yield* uploadEngine.subscribeToUploadEvents(uploadId, connection);
|
|
29
29
|
});
|
|
30
30
|
};
|
|
31
31
|
|
|
@@ -34,7 +34,7 @@ export const handleSubscribeToUploadEvents = (
|
|
|
34
34
|
* Removes the WebSocket connection from receiving upload events
|
|
35
35
|
*/
|
|
36
36
|
export const handleUnsubscribeFromUploadEvents = (
|
|
37
|
-
|
|
37
|
+
uploadEngine: UploadEngineShape,
|
|
38
38
|
uploadId: string | undefined,
|
|
39
39
|
) => {
|
|
40
40
|
return Effect.gen(function* () {
|
|
@@ -42,6 +42,6 @@ export const handleUnsubscribeFromUploadEvents = (
|
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
yield*
|
|
45
|
+
yield* uploadEngine.unsubscribeFromUploadEvents(uploadId);
|
|
46
46
|
});
|
|
47
47
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UploadistaError } from "@uploadista/core/errors";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { FlowEngineShape } from "@uploadista/core/flow";
|
|
3
|
+
import type { UploadEngineShape } from "@uploadista/core/upload";
|
|
4
4
|
import { Effect } from "effect";
|
|
5
5
|
import type {
|
|
6
6
|
WebSocketConnection,
|
|
@@ -26,8 +26,8 @@ export type {
|
|
|
26
26
|
*/
|
|
27
27
|
export const handleWebSocketOpen = (
|
|
28
28
|
request: WebSocketConnectionRequest,
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
uploadEngine: UploadEngineShape,
|
|
30
|
+
flowEngine: FlowEngineShape,
|
|
31
31
|
) => {
|
|
32
32
|
const { connection, isFlowRoute, isUploadRoute, jobId, uploadId, eventId } =
|
|
33
33
|
request;
|
|
@@ -35,12 +35,12 @@ export const handleWebSocketOpen = (
|
|
|
35
35
|
return Effect.gen(function* () {
|
|
36
36
|
// Subscribe to flow events if this is a flow route
|
|
37
37
|
if (isFlowRoute) {
|
|
38
|
-
yield* handleSubscribeToFlowEvents(
|
|
38
|
+
yield* handleSubscribeToFlowEvents(flowEngine, jobId, connection);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// Subscribe to upload events if this is an upload route
|
|
42
42
|
if (isUploadRoute) {
|
|
43
|
-
yield* handleSubscribeToUploadEvents(
|
|
43
|
+
yield* handleSubscribeToUploadEvents(uploadEngine, uploadId, connection);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
// Send connection confirmation
|
|
@@ -114,20 +114,20 @@ export const handleWebSocketMessage = (
|
|
|
114
114
|
*/
|
|
115
115
|
export const handleWebSocketClose = (
|
|
116
116
|
request: WebSocketConnectionRequest,
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
uploadEngine: UploadEngineShape,
|
|
118
|
+
flowEngine: FlowEngineShape,
|
|
119
119
|
) => {
|
|
120
120
|
const { isFlowRoute, isUploadRoute, jobId, uploadId } = request;
|
|
121
121
|
|
|
122
122
|
return Effect.gen(function* () {
|
|
123
123
|
// Unsubscribe from flow events if this was a flow route
|
|
124
124
|
if (isFlowRoute) {
|
|
125
|
-
yield* handleUnsubscribeFromFlowEvents(
|
|
125
|
+
yield* handleUnsubscribeFromFlowEvents(flowEngine, jobId);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
// Unsubscribe from upload events if this was an upload route
|
|
129
129
|
if (isUploadRoute) {
|
|
130
|
-
yield* handleUnsubscribeFromUploadEvents(
|
|
130
|
+
yield* handleUnsubscribeFromUploadEvents(uploadEngine, uploadId);
|
|
131
131
|
}
|
|
132
132
|
}).pipe(
|
|
133
133
|
Effect.catchAll((error) =>
|
package/src/error-types.ts
CHANGED
|
@@ -114,7 +114,7 @@ export const createErrorResponseBody = (error: AdapterError) => ({
|
|
|
114
114
|
* import { createUploadistaErrorResponseBody } from "@uploadista/server";
|
|
115
115
|
*
|
|
116
116
|
* try {
|
|
117
|
-
* const result = yield*
|
|
117
|
+
* const result = yield* uploadEngine.handleUpload(input);
|
|
118
118
|
* } catch (err) {
|
|
119
119
|
* if (err instanceof UploadistaError) {
|
|
120
120
|
* const errorResponse = createUploadistaErrorResponseBody(err);
|