Skip to content

Commit 3cbf0b9

Browse files
chore(release): version packages (#1119)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 08c1deb commit 3cbf0b9

File tree

4 files changed

+211
-6
lines changed

4 files changed

+211
-6
lines changed

.changeset/eight-mammals-dance.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/google-cloud-pubsub/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# @golevelup/nestjs-google-cloud-pubsub
22

3+
## 1.2.0
4+
5+
### Minor Changes
6+
7+
- introduction of batching, async initialization and centralized documentation
8+
39
## 1.1.1
410

511
### Patch Changes
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
# Google Cloud PubSub
2+
3+
A type-safe Google Cloud Pub/Sub integration for NestJS. The module validates topic/subscription configuration, keeps schemas in sync with remote revisions, and generates a fully typed publisher/subscriber API through `initializeKit`.
4+
5+
## Installation
6+
7+
```bash
8+
npm install @golevelup/nestjs-google-cloud-pubsub
9+
npm install @google-cloud/pubsub avsc @protobuf-ts/runtime
10+
```
11+
12+
## Quick Start
13+
14+
Define your topics/subscriptions once and call `initializeKit`. It produces a typed publisher class, a subscribe decorator, and a payload map inferred from your Avro/Proto schemas.
15+
16+
// google-cloud-pubsub.configuration.ts
17+
18+
```ts
19+
import {
20+
GoogleCloudPubsubModule,
21+
PubsubTopicConfiguration,
22+
} from '@golevelup/nestjs-google-cloud-pubsub';
23+
import { SchemaTypes, Encodings } from '@google-cloud/pubsub';
24+
import { MessageType } from '@protobuf-ts/runtime';
25+
26+
import { PaymentProcessedProtocolBufferSchema } from './generated-proto/payment-processed-schema';
27+
28+
export const topics = [
29+
{
30+
name: 'order.created',
31+
schema: {
32+
definition: {
33+
fields: [
34+
{ name: 'field1', type: 'string' },
35+
{ name: 'field2', type: 'int' },
36+
{ name: 'field3', type: 'boolean' },
37+
{ name: 'field4', type: 'double' },
38+
{
39+
name: 'field5',
40+
type: {
41+
fields: [{ name: 'nestedField1', type: 'string' }],
42+
name: 'Nested1',
43+
type: 'record',
44+
},
45+
},
46+
{ name: 'field6', type: ['double', 'null'] },
47+
],
48+
name: 'order.created.schema',
49+
type: 'record',
50+
},
51+
encoding: Encodings.Binary,
52+
name: 'order.created.schema',
53+
type: SchemaTypes.Avro,
54+
},
55+
subscriptions: [
56+
/**
57+
* High Density Configuration (Designed for up to 100 subscriptions per instance):
58+
*
59+
* 1. Flow Control:
60+
* - Limits each subscription to 10MB or 500 messages.
61+
* - Math: 100 subs * 10MB = 1GB Raw Buffer (~2GB Real RAM Usage).
62+
*
63+
* 2. Batch Manager:
64+
* - Aggregates up to 125 messages.
65+
* - Flushes every 200ms even if 125 messages weren't aggregated.
66+
*/
67+
{
68+
name: 'order.created.subscription.order-processor-service',
69+
batchManagerOptions: { maxMessages: 125, maxWaitTimeMilliseconds: 200 },
70+
options: {
71+
flowControl: {
72+
allowExcessMessages: false,
73+
maxBytes: 10 * 1024 * 1024,
74+
maxMessages: 500,
75+
},
76+
},
77+
},
78+
{ name: 'order.created.subscription.analytic-service' },
79+
],
80+
},
81+
{
82+
name: 'payment.processed',
83+
schema: {
84+
definition:
85+
PaymentProcessedProtocolBufferSchema as MessageType<PaymentProcessedProtocolBufferSchema>,
86+
encoding: Encodings.Binary,
87+
name: 'payment.processed.schema',
88+
protoPath:
89+
'/Users/Desktop/google-cloud-pubsub/proto/payment-processed.proto',
90+
type: SchemaTypes.ProtocolBuffer,
91+
},
92+
subscriptions: [
93+
{ name: 'payment.processed.payment-processor-service' },
94+
{ name: 'payment.processed.analytic-service' },
95+
],
96+
},
97+
] as const satisfies readonly PubsubTopicConfiguration[];
98+
99+
const googleCloudPubsubKit =
100+
GoogleCloudPubsubModule.initializeKit<typeof topics>();
101+
const {
102+
GoogleCloudPubsubAbstractPublisher,
103+
GoogleCloudPubsubBatchSubscribe,
104+
GoogleCloudPubsubSubscribe,
105+
} = googleCloudPubsubKit;
106+
107+
export type GoogleCloudPubsubPayloadsMap =
108+
typeof googleCloudPubsubKit._GoogleCloudPubsubPayloadsMap;
109+
export class GoogleCloudPubsubPublisher extends GoogleCloudPubsubAbstractPublisher<GoogleCloudPubsubPayloadsMap> {}
110+
export { GoogleCloudPubsubSubscribe, GoogleCloudPubsubBatchSubscribe };
111+
```
112+
113+
// app.module.ts
114+
115+
```ts
116+
import { Module } from '@nestjs/common';
117+
import { GoogleCloudPubsubModule } from '@golevelup/nestjs-google-cloud-pubsub';
118+
119+
import {
120+
GoogleCloudPubsubPublisher,
121+
topics,
122+
} from './google-cloud-pubsub.configuration';
123+
124+
@Module({
125+
imports: [
126+
GoogleCloudPubsubModule.registerAsync({
127+
useFactory: () => ({
128+
client: { keyFilename: process.env.GOOGLE_APPLICATION_CREDENTIALS },
129+
topics,
130+
}),
131+
publisher: GoogleCloudPubsubPublisher,
132+
}),
133+
],
134+
})
135+
export class AppModule {}
136+
```
137+
138+
// app.service.ts
139+
140+
```ts
141+
import { Injectable } from '@nestjs/common';
142+
import { GoogleCloudPubsubMessage } from '@golevelup/nestjs-google-cloud-pubsub';
143+
144+
import {
145+
GoogleCloudPubsubPayloadsMap,
146+
GoogleCloudPubsubPublisher,
147+
GoogleCloudPubsubSubscribe,
148+
GoogleCloudPubsubBatchSubscribe,
149+
} from './google-cloud-pubsub.configuration';
150+
151+
@Injectable()
152+
export class AppService {
153+
constructor(
154+
private readonly googleCloudPubsubPublisher: GoogleCloudPubsubPublisher,
155+
) {}
156+
157+
public async publishOrderCreated() {
158+
await this.googleCloudPubsubPublisher.publish('order.created', {
159+
data: {
160+
field1: 'field1',
161+
field2: 0,
162+
field3: true,
163+
field4: 10,
164+
field5: { nestedField1: 'nestedField1' },
165+
field6: null,
166+
},
167+
});
168+
}
169+
170+
@GoogleCloudPubsubBatchSubscribe(
171+
'order.created',
172+
'order.created.subscription.analytic-service',
173+
)
174+
public async onOrdersCreated(
175+
payload: GoogleCloudPubsubMessage<
176+
GoogleCloudPubsubPayloadsMap['order.created']
177+
>[],
178+
) {
179+
console.log({ data: payload.data });
180+
}
181+
182+
@GoogleCloudPubsubSubscribe(
183+
'order.created',
184+
'order.created.subscription.analytic-service',
185+
)
186+
public async onOrderCreated(
187+
payload: GoogleCloudPubsubMessage<
188+
GoogleCloudPubsubPayloadsMap['order.created']
189+
>,
190+
) {
191+
console.log({ data: payload.data });
192+
}
193+
}
194+
```
195+
196+
## Future features
197+
198+
- Custom error hooks / metric emitters.
199+
- Push subscription support.
200+
- Split optional dependencies so Avro (`avsc`) and Protocol Buffer runtimes are only required when those schema types are used.
201+
- Publisher.ready() helper that awaits PubsubClient initialization.
202+
- Manual ack/nack.
203+
- Iterate over schema revisions page by page instead of fetching them all at once.
204+
- Support for custom Avro serialization options (e.g. `wrapUnions`, `logicalTypes`) with adaptive type inference.

packages/google-cloud-pubsub/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@golevelup/nestjs-google-cloud-pubsub",
3-
"version": "1.1.1",
3+
"version": "1.2.0",
44
"description": "Google cloud pubsub wrapper for NestJS",
55
"author": "Nikita Chaikin <nikita.chaikinn@gmail.com>",
66
"homepage": "https://github.com/golevelup/nestjs/blob/master/packages/google-cloud-pubsub/README.md",

0 commit comments

Comments
 (0)