From 3df28d9b32b4236bc79f939b1eae472fa5feefa5 Mon Sep 17 00:00:00 2001 From: 0xZensh Date: Sat, 12 Oct 2024 11:08:56 +0800 Subject: [PATCH] fix: add "web-streams-polyfill" to "ic_oss_ts" for Safari browser compatibility --- package-lock.json | 132 ++++++++++++++------------ src/ic_oss_ts/package.json | 15 +-- src/ic_oss_ts/src/bucket.canister.ts | 10 +- src/ic_oss_ts/src/cluster.canister.ts | 12 +-- src/ic_oss_ts/src/stream.test.ts | 7 +- src/ic_oss_ts/src/stream.ts | 21 ++-- src/ic_oss_ts/src/types.ts | 2 +- src/ic_oss_ts/src/uploader.ts | 7 +- 8 files changed, 108 insertions(+), 98 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7243f75..2873939 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8538,9 +8538,9 @@ } }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -8804,6 +8804,15 @@ } } }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0.tgz", + "integrity": "sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/webcrypto-core": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.8.0.tgz", @@ -9102,27 +9111,28 @@ }, "src/ic_oss_ts": { "name": "@ldclabs/ic_oss_ts", - "version": "0.7.0", + "version": "0.9.3", "license": "MIT", "dependencies": { "@dfinity/agent": "^2.1.2", "@dfinity/candid": "^2.1.2", "@dfinity/principal": "^2.1.2", - "@dfinity/utils": "^2.5.1", + "@dfinity/utils": "^2.5.2", "@noble/hashes": "^1.5.0", - "mime": "^4.0.4" + "mime": "^4.0.4", + "web-streams-polyfill": "^4.0.0" }, "devDependencies": { "@types/eslint": "^9.6.1", - "@types/node": "22.7.4", - "@typescript-eslint/eslint-plugin": "^8.8.0", - "@typescript-eslint/parser": "^8.8.0", + "@types/node": "22.7.5", + "@typescript-eslint/eslint-plugin": "^8.8.1", + "@typescript-eslint/parser": "^8.8.1", "eslint": "^9.12.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.31.0", "eslint-plugin-prettier": "^5.2.1", "prettier": "^3.3.3", - "typescript": "^5.6.2", + "typescript": "^5.6.3", "vitest": "^2.1.2" }, "engines": { @@ -9166,14 +9176,14 @@ } }, "src/ic_oss_ts/node_modules/@dfinity/utils": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@dfinity/utils/-/utils-2.5.1.tgz", - "integrity": "sha512-ypu63xSX/7f79rVVe/T/2eiEwwi2+XvPNEuHz+isj8zf4jvEoG8DDDBZF9hedDgYC5uxuBDm1UJqHGYUcaCmRg==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@dfinity/utils/-/utils-2.5.2.tgz", + "integrity": "sha512-QSW7t8kcLj0s/gL4NbYqr+Pqr3e2QhFn2JriwcghuflhwrYet1y23ANyM4EwSUeDAUR/OQXR86e4MfWkGMttAg==", "license": "Apache-2.0", "peerDependencies": { - "@dfinity/agent": "^2.1.2", - "@dfinity/candid": "^2.1.2", - "@dfinity/principal": "^2.1.2" + "@dfinity/agent": "^2.0.0", + "@dfinity/candid": "^2.0.0", + "@dfinity/principal": "^2.0.0" } }, "src/ic_oss_ts/node_modules/@eslint/eslintrc": { @@ -9243,9 +9253,9 @@ } }, "src/ic_oss_ts/node_modules/@types/node": { - "version": "22.7.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz", - "integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==", + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9253,17 +9263,17 @@ } }, "src/ic_oss_ts/node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.0.tgz", - "integrity": "sha512-wORFWjU30B2WJ/aXBfOm1LX9v9nyt9D3jsSOxC3cCaTQGCW5k4jNpmjFv3U7p/7s4yvdjHzwtv2Sd2dOyhjS0A==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.1.tgz", + "integrity": "sha512-xfvdgA8AP/vxHgtgU310+WBnLB4uJQ9XdyP17RebG26rLtDrQJV3ZYrcopX91GrHmMoH8bdSwMRh2a//TiJ1jQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.8.0", - "@typescript-eslint/type-utils": "8.8.0", - "@typescript-eslint/utils": "8.8.0", - "@typescript-eslint/visitor-keys": "8.8.0", + "@typescript-eslint/scope-manager": "8.8.1", + "@typescript-eslint/type-utils": "8.8.1", + "@typescript-eslint/utils": "8.8.1", + "@typescript-eslint/visitor-keys": "8.8.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -9287,16 +9297,16 @@ } }, "src/ic_oss_ts/node_modules/@typescript-eslint/parser": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.0.tgz", - "integrity": "sha512-uEFUsgR+tl8GmzmLjRqz+VrDv4eoaMqMXW7ruXfgThaAShO9JTciKpEsB+TvnfFfbg5IpujgMXVV36gOJRLtZg==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.1.tgz", + "integrity": "sha512-hQUVn2Lij2NAxVFEdvIGxT9gP1tq2yM83m+by3whWFsWC+1y8pxxxHUFE1UqDu2VsGi2i6RLcv4QvouM84U+ow==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "8.8.0", - "@typescript-eslint/types": "8.8.0", - "@typescript-eslint/typescript-estree": "8.8.0", - "@typescript-eslint/visitor-keys": "8.8.0", + "@typescript-eslint/scope-manager": "8.8.1", + "@typescript-eslint/types": "8.8.1", + "@typescript-eslint/typescript-estree": "8.8.1", + "@typescript-eslint/visitor-keys": "8.8.1", "debug": "^4.3.4" }, "engines": { @@ -9316,14 +9326,14 @@ } }, "src/ic_oss_ts/node_modules/@typescript-eslint/scope-manager": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.0.tgz", - "integrity": "sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.1.tgz", + "integrity": "sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.8.0", - "@typescript-eslint/visitor-keys": "8.8.0" + "@typescript-eslint/types": "8.8.1", + "@typescript-eslint/visitor-keys": "8.8.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -9334,14 +9344,14 @@ } }, "src/ic_oss_ts/node_modules/@typescript-eslint/type-utils": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.0.tgz", - "integrity": "sha512-IKwJSS7bCqyCeG4NVGxnOP6lLT9Okc3Zj8hLO96bpMkJab+10HIfJbMouLrlpyOr3yrQ1cA413YPFiGd1mW9/Q==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.1.tgz", + "integrity": "sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.8.0", - "@typescript-eslint/utils": "8.8.0", + "@typescript-eslint/typescript-estree": "8.8.1", + "@typescript-eslint/utils": "8.8.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -9359,9 +9369,9 @@ } }, "src/ic_oss_ts/node_modules/@typescript-eslint/types": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.0.tgz", - "integrity": "sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.1.tgz", + "integrity": "sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==", "dev": true, "license": "MIT", "engines": { @@ -9373,14 +9383,14 @@ } }, "src/ic_oss_ts/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.0.tgz", - "integrity": "sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.1.tgz", + "integrity": "sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.8.0", - "@typescript-eslint/visitor-keys": "8.8.0", + "@typescript-eslint/types": "8.8.1", + "@typescript-eslint/visitor-keys": "8.8.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -9402,16 +9412,16 @@ } }, "src/ic_oss_ts/node_modules/@typescript-eslint/utils": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.0.tgz", - "integrity": "sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.1.tgz", + "integrity": "sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.8.0", - "@typescript-eslint/types": "8.8.0", - "@typescript-eslint/typescript-estree": "8.8.0" + "@typescript-eslint/scope-manager": "8.8.1", + "@typescript-eslint/types": "8.8.1", + "@typescript-eslint/typescript-estree": "8.8.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -9425,13 +9435,13 @@ } }, "src/ic_oss_ts/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.0.tgz", - "integrity": "sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.1.tgz", + "integrity": "sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.8.0", + "@typescript-eslint/types": "8.8.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { diff --git a/src/ic_oss_ts/package.json b/src/ic_oss_ts/package.json index 5989ce8..ede39b8 100644 --- a/src/ic_oss_ts/package.json +++ b/src/ic_oss_ts/package.json @@ -1,6 +1,6 @@ { "name": "@ldclabs/ic_oss_ts", - "version": "0.9.3", + "version": "0.9.4", "type": "module", "description": "The Typescript version of the client SDK for the ic-oss cluster.", "license": "MIT", @@ -37,21 +37,22 @@ "@dfinity/agent": "^2.1.2", "@dfinity/candid": "^2.1.2", "@dfinity/principal": "^2.1.2", - "@dfinity/utils": "^2.5.1", + "@dfinity/utils": "^2.5.2", "@noble/hashes": "^1.5.0", - "mime": "^4.0.4" + "mime": "^4.0.4", + "web-streams-polyfill": "^4.0.0" }, "devDependencies": { - "@types/node": "22.7.4", "@types/eslint": "^9.6.1", - "@typescript-eslint/eslint-plugin": "^8.8.0", - "@typescript-eslint/parser": "^8.8.0", - "typescript": "^5.6.2", + "@types/node": "22.7.5", + "@typescript-eslint/eslint-plugin": "^8.8.1", + "@typescript-eslint/parser": "^8.8.1", "eslint": "^9.12.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.31.0", "eslint-plugin-prettier": "^5.2.1", "prettier": "^3.3.3", + "typescript": "^5.6.3", "vitest": "^2.1.2" } } \ No newline at end of file diff --git a/src/ic_oss_ts/src/bucket.canister.ts b/src/ic_oss_ts/src/bucket.canister.ts index d448658..ef6df80 100644 --- a/src/ic_oss_ts/src/bucket.canister.ts +++ b/src/ic_oss_ts/src/bucket.canister.ts @@ -1,24 +1,24 @@ import { Canister, createServices } from '@dfinity/utils' -import type { _SERVICE as BucketService } from '../candid/ic_oss_bucket/ic_oss_bucket.did.js' -import { idlFactory } from '../candid/ic_oss_bucket/ic_oss_bucket.did.js' import type { BucketInfo, + _SERVICE as BucketService, CanisterStatusResponse, CreateFileInput, CreateFileOutput, CreateFolderInput, - FolderName, FileInfo, FolderInfo, + FolderName, MoveInput, - UpdateFileOutput, UpdateFileChunkInput, UpdateFileChunkOutput, UpdateFileInput, + UpdateFileOutput, UpdateFolderInput } from '../candid/ic_oss_bucket/ic_oss_bucket.did.js' +import { idlFactory } from '../candid/ic_oss_bucket/ic_oss_bucket.did.js' import type { CanisterOptions } from './types.js' -import { resultOk, FileChunk } from './types.js' +import { FileChunk, resultOk } from './types.js' export class BucketCanister extends Canister { #resultOk: typeof resultOk = resultOk diff --git a/src/ic_oss_ts/src/cluster.canister.ts b/src/ic_oss_ts/src/cluster.canister.ts index 2b8dc4f..3f6ef95 100644 --- a/src/ic_oss_ts/src/cluster.canister.ts +++ b/src/ic_oss_ts/src/cluster.canister.ts @@ -1,17 +1,17 @@ +import type { Principal } from '@dfinity/principal' import { Canister, createServices } from '@dfinity/utils' -import type { _SERVICE as ClusterService } from '../candid/ic_oss_cluster/ic_oss_cluster.did.js' -import { idlFactory } from '../candid/ic_oss_cluster/ic_oss_cluster.did.js' import type { - ClusterInfo, AddWasmInput, - Token, - DeployWasmInput, BucketDeploymentInfo, + ClusterInfo, + _SERVICE as ClusterService, + DeployWasmInput, + Token, WasmInfo } from '../candid/ic_oss_cluster/ic_oss_cluster.did.js' +import { idlFactory } from '../candid/ic_oss_cluster/ic_oss_cluster.did.js' import type { CanisterOptions } from './types.js' import { resultOk } from './types.js' -import type { Principal } from '@dfinity/principal' export class ClusterCanister extends Canister { #resultOk: typeof resultOk = resultOk diff --git a/src/ic_oss_ts/src/stream.test.ts b/src/ic_oss_ts/src/stream.test.ts index 52bd523..3e3e864 100644 --- a/src/ic_oss_ts/src/stream.test.ts +++ b/src/ic_oss_ts/src/stream.test.ts @@ -1,11 +1,12 @@ +import { open } from 'node:fs/promises' import { expect, test } from 'vitest' +import { type ReadableStream } from 'web-streams-polyfill' import { - uint8ArrayToFixedChunkSizeReadable, readableStreamAsyncIterator, + readAll, streamToFixedChunkSizeReadable, - readAll + uint8ArrayToFixedChunkSizeReadable } from './stream' -import { open } from 'node:fs/promises' test('uint8ArrayToFixedChunkSizeReadable', async () => { const src = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) diff --git a/src/ic_oss_ts/src/stream.ts b/src/ic_oss_ts/src/stream.ts index 242da87..662bb5d 100644 --- a/src/ic_oss_ts/src/stream.ts +++ b/src/ic_oss_ts/src/stream.ts @@ -1,5 +1,6 @@ -import type { FileHandle } from 'node:fs/promises' import mime from 'mime/lite' +import type { FileHandle } from 'node:fs/promises' +import { ReadableStream } from 'web-streams-polyfill' import { FileConfig } from './types.js' export const CHUNK_SIZE = 256 * 1024 @@ -155,25 +156,21 @@ export function uint8ArrayToFixedChunkSizeReadable( type: 'bytes', autoAllocateChunkSize: chunkSize, pull(controller) { - let bytesRead = 0 const byob = (controller as ReadableByteStreamController).byobRequest if (!byob) { throw new Error('byobRequest is required') } + const v = byob.view! const w = new Uint8Array(v.buffer, v.byteOffset, v.byteLength) - for ( - ; - bytesRead < w.byteLength && offset < data.byteLength; - bytesRead++ - ) { - w[bytesRead] = data[offset] - offset += 1 - } - if (bytesRead === 0) { + const bytesToRead = Math.min(w.byteLength, data.byteLength - offset) + w.set(data.subarray(offset, offset + bytesToRead)) + offset += bytesToRead + + if (bytesToRead === 0) { controller.close() } else { - byob.respond(bytesRead) + byob.respond(bytesToRead) } } }) diff --git a/src/ic_oss_ts/src/types.ts b/src/ic_oss_ts/src/types.ts index f35be3a..563322d 100644 --- a/src/ic_oss_ts/src/types.ts +++ b/src/ic_oss_ts/src/types.ts @@ -1,5 +1,5 @@ -import type { CanisterOptions as Options } from '@dfinity/utils' import type { Principal } from '@dfinity/principal' +import type { CanisterOptions as Options } from '@dfinity/utils' export interface CanisterOptions extends Omit, 'canisterId'> { canisterId: Principal diff --git a/src/ic_oss_ts/src/uploader.ts b/src/ic_oss_ts/src/uploader.ts index 7bd0fa6..5e7b841 100644 --- a/src/ic_oss_ts/src/uploader.ts +++ b/src/ic_oss_ts/src/uploader.ts @@ -1,13 +1,14 @@ import { sha3_256 } from '@noble/hashes/sha3' +import { type ReadableStream } from 'web-streams-polyfill' import { BucketCanister } from './bucket.canister.js' import { ConcurrencyQueue } from './queue.js' import { - toFixedChunkSizeReadable, + CHUNK_SIZE, readableStreamAsyncIterator, readAll, - CHUNK_SIZE + toFixedChunkSizeReadable } from './stream.js' -import { FileConfig, UploadFileChunksResult, Progress } from './types.js' +import { FileConfig, Progress, UploadFileChunksResult } from './types.js' export const MAX_FILE_SIZE_PER_CALL = 1024 * 2000