@simplysm/service-common 14.0.85 → 14.0.87
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/define-event.d.ts +6 -6
- package/dist/define-event.js +6 -6
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- 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/define-event.ts +6 -6
- package/src/index.ts +0 -1
- package/src/protocol/create-service-protocol.ts +56 -12
- package/dist/service-types/app-structure-service.types.d.ts +0 -10
- package/dist/service-types/app-structure-service.types.d.ts.map +0 -1
- package/dist/service-types/app-structure-service.types.js +0 -2
- package/dist/service-types/app-structure-service.types.js.map +0 -1
- package/src/service-types/app-structure-service.types.ts +0 -10
package/dist/define-event.d.ts
CHANGED
|
@@ -13,15 +13,15 @@ export interface ServiceEventDef<TInfo = unknown, TData = unknown> {
|
|
|
13
13
|
* 타입 안전한 info와 data를 가진 서비스 이벤트를 정의한다.
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
|
-
* //
|
|
16
|
+
* // 서버·클라이언트 공통 패키지에서 이벤트 정의 + export
|
|
17
17
|
* export const OrderUpdated = defineEvent<{ orderId: number }, { status: string }>("OrderUpdated");
|
|
18
18
|
*
|
|
19
|
-
* // 서버에서 이벤트 발생
|
|
20
|
-
* await server.emitEvent
|
|
19
|
+
* // 서버에서 이벤트 발생 (정의 객체를 그대로 전달, 이름·타입 자동 추론)
|
|
20
|
+
* await server.emitEvent(OrderUpdated, (info) => info.orderId === 123, { status: "shipped" });
|
|
21
21
|
*
|
|
22
|
-
* // 클라이언트에서 구독
|
|
23
|
-
* import
|
|
24
|
-
* await client.addListener
|
|
22
|
+
* // 클라이언트에서 구독
|
|
23
|
+
* import { OrderUpdated } from "@common-package";
|
|
24
|
+
* await client.addListener(OrderUpdated, { orderId: 123 }, async (data) => {
|
|
25
25
|
* console.log(data.status); // typed
|
|
26
26
|
* });
|
|
27
27
|
*/
|
package/dist/define-event.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* 타입 안전한 info와 data를 가진 서비스 이벤트를 정의한다.
|
|
3
3
|
*
|
|
4
4
|
* @example
|
|
5
|
-
* //
|
|
5
|
+
* // 서버·클라이언트 공통 패키지에서 이벤트 정의 + export
|
|
6
6
|
* export const OrderUpdated = defineEvent<{ orderId: number }, { status: string }>("OrderUpdated");
|
|
7
7
|
*
|
|
8
|
-
* // 서버에서 이벤트 발생
|
|
9
|
-
* await server.emitEvent
|
|
8
|
+
* // 서버에서 이벤트 발생 (정의 객체를 그대로 전달, 이름·타입 자동 추론)
|
|
9
|
+
* await server.emitEvent(OrderUpdated, (info) => info.orderId === 123, { status: "shipped" });
|
|
10
10
|
*
|
|
11
|
-
* // 클라이언트에서 구독
|
|
12
|
-
* import
|
|
13
|
-
* await client.addListener
|
|
11
|
+
* // 클라이언트에서 구독
|
|
12
|
+
* import { OrderUpdated } from "@common-package";
|
|
13
|
+
* await client.addListener(OrderUpdated, { orderId: 123 }, async (data) => {
|
|
14
14
|
* console.log(data.status); // typed
|
|
15
15
|
* });
|
|
16
16
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ export * from "./protocol/protocol.types";
|
|
|
2
2
|
export * from "./protocol/create-service-protocol";
|
|
3
3
|
export * from "./service-types/orm-service.types";
|
|
4
4
|
export * from "./service-types/auto-update-service.types";
|
|
5
|
-
export * from "./service-types/app-structure-service.types";
|
|
6
5
|
export * from "./types";
|
|
7
6
|
export * from "./app-structure/app-structure.types";
|
|
8
7
|
export * from "./app-structure/app-structure.utils";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AAGnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AAGnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAE1D,cAAc,SAAS,CAAC;AAGxB,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AAGpD,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,6 @@ export * from "./protocol/create-service-protocol.js";
|
|
|
4
4
|
// 서비스 타입
|
|
5
5
|
export * from "./service-types/orm-service.types.js";
|
|
6
6
|
export * from "./service-types/auto-update-service.types.js";
|
|
7
|
-
export * from "./service-types/app-structure-service.types.js";
|
|
8
7
|
// 타입
|
|
9
8
|
export * from "./types.js";
|
|
10
9
|
// App Structure
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO;AACP,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AAEnD,SAAS;AACT,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO;AACP,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AAEnD,SAAS;AACT,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,KAAK;AACL,cAAc,SAAS,CAAC;AAExB,gBAAgB;AAChB,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AAEpD,KAAK;AACL,cAAc,gBAAgB,CAAC"}
|
|
@@ -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":"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;AAqExE;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB;IACnC,sEAAsE;IACtE,KAAK;IACL,sEAAsE;IAEtE,MAAM,WAAW,GAAG,IAAI,SAAS,CAO/B;QACA,UAAU,EAAE,eAAe,CAAC,WAAW;QACvC,UAAU,EAAE,eAAe,CAAC,WAAW;KACxC,CAAC,CAAC;IAEH,sEAAsE;IACtE,SAAS;IACT,sEAAsE;IAEtE;;;;;;;;;;;OAWG;IACH,SAAS,WAAW,CAClB,MAIC,EACD,SAAiB;QAEjB,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;QAEvC,cAAc;QACd,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QAClD,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAE9B,mCAAmC;QACnC,MAAM,UAAU,GAAG,IAAI,QAAQ,CAC7B,WAAW,CAAC,MAAM,EAClB,WAAW,CAAC,UAAU,EACtB,WAAW,CAAC,UAAU,CACvB,CAAC;QACF,UAAU,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,sCAAsC;QAC1E,UAAU,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,sBAAsB;QACzE,UAAU,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAE9C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,sEAAsE;IACtE,SAAS;IACT,sEAAsE;IAEtE,OAAO;QACL,MAAM,CAAC,IAAY,EAAE,OAAuB;YAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7F,MAAM,QAAQ,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAEnD,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC;YAElC,sBAAsB;YACtB,IAAI,SAAS,GAAG,eAAe,CAAC,cAAc,EAAE,CAAC;gBAC/C,MAAM,IAAI,aAAa,CAAC,qBAAqB,EAAE;oBAC7C,SAAS;oBACT,OAAO,EAAE,eAAe,CAAC,cAAc;iBACxC,CAAC,CAAC;YACL,CAAC;YAED,iBAAiB;YACjB,IAAI,SAAS,IAAI,eAAe,CAAC,kBAAkB,EAAE,CAAC;gBACpD,OAAO,EAAE,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;YACvF,CAAC;YAED,SAAS;YACT,MAAM,MAAM,GAAY,EAAE,CAAC;YAC3B,IAAI,MAAM,GAAG,CAAC,CAAC;YACf,IAAI,KAAK,GAAG,CAAC,CAAC;YAEd,OAAO,MAAM,GAAG,SAAS,EAAE,CAAC;gBAC1B,MAAM,cAAc,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;gBAEtF,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,cAAc,CAAC,CAAC;gBACtE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAEnB,MAAM,IAAI,eAAe,CAAC,UAAU,CAAC;gBACrC,KAAK,EAAE,CAAC;YACV,CAAC;YAED,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC/B,CAAC;QAED,UAAU,CAAC,KAAY;YACrB,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBACtB,MAAM,IAAI,aAAa,CAAC,sBAAsB,EAAE;oBAC9C,UAAU,EAAE,KAAK,CAAC,MAAM;oBACxB,WAAW,EAAE,EAAE;iBAChB,CAAC,CAAC;YACL,CAAC;YAED,WAAW;YAEX,OAAO;YACP,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACxC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;YAElD,oBAAoB;YACpB,MAAM,UAAU,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;YAClF,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,cAAc;YACjE,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YAE9C,sBAAsB;YACtB,IAAI,SAAS,GAAG,eAAe,CAAC,cAAc,EAAE,CAAC;gBAC/C,MAAM,IAAI,aAAa,CAAC,qBAAqB,EAAE;oBAC7C,SAAS;oBACT,OAAO,EAAE,eAAe,CAAC,cAAc;iBACxC,CAAC,CAAC;YACL,CAAC;YAED,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAErC,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;gBACnD,SAAS;gBACT,aAAa,EAAE,CAAC;gBAChB,MAAM,EAAE,EAAE;aACX,CAAC,CAAC,CAAC;YACJ,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;gBAClC,WAAW;gBACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;gBAClC,OAAO,CAAC,aAAa,IAAI,SAAS,CAAC,MAAM,CAAC;YAC5C,CAAC;YAED,IAAI,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;gBAC9C,OAAO;oBACL,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,IAAI;oBACV,SAAS,EAAE,SAAS;oBACpB,aAAa,EAAE,OAAO,CAAC,aAAa;iBACrC,CAAC;YACJ,CAAC;iBAAM,IAAI,OAAO,CAAC,aAAa,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;gBACvD,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;gBAEnC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;gBACjE,OAAO;oBACL,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,IAAI;oBACV,WAAW;iBACZ,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACzB,MAAM,IAAI,aAAa,CAAC,gDAAgD,EAAE;oBACxE,IAAI;oBACJ,aAAa,EAAE,OAAO,CAAC,aAAa;oBACpC,SAAS,EAAE,OAAO,CAAC,SAAS;iBAC7B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,YAAY,CAAC,WAAkB;YAC7B,IAAI,UAA6B,CAAC;YAClC,IAAI,CAAC;gBACH,UAAU,GAAG,IAAI,CAAC,KAAK,CAAoB,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;YACpF,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,IAAI,aAAa,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;gBACnB,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;aACF,CAAC;QACtB,CAAC;QAED,MAAM,CAA2B,KAAY;YAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACnC,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC5B,OAAO,GAAG,CAAC;YACb,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAM;aACjD,CAAC;QACJ,CAAC;QAED,OAAO;YACL,WAAW,CAAC,OAAO,EAAE,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/service-common",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.87",
|
|
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.87",
|
|
25
|
+
"@simplysm/orm-common": "14.0.87"
|
|
26
26
|
}
|
|
27
27
|
}
|
package/src/define-event.ts
CHANGED
|
@@ -14,15 +14,15 @@ export interface ServiceEventDef<TInfo = unknown, TData = unknown> {
|
|
|
14
14
|
* 타입 안전한 info와 data를 가진 서비스 이벤트를 정의한다.
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
17
|
-
* //
|
|
17
|
+
* // 서버·클라이언트 공통 패키지에서 이벤트 정의 + export
|
|
18
18
|
* export const OrderUpdated = defineEvent<{ orderId: number }, { status: string }>("OrderUpdated");
|
|
19
19
|
*
|
|
20
|
-
* // 서버에서 이벤트 발생
|
|
21
|
-
* await server.emitEvent
|
|
20
|
+
* // 서버에서 이벤트 발생 (정의 객체를 그대로 전달, 이름·타입 자동 추론)
|
|
21
|
+
* await server.emitEvent(OrderUpdated, (info) => info.orderId === 123, { status: "shipped" });
|
|
22
22
|
*
|
|
23
|
-
* // 클라이언트에서 구독
|
|
24
|
-
* import
|
|
25
|
-
* await client.addListener
|
|
23
|
+
* // 클라이언트에서 구독
|
|
24
|
+
* import { OrderUpdated } from "@common-package";
|
|
25
|
+
* await client.addListener(OrderUpdated, { orderId: 123 }, async (data) => {
|
|
26
26
|
* console.log(data.status); // typed
|
|
27
27
|
* });
|
|
28
28
|
*/
|
package/src/index.ts
CHANGED
|
@@ -5,7 +5,6 @@ export * from "./protocol/create-service-protocol";
|
|
|
5
5
|
// 서비스 타입
|
|
6
6
|
export * from "./service-types/orm-service.types";
|
|
7
7
|
export * from "./service-types/auto-update-service.types";
|
|
8
|
-
export * from "./service-types/app-structure-service.types";
|
|
9
8
|
// 타입
|
|
10
9
|
export * from "./types";
|
|
11
10
|
|
|
@@ -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
|
},
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { AppStructureItem } from "../app-structure/app-structure.types";
|
|
2
|
-
/**
|
|
3
|
-
* AppStructure 서비스 인터페이스
|
|
4
|
-
*
|
|
5
|
-
* 서버에 등록된 앱 구조 항목을 클라이언트명 기준 맵으로 조회한다.
|
|
6
|
-
*/
|
|
7
|
-
export interface AppStructureService {
|
|
8
|
-
getItems(): Record<string, AppStructureItem[]>;
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=app-structure-service.types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-structure-service.types.d.ts","sourceRoot":"","sources":["../../src/service-types/app-structure-service.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAE7E;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;CAChD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-structure-service.types.js","sourceRoot":"","sources":["../../src/service-types/app-structure-service.types.ts"],"names":[],"mappings":""}
|