Skip to content

Commit

Permalink
Move types required for user-provided LiveObjects typings to ably.d.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
VeskeR committed Nov 22, 2024
1 parent d5d12e7 commit ad2d457
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 31 deletions.
25 changes: 22 additions & 3 deletions ably.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2029,13 +2029,32 @@ export declare interface PushChannel {
* Enables the LiveObjects state to be subscribed to for a channel.
*/
export declare interface LiveObjects {
getRoot(): Promise<LiveMap>;
getRoot<T extends LiveMapType = DefaultRoot>(): Promise<LiveMap<T>>;
}

// TODO: document public API for LiveObjects

export declare interface LiveMap extends LiveObject<LiveMapUpdate> {
get(key: string): LiveObject | StateValue | undefined;
declare global {
// a global interface which can be used by users to define their own types for LiveObjects.
export interface LiveObjectsTypes {
[key: string]: unknown;
}
}

// LiveMap type representation of how it looks to the user. A mapping of string keys to scalar values (StateValue) or other Live Objects.
export type LiveMapType = { [key: string]: StateValue | LiveMap<LiveMapType> | LiveCounter | undefined };

export type DefaultRoot =
// we need a way to know when no types were provided by the user.
// we expect a "root" property to be set on LiveObjectsTypes interface, e.g. it won't be "unknown" anymore
unknown extends LiveObjectsTypes['root']
? LiveMapType // no types provided by the user, use the default map type for the root
: LiveObjectsTypes['root'] extends LiveMapType
? LiveObjectsTypes['root'] // "root" was provided by the user, and it is of an expected type, we can use this interface for the root object in LiveObjects.
: `Provided type definition for the "root" object in LiveObjectsTypes is not of an expected LiveMapType type`;

export declare interface LiveMap<T extends LiveMapType> extends LiveObject<LiveMapUpdate> {
get<TKey extends keyof T & string>(key: TKey): T[TKey];
size(): number;
}

Expand Down
8 changes: 4 additions & 4 deletions src/plugins/liveobjects/livemap.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import deepEqual from 'deep-equal';

import type * as API from '../../../ably';
import { LiveObject, LiveObjectData, LiveObjectUpdate, LiveObjectUpdateNoop } from './liveobject';
import { LiveObjects } from './liveobjects';
import {
Expand All @@ -13,7 +14,6 @@ import {
StateValue,
} from './statemessage';
import { DefaultTimeserial, Timeserial } from './timeserial';
import { LiveMapType } from './typings';

export interface ObjectIdStateData {
/** A reference to another state object, used to support composable state objects. */
Expand Down Expand Up @@ -46,7 +46,7 @@ export interface LiveMapUpdate extends LiveObjectUpdate {
update: { [keyName: string]: 'updated' | 'removed' };
}

export class LiveMap<T extends LiveMapType> extends LiveObject<LiveMapData, LiveMapUpdate> {
export class LiveMap<T extends API.LiveMapType> extends LiveObject<LiveMapData, LiveMapUpdate> {
constructor(
liveObjects: LiveObjects,
private _semantics: MapSemantics,
Expand All @@ -60,7 +60,7 @@ export class LiveMap<T extends LiveMapType> extends LiveObject<LiveMapData, Live
*
* @internal
*/
static zeroValue<T extends LiveMapType>(liveobjects: LiveObjects, objectId: string): LiveMap<T> {
static zeroValue<T extends API.LiveMapType>(liveobjects: LiveObjects, objectId: string): LiveMap<T> {
return new LiveMap(liveobjects, MapSemantics.LWW, objectId);
}

Expand All @@ -70,7 +70,7 @@ export class LiveMap<T extends LiveMapType> extends LiveObject<LiveMapData, Live
*
* @internal
*/
static fromStateObject<T extends LiveMapType>(liveobjects: LiveObjects, stateObject: StateObject): LiveMap<T> {
static fromStateObject<T extends API.LiveMapType>(liveobjects: LiveObjects, stateObject: StateObject): LiveMap<T> {
const obj = new LiveMap<T>(liveobjects, stateObject.map?.semantics!, stateObject.objectId);
obj.overrideWithStateObject(stateObject);
return obj;
Expand Down
3 changes: 1 addition & 2 deletions src/plugins/liveobjects/liveobjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { LiveObject, LiveObjectUpdate } from './liveobject';
import { LiveObjectsPool, ROOT_OBJECT_ID } from './liveobjectspool';
import { StateMessage } from './statemessage';
import { SyncLiveObjectsDataPool } from './syncliveobjectsdatapool';
import { DefaultRoot, LiveMapType } from './typings';

enum LiveObjectsEvents {
SyncCompleted = 'SyncCompleted',
Expand Down Expand Up @@ -42,7 +41,7 @@ export class LiveObjects {
* A user can provide an explicit type for the getRoot method to explicitly set the LiveObjects type structure on this particular channel.
* This is useful when working with LiveObjects on multiple channels with different underlying data.
*/
async getRoot<T extends LiveMapType = DefaultRoot>(): Promise<LiveMap<T>> {
async getRoot<T extends API.LiveMapType = API.DefaultRoot>(): Promise<LiveMap<T>> {
// SYNC is currently in progress, wait for SYNC sequence to finish
if (this._syncInProgress) {
await this._eventEmitter.once(LiveObjectsEvents.SyncCompleted);
Expand Down
22 changes: 0 additions & 22 deletions src/plugins/liveobjects/typings.ts

This file was deleted.

0 comments on commit ad2d457

Please sign in to comment.