@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,28 @@
|
|
|
1
|
+
import type { DurableObjectState } from "./state.js";
|
|
2
|
+
/** Stand-in for `import { DurableObject } from "cloudflare:workers"` (mapped via webrun-modules ~deps/ in P08). */
|
|
3
|
+
export declare class DurableObject<Env = unknown> {
|
|
4
|
+
protected ctx: DurableObjectState;
|
|
5
|
+
protected env: Env;
|
|
6
|
+
constructor(ctx: DurableObjectState, env: Env);
|
|
7
|
+
}
|
|
8
|
+
/** Brands WorkerEntrypoint subclasses across copies of this module (a loaded Worker bundles its own). */
|
|
9
|
+
declare const ENTRYPOINT: unique symbol;
|
|
10
|
+
export declare const isWorkerEntrypoint: (v: unknown) => boolean;
|
|
11
|
+
export declare class WorkerEntrypoint<Env = unknown> {
|
|
12
|
+
static readonly [ENTRYPOINT] = true;
|
|
13
|
+
protected ctx: ExecutionContext;
|
|
14
|
+
protected env: Env;
|
|
15
|
+
constructor(ctx: ExecutionContext, env: Env);
|
|
16
|
+
}
|
|
17
|
+
export interface ExecutionContext {
|
|
18
|
+
waitUntil(p: Promise<unknown>): void;
|
|
19
|
+
passThroughOnException(): void;
|
|
20
|
+
}
|
|
21
|
+
/** Brands RpcTarget instances across copies of this module (a loaded Worker bundles its own). */
|
|
22
|
+
declare const RPC_TARGET: unique symbol;
|
|
23
|
+
export declare const isRpcTarget: (v: unknown) => boolean;
|
|
24
|
+
/** Marker base class for JS-RPC targets returned by reference (`cloudflare:workers`). */
|
|
25
|
+
export declare class RpcTarget {
|
|
26
|
+
get [RPC_TARGET](): boolean;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Stand-in for `import { DurableObject } from "cloudflare:workers"` (mapped via webrun-modules ~deps/ in P08). */
|
|
2
|
+
export class DurableObject {
|
|
3
|
+
ctx;
|
|
4
|
+
env;
|
|
5
|
+
constructor(ctx, env) {
|
|
6
|
+
this.ctx = ctx;
|
|
7
|
+
this.env = env;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** Brands WorkerEntrypoint subclasses across copies of this module (a loaded Worker bundles its own). */
|
|
11
|
+
const ENTRYPOINT = Symbol.for("cellb.WorkerEntrypoint");
|
|
12
|
+
export const isWorkerEntrypoint = (v) => typeof v === "function" && v[ENTRYPOINT] === true;
|
|
13
|
+
export class WorkerEntrypoint {
|
|
14
|
+
static [ENTRYPOINT] = true;
|
|
15
|
+
ctx;
|
|
16
|
+
env;
|
|
17
|
+
constructor(ctx, env) {
|
|
18
|
+
this.ctx = ctx;
|
|
19
|
+
this.env = env;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Brands RpcTarget instances across copies of this module (a loaded Worker bundles its own). */
|
|
23
|
+
const RPC_TARGET = Symbol.for("cellb.RpcTarget");
|
|
24
|
+
export const isRpcTarget = (v) => !!v && typeof v === "object" && v[RPC_TARGET] === true;
|
|
25
|
+
/** Marker base class for JS-RPC targets returned by reference (`cloudflare:workers`). */
|
|
26
|
+
export class RpcTarget {
|
|
27
|
+
get [RPC_TARGET]() {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=durable-object.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durable-object.js","sourceRoot":"","sources":["../../src/core/durable-object.ts"],"names":[],"mappings":"AAEA,mHAAmH;AACnH,MAAM,OAAO,aAAa;IACd,GAAG,CAAqB;IACxB,GAAG,CAAM;IACnB,YAAY,GAAuB,EAAE,GAAQ;QAC3C,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;CACF;AAED,yGAAyG;AACzG,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;AAExD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAU,EAAW,EAAE,CACxD,OAAO,CAAC,KAAK,UAAU,IAAK,CAAwC,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;AAE5F,MAAM,OAAO,gBAAgB;IAC3B,MAAM,CAAU,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAmB;IACtB,GAAG,CAAM;IACnB,YAAY,GAAqB,EAAE,GAAQ;QACzC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;CACF;AAOD,iGAAiG;AACjG,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAEjD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAU,EAAW,EAAE,CACjD,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAK,CAA6B,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;AAEtF,yFAAyF;AACzF,MAAM,OAAO,SAAS;IACpB,IAAI,CAAC,UAAU,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import type { DurableObjectState } from \"./state.js\";\n\n/** Stand-in for `import { DurableObject } from \"cloudflare:workers\"` (mapped via webrun-modules ~deps/ in P08). */\nexport class DurableObject<Env = unknown> {\n protected ctx: DurableObjectState;\n protected env: Env;\n constructor(ctx: DurableObjectState, env: Env) {\n this.ctx = ctx;\n this.env = env;\n }\n}\n\n/** Brands WorkerEntrypoint subclasses across copies of this module (a loaded Worker bundles its own). */\nconst ENTRYPOINT = Symbol.for(\"cellb.WorkerEntrypoint\");\n\nexport const isWorkerEntrypoint = (v: unknown): boolean =>\n typeof v === \"function\" && (v as unknown as Record<symbol, unknown>)[ENTRYPOINT] === true;\n\nexport class WorkerEntrypoint<Env = unknown> {\n static readonly [ENTRYPOINT] = true;\n protected ctx: ExecutionContext;\n protected env: Env;\n constructor(ctx: ExecutionContext, env: Env) {\n this.ctx = ctx;\n this.env = env;\n }\n}\n\nexport interface ExecutionContext {\n waitUntil(p: Promise<unknown>): void;\n passThroughOnException(): void;\n}\n\n/** Brands RpcTarget instances across copies of this module (a loaded Worker bundles its own). */\nconst RPC_TARGET = Symbol.for(\"cellb.RpcTarget\");\n\nexport const isRpcTarget = (v: unknown): boolean =>\n !!v && typeof v === \"object\" && (v as Record<symbol, unknown>)[RPC_TARGET] === true;\n\n/** Marker base class for JS-RPC targets returned by reference (`cloudflare:workers`). */\nexport class RpcTarget {\n get [RPC_TARGET]() {\n return true;\n }\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Defers to a macrotask (portable: browser, Worker, Node, Deno). */
|
|
2
|
+
export declare const nextMacrotask: () => Promise<void>;
|
|
3
|
+
/**
|
|
4
|
+
* Input gate: while any storage operation is in flight, no new event is
|
|
5
|
+
* delivered to the object. Unlike Miniflare 2 it needs no AsyncLocalStorage:
|
|
6
|
+
* each object owns its gate and storage captures it by closure.
|
|
7
|
+
*
|
|
8
|
+
* Release is deferred to a macrotask so the continuation of the operation
|
|
9
|
+
* that held the gate runs before the next event (the read-modify-write
|
|
10
|
+
* guarantee), and waiters are woken ONE at a time, re-checking the gate.
|
|
11
|
+
*/
|
|
12
|
+
export declare class InputGate {
|
|
13
|
+
#private;
|
|
14
|
+
get isOpen(): boolean;
|
|
15
|
+
waitOpen(): Promise<void>;
|
|
16
|
+
/** Calls `cb` synchronously at the moment the gate is (re)opened for it. */
|
|
17
|
+
onOpen(cb: () => void): void;
|
|
18
|
+
lock(): void;
|
|
19
|
+
unlock(): void;
|
|
20
|
+
runClosed<T>(fn: () => T | Promise<T>): Promise<T>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Output gate: tracks durability promises of local commits. Responses and
|
|
24
|
+
* outgoing messages are released only once every commit that happened
|
|
25
|
+
* before them is durable. A failed commit breaks the object.
|
|
26
|
+
*/
|
|
27
|
+
export declare class OutputGate {
|
|
28
|
+
#private;
|
|
29
|
+
track(p: Promise<void>): void;
|
|
30
|
+
get failure(): unknown;
|
|
31
|
+
/** Resolves when everything committed so far is durable; rejects if any failed. */
|
|
32
|
+
barrier(): Promise<void>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/** Defers to a macrotask (portable: browser, Worker, Node, Deno). */
|
|
2
|
+
export const nextMacrotask = () => new Promise((r) => setTimeout(r, 0));
|
|
3
|
+
/**
|
|
4
|
+
* Input gate: while any storage operation is in flight, no new event is
|
|
5
|
+
* delivered to the object. Unlike Miniflare 2 it needs no AsyncLocalStorage:
|
|
6
|
+
* each object owns its gate and storage captures it by closure.
|
|
7
|
+
*
|
|
8
|
+
* Release is deferred to a macrotask so the continuation of the operation
|
|
9
|
+
* that held the gate runs before the next event (the read-modify-write
|
|
10
|
+
* guarantee), and waiters are woken ONE at a time, re-checking the gate.
|
|
11
|
+
*/
|
|
12
|
+
export class InputGate {
|
|
13
|
+
#locks = 0;
|
|
14
|
+
#waiters = [];
|
|
15
|
+
#draining = false;
|
|
16
|
+
get isOpen() {
|
|
17
|
+
return this.#locks === 0;
|
|
18
|
+
}
|
|
19
|
+
async waitOpen() {
|
|
20
|
+
while (this.#locks > 0)
|
|
21
|
+
await new Promise((r) => this.#waiters.push(r));
|
|
22
|
+
}
|
|
23
|
+
/** Calls `cb` synchronously at the moment the gate is (re)opened for it. */
|
|
24
|
+
onOpen(cb) {
|
|
25
|
+
if (this.#locks === 0 && !this.#draining)
|
|
26
|
+
cb();
|
|
27
|
+
else
|
|
28
|
+
this.#waiters.push(cb);
|
|
29
|
+
}
|
|
30
|
+
lock() {
|
|
31
|
+
this.#locks++;
|
|
32
|
+
}
|
|
33
|
+
unlock() {
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
this.#locks--;
|
|
36
|
+
void this.#drain();
|
|
37
|
+
}, 0);
|
|
38
|
+
}
|
|
39
|
+
async runClosed(fn) {
|
|
40
|
+
this.lock();
|
|
41
|
+
try {
|
|
42
|
+
return await fn();
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
this.unlock();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async #drain() {
|
|
49
|
+
if (this.#draining)
|
|
50
|
+
return;
|
|
51
|
+
this.#draining = true;
|
|
52
|
+
try {
|
|
53
|
+
while (this.#locks === 0 && this.#waiters.length) {
|
|
54
|
+
this.#waiters.shift()();
|
|
55
|
+
await nextMacrotask();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
this.#draining = false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Output gate: tracks durability promises of local commits. Responses and
|
|
65
|
+
* outgoing messages are released only once every commit that happened
|
|
66
|
+
* before them is durable. A failed commit breaks the object.
|
|
67
|
+
*/
|
|
68
|
+
export class OutputGate {
|
|
69
|
+
#pending = new Set();
|
|
70
|
+
#failure = undefined;
|
|
71
|
+
track(p) {
|
|
72
|
+
const tracked = p.then(() => void this.#pending.delete(tracked), (err) => {
|
|
73
|
+
this.#pending.delete(tracked);
|
|
74
|
+
this.#failure ??= err;
|
|
75
|
+
});
|
|
76
|
+
this.#pending.add(tracked);
|
|
77
|
+
}
|
|
78
|
+
get failure() {
|
|
79
|
+
return this.#failure;
|
|
80
|
+
}
|
|
81
|
+
/** Resolves when everything committed so far is durable; rejects if any failed. */
|
|
82
|
+
async barrier() {
|
|
83
|
+
while (this.#pending.size)
|
|
84
|
+
await Promise.all([...this.#pending]);
|
|
85
|
+
if (this.#failure !== undefined)
|
|
86
|
+
throw this.#failure;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=gates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gates.js","sourceRoot":"","sources":["../../src/core/gates.ts"],"names":[],"mappings":"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","sourcesContent":["/** Defers to a macrotask (portable: browser, Worker, Node, Deno). */\nexport const nextMacrotask = () => new Promise<void>((r) => setTimeout(r, 0));\n\n/**\n * Input gate: while any storage operation is in flight, no new event is\n * delivered to the object. Unlike Miniflare 2 it needs no AsyncLocalStorage:\n * each object owns its gate and storage captures it by closure.\n *\n * Release is deferred to a macrotask so the continuation of the operation\n * that held the gate runs before the next event (the read-modify-write\n * guarantee), and waiters are woken ONE at a time, re-checking the gate.\n */\nexport class InputGate {\n #locks = 0;\n #waiters: (() => void)[] = [];\n #draining = false;\n\n get isOpen(): boolean {\n return this.#locks === 0;\n }\n async waitOpen(): Promise<void> {\n while (this.#locks > 0) await new Promise<void>((r) => this.#waiters.push(r));\n }\n /** Calls `cb` synchronously at the moment the gate is (re)opened for it. */\n onOpen(cb: () => void): void {\n if (this.#locks === 0 && !this.#draining) cb();\n else this.#waiters.push(cb);\n }\n lock(): void {\n this.#locks++;\n }\n unlock(): void {\n setTimeout(() => {\n this.#locks--;\n void this.#drain();\n }, 0);\n }\n async runClosed<T>(fn: () => T | Promise<T>): Promise<T> {\n this.lock();\n try {\n return await fn();\n } finally {\n this.unlock();\n }\n }\n async #drain(): Promise<void> {\n if (this.#draining) return;\n this.#draining = true;\n try {\n while (this.#locks === 0 && this.#waiters.length) {\n this.#waiters.shift()!();\n await nextMacrotask();\n }\n } finally {\n this.#draining = false;\n }\n }\n}\n\n/**\n * Output gate: tracks durability promises of local commits. Responses and\n * outgoing messages are released only once every commit that happened\n * before them is durable. A failed commit breaks the object.\n */\nexport class OutputGate {\n #pending = new Set<Promise<void>>();\n #failure: unknown = undefined;\n\n track(p: Promise<void>): void {\n const tracked = p.then(\n () => void this.#pending.delete(tracked),\n (err) => {\n this.#pending.delete(tracked);\n this.#failure ??= err;\n },\n );\n this.#pending.add(tracked);\n }\n get failure(): unknown {\n return this.#failure;\n }\n /** Resolves when everything committed so far is durable; rejects if any failed. */\n async barrier(): Promise<void> {\n while (this.#pending.size) await Promise.all([...this.#pending]);\n if (this.#failure !== undefined) throw this.#failure;\n }\n}\n"]}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { type HostObjects } from "../v8/serialize.js";
|
|
2
|
+
import type { DurableObjectState } from "./state.js";
|
|
3
|
+
export type DurableObjectClass = new (ctx: DurableObjectState, env: any) => any;
|
|
4
|
+
/**
|
|
5
|
+
* A class handle — what `worker.getDurableObjectClass(name)` (Worker Loader) and
|
|
6
|
+
* `ctx.exports.App` return, and what `ctx.facets.get(name, () => ({ class }))` accepts.
|
|
7
|
+
* Resolution may be asynchronous (loaded code is compiled on first use).
|
|
8
|
+
*/
|
|
9
|
+
export interface ClassHandle {
|
|
10
|
+
readonly __cellsClassHandle: true;
|
|
11
|
+
resolve(): Promise<{
|
|
12
|
+
cls: DurableObjectClass;
|
|
13
|
+
env: unknown;
|
|
14
|
+
props?: unknown;
|
|
15
|
+
} | {
|
|
16
|
+
isolated: IsolatedClass;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
/** Key of the isolate's class factory on a module facade (see getDurableObjectClass). */
|
|
20
|
+
export declare const ISOLATED: unique symbol;
|
|
21
|
+
/** A Durable Object class that runs in an isolate: its instances and storage live there. */
|
|
22
|
+
export interface IsolatedClass {
|
|
23
|
+
fetch(cellKey: string, req: Request): Promise<Response>;
|
|
24
|
+
call(cellKey: string, method: string, args: unknown[]): Promise<unknown>;
|
|
25
|
+
restart(cellKey: string): Promise<void>;
|
|
26
|
+
delete(cellKey: string): Promise<void>;
|
|
27
|
+
/** Tells the isolate which root epoch the facet's log is written under. */
|
|
28
|
+
attach?(cellKey: string, epoch?: number): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
export declare function classHandle(resolve: ClassHandle["resolve"]): ClassHandle;
|
|
31
|
+
export declare function isClassHandle(v: unknown): v is ClassHandle;
|
|
32
|
+
/** Answered `true` by cellb's stubs: they cross by reference. */
|
|
33
|
+
export declare const STUB: unique symbol;
|
|
34
|
+
/** Answered by a value that may not cross, with workerd's reason. */
|
|
35
|
+
export declare const REFUSE: unique symbol;
|
|
36
|
+
/** Answered by a `ctx.exports.X({ props })` stub or class handle: `{ name, props }` (storable). */
|
|
37
|
+
export declare const EXPORT: unique symbol;
|
|
38
|
+
/**
|
|
39
|
+
* What crosses a stub, as in workerd: functions, `RpcTarget`s, stubs and class handles by
|
|
40
|
+
* reference (`ref` says what stands for one on the far side; in one realm, the value itself),
|
|
41
|
+
* arrays and plain objects walked, anything else structured-cloned (`copy`).
|
|
42
|
+
*/
|
|
43
|
+
export declare function cross<T>(v: T, ref?: (v: object) => unknown, copy?: (v: unknown) => unknown): T;
|
|
44
|
+
/**
|
|
45
|
+
* A value sent to an object on another node (cells-http, celld's tunnel), checked first: only
|
|
46
|
+
* copies travel between nodes, so a function, `RpcTarget` or stub is refused, not sent as `{}`.
|
|
47
|
+
*/
|
|
48
|
+
export declare function toAnotherNode<T>(v: T): T;
|
|
49
|
+
/** Where a call on an RpcPromise goes: the property path from its result, and the arguments. */
|
|
50
|
+
export type Pipe = (path: string[], args: unknown[]) => unknown;
|
|
51
|
+
/**
|
|
52
|
+
* workerd's RpcPromise: what a call on a stub returns. It is awaited as a promise, and used
|
|
53
|
+
* before it settles (promise pipelining): a property read gives the RpcPromise of that path,
|
|
54
|
+
* and a call on a path goes through `pipe` at once, without waiting for `result`.
|
|
55
|
+
*/
|
|
56
|
+
export declare function rpcPromise(result: Promise<unknown>, pipe: Pipe): any;
|
|
57
|
+
/**
|
|
58
|
+
* Runs a call and returns its result as an RpcPromise (`map` applies to the settled value);
|
|
59
|
+
* calls on it go to the result: at once if the result is an RpcPromise itself, else once it
|
|
60
|
+
* settles.
|
|
61
|
+
*/
|
|
62
|
+
export declare function rpcCall(call: () => unknown, map?: (v: unknown) => unknown): any;
|
|
63
|
+
/** Calls `path` of `r` (a value, a promise of one, or an RpcPromise) with `args`. */
|
|
64
|
+
export declare function pipeTo(r: unknown, path: string[], args: unknown[]): unknown;
|
|
65
|
+
/**
|
|
66
|
+
* A stub over an asynchronously obtained target: `fetch` and JS-RPC methods, arguments
|
|
67
|
+
* and results crossing as between isolates. A method's result is an RpcPromise over what
|
|
68
|
+
* `call` returns.
|
|
69
|
+
*/
|
|
70
|
+
export declare function asyncStub(call: (method: string, args: unknown[]) => unknown, fetch: (req: Request) => Promise<Response>): Record<string, any>;
|
|
71
|
+
/**
|
|
72
|
+
* A stub of a WorkerEntrypoint (or a default export object): a fresh instance per call,
|
|
73
|
+
* as workerd creates one per request; `ctx.props` carries copied startup properties. Methods
|
|
74
|
+
* of a plain object receive `(…args, env, ctx)`, as its `fetch` receives `(request, env, ctx)`.
|
|
75
|
+
*/
|
|
76
|
+
export declare function entrypointStub(target: unknown, env: unknown, props: unknown, exports?: unknown): Record<string, any>;
|
|
77
|
+
/**
|
|
78
|
+
* `ctx.exports`: loopback handles of a Worker's named exports. An entrypoint's (a
|
|
79
|
+
* WorkerEntrypoint class, or an object with methods) is a stub (`ctx.exports.Greeter.greet()`),
|
|
80
|
+
* and called with `{ props }` gives one with props; a Durable Object class's is a facet class
|
|
81
|
+
* handle, also callable with `{ props }`.
|
|
82
|
+
*/
|
|
83
|
+
export declare function ctxExports(worker: Record<string, unknown>, env: unknown): Record<string, unknown>;
|
|
84
|
+
/**
|
|
85
|
+
* Stubs in Durable Object storage (workerd's `allow_irrevocable_stub_storage`), as V8 host
|
|
86
|
+
* objects: a `ctx.exports.X({ props })` stub or class handle is stored as `[name, props]` and
|
|
87
|
+
* read back as `ctx.exports[name]({ props })`. Other stubs and `RpcTarget`s are refused rather
|
|
88
|
+
* than stored as `{}`.
|
|
89
|
+
*/
|
|
90
|
+
export declare function storedExports(exports: Record<string, unknown>): HostObjects;
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { deserialize, serialize } from "../v8/serialize.js";
|
|
2
|
+
import { isRpcTarget, isWorkerEntrypoint } from "./durable-object.js";
|
|
3
|
+
/** Key of the isolate's class factory on a module facade (see getDurableObjectClass). */
|
|
4
|
+
export const ISOLATED = Symbol.for("cellb.isolated-classes");
|
|
5
|
+
export function classHandle(resolve) {
|
|
6
|
+
return { __cellsClassHandle: true, resolve };
|
|
7
|
+
}
|
|
8
|
+
export function isClassHandle(v) {
|
|
9
|
+
return (!!v &&
|
|
10
|
+
(typeof v === "object" || typeof v === "function") &&
|
|
11
|
+
v.__cellsClassHandle === true);
|
|
12
|
+
}
|
|
13
|
+
/** Answered `true` by cellb's stubs: they cross by reference. */
|
|
14
|
+
export const STUB = Symbol.for("cellb.stub");
|
|
15
|
+
/** Answered by a value that may not cross, with workerd's reason. */
|
|
16
|
+
export const REFUSE = Symbol.for("cellb.refuse");
|
|
17
|
+
/** Answered by a `ctx.exports.X({ props })` stub or class handle: `{ name, props }` (storable). */
|
|
18
|
+
export const EXPORT = Symbol.for("cellb.export");
|
|
19
|
+
/**
|
|
20
|
+
* What crosses a stub, as in workerd: functions, `RpcTarget`s, stubs and class handles by
|
|
21
|
+
* reference (`ref` says what stands for one on the far side; in one realm, the value itself),
|
|
22
|
+
* arrays and plain objects walked, anything else structured-cloned (`copy`).
|
|
23
|
+
*/
|
|
24
|
+
export function cross(v, ref = (x) => x, copy = structuredClone) {
|
|
25
|
+
if (v === undefined || v === null || (typeof v !== "object" && typeof v !== "function"))
|
|
26
|
+
return copy(v);
|
|
27
|
+
const refused = v[REFUSE];
|
|
28
|
+
if (typeof refused === "string")
|
|
29
|
+
throw new DOMException(refused, "DataCloneError");
|
|
30
|
+
if (typeof v === "function" ||
|
|
31
|
+
isRpcTarget(v) ||
|
|
32
|
+
v[STUB] === true ||
|
|
33
|
+
isClassHandle(v))
|
|
34
|
+
return ref(v);
|
|
35
|
+
if (Array.isArray(v))
|
|
36
|
+
return v.map((x) => cross(x, ref, copy));
|
|
37
|
+
if (Object.getPrototypeOf(v) === Object.prototype) {
|
|
38
|
+
const out = {};
|
|
39
|
+
for (const [k, x] of Object.entries(v))
|
|
40
|
+
out[k] = cross(x, ref, copy);
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
return copy(v);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A value sent to an object on another node (cells-http, celld's tunnel), checked first: only
|
|
47
|
+
* copies travel between nodes, so a function, `RpcTarget` or stub is refused, not sent as `{}`.
|
|
48
|
+
*/
|
|
49
|
+
export function toAnotherNode(v) {
|
|
50
|
+
cross(v, () => {
|
|
51
|
+
const e = new DOMException("Functions, RpcTargets and stubs cannot be sent to another node: they pass by reference only within one runtime.", "DataCloneError");
|
|
52
|
+
// An own `name`, so it survives the error's trip back over the link.
|
|
53
|
+
throw Object.defineProperty(e, "name", { value: e.name, enumerable: true });
|
|
54
|
+
}, (x) => x);
|
|
55
|
+
return v;
|
|
56
|
+
}
|
|
57
|
+
const RPC_PROMISE = Symbol("cellb.rpc-promise");
|
|
58
|
+
/**
|
|
59
|
+
* workerd's RpcPromise: what a call on a stub returns. It is awaited as a promise, and used
|
|
60
|
+
* before it settles (promise pipelining): a property read gives the RpcPromise of that path,
|
|
61
|
+
* and a call on a path goes through `pipe` at once, without waiting for `result`.
|
|
62
|
+
*/
|
|
63
|
+
export function rpcPromise(result, pipe) {
|
|
64
|
+
const at = (path) => {
|
|
65
|
+
let value;
|
|
66
|
+
// The result itself is a Promise-like object, not callable (node:assert calls a function
|
|
67
|
+
// given to `rejects`); a property path is callable.
|
|
68
|
+
return new Proxy(path.length ? () => { } : Object.create(Promise.prototype), {
|
|
69
|
+
apply: (_t, _this, args) => rpcCall(() => pipe(path, args)),
|
|
70
|
+
get(_t, prop) {
|
|
71
|
+
if (prop === RPC_PROMISE)
|
|
72
|
+
return true;
|
|
73
|
+
if (prop === "then" || prop === "catch" || prop === "finally") {
|
|
74
|
+
value ??= result.then((v) => path.reduce((o, k) => o[k], v));
|
|
75
|
+
return value[prop].bind(value);
|
|
76
|
+
}
|
|
77
|
+
if (typeof prop === "symbol")
|
|
78
|
+
return undefined;
|
|
79
|
+
return at([...path, prop]);
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
return at([]);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Runs a call and returns its result as an RpcPromise (`map` applies to the settled value);
|
|
87
|
+
* calls on it go to the result: at once if the result is an RpcPromise itself, else once it
|
|
88
|
+
* settles.
|
|
89
|
+
*/
|
|
90
|
+
export function rpcCall(call, map) {
|
|
91
|
+
let r;
|
|
92
|
+
try {
|
|
93
|
+
r = call();
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
r = Promise.reject(e);
|
|
97
|
+
}
|
|
98
|
+
const result = Promise.resolve(r);
|
|
99
|
+
return rpcPromise(map ? result.then(map) : result, (path, args) => pipeTo(r, path, args));
|
|
100
|
+
}
|
|
101
|
+
/** Calls `path` of `r` (a value, a promise of one, or an RpcPromise) with `args`. */
|
|
102
|
+
export function pipeTo(r, path, args) {
|
|
103
|
+
const callAt = (v) => {
|
|
104
|
+
if (!path.length)
|
|
105
|
+
return v(...args);
|
|
106
|
+
const receiver = path.slice(0, -1).reduce((o, k) => o[k], v);
|
|
107
|
+
return receiver[path[path.length - 1]](...args);
|
|
108
|
+
};
|
|
109
|
+
return r?.[RPC_PROMISE]
|
|
110
|
+
? callAt(r)
|
|
111
|
+
: Promise.resolve(r).then(callAt);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* A stub over an asynchronously obtained target: `fetch` and JS-RPC methods, arguments
|
|
115
|
+
* and results crossing as between isolates. A method's result is an RpcPromise over what
|
|
116
|
+
* `call` returns.
|
|
117
|
+
*/
|
|
118
|
+
export function asyncStub(call, fetch) {
|
|
119
|
+
return new Proxy({}, {
|
|
120
|
+
get(_t, prop) {
|
|
121
|
+
if (prop === STUB)
|
|
122
|
+
return true;
|
|
123
|
+
if (prop === "then" || typeof prop === "symbol")
|
|
124
|
+
return undefined;
|
|
125
|
+
if (prop === "fetch")
|
|
126
|
+
return (input, init) => fetch(new Request(input, init));
|
|
127
|
+
return (...args) => rpcCall(() => call(String(prop), cross(args)), cross);
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* A stub of a WorkerEntrypoint (or a default export object): a fresh instance per call,
|
|
133
|
+
* as workerd creates one per request; `ctx.props` carries copied startup properties. Methods
|
|
134
|
+
* of a plain object receive `(…args, env, ctx)`, as its `fetch` receives `(request, env, ctx)`.
|
|
135
|
+
*/
|
|
136
|
+
export function entrypointStub(target, env, props, exports) {
|
|
137
|
+
const objectCtx = () => ({
|
|
138
|
+
waitUntil() { },
|
|
139
|
+
passThroughOnException() { },
|
|
140
|
+
props: cross(props ?? {}),
|
|
141
|
+
});
|
|
142
|
+
const make = () => {
|
|
143
|
+
if (typeof target === "function") {
|
|
144
|
+
const ctx = {
|
|
145
|
+
props: cross(props ?? {}),
|
|
146
|
+
exports,
|
|
147
|
+
waitUntil() { },
|
|
148
|
+
passThroughOnException() { },
|
|
149
|
+
};
|
|
150
|
+
return new target(ctx, env);
|
|
151
|
+
}
|
|
152
|
+
return target;
|
|
153
|
+
};
|
|
154
|
+
return asyncStub((method, args) => {
|
|
155
|
+
const instance = make();
|
|
156
|
+
const fn = instance?.[method];
|
|
157
|
+
if (typeof fn !== "function")
|
|
158
|
+
throw new TypeError(`The RPC receiver does not implement the method "${method}".`);
|
|
159
|
+
return fn.apply(instance, typeof target === "function" ? args : [...args, env, objectCtx()]);
|
|
160
|
+
}, async (req) => {
|
|
161
|
+
const instance = make();
|
|
162
|
+
if (typeof instance?.fetch !== "function")
|
|
163
|
+
throw new Error("Handler does not export a fetch() function.");
|
|
164
|
+
return typeof target === "function"
|
|
165
|
+
? instance.fetch(req)
|
|
166
|
+
: instance.fetch(req, env, objectCtx());
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/** workerd's refusal of `ctx.exports.<Entrypoint>` passed on without `({ props })`. */
|
|
170
|
+
const LOOPBACK = 'Could not serialize object of type "LoopbackServiceStub". This type does not support serialization.';
|
|
171
|
+
/**
|
|
172
|
+
* `ctx.exports`: loopback handles of a Worker's named exports. An entrypoint's (a
|
|
173
|
+
* WorkerEntrypoint class, or an object with methods) is a stub (`ctx.exports.Greeter.greet()`),
|
|
174
|
+
* and called with `{ props }` gives one with props; a Durable Object class's is a facet class
|
|
175
|
+
* handle, also callable with `{ props }`.
|
|
176
|
+
*/
|
|
177
|
+
export function ctxExports(worker, env) {
|
|
178
|
+
const exports = {};
|
|
179
|
+
for (const [name, value] of Object.entries(worker)) {
|
|
180
|
+
if (name === "default" || !value || (typeof value !== "function" && typeof value !== "object"))
|
|
181
|
+
continue;
|
|
182
|
+
if (typeof value === "object" || isWorkerEntrypoint(value)) {
|
|
183
|
+
const withProps = (o = {}) => {
|
|
184
|
+
const stub = entrypointStub(value, env, o.props, exports);
|
|
185
|
+
return new Proxy(stub, {
|
|
186
|
+
get: (t, prop) => (prop === EXPORT ? { name, props: o.props } : t[prop]),
|
|
187
|
+
});
|
|
188
|
+
};
|
|
189
|
+
const stub = withProps();
|
|
190
|
+
exports[name] = new Proxy(withProps, {
|
|
191
|
+
get: (_t, prop) => (prop === REFUSE ? LOOPBACK : stub[prop]),
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
const handle = (o = {}) => Object.assign(classHandle(async () => ({ cls: value, env, props: o.props })), { [EXPORT]: { name, props: o.props } });
|
|
196
|
+
exports[name] = Object.assign(handle, classHandle(async () => ({ cls: value, env })));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return exports;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Stubs in Durable Object storage (workerd's `allow_irrevocable_stub_storage`), as V8 host
|
|
203
|
+
* objects: a `ctx.exports.X({ props })` stub or class handle is stored as `[name, props]` and
|
|
204
|
+
* read back as `ctx.exports[name]({ props })`. Other stubs and `RpcTarget`s are refused rather
|
|
205
|
+
* than stored as `{}`.
|
|
206
|
+
*/
|
|
207
|
+
export function storedExports(exports) {
|
|
208
|
+
const host = {
|
|
209
|
+
encode(v) {
|
|
210
|
+
const e = v[EXPORT];
|
|
211
|
+
if (e)
|
|
212
|
+
return serialize([e.name, e.props], host);
|
|
213
|
+
if (v[STUB] === true || isRpcTarget(v))
|
|
214
|
+
throw new DOMException("Only ctx.exports.<name>({ props }) stubs and class handles can be stored.", "DataCloneError");
|
|
215
|
+
return undefined;
|
|
216
|
+
},
|
|
217
|
+
decode(bytes) {
|
|
218
|
+
const [name, props] = deserialize(bytes, host);
|
|
219
|
+
return exports[name]({ props });
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
return host;
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=handles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handles.js","sourceRoot":"","sources":["../../src/core/handles.ts"],"names":[],"mappings":"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","sourcesContent":["import { deserialize, type HostObjects, serialize } from \"../v8/serialize.js\";\nimport { isRpcTarget, isWorkerEntrypoint } from \"./durable-object.js\";\nimport type { DurableObjectState } from \"./state.js\";\n\nexport type DurableObjectClass = new (ctx: DurableObjectState, env: any) => any;\n\n/**\n * A class handle — what `worker.getDurableObjectClass(name)` (Worker Loader) and\n * `ctx.exports.App` return, and what `ctx.facets.get(name, () => ({ class }))` accepts.\n * Resolution may be asynchronous (loaded code is compiled on first use).\n */\nexport interface ClassHandle {\n readonly __cellsClassHandle: true;\n resolve(): Promise<\n { cls: DurableObjectClass; env: unknown; props?: unknown } | { isolated: IsolatedClass }\n >;\n}\n\n/** Key of the isolate's class factory on a module facade (see getDurableObjectClass). */\nexport const ISOLATED = Symbol.for(\"cellb.isolated-classes\");\n\n/** A Durable Object class that runs in an isolate: its instances and storage live there. */\nexport interface IsolatedClass {\n fetch(cellKey: string, req: Request): Promise<Response>;\n call(cellKey: string, method: string, args: unknown[]): Promise<unknown>;\n restart(cellKey: string): Promise<void>;\n delete(cellKey: string): Promise<void>;\n /** Tells the isolate which root epoch the facet's log is written under. */\n attach?(cellKey: string, epoch?: number): Promise<void>;\n}\n\nexport function classHandle(resolve: ClassHandle[\"resolve\"]): ClassHandle {\n return { __cellsClassHandle: true, resolve };\n}\n\nexport function isClassHandle(v: unknown): v is ClassHandle {\n return (\n !!v &&\n (typeof v === \"object\" || typeof v === \"function\") &&\n (v as ClassHandle).__cellsClassHandle === true\n );\n}\n\n/** Answered `true` by cellb's stubs: they cross by reference. */\nexport const STUB = Symbol.for(\"cellb.stub\");\n/** Answered by a value that may not cross, with workerd's reason. */\nexport const REFUSE = Symbol.for(\"cellb.refuse\");\n/** Answered by a `ctx.exports.X({ props })` stub or class handle: `{ name, props }` (storable). */\nexport const EXPORT = Symbol.for(\"cellb.export\");\n\n/**\n * What crosses a stub, as in workerd: functions, `RpcTarget`s, stubs and class handles by\n * reference (`ref` says what stands for one on the far side; in one realm, the value itself),\n * arrays and plain objects walked, anything else structured-cloned (`copy`).\n */\nexport function cross<T>(\n v: T,\n ref: (v: object) => unknown = (x) => x,\n copy: (v: unknown) => unknown = structuredClone,\n): T {\n if (v === undefined || v === null || (typeof v !== \"object\" && typeof v !== \"function\"))\n return copy(v) as T;\n const refused = (v as Record<symbol, unknown>)[REFUSE];\n if (typeof refused === \"string\") throw new DOMException(refused, \"DataCloneError\");\n if (\n typeof v === \"function\" ||\n isRpcTarget(v) ||\n (v as Record<symbol, unknown>)[STUB] === true ||\n isClassHandle(v)\n )\n return ref(v) as T;\n if (Array.isArray(v)) return v.map((x) => cross(x, ref, copy)) as T;\n if (Object.getPrototypeOf(v) === Object.prototype) {\n const out: Record<string, unknown> = {};\n for (const [k, x] of Object.entries(v)) out[k] = cross(x, ref, copy);\n return out as T;\n }\n return copy(v) as T;\n}\n\n/**\n * A value sent to an object on another node (cells-http, celld's tunnel), checked first: only\n * copies travel between nodes, so a function, `RpcTarget` or stub is refused, not sent as `{}`.\n */\nexport function toAnotherNode<T>(v: T): T {\n cross(\n v,\n () => {\n const e = new DOMException(\n \"Functions, RpcTargets and stubs cannot be sent to another node: they pass by reference only within one runtime.\",\n \"DataCloneError\",\n );\n // An own `name`, so it survives the error's trip back over the link.\n throw Object.defineProperty(e, \"name\", { value: e.name, enumerable: true });\n },\n (x) => x,\n );\n return v;\n}\n\n/** Where a call on an RpcPromise goes: the property path from its result, and the arguments. */\nexport type Pipe = (path: string[], args: unknown[]) => unknown;\n\nconst RPC_PROMISE = Symbol(\"cellb.rpc-promise\");\n\n/**\n * workerd's RpcPromise: what a call on a stub returns. It is awaited as a promise, and used\n * before it settles (promise pipelining): a property read gives the RpcPromise of that path,\n * and a call on a path goes through `pipe` at once, without waiting for `result`.\n */\nexport function rpcPromise(result: Promise<unknown>, pipe: Pipe): any {\n const at = (path: string[]): any => {\n let value: Promise<unknown> | undefined;\n // The result itself is a Promise-like object, not callable (node:assert calls a function\n // given to `rejects`); a property path is callable.\n return new Proxy(path.length ? () => {} : Object.create(Promise.prototype), {\n apply: (_t, _this, args) => rpcCall(() => pipe(path, args)),\n get(_t, prop) {\n if (prop === RPC_PROMISE) return true;\n if (prop === \"then\" || prop === \"catch\" || prop === \"finally\") {\n value ??= result.then((v) => path.reduce((o: any, k) => o[k], v));\n return value[prop].bind(value);\n }\n if (typeof prop === \"symbol\") return undefined;\n return at([...path, prop]);\n },\n });\n };\n return at([]);\n}\n\n/**\n * Runs a call and returns its result as an RpcPromise (`map` applies to the settled value);\n * calls on it go to the result: at once if the result is an RpcPromise itself, else once it\n * settles.\n */\nexport function rpcCall(call: () => unknown, map?: (v: unknown) => unknown): any {\n let r: unknown;\n try {\n r = call();\n } catch (e) {\n r = Promise.reject(e);\n }\n const result = Promise.resolve(r);\n return rpcPromise(map ? result.then(map) : result, (path, args) => pipeTo(r, path, args));\n}\n\n/** Calls `path` of `r` (a value, a promise of one, or an RpcPromise) with `args`. */\nexport function pipeTo(r: unknown, path: string[], args: unknown[]): unknown {\n const callAt = (v: any) => {\n if (!path.length) return v(...args);\n const receiver = path.slice(0, -1).reduce((o, k) => o[k], v);\n return receiver[path[path.length - 1]](...args);\n };\n return (r as Record<symbol, unknown>)?.[RPC_PROMISE]\n ? callAt(r)\n : Promise.resolve(r).then(callAt);\n}\n\n/**\n * A stub over an asynchronously obtained target: `fetch` and JS-RPC methods, arguments\n * and results crossing as between isolates. A method's result is an RpcPromise over what\n * `call` returns.\n */\nexport function asyncStub(\n call: (method: string, args: unknown[]) => unknown,\n fetch: (req: Request) => Promise<Response>,\n): Record<string, any> {\n return new Proxy(\n {},\n {\n get(_t, prop) {\n if (prop === STUB) return true;\n if (prop === \"then\" || typeof prop === \"symbol\") return undefined;\n if (prop === \"fetch\")\n return (input: RequestInfo | URL, init?: RequestInit) =>\n fetch(new Request(input as RequestInfo, init));\n return (...args: unknown[]) => rpcCall(() => call(String(prop), cross(args)), cross);\n },\n },\n );\n}\n\n/**\n * A stub of a WorkerEntrypoint (or a default export object): a fresh instance per call,\n * as workerd creates one per request; `ctx.props` carries copied startup properties. Methods\n * of a plain object receive `(…args, env, ctx)`, as its `fetch` receives `(request, env, ctx)`.\n */\nexport function entrypointStub(\n target: unknown,\n env: unknown,\n props: unknown,\n exports?: unknown,\n): Record<string, any> {\n const objectCtx = () => ({\n waitUntil() {},\n passThroughOnException() {},\n props: cross(props ?? {}),\n });\n const make = () => {\n if (typeof target === \"function\") {\n const ctx = {\n props: cross(props ?? {}),\n exports,\n waitUntil() {},\n passThroughOnException() {},\n };\n return new (target as new (c: unknown, e: unknown) => any)(ctx, env);\n }\n return target as any;\n };\n return asyncStub(\n (method, args) => {\n const instance = make();\n const fn = instance?.[method];\n if (typeof fn !== \"function\")\n throw new TypeError(`The RPC receiver does not implement the method \"${method}\".`);\n return fn.apply(instance, typeof target === \"function\" ? args : [...args, env, objectCtx()]);\n },\n async (req) => {\n const instance = make();\n if (typeof instance?.fetch !== \"function\")\n throw new Error(\"Handler does not export a fetch() function.\");\n return typeof target === \"function\"\n ? instance.fetch(req)\n : instance.fetch(req, env, objectCtx());\n },\n );\n}\n\n/** workerd's refusal of `ctx.exports.<Entrypoint>` passed on without `({ props })`. */\nconst LOOPBACK =\n 'Could not serialize object of type \"LoopbackServiceStub\". This type does not support serialization.';\n\n/**\n * `ctx.exports`: loopback handles of a Worker's named exports. An entrypoint's (a\n * WorkerEntrypoint class, or an object with methods) is a stub (`ctx.exports.Greeter.greet()`),\n * and called with `{ props }` gives one with props; a Durable Object class's is a facet class\n * handle, also callable with `{ props }`.\n */\nexport function ctxExports(worker: Record<string, unknown>, env: unknown): Record<string, unknown> {\n const exports: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(worker)) {\n if (name === \"default\" || !value || (typeof value !== \"function\" && typeof value !== \"object\"))\n continue;\n if (typeof value === \"object\" || isWorkerEntrypoint(value)) {\n const withProps = (o: { props?: unknown } = {}) => {\n const stub = entrypointStub(value, env, o.props, exports);\n return new Proxy(stub, {\n get: (t, prop) => (prop === EXPORT ? { name, props: o.props } : t[prop as string]),\n });\n };\n const stub = withProps();\n exports[name] = new Proxy(withProps, {\n get: (_t, prop) => (prop === REFUSE ? LOOPBACK : stub[prop as string]),\n });\n } else {\n const handle = (o: { props?: unknown } = {}) =>\n Object.assign(\n classHandle(async () => ({ cls: value as DurableObjectClass, env, props: o.props })),\n { [EXPORT]: { name, props: o.props } },\n );\n exports[name] = Object.assign(\n handle,\n classHandle(async () => ({ cls: value as DurableObjectClass, env })),\n );\n }\n }\n return exports;\n}\n\n/**\n * Stubs in Durable Object storage (workerd's `allow_irrevocable_stub_storage`), as V8 host\n * objects: a `ctx.exports.X({ props })` stub or class handle is stored as `[name, props]` and\n * read back as `ctx.exports[name]({ props })`. Other stubs and `RpcTarget`s are refused rather\n * than stored as `{}`.\n */\nexport function storedExports(exports: Record<string, unknown>): HostObjects {\n const host: HostObjects = {\n encode(v) {\n const e = (v as Record<symbol, { name: string; props: unknown } | undefined>)[EXPORT];\n if (e) return serialize([e.name, e.props], host);\n if ((v as Record<symbol, unknown>)[STUB] === true || isRpcTarget(v))\n throw new DOMException(\n \"Only ctx.exports.<name>({ props }) stubs and class handles can be stored.\",\n \"DataCloneError\",\n );\n return undefined;\n },\n decode(bytes) {\n const [name, props] = deserialize(bytes, host) as [string, unknown];\n return (exports[name] as (o: { props: unknown }) => unknown)({ props });\n },\n };\n return host;\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** 64-hex-char object id. idFromName is SYNCHRONOUS (as on CF), hence noble instead of crypto.subtle. */
|
|
2
|
+
export declare class DurableObjectId {
|
|
3
|
+
#private;
|
|
4
|
+
readonly name?: string;
|
|
5
|
+
constructor(hex: string, name?: string);
|
|
6
|
+
toString(): string;
|
|
7
|
+
equals(other: DurableObjectId): boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Ids as celld derives them (engine_api.rs), so one name reaches the same object id on
|
|
11
|
+
* celld and on cellb: namespace key `cells:v1:<len(script)>:<script>:<class>`;
|
|
12
|
+
* key = SHA-256(namespace key); id = HMAC(key, name)[0..16] ‖ HMAC(key, first half)[0..16].
|
|
13
|
+
* The second half authenticates the first, so idFromString() rejects ids of other namespaces.
|
|
14
|
+
*/
|
|
15
|
+
export declare function namespaceKey(scriptName: string, className: string): string;
|
|
16
|
+
export declare function idFromName(ns: string, name: string): DurableObjectId;
|
|
17
|
+
export declare function newUniqueId(ns: string): DurableObjectId;
|
|
18
|
+
/** idFromString(): 64 hex digits whose second half authenticates the first for `ns`. */
|
|
19
|
+
export declare function validateId(ns: string, hex: string): DurableObjectId;
|
package/dist/core/id.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { hmac } from "@noble/hashes/hmac";
|
|
2
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
3
|
+
import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
|
|
4
|
+
/** 64-hex-char object id. idFromName is SYNCHRONOUS (as on CF), hence noble instead of crypto.subtle. */
|
|
5
|
+
export class DurableObjectId {
|
|
6
|
+
#hex;
|
|
7
|
+
name;
|
|
8
|
+
constructor(hex, name) {
|
|
9
|
+
if (!/^[0-9a-f]{64}$/.test(hex))
|
|
10
|
+
throw new TypeError("Invalid Durable Object ID: must be 64 hex digits");
|
|
11
|
+
this.#hex = hex;
|
|
12
|
+
if (name !== undefined)
|
|
13
|
+
this.name = name;
|
|
14
|
+
}
|
|
15
|
+
toString() {
|
|
16
|
+
return this.#hex;
|
|
17
|
+
}
|
|
18
|
+
equals(other) {
|
|
19
|
+
return other.toString() === this.#hex;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Ids as celld derives them (engine_api.rs), so one name reaches the same object id on
|
|
24
|
+
* celld and on cellb: namespace key `cells:v1:<len(script)>:<script>:<class>`;
|
|
25
|
+
* key = SHA-256(namespace key); id = HMAC(key, name)[0..16] ‖ HMAC(key, first half)[0..16].
|
|
26
|
+
* The second half authenticates the first, so idFromString() rejects ids of other namespaces.
|
|
27
|
+
*/
|
|
28
|
+
export function namespaceKey(scriptName, className) {
|
|
29
|
+
return `cells:v1:${scriptName.length}:${scriptName}:${className}`;
|
|
30
|
+
}
|
|
31
|
+
const keys = new Map();
|
|
32
|
+
const keyOf = (ns) => {
|
|
33
|
+
let k = keys.get(ns);
|
|
34
|
+
if (!k) {
|
|
35
|
+
k = sha256(new TextEncoder().encode(ns));
|
|
36
|
+
keys.set(ns, k);
|
|
37
|
+
}
|
|
38
|
+
return k;
|
|
39
|
+
};
|
|
40
|
+
const half = (key, data) => hmac(sha256, key, data).subarray(0, 16);
|
|
41
|
+
const withSuffix = (ns, first) => {
|
|
42
|
+
const id = new Uint8Array(32);
|
|
43
|
+
id.set(first, 0);
|
|
44
|
+
id.set(half(keyOf(ns), first), 16);
|
|
45
|
+
return bytesToHex(id);
|
|
46
|
+
};
|
|
47
|
+
export function idFromName(ns, name) {
|
|
48
|
+
const hex = withSuffix(ns, half(keyOf(ns), new TextEncoder().encode(name)));
|
|
49
|
+
// ctx.id.name holds names up to 1024 UTF-8 bytes, as on Cloudflare and celld.
|
|
50
|
+
return new DurableObjectId(hex, new TextEncoder().encode(name).byteLength <= 1024 ? name : undefined);
|
|
51
|
+
}
|
|
52
|
+
export function newUniqueId(ns) {
|
|
53
|
+
const first = new Uint8Array(16);
|
|
54
|
+
crypto.getRandomValues(first);
|
|
55
|
+
return new DurableObjectId(withSuffix(ns, first));
|
|
56
|
+
}
|
|
57
|
+
/** idFromString(): 64 hex digits whose second half authenticates the first for `ns`. */
|
|
58
|
+
export function validateId(ns, hex) {
|
|
59
|
+
const id = new DurableObjectId(hex);
|
|
60
|
+
if (withSuffix(ns, hexToBytes(hex.slice(0, 32))) !== hex)
|
|
61
|
+
throw new TypeError("Durable Object ID is not valid for this namespace");
|
|
62
|
+
return id;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=id.js.map
|