From 8cad65ab3e006d0de07047edad43f310d34c309f Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Tue, 13 Feb 2024 01:49:01 +0000 Subject: [PATCH 01/13] fix: remove the only dep to use native Uint8Array as recommended here https://sindresorhus.com/blog/goodbye-nodejs-buffer --- deps.ts | 1 - transform-chunk-sizes.ts | 43 +++++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 21 deletions(-) delete mode 100644 deps.ts diff --git a/deps.ts b/deps.ts deleted file mode 100644 index 76d8318..0000000 --- a/deps.ts +++ /dev/null @@ -1 +0,0 @@ -export { Buffer } from "https://deno.land/std@0.215.0/io/buffer.ts"; diff --git a/transform-chunk-sizes.ts b/transform-chunk-sizes.ts index c0940ac..6ced3d2 100644 --- a/transform-chunk-sizes.ts +++ b/transform-chunk-sizes.ts @@ -1,4 +1,3 @@ -import { Buffer } from "./deps.ts"; /** * This stream transform will buffer the data it receives until it has enough to form @@ -6,31 +5,35 @@ import { Buffer } from "./deps.ts"; */ export class TransformChunkSizes extends TransformStream { constructor(outChunkSize: number) { - // This large buffer holds all the incoming data we receive until we reach at least outChunkSize, which we then pass on. - const buffer = new Buffer(); - buffer.grow(outChunkSize); + const buffer = new Uint8Array(outChunkSize * 2); // Buffer size is twice the chunk size to ensure there's enough space + let offset = 0; // Offset to keep track of the current position in the buffer super({ - start() {}, // required - async transform(chunk, controller) { - buffer.write(chunk); + start(_controller) { + // No initialization needed here since we've already initialized buffer and offset in the constructor. + }, + transform(chunk, controller) { + let chunkOffset = 0; - while (buffer.length >= outChunkSize) { - const outChunk = new Uint8Array(outChunkSize); - const readFromBuffer = await buffer.read(outChunk); - if (readFromBuffer !== outChunkSize) { - throw new Error( - `Unexpectedly read ${readFromBuffer} bytes from transform buffer when trying to read ${outChunkSize} bytes.`, - ); - } - // Now "outChunk" holds the next chunk of data - pass it on to the output: - controller.enqueue(outChunk); + // If the incoming chunk won't fit in the remaining buffer space, we need to process what's in the buffer first + while (offset + chunk.length - chunkOffset > outChunkSize) { + // Calculate how much of the incoming chunk we can fit into the buffer + const spaceLeft = outChunkSize - offset; + buffer.set(chunk.subarray(chunkOffset, chunkOffset + spaceLeft), offset); + controller.enqueue(buffer.subarray(0, outChunkSize)); + offset = 0; + chunkOffset += spaceLeft; } + + // Put the remaining chunk into the buffer + buffer.set(chunk.subarray(chunkOffset), offset); + offset += chunk.length - chunkOffset; }, flush(controller) { - if (buffer.length) { - // The buffer still contains some data, send it now even though it's smaller than the desired chunk size. - controller.enqueue(buffer.bytes()); + if (offset > 0) { + // Send any remaining data in the buffer + controller.enqueue(buffer.subarray(0, offset)); + offset = 0; } }, }); From c33ee9d705cdcc60ef360a486e7549f8e92d3087 Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Tue, 13 Feb 2024 02:17:06 +0000 Subject: [PATCH 02/13] feat: add npm build --- build_npm.ts | 48 +++++++++++++++++++++++++++++++++++ signing.ts | 11 ++++---- transform-chunk-sizes.test.ts | 2 +- 3 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 build_npm.ts diff --git a/build_npm.ts b/build_npm.ts new file mode 100644 index 0000000..b593aa0 --- /dev/null +++ b/build_npm.ts @@ -0,0 +1,48 @@ +import { build, emptyDir } from "https://deno.land/x/dnt/mod.ts"; + +const version = Deno.args[0]; + +if (!version) { + throw new Error("Please specify a version."); +} + +await emptyDir("./npm"); + +await build({ + entryPoints: ["./mod.ts"], // Replace with your actual entry point + outDir: "./npm", + shims: { + // Add shims as necessary for your project + deno: true, + custom: [ + { + package: { + name: "web-streams-polyfill", + version: "^3.1.1", + }, + globalNames: ["ReadableStream", "WritableStream", "TransformStream"], + }, + ], + }, + package: { + // Update with your package details + name: "@capgo/s3-lite-client", + version: version, + description: "This is a lightweight S3 client for Node.js and Deno.", + license: "MIT", + repository: { + type: "git", + url: "git+https://github.com/riderx/deno-s3-lite-client.git", + }, + bugs: { + url: "https://github.com/riderx/deno-s3-lite-client/issues", + }, + }, + postBuild() { + // Copy additional files to the npm directory if needed + Deno.copyFileSync("LICENSE", "npm/LICENSE"); + Deno.copyFileSync("README.md", "npm/README.md"); + }, +}); + +console.log("Build complete. Run `npm publish` in the `npm` directory."); diff --git a/signing.ts b/signing.ts index cc58695..8c11ba3 100644 --- a/signing.ts +++ b/signing.ts @@ -153,13 +153,12 @@ function getHeadersToSign(headers: Headers): string[] { "content-type", "user-agent", ]; - const headersToSign = []; - for (const key of headers.keys()) { - if (ignoredHeaders.includes(key.toLowerCase())) { - continue; // Ignore this header + const headersToSign: string[] = []; + headers.forEach((value, key) => { + if (!ignoredHeaders.includes(key.toLowerCase())) { + headersToSign.push(key); } - headersToSign.push(key); - } + }); headersToSign.sort(); return headersToSign; } diff --git a/transform-chunk-sizes.test.ts b/transform-chunk-sizes.test.ts index 935db31..6852325 100644 --- a/transform-chunk-sizes.test.ts +++ b/transform-chunk-sizes.test.ts @@ -9,7 +9,7 @@ import { TransformChunkSizes } from "./transform-chunk-sizes.ts"; */ class NumberSource extends ReadableStream { constructor(delayMs: number, chunksCount: number, bytesPerChunk = 1) { - let intervalTimer: number; + let intervalTimer: any; let i = 0; super({ start(controller) { From 8cbad316dd4164c6b194cdfc35359415f7f67a99 Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Tue, 13 Feb 2024 02:17:29 +0000 Subject: [PATCH 03/13] fix: add gitignore npm folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..50d08d0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +npm \ No newline at end of file From 162238a50d6d2f54e7471f3e97ee88e99dbfee2d Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Tue, 13 Feb 2024 02:41:20 +0000 Subject: [PATCH 04/13] fix: use the name of the author for the Pr --- build_npm.ts | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/build_npm.ts b/build_npm.ts index b593aa0..d00aba8 100644 --- a/build_npm.ts +++ b/build_npm.ts @@ -26,17 +26,36 @@ await build({ }, package: { // Update with your package details - name: "@capgo/s3-lite-client", + name: "s3-lite-client", version: version, description: "This is a lightweight S3 client for Node.js and Deno.", license: "MIT", repository: { type: "git", - url: "git+https://github.com/riderx/deno-s3-lite-client.git", + url: "git+https://github.com/bradenmacdonald/deno-s3-lite-client.git", }, bugs: { - url: "https://github.com/riderx/deno-s3-lite-client/issues", + url: "https://github.com/bradenmacdonald/deno-s3-lite-client/issues", }, + engines: { + "node": ">=16" + }, + author: { + "name": "Braden MacDonald", + "url": "https://github.com/bradenmacdonald" + }, + contributors: [ + "Martin Donadieu (https://martin.solos.ventures/)", + ], + keywords: [ + "api", + "lite", + "amazon", + "minio", + "cloud", + "s3", + "storage" + ] }, postBuild() { // Copy additional files to the npm directory if needed @@ -45,4 +64,4 @@ await build({ }, }); -console.log("Build complete. Run `npm publish` in the `npm` directory."); +console.log("Build complete. Run `cd npm && npm publish`."); From 44908aafacd170bf1228c3cdadd8592df51e61ee Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Tue, 13 Feb 2024 03:06:03 +0000 Subject: [PATCH 05/13] fix: only shim tests --- build_npm.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build_npm.ts b/build_npm.ts index d00aba8..357e358 100644 --- a/build_npm.ts +++ b/build_npm.ts @@ -12,8 +12,9 @@ await build({ entryPoints: ["./mod.ts"], // Replace with your actual entry point outDir: "./npm", shims: { - // Add shims as necessary for your project - deno: true, + deno: { + test: "dev", + }, custom: [ { package: { From b216061afb93de97a94792ef1535b9bcbbbbd8da Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Fri, 16 Feb 2024 15:27:26 +0100 Subject: [PATCH 06/13] fix: use better type --- transform-chunk-sizes.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transform-chunk-sizes.test.ts b/transform-chunk-sizes.test.ts index 6852325..b55e1bf 100644 --- a/transform-chunk-sizes.test.ts +++ b/transform-chunk-sizes.test.ts @@ -9,7 +9,7 @@ import { TransformChunkSizes } from "./transform-chunk-sizes.ts"; */ class NumberSource extends ReadableStream { constructor(delayMs: number, chunksCount: number, bytesPerChunk = 1) { - let intervalTimer: any; + let intervalTimer: ReturnType; let i = 0; super({ start(controller) { From 9449e0df91a334006206a71089257cab1f9c4dc6 Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Sat, 17 Feb 2024 00:25:16 +0100 Subject: [PATCH 07/13] fix: rollback deps change --- deps.ts | 1 + transform-chunk-sizes.ts | 43 +++++++++++++++++++--------------------- 2 files changed, 21 insertions(+), 23 deletions(-) create mode 100644 deps.ts diff --git a/deps.ts b/deps.ts new file mode 100644 index 0000000..76d8318 --- /dev/null +++ b/deps.ts @@ -0,0 +1 @@ +export { Buffer } from "https://deno.land/std@0.215.0/io/buffer.ts"; diff --git a/transform-chunk-sizes.ts b/transform-chunk-sizes.ts index 6ced3d2..c0940ac 100644 --- a/transform-chunk-sizes.ts +++ b/transform-chunk-sizes.ts @@ -1,3 +1,4 @@ +import { Buffer } from "./deps.ts"; /** * This stream transform will buffer the data it receives until it has enough to form @@ -5,35 +6,31 @@ */ export class TransformChunkSizes extends TransformStream { constructor(outChunkSize: number) { - const buffer = new Uint8Array(outChunkSize * 2); // Buffer size is twice the chunk size to ensure there's enough space - let offset = 0; // Offset to keep track of the current position in the buffer + // This large buffer holds all the incoming data we receive until we reach at least outChunkSize, which we then pass on. + const buffer = new Buffer(); + buffer.grow(outChunkSize); super({ - start(_controller) { - // No initialization needed here since we've already initialized buffer and offset in the constructor. - }, - transform(chunk, controller) { - let chunkOffset = 0; + start() {}, // required + async transform(chunk, controller) { + buffer.write(chunk); - // If the incoming chunk won't fit in the remaining buffer space, we need to process what's in the buffer first - while (offset + chunk.length - chunkOffset > outChunkSize) { - // Calculate how much of the incoming chunk we can fit into the buffer - const spaceLeft = outChunkSize - offset; - buffer.set(chunk.subarray(chunkOffset, chunkOffset + spaceLeft), offset); - controller.enqueue(buffer.subarray(0, outChunkSize)); - offset = 0; - chunkOffset += spaceLeft; + while (buffer.length >= outChunkSize) { + const outChunk = new Uint8Array(outChunkSize); + const readFromBuffer = await buffer.read(outChunk); + if (readFromBuffer !== outChunkSize) { + throw new Error( + `Unexpectedly read ${readFromBuffer} bytes from transform buffer when trying to read ${outChunkSize} bytes.`, + ); + } + // Now "outChunk" holds the next chunk of data - pass it on to the output: + controller.enqueue(outChunk); } - - // Put the remaining chunk into the buffer - buffer.set(chunk.subarray(chunkOffset), offset); - offset += chunk.length - chunkOffset; }, flush(controller) { - if (offset > 0) { - // Send any remaining data in the buffer - controller.enqueue(buffer.subarray(0, offset)); - offset = 0; + if (buffer.length) { + // The buffer still contains some data, send it now even though it's smaller than the desired chunk size. + controller.enqueue(buffer.bytes()); } }, }); From fee6b0ded89dd680fe9e145a8c38c95598fbe2e3 Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Sat, 17 Feb 2024 01:44:06 +0100 Subject: [PATCH 08/13] fix: make test integration pass in nodejs --- build_npm.ts | 27 ++++++++++++++++++++++----- deno.jsonc | 7 ++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/build_npm.ts b/build_npm.ts index 357e358..fa2ba83 100644 --- a/build_npm.ts +++ b/build_npm.ts @@ -11,6 +11,16 @@ await emptyDir("./npm"); await build({ entryPoints: ["./mod.ts"], // Replace with your actual entry point outDir: "./npm", + testPattern: "**/*(*.test|integration).{ts,tsx,js,mjs,jsx}", + // Filter when we use node stream package + // filterDiagnostic(diagnostic) { + // if ( + // diagnostic.messageText.startsWith("Property 'from' does not exist on type '{ new (underlyingSource: UnderlyingByteSource, strategy?: QueuingStrategy | undefined): ReadableStream") + // ) { + // return false; // ignore all diagnostics For ReadableStream.from in this file + // } + // return true; + // }, shims: { deno: { test: "dev", @@ -19,10 +29,17 @@ await build({ { package: { name: "web-streams-polyfill", - version: "^3.1.1", + version: "^3.3.3", + // subPath: "ponyfill", }, globalNames: ["ReadableStream", "WritableStream", "TransformStream"], }, + // { + // package: { + // name: "node:stream/web", + // }, + // globalNames: ["ReadableStream", "WritableStream", "TransformStream"], + // }, ], }, package: { @@ -39,11 +56,11 @@ await build({ url: "https://github.com/bradenmacdonald/deno-s3-lite-client/issues", }, engines: { - "node": ">=16" + "node": ">=16", }, author: { "name": "Braden MacDonald", - "url": "https://github.com/bradenmacdonald" + "url": "https://github.com/bradenmacdonald", }, contributors: [ "Martin Donadieu (https://martin.solos.ventures/)", @@ -55,8 +72,8 @@ await build({ "minio", "cloud", "s3", - "storage" - ] + "storage", + ], }, postBuild() { // Copy additional files to the npm directory if needed diff --git a/deno.jsonc b/deno.jsonc index ba454f4..19177f6 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -2,5 +2,10 @@ "fmt": { "lineWidth": 120 }, - "lock": false + "lock": false, + "tasks": { + "test-integration": "deno test --allow-net integration.ts", + "npm-build": "deno run -A --no-check build_npm.ts", + "npm-publish": "cd npm && npm publish && cd .." + } } From 81b931b72536e1f80cbcf0b06d0a08e46c9390a5 Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Sat, 17 Feb 2024 01:48:31 +0100 Subject: [PATCH 09/13] fix: lint and fmt --- deno.jsonc | 6 +++++- signing.ts | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/deno.jsonc b/deno.jsonc index 19177f6..693c37c 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,6 +1,10 @@ { "fmt": { - "lineWidth": 120 + "lineWidth": 120, + "exclude": ["npm/"] + }, + "lint": { + "exclude": ["npm/"] }, "lock": false, "tasks": { diff --git a/signing.ts b/signing.ts index 8c11ba3..ca76c90 100644 --- a/signing.ts +++ b/signing.ts @@ -154,7 +154,7 @@ function getHeadersToSign(headers: Headers): string[] { "user-agent", ]; const headersToSign: string[] = []; - headers.forEach((value, key) => { + headers.forEach((_value, key) => { if (!ignoredHeaders.includes(key.toLowerCase())) { headersToSign.push(key); } From c50b5cab6d941822d9ba4367d5c0269bd9a9a589 Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Sat, 17 Feb 2024 02:19:14 +0100 Subject: [PATCH 10/13] fix: npm build and test --- build_npm.ts | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/build_npm.ts b/build_npm.ts index fa2ba83..8a768c6 100644 --- a/build_npm.ts +++ b/build_npm.ts @@ -13,33 +13,26 @@ await build({ outDir: "./npm", testPattern: "**/*(*.test|integration).{ts,tsx,js,mjs,jsx}", // Filter when we use node stream package - // filterDiagnostic(diagnostic) { - // if ( - // diagnostic.messageText.startsWith("Property 'from' does not exist on type '{ new (underlyingSource: UnderlyingByteSource, strategy?: QueuingStrategy | undefined): ReadableStream") - // ) { - // return false; // ignore all diagnostics For ReadableStream.from in this file - // } - // return true; - // }, + filterDiagnostic(diagnostic) { + if ( + diagnostic.messageText.startsWith("Property 'from' does not exist on type '{ new (underlyingSource: UnderlyingByteSource, strategy?: QueuingStrategy | undefined): ReadableStream") + ) { + return false; // ignore all diagnostics For ReadableStream.from in this file + } + return true; + }, shims: { + undici: true, // fix: can copy a file test integration deno: { test: "dev", }, custom: [ { package: { - name: "web-streams-polyfill", - version: "^3.3.3", - // subPath: "ponyfill", + name: "node:stream/web", }, globalNames: ["ReadableStream", "WritableStream", "TransformStream"], }, - // { - // package: { - // name: "node:stream/web", - // }, - // globalNames: ["ReadableStream", "WritableStream", "TransformStream"], - // }, ], }, package: { From 8cbf075d0b48c6a586c4412cc6ad94e6e85c634e Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Sun, 18 Feb 2024 03:49:43 +0100 Subject: [PATCH 11/13] fix: simplify the problem and fix the tests --- build_npm.ts | 18 +++++------------- client.ts | 14 ++++++++++++-- integration.ts | 11 +++++++---- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/build_npm.ts b/build_npm.ts index 8a768c6..a30cccc 100644 --- a/build_npm.ts +++ b/build_npm.ts @@ -1,4 +1,4 @@ -import { build, emptyDir } from "https://deno.land/x/dnt/mod.ts"; +import { build, emptyDir } from "https://deno.land/x/dnt@0.40.0/mod.ts"; const version = Deno.args[0]; @@ -12,17 +12,7 @@ await build({ entryPoints: ["./mod.ts"], // Replace with your actual entry point outDir: "./npm", testPattern: "**/*(*.test|integration).{ts,tsx,js,mjs,jsx}", - // Filter when we use node stream package - filterDiagnostic(diagnostic) { - if ( - diagnostic.messageText.startsWith("Property 'from' does not exist on type '{ new (underlyingSource: UnderlyingByteSource, strategy?: QueuingStrategy | undefined): ReadableStream") - ) { - return false; // ignore all diagnostics For ReadableStream.from in this file - } - return true; - }, shims: { - undici: true, // fix: can copy a file test integration deno: { test: "dev", }, @@ -36,7 +26,6 @@ await build({ ], }, package: { - // Update with your package details name: "s3-lite-client", version: version, description: "This is a lightweight S3 client for Node.js and Deno.", @@ -49,7 +38,7 @@ await build({ url: "https://github.com/bradenmacdonald/deno-s3-lite-client/issues", }, engines: { - "node": ">=16", + "node": ">=20", }, author: { "name": "Braden MacDonald", @@ -58,6 +47,9 @@ await build({ contributors: [ "Martin Donadieu (https://martin.solos.ventures/)", ], + devDependencies: { + "@types/node": "^20.11.1", + }, keywords: [ "api", "lite", diff --git a/client.ts b/client.ts index 8f50b34..1295a90 100644 --- a/client.ts +++ b/client.ts @@ -648,10 +648,20 @@ export class Client { if (typeof streamOrData === "string") { // Convert to binary using UTF-8 const binaryData = new TextEncoder().encode(streamOrData); - stream = ReadableStream.from([binaryData]); + stream = new ReadableStream({ + start(controller) { + controller.enqueue(binaryData); + controller.close(); + } + }); size = binaryData.length; } else if (streamOrData instanceof Uint8Array) { - stream = ReadableStream.from([streamOrData]); + stream = new ReadableStream({ + start(controller) { + controller.enqueue(streamOrData); + controller.close(); + } + }); size = streamOrData.byteLength; } else if (streamOrData instanceof ReadableStream) { stream = streamOrData; diff --git a/integration.ts b/integration.ts index 63eb0e9..66842c8 100644 --- a/integration.ts +++ b/integration.ts @@ -91,11 +91,14 @@ Deno.test({ name: "putObject() can stream a large file upload", fn: async () => { // First generate a 32MiB file in memory, 1 MiB at a time, as a stream - const dataStream = ReadableStream.from(async function* () { - for (let i = 0; i < 32; i++) { - yield new Uint8Array(1024 * 1024).fill(i % 256); // Yield 1MB of data + const dataStream = new ReadableStream({ + start(controller) { + for (let i = 0; i < 32; i++) { + controller.enqueue(new Uint8Array(1024 * 1024).fill(i % 256)); // Yield 1MB of data + } + controller.close(); } - }()); + }); // Upload the 32MB stream data as 7 5MB parts. The client doesn't know in advance how big the stream is. const key = "test-32m.dat"; From 183584053042265504740183aeb1d541a32ec3f9 Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Sun, 18 Feb 2024 03:54:10 +0100 Subject: [PATCH 12/13] fix: lint issue --- client.ts | 4 ++-- integration.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client.ts b/client.ts index 1295a90..426beff 100644 --- a/client.ts +++ b/client.ts @@ -652,7 +652,7 @@ export class Client { start(controller) { controller.enqueue(binaryData); controller.close(); - } + }, }); size = binaryData.length; } else if (streamOrData instanceof Uint8Array) { @@ -660,7 +660,7 @@ export class Client { start(controller) { controller.enqueue(streamOrData); controller.close(); - } + }, }); size = streamOrData.byteLength; } else if (streamOrData instanceof ReadableStream) { diff --git a/integration.ts b/integration.ts index 66842c8..714f35f 100644 --- a/integration.ts +++ b/integration.ts @@ -97,7 +97,7 @@ Deno.test({ controller.enqueue(new Uint8Array(1024 * 1024).fill(i % 256)); // Yield 1MB of data } controller.close(); - } + }, }); // Upload the 32MB stream data as 7 5MB parts. The client doesn't know in advance how big the stream is. From 811be45b04d1262641866bbb27903ed20a8bd5b1 Mon Sep 17 00:00:00 2001 From: Martin Donadieu Date: Sun, 18 Feb 2024 05:35:43 +0100 Subject: [PATCH 13/13] fix: use optional shiming like oak --- build_npm.ts | 18 +++++++++--------- mod.ts | 2 ++ node_shims.ts | 25 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 node_shims.ts diff --git a/build_npm.ts b/build_npm.ts index a30cccc..4ec655b 100644 --- a/build_npm.ts +++ b/build_npm.ts @@ -16,14 +16,14 @@ await build({ deno: { test: "dev", }, - custom: [ - { - package: { - name: "node:stream/web", - }, - globalNames: ["ReadableStream", "WritableStream", "TransformStream"], - }, - ], + }, + compilerOptions: { + lib: ["ESNext", "DOM"], + }, + mappings: { + "node:stream/web": { + name: "node:stream/web", + }, }, package: { name: "s3-lite-client", @@ -67,4 +67,4 @@ await build({ }, }); -console.log("Build complete. Run `cd npm && npm publish`."); +console.log("Build complete. Run `cd npm && npm publish && cd ..`."); diff --git a/mod.ts b/mod.ts index 4f8deca..0973cb8 100644 --- a/mod.ts +++ b/mod.ts @@ -1,2 +1,4 @@ +import "./node_shims.ts"; + export { Client as S3Client } from "./client.ts"; export * as S3Errors from "./errors.ts"; diff --git a/node_shims.ts b/node_shims.ts new file mode 100644 index 0000000..a2b35d8 --- /dev/null +++ b/node_shims.ts @@ -0,0 +1,25 @@ +if (!("ReadableStream" in globalThis) || !("TransformStream" in globalThis) || !("WritableStream" in globalThis)) { + (async () => { + const { ReadableStream, TransformStream, WritableStream } = await import("node:stream/web"); + Object.defineProperties(globalThis, { + "ReadableStream": { + value: ReadableStream, + writable: true, + enumerable: false, + configurable: true, + }, + "TransformStream": { + value: TransformStream, + writable: true, + enumerable: false, + configurable: true, + }, + "WritableStream": { + value: WritableStream, + writable: true, + enumerable: false, + configurable: true, + }, + }); + })(); +}