or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

events.mdindex.mdlegacy-factories.mdshared-directory.mdshared-map.md
tile.json

shared-map.mddocs/

SharedMap Operations

SharedMap provides a distributed key-value data structure with a JavaScript Map-compatible API. It automatically synchronizes changes across multiple clients using last-write-wins conflict resolution.

Capabilities

Creating SharedMap

Creates a new SharedMap instance for collaborative key-value storage.

/**
 * Creates a new SharedMap instance
 * @param runtime - Fluid data store runtime
 * @param id - Optional unique identifier for the map
 * @returns SharedMap instance
 */
const SharedMap: ISharedObjectKind<ISharedMap>;

interface ISharedObjectKind<T> {
  create(runtime: IFluidDataStoreRuntime, id?: string): T;
  getFactory(): IChannelFactory;
}

Usage Example:

import { SharedMap } from "@fluidframework/map";

// Create a new shared map
const userPreferences = SharedMap.create(runtime, "user-prefs");
const gameState = SharedMap.create(runtime); // Auto-generated ID

Getting Values

Retrieves values from the SharedMap by key.

/**
 * 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
 */
get<T = any>(key: string): T | undefined;

Usage Examples:

// Basic value retrieval
const userName = myMap.get("user-name");
const config = myMap.get("app-config");

// Type-safe retrieval with generics
const score = myMap.get<number>("player-score");
const settings = myMap.get<UserSettings>("user-settings");

// Check if value exists
if (myMap.has("feature-flag")) {
  const isEnabled = myMap.get<boolean>("feature-flag");
}

Setting Values

Sets key-value pairs in the SharedMap, which automatically synchronizes to other clients.

/**
 * Sets the value stored at key to the provided value
 * @param key - Key to set
 * @param value - Value to set (must be JSON-serializable or a handle)
 * @returns The ISharedMap itself for chaining
 */
set<T = unknown>(key: string, value: T): this;

Usage Examples:

// Set primitive values
myMap.set("user-count", 42);
myMap.set("app-name", "My Collaborative App");
myMap.set("is-active", true);

// Set complex objects (must be JSON-serializable)
myMap.set("user-profile", {
  name: "Alice",
  email: "alice@example.com",
  preferences: { theme: "dark", lang: "en" }
});

// Set arrays
myMap.set("recent-actions", ["login", "view-dashboard", "edit-profile"]);

// Chaining operations
myMap
  .set("initialized", true)
  .set("last-update", new Date().toISOString())
  .set("version", "1.0.0");

Checking Key Existence

Checks whether a key exists in the SharedMap.

/**
 * Returns true if the specified key exists, false otherwise
 * @param key - Key to check for
 * @returns Boolean indicating key existence
 */
has(key: string): boolean;

Usage Examples:

// Check before getting
if (myMap.has("user-settings")) {
  const settings = myMap.get("user-settings");
  // Process settings...
}

// Conditional logic based on key existence
const theme = myMap.has("theme") ? myMap.get("theme") : "light";

Deleting Keys

Removes key-value pairs from the SharedMap.

/**
 * Removes the specified key and its value from the map
 * @param key - Key to delete
 * @returns True if the key existed and was deleted, false if it didn't exist
 */
delete(key: string): boolean;

Usage Examples:

// Delete a specific key
const wasDeleted = myMap.delete("temporary-data");
if (wasDeleted) {
  console.log("Temporary data was removed");
}

// Clean up expired data
if (myMap.has("session-token")) {
  myMap.delete("session-token");
}

Clearing All Data

Removes all key-value pairs from the SharedMap.

/**
 * Removes all key-value pairs from the map
 */
clear(): void;

Usage Example:

// Reset the entire map
myMap.clear();
console.log(myMap.size); // 0

Getting Map Size

Returns the number of key-value pairs in the SharedMap.

/**
 * Returns the number of key-value pairs in the map
 */
readonly size: number;

Usage Examples:

console.log(`Map contains ${myMap.size} items`);

// Check if map is empty
if (myMap.size === 0) {
  console.log("Map is empty");
}

Iterating Over Keys

Iterates over all keys in the SharedMap.

/**
 * Returns an iterator over the keys in the map
 * @returns Iterator for map keys
 */
keys(): IterableIterator<string>;

Usage Examples:

// Iterate over all keys
for (const key of myMap.keys()) {
  console.log(`Key: ${key}, Value: ${myMap.get(key)}`);
}

// Convert to array
const allKeys = Array.from(myMap.keys());
console.log("All keys:", allKeys);

Iterating Over Values

Iterates over all values in the SharedMap.

/**
 * Returns an iterator over the values in the map
 * @returns Iterator for map values
 */
values(): IterableIterator<any>;

Usage Examples:

// Iterate over all values
for (const value of myMap.values()) {
  console.log("Value:", value);
}

// Process all values
const allValues = Array.from(myMap.values());
const processedValues = allValues.filter(v => v !== null);

Iterating Over Entries

Iterates over all key-value pairs in the SharedMap.

/**
 * Returns an iterator over key-value pairs in the map
 * @returns Iterator for [key, value] pairs
 */
entries(): IterableIterator<[string, any]>;

/**
 * Default iterator - same as entries()
 */
[Symbol.iterator](): IterableIterator<[string, any]>;

Usage Examples:

// Iterate over entries using for...of
for (const [key, value] of myMap) {
  console.log(`${key}: ${value}`);
}

// Explicit entries iteration
for (const [key, value] of myMap.entries()) {
  console.log(`Entry - ${key}: ${JSON.stringify(value)}`);
}

// Convert to array of entries
const entries = Array.from(myMap.entries());
console.log("All entries:", entries);

ForEach Iteration

Executes a callback function for each key-value pair in the SharedMap.

/**
 * Executes a provided function once for each key-value pair
 * @param callbackfn - Function to execute for each entry
 * @param thisArg - Optional value to use as 'this' when executing callback
 */
forEach(callbackfn: (value: any, key: string, map: Map<string, any>) => void, thisArg?: any): void;

Usage Examples:

// Basic forEach usage
myMap.forEach((value, key) => {
  console.log(`Processing ${key}: ${value}`);
});

// With index tracking
let index = 0;
myMap.forEach((value, key) => {
  console.log(`Item ${index++}: ${key} = ${value}`);
});

// Using thisArg
const processor = {
  prefix: "Data:",
  process(value: any, key: string) {
    console.log(`${this.prefix} ${key} = ${value}`);
  }
};

myMap.forEach(function(value, key) {
  this.process(value, key);
}, processor);

Event Handling

SharedMap emits events when data changes, enabling reactive programming patterns.

interface ISharedMapEvents extends ISharedObjectEvents {
  /**
   * Emitted when a key is set or deleted
   * @param changed - Information about the key that changed
   * @param local - Whether the change originated from this client
   */
  (event: "valueChanged", listener: (changed: IValueChanged, local: boolean, target: IEventThisPlaceHolder) => void): any;
  
  /**
   * Emitted when the map is cleared
   * @param local - Whether the clear originated from this client
   */
  (event: "clear", listener: (local: boolean, target: IEventThisPlaceHolder) => void): any;
}

interface IValueChanged {
  readonly key: string;
  readonly previousValue: any;
}

Usage Examples:

// Listen for value changes
myMap.on("valueChanged", (changed, local) => {
  console.log(`Key "${changed.key}" changed from:`, changed.previousValue);
  console.log(`New value:`, myMap.get(changed.key));
  console.log(`Change was ${local ? "local" : "from another client"}`);
});

// Listen for map clear events
myMap.on("clear", (local) => {
  console.log(`Map was cleared ${local ? "locally" : "by another client"}`);
});

// One-time event listeners
myMap.once("valueChanged", (changed, local) => {
  console.log("First change detected:", changed.key);
});

// Remove event listeners
const valueChangeHandler = (changed, local) => {
  // Handle change...
};
myMap.on("valueChanged", valueChangeHandler);
// Later...
myMap.off("valueChanged", valueChangeHandler);

Value Constraints

SharedMap values must be:

  1. JSON-serializable: Objects that can be converted to/from JSON
  2. Fluid handles: References to other Fluid Framework objects
  3. Primitive types: Strings, numbers, booleans, null, undefined

Valid values:

myMap.set("string", "hello");
myMap.set("number", 42);
myMap.set("boolean", true);
myMap.set("null", null);
myMap.set("object", { name: "Alice", age: 30 });
myMap.set("array", [1, 2, 3]);
myMap.set("date-string", new Date().toISOString());

Invalid values:

// These will not synchronize properly
myMap.set("function", () => console.log("hello")); // Functions
myMap.set("date-object", new Date()); // Date objects (use toISOString())
myMap.set("regex", /pattern/); // Regular expressions
myMap.set("symbol", Symbol("unique")); // Symbols

Conflict Resolution

SharedMap uses last-write-wins conflict resolution:

  • When multiple clients modify the same key simultaneously, the last modification to reach the server wins
  • No automatic merging of values occurs
  • Applications should implement custom conflict resolution if needed
  • Consider using operational transforms for more sophisticated conflict handling