codatta-frontier-sdk 0.1.9 → 0.2.0
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 +56 -0
- package/dist/index.cjs +294 -1
- package/dist/index.d.ts +54 -0
- package/dist/index.mjs +666 -96
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -48,6 +48,8 @@ const uploadResult = await sdk.uploadFile(file, (event) => {
|
|
|
48
48
|
console.log(`Upload progress: ${Math.round((event.loaded * 100) / (event.total ?? 1))}%`)
|
|
49
49
|
})
|
|
50
50
|
|
|
51
|
+
// Large file upload (chunked + resumable). See "Large file upload" section below.
|
|
52
|
+
|
|
51
53
|
// Get a single spec task info
|
|
52
54
|
const specTask = await sdk.getSpecTaskInfo('task-id')
|
|
53
55
|
|
|
@@ -92,6 +94,8 @@ Creates an SDK instance. No parameters required — the SDK handles the followin
|
|
|
92
94
|
| `getFrontierInfo(frontierId)` | Get Frontier detail |
|
|
93
95
|
| `getSubmissionDetail(submissionId)` | Get submission detail |
|
|
94
96
|
| `uploadFile(file, onProgress?)` | Upload a file |
|
|
97
|
+
| `uploadLargeFile(file, options?)` | Upload a large file with chunking, parallel parts, and resumable checkpoints |
|
|
98
|
+
| `abortUpload(object_key, upload_id)` | Abort an in-progress multipart upload |
|
|
95
99
|
| `getSpecTaskInfo(taskId)` | Get single spec task info |
|
|
96
100
|
| `getSpecTaskInfos(taskIds)` | Get multiple spec tasks info |
|
|
97
101
|
| `submitSpecTask(taskId, content?, status?)` | Submit or update a spec task |
|
|
@@ -165,6 +169,58 @@ Key types exported from `codatta-frontier-sdk`:
|
|
|
165
169
|
| `ActiveStatus` | Frontier status: `'ACTIVE' \| 'INACTIVE' \| 'COMPLETED'` |
|
|
166
170
|
| `MediaName` | Social media identifiers used in frontier media links |
|
|
167
171
|
|
|
172
|
+
## Large file upload (chunked + resumable)
|
|
173
|
+
|
|
174
|
+
For large files (e.g. multi-GB video), use `uploadLargeFile`. It uses presigned multipart upload: the backend signs short-lived PUT URLs for each part, and the browser streams chunks directly to object storage in parallel. SHA-256 is computed in a Web Worker concurrently with upload.
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { FrontierSDK, type Checkpoint } from 'codatta-frontier-sdk'
|
|
178
|
+
|
|
179
|
+
const sdk = new FrontierSDK()
|
|
180
|
+
const controller = new AbortController()
|
|
181
|
+
|
|
182
|
+
// Restore checkpoint from a previous session (optional)
|
|
183
|
+
const saved = localStorage.getItem(`upload-cp:${taskId}`)
|
|
184
|
+
const checkpoint: Checkpoint | undefined = saved ? JSON.parse(saved) : undefined
|
|
185
|
+
|
|
186
|
+
const result = await sdk.uploadLargeFile(file, {
|
|
187
|
+
checkpoint,
|
|
188
|
+
partSize: 8 * 1024 * 1024, // optional, default 8 MiB
|
|
189
|
+
parallel: 4, // optional, default 4
|
|
190
|
+
signal: controller.signal,
|
|
191
|
+
onProgress: ({ percent, speed, etaSec }) => {
|
|
192
|
+
console.log(`${percent.toFixed(1)}% ${(speed / 1024 / 1024).toFixed(2)} MB/s ETA ${etaSec}s`)
|
|
193
|
+
},
|
|
194
|
+
onCheckpoint: (cp) => {
|
|
195
|
+
localStorage.setItem(`upload-cp:${taskId}`, JSON.stringify(cp))
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
localStorage.removeItem(`upload-cp:${taskId}`)
|
|
200
|
+
console.log(result.file_path, result.sha256)
|
|
201
|
+
|
|
202
|
+
// Pause: controller.abort()
|
|
203
|
+
// Resume: call uploadLargeFile again with the persisted `checkpoint`
|
|
204
|
+
// Cancel and free OSS reservation: await sdk.abortUpload(result.object_key, uploadId)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### `uploadLargeFile(file, options?)`
|
|
208
|
+
|
|
209
|
+
| Option | Type | Description |
|
|
210
|
+
|---|---|---|
|
|
211
|
+
| `checkpoint` | `Checkpoint` | Resume a previous upload (same file size required) |
|
|
212
|
+
| `partSize` | `number` | Part size in bytes (default `8 * 1024 * 1024`) |
|
|
213
|
+
| `parallel` | `number` | Parallel part uploads (default `4`) |
|
|
214
|
+
| `signal` | `AbortSignal` | Abort in-flight upload |
|
|
215
|
+
| `onProgress` | `(info) => void` | `{ percent, loaded, total, speed, etaSec }` (10-second sliding window) |
|
|
216
|
+
| `onCheckpoint` | `(cp) => void` | Invoked after each part success; persist to resume later |
|
|
217
|
+
|
|
218
|
+
Returns `{ file_path, original_name, object_key, sha256 }`.
|
|
219
|
+
|
|
220
|
+
### `abortUpload(object_key, upload_id)`
|
|
221
|
+
|
|
222
|
+
Aborts an in-progress multipart upload server-side so storage can reclaim parts immediately (OSS lifecycle rules will also clean up eventually).
|
|
223
|
+
|
|
168
224
|
## Build
|
|
169
225
|
|
|
170
226
|
```bash
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1,294 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const q=require("axios");/*! js-cookie v3.0.5 | MIT */function h(n){for(var A=1;A<arguments.length;A++){var e=arguments[A];for(var I in e)n[I]=e[I]}return n}var P={read:function(n){return n[0]==='"'&&(n=n.slice(1,-1)),n.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)},write:function(n){return encodeURIComponent(n).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}};function m(n,A){function e(t,c,g){if(!(typeof document>"u")){g=h({},A,g),typeof g.expires=="number"&&(g.expires=new Date(Date.now()+g.expires*864e5)),g.expires&&(g.expires=g.expires.toUTCString()),t=encodeURIComponent(t).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape);var i="";for(var o in g)g[o]&&(i+="; "+o,g[o]!==!0&&(i+="="+g[o].split(";")[0]));return document.cookie=t+"="+n.write(c,t)+i}}function I(t){if(!(typeof document>"u"||arguments.length&&!t)){for(var c=document.cookie?document.cookie.split("; "):[],g={},i=0;i<c.length;i++){var o=c[i].split("="),r=o.slice(1).join("=");try{var B=decodeURIComponent(o[0]);if(g[B]=n.read(r,B),t===B)break}catch{}}return t?g[t]:g}}return Object.create({set:e,get:I,remove:function(t,c){e(t,"",h({},c,{expires:-1}))},withAttributes:function(t){return m(this.converter,h({},this.attributes,t))},withConverter:function(t){return m(h({},this.converter,t),this.attributes)}},{attributes:{value:Object.freeze(A)},converter:{value:Object.freeze(n)}})}var U=m(P,{path:"/"});const Y=1e4;class V{constructor(){this.samples=[]}addSample(A,e){this.samples.push({loaded:A,timestamp:e});const I=e-Y;for(;this.samples.length>0&&this.samples[0].timestamp<I;)this.samples.shift()}getSpeed(){if(this.samples.length<2)return 0;const A=this.samples[0],e=this.samples[this.samples.length-1],I=(e.timestamp-A.timestamp)/1e3;if(I<=0)return 0;const t=e.loaded-A.loaded;return t>0?t/I:0}getEtaSec(A,e){const I=this.getSpeed();if(I<=0)return 1/0;const t=A-e;return t<=0?0:t/I}}const b=`/*!
|
|
2
|
+
* hash-wasm (https://www.npmjs.com/package/hash-wasm)
|
|
3
|
+
* (c) Dani Biro
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
function F(A, g, I, E) {
|
|
7
|
+
function Q(n) {
|
|
8
|
+
return n instanceof I ? n : new I(function(o) {
|
|
9
|
+
o(n);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
return new (I || (I = Promise))(function(n, o) {
|
|
13
|
+
function y(e) {
|
|
14
|
+
try {
|
|
15
|
+
t(E.next(e));
|
|
16
|
+
} catch (C) {
|
|
17
|
+
o(C);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function N(e) {
|
|
21
|
+
try {
|
|
22
|
+
t(E.throw(e));
|
|
23
|
+
} catch (C) {
|
|
24
|
+
o(C);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function t(e) {
|
|
28
|
+
e.done ? n(e.value) : Q(e.value).then(y, N);
|
|
29
|
+
}
|
|
30
|
+
t((E = E.apply(A, [])).next());
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
class i {
|
|
34
|
+
constructor() {
|
|
35
|
+
this.mutex = Promise.resolve();
|
|
36
|
+
}
|
|
37
|
+
lock() {
|
|
38
|
+
let g = () => {
|
|
39
|
+
};
|
|
40
|
+
return this.mutex = this.mutex.then(() => new Promise(g)), new Promise((I) => {
|
|
41
|
+
g = I;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
dispatch(g) {
|
|
45
|
+
return F(this, void 0, void 0, function* () {
|
|
46
|
+
const I = yield this.lock();
|
|
47
|
+
try {
|
|
48
|
+
return yield Promise.resolve(g());
|
|
49
|
+
} finally {
|
|
50
|
+
I();
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
var h;
|
|
56
|
+
function V() {
|
|
57
|
+
return typeof globalThis < "u" ? globalThis : typeof self < "u" ? self : typeof window < "u" ? window : global;
|
|
58
|
+
}
|
|
59
|
+
const G = V(), M = (h = G.Buffer) !== null && h !== void 0 ? h : null, L = G.TextEncoder ? new G.TextEncoder() : null;
|
|
60
|
+
function K(A, g) {
|
|
61
|
+
return (A & 15) + (A >> 6 | A >> 3 & 8) << 4 | (g & 15) + (g >> 6 | g >> 3 & 8);
|
|
62
|
+
}
|
|
63
|
+
function W(A, g) {
|
|
64
|
+
const I = g.length >> 1;
|
|
65
|
+
for (let E = 0; E < I; E++) {
|
|
66
|
+
const Q = E << 1;
|
|
67
|
+
A[E] = K(g.charCodeAt(Q), g.charCodeAt(Q + 1));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function O(A, g) {
|
|
71
|
+
if (A.length !== g.length * 2)
|
|
72
|
+
return !1;
|
|
73
|
+
for (let I = 0; I < g.length; I++) {
|
|
74
|
+
const E = I << 1;
|
|
75
|
+
if (g[I] !== K(A.charCodeAt(E), A.charCodeAt(E + 1)))
|
|
76
|
+
return !1;
|
|
77
|
+
}
|
|
78
|
+
return !0;
|
|
79
|
+
}
|
|
80
|
+
const x = 87, H = 48;
|
|
81
|
+
function U(A, g, I) {
|
|
82
|
+
let E = 0;
|
|
83
|
+
for (let Q = 0; Q < I; Q++) {
|
|
84
|
+
let n = g[Q] >>> 4;
|
|
85
|
+
A[E++] = n > 9 ? n + x : n + H, n = g[Q] & 15, A[E++] = n > 9 ? n + x : n + H;
|
|
86
|
+
}
|
|
87
|
+
return String.fromCharCode.apply(null, A);
|
|
88
|
+
}
|
|
89
|
+
const u = M !== null ? (A) => {
|
|
90
|
+
if (typeof A == "string") {
|
|
91
|
+
const g = M.from(A, "utf8");
|
|
92
|
+
return new Uint8Array(g.buffer, g.byteOffset, g.length);
|
|
93
|
+
}
|
|
94
|
+
if (M.isBuffer(A))
|
|
95
|
+
return new Uint8Array(A.buffer, A.byteOffset, A.length);
|
|
96
|
+
if (ArrayBuffer.isView(A))
|
|
97
|
+
return new Uint8Array(A.buffer, A.byteOffset, A.byteLength);
|
|
98
|
+
throw new Error("Invalid data type!");
|
|
99
|
+
} : (A) => {
|
|
100
|
+
if (typeof A == "string")
|
|
101
|
+
return L.encode(A);
|
|
102
|
+
if (ArrayBuffer.isView(A))
|
|
103
|
+
return new Uint8Array(A.buffer, A.byteOffset, A.byteLength);
|
|
104
|
+
throw new Error("Invalid data type!");
|
|
105
|
+
}, X = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", z = new Uint8Array(256);
|
|
106
|
+
for (let A = 0; A < X.length; A++)
|
|
107
|
+
z[X.charCodeAt(A)] = A;
|
|
108
|
+
function P(A) {
|
|
109
|
+
let g = Math.floor(A.length * 0.75);
|
|
110
|
+
const I = A.length;
|
|
111
|
+
return A[I - 1] === "=" && (g -= 1, A[I - 2] === "=" && (g -= 1)), g;
|
|
112
|
+
}
|
|
113
|
+
function v(A) {
|
|
114
|
+
const g = P(A), I = A.length, E = new Uint8Array(g);
|
|
115
|
+
let Q = 0;
|
|
116
|
+
for (let n = 0; n < I; n += 4) {
|
|
117
|
+
const o = z[A.charCodeAt(n)], y = z[A.charCodeAt(n + 1)], N = z[A.charCodeAt(n + 2)], t = z[A.charCodeAt(n + 3)];
|
|
118
|
+
E[Q] = o << 2 | y >> 4, Q += 1, E[Q] = (y & 15) << 4 | N >> 2, Q += 1, E[Q] = (N & 3) << 6 | t & 63, Q += 1;
|
|
119
|
+
}
|
|
120
|
+
return E;
|
|
121
|
+
}
|
|
122
|
+
const q = 16 * 1024, D = 4, j = new i(), R = /* @__PURE__ */ new Map();
|
|
123
|
+
function _(A, g) {
|
|
124
|
+
return F(this, void 0, void 0, function* () {
|
|
125
|
+
let I = null, E = null, Q = !1;
|
|
126
|
+
if (typeof WebAssembly > "u")
|
|
127
|
+
throw new Error("WebAssembly is not supported in this environment!");
|
|
128
|
+
const n = (B, c = 0) => {
|
|
129
|
+
E.set(B, c);
|
|
130
|
+
}, o = () => E, y = () => I.exports, N = (B) => {
|
|
131
|
+
I.exports.Hash_SetMemorySize(B);
|
|
132
|
+
const c = I.exports.Hash_GetBuffer(), d = I.exports.memory.buffer;
|
|
133
|
+
E = new Uint8Array(d, c, B);
|
|
134
|
+
}, t = () => new DataView(I.exports.memory.buffer).getUint32(I.exports.STATE_SIZE, !0), e = j.dispatch(() => F(this, void 0, void 0, function* () {
|
|
135
|
+
if (!R.has(A.name)) {
|
|
136
|
+
const c = v(A.data), d = WebAssembly.compile(c);
|
|
137
|
+
R.set(A.name, d);
|
|
138
|
+
}
|
|
139
|
+
const B = yield R.get(A.name);
|
|
140
|
+
I = yield WebAssembly.instantiate(B, {
|
|
141
|
+
// env: {
|
|
142
|
+
// emscripten_memcpy_big: (dest, src, num) => {
|
|
143
|
+
// const memoryBuffer = wasmInstance.exports.memory.buffer;
|
|
144
|
+
// const memView = new Uint8Array(memoryBuffer, 0);
|
|
145
|
+
// memView.set(memView.subarray(src, src + num), dest);
|
|
146
|
+
// },
|
|
147
|
+
// print_memory: (offset, len) => {
|
|
148
|
+
// const memoryBuffer = wasmInstance.exports.memory.buffer;
|
|
149
|
+
// const memView = new Uint8Array(memoryBuffer, 0);
|
|
150
|
+
// console.log('print_int32', memView.subarray(offset, offset + len));
|
|
151
|
+
// },
|
|
152
|
+
// },
|
|
153
|
+
});
|
|
154
|
+
})), C = () => F(this, void 0, void 0, function* () {
|
|
155
|
+
I || (yield e);
|
|
156
|
+
const B = I.exports.Hash_GetBuffer(), c = I.exports.memory.buffer;
|
|
157
|
+
E = new Uint8Array(c, B, q);
|
|
158
|
+
}), f = (B = null) => {
|
|
159
|
+
Q = !0, I.exports.Hash_Init(B);
|
|
160
|
+
}, m = (B) => {
|
|
161
|
+
let c = 0;
|
|
162
|
+
for (; c < B.length; ) {
|
|
163
|
+
const d = B.subarray(c, c + q);
|
|
164
|
+
c += d.length, E.set(d), I.exports.Hash_Update(d.length);
|
|
165
|
+
}
|
|
166
|
+
}, k = (B) => {
|
|
167
|
+
if (!Q)
|
|
168
|
+
throw new Error("update() called before init()");
|
|
169
|
+
const c = u(B);
|
|
170
|
+
m(c);
|
|
171
|
+
}, S = new Uint8Array(g * 2), p = (B, c = null) => {
|
|
172
|
+
if (!Q)
|
|
173
|
+
throw new Error("digest() called before init()");
|
|
174
|
+
return Q = !1, I.exports.Hash_Final(c), B === "binary" ? E.slice(0, g) : U(S, E, g);
|
|
175
|
+
}, Z = () => {
|
|
176
|
+
if (!Q)
|
|
177
|
+
throw new Error("save() can only be called after init() and before digest()");
|
|
178
|
+
const B = I.exports.Hash_GetState(), c = t(), d = I.exports.memory.buffer, a = new Uint8Array(d, B, c), s = new Uint8Array(D + c);
|
|
179
|
+
return W(s, A.hash), s.set(a, D), s;
|
|
180
|
+
}, Y = (B) => {
|
|
181
|
+
if (!(B instanceof Uint8Array))
|
|
182
|
+
throw new Error("load() expects an Uint8Array generated by save()");
|
|
183
|
+
const c = I.exports.Hash_GetState(), d = t(), a = D + d, s = I.exports.memory.buffer;
|
|
184
|
+
if (B.length !== a)
|
|
185
|
+
throw new Error(\`Bad state length (expected \${a} bytes, got \${B.length})\`);
|
|
186
|
+
if (!O(A.hash, B.subarray(0, D)))
|
|
187
|
+
throw new Error("This state was written by an incompatible hash implementation");
|
|
188
|
+
const b = B.subarray(D);
|
|
189
|
+
new Uint8Array(s, c, d).set(b), Q = !0;
|
|
190
|
+
}, l = (B) => typeof B == "string" ? B.length < q / 4 : B.byteLength < q;
|
|
191
|
+
let r = l;
|
|
192
|
+
switch (A.name) {
|
|
193
|
+
case "argon2":
|
|
194
|
+
case "scrypt":
|
|
195
|
+
r = () => !0;
|
|
196
|
+
break;
|
|
197
|
+
case "blake2b":
|
|
198
|
+
case "blake2s":
|
|
199
|
+
r = (B, c) => c <= 512 && l(B);
|
|
200
|
+
break;
|
|
201
|
+
case "blake3":
|
|
202
|
+
r = (B, c) => c === 0 && l(B);
|
|
203
|
+
break;
|
|
204
|
+
case "xxhash64":
|
|
205
|
+
// cannot simplify
|
|
206
|
+
case "xxhash3":
|
|
207
|
+
case "xxhash128":
|
|
208
|
+
case "crc64":
|
|
209
|
+
r = () => !1;
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
const T = (B, c = null, d = null) => {
|
|
213
|
+
if (!r(B, c))
|
|
214
|
+
return f(c), k(B), p("hex", d);
|
|
215
|
+
const a = u(B);
|
|
216
|
+
return E.set(a), I.exports.Hash_Calculate(a.length, c, d), U(S, E, g);
|
|
217
|
+
};
|
|
218
|
+
return yield C(), {
|
|
219
|
+
getMemory: o,
|
|
220
|
+
writeMemory: n,
|
|
221
|
+
getExports: y,
|
|
222
|
+
setMemorySize: N,
|
|
223
|
+
init: f,
|
|
224
|
+
update: k,
|
|
225
|
+
digest: p,
|
|
226
|
+
save: Z,
|
|
227
|
+
load: Y,
|
|
228
|
+
calculate: T,
|
|
229
|
+
hashLength: g
|
|
230
|
+
};
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
new i();
|
|
234
|
+
new i();
|
|
235
|
+
new i();
|
|
236
|
+
new i();
|
|
237
|
+
new i();
|
|
238
|
+
new i();
|
|
239
|
+
new i();
|
|
240
|
+
new i();
|
|
241
|
+
new i();
|
|
242
|
+
new i();
|
|
243
|
+
new i();
|
|
244
|
+
var $ = "sha256", AA = "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c2pBx6KerX1qIhkgASADcyACcSABIANxcyABQR53IAFBE3dzIAFBCndzaiAaaiICaiIJIBMgEnNxIBJzaiAJQRp3IAlBFXdzIAlBB3dzakHRxqk2aiIaIAIgAXMgA3EgAiABcXMgAkEedyACQRN3cyACQQp3c2ogGGoiA2oiESAJIBNzcSATc2ogEUEadyARQRV3cyARQQd3c2pB59KkoQFqIhggAyACcyABcSADIAJxcyADQR53IANBE3dzIANBCndzaiAUaiIBaiISIBEgCXNxIAlzaiASQRp3IBJBFXdzIBJBB3dzakGFldy9AmoiFCABIANzIAJxIAEgA3FzIAFBHncgAUETd3MgAUEKd3NqIBdqIgJqIhMgI2ogJiASaiAiIBFqICUgCWogEyASIBFzcSARc2ogE0EadyATQRV3cyATQQd3c2pBuMLs8AJqIhcgAiABcyADcSACIAFxcyACQR53IAJBE3dzIAJBCndzaiAZaiIDaiIJIBMgEnNxIBJzaiAJQRp3IAlBFXdzIAlBB3dzakH827HpBGoiGSADIAJzIAFxIAMgAnFzIANBHncgA0ETd3MgA0EKd3NqIBpqIgFqIhEgCSATc3EgE3NqIBFBGncgEUEVd3MgEUEHd3NqQZOa4JkFaiIaIAEgA3MgAnEgASADcXMgAUEedyABQRN3cyABQQp3c2ogGGoiAmoiEiARIAlzcSAJc2ogEkEadyASQRV3cyASQQd3c2pB1OapqAZqIhggAiABcyADcSACIAFxcyACQR53IAJBE3dzIAJBCndzaiAUaiIDaiITaiAoIBJqICQgEWogJyAJaiATIBIgEXNxIBFzaiATQRp3IBNBFXdzIBNBB3dzakG7laizB2oiFCADIAJzIAFxIAMgAnFzIANBHncgA0ETd3MgA0EKd3NqIBdqIgFqIgkgEyASc3EgEnNqIAlBGncgCUEVd3MgCUEHd3NqQa6Si454aiIXIAEgA3MgAnEgASADcXMgAUEedyABQRN3cyABQQp3c2ogGWoiAmoiESAJIBNzcSATc2ogEUEadyARQRV3cyARQQd3c2pBhdnIk3lqIhkgAiABcyADcSACIAFxcyACQR53IAJBE3dzIAJBCndzaiAaaiIDaiISIBEgCXNxIAlzaiASQRp3IBJBFXdzIBJBB3dzakGh0f+VemoiGiADIAJz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", IA = "8c18dd94", gA = {
|
|
245
|
+
name: $,
|
|
246
|
+
data: AA,
|
|
247
|
+
hash: IA
|
|
248
|
+
};
|
|
249
|
+
new i();
|
|
250
|
+
new i();
|
|
251
|
+
function BA() {
|
|
252
|
+
return _(gA, 32).then((A) => {
|
|
253
|
+
A.init(256);
|
|
254
|
+
const g = {
|
|
255
|
+
init: () => (A.init(256), g),
|
|
256
|
+
update: (I) => (A.update(I), g),
|
|
257
|
+
// biome-ignore lint/suspicious/noExplicitAny: Conflict with IHasher type
|
|
258
|
+
digest: (I) => A.digest(I),
|
|
259
|
+
save: () => A.save(),
|
|
260
|
+
load: (I) => (A.load(I), g),
|
|
261
|
+
blockSize: 64,
|
|
262
|
+
digestSize: 32
|
|
263
|
+
};
|
|
264
|
+
return g;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
new i();
|
|
268
|
+
new i();
|
|
269
|
+
new i();
|
|
270
|
+
new i();
|
|
271
|
+
new i();
|
|
272
|
+
new i();
|
|
273
|
+
new i();
|
|
274
|
+
new i();
|
|
275
|
+
new i();
|
|
276
|
+
let J = null;
|
|
277
|
+
async function w() {
|
|
278
|
+
return J || (J = BA().then((A) => (A.init(), A))), J;
|
|
279
|
+
}
|
|
280
|
+
self.addEventListener("message", async (A) => {
|
|
281
|
+
const g = A.data;
|
|
282
|
+
try {
|
|
283
|
+
if (g.type === "update")
|
|
284
|
+
(await w()).update(new Uint8Array(g.chunk));
|
|
285
|
+
else if (g.type === "finish") {
|
|
286
|
+
const Q = { type: "done", hex: (await w()).digest("hex") };
|
|
287
|
+
self.postMessage(Q);
|
|
288
|
+
}
|
|
289
|
+
} catch (I) {
|
|
290
|
+
const E = { type: "error", error: I instanceof Error ? I.message : String(I) };
|
|
291
|
+
self.postMessage(E);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
`,J=typeof self<"u"&&self.Blob&&new Blob(["URL.revokeObjectURL(import.meta.url);",b],{type:"text/javascript;charset=utf-8"});function O(n){let A;try{if(A=J&&(self.URL||self.webkitURL).createObjectURL(J),!A)throw"";const e=new Worker(A,{type:"module",name:n==null?void 0:n.name});return e.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(A)}),e}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(b),{type:"module",name:n==null?void 0:n.name})}}const W=8*1024*1024,_=4,G=50,x=4*1024*1024,H=3;class f extends Error{constructor(A="Upload aborted"){super(A),this.name="AbortError"}}function j(n,A){return new Promise((e,I)=>{if(A!=null&&A.aborted){I(new f);return}const t=setTimeout(()=>{A==null||A.removeEventListener("abort",c),e()},n),c=()=>{clearTimeout(t),I(new f)};A==null||A.addEventListener("abort",c,{once:!0})})}function D(n){if(n!=null&&n.aborted)throw new f}async function $(n,A){return(await n.post("/api/file/upload/init",{original_name:A.name,content_type:A.type})).data.data}async function AA(n,A,e){return(await n.post("/api/file/upload/list-parts",{object_key:A,upload_id:e})).data.data.parts}async function X(n,A,e,I){const t={};for(let c=0;c<I.length;c+=G){const g=I.slice(c,c+G),i=await n.post("/api/file/upload/sign-parts",{object_key:A,upload_id:e,part_numbers:g});Object.assign(t,i.data.data.urls)}return t}async function eA(n,A,e,I,t,c){return(await n.post("/api/file/upload/complete",{object_key:A,upload_id:e,parts:I.slice().sort((i,o)=>i.partNumber-o.partNumber).map(i=>({part_number:i.partNumber,etag:i.etag})),original_name:t,sha256:c})).data.data}async function nA(n,A,e){const I=await fetch(n,{method:"PUT",body:A,signal:e});if(!I.ok){const c=new Error(`PUT part failed: ${I.status}`);throw c.status=I.status,c}const t=I.headers.get("ETag")||I.headers.get("etag");if(!t)throw new Error("Missing ETag header in OSS response (check CORS ExposeHeader)");return t.replace(/^"|"$/g,"")}async function tA(n,A,e,I,t,c,g){let i=c,o=!1,r;for(let B=0;B<=H;B++){D(g);try{return await nA(i,t,g)}catch(E){if(E.name==="AbortError")throw E;if(r=E,E.status===403&&!o){i=(await X(n,A,e,[I]))[String(I)],o=!0;continue}if(B>=H)break;const z=1e3*Math.pow(2,B);await j(z,g)}}throw r instanceof Error?r:new Error("Part upload failed")}function IA(n,A){return new Promise((e,I)=>{let t;try{t=new O}catch(i){I(i);return}let c=!1;const g=()=>{c=!0,t.terminate(),I(new f)};A==null||A.addEventListener("abort",g,{once:!0}),t.addEventListener("message",i=>{const o=i.data;o.type==="done"?(A==null||A.removeEventListener("abort",g),t.terminate(),e(o.hex)):o.type==="error"&&(A==null||A.removeEventListener("abort",g),t.terminate(),I(new Error(o.error)))}),t.addEventListener("error",i=>{A==null||A.removeEventListener("abort",g),t.terminate(),I(new Error(i.message||"Hash worker error"))}),(async()=>{try{for(let i=0;i<n.size;i+=x){if(c)return;const o=Math.min(i+x,n.size),r=await n.slice(i,o).arrayBuffer();if(c)return;t.postMessage({type:"update",chunk:r},[r])}c||t.postMessage({type:"finish"})}catch(i){A==null||A.removeEventListener("abort",g),t.terminate(),I(i instanceof Error?i:new Error(String(i)))}})()})}async function iA(n,A,e={}){const{onProgress:I,onCheckpoint:t,signal:c}=e,g=e.partSize??W,i=e.parallel??_;D(c);let o,r,B=[],E=g;if(e.checkpoint){const a=e.checkpoint;if(a.fileSize!==A.size)throw new Error("Checkpoint fileSize does not match current file");o=a.objectKey,r=a.uploadId,E=a.partSize;const y=await AA(n,o,r),p=new Map(y.map(d=>[d.part_number,d.etag])),C=new Map(a.completedParts.map(d=>[d.partNumber,d.etag])),l=[];for(const[d,N]of p)C.get(d)===N&&l.push({partNumber:d,etag:N});B=l}else{const a=await $(n,A);o=a.object_key,r=a.upload_id}const R=Math.max(1,Math.ceil(A.size/E)),z=new Set(B.map(a=>a.partNumber)),s=[];for(let a=1;a<=R;a++)z.has(a)||s.push(a);const u=new V;let Q=B.reduce((a,y)=>{const p=(y.partNumber-1)*E,C=Math.min(p+E,A.size);return a+(C-p)},0);u.addSample(Q,Date.now());const F=()=>{if(!I)return;const a={percent:A.size===0?100:Q/A.size*100,loaded:Q,total:A.size,speed:u.getSpeed(),etaSec:u.getEtaSec(A.size,Q)};I(a)},T=()=>{if(!t)return;const a={objectKey:o,uploadId:r,partSize:E,completedParts:B.slice(),fileSize:A.size,originalName:A.name};t(a)};F();const Z=IA(A,c);if(s.length>0){const a=await X(n,o,r,s);let y=0;const p=()=>y>=s.length?null:s[y++],C=[];for(let l=0;l<Math.min(i,s.length);l++)C.push((async()=>{for(;;){D(c);const d=p();if(d===null)return;const N=(d-1)*E,w=Math.min(N+E,A.size),v=A.slice(N,w),S=a[String(d)];if(!S)throw new Error(`Missing signed URL for part ${d}`);const L=await tA(n,o,r,d,v,S,c);B.push({partNumber:d,etag:L}),Q+=w-N,u.addSample(Q,Date.now()),T(),F()}})());await Promise.all(C)}const k=await Z;D(c);const M=await eA(n,o,r,B,A.name,k);return{file_path:M.file_path,original_name:M.original_name,object_key:o,sha256:k}}async function cA(n,A,e){await n.post("/api/file/upload/abort",{object_key:A,upload_id:e})}class gA{constructor(){this.request=q.create({timeout:3e4}),this.setupRequestInterceptor(),this.setupResponseInterceptor()}setupRequestInterceptor(){this.request.interceptors.request.use(A=>{var i;const e=navigator.userAgent.toLowerCase(),I=e.includes("codatta")||((i=location.hash)==null?void 0:i.toLowerCase().includes("codatta")),t=U.get("auth")||localStorage.getItem("auth"),c=/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(e);t&&(A.headers.token=t);const g=U.get("uid")||localStorage.getItem("uid");return g&&(A.headers.uid=g),A.headers.channel=I?"codatta-ios-app":"codatta-platform-website",A.headers.device=c?"mobile":"web",A})}setupResponseInterceptor(){this.request.interceptors.response.use(A=>{const e=A.data,I=Object.getOwnPropertyNames(e).includes("code"),t=Object.getOwnPropertyNames(e).includes("success");return I&&(e==null?void 0:e.code)!=="000000"?Promise.reject(new q.AxiosError(e==null?void 0:e.message,e==null?void 0:e.code,A.config,A.request,A)):t&&(e==null?void 0:e.success)!==!0?Promise.reject(new q.AxiosError(e==null?void 0:e.errorMessage,e==null?void 0:e.errorCode,A.config,A.request,A)):A},A=>{if(A.status===401){localStorage.removeItem("uid"),localStorage.removeItem("token"),localStorage.removeItem("auth");const e=new URL(window.location.href),I=e.pathname+e.search;window.location.href=`/account/signin?from=${encodeURIComponent(I)}`}return Promise.reject(A)})}async getTaskDetail(A){return(await this.request.post("/api/v2/frontier/task/detail",{task_id:A})).data}async submitTask(A,e,I){return(await this.request.post("/api/v2/frontier/task/submit",{task_id:A,data_submission:{uid:I,data:e,task_id:A}})).data}async getTaskList(A){return(await this.request.post("/api/v2/frontier/task/list",A)).data}async getSubmissionList(A){return(await this.request.post("/api/v2/submission/list",A)).data}async getFrontierInfo(A){return(await this.request.get(`/api/v2/frontier/info?frontier_id=${A}`)).data}async getSubmissionDetail(A){return(await this.request.get("/api/v2/submission/user/detail",{params:{submission_id:A}})).data}async uploadFile(A,e){const I=new FormData;return I.append("file",A),(await this.request.post("/api/file/upload",I,{params:{content_type:A.type},onUploadProgress:e})).data}async uploadLargeFile(A,e){return iA(this.request,A,e)}async abortUpload(A,e){return cA(this.request,A,e)}async getSpecTaskInfo(A){return(await this.request.get(`/api/v2/spec/task/info?task_id=${A}`)).data}async getSpecTaskInfos(A){return(await this.request.get(`/api/v2/spec/task/infos?task_ids=${A}`)).data}async submitSpecTask(A,e,I){return(await this.request.post("/api/v2/spec/task/submit",{task_id:A,status:I??2,content:e})).data}async getVerificationCode({account_type:A,email:e,opt:I}){return(await this.request.post("/api/v2/user/get_code",{account_type:A??"email",email:e??"",opt:I??"verify"})).data.data}async checkEmail({email:A,code:e,task_id:I}){return(await this.request.post("/api/v2/frontier/email/check",{email:A,code:e,task_id:I})).data.data}}var K=(n=>(n.TWITTER="x",n.TELEGRAM="telegram",n.DISCORD="discord",n.WEBSITE="website",n.DOC="doc",n))(K||{});exports.FrontierSDK=gA;exports.MediaName=K;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,15 @@ import { AxiosProgressEvent } from 'axios';
|
|
|
2
2
|
|
|
3
3
|
export declare type ActiveStatus = 'ACTIVE' | 'INACTIVE' | 'COMPLETED';
|
|
4
4
|
|
|
5
|
+
export declare interface Checkpoint {
|
|
6
|
+
objectKey: string;
|
|
7
|
+
uploadId: string;
|
|
8
|
+
partSize: number;
|
|
9
|
+
completedParts: CompletedPart[];
|
|
10
|
+
fileSize: number;
|
|
11
|
+
originalName: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
5
14
|
export declare interface CMUDataRequirements {
|
|
6
15
|
num: string;
|
|
7
16
|
querytext: string;
|
|
@@ -24,6 +33,11 @@ export declare interface CMUDataRequirements {
|
|
|
24
33
|
};
|
|
25
34
|
}
|
|
26
35
|
|
|
36
|
+
export declare interface CompletedPart {
|
|
37
|
+
partNumber: number;
|
|
38
|
+
etag: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
27
41
|
export declare interface FashionQuestion {
|
|
28
42
|
content: object;
|
|
29
43
|
image_url: string;
|
|
@@ -122,6 +136,19 @@ export declare class FrontierSDK {
|
|
|
122
136
|
file_path: string;
|
|
123
137
|
original_name: string;
|
|
124
138
|
}>;
|
|
139
|
+
/**
|
|
140
|
+
* Upload a large file using presigned multipart upload (chunked + resumable).
|
|
141
|
+
* @param file - The `File` to upload.
|
|
142
|
+
* @param options - Optional progress/checkpoint callbacks, concurrency, part size, and AbortSignal.
|
|
143
|
+
* @returns Final object info including `file_path`, `object_key`, and `sha256`.
|
|
144
|
+
*/
|
|
145
|
+
uploadLargeFile(file: File, options?: LargeUploadOptions): Promise<LargeUploadResult>;
|
|
146
|
+
/**
|
|
147
|
+
* Abort an in-progress multipart upload so OSS can release the reserved parts immediately.
|
|
148
|
+
* @param object_key - The object key returned from `init`.
|
|
149
|
+
* @param upload_id - The upload ID returned from `init`.
|
|
150
|
+
*/
|
|
151
|
+
abortUpload(object_key: string, upload_id: string): Promise<void>;
|
|
125
152
|
/**
|
|
126
153
|
* Fetch the info of a single spec task.
|
|
127
154
|
* @param taskId - Unique task ID.
|
|
@@ -171,6 +198,22 @@ export declare class FrontierSDK {
|
|
|
171
198
|
}>;
|
|
172
199
|
}
|
|
173
200
|
|
|
201
|
+
export declare interface LargeUploadOptions {
|
|
202
|
+
onProgress?: (info: ProgressInfo) => void;
|
|
203
|
+
onCheckpoint?: (cp: Checkpoint) => void;
|
|
204
|
+
checkpoint?: Checkpoint;
|
|
205
|
+
partSize?: number;
|
|
206
|
+
parallel?: number;
|
|
207
|
+
signal?: AbortSignal;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export declare interface LargeUploadResult {
|
|
211
|
+
file_path: string;
|
|
212
|
+
original_name: string;
|
|
213
|
+
object_key: string;
|
|
214
|
+
sha256: string;
|
|
215
|
+
}
|
|
216
|
+
|
|
174
217
|
export declare enum MediaName {
|
|
175
218
|
TWITTER = "x",
|
|
176
219
|
TELEGRAM = "telegram",
|
|
@@ -194,6 +237,14 @@ export declare interface PaginationResponse<T> {
|
|
|
194
237
|
page_size: number;
|
|
195
238
|
}
|
|
196
239
|
|
|
240
|
+
export declare interface ProgressInfo {
|
|
241
|
+
percent: number;
|
|
242
|
+
loaded: number;
|
|
243
|
+
total: number;
|
|
244
|
+
speed: number;
|
|
245
|
+
etaSec: number;
|
|
246
|
+
}
|
|
247
|
+
|
|
197
248
|
export declare type RankingGrade = 'S' | 'A' | 'B' | 'C' | 'D';
|
|
198
249
|
|
|
199
250
|
/**
|
|
@@ -338,6 +389,9 @@ export declare interface TaskDetail {
|
|
|
338
389
|
tags: string[];
|
|
339
390
|
/** Reason provided by reviewer when the task is refused. */
|
|
340
391
|
audit_reason?: string;
|
|
392
|
+
today_complete_count: number;
|
|
393
|
+
total_complete_count: number;
|
|
394
|
+
total_count: number;
|
|
341
395
|
}
|
|
342
396
|
|
|
343
397
|
/**
|