@bifravst/aws-cdk-lambda-helpers 1.2.4 → 1.2.6
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.
- package/README.md +9 -1
- package/dist/src/module-folder-named-like-handler-bug.spec.js +6 -2
- package/dist/src/packLambda.js +10 -3
- package/dist/src/test-data/module-folder-named-like-handler-bug/different-level/lambda/acme.js +2 -0
- package/dist/src/test-data/module-folder-named-like-handler-bug/same-level/acme/lib.d.ts +1 -0
- package/dist/src/test-data/module-folder-named-like-handler-bug/same-level/acme/lib.js +1 -0
- package/dist/src/test-data/module-folder-named-like-handler-bug/same-level/acme.d.ts +1 -0
- package/package.json +2 -2
- package/dist/cdk/TestApp.d.ts +0 -5
- package/dist/cdk/TestApp.js +0 -12
- package/dist/cdk/TestStack.d.ts +0 -12
- package/dist/cdk/TestStack.js +0 -39
- package/dist/cdk/baseLayer.d.ts +0 -2
- package/dist/cdk/baseLayer.js +0 -5
- package/dist/cdk/e2e.d.ts +0 -1
- package/dist/cdk/e2e.js +0 -11
- package/dist/cdk/lambda.d.ts +0 -2
- package/dist/cdk/lambda.js +0 -5
- package/dist/cdk/packTestLambdas.d.ts +0 -5
- package/dist/cdk/packTestLambdas.js +0 -4
- package/dist/e2e.spec.d.ts +0 -1
- package/dist/e2e.spec.js +0 -17
- package/dist/lambdas/test.zip +0 -0
- package/dist/layers/baseLayer/nodejs/node_modules/.package-lock.json +0 -16
- package/dist/layers/baseLayer/nodejs/node_modules/id128/CHANGES +0 -20
- package/dist/layers/baseLayer/nodejs/node_modules/id128/LICENSE +0 -18
- package/dist/layers/baseLayer/nodejs/node_modules/id128/README.md +0 -853
- package/dist/layers/baseLayer/nodejs/node_modules/id128/index.d.ts +0 -167
- package/dist/layers/baseLayer/nodejs/node_modules/id128/index.js +0 -49
- package/dist/layers/baseLayer/nodejs/node_modules/id128/package.json +0 -68
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/coder/base.js +0 -53
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/coder/crockford32.js +0 -114
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/coder/hex.js +0 -63
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/coder/uuid.js +0 -77
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/byte-array.js +0 -26
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/epoch-converter.js +0 -32
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/exception.js +0 -18
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/fake-machine.js +0 -26
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/machine.js +0 -37
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/random-bytes-browser.js +0 -9
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/random-bytes.js +0 -17
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/factory/id.js +0 -96
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/factory/versioned-id.js +0 -72
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/base.js +0 -39
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/ulid-monotonic.js +0 -71
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/ulid.js +0 -64
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/uuid-1.js +0 -149
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/uuid-4.js +0 -24
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/uuid-6.js +0 -146
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/uuid-nil.js +0 -33
- package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/uuid.js +0 -58
- package/dist/layers/baseLayer/nodejs/node_modules/id128/utils.js +0 -35
- package/dist/layers/baseLayer/nodejs/package-lock.json +0 -6671
- package/dist/layers/baseLayer/nodejs/package.json +0 -1
- package/dist/layers/baseLayer.zip +0 -0
- /package/dist/src/test-data/module-folder-named-like-handler-bug/{acme → different-level/acme}/lib.d.ts +0 -0
- /package/dist/src/test-data/module-folder-named-like-handler-bug/{acme → different-level/acme}/lib.js +0 -0
- /package/dist/src/test-data/module-folder-named-like-handler-bug/{acme.d.ts → different-level/lambda/acme.d.ts} +0 -0
- /package/dist/src/test-data/module-folder-named-like-handler-bug/{acme.js → same-level/acme.js} +0 -0
@@ -1,853 +0,0 @@
|
|
1
|
-
# Id128
|
2
|
-
|
3
|
-
Generate 128-bit unique identifiers for various specifications. In particular:
|
4
|
-
- [ULID](#ulid)
|
5
|
-
- [Monotonic ULID](#ulidmonotonic)
|
6
|
-
- [UUID 1 (Variant 1 Version 1)](#uuid1)
|
7
|
-
- [UUID 4 (Variant 1 Version 4)](#uuid4)
|
8
|
-
- [UUID 6 (Variant 1 Version 6)](#uuid6)
|
9
|
-
- [Nil UUID (Variant 0 Version 0)](#uuidnil)
|
10
|
-
- [Uuid (Unknown Variant and Version)](#uuid)
|
11
|
-
|
12
|
-
# Common Usage
|
13
|
-
|
14
|
-
```es6
|
15
|
-
const {
|
16
|
-
Ulid,
|
17
|
-
UlidMonotonic,
|
18
|
-
Uuid,
|
19
|
-
Uuid1,
|
20
|
-
Uuid4,
|
21
|
-
Uuid6,
|
22
|
-
UuidNil,
|
23
|
-
idCompare,
|
24
|
-
idEqual,
|
25
|
-
} = require('id128');
|
26
|
-
|
27
|
-
// Id factories
|
28
|
-
[
|
29
|
-
Ulid,
|
30
|
-
UlidMonotonic,
|
31
|
-
Uuid1,
|
32
|
-
Uuid4,
|
33
|
-
Uuid6,
|
34
|
-
UuidNil,
|
35
|
-
].forEach((IdType) => {
|
36
|
-
// Identify the factory
|
37
|
-
console.log(IdType.name);
|
38
|
-
|
39
|
-
// Generate a new id
|
40
|
-
const id = IdType.generate();
|
41
|
-
|
42
|
-
// Get the smallest valid id
|
43
|
-
const min = IdType.MIN();
|
44
|
-
|
45
|
-
// Get the largest valid id
|
46
|
-
const max = IdType.MAX();
|
47
|
-
|
48
|
-
// Type-check the id
|
49
|
-
console.log(id instanceof IdType.type)
|
50
|
-
|
51
|
-
// Compare ids
|
52
|
-
console.log(id.equal(id));
|
53
|
-
console.log(! id.equal(min));
|
54
|
-
console.log(! id.equal(max));
|
55
|
-
console.log(id.compare(min) === 1);
|
56
|
-
console.log(id.compare(id) === 0);
|
57
|
-
console.log(id.compare(max) === -1);
|
58
|
-
|
59
|
-
// Encode the id in its canonical form
|
60
|
-
const canonical = id.toCanonical();
|
61
|
-
console.log(canonical);
|
62
|
-
|
63
|
-
// Encode the id for efficient db storage
|
64
|
-
const raw = id.toRaw();
|
65
|
-
console.log(raw);
|
66
|
-
|
67
|
-
// Verify a canonically formatted id
|
68
|
-
console.log(IdType.isCanonical(canonical));
|
69
|
-
|
70
|
-
// Decode a valid canonically formatted id
|
71
|
-
console.log(id.equal(IdType.fromCanonical(canonical)));
|
72
|
-
|
73
|
-
// Decode a canonically formatted id, skipping validation
|
74
|
-
console.log(id.equal(IdType.fromCanonicalTrusted(canonical)));
|
75
|
-
|
76
|
-
// Verify a raw formatted id
|
77
|
-
console.log(IdType.isRaw(raw));
|
78
|
-
|
79
|
-
// Decode a valid raw formatted id
|
80
|
-
console.log(id.equal(IdType.fromRaw(raw)));
|
81
|
-
|
82
|
-
// Decode a raw formatted id, skipping validation
|
83
|
-
console.log(id.equal(IdType.fromRawTrusted(raw)));
|
84
|
-
});
|
85
|
-
|
86
|
-
// Uuid Factory
|
87
|
-
[0, 1, 4, 6].forEach((version) => {
|
88
|
-
// Generate a new id
|
89
|
-
const id = Uuid.generate({ version });
|
90
|
-
|
91
|
-
// Get the smallest valid id
|
92
|
-
const min = Uuid.MIN({ version });
|
93
|
-
|
94
|
-
// Get the largest valid id
|
95
|
-
const max = Uuid.MAX({ version });
|
96
|
-
|
97
|
-
// Type-check the id
|
98
|
-
console.log(id instanceof Uuid.type)
|
99
|
-
|
100
|
-
// Encode the id in its canonical form
|
101
|
-
const canonical = id.toCanonical();
|
102
|
-
console.log(canonical);
|
103
|
-
|
104
|
-
// Encode the id for efficient db storage
|
105
|
-
const raw = id.toRaw();
|
106
|
-
console.log(raw);
|
107
|
-
|
108
|
-
// Decode a valid canonically formatted id
|
109
|
-
console.log(id.equal(Uuid.fromCanonical(canonical)));
|
110
|
-
|
111
|
-
// Decode a canonically formatted id, skipping validation
|
112
|
-
console.log(id.equal(Uuid.fromCanonicalTrusted(canonical)));
|
113
|
-
|
114
|
-
// Decode a valid raw formatted id
|
115
|
-
console.log(id.equal(Uuid.fromRaw(raw)));
|
116
|
-
|
117
|
-
// Decode a raw formatted id, skipping validation
|
118
|
-
console.log(id.equal(Uuid.fromRawTrusted(raw)));
|
119
|
-
});
|
120
|
-
|
121
|
-
// Static Utilities
|
122
|
-
|
123
|
-
// Equate arbitrary ids
|
124
|
-
console.log(idEqual(Ulid.generate(), Uuid4.generate()))
|
125
|
-
|
126
|
-
// Compare arbitrary ids
|
127
|
-
console.log(idCompare(Ulid.generate(), Uuid4.generate()))
|
128
|
-
```
|
129
|
-
|
130
|
-
## Common Factory Properties
|
131
|
-
|
132
|
-
### name
|
133
|
-
Return the name of the generated id type.
|
134
|
-
|
135
|
-
### type
|
136
|
-
Return the type of the generated id instances for type-checking
|
137
|
-
with the `instanceof` operator.
|
138
|
-
|
139
|
-
## Common Factory Methods
|
140
|
-
|
141
|
-
### .construct(bytes) => id
|
142
|
-
Return a new id instance without validating the bytes.
|
143
|
-
|
144
|
-
### .generate() => id
|
145
|
-
Return a new id instance.
|
146
|
-
|
147
|
-
### .MIN() => id
|
148
|
-
Return the id instance with the smallest valid value.
|
149
|
-
|
150
|
-
### .MAX() => id
|
151
|
-
Return the id instance with the largest valid value.
|
152
|
-
|
153
|
-
### .fromCanonical(canonical_string) => id
|
154
|
-
Decode an id from its canonical representation.
|
155
|
-
Throw `InvalidEncoding` if the string is undecodable.
|
156
|
-
|
157
|
-
### .fromCanonicalTrusted(canonical_string) => id
|
158
|
-
Decode an id from its canonical representation.
|
159
|
-
Skip validation and assume the input is decodable.
|
160
|
-
|
161
|
-
### .fromRaw(raw_string) => id
|
162
|
-
Decode an id from its raw representation.
|
163
|
-
Throw `InvalidEncoding` if the string is undecodable.
|
164
|
-
|
165
|
-
### .fromRawTrusted(raw_string) => id
|
166
|
-
Decode an id from its raw representation.
|
167
|
-
Skip validation and assume the input is decodable.
|
168
|
-
|
169
|
-
### .toCanonical(id) => canonical_string
|
170
|
-
Encode the given id in the canonical form.
|
171
|
-
Throw `InvalidBytes` if the id is not 128-bit conformant.
|
172
|
-
|
173
|
-
### .toRaw(id) => raw_string
|
174
|
-
Encode the given id in the raw form.
|
175
|
-
Throw `InvalidBytes` if the id is not 128-bit conformant.
|
176
|
-
|
177
|
-
### .isCanonical(canonical_string) => (true|false)
|
178
|
-
Verify if a string is a valid canonical encoding.
|
179
|
-
|
180
|
-
### .isRaw(raw_string) => (true|false)
|
181
|
-
Verify if a string is a valid raw encoding.
|
182
|
-
|
183
|
-
## Common Instance Properties
|
184
|
-
|
185
|
-
### bytes
|
186
|
-
Return the actual byte array representing the id.
|
187
|
-
|
188
|
-
## Common Instance Methods
|
189
|
-
|
190
|
-
### .clone() => deep_copy
|
191
|
-
Return a new instance of the id with the same bit signature.
|
192
|
-
|
193
|
-
### .compare(other) => (-1|0|1)
|
194
|
-
Determine how this id is ordered against another.
|
195
|
-
|
196
|
-
### .equal(other) => (true|false)
|
197
|
-
Determine if this id has the same bytes as another.
|
198
|
-
|
199
|
-
### .toCanonical() => canonical_string
|
200
|
-
Encode this id in its canonical form.
|
201
|
-
|
202
|
-
### .toRaw() => raw_string
|
203
|
-
Encode this id in its raw form.
|
204
|
-
|
205
|
-
## Namespace Static Utilities
|
206
|
-
|
207
|
-
### idCompare(left_id, right_id) => (-1|0|1)
|
208
|
-
Determine if the left id is `less than | equal to | greater than`
|
209
|
-
the right id using lexicographical byte order.
|
210
|
-
|
211
|
-
### idEqual(left_id, right_id) => (true|false)
|
212
|
-
Determine if 2 ids have the same byte value.
|
213
|
-
|
214
|
-
# Ulid
|
215
|
-
```es6
|
216
|
-
const { Ulid } = require('id128');
|
217
|
-
```
|
218
|
-
|
219
|
-
Ulid, as [specified](https://github.com/ulid/spec), has some nice properties:
|
220
|
-
- collision resistant: 80-bits of randomness
|
221
|
-
- k-ordered: prefixed with millisecond precision timestamp
|
222
|
-
- database friendly: fits within a uuid and generally appends to the index
|
223
|
-
- human friendly: canonically encodes as a case-insensitive Crockford 32 number
|
224
|
-
|
225
|
-
It is useful when you need a distributed domain unique id.
|
226
|
-
|
227
|
-
## Additional Instance Properties
|
228
|
-
|
229
|
-
### time
|
230
|
-
Return a Date object for the epoch milliseconds encoded in the id.
|
231
|
-
|
232
|
-
## Additional Factory Methods
|
233
|
-
|
234
|
-
### .generate({ time }) => id
|
235
|
-
Return a new id instance. Set any argument to `null` or `undefined` to trigger
|
236
|
-
its default behavior.
|
237
|
-
|
238
|
-
`time` defaults to the current time. It can be given either as a `Date` object
|
239
|
-
or epoch milliseconds (milliseconds since January 1st, 1970).
|
240
|
-
Throw `InvalidEpoch` for times before the epoch or after approximately August 2nd, 10889.
|
241
|
-
This is provided mostly for unit tests.
|
242
|
-
|
243
|
-
## Byte Format
|
244
|
-
Format `tttt tttt tttt rrrr rrrr rrrr rrrr rrrr` where:
|
245
|
-
- `t` is 4 bits of time
|
246
|
-
- `r` is 4 bits of random
|
247
|
-
|
248
|
-
# UlidMonotonic
|
249
|
-
```es6
|
250
|
-
const { UlidMonotonic } = require('id128');
|
251
|
-
```
|
252
|
-
|
253
|
-
UlidMonotonic is inspired by the [specification](https://github.com/ulid/spec#monotonicity):
|
254
|
-
- collision resistant: 15-bits of random seeded clock sequence plus 64-bits of randomness
|
255
|
-
- total ordered: prefixed with millisecond precision timestamp plus 15-bit clock sequence
|
256
|
-
- database friendly: fits within a uuid and generally appends to the index
|
257
|
-
- human friendly: canonically encodes as a case-insensitive Crockford 32 number
|
258
|
-
|
259
|
-
It is useful when you need to guarantee a process unique id.
|
260
|
-
|
261
|
-
## Additional Instance Properties
|
262
|
-
|
263
|
-
### time
|
264
|
-
Return a Date object for the epoch milliseconds encoded in the id.
|
265
|
-
|
266
|
-
## Additional Factory Methods
|
267
|
-
|
268
|
-
### .generate({ time }) => id
|
269
|
-
Return a new id instance. Set any argument to `null` or `undefined` to trigger
|
270
|
-
its default behavior.
|
271
|
-
|
272
|
-
`time` defaults to the current time. It can be given either as a `Date` object
|
273
|
-
or epoch milliseconds (milliseconds since January 1st, 1970). Extra caution is
|
274
|
-
required since setting a future time and subsequently calling `generate`
|
275
|
-
guarantees usage of the clock sequence.
|
276
|
-
Throw `InvalidEpoch` for times before the epoch or after approximately August 2nd, 10889.
|
277
|
-
Throw `ClockSequenceOverflow` when the clock sequence is exhausted.
|
278
|
-
This is provided mostly for unit tests.
|
279
|
-
|
280
|
-
### .reset()
|
281
|
-
Return the clock sequence to its starting position. This is provided mostly for
|
282
|
-
unit tests.
|
283
|
-
|
284
|
-
## Byte Format
|
285
|
-
Format `tttt tttt tttt cccc rrrr rrrr rrrr rrrr` where:
|
286
|
-
- `t` is 4 bits of time
|
287
|
-
- `c` is 4 bits of random-seeded clock sequence
|
288
|
-
- `r` is 4 bits of random
|
289
|
-
|
290
|
-
More specifically, the clock sequence is a counter. When the first id for a new
|
291
|
-
timestamp is generated, the clock sequence is seeded with random bits and the
|
292
|
-
left-most clock sequence bit is set to 0, reserving 2^15 clock ticks. Whenever
|
293
|
-
a time from the past seeds the generator, the previous id's time and clock sequence
|
294
|
-
are used instead, with the clock sequence incremented by 1. This guarantees
|
295
|
-
strict local monotonicity and preserves lexical ordering and general randomness.
|
296
|
-
|
297
|
-
Without a seeded time, UlidMonotonic is unlikely to exceed the clock sequence
|
298
|
-
(the clock sequence supports generating a new id every 31 nanoseconds). However,
|
299
|
-
in the unlikely event of an overflow, id generation is aborted.
|
300
|
-
|
301
|
-
# Uuid1
|
302
|
-
```es6
|
303
|
-
const { Uuid1 } = require('id128');
|
304
|
-
```
|
305
|
-
|
306
|
-
Uuid1 implements the [RFC 4122 time specification](https://tools.ietf.org/html/rfc4122#section-4.2):
|
307
|
-
- time-based: encodes the current millisecond timestamp
|
308
|
-
- location-based: encodes the mac address of the machine
|
309
|
-
|
310
|
-
While this mostly adheres to the spec, there are a few nuances in the handling
|
311
|
-
of time. Instead of encoding time as 100-nanoseconds since the Gregorian epoch,
|
312
|
-
48 bits encode milliseconds since the Gregorian epoch time and 12 bits count past
|
313
|
-
time collisions, resetting whenever given a new future time. There are a few benefits:
|
314
|
-
- high precision time is unreliable in the browser so this ensures better precision
|
315
|
-
- the max supported date is now around the year 10502 instead of around 5236
|
316
|
-
- generating 4096 ids/ms (~4,000,000 ids/s) is wildly unlikely in real world uses
|
317
|
-
- in the rare hi-res overflow, the count simply spills over to the clock sequence
|
318
|
-
|
319
|
-
## Additional Instance Properties
|
320
|
-
|
321
|
-
### clock_sequence
|
322
|
-
Return the clock sequence encoded in the id.
|
323
|
-
|
324
|
-
### hires_time
|
325
|
-
Return the number of prior ids generated while time stood still.
|
326
|
-
|
327
|
-
### node
|
328
|
-
Return the MAC address encoded in the id.
|
329
|
-
|
330
|
-
### time
|
331
|
-
Return a Date object for the epoch milliseconds encoded in the id.
|
332
|
-
|
333
|
-
### variant
|
334
|
-
Return the variant as encoded in the id. Should be 1.
|
335
|
-
|
336
|
-
### version
|
337
|
-
Return the version as encoded in the id. Should be 1.
|
338
|
-
|
339
|
-
## Additional Factory Methods
|
340
|
-
|
341
|
-
### .generate({ node, time }) => id
|
342
|
-
Return a new id instance. Set any argument to `null` or `undefined` to trigger
|
343
|
-
its default behavior.
|
344
|
-
|
345
|
-
`time` defaults to the current time. It can be given either as a `Date` object
|
346
|
-
or Gregorian milliseconds (milliseconds since October 15th, 1582). Extra caution
|
347
|
-
is required since setting a future time and subsequently calling `generate`
|
348
|
-
guarantees usage of the hi-res counter and clock sequence.
|
349
|
-
Throw `InvalidEpoch` for times before the Gregorian epoch or after approximately May 17, 10502.
|
350
|
-
This is provided mostly for unit tests.
|
351
|
-
|
352
|
-
`node` defaults to the MAC address, or a random multicast address when the MAC
|
353
|
-
address is unavailable. It can be given as an array of 6 bytes.
|
354
|
-
|
355
|
-
### .reset()
|
356
|
-
Return the hi-res counter to its starting position and generate a new random
|
357
|
-
clock sequence seed. This is provided mostly for unit tests.
|
358
|
-
|
359
|
-
## Byte Format
|
360
|
-
Format `llll lnnn mmmm vhhh tccc aaaa aaaa aaaa` where:
|
361
|
-
- `l` is 4 bits of low millisecond time
|
362
|
-
- `n` is 4 bits of hi-res time
|
363
|
-
- `m` is 4 bits of mid millisecond time
|
364
|
-
- `v` is 4 bits of the version
|
365
|
-
- `h` is 4 bits of high millisecond time
|
366
|
-
- `t` is 2 bits of the variant followed by 2 bits of the clock sequence
|
367
|
-
- `c` is 4 bits of the clock sequence
|
368
|
-
- `a` is 4 bits of the machine address
|
369
|
-
|
370
|
-
# Uuid4
|
371
|
-
```es6
|
372
|
-
const { Uuid4 } = require('id128');
|
373
|
-
```
|
374
|
-
|
375
|
-
Uuid4 implements the [RFC 4122 random uuid specification](https://tools.ietf.org/html/rfc4122#section-4.4):
|
376
|
-
|
377
|
-
- 122 random bits
|
378
|
-
- 2 bits reserved for the variant (1)
|
379
|
-
- 4 bits reserved for the version (4)
|
380
|
-
|
381
|
-
It is useful when you need a well-supported globally unique id.
|
382
|
-
|
383
|
-
## Additional Instance Properties
|
384
|
-
|
385
|
-
### variant
|
386
|
-
Return the variant as encoded in the id. Should be 1.
|
387
|
-
|
388
|
-
### version
|
389
|
-
Return the version as encoded in the id. Should be 4.
|
390
|
-
|
391
|
-
## Byte Format
|
392
|
-
Format `rrrr rrrr rrrr vrrr trrr rrrr rrrr rrrr` where:
|
393
|
-
- `r` is 4 bits of random
|
394
|
-
- `v` is 4 bits of the version
|
395
|
-
- `t` is 2 bits of the variant followed by 2 bits of random
|
396
|
-
|
397
|
-
# Uuid6
|
398
|
-
```es6
|
399
|
-
const { Uuid6 } = require('id128');
|
400
|
-
```
|
401
|
-
|
402
|
-
Uuid6 implements this [controversial blog post](https://bradleypeabody.github.io/uuidv6/):
|
403
|
-
- time-based: encodes the current millisecond timestamp
|
404
|
-
- location-based: encodes the mac address of the machine
|
405
|
-
|
406
|
-
This is essentially the same implementation as Uuid1, however the time bits are
|
407
|
-
arranged in lexicographical order. If you're looking for a spacial UUID that
|
408
|
-
is optimized for clustered indices, consider Uuid6 as a viable option.
|
409
|
-
|
410
|
-
## Additional Instance Properties
|
411
|
-
|
412
|
-
### clock_sequence
|
413
|
-
Return the clock sequence encoded in the id.
|
414
|
-
|
415
|
-
### hires_time
|
416
|
-
Return the number of prior ids generated while time stood still.
|
417
|
-
|
418
|
-
### node
|
419
|
-
Return the MAC address encoded in the id.
|
420
|
-
|
421
|
-
### time
|
422
|
-
Return a Date object for the epoch milliseconds encoded in the id.
|
423
|
-
|
424
|
-
### variant
|
425
|
-
Return the variant as encoded in the id. Should be 1.
|
426
|
-
|
427
|
-
### version
|
428
|
-
Return the version as encoded in the id. Should be 6.
|
429
|
-
|
430
|
-
## Additional Factory Methods
|
431
|
-
|
432
|
-
### .generate({ node, time }) => id
|
433
|
-
Return a new id instance. Set any argument to `null` or `undefined` to trigger
|
434
|
-
its default behavior.
|
435
|
-
|
436
|
-
`time` defaults to the current time. It can be given either as a `Date` object
|
437
|
-
or Gregorian milliseconds (milliseconds since October 15th, 1582). Extra caution
|
438
|
-
is required since setting a future time and subsequently calling `generate`
|
439
|
-
guarantees usage of the hi-res counter and clock sequence.
|
440
|
-
Throw `InvalidEpoch` for times before the Gregorian epoch or after approximately May 17, 10502.
|
441
|
-
This is provided mostly for unit tests.
|
442
|
-
|
443
|
-
`node` defaults to the MAC address, or a random multicast address when the MAC
|
444
|
-
address is unavailable. It can be given as an array of 6 bytes.
|
445
|
-
|
446
|
-
### .reset()
|
447
|
-
Return the hi-res counter to its starting position and generate a new random
|
448
|
-
clock sequence seed. This is provided mostly for unit tests.
|
449
|
-
|
450
|
-
## Byte Format
|
451
|
-
Format `mmmm mmmm mmmm vnnn tccc aaaa aaaa aaaa` where:
|
452
|
-
- `m` is 4 bits of millisecond time
|
453
|
-
- `v` is 4 bits of the version
|
454
|
-
- `n` is 4 bits of hi-res time
|
455
|
-
- `t` is 2 bits of the variant followed by 2 bits of the clock sequence
|
456
|
-
- `c` is 4 bits of the clock sequence
|
457
|
-
- `a` is 4 bits of the machine address
|
458
|
-
|
459
|
-
# UuidNil
|
460
|
-
```es6
|
461
|
-
const { UuidNil } = require('id128');
|
462
|
-
```
|
463
|
-
|
464
|
-
UuidNil implements the [RFC 4122 nil uuid specification](https://tools.ietf.org/html/rfc4122#section-4.1.7):
|
465
|
-
|
466
|
-
- 128 bits of glorious 0
|
467
|
-
|
468
|
-
It is useful as placeholder for other 128-bit ids.
|
469
|
-
|
470
|
-
## Additional Instance Properties
|
471
|
-
|
472
|
-
### variant
|
473
|
-
Return the variant as encoded in the id. Should be 0.
|
474
|
-
|
475
|
-
### version
|
476
|
-
Return the version as encoded in the id. Should be 0.
|
477
|
-
|
478
|
-
## Byte Format
|
479
|
-
Format `0000 0000 0000 v000 t000 0000 0000 0000` where:
|
480
|
-
- `0` is 4 bits of 0
|
481
|
-
- `v` is 4 bits of the version (also 0)
|
482
|
-
- `t` is 2 bits of the variant (also 0) followed by 2 bits of 0
|
483
|
-
|
484
|
-
# Uuid
|
485
|
-
```es6
|
486
|
-
const { Uuid } = require('id128');
|
487
|
-
```
|
488
|
-
|
489
|
-
Uuid is a factory for generating and decoding UUIDs when the version is unknown
|
490
|
-
until runtime. If the version is supported, it will produce UUIDs of the
|
491
|
-
appropriate type. In exchange for the runtime flexibility, there is a necessary
|
492
|
-
performance degradation. It is recommended to use this for decoding data from
|
493
|
-
uncontrolled sources rather than generating new ids.
|
494
|
-
|
495
|
-
Uuid supports all the same methods as the other ID factories. All modifications
|
496
|
-
to typical behavior are noted below.
|
497
|
-
|
498
|
-
## Factory Properties
|
499
|
-
|
500
|
-
### versioned_ids
|
501
|
-
Return the factories of all the supported ids.
|
502
|
-
|
503
|
-
## Factory Methods
|
504
|
-
|
505
|
-
### .construct(bytes) => versioned_id
|
506
|
-
Return a new versioned id instance without validating the bytes.
|
507
|
-
Return a Uuid if an appropriate version does not exist.
|
508
|
-
|
509
|
-
### .generate({ version, ... }) => versioned_id
|
510
|
-
Return a new versioned id instance. All additional arguments are passed through
|
511
|
-
to the associated version.
|
512
|
-
Throw `UnsupportedVersion` if no associated version exists.
|
513
|
-
|
514
|
-
### .MIN({ version }) => versioned_id
|
515
|
-
Return the versioned id instance with the smallest valid value.
|
516
|
-
Throw `UnsupportedVersion` if no associated version exists.
|
517
|
-
|
518
|
-
### .MAX({ version }) => versioned_id
|
519
|
-
Return the versioned id instance with the largest valid value.
|
520
|
-
Throw `UnsupportedVersion` if no associated version exists.
|
521
|
-
|
522
|
-
### .fromCanonical(canonical_string) => versioned_id
|
523
|
-
Decode a versioned id from its canonical representation.
|
524
|
-
Return a Uuid if an appropriate version does not exist.
|
525
|
-
Throw `InvalidEncoding` if the string is undecodable.
|
526
|
-
|
527
|
-
### .fromCanonicalTrusted(canonical_string) => versioned_id
|
528
|
-
Decode a versioned id from its canonical representation.
|
529
|
-
Return a Uuid if an appropriate version does not exist.
|
530
|
-
Skip validation and assume the input is decodable.
|
531
|
-
|
532
|
-
### .fromRaw(raw_string) => versioned_id
|
533
|
-
Decode a versioned id from its raw representation.
|
534
|
-
Return a Uuid if an appropriate version does not exist.
|
535
|
-
Throw `InvalidEncoding` if the string is undecodable.
|
536
|
-
|
537
|
-
### .fromRawTrusted(raw_string) => versioned_id
|
538
|
-
Decode a versioned id from its raw representation.
|
539
|
-
Return a Uuid if an appropriate version does not exist.
|
540
|
-
Skip validation and assume the input is decodable.
|
541
|
-
|
542
|
-
# Exceptions
|
543
|
-
```es6
|
544
|
-
const { Exception } = require('id128');
|
545
|
-
```
|
546
|
-
All exceptions are namespaced under `Exception` for clarity.
|
547
|
-
|
548
|
-
## Id128Error
|
549
|
-
```es6
|
550
|
-
const { Exception: { Id128Error } } = require('id128');
|
551
|
-
```
|
552
|
-
Base exception class for generic error catching.
|
553
|
-
|
554
|
-
## ClockSequenceOverflow
|
555
|
-
```es6
|
556
|
-
const { Exception: { ClockSequenceOverflow } } = require('id128');
|
557
|
-
```
|
558
|
-
Incrementing the clock sequence is impossible. Should not happen unless manually seeding `#generate`.
|
559
|
-
|
560
|
-
## InvalidBytes
|
561
|
-
```es6
|
562
|
-
const { Exception: { InvalidBytes } } = require('id128');
|
563
|
-
```
|
564
|
-
Encoding something other than 16 bytes. Likely to happen when encoding untrusted user input.
|
565
|
-
|
566
|
-
## InvalidEncoding
|
567
|
-
```es6
|
568
|
-
const { Exception: { InvalidEncoding } } = require('id128');
|
569
|
-
```
|
570
|
-
Decoding an invalid format or non-string object. Likely to happen when decoding untrusted user input.
|
571
|
-
|
572
|
-
## InvalidEpoch
|
573
|
-
```es6
|
574
|
-
const { Exception: { InvalidEpoch } } = require('id128');
|
575
|
-
```
|
576
|
-
Generating an id with an invalid timestamp. Should not happen unless manually seeding `#generate`.
|
577
|
-
|
578
|
-
## UnsupportedVersion
|
579
|
-
```es6
|
580
|
-
const { Exception: { UnsupportedVersion } } = require('id128');
|
581
|
-
```
|
582
|
-
Failed to find a factory for the desired version. Likely to happen when decoding untrusted user input.
|
583
|
-
|
584
|
-
# Browser Support
|
585
|
-
|
586
|
-
This module supports browser compilation though Webpack/Browserify with a few caveats:
|
587
|
-
- Random number generation is optimized for memory usage over speed since only a
|
588
|
-
handful of ids are likely to be generated during a user's session so the overhead
|
589
|
-
of generating a page of random values has poor amortized cost.
|
590
|
-
- The browser must have native support for `crypto`. `Math.random` is far too
|
591
|
-
insecure to support as a fallback, especially since the fallback only makes sense
|
592
|
-
for older browsers with proven security holes. `msCrypto` is not a supported
|
593
|
-
fallback due to many of the other required features.
|
594
|
-
- The browser must support:
|
595
|
-
* classes
|
596
|
-
* closures
|
597
|
-
* `const` and `let`
|
598
|
-
* `Uint8Array`
|
599
|
-
* `Symbol`
|
600
|
-
|
601
|
-
This library is intended for modern browsers that keep pace with Javascript's
|
602
|
-
growing ecosystem. I philosophically object to supporting efforts of companies
|
603
|
-
to pour more money into broken browsers that only cause headaches for developers
|
604
|
-
to support. I expect these caveats to be unnecessary within the next 5 years.
|
605
|
-
|
606
|
-
All that said, please notify me of any issues with modern browsers and I'll do
|
607
|
-
my best to support you.
|
608
|
-
|
609
|
-
# Typescript Support
|
610
|
-
|
611
|
-
This module includes Typescript bindings for all primary usage patterns.
|
612
|
-
I'd like to highlight some design decisions:
|
613
|
-
|
614
|
-
## Id Types and Factory Types
|
615
|
-
Each factory is exported as an instance using the same name as the type of id
|
616
|
-
it produces. In Javascript, this is desirable as it provides a uniform interface
|
617
|
-
regardless of the implementation. However, this complicates the Typescript
|
618
|
-
type imports.
|
619
|
-
|
620
|
-
For simple cases, like constructing an id and passing it around the program,
|
621
|
-
this will behave exactly as desired:
|
622
|
-
```
|
623
|
-
import { Ulid } from 'id128'
|
624
|
-
|
625
|
-
const id: Ulid = Ulid.generate()
|
626
|
-
```
|
627
|
-
|
628
|
-
When you need to check the type of the id, you should use the `type` attribute:
|
629
|
-
```
|
630
|
-
import { Ulid } from 'id128'
|
631
|
-
|
632
|
-
const id: Ulid = Ulid.generate()
|
633
|
-
if (id instanceof Ulid.type) { ... }
|
634
|
-
```
|
635
|
-
|
636
|
-
If you wish to pass around the factory itself, you can import the factory type:
|
637
|
-
```
|
638
|
-
import { Ulid } from 'id128'
|
639
|
-
import type { UlidFactory } from 'id128'
|
640
|
-
|
641
|
-
function doSomething(factory: UlidFactory) { ... }
|
642
|
-
doSomething(Ulid)
|
643
|
-
```
|
644
|
-
|
645
|
-
Finally, if you need to operate on any id or id factory, you can import base types:
|
646
|
-
```
|
647
|
-
import type { Id, AnyIdFactory } from 'id128'
|
648
|
-
|
649
|
-
function makeOne(factory: AnyIdFactory): Id {
|
650
|
-
return factory.generate()
|
651
|
-
}
|
652
|
-
```
|
653
|
-
|
654
|
-
## Exception Handling
|
655
|
-
Exception classes are designed to be checked using `instanceof`. Unfortunately,
|
656
|
-
Typescript broke `instanceof` `Error` support for a more compliant compilation.
|
657
|
-
Fortunately, the included exceptions bypass the issues caused by inheriting from
|
658
|
-
the native `Error` by never overriding the constructor and implementing `name`
|
659
|
-
as a readonly getter, As a consequence, the exceptions actually violate the
|
660
|
-
standard `Error` interface, but they fulfill the standard `Function` interface.
|
661
|
-
Therefore, you can safely use `instanceof` as intended:
|
662
|
-
```
|
663
|
-
import { UlidMonotonic } from 'id128'
|
664
|
-
import { Exception } from 'id128'
|
665
|
-
|
666
|
-
try { UlidMonotonic.generate() }
|
667
|
-
catch (err) {
|
668
|
-
if (err instanceof Exception.ClockSequenceOverflow ) { ... }
|
669
|
-
}
|
670
|
-
```
|
671
|
-
|
672
|
-
# Motivation
|
673
|
-
|
674
|
-
Originally, I was looking for an id that is independent of the database, but plays
|
675
|
-
nice with database indices and data types. Most databases have built-in support
|
676
|
-
for storing UUIDs efficiently, but UUID v4 does not cluster well and the other UUIDs
|
677
|
-
require bit manipulation to get good performance, which will likely cause future
|
678
|
-
maintenance headaches.
|
679
|
-
|
680
|
-
After a bit of research, ULID was determined to nicely solve the problem. However,
|
681
|
-
the javascript implementation had 2 major issues:
|
682
|
-
1. lacks database support
|
683
|
-
2. it's slow, which in a single-threaded Node server is deadly
|
684
|
-
|
685
|
-
I considered sending in a patch, however I saw an opportunity for a more expressive
|
686
|
-
interface, which is typically a bit harder to modify once a project is in wide use.
|
687
|
-
There was also a clear pattern for encoding 128-bit ids into various formats,
|
688
|
-
which seems generally useful.
|
689
|
-
|
690
|
-
Ultimately, this library strives to be:
|
691
|
-
- secure: uses cryptographic randomness to ensure general uniqueness
|
692
|
-
- performant: currently one of the fastest id generators available
|
693
|
-
- maintainable: heavily tested isolated code with a consistent interface
|
694
|
-
- extensible: modular design to easily add new ids and new encodings
|
695
|
-
|
696
|
-
# Tests
|
697
|
-
|
698
|
-
To run the tests:
|
699
|
-
```bash
|
700
|
-
npm install
|
701
|
-
npm run test-all
|
702
|
-
```
|
703
|
-
|
704
|
-
# Benchmarks
|
705
|
-
|
706
|
-
Competitive benchmarks have been moved to [benchmark-guid](https://github.com/aarondcohen/benchmark-guid)
|
707
|
-
|
708
|
-
To run the benchmarks:
|
709
|
-
```bash
|
710
|
-
npm install
|
711
|
-
npm run benchmark
|
712
|
-
```
|
713
|
-
|
714
|
-
```
|
715
|
-
Platform info:
|
716
|
-
==============
|
717
|
-
Darwin 18.2.0 x64
|
718
|
-
Node.JS: 15.0.0
|
719
|
-
V8: 8.6.395.16-node.15
|
720
|
-
Intel(R) Core(TM) i7-4578U CPU @ 3.00GHz × 4
|
721
|
-
|
722
|
-
Ulid
|
723
|
-
====
|
724
|
-
generate: (4,590,833rps) (avg: 217ns)
|
725
|
-
MIN: (12,491,186rps) (avg: 80ns)
|
726
|
-
MAX: (12,669,223rps) (avg: 78ns)
|
727
|
-
fromCanonical: (1,707,717rps) (avg: 585ns)
|
728
|
-
fromCanonicalTrusted: (2,078,278rps) (avg: 481ns)
|
729
|
-
fromRaw: (1,483,373rps) (avg: 674ns)
|
730
|
-
fromRawTrusted: (1,979,964rps) (avg: 505ns)
|
731
|
-
toCanonical: (3,256,155rps) (avg: 307ns)
|
732
|
-
toRaw: (6,012,244rps) (avg: 166ns)
|
733
|
-
|
734
|
-
UlidMonotonic
|
735
|
-
=============
|
736
|
-
generate: (3,787,685rps) (avg: 264ns)
|
737
|
-
MIN: (6,306,928rps) (avg: 158ns)
|
738
|
-
MAX: (6,301,217rps) (avg: 158ns)
|
739
|
-
fromCanonical: (1,423,104rps) (avg: 702ns)
|
740
|
-
fromCanonicalTrusted: (1,722,958rps) (avg: 580ns)
|
741
|
-
fromRaw: (1,381,296rps) (avg: 723ns)
|
742
|
-
fromRawTrusted: (1,698,639rps) (avg: 588ns)
|
743
|
-
toCanonical: (3,205,394rps) (avg: 311ns)
|
744
|
-
toRaw: (5,774,288rps) (avg: 173ns)
|
745
|
-
|
746
|
-
Uuid1
|
747
|
-
=====
|
748
|
-
generate: (4,984,699rps) (avg: 200ns)
|
749
|
-
MIN: (12,888,384rps) (avg: 77ns)
|
750
|
-
MAX: (12,817,435rps) (avg: 78ns)
|
751
|
-
fromCanonical: (1,226,007rps) (avg: 815ns)
|
752
|
-
fromCanonicalTrusted: (1,578,429rps) (avg: 633ns)
|
753
|
-
fromRaw: (1,306,295rps) (avg: 765ns)
|
754
|
-
fromRawTrusted: (1,626,095rps) (avg: 614ns)
|
755
|
-
toCanonical: (5,859,714rps) (avg: 170ns)
|
756
|
-
toRaw: (5,973,139rps) (avg: 167ns)
|
757
|
-
|
758
|
-
Uuid4
|
759
|
-
=====
|
760
|
-
generate: (6,492,849rps) (avg: 154ns)
|
761
|
-
MIN: (6,400,528rps) (avg: 156ns)
|
762
|
-
MAX: (6,617,714rps) (avg: 151ns)
|
763
|
-
fromCanonical: (1,286,561rps) (avg: 777ns)
|
764
|
-
fromCanonicalTrusted: (1,625,362rps) (avg: 615ns)
|
765
|
-
fromRaw: (1,313,004rps) (avg: 761ns)
|
766
|
-
fromRawTrusted: (1,672,463rps) (avg: 597ns)
|
767
|
-
toCanonical: (6,103,543rps) (avg: 163ns)
|
768
|
-
toRaw: (6,235,448rps) (avg: 160ns)
|
769
|
-
|
770
|
-
Uuid6
|
771
|
-
=====
|
772
|
-
generate: (3,466,357rps) (avg: 288ns)
|
773
|
-
MIN: (5,244,292rps) (avg: 190ns)
|
774
|
-
MAX: (5,151,746rps) (avg: 194ns)
|
775
|
-
fromCanonical: (1,324,905rps) (avg: 754ns)
|
776
|
-
fromCanonicalTrusted: (1,676,541rps) (avg: 596ns)
|
777
|
-
fromRaw: (1,357,353rps) (avg: 736ns)
|
778
|
-
fromRawTrusted: (1,717,530rps) (avg: 582ns)
|
779
|
-
toCanonical: (5,061,822rps) (avg: 197ns)
|
780
|
-
toRaw: (4,839,125rps) (avg: 206ns)
|
781
|
-
|
782
|
-
UuidNil
|
783
|
-
=======
|
784
|
-
generate: (9,312,932rps) (avg: 107ns)
|
785
|
-
MIN: (5,158,703rps) (avg: 193ns)
|
786
|
-
MAX: (8,795,275rps) (avg: 113ns)
|
787
|
-
fromCanonical: (1,293,946rps) (avg: 772ns)
|
788
|
-
fromCanonicalTrusted: (1,629,605rps) (avg: 613ns)
|
789
|
-
fromRaw: (1,472,042rps) (avg: 679ns)
|
790
|
-
fromRawTrusted: (1,780,904rps) (avg: 561ns)
|
791
|
-
toCanonical: (5,169,323rps) (avg: 193ns)
|
792
|
-
toRaw: (5,196,170rps) (avg: 192ns)
|
793
|
-
|
794
|
-
Uuid processing Uuid1
|
795
|
-
=====================
|
796
|
-
generate: (4,159,340rps) (avg: 240ns)
|
797
|
-
MIN: (4,877,918rps) (avg: 205ns)
|
798
|
-
MAX: (4,907,348rps) (avg: 203ns)
|
799
|
-
fromCanonical: (1,045,214rps) (avg: 956ns)
|
800
|
-
fromCanonicalTrusted: (1,255,223rps) (avg: 796ns)
|
801
|
-
fromRaw: (1,021,436rps) (avg: 979ns)
|
802
|
-
fromRawTrusted: (1,268,213rps) (avg: 788ns)
|
803
|
-
|
804
|
-
Uuid processing Uuid4
|
805
|
-
=====================
|
806
|
-
generate: (5,695,823rps) (avg: 175ns)
|
807
|
-
MIN: (4,886,337rps) (avg: 204ns)
|
808
|
-
MAX: (4,907,325rps) (avg: 203ns)
|
809
|
-
fromCanonical: (1,047,372rps) (avg: 954ns)
|
810
|
-
fromCanonicalTrusted: (1,292,729rps) (avg: 773ns)
|
811
|
-
fromRaw: (1,031,590rps) (avg: 969ns)
|
812
|
-
fromRawTrusted: (1,266,122rps) (avg: 789ns)
|
813
|
-
|
814
|
-
Uuid processing Uuid6
|
815
|
-
=====================
|
816
|
-
generate: (4,122,279rps) (avg: 242ns)
|
817
|
-
MIN: (4,744,102rps) (avg: 210ns)
|
818
|
-
MAX: (4,860,271rps) (avg: 205ns)
|
819
|
-
fromCanonical: (1,066,004rps) (avg: 938ns)
|
820
|
-
fromCanonicalTrusted: (1,298,925rps) (avg: 769ns)
|
821
|
-
fromRaw: (1,053,871rps) (avg: 948ns)
|
822
|
-
fromRawTrusted: (1,286,373rps) (avg: 777ns)
|
823
|
-
|
824
|
-
Uuid processing UuidNil
|
825
|
-
=======================
|
826
|
-
generate: (8,140,742rps) (avg: 122ns)
|
827
|
-
MIN: (4,717,779rps) (avg: 211ns)
|
828
|
-
MAX: (8,261,012rps) (avg: 121ns)
|
829
|
-
fromCanonical: (1,052,765rps) (avg: 949ns)
|
830
|
-
fromCanonicalTrusted: (1,285,968rps) (avg: 777ns)
|
831
|
-
fromRaw: (1,130,468rps) (avg: 884ns)
|
832
|
-
fromRawTrusted: (1,312,878rps) (avg: 761ns)
|
833
|
-
```
|
834
|
-
|
835
|
-
# Acknowledgments
|
836
|
-
|
837
|
-
Much of this library would not exist without the great work and documentation of
|
838
|
-
other engineers. In particular:
|
839
|
-
|
840
|
-
- [ksuid](https://github.com/segmentio/ksuid): an in-depth exploration of the guid nuances
|
841
|
-
- [ulid](https://github.com/ulid/javascript): an elegant solution to a persistent problem
|
842
|
-
- [uuid-random](https://github.com/jchook/uuid-random): allocating pages of randomness is by far the biggest performance factor
|
843
|
-
|
844
|
-
Also, thank you:
|
845
|
-
- [ruleb](https://github.com/ruleb): researching and patching worker support
|
846
|
-
|
847
|
-
# Contributing
|
848
|
-
|
849
|
-
Feel free to make a branch and send a pull request through [github](https://github.com/aarondcohen/id128)
|
850
|
-
|
851
|
-
# Issues
|
852
|
-
|
853
|
-
Please report any issues or bugs through [github](https://github.com/aarondcohen/id128/issues)
|