@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.
- package/README.md +397 -0
- package/dist/core-common/src/common.types.d.ts +74 -0
- package/dist/core-common/src/common.types.d.ts.map +1 -0
- package/dist/core-common/src/env.d.ts +6 -0
- package/dist/core-common/src/env.d.ts.map +1 -0
- package/dist/core-common/src/errors/argument-error.d.ts +25 -0
- package/dist/core-common/src/errors/argument-error.d.ts.map +1 -0
- package/dist/core-common/src/errors/not-implemented-error.d.ts +29 -0
- package/dist/core-common/src/errors/not-implemented-error.d.ts.map +1 -0
- package/dist/core-common/src/errors/sd-error.d.ts +27 -0
- package/dist/core-common/src/errors/sd-error.d.ts.map +1 -0
- package/dist/core-common/src/errors/timeout-error.d.ts +31 -0
- package/dist/core-common/src/errors/timeout-error.d.ts.map +1 -0
- package/dist/core-common/src/extensions/arr-ext.d.ts +15 -0
- package/dist/core-common/src/extensions/arr-ext.d.ts.map +1 -0
- package/dist/core-common/src/extensions/arr-ext.helpers.d.ts +19 -0
- package/dist/core-common/src/extensions/arr-ext.helpers.d.ts.map +1 -0
- package/dist/core-common/src/extensions/arr-ext.types.d.ts +215 -0
- package/dist/core-common/src/extensions/arr-ext.types.d.ts.map +1 -0
- package/dist/core-common/src/extensions/map-ext.d.ts +57 -0
- package/dist/core-common/src/extensions/map-ext.d.ts.map +1 -0
- package/dist/core-common/src/extensions/set-ext.d.ts +36 -0
- package/dist/core-common/src/extensions/set-ext.d.ts.map +1 -0
- package/dist/core-common/src/features/debounce-queue.d.ts +53 -0
- package/dist/core-common/src/features/debounce-queue.d.ts.map +1 -0
- package/dist/core-common/src/features/event-emitter.d.ts +66 -0
- package/dist/core-common/src/features/event-emitter.d.ts.map +1 -0
- package/dist/core-common/src/features/serial-queue.d.ts +47 -0
- package/dist/core-common/src/features/serial-queue.d.ts.map +1 -0
- package/dist/core-common/src/index.d.ts +32 -0
- package/dist/core-common/src/index.d.ts.map +1 -0
- package/dist/core-common/src/types/date-only.d.ts +152 -0
- package/dist/core-common/src/types/date-only.d.ts.map +1 -0
- package/dist/core-common/src/types/date-time.d.ts +96 -0
- package/dist/core-common/src/types/date-time.d.ts.map +1 -0
- package/dist/core-common/src/types/lazy-gc-map.d.ts +80 -0
- package/dist/core-common/src/types/lazy-gc-map.d.ts.map +1 -0
- package/dist/core-common/src/types/time.d.ts +68 -0
- package/dist/core-common/src/types/time.d.ts.map +1 -0
- package/dist/core-common/src/types/uuid.d.ts +35 -0
- package/dist/core-common/src/types/uuid.d.ts.map +1 -0
- package/dist/core-common/src/utils/bytes.d.ts +51 -0
- package/dist/core-common/src/utils/bytes.d.ts.map +1 -0
- package/dist/core-common/src/utils/date-format.d.ts +90 -0
- package/dist/core-common/src/utils/date-format.d.ts.map +1 -0
- package/dist/core-common/src/utils/json.d.ts +34 -0
- package/dist/core-common/src/utils/json.d.ts.map +1 -0
- package/dist/core-common/src/utils/num.d.ts +60 -0
- package/dist/core-common/src/utils/num.d.ts.map +1 -0
- package/dist/core-common/src/utils/obj.d.ts +258 -0
- package/dist/core-common/src/utils/obj.d.ts.map +1 -0
- package/dist/core-common/src/utils/path.d.ts +23 -0
- package/dist/core-common/src/utils/path.d.ts.map +1 -0
- package/dist/core-common/src/utils/primitive.d.ts +18 -0
- package/dist/core-common/src/utils/primitive.d.ts.map +1 -0
- package/dist/core-common/src/utils/str.d.ts +103 -0
- package/dist/core-common/src/utils/str.d.ts.map +1 -0
- package/dist/core-common/src/utils/template-strings.d.ts +84 -0
- package/dist/core-common/src/utils/template-strings.d.ts.map +1 -0
- package/dist/core-common/src/utils/transferable.d.ts +47 -0
- package/dist/core-common/src/utils/transferable.d.ts.map +1 -0
- package/dist/core-common/src/utils/wait.d.ts +19 -0
- package/dist/core-common/src/utils/wait.d.ts.map +1 -0
- package/dist/core-common/src/utils/xml.d.ts +36 -0
- package/dist/core-common/src/utils/xml.d.ts.map +1 -0
- package/dist/core-common/src/zip/sd-zip.d.ts +80 -0
- package/dist/core-common/src/zip/sd-zip.d.ts.map +1 -0
- package/dist/features/event-client.js +74 -0
- package/dist/features/event-client.js.map +7 -0
- package/dist/features/file-client.js +42 -0
- package/dist/features/file-client.js.map +7 -0
- package/dist/features/orm/orm-client-connector.js +41 -0
- package/dist/features/orm/orm-client-connector.js.map +7 -0
- package/dist/features/orm/orm-client-db-context-executor.js +61 -0
- package/dist/features/orm/orm-client-db-context-executor.js.map +7 -0
- package/dist/features/orm/orm-connect-config.js +1 -0
- package/dist/features/orm/orm-connect-config.js.map +7 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +7 -0
- package/dist/orm-common/src/db-context.d.ts +669 -0
- package/dist/orm-common/src/db-context.d.ts.map +1 -0
- package/dist/orm-common/src/errors/db-transaction-error.d.ts +51 -0
- package/dist/orm-common/src/errors/db-transaction-error.d.ts.map +1 -0
- package/dist/orm-common/src/exec/executable.d.ts +79 -0
- package/dist/orm-common/src/exec/executable.d.ts.map +1 -0
- package/dist/orm-common/src/exec/queryable.d.ts +708 -0
- package/dist/orm-common/src/exec/queryable.d.ts.map +1 -0
- package/dist/orm-common/src/exec/search-parser.d.ts +72 -0
- package/dist/orm-common/src/exec/search-parser.d.ts.map +1 -0
- package/dist/orm-common/src/expr/expr-unit.d.ts +25 -0
- package/dist/orm-common/src/expr/expr-unit.d.ts.map +1 -0
- package/dist/orm-common/src/expr/expr.d.ts +1369 -0
- package/dist/orm-common/src/expr/expr.d.ts.map +1 -0
- package/dist/orm-common/src/index.d.ts +32 -0
- package/dist/orm-common/src/index.d.ts.map +1 -0
- package/dist/orm-common/src/models/system-migration.d.ts +10 -0
- package/dist/orm-common/src/models/system-migration.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/base/expr-renderer-base.d.ts +95 -0
- package/dist/orm-common/src/query-builder/base/expr-renderer-base.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/base/query-builder-base.d.ts +66 -0
- package/dist/orm-common/src/query-builder/base/query-builder-base.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/mssql/mssql-expr-renderer.d.ts +84 -0
- package/dist/orm-common/src/query-builder/mssql/mssql-expr-renderer.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/mssql/mssql-query-builder.d.ts +45 -0
- package/dist/orm-common/src/query-builder/mssql/mssql-query-builder.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/mysql/mysql-expr-renderer.d.ts +84 -0
- package/dist/orm-common/src/query-builder/mysql/mysql-expr-renderer.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/mysql/mysql-query-builder.d.ts +54 -0
- package/dist/orm-common/src/query-builder/mysql/mysql-query-builder.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/postgresql/postgresql-expr-renderer.d.ts +84 -0
- package/dist/orm-common/src/query-builder/postgresql/postgresql-expr-renderer.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/postgresql/postgresql-query-builder.d.ts +52 -0
- package/dist/orm-common/src/query-builder/postgresql/postgresql-query-builder.d.ts.map +1 -0
- package/dist/orm-common/src/query-builder/query-builder.d.ts +7 -0
- package/dist/orm-common/src/query-builder/query-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/factory/column-builder.d.ts +394 -0
- package/dist/orm-common/src/schema/factory/column-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/factory/index-builder.d.ts +151 -0
- package/dist/orm-common/src/schema/factory/index-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/factory/relation-builder.d.ts +337 -0
- package/dist/orm-common/src/schema/factory/relation-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/procedure-builder.d.ts +202 -0
- package/dist/orm-common/src/schema/procedure-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/table-builder.d.ts +259 -0
- package/dist/orm-common/src/schema/table-builder.d.ts.map +1 -0
- package/dist/orm-common/src/schema/view-builder.d.ts +183 -0
- package/dist/orm-common/src/schema/view-builder.d.ts.map +1 -0
- package/dist/orm-common/src/types/column.d.ts +172 -0
- package/dist/orm-common/src/types/column.d.ts.map +1 -0
- package/dist/orm-common/src/types/db.d.ts +175 -0
- package/dist/orm-common/src/types/db.d.ts.map +1 -0
- package/dist/orm-common/src/types/expr.d.ts +474 -0
- package/dist/orm-common/src/types/expr.d.ts.map +1 -0
- package/dist/orm-common/src/types/query-def.d.ts +351 -0
- package/dist/orm-common/src/types/query-def.d.ts.map +1 -0
- package/dist/orm-common/src/utils/result-parser.d.ts +38 -0
- package/dist/orm-common/src/utils/result-parser.d.ts.map +1 -0
- package/dist/protocol/client-protocol-wrapper.js +92 -0
- package/dist/protocol/client-protocol-wrapper.js.map +7 -0
- package/dist/service-client/src/features/event-client.d.ts +14 -0
- package/dist/service-client/src/features/event-client.d.ts.map +1 -0
- package/dist/service-client/src/features/file-client.d.ts +13 -0
- package/dist/service-client/src/features/file-client.d.ts.map +1 -0
- package/dist/service-client/src/features/orm/orm-client-connector.d.ts +10 -0
- package/dist/service-client/src/features/orm/orm-client-connector.d.ts.map +1 -0
- package/dist/service-client/src/features/orm/orm-client-db-context-executor.d.ts +26 -0
- package/dist/service-client/src/features/orm/orm-client-db-context-executor.d.ts.map +1 -0
- package/dist/service-client/src/features/orm/orm-connect-config.d.ts +13 -0
- package/dist/service-client/src/features/orm/orm-connect-config.d.ts.map +1 -0
- package/dist/service-client/src/index.d.ts +12 -0
- package/dist/service-client/src/index.d.ts.map +1 -0
- package/dist/service-client/src/protocol/client-protocol-wrapper.d.ts +23 -0
- package/dist/service-client/src/protocol/client-protocol-wrapper.d.ts.map +1 -0
- package/dist/service-client/src/service-client.d.ts +41 -0
- package/dist/service-client/src/service-client.d.ts.map +1 -0
- package/dist/service-client/src/transport/service-transport.d.ts +24 -0
- package/dist/service-client/src/transport/service-transport.d.ts.map +1 -0
- package/dist/service-client/src/transport/socket-provider.d.ts +31 -0
- package/dist/service-client/src/transport/socket-provider.d.ts.map +1 -0
- package/dist/service-client/src/types/connection-config.d.ts +8 -0
- package/dist/service-client/src/types/connection-config.d.ts.map +1 -0
- package/dist/service-client/src/types/progress.types.d.ts +10 -0
- package/dist/service-client/src/types/progress.types.d.ts.map +1 -0
- package/dist/service-client/src/workers/client-protocol.worker.d.ts +2 -0
- package/dist/service-client/src/workers/client-protocol.worker.d.ts.map +1 -0
- package/dist/service-client.js +114 -0
- package/dist/service-client.js.map +7 -0
- package/dist/service-common/src/index.d.ts +8 -0
- package/dist/service-common/src/index.d.ts.map +1 -0
- package/dist/service-common/src/protocol/protocol.types.d.ts +100 -0
- package/dist/service-common/src/protocol/protocol.types.d.ts.map +1 -0
- package/dist/service-common/src/protocol/service-protocol.d.ts +63 -0
- package/dist/service-common/src/protocol/service-protocol.d.ts.map +1 -0
- package/dist/service-common/src/service-types/auto-update-service.types.d.ts +17 -0
- package/dist/service-common/src/service-types/auto-update-service.types.d.ts.map +1 -0
- package/dist/service-common/src/service-types/crypto-service.types.d.ts +22 -0
- package/dist/service-common/src/service-types/crypto-service.types.d.ts.map +1 -0
- package/dist/service-common/src/service-types/orm-service.types.d.ts +30 -0
- package/dist/service-common/src/service-types/orm-service.types.d.ts.map +1 -0
- package/dist/service-common/src/service-types/smtp-service.types.d.ts +55 -0
- package/dist/service-common/src/service-types/smtp-service.types.d.ts.map +1 -0
- package/dist/service-common/src/types.d.ts +43 -0
- package/dist/service-common/src/types.d.ts.map +1 -0
- package/dist/transport/service-transport.js +112 -0
- package/dist/transport/service-transport.js.map +7 -0
- package/dist/transport/socket-provider.js +170 -0
- package/dist/transport/socket-provider.js.map +7 -0
- package/dist/types/connection-config.js +1 -0
- package/dist/types/connection-config.js.map +7 -0
- package/dist/types/progress.types.js +1 -0
- package/dist/types/progress.types.js.map +7 -0
- package/dist/workers/client-protocol.worker.js +30 -0
- package/dist/workers/client-protocol.worker.js.map +7 -0
- 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 @@
|
|
|
1
|
+
//# sourceMappingURL=progress.types.js.map
|
|
@@ -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
|
+
}
|