/*! * Copyright (c) Microsoft Corporation and contributors. All rights reserved. * Licensed under the MIT License. */ import type { FluidIterableIterator, Listenable } from "@fluidframework/core-interfaces"; import type { DeepReadonly, JsonDeserialized, JsonSerializable } from "@fluidframework/core-interfaces/internal/exposedUtilityTypes"; import type { BroadcastControls, BroadcastControlSettings } from "./broadcastControlsTypes.js"; import type { InternalTypes } from "./exposedInternalTypes.js"; import type { LatestClientData, LatestData, LatestMetadata, ProxiedValueAccessor, RawValueAccessor, StateSchemaValidator, ValueAccessor } from "./latestValueTypes.js"; import type { Attendee, AttendeeId, Presence } from "./presence.js"; /** * A validator function that can optionally be provided to do runtime validation * of the custom key listed in a {@link LatestMap}. * * @param unvalidatedKey - The unknown key that should be validated. * * @returns True if the key is valid. * * @public */ export type KeySchemaValidator = (unvalidatedKey: string) => unvalidatedKey is Keys; /** * Collection of latest known values for a specific {@link Attendee}. * * @sealed * @public */ export interface LatestMapClientData, SpecificAttendeeId extends AttendeeId = AttendeeId> { /** * Associated {@link Attendee}. */ attendee: Attendee; /** * Map of items for the state. * * @privateRemarks This could be regular map currently as no Map is * stored internally and a new instance is created for every request. */ items: ReadonlyMap>; } /** * State of a single item value, its key, and its metadata. * * @sealed * @public */ export interface LatestMapItemUpdatedClientData> extends LatestClientData { /** * Key of the updated item. */ key: K; } /** * Identifier and metadata for a removed item. * * @sealed * @public */ export interface LatestMapItemRemovedClientData { /** * Associated {@link Attendee}. */ attendee: Attendee; /** * Key of the removed item. */ key: K; /** * Metadata associated with the removal of the item. */ metadata: LatestMetadata; } /** * Events from {@link LatestMapRaw}. * * @sealed * @public */ export interface LatestMapEvents = ProxiedValueAccessor> { /** * Raised when any item's value for remote client is updated. * @param updates - Map of one or more values updated. * * @remarks The event does not include item removals. * * @eventProperty */ remoteUpdated: (updates: LatestMapClientData) => void; /** * Raised when specific item's value of remote client is updated. * @param updatedItem - Updated item value. * * @eventProperty */ remoteItemUpdated: (updatedItem: LatestMapItemUpdatedClientData) => void; /** * Raised when specific item of remote client is removed. * @param removedItem - Removed item. * * @eventProperty */ remoteItemRemoved: (removedItem: LatestMapItemRemovedClientData) => void; /** * Raised when specific local item's value is updated. * @param updatedItem - Updated item value. * * @eventProperty */ localItemUpdated: (updatedItem: { value: DeepReadonly>; key: K; }) => void; /** * Raised when specific local item is removed. * @param removedItem - Removed item. * * @eventProperty */ localItemRemoved: (removedItem: { key: K; }) => void; } /** * Events from {@link LatestMapRaw}. * * @sealed * @public */ export type LatestMapRawEvents = LatestMapEvents>; /** * Map of local client's values. Modifications are transmitted to all other connected clients. * * @sealed * @public */ export interface StateMap { /** * ${@link StateMap.delete}s all elements in the StateMap. * @remarks This is not yet implemented. */ clear(): void; /** * Removes the element with the specified key from the StateMap, if it exists. * * @returns true if an element in the StateMap existed and has been removed, or false if * the element does not exist. * @remarks No entry is fully removed. Instead an undefined placeholder is locally and * transmitted to all other clients. For better performance limit the number of deleted * entries and reuse keys when possible. * @privateRemarks In the future we may add a mechanism to remove the placeholder, at least * from transmissions after sufficient time has passed. */ delete(key: K): boolean; /** * Executes a provided function once per each key/value pair in the StateMap, in arbitrary order. */ forEach(callbackfn: (value: DeepReadonly>, key: K, map: StateMap) => void, thisArg?: unknown): void; /** * Returns the element with the specified key from the StateMap, if it exists. * * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned. */ get(key: K): DeepReadonly> | undefined; /** * Checks if an element with the specified key exists in the StateMap. * @returns boolean indicating whether an element with the specified key exists or not. */ has(key: K): boolean; /** * Adds a new element with a specified key and value to the StateMap. If an element with the same key already exists, the element will be updated. * The value will be transmitted to all other connected clients. * * @remarks Manager assumes ownership of the value and its references. * Make a deep clone before setting, if needed. No comparison is done to detect changes; all * sets are transmitted. */ set(key: K, value: JsonSerializable): this; /** * The number of elements in the StateMap. */ readonly size: number; /** * Returns an iterable of entries in the map. */ /** * Returns an iterable of key, value pairs for every entry in the map. */ /** * Returns an iterable of keys in the map. */ keys(): FluidIterableIterator; } /** * State that provides a `Map` of latest known values from this client to * others and read access to their values. * Entries in the map may vary over time and by client, but all values are expected to * be of the same type, which may be a union type. * * @remarks Create using {@link @fluidframework/presence#StateFactory.latestMap} registered to {@link StatesWorkspace}. * * @sealed * @public */ export interface LatestMap = ProxiedValueAccessor> { /** * Containing {@link Presence} */ readonly presence: Presence; /** * Events for LatestMap. */ readonly events: Listenable>; /** * Controls for management of sending updates. */ readonly controls: BroadcastControls; /** * Current value map for this client. */ readonly local: StateMap; /** * Iterable access to remote clients' map of values. */ getRemotes(): IterableIterator>; /** * Array of {@link Attendee}s that have provided states. */ getStateAttendees(): Attendee[]; /** * Access to a specific client's map of values. */ getRemote(attendee: Attendee): ReadonlyMap>; } /** * State that provides a `Map` of latest known values from this client to * others and read access to their values. * Entries in the map may vary over time and by client, but all values are expected to * be of the same type, which may be a union type. * * @remarks Create using {@link @fluidframework/presence#StateFactory.latestMap} registered to {@link StatesWorkspace}. * * @sealed * @public */ export type LatestMapRaw = LatestMap>; /** * Arguments that are passed to the {@link @fluidframework/presence#StateFactory|StateFactory}.{@link LatestMapFactory|latestMap} function. * * @input * @public */ export interface LatestMapArgumentsRaw { /** * The initial value of the local state. */ local?: { [K in Keys]: JsonSerializable; }; /** * See {@link BroadcastControlSettings}. */ settings?: BroadcastControlSettings | undefined; } /** * Arguments that are passed to the {@link @fluidframework/presence#StateFactory|StateFactory}.{@link LatestMapFactory|latestMap} function. * * @input * @public */ export interface LatestMapArguments extends LatestMapArgumentsRaw { /** * An optional function that will be called at runtime to validate data value * under a key. A runtime validator is strongly recommended. * @see {@link StateSchemaValidator}. */ validator: StateSchemaValidator; /** * An optional function that will be called at runtime to validate the presence * data key. A runtime validator is strongly recommended when key type is not * simply `string`. * @see {@link KeySchemaValidator}. */ keyValidator?: KeySchemaValidator; } /** * Type alias for the return type of {@link LatestMapFactory} when called with * {@link LatestMapArguments}. * * @remarks * Use this type instead of any InternalPresenceTypes that may be revealed from * examining factory return type. * * @typeparam RegistrationKeyRestrictions - Optional type parameter to constrain * allowed registration keys for this State object within a workspace. * Specification is recommended to highlight connection between schema and * factory when spread across modules. * * @public * @sealed */ export type LatestMapConfiguration = InternalTypes.ManagerFactory, LatestMap>; /** * Type alias for the return type of {@link LatestMapFactory} when called with * {@link LatestMapArgumentsRaw}. * * @remarks * Use this type instead of any InternalPresenceTypes that may be revealed from * examining factory return type. * * @typeparam RegistrationKeyRestrictions - Optional type parameter to constrain * allowed registration keys for this State object within a workspace. * Specification is recommended to highlight connection between schema and * factory when spread across modules. * * @public * @sealed */ export type LatestMapRawConfiguration = InternalTypes.ManagerFactory, LatestMapRaw>; /** * Factory for creating a {@link LatestMap} or {@link LatestMapRaw} State object. * * @public * @sealed */ export interface LatestMapFactory { /** * Factory for creating a {@link LatestMap} State object. * * @remarks * This overload is used when called with {@link LatestMapArguments}. * That is, if a validator function is provided. */ (args: LatestMapArguments): LatestMapConfiguration; /** * Factory for creating a {@link LatestMapRaw} State object. * * @remarks * This overload is used when called with {@link LatestMapArgumentsRaw}. * That is, if a validator function is _not_ provided. */ (args?: LatestMapArgumentsRaw): LatestMapRawConfiguration; } //# sourceMappingURL=latestMapTypes.d.ts.map