New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

scru128

Package Overview
Dependencies
Maintainers
1
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

scru128 - npm Package Compare versions

Comparing version 2.3.1 to 2.3.2

17

CHANGELOG.md
# Changelog
## v2.3.2 - 2023-03-19
### Added
- `generateNoRewind()` and `generateCoreNoRewind()` to `Scru128Generator`
(experimental)
### Changed
- Precedence of PRNG selection in Node.js: Web Crypto first if available
- node:crypto > Web Crypto > Math.random -> Web > node > Math
### Maintenance
- Improved documentation about generator method flavors
- Updated dev dependencies
## v2.3.1 - 2023-02-18

@@ -4,0 +21,0 @@

83

dist/index.d.ts

@@ -37,3 +37,3 @@ /**

/**
* 16-byte byte array containing the 128-bit unsigned integer representation
* A 16-byte byte array containing the 128-bit unsigned integer representation
* in the big-endian (network) byte order.

@@ -58,6 +58,6 @@ */

*
* @param timestamp - 48-bit `timestamp` field value.
* @param counterHi - 24-bit `counter_hi` field value.
* @param counterLo - 24-bit `counter_lo` field value.
* @param entropy - 32-bit `entropy` field value.
* @param timestamp - A 48-bit `timestamp` field value.
* @param counterHi - A 24-bit `counter_hi` field value.
* @param counterLo - A 24-bit `counter_lo` field value.
* @param entropy - A 32-bit `entropy` field value.
* @throws RangeError if any argument is out of the value range of the field.

@@ -118,4 +118,4 @@ * @category Conversion

*
* @param value - 16-byte buffer that represents a 128-bit unsigned integer in
* the big-endian (network) byte order.
* @param value - A 16-byte buffer that represents a 128-bit unsigned integer
* in the big-endian (network) byte order.
* @throws TypeError if the byte length of the argument is not 16.

@@ -180,2 +180,20 @@ * @category Conversion

* ```
*
* @remarks
* The generator offers four different methods to generate a SCRU128 ID:
*
* | Flavor | Timestamp | On big clock rewind |
* | ---------------------------- | --------- | ------------------- |
* | {@link generate} | Now | Rewinds state |
* | {@link generateNoRewind} | Now | Returns `undefined` |
* | {@link generateCore} | Argument | Rewinds state |
* | {@link generateCoreNoRewind} | Argument | Returns `undefined` |
*
* Each method returns monotonically increasing IDs unless a `timestamp`
* provided is significantly (by ten seconds or more by default) smaller than
* the one embedded in the immediately preceding ID. If such a significant clock
* rollback is detected, the `generate` method rewinds the generator state and
* returns a new ID based on the current `timestamp`, whereas the experimental
* `NoRewind` variants keep the state untouched and return `undefined`. `Core`
* functions offer low-level primitives.
*/

@@ -186,7 +204,7 @@ export declare class Scru128Generator {

private counterLo;
/** Timestamp at the last renewal of `counter_hi` field. */
/** The timestamp at the last renewal of `counter_hi` field. */
private tsCounterHi;
/** Status code reported at the last generation. */
/** The status code reported at the last generation. */
private lastStatus;
/** Random number generator used by the generator. */
/** The random number generator used by the generator. */
private rng;

@@ -202,11 +220,40 @@ /**

});
/** Generates a new SCRU128 ID object. */
/**
* Generates a new SCRU128 ID object from the current `timestamp`.
*
* See the {@link Scru128Generator} class documentation for the description.
*/
generate(): Scru128Id;
/**
* Generates a new SCRU128 ID object with the `timestamp` passed.
* Generates a new SCRU128 ID object from the current `timestamp`,
* guaranteeing the monotonic order of generated IDs despite a significant
* timestamp rollback.
*
* @throws RangeError if the argument is not a 48-bit positive integer.
* See the {@link Scru128Generator} class documentation for the description.
*
* @experimental
*/
generateNoRewind(): Scru128Id | undefined;
/**
* Generates a new SCRU128 ID object from the `timestamp` passed.
*
* See the {@link Scru128Generator} class documentation for the description.
*
* @throws RangeError if `timestamp` is not a 48-bit positive integer.
*/
generateCore(timestamp: number): Scru128Id;
/**
* Generates a new SCRU128 ID object from the `timestamp` passed, guaranteeing
* the monotonic order of generated IDs despite a significant timestamp
* rollback.
*
* See the {@link Scru128Generator} class documentation for the description.
*
* @param rollbackAllowance - The amount of `timestamp` rollback that is
* considered significant. A suggested value is `10_000` (milliseconds).
* @throws RangeError if `timestamp` is not a 48-bit positive integer.
* @experimental
*/
generateCoreNoRewind(timestamp: number, rollbackAllowance: number): Scru128Id | undefined;
/**
* Returns a status code that indicates the internal state involved in the

@@ -261,4 +308,4 @@ * last generation of ID.

*
* This method wraps the result of {@link generate | generate()} in an
* [`IteratorResult`] object to use `this` as an infinite iterator.
* This method wraps the result of {@link generate} in an [`IteratorResult`]
* object to use `this` as an infinite iterator.
*

@@ -269,10 +316,10 @@ * [`IteratorResult`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Iteration_protocols

}
/** Generates a new SCRU128 ID object. */
/** Generates a new SCRU128 ID object using the global generator. */
export declare const scru128: () => Scru128Id;
/**
* Generates a new SCRU128 ID encoded in a string.
* Generates a new SCRU128 ID encoded in a string using the global generator.
*
* Use this function to quickly get a new SCRU128 ID as a string.
*
* @returns 25-digit canonical string representation.
* @returns The 25-digit canonical string representation.
* @example

@@ -279,0 +326,0 @@ * ```javascript

@@ -21,11 +21,11 @@ /**

*/
/** Maximum value of 48-bit `timestamp` field. */
/** The maximum value of 48-bit `timestamp` field. */
const MAX_TIMESTAMP = 281474976710655;
/** Maximum value of 24-bit `counter_hi` field. */
/** The maximum value of 24-bit `counter_hi` field. */
const MAX_COUNTER_HI = 16777215;
/** Maximum value of 24-bit `counter_lo` field. */
/** The maximum value of 24-bit `counter_lo` field. */
const MAX_COUNTER_LO = 16777215;
/** 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 = [

@@ -43,2 +43,4 @@ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,

];
/** The default timestamp rollback allowance. */
const DEFAULT_ROLLBACK_ALLOWANCE = 10000; // 10 seconds
/**

@@ -82,6 +84,6 @@ * Represents a SCRU128 ID and provides converters and comparison operators.

*
* @param timestamp - 48-bit `timestamp` field value.
* @param counterHi - 24-bit `counter_hi` field value.
* @param counterLo - 24-bit `counter_lo` field value.
* @param entropy - 32-bit `entropy` field value.
* @param timestamp - A 48-bit `timestamp` field value.
* @param counterHi - A 24-bit `counter_hi` field value.
* @param counterLo - A 24-bit `counter_lo` field value.
* @param entropy - A 32-bit `entropy` field value.
* @throws RangeError if any argument is out of the value range of the field.

@@ -221,3 +223,3 @@ * @category Conversion

let text = "";
for (let d of dst) {
for (const d of dst) {
text += DIGITS.charAt(d);

@@ -261,4 +263,4 @@ }

*
* @param value - 16-byte buffer that represents a 128-bit unsigned integer in
* the big-endian (network) byte order.
* @param value - A 16-byte buffer that represents a 128-bit unsigned integer
* in the big-endian (network) byte order.
* @throws TypeError if the byte length of the argument is not 16.

@@ -314,3 +316,3 @@ * @category Conversion

let text = "0x";
for (let e of this.bytes) {
for (const e of this.bytes) {
text += digits.charAt(e >>> 4);

@@ -373,2 +375,20 @@ text += digits.charAt(e & 0xf);

* ```
*
* @remarks
* The generator offers four different methods to generate a SCRU128 ID:
*
* | Flavor | Timestamp | On big clock rewind |
* | ---------------------------- | --------- | ------------------- |
* | {@link generate} | Now | Rewinds state |
* | {@link generateNoRewind} | Now | Returns `undefined` |
* | {@link generateCore} | Argument | Rewinds state |
* | {@link generateCoreNoRewind} | Argument | Returns `undefined` |
*
* Each method returns monotonically increasing IDs unless a `timestamp`
* provided is significantly (by ten seconds or more by default) smaller than
* the one embedded in the immediately preceding ID. If such a significant clock
* rollback is detected, the `generate` method rewinds the generator state and
* returns a new ID based on the current `timestamp`, whereas the experimental
* `NoRewind` variants keep the state untouched and return `undefined`. `Core`
* functions offer low-level primitives.
*/

@@ -385,9 +405,13 @@ export class Scru128Generator {

this.counterLo = 0;
/** Timestamp at the last renewal of `counter_hi` field. */
/** The timestamp at the last renewal of `counter_hi` field. */
this.tsCounterHi = 0;
/** Status code reported at the last generation. */
/** The status code reported at the last generation. */
this.lastStatus = "NOT_EXECUTED";
this.rng = randomNumberGenerator || new DefaultRandom();
}
/** Generates a new SCRU128 ID object. */
/**
* Generates a new SCRU128 ID object from the current `timestamp`.
*
* See the {@link Scru128Generator} class documentation for the description.
*/
generate() {

@@ -397,7 +421,45 @@ return this.generateCore(Date.now());

/**
* Generates a new SCRU128 ID object with the `timestamp` passed.
* Generates a new SCRU128 ID object from the current `timestamp`,
* guaranteeing the monotonic order of generated IDs despite a significant
* timestamp rollback.
*
* @throws RangeError if the argument is not a 48-bit positive integer.
* See the {@link Scru128Generator} class documentation for the description.
*
* @experimental
*/
generateNoRewind() {
return this.generateCoreNoRewind(Date.now(), DEFAULT_ROLLBACK_ALLOWANCE);
}
/**
* Generates a new SCRU128 ID object from the `timestamp` passed.
*
* See the {@link Scru128Generator} class documentation for the description.
*
* @throws RangeError if `timestamp` is not a 48-bit positive integer.
*/
generateCore(timestamp) {
const rollbackAllowance = DEFAULT_ROLLBACK_ALLOWANCE;
let value = this.generateCoreNoRewind(timestamp, rollbackAllowance);
if (value === undefined) {
// reset state and resume
this.timestamp = 0;
this.tsCounterHi = 0;
value = this.generateCoreNoRewind(timestamp, rollbackAllowance);
this.lastStatus = "CLOCK_ROLLBACK";
}
return value;
}
/**
* Generates a new SCRU128 ID object from the `timestamp` passed, guaranteeing
* the monotonic order of generated IDs despite a significant timestamp
* rollback.
*
* See the {@link Scru128Generator} class documentation for the description.
*
* @param rollbackAllowance - The amount of `timestamp` rollback that is
* considered significant. A suggested value is `10_000` (milliseconds).
* @throws RangeError if `timestamp` is not a 48-bit positive integer.
* @experimental
*/
generateCoreNoRewind(timestamp, rollbackAllowance) {
if (!Number.isInteger(timestamp) ||

@@ -408,8 +470,12 @@ timestamp < 1 ||

}
this.lastStatus = "NEW_TIMESTAMP";
else if (rollbackAllowance < 0 || rollbackAllowance > MAX_TIMESTAMP) {
throw new RangeError("`rollbackAllowance` out of reasonable range");
}
if (timestamp > this.timestamp) {
this.timestamp = timestamp;
this.counterLo = this.rng.nextUint32() & MAX_COUNTER_LO;
this.lastStatus = "NEW_TIMESTAMP";
}
else if (timestamp + 10000 > this.timestamp) {
else if (timestamp + rollbackAllowance > this.timestamp) {
// go on with previous timestamp if new one is not much smaller
this.counterLo++;

@@ -431,7 +497,4 @@ this.lastStatus = "COUNTER_LO_INC";

else {
// reset state if clock moves back by ten seconds or more
this.tsCounterHi = 0;
this.timestamp = timestamp;
this.counterLo = this.rng.nextUint32() & MAX_COUNTER_LO;
this.lastStatus = "CLOCK_ROLLBACK";
// abort if clock moves back to unbearable extent
return undefined;
}

@@ -498,4 +561,4 @@ if (this.timestamp - this.tsCounterHi >= 1000 || this.tsCounterHi < 1) {

*
* This method wraps the result of {@link generate | generate()} in an
* [`IteratorResult`] object to use `this` as an infinite iterator.
* This method wraps the result of {@link generate} in an [`IteratorResult`]
* object to use `this` as an infinite iterator.
*

@@ -547,11 +610,11 @@ * [`IteratorResult`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Iteration_protocols

}
let defaultGenerator;
/** Generates a new SCRU128 ID object. */
export const scru128 = () => (defaultGenerator || (defaultGenerator = new Scru128Generator())).generate();
let globalGenerator;
/** Generates a new SCRU128 ID object using the global generator. */
export const scru128 = () => (globalGenerator || (globalGenerator = new Scru128Generator())).generate();
/**
* Generates a new SCRU128 ID encoded in a string.
* Generates a new SCRU128 ID encoded in a string using the global generator.
*
* Use this function to quickly get a new SCRU128 ID as a string.
*
* @returns 25-digit canonical string representation.
* @returns The 25-digit canonical string representation.
* @example

@@ -558,0 +621,0 @@ * ```javascript

export * from "./index.js";
import * as nodeCrypto from "crypto";
import { _setRandom } from "./index.js";
if (nodeCrypto && nodeCrypto.randomFillSync) {
_setRandom(nodeCrypto.randomFillSync);
if (typeof crypto === "undefined" || !crypto.getRandomValues) {
if (nodeCrypto && nodeCrypto.randomFillSync) {
_setRandom(nodeCrypto.randomFillSync);
}
}
{
"name": "scru128",
"version": "2.3.1",
"version": "2.3.2",
"description": "SCRU128: Sortable, Clock and Random number-based Unique identifier",

@@ -55,7 +55,7 @@ "type": "module",

"mocha": "^10.2.0",
"typedoc": "^0.23.25",
"typedoc": "^0.23.27",
"typescript": "^4.9.5",
"webpack": "^5.75.0",
"webpack": "^5.76.2",
"webpack-cli": "^5.0.1"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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