@simplysm/core-common 13.0.0-beta.7 → 13.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -815
- package/dist/common.types.js +4 -4
- package/dist/common.types.js.map +0 -1
- package/dist/env.js +2 -2
- package/dist/env.js.map +1 -2
- package/dist/errors/argument-error.js +1 -1
- package/dist/errors/argument-error.js.map +0 -1
- package/dist/errors/not-implemented-error.js +1 -1
- package/dist/errors/not-implemented-error.js.map +0 -1
- package/dist/errors/sd-error.js.map +0 -1
- package/dist/errors/timeout-error.js +1 -1
- package/dist/errors/timeout-error.js.map +0 -1
- package/dist/extensions/arr-ext.helpers.js +4 -4
- package/dist/extensions/arr-ext.helpers.js.map +0 -1
- package/dist/extensions/arr-ext.js +9 -9
- package/dist/extensions/arr-ext.js.map +0 -1
- package/dist/extensions/arr-ext.types.js.map +0 -1
- package/dist/extensions/map-ext.js.map +0 -1
- package/dist/extensions/set-ext.js.map +0 -1
- package/dist/features/debounce-queue.d.ts.map +1 -1
- package/dist/features/debounce-queue.js +4 -4
- package/dist/features/debounce-queue.js.map +1 -2
- package/dist/features/event-emitter.js.map +0 -1
- package/dist/features/serial-queue.d.ts.map +1 -1
- package/dist/features/serial-queue.js +5 -5
- package/dist/features/serial-queue.js.map +1 -2
- package/dist/globals.js.map +0 -1
- package/dist/index.js +30 -30
- package/dist/index.js.map +0 -1
- package/dist/types/date-only.js +2 -2
- package/dist/types/date-only.js.map +0 -1
- package/dist/types/date-time.js +2 -2
- package/dist/types/date-time.js.map +0 -1
- package/dist/types/lazy-gc-map.d.ts.map +1 -1
- package/dist/types/lazy-gc-map.js +2 -2
- package/dist/types/lazy-gc-map.js.map +1 -2
- package/dist/types/time.js +2 -2
- package/dist/types/time.js.map +0 -1
- package/dist/types/uuid.js +1 -1
- package/dist/types/uuid.js.map +0 -1
- package/dist/utils/bytes.js +1 -1
- package/dist/utils/bytes.js.map +0 -1
- package/dist/utils/date-format.js.map +0 -1
- package/dist/utils/json.js +8 -8
- package/dist/utils/json.js.map +0 -1
- package/dist/utils/num.js.map +0 -1
- package/dist/utils/obj.js +5 -5
- package/dist/utils/obj.js.map +0 -1
- package/dist/utils/path.js.map +0 -1
- package/dist/utils/primitive.js +5 -5
- package/dist/utils/primitive.js.map +0 -1
- package/dist/utils/str.js.map +0 -1
- package/dist/utils/template-strings.js.map +0 -1
- package/dist/utils/transferable.js +4 -4
- package/dist/utils/transferable.js.map +0 -1
- package/dist/utils/wait.js +1 -1
- package/dist/utils/wait.js.map +0 -1
- package/dist/utils/xml.js.map +0 -1
- package/dist/zip/sd-zip.js.map +0 -1
- package/docs/extensions.md +381 -0
- package/docs/features.md +94 -0
- package/docs/types.md +338 -0
- package/docs/utils.md +631 -0
- package/package.json +5 -3
- package/src/common.types.ts +91 -0
- package/src/env.ts +11 -0
- package/src/errors/argument-error.ts +40 -0
- package/src/errors/not-implemented-error.ts +32 -0
- package/src/errors/sd-error.ts +53 -0
- package/src/errors/timeout-error.ts +36 -0
- package/src/extensions/arr-ext.helpers.ts +53 -0
- package/src/extensions/arr-ext.ts +777 -0
- package/src/extensions/arr-ext.types.ts +258 -0
- package/src/extensions/map-ext.ts +86 -0
- package/src/extensions/set-ext.ts +68 -0
- package/src/features/debounce-queue.ts +116 -0
- package/src/features/event-emitter.ts +112 -0
- package/src/features/serial-queue.ts +94 -0
- package/src/globals.ts +12 -0
- package/src/index.ts +55 -0
- package/src/types/date-only.ts +329 -0
- package/src/types/date-time.ts +294 -0
- package/src/types/lazy-gc-map.ts +244 -0
- package/src/types/time.ts +210 -0
- package/src/types/uuid.ts +113 -0
- package/src/utils/bytes.ts +160 -0
- package/src/utils/date-format.ts +239 -0
- package/src/utils/json.ts +230 -0
- package/src/utils/num.ts +97 -0
- package/src/utils/obj.ts +956 -0
- package/src/utils/path.ts +40 -0
- package/src/utils/primitive.ts +33 -0
- package/src/utils/str.ts +252 -0
- package/src/utils/template-strings.ts +132 -0
- package/src/utils/transferable.ts +269 -0
- package/src/utils/wait.ts +40 -0
- package/src/utils/xml.ts +105 -0
- package/src/zip/sd-zip.ts +218 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/template-strings.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * \uD15C\uD50C\uB9BF \uBB38\uC790\uC5F4 \uD0DC\uADF8 \uD568\uC218\uB4E4\n * IDE \uCF54\uB4DC \uD558\uC774\uB77C\uC774\uD305 \uC9C0\uC6D0\uC6A9 (\uC2E4\uC81C \uB3D9\uC791\uC740 \uBB38\uC790\uC5F4 \uC870\uD569 + \uB4E4\uC5EC\uC4F0\uAE30 \uC815\uB9AC)\n */\n\n/**\n * JavaScript \uCF54\uB4DC \uD558\uC774\uB77C\uC774\uD305\uC6A9 \uD15C\uD50C\uB9BF \uD0DC\uADF8\n * @param strings \uD15C\uD50C\uB9BF \uBB38\uC790\uC5F4 \uBC30\uC5F4\n * @param values \uBCF4\uAC04\uB41C \uAC12\uB4E4\n * @returns \uB4E4\uC5EC\uC4F0\uAE30\uAC00 \uC815\uB9AC\uB41C \uBB38\uC790\uC5F4\n * @example\n * const code = js`\n * function hello() {\n * return \"world\";\n * }\n * `;\n */\nexport function js(strings: TemplateStringsArray, ...values: unknown[]): string {\n return _combine(strings, values);\n}\n\n/**\n * TypeScript \uCF54\uB4DC \uD558\uC774\uB77C\uC774\uD305\uC6A9 \uD15C\uD50C\uB9BF \uD0DC\uADF8\n * @param strings \uD15C\uD50C\uB9BF \uBB38\uC790\uC5F4 \uBC30\uC5F4\n * @param values \uBCF4\uAC04\uB41C \uAC12\uB4E4\n * @returns \uB4E4\uC5EC\uC4F0\uAE30\uAC00 \uC815\uB9AC\uB41C \uBB38\uC790\uC5F4\n * @example\n * const code = ts`\n * interface User {\n * name: string;\n * age: number;\n * }\n * `;\n */\nexport function ts(strings: TemplateStringsArray, ...values: unknown[]): string {\n return _combine(strings, values);\n}\n\n/**\n * HTML \uB9C8\uD06C\uC5C5 \uD558\uC774\uB77C\uC774\uD305\uC6A9 \uD15C\uD50C\uB9BF \uD0DC\uADF8\n * @param strings \uD15C\uD50C\uB9BF \uBB38\uC790\uC5F4 \uBC30\uC5F4\n * @param values \uBCF4\uAC04\uB41C \uAC12\uB4E4\n * @returns \uB4E4\uC5EC\uC4F0\uAE30\uAC00 \uC815\uB9AC\uB41C \uBB38\uC790\uC5F4\n * @example\n * const markup = html`\n * <div class=\"container\">\n * <span>${name}</span>\n * </div>\n * `;\n */\nexport function html(strings: TemplateStringsArray, ...values: unknown[]): string {\n return _combine(strings, values);\n}\n\n/**\n * MSSQL T-SQL \uD558\uC774\uB77C\uC774\uD305\uC6A9 \uD15C\uD50C\uB9BF \uD0DC\uADF8\n * @param strings \uD15C\uD50C\uB9BF \uBB38\uC790\uC5F4 \uBC30\uC5F4\n * @param values \uBCF4\uAC04\uB41C \uAC12\uB4E4\n * @returns \uB4E4\uC5EC\uC4F0\uAE30\uAC00 \uC815\uB9AC\uB41C \uBB38\uC790\uC5F4\n * @example\n * const query = tsql`\n * SELECT TOP 10 *\n * FROM Users\n * WHERE Name LIKE '%${keyword}%'\n * `;\n */\nexport function tsql(strings: TemplateStringsArray, ...values: unknown[]): string {\n return _combine(strings, values);\n}\n\n/**\n * MySQL SQL \uD558\uC774\uB77C\uC774\uD305\uC6A9 \uD15C\uD50C\uB9BF \uD0DC\uADF8\n * @param strings \uD15C\uD50C\uB9BF \uBB38\uC790\uC5F4 \uBC30\uC5F4\n * @param values \uBCF4\uAC04\uB41C \uAC12\uB4E4\n * @returns \uB4E4\uC5EC\uC4F0\uAE30\uAC00 \uC815\uB9AC\uB41C \uBB38\uC790\uC5F4\n * @example\n * const query = mysql`\n * SELECT *\n * FROM users\n * LIMIT 10\n * `;\n */\nexport function mysql(strings: TemplateStringsArray, ...values: unknown[]): string {\n return _combine(strings, values);\n}\n\n/**\n * PostgreSQL SQL \uD558\uC774\uB77C\uC774\uD305\uC6A9 \uD15C\uD50C\uB9BF \uD0DC\uADF8\n * @param strings \uD15C\uD50C\uB9BF \uBB38\uC790\uC5F4 \uBC30\uC5F4\n * @param values \uBCF4\uAC04\uB41C \uAC12\uB4E4\n * @returns \uB4E4\uC5EC\uC4F0\uAE30\uAC00 \uC815\uB9AC\uB41C \uBB38\uC790\uC5F4\n * @example\n * const query = pgsql`\n * SELECT *\n * FROM users\n * OFFSET 0 LIMIT 10\n * `;\n */\nexport function pgsql(strings: TemplateStringsArray, ...values: unknown[]): string {\n return _combine(strings, values);\n}\n\nfunction _combine(strings: TemplateStringsArray, values: unknown[]): string {\n const raw = strings.reduce((result, str, i) => {\n const value = values[i] !== undefined ? String(values[i]) : \"\";\n return result + str + value;\n }, \"\");\n return _trimIndent(raw);\n}\n\nfunction _trimIndent(text: string): string {\n const lines = text.split(\"\\n\");\n\n // \uCCAB/\uB9C8\uC9C0\uB9C9 \uBE48 \uC904 \uC81C\uAC70 (\uC5F0\uC18D\uB41C \uBE48 \uC904 \uBAA8\uB450 \uC81C\uAC70)\n while (lines.length > 0 && lines[0].trim() === \"\") {\n lines.shift();\n }\n while (lines.length > 0 && lines[lines.length - 1].trim() === \"\") {\n lines.pop();\n }\n\n // \uCD5C\uC18C \uB4E4\uC5EC\uC4F0\uAE30 \uACC4\uC0B0\n const minIndent = lines\n .filter((line) => line.trim() !== \"\")\n .reduce((min, line) => {\n const indent = line.match(/^ */)?.[0].length ?? 0;\n return Math.min(min, indent);\n }, Infinity);\n\n // \uB4E4\uC5EC\uC4F0\uAE30 \uC81C\uAC70\n return lines.map((line) => (line.trim() === \"\" ? \"\" : line.slice(minIndent))).join(\"\\n\");\n}\n"],
|
|
5
4
|
"mappings": "AAiBO,SAAS,GAAG,YAAkC,QAA2B;AAC9E,SAAO,SAAS,SAAS,MAAM;AACjC;AAeO,SAAS,GAAG,YAAkC,QAA2B;AAC9E,SAAO,SAAS,SAAS,MAAM;AACjC;AAcO,SAAS,KAAK,YAAkC,QAA2B;AAChF,SAAO,SAAS,SAAS,MAAM;AACjC;AAcO,SAAS,KAAK,YAAkC,QAA2B;AAChF,SAAO,SAAS,SAAS,MAAM;AACjC;AAcO,SAAS,MAAM,YAAkC,QAA2B;AACjF,SAAO,SAAS,SAAS,MAAM;AACjC;AAcO,SAAS,MAAM,YAAkC,QAA2B;AACjF,SAAO,SAAS,SAAS,MAAM;AACjC;AAEA,SAAS,SAAS,SAA+B,QAA2B;AAC1E,QAAM,MAAM,QAAQ,OAAO,CAAC,QAAQ,KAAK,MAAM;AAC7C,UAAM,QAAQ,OAAO,CAAC,MAAM,SAAY,OAAO,OAAO,CAAC,CAAC,IAAI;AAC5D,WAAO,SAAS,MAAM;AAAA,EACxB,GAAG,EAAE;AACL,SAAO,YAAY,GAAG;AACxB;AAEA,SAAS,YAAY,MAAsB;AACzC,QAAM,QAAQ,KAAK,MAAM,IAAI;AAG7B,SAAO,MAAM,SAAS,KAAK,MAAM,CAAC,EAAE,KAAK,MAAM,IAAI;AACjD,UAAM,MAAM;AAAA,EACd;AACA,SAAO,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,EAAE,KAAK,MAAM,IAAI;AAChE,UAAM,IAAI;AAAA,EACZ;AAGA,QAAM,YAAY,MACf,OAAO,CAAC,SAAS,KAAK,KAAK,MAAM,EAAE,EACnC,OAAO,CAAC,KAAK,SAAS;AA5H3B;AA6HM,UAAM,WAAS,UAAK,MAAM,KAAK,MAAhB,mBAAoB,GAAG,WAAU;AAChD,WAAO,KAAK,IAAI,KAAK,MAAM;AAAA,EAC7B,GAAG,QAAQ;AAGb,SAAO,MAAM,IAAI,CAAC,SAAU,KAAK,KAAK,MAAM,KAAK,KAAK,KAAK,MAAM,SAAS,CAAE,EAAE,KAAK,IAAI;AACzF;",
|
|
6
5
|
"names": []
|
|
7
6
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
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";
|
|
1
|
+
import { DateTime } from "../types/date-time.js";
|
|
2
|
+
import { DateOnly } from "../types/date-only.js";
|
|
3
|
+
import { Time } from "../types/time.js";
|
|
4
|
+
import { Uuid } from "../types/uuid.js";
|
|
5
5
|
function transferableEncode(obj) {
|
|
6
6
|
const transferList = [];
|
|
7
7
|
const ancestors = /* @__PURE__ */ new Set();
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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
4
|
"mappings": "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",
|
|
6
5
|
"names": []
|
|
7
6
|
}
|
package/dist/utils/wait.js
CHANGED
package/dist/utils/wait.js.map
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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
4
|
"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
5
|
"names": []
|
|
7
6
|
}
|
package/dist/utils/xml.js.map
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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
4
|
"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
5
|
"names": []
|
|
7
6
|
}
|
package/dist/zip/sd-zip.js.map
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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
4
|
"mappings": "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",
|
|
6
5
|
"names": []
|
|
7
6
|
}
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# Extensions
|
|
2
|
+
|
|
3
|
+
Array, Map, Set prototype extensions. Activated by `import "@simplysm/core-common"`.
|
|
4
|
+
|
|
5
|
+
## Array extension methods
|
|
6
|
+
|
|
7
|
+
### Query
|
|
8
|
+
|
|
9
|
+
#### single
|
|
10
|
+
|
|
11
|
+
Return single element (error if 2+).
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import "@simplysm/core-common";
|
|
15
|
+
|
|
16
|
+
const users = [{ id: 1, name: "Alice" }];
|
|
17
|
+
users.single((u) => u.id === 1); // { id: 1, name: "Alice" }
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
#### first
|
|
21
|
+
|
|
22
|
+
Return first element.
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
users.first(); // { id: 1, name: "Alice" }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
#### last
|
|
29
|
+
|
|
30
|
+
Return last element.
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
users.last(); // Last user
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
### Filtering
|
|
39
|
+
|
|
40
|
+
#### filterExists
|
|
41
|
+
|
|
42
|
+
Remove `null`/`undefined`.
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
[1, null, 2, undefined, 3].filterExists(); // [1, 2, 3]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### ofType
|
|
49
|
+
|
|
50
|
+
Filter by type (`PrimitiveTypeStr` or constructor).
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import "@simplysm/core-common";
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### filterAsync
|
|
57
|
+
|
|
58
|
+
Async filter.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import "@simplysm/core-common";
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
### Mapping/Transformation
|
|
67
|
+
|
|
68
|
+
#### mapAsync
|
|
69
|
+
|
|
70
|
+
Async mapping (sequential execution).
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
await ids.mapAsync(async (id) => await fetchUser(id));
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### mapMany
|
|
77
|
+
|
|
78
|
+
flat + filterExists.
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import "@simplysm/core-common";
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### mapManyAsync
|
|
85
|
+
|
|
86
|
+
Async mapMany.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import "@simplysm/core-common";
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### parallelAsync
|
|
93
|
+
|
|
94
|
+
Parallel async mapping (`Promise.all`).
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
await ids.parallelAsync(async (id) => await fetchUser(id));
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
### Grouping/Transformation
|
|
103
|
+
|
|
104
|
+
#### groupBy
|
|
105
|
+
|
|
106
|
+
Group by key.
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
const users = [
|
|
110
|
+
{ id: 1, name: "Alice", dept: "dev" },
|
|
111
|
+
{ id: 2, name: "Bob", dept: "dev" },
|
|
112
|
+
{ id: 3, name: "Charlie", dept: "hr" },
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
users.groupBy((u) => u.dept);
|
|
116
|
+
// [{ key: "dev", values: [...] }, { key: "hr", values: [...] }]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### toMap
|
|
120
|
+
|
|
121
|
+
Convert to Map (error on duplicate key).
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
users.toMap((u) => u.id); // Map<number, User>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### toMapAsync
|
|
128
|
+
|
|
129
|
+
Async Map conversion.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import "@simplysm/core-common";
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### toArrayMap
|
|
136
|
+
|
|
137
|
+
Convert to `Map<K, V[]>`.
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
users.toArrayMap((u) => u.dept); // Map<string, User[]>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### toSetMap
|
|
144
|
+
|
|
145
|
+
Convert to `Map<K, Set<V>>`.
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import "@simplysm/core-common";
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### toMapValues
|
|
152
|
+
|
|
153
|
+
Aggregate Map by group.
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import "@simplysm/core-common";
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### toObject
|
|
160
|
+
|
|
161
|
+
Convert to `Record<string, V>`.
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
import "@simplysm/core-common";
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### toTree
|
|
168
|
+
|
|
169
|
+
Convert to tree structure.
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import "@simplysm/core-common";
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
### Deduplication
|
|
178
|
+
|
|
179
|
+
#### distinct
|
|
180
|
+
|
|
181
|
+
Remove duplicates (return new array).
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
[1, 2, 2, 3, 3].distinct(); // [1, 2, 3]
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
#### distinctThis
|
|
188
|
+
|
|
189
|
+
Remove duplicates (modify original).
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import "@simplysm/core-common";
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
### Sorting
|
|
198
|
+
|
|
199
|
+
#### orderBy
|
|
200
|
+
|
|
201
|
+
Ascending sort (return new array).
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
users.orderBy((u) => u.name);
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### orderByDesc
|
|
208
|
+
|
|
209
|
+
Descending sort (return new array).
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
users.orderByDesc((u) => u.id);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
#### orderByThis
|
|
216
|
+
|
|
217
|
+
Ascending sort (modify original).
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import "@simplysm/core-common";
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
#### orderByDescThis
|
|
224
|
+
|
|
225
|
+
Descending sort (modify original).
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
import "@simplysm/core-common";
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
### Comparison/Merging
|
|
234
|
+
|
|
235
|
+
#### diffs
|
|
236
|
+
|
|
237
|
+
Compare differences between two arrays.
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import "@simplysm/core-common";
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### oneWayDiffs
|
|
244
|
+
|
|
245
|
+
One-way diff comparison (create/update/same).
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import "@simplysm/core-common";
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### merge
|
|
252
|
+
|
|
253
|
+
Merge arrays.
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
import "@simplysm/core-common";
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
### Aggregation
|
|
262
|
+
|
|
263
|
+
#### sum
|
|
264
|
+
|
|
265
|
+
Sum.
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
import "@simplysm/core-common";
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### min
|
|
272
|
+
|
|
273
|
+
Minimum.
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
import "@simplysm/core-common";
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
#### max
|
|
280
|
+
|
|
281
|
+
Maximum.
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
import "@simplysm/core-common";
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
### Mutation
|
|
290
|
+
|
|
291
|
+
#### insert
|
|
292
|
+
|
|
293
|
+
Insert at specific position.
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
import "@simplysm/core-common";
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### remove
|
|
300
|
+
|
|
301
|
+
Remove item.
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
import "@simplysm/core-common";
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
#### toggle
|
|
308
|
+
|
|
309
|
+
Remove if exists, add if not.
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import "@simplysm/core-common";
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### clear
|
|
316
|
+
|
|
317
|
+
Remove all items.
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import "@simplysm/core-common";
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
#### shuffle
|
|
324
|
+
|
|
325
|
+
Shuffle (return new array).
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
import "@simplysm/core-common";
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Map extension methods
|
|
334
|
+
|
|
335
|
+
### getOrCreate
|
|
336
|
+
|
|
337
|
+
If key doesn't exist, set new value and return.
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
const map = new Map<string, number[]>();
|
|
341
|
+
|
|
342
|
+
// Create and return if value doesn't exist
|
|
343
|
+
const arr = map.getOrCreate("key", []);
|
|
344
|
+
arr.push(1);
|
|
345
|
+
|
|
346
|
+
// Create with factory function (when computation is expensive)
|
|
347
|
+
map.getOrCreate("key2", () => expensiveComputation());
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### update
|
|
351
|
+
|
|
352
|
+
Update value for key using function.
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
const countMap = new Map<string, number>();
|
|
356
|
+
countMap.update("key", (v) => (v ?? 0) + 1); // Increment counter
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Set extension methods
|
|
362
|
+
|
|
363
|
+
### adds
|
|
364
|
+
|
|
365
|
+
Add multiple values at once.
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
const set = new Set<number>([1, 2, 3]);
|
|
369
|
+
set.adds(4, 5, 6); // {1, 2, 3, 4, 5, 6}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### toggle
|
|
373
|
+
|
|
374
|
+
Toggle value (remove if exists, add if not).
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
set.toggle(2); // 2 exists so remove -> {1, 3, 4, 5, 6}
|
|
378
|
+
set.toggle(7); // 7 doesn't exist so add -> {1, 3, 4, 5, 6, 7}
|
|
379
|
+
set.toggle(8, "add"); // Force add
|
|
380
|
+
set.toggle(1, "del"); // Force delete
|
|
381
|
+
```
|
package/docs/features.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Features
|
|
2
|
+
|
|
3
|
+
Async operation control and event handling classes. All support `using` statements or `dispose()`.
|
|
4
|
+
|
|
5
|
+
## DebounceQueue
|
|
6
|
+
|
|
7
|
+
Async debounce queue (executes only last request).
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { DebounceQueue } from "@simplysm/core-common";
|
|
11
|
+
|
|
12
|
+
using queue = new DebounceQueue(300); // 300ms debounce
|
|
13
|
+
|
|
14
|
+
// Error handling
|
|
15
|
+
queue.on("error", (err) => console.error(err));
|
|
16
|
+
|
|
17
|
+
// Only last call is executed
|
|
18
|
+
queue.run(() => console.log("1")); // Ignored
|
|
19
|
+
queue.run(() => console.log("2")); // Ignored
|
|
20
|
+
queue.run(() => console.log("3")); // Executed after 300ms
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## SerialQueue
|
|
26
|
+
|
|
27
|
+
Async serial queue (sequential execution).
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { SerialQueue } from "@simplysm/core-common";
|
|
31
|
+
|
|
32
|
+
using queue = new SerialQueue(100); // 100ms interval between tasks
|
|
33
|
+
|
|
34
|
+
queue.on("error", (err) => console.error(err));
|
|
35
|
+
|
|
36
|
+
queue.run(async () => { await fetch("/api/1"); });
|
|
37
|
+
queue.run(async () => { await fetch("/api/2"); }); // Runs after #1 completes
|
|
38
|
+
queue.run(async () => { await fetch("/api/3"); }); // Runs after #2 completes
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## EventEmitter
|
|
44
|
+
|
|
45
|
+
EventTarget wrapper with type-safe events.
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { EventEmitter } from "@simplysm/core-common";
|
|
49
|
+
|
|
50
|
+
interface MyEvents {
|
|
51
|
+
data: string;
|
|
52
|
+
error: Error;
|
|
53
|
+
done: void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
class MyService extends EventEmitter<MyEvents> {
|
|
57
|
+
process(): void {
|
|
58
|
+
this.emit("data", "result data");
|
|
59
|
+
this.emit("done"); // void type called without arguments
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const service = new MyService();
|
|
64
|
+
service.on("data", (data) => console.log(data)); // data: string (type inferred)
|
|
65
|
+
service.off("data", listener); // Remove listener
|
|
66
|
+
service.listenerCount("data"); // Number of registered listeners
|
|
67
|
+
service.dispose(); // Remove all listeners
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## ZipArchive
|
|
73
|
+
|
|
74
|
+
ZIP file compression/decompression utility. Resources can be auto-cleaned with `await using`.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { ZipArchive } from "@simplysm/core-common";
|
|
78
|
+
|
|
79
|
+
// Read ZIP file
|
|
80
|
+
await using archive = new ZipArchive(zipBytes);
|
|
81
|
+
const content = await archive.get("file.txt");
|
|
82
|
+
const exists = await archive.exists("data.json");
|
|
83
|
+
|
|
84
|
+
// Extract all (with progress)
|
|
85
|
+
const files = await archive.extractAll((progress) => {
|
|
86
|
+
console.log(`${progress.fileName}: ${progress.extractedSize}/${progress.totalSize}`);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Create ZIP file
|
|
90
|
+
await using newArchive = new ZipArchive();
|
|
91
|
+
newArchive.write("file.txt", textBytes);
|
|
92
|
+
newArchive.write("data.json", jsonBytes);
|
|
93
|
+
const zipBytes = await newArchive.compress();
|
|
94
|
+
```
|