@tabsircg/snowflake 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,30 @@
1
+ export type SnowflakeId<T extends boolean> = T extends true ? string : bigint;
2
+ /**
3
+ * Creates a Snowflake ID generator with consistent sequence tracking.
4
+ *
5
+ * @param workerId - Unique worker identifier
6
+ * @param datacenterId - Unique datacenter identifier
7
+ * @returns Function that generates unique Snowflake IDs
8
+ *
9
+ * @example
10
+ * const generator = createSnowflakeGenerator(1, 1);
11
+ * const id = generator(); // 1234567890123456789n
12
+ * const stringId = generator(true); // "1234567890123456789"
13
+ */
14
+ export declare const createSnowflakeGenerator: (workerId: number, datacenterId: number) => <T extends boolean = false>(returnAsString?: T) => SnowflakeId<T>;
15
+ /**
16
+ * Generates a Snowflake ID for a specific timestamp (used for cleanup thresholds).
17
+ *
18
+ * @param timestamp - Unix timestamp in milliseconds
19
+ * @param workerId - Worker ID (default: 0 for minimum possible ID)
20
+ * @param datacenterId - Datacenter ID (default: 0 for minimum possible ID)
21
+ * @param sequence - Sequence number (default: 0 for minimum possible ID)
22
+ * @returns Snowflake ID as BigInt
23
+ *
24
+ * @example
25
+ * // Get threshold for deleting records older than 30 days
26
+ * const thirtyDaysAgo = Date.now() - (30 * 24 * 60 * 60 * 1000);
27
+ * const threshold = generateTimestampSnowflake(thirtyDaysAgo);
28
+ */
29
+ export declare const generateTimestampSnowflake: (timestamp: number, workerId: number, datacenterId: number, sequence: number) => bigint;
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,OAAO,IAAI,CAAC,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAE9E;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,wBAAwB,GACnC,UAAU,MAAM,EAChB,cAAc,MAAM,MAyBZ,CAAC,SAAS,OAAO,GAAG,KAAK,EAAE,iBAAiB,CAAC,KAAG,WAAW,CAAC,CAAC,CA+BtE,CAAC;AAEF;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,0BAA0B,GACrC,WAAW,MAAM,EACjB,UAAU,MAAM,EAChB,cAAc,MAAM,EACpB,UAAU,MAAM,WAUjB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,93 @@
1
+ const SNOWFLAKE_EPOCH = 1770479980106;
2
+ const SNOWFLAKE_BITS = {
3
+ SEQUENCE: 11,
4
+ WORKER_ID: 4,
5
+ DATACENTER_ID: 5,
6
+ };
7
+ const SNOWFLAKE_SHIFTS = {
8
+ WORKER_ID: SNOWFLAKE_BITS.SEQUENCE,
9
+ DATACENTER_ID: SNOWFLAKE_BITS.SEQUENCE + SNOWFLAKE_BITS.WORKER_ID,
10
+ TIMESTAMP: SNOWFLAKE_BITS.SEQUENCE +
11
+ SNOWFLAKE_BITS.WORKER_ID +
12
+ SNOWFLAKE_BITS.DATACENTER_ID,
13
+ };
14
+ const SNOWFLAKE_MASKS = {
15
+ SEQUENCE: (1 << SNOWFLAKE_BITS.SEQUENCE) - 1,
16
+ };
17
+ /**
18
+ * Creates a Snowflake ID generator with consistent sequence tracking.
19
+ *
20
+ * @param workerId - Unique worker identifier
21
+ * @param datacenterId - Unique datacenter identifier
22
+ * @returns Function that generates unique Snowflake IDs
23
+ *
24
+ * @example
25
+ * const generator = createSnowflakeGenerator(1, 1);
26
+ * const id = generator(); // 1234567890123456789n
27
+ * const stringId = generator(true); // "1234567890123456789"
28
+ */
29
+ export const createSnowflakeGenerator = (workerId, datacenterId) => {
30
+ const maxWorkerId = (1 << SNOWFLAKE_BITS.WORKER_ID) - 1;
31
+ const maxDatacenterId = (1 << SNOWFLAKE_BITS.DATACENTER_ID) - 1;
32
+ if (workerId < 0 || workerId > maxWorkerId) {
33
+ throw new Error(`Worker ID must be between 0 and ${maxWorkerId}`);
34
+ }
35
+ if (datacenterId < 0 || datacenterId > maxDatacenterId) {
36
+ throw new Error(`Datacenter ID must be between 0 and ${maxDatacenterId}`);
37
+ }
38
+ let sequence = 0;
39
+ let lastTimestamp = -1;
40
+ const getCurrentTimestamp = () => Date.now();
41
+ const waitForNextMillis = (lastTimestamp) => {
42
+ let timestamp = getCurrentTimestamp();
43
+ while (timestamp <= lastTimestamp) {
44
+ timestamp = getCurrentTimestamp();
45
+ }
46
+ return timestamp;
47
+ };
48
+ return (returnAsString) => {
49
+ let timestamp = getCurrentTimestamp();
50
+ if (timestamp < lastTimestamp) {
51
+ throw new Error(`Clock moved backwards. Refusing to generate id for ${lastTimestamp - timestamp} milliseconds`);
52
+ }
53
+ if (timestamp === lastTimestamp) {
54
+ sequence = (sequence + 1) & SNOWFLAKE_MASKS.SEQUENCE;
55
+ if (sequence === 0) {
56
+ timestamp = waitForNextMillis(lastTimestamp);
57
+ }
58
+ }
59
+ else {
60
+ sequence = 0;
61
+ }
62
+ lastTimestamp = timestamp;
63
+ const id = (BigInt(timestamp - SNOWFLAKE_EPOCH) <<
64
+ BigInt(SNOWFLAKE_SHIFTS.TIMESTAMP)) +
65
+ (BigInt(datacenterId) << BigInt(SNOWFLAKE_SHIFTS.DATACENTER_ID)) +
66
+ (BigInt(workerId) << BigInt(SNOWFLAKE_SHIFTS.WORKER_ID)) +
67
+ BigInt(sequence);
68
+ return (returnAsString ? id.toString() : id);
69
+ };
70
+ };
71
+ /**
72
+ * Generates a Snowflake ID for a specific timestamp (used for cleanup thresholds).
73
+ *
74
+ * @param timestamp - Unix timestamp in milliseconds
75
+ * @param workerId - Worker ID (default: 0 for minimum possible ID)
76
+ * @param datacenterId - Datacenter ID (default: 0 for minimum possible ID)
77
+ * @param sequence - Sequence number (default: 0 for minimum possible ID)
78
+ * @returns Snowflake ID as BigInt
79
+ *
80
+ * @example
81
+ * // Get threshold for deleting records older than 30 days
82
+ * const thirtyDaysAgo = Date.now() - (30 * 24 * 60 * 60 * 1000);
83
+ * const threshold = generateTimestampSnowflake(thirtyDaysAgo);
84
+ */
85
+ export const generateTimestampSnowflake = (timestamp, workerId, datacenterId, sequence) => {
86
+ const id = (BigInt(timestamp - SNOWFLAKE_EPOCH) <<
87
+ BigInt(SNOWFLAKE_SHIFTS.TIMESTAMP)) +
88
+ (BigInt(datacenterId) << BigInt(SNOWFLAKE_SHIFTS.DATACENTER_ID)) +
89
+ (BigInt(workerId) << BigInt(SNOWFLAKE_SHIFTS.WORKER_ID)) +
90
+ BigInt(sequence);
91
+ return id;
92
+ };
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@tabsircg/snowflake",
3
+ "version": "1.0.0",
4
+ "description": "Lightweight Snowflake ID generator for Node.js",
5
+ "license": "ISC",
6
+ "author": "Tabsir CG",
7
+ "type": "module",
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "prepublishOnly": "tsc"
22
+ },
23
+ "keywords": [
24
+ "snowflake",
25
+ "id",
26
+ "generator",
27
+ "distributed",
28
+ "unique-id"
29
+ ],
30
+ "devDependencies": {
31
+ "typescript": "^5.9.3"
32
+ }
33
+ }