@simplysm/service-common 14.0.86 → 14.0.88
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/protocol/create-service-protocol.d.ts +33 -1
- package/dist/protocol/create-service-protocol.d.ts.map +1 -1
- package/dist/protocol/create-service-protocol.js +26 -12
- package/dist/protocol/create-service-protocol.js.map +1 -1
- package/package.json +3 -3
- package/src/protocol/create-service-protocol.ts +56 -12
|
@@ -19,7 +19,23 @@ export interface ServiceProtocol {
|
|
|
19
19
|
totalSize: number;
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* 청크 패킷을 누적한다 (재조립 전용, stateful).
|
|
23
|
+
*
|
|
24
|
+
* 한 메시지(uuid)의 모든 청크를 동일 누적기에 모은다. 아직 미완성이면 `progress`,
|
|
25
|
+
* 모든 청크가 도착하면 재조립된 raw 바이트를 담은 `complete` 를 반환한다.
|
|
26
|
+
* JSON 파싱은 수행하지 않는다 (파싱은 {@link parseMessage} 가 담당).
|
|
27
|
+
*/
|
|
28
|
+
accumulate(bytes: Bytes): ServiceAccumulateResult;
|
|
29
|
+
/**
|
|
30
|
+
* 재조립 완료된 raw 바이트를 메시지로 파싱한다 (stateless).
|
|
31
|
+
*
|
|
32
|
+
* 누적기 상태에 의존하지 않으므로 worker 등 다른 실행 컨텍스트에 위임할 수 있다.
|
|
33
|
+
*/
|
|
34
|
+
parseMessage(resultBytes: Bytes): ServiceMessage;
|
|
35
|
+
/**
|
|
36
|
+
* 메시지를 디코딩한다 (청크 패킷 자동 재조립).
|
|
37
|
+
*
|
|
38
|
+
* {@link accumulate} 로 누적한 뒤 완료 시 {@link parseMessage} 로 파싱하는 통합 동작이다.
|
|
23
39
|
*/
|
|
24
40
|
decode<T extends ServiceMessage>(bytes: Bytes): ServiceMessageDecodeResult<T>;
|
|
25
41
|
/**
|
|
@@ -46,6 +62,22 @@ export type ServiceMessageDecodeResult<TMessage extends ServiceMessage> = {
|
|
|
46
62
|
totalSize: number;
|
|
47
63
|
completedSize: number;
|
|
48
64
|
};
|
|
65
|
+
/**
|
|
66
|
+
* 청크 누적({@link ServiceProtocol.accumulate}) 결과 타입 (유니언)
|
|
67
|
+
*
|
|
68
|
+
* - `type: "complete"`: 모든 청크를 수신하여 재조립이 완료됨 (파싱 전 raw 바이트)
|
|
69
|
+
* - `type: "progress"`: 청크 메시지 진행 중 (일부 청크만 도착)
|
|
70
|
+
*/
|
|
71
|
+
export type ServiceAccumulateResult = {
|
|
72
|
+
type: "complete";
|
|
73
|
+
uuid: string;
|
|
74
|
+
resultBytes: Bytes;
|
|
75
|
+
} | {
|
|
76
|
+
type: "progress";
|
|
77
|
+
uuid: string;
|
|
78
|
+
totalSize: number;
|
|
79
|
+
completedSize: number;
|
|
80
|
+
};
|
|
49
81
|
/**
|
|
50
82
|
* 서비스 프로토콜 인코더/디코더를 생성한다
|
|
51
83
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-service-protocol.d.ts","sourceRoot":"","sources":["../../src/protocol/create-service-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,uBAAuB,CAAC;AAQ/B,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAExE;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG;QAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAEtF
|
|
1
|
+
{"version":3,"file":"create-service-protocol.d.ts","sourceRoot":"","sources":["../../src/protocol/create-service-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,uBAAuB,CAAC;AAQ/B,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAExE;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG;QAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAEtF;;;;;;OAMG;IACH,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,uBAAuB,CAAC;IAElD;;;;OAIG;IACH,YAAY,CAAC,WAAW,EAAE,KAAK,GAAG,cAAc,CAAC;IAEjD;;;;OAIG;IACH,MAAM,CAAC,CAAC,SAAS,cAAc,EAAE,KAAK,EAAE,KAAK,GAAG,0BAA0B,CAAC,CAAC,CAAC,CAAC;IAE9E;;;;;OAKG;IACH,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,CAAC,QAAQ,SAAS,cAAc,IAClE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjF;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,KAAK,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjF;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAqMvD"}
|
|
@@ -77,7 +77,7 @@ export function createServiceProtocol() {
|
|
|
77
77
|
}
|
|
78
78
|
return { chunks, totalSize };
|
|
79
79
|
},
|
|
80
|
-
|
|
80
|
+
accumulate(bytes) {
|
|
81
81
|
if (bytes.length < 28) {
|
|
82
82
|
throw new ArgumentError("버퍼 크기가 헤더 크기보다 작습니다.", {
|
|
83
83
|
bufferSize: bytes.length,
|
|
@@ -121,20 +121,10 @@ export function createServiceProtocol() {
|
|
|
121
121
|
else if (accItem.completedSize === accItem.totalSize) {
|
|
122
122
|
accumulator.delete(uuid); // 메모리 해제
|
|
123
123
|
const resultBytes = bytesU.concat(accItem.chunks.filterExists());
|
|
124
|
-
let messageArr;
|
|
125
|
-
try {
|
|
126
|
-
messageArr = json.parse(new TextDecoder().decode(resultBytes));
|
|
127
|
-
}
|
|
128
|
-
catch (err) {
|
|
129
|
-
throw new ArgumentError("메시지 디코딩에 실패했습니다.", { uuid, cause: err });
|
|
130
|
-
}
|
|
131
124
|
return {
|
|
132
125
|
type: "complete",
|
|
133
126
|
uuid: uuid,
|
|
134
|
-
|
|
135
|
-
name: messageArr[0],
|
|
136
|
-
body: messageArr[1],
|
|
137
|
-
},
|
|
127
|
+
resultBytes,
|
|
138
128
|
};
|
|
139
129
|
}
|
|
140
130
|
else {
|
|
@@ -146,6 +136,30 @@ export function createServiceProtocol() {
|
|
|
146
136
|
});
|
|
147
137
|
}
|
|
148
138
|
},
|
|
139
|
+
parseMessage(resultBytes) {
|
|
140
|
+
let messageArr;
|
|
141
|
+
try {
|
|
142
|
+
messageArr = json.parse(new TextDecoder().decode(resultBytes));
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
throw new ArgumentError("메시지 디코딩에 실패했습니다.", { cause: err });
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
name: messageArr[0],
|
|
149
|
+
body: messageArr[1],
|
|
150
|
+
};
|
|
151
|
+
},
|
|
152
|
+
decode(bytes) {
|
|
153
|
+
const acc = this.accumulate(bytes);
|
|
154
|
+
if (acc.type === "progress") {
|
|
155
|
+
return acc;
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
type: "complete",
|
|
159
|
+
uuid: acc.uuid,
|
|
160
|
+
message: this.parseMessage(acc.resultBytes),
|
|
161
|
+
};
|
|
162
|
+
},
|
|
149
163
|
dispose() {
|
|
150
164
|
accumulator.dispose();
|
|
151
165
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-service-protocol.js","sourceRoot":"","sources":["../../src/protocol/create-service-protocol.ts"],"names":[],"mappings":"AACA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,KAAK,IAAI,MAAM,EACf,IAAI,EACJ,SAAS,EACT,IAAI,GACL,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAuB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"create-service-protocol.js","sourceRoot":"","sources":["../../src/protocol/create-service-protocol.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/service-common",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.88",
|
|
4
4
|
"description": "심플리즘 패키지 - 서비스 (common)",
|
|
5
5
|
"author": "심플리즘",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"@types/node": "^20.19.41"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@simplysm/core-common": "14.0.
|
|
25
|
-
"@simplysm/orm-common": "14.0.
|
|
24
|
+
"@simplysm/core-common": "14.0.88",
|
|
25
|
+
"@simplysm/orm-common": "14.0.88"
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -25,7 +25,25 @@ export interface ServiceProtocol {
|
|
|
25
25
|
encode(uuid: string, message: ServiceMessage): { chunks: Bytes[]; totalSize: number };
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
28
|
+
* 청크 패킷을 누적한다 (재조립 전용, stateful).
|
|
29
|
+
*
|
|
30
|
+
* 한 메시지(uuid)의 모든 청크를 동일 누적기에 모은다. 아직 미완성이면 `progress`,
|
|
31
|
+
* 모든 청크가 도착하면 재조립된 raw 바이트를 담은 `complete` 를 반환한다.
|
|
32
|
+
* JSON 파싱은 수행하지 않는다 (파싱은 {@link parseMessage} 가 담당).
|
|
33
|
+
*/
|
|
34
|
+
accumulate(bytes: Bytes): ServiceAccumulateResult;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 재조립 완료된 raw 바이트를 메시지로 파싱한다 (stateless).
|
|
38
|
+
*
|
|
39
|
+
* 누적기 상태에 의존하지 않으므로 worker 등 다른 실행 컨텍스트에 위임할 수 있다.
|
|
40
|
+
*/
|
|
41
|
+
parseMessage(resultBytes: Bytes): ServiceMessage;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 메시지를 디코딩한다 (청크 패킷 자동 재조립).
|
|
45
|
+
*
|
|
46
|
+
* {@link accumulate} 로 누적한 뒤 완료 시 {@link parseMessage} 로 파싱하는 통합 동작이다.
|
|
29
47
|
*/
|
|
30
48
|
decode<T extends ServiceMessage>(bytes: Bytes): ServiceMessageDecodeResult<T>;
|
|
31
49
|
|
|
@@ -48,6 +66,16 @@ export type ServiceMessageDecodeResult<TMessage extends ServiceMessage> =
|
|
|
48
66
|
| { type: "complete"; uuid: string; message: TMessage }
|
|
49
67
|
| { type: "progress"; uuid: string; totalSize: number; completedSize: number };
|
|
50
68
|
|
|
69
|
+
/**
|
|
70
|
+
* 청크 누적({@link ServiceProtocol.accumulate}) 결과 타입 (유니언)
|
|
71
|
+
*
|
|
72
|
+
* - `type: "complete"`: 모든 청크를 수신하여 재조립이 완료됨 (파싱 전 raw 바이트)
|
|
73
|
+
* - `type: "progress"`: 청크 메시지 진행 중 (일부 청크만 도착)
|
|
74
|
+
*/
|
|
75
|
+
export type ServiceAccumulateResult =
|
|
76
|
+
| { type: "complete"; uuid: string; resultBytes: Bytes }
|
|
77
|
+
| { type: "progress"; uuid: string; totalSize: number; completedSize: number };
|
|
78
|
+
|
|
51
79
|
/**
|
|
52
80
|
* 서비스 프로토콜 인코더/디코더를 생성한다
|
|
53
81
|
*
|
|
@@ -159,7 +187,7 @@ export function createServiceProtocol(): ServiceProtocol {
|
|
|
159
187
|
return { chunks, totalSize };
|
|
160
188
|
},
|
|
161
189
|
|
|
162
|
-
|
|
190
|
+
accumulate(bytes: Bytes): ServiceAccumulateResult {
|
|
163
191
|
if (bytes.length < 28) {
|
|
164
192
|
throw new ArgumentError("버퍼 크기가 헤더 크기보다 작습니다.", {
|
|
165
193
|
bufferSize: bytes.length,
|
|
@@ -210,19 +238,10 @@ export function createServiceProtocol(): ServiceProtocol {
|
|
|
210
238
|
accumulator.delete(uuid); // 메모리 해제
|
|
211
239
|
|
|
212
240
|
const resultBytes = bytesU.concat(accItem.chunks.filterExists());
|
|
213
|
-
let messageArr: [string, unknown];
|
|
214
|
-
try {
|
|
215
|
-
messageArr = json.parse<[string, unknown]>(new TextDecoder().decode(resultBytes));
|
|
216
|
-
} catch (err) {
|
|
217
|
-
throw new ArgumentError("메시지 디코딩에 실패했습니다.", { uuid, cause: err });
|
|
218
|
-
}
|
|
219
241
|
return {
|
|
220
242
|
type: "complete",
|
|
221
243
|
uuid: uuid,
|
|
222
|
-
|
|
223
|
-
name: messageArr[0],
|
|
224
|
-
body: messageArr[1],
|
|
225
|
-
} as T,
|
|
244
|
+
resultBytes,
|
|
226
245
|
};
|
|
227
246
|
} else {
|
|
228
247
|
accumulator.delete(uuid);
|
|
@@ -234,6 +253,31 @@ export function createServiceProtocol(): ServiceProtocol {
|
|
|
234
253
|
}
|
|
235
254
|
},
|
|
236
255
|
|
|
256
|
+
parseMessage(resultBytes: Bytes): ServiceMessage {
|
|
257
|
+
let messageArr: [string, unknown];
|
|
258
|
+
try {
|
|
259
|
+
messageArr = json.parse<[string, unknown]>(new TextDecoder().decode(resultBytes));
|
|
260
|
+
} catch (err) {
|
|
261
|
+
throw new ArgumentError("메시지 디코딩에 실패했습니다.", { cause: err });
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
name: messageArr[0],
|
|
265
|
+
body: messageArr[1],
|
|
266
|
+
} as ServiceMessage;
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
decode<T extends ServiceMessage>(bytes: Bytes): ServiceMessageDecodeResult<T> {
|
|
270
|
+
const acc = this.accumulate(bytes);
|
|
271
|
+
if (acc.type === "progress") {
|
|
272
|
+
return acc;
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
type: "complete",
|
|
276
|
+
uuid: acc.uuid,
|
|
277
|
+
message: this.parseMessage(acc.resultBytes) as T,
|
|
278
|
+
};
|
|
279
|
+
},
|
|
280
|
+
|
|
237
281
|
dispose(): void {
|
|
238
282
|
accumulator.dispose();
|
|
239
283
|
},
|