@nitra/nats 3.0.4 → 3.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -48,7 +48,7 @@ import { publish } from '@nitra/nats'
48
48
  await publish('project:subject', { id: 1, foo: 'bar' })
49
49
  ```
50
50
 
51
- - Stream буде створено автоматично, якщо не існує.
51
+ - Stream і Consumer будуть створені автоматично, якщо не існують.
52
52
  - Повідомлення публікується у subject `stream.project:subject`.
53
53
 
54
54
  ---
@@ -64,7 +64,6 @@ await finish() // підтвердження (ack) повідомлення
64
64
  ```
65
65
 
66
66
  - Якщо не викликати `finish()`, повідомлення буде повернуто у чергу (`nak`) при завершенні процесу або помилці.
67
- - Stream і consumer створюються автоматично при першому запуску воркера для кожного subject.
68
67
 
69
68
  ---
70
69
 
@@ -77,20 +76,17 @@ const count = await getPendingCount('project:subject')
77
76
  console.log('pending:', count)
78
77
  ```
79
78
 
80
- - Якщо consumer для subject ще не існує, він буде створений автоматично.
81
-
82
79
  ---
83
80
 
84
81
  ## Як це працює
85
82
 
86
83
  - **publish(subject, data):**
87
84
 
88
- - Перевіряє/створює stream (один раз за процес).
85
+ - Перевіряє/створює stream і consumer для subject (один раз за процес).
89
86
  - Публікує повідомлення у subject `stream.${subject}`.
90
87
 
91
88
  - **read(subject):**
92
89
 
93
- - Перевіряє/створює stream і consumer для subject (один раз за процес).
94
90
  - Читає одне повідомлення з черги для subject.
95
91
 
96
92
  - **finish():**
@@ -98,7 +94,7 @@ console.log('pending:', count)
98
94
  - Підтверджує (ack) повідомлення.
99
95
 
100
96
  - **getPendingCount(subject):**
101
- - Повертає кількість непрочитаних повідомлень для consumer `durable_${subject}` (створює його, якщо не існує).
97
+ - Повертає кількість непрочитаних повідомлень для consumer `durable_${subject}`.
102
98
 
103
99
  ---
104
100
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nitra/nats",
3
3
  "description": "nats helper",
4
- "version": "3.0.4",
4
+ "version": "3.0.6",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "src"
package/src/consumer.js CHANGED
@@ -1,11 +1,16 @@
1
1
  import { jsm, AckPolicy } from './nats.js'
2
+ import { ensureStream } from './stream.js'
2
3
 
3
4
  /**
4
5
  * Перевіряє наявність або створює durable consumer для subject.
6
+ * Stream створюється автоматично, якщо не існує.
5
7
  * @param {string} subject - subject у форматі project:subject
6
8
  * @returns {Promise<void>}
7
9
  */
8
10
  export async function ensureConsumer(subject) {
11
+ // створюємо stream якщо не існує
12
+ await ensureStream()
13
+
9
14
  try {
10
15
  await jsm.consumers.info('stream', `durable_${subject}`)
11
16
  console.debug('✅ Durable consumer already exists')
@@ -1,24 +1,19 @@
1
1
  import { jsm } from './nats.js'
2
- import { ensureConsumer } from './consumer.js'
3
2
  import { checkSubjectFormat } from './utils.js'
4
3
 
5
4
  /**
6
5
  * Повертає кількість непрочитаних (pending) повідомлень для durable consumer, пов’язаного з subject.
7
- * Consumer створюється автоматично, якщо не існує.
8
6
  * @param {string} subject - subject у форматі project:subject
9
7
  * @returns {Promise<number>} - кількість непрочитаних повідомлень
10
8
  */
11
9
  export async function getPendingCount(subject) {
12
10
  checkSubjectFormat(subject)
13
11
 
14
- let info
15
12
  try {
16
- info = await jsm.consumers.info('stream', `durable_${subject}`)
13
+ const info = await jsm.consumers.info('stream', `durable_${subject}`)
14
+ return info.num_pending
17
15
  } catch {
18
- console.debug('consumer not found. create new one.')
19
- await ensureConsumer(subject)
20
- info = await jsm.consumers.info('stream', `durable_${subject}`)
16
+ console.error('consumer not found for subject:', subject)
17
+ return 0
21
18
  }
22
-
23
- return info?.num_pending || 0
24
19
  }
package/src/publish.js CHANGED
@@ -1,20 +1,22 @@
1
1
  import { client, jc } from './nats.js'
2
- import { ensureStream } from './stream.js'
2
+ import { ensureConsumer } from './consumer.js'
3
+ import { checkSubjectFormat } from './utils.js'
3
4
 
4
- let streamReady = new Set()
5
+ const consumerReady = new Set()
5
6
 
6
7
  /**
7
8
  * Публікує повідомлення у JetStream для вказаного subject.
8
- * Stream створюється автоматично, якщо не існує.
9
+ * Stream і Consumer створюються автоматично, якщо не існують.
9
10
  * @param {string} subject - subject у форматі project:subject
10
11
  * @param {object} data - дані для публікації
11
12
  * @returns {Promise<void>}
12
13
  */
13
14
  export async function publish(subject, data) {
14
- // Ensure stream if not exists
15
- if (!streamReady.has(subject)) {
16
- await ensureStream(subject)
17
- streamReady.add(subject)
15
+ // Ensure stream and consumer if not exists
16
+ if (!consumerReady.has(subject)) {
17
+ checkSubjectFormat(subject)
18
+ await ensureConsumer(subject)
19
+ consumerReady.add(subject)
18
20
  }
19
21
  console.debug('publish', data)
20
22
  // Publish message
package/src/stream.js CHANGED
@@ -1,14 +1,10 @@
1
1
  import { jsm } from './nats.js'
2
- import { checkSubjectFormat } from './utils.js'
3
2
 
4
3
  /**
5
4
  * Перевіряє наявність або створює JetStream stream.
6
- * @param {string} subject - subject у форматі project:subject (для валідації)
7
5
  * @returns {Promise<void>}
8
6
  */
9
- export async function ensureStream(subject) {
10
- checkSubjectFormat(subject)
11
-
7
+ export async function ensureStream() {
12
8
  try {
13
9
  await jsm.streams.info('stream')
14
10
  console.debug('✅ Stream already exists')
package/src/worker.js CHANGED
@@ -1,20 +1,21 @@
1
1
  import { js, jc } from './nats.js'
2
- import { ensureStream } from './stream.js'
3
- import { ensureConsumer } from './consumer.js'
4
- import { state } from './utils.js'
2
+ import { state, checkSubjectFormat } from './utils.js'
5
3
 
6
4
  /**
7
5
  * Зчитує одне повідомлення з JetStream для вказаного subject.
8
- * Consumer створюється автоматично, якщо не існує.
9
6
  * @param {string} subject - subject у форматі project:subject
10
7
  * @returns {Promise<object>} - декодовані дані повідомлення
11
8
  */
12
9
  export async function read(subject) {
13
- // Ensure stream and consumer if not exists
14
- await ensureStream(subject)
15
- await ensureConsumer(subject)
10
+ checkSubjectFormat(subject)
16
11
 
17
- const consumer = await js.consumers.get('stream', `durable_${subject}`)
12
+ let consumer
13
+ try {
14
+ consumer = await js.consumers.get('stream', `durable_${subject}`)
15
+ } catch {
16
+ console.error('consumer not found for subject:', subject)
17
+ return {}
18
+ }
18
19
 
19
20
  const iter = await consumer.fetch({ max_messages: 1 })
20
21
  for await (const msg of iter) {