Harden build/publish, algorithm, and tests without changing the API#2
Merged
Conversation
Backward-compatible improvements to the library: - Fix broken publish flow: `prepublish` was outside `scripts` (ignored by npm) and is deprecated. Build now runs via `prepare`, and a `files` allowlist guarantees `dist/` ships even though it is git-ignored. - Correct license metadata (package.json said ISC; LICENSE is MIT). - Rewrite the worker pool as an iterative loop instead of async recursion, avoiding retained promise chains for large job arrays. - Normalise the concurrency limit: non-positive / non-integer values fall back to the default of 5 (preserves the old `limit || 5` behaviour and no longer throws a RangeError on negatives/floats). `limit` is now optional with a default. - Add a named `parallel` export and `DEFAULT_CONCURRENCY` alongside the existing default export (default export unchanged). - Add a real, dependency-free assertion test suite and wire up `npm test` plus a GitHub Actions CI matrix (Node 16/18/20/22). - Modernise tsconfig (drop deprecated/unused options) and refresh README. Tuple return-type inference for `as const` job arrays is preserved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013eq96Mbqa2dBCAN3YCyrDK
…ching) Adds a deterministic test using deferred promises: after resolving only the first of two in-flight jobs, the third job must start immediately while the second is still running. This distinguishes a true sliding worker pool from a batching implementation (which would wait for the whole chunk). Verified to fail against a batching impl and pass against the current loop-based pool. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013eq96Mbqa2dBCAN3YCyrDK
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 free
to 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.
Backward-compatible hardening of the library. The public default-export signature, the default concurrency of
5, input-order results,Promise.allerror semantics, andas consttuple return-type inference are all unchanged (verified with a type test). Version bumped to2.2.0(additive feature + fixes).Critical fixes (were quietly breaking or fragile)
tsc."prepublish": "tsc"sat outsidescripts(npm ignores it) andprepublishis deprecated. Build now runs viaprepare+ abuildscript.dist/shipping was non-deterministic.dist/is git-ignored with no.npmignoreand nofilesfield, so npm falls back to.gitignore. Added"files": ["dist"];npm pack --dry-runnow yields a deterministic 5-file / ~5.6 kB tarball (the published2.1.0ships 10 files includingsrc/,test/, andtsconfig.json).LICENSEis MIT butpackage.jsonsaid ISC — and npm currently advertises ISC. Set to MIT to match the actual license file.Correctness / robustness
limit || 5with no validation madelimit = -1/2.5throw a crypticRangeError. Now normalized: non-positive / non-integer values fall back to the default of5(preserves the old0 → 5behaviour).limitis now optional.whileloop. Same output; no retained chains. Tested with 1000 jobs.Quality / DX
npm test.parallelexport andDEFAULT_CONCURRENCYalongside the unchanged default export.tsconfig(dropped deprecated/unused options),var→const/let, refreshed README to document ordering and error behaviour.Backward-compatibility: verified against the real dependent
The only published dependent is
@paperbits/core(@paperbits/ampdeclares the dep but has no call site). It pins^2.1.0, so it will pick up2.2.0automatically. Its actual usage, at all 3 call sites, is:30), result never read → every changed surface (optionallimit,0→5fallback, tuple typing, named export) is a no-op for them.2.1.0vs. this branch, 100 thunks @ limit 30): happy path identical — peak concurrency 30, all 100 complete, input order preserved; error path — both fail-fast with the same error at the same point.Not included (deliberately — breaking or judgment calls)
AbortSignalsupport and a settle-all /stopOnError: falsemode (change/extend semantics — worth a3.0or opt-in option).exportsmap.Testing
npm test→ 11/11 passing (build + assertions).npm pack --dry-run→ tarball containsdist/index.js,dist/index.d.ts,LICENSE,README.md,package.json.parallel(jobs as const, 2)still infers an ordered tuple.2.1.0on the@paperbits/corecall shape.🤖 Generated with Claude Code