CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-fluidframework--map

Distributed data structures for collaborative applications providing SharedMap and SharedDirectory implementations with real-time synchronization and last-write-wins conflict resolution

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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

docs

events.md

index.md

legacy-factories.md

shared-directory.md

shared-map.md

tile.json