Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,15 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci --ignore-scripts
- run: npm test
- run: npm pack

runtime-floor:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 6
- run: node test/runtime-smoke.js
17 changes: 0 additions & 17 deletions .travis.yml

This file was deleted.

6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## Unreleased
## 2.0.0 (release candidate)

- Count keys such as `__proto__`, `constructor` and `toString` without interacting with Object.prototype.
- Return independent top-k tuples so callers cannot modify internal sketch state.
Expand All @@ -11,7 +11,7 @@

### Release compatibility

Runtime minimum becomes Node 6 because Buffer.alloc is now used; test development requires modern Node (CI: 22/24/26). Dropping previously advertised Node 0.6 support requires a major release. No version has been bumped yet. Top-k tie ordering is unspecified and may change. The follow-up below adds versioned serialization and validates malformed inputs. See SERIALIZATION.md for legacy import/export and the major-release migration.
Runtime minimum becomes Node 6 because Buffer.alloc is now used; test development requires modern Node (CI: 22/24/26). Dropping previously advertised Node 0.6 support requires a major release. The package version is prepared as 2.0.0; publication is pending. Top-k tie ordering is unspecified and may change. The follow-up below adds versioned serialization and validates malformed inputs. See SERIALIZATION.md for legacy import/export and the major-release migration.

## Release validation follow-up

Expand All @@ -20,3 +20,5 @@ Runtime minimum becomes Node 6 because Buffer.alloc is now used; test developmen
- Reject overflowing counters atomically and validate HLL merges before mutation.
- Fix the signed-minimum hash bucket edge case and retain the existing mapping for all other hashes.
- Add legacy golden fixtures and tests for truncation, malformed metadata, invalid Unicode, capacity preservation and overflow.

- Add complete root/deep-import TypeScript declarations, packed runtime/type consumer tests, a Node 6 runtime-floor check, and remove the obsolete Travis matrix identified in review.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ __Arguments__
Returns the serialized size of a views counter (CountMinSketch) object in
bytes given an errFactor and failRate. __NOTE:__ This does not include the size
of the serialized MinHeap which includes the size of each unique ID (up to a
max of topEntryCount) plus 5 bytes overhead per entry. __NOTE2:__ The memory
max of topEntryCount) plus 8 bytes overhead per entry. __NOTE2:__ The memory
usage will be higher than this number since we serialize 32-bit integers but
JavaScript uses 64-bit numbers.

Expand Down Expand Up @@ -235,3 +235,11 @@ __Example__
```js
var pageCounts = CountMinSketch.deserialize(bufferData);
```

## Version 2 migration and release checks

Version 2 writes capacity-preserving CMS2 sketches by default. Old files remain readable; old readers need `serialize({ legacy: true })`. See [SERIALIZATION.md](SERIALIZATION.md) for layouts, allocation/input bounds and recovering the capacity of partially filled legacy sketches. Explicit zero/null/NaN options no longer silently select defaults.

TypeScript declarations cover the package root and existing class/helper deep imports. Node TypeScript projects need `@types/node`. Runtime compatibility starts at Node 6; development and the complete test suite use Node 22 or newer. CI runs the full suite on 22/24/26 and a separate Node 6 runtime smoke test.

Before releasing: `npm ci`, `npm test`, then review the archive produced by `npm pack`. The test suite itself installs the archive into an independent consumer, checks CommonJS/ESM and compiles NodeNext/Node16 TypeScript fixtures. `npm publish` runs the tests through `prepublishOnly`; publishing still requires the maintainer's authenticated release action. The version bump in this branch is preparation, not evidence of a published release.
50 changes: 50 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/// <reference types="node" />
export interface SerializeOptions { legacy?: boolean; }
export interface DeserializeOptions { maxEntries?: number; }
/** Constructors return structural counter objects, not instanceof-compatible instances. */
export class CountMinSketch {
constructor(maxEntries: number, epsilon: number, delta: number);
increment(key: string): void;
getTopK(): Array<[count: number, key: string]>;
serialize(options?: SerializeOptions): Buffer;
static deserialize(buffer: Buffer, start?: number, length?: number, options?: DeserializeOptions): CountMinSketch;
}
export class HyperLogLog {
constructor(stdError: number);
M: number[];
add(key: string): void;
count(): number;
serialize(): Buffer;
merge(other: HyperLogLog): void;
static deserialize(buffer: Buffer, start?: number, length?: number): HyperLogLog;
}
export function createUniquesCounter(stdError?: number): HyperLogLog;
export function createViewsCounter(topEntryCount: number, errFactor?: number, failRate?: number): CountMinSketch;
export function getUniquesObjSize(stdError?: number): number;
/** Excludes variable-sized heap entries; each adds 8 bytes plus its UTF-8 key. */
export function getViewsObjSize(errFactor?: number, failRate?: number): number;
export class MinHeap<T = number> {
constructor(array?: T[], comparator?: (a: T, b: T) => number);
heap: T[];
compare: (a: T, b: T) => number;
heapify(index: number): void;
siftUp(index: number): void;
heapifyArray(): void;
push(item: T): void;
pop(): T | undefined;
getMin(): T | undefined;
size(): number;
}
export interface RandomGenerator {
(): number;
random(): number;
uint32(): number;
fract53(): number;
version: string;
args: Array<string | number>;
}
export interface RandomConstructor {
(...seeds: Array<string | number>): RandomGenerator;
new (...seeds: Array<string | number>): RandomGenerator;
}
export const PRNG: RandomConstructor;
2 changes: 2 additions & 0 deletions lib/countMinSketch.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { CountMinSketch } from "../index";
export = CountMinSketch;
2 changes: 2 additions & 0 deletions lib/hyperLogLog.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { HyperLogLog } from "../index";
export = HyperLogLog;
2 changes: 2 additions & 0 deletions lib/minHeap.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { MinHeap } from "../index";
export = MinHeap;
2 changes: 2 additions & 0 deletions lib/prng.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { PRNG } from "../index";
export = PRNG;
Loading
Loading