Conversation
stopWhen(items, predicate) stops pulling from any iterable once the predicate is truthy, checked before the item is offered downstream. Promoted from nucube-app where it replaced hand-rolled stop logic in the MusicBrainz enrichment pipeline. - check before yield: the triggering item is never processed - pull-lazy: abandoned sources are left mid-stream, cleanup still runs - clean completion: failure: false, empty sourceErrors — cancel is a shorter run, not a source death; predicate throws are source errors - predicate receives (item, index), sync only, defaults to () => false - forwards numeric length from array sources so series keeps progress totals without an explicit total option - composes with series/scan/reduce/filter/findSync and raw for await with zero changes to those functions Also fixes filter/filterSync/findSync arg sniffing: iterable objects (generators, custom adapters) were misread as where() patterns because any non-array object matched. Patterns are now objects that do not implement an iteration protocol.
The default `() => false` is a pass-through, not an identity wrapper.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
New source adapter, promoted from nucube-app where it already replaced hand-rolled stop logic in the MusicBrainz enrichment pipeline (second time the pattern was requested by a consumer):
```js
export const stopWhen = (items, predicate = () => false) => ({
async * [Symbol.asyncIterator] () {
for await (const item of items) {
if (predicate(item))
return
yield item
}
},
})
// + stopWhenSync with Symbol.iterator
```
Usage — cancellation lives in the source, everything else stays in its own place:
```js
await series(enrichOne, {
total: albums.length,
pause: ENRICH_DELAY_MS,
pauseOnErrors: true,
onProgress: onItem,
})(stopWhen(albums, shouldStop))
stopWhen(folders, () => count >= limit) // limits close over counters
```
Contract (pinned by tests)
Design notes for reviewers
Out of scope (explicitly)
Testing
34 new tests (`tests/stop-when.test.js`, `tests/stop-when-sync.test.js`): nucube's 7 ported verbatim in intent + composition (series/reduce/filter/take), length forwarding, index passing, closure predicates, predicate-throws-as-source-error, generator cleanup. Full suite: 400 passed. Lint clean.
Docs
reference.md (new entry + TOC), guide.md, patterns.md (Pattern 9), examples.md (MusicBrainz-shaped example), architecture.md (one sentence under Eager Execution), migration.md (0.9.2 section incl. the filter fix note), skills/core/SKILL.md, README. Version bumped to 0.9.2.
Follow-up (not here)
nucube-app can delete `src/lib/iterables/stop-when.js` and import from `pipelean@0.9.2` with no call-site change; it may then drop its explicit `total: albums.length`.