permaweb-deploy 3.2.1 → 3.4.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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"uploader-d40K7e4Z.js","sources":["../../src/utils/cache.ts","../../node_modules/.pnpm/yocto-queue@1.2.2/node_modules/yocto-queue/index.js","../../node_modules/.pnpm/p-limit@7.2.0/node_modules/p-limit/index.js","../../src/utils/uploader.ts"],"sourcesContent":["import crypto from 'node:crypto'\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport { CACHE_DIR, CACHE_FILE } from '../constants/cache.js'\n\nexport interface TransactionCacheEntry {\n createdAtTimestamp: number\n lastUsedTimestamp: number\n transactionId: string\n}\n\nexport type TransactionCache = Record<string, TransactionCacheEntry>\n\n/**\n * Get the path to the cache file in the current working directory\n */\nexport function getCachePath(): string {\n return path.join(process.cwd(), CACHE_DIR, CACHE_FILE)\n}\n\n/**\n * Load the transaction cache from disk\n * Returns an empty object if the cache file doesn't exist or is invalid\n */\nexport function loadCache(): TransactionCache {\n const cachePath = getCachePath()\n\n try {\n if (!fs.existsSync(cachePath)) {\n return {}\n }\n\n const content = fs.readFileSync(cachePath, 'utf8')\n return JSON.parse(content) as TransactionCache\n } catch {\n // If the cache is corrupted or unreadable, start fresh\n return {}\n }\n}\n\n/**\n * Save the transaction cache to disk\n * Creates the cache directory if it doesn't exist\n */\nexport function saveCache(cache: TransactionCache): void {\n const cachePath = getCachePath()\n const cacheDir = path.dirname(cachePath)\n\n if (!fs.existsSync(cacheDir)) {\n fs.mkdirSync(cacheDir, { recursive: true })\n }\n\n fs.writeFileSync(cachePath, JSON.stringify(cache, null, 2), 'utf8')\n}\n\n/**\n * Compute the SHA-256 hash of a file using streaming\n */\nexport async function hashFile(filePath: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const hash = crypto.createHash('sha256')\n const stream = fs.createReadStream(filePath)\n\n stream.on('data', (chunk) => hash.update(chunk))\n stream.on('end', () => resolve(hash.digest('hex')))\n stream.on('error', reject)\n })\n}\n\n/**\n * Recursively get all files in a directory\n * Returns relative paths from the base directory\n */\nexport function getAllFiles(dirPath: string, basePath: string = dirPath): string[] {\n const files: string[] = []\n\n for (const item of fs.readdirSync(dirPath)) {\n const fullPath = path.join(dirPath, item)\n const stats = fs.statSync(fullPath)\n\n if (stats.isDirectory()) {\n files.push(...getAllFiles(fullPath, basePath))\n } else {\n // Store relative path for consistent hashing\n files.push(path.relative(basePath, fullPath))\n }\n }\n\n return files\n}\n\n/**\n * Get a cached transaction entry by its file hash\n */\nexport function getCachedTransaction(\n cache: TransactionCache,\n hash: string,\n): TransactionCacheEntry | undefined {\n return cache[hash]\n}\n\n/**\n * Add or update a cache entry for a file hash\n * Updates lastUsedTimestamp if the entry already exists\n */\nexport function setCachedTransaction(\n cache: TransactionCache,\n hash: string,\n transactionId: string,\n): TransactionCache {\n const now = Date.now()\n const existing = cache[hash]\n\n return {\n ...cache,\n [hash]: {\n createdAtTimestamp: existing?.createdAtTimestamp ?? now,\n lastUsedTimestamp: now,\n transactionId,\n },\n }\n}\n\n/**\n * Update the lastUsedTimestamp for an existing cache entry\n */\nexport function touchCacheEntry(cache: TransactionCache, hash: string): TransactionCache {\n const existing = cache[hash]\n if (!existing) {\n return cache\n }\n\n return {\n ...cache,\n [hash]: {\n ...existing,\n lastUsedTimestamp: Date.now(),\n },\n }\n}\n\n/**\n * Clean up the cache by keeping only the most recently used entries\n * Entries are sorted by lastUsedTimestamp descending, keeping the newest maxEntries\n */\nexport function cleanupCache(cache: TransactionCache, maxEntries: number): TransactionCache {\n const entries = Object.entries(cache)\n\n if (entries.length <= maxEntries) {\n return cache\n }\n\n // Sort by lastUsedTimestamp descending (newest first)\n const sorted = entries.sort(([, a], [, b]) => b.lastUsedTimestamp - a.lastUsedTimestamp)\n\n // Keep only the newest maxEntries\n const kept = sorted.slice(0, maxEntries)\n\n return Object.fromEntries(kept)\n}\n","/*\nHow it works:\n`this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.\n*/\n\nclass Node {\n\tvalue;\n\tnext;\n\n\tconstructor(value) {\n\t\tthis.value = value;\n\t}\n}\n\nexport default class Queue {\n\t#head;\n\t#tail;\n\t#size;\n\n\tconstructor() {\n\t\tthis.clear();\n\t}\n\n\tenqueue(value) {\n\t\tconst node = new Node(value);\n\n\t\tif (this.#head) {\n\t\t\tthis.#tail.next = node;\n\t\t\tthis.#tail = node;\n\t\t} else {\n\t\t\tthis.#head = node;\n\t\t\tthis.#tail = node;\n\t\t}\n\n\t\tthis.#size++;\n\t}\n\n\tdequeue() {\n\t\tconst current = this.#head;\n\t\tif (!current) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#head = this.#head.next;\n\t\tthis.#size--;\n\n\t\t// Clean up tail reference when queue becomes empty\n\t\tif (!this.#head) {\n\t\t\tthis.#tail = undefined;\n\t\t}\n\n\t\treturn current.value;\n\t}\n\n\tpeek() {\n\t\tif (!this.#head) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this.#head.value;\n\n\t\t// TODO: Node.js 18.\n\t\t// return this.#head?.value;\n\t}\n\n\tclear() {\n\t\tthis.#head = undefined;\n\t\tthis.#tail = undefined;\n\t\tthis.#size = 0;\n\t}\n\n\tget size() {\n\t\treturn this.#size;\n\t}\n\n\t* [Symbol.iterator]() {\n\t\tlet current = this.#head;\n\n\t\twhile (current) {\n\t\t\tyield current.value;\n\t\t\tcurrent = current.next;\n\t\t}\n\t}\n\n\t* drain() {\n\t\twhile (this.#head) {\n\t\t\tyield this.dequeue();\n\t\t}\n\t}\n}\n","import Queue from 'yocto-queue';\n\nexport default function pLimit(concurrency) {\n\tvalidateConcurrency(concurrency);\n\n\tconst queue = new Queue();\n\tlet activeCount = 0;\n\n\tconst resumeNext = () => {\n\t\t// Process the next queued function if we're under the concurrency limit\n\t\tif (activeCount < concurrency && queue.size > 0) {\n\t\t\tactiveCount++;\n\t\t\tqueue.dequeue()();\n\t\t}\n\t};\n\n\tconst next = () => {\n\t\tactiveCount--;\n\t\tresumeNext();\n\t};\n\n\tconst run = async (function_, resolve, arguments_) => {\n\t\t// Execute the function and capture the result promise\n\t\tconst result = (async () => function_(...arguments_))();\n\n\t\t// Resolve immediately with the promise (don't wait for completion)\n\t\tresolve(result);\n\n\t\t// Wait for the function to complete (success or failure)\n\t\t// We catch errors here to prevent unhandled rejections,\n\t\t// but the original promise rejection is preserved for the caller\n\t\ttry {\n\t\t\tawait result;\n\t\t} catch {}\n\n\t\t// Decrement active count and process next queued function\n\t\tnext();\n\t};\n\n\tconst enqueue = (function_, resolve, arguments_) => {\n\t\t// Queue the internal resolve function instead of the run function\n\t\t// to preserve the asynchronous execution context.\n\t\tnew Promise(internalResolve => { // eslint-disable-line promise/param-names\n\t\t\tqueue.enqueue(internalResolve);\n\t\t}).then(run.bind(undefined, function_, resolve, arguments_)); // eslint-disable-line promise/prefer-await-to-then\n\n\t\t// Start processing immediately if we haven't reached the concurrency limit\n\t\tif (activeCount < concurrency) {\n\t\t\tresumeNext();\n\t\t}\n\t};\n\n\tconst generator = (function_, ...arguments_) => new Promise(resolve => {\n\t\tenqueue(function_, resolve, arguments_);\n\t});\n\n\tObject.defineProperties(generator, {\n\t\tactiveCount: {\n\t\t\tget: () => activeCount,\n\t\t},\n\t\tpendingCount: {\n\t\t\tget: () => queue.size,\n\t\t},\n\t\tclearQueue: {\n\t\t\tvalue() {\n\t\t\t\tqueue.clear();\n\t\t\t},\n\t\t},\n\t\tconcurrency: {\n\t\t\tget: () => concurrency,\n\n\t\t\tset(newConcurrency) {\n\t\t\t\tvalidateConcurrency(newConcurrency);\n\t\t\t\tconcurrency = newConcurrency;\n\n\t\t\t\tqueueMicrotask(() => {\n\t\t\t\t\t// eslint-disable-next-line no-unmodified-loop-condition\n\t\t\t\t\twhile (activeCount < concurrency && queue.size > 0) {\n\t\t\t\t\t\tresumeNext();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t},\n\t\tmap: {\n\t\t\tasync value(iterable, function_) {\n\t\t\t\tconst promises = Array.from(iterable, (value, index) => this(function_, value, index));\n\t\t\t\treturn Promise.all(promises);\n\t\t\t},\n\t\t},\n\t});\n\n\treturn generator;\n}\n\nexport function limitFunction(function_, options) {\n\tconst {concurrency} = options;\n\tconst limit = pLimit(concurrency);\n\n\treturn (...arguments_) => limit(() => function_(...arguments_));\n}\n\nfunction validateConcurrency(concurrency) {\n\tif (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {\n\t\tthrow new TypeError('Expected `concurrency` to be a number from 1 and up');\n\t}\n}\n","import path from 'node:path'\nimport { Readable } from 'node:stream'\n\nimport { OnDemandFunding, type TurboAuthenticatedClient } from '@ardrive/turbo-sdk'\nimport * as mime from 'mime-types'\nimport pLimit from 'p-limit'\n\nimport {\n getAllFiles,\n getCachedTransaction,\n hashFile,\n setCachedTransaction,\n touchCacheEntry,\n type TransactionCache,\n} from './cache.js'\n\nexport interface UploadResult {\n cacheHit: boolean\n transactionId: string\n updatedCache?: TransactionCache\n}\n\nexport interface FolderUploadResult extends UploadResult {\n /** Number of files that were cache hits (not re-uploaded) */\n cacheHits: number\n /** Total number of files in the folder */\n totalFiles: number\n /** Number of files that were uploaded */\n uploaded: number\n}\n\nexport async function uploadFile(\n turbo: TurboAuthenticatedClient,\n filePath: string,\n options?: {\n cache?: TransactionCache\n fundingMode?: OnDemandFunding\n },\n): Promise<UploadResult> {\n const mimeType = mime.lookup(filePath) || 'application/octet-stream'\n\n // Compute hash if cache is provided\n const fileHash = options?.cache ? await hashFile(filePath) : undefined\n\n // Check cache for hit\n if (fileHash && options?.cache) {\n const cached = getCachedTransaction(options.cache, fileHash)\n if (cached) {\n const updatedCache = touchCacheEntry(options.cache, fileHash)\n return {\n cacheHit: true,\n transactionId: cached.transactionId,\n updatedCache,\n }\n }\n }\n\n // Upload file\n const uploadResult = await turbo.uploadFile({\n dataItemOpts: {\n tags: [\n {\n name: 'App-Name',\n value: 'Permaweb-Deploy',\n },\n {\n name: 'anchor',\n value: new Date().toISOString(),\n },\n {\n name: 'Content-Type',\n value: mimeType,\n },\n ],\n },\n file: filePath,\n ...(options?.fundingMode && { fundingMode: options.fundingMode }),\n })\n\n if (!uploadResult?.id) {\n throw new Error('Failed to upload file: upload result missing transaction ID')\n }\n\n // Store in cache if provided\n if (fileHash && options?.cache) {\n const updatedCache = setCachedTransaction(options.cache, fileHash, uploadResult.id)\n return {\n cacheHit: false,\n transactionId: uploadResult.id,\n updatedCache,\n }\n }\n\n return {\n cacheHit: false,\n transactionId: uploadResult.id,\n }\n}\n\n/** Default concurrency for parallel file uploads */\nconst DEFAULT_UPLOAD_CONCURRENCY = 10\n\ninterface FileUploadTask {\n cached?: { transactionId: string }\n fullPath: string\n hash: string\n relativePath: string\n}\n\n/**\n * Upload a folder with per-file deduplication.\n * Each file is checked against the cache individually, and only uncached files are uploaded.\n * A manifest is then constructed and uploaded to create the folder structure.\n */\nexport async function uploadFolder(\n turbo: TurboAuthenticatedClient,\n folderPath: string,\n options?: {\n cache?: TransactionCache\n concurrency?: number\n fundingMode?: OnDemandFunding\n throwOnFailure?: boolean\n },\n): Promise<FolderUploadResult> {\n const concurrency = options?.concurrency ?? DEFAULT_UPLOAD_CONCURRENCY\n const useCache = options?.cache !== undefined\n\n // Get all files in the folder\n const relativePaths = getAllFiles(folderPath)\n\n if (relativePaths.length === 0) {\n throw new Error('Folder is empty, nothing to upload')\n }\n\n // Prepare file tasks with hashes (if caching is enabled)\n const tasks: FileUploadTask[] = await Promise.all(\n relativePaths.map(async (relativePath) => {\n const fullPath = path.join(folderPath, relativePath)\n const hash = useCache ? await hashFile(fullPath) : ''\n return { fullPath, hash, relativePath }\n }),\n )\n\n // Check cache for each file\n let cache = options?.cache ?? {}\n let cacheHits = 0\n\n for (const task of tasks) {\n if (useCache && task.hash) {\n const cached = getCachedTransaction(cache, task.hash)\n if (cached) {\n task.cached = { transactionId: cached.transactionId }\n cache = touchCacheEntry(cache, task.hash)\n cacheHits++\n }\n }\n }\n\n // If all files are cached, we still need to build and upload a new manifest\n // (because the manifest itself has a unique transaction ID each time)\n const uncachedTasks = tasks.filter((t) => !t.cached)\n\n // Upload uncached files with concurrency control using p-limit\n const limit = pLimit(concurrency)\n\n const uploadResults = await Promise.all(\n uncachedTasks.map((task) =>\n limit(async () => {\n const mimeType = mime.lookup(task.fullPath) || 'application/octet-stream'\n\n const uploadResult = await turbo.uploadFile({\n dataItemOpts: {\n tags: [\n { name: 'App-Name', value: 'Permaweb-Deploy' },\n { name: 'Content-Type', value: mimeType },\n ],\n },\n file: task.fullPath,\n ...(options?.fundingMode && { fundingMode: options.fundingMode }),\n })\n\n if (!uploadResult?.id) {\n if (options?.throwOnFailure) {\n throw new Error(`Failed to upload file: ${task.relativePath}`)\n }\n\n return { hash: task.hash, task, transactionId: null }\n }\n\n return { hash: task.hash, task, transactionId: uploadResult.id }\n }),\n ),\n )\n\n // Update cache with all successful uploads (done sequentially to avoid race conditions)\n for (const result of uploadResults) {\n if (useCache && result.hash && result.transactionId) {\n cache = setCachedTransaction(cache, result.hash, result.transactionId)\n }\n }\n\n // Check for any failed uploads\n const failedUploads = uploadResults.filter((r) => r.transactionId === null)\n if (failedUploads.length > 0 && options?.throwOnFailure) {\n throw new Error(\n `Failed to upload ${failedUploads.length} file(s): ${failedUploads.map((f) => f.task.relativePath).join(', ')}`,\n )\n }\n\n // Build manifest paths from cached and newly uploaded files\n const manifestPaths: Record<string, { id: string }> = {}\n\n for (const task of tasks) {\n let transactionId: string | null = null\n\n if (task.cached) {\n transactionId = task.cached.transactionId\n } else {\n const uploadResult = uploadResults.find((r) => r.task === task)\n transactionId = uploadResult?.transactionId ?? null\n }\n\n if (transactionId) {\n manifestPaths[task.relativePath] = { id: transactionId }\n\n // Add directory index support: if file is dir/index.html, also add dir → same ID\n if (task.relativePath.endsWith('/index.html')) {\n const dirPath = task.relativePath.replace(/\\/index\\.html$/, '')\n manifestPaths[dirPath] = { id: transactionId }\n }\n }\n }\n\n // Determine the index path (root index.html)\n const indexPath = relativePaths.includes('index.html') ? 'index.html' : undefined\n\n // Build the manifest\n const manifest = {\n manifest: 'arweave/paths',\n version: '0.2.0',\n ...(indexPath && { index: { path: indexPath } }),\n paths: manifestPaths,\n }\n\n // Upload the manifest\n const manifestBuffer = Buffer.from(JSON.stringify(manifest))\n const manifestUploadResult = await turbo.uploadFile({\n dataItemOpts: {\n tags: [\n { name: 'App-Name', value: 'Permaweb-Deploy' },\n { name: 'Content-Type', value: 'application/x.arweave-manifest+json' },\n ],\n },\n fileSizeFactory: () => manifestBuffer.length,\n fileStreamFactory: () => Readable.from(manifestBuffer),\n ...(options?.fundingMode && { fundingMode: options.fundingMode }),\n })\n\n if (!manifestUploadResult?.id) {\n throw new Error('Failed to upload manifest: upload result missing transaction ID')\n }\n\n return {\n cacheHit: cacheHits === tasks.length,\n cacheHits,\n totalFiles: tasks.length,\n transactionId: manifestUploadResult.id,\n updatedCache: useCache ? cache : undefined,\n uploaded: uncachedTasks.length - failedUploads.length,\n }\n}\n"],"names":[],"mappings":"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","x_google_ignoreList":[1,2]}