@bifravst/aws-cdk-lambda-helpers 1.2.0 → 1.2.2

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.
Files changed (76) hide show
  1. package/dist/cdk/TestApp.d.ts +5 -0
  2. package/dist/cdk/TestApp.js +12 -0
  3. package/dist/cdk/TestStack.d.ts +12 -0
  4. package/dist/cdk/TestStack.js +39 -0
  5. package/dist/cdk/baseLayer.d.ts +2 -0
  6. package/dist/cdk/baseLayer.js +5 -0
  7. package/dist/cdk/e2e.js +11 -0
  8. package/dist/cdk/lambda.d.ts +2 -0
  9. package/dist/cdk/lambda.js +5 -0
  10. package/dist/cdk/packTestLambdas.d.ts +5 -0
  11. package/dist/cdk/packTestLambdas.js +4 -0
  12. package/dist/e2e.spec.js +17 -0
  13. package/dist/lambdas/test.zip +0 -0
  14. package/dist/layers/baseLayer/nodejs/node_modules/.package-lock.json +16 -0
  15. package/dist/layers/baseLayer/nodejs/node_modules/id128/CHANGES +20 -0
  16. package/dist/layers/baseLayer/nodejs/node_modules/id128/LICENSE +18 -0
  17. package/dist/layers/baseLayer/nodejs/node_modules/id128/README.md +853 -0
  18. package/dist/layers/baseLayer/nodejs/node_modules/id128/index.d.ts +167 -0
  19. package/dist/layers/baseLayer/nodejs/node_modules/id128/index.js +49 -0
  20. package/dist/layers/baseLayer/nodejs/node_modules/id128/package.json +68 -0
  21. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/coder/base.js +53 -0
  22. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/coder/crockford32.js +114 -0
  23. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/coder/hex.js +63 -0
  24. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/coder/uuid.js +77 -0
  25. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/byte-array.js +26 -0
  26. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/epoch-converter.js +32 -0
  27. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/exception.js +18 -0
  28. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/fake-machine.js +26 -0
  29. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/machine.js +37 -0
  30. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/random-bytes-browser.js +9 -0
  31. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/common/random-bytes.js +17 -0
  32. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/factory/id.js +96 -0
  33. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/factory/versioned-id.js +72 -0
  34. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/base.js +39 -0
  35. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/ulid-monotonic.js +71 -0
  36. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/ulid.js +64 -0
  37. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/uuid-1.js +149 -0
  38. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/uuid-4.js +24 -0
  39. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/uuid-6.js +146 -0
  40. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/uuid-nil.js +33 -0
  41. package/dist/layers/baseLayer/nodejs/node_modules/id128/src/id/uuid.js +58 -0
  42. package/dist/layers/baseLayer/nodejs/node_modules/id128/utils.js +35 -0
  43. package/dist/layers/baseLayer/nodejs/package-lock.json +6671 -0
  44. package/dist/layers/baseLayer/nodejs/package.json +1 -0
  45. package/dist/layers/baseLayer.zip +0 -0
  46. package/dist/src/checkSumOfFiles.spec.d.ts +1 -0
  47. package/dist/src/commonParent.spec.d.ts +1 -0
  48. package/dist/{packLambda.d.ts → src/packLambda.d.ts} +2 -2
  49. package/package.json +12 -5
  50. /package/dist/{checkSumOfFiles.spec.d.ts → cdk/e2e.d.ts} +0 -0
  51. /package/dist/{commonParent.spec.d.ts → e2e.spec.d.ts} +0 -0
  52. /package/dist/{LambdaLogGroup.d.ts → src/LambdaLogGroup.d.ts} +0 -0
  53. /package/dist/{LambdaLogGroup.js → src/LambdaLogGroup.js} +0 -0
  54. /package/dist/{LambdaSource.d.ts → src/LambdaSource.d.ts} +0 -0
  55. /package/dist/{LambdaSource.js → src/LambdaSource.js} +0 -0
  56. /package/dist/{cdk.d.ts → src/cdk.d.ts} +0 -0
  57. /package/dist/{cdk.js → src/cdk.js} +0 -0
  58. /package/dist/{checkSumOfFiles.spec.js → src/checkSumOfFiles.spec.js} +0 -0
  59. /package/dist/{checksumOfFiles.d.ts → src/checksumOfFiles.d.ts} +0 -0
  60. /package/dist/{checksumOfFiles.js → src/checksumOfFiles.js} +0 -0
  61. /package/dist/{commonParent.d.ts → src/commonParent.d.ts} +0 -0
  62. /package/dist/{commonParent.js → src/commonParent.js} +0 -0
  63. /package/dist/{commonParent.spec.js → src/commonParent.spec.js} +0 -0
  64. /package/dist/{findDependencies.d.ts → src/findDependencies.d.ts} +0 -0
  65. /package/dist/{findDependencies.js → src/findDependencies.js} +0 -0
  66. /package/dist/{lambda.d.ts → src/lambda.d.ts} +0 -0
  67. /package/dist/{lambda.js → src/lambda.js} +0 -0
  68. /package/dist/{layer.d.ts → src/layer.d.ts} +0 -0
  69. /package/dist/{layer.js → src/layer.js} +0 -0
  70. /package/dist/{packLambda.js → src/packLambda.js} +0 -0
  71. /package/dist/{packLambdaFromPath.d.ts → src/packLambdaFromPath.d.ts} +0 -0
  72. /package/dist/{packLambdaFromPath.js → src/packLambdaFromPath.js} +0 -0
  73. /package/dist/{packLayer.d.ts → src/packLayer.d.ts} +0 -0
  74. /package/dist/{packLayer.js → src/packLayer.js} +0 -0
  75. /package/dist/{util.d.ts → src/util.d.ts} +0 -0
  76. /package/dist/{util.js → src/util.js} +0 -0
@@ -0,0 +1,853 @@
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)