@simplysm/core-common 13.0.69 → 13.0.71

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 (151) hide show
  1. package/README.md +66 -267
  2. package/dist/common.types.d.ts +14 -14
  3. package/dist/errors/argument-error.d.ts +10 -10
  4. package/dist/errors/argument-error.d.ts.map +1 -1
  5. package/dist/errors/argument-error.js +2 -2
  6. package/dist/errors/argument-error.js.map +1 -1
  7. package/dist/errors/not-implemented-error.d.ts +8 -8
  8. package/dist/errors/not-implemented-error.js +2 -2
  9. package/dist/errors/not-implemented-error.js.map +1 -1
  10. package/dist/errors/sd-error.d.ts +10 -10
  11. package/dist/errors/sd-error.d.ts.map +1 -1
  12. package/dist/errors/timeout-error.d.ts +10 -10
  13. package/dist/errors/timeout-error.js +3 -3
  14. package/dist/errors/timeout-error.js.map +1 -1
  15. package/dist/extensions/arr-ext.d.ts +2 -2
  16. package/dist/extensions/arr-ext.helpers.d.ts +8 -8
  17. package/dist/extensions/arr-ext.helpers.js +1 -1
  18. package/dist/extensions/arr-ext.helpers.js.map +1 -1
  19. package/dist/extensions/arr-ext.js +13 -13
  20. package/dist/extensions/arr-ext.js.map +1 -1
  21. package/dist/extensions/arr-ext.types.d.ts +57 -57
  22. package/dist/extensions/arr-ext.types.d.ts.map +1 -1
  23. package/dist/extensions/map-ext.d.ts +16 -16
  24. package/dist/extensions/set-ext.d.ts +11 -11
  25. package/dist/features/debounce-queue.d.ts +17 -15
  26. package/dist/features/debounce-queue.d.ts.map +1 -1
  27. package/dist/features/debounce-queue.js +6 -6
  28. package/dist/features/debounce-queue.js.map +1 -1
  29. package/dist/features/event-emitter.d.ts +20 -20
  30. package/dist/features/event-emitter.js +17 -17
  31. package/dist/features/serial-queue.d.ts +11 -11
  32. package/dist/features/serial-queue.js +5 -5
  33. package/dist/features/serial-queue.js.map +1 -1
  34. package/dist/globals.d.ts +4 -4
  35. package/dist/types/date-only.d.ts +64 -64
  36. package/dist/types/date-only.d.ts.map +1 -1
  37. package/dist/types/date-only.js +63 -63
  38. package/dist/types/date-time.d.ts +37 -37
  39. package/dist/types/date-time.d.ts.map +1 -1
  40. package/dist/types/date-time.js +54 -37
  41. package/dist/types/date-time.js.map +1 -1
  42. package/dist/types/lazy-gc-map.d.ts +26 -26
  43. package/dist/types/lazy-gc-map.d.ts.map +1 -1
  44. package/dist/types/lazy-gc-map.js +26 -26
  45. package/dist/types/lazy-gc-map.js.map +1 -1
  46. package/dist/types/time.d.ts +25 -25
  47. package/dist/types/time.d.ts.map +1 -1
  48. package/dist/types/time.js +25 -25
  49. package/dist/types/time.js.map +1 -1
  50. package/dist/types/uuid.d.ts +11 -11
  51. package/dist/types/uuid.d.ts.map +1 -1
  52. package/dist/types/uuid.js +12 -12
  53. package/dist/types/uuid.js.map +1 -1
  54. package/dist/utils/bytes.d.ts +17 -17
  55. package/dist/utils/bytes.js +4 -4
  56. package/dist/utils/bytes.js.map +1 -1
  57. package/dist/utils/date-format.d.ts +45 -45
  58. package/dist/utils/date-format.js +1 -1
  59. package/dist/utils/date-format.js.map +1 -1
  60. package/dist/utils/error.d.ts +4 -4
  61. package/dist/utils/json.d.ts +17 -17
  62. package/dist/utils/json.js +3 -3
  63. package/dist/utils/json.js.map +1 -1
  64. package/dist/utils/num.d.ts +23 -23
  65. package/dist/utils/obj.d.ts +111 -111
  66. package/dist/utils/obj.d.ts.map +1 -1
  67. package/dist/utils/obj.js +3 -3
  68. package/dist/utils/obj.js.map +1 -1
  69. package/dist/utils/path.d.ts +10 -10
  70. package/dist/utils/primitive.d.ts +5 -5
  71. package/dist/utils/primitive.js +1 -1
  72. package/dist/utils/primitive.js.map +1 -1
  73. package/dist/utils/str.d.ts +46 -46
  74. package/dist/utils/str.d.ts.map +1 -1
  75. package/dist/utils/str.js +5 -5
  76. package/dist/utils/str.js.map +1 -1
  77. package/dist/utils/template-strings.d.ts +26 -26
  78. package/dist/utils/transferable.d.ts +18 -18
  79. package/dist/utils/transferable.js +1 -1
  80. package/dist/utils/transferable.js.map +1 -1
  81. package/dist/utils/wait.d.ts +9 -9
  82. package/dist/utils/xml.d.ts +13 -13
  83. package/dist/utils/xml.d.ts.map +1 -1
  84. package/dist/utils/xml.js +1 -0
  85. package/dist/utils/xml.js.map +1 -1
  86. package/dist/zip/sd-zip.d.ts +22 -22
  87. package/dist/zip/sd-zip.js +16 -16
  88. package/package.json +4 -4
  89. package/src/common.types.ts +17 -17
  90. package/src/errors/argument-error.ts +15 -15
  91. package/src/errors/not-implemented-error.ts +9 -9
  92. package/src/errors/sd-error.ts +12 -12
  93. package/src/errors/timeout-error.ts +12 -12
  94. package/src/extensions/arr-ext.helpers.ts +10 -10
  95. package/src/extensions/arr-ext.ts +57 -57
  96. package/src/extensions/arr-ext.types.ts +59 -59
  97. package/src/extensions/map-ext.ts +16 -16
  98. package/src/extensions/set-ext.ts +11 -11
  99. package/src/features/debounce-queue.ts +21 -19
  100. package/src/features/event-emitter.ts +25 -25
  101. package/src/features/serial-queue.ts +13 -13
  102. package/src/globals.ts +4 -4
  103. package/src/index.ts +1 -1
  104. package/src/types/date-only.ts +83 -83
  105. package/src/types/date-time.ts +64 -44
  106. package/src/types/lazy-gc-map.ts +45 -45
  107. package/src/types/time.ts +34 -34
  108. package/src/types/uuid.ts +17 -17
  109. package/src/utils/bytes.ts +35 -35
  110. package/src/utils/date-format.ts +65 -65
  111. package/src/utils/error.ts +4 -4
  112. package/src/utils/json.ts +39 -39
  113. package/src/utils/num.ts +23 -23
  114. package/src/utils/obj.ts +138 -138
  115. package/src/utils/path.ts +10 -10
  116. package/src/utils/primitive.ts +6 -6
  117. package/src/utils/str.ts +260 -261
  118. package/src/utils/template-strings.ts +29 -29
  119. package/src/utils/transferable.ts +284 -284
  120. package/src/utils/wait.ts +10 -10
  121. package/src/utils/xml.ts +20 -19
  122. package/src/zip/sd-zip.ts +25 -25
  123. package/tests/errors/errors.spec.ts +80 -0
  124. package/tests/extensions/array-extension.spec.ts +796 -0
  125. package/tests/extensions/map-extension.spec.ts +147 -0
  126. package/tests/extensions/set-extension.spec.ts +74 -0
  127. package/tests/types/date-only.spec.ts +638 -0
  128. package/tests/types/date-time.spec.ts +391 -0
  129. package/tests/types/lazy-gc-map.spec.ts +692 -0
  130. package/tests/types/time.spec.ts +559 -0
  131. package/tests/types/uuid.spec.ts +74 -0
  132. package/tests/utils/bytes-utils.spec.ts +230 -0
  133. package/tests/utils/date-format.spec.ts +373 -0
  134. package/tests/utils/debounce-queue.spec.ts +272 -0
  135. package/tests/utils/json.spec.ts +486 -0
  136. package/tests/utils/number.spec.ts +157 -0
  137. package/tests/utils/object.spec.ts +829 -0
  138. package/tests/utils/path.spec.ts +78 -0
  139. package/tests/utils/primitive.spec.ts +43 -0
  140. package/tests/utils/sd-event-emitter.spec.ts +216 -0
  141. package/tests/utils/serial-queue.spec.ts +365 -0
  142. package/tests/utils/string.spec.ts +281 -0
  143. package/tests/utils/template-strings.spec.ts +57 -0
  144. package/tests/utils/transferable.spec.ts +703 -0
  145. package/tests/utils/wait.spec.ts +145 -0
  146. package/tests/utils/xml.spec.ts +146 -0
  147. package/tests/zip/sd-zip.spec.ts +238 -0
  148. package/docs/extensions.md +0 -503
  149. package/docs/features.md +0 -109
  150. package/docs/types.md +0 -486
  151. package/docs/utils.md +0 -780
@@ -1,20 +1,20 @@
1
1
  import consola from "consola";
2
2
 
3
3
  /**
4
- * 자동 만료 기능이 있는 Map
5
- * LRU 방식으로 접근 시간 갱신, 일정 시간 미접근 자동 삭제
4
+ * Map with automatic expiration feature
5
+ * Updates access time in LRU manner, auto-deletes if not accessed for specified time
6
6
  *
7
- * @note 인스턴스 사용 후 반드시 dispose() 호출하거나 using 문을 사용해야 함.
8
- * 그렇지 않으면 GC 타이머가 계속 동작하여 메모리 누수 발생.
7
+ * @note Must call dispose() or use 'using' statement after use.
8
+ * Otherwise GC timer continues running and causes memory leak.
9
9
  *
10
10
  * @example
11
- * // using 사용 (권장)
11
+ * // using statement (recommended)
12
12
  * using map = new LazyGcMap({ gcInterval: 10000, expireTime: 60000 });
13
13
  *
14
- * // 또는 명시적 dispose() 호출
14
+ * // Or explicit dispose() call
15
15
  * const map = new LazyGcMap({ gcInterval: 10000, expireTime: 60000 });
16
16
  * try {
17
- * // ... 사용
17
+ * // ... usage
18
18
  * } finally {
19
19
  * map.dispose();
20
20
  * }
@@ -22,21 +22,21 @@ import consola from "consola";
22
22
  export class LazyGcMap<TKey, TValue> {
23
23
  private static readonly _logger = consola.withTag("LazyGcMap");
24
24
 
25
- // 실제 데이터와 마지막 접근 시간을 함께 저장
25
+ // Store actual data and last access time together
26
26
  private readonly _map = new Map<TKey, { value: TValue; lastAccess: number }>();
27
27
 
28
- // GC 타이머
28
+ // GC timer
29
29
  private _gcTimer?: ReturnType<typeof setInterval>;
30
- // GC 실행 플래그 (중복 실행 방지)
30
+ // Flag to prevent duplicate GC runs
31
31
  private _isGcRunning = false;
32
- // destroy 호출 여부
32
+ // Whether dispose() has been called
33
33
  private _isDestroyed = false;
34
34
 
35
35
  /**
36
- * @param _options 설정 옵션
37
- * @param _options.gcInterval GC 주기 (밀리초). 기본값: expireTime의 1/10 (최소 1000ms)
38
- * @param _options.expireTime 만료 시간 (밀리초). 마지막 접근 시간이 지나면 삭제됨. 예: 60000 (60)
39
- * @param _options.onExpire 만료 호출되는 콜백. 비동기 함수도 가능하며, 에러 발생 로깅 계속 진행됨
36
+ * @param _options Configuration options
37
+ * @param _options.gcInterval GC interval in milliseconds. Default: 1/10 of expireTime (minimum 1000ms)
38
+ * @param _options.expireTime Expiration time in milliseconds. Deleted after this time since last access. Example: 60000 (60 seconds)
39
+ * @param _options.onExpire Callback called on expiration. Can be async function, errors are logged and continue execution
40
40
  */
41
41
  constructor(
42
42
  private readonly _options: {
@@ -46,48 +46,48 @@ export class LazyGcMap<TKey, TValue> {
46
46
  },
47
47
  ) {}
48
48
 
49
- /** 저장된 항목 */
49
+ /** Number of stored items */
50
50
  get size(): number {
51
51
  return this._map.size;
52
52
  }
53
53
 
54
- /** 존재 여부 확인 (접근 시간 갱신 안함) */
54
+ /** Check if key exists (does not update access time) */
55
55
  has(key: TKey): boolean {
56
56
  if (this._isDestroyed) return false;
57
57
  return this._map.has(key);
58
58
  }
59
59
 
60
- /** 조회 (접근 시간 갱신됨) */
60
+ /** Get value (updates access time) */
61
61
  get(key: TKey): TValue | undefined {
62
62
  if (this._isDestroyed) return undefined;
63
63
  const item = this._map.get(key);
64
64
  if (item == null) return undefined;
65
65
 
66
- // 접근 시간 갱신 (LRU)
66
+ // Update access time on retrieval (LRU)
67
67
  item.lastAccess = Date.now();
68
68
  return item.value;
69
69
  }
70
70
 
71
- /** 저장 (접근 시간 설정 GC 타이머 시작) */
71
+ /** Store value (sets access time and starts GC timer) */
72
72
  set(key: TKey, value: TValue): void {
73
73
  if (this._isDestroyed) return;
74
74
  this._map.set(key, { value, lastAccess: Date.now() });
75
- // 데이터가 들어왔으므로 GC 타이머 가동
75
+ // Start GC timer when data is added
76
76
  this._startGc();
77
77
  }
78
78
 
79
- /** 항목 삭제 (비었으면 GC 타이머 중지) */
79
+ /** Delete item (stops GC timer if empty) */
80
80
  delete(key: TKey): boolean {
81
81
  if (this._isDestroyed) return false;
82
82
  const result = this._map.delete(key);
83
- // 비었으면 타이머 중지
83
+ // Stop timer if empty
84
84
  if (this._map.size === 0) {
85
85
  this._stopGc();
86
86
  }
87
87
  return result;
88
88
  }
89
89
 
90
- /** 인스턴스 정리 (GC 타이머 중지 데이터 삭제) */
90
+ /** Clean up instance (stop GC timer and delete data) */
91
91
  dispose(): void {
92
92
  if (this._isDestroyed) return;
93
93
  this._isDestroyed = true;
@@ -95,13 +95,13 @@ export class LazyGcMap<TKey, TValue> {
95
95
  this._stopGc();
96
96
  }
97
97
 
98
- /** using 지원 */
98
+ /** Support for 'using' statement */
99
99
  [Symbol.dispose](): void {
100
100
  this.dispose();
101
101
  }
102
102
 
103
103
  /**
104
- * 모든 항목 삭제 (인스턴스는 계속 사용 가능)
104
+ * Delete all items (instance can still be used)
105
105
  */
106
106
  clear(): void {
107
107
  if (this._isDestroyed) return;
@@ -110,14 +110,14 @@ export class LazyGcMap<TKey, TValue> {
110
110
  }
111
111
 
112
112
  /**
113
- * 키에 해당하는 값을 반환하고, 없으면 factory 생성 저장하여 반환
114
- * @param key 조회할
115
- * @param factory 키가 없을 값을 생성하는 함수
116
- * @returns 기존 또는 새로 생성된 값
113
+ * Return value for key, or create and store via factory if not found
114
+ * @param key Key to look up
115
+ * @param factory Function to create value if key not found
116
+ * @returns Existing or newly created value
117
117
  */
118
118
  getOrCreate(key: TKey, factory: () => TValue): TValue {
119
119
  if (this._isDestroyed) {
120
- throw new Error("LazyGcMap 이미 dispose되었습니다.");
120
+ throw new Error("LazyGcMap has already been disposed.");
121
121
  }
122
122
  const item = this._map.get(key);
123
123
  if (item == null) {
@@ -130,7 +130,7 @@ export class LazyGcMap<TKey, TValue> {
130
130
  return item.value;
131
131
  }
132
132
 
133
- /** 값들만 순회 (Iterator) */
133
+ /** Iterate over values only (Iterator) */
134
134
  *values(): IterableIterator<TValue> {
135
135
  if (this._isDestroyed) return;
136
136
  for (const item of this._map.values()) {
@@ -138,13 +138,13 @@ export class LazyGcMap<TKey, TValue> {
138
138
  }
139
139
  }
140
140
 
141
- /** 키들만 순회 (Iterator) */
141
+ /** Iterate over keys only (Iterator) */
142
142
  *keys(): IterableIterator<TKey> {
143
143
  if (this._isDestroyed) return;
144
144
  yield* this._map.keys();
145
145
  }
146
146
 
147
- /** 엔트리 순회 (Iterator) */
147
+ /** Iterate over entries (Iterator) */
148
148
  *entries(): IterableIterator<[TKey, TValue]> {
149
149
  if (this._isDestroyed) return;
150
150
  for (const [key, item] of this._map.entries()) {
@@ -152,7 +152,7 @@ export class LazyGcMap<TKey, TValue> {
152
152
  }
153
153
  }
154
154
 
155
- //#region GC 로직
155
+ //#region GC logic
156
156
 
157
157
  private _startGc(): void {
158
158
  if (this._isDestroyed) return;
@@ -165,14 +165,14 @@ export class LazyGcMap<TKey, TValue> {
165
165
  }
166
166
 
167
167
  private async _runGc(): Promise<void> {
168
- // 이미 실행 중이면 스킵 (onExpire 콜백이 오래 걸리는 경우 중복 실행 방지)
168
+ // Skip if already running (prevent duplicate runs when onExpire callback takes time)
169
169
  if (this._isGcRunning) return;
170
170
  this._isGcRunning = true;
171
171
 
172
172
  try {
173
173
  const now = Date.now();
174
174
 
175
- // 1. 만료된 항목 수집 (삭제 )
175
+ // 1. Collect expired items (before deletion)
176
176
  const expiredEntries: { key: TKey; item: { value: TValue; lastAccess: number } }[] = [];
177
177
  for (const [key, item] of this._map) {
178
178
  if (now - item.lastAccess > this._options.expireTime) {
@@ -180,33 +180,33 @@ export class LazyGcMap<TKey, TValue> {
180
180
  }
181
181
  }
182
182
 
183
- // 2. 항목에 대해 콜백 실행 후 삭제
183
+ // 2. Run callback then delete each item
184
184
  for (const { key, item } of expiredEntries) {
185
- // 콜백 실행 현재 상태 확인 (이미 다른 값으로 교체되었거나 삭제되었으면 스킵)
185
+ // Check current state before callback (skip if already replaced or deleted)
186
186
  const currentItem = this._map.get(key);
187
187
  if (currentItem !== item) {
188
188
  continue;
189
189
  }
190
190
 
191
- // 만료 콜백 실행
191
+ // Run expiration callback
192
192
  if (this._options.onExpire != null) {
193
193
  try {
194
194
  await this._options.onExpire(key, item.value);
195
195
  } catch (err) {
196
- LazyGcMap._logger.error("onExpire 콜백 에러", err);
196
+ LazyGcMap._logger.error("onExpire callback error", err);
197
197
  }
198
198
  }
199
199
 
200
- // 콜백 재등록 여부 확인
201
- // 시나리오: onExpire 콜백에서 동일 키로 새 값을 set() 경우,
202
- // 새로 등록된 항목을 삭제하면 됨. item 참조가 같으면 재등록되지 않은 것이므로 삭제 진행.
200
+ // Check if item was re-registered after callback
201
+ // Scenario: onExpire callback calls set() with same key,
202
+ // we should not delete newly registered item. If item reference is same, not re-registered, so delete.
203
203
  const afterItem = this._map.get(key);
204
204
  if (afterItem === item) {
205
205
  this._map.delete(key);
206
206
  }
207
207
  }
208
208
 
209
- // GC 비었으면 끄기
209
+ // Stop GC if empty after cleanup
210
210
  if (this._map.size === 0) {
211
211
  this._stopGc();
212
212
  }
package/src/types/time.ts CHANGED
@@ -2,10 +2,10 @@ import { ArgumentError } from "../errors/argument-error";
2
2
  import { convert12To24, formatDate } from "../utils/date-format";
3
3
 
4
4
  /**
5
- * 시간 클래스 (날짜제외: HH:mm:ss.fff, 불변)
5
+ * Time class (without date: HH:mm:ss.fff, immutable)
6
6
  *
7
- * 날짜 정보 없이 시간만 저장하는 불변 클래스이다.
8
- * 24시간을 초과하거나 음수인 경우 자동으로 정규화된다.
7
+ * An immutable class that stores only time without date information.
8
+ * Values exceeding 24 hours or negative values are automatically normalized.
9
9
  *
10
10
  * @example
11
11
  * const now = new Time();
@@ -17,13 +17,13 @@ export class Time {
17
17
 
18
18
  private readonly _tick: number;
19
19
 
20
- /** 현재 시간으로 생성 */
20
+ /** Create with current time */
21
21
  constructor();
22
- /** 시분초밀리초로 생성 */
22
+ /** Create with hour, minute, second, millisecond */
23
23
  constructor(hour: number, minute: number, second?: number, millisecond?: number);
24
- /** tick (밀리초)으로 생성 */
24
+ /** Create from tick (millisecond) */
25
25
  constructor(tick: number);
26
- /** Date 객체에서 시간 부분만 추출하여 생성 */
26
+ /** Create by extracting time part only from Date object */
27
27
  constructor(date: Date);
28
28
  constructor(arg1?: number | Date, arg2?: number, arg3?: number, arg4?: number) {
29
29
  if (arg1 === undefined) {
@@ -55,23 +55,23 @@ export class Time {
55
55
  }
56
56
 
57
57
  /**
58
- * 문자열을 파싱하여 Time 인스턴스를 생성
58
+ * Parse a string to create Time instance
59
59
  *
60
- * @param str 시간 문자열
61
- * @returns 파싱된 Time 인스턴스
62
- * @throws ArgumentError 지원하지 않는 형식인 경우
60
+ * @param str Time string
61
+ * @returns Parsed Time instance
62
+ * @throws ArgumentError If unsupported format
63
63
  *
64
64
  * @example
65
65
  * Time.parse("10:30:00") // HH:mm:ss
66
66
  * Time.parse("10:30:00.123") // HH:mm:ss.fff
67
- * Time.parse("오전 10:30:00") // 오전/오후 HH:mm:ss
68
- * Time.parse("2025-01-15T10:30:00") // ISO 8601 (시간 부분만 추출)
67
+ * Time.parse("AM 10:30:00") // AM/PM HH:mm:ss
68
+ * Time.parse("2025-01-15T10:30:00") // ISO 8601 (extract time part only)
69
69
  */
70
70
  static parse(str: string): Time {
71
- const match1 = /(오전|오후) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})(\.([0-9]{1,3}))?$/.exec(str);
71
+ const match1 = /(AM|PM) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})(\.([0-9]{1,3}))?$/i.exec(str);
72
72
  if (match1 != null) {
73
73
  const rawHour = Number(match1[2]);
74
- const isPM = match1[1] === "오후";
74
+ const isPM = match1[1].toUpperCase() === "PM";
75
75
  const hour = convert12To24(rawHour, isPM);
76
76
  return new Time(
77
77
  hour,
@@ -91,8 +91,8 @@ export class Time {
91
91
  );
92
92
  }
93
93
 
94
- // ISO 8601 형식 (예: 2025-01-15T10:30:00.123Z, 2025-01-15T10:30:00+09:00)
95
- // Date 객체를 사용하여 타임존 변환 처리
94
+ // ISO 8601 format (e.g., 2025-01-15T10:30:00.123Z, 2025-01-15T10:30:00+09:00)
95
+ // Use Date object to handle timezone conversion
96
96
  const isoMatch = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.exec(str);
97
97
  if (isoMatch != null) {
98
98
  const date = new Date(str);
@@ -107,12 +107,12 @@ export class Time {
107
107
  }
108
108
 
109
109
  throw new ArgumentError(
110
- `시간 형식을 파싱할 없습니다. 지원 형식: 'HH:mm:ss', 'HH:mm:ss.fff', '오전/오후 HH:mm:ss', ISO 8601`,
110
+ `Failed to parse time format. Supported formats: 'HH:mm:ss', 'HH:mm:ss.fff', 'AM/PM HH:mm:ss', ISO 8601`,
111
111
  { input: str },
112
112
  );
113
113
  }
114
114
 
115
- //#region Getters (읽기 전용)
115
+ //#region Getters (read-only)
116
116
 
117
117
  get hour(): number {
118
118
  return Math.floor(this._tick / (60 * 60 * 1000));
@@ -134,61 +134,61 @@ export class Time {
134
134
  return this._tick;
135
135
  }
136
136
 
137
- /** 시간 세팅이 제대로 되었는지 여부 */
137
+ /** Whether time is set correctly */
138
138
  get isValid(): boolean {
139
139
  return !Number.isNaN(this._tick);
140
140
  }
141
141
 
142
142
  //#endregion
143
143
 
144
- //#region 불변 변환 메서드 ( 인스턴스 반환)
144
+ //#region Immutable transformation methods (returns new instance)
145
145
 
146
- /** 지정된 시로 인스턴스 반환 */
146
+ /** Return new instance with specified hour */
147
147
  setHour(hour: number): Time {
148
148
  return new Time(hour, this.minute, this.second, this.millisecond);
149
149
  }
150
150
 
151
- /** 지정된 분으로 인스턴스 반환 */
151
+ /** Return new instance with specified minute */
152
152
  setMinute(minute: number): Time {
153
153
  return new Time(this.hour, minute, this.second, this.millisecond);
154
154
  }
155
155
 
156
- /** 지정된 초로 인스턴스 반환 */
156
+ /** Return new instance with specified second */
157
157
  setSecond(second: number): Time {
158
158
  return new Time(this.hour, this.minute, second, this.millisecond);
159
159
  }
160
160
 
161
- /** 지정된 밀리초로 인스턴스 반환 */
161
+ /** Return new instance with specified millisecond */
162
162
  setMillisecond(millisecond: number): Time {
163
163
  return new Time(this.hour, this.minute, this.second, millisecond);
164
164
  }
165
165
 
166
166
  //#endregion
167
167
 
168
- //#region 산술 메서드 ( 인스턴스 반환)
168
+ //#region Arithmetic methods (returns new instance)
169
169
 
170
- /** 지정된 시간을 더한 인스턴스 반환 (24시간 순환) */
170
+ /** Return new instance with specified hours added (24-hour wraparound) */
171
171
  addHours(hours: number): Time {
172
172
  let newTick = (this._tick + hours * 60 * 60 * 1000) % Time.MS_PER_DAY;
173
173
  if (newTick < 0) newTick += Time.MS_PER_DAY;
174
174
  return new Time(newTick);
175
175
  }
176
176
 
177
- /** 지정된 분을 더한 인스턴스 반환 (24시간 순환) */
177
+ /** Return new instance with specified minutes added (24-hour wraparound) */
178
178
  addMinutes(minutes: number): Time {
179
179
  let newTick = (this._tick + minutes * 60 * 1000) % Time.MS_PER_DAY;
180
180
  if (newTick < 0) newTick += Time.MS_PER_DAY;
181
181
  return new Time(newTick);
182
182
  }
183
183
 
184
- /** 지정된 초를 더한 인스턴스 반환 (24시간 순환) */
184
+ /** Return new instance with specified seconds added (24-hour wraparound) */
185
185
  addSeconds(seconds: number): Time {
186
186
  let newTick = (this._tick + seconds * 1000) % Time.MS_PER_DAY;
187
187
  if (newTick < 0) newTick += Time.MS_PER_DAY;
188
188
  return new Time(newTick);
189
189
  }
190
190
 
191
- /** 지정된 밀리초를 더한 인스턴스 반환 (24시간 순환) */
191
+ /** Return new instance with specified milliseconds added (24-hour wraparound) */
192
192
  addMilliseconds(milliseconds: number): Time {
193
193
  let newTick = (this._tick + milliseconds) % Time.MS_PER_DAY;
194
194
  if (newTick < 0) newTick += Time.MS_PER_DAY;
@@ -197,12 +197,12 @@ export class Time {
197
197
 
198
198
  //#endregion
199
199
 
200
- //#region 포맷팅
200
+ //#region Formatting
201
201
 
202
202
  /**
203
- * 지정된 포맷으로 문자열 변환
204
- * @param format 포맷 문자열
205
- * @see dtFormat 지원 포맷 문자열 참조
203
+ * Convert to string with specified format
204
+ * @param format Format string
205
+ * @see dtFormat for supported format strings
206
206
  */
207
207
  toFormatString(formatStr: string): string {
208
208
  return formatDate(formatStr, {
package/src/types/uuid.ts CHANGED
@@ -2,16 +2,16 @@ import type { Bytes } from "../common.types";
2
2
  import { ArgumentError } from "../errors/argument-error";
3
3
 
4
4
  /**
5
- * UUID v4 클래스
5
+ * UUID v4 class
6
6
  *
7
- * crypto.getRandomValues 기반으로 암호학적으로 안전한 UUID를 생성한다. (Chrome 79+, Node.js 공용)
7
+ * Generates cryptographically secure UUIDs based on crypto.getRandomValues. (Chrome 79+, Node.js compatible)
8
8
  *
9
9
  * @example
10
10
  * const id = Uuid.new();
11
11
  * const fromStr = new Uuid("550e8400-e29b-41d4-a716-446655440000");
12
12
  */
13
13
  export class Uuid {
14
- // 0x00 ~ 0xFF에 대한 hex 문자열 미리 계산 (256)
14
+ // Pre-calculate hex strings for 0x00 ~ 0xFF (256 entries)
15
15
  private static readonly _hexTable: string[] = Array.from({ length: 256 }, (_, i) =>
16
16
  i.toString(16).padStart(2, "0"),
17
17
  );
@@ -19,7 +19,7 @@ export class Uuid {
19
19
  private static readonly _uuidRegex =
20
20
  /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
21
21
 
22
- /** 16바이트 배열을 UUID 문자열로 변환 */
22
+ /** Convert 16-byte array to UUID string */
23
23
  private static _bytesToUuidStr(bytes: Uint8Array): string {
24
24
  const h = Uuid._hexTable;
25
25
  return (
@@ -46,12 +46,12 @@ export class Uuid {
46
46
  );
47
47
  }
48
48
 
49
- /** UUID v4 인스턴스 생성 */
49
+ /** Create new UUID v4 instance */
50
50
  static new(): Uuid {
51
51
  const bytes = new Uint8Array(16);
52
52
  crypto.getRandomValues(bytes);
53
53
 
54
- // UUID v4 설정
54
+ // Set UUID v4 bits
55
55
  bytes[6] = (bytes[6] & 0x0f) | 0x40;
56
56
  bytes[8] = (bytes[8] & 0x3f) | 0x80;
57
57
 
@@ -59,13 +59,13 @@ export class Uuid {
59
59
  }
60
60
 
61
61
  /**
62
- * 16바이트 Uint8Array에서 UUID 생성
63
- * @param bytes 16바이트 배열
64
- * @throws {ArgumentError} 바이트 크기가 16이 아닌 경우
62
+ * Create UUID from 16-byte Uint8Array
63
+ * @param bytes 16-byte array
64
+ * @throws {ArgumentError} If byte size is not 16
65
65
  */
66
66
  static fromBytes(bytes: Bytes): Uuid {
67
67
  if (bytes.length !== 16) {
68
- throw new ArgumentError("UUID 바이트 크기는 16이어야 합니다.", { length: bytes.length });
68
+ throw new ArgumentError("UUID byte size must be 16.", { length: bytes.length });
69
69
  }
70
70
 
71
71
  return new Uuid(Uuid._bytesToUuidStr(bytes));
@@ -74,26 +74,26 @@ export class Uuid {
74
74
  private readonly _uuid: string;
75
75
 
76
76
  /**
77
- * @param uuid UUID 문자열 (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 형식)
78
- * @throws {ArgumentError} 형식이 올바르지 않은 경우
77
+ * @param uuid UUID string (format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
78
+ * @throws {ArgumentError} If format is invalid
79
79
  */
80
80
  constructor(uuid: string) {
81
81
  if (!Uuid._uuidRegex.test(uuid)) {
82
- throw new ArgumentError("UUID 형식이 올바르지 않습니다.", { uuid });
82
+ throw new ArgumentError("Invalid UUID format.", { uuid });
83
83
  }
84
84
  this._uuid = uuid;
85
85
  }
86
86
 
87
- /** UUID 문자열로 변환 */
87
+ /** Convert UUID to string */
88
88
  toString(): string {
89
89
  return this._uuid;
90
90
  }
91
91
 
92
- /** UUID 16바이트 Uint8Array 변환 */
92
+ /** Convert UUID to 16-byte Uint8Array */
93
93
  toBytes(): Bytes {
94
94
  const u = this._uuid;
95
- // UUID 형식: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)
96
- // 하이픈 위치: 8, 13, 18, 23
95
+ // UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)
96
+ // Hyphen positions: 8, 13, 18, 23
97
97
  return new Uint8Array([
98
98
  Number.parseInt(u.substring(0, 2), 16),
99
99
  Number.parseInt(u.substring(2, 4), 16),