@opennextjs/aws 3.8.1 → 3.8.2

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
@@ -98,7 +98,28 @@ To run `OpenNext` locally:
98
98
 
99
99
  There is also a way to run OpenNext locally. You can read a guide about it [here](https://opennext.js.org/aws/contribute/local_run). Its mostly used for development/debugging purposes.
100
100
 
101
- ### Coldstart
101
+ ## Testing
102
+
103
+ You can run unit tests with
104
+
105
+ ```bash
106
+ pnpm test
107
+ ```
108
+
109
+ You can tun e2e locally with:
110
+
111
+ ```bash
112
+ pnpm -r openbuild:local
113
+ pnpm -r openbuild:local:start
114
+ ```
115
+
116
+ And in a different shell:
117
+
118
+ ```bash
119
+ pnpm e2e:test
120
+ ```
121
+
122
+ ## Coldstart
102
123
 
103
124
  OpenNext provide you with a warmer function that can be used to reduce cold start.
104
125
 
@@ -1,5 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import { createRequire } from "node:module";
3
+ import os from "node:os";
3
4
  import path from "node:path";
4
5
  import logger from "../logger.js";
5
6
  import { openNextReplacementPlugin } from "../plugins/replacement.js";
@@ -74,10 +75,14 @@ export async function createImageOptimizationBundle(options) {
74
75
  // Target should be same as used by Lambda, see https://github.com/sst/sst/blob/ca6f763fdfddd099ce2260202d0ce48c72e211ea/packages/sst/src/constructs/NextjsSite.ts#L114
75
76
  // For SHARP_IGNORE_GLOBAL_LIBVIPS see: https://github.com/lovell/sharp/blob/main/docs/install.md#aws-lambda
76
77
  const sharpVersion = process.env.SHARP_VERSION ?? "0.32.6";
78
+ // In development, we want to use the local machine settings
79
+ const isDev = config.imageOptimization?.loader === "fs-dev";
77
80
  installDependencies(outputPath, config.imageOptimization?.install ?? {
78
81
  packages: [`sharp@${sharpVersion}`],
79
- // By not specifying an arch, `npm install` will choose one for us (i.e. our system one)
80
- arch: config.imageOptimization?.loader === "fs-dev" ? undefined : "arm64",
82
+ // By not specifying an arch in dev, `npm install` will choose one for us (i.e. our system one)
83
+ arch: isDev ? undefined : "arm64",
84
+ // Use the local platform in dev
85
+ os: isDev ? os.platform() : "linux",
81
86
  nodeVersion: "18",
82
87
  libc: "glibc",
83
88
  });
@@ -24,8 +24,9 @@ export function installDependencies(outputDir, installOptions) {
24
24
  const libcOption = installOptions.libc
25
25
  ? `--libc=${installOptions.libc}`
26
26
  : "";
27
+ const osOption = `--os=${installOptions.os ?? "linux"}`;
27
28
  const additionalArgs = installOptions.additionalArgs ?? "";
28
- const installCommand = `npm install --platform=linux ${archOption} ${targetOption} ${libcOption} ${additionalArgs} ${installOptions.packages.join(" ")}`;
29
+ const installCommand = `npm install ${osOption} ${archOption} ${targetOption} ${libcOption} ${additionalArgs} ${installOptions.packages.join(" ")}`;
29
30
  execSync(installCommand, {
30
31
  stdio: "pipe",
31
32
  cwd: tempInstallDir,
@@ -177,13 +177,12 @@ export function convertBodyToReadableStream(method, body) {
177
177
  return undefined;
178
178
  if (!body)
179
179
  return undefined;
180
- const readable = new ReadableStream({
180
+ return new ReadableStream({
181
181
  start(controller) {
182
182
  controller.enqueue(body);
183
183
  controller.close();
184
184
  },
185
185
  });
186
- return readable;
187
186
  }
188
187
  var CommonHeaders;
189
188
  (function (CommonHeaders) {
@@ -190,18 +190,14 @@ export interface InstallOptions {
190
190
  * ```
191
191
  */
192
192
  packages: string[];
193
- /**
194
- * @default undefined
195
- */
193
+ /** @default undefined */
196
194
  arch?: "x64" | "arm64";
197
- /**
198
- * @default undefined
199
- */
195
+ /** @default undefined */
200
196
  nodeVersion?: string;
201
- /**
202
- * @default undefined
203
- */
197
+ /** @default undefined */
204
198
  libc?: "glibc" | "musl";
199
+ /** @default "linux" */
200
+ os?: string;
205
201
  /**
206
202
  * @default undefined
207
203
  * Additional arguments to pass to the install command (i.e. npm install)
@@ -61,6 +61,6 @@ const commonBinaryMimeTypes = new Set([
61
61
  export function isBinaryContentType(contentType) {
62
62
  if (!contentType)
63
63
  return false;
64
- const value = contentType?.split(";")[0] ?? "";
64
+ const value = contentType.split(";")[0];
65
65
  return commonBinaryMimeTypes.has(value);
66
66
  }
@@ -17,7 +17,6 @@ export function customFetchClient(client) {
17
17
  * This is necessary otherwise we get some error : SocketError: other side closed
18
18
  * https://github.com/nodejs/undici/issues/583#issuecomment-855384858
19
19
  */
20
- const clonedResponse = response.clone();
21
- return clonedResponse;
20
+ return response.clone();
22
21
  };
23
22
  }
@@ -1,4 +1,4 @@
1
- import type { ReadableStream } from "node:stream/web";
1
+ import { ReadableStream } from "node:stream/web";
2
2
  export declare function fromReadableStream(stream: ReadableStream<Uint8Array>, base64?: boolean): Promise<string>;
3
3
  export declare function toReadableStream(value: string, isBase64?: boolean): ReadableStream;
4
4
  export declare function emptyReadableStream(): ReadableStream;
@@ -1,30 +1,49 @@
1
- import { Readable } from "node:stream";
2
- export function fromReadableStream(stream, base64) {
3
- const reader = stream.getReader();
1
+ import { ReadableStream } from "node:stream/web";
2
+ export async function fromReadableStream(stream, base64) {
4
3
  const chunks = [];
5
- return new Promise((resolve, reject) => {
6
- function pump() {
7
- reader
8
- .read()
9
- .then(({ done, value }) => {
10
- if (done) {
11
- resolve(Buffer.concat(chunks).toString(base64 ? "base64" : "utf8"));
12
- return;
13
- }
14
- chunks.push(value);
15
- pump();
16
- })
17
- .catch(reject);
18
- }
19
- pump();
20
- });
4
+ let totalLength = 0;
5
+ for await (const chunk of stream) {
6
+ chunks.push(chunk);
7
+ totalLength += chunk.length;
8
+ }
9
+ if (chunks.length === 0) {
10
+ return "";
11
+ }
12
+ if (chunks.length === 1) {
13
+ return Buffer.from(chunks[0]).toString(base64 ? "base64" : "utf8");
14
+ }
15
+ // Pre-allocate buffer with exact size to avoid reallocation
16
+ const buffer = Buffer.alloc(totalLength);
17
+ let offset = 0;
18
+ for (const chunk of chunks) {
19
+ buffer.set(chunk, offset);
20
+ offset += chunk.length;
21
+ }
22
+ return buffer.toString(base64 ? "base64" : "utf8");
21
23
  }
22
24
  export function toReadableStream(value, isBase64) {
23
- return Readable.toWeb(Readable.from(Buffer.from(value, isBase64 ? "base64" : "utf8")));
25
+ return new ReadableStream({
26
+ pull(controller) {
27
+ // Defer the Buffer.from conversion to when the stream is actually read.
28
+ controller.enqueue(Buffer.from(value, isBase64 ? "base64" : "utf8"));
29
+ controller.close();
30
+ },
31
+ }, { highWaterMark: 0 });
24
32
  }
33
+ let maybeSomethingBuffer;
25
34
  export function emptyReadableStream() {
26
35
  if (process.env.OPEN_NEXT_FORCE_NON_EMPTY_RESPONSE === "true") {
27
- return Readable.toWeb(Readable.from([Buffer.from("SOMETHING")]));
36
+ return new ReadableStream({
37
+ pull(controller) {
38
+ maybeSomethingBuffer ??= Buffer.from("SOMETHING");
39
+ controller.enqueue(maybeSomethingBuffer);
40
+ controller.close();
41
+ },
42
+ }, { highWaterMark: 0 });
28
43
  }
29
- return Readable.toWeb(Readable.from([]));
44
+ return new ReadableStream({
45
+ start(controller) {
46
+ controller.close();
47
+ },
48
+ });
30
49
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "access": "public"
4
4
  },
5
5
  "name": "@opennextjs/aws",
6
- "version": "3.8.1",
6
+ "version": "3.8.2",
7
7
  "bin": {
8
8
  "open-next": "./dist/index.js"
9
9
  },