takanawa-node 0.3.1 → 0.4.3

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 CHANGED
@@ -1,6 +1,7 @@
1
1
  # takanawa-node
2
2
 
3
- Node.js and Electron bindings for Takanawa, built with napi-rs and wrapped with a Vite + TypeScript API.
3
+ Node.js and Electron bindings for Takanawa, built with napi-rs and wrapped with
4
+ the shared Takanawa TypeScript API.
4
5
 
5
6
  ## Development
6
7
 
@@ -13,7 +14,7 @@ The package builds the native Node-API addon first, then emits the TypeScript wr
13
14
  ## Usage
14
15
 
15
16
  ```ts
16
- import { DownloadTask, downloadToCompletion } from '@yetanother.ai/takanawa'
17
+ import { DownloadTask, downloadToCompletion } from 'takanawa-node'
17
18
 
18
19
  await downloadToCompletion({
19
20
  url: 'https://example.com/file.zip',
@@ -30,11 +31,20 @@ const task = new DownloadTask({
30
31
  targetPath: '/tmp/file.zip'
31
32
  })
32
33
 
33
- task.start()
34
- console.log(task.snapshot())
34
+ const progress = await task.addProgressListener((snapshot) => {
35
+ console.log(snapshot.phase, snapshot.downloadedBytes, snapshot.contentLen)
36
+ })
37
+
38
+ await task.start()
39
+ console.log(await task.snapshot())
40
+
41
+ await progress.remove()
42
+ await task.close()
35
43
  ```
36
44
 
37
- Large byte counts are exposed as `bigint` in the TypeScript API so Node and Electron callers do not lose precision.
45
+ The public API matches the other Takanawa npm targets. Task methods return
46
+ promises, and large byte counts are exposed as `bigint` so callers do not lose
47
+ precision.
38
48
 
39
49
  `hash` supports `sha1`, `sha256`, `sha512`, `md5`, and `crc32` expected
40
50
  digests. You can also pass a compact string such as `sha512:<hex>`. The legacy
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("node:module");var h=typeof document<"u"?document.currentScript:null;const g=4;function b(e){class t{#e;#a;#t;#i=!1;#n=new Set;constructor(r){this.#e=r}async start(){await e.start(await this.#r())}async pause(){await e.pause(await this.#r())}async cancel(){await e.cancel(await this.#r())}async snapshot(){return l(await e.snapshot(await this.#r()))}async bitmap(){return e.bitmap(await this.#r())}async close(){if(this.#i)return;this.#i=!0;const r=[...this.#n];this.#n.clear(),await Promise.all(r.map(c=>c.remove()));const n=this.#t;this.#t=void 0,this.#a=void 0,n!==void 0&&await e.close(await n)}async addProgressListener(r){const n=await this.#r(),c=await e.addProgressListener(n,u=>{r(l(u))});let d=!1;const s={remove:async()=>{d||(d=!0,this.#n.delete(s),await c.remove())}};this.#n.add(s);try{r(await this.snapshot())}catch(u){throw await s.remove(),u}return s}async#r(){if(this.#i)throw new Error("download task is closed");return this.#a!==void 0?this.#a:(this.#t===void 0&&(this.#t=Promise.resolve(e.create(m(this.#e))).then(r=>(this.#a=r,r),r=>{throw this.#t=void 0,r})),this.#t)}}async function a(i){return l(await e.downloadToCompletion(m(i)))}return{DownloadTask:t,downloadToCompletion:a}}function m(e){return{url:e.url,targetPath:e.targetPath,chunkSize:w(e.chunkSize,"chunkSize"),parallelism:e.parallelism,maxParallelChunks:e.maxParallelChunks,maxIo:S(e.maxIo),maxRetries:e.maxRetries,backoffInitialMs:e.backoffInitialMs,backoffMaxMs:e.backoffMaxMs,connectTimeoutMs:e.connectTimeoutMs,readTimeoutMs:e.readTimeoutMs,totalTimeoutMs:e.totalTimeoutMs,bytesPerSecondLimit:w(e.bytesPerSecondLimit,"bytesPerSecondLimit"),hash:x(e),sha256:void 0}}function x(e){if(e.hash!==void 0&&e.sha256!==void 0)throw new TypeError("use either hash or sha256, not both");if(e.hash===void 0)return e.sha256===void 0?void 0:{kind:"sha256",expected:e.sha256};if(typeof e.hash=="string"){const t=e.hash.indexOf(":");if(t===-1)throw new TypeError('hash string must use the format "kind:hex"');return{kind:f(e.hash.slice(0,t)),expected:e.hash.slice(t+1)}}return{kind:f(e.hash.kind),expected:e.hash.expected}}function f(e){switch(e.toLowerCase()){case"sha1":case"sha-1":return"sha1";case"sha256":case"sha-256":return"sha256";case"sha512":case"sha-512":return"sha512";case"md5":return"md5";case"crc32":case"crc-32":return"crc32";default:throw new TypeError(`unsupported hash kind: ${e}`)}}function l(e){return{phase:e.phase,contentLen:BigInt(e.contentLen),downloadedBytes:BigInt(e.downloadedBytes),chunkSize:BigInt(e.chunkSize),chunkCount:BigInt(e.chunkCount),completedChunks:BigInt(e.completedChunks),activeIo:e.activeIo,lastError:e.lastError}}function S(e){if(e===void 0)return g;if(!Number.isSafeInteger(e)||e<0)throw new TypeError("maxIo must be a non-negative safe integer");return Math.max(1,e)}function w(e,t){if(e===void 0)return;if(typeof e=="number"&&!Number.isSafeInteger(e))throw new TypeError(`${t} must be a safe integer number; pass a bigint or string for larger values`);const a=e.toString();if(!/^\d+$/.test(a))throw new TypeError(`expected an unsigned integer string for ${t}, got ${a}`);return a}const I=T.createRequire(typeof document>"u"?require("url").pathToFileURL(__filename).href:h&&h.tagName.toUpperCase()==="SCRIPT"&&h.src||new URL("index.cjs",document.baseURI).href),k=I("../index.js"),M=250,P={create(e){return new k.NativeDownloadTask(y(e))},start(e){e.start()},pause(e){e.pause()},cancel(e){e.cancel()},snapshot(e){return o(e.snapshot())},bitmap(e){return e.bitmap()},close(){},addProgressListener(e,t){let a=_(o(e.snapshot()));const i=setInterval(()=>{const r=o(e.snapshot()),n=_(r);n!==a&&(a=n,t(r))},M);return{async remove(){clearInterval(i)}}},async downloadToCompletion(e){return o(await k.nativeDownloadToCompletion(y(e)))}},v=b(P);class C{#e;constructor(t){this.#e=new v.DownloadTask(t)}start(){return this.#e.start()}pause(){return this.#e.pause()}cancel(){return this.#e.cancel()}snapshot(){return this.#e.snapshot()}bitmap(){return this.#e.bitmap()}close(){return this.#e.close()}addProgressListener(t){return this.#e.addProgressListener(t)}}function p(e){return v.downloadToCompletion(e)}function y(e){return{url:e.url,target_path:e.targetPath,chunk_size:e.chunkSize,parallelism:e.parallelism,max_parallel_chunks:e.maxParallelChunks,max_io:e.maxIo,max_retries:e.maxRetries,backoff_initial_ms:e.backoffInitialMs,backoff_max_ms:e.backoffMaxMs,connect_timeout_ms:e.connectTimeoutMs,read_timeout_ms:e.readTimeoutMs,total_timeout_ms:e.totalTimeoutMs,bytes_per_second_limit:e.bytesPerSecondLimit,hash:e.hash,sha256:void 0}}function o(e){return{phase:e.phase,contentLen:e.content_len,downloadedBytes:e.downloaded_bytes,chunkSize:e.chunk_size,chunkCount:e.chunk_count,completedChunks:e.completed_chunks,activeIo:e.active_io,lastError:e.last_error}}function _(e){return[e.phase,e.contentLen,e.downloadedBytes,e.chunkSize,e.chunkCount,e.completedChunks,e.activeIo,e.lastError??""].join("\0")}exports.DownloadTask=C;exports.downloadToCompletion=p;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../../takanawa-js-core/src/index.ts","../src/binding.ts","../src/index.ts"],"sourcesContent":["export type Awaitable<T> = T | Promise<T>\n\nexport type DownloadPhase =\n | 'created'\n | 'running'\n | 'pausing'\n | 'paused'\n | 'cancelling'\n | 'cancelled'\n | 'completed'\n | 'failed'\n\nexport type HashKind = 'sha1' | 'sha256' | 'sha512' | 'md5' | 'crc32'\n\nexport interface HashConfig {\n kind: HashKind\n expected: string\n}\n\nexport interface DownloadOptions {\n url: string\n targetPath: string\n chunkSize?: bigint | number | string\n parallelism?: number\n maxParallelChunks?: number\n maxIo?: number\n maxRetries?: number\n backoffInitialMs?: number\n backoffMaxMs?: number\n connectTimeoutMs?: number\n readTimeoutMs?: number\n totalTimeoutMs?: number\n bytesPerSecondLimit?: bigint | number | string\n hash?: HashConfig | `${HashKind}:${string}`\n /**\n * @deprecated Use `hash: { kind: 'sha256', expected: value }` instead.\n */\n sha256?: string\n}\n\nexport interface DownloadSnapshot {\n phase: DownloadPhase\n contentLen: bigint\n downloadedBytes: bigint\n chunkSize: bigint\n chunkCount: bigint\n completedChunks: bigint\n activeIo: number\n lastError?: string\n}\n\nexport type DownloadProgressListener = (snapshot: DownloadSnapshot) => void\n\nexport interface DownloadListenerHandle {\n remove(): Promise<void>\n}\n\nexport interface NormalizedHashConfig {\n kind: HashKind\n expected: string\n}\n\nexport interface NormalizedDownloadOptions {\n url: string\n targetPath: string\n chunkSize?: string\n parallelism?: number\n maxParallelChunks?: number\n maxIo: number\n maxRetries?: number\n backoffInitialMs?: number\n backoffMaxMs?: number\n connectTimeoutMs?: number\n readTimeoutMs?: number\n totalTimeoutMs?: number\n bytesPerSecondLimit?: string\n hash?: NormalizedHashConfig\n sha256?: undefined\n}\n\nexport interface NormalizedDownloadSnapshot {\n phase: string\n contentLen: string\n downloadedBytes: string\n chunkSize: string\n chunkCount: string\n completedChunks: string\n activeIo: number\n lastError?: string\n}\n\nexport interface TakanawaTargetAdapter<TTask> {\n create(options: NormalizedDownloadOptions): Awaitable<TTask>\n start(task: TTask): Awaitable<void>\n pause(task: TTask): Awaitable<void>\n cancel(task: TTask): Awaitable<void>\n snapshot(task: TTask): Awaitable<NormalizedDownloadSnapshot>\n bitmap(task: TTask): Awaitable<Uint8Array>\n close(task: TTask): Awaitable<void>\n addProgressListener(\n task: TTask,\n listener: (snapshot: NormalizedDownloadSnapshot) => void\n ): Awaitable<DownloadListenerHandle>\n downloadToCompletion(options: NormalizedDownloadOptions): Awaitable<NormalizedDownloadSnapshot>\n}\n\nconst DEFAULT_MAX_IO = 4\n\nexport function createTakanawaApi<TTask>(adapter: TakanawaTargetAdapter<TTask>) {\n class DownloadTask {\n readonly #options: DownloadOptions\n #task?: TTask\n #taskPromise?: Promise<TTask>\n #closed = false\n readonly #listenerHandles = new Set<DownloadListenerHandle>()\n\n constructor(options: DownloadOptions) {\n this.#options = options\n }\n\n async start(): Promise<void> {\n await adapter.start(await this.#ensureTask())\n }\n\n async pause(): Promise<void> {\n await adapter.pause(await this.#ensureTask())\n }\n\n async cancel(): Promise<void> {\n await adapter.cancel(await this.#ensureTask())\n }\n\n async snapshot(): Promise<DownloadSnapshot> {\n return mapSnapshot(await adapter.snapshot(await this.#ensureTask()))\n }\n\n async bitmap(): Promise<Uint8Array> {\n return adapter.bitmap(await this.#ensureTask())\n }\n\n async close(): Promise<void> {\n if (this.#closed) {\n return\n }\n this.#closed = true\n\n const listenerHandles = [...this.#listenerHandles]\n this.#listenerHandles.clear()\n await Promise.all(listenerHandles.map((handle) => handle.remove()))\n\n const taskPromise = this.#taskPromise\n this.#taskPromise = undefined\n this.#task = undefined\n if (taskPromise === undefined) {\n return\n }\n await adapter.close(await taskPromise)\n }\n\n async addProgressListener(listener: DownloadProgressListener): Promise<DownloadListenerHandle> {\n const task = await this.#ensureTask()\n const adapterHandle = await adapter.addProgressListener(task, (snapshot) => {\n listener(mapSnapshot(snapshot))\n })\n let removed = false\n const handle = {\n remove: async () => {\n if (removed) {\n return\n }\n removed = true\n this.#listenerHandles.delete(handle)\n await adapterHandle.remove()\n }\n } satisfies DownloadListenerHandle\n this.#listenerHandles.add(handle)\n\n try {\n listener(await this.snapshot())\n } catch (error) {\n await handle.remove()\n throw error\n }\n\n return handle\n }\n\n async #ensureTask(): Promise<TTask> {\n if (this.#closed) {\n throw new Error('download task is closed')\n }\n if (this.#task !== undefined) {\n return this.#task\n }\n if (this.#taskPromise === undefined) {\n this.#taskPromise = Promise.resolve(adapter.create(normalizeOptions(this.#options))).then(\n (task) => {\n this.#task = task\n return task\n },\n (error: unknown) => {\n this.#taskPromise = undefined\n throw error\n }\n )\n }\n return this.#taskPromise\n }\n }\n\n async function downloadToCompletion(options: DownloadOptions): Promise<DownloadSnapshot> {\n return mapSnapshot(await adapter.downloadToCompletion(normalizeOptions(options)))\n }\n\n return { DownloadTask, downloadToCompletion }\n}\n\nexport function normalizeOptions(options: DownloadOptions): NormalizedDownloadOptions {\n return {\n url: options.url,\n targetPath: options.targetPath,\n chunkSize: normalizeOptionalU64(options.chunkSize, 'chunkSize'),\n parallelism: options.parallelism,\n maxParallelChunks: options.maxParallelChunks,\n maxIo: normalizeMaxIo(options.maxIo),\n maxRetries: options.maxRetries,\n backoffInitialMs: options.backoffInitialMs,\n backoffMaxMs: options.backoffMaxMs,\n connectTimeoutMs: options.connectTimeoutMs,\n readTimeoutMs: options.readTimeoutMs,\n totalTimeoutMs: options.totalTimeoutMs,\n bytesPerSecondLimit: normalizeOptionalU64(options.bytesPerSecondLimit, 'bytesPerSecondLimit'),\n hash: normalizeHash(options),\n sha256: undefined\n }\n}\n\nexport function normalizeHash(options: DownloadOptions): NormalizedHashConfig | undefined {\n if (options.hash !== undefined && options.sha256 !== undefined) {\n throw new TypeError('use either hash or sha256, not both')\n }\n if (options.hash === undefined) {\n return options.sha256 === undefined ? undefined : { kind: 'sha256', expected: options.sha256 }\n }\n if (typeof options.hash === 'string') {\n const separator = options.hash.indexOf(':')\n if (separator === -1) {\n throw new TypeError('hash string must use the format \"kind:hex\"')\n }\n return {\n kind: normalizeHashKind(options.hash.slice(0, separator)),\n expected: options.hash.slice(separator + 1)\n }\n }\n return {\n kind: normalizeHashKind(options.hash.kind),\n expected: options.hash.expected\n }\n}\n\nexport function normalizeHashKind(kind: string): HashKind {\n switch (kind.toLowerCase()) {\n case 'sha1':\n case 'sha-1':\n return 'sha1'\n case 'sha256':\n case 'sha-256':\n return 'sha256'\n case 'sha512':\n case 'sha-512':\n return 'sha512'\n case 'md5':\n return 'md5'\n case 'crc32':\n case 'crc-32':\n return 'crc32'\n default:\n throw new TypeError(`unsupported hash kind: ${kind}`)\n }\n}\n\nexport function mapSnapshot(snapshot: NormalizedDownloadSnapshot): DownloadSnapshot {\n return {\n phase: snapshot.phase as DownloadPhase,\n contentLen: BigInt(snapshot.contentLen),\n downloadedBytes: BigInt(snapshot.downloadedBytes),\n chunkSize: BigInt(snapshot.chunkSize),\n chunkCount: BigInt(snapshot.chunkCount),\n completedChunks: BigInt(snapshot.completedChunks),\n activeIo: snapshot.activeIo,\n lastError: snapshot.lastError\n }\n}\n\nexport function decodeBase64ToUint8Array(data: string): Uint8Array {\n if (data.length === 0) {\n return new Uint8Array()\n }\n\n const bufferConstructor = (globalThis as { Buffer?: { from(data: string, encoding: 'base64'): Uint8Array } }).Buffer\n if (bufferConstructor !== undefined) {\n return Uint8Array.from(bufferConstructor.from(data, 'base64'))\n }\n\n const binary = globalThis.atob(data)\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index)\n }\n return bytes\n}\n\nfunction normalizeMaxIo(value: number | undefined): number {\n if (value === undefined) {\n return DEFAULT_MAX_IO\n }\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new TypeError('maxIo must be a non-negative safe integer')\n }\n return Math.max(1, value)\n}\n\nfunction normalizeOptionalU64(\n value: bigint | number | string | undefined,\n fieldName: string\n): string | undefined {\n if (value === undefined) {\n return undefined\n }\n if (typeof value === 'number' && !Number.isSafeInteger(value)) {\n throw new TypeError(`${fieldName} must be a safe integer number; pass a bigint or string for larger values`)\n }\n const text = value.toString()\n if (!/^\\d+$/.test(text)) {\n throw new TypeError(`expected an unsigned integer string for ${fieldName}, got ${text}`)\n }\n return text\n}\n","import { createRequire } from 'node:module'\n\nconst require = createRequire(import.meta.url)\n\nexport interface NativeDownloadOptions {\n url: string\n target_path: string\n chunk_size?: string\n parallelism?: number\n max_parallel_chunks?: number\n max_io?: number\n max_retries?: number\n backoff_initial_ms?: number\n backoff_max_ms?: number\n connect_timeout_ms?: number\n read_timeout_ms?: number\n total_timeout_ms?: number\n bytes_per_second_limit?: string\n hash?: NativeHashConfig\n sha256?: string\n}\n\nexport interface NativeHashConfig {\n kind: string\n expected: string\n}\n\nexport interface NativeDownloadSnapshot {\n phase: string\n content_len: string\n downloaded_bytes: string\n chunk_size: string\n chunk_count: string\n completed_chunks: string\n active_io: number\n last_error?: string\n}\n\nexport interface NativeDownloadTask {\n start(): void\n pause(): void\n cancel(): void\n snapshot(): NativeDownloadSnapshot\n bitmap(): Uint8Array\n}\n\nexport interface TakanawaNativeBinding {\n nativeDownloadToCompletion(options: NativeDownloadOptions): Promise<NativeDownloadSnapshot>\n NativeDownloadTask: new (options: NativeDownloadOptions) => NativeDownloadTask\n}\n\nexport const nativeBinding = require('../index.js') as TakanawaNativeBinding\n","import {\n createTakanawaApi,\n type DownloadListenerHandle as CoreDownloadListenerHandle,\n type DownloadOptions as CoreDownloadOptions,\n type DownloadProgressListener as CoreDownloadProgressListener,\n type DownloadSnapshot as CoreDownloadSnapshot,\n type NormalizedDownloadOptions,\n type NormalizedDownloadSnapshot,\n type TakanawaTargetAdapter\n} from 'takanawa-js-core'\n\nimport {\n nativeBinding,\n type NativeDownloadOptions,\n type NativeDownloadSnapshot,\n type NativeDownloadTask\n} from './binding'\n\nexport type DownloadPhase =\n | 'created'\n | 'running'\n | 'pausing'\n | 'paused'\n | 'cancelling'\n | 'cancelled'\n | 'completed'\n | 'failed'\n\nexport type HashKind = 'sha1' | 'sha256' | 'sha512' | 'md5' | 'crc32'\n\nexport interface HashConfig {\n kind: HashKind\n expected: string\n}\n\nexport interface DownloadOptions {\n url: string\n targetPath: string\n chunkSize?: bigint | number | string\n parallelism?: number\n maxParallelChunks?: number\n maxIo?: number\n maxRetries?: number\n backoffInitialMs?: number\n backoffMaxMs?: number\n connectTimeoutMs?: number\n readTimeoutMs?: number\n totalTimeoutMs?: number\n bytesPerSecondLimit?: bigint | number | string\n hash?: HashConfig | `${HashKind}:${string}`\n /**\n * @deprecated Use `hash: { kind: 'sha256', expected: value }` instead.\n */\n sha256?: string\n}\n\nexport interface DownloadSnapshot {\n phase: DownloadPhase\n contentLen: bigint\n downloadedBytes: bigint\n chunkSize: bigint\n chunkCount: bigint\n completedChunks: bigint\n activeIo: number\n lastError?: string\n}\n\nexport type DownloadProgressListener = (snapshot: DownloadSnapshot) => void\n\nexport interface DownloadListenerHandle {\n remove(): Promise<void>\n}\n\nconst PROGRESS_POLL_INTERVAL_MS = 250\n\nconst nodeAdapter: TakanawaTargetAdapter<NativeDownloadTask> = {\n create(options) {\n return new nativeBinding.NativeDownloadTask(toNativeOptions(options))\n },\n start(task) {\n task.start()\n },\n pause(task) {\n task.pause()\n },\n cancel(task) {\n task.cancel()\n },\n snapshot(task) {\n return fromNativeSnapshot(task.snapshot())\n },\n bitmap(task) {\n return task.bitmap()\n },\n close() {},\n addProgressListener(task, listener) {\n let previous = snapshotKey(fromNativeSnapshot(task.snapshot()))\n const timer = setInterval(() => {\n const snapshot = fromNativeSnapshot(task.snapshot())\n const key = snapshotKey(snapshot)\n if (key !== previous) {\n previous = key\n listener(snapshot)\n }\n }, PROGRESS_POLL_INTERVAL_MS)\n\n return {\n async remove() {\n clearInterval(timer)\n }\n } satisfies CoreDownloadListenerHandle\n },\n async downloadToCompletion(options) {\n return fromNativeSnapshot(await nativeBinding.nativeDownloadToCompletion(toNativeOptions(options)))\n }\n}\n\nconst nodeApi = createTakanawaApi(nodeAdapter)\n\nexport class DownloadTask {\n readonly #inner: InstanceType<typeof nodeApi.DownloadTask>\n\n constructor(options: DownloadOptions) {\n this.#inner = new nodeApi.DownloadTask(options as CoreDownloadOptions)\n }\n\n start(): Promise<void> {\n return this.#inner.start()\n }\n\n pause(): Promise<void> {\n return this.#inner.pause()\n }\n\n cancel(): Promise<void> {\n return this.#inner.cancel()\n }\n\n snapshot(): Promise<DownloadSnapshot> {\n return this.#inner.snapshot() as Promise<DownloadSnapshot>\n }\n\n bitmap(): Promise<Uint8Array> {\n return this.#inner.bitmap()\n }\n\n close(): Promise<void> {\n return this.#inner.close()\n }\n\n addProgressListener(listener: DownloadProgressListener): Promise<DownloadListenerHandle> {\n return this.#inner.addProgressListener(listener as CoreDownloadProgressListener)\n }\n}\n\nexport function downloadToCompletion(options: DownloadOptions): Promise<DownloadSnapshot> {\n return nodeApi.downloadToCompletion(options as CoreDownloadOptions) as Promise<CoreDownloadSnapshot> as Promise<DownloadSnapshot>\n}\n\nfunction toNativeOptions(options: NormalizedDownloadOptions): NativeDownloadOptions {\n return {\n url: options.url,\n target_path: options.targetPath,\n chunk_size: options.chunkSize,\n parallelism: options.parallelism,\n max_parallel_chunks: options.maxParallelChunks,\n max_io: options.maxIo,\n max_retries: options.maxRetries,\n backoff_initial_ms: options.backoffInitialMs,\n backoff_max_ms: options.backoffMaxMs,\n connect_timeout_ms: options.connectTimeoutMs,\n read_timeout_ms: options.readTimeoutMs,\n total_timeout_ms: options.totalTimeoutMs,\n bytes_per_second_limit: options.bytesPerSecondLimit,\n hash: options.hash,\n sha256: undefined\n }\n}\n\nfunction fromNativeSnapshot(snapshot: NativeDownloadSnapshot): NormalizedDownloadSnapshot {\n return {\n phase: snapshot.phase,\n contentLen: snapshot.content_len,\n downloadedBytes: snapshot.downloaded_bytes,\n chunkSize: snapshot.chunk_size,\n chunkCount: snapshot.chunk_count,\n completedChunks: snapshot.completed_chunks,\n activeIo: snapshot.active_io,\n lastError: snapshot.last_error\n }\n}\n\nfunction snapshotKey(snapshot: NormalizedDownloadSnapshot): string {\n return [\n snapshot.phase,\n snapshot.contentLen,\n snapshot.downloadedBytes,\n snapshot.chunkSize,\n snapshot.chunkCount,\n snapshot.completedChunks,\n snapshot.activeIo,\n snapshot.lastError ?? ''\n ].join('\\0')\n}\n"],"names":["DEFAULT_MAX_IO","createTakanawaApi","adapter","DownloadTask","#options","#task","#taskPromise","#closed","#listenerHandles","options","#ensureTask","mapSnapshot","listenerHandles","handle","taskPromise","listener","task","adapterHandle","snapshot","removed","error","normalizeOptions","downloadToCompletion","normalizeOptionalU64","normalizeMaxIo","normalizeHash","separator","normalizeHashKind","kind","value","fieldName","text","require","createRequire","nativeBinding","PROGRESS_POLL_INTERVAL_MS","nodeAdapter","toNativeOptions","fromNativeSnapshot","previous","snapshotKey","timer","key","nodeApi","#inner"],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ export type DownloadPhase = 'created' | 'running' | 'pausing' | 'paused' | 'cancelling' | 'cancelled' | 'completed' | 'failed';
2
+ export type HashKind = 'sha1' | 'sha256' | 'sha512' | 'md5' | 'crc32';
3
+ export interface HashConfig {
4
+ kind: HashKind;
5
+ expected: string;
6
+ }
7
+ export interface DownloadOptions {
8
+ url: string;
9
+ targetPath: string;
10
+ chunkSize?: bigint | number | string;
11
+ parallelism?: number;
12
+ maxParallelChunks?: number;
13
+ maxIo?: number;
14
+ maxRetries?: number;
15
+ backoffInitialMs?: number;
16
+ backoffMaxMs?: number;
17
+ connectTimeoutMs?: number;
18
+ readTimeoutMs?: number;
19
+ totalTimeoutMs?: number;
20
+ bytesPerSecondLimit?: bigint | number | string;
21
+ hash?: HashConfig | `${HashKind}:${string}`;
22
+ /**
23
+ * @deprecated Use `hash: { kind: 'sha256', expected: value }` instead.
24
+ */
25
+ sha256?: string;
26
+ }
27
+ export interface DownloadSnapshot {
28
+ phase: DownloadPhase;
29
+ contentLen: bigint;
30
+ downloadedBytes: bigint;
31
+ chunkSize: bigint;
32
+ chunkCount: bigint;
33
+ completedChunks: bigint;
34
+ activeIo: number;
35
+ lastError?: string;
36
+ }
37
+ export type DownloadProgressListener = (snapshot: DownloadSnapshot) => void;
38
+ export interface DownloadListenerHandle {
39
+ remove(): Promise<void>;
40
+ }
41
+ export declare class DownloadTask {
42
+ #private;
43
+ constructor(options: DownloadOptions);
44
+ start(): Promise<void>;
45
+ pause(): Promise<void>;
46
+ cancel(): Promise<void>;
47
+ snapshot(): Promise<DownloadSnapshot>;
48
+ bitmap(): Promise<Uint8Array>;
49
+ close(): Promise<void>;
50
+ addProgressListener(listener: DownloadProgressListener): Promise<DownloadListenerHandle>;
51
+ }
52
+ export declare function downloadToCompletion(options: DownloadOptions): Promise<DownloadSnapshot>;
package/dist/index.mjs ADDED
@@ -0,0 +1,272 @@
1
+ import { createRequire as _ } from "node:module";
2
+ const g = 4;
3
+ function x(e) {
4
+ class t {
5
+ #e;
6
+ #r;
7
+ #t;
8
+ #s = !1;
9
+ #n = /* @__PURE__ */ new Set();
10
+ constructor(a) {
11
+ this.#e = a;
12
+ }
13
+ async start() {
14
+ await e.start(await this.#a());
15
+ }
16
+ async pause() {
17
+ await e.pause(await this.#a());
18
+ }
19
+ async cancel() {
20
+ await e.cancel(await this.#a());
21
+ }
22
+ async snapshot() {
23
+ return u(await e.snapshot(await this.#a()));
24
+ }
25
+ async bitmap() {
26
+ return e.bitmap(await this.#a());
27
+ }
28
+ async close() {
29
+ if (this.#s)
30
+ return;
31
+ this.#s = !0;
32
+ const a = [...this.#n];
33
+ this.#n.clear(), await Promise.all(a.map((c) => c.remove()));
34
+ const n = this.#t;
35
+ this.#t = void 0, this.#r = void 0, n !== void 0 && await e.close(await n);
36
+ }
37
+ async addProgressListener(a) {
38
+ const n = await this.#a(), c = await e.addProgressListener(n, (h) => {
39
+ a(u(h));
40
+ });
41
+ let l = !1;
42
+ const i = {
43
+ remove: async () => {
44
+ l || (l = !0, this.#n.delete(i), await c.remove());
45
+ }
46
+ };
47
+ this.#n.add(i);
48
+ try {
49
+ a(await this.snapshot());
50
+ } catch (h) {
51
+ throw await i.remove(), h;
52
+ }
53
+ return i;
54
+ }
55
+ async #a() {
56
+ if (this.#s)
57
+ throw new Error("download task is closed");
58
+ return this.#r !== void 0 ? this.#r : (this.#t === void 0 && (this.#t = Promise.resolve(e.create(d(this.#e))).then(
59
+ (a) => (this.#r = a, a),
60
+ (a) => {
61
+ throw this.#t = void 0, a;
62
+ }
63
+ )), this.#t);
64
+ }
65
+ }
66
+ async function r(s) {
67
+ return u(await e.downloadToCompletion(d(s)));
68
+ }
69
+ return { DownloadTask: t, downloadToCompletion: r };
70
+ }
71
+ function d(e) {
72
+ return {
73
+ url: e.url,
74
+ targetPath: e.targetPath,
75
+ chunkSize: f(e.chunkSize, "chunkSize"),
76
+ parallelism: e.parallelism,
77
+ maxParallelChunks: e.maxParallelChunks,
78
+ maxIo: b(e.maxIo),
79
+ maxRetries: e.maxRetries,
80
+ backoffInitialMs: e.backoffInitialMs,
81
+ backoffMaxMs: e.backoffMaxMs,
82
+ connectTimeoutMs: e.connectTimeoutMs,
83
+ readTimeoutMs: e.readTimeoutMs,
84
+ totalTimeoutMs: e.totalTimeoutMs,
85
+ bytesPerSecondLimit: f(e.bytesPerSecondLimit, "bytesPerSecondLimit"),
86
+ hash: T(e),
87
+ sha256: void 0
88
+ };
89
+ }
90
+ function T(e) {
91
+ if (e.hash !== void 0 && e.sha256 !== void 0)
92
+ throw new TypeError("use either hash or sha256, not both");
93
+ if (e.hash === void 0)
94
+ return e.sha256 === void 0 ? void 0 : { kind: "sha256", expected: e.sha256 };
95
+ if (typeof e.hash == "string") {
96
+ const t = e.hash.indexOf(":");
97
+ if (t === -1)
98
+ throw new TypeError('hash string must use the format "kind:hex"');
99
+ return {
100
+ kind: m(e.hash.slice(0, t)),
101
+ expected: e.hash.slice(t + 1)
102
+ };
103
+ }
104
+ return {
105
+ kind: m(e.hash.kind),
106
+ expected: e.hash.expected
107
+ };
108
+ }
109
+ function m(e) {
110
+ switch (e.toLowerCase()) {
111
+ case "sha1":
112
+ case "sha-1":
113
+ return "sha1";
114
+ case "sha256":
115
+ case "sha-256":
116
+ return "sha256";
117
+ case "sha512":
118
+ case "sha-512":
119
+ return "sha512";
120
+ case "md5":
121
+ return "md5";
122
+ case "crc32":
123
+ case "crc-32":
124
+ return "crc32";
125
+ default:
126
+ throw new TypeError(`unsupported hash kind: ${e}`);
127
+ }
128
+ }
129
+ function u(e) {
130
+ return {
131
+ phase: e.phase,
132
+ contentLen: BigInt(e.contentLen),
133
+ downloadedBytes: BigInt(e.downloadedBytes),
134
+ chunkSize: BigInt(e.chunkSize),
135
+ chunkCount: BigInt(e.chunkCount),
136
+ completedChunks: BigInt(e.completedChunks),
137
+ activeIo: e.activeIo,
138
+ lastError: e.lastError
139
+ };
140
+ }
141
+ function b(e) {
142
+ if (e === void 0)
143
+ return g;
144
+ if (!Number.isSafeInteger(e) || e < 0)
145
+ throw new TypeError("maxIo must be a non-negative safe integer");
146
+ return Math.max(1, e);
147
+ }
148
+ function f(e, t) {
149
+ if (e === void 0)
150
+ return;
151
+ if (typeof e == "number" && !Number.isSafeInteger(e))
152
+ throw new TypeError(`${t} must be a safe integer number; pass a bigint or string for larger values`);
153
+ const r = e.toString();
154
+ if (!/^\d+$/.test(r))
155
+ throw new TypeError(`expected an unsigned integer string for ${t}, got ${r}`);
156
+ return r;
157
+ }
158
+ const I = _(import.meta.url), w = I("../index.js"), M = 250, P = {
159
+ create(e) {
160
+ return new w.NativeDownloadTask(k(e));
161
+ },
162
+ start(e) {
163
+ e.start();
164
+ },
165
+ pause(e) {
166
+ e.pause();
167
+ },
168
+ cancel(e) {
169
+ e.cancel();
170
+ },
171
+ snapshot(e) {
172
+ return o(e.snapshot());
173
+ },
174
+ bitmap(e) {
175
+ return e.bitmap();
176
+ },
177
+ close() {
178
+ },
179
+ addProgressListener(e, t) {
180
+ let r = y(o(e.snapshot()));
181
+ const s = setInterval(() => {
182
+ const a = o(e.snapshot()), n = y(a);
183
+ n !== r && (r = n, t(a));
184
+ }, M);
185
+ return {
186
+ async remove() {
187
+ clearInterval(s);
188
+ }
189
+ };
190
+ },
191
+ async downloadToCompletion(e) {
192
+ return o(await w.nativeDownloadToCompletion(k(e)));
193
+ }
194
+ }, v = x(P);
195
+ class C {
196
+ #e;
197
+ constructor(t) {
198
+ this.#e = new v.DownloadTask(t);
199
+ }
200
+ start() {
201
+ return this.#e.start();
202
+ }
203
+ pause() {
204
+ return this.#e.pause();
205
+ }
206
+ cancel() {
207
+ return this.#e.cancel();
208
+ }
209
+ snapshot() {
210
+ return this.#e.snapshot();
211
+ }
212
+ bitmap() {
213
+ return this.#e.bitmap();
214
+ }
215
+ close() {
216
+ return this.#e.close();
217
+ }
218
+ addProgressListener(t) {
219
+ return this.#e.addProgressListener(t);
220
+ }
221
+ }
222
+ function L(e) {
223
+ return v.downloadToCompletion(e);
224
+ }
225
+ function k(e) {
226
+ return {
227
+ url: e.url,
228
+ target_path: e.targetPath,
229
+ chunk_size: e.chunkSize,
230
+ parallelism: e.parallelism,
231
+ max_parallel_chunks: e.maxParallelChunks,
232
+ max_io: e.maxIo,
233
+ max_retries: e.maxRetries,
234
+ backoff_initial_ms: e.backoffInitialMs,
235
+ backoff_max_ms: e.backoffMaxMs,
236
+ connect_timeout_ms: e.connectTimeoutMs,
237
+ read_timeout_ms: e.readTimeoutMs,
238
+ total_timeout_ms: e.totalTimeoutMs,
239
+ bytes_per_second_limit: e.bytesPerSecondLimit,
240
+ hash: e.hash,
241
+ sha256: void 0
242
+ };
243
+ }
244
+ function o(e) {
245
+ return {
246
+ phase: e.phase,
247
+ contentLen: e.content_len,
248
+ downloadedBytes: e.downloaded_bytes,
249
+ chunkSize: e.chunk_size,
250
+ chunkCount: e.chunk_count,
251
+ completedChunks: e.completed_chunks,
252
+ activeIo: e.active_io,
253
+ lastError: e.last_error
254
+ };
255
+ }
256
+ function y(e) {
257
+ return [
258
+ e.phase,
259
+ e.contentLen,
260
+ e.downloadedBytes,
261
+ e.chunkSize,
262
+ e.chunkCount,
263
+ e.completedChunks,
264
+ e.activeIo,
265
+ e.lastError ?? ""
266
+ ].join("\0");
267
+ }
268
+ export {
269
+ C as DownloadTask,
270
+ L as downloadToCompletion
271
+ };
272
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../../takanawa-js-core/src/index.ts","../src/binding.ts","../src/index.ts"],"sourcesContent":["export type Awaitable<T> = T | Promise<T>\n\nexport type DownloadPhase =\n | 'created'\n | 'running'\n | 'pausing'\n | 'paused'\n | 'cancelling'\n | 'cancelled'\n | 'completed'\n | 'failed'\n\nexport type HashKind = 'sha1' | 'sha256' | 'sha512' | 'md5' | 'crc32'\n\nexport interface HashConfig {\n kind: HashKind\n expected: string\n}\n\nexport interface DownloadOptions {\n url: string\n targetPath: string\n chunkSize?: bigint | number | string\n parallelism?: number\n maxParallelChunks?: number\n maxIo?: number\n maxRetries?: number\n backoffInitialMs?: number\n backoffMaxMs?: number\n connectTimeoutMs?: number\n readTimeoutMs?: number\n totalTimeoutMs?: number\n bytesPerSecondLimit?: bigint | number | string\n hash?: HashConfig | `${HashKind}:${string}`\n /**\n * @deprecated Use `hash: { kind: 'sha256', expected: value }` instead.\n */\n sha256?: string\n}\n\nexport interface DownloadSnapshot {\n phase: DownloadPhase\n contentLen: bigint\n downloadedBytes: bigint\n chunkSize: bigint\n chunkCount: bigint\n completedChunks: bigint\n activeIo: number\n lastError?: string\n}\n\nexport type DownloadProgressListener = (snapshot: DownloadSnapshot) => void\n\nexport interface DownloadListenerHandle {\n remove(): Promise<void>\n}\n\nexport interface NormalizedHashConfig {\n kind: HashKind\n expected: string\n}\n\nexport interface NormalizedDownloadOptions {\n url: string\n targetPath: string\n chunkSize?: string\n parallelism?: number\n maxParallelChunks?: number\n maxIo: number\n maxRetries?: number\n backoffInitialMs?: number\n backoffMaxMs?: number\n connectTimeoutMs?: number\n readTimeoutMs?: number\n totalTimeoutMs?: number\n bytesPerSecondLimit?: string\n hash?: NormalizedHashConfig\n sha256?: undefined\n}\n\nexport interface NormalizedDownloadSnapshot {\n phase: string\n contentLen: string\n downloadedBytes: string\n chunkSize: string\n chunkCount: string\n completedChunks: string\n activeIo: number\n lastError?: string\n}\n\nexport interface TakanawaTargetAdapter<TTask> {\n create(options: NormalizedDownloadOptions): Awaitable<TTask>\n start(task: TTask): Awaitable<void>\n pause(task: TTask): Awaitable<void>\n cancel(task: TTask): Awaitable<void>\n snapshot(task: TTask): Awaitable<NormalizedDownloadSnapshot>\n bitmap(task: TTask): Awaitable<Uint8Array>\n close(task: TTask): Awaitable<void>\n addProgressListener(\n task: TTask,\n listener: (snapshot: NormalizedDownloadSnapshot) => void\n ): Awaitable<DownloadListenerHandle>\n downloadToCompletion(options: NormalizedDownloadOptions): Awaitable<NormalizedDownloadSnapshot>\n}\n\nconst DEFAULT_MAX_IO = 4\n\nexport function createTakanawaApi<TTask>(adapter: TakanawaTargetAdapter<TTask>) {\n class DownloadTask {\n readonly #options: DownloadOptions\n #task?: TTask\n #taskPromise?: Promise<TTask>\n #closed = false\n readonly #listenerHandles = new Set<DownloadListenerHandle>()\n\n constructor(options: DownloadOptions) {\n this.#options = options\n }\n\n async start(): Promise<void> {\n await adapter.start(await this.#ensureTask())\n }\n\n async pause(): Promise<void> {\n await adapter.pause(await this.#ensureTask())\n }\n\n async cancel(): Promise<void> {\n await adapter.cancel(await this.#ensureTask())\n }\n\n async snapshot(): Promise<DownloadSnapshot> {\n return mapSnapshot(await adapter.snapshot(await this.#ensureTask()))\n }\n\n async bitmap(): Promise<Uint8Array> {\n return adapter.bitmap(await this.#ensureTask())\n }\n\n async close(): Promise<void> {\n if (this.#closed) {\n return\n }\n this.#closed = true\n\n const listenerHandles = [...this.#listenerHandles]\n this.#listenerHandles.clear()\n await Promise.all(listenerHandles.map((handle) => handle.remove()))\n\n const taskPromise = this.#taskPromise\n this.#taskPromise = undefined\n this.#task = undefined\n if (taskPromise === undefined) {\n return\n }\n await adapter.close(await taskPromise)\n }\n\n async addProgressListener(listener: DownloadProgressListener): Promise<DownloadListenerHandle> {\n const task = await this.#ensureTask()\n const adapterHandle = await adapter.addProgressListener(task, (snapshot) => {\n listener(mapSnapshot(snapshot))\n })\n let removed = false\n const handle = {\n remove: async () => {\n if (removed) {\n return\n }\n removed = true\n this.#listenerHandles.delete(handle)\n await adapterHandle.remove()\n }\n } satisfies DownloadListenerHandle\n this.#listenerHandles.add(handle)\n\n try {\n listener(await this.snapshot())\n } catch (error) {\n await handle.remove()\n throw error\n }\n\n return handle\n }\n\n async #ensureTask(): Promise<TTask> {\n if (this.#closed) {\n throw new Error('download task is closed')\n }\n if (this.#task !== undefined) {\n return this.#task\n }\n if (this.#taskPromise === undefined) {\n this.#taskPromise = Promise.resolve(adapter.create(normalizeOptions(this.#options))).then(\n (task) => {\n this.#task = task\n return task\n },\n (error: unknown) => {\n this.#taskPromise = undefined\n throw error\n }\n )\n }\n return this.#taskPromise\n }\n }\n\n async function downloadToCompletion(options: DownloadOptions): Promise<DownloadSnapshot> {\n return mapSnapshot(await adapter.downloadToCompletion(normalizeOptions(options)))\n }\n\n return { DownloadTask, downloadToCompletion }\n}\n\nexport function normalizeOptions(options: DownloadOptions): NormalizedDownloadOptions {\n return {\n url: options.url,\n targetPath: options.targetPath,\n chunkSize: normalizeOptionalU64(options.chunkSize, 'chunkSize'),\n parallelism: options.parallelism,\n maxParallelChunks: options.maxParallelChunks,\n maxIo: normalizeMaxIo(options.maxIo),\n maxRetries: options.maxRetries,\n backoffInitialMs: options.backoffInitialMs,\n backoffMaxMs: options.backoffMaxMs,\n connectTimeoutMs: options.connectTimeoutMs,\n readTimeoutMs: options.readTimeoutMs,\n totalTimeoutMs: options.totalTimeoutMs,\n bytesPerSecondLimit: normalizeOptionalU64(options.bytesPerSecondLimit, 'bytesPerSecondLimit'),\n hash: normalizeHash(options),\n sha256: undefined\n }\n}\n\nexport function normalizeHash(options: DownloadOptions): NormalizedHashConfig | undefined {\n if (options.hash !== undefined && options.sha256 !== undefined) {\n throw new TypeError('use either hash or sha256, not both')\n }\n if (options.hash === undefined) {\n return options.sha256 === undefined ? undefined : { kind: 'sha256', expected: options.sha256 }\n }\n if (typeof options.hash === 'string') {\n const separator = options.hash.indexOf(':')\n if (separator === -1) {\n throw new TypeError('hash string must use the format \"kind:hex\"')\n }\n return {\n kind: normalizeHashKind(options.hash.slice(0, separator)),\n expected: options.hash.slice(separator + 1)\n }\n }\n return {\n kind: normalizeHashKind(options.hash.kind),\n expected: options.hash.expected\n }\n}\n\nexport function normalizeHashKind(kind: string): HashKind {\n switch (kind.toLowerCase()) {\n case 'sha1':\n case 'sha-1':\n return 'sha1'\n case 'sha256':\n case 'sha-256':\n return 'sha256'\n case 'sha512':\n case 'sha-512':\n return 'sha512'\n case 'md5':\n return 'md5'\n case 'crc32':\n case 'crc-32':\n return 'crc32'\n default:\n throw new TypeError(`unsupported hash kind: ${kind}`)\n }\n}\n\nexport function mapSnapshot(snapshot: NormalizedDownloadSnapshot): DownloadSnapshot {\n return {\n phase: snapshot.phase as DownloadPhase,\n contentLen: BigInt(snapshot.contentLen),\n downloadedBytes: BigInt(snapshot.downloadedBytes),\n chunkSize: BigInt(snapshot.chunkSize),\n chunkCount: BigInt(snapshot.chunkCount),\n completedChunks: BigInt(snapshot.completedChunks),\n activeIo: snapshot.activeIo,\n lastError: snapshot.lastError\n }\n}\n\nexport function decodeBase64ToUint8Array(data: string): Uint8Array {\n if (data.length === 0) {\n return new Uint8Array()\n }\n\n const bufferConstructor = (globalThis as { Buffer?: { from(data: string, encoding: 'base64'): Uint8Array } }).Buffer\n if (bufferConstructor !== undefined) {\n return Uint8Array.from(bufferConstructor.from(data, 'base64'))\n }\n\n const binary = globalThis.atob(data)\n const bytes = new Uint8Array(binary.length)\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index)\n }\n return bytes\n}\n\nfunction normalizeMaxIo(value: number | undefined): number {\n if (value === undefined) {\n return DEFAULT_MAX_IO\n }\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new TypeError('maxIo must be a non-negative safe integer')\n }\n return Math.max(1, value)\n}\n\nfunction normalizeOptionalU64(\n value: bigint | number | string | undefined,\n fieldName: string\n): string | undefined {\n if (value === undefined) {\n return undefined\n }\n if (typeof value === 'number' && !Number.isSafeInteger(value)) {\n throw new TypeError(`${fieldName} must be a safe integer number; pass a bigint or string for larger values`)\n }\n const text = value.toString()\n if (!/^\\d+$/.test(text)) {\n throw new TypeError(`expected an unsigned integer string for ${fieldName}, got ${text}`)\n }\n return text\n}\n","import { createRequire } from 'node:module'\n\nconst require = createRequire(import.meta.url)\n\nexport interface NativeDownloadOptions {\n url: string\n target_path: string\n chunk_size?: string\n parallelism?: number\n max_parallel_chunks?: number\n max_io?: number\n max_retries?: number\n backoff_initial_ms?: number\n backoff_max_ms?: number\n connect_timeout_ms?: number\n read_timeout_ms?: number\n total_timeout_ms?: number\n bytes_per_second_limit?: string\n hash?: NativeHashConfig\n sha256?: string\n}\n\nexport interface NativeHashConfig {\n kind: string\n expected: string\n}\n\nexport interface NativeDownloadSnapshot {\n phase: string\n content_len: string\n downloaded_bytes: string\n chunk_size: string\n chunk_count: string\n completed_chunks: string\n active_io: number\n last_error?: string\n}\n\nexport interface NativeDownloadTask {\n start(): void\n pause(): void\n cancel(): void\n snapshot(): NativeDownloadSnapshot\n bitmap(): Uint8Array\n}\n\nexport interface TakanawaNativeBinding {\n nativeDownloadToCompletion(options: NativeDownloadOptions): Promise<NativeDownloadSnapshot>\n NativeDownloadTask: new (options: NativeDownloadOptions) => NativeDownloadTask\n}\n\nexport const nativeBinding = require('../index.js') as TakanawaNativeBinding\n","import {\n createTakanawaApi,\n type DownloadListenerHandle as CoreDownloadListenerHandle,\n type DownloadOptions as CoreDownloadOptions,\n type DownloadProgressListener as CoreDownloadProgressListener,\n type DownloadSnapshot as CoreDownloadSnapshot,\n type NormalizedDownloadOptions,\n type NormalizedDownloadSnapshot,\n type TakanawaTargetAdapter\n} from 'takanawa-js-core'\n\nimport {\n nativeBinding,\n type NativeDownloadOptions,\n type NativeDownloadSnapshot,\n type NativeDownloadTask\n} from './binding'\n\nexport type DownloadPhase =\n | 'created'\n | 'running'\n | 'pausing'\n | 'paused'\n | 'cancelling'\n | 'cancelled'\n | 'completed'\n | 'failed'\n\nexport type HashKind = 'sha1' | 'sha256' | 'sha512' | 'md5' | 'crc32'\n\nexport interface HashConfig {\n kind: HashKind\n expected: string\n}\n\nexport interface DownloadOptions {\n url: string\n targetPath: string\n chunkSize?: bigint | number | string\n parallelism?: number\n maxParallelChunks?: number\n maxIo?: number\n maxRetries?: number\n backoffInitialMs?: number\n backoffMaxMs?: number\n connectTimeoutMs?: number\n readTimeoutMs?: number\n totalTimeoutMs?: number\n bytesPerSecondLimit?: bigint | number | string\n hash?: HashConfig | `${HashKind}:${string}`\n /**\n * @deprecated Use `hash: { kind: 'sha256', expected: value }` instead.\n */\n sha256?: string\n}\n\nexport interface DownloadSnapshot {\n phase: DownloadPhase\n contentLen: bigint\n downloadedBytes: bigint\n chunkSize: bigint\n chunkCount: bigint\n completedChunks: bigint\n activeIo: number\n lastError?: string\n}\n\nexport type DownloadProgressListener = (snapshot: DownloadSnapshot) => void\n\nexport interface DownloadListenerHandle {\n remove(): Promise<void>\n}\n\nconst PROGRESS_POLL_INTERVAL_MS = 250\n\nconst nodeAdapter: TakanawaTargetAdapter<NativeDownloadTask> = {\n create(options) {\n return new nativeBinding.NativeDownloadTask(toNativeOptions(options))\n },\n start(task) {\n task.start()\n },\n pause(task) {\n task.pause()\n },\n cancel(task) {\n task.cancel()\n },\n snapshot(task) {\n return fromNativeSnapshot(task.snapshot())\n },\n bitmap(task) {\n return task.bitmap()\n },\n close() {},\n addProgressListener(task, listener) {\n let previous = snapshotKey(fromNativeSnapshot(task.snapshot()))\n const timer = setInterval(() => {\n const snapshot = fromNativeSnapshot(task.snapshot())\n const key = snapshotKey(snapshot)\n if (key !== previous) {\n previous = key\n listener(snapshot)\n }\n }, PROGRESS_POLL_INTERVAL_MS)\n\n return {\n async remove() {\n clearInterval(timer)\n }\n } satisfies CoreDownloadListenerHandle\n },\n async downloadToCompletion(options) {\n return fromNativeSnapshot(await nativeBinding.nativeDownloadToCompletion(toNativeOptions(options)))\n }\n}\n\nconst nodeApi = createTakanawaApi(nodeAdapter)\n\nexport class DownloadTask {\n readonly #inner: InstanceType<typeof nodeApi.DownloadTask>\n\n constructor(options: DownloadOptions) {\n this.#inner = new nodeApi.DownloadTask(options as CoreDownloadOptions)\n }\n\n start(): Promise<void> {\n return this.#inner.start()\n }\n\n pause(): Promise<void> {\n return this.#inner.pause()\n }\n\n cancel(): Promise<void> {\n return this.#inner.cancel()\n }\n\n snapshot(): Promise<DownloadSnapshot> {\n return this.#inner.snapshot() as Promise<DownloadSnapshot>\n }\n\n bitmap(): Promise<Uint8Array> {\n return this.#inner.bitmap()\n }\n\n close(): Promise<void> {\n return this.#inner.close()\n }\n\n addProgressListener(listener: DownloadProgressListener): Promise<DownloadListenerHandle> {\n return this.#inner.addProgressListener(listener as CoreDownloadProgressListener)\n }\n}\n\nexport function downloadToCompletion(options: DownloadOptions): Promise<DownloadSnapshot> {\n return nodeApi.downloadToCompletion(options as CoreDownloadOptions) as Promise<CoreDownloadSnapshot> as Promise<DownloadSnapshot>\n}\n\nfunction toNativeOptions(options: NormalizedDownloadOptions): NativeDownloadOptions {\n return {\n url: options.url,\n target_path: options.targetPath,\n chunk_size: options.chunkSize,\n parallelism: options.parallelism,\n max_parallel_chunks: options.maxParallelChunks,\n max_io: options.maxIo,\n max_retries: options.maxRetries,\n backoff_initial_ms: options.backoffInitialMs,\n backoff_max_ms: options.backoffMaxMs,\n connect_timeout_ms: options.connectTimeoutMs,\n read_timeout_ms: options.readTimeoutMs,\n total_timeout_ms: options.totalTimeoutMs,\n bytes_per_second_limit: options.bytesPerSecondLimit,\n hash: options.hash,\n sha256: undefined\n }\n}\n\nfunction fromNativeSnapshot(snapshot: NativeDownloadSnapshot): NormalizedDownloadSnapshot {\n return {\n phase: snapshot.phase,\n contentLen: snapshot.content_len,\n downloadedBytes: snapshot.downloaded_bytes,\n chunkSize: snapshot.chunk_size,\n chunkCount: snapshot.chunk_count,\n completedChunks: snapshot.completed_chunks,\n activeIo: snapshot.active_io,\n lastError: snapshot.last_error\n }\n}\n\nfunction snapshotKey(snapshot: NormalizedDownloadSnapshot): string {\n return [\n snapshot.phase,\n snapshot.contentLen,\n snapshot.downloadedBytes,\n snapshot.chunkSize,\n snapshot.chunkCount,\n snapshot.completedChunks,\n snapshot.activeIo,\n snapshot.lastError ?? ''\n ].join('\\0')\n}\n"],"names":["DEFAULT_MAX_IO","createTakanawaApi","adapter","DownloadTask","#options","#task","#taskPromise","#closed","#listenerHandles","options","#ensureTask","mapSnapshot","listenerHandles","handle","taskPromise","listener","task","adapterHandle","snapshot","removed","error","normalizeOptions","downloadToCompletion","normalizeOptionalU64","normalizeMaxIo","normalizeHash","separator","normalizeHashKind","kind","value","fieldName","text","require","createRequire","nativeBinding","PROGRESS_POLL_INTERVAL_MS","nodeAdapter","toNativeOptions","fromNativeSnapshot","previous","snapshotKey","timer","key","nodeApi","#inner"],"mappings":"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"}
package/index.js ADDED
@@ -0,0 +1,590 @@
1
+ // prettier-ignore
2
+ /* eslint-disable */
3
+ // @ts-nocheck
4
+ /* auto-generated by NAPI-RS */
5
+
6
+ const { readFileSync } = require('node:fs')
7
+ let nativeBinding = null
8
+ const loadErrors = []
9
+
10
+ const isMusl = () => {
11
+ let musl = false
12
+ if (process.platform === 'linux') {
13
+ musl = isMuslFromFilesystem()
14
+ if (musl === null) {
15
+ musl = isMuslFromReport()
16
+ }
17
+ if (musl === null) {
18
+ musl = isMuslFromChildProcess()
19
+ }
20
+ }
21
+ return musl
22
+ }
23
+
24
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
25
+
26
+ const isMuslFromFilesystem = () => {
27
+ try {
28
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
29
+ } catch {
30
+ return null
31
+ }
32
+ }
33
+
34
+ const isMuslFromReport = () => {
35
+ let report = null
36
+ if (typeof process.report?.getReport === 'function') {
37
+ process.report.excludeNetwork = true
38
+ report = process.report.getReport()
39
+ }
40
+ if (!report) {
41
+ return null
42
+ }
43
+ if (report.header && report.header.glibcVersionRuntime) {
44
+ return false
45
+ }
46
+ if (Array.isArray(report.sharedObjects)) {
47
+ if (report.sharedObjects.some(isFileMusl)) {
48
+ return true
49
+ }
50
+ }
51
+ return false
52
+ }
53
+
54
+ const isMuslFromChildProcess = () => {
55
+ try {
56
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
57
+ } catch (e) {
58
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
59
+ return false
60
+ }
61
+ }
62
+
63
+ function requireNative() {
64
+ if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
65
+ try {
66
+ return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
67
+ } catch (err) {
68
+ loadErrors.push(err)
69
+ }
70
+ } else if (process.platform === 'android') {
71
+ if (process.arch === 'arm64') {
72
+ try {
73
+ return require('./takanawa.android-arm64.node')
74
+ } catch (e) {
75
+ loadErrors.push(e)
76
+ }
77
+ try {
78
+ const binding = require('takanawa-node-android-arm64')
79
+ const bindingPackageVersion = require('takanawa-node-android-arm64/package.json').version
80
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
81
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
82
+ }
83
+ return binding
84
+ } catch (e) {
85
+ loadErrors.push(e)
86
+ }
87
+ } else if (process.arch === 'arm') {
88
+ try {
89
+ return require('./takanawa.android-arm-eabi.node')
90
+ } catch (e) {
91
+ loadErrors.push(e)
92
+ }
93
+ try {
94
+ const binding = require('takanawa-node-android-arm-eabi')
95
+ const bindingPackageVersion = require('takanawa-node-android-arm-eabi/package.json').version
96
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
97
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
98
+ }
99
+ return binding
100
+ } catch (e) {
101
+ loadErrors.push(e)
102
+ }
103
+ } else {
104
+ loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`))
105
+ }
106
+ } else if (process.platform === 'win32') {
107
+ if (process.arch === 'x64') {
108
+ if (process.config?.variables?.shlib_suffix === 'dll.a' || process.config?.variables?.node_target_type === 'shared_library') {
109
+ try {
110
+ return require('./takanawa.win32-x64-gnu.node')
111
+ } catch (e) {
112
+ loadErrors.push(e)
113
+ }
114
+ try {
115
+ const binding = require('takanawa-node-win32-x64-gnu')
116
+ const bindingPackageVersion = require('takanawa-node-win32-x64-gnu/package.json').version
117
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
118
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
119
+ }
120
+ return binding
121
+ } catch (e) {
122
+ loadErrors.push(e)
123
+ }
124
+ } else {
125
+ try {
126
+ return require('./takanawa.win32-x64-msvc.node')
127
+ } catch (e) {
128
+ loadErrors.push(e)
129
+ }
130
+ try {
131
+ const binding = require('takanawa-node-win32-x64-msvc')
132
+ const bindingPackageVersion = require('takanawa-node-win32-x64-msvc/package.json').version
133
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
134
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
135
+ }
136
+ return binding
137
+ } catch (e) {
138
+ loadErrors.push(e)
139
+ }
140
+ }
141
+ } else if (process.arch === 'ia32') {
142
+ try {
143
+ return require('./takanawa.win32-ia32-msvc.node')
144
+ } catch (e) {
145
+ loadErrors.push(e)
146
+ }
147
+ try {
148
+ const binding = require('takanawa-node-win32-ia32-msvc')
149
+ const bindingPackageVersion = require('takanawa-node-win32-ia32-msvc/package.json').version
150
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
151
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
152
+ }
153
+ return binding
154
+ } catch (e) {
155
+ loadErrors.push(e)
156
+ }
157
+ } else if (process.arch === 'arm64') {
158
+ try {
159
+ return require('./takanawa.win32-arm64-msvc.node')
160
+ } catch (e) {
161
+ loadErrors.push(e)
162
+ }
163
+ try {
164
+ const binding = require('takanawa-node-win32-arm64-msvc')
165
+ const bindingPackageVersion = require('takanawa-node-win32-arm64-msvc/package.json').version
166
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
167
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
168
+ }
169
+ return binding
170
+ } catch (e) {
171
+ loadErrors.push(e)
172
+ }
173
+ } else {
174
+ loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`))
175
+ }
176
+ } else if (process.platform === 'darwin') {
177
+ try {
178
+ return require('./takanawa.darwin-universal.node')
179
+ } catch (e) {
180
+ loadErrors.push(e)
181
+ }
182
+ try {
183
+ const binding = require('takanawa-node-darwin-universal')
184
+ const bindingPackageVersion = require('takanawa-node-darwin-universal/package.json').version
185
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
186
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
187
+ }
188
+ return binding
189
+ } catch (e) {
190
+ loadErrors.push(e)
191
+ }
192
+ if (process.arch === 'x64') {
193
+ try {
194
+ return require('./takanawa.darwin-x64.node')
195
+ } catch (e) {
196
+ loadErrors.push(e)
197
+ }
198
+ try {
199
+ const binding = require('takanawa-node-darwin-x64')
200
+ const bindingPackageVersion = require('takanawa-node-darwin-x64/package.json').version
201
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
202
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
203
+ }
204
+ return binding
205
+ } catch (e) {
206
+ loadErrors.push(e)
207
+ }
208
+ } else if (process.arch === 'arm64') {
209
+ try {
210
+ return require('./takanawa.darwin-arm64.node')
211
+ } catch (e) {
212
+ loadErrors.push(e)
213
+ }
214
+ try {
215
+ const binding = require('takanawa-node-darwin-arm64')
216
+ const bindingPackageVersion = require('takanawa-node-darwin-arm64/package.json').version
217
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
218
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
219
+ }
220
+ return binding
221
+ } catch (e) {
222
+ loadErrors.push(e)
223
+ }
224
+ } else {
225
+ loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`))
226
+ }
227
+ } else if (process.platform === 'freebsd') {
228
+ if (process.arch === 'x64') {
229
+ try {
230
+ return require('./takanawa.freebsd-x64.node')
231
+ } catch (e) {
232
+ loadErrors.push(e)
233
+ }
234
+ try {
235
+ const binding = require('takanawa-node-freebsd-x64')
236
+ const bindingPackageVersion = require('takanawa-node-freebsd-x64/package.json').version
237
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
238
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
239
+ }
240
+ return binding
241
+ } catch (e) {
242
+ loadErrors.push(e)
243
+ }
244
+ } else if (process.arch === 'arm64') {
245
+ try {
246
+ return require('./takanawa.freebsd-arm64.node')
247
+ } catch (e) {
248
+ loadErrors.push(e)
249
+ }
250
+ try {
251
+ const binding = require('takanawa-node-freebsd-arm64')
252
+ const bindingPackageVersion = require('takanawa-node-freebsd-arm64/package.json').version
253
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
254
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
255
+ }
256
+ return binding
257
+ } catch (e) {
258
+ loadErrors.push(e)
259
+ }
260
+ } else {
261
+ loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`))
262
+ }
263
+ } else if (process.platform === 'linux') {
264
+ if (process.arch === 'x64') {
265
+ if (isMusl()) {
266
+ try {
267
+ return require('./takanawa.linux-x64-musl.node')
268
+ } catch (e) {
269
+ loadErrors.push(e)
270
+ }
271
+ try {
272
+ const binding = require('takanawa-node-linux-x64-musl')
273
+ const bindingPackageVersion = require('takanawa-node-linux-x64-musl/package.json').version
274
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
275
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
276
+ }
277
+ return binding
278
+ } catch (e) {
279
+ loadErrors.push(e)
280
+ }
281
+ } else {
282
+ try {
283
+ return require('./takanawa.linux-x64-gnu.node')
284
+ } catch (e) {
285
+ loadErrors.push(e)
286
+ }
287
+ try {
288
+ const binding = require('takanawa-node-linux-x64-gnu')
289
+ const bindingPackageVersion = require('takanawa-node-linux-x64-gnu/package.json').version
290
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
291
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
292
+ }
293
+ return binding
294
+ } catch (e) {
295
+ loadErrors.push(e)
296
+ }
297
+ }
298
+ } else if (process.arch === 'arm64') {
299
+ if (isMusl()) {
300
+ try {
301
+ return require('./takanawa.linux-arm64-musl.node')
302
+ } catch (e) {
303
+ loadErrors.push(e)
304
+ }
305
+ try {
306
+ const binding = require('takanawa-node-linux-arm64-musl')
307
+ const bindingPackageVersion = require('takanawa-node-linux-arm64-musl/package.json').version
308
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
309
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
310
+ }
311
+ return binding
312
+ } catch (e) {
313
+ loadErrors.push(e)
314
+ }
315
+ } else {
316
+ try {
317
+ return require('./takanawa.linux-arm64-gnu.node')
318
+ } catch (e) {
319
+ loadErrors.push(e)
320
+ }
321
+ try {
322
+ const binding = require('takanawa-node-linux-arm64-gnu')
323
+ const bindingPackageVersion = require('takanawa-node-linux-arm64-gnu/package.json').version
324
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
325
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
326
+ }
327
+ return binding
328
+ } catch (e) {
329
+ loadErrors.push(e)
330
+ }
331
+ }
332
+ } else if (process.arch === 'arm') {
333
+ if (isMusl()) {
334
+ try {
335
+ return require('./takanawa.linux-arm-musleabihf.node')
336
+ } catch (e) {
337
+ loadErrors.push(e)
338
+ }
339
+ try {
340
+ const binding = require('takanawa-node-linux-arm-musleabihf')
341
+ const bindingPackageVersion = require('takanawa-node-linux-arm-musleabihf/package.json').version
342
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
343
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
344
+ }
345
+ return binding
346
+ } catch (e) {
347
+ loadErrors.push(e)
348
+ }
349
+ } else {
350
+ try {
351
+ return require('./takanawa.linux-arm-gnueabihf.node')
352
+ } catch (e) {
353
+ loadErrors.push(e)
354
+ }
355
+ try {
356
+ const binding = require('takanawa-node-linux-arm-gnueabihf')
357
+ const bindingPackageVersion = require('takanawa-node-linux-arm-gnueabihf/package.json').version
358
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
359
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
360
+ }
361
+ return binding
362
+ } catch (e) {
363
+ loadErrors.push(e)
364
+ }
365
+ }
366
+ } else if (process.arch === 'loong64') {
367
+ if (isMusl()) {
368
+ try {
369
+ return require('./takanawa.linux-loong64-musl.node')
370
+ } catch (e) {
371
+ loadErrors.push(e)
372
+ }
373
+ try {
374
+ const binding = require('takanawa-node-linux-loong64-musl')
375
+ const bindingPackageVersion = require('takanawa-node-linux-loong64-musl/package.json').version
376
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
377
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
378
+ }
379
+ return binding
380
+ } catch (e) {
381
+ loadErrors.push(e)
382
+ }
383
+ } else {
384
+ try {
385
+ return require('./takanawa.linux-loong64-gnu.node')
386
+ } catch (e) {
387
+ loadErrors.push(e)
388
+ }
389
+ try {
390
+ const binding = require('takanawa-node-linux-loong64-gnu')
391
+ const bindingPackageVersion = require('takanawa-node-linux-loong64-gnu/package.json').version
392
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
393
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
394
+ }
395
+ return binding
396
+ } catch (e) {
397
+ loadErrors.push(e)
398
+ }
399
+ }
400
+ } else if (process.arch === 'riscv64') {
401
+ if (isMusl()) {
402
+ try {
403
+ return require('./takanawa.linux-riscv64-musl.node')
404
+ } catch (e) {
405
+ loadErrors.push(e)
406
+ }
407
+ try {
408
+ const binding = require('takanawa-node-linux-riscv64-musl')
409
+ const bindingPackageVersion = require('takanawa-node-linux-riscv64-musl/package.json').version
410
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
411
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
412
+ }
413
+ return binding
414
+ } catch (e) {
415
+ loadErrors.push(e)
416
+ }
417
+ } else {
418
+ try {
419
+ return require('./takanawa.linux-riscv64-gnu.node')
420
+ } catch (e) {
421
+ loadErrors.push(e)
422
+ }
423
+ try {
424
+ const binding = require('takanawa-node-linux-riscv64-gnu')
425
+ const bindingPackageVersion = require('takanawa-node-linux-riscv64-gnu/package.json').version
426
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
427
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
428
+ }
429
+ return binding
430
+ } catch (e) {
431
+ loadErrors.push(e)
432
+ }
433
+ }
434
+ } else if (process.arch === 'ppc64') {
435
+ try {
436
+ return require('./takanawa.linux-ppc64-gnu.node')
437
+ } catch (e) {
438
+ loadErrors.push(e)
439
+ }
440
+ try {
441
+ const binding = require('takanawa-node-linux-ppc64-gnu')
442
+ const bindingPackageVersion = require('takanawa-node-linux-ppc64-gnu/package.json').version
443
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
444
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
445
+ }
446
+ return binding
447
+ } catch (e) {
448
+ loadErrors.push(e)
449
+ }
450
+ } else if (process.arch === 's390x') {
451
+ try {
452
+ return require('./takanawa.linux-s390x-gnu.node')
453
+ } catch (e) {
454
+ loadErrors.push(e)
455
+ }
456
+ try {
457
+ const binding = require('takanawa-node-linux-s390x-gnu')
458
+ const bindingPackageVersion = require('takanawa-node-linux-s390x-gnu/package.json').version
459
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
460
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
461
+ }
462
+ return binding
463
+ } catch (e) {
464
+ loadErrors.push(e)
465
+ }
466
+ } else {
467
+ loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`))
468
+ }
469
+ } else if (process.platform === 'openharmony') {
470
+ if (process.arch === 'arm64') {
471
+ try {
472
+ return require('./takanawa.openharmony-arm64.node')
473
+ } catch (e) {
474
+ loadErrors.push(e)
475
+ }
476
+ try {
477
+ const binding = require('takanawa-node-openharmony-arm64')
478
+ const bindingPackageVersion = require('takanawa-node-openharmony-arm64/package.json').version
479
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
480
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
481
+ }
482
+ return binding
483
+ } catch (e) {
484
+ loadErrors.push(e)
485
+ }
486
+ } else if (process.arch === 'x64') {
487
+ try {
488
+ return require('./takanawa.openharmony-x64.node')
489
+ } catch (e) {
490
+ loadErrors.push(e)
491
+ }
492
+ try {
493
+ const binding = require('takanawa-node-openharmony-x64')
494
+ const bindingPackageVersion = require('takanawa-node-openharmony-x64/package.json').version
495
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
496
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
497
+ }
498
+ return binding
499
+ } catch (e) {
500
+ loadErrors.push(e)
501
+ }
502
+ } else if (process.arch === 'arm') {
503
+ try {
504
+ return require('./takanawa.openharmony-arm.node')
505
+ } catch (e) {
506
+ loadErrors.push(e)
507
+ }
508
+ try {
509
+ const binding = require('takanawa-node-openharmony-arm')
510
+ const bindingPackageVersion = require('takanawa-node-openharmony-arm/package.json').version
511
+ if (bindingPackageVersion !== '0.4.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
512
+ throw new Error(`Native binding package version mismatch, expected 0.4.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
513
+ }
514
+ return binding
515
+ } catch (e) {
516
+ loadErrors.push(e)
517
+ }
518
+ } else {
519
+ loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`))
520
+ }
521
+ } else {
522
+ loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`))
523
+ }
524
+ }
525
+
526
+ nativeBinding = requireNative()
527
+
528
+ // NAPI_RS_FORCE_WASI is a tri-state flag:
529
+ // unset / any other value → native binding preferred, WASI is only a fallback
530
+ // 'true' → force WASI fallback even if native loaded
531
+ // 'error' → force WASI and throw if no WASI binding is found
532
+ // Treating any non-empty string as truthy (the historical behavior) meant
533
+ // NAPI_RS_FORCE_WASI=false, NAPI_RS_FORCE_WASI=0, etc. inadvertently triggered
534
+ // the WASI path, causing ENOENT for packages shipped without a .wasi.cjs file.
535
+ const forceWasi =
536
+ process.env.NAPI_RS_FORCE_WASI === 'true' || process.env.NAPI_RS_FORCE_WASI === 'error'
537
+
538
+ if (!nativeBinding || forceWasi) {
539
+ let wasiBinding = null
540
+ let wasiBindingError = null
541
+ try {
542
+ wasiBinding = require('./takanawa.wasi.cjs')
543
+ nativeBinding = wasiBinding
544
+ } catch (err) {
545
+ if (forceWasi) {
546
+ wasiBindingError = err
547
+ }
548
+ }
549
+ if (!nativeBinding || forceWasi) {
550
+ try {
551
+ wasiBinding = require('takanawa-node-wasm32-wasi')
552
+ nativeBinding = wasiBinding
553
+ } catch (err) {
554
+ if (forceWasi) {
555
+ if (!wasiBindingError) {
556
+ wasiBindingError = err
557
+ } else {
558
+ wasiBindingError.cause = err
559
+ }
560
+ loadErrors.push(err)
561
+ }
562
+ }
563
+ }
564
+ if (process.env.NAPI_RS_FORCE_WASI === 'error' && !wasiBinding) {
565
+ const error = new Error('WASI binding not found and NAPI_RS_FORCE_WASI is set to error')
566
+ error.cause = wasiBindingError
567
+ throw error
568
+ }
569
+ }
570
+
571
+ if (!nativeBinding) {
572
+ if (loadErrors.length > 0) {
573
+ throw new Error(
574
+ `Cannot find native binding. ` +
575
+ `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
576
+ 'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
577
+ {
578
+ cause: loadErrors.reduce((err, cur) => {
579
+ cur.cause = err
580
+ return cur
581
+ }),
582
+ },
583
+ )
584
+ }
585
+ throw new Error(`Failed to load native binding`)
586
+ }
587
+
588
+ module.exports = nativeBinding
589
+ module.exports.NativeDownloadTask = nativeBinding.NativeDownloadTask
590
+ module.exports.nativeDownloadToCompletion = nativeBinding.nativeDownloadToCompletion
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "takanawa-node",
3
- "version": "0.3.1",
3
+ "version": "0.4.3",
4
4
  "description": "Node.js and Electron bindings for Takanawa powered by napi-rs.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/yetanother.ai/takanawa.git",
8
+ "url": "https://github.com/yet-another-ai/takanawa",
9
9
  "directory": "packages/takanawa"
10
10
  },
11
11
  "main": "./dist/index.cjs",
@@ -20,14 +20,18 @@
20
20
  },
21
21
  "files": [
22
22
  "README.md",
23
- "dist",
23
+ "dist/index.cjs",
24
+ "dist/index.cjs.map",
25
+ "dist/index.d.ts",
26
+ "dist/index.mjs",
27
+ "dist/index.mjs.map",
24
28
  "index.js",
25
29
  "*.node"
26
30
  ],
27
31
  "scripts": {
28
32
  "build": "pnpm run build:native && pnpm run build:ts",
29
33
  "build:native": "napi build --platform --release",
30
- "build:ts": "vite build && tsc -p tsconfig.json --emitDeclarationOnly",
34
+ "build:ts": "vite build && tsc -p tsconfig.json --emitDeclarationOnly && node -e \"require('node:fs').copyFileSync('dist/takanawa-node/src/index.d.ts', 'dist/index.d.ts')\"",
31
35
  "dev:native": "napi build --platform",
32
36
  "dev:ts": "vite build --watch",
33
37
  "test": "node --test __test__/*.test.mjs"
Binary file