@simplysm/core-common 13.0.99 → 14.0.1

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 (181) hide show
  1. package/dist/common.types.d.ts +14 -14
  2. package/dist/common.types.js +2 -1
  3. package/dist/common.types.js.map +1 -6
  4. package/dist/env.d.ts +5 -0
  5. package/dist/env.d.ts.map +1 -1
  6. package/dist/env.js +12 -8
  7. package/dist/env.js.map +1 -6
  8. package/dist/errors/argument-error.d.ts +10 -10
  9. package/dist/errors/argument-error.d.ts.map +1 -1
  10. package/dist/errors/argument-error.js +31 -14
  11. package/dist/errors/argument-error.js.map +1 -6
  12. package/dist/errors/not-implemented-error.d.ts +8 -8
  13. package/dist/errors/not-implemented-error.js +30 -12
  14. package/dist/errors/not-implemented-error.js.map +1 -6
  15. package/dist/errors/sd-error.d.ts +10 -10
  16. package/dist/errors/sd-error.d.ts.map +1 -1
  17. package/dist/errors/sd-error.js +45 -24
  18. package/dist/errors/sd-error.js.map +1 -6
  19. package/dist/errors/timeout-error.d.ts +10 -10
  20. package/dist/errors/timeout-error.js +34 -15
  21. package/dist/errors/timeout-error.js.map +1 -6
  22. package/dist/extensions/arr-ext.d.ts +2 -2
  23. package/dist/extensions/arr-ext.helpers.d.ts +10 -10
  24. package/dist/extensions/arr-ext.helpers.js +112 -89
  25. package/dist/extensions/arr-ext.helpers.js.map +1 -6
  26. package/dist/extensions/arr-ext.js +458 -422
  27. package/dist/extensions/arr-ext.js.map +1 -6
  28. package/dist/extensions/arr-ext.types.d.ts +57 -57
  29. package/dist/extensions/arr-ext.types.d.ts.map +1 -1
  30. package/dist/extensions/arr-ext.types.js +6 -1
  31. package/dist/extensions/arr-ext.types.js.map +1 -6
  32. package/dist/extensions/map-ext.d.ts +16 -16
  33. package/dist/extensions/map-ext.js +27 -22
  34. package/dist/extensions/map-ext.js.map +1 -6
  35. package/dist/extensions/set-ext.d.ts +11 -11
  36. package/dist/extensions/set-ext.js +32 -25
  37. package/dist/extensions/set-ext.js.map +1 -6
  38. package/dist/features/debounce-queue.d.ts +17 -17
  39. package/dist/features/debounce-queue.js +98 -70
  40. package/dist/features/debounce-queue.js.map +1 -6
  41. package/dist/features/event-emitter.d.ts +20 -20
  42. package/dist/features/event-emitter.js +101 -78
  43. package/dist/features/event-emitter.js.map +1 -6
  44. package/dist/features/serial-queue.d.ts +11 -11
  45. package/dist/features/serial-queue.js +78 -57
  46. package/dist/features/serial-queue.js.map +1 -6
  47. package/dist/globals.d.ts +4 -4
  48. package/dist/globals.js +9 -1
  49. package/dist/globals.js.map +1 -6
  50. package/dist/index.js +28 -27
  51. package/dist/index.js.map +1 -6
  52. package/dist/types/date-only.d.ts +64 -64
  53. package/dist/types/date-only.d.ts.map +1 -1
  54. package/dist/types/date-only.js +263 -252
  55. package/dist/types/date-only.js.map +1 -6
  56. package/dist/types/date-time.d.ts +36 -36
  57. package/dist/types/date-time.d.ts.map +1 -1
  58. package/dist/types/date-time.js +196 -288
  59. package/dist/types/date-time.js.map +1 -6
  60. package/dist/types/lazy-gc-map.d.ts +26 -26
  61. package/dist/types/lazy-gc-map.d.ts.map +1 -1
  62. package/dist/types/lazy-gc-map.js +202 -159
  63. package/dist/types/lazy-gc-map.js.map +1 -6
  64. package/dist/types/time.d.ts +23 -23
  65. package/dist/types/time.d.ts.map +1 -1
  66. package/dist/types/time.js +169 -158
  67. package/dist/types/time.js.map +1 -6
  68. package/dist/types/uuid.d.ts +11 -11
  69. package/dist/types/uuid.d.ts.map +1 -1
  70. package/dist/types/uuid.js +95 -70
  71. package/dist/types/uuid.js.map +1 -6
  72. package/dist/utils/bytes.d.ts +17 -17
  73. package/dist/utils/bytes.js +137 -81
  74. package/dist/utils/bytes.js.map +1 -6
  75. package/dist/utils/date-format.d.ts +40 -40
  76. package/dist/utils/date-format.js +187 -101
  77. package/dist/utils/date-format.js.map +1 -6
  78. package/dist/utils/error.d.ts +4 -4
  79. package/dist/utils/error.js +11 -6
  80. package/dist/utils/error.js.map +1 -6
  81. package/dist/utils/json.d.ts +19 -19
  82. package/dist/utils/json.js +187 -135
  83. package/dist/utils/json.js.map +1 -6
  84. package/dist/utils/num.d.ts +20 -20
  85. package/dist/utils/num.js +76 -34
  86. package/dist/utils/num.js.map +1 -6
  87. package/dist/utils/obj.d.ts +111 -111
  88. package/dist/utils/obj.d.ts.map +1 -1
  89. package/dist/utils/obj.js +706 -496
  90. package/dist/utils/obj.js.map +1 -6
  91. package/dist/utils/path.d.ts +10 -10
  92. package/dist/utils/path.js +35 -18
  93. package/dist/utils/path.js.map +1 -6
  94. package/dist/utils/primitive.d.ts +5 -5
  95. package/dist/utils/primitive.js +34 -14
  96. package/dist/utils/primitive.js.map +1 -6
  97. package/dist/utils/str.d.ts +38 -38
  98. package/dist/utils/str.js +217 -113
  99. package/dist/utils/str.js.map +1 -6
  100. package/dist/utils/template-strings.d.ts +26 -26
  101. package/dist/utils/template-strings.js +113 -40
  102. package/dist/utils/template-strings.js.map +1 -6
  103. package/dist/utils/transferable.d.ts +18 -18
  104. package/dist/utils/transferable.js +218 -151
  105. package/dist/utils/transferable.js.map +1 -6
  106. package/dist/utils/wait.d.ts +9 -9
  107. package/dist/utils/wait.js +30 -15
  108. package/dist/utils/wait.js.map +1 -6
  109. package/dist/utils/xml.d.ts +13 -13
  110. package/dist/utils/xml.js +84 -46
  111. package/dist/utils/xml.js.map +1 -6
  112. package/dist/utils/zip.d.ts +22 -22
  113. package/dist/utils/zip.js +172 -148
  114. package/dist/utils/zip.js.map +1 -6
  115. package/package.json +5 -7
  116. package/src/common.types.ts +14 -14
  117. package/src/env.ts +9 -1
  118. package/src/errors/argument-error.ts +15 -15
  119. package/src/errors/not-implemented-error.ts +9 -9
  120. package/src/errors/sd-error.ts +12 -12
  121. package/src/errors/timeout-error.ts +12 -12
  122. package/src/extensions/arr-ext.helpers.ts +16 -16
  123. package/src/extensions/arr-ext.ts +35 -35
  124. package/src/extensions/arr-ext.types.ts +57 -57
  125. package/src/extensions/map-ext.ts +16 -16
  126. package/src/extensions/set-ext.ts +11 -11
  127. package/src/features/debounce-queue.ts +23 -23
  128. package/src/features/event-emitter.ts +25 -25
  129. package/src/features/serial-queue.ts +13 -13
  130. package/src/globals.ts +4 -4
  131. package/src/index.ts +5 -5
  132. package/src/types/date-only.ts +84 -83
  133. package/src/types/date-time.ts +43 -42
  134. package/src/types/lazy-gc-map.ts +44 -44
  135. package/src/types/time.ts +29 -29
  136. package/src/types/uuid.ts +15 -15
  137. package/src/utils/bytes.ts +35 -35
  138. package/src/utils/date-format.ts +59 -59
  139. package/src/utils/error.ts +4 -4
  140. package/src/utils/json.ts +41 -41
  141. package/src/utils/num.ts +20 -20
  142. package/src/utils/obj.ts +138 -138
  143. package/src/utils/path.ts +10 -10
  144. package/src/utils/primitive.ts +6 -6
  145. package/src/utils/str.ts +48 -48
  146. package/src/utils/template-strings.ts +29 -29
  147. package/src/utils/transferable.ts +38 -38
  148. package/src/utils/wait.ts +10 -10
  149. package/src/utils/xml.ts +19 -19
  150. package/src/utils/zip.ts +25 -25
  151. package/README.md +0 -160
  152. package/docs/errors.md +0 -119
  153. package/docs/extensions.md +0 -387
  154. package/docs/features.md +0 -143
  155. package/docs/types.md +0 -287
  156. package/docs/utils.md +0 -757
  157. package/tests/errors/errors.spec.ts +0 -80
  158. package/tests/extensions/array-extension.spec.ts +0 -654
  159. package/tests/extensions/map-extension.spec.ts +0 -117
  160. package/tests/extensions/set-extension.spec.ts +0 -67
  161. package/tests/types/date-only.spec.ts +0 -533
  162. package/tests/types/date-time.spec.ts +0 -246
  163. package/tests/types/lazy-gc-map.spec.ts +0 -606
  164. package/tests/types/time.spec.ts +0 -428
  165. package/tests/types/uuid.spec.ts +0 -74
  166. package/tests/utils/bytes-utils.spec.ts +0 -197
  167. package/tests/utils/date-format.spec.ts +0 -350
  168. package/tests/utils/debounce-queue.spec.ts +0 -226
  169. package/tests/utils/json.spec.ts +0 -400
  170. package/tests/utils/number.spec.ts +0 -136
  171. package/tests/utils/object.spec.ts +0 -810
  172. package/tests/utils/path.spec.ts +0 -70
  173. package/tests/utils/primitive.spec.ts +0 -43
  174. package/tests/utils/sd-event-emitter.spec.ts +0 -189
  175. package/tests/utils/serial-queue.spec.ts +0 -305
  176. package/tests/utils/string.spec.ts +0 -265
  177. package/tests/utils/template-strings.spec.ts +0 -48
  178. package/tests/utils/transferable.spec.ts +0 -639
  179. package/tests/utils/wait.spec.ts +0 -123
  180. package/tests/utils/xml.spec.ts +0 -146
  181. package/tests/utils/zip.spec.ts +0 -221
package/src/utils/obj.ts CHANGED
@@ -7,26 +7,26 @@ import { ArgumentError } from "../errors/argument-error";
7
7
  //#region clone
8
8
 
9
9
  /**
10
- * Deep clone
11
- * - Supports circular references
12
- * - Supports copying custom types (DateTime, DateOnly, Time, Uuid, Uint8Array)
10
+ * 깊은 복사
11
+ * - 순환 참조 지원
12
+ * - 커스텀 타입 복사 지원 (DateTime, DateOnly, Time, Uuid, Uint8Array)
13
13
  *
14
- * @note Functions and Symbols are not cloned and references are maintained
15
- * @note WeakMap and WeakSet are not supported (copied as generic objects, resulting in empty objects)
16
- * @note Prototype chain is maintained (using Object.setPrototypeOf)
17
- * @note Getters/setters are evaluated as current values and copied (accessor properties themselves are not copied)
14
+ * @note 함수와 Symbol은 복사되지 않고 참조가 유지됨
15
+ * @note WeakMap WeakSet 지원되지 않음 (일반 객체로 복사되어 객체가 )
16
+ * @note 프로토타입 체인이 유지됨 (Object.setPrototypeOf 사용)
17
+ * @note Getter/setter는 현재 값으로 평가되어 복사됨 (접근자 속성 자체는 복사되지 않음)
18
18
  */
19
19
  export function clone<TObj>(source: TObj): TObj {
20
20
  return cloneImpl(source) as TObj;
21
21
  }
22
22
 
23
23
  function cloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): unknown {
24
- // Primitives are returned as-is
24
+ // 원시 값은 그대로 반환
25
25
  if (typeof source !== "object" || source === null) {
26
26
  return source;
27
27
  }
28
28
 
29
- // Immutable-like types (no internal object references)
29
+ // 불변과 유사한 타입 (내부 객체 참조 없음)
30
30
  if (source instanceof Date) {
31
31
  return new Date(source.getTime());
32
32
  }
@@ -52,14 +52,14 @@ function cloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): unkn
52
52
  return new RegExp(source.source, source.flags);
53
53
  }
54
54
 
55
- // Circular reference check (applies to all object types including Error)
55
+ // 순환 참조 검사 (Error를 포함한 모든 객체 타입에 적용)
56
56
  const currPrevClones = prevClones ?? new WeakMap<object, unknown>();
57
57
  if (currPrevClones.has(source)) {
58
58
  return currPrevClones.get(source);
59
59
  }
60
60
 
61
- // Error (including cause)
62
- // Prototype-based copying instead of constructor call - ensures custom Error class compatibility
61
+ // Error (cause 포함)
62
+ // 생성자 호출 대신 프로토타입 기반 복사 - 커스텀 Error 클래스 호환성 보장
63
63
  if (source instanceof Error) {
64
64
  const cloned = Object.create(Object.getPrototypeOf(source)) as Error;
65
65
  currPrevClones.set(source, cloned);
@@ -69,7 +69,7 @@ function cloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): unkn
69
69
  if (source.cause !== undefined) {
70
70
  cloned.cause = cloneImpl(source.cause, currPrevClones);
71
71
  }
72
- // Copy custom Error properties
72
+ // 커스텀 Error 속성 복사
73
73
  for (const key of Object.keys(source)) {
74
74
  if (!["message", "name", "stack", "cause"].includes(key)) {
75
75
  const desc = Object.getOwnPropertyDescriptor(source, key);
@@ -117,7 +117,7 @@ function cloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): unkn
117
117
  return result;
118
118
  }
119
119
 
120
- // Other Object types
120
+ // 기타 Object 타입
121
121
  const result: Record<string, unknown> = {};
122
122
  Object.setPrototypeOf(result, Object.getPrototypeOf(source));
123
123
  currPrevClones.set(source, result);
@@ -134,40 +134,40 @@ function cloneImpl(source: unknown, prevClones?: WeakMap<object, unknown>): unkn
134
134
 
135
135
  //#region equal
136
136
 
137
- /** equal options type */
137
+ /** equal 옵션 타입 */
138
138
  export interface EqualOptions {
139
- /** List of keys to compare. When specified, only those keys are compared (applies only to top level) */
139
+ /** 비교할 key 목록. 지정 해당 key만 비교 (최상위 레벨에만 적용) */
140
140
  topLevelIncludes?: string[];
141
- /** List of keys to exclude from comparison (applies only to top level) */
141
+ /** 비교에서 제외할 key 목록 (최상위 레벨에만 적용) */
142
142
  topLevelExcludes?: string[];
143
- /** Whether to ignore array order. O(n²) complexity when true */
143
+ /** array 순서를 무시할지 여부. true면 O(n²) 복잡도 */
144
144
  ignoreArrayIndex?: boolean;
145
- /** Whether to do shallow comparison. Only compare 1 level (reference comparison) when true */
145
+ /** 얕은 비교 여부. true면 1단계만 비교 (참조 비교) */
146
146
  shallow?: boolean;
147
147
  }
148
148
 
149
149
  /**
150
- * Deep equality comparison
150
+ * 깊은 동등성 비교
151
151
  *
152
- * @param source Comparison target 1
153
- * @param target Comparison target 2
154
- * @param options Comparison options
155
- * @param options.topLevelIncludes List of keys to compare. When specified, only those keys are compared (applies only to top level)
156
- * @example `{ topLevelIncludes: ["id", "name"] }` - Compare only id and name keys
157
- * @param options.topLevelExcludes List of keys to exclude from comparison (applies only to top level)
158
- * @example `{ topLevelExcludes: ["updatedAt"] }` - Compare excluding updatedAt key
159
- * @param options.ignoreArrayIndex Whether to ignore array order. O(n²) complexity when true
160
- * @param options.shallow Whether to do shallow comparison. Only compare 1 level (reference comparison) when true
152
+ * @param source 비교 대상 1
153
+ * @param target 비교 대상 2
154
+ * @param options 비교 옵션
155
+ * @param options.topLevelIncludes 비교할 key 목록. 지정 해당 key만 비교 (최상위 레벨에만 적용)
156
+ * @example `{ topLevelIncludes: ["id", "name"] }` - id name key만 비교
157
+ * @param options.topLevelExcludes 비교에서 제외할 key 목록 (최상위 레벨에만 적용)
158
+ * @example `{ topLevelExcludes: ["updatedAt"] }` - updatedAt key를 제외하고 비교
159
+ * @param options.ignoreArrayIndex array 순서를 무시할지 여부. true면 O(n²) 복잡도
160
+ * @param options.shallow 얕은 비교 여부. true면 1단계만 비교 (참조 비교)
161
161
  *
162
- * @note topLevelIncludes/topLevelExcludes options apply only to object property keys.
163
- * All keys in Map are always included in comparison.
164
- * @note Performance considerations:
165
- * - Basic array comparison: O(n) time complexity
166
- * - When using `ignoreArrayIndex: true`: O(n²) time complexity
167
- * (possible performance degradation on large arrays)
168
- * @note `ignoreArrayIndex: true` behavior characteristics:
169
- * - Ignore array order and check if elements are permutations of the same set
170
- * - Example: `[1,2,3]` and `[3,2,1]` → true, `[1,1,1]` and `[1,2,3]` → false
162
+ * @note topLevelIncludes/topLevelExcludes 옵션은 객체 속성 key에만 적용됨.
163
+ * Map 모든 key는 항상 비교에 포함됨.
164
+ * @note 성능 고려사항:
165
+ * - 기본 array 비교: O(n) 시간 복잡도
166
+ * - `ignoreArrayIndex: true` 사용 시: O(n²) 시간 복잡도
167
+ * (대형 array에서 성능 저하 가능)
168
+ * @note `ignoreArrayIndex: true` 동작 특성:
169
+ * - array 순서를 무시하고 요소가 같은 집합의 순열인지 확인
170
+ * - 예: `[1,2,3]`과 `[3,2,1]` → true, `[1,1,1]`과 `[1,2,3]` → false
171
171
  */
172
172
  export function equal(source: unknown, target: unknown, options?: EqualOptions): boolean {
173
173
  if (source === target) return true;
@@ -235,7 +235,7 @@ function equalArray(source: unknown[], target: unknown[], options?: EqualOptions
235
235
  return false;
236
236
  });
237
237
  } else {
238
- // On recursive calls, topLevelIncludes/topLevelExcludes options apply only to top level, so exclude them
238
+ // 재귀 호출 topLevelIncludes/topLevelExcludes 옵션은 최상위 레벨에만 적용되므로 제외
239
239
  const recursiveOptions = {
240
240
  ignoreArrayIndex: options.ignoreArrayIndex,
241
241
  shallow: options.shallow,
@@ -259,7 +259,7 @@ function equalArray(source: unknown[], target: unknown[], options?: EqualOptions
259
259
  }
260
260
  }
261
261
  } else {
262
- // On recursive calls, topLevelIncludes/topLevelExcludes options apply only to top level, so exclude them
262
+ // 재귀 호출 topLevelIncludes/topLevelExcludes 옵션은 최상위 레벨에만 적용되므로 제외
263
263
  for (let i = 0; i < source.length; i++) {
264
264
  if (
265
265
  !equal(source[i], target[i], {
@@ -277,16 +277,16 @@ function equalArray(source: unknown[], target: unknown[], options?: EqualOptions
277
277
  }
278
278
 
279
279
  /**
280
- * Map object comparison
281
- * @note O(n²) complexity when handling non-string keys (objects, arrays, etc.)
282
- * @note Recommended to use shallow: true option for large datasets (improves to O(n) with reference comparison)
280
+ * Map 객체 비교
281
+ * @note 비문자열 key(객체, array 등) 처리 O(n²) 복잡도
282
+ * @note 대용량 데이터에는 shallow: true 옵션 사용 권장 (참조 비교로 O(n)으로 개선)
283
283
  */
284
284
  function equalMap(
285
285
  source: Map<unknown, unknown>,
286
286
  target: Map<unknown, unknown>,
287
287
  options?: EqualOptions,
288
288
  ): boolean {
289
- // When comparing Maps, topLevelIncludes/topLevelExcludes options are ignored (apply only to object property keys)
289
+ // Map 비교 topLevelIncludes/topLevelExcludes 옵션은 무시됨 (객체 속성 key에만 적용)
290
290
  const sourceKeys = Array.from(source.keys()).filter((key) => source.get(key) != null);
291
291
  const targetKeys = Array.from(target.keys()).filter((key) => target.get(key) != null);
292
292
 
@@ -296,7 +296,7 @@ function equalMap(
296
296
 
297
297
  const usedTargetKeys = new Set<number>();
298
298
  for (const sourceKey of sourceKeys) {
299
- // String keys: compare directly
299
+ // 문자열 key: 직접 비교
300
300
  if (typeof sourceKey === "string") {
301
301
  const sourceValue = source.get(sourceKey);
302
302
  const targetValue = target.get(sourceKey);
@@ -313,7 +313,7 @@ function equalMap(
313
313
  }
314
314
  }
315
315
  } else {
316
- // Non-string keys: find equivalent key in targetKeys
316
+ // 비문자열 key: targetKeys에서 동등한 key 검색
317
317
  let found = false;
318
318
  for (let i = 0; i < targetKeys.length; i++) {
319
319
  const targetKey = targetKeys[i];
@@ -387,9 +387,9 @@ function equalObject(
387
387
  }
388
388
 
389
389
  /**
390
- * Set deep equality comparison
391
- * @note Deep equal comparison (`shallow: false`) has O(n²) time complexity.
392
- * Recommended to use `shallow: true` for primitive Sets or when performance is critical
390
+ * Set 깊은 동등성 비교
391
+ * @note 깊은 비교(`shallow: false`) O(n²) 시간 복잡도.
392
+ * 원시 타입 Set이거나 성능이 중요한 경우 `shallow: true` 사용 권장
393
393
  */
394
394
  function equalSet(source: Set<unknown>, target: Set<unknown>, options?: EqualOptions): boolean {
395
395
  if (source.size !== target.size) {
@@ -403,8 +403,8 @@ function equalSet(source: Set<unknown>, target: Set<unknown>, options?: EqualOpt
403
403
  }
404
404
  }
405
405
  } else {
406
- // Deep equal: create target array only once outside loop
407
- // Track matched indices to prevent duplicate matching
406
+ // 깊은 비교: 루프 외부에서 target array 번만 생성
407
+ // 중복 매칭 방지를 위해 매칭된 인덱스 추적
408
408
  const targetArr = [...target];
409
409
  const matchedIndices = new Set<number>();
410
410
  for (const sourceItem of source) {
@@ -425,31 +425,31 @@ function equalSet(source: Set<unknown>, target: Set<unknown>, options?: EqualOpt
425
425
 
426
426
  //#region merge
427
427
 
428
- /** merge options type */
428
+ /** merge 옵션 타입 */
429
429
  export interface MergeOptions {
430
- /** Array processing method. "replace": replace with target (default), "concat": merge (deduplicate) */
430
+ /** Array 처리 방식. "replace": target으로 교체 (기본값), "concat": 병합 (중복 제거) */
431
431
  arrayProcess?: "replace" | "concat";
432
- /** Whether to delete the key when target is null */
432
+ /** target이 null일 해당 key 삭제할지 여부 */
433
433
  useDelTargetNull?: boolean;
434
434
  }
435
435
 
436
436
  /**
437
- * Deep merge (merge target into source as base)
437
+ * 깊은 병합 (source를 기반으로 target 병합)
438
438
  *
439
- * @param source Base object
440
- * @param target Object to merge
441
- * @param opt Merge options
442
- * @param opt.arrayProcess Array processing method
443
- * - `"replace"`: Replace with target array (default)
444
- * - `"concat"`: Merge source and target arrays (deduplicate with Set)
445
- * @param opt.useDelTargetNull Whether to delete the key when target value is null
446
- * - `true`: Delete the key from result if target is null
447
- * - `false` or not specified: Keep source value
439
+ * @param source 기본 객체
440
+ * @param target 병합할 객체
441
+ * @param opt 병합 옵션
442
+ * @param opt.arrayProcess Array 처리 방식
443
+ * - `"replace"`: target array 교체 (기본값)
444
+ * - `"concat"`: source target array를 병합 (Set으로 중복 제거)
445
+ * @param opt.useDelTargetNull target 값이 null일 해당 key 삭제할지 여부
446
+ * - `true`: target이 null이면 결과에서 해당 key 삭제
447
+ * - `false` 또는 미지정: source 유지
448
448
  *
449
- * @note Returns a new object without modifying original objects (guarantees immutability)
450
- * @note When using arrayProcess="concat", deduplication is done with Set,
451
- * and for object arrays, deduplication is determined by reference (address) comparison
452
- * @note If types are different, overwrite with target value
449
+ * @note 원본 객체를 수정하지 않고 객체를 반환 (불변성 보장)
450
+ * @note arrayProcess="concat" 사용 Set으로 중복 제거되며,
451
+ * 객체 array의 경우 참조(주소) 비교로 중복 여부 판단
452
+ * @note 타입이 다르면 target 값으로 덮어씀
453
453
  */
454
454
  export function merge<TSource, TMergeTarget>(
455
455
  source: TSource,
@@ -486,7 +486,7 @@ export function merge<TSource, TMergeTarget>(
486
486
  return clone(target) as TSource & TMergeTarget;
487
487
  }
488
488
 
489
- // If source is not an object or source and target are different types of objects, overwrite with target
489
+ // source 객체가 아니거나 source target 다른 타입의 객체이면 target으로 덮어씀
490
490
  if (typeof source !== "object" || source.constructor !== target.constructor) {
491
491
  return clone(target) as TSource & TMergeTarget;
492
492
  }
@@ -524,33 +524,33 @@ export function merge<TSource, TMergeTarget>(
524
524
  return resultRec as TSource & TMergeTarget;
525
525
  }
526
526
 
527
- /** merge3 options type */
527
+ /** merge3 옵션 타입 */
528
528
  export interface Merge3KeyOptions {
529
- /** List of sub-keys to compare (same as equal's topLevelIncludes) */
529
+ /** 비교할 하위 key 목록 (equal topLevelIncludes와 동일) */
530
530
  keys?: string[];
531
- /** List of sub-keys to exclude from comparison */
531
+ /** 비교에서 제외할 하위 key 목록 */
532
532
  excludes?: string[];
533
- /** Whether to ignore array order */
533
+ /** array 순서를 무시할지 여부 */
534
534
  ignoreArrayIndex?: boolean;
535
535
  }
536
536
 
537
537
  /**
538
- * 3-way merge
538
+ * 3-way 병합
539
539
  *
540
- * Merge by comparing three objects: source, origin, and target.
541
- * - If source and origin are equal and target differsuse target value
542
- * - If target and origin are equal and source differsuse source value
543
- * - If source and target are equal use that value
544
- * - If all three values differ conflict occurs (maintain origin value)
540
+ * source, origin, target 세 객체를 비교하여 병합.
541
+ * - source origin 같고 target 다르면 → target 값 사용
542
+ * - target origin 같고 source 다르면 → source 값 사용
543
+ * - source target 같으면해당 사용
544
+ * - 값이 모두 다르면충돌 발생 (origin 값 유지)
545
545
  *
546
- * @param source Changed version 1
547
- * @param origin Base version (common ancestor)
548
- * @param target Changed version 2
549
- * @param optionsObj Comparison options per key. Specify equal() comparison options individually for each key
550
- * - `keys`: List of sub-keys to compare (same as equal's topLevelIncludes)
551
- * - `excludes`: List of sub-keys to exclude from comparison
552
- * - `ignoreArrayIndex`: Whether to ignore array order
553
- * @returns conflict: Whether conflict occurred, result: Merge result
546
+ * @param source 변경된 버전 1
547
+ * @param origin 기본 버전 (공통 조상)
548
+ * @param target 변경된 버전 2
549
+ * @param optionsObj key별 비교 옵션. key 대해 equal() 비교 옵션을 개별 지정
550
+ * - `keys`: 비교할 하위 key 목록 (equal topLevelIncludes와 동일)
551
+ * - `excludes`: 비교에서 제외할 하위 key 목록
552
+ * - `ignoreArrayIndex`: array 순서를 무시할지 여부
553
+ * @returns conflict: 충돌 발생 여부, result: 병합 결과
554
554
  *
555
555
  * @example
556
556
  * const { conflict, result } = merge3(
@@ -599,10 +599,10 @@ export function merge3<
599
599
  //#region omit / pick
600
600
 
601
601
  /**
602
- * Exclude specific keys from object
603
- * @param item Source object
604
- * @param omitKeys Array of keys to exclude
605
- * @returns New object with specified keys excluded
602
+ * 객체에서 특정 key 제외
603
+ * @param item 원본 객체
604
+ * @param omitKeys 제외할 key 배열
605
+ * @returns 지정된 key가 제외된 객체
606
606
  * @example
607
607
  * const user = { name: "Alice", age: 30, email: "alice@example.com" };
608
608
  * omit(user, ["email"]);
@@ -622,11 +622,11 @@ export function omit<T extends Record<string, unknown>, K extends keyof T>(
622
622
  }
623
623
 
624
624
  /**
625
- * Exclude keys matching condition
625
+ * 조건에 맞는 key 제외
626
626
  * @internal
627
- * @param item Source object
628
- * @param omitKeyFn Function that receives key and returns whether to exclude (true to exclude)
629
- * @returns New object with keys matching condition excluded
627
+ * @param item 원본 객체
628
+ * @param omitKeyFn key 받아 제외 여부를 반환하는 함수 (true 제외)
629
+ * @returns 조건에 맞는 key가 제외된 객체
630
630
  * @example
631
631
  * const data = { name: "Alice", _internal: "secret", age: 30 };
632
632
  * omitByFilter(data, (key) => key.startsWith("_"));
@@ -646,10 +646,10 @@ export function omitByFilter<T extends Record<string, unknown>>(
646
646
  }
647
647
 
648
648
  /**
649
- * Select specific keys from object
650
- * @param item Source object
651
- * @param keys Array of keys to select
652
- * @returns New object containing only specified keys
649
+ * 객체에서 특정 key만 선택
650
+ * @param item 원본 객체
651
+ * @param keys 선택할 key 배열
652
+ * @returns 지정된 key만 포함된 객체
653
653
  * @example
654
654
  * const user = { name: "Alice", age: 30, email: "alice@example.com" };
655
655
  * pick(user, ["name", "age"]);
@@ -670,7 +670,7 @@ export function pick<T extends Record<string, unknown>, K extends keyof T>(
670
670
 
671
671
  //#region getChainValue / setChainValue / deleteChainValue
672
672
 
673
- // Regex caching (created once at module load)
673
+ // 정규식 캐싱 (모듈 로드 번만 생성)
674
674
  const chainSplitRegex = /[.[\]]/g;
675
675
  const chainCleanRegex = /[?!'"]/g;
676
676
  const chainNumericRegex = /^[0-9]*$/;
@@ -693,7 +693,7 @@ function getChainSplits(chain: string): (string | number)[] {
693
693
  }
694
694
 
695
695
  /**
696
- * Get value by chain path
696
+ * 체인 경로로 조회
697
697
  * @example getChainValue(obj, "a.b[0].c")
698
698
  */
699
699
  export function getChainValue(obj: unknown, chain: string, optional: true): unknown | undefined;
@@ -716,13 +716,13 @@ export function getChainValue(
716
716
  }
717
717
 
718
718
  /**
719
- * Descend by the same key for depth levels
719
+ * 같은 key 지정된 깊이만큼 하강
720
720
  * @internal
721
- * @param obj Target object
722
- * @param key Key to descend by
723
- * @param depth Depth to descend (1 or more)
724
- * @param optional If true, return undefined without error if null/undefined found in the middle
725
- * @throws ArgumentError If depth is less than 1
721
+ * @param obj 대상 객체
722
+ * @param key 하강에 사용할 key
723
+ * @param depth 하강 깊이 (1 이상)
724
+ * @param optional true이면 중간에 null/undefined 만나도 에러 없이 undefined 반환
725
+ * @throws ArgumentError depth 1 미만인 경우
726
726
  * @example getChainValueByDepth({ parent: { parent: { name: 'a' } } }, 'parent', 2) => { name: 'a' }
727
727
  */
728
728
  export function getChainValueByDepth<TObject, TKey extends keyof TObject>(
@@ -743,7 +743,7 @@ export function getChainValueByDepth<TObject, TKey extends keyof TObject>(
743
743
  optional?: true,
744
744
  ): TObject[TKey] | undefined {
745
745
  if (depth < 1) {
746
- throw new ArgumentError("depth must be 1 or greater", { depth });
746
+ throw new ArgumentError("depth 1 이상이어야 합니다", { depth });
747
747
  }
748
748
  let result: unknown = obj;
749
749
  for (let i = 0; i < depth; i++) {
@@ -757,13 +757,13 @@ export function getChainValueByDepth<TObject, TKey extends keyof TObject>(
757
757
  }
758
758
 
759
759
  /**
760
- * Set value by chain path
760
+ * 체인 경로로 설정
761
761
  * @example setChainValue(obj, "a.b[0].c", value)
762
762
  */
763
763
  export function setChainValue(obj: unknown, chain: string, value: unknown): void {
764
764
  const splits = getChainSplits(chain);
765
765
  if (splits.length === 0) {
766
- throw new ArgumentError("Chain is empty", { chain });
766
+ throw new ArgumentError("chain이 비어있습니다", { chain });
767
767
  }
768
768
 
769
769
  let curr: Record<string | number, unknown> = obj as Record<string | number, unknown>;
@@ -777,19 +777,19 @@ export function setChainValue(obj: unknown, chain: string, value: unknown): void
777
777
  }
778
778
 
779
779
  /**
780
- * Delete value by chain path
780
+ * 체인 경로로 삭제
781
781
  * @example deleteChainValue(obj, "a.b[0].c")
782
782
  */
783
783
  export function deleteChainValue(obj: unknown, chain: string): void {
784
784
  const splits = getChainSplits(chain);
785
785
  if (splits.length === 0) {
786
- throw new ArgumentError("Chain is empty", { chain });
786
+ throw new ArgumentError("chain이 비어있습니다", { chain });
787
787
  }
788
788
 
789
789
  let curr: Record<string | number, unknown> = obj as Record<string | number, unknown>;
790
790
  for (const splitItem of splits.slice(0, -1)) {
791
791
  const next = curr[splitItem];
792
- // Silently return if middle path doesn't exist (nothing to delete)
792
+ // 중간 경로가 존재하지 않으면 조용히 반환 (삭제할 것이 없음)
793
793
  if (next == null || typeof next !== "object") {
794
794
  return;
795
795
  }
@@ -805,10 +805,10 @@ export function deleteChainValue(obj: unknown, chain: string): void {
805
805
  //#region clearUndefined / clear / nullToUndefined / unflatten
806
806
 
807
807
  /**
808
- * Delete keys with undefined values from object
808
+ * 객체에서 undefined 값을 가진 key 삭제
809
809
  * @internal
810
810
  *
811
- * @mutates Modifies the original object directly
811
+ * @mutates 원본 객체를 직접 수정
812
812
  */
813
813
  export function clearUndefined<T extends object>(obj: T): T {
814
814
  const record = obj as Record<string, unknown>;
@@ -821,10 +821,10 @@ export function clearUndefined<T extends object>(obj: T): T {
821
821
  }
822
822
 
823
823
  /**
824
- * Delete all keys from object
824
+ * 객체의 모든 key 삭제
825
825
  * @internal
826
826
  *
827
- * @mutates Modifies the original object directly
827
+ * @mutates 원본 객체를 직접 수정
828
828
  */
829
829
  export function clear<T extends Record<string, unknown>>(obj: T): Record<string, never> {
830
830
  for (const key of Object.keys(obj)) {
@@ -834,10 +834,10 @@ export function clear<T extends Record<string, unknown>>(obj: T): Record<string,
834
834
  }
835
835
 
836
836
  /**
837
- * Convert null to undefined (recursive)
837
+ * null undefined 변환 (재귀)
838
838
  * @internal
839
839
  *
840
- * @mutates Modifies the original array/object directly
840
+ * @mutates 원본 array/객체를 직접 수정
841
841
  */
842
842
  export function nullToUndefined<TObject>(obj: TObject): TObject | undefined {
843
843
  return nullToUndefinedImpl(obj, new WeakSet());
@@ -882,7 +882,7 @@ function nullToUndefinedImpl<TObject>(obj: TObject, seen: WeakSet<object>): TObj
882
882
  }
883
883
 
884
884
  /**
885
- * Convert flattened object to nested object
885
+ * 평탄화된 객체를 중첩 객체로 변환
886
886
  * @internal
887
887
  * @example unflatten({ "a.b.c": 1 }) => { a: { b: { c: 1 } } }
888
888
  */
@@ -912,10 +912,10 @@ export function unflatten(flatObj: Record<string, unknown>): Record<string, unkn
912
912
 
913
913
  //#endregion
914
914
 
915
- //#region Type utilities
915
+ //#region 타입 유틸리티
916
916
 
917
917
  /**
918
- * Convert properties with undefined to optional
918
+ * undefined를 가진 속성을 optional로 변환
919
919
  * @example { a: string; b: string | undefined } → { a: string; b?: string | undefined }
920
920
  */
921
921
  export type UndefToOptional<TObject> = {
@@ -923,7 +923,7 @@ export type UndefToOptional<TObject> = {
923
923
  } & { [K in keyof TObject as undefined extends TObject[K] ? never : K]: TObject[K] };
924
924
 
925
925
  /**
926
- * Convert optional properties to required + undefined union
926
+ * optional 속성을 필수 + undefined 유니온으로 변환
927
927
  * @example { a: string; b?: string } → { a: string; b: string | undefined }
928
928
  */
929
929
  export type OptionalToUndef<TObject> = {
@@ -933,27 +933,27 @@ export type OptionalToUndef<TObject> = {
933
933
  //#endregion
934
934
 
935
935
  /**
936
- * Type-safe version of Object.keys
937
- * @param obj Object to extract keys from
938
- * @returns Array of object keys
936
+ * 타입 안전한 Object.keys
937
+ * @param obj key를 추출할 객체
938
+ * @returns 객체 key 배열
939
939
  */
940
940
  export function keys<T extends object>(obj: T): (keyof T)[] {
941
941
  return Object.keys(obj) as (keyof T)[];
942
942
  }
943
943
 
944
944
  /**
945
- * Type-safe version of Object.entries
946
- * @param obj Object to extract entries from
947
- * @returns Array of [key, value] tuples
945
+ * 타입 안전한 Object.entries
946
+ * @param obj 엔트리를 추출할 객체
947
+ * @returns [key, value] 튜플 배열
948
948
  */
949
949
  export function entries<T extends object>(obj: T): Entries<T> {
950
950
  return Object.entries(obj) as Entries<T>;
951
951
  }
952
952
 
953
953
  /**
954
- * Type-safe version of Object.fromEntries
955
- * @param entries Array of [key, value] tuples
956
- * @returns Created object
954
+ * 타입 안전한 Object.fromEntries
955
+ * @param entries [key, value] 튜플 배열
956
+ * @returns 생성된 객체
957
957
  */
958
958
  export function fromEntries<T extends [string, unknown]>(entryPairs: T[]): { [K in T[0]]: T[1] } {
959
959
  return Object.fromEntries(entryPairs) as { [K in T[0]]: T[1] };
@@ -962,18 +962,18 @@ export function fromEntries<T extends [string, unknown]>(entryPairs: T[]): { [K
962
962
  type Entries<TObject> = { [K in keyof TObject]: [K, TObject[K]] }[keyof TObject][];
963
963
 
964
964
  /**
965
- * Transform each entry of object and return new object
966
- * @param obj Object to transform
967
- * @param fn Transform function (key, value) => [newKey, newValue]
968
- * @returns New object with transformed keys and values
965
+ * 객체의 엔트리를 변환하여 객체 반환
966
+ * @param obj 변환할 객체
967
+ * @param fn 변환 함수 (key, value) => [newKey, newValue]
968
+ * @returns key와 value가 변환된 객체
969
969
  * @example
970
970
  * const colors = { primary: "255, 0, 0", secondary: "0, 255, 0" };
971
971
  *
972
- * // Transform only values
972
+ * // 값만 변환
973
973
  * map(colors, (key, rgb) => [null, `rgb(${rgb})`]);
974
974
  * // { primary: "rgb(255, 0, 0)", secondary: "rgb(0, 255, 0)" }
975
975
  *
976
- * // Transform both keys and values
976
+ * // key와 모두 변환
977
977
  * map(colors, (key, rgb) => [`${key}Light`, `rgb(${rgb})`]);
978
978
  * // { primaryLight: "rgb(255, 0, 0)", secondaryLight: "rgb(0, 255, 0)" }
979
979
  */
package/src/utils/path.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  /**
2
- * Path utility functions
3
- * Replacement for Node.js path module (supports browser environments)
2
+ * 경로 유틸리티 함수
3
+ * Node.js path 모듈 대체 (브라우저 환경 지원)
4
4
  *
5
- * @note This utility supports POSIX style paths (slash `/`) only.
6
- * Windows backslash (`\`) paths are not supported.
7
- * Designed for browser environments and Capacitor plugins.
5
+ * @note 유틸리티는 POSIX 스타일 경로(슬래시 `/`) 지원.
6
+ * Windows 백슬래시(`\`) 경로는 지원하지 않음.
7
+ * 브라우저 환경 Capacitor 플러그인용으로 설계됨.
8
8
  */
9
9
 
10
10
  /**
11
- * Combine paths (path.join replacement)
12
- * @note Supports POSIX style paths only (slash `/`)
11
+ * 경로 결합 (path.join 대체)
12
+ * @note POSIX 스타일 경로(슬래시 `/`)만 지원
13
13
  */
14
14
  export function join(...segments: string[]): string {
15
15
  return segments
@@ -19,7 +19,7 @@ export function join(...segments: string[]): string {
19
19
  }
20
20
 
21
21
  /**
22
- * Extract filename (path.basename replacement)
22
+ * 파일명 추출 (path.basename 대체)
23
23
  */
24
24
  export function basename(filePath: string, ext?: string): string {
25
25
  const name = filePath.split("/").pop() ?? "";
@@ -30,8 +30,8 @@ export function basename(filePath: string, ext?: string): string {
30
30
  }
31
31
 
32
32
  /**
33
- * Extract file extension (path.extname replacement)
34
- * @note Hidden files (e.g., `.gitignore`) return empty string (same as Node.js path.extname)
33
+ * 파일 확장자 추출 (path.extname 대체)
34
+ * @note 숨김 파일(예: `.gitignore`) 문자열 반환 (Node.js path.extname과 동일)
35
35
  */
36
36
  export function extname(filePath: string): string {
37
37
  const name = filePath.split("/").pop() ?? "";