aspect-sync 0.0.1

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.
@@ -0,0 +1,220 @@
1
+ import axios from "axios";
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ import { Readable } from "stream";
5
+ import { statusTracker } from "./statusTracker.js";
6
+ const CHUNK_SIZE = 20 * 1024 * 1024; // 20MB per part
7
+ const MAX_PART_UPLOAD_RETRIES = 3;
8
+ const MAX_FILE_UPLOAD_RETRIES = 3;
9
+ const sleep = (milliseconds) => {
10
+ return new Promise(resolve => setTimeout(resolve, milliseconds));
11
+ };
12
+ // Helper function to create a readable stream with progress tracking
13
+ function createProgressStream(buffer, onProgress) {
14
+ const PROGRESS_CHUNK_SIZE = 64 * 1024; // Report progress every 64KB
15
+ let offset = 0;
16
+ return new Readable({
17
+ read() {
18
+ if (offset >= buffer.length) {
19
+ this.push(null); // Signal end of stream
20
+ return;
21
+ }
22
+ const end = Math.min(offset + PROGRESS_CHUNK_SIZE, buffer.length);
23
+ const chunk = buffer.subarray(offset, end);
24
+ offset = end;
25
+ // Report progress
26
+ onProgress(offset);
27
+ this.push(chunk);
28
+ }
29
+ });
30
+ }
31
+ class SimpleWeightedTaskController {
32
+ #maxConcurrent;
33
+ #currentCount = 0;
34
+ #queue = [];
35
+ constructor(maxConcurrent) {
36
+ this.#maxConcurrent = maxConcurrent;
37
+ }
38
+ async acquire() {
39
+ if (this.#currentCount < this.#maxConcurrent) {
40
+ this.#currentCount++;
41
+ return;
42
+ }
43
+ return new Promise((resolve) => {
44
+ this.#queue.push(resolve);
45
+ });
46
+ }
47
+ release() {
48
+ const nextInQueue = this.#queue.shift();
49
+ if (nextInQueue) {
50
+ nextInQueue();
51
+ }
52
+ else {
53
+ this.#currentCount--;
54
+ }
55
+ }
56
+ }
57
+ export class Uploader {
58
+ #config;
59
+ #apiClient;
60
+ constructor(config) {
61
+ this.#config = config;
62
+ this.#apiClient = axios.create({
63
+ baseURL: config.apiUrl,
64
+ headers: {
65
+ "Authorization": `Bearer ${config.apiKey}`,
66
+ "Content-Type": "application/json",
67
+ }
68
+ });
69
+ }
70
+ async uploadFile(fileId, filePath, directoryId, taskController) {
71
+ let retryCount = 0;
72
+ while (retryCount <= MAX_FILE_UPLOAD_RETRIES) {
73
+ try {
74
+ await this.#uploadFileAttempt(fileId, filePath, directoryId, taskController);
75
+ statusTracker.markUploadSuccess(fileId);
76
+ return;
77
+ }
78
+ catch (error) {
79
+ retryCount++;
80
+ if (retryCount > MAX_FILE_UPLOAD_RETRIES) {
81
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
82
+ statusTracker.markUploadFailed(fileId, errorMessage);
83
+ throw error;
84
+ }
85
+ const backoffMs = 2000 * Math.pow(2, retryCount - 1);
86
+ console.error(`File ${fileId} upload attempt ${retryCount}/${MAX_FILE_UPLOAD_RETRIES} failed, retrying in ${backoffMs}ms...`, error);
87
+ statusTracker.resetFileForRetry(fileId);
88
+ await sleep(backoffMs);
89
+ }
90
+ }
91
+ }
92
+ async #uploadFileAttempt(fileId, filePath, directoryId, taskController) {
93
+ const fileStats = await fs.promises.stat(filePath);
94
+ const fileName = path.basename(filePath);
95
+ const { upload_id, asset_id } = await this.#initiateMultipartUpload(directoryId, fileName, fileStats.size);
96
+ const fileHandle = await fs.promises.open(filePath, "r");
97
+ const totalChunks = Math.ceil(fileStats.size / CHUNK_SIZE);
98
+ const parts = [];
99
+ const uploadedChunkBytes = new Array(totalChunks).fill(0);
100
+ const calculateTotalProgress = () => {
101
+ return uploadedChunkBytes.reduce((sum, bytes) => sum + bytes, 0);
102
+ };
103
+ const uploadOneChunk = async (chunkIndex) => {
104
+ const partNumber = chunkIndex + 1;
105
+ const start = chunkIndex * CHUNK_SIZE;
106
+ const end = Math.min(start + CHUNK_SIZE, fileStats.size);
107
+ const chunkSize = end - start;
108
+ const buffer = Buffer.alloc(chunkSize);
109
+ await fileHandle.read(buffer, 0, chunkSize, start);
110
+ const { url } = await this.#getMultipartPartUrl(asset_id, upload_id, partNumber);
111
+ // Create progress-tracking stream
112
+ const stream = createProgressStream(buffer, (bytesUploaded) => {
113
+ uploadedChunkBytes[chunkIndex] = bytesUploaded;
114
+ const totalProgress = calculateTotalProgress();
115
+ statusTracker.updateUploadProgress(fileId, totalProgress);
116
+ });
117
+ // Use native fetch with streaming body
118
+ const response = await fetch(url, {
119
+ method: "PUT",
120
+ body: stream, // Node.js accepts Readable streams
121
+ headers: {
122
+ "Content-Type": "",
123
+ "Content-Length": chunkSize.toString(),
124
+ },
125
+ // @ts-ignore - duplex is required for streaming request body in Node.js
126
+ duplex: "half",
127
+ });
128
+ if (!response.ok) {
129
+ throw new Error(`Upload failed with status ${response.status}: ${await response.text()}`);
130
+ }
131
+ const etag = response.headers.get("etag");
132
+ if (!etag) {
133
+ throw new Error(`No ETag returned for part ${partNumber}`);
134
+ }
135
+ parts.push({
136
+ part_number: partNumber,
137
+ etag: etag.replace(/"/g, ""),
138
+ });
139
+ uploadedChunkBytes[chunkIndex] = chunkSize;
140
+ statusTracker.updateUploadProgress(fileId, calculateTotalProgress());
141
+ };
142
+ const uploadOneChunkWithRetry = async (chunkIndex) => {
143
+ let lastError;
144
+ for (let attempt = 0; attempt < MAX_PART_UPLOAD_RETRIES; attempt++) {
145
+ try {
146
+ uploadedChunkBytes[chunkIndex] = 0;
147
+ statusTracker.updateUploadProgress(fileId, calculateTotalProgress());
148
+ await uploadOneChunk(chunkIndex);
149
+ return;
150
+ }
151
+ catch (error) {
152
+ lastError = error instanceof Error ? error : new Error(String(error));
153
+ if (attempt === MAX_PART_UPLOAD_RETRIES - 1) {
154
+ throw lastError;
155
+ }
156
+ uploadedChunkBytes[chunkIndex] = 0;
157
+ statusTracker.updateUploadProgress(fileId, calculateTotalProgress());
158
+ const backoffMs = 1000 * Math.pow(2, attempt);
159
+ console.error(`Part ${chunkIndex + 1} failed (attempt ${attempt + 1}/${MAX_PART_UPLOAD_RETRIES}), retrying in ${backoffMs}ms...`, lastError);
160
+ await sleep(backoffMs);
161
+ }
162
+ }
163
+ throw lastError || new Error("Unknown error during chunk upload");
164
+ };
165
+ const promises = [];
166
+ try {
167
+ for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
168
+ await taskController.acquire();
169
+ promises.push((async () => {
170
+ try {
171
+ await uploadOneChunkWithRetry(chunkIndex);
172
+ taskController.release();
173
+ }
174
+ catch (e) {
175
+ taskController.release();
176
+ throw e;
177
+ }
178
+ })());
179
+ }
180
+ await Promise.all(promises);
181
+ await this.#completeMultipartUpload(asset_id, upload_id, parts.sort((a, b) => a.part_number - b.part_number));
182
+ }
183
+ catch (error) {
184
+ await this.#abortMultipartUpload(asset_id, upload_id).catch(e => {
185
+ console.error("Failed to abort multipart upload:", e);
186
+ });
187
+ throw error;
188
+ }
189
+ finally {
190
+ await fileHandle.close();
191
+ }
192
+ }
193
+ async #initiateMultipartUpload(directoryId, fileName, sizeBytes) {
194
+ const response = await this.#apiClient.post("/assets/multipart/initiate", {
195
+ directory_id: directoryId,
196
+ name: fileName,
197
+ size_bytes: sizeBytes,
198
+ });
199
+ return response.data;
200
+ }
201
+ async #getMultipartPartUrl(assetId, uploadId, partNumber) {
202
+ const response = await this.#apiClient.get(`/assets/${assetId}/multipart/part/${partNumber}?upload_id=${encodeURIComponent(uploadId)}`);
203
+ return response.data;
204
+ }
205
+ async #completeMultipartUpload(assetId, uploadId, parts) {
206
+ await this.#apiClient.post(`/assets/${assetId}/multipart/complete`, {
207
+ upload_id: uploadId,
208
+ parts: parts,
209
+ });
210
+ }
211
+ async #abortMultipartUpload(assetId, uploadId) {
212
+ await this.#apiClient.post(`/assets/${assetId}/multipart/abort`, {
213
+ upload_id: uploadId,
214
+ });
215
+ }
216
+ }
217
+ export function createTaskController(maxConcurrent) {
218
+ return new SimpleWeightedTaskController(maxConcurrent);
219
+ }
220
+ //# sourceMappingURL=uploader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploader.js","sourceRoot":"","sources":["../src/uploader.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "aspect-sync",
3
+ "version": "0.0.1",
4
+ "description": "CLI tool to sync files from external services to Aspect via rclone",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "aspect-sync": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "README.md"
12
+ ],
13
+ "type": "module",
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "build:watch": "tsc --watch",
17
+ "dev": "tsx src/index.ts",
18
+ "clean": "rm -rf dist",
19
+ "prepublishOnly": "npm run clean && npm run build"
20
+ },
21
+ "keywords": [
22
+ "aspect",
23
+ "sync",
24
+ "rclone",
25
+ "cli",
26
+ "upload"
27
+ ],
28
+ "author": "Aspect Team",
29
+ "license": "MIT",
30
+ "homepage": "https://aspect.inc",
31
+ "dependencies": {
32
+ "@types/uuid": "^10.0.0",
33
+ "axios": "^1.11.0",
34
+ "chalk": "^5.3.0",
35
+ "commander": "^12.0.0",
36
+ "log-update": "^6.0.0",
37
+ "uuid": "^13.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^22.0.0",
41
+ "tsx": "^4.7.0",
42
+ "typescript": "^5.8.0"
43
+ },
44
+ "engines": {
45
+ "node": ">=22"
46
+ }
47
+ }