rwsdk
Version:
Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime
197 lines (196 loc) • 10.6 kB
JavaScript
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _SyncedStateServer_instances, _a, _SyncedStateServer_keyHandler, _SyncedStateServer_roomHandler, _SyncedStateServer_setStateHandler, _SyncedStateServer_getStateHandler, _SyncedStateServer_subscribeHandler, _SyncedStateServer_unsubscribeHandler, _SyncedStateServer_namespace, _SyncedStateServer_durableObjectName, _SyncedStateServer_stub, _SyncedStateServer_stateStore, _SyncedStateServer_subscriptions, _SyncedStateServer_subscriptionRefs, _SyncedStateServer_getStubForHandlers, _CoordinatorApi_coordinator, _CoordinatorApi_stub;
import { RpcTarget, newWorkersRpcResponse } from "capnweb";
import { DurableObject } from "cloudflare:workers";
/**
* Durable Object that keeps shared state for multiple clients and notifies subscribers.
*/
export class SyncedStateServer extends DurableObject {
constructor() {
super(...arguments);
_SyncedStateServer_instances.add(this);
_SyncedStateServer_stub.set(this, null);
_SyncedStateServer_stateStore.set(this, new Map());
_SyncedStateServer_subscriptions.set(this, new Map());
_SyncedStateServer_subscriptionRefs.set(this, new Map());
}
static registerKeyHandler(handler) {
__classPrivateFieldSet(_a, _a, handler, "f", _SyncedStateServer_keyHandler);
}
static getKeyHandler() {
return __classPrivateFieldGet(_a, _a, "f", _SyncedStateServer_keyHandler);
}
static registerRoomHandler(handler) {
__classPrivateFieldSet(_a, _a, handler, "f", _SyncedStateServer_roomHandler);
}
static getRoomHandler() {
return __classPrivateFieldGet(_a, _a, "f", _SyncedStateServer_roomHandler);
}
static registerNamespace(namespace, durableObjectName) {
__classPrivateFieldSet(_a, _a, namespace, "f", _SyncedStateServer_namespace);
if (durableObjectName) {
__classPrivateFieldSet(_a, _a, durableObjectName, "f", _SyncedStateServer_durableObjectName);
}
}
static getNamespace() {
return __classPrivateFieldGet(_a, _a, "f", _SyncedStateServer_namespace);
}
static getDurableObjectName() {
return __classPrivateFieldGet(_a, _a, "f", _SyncedStateServer_durableObjectName);
}
setStub(stub) {
__classPrivateFieldSet(this, _SyncedStateServer_stub, stub, "f");
}
static registerSetStateHandler(handler) {
__classPrivateFieldSet(_a, _a, handler, "f", _SyncedStateServer_setStateHandler);
}
static registerGetStateHandler(handler) {
__classPrivateFieldSet(_a, _a, handler, "f", _SyncedStateServer_getStateHandler);
}
static registerSubscribeHandler(handler) {
__classPrivateFieldSet(_a, _a, handler, "f", _SyncedStateServer_subscribeHandler);
}
static registerUnsubscribeHandler(handler) {
__classPrivateFieldSet(_a, _a, handler, "f", _SyncedStateServer_unsubscribeHandler);
}
static getSubscribeHandler() {
return __classPrivateFieldGet(_a, _a, "f", _SyncedStateServer_subscribeHandler);
}
static getUnsubscribeHandler() {
return __classPrivateFieldGet(_a, _a, "f", _SyncedStateServer_unsubscribeHandler);
}
getState(key) {
const value = __classPrivateFieldGet(this, _SyncedStateServer_stateStore, "f").get(key);
if (__classPrivateFieldGet(_a, _a, "f", _SyncedStateServer_getStateHandler)) {
const stub = __classPrivateFieldGet(this, _SyncedStateServer_instances, "m", _SyncedStateServer_getStubForHandlers).call(this);
if (stub) {
__classPrivateFieldGet(_a, _a, "f", _SyncedStateServer_getStateHandler).call(_a, key, value, stub);
}
}
return value;
}
setState(value, key) {
__classPrivateFieldGet(this, _SyncedStateServer_stateStore, "f").set(key, value);
if (__classPrivateFieldGet(_a, _a, "f", _SyncedStateServer_setStateHandler)) {
const stub = __classPrivateFieldGet(this, _SyncedStateServer_instances, "m", _SyncedStateServer_getStubForHandlers).call(this);
if (stub) {
__classPrivateFieldGet(_a, _a, "f", _SyncedStateServer_setStateHandler).call(_a, key, value, stub);
}
}
const subscribers = __classPrivateFieldGet(this, _SyncedStateServer_subscriptions, "f").get(key);
if (!subscribers) {
return;
}
for (const subscriber of subscribers) {
subscriber(value).catch(() => {
subscribers.delete(subscriber);
const refs = __classPrivateFieldGet(this, _SyncedStateServer_subscriptionRefs, "f").get(key);
if (refs) {
for (const [original, duplicate] of refs) {
if (duplicate === subscriber) {
refs.delete(original);
break;
}
}
if (refs.size === 0) {
__classPrivateFieldGet(this, _SyncedStateServer_subscriptionRefs, "f").delete(key);
}
}
});
}
if (subscribers.size === 0) {
__classPrivateFieldGet(this, _SyncedStateServer_subscriptions, "f").delete(key);
}
}
subscribe(key, client) {
if (!__classPrivateFieldGet(this, _SyncedStateServer_subscriptions, "f").has(key)) {
__classPrivateFieldGet(this, _SyncedStateServer_subscriptions, "f").set(key, new Set());
}
if (!__classPrivateFieldGet(this, _SyncedStateServer_subscriptionRefs, "f").has(key)) {
__classPrivateFieldGet(this, _SyncedStateServer_subscriptionRefs, "f").set(key, new Map());
}
const duplicate = typeof client.dup === "function"
? client.dup()
: client;
__classPrivateFieldGet(this, _SyncedStateServer_subscriptions, "f").get(key).add(duplicate);
__classPrivateFieldGet(this, _SyncedStateServer_subscriptionRefs, "f").get(key).set(client, duplicate);
}
unsubscribe(key, client) {
const duplicates = __classPrivateFieldGet(this, _SyncedStateServer_subscriptionRefs, "f").get(key);
const duplicate = duplicates?.get(client);
const subscribers = __classPrivateFieldGet(this, _SyncedStateServer_subscriptions, "f").get(key);
if (duplicate && subscribers) {
subscribers.delete(duplicate);
duplicates.delete(client);
if (subscribers.size === 0) {
__classPrivateFieldGet(this, _SyncedStateServer_subscriptions, "f").delete(key);
}
if (duplicates.size === 0) {
__classPrivateFieldGet(this, _SyncedStateServer_subscriptionRefs, "f").delete(key);
}
}
}
async fetch(request) {
// Create a placeholder stub - it will be set by the worker via _setStub
const api = new CoordinatorApi(this, __classPrivateFieldGet(this, _SyncedStateServer_stub, "f") || {});
return newWorkersRpcResponse(request, api);
}
}
_a = SyncedStateServer, _SyncedStateServer_stub = new WeakMap(), _SyncedStateServer_stateStore = new WeakMap(), _SyncedStateServer_subscriptions = new WeakMap(), _SyncedStateServer_subscriptionRefs = new WeakMap(), _SyncedStateServer_instances = new WeakSet(), _SyncedStateServer_getStubForHandlers = function _SyncedStateServer_getStubForHandlers() {
// If we have a stub already, use it
if (__classPrivateFieldGet(this, _SyncedStateServer_stub, "f")) {
return __classPrivateFieldGet(this, _SyncedStateServer_stub, "f");
}
// Otherwise, try to get a stub from the registered namespace using our own ID
const namespace = __classPrivateFieldGet(_a, _a, "f", _SyncedStateServer_namespace);
if (namespace) {
return namespace.get(this.ctx.id);
}
return null;
};
_SyncedStateServer_keyHandler = { value: null };
_SyncedStateServer_roomHandler = { value: null };
_SyncedStateServer_setStateHandler = { value: null };
_SyncedStateServer_getStateHandler = { value: null };
_SyncedStateServer_subscribeHandler = { value: null };
_SyncedStateServer_unsubscribeHandler = { value: null };
_SyncedStateServer_namespace = { value: null };
_SyncedStateServer_durableObjectName = { value: "syncedState" };
class CoordinatorApi extends RpcTarget {
constructor(coordinator, stub) {
super();
_CoordinatorApi_coordinator.set(this, void 0);
_CoordinatorApi_stub.set(this, void 0);
__classPrivateFieldSet(this, _CoordinatorApi_coordinator, coordinator, "f");
__classPrivateFieldSet(this, _CoordinatorApi_stub, stub, "f");
coordinator.setStub(stub);
}
// Internal method to set the stub - called from worker
_setStub(stub) {
__classPrivateFieldSet(this, _CoordinatorApi_stub, stub, "f");
__classPrivateFieldGet(this, _CoordinatorApi_coordinator, "f").setStub(stub);
}
getState(key) {
return __classPrivateFieldGet(this, _CoordinatorApi_coordinator, "f").getState(key);
}
setState(value, key) {
__classPrivateFieldGet(this, _CoordinatorApi_coordinator, "f").setState(value, key);
}
subscribe(key, client) {
__classPrivateFieldGet(this, _CoordinatorApi_coordinator, "f").subscribe(key, client);
}
unsubscribe(key, client) {
__classPrivateFieldGet(this, _CoordinatorApi_coordinator, "f").unsubscribe(key, client);
}
}
_CoordinatorApi_coordinator = new WeakMap(), _CoordinatorApi_stub = new WeakMap();