@autonomys/auto-files 1.4.34

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 ADDED
@@ -0,0 +1 @@
1
+ # auto-files
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@autonomys/auto-files",
3
+ "version": "1.4.34",
4
+ "packageManager": "yarn@4.7.0",
5
+ "private": false,
6
+ "scripts": {
7
+ "build": "tsc"
8
+ },
9
+ "devDependencies": {
10
+ "typescript": "^5.5.4"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "require": "./dist/index.js",
15
+ "import": "./dist/index.js",
16
+ "types": "./dist/index.d.ts"
17
+ }
18
+ },
19
+ "dependencies": {
20
+ "@autonomys/auto-drive": "^1.4.34"
21
+ }
22
+ }
package/src/api.ts ADDED
@@ -0,0 +1,106 @@
1
+ import { CompressionOptions, EncryptionOptions } from '@autonomys/auto-drive'
2
+ import { Readable } from 'stream'
3
+ import { withRetries } from './utils'
4
+
5
+ interface FetchedFile {
6
+ length: bigint
7
+ compression: CompressionOptions | undefined
8
+ encryption: EncryptionOptions | undefined
9
+ data: Readable
10
+ }
11
+
12
+ /**
13
+ * Creates an API client for interacting with the Auto Files service
14
+ * @param baseUrl - The base URL of the Auto Files API
15
+ * @param apiSecret - The API secret key for authentication
16
+ * @returns An object containing methods to interact with the API
17
+ */
18
+ export const createAutoFilesApi = (baseUrl: string, apiSecret: string) => {
19
+ /**
20
+ * Makes an authenticated fetch request to the API
21
+ * @param url - The URL to fetch from
22
+ * @param options - Optional fetch request options
23
+ * @returns A Promise that resolves to the fetch Response
24
+ */
25
+ const authFetch = (url: string, options: RequestInit = {}) => {
26
+ const urlObj = new URL(url)
27
+ return fetch(urlObj.toString(), {
28
+ ...options,
29
+ headers: { ...options.headers, Authorization: `Bearer ${apiSecret}` },
30
+ })
31
+ }
32
+
33
+ /**
34
+ * Fetches a specific chunk of a file from the API
35
+ * @param cid - The content identifier of the file
36
+ * @param chunk - The chunk number to fetch
37
+ * @returns A Promise that resolves to the chunk data as ArrayBuffer, or null if chunk doesn't exist
38
+ * @throws Error if the chunk fetch fails
39
+ */
40
+ const getChunk = async (cid: string, chunk: number): Promise<ArrayBuffer | null> => {
41
+ const response = await authFetch(`${baseUrl}/files/${cid}/partial?chunk=${chunk}`)
42
+ if (!response.ok) {
43
+ throw new Error('Error fetching chunk')
44
+ }
45
+
46
+ if (response.status === 204) {
47
+ return null
48
+ }
49
+
50
+ const buffer = await response.arrayBuffer()
51
+ console.log('Chunk download finished:', buffer.byteLength)
52
+ return buffer
53
+ }
54
+
55
+ /**
56
+ * Fetches a complete file from the API with support for progress tracking and retries
57
+ * @param cid - The content identifier of the file to fetch
58
+ * @param options - Optional configuration for the fetch operation
59
+ * @param options.retriesPerFetch - Number of retry attempts for failed requests (default: 3)
60
+ * @param options.onProgress - Optional callback function to track download progress (0-1)
61
+ * @returns A Promise that resolves to a FetchedFile object containing the file data and metadata
62
+ * @throws Error if the file metadata fetch fails
63
+ */
64
+ const getFile = async (
65
+ cid: string,
66
+ {
67
+ retriesPerFetch = 3,
68
+ onProgress,
69
+ }: { retriesPerFetch?: number; onProgress?: (progress: number) => void } = {},
70
+ ): Promise<FetchedFile> => {
71
+ const response = await withRetries(
72
+ () => authFetch(`${baseUrl}/files/${cid}/metadata`),
73
+ retriesPerFetch,
74
+ )
75
+ if (!response.ok) {
76
+ throw new Error('Error fetching file header')
77
+ }
78
+
79
+ const metadata = await response.json()
80
+
81
+ // Parse size from string to bigint
82
+ const length = BigInt(metadata.size ?? 0)
83
+
84
+ const compression = metadata.uploadOptions?.compression
85
+ const encryption = metadata.uploadOptions?.encryption
86
+
87
+ let i = 0
88
+ let totalDownloaded = BigInt(0)
89
+ const precision = 10 ** 4
90
+ return {
91
+ data: new Readable({
92
+ async read() {
93
+ const chunk = await withRetries(() => getChunk(cid, i++), retriesPerFetch)
94
+ this.push(chunk ? Buffer.from(chunk) : null)
95
+ totalDownloaded += BigInt(chunk?.byteLength ?? 0)
96
+ onProgress?.(Number((BigInt(precision) * totalDownloaded) / length) / precision)
97
+ },
98
+ }),
99
+ length,
100
+ compression,
101
+ encryption,
102
+ }
103
+ }
104
+
105
+ return { getFile }
106
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './api'
package/src/utils.ts ADDED
@@ -0,0 +1,18 @@
1
+ export const withRetries = <T>(fn: () => Promise<T>, retries: number, delay: number = 1000) => {
2
+ return new Promise<T>((resolve, reject) => {
3
+ const attempt = async () => {
4
+ try {
5
+ const result = await fn()
6
+ resolve(result)
7
+ } catch (error) {
8
+ if (retries > 0) {
9
+ await new Promise((resolve) => setTimeout(resolve, delay))
10
+ attempt()
11
+ } else {
12
+ reject(error)
13
+ }
14
+ }
15
+ }
16
+ attempt()
17
+ })
18
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "module": "Node16",
7
+ "moduleResolution": "Node16",
8
+ "resolveJsonModule": true
9
+ },
10
+ "include": ["src"]
11
+ }