@ryuzaki13/react-foundation-api 1.0.0
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/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/adt/fetchUserTransports.d.ts +2 -0
- package/dist/adt/fetchUserTransports.d.ts.map +1 -0
- package/dist/adt/index.d.ts +4 -0
- package/dist/adt/index.d.ts.map +1 -0
- package/dist/adt/index.js +70 -0
- package/dist/adt/index.js.map +1 -0
- package/dist/adt/parseUserTransportsXml.d.ts +3 -0
- package/dist/adt/parseUserTransportsXml.d.ts.map +1 -0
- package/dist/adt/types.d.ts +10 -0
- package/dist/adt/types.d.ts.map +1 -0
- package/dist/async/AsyncTasksError.d.ts +6 -0
- package/dist/async/AsyncTasksError.d.ts.map +1 -0
- package/dist/async/ConcurrencyPartialError.d.ts +6 -0
- package/dist/async/ConcurrencyPartialError.d.ts.map +1 -0
- package/dist/async/index.d.ts +5 -0
- package/dist/async/index.d.ts.map +1 -0
- package/dist/async/index.js +163 -0
- package/dist/async/index.js.map +1 -0
- package/dist/async/runAsyncTasks.d.ts +32 -0
- package/dist/async/runAsyncTasks.d.ts.map +1 -0
- package/dist/async/runConcurrentTasks.d.ts +127 -0
- package/dist/async/runConcurrentTasks.d.ts.map +1 -0
- package/dist/chunks/fetch-BW2OtCu7.js +508 -0
- package/dist/chunks/fetch-BW2OtCu7.js.map +1 -0
- package/dist/chunks/odata-ZgZGme_K.js +473 -0
- package/dist/chunks/odata-ZgZGme_K.js.map +1 -0
- package/dist/chunks/odataFetchFn-BXVJxOou.js +302 -0
- package/dist/chunks/odataFetchFn-BXVJxOou.js.map +1 -0
- package/dist/error-report/errorReport.d.ts +28 -0
- package/dist/error-report/errorReport.d.ts.map +1 -0
- package/dist/error-report/index.d.ts +2 -0
- package/dist/error-report/index.d.ts.map +1 -0
- package/dist/error-report/index.js +42 -0
- package/dist/error-report/index.js.map +1 -0
- package/dist/http/RouteError.d.ts +5 -0
- package/dist/http/RouteError.d.ts.map +1 -0
- package/dist/http/http.d.ts +20 -0
- package/dist/http/http.d.ts.map +1 -0
- package/dist/http/index.d.ts +4 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +67 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/types.d.ts +23 -0
- package/dist/http/types.d.ts.map +1 -0
- package/dist/odata/createODataCollectionQueryKey.d.ts +9 -0
- package/dist/odata/createODataCollectionQueryKey.d.ts.map +1 -0
- package/dist/odata/fetchCollectionData.d.ts +15 -0
- package/dist/odata/fetchCollectionData.d.ts.map +1 -0
- package/dist/odata/flattenODataDependentServices.d.ts +6 -0
- package/dist/odata/flattenODataDependentServices.d.ts.map +1 -0
- package/dist/odata/index.d.ts +21 -0
- package/dist/odata/index.d.ts.map +1 -0
- package/dist/odata/index.js +4 -0
- package/dist/odata/metadataVersionCheck.d.ts +49 -0
- package/dist/odata/metadataVersionCheck.d.ts.map +1 -0
- package/dist/odata/odataBaseQueryKey.d.ts +2 -0
- package/dist/odata/odataBaseQueryKey.d.ts.map +1 -0
- package/dist/odata/odataFetch.d.ts +87 -0
- package/dist/odata/odataFetch.d.ts.map +1 -0
- package/dist/odata/odataFetchFn.d.ts +399 -0
- package/dist/odata/odataFetchFn.d.ts.map +1 -0
- package/dist/odata/odataFetchFnDev.d.ts +58 -0
- package/dist/odata/odataFetchFnDev.d.ts.map +1 -0
- package/dist/odata/odataFetchFnHelpers.d.ts +9 -0
- package/dist/odata/odataFetchFnHelpers.d.ts.map +1 -0
- package/dist/odata/odataProjectAdapter.d.ts +22 -0
- package/dist/odata/odataProjectAdapter.d.ts.map +1 -0
- package/dist/odata/parseODataResponseByMetadata.d.ts +4 -0
- package/dist/odata/parseODataResponseByMetadata.d.ts.map +1 -0
- package/dist/odata/sortODataDependentSegmentItemsByChains.d.ts +8 -0
- package/dist/odata/sortODataDependentSegmentItemsByChains.d.ts.map +1 -0
- package/dist/odata/sortODataDependentServicesByChains.d.ts +12 -0
- package/dist/odata/sortODataDependentServicesByChains.d.ts.map +1 -0
- package/dist/odata/transport/SsoRequiredError.d.ts +22 -0
- package/dist/odata/transport/SsoRequiredError.d.ts.map +1 -0
- package/dist/odata/transport/errorReport.d.ts +3 -0
- package/dist/odata/transport/errorReport.d.ts.map +1 -0
- package/dist/odata/transport/fetch.d.ts +43 -0
- package/dist/odata/transport/fetch.d.ts.map +1 -0
- package/dist/odata/transport/index.d.ts +5 -0
- package/dist/odata/transport/index.d.ts.map +1 -0
- package/dist/odata/transport/types.d.ts +12 -0
- package/dist/odata/transport/types.d.ts.map +1 -0
- package/dist/odata/transport/url.d.ts +13 -0
- package/dist/odata/transport/url.d.ts.map +1 -0
- package/dist/odata/types.d.ts +176 -0
- package/dist/odata/types.d.ts.map +1 -0
- package/dist/odata/useODataCollection.d.ts +39 -0
- package/dist/odata/useODataCollection.d.ts.map +1 -0
- package/dist/odata/useODataCollectionChains.d.ts +7 -0
- package/dist/odata/useODataCollectionChains.d.ts.map +1 -0
- package/dist/odata/useODataCollectionModel.d.ts +3 -0
- package/dist/odata/useODataCollectionModel.d.ts.map +1 -0
- package/dist/odata/useODataCollectionQuery.d.ts +34 -0
- package/dist/odata/useODataCollectionQuery.d.ts.map +1 -0
- package/dist/odata/useODataCollectionUpdatesQuery.d.ts +51 -0
- package/dist/odata/useODataCollectionUpdatesQuery.d.ts.map +1 -0
- package/dist/odata/useODataEntity.d.ts +28 -0
- package/dist/odata/useODataEntity.d.ts.map +1 -0
- package/dist/odata/useODataMetadata.d.ts +13 -0
- package/dist/odata/useODataMetadata.d.ts.map +1 -0
- package/dist/odata/useODataMetadataQuery.d.ts +32 -0
- package/dist/odata/useODataMetadataQuery.d.ts.map +1 -0
- package/dist/odata/useODataTableColumns.d.ts +69 -0
- package/dist/odata/useODataTableColumns.d.ts.map +1 -0
- package/dist/odata/useTextServiceQuery.d.ts +3 -0
- package/dist/odata/useTextServiceQuery.d.ts.map +1 -0
- package/dist/persisted/cache.d.ts +29 -0
- package/dist/persisted/cache.d.ts.map +1 -0
- package/dist/persisted/index.d.ts +22 -0
- package/dist/persisted/index.d.ts.map +1 -0
- package/dist/persisted/index.js +339 -0
- package/dist/persisted/index.js.map +1 -0
- package/dist/persisted/keys.d.ts +21 -0
- package/dist/persisted/keys.d.ts.map +1 -0
- package/dist/persisted/odata.d.ts +113 -0
- package/dist/persisted/odata.d.ts.map +1 -0
- package/dist/persisted/payload.d.ts +29 -0
- package/dist/persisted/payload.d.ts.map +1 -0
- package/dist/persisted/resource.d.ts +87 -0
- package/dist/persisted/resource.d.ts.map +1 -0
- package/dist/persisted/rest.d.ts +87 -0
- package/dist/persisted/rest.d.ts.map +1 -0
- package/dist/persisted/types.d.ts +172 -0
- package/dist/persisted/types.d.ts.map +1 -0
- package/dist/resource/cache.d.ts +22 -0
- package/dist/resource/cache.d.ts.map +1 -0
- package/dist/resource/index.d.ts +5 -0
- package/dist/resource/index.d.ts.map +1 -0
- package/dist/resource/index.js +147 -0
- package/dist/resource/index.js.map +1 -0
- package/dist/resource/keys.d.ts +14 -0
- package/dist/resource/keys.d.ts.map +1 -0
- package/dist/resource/resource.d.ts +38 -0
- package/dist/resource/resource.d.ts.map +1 -0
- package/dist/resource/types.d.ts +112 -0
- package/dist/resource/types.d.ts.map +1 -0
- package/dist/s3/constants.d.ts +12 -0
- package/dist/s3/constants.d.ts.map +1 -0
- package/dist/s3/fetchFileFromS3.d.ts +13 -0
- package/dist/s3/fetchFileFromS3.d.ts.map +1 -0
- package/dist/s3/index.d.ts +3 -0
- package/dist/s3/index.d.ts.map +1 -0
- package/dist/s3/index.js +41 -0
- package/dist/s3/index.js.map +1 -0
- package/dist/s3/uploadToS3.d.ts +18 -0
- package/dist/s3/uploadToS3.d.ts.map +1 -0
- package/dist/server-fn/index.d.ts +2 -0
- package/dist/server-fn/index.d.ts.map +1 -0
- package/dist/server-fn/index.js +37 -0
- package/dist/server-fn/index.js.map +1 -0
- package/dist/server-fn/serverFn.d.ts +64 -0
- package/dist/server-fn/serverFn.d.ts.map +1 -0
- package/dist/transport/fetchTransportRequests.d.ts +11 -0
- package/dist/transport/fetchTransportRequests.d.ts.map +1 -0
- package/dist/transport/index.d.ts +4 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +52 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/normalizeTransportRequests.d.ts +3 -0
- package/dist/transport/normalizeTransportRequests.d.ts.map +1 -0
- package/dist/transport/types.d.ts +19 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/package.json +202 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Афанасьев Алексей
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @ryuzaki13/react-foundation-api
|
|
2
|
+
|
|
3
|
+
Библиотечный пакет для инфраструктуры `shared/api`: HTTP-транспорт, async/resource helpers, persisted resources и специализированные transport adapters.
|
|
4
|
+
|
|
5
|
+
## Публичные entrypoints
|
|
6
|
+
|
|
7
|
+
- `@ryuzaki13/react-foundation-api/http` — обычный HTTP/REST transport.
|
|
8
|
+
- `@ryuzaki13/react-foundation-api/async` — batch/concurrent async helpers.
|
|
9
|
+
- `@ryuzaki13/react-foundation-api/resource` — generic resource descriptors поверх TanStack Query.
|
|
10
|
+
- `@ryuzaki13/react-foundation-api/persisted` — persisted resource helpers.
|
|
11
|
+
- `@ryuzaki13/react-foundation-api/odata` — OData/SAP Gateway helpers.
|
|
12
|
+
- `@ryuzaki13/react-foundation-api/transport` — transport request normalization.
|
|
13
|
+
- `@ryuzaki13/react-foundation-api/server-fn` — adapters для server function operations.
|
|
14
|
+
- `@ryuzaki13/react-foundation-api/adt` — ADT/SAP transport helpers.
|
|
15
|
+
- `@ryuzaki13/react-foundation-api/s3` — S3 file transfer helpers.
|
|
16
|
+
- `@ryuzaki13/react-foundation-api/error-report` — API-level error report adapters.
|
|
17
|
+
|
|
18
|
+
## Peer-зависимости
|
|
19
|
+
|
|
20
|
+
`@ryuzaki13/react-foundation-lib`, `@tanstack/react-query`, `react` и `fast-xml-parser` объявлены как peerDependencies. `react`, `@tanstack/react-query` и `fast-xml-parser` помечены optional на уровне npm, потому что они нужны только отдельным subpath entrypoints.
|
|
21
|
+
|
|
22
|
+
## Сборка
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install
|
|
26
|
+
npm run typecheck
|
|
27
|
+
npm run build
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Сборка создаёт ESM-файлы через Vite и декларации типов через `tsc`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchUserTransports.d.ts","sourceRoot":"","sources":["../../src/adt/fetchUserTransports.ts"],"names":[],"mappings":"AAUA,wBAAsB,mBAAmB,+CAoBxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adt/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { t as e } from "../chunks/fetch-BW2OtCu7.js";
|
|
2
|
+
import { isRecord as t } from "@ryuzaki13/react-foundation-lib/validators";
|
|
3
|
+
import { normalizeText as n } from "@ryuzaki13/react-foundation-lib/formatters";
|
|
4
|
+
import { arrayUniqueBy as r } from "@ryuzaki13/react-foundation-lib/array";
|
|
5
|
+
import { XMLParser as i } from "fast-xml-parser";
|
|
6
|
+
//#region src/adt/parseUserTransportsXml.ts
|
|
7
|
+
var a = new i({
|
|
8
|
+
ignoreAttributes: !1,
|
|
9
|
+
attributeNamePrefix: "",
|
|
10
|
+
parseTagValue: !1,
|
|
11
|
+
trimValues: !0
|
|
12
|
+
});
|
|
13
|
+
function o(e, n, r = []) {
|
|
14
|
+
if (Array.isArray(e)) {
|
|
15
|
+
for (let t of e) o(t, n, r);
|
|
16
|
+
return r;
|
|
17
|
+
}
|
|
18
|
+
if (!t(e)) return r;
|
|
19
|
+
for (let [t, i] of Object.entries(e)) t === n && r.push(i), o(i, n, r);
|
|
20
|
+
return r;
|
|
21
|
+
}
|
|
22
|
+
function s(e) {
|
|
23
|
+
if (!t(e)) return null;
|
|
24
|
+
let r = n(e.TRKORR);
|
|
25
|
+
return r ? {
|
|
26
|
+
transportNo: r,
|
|
27
|
+
description: n(e.AS4TEXT),
|
|
28
|
+
owner: n(e.AS4USER),
|
|
29
|
+
targetSystem: n(e.TARSYSTEM),
|
|
30
|
+
functionCode: n(e.TRFUNCTION),
|
|
31
|
+
statusCode: n(e.TRSTATUS),
|
|
32
|
+
parentTransportNo: n(e.STRKORR)
|
|
33
|
+
} : null;
|
|
34
|
+
}
|
|
35
|
+
function c(e) {
|
|
36
|
+
let t = e.trim();
|
|
37
|
+
if (!t) return [];
|
|
38
|
+
let i = a.parse(t), c = o(i, "CTS_REQ_HEADER").flatMap((e) => {
|
|
39
|
+
if (Array.isArray(e)) return e.map(s).filter((e) => e !== null);
|
|
40
|
+
let t = s(e);
|
|
41
|
+
return t ? [t] : [];
|
|
42
|
+
});
|
|
43
|
+
return c.length > 0 ? r(c, "transportNo") : r(o(i, "TRKORR").map((e) => n(e)).filter((e) => e !== void 0).map((e) => ({
|
|
44
|
+
transportNo: e,
|
|
45
|
+
description: void 0,
|
|
46
|
+
owner: void 0,
|
|
47
|
+
targetSystem: void 0,
|
|
48
|
+
functionCode: void 0,
|
|
49
|
+
statusCode: void 0,
|
|
50
|
+
parentTransportNo: void 0
|
|
51
|
+
})), "transportNo");
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/adt/fetchUserTransports.ts
|
|
55
|
+
var l = "/sap/bc/adt/cts/transports?_action=FIND&trfunction=K";
|
|
56
|
+
function u(e, t) {
|
|
57
|
+
return t.includes("text/html") || /^\s*<!doctype html/i.test(e) || /^\s*<html/i.test(e);
|
|
58
|
+
}
|
|
59
|
+
async function d() {
|
|
60
|
+
let t = await e(l, {
|
|
61
|
+
method: "GET",
|
|
62
|
+
headers: { Accept: "application/xml, text/xml, */*" }
|
|
63
|
+
}, ""), n = await t.text();
|
|
64
|
+
if (u(n, (t.headers.get("Content-Type") || "").toLowerCase())) throw Error("ADT вернул HTML вместо XML при запросе списка транспортов");
|
|
65
|
+
return c(n);
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { d as fetchUserTransports, c as parseUserTransportsXml };
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/adt/parseUserTransportsXml.ts","../../src/adt/fetchUserTransports.ts"],"sourcesContent":["import { arrayUniqueBy } from \"@ryuzaki13/react-foundation-lib/array\";\nimport { normalizeText } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { isRecord } from \"@ryuzaki13/react-foundation-lib/validators\";\nimport { XMLParser } from \"fast-xml-parser\";\n\nimport type { UserTransport } from \"./types\";\n\nconst parser = new XMLParser({\n\tignoreAttributes: false,\n\tattributeNamePrefix: \"\",\n\tparseTagValue: false,\n\ttrimValues: true\n});\n\nfunction collectByKey(value: unknown, key: string, result: unknown[] = []): unknown[] {\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) {\n\t\t\tcollectByKey(item, key, result);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tif (!isRecord(value)) return result;\n\n\tfor (const [entryKey, entryValue] of Object.entries(value)) {\n\t\tif (entryKey === key) {\n\t\t\tresult.push(entryValue);\n\t\t}\n\n\t\tcollectByKey(entryValue, key, result);\n\t}\n\n\treturn result;\n}\n\nfunction toTransportRecord(value: unknown): UserTransport | null {\n\tif (!isRecord(value)) return null;\n\n\tconst transportNo = normalizeText(value.TRKORR);\n\tif (!transportNo) return null;\n\n\treturn {\n\t\ttransportNo,\n\t\tdescription: normalizeText(value.AS4TEXT),\n\t\towner: normalizeText(value.AS4USER),\n\t\ttargetSystem: normalizeText(value.TARSYSTEM),\n\t\tfunctionCode: normalizeText(value.TRFUNCTION),\n\t\tstatusCode: normalizeText(value.TRSTATUS),\n\t\tparentTransportNo: normalizeText(value.STRKORR)\n\t};\n}\n\nexport function parseUserTransportsXml(xml: string): UserTransport[] {\n\tconst normalizedXml = xml.trim();\n\tif (!normalizedXml) return [];\n\n\tconst parsed = parser.parse(normalizedXml) as unknown;\n\tconst transportHeaders = collectByKey(parsed, \"CTS_REQ_HEADER\").flatMap((entry) => {\n\t\tif (Array.isArray(entry)) {\n\t\t\treturn entry.map(toTransportRecord).filter((item): item is UserTransport => item !== null);\n\t\t}\n\n\t\tconst transport = toTransportRecord(entry);\n\t\treturn transport ? [transport] : [];\n\t});\n\n\tif (transportHeaders.length > 0) {\n\t\treturn arrayUniqueBy(transportHeaders, \"transportNo\");\n\t}\n\n\tconst transportNos = collectByKey(parsed, \"TRKORR\")\n\t\t.map((value) => normalizeText(value))\n\t\t.filter((value): value is string => value !== undefined)\n\t\t.map((transportNo): UserTransport => ({\n\t\t\ttransportNo,\n\t\t\tdescription: undefined,\n\t\t\towner: undefined,\n\t\t\ttargetSystem: undefined,\n\t\t\tfunctionCode: undefined,\n\t\t\tstatusCode: undefined,\n\t\t\tparentTransportNo: undefined\n\t\t}));\n\n\treturn arrayUniqueBy(transportNos, \"transportNo\");\n}\n","import { fetchBase } from \"../odata/transport\";\n\nimport { parseUserTransportsXml } from \"./parseUserTransportsXml\";\n\nconst USER_TRANSPORTS_URL = \"/sap/bc/adt/cts/transports?_action=FIND&trfunction=K\";\n\nfunction isHtmlResponse(text: string, contentType: string) {\n\treturn contentType.includes(\"text/html\") || /^\\s*<!doctype html/i.test(text) || /^\\s*<html/i.test(text);\n}\n\nexport async function fetchUserTransports() {\n\tconst response = await fetchBase(\n\t\tUSER_TRANSPORTS_URL,\n\t\t{\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/xml, text/xml, */*\"\n\t\t\t}\n\t\t},\n\t\t\"\"\n\t);\n\n\tconst responseText = await response.text();\n\tconst contentType = (response.headers.get(\"Content-Type\") || \"\").toLowerCase();\n\n\tif (isHtmlResponse(responseText, contentType)) {\n\t\tthrow new Error(\"ADT вернул HTML вместо XML при запросе списка транспортов\");\n\t}\n\n\treturn parseUserTransportsXml(responseText);\n}\n"],"mappings":";;;;;;AAOA,IAAM,IAAS,IAAI,EAAU;CAC5B,kBAAkB;CAClB,qBAAqB;CACrB,eAAe;CACf,YAAY;AACb,CAAC;AAED,SAAS,EAAa,GAAgB,GAAa,IAAoB,CAAC,GAAc;CACrF,IAAI,MAAM,QAAQ,CAAK,GAAG;EACzB,KAAK,IAAM,KAAQ,GAClB,EAAa,GAAM,GAAK,CAAM;EAG/B,OAAO;CACR;CAEA,IAAI,CAAC,EAAS,CAAK,GAAG,OAAO;CAE7B,KAAK,IAAM,CAAC,GAAU,MAAe,OAAO,QAAQ,CAAK,GAKxD,AAJI,MAAa,KAChB,EAAO,KAAK,CAAU,GAGvB,EAAa,GAAY,GAAK,CAAM;CAGrC,OAAO;AACR;AAEA,SAAS,EAAkB,GAAsC;CAChE,IAAI,CAAC,EAAS,CAAK,GAAG,OAAO;CAE7B,IAAM,IAAc,EAAc,EAAM,MAAM;CAG9C,OAFK,IAEE;EACN;EACA,aAAa,EAAc,EAAM,OAAO;EACxC,OAAO,EAAc,EAAM,OAAO;EAClC,cAAc,EAAc,EAAM,SAAS;EAC3C,cAAc,EAAc,EAAM,UAAU;EAC5C,YAAY,EAAc,EAAM,QAAQ;EACxC,mBAAmB,EAAc,EAAM,OAAO;CAC/C,IAVyB;AAW1B;AAEA,SAAgB,EAAuB,GAA8B;CACpE,IAAM,IAAgB,EAAI,KAAK;CAC/B,IAAI,CAAC,GAAe,OAAO,CAAC;CAE5B,IAAM,IAAS,EAAO,MAAM,CAAa,GACnC,IAAmB,EAAa,GAAQ,gBAAgB,CAAC,CAAC,SAAS,MAAU;EAClF,IAAI,MAAM,QAAQ,CAAK,GACtB,OAAO,EAAM,IAAI,CAAiB,CAAC,CAAC,QAAQ,MAAgC,MAAS,IAAI;EAG1F,IAAM,IAAY,EAAkB,CAAK;EACzC,OAAO,IAAY,CAAC,CAAS,IAAI,CAAC;CACnC,CAAC;CAmBD,OAjBI,EAAiB,SAAS,IACtB,EAAc,GAAkB,aAAa,IAgB9C,EAbc,EAAa,GAAQ,QAAQ,CAAC,CACjD,KAAK,MAAU,EAAc,CAAK,CAAC,CAAC,CACpC,QAAQ,MAA2B,MAAU,KAAA,CAAS,CAAC,CACvD,KAAK,OAAgC;EACrC;EACA,aAAa,KAAA;EACb,OAAO,KAAA;EACP,cAAc,KAAA;EACd,cAAc,KAAA;EACd,YAAY,KAAA;EACZ,mBAAmB,KAAA;CACpB,EAEoB,GAAc,aAAa;AACjD;;;ACjFA,IAAM,IAAsB;AAE5B,SAAS,EAAe,GAAc,GAAqB;CAC1D,OAAO,EAAY,SAAS,WAAW,KAAK,sBAAsB,KAAK,CAAI,KAAK,aAAa,KAAK,CAAI;AACvG;AAEA,eAAsB,IAAsB;CAC3C,IAAM,IAAW,MAAM,EACtB,GACA;EACC,QAAQ;EACR,SAAS,EACR,QAAQ,iCACT;CACD,GACA,EACD,GAEM,IAAe,MAAM,EAAS,KAAK;CAGzC,IAAI,EAAe,IAFE,EAAS,QAAQ,IAAI,cAAc,KAAK,GAAA,CAAI,YAEhC,CAAW,GAC3C,MAAU,MAAM,2DAA2D;CAG5E,OAAO,EAAuB,CAAY;AAC3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseUserTransportsXml.d.ts","sourceRoot":"","sources":["../../src/adt/parseUserTransportsXml.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAgD7C,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE,CAgCnE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface UserTransport {
|
|
2
|
+
transportNo: string;
|
|
3
|
+
description: string | undefined;
|
|
4
|
+
owner: string | undefined;
|
|
5
|
+
targetSystem: string | undefined;
|
|
6
|
+
functionCode: string | undefined;
|
|
7
|
+
statusCode: string | undefined;
|
|
8
|
+
parentTransportNo: string | undefined;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adt/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RunAsyncTasksResult } from "./runAsyncTasks";
|
|
2
|
+
export declare class AsyncTasksError<TResult = unknown> extends Error {
|
|
3
|
+
readonly result: RunAsyncTasksResult<TResult>;
|
|
4
|
+
constructor(message: string, result: RunAsyncTasksResult<TResult>);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=AsyncTasksError.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AsyncTasksError.d.ts","sourceRoot":"","sources":["../../src/async/AsyncTasksError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,qBAAa,eAAe,CAAC,OAAO,GAAG,OAAO,CAAE,SAAQ,KAAK;IAC5D,SAAgB,MAAM,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC;gBAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,CAAC;CAKjE"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { RunConcurrentTasksResult } from "./runConcurrentTasks";
|
|
2
|
+
export declare class ConcurrencyPartialError<TInput, TResult> extends Error {
|
|
3
|
+
readonly result: RunConcurrentTasksResult<TInput, TResult>;
|
|
4
|
+
constructor(message: string, result: RunConcurrentTasksResult<TInput, TResult>);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=ConcurrencyPartialError.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConcurrencyPartialError.d.ts","sourceRoot":"","sources":["../../src/async/ConcurrencyPartialError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,qBAAa,uBAAuB,CAAC,MAAM,EAAE,OAAO,CAAE,SAAQ,KAAK;IAClE,SAAgB,MAAM,EAAE,wBAAwB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,wBAAwB,CAAC,MAAM,EAAE,OAAO,CAAC;CAK9E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/async/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
//#region src/async/AsyncTasksError.ts
|
|
2
|
+
var e = class extends Error {
|
|
3
|
+
result;
|
|
4
|
+
constructor(e, t) {
|
|
5
|
+
super(e), this.name = "AsyncTasksError", this.result = t;
|
|
6
|
+
}
|
|
7
|
+
}, t = class extends Error {
|
|
8
|
+
result;
|
|
9
|
+
constructor(e, t) {
|
|
10
|
+
super(e), this.name = "ConcurrencyPartialError", this.result = t;
|
|
11
|
+
}
|
|
12
|
+
}, n = "Не удалось выполнить все асинхронные задачи.";
|
|
13
|
+
async function r(e, t) {
|
|
14
|
+
try {
|
|
15
|
+
let n = await e.run();
|
|
16
|
+
return {
|
|
17
|
+
status: "fulfilled",
|
|
18
|
+
index: t,
|
|
19
|
+
name: e.name,
|
|
20
|
+
data: n
|
|
21
|
+
};
|
|
22
|
+
} catch (n) {
|
|
23
|
+
return {
|
|
24
|
+
status: "rejected",
|
|
25
|
+
index: t,
|
|
26
|
+
name: e.name,
|
|
27
|
+
error: n
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function i(e) {
|
|
32
|
+
let t = [], n = [];
|
|
33
|
+
for (let r of e) switch (r.status) {
|
|
34
|
+
case "fulfilled":
|
|
35
|
+
t.push(r);
|
|
36
|
+
break;
|
|
37
|
+
case "rejected":
|
|
38
|
+
n.push(r);
|
|
39
|
+
break;
|
|
40
|
+
default:
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
successes: t,
|
|
44
|
+
errors: n
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function a(e) {
|
|
48
|
+
let { successes: t, errors: n } = i(e);
|
|
49
|
+
return {
|
|
50
|
+
settled: e,
|
|
51
|
+
successes: t,
|
|
52
|
+
errors: n,
|
|
53
|
+
summary: {
|
|
54
|
+
total: e.length,
|
|
55
|
+
succeeded: t.length,
|
|
56
|
+
failed: n.length
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
async function o(t, i = {}) {
|
|
61
|
+
let o = a(await Promise.all(t.map((e, t) => r(e, t))));
|
|
62
|
+
if (o.errors.length > 0) throw new e(i.errorMessage ?? n, o);
|
|
63
|
+
return o;
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/async/runConcurrentTasks.ts
|
|
67
|
+
function s(e) {
|
|
68
|
+
if (!Number.isInteger(e)) throw TypeError("concurrency должен быть целым числом");
|
|
69
|
+
if (e < 1) throw RangeError("concurrency должен быть >= 1");
|
|
70
|
+
}
|
|
71
|
+
async function c(e, t, n = {}) {
|
|
72
|
+
let { concurrency: r = 4, signal: i, onProgress: a, onItemSuccess: o, onItemError: c } = n;
|
|
73
|
+
if (s(r), e.length === 0) return {
|
|
74
|
+
settled: [],
|
|
75
|
+
successes: [],
|
|
76
|
+
errors: [],
|
|
77
|
+
unprocessed: [],
|
|
78
|
+
aborted: !!i?.aborted,
|
|
79
|
+
summary: {
|
|
80
|
+
total: 0,
|
|
81
|
+
completed: 0,
|
|
82
|
+
succeeded: 0,
|
|
83
|
+
failed: 0,
|
|
84
|
+
unprocessed: 0
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
let l = Array(e.length), u = 0, d = 0, f = 0, p = 0, m = 0, h = () => !!i?.aborted, g = (t) => {
|
|
88
|
+
a?.({
|
|
89
|
+
total: e.length,
|
|
90
|
+
completed: d,
|
|
91
|
+
succeeded: f,
|
|
92
|
+
failed: p,
|
|
93
|
+
running: m,
|
|
94
|
+
pending: Math.max(e.length - d - m, 0),
|
|
95
|
+
percentage: e.length === 0 ? 100 : Math.round(d / e.length * 100),
|
|
96
|
+
aborted: h(),
|
|
97
|
+
lastSettled: t
|
|
98
|
+
});
|
|
99
|
+
}, _ = Math.min(r, e.length), v = async () => {
|
|
100
|
+
for (;;) {
|
|
101
|
+
if (h()) return;
|
|
102
|
+
let n = u;
|
|
103
|
+
if (u += 1, n >= e.length) return;
|
|
104
|
+
let r = e[n];
|
|
105
|
+
m += 1;
|
|
106
|
+
try {
|
|
107
|
+
let e = {
|
|
108
|
+
status: "fulfilled",
|
|
109
|
+
index: n,
|
|
110
|
+
input: r,
|
|
111
|
+
data: await t(r, {
|
|
112
|
+
index: n,
|
|
113
|
+
signal: i
|
|
114
|
+
})
|
|
115
|
+
};
|
|
116
|
+
l[n] = e, f += 1, o?.(e);
|
|
117
|
+
} catch (e) {
|
|
118
|
+
let t = {
|
|
119
|
+
status: "rejected",
|
|
120
|
+
index: n,
|
|
121
|
+
input: r,
|
|
122
|
+
error: e
|
|
123
|
+
};
|
|
124
|
+
l[n] = t, p += 1, c?.(t);
|
|
125
|
+
} finally {
|
|
126
|
+
--m, d += 1;
|
|
127
|
+
let e = l[n];
|
|
128
|
+
e && g(e);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
await Promise.all(Array.from({ length: _ }, () => v()));
|
|
133
|
+
let y = [], b = [], x = [], S = [];
|
|
134
|
+
for (let [t, n] of e.entries()) {
|
|
135
|
+
let e = l[t];
|
|
136
|
+
if (!e) {
|
|
137
|
+
S.push({
|
|
138
|
+
index: t,
|
|
139
|
+
input: n
|
|
140
|
+
});
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
y.push(e), e.status === "fulfilled" ? b.push(e) : x.push(e);
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
settled: y,
|
|
147
|
+
successes: b,
|
|
148
|
+
errors: x,
|
|
149
|
+
unprocessed: S,
|
|
150
|
+
aborted: h(),
|
|
151
|
+
summary: {
|
|
152
|
+
total: e.length,
|
|
153
|
+
completed: y.length,
|
|
154
|
+
succeeded: b.length,
|
|
155
|
+
failed: x.length,
|
|
156
|
+
unprocessed: S.length
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
export { e as AsyncTasksError, t as ConcurrencyPartialError, o as runAsyncTasks, c as runConcurrentTasks };
|
|
162
|
+
|
|
163
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/async/AsyncTasksError.ts","../../src/async/ConcurrencyPartialError.ts","../../src/async/runAsyncTasks.ts","../../src/async/runConcurrentTasks.ts"],"sourcesContent":["import type { RunAsyncTasksResult } from \"./runAsyncTasks\";\n\nexport class AsyncTasksError<TResult = unknown> extends Error {\n\tpublic readonly result: RunAsyncTasksResult<TResult>;\n\n\tconstructor(message: string, result: RunAsyncTasksResult<TResult>) {\n\t\tsuper(message);\n\t\tthis.name = \"AsyncTasksError\";\n\t\tthis.result = result;\n\t}\n}\n","import { RunConcurrentTasksResult } from \"./runConcurrentTasks\";\n\nexport class ConcurrencyPartialError<TInput, TResult> extends Error {\n\tpublic readonly result: RunConcurrentTasksResult<TInput, TResult>;\n\n\tconstructor(message: string, result: RunConcurrentTasksResult<TInput, TResult>) {\n\t\tsuper(message);\n\t\tthis.name = \"ConcurrencyPartialError\";\n\t\tthis.result = result;\n\t}\n}\n","import { AsyncTasksError } from \"./AsyncTasksError\";\n\nexport type AsyncTask<TResult = unknown> = {\n\treadonly name: string;\n\treadonly run: () => Promise<TResult>;\n};\n\nexport type AsyncTaskSuccess<TResult> = {\n\treadonly status: \"fulfilled\";\n\treadonly index: number;\n\treadonly name: string;\n\treadonly data: TResult;\n};\n\nexport type AsyncTaskFailure = {\n\treadonly status: \"rejected\";\n\treadonly index: number;\n\treadonly name: string;\n\treadonly error: unknown;\n};\n\nexport type AsyncTaskSettled<TResult> = AsyncTaskSuccess<TResult> | AsyncTaskFailure;\n\nexport type RunAsyncTasksResult<TResult = unknown> = {\n\treadonly settled: readonly AsyncTaskSettled<TResult>[];\n\treadonly successes: readonly AsyncTaskSuccess<TResult>[];\n\treadonly errors: readonly AsyncTaskFailure[];\n\treadonly summary: {\n\t\treadonly total: number;\n\t\treadonly succeeded: number;\n\t\treadonly failed: number;\n\t};\n};\n\nexport type RunAsyncTasksOptions = {\n\treadonly errorMessage?: string;\n};\n\nconst DEFAULT_ASYNC_TASKS_ERROR_MESSAGE = \"Не удалось выполнить все асинхронные задачи.\";\n\nasync function runSingleAsyncTask<TResult>(task: AsyncTask<TResult>, index: number): Promise<AsyncTaskSettled<TResult>> {\n\ttry {\n\t\tconst data = await task.run();\n\n\t\treturn {\n\t\t\tstatus: \"fulfilled\",\n\t\t\tindex,\n\t\t\tname: task.name,\n\t\t\tdata\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tstatus: \"rejected\",\n\t\t\tindex,\n\t\t\tname: task.name,\n\t\t\terror\n\t\t};\n\t}\n}\n\nfunction splitAsyncTaskSettled<TResult>(\n\tsettled: readonly AsyncTaskSettled<TResult>[]\n): Pick<RunAsyncTasksResult<TResult>, \"successes\" | \"errors\"> {\n\tconst successes: AsyncTaskSuccess<TResult>[] = [];\n\tconst errors: AsyncTaskFailure[] = [];\n\n\tfor (const item of settled) {\n\t\tswitch (item.status) {\n\t\t\tcase \"fulfilled\": {\n\t\t\t\tsuccesses.push(item);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"rejected\": {\n\t\t\t\terrors.push(item);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst checker: never = item;\n\t\t\t\tvoid checker;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tsuccesses,\n\t\terrors\n\t};\n}\n\nfunction createRunAsyncTasksResult<TResult>(settled: readonly AsyncTaskSettled<TResult>[]): RunAsyncTasksResult<TResult> {\n\tconst { successes, errors } = splitAsyncTaskSettled(settled);\n\n\treturn {\n\t\tsettled,\n\t\tsuccesses,\n\t\terrors,\n\t\tsummary: {\n\t\t\ttotal: settled.length,\n\t\t\tsucceeded: successes.length,\n\t\t\tfailed: errors.length\n\t\t}\n\t};\n}\n\nexport async function runAsyncTasks<TResult>(\n\ttasks: readonly AsyncTask<TResult>[],\n\toptions: RunAsyncTasksOptions = {}\n): Promise<RunAsyncTasksResult<TResult>> {\n\tconst settled = await Promise.all(tasks.map((task, index) => runSingleAsyncTask(task, index)));\n\tconst result = createRunAsyncTasksResult(settled);\n\n\tif (result.errors.length > 0) {\n\t\tthrow new AsyncTasksError(options.errorMessage ?? DEFAULT_ASYNC_TASKS_ERROR_MESSAGE, result);\n\t}\n\n\treturn result;\n}\n","export type ConcurrentTaskContext = {\n\t/**\n\t * Индекс элемента во входном массиве.\n\t */\n\tindex: number;\n\n\t/**\n\t * Внешний AbortSignal.\n\t * Важно: helper сам не может \"магически\" отменить уже начатую async-операцию.\n\t * Для реальной отмены нужно пробрасывать signal внутрь task\n\t * и чтобы сама реализация task его поддерживала.\n\t */\n\tsignal?: AbortSignal;\n};\n\nexport type ConcurrentTaskFn<TInput, TResult> = (input: TInput, context: ConcurrentTaskContext) => Promise<TResult>;\n\nexport type ConcurrentTaskSuccess<TInput, TResult> = {\n\tstatus: \"fulfilled\";\n\tindex: number;\n\tinput: TInput;\n\tdata: TResult;\n};\n\nexport type ConcurrentTaskError<TInput> = {\n\tstatus: \"rejected\";\n\tindex: number;\n\tinput: TInput;\n\terror: unknown;\n};\n\nexport type ConcurrentTaskSettled<TInput, TResult> = ConcurrentTaskSuccess<TInput, TResult> | ConcurrentTaskError<TInput>;\n\nexport type ConcurrentTaskUnprocessed<TInput> = {\n\tindex: number;\n\tinput: TInput;\n};\n\nexport type ConcurrentTaskProgress<TInput, TResult> = {\n\ttotal: number;\n\tcompleted: number;\n\tsucceeded: number;\n\tfailed: number;\n\trunning: number;\n\tpending: number;\n\tpercentage: number;\n\taborted: boolean;\n\tlastSettled?: ConcurrentTaskSettled<TInput, TResult>;\n};\n\nexport type RunConcurrentTasksOptions<TInput, TResult> = {\n\t/**\n\t * Максимальное количество одновременно выполняемых задач.\n\t *\n\t * @default 4\n\t */\n\tconcurrency?: number;\n\n\t/**\n\t * Внешний AbortSignal.\n\t *\n\t * Поведение при abort:\n\t * - новые задачи больше не стартуют;\n\t * - уже начатые задачи helper не прерывает сам;\n\t * - функция возвращает partial result с `aborted: true`.\n\t */\n\tsignal?: AbortSignal;\n\n\t/**\n\t * Вызывается после каждого завершенного элемента.\n\t *\n\t * ### Важно: callback не должен бросать исключения.\n\t */\n\tonProgress?: (progress: ConcurrentTaskProgress<TInput, TResult>) => void;\n\n\t/**\n\t * Вызывается при успешной обработке одного элемента.\n\t *\n\t * ### Важно: callback не должен бросать исключения.\n\t */\n\tonItemSuccess?: (item: ConcurrentTaskSuccess<TInput, TResult>) => void;\n\n\t/**\n\t * Вызывается при ошибке одного элемента.\n\t *\n\t * ### Важно: callback не должен бросать исключения.\n\t */\n\tonItemError?: (item: ConcurrentTaskError<TInput>) => void;\n};\n\nexport type RunConcurrentTasksResult<TInput, TResult> = {\n\t/**\n\t * Итоги по каждому обработанному элементу в порядке исходного массива.\n\t * Необработанные элементы сюда не попадают.\n\t */\n\tsettled: ConcurrentTaskSettled<TInput, TResult>[];\n\n\t/**\n\t * Только успешные элементы.\n\t */\n\tsuccesses: ConcurrentTaskSuccess<TInput, TResult>[];\n\n\t/**\n\t * Только ошибки.\n\t */\n\terrors: ConcurrentTaskError<TInput>[];\n\n\t/**\n\t * Элементы, которые не были запущены.\n\t * Обычно это актуально при abort.\n\t */\n\tunprocessed: ConcurrentTaskUnprocessed<TInput>[];\n\n\t/**\n\t * Был ли batch прерван внешним signal.\n\t */\n\taborted: boolean;\n\n\t/**\n\t * Сводка для UI/логов.\n\t */\n\tsummary: {\n\t\ttotal: number;\n\t\tcompleted: number;\n\t\tsucceeded: number;\n\t\tfailed: number;\n\t\tunprocessed: number;\n\t};\n};\n\nfunction validateConcurrency(concurrency: number): void {\n\tif (!Number.isInteger(concurrency)) {\n\t\tthrow new TypeError(\"concurrency должен быть целым числом\");\n\t}\n\n\tif (concurrency < 1) {\n\t\tthrow new RangeError(\"concurrency должен быть >= 1\");\n\t}\n}\n\n/**\n * Выполняет задачи над набором входных данных с ограничением по параллелизму.\n *\n * Ключевые свойства:\n * - не останавливается на первой ошибке;\n * - всегда собирает полный список success/error для уже стартовавших задач;\n * - поддерживает progress callbacks;\n * - поддерживает abort на уровне постановки новых задач;\n * - не зависит от конкретного transport/query stack.\n *\n * Исключения:\n * - выбрасывает только при невалидных аргументах;\n * - ошибки отдельных задач НЕ выбрасываются наружу, а попадают в `result.errors`.\n */\nexport async function runConcurrentTasks<TInput, TResult>(\n\tinputs: readonly TInput[],\n\ttask: ConcurrentTaskFn<TInput, TResult>,\n\toptions: RunConcurrentTasksOptions<TInput, TResult> = {}\n): Promise<RunConcurrentTasksResult<TInput, TResult>> {\n\tconst { concurrency = 4, signal, onProgress, onItemSuccess, onItemError } = options;\n\n\tvalidateConcurrency(concurrency);\n\n\tif (inputs.length === 0) {\n\t\treturn {\n\t\t\tsettled: [],\n\t\t\tsuccesses: [],\n\t\t\terrors: [],\n\t\t\tunprocessed: [],\n\t\t\taborted: Boolean(signal?.aborted),\n\t\t\tsummary: {\n\t\t\t\ttotal: 0,\n\t\t\t\tcompleted: 0,\n\t\t\t\tsucceeded: 0,\n\t\t\t\tfailed: 0,\n\t\t\t\tunprocessed: 0\n\t\t\t}\n\t\t};\n\t}\n\n\tconst settledByIndex = new Array<ConcurrentTaskSettled<TInput, TResult> | undefined>(inputs.length);\n\n\tlet nextIndex = 0;\n\tlet completed = 0;\n\tlet succeeded = 0;\n\tlet failed = 0;\n\tlet running = 0;\n\n\tconst isAborted = (): boolean => Boolean(signal?.aborted);\n\n\tconst emitProgress = (lastSettled?: ConcurrentTaskSettled<TInput, TResult>): void => {\n\t\tonProgress?.({\n\t\t\ttotal: inputs.length,\n\t\t\tcompleted,\n\t\t\tsucceeded,\n\t\t\tfailed,\n\t\t\trunning,\n\t\t\tpending: Math.max(inputs.length - completed - running, 0),\n\t\t\tpercentage: inputs.length === 0 ? 100 : Math.round((completed / inputs.length) * 100),\n\t\t\taborted: isAborted(),\n\t\t\tlastSettled\n\t\t});\n\t};\n\n\tconst workerCount = Math.min(concurrency, inputs.length);\n\n\tconst worker = async (): Promise<void> => {\n\t\twhile (true) {\n\t\t\tif (isAborted()) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst currentIndex = nextIndex;\n\t\t\tnextIndex += 1;\n\n\t\t\tif (currentIndex >= inputs.length) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst input = inputs[currentIndex];\n\t\t\trunning += 1;\n\n\t\t\ttry {\n\t\t\t\tconst data = await task(input, {\n\t\t\t\t\tindex: currentIndex,\n\t\t\t\t\tsignal\n\t\t\t\t});\n\n\t\t\t\tconst item: ConcurrentTaskSuccess<TInput, TResult> = {\n\t\t\t\t\tstatus: \"fulfilled\",\n\t\t\t\t\tindex: currentIndex,\n\t\t\t\t\tinput,\n\t\t\t\t\tdata\n\t\t\t\t};\n\n\t\t\t\tsettledByIndex[currentIndex] = item;\n\t\t\t\tsucceeded += 1;\n\t\t\t\tonItemSuccess?.(item);\n\t\t\t} catch (error) {\n\t\t\t\tconst item: ConcurrentTaskError<TInput> = {\n\t\t\t\t\tstatus: \"rejected\",\n\t\t\t\t\tindex: currentIndex,\n\t\t\t\t\tinput,\n\t\t\t\t\terror\n\t\t\t\t};\n\n\t\t\t\tsettledByIndex[currentIndex] = item;\n\t\t\t\tfailed += 1;\n\t\t\t\tonItemError?.(item);\n\t\t\t} finally {\n\t\t\t\trunning -= 1;\n\t\t\t\tcompleted += 1;\n\n\t\t\t\tconst settledItem = settledByIndex[currentIndex];\n\t\t\t\tif (settledItem) {\n\t\t\t\t\temitProgress(settledItem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tawait Promise.all(Array.from({ length: workerCount }, () => worker()));\n\n\tconst settled: ConcurrentTaskSettled<TInput, TResult>[] = [];\n\tconst successes: ConcurrentTaskSuccess<TInput, TResult>[] = [];\n\tconst errors: ConcurrentTaskError<TInput>[] = [];\n\tconst unprocessed: ConcurrentTaskUnprocessed<TInput>[] = [];\n\n\tfor (const [index, input] of inputs.entries()) {\n\t\tconst item = settledByIndex[index];\n\n\t\tif (!item) {\n\t\t\tunprocessed.push({ index, input });\n\t\t\tcontinue;\n\t\t}\n\n\t\tsettled.push(item);\n\n\t\tif (item.status === \"fulfilled\") {\n\t\t\tsuccesses.push(item);\n\t\t} else {\n\t\t\terrors.push(item);\n\t\t}\n\t}\n\n\treturn {\n\t\tsettled,\n\t\tsuccesses,\n\t\terrors,\n\t\tunprocessed,\n\t\taborted: isAborted(),\n\t\tsummary: {\n\t\t\ttotal: inputs.length,\n\t\t\tcompleted: settled.length,\n\t\t\tsucceeded: successes.length,\n\t\t\tfailed: errors.length,\n\t\t\tunprocessed: unprocessed.length\n\t\t}\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type AsyncTask<TResult = unknown> = {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly run: () => Promise<TResult>;
|
|
4
|
+
};
|
|
5
|
+
export type AsyncTaskSuccess<TResult> = {
|
|
6
|
+
readonly status: "fulfilled";
|
|
7
|
+
readonly index: number;
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly data: TResult;
|
|
10
|
+
};
|
|
11
|
+
export type AsyncTaskFailure = {
|
|
12
|
+
readonly status: "rejected";
|
|
13
|
+
readonly index: number;
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly error: unknown;
|
|
16
|
+
};
|
|
17
|
+
export type AsyncTaskSettled<TResult> = AsyncTaskSuccess<TResult> | AsyncTaskFailure;
|
|
18
|
+
export type RunAsyncTasksResult<TResult = unknown> = {
|
|
19
|
+
readonly settled: readonly AsyncTaskSettled<TResult>[];
|
|
20
|
+
readonly successes: readonly AsyncTaskSuccess<TResult>[];
|
|
21
|
+
readonly errors: readonly AsyncTaskFailure[];
|
|
22
|
+
readonly summary: {
|
|
23
|
+
readonly total: number;
|
|
24
|
+
readonly succeeded: number;
|
|
25
|
+
readonly failed: number;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export type RunAsyncTasksOptions = {
|
|
29
|
+
readonly errorMessage?: string;
|
|
30
|
+
};
|
|
31
|
+
export declare function runAsyncTasks<TResult>(tasks: readonly AsyncTask<TResult>[], options?: RunAsyncTasksOptions): Promise<RunAsyncTasksResult<TResult>>;
|
|
32
|
+
//# sourceMappingURL=runAsyncTasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runAsyncTasks.d.ts","sourceRoot":"","sources":["../../src/async/runAsyncTasks.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,CAAC,OAAO,GAAG,OAAO,IAAI;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAAI;IACvC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAAI,gBAAgB,CAAC,OAAO,CAAC,GAAG,gBAAgB,CAAC;AAErF,MAAM,MAAM,mBAAmB,CAAC,OAAO,GAAG,OAAO,IAAI;IACpD,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;IACvD,QAAQ,CAAC,SAAS,EAAE,SAAS,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;IACzD,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE;QACjB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACxB,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAClC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAsEF,wBAAsB,aAAa,CAAC,OAAO,EAC1C,KAAK,EAAE,SAAS,SAAS,CAAC,OAAO,CAAC,EAAE,EACpC,OAAO,GAAE,oBAAyB,GAChC,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CASvC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export type ConcurrentTaskContext = {
|
|
2
|
+
/**
|
|
3
|
+
* Индекс элемента во входном массиве.
|
|
4
|
+
*/
|
|
5
|
+
index: number;
|
|
6
|
+
/**
|
|
7
|
+
* Внешний AbortSignal.
|
|
8
|
+
* Важно: helper сам не может "магически" отменить уже начатую async-операцию.
|
|
9
|
+
* Для реальной отмены нужно пробрасывать signal внутрь task
|
|
10
|
+
* и чтобы сама реализация task его поддерживала.
|
|
11
|
+
*/
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
};
|
|
14
|
+
export type ConcurrentTaskFn<TInput, TResult> = (input: TInput, context: ConcurrentTaskContext) => Promise<TResult>;
|
|
15
|
+
export type ConcurrentTaskSuccess<TInput, TResult> = {
|
|
16
|
+
status: "fulfilled";
|
|
17
|
+
index: number;
|
|
18
|
+
input: TInput;
|
|
19
|
+
data: TResult;
|
|
20
|
+
};
|
|
21
|
+
export type ConcurrentTaskError<TInput> = {
|
|
22
|
+
status: "rejected";
|
|
23
|
+
index: number;
|
|
24
|
+
input: TInput;
|
|
25
|
+
error: unknown;
|
|
26
|
+
};
|
|
27
|
+
export type ConcurrentTaskSettled<TInput, TResult> = ConcurrentTaskSuccess<TInput, TResult> | ConcurrentTaskError<TInput>;
|
|
28
|
+
export type ConcurrentTaskUnprocessed<TInput> = {
|
|
29
|
+
index: number;
|
|
30
|
+
input: TInput;
|
|
31
|
+
};
|
|
32
|
+
export type ConcurrentTaskProgress<TInput, TResult> = {
|
|
33
|
+
total: number;
|
|
34
|
+
completed: number;
|
|
35
|
+
succeeded: number;
|
|
36
|
+
failed: number;
|
|
37
|
+
running: number;
|
|
38
|
+
pending: number;
|
|
39
|
+
percentage: number;
|
|
40
|
+
aborted: boolean;
|
|
41
|
+
lastSettled?: ConcurrentTaskSettled<TInput, TResult>;
|
|
42
|
+
};
|
|
43
|
+
export type RunConcurrentTasksOptions<TInput, TResult> = {
|
|
44
|
+
/**
|
|
45
|
+
* Максимальное количество одновременно выполняемых задач.
|
|
46
|
+
*
|
|
47
|
+
* @default 4
|
|
48
|
+
*/
|
|
49
|
+
concurrency?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Внешний AbortSignal.
|
|
52
|
+
*
|
|
53
|
+
* Поведение при abort:
|
|
54
|
+
* - новые задачи больше не стартуют;
|
|
55
|
+
* - уже начатые задачи helper не прерывает сам;
|
|
56
|
+
* - функция возвращает partial result с `aborted: true`.
|
|
57
|
+
*/
|
|
58
|
+
signal?: AbortSignal;
|
|
59
|
+
/**
|
|
60
|
+
* Вызывается после каждого завершенного элемента.
|
|
61
|
+
*
|
|
62
|
+
* ### Важно: callback не должен бросать исключения.
|
|
63
|
+
*/
|
|
64
|
+
onProgress?: (progress: ConcurrentTaskProgress<TInput, TResult>) => void;
|
|
65
|
+
/**
|
|
66
|
+
* Вызывается при успешной обработке одного элемента.
|
|
67
|
+
*
|
|
68
|
+
* ### Важно: callback не должен бросать исключения.
|
|
69
|
+
*/
|
|
70
|
+
onItemSuccess?: (item: ConcurrentTaskSuccess<TInput, TResult>) => void;
|
|
71
|
+
/**
|
|
72
|
+
* Вызывается при ошибке одного элемента.
|
|
73
|
+
*
|
|
74
|
+
* ### Важно: callback не должен бросать исключения.
|
|
75
|
+
*/
|
|
76
|
+
onItemError?: (item: ConcurrentTaskError<TInput>) => void;
|
|
77
|
+
};
|
|
78
|
+
export type RunConcurrentTasksResult<TInput, TResult> = {
|
|
79
|
+
/**
|
|
80
|
+
* Итоги по каждому обработанному элементу в порядке исходного массива.
|
|
81
|
+
* Необработанные элементы сюда не попадают.
|
|
82
|
+
*/
|
|
83
|
+
settled: ConcurrentTaskSettled<TInput, TResult>[];
|
|
84
|
+
/**
|
|
85
|
+
* Только успешные элементы.
|
|
86
|
+
*/
|
|
87
|
+
successes: ConcurrentTaskSuccess<TInput, TResult>[];
|
|
88
|
+
/**
|
|
89
|
+
* Только ошибки.
|
|
90
|
+
*/
|
|
91
|
+
errors: ConcurrentTaskError<TInput>[];
|
|
92
|
+
/**
|
|
93
|
+
* Элементы, которые не были запущены.
|
|
94
|
+
* Обычно это актуально при abort.
|
|
95
|
+
*/
|
|
96
|
+
unprocessed: ConcurrentTaskUnprocessed<TInput>[];
|
|
97
|
+
/**
|
|
98
|
+
* Был ли batch прерван внешним signal.
|
|
99
|
+
*/
|
|
100
|
+
aborted: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Сводка для UI/логов.
|
|
103
|
+
*/
|
|
104
|
+
summary: {
|
|
105
|
+
total: number;
|
|
106
|
+
completed: number;
|
|
107
|
+
succeeded: number;
|
|
108
|
+
failed: number;
|
|
109
|
+
unprocessed: number;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Выполняет задачи над набором входных данных с ограничением по параллелизму.
|
|
114
|
+
*
|
|
115
|
+
* Ключевые свойства:
|
|
116
|
+
* - не останавливается на первой ошибке;
|
|
117
|
+
* - всегда собирает полный список success/error для уже стартовавших задач;
|
|
118
|
+
* - поддерживает progress callbacks;
|
|
119
|
+
* - поддерживает abort на уровне постановки новых задач;
|
|
120
|
+
* - не зависит от конкретного transport/query stack.
|
|
121
|
+
*
|
|
122
|
+
* Исключения:
|
|
123
|
+
* - выбрасывает только при невалидных аргументах;
|
|
124
|
+
* - ошибки отдельных задач НЕ выбрасываются наружу, а попадают в `result.errors`.
|
|
125
|
+
*/
|
|
126
|
+
export declare function runConcurrentTasks<TInput, TResult>(inputs: readonly TInput[], task: ConcurrentTaskFn<TInput, TResult>, options?: RunConcurrentTasksOptions<TInput, TResult>): Promise<RunConcurrentTasksResult<TInput, TResult>>;
|
|
127
|
+
//# sourceMappingURL=runConcurrentTasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runConcurrentTasks.d.ts","sourceRoot":"","sources":["../../src/async/runConcurrentTasks.ts"],"names":[],"mappings":"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"}
|