diff --git a/apps/external/.env.production b/apps/external/.env.production
new file mode 100644
index 0000000..49c8887
--- /dev/null
+++ b/apps/external/.env.production
@@ -0,0 +1,7 @@
+VITE_SUPABASE_URL=https://mhcafqvzbrrwvahpvvzd.supabase.co
+VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im1oY2FmcXZ6YnJyd3ZhaHB2dnpkIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDEyNDEzMjEsImV4cCI6MjA1NjgxNzMyMX0.Otxn5BWCPD2ABlMM59hCgeur9Tf_Q7PndAbTkqXDPtM
+
+VITE_SUPABASE_ID=mhcafqvzbrrwvahpvvzd
+VITE_STREAM_CHAT_API_KEY="t5vvvddteapa"
+
+VITE_API_URL=https://xablo-api-636270553187.europe-west1.run.app
\ No newline at end of file
diff --git a/apps/external/biome.json b/apps/external/biome.json
index 7d53391..8c68d3a 100644
--- a/apps/external/biome.json
+++ b/apps/external/biome.json
@@ -3,7 +3,7 @@
"vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": false },
"files": {
"ignoreUnknown": true,
- "includes": ["src/**/*", "*.{ts,tsx,js,jsx,json}"]
+ "includes": ["src/**/*", "*.{tsx,js,jsx,json}", "vite.config.ts"]
},
"formatter": {
"enabled": true,
diff --git a/apps/external/package.json b/apps/external/package.json
index f72fd79..b49d447 100644
--- a/apps/external/package.json
+++ b/apps/external/package.json
@@ -4,8 +4,8 @@
"version": "0.0.0",
"type": "module",
"scripts": {
- "dev": "vite dev",
- "build": "tsc -b && vite build",
+ "dev": "vite dev --port 5174",
+ "build": "tsc -b && vite build --mode production",
"deploy": "wrangler deploy",
"typecheck": "tsc --noEmit",
"lint": "biome check .",
@@ -17,6 +17,7 @@
},
"devDependencies": {
"@biomejs/biome": "2.2.5",
+ "@cloudflare/vite-plugin": "^1.9.4",
"@tailwindcss/vite": "^4.0.14",
"@types/react": "19.0.10",
"@types/react-dom": "19.0.4",
diff --git a/apps/external/src/EmbeddedBookingPage.tsx b/apps/external/src/EmbeddedBookingPage.tsx
index 1a7269e..c5e65a5 100644
--- a/apps/external/src/EmbeddedBookingPage.tsx
+++ b/apps/external/src/EmbeddedBookingPage.tsx
@@ -213,11 +213,7 @@ export function EmbeddedBookingPage() {
const shortUserId = userInfo?.substring(userInfo.lastIndexOf("-") + 1);
- const { data: publicSlots } = usePublicSlots(
- api,
- shortUserId || "",
- eventTypeStandardName || ""
- );
+ const { data: publicSlots } = usePublicSlots(api, shortUserId || "", eventTypeStandardName || "");
const { mutateAsync: createTabloWithOwner } = useCreateTabloWithOwner(api, () => {
handleCloseModal();
diff --git a/apps/external/src/FloatingBookingWidget.tsx b/apps/external/src/FloatingBookingWidget.tsx
index 5887d89..22a1ca0 100644
--- a/apps/external/src/FloatingBookingWidget.tsx
+++ b/apps/external/src/FloatingBookingWidget.tsx
@@ -119,29 +119,31 @@ export function FloatingBookingWidget() {
const eventTypeStandardName = params.eventTypeStandardName as string;
const shortUserId = userInfo?.substring(userInfo.lastIndexOf("-") + 1);
- // Get variants from URL params with fallback to purple
+ // Get view mode and variants from URL params
+ const view = searchParams.get("view") || "default"; // 'button', 'modal', or 'default'
const buttonVariant = (searchParams.get("buttonVariant") as ColorVariant) || "purple";
// Get color schemes based on variants
const btnColors = buttonColors[buttonVariant];
- const { data: publicSlots } = usePublicSlots(
- api,
- shortUserId || "",
- eventTypeStandardName || ""
- );
+ const { data: publicSlots } = usePublicSlots(api, shortUserId || "", eventTypeStandardName || "");
const { mutateAsync: createTabloWithOwner } = useCreateTabloWithOwner(api, () => {
handleCloseModal();
- setIsWidgetOpen(false);
+ if (view === "modal") {
+ // Send message to parent to close the modal
+ window.parent.postMessage("xtablo:close", "*");
+ } else {
+ setIsWidgetOpen(false);
+ }
});
const userProfile = publicSlots?.user;
const eventType = publicSlots?.eventType;
const slotsData = publicSlots?.slots || {};
- // Widget state
- const [isWidgetOpen, setIsWidgetOpen] = useState(false);
+ // Widget state - auto-open if in modal view
+ const [isWidgetOpen, setIsWidgetOpen] = useState(view === "modal");
// Calendar state
const [currentDate, setCurrentDate] = useState(new Date());
@@ -370,27 +372,61 @@ export function FloatingBookingWidget() {
}
};
-
- return (
-
- {/* Floating Button */}
-
+ // If view is 'button', only show the button
+ if (view === "button") {
+ return (
+
+ );
+ }
+
+ return (
+
+ {/* Backdrop for modal view */}
+ {view === "modal" && isWidgetOpen && (
+
window.parent.postMessage("xtablo:close", "*")}
+ />
+ )}
+
+ {/* Floating Button - only show in default view */}
+ {view === "default" && (
+
+
+
+ )}
{/* Floating Widget Popup */}
{isWidgetOpen && (
-
+
{/* Header */}
@@ -419,8 +455,12 @@ export function FloatingBookingWidget() {
size="icon"
className="h-8 w-8 shrink-0"
onClick={() => {
- setIsWidgetOpen(false);
- setSelectedDate(null);
+ if (view === "modal") {
+ window.parent.postMessage("xtablo:close", "*");
+ } else {
+ setIsWidgetOpen(false);
+ setSelectedDate(null);
+ }
}}
>
diff --git a/apps/external/turbo.json b/apps/external/turbo.json
index 3ed9f2c..a3f7d59 100644
--- a/apps/external/turbo.json
+++ b/apps/external/turbo.json
@@ -9,4 +9,3 @@
}
}
}
-
diff --git a/apps/external/vite.config.ts b/apps/external/vite.config.ts
index 7c8420c..964bddd 100644
--- a/apps/external/vite.config.ts
+++ b/apps/external/vite.config.ts
@@ -1,26 +1,44 @@
///
+import { cloudflare } from "@cloudflare/vite-plugin";
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
-import { dirname, resolve } from "path";
+import { dirname } from "path";
import { fileURLToPath } from "url";
-import { defineConfig } from "vite";
+import { defineConfig, PluginOption } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
const __dirname = dirname(fileURLToPath(import.meta.url));
// https://vitejs.dev/config/
-export default defineConfig({
- plugins: [react(), tailwindcss(), tsconfigPaths()],
- server: {
- cors: false,
- port: 5174,
- },
- build: {
- rollupOptions: {
- input: {
- main: resolve(__dirname, "index.html"),
- },
+export default defineConfig(({ mode }) => {
+ const plugins: PluginOption[] = [
+ react(),
+ // visualizer() as PluginOption,
+ tailwindcss(),
+ tsconfigPaths(),
+ ];
+
+ // Only include cloudflare plugin when not in test mode
+ if (mode !== "test" && process.env.VITEST !== "true") {
+ plugins.push(cloudflare());
+ }
+
+ return {
+ plugins,
+ server: {
+ cors: false,
},
- },
+ define: process.env.VITEST
+ ? {
+ "import.meta.env.VITE_SUPABASE_URL": JSON.stringify("https://test.supabase.co"),
+ "import.meta.env.VITE_SUPABASE_ANON_KEY": JSON.stringify("test-anon-key"),
+ }
+ : undefined,
+ test: {
+ globals: true,
+ environment: "jsdom",
+ setupFiles: "./src/setupTests.ts",
+ },
+ };
});
diff --git a/apps/external/worker-configuration.d.ts b/apps/external/worker-configuration.d.ts
new file mode 100644
index 0000000..64d868a
--- /dev/null
+++ b/apps/external/worker-configuration.d.ts
@@ -0,0 +1,9363 @@
+/* eslint-disable */
+// Generated by Wrangler by running `wrangler types` (hash: a900135a3c6c1c08ec1bbba0ea58d9d3)
+// Runtime types generated with workerd@1.20251011.0 2025-07-09
+declare namespace Cloudflare {
+ interface GlobalProps {
+ mainModule: typeof import("./worker/index");
+ }
+ interface Env {
+ PYTHON_VERSION: "3.11.5";
+ VITE_SUPABASE_URL: string;
+ VITE_SUPABASE_ANON_KEY: string;
+ VITE_SUPABASE_ID: string;
+ VITE_STREAM_CHAT_API_KEY: string;
+ VITE_API_URL: string;
+ }
+}
+interface Env extends Cloudflare.Env {}
+
+// Begin runtime types
+/*! *****************************************************************************
+Copyright (c) Cloudflare. All rights reserved.
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at http://www.apache.org/licenses/LICENSE-2.0
+THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+MERCHANTABLITY OR NON-INFRINGEMENT.
+See the Apache Version 2.0 License for specific language governing permissions
+and limitations under the License.
+***************************************************************************** */
+/* eslint-disable */
+// noinspection JSUnusedGlobalSymbols
+declare var onmessage: never;
+/**
+ * An abnormal event (called an exception) which occurs as a result of calling a method or accessing a property of a web API.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException)
+ */
+declare class DOMException extends Error {
+ constructor(message?: string, name?: string);
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException/message) */
+ readonly message: string;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException/name) */
+ readonly name: string;
+ /**
+ * @deprecated
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException/code)
+ */
+ readonly code: number;
+ static readonly INDEX_SIZE_ERR: number;
+ static readonly DOMSTRING_SIZE_ERR: number;
+ static readonly HIERARCHY_REQUEST_ERR: number;
+ static readonly WRONG_DOCUMENT_ERR: number;
+ static readonly INVALID_CHARACTER_ERR: number;
+ static readonly NO_DATA_ALLOWED_ERR: number;
+ static readonly NO_MODIFICATION_ALLOWED_ERR: number;
+ static readonly NOT_FOUND_ERR: number;
+ static readonly NOT_SUPPORTED_ERR: number;
+ static readonly INUSE_ATTRIBUTE_ERR: number;
+ static readonly INVALID_STATE_ERR: number;
+ static readonly SYNTAX_ERR: number;
+ static readonly INVALID_MODIFICATION_ERR: number;
+ static readonly NAMESPACE_ERR: number;
+ static readonly INVALID_ACCESS_ERR: number;
+ static readonly VALIDATION_ERR: number;
+ static readonly TYPE_MISMATCH_ERR: number;
+ static readonly SECURITY_ERR: number;
+ static readonly NETWORK_ERR: number;
+ static readonly ABORT_ERR: number;
+ static readonly URL_MISMATCH_ERR: number;
+ static readonly QUOTA_EXCEEDED_ERR: number;
+ static readonly TIMEOUT_ERR: number;
+ static readonly INVALID_NODE_TYPE_ERR: number;
+ static readonly DATA_CLONE_ERR: number;
+ get stack(): any;
+ set stack(value: any);
+}
+type WorkerGlobalScopeEventMap = {
+ fetch: FetchEvent;
+ scheduled: ScheduledEvent;
+ queue: QueueEvent;
+ unhandledrejection: PromiseRejectionEvent;
+ rejectionhandled: PromiseRejectionEvent;
+};
+declare abstract class WorkerGlobalScope extends EventTarget
{
+ EventTarget: typeof EventTarget;
+}
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console) */
+interface Console {
+ assert(condition?: boolean, ...data: any[]): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/clear_static) */
+ clear(): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/count_static) */
+ count(label?: string): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/countReset_static) */
+ countReset(label?: string): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/debug_static) */
+ debug(...data: any[]): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/dir_static) */
+ dir(item?: any, options?: any): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/dirxml_static) */
+ dirxml(...data: any[]): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static) */
+ error(...data: any[]): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/group_static) */
+ group(...data: any[]): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/groupCollapsed_static) */
+ groupCollapsed(...data: any[]): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/groupEnd_static) */
+ groupEnd(): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/info_static) */
+ info(...data: any[]): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static) */
+ log(...data: any[]): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/table_static) */
+ table(tabularData?: any, properties?: string[]): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/time_static) */
+ time(label?: string): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/timeEnd_static) */
+ timeEnd(label?: string): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/timeLog_static) */
+ timeLog(label?: string, ...data: any[]): void;
+ timeStamp(label?: string): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/trace_static) */
+ trace(...data: any[]): void;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/warn_static) */
+ warn(...data: any[]): void;
+}
+declare const console: Console;
+type BufferSource = ArrayBufferView | ArrayBuffer;
+type TypedArray =
+ | Int8Array
+ | Uint8Array
+ | Uint8ClampedArray
+ | Int16Array
+ | Uint16Array
+ | Int32Array
+ | Uint32Array
+ | Float32Array
+ | Float64Array
+ | BigInt64Array
+ | BigUint64Array;
+declare namespace WebAssembly {
+ class CompileError extends Error {
+ constructor(message?: string);
+ }
+ class RuntimeError extends Error {
+ constructor(message?: string);
+ }
+ type ValueType = "anyfunc" | "externref" | "f32" | "f64" | "i32" | "i64" | "v128";
+ interface GlobalDescriptor {
+ value: ValueType;
+ mutable?: boolean;
+ }
+ class Global {
+ constructor(descriptor: GlobalDescriptor, value?: any);
+ value: any;
+ valueOf(): any;
+ }
+ type ImportValue = ExportValue | number;
+ type ModuleImports = Record;
+ type Imports = Record;
+ type ExportValue = Function | Global | Memory | Table;
+ type Exports = Record;
+ class Instance {
+ constructor(module: Module, imports?: Imports);
+ readonly exports: Exports;
+ }
+ interface MemoryDescriptor {
+ initial: number;
+ maximum?: number;
+ shared?: boolean;
+ }
+ class Memory {
+ constructor(descriptor: MemoryDescriptor);
+ readonly buffer: ArrayBuffer;
+ grow(delta: number): number;
+ }
+ type ImportExportKind = "function" | "global" | "memory" | "table";
+ interface ModuleExportDescriptor {
+ kind: ImportExportKind;
+ name: string;
+ }
+ interface ModuleImportDescriptor {
+ kind: ImportExportKind;
+ module: string;
+ name: string;
+ }
+ abstract class Module {
+ static customSections(module: Module, sectionName: string): ArrayBuffer[];
+ static exports(module: Module): ModuleExportDescriptor[];
+ static imports(module: Module): ModuleImportDescriptor[];
+ }
+ type TableKind = "anyfunc" | "externref";
+ interface TableDescriptor {
+ element: TableKind;
+ initial: number;
+ maximum?: number;
+ }
+ class Table {
+ constructor(descriptor: TableDescriptor, value?: any);
+ readonly length: number;
+ get(index: number): any;
+ grow(delta: number, value?: any): number;
+ set(index: number, value?: any): void;
+ }
+ function instantiate(module: Module, imports?: Imports): Promise;
+ function validate(bytes: BufferSource): boolean;
+}
+/**
+ * This ServiceWorker API interface represents the global execution context of a service worker.
+ * Available only in secure contexts.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope)
+ */
+interface ServiceWorkerGlobalScope extends WorkerGlobalScope {
+ DOMException: typeof DOMException;
+ WorkerGlobalScope: typeof WorkerGlobalScope;
+ btoa(data: string): string;
+ atob(data: string): string;
+ setTimeout(callback: (...args: any[]) => void, msDelay?: number): number;
+ setTimeout(
+ callback: (...args: Args) => void,
+ msDelay?: number,
+ ...args: Args
+ ): number;
+ clearTimeout(timeoutId: number | null): void;
+ setInterval(callback: (...args: any[]) => void, msDelay?: number): number;
+ setInterval(
+ callback: (...args: Args) => void,
+ msDelay?: number,
+ ...args: Args
+ ): number;
+ clearInterval(timeoutId: number | null): void;
+ queueMicrotask(task: Function): void;
+ structuredClone(value: T, options?: StructuredSerializeOptions): T;
+ reportError(error: any): void;
+ fetch(input: RequestInfo | URL, init?: RequestInit): Promise;
+ self: ServiceWorkerGlobalScope;
+ crypto: Crypto;
+ caches: CacheStorage;
+ scheduler: Scheduler;
+ performance: Performance;
+ Cloudflare: Cloudflare;
+ readonly origin: string;
+ Event: typeof Event;
+ ExtendableEvent: typeof ExtendableEvent;
+ CustomEvent: typeof CustomEvent;
+ PromiseRejectionEvent: typeof PromiseRejectionEvent;
+ FetchEvent: typeof FetchEvent;
+ TailEvent: typeof TailEvent;
+ TraceEvent: typeof TailEvent;
+ ScheduledEvent: typeof ScheduledEvent;
+ MessageEvent: typeof MessageEvent;
+ CloseEvent: typeof CloseEvent;
+ ReadableStreamDefaultReader: typeof ReadableStreamDefaultReader;
+ ReadableStreamBYOBReader: typeof ReadableStreamBYOBReader;
+ ReadableStream: typeof ReadableStream;
+ WritableStream: typeof WritableStream;
+ WritableStreamDefaultWriter: typeof WritableStreamDefaultWriter;
+ TransformStream: typeof TransformStream;
+ ByteLengthQueuingStrategy: typeof ByteLengthQueuingStrategy;
+ CountQueuingStrategy: typeof CountQueuingStrategy;
+ ErrorEvent: typeof ErrorEvent;
+ EventSource: typeof EventSource;
+ ReadableStreamBYOBRequest: typeof ReadableStreamBYOBRequest;
+ ReadableStreamDefaultController: typeof ReadableStreamDefaultController;
+ ReadableByteStreamController: typeof ReadableByteStreamController;
+ WritableStreamDefaultController: typeof WritableStreamDefaultController;
+ TransformStreamDefaultController: typeof TransformStreamDefaultController;
+ CompressionStream: typeof CompressionStream;
+ DecompressionStream: typeof DecompressionStream;
+ TextEncoderStream: typeof TextEncoderStream;
+ TextDecoderStream: typeof TextDecoderStream;
+ Headers: typeof Headers;
+ Body: typeof Body;
+ Request: typeof Request;
+ Response: typeof Response;
+ WebSocket: typeof WebSocket;
+ WebSocketPair: typeof WebSocketPair;
+ WebSocketRequestResponsePair: typeof WebSocketRequestResponsePair;
+ AbortController: typeof AbortController;
+ AbortSignal: typeof AbortSignal;
+ TextDecoder: typeof TextDecoder;
+ TextEncoder: typeof TextEncoder;
+ navigator: Navigator;
+ Navigator: typeof Navigator;
+ URL: typeof URL;
+ URLSearchParams: typeof URLSearchParams;
+ URLPattern: typeof URLPattern;
+ Blob: typeof Blob;
+ File: typeof File;
+ FormData: typeof FormData;
+ Crypto: typeof Crypto;
+ SubtleCrypto: typeof SubtleCrypto;
+ CryptoKey: typeof CryptoKey;
+ CacheStorage: typeof CacheStorage;
+ Cache: typeof Cache;
+ FixedLengthStream: typeof FixedLengthStream;
+ IdentityTransformStream: typeof IdentityTransformStream;
+ HTMLRewriter: typeof HTMLRewriter;
+}
+declare function addEventListener(
+ type: Type,
+ handler: EventListenerOrEventListenerObject,
+ options?: EventTargetAddEventListenerOptions | boolean
+): void;
+declare function removeEventListener(
+ type: Type,
+ handler: EventListenerOrEventListenerObject,
+ options?: EventTargetEventListenerOptions | boolean
+): void;
+/**
+ * Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget/dispatchEvent)
+ */
+declare function dispatchEvent(
+ event: WorkerGlobalScopeEventMap[keyof WorkerGlobalScopeEventMap]
+): boolean;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/btoa) */
+declare function btoa(data: string): string;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/atob) */
+declare function atob(data: string): string;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setTimeout) */
+declare function setTimeout(callback: (...args: any[]) => void, msDelay?: number): number;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setTimeout) */
+declare function setTimeout(
+ callback: (...args: Args) => void,
+ msDelay?: number,
+ ...args: Args
+): number;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/clearTimeout) */
+declare function clearTimeout(timeoutId: number | null): void;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setInterval) */
+declare function setInterval(callback: (...args: any[]) => void, msDelay?: number): number;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setInterval) */
+declare function setInterval(
+ callback: (...args: Args) => void,
+ msDelay?: number,
+ ...args: Args
+): number;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/clearInterval) */
+declare function clearInterval(timeoutId: number | null): void;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/queueMicrotask) */
+declare function queueMicrotask(task: Function): void;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/structuredClone) */
+declare function structuredClone(value: T, options?: StructuredSerializeOptions): T;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/reportError) */
+declare function reportError(error: any): void;
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch) */
+declare function fetch(
+ input: RequestInfo | URL,
+ init?: RequestInit
+): Promise;
+declare const self: ServiceWorkerGlobalScope;
+/**
+ * The Web Crypto API provides a set of low-level functions for common cryptographic tasks.
+ * The Workers runtime implements the full surface of this API, but with some differences in
+ * the [supported algorithms](https://developers.cloudflare.com/workers/runtime-apis/web-crypto/#supported-algorithms)
+ * compared to those implemented in most browsers.
+ *
+ * [Cloudflare Docs Reference](https://developers.cloudflare.com/workers/runtime-apis/web-crypto/)
+ */
+declare const crypto: Crypto;
+/**
+ * The Cache API allows fine grained control of reading and writing from the Cloudflare global network cache.
+ *
+ * [Cloudflare Docs Reference](https://developers.cloudflare.com/workers/runtime-apis/cache/)
+ */
+declare const caches: CacheStorage;
+declare const scheduler: Scheduler;
+/**
+ * The Workers runtime supports a subset of the Performance API, used to measure timing and performance,
+ * as well as timing of subrequests and other operations.
+ *
+ * [Cloudflare Docs Reference](https://developers.cloudflare.com/workers/runtime-apis/performance/)
+ */
+declare const performance: Performance;
+declare const Cloudflare: Cloudflare;
+declare const origin: string;
+declare const navigator: Navigator;
+interface TestController {}
+interface ExecutionContext {
+ waitUntil(promise: Promise): void;
+ passThroughOnException(): void;
+ readonly props: Props;
+}
+type ExportedHandlerFetchHandler = (
+ request: Request>,
+ env: Env,
+ ctx: ExecutionContext
+) => Response | Promise;
+type ExportedHandlerTailHandler = (
+ events: TraceItem[],
+ env: Env,
+ ctx: ExecutionContext
+) => void | Promise;
+type ExportedHandlerTraceHandler = (
+ traces: TraceItem[],
+ env: Env,
+ ctx: ExecutionContext
+) => void | Promise;
+type ExportedHandlerTailStreamHandler = (
+ event: TailStream.TailEvent,
+ env: Env,
+ ctx: ExecutionContext
+) => TailStream.TailEventHandlerType | Promise;
+type ExportedHandlerScheduledHandler = (
+ controller: ScheduledController,
+ env: Env,
+ ctx: ExecutionContext
+) => void | Promise;
+type ExportedHandlerQueueHandler = (
+ batch: MessageBatch,
+ env: Env,
+ ctx: ExecutionContext
+) => void | Promise;
+type ExportedHandlerTestHandler = (
+ controller: TestController,
+ env: Env,
+ ctx: ExecutionContext
+) => void | Promise;
+interface ExportedHandler {
+ fetch?: ExportedHandlerFetchHandler;
+ tail?: ExportedHandlerTailHandler;
+ trace?: ExportedHandlerTraceHandler;
+ tailStream?: ExportedHandlerTailStreamHandler;
+ scheduled?: ExportedHandlerScheduledHandler;
+ test?: ExportedHandlerTestHandler;
+ email?: EmailExportedHandler;
+ queue?: ExportedHandlerQueueHandler;
+}
+interface StructuredSerializeOptions {
+ transfer?: any[];
+}
+/* [MDN Reference](https://developer.mozilla.org/docs/Web/API/PromiseRejectionEvent) */
+declare abstract class PromiseRejectionEvent extends Event {
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/PromiseRejectionEvent/promise) */
+ readonly promise: Promise;
+ /* [MDN Reference](https://developer.mozilla.org/docs/Web/API/PromiseRejectionEvent/reason) */
+ readonly reason: any;
+}
+declare abstract class Navigator {
+ sendBeacon(
+ url: string,
+ body?:
+ | ReadableStream
+ | string
+ | (ArrayBuffer | ArrayBufferView)
+ | Blob
+ | FormData
+ | URLSearchParams
+ | URLSearchParams
+ ): boolean;
+ readonly userAgent: string;
+ readonly hardwareConcurrency: number;
+ readonly language: string;
+ readonly languages: string[];
+}
+interface AlarmInvocationInfo {
+ readonly isRetry: boolean;
+ readonly retryCount: number;
+}
+interface Cloudflare {
+ readonly compatibilityFlags: Record;
+}
+interface DurableObject {
+ fetch(request: Request): Response | Promise;
+ alarm?(alarmInfo?: AlarmInvocationInfo): void | Promise;
+ webSocketMessage?(ws: WebSocket, message: string | ArrayBuffer): void | Promise;
+ webSocketClose?(
+ ws: WebSocket,
+ code: number,
+ reason: string,
+ wasClean: boolean
+ ): void | Promise;
+ webSocketError?(ws: WebSocket, error: unknown): void | Promise;
+}
+type DurableObjectStub = Fetcher<
+ T,
+ "alarm" | "webSocketMessage" | "webSocketClose" | "webSocketError"
+> & {
+ readonly id: DurableObjectId;
+ readonly name?: string;
+};
+interface DurableObjectId {
+ toString(): string;
+ equals(other: DurableObjectId): boolean;
+ readonly name?: string;
+}
+declare abstract class DurableObjectNamespace<
+ T extends Rpc.DurableObjectBranded | undefined = undefined,
+> {
+ newUniqueId(options?: DurableObjectNamespaceNewUniqueIdOptions): DurableObjectId;
+ idFromName(name: string): DurableObjectId;
+ idFromString(id: string): DurableObjectId;
+ get(
+ id: DurableObjectId,
+ options?: DurableObjectNamespaceGetDurableObjectOptions
+ ): DurableObjectStub;
+ getByName(
+ name: string,
+ options?: DurableObjectNamespaceGetDurableObjectOptions
+ ): DurableObjectStub;
+ jurisdiction(jurisdiction: DurableObjectJurisdiction): DurableObjectNamespace;
+}
+type DurableObjectJurisdiction = "eu" | "fedramp" | "fedramp-high";
+interface DurableObjectNamespaceNewUniqueIdOptions {
+ jurisdiction?: DurableObjectJurisdiction;
+}
+type DurableObjectLocationHint =
+ | "wnam"
+ | "enam"
+ | "sam"
+ | "weur"
+ | "eeur"
+ | "apac"
+ | "oc"
+ | "afr"
+ | "me";
+interface DurableObjectNamespaceGetDurableObjectOptions {
+ locationHint?: DurableObjectLocationHint;
+}
+interface DurableObjectClass<_T extends Rpc.DurableObjectBranded | undefined = undefined> {}
+interface DurableObjectState {
+ waitUntil(promise: Promise): void;
+ readonly props: Props;
+ readonly id: DurableObjectId;
+ readonly storage: DurableObjectStorage;
+ container?: Container;
+ blockConcurrencyWhile(callback: () => Promise): Promise;
+ acceptWebSocket(ws: WebSocket, tags?: string[]): void;
+ getWebSockets(tag?: string): WebSocket[];
+ setWebSocketAutoResponse(maybeReqResp?: WebSocketRequestResponsePair): void;
+ getWebSocketAutoResponse(): WebSocketRequestResponsePair | null;
+ getWebSocketAutoResponseTimestamp(ws: WebSocket): Date | null;
+ setHibernatableWebSocketEventTimeout(timeoutMs?: number): void;
+ getHibernatableWebSocketEventTimeout(): number | null;
+ getTags(ws: WebSocket): string[];
+ abort(reason?: string): void;
+}
+interface DurableObjectTransaction {
+ get(key: string, options?: DurableObjectGetOptions): Promise;
+ get(keys: string[], options?: DurableObjectGetOptions): Promise