@uploadista/core 0.2.0 → 1.0.0-beta.3
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/dist/{checksum-BjP9nb5b.mjs → checksum-BRjFmTRk.mjs} +2 -2
- package/dist/{checksum-BjP9nb5b.mjs.map → checksum-BRjFmTRk.mjs.map} +1 -1
- package/dist/{checksum-B7RDiO7V.cjs → checksum-BrjQ8GJL.cjs} +1 -1
- package/dist/errors/index.cjs +1 -1
- package/dist/errors/index.d.cts +1 -1
- package/dist/errors/index.d.mts +1 -1
- package/dist/errors/index.mjs +1 -1
- package/dist/flow/index.cjs +1 -1
- package/dist/flow/index.d.cts +3 -2
- package/dist/flow/index.d.mts +8 -5
- package/dist/flow/index.mjs +1 -1
- package/dist/generate-id-BAMRQzMr.d.cts +34 -0
- package/dist/generate-id-BAMRQzMr.d.cts.map +1 -0
- package/dist/generate-id-DuZwLm4m.d.mts +34 -0
- package/dist/generate-id-DuZwLm4m.d.mts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +8 -5
- package/dist/index.d.mts +8 -5
- package/dist/index.mjs +1 -1
- package/dist/middleware-BghazxzH.d.cts +4129 -0
- package/dist/middleware-BghazxzH.d.cts.map +1 -0
- package/dist/middleware-CYizzAhP.d.mts +4129 -0
- package/dist/middleware-CYizzAhP.d.mts.map +1 -0
- package/dist/resolve-upload-metadata-CYl2PHIs.d.mts +4542 -0
- package/dist/resolve-upload-metadata-CYl2PHIs.d.mts.map +1 -0
- package/dist/resolve-upload-metadata-D0qFuyWc.d.cts +4542 -0
- package/dist/resolve-upload-metadata-D0qFuyWc.d.cts.map +1 -0
- package/dist/run-args-CM14Vtzu.cjs +1 -0
- package/dist/run-args-DSKHoSWs.mjs +2 -0
- package/dist/run-args-DSKHoSWs.mjs.map +1 -0
- package/dist/{stream-limiter-BCFULdAM.d.cts → stream-limiter-7wkBVLWT.d.mts} +2 -2
- package/dist/{stream-limiter-BCFULdAM.d.cts.map → stream-limiter-7wkBVLWT.d.mts.map} +1 -1
- package/dist/{stream-limiter-DZ22uIqf.cjs → stream-limiter-B-Y0DTgA.cjs} +1 -1
- package/dist/{stream-limiter-CTJPEJqE.mjs → stream-limiter-CvDuNIyd.mjs} +2 -2
- package/dist/{stream-limiter-CTJPEJqE.mjs.map → stream-limiter-CvDuNIyd.mjs.map} +1 -1
- package/dist/{stream-limiter-Bi7OTbRp.d.mts → stream-limiter-D1KC-6pK.d.cts} +2 -2
- package/dist/{stream-limiter-Bi7OTbRp.d.mts.map → stream-limiter-D1KC-6pK.d.cts.map} +1 -1
- package/dist/streams/index.cjs +1 -1
- package/dist/streams/index.d.cts +1 -1
- package/dist/streams/index.d.mts +2 -2
- package/dist/streams/index.mjs +1 -1
- package/dist/testing/index.cjs +1 -1
- package/dist/testing/index.d.cts +2 -1
- package/dist/testing/index.d.cts.map +1 -1
- package/dist/testing/index.d.mts +7 -4
- package/dist/testing/index.d.mts.map +1 -1
- package/dist/testing/index.mjs +1 -1
- package/dist/{throttle-Da0OA8JT.d.cts → throttle-3FRcr7MU.d.mts} +4 -34
- package/dist/throttle-3FRcr7MU.d.mts.map +1 -0
- package/dist/{throttle-ibiT6E4U.d.mts → throttle-BlH27EGu.d.cts} +4 -34
- package/dist/throttle-BlH27EGu.d.cts.map +1 -0
- package/dist/{throttle-KnkRgZPi.cjs → throttle-Dp59f37i.cjs} +1 -1
- package/dist/{throttle-CnDa3v1k.mjs → throttle-TFY-V41R.mjs} +2 -2
- package/dist/{throttle-CnDa3v1k.mjs.map → throttle-TFY-V41R.mjs.map} +1 -1
- package/dist/types/index.cjs +1 -1
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.mts +3 -5
- package/dist/types/index.mjs +1 -1
- package/dist/upload/index.cjs +1 -1
- package/dist/upload/index.d.cts +1 -1
- package/dist/upload/index.d.mts +4 -4
- package/dist/upload/index.mjs +1 -1
- package/dist/upload-strategy-negotiator-0-dpNIce.d.cts +455 -0
- package/dist/upload-strategy-negotiator-0-dpNIce.d.cts.map +1 -0
- package/dist/upload-strategy-negotiator-BR_o1Ez8.cjs +1 -0
- package/dist/upload-strategy-negotiator-C9MeoOnW.mjs +2 -0
- package/dist/upload-strategy-negotiator-C9MeoOnW.mjs.map +1 -0
- package/dist/upload-strategy-negotiator-CEnlfVgJ.d.mts +455 -0
- package/dist/upload-strategy-negotiator-CEnlfVgJ.d.mts.map +1 -0
- package/dist/{uploadista-error-B-geDgi8.cjs → uploadista-error-CZx1JU_L.cjs} +3 -1
- package/dist/{uploadista-error-Fsfvr2Bb.mjs → uploadista-error-DQ7V1FlX.mjs} +3 -1
- package/dist/uploadista-error-DQ7V1FlX.mjs.map +1 -0
- package/dist/{uploadista-error-BragVhIs.d.mts → uploadista-error-LtiZn-R_.d.mts} +2 -2
- package/dist/{uploadista-error-BragVhIs.d.mts.map → uploadista-error-LtiZn-R_.d.mts.map} +1 -1
- package/dist/{uploadista-error-Cj_pAFck.d.cts → uploadista-error-eZtG4iyf.d.cts} +2 -2
- package/dist/{uploadista-error-Cj_pAFck.d.cts.map → uploadista-error-eZtG4iyf.d.cts.map} +1 -1
- package/dist/utils/index.cjs +1 -1
- package/dist/utils/index.d.cts +2 -1
- package/dist/utils/index.d.mts +3 -2
- package/dist/utils/index.mjs +1 -1
- package/dist/websocket-Br0ijEZA.cjs +1 -0
- package/dist/websocket-DftnHFfN.mjs +2 -0
- package/dist/websocket-DftnHFfN.mjs.map +1 -0
- package/package.json +3 -3
- package/src/errors/uploadista-error.ts +11 -1
- package/src/flow/README.md +115 -0
- package/src/flow/flow-engine.ts +36 -2
- package/src/flow/flow-queue-store.ts +155 -0
- package/src/flow/flow-queue.ts +640 -0
- package/src/flow/index.ts +4 -0
- package/src/flow/types/flow-queue-item.ts +154 -0
- package/src/types/data-store.ts +3 -3
- package/src/types/kv-store.ts +31 -1
- package/src/upload/write-to-store.ts +24 -29
- package/tests/flow-queue-store.test.ts +150 -0
- package/tests/flow-queue.test.ts +308 -0
- package/dist/resolve-upload-metadata-BUVl1LoS.d.cts +0 -8723
- package/dist/resolve-upload-metadata-BUVl1LoS.d.cts.map +0 -1
- package/dist/resolve-upload-metadata-MPDmDfOZ.d.mts +0 -8723
- package/dist/resolve-upload-metadata-MPDmDfOZ.d.mts.map +0 -1
- package/dist/run-args-WD1otVrz.mjs +0 -2
- package/dist/run-args-WD1otVrz.mjs.map +0 -1
- package/dist/run-args-g74p8pEZ.cjs +0 -1
- package/dist/throttle-Da0OA8JT.d.cts.map +0 -1
- package/dist/throttle-ibiT6E4U.d.mts.map +0 -1
- package/dist/upload-strategy-negotiator-BuxPf1sa.mjs +0 -2
- package/dist/upload-strategy-negotiator-BuxPf1sa.mjs.map +0 -1
- package/dist/upload-strategy-negotiator-DfiQ0Fy0.cjs +0 -1
- package/dist/uploadista-error-Fsfvr2Bb.mjs.map +0 -1
- package/dist/websocket-Avz4T8YB.cjs +0 -1
- package/dist/websocket-CdgVhVJs.mjs +0 -2
- package/dist/websocket-CdgVhVJs.mjs.map +0 -1
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flow Queue Store adapter interface and in-memory default implementation.
|
|
3
|
+
*
|
|
4
|
+
* The FlowQueueStore defines the persistence contract for queue items. Any
|
|
5
|
+
* backend can be used by implementing this interface — in-memory (default),
|
|
6
|
+
* Redis, filesystem, etc.
|
|
7
|
+
*
|
|
8
|
+
* @module flow/flow-queue-store
|
|
9
|
+
* @see {@link FlowQueueService} for the queue service that uses this store
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { Effect } from "effect";
|
|
13
|
+
import { UploadistaError } from "../errors";
|
|
14
|
+
import type { FlowQueueItem, FlowQueueItemStatus } from "./types/flow-queue-item";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Adapter interface for flow queue item persistence.
|
|
18
|
+
*
|
|
19
|
+
* Implementations must provide CRUD operations for FlowQueueItems and an
|
|
20
|
+
* efficient status-based listing. Redis implementations use sorted sets and
|
|
21
|
+
* sets for O(log n) lookups; the memory implementation uses a plain Map.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // Provide a custom store via the Effect layer
|
|
26
|
+
* const customStore: FlowQueueStore = { ... };
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export interface FlowQueueStore {
|
|
30
|
+
/**
|
|
31
|
+
* Persist a new queue item.
|
|
32
|
+
*
|
|
33
|
+
* @param item - The fully-constructed FlowQueueItem to store
|
|
34
|
+
* @returns The stored item
|
|
35
|
+
*/
|
|
36
|
+
createItem(item: FlowQueueItem): Effect.Effect<FlowQueueItem, UploadistaError>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Retrieve a queue item by ID.
|
|
40
|
+
*
|
|
41
|
+
* @param id - The queue item ID
|
|
42
|
+
* @returns The item, or null if not found
|
|
43
|
+
*/
|
|
44
|
+
getItem(id: string): Effect.Effect<FlowQueueItem | null, UploadistaError>;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Apply partial updates to an existing queue item.
|
|
48
|
+
*
|
|
49
|
+
* The implementation must atomically update the item and any status-based
|
|
50
|
+
* indexes (e.g., Redis sorted sets) when status changes.
|
|
51
|
+
*
|
|
52
|
+
* @param id - The queue item ID
|
|
53
|
+
* @param updates - Fields to update (merged over the existing item)
|
|
54
|
+
* @returns The fully-updated item
|
|
55
|
+
*/
|
|
56
|
+
updateItem(
|
|
57
|
+
id: string,
|
|
58
|
+
updates: Partial<FlowQueueItem>,
|
|
59
|
+
): Effect.Effect<FlowQueueItem, UploadistaError>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* List all items with a specific status.
|
|
63
|
+
*
|
|
64
|
+
* For "pending" items, results SHOULD be returned in FIFO order (oldest first)
|
|
65
|
+
* so that the worker loop dispatches items in enqueuedAt order.
|
|
66
|
+
*
|
|
67
|
+
* @param status - The status to filter by
|
|
68
|
+
* @returns Array of matching items
|
|
69
|
+
*/
|
|
70
|
+
listByStatus(
|
|
71
|
+
status: FlowQueueItemStatus,
|
|
72
|
+
): Effect.Effect<FlowQueueItem[], UploadistaError>;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Remove a queue item from the store.
|
|
76
|
+
*
|
|
77
|
+
* @param id - The queue item ID to remove
|
|
78
|
+
*/
|
|
79
|
+
deleteItem(id: string): Effect.Effect<void, UploadistaError>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* In-memory implementation of FlowQueueStore.
|
|
84
|
+
*
|
|
85
|
+
* Uses a plain Map for storage. Items are not persisted across process restarts.
|
|
86
|
+
* Suitable for single-process deployments or development/testing.
|
|
87
|
+
*
|
|
88
|
+
* For durability across restarts, use RedisFlowQueueStore or IoRedisFlowQueueStore.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const store = new MemoryFlowQueueStore();
|
|
93
|
+
* // Pass to FlowQueueService.make(config, store)
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export class MemoryFlowQueueStore implements FlowQueueStore {
|
|
97
|
+
private readonly items = new Map<string, FlowQueueItem>();
|
|
98
|
+
|
|
99
|
+
createItem(item: FlowQueueItem): Effect.Effect<FlowQueueItem, UploadistaError> {
|
|
100
|
+
return Effect.sync(() => {
|
|
101
|
+
this.items.set(item.id, { ...item });
|
|
102
|
+
return item;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
getItem(id: string): Effect.Effect<FlowQueueItem | null, UploadistaError> {
|
|
107
|
+
return Effect.sync(() => {
|
|
108
|
+
return this.items.get(id) ?? null;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
updateItem(
|
|
113
|
+
id: string,
|
|
114
|
+
updates: Partial<FlowQueueItem>,
|
|
115
|
+
): Effect.Effect<FlowQueueItem, UploadistaError> {
|
|
116
|
+
const self = this;
|
|
117
|
+
return Effect.suspend(() => {
|
|
118
|
+
const existing = self.items.get(id);
|
|
119
|
+
if (!existing) {
|
|
120
|
+
return Effect.fail(
|
|
121
|
+
UploadistaError.fromCode("FLOW_JOB_NOT_FOUND", {
|
|
122
|
+
body: `Queue item ${id} not found`,
|
|
123
|
+
}),
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
const updated: FlowQueueItem = { ...existing, ...updates };
|
|
127
|
+
self.items.set(id, updated);
|
|
128
|
+
return Effect.succeed(updated);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
listByStatus(
|
|
133
|
+
status: FlowQueueItemStatus,
|
|
134
|
+
): Effect.Effect<FlowQueueItem[], UploadistaError> {
|
|
135
|
+
return Effect.sync(() => {
|
|
136
|
+
const result: FlowQueueItem[] = [];
|
|
137
|
+
for (const item of this.items.values()) {
|
|
138
|
+
if (item.status === status) {
|
|
139
|
+
result.push({ ...item });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Return in FIFO order for pending items
|
|
143
|
+
if (status === "pending") {
|
|
144
|
+
result.sort((a, b) => a.enqueuedAt.getTime() - b.enqueuedAt.getTime());
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
deleteItem(id: string): Effect.Effect<void, UploadistaError> {
|
|
151
|
+
return Effect.sync(() => {
|
|
152
|
+
this.items.delete(id);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|