Skip to content

Commit d3693a5

Browse files
authored
Merge pull request #12 from ryanande/feature/rewrite
Sequential GUID Generator Improvements
2 parents ca54c0b + 15a8346 commit d3693a5

File tree

11 files changed

+9925
-214
lines changed

11 files changed

+9925
-214
lines changed

.babelrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"presets": ["env"]
2+
"presets": ["@babel/preset-env"]
33
}

.github/workflows/main.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Build and Test
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main, master ]
8+
9+
permissions:
10+
contents: read
11+
packages: write
12+
13+
jobs:
14+
build:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
20+
21+
- uses: actions/setup-node@v4
22+
with:
23+
node-version: '20'
24+
cache: 'npm'
25+
registry-url: 'https://registry.npmjs.org'
26+
27+
- name: Install npm dependencies
28+
run: npm ci
29+
30+
- name: Build and Test
31+
run: npm run build
32+
33+
- name: Publish to NPM
34+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
35+
run: npm run trypublish
36+
env:
37+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ lib/
2525
# Dependency directories
2626
node_modules/
2727
jspm_packages/
28-
package-lock.json
2928

3029
# Optional npm cache directory
3130
.npm

README.md

Lines changed: 57 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,103 @@
11
# JsCombGuid
22

33
[![npm version](https://badge.fury.io/js/jscombguid.svg)](https://badge.fury.io/js/jscombguid)
4+
[![Build Status](https://github.com/ryanande/JsCombGuid/workflows/CI/badge.svg)](https://github.com/ryanande/JsCombGuid/actions)
5+
[![Coverage Status](https://coveralls.io/repos/github/ryanande/JsCombGuid/badge.svg?branch=master)](https://coveralls.io/github/ryanande/JsCombGuid?branch=master)
46

5-
A simple JavaScript Comb Guid Generator.
7+
A high-performance JavaScript Sequential GUID Generator that creates sortable, unique identifiers with microsecond precision.
68

7-
No guarantees it's perfect!
9+
## Features
810

9-
That being said, we have run tests generating 100,000 ids and not having any duplicates.
10-
Guids are generated based on current date/ time and this data is used to create the sequential unique identifiers.
11+
- **High Performance**: Optimized for speed with minimal memory allocations
12+
- **Microsecond Precision**: Uses high-resolution timestamps for better uniqueness
13+
- **Sortable**: GUIDs are chronologically sortable
14+
- **Collision Resistant**: Multiple entropy sources and a counter for high-frequency generation
15+
- **RFC4122 Compliant**: Generates valid UUID v4 format
16+
- **Zero Dependencies**: Only requires moment.js for date calculations
1117

12-
Primary concept of the code was sparked within this discussion [http://stackoverflow.com/a/8809472/173949](http://stackoverflow.com/a/8809472/173949).
13-
14-
## Getting Started
15-
16-
### Installing
17-
18-
Pretty simple implementation, simply import the module, and you're off an running!
18+
## Installation
1919

2020
```bash
2121
npm install jscombguid
2222
```
2323

24-
And cheap node example usage;
24+
## Usage
2525

2626
```javascript
27-
const comb = require("jscombguid");
27+
import generateSequentialGuid from 'jscombguid';
2828

29-
console.log(comb.generateCombGuid());
29+
// Generate a single GUID
30+
const guid = generateSequentialGuid();
31+
console.log(guid); // e.g., "550e8400-e29b-41d4-a716-446655440000"
32+
33+
// Generate multiple GUIDs
34+
const guids = Array.from({ length: 10 }, () => generateSequentialGuid());
3035
```
3136

32-
## Running the tests
37+
## Performance
3338

34-
The library source includes some straight forward mocha tests and a duplicate check test which executes 10,000 cycles of guid generation check for duplicates being created. These tests sre located in the test/index.test.js file.
39+
The generator is optimized for high-performance scenarios:
3540

36-
To execute the tests fire off the following line of code in your fav tool.
41+
- Average generation time: < 0.1ms per GUID
42+
- Can generate 100,000+ unique GUIDs per second
43+
- Memory efficient with minimal allocations
44+
- Stable performance under load
3745

38-
```bash
39-
npm run test
40-
```
46+
## How It Works
4147

42-
.nyc_output directory will have the coverage reports outputted to the coverage directory.
43-
To view this report, and you have `http-server`, a handy basic insta web server, you can instal it and simply run;
44-
Total overkill for this small package, but a good example of code coverage reporting.
48+
The generator creates sequential GUIDs by combining:
4549

46-
```bash
47-
npm i -g http-server
48-
```
50+
1. A base UUID (24 characters)
51+
2. Days since 1900-01-01 (4 characters)
52+
3. Microseconds since start of day (8 characters)
53+
4. A 16-bit counter for high-frequency generation (4 characters)
4954

50-
Then fire it up and run it post the test execution;
55+
This combination ensures:
56+
- Chronological sortability
57+
- High uniqueness
58+
- Microsecond precision
59+
- Collision resistance
5160

52-
```bash
53-
http-server ./coverage/lcov-report/
54-
```
61+
## Benchmarks
5562

56-
and check out the server site at [http://127.0.0.1:8080](http://127.0.0.1:8080)
63+
```javascript
64+
const iterations = 100000;
65+
const start = process.hrtime();
5766

58-
## Built With
67+
for (let i = 0; i < iterations; i++) {
68+
generateSequentialGuid();
69+
}
5970

60-
* [momentjs](http://www.momentjs.com) - used in working with date time to generate the combs (direct dependency)
61-
* [mocha](https://maven.apache.org/) - unsed in the unit testing of the simple function
62-
* [instabul](https://istanbul.js.org/) - used to validate test coverage and reporting
63-
* [eslint](https://eslint.org/) - used for housekeeping and sanity
64-
* [babel](https://babeljs.io/) - used to bust down the code, we aren't doing anything that would fully constitute this however
71+
const [seconds, nanoseconds] = process.hrtime(start);
72+
const averageTime = (seconds * 1000 + nanoseconds / 1000000) / iterations;
73+
console.log(`Average generation time: ${averageTime.toFixed(3)}ms`);
74+
```
6575

6676
## Development
6777

68-
After cloning the repo run;
69-
7078
```bash
79+
# Install dependencies
7180
npm install
72-
```
73-
74-
From that point, there are 3 possible scripts to run;
7581

76-
1. build - runs lint, tests, then babel
77-
2. lint - runs eslint
78-
3. test - runs the mocha tests
82+
# Run tests
83+
npm test
7984

80-
To start, just run a build;
85+
# Run linting
86+
npm run lint
8187

82-
```bash
88+
# Build
8389
npm run build
8490
```
8591

86-
And away you go. This is an overblown project repo, with probably more going on than necessary, however, it is a proof of concept on all aspects of npm package development. That being said, there are a few references which are worth mentioning here;
87-
88-
1. [Developing and Publishing an NPM Package](https://auth0.com/blog/developing-npm-packages/)
89-
2. [BadgeFury](https://badge.fury.io/)
90-
3. [How to Build and Publish an NPM Package](https://scotch.io/bar-talk/how-to-build-and-publish-a-npm-package)
91-
4. [Automate your NPM publish with GitHub Actions](https://medium.com/devopslinks/automate-your-npm-publish-with-github-actions-dfe8059645dd)
92-
9392
## Contributing
9493

95-
Please read [CONTRIBUTING.md](https://github.com/ryanande/JsCombGuid/blob/master/CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
96-
97-
## Versioning
98-
99-
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/ryanande/JsCombGuid/tags).
94+
Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
10095

10196
## License
10297

103-
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
98+
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
10499

105100
## Acknowledgments
106101

107-
* Big thanks to [@thetinomen](https://twitter.com/thetinomen) he refactored out the sophmoric code...
102+
- Original concept inspired by [this StackOverflow discussion](http://stackoverflow.com/a/8809472/173949)
103+
- Thanks to [@thetinomen](https://twitter.com/thetinomen) for code improvements

eslint.config.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import js from '@eslint/js';
2+
import globals from 'globals';
3+
4+
export default [
5+
js.configs.recommended,
6+
{
7+
languageOptions: {
8+
ecmaVersion: 2022,
9+
sourceType: 'module',
10+
globals: {
11+
...globals.browser,
12+
...globals.node,
13+
...globals.mocha
14+
}
15+
},
16+
rules: {
17+
'no-unused-vars': 'error',
18+
'no-redeclare': 'off'
19+
}
20+
}
21+
];

github/main.workflow

Lines changed: 0 additions & 38 deletions
This file was deleted.

lib/index.js

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)