{"_id":"@aias/crossfilter","name":"@aias/crossfilter","dist-tags":{"latest":"1.6.0"},"versions":{"1.6.0":{"name":"@aias/crossfilter","version":"1.6.0","description":"Fast multidimensional filtering for coordinated views.","license":"Apache-2.0","keywords":["analytics","visualization","crossfilter"],"author":{"name":"Nick Trombley","url":"https://github.com/Aias"},"contributors":[{"name":"Mike Bostock","url":"https://bost.ocks.org/mike"},{"name":"Jason Davies","url":"https://www.jasondavies.com/"},{"name":"Gordon Woodhull","url":"https://github.com/gordonwoodhull"},{"name":"Tanner Linsley","url":"https://github.com/tannerlinsley"},{"name":"Ethan Jewett","url":"https://github.com/esjewett"}],"homepage":"https://github.com/Aias/crossfilter","types":"./dist/index.d.ts","unpkg":"./dist/crossfilter.min.js","repository":{"type":"git","url":"git+https://github.com/Aias/crossfilter.git"},"publishConfig":{"access":"public"},"type":"module","packageManager":"pnpm@12.3.4","engines":{"node":">=22.12.0"},"peerDependencies":{"react":">=19.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"devDependencies":{"@arethetypeswrong/core":"~0.18.5","@testing-library/react":"~16.3.3","@types/react":"~19.2.18","@types/react-dom":"~19.2.7","fast-check":"~4.9.0","happy-dom":"~20.14.0","oxlint":"~1.81.0","publint":"~0.3.24","react":"~19.2.8","react-dom":"~19.2.8","tsdown":"~0.23.0","typescript":"~7.0.2","vitest":"~5.0.0"},"scripts":{"benchmark":"vitest bench --run --reporter=verbose","build":"tsdown","clean":"rm -rf dist","demo":"pnpm run build && pnpm --filter crossfilter-demo dev","lint":"oxlint --deny-warnings src index.ts react.ts test demo/src tsdown.config.ts vitest.config.ts","prepack":"pnpm run build","test":"pnpm run build && vitest run && pnpm run typecheck && pnpm --filter crossfilter-demo check && pnpm run lint","typecheck":"tsc"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./react":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"gitHead":"a83f8e1a9febe9890e70d2c414cd22a3aa672338","_id":"@aias/crossfilter@1.6.0","bugs":{"url":"https://github.com/Aias/crossfilter/issues"},"_nodeVersion":"24.20.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-N9R8fBzuzlcW+FsCuryP0JqobPwL1kOv7g9Jh2HpKX70a/SD07o+0qwSudeatcaYFmaOEfmSZ8TYMrEPUFiQQA==","shasum":"6298e57d144044027f4e5e7f8cb5884fb97e0e94","tarball":"https://registry.npmjs.org/@aias/crossfilter/-/crossfilter-1.6.0.tgz","fileCount":30,"unpackedSize":361798,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCS/GwQwB258hSkjQNFYpqNLUifQLrx/Q8K7RcZw+eeNAIhAO76lfF4lNRRn8TXFCjnsHoutw/Gyrly1lr9duX+2BS8"}]},"_npmUser":{"name":"aias","email":"trombley.nick@gmail.com"},"directories":{},"maintainers":[{"name":"aias","email":"trombley.nick@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/crossfilter_1.6.0_1788799712402_0.05001820334771434"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-07T16:48:32.198Z","1.6.0":"2026-09-07T16:48:32.595Z","modified":"2026-09-07T16:48:32.824Z"},"maintainers":[{"name":"aias","email":"trombley.nick@gmail.com"}],"description":"Fast multidimensional filtering for coordinated views.","homepage":"https://github.com/Aias/crossfilter","keywords":["analytics","visualization","crossfilter"],"repository":{"type":"git","url":"git+https://github.com/Aias/crossfilter.git"},"contributors":[{"name":"Mike Bostock","url":"https://bost.ocks.org/mike"},{"name":"Jason Davies","url":"https://www.jasondavies.com/"},{"name":"Gordon Woodhull","url":"https://github.com/gordonwoodhull"},{"name":"Tanner Linsley","url":"https://github.com/tannerlinsley"},{"name":"Ethan Jewett","url":"https://github.com/esjewett"}],"author":{"name":"Nick Trombley","url":"https://github.com/Aias"},"bugs":{"url":"https://github.com/Aias/crossfilter/issues"},"license":"Apache-2.0","readme":"# Crossfilter\n\n![Tests](https://github.com/Aias/crossfilter/actions/workflows/tests.yml/badge.svg)\n\n**Crossfilter** is a JavaScript library for exploring large multivariate datasets in the browser. It supports extremely fast (<30ms) interaction with coordinated views, even with datasets containing a million or more records.\n\nSince most interactions only involve a single dimension, and then only small adjustments are made to the filter values, incremental filtering and reducing is significantly faster than starting from scratch. Crossfilter uses sorted indexes (and a few bit-twiddling hacks) to make this possible, dramatically increasing the performance of live histograms and top-_K_ lists.\n\nThis repository is a TypeScript rewrite of the community-maintained [crossfilter/crossfilter](https://github.com/crossfilter/crossfilter), itself a fork of the original [square/crossfilter](https://github.com/square/crossfilter). The runtime API is unchanged, so the upstream [API reference](https://github.com/crossfilter/crossfilter/wiki/API-Reference) still applies; the types are new.\n\n## Installation\n\n    pnpm add @aias/crossfilter\n\nThe package ships as an ES module with TypeScript declarations. Node 22.12 and later can `require()` it as well. A minified browser build at `dist/crossfilter.min.js` exposes a global `crossfilter` for script tags and CDNs.\n\n## Usage\n\n```ts\nimport crossfilter from \"@aias/crossfilter\";\n\ninterface Payment {\n  date: Date;\n  amount: number;\n  type: string;\n}\n\nconst records: Payment[] = [\n  { date: new Date(2024, 0, 1), amount: 24, type: \"cash\" },\n  { date: new Date(2024, 0, 2), amount: 61, type: \"card\" },\n];\n\nconst payments = crossfilter(records);\nconst amount = payments.dimension((payment) => payment.amount);\nconst type = payments.dimension((payment) => payment.type);\nconst amountsByTen = amount.group((value) => Math.floor(value / 10) * 10);\nconst totalByType = type.group().reduceSum((payment) => payment.amount);\n\namount.filterRange([10, 50]);\namountsByTen.top(3);\ntotalByType.all();\npayments.groupAll().reduceSum((payment) => payment.amount).value();\n```\n\nRecord types flow from the records you pass in: dimensions know their value type, groups know their key and value types, and reducers infer the accumulated value from the `initial` callback. Pass an explicit record type only when starting empty, as in `crossfilter<Payment>()`.\n\nFilters, additions, and removals are synchronous. Subscribe with `onChange` to react to them:\n\n```ts\nconst unsubscribe = payments.onChange((event) => {\n  console.log(event, payments.groupAll().value());\n});\n```\n\n## React\n\n`@aias/crossfilter/react` bridges crossfilter's synchronous change events to React through `useSyncExternalStore`. React is an optional peer dependency, so the core package stays framework-free.\n\n```tsx\nimport { useCrossfilter, useDimensionFilter, useGroupAll, useGroupValue } from \"@aias/crossfilter/react\";\n\nfunction Dashboard({ records }: { records: Payment[] }) {\n  const { payments, amount, byType, total } = useCrossfilter(records, (payments) => {\n    const amount = payments.dimension((payment) => payment.amount);\n    const type = payments.dimension((payment) => payment.type);\n    return {\n      payments,\n      amount,\n      byType: type.group(),\n      total: payments.groupAll().reduceSum((payment) => payment.amount),\n    };\n  });\n  const bins = useGroupAll(payments, byType);\n  const sum = useGroupValue(payments, total);\n  const [range, setRange] = useDimensionFilter(payments, amount);\n  return (\n    <>\n      <button onClick={() => setRange([10, 50])}>Between 10 and 50</button>\n      <button onClick={() => setRange(null)}>Clear</button>\n      <p>{sum} across {bins.length} types{range ? \" (filtered)\" : \"\"}</p>\n    </>\n  );\n}\n```\n\n`useCrossfilter` builds the crossfilter and everything derived from it once per component, which keeps dimensions and groups from being created twice under Strict Mode, and replaces the records whenever the array identity changes. The other hooks subscribe to an instance and return fresh snapshots after every filter, add, or remove: `useGroupAll`, `useGroupTop`, `useGroupValue`, `useDimensionTop`, `useDimensionBottom`, and `useDimensionFilter`. Components that read the instance directly in render can call `useCrossfilterVersion` to subscribe.\n\n## Demo\n\nThe airline on-time performance example is deployed at https://aias.github.io/crossfilter/ and lives in `demo/` as a React application. It consumes the `@aias/crossfilter` package through the workspace, builds its charts on the modular d3 packages, and drives every chart and list through the `@aias/crossfilter/react` hooks. Run `pnpm run demo` to build the library and start the Vite dev server.\n\n## Development\n\nUse Node.js 24 and the pnpm version pinned in `package.json`. Install dependencies with `pnpm install --frozen-lockfile`.\n\n`pnpm test` builds the library, runs the tests, typechecks the library and test suite, checks the demo, and runs lint. `pnpm run build` bundles the library with tsdown into an ES module with TypeScript declarations and a minified browser script. `pnpm run benchmark` measures indexing, filtering, and removal.\n\n## License\n\nCrossfilter is available under the [Apache License 2.0](LICENSE). See [NOTICE](NOTICE) for attribution.\n","readmeFilename":"README.md","_rev":"1-7f4507daa231367465de6c561651e103"}