@marko/run 0.1.4 → 0.1.6
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/dist/adapter/default-entry.mjs +2 -0
- package/dist/adapter/dev-entry.mjs +36 -0
- package/dist/adapter/dev-server.d.ts +4 -2
- package/dist/adapter/index.cjs +140 -25
- package/dist/adapter/index.d.ts +4 -3
- package/dist/adapter/index.js +137 -24
- package/dist/adapter/load-dev-worker.mjs +37 -0
- package/dist/cli/index.mjs +98 -144
- package/dist/index.html +1 -0
- package/dist/runtime/index.d.ts +3 -2
- package/dist/runtime/router.cjs +13 -7
- package/dist/runtime/router.js +13 -7
- package/dist/vite/index.cjs +58 -30
- package/dist/vite/index.js +58 -30
- package/dist/vite/types.d.ts +15 -3
- package/dist/vite/utils/server.d.ts +8 -2
- package/package.json +15 -7
|
@@ -5,6 +5,7 @@ import { createMiddleware } from "@marko/run/adapter/middleware";
|
|
|
5
5
|
import { fetch } from "@marko/run/router";
|
|
6
6
|
import { dirname } from 'path';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
|
+
import zlib from 'zlib';
|
|
8
9
|
|
|
9
10
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
|
|
@@ -12,6 +13,7 @@ const { PORT = 3456 } = process.env;
|
|
|
12
13
|
|
|
13
14
|
const middleware = createMiddleware(fetch);
|
|
14
15
|
const compress = compression({
|
|
16
|
+
flush: zlib.constants.Z_PARTIAL_FLUSH,
|
|
15
17
|
threshold: 500,
|
|
16
18
|
});
|
|
17
19
|
const staticServe = createStaticServe(__dirname, {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createServer } from "vite";
|
|
2
|
+
|
|
3
|
+
let activeDevServers;
|
|
4
|
+
|
|
5
|
+
process
|
|
6
|
+
.on("message", (message) => {
|
|
7
|
+
switch (message.type) {
|
|
8
|
+
case "start":
|
|
9
|
+
return start(message.entry, message.config);
|
|
10
|
+
case "shutdown":
|
|
11
|
+
return shutdown();
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
.send("ready");
|
|
15
|
+
|
|
16
|
+
async function start(entry, config) {
|
|
17
|
+
let changed = false;
|
|
18
|
+
const loader = await createServer(config);
|
|
19
|
+
({ activeDevServers } = await loader.ssrLoadModule("@marko/run/adapter"));
|
|
20
|
+
await loader.ssrLoadModule(entry);
|
|
21
|
+
|
|
22
|
+
loader.watcher.on("change", (path) => {
|
|
23
|
+
if (!changed && loader.moduleGraph.getModulesByFile(path)) {
|
|
24
|
+
changed = true;
|
|
25
|
+
process.send("restart");
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function shutdown() {
|
|
31
|
+
if (activeDevServers) {
|
|
32
|
+
for (const devServer of activeDevServers) {
|
|
33
|
+
devServer.ws.send({ type: "full-reload" });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { ViteDevServer } from "vite";
|
|
1
|
+
import { type InlineConfig, type ViteDevServer } from "vite";
|
|
2
2
|
import type { NodeMiddleware } from "./middleware";
|
|
3
|
+
export declare const activeDevServers: Set<ViteDevServer>;
|
|
3
4
|
export declare function createViteDevMiddleware<T>(devServer: ViteDevServer, load: (prev: T | undefined) => Promise<T>, factory: (value: T) => NodeMiddleware): NodeMiddleware;
|
|
4
|
-
export declare function
|
|
5
|
+
export declare function createViteDevServer(config?: InlineConfig): Promise<ViteDevServer>;
|
|
6
|
+
export declare function createDevServer(config?: InlineConfig): Promise<ViteDevServer>;
|
package/dist/adapter/index.cjs
CHANGED
|
@@ -26,8 +26,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
26
26
|
// src/adapter/index.ts
|
|
27
27
|
var adapter_exports = {};
|
|
28
28
|
__export(adapter_exports, {
|
|
29
|
+
activeDevServers: () => activeDevServers,
|
|
29
30
|
createDevServer: () => createDevServer,
|
|
30
31
|
createViteDevMiddleware: () => createViteDevMiddleware,
|
|
32
|
+
createViteDevServer: () => createViteDevServer,
|
|
31
33
|
default: () => adapter
|
|
32
34
|
});
|
|
33
35
|
module.exports = __toCommonJS(adapter_exports);
|
|
@@ -37,6 +39,7 @@ var import_url = require("url");
|
|
|
37
39
|
// src/adapter/dev-server.ts
|
|
38
40
|
var import_vite = require("vite");
|
|
39
41
|
var import_strip_ansi = __toESM(require("strip-ansi"), 1);
|
|
42
|
+
var activeDevServers = /* @__PURE__ */ new Set();
|
|
40
43
|
function createViteDevMiddleware(devServer, load, factory) {
|
|
41
44
|
let value;
|
|
42
45
|
let middleware;
|
|
@@ -59,12 +62,22 @@ function createViteDevMiddleware(devServer, load, factory) {
|
|
|
59
62
|
}
|
|
60
63
|
};
|
|
61
64
|
}
|
|
62
|
-
async function
|
|
65
|
+
async function createViteDevServer(config2) {
|
|
63
66
|
const devServer = await (0, import_vite.createServer)({
|
|
64
|
-
|
|
67
|
+
...config2,
|
|
65
68
|
appType: "custom",
|
|
66
69
|
server: { middlewareMode: true }
|
|
67
70
|
});
|
|
71
|
+
const originalClose = devServer.close;
|
|
72
|
+
devServer.close = () => {
|
|
73
|
+
activeDevServers.delete(devServer);
|
|
74
|
+
return originalClose.call(devServer);
|
|
75
|
+
};
|
|
76
|
+
activeDevServers.add(devServer);
|
|
77
|
+
return devServer;
|
|
78
|
+
}
|
|
79
|
+
async function createDevServer(config2) {
|
|
80
|
+
const devServer = await createViteDevServer(config2);
|
|
68
81
|
const { createMiddleware } = await devServer.ssrLoadModule(
|
|
69
82
|
"@marko/run/adapter/middleware"
|
|
70
83
|
);
|
|
@@ -73,7 +86,8 @@ async function createDevServer(configFile) {
|
|
|
73
86
|
async () => await devServer.ssrLoadModule("@marko/run/router"),
|
|
74
87
|
(module2) => createMiddleware(module2.fetch, { devServer })
|
|
75
88
|
);
|
|
76
|
-
|
|
89
|
+
devServer.middlewares.use(middleware);
|
|
90
|
+
return devServer;
|
|
77
91
|
}
|
|
78
92
|
|
|
79
93
|
// src/vite/utils/server.ts
|
|
@@ -81,6 +95,7 @@ var import_net = __toESM(require("net"), 1);
|
|
|
81
95
|
var import_child_process = __toESM(require("child_process"), 1);
|
|
82
96
|
var import_dotenv = require("dotenv");
|
|
83
97
|
var import_fs = __toESM(require("fs"), 1);
|
|
98
|
+
var import_cluster = __toESM(require("cluster"), 1);
|
|
84
99
|
async function parseEnv(envFile) {
|
|
85
100
|
if (import_fs.default.existsSync(envFile)) {
|
|
86
101
|
const content = await import_fs.default.promises.readFile(envFile, "utf8");
|
|
@@ -90,14 +105,14 @@ async function parseEnv(envFile) {
|
|
|
90
105
|
function loadEnv(envFile) {
|
|
91
106
|
(0, import_dotenv.config)({ path: envFile });
|
|
92
107
|
}
|
|
93
|
-
async function spawnServer(cmd, port = 0, env, cwd = process.cwd(), wait = 3e4) {
|
|
108
|
+
async function spawnServer(cmd, args = [], port = 0, env, cwd = process.cwd(), wait = 3e4) {
|
|
94
109
|
if (port <= 0) {
|
|
95
110
|
port = await getAvailablePort();
|
|
96
111
|
}
|
|
97
112
|
if (typeof env === "string") {
|
|
98
113
|
env = await parseEnv(env);
|
|
99
114
|
}
|
|
100
|
-
const proc = import_child_process.default.spawn(cmd, {
|
|
115
|
+
const proc = import_child_process.default.spawn(cmd, args, {
|
|
101
116
|
cwd,
|
|
102
117
|
shell: true,
|
|
103
118
|
stdio: "inherit",
|
|
@@ -108,30 +123,67 @@ async function spawnServer(cmd, port = 0, env, cwd = process.cwd(), wait = 3e4)
|
|
|
108
123
|
proc.unref();
|
|
109
124
|
proc.kill();
|
|
110
125
|
};
|
|
126
|
+
try {
|
|
127
|
+
await waitForServer(port, wait);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
close();
|
|
130
|
+
throw err;
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
port,
|
|
134
|
+
close
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
async function spawnServerWorker(module2, args = [], port = 0, env) {
|
|
138
|
+
if (port <= 0) {
|
|
139
|
+
port = await getAvailablePort();
|
|
140
|
+
}
|
|
141
|
+
if (typeof env === "string") {
|
|
142
|
+
env = await parseEnv(env);
|
|
143
|
+
}
|
|
144
|
+
const originalExec = import_cluster.default.settings.exec;
|
|
145
|
+
const originalArgs = import_cluster.default.settings.execArgv;
|
|
146
|
+
try {
|
|
147
|
+
import_cluster.default.settings.exec = module2;
|
|
148
|
+
import_cluster.default.settings.execArgv = args;
|
|
149
|
+
const worker = import_cluster.default.fork({ ...env, NODE_ENV: "development", ...process.env, PORT: `${port}` });
|
|
150
|
+
return new Promise((resolve) => {
|
|
151
|
+
function ready(message) {
|
|
152
|
+
if (message === "ready") {
|
|
153
|
+
worker.off("message", ready);
|
|
154
|
+
resolve(worker);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
worker.on("message", ready);
|
|
158
|
+
});
|
|
159
|
+
} finally {
|
|
160
|
+
import_cluster.default.settings.exec = originalExec;
|
|
161
|
+
import_cluster.default.settings.execArgv = originalArgs;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
async function waitForServer(port, wait = 0) {
|
|
111
165
|
let remaining = wait > 0 ? wait : Infinity;
|
|
112
|
-
|
|
166
|
+
let connection;
|
|
167
|
+
while (!(connection = await getConnection(port))) {
|
|
113
168
|
if (remaining >= 100) {
|
|
114
169
|
remaining -= 100;
|
|
115
170
|
await sleep(100);
|
|
116
171
|
} else {
|
|
117
|
-
close();
|
|
118
172
|
throw new Error(
|
|
119
173
|
`site-write: timeout while wating for server to start on port "${port}".`
|
|
120
174
|
);
|
|
121
175
|
}
|
|
122
176
|
}
|
|
123
|
-
return
|
|
124
|
-
port,
|
|
125
|
-
close
|
|
126
|
-
};
|
|
177
|
+
return connection;
|
|
127
178
|
}
|
|
128
|
-
async function
|
|
179
|
+
async function getConnection(port) {
|
|
129
180
|
return new Promise((resolve) => {
|
|
130
|
-
const connection = import_net.default.connect(port).setNoDelay(true).setKeepAlive(false).on("error", () =>
|
|
131
|
-
function done(connected) {
|
|
181
|
+
const connection = import_net.default.connect(port).setNoDelay(true).setKeepAlive(false).on("error", () => {
|
|
132
182
|
connection.end();
|
|
133
|
-
resolve(
|
|
134
|
-
}
|
|
183
|
+
resolve(null);
|
|
184
|
+
}).on("connect", () => {
|
|
185
|
+
resolve(connection);
|
|
186
|
+
});
|
|
135
187
|
});
|
|
136
188
|
}
|
|
137
189
|
async function getAvailablePort() {
|
|
@@ -147,34 +199,97 @@ function sleep(ms) {
|
|
|
147
199
|
}
|
|
148
200
|
|
|
149
201
|
// src/adapter/index.ts
|
|
202
|
+
var import_parse_node_args = __toESM(require("parse-node-args"), 1);
|
|
150
203
|
var import_meta = {};
|
|
151
204
|
var __dirname = (0, import_url.fileURLToPath)(new URL(".", import_meta.url));
|
|
205
|
+
var defaultEntry = import_path.default.join(__dirname, "default-entry");
|
|
206
|
+
var loadDevWorker = import_path.default.join(__dirname, "load-dev-worker.mjs");
|
|
152
207
|
function adapter() {
|
|
153
208
|
return {
|
|
154
209
|
name: "base-adapter",
|
|
155
210
|
async getEntryFile() {
|
|
156
|
-
|
|
157
|
-
return entry;
|
|
211
|
+
return defaultEntry;
|
|
158
212
|
},
|
|
159
|
-
async startDev(
|
|
213
|
+
async startDev(entry, config2, options) {
|
|
214
|
+
const { port = 3e3, envFile } = options;
|
|
215
|
+
if (entry) {
|
|
216
|
+
const { nodeArgs } = (0, import_parse_node_args.default)(options.args);
|
|
217
|
+
let worker;
|
|
218
|
+
async function start() {
|
|
219
|
+
const nextWorker = await spawnServerWorker(
|
|
220
|
+
loadDevWorker,
|
|
221
|
+
nodeArgs,
|
|
222
|
+
port,
|
|
223
|
+
envFile
|
|
224
|
+
);
|
|
225
|
+
nextWorker.on("message", (messsage) => {
|
|
226
|
+
if (messsage === "restart") {
|
|
227
|
+
start();
|
|
228
|
+
}
|
|
229
|
+
}).send({ type: "start", entry, config: config2 });
|
|
230
|
+
await waitForWorker(nextWorker, port);
|
|
231
|
+
if (worker) {
|
|
232
|
+
const prevWorker = worker;
|
|
233
|
+
let timeout;
|
|
234
|
+
worker.once("disconnect", () => {
|
|
235
|
+
clearTimeout(timeout);
|
|
236
|
+
});
|
|
237
|
+
worker.send({ type: "shutdown" });
|
|
238
|
+
worker.disconnect();
|
|
239
|
+
timeout = setTimeout(() => {
|
|
240
|
+
prevWorker.kill();
|
|
241
|
+
}, 2e3);
|
|
242
|
+
}
|
|
243
|
+
worker = nextWorker;
|
|
244
|
+
}
|
|
245
|
+
await start();
|
|
246
|
+
return {
|
|
247
|
+
port,
|
|
248
|
+
close() {
|
|
249
|
+
worker.kill();
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const devServer = await createDevServer(config2);
|
|
160
254
|
envFile && await loadEnv(envFile);
|
|
161
|
-
const server = await createDevServer(configFile);
|
|
162
255
|
return new Promise((resolve) => {
|
|
163
|
-
const listener =
|
|
256
|
+
const listener = devServer.middlewares.listen(port, () => {
|
|
164
257
|
const address = listener.address();
|
|
165
258
|
console.log(`Dev server started: http://localhost:${address.port}`);
|
|
166
|
-
resolve(
|
|
259
|
+
resolve({
|
|
260
|
+
port,
|
|
261
|
+
async close() {
|
|
262
|
+
await devServer.close();
|
|
263
|
+
}
|
|
264
|
+
});
|
|
167
265
|
});
|
|
168
266
|
});
|
|
169
267
|
},
|
|
170
|
-
async startPreview(
|
|
171
|
-
const
|
|
268
|
+
async startPreview(entry, options) {
|
|
269
|
+
const { port, envFile } = options;
|
|
270
|
+
const { nodeArgs } = (0, import_parse_node_args.default)(options.args);
|
|
271
|
+
const args = [...nodeArgs, entry];
|
|
272
|
+
const server = await spawnServer("node", args, port, envFile);
|
|
172
273
|
console.log(`Preview server started: http://localhost:${server.port}`);
|
|
274
|
+
return server;
|
|
173
275
|
}
|
|
174
276
|
};
|
|
175
277
|
}
|
|
278
|
+
async function waitForWorker(worker, port) {
|
|
279
|
+
return new Promise((resolve) => {
|
|
280
|
+
function listening(address) {
|
|
281
|
+
if (address.port === port) {
|
|
282
|
+
worker.off("listening", listening);
|
|
283
|
+
resolve();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
worker.on("listening", listening);
|
|
287
|
+
});
|
|
288
|
+
}
|
|
176
289
|
// Annotate the CommonJS export names for ESM import in node:
|
|
177
290
|
0 && (module.exports = {
|
|
291
|
+
activeDevServers,
|
|
178
292
|
createDevServer,
|
|
179
|
-
createViteDevMiddleware
|
|
293
|
+
createViteDevMiddleware,
|
|
294
|
+
createViteDevServer
|
|
180
295
|
});
|
package/dist/adapter/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Adapter } from "../vite";
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
export type {
|
|
2
|
+
import { type SpawnedServer } from "../vite/utils/server";
|
|
3
|
+
export { activeDevServers, createDevServer, createViteDevServer, createViteDevMiddleware, } from "./dev-server";
|
|
4
|
+
export type { Adapter, SpawnedServer };
|
|
5
|
+
export type { NodePlatformInfo } from "./middleware";
|
|
5
6
|
export default function adapter(): Adapter;
|
package/dist/adapter/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { fileURLToPath } from "url";
|
|
|
5
5
|
// src/adapter/dev-server.ts
|
|
6
6
|
import { createServer } from "vite";
|
|
7
7
|
import stripAnsi from "strip-ansi";
|
|
8
|
+
var activeDevServers = /* @__PURE__ */ new Set();
|
|
8
9
|
function createViteDevMiddleware(devServer, load, factory) {
|
|
9
10
|
let value;
|
|
10
11
|
let middleware;
|
|
@@ -27,12 +28,22 @@ function createViteDevMiddleware(devServer, load, factory) {
|
|
|
27
28
|
}
|
|
28
29
|
};
|
|
29
30
|
}
|
|
30
|
-
async function
|
|
31
|
+
async function createViteDevServer(config2) {
|
|
31
32
|
const devServer = await createServer({
|
|
32
|
-
|
|
33
|
+
...config2,
|
|
33
34
|
appType: "custom",
|
|
34
35
|
server: { middlewareMode: true }
|
|
35
36
|
});
|
|
37
|
+
const originalClose = devServer.close;
|
|
38
|
+
devServer.close = () => {
|
|
39
|
+
activeDevServers.delete(devServer);
|
|
40
|
+
return originalClose.call(devServer);
|
|
41
|
+
};
|
|
42
|
+
activeDevServers.add(devServer);
|
|
43
|
+
return devServer;
|
|
44
|
+
}
|
|
45
|
+
async function createDevServer(config2) {
|
|
46
|
+
const devServer = await createViteDevServer(config2);
|
|
36
47
|
const { createMiddleware } = await devServer.ssrLoadModule(
|
|
37
48
|
"@marko/run/adapter/middleware"
|
|
38
49
|
);
|
|
@@ -41,7 +52,8 @@ async function createDevServer(configFile) {
|
|
|
41
52
|
async () => await devServer.ssrLoadModule("@marko/run/router"),
|
|
42
53
|
(module) => createMiddleware(module.fetch, { devServer })
|
|
43
54
|
);
|
|
44
|
-
|
|
55
|
+
devServer.middlewares.use(middleware);
|
|
56
|
+
return devServer;
|
|
45
57
|
}
|
|
46
58
|
|
|
47
59
|
// src/vite/utils/server.ts
|
|
@@ -49,6 +61,7 @@ import net from "net";
|
|
|
49
61
|
import cp from "child_process";
|
|
50
62
|
import { parse, config } from "dotenv";
|
|
51
63
|
import fs from "fs";
|
|
64
|
+
import cluster from "cluster";
|
|
52
65
|
async function parseEnv(envFile) {
|
|
53
66
|
if (fs.existsSync(envFile)) {
|
|
54
67
|
const content = await fs.promises.readFile(envFile, "utf8");
|
|
@@ -58,14 +71,14 @@ async function parseEnv(envFile) {
|
|
|
58
71
|
function loadEnv(envFile) {
|
|
59
72
|
config({ path: envFile });
|
|
60
73
|
}
|
|
61
|
-
async function spawnServer(cmd, port = 0, env, cwd = process.cwd(), wait = 3e4) {
|
|
74
|
+
async function spawnServer(cmd, args = [], port = 0, env, cwd = process.cwd(), wait = 3e4) {
|
|
62
75
|
if (port <= 0) {
|
|
63
76
|
port = await getAvailablePort();
|
|
64
77
|
}
|
|
65
78
|
if (typeof env === "string") {
|
|
66
79
|
env = await parseEnv(env);
|
|
67
80
|
}
|
|
68
|
-
const proc = cp.spawn(cmd, {
|
|
81
|
+
const proc = cp.spawn(cmd, args, {
|
|
69
82
|
cwd,
|
|
70
83
|
shell: true,
|
|
71
84
|
stdio: "inherit",
|
|
@@ -76,30 +89,67 @@ async function spawnServer(cmd, port = 0, env, cwd = process.cwd(), wait = 3e4)
|
|
|
76
89
|
proc.unref();
|
|
77
90
|
proc.kill();
|
|
78
91
|
};
|
|
92
|
+
try {
|
|
93
|
+
await waitForServer(port, wait);
|
|
94
|
+
} catch (err) {
|
|
95
|
+
close();
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
port,
|
|
100
|
+
close
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
async function spawnServerWorker(module, args = [], port = 0, env) {
|
|
104
|
+
if (port <= 0) {
|
|
105
|
+
port = await getAvailablePort();
|
|
106
|
+
}
|
|
107
|
+
if (typeof env === "string") {
|
|
108
|
+
env = await parseEnv(env);
|
|
109
|
+
}
|
|
110
|
+
const originalExec = cluster.settings.exec;
|
|
111
|
+
const originalArgs = cluster.settings.execArgv;
|
|
112
|
+
try {
|
|
113
|
+
cluster.settings.exec = module;
|
|
114
|
+
cluster.settings.execArgv = args;
|
|
115
|
+
const worker = cluster.fork({ ...env, NODE_ENV: "development", ...process.env, PORT: `${port}` });
|
|
116
|
+
return new Promise((resolve) => {
|
|
117
|
+
function ready(message) {
|
|
118
|
+
if (message === "ready") {
|
|
119
|
+
worker.off("message", ready);
|
|
120
|
+
resolve(worker);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
worker.on("message", ready);
|
|
124
|
+
});
|
|
125
|
+
} finally {
|
|
126
|
+
cluster.settings.exec = originalExec;
|
|
127
|
+
cluster.settings.execArgv = originalArgs;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function waitForServer(port, wait = 0) {
|
|
79
131
|
let remaining = wait > 0 ? wait : Infinity;
|
|
80
|
-
|
|
132
|
+
let connection;
|
|
133
|
+
while (!(connection = await getConnection(port))) {
|
|
81
134
|
if (remaining >= 100) {
|
|
82
135
|
remaining -= 100;
|
|
83
136
|
await sleep(100);
|
|
84
137
|
} else {
|
|
85
|
-
close();
|
|
86
138
|
throw new Error(
|
|
87
139
|
`site-write: timeout while wating for server to start on port "${port}".`
|
|
88
140
|
);
|
|
89
141
|
}
|
|
90
142
|
}
|
|
91
|
-
return
|
|
92
|
-
port,
|
|
93
|
-
close
|
|
94
|
-
};
|
|
143
|
+
return connection;
|
|
95
144
|
}
|
|
96
|
-
async function
|
|
145
|
+
async function getConnection(port) {
|
|
97
146
|
return new Promise((resolve) => {
|
|
98
|
-
const connection = net.connect(port).setNoDelay(true).setKeepAlive(false).on("error", () =>
|
|
99
|
-
function done(connected) {
|
|
147
|
+
const connection = net.connect(port).setNoDelay(true).setKeepAlive(false).on("error", () => {
|
|
100
148
|
connection.end();
|
|
101
|
-
resolve(
|
|
102
|
-
}
|
|
149
|
+
resolve(null);
|
|
150
|
+
}).on("connect", () => {
|
|
151
|
+
resolve(connection);
|
|
152
|
+
});
|
|
103
153
|
});
|
|
104
154
|
}
|
|
105
155
|
async function getAvailablePort() {
|
|
@@ -115,33 +165,96 @@ function sleep(ms) {
|
|
|
115
165
|
}
|
|
116
166
|
|
|
117
167
|
// src/adapter/index.ts
|
|
168
|
+
import parseNodeArgs from "parse-node-args";
|
|
118
169
|
var __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
170
|
+
var defaultEntry = path.join(__dirname, "default-entry");
|
|
171
|
+
var loadDevWorker = path.join(__dirname, "load-dev-worker.mjs");
|
|
119
172
|
function adapter() {
|
|
120
173
|
return {
|
|
121
174
|
name: "base-adapter",
|
|
122
175
|
async getEntryFile() {
|
|
123
|
-
|
|
124
|
-
return entry;
|
|
176
|
+
return defaultEntry;
|
|
125
177
|
},
|
|
126
|
-
async startDev(
|
|
178
|
+
async startDev(entry, config2, options) {
|
|
179
|
+
const { port = 3e3, envFile } = options;
|
|
180
|
+
if (entry) {
|
|
181
|
+
const { nodeArgs } = parseNodeArgs(options.args);
|
|
182
|
+
let worker;
|
|
183
|
+
async function start() {
|
|
184
|
+
const nextWorker = await spawnServerWorker(
|
|
185
|
+
loadDevWorker,
|
|
186
|
+
nodeArgs,
|
|
187
|
+
port,
|
|
188
|
+
envFile
|
|
189
|
+
);
|
|
190
|
+
nextWorker.on("message", (messsage) => {
|
|
191
|
+
if (messsage === "restart") {
|
|
192
|
+
start();
|
|
193
|
+
}
|
|
194
|
+
}).send({ type: "start", entry, config: config2 });
|
|
195
|
+
await waitForWorker(nextWorker, port);
|
|
196
|
+
if (worker) {
|
|
197
|
+
const prevWorker = worker;
|
|
198
|
+
let timeout;
|
|
199
|
+
worker.once("disconnect", () => {
|
|
200
|
+
clearTimeout(timeout);
|
|
201
|
+
});
|
|
202
|
+
worker.send({ type: "shutdown" });
|
|
203
|
+
worker.disconnect();
|
|
204
|
+
timeout = setTimeout(() => {
|
|
205
|
+
prevWorker.kill();
|
|
206
|
+
}, 2e3);
|
|
207
|
+
}
|
|
208
|
+
worker = nextWorker;
|
|
209
|
+
}
|
|
210
|
+
await start();
|
|
211
|
+
return {
|
|
212
|
+
port,
|
|
213
|
+
close() {
|
|
214
|
+
worker.kill();
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
const devServer = await createDevServer(config2);
|
|
127
219
|
envFile && await loadEnv(envFile);
|
|
128
|
-
const server = await createDevServer(configFile);
|
|
129
220
|
return new Promise((resolve) => {
|
|
130
|
-
const listener =
|
|
221
|
+
const listener = devServer.middlewares.listen(port, () => {
|
|
131
222
|
const address = listener.address();
|
|
132
223
|
console.log(`Dev server started: http://localhost:${address.port}`);
|
|
133
|
-
resolve(
|
|
224
|
+
resolve({
|
|
225
|
+
port,
|
|
226
|
+
async close() {
|
|
227
|
+
await devServer.close();
|
|
228
|
+
}
|
|
229
|
+
});
|
|
134
230
|
});
|
|
135
231
|
});
|
|
136
232
|
},
|
|
137
|
-
async startPreview(
|
|
138
|
-
const
|
|
233
|
+
async startPreview(entry, options) {
|
|
234
|
+
const { port, envFile } = options;
|
|
235
|
+
const { nodeArgs } = parseNodeArgs(options.args);
|
|
236
|
+
const args = [...nodeArgs, entry];
|
|
237
|
+
const server = await spawnServer("node", args, port, envFile);
|
|
139
238
|
console.log(`Preview server started: http://localhost:${server.port}`);
|
|
239
|
+
return server;
|
|
140
240
|
}
|
|
141
241
|
};
|
|
142
242
|
}
|
|
243
|
+
async function waitForWorker(worker, port) {
|
|
244
|
+
return new Promise((resolve) => {
|
|
245
|
+
function listening(address) {
|
|
246
|
+
if (address.port === port) {
|
|
247
|
+
worker.off("listening", listening);
|
|
248
|
+
resolve();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
worker.on("listening", listening);
|
|
252
|
+
});
|
|
253
|
+
}
|
|
143
254
|
export {
|
|
255
|
+
activeDevServers,
|
|
144
256
|
createDevServer,
|
|
145
257
|
createViteDevMiddleware,
|
|
258
|
+
createViteDevServer,
|
|
146
259
|
adapter as default
|
|
147
260
|
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createServer } from "vite";
|
|
2
|
+
|
|
3
|
+
let activeDevServers;
|
|
4
|
+
|
|
5
|
+
process
|
|
6
|
+
.on("message", (message) => {
|
|
7
|
+
switch (message.type) {
|
|
8
|
+
case "start":
|
|
9
|
+
return start(message.entry, message.config);
|
|
10
|
+
case "shutdown":
|
|
11
|
+
return shutdown();
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
.send("ready");
|
|
15
|
+
|
|
16
|
+
async function start(entry, config) {
|
|
17
|
+
let changed = false;
|
|
18
|
+
const loader = await createServer(config);
|
|
19
|
+
({ activeDevServers } = await loader.ssrLoadModule("@marko/run/adapter"));
|
|
20
|
+
await loader.ssrLoadModule(entry);
|
|
21
|
+
|
|
22
|
+
loader.watcher.on("change", (path) => {
|
|
23
|
+
if (!changed && loader.moduleGraph.getModulesByFile(path)) {
|
|
24
|
+
changed = true;
|
|
25
|
+
process.send("restart");
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function shutdown() {
|
|
31
|
+
if (activeDevServers) {
|
|
32
|
+
for (const devServer of activeDevServers) {
|
|
33
|
+
devServer.ws.send({ type: "full-reload" });
|
|
34
|
+
}
|
|
35
|
+
activeDevServers.clear();
|
|
36
|
+
}
|
|
37
|
+
}
|