@marko/run 0.1.14 → 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 {};
@@ -55,7 +55,6 @@ var virtualRoutesPrefix = `${virtualFilePrefix}/routes`;
55
55
  var virtualRuntimePrefix = `${virtualFilePrefix}/internal`;
56
56
  var httpVerbs = ["get", "post", "put", "delete"];
57
57
  var serverEntryQuery = "?marko-server-entry";
58
- var browserEntryQuery = "?marko-browser-entry";
59
58
  var RoutableFileTypes = {
60
59
  Page: "page",
61
60
  Layout: "layout",
@@ -73,9 +72,6 @@ var routeableFileRegex = new RegExp(
73
72
  `^[+](?:${markoFiles}|${nonMarkoFiles})$`,
74
73
  "i"
75
74
  );
76
- function isRoutableFile(filename) {
77
- return routeableFileRegex.test(filename);
78
- }
79
75
  function matchRoutableFile(filename) {
80
76
  const match = filename.match(routeableFileRegex);
81
77
  return match && (match[1] || match[3]).toLowerCase();
@@ -750,7 +746,7 @@ const page404ResponseInit = {
750
746
  if (routes.special[RoutableFileTypes.Error]) {
751
747
  imports.writeLines(`
752
748
  const page500ResponseInit = {
753
- status: 404,
749
+ status: 500,
754
750
  headers: { "content-type": "text/html;charset=UTF-8" },
755
751
  };`);
756
752
  writer.writeBlockStart(
@@ -1341,13 +1337,9 @@ var getExternalAdapterOptions = (viteConfig) => getConfig(viteConfig, AdapterCon
1341
1337
  // src/vite/plugin.ts
1342
1338
  var import_url2 = require("url");
1343
1339
  var __dirname = import_path2.default.dirname((0, import_url2.fileURLToPath)(__importMetaURL));
1344
- var markoExt = ".marko";
1345
1340
  var POSIX_SEP = "/";
1346
1341
  var WINDOWS_SEP = "\\";
1347
1342
  var normalizePath = import_path2.default.sep === WINDOWS_SEP ? (id) => id.replace(/\\/g, POSIX_SEP) : (id) => id;
1348
- function isMarkoFile(id) {
1349
- return id.endsWith(markoExt);
1350
- }
1351
1343
  function markoRun(opts = {}) {
1352
1344
  let { routesDir, adapter, ...markoVitePluginOptions } = opts;
1353
1345
  let compiler;
@@ -1578,15 +1570,14 @@ function markoRun(opts = {}) {
1578
1570
  configureServer(_server) {
1579
1571
  devServer = _server;
1580
1572
  devServer.watcher.on("all", async (type, filename) => {
1581
- const file = import_path2.default.parse(filename);
1582
- if (filename.startsWith(resolvedRoutesDir) && isRoutableFile(file.base)) {
1573
+ const routableFileType = matchRoutableFile(import_path2.default.parse(filename).base);
1574
+ if (filename.startsWith(resolvedRoutesDir) && routableFileType) {
1583
1575
  if (type === "add") {
1584
1576
  isStale = true;
1585
1577
  } else if (type === "unlink") {
1586
1578
  isStale = true;
1587
1579
  } else if (type === "change") {
1588
- const match = matchRoutableFile(file.base);
1589
- if (match === RoutableFileTypes.Handler) {
1580
+ if (routableFileType === RoutableFileTypes.Handler) {
1590
1581
  isStale = true;
1591
1582
  }
1592
1583
  }
@@ -1621,7 +1612,7 @@ function markoRun(opts = {}) {
1621
1612
  extractVerbs = isBuild ? getVerbsFromFileBuild.bind(null, this) : getVerbsFromFileDev.bind(null, devServer);
1622
1613
  }
1623
1614
  },
1624
- async resolveId(importee, importer, { ssr }) {
1615
+ async resolveId(importee, importer) {
1625
1616
  let resolved;
1626
1617
  if (importee.startsWith(virtualRuntimePrefix)) {
1627
1618
  return this.resolve(
@@ -1643,16 +1634,13 @@ function markoRun(opts = {}) {
1643
1634
  }
1644
1635
  if (virtualFiles.has(importee)) {
1645
1636
  resolved = importee;
1646
- if (!ssr && isMarkoFile(resolved)) {
1647
- resolved += browserEntryQuery;
1648
- }
1649
1637
  }
1650
1638
  return resolved || null;
1651
1639
  },
1652
1640
  async load(id) {
1653
1641
  var _a;
1654
- if (id.endsWith(browserEntryQuery)) {
1655
- id = id.slice(0, -browserEntryQuery.length);
1642
+ if (id.endsWith(serverEntryQuery)) {
1643
+ id = id.slice(0, -serverEntryQuery.length);
1656
1644
  }
1657
1645
  if (virtualFiles.has(id)) {
1658
1646
  if (!isRendered) {
@@ -13,7 +13,6 @@ var virtualRoutesPrefix = `${virtualFilePrefix}/routes`;
13
13
  var virtualRuntimePrefix = `${virtualFilePrefix}/internal`;
14
14
  var httpVerbs = ["get", "post", "put", "delete"];
15
15
  var serverEntryQuery = "?marko-server-entry";
16
- var browserEntryQuery = "?marko-browser-entry";
17
16
  var RoutableFileTypes = {
18
17
  Page: "page",
19
18
  Layout: "layout",
@@ -31,9 +30,6 @@ var routeableFileRegex = new RegExp(
31
30
  `^[+](?:${markoFiles}|${nonMarkoFiles})$`,
32
31
  "i"
33
32
  );
34
- function isRoutableFile(filename) {
35
- return routeableFileRegex.test(filename);
36
- }
37
33
  function matchRoutableFile(filename) {
38
34
  const match = filename.match(routeableFileRegex);
39
35
  return match && (match[1] || match[3]).toLowerCase();
@@ -708,7 +704,7 @@ const page404ResponseInit = {
708
704
  if (routes.special[RoutableFileTypes.Error]) {
709
705
  imports.writeLines(`
710
706
  const page500ResponseInit = {
711
- status: 404,
707
+ status: 500,
712
708
  headers: { "content-type": "text/html;charset=UTF-8" },
713
709
  };`);
714
710
  writer.writeBlockStart(
@@ -1299,13 +1295,9 @@ var getExternalAdapterOptions = (viteConfig) => getConfig(viteConfig, AdapterCon
1299
1295
  // src/vite/plugin.ts
1300
1296
  import { fileURLToPath } from "url";
1301
1297
  var __dirname = path2.dirname(fileURLToPath(import.meta.url));
1302
- var markoExt = ".marko";
1303
1298
  var POSIX_SEP = "/";
1304
1299
  var WINDOWS_SEP = "\\";
1305
1300
  var normalizePath = path2.sep === WINDOWS_SEP ? (id) => id.replace(/\\/g, POSIX_SEP) : (id) => id;
1306
- function isMarkoFile(id) {
1307
- return id.endsWith(markoExt);
1308
- }
1309
1301
  function markoRun(opts = {}) {
1310
1302
  let { routesDir, adapter, ...markoVitePluginOptions } = opts;
1311
1303
  let compiler;
@@ -1536,15 +1528,14 @@ function markoRun(opts = {}) {
1536
1528
  configureServer(_server) {
1537
1529
  devServer = _server;
1538
1530
  devServer.watcher.on("all", async (type, filename) => {
1539
- const file = path2.parse(filename);
1540
- if (filename.startsWith(resolvedRoutesDir) && isRoutableFile(file.base)) {
1531
+ const routableFileType = matchRoutableFile(path2.parse(filename).base);
1532
+ if (filename.startsWith(resolvedRoutesDir) && routableFileType) {
1541
1533
  if (type === "add") {
1542
1534
  isStale = true;
1543
1535
  } else if (type === "unlink") {
1544
1536
  isStale = true;
1545
1537
  } else if (type === "change") {
1546
- const match = matchRoutableFile(file.base);
1547
- if (match === RoutableFileTypes.Handler) {
1538
+ if (routableFileType === RoutableFileTypes.Handler) {
1548
1539
  isStale = true;
1549
1540
  }
1550
1541
  }
@@ -1579,7 +1570,7 @@ function markoRun(opts = {}) {
1579
1570
  extractVerbs = isBuild ? getVerbsFromFileBuild.bind(null, this) : getVerbsFromFileDev.bind(null, devServer);
1580
1571
  }
1581
1572
  },
1582
- async resolveId(importee, importer, { ssr }) {
1573
+ async resolveId(importee, importer) {
1583
1574
  let resolved;
1584
1575
  if (importee.startsWith(virtualRuntimePrefix)) {
1585
1576
  return this.resolve(
@@ -1601,16 +1592,13 @@ function markoRun(opts = {}) {
1601
1592
  }
1602
1593
  if (virtualFiles.has(importee)) {
1603
1594
  resolved = importee;
1604
- if (!ssr && isMarkoFile(resolved)) {
1605
- resolved += browserEntryQuery;
1606
- }
1607
1595
  }
1608
1596
  return resolved || null;
1609
1597
  },
1610
1598
  async load(id) {
1611
1599
  var _a;
1612
- if (id.endsWith(browserEntryQuery)) {
1613
- id = id.slice(0, -browserEntryQuery.length);
1600
+ if (id.endsWith(serverEntryQuery)) {
1601
+ id = id.slice(0, -serverEntryQuery.length);
1614
1602
  }
1615
1603
  if (virtualFiles.has(id)) {
1616
1604
  if (!isRendered) {
@@ -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.14",
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",
@@ -112,7 +112,7 @@
112
112
  "typescript": "^4.7.4"
113
113
  },
114
114
  "dependencies": {
115
- "@marko/vite": "^2.4.6",
115
+ "@marko/vite": "^2.4.8",
116
116
  "cli-table3": "^0.6.3",
117
117
  "compression": "^1.7.4",
118
118
  "dotenv": "^16.0.3",