@thangnv-dev/message-streaming-mikroorm-node 0.0.1
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/errors.d.ts +8 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +25 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/message-streaming.d.ts +18 -0
- package/dist/message-streaming.d.ts.map +1 -0
- package/dist/message-streaming.js +213 -0
- package/dist/message-streaming.js.map +1 -0
- package/dist/migrations/migration-20260215231000-message-store.d.ts +6 -0
- package/dist/migrations/migration-20260215231000-message-store.d.ts.map +1 -0
- package/dist/migrations/migration-20260215231000-message-store.js +144 -0
- package/dist/migrations/migration-20260215231000-message-store.js.map +1 -0
- package/package.json +49 -0
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { StandardError } from '@thangnv-dev/error-common';
|
|
2
|
+
export declare class MessageStreamingQueryError extends StandardError {
|
|
3
|
+
constructor(operation: string, cause?: unknown);
|
|
4
|
+
}
|
|
5
|
+
export declare class MessageStreamingInvalidResultError extends StandardError {
|
|
6
|
+
constructor(field: string, cause?: unknown);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAIzD,qBAAa,0BAA2B,SAAQ,aAAa;gBAC/C,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAS/C;AAED,qBAAa,kCAAmC,SAAQ,aAAa;gBACvD,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAS3C"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { StandardError } from '@thangnv-dev/error-common';
|
|
2
|
+
const MESSAGE_STREAMING_IMPL_PACKAGE = '@thangnv-dev/message-streaming-mikroorm-node';
|
|
3
|
+
export class MessageStreamingQueryError extends StandardError {
|
|
4
|
+
constructor(operation, cause) {
|
|
5
|
+
super({
|
|
6
|
+
package: MESSAGE_STREAMING_IMPL_PACKAGE,
|
|
7
|
+
code: 'MESSAGE_STREAMING_QUERY_FAILED',
|
|
8
|
+
cause,
|
|
9
|
+
message: `${operation} query failed`,
|
|
10
|
+
});
|
|
11
|
+
this.name = 'MessageStreamingQueryError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class MessageStreamingInvalidResultError extends StandardError {
|
|
15
|
+
constructor(field, cause) {
|
|
16
|
+
super({
|
|
17
|
+
package: MESSAGE_STREAMING_IMPL_PACKAGE,
|
|
18
|
+
code: 'MESSAGE_STREAMING_INVALID_RESULT',
|
|
19
|
+
cause,
|
|
20
|
+
message: `invalid message-streaming result field: ${field}`,
|
|
21
|
+
});
|
|
22
|
+
this.name = 'MessageStreamingInvalidResultError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEzD,MAAM,8BAA8B,GAAG,8CAA8C,CAAA;AAErF,MAAM,OAAO,0BAA2B,SAAQ,aAAa;IAC3D,YAAY,SAAiB,EAAE,KAAe;QAC5C,KAAK,CAAC;YACJ,OAAO,EAAE,8BAA8B;YACvC,IAAI,EAAE,gCAAgC;YACtC,KAAK;YACL,OAAO,EAAE,GAAG,SAAS,eAAe;SACrC,CAAC,CAAA;QACF,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAA;IAC1C,CAAC;CACF;AAED,MAAM,OAAO,kCAAmC,SAAQ,aAAa;IACnE,YAAY,KAAa,EAAE,KAAe;QACxC,KAAK,CAAC;YACJ,OAAO,EAAE,8BAA8B;YACvC,IAAI,EAAE,kCAAkC;YACxC,KAAK;YACL,OAAO,EAAE,2CAA2C,KAAK,EAAE;SAC5D,CAAC,CAAA;QACF,IAAI,CAAC,IAAI,GAAG,oCAAoC,CAAA;IAClD,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { MessageStreamingInvalidResultError, MessageStreamingQueryError } from './errors.js';
|
|
2
|
+
export { KnexMessageStreaming, type KnexMessageStreamingOptions } from './message-streaming.js';
|
|
3
|
+
export { Migration20260215231000MessageStore } from './migrations/migration-20260215231000-message-store.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kCAAkC,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,oBAAoB,EAAE,KAAK,2BAA2B,EAAE,MAAM,wBAAwB,CAAA;AAC/F,OAAO,EAAE,mCAAmC,EAAE,MAAM,wDAAwD,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { MessageStreamingInvalidResultError, MessageStreamingQueryError } from './errors.js';
|
|
2
|
+
export { KnexMessageStreaming } from './message-streaming.js';
|
|
3
|
+
export { Migration20260215231000MessageStore } from './migrations/migration-20260215231000-message-store.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kCAAkC,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,oBAAoB,EAAoC,MAAM,wBAAwB,CAAA;AAC/F,OAAO,EAAE,mCAAmC,EAAE,MAAM,wDAAwD,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import 'temporal-polyfill/global';
|
|
2
|
+
import { type MessageStreaming, type MessageStreamingGetLastStreamMessageInput, type MessageStreamingMessage, type MessageStreamingReadCategoryInput, type MessageStreamingReadStreamInput, type MessageStreamingWriteInput } from '@thangnv-dev/message-streaming-node';
|
|
3
|
+
import type { SqlEntityManager } from '@mikro-orm/knex';
|
|
4
|
+
export type KnexMessageStreamingOptions = {
|
|
5
|
+
readonly schema?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare class KnexMessageStreaming implements MessageStreaming {
|
|
8
|
+
private readonly em;
|
|
9
|
+
private readonly schema;
|
|
10
|
+
constructor(em: SqlEntityManager, options?: KnexMessageStreamingOptions);
|
|
11
|
+
writeMessage<TData = unknown, TMetadata = unknown>(input: MessageStreamingWriteInput<TData, TMetadata>): Promise<bigint>;
|
|
12
|
+
getStreamMessages<TData = unknown, TMetadata = unknown>(input: MessageStreamingReadStreamInput): Promise<Array<MessageStreamingMessage<TData, TMetadata>>>;
|
|
13
|
+
getCategoryMessages<TData = unknown, TMetadata = unknown>(input: MessageStreamingReadCategoryInput): Promise<Array<MessageStreamingMessage<TData, TMetadata>>>;
|
|
14
|
+
getLastStreamMessage<TData = unknown, TMetadata = unknown>(input: MessageStreamingGetLastStreamMessageInput): Promise<MessageStreamingMessage<TData, TMetadata> | null>;
|
|
15
|
+
streamVersion(streamNameInput: string): Promise<bigint | null>;
|
|
16
|
+
private queryRows;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=message-streaming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-streaming.d.ts","sourceRoot":"","sources":["../src/message-streaming.ts"],"names":[],"mappings":"AAAA,OAAO,0BAA0B,CAAA;AACjC,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,yCAAyC,EAC9C,KAAK,uBAAuB,EAC5B,KAAK,iCAAiC,EACtC,KAAK,+BAA+B,EACpC,KAAK,0BAA0B,EAChC,MAAM,qCAAqC,CAAA;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAmBvD,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAsKD,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAkB;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;gBAEnB,EAAE,EAAE,gBAAgB,EAAE,OAAO,GAAE,2BAAgC;IAOrE,YAAY,CAAC,KAAK,GAAG,OAAO,EAAE,SAAS,GAAG,OAAO,EACrD,KAAK,EAAE,0BAA0B,CAAC,KAAK,EAAE,SAAS,CAAC,GAClD,OAAO,CAAC,MAAM,CAAC;IAgBZ,iBAAiB,CAAC,KAAK,GAAG,OAAO,EAAE,SAAS,GAAG,OAAO,EAC1D,KAAK,EAAE,+BAA+B,GACrC,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IActD,mBAAmB,CAAC,KAAK,GAAG,OAAO,EAAE,SAAS,GAAG,OAAO,EAC5D,KAAK,EAAE,iCAAiC,GACvC,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAsBtD,oBAAoB,CAAC,KAAK,GAAG,OAAO,EAAE,SAAS,GAAG,OAAO,EAC7D,KAAK,EAAE,yCAAyC,GAC/C,OAAO,CAAC,uBAAuB,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC;IAmBtD,aAAa,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;YAiBtD,SAAS;CAYxB"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import 'temporal-polyfill/global';
|
|
2
|
+
import { MESSAGE_STREAMING_DEFAULT_BATCH_SIZE, MESSAGE_STREAMING_DEFAULT_POSITION, } from '@thangnv-dev/message-streaming-node';
|
|
3
|
+
import { MessageStreamingInvalidResultError, MessageStreamingQueryError } from './errors.js';
|
|
4
|
+
const DEFAULT_SCHEMA = 'message_store';
|
|
5
|
+
const SQL_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
6
|
+
function isRecord(value) {
|
|
7
|
+
return typeof value === 'object' && value !== null;
|
|
8
|
+
}
|
|
9
|
+
function readField(record, keys) {
|
|
10
|
+
for (const key of keys) {
|
|
11
|
+
if (Object.prototype.hasOwnProperty.call(record, key)) {
|
|
12
|
+
return record[key];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
function requireNonEmptyString(fieldName, value) {
|
|
18
|
+
if (typeof value !== 'string') {
|
|
19
|
+
throw new TypeError(`${fieldName} must be a string`);
|
|
20
|
+
}
|
|
21
|
+
const trimmed = value.trim();
|
|
22
|
+
if (!trimmed) {
|
|
23
|
+
throw new TypeError(`${fieldName} must not be empty`);
|
|
24
|
+
}
|
|
25
|
+
return trimmed;
|
|
26
|
+
}
|
|
27
|
+
function toPgBigInt(value) {
|
|
28
|
+
if (value == null) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return value.toString();
|
|
32
|
+
}
|
|
33
|
+
function parseBigIntField(fieldName, value) {
|
|
34
|
+
if (typeof value === 'bigint') {
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
if (typeof value === 'string') {
|
|
38
|
+
try {
|
|
39
|
+
return BigInt(value);
|
|
40
|
+
}
|
|
41
|
+
catch (cause) {
|
|
42
|
+
throw new MessageStreamingInvalidResultError(fieldName, cause);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (typeof value === 'number' && Number.isInteger(value)) {
|
|
46
|
+
return BigInt(value);
|
|
47
|
+
}
|
|
48
|
+
throw new MessageStreamingInvalidResultError(fieldName);
|
|
49
|
+
}
|
|
50
|
+
function parseJsonField(fieldName, value) {
|
|
51
|
+
if (value == null) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
if (typeof value === 'string') {
|
|
55
|
+
try {
|
|
56
|
+
return JSON.parse(value);
|
|
57
|
+
}
|
|
58
|
+
catch (cause) {
|
|
59
|
+
throw new MessageStreamingInvalidResultError(fieldName, cause);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
function hasTimeZoneSuffix(value) {
|
|
65
|
+
return /(Z|z|[+-]\d{2}:\d{2}|[+-]\d{2})$/.test(value);
|
|
66
|
+
}
|
|
67
|
+
function normalizeUtcTimestamp(value) {
|
|
68
|
+
const normalized = value.trim().replace(' ', 'T');
|
|
69
|
+
if (hasTimeZoneSuffix(normalized)) {
|
|
70
|
+
return normalized;
|
|
71
|
+
}
|
|
72
|
+
return `${normalized}Z`;
|
|
73
|
+
}
|
|
74
|
+
function parseInstantField(fieldName, value) {
|
|
75
|
+
if (value instanceof Date) {
|
|
76
|
+
return Temporal.Instant.from(value.toISOString());
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
if (typeof value === 'string') {
|
|
80
|
+
return Temporal.Instant.from(normalizeUtcTimestamp(value));
|
|
81
|
+
}
|
|
82
|
+
return Temporal.Instant.from(value);
|
|
83
|
+
}
|
|
84
|
+
catch (cause) {
|
|
85
|
+
throw new MessageStreamingInvalidResultError(fieldName, cause);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function toMessageStreamingMessage(rowInput) {
|
|
89
|
+
if (!isRecord(rowInput)) {
|
|
90
|
+
throw new MessageStreamingInvalidResultError('row');
|
|
91
|
+
}
|
|
92
|
+
const id = requireNonEmptyString('id', readField(rowInput, ['id']));
|
|
93
|
+
const streamName = requireNonEmptyString('stream_name', readField(rowInput, ['stream_name', 'streamName']));
|
|
94
|
+
const messageType = requireNonEmptyString('type', readField(rowInput, ['type']));
|
|
95
|
+
const position = parseBigIntField('position', readField(rowInput, ['position']));
|
|
96
|
+
const globalPosition = parseBigIntField('global_position', readField(rowInput, ['global_position', 'globalPosition']));
|
|
97
|
+
const data = parseJsonField('data', readField(rowInput, ['data']));
|
|
98
|
+
const metadata = parseJsonField('metadata', readField(rowInput, ['metadata']));
|
|
99
|
+
const time = parseInstantField('time', readField(rowInput, ['time']));
|
|
100
|
+
return {
|
|
101
|
+
id,
|
|
102
|
+
streamName,
|
|
103
|
+
type: messageType,
|
|
104
|
+
position,
|
|
105
|
+
globalPosition,
|
|
106
|
+
data,
|
|
107
|
+
metadata,
|
|
108
|
+
time,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function extractRows(rawResult) {
|
|
112
|
+
if (isRecord(rawResult)) {
|
|
113
|
+
const rows = rawResult.rows;
|
|
114
|
+
if (Array.isArray(rows)) {
|
|
115
|
+
return rows;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (Array.isArray(rawResult)) {
|
|
119
|
+
if (rawResult.length === 0 || !Array.isArray(rawResult[0])) {
|
|
120
|
+
return rawResult;
|
|
121
|
+
}
|
|
122
|
+
const [rows] = rawResult;
|
|
123
|
+
if (Array.isArray(rows)) {
|
|
124
|
+
return rows;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
function serializeJson(fieldName, value) {
|
|
130
|
+
try {
|
|
131
|
+
const serialized = JSON.stringify(value);
|
|
132
|
+
if (serialized === undefined) {
|
|
133
|
+
throw new TypeError(`${fieldName} must be JSON-serializable`);
|
|
134
|
+
}
|
|
135
|
+
return serialized;
|
|
136
|
+
}
|
|
137
|
+
catch (cause) {
|
|
138
|
+
throw new TypeError(`${fieldName} must be JSON-serializable`, { cause });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function assertValidSchemaIdentifier(schema) {
|
|
142
|
+
if (!SQL_IDENTIFIER_PATTERN.test(schema)) {
|
|
143
|
+
throw new TypeError('schema must be a valid SQL identifier');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
export class KnexMessageStreaming {
|
|
147
|
+
em;
|
|
148
|
+
schema;
|
|
149
|
+
constructor(em, options = {}) {
|
|
150
|
+
this.em = em;
|
|
151
|
+
const schema = options.schema ?? DEFAULT_SCHEMA;
|
|
152
|
+
assertValidSchemaIdentifier(schema);
|
|
153
|
+
this.schema = schema;
|
|
154
|
+
}
|
|
155
|
+
async writeMessage(input) {
|
|
156
|
+
const id = requireNonEmptyString('id', input.id);
|
|
157
|
+
const streamName = requireNonEmptyString('streamName', input.streamName);
|
|
158
|
+
const type = requireNonEmptyString('type', input.type);
|
|
159
|
+
const dataJson = serializeJson('data', input.data);
|
|
160
|
+
const metadataJson = input.metadata == null ? null : serializeJson('metadata', input.metadata);
|
|
161
|
+
const rows = await this.queryRows(`select ${this.schema}.write_message(?, ?, ?, ?::jsonb, ?::jsonb, ?::bigint) as write_message`, [id, streamName, type, dataJson, metadataJson, toPgBigInt(input.expectedVersion ?? null)], 'writeMessage');
|
|
162
|
+
return parseBigIntField('write_message', rows[0]?.write_message);
|
|
163
|
+
}
|
|
164
|
+
async getStreamMessages(input) {
|
|
165
|
+
const streamName = requireNonEmptyString('streamName', input.streamName);
|
|
166
|
+
const position = input.position ?? MESSAGE_STREAMING_DEFAULT_POSITION;
|
|
167
|
+
const batchSize = input.batchSize ?? MESSAGE_STREAMING_DEFAULT_BATCH_SIZE;
|
|
168
|
+
const rows = await this.queryRows(`select * from ${this.schema}.get_stream_messages(?, ?::bigint, ?::bigint, ?)`, [streamName, toPgBigInt(position), toPgBigInt(batchSize), input.condition ?? null], 'getStreamMessages');
|
|
169
|
+
return rows.map((row) => toMessageStreamingMessage(row));
|
|
170
|
+
}
|
|
171
|
+
async getCategoryMessages(input) {
|
|
172
|
+
const category = requireNonEmptyString('category', input.category);
|
|
173
|
+
const position = input.position ?? MESSAGE_STREAMING_DEFAULT_POSITION;
|
|
174
|
+
const batchSize = input.batchSize ?? MESSAGE_STREAMING_DEFAULT_BATCH_SIZE;
|
|
175
|
+
const rows = await this.queryRows(`select * from ${this.schema}.get_category_messages(?, ?::bigint, ?::bigint, ?, ?::bigint, ?::bigint, ?)`, [
|
|
176
|
+
category,
|
|
177
|
+
toPgBigInt(position),
|
|
178
|
+
toPgBigInt(batchSize),
|
|
179
|
+
input.correlation ?? null,
|
|
180
|
+
toPgBigInt(input.consumerGroupMember ?? null),
|
|
181
|
+
toPgBigInt(input.consumerGroupSize ?? null),
|
|
182
|
+
input.condition ?? null,
|
|
183
|
+
], 'getCategoryMessages');
|
|
184
|
+
return rows.map((row) => toMessageStreamingMessage(row));
|
|
185
|
+
}
|
|
186
|
+
async getLastStreamMessage(input) {
|
|
187
|
+
const streamName = requireNonEmptyString('streamName', input.streamName);
|
|
188
|
+
const rows = input.type
|
|
189
|
+
? await this.queryRows(`select * from ${this.schema}.get_last_stream_message(?, ?)`, [streamName, input.type], 'getLastStreamMessage')
|
|
190
|
+
: await this.queryRows(`select * from ${this.schema}.get_last_stream_message(?)`, [streamName], 'getLastStreamMessage');
|
|
191
|
+
const row = rows[0];
|
|
192
|
+
return row ? toMessageStreamingMessage(row) : null;
|
|
193
|
+
}
|
|
194
|
+
async streamVersion(streamNameInput) {
|
|
195
|
+
const streamName = requireNonEmptyString('streamName', streamNameInput);
|
|
196
|
+
const rows = await this.queryRows(`select ${this.schema}.stream_version(?) as stream_version`, [streamName], 'streamVersion');
|
|
197
|
+
const streamVersion = rows[0]?.stream_version;
|
|
198
|
+
if (streamVersion == null) {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
return parseBigIntField('stream_version', streamVersion);
|
|
202
|
+
}
|
|
203
|
+
async queryRows(sql, bindings, operation) {
|
|
204
|
+
try {
|
|
205
|
+
const rawResult = await this.em.execute(sql, [...bindings], 'all');
|
|
206
|
+
return extractRows(rawResult);
|
|
207
|
+
}
|
|
208
|
+
catch (cause) {
|
|
209
|
+
throw new MessageStreamingQueryError(operation, cause);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=message-streaming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-streaming.js","sourceRoot":"","sources":["../src/message-streaming.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-20260215231000-message-store.d.ts","sourceRoot":"","sources":["../../src/migrations/migration-20260215231000-message-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAEjD,qBAAa,mCAAoC,SAAQ,SAAS;IACjD,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IA0InB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAerC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { Migration } from '@mikro-orm/migrations';
|
|
2
|
+
export class Migration20260215231000MessageStore extends Migration {
|
|
3
|
+
async up() {
|
|
4
|
+
this.addSql('create schema if not exists message_store;');
|
|
5
|
+
this.addSql(`
|
|
6
|
+
create table if not exists message_store.messages (
|
|
7
|
+
id text primary key,
|
|
8
|
+
stream_name text not null,
|
|
9
|
+
type text not null,
|
|
10
|
+
position bigint not null,
|
|
11
|
+
global_position bigserial not null,
|
|
12
|
+
data jsonb not null,
|
|
13
|
+
metadata jsonb,
|
|
14
|
+
time timestamptz not null default clock_timestamp(),
|
|
15
|
+
unique (stream_name, position)
|
|
16
|
+
);
|
|
17
|
+
`);
|
|
18
|
+
this.addSql(`
|
|
19
|
+
create or replace function message_store.write_message(
|
|
20
|
+
p_id varchar,
|
|
21
|
+
p_stream_name varchar,
|
|
22
|
+
p_type varchar,
|
|
23
|
+
p_data jsonb,
|
|
24
|
+
p_metadata jsonb default null,
|
|
25
|
+
p_expected_version bigint default null
|
|
26
|
+
)
|
|
27
|
+
returns bigint
|
|
28
|
+
language plpgsql
|
|
29
|
+
as $$
|
|
30
|
+
declare
|
|
31
|
+
current_version bigint;
|
|
32
|
+
next_position bigint;
|
|
33
|
+
begin
|
|
34
|
+
select max(m.position)
|
|
35
|
+
into current_version
|
|
36
|
+
from message_store.messages m
|
|
37
|
+
where m.stream_name = p_stream_name;
|
|
38
|
+
|
|
39
|
+
if current_version is null then
|
|
40
|
+
current_version := -1;
|
|
41
|
+
end if;
|
|
42
|
+
|
|
43
|
+
if p_expected_version is not null and current_version <> p_expected_version then
|
|
44
|
+
raise exception 'Wrong expected version. expected %, actual %', p_expected_version, current_version;
|
|
45
|
+
end if;
|
|
46
|
+
|
|
47
|
+
next_position := current_version + 1;
|
|
48
|
+
|
|
49
|
+
insert into message_store.messages (id, stream_name, type, position, data, metadata)
|
|
50
|
+
values (p_id, p_stream_name, p_type, next_position, p_data, p_metadata);
|
|
51
|
+
|
|
52
|
+
return next_position;
|
|
53
|
+
end;
|
|
54
|
+
$$;
|
|
55
|
+
`);
|
|
56
|
+
this.addSql(`
|
|
57
|
+
create or replace function message_store.get_stream_messages(
|
|
58
|
+
p_stream_name varchar,
|
|
59
|
+
p_position bigint default 0,
|
|
60
|
+
p_batch_size bigint default 1000,
|
|
61
|
+
p_condition varchar default null
|
|
62
|
+
)
|
|
63
|
+
returns setof message_store.messages
|
|
64
|
+
language sql
|
|
65
|
+
stable
|
|
66
|
+
as $$
|
|
67
|
+
select m.*
|
|
68
|
+
from message_store.messages m
|
|
69
|
+
where m.stream_name = p_stream_name
|
|
70
|
+
and m.position >= p_position
|
|
71
|
+
and (p_condition is null or m.type = p_condition)
|
|
72
|
+
order by m.position asc
|
|
73
|
+
limit p_batch_size;
|
|
74
|
+
$$;
|
|
75
|
+
`);
|
|
76
|
+
this.addSql(`
|
|
77
|
+
create or replace function message_store.get_category_messages(
|
|
78
|
+
p_category varchar,
|
|
79
|
+
p_position bigint default 0,
|
|
80
|
+
p_batch_size bigint default 1000,
|
|
81
|
+
p_correlation varchar default null,
|
|
82
|
+
p_consumer_group_member bigint default null,
|
|
83
|
+
p_consumer_group_size bigint default null,
|
|
84
|
+
p_condition varchar default null
|
|
85
|
+
)
|
|
86
|
+
returns setof message_store.messages
|
|
87
|
+
language sql
|
|
88
|
+
stable
|
|
89
|
+
as $$
|
|
90
|
+
select m.*
|
|
91
|
+
from message_store.messages m
|
|
92
|
+
where split_part(m.stream_name, '-', 1) = p_category
|
|
93
|
+
and m.global_position >= p_position
|
|
94
|
+
and (p_correlation is null or coalesce(m.metadata ->> 'correlation', '') = p_correlation)
|
|
95
|
+
and (
|
|
96
|
+
p_consumer_group_member is null
|
|
97
|
+
or p_consumer_group_size is null
|
|
98
|
+
or mod(m.global_position, p_consumer_group_size) = p_consumer_group_member
|
|
99
|
+
)
|
|
100
|
+
and (p_condition is null or m.type = p_condition)
|
|
101
|
+
order by m.global_position asc
|
|
102
|
+
limit p_batch_size;
|
|
103
|
+
$$;
|
|
104
|
+
`);
|
|
105
|
+
this.addSql(`
|
|
106
|
+
create or replace function message_store.get_last_stream_message(
|
|
107
|
+
p_stream_name varchar,
|
|
108
|
+
p_type varchar default null
|
|
109
|
+
)
|
|
110
|
+
returns setof message_store.messages
|
|
111
|
+
language sql
|
|
112
|
+
stable
|
|
113
|
+
as $$
|
|
114
|
+
select m.*
|
|
115
|
+
from message_store.messages m
|
|
116
|
+
where m.stream_name = p_stream_name
|
|
117
|
+
and (p_type is null or m.type = p_type)
|
|
118
|
+
order by m.position desc
|
|
119
|
+
limit 1;
|
|
120
|
+
$$;
|
|
121
|
+
`);
|
|
122
|
+
this.addSql(`
|
|
123
|
+
create or replace function message_store.stream_version(p_stream_name varchar)
|
|
124
|
+
returns bigint
|
|
125
|
+
language sql
|
|
126
|
+
stable
|
|
127
|
+
as $$
|
|
128
|
+
select max(m.position)
|
|
129
|
+
from message_store.messages m
|
|
130
|
+
where m.stream_name = p_stream_name;
|
|
131
|
+
$$;
|
|
132
|
+
`);
|
|
133
|
+
}
|
|
134
|
+
async down() {
|
|
135
|
+
this.addSql('drop function if exists message_store.stream_version(varchar);');
|
|
136
|
+
this.addSql('drop function if exists message_store.get_last_stream_message(varchar, varchar);');
|
|
137
|
+
this.addSql('drop function if exists message_store.get_category_messages(varchar, bigint, bigint, varchar, bigint, bigint, varchar);');
|
|
138
|
+
this.addSql('drop function if exists message_store.get_stream_messages(varchar, bigint, bigint, varchar);');
|
|
139
|
+
this.addSql('drop function if exists message_store.write_message(varchar, varchar, varchar, jsonb, jsonb, bigint);');
|
|
140
|
+
this.addSql('drop table if exists message_store.messages;');
|
|
141
|
+
this.addSql('drop schema if exists message_store;');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=migration-20260215231000-message-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-20260215231000-message-store.js","sourceRoot":"","sources":["../../src/migrations/migration-20260215231000-message-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAEjD,MAAM,OAAO,mCAAoC,SAAQ,SAAS;IACvD,KAAK,CAAC,EAAE;QACf,IAAI,CAAC,MAAM,CAAC,4CAA4C,CAAC,CAAA;QAEzD,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;KAYX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqCX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;KAmBX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4BX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;KAgBX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;KAUX,CAAC,CAAA;IACJ,CAAC;IAEQ,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,MAAM,CAAC,gEAAgE,CAAC,CAAA;QAC7E,IAAI,CAAC,MAAM,CAAC,kFAAkF,CAAC,CAAA;QAC/F,IAAI,CAAC,MAAM,CACT,yHAAyH,CAC1H,CAAA;QACD,IAAI,CAAC,MAAM,CACT,8FAA8F,CAC/F,CAAA;QACD,IAAI,CAAC,MAAM,CACT,uGAAuG,CACxG,CAAA;QACD,IAAI,CAAC,MAAM,CAAC,8CAA8C,CAAC,CAAA;QAC3D,IAAI,CAAC,MAAM,CAAC,sCAAsC,CAAC,CAAA;IACrD,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@thangnv-dev/message-streaming-mikroorm-node",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc -p tsconfig.build.json",
|
|
22
|
+
"lint": "eslint .",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"test": "vitest run"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@thangnv-dev/error-common": "workspace:^",
|
|
28
|
+
"@thangnv-dev/message-streaming-node": "workspace:^"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@mikro-orm/core": "^6.6.7",
|
|
32
|
+
"@mikro-orm/knex": "^6.6.7",
|
|
33
|
+
"@mikro-orm/migrations": "^6.6.7",
|
|
34
|
+
"@mikro-orm/postgresql": "^6.6.7",
|
|
35
|
+
"@thangnv-dev/mikroorm-nest": "workspace:^",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
37
|
+
"@typescript-eslint/parser": "^8.56.0",
|
|
38
|
+
"eslint": "^10.0.0",
|
|
39
|
+
"pg": "^8.18.0",
|
|
40
|
+
"temporal-polyfill": "^0.3.0",
|
|
41
|
+
"typescript": "^5.9.3",
|
|
42
|
+
"vitest": "^4.0.18"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@mikro-orm/knex": "^6.6.6",
|
|
46
|
+
"@mikro-orm/migrations": "^6.6.6",
|
|
47
|
+
"temporal-polyfill": "*"
|
|
48
|
+
}
|
|
49
|
+
}
|