@uploadista/core 0.0.20 → 0.1.0-beta.5
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-DVPe3Db4.cjs → checksum-CTpNXWEL.cjs} +1 -1
- package/dist/errors/index.cjs +1 -1
- package/dist/errors/index.d.mts +2 -2
- package/dist/flow/index.cjs +1 -1
- package/dist/flow/index.d.cts +2 -2
- package/dist/flow/index.d.mts +6 -6
- package/dist/flow/index.mjs +1 -1
- package/dist/flow-CA8xO6wP.mjs +2 -0
- package/dist/flow-CA8xO6wP.mjs.map +1 -0
- package/dist/flow-DKJaCPxL.cjs +1 -0
- package/dist/index-9gyMMEIB.d.cts.map +1 -1
- package/dist/{index-RuQUCROH.d.mts → index-BNhJmMuC.d.mts} +228 -167
- package/dist/index-BNhJmMuC.d.mts.map +1 -0
- package/dist/{index-DMqaf28W.d.cts → index-BmkhRBV6.d.cts} +226 -165
- package/dist/index-BmkhRBV6.d.cts.map +1 -0
- package/dist/{index-B9V5SSxl.d.mts → index-D8MZ6P3o.d.mts} +2 -2
- package/dist/{index-B9V5SSxl.d.mts.map → index-D8MZ6P3o.d.mts.map} +1 -1
- package/dist/{index-BFSHumky.d.mts → index-DQuMQssI.d.mts} +2 -2
- package/dist/{index-BFSHumky.d.mts.map → index-DQuMQssI.d.mts.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +1 -1
- package/dist/{stream-limiter-BvkaZXcz.cjs → stream-limiter-DH0vv46_.cjs} +1 -1
- package/dist/streams/index.cjs +1 -1
- package/dist/streams/index.d.mts +2 -2
- package/dist/streams/index.mjs +1 -1
- package/dist/testing/index.cjs +2 -2
- package/dist/testing/index.d.cts +1 -1
- package/dist/testing/index.d.cts.map +1 -1
- package/dist/testing/index.d.mts +5 -5
- package/dist/testing/index.d.mts.map +1 -1
- package/dist/testing/index.mjs +2 -2
- package/dist/testing/index.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 +6 -6
- package/dist/types/index.mjs +1 -1
- package/dist/types-BF_tvkRh.cjs +1 -0
- package/dist/types-BRnwrJDg.mjs +2 -0
- package/dist/types-BRnwrJDg.mjs.map +1 -0
- package/dist/upload/index.cjs +1 -1
- package/dist/upload/index.d.cts +1 -1
- package/dist/upload/index.d.mts +5 -5
- package/dist/upload/index.mjs +1 -1
- package/dist/upload-CLHJ1SFS.cjs +1 -0
- package/dist/upload-CpsShjP3.mjs +2 -0
- package/dist/upload-CpsShjP3.mjs.map +1 -0
- package/dist/{uploadista-error-DR0XimpE.d.mts → uploadista-error-B1qbOy9N.d.mts} +1 -1
- package/dist/{uploadista-error-DR0XimpE.d.mts.map → uploadista-error-B1qbOy9N.d.mts.map} +1 -1
- package/dist/{uploadista-error-BgQU45we.cjs → uploadista-error-CLWoRAAr.cjs} +1 -1
- package/dist/uploadista-error-CkSxSyNo.mjs.map +1 -1
- package/dist/utils/index.cjs +1 -1
- package/dist/utils/index.d.mts +2 -2
- package/dist/utils/index.mjs +1 -1
- package/dist/{utils-UUJt8ILJ.cjs → utils-CvZJUNEo.cjs} +1 -1
- package/dist/{utils-B-ZhQ6b0.mjs → utils-DVwfrVBJ.mjs} +1 -1
- package/dist/utils-DVwfrVBJ.mjs.map +1 -0
- package/package.json +8 -8
- package/src/flow/circuit-breaker-store.ts +7 -8
- package/src/flow/flow.ts +6 -5
- package/src/flow/nodes/transform-node.ts +15 -1
- package/src/flow/plugins/image-plugin.ts +12 -3
- package/src/flow/plugins/video-plugin.ts +12 -3
- package/src/flow/types/flow-types.ts +75 -6
- package/src/flow/types/retry-policy.ts +5 -2
- package/src/flow/types/type-utils.ts +4 -6
- package/src/flow/utils/file-naming.ts +36 -11
- package/src/testing/mock-upload-engine.ts +18 -1
- package/src/types/circuit-breaker-store.ts +2 -2
- package/src/types/data-store.ts +4 -1
- package/src/types/kv-store.ts +13 -12
- package/src/types/upload-file.ts +29 -4
- package/src/upload/upload-chunk.ts +1 -1
- package/dist/flow-BHVkk_6W.cjs +0 -1
- package/dist/flow-DlhHOlMk.mjs +0 -2
- package/dist/flow-DlhHOlMk.mjs.map +0 -1
- package/dist/index-DMqaf28W.d.cts.map +0 -1
- package/dist/index-RuQUCROH.d.mts.map +0 -1
- package/dist/streams-BiD_pOPH.cjs +0 -0
- package/dist/streams-Cqjxk2rI.mjs +0 -1
- package/dist/types-Cws60JHC.cjs +0 -1
- package/dist/types-DKGQJIEr.mjs +0 -2
- package/dist/types-DKGQJIEr.mjs.map +0 -1
- package/dist/upload-C-C7hn1-.mjs +0 -2
- package/dist/upload-C-C7hn1-.mjs.map +0 -1
- package/dist/upload-DWBlRXHh.cjs +0 -1
- package/dist/utils-B-ZhQ6b0.mjs.map +0 -1
- /package/dist/{index-C-svZlpj.d.mts → index-DWe68pTi.d.mts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-DVwfrVBJ.mjs","names":[],"sources":["../src/utils/md5.ts","../src/utils/once.ts","../src/utils/debounce.ts","../src/utils/throttle.ts"],"sourcesContent":["/*\n\nTypeScript Md5\n==============\n\nBased on work by\n* Joseph Myers: http://www.myersdaily.org/joseph/javascript/md5-text.html\n* André Cruz: https://github.com/satazor/SparkMD5\n* Raymond Hill: https://github.com/gorhill/yamd5.js\n\nEffectively a TypeScrypt re-write of Raymond Hill JS Library\n\nThe MIT License (MIT)\n\nCopyright (C) 2014 Raymond Hill\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n DO WHAT YOU WANT TO PUBLIC LICENSE\n Version 2, December 2004\n\n Copyright (C) 2015 André Cruz <amdfcruz@gmail.com>\n\n Everyone is permitted to copy and distribute verbatim or modified\n copies of this license document, and changing it is allowed as long\n as the name is changed.\n\n DO WHAT YOU WANT TO PUBLIC LICENSE\n TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n 0. You just DO WHAT YOU WANT TO.\n\n*/\n\ntype HasherState = {\n buffer: string;\n buflen: number;\n length: number;\n state: number[];\n};\n\nexport class Md5 {\n /**\n * Hash a UTF-8 string on the spot\n * @param str String to hash\n * @param raw Whether to return the value as an `Int32Array`\n */\n public static hashStr(str: string, raw?: false): string;\n public static hashStr(str: string, raw: true): Int32Array;\n public static hashStr(str: string, raw = false) {\n return Md5.onePassHasher.start().appendStr(str).end(raw);\n }\n\n /**\n * Hash a ASCII string on the spot\n * @param str String to hash\n * @param raw Whether to return the value as an `Int32Array`\n */\n public static hashAsciiStr(str: string, raw?: false): string;\n public static hashAsciiStr(str: string, raw: true): Int32Array;\n public static hashAsciiStr(str: string, raw = false) {\n return Md5.onePassHasher.start().appendAsciiStr(str).end(raw);\n }\n\n // Private Static Variables\n private static stateIdentity = new Int32Array([\n 1732584193, -271733879, -1732584194, 271733878,\n ]);\n\n private static buffer32Identity = new Int32Array([\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n ]);\n\n private static hexChars = \"0123456789abcdef\";\n private static hexOut: string[] = [];\n\n // Permanent instance is to use for one-call hashing\n private static onePassHasher = new Md5();\n\n private static _hex(x: Int32Array): string {\n const hc = Md5.hexChars;\n const ho = Md5.hexOut;\n let n: number;\n let offset: number;\n let j: number;\n let i: number;\n\n for (i = 0; i < 4; i += 1) {\n offset = i * 8;\n n = x[i] ?? 0;\n for (j = 0; j < 8; j += 2) {\n ho[offset + 1 + j] = hc.charAt(n & 0x0f);\n n >>>= 4;\n ho[offset + 0 + j] = hc.charAt(n & 0x0f);\n n >>>= 4;\n }\n }\n return ho.join(\"\");\n }\n\n private static _md5cycle(\n x: Int32Array | Uint32Array,\n k: Int32Array | Uint32Array,\n ) {\n let a: number = x[0] ?? 0;\n let b: number = x[1] ?? 0;\n let c: number = x[2] ?? 0;\n let d: number = x[3] ?? 0;\n // ff()\n a += (((b & c) | (~b & d)) + (k[0] ?? 0) - 680876936) | 0;\n a = (((a << 7) | (a >>> 25)) + b) | 0;\n d += (((a & b) | (~a & c)) + (k[1] ?? 0) - 389564586) | 0;\n d = (((d << 12) | (d >>> 20)) + a) | 0;\n c += (((d & a) | (~d & b)) + (k[2] ?? 0) + 606105819) | 0;\n c = (((c << 17) | (c >>> 15)) + d) | 0;\n b += (((c & d) | (~c & a)) + (k[3] ?? 0) - 1044525330) | 0;\n b = (((b << 22) | (b >>> 10)) + c) | 0;\n a += (((b & c) | (~b & d)) + (k[4] ?? 0) - 176418897) | 0;\n a = (((a << 7) | (a >>> 25)) + b) | 0;\n d += (((a & b) | (~a & c)) + (k[5] ?? 0) + 1200080426) | 0;\n d = (((d << 12) | (d >>> 20)) + a) | 0;\n c += (((d & a) | (~d & b)) + (k[6] ?? 0) - 1473231341) | 0;\n c = (((c << 17) | (c >>> 15)) + d) | 0;\n b += (((c & d) | (~c & a)) + (k[7] ?? 0) - 45705983) | 0;\n b = (((b << 22) | (b >>> 10)) + c) | 0;\n a += (((b & c) | (~b & d)) + (k[8] ?? 0) + 1770035416) | 0;\n a = (((a << 7) | (a >>> 25)) + b) | 0;\n d += (((a & b) | (~a & c)) + (k[9] ?? 0) - 1958414417) | 0;\n d = (((d << 12) | (d >>> 20)) + a) | 0;\n c += (((d & a) | (~d & b)) + (k[10] ?? 0) - 42063) | 0;\n c = (((c << 17) | (c >>> 15)) + d) | 0;\n b += (((c & d) | (~c & a)) + (k[11] ?? 0) - 1990404162) | 0;\n b = (((b << 22) | (b >>> 10)) + c) | 0;\n a += (((b & c) | (~b & d)) + (k[12] ?? 0) + 1804603682) | 0;\n a = (((a << 7) | (a >>> 25)) + b) | 0;\n d += (((a & b) | (~a & c)) + (k[13] ?? 0) - 40341101) | 0;\n d = (((d << 12) | (d >>> 20)) + a) | 0;\n c += (((d & a) | (~d & b)) + (k[14] ?? 0) - 1502002290) | 0;\n c = (((c << 17) | (c >>> 15)) + d) | 0;\n b += (((c & d) | (~c & a)) + (k[15] ?? 0) + 1236535329) | 0;\n b = (((b << 22) | (b >>> 10)) + c) | 0;\n // gg()\n a += (((b & d) | (c & ~d)) + (k[1] ?? 0) - 165796510) | 0;\n a = (((a << 5) | (a >>> 27)) + b) | 0;\n d += (((a & c) | (b & ~c)) + (k[6] ?? 0) - 1069501632) | 0;\n d = (((d << 9) | (d >>> 23)) + a) | 0;\n c += (((d & b) | (a & ~b)) + (k[11] ?? 0) + 643717713) | 0;\n c = (((c << 14) | (c >>> 18)) + d) | 0;\n b += (((c & a) | (d & ~a)) + (k[0] ?? 0) - 373897302) | 0;\n b = (((b << 20) | (b >>> 12)) + c) | 0;\n a += (((b & d) | (c & ~d)) + (k[5] ?? 0) - 701558691) | 0;\n a = (((a << 5) | (a >>> 27)) + b) | 0;\n d += (((a & c) | (b & ~c)) + (k[10] ?? 0) + 38016083) | 0;\n d = (((d << 9) | (d >>> 23)) + a) | 0;\n c += (((d & b) | (a & ~b)) + (k[15] ?? 0) - 660478335) | 0;\n c = (((c << 14) | (c >>> 18)) + d) | 0;\n b += (((c & a) | (d & ~a)) + (k[4] ?? 0) - 405537848) | 0;\n b = (((b << 20) | (b >>> 12)) + c) | 0;\n a += (((b & d) | (c & ~d)) + (k[9] ?? 0) + 568446438) | 0;\n a = (((a << 5) | (a >>> 27)) + b) | 0;\n d += (((a & c) | (b & ~c)) + (k[14] ?? 0) - 1019803690) | 0;\n d = (((d << 9) | (d >>> 23)) + a) | 0;\n c += (((d & b) | (a & ~b)) + (k[3] ?? 0) - 187363961) | 0;\n c = (((c << 14) | (c >>> 18)) + d) | 0;\n b += (((c & a) | (d & ~a)) + (k[8] ?? 0) + 1163531501) | 0;\n b = (((b << 20) | (b >>> 12)) + c) | 0;\n a += (((b & d) | (c & ~d)) + (k[13] ?? 0) - 1444681467) | 0;\n a = (((a << 5) | (a >>> 27)) + b) | 0;\n d += (((a & c) | (b & ~c)) + (k[2] ?? 0) - 51403784) | 0;\n d = (((d << 9) | (d >>> 23)) + a) | 0;\n c += (((d & b) | (a & ~b)) + (k[7] ?? 0) + 1735328473) | 0;\n c = (((c << 14) | (c >>> 18)) + d) | 0;\n b += (((c & a) | (d & ~a)) + (k[12] ?? 0) - 1926607734) | 0;\n b = (((b << 20) | (b >>> 12)) + c) | 0;\n // hh()\n a += ((b ^ c ^ d) + (k[5] ?? 0) - 378558) | 0;\n a = (((a << 4) | (a >>> 28)) + b) | 0;\n d += ((a ^ b ^ c) + (k[8] ?? 0) - 2022574463) | 0;\n d = (((d << 11) | (d >>> 21)) + a) | 0;\n c += ((d ^ a ^ b) + (k[11] ?? 0) + 1839030562) | 0;\n c = (((c << 16) | (c >>> 16)) + d) | 0;\n b += ((c ^ d ^ a) + (k[14] ?? 0) - 35309556) | 0;\n b = (((b << 23) | (b >>> 9)) + c) | 0;\n a += ((b ^ c ^ d) + (k[1] ?? 0) - 1530992060) | 0;\n a = (((a << 4) | (a >>> 28)) + b) | 0;\n d += ((a ^ b ^ c) + (k[4] ?? 0) + 1272893353) | 0;\n d = (((d << 11) | (d >>> 21)) + a) | 0;\n c += ((d ^ a ^ b) + (k[7] ?? 0) - 155497632) | 0;\n c = (((c << 16) | (c >>> 16)) + d) | 0;\n b += ((c ^ d ^ a) + (k[10] ?? 0) - 1094730640) | 0;\n b = (((b << 23) | (b >>> 9)) + c) | 0;\n a += ((b ^ c ^ d) + (k[13] ?? 0) + 681279174) | 0;\n a = (((a << 4) | (a >>> 28)) + b) | 0;\n d += ((a ^ b ^ c) + (k[0] ?? 0) - 358537222) | 0;\n d = (((d << 11) | (d >>> 21)) + a) | 0;\n c += ((d ^ a ^ b) + (k[3] ?? 0) - 722521979) | 0;\n c = (((c << 16) | (c >>> 16)) + d) | 0;\n b += ((c ^ d ^ a) + (k[6] ?? 0) + 76029189) | 0;\n b = (((b << 23) | (b >>> 9)) + c) | 0;\n a += ((b ^ c ^ d) + (k[9] ?? 0) - 640364487) | 0;\n a = (((a << 4) | (a >>> 28)) + b) | 0;\n d += ((a ^ b ^ c) + (k[12] ?? 0) - 421815835) | 0;\n d = (((d << 11) | (d >>> 21)) + a) | 0;\n c += ((d ^ a ^ b) + (k[15] ?? 0) + 530742520) | 0;\n c = (((c << 16) | (c >>> 16)) + d) | 0;\n b += ((c ^ d ^ a) + (k[2] ?? 0) - 995338651) | 0;\n b = (((b << 23) | (b >>> 9)) + c) | 0;\n // ii()\n a += ((c ^ (b | ~d)) + (k[0] ?? 0) - 198630844) | 0;\n a = (((a << 6) | (a >>> 26)) + b) | 0;\n d += ((b ^ (a | ~c)) + (k[7] ?? 0) + 1126891415) | 0;\n d = (((d << 10) | (d >>> 22)) + a) | 0;\n c += ((a ^ (d | ~b)) + (k[14] ?? 0) - 1416354905) | 0;\n c = (((c << 15) | (c >>> 17)) + d) | 0;\n b += ((d ^ (c | ~a)) + (k[5] ?? 0) - 57434055) | 0;\n b = (((b << 21) | (b >>> 11)) + c) | 0;\n a += ((c ^ (b | ~d)) + (k[12] ?? 0) + 1700485571) | 0;\n a = (((a << 6) | (a >>> 26)) + b) | 0;\n d += ((b ^ (a | ~c)) + (k[3] ?? 0) - 1894986606) | 0;\n d = (((d << 10) | (d >>> 22)) + a) | 0;\n c += ((a ^ (d | ~b)) + (k[10] ?? 0) - 1051523) | 0;\n c = (((c << 15) | (c >>> 17)) + d) | 0;\n b += ((d ^ (c | ~a)) + (k[1] ?? 0) - 2054922799) | 0;\n b = (((b << 21) | (b >>> 11)) + c) | 0;\n a += ((c ^ (b | ~d)) + (k[8] ?? 0) + 1873313359) | 0;\n a = (((a << 6) | (a >>> 26)) + b) | 0;\n d += ((b ^ (a | ~c)) + (k[15] ?? 0) - 30611744) | 0;\n d = (((d << 10) | (d >>> 22)) + a) | 0;\n c += ((a ^ (d | ~b)) + (k[6] ?? 0) - 1560198380) | 0;\n c = (((c << 15) | (c >>> 17)) + d) | 0;\n b += ((d ^ (c | ~a)) + (k[13] ?? 0) + 1309151649) | 0;\n b = (((b << 21) | (b >>> 11)) + c) | 0;\n a += ((c ^ (b | ~d)) + (k[4] ?? 0) - 145523070) | 0;\n a = (((a << 6) | (a >>> 26)) + b) | 0;\n d += ((b ^ (a | ~c)) + (k[11] ?? 0) - 1120210379) | 0;\n d = (((d << 10) | (d >>> 22)) + a) | 0;\n c += ((a ^ (d | ~b)) + (k[2] ?? 0) + 718787259) | 0;\n c = (((c << 15) | (c >>> 17)) + d) | 0;\n b += ((d ^ (c | ~a)) + (k[9] ?? 0) - 343485551) | 0;\n b = (((b << 21) | (b >>> 11)) + c) | 0;\n\n x[0] = (a + (x[0] ?? 0)) | 0;\n x[1] = (b + (x[1] ?? 0)) | 0;\n x[2] = (c + (x[2] ?? 0)) | 0;\n x[3] = (d + (x[3] ?? 0)) | 0;\n }\n\n private _dataLength = 0;\n private _bufferLength = 0;\n\n private _state: Int32Array = new Int32Array(4);\n private _buffer: ArrayBuffer = new ArrayBuffer(68);\n private _buffer8: Uint8Array;\n private _buffer32: Uint32Array;\n\n constructor() {\n this._buffer8 = new Uint8Array(this._buffer, 0, 68);\n this._buffer32 = new Uint32Array(this._buffer, 0, 17);\n this.start();\n }\n\n /**\n * Initialise buffer to be hashed\n */\n public start() {\n this._dataLength = 0;\n this._bufferLength = 0;\n this._state.set(Md5.stateIdentity);\n return this;\n }\n\n // Char to code point to to array conversion:\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt\n // #Example.3A_Fixing_charCodeAt_to_handle_non-Basic-Multilingual-Plane_characters_if_their_presence_earlier_in_the_string_is_unknown\n\n /**\n * Append a UTF-8 string to the hash buffer\n * @param str String to append\n */\n public appendStr(str: string) {\n const buf8 = this._buffer8;\n const buf32 = this._buffer32;\n let bufLen = this._bufferLength;\n let code: number;\n let i: number;\n\n for (i = 0; i < str.length; i += 1) {\n code = str.charCodeAt(i);\n if (code < 128) {\n buf8[bufLen++] = code;\n } else if (code < 0x800) {\n buf8[bufLen++] = (code >>> 6) + 0xc0;\n buf8[bufLen++] = (code & 0x3f) | 0x80;\n } else if (code < 0xd800 || code > 0xdbff) {\n buf8[bufLen++] = (code >>> 12) + 0xe0;\n buf8[bufLen++] = ((code >>> 6) & 0x3f) | 0x80;\n buf8[bufLen++] = (code & 0x3f) | 0x80;\n } else {\n code =\n (code - 0xd800) * 0x400 + (str.charCodeAt(++i) - 0xdc00) + 0x10000;\n if (code > 0x10ffff) {\n throw new Error(\n \"Unicode standard supports code points up to U+10FFFF\",\n );\n }\n buf8[bufLen++] = (code >>> 18) + 0xf0;\n buf8[bufLen++] = ((code >>> 12) & 0x3f) | 0x80;\n buf8[bufLen++] = ((code >>> 6) & 0x3f) | 0x80;\n buf8[bufLen++] = (code & 0x3f) | 0x80;\n }\n if (bufLen >= 64) {\n this._dataLength += 64;\n Md5._md5cycle(this._state, buf32);\n bufLen -= 64;\n buf32[0] = buf32[16] ?? 0;\n }\n }\n this._bufferLength = bufLen;\n return this;\n }\n\n /**\n * Append an ASCII string to the hash buffer\n * @param str String to append\n */\n public appendAsciiStr(str: string) {\n const buf8 = this._buffer8;\n const buf32 = this._buffer32;\n let bufLen = this._bufferLength;\n let i: number;\n let j = 0;\n\n for (;;) {\n i = Math.min(str.length - j, 64 - bufLen);\n while (i--) {\n buf8[bufLen++] = str.charCodeAt(j++);\n }\n if (bufLen < 64) {\n break;\n }\n this._dataLength += 64;\n Md5._md5cycle(this._state, buf32);\n bufLen = 0;\n }\n this._bufferLength = bufLen;\n return this;\n }\n\n /**\n * Append a byte array to the hash buffer\n * @param input array to append\n */\n public appendByteArray(input: Uint8Array) {\n const buf8 = this._buffer8;\n const buf32 = this._buffer32;\n let bufLen = this._bufferLength;\n let i: number;\n let j = 0;\n\n for (;;) {\n i = Math.min(input.length - j, 64 - bufLen);\n while (i--) {\n buf8[bufLen++] = input[j++] ?? 0;\n }\n if (bufLen < 64) {\n break;\n }\n this._dataLength += 64;\n Md5._md5cycle(this._state, buf32);\n bufLen = 0;\n }\n this._bufferLength = bufLen;\n return this;\n }\n\n /**\n * Get the state of the hash buffer\n */\n public getState(): HasherState {\n const s = this._state;\n\n return {\n buffer: String.fromCharCode.apply(null, Array.from(this._buffer8)),\n buflen: this._bufferLength,\n length: this._dataLength,\n state: [s[0] ?? 0, s[1] ?? 0, s[2] ?? 0, s[3] ?? 0],\n };\n }\n\n /**\n * Override the current state of the hash buffer\n * @param state New hash buffer state\n */\n public setState(state: HasherState) {\n const buf = state.buffer;\n const x = state.state;\n const s = this._state;\n let i: number;\n\n this._dataLength = state.length;\n this._bufferLength = state.buflen;\n s[0] = x[0] ?? 0;\n s[1] = x[1] ?? 0;\n s[2] = x[2] ?? 0;\n s[3] = x[3] ?? 0;\n\n for (i = 0; i < buf.length; i += 1) {\n this._buffer8[i] = buf.charCodeAt(i);\n }\n }\n\n /**\n * Hash the current state of the hash buffer and return the result\n * @param raw Whether to return the value as an `Int32Array`\n */\n public end(raw = false) {\n const bufLen = this._bufferLength;\n const buf8 = this._buffer8;\n const buf32 = this._buffer32;\n const i = (bufLen >> 2) + 1;\n\n this._dataLength += bufLen;\n const dataBitsLen = this._dataLength * 8;\n\n buf8[bufLen] = 0x80;\n buf8[bufLen + 1] = buf8[bufLen + 2] = buf8[bufLen + 3] = 0;\n buf32.set(Md5.buffer32Identity.subarray(i), i);\n\n if (bufLen > 55) {\n Md5._md5cycle(this._state, buf32);\n buf32.set(Md5.buffer32Identity);\n }\n\n // Do the final computation based on the tail and length\n // Beware that the final length may not fit in 32 bits so we take care of that\n if (dataBitsLen <= 0xffffffff) {\n buf32[14] = dataBitsLen;\n } else {\n const matches = dataBitsLen.toString(16).match(/(.*?)(.{0,8})$/);\n if (matches === null) {\n return;\n }\n\n const lo = Number.parseInt(matches[2] ?? \"\", 16);\n const hi = Number.parseInt(matches[1] ?? \"\", 16) || 0;\n\n buf32[14] = lo;\n buf32[15] = hi;\n }\n\n Md5._md5cycle(this._state, buf32);\n\n return raw ? this._state : Md5._hex(this._state);\n }\n}\n\nif (Md5.hashStr(\"hello\") !== \"5d41402abc4b2a76b9719d911017c592\") {\n throw new Error(\"Md5 self test failed.\");\n}\n","import { Effect } from \"effect\";\nimport { UploadistaError } from \"../errors/uploadista-error\";\n\n// only call a function once\nexport function once<T, A extends unknown[], Return>(\n fn: (this: T, ...args: A) => Return,\n) {\n let called = false;\n let value: Return | undefined;\n const f = function (this: T, ...args: A): Return {\n if (called) {\n if (value) {\n return value;\n }\n throw new Error(\"Function called more than once\");\n }\n called = true;\n value = fn.apply(this, args);\n return value;\n };\n return f;\n}\n\n/**\n * Effect-based once utilities\n */\nexport const OnceEffect = {\n /**\n * Creates an Effect-based once function that only executes once\n * @param effect - The effect to execute only once\n * @returns Effect that caches the result after first execution\n */\n make: <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n ): Effect.Effect<A, E | UploadistaError, R> => {\n let cached: A | undefined;\n let called = false;\n\n return Effect.gen(function* () {\n if (called) {\n if (cached !== undefined) {\n return cached;\n }\n yield* new UploadistaError({\n code: \"UNKNOWN_ERROR\",\n status: 500,\n body: \"Effect called more than once with undefined result\",\n }).toEffect();\n }\n\n called = true;\n cached = yield* effect;\n return cached;\n });\n },\n\n /**\n * Creates a legacy once function wrapper\n * @param fn - Function to wrap\n * @returns Once-wrapped function\n */\n legacy: once,\n};\n","type DebounceOptions = {\n // Whether the first call to the debounced function is run immediately.\n leading?: boolean;\n\n // Whether the last call to the debounced function is run after delay\n // milliseconds have elapsed since the last call.\n trailing?: boolean;\n};\n\nconst defaultDebounceOptions: DebounceOptions = {\n leading: false,\n trailing: true,\n};\n\n/**\n * Returns `fn` wrapped by a function that delays invoking `fn` for `delay`\n * milliseconds since the last call. Set `options.leading` to invoke `fn` on\n * the leading edge of the delay, and/or set `options.trailing` to invoke `fn`\n * on the trailing edge of the delay (true by default).\n *\n * Example for `debounce(fn, 30, {leading: true, trailing: true})`,\n * where `fn` is called twice, with the second call made 20 ms after the first:\n *\n * Time: 0 20 50 (ms)\n * Timeline: |----------------------------------------------------------------|\n * ^ ^ ^\n * | | |\n * | First call. | Second call 20ms after the | End of delay.\n * | (instant leading | first. | (trailing edge\n * | edge call) | | call)\n * |-----------------------------|\n * | 30 ms delay for debounce. |\n *\n *\n * Note that if both `options.leading` and `options.trailing` are true, `fn`\n * will only be invoked on the trailing edge if the debounced function is called\n * more than once during the delay.\n *\n * @param fn - Function to debounce.\n * @param delay - Milliseconds to delay calling `fn` since the last call.\n * @param debounceOptions - See `DebounceOptions` and `defaultDebounceOptions`.\n * @returns A debounced `fn`.\n */\nexport function debounce<T, A extends unknown[]>(\n fn: (this: T, ...args: A) => void,\n delay: number,\n debounceOptions: DebounceOptions = {},\n): (this: T, ...args: A) => void {\n const options = { ...defaultDebounceOptions, ...debounceOptions };\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n return function (this: T, ...args: A): void {\n if (options.leading && !timer) {\n // Leading edge.\n // Call fn on the leading edge, when debouncing hasn't started yet.\n console.log(\"leading\");\n fn.apply(this, args);\n\n // Debounce the next call.\n timer = setTimeout(() => {\n timer = undefined;\n }, delay);\n } else {\n // Trailing edge.\n // Postpone calling fn until the delay has elapsed since the last call.\n // Each call clears any previously delayed call and resets the delay, so\n // the postponed call will always be the last one.\n clearTimeout(timer);\n timer = setTimeout(() => {\n if (options.trailing) {\n // Call fn on the trailing edge.\n fn.apply(this, args);\n\n if (options.leading) {\n // Debounce next leading call since a trailing call was just made.\n setTimeout(() => {\n timer = undefined;\n }, delay);\n }\n } else {\n // No trailing call. Since the delay has elapsed since the last call,\n // immediately reset the debouncing delay.\n timer = undefined;\n }\n }, delay);\n }\n };\n}\n","import { debounce } from \"./debounce.js\";\n\nexport function throttle<T, A extends unknown[], Return>(\n fn: (this: T, ...args: A) => Return,\n wait: number,\n {\n leading = true,\n trailing = true,\n }: { leading?: boolean; trailing?: boolean } = {},\n) {\n return debounce(fn, wait, {\n leading,\n trailing,\n });\n}\n\n/**\n * Effect-based throttle utilities\n */\nexport const ThrottleEffect = {\n /**\n * Creates a legacy throttle function wrapper\n * @param fn - Function to throttle\n * @param wait - Wait time in milliseconds\n * @param options - Throttle options\n * @returns Throttled function\n */\n legacy: throttle,\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uploadista/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.1.0-beta.5",
|
|
4
4
|
"description": "Core package of Uploadista",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Uploadista",
|
|
@@ -71,13 +71,13 @@
|
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@effect/vitest": "0.27.0",
|
|
74
|
-
"@types/node": "24.10.
|
|
75
|
-
"effect": "3.19.
|
|
74
|
+
"@types/node": "24.10.8",
|
|
75
|
+
"effect": "3.19.14",
|
|
76
76
|
"tsd": "0.33.0",
|
|
77
|
-
"tsdown": "0.
|
|
78
|
-
"vitest": "4.0.
|
|
79
|
-
"zod": "4.
|
|
80
|
-
"@uploadista/typescript-config": "0.0.
|
|
77
|
+
"tsdown": "0.19.0",
|
|
78
|
+
"vitest": "4.0.17",
|
|
79
|
+
"zod": "4.3.5",
|
|
80
|
+
"@uploadista/typescript-config": "0.1.0-beta.5"
|
|
81
81
|
},
|
|
82
82
|
"publishConfig": {
|
|
83
83
|
"access": "public",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"format": "biome format --write ./src",
|
|
91
91
|
"lint": "biome lint --write ./src",
|
|
92
92
|
"check": "biome check --write ./src",
|
|
93
|
-
"test": "vitest",
|
|
93
|
+
"test": "vitest run",
|
|
94
94
|
"test:run": "vitest run",
|
|
95
95
|
"test:watch": "vitest --watch",
|
|
96
96
|
"typecheck": "tsc --noEmit"
|
|
@@ -9,12 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { Effect, Layer } from "effect";
|
|
11
11
|
|
|
12
|
-
import { UploadistaError } from "../errors";
|
|
13
|
-
import {
|
|
14
|
-
type BaseKvStore,
|
|
15
|
-
BaseKvStoreService,
|
|
16
|
-
jsonSerializer,
|
|
17
|
-
} from "../types/kv-store";
|
|
12
|
+
import type { UploadistaError } from "../errors";
|
|
18
13
|
import {
|
|
19
14
|
type CircuitBreakerStateData,
|
|
20
15
|
type CircuitBreakerStats,
|
|
@@ -22,6 +17,11 @@ import {
|
|
|
22
17
|
CircuitBreakerStoreService,
|
|
23
18
|
createInitialCircuitBreakerState,
|
|
24
19
|
} from "../types/circuit-breaker-store";
|
|
20
|
+
import {
|
|
21
|
+
type BaseKvStore,
|
|
22
|
+
BaseKvStoreService,
|
|
23
|
+
jsonSerializer,
|
|
24
|
+
} from "../types/kv-store";
|
|
25
25
|
|
|
26
26
|
// ============================================================================
|
|
27
27
|
// Key Prefix
|
|
@@ -231,8 +231,7 @@ export function makeMemoryCircuitBreakerStore(): CircuitBreakerStore {
|
|
|
231
231
|
const store = new Map<string, CircuitBreakerStateData>();
|
|
232
232
|
|
|
233
233
|
return {
|
|
234
|
-
getState: (nodeType: string) =>
|
|
235
|
-
Effect.succeed(store.get(nodeType) ?? null),
|
|
234
|
+
getState: (nodeType: string) => Effect.succeed(store.get(nodeType) ?? null),
|
|
236
235
|
|
|
237
236
|
setState: (nodeType: string, state: CircuitBreakerStateData) =>
|
|
238
237
|
Effect.sync(() => {
|
package/src/flow/flow.ts
CHANGED
|
@@ -890,9 +890,9 @@ export function createFlowWithSchema<
|
|
|
890
890
|
});
|
|
891
891
|
|
|
892
892
|
// Support both Effect and Promise
|
|
893
|
-
result = yield*
|
|
893
|
+
result = yield* Effect.isEffect(hookResult)
|
|
894
894
|
? hookResult
|
|
895
|
-
: Effect.promise(() => hookResult as Promise<unknown>)
|
|
895
|
+
: Effect.promise(() => hookResult as Promise<unknown>);
|
|
896
896
|
}
|
|
897
897
|
}
|
|
898
898
|
|
|
@@ -1040,9 +1040,10 @@ export function createFlowWithSchema<
|
|
|
1040
1040
|
const circuitBreakerStore = yield* Effect.serviceOption(
|
|
1041
1041
|
CircuitBreakerStoreService,
|
|
1042
1042
|
);
|
|
1043
|
-
const circuitBreakerRegistry =
|
|
1044
|
-
|
|
1045
|
-
|
|
1043
|
+
const circuitBreakerRegistry =
|
|
1044
|
+
circuitBreakerStore._tag === "Some"
|
|
1045
|
+
? new DistributedCircuitBreakerRegistry(circuitBreakerStore.value)
|
|
1046
|
+
: null;
|
|
1046
1047
|
|
|
1047
1048
|
// Emit FlowStart event only if starting fresh
|
|
1048
1049
|
if (!resumeFrom && onEvent) {
|
|
@@ -111,7 +111,13 @@ export interface TransformNodeConfig {
|
|
|
111
111
|
bytes: Uint8Array,
|
|
112
112
|
file: UploadFile,
|
|
113
113
|
) => Effect.Effect<
|
|
114
|
-
|
|
114
|
+
| Uint8Array
|
|
115
|
+
| {
|
|
116
|
+
bytes: Uint8Array;
|
|
117
|
+
type?: string;
|
|
118
|
+
fileName?: string;
|
|
119
|
+
metadata?: Record<string, unknown>;
|
|
120
|
+
},
|
|
115
121
|
UploadistaError
|
|
116
122
|
>;
|
|
117
123
|
/**
|
|
@@ -470,6 +476,12 @@ export function createTransformNode({
|
|
|
470
476
|
? undefined
|
|
471
477
|
: transformResult.fileName;
|
|
472
478
|
|
|
479
|
+
// Get metadata from transform result if provided
|
|
480
|
+
const outputMetadata =
|
|
481
|
+
transformResult instanceof Uint8Array
|
|
482
|
+
? undefined
|
|
483
|
+
: transformResult.metadata;
|
|
484
|
+
|
|
473
485
|
// Apply file naming if configured and no explicit fileName from transform
|
|
474
486
|
if (!outputFileName && naming) {
|
|
475
487
|
const namingContext = buildNamingContext(
|
|
@@ -513,6 +525,8 @@ export function createTransformNode({
|
|
|
513
525
|
const updatedMetadata = metadata
|
|
514
526
|
? {
|
|
515
527
|
...metadata,
|
|
528
|
+
// Merge transform-returned metadata (e.g., virusScan results)
|
|
529
|
+
...outputMetadata,
|
|
516
530
|
// Update mimeType and related fields if type changed
|
|
517
531
|
...(outputType && {
|
|
518
532
|
mimeType: outputType,
|
|
@@ -105,7 +105,10 @@ export type ImagePluginShape = {
|
|
|
105
105
|
optimizeStream?: (
|
|
106
106
|
input: Stream.Stream<Uint8Array, UploadistaError>,
|
|
107
107
|
options: OptimizeParams,
|
|
108
|
-
) => Effect.Effect<
|
|
108
|
+
) => Effect.Effect<
|
|
109
|
+
Stream.Stream<Uint8Array, UploadistaError>,
|
|
110
|
+
UploadistaError
|
|
111
|
+
>;
|
|
109
112
|
|
|
110
113
|
/**
|
|
111
114
|
* Resizes an image using streaming for memory-efficient processing of large files.
|
|
@@ -136,7 +139,10 @@ export type ImagePluginShape = {
|
|
|
136
139
|
resizeStream?: (
|
|
137
140
|
input: Stream.Stream<Uint8Array, UploadistaError>,
|
|
138
141
|
options: ResizeParams,
|
|
139
|
-
) => Effect.Effect<
|
|
142
|
+
) => Effect.Effect<
|
|
143
|
+
Stream.Stream<Uint8Array, UploadistaError>,
|
|
144
|
+
UploadistaError
|
|
145
|
+
>;
|
|
140
146
|
|
|
141
147
|
/**
|
|
142
148
|
* Applies a single transformation using streaming for memory-efficient processing.
|
|
@@ -166,7 +172,10 @@ export type ImagePluginShape = {
|
|
|
166
172
|
transformStream?: (
|
|
167
173
|
input: Stream.Stream<Uint8Array, UploadistaError>,
|
|
168
174
|
transformation: Transformation,
|
|
169
|
-
) => Effect.Effect<
|
|
175
|
+
) => Effect.Effect<
|
|
176
|
+
Stream.Stream<Uint8Array, UploadistaError>,
|
|
177
|
+
UploadistaError
|
|
178
|
+
>;
|
|
170
179
|
|
|
171
180
|
/**
|
|
172
181
|
* Indicates whether this plugin supports streaming operations.
|
|
@@ -124,7 +124,10 @@ export type VideoPluginShape = {
|
|
|
124
124
|
input: VideoStreamInput,
|
|
125
125
|
options: TranscodeVideoParams,
|
|
126
126
|
streamOptions?: VideoStreamOptions,
|
|
127
|
-
) => Effect.Effect<
|
|
127
|
+
) => Effect.Effect<
|
|
128
|
+
Stream.Stream<Uint8Array, UploadistaError>,
|
|
129
|
+
UploadistaError
|
|
130
|
+
>;
|
|
128
131
|
|
|
129
132
|
/**
|
|
130
133
|
* Resizes a video using streaming for memory-efficient processing of large files.
|
|
@@ -157,7 +160,10 @@ export type VideoPluginShape = {
|
|
|
157
160
|
input: VideoStreamInput,
|
|
158
161
|
options: ResizeVideoParams,
|
|
159
162
|
streamOptions?: VideoStreamOptions,
|
|
160
|
-
) => Effect.Effect<
|
|
163
|
+
) => Effect.Effect<
|
|
164
|
+
Stream.Stream<Uint8Array, UploadistaError>,
|
|
165
|
+
UploadistaError
|
|
166
|
+
>;
|
|
161
167
|
|
|
162
168
|
/**
|
|
163
169
|
* Trims a video using streaming for memory-efficient processing of large files.
|
|
@@ -189,7 +195,10 @@ export type VideoPluginShape = {
|
|
|
189
195
|
input: VideoStreamInput,
|
|
190
196
|
options: TrimVideoParams,
|
|
191
197
|
streamOptions?: VideoStreamOptions,
|
|
192
|
-
) => Effect.Effect<
|
|
198
|
+
) => Effect.Effect<
|
|
199
|
+
Stream.Stream<Uint8Array, UploadistaError>,
|
|
200
|
+
UploadistaError
|
|
201
|
+
>;
|
|
193
202
|
|
|
194
203
|
/**
|
|
195
204
|
* Indicates whether this plugin supports streaming operations.
|
|
@@ -56,6 +56,12 @@ export type FlowNodeData = {
|
|
|
56
56
|
nodeTypeId?: string;
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* All built-in node type identifiers.
|
|
61
|
+
* Used to exclude these from custom types for proper discriminated union narrowing.
|
|
62
|
+
*/
|
|
63
|
+
export type BuiltInNodeType = "storage-output-v1" | "streaming-input-v1";
|
|
64
|
+
|
|
59
65
|
/**
|
|
60
66
|
* Built-in typed outputs with automatic TypeScript narrowing.
|
|
61
67
|
*
|
|
@@ -72,12 +78,19 @@ export type FlowNodeData = {
|
|
|
72
78
|
* }
|
|
73
79
|
* ```
|
|
74
80
|
*/
|
|
75
|
-
export type BuiltInTypedOutput =
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
export type BuiltInTypedOutput =
|
|
82
|
+
| {
|
|
83
|
+
nodeType: "storage-output-v1";
|
|
84
|
+
data: UploadFile;
|
|
85
|
+
nodeId: string;
|
|
86
|
+
timestamp: string;
|
|
87
|
+
}
|
|
88
|
+
| {
|
|
89
|
+
nodeType: "streaming-input-v1";
|
|
90
|
+
data: UploadFile;
|
|
91
|
+
nodeId: string;
|
|
92
|
+
timestamp: string;
|
|
93
|
+
};
|
|
81
94
|
|
|
82
95
|
/**
|
|
83
96
|
* Custom typed output for user-defined node types.
|
|
@@ -179,6 +192,62 @@ export type TypedOutput<T = unknown> =
|
|
|
179
192
|
| BuiltInTypedOutput
|
|
180
193
|
| CustomTypedOutput<T>;
|
|
181
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Helper type to extract a specific built-in output by nodeType.
|
|
197
|
+
*
|
|
198
|
+
* This enables type-safe narrowing when you know the nodeType:
|
|
199
|
+
* ```typescript
|
|
200
|
+
* if (output.nodeType === "storage-output-v1") {
|
|
201
|
+
* const narrowed = output as NarrowTypedOutput<"storage-output-v1">;
|
|
202
|
+
* narrowed.data.url; // ✅ TypeScript knows data is UploadFile
|
|
203
|
+
* }
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
export type NarrowTypedOutput<NodeType extends BuiltInNodeType> = Extract<
|
|
207
|
+
BuiltInTypedOutput,
|
|
208
|
+
{ nodeType: NodeType }
|
|
209
|
+
>;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Type guard function signature for narrowing TypedOutput.
|
|
213
|
+
*
|
|
214
|
+
* @template NodeType - The built-in node type to narrow to
|
|
215
|
+
*/
|
|
216
|
+
export type TypedOutputGuard<NodeType extends BuiltInNodeType> = (
|
|
217
|
+
output: TypedOutput,
|
|
218
|
+
) => output is NarrowTypedOutput<NodeType>;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Creates a type-safe type guard for a built-in node type.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```typescript
|
|
225
|
+
* const isStorageV1 = createOutputGuard("storage-output-v1");
|
|
226
|
+
*
|
|
227
|
+
* for (const output of outputs) {
|
|
228
|
+
* if (isStorageV1(output)) {
|
|
229
|
+
* output.data.url; // ✅ TypeScript knows data is UploadFile
|
|
230
|
+
* }
|
|
231
|
+
* }
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
export const createOutputGuard =
|
|
235
|
+
<NodeType extends BuiltInNodeType>(
|
|
236
|
+
nodeType: NodeType,
|
|
237
|
+
): TypedOutputGuard<NodeType> =>
|
|
238
|
+
(output: TypedOutput): output is NarrowTypedOutput<NodeType> =>
|
|
239
|
+
output.nodeType === nodeType;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Pre-built type guard for storage-output-v1.
|
|
243
|
+
*/
|
|
244
|
+
export const isStorageOutputV1 = createOutputGuard("storage-output-v1");
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Pre-built type guard for streaming-input-v1.
|
|
248
|
+
*/
|
|
249
|
+
export const isStreamingInputV1 = createOutputGuard("streaming-input-v1");
|
|
250
|
+
|
|
182
251
|
/**
|
|
183
252
|
* Result of a node execution - either complete or waiting for more data.
|
|
184
253
|
*
|
|
@@ -74,7 +74,10 @@ export interface ExponentialBackoff {
|
|
|
74
74
|
/**
|
|
75
75
|
* Union type for all backoff strategies.
|
|
76
76
|
*/
|
|
77
|
-
export type BackoffStrategy =
|
|
77
|
+
export type BackoffStrategy =
|
|
78
|
+
| ImmediateBackoff
|
|
79
|
+
| FixedBackoff
|
|
80
|
+
| ExponentialBackoff;
|
|
78
81
|
|
|
79
82
|
/**
|
|
80
83
|
* Configuration for automatic retry behavior.
|
|
@@ -182,7 +185,7 @@ export function calculateBackoffDelay(
|
|
|
182
185
|
|
|
183
186
|
case "exponential": {
|
|
184
187
|
const baseDelay =
|
|
185
|
-
backoff.initialDelayMs *
|
|
188
|
+
backoff.initialDelayMs * backoff.multiplier ** retryCount;
|
|
186
189
|
const cappedDelay = Math.min(baseDelay, backoff.maxDelayMs);
|
|
187
190
|
|
|
188
191
|
if (backoff.jitter) {
|
|
@@ -110,9 +110,8 @@ export type ExtractLayerServices<
|
|
|
110
110
|
* ```
|
|
111
111
|
*/
|
|
112
112
|
// biome-ignore lint/suspicious/noExplicitAny: Utility type needs to handle any Effect type parameters
|
|
113
|
-
export type ResolveEffect<T> =
|
|
114
|
-
? S
|
|
115
|
-
: T;
|
|
113
|
+
export type ResolveEffect<T> =
|
|
114
|
+
T extends Effect.Effect<infer S, any, any> ? S : T;
|
|
116
115
|
|
|
117
116
|
/**
|
|
118
117
|
* Extracts the error type from an Effect.
|
|
@@ -138,9 +137,8 @@ export type ResolveEffect<T> = T extends Effect.Effect<infer S, any, any>
|
|
|
138
137
|
* ```
|
|
139
138
|
*/
|
|
140
139
|
// biome-ignore lint/suspicious/noExplicitAny: Utility type needs to handle any Effect type parameters
|
|
141
|
-
export type ExtractEffectError<T> =
|
|
142
|
-
? E
|
|
143
|
-
: never;
|
|
140
|
+
export type ExtractEffectError<T> =
|
|
141
|
+
T extends Effect.Effect<any, infer E, any> ? E : never;
|
|
144
142
|
|
|
145
143
|
/**
|
|
146
144
|
* Extracts the requirements (context) type from an Effect.
|
|
@@ -10,10 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import { render } from "micromustache";
|
|
12
12
|
import type { UploadFile } from "../../types/upload-file";
|
|
13
|
-
import type {
|
|
14
|
-
FileNamingConfig,
|
|
15
|
-
NamingContext,
|
|
16
|
-
} from "../types/flow-types";
|
|
13
|
+
import type { FileNamingConfig, NamingContext } from "../types/flow-types";
|
|
17
14
|
|
|
18
15
|
/**
|
|
19
16
|
* Extracts the base name (without extension) from a filename.
|
|
@@ -292,16 +289,44 @@ export function validatePattern(pattern: string): {
|
|
|
292
289
|
* List of available template variables for documentation and UI.
|
|
293
290
|
*/
|
|
294
291
|
export const AVAILABLE_TEMPLATE_VARIABLES = [
|
|
295
|
-
{
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
292
|
+
{
|
|
293
|
+
name: "baseName",
|
|
294
|
+
description: "Filename without extension",
|
|
295
|
+
example: "photo",
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: "extension",
|
|
299
|
+
description: "File extension without dot",
|
|
300
|
+
example: "jpg",
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: "fileName",
|
|
304
|
+
description: "Full original filename",
|
|
305
|
+
example: "photo.jpg",
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
name: "nodeType",
|
|
309
|
+
description: "Type of processing node",
|
|
310
|
+
example: "resize",
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
name: "nodeId",
|
|
314
|
+
description: "Specific node instance ID",
|
|
315
|
+
example: "resize-1",
|
|
316
|
+
},
|
|
300
317
|
{ name: "flowId", description: "Flow identifier", example: "flow-abc" },
|
|
301
318
|
{ name: "jobId", description: "Execution job ID", example: "job-123" },
|
|
302
|
-
{
|
|
319
|
+
{
|
|
320
|
+
name: "timestamp",
|
|
321
|
+
description: "ISO 8601 processing time",
|
|
322
|
+
example: "2024-01-15T10:30:00Z",
|
|
323
|
+
},
|
|
303
324
|
{ name: "width", description: "Output width (image/video)", example: "800" },
|
|
304
|
-
{
|
|
325
|
+
{
|
|
326
|
+
name: "height",
|
|
327
|
+
description: "Output height (image/video)",
|
|
328
|
+
example: "600",
|
|
329
|
+
},
|
|
305
330
|
{ name: "format", description: "Output format", example: "webp" },
|
|
306
331
|
{ name: "quality", description: "Quality setting", example: "80" },
|
|
307
332
|
{ name: "pageNumber", description: "Page number (documents)", example: "1" },
|
|
@@ -8,6 +8,13 @@ import {
|
|
|
8
8
|
} from "../types/data-store";
|
|
9
9
|
import { UploadEngine } from "../upload";
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* EICAR test file signature (standard antivirus test file)
|
|
13
|
+
* This is a safe, non-malicious string used to test antivirus software
|
|
14
|
+
*/
|
|
15
|
+
const EICAR_SIGNATURE =
|
|
16
|
+
"X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*";
|
|
17
|
+
|
|
11
18
|
/**
|
|
12
19
|
* Mock UploadEngine implementation for testing.
|
|
13
20
|
*
|
|
@@ -30,7 +37,17 @@ export const TestUploadEngine = Layer.succeed(
|
|
|
30
37
|
UploadEngine.of({
|
|
31
38
|
read: (fileId: string, _clientId: string | null) =>
|
|
32
39
|
Effect.sync(() => {
|
|
33
|
-
//
|
|
40
|
+
// Return infected content for files that should trigger virus detection
|
|
41
|
+
// This allows tests to verify virus scanning behavior
|
|
42
|
+
if (
|
|
43
|
+
fileId.toLowerCase().includes("infected") ||
|
|
44
|
+
fileId.toLowerCase().includes("virus") ||
|
|
45
|
+
fileId.toLowerCase().includes("malware") ||
|
|
46
|
+
fileId.toLowerCase().includes("eicar")
|
|
47
|
+
) {
|
|
48
|
+
return new TextEncoder().encode(EICAR_SIGNATURE);
|
|
49
|
+
}
|
|
50
|
+
// Generate clean mock file data for other files
|
|
34
51
|
const text = `Content of file ${fileId}`;
|
|
35
52
|
return new TextEncoder().encode(text);
|
|
36
53
|
}),
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* @module types/circuit-breaker-store
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { Context, Effect, Layer } from "effect";
|
|
12
|
-
import { UploadistaError } from "../errors";
|
|
11
|
+
import { Context, type Effect, Layer } from "effect";
|
|
12
|
+
import type { UploadistaError } from "../errors";
|
|
13
13
|
|
|
14
14
|
// ============================================================================
|
|
15
15
|
// State Types
|
package/src/types/data-store.ts
CHANGED
|
@@ -279,7 +279,10 @@ export type DataStore<TData = unknown> = {
|
|
|
279
279
|
readonly readStream?: (
|
|
280
280
|
file_id: string,
|
|
281
281
|
config?: StreamingConfig,
|
|
282
|
-
) => Effect.Effect<
|
|
282
|
+
) => Effect.Effect<
|
|
283
|
+
Stream.Stream<Uint8Array, UploadistaError>,
|
|
284
|
+
UploadistaError
|
|
285
|
+
>;
|
|
283
286
|
readonly write: (
|
|
284
287
|
options: DataStoreWriteOptions,
|
|
285
288
|
dependencies: {
|
package/src/types/kv-store.ts
CHANGED
|
@@ -196,15 +196,17 @@ export class TypedKvStore<TData> implements KvStore<TData> {
|
|
|
196
196
|
list = (): Effect.Effect<Array<string>, UploadistaError> => {
|
|
197
197
|
if (this.baseStore.list) {
|
|
198
198
|
// Get keys with prefix and strip the prefix for use with get/set/delete
|
|
199
|
-
return this.baseStore
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
199
|
+
return this.baseStore
|
|
200
|
+
.list(this.keyPrefix)
|
|
201
|
+
.pipe(
|
|
202
|
+
Effect.map((keys) =>
|
|
203
|
+
keys.map((key) =>
|
|
204
|
+
key.startsWith(this.keyPrefix)
|
|
205
|
+
? key.slice(this.keyPrefix.length)
|
|
206
|
+
: key,
|
|
207
|
+
),
|
|
205
208
|
),
|
|
206
|
-
)
|
|
207
|
-
);
|
|
209
|
+
);
|
|
208
210
|
}
|
|
209
211
|
return Effect.fail(
|
|
210
212
|
new UploadistaError({
|
|
@@ -419,10 +421,9 @@ export const flowJobKvStore = Layer.effect(
|
|
|
419
421
|
* });
|
|
420
422
|
* ```
|
|
421
423
|
*/
|
|
422
|
-
export class DeadLetterQueueKVStore extends Context.Tag(
|
|
423
|
-
DeadLetterQueueKVStore,
|
|
424
|
-
|
|
425
|
-
>() {}
|
|
424
|
+
export class DeadLetterQueueKVStore extends Context.Tag(
|
|
425
|
+
"DeadLetterQueueKVStore",
|
|
426
|
+
)<DeadLetterQueueKVStore, KvStore<DeadLetterItem>>() {}
|
|
426
427
|
|
|
427
428
|
/**
|
|
428
429
|
* Effect Layer that creates the DeadLetterQueueKVStore from a BaseKvStore.
|
package/src/types/upload-file.ts
CHANGED
|
@@ -17,13 +17,38 @@ export const traceContextSchema = z.object({
|
|
|
17
17
|
traceFlags: z.number(),
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* JSON value type that allows any JSON-serializable data.
|
|
22
|
+
* Used for metadata values which can be primitives, arrays, or nested objects.
|
|
23
|
+
*/
|
|
24
|
+
export type JsonValue =
|
|
25
|
+
| string
|
|
26
|
+
| number
|
|
27
|
+
| boolean
|
|
28
|
+
| null
|
|
29
|
+
| JsonValue[]
|
|
30
|
+
| { [key: string]: JsonValue };
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* JSON value schema that allows any JSON-serializable data.
|
|
34
|
+
* This is used for metadata values which can be primitives, arrays, or objects.
|
|
35
|
+
*/
|
|
36
|
+
const jsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>
|
|
37
|
+
z.union([
|
|
38
|
+
z.string(),
|
|
39
|
+
z.number(),
|
|
40
|
+
z.boolean(),
|
|
41
|
+
z.null(),
|
|
42
|
+
z.array(jsonValueSchema),
|
|
43
|
+
z.record(z.string(), jsonValueSchema),
|
|
44
|
+
]),
|
|
45
|
+
);
|
|
46
|
+
|
|
20
47
|
export const uploadFileSchema = z.object({
|
|
21
48
|
id: z.string(),
|
|
22
49
|
size: z.number().optional(),
|
|
23
50
|
offset: z.number(),
|
|
24
|
-
metadata: z
|
|
25
|
-
.record(z.string(), z.union([z.string(), z.number(), z.boolean()]))
|
|
26
|
-
.optional(),
|
|
51
|
+
metadata: z.record(z.string(), jsonValueSchema).optional(),
|
|
27
52
|
creationDate: z.string().optional(),
|
|
28
53
|
url: z.string().optional(),
|
|
29
54
|
sizeIsDeferred: z.boolean().optional(),
|
|
@@ -172,7 +197,7 @@ export type UploadFile = {
|
|
|
172
197
|
jobId: string;
|
|
173
198
|
};
|
|
174
199
|
size?: number | undefined;
|
|
175
|
-
metadata?: Record<string,
|
|
200
|
+
metadata?: Record<string, JsonValue> | undefined;
|
|
176
201
|
creationDate?: string | undefined;
|
|
177
202
|
url?: string | undefined;
|
|
178
203
|
sizeIsDeferred?: boolean | undefined;
|