Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | 28x 28x 28x | import { DurableObjectBinding } from '@/core/bindings/DurableObjectBinding'
import type { CoordinationStore } from '@bayudwiyansatria/core'
import type { CloudflareEnv } from '@/types/CloudflareEnv'
/**
* Durable Object namespace binding.
*
* Every setting it needs — binding name and location hint — arrives resolved
* from the configuration layer, so nothing about them is decided here. The
* binding itself is read from `env` per call, which is what makes one
* module-scope instance safe to share.
*/
const objects = new DurableObjectBinding()
/**
* Coordination capability, backed by Durable Objects.
*
* @remarks
* A name maps to exactly one object, so concurrent requests for the same name
* queue behind each other instead of racing — that is the whole point of
* reaching for this rather than KV or D1.
*
* Requests reach an object through its stub's `fetch`, so the URLs below are
* addressed to the object, not to the internet. The object class itself must
* be exported from the Worker entry and declared as a migration in
* `wrangler.json`.
*
* @class
*
* @author Bayu Dwiyan Satria
* @version 1.0.0
* @since 1.0.0
*/
export class DurableObjectService<E extends CloudflareEnv = CloudflareEnv> implements CoordinationStore<E> {
/**
* Calls the object that owns a name and parses its JSON reply.
*
* @param env The Worker environment.
* @param name The name identifying the object — a room, a tenant, a session.
* @param path Path on the object, e.g. `/increment`.
* @param init Request options, such as `{ method: 'POST' }`.
* @returns The object's parsed response.
* @throws Error When the object replies with a non-OK status.
*/
public async call<T = unknown>(env: E, name: string, path: string, init: RequestInit = {}): Promise<T> {
const stub = objects.stubByName(env, name)
const response = await stub.fetch(`https://durable-object${path}`, init)
if (!response.ok) {
throw new Error(`Durable Object '${name}' replied ${response.status} to ${path}`)
}
return (await response.json()) as T
}
/**
* Creates a fresh object and returns the id needed to reach it again.
*
* Use this when the caller — not a name — owns the identity: a new session,
* a new game, a new upload.
*
* @param env The Worker environment.
* @returns The new object's id, as a string.
*/
public create(env: E): string {
return objects.stubForNewId(env).id.toString()
}
/**
* Reports whether the namespace is bound to this Worker.
*
* @param env The Worker environment.
* @returns `true` when the binding is present.
*/
public isAvailable(env: E): boolean {
return objects.isBound(env)
}
}
|