@statewalker/cellb 0.0.0-stage → 0.1.1
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 +373 -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
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { filesApiBackup } from "./adapters/files-backup.js";
|
|
2
|
+
export { filesApiChangeLog } from "./adapters/files-changelog.js";
|
|
3
|
+
export { filesApiLtxLog } from "./adapters/files-ltx.js";
|
|
4
|
+
export { wasmMemoryOpener } from "./adapters/wasm-sqlite.js";
|
|
5
|
+
export { AiError, workersAi, } from "./bindings/workers-ai.js";
|
|
6
|
+
export { celldBucket } from "./bucket/celld-cells.js";
|
|
7
|
+
export { filesApiObjectStore, memoryObjectStore, PreconditionFailedError, } from "./bucket/object-store.js";
|
|
8
|
+
export { s3ObjectStore } from "./bucket/s3-object-store.js";
|
|
9
|
+
export { DurableObject, WorkerEntrypoint } from "./core/durable-object.js";
|
|
10
|
+
export { DurableObjectNamespace, runInDurableObject, } from "./core/namespace.js";
|
|
11
|
+
export { BrokenObjectError, CellOwnedElsewhereError } from "./core/object-host.js";
|
|
12
|
+
export { createCellRuntime, } from "./core/runtime.js";
|
|
13
|
+
export { shardOf } from "./core/shard.js";
|
|
14
|
+
export { DurableObjectState } from "./core/state.js";
|
|
15
|
+
export * from "./ports.js";
|
|
16
|
+
export { createProjectRuntime, } from "./project/wrangler.js";
|
|
17
|
+
export { CellRouter, ShardOwnerLostError } from "./router/cell-router.js";
|
|
18
|
+
export { createShardWorker, shardRouting, } from "./router/shard-worker.js";
|
|
19
|
+
export { cellsHttpHandler, remoteRuntime, } from "./transport/cells-http.js";
|
|
20
|
+
export { connectRuntime, linkOverPort, serveHandlerOverPort, serveRuntime, } from "./transport/port.js";
|
|
21
|
+
export { createWebSocketClass, } from "./ws/client.js";
|
|
22
|
+
export { CellsResponse, takeClientPort, WebSocketPair } from "./ws/server.js";
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACxF,OAAO,EAAyB,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,EAA8B,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EACL,OAAO,EAGP,SAAS,GACV,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAA2B,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EAEjB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAkB,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAyB,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,EACL,sBAAsB,EAEtB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAGL,iBAAiB,GAElB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,oBAAoB,GAIrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAA0B,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,EACL,iBAAiB,EAGjB,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,gBAAgB,EAEhB,aAAa,GACd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAEL,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,YAAY,GACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,oBAAoB,GAErB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC","sourcesContent":["export { type FilesApiBackupOptions, filesApiBackup } from \"./adapters/files-backup.js\";\nexport { type ChangeLogOptions, filesApiChangeLog } from \"./adapters/files-changelog.js\";\nexport { type FilesApiLtxLogOptions, filesApiLtxLog } from \"./adapters/files-ltx.js\";\nexport { wasmMemoryOpener } from \"./adapters/wasm-sqlite.js\";\nexport {\n AiError,\n type AiRunOptions,\n type WorkersAiOptions,\n workersAi,\n} from \"./bindings/workers-ai.js\";\nexport { type CelldBucketOptions, celldBucket } from \"./bucket/celld-cells.js\";\nexport {\n filesApiObjectStore,\n memoryObjectStore,\n type ObjectStore,\n PreconditionFailedError,\n} from \"./bucket/object-store.js\";\nexport { type S3Options, s3ObjectStore } from \"./bucket/s3-object-store.js\";\nexport { DurableObject, type ExecutionContext, WorkerEntrypoint } from \"./core/durable-object.js\";\nexport {\n DurableObjectNamespace,\n type DurableObjectStub,\n runInDurableObject,\n} from \"./core/namespace.js\";\nexport { BrokenObjectError, CellOwnedElsewhereError } from \"./core/object-host.js\";\nexport {\n type CellRuntime,\n type CellRuntimeOptions,\n createCellRuntime,\n type WorkerModule,\n} from \"./core/runtime.js\";\nexport { shardOf } from \"./core/shard.js\";\nexport { DurableObjectState } from \"./core/state.js\";\nexport * from \"./ports.js\";\nexport {\n createProjectRuntime,\n type ProjectHost,\n type ProjectRuntime,\n type WranglerConfig,\n} from \"./project/wrangler.js\";\nexport { CellRouter, type CellRouterOptions, ShardOwnerLostError } from \"./router/cell-router.js\";\nexport {\n createShardWorker,\n type ShardWorker,\n type ShardWorkerOptions,\n shardRouting,\n} from \"./router/shard-worker.js\";\nexport {\n type CellsHttpOptions,\n cellsHttpHandler,\n type RemoteRuntime,\n remoteRuntime,\n} from \"./transport/cells-http.js\";\nexport {\n type CellPort,\n connectRuntime,\n linkOverPort,\n serveHandlerOverPort,\n serveRuntime,\n} from \"./transport/port.js\";\nexport {\n type CellsWebSocketClass,\n createWebSocketClass,\n type WebSocketConnector,\n} from \"./ws/client.js\";\nexport { CellsResponse, takeClientPort, WebSocketPair } from \"./ws/server.js\";\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ModuleLoader } from "../bindings/worker-loader.js";
|
|
2
|
+
import type { CellStorage } from "../ports.js";
|
|
3
|
+
/**
|
|
4
|
+
* Isolated loading in browsers: each loaded Worker runs in its own Dedicated Worker
|
|
5
|
+
* (`isolateScript`, e.g. src/isolate/isolate-worker.ts). With `siteBaseUrl` (the in-browser
|
|
6
|
+
* HTTP server, docs/browser-host.md) its modules are uploaded and imported from URLs; otherwise they
|
|
7
|
+
* travel to the isolate and become Blob-URL modules there.
|
|
8
|
+
*/
|
|
9
|
+
export declare function browserIsolatedLoader(opts: {
|
|
10
|
+
isolateScript: URL;
|
|
11
|
+
siteBaseUrl?: string;
|
|
12
|
+
/** Prefix of the OPFS SQLite pool each isolate keeps its facets in (one pool per loaded id). */
|
|
13
|
+
storagePrefix?: string;
|
|
14
|
+
/** The host's storage: facets of loaded code are logged and restored through it. */
|
|
15
|
+
storage?: () => CellStorage | undefined;
|
|
16
|
+
}): ModuleLoader;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { putLoadedModule } from "../project/site.js";
|
|
2
|
+
import { isolatedModuleLoader } from "./host.js";
|
|
3
|
+
/**
|
|
4
|
+
* Isolated loading in browsers: each loaded Worker runs in its own Dedicated Worker
|
|
5
|
+
* (`isolateScript`, e.g. src/isolate/isolate-worker.ts). With `siteBaseUrl` (the in-browser
|
|
6
|
+
* HTTP server, docs/browser-host.md) its modules are uploaded and imported from URLs; otherwise they
|
|
7
|
+
* travel to the isolate and become Blob-URL modules there.
|
|
8
|
+
*/
|
|
9
|
+
export function browserIsolatedLoader(opts) {
|
|
10
|
+
const storageName = (id) => `${opts.storagePrefix ?? "isolate"}-${id}`.replace(/[^\w.-]/g, "_");
|
|
11
|
+
return isolatedModuleLoader({
|
|
12
|
+
storage: opts.storage,
|
|
13
|
+
spawn: () => {
|
|
14
|
+
const w = new Worker(opts.isolateScript, { type: "module" });
|
|
15
|
+
return { port: w, terminate: () => w.terminate() };
|
|
16
|
+
},
|
|
17
|
+
prepare: async (id, code) => {
|
|
18
|
+
if (!opts.siteBaseUrl)
|
|
19
|
+
return {
|
|
20
|
+
modules: code.modules,
|
|
21
|
+
mainModule: code.mainModule,
|
|
22
|
+
storageName: storageName(id),
|
|
23
|
+
};
|
|
24
|
+
const base = opts.siteBaseUrl.endsWith("/") ? opts.siteBaseUrl : `${opts.siteBaseUrl}/`;
|
|
25
|
+
const dir = encodeURIComponent(`isolate-${id}`);
|
|
26
|
+
for (const [name, m] of Object.entries(code.modules)) {
|
|
27
|
+
await putLoadedModule(`${base}loaded-src/${dir}/${name}`, m);
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
url: `${base}loaded/${dir}/~/${code.mainModule}`,
|
|
31
|
+
consoleId: `isolate-${id}`,
|
|
32
|
+
storageName: storageName(id),
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/isolate/browser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGjD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAOrC;IACC,MAAM,WAAW,GAAG,CAAC,EAAU,EAAE,EAAE,CACjC,GAAG,IAAI,CAAC,aAAa,IAAI,SAAS,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACtE,OAAO,oBAAoB,CAAC;QAC1B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC7D,OAAO,EAAE,IAAI,EAAE,CAAwB,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC;QAC5E,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,EAAU,EAAE,IAAgB,EAAE,EAAE;YAC9C,IAAI,CAAC,IAAI,CAAC,WAAW;gBACnB,OAAO;oBACL,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;iBACpB,CAAC;YACb,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC;YACxF,MAAM,GAAG,GAAG,kBAAkB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAChD,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrD,MAAM,eAAe,CAAC,GAAG,IAAI,cAAc,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;YAC/D,CAAC;YACD,OAAO;gBACL,GAAG,EAAE,GAAG,IAAI,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE;gBAChD,SAAS,EAAE,WAAW,EAAE,EAAE;gBAC1B,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;aACpB,CAAC;QACb,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { ModuleLoader, WorkerCode } from \"../bindings/worker-loader.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport { putLoadedModule } from \"../project/site.js\";\nimport { isolatedModuleLoader } from \"./host.js\";\nimport type { PortLike } from \"./protocol.js\";\n\n/**\n * Isolated loading in browsers: each loaded Worker runs in its own Dedicated Worker\n * (`isolateScript`, e.g. src/isolate/isolate-worker.ts). With `siteBaseUrl` (the in-browser\n * HTTP server, docs/browser-host.md) its modules are uploaded and imported from URLs; otherwise they\n * travel to the isolate and become Blob-URL modules there.\n */\nexport function browserIsolatedLoader(opts: {\n isolateScript: URL;\n siteBaseUrl?: string;\n /** Prefix of the OPFS SQLite pool each isolate keeps its facets in (one pool per loaded id). */\n storagePrefix?: string;\n /** The host's storage: facets of loaded code are logged and restored through it. */\n storage?: () => CellStorage | undefined;\n}): ModuleLoader {\n const storageName = (id: string) =>\n `${opts.storagePrefix ?? \"isolate\"}-${id}`.replace(/[^\\w.-]/g, \"_\");\n return isolatedModuleLoader({\n storage: opts.storage,\n spawn: () => {\n const w = new Worker(opts.isolateScript, { type: \"module\" });\n return { port: w as unknown as PortLike, terminate: () => w.terminate() };\n },\n prepare: async (id: string, code: WorkerCode) => {\n if (!opts.siteBaseUrl)\n return {\n modules: code.modules,\n mainModule: code.mainModule,\n storageName: storageName(id),\n } as never;\n const base = opts.siteBaseUrl.endsWith(\"/\") ? opts.siteBaseUrl : `${opts.siteBaseUrl}/`;\n const dir = encodeURIComponent(`isolate-${id}`);\n for (const [name, m] of Object.entries(code.modules)) {\n await putLoadedModule(`${base}loaded-src/${dir}/${name}`, m);\n }\n return {\n url: `${base}loaded/${dir}/~/${code.mainModule}`,\n consoleId: `isolate-${id}`,\n storageName: storageName(id),\n } as never;\n },\n });\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ModuleLoader, type WorkerCode } from "../bindings/worker-loader.js";
|
|
2
|
+
import type { CellStorage } from "../ports.js";
|
|
3
|
+
import { type PortLike } from "./protocol.js";
|
|
4
|
+
/**
|
|
5
|
+
* Worker Loader whose code runs in a separate realm per loaded Worker (an isolate). Returns
|
|
6
|
+
* a module facade: each export is an object whose `fetch()` and methods cross the port.
|
|
7
|
+
* Durable Object classes cannot cross (their storage API is synchronous): use an in-realm
|
|
8
|
+
* loader for `getDurableObjectClass` (see `workerLoader(load, { classes })`).
|
|
9
|
+
*/
|
|
10
|
+
export declare function isolatedModuleLoader(opts: {
|
|
11
|
+
/**
|
|
12
|
+
* The host's storage, so facets of loaded code are logged and restored like the root's
|
|
13
|
+
* own (celld: one stream per facet under the root, the root's epoch).
|
|
14
|
+
*/
|
|
15
|
+
storage?: () => CellStorage | undefined;
|
|
16
|
+
spawn(id: string): {
|
|
17
|
+
port: PortLike;
|
|
18
|
+
terminate(): void;
|
|
19
|
+
};
|
|
20
|
+
prepare(id: string, code: WorkerCode): Promise<{
|
|
21
|
+
source?: string;
|
|
22
|
+
url?: string;
|
|
23
|
+
}>;
|
|
24
|
+
}): ModuleLoader;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { outboundFetch, } from "../bindings/worker-loader.js";
|
|
2
|
+
import { ISOLATED } from "../core/handles.js";
|
|
3
|
+
import { hostPort } from "./protocol.js";
|
|
4
|
+
/**
|
|
5
|
+
* Worker Loader whose code runs in a separate realm per loaded Worker (an isolate). Returns
|
|
6
|
+
* a module facade: each export is an object whose `fetch()` and methods cross the port.
|
|
7
|
+
* Durable Object classes cannot cross (their storage API is synchronous): use an in-realm
|
|
8
|
+
* loader for `getDurableObjectClass` (see `workerLoader(load, { classes })`).
|
|
9
|
+
*/
|
|
10
|
+
export function isolatedModuleLoader(opts) {
|
|
11
|
+
return async (id, code, logs) => {
|
|
12
|
+
// The env crosses as any call does: bindings and other stubs by reference.
|
|
13
|
+
const env = { ...code.env };
|
|
14
|
+
// The loaded code's global fetch(): blocked in the isolate, or sent back here to the Fetcher.
|
|
15
|
+
const fetcher = outboundFetch(code);
|
|
16
|
+
const outbound = code.globalOutbound === null ? "blocked" : fetcher ? "fetcher" : undefined;
|
|
17
|
+
const where = await opts.prepare(id, code);
|
|
18
|
+
const isolate = opts.spawn(id);
|
|
19
|
+
const { call, fetch } = await hostPort(isolate.port, async (m) => {
|
|
20
|
+
if (m.type === "durable") {
|
|
21
|
+
const st = opts.storage?.() ?? {};
|
|
22
|
+
if (m.op === "load")
|
|
23
|
+
return st.backup?.load?.(m.cellKey);
|
|
24
|
+
if (m.op === "committed" && st.durability) {
|
|
25
|
+
const info = m.info;
|
|
26
|
+
const token = info.image;
|
|
27
|
+
await st.durability.committed(m.cellKey, {
|
|
28
|
+
...info,
|
|
29
|
+
image: typeof token === "number"
|
|
30
|
+
? () => call({ type: "image", token })
|
|
31
|
+
: token,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (m.type === "log") {
|
|
37
|
+
logs?.(m.level, m.args);
|
|
38
|
+
console[m.level](...m.args);
|
|
39
|
+
}
|
|
40
|
+
}, fetcher);
|
|
41
|
+
const exports = await call({
|
|
42
|
+
type: "load",
|
|
43
|
+
...where,
|
|
44
|
+
env,
|
|
45
|
+
outbound,
|
|
46
|
+
});
|
|
47
|
+
const facade = (name) => new Proxy({}, {
|
|
48
|
+
get(_t, prop) {
|
|
49
|
+
if (prop === "then" || typeof prop === "symbol")
|
|
50
|
+
return undefined;
|
|
51
|
+
// Called as a plain-object entrypoint (entrypointStub): `ctx` comes last, after `env`
|
|
52
|
+
// (the isolate has its own); its props cross with the call.
|
|
53
|
+
if (prop === "fetch")
|
|
54
|
+
return (req, _env, ctx) => fetch({ name, props: ctx?.props }, req);
|
|
55
|
+
return (...args) => {
|
|
56
|
+
const ctx = args.pop();
|
|
57
|
+
args.pop();
|
|
58
|
+
return call({ type: "call", name, method: prop, args, props: ctx.props });
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
const module = Object.fromEntries(Object.keys(exports).map((k) => [k, facade(k)]));
|
|
63
|
+
// Durable Object classes of the loaded code run in the isolate too (facets).
|
|
64
|
+
module[ISOLATED] = (className) => ({
|
|
65
|
+
fetch: (cellKey, req) => fetch({ className, cellKey }, req),
|
|
66
|
+
call: (cellKey, method, args) => call({ type: "object", op: "call", className, cellKey, method, args }),
|
|
67
|
+
restart: (cellKey) => call({ type: "object", op: "restart", className, cellKey }),
|
|
68
|
+
delete: (cellKey) => call({ type: "object", op: "delete", className, cellKey }),
|
|
69
|
+
attach: (cellKey, epoch) => call({ type: "object", op: "attach", className, cellKey, epoch }),
|
|
70
|
+
});
|
|
71
|
+
return module;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/isolate/host.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type LogSink,\n type ModuleLoader,\n outboundFetch,\n type WorkerCode,\n} from \"../bindings/worker-loader.js\";\nimport { ISOLATED, type IsolatedClass } from \"../core/handles.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport { hostPort, type PortLike } from \"./protocol.js\";\n\n/**\n * Worker Loader whose code runs in a separate realm per loaded Worker (an isolate). Returns\n * a module facade: each export is an object whose `fetch()` and methods cross the port.\n * Durable Object classes cannot cross (their storage API is synchronous): use an in-realm\n * loader for `getDurableObjectClass` (see `workerLoader(load, { classes })`).\n */\nexport function isolatedModuleLoader(opts: {\n /**\n * The host's storage, so facets of loaded code are logged and restored like the root's\n * own (celld: one stream per facet under the root, the root's epoch).\n */\n storage?: () => CellStorage | undefined;\n spawn(id: string): { port: PortLike; terminate(): void };\n prepare(id: string, code: WorkerCode): Promise<{ source?: string; url?: string }>;\n}): ModuleLoader {\n return async (id: string, code: WorkerCode, logs?: LogSink) => {\n // The env crosses as any call does: bindings and other stubs by reference.\n const env: Record<string, unknown> = { ...code.env };\n // The loaded code's global fetch(): blocked in the isolate, or sent back here to the Fetcher.\n const fetcher = outboundFetch(code);\n const outbound = code.globalOutbound === null ? \"blocked\" : fetcher ? \"fetcher\" : undefined;\n const where = await opts.prepare(id, code);\n const isolate = opts.spawn(id);\n const { call, fetch } = await hostPort(\n isolate.port,\n async (m) => {\n if (m.type === \"durable\") {\n const st = opts.storage?.() ?? {};\n if (m.op === \"load\") return st.backup?.load?.(m.cellKey);\n if (m.op === \"committed\" && st.durability) {\n const info = m.info;\n const token = info.image;\n await st.durability.committed(m.cellKey, {\n ...info,\n image:\n typeof token === \"number\"\n ? () => call<Uint8Array | undefined>({ type: \"image\", token })\n : token,\n });\n }\n return;\n }\n if (m.type === \"log\") {\n logs?.(m.level, m.args);\n (console as any)[m.level](...m.args);\n }\n },\n fetcher,\n );\n const exports = await call<Record<string, string>>({\n type: \"load\",\n ...where,\n env,\n outbound,\n });\n const facade = (name: string) =>\n new Proxy(\n {},\n {\n get(_t, prop) {\n if (prop === \"then\" || typeof prop === \"symbol\") return undefined;\n // Called as a plain-object entrypoint (entrypointStub): `ctx` comes last, after `env`\n // (the isolate has its own); its props cross with the call.\n if (prop === \"fetch\")\n return (req: Request, _env: unknown, ctx?: { props?: unknown }) =>\n fetch({ name, props: ctx?.props }, req);\n return (...args: unknown[]) => {\n const ctx = args.pop() as { props?: unknown };\n args.pop();\n return call({ type: \"call\", name, method: prop, args, props: ctx.props });\n };\n },\n },\n );\n const module: Record<string | symbol, unknown> = Object.fromEntries(\n Object.keys(exports).map((k) => [k, facade(k)]),\n );\n // Durable Object classes of the loaded code run in the isolate too (facets).\n module[ISOLATED] = (className: string): IsolatedClass => ({\n fetch: (cellKey, req) => fetch({ className, cellKey }, req),\n call: (cellKey, method, args) =>\n call({ type: \"object\", op: \"call\", className, cellKey, method, args }),\n restart: (cellKey) => call({ type: \"object\", op: \"restart\", className, cellKey }),\n delete: (cellKey) => call({ type: \"object\", op: \"delete\", className, cellKey }),\n attach: (cellKey, epoch) => call({ type: \"object\", op: \"attach\", className, cellKey, epoch }),\n });\n return module as Record<string, unknown>;\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/// <reference lib="webworker" />
|
|
2
|
+
// One loaded Worker in its own realm (a Dedicated Worker), served over its port.
|
|
3
|
+
import sqlite3InitModule from "@sqlite.org/sqlite-wasm";
|
|
4
|
+
import { sahpoolOpener } from "../adapters/wasm-sqlite.js";
|
|
5
|
+
import { browserModuleLoader, PROJECT_WORKERS_MODULE_SHIM } from "../project/browser-modules.js";
|
|
6
|
+
import * as emailModule from "../project/cloudflare-email.js";
|
|
7
|
+
import * as workersModule from "../project/cloudflare-workers.js";
|
|
8
|
+
import { workersHostRegistry } from "../project/site.js";
|
|
9
|
+
import { realmWorkerScope } from "../project/worker-scope.js";
|
|
10
|
+
import * as workersGlobals from "../project/workers-globals-module.js";
|
|
11
|
+
import { serveIsolate } from "./isolate.js";
|
|
12
|
+
globalThis.__cellsWorkersModule = workersModule;
|
|
13
|
+
// The loaded Worker's own `env` and `exports` (serveIsolate binds the realm's scope to them).
|
|
14
|
+
const scope = realmWorkerScope();
|
|
15
|
+
workersHostRegistry({
|
|
16
|
+
workersModule: {
|
|
17
|
+
...workersModule,
|
|
18
|
+
env: scope.env,
|
|
19
|
+
exports: scope.exports,
|
|
20
|
+
waitUntil: scope.waitUntil,
|
|
21
|
+
},
|
|
22
|
+
emailModule,
|
|
23
|
+
...workersGlobals,
|
|
24
|
+
Request: workersGlobals.CellsRequest,
|
|
25
|
+
Response: workersGlobals.CellsResponse,
|
|
26
|
+
});
|
|
27
|
+
// The global console is left alone (the dev server's client logs here too): loaded modules
|
|
28
|
+
// get a console of their own that reports to the host.
|
|
29
|
+
serveIsolate(self, async (load, logs) => {
|
|
30
|
+
const own = Object.assign(Object.create(console), {
|
|
31
|
+
log: (...a) => logs("log", a),
|
|
32
|
+
info: (...a) => logs("info", a),
|
|
33
|
+
warn: (...a) => logs("warn", a),
|
|
34
|
+
error: (...a) => logs("error", a),
|
|
35
|
+
debug: (...a) => logs("debug", a),
|
|
36
|
+
});
|
|
37
|
+
if (load.url) {
|
|
38
|
+
// The site's per-id module server binds `console` to __cellsLoadedConsoles[id].
|
|
39
|
+
const g = globalThis;
|
|
40
|
+
g.__cellsLoadedConsoles ??= {};
|
|
41
|
+
g.__cellsLoadedConsoles[load.consoleId] = own;
|
|
42
|
+
return (await import(/* @vite-ignore */ load.url));
|
|
43
|
+
}
|
|
44
|
+
return browserModuleLoader(PROJECT_WORKERS_MODULE_SHIM)("isolate", { mainModule: load.mainModule, modules: load.modules }, (level, args) => logs(level, args));
|
|
45
|
+
}, {
|
|
46
|
+
patchConsole: false,
|
|
47
|
+
// Facets of the loaded code: SQLite on OPFS, one sahpool per loaded Worker.
|
|
48
|
+
openSql: async (load) => {
|
|
49
|
+
const sqlite3 = await sqlite3InitModule({ print() { }, printErr() { } });
|
|
50
|
+
return sahpoolOpener(sqlite3, { name: load?.storageName ?? "isolate" });
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=isolate-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isolate-worker.js","sourceRoot":"","sources":["../../src/isolate/isolate-worker.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,iFAAiF;AAEjF,OAAO,iBAAiB,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AACjG,OAAO,KAAK,WAAW,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,aAAa,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,cAAc,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG3C,UAAsC,CAAC,oBAAoB,GAAG,aAAa,CAAC;AAC7E,8FAA8F;AAC9F,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;AACjC,mBAAmB,CAAC;IAClB,aAAa,EAAE;QACb,GAAG,aAAa;QAChB,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B;IACD,WAAW;IACX,GAAG,cAAc;IACjB,OAAO,EAAE,cAAc,CAAC,YAAY;IACpC,QAAQ,EAAE,cAAc,CAAC,aAAa;CACvC,CAAC,CAAC;AAEH,2FAA2F;AAC3F,uDAAuD;AACvD,YAAY,CACV,IAA2B,EAC3B,KAAK,EAAE,IAAS,EAAE,IAAI,EAAE,EAAE;IACxB,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;QAChD,GAAG,EAAE,CAAC,GAAG,CAAY,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACxC,IAAI,EAAE,CAAC,GAAG,CAAY,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1C,IAAI,EAAE,CAAC,GAAG,CAAY,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1C,KAAK,EAAE,CAAC,GAAG,CAAY,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5C,KAAK,EAAE,CAAC,GAAG,CAAY,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;KAC7C,CAAC,CAAC;IACH,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,gFAAgF;QAChF,MAAM,CAAC,GAAG,UAAiC,CAAC;QAC5C,CAAC,CAAC,qBAAqB,KAAK,EAAE,CAAC;QAC/B,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC;QAC9C,OAAO,CAAC,MAAM,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAA4B,CAAC;IAChF,CAAC;IACD,OAAO,mBAAmB,CAAC,2BAA2B,CAAC,CACrD,SAAS,EACT,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EACtD,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CACnC,CAAC;AACJ,CAAC,EACD;IACE,YAAY,EAAE,KAAK;IACnB,4EAA4E;IAC5E,OAAO,EAAE,KAAK,EAAE,IAAS,EAAE,EAAE;QAC3B,MAAM,OAAO,GAAG,MAAO,iBAAyB,CAAC,EAAE,KAAK,KAAI,CAAC,EAAE,QAAQ,KAAI,CAAC,EAAE,CAAC,CAAC;QAChF,OAAO,aAAa,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,IAAI,SAAS,EAAE,CAAC,CAAC;IAC1E,CAAC;CACF,CACF,CAAC","sourcesContent":["/// <reference lib=\"webworker\" />\n// One loaded Worker in its own realm (a Dedicated Worker), served over its port.\n\nimport sqlite3InitModule from \"@sqlite.org/sqlite-wasm\";\nimport { sahpoolOpener } from \"../adapters/wasm-sqlite.js\";\nimport { browserModuleLoader, PROJECT_WORKERS_MODULE_SHIM } from \"../project/browser-modules.js\";\nimport * as emailModule from \"../project/cloudflare-email.js\";\nimport * as workersModule from \"../project/cloudflare-workers.js\";\nimport { workersHostRegistry } from \"../project/site.js\";\nimport { realmWorkerScope } from \"../project/worker-scope.js\";\nimport * as workersGlobals from \"../project/workers-globals-module.js\";\nimport { serveIsolate } from \"./isolate.js\";\nimport type { PortLike } from \"./protocol.js\";\n\n(globalThis as Record<string, unknown>).__cellsWorkersModule = workersModule;\n// The loaded Worker's own `env` and `exports` (serveIsolate binds the realm's scope to them).\nconst scope = realmWorkerScope();\nworkersHostRegistry({\n workersModule: {\n ...workersModule,\n env: scope.env,\n exports: scope.exports,\n waitUntil: scope.waitUntil,\n },\n emailModule,\n ...workersGlobals,\n Request: workersGlobals.CellsRequest,\n Response: workersGlobals.CellsResponse,\n});\n\n// The global console is left alone (the dev server's client logs here too): loaded modules\n// get a console of their own that reports to the host.\nserveIsolate(\n self as unknown as PortLike,\n async (load: any, logs) => {\n const own = Object.assign(Object.create(console), {\n log: (...a: unknown[]) => logs(\"log\", a),\n info: (...a: unknown[]) => logs(\"info\", a),\n warn: (...a: unknown[]) => logs(\"warn\", a),\n error: (...a: unknown[]) => logs(\"error\", a),\n debug: (...a: unknown[]) => logs(\"debug\", a),\n });\n if (load.url) {\n // The site's per-id module server binds `console` to __cellsLoadedConsoles[id].\n const g = globalThis as Record<string, any>;\n g.__cellsLoadedConsoles ??= {};\n g.__cellsLoadedConsoles[load.consoleId] = own;\n return (await import(/* @vite-ignore */ load.url)) as Record<string, unknown>;\n }\n return browserModuleLoader(PROJECT_WORKERS_MODULE_SHIM)(\n \"isolate\",\n { mainModule: load.mainModule, modules: load.modules },\n (level, args) => logs(level, args),\n );\n },\n {\n patchConsole: false,\n // Facets of the loaded code: SQLite on OPFS, one sahpool per loaded Worker.\n openSql: async (load: any) => {\n const sqlite3 = await (sqlite3InitModule as any)({ print() {}, printErr() {} });\n return sahpoolOpener(sqlite3, { name: load?.storageName ?? \"isolate\" });\n },\n },\n);\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { OpenCellSql } from "../ports.js";
|
|
2
|
+
import { type PortLike } from "./protocol.js";
|
|
3
|
+
export declare function serveIsolate(port: PortLike, importCode: (load: any, logs: (level: string, args: unknown[]) => void) => Promise<Record<string, unknown>>, opts?: {
|
|
4
|
+
patchConsole?: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Storage for Durable Object classes run INSIDE this isolate (facets of loaded code):
|
|
7
|
+
* each facet is a cell of an isolate-local runtime, with its own SQLite.
|
|
8
|
+
*/
|
|
9
|
+
openSql?: (load: any) => OpenCellSql | Promise<OpenCellSql>;
|
|
10
|
+
}): void;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The isolate side: loads the Worker code in THIS realm and serves fetch/RPC for the host.
|
|
3
|
+
* `importCode` is realm specific (data: URL of a bundle on Node, a site URL in browsers).
|
|
4
|
+
*/
|
|
5
|
+
import { ctxExports, entrypointStub } from "../core/handles.js";
|
|
6
|
+
import { runInDurableObject } from "../core/namespace.js";
|
|
7
|
+
import { createCellRuntime } from "../core/runtime.js";
|
|
8
|
+
import { realmWorkerScope } from "../project/worker-scope.js";
|
|
9
|
+
import { isolatePort } from "./protocol.js";
|
|
10
|
+
export function serveIsolate(port, importCode, opts = {}) {
|
|
11
|
+
let module = {};
|
|
12
|
+
const runtimes = new Map();
|
|
13
|
+
// Facet logging through the host: the isolate-local cell key → the facet's key in the
|
|
14
|
+
// root's storage (celld: <root>/facets/<sha>) and the root's epoch.
|
|
15
|
+
const facetKeys = new Map();
|
|
16
|
+
const images = new Map();
|
|
17
|
+
let nextImage = 0;
|
|
18
|
+
const hostLogged = (internal) => facetKeys.get(internal);
|
|
19
|
+
const durability = {
|
|
20
|
+
capturePages: true,
|
|
21
|
+
async committed(cellKey, info) {
|
|
22
|
+
const f = hostLogged(cellKey);
|
|
23
|
+
if (!f)
|
|
24
|
+
return;
|
|
25
|
+
const token = ++nextImage;
|
|
26
|
+
if (typeof info.image === "function")
|
|
27
|
+
images.set(token, info.image);
|
|
28
|
+
try {
|
|
29
|
+
await call({
|
|
30
|
+
type: "durable",
|
|
31
|
+
op: "committed",
|
|
32
|
+
cellKey: f.key,
|
|
33
|
+
info: {
|
|
34
|
+
seq: info.seq,
|
|
35
|
+
pages: info.pages,
|
|
36
|
+
epoch: f.epoch,
|
|
37
|
+
image: typeof info.image === "function" ? token : info.image,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
images.delete(token);
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
const backup = {
|
|
47
|
+
async load(cellKey) {
|
|
48
|
+
const f = hostLogged(cellKey);
|
|
49
|
+
return f
|
|
50
|
+
? (await call({ type: "durable", op: "load", cellKey: f.key }))
|
|
51
|
+
: undefined;
|
|
52
|
+
},
|
|
53
|
+
async save() { },
|
|
54
|
+
};
|
|
55
|
+
// The host holds the root's lease and attaches each facet with its epoch: handing that epoch
|
|
56
|
+
// out as the facet's own lease makes its ObjectHost rebuild the local database from the
|
|
57
|
+
// bucket when it opens, as a root does under a lease (a pool kept from an earlier ownership
|
|
58
|
+
// is older than what other nodes wrote since). Without an epoch, the local file stays primary.
|
|
59
|
+
const ownership = {
|
|
60
|
+
async tryAcquire(cellKey) {
|
|
61
|
+
const lost = new AbortController().signal; // fencing stays with the root's lease, in the host
|
|
62
|
+
return {
|
|
63
|
+
name: cellKey,
|
|
64
|
+
epoch: hostLogged(cellKey)?.epoch,
|
|
65
|
+
lost,
|
|
66
|
+
release: async () => { },
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
let loadMsg;
|
|
71
|
+
let sql;
|
|
72
|
+
const objectRuntime = async (className) => {
|
|
73
|
+
let rt = runtimes.get(className);
|
|
74
|
+
if (!rt) {
|
|
75
|
+
if (!opts.openSql)
|
|
76
|
+
throw new Error("this isolate cannot host Durable Object classes (no storage)");
|
|
77
|
+
sql ??= Promise.resolve(opts.openSql(loadMsg));
|
|
78
|
+
const openSql = await sql;
|
|
79
|
+
if (runtimes.has(className))
|
|
80
|
+
return runtimes.get(className);
|
|
81
|
+
if (typeof module[className] !== "function")
|
|
82
|
+
throw new Error(`Loaded worker does not export class "${className}"`);
|
|
83
|
+
rt = createCellRuntime({
|
|
84
|
+
worker: { ...module, default: {} },
|
|
85
|
+
durableObjects: { [className]: { className } },
|
|
86
|
+
openSql,
|
|
87
|
+
vars: env, // the loaded Worker's env: plain values and host stubs
|
|
88
|
+
storage: { durability, backup, ownership },
|
|
89
|
+
facets: true, // rows move to this run's scope on open, as celld does for facets
|
|
90
|
+
});
|
|
91
|
+
runtimes.set(className, rt);
|
|
92
|
+
}
|
|
93
|
+
return rt;
|
|
94
|
+
};
|
|
95
|
+
let env = {};
|
|
96
|
+
let exports = {};
|
|
97
|
+
// The loaded Worker is this realm's own: its `cloudflare:workers` reads `env` and `exports` here.
|
|
98
|
+
const scope = realmWorkerScope();
|
|
99
|
+
// A facet of loaded code: the object lives here, named by the parent's facet cell key.
|
|
100
|
+
const facet = async (className, cellKey) => {
|
|
101
|
+
const rt = await objectRuntime(className);
|
|
102
|
+
const ns = rt.env[className];
|
|
103
|
+
return { rt, stub: ns.getByName(cellKey), key: `${className}/${ns.idFromName(cellKey)}` };
|
|
104
|
+
};
|
|
105
|
+
const exported = (name, props) => {
|
|
106
|
+
const target = module[name];
|
|
107
|
+
if (target === undefined)
|
|
108
|
+
throw new Error(`Loaded worker does not export "${name}"`);
|
|
109
|
+
return entrypointStub(target, env, props, exports);
|
|
110
|
+
};
|
|
111
|
+
const fetchTarget = async (t, req) => "className" in t
|
|
112
|
+
? (await facet(t.className, t.cellKey)).stub.fetch(req)
|
|
113
|
+
: exported(t.name, t.props).fetch(req);
|
|
114
|
+
const handle = async (m) => {
|
|
115
|
+
if (m.type === "load") {
|
|
116
|
+
loadMsg = m;
|
|
117
|
+
env = m.env; // host bindings arrive as stubs: every call goes back to the host
|
|
118
|
+
// Logs go to the host (Tail Workers, and the host prints them): through the global
|
|
119
|
+
// console, or — where the realm has other code that logs — a console scoped to the
|
|
120
|
+
// loaded modules (importCode receives the sink).
|
|
121
|
+
const sink = (level, args) => call({ type: "log", level, args: safe(args) }).catch(() => { });
|
|
122
|
+
if (opts.patchConsole !== false)
|
|
123
|
+
for (const level of ["log", "info", "warn", "error", "debug"])
|
|
124
|
+
console[level] = (...args) => sink(level, args);
|
|
125
|
+
if (m.outbound === "fetcher")
|
|
126
|
+
globalThis.fetch = (async (input, init) => outbound(new Request(input, init)));
|
|
127
|
+
if (m.outbound === "blocked")
|
|
128
|
+
globalThis.fetch = (async () => {
|
|
129
|
+
throw new Error("This worker is not permitted to access the internet via global functions like fetch(). It must use capabilities (such as bindings in 'env') to talk to the outside world.");
|
|
130
|
+
});
|
|
131
|
+
scope.bind({ env, exports }); // read while the module is evaluated
|
|
132
|
+
module = await importCode(m, sink);
|
|
133
|
+
exports = ctxExports(module, env);
|
|
134
|
+
scope.bind({ env, exports });
|
|
135
|
+
return Object.fromEntries(Object.entries(module).map(([k, v]) => [k, typeof v]));
|
|
136
|
+
}
|
|
137
|
+
if (m.type === "image")
|
|
138
|
+
return await images.get(m.token)?.();
|
|
139
|
+
if (m.type === "object") {
|
|
140
|
+
const { rt, stub, key } = await facet(m.className, m.cellKey);
|
|
141
|
+
if (m.op === "attach") {
|
|
142
|
+
facetKeys.set(key, { key: m.cellKey, epoch: m.epoch });
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (m.op === "call")
|
|
146
|
+
return stub[m.method](...m.args);
|
|
147
|
+
if (m.op === "restart")
|
|
148
|
+
return rt.restartObject(key);
|
|
149
|
+
if (m.op === "delete") {
|
|
150
|
+
await runInDurableObject(stub, (_o, ctx) => ctx.storage.deleteAll());
|
|
151
|
+
return rt.restartObject(key);
|
|
152
|
+
}
|
|
153
|
+
throw new Error(`unknown object op ${m.op}`);
|
|
154
|
+
}
|
|
155
|
+
if (m.type === "call")
|
|
156
|
+
return exported(m.name, m.props)[m.method](...m.args);
|
|
157
|
+
throw new Error(`unknown isolate message ${m.type}`);
|
|
158
|
+
};
|
|
159
|
+
const { call, outbound } = isolatePort(port, handle, fetchTarget);
|
|
160
|
+
}
|
|
161
|
+
const safe = (args) => args.map((a) => {
|
|
162
|
+
try {
|
|
163
|
+
return structuredClone(a);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return String(a);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
//# sourceMappingURL=isolate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isolate.js","sourceRoot":"","sources":["../../src/isolate/isolate.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The isolate side: loads the Worker code in THIS realm and serves fetch/RPC for the host.\n * `importCode` is realm specific (data: URL of a bundle on Node, a site URL in browsers).\n */\nimport { ctxExports, entrypointStub } from \"../core/handles.js\";\nimport { runInDurableObject } from \"../core/namespace.js\";\nimport { type CellRuntime, createCellRuntime, type WorkerModule } from \"../core/runtime.js\";\nimport type { Lease, LeaseHandle, OpenCellSql } from \"../ports.js\";\nimport { realmWorkerScope } from \"../project/worker-scope.js\";\nimport { type FetchTarget, isolatePort, type PortLike } from \"./protocol.js\";\n\nexport function serveIsolate(\n port: PortLike,\n importCode: (\n load: any,\n logs: (level: string, args: unknown[]) => void,\n ) => Promise<Record<string, unknown>>,\n opts: {\n patchConsole?: boolean;\n /**\n * Storage for Durable Object classes run INSIDE this isolate (facets of loaded code):\n * each facet is a cell of an isolate-local runtime, with its own SQLite.\n */\n openSql?: (load: any) => OpenCellSql | Promise<OpenCellSql>;\n } = {},\n) {\n let module: Record<string, unknown> = {};\n const runtimes = new Map<string, CellRuntime>();\n // Facet logging through the host: the isolate-local cell key → the facet's key in the\n // root's storage (celld: <root>/facets/<sha>) and the root's epoch.\n const facetKeys = new Map<string, { key: string; epoch?: number }>();\n const images = new Map<number, () => unknown>();\n let nextImage = 0;\n const hostLogged = (internal: string) => facetKeys.get(internal);\n const durability = {\n capturePages: true,\n async committed(cellKey: string, info: any) {\n const f = hostLogged(cellKey);\n if (!f) return;\n const token = ++nextImage;\n if (typeof info.image === \"function\") images.set(token, info.image);\n try {\n await call({\n type: \"durable\",\n op: \"committed\",\n cellKey: f.key,\n info: {\n seq: info.seq,\n pages: info.pages,\n epoch: f.epoch,\n image: typeof info.image === \"function\" ? token : info.image,\n },\n });\n } finally {\n images.delete(token);\n }\n },\n };\n const backup = {\n async load(cellKey: string) {\n const f = hostLogged(cellKey);\n return f\n ? ((await call({ type: \"durable\", op: \"load\", cellKey: f.key })) as Uint8Array | undefined)\n : undefined;\n },\n async save() {},\n };\n // The host holds the root's lease and attaches each facet with its epoch: handing that epoch\n // out as the facet's own lease makes its ObjectHost rebuild the local database from the\n // bucket when it opens, as a root does under a lease (a pool kept from an earlier ownership\n // is older than what other nodes wrote since). Without an epoch, the local file stays primary.\n const ownership: Lease = {\n async tryAcquire(cellKey) {\n const lost = new AbortController().signal; // fencing stays with the root's lease, in the host\n return {\n name: cellKey,\n epoch: hostLogged(cellKey)?.epoch,\n lost,\n release: async () => {},\n } as LeaseHandle;\n },\n };\n let loadMsg: any;\n let sql: Promise<OpenCellSql> | undefined;\n const objectRuntime = async (className: string) => {\n let rt = runtimes.get(className);\n if (!rt) {\n if (!opts.openSql)\n throw new Error(\"this isolate cannot host Durable Object classes (no storage)\");\n sql ??= Promise.resolve(opts.openSql(loadMsg));\n const openSql = await sql;\n if (runtimes.has(className)) return runtimes.get(className)!;\n if (typeof module[className] !== \"function\")\n throw new Error(`Loaded worker does not export class \"${className}\"`);\n rt = createCellRuntime({\n worker: { ...(module as WorkerModule), default: {} },\n durableObjects: { [className]: { className } },\n openSql,\n vars: env, // the loaded Worker's env: plain values and host stubs\n storage: { durability, backup, ownership },\n facets: true, // rows move to this run's scope on open, as celld does for facets\n });\n runtimes.set(className, rt);\n }\n return rt;\n };\n let env: Record<string, unknown> = {};\n let exports: Record<string, unknown> = {};\n // The loaded Worker is this realm's own: its `cloudflare:workers` reads `env` and `exports` here.\n const scope = realmWorkerScope();\n // A facet of loaded code: the object lives here, named by the parent's facet cell key.\n const facet = async (className: string, cellKey: string) => {\n const rt = await objectRuntime(className);\n const ns = rt.env[className] as {\n getByName(n: string): any;\n idFromName(n: string): { toString(): string };\n };\n return { rt, stub: ns.getByName(cellKey), key: `${className}/${ns.idFromName(cellKey)}` };\n };\n const exported = (name: string, props?: unknown) => {\n const target = module[name];\n if (target === undefined) throw new Error(`Loaded worker does not export \"${name}\"`);\n return entrypointStub(target, env, props, exports);\n };\n const fetchTarget = async (t: FetchTarget, req: Request): Promise<Response> =>\n \"className\" in t\n ? (await facet(t.className, t.cellKey)).stub.fetch(req)\n : exported(t.name, t.props).fetch(req);\n const handle = async (m: any) => {\n if (m.type === \"load\") {\n loadMsg = m;\n env = m.env; // host bindings arrive as stubs: every call goes back to the host\n // Logs go to the host (Tail Workers, and the host prints them): through the global\n // console, or — where the realm has other code that logs — a console scoped to the\n // loaded modules (importCode receives the sink).\n const sink = (level: string, args: unknown[]) =>\n call({ type: \"log\", level, args: safe(args) }).catch(() => {});\n if (opts.patchConsole !== false)\n for (const level of [\"log\", \"info\", \"warn\", \"error\", \"debug\"] as const)\n console[level] = (...args: unknown[]) => sink(level, args);\n if (m.outbound === \"fetcher\")\n globalThis.fetch = (async (input: RequestInfo | URL, init?: RequestInit) =>\n outbound(new Request(input, init))) as typeof fetch;\n if (m.outbound === \"blocked\")\n globalThis.fetch = (async () => {\n throw new Error(\n \"This worker is not permitted to access the internet via global functions like fetch(). It must use capabilities (such as bindings in 'env') to talk to the outside world.\",\n );\n }) as typeof fetch;\n scope.bind({ env, exports }); // read while the module is evaluated\n module = await importCode(m, sink);\n exports = ctxExports(module, env);\n scope.bind({ env, exports });\n return Object.fromEntries(Object.entries(module).map(([k, v]) => [k, typeof v]));\n }\n if (m.type === \"image\") return await images.get(m.token)?.();\n if (m.type === \"object\") {\n const { rt, stub, key } = await facet(m.className, m.cellKey);\n if (m.op === \"attach\") {\n facetKeys.set(key, { key: m.cellKey, epoch: m.epoch });\n return;\n }\n if (m.op === \"call\") return stub[m.method](...m.args);\n if (m.op === \"restart\") return rt.restartObject(key);\n if (m.op === \"delete\") {\n await runInDurableObject(\n stub,\n (_o: unknown, ctx: { storage: { deleteAll(): Promise<void> } }) =>\n ctx.storage.deleteAll(),\n );\n return rt.restartObject(key);\n }\n throw new Error(`unknown object op ${m.op}`);\n }\n if (m.type === \"call\") return exported(m.name, m.props)[m.method](...m.args);\n throw new Error(`unknown isolate message ${m.type}`);\n };\n const { call, outbound } = isolatePort(port, handle, fetchTarget);\n}\n\nconst safe = (args: unknown[]) =>\n args.map((a) => {\n try {\n return structuredClone(a);\n } catch {\n return String(a);\n }\n });\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// A worker thread hosting ONE loaded Worker (an isolate); see src/isolate/protocol.ts.
|
|
2
|
+
import { parentPort } from "node:worker_threads";
|
|
3
|
+
import { nodeSqliteOpener } from "../adapters/node-sqlite.js";
|
|
4
|
+
import { serveIsolate } from "./isolate.js";
|
|
5
|
+
// An exception no request awaits (a timer, ctx.abort() from one) is reported, and the isolate
|
|
6
|
+
// lives on, as in a browser Dedicated Worker and workerd; Node would end the thread.
|
|
7
|
+
process.on("uncaughtException", (e) => console.error("Uncaught", e));
|
|
8
|
+
serveIsolate(parentPort, async ({ source }) => import(`data:text/javascript;base64,${Buffer.from(source ?? "").toString("base64")}`),
|
|
9
|
+
// Facets of the loaded code keep their SQLite here: files under `dataDir` when the host
|
|
10
|
+
// gives one, else in memory (lost with the isolate).
|
|
11
|
+
{ openSql: (load) => nodeSqliteOpener(load?.dataDir) });
|
|
12
|
+
//# sourceMappingURL=node-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-entry.js","sourceRoot":"","sources":["../../src/isolate/node-entry.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,8FAA8F;AAC9F,qFAAqF;AACrF,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAErE,YAAY,CACV,UAAiC,EACjC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CACnB,MAAM,CAAC,+BAA+B,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;AACvF,wFAAwF;AACxF,qDAAqD;AACrD,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CACvD,CAAC","sourcesContent":["// A worker thread hosting ONE loaded Worker (an isolate); see src/isolate/protocol.ts.\nimport { parentPort } from \"node:worker_threads\";\nimport { nodeSqliteOpener } from \"../adapters/node-sqlite.js\";\nimport { serveIsolate } from \"./isolate.js\";\nimport type { PortLike } from \"./protocol.js\";\n\n// An exception no request awaits (a timer, ctx.abort() from one) is reported, and the isolate\n// lives on, as in a browser Dedicated Worker and workerd; Node would end the thread.\nprocess.on(\"uncaughtException\", (e) => console.error(\"Uncaught\", e));\n\nserveIsolate(\n parentPort as unknown as PortLike,\n async ({ source }) =>\n import(`data:text/javascript;base64,${Buffer.from(source ?? \"\").toString(\"base64\")}`),\n // Facets of the loaded code keep their SQLite here: files under `dataDir` when the host\n // gives one, else in memory (lost with the isolate).\n { openSql: (load) => nodeSqliteOpener(load?.dataDir) },\n);\n"]}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Isolation for loaded Workers (celld runs each in its own V8 isolate): the loaded code runs
|
|
3
|
+
* in a separate realm — a worker thread on Node, a Dedicated Worker in browsers — and talks
|
|
4
|
+
* to the host over one MessagePort, multiplexed with `@statewalker/webrun-rpc`. The host keeps
|
|
5
|
+
* everything else: bindings in the loaded Worker's env are reached through stubs, and its logs
|
|
6
|
+
* come back for Tail Workers. Errors cross with their own properties (`name`, `code`, …).
|
|
7
|
+
* Functions, `RpcTarget`s and stubs anywhere in a call or result cross by reference (as
|
|
8
|
+
* workerd passes them): the far side gets a stub whose calls come back.
|
|
9
|
+
*
|
|
10
|
+
* Calls (one port, both directions; each names an `answer`, which the serving side keeps until
|
|
11
|
+
* the caller has the result, so calls on it can be sent before then — promise pipelining):
|
|
12
|
+
* host → isolate load {source|url, env, outbound} → loaded {exports}
|
|
13
|
+
* call {name, method, args, props} → result
|
|
14
|
+
* isolate → host log {level, args}
|
|
15
|
+
* either way ref {id|on, path, args} (a call on a stub of the other side's value, or
|
|
16
|
+
* on answer `on`: `path` is the property path
|
|
17
|
+
* called, [] the value itself)
|
|
18
|
+
* release {id|answer} (that stub was disposed or collected; the caller
|
|
19
|
+
* has that answer)
|
|
20
|
+
* Fetches: one port per request (meta: its target and URL), HTTP/1.1 with streamed bodies,
|
|
21
|
+
* as cells-http over a port (src/transport/port.ts): host → isolate to an export or facet,
|
|
22
|
+
* isolate → host for the loaded code's global `fetch()` when a `globalOutbound` Fetcher routes it.
|
|
23
|
+
*/
|
|
24
|
+
export interface PortLike {
|
|
25
|
+
postMessage(msg: unknown, transfer?: Transferable[]): void;
|
|
26
|
+
addEventListener?(type: "message", fn: (e: {
|
|
27
|
+
data: unknown;
|
|
28
|
+
}) => void): void;
|
|
29
|
+
removeEventListener?(type: "message", fn: (e: {
|
|
30
|
+
data: unknown;
|
|
31
|
+
}) => void): void;
|
|
32
|
+
on?(type: "message", fn: (data: unknown) => void): void;
|
|
33
|
+
off?(type: "message", fn: (data: unknown) => void): void;
|
|
34
|
+
start?(): void;
|
|
35
|
+
}
|
|
36
|
+
/** Where a fetch goes in the isolate: an export of the loaded Worker, or one of its facets. */
|
|
37
|
+
export type FetchTarget = {
|
|
38
|
+
name: string;
|
|
39
|
+
props?: unknown;
|
|
40
|
+
} | {
|
|
41
|
+
className: string;
|
|
42
|
+
cellKey: string;
|
|
43
|
+
};
|
|
44
|
+
type Fetch = (target: FetchTarget, req: Request) => Promise<Response>;
|
|
45
|
+
export type Call = <T = unknown>(msg: object) => Promise<T>;
|
|
46
|
+
type Handle = (msg: any) => Promise<unknown>;
|
|
47
|
+
/**
|
|
48
|
+
* The host's end of an isolate's port: one webrun-rpc multiplexer over it, a calls port on
|
|
49
|
+
* which each side calls the other (`callPort`/`listenPort`, no timeout: a call lasts as long
|
|
50
|
+
* as the work it starts), and a port per fetch. `outbound` serves the loaded code's global
|
|
51
|
+
* `fetch()` (its `globalOutbound` Fetcher).
|
|
52
|
+
*/
|
|
53
|
+
export declare function hostPort(port: PortLike, handle: Handle, outbound?: (req: Request) => Promise<Response>): Promise<{
|
|
54
|
+
call: Call;
|
|
55
|
+
fetch: Fetch;
|
|
56
|
+
}>;
|
|
57
|
+
/**
|
|
58
|
+
* The isolate's end: accepts the ports the host opens. Everything the isolate calls the host
|
|
59
|
+
* for happens while serving a host call, so the calls port is open by then. `outbound` sends
|
|
60
|
+
* a fetch to the host's `globalOutbound`.
|
|
61
|
+
*/
|
|
62
|
+
export declare function isolatePort(port: PortLike, handle: Handle, fetch: Fetch): {
|
|
63
|
+
call: Call;
|
|
64
|
+
outbound: (req: Request) => Promise<Response>;
|
|
65
|
+
};
|
|
66
|
+
export {};
|