User Manual
Hamok / HamokEmitter / HamokMap / HamokQueue / HamokRecord / HamokRemoteMap
Table of Contents
Overview
HamokMap
is a class that provides a replicated storage solution across instances, allowing for key-value pair manipulation with event-driven notifications.
Create a HamokMap instance
You need a Hamok to create a Map. Here is how you can create a HamokMap instance:
const map = hamok.createMap<string, number>({
mapId: "exampleMap",
});
Configuration
At the time of creation, you can pass the following configuration options:
const map = hamok.createMap<string, number>({
/**
* The unique identifier for the map.
*/
mapId: 'map1',
/**
* Optional. The timeout duration in milliseconds for requests.
*
* DEFAULT: 5000
*/
requestTimeoutInMs: 5000,
/**
* Optional. The maximum number of keys allowed in request or response messages.
*
* DEFAULT: 0 means infinity
*/
maxOutboundMessageKeys: 1000,
/**
* Optional. The maximum number of values allowed in request or response messages.
*
* DEFAULT: 0 means infinity
*/
maxOutboundMessageValues: 100,
/**
* Optional. A base map to be used as the initial state of the map.
*
* DEFAULT: a new and empty BaseMap instance
*/
baseMap: new BaseMap<K, V>(),
/**
* Optional. A codec for encoding and decoding keys in the map.
*
* DEFAULT: JSON codec
*/
keyCodec: {
encode: (key: K) => Buffer.from(JSON.stringify(key)),
decode: (data: Uint8Array) => JSON.parse(Buffer.from(data).toString()),
}
/**
* Optional. A codec for encoding and decoding values in the map.
*
* DEFAULT: JSON codec
*/
valueCodec?: {
encode: (value: V) => Buffer.from(JSON.stringify(value)),
decode: (data: Uint8Array) => JSON.parse(Buffer.from(data).toString()),
}
/**
* Optional. A function to determine equality between two values.
* Used for custom equality checking.
*/
equalValues: (a: V, b: V) => a === b,
});
API Reference HamokMap<K, V>
A class representing a distributed map with various methods for manipulating and accessing the stored entries.
Properties
id
:string
- The unique identifier of the map.closed
:boolean
- Indicates whether the map is closed.size
:number
- The number of entries in the map.isEmpty
:boolean
- Indicates whether the map is empty.equalValues
:(a: V, b: V) => boolean
- A function to compare values for equality.connection
:HamokConnection<string, string>
- The connection used by the map.ready
:Promise<void>
- A promise that resolves when the map is initialized and ready to use.
Events
The HamokMap
class extends EventEmitter
and emits the following events:
insert
- Emitted when a new entry is inserted.update
- Emitted when an entry is updated.remove
- Emitted when an entry is removed.clear
- Emitted when all entries are cleared.close
- Emitted when the map is closed.
Methods
-
close():
void
- Closes the map and releases any held resources.
-
keys():
IterableIterator<K>
- Returns an iterator over the keys in the map.
-
clear():
Promise<void>
- Clears all entries in the map.
-
get(
key: K
):V | undefined
- Retrieves the value associated with the specified key.
-
removeIf(
key: K
,value: V
):Promise<boolean>
- Removes the entry if the current value matches the specified value.
-
getAll(
keys: IterableIterator<K> | K[]
):ReadonlyMap<K, V>
- Retrieves all values associated with the specified keys.
-
set(
key: K
,value: V
):Promise<V | undefined>
- Sets the value for the specified key.
-
setAll(
entries: ReadonlyMap<K, V>
):Promise<ReadonlyMap<K, V>>
- Sets multiple entries in the map.
-
insert(
key: K
,value: V
):Promise<V | undefined>
- Inserts the specified entry into the map.
-
insertAll(
entries: ReadonlyMap<K, V> | [K, V][]
):Promise<ReadonlyMap<K, V>>
- Inserts multiple entries into the map.
-
delete(
key: K
):Promise<boolean>
- Deletes the entry associated with the specified key.
-
deleteAll(
keys: ReadonlySet<K> | K[]
):Promise<ReadonlySet<K>>
- Deletes multiple entries from the map.
-
remove(
key: K
):Promise<boolean>
- Removes the entry associated with the specified key.
-
removeAll(
keys: ReadonlySet<K> | K[]
):Promise<ReadonlyMap<K, V>>
- Removes multiple entries from the map.
-
updateIf(
key: K
,value: V
,oldValue: V
):Promise<boolean>
- Updates the entry if the current value matches the specified old value.
-
export():
HamokMapSnapshot
- Exports the map data as a snapshot.
-
import(
data: HamokMapSnapshot
,eventing?: boolean
):void
- Imports data from a snapshot.
-
[Symbol.iterator]():
IterableIterator<[K, V]>
- Returns an iterator over the entries in the map.
Example Usage
const map = new HamokMap(connection, baseMap);
map.set("key", "value").then((oldValue) => {
console.log(`Old value: ${oldValue}`);
});
const value = map.get("key");
console.log(`Value: ${value}`);
for (const [key, value] of map) {
console.log(`Key: ${key}, Value: ${value}`);
}
map.close();
Examples
FAQ
How do I create a HamokMap instance?
To create a HamokMap instance, you need a Hamok instance. Here is an example:
const map = hamok.createMap<string, number>({
mapId: "exampleMap",
});
How can I listen to HamokMap events?
You can listen to HamokMap events using the on
method. Here is an example:
map.on("insert", (key, value) => console.log(`Inserted: ${key} -> ${value}`));
map.on("update", (key, oldValue, newValue) =>
console.log(`Updated: ${key} from ${oldValue} to ${newValue}`)
);
map.on("remove", (key, value) => console.log(`Removed: ${key} -> ${value}`));
map.on("clear", () => console.log("Map cleared"));
map.on("close", () => console.log("Map closed"));
How do I close a HamokMap instance?
To close a HamokMap instance, use the close
method:
map.close();
And what does that do?
The close
method closes the map and releases any held resources.
It deletes the map from the Hamok instance and stops all event emissions.
You cannot mutate the map after it is closed.
How do I clear all entries in a HamokMap?
To clear all entries in a HamokMap, use the clear
method:
await map.clear();
How do I retrieve a value for a given key?
To retrieve a value for a given key, use the get
method:
const value = map.get("key1");
console.log(value);
How do I set a value for a given key?
To set a value for a given key, use the set
method:
const oldValue = await map.set("key1", "value1");
console.log(oldValue);
How do I insert a value for a given key?
To insert a value for a given key, use the insert
method:
const existingValue = await map.insert("key1", "value1");
console.log(
existingValue
? "Insert failed, because the map already has a value for the key: " +
existingValue
: "Insert successful"
);
How do I delete an entry for a given key?
To delete an entry for a given key, use the delete
method:
const success = await map.delete("key1");
console.log("Deleted", success ? "successfully" : "failed");
What is the difference between the set
and insert
methods?
The set
method updates the value for a given key, regardless of whether the key already exists.
The insert
method, however, only adds a new key-value pair if the key does not already exist.
map.on("insert", (key, value) => console.log(`Inserted: ${key} -> ${value}`));
map.on("update", (key, oldValue, newValue) =>
console.log(`Updated: ${key} from ${oldValue} to ${newValue}`)
);
await map.set("key", "value"); // Updates or inserts the key-value pair
await map.set("key", "new-value"); // Updates or inserts the key-value pair
What is the difference between delete and remove methods?
The delete
method deletes the entry associated with the specified keyand returns true
, or false
indicating it’s success or failuire.
The remove
method removes the entry associated with the specified key return the removed value.
How many entries can be pushed as batch to setAll
, insertAll
, deleteAll
, and removeAll
methods?
As many as you wish, just take care of the memory usage.
If you go in this way of large maps and batches, you should configure the maxOutboundMessageKeys
and maxOutboundMessageValues
options.
In that way, you can control the maximum number of keys and values allowed in request or response messages
preventing the communication channel to be bloated.
How do I retrieve multiple values for multiple keys?
To retrieve multiple values for multiple keys, use the getAll
method:
const keys = ["key1", "key2"];
const values = map.getAll(keys);
console.log(values);
Should I export the map?
As you wish, but I designed the export
and import
methods to be used by Hamok
to export and import the whole state of the map.
Can I change the value of entries in the map when iterating or modify the baseMap?
You can, but you should not! THe whole purpose of the HamokMap is to give a wrapper to mutate the baseMap in a safe way. If you use the method designed for mutating the baseMap and keep entries consistent then you have a consistent map. If you change the baseMap directly, you can break the consistency of the map. But noone stops you from doing that.