@uploadista/client-browser 1.0.0-beta.4 → 1.0.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uploadista/client-browser",
3
3
  "type": "module",
4
- "version": "1.0.0-beta.4",
4
+ "version": "1.0.0",
5
5
  "description": "Browser client for Uploadista",
6
6
  "license": "MIT",
7
7
  "author": "Uploadista",
@@ -25,14 +25,14 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "js-base64": "3.8.0",
28
- "@uploadista/core": "1.0.0-beta.4",
29
- "@uploadista/client-core": "1.0.0-beta.4"
28
+ "@uploadista/core": "1.0.0",
29
+ "@uploadista/client-core": "1.0.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "happy-dom": "20.4.0",
33
33
  "tsdown": "0.22.3",
34
- "vitest": "4.0.18",
35
- "@uploadista/typescript-config": "1.0.0-beta.4"
34
+ "vitest": "4.1.10",
35
+ "@uploadista/typescript-config": "1.0.0"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "tsc --noEmit && tsdown",
@@ -8,15 +8,17 @@ import { afterEach, vi } from "vitest";
8
8
 
9
9
  // Mock crypto.subtle for tests that need it
10
10
  const mockSubtle = {
11
- digest: vi.fn().mockImplementation(async (_algorithm: string, data: ArrayBuffer) => {
12
- // Return a mock hash based on data length for testing
13
- const mockHash = new Uint8Array(32);
14
- const view = new Uint8Array(data);
15
- for (let i = 0; i < 32; i++) {
16
- mockHash[i] = (view[i % view.length] || 0) ^ (i * 7);
17
- }
18
- return mockHash.buffer;
19
- }),
11
+ digest: vi
12
+ .fn()
13
+ .mockImplementation(async (_algorithm: string, data: ArrayBuffer) => {
14
+ // Return a mock hash based on data length for testing
15
+ const mockHash = new Uint8Array(32);
16
+ const view = new Uint8Array(data);
17
+ for (let i = 0; i < 32; i++) {
18
+ mockHash[i] = (view[i % view.length] || 0) ^ (i * 7);
19
+ }
20
+ return mockHash.buffer;
21
+ }),
20
22
  };
21
23
 
22
24
  // Mock crypto.randomUUID
@@ -20,8 +20,8 @@ import {
20
20
  isImageFile,
21
21
  isNetworkError,
22
22
  isVideoFile,
23
- validateFileType,
24
23
  type UploadItem,
24
+ validateFileType,
25
25
  } from "./framework-utils";
26
26
 
27
27
  describe("formatFileSize", () => {
@@ -209,14 +209,18 @@ describe("validateFileType", () => {
209
209
  describe("createFileSizeValidator", () => {
210
210
  it("should pass files under the size limit", () => {
211
211
  const validator = createFileSizeValidator(1024 * 1024); // 1MB
212
- const file = new File(["x".repeat(100)], "small.txt", { type: "text/plain" });
212
+ const file = new File(["x".repeat(100)], "small.txt", {
213
+ type: "text/plain",
214
+ });
213
215
  const result = validator(file);
214
216
  expect(result.valid).toBe(true);
215
217
  });
216
218
 
217
219
  it("should fail files over the size limit", () => {
218
220
  const validator = createFileSizeValidator(100);
219
- const file = new File(["x".repeat(200)], "large.txt", { type: "text/plain" });
221
+ const file = new File(["x".repeat(200)], "large.txt", {
222
+ type: "text/plain",
223
+ });
220
224
  const result = validator(file);
221
225
  expect(result.valid).toBe(false);
222
226
  expect(result.error).toContain("exceeds maximum");
@@ -62,7 +62,7 @@ describe("createHttpClient", () => {
62
62
  headers: expect.objectContaining({
63
63
  Connection: "keep-alive",
64
64
  }),
65
- })
65
+ }),
66
66
  );
67
67
  expect(response.status).toBe(200);
68
68
  expect(response.ok).toBe(true);
@@ -93,7 +93,7 @@ describe("createHttpClient", () => {
93
93
  expect.objectContaining({
94
94
  method: "POST",
95
95
  body,
96
- })
96
+ }),
97
97
  );
98
98
  expect(response.status).toBe(201);
99
99
  });
@@ -123,7 +123,7 @@ describe("createHttpClient", () => {
123
123
  clearTimeout(timeoutId);
124
124
  reject(new DOMException("Aborted", "AbortError"));
125
125
  });
126
- })
126
+ }),
127
127
  );
128
128
 
129
129
  const client = createHttpClient();
@@ -131,7 +131,7 @@ describe("createHttpClient", () => {
131
131
  await expect(
132
132
  client.request("https://api.example.com/slow", {
133
133
  timeout: 50,
134
- })
134
+ }),
135
135
  ).rejects.toThrow();
136
136
 
137
137
  // Restore fake timers for other tests
@@ -161,7 +161,7 @@ describe("createHttpClient", () => {
161
161
  "https://api.example.com/data",
162
162
  expect.objectContaining({
163
163
  signal: expect.any(AbortSignal),
164
- })
164
+ }),
165
165
  );
166
166
  });
167
167
 
@@ -184,7 +184,7 @@ describe("createHttpClient", () => {
184
184
  "https://api.example.com/data",
185
185
  expect.objectContaining({
186
186
  credentials: "include",
187
- })
187
+ }),
188
188
  );
189
189
  });
190
190
 
@@ -194,7 +194,7 @@ describe("createHttpClient", () => {
194
194
  const client = createHttpClient();
195
195
 
196
196
  await expect(
197
- client.request("https://api.example.com/data")
197
+ client.request("https://api.example.com/data"),
198
198
  ).rejects.toThrow("Network error");
199
199
  });
200
200
  });
@@ -312,13 +312,13 @@ describe("createHttpClient", () => {
312
312
  "https://api1.example.com",
313
313
  expect.objectContaining({
314
314
  method: "HEAD",
315
- })
315
+ }),
316
316
  );
317
317
  expect(mockFetch).toHaveBeenCalledWith(
318
318
  "https://api2.example.com",
319
319
  expect.objectContaining({
320
320
  method: "HEAD",
321
- })
321
+ }),
322
322
  );
323
323
  });
324
324
 
@@ -329,7 +329,7 @@ describe("createHttpClient", () => {
329
329
 
330
330
  // Should not throw
331
331
  await expect(
332
- client.warmupConnections(["https://api.example.com"])
332
+ client.warmupConnections(["https://api.example.com"]),
333
333
  ).resolves.not.toThrow();
334
334
  });
335
335
 
@@ -1,5 +1,8 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { createBrowserServices, type BrowserServiceOptions } from "./create-browser-services";
2
+ import {
3
+ type BrowserServiceOptions,
4
+ createBrowserServices,
5
+ } from "./create-browser-services";
3
6
 
4
7
  describe("createBrowserServices", () => {
5
8
  it("should create a service container with default options", () => {
@@ -186,7 +189,7 @@ describe("createBrowserServices", () => {
186
189
 
187
190
  const fingerprint = await services.fingerprintService.computeFingerprint(
188
191
  file,
189
- "https://api.example.com"
192
+ "https://api.example.com",
190
193
  );
191
194
 
192
195
  expect(fingerprint).toBeDefined();
@@ -216,7 +219,7 @@ describe("createBrowserServices", () => {
216
219
  // 4. Compute fingerprint for deduplication
217
220
  const fingerprint = await services.fingerprintService.computeFingerprint(
218
221
  file,
219
- "https://api.example.com"
222
+ "https://api.example.com",
220
223
  );
221
224
  expect(fingerprint).toHaveLength(64);
222
225
 
@@ -231,7 +234,7 @@ describe("createBrowserServices", () => {
231
234
  id: uploadId,
232
235
  fingerprint,
233
236
  status: "pending",
234
- })
237
+ }),
235
238
  );
236
239
 
237
240
  // 7. Retrieve stored state
@@ -44,7 +44,7 @@ describe("createBrowserFileReaderService", () => {
44
44
  const service = createBrowserFileReaderService();
45
45
 
46
46
  await expect(
47
- service.openFile("invalid" as unknown as Blob, 1024)
47
+ service.openFile("invalid" as unknown as Blob, 1024),
48
48
  ).rejects.toThrow("source object may only be an instance of File, Blob");
49
49
  });
50
50
  });
@@ -110,7 +110,9 @@ describe("createBrowserFileReaderService", () => {
110
110
  it("should handle binary data", async () => {
111
111
  const service = createBrowserFileReaderService();
112
112
  const binaryData = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
113
- const blob = new Blob([binaryData], { type: "application/octet-stream" });
113
+ const blob = new Blob([binaryData], {
114
+ type: "application/octet-stream",
115
+ });
114
116
 
115
117
  const source = await service.openFile(blob, 1024);
116
118
  const result = await source.slice(0, 5);
@@ -156,7 +158,7 @@ describe("createBrowserFileReaderService", () => {
156
158
 
157
159
  // Verify combined content
158
160
  const combined = new Uint8Array(
159
- chunks.reduce((acc, chunk) => acc + chunk.length, 0)
161
+ chunks.reduce((acc, chunk) => acc + chunk.length, 0),
160
162
  );
161
163
  let pos = 0;
162
164
  for (const chunk of chunks) {
@@ -18,7 +18,7 @@ describe("createFingerprintService", () => {
18
18
 
19
19
  const fingerprint = await service.computeFingerprint(
20
20
  file,
21
- "https://api.example.com"
21
+ "https://api.example.com",
22
22
  );
23
23
 
24
24
  // Should return a 64-character hex string (SHA-256)
@@ -32,7 +32,7 @@ describe("createFingerprintService", () => {
32
32
 
33
33
  const fingerprint = await service.computeFingerprint(
34
34
  blob,
35
- "https://api.example.com"
35
+ "https://api.example.com",
36
36
  );
37
37
 
38
38
  expect(fingerprint).toHaveLength(64);
@@ -47,11 +47,11 @@ describe("createFingerprintService", () => {
47
47
 
48
48
  const fingerprint1 = await service.computeFingerprint(
49
49
  file1,
50
- "https://api.example.com"
50
+ "https://api.example.com",
51
51
  );
52
52
  const fingerprint2 = await service.computeFingerprint(
53
53
  file2,
54
- "https://api.example.com"
54
+ "https://api.example.com",
55
55
  );
56
56
 
57
57
  expect(fingerprint1).toBe(fingerprint2);
@@ -59,16 +59,20 @@ describe("createFingerprintService", () => {
59
59
 
60
60
  it("should return different fingerprint for different files", async () => {
61
61
  const service = createFingerprintService();
62
- const file1 = new File(["Content A"], "file1.txt", { type: "text/plain" });
63
- const file2 = new File(["Content B"], "file2.txt", { type: "text/plain" });
62
+ const file1 = new File(["Content A"], "file1.txt", {
63
+ type: "text/plain",
64
+ });
65
+ const file2 = new File(["Content B"], "file2.txt", {
66
+ type: "text/plain",
67
+ });
64
68
 
65
69
  const fingerprint1 = await service.computeFingerprint(
66
70
  file1,
67
- "https://api.example.com"
71
+ "https://api.example.com",
68
72
  );
69
73
  const fingerprint2 = await service.computeFingerprint(
70
74
  file2,
71
- "https://api.example.com"
75
+ "https://api.example.com",
72
76
  );
73
77
 
74
78
  expect(fingerprint1).not.toBe(fingerprint2);
@@ -82,11 +86,11 @@ describe("createFingerprintService", () => {
82
86
 
83
87
  const fingerprint1 = await service.computeFingerprint(
84
88
  file,
85
- "https://api1.example.com"
89
+ "https://api1.example.com",
86
90
  );
87
91
  const fingerprint2 = await service.computeFingerprint(
88
92
  file,
89
- "https://api2.example.com"
93
+ "https://api2.example.com",
90
94
  );
91
95
 
92
96
  // The current implementation ignores the endpoint
@@ -99,7 +103,7 @@ describe("createFingerprintService", () => {
99
103
 
100
104
  const fingerprint = await service.computeFingerprint(
101
105
  file,
102
- "https://api.example.com"
106
+ "https://api.example.com",
103
107
  );
104
108
 
105
109
  expect(fingerprint).toHaveLength(64);
@@ -113,7 +117,7 @@ describe("createFingerprintService", () => {
113
117
 
114
118
  const fingerprint = await service.computeFingerprint(
115
119
  blob,
116
- "https://api.example.com"
120
+ "https://api.example.com",
117
121
  );
118
122
 
119
123
  expect(fingerprint).toHaveLength(64);
@@ -16,7 +16,7 @@ describe("createBrowserIdGenerationService", () => {
16
16
 
17
17
  // UUID v4 format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
18
18
  expect(id).toMatch(
19
- /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
19
+ /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
20
20
  );
21
21
  });
22
22
 
@@ -72,7 +72,7 @@ describe("computeblobSha256", () => {
72
72
  const blob = new Blob(["test"], { type: "text/plain" });
73
73
 
74
74
  await expect(computeblobSha256(blob)).rejects.toThrow(
75
- "Failed to compute file checksum"
75
+ "Failed to compute file checksum",
76
76
  );
77
77
 
78
78
  // Restore original