@simplysm/core-common 13.0.76 → 13.0.78

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 (126) hide show
  1. package/README.md +64 -21
  2. package/dist/extensions/arr-ext.d.ts +1 -1
  3. package/dist/extensions/arr-ext.d.ts.map +1 -1
  4. package/dist/extensions/arr-ext.helpers.d.ts +8 -0
  5. package/dist/extensions/arr-ext.helpers.d.ts.map +1 -1
  6. package/dist/extensions/arr-ext.helpers.js +65 -0
  7. package/dist/extensions/arr-ext.helpers.js.map +2 -2
  8. package/dist/extensions/arr-ext.js +16 -124
  9. package/dist/extensions/arr-ext.js.map +2 -2
  10. package/dist/extensions/arr-ext.types.d.ts +40 -32
  11. package/dist/extensions/arr-ext.types.d.ts.map +1 -1
  12. package/dist/extensions/map-ext.js.map +1 -1
  13. package/dist/extensions/set-ext.js.map +1 -1
  14. package/dist/features/event-emitter.d.ts +4 -4
  15. package/dist/features/event-emitter.d.ts.map +1 -1
  16. package/dist/features/event-emitter.js.map +1 -1
  17. package/dist/features/serial-queue.js +2 -2
  18. package/dist/features/serial-queue.js.map +1 -1
  19. package/dist/index.d.ts +13 -13
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +27 -13
  22. package/dist/index.js.map +1 -1
  23. package/dist/types/date-only.js +2 -2
  24. package/dist/types/date-only.js.map +1 -1
  25. package/dist/types/date-time.js +2 -2
  26. package/dist/types/date-time.js.map +1 -1
  27. package/dist/types/time.js +2 -2
  28. package/dist/types/time.js.map +1 -1
  29. package/dist/types/uuid.d.ts +2 -2
  30. package/dist/types/uuid.d.ts.map +1 -1
  31. package/dist/types/uuid.js +1 -1
  32. package/dist/types/uuid.js.map +1 -1
  33. package/dist/utils/bytes.d.ts +10 -10
  34. package/dist/utils/bytes.d.ts.map +1 -1
  35. package/dist/utils/bytes.js +10 -10
  36. package/dist/utils/bytes.js.map +1 -1
  37. package/dist/utils/date-format.d.ts +1 -1
  38. package/dist/utils/date-format.d.ts.map +1 -1
  39. package/dist/utils/date-format.js +2 -2
  40. package/dist/utils/date-format.js.map +1 -1
  41. package/dist/utils/error.d.ts +1 -1
  42. package/dist/utils/error.d.ts.map +1 -1
  43. package/dist/utils/error.js +2 -2
  44. package/dist/utils/error.js.map +1 -1
  45. package/dist/utils/json.d.ts +4 -2
  46. package/dist/utils/json.d.ts.map +1 -1
  47. package/dist/utils/json.js +9 -9
  48. package/dist/utils/json.js.map +1 -1
  49. package/dist/utils/num.d.ts +10 -10
  50. package/dist/utils/num.d.ts.map +1 -1
  51. package/dist/utils/num.js +11 -11
  52. package/dist/utils/num.js.map +1 -1
  53. package/dist/utils/obj.d.ts +40 -40
  54. package/dist/utils/obj.d.ts.map +1 -1
  55. package/dist/utils/obj.js +102 -99
  56. package/dist/utils/obj.js.map +1 -1
  57. package/dist/utils/path.d.ts +3 -3
  58. package/dist/utils/path.d.ts.map +1 -1
  59. package/dist/utils/path.js +6 -6
  60. package/dist/utils/path.js.map +1 -1
  61. package/dist/utils/primitive.d.ts +1 -1
  62. package/dist/utils/primitive.d.ts.map +1 -1
  63. package/dist/utils/primitive.js +2 -2
  64. package/dist/utils/primitive.js.map +1 -1
  65. package/dist/utils/str.d.ts +16 -16
  66. package/dist/utils/str.d.ts.map +1 -1
  67. package/dist/utils/str.js +16 -16
  68. package/dist/utils/str.js.map +1 -1
  69. package/dist/utils/transferable.d.ts +3 -3
  70. package/dist/utils/transferable.d.ts.map +1 -1
  71. package/dist/utils/transferable.js +10 -10
  72. package/dist/utils/transferable.js.map +1 -1
  73. package/dist/utils/wait.d.ts +2 -2
  74. package/dist/utils/wait.d.ts.map +1 -1
  75. package/dist/utils/wait.js +5 -5
  76. package/dist/utils/wait.js.map +1 -1
  77. package/dist/utils/xml.d.ts +2 -2
  78. package/dist/utils/xml.d.ts.map +1 -1
  79. package/dist/utils/xml.js +4 -4
  80. package/dist/utils/xml.js.map +1 -1
  81. package/dist/{zip/sd-zip.d.ts → utils/zip.d.ts} +1 -1
  82. package/dist/utils/zip.d.ts.map +1 -0
  83. package/dist/{zip/sd-zip.js → utils/zip.js} +1 -1
  84. package/dist/{zip/sd-zip.js.map → utils/zip.js.map} +1 -1
  85. package/package.json +1 -1
  86. package/src/extensions/arr-ext.helpers.ts +86 -0
  87. package/src/extensions/arr-ext.ts +22 -170
  88. package/src/extensions/arr-ext.types.ts +76 -48
  89. package/src/extensions/map-ext.ts +3 -3
  90. package/src/extensions/set-ext.ts +2 -2
  91. package/src/features/event-emitter.ts +6 -6
  92. package/src/features/serial-queue.ts +2 -2
  93. package/src/index.ts +16 -16
  94. package/src/types/date-only.ts +2 -2
  95. package/src/types/date-time.ts +2 -2
  96. package/src/types/time.ts +2 -2
  97. package/src/types/uuid.ts +2 -2
  98. package/src/utils/bytes.ts +15 -15
  99. package/src/utils/date-format.ts +1 -1
  100. package/src/utils/error.ts +1 -1
  101. package/src/utils/json.ts +9 -7
  102. package/src/utils/num.ts +15 -15
  103. package/src/utils/obj.ts +119 -116
  104. package/src/utils/path.ts +3 -3
  105. package/src/utils/primitive.ts +1 -1
  106. package/src/utils/str.ts +16 -16
  107. package/src/utils/transferable.ts +9 -9
  108. package/src/utils/wait.ts +3 -3
  109. package/src/utils/xml.ts +2 -2
  110. package/tests/extensions/array-extension.spec.ts +7 -5
  111. package/tests/types/uuid.spec.ts +4 -4
  112. package/tests/utils/bytes-utils.spec.ts +42 -49
  113. package/tests/utils/date-format.spec.ts +89 -88
  114. package/tests/utils/debounce-queue.spec.ts +3 -1
  115. package/tests/utils/json.spec.ts +61 -68
  116. package/tests/utils/number.spec.ts +41 -46
  117. package/tests/utils/object.spec.ts +120 -139
  118. package/tests/utils/path.spec.ts +19 -19
  119. package/tests/utils/primitive.spec.ts +12 -12
  120. package/tests/utils/string.spec.ts +66 -74
  121. package/tests/utils/transferable.spec.ts +55 -62
  122. package/tests/utils/wait.spec.ts +10 -10
  123. package/tests/utils/xml.spec.ts +25 -25
  124. package/dist/zip/sd-zip.d.ts.map +0 -1
  125. /package/src/{zip/sd-zip.ts → utils/zip.ts} +0 -0
  126. /package/tests/{zip/sd-zip.spec.ts → utils/zip.spec.ts} +0 -0
package/src/utils/path.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  * Combine paths (path.join replacement)
12
12
  * @note Supports POSIX style paths only (slash `/`)
13
13
  */
14
- export function pathJoin(...segments: string[]): string {
14
+ export function join(...segments: string[]): string {
15
15
  return segments
16
16
  .map((s, i) => (i === 0 ? s.replace(/\/+$/, "") : s.replace(/^\/+|\/+$/g, "")))
17
17
  .filter(Boolean)
@@ -21,7 +21,7 @@ export function pathJoin(...segments: string[]): string {
21
21
  /**
22
22
  * Extract filename (path.basename replacement)
23
23
  */
24
- export function pathBasename(filePath: string, ext?: string): string {
24
+ export function basename(filePath: string, ext?: string): string {
25
25
  const name = filePath.split("/").pop() ?? "";
26
26
  if (ext != null && ext !== "" && name.endsWith(ext)) {
27
27
  return name.slice(0, -ext.length);
@@ -33,7 +33,7 @@ export function pathBasename(filePath: string, ext?: string): string {
33
33
  * Extract file extension (path.extname replacement)
34
34
  * @note Hidden files (e.g., `.gitignore`) return empty string (same as Node.js path.extname)
35
35
  */
36
- export function pathExtname(filePath: string): string {
36
+ export function extname(filePath: string): string {
37
37
  const name = filePath.split("/").pop() ?? "";
38
38
  const dotIndex = name.lastIndexOf(".");
39
39
  return dotIndex > 0 ? name.slice(dotIndex) : "";
@@ -20,7 +20,7 @@ import type { PrimitiveTypeMap, PrimitiveTypeStr } from "../common.types";
20
20
  * getPrimitiveTypeStr(new DateTime()) // "DateTime"
21
21
  * getPrimitiveTypeStr(new Uint8Array()) // "Bytes"
22
22
  */
23
- export function getPrimitiveTypeStr(value: PrimitiveTypeMap[PrimitiveTypeStr]): PrimitiveTypeStr {
23
+ export function typeStr(value: PrimitiveTypeMap[PrimitiveTypeStr]): PrimitiveTypeStr {
24
24
  if (typeof value === "string") return "string";
25
25
  if (typeof value === "number") return "number";
26
26
  if (typeof value === "boolean") return "boolean";
package/src/utils/str.ts CHANGED
@@ -28,10 +28,10 @@ const suffixTable = {
28
28
  * - `"라"`: 이라/라 (ira/ra - copula particle)
29
29
  *
30
30
  * @example
31
- * koreanGetSuffix("Apple", "을") // "를"
32
- * koreanGetSuffix("책", "이") // "이"
31
+ * getKoreanSuffix("Apple", "을") // "를"
32
+ * getKoreanSuffix("책", "이") // "이"
33
33
  */
34
- export function koreanGetSuffix(
34
+ export function getKoreanSuffix(
35
35
  text: string,
36
36
  type: "을" | "은" | "이" | "와" | "랑" | "로" | "라",
37
37
  ): string {
@@ -147,10 +147,10 @@ const fullWidthCharRegex = new RegExp(`[${Object.keys(fullWidthCharMap).join("")
147
147
  * - Full-width parentheses (() → ())
148
148
  *
149
149
  * @example
150
- * strReplaceFullWidth("A123") // "A123"
151
- * strReplaceFullWidth("(株)") // "(株)"
150
+ * replaceFullWidth("A123") // "A123"
151
+ * replaceFullWidth("(株)") // "(株)"
152
152
  */
153
- export function strReplaceFullWidth(str: string): string {
153
+ export function replaceFullWidth(str: string): string {
154
154
  return str.replace(fullWidthCharRegex, (char) => fullWidthCharMap[char] ?? char);
155
155
  }
156
156
 
@@ -164,7 +164,7 @@ export function strReplaceFullWidth(str: string): string {
164
164
  * @example "hello_world" → "HelloWorld"
165
165
  * @example "hello.world" → "HelloWorld"
166
166
  */
167
- export function strToPascalCase(str: string): string {
167
+ export function toPascalCase(str: string): string {
168
168
  return str
169
169
  .replace(/[-._][a-z]/g, (m) => m[1].toUpperCase())
170
170
  .replace(/^[a-z]/, (m) => m.toUpperCase());
@@ -176,7 +176,7 @@ export function strToPascalCase(str: string): string {
176
176
  * @example "hello_world" → "helloWorld"
177
177
  * @example "HelloWorld" → "helloWorld"
178
178
  */
179
- export function strToCamelCase(str: string): string {
179
+ export function toCamelCase(str: string): string {
180
180
  return str
181
181
  .replace(/[-._][a-z]/g, (m) => m[1].toUpperCase())
182
182
  .replace(/^[A-Z]/, (m) => m.toLowerCase());
@@ -192,7 +192,7 @@ export function strToCamelCase(str: string): string {
192
192
  * @example "Hello-World" → "hello--world" (existing separators are preserved)
193
193
  * @example "XMLParser" → "x-m-l-parser" (consecutive uppercase letters are separated)
194
194
  */
195
- export function strToKebabCase(str: string): string {
195
+ export function toKebabCase(str: string): string {
196
196
  return toCaseWithSeparator(str, "-");
197
197
  }
198
198
 
@@ -206,7 +206,7 @@ export function strToKebabCase(str: string): string {
206
206
  * @example "Hello_World" → "hello__world" (existing separators are preserved)
207
207
  * @example "XMLParser" → "x_m_l_parser" (consecutive uppercase letters are separated)
208
208
  */
209
- export function strToSnakeCase(str: string): string {
209
+ export function toSnakeCase(str: string): string {
210
210
  return toCaseWithSeparator(str, "_");
211
211
  }
212
212
 
@@ -228,7 +228,7 @@ function toCaseWithSeparator(str: string, separator: string): string {
228
228
  *
229
229
  * @example
230
230
  * const name: string | undefined = getValue();
231
- * if (strIsNullOrEmpty(name)) {
231
+ * if (isNullOrEmpty(name)) {
232
232
  * // name: "" | undefined
233
233
  * console.log("Name is empty");
234
234
  * } else {
@@ -236,7 +236,7 @@ function toCaseWithSeparator(str: string, separator: string): string {
236
236
  * console.log(`Name: ${name}`);
237
237
  * }
238
238
  */
239
- export function strIsNullOrEmpty(str: string | undefined): str is "" | undefined {
239
+ export function isNullOrEmpty(str: string | undefined): str is "" | undefined {
240
240
  return str == null || str === "";
241
241
  }
242
242
 
@@ -249,11 +249,11 @@ export function strIsNullOrEmpty(str: string | undefined): str is "" | undefined
249
249
  * @returns A new string with the insertion applied
250
250
  *
251
251
  * @example
252
- * strInsert("Hello World", 5, ","); // "Hello, World"
253
- * strInsert("abc", 0, "X"); // "Xabc"
254
- * strInsert("abc", 3, "X"); // "abcX"
252
+ * insert("Hello World", 5, ","); // "Hello, World"
253
+ * insert("abc", 0, "X"); // "Xabc"
254
+ * insert("abc", 3, "X"); // "abcX"
255
255
  */
256
- export function strInsert(str: string, index: number, insertString: string): string {
256
+ export function insert(str: string, index: number, insertString: string): string {
257
257
  return str.substring(0, index) + insertString + str.substring(index);
258
258
  }
259
259
 
@@ -32,7 +32,7 @@ type Transferable = ArrayBuffer;
32
32
  * worker.postMessage(result, transferList);
33
33
  *
34
34
  * // Receive data from Worker
35
- * const decoded = transferableDecode(event.data);
35
+ * const decoded = decode(event.data);
36
36
  */
37
37
 
38
38
  //#region encode
@@ -43,7 +43,7 @@ type Transferable = ArrayBuffer;
43
43
  *
44
44
  * @throws TypeError if circular reference is detected
45
45
  */
46
- export function transferableEncode(obj: unknown): {
46
+ export function encode(obj: unknown): {
47
47
  result: unknown;
48
48
  transferList: Transferable[];
49
49
  } {
@@ -204,7 +204,7 @@ function encodeImpl(
204
204
  * Convert serialized objects to objects using Simplysm types
205
205
  * Deserialize data received from a Worker
206
206
  */
207
- export function transferableDecode(obj: unknown): unknown {
207
+ export function decode(obj: unknown): unknown {
208
208
  if (obj == null) return obj;
209
209
 
210
210
  // 1. Restore special types from tagged objects
@@ -239,22 +239,22 @@ export function transferableDecode(obj: unknown): unknown {
239
239
  err.stack = errorData.stack;
240
240
 
241
241
  if (errorData.code !== undefined) err.code = errorData.code;
242
- if (errorData.cause !== undefined) (err as Error).cause = transferableDecode(errorData.cause);
243
- if (errorData.detail !== undefined) err.detail = transferableDecode(errorData.detail);
242
+ if (errorData.cause !== undefined) (err as Error).cause = decode(errorData.cause);
243
+ if (errorData.detail !== undefined) err.detail = decode(errorData.detail);
244
244
  return err;
245
245
  }
246
246
  }
247
247
 
248
248
  // 2. Array recursion
249
249
  if (Array.isArray(obj)) {
250
- return obj.map((item) => transferableDecode(item));
250
+ return obj.map((item) => decode(item));
251
251
  }
252
252
 
253
253
  // 3. Map recursion
254
254
  if (obj instanceof Map) {
255
255
  const newMap = new Map<unknown, unknown>();
256
256
  for (const [k, v] of obj) {
257
- newMap.set(transferableDecode(k), transferableDecode(v));
257
+ newMap.set(decode(k), decode(v));
258
258
  }
259
259
  return newMap;
260
260
  }
@@ -263,7 +263,7 @@ export function transferableDecode(obj: unknown): unknown {
263
263
  if (obj instanceof Set) {
264
264
  const newSet = new Set<unknown>();
265
265
  for (const v of obj) {
266
- newSet.add(transferableDecode(v));
266
+ newSet.add(decode(v));
267
267
  }
268
268
  return newSet;
269
269
  }
@@ -273,7 +273,7 @@ export function transferableDecode(obj: unknown): unknown {
273
273
  const record = obj as Record<string, unknown>;
274
274
  const result: Record<string, unknown> = {};
275
275
  for (const key of Object.keys(record)) {
276
- result[key] = transferableDecode(record[key]);
276
+ result[key] = decode(record[key]);
277
277
  }
278
278
  return result;
279
279
  }
package/src/utils/wait.ts CHANGED
@@ -15,7 +15,7 @@ import { TimeoutError } from "../errors/timeout-error";
15
15
  * await waitUntil(() => someCondition, 100, 3);
16
16
  * @throws TimeoutError when maximum number of attempts is exceeded
17
17
  */
18
- export async function waitUntil(
18
+ export async function until(
19
19
  forwarder: () => boolean | Promise<boolean>,
20
20
  milliseconds?: number,
21
21
  maxCount?: number,
@@ -27,7 +27,7 @@ export async function waitUntil(
27
27
  throw new TimeoutError(count);
28
28
  }
29
29
 
30
- await waitTime(milliseconds ?? 100);
30
+ await time(milliseconds ?? 100);
31
31
  }
32
32
  }
33
33
 
@@ -35,6 +35,6 @@ export async function waitUntil(
35
35
  * Wait for a specified amount of time
36
36
  * @param millisecond Wait time (ms)
37
37
  */
38
- export async function waitTime(millisecond: number): Promise<void> {
38
+ export async function time(millisecond: number): Promise<void> {
39
39
  return new Promise<void>((resolve) => setTimeout(resolve, millisecond));
40
40
  }
package/src/utils/xml.ts CHANGED
@@ -19,7 +19,7 @@ import { XMLBuilder, XMLParser } from "fast-xml-parser";
19
19
  * xmlParse('<root id="1"><item>hello</item></root>');
20
20
  * // { root: { $: { id: "1" }, item: [{ _: "hello" }] } }
21
21
  */
22
- export function xmlParse(str: string, options?: { stripTagPrefix?: boolean }): unknown {
22
+ export function parse(str: string, options?: { stripTagPrefix?: boolean }): unknown {
23
23
  const result = new XMLParser({
24
24
  ignoreAttributes: false,
25
25
  attributeNamePrefix: "",
@@ -53,7 +53,7 @@ export function xmlParse(str: string, options?: { stripTagPrefix?: boolean }): u
53
53
  * });
54
54
  * // '<root id="1"><item>hello</item><item>world</item></root>'
55
55
  */
56
- export function xmlStringify(obj: unknown, options?: XmlBuilderOptions): string {
56
+ export function stringify(obj: unknown, options?: XmlBuilderOptions): string {
57
57
  return new XMLBuilder({
58
58
  ignoreAttributes: false,
59
59
  attributeNamePrefix: "",
@@ -196,6 +196,7 @@ describe("Array prototype extensions", () => {
196
196
  describe("diffs()", () => {
197
197
  it("Analyzes differences between arrays", () => {
198
198
  interface Item {
199
+ [key: string]: unknown;
199
200
  id: number;
200
201
  value: string;
201
202
  }
@@ -214,13 +215,13 @@ describe("Array prototype extensions", () => {
214
215
 
215
216
  const result = source.diffs(target, { keys: ["id"] });
216
217
 
217
- const deleted = result.find((d) => d.source?.id === 1);
218
+ const deleted = result.find((d) => d.source?.["id"] === 1);
218
219
  expect(deleted?.target).toBe(undefined);
219
220
 
220
- const updated = result.find((d) => d.source?.id === 3);
221
- expect(updated?.target?.value).toBe("changed");
221
+ const updated = result.find((d) => d.source?.["id"] === 3);
222
+ expect(updated?.target?.["value"]).toBe("changed");
222
223
 
223
- const inserted = result.find((d) => d.target?.id === 4);
224
+ const inserted = result.find((d) => d.target?.["id"] === 4);
224
225
  expect(inserted?.source).toBe(undefined);
225
226
  });
226
227
  });
@@ -280,6 +281,7 @@ describe("Array prototype extensions", () => {
280
281
  describe("merge()", () => {
281
282
  it("Merges modified items", () => {
282
283
  interface Item {
284
+ [key: string]: unknown;
283
285
  id: number;
284
286
  value: string;
285
287
  }
@@ -296,7 +298,7 @@ describe("Array prototype extensions", () => {
296
298
  const result = source.merge(target, { keys: ["id"] });
297
299
 
298
300
  expect(result).toHaveLength(2);
299
- expect(result.find((r) => r.id === 2)?.value).toBe("changed");
301
+ expect(result.find((r) => r["id"] === 2)?.["value"]).toBe("changed");
300
302
  });
301
303
  });
302
304
 
@@ -2,9 +2,9 @@ import { describe, it, expect } from "vitest";
2
2
  import { Uuid } from "@simplysm/core-common";
3
3
 
4
4
  describe("Uuid", () => {
5
- describe("new()", () => {
5
+ describe("generate()", () => {
6
6
  it("Generates valid UUID v4 format", () => {
7
- const uuid = Uuid.new();
7
+ const uuid = Uuid.generate();
8
8
  const str = uuid.toString();
9
9
 
10
10
  // UUID v4 format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
@@ -12,8 +12,8 @@ describe("Uuid", () => {
12
12
  });
13
13
 
14
14
  it("Generates new UUID each time", () => {
15
- const uuid1 = Uuid.new();
16
- const uuid2 = Uuid.new();
15
+ const uuid1 = Uuid.generate();
16
+ const uuid2 = Uuid.generate();
17
17
 
18
18
  expect(uuid1.toString()).not.toBe(uuid2.toString());
19
19
  });
@@ -1,29 +1,22 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import {
3
- ArgumentError,
4
- bytesConcat as concat,
5
- bytesToHex as toHex,
6
- bytesFromHex as fromHex,
7
- bytesToBase64 as toBase64,
8
- bytesFromBase64 as fromBase64,
9
- } from "@simplysm/core-common";
2
+ import { ArgumentError, bytes } from "@simplysm/core-common";
10
3
 
11
4
  describe("BytesUtils", () => {
12
5
  //#region concat
13
6
 
14
- describe("concat()", () => {
7
+ describe("bytes.concat()", () => {
15
8
  it("Concatenates multiple Uint8Arrays", () => {
16
9
  const arr1 = new Uint8Array([1, 2, 3]);
17
10
  const arr2 = new Uint8Array([4, 5]);
18
11
  const arr3 = new Uint8Array([6, 7, 8, 9]);
19
12
 
20
- const result = concat([arr1, arr2, arr3]);
13
+ const result = bytes.concat([arr1, arr2, arr3]);
21
14
 
22
15
  expect(result).toEqual(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9]));
23
16
  });
24
17
 
25
18
  it("Handles empty array", () => {
26
- const result = concat([]);
19
+ const result = bytes.concat([]);
27
20
 
28
21
  expect(result).toEqual(new Uint8Array([]));
29
22
  expect(result.length).toBe(0);
@@ -34,7 +27,7 @@ describe("BytesUtils", () => {
34
27
  const arr2 = new Uint8Array([]);
35
28
  const arr3 = new Uint8Array([3, 4]);
36
29
 
37
- const result = concat([arr1, arr2, arr3]);
30
+ const result = bytes.concat([arr1, arr2, arr3]);
38
31
 
39
32
  expect(result).toEqual(new Uint8Array([1, 2, 3, 4]));
40
33
  });
@@ -44,56 +37,56 @@ describe("BytesUtils", () => {
44
37
 
45
38
  //#region toHex/fromHex
46
39
 
47
- describe("toHex()", () => {
40
+ describe("bytes.toHex()", () => {
48
41
  it("Converts Uint8Array to hex string", () => {
49
- const bytes = new Uint8Array([0, 1, 15, 16, 255]);
42
+ const data = new Uint8Array([0, 1, 15, 16, 255]);
50
43
 
51
- const result = toHex(bytes);
44
+ const result = bytes.toHex(data);
52
45
 
53
46
  expect(result).toBe("00010f10ff");
54
47
  });
55
48
 
56
49
  it("Handles empty array", () => {
57
- const result = toHex(new Uint8Array([]));
50
+ const result = bytes.toHex(new Uint8Array([]));
58
51
 
59
52
  expect(result).toBe("");
60
53
  });
61
54
 
62
55
  it("Handles single byte", () => {
63
- expect(toHex(new Uint8Array([0]))).toBe("00");
64
- expect(toHex(new Uint8Array([255]))).toBe("ff");
56
+ expect(bytes.toHex(new Uint8Array([0]))).toBe("00");
57
+ expect(bytes.toHex(new Uint8Array([255]))).toBe("ff");
65
58
  });
66
59
  });
67
60
 
68
- describe("fromHex()", () => {
61
+ describe("bytes.fromHex()", () => {
69
62
  it("Converts hex string to Uint8Array", () => {
70
- const result = fromHex("00010f10ff");
63
+ const result = bytes.fromHex("00010f10ff");
71
64
 
72
65
  expect(result).toEqual(new Uint8Array([0, 1, 15, 16, 255]));
73
66
  });
74
67
 
75
68
  it("Handles empty string", () => {
76
- const result = fromHex("");
69
+ const result = bytes.fromHex("");
77
70
 
78
71
  expect(result).toEqual(new Uint8Array([]));
79
72
  });
80
73
 
81
74
  it("Handles uppercase hex", () => {
82
- const result = fromHex("FF0A");
75
+ const result = bytes.fromHex("FF0A");
83
76
 
84
77
  expect(result).toEqual(new Uint8Array([255, 10]));
85
78
  });
86
79
 
87
80
  it("Throws error for odd-length string", () => {
88
- expect(() => fromHex("abc")).toThrow(ArgumentError);
89
- expect(() => fromHex("a")).toThrow(ArgumentError);
90
- expect(() => fromHex("12345")).toThrow(ArgumentError);
81
+ expect(() => bytes.fromHex("abc")).toThrow(ArgumentError);
82
+ expect(() => bytes.fromHex("a")).toThrow(ArgumentError);
83
+ expect(() => bytes.fromHex("12345")).toThrow(ArgumentError);
91
84
  });
92
85
 
93
86
  it("Throws error for invalid hex characters", () => {
94
- expect(() => fromHex("zz")).toThrow(ArgumentError);
95
- expect(() => fromHex("gh")).toThrow(ArgumentError);
96
- expect(() => fromHex("12g4")).toThrow(ArgumentError);
87
+ expect(() => bytes.fromHex("zz")).toThrow(ArgumentError);
88
+ expect(() => bytes.fromHex("gh")).toThrow(ArgumentError);
89
+ expect(() => bytes.fromHex("12g4")).toThrow(ArgumentError);
97
90
  });
98
91
  });
99
92
 
@@ -104,8 +97,8 @@ describe("BytesUtils", () => {
104
97
  original[i] = i;
105
98
  }
106
99
 
107
- const hex = toHex(original);
108
- const restored = fromHex(hex);
100
+ const hex = bytes.toHex(original);
101
+ const restored = bytes.fromHex(hex);
109
102
 
110
103
  expect(restored).toEqual(original);
111
104
  });
@@ -115,60 +108,60 @@ describe("BytesUtils", () => {
115
108
 
116
109
  //#region toBase64/fromBase64
117
110
 
118
- describe("toBase64()", () => {
111
+ describe("bytes.toBase64()", () => {
119
112
  it("Handles empty array", () => {
120
- expect(toBase64(new Uint8Array([]))).toBe("");
113
+ expect(bytes.toBase64(new Uint8Array([]))).toBe("");
121
114
  });
122
115
 
123
116
  it("Converts general data", () => {
124
- expect(toBase64(new Uint8Array([72, 101, 108, 108, 111]))).toBe("SGVsbG8=");
117
+ expect(bytes.toBase64(new Uint8Array([72, 101, 108, 108, 111]))).toBe("SGVsbG8=");
125
118
  });
126
119
 
127
120
  it("Handles large data (1MB) without stack overflow", () => {
128
121
  const data = new Uint8Array(1024 * 1024);
129
- expect(() => toBase64(data)).not.toThrow();
122
+ expect(() => bytes.toBase64(data)).not.toThrow();
130
123
  });
131
124
 
132
125
  it("Handles case with no padding needed", () => {
133
126
  // Multiple of 3 length - no padding
134
- expect(toBase64(new Uint8Array([1, 2, 3]))).toBe("AQID");
127
+ expect(bytes.toBase64(new Uint8Array([1, 2, 3]))).toBe("AQID");
135
128
  });
136
129
 
137
130
  it("Handles case with single padding needed", () => {
138
131
  // Remainder 2 when divided by 3 - 1 padding
139
- expect(toBase64(new Uint8Array([1, 2]))).toBe("AQI=");
132
+ expect(bytes.toBase64(new Uint8Array([1, 2]))).toBe("AQI=");
140
133
  });
141
134
 
142
135
  it("Handles case with double padding needed", () => {
143
136
  // Remainder 1 when divided by 3 - 2 padding
144
- expect(toBase64(new Uint8Array([1]))).toBe("AQ==");
137
+ expect(bytes.toBase64(new Uint8Array([1]))).toBe("AQ==");
145
138
  });
146
139
  });
147
140
 
148
- describe("fromBase64()", () => {
141
+ describe("bytes.fromBase64()", () => {
149
142
  it("Handles empty string", () => {
150
- expect(fromBase64("")).toEqual(new Uint8Array([]));
143
+ expect(bytes.fromBase64("")).toEqual(new Uint8Array([]));
151
144
  });
152
145
 
153
146
  it("Converts general data", () => {
154
- expect(fromBase64("SGVsbG8=")).toEqual(new Uint8Array([72, 101, 108, 108, 111]));
147
+ expect(bytes.fromBase64("SGVsbG8=")).toEqual(new Uint8Array([72, 101, 108, 108, 111]));
155
148
  });
156
149
 
157
150
  it("Throws error for invalid base64 characters", () => {
158
- expect(() => fromBase64("!!invalid!!")).toThrow(ArgumentError);
151
+ expect(() => bytes.fromBase64("!!invalid!!")).toThrow(ArgumentError);
159
152
  });
160
153
 
161
154
  it("Throws error for invalid base64 length (remainder 1)", () => {
162
- expect(() => fromBase64("A")).toThrow(ArgumentError);
163
- expect(() => fromBase64("AAAAA")).toThrow(ArgumentError);
155
+ expect(() => bytes.fromBase64("A")).toThrow(ArgumentError);
156
+ expect(() => bytes.fromBase64("AAAAA")).toThrow(ArgumentError);
164
157
  });
165
158
 
166
159
  it("Handles base64 without padding", () => {
167
- expect(fromBase64("AQID")).toEqual(new Uint8Array([1, 2, 3]));
160
+ expect(bytes.fromBase64("AQID")).toEqual(new Uint8Array([1, 2, 3]));
168
161
  });
169
162
 
170
163
  it("Handles base64 with whitespace", () => {
171
- expect(fromBase64("SGVs bG8=")).toEqual(new Uint8Array([72, 101, 108, 108, 111]));
164
+ expect(bytes.fromBase64("SGVs bG8=")).toEqual(new Uint8Array([72, 101, 108, 108, 111]));
172
165
  });
173
166
  });
174
167
 
@@ -179,8 +172,8 @@ describe("BytesUtils", () => {
179
172
  original[i] = i;
180
173
  }
181
174
 
182
- const base64 = toBase64(original);
183
- const restored = fromBase64(base64);
175
+ const base64 = bytes.toBase64(original);
176
+ const restored = bytes.fromBase64(base64);
184
177
 
185
178
  expect(restored).toEqual(original);
186
179
  });
@@ -192,8 +185,8 @@ describe("BytesUtils", () => {
192
185
  original[i] = (i * 37 + 13) % 256;
193
186
  }
194
187
 
195
- const base64 = toBase64(original);
196
- const restored = fromBase64(base64);
188
+ const base64 = bytes.toBase64(original);
189
+ const restored = bytes.fromBase64(base64);
197
190
 
198
191
  expect(restored).toEqual(original);
199
192
  }