Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
27 lines
942 B
TypeScript
27 lines
942 B
TypeScript
/**
|
|
* Split a flat list into consecutive runs. A new run starts whenever
|
|
* `sameRun(previousItem, currentItem)` returns false. Total function: every
|
|
* input element lands in exactly one run, runs preserve order, and an empty
|
|
* input yields an empty result. No element is ever dropped or duplicated.
|
|
*
|
|
* This is the segmentation primitive behind neighbour-dependent projections
|
|
* (e.g. coalescing thinking into the message it precedes). Keeping it generic
|
|
* and pure means the grouping decision lives entirely in the `sameRun`
|
|
* predicate, which is trivially table-testable on its own.
|
|
*/
|
|
export function chunkBy<T>(
|
|
items: readonly T[],
|
|
sameRun: (previous: T, current: T) => boolean
|
|
): T[][] {
|
|
const runs: T[][] = [];
|
|
for (const item of items) {
|
|
const current = runs.at(-1);
|
|
if (current && sameRun(current.at(-1)!, item)) {
|
|
current.push(item);
|
|
continue;
|
|
}
|
|
runs.push([item]);
|
|
}
|
|
return runs;
|
|
}
|