@simplysm/core-common 13.0.0-beta.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 (202) hide show
  1. package/.cache/typecheck-browser.tsbuildinfo +1 -0
  2. package/.cache/typecheck-node.tsbuildinfo +1 -0
  3. package/.cache/typecheck-tests-browser.tsbuildinfo +1 -0
  4. package/.cache/typecheck-tests-node.tsbuildinfo +1 -0
  5. package/README.md +887 -0
  6. package/dist/common.types.d.ts +74 -0
  7. package/dist/common.types.d.ts.map +1 -0
  8. package/dist/common.types.js +5 -0
  9. package/dist/common.types.js.map +7 -0
  10. package/dist/env.d.ts +6 -0
  11. package/dist/env.d.ts.map +1 -0
  12. package/dist/env.js +9 -0
  13. package/dist/env.js.map +7 -0
  14. package/dist/errors/argument-error.d.ts +25 -0
  15. package/dist/errors/argument-error.d.ts.map +1 -0
  16. package/dist/errors/argument-error.js +18 -0
  17. package/dist/errors/argument-error.js.map +7 -0
  18. package/dist/errors/not-implemented-error.d.ts +29 -0
  19. package/dist/errors/not-implemented-error.d.ts.map +1 -0
  20. package/dist/errors/not-implemented-error.js +14 -0
  21. package/dist/errors/not-implemented-error.js.map +7 -0
  22. package/dist/errors/sd-error.d.ts +27 -0
  23. package/dist/errors/sd-error.d.ts.map +1 -0
  24. package/dist/errors/sd-error.js +23 -0
  25. package/dist/errors/sd-error.js.map +7 -0
  26. package/dist/errors/timeout-error.d.ts +31 -0
  27. package/dist/errors/timeout-error.d.ts.map +1 -0
  28. package/dist/errors/timeout-error.js +17 -0
  29. package/dist/errors/timeout-error.js.map +7 -0
  30. package/dist/extensions/arr-ext.d.ts +15 -0
  31. package/dist/extensions/arr-ext.d.ts.map +1 -0
  32. package/dist/extensions/arr-ext.helpers.d.ts +19 -0
  33. package/dist/extensions/arr-ext.helpers.d.ts.map +1 -0
  34. package/dist/extensions/arr-ext.helpers.js +35 -0
  35. package/dist/extensions/arr-ext.helpers.js.map +7 -0
  36. package/dist/extensions/arr-ext.js +546 -0
  37. package/dist/extensions/arr-ext.js.map +7 -0
  38. package/dist/extensions/arr-ext.types.d.ts +215 -0
  39. package/dist/extensions/arr-ext.types.d.ts.map +1 -0
  40. package/dist/extensions/arr-ext.types.js +1 -0
  41. package/dist/extensions/arr-ext.types.js.map +7 -0
  42. package/dist/extensions/map-ext.d.ts +57 -0
  43. package/dist/extensions/map-ext.d.ts.map +1 -0
  44. package/dist/extensions/map-ext.js +26 -0
  45. package/dist/extensions/map-ext.js.map +7 -0
  46. package/dist/extensions/set-ext.d.ts +36 -0
  47. package/dist/extensions/set-ext.d.ts.map +1 -0
  48. package/dist/extensions/set-ext.js +29 -0
  49. package/dist/extensions/set-ext.js.map +7 -0
  50. package/dist/features/debounce-queue.d.ts +53 -0
  51. package/dist/features/debounce-queue.d.ts.map +1 -0
  52. package/dist/features/debounce-queue.js +80 -0
  53. package/dist/features/debounce-queue.js.map +7 -0
  54. package/dist/features/event-emitter.d.ts +66 -0
  55. package/dist/features/event-emitter.d.ts.map +1 -0
  56. package/dist/features/event-emitter.js +82 -0
  57. package/dist/features/event-emitter.js.map +7 -0
  58. package/dist/features/serial-queue.d.ts +47 -0
  59. package/dist/features/serial-queue.d.ts.map +1 -0
  60. package/dist/features/serial-queue.js +66 -0
  61. package/dist/features/serial-queue.js.map +7 -0
  62. package/dist/globals.d.ts +12 -0
  63. package/dist/globals.d.ts.map +1 -0
  64. package/dist/globals.js +1 -0
  65. package/dist/globals.js.map +7 -0
  66. package/dist/index.d.ts +32 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +31 -0
  69. package/dist/index.js.map +7 -0
  70. package/dist/types/date-only.d.ts +152 -0
  71. package/dist/types/date-only.d.ts.map +1 -0
  72. package/dist/types/date-only.js +251 -0
  73. package/dist/types/date-only.js.map +7 -0
  74. package/dist/types/date-time.d.ts +96 -0
  75. package/dist/types/date-time.d.ts.map +1 -0
  76. package/dist/types/date-time.js +220 -0
  77. package/dist/types/date-time.js.map +7 -0
  78. package/dist/types/lazy-gc-map.d.ts +80 -0
  79. package/dist/types/lazy-gc-map.d.ts.map +1 -0
  80. package/dist/types/lazy-gc-map.js +179 -0
  81. package/dist/types/lazy-gc-map.js.map +7 -0
  82. package/dist/types/time.d.ts +68 -0
  83. package/dist/types/time.d.ts.map +1 -0
  84. package/dist/types/time.js +151 -0
  85. package/dist/types/time.js.map +7 -0
  86. package/dist/types/uuid.d.ts +35 -0
  87. package/dist/types/uuid.d.ts.map +1 -0
  88. package/dist/types/uuid.js +71 -0
  89. package/dist/types/uuid.js.map +7 -0
  90. package/dist/utils/bytes.d.ts +51 -0
  91. package/dist/utils/bytes.d.ts.map +1 -0
  92. package/dist/utils/bytes.js +89 -0
  93. package/dist/utils/bytes.js.map +7 -0
  94. package/dist/utils/date-format.d.ts +90 -0
  95. package/dist/utils/date-format.d.ts.map +1 -0
  96. package/dist/utils/date-format.js +106 -0
  97. package/dist/utils/date-format.js.map +7 -0
  98. package/dist/utils/json.d.ts +34 -0
  99. package/dist/utils/json.d.ts.map +1 -0
  100. package/dist/utils/json.js +152 -0
  101. package/dist/utils/json.js.map +7 -0
  102. package/dist/utils/num.d.ts +60 -0
  103. package/dist/utils/num.d.ts.map +1 -0
  104. package/dist/utils/num.js +39 -0
  105. package/dist/utils/num.js.map +7 -0
  106. package/dist/utils/obj.d.ts +258 -0
  107. package/dist/utils/obj.d.ts.map +1 -0
  108. package/dist/utils/obj.js +538 -0
  109. package/dist/utils/obj.js.map +7 -0
  110. package/dist/utils/path.d.ts +23 -0
  111. package/dist/utils/path.d.ts.map +1 -0
  112. package/dist/utils/path.js +21 -0
  113. package/dist/utils/path.js.map +7 -0
  114. package/dist/utils/primitive.d.ts +18 -0
  115. package/dist/utils/primitive.d.ts.map +1 -0
  116. package/dist/utils/primitive.js +20 -0
  117. package/dist/utils/primitive.js.map +7 -0
  118. package/dist/utils/str.d.ts +103 -0
  119. package/dist/utils/str.d.ts.map +1 -0
  120. package/dist/utils/str.js +128 -0
  121. package/dist/utils/str.js.map +7 -0
  122. package/dist/utils/template-strings.d.ts +84 -0
  123. package/dist/utils/template-strings.d.ts.map +1 -0
  124. package/dist/utils/template-strings.js +49 -0
  125. package/dist/utils/template-strings.js.map +7 -0
  126. package/dist/utils/transferable.d.ts +47 -0
  127. package/dist/utils/transferable.d.ts.map +1 -0
  128. package/dist/utils/transferable.js +153 -0
  129. package/dist/utils/transferable.js.map +7 -0
  130. package/dist/utils/wait.d.ts +19 -0
  131. package/dist/utils/wait.d.ts.map +1 -0
  132. package/dist/utils/wait.js +19 -0
  133. package/dist/utils/wait.js.map +7 -0
  134. package/dist/utils/xml.d.ts +36 -0
  135. package/dist/utils/xml.d.ts.map +1 -0
  136. package/dist/utils/xml.js +51 -0
  137. package/dist/utils/xml.js.map +7 -0
  138. package/dist/zip/sd-zip.d.ts +80 -0
  139. package/dist/zip/sd-zip.d.ts.map +1 -0
  140. package/dist/zip/sd-zip.js +153 -0
  141. package/dist/zip/sd-zip.js.map +7 -0
  142. package/package.json +31 -0
  143. package/src/common.types.ts +91 -0
  144. package/src/env.ts +11 -0
  145. package/src/errors/argument-error.ts +40 -0
  146. package/src/errors/not-implemented-error.ts +32 -0
  147. package/src/errors/sd-error.ts +53 -0
  148. package/src/errors/timeout-error.ts +36 -0
  149. package/src/extensions/arr-ext.helpers.ts +53 -0
  150. package/src/extensions/arr-ext.ts +777 -0
  151. package/src/extensions/arr-ext.types.ts +258 -0
  152. package/src/extensions/map-ext.ts +86 -0
  153. package/src/extensions/set-ext.ts +68 -0
  154. package/src/features/debounce-queue.ts +116 -0
  155. package/src/features/event-emitter.ts +112 -0
  156. package/src/features/serial-queue.ts +94 -0
  157. package/src/globals.ts +12 -0
  158. package/src/index.ts +55 -0
  159. package/src/types/date-only.ts +329 -0
  160. package/src/types/date-time.ts +294 -0
  161. package/src/types/lazy-gc-map.ts +244 -0
  162. package/src/types/time.ts +210 -0
  163. package/src/types/uuid.ts +113 -0
  164. package/src/utils/bytes.ts +160 -0
  165. package/src/utils/date-format.ts +239 -0
  166. package/src/utils/json.ts +230 -0
  167. package/src/utils/num.ts +97 -0
  168. package/src/utils/obj.ts +956 -0
  169. package/src/utils/path.ts +40 -0
  170. package/src/utils/primitive.ts +33 -0
  171. package/src/utils/str.ts +252 -0
  172. package/src/utils/template-strings.ts +132 -0
  173. package/src/utils/transferable.ts +269 -0
  174. package/src/utils/wait.ts +40 -0
  175. package/src/utils/xml.ts +105 -0
  176. package/src/zip/sd-zip.ts +218 -0
  177. package/tests/errors/errors.spec.ts +196 -0
  178. package/tests/extensions/array-extension.spec.ts +790 -0
  179. package/tests/extensions/map-extension.spec.ts +147 -0
  180. package/tests/extensions/set-extension.spec.ts +74 -0
  181. package/tests/types/date-only.spec.ts +636 -0
  182. package/tests/types/date-time.spec.ts +391 -0
  183. package/tests/types/lazy-gc-map.spec.ts +692 -0
  184. package/tests/types/time.spec.ts +559 -0
  185. package/tests/types/types.spec.ts +55 -0
  186. package/tests/types/uuid.spec.ts +91 -0
  187. package/tests/utils/bytes-utils.spec.ts +230 -0
  188. package/tests/utils/date-format.spec.ts +371 -0
  189. package/tests/utils/debounce-queue.spec.ts +272 -0
  190. package/tests/utils/json.spec.ts +475 -0
  191. package/tests/utils/number.spec.ts +184 -0
  192. package/tests/utils/object.spec.ts +827 -0
  193. package/tests/utils/path.spec.ts +78 -0
  194. package/tests/utils/primitive.spec.ts +55 -0
  195. package/tests/utils/sd-event-emitter.spec.ts +216 -0
  196. package/tests/utils/serial-queue.spec.ts +365 -0
  197. package/tests/utils/string.spec.ts +294 -0
  198. package/tests/utils/template-strings.spec.ts +96 -0
  199. package/tests/utils/transferable.spec.ts +698 -0
  200. package/tests/utils/wait.spec.ts +145 -0
  201. package/tests/utils/xml.spec.ts +146 -0
  202. package/tests/zip/sd-zip.spec.ts +234 -0
@@ -0,0 +1,153 @@
1
+ import { DateTime } from "../types/date-time";
2
+ import { DateOnly } from "../types/date-only";
3
+ import { Time } from "../types/time";
4
+ import { Uuid } from "../types/uuid";
5
+ function transferableEncode(obj) {
6
+ const transferList = [];
7
+ const ancestors = /* @__PURE__ */ new Set();
8
+ const cache = /* @__PURE__ */ new Map();
9
+ const result = encodeImpl(obj, transferList, [], ancestors, cache);
10
+ return { result, transferList };
11
+ }
12
+ function encodeImpl(obj, transferList, path, ancestors, cache) {
13
+ if (obj == null) return obj;
14
+ if (typeof obj === "object") {
15
+ if (ancestors.has(obj)) {
16
+ const currentPath = path.length > 0 ? path.join(".") : "root";
17
+ throw new TypeError(`\uC21C\uD658 \uCC38\uC870\uAC00 \uAC10\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4: ${currentPath}`);
18
+ }
19
+ const cached = cache.get(obj);
20
+ if (cached !== void 0) return cached;
21
+ ancestors.add(obj);
22
+ }
23
+ let result;
24
+ try {
25
+ if (obj instanceof Uint8Array) {
26
+ const isSharedArrayBuffer = typeof SharedArrayBuffer !== "undefined" && obj.buffer instanceof SharedArrayBuffer;
27
+ const buffer = obj.buffer;
28
+ if (!isSharedArrayBuffer && !transferList.includes(buffer)) {
29
+ transferList.push(buffer);
30
+ }
31
+ result = obj;
32
+ } else if (obj instanceof Date) {
33
+ result = { __type__: "Date", data: obj.getTime() };
34
+ } else if (obj instanceof DateTime) {
35
+ result = { __type__: "DateTime", data: obj.tick };
36
+ } else if (obj instanceof DateOnly) {
37
+ result = { __type__: "DateOnly", data: obj.tick };
38
+ } else if (obj instanceof Time) {
39
+ result = { __type__: "Time", data: obj.tick };
40
+ } else if (obj instanceof Uuid) {
41
+ result = { __type__: "Uuid", data: obj.toString() };
42
+ } else if (obj instanceof RegExp) {
43
+ result = { __type__: "RegExp", data: { source: obj.source, flags: obj.flags } };
44
+ } else if (obj instanceof Error) {
45
+ const errObj = obj;
46
+ result = {
47
+ __type__: "Error",
48
+ data: {
49
+ name: errObj.name,
50
+ message: errObj.message,
51
+ stack: errObj.stack,
52
+ ...errObj.code !== void 0 ? { code: errObj.code } : {},
53
+ ...errObj.detail !== void 0 ? { detail: encodeImpl(errObj.detail, transferList, [...path, "detail"], ancestors, cache) } : {},
54
+ ...errObj.cause !== void 0 ? { cause: encodeImpl(errObj.cause, transferList, [...path, "cause"], ancestors, cache) } : {}
55
+ }
56
+ };
57
+ } else if (Array.isArray(obj)) {
58
+ result = obj.map((item, idx) => encodeImpl(item, transferList, [...path, idx], ancestors, cache));
59
+ } else if (obj instanceof Map) {
60
+ let idx = 0;
61
+ result = new Map(
62
+ Array.from(obj.entries()).map(([k, v]) => {
63
+ const keyPath = [...path, `Map[${idx}].key`];
64
+ const valuePath = [...path, `Map[${idx}].value`];
65
+ idx++;
66
+ return [
67
+ encodeImpl(k, transferList, keyPath, ancestors, cache),
68
+ encodeImpl(v, transferList, valuePath, ancestors, cache)
69
+ ];
70
+ })
71
+ );
72
+ } else if (obj instanceof Set) {
73
+ let idx = 0;
74
+ result = new Set(
75
+ Array.from(obj).map((v) => encodeImpl(v, transferList, [...path, `Set[${idx++}]`], ancestors, cache))
76
+ );
77
+ } else if (typeof obj === "object") {
78
+ const res = {};
79
+ const record = obj;
80
+ for (const key of Object.keys(record)) {
81
+ res[key] = encodeImpl(record[key], transferList, [...path, key], ancestors, cache);
82
+ }
83
+ result = res;
84
+ } else {
85
+ return obj;
86
+ }
87
+ if (typeof obj === "object") {
88
+ cache.set(obj, result);
89
+ }
90
+ return result;
91
+ } finally {
92
+ if (typeof obj === "object") {
93
+ ancestors.delete(obj);
94
+ }
95
+ }
96
+ }
97
+ function transferableDecode(obj) {
98
+ if (obj == null) return obj;
99
+ if (typeof obj === "object" && "__type__" in obj && "data" in obj) {
100
+ const typed = obj;
101
+ const data = typed.data;
102
+ if (typed.__type__ === "Date" && typeof data === "number") return new Date(data);
103
+ if (typed.__type__ === "DateTime" && typeof data === "number") return new DateTime(data);
104
+ if (typed.__type__ === "DateOnly" && typeof data === "number") return new DateOnly(data);
105
+ if (typed.__type__ === "Time" && typeof data === "number") return new Time(data);
106
+ if (typed.__type__ === "Uuid" && typeof data === "string") return new Uuid(data);
107
+ if (typed.__type__ === "RegExp" && typeof data === "object" && data !== null) {
108
+ const regexData = data;
109
+ return new RegExp(regexData.source, regexData.flags);
110
+ }
111
+ if (typed.__type__ === "Error" && typeof data === "object" && data !== null) {
112
+ const errorData = data;
113
+ const err = new Error(errorData.message);
114
+ err.name = errorData.name;
115
+ err.stack = errorData.stack;
116
+ if (errorData.code !== void 0) err.code = errorData.code;
117
+ if (errorData.cause !== void 0) err.cause = transferableDecode(errorData.cause);
118
+ if (errorData.detail !== void 0) err.detail = transferableDecode(errorData.detail);
119
+ return err;
120
+ }
121
+ }
122
+ if (Array.isArray(obj)) {
123
+ return obj.map((item) => transferableDecode(item));
124
+ }
125
+ if (obj instanceof Map) {
126
+ const newMap = /* @__PURE__ */ new Map();
127
+ for (const [k, v] of obj) {
128
+ newMap.set(transferableDecode(k), transferableDecode(v));
129
+ }
130
+ return newMap;
131
+ }
132
+ if (obj instanceof Set) {
133
+ const newSet = /* @__PURE__ */ new Set();
134
+ for (const v of obj) {
135
+ newSet.add(transferableDecode(v));
136
+ }
137
+ return newSet;
138
+ }
139
+ if (typeof obj === "object") {
140
+ const record = obj;
141
+ const result = {};
142
+ for (const key of Object.keys(record)) {
143
+ result[key] = transferableDecode(record[key]);
144
+ }
145
+ return result;
146
+ }
147
+ return obj;
148
+ }
149
+ export {
150
+ transferableDecode,
151
+ transferableEncode
152
+ };
153
+ //# sourceMappingURL=transferable.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/transferable.ts"],
4
+ "sourcesContent": ["import { DateTime } from \"../types/date-time\";\nimport { DateOnly } from \"../types/date-only\";\nimport { Time } from \"../types/time\";\nimport { Uuid } from \"../types/uuid\";\n\n/**\n * Worker \uAC04 \uC804\uC1A1 \uAC00\uB2A5\uD55C \uAC1D\uCCB4 \uD0C0\uC785\n *\n * \uC774 \uCF54\uB4DC\uC5D0\uC11C\uB294 ArrayBuffer\uB9CC \uC0AC\uC6A9\uB429\uB2C8\uB2E4.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects\n */\ntype Transferable = ArrayBuffer;\n\n/**\n * Transferable \uBCC0\uD658 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\n *\n * Worker \uAC04 \uB370\uC774\uD130 \uC804\uC1A1\uC744 \uC704\uD55C \uC9C1\uB82C\uD654/\uC5ED\uC9C1\uB82C\uD654\uB97C \uC218\uD589\uD569\uB2C8\uB2E4.\n * structuredClone\uC774 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uCEE4\uC2A4\uD140 \uD0C0\uC785\uB4E4\uC744 \uCC98\uB9AC\uD569\uB2C8\uB2E4.\n *\n * \uC9C0\uC6D0 \uD0C0\uC785:\n * - Date, DateTime, DateOnly, Time, Uuid, RegExp\n * - Error (cause, code, detail \uD3EC\uD568)\n * - Uint8Array (\uB2E4\uB978 TypedArray\uB294 \uBBF8\uC9C0\uC6D0, \uC77C\uBC18 \uAC1D\uCCB4\uB85C \uCC98\uB9AC\uB428)\n * - Array, Map, Set, \uC77C\uBC18 \uAC1D\uCCB4\n *\n * @note \uC21C\uD658 \uCC38\uC870\uAC00 \uC788\uC73C\uBA74 transferableEncode \uC2DC TypeError \uBC1C\uC0DD (\uACBD\uB85C \uC815\uBCF4 \uD3EC\uD568)\n * @note \uB3D9\uC77C \uAC1D\uCCB4\uAC00 \uC5EC\uB7EC \uACF3\uC5D0\uC11C \uCC38\uC870\uB418\uBA74 \uCE90\uC2DC\uB41C \uC778\uCF54\uB529 \uACB0\uACFC\uB97C \uC7AC\uC0AC\uC6A9\uD569\uB2C8\uB2E4\n *\n * @example\n * // Worker\uB85C \uB370\uC774\uD130 \uC804\uC1A1\n * const { result, transferList } = transferableEncode(data);\n * worker.postMessage(result, transferList);\n *\n * // Worker\uC5D0\uC11C \uB370\uC774\uD130 \uC218\uC2E0\n * const decoded = transferableDecode(event.data);\n */\n\n//#region encode\n\n/**\n * \uC2EC\uD50C\uB9AC\uC998 \uD0C0\uC785\uC744 \uC0AC\uC6A9\uD55C \uAC1D\uCCB4\uB97C \uC77C\uBC18 \uAC1D\uCCB4\uB85C \uBCC0\uD658\n * Worker\uC5D0 \uC804\uC1A1\uD560 \uC218 \uC788\uB294 \uD615\uD0DC\uB85C \uC9C1\uB82C\uD654\n *\n * @throws \uC21C\uD658 \uCC38\uC870 \uAC10\uC9C0 \uC2DC TypeError\n */\nexport function transferableEncode(obj: unknown): {\n result: unknown;\n transferList: Transferable[];\n} {\n const transferList: Transferable[] = [];\n const ancestors = new Set<object>();\n const cache = new Map<object, unknown>();\n const result = encodeImpl(obj, transferList, [], ancestors, cache);\n return { result, transferList };\n}\n\nfunction encodeImpl(\n obj: unknown,\n transferList: Transferable[],\n path: (string | number)[],\n ancestors: Set<object>,\n cache: Map<object, unknown>,\n): unknown {\n if (obj == null) return obj;\n\n // \uAC1D\uCCB4 \uD0C0\uC785 \uCC98\uB9AC: \uC21C\uD658 \uAC10\uC9C0 + \uCE90\uC2DC\n if (typeof obj === \"object\") {\n // \uC21C\uD658 \uCC38\uC870 \uAC10\uC9C0 (\uD604\uC7AC \uC7AC\uADC0 \uC2A4\uD0DD\uC5D0 \uC788\uB294 \uAC1D\uCCB4)\n if (ancestors.has(obj)) {\n const currentPath = path.length > 0 ? path.join(\".\") : \"root\";\n throw new TypeError(`\uC21C\uD658 \uCC38\uC870\uAC00 \uAC10\uC9C0\uB418\uC5C8\uC2B5\uB2C8\uB2E4: ${currentPath}`);\n }\n\n // \uCE90\uC2DC \uD788\uD2B8 \u2192 \uC774\uC804 \uC778\uCF54\uB529 \uACB0\uACFC \uC7AC\uC0AC\uC6A9\n const cached = cache.get(obj);\n if (cached !== undefined) return cached;\n\n // \uC7AC\uADC0 \uC2A4\uD0DD\uC5D0 \uCD94\uAC00\n ancestors.add(obj);\n }\n\n let result: unknown;\n\n try {\n // 1. Uint8Array\n if (obj instanceof Uint8Array) {\n // SharedArrayBuffer\uB294 \uC774\uBBF8 \uACF5\uC720 \uBA54\uBAA8\uB9AC\uC774\uBBC0\uB85C transferList\uC5D0 \uCD94\uAC00\uD558\uC9C0 \uC54A\uC74C\n // ArrayBuffer\uB9CC transferList\uC5D0 \uCD94\uAC00\n const isSharedArrayBuffer = typeof SharedArrayBuffer !== \"undefined\" && obj.buffer instanceof SharedArrayBuffer;\n const buffer = obj.buffer as ArrayBuffer;\n if (!isSharedArrayBuffer && !transferList.includes(buffer)) {\n transferList.push(buffer);\n }\n result = obj;\n }\n // 2. \uD2B9\uC218 \uD0C0\uC785 \uBCC0\uD658 (JSON.stringify \uC5C6\uC774 \uAD6C\uC870\uCCB4\uB85C \uBCC0\uD658)\n else if (obj instanceof Date) {\n result = { __type__: \"Date\", data: obj.getTime() };\n } else if (obj instanceof DateTime) {\n result = { __type__: \"DateTime\", data: obj.tick };\n } else if (obj instanceof DateOnly) {\n result = { __type__: \"DateOnly\", data: obj.tick };\n } else if (obj instanceof Time) {\n result = { __type__: \"Time\", data: obj.tick };\n } else if (obj instanceof Uuid) {\n result = { __type__: \"Uuid\", data: obj.toString() };\n } else if (obj instanceof RegExp) {\n result = { __type__: \"RegExp\", data: { source: obj.source, flags: obj.flags } };\n } else if (obj instanceof Error) {\n const errObj = obj as Error & {\n code?: unknown;\n detail?: unknown;\n };\n result = {\n __type__: \"Error\",\n data: {\n name: errObj.name,\n message: errObj.message,\n stack: errObj.stack,\n ...(errObj.code !== undefined ? { code: errObj.code } : {}),\n ...(errObj.detail !== undefined\n ? { detail: encodeImpl(errObj.detail, transferList, [...path, \"detail\"], ancestors, cache) }\n : {}),\n ...(errObj.cause !== undefined\n ? { cause: encodeImpl(errObj.cause, transferList, [...path, \"cause\"], ancestors, cache) }\n : {}),\n },\n };\n }\n // 3. \uBC30\uC5F4 \uC7AC\uADC0 \uC21C\uD68C\n else if (Array.isArray(obj)) {\n result = obj.map((item, idx) => encodeImpl(item, transferList, [...path, idx], ancestors, cache));\n }\n // 4. Map \uC7AC\uADC0 \uC21C\uD68C\n else if (obj instanceof Map) {\n let idx = 0;\n result = new Map(\n Array.from(obj.entries()).map(([k, v]) => {\n const keyPath = [...path, `Map[${idx}].key`];\n const valuePath = [...path, `Map[${idx}].value`];\n idx++;\n return [\n encodeImpl(k, transferList, keyPath, ancestors, cache),\n encodeImpl(v, transferList, valuePath, ancestors, cache),\n ];\n }),\n );\n }\n // 5. Set \uC7AC\uADC0 \uC21C\uD68C\n else if (obj instanceof Set) {\n let idx = 0;\n result = new Set(\n Array.from(obj).map((v) => encodeImpl(v, transferList, [...path, `Set[${idx++}]`], ancestors, cache)),\n );\n }\n // 6. \uC77C\uBC18 \uAC1D\uCCB4 \uC7AC\uADC0 \uC21C\uD68C\n else if (typeof obj === \"object\") {\n const res: Record<string, unknown> = {};\n const record = obj as Record<string, unknown>;\n for (const key of Object.keys(record)) {\n res[key] = encodeImpl(record[key], transferList, [...path, key], ancestors, cache);\n }\n result = res;\n }\n // 7. \uC6D0\uC2DC \uD0C0\uC785\n else {\n return obj;\n }\n\n // \uCE90\uC2DC \uC800\uC7A5 (\uC131\uACF5 \uC2DC\uC5D0\uB9CC)\n if (typeof obj === \"object\") {\n cache.set(obj, result);\n }\n\n return result;\n } finally {\n // \uC7AC\uADC0 \uC2A4\uD0DD\uC5D0\uC11C \uC81C\uAC70 (\uC608\uC678 \uC2DC\uC5D0\uB3C4 \uBC18\uB4DC\uC2DC \uC2E4\uD589)\n if (typeof obj === \"object\") {\n ancestors.delete(obj);\n }\n }\n}\n\n//#endregion\n\n//#region decode\n\n/**\n * serialize \uAC1D\uCCB4\uB97C \uC2EC\uD50C\uB9AC\uC998 \uD0C0\uC785 \uC0AC\uC6A9 \uAC1D\uCCB4\uB85C \uBCC0\uD658\n * Worker\uB85C\uBD80\uD130 \uBC1B\uC740 \uB370\uC774\uD130\uB97C \uC5ED\uC9C1\uB82C\uD654\n */\nexport function transferableDecode(obj: unknown): unknown {\n if (obj == null) return obj;\n\n // 1. \uD2B9\uC218 \uD0C0\uC785 \uBCF5\uC6D0\n if (typeof obj === \"object\" && \"__type__\" in obj && \"data\" in obj) {\n const typed = obj as { __type__: string; data: unknown };\n const data = typed.data;\n\n if (typed.__type__ === \"Date\" && typeof data === \"number\") return new Date(data);\n if (typed.__type__ === \"DateTime\" && typeof data === \"number\") return new DateTime(data);\n if (typed.__type__ === \"DateOnly\" && typeof data === \"number\") return new DateOnly(data);\n if (typed.__type__ === \"Time\" && typeof data === \"number\") return new Time(data);\n if (typed.__type__ === \"Uuid\" && typeof data === \"string\") return new Uuid(data);\n if (typed.__type__ === \"RegExp\" && typeof data === \"object\" && data !== null) {\n const regexData = data as { source: string; flags: string };\n return new RegExp(regexData.source, regexData.flags);\n }\n if (typed.__type__ === \"Error\" && typeof data === \"object\" && data !== null) {\n const errorData = data as {\n name: string;\n message: string;\n stack?: string;\n code?: unknown;\n cause?: unknown;\n detail?: unknown;\n };\n const err = new Error(errorData.message) as Error & {\n code?: unknown;\n detail?: unknown;\n };\n\n err.name = errorData.name;\n err.stack = errorData.stack;\n\n if (errorData.code !== undefined) err.code = errorData.code;\n if (errorData.cause !== undefined) (err as Error).cause = transferableDecode(errorData.cause);\n if (errorData.detail !== undefined) err.detail = transferableDecode(errorData.detail);\n return err;\n }\n }\n\n // 2. \uBC30\uC5F4 \uC7AC\uADC0 (\uC0C8 \uBC30\uC5F4 \uC0DD\uC131)\n if (Array.isArray(obj)) {\n return obj.map((item) => transferableDecode(item));\n }\n\n // 3. Map \uC7AC\uADC0\n if (obj instanceof Map) {\n const newMap = new Map<unknown, unknown>();\n for (const [k, v] of obj) {\n newMap.set(transferableDecode(k), transferableDecode(v));\n }\n return newMap;\n }\n\n // 4. Set \uC7AC\uADC0\n if (obj instanceof Set) {\n const newSet = new Set<unknown>();\n for (const v of obj) {\n newSet.add(transferableDecode(v));\n }\n return newSet;\n }\n\n // 5. \uAC1D\uCCB4 \uC7AC\uADC0 (\uC0C8 \uAC1D\uCCB4 \uC0DD\uC131)\n if (typeof obj === \"object\") {\n const record = obj as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(record)) {\n result[key] = transferableDecode(record[key]);\n }\n return result;\n }\n\n return obj;\n}\n\n//#endregion\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 조건이 참이 될 때까지 대기
3
+ * @param forwarder 조건 함수
4
+ * @param milliseconds 체크 간격 (기본: 100ms)
5
+ * @param maxCount 최대 시도 횟수 (undefined면 무제한)
6
+ *
7
+ * @note 조건이 첫 번째 호출에서 true면 즉시 반환됩니다.
8
+ * @example
9
+ * // maxCount=3: 최대 3번 조건 확인 후 모두 false면 TimeoutError
10
+ * await waitUntil(() => someCondition, 100, 3);
11
+ * @throws TimeoutError 최대 시도 횟수 초과 시
12
+ */
13
+ export declare function waitUntil(forwarder: () => boolean | Promise<boolean>, milliseconds?: number, maxCount?: number): Promise<void>;
14
+ /**
15
+ * 지정된 시간만큼 대기
16
+ * @param millisecond 대기 시간 (ms)
17
+ */
18
+ export declare function waitTime(millisecond: number): Promise<void>;
19
+ //# sourceMappingURL=wait.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait.d.ts","sourceRoot":"","sources":["../../src/utils/wait.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;GAWG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EAC3C,YAAY,CAAC,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE"}
@@ -0,0 +1,19 @@
1
+ import { TimeoutError } from "../errors/timeout-error";
2
+ async function waitUntil(forwarder, milliseconds, maxCount) {
3
+ let count = 0;
4
+ while (!await forwarder()) {
5
+ count++;
6
+ if (maxCount !== void 0 && count >= maxCount) {
7
+ throw new TimeoutError(count);
8
+ }
9
+ await waitTime(milliseconds ?? 100);
10
+ }
11
+ }
12
+ async function waitTime(millisecond) {
13
+ return new Promise((resolve) => setTimeout(resolve, millisecond));
14
+ }
15
+ export {
16
+ waitTime,
17
+ waitUntil
18
+ };
19
+ //# sourceMappingURL=wait.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/wait.ts"],
4
+ "sourcesContent": ["/**\n * \uB300\uAE30 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\n */\nimport { TimeoutError } from \"../errors/timeout-error\";\n\n/**\n * \uC870\uAC74\uC774 \uCC38\uC774 \uB420 \uB54C\uAE4C\uC9C0 \uB300\uAE30\n * @param forwarder \uC870\uAC74 \uD568\uC218\n * @param milliseconds \uCCB4\uD06C \uAC04\uACA9 (\uAE30\uBCF8: 100ms)\n * @param maxCount \uCD5C\uB300 \uC2DC\uB3C4 \uD69F\uC218 (undefined\uBA74 \uBB34\uC81C\uD55C)\n *\n * @note \uC870\uAC74\uC774 \uCCAB \uBC88\uC9F8 \uD638\uCD9C\uC5D0\uC11C true\uBA74 \uC989\uC2DC \uBC18\uD658\uB429\uB2C8\uB2E4.\n * @example\n * // maxCount=3: \uCD5C\uB300 3\uBC88 \uC870\uAC74 \uD655\uC778 \uD6C4 \uBAA8\uB450 false\uBA74 TimeoutError\n * await waitUntil(() => someCondition, 100, 3);\n * @throws TimeoutError \uCD5C\uB300 \uC2DC\uB3C4 \uD69F\uC218 \uCD08\uACFC \uC2DC\n */\nexport async function waitUntil(\n forwarder: () => boolean | Promise<boolean>,\n milliseconds?: number,\n maxCount?: number,\n): Promise<void> {\n let count = 0;\n while (!(await forwarder())) {\n count++;\n if (maxCount !== undefined && count >= maxCount) {\n throw new TimeoutError(count);\n }\n\n await waitTime(milliseconds ?? 100);\n }\n}\n\n/**\n * \uC9C0\uC815\uB41C \uC2DC\uAC04\uB9CC\uD07C \uB300\uAE30\n * @param millisecond \uB300\uAE30 \uC2DC\uAC04 (ms)\n */\nexport async function waitTime(millisecond: number): Promise<void> {\n return new Promise<void>((resolve) => setTimeout(resolve, millisecond));\n}\n"],
5
+ "mappings": "AAGA,SAAS,oBAAoB;AAc7B,eAAsB,UACpB,WACA,cACA,UACe;AACf,MAAI,QAAQ;AACZ,SAAO,CAAE,MAAM,UAAU,GAAI;AAC3B;AACA,QAAI,aAAa,UAAa,SAAS,UAAU;AAC/C,YAAM,IAAI,aAAa,KAAK;AAAA,IAC9B;AAEA,UAAM,SAAS,gBAAgB,GAAG;AAAA,EACpC;AACF;AAMA,eAAsB,SAAS,aAAoC;AACjE,SAAO,IAAI,QAAc,CAAC,YAAY,WAAW,SAAS,WAAW,CAAC;AACxE;",
6
+ "names": []
7
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * XML 변환 유틸리티
3
+ */
4
+ import type { XmlBuilderOptions } from "fast-xml-parser";
5
+ /**
6
+ * XML 문자열을 객체로 파싱
7
+ * @param str XML 문자열
8
+ * @param options 옵션
9
+ * @param options.stripTagPrefix 태그 prefix 제거 여부 (namespace)
10
+ * @returns 파싱된 객체. 구조:
11
+ * - 속성: `$` 객체에 그룹화
12
+ * - 텍스트 노드: `_` 키에 저장
13
+ * - 자식 요소: 배열로 변환 (루트 요소 제외)
14
+ * @example
15
+ * xmlParse('<root id="1"><item>hello</item></root>');
16
+ * // { root: { $: { id: "1" }, item: [{ _: "hello" }] } }
17
+ */
18
+ export declare function xmlParse(str: string, options?: {
19
+ stripTagPrefix?: boolean;
20
+ }): unknown;
21
+ /**
22
+ * 객체를 XML 문자열로 직렬화
23
+ * @param obj 직렬화할 객체
24
+ * @param options fast-xml-parser XmlBuilderOptions (선택)
25
+ * @returns XML 문자열
26
+ * @example
27
+ * xmlStringify({
28
+ * root: {
29
+ * $: { id: "1" },
30
+ * item: [{ _: "hello" }, { _: "world" }],
31
+ * },
32
+ * });
33
+ * // '<root id="1"><item>hello</item><item>world</item></root>'
34
+ */
35
+ export declare function xmlStringify(obj: unknown, options?: XmlBuilderOptions): string;
36
+ //# sourceMappingURL=xml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xml.d.ts","sourceRoot":"","sources":["../../src/utils/xml.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAKzD;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAarF;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAS9E"}
@@ -0,0 +1,51 @@
1
+ import { XMLBuilder, XMLParser } from "fast-xml-parser";
2
+ function xmlParse(str, options) {
3
+ const result = new XMLParser({
4
+ ignoreAttributes: false,
5
+ attributeNamePrefix: "",
6
+ attributesGroupName: "$",
7
+ parseAttributeValue: false,
8
+ parseTagValue: false,
9
+ textNodeName: "_",
10
+ isArray: (_tagName, jPath, _isLeafNode, isAttribute) => {
11
+ return !isAttribute && jPath.split(".").length > 1;
12
+ }
13
+ }).parse(str);
14
+ return (options == null ? void 0 : options.stripTagPrefix) ? stripTagPrefix(result) : result;
15
+ }
16
+ function xmlStringify(obj, options) {
17
+ return new XMLBuilder({
18
+ ignoreAttributes: false,
19
+ attributeNamePrefix: "",
20
+ attributesGroupName: "$",
21
+ suppressBooleanAttributes: false,
22
+ textNodeName: "_",
23
+ ...options
24
+ }).build(obj);
25
+ }
26
+ function stripTagPrefix(obj) {
27
+ if (Array.isArray(obj)) {
28
+ return obj.map((item) => stripTagPrefix(item));
29
+ }
30
+ if (typeof obj === "object" && obj !== null) {
31
+ const newObj = {};
32
+ const record = obj;
33
+ for (const key of Object.keys(record)) {
34
+ const value = record[key];
35
+ if (key === "$") {
36
+ newObj[key] = value;
37
+ } else {
38
+ const colonIndex = key.indexOf(":");
39
+ const cleanKey = colonIndex !== -1 ? key.slice(colonIndex + 1) : key;
40
+ newObj[cleanKey] = stripTagPrefix(value);
41
+ }
42
+ }
43
+ return newObj;
44
+ }
45
+ return obj;
46
+ }
47
+ export {
48
+ xmlParse,
49
+ xmlStringify
50
+ };
51
+ //# sourceMappingURL=xml.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/xml.ts"],
4
+ "sourcesContent": ["/**\n * XML \uBCC0\uD658 \uC720\uD2F8\uB9AC\uD2F0\n */\nimport type { XmlBuilderOptions } from \"fast-xml-parser\";\nimport { XMLBuilder, XMLParser } from \"fast-xml-parser\";\n\n//#region parse\n\n/**\n * XML \uBB38\uC790\uC5F4\uC744 \uAC1D\uCCB4\uB85C \uD30C\uC2F1\n * @param str XML \uBB38\uC790\uC5F4\n * @param options \uC635\uC158\n * @param options.stripTagPrefix \uD0DC\uADF8 prefix \uC81C\uAC70 \uC5EC\uBD80 (namespace)\n * @returns \uD30C\uC2F1\uB41C \uAC1D\uCCB4. \uAD6C\uC870:\n * - \uC18D\uC131: `$` \uAC1D\uCCB4\uC5D0 \uADF8\uB8F9\uD654\n * - \uD14D\uC2A4\uD2B8 \uB178\uB4DC: `_` \uD0A4\uC5D0 \uC800\uC7A5\n * - \uC790\uC2DD \uC694\uC18C: \uBC30\uC5F4\uB85C \uBCC0\uD658 (\uB8E8\uD2B8 \uC694\uC18C \uC81C\uC678)\n * @example\n * xmlParse('<root id=\"1\"><item>hello</item></root>');\n * // { root: { $: { id: \"1\" }, item: [{ _: \"hello\" }] } }\n */\nexport function xmlParse(str: string, options?: { stripTagPrefix?: boolean }): unknown {\n const result = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"\",\n attributesGroupName: \"$\",\n parseAttributeValue: false,\n parseTagValue: false,\n textNodeName: \"_\",\n isArray: (_tagName: string, jPath: string, _isLeafNode: boolean, isAttribute: boolean) => {\n return !isAttribute && jPath.split(\".\").length > 1;\n },\n }).parse(str) as unknown;\n return options?.stripTagPrefix ? stripTagPrefix(result) : result;\n}\n\n//#endregion\n\n//#region stringify\n\n/**\n * \uAC1D\uCCB4\uB97C XML \uBB38\uC790\uC5F4\uB85C \uC9C1\uB82C\uD654\n * @param obj \uC9C1\uB82C\uD654\uD560 \uAC1D\uCCB4\n * @param options fast-xml-parser XmlBuilderOptions (\uC120\uD0DD)\n * @returns XML \uBB38\uC790\uC5F4\n * @example\n * xmlStringify({\n * root: {\n * $: { id: \"1\" },\n * item: [{ _: \"hello\" }, { _: \"world\" }],\n * },\n * });\n * // '<root id=\"1\"><item>hello</item><item>world</item></root>'\n */\nexport function xmlStringify(obj: unknown, options?: XmlBuilderOptions): string {\n return new XMLBuilder({\n ignoreAttributes: false,\n attributeNamePrefix: \"\",\n attributesGroupName: \"$\",\n suppressBooleanAttributes: false,\n textNodeName: \"_\",\n ...options,\n }).build(obj);\n}\n\n//#endregion\n\n//#region private\n\n/**\n * \uD0DC\uADF8 \uC774\uB984\uC5D0\uC11C namespace prefix \uC81C\uAC70\n * @note XML \uD30C\uC2F1 \uACB0\uACFC\uC5D0\uC11C \"ns:tag\" \uD615\uD0DC\uC758 namespace prefix\uB97C \uC81C\uAC70\uD558\uC5EC \uD0DC\uADF8 \uC774\uB984\uB9CC \uB0A8\uAE34\uB2E4.\n * \uC774\uB97C \uD1B5\uD574 namespace\uB97C \uACE0\uB824\uD558\uC9C0 \uC54A\uACE0 \uC77C\uAD00\uB41C \uBC29\uC2DD\uC73C\uB85C XML \uB370\uC774\uD130\uC5D0 \uC811\uADFC\uD560 \uC218 \uC788\uB2E4.\n * \uB2E8, \uC18D\uC131(attribute)\uC740 prefix\uB97C \uC720\uC9C0\uD55C\uB2E4.\n */\nfunction stripTagPrefix(obj: unknown): unknown {\n if (Array.isArray(obj)) {\n return obj.map((item) => stripTagPrefix(item));\n }\n\n if (typeof obj === \"object\" && obj !== null) {\n const newObj: Record<string, unknown> = {};\n const record = obj as Record<string, unknown>;\n\n for (const key of Object.keys(record)) {\n const value = record[key];\n\n // Attribute\uB294 prefix\uB97C \uC81C\uAC70\uD558\uBA74 \uC548 \uB41C\uB2E4.\n if (key === \"$\") {\n newObj[key] = value;\n } else {\n // \uD0DC\uADF8 \uC774\uB984\uC5D0\uC11C\uB9CC \uCCAB \uBC88\uC9F8 \":\"\uC744 \uAE30\uC900\uC73C\uB85C prefix \uC81C\uAC70\n const colonIndex = key.indexOf(\":\");\n const cleanKey = colonIndex !== -1 ? key.slice(colonIndex + 1) : key;\n newObj[cleanKey] = stripTagPrefix(value);\n }\n }\n\n return newObj;\n }\n\n return obj;\n}\n\n//#endregion\n"],
5
+ "mappings": "AAIA,SAAS,YAAY,iBAAiB;AAiB/B,SAAS,SAAS,KAAa,SAAiD;AACrF,QAAM,SAAS,IAAI,UAAU;AAAA,IAC3B,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,IACrB,qBAAqB;AAAA,IACrB,qBAAqB;AAAA,IACrB,eAAe;AAAA,IACf,cAAc;AAAA,IACd,SAAS,CAAC,UAAkB,OAAe,aAAsB,gBAAyB;AACxF,aAAO,CAAC,eAAe,MAAM,MAAM,GAAG,EAAE,SAAS;AAAA,IACnD;AAAA,EACF,CAAC,EAAE,MAAM,GAAG;AACZ,UAAO,mCAAS,kBAAiB,eAAe,MAAM,IAAI;AAC5D;AAoBO,SAAS,aAAa,KAAc,SAAqC;AAC9E,SAAO,IAAI,WAAW;AAAA,IACpB,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,IACrB,qBAAqB;AAAA,IACrB,2BAA2B;AAAA,IAC3B,cAAc;AAAA,IACd,GAAG;AAAA,EACL,CAAC,EAAE,MAAM,GAAG;AACd;AAYA,SAAS,eAAe,KAAuB;AAC7C,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO,IAAI,IAAI,CAAC,SAAS,eAAe,IAAI,CAAC;AAAA,EAC/C;AAEA,MAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,UAAM,SAAkC,CAAC;AACzC,UAAM,SAAS;AAEf,eAAW,OAAO,OAAO,KAAK,MAAM,GAAG;AACrC,YAAM,QAAQ,OAAO,GAAG;AAGxB,UAAI,QAAQ,KAAK;AACf,eAAO,GAAG,IAAI;AAAA,MAChB,OAAO;AAEL,cAAM,aAAa,IAAI,QAAQ,GAAG;AAClC,cAAM,WAAW,eAAe,KAAK,IAAI,MAAM,aAAa,CAAC,IAAI;AACjE,eAAO,QAAQ,IAAI,eAAe,KAAK;AAAA,MACzC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,80 @@
1
+ import type { Bytes } from "../common.types";
2
+ export interface ZipArchiveProgress {
3
+ fileName: string;
4
+ totalSize: number;
5
+ extractedSize: number;
6
+ }
7
+ /**
8
+ * ZIP 아카이브 처리 클래스
9
+ *
10
+ * ZIP 파일의 읽기, 쓰기, 압축/해제를 처리합니다.
11
+ * 내부 캐시를 사용하여 동일 파일의 중복 압축 해제를 방지합니다.
12
+ *
13
+ * @example
14
+ * // ZIP 파일 읽기
15
+ * await using archive = new ZipArchive(zipBytes);
16
+ * const content = await archive.get("file.txt");
17
+ *
18
+ * @example
19
+ * // ZIP 파일 생성
20
+ * await using archive = new ZipArchive();
21
+ * archive.write("file.txt", textBytes);
22
+ * archive.write("data.json", jsonBytes);
23
+ * const zipBytes = await archive.compress();
24
+ *
25
+ * @example
26
+ * // 전체 압축 해제 (진행률 표시)
27
+ * await using archive = new ZipArchive(zipBytes);
28
+ * const files = await archive.extractAll((progress) => {
29
+ * console.log(`${progress.fileName}: ${progress.extractedSize}/${progress.totalSize}`);
30
+ * });
31
+ */
32
+ export declare class ZipArchive {
33
+ private readonly _reader?;
34
+ private readonly _cache;
35
+ private _entries?;
36
+ /**
37
+ * ZipArchive 생성
38
+ * @param data ZIP 데이터 (생략 시 새 아카이브 생성)
39
+ */
40
+ constructor(data?: Blob | Bytes);
41
+ private _getEntries;
42
+ /**
43
+ * 모든 파일을 압축 해제
44
+ * @param progressCallback 진행률 콜백
45
+ */
46
+ extractAll(progressCallback?: (progress: ZipArchiveProgress) => void): Promise<Map<string, Bytes | undefined>>;
47
+ /**
48
+ * 특정 파일 압축 해제
49
+ * @param fileName 파일 이름
50
+ */
51
+ get(fileName: string): Promise<Bytes | undefined>;
52
+ /**
53
+ * 파일 존재 여부 확인
54
+ * @param fileName 파일 이름
55
+ */
56
+ exists(fileName: string): Promise<boolean>;
57
+ /**
58
+ * 파일 쓰기 (캐시에 저장)
59
+ * @param fileName 파일 이름
60
+ * @param bytes 파일 내용
61
+ */
62
+ write(fileName: string, bytes: Bytes): void;
63
+ /**
64
+ * 캐시된 파일들을 ZIP으로 압축
65
+ *
66
+ * @remarks
67
+ * 내부적으로 `extractAll()`을 호출하여 모든 파일을 메모리에 로드한 후 압축합니다.
68
+ * 대용량 ZIP 파일의 경우 메모리 사용량에 주의가 필요합니다.
69
+ */
70
+ compress(): Promise<Bytes>;
71
+ /**
72
+ * 리더 닫기 및 캐시 정리
73
+ */
74
+ close(): Promise<void>;
75
+ /**
76
+ * await using 지원
77
+ */
78
+ [Symbol.asyncDispose](): Promise<void>;
79
+ }
80
+ //# sourceMappingURL=sd-zip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sd-zip.d.ts","sourceRoot":"","sources":["../../src/zip/sd-zip.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,QAAQ,CAAC,CAA6D;IAE9E;;;OAGG;gBACS,IAAI,CAAC,EAAE,IAAI,GAAG,KAAK;YAUjB,WAAW;IAQzB;;;OAGG;IACG,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,GAAG,SAAS,CAAC,CAAC;IAkDpH;;;OAGG;IACG,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;IAwBvD;;;OAGG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBhD;;;;OAIG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAM3C;;;;;;OAMG;IACG,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC;IAiBhC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B;;OAEG;IACG,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7C"}
@@ -0,0 +1,153 @@
1
+ import { BlobReader, Uint8ArrayReader, Uint8ArrayWriter, ZipReader, ZipWriter } from "@zip.js/zip.js";
2
+ class ZipArchive {
3
+ _reader;
4
+ _cache = /* @__PURE__ */ new Map();
5
+ _entries;
6
+ /**
7
+ * ZipArchive 생성
8
+ * @param data ZIP 데이터 (생략 시 새 아카이브 생성)
9
+ */
10
+ constructor(data) {
11
+ if (!data) return;
12
+ if (data instanceof Uint8Array) {
13
+ this._reader = new ZipReader(new Uint8ArrayReader(data));
14
+ } else {
15
+ this._reader = new ZipReader(new BlobReader(data));
16
+ }
17
+ }
18
+ async _getEntries() {
19
+ if (this._entries == null && this._reader != null) {
20
+ this._entries = await this._reader.getEntries();
21
+ }
22
+ return this._entries;
23
+ }
24
+ //#region extractAll
25
+ /**
26
+ * 모든 파일을 압축 해제
27
+ * @param progressCallback 진행률 콜백
28
+ */
29
+ async extractAll(progressCallback) {
30
+ const entries = await this._getEntries();
31
+ if (entries == null) return this._cache;
32
+ const totalSize = entries.filter((e) => !e.directory).reduce((acc, e) => acc + e.uncompressedSize, 0);
33
+ let totalExtracted = 0;
34
+ for (const entry of entries) {
35
+ if (entry.directory) continue;
36
+ progressCallback == null ? void 0 : progressCallback({
37
+ fileName: entry.filename,
38
+ totalSize,
39
+ extractedSize: totalExtracted
40
+ });
41
+ const entryBytes = this._cache.get(entry.filename) ?? await entry.getData(new Uint8ArrayWriter(), {
42
+ onprogress: (extracted) => {
43
+ const currentTotal = totalExtracted + extracted;
44
+ progressCallback == null ? void 0 : progressCallback({
45
+ fileName: entry.filename,
46
+ totalSize,
47
+ extractedSize: currentTotal
48
+ });
49
+ return void 0;
50
+ }
51
+ });
52
+ this._cache.set(entry.filename, entryBytes);
53
+ totalExtracted += entry.uncompressedSize;
54
+ progressCallback == null ? void 0 : progressCallback({
55
+ fileName: entry.filename,
56
+ totalSize,
57
+ extractedSize: totalExtracted
58
+ });
59
+ }
60
+ return this._cache;
61
+ }
62
+ //#endregion
63
+ //#region get
64
+ /**
65
+ * 특정 파일 압축 해제
66
+ * @param fileName 파일 이름
67
+ */
68
+ async get(fileName) {
69
+ if (this._cache.has(fileName)) {
70
+ return this._cache.get(fileName);
71
+ }
72
+ const entries = await this._getEntries();
73
+ if (entries == null) {
74
+ this._cache.set(fileName, void 0);
75
+ return void 0;
76
+ }
77
+ const entry = entries.find((item) => item.filename === fileName);
78
+ if (!entry) {
79
+ this._cache.set(fileName, void 0);
80
+ return void 0;
81
+ }
82
+ const bytes = await entry.getData(new Uint8ArrayWriter());
83
+ this._cache.set(fileName, bytes);
84
+ return bytes;
85
+ }
86
+ //#endregion
87
+ //#region exists
88
+ /**
89
+ * 파일 존재 여부 확인
90
+ * @param fileName 파일 이름
91
+ */
92
+ async exists(fileName) {
93
+ if (this._cache.has(fileName)) {
94
+ return this._cache.get(fileName) != null;
95
+ }
96
+ const entries = await this._getEntries();
97
+ if (entries == null) {
98
+ return false;
99
+ }
100
+ const entry = entries.find((item) => item.filename === fileName);
101
+ return entry !== void 0;
102
+ }
103
+ //#endregion
104
+ //#region write
105
+ /**
106
+ * 파일 쓰기 (캐시에 저장)
107
+ * @param fileName 파일 이름
108
+ * @param bytes 파일 내용
109
+ */
110
+ write(fileName, bytes) {
111
+ this._cache.set(fileName, bytes);
112
+ }
113
+ //#endregion
114
+ //#region compress
115
+ /**
116
+ * 캐시된 파일들을 ZIP으로 압축
117
+ *
118
+ * @remarks
119
+ * 내부적으로 `extractAll()`을 호출하여 모든 파일을 메모리에 로드한 후 압축합니다.
120
+ * 대용량 ZIP 파일의 경우 메모리 사용량에 주의가 필요합니다.
121
+ */
122
+ async compress() {
123
+ const fileMap = await this.extractAll();
124
+ const writer = new ZipWriter(new Uint8ArrayWriter());
125
+ for (const key of fileMap.keys()) {
126
+ const fileBytes = fileMap.get(key);
127
+ if (!fileBytes) continue;
128
+ await writer.add(key, new Uint8ArrayReader(fileBytes));
129
+ }
130
+ return writer.close();
131
+ }
132
+ //#endregion
133
+ //#region close
134
+ /**
135
+ * 리더 닫기 및 캐시 정리
136
+ */
137
+ async close() {
138
+ var _a;
139
+ await ((_a = this._reader) == null ? void 0 : _a.close());
140
+ this._cache.clear();
141
+ }
142
+ /**
143
+ * await using 지원
144
+ */
145
+ async [Symbol.asyncDispose]() {
146
+ await this.close();
147
+ }
148
+ //#endregion
149
+ }
150
+ export {
151
+ ZipArchive
152
+ };
153
+ //# sourceMappingURL=sd-zip.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/zip/sd-zip.ts"],
4
+ "sourcesContent": ["/**\n * ZIP \uD30C\uC77C \uCC98\uB9AC \uC720\uD2F8\uB9AC\uD2F0\n */\nimport type { FileEntry } from \"@zip.js/zip.js\";\nimport { BlobReader, Uint8ArrayReader, Uint8ArrayWriter, ZipReader, ZipWriter } from \"@zip.js/zip.js\";\nimport type { Bytes } from \"../common.types\";\n\nexport interface ZipArchiveProgress {\n fileName: string;\n totalSize: number;\n extractedSize: number;\n}\n\n/**\n * ZIP \uC544\uCE74\uC774\uBE0C \uCC98\uB9AC \uD074\uB798\uC2A4\n *\n * ZIP \uD30C\uC77C\uC758 \uC77D\uAE30, \uC4F0\uAE30, \uC555\uCD95/\uD574\uC81C\uB97C \uCC98\uB9AC\uD569\uB2C8\uB2E4.\n * \uB0B4\uBD80 \uCE90\uC2DC\uB97C \uC0AC\uC6A9\uD558\uC5EC \uB3D9\uC77C \uD30C\uC77C\uC758 \uC911\uBCF5 \uC555\uCD95 \uD574\uC81C\uB97C \uBC29\uC9C0\uD569\uB2C8\uB2E4.\n *\n * @example\n * // ZIP \uD30C\uC77C \uC77D\uAE30\n * await using archive = new ZipArchive(zipBytes);\n * const content = await archive.get(\"file.txt\");\n *\n * @example\n * // ZIP \uD30C\uC77C \uC0DD\uC131\n * await using archive = new ZipArchive();\n * archive.write(\"file.txt\", textBytes);\n * archive.write(\"data.json\", jsonBytes);\n * const zipBytes = await archive.compress();\n *\n * @example\n * // \uC804\uCCB4 \uC555\uCD95 \uD574\uC81C (\uC9C4\uD589\uB960 \uD45C\uC2DC)\n * await using archive = new ZipArchive(zipBytes);\n * const files = await archive.extractAll((progress) => {\n * console.log(`${progress.fileName}: ${progress.extractedSize}/${progress.totalSize}`);\n * });\n */\nexport class ZipArchive {\n private readonly _reader?: ZipReader<Blob | Bytes>;\n private readonly _cache = new Map<string, Bytes | undefined>();\n private _entries?: Awaited<ReturnType<ZipReader<Blob | Bytes>[\"getEntries\"]>>;\n\n /**\n * ZipArchive \uC0DD\uC131\n * @param data ZIP \uB370\uC774\uD130 (\uC0DD\uB7B5 \uC2DC \uC0C8 \uC544\uCE74\uC774\uBE0C \uC0DD\uC131)\n */\n constructor(data?: Blob | Bytes) {\n if (!data) return;\n\n if (data instanceof Uint8Array) {\n this._reader = new ZipReader(new Uint8ArrayReader(data));\n } else {\n this._reader = new ZipReader(new BlobReader(data));\n }\n }\n\n private async _getEntries() {\n if (this._entries == null && this._reader != null) {\n this._entries = await this._reader.getEntries();\n }\n return this._entries;\n }\n\n //#region extractAll\n /**\n * \uBAA8\uB4E0 \uD30C\uC77C\uC744 \uC555\uCD95 \uD574\uC81C\n * @param progressCallback \uC9C4\uD589\uB960 \uCF5C\uBC31\n */\n async extractAll(progressCallback?: (progress: ZipArchiveProgress) => void): Promise<Map<string, Bytes | undefined>> {\n const entries = await this._getEntries();\n if (entries == null) return this._cache;\n\n // \uC555\uCD95 \uD574\uC81C \uB300\uC0C1 \uD06C\uAE30 \uCD1D\uD569 \uACC4\uC0B0\n const totalSize = entries.filter((e) => !e.directory).reduce((acc, e) => acc + e.uncompressedSize, 0);\n\n let totalExtracted = 0;\n for (const entry of entries) {\n if (entry.directory) continue;\n\n progressCallback?.({\n fileName: entry.filename,\n totalSize: totalSize,\n extractedSize: totalExtracted,\n });\n\n const entryBytes =\n this._cache.get(entry.filename) ??\n (await entry.getData(new Uint8ArrayWriter(), {\n onprogress: (extracted) => {\n const currentTotal = totalExtracted + extracted;\n\n progressCallback?.({\n fileName: entry.filename,\n totalSize: totalSize,\n extractedSize: currentTotal,\n });\n\n return undefined;\n },\n }));\n\n this._cache.set(entry.filename, entryBytes);\n\n // \uAC1C\uBCC4 \uD30C\uC77C\uC774 \uB05D\uB098\uBA74 \uB204\uC801 \uCC98\uB9AC\n totalExtracted += entry.uncompressedSize;\n\n progressCallback?.({\n fileName: entry.filename,\n totalSize: totalSize,\n extractedSize: totalExtracted,\n });\n }\n\n return this._cache;\n }\n //#endregion\n\n //#region get\n /**\n * \uD2B9\uC815 \uD30C\uC77C \uC555\uCD95 \uD574\uC81C\n * @param fileName \uD30C\uC77C \uC774\uB984\n */\n async get(fileName: string): Promise<Bytes | undefined> {\n if (this._cache.has(fileName)) {\n return this._cache.get(fileName);\n }\n\n const entries = await this._getEntries();\n if (entries == null) {\n this._cache.set(fileName, undefined);\n return undefined;\n }\n\n const entry = entries.find((item) => item.filename === fileName) as FileEntry | undefined;\n if (!entry) {\n this._cache.set(fileName, undefined);\n return undefined;\n }\n\n const bytes = await entry.getData(new Uint8ArrayWriter());\n this._cache.set(fileName, bytes);\n return bytes;\n }\n //#endregion\n\n //#region exists\n /**\n * \uD30C\uC77C \uC874\uC7AC \uC5EC\uBD80 \uD655\uC778\n * @param fileName \uD30C\uC77C \uC774\uB984\n */\n async exists(fileName: string): Promise<boolean> {\n if (this._cache.has(fileName)) {\n return this._cache.get(fileName) != null;\n }\n\n const entries = await this._getEntries();\n if (entries == null) {\n return false;\n }\n\n const entry = entries.find((item) => item.filename === fileName) as FileEntry | undefined;\n return entry !== undefined;\n }\n //#endregion\n\n //#region write\n /**\n * \uD30C\uC77C \uC4F0\uAE30 (\uCE90\uC2DC\uC5D0 \uC800\uC7A5)\n * @param fileName \uD30C\uC77C \uC774\uB984\n * @param bytes \uD30C\uC77C \uB0B4\uC6A9\n */\n write(fileName: string, bytes: Bytes): void {\n this._cache.set(fileName, bytes);\n }\n //#endregion\n\n //#region compress\n /**\n * \uCE90\uC2DC\uB41C \uD30C\uC77C\uB4E4\uC744 ZIP\uC73C\uB85C \uC555\uCD95\n *\n * @remarks\n * \uB0B4\uBD80\uC801\uC73C\uB85C `extractAll()`\uC744 \uD638\uCD9C\uD558\uC5EC \uBAA8\uB4E0 \uD30C\uC77C\uC744 \uBA54\uBAA8\uB9AC\uC5D0 \uB85C\uB4DC\uD55C \uD6C4 \uC555\uCD95\uD569\uB2C8\uB2E4.\n * \uB300\uC6A9\uB7C9 ZIP \uD30C\uC77C\uC758 \uACBD\uC6B0 \uBA54\uBAA8\uB9AC \uC0AC\uC6A9\uB7C9\uC5D0 \uC8FC\uC758\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.\n */\n async compress(): Promise<Bytes> {\n const fileMap = await this.extractAll();\n\n const writer = new ZipWriter(new Uint8ArrayWriter());\n\n for (const key of fileMap.keys()) {\n const fileBytes = fileMap.get(key);\n if (!fileBytes) continue;\n\n await writer.add(key, new Uint8ArrayReader(fileBytes));\n }\n\n return writer.close();\n }\n //#endregion\n\n //#region close\n /**\n * \uB9AC\uB354 \uB2EB\uAE30 \uBC0F \uCE90\uC2DC \uC815\uB9AC\n */\n async close(): Promise<void> {\n await this._reader?.close();\n this._cache.clear();\n }\n\n /**\n * await using \uC9C0\uC6D0\n */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n //#endregion\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@simplysm/core-common",
3
+ "version": "13.0.0-beta.1",
4
+ "description": "심플리즘 패키지 - 코어 모듈 (common)",
5
+ "author": "김석래",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/kslhunter/simplysm.git",
9
+ "directory": "packages/core-common"
10
+ },
11
+ "license": "Apache-2.0",
12
+ "type": "module",
13
+ "main": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "sideEffects": [
16
+ "./src/extensions/arr-ext.ts",
17
+ "./src/extensions/map-ext.ts",
18
+ "./src/extensions/set-ext.ts",
19
+ "./src/index.ts",
20
+ "./dist/extensions/arr-ext.js",
21
+ "./dist/extensions/map-ext.js",
22
+ "./dist/extensions/set-ext.js",
23
+ "./dist/index.js"
24
+ ],
25
+ "dependencies": {
26
+ "@zip.js/zip.js": "^2.8.15",
27
+ "consola": "^3.4.2",
28
+ "fast-xml-parser": "^5.3.3",
29
+ "yaml": "^2.8.2"
30
+ }
31
+ }