opticedge-cloud-utils 1.1.18 → 1.1.19

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/dist/pub.js CHANGED
@@ -3,16 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.publishMessage = publishMessage;
4
4
  // src/pub.ts
5
5
  const pubsub_1 = require("@google-cloud/pubsub");
6
- const pubsubCache = new Map();
6
+ let cachedPubSub = null;
7
7
  function getPubSub(projectId) {
8
8
  if (!projectId)
9
9
  throw new Error('projectId is required');
10
- let ps = pubsubCache.get(projectId);
11
- if (!ps) {
12
- ps = new pubsub_1.PubSub({ projectId });
13
- pubsubCache.set(projectId, ps);
10
+ if (!cachedPubSub) {
11
+ cachedPubSub = new pubsub_1.PubSub({ projectId });
14
12
  }
15
- return ps;
13
+ return cachedPubSub;
16
14
  }
17
15
  async function publishMessage(projectId, topicName, envelope) {
18
16
  if (!projectId)
@@ -28,7 +26,7 @@ async function publishMessage(projectId, topicName, envelope) {
28
26
  const messageId = await topic.publishMessage({
29
27
  data
30
28
  });
31
- console.info(`INFO: Pub/Sub publish project=${projectId} topic=${topicName} msg_id=${messageId}`);
29
+ console.info(`INFO: Pub/Sub publish topic=${topicName} msg_id=${messageId}`);
32
30
  return messageId;
33
31
  }
34
32
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opticedge-cloud-utils",
3
- "version": "1.1.18",
3
+ "version": "1.1.19",
4
4
  "description": "Common utilities for cloud functions",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/pub.ts CHANGED
@@ -1,16 +1,16 @@
1
1
  // src/pub.ts
2
2
  import { PubSub } from '@google-cloud/pubsub'
3
3
 
4
- const pubsubCache = new Map<string, PubSub>()
4
+ let cachedPubSub: PubSub | null = null
5
5
 
6
6
  function getPubSub(projectId: string): PubSub {
7
7
  if (!projectId) throw new Error('projectId is required')
8
- let ps = pubsubCache.get(projectId)
9
- if (!ps) {
10
- ps = new PubSub({ projectId })
11
- pubsubCache.set(projectId, ps)
8
+
9
+ if (!cachedPubSub) {
10
+ cachedPubSub = new PubSub({ projectId })
12
11
  }
13
- return ps
12
+
13
+ return cachedPubSub
14
14
  }
15
15
 
16
16
  export async function publishMessage(
@@ -30,9 +30,7 @@ export async function publishMessage(
30
30
  data
31
31
  })
32
32
 
33
- console.info(
34
- `INFO: Pub/Sub publish project=${projectId} topic=${topicName} msg_id=${messageId}`
35
- )
33
+ console.info(`INFO: Pub/Sub publish topic=${topicName} msg_id=${messageId}`)
36
34
  return messageId
37
35
  } catch (err) {
38
36
  console.error('ERROR: publish failed:', err)
package/tests/pub.test.ts CHANGED
@@ -27,8 +27,17 @@ const path = '../src/pub'
27
27
 
28
28
  describe('publishMessage', () => {
29
29
  beforeEach(() => {
30
- // Ensure a fresh module load so the mocked PubSub and src/pub share the same mock instance
30
+ // ensure fresh module state between tests
31
31
  jest.resetModules()
32
+ // clear any existing mock instances array if present
33
+ try {
34
+ const mockPubsub = require('@google-cloud/pubsub')
35
+ if (mockPubsub && Array.isArray(mockPubsub.__instances)) {
36
+ mockPubsub.__instances.length = 0
37
+ }
38
+ } catch {
39
+ // ignore if not loaded yet
40
+ }
32
41
  })
33
42
 
34
43
  test('publishes and returns messageId, sends JSON buffer', async () => {
@@ -57,7 +66,7 @@ describe('publishMessage', () => {
57
66
  await expect(publishMessage('p', 't', undefined as any)).rejects.toThrow('envelope is required')
58
67
  })
59
68
 
60
- test('caches one PubSub instance per project', async () => {
69
+ test('caches one PubSub instance across multiple calls for the same project', async () => {
61
70
  const mockPubsub = require('@google-cloud/pubsub')
62
71
  const { publishMessage } = require(path)
63
72
 
@@ -70,16 +79,49 @@ describe('publishMessage', () => {
70
79
  expect(publishMock).toHaveBeenCalledTimes(2)
71
80
  })
72
81
 
73
- test('creates separate PubSub instances for different projects', async () => {
82
+ test('reuses the same PubSub instance even when called with a different projectId', async () => {
74
83
  const mockPubsub = require('@google-cloud/pubsub')
75
84
  const { publishMessage } = require(path)
76
85
 
86
+ // first call creates instance with project-A
77
87
  await publishMessage('project-A', 't1', { x: 1 })
88
+ // second call passes a different project id but module currently reuses the cached instance
78
89
  await publishMessage('project-B', 't2', { y: 2 })
79
90
 
80
91
  const instances = mockPubsub.__instances
81
- expect(instances.length).toBe(2)
92
+ // because src/pub.ts caches a single PubSub instance, only one instance should exist
93
+ expect(instances.length).toBe(1)
94
+ // the created instance was constructed with the first project id
82
95
  expect(instances[0].opts).toEqual({ projectId: 'project-A' })
83
- expect(instances[1].opts).toEqual({ projectId: 'project-B' })
96
+
97
+ // ensure both publishes were invoked on the same instance (different topics)
98
+ expect(instances[0].topics.get('t1').publishMessage).toHaveBeenCalledTimes(1)
99
+ expect(instances[0].topics.get('t2').publishMessage).toHaveBeenCalledTimes(1)
100
+ })
101
+
102
+ test('logs error and rethrows when publish fails', async () => {
103
+ const mockPubsub = require('@google-cloud/pubsub')
104
+
105
+ // Override the mock PubSub.topic to return a publishMessage that rejects
106
+ mockPubsub.PubSub.prototype.topic = function (name: string) {
107
+ if (!this.topics.has(name)) {
108
+ const publishMessage = jest.fn(() => Promise.reject(new Error('boom')))
109
+ this.topics.set(name, { publishMessage })
110
+ }
111
+ return this.topics.get(name)
112
+ }
113
+
114
+ const { publishMessage } = require(path)
115
+
116
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
117
+
118
+ await expect(publishMessage('project-err', 'topic-err', { fail: true })).rejects.toThrow('boom')
119
+
120
+ expect(consoleErrorSpy).toHaveBeenCalled()
121
+ const firstArg = consoleErrorSpy.mock.calls[0][0]
122
+ expect(typeof firstArg).toBe('string')
123
+ expect(firstArg).toContain('ERROR: publish failed:')
124
+
125
+ consoleErrorSpy.mockRestore()
84
126
  })
85
127
  })