@cloudflare/vite-plugin 0.0.0-d16f1c6a1 → 0.0.0-d1a1787b2

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/index.js CHANGED
@@ -489,7 +489,7 @@ import assert10 from "node:assert";
489
489
  import * as fs5 from "node:fs";
490
490
  import * as fsp2 from "node:fs/promises";
491
491
  import * as path9 from "node:path";
492
- import { createMiddleware } from "@hattip/adapter-node";
492
+ import { createRequest, sendResponse } from "@mjackson/node-fetch-server";
493
493
  import replace from "@rollup/plugin-replace";
494
494
 
495
495
  // ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
@@ -1558,7 +1558,7 @@ var MagicString = class _MagicString {
1558
1558
 
1559
1559
  // src/index.ts
1560
1560
  import { Miniflare } from "miniflare";
1561
- import colors2 from "picocolors";
1561
+ import colors3 from "picocolors";
1562
1562
  import * as vite7 from "vite";
1563
1563
 
1564
1564
  // src/constants.ts
@@ -1571,6 +1571,7 @@ var ADDITIONAL_MODULE_TYPES = [
1571
1571
  "Text"
1572
1572
  ];
1573
1573
  var DEFAULT_INSPECTOR_PORT = 9229;
1574
+ var kRequestType = Symbol("kRequestType");
1574
1575
 
1575
1576
  // src/additional-modules.ts
1576
1577
  var moduleRules = [
@@ -1589,7 +1590,7 @@ function matchAdditionalModule(source) {
1589
1590
  return null;
1590
1591
  }
1591
1592
  function createModuleReference(type, id) {
1592
- return `__CLOUDFLARE_MODULE__${type}__${id}__`;
1593
+ return `__CLOUDFLARE_MODULE__${type}__${id}__CLOUDFLARE_MODULE__`;
1593
1594
  }
1594
1595
 
1595
1596
  // src/asset-config.ts
@@ -12648,8 +12649,8 @@ function packageResolve(specifier, base, conditions) {
12648
12649
  let packageJsonPath = fileURLToPath$1(packageJsonUrl);
12649
12650
  let lastPath;
12650
12651
  do {
12651
- const stat = tryStatSync(packageJsonPath.slice(0, -13));
12652
- if (!stat || !stat.isDirectory()) {
12652
+ const stat2 = tryStatSync(packageJsonPath.slice(0, -13));
12653
+ if (!stat2 || !stat2.isDirectory()) {
12653
12654
  lastPath = packageJsonPath;
12654
12655
  packageJsonUrl = new URL$1(
12655
12656
  (isScoped ? "../../../../node_modules/" : "../../../node_modules/") + packageName + "/package.json",
@@ -12779,8 +12780,8 @@ function _resolve(id, options = {}) {
12779
12780
  }
12780
12781
  if (isAbsolute(id)) {
12781
12782
  try {
12782
- const stat = statSync(id);
12783
- if (stat.isFile()) {
12783
+ const stat2 = statSync(id);
12784
+ if (stat2.isFile()) {
12784
12785
  return pathToFileURL(id);
12785
12786
  }
12786
12787
  } catch (error) {
@@ -12993,7 +12994,7 @@ var NodeJsCompatWarnings = class {
12993
12994
  // src/shared.ts
12994
12995
  var UNKNOWN_HOST = "http://localhost";
12995
12996
  var INIT_PATH = "/__vite_plugin_cloudflare_init__";
12996
- var ADDITIONAL_MODULE_PATTERN = `__CLOUDFLARE_MODULE__(${ADDITIONAL_MODULE_TYPES.join("|")})__(.*?)__`;
12997
+ var ADDITIONAL_MODULE_PATTERN = `__CLOUDFLARE_MODULE__(${ADDITIONAL_MODULE_TYPES.join("|")})__(.*?)__CLOUDFLARE_MODULE__`;
12997
12998
  var additionalModuleRE = new RegExp(ADDITIONAL_MODULE_PATTERN);
12998
12999
  var additionalModuleGlobalRE = new RegExp(
12999
13000
  ADDITIONAL_MODULE_PATTERN,
@@ -13010,9 +13011,6 @@ function getOutputDirectory(userConfig, environmentName) {
13010
13011
  const rootOutputDirectory = userConfig.build?.outDir ?? "dist";
13011
13012
  return userConfig.environments?.[environmentName]?.build?.outDir ?? path4.join(rootOutputDirectory, environmentName);
13012
13013
  }
13013
- function getRouterWorker(miniflare2) {
13014
- return miniflare2.getWorker(ROUTER_WORKER_NAME);
13015
- }
13016
13014
  function toMiniflareRequest(request) {
13017
13015
  const host = request.headers.get("Host");
13018
13016
  if (host) {
@@ -13029,19 +13027,6 @@ function toMiniflareRequest(request) {
13029
13027
  duplex: "half"
13030
13028
  });
13031
13029
  }
13032
- function nodeHeadersToWebHeaders(nodeHeaders) {
13033
- const headers = new Headers();
13034
- for (const [key, value] of Object.entries(nodeHeaders)) {
13035
- if (typeof value === "string") {
13036
- headers.append(key, value);
13037
- } else if (Array.isArray(value)) {
13038
- for (const item of value) {
13039
- headers.append(key, item);
13040
- }
13041
- }
13042
- }
13043
- return headers;
13044
- }
13045
13030
  var postfixRE = /[?#].*$/;
13046
13031
  function cleanUrl(url) {
13047
13032
  return url.replace(postfixRE, "");
@@ -13270,7 +13255,7 @@ import { unstable_readConfig } from "wrangler";
13270
13255
  function getDeployConfigPath(root) {
13271
13256
  return path5.resolve(root, ".wrangler", "deploy", "config.json");
13272
13257
  }
13273
- function getWorkerConfigs(root) {
13258
+ function getWorkerConfigs(root, mixedModeEnabled) {
13274
13259
  const deployConfigPath = getDeployConfigPath(root);
13275
13260
  const deployConfig = JSON.parse(
13276
13261
  fs2.readFileSync(deployConfigPath, "utf-8")
@@ -13283,7 +13268,10 @@ function getWorkerConfigs(root) {
13283
13268
  path5.dirname(deployConfigPath),
13284
13269
  configPath
13285
13270
  );
13286
- return unstable_readConfig({ config: resolvedConfigPath });
13271
+ return unstable_readConfig(
13272
+ { config: resolvedConfigPath },
13273
+ { experimental: { mixedModeEnabled } }
13274
+ );
13287
13275
  });
13288
13276
  }
13289
13277
  function getRelativePathToWorkerConfig(deployConfigDirectory, root, outputDirectory) {
@@ -13350,17 +13338,24 @@ import * as fsp from "node:fs/promises";
13350
13338
  import * as path6 from "node:path";
13351
13339
  import { fileURLToPath as fileURLToPath2 } from "node:url";
13352
13340
  import {
13341
+ getDefaultDevRegistryPath,
13353
13342
  kCurrentWorker,
13354
13343
  Log,
13355
13344
  LogLevel,
13356
13345
  Response as MiniflareResponse
13357
13346
  } from "miniflare";
13347
+ import colors2 from "picocolors";
13358
13348
  import { globSync } from "tinyglobby";
13359
13349
  import "vite";
13360
- import { unstable_getMiniflareWorkerOptions } from "wrangler";
13361
- function getPersistence(root, persistState) {
13350
+ import {
13351
+ experimental_pickRemoteBindings,
13352
+ experimental_startMixedModeSession,
13353
+ unstable_convertConfigBindingsToStartWorkerBindings,
13354
+ unstable_getMiniflareWorkerOptions
13355
+ } from "wrangler";
13356
+ function getPersistenceRoot(root, persistState) {
13362
13357
  if (persistState === false) {
13363
- return {};
13358
+ return;
13364
13359
  }
13365
13360
  const defaultPersistPath = ".wrangler/state";
13366
13361
  const persistPath = path6.resolve(
@@ -13368,14 +13363,7 @@ function getPersistence(root, persistState) {
13368
13363
  typeof persistState === "object" ? persistState.path : defaultPersistPath,
13369
13364
  "v3"
13370
13365
  );
13371
- return {
13372
- cachePersist: path6.join(persistPath, "cache"),
13373
- d1Persist: path6.join(persistPath, "d1"),
13374
- durableObjectsPersist: path6.join(persistPath, "do"),
13375
- kvPersist: path6.join(persistPath, "kv"),
13376
- r2Persist: path6.join(persistPath, "r2"),
13377
- workflowsPersist: path6.join(persistPath, "workflows")
13378
- };
13366
+ return persistPath;
13379
13367
  }
13380
13368
  function missingWorkerErrorMessage(workerName) {
13381
13369
  return `${workerName} does not match a worker name.`;
@@ -13459,7 +13447,29 @@ function getEntryWorkerConfig(resolvedPluginConfig) {
13459
13447
  }
13460
13448
  return resolvedPluginConfig.workers[resolvedPluginConfig.entryWorkerEnvironmentName];
13461
13449
  }
13462
- function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPort) {
13450
+ function logUnknownTails(tails, userWorkers, log) {
13451
+ for (const tailService of tails ?? []) {
13452
+ let name;
13453
+ if (typeof tailService === "string") {
13454
+ name = tailService;
13455
+ } else if (typeof tailService === "object" && "name" in tailService && typeof tailService.name === "string") {
13456
+ name = tailService.name;
13457
+ } else {
13458
+ continue;
13459
+ }
13460
+ const found = userWorkers.some((w) => w.name === name);
13461
+ if (!found) {
13462
+ log(
13463
+ colors2.dim(
13464
+ colors2.yellow(
13465
+ `Tail consumer "${name}" was not found in your config. Make sure you add it to the config or run it in another dev session if you'd like to simulate receiving tail events locally.`
13466
+ )
13467
+ )
13468
+ );
13469
+ }
13470
+ }
13471
+ }
13472
+ async function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPort) {
13463
13473
  const resolvedViteConfig = viteDevServer.config;
13464
13474
  const entryWorkerConfig = getEntryWorkerConfig(resolvedPluginConfig);
13465
13475
  const assetsConfig = getAssetsConfig(
@@ -13510,12 +13520,14 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13510
13520
  serviceBindings: {
13511
13521
  __VITE_ASSET_EXISTS__: async (request) => {
13512
13522
  const { pathname } = new URL(request.url);
13513
- const filePath = path6.join(resolvedViteConfig.root, pathname);
13514
- let exists;
13515
- try {
13516
- exists = fs3.statSync(filePath).isFile();
13517
- } catch (error) {
13518
- exists = false;
13523
+ let exists = false;
13524
+ if (pathname.endsWith(".html")) {
13525
+ try {
13526
+ const filePath = path6.join(resolvedViteConfig.root, pathname);
13527
+ const stats = await fsp.stat(filePath);
13528
+ exists = stats.isFile();
13529
+ } catch (error) {
13530
+ }
13519
13531
  }
13520
13532
  return MiniflareResponse.json(exists);
13521
13533
  },
@@ -13529,59 +13541,75 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13529
13541
  headers: { "Content-Type": "text/html" }
13530
13542
  });
13531
13543
  } catch (error) {
13532
- throw new Error(`Unexpected error. Failed to load ${pathname}`);
13544
+ throw new Error(`Unexpected error. Failed to load "${pathname}".`);
13533
13545
  }
13534
13546
  }
13535
13547
  }
13536
13548
  }
13537
13549
  ];
13538
- const workersFromConfig = resolvedPluginConfig.type === "workers" ? Object.entries(resolvedPluginConfig.workers).map(
13539
- ([environmentName, workerConfig]) => {
13540
- const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(
13541
- {
13542
- ...workerConfig,
13543
- assets: void 0
13544
- },
13545
- resolvedPluginConfig.cloudflareEnv
13546
- );
13547
- const { externalWorkers: externalWorkers2 } = miniflareWorkerOptions;
13548
- const { ratelimits, ...workerOptions } = miniflareWorkerOptions.workerOptions;
13549
- return {
13550
- externalWorkers: externalWorkers2,
13551
- worker: {
13552
- ...workerOptions,
13553
- name: workerOptions.name ?? workerConfig.name,
13554
- unsafeInspectorProxy: inspectorPort !== false,
13555
- modulesRoot: miniflareModulesRoot,
13556
- unsafeEvalBinding: "__VITE_UNSAFE_EVAL__",
13557
- serviceBindings: {
13558
- ...workerOptions.serviceBindings,
13559
- ...environmentName === resolvedPluginConfig.entryWorkerEnvironmentName && workerConfig.assets?.binding ? {
13560
- [workerConfig.assets.binding]: ASSET_WORKER_NAME
13561
- } : {},
13562
- __VITE_INVOKE_MODULE__: async (request) => {
13563
- const payload = await request.json();
13564
- const invokePayloadData = payload.data;
13565
- assert6(
13566
- invokePayloadData.name === "fetchModule",
13567
- `Invalid invoke event: ${invokePayloadData.name}`
13568
- );
13569
- const [moduleId] = invokePayloadData.data;
13570
- if (additionalModuleRE.test(moduleId)) {
13571
- const result2 = {
13572
- externalize: moduleId,
13573
- type: "module"
13574
- };
13575
- return MiniflareResponse.json({ result: result2 });
13550
+ const workersFromConfig = resolvedPluginConfig.type === "workers" ? await Promise.all(
13551
+ Object.entries(resolvedPluginConfig.workers).map(
13552
+ async ([environmentName, workerConfig]) => {
13553
+ const mixedModeSession = resolvedPluginConfig.experimental.mixedMode ? await maybeStartOrUpdateMixedModeSession(workerConfig) : void 0;
13554
+ const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(
13555
+ {
13556
+ ...workerConfig,
13557
+ assets: void 0
13558
+ },
13559
+ resolvedPluginConfig.cloudflareEnv,
13560
+ {
13561
+ mixedModeConnectionString: mixedModeSession?.mixedModeConnectionString,
13562
+ mixedModeEnabled: resolvedPluginConfig.experimental.mixedMode
13563
+ }
13564
+ );
13565
+ const { externalWorkers: externalWorkers2 } = miniflareWorkerOptions;
13566
+ const { ratelimits, ...workerOptions } = miniflareWorkerOptions.workerOptions;
13567
+ return {
13568
+ externalWorkers: externalWorkers2,
13569
+ worker: {
13570
+ ...workerOptions,
13571
+ name: workerOptions.name ?? workerConfig.name,
13572
+ unsafeInspectorProxy: inspectorPort !== false,
13573
+ unsafeDirectSockets: environmentName === resolvedPluginConfig.entryWorkerEnvironmentName ? (
13574
+ // Expose the default entrypoint of the entry worker on the dev registry
13575
+ [{ entrypoint: void 0, proxy: true }]
13576
+ ) : [],
13577
+ modulesRoot: miniflareModulesRoot,
13578
+ unsafeEvalBinding: "__VITE_UNSAFE_EVAL__",
13579
+ serviceBindings: {
13580
+ ...workerOptions.serviceBindings,
13581
+ ...environmentName === resolvedPluginConfig.entryWorkerEnvironmentName && workerConfig.assets?.binding ? {
13582
+ [workerConfig.assets.binding]: {
13583
+ node: (req, res) => {
13584
+ req[kRequestType] = "asset";
13585
+ viteDevServer.middlewares(req, res);
13586
+ }
13587
+ }
13588
+ } : {},
13589
+ __VITE_INVOKE_MODULE__: async (request) => {
13590
+ const payload = await request.json();
13591
+ const invokePayloadData = payload.data;
13592
+ assert6(
13593
+ invokePayloadData.name === "fetchModule",
13594
+ `Invalid invoke event: ${invokePayloadData.name}`
13595
+ );
13596
+ const [moduleId] = invokePayloadData.data;
13597
+ if (additionalModuleRE.test(moduleId)) {
13598
+ const result2 = {
13599
+ externalize: moduleId,
13600
+ type: "module"
13601
+ };
13602
+ return MiniflareResponse.json({ result: result2 });
13603
+ }
13604
+ const devEnvironment = viteDevServer.environments[environmentName];
13605
+ const result = await devEnvironment.hot.handleInvoke(payload);
13606
+ return MiniflareResponse.json(result);
13576
13607
  }
13577
- const devEnvironment = viteDevServer.environments[environmentName];
13578
- const result = await devEnvironment.hot.handleInvoke(payload);
13579
- return MiniflareResponse.json(result);
13580
13608
  }
13581
13609
  }
13582
- }
13583
- };
13584
- }
13610
+ };
13611
+ }
13612
+ )
13585
13613
  ) : [];
13586
13614
  const userWorkers = workersFromConfig.map((options) => options.worker);
13587
13615
  const externalWorkers = workersFromConfig.flatMap(
@@ -13593,8 +13621,10 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13593
13621
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
13594
13622
  return {
13595
13623
  log: logger,
13624
+ logRequests: false,
13596
13625
  inspectorPort: inspectorPort === false ? void 0 : inspectorPort,
13597
13626
  unsafeInspectorProxy: inspectorPort !== false,
13627
+ unsafeDevRegistryPath: getDefaultDevRegistryPath(),
13598
13628
  handleRuntimeStdio(stdout, stderr) {
13599
13629
  const decoder = new TextDecoder();
13600
13630
  stdout.forEach((data2) => logger.info(decoder.decode(data2)));
@@ -13602,7 +13632,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13602
13632
  (error) => logger.logWithLevel(LogLevel.ERROR, decoder.decode(error))
13603
13633
  );
13604
13634
  },
13605
- ...getPersistence(
13635
+ defaultPersistRoot: getPersistenceRoot(
13606
13636
  resolvedViteConfig.root,
13607
13637
  resolvedPluginConfig.persistState
13608
13638
  ),
@@ -13648,6 +13678,11 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPo
13648
13678
  `export const ${className} = createWorkflowEntrypointWrapper('${className}');`
13649
13679
  );
13650
13680
  }
13681
+ logUnknownTails(
13682
+ workerOptions.tails,
13683
+ userWorkers,
13684
+ viteDevServer.config.logger.warn
13685
+ );
13651
13686
  return {
13652
13687
  ...workerOptions,
13653
13688
  modules: [
@@ -13731,27 +13766,48 @@ function getPreviewModules(main, modulesRules) {
13731
13766
  ]
13732
13767
  };
13733
13768
  }
13734
- function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistState, inspectorPort) {
13769
+ async function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistState, mixedModeEnabled, inspectorPort) {
13735
13770
  const resolvedViteConfig = vitePreviewServer.config;
13736
- const workers = workerConfigs.flatMap((config) => {
13737
- const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(config);
13738
- const { externalWorkers } = miniflareWorkerOptions;
13739
- const { ratelimits, modulesRules, ...workerOptions } = miniflareWorkerOptions.workerOptions;
13740
- return [
13741
- {
13742
- ...workerOptions,
13743
- name: workerOptions.name ?? config.name,
13744
- unsafeInspectorProxy: inspectorPort !== false,
13745
- ...miniflareWorkerOptions.main ? getPreviewModules(miniflareWorkerOptions.main, modulesRules) : { modules: true, script: "" }
13746
- },
13747
- ...externalWorkers
13748
- ];
13749
- });
13771
+ const workers = (await Promise.all(
13772
+ workerConfigs.map(async (workerConfig, i) => {
13773
+ const mixedModeSession = mixedModeEnabled ? await maybeStartOrUpdateMixedModeSession(workerConfig) : void 0;
13774
+ const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(
13775
+ workerConfig,
13776
+ void 0,
13777
+ {
13778
+ mixedModeConnectionString: mixedModeSession?.mixedModeConnectionString,
13779
+ mixedModeEnabled
13780
+ }
13781
+ );
13782
+ const { externalWorkers } = miniflareWorkerOptions;
13783
+ const { ratelimits, modulesRules, ...workerOptions } = miniflareWorkerOptions.workerOptions;
13784
+ logUnknownTails(
13785
+ workerOptions.tails,
13786
+ workerConfigs,
13787
+ vitePreviewServer.config.logger.warn
13788
+ );
13789
+ return [
13790
+ {
13791
+ ...workerOptions,
13792
+ name: workerOptions.name ?? workerConfig.name,
13793
+ unsafeInspectorProxy: inspectorPort !== false,
13794
+ unsafeDirectSockets: (
13795
+ // This exposes the default entrypoint of the entry worker on the dev registry
13796
+ // Assuming that the first worker config to be the entry worker.
13797
+ i === 0 ? [{ entrypoint: void 0, proxy: true }] : []
13798
+ ),
13799
+ ...miniflareWorkerOptions.main ? getPreviewModules(miniflareWorkerOptions.main, modulesRules) : { modules: true, script: "" }
13800
+ },
13801
+ ...externalWorkers
13802
+ ];
13803
+ })
13804
+ )).flat();
13750
13805
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
13751
13806
  return {
13752
13807
  log: logger,
13753
13808
  inspectorPort: inspectorPort === false ? void 0 : inspectorPort,
13754
13809
  unsafeInspectorProxy: inspectorPort !== false,
13810
+ unsafeDevRegistryPath: getDefaultDevRegistryPath(),
13755
13811
  handleRuntimeStdio(stdout, stderr) {
13756
13812
  const decoder = new TextDecoder();
13757
13813
  stdout.forEach((data2) => logger.info(decoder.decode(data2)));
@@ -13759,11 +13815,13 @@ function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistSta
13759
13815
  (error) => logger.logWithLevel(LogLevel.ERROR, decoder.decode(error))
13760
13816
  );
13761
13817
  },
13762
- ...getPersistence(resolvedViteConfig.root, persistState),
13818
+ defaultPersistRoot: getPersistenceRoot(
13819
+ resolvedViteConfig.root,
13820
+ persistState
13821
+ ),
13763
13822
  workers
13764
13823
  };
13765
13824
  }
13766
- var removedMessages = [/^Ready on http/, /^Updated and ready on http/];
13767
13825
  var ViteMiniflareLogger = class extends Log {
13768
13826
  logger;
13769
13827
  constructor(config) {
@@ -13771,11 +13829,6 @@ var ViteMiniflareLogger = class extends Log {
13771
13829
  this.logger = config.logger;
13772
13830
  }
13773
13831
  logWithLevel(level, message) {
13774
- for (const removedMessage of removedMessages) {
13775
- if (removedMessage.test(message)) {
13776
- return;
13777
- }
13778
- }
13779
13832
  switch (level) {
13780
13833
  case LogLevel.ERROR:
13781
13834
  return this.logger.error(message);
@@ -13785,6 +13838,8 @@ var ViteMiniflareLogger = class extends Log {
13785
13838
  return this.logger.info(message);
13786
13839
  }
13787
13840
  }
13841
+ logReady() {
13842
+ }
13788
13843
  };
13789
13844
  function miniflareLogLevelFromViteLogLevel(level = "info") {
13790
13845
  switch (level) {
@@ -13798,6 +13853,24 @@ function miniflareLogLevelFromViteLogLevel(level = "info") {
13798
13853
  return LogLevel.NONE;
13799
13854
  }
13800
13855
  }
13856
+ var mixedModeSessionsMap = /* @__PURE__ */ new Map();
13857
+ async function maybeStartOrUpdateMixedModeSession(workerConfig) {
13858
+ const workerRemoteBindings = experimental_pickRemoteBindings(
13859
+ unstable_convertConfigBindingsToStartWorkerBindings(workerConfig) ?? {}
13860
+ );
13861
+ assert6(workerConfig.name, "Found workerConfig without a name");
13862
+ let mixedModeSession = mixedModeSessionsMap.get(workerConfig.name);
13863
+ if (mixedModeSession === void 0) {
13864
+ if (Object.keys(workerRemoteBindings).length > 0) {
13865
+ mixedModeSession = await experimental_startMixedModeSession(workerRemoteBindings);
13866
+ mixedModeSessionsMap.set(workerConfig.name, mixedModeSession);
13867
+ }
13868
+ } else {
13869
+ await mixedModeSession.updateBindings(workerRemoteBindings);
13870
+ }
13871
+ await mixedModeSession?.ready;
13872
+ return mixedModeSession;
13873
+ }
13801
13874
 
13802
13875
  // src/plugin-config.ts
13803
13876
  import assert8 from "node:assert";
@@ -13852,12 +13925,15 @@ var nullableNonApplicable = [
13852
13925
  "site",
13853
13926
  "tsconfig"
13854
13927
  ];
13855
- function readWorkerConfig(configPath, env2) {
13928
+ function readWorkerConfig(configPath, env2, mixedModeEnabled) {
13856
13929
  const nonApplicable = {
13857
13930
  replacedByVite: /* @__PURE__ */ new Set(),
13858
13931
  notRelevant: /* @__PURE__ */ new Set()
13859
13932
  };
13860
- const config = unstable_readConfig2({ config: configPath, env: env2 }, {});
13933
+ const config = unstable_readConfig2(
13934
+ { config: configPath, env: env2 },
13935
+ { experimental: { mixedModeEnabled } }
13936
+ );
13861
13937
  const raw = structuredClone(config);
13862
13938
  nullableNonApplicable.forEach((prop) => {
13863
13939
  if (config[prop] !== void 0) {
@@ -13952,11 +14028,15 @@ function isNotRelevant(configName) {
13952
14028
  function missingFieldErrorMessage(field, configPath, env2) {
13953
14029
  return `No ${field} field provided in '${configPath}'${env2 ? ` for '${env2}' environment` : ""}`;
13954
14030
  }
13955
- function getWorkerConfig(configPath, env2, opts) {
14031
+ function getWorkerConfig(configPath, env2, mixedModeEnabled, opts) {
13956
14032
  if (opts?.visitedConfigPaths?.has(configPath)) {
13957
14033
  throw new Error(`Duplicate Wrangler config path found: ${configPath}`);
13958
14034
  }
13959
- const { raw, config, nonApplicable } = readWorkerConfig(configPath, env2);
14035
+ const { raw, config, nonApplicable } = readWorkerConfig(
14036
+ configPath,
14037
+ env2,
14038
+ mixedModeEnabled
14039
+ );
13960
14040
  opts?.visitedConfigPaths?.add(configPath);
13961
14041
  if (!config.name) {
13962
14042
  throw new Error(missingFieldErrorMessage(`'name'`, configPath, env2));
@@ -14081,6 +14161,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14081
14161
  const entryWorkerResolvedConfig = getWorkerConfig(
14082
14162
  entryWorkerConfigPath,
14083
14163
  cloudflareEnv,
14164
+ pluginConfig.experimental?.mixedMode ?? false,
14084
14165
  {
14085
14166
  visitedConfigPaths: configPaths,
14086
14167
  isEntryWorker: true
@@ -14114,6 +14195,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14114
14195
  const workerResolvedConfig = getWorkerConfig(
14115
14196
  workerConfigPath,
14116
14197
  cloudflareEnv,
14198
+ pluginConfig.experimental?.mixedMode ?? false,
14117
14199
  {
14118
14200
  visitedConfigPaths: configPaths
14119
14201
  }
@@ -14148,6 +14230,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14148
14230
  }
14149
14231
 
14150
14232
  // src/websockets.ts
14233
+ import { createHeaders } from "@mjackson/node-fetch-server";
14151
14234
  import { coupleWebSocket } from "miniflare";
14152
14235
  import { WebSocketServer } from "ws";
14153
14236
  function handleWebSocket(httpServer, getFetcher) {
@@ -14159,7 +14242,7 @@ function handleWebSocket(httpServer, getFetcher) {
14159
14242
  if (request.headers["sec-websocket-protocol"]?.startsWith("vite")) {
14160
14243
  return;
14161
14244
  }
14162
- const headers = nodeHeadersToWebHeaders(request.headers);
14245
+ const headers = createHeaders(request);
14163
14246
  const fetcher = await getFetcher();
14164
14247
  const response = await fetcher(url, {
14165
14248
  headers,
@@ -14426,81 +14509,93 @@ function cloudflare2(pluginConfig = {}) {
14426
14509
  }
14427
14510
  },
14428
14511
  async configureServer(viteDevServer) {
14429
- assert10(
14430
- viteDevServer.httpServer,
14431
- "Unexpected error: No Vite HTTP server"
14432
- );
14433
14512
  const inputInspectorPort = await getInputInspectorPortOption(
14434
14513
  pluginConfig,
14435
14514
  viteDevServer
14436
14515
  );
14516
+ const miniflareDevOptions = await getDevMiniflareOptions(
14517
+ resolvedPluginConfig,
14518
+ viteDevServer,
14519
+ inputInspectorPort
14520
+ );
14437
14521
  if (!miniflare) {
14438
- miniflare = new Miniflare(
14439
- getDevMiniflareOptions(
14440
- resolvedPluginConfig,
14441
- viteDevServer,
14442
- inputInspectorPort
14443
- )
14444
- );
14522
+ miniflare = new Miniflare(miniflareDevOptions);
14445
14523
  } else {
14446
- await miniflare.setOptions(
14447
- getDevMiniflareOptions(
14448
- resolvedPluginConfig,
14449
- viteDevServer,
14450
- inputInspectorPort
14451
- )
14452
- );
14524
+ await miniflare.setOptions(miniflareDevOptions);
14453
14525
  }
14454
14526
  await initRunners(resolvedPluginConfig, viteDevServer, miniflare);
14455
- const middleware = createMiddleware(
14456
- async ({ request }) => {
14527
+ if (viteDevServer.httpServer) {
14528
+ handleWebSocket(viteDevServer.httpServer, async () => {
14457
14529
  assert10(miniflare, `Miniflare not defined`);
14458
- const routerWorker = await getRouterWorker(miniflare);
14459
- return routerWorker.fetch(toMiniflareRequest(request), {
14460
- redirect: "manual"
14461
- });
14462
- },
14463
- { alwaysCallNext: false }
14464
- );
14465
- handleWebSocket(viteDevServer.httpServer, async () => {
14466
- assert10(miniflare, `Miniflare not defined`);
14467
- const routerWorker = await getRouterWorker(miniflare);
14468
- return routerWorker.fetch;
14469
- });
14530
+ const routerWorker = await miniflare.getWorker(ROUTER_WORKER_NAME);
14531
+ return routerWorker.fetch;
14532
+ });
14533
+ }
14470
14534
  return () => {
14471
- viteDevServer.middlewares.use((req, res, next) => {
14472
- middleware(req, res, next);
14535
+ viteDevServer.middlewares.use(async (req, res, next) => {
14536
+ try {
14537
+ assert10(miniflare, `Miniflare not defined`);
14538
+ const request = createRequest(req, res);
14539
+ let response;
14540
+ if (req[kRequestType] === "asset") {
14541
+ const assetWorker = await miniflare.getWorker(ASSET_WORKER_NAME);
14542
+ response = await assetWorker.fetch(
14543
+ toMiniflareRequest(request),
14544
+ { redirect: "manual" }
14545
+ );
14546
+ } else {
14547
+ const routerWorker = await miniflare.getWorker(ROUTER_WORKER_NAME);
14548
+ response = await routerWorker.fetch(
14549
+ toMiniflareRequest(request),
14550
+ { redirect: "manual" }
14551
+ );
14552
+ }
14553
+ if (req.httpVersionMajor === 2) {
14554
+ response.headers.delete("transfer-encoding");
14555
+ }
14556
+ await sendResponse(res, response);
14557
+ } catch (error) {
14558
+ next(error);
14559
+ }
14473
14560
  });
14474
14561
  };
14475
14562
  },
14476
14563
  async configurePreviewServer(vitePreviewServer) {
14477
- const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
14564
+ const workerConfigs = getWorkerConfigs(
14565
+ vitePreviewServer.config.root,
14566
+ pluginConfig.experimental?.mixedMode ?? false
14567
+ );
14478
14568
  const inputInspectorPort = await getInputInspectorPortOption(
14479
14569
  pluginConfig,
14480
14570
  vitePreviewServer
14481
14571
  );
14482
14572
  const miniflare2 = new Miniflare(
14483
- getPreviewMiniflareOptions(
14573
+ await getPreviewMiniflareOptions(
14484
14574
  vitePreviewServer,
14485
14575
  workerConfigs,
14486
14576
  pluginConfig.persistState ?? true,
14577
+ !!pluginConfig.experimental?.mixedMode,
14487
14578
  inputInspectorPort
14488
14579
  )
14489
14580
  );
14490
- const middleware = createMiddleware(
14491
- ({ request }) => {
14492
- return miniflare2.dispatchFetch(toMiniflareRequest(request), {
14493
- redirect: "manual"
14494
- });
14495
- },
14496
- { alwaysCallNext: false }
14497
- );
14498
14581
  handleWebSocket(
14499
14582
  vitePreviewServer.httpServer,
14500
14583
  () => miniflare2.dispatchFetch
14501
14584
  );
14502
- vitePreviewServer.middlewares.use((req, res, next) => {
14503
- middleware(req, res, next);
14585
+ vitePreviewServer.middlewares.use(async (req, res, next) => {
14586
+ try {
14587
+ const request = createRequest(req, res);
14588
+ const response = await miniflare2.dispatchFetch(
14589
+ toMiniflareRequest(request),
14590
+ { redirect: "manual" }
14591
+ );
14592
+ if (req.httpVersionMajor === 2) {
14593
+ response.headers.delete("transfer-encoding");
14594
+ }
14595
+ await sendResponse(res, response);
14596
+ } catch (error) {
14597
+ next(error);
14598
+ }
14504
14599
  });
14505
14600
  }
14506
14601
  },
@@ -14736,7 +14831,10 @@ function cloudflare2(pluginConfig = {}) {
14736
14831
  });
14737
14832
  },
14738
14833
  async configurePreviewServer(vitePreviewServer) {
14739
- const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
14834
+ const workerConfigs = getWorkerConfigs(
14835
+ vitePreviewServer.config.root,
14836
+ pluginConfig.experimental?.mixedMode ?? false
14837
+ );
14740
14838
  if (workerConfigs.length >= 1 && pluginConfig.inspectorPort !== false) {
14741
14839
  addDebugToVitePrintUrls(vitePreviewServer);
14742
14840
  }
@@ -14839,7 +14937,7 @@ async function getInputInspectorPortOption(pluginConfig, viteServer) {
14839
14937
  const inputInspectorPort = pluginConfig.inspectorPort ?? await getFirstAvailablePort(DEFAULT_INSPECTOR_PORT);
14840
14938
  if (pluginConfig.inspectorPort === void 0 && inputInspectorPort !== DEFAULT_INSPECTOR_PORT) {
14841
14939
  viteServer.config.logger.warn(
14842
- colors2.dim(
14940
+ colors3.dim(
14843
14941
  `Default inspector port ${DEFAULT_INSPECTOR_PORT} not available, using ${inputInspectorPort} instead
14844
14942
  `
14845
14943
  )