@simplysm/core-common 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.
- package/README.md +86 -92
- package/dist/common.types.d.ts +14 -14
- package/dist/common.types.js +2 -1
- package/dist/common.types.js.map +1 -6
- package/dist/env.d.ts +8 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +13 -9
- package/dist/env.js.map +1 -6
- package/dist/errors/argument-error.d.ts +10 -10
- package/dist/errors/argument-error.d.ts.map +1 -1
- package/dist/errors/argument-error.js +31 -14
- package/dist/errors/argument-error.js.map +1 -6
- package/dist/errors/not-implemented-error.d.ts +8 -8
- package/dist/errors/not-implemented-error.js +30 -12
- package/dist/errors/not-implemented-error.js.map +1 -6
- package/dist/errors/sd-error.d.ts +10 -10
- package/dist/errors/sd-error.d.ts.map +1 -1
- package/dist/errors/sd-error.js +45 -24
- package/dist/errors/sd-error.js.map +1 -6
- package/dist/errors/timeout-error.d.ts +10 -10
- package/dist/errors/timeout-error.js +34 -15
- package/dist/errors/timeout-error.js.map +1 -6
- package/dist/extensions/arr-ext.d.ts +2 -2
- package/dist/extensions/arr-ext.helpers.d.ts +10 -10
- package/dist/extensions/arr-ext.helpers.js +112 -89
- package/dist/extensions/arr-ext.helpers.js.map +1 -6
- package/dist/extensions/arr-ext.js +458 -422
- package/dist/extensions/arr-ext.js.map +1 -6
- package/dist/extensions/arr-ext.types.d.ts +57 -57
- package/dist/extensions/arr-ext.types.d.ts.map +1 -1
- package/dist/extensions/arr-ext.types.js +6 -1
- package/dist/extensions/arr-ext.types.js.map +1 -6
- package/dist/extensions/map-ext.d.ts +16 -16
- package/dist/extensions/map-ext.js +27 -22
- package/dist/extensions/map-ext.js.map +1 -6
- package/dist/extensions/set-ext.d.ts +11 -11
- package/dist/extensions/set-ext.js +32 -25
- package/dist/extensions/set-ext.js.map +1 -6
- package/dist/features/debounce-queue.d.ts +17 -17
- package/dist/features/debounce-queue.js +98 -70
- package/dist/features/debounce-queue.js.map +1 -6
- package/dist/features/event-emitter.d.ts +20 -20
- package/dist/features/event-emitter.js +101 -78
- package/dist/features/event-emitter.js.map +1 -6
- package/dist/features/serial-queue.d.ts +11 -11
- package/dist/features/serial-queue.js +78 -57
- package/dist/features/serial-queue.js.map +1 -6
- package/dist/globals.d.ts +4 -4
- package/dist/globals.js +9 -1
- package/dist/globals.js.map +1 -6
- package/dist/index.js +28 -27
- package/dist/index.js.map +1 -6
- package/dist/types/date-only.d.ts +64 -64
- package/dist/types/date-only.d.ts.map +1 -1
- package/dist/types/date-only.js +263 -252
- package/dist/types/date-only.js.map +1 -6
- package/dist/types/date-time.d.ts +36 -36
- package/dist/types/date-time.d.ts.map +1 -1
- package/dist/types/date-time.js +196 -288
- package/dist/types/date-time.js.map +1 -6
- package/dist/types/lazy-gc-map.d.ts +26 -26
- package/dist/types/lazy-gc-map.d.ts.map +1 -1
- package/dist/types/lazy-gc-map.js +202 -159
- package/dist/types/lazy-gc-map.js.map +1 -6
- package/dist/types/time.d.ts +23 -23
- package/dist/types/time.d.ts.map +1 -1
- package/dist/types/time.js +169 -158
- package/dist/types/time.js.map +1 -6
- package/dist/types/uuid.d.ts +11 -11
- package/dist/types/uuid.d.ts.map +1 -1
- package/dist/types/uuid.js +95 -70
- package/dist/types/uuid.js.map +1 -6
- package/dist/utils/bytes.d.ts +17 -17
- package/dist/utils/bytes.js +137 -81
- package/dist/utils/bytes.js.map +1 -6
- package/dist/utils/date-format.d.ts +40 -40
- package/dist/utils/date-format.js +187 -101
- package/dist/utils/date-format.js.map +1 -6
- package/dist/utils/error.d.ts +4 -4
- package/dist/utils/error.js +11 -6
- package/dist/utils/error.js.map +1 -6
- package/dist/utils/json.d.ts +19 -19
- package/dist/utils/json.js +187 -135
- package/dist/utils/json.js.map +1 -6
- package/dist/utils/num.d.ts +20 -20
- package/dist/utils/num.js +76 -34
- package/dist/utils/num.js.map +1 -6
- package/dist/utils/obj.d.ts +111 -111
- package/dist/utils/obj.d.ts.map +1 -1
- package/dist/utils/obj.js +706 -496
- package/dist/utils/obj.js.map +1 -6
- package/dist/utils/path.d.ts +10 -10
- package/dist/utils/path.js +35 -18
- package/dist/utils/path.js.map +1 -6
- package/dist/utils/primitive.d.ts +5 -5
- package/dist/utils/primitive.js +34 -14
- package/dist/utils/primitive.js.map +1 -6
- package/dist/utils/str.d.ts +38 -38
- package/dist/utils/str.js +217 -113
- package/dist/utils/str.js.map +1 -6
- package/dist/utils/template-strings.d.ts +26 -26
- package/dist/utils/template-strings.js +113 -40
- package/dist/utils/template-strings.js.map +1 -6
- package/dist/utils/transferable.d.ts +18 -18
- package/dist/utils/transferable.js +218 -151
- package/dist/utils/transferable.js.map +1 -6
- package/dist/utils/wait.d.ts +9 -9
- package/dist/utils/wait.js +30 -15
- package/dist/utils/wait.js.map +1 -6
- package/dist/utils/xml.d.ts +13 -13
- package/dist/utils/xml.js +84 -46
- package/dist/utils/xml.js.map +1 -6
- package/dist/utils/zip.d.ts +22 -22
- package/dist/utils/zip.js +172 -148
- package/dist/utils/zip.js.map +1 -6
- package/docs/array-extensions.md +430 -0
- package/docs/env.md +52 -0
- package/docs/errors.md +41 -56
- package/docs/features.md +82 -97
- package/docs/type-utilities.md +91 -0
- package/docs/types.md +221 -201
- package/docs/utils.md +319 -435
- package/package.json +7 -5
- package/src/common.types.ts +14 -14
- package/src/env.ts +12 -3
- package/src/errors/argument-error.ts +15 -15
- package/src/errors/not-implemented-error.ts +9 -9
- package/src/errors/sd-error.ts +12 -12
- package/src/errors/timeout-error.ts +12 -12
- package/src/extensions/arr-ext.helpers.ts +16 -16
- package/src/extensions/arr-ext.ts +35 -35
- package/src/extensions/arr-ext.types.ts +57 -57
- package/src/extensions/map-ext.ts +16 -16
- package/src/extensions/set-ext.ts +11 -11
- package/src/features/debounce-queue.ts +23 -23
- package/src/features/event-emitter.ts +25 -25
- package/src/features/serial-queue.ts +13 -13
- package/src/globals.ts +4 -4
- package/src/index.ts +5 -5
- package/src/types/date-only.ts +84 -83
- package/src/types/date-time.ts +43 -42
- package/src/types/lazy-gc-map.ts +44 -44
- package/src/types/time.ts +29 -29
- package/src/types/uuid.ts +15 -15
- package/src/utils/bytes.ts +35 -35
- package/src/utils/date-format.ts +59 -59
- package/src/utils/error.ts +4 -4
- package/src/utils/json.ts +41 -41
- package/src/utils/num.ts +20 -20
- package/src/utils/obj.ts +138 -138
- package/src/utils/path.ts +10 -10
- package/src/utils/primitive.ts +6 -6
- package/src/utils/str.ts +48 -48
- package/src/utils/template-strings.ts +29 -29
- package/src/utils/transferable.ts +38 -38
- package/src/utils/wait.ts +10 -10
- package/src/utils/xml.ts +19 -19
- package/src/utils/zip.ts +25 -25
- package/docs/extensions.md +0 -387
- package/tests/errors/errors.spec.ts +0 -80
- package/tests/extensions/array-extension.spec.ts +0 -654
- package/tests/extensions/map-extension.spec.ts +0 -117
- package/tests/extensions/set-extension.spec.ts +0 -67
- package/tests/types/date-only.spec.ts +0 -533
- package/tests/types/date-time.spec.ts +0 -246
- package/tests/types/lazy-gc-map.spec.ts +0 -606
- package/tests/types/time.spec.ts +0 -428
- package/tests/types/uuid.spec.ts +0 -74
- package/tests/utils/bytes-utils.spec.ts +0 -197
- package/tests/utils/date-format.spec.ts +0 -350
- package/tests/utils/debounce-queue.spec.ts +0 -226
- package/tests/utils/json.spec.ts +0 -400
- package/tests/utils/number.spec.ts +0 -136
- package/tests/utils/object.spec.ts +0 -810
- package/tests/utils/path.spec.ts +0 -70
- package/tests/utils/primitive.spec.ts +0 -43
- package/tests/utils/sd-event-emitter.spec.ts +0 -189
- package/tests/utils/serial-queue.spec.ts +0 -305
- package/tests/utils/string.spec.ts +0 -265
- package/tests/utils/template-strings.spec.ts +0 -48
- package/tests/utils/transferable.spec.ts +0 -639
- package/tests/utils/wait.spec.ts +0 -123
- package/tests/utils/xml.spec.ts +0 -146
- package/tests/utils/zip.spec.ts +0 -221
package/src/utils/primitive.ts
CHANGED
|
@@ -6,13 +6,13 @@ import { ArgumentError } from "../errors/argument-error";
|
|
|
6
6
|
import type { PrimitiveTypeMap, PrimitiveTypeStr } from "../common.types";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* 값으로부터 PrimitiveTypeStr 추론
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* 런타임에 값의 타입을 확인하고 해당하는 PrimitiveTypeStr을 반환.
|
|
12
12
|
*
|
|
13
|
-
* @param value
|
|
14
|
-
* @returns
|
|
15
|
-
* @throws ArgumentError
|
|
13
|
+
* @param value 타입을 추론할 값
|
|
14
|
+
* @returns 값에 해당하는 PrimitiveTypeStr
|
|
15
|
+
* @throws ArgumentError 지원하지 않는 타입인 경우
|
|
16
16
|
*
|
|
17
17
|
* @example
|
|
18
18
|
* getPrimitiveTypeStr("hello") // "string"
|
|
@@ -29,5 +29,5 @@ export function typeStr(value: PrimitiveTypeMap[PrimitiveTypeStr]): PrimitiveTyp
|
|
|
29
29
|
if (value instanceof Time) return "Time";
|
|
30
30
|
if (value instanceof Uuid) return "Uuid";
|
|
31
31
|
if (value instanceof Uint8Array) return "Bytes";
|
|
32
|
-
throw new ArgumentError("
|
|
32
|
+
throw new ArgumentError("알 수 없는 값 타입입니다.", { type: typeof value });
|
|
33
33
|
}
|
package/src/utils/str.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 문자열 유틸리티 함수
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
//#region
|
|
5
|
+
//#region 한국어 조사 처리
|
|
6
6
|
|
|
7
|
-
//
|
|
7
|
+
// 한국어 조사 매핑 테이블 (모듈 로드 시 한 번만 생성)
|
|
8
8
|
const suffixTable = {
|
|
9
9
|
을: { t: "을", f: "를" },
|
|
10
10
|
은: { t: "은", f: "는" },
|
|
@@ -16,16 +16,16 @@ const suffixTable = {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
20
|
-
* @param text
|
|
21
|
-
* @param type
|
|
22
|
-
* - `"을"`: 을/를 (
|
|
23
|
-
* - `"은"`: 은/는 (
|
|
24
|
-
* - `"이"`: 이/가 (
|
|
25
|
-
* - `"와"`: 과/와 (
|
|
26
|
-
* - `"랑"`: 이랑/랑 (
|
|
27
|
-
* - `"로"`: 으로/로 (
|
|
28
|
-
* - `"라"`: 이라/라 (
|
|
19
|
+
* 받침 유무에 따라 적절한 한국어 조사 반환
|
|
20
|
+
* @param text 확인할 텍스트
|
|
21
|
+
* @param type 조사 타입
|
|
22
|
+
* - `"을"`: 을/를 (목적격 조사)
|
|
23
|
+
* - `"은"`: 은/는 (주격 보조사)
|
|
24
|
+
* - `"이"`: 이/가 (주격 조사)
|
|
25
|
+
* - `"와"`: 과/와 (접속 조사)
|
|
26
|
+
* - `"랑"`: 이랑/랑 (접속 조사)
|
|
27
|
+
* - `"로"`: 으로/로 (도구격 조사)
|
|
28
|
+
* - `"라"`: 이라/라 (서술격 조사)
|
|
29
29
|
*
|
|
30
30
|
* @example
|
|
31
31
|
* getKoreanSuffix("Apple", "을") // "를"
|
|
@@ -43,16 +43,16 @@ export function getKoreanSuffix(
|
|
|
43
43
|
|
|
44
44
|
const lastCharCode = text.charCodeAt(text.length - 1);
|
|
45
45
|
|
|
46
|
-
//
|
|
46
|
+
// 한글 범위 확인 (0xAC00 ~ 0xD7A3)
|
|
47
47
|
if (lastCharCode < 0xac00 || lastCharCode > 0xd7a3) {
|
|
48
48
|
return table[type].f;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
//
|
|
51
|
+
// 받침(종성) 존재 여부 판단
|
|
52
52
|
const jongseongIndex = (lastCharCode - 0xac00) % 28;
|
|
53
53
|
const hasLast = jongseongIndex !== 0;
|
|
54
54
|
|
|
55
|
-
//
|
|
55
|
+
// "로" 조사 특수 처리: 받침이 ㄹ (종성 인덱스 8)이면 "로" 사용
|
|
56
56
|
if (type === "로" && jongseongIndex === 8) {
|
|
57
57
|
return table[type].f;
|
|
58
58
|
}
|
|
@@ -62,9 +62,9 @@ export function getKoreanSuffix(
|
|
|
62
62
|
|
|
63
63
|
//#endregion
|
|
64
64
|
|
|
65
|
-
//#region
|
|
65
|
+
//#region 전각 → 반각 변환
|
|
66
66
|
|
|
67
|
-
//
|
|
67
|
+
// 전각 → 반각 매핑 테이블 (모듈 로드 시 한 번만 생성)
|
|
68
68
|
const fullWidthCharMap: Record<string, string> = {
|
|
69
69
|
"A": "A",
|
|
70
70
|
"B": "B",
|
|
@@ -133,18 +133,18 @@ const fullWidthCharMap: Record<string, string> = {
|
|
|
133
133
|
"(": "(",
|
|
134
134
|
};
|
|
135
135
|
|
|
136
|
-
//
|
|
136
|
+
// 정규식도 한 번만 생성
|
|
137
137
|
const fullWidthCharRegex = new RegExp(`[${Object.keys(fullWidthCharMap).join("")}]`, "g");
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
|
-
*
|
|
140
|
+
* 전각 문자를 반각 문자로 변환
|
|
141
141
|
*
|
|
142
|
-
*
|
|
143
|
-
* -
|
|
144
|
-
* -
|
|
145
|
-
* -
|
|
146
|
-
* -
|
|
147
|
-
* -
|
|
142
|
+
* 변환 대상:
|
|
143
|
+
* - 전각 대문자 (A-Z → A-Z)
|
|
144
|
+
* - 전각 소문자 (a-z → a-z)
|
|
145
|
+
* - 전각 숫자 (0-9 → 0-9)
|
|
146
|
+
* - 전각 공백 ( → 일반 공백)
|
|
147
|
+
* - 전각 괄호 (() → ())
|
|
148
148
|
*
|
|
149
149
|
* @example
|
|
150
150
|
* replaceFullWidth("A123") // "A123"
|
|
@@ -156,10 +156,10 @@ export function replaceFullWidth(str: string): string {
|
|
|
156
156
|
|
|
157
157
|
//#endregion
|
|
158
158
|
|
|
159
|
-
//#region
|
|
159
|
+
//#region 대소문자 변환
|
|
160
160
|
|
|
161
161
|
/**
|
|
162
|
-
*
|
|
162
|
+
* PascalCase로 변환
|
|
163
163
|
* @example "hello-world" → "HelloWorld"
|
|
164
164
|
* @example "hello_world" → "HelloWorld"
|
|
165
165
|
* @example "hello.world" → "HelloWorld"
|
|
@@ -171,7 +171,7 @@ export function toPascalCase(str: string): string {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
/**
|
|
174
|
-
*
|
|
174
|
+
* camelCase로 변환
|
|
175
175
|
* @example "hello-world" → "helloWorld"
|
|
176
176
|
* @example "hello_world" → "helloWorld"
|
|
177
177
|
* @example "HelloWorld" → "helloWorld"
|
|
@@ -183,28 +183,28 @@ export function toCamelCase(str: string): string {
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
/**
|
|
186
|
-
*
|
|
186
|
+
* kebab-case로 변환
|
|
187
187
|
*
|
|
188
188
|
* @example "HelloWorld" → "hello-world"
|
|
189
189
|
* @example "helloWorld" → "hello-world"
|
|
190
|
-
* @example "hello_world" → "hello_world" (
|
|
191
|
-
* @example "Hello_World" → "hello-_world" (
|
|
192
|
-
* @example "Hello-World" → "hello--world" (
|
|
193
|
-
* @example "XMLParser" → "x-m-l-parser" (
|
|
190
|
+
* @example "hello_world" → "hello_world" (소문자만이면 변환 없음)
|
|
191
|
+
* @example "Hello_World" → "hello-_world" (기존 구분자 유지)
|
|
192
|
+
* @example "Hello-World" → "hello--world" (기존 구분자 유지)
|
|
193
|
+
* @example "XMLParser" → "x-m-l-parser" (연속 대문자 분리)
|
|
194
194
|
*/
|
|
195
195
|
export function toKebabCase(str: string): string {
|
|
196
196
|
return toCaseWithSeparator(str, "-");
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
/**
|
|
200
|
-
*
|
|
200
|
+
* snake_case로 변환
|
|
201
201
|
*
|
|
202
202
|
* @example "HelloWorld" → "hello_world"
|
|
203
203
|
* @example "helloWorld" → "hello_world"
|
|
204
|
-
* @example "hello-world" → "hello-world" (
|
|
205
|
-
* @example "Hello-World" → "hello_-world" (
|
|
206
|
-
* @example "Hello_World" → "hello__world" (
|
|
207
|
-
* @example "XMLParser" → "x_m_l_parser" (
|
|
204
|
+
* @example "hello-world" → "hello-world" (소문자만이면 변환 없음)
|
|
205
|
+
* @example "Hello-World" → "hello_-world" (기존 구분자 유지)
|
|
206
|
+
* @example "Hello_World" → "hello__world" (기존 구분자 유지)
|
|
207
|
+
* @example "XMLParser" → "x_m_l_parser" (연속 대문자 분리)
|
|
208
208
|
*/
|
|
209
209
|
export function toSnakeCase(str: string): string {
|
|
210
210
|
return toCaseWithSeparator(str, "_");
|
|
@@ -218,13 +218,13 @@ function toCaseWithSeparator(str: string, separator: string): string {
|
|
|
218
218
|
|
|
219
219
|
//#endregion
|
|
220
220
|
|
|
221
|
-
//#region
|
|
221
|
+
//#region 기타
|
|
222
222
|
|
|
223
223
|
/**
|
|
224
|
-
*
|
|
224
|
+
* 문자열이 undefined 또는 빈 문자열인지 검사 (타입 가드)
|
|
225
225
|
*
|
|
226
|
-
* @param str
|
|
227
|
-
* @returns
|
|
226
|
+
* @param str 검사할 문자열
|
|
227
|
+
* @returns undefined, null, 또는 빈 문자열이면 true
|
|
228
228
|
*
|
|
229
229
|
* @example
|
|
230
230
|
* const name: string | undefined = getValue();
|
|
@@ -241,12 +241,12 @@ export function isNullOrEmpty(str: string | undefined): str is "" | undefined {
|
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
/**
|
|
244
|
-
*
|
|
244
|
+
* 특정 위치에 문자열 삽입
|
|
245
245
|
*
|
|
246
|
-
* @param str
|
|
247
|
-
* @param index
|
|
248
|
-
* @param insertString
|
|
249
|
-
* @returns
|
|
246
|
+
* @param str 원본 문자열
|
|
247
|
+
* @param index 삽입할 위치 (0부터 시작)
|
|
248
|
+
* @param insertString 삽입할 문자열
|
|
249
|
+
* @returns 삽입이 적용된 새 문자열
|
|
250
250
|
*
|
|
251
251
|
* @example
|
|
252
252
|
* insert("Hello World", 5, ","); // "Hello, World"
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* 템플릿 문자열 태그 함수
|
|
3
|
+
* IDE 코드 하이라이팅 지원용 (실제 동작은 문자열 결합 + 들여쓰기 정규화)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @param strings
|
|
9
|
-
* @param values
|
|
10
|
-
* @returns
|
|
7
|
+
* JavaScript 코드 하이라이팅용 템플릿 태그
|
|
8
|
+
* @param strings 템플릿 문자열 배열
|
|
9
|
+
* @param values 보간된 값들
|
|
10
|
+
* @returns 들여쓰기가 정규화된 문자열
|
|
11
11
|
* @example
|
|
12
12
|
* const code = js`
|
|
13
13
|
* function hello() {
|
|
@@ -20,10 +20,10 @@ export function js(strings: TemplateStringsArray, ...values: unknown[]): string
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
* @param strings
|
|
25
|
-
* @param values
|
|
26
|
-
* @returns
|
|
23
|
+
* TypeScript 코드 하이라이팅용 템플릿 태그
|
|
24
|
+
* @param strings 템플릿 문자열 배열
|
|
25
|
+
* @param values 보간된 값들
|
|
26
|
+
* @returns 들여쓰기가 정규화된 문자열
|
|
27
27
|
* @example
|
|
28
28
|
* const code = ts`
|
|
29
29
|
* interface User {
|
|
@@ -37,10 +37,10 @@ export function ts(strings: TemplateStringsArray, ...values: unknown[]): string
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
41
|
-
* @param strings
|
|
42
|
-
* @param values
|
|
43
|
-
* @returns
|
|
40
|
+
* HTML 마크업 하이라이팅용 템플릿 태그
|
|
41
|
+
* @param strings 템플릿 문자열 배열
|
|
42
|
+
* @param values 보간된 값들
|
|
43
|
+
* @returns 들여쓰기가 정규화된 문자열
|
|
44
44
|
* @example
|
|
45
45
|
* const markup = html`
|
|
46
46
|
* <div class="container">
|
|
@@ -53,10 +53,10 @@ export function html(strings: TemplateStringsArray, ...values: unknown[]): strin
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
57
|
-
* @param strings
|
|
58
|
-
* @param values
|
|
59
|
-
* @returns
|
|
56
|
+
* MSSQL T-SQL 하이라이팅용 템플릿 태그
|
|
57
|
+
* @param strings 템플릿 문자열 배열
|
|
58
|
+
* @param values 보간된 값들
|
|
59
|
+
* @returns 들여쓰기가 정규화된 문자열
|
|
60
60
|
* @example
|
|
61
61
|
* const query = tsql`
|
|
62
62
|
* SELECT TOP 10 *
|
|
@@ -69,10 +69,10 @@ export function tsql(strings: TemplateStringsArray, ...values: unknown[]): strin
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
|
-
*
|
|
73
|
-
* @param strings
|
|
74
|
-
* @param values
|
|
75
|
-
* @returns
|
|
72
|
+
* MySQL SQL 하이라이팅용 템플릿 태그
|
|
73
|
+
* @param strings 템플릿 문자열 배열
|
|
74
|
+
* @param values 보간된 값들
|
|
75
|
+
* @returns 들여쓰기가 정규화된 문자열
|
|
76
76
|
* @example
|
|
77
77
|
* const query = mysql`
|
|
78
78
|
* SELECT *
|
|
@@ -85,10 +85,10 @@ export function mysql(strings: TemplateStringsArray, ...values: unknown[]): stri
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
*
|
|
89
|
-
* @param strings
|
|
90
|
-
* @param values
|
|
91
|
-
* @returns
|
|
88
|
+
* PostgreSQL SQL 하이라이팅용 템플릿 태그
|
|
89
|
+
* @param strings 템플릿 문자열 배열
|
|
90
|
+
* @param values 보간된 값들
|
|
91
|
+
* @returns 들여쓰기가 정규화된 문자열
|
|
92
92
|
* @example
|
|
93
93
|
* const query = pgsql`
|
|
94
94
|
* SELECT *
|
|
@@ -111,7 +111,7 @@ function _combine(strings: TemplateStringsArray, values: unknown[]): string {
|
|
|
111
111
|
function _trimIndent(text: string): string {
|
|
112
112
|
const lines = text.split("\n");
|
|
113
113
|
|
|
114
|
-
//
|
|
114
|
+
// 앞뒤 빈 줄 제거 (연속된 빈 줄 모두 제거)
|
|
115
115
|
while (lines.length > 0 && lines[0].trim() === "") {
|
|
116
116
|
lines.shift();
|
|
117
117
|
}
|
|
@@ -119,7 +119,7 @@ function _trimIndent(text: string): string {
|
|
|
119
119
|
lines.pop();
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
//
|
|
122
|
+
// 최소 들여쓰기 계산
|
|
123
123
|
const minIndent = lines
|
|
124
124
|
.filter((line) => line.trim() !== "")
|
|
125
125
|
.reduce((min, line) => {
|
|
@@ -127,6 +127,6 @@ function _trimIndent(text: string): string {
|
|
|
127
127
|
return Math.min(min, indent);
|
|
128
128
|
}, Infinity);
|
|
129
129
|
|
|
130
|
-
//
|
|
130
|
+
// 들여쓰기 제거
|
|
131
131
|
return lines.map((line) => (line.trim() === "" ? "" : line.slice(minIndent))).join("\n");
|
|
132
132
|
}
|
|
@@ -4,44 +4,44 @@ import { Time } from "../types/time";
|
|
|
4
4
|
import { Uuid } from "../types/uuid";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Worker 간 전송 가능한 객체 타입
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* 이 코드에서는 ArrayBuffer만 사용됨.
|
|
10
10
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects
|
|
11
11
|
*/
|
|
12
12
|
type Transferable = ArrayBuffer;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Transferable
|
|
15
|
+
* Transferable 변환 유틸리티 함수
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Worker 간 데이터 전송을 위한 직렬화/역직렬화 수행.
|
|
18
|
+
* structuredClone이 지원하지 않는 커스텀 타입을 처리.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
20
|
+
* 지원 타입:
|
|
21
21
|
* - Date, DateTime, DateOnly, Time, Uuid, RegExp
|
|
22
|
-
* - Error (
|
|
23
|
-
* - Uint8Array (
|
|
24
|
-
* - Array, Map, Set,
|
|
22
|
+
* - Error (cause, code, detail 포함)
|
|
23
|
+
* - Uint8Array (다른 TypedArray는 지원하지 않으며 일반 객체로 처리)
|
|
24
|
+
* - Array, Map, Set, 일반 객체
|
|
25
25
|
*
|
|
26
|
-
* @note
|
|
27
|
-
* @note
|
|
26
|
+
* @note 순환 참조 시 transferableEncode에서 TypeError 발생 (경로 정보 포함)
|
|
27
|
+
* @note 같은 객체가 여러 곳에서 참조되면 캐싱된 인코딩 결과를 재사용
|
|
28
28
|
*
|
|
29
29
|
* @example
|
|
30
|
-
* //
|
|
30
|
+
* // Worker로 데이터 전송
|
|
31
31
|
* const { result, transferList } = transferableEncode(data);
|
|
32
32
|
* worker.postMessage(result, transferList);
|
|
33
33
|
*
|
|
34
|
-
* //
|
|
34
|
+
* // Worker에서 데이터 수신
|
|
35
35
|
* const decoded = decode(event.data);
|
|
36
36
|
*/
|
|
37
37
|
|
|
38
38
|
//#region encode
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
41
|
+
* Simplysm 타입을 사용하는 객체를 일반 객체로 변환
|
|
42
|
+
* Worker로 전송 가능한 형태로 직렬화
|
|
43
43
|
*
|
|
44
|
-
* @throws TypeError
|
|
44
|
+
* @throws TypeError 순환 참조가 감지된 경우
|
|
45
45
|
*/
|
|
46
46
|
export function encode(obj: unknown): {
|
|
47
47
|
result: unknown;
|
|
@@ -63,19 +63,19 @@ function encodeImpl(
|
|
|
63
63
|
): unknown {
|
|
64
64
|
if (obj == null) return obj;
|
|
65
65
|
|
|
66
|
-
//
|
|
66
|
+
// 객체 타입 처리: 순환 참조 감지 + 캐시
|
|
67
67
|
if (typeof obj === "object") {
|
|
68
|
-
//
|
|
68
|
+
// 순환 참조 감지 (현재 재귀 스택에 있는 객체)
|
|
69
69
|
if (ancestors.has(obj)) {
|
|
70
70
|
const currentPath = path.length > 0 ? path.join(".") : "root";
|
|
71
|
-
throw new TypeError(
|
|
71
|
+
throw new TypeError(`순환 참조 감지됨: ${currentPath}`);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
//
|
|
74
|
+
// 이미 인코딩된 객체이면 캐싱된 결과 재사용
|
|
75
75
|
const cached = cache.get(obj);
|
|
76
76
|
if (cached !== undefined) return cached;
|
|
77
77
|
|
|
78
|
-
//
|
|
78
|
+
// 재귀 스택에 추가
|
|
79
79
|
ancestors.add(obj);
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -84,8 +84,8 @@ function encodeImpl(
|
|
|
84
84
|
try {
|
|
85
85
|
// 1. Uint8Array
|
|
86
86
|
if (obj instanceof Uint8Array) {
|
|
87
|
-
// SharedArrayBuffer
|
|
88
|
-
//
|
|
87
|
+
// SharedArrayBuffer는 이미 공유 메모리이므로 transferList에 추가하지 않음
|
|
88
|
+
// zero-copy 전송을 위해 ArrayBuffer만 transferList에 추가
|
|
89
89
|
const isSharedArrayBuffer =
|
|
90
90
|
typeof SharedArrayBuffer !== "undefined" && obj.buffer instanceof SharedArrayBuffer;
|
|
91
91
|
const buffer = obj.buffer as ArrayBuffer;
|
|
@@ -94,7 +94,7 @@ function encodeImpl(
|
|
|
94
94
|
}
|
|
95
95
|
result = obj;
|
|
96
96
|
}
|
|
97
|
-
// 2.
|
|
97
|
+
// 2. 특수 타입 변환 (JSON.stringify 없이 태그된 객체로 변환)
|
|
98
98
|
else if (obj instanceof Date) {
|
|
99
99
|
result = { __type__: "Date", data: obj.getTime() };
|
|
100
100
|
} else if (obj instanceof DateTime) {
|
|
@@ -138,13 +138,13 @@ function encodeImpl(
|
|
|
138
138
|
},
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
|
-
// 3. Array
|
|
141
|
+
// 3. Array 재귀
|
|
142
142
|
else if (Array.isArray(obj)) {
|
|
143
143
|
result = obj.map((item, idx) =>
|
|
144
144
|
encodeImpl(item, transferList, [...path, idx], ancestors, cache),
|
|
145
145
|
);
|
|
146
146
|
}
|
|
147
|
-
// 4. Map
|
|
147
|
+
// 4. Map 재귀
|
|
148
148
|
else if (obj instanceof Map) {
|
|
149
149
|
let idx = 0;
|
|
150
150
|
result = new Map(
|
|
@@ -159,7 +159,7 @@ function encodeImpl(
|
|
|
159
159
|
}),
|
|
160
160
|
);
|
|
161
161
|
}
|
|
162
|
-
// 5. Set
|
|
162
|
+
// 5. Set 재귀
|
|
163
163
|
else if (obj instanceof Set) {
|
|
164
164
|
let idx = 0;
|
|
165
165
|
result = new Set(
|
|
@@ -168,7 +168,7 @@ function encodeImpl(
|
|
|
168
168
|
),
|
|
169
169
|
);
|
|
170
170
|
}
|
|
171
|
-
// 6.
|
|
171
|
+
// 6. 일반 객체 재귀
|
|
172
172
|
else if (typeof obj === "object") {
|
|
173
173
|
const res: Record<string, unknown> = {};
|
|
174
174
|
const record = obj as Record<string, unknown>;
|
|
@@ -177,19 +177,19 @@ function encodeImpl(
|
|
|
177
177
|
}
|
|
178
178
|
result = res;
|
|
179
179
|
}
|
|
180
|
-
// 7.
|
|
180
|
+
// 7. 원시 타입
|
|
181
181
|
else {
|
|
182
182
|
return obj;
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
//
|
|
185
|
+
// 캐시에 저장 (성공 시에만)
|
|
186
186
|
if (typeof obj === "object") {
|
|
187
187
|
cache.set(obj, result);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
return result;
|
|
191
191
|
} finally {
|
|
192
|
-
//
|
|
192
|
+
// 재귀 스택에서 제거 (예외 발생 시에도 반드시 실행)
|
|
193
193
|
if (typeof obj === "object") {
|
|
194
194
|
ancestors.delete(obj);
|
|
195
195
|
}
|
|
@@ -201,13 +201,13 @@ function encodeImpl(
|
|
|
201
201
|
//#region decode
|
|
202
202
|
|
|
203
203
|
/**
|
|
204
|
-
*
|
|
205
|
-
*
|
|
204
|
+
* 직렬화된 객체를 Simplysm 타입을 사용하는 객체로 변환
|
|
205
|
+
* Worker에서 수신한 데이터 역직렬화
|
|
206
206
|
*/
|
|
207
207
|
export function decode(obj: unknown): unknown {
|
|
208
208
|
if (obj == null) return obj;
|
|
209
209
|
|
|
210
|
-
// 1.
|
|
210
|
+
// 1. 태그된 객체에서 특수 타입 복원
|
|
211
211
|
if (typeof obj === "object" && "__type__" in obj && "data" in obj) {
|
|
212
212
|
const typed = obj as { __type__: string; data: unknown };
|
|
213
213
|
const data = typed.data;
|
|
@@ -245,12 +245,12 @@ export function decode(obj: unknown): unknown {
|
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
// 2. Array
|
|
248
|
+
// 2. Array 재귀
|
|
249
249
|
if (Array.isArray(obj)) {
|
|
250
250
|
return obj.map((item) => decode(item));
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
// 3. Map
|
|
253
|
+
// 3. Map 재귀
|
|
254
254
|
if (obj instanceof Map) {
|
|
255
255
|
const newMap = new Map<unknown, unknown>();
|
|
256
256
|
for (const [k, v] of obj) {
|
|
@@ -259,7 +259,7 @@ export function decode(obj: unknown): unknown {
|
|
|
259
259
|
return newMap;
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
-
// 4. Set
|
|
262
|
+
// 4. Set 재귀
|
|
263
263
|
if (obj instanceof Set) {
|
|
264
264
|
const newSet = new Set<unknown>();
|
|
265
265
|
for (const v of obj) {
|
|
@@ -268,7 +268,7 @@ export function decode(obj: unknown): unknown {
|
|
|
268
268
|
return newSet;
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
-
// 5.
|
|
271
|
+
// 5. 객체 재귀
|
|
272
272
|
if (typeof obj === "object") {
|
|
273
273
|
const record = obj as Record<string, unknown>;
|
|
274
274
|
const result: Record<string, unknown> = {};
|
package/src/utils/wait.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 대기 유틸리티 함수
|
|
3
3
|
*/
|
|
4
4
|
import { TimeoutError } from "../errors/timeout-error";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @param forwarder
|
|
9
|
-
* @param milliseconds
|
|
10
|
-
* @param maxCount
|
|
7
|
+
* 조건이 true가 될 때까지 대기
|
|
8
|
+
* @param forwarder 조건 함수
|
|
9
|
+
* @param milliseconds 확인 간격 (기본값: 100ms)
|
|
10
|
+
* @param maxCount 최대 시도 횟수 (undefined이면 무제한)
|
|
11
11
|
*
|
|
12
|
-
* @note
|
|
12
|
+
* @note 첫 번째 호출에서 조건이 true이면 즉시 반환.
|
|
13
13
|
* @example
|
|
14
|
-
* // maxCount=3:
|
|
14
|
+
* // maxCount=3: 최대 3번 조건 확인, 모두 false이면 TimeoutError 발생
|
|
15
15
|
* await waitUntil(() => someCondition, 100, 3);
|
|
16
|
-
* @throws TimeoutError
|
|
16
|
+
* @throws TimeoutError 최대 시도 횟수를 초과했을 때
|
|
17
17
|
*/
|
|
18
18
|
export async function until(
|
|
19
19
|
forwarder: () => boolean | Promise<boolean>,
|
|
@@ -32,8 +32,8 @@ export async function until(
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
36
|
-
* @param millisecond
|
|
35
|
+
* 지정된 시간만큼 대기
|
|
36
|
+
* @param millisecond 대기 시간 (ms)
|
|
37
37
|
*/
|
|
38
38
|
export async function time(millisecond: number): Promise<void> {
|
|
39
39
|
return new Promise<void>((resolve) => setTimeout(resolve, millisecond));
|