Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

Refactor/new nats lib #4

Merged
9 commits merged into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ jobs:
with:
node-version: 18
registry-url: https://registry.npmjs.org/
- name: NPM 9 install
run: npm install -g npm@9
- name: Install dependencies
run: npm install
- name: Lint code
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
with:
node-version: 18
registry-url: https://registry.npmjs.org/
- name: NPM 9 install
run: npm install -g npm@9
- name: Install dependencies
run: npm install
- name: Lint code
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
"./src"
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
}
}
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log (@egomobile/nats)

## 0.5.0

- **BREAKING CHANGE**: refactor to new [nats module](https://www.npmjs.com/package/nats)

## 0.4.0

- add user and password to connection options
Expand Down
138 changes: 56 additions & 82 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,92 +17,66 @@ npm install --save @egomobile/nats
## Usage

```typescript
import { loadNatsListeners, stan } from "@egomobile/nats";

// 'stan' configuration is setup
// in following environment variables
//
// POD_NAME => client ID
// NATS_CLUSTER_ID => cluster ID
// NATS_URL => (optional) URL to NATS server ... Default 'http://nats:4222'
// NATS_USER => user for authentication
// NATS_PASSWORD => password for authentication
// NATS_TLS => connections via TLS

let subscriptions: any[] | undefined;

async function main() {
// connect to server
await stan.connect();

// close connection, when process exits
// --or-- exit process, when connection collapses
//
// this is very useful in Kubernetes PODs
stan.exitOnClose();

// scan all .ts files in 'listeners' sub folder
// and execute all exported functions, which are
// exported by 'default' or directly as CommonJS
// function
//
// s. below
subscriptions = await loadNatsListeners({
dir: __dirname + "/listener",
filter: ".ts",
});
}

main().error(console.error);
```

A "listener" file, loaded by `loadNatsListeners()` function can look like that:

```typescript
// file: listeners/foo_subject.ts

import {
ISetupNatsListenerActionArguments,
NatsListener,
} from "@egomobile/nats";
INatsMessageConsumerContext,
NatsClient,
NatsMessageError
} from "@egomobile/nats"

interface IFooEvent {
bar: string;
baz?: number;
interface IFooMessage {
bar: number;
}

export default async ({ client, name }: ISetupNatsListenerActionArguments) => {
// name === 'foo_subject'
// use it as subject for the listener

const listener = new NatsListener<IFooEvent>(name, {
client,
});
listener.onMessage = async ({ message }) => {
// handle 'message'
};

// 'Subscription' instance should
// be used as object / value that
// represents the listener (connection)
return listener.listen();
};
```

This example shows, how to send / publish a `foo_subject` event from another client later, e.g.:

```typescript
import { NatsPublisher } from "@egomobile/nats";

interface IFooEvent {
bar: string;
baz?: number;
}

await new NatsPublisher<IFooEvent>("foo_subject").publish({
bar: "Foo",
baz: 5979,
});
// creates and opens an instance to a NATS
// server using `NATS_URL`, `NATS_USER` and `NATS_PASSWORD`
// environment variables by default
const client = NatsClient.open({
"name": process.env.POD_NAME!.trim()
})

// optional:
// https://developer.mozilla.org/en-US/docs/Web/API/AbortController
const ac = new AbortController()

const consumer = client.createConsumer<IFooMessage>({ "streamName": "foo-stream" })
consumer.on("message", (context: INatsMessageConsumerContext<IFooMessage>) => {
const {
ack,
message
} = context

// process `message` ...

// ack() is usually executed automatically
})
consumer.on("error", (error: any) => {
if (error instanceof NatsMessageError) {
// is happends if handling a message failed
//
// error.msg contains `JsMsg`
// error.cause contains inner exception
console.error('Consumer message error:', error)
} else {
console.error('Consumer error:', error)
}
})

const disposeSubscription = consumer.subscribe({
signal: ac.signal
})

const publisher = client.createPublisher<IFooMessage>({ "streamName": "foo-stream" })
await publisher.publish({
"bar": 42
})

setTimeout(() => {
ac.abort()

// alternative, if there is no AbortController:
//
// disposeSubscription()
}, 10000)
```

## Documentation
Expand Down
Loading