simpleflakes 4.1.0 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -8
- package/dist/simpleflakes.d.ts.map +1 -1
- package/dist/simpleflakes.js +1 -1
- package/dist/simpleflakes.js.map +1 -1
- package/package.json +17 -12
package/README.md
CHANGED
|
@@ -7,16 +7,16 @@
|
|
|
7
7
|
[](https://bundlephobia.com/package/simpleflakes)
|
|
8
8
|
[](https://www.typescriptlang.org/)
|
|
9
9
|
[](https://nodejs.org/)
|
|
10
|
-
[](https://github.com/leodutra/simpleflakes/actions/workflows/ci.yml)
|
|
11
11
|
[](https://github.com/leodutra/simpleflakes)
|
|
12
12
|
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fleodutra%2Fsimpleflakes?ref=badge_shield&issueType=license)
|
|
13
13
|
|
|
14
14
|
> **Fast, lightweight, and reliable distributed 64-bit ID generation for Node.js and the web**
|
|
15
|
-
> Zero dependencies • TypeScript-ready •
|
|
15
|
+
> Zero dependencies • TypeScript-ready • 10M+ ops/sec performance
|
|
16
16
|
|
|
17
17
|
## Features
|
|
18
18
|
|
|
19
|
-
- ⚡ **
|
|
19
|
+
- ⚡ **10M+ ops/sec** - Ultra-fast performance
|
|
20
20
|
- 🔢 **Time-oriented 64-bit IDs** - Globally unique, sortable by creation time
|
|
21
21
|
- 0️⃣ **Zero dependencies** - Pure JavaScript, lightweight bundle
|
|
22
22
|
- 🏷️ **TypeScript-ready** - Full type safety and universal module support
|
|
@@ -157,13 +157,29 @@ This gives you:
|
|
|
157
157
|
|
|
158
158
|
This library is optimized for speed:
|
|
159
159
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
simpleflake()
|
|
163
|
-
|
|
164
|
-
binary()
|
|
160
|
+
| Operation | Ops/sec | Time/op |
|
|
161
|
+
|-----------|---------|---------|
|
|
162
|
+
| `simpleflake()` | 11,468,350 | 87.20 ns |
|
|
163
|
+
| `simpleflake(timestamp, randomBits, epoch)` | 14,557,764 | 68.69 ns |
|
|
164
|
+
| `binary()` | 22,794,523 | 43.87 ns |
|
|
165
|
+
| `BigInt()` | 15,933,159 | 62.76 ns |
|
|
166
|
+
| `parseSimpleflake()` | 6,722,882 | 148.75 ns |
|
|
167
|
+
|
|
168
|
+
Benchmark command:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
npm run benchmark
|
|
165
172
|
```
|
|
166
173
|
|
|
174
|
+
Benchmark environment:
|
|
175
|
+
|
|
176
|
+
- Node.js v24.14.1
|
|
177
|
+
- Linux 6.6.87.2-microsoft-standard-WSL2 (WSL2)
|
|
178
|
+
- AMD Ryzen 7 5800X3D 8-Core Processor
|
|
179
|
+
- 8 cores / 16 threads
|
|
180
|
+
|
|
181
|
+
Results will vary across CPUs, Node.js versions, power profiles, and native Linux vs. WSL2 environments.
|
|
182
|
+
|
|
167
183
|
Perfect for high-throughput applications requiring millions of IDs per second.
|
|
168
184
|
|
|
169
185
|
## Architecture
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simpleflakes.d.ts","sourceRoot":"","sources":["../src/simpleflakes.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,iBAAiB,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"simpleflakes.d.ts","sourceRoot":"","sources":["../src/simpleflakes.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,iBAAiB,gBAAgB,CAAC;AA2DxC;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,EAAE,GAAE,MAAM,GAAG,MAAmB,EAChC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAC5B,KAAK,GAAE,MAAM,GAAG,MAA0B,GACzC,MAAM,CAOR;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CACpB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAC/B,OAAO,GAAE,OAAc,GACtB,MAAM,CAKR;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAC9B,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,MAAM,EAAE,MAAM,GAAG,MAAM,GACtB,MAAM,CAKR;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,SAAwB,SAAS,EAAE,MAAM,CAAC;IAC1C,SAAwB,UAAU,EAAE,MAAM,CAAC;gBAE/B,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;CAOlD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAC9B,iBAAiB,CAWnB;AAGD,OAAO,EAAE,iBAAiB,EAAE,CAAC;;;;;;;;;AAG7B,wBAOE"}
|
package/dist/simpleflakes.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),function(e,t){for(var r in t)Object.defineProperty(e,r,{enumerable:!0,get:Object.getOwnPropertyDescriptor(t,r).get})}(exports,{get SIMPLEFLAKE_EPOCH(){return SIMPLEFLAKE_EPOCH},get SimpleflakeStruct(){return SimpleflakeStruct},get binary(){return binary},get default(){return _default},get extractBits(){return extractBits},get parseSimpleflake(){return parseSimpleflake},get simpleflake(){return simpleflake}});const SIMPLEFLAKE_EPOCH=946684800000n;let randomBuffer=new Uint32Array(1024),randomBufferIndex=1024;function toBigInt(e){return"bigint"==typeof e?e:BigInt(e)}function getRandomSource(){let e=globalThis.crypto;if(e)return e;try{return require("node:crypto").webcrypto}catch{throw Error("Cryptographically secure random values are unavailable in this environment.")}}function refillRandomBuffer(){getRandomSource().getRandomValues(randomBuffer),randomBufferIndex=0}function random23(){randomBufferIndex>=1024&&refillRandomBuffer();let e=randomBuffer[randomBufferIndex];return randomBufferIndex+=1,BigInt(8388607&e)}function simpleflake(e=Date.now(),t,r=SIMPLEFLAKE_EPOCH){return toBigInt(e)-toBigInt(r)<<23n|(null==t?random23():toBigInt(t))}function binary(e,t=!0){let r=toBigInt(e).toString(2);return t&&r.length<64?"0000000000000000000000000000000000000000000000000000000000000000".substr(0,64-r.length)+r:r}function extractBits(e,t,r){let n=toBigInt(t),i=toBigInt(r);return toBigInt(e)>>n&(1n<<i)-1n}class SimpleflakeStruct{constructor(e,t){if(null==e||null==t)throw Error("Missing argument for SimpleflakeStruct.");this.timestamp=e,this.randomBits=t}}function parseSimpleflake(e){return new SimpleflakeStruct(extractBits(e,23n,41n)+SIMPLEFLAKE_EPOCH,extractBits(e,0n,23n))}const _default={binary,extractBits,parseSimpleflake,SIMPLEFLAKE_EPOCH,simpleflake,SimpleflakeStruct};
|
|
2
2
|
|
|
3
3
|
//# sourceMappingURL=simpleflakes.js.map
|
package/dist/simpleflakes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/simpleflakes.ts"],"names":["SIMPLEFLAKE_EPOCH","SimpleflakeStruct","binary","extractBits","parseSimpleflake","simpleflake","randomBuffer","Uint32Array","randomBufferIndex","toBigInt","value","BigInt","getRandomSource","globalCrypto","globalThis","crypto","require","webcrypto","Error","refillRandomBuffer","getRandomValues","random23","ts","Date","now","randomBits","epoch","padding","binValue","toString","length","CACHE_64_BIT_ZEROS","substr","data","shift","shiftN","lengthN","timestamp","flake"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/simpleflakes.ts"],"names":["SIMPLEFLAKE_EPOCH","SimpleflakeStruct","binary","extractBits","parseSimpleflake","simpleflake","randomBuffer","Uint32Array","randomBufferIndex","toBigInt","value","BigInt","getRandomSource","globalCrypto","globalThis","crypto","require","webcrypto","Error","refillRandomBuffer","getRandomValues","random23","ts","Date","now","randomBits","epoch","padding","binValue","toString","length","CACHE_64_BIT_ZEROS","substr","data","shift","shiftN","lengthN","timestamp","flake"],"mappings":"uMAsJSA,2BAAAA,uBAlCIC,2BAAAA,uBA/BGC,gBAAAA,YAoEhB,iBAAA,cAnDgBC,qBAAAA,iBAgCAC,0BAAAA,sBApEAC,qBAAAA,eAlEhB,MAAML,kBAAoB,YAAA,AAAa,CAAA,CAmBvC,IAAIM,aAAe,IAAIC,YAjBI,MAkBvBC,kBAlBuB,KAoB3B,SAASC,SAASC,CAA+B,EAC/C,MAAO,AAAiB,UAAjB,OAAOA,EAAqBA,EAAQC,OAAOD,EACpD,CAEA,SAASE,kBACP,IAAMC,EAAe,AAACC,WAEnBC,MAAM,CAET,GAAIF,EAAc,OAAOA,EAEzB,GAAI,CACF,OAAO,AAACG,QACN,eACAC,SAAS,AACb,CAAE,KAAM,CACN,MAAM,AAAIC,MACR,8EAEJ,CACF,CAEA,SAASC,qBACPP,kBAAkBQ,eAAe,CAACd,cAClCE,kBAAoB,CACtB,CAEA,SAASa,WACHb,mBAhDqB,MAiDvBW,qBAEF,IAAMT,EAAQJ,YAAY,CAACE,kBAAkB,CAG7C,OADAA,mBAAqB,EACdG,OAvDkB,AAuDXD,QAAAA,EAChB,CASO,SAASL,YACdiB,EAAsBC,KAAKC,GAAG,EAAE,CAChCC,CAA4B,CAC5BC,EAAyB1B,iBAAiB,EAI1C,OACE,AAAES,SAASa,GAAMb,SAASiB,IAlEM,EAAA,AAAG,CAAA,CAmElCD,CAAAA,AAAc,MAAdA,EAAqBJ,WAAaZ,SAASgB,EAAU,CAE1D,CAQO,SAASvB,OACdQ,CAA+B,CAC/BiB,EAAmB,CAAA,CAAI,EAEvB,IAAMC,EAAWnB,SAASC,GAAOmB,QAAQ,CAAC,GAC1C,OAAOF,GAAWC,EAASE,MAAM,CAAG,GA/EpC,AAgFIC,mEAAmBC,MAAM,CAAC,EAAG,GAAKJ,EAASE,MAAM,EAAIF,EACrDA,CACN,CASO,SAASzB,YACd8B,CAA8B,CAC9BC,CAAsB,CACtBJ,CAAuB,EAEvB,IAAMK,EAAS1B,SAASyB,GAClBE,EAAU3B,SAASqB,GAEzB,OAAO,AAACrB,SAASwB,IAASE,EAAW,AAAC,CAAA,CAAA,AAAE,CAAA,EAAIC,CAAM,EAAK,CAAA,AAAE,CAAA,AAC3D,CAKO,MAAMnC,kBAIX,YAAYoC,CAAiB,CAAEZ,CAAkB,CAAE,CACjD,GAAIY,AAAa,MAAbA,GAAqBZ,AAAc,MAAdA,EACvB,MAAM,AAAIP,MAAM,0CAElB,CAAA,IAAI,CAACmB,SAAS,CAAGA,EACjB,IAAI,CAACZ,UAAU,CAAGA,CACpB,CACF,CAOO,SAASrB,iBACdkC,CAA+B,EAE/B,OAAO,IAAIrC,kBAETE,YACEmC,EApI8B,EAAA,AAAG,CAAA,CAJF,EAAA,AAAG,CAAA,EA2IhCtC,kBAEJG,YAAYmC,EA1IiB,CAAA,AAAE,CAAA,CAFD,EAAA,AAAG,CAAA,EA8IrC,OAMA,SAAe,CACbpC,OACAC,YACAC,iBACAJ,kBACAK,YACAJ,iBACF","file":"simpleflakes.js","sourcesContent":["const SIMPLEFLAKE_EPOCH = 946684800000n; // Date.UTC(2000, 0, 1) == epoch ms, since 1 Jan 2000 00:00\nconst UNSIGNED_23BIT_MAX = 8388607; // (Math.pow(2, 23) - 1) >> 0\nconst RANDOM_BUFFER_SIZE = 1024;\n\nconst SIMPLEFLAKE_TIMESTAMP_LENGTH = 41n;\nconst SIMPLEFLAKE_RANDOM_LENGTH = 23n;\n\nconst SIMPLEFLAKE_RANDOM_SHIFT = 0n;\nconst SIMPLEFLAKE_TIMESTAMP_SHIFT = 23n;\n\nconst CACHE_64_BIT_ZEROS =\n \"0000000000000000000000000000000000000000000000000000000000000000\";\n\ninterface RandomSource {\n getRandomValues<T extends ArrayBufferView>(array: T): T;\n}\n\ndeclare const require: ((moduleName: string) => unknown) | undefined;\n\nlet randomBuffer = new Uint32Array(RANDOM_BUFFER_SIZE);\nlet randomBufferIndex = RANDOM_BUFFER_SIZE;\n\nfunction toBigInt(value: bigint | number | string): bigint {\n return typeof value === \"bigint\" ? value : BigInt(value);\n}\n\nfunction getRandomSource(): RandomSource {\n const globalCrypto = (globalThis as typeof globalThis & {\n crypto?: RandomSource;\n }).crypto;\n\n if (globalCrypto) return globalCrypto;\n\n try {\n return (require as (moduleName: string) => { webcrypto: RandomSource })(\n [\"node\", \"crypto\"].join(\":\")\n ).webcrypto;\n } catch {\n throw new Error(\n \"Cryptographically secure random values are unavailable in this environment.\"\n );\n }\n}\n\nfunction refillRandomBuffer(): void {\n getRandomSource().getRandomValues(randomBuffer);\n randomBufferIndex = 0;\n}\n\nfunction random23(): bigint {\n if (randomBufferIndex >= RANDOM_BUFFER_SIZE) {\n refillRandomBuffer();\n }\n const value = randomBuffer[randomBufferIndex]!;\n\n randomBufferIndex += 1;\n return BigInt(value & UNSIGNED_23BIT_MAX);\n}\n\n/**\n * Generates a simpleflake ID\n * @param ts - Timestamp in milliseconds (defaults to current time)\n * @param randomBits - Random bits for the ID (defaults to a cryptographically secure random value)\n * @param epoch - Epoch timestamp in milliseconds (defaults to SIMPLEFLAKE_EPOCH)\n * @returns Generated simpleflake as a BigInt\n */\nexport function simpleflake(\n ts: number | bigint = Date.now(),\n randomBits?: number | bigint,\n epoch: number | bigint = SIMPLEFLAKE_EPOCH\n): bigint {\n // Use bitwise OR instead of addition since bit ranges don't overlap\n\n return (\n ((toBigInt(ts) - toBigInt(epoch)) << SIMPLEFLAKE_TIMESTAMP_SHIFT) |\n (randomBits == null ? random23() : toBigInt(randomBits))\n );\n}\n\n/**\n * Converts a value to binary representation\n * @param value - The value to convert to binary\n * @param padding - Whether to pad to 64 bits (defaults to true)\n * @returns Binary string representation\n */\nexport function binary(\n value: bigint | number | string,\n padding: boolean = true\n): string {\n const binValue = toBigInt(value).toString(2);\n return padding && binValue.length < 64\n ? CACHE_64_BIT_ZEROS.substr(0, 64 - binValue.length) + binValue\n : binValue;\n}\n\n/**\n * Extracts bits from a data value\n * @param data - The data to extract bits from\n * @param shift - Number of bits to shift\n * @param length - Number of bits to extract\n * @returns Extracted bits as a BigInt\n */\nexport function extractBits(\n data: bigint | number | string,\n shift: bigint | number,\n length: bigint | number\n): bigint {\n const shiftN = toBigInt(shift);\n const lengthN = toBigInt(length);\n // Optimize: shift right first, then mask (avoids creating large bitmask)\n return (toBigInt(data) >> shiftN) & ((1n << lengthN) - 1n);\n}\n\n/**\n * Structure representing a parsed simpleflake\n */\nexport class SimpleflakeStruct {\n public declare readonly timestamp: bigint;\n public declare readonly randomBits: bigint;\n\n constructor(timestamp: bigint, randomBits: bigint) {\n if (timestamp == null || randomBits == null) {\n throw new Error(\"Missing argument for SimpleflakeStruct.\");\n }\n this.timestamp = timestamp;\n this.randomBits = randomBits;\n }\n}\n\n/**\n * Parses a simpleflake into its components\n * @param flake - The simpleflake to parse\n * @returns SimpleflakeStruct containing timestamp and random bits\n */\nexport function parseSimpleflake(\n flake: bigint | number | string\n): SimpleflakeStruct {\n return new SimpleflakeStruct(\n // timestamp\n extractBits(\n flake,\n SIMPLEFLAKE_TIMESTAMP_SHIFT,\n SIMPLEFLAKE_TIMESTAMP_LENGTH\n ) + SIMPLEFLAKE_EPOCH,\n // random bits\n extractBits(flake, SIMPLEFLAKE_RANDOM_SHIFT, SIMPLEFLAKE_RANDOM_LENGTH)\n );\n}\n\n// Export constants\nexport { SIMPLEFLAKE_EPOCH };\n\n// Default export for CommonJS compatibility\nexport default {\n binary,\n extractBits,\n parseSimpleflake,\n SIMPLEFLAKE_EPOCH,\n simpleflake,\n SimpleflakeStruct,\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simpleflakes",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"description": "Fast, lightweight, and reliable distributed 64-bit ID generation with zero dependencies for Node.js and the web.",
|
|
5
5
|
"main": "dist/simpleflakes.js",
|
|
6
6
|
"types": "dist/simpleflakes.d.ts",
|
|
@@ -33,19 +33,24 @@
|
|
|
33
33
|
"keywords": [
|
|
34
34
|
"simpleflake",
|
|
35
35
|
"snowflake",
|
|
36
|
-
"
|
|
37
|
-
"id",
|
|
36
|
+
"snowflake-id",
|
|
37
|
+
"id-generator",
|
|
38
|
+
"unique-id",
|
|
39
|
+
"sortable-id",
|
|
40
|
+
"time-ordered",
|
|
41
|
+
"64-bit",
|
|
42
|
+
"bigint",
|
|
43
|
+
"distributed-id",
|
|
44
|
+
"database-id",
|
|
38
45
|
"uuid",
|
|
39
|
-
"sequential",
|
|
40
|
-
"monotonic",
|
|
41
|
-
"ksuid",
|
|
42
|
-
"nanoid",
|
|
43
46
|
"uuidv7",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"typescript"
|
|
47
|
+
"nanoid",
|
|
48
|
+
"ksuid",
|
|
49
|
+
"webcrypto",
|
|
50
|
+
"zero-dependency",
|
|
51
|
+
"typescript",
|
|
52
|
+
"nodejs",
|
|
53
|
+
"browser"
|
|
49
54
|
],
|
|
50
55
|
"author": {
|
|
51
56
|
"name": "Leonardo Dutra",
|