@hardlydifficult/collections 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/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # @hardlydifficult/collections
2
+
3
+ Array and collection utilities for batched parallel processing.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @hardlydifficult/collections
9
+ ```
10
+
11
+ ## API
12
+
13
+ ### `chunk<T>(arr: readonly T[], size: number): T[][]`
14
+
15
+ Split an array into chunks of a given size. Useful for processing items in parallel batches with a concurrency limit.
16
+
17
+ ```typescript
18
+ import { chunk } from "@hardlydifficult/collections";
19
+
20
+ const items = [1, 2, 3, 4, 5, 6, 7];
21
+ const batches = chunk(items, 3);
22
+ // [[1, 2, 3], [4, 5, 6], [7]]
23
+
24
+ for (const batch of batches) {
25
+ await Promise.allSettled(batch.map(processItem));
26
+ }
27
+ ```
28
+
29
+ ### `groupByDepth(paths: readonly string[]): { depth: number; paths: string[] }[]`
30
+
31
+ Group `/`-separated path strings by their depth, sorted deepest-first. Useful for bottom-up directory processing where children must be handled before parents.
32
+
33
+ ```typescript
34
+ import { groupByDepth } from "@hardlydifficult/collections";
35
+
36
+ const dirs = ["src/services/summarize", "src/services", "src", "src/utils"];
37
+ groupByDepth(dirs);
38
+ // [
39
+ // { depth: 3, paths: ["src/services/summarize"] },
40
+ // { depth: 2, paths: ["src/services", "src/utils"] },
41
+ // { depth: 1, paths: ["src"] },
42
+ // ]
43
+
44
+ // Process directories bottom-up, parallelizing within each depth level
45
+ for (const { paths: dirsAtDepth } of groupByDepth(dirs)) {
46
+ await Promise.allSettled(dirsAtDepth.map(summarizeDir));
47
+ }
48
+ ```
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Split an array into chunks of a given size.
3
+ */
4
+ export declare function chunk<T>(arr: readonly T[], size: number): T[][];
5
+ //# sourceMappingURL=chunk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk.d.ts","sourceRoot":"","sources":["../src/chunk.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAM/D"}
package/dist/chunk.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.chunk = chunk;
4
+ /**
5
+ * Split an array into chunks of a given size.
6
+ */
7
+ function chunk(arr, size) {
8
+ const result = [];
9
+ for (let i = 0; i < arr.length; i += size) {
10
+ result.push(arr.slice(i, i + size));
11
+ }
12
+ return result;
13
+ }
14
+ //# sourceMappingURL=chunk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk.js","sourceRoot":"","sources":["../src/chunk.ts"],"names":[],"mappings":";;AAGA,sBAMC;AATD;;GAEG;AACH,SAAgB,KAAK,CAAI,GAAiB,EAAE,IAAY;IACtD,MAAM,MAAM,GAAU,EAAE,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Group path strings by their `/`-separated depth, sorted deepest-first.
3
+ * Useful for bottom-up directory processing where children must be handled before parents.
4
+ */
5
+ export declare function groupByDepth(paths: readonly string[]): {
6
+ depth: number;
7
+ paths: string[];
8
+ }[];
9
+ //# sourceMappingURL=groupByDepth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groupByDepth.d.ts","sourceRoot":"","sources":["../src/groupByDepth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,CAgBtC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.groupByDepth = groupByDepth;
4
+ /**
5
+ * Group path strings by their `/`-separated depth, sorted deepest-first.
6
+ * Useful for bottom-up directory processing where children must be handled before parents.
7
+ */
8
+ function groupByDepth(paths) {
9
+ const depthMap = new Map();
10
+ for (const p of paths) {
11
+ const depth = p === "" ? 0 : p.split("/").length;
12
+ let group = depthMap.get(depth);
13
+ if (!group) {
14
+ group = [];
15
+ depthMap.set(depth, group);
16
+ }
17
+ group.push(p);
18
+ }
19
+ return [...depthMap.entries()]
20
+ .sort(([a], [b]) => b - a)
21
+ .map(([depth, paths]) => ({ depth, paths }));
22
+ }
23
+ //# sourceMappingURL=groupByDepth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groupByDepth.js","sourceRoot":"","sources":["../src/groupByDepth.ts"],"names":[],"mappings":";;AAIA,oCAkBC;AAtBD;;;GAGG;AACH,SAAgB,YAAY,CAC1B,KAAwB;IAExB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE7C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QACjD,IAAI,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,EAAE,CAAC;YACX,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;SAC3B,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;SACzB,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { chunk } from "./chunk.js";
2
+ export { groupByDepth } from "./groupByDepth.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.groupByDepth = exports.chunk = void 0;
4
+ var chunk_js_1 = require("./chunk.js");
5
+ Object.defineProperty(exports, "chunk", { enumerable: true, get: function () { return chunk_js_1.chunk; } });
6
+ var groupByDepth_js_1 = require("./groupByDepth.js");
7
+ Object.defineProperty(exports, "groupByDepth", { enumerable: true, get: function () { return groupByDepth_js_1.groupByDepth; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uCAAmC;AAA1B,iGAAA,KAAK,OAAA;AACd,qDAAiD;AAAxC,+GAAA,YAAY,OAAA"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@hardlydifficult/collections",
3
+ "version": "1.0.0",
4
+ "main": "./dist/index.js",
5
+ "types": "./dist/index.d.ts",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "test": "vitest run",
12
+ "test:watch": "vitest",
13
+ "test:coverage": "vitest run --coverage",
14
+ "lint": "tsc --noEmit",
15
+ "clean": "rm -rf dist"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "25.2.3",
19
+ "typescript": "5.9.3",
20
+ "vitest": "4.0.18"
21
+ },
22
+ "engines": {
23
+ "node": ">=18.0.0"
24
+ }
25
+ }