devflare 1.0.0-next.6 → 1.0.0-next.7
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/{build-nz5yrj7f.js → build-9myaxf07.js} +19 -2
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/deploy.d.ts.map +1 -1
- package/dist/cli/commands/types.d.ts.map +1 -1
- package/dist/{deploy-a5pcxd5w.js → deploy-h1wz5p7m.js} +26 -10
- package/dist/{dev-7agn9g5s.js → dev-rsdssknb.js} +380 -91
- package/dist/dev-server/server.d.ts.map +1 -1
- package/dist/index-a0fjkq68.js +198 -0
- package/dist/{index-rprrn24p.js → index-f8qh2tyh.js} +9 -10
- package/dist/index.js +5 -5
- package/dist/test/index.js +1 -1
- package/dist/test/simple-context.d.ts +1 -1
- package/dist/test/simple-context.d.ts.map +1 -1
- package/dist/{types-vss6vrz7.js → types-wdcpnfvy.js} +39 -7
- package/dist/vite/index.js +118 -50
- package/dist/vite/plugin.d.ts.map +1 -1
- package/dist/worker-entry/composed-worker.d.ts +10 -0
- package/dist/worker-entry/composed-worker.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
findDurableObjectClasses
|
|
11
11
|
} from "./index-gz1gndna.js";
|
|
12
12
|
import {
|
|
13
|
-
loadConfig
|
|
13
|
+
loadConfig,
|
|
14
|
+
resolveConfigPath
|
|
14
15
|
} from "./index-hcex3rgh.js";
|
|
15
16
|
import {
|
|
16
17
|
__require
|
|
@@ -21,7 +22,7 @@ import { createConsola } from "consola";
|
|
|
21
22
|
import { resolve as resolve3 } from "pathe";
|
|
22
23
|
|
|
23
24
|
// src/dev-server/server.ts
|
|
24
|
-
import { dirname as dirname2, resolve as resolve2 } from "pathe";
|
|
25
|
+
import { dirname as dirname2, relative as relative2, resolve as resolve2 } from "pathe";
|
|
25
26
|
|
|
26
27
|
// src/bundler/do-bundler.ts
|
|
27
28
|
import { resolve, dirname, relative } from "pathe";
|
|
@@ -1099,17 +1100,35 @@ var DEFAULT_FETCH_ENTRY_FILES = [
|
|
|
1099
1100
|
"src/fetch.mts",
|
|
1100
1101
|
"src/fetch.mjs"
|
|
1101
1102
|
];
|
|
1103
|
+
var DEFAULT_QUEUE_ENTRY_FILES = [
|
|
1104
|
+
"src/queue.ts",
|
|
1105
|
+
"src/queue.js",
|
|
1106
|
+
"src/queue.mts",
|
|
1107
|
+
"src/queue.mjs"
|
|
1108
|
+
];
|
|
1109
|
+
var DEFAULT_SCHEDULED_ENTRY_FILES = [
|
|
1110
|
+
"src/scheduled.ts",
|
|
1111
|
+
"src/scheduled.js",
|
|
1112
|
+
"src/scheduled.mts",
|
|
1113
|
+
"src/scheduled.mjs"
|
|
1114
|
+
];
|
|
1115
|
+
var DEFAULT_EMAIL_ENTRY_FILES = [
|
|
1116
|
+
"src/email.ts",
|
|
1117
|
+
"src/email.js",
|
|
1118
|
+
"src/email.mts",
|
|
1119
|
+
"src/email.mjs"
|
|
1120
|
+
];
|
|
1102
1121
|
var INTERNAL_APP_SERVICE_BINDING = "__DEVFLARE_APP";
|
|
1103
|
-
async function
|
|
1104
|
-
if (
|
|
1122
|
+
async function resolveWorkerHandlerPath(cwd, configuredPath, defaultEntries) {
|
|
1123
|
+
if (configuredPath === false) {
|
|
1105
1124
|
return null;
|
|
1106
1125
|
}
|
|
1107
1126
|
const fs = await import("node:fs/promises");
|
|
1108
1127
|
const candidates = new Set;
|
|
1109
|
-
if (typeof
|
|
1110
|
-
candidates.add(
|
|
1128
|
+
if (typeof configuredPath === "string" && configuredPath) {
|
|
1129
|
+
candidates.add(configuredPath);
|
|
1111
1130
|
}
|
|
1112
|
-
for (const defaultEntry of
|
|
1131
|
+
for (const defaultEntry of defaultEntries) {
|
|
1113
1132
|
candidates.add(defaultEntry);
|
|
1114
1133
|
}
|
|
1115
1134
|
for (const candidate of candidates) {
|
|
@@ -1123,7 +1142,214 @@ async function resolveMainWorkerScriptPath(cwd, config) {
|
|
|
1123
1142
|
}
|
|
1124
1143
|
return null;
|
|
1125
1144
|
}
|
|
1126
|
-
function
|
|
1145
|
+
async function resolveMainWorkerSurfacePaths(cwd, config) {
|
|
1146
|
+
return {
|
|
1147
|
+
fetch: await resolveWorkerHandlerPath(cwd, config.files?.fetch, DEFAULT_FETCH_ENTRY_FILES),
|
|
1148
|
+
queue: await resolveWorkerHandlerPath(cwd, config.files?.queue, DEFAULT_QUEUE_ENTRY_FILES),
|
|
1149
|
+
scheduled: await resolveWorkerHandlerPath(cwd, config.files?.scheduled, DEFAULT_SCHEDULED_ENTRY_FILES),
|
|
1150
|
+
email: await resolveWorkerHandlerPath(cwd, config.files?.email, DEFAULT_EMAIL_ENTRY_FILES)
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1153
|
+
function getFirstWorkerSurfacePath(surfacePaths) {
|
|
1154
|
+
return surfacePaths.fetch ?? surfacePaths.queue ?? surfacePaths.scheduled ?? surfacePaths.email;
|
|
1155
|
+
}
|
|
1156
|
+
function hasWorkerSurfacePaths(surfacePaths) {
|
|
1157
|
+
return Object.values(surfacePaths).some((surfacePath) => typeof surfacePath === "string" && surfacePath.length > 0);
|
|
1158
|
+
}
|
|
1159
|
+
function toImportSpecifier(fromFilePath, toFilePath) {
|
|
1160
|
+
const specifier = relative2(dirname2(fromFilePath), toFilePath).replace(/\\/g, "/");
|
|
1161
|
+
return specifier.startsWith(".") ? specifier : `./${specifier}`;
|
|
1162
|
+
}
|
|
1163
|
+
function getMainWorkerEntryScript(surfaceImportPaths) {
|
|
1164
|
+
const importLines = [`import { runWithContext } from 'devflare/runtime'`];
|
|
1165
|
+
const moduleFallbackLines = [];
|
|
1166
|
+
const registerSurfaceModule = (identifier, importPath) => {
|
|
1167
|
+
if (importPath) {
|
|
1168
|
+
importLines.push(`import * as ${identifier} from '${importPath}'`);
|
|
1169
|
+
return;
|
|
1170
|
+
}
|
|
1171
|
+
moduleFallbackLines.push(`const ${identifier} = {}`);
|
|
1172
|
+
};
|
|
1173
|
+
registerSurfaceModule("__devflareFetchModule", surfaceImportPaths.fetch);
|
|
1174
|
+
registerSurfaceModule("__devflareQueueModule", surfaceImportPaths.queue);
|
|
1175
|
+
registerSurfaceModule("__devflareScheduledModule", surfaceImportPaths.scheduled);
|
|
1176
|
+
registerSurfaceModule("__devflareEmailModule", surfaceImportPaths.email);
|
|
1177
|
+
return `
|
|
1178
|
+
${importLines.join(`
|
|
1179
|
+
`)}
|
|
1180
|
+
${moduleFallbackLines.join(`
|
|
1181
|
+
`)}
|
|
1182
|
+
|
|
1183
|
+
const __devflareResolveHandler = (module, namedExport) => {
|
|
1184
|
+
const defaultExport = module.default
|
|
1185
|
+
|
|
1186
|
+
if (typeof defaultExport === 'function') {
|
|
1187
|
+
return defaultExport
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
if (defaultExport && typeof defaultExport[namedExport] === 'function') {
|
|
1191
|
+
return defaultExport[namedExport].bind(defaultExport)
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
if (typeof module[namedExport] === 'function') {
|
|
1195
|
+
return module[namedExport]
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
return null
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
const __devflareFetchHandler = __devflareResolveHandler(__devflareFetchModule, 'fetch')
|
|
1202
|
+
const __devflareQueueHandler = __devflareResolveHandler(__devflareQueueModule, 'queue')
|
|
1203
|
+
const __devflareScheduledHandler = __devflareResolveHandler(__devflareScheduledModule, 'scheduled')
|
|
1204
|
+
const __devflareEmailHandler = __devflareResolveHandler(__devflareEmailModule, 'email')
|
|
1205
|
+
|
|
1206
|
+
function __devflareCreateEmailHeaders(rawBody) {
|
|
1207
|
+
const headers = new Headers()
|
|
1208
|
+
const lines = rawBody.split(/\\r?\\n/)
|
|
1209
|
+
|
|
1210
|
+
for (const line of lines) {
|
|
1211
|
+
if (line.trim() === '') {
|
|
1212
|
+
break
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
const colonIndex = line.indexOf(':')
|
|
1216
|
+
if (colonIndex <= 0) {
|
|
1217
|
+
continue
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
headers.append(line.slice(0, colonIndex).trim(), line.slice(colonIndex + 1).trim())
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
return headers
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
function __devflareCreateEmailRawStream(rawBody) {
|
|
1227
|
+
return new ReadableStream({
|
|
1228
|
+
start(controller) {
|
|
1229
|
+
controller.enqueue(new TextEncoder().encode(rawBody))
|
|
1230
|
+
controller.close()
|
|
1231
|
+
}
|
|
1232
|
+
})
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
async function __devflareHandleInternalEmail(request, env, ctx) {
|
|
1236
|
+
if (!__devflareEmailHandler) {
|
|
1237
|
+
return new Response('Email handler not configured', { status: 501 })
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
const from = request.headers.get('x-devflare-email-from') || 'unknown@example.com'
|
|
1241
|
+
const to = request.headers.get('x-devflare-email-to') || 'worker@example.com'
|
|
1242
|
+
const rawBody = await request.text()
|
|
1243
|
+
const emailMessage = {
|
|
1244
|
+
from,
|
|
1245
|
+
to,
|
|
1246
|
+
headers: __devflareCreateEmailHeaders(rawBody),
|
|
1247
|
+
raw: __devflareCreateEmailRawStream(rawBody),
|
|
1248
|
+
rawSize: rawBody.length,
|
|
1249
|
+
setReject(reason) {
|
|
1250
|
+
console.warn('[Devflare email rejected]', reason)
|
|
1251
|
+
},
|
|
1252
|
+
async forward(rcptTo) {
|
|
1253
|
+
console.log('[Devflare email forwarded]', rcptTo)
|
|
1254
|
+
return Promise.resolve()
|
|
1255
|
+
},
|
|
1256
|
+
async reply(message) {
|
|
1257
|
+
console.log('[Devflare email reply sent]', message?.from)
|
|
1258
|
+
return Promise.resolve()
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
await runWithContext(
|
|
1263
|
+
env,
|
|
1264
|
+
ctx,
|
|
1265
|
+
null,
|
|
1266
|
+
() => __devflareEmailHandler(emailMessage, env, ctx),
|
|
1267
|
+
'email'
|
|
1268
|
+
)
|
|
1269
|
+
|
|
1270
|
+
return new Response(JSON.stringify({ ok: true, from, to }), {
|
|
1271
|
+
headers: { 'Content-Type': 'application/json' }
|
|
1272
|
+
})
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
export default {
|
|
1276
|
+
async fetch(request, env, ctx) {
|
|
1277
|
+
const url = new URL(request.url)
|
|
1278
|
+
|
|
1279
|
+
if (
|
|
1280
|
+
request.headers.get('x-devflare-event') === 'email' &&
|
|
1281
|
+
url.pathname === '/_devflare/internal/email'
|
|
1282
|
+
) {
|
|
1283
|
+
return __devflareHandleInternalEmail(request, env, ctx)
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
if (!__devflareFetchHandler) {
|
|
1287
|
+
return new Response('Fetch handler not configured', { status: 404 })
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
return runWithContext(
|
|
1291
|
+
env,
|
|
1292
|
+
ctx,
|
|
1293
|
+
request,
|
|
1294
|
+
() => __devflareFetchHandler(request, env, ctx),
|
|
1295
|
+
'fetch'
|
|
1296
|
+
)
|
|
1297
|
+
},
|
|
1298
|
+
...(__devflareQueueHandler
|
|
1299
|
+
? {
|
|
1300
|
+
async queue(batch, env, ctx) {
|
|
1301
|
+
return runWithContext(
|
|
1302
|
+
env,
|
|
1303
|
+
ctx,
|
|
1304
|
+
null,
|
|
1305
|
+
() => __devflareQueueHandler(batch, env, ctx),
|
|
1306
|
+
'queue'
|
|
1307
|
+
)
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
: {}),
|
|
1311
|
+
...(__devflareScheduledHandler
|
|
1312
|
+
? {
|
|
1313
|
+
async scheduled(controller, env, ctx) {
|
|
1314
|
+
return runWithContext(
|
|
1315
|
+
env,
|
|
1316
|
+
ctx,
|
|
1317
|
+
null,
|
|
1318
|
+
() => __devflareScheduledHandler(controller, env, ctx),
|
|
1319
|
+
'scheduled'
|
|
1320
|
+
)
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
: {}),
|
|
1324
|
+
...(__devflareEmailHandler
|
|
1325
|
+
? {
|
|
1326
|
+
async email(message, env, ctx) {
|
|
1327
|
+
return runWithContext(
|
|
1328
|
+
env,
|
|
1329
|
+
ctx,
|
|
1330
|
+
null,
|
|
1331
|
+
() => __devflareEmailHandler(message, env, ctx),
|
|
1332
|
+
'email'
|
|
1333
|
+
)
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
: {})
|
|
1337
|
+
}
|
|
1338
|
+
`;
|
|
1339
|
+
}
|
|
1340
|
+
function addWorkerWatchRoots(roots, cwd, configuredPath, defaultEntries) {
|
|
1341
|
+
if (configuredPath === false) {
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1344
|
+
if (typeof configuredPath === "string" && configuredPath) {
|
|
1345
|
+
roots.add(dirname2(resolve2(cwd, configuredPath)));
|
|
1346
|
+
return;
|
|
1347
|
+
}
|
|
1348
|
+
for (const defaultEntry of defaultEntries) {
|
|
1349
|
+
roots.add(dirname2(resolve2(cwd, defaultEntry)));
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
function collectWorkerWatchRoots(cwd, config, mainWorkerSurfacePaths) {
|
|
1127
1353
|
const roots = new Set;
|
|
1128
1354
|
const addFileParent = (filePath) => {
|
|
1129
1355
|
if (typeof filePath !== "string" || !filePath) {
|
|
@@ -1131,13 +1357,15 @@ function collectWorkerWatchRoots(cwd, config, mainWorkerScriptPath) {
|
|
|
1131
1357
|
}
|
|
1132
1358
|
roots.add(dirname2(resolve2(cwd, filePath)));
|
|
1133
1359
|
};
|
|
1134
|
-
|
|
1135
|
-
|
|
1360
|
+
for (const surfacePath of Object.values(mainWorkerSurfacePaths)) {
|
|
1361
|
+
if (surfacePath) {
|
|
1362
|
+
roots.add(dirname2(surfacePath));
|
|
1363
|
+
}
|
|
1136
1364
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1365
|
+
addWorkerWatchRoots(roots, cwd, config.files?.fetch, DEFAULT_FETCH_ENTRY_FILES);
|
|
1366
|
+
addWorkerWatchRoots(roots, cwd, config.files?.queue, DEFAULT_QUEUE_ENTRY_FILES);
|
|
1367
|
+
addWorkerWatchRoots(roots, cwd, config.files?.scheduled, DEFAULT_SCHEDULED_ENTRY_FILES);
|
|
1368
|
+
addWorkerWatchRoots(roots, cwd, config.files?.email, DEFAULT_EMAIL_ENTRY_FILES);
|
|
1141
1369
|
addFileParent(config.files?.transport);
|
|
1142
1370
|
if (config.files?.routes && typeof config.files.routes === "object") {
|
|
1143
1371
|
roots.add(resolve2(cwd, config.files.routes.dir));
|
|
@@ -1263,69 +1491,27 @@ async function handleEmailIncoming(request, env, ctx, url) {
|
|
|
1263
1491
|
const rawBody = await request.text()
|
|
1264
1492
|
|
|
1265
1493
|
log('Email incoming:', { from, to, bodyLength: rawBody.length })
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
const value = line.slice(colonIdx + 1).trim()
|
|
1285
|
-
headers.append(key, value)
|
|
1286
|
-
}
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
// Create ReadableStream from raw email
|
|
1290
|
-
const rawStream = new ReadableStream({
|
|
1291
|
-
start(controller) {
|
|
1292
|
-
controller.enqueue(new TextEncoder().encode(rawBody))
|
|
1293
|
-
controller.close()
|
|
1294
|
-
}
|
|
1295
|
-
})
|
|
1296
|
-
|
|
1297
|
-
// Create ForwardableEmailMessage-like object
|
|
1298
|
-
const emailMessage = {
|
|
1299
|
-
from,
|
|
1300
|
-
to,
|
|
1301
|
-
headers,
|
|
1302
|
-
raw: rawStream,
|
|
1303
|
-
rawSize: rawBody.length,
|
|
1304
|
-
|
|
1305
|
-
setReject(reason) {
|
|
1306
|
-
log('Email rejected:', reason)
|
|
1307
|
-
},
|
|
1308
|
-
|
|
1309
|
-
async forward(rcptTo, extraHeaders) {
|
|
1310
|
-
log('Email forwarded to:', rcptTo)
|
|
1311
|
-
return Promise.resolve()
|
|
1312
|
-
},
|
|
1313
|
-
|
|
1314
|
-
async reply(message) {
|
|
1315
|
-
log('Email reply sent to:', message.from)
|
|
1316
|
-
return Promise.resolve()
|
|
1494
|
+
|
|
1495
|
+
if (APP_SERVICE_BINDING) {
|
|
1496
|
+
const appWorker = env[APP_SERVICE_BINDING]
|
|
1497
|
+
if (appWorker && typeof appWorker.fetch === 'function') {
|
|
1498
|
+
const response = await appWorker.fetch(new Request('http://devflare.internal/_devflare/internal/email', {
|
|
1499
|
+
method: 'POST',
|
|
1500
|
+
headers: {
|
|
1501
|
+
'x-devflare-event': 'email',
|
|
1502
|
+
'x-devflare-email-from': from,
|
|
1503
|
+
'x-devflare-email-to': to,
|
|
1504
|
+
'content-type': request.headers.get('content-type') || 'text/plain'
|
|
1505
|
+
},
|
|
1506
|
+
body: rawBody
|
|
1507
|
+
}))
|
|
1508
|
+
|
|
1509
|
+
if (!response.ok) {
|
|
1510
|
+
return response
|
|
1511
|
+
}
|
|
1317
1512
|
}
|
|
1318
1513
|
}
|
|
1319
1514
|
|
|
1320
|
-
// Look for email handler in the worker module
|
|
1321
|
-
// For now, we call via a special RPC method that DO workers can implement
|
|
1322
|
-
// The email binding should be configured in the worker
|
|
1323
|
-
|
|
1324
|
-
// Check if there's an EMAIL_HANDLER binding (special DO for email handling)
|
|
1325
|
-
if (env.__emailHandler && typeof env.__emailHandler.email === 'function') {
|
|
1326
|
-
await env.__emailHandler.email(emailMessage, env, ctx)
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
1515
|
return new Response(JSON.stringify({ ok: true, from, to }), {
|
|
1330
1516
|
headers: { 'Content-Type': 'application/json' }
|
|
1331
1517
|
})
|
|
@@ -1737,16 +1923,24 @@ function createDevServer(options) {
|
|
|
1737
1923
|
let miniflare = null;
|
|
1738
1924
|
let doBundler = null;
|
|
1739
1925
|
let workerSourceWatcher = null;
|
|
1926
|
+
let workerWatchTargets = [];
|
|
1740
1927
|
let viteProcess = null;
|
|
1741
1928
|
let config = null;
|
|
1742
1929
|
let browserShim = null;
|
|
1743
1930
|
let browserShimPort = 8788;
|
|
1931
|
+
let mainWorkerSurfacePaths = {
|
|
1932
|
+
fetch: null,
|
|
1933
|
+
queue: null,
|
|
1934
|
+
scheduled: null,
|
|
1935
|
+
email: null
|
|
1936
|
+
};
|
|
1937
|
+
let resolvedWorkerConfigPath = null;
|
|
1744
1938
|
let mainWorkerScriptPath = null;
|
|
1745
1939
|
let bundledMainWorkerScriptPath = null;
|
|
1746
1940
|
let currentDoResult = null;
|
|
1747
1941
|
let reloadChain = Promise.resolve();
|
|
1748
1942
|
async function bundleMainWorker() {
|
|
1749
|
-
if (!
|
|
1943
|
+
if (!hasWorkerSurfacePaths(mainWorkerSurfacePaths)) {
|
|
1750
1944
|
bundledMainWorkerScriptPath = null;
|
|
1751
1945
|
return;
|
|
1752
1946
|
}
|
|
@@ -1755,17 +1949,27 @@ function createDevServer(options) {
|
|
|
1755
1949
|
}
|
|
1756
1950
|
const fs = await import("node:fs/promises");
|
|
1757
1951
|
const outDir = resolve2(cwd, ".devflare", "worker-bundles");
|
|
1952
|
+
const entryDir = resolve2(cwd, ".devflare", "worker-entrypoints");
|
|
1758
1953
|
await fs.rm(outDir, { recursive: true, force: true });
|
|
1759
1954
|
await fs.mkdir(outDir, { recursive: true });
|
|
1955
|
+
await fs.mkdir(entryDir, { recursive: true });
|
|
1956
|
+
const entryPath = resolve2(entryDir, "fetch-entry.ts");
|
|
1957
|
+
const surfaceImportPaths = {
|
|
1958
|
+
fetch: mainWorkerSurfacePaths.fetch ? toImportSpecifier(entryPath, mainWorkerSurfacePaths.fetch) : null,
|
|
1959
|
+
queue: mainWorkerSurfacePaths.queue ? toImportSpecifier(entryPath, mainWorkerSurfacePaths.queue) : null,
|
|
1960
|
+
scheduled: mainWorkerSurfacePaths.scheduled ? toImportSpecifier(entryPath, mainWorkerSurfacePaths.scheduled) : null,
|
|
1961
|
+
email: mainWorkerSurfacePaths.email ? toImportSpecifier(entryPath, mainWorkerSurfacePaths.email) : null
|
|
1962
|
+
};
|
|
1963
|
+
await fs.writeFile(entryPath, getMainWorkerEntryScript(surfaceImportPaths));
|
|
1760
1964
|
const result = await Bun.build({
|
|
1761
|
-
entrypoints: [
|
|
1965
|
+
entrypoints: [entryPath],
|
|
1762
1966
|
outdir: outDir,
|
|
1763
1967
|
target: "browser",
|
|
1764
1968
|
conditions: ["browser"],
|
|
1765
1969
|
format: "esm",
|
|
1766
1970
|
minify: false,
|
|
1767
1971
|
splitting: false,
|
|
1768
|
-
external: ["cloudflare:workers", "cloudflare:*"]
|
|
1972
|
+
external: ["cloudflare:workers", "cloudflare:*", "node:*"]
|
|
1769
1973
|
});
|
|
1770
1974
|
if (!result.success || result.outputs.length === 0) {
|
|
1771
1975
|
const logs = result.logs.map((log) => ("message" in log) ? log.message : String(log)).join(`
|
|
@@ -1783,7 +1987,7 @@ ${logs}`);
|
|
|
1783
1987
|
const bindings = loadedConfig.bindings ?? {};
|
|
1784
1988
|
const persistPath = resolve2(cwd, ".devflare/data");
|
|
1785
1989
|
const appWorkerName = loadedConfig.name;
|
|
1786
|
-
const shouldRunMainWorker = !enableVite &&
|
|
1990
|
+
const shouldRunMainWorker = !enableVite && hasWorkerSurfacePaths(mainWorkerSurfacePaths);
|
|
1787
1991
|
const queueProducers = (() => {
|
|
1788
1992
|
if (!bindings.queues?.producers) {
|
|
1789
1993
|
return;
|
|
@@ -1794,6 +1998,23 @@ ${logs}`);
|
|
|
1794
1998
|
}
|
|
1795
1999
|
return producers;
|
|
1796
2000
|
})();
|
|
2001
|
+
const queueConsumers = (() => {
|
|
2002
|
+
if (!bindings.queues?.consumers || bindings.queues.consumers.length === 0) {
|
|
2003
|
+
return;
|
|
2004
|
+
}
|
|
2005
|
+
const consumers = {};
|
|
2006
|
+
for (const consumer of bindings.queues.consumers) {
|
|
2007
|
+
consumers[consumer.queue] = {
|
|
2008
|
+
...consumer.maxBatchSize !== undefined && { maxBatchSize: consumer.maxBatchSize },
|
|
2009
|
+
...consumer.maxBatchTimeout !== undefined && { maxBatchTimeout: consumer.maxBatchTimeout },
|
|
2010
|
+
...consumer.maxRetries !== undefined && { maxRetries: consumer.maxRetries },
|
|
2011
|
+
...consumer.deadLetterQueue && { deadLetterQueue: consumer.deadLetterQueue },
|
|
2012
|
+
...consumer.maxConcurrency !== undefined && { maxConcurrency: consumer.maxConcurrency },
|
|
2013
|
+
...consumer.retryDelay !== undefined && { retryDelay: consumer.retryDelay }
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
return consumers;
|
|
2017
|
+
})();
|
|
1797
2018
|
const sharedOptions = {
|
|
1798
2019
|
port: miniflarePort,
|
|
1799
2020
|
host: "127.0.0.1",
|
|
@@ -1829,7 +2050,9 @@ ${logs}`);
|
|
|
1829
2050
|
...bindings.r2 && { r2Buckets: bindings.r2 },
|
|
1830
2051
|
...bindings.d1 && { d1Databases: bindings.d1 },
|
|
1831
2052
|
...loadedConfig.vars && Object.keys(loadedConfig.vars).length > 0 && { bindings: loadedConfig.vars },
|
|
1832
|
-
...queueProducers && { queueProducers }
|
|
2053
|
+
...queueProducers && { queueProducers },
|
|
2054
|
+
...options2.queueConsumers && { queueConsumers: options2.queueConsumers },
|
|
2055
|
+
...options2.triggers && { triggers: options2.triggers }
|
|
1833
2056
|
};
|
|
1834
2057
|
if (options2.scriptPath) {
|
|
1835
2058
|
workerConfig.scriptPath = options2.scriptPath;
|
|
@@ -1879,7 +2102,9 @@ ${logs}`);
|
|
|
1879
2102
|
const mainWorkerConfig = createWorkerConfig({
|
|
1880
2103
|
name: appWorkerName,
|
|
1881
2104
|
scriptPath: bundledMainWorkerScriptPath ?? mainWorkerScriptPath,
|
|
1882
|
-
serviceBindings: mainWorkerServiceBindings
|
|
2105
|
+
serviceBindings: mainWorkerServiceBindings,
|
|
2106
|
+
queueConsumers,
|
|
2107
|
+
triggers: loadedConfig.triggers?.crons?.length ? { crons: loadedConfig.triggers.crons } : undefined
|
|
1883
2108
|
});
|
|
1884
2109
|
workers.push(mainWorkerConfig);
|
|
1885
2110
|
}
|
|
@@ -1994,12 +2219,68 @@ ${logs}`);
|
|
|
1994
2219
|
reloadChain = queuedReload.catch(() => {});
|
|
1995
2220
|
await queuedReload;
|
|
1996
2221
|
}
|
|
2222
|
+
async function resolveWorkerConfigWatchPath() {
|
|
2223
|
+
if (configPath) {
|
|
2224
|
+
const explicitPath = resolve2(cwd, configPath);
|
|
2225
|
+
const fs = await import("node:fs/promises");
|
|
2226
|
+
try {
|
|
2227
|
+
await fs.access(explicitPath);
|
|
2228
|
+
return explicitPath;
|
|
2229
|
+
} catch {}
|
|
2230
|
+
}
|
|
2231
|
+
return await resolveConfigPath(cwd) ?? null;
|
|
2232
|
+
}
|
|
2233
|
+
async function refreshWorkerOnlySurfaceState() {
|
|
2234
|
+
if (!config) {
|
|
2235
|
+
return;
|
|
2236
|
+
}
|
|
2237
|
+
mainWorkerSurfacePaths = await resolveMainWorkerSurfacePaths(cwd, config);
|
|
2238
|
+
mainWorkerScriptPath = getFirstWorkerSurfacePath(mainWorkerSurfacePaths);
|
|
2239
|
+
if (hasWorkerSurfacePaths(mainWorkerSurfacePaths)) {
|
|
2240
|
+
await bundleMainWorker();
|
|
2241
|
+
} else {
|
|
2242
|
+
bundledMainWorkerScriptPath = null;
|
|
2243
|
+
}
|
|
2244
|
+
await syncWorkerWatchTargets();
|
|
2245
|
+
}
|
|
2246
|
+
function getWorkerWatchTargets() {
|
|
2247
|
+
if (enableVite || !config) {
|
|
2248
|
+
return [];
|
|
2249
|
+
}
|
|
2250
|
+
const targets = collectWorkerWatchRoots(cwd, config, mainWorkerSurfacePaths);
|
|
2251
|
+
if (resolvedWorkerConfigPath) {
|
|
2252
|
+
targets.push(resolvedWorkerConfigPath);
|
|
2253
|
+
}
|
|
2254
|
+
return [...new Set(targets)];
|
|
2255
|
+
}
|
|
2256
|
+
async function syncWorkerWatchTargets() {
|
|
2257
|
+
if (!workerSourceWatcher) {
|
|
2258
|
+
return;
|
|
2259
|
+
}
|
|
2260
|
+
const nextWatchTargets = getWorkerWatchTargets();
|
|
2261
|
+
const nextWatchTargetSet = new Set(nextWatchTargets);
|
|
2262
|
+
const targetsToRemove = workerWatchTargets.filter((target) => !nextWatchTargetSet.has(target));
|
|
2263
|
+
const targetsToAdd = nextWatchTargets.filter((target) => !workerWatchTargets.includes(target));
|
|
2264
|
+
if (targetsToRemove.length > 0) {
|
|
2265
|
+
await workerSourceWatcher.unwatch(targetsToRemove);
|
|
2266
|
+
}
|
|
2267
|
+
if (targetsToAdd.length > 0) {
|
|
2268
|
+
workerSourceWatcher.add(targetsToAdd);
|
|
2269
|
+
}
|
|
2270
|
+
workerWatchTargets = nextWatchTargets;
|
|
2271
|
+
}
|
|
2272
|
+
async function reloadWorkerOnlyConfig() {
|
|
2273
|
+
config = await loadConfig({ cwd, configFile: configPath });
|
|
2274
|
+
resolvedWorkerConfigPath = await resolveWorkerConfigWatchPath();
|
|
2275
|
+
await refreshWorkerOnlySurfaceState();
|
|
2276
|
+
await reloadMiniflare(currentDoResult);
|
|
2277
|
+
}
|
|
1997
2278
|
async function startWorkerSourceWatcher() {
|
|
1998
|
-
if (enableVite || !config
|
|
2279
|
+
if (enableVite || !config) {
|
|
1999
2280
|
return;
|
|
2000
2281
|
}
|
|
2001
|
-
const
|
|
2002
|
-
if (
|
|
2282
|
+
const watchTargets = getWorkerWatchTargets();
|
|
2283
|
+
if (watchTargets.length === 0) {
|
|
2003
2284
|
return;
|
|
2004
2285
|
}
|
|
2005
2286
|
const chokidar = await import("chokidar");
|
|
@@ -2020,8 +2301,14 @@ ${logs}`);
|
|
|
2020
2301
|
}
|
|
2021
2302
|
reloadInProgress = true;
|
|
2022
2303
|
try {
|
|
2304
|
+
const normalizedConfigPath = resolvedWorkerConfigPath ? normalizePath(resolvedWorkerConfigPath) : null;
|
|
2305
|
+
if (normalizedConfigPath && normalizePath(filePath) === normalizedConfigPath) {
|
|
2306
|
+
logger?.info(`Devflare config changed: ${filePath}`);
|
|
2307
|
+
await reloadWorkerOnlyConfig();
|
|
2308
|
+
return;
|
|
2309
|
+
}
|
|
2023
2310
|
logger?.info(`Worker source changed: ${filePath}`);
|
|
2024
|
-
await
|
|
2311
|
+
await refreshWorkerOnlySurfaceState();
|
|
2025
2312
|
await reloadMiniflare(currentDoResult);
|
|
2026
2313
|
} catch (error) {
|
|
2027
2314
|
logger?.error("Worker source reload failed:", error);
|
|
@@ -2042,7 +2329,8 @@ ${logs}`);
|
|
|
2042
2329
|
triggerReload(filePath);
|
|
2043
2330
|
}, 150);
|
|
2044
2331
|
};
|
|
2045
|
-
|
|
2332
|
+
workerWatchTargets = watchTargets;
|
|
2333
|
+
workerSourceWatcher = chokidar.watch(watchTargets, {
|
|
2046
2334
|
ignoreInitial: true,
|
|
2047
2335
|
usePolling: isWindows,
|
|
2048
2336
|
interval: isWindows ? 300 : undefined,
|
|
@@ -2062,7 +2350,7 @@ ${logs}`);
|
|
|
2062
2350
|
workerSourceWatcher.on("add", onFileEvent);
|
|
2063
2351
|
workerSourceWatcher.on("unlink", onFileEvent);
|
|
2064
2352
|
workerSourceWatcher.on("ready", () => {
|
|
2065
|
-
logger?.info(`Worker source watcher ready (${
|
|
2353
|
+
logger?.info(`Worker source watcher ready (${watchTargets.length} target(s))`);
|
|
2066
2354
|
});
|
|
2067
2355
|
workerSourceWatcher.on("error", (error) => {
|
|
2068
2356
|
logger?.error("Worker source watcher error:", error);
|
|
@@ -2152,13 +2440,14 @@ ${logs}`);
|
|
|
2152
2440
|
async function start() {
|
|
2153
2441
|
logger?.info("Starting unified dev server...");
|
|
2154
2442
|
config = await loadConfig({ cwd, configFile: configPath });
|
|
2443
|
+
resolvedWorkerConfigPath = await resolveWorkerConfigWatchPath();
|
|
2155
2444
|
logger?.debug("Loaded config:", config.name);
|
|
2156
|
-
|
|
2157
|
-
if (!enableVite &&
|
|
2158
|
-
|
|
2159
|
-
|
|
2445
|
+
await refreshWorkerOnlySurfaceState();
|
|
2446
|
+
if (!enableVite && hasWorkerSurfacePaths(mainWorkerSurfacePaths)) {
|
|
2447
|
+
const detectedWorkerHandlers = Object.entries(mainWorkerSurfacePaths).filter(([, surfacePath]) => !!surfacePath).map(([surfaceName, surfacePath]) => `${surfaceName}=${surfacePath}`).join(", ");
|
|
2448
|
+
logger?.info(`Worker handlers detected: ${detectedWorkerHandlers}`);
|
|
2160
2449
|
} else if (!enableVite) {
|
|
2161
|
-
logger?.warn("No local
|
|
2450
|
+
logger?.warn("No local worker handler entry was found for worker-only mode");
|
|
2162
2451
|
}
|
|
2163
2452
|
const remoteCheck = await checkRemoteBindingRequirements(config);
|
|
2164
2453
|
if (remoteCheck.hasRemoteBindings) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dev-server/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,WAAW,CAAA;AAc3D,MAAM,WAAW,gBAAgB;IAChC,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,sBAAsB;IACtB,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,SAAS;IACzB,2BAA2B;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,0BAA0B;IAC1B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrB,yCAAyC;IACzC,YAAY,IAAI,aAAa,GAAG,IAAI,CAAA;CACpC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dev-server/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,WAAW,CAAA;AAc3D,MAAM,WAAW,gBAAgB;IAChC,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,sBAAsB;IACtB,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,SAAS;IACzB,2BAA2B;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,0BAA0B;IAC1B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrB,yCAAyC;IACzC,YAAY,IAAI,aAAa,GAAG,IAAI,CAAA;CACpC;AAy3BD,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAi3BpE"}
|