Skip to content

Commit 1ba0d64

Browse files
authored
Feat/v2 (#13)
* chore: started working on v2 * chore: added biome and lefthook * chore: cleanup * chore: increased coverage to 100% * chore: improved interface and README * chore: codecov integration + publish ci * chore: updated codecov integration * chore: trying to see if in ci --coverage is automatic * chore: explicit CODECOV_TOKEN env * chore: avoid double ci run on PR * chore: improved tests and updated README badges
1 parent 52fb6b5 commit 1ba0d64

22 files changed

+3152
-654
lines changed

.editorconfig

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

.github/workflows/ci.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
build-and-test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout repository
14+
uses: actions/checkout@v4
15+
16+
- name: Set up Node.js
17+
uses: actions/setup-node@v4
18+
with:
19+
node-version: 22
20+
21+
- name: Install dependencies
22+
run: npm ci
23+
24+
- name: Build
25+
run: npm run build
26+
27+
- name: Run tests with coverage
28+
run: npm run test:unit -- --coverage
29+
30+
- name: Upload coverage to Codecov
31+
uses: codecov/codecov-action@v5
32+
env:
33+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
34+

.github/workflows/release.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Release to npm
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
publish-npm:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout repository
12+
uses: actions/checkout@v4
13+
14+
- name: Set up Node.js
15+
uses: actions/setup-node@v4
16+
with:
17+
node-version: 22
18+
registry-url: 'https://registry.npmjs.org/'
19+
20+
- name: Install dependencies
21+
run: npm ci
22+
23+
- name: Build
24+
run: npm run build
25+
26+
- name: Publish to npm
27+
run: npm publish --provenance --access public
28+
env:
29+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,6 @@ jspm_packages
3535

3636
# Optional REPL history
3737
.node_repl_history
38+
39+
lib/
40+
dist/

.travis.yml

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

README.md

Lines changed: 53 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,163 +1,90 @@
11
# indexed-string-variation
22

33
[![npm version](https://badge.fury.io/js/indexed-string-variation.svg)](http://badge.fury.io/js/indexed-string-variation)
4-
[![Build Status](https://travis-ci.org/lmammino/indexed-string-variation.svg?branch=master)](https://travis-ci.org/lmammino/indexed-string-variation)
5-
[![codecov.io](https://codecov.io/gh/lmammino/indexed-string-variation/coverage.svg?branch=master)](https://codecov.io/gh/lmammino/indexed-string-variation)
4+
[![CI](https://github.com/lmammino/indexed-string-variation/actions/workflows/ci.yml/badge.svg)](https://github.com/lmammino/indexed-string-variation/actions/workflows/ci.yml)
5+
[![codecov](https://codecov.io/gh/lmammino/indexed-string-variation/graph/badge.svg?token=4zplgm5bBj)](https://codecov.io/gh/lmammino/indexed-string-variation)
66

7+
JavaScript module to generate all possible variations of strings over an
8+
alphabet using an n-ary virtual tree.
79

8-
Experimental JavaScript module to generate all possible variations of strings over an alphabet using an n-ary virtual tree.
10+
## Requirements
911

12+
- Node.js >= 22
1013

1114
## Install
1215

1316
With NPM:
1417

1518
```bash
16-
npm install --save indexed-string-variation
19+
npm install indexed-string-variation
1720
```
1821

19-
2022
## Usage
2123

22-
Generally useful to create distributed brute-force password recovery tools or
23-
other software that might require distributed generation of all possible
24-
strings on a given alphabet.
24+
This library is ESM-only and written in TypeScript. You can import and use it as
25+
follows:
2526

26-
```javascript
27-
const generator = require('indexed-string-variation').generator;
28-
const variations = generator('abc1');
27+
```js
28+
import isv from "indexed-string-variation";
2929

30-
for (let i=0; i < 23; i++) {
31-
console.log(i, variations(i)); // generates the i-th string in the alphabet 'abc1'
30+
// Basic usage: generate all variations for a given alphabet
31+
for (
32+
const str of isv({ alphabet: "abc1", maxIterations: 23 })
33+
) {
34+
console.log(str);
3235
}
33-
```
34-
35-
Will print:
36-
37-
```bash
38-
0 ''
39-
1 'a'
40-
2 'b'
41-
3 'c'
42-
4 '1'
43-
5 'aa'
44-
6 'ab'
45-
7 'ac'
46-
8 'a1'
47-
9 'ba'
48-
10 'bb'
49-
11 'bc'
50-
12 'b1'
51-
13 'ca'
52-
14 'cb'
53-
15 'cc'
54-
16 'c1'
55-
17 '1a'
56-
18 '1b'
57-
19 '1c'
58-
20 '11'
59-
21 'aaa'
60-
22 'aab'
61-
```
62-
6336

64-
## API
37+
// Generate variations from a specific index (using BigInt)
38+
for (
39+
const str of isv({
40+
alphabet: "abc1",
41+
from: 20n,
42+
maxIterations: 5,
43+
})
44+
) {
45+
console.log(str);
46+
}
6547

66-
The module `indexed-string-variation` exposes the following components:
67-
68-
* `generator` (also aliased as `default` for ES2015 modules): the
69-
main generator function
70-
* `defaultAlphabet`: a constant string that contains the sequence of
71-
characters in the defaultAlphabet
48+
// Generate variations up to a maximum string length
49+
for (const str of isv({ alphabet: "abc1", maxLen: 2 })) {
50+
console.log(str);
51+
}
7252

73-
As you can see in the [usage example](#usage), the `generator` function takes as input the
74-
alphabet string (which is optional and it will default to `defaultAlphabet` if
75-
not provided) and returns a new function called `variations` which can be
76-
used to retrieve the indexed variation on the given alphabet. `variations` takes
77-
a non-negative integer as input which represents the index of the variations
78-
that we want to generate:
53+
// endless variations (don't use a `for ... of` loop because it will never end!)
54+
const values = isv({
55+
alphabet: "abc1",
56+
});
7957

80-
```javascript
81-
const variations = generator('XYZ');
82-
console.log(variations(7123456789)); // "XYYZYZZZYYYZYZYXYYYYX"
58+
console.log(values.next()); // { value: 'a', done: false }
59+
console.log(values.next()); // { value: 'b', done: false }
60+
//...
8361
```
8462

63+
## TypeScript
8564

86-
## How the algorithm works
87-
88-
The way the generation algorithm work is using an n-ary tree where n is the size of the alphabet.
89-
For example, if we have an alphabet containing only `a`, `b` and `c` and we want to generate all
90-
the strings with a maximum length of 3 the algorithm will use the following tree:
91-
92-
![Sample ternary tree over abc alphabet](doc/sample_diagram.png)
93-
94-
The tree is to be considered "virtual", because it's never generated in its integrity, so the
95-
used space in memory is minimal.
96-
97-
In brevity we can describe the algorithm as follows:
65+
Type definitions are included. You can use this library with full type safety in
66+
TypeScript projects.
9867

99-
> Given an index **i** over an alphabet of length **n** and it's corresponding n-ary tree,
100-
the string associated to **i** corresponds to the string obtained by
101-
concatenating all the characters found in the path that goes from the root node to the **i**-th node.
68+
## Testing
10269

103-
For example, with the alphabet in the image we can generate the following strings:
70+
This project uses [Vitest](https://vitest.dev/):
10471

105-
| i | generated string |
106-
|---:|---|
107-
|0||
108-
|1|a|
109-
|2|b|
110-
|3|c|
111-
|4|aa|
112-
|5|ab|
113-
|6|ac|
114-
|7|ba|
115-
|8|bb|
116-
|9|bc|
117-
|10|ca|
118-
|11|cb|
119-
|12|cc|
120-
121-
122-
Important note: The alphabet is always normalized (i.e. duplicates are removed)
123-
124-
125-
## Use big-integer to avoid JavaScript big integers approximations
126-
127-
Integers with more than 18 digits are approximated (e.g. `123456789012345680000 === 123456789012345678901`), so at some
128-
point the generator will start to generate a lot of duplicated strings and it will start to miss many cases.
129-
130-
To workaround this issue you can use indexes generated with the module [big-integer](https://www.npmjs.com/package/big-integer).
131-
Internally the indexed-string-variation will take care of performing the correct
132-
operations using the library.
133-
134-
Let's see an example:
135-
136-
```javascript
137-
const bigInt = require('big-integer'); // install from https://npmjs.com/package/big-integer
138-
const generator = require('indexed-string-variation').generator;
139-
const variations = generator('JKWXYZ');
140-
141-
// generation using regular big numbers (same result)
142-
console.log(variations(123456789012345678901)); // XJZJYXXXYYJKYZZJKZKYJWJJYW
143-
console.log(variations(123456789012345680000)); // XJZJYXXXYYJKYZZJKZKYJWJJYW
144-
145-
// generation using big-integer numbers (correct results)
146-
console.log(variations(bigInt('123456789012345678901'))); // XJZJYXXXYYJKYZZJKZKXZKJZZJ
147-
console.log(variations(bigInt('123456789012345680000'))); // XJZJYXXXYYJKYZZJKZKXZWJJWK
72+
```bash
73+
npm test
14874
```
14975

150-
Anyway, keep in mind that big-integers might have a relevant performance impact,
151-
so if you don't plan to use huge integers it's still recommended to use
152-
plain JavaScript numbers as indexes.
153-
76+
## Development
15477

155-
## Contributing
78+
- Source code is in `src/` (TypeScript)
79+
- Build output is in `dist/`
80+
- Tests are in `src/test.ts`
15681

157-
Everyone is very welcome to contribute to this project.
158-
You can contribute just by submitting bugs or suggesting improvements by
159-
[opening an issue on GitHub](https://github.com/lmammino/indexed-string-variation/issues).
82+
## Migration notes
16083

84+
- The library now uses native JavaScript `BigInt` instead of the `big-integer`
85+
dependency.
86+
- Only ESM is supported (no CommonJS `require`).
87+
- Node.js 22 or newer is required.
16188

16289
## License
16390

biome.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3+
"vcs": {
4+
"enabled": false,
5+
"clientKind": "git",
6+
"useIgnoreFile": false
7+
},
8+
"files": {
9+
"ignoreUnknown": false,
10+
"ignore": ["dist/", "coverage/"]
11+
},
12+
"formatter": {
13+
"enabled": true,
14+
"indentStyle": "space"
15+
},
16+
"organizeImports": {
17+
"enabled": true
18+
},
19+
"linter": {
20+
"enabled": true,
21+
"rules": {
22+
"recommended": true
23+
}
24+
},
25+
"javascript": {
26+
"formatter": {
27+
"quoteStyle": "single",
28+
"semicolons": "asNeeded"
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)