@thi.ng/ksuid
Advanced tools
Comparing version 0.3.0 to 0.4.0
@@ -6,2 +6,13 @@ # Change Log | ||
# [0.4.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/ksuid@0.3.0...@thi.ng/ksuid@0.4.0) (2021-08-07) | ||
### Features | ||
* **ksuid:** add ULID impl, update IKSUID & tests ([566846b](https://github.com/thi-ng/umbrella/commit/566846b7cfa735f15d07b25e4514fa3ee540adbf)) | ||
# [0.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/ksuid@0.2.6...@thi.ng/ksuid@0.3.0) (2021-08-07) | ||
@@ -8,0 +19,0 @@ |
@@ -5,2 +5,3 @@ export * from "./api"; | ||
export * from "./ksuid64"; | ||
export * from "./ulid"; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -5,1 +5,2 @@ export * from "./api"; | ||
export * from "./ksuid64"; | ||
export * from "./ulid"; |
@@ -105,6 +105,40 @@ 'use strict'; | ||
class ULID extends AKSUID { | ||
constructor(opts) { | ||
super(6, Object.assign({ epoch: 0, bytes: 10, base: baseN.BASE32_CROCKFORD }, opts)); | ||
} | ||
timeOnlyBinary(epoch = Date.now()) { | ||
const buf = new Uint8Array(this.size); | ||
const t = this.ensureTime(epoch - this.epoch); | ||
const h = (t / 4294967296) >>> 0; | ||
const l = (t & 4294967295) >>> 0; | ||
buf.set([ | ||
(h >> 8) & 0xff, | ||
h & 0xff, | ||
l >>> 24, | ||
(l >> 16) & 0xff, | ||
(l >> 8) & 0xff, | ||
l & 0xff, | ||
]); | ||
return buf; | ||
} | ||
parse(id) { | ||
const buf = new Uint8Array(this.size); | ||
this.base.decodeBytes(id, buf); | ||
return { | ||
epoch: ((buf[0] << 8) | buf[1]) * 4294967296 + | ||
this.u32(buf, 2) + | ||
this.epoch, | ||
id: buf.slice(6), | ||
}; | ||
} | ||
} | ||
const defULID = (opts) => new ULID(opts); | ||
exports.AKSUID = AKSUID; | ||
exports.KSUID32 = KSUID32; | ||
exports.KSUID64 = KSUID64; | ||
exports.ULID = ULID; | ||
exports.defKSUID32 = defKSUID32; | ||
exports.defKSUID64 = defKSUID64; | ||
exports.defULID = defULID; |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@thi.ng/api"),require("@thi.ng/base-n"),require("@thi.ng/random"),require("@thi.ng/strings")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/api","@thi.ng/base-n","@thi.ng/random","@thi.ng/strings"],t):t(((e="undefined"!=typeof globalThis?globalThis:e||self).thi=e.thi||{},e.thi.ng=e.thi.ng||{},e.thi.ng.ksuid={}),e.thi.ng.api,e.thi.ng.baseN,e.thi.ng.random,e.thi.ng.strings)}(this,(function(e,t,s,i,n){"use strict";class r{constructor(e,t){this.epochSize=e,this.base=t.base||s.BASE62,this.rnd=t.rnd,this.epoch=t.epoch,this.size=this.epochSize+t.bytes,this.pad=n.padLeft(this.base.size(2**(8*this.size)-1),this.base.base[0])}next(){return this.format(this.nextBinary())}nextBinary(){const e=this.timeOnlyBinary();return this.rnd?i.randomBytesFrom(this.rnd,e,this.epochSize):i.randomBytes(e,this.epochSize)}timeOnly(e){return this.format(this.timeOnlyBinary(e))}format(e){return this.ensureSize(e),this.pad(this.base.encodeBytes(e))}ensureSize(e){return t.assert(e.length==this.size,`illegal KSUID size, expected ${this.size} bytes`),e}ensureTime(e){return t.assert(e>=0,"configured base epoch must be in the past"),e}u32(e,t=0){return(e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3])>>>0}}class h extends r{constructor(e){super(4,Object.assign({epoch:16e8,bytes:16},e))}timeOnlyBinary(e=Date.now()){const t=new Uint8Array(this.size),s=this.ensureTime(e/1e3-this.epoch|0);return t.set([s>>>24,s>>16&255,s>>8&255,255&s]),t}parse(e){const t=new Uint8Array(this.size);return this.base.decodeBytes(e,t),{epoch:1e3*(this.u32(t)+this.epoch),id:t.slice(4)}}}class o extends r{constructor(e){super(8,Object.assign({epoch:16e11,bytes:12},e))}timeOnlyBinary(e=Date.now()){const t=new Uint8Array(this.size),s=this.ensureTime(e-this.epoch),i=s/4294967296>>>0,n=(4294967295&s)>>>0;return t.set([i>>>24,i>>16&255,i>>8&255,255&i,n>>>24,n>>16&255,n>>8&255,255&n]),t}parse(e){const t=new Uint8Array(this.size);return this.base.decodeBytes(e,t),{epoch:4294967296*this.u32(t)+this.u32(t,4)+this.epoch,id:t.slice(8)}}}e.AKSUID=r,e.KSUID32=h,e.KSUID64=o,e.defKSUID32=e=>new h(e),e.defKSUID64=e=>new o(e),Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@thi.ng/api"),require("@thi.ng/base-n"),require("@thi.ng/random"),require("@thi.ng/strings")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/api","@thi.ng/base-n","@thi.ng/random","@thi.ng/strings"],t):t(((e="undefined"!=typeof globalThis?globalThis:e||self).thi=e.thi||{},e.thi.ng=e.thi.ng||{},e.thi.ng.ksuid={}),e.thi.ng.api,e.thi.ng.baseN,e.thi.ng.random,e.thi.ng.strings)}(this,(function(e,t,s,i,n){"use strict";class r{constructor(e,t){this.epochSize=e,this.base=t.base||s.BASE62,this.rnd=t.rnd,this.epoch=t.epoch,this.size=this.epochSize+t.bytes,this.pad=n.padLeft(this.base.size(2**(8*this.size)-1),this.base.base[0])}next(){return this.format(this.nextBinary())}nextBinary(){const e=this.timeOnlyBinary();return this.rnd?i.randomBytesFrom(this.rnd,e,this.epochSize):i.randomBytes(e,this.epochSize)}timeOnly(e){return this.format(this.timeOnlyBinary(e))}format(e){return this.ensureSize(e),this.pad(this.base.encodeBytes(e))}ensureSize(e){return t.assert(e.length==this.size,`illegal KSUID size, expected ${this.size} bytes`),e}ensureTime(e){return t.assert(e>=0,"configured base epoch must be in the past"),e}u32(e,t=0){return(e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3])>>>0}}class h extends r{constructor(e){super(4,Object.assign({epoch:16e8,bytes:16},e))}timeOnlyBinary(e=Date.now()){const t=new Uint8Array(this.size),s=this.ensureTime(e/1e3-this.epoch|0);return t.set([s>>>24,s>>16&255,s>>8&255,255&s]),t}parse(e){const t=new Uint8Array(this.size);return this.base.decodeBytes(e,t),{epoch:1e3*(this.u32(t)+this.epoch),id:t.slice(4)}}}class o extends r{constructor(e){super(8,Object.assign({epoch:16e11,bytes:12},e))}timeOnlyBinary(e=Date.now()){const t=new Uint8Array(this.size),s=this.ensureTime(e-this.epoch),i=s/4294967296>>>0,n=(4294967295&s)>>>0;return t.set([i>>>24,i>>16&255,i>>8&255,255&i,n>>>24,n>>16&255,n>>8&255,255&n]),t}parse(e){const t=new Uint8Array(this.size);return this.base.decodeBytes(e,t),{epoch:4294967296*this.u32(t)+this.u32(t,4)+this.epoch,id:t.slice(8)}}}class a extends r{constructor(e){super(6,Object.assign({epoch:0,bytes:10,base:s.BASE32_CROCKFORD},e))}timeOnlyBinary(e=Date.now()){const t=new Uint8Array(this.size),s=this.ensureTime(e-this.epoch),i=s/4294967296>>>0,n=(4294967295&s)>>>0;return t.set([i>>8&255,255&i,n>>>24,n>>16&255,n>>8&255,255&n]),t}parse(e){const t=new Uint8Array(this.size);return this.base.decodeBytes(e,t),{epoch:4294967296*(t[0]<<8|t[1])+this.u32(t,2)+this.epoch,id:t.slice(6)}}}e.AKSUID=r,e.KSUID32=h,e.KSUID64=o,e.ULID=a,e.defKSUID32=e=>new h(e),e.defKSUID64=e=>new o(e),e.defULID=e=>new a(e),Object.defineProperty(e,"__esModule",{value:!0})})); |
{ | ||
"name": "@thi.ng/ksuid", | ||
"version": "0.3.0", | ||
"description": "Configurable sortable unique IDs, binary & base-N encoded, 32/64bit time resolution", | ||
"version": "0.4.0", | ||
"description": "Configurable K-sortable unique IDs, ULIDs, binary & base-N encoded, 32/48/64bit time resolutions", | ||
"module": "./index.js", | ||
@@ -43,3 +43,3 @@ "main": "./lib/index.js", | ||
"@thi.ng/api": "^7.1.7", | ||
"@thi.ng/base-n": "^0.1.8", | ||
"@thi.ng/base-n": "^0.2.0", | ||
"@thi.ng/random": "^2.4.4", | ||
@@ -72,2 +72,3 @@ "@thi.ng/strings": "^2.1.3" | ||
"typescript", | ||
"ulid", | ||
"uuid" | ||
@@ -86,3 +87,3 @@ ], | ||
}, | ||
"gitHead": "0c3f02d2670775eefda522bcee8789f1a686b1fc" | ||
"gitHead": "fe6cee7534b8534ee97aa52b159979dba6b90461" | ||
} |
@@ -24,19 +24,26 @@ <!-- This file is generated - DO NOT EDIT! --> | ||
Configurable sortable unique IDs, binary & base-N encoded, 32/64bit time resolution. | ||
Configurable sortable unique IDs, ULIDs, binary & base-N encoded, 32/48/64bit time resolution. | ||
Idea based on [segmentio/ksuid](https://github.com/segmentio/ksuid), though with | ||
added flexibility in terms of configuration & implementation: | ||
Idea based on [segmentio/ksuid](https://github.com/segmentio/ksuid), though the | ||
added flexibility in terms of configuration & implementation also enables the | ||
creation of [ULIDs](https://github.com/ulid/spec): | ||
- Configurable bit size (default: 160 bits) | ||
- Base-N encoding scheme (default: base62, see | ||
| Feature | KSUID default | ULID default | | ||
|---------------------------------------|------------------------|------------------------| | ||
| Configurable bit size | 160 bits | 128 bits | | ||
| Base-N encoding scheme | base62<sup>(1)</sup> | base32 (Crockford) | | ||
| Timestamp resolution | seconds (32 bits) | milliseconds (48 bits) | | ||
| | milliseconds (64 bits) | | | ||
| Epoch start time offset | approx. 2020-09-13 | none | | ||
| Time-only base ID generation | ✅ | ✅ | | ||
| ID parsing / decomposition | ✅ | ✅ | | ||
| Configurable RNG source<sup>(2)</sup> | ✅ | ✅ | | ||
- <sup>(1)</sup> See | ||
[@thi.ng/base-n](https://github.com/thi-ng/umbrella/tree/develop/packages/base-n) | ||
for alternatives) | ||
- Timestamp resolution (seconds [32 bits], milliseconds [64 bits]) | ||
- Epoch start time offset | ||
- Time-only base ID generation (optional) | ||
- KSUID parsing / decomposition | ||
- Configurable RNG source (default: `window.crypto`, `Math.random` fallback) | ||
for alternatives | ||
- <sup>(2)</sup> Default: `window.crypto`, `Math.random` as fallback | ||
KSUIDs generated w/ this package are composed from a 32 bit or 64 bit Unix epoch | ||
(by default time shifted to free up bits for future timestamps) and N additional | ||
IDs generated w/ this package are composed of a 32, 48 or 64 bit Unix epochs (by | ||
default time shifted to free up bits for future timestamps) and N additional | ||
bits of a random payload (from a configurable source). IDs can be generated as | ||
@@ -74,3 +81,3 @@ byte arrays or base-N encoded strings. For the latter, the JS runtime MUST | ||
Package sizes (gzipped, pre-treeshake): ESM: 730 bytes / CJS: 798 bytes / UMD: 907 bytes | ||
Package sizes (gzipped, pre-treeshake): ESM: 803 bytes / CJS: 879 bytes / UMD: 974 bytes | ||
@@ -89,3 +96,3 @@ ## Dependencies | ||
```ts | ||
import { defKSUID32, defKSUID64 } from "@thi.ng/ksuid"; | ||
import { defKSUID32, defKSUID64, defULID } from "@thi.ng/ksuid"; | ||
@@ -96,2 +103,4 @@ // init 32bit epoch (resolution: seconds) w/ defaults | ||
const id = defKSUID64(); | ||
// init 48bit epoch (resolution: milliseconds), same API | ||
const id = defULID(); | ||
@@ -98,0 +107,0 @@ id.next(); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
51123
20
474
188
0
+ Added@thi.ng/base-n@0.2.0(transitive)
- Removed@thi.ng/base-n@0.1.8(transitive)
Updated@thi.ng/base-n@^0.2.0