devflare 1.0.0-next.10 → 1.0.0-next.12

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.
Files changed (45) hide show
  1. package/LLM.md +683 -13
  2. package/README.md +33 -5
  3. package/dist/{build-k36xrzvy.js → build-rfh8cgh3.js} +40 -11
  4. package/dist/bundler/index.d.ts +1 -0
  5. package/dist/bundler/index.d.ts.map +1 -1
  6. package/dist/bundler/worker-bundler.d.ts +14 -0
  7. package/dist/bundler/worker-bundler.d.ts.map +1 -0
  8. package/dist/cli/commands/build.d.ts.map +1 -1
  9. package/dist/cli/commands/deploy.d.ts.map +1 -1
  10. package/dist/cli/commands/dev.d.ts.map +1 -1
  11. package/dist/config/compiler.d.ts.map +1 -1
  12. package/dist/config/index.d.ts +1 -0
  13. package/dist/config/index.d.ts.map +1 -1
  14. package/dist/config/resolve.d.ts +3 -0
  15. package/dist/config/resolve.d.ts.map +1 -0
  16. package/dist/config/schema.d.ts +37 -31
  17. package/dist/config/schema.d.ts.map +1 -1
  18. package/dist/{deploy-dbvfq8vq.js → deploy-k0fcgt3d.js} +40 -11
  19. package/dist/{dev-rk8p6pse.js → dev-d4wabqyf.js} +73 -470
  20. package/dist/dev-server/server.d.ts.map +1 -1
  21. package/dist/{doctor-06y8nxd4.js → doctor-z4ffybce.js} +2 -2
  22. package/dist/{index-jht2j546.js → index-0kzg8wed.js} +26 -6
  23. package/dist/index-1xqeptt2.js +623 -0
  24. package/dist/{index-pwgyy2q9.js → index-dr6sbp8d.js} +1 -1
  25. package/dist/{index-6v3wjg1r.js → index-rfhx0yd5.js} +11 -7
  26. package/dist/{index-05fyzwne.js → index-twpgq9k9.js} +5 -5
  27. package/dist/{index-1phx14av.js → index-wyf3s77s.js} +1 -1
  28. package/dist/{index-vs49yxn4.js → index-xxwbb2nt.js} +1 -1
  29. package/dist/index-zbvmtcn2.js +795 -0
  30. package/dist/src/browser.js +1 -1
  31. package/dist/src/cli/index.js +1 -1
  32. package/dist/src/index.js +12 -13
  33. package/dist/src/sveltekit/index.js +4 -5
  34. package/dist/src/test/index.js +6 -7
  35. package/dist/src/vite/index.js +19 -399
  36. package/dist/test/simple-context.d.ts.map +1 -1
  37. package/dist/{types-x9q7t491.js → types-sffr9681.js} +7 -8
  38. package/dist/vite/config-file.d.ts +25 -0
  39. package/dist/vite/config-file.d.ts.map +1 -0
  40. package/dist/vite/index.d.ts +1 -0
  41. package/dist/vite/index.d.ts.map +1 -1
  42. package/dist/worker-entry/composed-worker.d.ts.map +1 -1
  43. package/package.json +1 -1
  44. package/dist/index-k7r18na8.js +0 -0
  45. package/dist/index-ws68xvq2.js +0 -311
@@ -0,0 +1,623 @@
1
+ import {
2
+ findFiles
3
+ } from "./index-rbht7m9r.js";
4
+ import {
5
+ findDurableObjectClasses,
6
+ transformDurableObject
7
+ } from "./index-9wt9x09k.js";
8
+ import {
9
+ __require
10
+ } from "./index-37x76zdn.js";
11
+
12
+ // src/bundler/worker-bundler.ts
13
+ import { fileURLToPath } from "node:url";
14
+ import { dirname, resolve } from "pathe";
15
+ function toArray(value) {
16
+ return Array.isArray(value) ? value : [value];
17
+ }
18
+ function matchesExternalPattern(pattern, id) {
19
+ if (pattern instanceof RegExp) {
20
+ pattern.lastIndex = 0;
21
+ return pattern.test(id);
22
+ }
23
+ return pattern === id;
24
+ }
25
+ function matchesExternalOption(option, id, parentId, isResolved) {
26
+ if (!option) {
27
+ return false;
28
+ }
29
+ if (typeof option === "function") {
30
+ return option(id, parentId, isResolved) ?? false;
31
+ }
32
+ return toArray(option).some((pattern) => matchesExternalPattern(pattern, id));
33
+ }
34
+ function mergeExternalOptions(base, user) {
35
+ if (!base) {
36
+ return user;
37
+ }
38
+ if (!user) {
39
+ return base;
40
+ }
41
+ if (typeof base !== "function" && typeof user !== "function") {
42
+ return [...toArray(base), ...toArray(user)];
43
+ }
44
+ return (id, parentId, isResolved) => {
45
+ return matchesExternalOption(base, id, parentId, isResolved) || matchesExternalOption(user, id, parentId, isResolved) || false;
46
+ };
47
+ }
48
+ function mergePluginOptions(base, user) {
49
+ if (!base) {
50
+ return user;
51
+ }
52
+ if (!user) {
53
+ return base;
54
+ }
55
+ return [base, user];
56
+ }
57
+ function mergeResolveOptions(base, user) {
58
+ if (!base) {
59
+ return user;
60
+ }
61
+ if (!user) {
62
+ return base;
63
+ }
64
+ return {
65
+ ...user,
66
+ ...base,
67
+ alias: {
68
+ ...user.alias ?? {},
69
+ ...base.alias ?? {}
70
+ }
71
+ };
72
+ }
73
+ async function ensureDebugShim(outDir) {
74
+ const fs = await import("node:fs/promises");
75
+ const debugShimCode = `
76
+ // Debug module shim for local development
77
+ const createDebug = (namespace) => {
78
+ const logger = (...args) => {
79
+ if (createDebug.enabled) console.debug(\`[\${namespace}]\`, ...args)
80
+ }
81
+ logger.enabled = false
82
+ logger.namespace = namespace
83
+ logger.extend = (sub) => createDebug(\`\${namespace}:\${sub}\`)
84
+ return logger
85
+ }
86
+ createDebug.enabled = false
87
+ createDebug.formatters = {}
88
+ export default createDebug
89
+ `;
90
+ const debugShimPath = resolve(outDir, "_debug_shim.js");
91
+ await fs.writeFile(debugShimPath, debugShimCode, "utf-8");
92
+ return debugShimPath;
93
+ }
94
+ async function resolveInternalModuleEntry(relativeCandidates) {
95
+ const fs = await import("node:fs/promises");
96
+ const currentFileDir = dirname(fileURLToPath(import.meta.url));
97
+ for (const candidate of relativeCandidates) {
98
+ const absolutePath = resolve(currentFileDir, candidate);
99
+ try {
100
+ await fs.access(absolutePath);
101
+ return absolutePath;
102
+ } catch {
103
+ continue;
104
+ }
105
+ }
106
+ return null;
107
+ }
108
+ async function resolveInternalAliasMap(outDir) {
109
+ const debugShimPath = await ensureDebugShim(outDir);
110
+ const runtimeEntry = await resolveInternalModuleEntry([
111
+ "../runtime/index.ts",
112
+ "../runtime/index.js"
113
+ ]);
114
+ const packageEntry = await resolveInternalModuleEntry([
115
+ "../index.ts",
116
+ "../index.js"
117
+ ]);
118
+ return {
119
+ debug: debugShimPath,
120
+ ...runtimeEntry ? { "devflare/runtime": runtimeEntry } : {},
121
+ ...packageEntry ? { devflare: packageEntry } : {}
122
+ };
123
+ }
124
+ function resolveWorkerRolldownConfig(options) {
125
+ const {
126
+ output: userOutputOptions,
127
+ input: _ignoredInput,
128
+ cwd: _ignoredCwd,
129
+ platform: _ignoredPlatform,
130
+ target: userTarget,
131
+ watch: _ignoredWatch,
132
+ external: userExternal,
133
+ plugins: userPlugins,
134
+ resolve: userResolve,
135
+ tsconfig: userTsconfig,
136
+ ...userInputOptions
137
+ } = options.rolldownOptions ?? {};
138
+ const {
139
+ codeSplitting: _ignoredCodeSplitting,
140
+ dir: _ignoredDir,
141
+ file: _ignoredFile,
142
+ format: _ignoredFormat,
143
+ inlineDynamicImports: _ignoredInlineDynamicImports,
144
+ ...safeUserOutputOptions
145
+ } = userOutputOptions ?? {};
146
+ const defaultExternalModules = [
147
+ /^cloudflare:/,
148
+ /^node:/,
149
+ "buffer",
150
+ "crypto",
151
+ "events",
152
+ "http",
153
+ "https",
154
+ "net",
155
+ "os",
156
+ "path",
157
+ "stream",
158
+ "tls",
159
+ "url",
160
+ "util",
161
+ "zlib",
162
+ "fs",
163
+ "child_process",
164
+ "async_hooks",
165
+ "querystring",
166
+ "string_decoder",
167
+ "assert",
168
+ "dns"
169
+ ];
170
+ return {
171
+ inputOptions: {
172
+ ...userInputOptions,
173
+ input: options.inputFile,
174
+ cwd: options.cwd,
175
+ platform: "browser",
176
+ target: userTarget ?? options.target,
177
+ tsconfig: userTsconfig ?? resolve(options.cwd, "tsconfig.json"),
178
+ external: mergeExternalOptions(defaultExternalModules, userExternal),
179
+ plugins: mergePluginOptions(undefined, userPlugins),
180
+ resolve: mergeResolveOptions({
181
+ alias: options.alias
182
+ }, userResolve)
183
+ },
184
+ outputOptions: {
185
+ ...safeUserOutputOptions,
186
+ file: options.outFile,
187
+ format: "esm",
188
+ sourcemap: safeUserOutputOptions.sourcemap ?? options.sourcemap ?? false,
189
+ minify: safeUserOutputOptions.minify ?? options.minify,
190
+ codeSplitting: false
191
+ }
192
+ };
193
+ }
194
+ async function bundleWorkerEntry(options) {
195
+ const { rolldown } = await import("rolldown");
196
+ const fs = await import("node:fs/promises");
197
+ const outDir = dirname(options.outFile);
198
+ await fs.mkdir(outDir, { recursive: true });
199
+ await fs.rm(options.outFile, { force: true });
200
+ await fs.rm(`${options.outFile}.map`, { force: true });
201
+ const alias = await resolveInternalAliasMap(outDir);
202
+ const { inputOptions, outputOptions } = resolveWorkerRolldownConfig({
203
+ cwd: options.cwd,
204
+ inputFile: options.inputFile,
205
+ outFile: options.outFile,
206
+ alias,
207
+ rolldownOptions: options.rolldownOptions,
208
+ sourcemap: options.sourcemap,
209
+ minify: options.minify,
210
+ target: options.target
211
+ });
212
+ options.logger?.debug(`Bundling main worker → ${options.outFile}`);
213
+ const bundle = await rolldown(inputOptions);
214
+ try {
215
+ await bundle.write(outputOptions);
216
+ } finally {
217
+ await bundle.close();
218
+ }
219
+ return options.outFile;
220
+ }
221
+
222
+ // src/bundler/do-bundler.ts
223
+ import { resolve as resolve2, dirname as dirname2, relative } from "pathe";
224
+ import picomatch from "picomatch";
225
+ function classToBindingName(className) {
226
+ return className.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").toUpperCase();
227
+ }
228
+ async function discoverDOs(cwd, pattern) {
229
+ const fs = await import("node:fs/promises");
230
+ const discovered = [];
231
+ const files = await findFiles(pattern, { cwd });
232
+ for (const filePath of files) {
233
+ try {
234
+ const code = await fs.readFile(filePath, "utf-8");
235
+ const classNames = findDurableObjectClasses(code);
236
+ for (const className of classNames) {
237
+ discovered.push({
238
+ filePath,
239
+ className,
240
+ bindingName: classToBindingName(className)
241
+ });
242
+ }
243
+ } catch {}
244
+ }
245
+ return discovered;
246
+ }
247
+ function stripDecoratorSyntax(code) {
248
+ let result = code;
249
+ result = result.replace(/@durableObject\s*\([^)]*\)\s*\n?\s*(?=export\s+class)/g, "");
250
+ result = result.replace(/import\s*\{([^}]*)\bdurableObject\b[^}]*\}\s*from\s*['"]devflare\/runtime['"]\s*;?/g, (match, imports) => {
251
+ const cleanedImports = imports.split(",").map((s) => s.trim()).filter((s) => !s.startsWith("durableObject")).join(", ");
252
+ if (cleanedImports.trim() === "") {
253
+ return "";
254
+ }
255
+ return `import { ${cleanedImports} } from 'devflare/runtime'`;
256
+ });
257
+ return result;
258
+ }
259
+ function toArray2(value) {
260
+ return Array.isArray(value) ? value : [value];
261
+ }
262
+ function matchesExternalPattern2(pattern, id) {
263
+ if (pattern instanceof RegExp) {
264
+ pattern.lastIndex = 0;
265
+ return pattern.test(id);
266
+ }
267
+ return pattern === id;
268
+ }
269
+ function matchesExternalOption2(option, id, parentId, isResolved) {
270
+ if (!option) {
271
+ return false;
272
+ }
273
+ if (typeof option === "function") {
274
+ return option(id, parentId, isResolved) ?? false;
275
+ }
276
+ return toArray2(option).some((pattern) => matchesExternalPattern2(pattern, id));
277
+ }
278
+ function mergeExternalOptions2(base, user) {
279
+ if (!base) {
280
+ return user;
281
+ }
282
+ if (!user) {
283
+ return base;
284
+ }
285
+ if (typeof base !== "function" && typeof user !== "function") {
286
+ return [...toArray2(base), ...toArray2(user)];
287
+ }
288
+ return (id, parentId, isResolved) => {
289
+ return matchesExternalOption2(base, id, parentId, isResolved) || matchesExternalOption2(user, id, parentId, isResolved) || false;
290
+ };
291
+ }
292
+ function mergePluginOptions2(base, user) {
293
+ if (!base) {
294
+ return user;
295
+ }
296
+ if (!user) {
297
+ return base;
298
+ }
299
+ return [base, user];
300
+ }
301
+ function mergeResolveOptions2(base, user) {
302
+ if (!base) {
303
+ return user;
304
+ }
305
+ if (!user) {
306
+ return base;
307
+ }
308
+ return {
309
+ ...user,
310
+ ...base,
311
+ alias: {
312
+ ...user.alias ?? {},
313
+ ...base.alias ?? {}
314
+ }
315
+ };
316
+ }
317
+ function resolveDOBundleRolldownConfig(options) {
318
+ const {
319
+ output: userOutputOptions,
320
+ input: _ignoredInput,
321
+ cwd: _ignoredCwd,
322
+ platform: _ignoredPlatform,
323
+ watch: _ignoredWatch,
324
+ external: userExternal,
325
+ plugins: userPlugins,
326
+ resolve: userResolve,
327
+ tsconfig: userTsconfig,
328
+ ...userInputOptions
329
+ } = options.rolldownOptions ?? {};
330
+ const {
331
+ codeSplitting: _ignoredCodeSplitting,
332
+ dir: _ignoredDir,
333
+ file: _ignoredFile,
334
+ format: _ignoredFormat,
335
+ inlineDynamicImports: _ignoredInlineDynamicImports,
336
+ ...safeUserOutputOptions
337
+ } = userOutputOptions ?? {};
338
+ const defaultExternalModules = [
339
+ /^cloudflare:/,
340
+ /^node:/,
341
+ "buffer",
342
+ "crypto",
343
+ "events",
344
+ "http",
345
+ "https",
346
+ "net",
347
+ "os",
348
+ "path",
349
+ "stream",
350
+ "tls",
351
+ "url",
352
+ "util",
353
+ "zlib",
354
+ "fs",
355
+ "child_process",
356
+ "async_hooks",
357
+ "querystring",
358
+ "string_decoder",
359
+ "assert",
360
+ "dns"
361
+ ];
362
+ return {
363
+ inputOptions: {
364
+ ...userInputOptions,
365
+ input: options.inputFile,
366
+ cwd: options.cwd,
367
+ platform: "neutral",
368
+ tsconfig: userTsconfig ?? resolve2(options.cwd, "tsconfig.json"),
369
+ external: mergeExternalOptions2(defaultExternalModules, userExternal),
370
+ plugins: mergePluginOptions2(undefined, userPlugins),
371
+ resolve: mergeResolveOptions2({
372
+ alias: {
373
+ debug: options.debugShimPath
374
+ }
375
+ }, userResolve)
376
+ },
377
+ outputOptions: {
378
+ ...safeUserOutputOptions,
379
+ file: options.outFile,
380
+ format: "esm",
381
+ sourcemap: safeUserOutputOptions.sourcemap ?? options.sourcemap ?? false,
382
+ minify: safeUserOutputOptions.minify ?? options.minify,
383
+ codeSplitting: false
384
+ }
385
+ };
386
+ }
387
+ async function bundleDOFile(sourcePath, className, outDir, cwd, bundleOptions) {
388
+ const { rolldown } = await import("rolldown");
389
+ const fs = await import("node:fs/promises");
390
+ await fs.mkdir(outDir, { recursive: true });
391
+ const sourceCode = await fs.readFile(sourcePath, "utf-8");
392
+ const transformedCode = (await transformDurableObject(sourceCode, sourcePath))?.code ?? stripDecoratorSyntax(sourceCode);
393
+ const entryCode = `${transformedCode}
394
+
395
+ // Default export for worker (required by Miniflare)
396
+ export default {
397
+ async fetch(request) {
398
+ return new Response('DO Worker for ${className}', { status: 200 });
399
+ }
400
+ };
401
+ `;
402
+ const tempFilePath = resolve2(dirname2(sourcePath), `.devflare-temp-${className}.ts`);
403
+ await fs.writeFile(tempFilePath, entryCode, "utf-8");
404
+ const classOutDir = resolve2(outDir, className);
405
+ try {
406
+ await fs.rm(classOutDir, { recursive: true, force: true });
407
+ } catch {}
408
+ await fs.mkdir(classOutDir, { recursive: true });
409
+ const debugShimCode = `
410
+ // Debug module shim for local development
411
+ const createDebug = (namespace) => {
412
+ const logger = (...args) => {
413
+ if (createDebug.enabled) console.debug(\`[\${namespace}]\`, ...args)
414
+ }
415
+ logger.enabled = false
416
+ logger.namespace = namespace
417
+ logger.extend = (sub) => createDebug(\`\${namespace}:\${sub}\`)
418
+ return logger
419
+ }
420
+ createDebug.enabled = false
421
+ createDebug.formatters = {}
422
+ export default createDebug
423
+ `;
424
+ const debugShimPath = resolve2(outDir, "_debug_shim.js");
425
+ await fs.writeFile(debugShimPath, debugShimCode, "utf-8");
426
+ const outFile = resolve2(classOutDir, "index.js");
427
+ const { inputOptions, outputOptions } = resolveDOBundleRolldownConfig({
428
+ cwd,
429
+ inputFile: tempFilePath,
430
+ outFile,
431
+ debugShimPath,
432
+ rolldownOptions: bundleOptions?.rolldownOptions,
433
+ sourcemap: bundleOptions?.sourcemap,
434
+ minify: bundleOptions?.minify
435
+ });
436
+ const bundle = await rolldown(inputOptions);
437
+ await bundle.write(outputOptions);
438
+ await bundle.close();
439
+ try {
440
+ await fs.unlink(tempFilePath);
441
+ } catch {}
442
+ return resolve2(classOutDir, "index.js");
443
+ }
444
+ async function bundleAllDOs(discovered, outDir, cwd, logger, bundleOptions) {
445
+ const fs = await import("node:fs/promises");
446
+ const bundles = new Map;
447
+ const classes = new Map;
448
+ const sourceFiles = new Map;
449
+ const errors = [];
450
+ for (const do_ of discovered) {
451
+ const existing = sourceFiles.get(do_.filePath) || [];
452
+ existing.push(do_.className);
453
+ sourceFiles.set(do_.filePath, existing);
454
+ }
455
+ for (const do_ of discovered) {
456
+ try {
457
+ logger?.debug(`Bundling ${do_.className} from ${do_.filePath}`);
458
+ const outFile = await bundleDOFile(do_.filePath, do_.className, outDir, cwd, bundleOptions);
459
+ bundles.set(do_.bindingName, outFile);
460
+ classes.set(do_.bindingName, do_.className);
461
+ logger?.debug(` → ${outFile}`);
462
+ } catch (error) {
463
+ const err = error instanceof Error ? error : new Error(String(error));
464
+ errors.push(err);
465
+ logger?.error(`Failed to bundle ${do_.className}:`, err.message);
466
+ }
467
+ }
468
+ return { bundles, classes, sourceFiles, errors };
469
+ }
470
+ function createDOBundler(options) {
471
+ const { cwd, pattern, outDir, logger, onRebuild, rolldownOptions, sourcemap, minify } = options;
472
+ let result = {
473
+ bundles: new Map,
474
+ classes: new Map,
475
+ sourceFiles: new Map,
476
+ errors: []
477
+ };
478
+ let watcher = null;
479
+ let chokidarWatcher = null;
480
+ async function build() {
481
+ const discovered = await discoverDOs(cwd, pattern);
482
+ if (discovered.length === 0) {
483
+ logger?.debug("No DOs found matching pattern:", pattern);
484
+ return result;
485
+ }
486
+ logger?.info(`Found ${discovered.length} Durable Object(s)`);
487
+ for (const do_ of discovered) {
488
+ logger?.info(` • ${do_.className} → ${do_.bindingName}`);
489
+ }
490
+ result = await bundleAllDOs(discovered, outDir, cwd, logger, {
491
+ rolldownOptions,
492
+ sourcemap,
493
+ minify
494
+ });
495
+ if (result.errors.length === 0) {
496
+ logger?.success(`Bundled ${result.bundles.size} DO(s) to ${outDir}`);
497
+ }
498
+ return result;
499
+ }
500
+ async function watch() {
501
+ const chokidar = await import("chokidar");
502
+ const files = await findFiles(pattern, { cwd });
503
+ let dirsToWatch;
504
+ if (files.length > 0) {
505
+ dirsToWatch = [...new Set(files.map((f) => dirname2(f)))];
506
+ } else {
507
+ const patternDir = dirname2(pattern);
508
+ const absolutePatternDir = resolve2(cwd, patternDir === "." ? "" : patternDir) || cwd;
509
+ dirsToWatch = [absolutePatternDir];
510
+ logger?.debug(`No DO files yet, watching pattern directory: ${absolutePatternDir}`);
511
+ }
512
+ logger?.info(`Watching ${files.length} DO file(s) in ${dirsToWatch.length} director(ies)...`);
513
+ const isWindows = process.platform === "win32";
514
+ chokidarWatcher = chokidar.watch(dirsToWatch, {
515
+ ignoreInitial: true,
516
+ usePolling: isWindows,
517
+ interval: isWindows ? 300 : undefined,
518
+ awaitWriteFinish: {
519
+ stabilityThreshold: 100,
520
+ pollInterval: 50
521
+ },
522
+ depth: 0
523
+ });
524
+ const normalizePath = (p) => {
525
+ let normalized = p.replace(/\\/g, "/");
526
+ if (isWindows && /^[a-zA-Z]:/.test(normalized)) {
527
+ normalized = normalized[0].toLowerCase() + normalized.slice(1);
528
+ }
529
+ return normalized;
530
+ };
531
+ const isMatch = picomatch(pattern, {
532
+ cwd,
533
+ dot: true,
534
+ matchBase: false
535
+ });
536
+ const matchesPattern = (filePath) => {
537
+ const normalizedPath = normalizePath(filePath);
538
+ const relativePath = relative(normalizePath(cwd), normalizedPath);
539
+ return isMatch(relativePath);
540
+ };
541
+ let isRebuilding = false;
542
+ let pendingRebuild = null;
543
+ let rebuildTimeout = null;
544
+ const scheduleRebuild = (changedPath) => {
545
+ if (rebuildTimeout) {
546
+ clearTimeout(rebuildTimeout);
547
+ }
548
+ rebuildTimeout = setTimeout(() => {
549
+ triggerRebuild(changedPath);
550
+ }, 150);
551
+ };
552
+ const triggerRebuild = async (changedPath) => {
553
+ if (isRebuilding) {
554
+ pendingRebuild = changedPath;
555
+ logger?.debug(`Rebuild already in progress, queuing: ${changedPath}`);
556
+ return;
557
+ }
558
+ isRebuilding = true;
559
+ try {
560
+ logger?.info(`DO file changed: ${changedPath}`);
561
+ logger?.info("Rebuilding DOs...");
562
+ const startTime = Date.now();
563
+ result = await build();
564
+ const elapsed = Date.now() - startTime;
565
+ logger?.success(`DO rebuild complete (${elapsed}ms)`);
566
+ await onRebuild?.(result);
567
+ } catch (error) {
568
+ logger?.error("DO rebuild failed:", error);
569
+ } finally {
570
+ isRebuilding = false;
571
+ if (pendingRebuild) {
572
+ const nextPath = pendingRebuild;
573
+ pendingRebuild = null;
574
+ triggerRebuild(nextPath);
575
+ }
576
+ }
577
+ };
578
+ chokidarWatcher.on("change", (filePath) => {
579
+ if (matchesPattern(filePath)) {
580
+ logger?.debug(`File changed: ${filePath}`);
581
+ scheduleRebuild(filePath);
582
+ }
583
+ });
584
+ chokidarWatcher.on("add", (filePath) => {
585
+ if (matchesPattern(filePath)) {
586
+ logger?.debug(`File added: ${filePath}`);
587
+ scheduleRebuild(filePath);
588
+ }
589
+ });
590
+ chokidarWatcher.on("unlink", (filePath) => {
591
+ if (matchesPattern(filePath)) {
592
+ logger?.debug(`File removed: ${filePath}`);
593
+ scheduleRebuild(filePath);
594
+ }
595
+ });
596
+ chokidarWatcher.on("ready", () => {
597
+ logger?.info("DO file watcher ready");
598
+ });
599
+ chokidarWatcher.on("error", (error) => {
600
+ logger?.error("DO file watcher error:", error);
601
+ });
602
+ }
603
+ async function close() {
604
+ if (watcher) {
605
+ await watcher.close();
606
+ watcher = null;
607
+ }
608
+ if (chokidarWatcher) {
609
+ await chokidarWatcher.close();
610
+ chokidarWatcher = null;
611
+ }
612
+ }
613
+ function getResult() {
614
+ return result;
615
+ }
616
+ return {
617
+ build,
618
+ watch,
619
+ close,
620
+ getResult
621
+ };
622
+ }
623
+ export { createDOBundler, bundleWorkerEntry };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveConfigPath
3
- } from "./index-1phx14av.js";
3
+ } from "./index-wyf3s77s.js";
4
4
 
5
5
  // src/cli/config-path.ts
6
6
  import { stat } from "node:fs/promises";
@@ -1,17 +1,22 @@
1
1
  import {
2
2
  normalizeDOBinding
3
- } from "./index-1phx14av.js";
3
+ } from "./index-wyf3s77s.js";
4
4
  import {
5
5
  __require
6
6
  } from "./index-37x76zdn.js";
7
7
 
8
- // src/config/compiler.ts
8
+ // src/config/resolve.ts
9
9
  import { defu } from "defu";
10
- function compileConfig(config, environment) {
11
- let mergedConfig = config;
10
+ function resolveConfigForEnvironment(config, environment) {
12
11
  if (environment && config.env?.[environment]) {
13
- mergedConfig = defu(config.env[environment], config);
12
+ return defu(config.env[environment], config);
14
13
  }
14
+ return config;
15
+ }
16
+
17
+ // src/config/compiler.ts
18
+ function compileConfig(config, environment) {
19
+ const mergedConfig = resolveConfigForEnvironment(config, environment);
15
20
  const result = {
16
21
  name: mergedConfig.name,
17
22
  compatibility_date: mergedConfig.compatibilityDate
@@ -194,5 +199,4 @@ async function writeWranglerConfig(cwd, config, filename = "wrangler.jsonc") {
194
199
  await fs.writeFile(wranglerPath, content, "utf-8");
195
200
  return wranglerPath;
196
201
  }
197
-
198
- export { compileConfig, compileToProgrammaticConfig, stringifyConfig, writeWranglerConfig };
202
+ export { resolveConfigForEnvironment, compileConfig, compileToProgrammaticConfig, stringifyConfig, writeWranglerConfig };
@@ -160,23 +160,23 @@ async function runInit(parsed, logger, options) {
160
160
  return runInitCommand(parsed, logger, options);
161
161
  }
162
162
  async function runDev(parsed, logger, options) {
163
- const { runDevCommand } = await import("./dev-rk8p6pse.js");
163
+ const { runDevCommand } = await import("./dev-d4wabqyf.js");
164
164
  return runDevCommand(parsed, logger, options);
165
165
  }
166
166
  async function runBuild(parsed, logger, options) {
167
- const { runBuildCommand } = await import("./build-k36xrzvy.js");
167
+ const { runBuildCommand } = await import("./build-rfh8cgh3.js");
168
168
  return runBuildCommand(parsed, logger, options);
169
169
  }
170
170
  async function runDeploy(parsed, logger, options) {
171
- const { runDeployCommand } = await import("./deploy-dbvfq8vq.js");
171
+ const { runDeployCommand } = await import("./deploy-k0fcgt3d.js");
172
172
  return runDeployCommand(parsed, logger, options);
173
173
  }
174
174
  async function runTypes(parsed, logger, options) {
175
- const { runTypesCommand } = await import("./types-x9q7t491.js");
175
+ const { runTypesCommand } = await import("./types-sffr9681.js");
176
176
  return runTypesCommand(parsed, logger, options);
177
177
  }
178
178
  async function runDoctor(parsed, logger, options) {
179
- const { runDoctorCommand } = await import("./doctor-06y8nxd4.js");
179
+ const { runDoctorCommand } = await import("./doctor-z4ffybce.js");
180
180
  return runDoctorCommand(parsed, logger, options);
181
181
  }
182
182
  async function runAccount(parsed, logger, options) {
@@ -17,7 +17,7 @@ var filesSchema = z.object({
17
17
  entrypoints: z.union([z.string(), z.literal(false)]).optional(),
18
18
  workflows: z.union([z.string(), z.literal(false)]).optional(),
19
19
  routes: z.union([routesConfigSchema, z.literal(false)]).optional(),
20
- transport: z.string().optional()
20
+ transport: z.union([z.string(), z.null()]).optional()
21
21
  }).optional();
22
22
  var durableObjectBindingSchema = z.custom((val) => {
23
23
  if (typeof val === "string")