devflare 1.0.0-next.29 → 1.0.0-next.30

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.
@@ -50,6 +50,7 @@ export declare class BridgeClient {
50
50
  private wsProxies;
51
51
  private pendingWsOpens;
52
52
  private outgoingStreams;
53
+ private eventListeners;
53
54
  private connectPromise;
54
55
  private isConnected;
55
56
  constructor(options?: BridgeClientOptions);
@@ -72,6 +73,18 @@ export declare class BridgeClient {
72
73
  private cleanupPending;
73
74
  /** Call an RPC method */
74
75
  call(method: string, params: unknown[], timeoutMs?: number): Promise<unknown>;
76
+ /**
77
+ * Subscribe to bridge `event` notifications for a topic.
78
+ *
79
+ * Pass `'*'` to receive every event regardless of topic. Returns an
80
+ * unsubscribe function; calling it removes this listener. Subscriptions
81
+ * survive auto-reconnect and are only dropped on an explicit disconnect().
82
+ *
83
+ * NOTE: no gateway currently emits `event` frames, so listeners will not
84
+ * fire until an event producer is wired on the gateway side. The subscriber
85
+ * surface is provided so consumers can register ahead of that work.
86
+ */
87
+ on(topic: string, cb: (data: unknown) => void): () => void;
75
88
  /** Create a proxied WebSocket to a Durable Object */
76
89
  createWsProxy(binding: string, id: string, url: string, headers?: [string, string][]): Promise<{
77
90
  wid: number;
@@ -90,6 +103,7 @@ export declare class BridgeClient {
90
103
  */
91
104
  private handleV2BinaryFrame;
92
105
  private handleEvent;
106
+ private dispatchEvent;
93
107
  private handleStreamPull;
94
108
  private pumpStream;
95
109
  private handleStreamChunk;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/bridge/client.ts"],"names":[],"mappings":"AAqEA,KAAK,oBAAoB,GAAG,KAAK,GAAG,EAAE,MAAM,KAAK,SAAS,CAAA;AA6C1D,wBAAsB,iCAAiC,CACtD,gBAAgB,GAAE,OAA8B,GAC9C,OAAO,CAAC,oBAAoB,CAAC,CAK/B;AAMD,MAAM,WAAW,mBAAmB;IACnC,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,mCAAmC;IACnC,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,4BAA4B;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,+BAA+B;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACjC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAC9B,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,YAAY;IAC5B,UAAU,EAAE,+BAA+B,CAAC,UAAU,CAAC,CAAA;IACvD,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,eAAe,EAAE,MAAM,CAAA;IACvB,0DAA0D;IAC1D,WAAW,EAAE;QACZ,OAAO,EAAE,MAAM,IAAI,CAAA;QACnB,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;KAC9B,GAAG,IAAI,CAAA;IACR,kEAAkE;IAClE,KAAK,EAAE,OAAO,CAAA;IACd,8CAA8C;IAC9C,MAAM,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,KAAK,IAAI,CAAA;IAC9C,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CACjD;AAED,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CAC9B;AAMD,qBAAa,YAAY;IACxB,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,GAAG,CAAQ;IACnB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,cAAc,CAAQ;IAE9B,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,cAAc,CAAmC;IACzD,OAAO,CAAC,eAAe,CAA+B;IAEtD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,WAAW,CAAQ;IAE3B,YAAY,OAAO,GAAE,mBAAwB,EAK5C;IAED,4BAA4B;IAC5B,MAAM,IAAI,MAAM,CAEf;IAED,6CAA6C;IAC7C,UAAU,IAAI,MAAM,CAGnB;IAMD,4BAA4B;IACtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAgB7B;YAEa,iCAAiC;IAK/C,OAAO,CAAC,cAAc;IA4DtB,iEAAiE;IACjE,UAAU,IAAI,IAAI,CAYjB;IAED,6BAA6B;IAC7B,KAAK,IAAI,IAAI,CAEZ;IAED,yBAAyB;IACzB,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,OAAO,CAAC,gBAAgB;IAmBxB,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAwCtB,yBAAyB;IACnB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,SAAS,SAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAuCjF;IAMD,qDAAqD;IAC/C,aAAa,CAClB,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAC1B,OAAO,CAAC;QACV,GAAG,EAAE,MAAM,CAAA;QACX,IAAI,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,KAAK,IAAI,CAAA;QACzC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;QAC/C,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,KAAK,IAAI,KAAK,IAAI,CAAA;QACjE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAA;KACpE,CAAC,CAuDD;IAMD,0DAA0D;IAC1D,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAqE5D;IASD,OAAO,CAAC,iBAAiB;IA6BzB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,gBAAgB;YAQV,UAAU;IAyCxB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,iBAAiB;IAmBzB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,cAAc;YAWR,eAAe;IAM7B,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,UAAU;CAOlB;AAQD,8CAA8C;AAC9C,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,YAAY,CAKrE;AAED,6CAA6C;AAC7C,wBAAgB,WAAW,IAAI,IAAI,CAGlC"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/bridge/client.ts"],"names":[],"mappings":"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"}
@@ -4,5 +4,5 @@
4
4
  * module. All symbols are declared with `function`/`const` so they are
5
5
  * hoisted in both embedding sites.
6
6
  */
7
- export declare const GATEWAY_RUNTIME_JS = "\nconst RAW_EMAIL = 'EmailMessage::raw'\n\nfunction arrayBufferToBase64(buffer) {\n\tconst bytes = new Uint8Array(buffer)\n\tlet binary = ''\n\tfor (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i])\n\treturn btoa(binary)\n}\n\nfunction base64ToArrayBuffer(base64) {\n\tconst binary = atob(base64)\n\tconst bytes = new Uint8Array(binary.length)\n\tfor (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n\treturn bytes.buffer\n}\n\nfunction serializeR2Object(obj) {\n\tif (!obj) return null\n\treturn {\n\t\t__type: 'R2Object',\n\t\tkey: obj.key,\n\t\tversion: obj.version,\n\t\tsize: obj.size,\n\t\tetag: obj.etag,\n\t\thttpEtag: obj.httpEtag,\n\t\tchecksums: obj.checksums,\n\t\tuploaded: obj.uploaded?.toISOString(),\n\t\thttpMetadata: obj.httpMetadata,\n\t\tcustomMetadata: obj.customMetadata,\n\t\trange: obj.range,\n\t\tstorageClass: obj.storageClass\n\t}\n}\n\nfunction serializeR2ObjectBody(obj, bodyData) {\n\tif (!obj) return null\n\treturn {\n\t\t__type: 'R2ObjectBody',\n\t\tkey: obj.key,\n\t\tversion: obj.version,\n\t\tsize: obj.size,\n\t\tetag: obj.etag,\n\t\thttpEtag: obj.httpEtag,\n\t\tchecksums: obj.checksums,\n\t\tuploaded: obj.uploaded?.toISOString(),\n\t\thttpMetadata: obj.httpMetadata,\n\t\tcustomMetadata: obj.customMetadata,\n\t\trange: obj.range,\n\t\tstorageClass: obj.storageClass,\n\t\tbodyData\n\t}\n}\n\nfunction serializeR2Objects(result) {\n\tif (!result) return null\n\treturn {\n\t\tobjects: result.objects.map(serializeR2Object),\n\t\ttruncated: result.truncated,\n\t\tcursor: result.cursor,\n\t\tdelimitedPrefixes: result.delimitedPrefixes\n\t}\n}\n\nasync function serializeResponse(response) {\n\tlet body = null\n\tif (response.body) {\n\t\tconst bytes = await response.arrayBuffer()\n\t\tif (bytes.byteLength > 0) {\n\t\t\tbody = { type: 'bytes', data: arrayBufferToBase64(bytes) }\n\t\t}\n\t}\n\treturn {\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText,\n\t\theaders: [...response.headers.entries()],\n\t\tbody\n\t}\n}\n\nfunction deserializeRequest(serializedReq) {\n\treturn new Request(serializedReq.url, {\n\t\tmethod: serializedReq.method,\n\t\theaders: serializedReq.headers,\n\t\tbody: serializedReq.body?.type === 'bytes'\n\t\t\t? base64ToArrayBuffer(serializedReq.body.data)\n\t\t\t: undefined,\n\t\tredirect: serializedReq.redirect\n\t})\n}\n\nfunction createEmailMessageRaw(raw) {\n\tif (typeof raw === 'string' || raw instanceof ReadableStream) {\n\t\treturn raw\n\t}\n\tif (raw instanceof ArrayBuffer || raw instanceof Uint8Array) {\n\t\treturn new Response(raw).body\n\t}\n\tthrow new Error('Unsupported EmailMessage raw payload')\n}\n\nfunction isDurableObjectNamespace(binding) {\n\treturn !!binding\n\t\t&& typeof binding.idFromName === 'function'\n\t\t&& typeof binding.idFromString === 'function'\n\t\t&& typeof binding.newUniqueId === 'function'\n}\n\n/**\n * Execute an RPC method against the gateway's bindings.\n *\n * Method format: \"binding.operation\". Operations must be namespaced by\n * binding kind (e.g. \"kv.get\", \"r2.head\", \"d1.stmt.first\", \"do.fetch\",\n * \"service.fetch\", \"queue.send\", \"email.send\", \"ai.run\"). Bare verbs and the legacy\n * \"stmt.*\" / \"stub.*\" sub-prefixes were removed in B3-final and now throw.\n * Method vocabulary must stay in sync with the canonical server in\n * src/bridge/server.ts.\n */\nasync function executeRpcMethod(method, params, env, _ctx) {\n\tconst parts = method.split('.')\n\tif (parts.length < 2) throw new Error('Invalid method format: ' + method)\n\n\tconst bindingName = parts[0]\n\tconst operation = parts.slice(1).join('.')\n\tconst binding = env[bindingName]\n\n\tif (!binding) throw new Error('Binding not found: ' + bindingName)\n\n\tconst isNamespaced =\n\t\toperation.indexOf('kv.') === 0 ||\n\t\toperation.indexOf('r2.') === 0 ||\n\t\toperation.indexOf('d1.') === 0 ||\n\t\toperation.indexOf('do.') === 0 ||\n\t\toperation.indexOf('service.') === 0 ||\n\t\toperation.indexOf('queue.') === 0 ||\n\t\toperation.indexOf('email.') === 0 ||\n\t\toperation.indexOf('ai.') === 0 ||\n\t\toperation.indexOf('workflow.') === 0 ||\n\t\toperation.indexOf('var.') === 0\n\tif (!isNamespaced) {\n\t\tthrow new Error(createUnsupportedBridgeOperationErrorMessage(bindingName, operation))\n\t}\n\n\t// KV\n\tif (operation === 'kv.get') return binding.get(params[0], params[1])\n\tif (operation === 'kv.put') return binding.put(params[0], params[1], params[2])\n\tif (operation === 'kv.delete') return binding.delete(params[0])\n\tif (operation === 'kv.list') return binding.list(params[0])\n\tif (operation === 'kv.getWithMetadata') return binding.getWithMetadata(params[0], params[1])\n\n\t// DO get (returns DOStub reference)\n\tif (operation === 'do.get') {\n\t\treturn { __type: 'DOStub', binding: bindingName, id: params[0] }\n\t}\n\n\t// R2\n\tif (operation === 'r2.head') return serializeR2Object(await binding.head(params[0]))\n\tif (operation === 'r2.get') {\n\t\tconst obj = await binding.get(params[0], params[1])\n\t\tif (!obj) return null\n\t\tconst body = await obj.arrayBuffer()\n\t\treturn serializeR2ObjectBody(obj, arrayBufferToBase64(body))\n\t}\n\tif (operation === 'r2.put') {\n\t\tlet value = params[1]\n\t\tif (value && typeof value === 'object') {\n\t\t\tif (value.__type === 'ArrayBuffer' || value.__type === 'Uint8Array') {\n\t\t\t\tvalue = base64ToArrayBuffer(value.data)\n\t\t\t}\n\t\t}\n\t\treturn serializeR2Object(await binding.put(params[0], value, params[2]))\n\t}\n\tif (operation === 'r2.delete') return binding.delete(params[0])\n\tif (operation === 'r2.list') return serializeR2Objects(await binding.list(params[0]))\n\n\t// D1\n\tif (operation === 'd1.exec') return binding.exec(params[0])\n\tif (operation === 'd1.batch') {\n\t\tconst statements = params[0].map((s) => binding.prepare(s.sql).bind(...(s.bindings || [])))\n\t\treturn binding.batch(statements)\n\t}\n\tif (operation.indexOf('d1.stmt.') === 0) {\n\t\tconst mode = operation.split('.')[2]\n\t\tconst [sql, ...rest] = params\n\t\tlet bindings = rest\n\t\tlet extraParam\n\t\tif (mode === 'first' || mode === 'raw') {\n\t\t\textraParam = rest[rest.length - 1]\n\t\t\tbindings = rest.slice(0, -1)\n\t\t}\n\t\tlet stmt = binding.prepare(sql)\n\t\tif (bindings.length > 0) stmt = stmt.bind(...bindings)\n\t\tif (mode === 'first') {\n\t\t\tif (typeof extraParam === 'string' && extraParam.length > 0) return stmt.first(extraParam)\n\t\t\treturn stmt.first()\n\t\t}\n\t\tif (mode === 'all') return stmt.all()\n\t\tif (mode === 'run') return stmt.run()\n\t\tif (mode === 'raw') return stmt.raw(extraParam)\n\t\tthrow new Error('Unknown stmt mode: ' + mode)\n\t}\n\n\t// Durable Objects\n\tif (operation === 'do.idFromName') {\n\t\tconst id = binding.idFromName(params[0])\n\t\treturn { __type: 'DOId', hex: id.toString() }\n\t}\n\tif (operation === 'do.idFromString') {\n\t\tconst id = binding.idFromString(params[0])\n\t\treturn { __type: 'DOId', hex: id.toString() }\n\t}\n\tif (operation === 'do.newUniqueId') {\n\t\tconst id = binding.newUniqueId(params[0])\n\t\treturn { __type: 'DOId', hex: id.toString() }\n\t}\n\tif (operation === 'do.fetch') {\n\t\tconst [, serializedId, serializedReq] = params\n\t\tconst id = binding.idFromString(serializedId.hex)\n\t\tconst stub = binding.get(id)\n\t\tconst response = await stub.fetch(new Request(serializedReq.url, {\n\t\t\tmethod: serializedReq.method,\n\t\t\theaders: serializedReq.headers,\n\t\t\tbody: serializedReq.body?.type === 'bytes'\n\t\t\t\t? base64ToArrayBuffer(serializedReq.body.data)\n\t\t\t\t: undefined\n\t\t}))\n\t\treturn serializeResponse(response)\n\t}\n\tif (operation === 'do.rpc') {\n\t\tconst [, serializedId, methodName, args] = params\n\t\tconst id = binding.idFromString(serializedId.hex)\n\t\tconst stub = binding.get(id)\n\t\tconst response = await stub.fetch(new Request('http://do/_rpc', {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\tbody: JSON.stringify({ method: methodName, params: args })\n\t\t}))\n\t\tconst result = await response.json()\n\t\tif (!result.ok) throw new Error(result.error?.message || 'RPC failed')\n\t\treturn result.result\n\t}\n\n\t// Service Bindings\n\tif (operation === 'service.fetch') {\n\t\tif (!binding || typeof binding.fetch !== 'function') {\n\t\t\tthrow new Error('Service binding ' + bindingName + ' does not support fetch()')\n\t\t}\n\t\tconst response = await binding.fetch(deserializeRequest(params[0]))\n\t\treturn serializeResponse(response)\n\t}\n\tif (operation === 'service.rpc') {\n\t\tconst methodName = params[0]\n\t\tif (typeof methodName !== 'string') {\n\t\t\tthrow new Error('Service binding ' + bindingName + ' RPC method name must be a string')\n\t\t}\n\t\tconst args = Array.isArray(params[1]) ? params[1] : []\n\t\tconst method = binding && binding[methodName]\n\t\tif (typeof method !== 'function') {\n\t\t\tthrow new Error('Service binding ' + bindingName + ' does not support ' + methodName + '()')\n\t\t}\n\t\treturn method.apply(binding, args)\n\t}\n\n\t// Queues\n\tif (operation === 'queue.send') return binding.send(params[0], params[1])\n\tif (operation === 'queue.sendBatch') return binding.sendBatch(params[0], params[1])\n\n\t// Send Email\n\tif (operation === 'email.send') {\n\t\tif (binding && typeof binding.send === 'function') {\n\t\t\tconst message = params[0]\n\t\t\tif (message && typeof message === 'object' && 'from' in message && 'to' in message && 'raw' in message) {\n\t\t\t\treturn binding.send({\n\t\t\t\t\tfrom: message.from,\n\t\t\t\t\tto: message.to,\n\t\t\t\t\t[RAW_EMAIL]: createEmailMessageRaw(message.raw)\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn binding.send(message)\n\t\t}\n\t\treturn { ok: true, simulated: true }\n\t}\n\n\t// Workflows\n\tif (operation === 'workflow.create') {\n\t\treturn serializeWorkflowInstance(await binding.create(params[0]))\n\t}\n\tif (operation === 'workflow.get') {\n\t\treturn serializeWorkflowInstance(await binding.get(params[0]))\n\t}\n\tif (operation === 'workflow.status') {\n\t\treturn (await binding.get(params[0])).status()\n\t}\n\tif (operation === 'workflow.pause') {\n\t\treturn (await binding.get(params[0])).pause()\n\t}\n\tif (operation === 'workflow.resume') {\n\t\treturn (await binding.get(params[0])).resume()\n\t}\n\tif (operation === 'workflow.terminate') {\n\t\treturn (await binding.get(params[0])).terminate()\n\t}\n\tif (operation === 'workflow.restart') {\n\t\treturn (await binding.get(params[0])).restart()\n\t}\n\tif (operation === 'workflow.sendEvent') {\n\t\treturn (await binding.get(params[0])).sendEvent(params[1])\n\t}\n\n\t// AI / generic run()\n\tif (operation === 'ai.run') {\n\t\tif (typeof binding.run !== 'function') {\n\t\t\tthrow new Error('Binding ' + bindingName + ' does not support run(): ' + method)\n\t\t}\n\t\treturn binding.run(params[0], params[1])\n\t}\n\n\tthrow new Error('Unknown operation: ' + method)\n}\n\nfunction createUnsupportedBridgeOperationErrorMessage(bindingName, operation) {\n\tconst base = \"[devflare][bridge] Unsupported bridge operation '\" + operation + \"' for binding '\" + bindingName + \"'.\"\n\tif (operation === 'fetch') {\n\t\treturn base + ' Devflare could not dispatch fetch() for this binding through the local bridge. '\n\t\t\t+ 'Expected Cloudflare API: env.' + bindingName + '.fetch(request). '\n\t\t\t+ 'If this came from SvelteKit platform.env, make sure the binding is declared as a service binding; '\n\t\t\t+ 'this is a Devflare local bridge issue when service bindings fall back to a bare fetch operation.'\n\t}\n\tif (operation === 'toString') {\n\t\treturn base + ' A platform.env value was coerced to a string through the bridge. '\n\t\t\t+ 'For SvelteKit local dev, declared vars should be plain string values and missing env names should read as undefined.'\n\t}\n\treturn base + ' Bare verbs and the legacy stmt.*/stub.* sub-prefixes are not supported; '\n\t\t+ 'use the namespaced form (e.g. kv.get, r2.put, d1.stmt.first, do.fetch, service.fetch).'\n}\n\nfunction serializeWorkflowInstance(instance) {\n\treturn {\n\t\t__type: 'WorkflowInstance',\n\t\tid: instance.id\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// WebSocket bridge (shared with src/bridge/server.ts in shape)\n// ---------------------------------------------------------------------------\n// NOTE: wsProxies is intentionally created per handleBridgeWebSocket call so\n// state never leaks across connections or across gateway-script regenerations.\n\nasync function handleBridgeRpcCall(msg, ws, env, ctx) {\n\ttry {\n\t\tconst result = await executeRpcMethod(msg.method, msg.params, env, ctx)\n\t\tws.send(JSON.stringify({ t: 'rpc.ok', id: msg.id, result }))\n\t} catch (error) {\n\t\tws.send(JSON.stringify({\n\t\t\tt: 'rpc.err',\n\t\t\tid: msg.id,\n\t\t\terror: {\n\t\t\t\tcode: error?.code || 'INTERNAL_ERROR',\n\t\t\t\tmessage: error?.message || String(error)\n\t\t\t}\n\t\t}))\n\t}\n}\n\nasync function handleBridgeWsOpen(msg, ws, env, wsProxies) {\n\ttry {\n\t\tconst binding = env[msg.target.binding]\n\t\tconst id = binding.idFromString(msg.target.id)\n\t\tconst stub = binding.get(id)\n\n\t\tconst headers = new Headers(msg.target.headers || [])\n\t\theaders.set('Upgrade', 'websocket')\n\n\t\tconst response = await stub.fetch(new Request(msg.target.url, { method: 'GET', headers }))\n\t\tconst doWs = response.webSocket\n\n\t\tif (!doWs) {\n\t\t\tws.send(JSON.stringify({\n\t\t\t\tt: 'rpc.err',\n\t\t\t\tid: 'ws_' + msg.wid,\n\t\t\t\terror: { code: 'WS_FAILED', message: 'No WebSocket returned' }\n\t\t\t}))\n\t\t\treturn\n\t\t}\n\n\t\tdoWs.accept()\n\t\twsProxies.set(msg.wid, { doWs })\n\n\t\tdoWs.addEventListener('message', (event) => {\n\t\t\tconst isText = typeof event.data === 'string'\n\t\t\tconst data = isText ? event.data : arrayBufferToBase64(event.data)\n\t\t\tws.send(JSON.stringify({ t: 'ws.data', wid: msg.wid, data, isText }))\n\t\t})\n\n\t\tdoWs.addEventListener('close', (event) => {\n\t\t\tws.send(JSON.stringify({ t: 'ws.close', wid: msg.wid, code: event.code, reason: event.reason }))\n\t\t\twsProxies.delete(msg.wid)\n\t\t})\n\n\t\tws.send(JSON.stringify({ t: 'ws.opened', wid: msg.wid }))\n\t} catch (error) {\n\t\tws.send(JSON.stringify({\n\t\t\tt: 'rpc.err',\n\t\t\tid: 'ws_' + msg.wid,\n\t\t\terror: { code: 'WS_FAILED', message: error.message }\n\t\t}))\n\t}\n}\n\nfunction handleBridgeWsClose(msg, wsProxies) {\n\tconst proxy = wsProxies.get(msg.wid)\n\tif (proxy) {\n\t\tproxy.doWs.close(msg.code, msg.reason)\n\t\twsProxies.delete(msg.wid)\n\t}\n}\n\nasync function handleBridgeJsonMessage(data, ws, env, ctx, wsProxies) {\n\tconst msg = JSON.parse(data)\n\tswitch (msg.t) {\n\t\tcase 'hello':\n\t\t\t// v2 handshake \u2014 acknowledge with welcome echoing the negotiated\n\t\t\t// capability intersection. Capabilities advertised by the gateway\n\t\t\t// are kept in sync with src/bridge/client.ts (BRIDGE_CLIENT_CAPABILITIES).\n\t\t\tws.send(JSON.stringify({\n\t\t\t\tt: 'welcome',\n\t\t\t\tprotocolVersion: 2,\n\t\t\t\tcapabilities: ['streams', 'ws-relay', 'http-transfer']\n\t\t\t\t\t.filter((c) => Array.isArray(msg.capabilities) && msg.capabilities.includes(c))\n\t\t\t\t\t.sort()\n\t\t\t}))\n\t\t\tbreak\n\t\tcase 'rpc.call':\n\t\t\tawait handleBridgeRpcCall(msg, ws, env, ctx)\n\t\t\tbreak\n\t\tcase 'ws.open':\n\t\t\tawait handleBridgeWsOpen(msg, ws, env, wsProxies)\n\t\t\tbreak\n\t\tcase 'ws.close':\n\t\t\thandleBridgeWsClose(msg, wsProxies)\n\t\t\tbreak\n\t}\n}\n\nfunction handleBridgeWebSocket(request, env, ctx) {\n\tconst { 0: client, 1: server } = new WebSocketPair()\n\tserver.accept()\n\n\t// Per-connection state: recreated for every bridge client so reloads and\n\t// concurrent clients never share WS proxy entries.\n\tconst wsProxies = new Map()\n\n\tserver.addEventListener('message', async (event) => {\n\t\ttry {\n\t\t\tif (typeof event.data === 'string') {\n\t\t\t\tawait handleBridgeJsonMessage(event.data, server, env, ctx, wsProxies)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error('[Gateway] Error:', error)\n\t\t}\n\t})\n\n\tserver.addEventListener('close', () => {\n\t\tfor (const proxy of wsProxies.values()) {\n\t\t\t// Best-effort cleanup: the DO-side WS may already be closed or in an\n\t\t\t// invalid state; any throw here would abort sibling closes. Surface\n\t\t\t// the swallowed error when DEVFLARE_DEBUG_BRIDGE is enabled.\n\t\t\ttry { proxy.doWs.close() } catch (error) {\n\t\t\t\tif (globalThis.DEVFLARE_DEBUG_BRIDGE) {\n\t\t\t\t\tconsole.warn('[devflare:bridge] proxy.doWs.close() failed', error)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\twsProxies.clear()\n\t})\n\n\treturn new Response(null, { status: 101, webSocket: client })\n}\n\n// ---------------------------------------------------------------------------\n// HTTP transfer for R2 bodies (shared with src/bridge/server.ts in shape)\n// ---------------------------------------------------------------------------\n\nasync function handleHttpTransfer(request, env, url) {\n\tconst transferIdEncoded = url.pathname.split('/').pop()\n\tconst transferId = decodeURIComponent(transferIdEncoded || '')\n\tconst [binding, ...keyParts] = transferId.split(':')\n\tconst key = keyParts.join(':')\n\tconst bucket = env[binding]\n\n\tif (!bucket) return new Response('Bucket not found: ' + binding, { status: 404 })\n\n\tif (request.method === 'PUT' || request.method === 'POST') {\n\t\tconst result = await bucket.put(key, request.body)\n\t\treturn new Response(JSON.stringify(serializeR2Object(result)), {\n\t\t\theaders: { 'Content-Type': 'application/json' }\n\t\t})\n\t}\n\n\tif (request.method === 'GET') {\n\t\tconst object = await bucket.get(key)\n\t\tif (!object) return new Response('Not found', { status: 404 })\n\t\treturn new Response(object.body, {\n\t\t\theaders: {\n\t\t\t\t'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream',\n\t\t\t\t'Content-Length': String(object.size)\n\t\t\t}\n\t\t})\n\t}\n\n\treturn new Response('Method not allowed', { status: 405 })\n}\n";
7
+ export declare const GATEWAY_RUNTIME_JS = "\nconst RAW_EMAIL = 'EmailMessage::raw'\n\nfunction arrayBufferToBase64(buffer) {\n\tconst bytes = new Uint8Array(buffer)\n\tlet binary = ''\n\tfor (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i])\n\treturn btoa(binary)\n}\n\nfunction base64ToArrayBuffer(base64) {\n\tconst binary = atob(base64)\n\tconst bytes = new Uint8Array(binary.length)\n\tfor (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n\treturn bytes.buffer\n}\n\nfunction serializeR2Object(obj) {\n\tif (!obj) return null\n\treturn {\n\t\t__type: 'R2Object',\n\t\tkey: obj.key,\n\t\tversion: obj.version,\n\t\tsize: obj.size,\n\t\tetag: obj.etag,\n\t\thttpEtag: obj.httpEtag,\n\t\tchecksums: obj.checksums,\n\t\tuploaded: obj.uploaded?.toISOString(),\n\t\thttpMetadata: obj.httpMetadata,\n\t\tcustomMetadata: obj.customMetadata,\n\t\trange: obj.range,\n\t\tstorageClass: obj.storageClass\n\t}\n}\n\nfunction serializeR2ObjectBody(obj, bodyData) {\n\tif (!obj) return null\n\treturn {\n\t\t__type: 'R2ObjectBody',\n\t\tkey: obj.key,\n\t\tversion: obj.version,\n\t\tsize: obj.size,\n\t\tetag: obj.etag,\n\t\thttpEtag: obj.httpEtag,\n\t\tchecksums: obj.checksums,\n\t\tuploaded: obj.uploaded?.toISOString(),\n\t\thttpMetadata: obj.httpMetadata,\n\t\tcustomMetadata: obj.customMetadata,\n\t\trange: obj.range,\n\t\tstorageClass: obj.storageClass,\n\t\tbodyData\n\t}\n}\n\nfunction serializeR2Objects(result) {\n\tif (!result) return null\n\treturn {\n\t\tobjects: result.objects.map(serializeR2Object),\n\t\ttruncated: result.truncated,\n\t\tcursor: result.cursor,\n\t\tdelimitedPrefixes: result.delimitedPrefixes\n\t}\n}\n\nasync function serializeResponse(response) {\n\tlet body = null\n\tif (response.body) {\n\t\tconst bytes = await response.arrayBuffer()\n\t\tif (bytes.byteLength > 0) {\n\t\t\tbody = { type: 'bytes', data: arrayBufferToBase64(bytes) }\n\t\t}\n\t}\n\treturn {\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText,\n\t\theaders: [...response.headers.entries()],\n\t\tbody\n\t}\n}\n\nfunction deserializeRequest(serializedReq) {\n\treturn new Request(serializedReq.url, {\n\t\tmethod: serializedReq.method,\n\t\theaders: serializedReq.headers,\n\t\tbody: serializedReq.body?.type === 'bytes'\n\t\t\t? base64ToArrayBuffer(serializedReq.body.data)\n\t\t\t: undefined,\n\t\tredirect: serializedReq.redirect\n\t})\n}\n\nfunction createEmailMessageRaw(raw) {\n\tif (typeof raw === 'string' || raw instanceof ReadableStream) {\n\t\treturn raw\n\t}\n\tif (raw instanceof ArrayBuffer || raw instanceof Uint8Array) {\n\t\treturn new Response(raw).body\n\t}\n\tthrow new Error('Unsupported EmailMessage raw payload')\n}\n\nfunction isDurableObjectNamespace(binding) {\n\treturn !!binding\n\t\t&& typeof binding.idFromName === 'function'\n\t\t&& typeof binding.idFromString === 'function'\n\t\t&& typeof binding.newUniqueId === 'function'\n}\n\n/**\n * Resolve a (possibly jurisdiction-scoped) DurableObjectNamespace.\n * Forwards the jurisdiction faithfully when the binding supports it\n * (real Cloudflare), and degrades to the plain binding otherwise\n * (miniflare/workerd local emulation, which does not pin jurisdictions).\n */\nfunction resolveDoNamespace(binding, jurisdiction) {\n\tif (jurisdiction && typeof binding.jurisdiction === 'function') {\n\t\treturn binding.jurisdiction(jurisdiction)\n\t}\n\treturn binding\n}\n\n/**\n * Execute an RPC method against the gateway's bindings.\n *\n * Method format: \"binding.operation\". Operations must be namespaced by\n * binding kind (e.g. \"kv.get\", \"r2.head\", \"d1.stmt.first\", \"do.fetch\",\n * \"service.fetch\", \"queue.send\", \"email.send\", \"ai.run\"). Bare verbs and the legacy\n * \"stmt.*\" / \"stub.*\" sub-prefixes were removed in B3-final and now throw.\n * Method vocabulary must stay in sync with the canonical server in\n * src/bridge/server.ts.\n */\nasync function executeRpcMethod(method, params, env, _ctx) {\n\tconst parts = method.split('.')\n\tif (parts.length < 2) throw new Error('Invalid method format: ' + method)\n\n\tconst bindingName = parts[0]\n\tconst operation = parts.slice(1).join('.')\n\tconst binding = env[bindingName]\n\n\tif (!binding) throw new Error('Binding not found: ' + bindingName)\n\n\tconst isNamespaced =\n\t\toperation.indexOf('kv.') === 0 ||\n\t\toperation.indexOf('r2.') === 0 ||\n\t\toperation.indexOf('d1.') === 0 ||\n\t\toperation.indexOf('do.') === 0 ||\n\t\toperation.indexOf('service.') === 0 ||\n\t\toperation.indexOf('queue.') === 0 ||\n\t\toperation.indexOf('email.') === 0 ||\n\t\toperation.indexOf('ai.') === 0 ||\n\t\toperation.indexOf('workflow.') === 0 ||\n\t\toperation.indexOf('var.') === 0\n\tif (!isNamespaced) {\n\t\tthrow new Error(createUnsupportedBridgeOperationErrorMessage(bindingName, operation))\n\t}\n\n\t// KV\n\tif (operation === 'kv.get') return binding.get(params[0], params[1])\n\tif (operation === 'kv.put') return binding.put(params[0], params[1], params[2])\n\tif (operation === 'kv.delete') return binding.delete(params[0])\n\tif (operation === 'kv.list') return binding.list(params[0])\n\tif (operation === 'kv.getWithMetadata') return binding.getWithMetadata(params[0], params[1])\n\n\t// DO get (returns DOStub reference)\n\tif (operation === 'do.get') {\n\t\treturn { __type: 'DOStub', binding: bindingName, id: params[0] }\n\t}\n\n\t// R2\n\tif (operation === 'r2.head') return serializeR2Object(await binding.head(params[0]))\n\tif (operation === 'r2.get') {\n\t\tconst obj = await binding.get(params[0], params[1])\n\t\tif (!obj) return null\n\t\tconst body = await obj.arrayBuffer()\n\t\treturn serializeR2ObjectBody(obj, arrayBufferToBase64(body))\n\t}\n\tif (operation === 'r2.put') {\n\t\tlet value = params[1]\n\t\tif (value && typeof value === 'object') {\n\t\t\tif (value.__type === 'ArrayBuffer' || value.__type === 'Uint8Array') {\n\t\t\t\tvalue = base64ToArrayBuffer(value.data)\n\t\t\t}\n\t\t}\n\t\treturn serializeR2Object(await binding.put(params[0], value, params[2]))\n\t}\n\tif (operation === 'r2.delete') return binding.delete(params[0])\n\tif (operation === 'r2.list') return serializeR2Objects(await binding.list(params[0]))\n\n\t// D1\n\tif (operation === 'd1.exec') return binding.exec(params[0])\n\tif (operation === 'd1.batch') {\n\t\tconst statements = params[0].map((s) => binding.prepare(s.sql).bind(...(s.bindings || [])))\n\t\treturn binding.batch(statements)\n\t}\n\tif (operation.indexOf('d1.stmt.') === 0) {\n\t\tconst mode = operation.split('.')[2]\n\t\tconst [sql, ...rest] = params\n\t\tlet bindings = rest\n\t\tlet extraParam\n\t\tif (mode === 'first' || mode === 'raw') {\n\t\t\textraParam = rest[rest.length - 1]\n\t\t\tbindings = rest.slice(0, -1)\n\t\t}\n\t\tlet stmt = binding.prepare(sql)\n\t\tif (bindings.length > 0) stmt = stmt.bind(...bindings)\n\t\tif (mode === 'first') {\n\t\t\tif (typeof extraParam === 'string' && extraParam.length > 0) return stmt.first(extraParam)\n\t\t\treturn stmt.first()\n\t\t}\n\t\tif (mode === 'all') return stmt.all()\n\t\tif (mode === 'run') return stmt.run()\n\t\tif (mode === 'raw') return stmt.raw(extraParam)\n\t\tthrow new Error('Unknown stmt mode: ' + mode)\n\t}\n\n\t// Durable Objects\n\tif (operation === 'do.idFromName') {\n\t\tconst ns = resolveDoNamespace(binding, params[1])\n\t\tconst id = ns.idFromName(params[0])\n\t\treturn { __type: 'DOId', hex: id.toString() }\n\t}\n\tif (operation === 'do.idFromString') {\n\t\tconst id = binding.idFromString(params[0])\n\t\treturn { __type: 'DOId', hex: id.toString() }\n\t}\n\tif (operation === 'do.newUniqueId') {\n\t\tconst ns = resolveDoNamespace(binding, params[1])\n\t\tconst id = ns.newUniqueId(params[0])\n\t\treturn { __type: 'DOId', hex: id.toString() }\n\t}\n\tif (operation === 'do.fetch') {\n\t\tconst [, serializedId, serializedReq] = params\n\t\tconst id = binding.idFromString(serializedId.hex)\n\t\tconst stub = binding.get(id)\n\t\tconst response = await stub.fetch(new Request(serializedReq.url, {\n\t\t\tmethod: serializedReq.method,\n\t\t\theaders: serializedReq.headers,\n\t\t\tbody: serializedReq.body?.type === 'bytes'\n\t\t\t\t? base64ToArrayBuffer(serializedReq.body.data)\n\t\t\t\t: undefined\n\t\t}))\n\t\treturn serializeResponse(response)\n\t}\n\tif (operation === 'do.rpc') {\n\t\tconst [, serializedId, methodName, args] = params\n\t\tconst id = binding.idFromString(serializedId.hex)\n\t\tconst stub = binding.get(id)\n\t\tconst response = await stub.fetch(new Request('http://do/_rpc', {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\tbody: JSON.stringify({ method: methodName, params: args })\n\t\t}))\n\t\tconst result = await response.json()\n\t\tif (!result.ok) throw new Error(result.error?.message || 'RPC failed')\n\t\treturn result.result\n\t}\n\n\t// Service Bindings\n\tif (operation === 'service.fetch') {\n\t\tif (!binding || typeof binding.fetch !== 'function') {\n\t\t\tthrow new Error('Service binding ' + bindingName + ' does not support fetch()')\n\t\t}\n\t\tconst response = await binding.fetch(deserializeRequest(params[0]))\n\t\treturn serializeResponse(response)\n\t}\n\tif (operation === 'service.rpc') {\n\t\tconst methodName = params[0]\n\t\tif (typeof methodName !== 'string') {\n\t\t\tthrow new Error('Service binding ' + bindingName + ' RPC method name must be a string')\n\t\t}\n\t\tconst args = Array.isArray(params[1]) ? params[1] : []\n\t\tconst method = binding && binding[methodName]\n\t\tif (typeof method !== 'function') {\n\t\t\tthrow new Error('Service binding ' + bindingName + ' does not support ' + methodName + '()')\n\t\t}\n\t\treturn method.apply(binding, args)\n\t}\n\n\t// Queues\n\tif (operation === 'queue.send') return binding.send(params[0], params[1])\n\tif (operation === 'queue.sendBatch') return binding.sendBatch(params[0], params[1])\n\n\t// Send Email\n\tif (operation === 'email.send') {\n\t\tif (binding && typeof binding.send === 'function') {\n\t\t\tconst message = params[0]\n\t\t\tif (message && typeof message === 'object' && 'from' in message && 'to' in message && 'raw' in message) {\n\t\t\t\treturn binding.send({\n\t\t\t\t\tfrom: message.from,\n\t\t\t\t\tto: message.to,\n\t\t\t\t\t[RAW_EMAIL]: createEmailMessageRaw(message.raw)\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn binding.send(message)\n\t\t}\n\t\treturn { ok: true, simulated: true }\n\t}\n\n\t// Workflows\n\tif (operation === 'workflow.create') {\n\t\treturn serializeWorkflowInstance(await binding.create(params[0]))\n\t}\n\tif (operation === 'workflow.get') {\n\t\treturn serializeWorkflowInstance(await binding.get(params[0]))\n\t}\n\tif (operation === 'workflow.status') {\n\t\treturn (await binding.get(params[0])).status()\n\t}\n\tif (operation === 'workflow.pause') {\n\t\treturn (await binding.get(params[0])).pause()\n\t}\n\tif (operation === 'workflow.resume') {\n\t\treturn (await binding.get(params[0])).resume()\n\t}\n\tif (operation === 'workflow.terminate') {\n\t\treturn (await binding.get(params[0])).terminate()\n\t}\n\tif (operation === 'workflow.restart') {\n\t\treturn (await binding.get(params[0])).restart()\n\t}\n\tif (operation === 'workflow.sendEvent') {\n\t\treturn (await binding.get(params[0])).sendEvent(params[1])\n\t}\n\n\t// AI / generic run()\n\tif (operation === 'ai.run') {\n\t\tif (typeof binding.run !== 'function') {\n\t\t\tthrow new Error('Binding ' + bindingName + ' does not support run(): ' + method)\n\t\t}\n\t\treturn binding.run(params[0], params[1])\n\t}\n\n\tthrow new Error('Unknown operation: ' + method)\n}\n\nfunction createUnsupportedBridgeOperationErrorMessage(bindingName, operation) {\n\tconst base = \"[devflare][bridge] Unsupported bridge operation '\" + operation + \"' for binding '\" + bindingName + \"'.\"\n\tif (operation === 'fetch') {\n\t\treturn base + ' Devflare could not dispatch fetch() for this binding through the local bridge. '\n\t\t\t+ 'Expected Cloudflare API: env.' + bindingName + '.fetch(request). '\n\t\t\t+ 'If this came from SvelteKit platform.env, make sure the binding is declared as a service binding; '\n\t\t\t+ 'this is a Devflare local bridge issue when service bindings fall back to a bare fetch operation.'\n\t}\n\tif (operation === 'toString') {\n\t\treturn base + ' A platform.env value was coerced to a string through the bridge. '\n\t\t\t+ 'For SvelteKit local dev, declared vars should be plain string values and missing env names should read as undefined.'\n\t}\n\treturn base + ' Bare verbs and the legacy stmt.*/stub.* sub-prefixes are not supported; '\n\t\t+ 'use the namespaced form (e.g. kv.get, r2.put, d1.stmt.first, do.fetch, service.fetch).'\n}\n\nfunction serializeWorkflowInstance(instance) {\n\treturn {\n\t\t__type: 'WorkflowInstance',\n\t\tid: instance.id\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// WebSocket bridge (shared with src/bridge/server.ts in shape)\n// ---------------------------------------------------------------------------\n// NOTE: wsProxies is intentionally created per handleBridgeWebSocket call so\n// state never leaks across connections or across gateway-script regenerations.\n\nasync function handleBridgeRpcCall(msg, ws, env, ctx) {\n\ttry {\n\t\tconst result = await executeRpcMethod(msg.method, msg.params, env, ctx)\n\t\tws.send(JSON.stringify({ t: 'rpc.ok', id: msg.id, result }))\n\t} catch (error) {\n\t\tws.send(JSON.stringify({\n\t\t\tt: 'rpc.err',\n\t\t\tid: msg.id,\n\t\t\terror: {\n\t\t\t\tcode: error?.code || 'INTERNAL_ERROR',\n\t\t\t\tmessage: error?.message || String(error)\n\t\t\t}\n\t\t}))\n\t}\n}\n\nasync function handleBridgeWsOpen(msg, ws, env, wsProxies) {\n\ttry {\n\t\tconst binding = env[msg.target.binding]\n\t\tconst id = binding.idFromString(msg.target.id)\n\t\tconst stub = binding.get(id)\n\n\t\tconst headers = new Headers(msg.target.headers || [])\n\t\theaders.set('Upgrade', 'websocket')\n\n\t\tconst response = await stub.fetch(new Request(msg.target.url, { method: 'GET', headers }))\n\t\tconst doWs = response.webSocket\n\n\t\tif (!doWs) {\n\t\t\tws.send(JSON.stringify({\n\t\t\t\tt: 'rpc.err',\n\t\t\t\tid: 'ws_' + msg.wid,\n\t\t\t\terror: { code: 'WS_FAILED', message: 'No WebSocket returned' }\n\t\t\t}))\n\t\t\treturn\n\t\t}\n\n\t\tdoWs.accept()\n\t\twsProxies.set(msg.wid, { doWs })\n\n\t\tdoWs.addEventListener('message', (event) => {\n\t\t\tconst isText = typeof event.data === 'string'\n\t\t\tconst data = isText ? event.data : arrayBufferToBase64(event.data)\n\t\t\tws.send(JSON.stringify({ t: 'ws.data', wid: msg.wid, data, isText }))\n\t\t})\n\n\t\tdoWs.addEventListener('close', (event) => {\n\t\t\tws.send(JSON.stringify({ t: 'ws.close', wid: msg.wid, code: event.code, reason: event.reason }))\n\t\t\twsProxies.delete(msg.wid)\n\t\t})\n\n\t\tws.send(JSON.stringify({ t: 'ws.opened', wid: msg.wid }))\n\t} catch (error) {\n\t\tws.send(JSON.stringify({\n\t\t\tt: 'rpc.err',\n\t\t\tid: 'ws_' + msg.wid,\n\t\t\terror: { code: 'WS_FAILED', message: error.message }\n\t\t}))\n\t}\n}\n\nfunction handleBridgeWsClose(msg, wsProxies) {\n\tconst proxy = wsProxies.get(msg.wid)\n\tif (proxy) {\n\t\tproxy.doWs.close(msg.code, msg.reason)\n\t\twsProxies.delete(msg.wid)\n\t}\n}\n\nasync function handleBridgeJsonMessage(data, ws, env, ctx, wsProxies) {\n\tconst msg = JSON.parse(data)\n\tswitch (msg.t) {\n\t\tcase 'hello':\n\t\t\t// v2 handshake \u2014 acknowledge with welcome echoing the negotiated\n\t\t\t// capability intersection. Capabilities advertised by the gateway\n\t\t\t// are kept in sync with src/bridge/client.ts (BRIDGE_CLIENT_CAPABILITIES).\n\t\t\tws.send(JSON.stringify({\n\t\t\t\tt: 'welcome',\n\t\t\t\tprotocolVersion: 2,\n\t\t\t\tcapabilities: ['streams', 'ws-relay', 'http-transfer']\n\t\t\t\t\t.filter((c) => Array.isArray(msg.capabilities) && msg.capabilities.includes(c))\n\t\t\t\t\t.sort()\n\t\t\t}))\n\t\t\tbreak\n\t\tcase 'rpc.call':\n\t\t\tawait handleBridgeRpcCall(msg, ws, env, ctx)\n\t\t\tbreak\n\t\tcase 'ws.open':\n\t\t\tawait handleBridgeWsOpen(msg, ws, env, wsProxies)\n\t\t\tbreak\n\t\tcase 'ws.close':\n\t\t\thandleBridgeWsClose(msg, wsProxies)\n\t\t\tbreak\n\t}\n}\n\nfunction handleBridgeWebSocket(request, env, ctx) {\n\tconst { 0: client, 1: server } = new WebSocketPair()\n\tserver.accept()\n\n\t// Per-connection state: recreated for every bridge client so reloads and\n\t// concurrent clients never share WS proxy entries.\n\tconst wsProxies = new Map()\n\n\tserver.addEventListener('message', async (event) => {\n\t\ttry {\n\t\t\tif (typeof event.data === 'string') {\n\t\t\t\tawait handleBridgeJsonMessage(event.data, server, env, ctx, wsProxies)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error('[Gateway] Error:', error)\n\t\t}\n\t})\n\n\tserver.addEventListener('close', () => {\n\t\tfor (const proxy of wsProxies.values()) {\n\t\t\t// Best-effort cleanup: the DO-side WS may already be closed or in an\n\t\t\t// invalid state; any throw here would abort sibling closes. Surface\n\t\t\t// the swallowed error when DEVFLARE_DEBUG_BRIDGE is enabled.\n\t\t\ttry { proxy.doWs.close() } catch (error) {\n\t\t\t\tif (globalThis.DEVFLARE_DEBUG_BRIDGE) {\n\t\t\t\t\tconsole.warn('[devflare:bridge] proxy.doWs.close() failed', error)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\twsProxies.clear()\n\t})\n\n\treturn new Response(null, { status: 101, webSocket: client })\n}\n\n// ---------------------------------------------------------------------------\n// HTTP transfer for R2 bodies (shared with src/bridge/server.ts in shape)\n// ---------------------------------------------------------------------------\n\nasync function handleHttpTransfer(request, env, url) {\n\tconst transferIdEncoded = url.pathname.split('/').pop()\n\tconst transferId = decodeURIComponent(transferIdEncoded || '')\n\tconst [binding, ...keyParts] = transferId.split(':')\n\tconst key = keyParts.join(':')\n\tconst bucket = env[binding]\n\n\tif (!bucket) return new Response('Bucket not found: ' + binding, { status: 404 })\n\n\tif (request.method === 'PUT' || request.method === 'POST') {\n\t\tconst result = await bucket.put(key, request.body)\n\t\treturn new Response(JSON.stringify(serializeR2Object(result)), {\n\t\t\theaders: { 'Content-Type': 'application/json' }\n\t\t})\n\t}\n\n\tif (request.method === 'GET') {\n\t\tconst object = await bucket.get(key)\n\t\tif (!object) return new Response('Not found', { status: 404 })\n\t\treturn new Response(object.body, {\n\t\t\theaders: {\n\t\t\t\t'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream',\n\t\t\t\t'Content-Length': String(object.size)\n\t\t\t}\n\t\t})\n\t}\n\n\treturn new Response('Method not allowed', { status: 405 })\n}\n";
8
8
  //# sourceMappingURL=gateway-runtime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-runtime.d.ts","sourceRoot":"","sources":["../../src/bridge/gateway-runtime.ts"],"names":[],"mappings":"AAcA;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,skjBAigB9B,CAAA"}
1
+ {"version":3,"file":"gateway-runtime.d.ts","sourceRoot":"","sources":["../../src/bridge/gateway-runtime.ts"],"names":[],"mappings":"AAcA;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,mpkBAghB9B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/bridge/proxy.ts"],"names":[],"mappings":"AAMA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,UAAU,CAAA;AAavD,MAAM,WAAW,eAAe;IAC/B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,qCAAqC;IACrC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wEAAwE;IACxE,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAA;CAC9C;AAilBD,mDAAmD;AACnD,MAAM,MAAM,WAAW,GACpB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,OAAO,GACP,IAAI,GACJ,SAAS,GACT,WAAW,GACX,UAAU,GACV,QAAQ,GACR,KAAK,CAAA;AAER,MAAM,WAAW,YAAY;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;CAC1B;AAKD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAe,GAAG;IAAE,KAAK,CAAC,EAAE,YAAY,CAAA;CAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoFhH;AAoFD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAO5C,CAAA;AAEF;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,eAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAG9E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAIzD"}
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/bridge/proxy.ts"],"names":[],"mappings":"AAMA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,UAAU,CAAA;AAavD,MAAM,WAAW,eAAe;IAC/B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,qCAAqC;IACrC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wEAAwE;IACxE,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAA;CAC9C;AAqmBD,mDAAmD;AACnD,MAAM,MAAM,WAAW,GACpB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,OAAO,GACP,IAAI,GACJ,SAAS,GACT,WAAW,GACX,UAAU,GACV,QAAQ,GACR,KAAK,CAAA;AAER,MAAM,WAAW,YAAY;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;CAC1B;AAKD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAe,GAAG;IAAE,KAAK,CAAC,EAAE,YAAY,CAAA;CAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoFhH;AAoFD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAO5C,CAAA;AAEF;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,eAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAG9E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAIzD"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/bridge/server.ts"],"names":[],"mappings":"AAuCA,MAAM,WAAW,UAAU;IAE1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACtB;;IAiBM,KAAK,UAAU,OAAO,OAAO,UAAU,OAAO,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;;;AA8KzF,wBAAsB,gBAAgB,CACrC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EAAE,EACjB,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,gBAAgB,GACnB,OAAO,CAAC,OAAO,CAAC,CA2JlB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/bridge/server.ts"],"names":[],"mappings":"AAuCA,MAAM,WAAW,UAAU;IAE1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACtB;;IAiBM,KAAK,UAAU,OAAO,OAAO,UAAU,OAAO,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;;;AA8KzF,wBAAsB,gBAAgB,CACrC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EAAE,EACjB,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,gBAAgB,GACnB,OAAO,CAAC,OAAO,CAAC,CA+JlB"}
@@ -90,7 +90,9 @@ export type SerializedSpecial = {
90
90
  stack?: string;
91
91
  };
92
92
  /** Serialize a value that may contain special types */
93
- export declare function serializeValue(value: unknown): Promise<{
93
+ export declare function serializeValue(value: unknown, options?: {
94
+ httpThreshold?: number;
95
+ }): Promise<{
94
96
  value: unknown;
95
97
  streams: StreamRef[];
96
98
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"value-serialization.d.ts","sourceRoot":"","sources":["../../../src/bridge/v2/value-serialization.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"value-serialization.d.ts","sourceRoot":"","sources":["../../../src/bridge/v2/value-serialization.ts"],"names":[],"mappings":"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"}
package/dist/browser.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  env,
6
6
  vars
7
- } from "./index-vfh0ctjw.js";
7
+ } from "./index-qz6nbwpw.js";
8
8
  import {
9
9
  durableObject,
10
10
  getDurableObjectOptions
@@ -15,7 +15,7 @@ import {
15
15
  getClient,
16
16
  initEnv,
17
17
  setBindingHints
18
- } from "./index-a6cbcsyp.js";
18
+ } from "./index-6sj0v0dk.js";
19
19
  import"./index-hpwa6vsw.js";
20
20
  import {
21
21
  defineConfig,
package/dist/cli/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  parseArgs,
3
3
  runCli
4
- } from "../index-g7142jcz.js";
4
+ } from "../index-sqkbyw0c.js";
5
5
  import"../index-627srx16.js";
6
6
  import"../index-stgn34cr.js";
7
7
  import"../index-3t6rypgc.js";
@@ -60,7 +60,7 @@ import {
60
60
  GATEWAY_RUNTIME_JS,
61
61
  createMiniflareLog,
62
62
  isIgnorableMiniflareDisposeError
63
- } from "./index-35bmgpfw.js";
63
+ } from "./index-za0r01bx.js";
64
64
  import {
65
65
  buildLocalBindingShimServiceConfig
66
66
  } from "./index-dm9q84c7.js";
@@ -434,7 +434,7 @@ var DEFAULT_BRIDGE_PORT = 8686;
434
434
  // src/bridge/v2/value-serialization.ts
435
435
  async function serializeRequest(request, options) {
436
436
  const streams = [];
437
- const threshold = options?.httpThreshold ?? 10 * 1024 * 1024;
437
+ const threshold = options?.httpThreshold ?? HTTP_TRANSFER_THRESHOLD;
438
438
  const headers = [];
439
439
  request.headers.forEach((value, key) => {
440
440
  headers.push([key, value]);
@@ -443,7 +443,7 @@ async function serializeRequest(request, options) {
443
443
  if (request.body) {
444
444
  const bytes = await request.arrayBuffer();
445
445
  if (bytes.byteLength > threshold) {
446
- throw new Error("http body transfer not implemented; caller should use inline or binary transfer");
446
+ throw new Error("Request body exceeds the bridge inline limit (~512 KB) and large request-body streaming is not yet supported over the local bridge. " + "Send the payload in smaller chunks or via an R2 binding for now.");
447
447
  } else if (bytes.byteLength > 0) {
448
448
  body = { type: "bytes", data: base64Encode(new Uint8Array(bytes)) };
449
449
  }
@@ -482,7 +482,7 @@ function deserializeRequest(serialized, getStream) {
482
482
  }
483
483
  async function serializeResponse(response, options) {
484
484
  const streams = [];
485
- const threshold = options?.httpThreshold ?? 10 * 1024 * 1024;
485
+ const threshold = options?.httpThreshold ?? HTTP_TRANSFER_THRESHOLD;
486
486
  const headers = [];
487
487
  response.headers.forEach((value, key) => {
488
488
  headers.push([key, value]);
@@ -491,7 +491,19 @@ async function serializeResponse(response, options) {
491
491
  if (response.body) {
492
492
  const bytes = await response.arrayBuffer();
493
493
  if (bytes.byteLength > threshold) {
494
- throw new Error("http body transfer not implemented; caller should use inline or binary transfer");
494
+ const sid = nextStreamId();
495
+ const payload = new Uint8Array(bytes);
496
+ const frameSize = HTTP_TRANSFER_THRESHOLD;
497
+ const stream = new ReadableStream({
498
+ start(controller) {
499
+ for (let offset = 0;offset < payload.byteLength; offset += frameSize) {
500
+ controller.enqueue(payload.slice(offset, Math.min(offset + frameSize, payload.byteLength)));
501
+ }
502
+ controller.close();
503
+ }
504
+ });
505
+ streams.push({ sid, stream });
506
+ body = { type: "stream", sid };
495
507
  } else if (bytes.byteLength > 0) {
496
508
  body = { type: "bytes", data: base64Encode(new Uint8Array(bytes)) };
497
509
  }
@@ -526,22 +538,22 @@ function deserializeResponse(serialized, getStream) {
526
538
  headers: serialized.headers
527
539
  });
528
540
  }
529
- async function serializeValue(value) {
541
+ async function serializeValue(value, options) {
530
542
  const streams = [];
531
- const result = await serializeValueInternal(value, streams);
543
+ const result = await serializeValueInternal(value, streams, options);
532
544
  return { value: result, streams };
533
545
  }
534
- async function serializeValueInternal(value, streams) {
546
+ async function serializeValueInternal(value, streams, options) {
535
547
  if (value === null || value === undefined) {
536
548
  return value;
537
549
  }
538
550
  if (value instanceof Request) {
539
- const { serialized, streams: reqStreams } = await serializeRequest(value);
551
+ const { serialized, streams: reqStreams } = await serializeRequest(value, options);
540
552
  streams.push(...reqStreams);
541
553
  return { __type: "Request", ...serialized };
542
554
  }
543
555
  if (value instanceof Response) {
544
- const { serialized, streams: resStreams } = await serializeResponse(value);
556
+ const { serialized, streams: resStreams } = await serializeResponse(value, options);
545
557
  streams.push(...resStreams);
546
558
  return { __type: "Response", ...serialized };
547
559
  }
@@ -576,8 +588,8 @@ async function serializeValueInternal(value, streams) {
576
588
  const entries = [];
577
589
  for (const [k, v] of value.entries()) {
578
590
  entries.push([
579
- await serializeValueInternal(k, streams),
580
- await serializeValueInternal(v, streams)
591
+ await serializeValueInternal(k, streams, options),
592
+ await serializeValueInternal(v, streams, options)
581
593
  ]);
582
594
  }
583
595
  return { __devflare: "map", entries };
@@ -585,17 +597,17 @@ async function serializeValueInternal(value, streams) {
585
597
  if (value instanceof Set) {
586
598
  const values = [];
587
599
  for (const v of value.values()) {
588
- values.push(await serializeValueInternal(v, streams));
600
+ values.push(await serializeValueInternal(v, streams, options));
589
601
  }
590
602
  return { __devflare: "set", values };
591
603
  }
592
604
  if (Array.isArray(value)) {
593
- return Promise.all(value.map((v) => serializeValueInternal(v, streams)));
605
+ return Promise.all(value.map((v) => serializeValueInternal(v, streams, options)));
594
606
  }
595
607
  if (typeof value === "object") {
596
608
  const result = {};
597
609
  for (const [k, v] of Object.entries(value)) {
598
- result[k] = await serializeValueInternal(v, streams);
610
+ result[k] = await serializeValueInternal(v, streams, options);
599
611
  }
600
612
  return result;
601
613
  }
@@ -1263,6 +1275,7 @@ class BridgeClient {
1263
1275
  wsProxies = new Map;
1264
1276
  pendingWsOpens = new Map;
1265
1277
  outgoingStreams = new Map;
1278
+ eventListeners = new Map;
1266
1279
  connectPromise = null;
1267
1280
  isConnected = false;
1268
1281
  constructor(options = {}) {
@@ -1352,6 +1365,7 @@ class BridgeClient {
1352
1365
  this.ws = null;
1353
1366
  this.isConnected = false;
1354
1367
  this.cleanupPending(new Error("Bridge disconnected"));
1368
+ this.eventListeners.clear();
1355
1369
  }
1356
1370
  close() {
1357
1371
  this.disconnect();
@@ -1428,6 +1442,22 @@ class BridgeClient {
1428
1442
  clearTimeout(timeoutHandle);
1429
1443
  }
1430
1444
  }
1445
+ on(topic, cb) {
1446
+ let set = this.eventListeners.get(topic);
1447
+ if (!set) {
1448
+ set = new Set;
1449
+ this.eventListeners.set(topic, set);
1450
+ }
1451
+ set.add(cb);
1452
+ return () => {
1453
+ const current = this.eventListeners.get(topic);
1454
+ if (!current)
1455
+ return;
1456
+ current.delete(cb);
1457
+ if (current.size === 0)
1458
+ this.eventListeners.delete(topic);
1459
+ };
1460
+ }
1431
1461
  async createWsProxy(binding, id, url, headers) {
1432
1462
  await this.ensureConnected();
1433
1463
  const wid = nextWsId();
@@ -1571,7 +1601,21 @@ class BridgeClient {
1571
1601
  break;
1572
1602
  }
1573
1603
  }
1574
- handleEvent(_msg) {}
1604
+ handleEvent(msg) {
1605
+ this.dispatchEvent(this.eventListeners.get(msg.topic), msg.data, msg.topic);
1606
+ this.dispatchEvent(this.eventListeners.get("*"), msg.data, msg.topic);
1607
+ }
1608
+ dispatchEvent(listeners, data, topic) {
1609
+ if (!listeners)
1610
+ return;
1611
+ for (const cb of [...listeners]) {
1612
+ try {
1613
+ cb(data);
1614
+ } catch (error) {
1615
+ bridgeLog.warn(`event listener for topic "${topic}" threw`, error);
1616
+ }
1617
+ }
1618
+ }
1575
1619
  handleStreamPull(msg) {
1576
1620
  const streamRef = this.outgoingStreams.get(msg.sid);
1577
1621
  if (!streamRef)
@@ -1817,14 +1861,14 @@ function createD1StatementProxy(client, bindingName, sql, bindings) {
1817
1861
  function createDOProxy(client, bindingName, proxyOptions = {}) {
1818
1862
  return {
1819
1863
  idFromName(name) {
1820
- return createDOIdProxy(client, bindingName, { type: "name", value: name });
1864
+ return createDOIdProxy(client, bindingName, { type: "name", value: name, jurisdiction: proxyOptions.jurisdiction });
1821
1865
  },
1822
1866
  idFromString(hexId) {
1823
- return createDOIdProxy(client, bindingName, { type: "hex", value: hexId });
1867
+ return createDOIdProxy(client, bindingName, { type: "hex", value: hexId, jurisdiction: proxyOptions.jurisdiction });
1824
1868
  },
1825
1869
  newUniqueId(options) {
1826
1870
  const tempId = crypto.randomUUID().replace(/-/g, "");
1827
- return createDOIdProxy(client, bindingName, { type: "unique", value: tempId, options });
1871
+ return createDOIdProxy(client, bindingName, { type: "unique", value: tempId, options, jurisdiction: proxyOptions.jurisdiction });
1828
1872
  },
1829
1873
  get(id) {
1830
1874
  const idProxy = id;
@@ -1835,7 +1879,7 @@ function createDOProxy(client, bindingName, proxyOptions = {}) {
1835
1879
  return this.get(id);
1836
1880
  },
1837
1881
  jurisdiction(jurisdiction) {
1838
- return createDOProxy(client, bindingName, proxyOptions);
1882
+ return createDOProxy(client, bindingName, { ...proxyOptions, jurisdiction });
1839
1883
  }
1840
1884
  };
1841
1885
  }
@@ -1860,13 +1904,13 @@ function createDOStubProxy(client, bindingName, idInfo, proxyOptions = {}) {
1860
1904
  return resolvedId;
1861
1905
  switch (idInfo.type) {
1862
1906
  case "name":
1863
- resolvedId = await client.call(`${bindingName}.do.idFromName`, [idInfo.value]);
1907
+ resolvedId = await client.call(`${bindingName}.do.idFromName`, [idInfo.value, idInfo.jurisdiction]);
1864
1908
  break;
1865
1909
  case "hex":
1866
1910
  resolvedId = { __type: "DOId", hex: idInfo.value };
1867
1911
  break;
1868
1912
  case "unique":
1869
- resolvedId = await client.call(`${bindingName}.do.newUniqueId`, [idInfo.options]);
1913
+ resolvedId = await client.call(`${bindingName}.do.newUniqueId`, [idInfo.options, idInfo.jurisdiction]);
1870
1914
  break;
1871
1915
  }
1872
1916
  return resolvedId;
@@ -1939,7 +1983,7 @@ function createDOStubProxy(client, bindingName, idInfo, proxyOptions = {}) {
1939
1983
  return Promise.resolve();
1940
1984
  },
1941
1985
  startTls() {
1942
- throw new Error("startTls not supported on DO WebSocket proxy");
1986
+ throw new Error("startTls() is not supported on a Durable Object WebSocket connection. " + "StartTLS applies to raw TCP sockets (cloudflare:sockets connect()), not " + "WebSocket-tunneled DO connections, whose transport is already secured by the connection itself.");
1943
1987
  }
1944
1988
  };
1945
1989
  },
@@ -3,7 +3,7 @@ import {
3
3
  createFetchEvent,
4
4
  getContextOrNull,
5
5
  runWithEventContext
6
- } from "./index-a6cbcsyp.js";
6
+ } from "./index-6sj0v0dk.js";
7
7
 
8
8
  // src/runtime/exports.ts
9
9
  function createReadonlyProxy(getter, name) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  bridgeEnv,
3
3
  getContextOrNull
4
- } from "./index-a6cbcsyp.js";
4
+ } from "./index-6sj0v0dk.js";
5
5
 
6
6
  // src/env.ts
7
7
  var testContextEnv = null;
@@ -1362,7 +1362,7 @@ async function runInit(parsed, logger, options) {
1362
1362
  return runInitCommand(parsed, logger, options);
1363
1363
  }
1364
1364
  async function runDev(parsed, logger, options) {
1365
- const { runDevCommand } = await import("./dev-f2zhzajr.js");
1365
+ const { runDevCommand } = await import("./dev-ymkq3thq.js");
1366
1366
  return runDevCommand(parsed, logger, options);
1367
1367
  }
1368
1368
  async function runBuild(parsed, logger, options) {
@@ -56,6 +56,29 @@ function extractBindingHints(config) {
56
56
  return hints;
57
57
  }
58
58
 
59
+ // src/shims/local-hyperdrive.ts
60
+ var HYPERDRIVE_CONNECT_MESSAGE = "Local Hyperdrive does not implement the raw socket connect(). " + "Use the populated connection fields (connectionString, or host/port/user/password/database) " + "with your Node database driver, or run a createTestContext()/Miniflare-backed test " + "(Miniflare establishes real Hyperdrive socket connections) for socket-level behavior.";
61
+ function defaultPortForDatabaseUrl(url) {
62
+ if (url.port) {
63
+ return Number(url.port);
64
+ }
65
+ return url.protocol === "mysql:" ? 3306 : 5432;
66
+ }
67
+ function createLocalHyperdrive(connectionString) {
68
+ const url = new URL(connectionString);
69
+ return {
70
+ connectionString,
71
+ host: url.hostname,
72
+ port: defaultPortForDatabaseUrl(url),
73
+ user: decodeURIComponent(url.username),
74
+ password: decodeURIComponent(url.password),
75
+ database: decodeURIComponent(url.pathname.replace(/^\//, "")),
76
+ connect() {
77
+ throw new Error(HYPERDRIVE_CONNECT_MESSAGE);
78
+ }
79
+ };
80
+ }
81
+
59
82
  // src/shims/local-worker-loader.ts
60
83
  var activeWorkerLoaderRuntimes = new Set;
61
84
  function getModuleSource(module, mainModule) {
@@ -107,7 +130,7 @@ function createLocalWorkerStub(codeProvider) {
107
130
  return fetcher;
108
131
  },
109
132
  getDurableObjectClass() {
110
- throw new Error("Worker Loader local shim does not support dynamic Durable Object classes yet.");
133
+ throw new Error("Worker Loader local shim cannot materialise a dynamic Durable Object class. getDurableObjectClass() returns an opaque facet-spawning reference that workerd only exposes inside the runtime. Use createTestContext() (a real Miniflare worker) for Durable Object behavior, or createMockWorkerLoader({ stub }) to inject a stub.");
111
134
  }
112
135
  };
113
136
  }
@@ -129,4 +152,4 @@ async function disposeLocalWorkerLoaderBindings() {
129
152
  }));
130
153
  }
131
154
 
132
- export { extractBindingHints, createLocalWorkerLoaderBinding, disposeLocalWorkerLoaderBindings };
155
+ export { extractBindingHints, createLocalHyperdrive, createLocalWorkerLoaderBinding, disposeLocalWorkerLoaderBindings };
@@ -154,6 +154,19 @@ function isDurableObjectNamespace(binding) {
154
154
  && typeof binding.newUniqueId === 'function'
155
155
  }
156
156
 
157
+ /**
158
+ * Resolve a (possibly jurisdiction-scoped) DurableObjectNamespace.
159
+ * Forwards the jurisdiction faithfully when the binding supports it
160
+ * (real Cloudflare), and degrades to the plain binding otherwise
161
+ * (miniflare/workerd local emulation, which does not pin jurisdictions).
162
+ */
163
+ function resolveDoNamespace(binding, jurisdiction) {
164
+ if (jurisdiction && typeof binding.jurisdiction === 'function') {
165
+ return binding.jurisdiction(jurisdiction)
166
+ }
167
+ return binding
168
+ }
169
+
157
170
  /**
158
171
  * Execute an RPC method against the gateway's bindings.
159
172
  *
@@ -250,7 +263,8 @@ async function executeRpcMethod(method, params, env, _ctx) {
250
263
 
251
264
  // Durable Objects
252
265
  if (operation === 'do.idFromName') {
253
- const id = binding.idFromName(params[0])
266
+ const ns = resolveDoNamespace(binding, params[1])
267
+ const id = ns.idFromName(params[0])
254
268
  return { __type: 'DOId', hex: id.toString() }
255
269
  }
256
270
  if (operation === 'do.idFromString') {
@@ -258,7 +272,8 @@ async function executeRpcMethod(method, params, env, _ctx) {
258
272
  return { __type: 'DOId', hex: id.toString() }
259
273
  }
260
274
  if (operation === 'do.newUniqueId') {
261
- const id = binding.newUniqueId(params[0])
275
+ const ns = resolveDoNamespace(binding, params[1])
276
+ const id = ns.newUniqueId(params[0])
262
277
  return { __type: 'DOId', hex: id.toString() }
263
278
  }
264
279
  if (operation === 'do.fetch') {
package/dist/index.js CHANGED
@@ -4,19 +4,19 @@ import {
4
4
  import {
5
5
  parseArgs,
6
6
  runCli
7
- } from "./index-g7142jcz.js";
7
+ } from "./index-sqkbyw0c.js";
8
8
  import"./index-627srx16.js";
9
9
  import"./index-stgn34cr.js";
10
10
  import"./index-3t6rypgc.js";
11
11
  import {
12
12
  env,
13
13
  vars
14
- } from "./index-vfh0ctjw.js";
14
+ } from "./index-qz6nbwpw.js";
15
15
  import {
16
16
  durableObject,
17
17
  getDurableObjectOptions
18
18
  } from "./index-a855bdsx.js";
19
- import"./index-a6cbcsyp.js";
19
+ import"./index-6sj0v0dk.js";
20
20
  import"./index-hpwa6vsw.js";
21
21
  import {
22
22
  compileConfig,
@@ -19,8 +19,8 @@ import {
19
19
  resolveFetchHandler,
20
20
  sequence,
21
21
  vars
22
- } from "../index-kecy9p48.js";
23
- import"../index-vfh0ctjw.js";
22
+ } from "../index-85yjb686.js";
23
+ import"../index-qz6nbwpw.js";
24
24
  import {
25
25
  durableObject,
26
26
  getDurableObjectOptions
@@ -56,7 +56,7 @@ import {
56
56
  hasContext,
57
57
  runWithContext,
58
58
  runWithEventContext
59
- } from "../index-a6cbcsyp.js";
59
+ } from "../index-6sj0v0dk.js";
60
60
  import {
61
61
  clearLocalSendEmailBindings,
62
62
  setLocalSendEmailBindings
@@ -0,0 +1,12 @@
1
+ export declare const HYPERDRIVE_CONNECT_MESSAGE: string;
2
+ /**
3
+ * Creates a Hyperdrive binding around a local database connection string.
4
+ *
5
+ * The connection fields are real and usable with any Node database client. The
6
+ * Cloudflare `connect()` raw socket is intentionally not implemented — it would
7
+ * require faithfully reproducing `cloudflare:sockets` semantics (TLS, startTls(),
8
+ * half-open, SocketInfo) over node:net, which is exactly the kind of fake that
9
+ * fails silently. It throws a clear, actionable error instead.
10
+ */
11
+ export declare function createLocalHyperdrive(connectionString: string): Hyperdrive;
12
+ //# sourceMappingURL=local-hyperdrive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-hyperdrive.d.ts","sourceRoot":"","sources":["../../src/shims/local-hyperdrive.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,0BAA0B,QAImD,CAAA;AAU1F;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,GAAG,UAAU,CAc1E"}
@@ -1 +1 @@
1
- {"version":3,"file":"local-worker-loader.d.ts","sourceRoot":"","sources":["../../src/shims/local-worker-loader.ts"],"names":[],"mappings":"AAuEA,wBAAgB,8BAA8B,IAAI,YAAY,CAY7D;AAED,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,IAAI,CAAC,CAOtE"}
1
+ {"version":3,"file":"local-worker-loader.d.ts","sourceRoot":"","sources":["../../src/shims/local-worker-loader.ts"],"names":[],"mappings":"AAkFA,wBAAgB,8BAA8B,IAAI,YAAY,CAY7D;AAED,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,IAAI,CAAC,CAOtE"}
@@ -1,8 +1,9 @@
1
- import"../index-35bmgpfw.js";
1
+ import"../index-za0r01bx.js";
2
2
  import {
3
+ createLocalHyperdrive,
3
4
  createLocalWorkerLoaderBinding,
4
5
  extractBindingHints
5
- } from "../index-y59hnmd0.js";
6
+ } from "../index-t9y0sve5.js";
6
7
  import {
7
8
  createLocalImagesBinding,
8
9
  createLocalMediaBinding
@@ -16,7 +17,7 @@ import {
16
17
  getClient,
17
18
  runWithEventContext,
18
19
  setBindingHints
19
- } from "../index-a6cbcsyp.js";
20
+ } from "../index-6sj0v0dk.js";
20
21
  import {
21
22
  createLocalSendEmailBinding
22
23
  } from "../index-hpwa6vsw.js";
@@ -31,32 +32,12 @@ import"../index-c8p4njqy.js";
31
32
  import"../index-q8f4kawk.js";
32
33
  import"../index-37x76zdn.js";
33
34
  // src/sveltekit/local-bindings.ts
34
- function defaultPortForDatabaseUrl(url) {
35
- if (url.port) {
36
- return Number(url.port);
37
- }
38
- return url.protocol === "mysql:" ? 3306 : 5432;
39
- }
40
- function createLocalHyperdriveBinding(connectionString) {
41
- const url = new URL(connectionString);
42
- return {
43
- connectionString,
44
- host: url.hostname,
45
- port: defaultPortForDatabaseUrl(url),
46
- user: decodeURIComponent(url.username),
47
- password: decodeURIComponent(url.password),
48
- database: decodeURIComponent(url.pathname.replace(/^\//, "")),
49
- connect() {
50
- throw new Error("Devflare local Hyperdrive exposes connectionString for local database clients. Raw socket connect() is not implemented in the SvelteKit Node adapter path.");
51
- }
52
- };
53
- }
54
35
  function buildLocalHyperdriveBindings(config) {
55
36
  const bindings = {};
56
37
  for (const [name, binding] of Object.entries(config.bindings?.hyperdrive ?? {})) {
57
38
  const normalized = normalizeHyperdriveBinding(binding);
58
39
  if (normalized.localConnectionString) {
59
- bindings[name] = createLocalHyperdriveBinding(normalized.localConnectionString);
40
+ bindings[name] = createLocalHyperdrive(normalized.localConnectionString);
60
41
  }
61
42
  }
62
43
  return bindings;
@@ -1 +1 @@
1
- {"version":3,"file":"local-bindings.d.ts","sourceRoot":"","sources":["../../src/sveltekit/local-bindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,cAAc,EACnB,MAAM,WAAW,CAAA;AAgDlB,wBAAgB,2BAA2B,CAC1C,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,MAAM,GACT,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwBzB;AAED,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACpC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoCzB"}
1
+ {"version":3,"file":"local-bindings.d.ts","sourceRoot":"","sources":["../../src/sveltekit/local-bindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,cAAc,EACnB,MAAM,WAAW,CAAA;AAuBlB,wBAAgB,2BAA2B,CAC1C,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,MAAM,GACT,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwBzB;AAED,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACpC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoCzB"}
@@ -14,12 +14,12 @@ import {
14
14
  invokeFetchModule,
15
15
  matchFetchRoute,
16
16
  resolveFetchHandler
17
- } from "../index-kecy9p48.js";
17
+ } from "../index-85yjb686.js";
18
18
  import {
19
19
  __clearTestContext,
20
20
  __setTestContext,
21
21
  env
22
- } from "../index-vfh0ctjw.js";
22
+ } from "../index-qz6nbwpw.js";
23
23
  import"../index-a855bdsx.js";
24
24
  import {
25
25
  buildHyperdrivesConfig,
@@ -38,10 +38,11 @@ import {
38
38
  import"../index-aqrwyy57.js";
39
39
  import"../index-vhqww6tt.js";
40
40
  import {
41
+ createLocalHyperdrive,
41
42
  createLocalWorkerLoaderBinding,
42
43
  disposeLocalWorkerLoaderBindings,
43
44
  extractBindingHints
44
- } from "../index-y59hnmd0.js";
45
+ } from "../index-t9y0sve5.js";
45
46
  import {
46
47
  buildLocalBindingShimServiceConfig
47
48
  } from "../index-dm9q84c7.js";
@@ -60,7 +61,7 @@ import {
60
61
  runWithContext,
61
62
  runWithEventContext,
62
63
  setBindingHints
63
- } from "../index-a6cbcsyp.js";
64
+ } from "../index-6sj0v0dk.js";
64
65
  import {
65
66
  createLocalSendEmailBinding,
66
67
  wrapEnvSendEmailBindings
@@ -1058,8 +1059,37 @@ function createMockD1(mockResultsOrOptions = []) {
1058
1059
  };
1059
1060
  }
1060
1061
  // src/test/utilities/r2.ts
1062
+ async function coerceToString(value) {
1063
+ if (typeof value === "string") {
1064
+ return value;
1065
+ }
1066
+ if (value === null) {
1067
+ return "";
1068
+ }
1069
+ if (value instanceof ArrayBuffer) {
1070
+ return new TextDecoder().decode(value);
1071
+ }
1072
+ if (ArrayBuffer.isView(value)) {
1073
+ return new TextDecoder().decode(value);
1074
+ }
1075
+ if (value instanceof Blob) {
1076
+ return await value.text();
1077
+ }
1078
+ const reader = value.getReader();
1079
+ const chunks = [];
1080
+ let done = false;
1081
+ while (!done) {
1082
+ const result = await reader.read();
1083
+ done = result.done;
1084
+ if (result.value) {
1085
+ chunks.push(new TextDecoder().decode(result.value));
1086
+ }
1087
+ }
1088
+ return chunks.join("");
1089
+ }
1061
1090
  function createMockR2() {
1062
1091
  const store = new Map;
1092
+ const uploads = new Map;
1063
1093
  const createR2Object = (key, content, metadata) => {
1064
1094
  const encoder = new TextEncoder;
1065
1095
  const data = encoder.encode(content);
@@ -1098,28 +1128,7 @@ function createMockR2() {
1098
1128
  };
1099
1129
  return {
1100
1130
  async put(key, value, options) {
1101
- let content;
1102
- if (typeof value === "string") {
1103
- content = value;
1104
- } else if (value instanceof ArrayBuffer) {
1105
- content = new TextDecoder().decode(value);
1106
- } else if (value instanceof Blob) {
1107
- content = await value.text();
1108
- } else if (value === null) {
1109
- content = "";
1110
- } else {
1111
- const reader = value.getReader();
1112
- const chunks = [];
1113
- let done = false;
1114
- while (!done) {
1115
- const result = await reader.read();
1116
- done = result.done;
1117
- if (result.value) {
1118
- chunks.push(new TextDecoder().decode(result.value));
1119
- }
1120
- }
1121
- content = chunks.join("");
1122
- }
1131
+ const content = await coerceToString(value);
1123
1132
  store.set(key, { content });
1124
1133
  return createR2Object(key, content);
1125
1134
  },
@@ -1162,12 +1171,54 @@ function createMockR2() {
1162
1171
  };
1163
1172
  },
1164
1173
  async createMultipartUpload(key, options) {
1165
- throw new Error("Multipart upload not implemented in mock");
1174
+ const uploadId = crypto.randomUUID();
1175
+ uploads.set(uploadId, { key, parts: new Map, options });
1176
+ return createMultipart(key, uploadId);
1166
1177
  },
1167
- async resumeMultipartUpload(key, uploadId) {
1168
- throw new Error("Multipart upload not implemented in mock");
1178
+ resumeMultipartUpload(key, uploadId) {
1179
+ if (!uploads.has(uploadId)) {
1180
+ uploads.set(uploadId, { key, parts: new Map });
1181
+ }
1182
+ return createMultipart(key, uploadId);
1169
1183
  }
1170
1184
  };
1185
+ function createMultipart(key, uploadId) {
1186
+ const requireEntry = () => {
1187
+ const entry = uploads.get(uploadId);
1188
+ if (!entry) {
1189
+ throw new Error(`Mock R2 multipart upload "${uploadId}" for key "${key}" is not active (it was aborted or completed).`);
1190
+ }
1191
+ return entry;
1192
+ };
1193
+ return {
1194
+ key,
1195
+ uploadId,
1196
+ async uploadPart(partNumber, value, _options) {
1197
+ const entry = requireEntry();
1198
+ const str = await coerceToString(value);
1199
+ entry.parts.set(partNumber, str);
1200
+ return { partNumber, etag: `"${key}-part-${partNumber}-etag"` };
1201
+ },
1202
+ async abort() {
1203
+ uploads.delete(uploadId);
1204
+ },
1205
+ async complete(uploadedParts) {
1206
+ const entry = requireEntry();
1207
+ const ordered = [...uploadedParts].sort((a, b) => a.partNumber - b.partNumber);
1208
+ const content = ordered.map((part) => {
1209
+ const chunk = entry.parts.get(part.partNumber);
1210
+ if (chunk === undefined) {
1211
+ throw new Error(`Mock R2 multipart complete() references part ${part.partNumber} that was never uploaded for upload "${uploadId}".`);
1212
+ }
1213
+ return chunk;
1214
+ }).join("");
1215
+ const metadata = entry.options?.customMetadata;
1216
+ store.set(key, { content, metadata });
1217
+ uploads.delete(uploadId);
1218
+ return createR2Object(key, content, metadata);
1219
+ }
1220
+ };
1221
+ }
1171
1222
  }
1172
1223
  // src/test/utilities/queue.ts
1173
1224
  function createMockQueue() {
@@ -1234,25 +1285,8 @@ function createMockSecretsStoreSecret(value) {
1234
1285
  }
1235
1286
  };
1236
1287
  }
1237
- function defaultPortForDatabaseUrl(url) {
1238
- if (url.port) {
1239
- return Number(url.port);
1240
- }
1241
- return url.protocol === "mysql:" ? 3306 : 5432;
1242
- }
1243
1288
  function createMockHyperdrive(connectionString) {
1244
- const url = new URL(connectionString);
1245
- return {
1246
- connectionString,
1247
- host: url.hostname,
1248
- port: defaultPortForDatabaseUrl(url),
1249
- user: decodeURIComponent(url.username),
1250
- password: decodeURIComponent(url.password),
1251
- database: decodeURIComponent(url.pathname.replace(/^\//, "")),
1252
- connect() {
1253
- throw new Error("Mock Hyperdrive connect() is not implemented. Use connectionString with your database client, or run a Miniflare-backed test for socket behavior.");
1254
- }
1255
- };
1289
+ return createLocalHyperdrive(connectionString);
1256
1290
  }
1257
1291
  function createDefaultWorkerStub() {
1258
1292
  return {
@@ -1260,7 +1294,7 @@ function createDefaultWorkerStub() {
1260
1294
  throw new Error("Mock WorkerLoader stub has no entrypoint. Pass createMockWorkerLoader({ stub }) for behavior.");
1261
1295
  },
1262
1296
  getDurableObjectClass() {
1263
- throw new Error("Mock WorkerLoader stub has no Durable Object class. Pass createMockWorkerLoader({ stub }) for behavior.");
1297
+ throw new Error("Mock WorkerLoader stub cannot materialise a Durable Object class. " + "getDurableObjectClass() returns an opaque facet-spawning reference that workerd " + "only exposes inside the runtime. Pass createMockWorkerLoader({ stub }) to inject a stub, " + "or use createTestContext() (a real Miniflare worker) for Durable Object behavior.");
1264
1298
  }
1265
1299
  };
1266
1300
  }
@@ -13,6 +13,9 @@ export declare function createMockVersionMetadata(metadata?: Partial<WorkerVersi
13
13
  export declare function createMockSecretsStoreSecret(value: string): SecretsStoreSecret;
14
14
  /**
15
15
  * Creates a Hyperdrive binding around a local database connection string.
16
+ *
17
+ * Connection fields are usable with any Node database client; the raw socket
18
+ * `connect()` is a documented limitation that throws a clear, actionable error.
16
19
  */
17
20
  export declare function createMockHyperdrive(connectionString: string): Hyperdrive;
18
21
  export interface MockWorkerLoaderOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/platform.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,oBAAoB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAAA;CAChB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,SAAS,CAkBjF;AAMD,wBAAgB,yBAAyB,CACxC,QAAQ,GAAE,OAAO,CAAC,qBAAqB,CAAM,GAC3C,qBAAqB,CAMvB;AAMD;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAM9E;AAcD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,GAAG,UAAU,CAgBzE;AAMD,MAAM,WAAW,uBAAuB;IACvC,IAAI,CAAC,EAAE,UAAU,CAAA;CACjB;AAiBD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,YAAY,CAc1F;AAMD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,GAAG,CAAA;AAEnD,MAAM,MAAM,kBAAkB,GAAG,CAChC,KAAK,EAAE,cAAc,EACrB,IAAI,CAAC,EAAE,WAAW,KACd,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;AAQjC;;GAEG;AACH,wBAAgB,yBAAyB,CACxC,OAAO,GAAE,kBAAkD,GACzD,OAAO,CAMT;AAMD,MAAM,WAAW,4BAA4B;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAA;CACtD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAC1C,OAAO,GAAE,4BAAiC,GACxC,iBAAiB,CAWnB"}
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/platform.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,oBAAoB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAAA;CAChB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,SAAS,CAkBjF;AAMD,wBAAgB,yBAAyB,CACxC,QAAQ,GAAE,OAAO,CAAC,qBAAqB,CAAM,GAC3C,qBAAqB,CAMvB;AAMD;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAM9E;AAMD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,GAAG,UAAU,CAEzE;AAMD,MAAM,WAAW,uBAAuB;IACvC,IAAI,CAAC,EAAE,UAAU,CAAA;CACjB;AAuBD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,YAAY,CAc1F;AAMD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,GAAG,CAAA;AAEnD,MAAM,MAAM,kBAAkB,GAAG,CAChC,KAAK,EAAE,cAAc,EACrB,IAAI,CAAC,EAAE,WAAW,KACd,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;AAQjC;;GAEG;AACH,wBAAgB,yBAAyB,CACxC,OAAO,GAAE,kBAAkD,GACzD,OAAO,CAMT;AAMD,MAAM,WAAW,4BAA4B;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAA;CACtD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAC1C,OAAO,GAAE,4BAAiC,GACxC,iBAAiB,CAWnB"}
@@ -1,12 +1,2 @@
1
- /**
2
- * Creates a mock R2Bucket for testing
3
- *
4
- * @example
5
- * ```ts
6
- * const r2 = createMockR2()
7
- * await r2.put('file.txt', 'content')
8
- * const obj = await r2.get('file.txt')
9
- * ```
10
- */
11
1
  export declare function createMockR2(): R2Bucket;
12
2
  //# sourceMappingURL=r2.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"r2.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/r2.ts"],"names":[],"mappings":"AAMA;;;;;;;;;GASG;AACH,wBAAgB,YAAY,IAAI,QAAQ,CAgIvC"}
1
+ {"version":3,"file":"r2.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/r2.ts"],"names":[],"mappings":"AAqDA,wBAAgB,YAAY,IAAI,QAAQ,CA6KvC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devflare",
3
- "version": "1.0.0-next.29",
3
+ "version": "1.0.0-next.30",
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",