Skip to content

Commit

Permalink
2.3.3 (#9)
Browse files Browse the repository at this point in the history
* 2.3.3
* Update index.md (#10)
* update readme
* check `records` instead of `maps` in `createRecord` method
* add `getOrCreate[Collection]`
* update docs
  • Loading branch information
balazskreith authored Aug 23, 2024
1 parent 37502b1 commit 8e16778
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 8 deletions.
4 changes: 2 additions & 2 deletions docs/emitter.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,9 @@ In short use notify for fire and forget messages, and use publish for messages t

### How many subscribers can a HamokEmitter have for one event?

A `HamokEmitter` can have an unlimited number of subscribers for each event on any peer.
A `HamokEmitter` can have an unlimited number of subscribers for each event on any peer.
The underlying `EventEmitter` implementation used in `HamokEmitter` has no limit on the number of listeners for an event.
To distribute the event to the remote peers subscribed to the event, the `HamokEmitter` uses the Raft consensus algorithm
To distribute the event to the remote peers subscribed to the event, the `HamokEmitter` uses the Raft consensus algorithm
to ensure that the subscription is consistent across all peers.

### What is the payloadsCodec for?
Expand Down
26 changes: 24 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,26 @@ Hamok emits various events that can be listened to for handling specific actions

- Creates a new emitter with the provided options.

- **getOrCreateMap**<`K, V`>(`options: HamokMapBuilderConfig<K, V>`, `callback?: (exists: boolean) => void`): `HamokMap<K, V>`

- Gets an existing map or creates a new map with the provided options.

- **getOrCreateEmitter**<`T extends HamokEmitterEventMap`>(`options: HamokEmitterBuilderConfig<T>`, `callback?: (exists: boolean) => void`): `HamokEmitter<T>`

- Gets an existing emitter or creates a new emitter with the provided options.

- **getOrCreateRemoteMap**<`K, V`>(`options: HamokRemoteMapBuilderConfig<K, V>`, `callback?: (exists: boolean) => void`): `HamokRemoteMap<K, V>`

- Gets an existing remote map or creates a new remote map with the provided options.

- **getOrCreateQueue**<`T`>(`options: HamokQueueBuilderConfig<T>`, `callback?: (exists: boolean) => void`): `HamokQueue<T>`

- Gets an existing queue or creates a new queue with the provided options.

- **getOrCreateRecord**<`T extends HamokRecordObject`>(`options: HamokRecordBuilderConfig<T>`, `callback?: (exists: boolean) => void`): `HamokRecord<T>`

- Gets an existing record or creates a new record with the provided options.

- **submit**(`entry: HamokMessage`): `Promise<void>`

- Submits a message to the Raft engine.
Expand Down Expand Up @@ -492,8 +512,6 @@ If you encounter issues with Hamok, consider the following steps:
- Review logs for any error messages or warnings.
- Consult the Hamok documentation and community forums for additional support.

Here is the updated markdown compatibility table for the `HamokMessage` schema with version 2.0.0 removed:

## `HamokMessage` compatibility Table

| Version | 2.1.0 | 2.2.0 | 2.3.0 |
Expand Down Expand Up @@ -625,3 +643,7 @@ const hamok = new Hamok({

console.log("foo is", hamok.appData.foo);
```

### How can I check if a Map/Record/Emitter/Queue I want to create already exists?

`Hamok` exposes the created objects via the `maps`, `records`, `emitters`, `remoteMaps`, and `queues` properties. You can check if an object already exists by using a command like `if (hamok.maps.has(mapId))`. Alternatively, you can use the `getOrCreate` method (`getOrCreateMap`, `getOrCreateEmitter`, `getOrCreateRecord`, `getOrCreateRemoteMap`, `getOrCreateQueue`) to either retrieve an existing object or create a new one if it doesn't already exist.
3 changes: 1 addition & 2 deletions examples/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hamok-example",
"version": "2.3.0",
"version": "2.4.0",
"description": "Example for Hamok",
"main": "main.js",
"scripts": {
Expand All @@ -21,7 +21,6 @@
"dev:common:3": "nodemon -x ts-node src/common-join-example.ts | pino-pretty",
"dev:common:4": "nodemon -x ts-node src/common-reelection-example.ts | pino-pretty",
"dev:common:5": "nodemon -x ts-node src/common-waiting-example-2.ts | pino-pretty",

"dev:redis:1": "nodemon -x ts-node src/redis-remote-map-example.ts | pino-pretty",
"build": "tsc",
"test": "jest --config jest.config.js",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hamok",
"version": "2.3.2",
"version": "2.3.3",
"description": "Lightweight Distributed Object Storage on RAFT consensus algorithm",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
62 changes: 61 additions & 1 deletion src/Hamok.ts
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,18 @@ export class Hamok<AppData extends Record<string, unknown> = Record<string, unkn
return storage;
}

public getOrCreateMap<K, V>(options: HamokMapBuilderConfig<K, V>, callback?: (alreadyExisted: boolean) => void): HamokMap<K, V> {
const existing = this.maps.get(options.mapId);

try {
if (existing) return existing;

return this.createMap(options);
} finally {
callback?.(Boolean(existing));
}
}

public createRemoteMap<K, V>(options: HamokRemoteMapBuilderConfig<K, V>): HamokRemoteMap<K, V> {
if (this.remoteMaps.has(options.mapId)) {
throw new Error(`RemoteMap with id ${options.mapId} already exists`);
Expand Down Expand Up @@ -799,8 +811,20 @@ export class Hamok<AppData extends Record<string, unknown> = Record<string, unkn
return storage;
}

public getOrCreateRemoteMap(options: HamokRemoteMapBuilderConfig<unknown, unknown>, callback?: (alreadyExisted: boolean) => void): HamokRemoteMap<unknown, unknown> {
const existing = this.remoteMaps.get(options.mapId);

try {
if (existing) return existing;

return this.createRemoteMap(options);
} finally {
callback?.(Boolean(existing));
}
}

public createRecord<T extends HamokRecordObject>(options: HamokRecordBuilderConfig<T>): HamokRecord<T> {
if (this.maps.has(options.recordId)) {
if (this.records.has(options.recordId)) {
throw new Error(`Record with id ${options.recordId} already exists`);
}

Expand Down Expand Up @@ -850,6 +874,18 @@ export class Hamok<AppData extends Record<string, unknown> = Record<string, unkn
return record;
}

public getOrCreateRecord<T extends HamokRecordObject>(options: HamokRecordBuilderConfig<T>, callback?: (alreadyExisted: boolean) => void): HamokRecord<T> {
const existing = this.records.get(options.recordId);

try {
if (existing) return existing;

return this.createRecord(options);
} finally {
callback?.(Boolean(existing));
}
}

public createQueue<T>(options: HamokQueueBuilderConfig<T>): HamokQueue<T> {
if (this.queues.has(options.queueId)) {
throw new Error(`Queue with id ${options.queueId} already exists`);
Expand Down Expand Up @@ -895,6 +931,18 @@ export class Hamok<AppData extends Record<string, unknown> = Record<string, unkn
return queue;
}

public getOrCreateQueue<T>(options: HamokQueueBuilderConfig<T>, callback?: (alreadyExisted: boolean) => void): HamokQueue<T> {
const existing = this.queues.get(options.queueId);

try {
if (existing) return existing;

return this.createQueue(options);
} finally {
callback?.(Boolean(existing));
}
}

public createEmitter<T extends HamokEmitterEventMap>(options: HamokEmitterBuilderConfig<T>): HamokEmitter<T> {
if (this.emitters.has(options.emitterId)) {
throw new Error(`Emitter with id ${options.emitterId} already exists`);
Expand Down Expand Up @@ -998,6 +1046,18 @@ export class Hamok<AppData extends Record<string, unknown> = Record<string, unkn
}
}

public getOrCreateEmitter<T extends HamokEmitterEventMap>(options: HamokEmitterBuilderConfig<T>, callback?: (alreadyExisted: boolean) => void): HamokEmitter<T> {
const existing = this.emitters.get(options.emitterId);

try {
if (existing) return existing;

return this.createEmitter(options);
} finally {
callback?.(Boolean(existing));
}
}

public accept(message: HamokMessage, commitIndex?: number): void {
if (message.destinationId && message.destinationId !== this.localPeerId) {
return logger.trace('%s Received message address is not matching with the local peer %o', this.localPeerId, message);
Expand Down

0 comments on commit 8e16778

Please sign in to comment.