@simplysm/service-common 13.0.100 → 14.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.
Files changed (46) hide show
  1. package/dist/define-event.d.ts +7 -7
  2. package/dist/define-event.d.ts.map +1 -1
  3. package/dist/define-event.js +21 -10
  4. package/dist/define-event.js.map +1 -6
  5. package/dist/index.d.ts +0 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +5 -2
  8. package/dist/index.js.map +1 -6
  9. package/dist/protocol/create-service-protocol.d.ts +20 -20
  10. package/dist/protocol/create-service-protocol.d.ts.map +1 -1
  11. package/dist/protocol/create-service-protocol.js +149 -112
  12. package/dist/protocol/create-service-protocol.js.map +1 -6
  13. package/dist/protocol/protocol.types.d.ts +17 -17
  14. package/dist/protocol/protocol.types.d.ts.map +1 -1
  15. package/dist/protocol/protocol.types.js +16 -15
  16. package/dist/protocol/protocol.types.js.map +1 -6
  17. package/dist/service-types/auto-update-service.types.d.ts +5 -5
  18. package/dist/service-types/auto-update-service.types.js +2 -1
  19. package/dist/service-types/auto-update-service.types.js.map +1 -6
  20. package/dist/service-types/orm-service.types.d.ts +7 -5
  21. package/dist/service-types/orm-service.types.d.ts.map +1 -1
  22. package/dist/service-types/orm-service.types.js +2 -1
  23. package/dist/service-types/orm-service.types.js.map +1 -6
  24. package/dist/types.d.ts +5 -5
  25. package/dist/types.d.ts.map +1 -1
  26. package/dist/types.js +2 -1
  27. package/dist/types.js.map +1 -6
  28. package/package.json +6 -8
  29. package/src/define-event.ts +7 -7
  30. package/src/index.ts +4 -6
  31. package/src/protocol/create-service-protocol.ts +45 -38
  32. package/src/protocol/protocol.types.ts +39 -39
  33. package/src/service-types/auto-update-service.types.ts +5 -5
  34. package/src/service-types/orm-service.types.ts +5 -5
  35. package/src/types.ts +5 -5
  36. package/README.md +0 -111
  37. package/dist/service-types/smtp-client-service.types.d.ts +0 -38
  38. package/dist/service-types/smtp-client-service.types.d.ts.map +0 -1
  39. package/dist/service-types/smtp-client-service.types.js +0 -1
  40. package/dist/service-types/smtp-client-service.types.js.map +0 -6
  41. package/docs/events.md +0 -51
  42. package/docs/protocol.md +0 -252
  43. package/docs/service-types.md +0 -162
  44. package/src/service-types/smtp-client-service.types.ts +0 -41
  45. package/tests/define-event.spec.ts +0 -11
  46. package/tests/protocol/service-protocol.spec.ts +0 -251
@@ -1,41 +0,0 @@
1
- export interface SmtpClientSendAttachment {
2
- filename: string;
3
- content?: string | Uint8Array;
4
- path?: any;
5
- contentType?: string;
6
- }
7
-
8
- export interface SmtpClientSendByDefaultOption {
9
- to: string;
10
- cc?: string;
11
- bcc?: string;
12
- subject: string;
13
- html: string;
14
- attachments?: SmtpClientSendAttachment[];
15
- }
16
-
17
- export interface SmtpClientSendOption {
18
- host: string;
19
- port?: number;
20
- secure?: boolean;
21
- user?: string;
22
- pass?: string;
23
-
24
- from: string;
25
- to: string;
26
- cc?: string;
27
- bcc?: string;
28
- subject: string;
29
- html: string;
30
- attachments?: SmtpClientSendAttachment[];
31
- }
32
-
33
- export interface SmtpClientDefaultOptions {
34
- senderName: string;
35
- senderEmail?: string;
36
- user?: string;
37
- pass?: string;
38
- host: string;
39
- port?: number;
40
- secure?: boolean;
41
- }
@@ -1,11 +0,0 @@
1
- // packages/service-common/tests/define-event.spec.ts
2
- import { describe, it, expect } from "vitest";
3
- import { defineEvent } from "@simplysm/service-common";
4
-
5
- describe("defineEvent", () => {
6
- it("create event definition with given name", () => {
7
- const evt = defineEvent<{ channel: string }, string>("OrderUpdated");
8
- expect(evt.eventName).toBe("OrderUpdated");
9
- });
10
-
11
- });
@@ -1,251 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
- import { createServiceProtocol, type ServiceProtocol } from "../../src/protocol/create-service-protocol";
3
- import type { ServiceMessage } from "../../src/protocol/protocol.types";
4
- import { Uuid } from "@simplysm/core-common";
5
-
6
- describe("ServiceProtocol", () => {
7
- let protocol: ServiceProtocol;
8
-
9
- beforeEach(() => {
10
- protocol = createServiceProtocol();
11
- });
12
-
13
- afterEach(() => {
14
- protocol.dispose();
15
- });
16
-
17
- describe("Encoding", () => {
18
- it("encode single message", () => {
19
- const uuid = Uuid.generate().toString();
20
- const message: ServiceMessage = { name: "test.method", body: [{ test: "data" }] };
21
-
22
- const result = protocol.encode(uuid, message);
23
-
24
- expect(result.chunks.length).toBe(1);
25
- expect(result.totalSize).toBeGreaterThan(0);
26
- });
27
-
28
- it("throw error when message exceeds 100MB", () => {
29
- const uuid = Uuid.generate().toString();
30
- // Generate data larger than 100MB
31
- const largeData = "x".repeat(101 * 1024 * 1024);
32
- const message: ServiceMessage = { name: "test.method", body: [largeData] };
33
-
34
- expect(() => protocol.encode(uuid, message)).toThrow("Message size exceeds the limit.");
35
- });
36
- });
37
-
38
- describe("Decoding", () => {
39
- it("decode single message", () => {
40
- const uuid = Uuid.generate().toString();
41
- const message: ServiceMessage = { name: "test.method", body: [{ value: 123 }] };
42
-
43
- const encoded = protocol.encode(uuid, message);
44
- const result = protocol.decode(encoded.chunks[0]);
45
-
46
- expect(result.type).toBe("complete");
47
- if (result.type === "complete") {
48
- expect(result.message.name).toBe("test.method");
49
- expect(result.message.body).toEqual([{ value: 123 }]);
50
- }
51
- });
52
-
53
- it("throw error when buffer size is smaller than header size", () => {
54
- const smallBytes = new Uint8Array(20);
55
-
56
- expect(() => protocol.decode(smallBytes)).toThrow("Buffer size is smaller than header size.");
57
- });
58
-
59
- it("throw error when decoded message exceeds 100MB", () => {
60
- // Manually create header with totalSize exceeding 100MB
61
- const headerBytes = new Uint8Array(28);
62
- const uuidBytes = new Uuid(Uuid.generate().toString()).toBytes();
63
- headerBytes.set(uuidBytes, 0);
64
-
65
- const headerView = new DataView(
66
- headerBytes.buffer,
67
- headerBytes.byteOffset,
68
- headerBytes.byteLength,
69
- );
70
- headerView.setBigUint64(16, BigInt(101 * 1024 * 1024), false); // 101MB
71
- headerView.setUint32(24, 0, false);
72
-
73
- expect(() => protocol.decode(headerBytes)).toThrow("Message size exceeds the limit.");
74
- });
75
- });
76
-
77
- describe("Chunking", () => {
78
- it("chunk message larger than 3MB", () => {
79
- const uuid = Uuid.generate().toString();
80
- // Create 4MB data
81
- const largeData = "x".repeat(4 * 1024 * 1024);
82
- const message: ServiceMessage = { name: "test.method", body: [largeData] };
83
-
84
- const result = protocol.encode(uuid, message);
85
-
86
- expect(result.chunks.length).toBeGreaterThan(1);
87
- });
88
-
89
- it("assemble chunked message in order", () => {
90
- const uuid = Uuid.generate().toString();
91
- // 4MB data
92
- const largeData = "x".repeat(4 * 1024 * 1024);
93
- const message: ServiceMessage = { name: "test.method", body: [largeData] };
94
-
95
- const encoded = protocol.encode(uuid, message);
96
- expect(encoded.chunks.length).toBeGreaterThan(1);
97
-
98
- // Decode chunks in order
99
- let result!: ReturnType<typeof protocol.decode>;
100
- for (let i = 0; i < encoded.chunks.length; i++) {
101
- result = protocol.decode(encoded.chunks[i]);
102
- if (i < encoded.chunks.length - 1) {
103
- expect(result.type).toBe("progress");
104
- }
105
- }
106
-
107
- expect(result.type).toBe("complete");
108
- if (result.type === "complete") {
109
- expect(result.message.body).toEqual([largeData]);
110
- }
111
- });
112
-
113
- it("assemble chunked message in reverse order", () => {
114
- const uuid = Uuid.generate().toString();
115
- // 4MB data
116
- const largeData = "x".repeat(4 * 1024 * 1024);
117
- const message: ServiceMessage = { name: "test.method", body: [largeData] };
118
-
119
- const encoded = protocol.encode(uuid, message);
120
- const reversedChunks = [...encoded.chunks].reverse();
121
-
122
- // Decode in reverse order
123
- let result!: ReturnType<typeof protocol.decode>;
124
- for (let i = 0; i < reversedChunks.length; i++) {
125
- result = protocol.decode(reversedChunks[i]);
126
- }
127
-
128
- // Should complete at the end
129
- expect(result.type).toBe("complete");
130
- if (result.type === "complete") {
131
- expect(result.message.body).toEqual([largeData]);
132
- }
133
- });
134
-
135
- it("prevent duplicate packets", () => {
136
- const uuid = Uuid.generate().toString();
137
- // 4MB data
138
- const largeData = "x".repeat(4 * 1024 * 1024);
139
- const message: ServiceMessage = { name: "test.method", body: [largeData] };
140
-
141
- const encoded = protocol.encode(uuid, message);
142
-
143
- // Send first chunk twice
144
- protocol.decode(encoded.chunks[0]);
145
- const result1 = protocol.decode(encoded.chunks[0]); // Duplicate
146
-
147
- // Should be in progress state, and completedSize should not increase from duplicate
148
- expect(result1.type).toBe("progress");
149
-
150
- // Send remaining chunks
151
- let result!: ReturnType<typeof protocol.decode>;
152
- for (let i = 1; i < encoded.chunks.length; i++) {
153
- result = protocol.decode(encoded.chunks[i]);
154
- }
155
-
156
- expect(result.type).toBe("complete");
157
- if (result.type === "complete") {
158
- expect(result.message.body).toEqual([largeData]);
159
- }
160
- });
161
- });
162
-
163
- describe("UUID interleaving", () => {
164
- it("receive chunks from multiple UUIDs in interleaved order", () => {
165
- const uuid1 = Uuid.generate().toString();
166
- const uuid2 = Uuid.generate().toString();
167
-
168
- // Each with 4MB data to trigger chunking
169
- const largeData1 = "A".repeat(4 * 1024 * 1024);
170
- const largeData2 = "B".repeat(4 * 1024 * 1024);
171
- const message1: ServiceMessage = { name: "test.method1", body: [largeData1] };
172
- const message2: ServiceMessage = { name: "test.method2", body: [largeData2] };
173
-
174
- const encoded1 = protocol.encode(uuid1, message1);
175
- const encoded2 = protocol.encode(uuid2, message2);
176
-
177
- expect(encoded1.chunks.length).toBeGreaterThan(1);
178
- expect(encoded2.chunks.length).toBeGreaterThan(1);
179
-
180
- // Decode chunks in interleaved order (uuid1[0], uuid2[0], uuid1[1], uuid2[1], ...)
181
- const maxChunks = Math.max(encoded1.chunks.length, encoded2.chunks.length);
182
- let result1!: ReturnType<typeof protocol.decode>;
183
- let result2!: ReturnType<typeof protocol.decode>;
184
-
185
- for (let i = 0; i < maxChunks; i++) {
186
- if (i < encoded1.chunks.length) {
187
- result1 = protocol.decode(encoded1.chunks[i]);
188
- }
189
- if (i < encoded2.chunks.length) {
190
- result2 = protocol.decode(encoded2.chunks[i]);
191
- }
192
- }
193
-
194
- // Both messages should complete
195
- expect(result1.type).toBe("complete");
196
- expect(result2.type).toBe("complete");
197
-
198
- if (result1.type === "complete" && result2.type === "complete") {
199
- expect(result1.message.name).toBe("test.method1");
200
- expect(result1.message.body).toEqual([largeData1]);
201
- expect(result2.message.name).toBe("test.method2");
202
- expect(result2.message.body).toEqual([largeData2]);
203
- }
204
- });
205
-
206
- });
207
-
208
- describe("Edge cases", () => {
209
- it("handle null body", () => {
210
- const uuid = Uuid.generate().toString();
211
- const message: ServiceMessage = { name: "test.method", body: [null] };
212
-
213
- const encoded = protocol.encode(uuid, message);
214
- const decoded = protocol.decode(encoded.chunks[0]);
215
-
216
- expect(decoded.type).toBe("complete");
217
- if (decoded.type === "complete") {
218
- // JsonConvert.stringify/parse converts null to undefined
219
- expect(decoded.message.body).toEqual([undefined]);
220
- }
221
- });
222
-
223
- it("handle message at exactly 3MB boundary", () => {
224
- const uuid = Uuid.generate().toString();
225
- // Exactly 3MB
226
- const data = "x".repeat(3 * 1024 * 1024 - 50); // Account for some JSON overhead
227
- const message: ServiceMessage = { name: "test.method", body: [data] };
228
-
229
- const encoded = protocol.encode(uuid, message);
230
- // Messages up to 3MB should not be chunked
231
- expect(encoded.chunks.length).toBe(1);
232
- });
233
-
234
- it("include correct information in progress response", () => {
235
- const uuid = Uuid.generate().toString();
236
- const largeData = "x".repeat(4 * 1024 * 1024);
237
- const message: ServiceMessage = { name: "test.method", body: [largeData] };
238
-
239
- const encoded = protocol.encode(uuid, message);
240
- const result = protocol.decode(encoded.chunks[0]);
241
-
242
- expect(result.type).toBe("progress");
243
- if (result.type === "progress") {
244
- expect(result.uuid).toBe(uuid);
245
- expect(result.totalSize).toBe(encoded.totalSize);
246
- expect(result.completedSize).toBeGreaterThan(0);
247
- expect(result.completedSize).toBeLessThan(result.totalSize);
248
- }
249
- });
250
- });
251
- });