import { Collab, CollabEventsRecord, CollabID, InitToken, IParent, MetaRequest, SavedStateTree, MessageMeta, SavedStateMeta } from "../core"; /** * Base class for a collaborative object, containing * properties that are themselves [[Collab]]s. * * See [Data Modeling](https://collabs.readthedocs.io/en/latest/guide/data_modeling.html) * for a guide and examples of how to extend this class. * * Extending CObject lets you create a reusable object-oriented * unit out of one or more existing Collabs. * In particular, you can: * - Wrap existing Collabs in a domain-specific API. * - Implement a complex Collab as a composition of simple ones, * without the need to send your own messages over the network. * * To use CObject: * 1. In your constructor, register any * Collab properties using [[registerCollab]]. The registrations * must be identical across all replicas. * We call the registered properties our [[children]]. * 2. Implement your methods by calling methods * on the Collab properties; operations called this way * are collaborative as usual. * 3. You may also register event * handlers on your Collab properties that emit your * own events in response (in your constructor). * For simple CObjects, * it may be easier to instead expose Collab properties * publicly (so users can add their own event handlers) * or have users listen on [[CRuntime]]'s "Change" event. * * A CObject may have non-Collab properties, but they * are not automatically collaborative. Typically, such * properties will all be `readonly`. You can also store * functional "views" of the Collab properties' states that * update in response to events (e.g., a cached `length` * field). */ export declare class CObject extends Collab implements IParent { /** * The children (registered Collab properties), keyed by name. * * This map should only be read, not mutated. * It is exposed to subclasses as a convenience for methods * that loop over all children. */ protected readonly children: Map; /** * Registers a [[Collab]] property of this CObject * with the given name, making it one of our [[children]]. * * Typically, you will call this method during the * constructor in the style: * ```ts * this.foo = this.registerCollab("foo", (init) => new FooClass(init, constructor args...)); * ``` * where `readonly foo: FooClass;` is a Collab property. See * [Data Modeling](https://collabs.readthedocs.io/en/latest/guide/data_modeling.html) * for examples. * * Registrations must be identical across all replicas. * * See also: [[CRuntime.registerCollab]]. * * @param name A name for this property, unique among * this class's `registerCollab` calls. * We recommend using the same name as the property, * but you can also use short strings to reduce * network usage ("", "0", "1", ...). * @param collabCallback A callback that uses the * given [[InitToken]] to construct the registered [[Collab]]. * @return The registered Collab. */ protected registerCollab(name: string, collabCallback: (init: InitToken) => C): C; childSend(child: Collab, messageStack: (Uint8Array | string)[], metaRequests: MetaRequest[]): void; receive(messageStack: (Uint8Array | string)[], meta: MessageMeta): void; /** * Internal (parent) use only. * * Returns saved state describing the current state of this CObject. * See [[Collab.save]]. * * A CObject subclass may override this method to save additional state. * It is recommended to do so as follows: * ```ts * save() { * const ans = super.save(); * // Put your extra saved state in ans.self, which is otherwise unused. * ans.self = ; * return ans; * } * ``` */ save(): SavedStateTree; /** * Internal (parent) use only. * * Called by this Collab's parent to load saved state. See [[Collab.load]]. * * A CObject subclass may override this method to load additional state from * [[Collab.save]] or to perform extra setup - e.g., refreshing functional * views that were not automatically updated by children's load events. * It is recommended to do so as follows: * ```ts * load(savedStateTree: SavedStateTree | null, meta: SavedStateMeta) { * super.load(savedStateTree, meta); * // Process your extra saved state from savedStateTree.self. * const savedState = savedStateTree === null? null: savedStateTree.self!; * ... * // Perform extra setup as needed. * ... * } * ``` */ load(savedStateTree: SavedStateTree | null, meta: SavedStateMeta): void; idOf(descendant: C): CollabID; fromID(id: CollabID, startIndex?: number): C | undefined; /** * Internal (parent) use only. * * By default, this method returns true if `canGC` returns true * on every child. Override to change this behavior. * * See [[Collab.canGC]]. */ canGC(): boolean; /** * Internal (parent) use only. * * By default, this methods calls `finalize` on every child. * Override to change this behavior, * e.g., to add your own finalization steps * (but consider calling `super.finalize()`). */ finalize(): void; }