devflare 1.0.0-next.62 → 1.0.0-next.63

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.
@@ -1101,7 +1101,7 @@ async function runInit(parsed, logger, options) {
1101
1101
  return runInitCommand(parsed, logger, options);
1102
1102
  }
1103
1103
  async function runDev(parsed, logger, options) {
1104
- const { runDevCommand } = await import("./dev-9XMiBRSG.js");
1104
+ const { runDevCommand } = await import("./dev-o1NHvkSX.js");
1105
1105
  return runDevCommand(parsed, logger, options);
1106
1106
  }
1107
1107
  async function runBuild(parsed, logger, options) {
@@ -1706,6 +1706,20 @@ export default {
1706
1706
  if (matchedRoute) {
1707
1707
  return handleDoWebSocket(request, env, url, matchedRoute)
1708
1708
  }
1709
+ // Worker mode: the app worker (SvelteKit etc.) owns app WebSocket routes.
1710
+ // A handler like GET /api/doc/:id/subscribe that does
1711
+ // \`return stub.fetch(clientUpgradeRequest)\` must reach the app worker so
1712
+ // its returned 101 (with the DO's client socket) flows back to the
1713
+ // browser and the DO's hibernation handlers fire. The gateway previously
1714
+ // hijacked EVERY unmatched WS upgrade into the in-worker bridge socket
1715
+ // (handleBridgeWebSocket), so the app route never ran and two tabs never
1716
+ // shared the DO. Forward to the app first; only fall back to the bridge
1717
+ // socket when the app did not answer with a WebSocket upgrade (e.g. a
1718
+ // Node-side bridge RPC client, which only exists when there is no app).
1719
+ const appWsResponse = await forwardWebSocketToApp(request, env)
1720
+ if (appWsResponse) {
1721
+ return appWsResponse
1722
+ }
1709
1723
  return handleBridgeWebSocket(request, env, ctx)
1710
1724
  }
1711
1725
 
@@ -1913,6 +1927,25 @@ function matchWsRoute(pathname) {
1913
1927
  return null
1914
1928
  }
1915
1929
 
1930
+ // Forward a WebSocket upgrade to the app worker (worker mode) and pass through
1931
+ // its response ONLY when the app answered with a genuine WebSocket upgrade
1932
+ // (status 101 + a webSocket). Returns null otherwise so the caller falls back to
1933
+ // the in-worker bridge socket. This is what lets an app route that does
1934
+ // \`return stub.fetch(clientUpgradeRequest)\` reach the DO and stream the DO's
1935
+ // client socket back to the browser (hibernation handlers then fire, and two
1936
+ // tabs share one DO instance). A GET upgrade has no body, so forwarding the same
1937
+ // request and — on a non-101 answer — discarding it is safe (no stream consumed).
1938
+ async function forwardWebSocketToApp(request, env) {
1939
+ if (!APP_SERVICE_BINDING) return null
1940
+ const appWorker = env[APP_SERVICE_BINDING]
1941
+ if (!appWorker || typeof appWorker.fetch !== 'function') return null
1942
+ const response = await appWorker.fetch(request)
1943
+ if (response.status === 101 && response.webSocket) {
1944
+ return response
1945
+ }
1946
+ return null
1947
+ }
1948
+
1916
1949
  async function handleDoWebSocket(request, env, url, route) {
1917
1950
  try {
1918
1951
  const namespace = env[route.doNamespace]
package/dist/cli/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as runCli, t as parseArgs } from "../_chunks/cli-sOZfXGua.js";
1
+ import { n as runCli, t as parseArgs } from "../_chunks/cli-DsmlUqPd.js";
2
2
  export { parseArgs, runCli };
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-script.d.ts","sourceRoot":"","sources":["../../src/dev-server/gateway-script.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAE9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC/B,QAAQ,GAAE,aAAa,EAAO,EAC9B,KAAK,UAAQ,EACb,qBAAqB,GAAE,MAAM,GAAG,IAAW,GACzC,MAAM,CA4QR"}
1
+ {"version":3,"file":"gateway-script.d.ts","sourceRoot":"","sources":["../../src/dev-server/gateway-script.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAE9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC/B,QAAQ,GAAE,aAAa,EAAO,EAC9B,KAAK,UAAQ,EACb,qBAAqB,GAAE,MAAM,GAAG,IAAW,GACzC,MAAM,CA6SR"}
package/dist/index.js CHANGED
@@ -4,6 +4,6 @@ import { a as ConfigResourceResolutionError, d as configSchema, n as ConfigValid
4
4
  import { n as compileConfig, s as stringifyConfig } from "./_chunks/compiler-CgIFPfRA.js";
5
5
  import { t as workerName } from "./_chunks/workerName-CFJsLZA-.js";
6
6
  import { n as getDurableObjectOptions, t as durableObject } from "./_chunks/decorators-QmV57ixr.js";
7
- import { n as runCli, t as parseArgs } from "./_chunks/cli-sOZfXGua.js";
7
+ import { n as runCli, t as parseArgs } from "./_chunks/cli-DsmlUqPd.js";
8
8
  import { i as vars, r as env } from "./_chunks/env-UqevBSTd.js";
9
9
  export { ConfigNotFoundError, ConfigResourceResolutionError, ConfigValidationError, compileConfig, configSchema, defineConfig as default, defineConfig, durableObject, env, getDurableObjectOptions, loadConfig, loadResolvedConfig, parseArgs, preview, ref, runCli, stringifyConfig, vars, workerName };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devflare",
3
- "version": "1.0.0-next.62",
3
+ "version": "1.0.0-next.63",
4
4
  "description": "Devflare is a developer-first toolkit for Cloudflare Workers that sits on top of Miniflare and Wrangler-compatible config",
5
5
  "repository": {
6
6
  "type": "git",
@@ -84,7 +84,7 @@
84
84
  "test:unit": "bun test tests/unit",
85
85
  "test:coverage": "bun test tests/unit --coverage",
86
86
  "test:integration:control": "bun test tests/integration/cli tests/integration/examples tests/integration/package-entry tests/integration/vite",
87
- "test:integration:bridge": "bun test tests/integration/bridge/bridge-proxy.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/case18-do.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/durable-object.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/do-websocket.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/do-rpc-native.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/do-websocket-hibernation.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/do-websocket-hibernation-test-context.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/miniflare.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/r2-transfer.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/r2-presign.test.ts --parallel=1 --max-concurrency=1",
87
+ "test:integration:bridge": "bun test tests/integration/bridge/bridge-proxy.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/case18-do.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/durable-object.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/do-websocket.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/do-rpc-native.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/do-websocket-hibernation.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/do-websocket-hibernation-test-context.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/do-websocket-app-route.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/miniflare.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/r2-transfer.test.ts --parallel=1 --max-concurrency=1 && bun test tests/integration/bridge/r2-presign.test.ts --parallel=1 --max-concurrency=1",
88
88
  "test:integration:test-context": "bun test tests/integration/test-context --parallel=1 --max-concurrency=1",
89
89
  "test:integration:dev-server": "bun test tests/integration/dev-server --parallel=1 --max-concurrency=1",
90
90
  "test:integration:shims": "bun test tests/integration/shims --parallel=1 --max-concurrency=1",