Skip to content

Commit

Permalink
feat(lib): init
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcnk committed Sep 18, 2024
0 parents commit 8b1b9b8
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 0 deletions.
175 changes: 175 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore

# Logs

logs
_.log
npm-debug.log_
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Caches

.cache

# Diagnostic reports (https://nodejs.org/api/report.html)

report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json

# Runtime data

pids
_.pid
_.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover

lib-cov

# Coverage directory used by tools like istanbul

coverage
*.lcov

# nyc test coverage

.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)

.grunt

# Bower dependency directory (https://bower.io/)

bower_components

# node-waf configuration

.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)

build/Release

# Dependency directories

node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)

web_modules/

# TypeScript cache

*.tsbuildinfo

# Optional npm cache directory

.npm

# Optional eslint cache

.eslintcache

# Optional stylelint cache

.stylelintcache

# Microbundle cache

.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history

.node_repl_history

# Output of 'npm pack'

*.tgz

# Yarn Integrity file

.yarn-integrity

# dotenv environment variable files

.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)

.parcel-cache

# Next.js build output

.next
out

# Nuxt.js build / generate output

.nuxt
dist

# Gatsby files

# Comment in the public line in if your project uses Gatsby and not Next.js

# https://nextjs.org/blog/next-9-1#public-directory-support

# public

# vuepress build output

.vuepress/dist

# vuepress v2.x temp and cache directory

.temp

# Docusaurus cache and generated files

.docusaurus

# Serverless directories

.serverless/

# FuseBox cache

.fusebox/

# DynamoDB Local files

.dynamodb/

# TernJS port file

.tern-port

# Stores VSCode versions used for testing VSCode extensions

.vscode-test

# yarn v2

.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

# IntelliJ based IDEs
.idea

# Finder (MacOS) folder config
.DS_Store
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# bigint-quantile

Easily calculate quantiles for large datasets.

## Installation

```bash
$ npm install bigint-quantile
```

## Usage

```ts
import { calculateQuantile } from "bigint-quantile";

const data: bigint[] = [1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n, 10n];
const quantile = 0.5;

const result = calculateQuantile(data, quantile);
```
30 changes: 30 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.1/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false,
"ignore": ["dist/**/*"]
},
"formatter": {
"enabled": true,
"indentStyle": "tab"
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
}
}
11 changes: 11 additions & 0 deletions build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineBuildConfig } from "unbuild";

export default defineBuildConfig({
entries: ["./src/index"],
outDir: "dist",
declaration: true,
failOnWarn: false,
rollup: {
emitCJS: true,
},
});
Binary file added bun.lockb
Binary file not shown.
29 changes: 29 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "bigint-quantile",
"type": "module",
"version": "0.0.1",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"main": "./dist/index.cjs",
"types": "./dist/index.d.ts",
"files": ["dist"],
"scripts": {
"build": "bunx unbuild",
"test": "bun test",
"test:coverage": "bun test --coverage",
"lint": "bunx biome check .",
"format": "bunx biome check . --write --unsafe"
},
"devDependencies": {
"@biomejs/biome": "1.9.1",
"@types/bun": "latest",
"unbuild": "^2.0.0"
},
"peerDependencies": {
"typescript": "^5.0.0"
}
}
32 changes: 32 additions & 0 deletions src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { expect, it } from "bun:test";
import { calculateQuantile } from "./";

const data: bigint[] = [1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n, 10n];

it("should calculate 25th percentile / first quartile", () => {
const firstQuartile = calculateQuantile(data, 0.25);
expect(firstQuartile).toBe(3n);
});

it("should calculate 50th percentile / median", () => {
const median = calculateQuantile(data, 0.5);
expect(median).toBe(5n);
});

it("should calculate 75th percentile / third quartile", () => {
const thirdQuartile = calculateQuantile(data, 0.75);
expect(thirdQuartile).toBe(7n);
});

it("should throw error if quantile is not between 0 and 1", () => {
expect(() => calculateQuantile(data, 1.1)).toThrowError(
"Quantile must be between 0 and 1",
);
expect(() => calculateQuantile(data, -0.1)).toThrowError(
"Quantile must be between 0 and 1",
);
});

it("should return 0 if data is empty", () => {
expect(calculateQuantile([], 0.5)).toBe(0n);
});
14 changes: 14 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const calculateQuantile = (data: bigint[], q: number): bigint => {
if (q < 0 || q > 1) throw new Error("Quantile must be between 0 and 1");
const sorted = data.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
const pos = (sorted.length - 1) * q;
const base = BigInt(Math.floor(pos));
const rest = pos - Math.floor(pos);
if (sorted[Number(base)] === undefined) return 0n;
const result = sorted[Number(base)];
if (rest === 0) {
return result;
}
const next = sorted[Number(base) + 1] || sorted[Number(base)];
return result + ((next - result) * BigInt(Math.round(rest * 100))) / 100n;
};
27 changes: 27 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"compilerOptions": {
// Enable latest features
"lib": ["ESNext", "DOM"],
"target": "ESNext",
"module": "ESNext",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,

// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,

// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,

// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
}

0 comments on commit 8b1b9b8

Please sign in to comment.