@marko/run 0.1.15 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,10 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
18
24
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
25
 
20
26
  // src/adapter/middleware.ts
@@ -22,6 +28,7 @@ var middleware_exports = {};
22
28
  __export(middleware_exports, {
23
29
  createMiddleware: () => createMiddleware,
24
30
  getOrigin: () => getOrigin,
31
+ getSetCookie_fallback: () => getSetCookie_fallback,
25
32
  setResponseHeaders: () => setResponseHeaders
26
33
  });
27
34
  module.exports = __toCommonJS(middleware_exports);
@@ -31,62 +38,21 @@ var import_url = require("url");
31
38
  var __importMetaURL = (0, import_url.pathToFileURL)(__filename);
32
39
 
33
40
  // src/adapter/polyfill.ts
34
- var import_web = require("stream/web");
41
+ var webStream = __toESM(require("stream/web"), 1);
35
42
  var import_crypto = require("crypto");
36
- var import_undici = require("undici");
37
- var import_http = require("http");
38
- var globals = {
39
- crypto: import_crypto.webcrypto,
40
- fetch: import_undici.fetch,
41
- Response: import_undici.Response,
42
- Request: import_undici.Request,
43
- Headers: import_undici.Headers,
44
- ReadableStream: import_web.ReadableStream,
45
- TransformStream: import_web.TransformStream,
46
- WritableStream: import_web.WritableStream,
47
- FormData: import_undici.FormData,
48
- File: import_undici.File
49
- };
50
- if (typeof import_http.OutgoingMessage.prototype.appendHeader !== "function") {
51
- const messageHeaders = /* @__PURE__ */ new WeakMap();
52
- import_http.OutgoingMessage.prototype.appendHeader = function(name, value) {
53
- let headers = messageHeaders.get(this);
54
- if (!headers) {
55
- headers = /* @__PURE__ */ new Map();
56
- messageHeaders.set(this, headers);
57
- }
58
- const key = name.toLowerCase();
59
- let existing = headers.get(key);
60
- if (existing) {
61
- if (Array.isArray(existing)) {
62
- existing.push(value);
63
- } else {
64
- existing = [existing, value];
65
- }
66
- this.setHeader(name, existing);
67
- headers.set(key, existing);
68
- } else {
69
- this.setHeader(name, value);
70
- headers.set(key, value);
71
- }
72
- return this;
73
- };
74
- }
75
- function installPolyfills() {
76
- for (const name in globals) {
77
- if (!(name in globalThis)) {
78
- Object.defineProperty(globalThis, name, {
79
- enumerable: true,
80
- configurable: true,
81
- writable: true,
82
- value: globals[name]
83
- });
84
- }
85
- }
86
- }
43
+ var undici = __toESM(require("undici"), 1);
44
+ globalThis.crypto ?? (globalThis.crypto = import_crypto.webcrypto);
45
+ globalThis.fetch ?? (globalThis.fetch = undici.fetch);
46
+ globalThis.Response ?? (globalThis.Response = undici.Response);
47
+ globalThis.Request ?? (globalThis.Request = undici.Request);
48
+ globalThis.Headers ?? (globalThis.Headers = undici.Headers);
49
+ globalThis.ReadableStream ?? (globalThis.ReadableStream = webStream.ReadableStream);
50
+ globalThis.TransformStream ?? (globalThis.TransformStream = webStream.TransformStream);
51
+ globalThis.WritableStream ?? (globalThis.WritableStream = webStream.WritableStream);
52
+ globalThis.FormData ?? (globalThis.FormData = undici.FormData);
53
+ globalThis.File ?? (globalThis.File = undici.File);
87
54
 
88
55
  // src/adapter/middleware.ts
89
- installPolyfills();
90
56
  function getForwardedHeader(req, name) {
91
57
  const value = req.headers["x-forwarded-" + name];
92
58
  if (value) {
@@ -97,10 +63,9 @@ function getForwardedHeader(req, name) {
97
63
  return value[0];
98
64
  }
99
65
  }
100
- function getOrigin(req, protocol, host, trustProxy) {
101
- var _a;
102
- protocol ?? (protocol = req.protocol || trustProxy && getForwardedHeader(req, "proto") || ((_a = req.socket) == null ? void 0 : _a.encrypted) && "https" || "http");
103
- host ?? (host = trustProxy && getForwardedHeader(req, "host") || req.headers.host);
66
+ function getOrigin(req, trustProxy) {
67
+ const protocol = req.protocol || trustProxy && getForwardedHeader(req, "proto") || (req.socket.encrypted ? "https" : "http");
68
+ let host = req.headers.host || trustProxy && getForwardedHeader(req, "host");
104
69
  if (!host) {
105
70
  if (process.env.NODE_ENV !== "production") {
106
71
  host = "localhost";
@@ -118,70 +83,116 @@ function getOrigin(req, protocol, host, trustProxy) {
118
83
  var inExpiresDateRgs = /Expires\s*=\s*(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*$/i;
119
84
  function setResponseHeaders(response, res) {
120
85
  for (const [key, value] of response.headers) {
121
- if (key === "set-cookie") {
122
- let sepIndex = value.indexOf(",") + 1;
123
- if (!sepIndex) {
124
- res.setHeader(key, value);
86
+ if (key !== "set-cookie") {
87
+ res.setHeader(key, value);
88
+ }
89
+ }
90
+ const setCookies = getSetCookie(response.headers);
91
+ if (setCookies == null ? void 0 : setCookies.length) {
92
+ res.setHeader("set-cookie", setCookies);
93
+ }
94
+ }
95
+ var getSetCookie = Headers.prototype.getSetCookie ? getSetCookie_platform : getSetCookie_fallback;
96
+ function getSetCookie_platform(headers) {
97
+ return headers.getSetCookie();
98
+ }
99
+ function getSetCookie_fallback(headers) {
100
+ const value = headers.get("set-cookie");
101
+ if (!value)
102
+ return void 0;
103
+ let sepIndex = value.indexOf(",") + 1;
104
+ if (!sepIndex)
105
+ return value;
106
+ let index = 0;
107
+ let setCookie = void 0;
108
+ let setCookies = void 0;
109
+ do {
110
+ const valuePart = value.slice(index, sepIndex - 1);
111
+ if (!inExpiresDateRgs.test(valuePart)) {
112
+ if (setCookies) {
113
+ setCookies.push(valuePart);
114
+ } else if (setCookie) {
115
+ setCookies = [setCookie, valuePart];
125
116
  } else {
126
- let index = 0;
127
- do {
128
- const valuePart = value.slice(index, sepIndex - 1);
129
- if (!inExpiresDateRgs.test(valuePart)) {
130
- res.appendHeader(key, valuePart);
131
- index = sepIndex;
132
- }
133
- sepIndex = value.indexOf(",", sepIndex) + 1;
134
- } while (sepIndex);
135
- res.appendHeader(key, value.slice(index));
117
+ setCookie = valuePart;
136
118
  }
137
- } else {
138
- res.setHeader(key, value);
119
+ index = sepIndex;
120
+ while (value.charCodeAt(index) === 32)
121
+ index++;
139
122
  }
123
+ sepIndex = value.indexOf(",", sepIndex) + 1;
124
+ } while (sepIndex);
125
+ if (index) {
126
+ const valuePart = value.slice(index);
127
+ if (setCookies) {
128
+ setCookies.push(valuePart);
129
+ return setCookies;
130
+ }
131
+ return [setCookie, valuePart];
140
132
  }
133
+ return value;
141
134
  }
142
135
  function createMiddleware(fetch2, options = {}) {
143
- const { trustProxy = process.env.TRUST_PROXY === "1", devServer } = options;
144
- let { origin = process.env.ORIGIN } = options;
145
- let protocol;
146
- let host;
147
- if (origin) {
148
- ({ protocol, host } = new URL(origin));
149
- protocol = protocol.slice(0, -1);
150
- }
136
+ const {
137
+ origin = process.env.ORIGIN,
138
+ trustProxy = process.env.TRUST_PROXY === "1",
139
+ devServer
140
+ } = options;
151
141
  return async (req, res, next) => {
152
- origin ?? (origin = getOrigin(req, protocol, host, trustProxy));
153
- const url = new URL(req.url, origin);
142
+ const controller = new AbortController();
143
+ const { signal } = controller;
144
+ const url = new URL(req.url, origin || getOrigin(req, trustProxy));
154
145
  const ip = req.ip || trustProxy && getForwardedHeader(req, "for") || req.socket.remoteAddress || "";
155
146
  const headers = req.headers;
156
- const body = req.method === "GET" || req.method === "HEAD" ? void 0 : req.socket ? req : new ReadableStream({
157
- start(controller) {
158
- req.on("data", (chunk) => controller.enqueue(chunk));
159
- req.on("end", () => controller.close());
160
- req.on("error", (err) => controller.error(err));
161
- }
162
- });
147
+ req.on("error", onError);
148
+ res.on("error", onError);
149
+ req.socket.on("error", onError);
150
+ function onError(err) {
151
+ req.off("error", onError);
152
+ res.off("error", onError);
153
+ req.socket.off("error", onError);
154
+ controller.abort(err);
155
+ }
156
+ if (process.env.NODE_ENV !== "production" && devServer) {
157
+ devServer.ws.on("connection", function onConnection(ws) {
158
+ devServer.ws.off("connection", onConnection);
159
+ if (signal.aborted) {
160
+ sendError();
161
+ } else {
162
+ signal.addEventListener("abort", sendError);
163
+ }
164
+ function sendError() {
165
+ const { message, stack = "" } = signal.reason;
166
+ ws.send(
167
+ JSON.stringify({
168
+ type: "error",
169
+ err: { message, stack }
170
+ })
171
+ );
172
+ }
173
+ });
174
+ } else {
175
+ signal.addEventListener("abort", () => {
176
+ if (!res.destroyed && res.socket) {
177
+ res.socket.destroySoon();
178
+ }
179
+ });
180
+ }
163
181
  const request = new Request(url, {
164
182
  method: req.method,
165
183
  headers,
166
- body,
167
- duplex: "half"
184
+ body: req.method === "GET" || req.method === "HEAD" ? void 0 : req,
185
+ duplex: "half",
186
+ signal
168
187
  });
169
188
  const response = await fetch2(request, {
170
189
  ip,
171
190
  request: req,
172
- response: res,
173
- setCookie(cookie) {
174
- res.appendHeader("set-cookie", cookie);
175
- }
191
+ response: res
176
192
  });
177
193
  if (!response) {
178
194
  if (next) {
179
195
  next();
180
- } else {
181
- res.statusCode = 404;
182
- res.setHeader("content-length", "0");
183
- res.end();
184
- return;
185
196
  }
186
197
  return;
187
198
  }
@@ -193,58 +204,35 @@ function createMiddleware(fetch2, options = {}) {
193
204
  }
194
205
  res.end();
195
206
  return;
196
- }
197
- const reader = response.body.getReader();
198
- if (res.destroyed) {
199
- reader.cancel();
207
+ } else if (res.destroyed) {
208
+ controller.abort(new Error("Response stream destroyed"));
200
209
  return;
201
210
  }
202
- res.on("close", cancel);
203
- res.on("error", cancel);
204
- write();
205
- function cancel(error) {
206
- res.off("close", cancel);
207
- res.off("error", cancel);
208
- reader.cancel(error).catch(() => {
209
- });
210
- if (error) {
211
- if (process.env.NODE_ENV !== "production" && devServer) {
212
- res.end();
213
- devServer.ws.send({
214
- type: "error",
215
- err: { message: error.message, stack: error.stack || "" }
216
- });
217
- } else {
218
- res.destroy(error);
219
- }
220
- }
221
- }
222
- async function write() {
223
- try {
224
- while (true) {
225
- const { done, value } = await reader.read();
226
- if (done) {
227
- res.end();
228
- return;
229
- } else if (!res.write(value)) {
230
- res.once("drain", write);
231
- return;
232
- } else if (res.flush) {
233
- res.flush();
234
- }
235
- }
236
- } catch (err) {
237
- const error = err instanceof Error ? err : new Error("Error while writing to node response", {
238
- cause: err
239
- });
240
- cancel(error);
211
+ writeResponse(response.body.getReader(), res, controller);
212
+ };
213
+ }
214
+ async function writeResponse(reader, res, controller) {
215
+ try {
216
+ while (!controller.signal.aborted) {
217
+ const { done, value } = await reader.read();
218
+ if (done) {
219
+ res.end();
220
+ return;
221
+ } else if (!res.write(value)) {
222
+ res.once("drain", () => writeResponse(reader, res, controller));
223
+ return;
224
+ } else if (res.flush) {
225
+ res.flush();
241
226
  }
242
227
  }
243
- };
228
+ } catch (err) {
229
+ controller.abort(err);
230
+ }
244
231
  }
245
232
  // Annotate the CommonJS export names for ESM import in node:
246
233
  0 && (module.exports = {
247
234
  createMiddleware,
248
235
  getOrigin,
236
+ getSetCookie_fallback,
249
237
  setResponseHeaders
250
238
  });
@@ -1,29 +1,15 @@
1
1
  /// <reference types="node" />
2
+ import "./polyfill";
2
3
  import type { Fetch } from "../runtime";
3
- import type { IncomingMessage, ServerResponse } from "http";
4
+ import type { IncomingMessage, ServerResponse, OutgoingMessage } from "http";
4
5
  import type { ViteDevServer } from "vite";
5
- import { OutgoingMessage } from "http";
6
- declare module "net" {
7
- interface Socket {
8
- encrypted?: boolean;
9
- }
10
- }
11
- declare module "http" {
12
- interface IncomingMessage {
13
- ip?: string;
14
- protocol?: string;
15
- }
16
- }
17
6
  export interface NodePlatformInfo {
18
7
  ip: string;
19
8
  request: IncomingMessage;
20
9
  response: ServerResponse;
21
- setCookie(cookie: string): void;
22
10
  }
23
11
  /** Connect/Express style request listener/middleware */
24
- export type NodeMiddleware = (req: IncomingMessage, res: ServerResponse & {
25
- flush?: () => void;
26
- }, next?: () => void) => void;
12
+ export type NodeMiddleware = (req: IncomingMessage, res: ServerResponse, next?: () => void) => void;
27
13
  /** Adapter options */
28
14
  export interface NodeAdapterOptions {
29
15
  /**
@@ -48,8 +34,9 @@ export interface NodeAdapterOptions {
48
34
  trustProxy?: boolean;
49
35
  devServer?: ViteDevServer;
50
36
  }
51
- export declare function getOrigin(req: IncomingMessage, protocol?: string, host?: string, trustProxy?: boolean): string;
37
+ export declare function getOrigin(req: IncomingMessage, trustProxy?: boolean): string;
52
38
  export declare function setResponseHeaders(response: Response, res: OutgoingMessage): void;
39
+ export declare function getSetCookie_fallback(headers: Headers): string | string[] | undefined;
53
40
  /**
54
41
  * Creates a request handler to be passed to http.createServer() or used as a
55
42
  * middleware in Connect-style frameworks like Express.
@@ -1,60 +1,19 @@
1
1
  // src/adapter/polyfill.ts
2
- import { ReadableStream as ReadableStream2, TransformStream, WritableStream } from "stream/web";
3
- import { webcrypto as crypto } from "crypto";
4
- import { fetch, Response, Request as Request2, Headers, FormData, File } from "undici";
5
- import { OutgoingMessage } from "http";
6
- var globals = {
7
- crypto,
8
- fetch,
9
- Response,
10
- Request: Request2,
11
- Headers,
12
- ReadableStream: ReadableStream2,
13
- TransformStream,
14
- WritableStream,
15
- FormData,
16
- File
17
- };
18
- if (typeof OutgoingMessage.prototype.appendHeader !== "function") {
19
- const messageHeaders = /* @__PURE__ */ new WeakMap();
20
- OutgoingMessage.prototype.appendHeader = function(name, value) {
21
- let headers = messageHeaders.get(this);
22
- if (!headers) {
23
- headers = /* @__PURE__ */ new Map();
24
- messageHeaders.set(this, headers);
25
- }
26
- const key = name.toLowerCase();
27
- let existing = headers.get(key);
28
- if (existing) {
29
- if (Array.isArray(existing)) {
30
- existing.push(value);
31
- } else {
32
- existing = [existing, value];
33
- }
34
- this.setHeader(name, existing);
35
- headers.set(key, existing);
36
- } else {
37
- this.setHeader(name, value);
38
- headers.set(key, value);
39
- }
40
- return this;
41
- };
42
- }
43
- function installPolyfills() {
44
- for (const name in globals) {
45
- if (!(name in globalThis)) {
46
- Object.defineProperty(globalThis, name, {
47
- enumerable: true,
48
- configurable: true,
49
- writable: true,
50
- value: globals[name]
51
- });
52
- }
53
- }
54
- }
2
+ import * as webStream from "stream/web";
3
+ import { webcrypto } from "crypto";
4
+ import * as undici from "undici";
5
+ globalThis.crypto ?? (globalThis.crypto = webcrypto);
6
+ globalThis.fetch ?? (globalThis.fetch = undici.fetch);
7
+ globalThis.Response ?? (globalThis.Response = undici.Response);
8
+ globalThis.Request ?? (globalThis.Request = undici.Request);
9
+ globalThis.Headers ?? (globalThis.Headers = undici.Headers);
10
+ globalThis.ReadableStream ?? (globalThis.ReadableStream = webStream.ReadableStream);
11
+ globalThis.TransformStream ?? (globalThis.TransformStream = webStream.TransformStream);
12
+ globalThis.WritableStream ?? (globalThis.WritableStream = webStream.WritableStream);
13
+ globalThis.FormData ?? (globalThis.FormData = undici.FormData);
14
+ globalThis.File ?? (globalThis.File = undici.File);
55
15
 
56
16
  // src/adapter/middleware.ts
57
- installPolyfills();
58
17
  function getForwardedHeader(req, name) {
59
18
  const value = req.headers["x-forwarded-" + name];
60
19
  if (value) {
@@ -65,10 +24,9 @@ function getForwardedHeader(req, name) {
65
24
  return value[0];
66
25
  }
67
26
  }
68
- function getOrigin(req, protocol, host, trustProxy) {
69
- var _a;
70
- protocol ?? (protocol = req.protocol || trustProxy && getForwardedHeader(req, "proto") || ((_a = req.socket) == null ? void 0 : _a.encrypted) && "https" || "http");
71
- host ?? (host = trustProxy && getForwardedHeader(req, "host") || req.headers.host);
27
+ function getOrigin(req, trustProxy) {
28
+ const protocol = req.protocol || trustProxy && getForwardedHeader(req, "proto") || (req.socket.encrypted ? "https" : "http");
29
+ let host = req.headers.host || trustProxy && getForwardedHeader(req, "host");
72
30
  if (!host) {
73
31
  if (process.env.NODE_ENV !== "production") {
74
32
  host = "localhost";
@@ -86,70 +44,116 @@ function getOrigin(req, protocol, host, trustProxy) {
86
44
  var inExpiresDateRgs = /Expires\s*=\s*(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*$/i;
87
45
  function setResponseHeaders(response, res) {
88
46
  for (const [key, value] of response.headers) {
89
- if (key === "set-cookie") {
90
- let sepIndex = value.indexOf(",") + 1;
91
- if (!sepIndex) {
92
- res.setHeader(key, value);
47
+ if (key !== "set-cookie") {
48
+ res.setHeader(key, value);
49
+ }
50
+ }
51
+ const setCookies = getSetCookie(response.headers);
52
+ if (setCookies == null ? void 0 : setCookies.length) {
53
+ res.setHeader("set-cookie", setCookies);
54
+ }
55
+ }
56
+ var getSetCookie = Headers.prototype.getSetCookie ? getSetCookie_platform : getSetCookie_fallback;
57
+ function getSetCookie_platform(headers) {
58
+ return headers.getSetCookie();
59
+ }
60
+ function getSetCookie_fallback(headers) {
61
+ const value = headers.get("set-cookie");
62
+ if (!value)
63
+ return void 0;
64
+ let sepIndex = value.indexOf(",") + 1;
65
+ if (!sepIndex)
66
+ return value;
67
+ let index = 0;
68
+ let setCookie = void 0;
69
+ let setCookies = void 0;
70
+ do {
71
+ const valuePart = value.slice(index, sepIndex - 1);
72
+ if (!inExpiresDateRgs.test(valuePart)) {
73
+ if (setCookies) {
74
+ setCookies.push(valuePart);
75
+ } else if (setCookie) {
76
+ setCookies = [setCookie, valuePart];
93
77
  } else {
94
- let index = 0;
95
- do {
96
- const valuePart = value.slice(index, sepIndex - 1);
97
- if (!inExpiresDateRgs.test(valuePart)) {
98
- res.appendHeader(key, valuePart);
99
- index = sepIndex;
100
- }
101
- sepIndex = value.indexOf(",", sepIndex) + 1;
102
- } while (sepIndex);
103
- res.appendHeader(key, value.slice(index));
78
+ setCookie = valuePart;
104
79
  }
105
- } else {
106
- res.setHeader(key, value);
80
+ index = sepIndex;
81
+ while (value.charCodeAt(index) === 32)
82
+ index++;
107
83
  }
84
+ sepIndex = value.indexOf(",", sepIndex) + 1;
85
+ } while (sepIndex);
86
+ if (index) {
87
+ const valuePart = value.slice(index);
88
+ if (setCookies) {
89
+ setCookies.push(valuePart);
90
+ return setCookies;
91
+ }
92
+ return [setCookie, valuePart];
108
93
  }
94
+ return value;
109
95
  }
110
96
  function createMiddleware(fetch2, options = {}) {
111
- const { trustProxy = process.env.TRUST_PROXY === "1", devServer } = options;
112
- let { origin = process.env.ORIGIN } = options;
113
- let protocol;
114
- let host;
115
- if (origin) {
116
- ({ protocol, host } = new URL(origin));
117
- protocol = protocol.slice(0, -1);
118
- }
97
+ const {
98
+ origin = process.env.ORIGIN,
99
+ trustProxy = process.env.TRUST_PROXY === "1",
100
+ devServer
101
+ } = options;
119
102
  return async (req, res, next) => {
120
- origin ?? (origin = getOrigin(req, protocol, host, trustProxy));
121
- const url = new URL(req.url, origin);
103
+ const controller = new AbortController();
104
+ const { signal } = controller;
105
+ const url = new URL(req.url, origin || getOrigin(req, trustProxy));
122
106
  const ip = req.ip || trustProxy && getForwardedHeader(req, "for") || req.socket.remoteAddress || "";
123
107
  const headers = req.headers;
124
- const body = req.method === "GET" || req.method === "HEAD" ? void 0 : req.socket ? req : new ReadableStream({
125
- start(controller) {
126
- req.on("data", (chunk) => controller.enqueue(chunk));
127
- req.on("end", () => controller.close());
128
- req.on("error", (err) => controller.error(err));
129
- }
130
- });
108
+ req.on("error", onError);
109
+ res.on("error", onError);
110
+ req.socket.on("error", onError);
111
+ function onError(err) {
112
+ req.off("error", onError);
113
+ res.off("error", onError);
114
+ req.socket.off("error", onError);
115
+ controller.abort(err);
116
+ }
117
+ if (process.env.NODE_ENV !== "production" && devServer) {
118
+ devServer.ws.on("connection", function onConnection(ws) {
119
+ devServer.ws.off("connection", onConnection);
120
+ if (signal.aborted) {
121
+ sendError();
122
+ } else {
123
+ signal.addEventListener("abort", sendError);
124
+ }
125
+ function sendError() {
126
+ const { message, stack = "" } = signal.reason;
127
+ ws.send(
128
+ JSON.stringify({
129
+ type: "error",
130
+ err: { message, stack }
131
+ })
132
+ );
133
+ }
134
+ });
135
+ } else {
136
+ signal.addEventListener("abort", () => {
137
+ if (!res.destroyed && res.socket) {
138
+ res.socket.destroySoon();
139
+ }
140
+ });
141
+ }
131
142
  const request = new Request(url, {
132
143
  method: req.method,
133
144
  headers,
134
- body,
135
- duplex: "half"
145
+ body: req.method === "GET" || req.method === "HEAD" ? void 0 : req,
146
+ duplex: "half",
147
+ signal
136
148
  });
137
149
  const response = await fetch2(request, {
138
150
  ip,
139
151
  request: req,
140
- response: res,
141
- setCookie(cookie) {
142
- res.appendHeader("set-cookie", cookie);
143
- }
152
+ response: res
144
153
  });
145
154
  if (!response) {
146
155
  if (next) {
147
156
  next();
148
- } else {
149
- res.statusCode = 404;
150
- res.setHeader("content-length", "0");
151
- res.end();
152
- return;
153
157
  }
154
158
  return;
155
159
  }
@@ -161,57 +165,34 @@ function createMiddleware(fetch2, options = {}) {
161
165
  }
162
166
  res.end();
163
167
  return;
164
- }
165
- const reader = response.body.getReader();
166
- if (res.destroyed) {
167
- reader.cancel();
168
+ } else if (res.destroyed) {
169
+ controller.abort(new Error("Response stream destroyed"));
168
170
  return;
169
171
  }
170
- res.on("close", cancel);
171
- res.on("error", cancel);
172
- write();
173
- function cancel(error) {
174
- res.off("close", cancel);
175
- res.off("error", cancel);
176
- reader.cancel(error).catch(() => {
177
- });
178
- if (error) {
179
- if (process.env.NODE_ENV !== "production" && devServer) {
180
- res.end();
181
- devServer.ws.send({
182
- type: "error",
183
- err: { message: error.message, stack: error.stack || "" }
184
- });
185
- } else {
186
- res.destroy(error);
187
- }
188
- }
189
- }
190
- async function write() {
191
- try {
192
- while (true) {
193
- const { done, value } = await reader.read();
194
- if (done) {
195
- res.end();
196
- return;
197
- } else if (!res.write(value)) {
198
- res.once("drain", write);
199
- return;
200
- } else if (res.flush) {
201
- res.flush();
202
- }
203
- }
204
- } catch (err) {
205
- const error = err instanceof Error ? err : new Error("Error while writing to node response", {
206
- cause: err
207
- });
208
- cancel(error);
172
+ writeResponse(response.body.getReader(), res, controller);
173
+ };
174
+ }
175
+ async function writeResponse(reader, res, controller) {
176
+ try {
177
+ while (!controller.signal.aborted) {
178
+ const { done, value } = await reader.read();
179
+ if (done) {
180
+ res.end();
181
+ return;
182
+ } else if (!res.write(value)) {
183
+ res.once("drain", () => writeResponse(reader, res, controller));
184
+ return;
185
+ } else if (res.flush) {
186
+ res.flush();
209
187
  }
210
188
  }
211
- };
189
+ } catch (err) {
190
+ controller.abort(err);
191
+ }
212
192
  }
213
193
  export {
214
194
  createMiddleware,
215
195
  getOrigin,
196
+ getSetCookie_fallback,
216
197
  setResponseHeaders
217
198
  };
@@ -1,6 +1,6 @@
1
- declare module 'http' {
2
- interface OutgoingMessage {
3
- appendHeader(this: OutgoingMessage, name: string, value: string): this;
1
+ declare global {
2
+ interface Headers {
3
+ getSetCookie: () => string[];
4
4
  }
5
5
  }
6
- export declare function installPolyfills(): void;
6
+ export {};
@@ -746,7 +746,7 @@ const page404ResponseInit = {
746
746
  if (routes.special[RoutableFileTypes.Error]) {
747
747
  imports.writeLines(`
748
748
  const page500ResponseInit = {
749
- status: 404,
749
+ status: 500,
750
750
  headers: { "content-type": "text/html;charset=UTF-8" },
751
751
  };`);
752
752
  writer.writeBlockStart(
@@ -704,7 +704,7 @@ const page404ResponseInit = {
704
704
  if (routes.special[RoutableFileTypes.Error]) {
705
705
  imports.writeLines(`
706
706
  const page500ResponseInit = {
707
- status: 404,
707
+ status: 500,
708
708
  headers: { "content-type": "text/html;charset=UTF-8" },
709
709
  };`);
710
710
  writer.writeBlockStart(
@@ -1,5 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
+ /// <reference types="node" />
3
4
  import { type Socket } from "net";
4
5
  import { type ChildProcess, type StdioOptions } from "child_process";
5
6
  import { type Worker } from "cluster";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marko/run",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "The Marko application framework.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/marko-js/run/tree/main/packages/run",
@@ -94,7 +94,7 @@
94
94
  "@types/human-format": "^1.0.0",
95
95
  "@types/jsdom": "^21.1.0",
96
96
  "@types/mocha": "^9.1.1",
97
- "@types/node": "^18.11.18",
97
+ "@types/node": "^20.3.1",
98
98
  "acorn": "^8.8.0",
99
99
  "cross-env": "^7.0.3",
100
100
  "esbuild": "^0.15.7",