scru64
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -9,9 +9,21 @@ /** | ||
/** | ||
* 8-byte byte array containing the 64-bit unsigned integer representation in | ||
* the big-endian (network) byte order. | ||
* An 8-byte byte array containing the 64-bit unsigned integer representation | ||
* in the big-endian (network) byte order. | ||
*/ | ||
readonly bytes: Readonly<Uint8Array>; | ||
/** Creates an object from a 8-byte byte array. */ | ||
/** Creates an object from an 8-byte byte array. */ | ||
private constructor(); | ||
/** | ||
* Creates an object from the internal representation, an 8-byte byte array | ||
* containing the 64-bit unsigned integer representation in the big-endian | ||
* (network) byte order. | ||
* | ||
* This method does NOT shallow-copy the argument, and thus the created object | ||
* holds the reference to the underlying buffer. | ||
* | ||
* @throws RangeError if the length of the argument is not 8 or the argument | ||
* contains an integer out of the valid value range. | ||
*/ | ||
static ofInner(bytes: Uint8Array): Scru64Id; | ||
/** | ||
* Returns the 12-digit canonical string representation. | ||
@@ -66,3 +78,3 @@ * | ||
* Note that this class is designed to be immutable, and thus `clone()` is not | ||
* necessary unless properties marked as private are modified directly. | ||
* necessary unless properties marked as read-only are modified. | ||
*/ | ||
@@ -85,19 +97,19 @@ clone(): Scru64Id; | ||
* | ||
* | Flavor | Timestamp | On big clock rewind | | ||
* | ---------------------------- | --------- | -------------------- | | ||
* | {@link generate} | Now | Rewinds state | | ||
* | {@link generateNoRewind} | Now | Returns `undefined` | | ||
* | {@link generateOrWait} | Now | Waits (blocking) | | ||
* | {@link generateOrWaitAsync} | Now | Waits (non-blocking) | | ||
* | {@link generateCore} | Argument | Rewinds state | | ||
* | {@link generateCoreNoRewind} | Argument | Returns `undefined` | | ||
* | Flavor | Timestamp | On big clock rewind | | ||
* | --------------------------- | --------- | ------------------- | | ||
* | {@link generate} | Now | Returns `undefined` | | ||
* | {@link generateOrReset} | Now | Resets generator | | ||
* | {@link generateOrSleep} | Now | Sleeps (blocking) | | ||
* | {@link generateOrAwait} | Now | Sleeps (async) | | ||
* | {@link generateOrAbortCore} | Argument | Returns `undefined` | | ||
* | {@link generateOrResetCore} | Argument | Resets generator | | ||
* | ||
* Each method returns monotonically increasing IDs unless a timestamp provided | ||
* is significantly (by ~10 seconds or more) smaller than the one embedded in | ||
* the immediately preceding ID. If such a significant clock rollback is | ||
* detected, (i) the standard `generate` rewinds the generator state and returns | ||
* a new ID based on the current timestamp; (ii) `NoRewind` variants keep the | ||
* state untouched and return `undefined`; and, (iii) `OrWait` functions sleep | ||
* and wait for the next timestamp tick. `core` functions offer low-level | ||
* primitives. | ||
* All of these methods return monotonically increasing IDs unless a timestamp | ||
* provided is significantly (by default, approx. 10 seconds or more) smaller | ||
* than the one embedded in the immediately preceding ID. If such a significant | ||
* clock rollback is detected, (1) the `generate` (OrAbort) method aborts and | ||
* returns `undefined`; (2) the `OrReset` variants reset the generator and | ||
* return a new ID based on the given timestamp; and, (3) the `OrSleep` and | ||
* `OrAwait` methods sleep and wait for the next timestamp tick. The `Core` | ||
* functions offer low-level primitives. | ||
*/ | ||
@@ -139,18 +151,18 @@ export declare class Scru64Generator { | ||
/** | ||
* Generates a new SCRU64 ID object from the current `timestamp`. | ||
* Generates a new SCRU64 ID object from the current `timestamp`, or returns | ||
* `undefined` upon significant timestamp rollback. | ||
* | ||
* See the {@link Scru64Generator} class documentation for the description. | ||
*/ | ||
generate(): Scru64Id; | ||
generate(): Scru64Id | undefined; | ||
/** | ||
* Generates a new SCRU64 ID object from the current `timestamp`, guaranteeing | ||
* the monotonic order of generated IDs despite a significant timestamp | ||
* rollback. | ||
* Generates a new SCRU64 ID object from the current `timestamp`, or resets | ||
* the generator upon significant timestamp rollback. | ||
* | ||
* See the {@link Scru64Generator} class documentation for the description. | ||
*/ | ||
generateNoRewind(): Scru64Id | undefined; | ||
generateOrReset(): Scru64Id; | ||
/** | ||
* Returns a new SCRU64 ID object, or waits for one if not immediately | ||
* available. | ||
* Returns a new SCRU64 ID object, or synchronously sleeps and waits for one | ||
* if not immediately available. | ||
* | ||
@@ -160,32 +172,36 @@ * See the {@link Scru64Generator} class documentation for the description. | ||
* This method uses a blocking busy loop to wait for the next `timestamp` | ||
* tick. Use {@link generateOrWaitAsync} where possible. | ||
* tick. Use {@link generateOrAwait} where possible. | ||
*/ | ||
generateOrWait(): Scru64Id; | ||
generateOrSleep(): Scru64Id; | ||
/** | ||
* Returns a new SCRU64 ID object, or waits for one if not immediately | ||
* available. | ||
* Returns a new SCRU64 ID object, or asynchronously sleeps and waits for one | ||
* if not immediately available. | ||
* | ||
* See the {@link Scru64Generator} class documentation for the description. | ||
*/ | ||
generateOrWaitAsync(): Promise<Scru64Id>; | ||
generateOrAwait(): Promise<Scru64Id>; | ||
/** | ||
* Generates a new SCRU64 ID object from a Unix timestamp in milliseconds. | ||
* Generates a new SCRU64 ID object from a Unix timestamp in milliseconds, or | ||
* resets the generator upon significant timestamp rollback. | ||
* | ||
* See the {@link Scru64Generator} class documentation for the description. | ||
* | ||
* @throws RangeError if the argument is not a positive integer within the | ||
* valid range. | ||
* @param rollbackAllowance - The amount of `unixTsMs` rollback that is | ||
* considered significant. A suggested value is `10_000` (milliseconds). | ||
* @throws RangeError if `unixTsMs` is not a positive integer within the valid | ||
* range. | ||
*/ | ||
generateCore(unixTsMs: number): Scru64Id; | ||
generateOrResetCore(unixTsMs: number, rollbackAllowance: number): Scru64Id; | ||
/** | ||
* Generates a new SCRU64 ID object from a Unix timestamp in milliseconds, | ||
* guaranteeing the monotonic order of generated IDs despite a significant | ||
* timestamp rollback. | ||
* Generates a new SCRU64 ID object from a Unix timestamp in milliseconds, or | ||
* returns `undefined` upon significant timestamp rollback. | ||
* | ||
* See the {@link Scru64Generator} class documentation for the description. | ||
* | ||
* @throws RangeError if the argument is not a positive integer within the | ||
* valid range. | ||
* @param rollbackAllowance - The amount of `unixTsMs` rollback that is | ||
* considered significant. A suggested value is `10_000` (milliseconds). | ||
* @throws RangeError if `unixTsMs` is not a positive integer within the valid | ||
* range. | ||
*/ | ||
generateCoreNoRewind(unixTsMs: number): Scru64Id | undefined; | ||
generateOrAbortCore(unixTsMs: number, rollbackAllowance: number): Scru64Id | undefined; | ||
} | ||
@@ -195,6 +211,14 @@ /** | ||
* | ||
* The global generator reads the node configuration from the `SCRU64_NODE_SPEC` | ||
* global variable. A node spec string consists of `nodeId` and `nodeIdSize` | ||
* separated by a slash (e.g., `"42/8"`, `"12345/16"`). | ||
* | ||
* This function usually returns a value immediately, but if not possible, it | ||
* sleeps and waits for the next timestamp tick. It employs a blocking busy loop | ||
* to wait; use the non-blocking {@link scru64} where possible. | ||
* | ||
* @throws Error if the global generator is not properly configured through the | ||
* `SCRU64_NODE_SPEC` global variable. | ||
* global variable. | ||
*/ | ||
export declare const scru64: () => Scru64Id; | ||
export declare const scru64Sync: () => Scru64Id; | ||
/** | ||
@@ -204,13 +228,28 @@ * Generates a new SCRU64 ID encoded in the 12-digit canonical string | ||
* | ||
* The global generator reads the node configuration from the `SCRU64_NODE_SPEC` | ||
* global variable. A node spec string consists of `nodeId` and `nodeIdSize` | ||
* separated by a slash (e.g., `"42/8"`, `"12345/16"`). | ||
* | ||
* This function usually returns a value immediately, but if not possible, it | ||
* sleeps and waits for the next timestamp tick. It employs a blocking busy loop | ||
* to wait; use the non-blocking {@link scru64String} where possible. | ||
* | ||
* @throws Error if the global generator is not properly configured through the | ||
* `SCRU64_NODE_SPEC` global variable. | ||
* global variable. | ||
*/ | ||
export declare const scru64String: () => string; | ||
export declare const scru64StringSync: () => string; | ||
/** | ||
* Generates a new SCRU64 ID object using the global generator. | ||
* | ||
* The global generator reads the node configuration from the `SCRU64_NODE_SPEC` | ||
* global variable. A node spec string consists of `nodeId` and `nodeIdSize` | ||
* separated by a slash (e.g., `"42/8"`, `"12345/16"`). | ||
* | ||
* This function usually returns a value immediately, but if not possible, it | ||
* sleeps and waits for the next timestamp tick. | ||
* | ||
* @throws Error if the global generator is not properly configured through the | ||
* `SCRU64_NODE_SPEC` global variable. | ||
* global variable. | ||
*/ | ||
export declare const scru64Async: () => Promise<Scru64Id>; | ||
export declare const scru64: () => Promise<Scru64Id>; | ||
/** | ||
@@ -220,5 +259,12 @@ * Generates a new SCRU64 ID encoded in the 12-digit canonical string | ||
* | ||
* The global generator reads the node configuration from the `SCRU64_NODE_SPEC` | ||
* global variable. A node spec string consists of `nodeId` and `nodeIdSize` | ||
* separated by a slash (e.g., `"42/8"`, `"12345/16"`). | ||
* | ||
* This function usually returns a value immediately, but if not possible, it | ||
* sleeps and waits for the next timestamp tick. | ||
* | ||
* @throws Error if the global generator is not properly configured through the | ||
* `SCRU64_NODE_SPEC` global variable. | ||
* global variable. | ||
*/ | ||
export declare const scru64StringAsync: () => Promise<string>; | ||
export declare const scru64String: () => Promise<string>; |
@@ -6,11 +6,13 @@ /** | ||
*/ | ||
/** Total size in bits of the `nodeId` and `counter` fields. */ | ||
/** The maximum valid value (i.e., `zzzzzzzzzzzz`). */ | ||
const MAX_SCRU64_BYTES = Uint8Array.of(65, 194, 28, 184, 224, 255, 255, 255); | ||
/** The total size in bits of the `nodeId` and `counter` fields. */ | ||
const NODE_CTR_SIZE = 24; | ||
/// Maximum valid value of the `timestamp` field. | ||
const TIMESTAMP_MAX = 282429536480; // (36n ** 12n - 1n) >> 24n | ||
/// Maximum valid value of the combined `nodeCtr` field. | ||
const NODE_CTR_MAX = (1 << NODE_CTR_SIZE) - 1; | ||
/// The maximum valid value of the `timestamp` field. | ||
const MAX_TIMESTAMP = 282429536480; // (36n ** 12n - 1n) >> 24n | ||
/// The maximum valid value of the combined `nodeCtr` field. | ||
const MAX_NODE_CTR = (1 << NODE_CTR_SIZE) - 1; | ||
/** Digit characters used in the Base36 notation. */ | ||
const DIGITS = "0123456789abcdefghijklmnopqrstuvwxyz"; | ||
/** O(1) map from ASCII code points to Base36 digit values. */ | ||
/** An O(1) map from ASCII code points to Base36 digit values. */ | ||
const DECODE_MAP = [ | ||
@@ -30,3 +32,3 @@ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, | ||
export class Scru64Id { | ||
/** Creates an object from a 8-byte byte array. */ | ||
/** Creates an object from an 8-byte byte array. */ | ||
constructor(bytes) { | ||
@@ -36,2 +38,27 @@ this.bytes = bytes; | ||
/** | ||
* Creates an object from the internal representation, an 8-byte byte array | ||
* containing the 64-bit unsigned integer representation in the big-endian | ||
* (network) byte order. | ||
* | ||
* This method does NOT shallow-copy the argument, and thus the created object | ||
* holds the reference to the underlying buffer. | ||
* | ||
* @throws RangeError if the length of the argument is not 8 or the argument | ||
* contains an integer out of the valid value range. | ||
*/ | ||
static ofInner(bytes) { | ||
if (bytes.length !== 8) { | ||
throw new RangeError("invalid length: " + bytes.length); | ||
} | ||
for (let i = 0; i < 8; i++) { | ||
if (bytes[i] > MAX_SCRU64_BYTES[i]) { | ||
throw new RangeError("integer out of valid value range"); | ||
} | ||
else if (bytes[i] < MAX_SCRU64_BYTES[i]) { | ||
break; | ||
} | ||
} | ||
return new Scru64Id(bytes); | ||
} | ||
/** | ||
* Returns the 12-digit canonical string representation. | ||
@@ -140,3 +167,3 @@ * | ||
if (timestamp < 0 || | ||
timestamp > TIMESTAMP_MAX || | ||
timestamp > MAX_TIMESTAMP || | ||
!Number.isInteger(timestamp)) { | ||
@@ -146,3 +173,3 @@ throw new RangeError("`timestamp` out of range"); | ||
else if (nodeCtr < 0 || | ||
nodeCtr > NODE_CTR_MAX || | ||
nodeCtr > MAX_NODE_CTR || | ||
!Number.isInteger(nodeCtr)) { | ||
@@ -185,3 +212,3 @@ throw new RangeError("`nodeCtr` out of range"); | ||
* Note that this class is designed to be immutable, and thus `clone()` is not | ||
* necessary unless properties marked as private are modified directly. | ||
* necessary unless properties marked as read-only are modified. | ||
*/ | ||
@@ -222,19 +249,19 @@ clone() { | ||
* | ||
* | Flavor | Timestamp | On big clock rewind | | ||
* | ---------------------------- | --------- | -------------------- | | ||
* | {@link generate} | Now | Rewinds state | | ||
* | {@link generateNoRewind} | Now | Returns `undefined` | | ||
* | {@link generateOrWait} | Now | Waits (blocking) | | ||
* | {@link generateOrWaitAsync} | Now | Waits (non-blocking) | | ||
* | {@link generateCore} | Argument | Rewinds state | | ||
* | {@link generateCoreNoRewind} | Argument | Returns `undefined` | | ||
* | Flavor | Timestamp | On big clock rewind | | ||
* | --------------------------- | --------- | ------------------- | | ||
* | {@link generate} | Now | Returns `undefined` | | ||
* | {@link generateOrReset} | Now | Resets generator | | ||
* | {@link generateOrSleep} | Now | Sleeps (blocking) | | ||
* | {@link generateOrAwait} | Now | Sleeps (async) | | ||
* | {@link generateOrAbortCore} | Argument | Returns `undefined` | | ||
* | {@link generateOrResetCore} | Argument | Resets generator | | ||
* | ||
* Each method returns monotonically increasing IDs unless a timestamp provided | ||
* is significantly (by ~10 seconds or more) smaller than the one embedded in | ||
* the immediately preceding ID. If such a significant clock rollback is | ||
* detected, (i) the standard `generate` rewinds the generator state and returns | ||
* a new ID based on the current timestamp; (ii) `NoRewind` variants keep the | ||
* state untouched and return `undefined`; and, (iii) `OrWait` functions sleep | ||
* and wait for the next timestamp tick. `core` functions offer low-level | ||
* primitives. | ||
* All of these methods return monotonically increasing IDs unless a timestamp | ||
* provided is significantly (by default, approx. 10 seconds or more) smaller | ||
* than the one embedded in the immediately preceding ID. If such a significant | ||
* clock rollback is detected, (1) the `generate` (OrAbort) method aborts and | ||
* returns `undefined`; (2) the `OrReset` variants reset the generator and | ||
* return a new ID based on the given timestamp; and, (3) the `OrSleep` and | ||
* `OrAwait` methods sleep and wait for the next timestamp tick. The `Core` | ||
* functions offer low-level primitives. | ||
*/ | ||
@@ -303,3 +330,4 @@ export class Scru64Generator { | ||
/** | ||
* Generates a new SCRU64 ID object from the current `timestamp`. | ||
* Generates a new SCRU64 ID object from the current `timestamp`, or returns | ||
* `undefined` upon significant timestamp rollback. | ||
* | ||
@@ -309,17 +337,16 @@ * See the {@link Scru64Generator} class documentation for the description. | ||
generate() { | ||
return this.generateCore(Date.now()); | ||
return this.generateOrAbortCore(Date.now(), 10000); | ||
} | ||
/** | ||
* Generates a new SCRU64 ID object from the current `timestamp`, guaranteeing | ||
* the monotonic order of generated IDs despite a significant timestamp | ||
* rollback. | ||
* Generates a new SCRU64 ID object from the current `timestamp`, or resets | ||
* the generator upon significant timestamp rollback. | ||
* | ||
* See the {@link Scru64Generator} class documentation for the description. | ||
*/ | ||
generateNoRewind() { | ||
return this.generateCoreNoRewind(Date.now()); | ||
generateOrReset() { | ||
return this.generateOrResetCore(Date.now(), 10000); | ||
} | ||
/** | ||
* Returns a new SCRU64 ID object, or waits for one if not immediately | ||
* available. | ||
* Returns a new SCRU64 ID object, or synchronously sleeps and waits for one | ||
* if not immediately available. | ||
* | ||
@@ -329,7 +356,7 @@ * See the {@link Scru64Generator} class documentation for the description. | ||
* This method uses a blocking busy loop to wait for the next `timestamp` | ||
* tick. Use {@link generateOrWaitAsync} where possible. | ||
* tick. Use {@link generateOrAwait} where possible. | ||
*/ | ||
generateOrWait() { | ||
generateOrSleep() { | ||
while (true) { | ||
const value = this.generateNoRewind(); | ||
const value = this.generate(); | ||
if (value !== undefined) { | ||
@@ -344,11 +371,11 @@ return value; | ||
/** | ||
* Returns a new SCRU64 ID object, or waits for one if not immediately | ||
* available. | ||
* Returns a new SCRU64 ID object, or asynchronously sleeps and waits for one | ||
* if not immediately available. | ||
* | ||
* See the {@link Scru64Generator} class documentation for the description. | ||
*/ | ||
async generateOrWaitAsync() { | ||
async generateOrAwait() { | ||
const DELAY = 64; | ||
while (true) { | ||
const value = this.generateNoRewind(); | ||
const value = this.generate(); | ||
if (value !== undefined) { | ||
@@ -363,11 +390,14 @@ return value; | ||
/** | ||
* Generates a new SCRU64 ID object from a Unix timestamp in milliseconds. | ||
* Generates a new SCRU64 ID object from a Unix timestamp in milliseconds, or | ||
* resets the generator upon significant timestamp rollback. | ||
* | ||
* See the {@link Scru64Generator} class documentation for the description. | ||
* | ||
* @throws RangeError if the argument is not a positive integer within the | ||
* valid range. | ||
* @param rollbackAllowance - The amount of `unixTsMs` rollback that is | ||
* considered significant. A suggested value is `10_000` (milliseconds). | ||
* @throws RangeError if `unixTsMs` is not a positive integer within the valid | ||
* range. | ||
*/ | ||
generateCore(unixTsMs) { | ||
const value = this.generateCoreNoRewind(unixTsMs); | ||
generateOrResetCore(unixTsMs, rollbackAllowance) { | ||
const value = this.generateOrAbortCore(unixTsMs, rollbackAllowance); | ||
if (value !== undefined) { | ||
@@ -384,17 +414,21 @@ return value; | ||
/** | ||
* Generates a new SCRU64 ID object from a Unix timestamp in milliseconds, | ||
* guaranteeing the monotonic order of generated IDs despite a significant | ||
* timestamp rollback. | ||
* Generates a new SCRU64 ID object from a Unix timestamp in milliseconds, or | ||
* returns `undefined` upon significant timestamp rollback. | ||
* | ||
* See the {@link Scru64Generator} class documentation for the description. | ||
* | ||
* @throws RangeError if the argument is not a positive integer within the | ||
* valid range. | ||
* @param rollbackAllowance - The amount of `unixTsMs` rollback that is | ||
* considered significant. A suggested value is `10_000` (milliseconds). | ||
* @throws RangeError if `unixTsMs` is not a positive integer within the valid | ||
* range. | ||
*/ | ||
generateCoreNoRewind(unixTsMs) { | ||
const ROLLBACK_ALLOWANCE = 40; // x256 milliseconds = ~10 seconds | ||
generateOrAbortCore(unixTsMs, rollbackAllowance) { | ||
const timestamp = Math.trunc(unixTsMs / 0x100); | ||
const allowance = Math.trunc(rollbackAllowance / 0x100); | ||
if (timestamp <= 0) { | ||
throw new RangeError("`timestamp` out of range"); | ||
} | ||
else if (allowance < 0 || allowance > 1099511627775) { | ||
throw new RangeError("`rollbackAllowance` out of reasonable range"); | ||
} | ||
if (timestamp > this.prevTimestamp) { | ||
@@ -404,3 +438,3 @@ this.prevTimestamp = timestamp; | ||
} | ||
else if (timestamp + ROLLBACK_ALLOWANCE > this.prevTimestamp) { | ||
else if (timestamp + allowance > this.prevTimestamp) { | ||
// go on with previous timestamp if new one is not much smaller | ||
@@ -418,3 +452,3 @@ const counterMask = (1 << this.counterSize) - 1; | ||
else { | ||
// abort if clock moves back to unbearable extent | ||
// abort if clock went backwards to unbearable extent | ||
return undefined; | ||
@@ -438,6 +472,14 @@ } | ||
* | ||
* The global generator reads the node configuration from the `SCRU64_NODE_SPEC` | ||
* global variable. A node spec string consists of `nodeId` and `nodeIdSize` | ||
* separated by a slash (e.g., `"42/8"`, `"12345/16"`). | ||
* | ||
* This function usually returns a value immediately, but if not possible, it | ||
* sleeps and waits for the next timestamp tick. It employs a blocking busy loop | ||
* to wait; use the non-blocking {@link scru64} where possible. | ||
* | ||
* @throws Error if the global generator is not properly configured through the | ||
* `SCRU64_NODE_SPEC` global variable. | ||
* global variable. | ||
*/ | ||
export const scru64 = () => getGlobalGenerator().generateOrWait(); | ||
export const scru64Sync = () => getGlobalGenerator().generateOrSleep(); | ||
/** | ||
@@ -447,13 +489,28 @@ * Generates a new SCRU64 ID encoded in the 12-digit canonical string | ||
* | ||
* The global generator reads the node configuration from the `SCRU64_NODE_SPEC` | ||
* global variable. A node spec string consists of `nodeId` and `nodeIdSize` | ||
* separated by a slash (e.g., `"42/8"`, `"12345/16"`). | ||
* | ||
* This function usually returns a value immediately, but if not possible, it | ||
* sleeps and waits for the next timestamp tick. It employs a blocking busy loop | ||
* to wait; use the non-blocking {@link scru64String} where possible. | ||
* | ||
* @throws Error if the global generator is not properly configured through the | ||
* `SCRU64_NODE_SPEC` global variable. | ||
* global variable. | ||
*/ | ||
export const scru64String = () => scru64().toString(); | ||
export const scru64StringSync = () => scru64Sync().toString(); | ||
/** | ||
* Generates a new SCRU64 ID object using the global generator. | ||
* | ||
* The global generator reads the node configuration from the `SCRU64_NODE_SPEC` | ||
* global variable. A node spec string consists of `nodeId` and `nodeIdSize` | ||
* separated by a slash (e.g., `"42/8"`, `"12345/16"`). | ||
* | ||
* This function usually returns a value immediately, but if not possible, it | ||
* sleeps and waits for the next timestamp tick. | ||
* | ||
* @throws Error if the global generator is not properly configured through the | ||
* `SCRU64_NODE_SPEC` global variable. | ||
* global variable. | ||
*/ | ||
export const scru64Async = async () => getGlobalGenerator().generateOrWaitAsync(); | ||
export const scru64 = async () => getGlobalGenerator().generateOrAwait(); | ||
/** | ||
@@ -463,5 +520,12 @@ * Generates a new SCRU64 ID encoded in the 12-digit canonical string | ||
* | ||
* The global generator reads the node configuration from the `SCRU64_NODE_SPEC` | ||
* global variable. A node spec string consists of `nodeId` and `nodeIdSize` | ||
* separated by a slash (e.g., `"42/8"`, `"12345/16"`). | ||
* | ||
* This function usually returns a value immediately, but if not possible, it | ||
* sleeps and waits for the next timestamp tick. | ||
* | ||
* @throws Error if the global generator is not properly configured through the | ||
* `SCRU64_NODE_SPEC` global variable. | ||
* global variable. | ||
*/ | ||
export const scru64StringAsync = async () => (await scru64Async()).toString(); | ||
export const scru64String = async () => (await scru64()).toString(); |
{ | ||
"name": "scru64", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "SCRU64: Sortable, Clock-based, Realm-specifically Unique identifier", | ||
@@ -18,3 +18,3 @@ "type": "module", | ||
"predoc": "rm -rf ./docs", | ||
"prepare": "npm run build && npm run doc", | ||
"prepare": "npm run build && npm run doc && npm test", | ||
"test": "mocha" | ||
@@ -34,5 +34,5 @@ }, | ||
"mocha": "^10.2.0", | ||
"typedoc": "^0.23.26", | ||
"typescript": "^4.9.5" | ||
"typedoc": "^0.23.28", | ||
"typescript": "^5.0.2" | ||
} | ||
} |
@@ -19,8 +19,8 @@ # SCRU64: Sortable, Clock-based, Realm-specifically Unique identifier | ||
import { scru64, scru64String } from "scru64"; | ||
import { scru64Sync, scru64StringSync } from "scru64"; | ||
// or on browsers: | ||
// import { scru64, scru64String } from "https://unpkg.com/scru64@^0.1"; | ||
// import { scru64Sync, scru64StringSync } from "https://unpkg.com/scru64@^0.2"; | ||
// generate a new identifier object | ||
const x = scru64(); | ||
const x = scru64Sync(); | ||
console.log(String(x)); // e.g. "0u2r85hm2pt3" | ||
@@ -30,3 +30,3 @@ console.log(BigInt(x.toHex())); // as a 64-bit unsigned integer | ||
// generate a textual representation directly | ||
console.log(scru64String()); // e.g. "0u2r85hm2pt4" | ||
console.log(scru64StringSync()); // e.g. "0u2r85hm2pt4" | ||
``` | ||
@@ -50,1 +50,2 @@ | ||
- [API Documentation](https://scru64.github.io/javascript/docs/) | ||
- [Run tests on your browser](https://scru64.github.io/javascript/test/) |
44527
775
49