/*! * Copyright (c) Microsoft Corporation and contributors. All rights reserved. * Licensed under the MIT License. */ import type { FluidIterableIterator, FluidMap, IDisposable, IEvent, IEventProvider, IEventThisPlaceHolder, } from "@fluidframework/core-interfaces"; import type { ISharedObject, ISharedObjectEvents, } from "@fluidframework/shared-object-base/internal"; /** * Type of "valueChanged" event parameter. * @sealed * @legacy * @public */ export interface IValueChanged { /** * The key storing the value that changed. */ readonly key: string; /** * The value that was stored at the key prior to the change. */ // TODO: Use `unknown` instead (breaking change). // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly previousValue: any; } /** * Interface describing actions on a directory. * * @remarks When used as a Map, operates on its keys. * @sealed * @legacy * @public */ export interface IDirectory // TODO: Use `unknown` instead (breaking change). // eslint-disable-next-line @typescript-eslint/no-explicit-any extends FluidMap, IEventProvider, Partial { /** * The absolute path of the directory. */ readonly absolutePath: string; /** * Retrieves the value stored at the given key from the directory. * @param key - Key to retrieve from * @returns The stored value, or undefined if the key is not set */ // TODO: Use `unknown` instead (breaking change). // eslint-disable-next-line @typescript-eslint/no-explicit-any get(key: string): T | undefined; /** * Sets the value stored at key to the provided value. * @param key - Key to set at * @param value - Value to set * @returns The IDirectory itself */ set(key: string, value: T): this; /** * Removes all entries from the directory. */ clear(): void; /** * Removes the specified element from this directory by its key. * @param key - The key of the element to remove * @returns `true` if an element existed and has been removed, or `false` if the element does not exist */ delete(key: string): boolean; /** * Get the number of sub directory within the directory. * @returns The number of sub directory within a directory. */ countSubDirectory?(): number; /** * Creates an IDirectory child of this IDirectory, or retrieves the existing IDirectory child if one with the * same name already exists. * @param subdirName - Name of the new child directory to create * @returns The IDirectory child that was created or retrieved */ createSubDirectory(subdirName: string): IDirectory; /** * Gets an IDirectory child of this IDirectory, if it exists. * @param subdirName - Name of the child directory to get * @returns The requested IDirectory */ getSubDirectory(subdirName: string): IDirectory | undefined; /** * Checks whether this directory has a child directory with the given name. * @param subdirName - Name of the child directory to check * @returns True if it exists, false otherwise */ hasSubDirectory(subdirName: string): boolean; /** * Deletes an IDirectory child of this IDirectory, if it exists, along with all descendent keys and directories. * @param subdirName - Name of the child directory to delete * @returns True if the IDirectory existed and was deleted, false if it did not exist */ deleteSubDirectory(subdirName: string): boolean; /** * Gets an iterator over the IDirectory children of this IDirectory. * @returns The IDirectory iterator */ subdirectories(): FluidIterableIterator<[string, IDirectory]>; /** * Get an IDirectory within the directory, in order to use relative paths from that location. * @param relativePath - Path of the IDirectory to get, relative to this IDirectory * @returns The requested IDirectory */ getWorkingDirectory(relativePath: string): IDirectory | undefined; } /** * Legacy map-like API that extends FluidMap, without the `get` and `set` methods supplied by legacy map interfaces. * * @sealed * @legacy @beta */ export interface FluidMapLegacy extends Omit, "get" | "set" | "forEach"> { /** * Removes all entries from the map. */ clear(): void; /** * Executes the provided function once per each key/value pair in the map. */ forEach( callbackfn: (value: V, key: K, map: FluidMap) => void, // Typing inherited from FluidMap. // eslint-disable-next-line @typescript-eslint/no-explicit-any thisArg?: any, ): void; /** * Executes the provided function once per each key/value pair in the map. */ forEach( callbackfn: (value: V, key: K, map: Map) => void, // Typing inherited from Map. // eslint-disable-next-line @typescript-eslint/no-explicit-any thisArg?: any, ): void; /** * Removes the specified element from the map by its key. * * @returns `true` if an element existed and has been removed, or `false` if the element does not exist. */ delete(key: K): boolean; } /** * Events emitted in response to changes to the directory data. * * @remarks * These events only emit on the {@link ISharedDirectory} itself, and not on subdirectories. * @sealed * @legacy @beta */ export interface ISharedDirectoryEvents extends ISharedObjectEvents { /** * Emitted when a key is set or deleted. This is emitted for any key in the {@link ISharedDirectory} or any * subdirectory. * * @remarks Listener parameters: * * - `changed` - Information on the key that changed, its value prior to the change, and the path to the * key that changed. * * - `local` - Whether the change originated from this client. * * - `target` - The {@link ISharedDirectory} itself. */ ( event: "valueChanged", listener: ( changed: IDirectoryValueChanged, local: boolean, target: IEventThisPlaceHolder, ) => void, ); /** * Emitted when the {@link ISharedDirectory} is cleared. * * @deprecated Use the "cleared" event instead which provides the path that was cleared. * * @remarks Listener parameters: * * - `local` - Whether the clear originated from this client. * * - `target` - The {@link ISharedDirectory} itself. */ (event: "clear", listener: (local: boolean, target: IEventThisPlaceHolder) => void); /** * Emitted when the {@link ISharedDirectory} is cleared. * * @remarks Listener parameters: * * - `path` - The absolute path to the directory that was cleared. * * - `local` - Whether the clear originated from this client. * * - `target` - The {@link ISharedDirectory} itself. */ ( event: "cleared", listener: (path: string, local: boolean, target: IEventThisPlaceHolder) => void, ); /** * Emitted when a subdirectory is created. * * @remarks Listener parameters: * * - `path` - The relative path to the subdirectory that is created. * It is relative from the object which raises the event. * * - `local` - Whether the create originated from the this client. * * - `target` - The {@link ISharedDirectory} itself. */ ( event: "subDirectoryCreated", listener: (path: string, local: boolean, target: IEventThisPlaceHolder) => void, ); /** * Emitted when a subdirectory is deleted. * * @remarks Listener parameters: * * - `path` - The relative path to the subdirectory that is deleted. * It is relative from the object which raises the event. * * - `local` - Whether the delete originated from the this client. * * - `target` - The {@link ISharedDirectory} itself. */ ( event: "subDirectoryDeleted", listener: (path: string, local: boolean, target: IEventThisPlaceHolder) => void, ); } /** * Events emitted in response to changes to the directory data. * @sealed * @legacy * @public */ export interface IDirectoryEvents extends IEvent { /** * Emitted when a key is set or deleted. As opposed to the * {@link ISharedDirectory}'s valueChanged event, this is emitted only on the {@link IDirectory} that directly * contains the key. * * @remarks Listener parameters: * * - `changed` - Information on the key that changed and its value prior to the change. * * - `local` - Whether the change originated from this client. * * - `target` - The {@link IDirectory} itself. */ ( event: "containedValueChanged", listener: (changed: IValueChanged, local: boolean, target: IEventThisPlaceHolder) => void, ); /** * Emitted when a subdirectory is created. Also emitted when a delete * of a subdirectory is rolled back. * * @remarks Listener parameters: * * - `path` - The relative path to the subdirectory that is created. * It is relative from the object which raises the event. * * - `local` - Whether the creation originated from the this client. * * - `target` - The {@link ISharedDirectory} itself. */ ( event: "subDirectoryCreated", listener: (path: string, local: boolean, target: IEventThisPlaceHolder) => void, ); /** * Emitted when a subdirectory is deleted. * * @remarks Listener parameters: * * - `path` - The relative path to the subdirectory that is deleted. * It is relative from the object which raises the event. * * - `local` - Whether the delete originated from the this client. * * - `target` - The {@link ISharedDirectory} itself. */ ( event: "subDirectoryDeleted", listener: (path: string, local: boolean, target: IEventThisPlaceHolder) => void, ); /** * Emitted when this sub directory is deleted. * * @remarks Listener parameters: * * - `target` - The {@link IDirectory} itself. */ (event: "disposed", listener: (target: IEventThisPlaceHolder) => void); /** * Emitted when this previously deleted sub directory is restored. * This event only needs to be handled in the case of rollback. If your application does * not use the local rollback feature, you can ignore this event. * * @remarks Listener parameters: * * - `target` - The {@link IDirectory} itself. */ (event: "undisposed", listener: (target: IEventThisPlaceHolder) => void); } /** * Provides a hierarchical organization of map-like data structures as SubDirectories. * The values stored within can be accessed like a map, and the hierarchy can be navigated using path syntax. * SubDirectories can be retrieved for use as working directories. * @sealed * @legacy @beta */ export interface ISharedDirectory extends ISharedObject, Omit { // The Omit type excludes symbols, which we don't want to exclude. Adding them back here manually. // https://github.com/microsoft/TypeScript/issues/31671 // TODO: Use `unknown` instead (breaking change). // eslint-disable-next-line @typescript-eslint/no-explicit-any [Symbol.iterator](): FluidIterableIterator<[string, any]>; readonly [Symbol.toStringTag]: string; } /** * Type of "valueChanged" event parameter for {@link ISharedDirectory}. * @sealed * @legacy * @public */ export interface IDirectoryValueChanged extends IValueChanged { /** * The absolute path to the IDirectory storing the key which changed. * @readonly * @privateRemarks * When breaking changes can be made, `readonly` should be added. */ path: string; } /** * Events emitted in response to changes to the {@link ISharedMap | map} data. * @sealed * @legacy @beta */ export interface ISharedMapEvents extends ISharedObjectEvents { /** * Emitted when a key is set or deleted. * * @remarks Listener parameters: * * - `changed` - Information on the key that changed and its value prior to the change. * * - `local` - Whether the change originated from this client. * * - `target` - The {@link ISharedMap} itself. */ ( event: "valueChanged", listener: (changed: IValueChanged, local: boolean, target: IEventThisPlaceHolder) => void, ); /** * Emitted when the map is cleared. * * @remarks Listener parameters: * * - `local` - Whether the clear originated from this client. * * - `target` - The {@link ISharedMap} itself. */ (event: "clear", listener: (local: boolean, target: IEventThisPlaceHolder) => void); } /** * The SharedMap distributed data structure can be used to store key-value pairs. * * @remarks * SharedMap provides the same API for setting and retrieving values that JavaScript developers are accustomed to with the * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map | Map} built-in object. * However, the keys of a SharedMap must be strings, and the values must either be a JSON-serializable object or a * {@link @fluidframework/datastore#FluidObjectHandle}. * * Note: unlike JavaScript maps, SharedMap does not make any guarantees regarding enumeration order. * * For more information, including example usages, see {@link https://fluidframework.com/docs/data-structures/map/}. * @sealed * @legacy @beta */ export interface ISharedMap extends ISharedObject, // TODO: Use `unknown` instead (breaking change). // eslint-disable-next-line @typescript-eslint/no-explicit-any FluidMap { /** * Retrieves the given key from the map if it exists. * @param key - Key to retrieve from * @returns The stored value, or undefined if the key is not set */ // TODO: Use `unknown` instead (breaking change). // eslint-disable-next-line @typescript-eslint/no-explicit-any get(key: string): T | undefined; /** * Sets the value stored at key to the provided value. * @param key - Key to set * @param value - Value to set * @returns The {@link ISharedMap} itself */ set(key: string, value: T): this; /** * Removes all entries from the map. */ clear(): void; /** * Removes the specified element from this map by its key. * @param key - The key of the element to remove * @returns `true` if an element existed and has been removed, or `false` if the element does not exist */ delete(key: string): boolean; } /** * Beta version of {@link ISharedMap} which uses {@link FluidMapLegacy} for its map-like API. * * @sealed * @legacy @beta */ export interface ISharedMapBeta extends Omit, "get" | "set">>, // eslint-disable-next-line @typescript-eslint/no-explicit-any FluidMapLegacy {}