Socket
Socket
Sign inDemoInstall

scru64

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

scru64 - npm Package Compare versions

Comparing version 0.2.1 to 0.3.0-beta.1

223

dist/index.d.ts

@@ -26,10 +26,4 @@ /**

*/
static ofInner(bytes: Uint8Array): Scru64Id;
static ofInner(bytes: Readonly<Uint8Array>): Scru64Id;
/**
* Returns the 12-digit canonical string representation.
*
* @category Conversion
*/
toString(): string;
/**
* Creates an object from a 12-digit string representation.

@@ -50,2 +44,16 @@ *

private static fromDigitValues;
/**
* Returns the 12-digit canonical string representation.
*
* @category Conversion
*/
toString(): string;
/**
* Creates a value from the `timestamp` and the combined `nodeCtr` field
* value.
*
* @throws RangeError if any argument is out of the valid value range.
* @category Conversion
*/
static fromParts(timestamp: number, nodeCtr: number): Scru64Id;
/** Returns the `timestamp` field value. */

@@ -59,16 +67,14 @@ get timestamp(): number;

/**
* Creates a value from the `timestamp` and the combined `nodeCtr` field
* value.
* Creates an object from a 64-bit unsigned integer.
*
* @throws RangeError if any argument is out of the valid value range.
* @throws RangeError if the argument is out of the valid value range.
* @category Conversion
*/
static fromParts(timestamp: number, nodeCtr: number): Scru64Id;
static fromBigInt(value: bigint): Scru64Id;
/**
* Returns the 64-bit unsigned integer representation as a 16-digit
* hexadecimal string prefixed with "0x".
* Returns the 64-bit unsigned integer representation.
*
* @category Conversion
*/
toHex(): string;
toBigInt(): bigint;
/** Represents `this` in JSON as a 12-digit canonical string. */

@@ -108,9 +114,9 @@ toJSON(): string;

* 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.
* provided is significantly (by default, approx. 10 seconds) 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.
*/

@@ -120,33 +126,29 @@ export declare class Scru64Generator {

private prevNodeCtr;
private counterSize;
private readonly counterSize;
private readonly counterMode;
/**
* Creates a generator with a node configuration.
* Creates a new generator with the given node configuration and counter mode.
*
* The `nodeId` must fit in `nodeIdSize` bits, where `nodeIdSize` ranges from
* 1 to 23, inclusive.
*
* @throws RangeError if the arguments represent an invalid node
* configuration.
* @throws `SyntaxError` if an invalid string `nodeSpec` is passed or
* `RangeError` if an invalid object `nodeSpec` is passed.
*/
constructor(nodeId: number, nodeIdSize: number);
constructor(nodeSpec: NodeSpec, counterMode?: CounterMode);
/** Returns the `nodeId` of the generator. */
getNodeId(): number;
/**
* Creates a generator by parsing a node spec string that describes the node
* configuration.
*
* A node spec string consists of `nodeId` and `nodeIdSize` separated by a
* slash (e.g., `"42/8"`, `"12345/16"`).
*
* @throws Error if the node spec does not conform to the valid syntax or
* represents an invalid node configuration.
* Returns the `nodePrev` value if the generator is constructed with one or
* `undefined` otherwise.
*/
static parse(nodeSpec: string): Scru64Generator;
/** Returns the `nodeId` of the generator. */
getNodeId(): number;
getNodePrev(): Scru64Id | undefined;
/** Returns the size in bits of the `nodeId` adopted by the generator. */
getNodeIdSize(): number;
/**
* Returns the node configuration specifier describing the generator state.
*/
getNodeSpec(): string;
/**
* Calculates the combined `nodeCtr` field value for the next `timestamp`
* tick.
*/
private initNodeCtr;
private renewNodeCtr;
/**

@@ -209,7 +211,104 @@ * Generates a new SCRU64 ID object from the current `timestamp`, or returns

/**
* Represents a node configuration specifier used to build a
* {@link Scru64Generator}.
*
* A `NodeSpec` is usually expressed as a node spec string, which starts with a
* decimal `nodeId`, a hexadecimal `nodeId` prefixed with `"0x"`, or a 12-digit
* `nodePrev` SCRU64 ID value, followed by a slash and a decimal `nodeIdSize`
* value ranging from 1 to 23 (e.g., `"42/8"`, `"0xb00/12"`, `"0u2r85hm2pt3/16"`).
* The first and second forms create a fresh new generator with the given
* `nodeId`, while the third form constructs one that generates subsequent
* SCRU64 IDs to the `nodePrev`.
*/
export type NodeSpec = string | {
nodeId: number;
nodeIdSize: number;
} | {
nodePrev: Scru64Id;
nodeIdSize: number;
};
/**
* An interface of objects to customize the initial counter value for each new
* `timestamp`.
*
* {@link Scru64Generator} calls `renew()` to obtain the initial counter value
* when the `timestamp` field has changed since the immediately preceding ID.
* Types implementing this interface may apply their respective logic to
* calculate the initial counter value.
*/
export type CounterMode = {
/**
* Returns the next initial counter value of `counterSize` bits.
*
* {@link Scru64Generator} passes the `counterSize` (from 1 to 23) and other
* context information that may be useful for counter renewal. The returned
* value must be within the range of `counterSize`-bit unsigned integer.
*/
renew(counterSize: number, context: {
timestamp: number;
nodeId: number;
}): number;
};
/**
* The default "initialize a portion counter" strategy.
*
* With this strategy, the counter is reset to a random number for each new
* `timestamp` tick, but some specified leading bits are set to zero to reserve
* space as the counter overflow guard.
*
* Note that the random number generator employed is not cryptographically
* strong. This mode does not pay for security because a small random number is
* insecure anyway.
*/
export declare class DefaultCounterMode {
private readonly overflowGuardSize;
/** Creates a new instance with the size (in bits) of overflow guard bits. */
constructor(overflowGuardSize: number);
/** Returns the next initial counter value of `counterSize` bits. */
renew(counterSize: number, context: {}): number;
}
/**
* The gateway object that forwards supported method calls to the process-wide
* global generator.
*/
export declare class GlobalGenerator {
private constructor();
/**
* Initializes the global generator, if not initialized, with the node spec
* passed.
*
* This method tries to configure the global generator with the argument only
* when the global generator is not yet initialized. Otherwise, it preserves
* the existing configuration.
*
* @throws `SyntaxError` or `RangeError` according to the semantics of
* {@link Scru64Generator.constructor | new Scru64Generator(nodeSpec)} if the
* argument represents an invalid node spec.
* @returns `true` if this method configures the global generator or `false`
* if it preserves the existing configuration.
*/
static initialize(nodeSpec: NodeSpec): boolean;
/** Calls {@link Scru64Generator.generate} of the global generator. */
static generate(): Scru64Id | undefined;
/** Calls {@link Scru64Generator.generateOrSleep} of the global generator. */
static generateOrSleep(): Scru64Id;
/** Calls {@link Scru64Generator.generateOrAwait} of the global generator. */
static generateOrAwait(): Promise<Scru64Id>;
/** Calls {@link Scru64Generator.getNodeId} of the global generator. */
static getNodeId(): number;
/** Calls {@link Scru64Generator.getNodePrev} of the global generator. */
static getNodePrev(): Scru64Id | undefined;
/** Calls {@link Scru64Generator.getNodeIdSize} of the global generator. */
static getNodeIdSize(): number;
/** Calls {@link Scru64Generator.getNodeSpec} of the global generator. */
static getNodeSpec(): 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"`).
* The {@link GlobalGenerator} reads the node configuration from the
* `SCRU64_NODE_SPEC` global variable by default, and it throws an error if it
* fails to read a well-formed node spec string (e.g., `"42/8"`, `"0xb00/12"`,
* `"0u2r85hm2pt3/16"`) when a generator method is first called. See also
* {@link NodeSpec} for the node spec string format.
*

@@ -220,4 +319,3 @@ * This function usually returns a value immediately, but if not possible, it

*
* @throws Error if the global generator is not properly configured through the
* global variable.
* @throws Error if the global generator is not properly configured.
*/

@@ -229,5 +327,7 @@ export declare const scru64Sync: () => Scru64Id;

*
* 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"`).
* The {@link GlobalGenerator} reads the node configuration from the
* `SCRU64_NODE_SPEC` global variable by default, and it throws an error if it
* fails to read a well-formed node spec string (e.g., `"42/8"`, `"0xb00/12"`,
* `"0u2r85hm2pt3/16"`) when a generator method is first called. See also
* {@link NodeSpec} for the node spec string format.
*

@@ -238,4 +338,3 @@ * This function usually returns a value immediately, but if not possible, it

*
* @throws Error if the global generator is not properly configured through the
* global variable.
* @throws Error if the global generator is not properly configured.
*/

@@ -246,5 +345,7 @@ export declare const scru64StringSync: () => 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"`).
* The {@link GlobalGenerator} reads the node configuration from the
* `SCRU64_NODE_SPEC` global variable by default, and it throws an error if it
* fails to read a well-formed node spec string (e.g., `"42/8"`, `"0xb00/12"`,
* `"0u2r85hm2pt3/16"`) when a generator method is first called. See also
* {@link NodeSpec} for the node spec string format.
*

@@ -254,4 +355,3 @@ * This function usually returns a value immediately, but if not possible, it

*
* @throws Error if the global generator is not properly configured through the
* global variable.
* @throws Error if the global generator is not properly configured.
*/

@@ -263,5 +363,7 @@ export declare const scru64: () => Promise<Scru64Id>;

*
* 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"`).
* The {@link GlobalGenerator} reads the node configuration from the
* `SCRU64_NODE_SPEC` global variable by default, and it throws an error if it
* fails to read a well-formed node spec string (e.g., `"42/8"`, `"0xb00/12"`,
* `"0u2r85hm2pt3/16"`) when a generator method is first called. See also
* {@link NodeSpec} for the node spec string format.
*

@@ -271,5 +373,4 @@ * This function usually returns a value immediately, but if not possible, it

*
* @throws Error if the global generator is not properly configured through the
* global variable.
* @throws Error if the global generator is not properly configured.
*/
export declare const scru64String: () => Promise<string>;

@@ -61,31 +61,2 @@ /**

/**
* Returns the 12-digit canonical string representation.
*
* @category Conversion
*/
toString() {
const dst = new Uint8Array(12);
let minIndex = 99; // any number greater than size of output array
for (let i = -2; i < 8; i += 5) {
// implement Base36 using 40-bit words
let carry = this.subUint(i < 0 ? 0 : i, i + 5);
// iterate over output array from right to left while carry != 0 but at
// least up to place already filled
let j = dst.length - 1;
for (; carry > 0 || j > minIndex; j--) {
console.assert(j >= 0);
carry += dst[j] * 1099511627776;
const quo = Math.trunc(carry / 36);
dst[j] = carry - quo * 36; // remainder
carry = quo;
}
minIndex = j;
}
let text = "";
for (const d of dst) {
text += DIGITS.charAt(d);
}
return text;
}
/**
* Creates an object from a 12-digit string representation.

@@ -145,12 +116,30 @@ *

}
/** Returns the `timestamp` field value. */
get timestamp() {
return this.subUint(0, 5);
}
/**
* Returns the `nodeId` and `counter` field values combined as a single
* integer.
* Returns the 12-digit canonical string representation.
*
* @category Conversion
*/
get nodeCtr() {
return this.subUint(5, 8);
toString() {
const dst = new Uint8Array(12);
let minIndex = 99; // any number greater than size of output array
for (let i = -2; i < 8; i += 5) {
// implement Base36 using 40-bit words
let carry = this.subUint(i < 0 ? 0 : i, i + 5);
// iterate over output array from right to left while carry != 0 but at
// least up to place already filled
let j = dst.length - 1;
for (; carry > 0 || j > minIndex; j--) {
console.assert(j >= 0);
carry += dst[j] * 1099511627776;
const quo = Math.trunc(carry / 36);
dst[j] = carry - quo * 36; // remainder
carry = quo;
}
minIndex = j;
}
let text = "";
for (const d of dst) {
text += DIGITS.charAt(d);
}
return text;
}

@@ -184,19 +173,43 @@ /**

bytes[7] = nodeCtr;
return new Scru64Id(bytes);
// upper bound check is necessary when `timestamp` is at max
return timestamp === MAX_TIMESTAMP
? Scru64Id.ofInner(bytes)
: new Scru64Id(bytes);
}
/** Returns the `timestamp` field value. */
get timestamp() {
return this.subUint(0, 5);
}
/**
* Returns the 64-bit unsigned integer representation as a 16-digit
* hexadecimal string prefixed with "0x".
* Returns the `nodeId` and `counter` field values combined as a single
* integer.
*/
get nodeCtr() {
return this.subUint(5, 8);
}
/**
* Creates an object from a 64-bit unsigned integer.
*
* @throws RangeError if the argument is out of the valid value range.
* @category Conversion
*/
toHex() {
const digits = "0123456789abcdef";
let text = "0x";
for (const e of this.bytes) {
text += digits.charAt(e >>> 4);
text += digits.charAt(e & 0xf);
static fromBigInt(value) {
if (value < 0 || value >> BigInt(64) > 0) {
throw new RangeError("out of 64-bit value range");
}
return text;
const bytes = new Uint8Array(8);
for (let i = 7; i >= 0; i--) {
bytes[i] = Number(value & BigInt(0xff));
value >>= BigInt(8);
}
return Scru64Id.ofInner(bytes);
}
/**
* Returns the 64-bit unsigned integer representation.
*
* @category Conversion
*/
toBigInt() {
return this.bytes.reduce((acc, curr) => (acc << BigInt(8)) | BigInt(curr), BigInt(0));
}
/** Represents `this` in JSON as a 12-digit canonical string. */

@@ -256,51 +269,70 @@ toJSON() {

* 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.
* provided is significantly (by default, approx. 10 seconds) 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.
*/
export class Scru64Generator {
/**
* Creates a generator with a node configuration.
* Creates a new generator with the given node configuration and counter mode.
*
* The `nodeId` must fit in `nodeIdSize` bits, where `nodeIdSize` ranges from
* 1 to 23, inclusive.
*
* @throws RangeError if the arguments represent an invalid node
* configuration.
* @throws `SyntaxError` if an invalid string `nodeSpec` is passed or
* `RangeError` if an invalid object `nodeSpec` is passed.
*/
constructor(nodeId, nodeIdSize) {
if (nodeIdSize <= 0 ||
constructor(nodeSpec, counterMode) {
let errType = RangeError;
if (typeof nodeSpec === "string") {
// convert string `nodeSpec` to object
errType = SyntaxError;
const m = nodeSpec.match(/^(?:([0-9a-z]{12})|([0-9]{1,8}|0x[0-9a-f]{1,6}))\/([0-9]{1,3})$/i);
if (m === null) {
throw new errType('could not parse string as node spec (expected: e.g., "42/8", "0xb00/12", "0u2r85hm2pt3/16")');
}
else if (typeof m[1] === "string") {
nodeSpec = {
nodePrev: Scru64Id.fromString(m[1]),
nodeIdSize: parseInt(m[3], 10),
};
}
else if (typeof m[2] === "string") {
nodeSpec = {
nodeId: parseInt(m[2]),
nodeIdSize: parseInt(m[3], 10),
};
}
else {
throw new Error("unreachable");
}
}
// process object `nodeSpec`
const nodeIdSize = nodeSpec.nodeIdSize;
if (nodeIdSize < 1 ||
nodeIdSize >= NODE_CTR_SIZE ||
!Number.isInteger(nodeIdSize)) {
throw new RangeError("`nodeIdSize` must range from 1 to 23");
throw new errType(`\`nodeIdSize\` (${nodeIdSize}) must range from 1 to 23`);
}
else if (nodeId < 0 ||
nodeId >= 1 << nodeIdSize ||
!Number.isInteger(nodeId)) {
throw new RangeError("`nodeId` must fit in `nodeIdSize` bits");
}
this.counterSize = NODE_CTR_SIZE - nodeIdSize;
this.prevTimestamp = 0;
this.prevNodeCtr = nodeId << this.counterSize;
}
/**
* Creates a generator by parsing a node spec string that describes the node
* configuration.
*
* A node spec string consists of `nodeId` and `nodeIdSize` separated by a
* slash (e.g., `"42/8"`, `"12345/16"`).
*
* @throws Error if the node spec does not conform to the valid syntax or
* represents an invalid node configuration.
*/
static parse(nodeSpec) {
const m = nodeSpec.match(/^([0-9]{1,10})\/([0-9]{1,3})$/);
if (m === null) {
throw new SyntaxError("invalid `nodeSpec`; it looks like: `42/8`, `12345/16`");
if ("nodePrev" in nodeSpec && typeof nodeSpec.nodePrev === "object") {
this.prevTimestamp = nodeSpec.nodePrev.timestamp;
this.prevNodeCtr = nodeSpec.nodePrev.nodeCtr;
}
return new Scru64Generator(parseInt(m[1], 10), parseInt(m[2], 10));
else if ("nodeId" in nodeSpec && typeof nodeSpec.nodeId === "number") {
this.prevTimestamp = 0;
const nodeId = nodeSpec.nodeId;
if (nodeId < 0 ||
nodeId >= 1 << nodeIdSize ||
!Number.isInteger(nodeId)) {
throw new errType(`\`nodeId\` (${nodeId}) must fit in \`nodeIdSize\` (${nodeIdSize}) bits`);
}
this.prevNodeCtr = nodeId << this.counterSize;
}
else {
throw new errType("invalid `nodeSpec` argument");
}
// reserve one overflow guard bit if `counterSize` is four or less
this.counterMode =
counterMode !== null && counterMode !== void 0 ? counterMode : new DefaultCounterMode(this.counterSize <= 4 ? 1 : 0);
}

@@ -311,2 +343,14 @@ /** Returns the `nodeId` of the generator. */

}
/**
* Returns the `nodePrev` value if the generator is constructed with one or
* `undefined` otherwise.
*/
getNodePrev() {
if (this.prevTimestamp > 0) {
return Scru64Id.fromParts(this.prevTimestamp, this.prevNodeCtr);
}
else {
return undefined;
}
}
/** Returns the size in bits of the `nodeId` adopted by the generator. */

@@ -317,11 +361,22 @@ getNodeIdSize() {

/**
* Returns the node configuration specifier describing the generator state.
*/
getNodeSpec() {
const nodePrev = this.getNodePrev();
return nodePrev !== undefined
? `${nodePrev.toString()}/${this.getNodeIdSize()}`
: `${this.getNodeId()}/${this.getNodeIdSize()}`;
}
/**
* Calculates the combined `nodeCtr` field value for the next `timestamp`
* tick.
*/
initNodeCtr() {
// initialize counter at `counter_size - 1`-bit random number
const OVERFLOW_GUARD_SIZE = 1;
const limit = 1 << (this.counterSize - OVERFLOW_GUARD_SIZE);
const counter = Math.trunc(Math.random() * limit);
return (this.getNodeId() << this.counterSize) | counter;
renewNodeCtr(timestamp) {
const nodeId = this.getNodeId();
const context = { timestamp, nodeId };
const counter = this.counterMode.renew(this.counterSize, context);
if (counter >= 1 << this.counterSize) {
throw new Error("illegal `CounterMode` implementation");
}
return (nodeId << this.counterSize) | counter;
}

@@ -403,3 +458,3 @@ /**

this.prevTimestamp = Math.trunc(unixTsMs / 0x100);
this.prevNodeCtr = this.initNodeCtr();
this.prevNodeCtr = this.renewNodeCtr(this.prevTimestamp);
return Scru64Id.fromParts(this.prevTimestamp, this.prevNodeCtr);

@@ -430,5 +485,5 @@ }

this.prevTimestamp = timestamp;
this.prevNodeCtr = this.initNodeCtr();
this.prevNodeCtr = this.renewNodeCtr(this.prevTimestamp);
}
else if (timestamp + allowance > this.prevTimestamp) {
else if (timestamp + allowance >= this.prevTimestamp) {
// go on with previous timestamp if new one is not much smaller

@@ -442,3 +497,3 @@ const counterMask = (1 << this.counterSize) - 1;

this.prevTimestamp++;
this.prevNodeCtr = this.initNodeCtr();
this.prevNodeCtr = this.renewNodeCtr(this.prevTimestamp);
}

@@ -453,18 +508,103 @@ }

}
let globalGenerator = undefined;
/**
* The default "initialize a portion counter" strategy.
*
* With this strategy, the counter is reset to a random number for each new
* `timestamp` tick, but some specified leading bits are set to zero to reserve
* space as the counter overflow guard.
*
* Note that the random number generator employed is not cryptographically
* strong. This mode does not pay for security because a small random number is
* insecure anyway.
*/
export class DefaultCounterMode {
/** Creates a new instance with the size (in bits) of overflow guard bits. */
constructor(overflowGuardSize) {
this.overflowGuardSize = overflowGuardSize;
if (overflowGuardSize < 0 || !Number.isInteger(overflowGuardSize)) {
throw new RangeError("`overflowGuardSize` must be an unsigned integer");
}
}
/** Returns the next initial counter value of `counterSize` bits. */
renew(counterSize, context) {
const k = Math.max(0, counterSize - this.overflowGuardSize);
return Math.trunc(Math.random() * (1 << k));
}
}
let globalGen = undefined;
const getGlobalGenerator = () => {
if (globalGenerator === undefined) {
if (globalGen === undefined) {
if (typeof SCRU64_NODE_SPEC === "undefined") {
throw new Error("scru64: could not read config from SCRU64_NODE_SPEC global var");
}
globalGenerator = Scru64Generator.parse(SCRU64_NODE_SPEC);
globalGen = new Scru64Generator(SCRU64_NODE_SPEC);
}
return globalGenerator;
return globalGen;
};
/**
* The gateway object that forwards supported method calls to the process-wide
* global generator.
*/
export class GlobalGenerator {
constructor() { }
/**
* Initializes the global generator, if not initialized, with the node spec
* passed.
*
* This method tries to configure the global generator with the argument only
* when the global generator is not yet initialized. Otherwise, it preserves
* the existing configuration.
*
* @throws `SyntaxError` or `RangeError` according to the semantics of
* {@link Scru64Generator.constructor | new Scru64Generator(nodeSpec)} if the
* argument represents an invalid node spec.
* @returns `true` if this method configures the global generator or `false`
* if it preserves the existing configuration.
*/
static initialize(nodeSpec) {
if (globalGen === undefined) {
globalGen = new Scru64Generator(nodeSpec);
return true;
}
else {
return false;
}
}
/** Calls {@link Scru64Generator.generate} of the global generator. */
static generate() {
return getGlobalGenerator().generate();
}
/** Calls {@link Scru64Generator.generateOrSleep} of the global generator. */
static generateOrSleep() {
return getGlobalGenerator().generateOrSleep();
}
/** Calls {@link Scru64Generator.generateOrAwait} of the global generator. */
static async generateOrAwait() {
return getGlobalGenerator().generateOrAwait();
}
/** Calls {@link Scru64Generator.getNodeId} of the global generator. */
static getNodeId() {
return getGlobalGenerator().getNodeId();
}
/** Calls {@link Scru64Generator.getNodePrev} of the global generator. */
static getNodePrev() {
return getGlobalGenerator().getNodePrev();
}
/** Calls {@link Scru64Generator.getNodeIdSize} of the global generator. */
static getNodeIdSize() {
return getGlobalGenerator().getNodeIdSize();
}
/** Calls {@link Scru64Generator.getNodeSpec} of the global generator. */
static getNodeSpec() {
return getGlobalGenerator().getNodeSpec();
}
}
/**
* 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"`).
* The {@link GlobalGenerator} reads the node configuration from the
* `SCRU64_NODE_SPEC` global variable by default, and it throws an error if it
* fails to read a well-formed node spec string (e.g., `"42/8"`, `"0xb00/12"`,
* `"0u2r85hm2pt3/16"`) when a generator method is first called. See also
* {@link NodeSpec} for the node spec string format.
*

@@ -475,6 +615,5 @@ * This function usually returns a value immediately, but if not possible, it

*
* @throws Error if the global generator is not properly configured through the
* global variable.
* @throws Error if the global generator is not properly configured.
*/
export const scru64Sync = () => getGlobalGenerator().generateOrSleep();
export const scru64Sync = () => GlobalGenerator.generateOrSleep();
/**

@@ -484,5 +623,7 @@ * 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"`).
* The {@link GlobalGenerator} reads the node configuration from the
* `SCRU64_NODE_SPEC` global variable by default, and it throws an error if it
* fails to read a well-formed node spec string (e.g., `"42/8"`, `"0xb00/12"`,
* `"0u2r85hm2pt3/16"`) when a generator method is first called. See also
* {@link NodeSpec} for the node spec string format.
*

@@ -493,4 +634,3 @@ * This function usually returns a value immediately, but if not possible, it

*
* @throws Error if the global generator is not properly configured through the
* global variable.
* @throws Error if the global generator is not properly configured.
*/

@@ -501,5 +641,7 @@ export const scru64StringSync = () => scru64Sync().toString();

*
* 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"`).
* The {@link GlobalGenerator} reads the node configuration from the
* `SCRU64_NODE_SPEC` global variable by default, and it throws an error if it
* fails to read a well-formed node spec string (e.g., `"42/8"`, `"0xb00/12"`,
* `"0u2r85hm2pt3/16"`) when a generator method is first called. See also
* {@link NodeSpec} for the node spec string format.
*

@@ -509,6 +651,5 @@ * This function usually returns a value immediately, but if not possible, it

*
* @throws Error if the global generator is not properly configured through the
* global variable.
* @throws Error if the global generator is not properly configured.
*/
export const scru64 = async () => getGlobalGenerator().generateOrAwait();
export const scru64 = async () => GlobalGenerator.generateOrAwait();
/**

@@ -518,5 +659,7 @@ * 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"`).
* The {@link GlobalGenerator} reads the node configuration from the
* `SCRU64_NODE_SPEC` global variable by default, and it throws an error if it
* fails to read a well-formed node spec string (e.g., `"42/8"`, `"0xb00/12"`,
* `"0u2r85hm2pt3/16"`) when a generator method is first called. See also
* {@link NodeSpec} for the node spec string format.
*

@@ -526,5 +669,4 @@ * This function usually returns a value immediately, but if not possible, it

*
* @throws Error if the global generator is not properly configured through the
* global variable.
* @throws Error if the global generator is not properly configured.
*/
export const scru64String = async () => (await scru64()).toString();
{
"name": "scru64",
"version": "0.2.1",
"version": "0.3.0-beta.1",
"description": "SCRU64: Sortable, Clock-based, Realm-specifically Unique identifier",

@@ -33,5 +33,5 @@ "type": "module",

"mocha": "^10.2.0",
"typedoc": "^0.23.28",
"typescript": "^5.0.2"
"typedoc": "^0.24.8",
"typescript": "^5.1.6"
}
}

@@ -21,11 +21,11 @@ # SCRU64: Sortable, Clock-based, Realm-specifically Unique identifier

// or on browsers:
// import { scru64Sync, scru64StringSync } from "https://unpkg.com/scru64@^0.2";
// import { scru64Sync, scru64StringSync } from "https://unpkg.com/scru64@^0.3";
// generate a new identifier object
const x = scru64Sync();
console.log(String(x)); // e.g. "0u2r85hm2pt3"
console.log(BigInt(x.toHex())); // as a 64-bit unsigned integer
console.log(String(x)); // e.g., "0u2r85hm2pt3"
console.log(x.toBigInt()); // as a 64-bit unsigned integer
// generate a textual representation directly
console.log(scru64StringSync()); // e.g. "0u2r85hm2pt4"
console.log(scru64StringSync()); // e.g., "0u2r85hm2pt4"
```

@@ -32,0 +32,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc