@uploadista/core 0.0.17 → 0.0.18-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.
Files changed (117) hide show
  1. package/README.md +102 -0
  2. package/dist/{checksum-DaCqP8Qa.mjs → checksum-COoD-F1l.mjs} +2 -2
  3. package/dist/{checksum-DaCqP8Qa.mjs.map → checksum-COoD-F1l.mjs.map} +1 -1
  4. package/dist/{checksum-BIlVW8bD.cjs → checksum-YLW4hVY7.cjs} +1 -1
  5. package/dist/errors/index.cjs +1 -1
  6. package/dist/errors/index.d.cts +1 -1
  7. package/dist/errors/index.d.mts +1 -1
  8. package/dist/errors/index.mjs +1 -1
  9. package/dist/flow/index.cjs +1 -1
  10. package/dist/flow/index.d.cts +5 -5
  11. package/dist/flow/index.d.mts +5 -5
  12. package/dist/flow/index.mjs +1 -1
  13. package/dist/flow-BLGpxdEm.mjs +2 -0
  14. package/dist/flow-BLGpxdEm.mjs.map +1 -0
  15. package/dist/flow-DaBzRGmY.cjs +1 -0
  16. package/dist/{index-BGi1r_fi.d.mts → index-9gyMMEIB.d.cts} +2 -2
  17. package/dist/{index-BGi1r_fi.d.mts.map → index-9gyMMEIB.d.cts.map} +1 -1
  18. package/dist/{index-B_SvQ0MU.d.cts → index-B9V5SSxl.d.mts} +2 -2
  19. package/dist/{index-B_SvQ0MU.d.cts.map → index-B9V5SSxl.d.mts.map} +1 -1
  20. package/dist/{index-DIWuZlxd.d.mts → index-BFSHumky.d.mts} +2 -2
  21. package/dist/{index-DIWuZlxd.d.mts.map → index-BFSHumky.d.mts.map} +1 -1
  22. package/dist/{index-BQ5luyME.d.cts → index-D7i4bgl3.d.mts} +2747 -828
  23. package/dist/index-D7i4bgl3.d.mts.map +1 -0
  24. package/dist/{index-qIN6ULCb.d.cts → index-DFbu_-zn.d.cts} +2 -2
  25. package/dist/{index-qIN6ULCb.d.cts.map → index-DFbu_-zn.d.cts.map} +1 -1
  26. package/dist/{index-BtnCNLsH.d.mts → index-fF-j_WhY.d.cts} +2747 -828
  27. package/dist/index-fF-j_WhY.d.cts.map +1 -0
  28. package/dist/index.cjs +1 -1
  29. package/dist/index.d.cts +5 -5
  30. package/dist/index.d.mts +5 -5
  31. package/dist/index.mjs +1 -1
  32. package/dist/{stream-limiter-D2Y8Z_Kv.mjs → stream-limiter-B9nsn2gb.mjs} +2 -2
  33. package/dist/{stream-limiter-D2Y8Z_Kv.mjs.map → stream-limiter-B9nsn2gb.mjs.map} +1 -1
  34. package/dist/{stream-limiter-By0fxkAh.cjs → stream-limiter-DyWOdil4.cjs} +1 -1
  35. package/dist/streams/index.cjs +1 -1
  36. package/dist/streams/index.d.cts +2 -2
  37. package/dist/streams/index.d.mts +2 -2
  38. package/dist/streams/index.mjs +1 -1
  39. package/dist/testing/index.cjs +1 -1
  40. package/dist/testing/index.d.cts +4 -4
  41. package/dist/testing/index.d.mts +4 -4
  42. package/dist/testing/index.mjs +1 -1
  43. package/dist/types/index.cjs +1 -1
  44. package/dist/types/index.d.cts +5 -5
  45. package/dist/types/index.d.mts +5 -5
  46. package/dist/types/index.mjs +1 -1
  47. package/dist/types-CH0BgiJN.mjs +2 -0
  48. package/dist/types-CH0BgiJN.mjs.map +1 -0
  49. package/dist/types-DUYVoR13.cjs +1 -0
  50. package/dist/upload/index.cjs +1 -1
  51. package/dist/upload/index.d.cts +4 -4
  52. package/dist/upload/index.d.mts +4 -4
  53. package/dist/upload/index.mjs +1 -1
  54. package/dist/{upload-bBgM3QFI.cjs → upload-CFT-dWPB.cjs} +1 -1
  55. package/dist/{upload-Bq9h95w6.mjs → upload-ggK-0ZBM.mjs} +2 -2
  56. package/dist/{upload-Bq9h95w6.mjs.map → upload-ggK-0ZBM.mjs.map} +1 -1
  57. package/dist/{uploadista-error-DCRIscEv.cjs → uploadista-error-BxBLmQtX.cjs} +4 -1
  58. package/dist/{uploadista-error-Bb-qIIKM.d.cts → uploadista-error-CYCmAtkZ.d.cts} +2 -2
  59. package/dist/uploadista-error-CYCmAtkZ.d.cts.map +1 -0
  60. package/dist/{uploadista-error-djFxVTLh.mjs → uploadista-error-CkSxSyNo.mjs} +4 -1
  61. package/dist/uploadista-error-CkSxSyNo.mjs.map +1 -0
  62. package/dist/{uploadista-error-D7Gubrr1.d.mts → uploadista-error-DR0XimpE.d.mts} +2 -2
  63. package/dist/uploadista-error-DR0XimpE.d.mts.map +1 -0
  64. package/dist/utils/index.cjs +1 -1
  65. package/dist/utils/index.d.cts +2 -2
  66. package/dist/utils/index.d.mts +2 -2
  67. package/dist/utils/index.mjs +1 -1
  68. package/dist/{utils-MQUZyB9S.mjs → utils-B-ZhQ6b0.mjs} +2 -2
  69. package/dist/{utils-MQUZyB9S.mjs.map → utils-B-ZhQ6b0.mjs.map} +1 -1
  70. package/dist/{utils-DxLVhlLd.cjs → utils-Dhq3vPqp.cjs} +1 -1
  71. package/docs/CIRCUIT_BREAKER.md +381 -0
  72. package/docs/DEAD-LETTER-QUEUE.md +374 -0
  73. package/package.json +11 -6
  74. package/src/errors/uploadista-error.ts +16 -1
  75. package/src/flow/README.md +102 -0
  76. package/src/flow/circuit-breaker-store.ts +382 -0
  77. package/src/flow/circuit-breaker.ts +99 -0
  78. package/src/flow/dead-letter-queue.ts +573 -0
  79. package/src/flow/distributed-circuit-breaker.ts +437 -0
  80. package/src/flow/event.ts +105 -1
  81. package/src/flow/flow-server.ts +70 -0
  82. package/src/flow/flow.ts +141 -3
  83. package/src/flow/index.ts +14 -2
  84. package/src/flow/input-type-registry.ts +229 -0
  85. package/src/flow/node-types/index.ts +26 -20
  86. package/src/flow/node.ts +48 -26
  87. package/src/flow/nodes/input-node.ts +4 -2
  88. package/src/flow/nodes/transform-node.ts +64 -6
  89. package/src/flow/output-type-registry.ts +231 -0
  90. package/src/flow/type-guards.ts +38 -22
  91. package/src/flow/typed-flow.ts +26 -0
  92. package/src/flow/types/dead-letter-item.ts +258 -0
  93. package/src/flow/types/flow-types.ts +320 -2
  94. package/src/flow/types/retry-policy.ts +260 -0
  95. package/src/flow/utils/file-naming.ts +308 -0
  96. package/src/types/circuit-breaker-store.ts +222 -0
  97. package/src/types/health-check.ts +204 -0
  98. package/src/types/index.ts +2 -0
  99. package/src/types/kv-store.ts +82 -2
  100. package/tests/flow/dead-letter-item.test.ts +283 -0
  101. package/tests/flow/dead-letter-queue.test.ts +613 -0
  102. package/tests/flow/file-naming.test.ts +390 -0
  103. package/tests/flow/retry-policy.test.ts +284 -0
  104. package/tests/flow/type-registry.test.ts +1 -1
  105. package/tests/flow/type-system.test.ts +17 -14
  106. package/dist/flow-BiUCrFTv.cjs +0 -1
  107. package/dist/flow-vXXjtBBv.mjs +0 -2
  108. package/dist/flow-vXXjtBBv.mjs.map +0 -1
  109. package/dist/index-BQ5luyME.d.cts.map +0 -1
  110. package/dist/index-BtnCNLsH.d.mts.map +0 -1
  111. package/dist/types-B5I4BioZ.cjs +0 -1
  112. package/dist/types-f6w5J3UD.mjs +0 -2
  113. package/dist/types-f6w5J3UD.mjs.map +0 -1
  114. package/dist/uploadista-error-Bb-qIIKM.d.cts.map +0 -1
  115. package/dist/uploadista-error-D7Gubrr1.d.mts.map +0 -1
  116. package/dist/uploadista-error-djFxVTLh.mjs.map +0 -1
  117. package/src/flow/type-registry.ts +0 -379
@@ -1,379 +0,0 @@
1
- /**
2
- * Type registry system for flow input and output nodes.
3
- *
4
- * This module provides a centralized registry for node type definitions with schemas
5
- * and metadata. The registry enables type-safe flow result consumption in dynamic
6
- * client environments by allowing clients to safely cast flow results based on
7
- * registered node types.
8
- *
9
- * @module flow/type-registry
10
- * @see {@link FlowTypeRegistry} for the registry implementation
11
- * @see {@link NodeTypeDefinition} for type definition structure
12
- *
13
- * @example
14
- * ```typescript
15
- * // Register a custom output type
16
- * import { flowTypeRegistry } from "@uploadista/core/flow";
17
- * import { z } from "zod";
18
- *
19
- * const descriptionOutputSchema = z.object({
20
- * description: z.string(),
21
- * confidence: z.number(),
22
- * });
23
- *
24
- * flowTypeRegistry.register({
25
- * id: "description-output-v1",
26
- * category: "output",
27
- * schema: descriptionOutputSchema,
28
- * version: "1.0.0",
29
- * description: "AI-powered image description output",
30
- * });
31
- *
32
- * // Later, validate data against the registered type
33
- * const result = flowTypeRegistry.validate("description-output-v1", data);
34
- * if (result.success) {
35
- * console.log(result.data.description);
36
- * }
37
- * ```
38
- */
39
-
40
- import type { z } from "zod";
41
- import { UploadistaError } from "../errors";
42
-
43
- /**
44
- * Node type category - determines where the node appears in the flow.
45
- *
46
- * - `input`: Nodes that receive data from external sources (e.g., file uploads)
47
- * - `output`: Nodes that produce final results (e.g., storage, webhooks, descriptions)
48
- */
49
- export type NodeTypeCategory = "input" | "output";
50
-
51
- /**
52
- * Defines a registered node type with its schema and metadata.
53
- *
54
- * Node type definitions are registered globally and used to validate and type-narrow
55
- * flow results at runtime. Each definition includes:
56
- * - A unique identifier with versioning
57
- * - A category (input or output)
58
- * - A Zod schema for runtime validation
59
- * - A semantic version for evolution
60
- * - A human-readable description
61
- *
62
- * @template TSchema - The Zod schema type for this node's data
63
- *
64
- * @property id - Unique identifier (e.g., "storage-output-v1", "webhook-output-v1")
65
- * @property category - Whether this is an input or output node type
66
- * @property schema - Zod schema for validating data produced by this node type
67
- * @property version - Semantic version (e.g., "1.0.0") for tracking type evolution
68
- * @property description - Human-readable explanation of what this node type does
69
- *
70
- * @example
71
- * ```typescript
72
- * const storageOutputDef: NodeTypeDefinition<z.infer<typeof uploadFileSchema>> = {
73
- * id: "storage-output-v1",
74
- * category: "output",
75
- * schema: uploadFileSchema,
76
- * version: "1.0.0",
77
- * description: "Storage output node that saves files to configured storage backend",
78
- * };
79
- * ```
80
- */
81
- export interface NodeTypeDefinition<TSchema = unknown> {
82
- id: string;
83
- category: NodeTypeCategory;
84
- schema: z.ZodSchema<TSchema>;
85
- version: string;
86
- description: string;
87
- }
88
-
89
- /**
90
- * Result type for validation operations.
91
- *
92
- * @template T - The expected type on successful validation
93
- */
94
- export type ValidationResult<T> =
95
- | { success: true; data: T }
96
- | { success: false; error: UploadistaError };
97
-
98
- /**
99
- * Central registry for node type definitions.
100
- *
101
- * The FlowTypeRegistry maintains a global registry of node types with their schemas
102
- * and metadata. It provides methods for:
103
- * - Registering new node types
104
- * - Retrieving type definitions
105
- * - Listing types by category
106
- * - Validating data against registered schemas
107
- *
108
- * The registry is immutable after registration - types cannot be modified or removed
109
- * once registered to prevent runtime errors.
110
- *
111
- * @remarks
112
- * - This is a singleton - use the exported `flowTypeRegistry` instance
113
- * - Types cannot be unregistered or modified after registration
114
- * - Duplicate type IDs are rejected
115
- * - Version strings should follow semantic versioning
116
- *
117
- * @example
118
- * ```typescript
119
- * // Register a new type
120
- * flowTypeRegistry.register({
121
- * id: "webhook-output-v1",
122
- * category: "output",
123
- * schema: webhookResponseSchema,
124
- * version: "1.0.0",
125
- * description: "HTTP webhook notification output",
126
- * });
127
- *
128
- * // Retrieve a type definition
129
- * const def = flowTypeRegistry.get("webhook-output-v1");
130
- * if (def) {
131
- * console.log(def.description);
132
- * }
133
- *
134
- * // List all output types
135
- * const outputTypes = flowTypeRegistry.listByCategory("output");
136
- * console.log(outputTypes.map(t => t.id));
137
- *
138
- * // Validate data
139
- * const result = flowTypeRegistry.validate("webhook-output-v1", data);
140
- * if (result.success) {
141
- * // data is now typed according to the schema
142
- * processWebhookResponse(result.data);
143
- * }
144
- * ```
145
- */
146
- export class FlowTypeRegistry {
147
- private readonly types: Map<string, NodeTypeDefinition<unknown>>;
148
-
149
- constructor() {
150
- this.types = new Map();
151
- }
152
-
153
- /**
154
- * Register a new node type in the registry.
155
- *
156
- * Once registered, a type cannot be modified or removed. Attempting to register
157
- * a type with a duplicate ID will throw an error.
158
- *
159
- * @template T - The TypeScript type inferred from the Zod schema
160
- * @param definition - The complete type definition including schema and metadata
161
- * @throws {UploadistaError} If a type with the same ID is already registered
162
- *
163
- * @example
164
- * ```typescript
165
- * import { z } from "zod";
166
- *
167
- * flowTypeRegistry.register({
168
- * id: "description-output-v1",
169
- * category: "output",
170
- * schema: z.object({
171
- * description: z.string(),
172
- * confidence: z.number().min(0).max(1),
173
- * tags: z.array(z.string()).optional(),
174
- * }),
175
- * version: "1.0.0",
176
- * description: "AI-generated image description with confidence score",
177
- * });
178
- * ```
179
- */
180
- register<T>(definition: NodeTypeDefinition<T>): void {
181
- if (this.types.has(definition.id)) {
182
- throw UploadistaError.fromCode("VALIDATION_ERROR", {
183
- body: `Node type "${definition.id}" is already registered. Types cannot be modified or re-registered.`,
184
- details: { typeId: definition.id },
185
- });
186
- }
187
-
188
- // Store as unknown to avoid generic constraints in the Map
189
- this.types.set(definition.id, definition as NodeTypeDefinition<unknown>);
190
- }
191
-
192
- /**
193
- * Retrieve a registered type definition by its ID.
194
- *
195
- * @param id - The unique type identifier (e.g., "storage-output-v1")
196
- * @returns The type definition if found, undefined otherwise
197
- *
198
- * @example
199
- * ```typescript
200
- * const def = flowTypeRegistry.get("storage-output-v1");
201
- * if (def) {
202
- * console.log(`Found ${def.description} (v${def.version})`);
203
- * } else {
204
- * console.warn("Type not registered");
205
- * }
206
- * ```
207
- */
208
- get(id: string): NodeTypeDefinition<unknown> | undefined {
209
- return this.types.get(id);
210
- }
211
-
212
- /**
213
- * List all registered types in a specific category.
214
- *
215
- * @param category - The node category to filter by ("input" or "output")
216
- * @returns Array of type definitions in the specified category
217
- *
218
- * @example
219
- * ```typescript
220
- * // List all registered output types
221
- * const outputTypes = flowTypeRegistry.listByCategory("output");
222
- * console.log("Available output types:");
223
- * for (const type of outputTypes) {
224
- * console.log(`- ${type.id}: ${type.description}`);
225
- * }
226
- * ```
227
- */
228
- listByCategory(category: NodeTypeCategory): NodeTypeDefinition<unknown>[] {
229
- const result: NodeTypeDefinition<unknown>[] = [];
230
- for (const definition of this.types.values()) {
231
- if (definition.category === category) {
232
- result.push(definition);
233
- }
234
- }
235
- return result;
236
- }
237
-
238
- /**
239
- * Validate data against a registered type's schema.
240
- *
241
- * This method performs runtime validation using the Zod schema associated with
242
- * the type. If validation succeeds, the data is returned with proper typing.
243
- * If validation fails, an UploadistaError is returned with details.
244
- *
245
- * @template T - The expected TypeScript type after validation
246
- * @param typeId - The ID of the registered type to validate against
247
- * @param data - The data to validate
248
- * @returns A result object with either the validated data or an error
249
- *
250
- * @example
251
- * ```typescript
252
- * const result = flowTypeRegistry.validate("storage-output-v1", unknownData);
253
- *
254
- * if (result.success) {
255
- * // TypeScript knows result.data is an UploadFile
256
- * console.log(`File stored at: ${result.data.url}`);
257
- * } else {
258
- * console.error(`Validation failed: ${result.error.body}`);
259
- * }
260
- * ```
261
- */
262
- validate<T>(typeId: string, data: unknown): ValidationResult<T> {
263
- const typeDef = this.types.get(typeId);
264
-
265
- if (!typeDef) {
266
- return {
267
- success: false,
268
- error: UploadistaError.fromCode("VALIDATION_ERROR", {
269
- body: `Node type "${typeId}" is not registered`,
270
- details: { typeId },
271
- }),
272
- };
273
- }
274
-
275
- try {
276
- const parsed = typeDef.schema.parse(data);
277
- return { success: true, data: parsed as T };
278
- } catch (error) {
279
- return {
280
- success: false,
281
- error: UploadistaError.fromCode("VALIDATION_ERROR", {
282
- body: `Data validation failed for type "${typeId}"`,
283
- cause: error,
284
- details: { typeId, validationErrors: error },
285
- }),
286
- };
287
- }
288
- }
289
-
290
- /**
291
- * Check if a type is registered.
292
- *
293
- * @param id - The unique type identifier to check
294
- * @returns True if the type is registered, false otherwise
295
- *
296
- * @example
297
- * ```typescript
298
- * if (flowTypeRegistry.has("custom-output-v1")) {
299
- * console.log("Custom output type is available");
300
- * }
301
- * ```
302
- */
303
- has(id: string): boolean {
304
- return this.types.has(id);
305
- }
306
-
307
- /**
308
- * Get the total number of registered types.
309
- *
310
- * @returns The count of registered types
311
- *
312
- * @example
313
- * ```typescript
314
- * console.log(`Registry contains ${flowTypeRegistry.size()} types`);
315
- * ```
316
- */
317
- size(): number {
318
- return this.types.size;
319
- }
320
- }
321
-
322
- /**
323
- * Global singleton instance of the flow type registry.
324
- *
325
- * Use this instance to register and access node type definitions throughout
326
- * your application. The registry is initialized once and shared globally.
327
- *
328
- * @example
329
- * ```typescript
330
- * import { flowTypeRegistry } from "@uploadista/core/flow";
331
- *
332
- * // Register a type
333
- * flowTypeRegistry.register({
334
- * id: "my-output-v1",
335
- * category: "output",
336
- * schema: mySchema,
337
- * version: "1.0.0",
338
- * description: "My custom output type",
339
- * });
340
- *
341
- * // Validate data
342
- * const result = flowTypeRegistry.validate("my-output-v1", data);
343
- * ```
344
- */
345
- export const flowTypeRegistry = new FlowTypeRegistry();
346
-
347
- /**
348
- * Validates flow input data against a registered node type.
349
- *
350
- * This helper function looks up the node type by ID and validates the provided
351
- * data against its schema. It's specifically designed for input validation
352
- * before flow execution.
353
- *
354
- * @param typeId - The registered type ID (e.g., "streaming-input-v1")
355
- * @param data - The input data to validate
356
- * @returns A validation result with either the typed data or an error
357
- *
358
- * @example
359
- * ```typescript
360
- * import { validateFlowInput } from "@uploadista/core/flow";
361
- *
362
- * const result = validateFlowInput("streaming-input-v1", {
363
- * operation: "url",
364
- * url: "https://example.com/image.jpg"
365
- * });
366
- *
367
- * if (result.success) {
368
- * console.log("Valid input:", result.data);
369
- * } else {
370
- * console.error("Validation error:", result.error);
371
- * }
372
- * ```
373
- */
374
- export function validateFlowInput<T = unknown>(
375
- typeId: string,
376
- data: unknown,
377
- ): ValidationResult<T> {
378
- return flowTypeRegistry.validate<T>(typeId, data);
379
- }