@simplysm/sd-claude 14.0.42 → 14.0.44

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/claude/references/sd-simplysm14/angular/docs/directives.md +74 -3
  2. package/claude/references/sd-simplysm14/angular/docs/features.md +64 -14
  3. package/claude/references/sd-simplysm14/angular/docs/plugins.md +2 -90
  4. package/claude/references/sd-simplysm14/angular/docs/providers.md +2 -2
  5. package/claude/references/sd-simplysm14/angular/docs/type-utilities.md +1 -2
  6. package/claude/references/sd-simplysm14/angular/docs/ui-data.md +103 -23
  7. package/claude/references/sd-simplysm14/angular/docs/ui-form.md +173 -28
  8. package/claude/references/sd-simplysm14/angular/docs/ui-layout.md +19 -4
  9. package/claude/references/sd-simplysm14/angular/docs/ui-navigation.md +20 -2
  10. package/claude/references/sd-simplysm14/angular/docs/ui-overlay.md +23 -14
  11. package/claude/references/sd-simplysm14/angular/docs/ui-visual.md +15 -7
  12. package/claude/references/sd-simplysm14/angular/docs/utils.md +1 -1
  13. package/claude/references/sd-simplysm14/angular/usage.md +59 -15
  14. package/claude/references/sd-simplysm14/capacitor-plugin-auto-update/usage.md +1 -1
  15. package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/file-operations.md +154 -0
  16. package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/permissions.md +84 -0
  17. package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/storage-paths.md +107 -0
  18. package/claude/references/sd-simplysm14/capacitor-plugin-file-system/docs/types.md +83 -0
  19. package/claude/references/sd-simplysm14/capacitor-plugin-file-system/usage.md +83 -128
  20. package/claude/references/sd-simplysm14/capacitor-plugin-usb-storage/usage.md +99 -1
  21. package/claude/references/sd-simplysm14/core-node/docs/child-process.md +182 -0
  22. package/claude/references/sd-simplysm14/core-node/docs/features.md +1 -1
  23. package/claude/references/sd-simplysm14/core-node/docs/file-system.md +509 -0
  24. package/claude/references/sd-simplysm14/core-node/docs/file-watching.md +139 -0
  25. package/claude/references/sd-simplysm14/core-node/docs/logging.md +180 -0
  26. package/claude/references/sd-simplysm14/core-node/docs/path.md +176 -0
  27. package/claude/references/sd-simplysm14/core-node/docs/worker-threads.md +334 -0
  28. package/claude/references/sd-simplysm14/core-node/usage.md +192 -96
  29. package/claude/references/sd-simplysm14/excel/docs/core-classes.md +33 -14
  30. package/claude/references/sd-simplysm14/excel/usage.md +47 -45
  31. package/claude/references/sd-simplysm14/lint/usage.md +3 -2
  32. package/claude/references/sd-simplysm14/orm-common/docs/queryable-executable.md +30 -35
  33. package/claude/references/sd-simplysm14/orm-common/usage.md +9 -8
  34. package/claude/references/sd-simplysm14/sd-claude/docs/assets.md +43 -34
  35. package/claude/references/sd-simplysm14/sd-claude/docs/cli.md +1 -1
  36. package/claude/references/sd-simplysm14/sd-claude/docs/hooks.md +20 -2
  37. package/claude/references/sd-simplysm14/sd-claude/docs/scripts.md +5 -18
  38. package/claude/references/sd-simplysm14/sd-claude/usage.md +6 -5
  39. package/claude/references/sd-simplysm14/sd-cli/usage.md +176 -1
  40. package/claude/references/sd-simplysm14/service-client/usage.md +126 -61
  41. package/claude/references/sd-simplysm14/service-common/usage.md +28 -28
  42. package/claude/references/sd-simplysm14/storage/usage.md +123 -30
  43. package/claude/{rules → references}/sd-simplysm14.md +1 -1
  44. package/claude/references/sd-testing.md +100 -4
  45. package/claude/rules/sd-claude-rules.md +21 -5
  46. package/claude/sd-check-write.py +1 -1
  47. package/claude/skills/sd-check/SKILL.md +7 -4
  48. package/claude/skills/sd-claude-docs/SKILL.md +7 -4
  49. package/claude/skills/sd-claude-docs/references/package-doc-gen.md +30 -7
  50. package/claude/skills/sd-commit/SKILL.md +2 -0
  51. package/claude/skills/sd-debug/SKILL.md +1 -1
  52. package/claude/skills/sd-deliverable/SKILL.md +2 -0
  53. package/claude/skills/sd-dev/SKILL.md +1 -1
  54. package/claude/skills/sd-doc-extract/SKILL.md +2 -0
  55. package/claude/{references/sd-debug.md → skills/sd-inner-debug/SKILL.md} +16 -20
  56. package/claude/{references/sd-review.md → skills/sd-inner-review/SKILL.md} +9 -4
  57. package/claude/skills/sd-issue/SKILL.md +2 -0
  58. package/claude/skills/sd-outlook/SKILL.md +2 -0
  59. package/claude/skills/sd-plan/SKILL.md +1 -1
  60. package/claude/skills/sd-prompt/SKILL.md +2 -2
  61. package/claude/skills/sd-refactor/SKILL.md +2 -2
  62. package/claude/skills/sd-review/SKILL.md +1 -1
  63. package/claude/skills/sd-tdd/SKILL.md +7 -7
  64. package/claude/skills/sd-use/SKILL.md +2 -0
  65. package/claude/skills/sd-wbs/SKILL.md +41 -18
  66. package/package.json +1 -1
  67. /package/claude/{references → rules}/sd-clarify.md +0 -0
@@ -0,0 +1,180 @@
1
+ # Logging (consola)
2
+
3
+ ## `setupConsola`
4
+
5
+ 환경에 따라 consola의 reporter를 자동으로 구성한다.
6
+
7
+ ```typescript
8
+ export function setupConsola(opts?: SetupConsolaOptions): void
9
+ ```
10
+
11
+ | Parameter | Type | Description |
12
+ |-----------|------|-------------|
13
+ | `opts` | SetupConsolaOptions (optional) | 옵션 객체 |
14
+
15
+ ### SetupConsolaOptions
16
+
17
+ ```typescript
18
+ export interface SetupConsolaOptions {
19
+ cli?: boolean;
20
+ }
21
+ ```
22
+
23
+ | Field | Type | Description |
24
+ |-------|------|-------------|
25
+ | `cli` | boolean (optional) | CLI 모드 여부. true이면 프로덕션에서도 PrettyReporter 사용 (기본값: false) |
26
+
27
+ ### Behavior by Environment
28
+
29
+ | Condition | Reporters | Debug Level |
30
+ |-----------|-----------|------------|
31
+ | Production (not DEV, not cli) | FileReporter | debug 레벨 포함 |
32
+ | Development or cli + SD_DEBUG | PrettyReporter | debug 레벨 포함 |
33
+ | Development or cli (일반) | FileReporter + PrettyReporter (info 이하) | debug는 파일에만 기록 |
34
+
35
+ **Note**:
36
+ - `DEV` 환경변수 또는 `SD_DEBUG` 환경변수의 값을 `parseBoolEnv()`로 파싱한다.
37
+ - `env("...")`는 @simplysm/core-common의 함수를 사용한다.
38
+
39
+ **Example**:
40
+ ```typescript
41
+ // 환경별 자동 구성
42
+ setupConsola();
43
+
44
+ // CLI 모드
45
+ setupConsola({ cli: true });
46
+ ```
47
+
48
+ ---
49
+
50
+ ## `withMaxLevel`
51
+
52
+ Consola reporter를 지정된 로그 레벨 이하로 제한하는 래퍼.
53
+
54
+ ```typescript
55
+ export function withMaxLevel(reporter: ConsolaReporter, maxLevel: number): ConsolaReporter
56
+ ```
57
+
58
+ | Parameter | Type | Description |
59
+ |-----------|------|-------------|
60
+ | `reporter` | ConsolaReporter | 원본 reporter |
61
+ | `maxLevel` | number | 최대 로그 레벨 (LogLevels 상수 참고) |
62
+
63
+ **Return**: 제한된 reporter
64
+
65
+ **Consola LogLevels**:
66
+ ```
67
+ 0: fatal
68
+ 1: error
69
+ 2: warn
70
+ 3: info
71
+ 4: success
72
+ 5: log
73
+ 6: debug
74
+ 7: trace
75
+ ```
76
+
77
+ **Example**:
78
+ ```typescript
79
+ import { withMaxLevel, PrettyReporter, LogLevels } from "@simplysm/core-node";
80
+
81
+ // info 레벨 이하만 출력
82
+ const limitedReporter = withMaxLevel(new PrettyReporter(), LogLevels.info);
83
+ ```
84
+
85
+ ---
86
+
87
+ ## `PrettyReporter`
88
+
89
+ 터미널 출력용 consola reporter.
90
+
91
+ 아이콘, 색상, 에러 스택 포맷팅을 지원한다.
92
+
93
+ ```typescript
94
+ export class PrettyReporter implements ConsolaReporter {
95
+ log(logObj: LogObject, ctx: { options: ConsolaOptions }): void
96
+ }
97
+ ```
98
+
99
+ **Features**:
100
+ - 로그 레벨별 아이콘 표시
101
+ - 컬러 출력
102
+ - 에러 객체의 스택 포맷팅
103
+ - 타임스탐프 표시 (선택적)
104
+
105
+ **Example**:
106
+ ```typescript
107
+ import { PrettyReporter } from "@simplysm/core-node";
108
+ import consola from "consola";
109
+
110
+ consola.options.reporters = [new PrettyReporter()];
111
+ ```
112
+
113
+ ---
114
+
115
+ ## `createFileReporter`
116
+
117
+ 파일 기반 consola reporter를 생성한다.
118
+
119
+ JSON 라인 형식으로 로그를 기록하며, 날짜별 로테이션과 크기 제한을 지원한다.
120
+
121
+ ```typescript
122
+ export function createFileReporter(options?: FileReporterOptions): ConsolaReporter
123
+ ```
124
+
125
+ | Parameter | Type | Description |
126
+ |-----------|------|-------------|
127
+ | `options` | FileReporterOptions (optional) | 옵션 객체 |
128
+
129
+ ### FileReporterOptions
130
+
131
+ ```typescript
132
+ export interface FileReporterOptions {
133
+ maxSize?: number; // 로그 파일 최대 크기 (바이트, 기본값: 20MB)
134
+ maxDays?: number; // 로그 보관 기간 (일, 기본값: 14일)
135
+ }
136
+ ```
137
+
138
+ | Field | Type | Description |
139
+ |-------|------|-------------|
140
+ | `maxSize` | number (optional) | 단일 로그 파일의 최대 크기 (바이트). 초과 시 롤오버됨 (기본값: 20MB = 20 * 1024 * 1024) |
141
+ | `maxDays` | number (optional) | 로그 파일 보관 기간 (일). 이 기간이 지난 로그는 자동 삭제됨 (기본값: 14) |
142
+
143
+ ### Log File Format
144
+
145
+ - 디렉토리: `.logs/`
146
+ - 파일명 형식: `app.YYYY-MM-DD.log`
147
+ - 내용: JSON 라인 (각 로그는 하나의 JSON 객체)
148
+
149
+ **Example**:
150
+ ```typescript
151
+ import { createFileReporter } from "@simplysm/core-node";
152
+ import consola from "consola";
153
+
154
+ const fileReporter = createFileReporter({
155
+ maxSize: 10 * 1024 * 1024, // 10MB
156
+ maxDays: 7, // 7일 보관
157
+ });
158
+
159
+ consola.options.reporters = [fileReporter];
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Integration with setupConsola
165
+
166
+ setupConsola()는 내부적으로 PrettyReporter와 createFileReporter()를 사용하여 환경에 맞게 reporters를 구성한다.
167
+
168
+ ```typescript
169
+ import { setupConsola } from "@simplysm/core-node";
170
+ import consola from "consola";
171
+
172
+ // 자동 구성
173
+ setupConsola();
174
+
175
+ // 이후 consola를 정상적으로 사용 가능
176
+ consola.info("Application started");
177
+ consola.debug("Debug information");
178
+ ```
179
+
180
+ **주의**: consola는 프로젝트 루트의 `console.*` 금지 규칙을 대체하는 표준 로깅 수단이다.
@@ -0,0 +1,176 @@
1
+ # Path (pathx)
2
+
3
+ ## `PosixPath`
4
+
5
+ POSIX 스타일(슬래시) 경로임을 타입 수준에서 보장하는 브랜드 타입.
6
+
7
+ posix() 또는 posixResolve()를 통해서만 생성할 수 있다.
8
+
9
+ ```typescript
10
+ export type PosixPath = string & {
11
+ [POSIX]: never;
12
+ }
13
+ ```
14
+
15
+ **Note**: 일반 문자열을 강제로 PosixPath로 캐스팅할 수 없다. posix() 또는 posixResolve()를 반드시 사용해야 한다.
16
+
17
+ ---
18
+
19
+ ## `posix`
20
+
21
+ 경로를 POSIX 스타일(슬래시)로 변환한다.
22
+
23
+ 경로 결합이나 resolve는 수행하지 않으며, 단순히 백슬래시를 슬래시로 바꾼다.
24
+
25
+ ```typescript
26
+ export function posix(p: string): PosixPath
27
+ ```
28
+
29
+ | Parameter | Type | Description |
30
+ |-----------|------|-------------|
31
+ | `p` | string | 변환할 경로 |
32
+
33
+ **Return**: PosixPath (슬래시로 정규화된 경로)
34
+
35
+ **Example**:
36
+ ```typescript
37
+ posix("C:\\Users\\test"); // "C:/Users/test"
38
+ posix("./relative/path"); // "./relative/path"
39
+ ```
40
+
41
+ ---
42
+
43
+ ## `posixResolve`
44
+
45
+ 절대 경로로 resolve한 뒤 POSIX 스타일로 변환한다.
46
+
47
+ ```typescript
48
+ export function posixResolve(...args: string[]): PosixPath
49
+ ```
50
+
51
+ | Parameter | Type | Description |
52
+ |-----------|------|-------------|
53
+ | `...args` | string[] | resolve할 경로 세그먼트 (node:path.resolve와 동일) |
54
+
55
+ **Return**: PosixPath (절대 경로, 슬래시로 정규화)
56
+
57
+ **Example**:
58
+ ```typescript
59
+ posixResolve("/base", "sub", "file.txt"); // "/base/sub/file.txt" (Unix 환경)
60
+ posixResolve("relative/path"); // "/home/user/relative/path" (절대 경로로 resolve됨)
61
+ ```
62
+
63
+ ---
64
+
65
+ ## `changeFileDirectory`
66
+
67
+ 파일 경로의 디렉토리를 변경한다.
68
+
69
+ ```typescript
70
+ export function changeFileDirectory(
71
+ filePath: string,
72
+ fromDirectory: string,
73
+ toDirectory: string,
74
+ ): string
75
+ ```
76
+
77
+ | Parameter | Type | Description |
78
+ |-----------|------|-------------|
79
+ | `filePath` | string | 파일 경로 |
80
+ | `fromDirectory` | string | 현재 디렉토리 |
81
+ | `toDirectory` | string | 새 디렉토리 |
82
+
83
+ **Return**: 새 디렉토리로 변경된 파일 경로
84
+
85
+ **Throws**: filePath가 fromDirectory 내부에 없는 경우 ArgumentError 발생
86
+
87
+ **Example**:
88
+ ```typescript
89
+ changeFileDirectory("/a/b/c.txt", "/a/b", "/x");
90
+ // → "/x/c.txt"
91
+
92
+ changeFileDirectory("/a/b/sub/c.txt", "/a/b", "/x");
93
+ // → "/x/sub/c.txt"
94
+ ```
95
+
96
+ ---
97
+
98
+ ## `basenameWithoutExt`
99
+
100
+ 확장자를 제외한 파일명(basename)을 반환한다.
101
+
102
+ ```typescript
103
+ export function basenameWithoutExt(filePath: string): string
104
+ ```
105
+
106
+ | Parameter | Type | Description |
107
+ |-----------|------|-------------|
108
+ | `filePath` | string | 파일 경로 |
109
+
110
+ **Return**: 확장자를 제외한 파일명
111
+
112
+ **Example**:
113
+ ```typescript
114
+ basenameWithoutExt("file.txt"); // "file"
115
+ basenameWithoutExt("/path/to/file.spec.ts"); // "file.spec"
116
+ basenameWithoutExt("/path/to/file"); // "file"
117
+ ```
118
+
119
+ ---
120
+
121
+ ## `isChildPath`
122
+
123
+ childPath가 parentPath의 하위 경로인지 확인한다.
124
+
125
+ 동일한 경로이면 false를 반환한다.
126
+
127
+ 경로는 내부적으로 posixResolve()를 사용하여 정규화되며, POSIX 슬래시(/)를 구분자로 사용하여 비교한다.
128
+
129
+ ```typescript
130
+ export function isChildPath(childPath: string, parentPath: string): boolean
131
+ ```
132
+
133
+ | Parameter | Type | Description |
134
+ |-----------|------|-------------|
135
+ | `childPath` | string | 자식으로 확인할 경로 |
136
+ | `parentPath` | string | 부모로 확인할 경로 |
137
+
138
+ **Return**: childPath가 parentPath의 하위 경로이면 true, 동일하거나 상위 경로이면 false
139
+
140
+ **Example**:
141
+ ```typescript
142
+ isChildPath("/a/b/c", "/a/b"); // true
143
+ isChildPath("/a/b", "/a/b/c"); // false
144
+ isChildPath("/a/b", "/a/b"); // false (동일 경로)
145
+ isChildPath("/a/bc", "/a/b"); // false (접두사 매칭이 아님)
146
+ ```
147
+
148
+ ---
149
+
150
+ ## `filterByTargets`
151
+
152
+ 대상 경로 목록을 기반으로 파일을 필터링한다.
153
+
154
+ 대상 경로와 일치하거나 하위에 있는 파일을 포함한다.
155
+
156
+ ```typescript
157
+ export function filterByTargets(files: string[], targets: string[], cwd: string): string[]
158
+ ```
159
+
160
+ | Parameter | Type | Description |
161
+ |-----------|------|-------------|
162
+ | `files` | string[] | 필터링할 파일 경로 배열. 주의: cwd 하위의 절대 경로여야 한다. cwd 외부의 경로는 상대 경로(../)로 변환되어 처리된다. |
163
+ | `targets` | string[] | 대상 경로 (cwd 기준 상대 경로, POSIX 스타일 권장) |
164
+ | `cwd` | string | 현재 작업 디렉토리 (절대 경로) |
165
+
166
+ **Return**: targets가 비어있으면 files를 그대로 반환; 그렇지 않으면 대상 경로 하위의 파일만 반환
167
+
168
+ **Example**:
169
+ ```typescript
170
+ const files = ["/proj/src/a.ts", "/proj/src/b.ts", "/proj/tests/c.ts"];
171
+ filterByTargets(files, ["src"], "/proj");
172
+ // → ["/proj/src/a.ts", "/proj/src/b.ts"]
173
+
174
+ filterByTargets(files, [], "/proj");
175
+ // → ["/proj/src/a.ts", "/proj/src/b.ts", "/proj/tests/c.ts"] (targets가 비어있음)
176
+ ```
@@ -0,0 +1,334 @@
1
+ # Worker Threads
2
+
3
+ ## `Worker`
4
+
5
+ Worker thread 프록시를 생성하는 팩토리 객체.
6
+
7
+ ```typescript
8
+ export const Worker: {
9
+ create<TModule extends WorkerModule>(
10
+ workerPath: string,
11
+ options?: Omit<WorkerRawOptions, "stdout" | "stderr">,
12
+ ): WorkerProxy<TModule>
13
+ }
14
+ ```
15
+
16
+ ### Static Method
17
+
18
+ #### `create`
19
+
20
+ 워커 파일을 로드하고 타입 안전한 프록시를 생성한다.
21
+
22
+ ```typescript
23
+ static create<TModule extends WorkerModule>(
24
+ workerPath: string,
25
+ options?: Omit<WorkerRawOptions, "stdout" | "stderr">,
26
+ ): WorkerProxy<TModule>
27
+ ```
28
+
29
+ | Parameter | Type | Description |
30
+ |-----------|------|-------------|
31
+ | `workerPath` | string | 워커 파일 경로 (.ts 또는 .js). 개발 환경에서는 .ts를 권장하며, 내부적으로 tsx를 통해 실행된다. |
32
+ | `options` | WorkerRawOptions (optional) | Worker thread 옵션. stdout/stderr는 자동으로 메인 프로세스로 파이프된다. |
33
+
34
+ **Return**: WorkerProxy<TModule> - 타입 안전한 워커 프록시
35
+
36
+ **Development vs Production**:
37
+ - **.ts 파일**: `lib/worker-dev-proxy.js`를 통해 tsx로 실행됨
38
+ - **.js 파일**: 직접 Worker로 로드됨
39
+
40
+ **Example**:
41
+ ```typescript
42
+ import { Worker } from "@simplysm/core-node";
43
+ import type * as MyWorker from "./worker";
44
+
45
+ const worker = Worker.create<typeof MyWorker>("./worker.ts");
46
+
47
+ // 메서드 호출 (타입 안전)
48
+ const result = await worker.add(10, 20);
49
+
50
+ // 이벤트 수신 (타입 안전)
51
+ worker.on("progress", (value) => {
52
+ console.log(`Progress: ${value}%`);
53
+ });
54
+
55
+ await worker.terminate();
56
+ ```
57
+
58
+ ---
59
+
60
+ ## `createWorker`
61
+
62
+ 워커 측에서 호출하여 메서드와 이벤트를 등록하는 팩토리 함수.
63
+
64
+ ```typescript
65
+ export function createWorker<
66
+ TMethods extends Record<string, (...args: any[]) => unknown>,
67
+ TEvents extends Record<string, unknown> = Record<string, never>,
68
+ >(
69
+ methods: TMethods,
70
+ ): {
71
+ send<TEventName extends keyof TEvents & string>(event: TEventName, data?: TEvents[TEventName]): void;
72
+ __methods: TMethods;
73
+ __events: TEvents;
74
+ }
75
+ ```
76
+
77
+ | Parameter | Type | Description |
78
+ |-----------|------|-------------|
79
+ | `methods` | Record<string, function> | 워커가 제공할 메서드 객체 |
80
+
81
+ **Type Parameters**:
82
+ - `TMethods`: 메서드 타입
83
+ - `TEvents`: 이벤트 타입 (기본값: 빈 객체)
84
+
85
+ **Return**: sender 객체. `send()` 메서드로 이벤트를 발송하고, export default로 내보낸다.
86
+
87
+ **Example**:
88
+ ```typescript
89
+ // worker.ts
90
+ import { createWorker } from "@simplysm/core-node";
91
+
92
+ interface MyEvents {
93
+ progress: number;
94
+ }
95
+
96
+ const methods = {
97
+ add: (a: number, b: number) => a + b,
98
+ multiply: (a: number, b: number) => a * b,
99
+ };
100
+
101
+ const sender = createWorker<typeof methods, MyEvents>(methods);
102
+
103
+ export default sender;
104
+ ```
105
+
106
+ ---
107
+
108
+ ## `WorkerProxy`
109
+
110
+ Worker.create()가 반환하는 프록시 타입.
111
+
112
+ Promise화된 메서드 + 이벤트 리스너 + 종료 메서드를 제공한다.
113
+
114
+ ```typescript
115
+ export type WorkerProxy<TModule extends WorkerModule> = PromisifyMethods<
116
+ TModule["default"]["__methods"]
117
+ > & {
118
+ on<TEventName extends keyof TModule["default"]["__events"] & string>(
119
+ event: TEventName,
120
+ listener: (data: TModule["default"]["__events"][TEventName]) => void,
121
+ ): void;
122
+
123
+ off<TEventName extends keyof TModule["default"]["__events"] & string>(
124
+ event: TEventName,
125
+ listener: (data: TModule["default"]["__events"][TEventName]) => void,
126
+ ): void;
127
+
128
+ terminate(): Promise<void>;
129
+ }
130
+ ```
131
+
132
+ ### Methods
133
+
134
+ | Name | Signature | Description |
135
+ |------|-----------|-------------|
136
+ | `[메서드명]` | `(...args): Promise<R>` | 워커의 메서드. 비동기로 Promise를 반환한다. |
137
+ | `on` | `<E extends EventName>(event, listener): void` | 워커 이벤트 리스너를 등록한다. |
138
+ | `off` | `<E extends EventName>(event, listener): void` | 워커 이벤트 리스너를 해제한다. |
139
+ | `terminate` | `(): Promise<void>` | 워커를 종료한다. |
140
+
141
+ **Example**:
142
+ ```typescript
143
+ const worker = Worker.create<typeof MyWorker>("./worker.ts");
144
+
145
+ // 메서드 호출
146
+ const sum = await worker.add(10, 20); // 30
147
+ const product = await worker.multiply(5, 6); // 30
148
+
149
+ // 이벤트 리스너 등록
150
+ worker.on("progress", (value) => {
151
+ console.log(`Progress: ${value}%`);
152
+ });
153
+
154
+ // 이벤트 리스너 제거
155
+ worker.off("progress", handler);
156
+
157
+ // 워커 종료
158
+ await worker.terminate();
159
+ ```
160
+
161
+ ---
162
+
163
+ ## `PromisifyMethods`
164
+
165
+ 메서드의 반환값을 Promise로 감싸는 매핑 타입.
166
+
167
+ ```typescript
168
+ export type PromisifyMethods<TMethods> = {
169
+ [K in keyof TMethods]: TMethods[K] extends (...args: infer P) => infer R
170
+ ? (...args: P) => Promise<Awaited<R>>
171
+ : never;
172
+ }
173
+ ```
174
+
175
+ **Note**: 워커 메서드는 postMessage 기반으로 동작하여 항상 비동기이므로, 동기 메서드 타입도 `Promise<Awaited<R>>`로 변환된다.
176
+
177
+ **Example**:
178
+ ```typescript
179
+ // 원본
180
+ interface Methods {
181
+ add: (a: number, b: number) => number;
182
+ process: (data: string) => Promise<Result>;
183
+ }
184
+
185
+ // PromisifyMethods 적용 후
186
+ type ProxiedMethods = {
187
+ add: (a: number, b: number) => Promise<number>;
188
+ process: (data: string) => Promise<Result>;
189
+ }
190
+ ```
191
+
192
+ ---
193
+
194
+ ## `WorkerModule`
195
+
196
+ createWorker()가 반환하는 워커 모듈의 타입 구조.
197
+
198
+ ```typescript
199
+ export interface WorkerModule {
200
+ default: {
201
+ __methods: Record<string, (...args: any[]) => unknown>;
202
+ __events: Record<string, unknown>;
203
+ };
204
+ }
205
+ ```
206
+
207
+ **Usage**:
208
+ ```typescript
209
+ import type * as MyWorker from "./worker";
210
+
211
+ const worker = Worker.create<typeof MyWorker>("./worker.ts");
212
+ ```
213
+
214
+ ---
215
+
216
+ ## `WorkerRequest`
217
+
218
+ 메인 프로세스에서 워커로 보내는 요청 메시지.
219
+
220
+ ```typescript
221
+ export interface WorkerRequest {
222
+ id: string;
223
+ method: string;
224
+ params: unknown[];
225
+ }
226
+ ```
227
+
228
+ | Field | Type | Description |
229
+ |-------|------|-------------|
230
+ | `id` | string | 요청의 고유 ID (응답과 매칭하는 데 사용) |
231
+ | `method` | string | 호출할 메서드명 |
232
+ | `params` | unknown[] | 메서드 인자 배열 |
233
+
234
+ ---
235
+
236
+ ## `WorkerResponse`
237
+
238
+ 워커에서 메인 프로세스로 보내는 응답 메시지.
239
+
240
+ Discriminated union 타입으로, 다음 중 하나의 형태를 가진다:
241
+
242
+ ```typescript
243
+ export type WorkerResponse =
244
+ | {
245
+ request: WorkerRequest;
246
+ type: "return";
247
+ body?: unknown;
248
+ }
249
+ | {
250
+ request: WorkerRequest;
251
+ type: "error";
252
+ body: Error;
253
+ }
254
+ | {
255
+ type: "event";
256
+ event: string;
257
+ body?: unknown;
258
+ }
259
+ | {
260
+ type: "log";
261
+ body: string;
262
+ }
263
+ ```
264
+
265
+ | Variant | Description |
266
+ |---------|-------------|
267
+ | `return` | 메서드 실행 성공 결과 |
268
+ | `error` | 메서드 실행 중 에러 발생 |
269
+ | `event` | 워커에서 발송한 이벤트 (request 없음, event 이름과 body 포함) |
270
+ | `log` | 워커의 stdout.write 출력 (string body) |
271
+
272
+ ---
273
+
274
+ ## Complete Example
275
+
276
+ ### worker.ts (워커 파일)
277
+
278
+ ```typescript
279
+ import { createWorker } from "@simplysm/core-node";
280
+
281
+ interface MyEvents {
282
+ progress: number;
283
+ done: { result: number };
284
+ }
285
+
286
+ const methods = {
287
+ compute: async (n: number) => {
288
+ const sender = createWorker<typeof methods, MyEvents>(methods);
289
+
290
+ let result = 0;
291
+ for (let i = 0; i <= n; i++) {
292
+ result += i;
293
+ // 진행률 보고
294
+ sender.send("progress", (i / n) * 100);
295
+ }
296
+
297
+ sender.send("done", { result });
298
+ return result;
299
+ },
300
+ };
301
+
302
+ const sender = createWorker<typeof methods, MyEvents>(methods);
303
+ export default sender;
304
+ ```
305
+
306
+ ### main.ts (메인 파일)
307
+
308
+ ```typescript
309
+ import { Worker } from "@simplysm/core-node";
310
+ import type * as MyWorker from "./worker";
311
+
312
+ async function main() {
313
+ const worker = Worker.create<typeof MyWorker>("./worker.ts");
314
+
315
+ // 진행률 수신
316
+ worker.on("progress", (value) => {
317
+ console.log(`Progress: ${value.toFixed(1)}%`);
318
+ });
319
+
320
+ // 완료 신호 수신
321
+ worker.on("done", ({ result }) => {
322
+ console.log(`Done! Result: ${result}`);
323
+ });
324
+
325
+ // 메서드 호출
326
+ const result = await worker.compute(100);
327
+ console.log(`Final result: ${result}`);
328
+
329
+ // 워커 종료
330
+ await worker.terminate();
331
+ }
332
+
333
+ main().catch(console.error);
334
+ ```