@simplysm/service-client 13.0.100 → 14.0.4

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 (67) hide show
  1. package/README.md +403 -89
  2. package/dist/features/event-client.d.ts.map +1 -1
  3. package/dist/features/event-client.js +75 -67
  4. package/dist/features/event-client.js.map +1 -6
  5. package/dist/features/file-client.d.ts +3 -2
  6. package/dist/features/file-client.d.ts.map +1 -1
  7. package/dist/features/file-client.js +41 -39
  8. package/dist/features/file-client.js.map +1 -6
  9. package/dist/features/orm/orm-client-connector.js +37 -38
  10. package/dist/features/orm/orm-client-connector.js.map +1 -6
  11. package/dist/features/orm/orm-client-db-context-executor.d.ts.map +1 -1
  12. package/dist/features/orm/orm-client-db-context-executor.js +60 -60
  13. package/dist/features/orm/orm-client-db-context-executor.js.map +1 -6
  14. package/dist/features/orm/orm-connect-options.js +2 -1
  15. package/dist/features/orm/orm-connect-options.js.map +1 -6
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +7 -1
  19. package/dist/index.js.map +1 -6
  20. package/dist/protocol/client-protocol-wrapper.d.ts +1 -0
  21. package/dist/protocol/client-protocol-wrapper.d.ts.map +1 -1
  22. package/dist/protocol/client-protocol-wrapper.js +93 -70
  23. package/dist/protocol/client-protocol-wrapper.js.map +1 -6
  24. package/dist/service-client.d.ts +5 -3
  25. package/dist/service-client.d.ts.map +1 -1
  26. package/dist/service-client.js +110 -111
  27. package/dist/service-client.js.map +1 -6
  28. package/dist/transport/service-transport.d.ts +0 -1
  29. package/dist/transport/service-transport.d.ts.map +1 -1
  30. package/dist/transport/service-transport.js +115 -104
  31. package/dist/transport/service-transport.js.map +1 -6
  32. package/dist/transport/socket-provider.d.ts.map +1 -1
  33. package/dist/transport/socket-provider.js +185 -155
  34. package/dist/transport/socket-provider.js.map +1 -6
  35. package/dist/types/browser-compat.d.ts +33 -0
  36. package/dist/types/browser-compat.d.ts.map +1 -0
  37. package/dist/types/browser-compat.js +17 -0
  38. package/dist/types/browser-compat.js.map +1 -0
  39. package/dist/types/connection-options.d.ts +1 -1
  40. package/dist/types/connection-options.d.ts.map +1 -1
  41. package/dist/types/connection-options.js +2 -1
  42. package/dist/types/connection-options.js.map +1 -6
  43. package/dist/types/progress.types.d.ts +1 -0
  44. package/dist/types/progress.types.d.ts.map +1 -1
  45. package/dist/types/progress.types.js +2 -1
  46. package/dist/types/progress.types.js.map +1 -6
  47. package/dist/workers/client-protocol.worker.js +38 -24
  48. package/dist/workers/client-protocol.worker.js.map +1 -6
  49. package/package.json +16 -9
  50. package/src/features/event-client.ts +19 -17
  51. package/src/features/file-client.ts +11 -10
  52. package/src/features/orm/orm-client-connector.ts +2 -2
  53. package/src/features/orm/orm-client-db-context-executor.ts +8 -7
  54. package/src/index.ts +6 -5
  55. package/src/protocol/client-protocol-wrapper.ts +37 -28
  56. package/src/service-client.ts +24 -20
  57. package/src/transport/service-transport.ts +19 -25
  58. package/src/transport/socket-provider.ts +44 -38
  59. package/src/types/browser-compat.ts +47 -0
  60. package/src/types/connection-options.ts +1 -1
  61. package/src/types/progress.types.ts +1 -0
  62. package/src/workers/client-protocol.worker.ts +10 -10
  63. package/docs/features.md +0 -143
  64. package/docs/protocol.md +0 -29
  65. package/docs/service-client.md +0 -93
  66. package/docs/transport.md +0 -96
  67. package/docs/types.md +0 -55
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Cross-environment compatible types for browser globals.
3
+ * DOM-only 타입(FileList, BlobPart, Worker, Transferable)을 대체하여
4
+ * Node.js / browser 양쪽 환경에서 typecheck가 통과하도록 한다.
5
+ */
6
+ /** Blob constructor가 허용하는 데이터 타입 (DOM BlobPart 대체) */
7
+ export type BlobInput = Blob | Uint8Array<ArrayBuffer> | ArrayBuffer | string;
8
+ /**
9
+ * File 컬렉션 인터페이스 (DOM FileList 대체).
10
+ * 브라우저 FileList와 구조적으로 호환됨.
11
+ */
12
+ export interface FileCollection {
13
+ readonly length: number;
14
+ item(index: number): File | null;
15
+ [index: number]: File;
16
+ [Symbol.iterator](): IterableIterator<File>;
17
+ }
18
+ /**
19
+ * Web Worker 인터페이스 (DOM Worker 대체).
20
+ * 브라우저 Worker와 구조적으로 호환됨.
21
+ */
22
+ export interface WorkerLike {
23
+ onmessage: ((ev: MessageEvent) => void) | null;
24
+ postMessage(message: unknown, transfer?: unknown[]): void;
25
+ terminate(): void;
26
+ }
27
+ /** Web Worker API 지원 여부 확인 */
28
+ export declare function isWorkerSupported(): boolean;
29
+ /** Web Worker 생성 (미지원 환경이면 undefined) */
30
+ export declare function createBrowserWorker(url: URL, options: {
31
+ type: string;
32
+ }): WorkerLike | undefined;
33
+ //# sourceMappingURL=browser-compat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-compat.d.ts","sourceRoot":"","sources":["..\\..\\src\\types\\browser-compat.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,sDAAsD;AACtD,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,WAAW,GAAG,MAAM,CAAC;AAE9E;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACjC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/C,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC1D,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,8BAA8B;AAC9B,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,yCAAyC;AACzC,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GACxB,UAAU,GAAG,SAAS,CAOxB"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Cross-environment compatible types for browser globals.
3
+ * DOM-only 타입(FileList, BlobPart, Worker, Transferable)을 대체하여
4
+ * Node.js / browser 양쪽 환경에서 typecheck가 통과하도록 한다.
5
+ */
6
+ /** Web Worker API 지원 여부 확인 */
7
+ export function isWorkerSupported() {
8
+ return "Worker" in globalThis;
9
+ }
10
+ /** Web Worker 생성 (미지원 환경이면 undefined) */
11
+ export function createBrowserWorker(url, options) {
12
+ if (!isWorkerSupported())
13
+ return undefined;
14
+ const ctor = globalThis["Worker"];
15
+ return new ctor(url, options);
16
+ }
17
+ //# sourceMappingURL=browser-compat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-compat.js","sourceRoot":"","sources":["..\\..\\src\\types\\browser-compat.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0BH,8BAA8B;AAC9B,MAAM,UAAU,iBAAiB;IAC/B,OAAO,QAAQ,IAAI,UAAU,CAAC;AAChC,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,mBAAmB,CACjC,GAAQ,EACR,OAAyB;IAEzB,IAAI,CAAC,iBAAiB,EAAE;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,IAAI,GAAI,UAAsC,CAAC,QAAQ,CAG9C,CAAC;IAChB,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAChC,CAAC"}
@@ -2,7 +2,7 @@ export interface ServiceConnectionOptions {
2
2
  port: number;
3
3
  host: string;
4
4
  ssl?: boolean;
5
- /** Set to 0 to disable reconnect; disconnects immediately */
5
+ /** 0으로 설정하면 재연결을 비활성화하고 즉시 연결을 끊음 */
6
6
  maxReconnectCount?: number;
7
7
  }
8
8
  //# sourceMappingURL=connection-options.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connection-options.d.ts","sourceRoot":"","sources":["..\\..\\src\\types\\connection-options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B"}
1
+ {"version":3,"file":"connection-options.d.ts","sourceRoot":"","sources":["..\\..\\src\\types\\connection-options.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,qCAAqC;IACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B"}
@@ -1 +1,2 @@
1
- //# sourceMappingURL=connection-options.js.map
1
+ export {};
2
+ //# sourceMappingURL=connection-options.js.map
@@ -1,6 +1 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "mappings": "",
5
- "names": []
6
- }
1
+ {"version":3,"file":"connection-options.js","sourceRoot":"","sources":["..\\..\\src\\types\\connection-options.ts"],"names":[],"mappings":""}
@@ -1,6 +1,7 @@
1
1
  export interface ServiceProgress {
2
2
  request?: (s: ServiceProgressState) => void;
3
3
  response?: (s: ServiceProgressState) => void;
4
+ server?: (s: ServiceProgressState) => void;
4
5
  }
5
6
  export interface ServiceProgressState {
6
7
  uuid: string;
@@ -1 +1 @@
1
- {"version":3,"file":"progress.types.d.ts","sourceRoot":"","sources":["..\\..\\src\\types\\progress.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC9C;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB"}
1
+ {"version":3,"file":"progress.types.d.ts","sourceRoot":"","sources":["..\\..\\src\\types\\progress.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC7C,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAC;CAC5C;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB"}
@@ -1 +1,2 @@
1
- //# sourceMappingURL=progress.types.js.map
1
+ export {};
2
+ //# sourceMappingURL=progress.types.js.map
@@ -1,6 +1 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "mappings": "",
5
- "names": []
6
- }
1
+ {"version":3,"file":"progress.types.js","sourceRoot":"","sources":["..\\..\\src\\types\\progress.types.ts"],"names":[],"mappings":""}
@@ -1,30 +1,44 @@
1
+ /// <reference lib="webworker" />
1
2
  import { createServiceProtocol } from "@simplysm/service-common";
2
3
  import { transfer } from "@simplysm/core-common";
3
4
  const protocol = createServiceProtocol();
4
5
  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 = transfer.encode(decodeResult);
18
- result = encoded.result;
19
- transferList = encoded.transferList;
6
+ const { id, type, data } = event.data;
7
+ try {
8
+ let result;
9
+ let transferList = [];
10
+ if (type === "encode") {
11
+ // [Main -> Worker] 인코딩 요청 (data: { uuid, message })
12
+ // message는 이미 Plain Object임 (Structured Clone을 통해 전달)
13
+ const { uuid, message } = data;
14
+ const { chunks } = protocol.encode(uuid, message);
15
+ // Buffer[]는 전송 가능하므로 결과로 반환
16
+ result = chunks;
17
+ // 결과 chunk의 내부 ArrayBuffer를 전송 목록에 추가
18
+ transferList = chunks.map((chunk) => chunk.buffer);
19
+ }
20
+ else {
21
+ // [Main -> Worker] 디코딩 요청 (data: Uint8Array)
22
+ // data는 Uint8Array로 전달됨
23
+ const bytes = new Uint8Array(data);
24
+ const decodeResult = protocol.decode(bytes);
25
+ // 결과 객체를 전송 가능한 형태로 변환 (zero-copy 준비)
26
+ const encoded = transfer.encode(decodeResult);
27
+ result = encoded.result;
28
+ transferList = encoded.transferList;
29
+ }
30
+ // [Worker -> Main] 성공 응답
31
+ self.postMessage({ id, type: "success", result }, transferList);
32
+ }
33
+ catch (err) {
34
+ // [Worker -> Main] 에러 응답
35
+ self.postMessage({
36
+ id,
37
+ type: "error",
38
+ error: err instanceof Error
39
+ ? { message: err.message, stack: err.stack }
40
+ : { message: String(err) },
41
+ });
20
42
  }
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
43
  };
30
- //# sourceMappingURL=client-protocol.worker.js.map
44
+ //# sourceMappingURL=client-protocol.worker.js.map
@@ -1,6 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/workers/client-protocol.worker.ts"],
4
- "mappings": "AAEA,SAAS,6BAA6B;AACtC,SAAS,gBAAgB;AAEzB,MAAM,WAAW,sBAAsB;AAEvC,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,SAAS,OAAO,YAAY;AAC5C,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,OACE,eAAe,QACX,EAAE,SAAS,IAAI,SAAS,OAAO,IAAI,MAAM,IACzC,EAAE,SAAS,OAAO,GAAG,EAAE;AAAA,IAC/B,CAAC;AAAA,EACH;AACF;",
5
- "names": []
6
- }
1
+ {"version":3,"file":"client-protocol.worker.js","sourceRoot":"","sources":["..\\..\\src\\workers\\client-protocol.worker.ts"],"names":[],"mappings":"AAAA,iCAAiC;AAEjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,MAAM,QAAQ,GAAG,qBAAqB,EAAE,CAAC;AAEzC,IAAI,CAAC,SAAS,GAAG,CAAC,KAAmB,EAAE,EAAE;IACvC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAIhC,CAAC;IAEF,IAAI,CAAC;QACH,IAAI,MAAe,CAAC;QACpB,IAAI,YAAY,GAAmB,EAAE,CAAC;QAEtC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,oDAAoD;YACpD,sDAAsD;YACtD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAGzB,CAAC;YACF,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAElD,4BAA4B;YAC5B,MAAM,GAAG,MAAM,CAAC;YAChB,sCAAsC;YACtC,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAqB,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,6CAA6C;YAC7C,wBAAwB;YACxB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAmB,CAAC,CAAC;YAClD,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAE5C,sCAAsC;YACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAC9C,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YACxB,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACtC,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC;IAClE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,yBAAyB;QACzB,IAAI,CAAC,WAAW,CAAC;YACf,EAAE;YACF,IAAI,EAAE,OAAO;YACb,KAAK,EACH,GAAG,YAAY,KAAK;gBAClB,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE;gBAC5C,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE;SAC/B,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@simplysm/service-client",
3
- "version": "13.0.100",
4
- "description": "Simplysm package - Service module (client)",
5
- "author": "simplysm",
3
+ "version": "14.0.4",
4
+ "description": "심플리즘 패키지 - 서비스 (client)",
5
+ "author": "심플리즘",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
8
8
  "type": "git",
@@ -14,18 +14,25 @@
14
14
  "types": "./dist/index.d.ts",
15
15
  "files": [
16
16
  "dist",
17
- "src",
18
- "docs"
17
+ "src"
19
18
  ],
20
19
  "sideEffects": false,
21
20
  "dependencies": {
22
21
  "consola": "^3.4.2",
23
- "@simplysm/core-common": "13.0.100",
24
- "@simplysm/orm-common": "13.0.100",
25
- "@simplysm/service-common": "13.0.100"
22
+ "@simplysm/core-common": "14.0.4",
23
+ "@simplysm/orm-common": "14.0.4",
24
+ "@simplysm/service-common": "14.0.4"
26
25
  },
27
26
  "devDependencies": {
28
27
  "@types/ws": "^8.18.1",
29
- "ws": "^8.19.0"
28
+ "ws": "^8.20.0"
29
+ },
30
+ "peerDependencies": {
31
+ "ws": "^8"
32
+ },
33
+ "peerDependenciesMeta": {
34
+ "ws": {
35
+ "optional": true
36
+ }
30
37
  }
31
38
  }
@@ -38,13 +38,13 @@ export function createEventClient(transport: ServiceTransport): EventClient {
38
38
  const key = Uuid.generate().toString();
39
39
  const eventName = eventDef.eventName;
40
40
 
41
- // Send registration request to server
41
+ // 서버에 등록 요청 전송
42
42
  await transport.send({
43
43
  name: "evt:add",
44
44
  body: { key, name: eventName, info },
45
45
  });
46
46
 
47
- // Store in local map (for recovery on reconnect)
47
+ // 로컬 맵에 저장 (재연결 복구용)
48
48
  listenerMap.set(key, {
49
49
  eventName,
50
50
  info,
@@ -59,7 +59,7 @@ export function createEventClient(transport: ServiceTransport): EventClient {
59
59
  try {
60
60
  await transport.send({ name: "evt:remove", body: { key } });
61
61
  } catch {
62
- // Server auto-cleans event listeners on disconnect; safe to ignore
62
+ // 서버가 연결 끊김 이벤트 리스너를 자동 정리하므로 무시해도 안전함
63
63
  }
64
64
  }
65
65
 
@@ -70,7 +70,7 @@ export function createEventClient(transport: ServiceTransport): EventClient {
70
70
  ): Promise<void> {
71
71
  const eventName = eventDef.eventName;
72
72
 
73
- // Send 'gets' request to server to obtain targets
73
+ // 서버에 'gets' 요청을 보내 대상 목록 조회
74
74
  const listenerInfos = (await transport.send({
75
75
  name: "evt:gets",
76
76
  body: { name: eventName },
@@ -88,21 +88,23 @@ export function createEventClient(transport: ServiceTransport): EventClient {
88
88
  }
89
89
  }
90
90
 
91
- // Called on reconnect
91
+ // 재연결 호출
92
92
  async function resubscribeAll(): Promise<void> {
93
- for (const [key, value] of listenerMap.entries()) {
94
- try {
95
- await transport.send({
96
- name: "evt:add",
97
- body: { key, name: value.eventName, info: value.info },
98
- });
99
- } catch (err) {
100
- logger.error("Failed to recover event listener", { err, eventName: value.eventName });
101
- }
102
- }
93
+ await Promise.allSettled(
94
+ Array.from(listenerMap.entries()).map(async ([key, value]) => {
95
+ try {
96
+ await transport.send({
97
+ name: "evt:add",
98
+ body: { key, name: value.eventName, info: value.info },
99
+ });
100
+ } catch (err) {
101
+ logger.error("이벤트 리스너 복구 실패", { err, eventName: value.eventName });
102
+ }
103
+ }),
104
+ );
103
105
  }
104
106
 
105
- // Dispatch server events to local listeners
107
+ // 서버 이벤트를 로컬 리스너에 디스패치
106
108
  async function executeByKey(keys: string[], data: unknown): Promise<void> {
107
109
  for (const key of keys) {
108
110
  const entry = listenerMap.get(key);
@@ -110,7 +112,7 @@ export function createEventClient(transport: ServiceTransport): EventClient {
110
112
  try {
111
113
  await entry.cb(data);
112
114
  } catch (err) {
113
- logger.error("Event handler error", { err, eventName: entry.eventName });
115
+ logger.error("이벤트 핸들러 에러", { err, eventName: entry.eventName });
114
116
  }
115
117
  }
116
118
  }
@@ -1,22 +1,23 @@
1
1
  import type { Bytes } from "@simplysm/core-common";
2
2
  import type { ServiceUploadResult } from "@simplysm/service-common";
3
+ import type { BlobInput, FileCollection } from "../types/browser-compat";
3
4
 
4
5
  export interface FileClient {
5
6
  download(relPath: string): Promise<Bytes>;
6
7
  upload(
7
- files: File[] | FileList | { name: string; data: BlobPart }[],
8
+ files: File[] | FileCollection | { name: string; data: BlobInput }[],
8
9
  authToken: string,
9
10
  ): Promise<ServiceUploadResult[]>;
10
11
  }
11
12
 
12
13
  export function createFileClient(hostUrl: string, clientName: string): FileClient {
13
14
  async function download(relPath: string): Promise<Bytes> {
14
- // Build URL
15
+ // URL 생성
15
16
  const url = `${hostUrl}${relPath.startsWith("/") ? "" : "/"}${relPath}`;
16
17
 
17
18
  const res = await fetch(url);
18
19
  if (!res.ok) {
19
- throw new Error(`Download failed: ${res.status} ${res.statusText}`);
20
+ throw new Error(`다운로드 실패: ${res.status} ${res.statusText}`);
20
21
  }
21
22
 
22
23
  // ArrayBuffer -> Uint8Array
@@ -24,19 +25,19 @@ export function createFileClient(hostUrl: string, clientName: string): FileClien
24
25
  }
25
26
 
26
27
  async function upload(
27
- files: File[] | FileList | { name: string; data: BlobPart }[],
28
+ files: File[] | FileCollection | { name: string; data: BlobInput }[],
28
29
  authToken: string,
29
30
  ): Promise<ServiceUploadResult[]> {
30
31
  const formData = new FormData();
31
- const fileList = files instanceof FileList ? Array.from(files) : files;
32
+ const fileArr = Array.isArray(files) ? files : Array.from(files);
32
33
 
33
- for (const file of fileList) {
34
+ for (const file of fileArr) {
34
35
  if ("data" in file) {
35
- // Custom object ({ name, data })
36
+ // 커스텀 객체 ({ name, data })
36
37
  const blob = file.data instanceof Blob ? file.data : new Blob([file.data]);
37
38
  formData.append("files", blob, file.name);
38
39
  } else {
39
- // Browser File object
40
+ // 브라우저 File 객체
40
41
  formData.append("files", file, file.name);
41
42
  }
42
43
  }
@@ -51,10 +52,10 @@ export function createFileClient(hostUrl: string, clientName: string): FileClien
51
52
  });
52
53
 
53
54
  if (!res.ok) {
54
- throw new Error(`Upload failed: ${res.statusText}`);
55
+ throw new Error(`업로드 실패: ${res.statusText}`);
55
56
  }
56
57
 
57
- return res.json();
58
+ return (await res.json()) as ServiceUploadResult[];
58
59
  }
59
60
 
60
61
  return {
@@ -22,7 +22,7 @@ export function createOrmClientConnector(serviceClient: ServiceClient): OrmClien
22
22
  const info = await executor.getInfo();
23
23
  const database = config.dbContextOpt?.database ?? info.database;
24
24
  if (database == null || database === "") {
25
- throw new Error("database is required");
25
+ throw new Error("database 필수입니다.");
26
26
  }
27
27
  return createDbContext(config.dbContextDef, executor, {
28
28
  database,
@@ -44,7 +44,7 @@ export function createOrmClientConnector(serviceClient: ServiceClient): OrmClien
44
44
  (err.message.includes("a parent row: a foreign key constraint") ||
45
45
  err.message.includes("conflicted with the REFERENCE"))
46
46
  ) {
47
- throw new Error("Warning! Operation rejected due to related operations. Please check subsequent operations.", { cause: err });
47
+ throw new Error("경고! 연관된 작업으로 인해 작업이 거부되었습니다. 후속 작업을 확인해 주세요.", { cause: err });
48
48
  }
49
49
 
50
50
  throw err;
@@ -34,7 +34,7 @@ export class OrmClientDbContextExecutor implements DbContextExecutor {
34
34
 
35
35
  async beginTransaction(isolationLevel?: IsolationLevel): Promise<void> {
36
36
  if (this._connId === undefined) {
37
- throw new Error("Not connected to the database.");
37
+ throw new Error("데이터베이스에 연결되지 않았습니다.");
38
38
  }
39
39
 
40
40
  await this._ormService.beginTransaction(this._connId, isolationLevel);
@@ -42,7 +42,7 @@ export class OrmClientDbContextExecutor implements DbContextExecutor {
42
42
 
43
43
  async commitTransaction(): Promise<void> {
44
44
  if (this._connId === undefined) {
45
- throw new Error("Not connected to the database.");
45
+ throw new Error("데이터베이스에 연결되지 않았습니다.");
46
46
  }
47
47
 
48
48
  await this._ormService.commitTransaction(this._connId);
@@ -50,7 +50,7 @@ export class OrmClientDbContextExecutor implements DbContextExecutor {
50
50
 
51
51
  async rollbackTransaction(): Promise<void> {
52
52
  if (this._connId === undefined) {
53
- throw new Error("Not connected to the database.");
53
+ throw new Error("데이터베이스에 연결되지 않았습니다.");
54
54
  }
55
55
 
56
56
  await this._ormService.rollbackTransaction(this._connId);
@@ -58,10 +58,11 @@ export class OrmClientDbContextExecutor implements DbContextExecutor {
58
58
 
59
59
  async close(): Promise<void> {
60
60
  if (this._connId === undefined) {
61
- throw new Error("Not connected to the database.");
61
+ throw new Error("데이터베이스에 연결되지 않았습니다.");
62
62
  }
63
63
 
64
64
  await this._ormService.close(this._connId);
65
+ this._connId = undefined;
65
66
  }
66
67
 
67
68
  async executeDefs<T = Record<string, unknown>>(
@@ -69,7 +70,7 @@ export class OrmClientDbContextExecutor implements DbContextExecutor {
69
70
  options?: (ResultMeta | undefined)[],
70
71
  ): Promise<T[][]> {
71
72
  if (this._connId === undefined) {
72
- throw new Error("Not connected to the database.");
73
+ throw new Error("데이터베이스에 연결되지 않았습니다.");
73
74
  }
74
75
 
75
76
  return (await this._ormService.executeDefs(this._connId, defs, options)) as T[][];
@@ -77,7 +78,7 @@ export class OrmClientDbContextExecutor implements DbContextExecutor {
77
78
 
78
79
  async executeParametrized(query: string, params?: unknown[]): Promise<unknown[][]> {
79
80
  if (this._connId === undefined) {
80
- throw new Error("Not connected to the database.");
81
+ throw new Error("데이터베이스에 연결되지 않았습니다.");
81
82
  }
82
83
 
83
84
  return this._ormService.executeParametrized(this._connId, query, params);
@@ -89,7 +90,7 @@ export class OrmClientDbContextExecutor implements DbContextExecutor {
89
90
  records: Record<string, unknown>[],
90
91
  ): Promise<void> {
91
92
  if (this._connId === undefined) {
92
- throw new Error("Not connected to the database.");
93
+ throw new Error("데이터베이스에 연결되지 않았습니다.");
93
94
  }
94
95
 
95
96
  return this._ormService.bulkInsert(this._connId, tableName, columnDefs, records);
package/src/index.ts CHANGED
@@ -1,20 +1,21 @@
1
- // Types
1
+ // 타입
2
+ export * from "./types/browser-compat";
2
3
  export * from "./types/connection-options";
3
4
  export * from "./types/progress.types";
4
5
 
5
- // Transport
6
+ // 전송 계층
6
7
  export * from "./transport/socket-provider";
7
8
  export * from "./transport/service-transport";
8
9
 
9
- // Protocol
10
+ // 프로토콜
10
11
  export * from "./protocol/client-protocol-wrapper";
11
12
 
12
- // Features
13
+ // 기능
13
14
  export * from "./features/event-client";
14
15
  export * from "./features/file-client";
15
16
  export * from "./features/orm/orm-connect-options";
16
17
  export * from "./features/orm/orm-client-connector";
17
18
  export * from "./features/orm/orm-client-db-context-executor";
18
19
 
19
- // Main
20
+ // 메인
20
21
  export * from "./service-client";