import type BaseClient from 'common/lib/client/baseclient'; import type { AnyBatchContext, BatchContext, CompactedJsonValue, CompactedValue, Instance, Primitive, Value, } from '../../../liveobjects'; import { DefaultInstance } from './instance'; import { LiveCounter } from './livecounter'; import { LiveMap } from './livemap'; import { RealtimeObject } from './realtimeobject'; import { RootBatchContext } from './rootbatchcontext'; export class DefaultBatchContext implements AnyBatchContext { protected _client: BaseClient; constructor( protected _realtimeObject: RealtimeObject, protected _instance: Instance, protected _rootContext: RootBatchContext, ) { this._client = this._realtimeObject.getClient(); } get id(): string | undefined { this._throwIfClosed(); return this._instance.id; } get(key: string): BatchContext | undefined { this._realtimeObject.throwIfInvalidAccessApiConfiguration(); this._throwIfClosed(); const instance = this._instance.get(key); if (!instance) { return undefined; } return this._rootContext.wrapInstance(instance) as unknown as BatchContext; } value(): T | undefined { this._realtimeObject.throwIfInvalidAccessApiConfiguration(); this._throwIfClosed(); return this._instance.value(); } compact(): CompactedValue | undefined { this._realtimeObject.throwIfInvalidAccessApiConfiguration(); this._throwIfClosed(); return this._instance.compact(); } compactJson(): CompactedJsonValue | undefined { this._realtimeObject.throwIfInvalidAccessApiConfiguration(); this._throwIfClosed(); return this._instance.compactJson(); } *entries>(): IterableIterator<[keyof T, BatchContext]> { this._realtimeObject.throwIfInvalidAccessApiConfiguration(); this._throwIfClosed(); for (const [key, value] of this._instance.entries()) { const ctx = this._rootContext.wrapInstance(value) as unknown as BatchContext; yield [key, ctx]; } } *keys>(): IterableIterator { this._realtimeObject.throwIfInvalidAccessApiConfiguration(); this._throwIfClosed(); yield* this._instance.keys(); } *values>(): IterableIterator> { this._realtimeObject.throwIfInvalidAccessApiConfiguration(); this._throwIfClosed(); for (const [_, value] of this.entries()) { yield value; } } size(): number | undefined { this._realtimeObject.throwIfInvalidAccessApiConfiguration(); this._throwIfClosed(); return this._instance.size(); } set(key: string, value: Value): void { this._realtimeObject.throwIfInvalidWriteApiConfiguration(); this._throwIfClosed(); if (!(this._instance as DefaultInstance).isLiveMap()) { throw new this._client.ErrorInfo('Cannot set a key on a non-LiveMap instance', 92007, 400); } this._rootContext.queueMessages(async () => LiveMap.createMapSetMessage(this._realtimeObject, this._instance.id!, key, value), ); } remove(key: string): void { this._realtimeObject.throwIfInvalidWriteApiConfiguration(); this._throwIfClosed(); if (!(this._instance as DefaultInstance).isLiveMap()) { throw new this._client.ErrorInfo('Cannot remove a key from a non-LiveMap instance', 92007, 400); } this._rootContext.queueMessages(async () => [ LiveMap.createMapRemoveMessage(this._realtimeObject, this._instance.id!, key), ]); } increment(amount?: number): void { this._realtimeObject.throwIfInvalidWriteApiConfiguration(); this._throwIfClosed(); if (!(this._instance as DefaultInstance).isLiveCounter()) { throw new this._client.ErrorInfo('Cannot increment a non-LiveCounter instance', 92007, 400); } this._rootContext.queueMessages(async () => [ LiveCounter.createCounterIncMessage(this._realtimeObject, this._instance.id!, amount ?? 1), ]); } decrement(amount?: number): void { this._realtimeObject.throwIfInvalidWriteApiConfiguration(); this._throwIfClosed(); if (!(this._instance as DefaultInstance).isLiveCounter()) { throw new this._client.ErrorInfo('Cannot decrement a non-LiveCounter instance', 92007, 400); } this.increment(-(amount ?? 1)); } private _throwIfClosed(): void { if (this._rootContext.isClosed()) { throw new this._client.ErrorInfo('Batch is closed', 40000, 400); } } }