@simplysm/service-client 13.0.0-beta.11

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 (194) hide show
  1. package/README.md +397 -0
  2. package/dist/core-common/src/common.types.d.ts +74 -0
  3. package/dist/core-common/src/common.types.d.ts.map +1 -0
  4. package/dist/core-common/src/env.d.ts +6 -0
  5. package/dist/core-common/src/env.d.ts.map +1 -0
  6. package/dist/core-common/src/errors/argument-error.d.ts +25 -0
  7. package/dist/core-common/src/errors/argument-error.d.ts.map +1 -0
  8. package/dist/core-common/src/errors/not-implemented-error.d.ts +29 -0
  9. package/dist/core-common/src/errors/not-implemented-error.d.ts.map +1 -0
  10. package/dist/core-common/src/errors/sd-error.d.ts +27 -0
  11. package/dist/core-common/src/errors/sd-error.d.ts.map +1 -0
  12. package/dist/core-common/src/errors/timeout-error.d.ts +31 -0
  13. package/dist/core-common/src/errors/timeout-error.d.ts.map +1 -0
  14. package/dist/core-common/src/extensions/arr-ext.d.ts +15 -0
  15. package/dist/core-common/src/extensions/arr-ext.d.ts.map +1 -0
  16. package/dist/core-common/src/extensions/arr-ext.helpers.d.ts +19 -0
  17. package/dist/core-common/src/extensions/arr-ext.helpers.d.ts.map +1 -0
  18. package/dist/core-common/src/extensions/arr-ext.types.d.ts +215 -0
  19. package/dist/core-common/src/extensions/arr-ext.types.d.ts.map +1 -0
  20. package/dist/core-common/src/extensions/map-ext.d.ts +57 -0
  21. package/dist/core-common/src/extensions/map-ext.d.ts.map +1 -0
  22. package/dist/core-common/src/extensions/set-ext.d.ts +36 -0
  23. package/dist/core-common/src/extensions/set-ext.d.ts.map +1 -0
  24. package/dist/core-common/src/features/debounce-queue.d.ts +53 -0
  25. package/dist/core-common/src/features/debounce-queue.d.ts.map +1 -0
  26. package/dist/core-common/src/features/event-emitter.d.ts +66 -0
  27. package/dist/core-common/src/features/event-emitter.d.ts.map +1 -0
  28. package/dist/core-common/src/features/serial-queue.d.ts +47 -0
  29. package/dist/core-common/src/features/serial-queue.d.ts.map +1 -0
  30. package/dist/core-common/src/index.d.ts +32 -0
  31. package/dist/core-common/src/index.d.ts.map +1 -0
  32. package/dist/core-common/src/types/date-only.d.ts +152 -0
  33. package/dist/core-common/src/types/date-only.d.ts.map +1 -0
  34. package/dist/core-common/src/types/date-time.d.ts +96 -0
  35. package/dist/core-common/src/types/date-time.d.ts.map +1 -0
  36. package/dist/core-common/src/types/lazy-gc-map.d.ts +80 -0
  37. package/dist/core-common/src/types/lazy-gc-map.d.ts.map +1 -0
  38. package/dist/core-common/src/types/time.d.ts +68 -0
  39. package/dist/core-common/src/types/time.d.ts.map +1 -0
  40. package/dist/core-common/src/types/uuid.d.ts +35 -0
  41. package/dist/core-common/src/types/uuid.d.ts.map +1 -0
  42. package/dist/core-common/src/utils/bytes.d.ts +51 -0
  43. package/dist/core-common/src/utils/bytes.d.ts.map +1 -0
  44. package/dist/core-common/src/utils/date-format.d.ts +90 -0
  45. package/dist/core-common/src/utils/date-format.d.ts.map +1 -0
  46. package/dist/core-common/src/utils/json.d.ts +34 -0
  47. package/dist/core-common/src/utils/json.d.ts.map +1 -0
  48. package/dist/core-common/src/utils/num.d.ts +60 -0
  49. package/dist/core-common/src/utils/num.d.ts.map +1 -0
  50. package/dist/core-common/src/utils/obj.d.ts +258 -0
  51. package/dist/core-common/src/utils/obj.d.ts.map +1 -0
  52. package/dist/core-common/src/utils/path.d.ts +23 -0
  53. package/dist/core-common/src/utils/path.d.ts.map +1 -0
  54. package/dist/core-common/src/utils/primitive.d.ts +18 -0
  55. package/dist/core-common/src/utils/primitive.d.ts.map +1 -0
  56. package/dist/core-common/src/utils/str.d.ts +103 -0
  57. package/dist/core-common/src/utils/str.d.ts.map +1 -0
  58. package/dist/core-common/src/utils/template-strings.d.ts +84 -0
  59. package/dist/core-common/src/utils/template-strings.d.ts.map +1 -0
  60. package/dist/core-common/src/utils/transferable.d.ts +47 -0
  61. package/dist/core-common/src/utils/transferable.d.ts.map +1 -0
  62. package/dist/core-common/src/utils/wait.d.ts +19 -0
  63. package/dist/core-common/src/utils/wait.d.ts.map +1 -0
  64. package/dist/core-common/src/utils/xml.d.ts +36 -0
  65. package/dist/core-common/src/utils/xml.d.ts.map +1 -0
  66. package/dist/core-common/src/zip/sd-zip.d.ts +80 -0
  67. package/dist/core-common/src/zip/sd-zip.d.ts.map +1 -0
  68. package/dist/features/event-client.js +74 -0
  69. package/dist/features/event-client.js.map +7 -0
  70. package/dist/features/file-client.js +42 -0
  71. package/dist/features/file-client.js.map +7 -0
  72. package/dist/features/orm/orm-client-connector.js +41 -0
  73. package/dist/features/orm/orm-client-connector.js.map +7 -0
  74. package/dist/features/orm/orm-client-db-context-executor.js +61 -0
  75. package/dist/features/orm/orm-client-db-context-executor.js.map +7 -0
  76. package/dist/features/orm/orm-connect-config.js +1 -0
  77. package/dist/features/orm/orm-connect-config.js.map +7 -0
  78. package/dist/index.js +12 -0
  79. package/dist/index.js.map +7 -0
  80. package/dist/orm-common/src/db-context.d.ts +669 -0
  81. package/dist/orm-common/src/db-context.d.ts.map +1 -0
  82. package/dist/orm-common/src/errors/db-transaction-error.d.ts +51 -0
  83. package/dist/orm-common/src/errors/db-transaction-error.d.ts.map +1 -0
  84. package/dist/orm-common/src/exec/executable.d.ts +79 -0
  85. package/dist/orm-common/src/exec/executable.d.ts.map +1 -0
  86. package/dist/orm-common/src/exec/queryable.d.ts +708 -0
  87. package/dist/orm-common/src/exec/queryable.d.ts.map +1 -0
  88. package/dist/orm-common/src/exec/search-parser.d.ts +72 -0
  89. package/dist/orm-common/src/exec/search-parser.d.ts.map +1 -0
  90. package/dist/orm-common/src/expr/expr-unit.d.ts +25 -0
  91. package/dist/orm-common/src/expr/expr-unit.d.ts.map +1 -0
  92. package/dist/orm-common/src/expr/expr.d.ts +1369 -0
  93. package/dist/orm-common/src/expr/expr.d.ts.map +1 -0
  94. package/dist/orm-common/src/index.d.ts +32 -0
  95. package/dist/orm-common/src/index.d.ts.map +1 -0
  96. package/dist/orm-common/src/models/system-migration.d.ts +10 -0
  97. package/dist/orm-common/src/models/system-migration.d.ts.map +1 -0
  98. package/dist/orm-common/src/query-builder/base/expr-renderer-base.d.ts +95 -0
  99. package/dist/orm-common/src/query-builder/base/expr-renderer-base.d.ts.map +1 -0
  100. package/dist/orm-common/src/query-builder/base/query-builder-base.d.ts +66 -0
  101. package/dist/orm-common/src/query-builder/base/query-builder-base.d.ts.map +1 -0
  102. package/dist/orm-common/src/query-builder/mssql/mssql-expr-renderer.d.ts +84 -0
  103. package/dist/orm-common/src/query-builder/mssql/mssql-expr-renderer.d.ts.map +1 -0
  104. package/dist/orm-common/src/query-builder/mssql/mssql-query-builder.d.ts +45 -0
  105. package/dist/orm-common/src/query-builder/mssql/mssql-query-builder.d.ts.map +1 -0
  106. package/dist/orm-common/src/query-builder/mysql/mysql-expr-renderer.d.ts +84 -0
  107. package/dist/orm-common/src/query-builder/mysql/mysql-expr-renderer.d.ts.map +1 -0
  108. package/dist/orm-common/src/query-builder/mysql/mysql-query-builder.d.ts +54 -0
  109. package/dist/orm-common/src/query-builder/mysql/mysql-query-builder.d.ts.map +1 -0
  110. package/dist/orm-common/src/query-builder/postgresql/postgresql-expr-renderer.d.ts +84 -0
  111. package/dist/orm-common/src/query-builder/postgresql/postgresql-expr-renderer.d.ts.map +1 -0
  112. package/dist/orm-common/src/query-builder/postgresql/postgresql-query-builder.d.ts +52 -0
  113. package/dist/orm-common/src/query-builder/postgresql/postgresql-query-builder.d.ts.map +1 -0
  114. package/dist/orm-common/src/query-builder/query-builder.d.ts +7 -0
  115. package/dist/orm-common/src/query-builder/query-builder.d.ts.map +1 -0
  116. package/dist/orm-common/src/schema/factory/column-builder.d.ts +394 -0
  117. package/dist/orm-common/src/schema/factory/column-builder.d.ts.map +1 -0
  118. package/dist/orm-common/src/schema/factory/index-builder.d.ts +151 -0
  119. package/dist/orm-common/src/schema/factory/index-builder.d.ts.map +1 -0
  120. package/dist/orm-common/src/schema/factory/relation-builder.d.ts +337 -0
  121. package/dist/orm-common/src/schema/factory/relation-builder.d.ts.map +1 -0
  122. package/dist/orm-common/src/schema/procedure-builder.d.ts +202 -0
  123. package/dist/orm-common/src/schema/procedure-builder.d.ts.map +1 -0
  124. package/dist/orm-common/src/schema/table-builder.d.ts +259 -0
  125. package/dist/orm-common/src/schema/table-builder.d.ts.map +1 -0
  126. package/dist/orm-common/src/schema/view-builder.d.ts +183 -0
  127. package/dist/orm-common/src/schema/view-builder.d.ts.map +1 -0
  128. package/dist/orm-common/src/types/column.d.ts +172 -0
  129. package/dist/orm-common/src/types/column.d.ts.map +1 -0
  130. package/dist/orm-common/src/types/db.d.ts +175 -0
  131. package/dist/orm-common/src/types/db.d.ts.map +1 -0
  132. package/dist/orm-common/src/types/expr.d.ts +474 -0
  133. package/dist/orm-common/src/types/expr.d.ts.map +1 -0
  134. package/dist/orm-common/src/types/query-def.d.ts +351 -0
  135. package/dist/orm-common/src/types/query-def.d.ts.map +1 -0
  136. package/dist/orm-common/src/utils/result-parser.d.ts +38 -0
  137. package/dist/orm-common/src/utils/result-parser.d.ts.map +1 -0
  138. package/dist/protocol/client-protocol-wrapper.js +92 -0
  139. package/dist/protocol/client-protocol-wrapper.js.map +7 -0
  140. package/dist/service-client/src/features/event-client.d.ts +14 -0
  141. package/dist/service-client/src/features/event-client.d.ts.map +1 -0
  142. package/dist/service-client/src/features/file-client.d.ts +13 -0
  143. package/dist/service-client/src/features/file-client.d.ts.map +1 -0
  144. package/dist/service-client/src/features/orm/orm-client-connector.d.ts +10 -0
  145. package/dist/service-client/src/features/orm/orm-client-connector.d.ts.map +1 -0
  146. package/dist/service-client/src/features/orm/orm-client-db-context-executor.d.ts +26 -0
  147. package/dist/service-client/src/features/orm/orm-client-db-context-executor.d.ts.map +1 -0
  148. package/dist/service-client/src/features/orm/orm-connect-config.d.ts +13 -0
  149. package/dist/service-client/src/features/orm/orm-connect-config.d.ts.map +1 -0
  150. package/dist/service-client/src/index.d.ts +12 -0
  151. package/dist/service-client/src/index.d.ts.map +1 -0
  152. package/dist/service-client/src/protocol/client-protocol-wrapper.d.ts +23 -0
  153. package/dist/service-client/src/protocol/client-protocol-wrapper.d.ts.map +1 -0
  154. package/dist/service-client/src/service-client.d.ts +41 -0
  155. package/dist/service-client/src/service-client.d.ts.map +1 -0
  156. package/dist/service-client/src/transport/service-transport.d.ts +24 -0
  157. package/dist/service-client/src/transport/service-transport.d.ts.map +1 -0
  158. package/dist/service-client/src/transport/socket-provider.d.ts +31 -0
  159. package/dist/service-client/src/transport/socket-provider.d.ts.map +1 -0
  160. package/dist/service-client/src/types/connection-config.d.ts +8 -0
  161. package/dist/service-client/src/types/connection-config.d.ts.map +1 -0
  162. package/dist/service-client/src/types/progress.types.d.ts +10 -0
  163. package/dist/service-client/src/types/progress.types.d.ts.map +1 -0
  164. package/dist/service-client/src/workers/client-protocol.worker.d.ts +2 -0
  165. package/dist/service-client/src/workers/client-protocol.worker.d.ts.map +1 -0
  166. package/dist/service-client.js +114 -0
  167. package/dist/service-client.js.map +7 -0
  168. package/dist/service-common/src/index.d.ts +8 -0
  169. package/dist/service-common/src/index.d.ts.map +1 -0
  170. package/dist/service-common/src/protocol/protocol.types.d.ts +100 -0
  171. package/dist/service-common/src/protocol/protocol.types.d.ts.map +1 -0
  172. package/dist/service-common/src/protocol/service-protocol.d.ts +63 -0
  173. package/dist/service-common/src/protocol/service-protocol.d.ts.map +1 -0
  174. package/dist/service-common/src/service-types/auto-update-service.types.d.ts +17 -0
  175. package/dist/service-common/src/service-types/auto-update-service.types.d.ts.map +1 -0
  176. package/dist/service-common/src/service-types/crypto-service.types.d.ts +22 -0
  177. package/dist/service-common/src/service-types/crypto-service.types.d.ts.map +1 -0
  178. package/dist/service-common/src/service-types/orm-service.types.d.ts +30 -0
  179. package/dist/service-common/src/service-types/orm-service.types.d.ts.map +1 -0
  180. package/dist/service-common/src/service-types/smtp-service.types.d.ts +55 -0
  181. package/dist/service-common/src/service-types/smtp-service.types.d.ts.map +1 -0
  182. package/dist/service-common/src/types.d.ts +43 -0
  183. package/dist/service-common/src/types.d.ts.map +1 -0
  184. package/dist/transport/service-transport.js +112 -0
  185. package/dist/transport/service-transport.js.map +7 -0
  186. package/dist/transport/socket-provider.js +170 -0
  187. package/dist/transport/socket-provider.js.map +7 -0
  188. package/dist/types/connection-config.js +1 -0
  189. package/dist/types/connection-config.js.map +7 -0
  190. package/dist/types/progress.types.js +1 -0
  191. package/dist/types/progress.types.js.map +7 -0
  192. package/dist/workers/client-protocol.worker.js +30 -0
  193. package/dist/workers/client-protocol.worker.js.map +7 -0
  194. package/package.json +29 -0
@@ -0,0 +1,55 @@
1
+ import type { Bytes } from "@simplysm/core-common";
2
+ /**
3
+ * SMTP 서비스 인터페이스
4
+ *
5
+ * 이메일 전송 기능을 제공한다.
6
+ * 직접 SMTP 설정을 전달하거나 서버 설정을 참조하여 전송할 수 있다.
7
+ */
8
+ export interface SmtpService {
9
+ /** 직접 SMTP 설정으로 이메일 전송 */
10
+ send(options: SmtpSendOption): Promise<string>;
11
+ /** 서버 설정 참조로 이메일 전송 */
12
+ sendByConfig(configName: string, options: SmtpSendByConfigOption): Promise<string>;
13
+ }
14
+ /**
15
+ * 이메일 첨부 파일 정보
16
+ *
17
+ * content 또는 path 중 하나를 지정해야 한다.
18
+ */
19
+ export interface SmtpSendAttachment {
20
+ /** 첨부 파일명 */
21
+ filename: string;
22
+ /** 파일 내용 (바이너리) */
23
+ content?: Bytes;
24
+ /** 서버 내 파일 경로 */
25
+ path?: string;
26
+ /** MIME 타입 (예: "application/pdf") */
27
+ contentType?: string;
28
+ }
29
+ /** SMTP 연결 옵션 (공통) */
30
+ export interface SmtpConnectionOptions {
31
+ host: string;
32
+ port?: number;
33
+ secure?: boolean;
34
+ user?: string;
35
+ pass?: string;
36
+ }
37
+ /** 이메일 내용 옵션 (공통) */
38
+ export interface SmtpEmailContentOptions {
39
+ to: string;
40
+ cc?: string;
41
+ bcc?: string;
42
+ subject: string;
43
+ html: string;
44
+ attachments?: SmtpSendAttachment[];
45
+ }
46
+ export interface SmtpSendByConfigOption extends SmtpEmailContentOptions {
47
+ }
48
+ export interface SmtpSendOption extends SmtpConnectionOptions, SmtpEmailContentOptions {
49
+ from: string;
50
+ }
51
+ export interface SmtpConfig extends SmtpConnectionOptions {
52
+ senderName: string;
53
+ senderEmail?: string;
54
+ }
55
+ //# sourceMappingURL=smtp-service.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smtp-service.types.d.ts","sourceRoot":"","sources":["../../../../../service-common/src/service-types/smtp-service.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,0BAA0B;IAC1B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,uBAAuB;IACvB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACpF;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,aAAa;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB;IACnB,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,iBAAiB;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,sBAAsB;AACtB,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAqB;AACrB,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,sBAAuB,SAAQ,uBAAuB;CAAG;AAE1E,MAAM,WAAW,cAAe,SAAQ,qBAAqB,EAAE,uBAAuB;IACpF,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAW,SAAQ,qBAAqB;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 이벤트 리스너 타입 정의용 추상 클래스
3
+ *
4
+ * - 상속만 하면 됨 (프로퍼티 구현 불필요)
5
+ * - $info, $data는 타입 추출용 (런타임 미사용)
6
+ * - eventName은 mangle 안전한 이벤트 식별자
7
+ *
8
+ * @example
9
+ * export class SharedDataChangeEvent extends ServiceEventListener<
10
+ * { name: string; filter: unknown },
11
+ * (string | number)[] | undefined
12
+ * > {
13
+ * readonly eventName = "SharedDataChangeEvent";
14
+ * }
15
+ *
16
+ * // 클라이언트에서 사용
17
+ * await client.addEventListener(
18
+ * SharedDataChangeEvent,
19
+ * { name: "test", filter: null },
20
+ * (data) => console.log(data)
21
+ * );
22
+ */
23
+ export declare abstract class ServiceEventListener<TInfo, TData> {
24
+ /** mangle 안전한 이벤트 식별자 (상속 시 필수 구현) */
25
+ abstract readonly eventName: string;
26
+ /** 타입 추출용 (런타임 미사용) */
27
+ readonly $info: TInfo;
28
+ readonly $data: TData;
29
+ }
30
+ /**
31
+ * 파일 업로드 결과
32
+ *
33
+ * 서버에 업로드된 파일의 정보를 담는다.
34
+ */
35
+ export interface ServiceUploadResult {
36
+ /** 서버 내 저장 경로 */
37
+ path: string;
38
+ /** 원본 파일명 */
39
+ filename: string;
40
+ /** 파일 크기 (bytes) */
41
+ size: number;
42
+ }
43
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../service-common/src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,8BAAsB,oBAAoB,CAAC,KAAK,EAAE,KAAK;IACrD,sCAAsC;IACtC,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAEpC,uBAAuB;IACvB,SAAiB,KAAK,EAAE,KAAK,CAAC;IAC9B,SAAiB,KAAK,EAAE,KAAK,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;CACd"}
@@ -0,0 +1,112 @@
1
+ import { EventEmitter, Uuid } from "@simplysm/core-common";
2
+ import { ClientProtocolWrapper } from "../protocol/client-protocol-wrapper";
3
+ class ServiceTransport extends EventEmitter {
4
+ constructor(_socket) {
5
+ super();
6
+ this._socket = _socket;
7
+ this._socket.on("message", this._onMessage.bind(this));
8
+ this._socket.on("state", (state) => {
9
+ if (state === "closed" || state === "reconnecting") {
10
+ this._cancelAllRequests("Socket connection lost");
11
+ }
12
+ });
13
+ }
14
+ _protocol = new ClientProtocolWrapper();
15
+ _pendingRequests = /* @__PURE__ */ new Map();
16
+ // 응답 progress의 totalSize 저장 (complete 시 100% emit용)
17
+ _responseProgressTotalSize = /* @__PURE__ */ new Map();
18
+ async send(message, progress) {
19
+ var _a, _b;
20
+ const uuid = Uuid.new().toString();
21
+ const responsePromise = new Promise((resolve, reject) => {
22
+ this._pendingRequests.set(uuid, { resolve, reject, progress });
23
+ });
24
+ try {
25
+ const { chunks, totalSize } = await this._protocol.encode(uuid, message);
26
+ if (chunks.length > 1) {
27
+ (_a = progress == null ? void 0 : progress.request) == null ? void 0 : _a.call(progress, {
28
+ uuid,
29
+ totalSize,
30
+ completedSize: 0
31
+ });
32
+ }
33
+ for (const chunk of chunks) {
34
+ await this._socket.send(chunk);
35
+ }
36
+ } catch (err) {
37
+ (_b = this._pendingRequests.get(uuid)) == null ? void 0 : _b.reject(err);
38
+ this._pendingRequests.delete(uuid);
39
+ throw err;
40
+ }
41
+ return responsePromise;
42
+ }
43
+ async _onMessage(buf) {
44
+ var _a, _b, _c, _d, _e, _f;
45
+ const decoded = await this._protocol.decode(buf);
46
+ const listenerInfo = this._pendingRequests.get(decoded.uuid);
47
+ try {
48
+ if (decoded.type === "progress") {
49
+ this._responseProgressTotalSize.set(decoded.uuid, decoded.totalSize);
50
+ (_b = (_a = listenerInfo == null ? void 0 : listenerInfo.progress) == null ? void 0 : _a.response) == null ? void 0 : _b.call(_a, {
51
+ uuid: decoded.uuid,
52
+ totalSize: decoded.totalSize,
53
+ completedSize: decoded.completedSize
54
+ });
55
+ } else {
56
+ if (decoded.message.name === "progress") {
57
+ const body = decoded.message.body;
58
+ (_d = (_c = listenerInfo == null ? void 0 : listenerInfo.progress) == null ? void 0 : _c.request) == null ? void 0 : _d.call(_c, {
59
+ uuid: decoded.uuid,
60
+ totalSize: body.totalSize,
61
+ completedSize: body.completedSize
62
+ });
63
+ } else if (decoded.message.name === "response") {
64
+ const totalSize = this._responseProgressTotalSize.get(decoded.uuid);
65
+ if (totalSize != null) {
66
+ this._responseProgressTotalSize.delete(decoded.uuid);
67
+ (_f = (_e = listenerInfo == null ? void 0 : listenerInfo.progress) == null ? void 0 : _e.response) == null ? void 0 : _f.call(_e, {
68
+ uuid: decoded.uuid,
69
+ totalSize,
70
+ completedSize: totalSize
71
+ });
72
+ }
73
+ this._pendingRequests.delete(decoded.uuid);
74
+ listenerInfo == null ? void 0 : listenerInfo.resolve(decoded.message.body);
75
+ } else if (decoded.message.name === "error") {
76
+ this._responseProgressTotalSize.delete(decoded.uuid);
77
+ this._pendingRequests.delete(decoded.uuid);
78
+ listenerInfo == null ? void 0 : listenerInfo.reject(this._toError(decoded.message.body));
79
+ } else if (decoded.message.name === "reload") {
80
+ const body = decoded.message.body;
81
+ if (this._socket.clientName === body.clientName) {
82
+ this.emit("reload", body.changedFileSet);
83
+ }
84
+ } else if (decoded.message.name === "evt:on") {
85
+ const body = decoded.message.body;
86
+ this.emit("event", { keys: body.keys, data: body.data });
87
+ } else {
88
+ throw new Error("\uC694\uCCAD\uC774 \uC798 \uBABB \uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
89
+ }
90
+ }
91
+ } catch (err) {
92
+ listenerInfo == null ? void 0 : listenerInfo.reject(err instanceof Error ? err : new Error(String(err)));
93
+ }
94
+ }
95
+ // 모든 대기 요청 취소 처리
96
+ _cancelAllRequests(reason) {
97
+ for (const listenerInfo of this._pendingRequests.values()) {
98
+ listenerInfo.reject(new Error(`Request canceled: ${reason}`));
99
+ }
100
+ this._pendingRequests.clear();
101
+ this._responseProgressTotalSize.clear();
102
+ }
103
+ _toError(body) {
104
+ let err = new Error(body.message);
105
+ err = Object.assign(err, body);
106
+ return err;
107
+ }
108
+ }
109
+ export {
110
+ ServiceTransport
111
+ };
112
+ //# sourceMappingURL=service-transport.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/transport/service-transport.ts"],
4
+ "sourcesContent": ["import type { Bytes } from \"@simplysm/core-common\";\nimport { EventEmitter, Uuid } from \"@simplysm/core-common\";\nimport type { ServiceErrorMessage, ServiceResponseMessage, ServiceClientMessage } from \"@simplysm/service-common\";\nimport { ClientProtocolWrapper } from \"../protocol/client-protocol-wrapper\";\nimport type { ServiceProgress } from \"../types/progress.types\";\nimport type { SocketProvider } from \"./socket-provider\";\n\ninterface ServiceTransportEvents {\n reload: Set<string>;\n event: { keys: string[]; data: unknown };\n}\n\nexport class ServiceTransport extends EventEmitter<ServiceTransportEvents> {\n private readonly _protocol = new ClientProtocolWrapper();\n\n private readonly _pendingRequests = new Map<\n string,\n {\n resolve: (msg: ServiceResponseMessage) => void;\n reject: (err: Error) => void;\n progress?: ServiceProgress;\n }\n >();\n\n // \uC751\uB2F5 progress\uC758 totalSize \uC800\uC7A5 (complete \uC2DC 100% emit\uC6A9)\n private readonly _responseProgressTotalSize = new Map<string, number>();\n\n constructor(private readonly _socket: SocketProvider) {\n super();\n\n this._socket.on(\"message\", this._onMessage.bind(this));\n\n // \uC18C\uCF13\uC774 \uB04A\uAE30\uBA74 \uB300\uAE30 \uC911\uC778 \uBAA8\uB4E0 \uC694\uCCAD\uC744 \uC5D0\uB7EC \uCC98\uB9AC\uD558\uC5EC \uBA54\uBAA8\uB9AC \uD574\uC81C\n this._socket.on(\"state\", (state) => {\n if (state === \"closed\" || state === \"reconnecting\") {\n this._cancelAllRequests(\"Socket connection lost\");\n }\n });\n }\n\n async send(message: ServiceClientMessage, progress?: ServiceProgress): Promise<unknown> {\n const uuid = Uuid.new().toString();\n\n // \uC751\uB2F5 \uB300\uAE30 \uC2DC\uC791 (\uC694\uCCAD \uBCF4\uB0B4\uAE30 \uC804\uC5D0 \uB9AC\uC2A4\uB108\uB97C \uBA3C\uC800 \uB4F1\uB85D\uD574\uC57C \uC548\uC804\uD568)\n const responsePromise = new Promise((resolve, reject) => {\n this._pendingRequests.set(uuid, { resolve, reject, progress });\n });\n\n // \uC694\uCCAD \uC804\uC1A1\n try {\n const { chunks, totalSize } = await this._protocol.encode(uuid, message);\n\n // \uC9C4\uD589\uB960 \uCD08\uAE30\uD654\n if (chunks.length > 1) {\n progress?.request?.({\n uuid,\n totalSize,\n completedSize: 0,\n });\n }\n\n // \uC804\uC1A1\n for (const chunk of chunks) {\n await this._socket.send(chunk);\n }\n } catch (err) {\n // \uC804\uC1A1 \uC2E4\uD328 \uC2DC \uC989\uC2DC \uC815\uB9AC\n this._pendingRequests.get(uuid)?.reject(err as Error);\n this._pendingRequests.delete(uuid);\n throw err;\n }\n\n // \uC751\uB2F5 \uACB0\uACFC \uBC18\uD658\n return responsePromise;\n }\n\n private async _onMessage(buf: Bytes): Promise<void> {\n const decoded = await this._protocol.decode(buf);\n\n const listenerInfo = this._pendingRequests.get(decoded.uuid);\n\n try {\n if (decoded.type === \"progress\") {\n // totalSize \uAE30\uC5B5 (complete \uC2DC 100% emit\uC6A9)\n this._responseProgressTotalSize.set(decoded.uuid, decoded.totalSize);\n\n listenerInfo?.progress?.response?.({\n uuid: decoded.uuid,\n totalSize: decoded.totalSize,\n completedSize: decoded.completedSize,\n });\n } else {\n if (decoded.message.name === \"progress\") {\n const body = decoded.message.body as { totalSize: number; completedSize: number };\n listenerInfo?.progress?.request?.({\n uuid: decoded.uuid,\n totalSize: body.totalSize,\n completedSize: body.completedSize,\n });\n } else if (decoded.message.name === \"response\") {\n // split\uB41C \uBA54\uC2DC\uC9C0\uC600\uC73C\uBA74 100% progress emit\n const totalSize = this._responseProgressTotalSize.get(decoded.uuid);\n if (totalSize != null) {\n this._responseProgressTotalSize.delete(decoded.uuid);\n listenerInfo?.progress?.response?.({\n uuid: decoded.uuid,\n totalSize,\n completedSize: totalSize,\n });\n }\n\n // \uC751\uB2F5\uC744 \uBC1B\uC558\uC73C\uBBC0\uB85C Map\uC5D0\uC11C \uC81C\uAC70\n this._pendingRequests.delete(decoded.uuid);\n\n listenerInfo?.resolve(decoded.message.body as ServiceResponseMessage);\n } else if (decoded.message.name === \"error\") {\n // progress totalSize \uC815\uB9AC\n this._responseProgressTotalSize.delete(decoded.uuid);\n\n // \uC5D0\uB7EC\uB97C \uBC1B\uC558\uC73C\uBBC0\uB85C Map\uC5D0\uC11C \uC81C\uAC70\n this._pendingRequests.delete(decoded.uuid);\n\n listenerInfo?.reject(this._toError(decoded.message.body));\n } else if (decoded.message.name === \"reload\") {\n const body = decoded.message.body as { clientName: string; changedFileSet: Set<string> };\n if (this._socket.clientName === body.clientName) {\n this.emit(\"reload\", body.changedFileSet);\n }\n } else if (decoded.message.name === \"evt:on\") {\n const body = decoded.message.body as { keys: string[]; data: unknown };\n this.emit(\"event\", { keys: body.keys, data: body.data });\n } else {\n throw new Error(\"\uC694\uCCAD\uC774 \uC798 \uBABB \uB418\uC5C8\uC2B5\uB2C8\uB2E4.\");\n }\n }\n } catch (err) {\n listenerInfo?.reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n // \uBAA8\uB4E0 \uB300\uAE30 \uC694\uCCAD \uCDE8\uC18C \uCC98\uB9AC\n private _cancelAllRequests(reason: string): void {\n for (const listenerInfo of this._pendingRequests.values()) {\n listenerInfo.reject(new Error(`Request canceled: ${reason}`));\n }\n this._pendingRequests.clear();\n this._responseProgressTotalSize.clear();\n }\n\n private _toError(body: ServiceErrorMessage[\"body\"]): Error {\n let err = new Error(body.message);\n err = Object.assign(err, body);\n return err;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,170 @@
1
+ import { EventEmitter, Uuid, waitUntil, waitTime } from "@simplysm/core-common";
2
+ import { createConsola } from "consola";
3
+ const logger = createConsola().withTag("service-client:SocketProvider");
4
+ class SocketProvider extends EventEmitter {
5
+ constructor(_url, clientName, _maxReconnectCount) {
6
+ super();
7
+ this._url = _url;
8
+ this.clientName = clientName;
9
+ this._maxReconnectCount = _maxReconnectCount;
10
+ }
11
+ // 설정상수
12
+ _HEARTBEAT_TIMEOUT = 3e4;
13
+ // 30초간 아무런 메시지가 없으면 끊김으로 간주
14
+ _HEARTBEAT_INTERVAL = 5e3;
15
+ // 5초마다 핑 전송
16
+ _RECONNECT_DELAY = 3e3;
17
+ // 3초마다 재연결 시도
18
+ // 1바이트 버퍼 미리 생성 (메모리 절약)
19
+ _PING_PACKET = new Uint8Array([1]);
20
+ // 상태
21
+ _ws;
22
+ _isManualClose = false;
23
+ _reconnectCount = 0;
24
+ _heartbeatTimer;
25
+ _lastHeartbeatTime = Date.now();
26
+ get connected() {
27
+ var _a;
28
+ return ((_a = this._ws) == null ? void 0 : _a.readyState) === WebSocket.OPEN;
29
+ }
30
+ async connect() {
31
+ if (this.connected) return;
32
+ this._isManualClose = false;
33
+ try {
34
+ await this._createSocket();
35
+ this._startHeartbeat();
36
+ this._reconnectCount = 0;
37
+ this.emit("state", "connected");
38
+ } catch (err) {
39
+ throw err;
40
+ }
41
+ }
42
+ async close() {
43
+ this._isManualClose = true;
44
+ this._stopHeartbeat();
45
+ const ws = this._ws;
46
+ if (ws != null) {
47
+ ws.close();
48
+ await waitUntil(() => ws.readyState === WebSocket.CLOSED, 100, 30).catch(() => {
49
+ });
50
+ }
51
+ this.emit("state", "closed");
52
+ }
53
+ async send(data) {
54
+ try {
55
+ await waitUntil(() => this.connected, void 0, 50);
56
+ } catch {
57
+ throw new Error("\uC11C\uBC84\uC640 \uC5F0\uACB0\uB418\uC5B4\uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC778\uD130\uB137 \uC5F0\uACB0\uC744 \uD655\uC778\uD558\uC138\uC694.");
58
+ }
59
+ const ws = this._ws;
60
+ if (ws == null) {
61
+ throw new Error("WebSocket\uC774 \uC5F0\uACB0\uB418\uC5B4\uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
62
+ }
63
+ ws.send(data);
64
+ }
65
+ async _createSocket() {
66
+ const clientId = Uuid.new().toString();
67
+ const params = new URLSearchParams({
68
+ ver: "2",
69
+ clientId,
70
+ clientName: this.clientName
71
+ });
72
+ await new Promise((resolve, reject) => {
73
+ const ws = new WebSocket(`${this._url}?${params.toString()}`);
74
+ ws.binaryType = "arraybuffer";
75
+ ws.onopen = () => {
76
+ this._ws = ws;
77
+ resolve();
78
+ };
79
+ ws.onerror = (event) => {
80
+ if (!this.connected) {
81
+ const errorEvent = event;
82
+ const msg = errorEvent.message;
83
+ reject(new Error(msg));
84
+ }
85
+ };
86
+ });
87
+ const currentWs = this._ws;
88
+ if (currentWs == null) {
89
+ throw new Error("WebSocket \uCD08\uAE30\uD654 \uC2E4\uD328");
90
+ }
91
+ currentWs.onmessage = (event) => {
92
+ this._lastHeartbeatTime = Date.now();
93
+ const data = event.data;
94
+ const bytes = new Uint8Array(data);
95
+ if (bytes.length === 1 && bytes[0] === 2) return;
96
+ this.emit("message", bytes);
97
+ };
98
+ currentWs.onclose = async () => {
99
+ this._stopHeartbeat();
100
+ if (!this._isManualClose) {
101
+ await this._tryReconnect();
102
+ }
103
+ };
104
+ }
105
+ async _tryReconnect() {
106
+ while (this._reconnectCount < this._maxReconnectCount) {
107
+ this._reconnectCount++;
108
+ this.emit("state", "reconnecting");
109
+ logger.warn("WebSocket \uC5F0\uACB0 \uB04A\uAE40. \uC7AC\uC5F0\uACB0 \uC2DC\uB3C4...", {
110
+ reconnectCount: this._reconnectCount,
111
+ maxReconnectCount: this._maxReconnectCount
112
+ });
113
+ await waitTime(this._RECONNECT_DELAY);
114
+ try {
115
+ await this._createSocket();
116
+ this._startHeartbeat();
117
+ this._reconnectCount = 0;
118
+ this.emit("state", "connected");
119
+ logger.info("WebSocket \uC7AC\uC5F0\uACB0 \uC131\uACF5");
120
+ return;
121
+ } catch {
122
+ }
123
+ }
124
+ logger.error("\uC7AC\uC5F0\uACB0 \uC2DC\uB3C4 \uD69F\uC218 \uCD08\uACFC. \uC5F0\uACB0\uC744 \uD3EC\uAE30\uD569\uB2C8\uB2E4.");
125
+ this.emit("state", "closed");
126
+ }
127
+ _startHeartbeat() {
128
+ this._stopHeartbeat();
129
+ this._lastHeartbeatTime = Date.now();
130
+ this._heartbeatTimer = setInterval(() => {
131
+ if (Date.now() - this._lastHeartbeatTime > this._HEARTBEAT_TIMEOUT) {
132
+ logger.warn("Heartbeat Timeout. Connection lost.");
133
+ this._stopHeartbeat();
134
+ if (this._ws != null) {
135
+ const tempWs = this._ws;
136
+ this._ws = void 0;
137
+ tempWs.onclose = null;
138
+ tempWs.onerror = null;
139
+ tempWs.onmessage = null;
140
+ try {
141
+ tempWs.close();
142
+ } catch {
143
+ }
144
+ if (!this._isManualClose) {
145
+ void this._tryReconnect();
146
+ }
147
+ }
148
+ return;
149
+ }
150
+ const ws = this._ws;
151
+ if (this.connected && ws != null) {
152
+ try {
153
+ ws.send(this._PING_PACKET);
154
+ } catch (err) {
155
+ logger.warn("Ping send failed", err);
156
+ }
157
+ }
158
+ }, this._HEARTBEAT_INTERVAL);
159
+ }
160
+ _stopHeartbeat() {
161
+ if (this._heartbeatTimer != null) {
162
+ clearInterval(this._heartbeatTimer);
163
+ this._heartbeatTimer = void 0;
164
+ }
165
+ }
166
+ }
167
+ export {
168
+ SocketProvider
169
+ };
170
+ //# sourceMappingURL=socket-provider.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/transport/socket-provider.ts"],
4
+ "sourcesContent": ["import type { Bytes } from \"@simplysm/core-common\";\nimport { EventEmitter, Uuid, waitUntil, waitTime } from \"@simplysm/core-common\";\nimport { createConsola } from \"consola\";\n\nconst logger = createConsola().withTag(\"service-client:SocketProvider\");\n\ninterface SocketProviderEvents {\n message: Bytes;\n state: \"connected\" | \"closed\" | \"reconnecting\";\n}\n\nexport class SocketProvider extends EventEmitter<SocketProviderEvents> {\n // \uC124\uC815\uC0C1\uC218\n private readonly _HEARTBEAT_TIMEOUT = 30000; // 30\uCD08\uAC04 \uC544\uBB34\uB7F0 \uBA54\uC2DC\uC9C0\uAC00 \uC5C6\uC73C\uBA74 \uB04A\uAE40\uC73C\uB85C \uAC04\uC8FC\n private readonly _HEARTBEAT_INTERVAL = 5000; // 5\uCD08\uB9C8\uB2E4 \uD551 \uC804\uC1A1\n private readonly _RECONNECT_DELAY = 3000; // 3\uCD08\uB9C8\uB2E4 \uC7AC\uC5F0\uACB0 \uC2DC\uB3C4\n\n // 1\uBC14\uC774\uD2B8 \uBC84\uD37C \uBBF8\uB9AC \uC0DD\uC131 (\uBA54\uBAA8\uB9AC \uC808\uC57D)\n private readonly _PING_PACKET = new Uint8Array([0x01]);\n\n // \uC0C1\uD0DC\n private _ws?: WebSocket;\n private _isManualClose = false;\n private _reconnectCount = 0;\n private _heartbeatTimer?: ReturnType<typeof setInterval>;\n private _lastHeartbeatTime = Date.now();\n\n get connected(): boolean {\n return this._ws?.readyState === WebSocket.OPEN;\n }\n\n constructor(\n private readonly _url: string,\n public readonly clientName: string,\n private readonly _maxReconnectCount: number,\n ) {\n super();\n }\n\n async connect(): Promise<void> {\n if (this.connected) return;\n this._isManualClose = false;\n\n try {\n await this._createSocket();\n this._startHeartbeat();\n this._reconnectCount = 0; // \uC5F0\uACB0 \uC131\uACF5 \uC2DC \uCE74\uC6B4\uD2B8 \uCD08\uAE30\uD654\n this.emit(\"state\", \"connected\");\n } catch (err) {\n // \uCD5C\uCD08 \uC5F0\uACB0 \uC2E4\uD328\uB294 \uC5D0\uB7EC\uB97C \uB358\uC9D0 (\uD638\uCD9C\uC790\uAC00 \uC54C \uC218 \uC788\uAC8C)\n throw err;\n }\n }\n\n async close(): Promise<void> {\n this._isManualClose = true;\n this._stopHeartbeat();\n const ws = this._ws;\n if (ws != null) {\n ws.close();\n // \uC644\uC804\uD788 \uB2EB\uD790 \uB54C\uAE4C\uC9C0 \uB300\uAE30 (Graceful Shutdown)\n await waitUntil(() => ws.readyState === WebSocket.CLOSED, 100, 30).catch(() => {});\n }\n this.emit(\"state\", \"closed\");\n }\n\n async send(data: Bytes): Promise<void> {\n try {\n await waitUntil(() => this.connected, undefined, 50);\n } catch {\n throw new Error(\"\uC11C\uBC84\uC640 \uC5F0\uACB0\uB418\uC5B4\uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC778\uD130\uB137 \uC5F0\uACB0\uC744 \uD655\uC778\uD558\uC138\uC694.\");\n }\n const ws = this._ws;\n if (ws == null) {\n throw new Error(\"WebSocket\uC774 \uC5F0\uACB0\uB418\uC5B4\uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\");\n }\n ws.send(data);\n }\n\n private async _createSocket(): Promise<void> {\n const clientId = Uuid.new().toString();\n const params = new URLSearchParams({\n ver: \"2\",\n clientId,\n clientName: this.clientName,\n });\n\n await new Promise<void>((resolve, reject) => {\n const ws = new WebSocket(`${this._url}?${params.toString()}`);\n ws.binaryType = \"arraybuffer\";\n\n ws.onopen = () => {\n this._ws = ws;\n resolve();\n };\n\n ws.onerror = (event: Event) => {\n // \uC5F0\uACB0 \uC911 \uC5D0\uB7EC \uBC1C\uC0DD \uC2DC reject\n if (!this.connected) {\n const errorEvent = event as ErrorEvent;\n const msg = errorEvent.message;\n reject(new Error(msg));\n }\n };\n });\n\n // \uC774 \uC2DC\uC810\uC5D0\uC11C this._ws\uB294 \uD56D\uC0C1 \uD560\uB2F9\uB418\uC5B4 \uC788\uC74C (ws.onopen\uC5D0\uC11C \uD560\uB2F9)\n const currentWs = this._ws;\n if (currentWs == null) {\n throw new Error(\"WebSocket \uCD08\uAE30\uD654 \uC2E4\uD328\");\n }\n\n currentWs.onmessage = (event) => {\n this._lastHeartbeatTime = Date.now(); // \uD558\uD2B8\uBE44\uD2B8 \uAC31\uC2E0\n\n const data = event.data as ArrayBuffer;\n const bytes = new Uint8Array(data);\n\n // Raw Ping/Pong \uCC98\uB9AC (\uAC00\uC7A5 \uBA3C\uC800 \uCCB4\uD06C)\n // 1\uBC14\uC774\uD2B8\uC774\uACE0 \uCCAB \uBC14\uC774\uD2B8\uAC00 0x02(Pong)\uC774\uBA74 \uBB34\uC2DC\n // (\uD558\uD2B8\uBE44\uD2B8 \uD0C0\uC784\uC2A4\uD0EC\uD504\uB9CC \uAC31\uC2E0\uD558\uACE0 \uB05D\uB0C4)\n if (bytes.length === 1 && bytes[0] === 0x02) return;\n\n this.emit(\"message\", bytes);\n };\n\n currentWs.onclose = async () => {\n this._stopHeartbeat();\n if (!this._isManualClose) {\n await this._tryReconnect();\n }\n };\n }\n\n private async _tryReconnect(): Promise<void> {\n // \uB8E8\uD504 \uAE30\uBC18 \uC7AC\uC5F0\uACB0 (\uC7AC\uADC0 \uB300\uC2E0 \uC0AC\uC6A9\uD558\uC5EC \uC2A4\uD0DD \uC548\uC804\uC131 \uD655\uBCF4)\n while (this._reconnectCount < this._maxReconnectCount) {\n this._reconnectCount++;\n this.emit(\"state\", \"reconnecting\");\n logger.warn(\"WebSocket \uC5F0\uACB0 \uB04A\uAE40. \uC7AC\uC5F0\uACB0 \uC2DC\uB3C4...\", {\n reconnectCount: this._reconnectCount,\n maxReconnectCount: this._maxReconnectCount,\n });\n\n await waitTime(this._RECONNECT_DELAY);\n\n try {\n await this._createSocket();\n this._startHeartbeat();\n this._reconnectCount = 0;\n this.emit(\"state\", \"connected\"); // \uC7AC\uC5F0\uACB0 \uC131\uACF5 \uC54C\uB9BC\n logger.info(\"WebSocket \uC7AC\uC5F0\uACB0 \uC131\uACF5\");\n return; // \uC7AC\uC5F0\uACB0 \uC131\uACF5 \uC2DC \uC885\uB8CC\n } catch {\n // \uC2E4\uD328 \uC2DC \uB8E8\uD504 \uACC4\uC18D\n }\n }\n\n // \uCD5C\uB300 \uC7AC\uC2DC\uB3C4 \uD69F\uC218 \uCD08\uACFC\n logger.error(\"\uC7AC\uC5F0\uACB0 \uC2DC\uB3C4 \uD69F\uC218 \uCD08\uACFC. \uC5F0\uACB0\uC744 \uD3EC\uAE30\uD569\uB2C8\uB2E4.\");\n this.emit(\"state\", \"closed\");\n }\n\n private _startHeartbeat(): void {\n this._stopHeartbeat();\n this._lastHeartbeatTime = Date.now();\n\n this._heartbeatTimer = setInterval(() => {\n // \uD0C0\uC784\uC544\uC6C3 \uCCB4\uD06C\n if (Date.now() - this._lastHeartbeatTime > this._HEARTBEAT_TIMEOUT) {\n logger.warn(\"Heartbeat Timeout. Connection lost.\");\n\n // \uD0C0\uC784\uC544\uC6C3\uC774 \uBC1C\uC0DD\uD588\uC73C\uBBC0\uB85C \uC989\uC2DC \uD0C0\uC774\uBA38\uB97C \uBA48\uCDB0\uC11C \uBC18\uBCF5 \uC2E4\uD589\uC744 \uB9C9\uC2B5\uB2C8\uB2E4.\n this._stopHeartbeat();\n\n // \uC18C\uCF13\uC774 \uB2EB\uD788\uAE30\uB97C \uAE30\uB2E4\uB9AC\uC9C0 \uB9D0\uACE0(onclose \uBBF8\uBC1C\uC0DD \uB300\uBE44), \uAC15\uC81C\uB85C \uC815\uB9AC \uD6C4 \uC7AC\uC5F0\uACB0\uD569\uB2C8\uB2E4.\n if (this._ws != null) {\n const tempWs = this._ws;\n this._ws = undefined; // \uC5F0\uACB0 \uC0C1\uD0DC \uB04A\uAE40\uC73C\uB85C \uAC04\uC8FC\n\n // \uAE30\uC874 \uC18C\uCF13\uC758 \uC774\uBCA4\uD2B8 \uD578\uB4E4\uB7EC \uC81C\uAC70\n // \uB4A4\uB2A6\uAC8C \uBC1C\uC0DD\uD55C onclose\uC5D0 \uB530\uB978 \uC911\uBCF5 \uC7AC\uC5F0\uACB0 \uBC29\uC9C0\n tempWs.onclose = null;\n tempWs.onerror = null;\n tempWs.onmessage = null;\n\n // \uC18C\uCF13 \uB2EB\uAE30 \uC2DC\uB3C4 (\uC5D0\uB7EC \uBB34\uC2DC)\n try {\n tempWs.close();\n } catch {\n // ignore\n }\n\n // \uC218\uB3D9 \uC885\uB8CC\uAC00 \uC544\uB2C8\uB77C\uBA74 \uC7AC\uC5F0\uACB0 \uB85C\uC9C1 \uAC15\uC81C \uC2E4\uD589\n if (!this._isManualClose) {\n void this._tryReconnect();\n }\n }\n return;\n }\n\n // ping \uC804\uC1A1\n const ws = this._ws;\n if (this.connected && ws != null) {\n try {\n ws.send(this._PING_PACKET);\n } catch (err) {\n logger.warn(\"Ping send failed\", err);\n }\n }\n }, this._HEARTBEAT_INTERVAL);\n }\n\n private _stopHeartbeat(): void {\n if (this._heartbeatTimer != null) {\n clearInterval(this._heartbeatTimer);\n this._heartbeatTimer = undefined;\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=connection-config.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=progress.types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,30 @@
1
+ import { ServiceProtocol } from "@simplysm/service-common";
2
+ import { transferableEncode } from "@simplysm/core-common";
3
+ const protocol = new ServiceProtocol();
4
+ self.onmessage = (event) => {
5
+ const { id, type, data } = event.data;
6
+ try {
7
+ let result;
8
+ let transferList = [];
9
+ if (type === "encode") {
10
+ const { uuid, message } = data;
11
+ const { chunks } = protocol.encode(uuid, message);
12
+ result = chunks;
13
+ transferList = chunks.map((chunk) => chunk.buffer);
14
+ } else {
15
+ const bytes = new Uint8Array(data);
16
+ const decodeResult = protocol.decode(bytes);
17
+ const encoded = transferableEncode(decodeResult);
18
+ result = encoded.result;
19
+ transferList = encoded.transferList;
20
+ }
21
+ self.postMessage({ id, type: "success", result }, { transfer: transferList });
22
+ } catch (err) {
23
+ self.postMessage({
24
+ id,
25
+ type: "error",
26
+ error: err instanceof Error ? { message: err.message, stack: err.stack } : { message: String(err) }
27
+ });
28
+ }
29
+ };
30
+ //# sourceMappingURL=client-protocol.worker.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/workers/client-protocol.worker.ts"],
4
+ "sourcesContent": ["/// <reference lib=\"webworker\" />\n\nimport { ServiceProtocol } from \"@simplysm/service-common\";\nimport { transferableEncode } from \"@simplysm/core-common\";\n\nconst protocol = new ServiceProtocol();\n\nself.onmessage = (event: MessageEvent) => {\n const { id, type, data } = event.data as {\n id: string;\n type: \"encode\" | \"decode\";\n data: unknown;\n };\n\n try {\n let result: unknown;\n let transferList: Transferable[] = [];\n\n if (type === \"encode\") {\n // [Main -> Worker] \uC778\uCF54\uB529 \uC694\uCCAD (data: { uuid, message })\n // message\uB294 \uC774\uBBF8 Plain Object\uB85C \uB118\uC5B4\uC634 (Structured Clone)\n const { uuid, message } = data as {\n uuid: string;\n message: Parameters<ServiceProtocol[\"encode\"]>[1];\n };\n const { chunks } = protocol.encode(uuid, message);\n\n // Buffer[]\uB294 \uC804\uC1A1 \uAC00\uB2A5\uD558\uBBC0\uB85C \uACB0\uACFC\uB85C \uBC18\uD658\n result = chunks;\n // \uACB0\uACFC\uBB3C \uCCAD\uD06C\uB4E4\uC758 \uB0B4\uBD80 ArrayBuffer\uB97C \uC18C\uC720\uAD8C \uC774\uC804 \uBAA9\uB85D\uC5D0 \uCD94\uAC00\n transferList = chunks.map((chunk) => chunk.buffer as ArrayBuffer);\n } else {\n // [Main -> Worker] \uB514\uCF54\uB529 \uC694\uCCAD (data: Uint8Array)\n // data\uB294 Uint8Array\uB85C \uB118\uC5B4\uC634\n const bytes = new Uint8Array(data as ArrayBuffer);\n const decodeResult = protocol.decode(bytes);\n\n // \uACB0\uACFC\uBB3C(\uAC1D\uCCB4)\uC744 \uC804\uC1A1 \uAC00\uB2A5\uD55C \uD615\uD0DC\uB85C \uBCC0\uD658 (Zero-Copy \uC900\uBE44)\n const encoded = transferableEncode(decodeResult);\n result = encoded.result;\n transferList = encoded.transferList;\n }\n\n // [Worker -> Main] \uC131\uACF5 \uC751\uB2F5\n self.postMessage({ id, type: \"success\", result }, { transfer: transferList });\n } catch (err) {\n // [Worker -> Main] \uC5D0\uB7EC \uC751\uB2F5\n self.postMessage({\n id,\n type: \"error\",\n error: err instanceof Error ? { message: err.message, stack: err.stack } : { message: String(err) },\n });\n }\n};\n"],
5
+ "mappings": "AAEA,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AAEnC,MAAM,WAAW,IAAI,gBAAgB;AAErC,KAAK,YAAY,CAAC,UAAwB;AACxC,QAAM,EAAE,IAAI,MAAM,KAAK,IAAI,MAAM;AAMjC,MAAI;AACF,QAAI;AACJ,QAAI,eAA+B,CAAC;AAEpC,QAAI,SAAS,UAAU;AAGrB,YAAM,EAAE,MAAM,QAAQ,IAAI;AAI1B,YAAM,EAAE,OAAO,IAAI,SAAS,OAAO,MAAM,OAAO;AAGhD,eAAS;AAET,qBAAe,OAAO,IAAI,CAAC,UAAU,MAAM,MAAqB;AAAA,IAClE,OAAO;AAGL,YAAM,QAAQ,IAAI,WAAW,IAAmB;AAChD,YAAM,eAAe,SAAS,OAAO,KAAK;AAG1C,YAAM,UAAU,mBAAmB,YAAY;AAC/C,eAAS,QAAQ;AACjB,qBAAe,QAAQ;AAAA,IACzB;AAGA,SAAK,YAAY,EAAE,IAAI,MAAM,WAAW,OAAO,GAAG,EAAE,UAAU,aAAa,CAAC;AAAA,EAC9E,SAAS,KAAK;AAEZ,SAAK,YAAY;AAAA,MACf;AAAA,MACA,MAAM;AAAA,MACN,OAAO,eAAe,QAAQ,EAAE,SAAS,IAAI,SAAS,OAAO,IAAI,MAAM,IAAI,EAAE,SAAS,OAAO,GAAG,EAAE;AAAA,IACpG,CAAC;AAAA,EACH;AACF;",
6
+ "names": []
7
+ }
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@simplysm/service-client",
3
+ "sideEffects": false,
4
+ "version": "13.0.0-beta.11",
5
+ "description": "심플리즘 패키지 - 서비스 모듈 (client)",
6
+ "author": "김석래",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/kslhunter/simplysm.git",
10
+ "directory": "packages/service-client"
11
+ },
12
+ "license": "Apache-2.0",
13
+ "type": "module",
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "dependencies": {
20
+ "consola": "^3.4.2",
21
+ "@simplysm/core-common": "13.0.0-beta.11",
22
+ "@simplysm/orm-common": "13.0.0-beta.11",
23
+ "@simplysm/service-common": "13.0.0-beta.11"
24
+ },
25
+ "devDependencies": {
26
+ "@types/ws": "^8.18.1",
27
+ "ws": "^8.19.0"
28
+ }
29
+ }