@statewalker/cellb 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +323 -2
- package/dist/adapters/files-backup.d.ts +16 -0
- package/dist/adapters/files-backup.js +32 -0
- package/dist/adapters/files-backup.js.map +1 -0
- package/dist/adapters/files-changelog.d.ts +33 -0
- package/dist/adapters/files-changelog.js +96 -0
- package/dist/adapters/files-changelog.js.map +1 -0
- package/dist/adapters/files-ltx.d.ts +35 -0
- package/dist/adapters/files-ltx.js +9 -0
- package/dist/adapters/files-ltx.js.map +1 -0
- package/dist/adapters/ltx-vfs.d.ts +21 -0
- package/dist/adapters/ltx-vfs.js +286 -0
- package/dist/adapters/ltx-vfs.js.map +1 -0
- package/dist/adapters/node-sqlite.d.ts +45 -0
- package/dist/adapters/node-sqlite.js +254 -0
- package/dist/adapters/node-sqlite.js.map +1 -0
- package/dist/adapters/wasm-page-hook.d.ts +26 -0
- package/dist/adapters/wasm-page-hook.js +55 -0
- package/dist/adapters/wasm-page-hook.js.map +1 -0
- package/dist/adapters/wasm-session.d.ts +11 -0
- package/dist/adapters/wasm-session.js +76 -0
- package/dist/adapters/wasm-session.js.map +1 -0
- package/dist/adapters/wasm-sqlite.d.ts +89 -0
- package/dist/adapters/wasm-sqlite.js +258 -0
- package/dist/adapters/wasm-sqlite.js.map +1 -0
- package/dist/bindings/assets.d.ts +26 -0
- package/dist/bindings/assets.js +260 -0
- package/dist/bindings/assets.js.map +1 -0
- package/dist/bindings/cache.d.ts +16 -0
- package/dist/bindings/cache.js +34 -0
- package/dist/bindings/cache.js.map +1 -0
- package/dist/bindings/celld-kv.d.ts +26 -0
- package/dist/bindings/celld-kv.js +81 -0
- package/dist/bindings/celld-kv.js.map +1 -0
- package/dist/bindings/celld-queues.d.ts +56 -0
- package/dist/bindings/celld-queues.js +223 -0
- package/dist/bindings/celld-queues.js.map +1 -0
- package/dist/bindings/celld-workflows.d.ts +22 -0
- package/dist/bindings/celld-workflows.js +54 -0
- package/dist/bindings/celld-workflows.js.map +1 -0
- package/dist/bindings/cron.d.ts +27 -0
- package/dist/bindings/cron.js +232 -0
- package/dist/bindings/cron.js.map +1 -0
- package/dist/bindings/d1-migrations.d.ts +22 -0
- package/dist/bindings/d1-migrations.js +32 -0
- package/dist/bindings/d1-migrations.js.map +1 -0
- package/dist/bindings/html-rewriter.d.ts +8 -0
- package/dist/bindings/html-rewriter.js +75 -0
- package/dist/bindings/html-rewriter.js.map +1 -0
- package/dist/bindings/r2-celld.d.ts +3 -0
- package/dist/bindings/r2-celld.js +113 -0
- package/dist/bindings/r2-celld.js.map +1 -0
- package/dist/bindings/r2.d.ts +236 -0
- package/dist/bindings/r2.js +419 -0
- package/dist/bindings/r2.js.map +1 -0
- package/dist/bindings/worker-loader.d.ts +83 -0
- package/dist/bindings/worker-loader.js +183 -0
- package/dist/bindings/worker-loader.js.map +1 -0
- package/dist/bindings/workers-ai.d.ts +39 -0
- package/dist/bindings/workers-ai.js +175 -0
- package/dist/bindings/workers-ai.js.map +1 -0
- package/dist/browser.d.ts +7 -0
- package/dist/browser.js +8 -0
- package/dist/browser.js.map +1 -0
- package/dist/bucket/celld-cells.d.ts +86 -0
- package/dist/bucket/celld-cells.js +273 -0
- package/dist/bucket/celld-cells.js.map +1 -0
- package/dist/bucket/celld-format.d.ts +10 -0
- package/dist/bucket/celld-format.js +27 -0
- package/dist/bucket/celld-format.js.map +1 -0
- package/dist/bucket/idb-object-store.d.ts +9 -0
- package/dist/bucket/idb-object-store.js +73 -0
- package/dist/bucket/idb-object-store.js.map +1 -0
- package/dist/bucket/ltx-log.d.ts +34 -0
- package/dist/bucket/ltx-log.js +289 -0
- package/dist/bucket/ltx-log.js.map +1 -0
- package/dist/bucket/object-store.d.ts +51 -0
- package/dist/bucket/object-store.js +114 -0
- package/dist/bucket/object-store.js.map +1 -0
- package/dist/bucket/s3-object-store.d.ts +25 -0
- package/dist/bucket/s3-object-store.js +151 -0
- package/dist/bucket/s3-object-store.js.map +1 -0
- package/dist/bucket/sqlite-object-store.d.ts +10 -0
- package/dist/bucket/sqlite-object-store.js +107 -0
- package/dist/bucket/sqlite-object-store.js.map +1 -0
- package/dist/core/alarms.d.ts +27 -0
- package/dist/core/alarms.js +88 -0
- package/dist/core/alarms.js.map +1 -0
- package/dist/core/async-context.d.ts +34 -0
- package/dist/core/async-context.js +50 -0
- package/dist/core/async-context.js.map +1 -0
- package/dist/core/celld-schema.d.ts +14 -0
- package/dist/core/celld-schema.js +34 -0
- package/dist/core/celld-schema.js.map +1 -0
- package/dist/core/durable-object.d.ts +28 -0
- package/dist/core/durable-object.js +31 -0
- package/dist/core/durable-object.js.map +1 -0
- package/dist/core/gates.d.ts +33 -0
- package/dist/core/gates.js +89 -0
- package/dist/core/gates.js.map +1 -0
- package/dist/core/handles.d.ts +90 -0
- package/dist/core/handles.js +224 -0
- package/dist/core/handles.js.map +1 -0
- package/dist/core/id.d.ts +19 -0
- package/dist/core/id.js +64 -0
- package/dist/core/id.js.map +1 -0
- package/dist/core/namespace.d.ts +38 -0
- package/dist/core/namespace.js +141 -0
- package/dist/core/namespace.js.map +1 -0
- package/dist/core/object-host.d.ts +91 -0
- package/dist/core/object-host.js +616 -0
- package/dist/core/object-host.js.map +1 -0
- package/dist/core/request-body.d.ts +9 -0
- package/dist/core/request-body.js +55 -0
- package/dist/core/request-body.js.map +1 -0
- package/dist/core/runtime.d.ts +121 -0
- package/dist/core/runtime.js +366 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/shard.d.ts +7 -0
- package/dist/core/shard.js +10 -0
- package/dist/core/shard.js.map +1 -0
- package/dist/core/sql-split.d.ts +15 -0
- package/dist/core/sql-split.js +101 -0
- package/dist/core/sql-split.js.map +1 -0
- package/dist/core/sql-storage.d.ts +53 -0
- package/dist/core/sql-storage.js +407 -0
- package/dist/core/sql-storage.js.map +1 -0
- package/dist/core/state.d.ts +44 -0
- package/dist/core/state.js +93 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/storage.d.ts +103 -0
- package/dist/core/storage.js +351 -0
- package/dist/core/storage.js.map +1 -0
- package/dist/core/worker-rejections.d.ts +21 -0
- package/dist/core/worker-rejections.js +55 -0
- package/dist/core/worker-rejections.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/isolate/browser.d.ts +16 -0
- package/dist/isolate/browser.js +37 -0
- package/dist/isolate/browser.js.map +1 -0
- package/dist/isolate/host.d.ts +24 -0
- package/dist/isolate/host.js +74 -0
- package/dist/isolate/host.js.map +1 -0
- package/dist/isolate/isolate-worker.d.ts +1 -0
- package/dist/isolate/isolate-worker.js +53 -0
- package/dist/isolate/isolate-worker.js.map +1 -0
- package/dist/isolate/isolate.d.ts +10 -0
- package/dist/isolate/isolate.js +169 -0
- package/dist/isolate/isolate.js.map +1 -0
- package/dist/isolate/node-entry.d.ts +1 -0
- package/dist/isolate/node-entry.js +12 -0
- package/dist/isolate/node-entry.js.map +1 -0
- package/dist/isolate/protocol.d.ts +66 -0
- package/dist/isolate/protocol.js +205 -0
- package/dist/isolate/protocol.js.map +1 -0
- package/dist/ltx/crc64.d.ts +6 -0
- package/dist/ltx/crc64.js +46 -0
- package/dist/ltx/crc64.js.map +1 -0
- package/dist/ltx/ltx-page-server.d.ts +65 -0
- package/dist/ltx/ltx-page-server.js +309 -0
- package/dist/ltx/ltx-page-server.js.map +1 -0
- package/dist/ltx/ltx-pages.d.ts +81 -0
- package/dist/ltx/ltx-pages.js +315 -0
- package/dist/ltx/ltx-pages.js.map +1 -0
- package/dist/ltx/ltx-store-worker.d.ts +1 -0
- package/dist/ltx/ltx-store-worker.js +38 -0
- package/dist/ltx/ltx-store-worker.js.map +1 -0
- package/dist/ltx/ltx.d.ts +45 -0
- package/dist/ltx/ltx.js +203 -0
- package/dist/ltx/ltx.js.map +1 -0
- package/dist/ltx/lz4.d.ts +9 -0
- package/dist/ltx/lz4.js +156 -0
- package/dist/ltx/lz4.js.map +1 -0
- package/dist/ltx/opfs-sync-files.d.ts +23 -0
- package/dist/ltx/opfs-sync-files.js +191 -0
- package/dist/ltx/opfs-sync-files.js.map +1 -0
- package/dist/ltx/xxh32.d.ts +1 -0
- package/dist/ltx/xxh32.js +43 -0
- package/dist/ltx/xxh32.js.map +1 -0
- package/dist/miniflare-compat/blob-service.d.ts +13 -0
- package/dist/miniflare-compat/blob-service.js +66 -0
- package/dist/miniflare-compat/blob-service.js.map +1 -0
- package/dist/miniflare-compat/kv-binding.d.ts +44 -0
- package/dist/miniflare-compat/kv-binding.js +99 -0
- package/dist/miniflare-compat/kv-binding.js.map +1 -0
- package/dist/miniflare-compat/shims/assert.d.ts +15 -0
- package/dist/miniflare-compat/shims/assert.js +24 -0
- package/dist/miniflare-compat/shims/assert.js.map +1 -0
- package/dist/miniflare-compat/shims/workerd-cloudflare.d.ts +7 -0
- package/dist/miniflare-compat/shims/workerd-cloudflare.js +6 -0
- package/dist/miniflare-compat/shims/workerd-cloudflare.js.map +1 -0
- package/dist/miniflare-compat/shims/workerd-globals.d.ts +1 -0
- package/dist/miniflare-compat/shims/workerd-globals.js +30 -0
- package/dist/miniflare-compat/shims/workerd-globals.js.map +1 -0
- package/dist/miniflare-compat/shims/workerd-internal.d.ts +20 -0
- package/dist/miniflare-compat/shims/workerd-internal.js +23 -0
- package/dist/miniflare-compat/shims/workerd-internal.js.map +1 -0
- package/dist/miniflare-compat/shims/workerd-performance.d.ts +4 -0
- package/dist/miniflare-compat/shims/workerd-performance.js +17 -0
- package/dist/miniflare-compat/shims/workerd-performance.js.map +1 -0
- package/dist/miniflare-compat/simulator-fetcher.d.ts +9 -0
- package/dist/miniflare-compat/simulator-fetcher.js +14 -0
- package/dist/miniflare-compat/simulator-fetcher.js.map +1 -0
- package/dist/miniflare-compat/vendored.d.ts +15 -0
- package/dist/miniflare-compat/vendored.js +27 -0
- package/dist/miniflare-compat/vendored.js.map +1 -0
- package/dist/node-compat/async_hooks.d.ts +22 -0
- package/dist/node-compat/async_hooks.js +176 -0
- package/dist/node-compat/async_hooks.js.map +1 -0
- package/dist/node-compat/browser-registry.d.ts +3 -0
- package/dist/node-compat/browser-registry.js +39 -0
- package/dist/node-compat/browser-registry.js.map +1 -0
- package/dist/node-compat/crypto.d.ts +60 -0
- package/dist/node-compat/crypto.js +143 -0
- package/dist/node-compat/crypto.js.map +1 -0
- package/dist/node-compat/diagnostics_channel.d.ts +27 -0
- package/dist/node-compat/diagnostics_channel.js +46 -0
- package/dist/node-compat/diagnostics_channel.js.map +1 -0
- package/dist/node-compat/fs.d.ts +35 -0
- package/dist/node-compat/fs.js +40 -0
- package/dist/node-compat/fs.js.map +1 -0
- package/dist/node-compat/globals.d.ts +3 -0
- package/dist/node-compat/globals.js +4 -0
- package/dist/node-compat/globals.js.map +1 -0
- package/dist/node-compat/install.d.ts +5 -0
- package/dist/node-compat/install.js +12 -0
- package/dist/node-compat/install.js.map +1 -0
- package/dist/node-compat/module.d.ts +12 -0
- package/dist/node-compat/module.js +36 -0
- package/dist/node-compat/module.js.map +1 -0
- package/dist/node-compat/modules.d.ts +8 -0
- package/dist/node-compat/modules.js +23 -0
- package/dist/node-compat/modules.js.map +1 -0
- package/dist/node-compat/os.d.ts +36 -0
- package/dist/node-compat/os.js +36 -0
- package/dist/node-compat/os.js.map +1 -0
- package/dist/node-compat/process.d.ts +14 -0
- package/dist/node-compat/process.js +16 -0
- package/dist/node-compat/process.js.map +1 -0
- package/dist/node-compat/shims.d.ts +4 -0
- package/dist/node.d.ts +5 -0
- package/dist/node.js +6 -0
- package/dist/node.js.map +1 -0
- package/dist/peer/celld-peer.d.ts +53 -0
- package/dist/peer/celld-peer.js +555 -0
- package/dist/peer/celld-peer.js.map +1 -0
- package/dist/ports.d.ts +183 -0
- package/dist/ports.js +10 -0
- package/dist/ports.js.map +1 -0
- package/dist/project/browser-bundle.d.ts +17 -0
- package/dist/project/browser-bundle.js +125 -0
- package/dist/project/browser-bundle.js.map +1 -0
- package/dist/project/browser-cookies.d.ts +12 -0
- package/dist/project/browser-cookies.js +90 -0
- package/dist/project/browser-cookies.js.map +1 -0
- package/dist/project/browser-host.d.ts +173 -0
- package/dist/project/browser-host.js +200 -0
- package/dist/project/browser-host.js.map +1 -0
- package/dist/project/browser-modules.d.ts +17 -0
- package/dist/project/browser-modules.js +89 -0
- package/dist/project/browser-modules.js.map +1 -0
- package/dist/project/browser-shards.d.ts +62 -0
- package/dist/project/browser-shards.js +210 -0
- package/dist/project/browser-shards.js.map +1 -0
- package/dist/project/browser-tabs.d.ts +103 -0
- package/dist/project/browser-tabs.js +418 -0
- package/dist/project/browser-tabs.js.map +1 -0
- package/dist/project/cloudflare-email.d.ts +8 -0
- package/dist/project/cloudflare-email.js +11 -0
- package/dist/project/cloudflare-email.js.map +1 -0
- package/dist/project/cloudflare-workers.d.ts +12 -0
- package/dist/project/cloudflare-workers.js +16 -0
- package/dist/project/cloudflare-workers.js.map +1 -0
- package/dist/project/host-modules.d.ts +4 -0
- package/dist/project/host-modules.js +40 -0
- package/dist/project/host-modules.js.map +1 -0
- package/dist/project/jsonc.d.ts +2 -0
- package/dist/project/jsonc.js +27 -0
- package/dist/project/jsonc.js.map +1 -0
- package/dist/project/lower-await.d.ts +2 -0
- package/dist/project/lower-await.js +151 -0
- package/dist/project/lower-await.js.map +1 -0
- package/dist/project/node-project.d.ts +38 -0
- package/dist/project/node-project.js +362 -0
- package/dist/project/node-project.js.map +1 -0
- package/dist/project/own-module.d.ts +6 -0
- package/dist/project/own-module.js +13 -0
- package/dist/project/own-module.js.map +1 -0
- package/dist/project/scheduler.d.ts +2 -0
- package/dist/project/scheduler.js +3 -0
- package/dist/project/scheduler.js.map +1 -0
- package/dist/project/site.d.ts +74 -0
- package/dist/project/site.js +206 -0
- package/dist/project/site.js.map +1 -0
- package/dist/project/virtual-modules.d.ts +3 -0
- package/dist/project/worker-scope.d.ts +27 -0
- package/dist/project/worker-scope.js +46 -0
- package/dist/project/worker-scope.js.map +1 -0
- package/dist/project/workerd-message-channel.d.ts +13 -0
- package/dist/project/workerd-message-channel.js +137 -0
- package/dist/project/workerd-message-channel.js.map +1 -0
- package/dist/project/workers-global-names.d.ts +6 -0
- package/dist/project/workers-global-names.js +15 -0
- package/dist/project/workers-global-names.js.map +1 -0
- package/dist/project/workers-globals-module.d.ts +8 -0
- package/dist/project/workers-globals-module.js +9 -0
- package/dist/project/workers-globals-module.js.map +1 -0
- package/dist/project/workers-globals.d.ts +9 -0
- package/dist/project/workers-globals.js +19 -0
- package/dist/project/workers-globals.js.map +1 -0
- package/dist/project/wrangler.d.ts +116 -0
- package/dist/project/wrangler.js +342 -0
- package/dist/project/wrangler.js.map +1 -0
- package/dist/router/cell-router.d.ts +72 -0
- package/dist/router/cell-router.js +247 -0
- package/dist/router/cell-router.js.map +1 -0
- package/dist/router/shard-worker.d.ts +44 -0
- package/dist/router/shard-worker.js +163 -0
- package/dist/router/shard-worker.js.map +1 -0
- package/dist/transport/cells-http.d.ts +25 -0
- package/dist/transport/cells-http.js +141 -0
- package/dist/transport/cells-http.js.map +1 -0
- package/dist/transport/cells-link.d.ts +27 -0
- package/dist/transport/cells-link.js +71 -0
- package/dist/transport/cells-link.js.map +1 -0
- package/dist/transport/port.d.ts +26 -0
- package/dist/transport/port.js +100 -0
- package/dist/transport/port.js.map +1 -0
- package/dist/v8/codec.d.ts +6 -0
- package/dist/v8/codec.js +9 -0
- package/dist/v8/codec.js.map +1 -0
- package/dist/v8/serialize.d.ts +10 -0
- package/dist/v8/serialize.js +601 -0
- package/dist/v8/serialize.js.map +1 -0
- package/dist/ws/client.d.ts +25 -0
- package/dist/ws/client.js +203 -0
- package/dist/ws/client.js.map +1 -0
- package/dist/ws/control.d.ts +48 -0
- package/dist/ws/control.js +44 -0
- package/dist/ws/control.js.map +1 -0
- package/dist/ws/frames.d.ts +38 -0
- package/dist/ws/frames.js +39 -0
- package/dist/ws/frames.js.map +1 -0
- package/dist/ws/server.d.ts +99 -0
- package/dist/ws/server.js +295 -0
- package/dist/ws/server.js.map +1 -0
- package/dist/ws/sw-connector.d.ts +10 -0
- package/dist/ws/sw-connector.js +25 -0
- package/dist/ws/sw-connector.js.map +1 -0
- package/dist/ws/upgrade.d.ts +28 -0
- package/dist/ws/upgrade.js +75 -0
- package/dist/ws/upgrade.js.map +1 -0
- package/package.json +111 -3
- package/vendor/celld/LICENSE +202 -0
- package/vendor/celld/kv.js +1131 -0
- package/vendor/celld/queues.js +1656 -0
- package/vendor/celld/workflows.js +1610 -0
- package/vendor/html-rewriter-wasm/html_rewriter.js +925 -0
- package/vendor/html-rewriter-wasm/html_rewriter_bg.wasm +0 -0
- package/vendor/miniflare/d1-api.js +738 -0
- package/vendor/miniflare/d1-database.js +6978 -0
- package/vendor/miniflare/kv-namespace.js +3061 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-cookies.js","sourceRoot":"","sources":["../../src/project/browser-cookies.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Cookies for Workers served through a ServiceWorker. A browser hands a ServiceWorker no\n * `Cookie` header and ignores `Set-Cookie` on the responses it builds, so the router does what\n * the browser's network stack would: it sends the page's cookies to the Worker under\n * `x-cellb-cookie` (an ingress that carries it gets the Worker's `Set-Cookie` values back under\n * `x-cellb-set-cookie`, cells-http.ts), and stores those through the Cookie Store API.\n *\n * What differs from a server's cookies: they are written by script, so `HttpOnly` cannot be set\n * and they are readable by the page's own scripts; `Domain` is ignored (the origin's host); and\n * every cookie is stored with `Path=/` and sent with every request. Chromium lets a\n * ServiceWorker read cookies only for its default URL (`getAll({ url })` throws \"URL must be\n * within Service Worker scope\" for any URL), so a cookie scoped to `/_emdash/` could not be read\n * back at all.\n */\nimport { H } from \"../transport/cells-link.js\";\n\ninterface CookieStoreLike {\n getAll(options?: { url?: string }): Promise<{ name: string; value: string }[]>;\n set(options: {\n name: string;\n value: string;\n path?: string;\n expires?: number | null;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n partitioned?: boolean;\n }): Promise<void>;\n delete(options: { name: string; path?: string }): Promise<void>;\n}\n\nconst storeOf = (scope: unknown): CookieStoreLike | undefined =>\n (scope as { cookieStore?: CookieStoreLike }).cookieStore;\n\n/** Headers for an ingress request: the request's own, plus the cookies its URL would carry. */\nexport async function withPageCookies(scope: unknown, req: Request): Promise<Headers> {\n const headers = new Headers(req.headers);\n const store = storeOf(scope);\n if (!store) return headers; // no Cookie Store API: no cookies either way\n const cookies = await store.getAll().catch(() => []);\n headers.set(H.cookie, cookies.map((c) => `${c.name}=${c.value}`).join(\"; \"));\n return headers;\n}\n\n/** One `Set-Cookie` value as Cookie Store options; `expires: 0` deletes. */\nexport function parseSetCookie(value: string, now = Date.now()) {\n const [pair, ...attrs] = value.split(\";\");\n const eq = pair.indexOf(\"=\");\n const cookie: {\n name: string;\n value: string;\n path?: string;\n expires?: number;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n } = {\n name: (eq < 0 ? \"\" : pair.slice(0, eq)).trim(),\n value: (eq < 0 ? pair : pair.slice(eq + 1)).trim(),\n };\n let maxAge: number | undefined;\n for (const attr of attrs) {\n const i = attr.indexOf(\"=\");\n const key = (i < 0 ? attr : attr.slice(0, i)).trim().toLowerCase();\n const val = i < 0 ? \"\" : attr.slice(i + 1).trim();\n if (key === \"path\") cookie.path = val || \"/\";\n else if (key === \"expires\") {\n const t = Date.parse(val);\n if (!Number.isNaN(t)) cookie.expires = t;\n } else if (key === \"max-age\" && /^-?\\d+$/.test(val)) maxAge = Number(val);\n else if (key === \"samesite\") {\n const s = val.toLowerCase();\n if (s === \"strict\" || s === \"lax\" || s === \"none\") cookie.sameSite = s;\n }\n }\n // Max-Age wins over Expires (RFC 6265); zero or less deletes.\n if (maxAge !== undefined) cookie.expires = maxAge <= 0 ? 0 : now + maxAge * 1000;\n return cookie;\n}\n\n/** Stores the Worker's tunneled Set-Cookie values and returns the response without them. */\nexport async function applyWorkerCookies(scope: unknown, res: Response): Promise<Response> {\n const tunneled = res.headers.get(H.setCookie);\n if (tunneled === null) return res;\n const store = storeOf(scope);\n for (const raw of tunneled.split(\",\").filter(Boolean)) {\n const c = parseSetCookie(decodeURIComponent(raw));\n if (!c.name || !store) continue;\n try {\n if (c.expires !== undefined && c.expires <= Date.now())\n await store.delete({ name: c.name, path: \"/\" });\n else\n await store.set({\n name: c.name,\n value: c.value,\n path: \"/\",\n expires: c.expires ?? null,\n sameSite: c.sameSite ?? \"lax\",\n });\n } catch (err) {\n console.warn(`cellb: cookie ${c.name} not stored: ${(err as Error)?.message ?? err}`);\n }\n }\n const headers = new Headers(res.headers);\n headers.delete(H.setCookie);\n return new Response(res.body, { status: res.status, statusText: res.statusText, headers });\n}\n"]}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import type { AssetFiles } from "../bindings/assets.js";
|
|
2
|
+
import type { WorkersAiOptions } from "../bindings/workers-ai.js";
|
|
3
|
+
import { type ObjectStore } from "../bucket/object-store.js";
|
|
4
|
+
import type { CellRuntimeOptions } from "../core/runtime.js";
|
|
5
|
+
import { type WranglerConfig } from "./wrangler.js";
|
|
6
|
+
/**
|
|
7
|
+
* Where a browser-hosted project keeps its cells when they must outlive the page or move to
|
|
8
|
+
* other nodes: a celld fleet bucket. Cells, facets and alarms are then exactly celld's
|
|
9
|
+
* (ownership in `own.json`, LTX logs, wake index) and R2 objects live in it too, so the same
|
|
10
|
+
* cells can be served by this browser, by other browsers and by celld nodes, in turn.
|
|
11
|
+
*
|
|
12
|
+
* - `s3`: an S3-compatible bucket, reached directly (the bucket must allow CORS for the page's
|
|
13
|
+
* origin: methods GET/PUT/DELETE/HEAD, request headers `authorization`, `content-type`,
|
|
14
|
+
* `x-amz-*`, `if-match`, `if-none-match`; exposed headers `etag`, `last-modified`,
|
|
15
|
+
* `x-amz-meta-celld-r2`) or through a same-origin proxy (`endpoint` = the proxy,
|
|
16
|
+
* `signAs` = the real endpoint: SigV4 signs the real host and path).
|
|
17
|
+
* - `opfs`: a bucket in this origin's OPFS — persistence without a server. Conditional writes
|
|
18
|
+
* are atomic only within one writer, so one tab or worker at a time should own its cells.
|
|
19
|
+
* - `store`: any ObjectStore.
|
|
20
|
+
*/
|
|
21
|
+
export type BrowserBucket = {
|
|
22
|
+
s3: {
|
|
23
|
+
endpoint: string;
|
|
24
|
+
signAs?: string;
|
|
25
|
+
bucket: string;
|
|
26
|
+
prefix?: string;
|
|
27
|
+
region?: string;
|
|
28
|
+
accessKeyId: string;
|
|
29
|
+
secretAccessKey: string;
|
|
30
|
+
};
|
|
31
|
+
node: string;
|
|
32
|
+
leaseTtlMs?: number;
|
|
33
|
+
} | {
|
|
34
|
+
opfs: string;
|
|
35
|
+
node: string;
|
|
36
|
+
leaseTtlMs?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* `idb`: a bucket in this origin's IndexedDB (atomic conditional writes across tabs and
|
|
40
|
+
* workers). Cells then run SQLite in memory and persist through the bucket's page-level logs:
|
|
41
|
+
* no OPFS pool, so any number of workers can serve cells at once.
|
|
42
|
+
*/
|
|
43
|
+
| {
|
|
44
|
+
idb: string;
|
|
45
|
+
node: string;
|
|
46
|
+
leaseTtlMs?: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* `ltx`: cells as celld keeps them, LTX files (a snapshot and one file per commit) in an OPFS
|
|
50
|
+
* directory, read page by page (a SQLite VFS over a store worker): no OPFS pool, and a
|
|
51
|
+
* cell's memory is its page cache, not its database. A cell is folded into one snapshot
|
|
52
|
+
* (streamed) past `compactAfter` files (default 64), or once the files after its snapshot hold
|
|
53
|
+
* more than half of it. See docs/browser-host.md.
|
|
54
|
+
*/
|
|
55
|
+
| {
|
|
56
|
+
ltx: string;
|
|
57
|
+
node: string;
|
|
58
|
+
leaseTtlMs?: number;
|
|
59
|
+
compactAfter?: number;
|
|
60
|
+
/**
|
|
61
|
+
* The cells' FilesApi in the store worker: OPFS through synchronous handles (default,
|
|
62
|
+
* `opfs-sync`), OPFS through its asynchronous API (`opfs`), or memory (nothing kept).
|
|
63
|
+
*/
|
|
64
|
+
files?: "opfs" | "opfs-sync" | "memory";
|
|
65
|
+
} | {
|
|
66
|
+
store: ObjectStore;
|
|
67
|
+
node: string;
|
|
68
|
+
leaseTtlMs?: number;
|
|
69
|
+
};
|
|
70
|
+
export interface BrowserProjectOptions {
|
|
71
|
+
config: WranglerConfig;
|
|
72
|
+
/**
|
|
73
|
+
* The project's Worker code, imported in this realm once its Workers globals (and with
|
|
74
|
+
* nodejs_compat `Buffer` and `process`) are installed:
|
|
75
|
+
* - `bundle`: one ES module built for browsers (`bundleWorkerForBrowser`), whose
|
|
76
|
+
* `cloudflare:workers` is `PROJECT_WORKERS_MODULE_SHIM` and whose Workers globals read
|
|
77
|
+
* `globalThis.__cellsGlobals`
|
|
78
|
+
* (`null`: the project has no `main`). Worker Loader code becomes Blob-URL modules.
|
|
79
|
+
* - `site`: the base URL of the project's site (`createProjectSite`, hosted by
|
|
80
|
+
* webrun-site-host). `main` and Worker Loader code are imported from it.
|
|
81
|
+
*/
|
|
82
|
+
code: {
|
|
83
|
+
bundle: string | null;
|
|
84
|
+
} | {
|
|
85
|
+
site: string;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* A Dedicated Worker script that serves one loaded Worker (`serveIsolate`): Worker Loader
|
|
89
|
+
* code then runs isolated, one Dedicated Worker per loaded Worker, as celld's isolates.
|
|
90
|
+
* The package ships one: `@statewalker/cellb/isolate-worker`.
|
|
91
|
+
*/
|
|
92
|
+
isolateScript?: URL;
|
|
93
|
+
/** An initialized SQLite WASM module (`@sqlite.org/sqlite-wasm`). */
|
|
94
|
+
sqlite3: unknown;
|
|
95
|
+
/** OPFS sahpool name for this host's SQLite files (one pool per worker). */
|
|
96
|
+
pool: string;
|
|
97
|
+
/** OPFS directory for the project's FilesApi (Workers' fs-like bindings, R2 without bucket). */
|
|
98
|
+
filesDir: string;
|
|
99
|
+
assetFiles?: AssetFiles;
|
|
100
|
+
bucket?: BrowserBucket;
|
|
101
|
+
/**
|
|
102
|
+
* Cells this runtime does not host: where to send their events (a `Send` over a MessagePort
|
|
103
|
+
* to the runtime that hosts them, `linkOverPort`), or undefined to host the cell here. With
|
|
104
|
+
* one runtime per worker and `shardOf` as the placement, cells run in parallel threads.
|
|
105
|
+
*/
|
|
106
|
+
route?: CellRuntimeOptions["route"];
|
|
107
|
+
/** The OpenAI-compatible endpoint behind the project's `ai` binding (Workers AI). */
|
|
108
|
+
ai?: WorkersAiOptions;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* A project's runtime in this worker: installs the Workers globals, imports the code and
|
|
112
|
+
* builds its Worker Loader; `close()` also releases the node's bucket lease.
|
|
113
|
+
*/
|
|
114
|
+
export declare function browserProjectRuntime(opts: BrowserProjectOptions): Promise<{
|
|
115
|
+
runtime: import("../core/runtime.js").CellRuntime;
|
|
116
|
+
unsupported: string[];
|
|
117
|
+
bucket: {
|
|
118
|
+
ownership: {
|
|
119
|
+
tryAcquire(cellKey: string): Promise<{
|
|
120
|
+
name: string;
|
|
121
|
+
epoch: number;
|
|
122
|
+
lost: AbortSignal;
|
|
123
|
+
release: () => Promise<void>;
|
|
124
|
+
} | undefined>;
|
|
125
|
+
};
|
|
126
|
+
durability: import("../ports.js").CellDurability & import("../ports.js").CellBackup & {
|
|
127
|
+
logCommit: import("../ports.js").CellDurability["committed"];
|
|
128
|
+
} & {
|
|
129
|
+
begin(cellKey: string, epoch: number): void;
|
|
130
|
+
forget(cellKey: string): void;
|
|
131
|
+
} & {
|
|
132
|
+
wakes(): Promise<{
|
|
133
|
+
cellKey: string;
|
|
134
|
+
className: string;
|
|
135
|
+
at: number;
|
|
136
|
+
}[]>;
|
|
137
|
+
};
|
|
138
|
+
backup: import("../ports.js").CellDurability & import("../ports.js").CellBackup & {
|
|
139
|
+
logCommit: import("../ports.js").CellDurability["committed"];
|
|
140
|
+
} & {
|
|
141
|
+
begin(cellKey: string, epoch: number): void;
|
|
142
|
+
forget(cellKey: string): void;
|
|
143
|
+
} & {
|
|
144
|
+
wakes(): Promise<{
|
|
145
|
+
cellKey: string;
|
|
146
|
+
className: string;
|
|
147
|
+
at: number;
|
|
148
|
+
}[]>;
|
|
149
|
+
};
|
|
150
|
+
objects: ObjectStore & {
|
|
151
|
+
close?(): void;
|
|
152
|
+
};
|
|
153
|
+
probe(challenge: string): Promise<{
|
|
154
|
+
version: number;
|
|
155
|
+
node: string;
|
|
156
|
+
advertise: string;
|
|
157
|
+
challenge: string;
|
|
158
|
+
signature: string;
|
|
159
|
+
}>;
|
|
160
|
+
advertise(address: string): Promise<void>;
|
|
161
|
+
close(): Promise<void>;
|
|
162
|
+
} | undefined;
|
|
163
|
+
close: () => Promise<void>;
|
|
164
|
+
}>;
|
|
165
|
+
/**
|
|
166
|
+
* workerd fills `process.env` with the project's text `vars` under nodejs_compat from
|
|
167
|
+
* compatibility date 2025-04-01 (`nodejs_compat_populate_process_env`), unless
|
|
168
|
+
* `nodejs_compat_do_not_populate_process_env` is set. Frameworks read their settings there
|
|
169
|
+
* (EmDash's `EMDASH_SITE_URL`, for one).
|
|
170
|
+
*/
|
|
171
|
+
export declare function populatesProcessEnv(config: WranglerConfig): boolean;
|
|
172
|
+
/** The text `vars` of a project, as `process.env` holds them. */
|
|
173
|
+
export declare function processEnvOf(config: WranglerConfig): Record<string, string>;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { BrowserFilesApi } from "@statewalker/webrun-files-browser";
|
|
2
|
+
import { installLtxVfs } from "../adapters/ltx-vfs.js";
|
|
3
|
+
import { sahpoolOpener, WasmSqliteDriver, wasmMemoryOpener } from "../adapters/wasm-sqlite.js";
|
|
4
|
+
import { celldBucket } from "../bucket/celld-cells.js";
|
|
5
|
+
import { idbObjectStore } from "../bucket/idb-object-store.js";
|
|
6
|
+
import { filesApiObjectStore } from "../bucket/object-store.js";
|
|
7
|
+
import { s3ObjectStore } from "../bucket/s3-object-store.js";
|
|
8
|
+
import { browserIsolatedLoader } from "../isolate/browser.js";
|
|
9
|
+
import { installAsyncContext } from "../node-compat/async_hooks.js";
|
|
10
|
+
import { installNodeGlobals } from "../node-compat/install.js";
|
|
11
|
+
import { browserModuleLoader } from "./browser-modules.js";
|
|
12
|
+
import * as workersModule from "./cloudflare-workers.js";
|
|
13
|
+
import { siteModuleLoader, workersHostRegistry } from "./site.js";
|
|
14
|
+
import { workerScope } from "./worker-scope.js";
|
|
15
|
+
import * as workersGlobals from "./workers-globals-module.js";
|
|
16
|
+
import { createProjectRuntime, loadTimeEnv } from "./wrangler.js";
|
|
17
|
+
async function bucketStore(b) {
|
|
18
|
+
if ("store" in b)
|
|
19
|
+
return b.store;
|
|
20
|
+
if ("s3" in b)
|
|
21
|
+
return s3ObjectStore({ region: "us-east-1", ...b.s3 });
|
|
22
|
+
if ("idb" in b)
|
|
23
|
+
return idbObjectStore(b.idb);
|
|
24
|
+
if ("ltx" in b)
|
|
25
|
+
throw new Error("an ltx directory is cell storage, not a bucket");
|
|
26
|
+
const root = await navigator.storage.getDirectory();
|
|
27
|
+
return filesApiObjectStore(new BrowserFilesApi({ rootHandle: await root.getDirectoryHandle(b.opfs, { create: true }) }), "");
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Cells on the LTX VFS: a store worker owns the OPFS directory; each cell is a SQLite database
|
|
31
|
+
* whose main file is its LTX files, read page by page (src/adapters/ltx-vfs.ts).
|
|
32
|
+
*/
|
|
33
|
+
async function ltxOpener(sqlite3, dir, compactAfter, files) {
|
|
34
|
+
const store = new Worker(new URL("../ltx/ltx-store-worker.js", import.meta.url) /* `.js` in dist/ (scripts/build.mjs) */, { type: "module" });
|
|
35
|
+
const sab = new SharedArrayBuffer(8 + 16 * 65536); // room for a read-ahead run of 64 KiB pages
|
|
36
|
+
// Wait until the store worker runs before any synchronous call: a nested worker is started
|
|
37
|
+
// (its script fetched) through this worker's event loop, which Atomics.wait would block.
|
|
38
|
+
const ready = new Promise((resolve, reject) => {
|
|
39
|
+
store.addEventListener("message", (e) => e.data?.op === "ready" && resolve(), { once: false });
|
|
40
|
+
store.addEventListener("error", (e) => reject(new Error(`ltx store worker: ${e.message}`)));
|
|
41
|
+
});
|
|
42
|
+
store.postMessage({ op: "init", sab, dir, compactAfter, files });
|
|
43
|
+
await ready;
|
|
44
|
+
const { name } = installLtxVfs(sqlite3, { sab, post: (m) => store.postMessage(m) });
|
|
45
|
+
const s3 = sqlite3;
|
|
46
|
+
const open = (cellKey) => {
|
|
47
|
+
const db = new s3.oo1.DB({ filename: cellKey, vfs: name, flags: "c" });
|
|
48
|
+
db.exec("PRAGMA journal_mode=MEMORY; PRAGMA synchronous=FULL;");
|
|
49
|
+
// SQLite's C API for inTransaction() only (no page hook or session capture on this VFS).
|
|
50
|
+
return new WasmSqliteDriver(db, undefined, undefined, sqlite3.capi);
|
|
51
|
+
};
|
|
52
|
+
return Object.assign(open, {
|
|
53
|
+
release() {
|
|
54
|
+
store.terminate();
|
|
55
|
+
},
|
|
56
|
+
reserve: async (n) => n,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** Installs the Workers globals the code reads, then imports its `main`. */
|
|
60
|
+
async function importWorkerCode(config, code, scope) {
|
|
61
|
+
const flags = config.compatibility_flags ?? [];
|
|
62
|
+
const nodeCompat = flags.some((f) => f.startsWith("nodejs_compat"));
|
|
63
|
+
if (nodeCompat) {
|
|
64
|
+
installNodeGlobals();
|
|
65
|
+
// node:* for bundles built with cellbHostModule (another bundler than bundleWorkerForBrowser);
|
|
66
|
+
// loaded after installNodeGlobals(), as the npm `util` polyfill reads `process`.
|
|
67
|
+
globalThis.__cellsNodeModules = (await import("../node-compat/browser-registry.js")).nodeRegistryEntries;
|
|
68
|
+
if (populatesProcessEnv(config)) {
|
|
69
|
+
const env = processEnvOf(config);
|
|
70
|
+
// The bundle's own `process` reads it when evaluated; a site's modules use this realm's.
|
|
71
|
+
globalThis.__cellsProcessEnv = env;
|
|
72
|
+
Object.assign(globalThis.process.env, env);
|
|
73
|
+
}
|
|
74
|
+
// node:async_hooks: continuations carry their AsyncLocalStorage stores (with AsyncContext
|
|
75
|
+
// the engine does, and this installs nothing). The code's awaits are lowered so that they go
|
|
76
|
+
// through them: by bundleWorkerForBrowser for a bundle, by createProjectSite (nodeCompat) for
|
|
77
|
+
// a site's modules.
|
|
78
|
+
installAsyncContext();
|
|
79
|
+
}
|
|
80
|
+
const globals = {
|
|
81
|
+
...workersGlobals,
|
|
82
|
+
Request: workersGlobals.CellsRequest,
|
|
83
|
+
Response: workersGlobals.CellsResponse,
|
|
84
|
+
WebSocketPair: flags.includes("websocket_standard_binary_type")
|
|
85
|
+
? workersGlobals.StandardWebSocketPair
|
|
86
|
+
: workersGlobals.WebSocketPair,
|
|
87
|
+
};
|
|
88
|
+
if ("site" in code) {
|
|
89
|
+
workersHostRegistry({
|
|
90
|
+
workersModule,
|
|
91
|
+
projectWorkersModule: {
|
|
92
|
+
...workersModule,
|
|
93
|
+
env: scope.env,
|
|
94
|
+
exports: scope.exports,
|
|
95
|
+
waitUntil: scope.waitUntil,
|
|
96
|
+
},
|
|
97
|
+
loadedPrefix: `${code.site}loaded/`,
|
|
98
|
+
emailModule: await import("./cloudflare-email.js"),
|
|
99
|
+
...globals,
|
|
100
|
+
// Loaded on demand, after installNodeGlobals(): the npm `util` polyfill reads `process`
|
|
101
|
+
// when it is imported.
|
|
102
|
+
node: nodeCompat
|
|
103
|
+
? (await import("../node-compat/browser-registry.js")).nodeRegistryEntries
|
|
104
|
+
: undefined,
|
|
105
|
+
});
|
|
106
|
+
return config.main
|
|
107
|
+
? await import(/* @vite-ignore */ `${code.site}modules/~/${config.main}`)
|
|
108
|
+
: { default: {} };
|
|
109
|
+
}
|
|
110
|
+
const g = globalThis;
|
|
111
|
+
g.__cellsWorkersModule = workersModule;
|
|
112
|
+
g.__cellsProjectScope = scope; // `env` and `exports` of the bundle's cloudflare:workers
|
|
113
|
+
g.__cellsGlobals = globals;
|
|
114
|
+
return code.bundle
|
|
115
|
+
? await import(
|
|
116
|
+
/* @vite-ignore */ URL.createObjectURL(new Blob([code.bundle], { type: "text/javascript" })))
|
|
117
|
+
: { default: {} };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* A project's runtime in this worker: installs the Workers globals, imports the code and
|
|
121
|
+
* builds its Worker Loader; `close()` also releases the node's bucket lease.
|
|
122
|
+
*/
|
|
123
|
+
export async function browserProjectRuntime(opts) {
|
|
124
|
+
const scope = workerScope(loadTimeEnv(opts.config, opts.ai));
|
|
125
|
+
const module = await importWorkerCode(opts.config, opts.code, scope);
|
|
126
|
+
const site = "site" in opts.code ? opts.code.site : undefined;
|
|
127
|
+
// With an IndexedDB bucket, cells live in memory and in the bucket's logs (no OPFS pool).
|
|
128
|
+
const openSql = opts.bucket && "ltx" in opts.bucket
|
|
129
|
+
? await ltxOpener(opts.sqlite3, opts.bucket.ltx, opts.bucket.compactAfter, opts.bucket.files)
|
|
130
|
+
: opts.bucket && "idb" in opts.bucket
|
|
131
|
+
? Object.assign(wasmMemoryOpener(opts.sqlite3), {
|
|
132
|
+
release() { },
|
|
133
|
+
reserve: async (n) => n,
|
|
134
|
+
})
|
|
135
|
+
: await sahpoolOpener(opts.sqlite3, {
|
|
136
|
+
name: opts.pool,
|
|
137
|
+
initialCapacity: 64, // grows on demand (sahpoolOpener)
|
|
138
|
+
});
|
|
139
|
+
const root = await navigator.storage.getDirectory();
|
|
140
|
+
const files = new BrowserFilesApi({
|
|
141
|
+
rootHandle: await root.getDirectoryHandle(opts.filesDir, { create: true }),
|
|
142
|
+
});
|
|
143
|
+
// An `ltx` directory is the cells' own storage (the VFS), not a fleet bucket.
|
|
144
|
+
const store = opts.bucket && !("ltx" in opts.bucket) ? await bucketStore(opts.bucket) : undefined;
|
|
145
|
+
const shared = opts.bucket && store
|
|
146
|
+
? celldBucket(store, { node: opts.bucket.node, leaseTtlMs: opts.bucket.leaseTtlMs })
|
|
147
|
+
: undefined;
|
|
148
|
+
const { runtime, unsupported } = createProjectRuntime(opts.config, module, {
|
|
149
|
+
openSql,
|
|
150
|
+
files,
|
|
151
|
+
assetFiles: opts.assetFiles,
|
|
152
|
+
loadModules: site ? siteModuleLoader(site) : browserModuleLoader(),
|
|
153
|
+
isolatedModules: opts.isolateScript
|
|
154
|
+
? browserIsolatedLoader({
|
|
155
|
+
isolateScript: opts.isolateScript,
|
|
156
|
+
siteBaseUrl: site,
|
|
157
|
+
storagePrefix: `${opts.pool}-iso`,
|
|
158
|
+
storage: () => shared, // facets of loaded code are logged like the root's own
|
|
159
|
+
})
|
|
160
|
+
: undefined,
|
|
161
|
+
storage: shared, // R2 objects in the fleet bucket too, as celld keeps them
|
|
162
|
+
route: opts.route,
|
|
163
|
+
ai: opts.ai,
|
|
164
|
+
});
|
|
165
|
+
scope.bind(runtime);
|
|
166
|
+
return {
|
|
167
|
+
runtime,
|
|
168
|
+
unsupported,
|
|
169
|
+
bucket: shared,
|
|
170
|
+
close: async () => {
|
|
171
|
+
await runtime.close();
|
|
172
|
+
openSql.release(); // the pool's files, for the next worker that opens it
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* workerd fills `process.env` with the project's text `vars` under nodejs_compat from
|
|
178
|
+
* compatibility date 2025-04-01 (`nodejs_compat_populate_process_env`), unless
|
|
179
|
+
* `nodejs_compat_do_not_populate_process_env` is set. Frameworks read their settings there
|
|
180
|
+
* (EmDash's `EMDASH_SITE_URL`, for one).
|
|
181
|
+
*/
|
|
182
|
+
export function populatesProcessEnv(config) {
|
|
183
|
+
const flags = config.compatibility_flags ?? [];
|
|
184
|
+
if (!flags.some((f) => f.startsWith("nodejs_compat")))
|
|
185
|
+
return false;
|
|
186
|
+
if (flags.includes("nodejs_compat_do_not_populate_process_env"))
|
|
187
|
+
return false;
|
|
188
|
+
if (flags.includes("nodejs_compat_populate_process_env"))
|
|
189
|
+
return true;
|
|
190
|
+
return (config.compatibility_date ?? "") >= "2025-04-01";
|
|
191
|
+
}
|
|
192
|
+
/** The text `vars` of a project, as `process.env` holds them. */
|
|
193
|
+
export function processEnvOf(config) {
|
|
194
|
+
const env = {};
|
|
195
|
+
for (const [k, v] of Object.entries(config.vars ?? {}))
|
|
196
|
+
if (typeof v === "string")
|
|
197
|
+
env[k] = v;
|
|
198
|
+
return env;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=browser-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-host.js","sourceRoot":"","sources":["../../src/project/browser-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { BrowserFilesApi } from \"@statewalker/webrun-files-browser\";\nimport { installLtxVfs } from \"../adapters/ltx-vfs.js\";\nimport { sahpoolOpener, WasmSqliteDriver, wasmMemoryOpener } from \"../adapters/wasm-sqlite.js\";\nimport type { AssetFiles } from \"../bindings/assets.js\";\nimport type { WorkersAiOptions } from \"../bindings/workers-ai.js\";\nimport { celldBucket } from \"../bucket/celld-cells.js\";\nimport { idbObjectStore } from \"../bucket/idb-object-store.js\";\nimport { filesApiObjectStore, type ObjectStore } from \"../bucket/object-store.js\";\nimport { s3ObjectStore } from \"../bucket/s3-object-store.js\";\nimport type { CellRuntimeOptions, WorkerModule } from \"../core/runtime.js\";\nimport { browserIsolatedLoader } from \"../isolate/browser.js\";\nimport { installAsyncContext } from \"../node-compat/async_hooks.js\";\nimport { installNodeGlobals } from \"../node-compat/install.js\";\nimport { browserModuleLoader } from \"./browser-modules.js\";\nimport * as workersModule from \"./cloudflare-workers.js\";\nimport { siteModuleLoader, workersHostRegistry } from \"./site.js\";\nimport { type WorkerScope, workerScope } from \"./worker-scope.js\";\nimport * as workersGlobals from \"./workers-globals-module.js\";\nimport { createProjectRuntime, loadTimeEnv, type WranglerConfig } from \"./wrangler.js\";\n\n/**\n * Where a browser-hosted project keeps its cells when they must outlive the page or move to\n * other nodes: a celld fleet bucket. Cells, facets and alarms are then exactly celld's\n * (ownership in `own.json`, LTX logs, wake index) and R2 objects live in it too, so the same\n * cells can be served by this browser, by other browsers and by celld nodes, in turn.\n *\n * - `s3`: an S3-compatible bucket, reached directly (the bucket must allow CORS for the page's\n * origin: methods GET/PUT/DELETE/HEAD, request headers `authorization`, `content-type`,\n * `x-amz-*`, `if-match`, `if-none-match`; exposed headers `etag`, `last-modified`,\n * `x-amz-meta-celld-r2`) or through a same-origin proxy (`endpoint` = the proxy,\n * `signAs` = the real endpoint: SigV4 signs the real host and path).\n * - `opfs`: a bucket in this origin's OPFS — persistence without a server. Conditional writes\n * are atomic only within one writer, so one tab or worker at a time should own its cells.\n * - `store`: any ObjectStore.\n */\nexport type BrowserBucket =\n | {\n s3: {\n endpoint: string;\n signAs?: string;\n bucket: string;\n prefix?: string;\n region?: string;\n accessKeyId: string;\n secretAccessKey: string;\n };\n node: string;\n leaseTtlMs?: number;\n }\n | { opfs: string; node: string; leaseTtlMs?: number }\n /**\n * `idb`: a bucket in this origin's IndexedDB (atomic conditional writes across tabs and\n * workers). Cells then run SQLite in memory and persist through the bucket's page-level logs:\n * no OPFS pool, so any number of workers can serve cells at once.\n */\n | { idb: string; node: string; leaseTtlMs?: number }\n /**\n * `ltx`: cells as celld keeps them, LTX files (a snapshot and one file per commit) in an OPFS\n * directory, read page by page (a SQLite VFS over a store worker): no OPFS pool, and a\n * cell's memory is its page cache, not its database. A cell is folded into one snapshot\n * (streamed) past `compactAfter` files (default 64), or once the files after its snapshot hold\n * more than half of it. See docs/browser-host.md.\n */\n | {\n ltx: string;\n node: string;\n leaseTtlMs?: number;\n compactAfter?: number;\n /**\n * The cells' FilesApi in the store worker: OPFS through synchronous handles (default,\n * `opfs-sync`), OPFS through its asynchronous API (`opfs`), or memory (nothing kept).\n */\n files?: \"opfs\" | \"opfs-sync\" | \"memory\";\n }\n | { store: ObjectStore; node: string; leaseTtlMs?: number };\n\nexport interface BrowserProjectOptions {\n config: WranglerConfig;\n /**\n * The project's Worker code, imported in this realm once its Workers globals (and with\n * nodejs_compat `Buffer` and `process`) are installed:\n * - `bundle`: one ES module built for browsers (`bundleWorkerForBrowser`), whose\n * `cloudflare:workers` is `PROJECT_WORKERS_MODULE_SHIM` and whose Workers globals read\n * `globalThis.__cellsGlobals`\n * (`null`: the project has no `main`). Worker Loader code becomes Blob-URL modules.\n * - `site`: the base URL of the project's site (`createProjectSite`, hosted by\n * webrun-site-host). `main` and Worker Loader code are imported from it.\n */\n code: { bundle: string | null } | { site: string };\n /**\n * A Dedicated Worker script that serves one loaded Worker (`serveIsolate`): Worker Loader\n * code then runs isolated, one Dedicated Worker per loaded Worker, as celld's isolates.\n * The package ships one: `@statewalker/cellb/isolate-worker`.\n */\n isolateScript?: URL;\n /** An initialized SQLite WASM module (`@sqlite.org/sqlite-wasm`). */\n sqlite3: unknown;\n /** OPFS sahpool name for this host's SQLite files (one pool per worker). */\n pool: string;\n /** OPFS directory for the project's FilesApi (Workers' fs-like bindings, R2 without bucket). */\n filesDir: string;\n assetFiles?: AssetFiles;\n bucket?: BrowserBucket;\n /**\n * Cells this runtime does not host: where to send their events (a `Send` over a MessagePort\n * to the runtime that hosts them, `linkOverPort`), or undefined to host the cell here. With\n * one runtime per worker and `shardOf` as the placement, cells run in parallel threads.\n */\n route?: CellRuntimeOptions[\"route\"];\n /** The OpenAI-compatible endpoint behind the project's `ai` binding (Workers AI). */\n ai?: WorkersAiOptions;\n}\n\nasync function bucketStore(b: BrowserBucket): Promise<ObjectStore> {\n if (\"store\" in b) return b.store;\n if (\"s3\" in b) return s3ObjectStore({ region: \"us-east-1\", ...b.s3 });\n if (\"idb\" in b) return idbObjectStore(b.idb);\n if (\"ltx\" in b) throw new Error(\"an ltx directory is cell storage, not a bucket\");\n const root = await navigator.storage.getDirectory();\n return filesApiObjectStore(\n new BrowserFilesApi({ rootHandle: await root.getDirectoryHandle(b.opfs, { create: true }) }),\n \"\",\n );\n}\n\n/**\n * Cells on the LTX VFS: a store worker owns the OPFS directory; each cell is a SQLite database\n * whose main file is its LTX files, read page by page (src/adapters/ltx-vfs.ts).\n */\nasync function ltxOpener(sqlite3: unknown, dir: string, compactAfter?: number, files?: string) {\n const store = new Worker(\n new URL(\"../ltx/ltx-store-worker.ts\", import.meta.url) /* `.js` in dist/ (scripts/build.mjs) */,\n { type: \"module\" },\n );\n const sab = new SharedArrayBuffer(8 + 16 * 65536); // room for a read-ahead run of 64 KiB pages\n // Wait until the store worker runs before any synchronous call: a nested worker is started\n // (its script fetched) through this worker's event loop, which Atomics.wait would block.\n const ready = new Promise<void>((resolve, reject) => {\n store.addEventListener(\"message\", (e) => e.data?.op === \"ready\" && resolve(), { once: false });\n store.addEventListener(\"error\", (e) => reject(new Error(`ltx store worker: ${e.message}`)));\n });\n store.postMessage({ op: \"init\", sab, dir, compactAfter, files });\n await ready;\n const { name } = installLtxVfs(sqlite3, { sab, post: (m) => store.postMessage(m) });\n const s3 = sqlite3 as { oo1: { DB: new (o: Record<string, unknown>) => any } };\n const open = (cellKey: string) => {\n const db = new s3.oo1.DB({ filename: cellKey, vfs: name, flags: \"c\" });\n db.exec(\"PRAGMA journal_mode=MEMORY; PRAGMA synchronous=FULL;\");\n // SQLite's C API for inTransaction() only (no page hook or session capture on this VFS).\n return new WasmSqliteDriver(db, undefined, undefined, (sqlite3 as { capi: never }).capi);\n };\n return Object.assign(open, {\n release() {\n store.terminate();\n },\n reserve: async (n: number) => n,\n });\n}\n\n/** Installs the Workers globals the code reads, then imports its `main`. */\nasync function importWorkerCode(\n config: WranglerConfig,\n code: BrowserProjectOptions[\"code\"],\n scope: WorkerScope,\n): Promise<WorkerModule> {\n const flags = config.compatibility_flags ?? [];\n const nodeCompat = flags.some((f) => f.startsWith(\"nodejs_compat\"));\n if (nodeCompat) {\n installNodeGlobals();\n // node:* for bundles built with cellbHostModule (another bundler than bundleWorkerForBrowser);\n // loaded after installNodeGlobals(), as the npm `util` polyfill reads `process`.\n (globalThis as Record<string, unknown>).__cellsNodeModules = (\n await import(\"../node-compat/browser-registry.js\")\n ).nodeRegistryEntries;\n if (populatesProcessEnv(config)) {\n const env = processEnvOf(config);\n // The bundle's own `process` reads it when evaluated; a site's modules use this realm's.\n (globalThis as Record<string, unknown>).__cellsProcessEnv = env;\n Object.assign((globalThis as { process: { env: Record<string, string> } }).process.env, env);\n }\n // node:async_hooks: continuations carry their AsyncLocalStorage stores (with AsyncContext\n // the engine does, and this installs nothing). The code's awaits are lowered so that they go\n // through them: by bundleWorkerForBrowser for a bundle, by createProjectSite (nodeCompat) for\n // a site's modules.\n installAsyncContext();\n }\n const globals = {\n ...workersGlobals,\n Request: workersGlobals.CellsRequest,\n Response: workersGlobals.CellsResponse,\n WebSocketPair: flags.includes(\"websocket_standard_binary_type\")\n ? workersGlobals.StandardWebSocketPair\n : workersGlobals.WebSocketPair,\n };\n if (\"site\" in code) {\n workersHostRegistry({\n workersModule,\n projectWorkersModule: {\n ...workersModule,\n env: scope.env,\n exports: scope.exports,\n waitUntil: scope.waitUntil,\n },\n loadedPrefix: `${code.site}loaded/`,\n emailModule: await import(\"./cloudflare-email.js\"),\n ...globals,\n // Loaded on demand, after installNodeGlobals(): the npm `util` polyfill reads `process`\n // when it is imported.\n node: nodeCompat\n ? (await import(\"../node-compat/browser-registry.js\")).nodeRegistryEntries\n : undefined,\n });\n return config.main\n ? await import(/* @vite-ignore */ `${code.site}modules/~/${config.main}`)\n : { default: {} };\n }\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkersModule = workersModule;\n g.__cellsProjectScope = scope; // `env` and `exports` of the bundle's cloudflare:workers\n g.__cellsGlobals = globals;\n return code.bundle\n ? await import(\n /* @vite-ignore */ URL.createObjectURL(new Blob([code.bundle], { type: \"text/javascript\" }))\n )\n : { default: {} };\n}\n\n/**\n * A project's runtime in this worker: installs the Workers globals, imports the code and\n * builds its Worker Loader; `close()` also releases the node's bucket lease.\n */\nexport async function browserProjectRuntime(opts: BrowserProjectOptions) {\n const scope = workerScope(loadTimeEnv(opts.config, opts.ai));\n const module = await importWorkerCode(opts.config, opts.code, scope);\n const site = \"site\" in opts.code ? opts.code.site : undefined;\n // With an IndexedDB bucket, cells live in memory and in the bucket's logs (no OPFS pool).\n const openSql =\n opts.bucket && \"ltx\" in opts.bucket\n ? await ltxOpener(opts.sqlite3, opts.bucket.ltx, opts.bucket.compactAfter, opts.bucket.files)\n : opts.bucket && \"idb\" in opts.bucket\n ? Object.assign(wasmMemoryOpener(opts.sqlite3 as never), {\n release() {},\n reserve: async (n: number) => n,\n })\n : await sahpoolOpener(opts.sqlite3 as never, {\n name: opts.pool,\n initialCapacity: 64, // grows on demand (sahpoolOpener)\n });\n const root = await navigator.storage.getDirectory();\n const files = new BrowserFilesApi({\n rootHandle: await root.getDirectoryHandle(opts.filesDir, { create: true }),\n });\n // An `ltx` directory is the cells' own storage (the VFS), not a fleet bucket.\n const store = opts.bucket && !(\"ltx\" in opts.bucket) ? await bucketStore(opts.bucket) : undefined;\n const shared =\n opts.bucket && store\n ? celldBucket(store, { node: opts.bucket.node, leaseTtlMs: opts.bucket.leaseTtlMs })\n : undefined;\n const { runtime, unsupported } = createProjectRuntime(opts.config, module, {\n openSql,\n files,\n assetFiles: opts.assetFiles,\n loadModules: site ? siteModuleLoader(site) : browserModuleLoader(),\n isolatedModules: opts.isolateScript\n ? browserIsolatedLoader({\n isolateScript: opts.isolateScript,\n siteBaseUrl: site,\n storagePrefix: `${opts.pool}-iso`,\n storage: () => shared, // facets of loaded code are logged like the root's own\n })\n : undefined,\n storage: shared, // R2 objects in the fleet bucket too, as celld keeps them\n route: opts.route,\n ai: opts.ai,\n });\n scope.bind(runtime);\n return {\n runtime,\n unsupported,\n bucket: shared,\n close: async () => {\n await runtime.close();\n openSql.release(); // the pool's files, for the next worker that opens it\n },\n };\n}\n\n/**\n * workerd fills `process.env` with the project's text `vars` under nodejs_compat from\n * compatibility date 2025-04-01 (`nodejs_compat_populate_process_env`), unless\n * `nodejs_compat_do_not_populate_process_env` is set. Frameworks read their settings there\n * (EmDash's `EMDASH_SITE_URL`, for one).\n */\nexport function populatesProcessEnv(config: WranglerConfig): boolean {\n const flags = config.compatibility_flags ?? [];\n if (!flags.some((f) => f.startsWith(\"nodejs_compat\"))) return false;\n if (flags.includes(\"nodejs_compat_do_not_populate_process_env\")) return false;\n if (flags.includes(\"nodejs_compat_populate_process_env\")) return true;\n return (config.compatibility_date ?? \"\") >= \"2025-04-01\";\n}\n\n/** The text `vars` of a project, as `process.env` holds them. */\nexport function processEnvOf(config: WranglerConfig): Record<string, string> {\n const env: Record<string, string> = {};\n for (const [k, v] of Object.entries(config.vars ?? {})) if (typeof v === \"string\") env[k] = v;\n return env;\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ModuleLoader } from "../bindings/worker-loader.js";
|
|
2
|
+
/**
|
|
3
|
+
* `cloudflare:workers` for a project's own bundle: the classes, and the project's `env` and
|
|
4
|
+
* `exports` from `globalThis.__cellsProjectScope` (set by `browserProjectRuntime`, and by
|
|
5
|
+
* `serveIsolate` for the loaded Worker an isolate runs). The shim is
|
|
6
|
+
* bundled with the Worker, so it declares no names beyond its exports: esbuild would rename the
|
|
7
|
+
* Worker's own variables of the same name, and those names show in error messages.
|
|
8
|
+
*/
|
|
9
|
+
export declare const PROJECT_WORKERS_MODULE_SHIM = "const m = globalThis.__cellsWorkersModule; export const DurableObject = m.DurableObject, WorkerEntrypoint = m.WorkerEntrypoint, WorkflowEntrypoint = m.WorkflowEntrypoint, RpcTarget = m.RpcTarget; export default m; export const env = globalThis.__cellsProjectScope?.env ?? {}, exports = globalThis.__cellsProjectScope?.exports ?? {}, waitUntil = (p) => globalThis.__cellsProjectScope?.waitUntil(p);";
|
|
10
|
+
/**
|
|
11
|
+
* Worker Loader in a browser realm: each module of a WorkerCode becomes a Blob-URL ES
|
|
12
|
+
* module. `cloudflare:workers` resolves to a shim reading the runtime's own classes from
|
|
13
|
+
* `globalThis.__cellsWorkersModule` and the loaded code's own `env` and `exports` (or to
|
|
14
|
+
* `workersModuleShim`, the same for every load); relative imports resolve to the Blob URLs of
|
|
15
|
+
* sibling modules; with a log sink the module gets a module-scoped `console` (Tail Workers).
|
|
16
|
+
*/
|
|
17
|
+
export declare function browserModuleLoader(workersModuleShim?: string): ModuleLoader;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { moduleText, outboundFetch, } from "../bindings/worker-loader.js";
|
|
2
|
+
import { ctxExports } from "../core/handles.js";
|
|
3
|
+
import { workerScope } from "./worker-scope.js";
|
|
4
|
+
const WORKERS_CLASSES = "const m = globalThis.__cellsWorkersModule; export const DurableObject = m.DurableObject, WorkerEntrypoint = m.WorkerEntrypoint, WorkflowEntrypoint = m.WorkflowEntrypoint, RpcTarget = m.RpcTarget; export default m;";
|
|
5
|
+
/**
|
|
6
|
+
* `cloudflare:workers` for a project's own bundle: the classes, and the project's `env` and
|
|
7
|
+
* `exports` from `globalThis.__cellsProjectScope` (set by `browserProjectRuntime`, and by
|
|
8
|
+
* `serveIsolate` for the loaded Worker an isolate runs). The shim is
|
|
9
|
+
* bundled with the Worker, so it declares no names beyond its exports: esbuild would rename the
|
|
10
|
+
* Worker's own variables of the same name, and those names show in error messages.
|
|
11
|
+
*/
|
|
12
|
+
export const PROJECT_WORKERS_MODULE_SHIM = `${WORKERS_CLASSES} export const env = globalThis.__cellsProjectScope?.env ?? {}, exports = globalThis.__cellsProjectScope?.exports ?? {}, waitUntil = (p) => globalThis.__cellsProjectScope?.waitUntil(p);`;
|
|
13
|
+
/**
|
|
14
|
+
* Worker Loader in a browser realm: each module of a WorkerCode becomes a Blob-URL ES
|
|
15
|
+
* module. `cloudflare:workers` resolves to a shim reading the runtime's own classes from
|
|
16
|
+
* `globalThis.__cellsWorkersModule` and the loaded code's own `env` and `exports` (or to
|
|
17
|
+
* `workersModuleShim`, the same for every load); relative imports resolve to the Blob URLs of
|
|
18
|
+
* sibling modules; with a log sink the module gets a module-scoped `console` (Tail Workers).
|
|
19
|
+
*/
|
|
20
|
+
export function browserModuleLoader(workersModuleShim) {
|
|
21
|
+
const blob = (text) => URL.createObjectURL(new Blob([text], { type: "text/javascript" }));
|
|
22
|
+
const fixedShimUrl = workersModuleShim && blob(workersModuleShim);
|
|
23
|
+
return async (_id, code, logs) => {
|
|
24
|
+
const env = code.env ?? {};
|
|
25
|
+
const scope = fixedShimUrl ? undefined : workerScope(env);
|
|
26
|
+
let shimUrl = fixedShimUrl;
|
|
27
|
+
if (scope) {
|
|
28
|
+
const key = `s${Math.random().toString(36).slice(2)}`;
|
|
29
|
+
const g = globalThis;
|
|
30
|
+
g.__cellsWorkerScopes ??= {};
|
|
31
|
+
g.__cellsWorkerScopes[key] = scope;
|
|
32
|
+
shimUrl = blob(`${WORKERS_CLASSES} const s = globalThis.__cellsWorkerScopes[${JSON.stringify(key)}]; export const env = s.env, exports = s.exports, waitUntil = s.waitUntil;`);
|
|
33
|
+
}
|
|
34
|
+
let consolePrelude = "";
|
|
35
|
+
if (logs) {
|
|
36
|
+
const key = `c${Math.random().toString(36).slice(2)}`;
|
|
37
|
+
const g = globalThis;
|
|
38
|
+
g.__cellsConsoles ??= {};
|
|
39
|
+
const real = globalThis.console;
|
|
40
|
+
const wrap = (level) => (...args) => {
|
|
41
|
+
logs(level, args);
|
|
42
|
+
real[level](...args);
|
|
43
|
+
};
|
|
44
|
+
g.__cellsConsoles[key] = Object.assign(Object.create(real), {
|
|
45
|
+
log: wrap("log"),
|
|
46
|
+
info: wrap("info"),
|
|
47
|
+
warn: wrap("warn"),
|
|
48
|
+
error: wrap("error"),
|
|
49
|
+
debug: wrap("debug"),
|
|
50
|
+
});
|
|
51
|
+
consolePrelude = `const console = globalThis.__cellsConsoles[${JSON.stringify(key)}];\n`;
|
|
52
|
+
}
|
|
53
|
+
const outbound = outboundFetch(code);
|
|
54
|
+
if (outbound) {
|
|
55
|
+
const key = `o${Math.random().toString(36).slice(2)}`;
|
|
56
|
+
const g = globalThis;
|
|
57
|
+
g.__cellsOutbound ??= {};
|
|
58
|
+
g.__cellsOutbound[key] = outbound;
|
|
59
|
+
consolePrelude += `const fetch = globalThis.__cellsOutbound[${JSON.stringify(key)}];\n`;
|
|
60
|
+
}
|
|
61
|
+
const urls = new Map();
|
|
62
|
+
const source = (name) => {
|
|
63
|
+
const m = code.modules[name];
|
|
64
|
+
if (m === undefined)
|
|
65
|
+
throw new Error(`Worker Loader: module "${name}" not found`);
|
|
66
|
+
return moduleText(m);
|
|
67
|
+
};
|
|
68
|
+
const urlOf = (name) => {
|
|
69
|
+
const known = urls.get(name);
|
|
70
|
+
if (known)
|
|
71
|
+
return known;
|
|
72
|
+
const base = name.includes("/") ? name.slice(0, name.lastIndexOf("/") + 1) : "";
|
|
73
|
+
const text = source(name).replace(/(\bfrom\s*|\bimport\s*\(?\s*)(["'])([^"']+)\2/g, (all, pre, q, spec) => {
|
|
74
|
+
if (spec === "cloudflare:workers")
|
|
75
|
+
return `${pre}${q}${shimUrl}${q}`;
|
|
76
|
+
if (spec.startsWith("./") || spec.startsWith("../"))
|
|
77
|
+
return `${pre}${q}${urlOf(new URL(spec, `file:///${base}`).pathname.slice(1))}${q}`;
|
|
78
|
+
return all;
|
|
79
|
+
});
|
|
80
|
+
const url = URL.createObjectURL(new Blob([consolePrelude + text], { type: "text/javascript" }));
|
|
81
|
+
urls.set(name, url);
|
|
82
|
+
return url;
|
|
83
|
+
};
|
|
84
|
+
const module = (await import(/* @vite-ignore */ urlOf(code.mainModule)));
|
|
85
|
+
scope?.bind({ env, exports: ctxExports(module, env) });
|
|
86
|
+
return module;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=browser-modules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-modules.js","sourceRoot":"","sources":["../../src/project/browser-modules.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,UAAU,EACV,aAAa,GAEd,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,eAAe,GACnB,uNAAuN,CAAC;AAE1N;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,eAAe,0LAA0L,CAAC;AAExP;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,iBAA0B;IAC5D,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC;IAClG,MAAM,YAAY,GAAG,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAClE,OAAO,KAAK,EAAE,GAAW,EAAE,IAAgB,EAAE,IAAc,EAAE,EAAE;QAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1D,IAAI,OAAO,GAAG,YAAY,CAAC;QAC3B,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,MAAM,CAAC,GAAG,UAAqC,CAAC;YAChD,CAAC,CAAC,mBAAmB,KAAK,EAAE,CAAC;YAC5B,CAAC,CAAC,mBAA+C,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAChE,OAAO,GAAG,IAAI,CACZ,GAAG,eAAe,6CAA6C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,4EAA4E,CAC/J,CAAC;QACJ,CAAC;QACD,IAAI,cAAc,GAAG,EAAE,CAAC;QACxB,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,MAAM,CAAC,GAAG,UAAqC,CAAC;YAChD,CAAC,CAAC,eAAe,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC;YAChC,MAAM,IAAI,GACR,CAAC,KAAkD,EAAE,EAAE,CACvD,CAAC,GAAG,IAAe,EAAE,EAAE;gBACrB,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAClB,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YACvB,CAAC,CAAC;YACH,CAAC,CAAC,eAA2C,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;gBACvF,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC;gBAChB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;gBAClB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;gBAClB,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC;gBACpB,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC;aACrB,CAAC,CAAC;YACH,cAAc,GAAG,8CAA8C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;QAC3F,CAAC;QACD,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,MAAM,CAAC,GAAG,UAAqC,CAAC;YAChD,CAAC,CAAC,eAAe,KAAK,EAAE,CAAC;YACxB,CAAC,CAAC,eAA2C,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;YAC/D,cAAc,IAAI,4CAA4C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;QAC1F,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;QACvC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;YAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,aAAa,CAAC,CAAC;YAClF,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,CAAC,IAAY,EAAU,EAAE;YACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7B,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAChF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAC/B,gDAAgD,EAChD,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,IAAY,EAAE,EAAE;gBAC5B,IAAI,IAAI,KAAK,oBAAoB;oBAAE,OAAO,GAAG,GAAG,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,EAAE,CAAC;gBACrE,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;oBACjD,OAAO,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtF,OAAO,GAAG,CAAC;YACb,CAAC,CACF,CAAC;YACF,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAC7B,IAAI,IAAI,CAAC,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAC/D,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACpB,OAAO,GAAG,CAAC;QACb,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAGtE,CAAC;QACF,KAAK,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACvD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import {\n type LogSink,\n type ModuleLoader,\n moduleText,\n outboundFetch,\n type WorkerCode,\n} from \"../bindings/worker-loader.js\";\nimport { ctxExports } from \"../core/handles.js\";\nimport { workerScope } from \"./worker-scope.js\";\n\nconst WORKERS_CLASSES =\n \"const m = globalThis.__cellsWorkersModule; export const DurableObject = m.DurableObject, WorkerEntrypoint = m.WorkerEntrypoint, WorkflowEntrypoint = m.WorkflowEntrypoint, RpcTarget = m.RpcTarget; export default m;\";\n\n/**\n * `cloudflare:workers` for a project's own bundle: the classes, and the project's `env` and\n * `exports` from `globalThis.__cellsProjectScope` (set by `browserProjectRuntime`, and by\n * `serveIsolate` for the loaded Worker an isolate runs). The shim is\n * bundled with the Worker, so it declares no names beyond its exports: esbuild would rename the\n * Worker's own variables of the same name, and those names show in error messages.\n */\nexport const PROJECT_WORKERS_MODULE_SHIM = `${WORKERS_CLASSES} export const env = globalThis.__cellsProjectScope?.env ?? {}, exports = globalThis.__cellsProjectScope?.exports ?? {}, waitUntil = (p) => globalThis.__cellsProjectScope?.waitUntil(p);`;\n\n/**\n * Worker Loader in a browser realm: each module of a WorkerCode becomes a Blob-URL ES\n * module. `cloudflare:workers` resolves to a shim reading the runtime's own classes from\n * `globalThis.__cellsWorkersModule` and the loaded code's own `env` and `exports` (or to\n * `workersModuleShim`, the same for every load); relative imports resolve to the Blob URLs of\n * sibling modules; with a log sink the module gets a module-scoped `console` (Tail Workers).\n */\nexport function browserModuleLoader(workersModuleShim?: string): ModuleLoader {\n const blob = (text: string) => URL.createObjectURL(new Blob([text], { type: \"text/javascript\" }));\n const fixedShimUrl = workersModuleShim && blob(workersModuleShim);\n return async (_id: string, code: WorkerCode, logs?: LogSink) => {\n const env = code.env ?? {};\n const scope = fixedShimUrl ? undefined : workerScope(env);\n let shimUrl = fixedShimUrl;\n if (scope) {\n const key = `s${Math.random().toString(36).slice(2)}`;\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkerScopes ??= {};\n (g.__cellsWorkerScopes as Record<string, unknown>)[key] = scope;\n shimUrl = blob(\n `${WORKERS_CLASSES} const s = globalThis.__cellsWorkerScopes[${JSON.stringify(key)}]; export const env = s.env, exports = s.exports, waitUntil = s.waitUntil;`,\n );\n }\n let consolePrelude = \"\";\n if (logs) {\n const key = `c${Math.random().toString(36).slice(2)}`;\n const g = globalThis as Record<string, unknown>;\n g.__cellsConsoles ??= {};\n const real = globalThis.console;\n const wrap =\n (level: \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\") =>\n (...args: unknown[]) => {\n logs(level, args);\n real[level](...args);\n };\n (g.__cellsConsoles as Record<string, unknown>)[key] = Object.assign(Object.create(real), {\n log: wrap(\"log\"),\n info: wrap(\"info\"),\n warn: wrap(\"warn\"),\n error: wrap(\"error\"),\n debug: wrap(\"debug\"),\n });\n consolePrelude = `const console = globalThis.__cellsConsoles[${JSON.stringify(key)}];\\n`;\n }\n const outbound = outboundFetch(code);\n if (outbound) {\n const key = `o${Math.random().toString(36).slice(2)}`;\n const g = globalThis as Record<string, unknown>;\n g.__cellsOutbound ??= {};\n (g.__cellsOutbound as Record<string, unknown>)[key] = outbound;\n consolePrelude += `const fetch = globalThis.__cellsOutbound[${JSON.stringify(key)}];\\n`;\n }\n const urls = new Map<string, string>();\n const source = (name: string) => {\n const m = code.modules[name];\n if (m === undefined) throw new Error(`Worker Loader: module \"${name}\" not found`);\n return moduleText(m);\n };\n const urlOf = (name: string): string => {\n const known = urls.get(name);\n if (known) return known;\n const base = name.includes(\"/\") ? name.slice(0, name.lastIndexOf(\"/\") + 1) : \"\";\n const text = source(name).replace(\n /(\\bfrom\\s*|\\bimport\\s*\\(?\\s*)([\"'])([^\"']+)\\2/g,\n (all, pre, q, spec: string) => {\n if (spec === \"cloudflare:workers\") return `${pre}${q}${shimUrl}${q}`;\n if (spec.startsWith(\"./\") || spec.startsWith(\"../\"))\n return `${pre}${q}${urlOf(new URL(spec, `file:///${base}`).pathname.slice(1))}${q}`;\n return all;\n },\n );\n const url = URL.createObjectURL(\n new Blob([consolePrelude + text], { type: \"text/javascript\" }),\n );\n urls.set(name, url);\n return url;\n };\n const module = (await import(/* @vite-ignore */ urlOf(code.mainModule))) as Record<\n string,\n unknown\n >;\n scope?.bind({ env, exports: ctxExports(module, env) });\n return module;\n };\n}\n"]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { RemoteRuntime } from "../transport/cells-http.js";
|
|
2
|
+
import { type BrowserBucket, type BrowserProjectOptions } from "./browser-host.js";
|
|
3
|
+
/** A shard of a project shared by the tabs of an origin (`joinProjectShards`): linked to a router. */
|
|
4
|
+
export declare const TAB_INIT = "cellb:tab-shard";
|
|
5
|
+
export declare const TAB_LINK = "cellb:tab-shard-link";
|
|
6
|
+
/** The router the shard was just linked to: the Web Lock its ServiceWorker holds while alive. */
|
|
7
|
+
export declare const TAB_WATCH = "cellb:tab-shard-watch";
|
|
8
|
+
/** From a shard worker to its tab: a call waits for a router that is gone; wake the ServiceWorker. */
|
|
9
|
+
export declare const SHARD_WAKE = "cellb:tab-shard-wake";
|
|
10
|
+
/** From a shard worker to its tab: calls into other shards are in flight; keep the ServiceWorker up. */
|
|
11
|
+
export declare const SHARD_KEEPALIVE = "cellb:tab-shard-keepalive";
|
|
12
|
+
/** What a shard worker shared by tabs is told: no peers, it reaches them through the router. */
|
|
13
|
+
export interface TabShardInit {
|
|
14
|
+
type: typeof TAB_INIT;
|
|
15
|
+
name: string;
|
|
16
|
+
shard: number;
|
|
17
|
+
shards: number;
|
|
18
|
+
config: BrowserProjectOptions["config"];
|
|
19
|
+
code: BrowserProjectOptions["code"];
|
|
20
|
+
assetFiles?: BrowserProjectOptions["assetFiles"];
|
|
21
|
+
/** The OpenAI-compatible endpoint behind the project's `ai` binding. */
|
|
22
|
+
ai?: BrowserProjectOptions["ai"];
|
|
23
|
+
bucket?: BrowserBucket;
|
|
24
|
+
pool: string;
|
|
25
|
+
filesDir: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The worker side: hosts one shard when a page says so — of `startProjectShards` (peers wired
|
|
29
|
+
* directly) or of `joinProjectShards` (shared by the tabs, linked to the ServiceWorker's router).
|
|
30
|
+
* Messages of other types are left to the worker's own listeners.
|
|
31
|
+
*/
|
|
32
|
+
export declare function serveProjectShard(opts: {
|
|
33
|
+
/** An initialized SQLite WASM module, or a function that makes one. */
|
|
34
|
+
sqlite3: unknown | (() => Promise<unknown>);
|
|
35
|
+
/** `browserProjectRuntime`'s `isolateScript`. */
|
|
36
|
+
isolateScript?: URL;
|
|
37
|
+
}): void;
|
|
38
|
+
export interface ProjectShards {
|
|
39
|
+
/** Ingress: a request to the project's Worker, in the next shard (round robin). */
|
|
40
|
+
fetch(req: Request): Promise<Response>;
|
|
41
|
+
/** The shards' runtimes, by shard number. */
|
|
42
|
+
readonly shards: RemoteRuntime[];
|
|
43
|
+
/** Configuration entries the runtime does not support (as `browserProjectRuntime` reports). */
|
|
44
|
+
readonly unsupported: string[];
|
|
45
|
+
/** Closes every shard's runtime (releasing bucket leases), then its worker. */
|
|
46
|
+
close(): Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
/** The page side: starts `shards` workers that each run `serveProjectShard`, wired together. */
|
|
49
|
+
export declare function startProjectShards(opts: {
|
|
50
|
+
shards: number;
|
|
51
|
+
/** Starts one worker whose script calls `serveProjectShard`. */
|
|
52
|
+
spawn: (shard: number) => Worker;
|
|
53
|
+
config: BrowserProjectOptions["config"];
|
|
54
|
+
code: BrowserProjectOptions["code"];
|
|
55
|
+
assetFiles?: BrowserProjectOptions["assetFiles"];
|
|
56
|
+
/** The OpenAI-compatible endpoint behind the project's `ai` binding. */
|
|
57
|
+
ai?: BrowserProjectOptions["ai"];
|
|
58
|
+
/** Each shard is its own fleet node, named `<node>-s<shard>`. */
|
|
59
|
+
bucket?: BrowserBucket;
|
|
60
|
+
/** Prefix of the shards' OPFS pools and files directories (`<name>-<shard>`). */
|
|
61
|
+
name: string;
|
|
62
|
+
}): Promise<ProjectShards>;
|