@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.
@@ -13,15 +13,15 @@ export interface ServiceEventDef<TInfo = unknown, TData = unknown> {
13
13
  * 타입 안전한 info와 data를 가진 서비스 이벤트를 정의한다.
14
14
  *
15
15
  * @example
16
- * // 서버에서 이벤트 정의 + 타입 export
16
+ * // 서버·클라이언트 공통 패키지에서 이벤트 정의 + export
17
17
  * export const OrderUpdated = defineEvent<{ orderId: number }, { status: string }>("OrderUpdated");
18
18
  *
19
- * // 서버에서 이벤트 발생
20
- * await server.emitEvent<typeof OrderUpdated>("OrderUpdated", (info) => info.orderId === 123, { status: "shipped" });
19
+ * // 서버에서 이벤트 발생 (정의 객체를 그대로 전달, 이름·타입 자동 추론)
20
+ * await server.emitEvent(OrderUpdated, (info) => info.orderId === 123, { status: "shipped" });
21
21
  *
22
- * // 클라이언트에서 구독 (import type으로 타입만 가져옴)
23
- * import type { OrderUpdated } from "@server-package";
24
- * await client.addListener<typeof OrderUpdated>("OrderUpdated", { orderId: 123 }, async (data) => {
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
  */
@@ -2,15 +2,15 @@
2
2
  * 타입 안전한 info와 data를 가진 서비스 이벤트를 정의한다.
3
3
  *
4
4
  * @example
5
- * // 서버에서 이벤트 정의 + 타입 export
5
+ * // 서버·클라이언트 공통 패키지에서 이벤트 정의 + export
6
6
  * export const OrderUpdated = defineEvent<{ orderId: number }, { status: string }>("OrderUpdated");
7
7
  *
8
- * // 서버에서 이벤트 발생
9
- * await server.emitEvent<typeof OrderUpdated>("OrderUpdated", (info) => info.orderId === 123, { status: "shipped" });
8
+ * // 서버에서 이벤트 발생 (정의 객체를 그대로 전달, 이름·타입 자동 추론)
9
+ * await server.emitEvent(OrderUpdated, (info) => info.orderId === 123, { status: "shipped" });
10
10
  *
11
- * // 클라이언트에서 구독 (import type으로 타입만 가져옴)
12
- * import type { OrderUpdated } from "@server-package";
13
- * await client.addListener<typeof OrderUpdated>("OrderUpdated", { orderId: 123 }, async (data) => {
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";
@@ -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;AAC1D,cAAc,6CAA6C,CAAC;AAE5D,cAAc,SAAS,CAAC;AAGxB,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AAGpD,cAAc,gBAAgB,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,cAAc,6CAA6C,CAAC;AAC5D,KAAK;AACL,cAAc,SAAS,CAAC;AAExB,gBAAgB;AAChB,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AAEpD,KAAK;AACL,cAAc,gBAAgB,CAAC"}
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;;OAEG;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;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAqLvD"}
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
- decode(bytes) {
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
- message: {
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":"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"}
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.85",
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.85",
25
- "@simplysm/orm-common": "14.0.85"
24
+ "@simplysm/core-common": "14.0.87",
25
+ "@simplysm/orm-common": "14.0.87"
26
26
  }
27
27
  }
@@ -14,15 +14,15 @@ export interface ServiceEventDef<TInfo = unknown, TData = unknown> {
14
14
  * 타입 안전한 info와 data를 가진 서비스 이벤트를 정의한다.
15
15
  *
16
16
  * @example
17
- * // 서버에서 이벤트 정의 + 타입 export
17
+ * // 서버·클라이언트 공통 패키지에서 이벤트 정의 + export
18
18
  * export const OrderUpdated = defineEvent<{ orderId: number }, { status: string }>("OrderUpdated");
19
19
  *
20
- * // 서버에서 이벤트 발생
21
- * await server.emitEvent<typeof OrderUpdated>("OrderUpdated", (info) => info.orderId === 123, { status: "shipped" });
20
+ * // 서버에서 이벤트 발생 (정의 객체를 그대로 전달, 이름·타입 자동 추론)
21
+ * await server.emitEvent(OrderUpdated, (info) => info.orderId === 123, { status: "shipped" });
22
22
  *
23
- * // 클라이언트에서 구독 (import type으로 타입만 가져옴)
24
- * import type { OrderUpdated } from "@server-package";
25
- * await client.addListener<typeof OrderUpdated>("OrderUpdated", { orderId: 123 }, async (data) => {
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
- decode<T extends ServiceMessage>(bytes: Bytes): ServiceMessageDecodeResult<T> {
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
- message: {
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,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=app-structure-service.types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-structure-service.types.js","sourceRoot":"","sources":["../../src/service-types/app-structure-service.types.ts"],"names":[],"mappings":""}
@@ -1,10 +0,0 @@
1
- import type { AppStructureItem } from "../app-structure/app-structure.types";
2
-
3
- /**
4
- * AppStructure 서비스 인터페이스
5
- *
6
- * 서버에 등록된 앱 구조 항목을 클라이언트명 기준 맵으로 조회한다.
7
- */
8
- export interface AppStructureService {
9
- getItems(): Record<string, AppStructureItem[]>;
10
- }