fantomid 1.0.0

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.
@@ -0,0 +1,2 @@
1
+ prettier $(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') -uw
2
+ git update-index --again
package/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) Gabriel de Oliveira <gabrielhk3@gmail.com> (https://nocnitsa.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # Fantom ID
2
+
3
+ A tiny, universal ID generator compatible with JavaScript integers.
4
+ Built for generating evenly distributed database identifiers at high concurrency.
5
+
6
+ ```js
7
+ import fantomid from "fantomid";
8
+ fantomid(); //=> 8209108814378532
9
+ ```
10
+
11
+ Fantom ID works by generating a timestamp of 36 bits and 17 random bits in
12
+ reverse order.
13
+
14
+ Generating a timestamp ensures the IDs are distributed evenly across time,
15
+ while the remaining bits of entropy allows different nodes to generate IDs at
16
+ the exact same moment with a low chance of collision.
17
+
18
+ ```
19
+
20
+ Bit-reverse
21
+ ◄─┐
22
+ Random bits Timestamp │
23
+ ┌─────────────────┐ ┌────────────────────────────────────┐ │
24
+ │11101001010100010│ │010000010110110011011011011000100100│ │
25
+ └─────────────────┘ └────────────────────────────────────┘
26
+
27
+ └───A2D2FF04C5────┘ └──────2025-11-24T19:13:45.994Z──────┘
28
+
29
+ ```
30
+
31
+ The result is a JavaScript-safe integer represented in bit-reverse order, which
32
+ prevents hotspots by keeping the monotonic part of the ID last.
33
+
34
+ It works similarly to [UUIDv7](https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-04.html#name-uuid-version-7), but restrained to the size of JavaScript integers: 53 bits.
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "fantomid",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "A tiny, universal ID generator compatible with JavaScript integers",
6
+ "keywords": [
7
+ "random",
8
+ "id",
9
+ "isomorphic"
10
+ ],
11
+ "author": "Gabriel de Oliveira <gabrielhk3@gmail.com> (https://nocnitsa.com)",
12
+ "license": "MIT",
13
+ "scripts": {
14
+ "prepare": "husky",
15
+ "build": "rimraf dist && pkgroll --sourcemap",
16
+ "test": "node --test --experimental-test-module-mocks **/*.spec.js"
17
+ },
18
+ "exports": {
19
+ "require": {
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
22
+ },
23
+ "import": {
24
+ "types": "./dist/index.d.mts",
25
+ "default": "./dist/index.mjs"
26
+ }
27
+ },
28
+ "dependencies": {
29
+ "@lukeed/csprng": "^1.1.0"
30
+ },
31
+ "devDependencies": {
32
+ "husky": "^9.1.7",
33
+ "pkgroll": "^2.21.3",
34
+ "prettier": "^3.6.2",
35
+ "rimraf": "^6.1.2",
36
+ "typescript": "^5.9.3"
37
+ }
38
+ }
@@ -0,0 +1,37 @@
1
+ import { random } from "@lukeed/csprng";
2
+
3
+ const EPOCH = new Date("2024-09-08");
4
+
5
+ export function fantomid() {
6
+ const TIMESTAMP_LENGTH = 36;
7
+ const RANDOM_BITS_LENGTH = 17;
8
+ const TIMESTAMP_PRECISION_DIVIDER = 100;
9
+
10
+ const bits = new Array(TIMESTAMP_LENGTH + RANDOM_BITS_LENGTH);
11
+
12
+ // Generates a timestamp to be part of the key. This is
13
+ // inspired by how UUID v7 works: the idea is that this
14
+ // will guarantee keys are generated evenly across time.
15
+ const timestamp = Math.round(
16
+ // Use a more recent base date instead of the Unix Epoch to
17
+ // increase the amount of time we can represent in the timestamp.
18
+ (new Date() - EPOCH) /
19
+ // Decrease the precision of the timestamp to
20
+ // increase the amount of bits we can fit in a key.
21
+ TIMESTAMP_PRECISION_DIVIDER,
22
+ );
23
+ for (let i = 0; i < TIMESTAMP_LENGTH; i++) {
24
+ bits[TIMESTAMP_LENGTH + RANDOM_BITS_LENGTH - 1 - i] = (timestamp >> i) & 1;
25
+ }
26
+
27
+ // Generates a randomized part of the key. If multiple machines generate a
28
+ // key at the exact same time (limited by the precision of the timestamp),
29
+ // we are ensured to have a chance of collision of `1` in `2 ** RANDOM_BITS_LENGTH`.
30
+ const randomBytes = random(Math.ceil(RANDOM_BITS_LENGTH / 8));
31
+ for (let i = 0; i < RANDOM_BITS_LENGTH; i++) {
32
+ bits[RANDOM_BITS_LENGTH - 1 - i] =
33
+ (randomBytes[Math.floor(i / 8)] >> i % 8) & 1;
34
+ }
35
+
36
+ return Number("0b" + bits.reduce((id, bit) => id + bit, String()));
37
+ }
@@ -0,0 +1,22 @@
1
+ import { test, mock, before, it } from "node:test";
2
+ import assert from "assert/strict";
3
+
4
+ test("fantomid", () => {
5
+ let randomMock = mock.fn();
6
+ let fantomid;
7
+
8
+ before(async () => {
9
+ mock.module("@lukeed/csprng", { namedExports: { random: randomMock } });
10
+ ({ fantomid } = await import("./fantomid.js"));
11
+ });
12
+
13
+ it("should generate an id", () => {
14
+ randomMock.mock.mockImplementationOnce(() =>
15
+ Buffer.from([0xa2, 0xd2, 0xff, 0x04, 0xc5]),
16
+ );
17
+ console.log(Buffer.from([0xa2, 0xd2, 0xff, 0x04, 0xc5]));
18
+ mock.timers.enable({ now: new Date("2025-11-24T19:13:45.994Z") });
19
+ const id = fantomid();
20
+ assert.equal(id, 8209108814378532);
21
+ });
22
+ });
package/src/index.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Generates an JavaScript-friendly unique ID.
3
+ *
4
+ * ```js
5
+ * import fantomId from "fantomid";
6
+ * fantomid(); //=> 5895736349537828
7
+ * ```
8
+ *
9
+ * @returns A random integer.
10
+ */
11
+ export default function fantomid(): number;
package/src/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import { fantomid } from "./fantomid.js";
2
+ export default fantomid;