@statewalker/cellb 0.5.2 → 0.7.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/README.md +40 -6
- package/dist/adapters/ltx-vfs.js +26 -4
- package/dist/adapters/ltx-vfs.js.map +1 -1
- package/dist/browser.d.ts +4 -0
- package/dist/browser.js +2 -0
- package/dist/browser.js.map +1 -1
- package/dist/bundle.d.ts +2 -0
- package/dist/bundle.js +5 -0
- package/dist/bundle.js.map +1 -0
- package/dist/core/object-host.d.ts +7 -0
- package/dist/core/object-host.js +40 -7
- package/dist/core/object-host.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/ltx/files-rpc.d.ts +30 -0
- package/dist/ltx/files-rpc.js +129 -0
- package/dist/ltx/files-rpc.js.map +1 -0
- package/dist/ltx/ltx-host.d.ts +63 -0
- package/dist/ltx/ltx-host.js +46 -0
- package/dist/ltx/ltx-host.js.map +1 -0
- package/dist/ltx/ltx-page-server.d.ts +42 -1
- package/dist/ltx/ltx-page-server.js +101 -21
- package/dist/ltx/ltx-page-server.js.map +1 -1
- package/dist/ltx/ltx-pages.d.ts +5 -0
- package/dist/ltx/ltx-pages.js +32 -3
- package/dist/ltx/ltx-pages.js.map +1 -1
- package/dist/ltx/ltx-store-worker.js +35 -22
- package/dist/ltx/ltx-store-worker.js.map +1 -1
- package/dist/node-compat/browser-registry.d.ts +1 -0
- package/dist/node-compat/browser-registry.js +5 -0
- package/dist/node-compat/browser-registry.js.map +1 -1
- package/dist/node-compat/util-guard.d.ts +2 -0
- package/dist/node-compat/util-guard.js +14 -0
- package/dist/node-compat/util-guard.js.map +1 -0
- package/dist/project/browser-host.d.ts +32 -3
- package/dist/project/browser-host.js +47 -20
- package/dist/project/browser-host.js.map +1 -1
- package/dist/project/browser-load.d.ts +16 -4
- package/dist/project/browser-load.js +46 -9
- package/dist/project/browser-load.js.map +1 -1
- package/dist/project/build.js +2 -2
- package/dist/project/build.js.map +1 -1
- package/dist/project/bundle-compiler.d.ts +31 -0
- package/dist/project/bundle-compiler.js +73 -0
- package/dist/project/bundle-compiler.js.map +1 -0
- package/dist/project/node-project.js +3 -3
- package/dist/project/node-project.js.map +1 -1
- package/dist/project/site-compiler.d.ts +67 -0
- package/dist/project/site-compiler.js +134 -0
- package/dist/project/site-compiler.js.map +1 -0
- package/dist/project/source-project.d.ts +46 -0
- package/dist/project/source-project.js +45 -0
- package/dist/project/source-project.js.map +1 -0
- package/dist/project/wrangler.d.ts +4 -0
- package/dist/project/wrangler.js +7 -1
- package/dist/project/wrangler.js.map +1 -1
- package/dist/site.d.ts +2 -0
- package/dist/site.js +4 -3
- package/dist/site.js.map +1 -1
- package/package.json +11 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-host.js","sourceRoot":"","sources":["../../src/core/object-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex } from \"@noble/hashes/utils.js\";\nimport type {\n BackupInfo,\n CellBackup,\n CellDurability,\n Lease,\n OpenCellSql,\n SyncSqlDriver,\n ValueCodec,\n} from \"../ports.js\";\nimport type { AsyncRoot } from \"./async-context.js\";\nimport { CELLD_SCHEMA, LOG_SEQ_READ, LOG_SEQ_WRITE, LOG_TABLE, scopeOf } from \"./celld-schema.js\";\nimport { InputGate, OutputGate } from \"./gates.js\";\nimport {\n asyncStub,\n type DurableObjectClass,\n type IsolatedClass,\n isClassHandle,\n} from \"./handles.js\";\nimport { type DurableObjectId, DurableObjectId as DurableObjectIdClass } from \"./id.js\";\nimport { SqlStorage } from \"./sql-storage.js\";\nimport { DurableObjectState } from \"./state.js\";\nimport { DurableObjectStorage, SyncKvStorage } from \"./storage.js\";\n\n/**\n * The request as the object sees it: its signal also aborts when the host closes (the runtime\n * shuts down), as on Cloudflare when the client goes away; a long poll or an SSE stream that\n * waits on it then ends instead of running on into a closed database.\n */\nexport function closingWith(req: Request, closing: AbortSignal): Request {\n if (closing.aborted) return req;\n const r = new Request(req, { signal: AbortSignal.any([req.signal, closing]) });\n // What cellb set on the request itself (`cf`; `headers` carrying a WebSocket upgrade's\n // headers, which a Request would drop) stays as it was.\n for (const k of [\"cf\", \"headers\"]) {\n const d = Object.getOwnPropertyDescriptor(req, k);\n if (d) Object.defineProperty(r, k, d);\n }\n return r;\n}\n\n/** The object's host was closed for good: its storage and events fail with this. */\nexport class ObjectClosedError extends Error {\n override name = \"ObjectClosedError\";\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} was closed (its runtime shut down, or it moved or was reset)`);\n }\n}\n\nexport class BrokenObjectError extends Error {\n constructor(cause: unknown, reason = \"its storage failed to commit durably\") {\n const detail = cause instanceof Error ? `: ${cause.message}` : \"\";\n super(`Durable Object reset because ${reason}${detail}`, { cause });\n this.name = \"BrokenObjectError\";\n }\n}\n\n/**\n * One live instance of one Durable Object: its SQLite, gates and dispatcher.\n * Everything that reaches the object (fetch, RPC, later alarms/WebSockets)\n * goes through `deliver()`.\n */\nexport class ObjectHost {\n readonly cellKey: string;\n readonly #gate = new InputGate();\n readonly #out = new OutputGate();\n /** The open database; `#driver` follows it, so it can be closed while idle and reopened. */\n #db!: SyncSqlDriver;\n readonly #driver: SyncSqlDriver = new Proxy({} as SyncSqlDriver, {\n get: (_t, k) => {\n // Closed for good (its runtime or shard shut down): code still running in the object\n // learns why, instead of SQLite's \"DB has been closed\".\n if (this.#closed && k !== \"close\")\n return () => {\n throw new ObjectClosedError(this.cellKey);\n };\n const v = (this.#db as unknown as Record<PropertyKey, unknown>)[k];\n return typeof v === \"function\" ? v.bind(this.#db) : v;\n },\n });\n readonly #sql: SqlStorage;\n #instance: any;\n readonly #backup?: CellBackup;\n #backedUpSeq = 0;\n #saving: Promise<void> | undefined;\n readonly state: DurableObjectState;\n #seq = 0;\n broken = false;\n #brokenCause: unknown;\n\n /** blockConcurrencyWhile() rejected (CF: the object is reset; queued events fail). */\n #breakOn(e: unknown): void {\n this.broken = true;\n this.#brokenCause = e;\n }\n\n constructor(opts: {\n cellKey: string;\n id: DurableObjectId;\n cls: DurableObjectClass;\n env: unknown;\n openSql: OpenCellSql;\n durability: CellDurability;\n codec: ValueCodec;\n waitUntil: (p: Promise<unknown>) => void;\n backup?: CellBackup;\n /** The stored alarm changed (null = cleared). */\n onAlarmChange?: (at: number | null) => void;\n /** `ctx.exports` (loopback handles of the Worker's exports). */\n exports?: Record<string, unknown>;\n /** `ctx.props` of a facet started from a class handle with `{ props }`. */\n props?: unknown;\n /** SQLite extensions to load into every cell database (e.g. \"sqlite_vec\"). */\n sqlExtensions?: string[];\n /** storage.deleteAll() keeps the alarm (`delete_all_preserves_alarm`). */\n deleteAllPreservesAlarm?: boolean;\n /**\n * Ownership: acquire the cell's lease before restoring it. No lease → the cell is owned\n * elsewhere (the host refuses events). The lease epoch fences the cell's log segments;\n * losing the lease breaks the host so it stops serving.\n */\n /** Owner epoch when no lease is taken (facets inherit their root's). */\n epoch?: number;\n /** A facet: on open its rows move to this run's scope, as celld does. */\n facet?: boolean;\n acquire?: Lease[\"tryAcquire\"];\n /** The async context events start in (`asyncRoot()`): not the caller's, as on Cloudflare. */\n asyncRoot?: AsyncRoot;\n }) {\n this.#backup = opts.backup;\n this.cellKey = opts.cellKey;\n this.#epoch = opts.epoch;\n this.#opts = opts;\n this.#open = () => {\n this.#db = opts.openSql(opts.cellKey);\n for (const ext of opts.sqlExtensions ?? []) this.#db.loadExtension(ext);\n };\n this.#open();\n this.#sql = new SqlStorage(\n this.#driver,\n (changes) => {\n if (changes && this.#epoch !== undefined) changes.epoch = this.#epoch;\n // Page-level logs (LTX): the changed pages straight from the page hook when the driver\n // has one; the image only on demand (a generation's first snapshot, or no hook).\n const d = this.#driver;\n const seq = ++this.#seq;\n const pages = opts.durability.capturePages ? d.takeDirtyPages() : undefined;\n const snap = () => d.pageImage?.() ?? d.image?.();\n // The log runs later, after the next event may have opened its transaction, and an\n // image cannot be taken inside one (VACUUM INTO). When the log will surely need it\n // (no page hook) or likely does (this host's first commit), take it now.\n const image = opts.durability.capturePages\n ? !pages || seq === 1\n ? snap()\n : snap\n : undefined;\n const durable = opts.durability.committed(this.cellKey, {\n seq,\n changes,\n image,\n pages,\n epoch: this.#epoch,\n });\n const wake = this.#wakeAfterCommit();\n return this.#out.track(wake ? durable.then(wake) : durable);\n },\n { capture: !!opts.durability.captureChanges },\n );\n // The cell's scope in celld's tables (\"Class:idhex\"), so its database is celld's format.\n const kv = new SyncKvStorage(this.#sql, opts.codec, scopeOf(opts.cellKey));\n if (!opts.facet) kv.actorName = opts.id.name;\n const storage = new DurableObjectStorage(this.#sql, kv, this.#gate, () => this.#barrier());\n if (opts.onAlarmChange) storage.onAlarmChange = opts.onAlarmChange;\n storage.deleteAllPreservesAlarm = !!opts.deleteAllPreservesAlarm;\n const state = new DurableObjectState(opts.id, storage, this.#gate, opts.waitUntil, (e) =>\n this.#breakOn(e),\n );\n this.state = state;\n state.attachDispatcher((fn) => this.deliver(fn));\n // ctx.abort(reason) (workerd, celld): the object resets — a fresh instance on the same\n // database serves the next event; the calling event fails with the reason. Writes the event\n // already made still commit (celld: celld's workflow cell aborts after its delete commit).\n (state as unknown as { abort(reason?: unknown): never }).abort = (reason?: unknown): never => {\n queueMicrotask(() => this.restart());\n throw reason ?? new Error(\"Durable Object reset because its code calls abort()\");\n };\n state.exports = opts.exports ?? {};\n state.props = opts.props;\n state.facets = createFacets(\n { ...opts, epoch: () => this.#epoch },\n (name, cls, env, id, props) => {\n const facet = new ObjectHost({\n ...opts,\n // celld's facet stream: <parent>/facets/<SHA-256(name)[0..16] hex> (engine_api.rs)\n cellKey: `${opts.cellKey}/facets/${facetSegment(name)}`,\n id,\n cls,\n env,\n props,\n onAlarmChange: undefined,\n // A facet is part of its root's cell: no lease of its own, the root's epoch.\n acquire: undefined,\n epoch: this.#epoch,\n facet: true,\n });\n this.#facets.add(facet); // closed with its root\n return facet;\n },\n );\n const root = opts.asyncRoot ?? ((fn) => fn());\n this.#root = root;\n const construct = () => root(() => (this.#instance = new opts.cls(state, opts.env)));\n this.#construct = construct;\n const load = opts.backup?.load;\n const replay = opts.backup?.replay;\n const acquire = opts.acquire;\n if (!load && !replay && !acquire) {\n this.#nameFromMetadata(state);\n construct();\n return;\n }\n // Restore-on-open: events queue behind the closed gate until the image is in.\n void this.#gate\n .runClosed(async () => {\n if (acquire) {\n const lease = await acquire(this.cellKey);\n if (!lease) throw new CellOwnedElsewhereError(this.cellKey);\n this.#epoch = lease.epoch;\n this.#release = lease.release;\n lease.lost.addEventListener(\n \"abort\",\n () => this.#breakOn(new Error(`lease of ${this.cellKey} lost`)),\n {\n once: true,\n },\n );\n }\n // Under a lease (the cell's own, or its root's for a facet) the bucket is the cell's\n // truth: a local file kept from an earlier ownership is older than what other owners\n // wrote since, and may hold commits that never became durable.\n await this.#catchUp(this.#epoch !== undefined);\n if (opts.facet) this.#rescope(scopeOf(opts.cellKey));\n else {\n this.#initWake();\n this.#scheduleRestoredAlarm(opts.onAlarmChange);\n }\n this.#nameFromMetadata(state);\n construct();\n })\n .catch((e) => this.#breakOn(e));\n }\n\n /**\n * Takes an image if the cell changed since the last successful save and hands\n * it to `backup.save`. Taken synchronously between events → a consistent image.\n * Skipped while an async transaction() holds the database or a save is running.\n */\n backupIfDirty(reason: BackupInfo[\"reason\"], now: number): Promise<void> {\n const b = this.#backup;\n if (!b || this.broken || this.#saving || this.#seq === this.#backedUpSeq)\n return this.#saving ?? Promise.resolve();\n if (!this.#driver.image)\n return Promise.reject(new Error(\"SyncSqlDriver has no image(): cannot back up\"));\n if (this.#sql.held) return Promise.resolve(); // mid-transaction: next round\n this.#sql.commit();\n const seq = this.#seq;\n let logSeq = 0;\n try {\n logSeq = Number(this.#driver.exec(LOG_SEQ_READ, []).rows[0]?.[0] ?? 0);\n } catch {\n // no _cf_LOG yet\n }\n const image = this.#driver.image();\n this.#saving = b\n .save(this.cellKey, image, { seq, takenAt: now, reason, logSeq })\n .then(\n () => {\n this.#backedUpSeq = Math.max(this.#backedUpSeq, seq);\n },\n (e) => b.onError?.(this.cellKey, e),\n )\n .finally(() => (this.#saving = undefined));\n return this.#saving;\n }\n\n /**\n * Input gate → handler → commit → output gate (durability) → result.\n *\n * Events are queued and STARTED synchronously by a pump only while the gate\n * is open: the first storage op of a handler closes the gate before the\n * next event can start (checking the gate in an `await` continuation is too\n * late — every queued continuation would see it open).\n */\n deliver<T>(fn: (instance: any, state: DurableObjectState) => T | Promise<T>): Promise<T> {\n if (this.#closed) return Promise.reject(new ObjectClosedError(this.cellKey));\n if (this.broken) return Promise.reject(new BrokenObjectError(undefined));\n return new Promise<T>((resolve, reject) => {\n this.#queue.push(() => {\n if (this.#closed) return reject(new ObjectClosedError(this.cellKey));\n if (this.broken)\n return reject(new BrokenObjectError(this.#brokenCause, \"its initialization failed\"));\n let started: Promise<T>;\n this.#active++;\n try {\n started = Promise.resolve(this.#root(() => fn(this.#instance, this.state)));\n } catch (e) {\n started = Promise.reject(e);\n }\n const done = () => {\n this.#active--;\n this.lastActive = Date.now();\n if (!this.#active && !this.#queue.length) this.#notifyIdle();\n };\n started.then(\n (r) => {\n this.#pinIfStandardWebSocket(r);\n this.#barrier().then(\n () => (done(), resolve(r)),\n (e) => (done(), reject(e)),\n );\n },\n (e) =>\n this.#barrier().then(\n () => (done(), reject(e)),\n (e2) => (done(), reject(e2)),\n ),\n );\n });\n this.#pump();\n });\n }\n\n #queue: (() => void)[] = [];\n #pumpWaiting = false;\n #pump = (): void => {\n this.#pumpWaiting = false;\n while (this.#queue.length && this.#gate.isOpen) {\n // A database closed while idle: reopen it (and catch up) before anything runs.\n if (this.#dbClosed) {\n this.#dbClosed = false;\n void this.#gate\n .runClosed(async () => {\n this.#open();\n // The lease was held throughout: a kept file is current, an empty one is restored.\n await this.#catchUp(false);\n })\n .catch((e) => this.#breakOn(e));\n continue;\n }\n // Waking from hibernation: the constructor runs again before the event (and may\n // close the gate with blockConcurrencyWhile, which the loop then respects).\n if (this.#hibernated) {\n this.#hibernated = false;\n this.#construct?.();\n continue;\n }\n this.#queue.shift()!();\n }\n if (this.#queue.length && !this.#pumpWaiting) {\n this.#pumpWaiting = true;\n this.#gate.onOpen(this.#pump);\n }\n };\n\n async #barrier(): Promise<void> {\n try {\n this.#sql.commit();\n await this.#out.barrier();\n } catch (e) {\n this.broken = true;\n try {\n this.#sql.rollback();\n } catch {}\n throw new BrokenObjectError(e);\n }\n }\n\n /**\n * Settles once no event is in flight or queued (a response body still streaming is not an\n * event: its handler has returned). The runtime waits for it, within a grace period, before\n * it closes the database on shutdown.\n */\n /** No event in flight or queued. */\n get idle(): boolean {\n return !this.#active && !this.#queue.length;\n }\n settled(): Promise<void> {\n if (!this.#active && !this.#queue.length) return Promise.resolve();\n return new Promise((resolve) => this.#idleWaiters.push(resolve));\n }\n #idleWaiters: (() => void)[] = [];\n #notifyIdle(): void {\n const waiters = this.#idleWaiters;\n this.#idleWaiters = [];\n for (const w of waiters) w();\n }\n\n /** Closed for good: storage calls throw ObjectClosedError. */\n #closed = false;\n readonly #closing = new AbortController();\n /** Aborts when the host is shutting down: the signal of the requests it is handed. */\n get closing(): AbortSignal {\n return this.#closing.signal;\n }\n /** The first step of a shutdown: requests in flight see their signal abort. */\n shutdown(): void {\n if (this.#closing.signal.aborted) return;\n this.#closing.abort(new ObjectClosedError(this.cellKey));\n for (const facet of this.#facets) facet.shutdown();\n }\n\n /** Settles once the cell lease is released (a store closed earlier would keep it held). */\n close(): Promise<void> {\n this.shutdown();\n this.#closed = true;\n for (const facet of this.#facets) void facet.close();\n this.#facets.clear();\n if (!this.#dbClosed) this.#db.close();\n // Events still queued fail (each checks #closed first); nothing more runs here.\n for (const queued of this.#queue.splice(0)) queued();\n this.#notifyIdle();\n // Hand the cell over at once instead of letting the lease expire.\n const released = this.#release?.().catch(() => {});\n this.#release = undefined;\n return released ?? Promise.resolve();\n }\n #release: (() => Promise<void>) | undefined;\n /** The hosts of this cell's facets: their databases close with the root's. */\n readonly #facets = new Set<ObjectHost>();\n\n /**\n * Brings the local database to the storage's state: restores the image, then replays the log.\n * Without `rebuild` only an empty database is restored (the local file is the primary copy);\n * with it, a non-empty one is replaced too — dropped first when the storage has no image.\n */\n async #catchUp(rebuild: boolean): Promise<void> {\n const { load, replay } = this.#backup ?? {};\n if (!load && !replay) return;\n const d = this.#driver;\n const empty = Number(d.exec(\"SELECT count(*) FROM sqlite_master\", []).rows[0][0]) === 0;\n if (!empty && !rebuild) return;\n const image = await load?.(this.cellKey);\n if (image) {\n if (!d.restore) throw new Error(\"SyncSqlDriver has no restore(): cannot restore a backup\");\n d.restore(image);\n } else if (!empty) {\n // Indexes and triggers go with their tables; sqlite_* tables cannot be dropped. Foreign\n // keys are off meanwhile, so a parent table can go before its children.\n const objects = d.exec(\n \"SELECT type, name FROM sqlite_master WHERE type IN ('view', 'table') AND name NOT LIKE 'sqlite_%'\",\n [],\n ).rows;\n const fk = Number(d.exec(\"PRAGMA foreign_keys\", []).rows[0][0]);\n d.exec(\"PRAGMA foreign_keys = OFF\", []);\n try {\n for (const [type, name] of objects)\n d.exec(`DROP ${type} IF EXISTS \"${String(name).replace(/\"/g, '\"\"')}\"`, []);\n } finally {\n d.exec(`PRAGMA foreign_keys = ${fk}`, []);\n }\n }\n // Then every logged transaction the image does not contain, in order.\n if (replay) await this.#replayLog(replay);\n }\n\n /** Applies log segments newer than the database's own log sequence (restore path). */\n async #replayLog(replay: NonNullable<CellBackup[\"replay\"]>): Promise<void> {\n const d = this.#driver;\n d.exec(LOG_TABLE, []);\n const row = d.exec(LOG_SEQ_READ, []).rows[0];\n const after = Number(row?.[0] ?? 0);\n for await (const seg of replay(this.cellKey, after)) {\n if (!d.applyChangeset)\n throw new Error(\"SyncSqlDriver cannot apply changesets: cannot replay a log\");\n d.exec(\"BEGIN\", []);\n try {\n for (const ddl of seg.ddl) d.exec(ddl, []);\n d.applyChangeset(seg.changeset);\n for (const [sql, params] of seg.statements) d.exec(sql, params);\n d.exec(LOG_SEQ_WRITE, [seg.logSeq]);\n d.exec(\"COMMIT\", []);\n } catch (e) {\n d.exec(\"ROLLBACK\", []);\n throw e;\n }\n }\n }\n\n #construct?: () => unknown;\n #root: AsyncRoot = (fn) => fn();\n readonly #open: () => void;\n #epoch: number | undefined;\n\n /**\n * celld gives each run of a facet its own scope and moves the facet database's rows to it\n * on open (storage.rs open_embedded); doing the same here reads a facet database celld\n * wrote, whatever scope it used.\n */\n /**\n * celld's alarm publication identity (storage/wake_record.rs initialize): one `_cf_WAKE`\n * row per cell carrying the writer epoch; triggers bump its sequence on every alarm change.\n */\n #initWake(): void {\n if (!this.#epoch || !this.#opts.durability.publishWake) return;\n const scope = scopeOf(this.cellKey);\n for (const ddl of CELLD_SCHEMA) this.#driver.exec(ddl, []);\n this.#driver.exec(\n `INSERT INTO _cf_WAKE(scope,epoch,sequence,at_ms)\n VALUES(?1,?2,0,(SELECT at_ms FROM _cf_ALARM WHERE scope=?1))\n ON CONFLICT(scope) DO UPDATE SET epoch=excluded.epoch WHERE excluded.epoch>_cf_WAKE.epoch`,\n [scope, this.#epoch.toString(16).padStart(16, \"0\")],\n );\n this.#wakeSeq = this.#wakeRow()?.sequence;\n }\n /**\n * A cell restored on open may carry an alarm armed by its previous owner (another node, or\n * celld). This node owns the cell now, so the alarm is its to fire: hand it to the scheduler,\n * which otherwise only hears of alarms set here (or of a later wake-index poll).\n */\n #scheduleRestoredAlarm(onAlarmChange?: (at: number) => void): void {\n let at: unknown;\n try {\n at = this.#driver.exec(\"SELECT at_ms FROM _cf_ALARM WHERE scope = ?\", [scopeOf(this.cellKey)])\n .rows[0]?.[0];\n } catch {\n return; // no alarm table: the cell never had an alarm\n }\n if (at != null) onAlarmChange?.(Number(at));\n }\n #wakeSeq: number | undefined;\n #wakeRow(): { epoch: number; sequence: number; at: number | null } | undefined {\n try {\n const r = this.#driver.exec(\"SELECT epoch, sequence, at_ms FROM _cf_WAKE WHERE scope = ?\", [\n scopeOf(this.cellKey),\n ]).rows[0];\n return r\n ? {\n epoch: Number.parseInt(String(r[0]), 16),\n sequence: Number(r[1]),\n at: r[2] == null ? null : Number(r[2]),\n }\n : undefined;\n } catch {\n return undefined;\n }\n }\n /**\n * After a commit: if it changed the alarm, a publication to run once the commit is durable\n * (celld publishes after replication).\n */\n #wakeAfterCommit(): (() => Promise<void>) | undefined {\n const publish = this.#opts.durability.publishWake;\n if (!publish || this.#opts.facet || !this.#epoch) return undefined;\n const row = this.#wakeRow();\n if (!row || row.sequence === this.#wakeSeq) return undefined;\n this.#wakeSeq = row.sequence;\n return () => publish(this.cellKey, row);\n }\n readonly #opts: { durability: CellDurability; facet?: boolean };\n\n /**\n * celld records the name an object was addressed by (`_cf_METADATA.actor_name`) and gives it\n * back as `ctx.id.name` when the object is woken by id alone (an alarm, a wake entry) —\n * celld's own queue cells rely on it. Both directions here: restore it, and record it.\n */\n #nameFromMetadata(state: { id: DurableObjectId }): void {\n if (this.#opts.facet) return;\n const scope = scopeOf(this.cellKey);\n // Reading only: no DDL or write outside a logged transaction (a changeset log replays\n // only what it captured). The name is recorded with the cell's first storage write.\n if (state.id.name !== undefined) return;\n try {\n const r = this.#driver.exec(\"SELECT actor_name FROM _cf_METADATA WHERE scope = ?\", [scope])\n .rows[0];\n if (r?.[0] != null)\n (state as { id: DurableObjectId }).id = new DurableObjectIdClass(\n state.id.toString(),\n String(r[0]),\n );\n } catch {\n // no _cf_METADATA yet\n }\n }\n\n #rescope(scope: string): void {\n for (const table of [\"_cf_KV\", \"_cf_ALARM\", \"_cf_METADATA\"])\n try {\n this.#driver.exec(`UPDATE ${table} SET scope = ? WHERE scope <> ?`, [scope, scope]);\n } catch {\n // table not created yet\n }\n }\n\n // ---- hibernation ---------------------------------------------------------------------\n #active = 0;\n #hibernated = false;\n #pinned = 0;\n /** Time of the last event's completion (the runtime's idle sweep reads it). */\n lastActive = Date.now();\n\n get hibernated(): boolean {\n return this.#hibernated;\n }\n\n /**\n * A 101 response whose server end was accepted with `accept()` (not acceptWebSocket)\n * holds a standard WebSocket: the object cannot hibernate until that socket closes —\n * as on Cloudflare, only the hibernation API lets an object sleep with open sockets.\n */\n #pinIfStandardWebSocket(r: unknown): void {\n const server = (\n r as { webSocket?: { peer?: { accepted: boolean; hibernatable: boolean } & EventTarget } }\n )?.webSocket?.peer;\n if (!server || server.hibernatable || !server.accepted) return;\n this.#pinned++;\n server.addEventListener(\"close\", () => this.#pinned--, { once: true });\n }\n\n /**\n * Drops the instance when nothing runs: no event in flight or queued, no open async\n * transaction, no standard WebSocket. Storage, alarms and hibernatable sockets stay; the\n * next event constructs the class again. Returns whether it hibernated.\n */\n hibernate(): boolean {\n if (\n this.#hibernated ||\n this.broken ||\n this.#active ||\n this.#queue.length ||\n this.#sql.held ||\n this.#pinned\n )\n return false;\n if (!this.#gate.isOpen) return false;\n this.#sql.commit();\n this.#instance = undefined;\n this.#hibernated = true;\n return true;\n }\n #dbClosed = false;\n /**\n * Closes the database of a hibernated cell (the cell lease stays); the next event reopens it.\n * A cell with changes its backup has not taken yet stays open. Returns whether it closed.\n */\n closeDatabase(): boolean {\n if (!this.#hibernated || this.#dbClosed || this.#queue.length || !this.#gate.isOpen)\n return false;\n if (this.#backup && (this.#saving || this.#seq !== this.#backedUpSeq)) return false;\n this.#db.close();\n this.#dbClosed = true;\n return true;\n }\n /** Replaces the instance with a fresh one on the SAME database (facet abort/delete). */\n restart(): void {\n if (this.#dbClosed) return; // the next event reopens it with a fresh instance\n this.#construct?.();\n }\n}\n\n/**\n * `ctx.facets` (celld docs/services/durable-object-facets.md): named child objects with a\n * SQLite database of their own (`<cellKey>/facets/<name>`), started on first call from a\n * class (or class handle) returned by the callback; the name alone selects the database.\n */\ninterface FacetTarget {\n call(method: string, args: unknown[]): Promise<unknown>;\n fetch(req: Request): Promise<Response>;\n restart(): void | Promise<void>;\n delete(): Promise<void>;\n}\n\nfunction createFacets(\n parent: { id: DurableObjectId; env: unknown; cellKey: string; epoch?: () => number | undefined },\n spawn: (\n name: string,\n cls: DurableObjectClass,\n env: unknown,\n id: DurableObjectId,\n props?: unknown,\n ) => ObjectHost,\n) {\n const running = new Map<string, Promise<FacetTarget>>();\n // abort() stops the stubs handed out so far (their calls throw the reason); a later\n // get() starts the facet again on the same database — as celld does.\n const generation = new Map<string, { n: number; reason?: unknown }>();\n const local = (h: ObjectHost): FacetTarget => ({\n call: (method, args) =>\n h.deliver((obj) => {\n const fn = obj[method];\n if (typeof fn !== \"function\") throw new TypeError(`${method} is not a function`);\n return fn.apply(obj, args);\n }),\n fetch: (req) => h.deliver((obj) => obj.fetch(closingWith(req, h.closing))),\n restart: () => h.restart(),\n delete: async () => {\n await h.deliver((_o, state) => state.storage.deleteAll());\n h.restart();\n },\n });\n /** A class of isolated loaded code: the facet's instance and SQLite live in the isolate. */\n const isolated = (iso: IsolatedClass, cellKey: string, idName?: string): FacetTarget => {\n const attached = iso.attach?.(cellKey, parent.epoch?.(), idName);\n const ready = async () => attached;\n return {\n call: async (method, args) => (await ready(), iso.call(cellKey, method, args)),\n fetch: async (req) => (await ready(), iso.fetch(cellKey, req)),\n restart: async () => (await ready(), iso.restart(cellKey)),\n delete: async () => (await ready(), iso.delete(cellKey)),\n };\n };\n\n const targetOf = (name: string, start?: () => unknown): Promise<FacetTarget> => {\n let p = running.get(name);\n if (!p) {\n if (!start) return Promise.reject(new Error(`Facet \"${name}\" is not running`));\n p = (async () => {\n const info = (await start()) as { class: unknown; id?: unknown };\n let cls: DurableObjectClass;\n let env = parent.env;\n let props: unknown;\n if (isClassHandle(info.class)) {\n const r = await info.class.resolve();\n if (\"isolated\" in r)\n return isolated(\n r.isolated,\n `${parent.cellKey}/facets/${facetSegment(name)}`,\n // The facet's own `ctx.id` (partyserver's `this.name` reads its name).\n info.id instanceof DurableObjectIdClass ? info.id.name : undefined,\n );\n ({ cls, env, props } = r);\n } else cls = info.class as DurableObjectClass;\n const id = info.id instanceof DurableObjectIdClass ? info.id : parent.id;\n return local(spawn(name, cls, env, id, props));\n })();\n p.catch(() => running.delete(name));\n running.set(name, p);\n }\n return p;\n };\n return {\n get(name: string, start: () => unknown) {\n if (new TextEncoder().encode(name).byteLength > 256)\n throw new Error(\"A facet name has a limit of 256 bytes\");\n const gen = generation.get(name)?.n ?? 0;\n const live = () => {\n const g = generation.get(name);\n if (g && g.n !== gen) throw g.reason;\n };\n return asyncStub(\n async (method, args) => (live(), await targetOf(name, start)).call(method, args),\n async (req) => (live(), await targetOf(name, start)).fetch(req),\n );\n },\n abort(name: string, reason?: unknown) {\n const n = (generation.get(name)?.n ?? 0) + 1;\n generation.set(name, { n, reason: reason ?? new Error(`Facet \"${name}\" was aborted`) });\n // The database stays: the next call on a new stub gets a fresh instance over it.\n void running.get(name)?.then((t) => t.restart());\n },\n async delete(name: string) {\n const p = running.get(name);\n generation.set(name, {\n n: (generation.get(name)?.n ?? 0) + 1,\n reason: new Error(`Facet \"${name}\" was deleted`),\n });\n if (p) await (await p).delete();\n },\n };\n}\n\n/** The cell's lease is held by another owner (route the request there, or retry later). */\nexport class CellOwnedElsewhereError extends Error {\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} is owned by another node`);\n this.name = \"CellOwnedElsewhereError\";\n }\n}\n\n/** celld's path segment for a facet name: the first 16 bytes of SHA-256(name), hex. */\nexport function facetSegment(name: string): string {\n return bytesToHex(sha256(new TextEncoder().encode(name)).subarray(0, 16));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"object-host.js","sourceRoot":"","sources":["../../src/core/object-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex } from \"@noble/hashes/utils.js\";\nimport type {\n BackupInfo,\n CellBackup,\n CellDurability,\n Lease,\n OpenCellSql,\n SyncSqlDriver,\n ValueCodec,\n} from \"../ports.js\";\nimport type { AsyncRoot } from \"./async-context.js\";\nimport { CELLD_SCHEMA, LOG_SEQ_READ, LOG_SEQ_WRITE, LOG_TABLE, scopeOf } from \"./celld-schema.js\";\nimport { InputGate, OutputGate } from \"./gates.js\";\nimport {\n asyncStub,\n type DurableObjectClass,\n type IsolatedClass,\n isClassHandle,\n} from \"./handles.js\";\nimport { type DurableObjectId, DurableObjectId as DurableObjectIdClass } from \"./id.js\";\nimport { SqlStorage } from \"./sql-storage.js\";\nimport { DurableObjectState } from \"./state.js\";\nimport { DurableObjectStorage, SyncKvStorage } from \"./storage.js\";\n\n/**\n * The request as the object sees it: its signal also aborts when the host closes (the runtime\n * shuts down), as on Cloudflare when the client goes away; a long poll or an SSE stream that\n * waits on it then ends instead of running on into a closed database.\n *\n * The request is not copied: its `signal` becomes a getter that builds the merged signal the\n * first time it is read. Copying a Request and merging two signals cost about 7 µs a request, as\n * much as a small handler's whole turn, and most handlers never read the signal. The request is\n * the caller's own object (`runtime.fetch`) or a stub's fresh copy (a Durable Object's `fetch`);\n * `cf` and the upgrade's `headers` that cellb sets on it stay as they are. A copy the handler\n * makes itself (`new Request(req)`) takes the request's own signal, without the host's.\n */\nexport function closingWith(req: Request, closing: AbortSignal): Request {\n if (closing.aborted) return req;\n const own = signalOf(req);\n let merged: AbortSignal | undefined;\n try {\n Object.defineProperty(req, \"signal\", {\n configurable: true,\n enumerable: false,\n get: () => {\n if (!merged) {\n const before = own();\n merged = before ? AbortSignal.any([before, closing]) : closing;\n }\n return merged;\n },\n });\n return req;\n } catch {\n // A request whose `signal` cannot be redefined: a copy with the merged signal, as before.\n const r = new Request(req, { signal: AbortSignal.any([req.signal, closing]) });\n for (const k of [\"cf\", \"headers\"]) {\n const d = Object.getOwnPropertyDescriptor(req, k);\n if (d) Object.defineProperty(r, k, d);\n }\n return r;\n }\n}\n\n/** Reads `req.signal` as it is now: a getter set by an earlier `closingWith`, or the Request's own. */\nfunction signalOf(req: Request): () => AbortSignal | undefined {\n for (let o: object | null = req; o; o = Object.getPrototypeOf(o)) {\n const d = Object.getOwnPropertyDescriptor(o, \"signal\");\n if (d) return d.get ? () => d.get?.call(req) : () => d.value;\n }\n return () => undefined;\n}\n\n/** The object's host was closed for good: its storage and events fail with this. */\nexport class ObjectClosedError extends Error {\n override name = \"ObjectClosedError\";\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} was closed (its runtime shut down, or it moved or was reset)`);\n }\n}\n\nexport class BrokenObjectError extends Error {\n constructor(cause: unknown, reason = \"its storage failed to commit durably\") {\n const detail = cause instanceof Error ? `: ${cause.message}` : \"\";\n super(`Durable Object reset because ${reason}${detail}`, { cause });\n this.name = \"BrokenObjectError\";\n }\n}\n\n/**\n * One live instance of one Durable Object: its SQLite, gates and dispatcher.\n * Everything that reaches the object (fetch, RPC, later alarms/WebSockets)\n * goes through `deliver()`.\n */\nexport class ObjectHost {\n readonly cellKey: string;\n readonly #gate = new InputGate();\n readonly #out = new OutputGate();\n /** The open database; `#driver` follows it, so it can be closed while idle and reopened. */\n #db!: SyncSqlDriver;\n readonly #driver: SyncSqlDriver = new Proxy({} as SyncSqlDriver, {\n get: (_t, k) => {\n // Closed for good (its runtime or shard shut down): code still running in the object\n // learns why, instead of SQLite's \"DB has been closed\".\n if (this.#closed && k !== \"close\")\n return () => {\n throw new ObjectClosedError(this.cellKey);\n };\n const v = (this.#db as unknown as Record<PropertyKey, unknown>)[k];\n return typeof v === \"function\" ? v.bind(this.#db) : v;\n },\n });\n readonly #sql: SqlStorage;\n #instance: any;\n readonly #backup?: CellBackup;\n #backedUpSeq = 0;\n #saving: Promise<void> | undefined;\n readonly state: DurableObjectState;\n #seq = 0;\n broken = false;\n #brokenCause: unknown;\n\n /** blockConcurrencyWhile() rejected (CF: the object is reset; queued events fail). */\n #breakOn(e: unknown): void {\n this.broken = true;\n this.#brokenCause = e;\n }\n\n constructor(opts: {\n cellKey: string;\n id: DurableObjectId;\n cls: DurableObjectClass;\n env: unknown;\n openSql: OpenCellSql;\n durability: CellDurability;\n codec: ValueCodec;\n waitUntil: (p: Promise<unknown>) => void;\n backup?: CellBackup;\n /** The stored alarm changed (null = cleared). */\n onAlarmChange?: (at: number | null) => void;\n /** `ctx.exports` (loopback handles of the Worker's exports). */\n exports?: Record<string, unknown>;\n /** `ctx.props` of a facet started from a class handle with `{ props }`. */\n props?: unknown;\n /** SQLite extensions to load into every cell database (e.g. \"sqlite_vec\"). */\n sqlExtensions?: string[];\n /** storage.deleteAll() keeps the alarm (`delete_all_preserves_alarm`). */\n deleteAllPreservesAlarm?: boolean;\n /**\n * Ownership: acquire the cell's lease before restoring it. No lease → the cell is owned\n * elsewhere (the host refuses events). The lease epoch fences the cell's log segments;\n * losing the lease breaks the host so it stops serving.\n */\n /** Owner epoch when no lease is taken (facets inherit their root's). */\n epoch?: number;\n /** A facet: on open its rows move to this run's scope, as celld does. */\n facet?: boolean;\n acquire?: Lease[\"tryAcquire\"];\n /** The async context events start in (`asyncRoot()`): not the caller's, as on Cloudflare. */\n asyncRoot?: AsyncRoot;\n }) {\n this.#backup = opts.backup;\n this.cellKey = opts.cellKey;\n this.#epoch = opts.epoch;\n this.#opts = opts;\n this.#open = () => {\n this.#db = opts.openSql(opts.cellKey);\n for (const ext of opts.sqlExtensions ?? []) this.#db.loadExtension(ext);\n };\n this.#open();\n this.#sql = new SqlStorage(\n this.#driver,\n (changes) => {\n if (changes && this.#epoch !== undefined) changes.epoch = this.#epoch;\n // Page-level logs (LTX): the changed pages straight from the page hook when the driver\n // has one; the image only on demand (a generation's first snapshot, or no hook).\n const d = this.#driver;\n const seq = ++this.#seq;\n const pages = opts.durability.capturePages ? d.takeDirtyPages() : undefined;\n const snap = () => d.pageImage?.() ?? d.image?.();\n // The log runs later, after the next event may have opened its transaction, and an\n // image cannot be taken inside one (VACUUM INTO). When the log will surely need it\n // (no page hook) or likely does (this host's first commit), take it now.\n const image = opts.durability.capturePages\n ? !pages || seq === 1\n ? snap()\n : snap\n : undefined;\n const durable = opts.durability.committed(this.cellKey, {\n seq,\n changes,\n image,\n pages,\n epoch: this.#epoch,\n });\n const wake = this.#wakeAfterCommit();\n return this.#out.track(wake ? durable.then(wake) : durable);\n },\n { capture: !!opts.durability.captureChanges },\n );\n // The cell's scope in celld's tables (\"Class:idhex\"), so its database is celld's format.\n const kv = new SyncKvStorage(this.#sql, opts.codec, scopeOf(opts.cellKey));\n if (!opts.facet) kv.actorName = opts.id.name;\n const storage = new DurableObjectStorage(this.#sql, kv, this.#gate, () => this.#barrier());\n if (opts.onAlarmChange) storage.onAlarmChange = opts.onAlarmChange;\n storage.deleteAllPreservesAlarm = !!opts.deleteAllPreservesAlarm;\n const state = new DurableObjectState(opts.id, storage, this.#gate, opts.waitUntil, (e) =>\n this.#breakOn(e),\n );\n this.state = state;\n state.attachDispatcher((fn) => this.deliver(fn));\n // ctx.abort(reason) (workerd, celld): the object resets — a fresh instance on the same\n // database serves the next event; the calling event fails with the reason. Writes the event\n // already made still commit (celld: celld's workflow cell aborts after its delete commit).\n (state as unknown as { abort(reason?: unknown): never }).abort = (reason?: unknown): never => {\n queueMicrotask(() => this.restart());\n throw reason ?? new Error(\"Durable Object reset because its code calls abort()\");\n };\n state.exports = opts.exports ?? {};\n state.props = opts.props;\n state.facets = createFacets(\n { ...opts, epoch: () => this.#epoch },\n (name, cls, env, id, props) => {\n const facet = new ObjectHost({\n ...opts,\n // celld's facet stream: <parent>/facets/<SHA-256(name)[0..16] hex> (engine_api.rs)\n cellKey: `${opts.cellKey}/facets/${facetSegment(name)}`,\n id,\n cls,\n env,\n props,\n onAlarmChange: undefined,\n // A facet is part of its root's cell: no lease of its own, the root's epoch.\n acquire: undefined,\n epoch: this.#epoch,\n facet: true,\n });\n this.#facets.add(facet); // closed with its root\n return facet;\n },\n );\n const root = opts.asyncRoot ?? ((fn) => fn());\n this.#root = root;\n const construct = () => root(() => (this.#instance = new opts.cls(state, opts.env)));\n this.#construct = construct;\n const load = opts.backup?.load;\n const replay = opts.backup?.replay;\n const acquire = opts.acquire;\n if (!load && !replay && !acquire) {\n this.#nameFromMetadata(state);\n construct();\n return;\n }\n // Restore-on-open: events queue behind the closed gate until the image is in.\n void this.#gate\n .runClosed(async () => {\n if (acquire) {\n const lease = await acquire(this.cellKey);\n if (!lease) throw new CellOwnedElsewhereError(this.cellKey);\n this.#epoch = lease.epoch;\n this.#release = lease.release;\n lease.lost.addEventListener(\n \"abort\",\n () => this.#breakOn(new Error(`lease of ${this.cellKey} lost`)),\n {\n once: true,\n },\n );\n }\n // Under a lease (the cell's own, or its root's for a facet) the bucket is the cell's\n // truth: a local file kept from an earlier ownership is older than what other owners\n // wrote since, and may hold commits that never became durable.\n await this.#catchUp(this.#epoch !== undefined);\n if (opts.facet) this.#rescope(scopeOf(opts.cellKey));\n else {\n this.#initWake();\n this.#scheduleRestoredAlarm(opts.onAlarmChange);\n }\n this.#nameFromMetadata(state);\n construct();\n })\n .catch((e) => this.#breakOn(e));\n }\n\n /**\n * Takes an image if the cell changed since the last successful save and hands\n * it to `backup.save`. Taken synchronously between events → a consistent image.\n * Skipped while an async transaction() holds the database or a save is running.\n */\n backupIfDirty(reason: BackupInfo[\"reason\"], now: number): Promise<void> {\n const b = this.#backup;\n if (!b || this.broken || this.#saving || this.#seq === this.#backedUpSeq)\n return this.#saving ?? Promise.resolve();\n if (!this.#driver.image)\n return Promise.reject(new Error(\"SyncSqlDriver has no image(): cannot back up\"));\n if (this.#sql.held) return Promise.resolve(); // mid-transaction: next round\n this.#sql.commit();\n const seq = this.#seq;\n let logSeq = 0;\n try {\n logSeq = Number(this.#driver.exec(LOG_SEQ_READ, []).rows[0]?.[0] ?? 0);\n } catch {\n // no _cf_LOG yet\n }\n const image = this.#driver.image();\n this.#saving = b\n .save(this.cellKey, image, { seq, takenAt: now, reason, logSeq })\n .then(\n () => {\n this.#backedUpSeq = Math.max(this.#backedUpSeq, seq);\n },\n (e) => b.onError?.(this.cellKey, e),\n )\n .finally(() => (this.#saving = undefined));\n return this.#saving;\n }\n\n /**\n * Input gate → handler → commit → output gate (durability) → result.\n *\n * Events are queued and STARTED synchronously by a pump only while the gate\n * is open: the first storage op of a handler closes the gate before the\n * next event can start (checking the gate in an `await` continuation is too\n * late — every queued continuation would see it open).\n */\n deliver<T>(fn: (instance: any, state: DurableObjectState) => T | Promise<T>): Promise<T> {\n if (this.#closed) return Promise.reject(new ObjectClosedError(this.cellKey));\n if (this.broken) return Promise.reject(new BrokenObjectError(undefined));\n return new Promise<T>((resolve, reject) => {\n this.#queue.push(() => {\n if (this.#closed) return reject(new ObjectClosedError(this.cellKey));\n if (this.broken)\n return reject(new BrokenObjectError(this.#brokenCause, \"its initialization failed\"));\n let started: Promise<T>;\n this.#active++;\n try {\n started = Promise.resolve(this.#root(() => fn(this.#instance, this.state)));\n } catch (e) {\n started = Promise.reject(e);\n }\n const done = () => {\n this.#active--;\n this.lastActive = Date.now();\n if (!this.#active && !this.#queue.length) this.#notifyIdle();\n };\n started.then(\n (r) => {\n this.#pinIfStandardWebSocket(r);\n this.#barrier().then(\n () => (done(), resolve(r)),\n (e) => (done(), reject(e)),\n );\n },\n (e) =>\n this.#barrier().then(\n () => (done(), reject(e)),\n (e2) => (done(), reject(e2)),\n ),\n );\n });\n this.#pump();\n });\n }\n\n #queue: (() => void)[] = [];\n #pumpWaiting = false;\n #pump = (): void => {\n this.#pumpWaiting = false;\n while (this.#queue.length && this.#gate.isOpen) {\n // A database closed while idle: reopen it (and catch up) before anything runs.\n if (this.#dbClosed) {\n this.#dbClosed = false;\n void this.#gate\n .runClosed(async () => {\n this.#open();\n // The lease was held throughout: a kept file is current, an empty one is restored.\n await this.#catchUp(false);\n })\n .catch((e) => this.#breakOn(e));\n continue;\n }\n // Waking from hibernation: the constructor runs again before the event (and may\n // close the gate with blockConcurrencyWhile, which the loop then respects).\n if (this.#hibernated) {\n this.#hibernated = false;\n this.#construct?.();\n continue;\n }\n this.#queue.shift()!();\n }\n if (this.#queue.length && !this.#pumpWaiting) {\n this.#pumpWaiting = true;\n this.#gate.onOpen(this.#pump);\n }\n };\n\n async #barrier(): Promise<void> {\n try {\n this.#sql.commit();\n await this.#out.barrier();\n } catch (e) {\n this.broken = true;\n try {\n this.#sql.rollback();\n } catch {}\n throw new BrokenObjectError(e);\n }\n }\n\n /**\n * Settles once no event is in flight or queued (a response body still streaming is not an\n * event: its handler has returned). The runtime waits for it, within a grace period, before\n * it closes the database on shutdown.\n */\n /** No event in flight or queued. */\n get idle(): boolean {\n return !this.#active && !this.#queue.length;\n }\n settled(): Promise<void> {\n if (!this.#active && !this.#queue.length) return Promise.resolve();\n return new Promise((resolve) => this.#idleWaiters.push(resolve));\n }\n #idleWaiters: (() => void)[] = [];\n #notifyIdle(): void {\n const waiters = this.#idleWaiters;\n this.#idleWaiters = [];\n for (const w of waiters) w();\n }\n\n /** Closed for good: storage calls throw ObjectClosedError. */\n #closed = false;\n readonly #closing = new AbortController();\n /** Aborts when the host is shutting down: the signal of the requests it is handed. */\n get closing(): AbortSignal {\n return this.#closing.signal;\n }\n /** The first step of a shutdown: requests in flight see their signal abort. */\n shutdown(): void {\n if (this.#closing.signal.aborted) return;\n this.#closing.abort(new ObjectClosedError(this.cellKey));\n for (const facet of this.#facets) facet.shutdown();\n }\n\n /** Settles once the cell lease is released (a store closed earlier would keep it held). */\n close(): Promise<void> {\n this.shutdown();\n this.#closed = true;\n for (const facet of this.#facets) void facet.close();\n this.#facets.clear();\n if (!this.#dbClosed) this.#db.close();\n // Events still queued fail (each checks #closed first); nothing more runs here.\n for (const queued of this.#queue.splice(0)) queued();\n this.#notifyIdle();\n // Hand the cell over at once instead of letting the lease expire.\n const released = this.#release?.().catch(() => {});\n this.#release = undefined;\n return released ?? Promise.resolve();\n }\n #release: (() => Promise<void>) | undefined;\n /** The hosts of this cell's facets: their databases close with the root's. */\n readonly #facets = new Set<ObjectHost>();\n\n /**\n * Brings the local database to the storage's state: restores the image, then replays the log.\n * Without `rebuild` only an empty database is restored (the local file is the primary copy);\n * with it, a non-empty one is replaced too — dropped first when the storage has no image.\n */\n async #catchUp(rebuild: boolean): Promise<void> {\n const { load, replay } = this.#backup ?? {};\n if (!load && !replay) return;\n const d = this.#driver;\n const empty = Number(d.exec(\"SELECT count(*) FROM sqlite_master\", []).rows[0][0]) === 0;\n if (!empty && !rebuild) return;\n const image = await load?.(this.cellKey);\n if (image) {\n if (!d.restore) throw new Error(\"SyncSqlDriver has no restore(): cannot restore a backup\");\n d.restore(image);\n } else if (!empty) {\n // Indexes and triggers go with their tables; sqlite_* tables cannot be dropped. Foreign\n // keys are off meanwhile, so a parent table can go before its children.\n const objects = d.exec(\n \"SELECT type, name FROM sqlite_master WHERE type IN ('view', 'table') AND name NOT LIKE 'sqlite_%'\",\n [],\n ).rows;\n const fk = Number(d.exec(\"PRAGMA foreign_keys\", []).rows[0][0]);\n d.exec(\"PRAGMA foreign_keys = OFF\", []);\n try {\n for (const [type, name] of objects)\n d.exec(`DROP ${type} IF EXISTS \"${String(name).replace(/\"/g, '\"\"')}\"`, []);\n } finally {\n d.exec(`PRAGMA foreign_keys = ${fk}`, []);\n }\n }\n // Then every logged transaction the image does not contain, in order.\n if (replay) await this.#replayLog(replay);\n }\n\n /** Applies log segments newer than the database's own log sequence (restore path). */\n async #replayLog(replay: NonNullable<CellBackup[\"replay\"]>): Promise<void> {\n const d = this.#driver;\n d.exec(LOG_TABLE, []);\n const row = d.exec(LOG_SEQ_READ, []).rows[0];\n const after = Number(row?.[0] ?? 0);\n for await (const seg of replay(this.cellKey, after)) {\n if (!d.applyChangeset)\n throw new Error(\"SyncSqlDriver cannot apply changesets: cannot replay a log\");\n d.exec(\"BEGIN\", []);\n try {\n for (const ddl of seg.ddl) d.exec(ddl, []);\n d.applyChangeset(seg.changeset);\n for (const [sql, params] of seg.statements) d.exec(sql, params);\n d.exec(LOG_SEQ_WRITE, [seg.logSeq]);\n d.exec(\"COMMIT\", []);\n } catch (e) {\n d.exec(\"ROLLBACK\", []);\n throw e;\n }\n }\n }\n\n #construct?: () => unknown;\n #root: AsyncRoot = (fn) => fn();\n readonly #open: () => void;\n #epoch: number | undefined;\n\n /**\n * celld gives each run of a facet its own scope and moves the facet database's rows to it\n * on open (storage.rs open_embedded); doing the same here reads a facet database celld\n * wrote, whatever scope it used.\n */\n /**\n * celld's alarm publication identity (storage/wake_record.rs initialize): one `_cf_WAKE`\n * row per cell carrying the writer epoch; triggers bump its sequence on every alarm change.\n */\n #initWake(): void {\n if (!this.#epoch || !this.#opts.durability.publishWake) return;\n const scope = scopeOf(this.cellKey);\n for (const ddl of CELLD_SCHEMA) this.#driver.exec(ddl, []);\n this.#driver.exec(\n `INSERT INTO _cf_WAKE(scope,epoch,sequence,at_ms)\n VALUES(?1,?2,0,(SELECT at_ms FROM _cf_ALARM WHERE scope=?1))\n ON CONFLICT(scope) DO UPDATE SET epoch=excluded.epoch WHERE excluded.epoch>_cf_WAKE.epoch`,\n [scope, this.#epoch.toString(16).padStart(16, \"0\")],\n );\n this.#wakeSeq = this.#wakeRow()?.sequence;\n }\n /**\n * A cell restored on open may carry an alarm armed by its previous owner (another node, or\n * celld). This node owns the cell now, so the alarm is its to fire: hand it to the scheduler,\n * which otherwise only hears of alarms set here (or of a later wake-index poll).\n */\n #scheduleRestoredAlarm(onAlarmChange?: (at: number) => void): void {\n let at: unknown;\n try {\n at = this.#driver.exec(\"SELECT at_ms FROM _cf_ALARM WHERE scope = ?\", [scopeOf(this.cellKey)])\n .rows[0]?.[0];\n } catch {\n return; // no alarm table: the cell never had an alarm\n }\n if (at != null) onAlarmChange?.(Number(at));\n }\n #wakeSeq: number | undefined;\n #wakeRow(): { epoch: number; sequence: number; at: number | null } | undefined {\n try {\n const r = this.#driver.exec(\"SELECT epoch, sequence, at_ms FROM _cf_WAKE WHERE scope = ?\", [\n scopeOf(this.cellKey),\n ]).rows[0];\n return r\n ? {\n epoch: Number.parseInt(String(r[0]), 16),\n sequence: Number(r[1]),\n at: r[2] == null ? null : Number(r[2]),\n }\n : undefined;\n } catch {\n return undefined;\n }\n }\n /**\n * After a commit: if it changed the alarm, a publication to run once the commit is durable\n * (celld publishes after replication).\n */\n #wakeAfterCommit(): (() => Promise<void>) | undefined {\n const publish = this.#opts.durability.publishWake;\n if (!publish || this.#opts.facet || !this.#epoch) return undefined;\n const row = this.#wakeRow();\n if (!row || row.sequence === this.#wakeSeq) return undefined;\n this.#wakeSeq = row.sequence;\n return () => publish(this.cellKey, row);\n }\n readonly #opts: { durability: CellDurability; facet?: boolean };\n\n /**\n * celld records the name an object was addressed by (`_cf_METADATA.actor_name`) and gives it\n * back as `ctx.id.name` when the object is woken by id alone (an alarm, a wake entry) —\n * celld's own queue cells rely on it. Both directions here: restore it, and record it.\n */\n #nameFromMetadata(state: { id: DurableObjectId }): void {\n if (this.#opts.facet) return;\n const scope = scopeOf(this.cellKey);\n // Reading only: no DDL or write outside a logged transaction (a changeset log replays\n // only what it captured). The name is recorded with the cell's first storage write.\n if (state.id.name !== undefined) return;\n try {\n const r = this.#driver.exec(\"SELECT actor_name FROM _cf_METADATA WHERE scope = ?\", [scope])\n .rows[0];\n if (r?.[0] != null)\n (state as { id: DurableObjectId }).id = new DurableObjectIdClass(\n state.id.toString(),\n String(r[0]),\n );\n } catch {\n // no _cf_METADATA yet\n }\n }\n\n #rescope(scope: string): void {\n for (const table of [\"_cf_KV\", \"_cf_ALARM\", \"_cf_METADATA\"])\n try {\n this.#driver.exec(`UPDATE ${table} SET scope = ? WHERE scope <> ?`, [scope, scope]);\n } catch {\n // table not created yet\n }\n }\n\n // ---- hibernation ---------------------------------------------------------------------\n #active = 0;\n #hibernated = false;\n #pinned = 0;\n /** Time of the last event's completion (the runtime's idle sweep reads it). */\n lastActive = Date.now();\n\n get hibernated(): boolean {\n return this.#hibernated;\n }\n\n /**\n * A 101 response whose server end was accepted with `accept()` (not acceptWebSocket)\n * holds a standard WebSocket: the object cannot hibernate until that socket closes —\n * as on Cloudflare, only the hibernation API lets an object sleep with open sockets.\n */\n #pinIfStandardWebSocket(r: unknown): void {\n const server = (\n r as { webSocket?: { peer?: { accepted: boolean; hibernatable: boolean } & EventTarget } }\n )?.webSocket?.peer;\n if (!server || server.hibernatable || !server.accepted) return;\n this.#pinned++;\n server.addEventListener(\"close\", () => this.#pinned--, { once: true });\n }\n\n /**\n * Drops the instance when nothing runs: no event in flight or queued, no open async\n * transaction, no standard WebSocket. Storage, alarms and hibernatable sockets stay; the\n * next event constructs the class again. Returns whether it hibernated.\n */\n hibernate(): boolean {\n if (\n this.#hibernated ||\n this.broken ||\n this.#active ||\n this.#queue.length ||\n this.#sql.held ||\n this.#pinned\n )\n return false;\n if (!this.#gate.isOpen) return false;\n this.#sql.commit();\n this.#instance = undefined;\n this.#hibernated = true;\n return true;\n }\n #dbClosed = false;\n /**\n * Closes the database of a hibernated cell (the cell lease stays); the next event reopens it.\n * A cell with changes its backup has not taken yet stays open. Returns whether it closed.\n */\n closeDatabase(): boolean {\n if (!this.#hibernated || this.#dbClosed || this.#queue.length || !this.#gate.isOpen)\n return false;\n if (this.#backup && (this.#saving || this.#seq !== this.#backedUpSeq)) return false;\n this.#db.close();\n this.#dbClosed = true;\n return true;\n }\n /** Replaces the instance with a fresh one on the SAME database (facet abort/delete). */\n restart(): void {\n if (this.#dbClosed) return; // the next event reopens it with a fresh instance\n this.#construct?.();\n }\n}\n\n/**\n * `ctx.facets` (celld docs/services/durable-object-facets.md): named child objects with a\n * SQLite database of their own (`<cellKey>/facets/<name>`), started on first call from a\n * class (or class handle) returned by the callback; the name alone selects the database.\n */\ninterface FacetTarget {\n call(method: string, args: unknown[]): Promise<unknown>;\n fetch(req: Request): Promise<Response>;\n restart(): void | Promise<void>;\n delete(): Promise<void>;\n}\n\nfunction createFacets(\n parent: { id: DurableObjectId; env: unknown; cellKey: string; epoch?: () => number | undefined },\n spawn: (\n name: string,\n cls: DurableObjectClass,\n env: unknown,\n id: DurableObjectId,\n props?: unknown,\n ) => ObjectHost,\n) {\n const running = new Map<string, Promise<FacetTarget>>();\n // abort() stops the stubs handed out so far (their calls throw the reason); a later\n // get() starts the facet again on the same database — as celld does.\n const generation = new Map<string, { n: number; reason?: unknown }>();\n const local = (h: ObjectHost): FacetTarget => ({\n call: (method, args) =>\n h.deliver((obj) => {\n const fn = obj[method];\n if (typeof fn !== \"function\") throw new TypeError(`${method} is not a function`);\n return fn.apply(obj, args);\n }),\n fetch: (req) => h.deliver((obj) => obj.fetch(closingWith(req, h.closing))),\n restart: () => h.restart(),\n delete: async () => {\n await h.deliver((_o, state) => state.storage.deleteAll());\n h.restart();\n },\n });\n /** A class of isolated loaded code: the facet's instance and SQLite live in the isolate. */\n const isolated = (iso: IsolatedClass, cellKey: string, idName?: string): FacetTarget => {\n const attached = iso.attach?.(cellKey, parent.epoch?.(), idName);\n const ready = async () => attached;\n return {\n call: async (method, args) => (await ready(), iso.call(cellKey, method, args)),\n fetch: async (req) => (await ready(), iso.fetch(cellKey, req)),\n restart: async () => (await ready(), iso.restart(cellKey)),\n delete: async () => (await ready(), iso.delete(cellKey)),\n };\n };\n\n const targetOf = (name: string, start?: () => unknown): Promise<FacetTarget> => {\n let p = running.get(name);\n if (!p) {\n if (!start) return Promise.reject(new Error(`Facet \"${name}\" is not running`));\n p = (async () => {\n const info = (await start()) as { class: unknown; id?: unknown };\n let cls: DurableObjectClass;\n let env = parent.env;\n let props: unknown;\n if (isClassHandle(info.class)) {\n const r = await info.class.resolve();\n if (\"isolated\" in r)\n return isolated(\n r.isolated,\n `${parent.cellKey}/facets/${facetSegment(name)}`,\n // The facet's own `ctx.id` (partyserver's `this.name` reads its name).\n info.id instanceof DurableObjectIdClass ? info.id.name : undefined,\n );\n ({ cls, env, props } = r);\n } else cls = info.class as DurableObjectClass;\n const id = info.id instanceof DurableObjectIdClass ? info.id : parent.id;\n return local(spawn(name, cls, env, id, props));\n })();\n p.catch(() => running.delete(name));\n running.set(name, p);\n }\n return p;\n };\n return {\n get(name: string, start: () => unknown) {\n if (new TextEncoder().encode(name).byteLength > 256)\n throw new Error(\"A facet name has a limit of 256 bytes\");\n const gen = generation.get(name)?.n ?? 0;\n const live = () => {\n const g = generation.get(name);\n if (g && g.n !== gen) throw g.reason;\n };\n return asyncStub(\n async (method, args) => (live(), await targetOf(name, start)).call(method, args),\n async (req) => (live(), await targetOf(name, start)).fetch(req),\n );\n },\n abort(name: string, reason?: unknown) {\n const n = (generation.get(name)?.n ?? 0) + 1;\n generation.set(name, { n, reason: reason ?? new Error(`Facet \"${name}\" was aborted`) });\n // The database stays: the next call on a new stub gets a fresh instance over it.\n void running.get(name)?.then((t) => t.restart());\n },\n async delete(name: string) {\n const p = running.get(name);\n generation.set(name, {\n n: (generation.get(name)?.n ?? 0) + 1,\n reason: new Error(`Facet \"${name}\" was deleted`),\n });\n if (p) await (await p).delete();\n },\n };\n}\n\n/** The cell's lease is held by another owner (route the request there, or retry later). */\nexport class CellOwnedElsewhereError extends Error {\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} is owned by another node`);\n this.name = \"CellOwnedElsewhereError\";\n }\n}\n\n/** celld's path segment for a facet name: the first 16 bytes of SHA-256(name), hex. */\nexport function facetSegment(name: string): string {\n return bytesToHex(sha256(new TextEncoder().encode(name)).subarray(0, 16));\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { BrokenObjectError, CellOwnedElsewhereError, ObjectClosedError, } from "
|
|
|
12
12
|
export { type CellRuntime, type CellRuntimeOptions, createCellRuntime, type WorkerModule, } from "./core/runtime.js";
|
|
13
13
|
export { shardOf } from "./core/shard.js";
|
|
14
14
|
export { DurableObjectState } from "./core/state.js";
|
|
15
|
+
export { type FilesRpcOptions, rpcFilesClient, serveFilesApi } from "./ltx/files-rpc.js";
|
|
15
16
|
export * from "./ports.js";
|
|
16
17
|
export { parseJsonc } from "./project/jsonc.js";
|
|
17
18
|
export { createProjectRuntime, type ProjectHost, type ProjectRuntime, type WranglerConfig, } from "./project/wrangler.js";
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export { BrokenObjectError, CellOwnedElsewhereError, ObjectClosedError, } from "
|
|
|
12
12
|
export { createCellRuntime, } from "./core/runtime.js";
|
|
13
13
|
export { shardOf } from "./core/shard.js";
|
|
14
14
|
export { DurableObjectState } from "./core/state.js";
|
|
15
|
+
export { rpcFilesClient, serveFilesApi } from "./ltx/files-rpc.js";
|
|
15
16
|
export * from "./ports.js";
|
|
16
17
|
export { parseJsonc } from "./project/jsonc.js";
|
|
17
18
|
export { createProjectRuntime, } from "./project/wrangler.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +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,EACL,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,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,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,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 {\n BrokenObjectError,\n CellOwnedElsewhereError,\n ObjectClosedError,\n} 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 { parseJsonc } from \"./project/jsonc.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"]}
|
|
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,EACL,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,iBAAiB,GAElB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAwB,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACzF,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,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 {\n BrokenObjectError,\n CellOwnedElsewhereError,\n ObjectClosedError,\n} 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 { type FilesRpcOptions, rpcFilesClient, serveFilesApi } from \"./ltx/files-rpc.js\";\nexport * from \"./ports.js\";\nexport { parseJsonc } from \"./project/jsonc.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,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A FilesApi across threads: `serveFilesApi(port, files)` answers on one end of a MessagePort
|
|
3
|
+
* for a FilesApi that lives in this thread (the user's own: File System Access, memory, OPFS,
|
|
4
|
+
* a key/value store, S3…), and `rpcFilesClient(port)` is that FilesApi in another thread (the
|
|
5
|
+
* LTX store worker, say). An instance cannot be posted to a worker; a port can.
|
|
6
|
+
*
|
|
7
|
+
* On @statewalker/webrun-rpc: the unary methods are one `callPort` each; a ranged read (the
|
|
8
|
+
* LTX store's page reads) is one `callPort` answered with the bytes; `read` without a length,
|
|
9
|
+
* `list` and `write` stream with `callBidi`. A write is sent in batches of up to `batchBytes`
|
|
10
|
+
* (the LTX encoder yields one small block per page).
|
|
11
|
+
*
|
|
12
|
+
* The client must not live in a thread that blocks on `Atomics.wait` (the SQLite VFS worker):
|
|
13
|
+
* a blocked thread receives no answers.
|
|
14
|
+
*/
|
|
15
|
+
import type { FilesApi } from "@statewalker/webrun-files";
|
|
16
|
+
import { type MessageTarget } from "@statewalker/webrun-rpc";
|
|
17
|
+
export interface FilesRpcOptions {
|
|
18
|
+
/** How long one call may take, in ms (a disk, a network store); 60 s by default. */
|
|
19
|
+
timeout?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Answers `rpcFilesClient` calls on `port` with `files`. Several ports may serve one FilesApi
|
|
23
|
+
* (one per worker). Returns the teardown.
|
|
24
|
+
*/
|
|
25
|
+
export declare function serveFilesApi(port: MessageTarget, files: FilesApi): () => void;
|
|
26
|
+
/** A FilesApi whose calls go over `port` to a `serveFilesApi`. */
|
|
27
|
+
export declare function rpcFilesClient(port: MessageTarget, opts?: FilesRpcOptions & {
|
|
28
|
+
/** Bytes of a write sent per message; 1 MiB by default. */
|
|
29
|
+
batchBytes?: number;
|
|
30
|
+
}): FilesApi;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { callBidi, callPort, listenBidi, listenPort, } from "@statewalker/webrun-rpc";
|
|
2
|
+
const UNARY = "webrun-files:unary";
|
|
3
|
+
const UNARY_METHODS = ["stats", "exists", "mkdir", "remove", "move", "copy", "readRange"];
|
|
4
|
+
const start = (port) => port.start?.();
|
|
5
|
+
/**
|
|
6
|
+
* The bytes of `c` in a buffer of their own: posting a view clones its WHOLE buffer (a page
|
|
7
|
+
* read as a subarray of a 10 MB file would cross the thread as 10 MB).
|
|
8
|
+
*/
|
|
9
|
+
const own = (c) => c.byteOffset === 0 && c.byteLength === c.buffer.byteLength ? c : c.slice();
|
|
10
|
+
async function* owned(chunks) {
|
|
11
|
+
for await (const c of chunks)
|
|
12
|
+
yield own(c);
|
|
13
|
+
}
|
|
14
|
+
async function concat(chunks) {
|
|
15
|
+
const parts = [];
|
|
16
|
+
let n = 0;
|
|
17
|
+
for await (const c of chunks)
|
|
18
|
+
parts.push(c), (n += c.length);
|
|
19
|
+
if (parts.length === 1)
|
|
20
|
+
return own(parts[0]);
|
|
21
|
+
const out = new Uint8Array(n);
|
|
22
|
+
let o = 0;
|
|
23
|
+
for (const p of parts)
|
|
24
|
+
out.set(p, o), (o += p.length);
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Answers `rpcFilesClient` calls on `port` with `files`. Several ports may serve one FilesApi
|
|
29
|
+
* (one per worker). Returns the teardown.
|
|
30
|
+
*/
|
|
31
|
+
export function serveFilesApi(port, files) {
|
|
32
|
+
const offUnary = listenPort(port, async ({ m, a }) => {
|
|
33
|
+
if (!UNARY_METHODS.includes(m))
|
|
34
|
+
throw new Error(`files-rpc: unknown method ${String(m)}`);
|
|
35
|
+
if (m === "readRange") {
|
|
36
|
+
const [path, start, length] = a;
|
|
37
|
+
return concat(files.read(path, { start, length }));
|
|
38
|
+
}
|
|
39
|
+
return files[m].apply(files, a);
|
|
40
|
+
}, { channelName: UNARY });
|
|
41
|
+
const offStream = listenBidi(port, async (input, params) => {
|
|
42
|
+
const { fs, path, opts } = params;
|
|
43
|
+
if (fs === "read")
|
|
44
|
+
return owned(files.read(path, opts));
|
|
45
|
+
if (fs === "list")
|
|
46
|
+
return files.list(path, opts);
|
|
47
|
+
await files.write(path, input);
|
|
48
|
+
return (async function* () { })();
|
|
49
|
+
}, (params) => typeof params.fs === "string");
|
|
50
|
+
start(port);
|
|
51
|
+
return () => {
|
|
52
|
+
offUnary();
|
|
53
|
+
offStream();
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** A FilesApi whose calls go over `port` to a `serveFilesApi`. */
|
|
57
|
+
export function rpcFilesClient(port, opts = {}) {
|
|
58
|
+
start(port);
|
|
59
|
+
const timeout = opts.timeout ?? 60_000;
|
|
60
|
+
const batchBytes = opts.batchBytes ?? 1 << 20;
|
|
61
|
+
const call = (m, a, signal) => callPort(port, { m, a }, { channelName: UNARY, timeout, signal });
|
|
62
|
+
const unary = (m) => (...a) => call(m, a);
|
|
63
|
+
const stream = (req, input = [], signal) => callBidi(port, input, {
|
|
64
|
+
...req,
|
|
65
|
+
// Read by the serving side too: its `send` waits this long for each chunk's
|
|
66
|
+
// acknowledgement, which comes when this side's consumer asks for the next one (without
|
|
67
|
+
// it, a consumer pausing over 1 s between chunks failed the stream).
|
|
68
|
+
timeout,
|
|
69
|
+
options: { timeout, bidiTimeout: 2147483647, signal },
|
|
70
|
+
});
|
|
71
|
+
/** Chunks gathered into messages of about `batchBytes`. */
|
|
72
|
+
async function* batched(content) {
|
|
73
|
+
let parts = [];
|
|
74
|
+
let n = 0;
|
|
75
|
+
const flush = () => {
|
|
76
|
+
const out = parts.length === 1 ? own(parts[0]) : new Uint8Array(n);
|
|
77
|
+
if (parts.length > 1) {
|
|
78
|
+
let o = 0;
|
|
79
|
+
for (const p of parts)
|
|
80
|
+
out.set(p, o), (o += p.length);
|
|
81
|
+
}
|
|
82
|
+
parts = [];
|
|
83
|
+
n = 0;
|
|
84
|
+
return out;
|
|
85
|
+
};
|
|
86
|
+
for await (const c of content) {
|
|
87
|
+
if (!c.length)
|
|
88
|
+
continue;
|
|
89
|
+
parts.push(c);
|
|
90
|
+
n += c.length;
|
|
91
|
+
if (n >= batchBytes)
|
|
92
|
+
yield flush();
|
|
93
|
+
}
|
|
94
|
+
if (n)
|
|
95
|
+
yield flush();
|
|
96
|
+
}
|
|
97
|
+
const api = {
|
|
98
|
+
read(path, o) {
|
|
99
|
+
const { start, length, signal } = o ?? {};
|
|
100
|
+
// A ranged read (the LTX store's page reads): one call, one answer.
|
|
101
|
+
if (length !== undefined)
|
|
102
|
+
return (async function* () {
|
|
103
|
+
const bytes = await call("readRange", [path, start ?? 0, length], signal);
|
|
104
|
+
if (bytes.length)
|
|
105
|
+
yield bytes;
|
|
106
|
+
})();
|
|
107
|
+
return stream({ fs: "read", path, opts: { start } }, [], signal);
|
|
108
|
+
},
|
|
109
|
+
list(path, o) {
|
|
110
|
+
return stream({
|
|
111
|
+
fs: "list",
|
|
112
|
+
path,
|
|
113
|
+
opts: { recursive: o?.recursive, after: o?.after },
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
async write(path, content) {
|
|
117
|
+
for await (const _ of stream({ fs: "write", path }, batched(content)))
|
|
118
|
+
void _;
|
|
119
|
+
},
|
|
120
|
+
stats: unary("stats"),
|
|
121
|
+
exists: unary("exists"),
|
|
122
|
+
mkdir: unary("mkdir"),
|
|
123
|
+
remove: unary("remove"),
|
|
124
|
+
move: unary("move"),
|
|
125
|
+
copy: unary("copy"),
|
|
126
|
+
};
|
|
127
|
+
return api;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=files-rpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-rpc.js","sourceRoot":"","sources":["../../src/ltx/files-rpc.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A FilesApi across threads: `serveFilesApi(port, files)` answers on one end of a MessagePort\n * for a FilesApi that lives in this thread (the user's own: File System Access, memory, OPFS,\n * a key/value store, S3…), and `rpcFilesClient(port)` is that FilesApi in another thread (the\n * LTX store worker, say). An instance cannot be posted to a worker; a port can.\n *\n * On @statewalker/webrun-rpc: the unary methods are one `callPort` each; a ranged read (the\n * LTX store's page reads) is one `callPort` answered with the bytes; `read` without a length,\n * `list` and `write` stream with `callBidi`. A write is sent in batches of up to `batchBytes`\n * (the LTX encoder yields one small block per page).\n *\n * The client must not live in a thread that blocks on `Atomics.wait` (the SQLite VFS worker):\n * a blocked thread receives no answers.\n */\nimport type {\n FileInfo,\n FileStats,\n FilesApi,\n ListOptions,\n ReadOptions,\n} from \"@statewalker/webrun-files\";\nimport {\n callBidi,\n callPort,\n listenBidi,\n listenPort,\n type MessageTarget,\n} from \"@statewalker/webrun-rpc\";\n\nconst UNARY = \"webrun-files:unary\";\nconst UNARY_METHODS = [\"stats\", \"exists\", \"mkdir\", \"remove\", \"move\", \"copy\", \"readRange\"] as const;\ntype UnaryMethod = (typeof UNARY_METHODS)[number];\n\ninterface UnaryRequest {\n m: UnaryMethod;\n a: unknown[];\n}\ninterface StreamRequest {\n fs: \"read\" | \"list\" | \"write\";\n path: string;\n opts?: { start?: number; length?: number; recursive?: boolean; after?: string };\n}\n\nexport interface FilesRpcOptions {\n /** How long one call may take, in ms (a disk, a network store); 60 s by default. */\n timeout?: number;\n}\n\nconst start = (port: MessageTarget) => (port as { start?: () => void }).start?.();\n\n/**\n * The bytes of `c` in a buffer of their own: posting a view clones its WHOLE buffer (a page\n * read as a subarray of a 10 MB file would cross the thread as 10 MB).\n */\nconst own = (c: Uint8Array) =>\n c.byteOffset === 0 && c.byteLength === c.buffer.byteLength ? c : c.slice();\n\nasync function* owned(chunks: AsyncIterable<Uint8Array>) {\n for await (const c of chunks) yield own(c);\n}\n\nasync function concat(chunks: AsyncIterable<Uint8Array>): Promise<Uint8Array> {\n const parts: Uint8Array[] = [];\n let n = 0;\n for await (const c of chunks) parts.push(c), (n += c.length);\n if (parts.length === 1) return own(parts[0]);\n const out = new Uint8Array(n);\n let o = 0;\n for (const p of parts) out.set(p, o), (o += p.length);\n return out;\n}\n\n/**\n * Answers `rpcFilesClient` calls on `port` with `files`. Several ports may serve one FilesApi\n * (one per worker). Returns the teardown.\n */\nexport function serveFilesApi(port: MessageTarget, files: FilesApi): () => void {\n const offUnary = listenPort<UnaryRequest, unknown>(\n port,\n async ({ m, a }) => {\n if (!UNARY_METHODS.includes(m)) throw new Error(`files-rpc: unknown method ${String(m)}`);\n if (m === \"readRange\") {\n const [path, start, length] = a as [string, number, number];\n return concat(files.read(path, { start, length }));\n }\n return (files[m] as (...args: unknown[]) => Promise<unknown>).apply(files, a);\n },\n { channelName: UNARY },\n );\n const offStream = listenBidi<Uint8Array, unknown>(\n port,\n async (input, params) => {\n const { fs, path, opts } = params as unknown as StreamRequest;\n if (fs === \"read\") return owned(files.read(path, opts as ReadOptions));\n if (fs === \"list\") return files.list(path, opts as ListOptions);\n await files.write(path, input);\n return (async function* () {})();\n },\n (params) => typeof (params as { fs?: unknown }).fs === \"string\",\n );\n start(port);\n return () => {\n offUnary();\n offStream();\n };\n}\n\n/** A FilesApi whose calls go over `port` to a `serveFilesApi`. */\nexport function rpcFilesClient(\n port: MessageTarget,\n opts: FilesRpcOptions & {\n /** Bytes of a write sent per message; 1 MiB by default. */\n batchBytes?: number;\n } = {},\n): FilesApi {\n start(port);\n const timeout = opts.timeout ?? 60_000;\n const batchBytes = opts.batchBytes ?? 1 << 20;\n const call = <T>(m: UnaryMethod, a: unknown[], signal?: AbortSignal) =>\n callPort<T, UnaryRequest>(port, { m, a }, { channelName: UNARY, timeout, signal });\n const unary =\n <T>(m: UnaryMethod) =>\n (...a: unknown[]) =>\n call<T>(m, a);\n const stream = <T>(\n req: StreamRequest,\n input: AsyncIterable<Uint8Array> | Uint8Array[] = [],\n signal?: AbortSignal,\n ) =>\n callBidi<Uint8Array, T>(port, input, {\n ...req,\n // Read by the serving side too: its `send` waits this long for each chunk's\n // acknowledgement, which comes when this side's consumer asks for the next one (without\n // it, a consumer pausing over 1 s between chunks failed the stream).\n timeout,\n options: { timeout, bidiTimeout: 2147483647, signal },\n });\n /** Chunks gathered into messages of about `batchBytes`. */\n async function* batched(content: Iterable<Uint8Array> | AsyncIterable<Uint8Array>) {\n let parts: Uint8Array[] = [];\n let n = 0;\n const flush = () => {\n const out = parts.length === 1 ? own(parts[0]) : new Uint8Array(n);\n if (parts.length > 1) {\n let o = 0;\n for (const p of parts) out.set(p, o), (o += p.length);\n }\n parts = [];\n n = 0;\n return out;\n };\n for await (const c of content as AsyncIterable<Uint8Array>) {\n if (!c.length) continue;\n parts.push(c);\n n += c.length;\n if (n >= batchBytes) yield flush();\n }\n if (n) yield flush();\n }\n const api: FilesApi = {\n read(path: string, o?: ReadOptions): AsyncIterable<Uint8Array> {\n const { start, length, signal } = o ?? {};\n // A ranged read (the LTX store's page reads): one call, one answer.\n if (length !== undefined)\n return (async function* () {\n const bytes = await call<Uint8Array>(\"readRange\", [path, start ?? 0, length], signal);\n if (bytes.length) yield bytes;\n })();\n return stream<Uint8Array>({ fs: \"read\", path, opts: { start } }, [], signal);\n },\n list(path: string, o?: ListOptions): AsyncIterable<FileInfo> {\n return stream<FileInfo>({\n fs: \"list\",\n path,\n opts: { recursive: o?.recursive, after: o?.after },\n });\n },\n async write(path, content) {\n for await (const _ of stream<never>({ fs: \"write\", path }, batched(content))) void _;\n },\n stats: unary<FileStats | undefined>(\"stats\") as FilesApi[\"stats\"],\n exists: unary<boolean>(\"exists\") as FilesApi[\"exists\"],\n mkdir: unary<void>(\"mkdir\") as FilesApi[\"mkdir\"],\n remove: unary<boolean>(\"remove\") as FilesApi[\"remove\"],\n move: unary<boolean>(\"move\") as FilesApi[\"move\"],\n copy: unary<boolean>(\"copy\") as FilesApi[\"copy\"],\n };\n return api;\n}\n"]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cells' storage chosen by the app: it opens a FilesApi (File System Access, memory, OPFS, a
|
|
3
|
+
* key/value store, S3…) BEFORE starting cellb's workers, then hands it to them in one of two
|
|
4
|
+
* ways (a FilesApi instance cannot be posted to a worker; a port can):
|
|
5
|
+
*
|
|
6
|
+
* - `filesApiPort(files)`: the FilesApi stays in this thread and is served over a port; the
|
|
7
|
+
* shard worker passes the port to its LTX store worker (`bucket: { ltx, files: { port } }`),
|
|
8
|
+
* which runs the store (LZ4, compaction) and calls the FilesApi by message.
|
|
9
|
+
* - `serveLtxStore(files)`: the LTX store itself runs in this thread on the instance (no
|
|
10
|
+
* FilesApi messages at all); the shard worker's VFS sends it its page reads and commits
|
|
11
|
+
* (`bucket: { ltx, ltxStore: { sab, port } }`). The store's work then shares this thread.
|
|
12
|
+
*
|
|
13
|
+
* Either way, one call per shard worker: a port answers one worker, a store one VFS.
|
|
14
|
+
*/
|
|
15
|
+
import type { FilesApi } from "@statewalker/webrun-files";
|
|
16
|
+
/** A port to `files` for a worker (transfer it); `close()` stops serving it. */
|
|
17
|
+
export declare function filesApiPort(files: FilesApi): {
|
|
18
|
+
port: MessagePort;
|
|
19
|
+
close(): void;
|
|
20
|
+
};
|
|
21
|
+
export interface ServeLtxStoreOptions {
|
|
22
|
+
/** Names the storage: two stores with one scope never write the same cell at once. */
|
|
23
|
+
lockScope: string;
|
|
24
|
+
/** Files per cell before it is folded into one snapshot (default 64). */
|
|
25
|
+
compactAfter?: number;
|
|
26
|
+
/** Free bytes where the files are (see ltxCellStore); unknown by default. */
|
|
27
|
+
room?: () => Promise<number | undefined>;
|
|
28
|
+
/** Bytes of the shared buffer's payload: a read-ahead run (default 1 MiB, at least 64 KiB). */
|
|
29
|
+
payloadBytes?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The LTX store on `files` in this thread, for ONE shard worker's VFS: give the worker
|
|
33
|
+
* `{ sab, port }` (transfer the port). This thread must not block (a page, or any worker that
|
|
34
|
+
* does not run SQLite); it answers into `sab`.
|
|
35
|
+
*/
|
|
36
|
+
export declare function serveLtxStore(files: FilesApi, opts: ServeLtxStoreOptions): {
|
|
37
|
+
sab: SharedArrayBuffer;
|
|
38
|
+
port: MessagePort;
|
|
39
|
+
store: {
|
|
40
|
+
handle(msg: import("./ltx-page-server.js").LtxStoreMessage & {
|
|
41
|
+
seq?: number;
|
|
42
|
+
until?: number;
|
|
43
|
+
}): void;
|
|
44
|
+
compact: (cell: string) => Promise<number>;
|
|
45
|
+
stats: {
|
|
46
|
+
commits: number;
|
|
47
|
+
writeMs: number;
|
|
48
|
+
appendMs: number;
|
|
49
|
+
compactions: number;
|
|
50
|
+
compactMs: number;
|
|
51
|
+
reads: number;
|
|
52
|
+
readMs: number;
|
|
53
|
+
};
|
|
54
|
+
close(): Promise<void>;
|
|
55
|
+
files: (cell: string) => Promise<string[]>;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Stops serving: call it when the shard worker ends, so a store for its successor can
|
|
59
|
+
* take the cells' Web Locks (it waits 20 s for them, then fails). Resolves once the
|
|
60
|
+
* store's work under way has ended and its locks are released.
|
|
61
|
+
*/
|
|
62
|
+
close(): Promise<void>;
|
|
63
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { serveFilesApi } from "./files-rpc.js";
|
|
2
|
+
import { ltxCellStore } from "./ltx-page-server.js";
|
|
3
|
+
/** A port to `files` for a worker (transfer it); `close()` stops serving it. */
|
|
4
|
+
export function filesApiPort(files) {
|
|
5
|
+
const ch = new MessageChannel();
|
|
6
|
+
const stop = serveFilesApi(ch.port1, files);
|
|
7
|
+
return {
|
|
8
|
+
port: ch.port2,
|
|
9
|
+
close() {
|
|
10
|
+
stop();
|
|
11
|
+
ch.port1.close();
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The LTX store on `files` in this thread, for ONE shard worker's VFS: give the worker
|
|
17
|
+
* `{ sab, port }` (transfer the port). This thread must not block (a page, or any worker that
|
|
18
|
+
* does not run SQLite); it answers into `sab`.
|
|
19
|
+
*/
|
|
20
|
+
export function serveLtxStore(files, opts) {
|
|
21
|
+
// At least one page of SQLite's largest size: a smaller buffer would answer reads with no
|
|
22
|
+
// pages at all.
|
|
23
|
+
const sab = new SharedArrayBuffer(8 + Math.max(65536, opts.payloadBytes ?? 16 * 65536));
|
|
24
|
+
const store = ltxCellStore(files, sab, {
|
|
25
|
+
lockScope: opts.lockScope,
|
|
26
|
+
compactAfter: opts.compactAfter,
|
|
27
|
+
room: opts.room ?? (async () => undefined),
|
|
28
|
+
});
|
|
29
|
+
const ch = new MessageChannel();
|
|
30
|
+
ch.port1.onmessage = (e) => store.handle(e.data);
|
|
31
|
+
return {
|
|
32
|
+
sab,
|
|
33
|
+
port: ch.port2,
|
|
34
|
+
store,
|
|
35
|
+
/**
|
|
36
|
+
* Stops serving: call it when the shard worker ends, so a store for its successor can
|
|
37
|
+
* take the cells' Web Locks (it waits 20 s for them, then fails). Resolves once the
|
|
38
|
+
* store's work under way has ended and its locks are released.
|
|
39
|
+
*/
|
|
40
|
+
close() {
|
|
41
|
+
ch.port1.close();
|
|
42
|
+
return store.close();
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=ltx-host.js.map
|