Skip to content

Commit b6e4ed6

Browse files
committed
Add JSDoc based types
1 parent 5613239 commit b6e4ed6

File tree

5 files changed

+84
-17
lines changed

5 files changed

+84
-17
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.DS_Store
2+
*.d.ts
23
*.log
34
coverage/
45
node_modules/

index.js

+35-13
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,48 @@
1+
/**
2+
* @typedef {import('unist').Node} Node
3+
* @typedef {import('unist-util-visit').Type} Type
4+
* @typedef {import('unist-util-visit').Props} Props
5+
* @typedef {import('unist-util-visit').TestFunctionAnything} TestFunctionAnything
6+
*
7+
* @typedef {(node: Node) => unknown} KeyFunction
8+
*/
9+
110
import {visit} from 'unist-util-visit'
211

312
export class Index {
4-
constructor(prop, tree, filter) {
5-
if (filter === null || filter === undefined) {
6-
filter = trueConst
7-
}
8-
13+
/**
14+
* @param {string|KeyFunction} prop
15+
* @param {Node} [tree]
16+
* @param {null|undefined|Type|Props|TestFunctionAnything|Array<Type|Props|TestFunctionAnything>} [test]
17+
*/
18+
constructor(prop, tree, test) {
19+
/** @type {Map.<unknown, Array.<Node>>} */
920
this.index = new Map()
10-
this.keyfn = typeof prop === 'string' ? (node) => node[prop] : prop
21+
/** @type {KeyFunction} */
22+
this.key =
23+
typeof prop === 'string' ? (/** @type {Node} */ node) => node[prop] : prop
1124

1225
if (tree) {
13-
visit(tree, filter, (node) => this.add(node))
26+
visit(tree, test, (/** @type {Node} */ node) => {
27+
this.add(node)
28+
})
1429
}
1530
}
1631

32+
/**
33+
* @param {unknown} key
34+
* @returns {Array.<Node>}
35+
*/
1736
get(key) {
1837
return this.index.get(key) || []
1938
}
2039

40+
/**
41+
* @param {Node} node
42+
*/
2143
add(node) {
22-
var key = this.keyfn(node)
44+
var key = this.key(node)
45+
/** @type {Array.<Node>} */
2346
var nodes
2447

2548
if (!this.index.has(key)) {
@@ -35,8 +58,11 @@ export class Index {
3558
return this
3659
}
3760

61+
/**
62+
* @param {Node} node
63+
*/
3864
remove(node) {
39-
var key = this.keyfn(node)
65+
var key = this.key(node)
4066
var nodes = this.index.get(key)
4167
var pos = nodes ? nodes.indexOf(node) : -1
4268

@@ -47,7 +73,3 @@ export class Index {
4773
return this
4874
}
4975
}
50-
51-
function trueConst() {
52-
return true
53-
}

package.json

+15-1
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,36 @@
3535
"sideEffects": false,
3636
"type": "module",
3737
"main": "index.js",
38+
"types": "index.d.ts",
3839
"files": [
40+
"index.d.ts",
3941
"index.js"
4042
],
4143
"dependencies": {
44+
"@types/unist": "^2.0.3",
4245
"unist-util-visit": "^3.0.0"
4346
},
4447
"devDependencies": {
48+
"@types/tape": "^4.0.0",
4549
"c8": "^7.0.0",
4650
"prettier": "^2.0.0",
4751
"remark-cli": "^9.0.0",
4852
"remark-preset-wooorm": "^8.0.0",
53+
"rimraf": "^3.0.0",
4954
"tape": "^5.0.0",
55+
"type-coverage": "^2.0.0",
56+
"typescript": "^4.0.0",
5057
"unist-builder": "^3.0.0",
5158
"unist-util-select": "^4.0.0",
5259
"xo": "^0.38.0"
5360
},
5461
"scripts": {
62+
"prepack": "npm run build && npm run format",
63+
"build": "rimraf \"*.d.ts\" && tsc && type-coverage",
5564
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
5665
"test-api": "node test.js",
5766
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js",
58-
"test": "npm run format && npm run test-coverage"
67+
"test": "npm run build && npm run format && npm run test-coverage"
5968
},
6069
"prettier": {
6170
"tabWidth": 2,
@@ -76,5 +85,10 @@
7685
"plugins": [
7786
"preset-wooorm"
7887
]
88+
},
89+
"typeCoverage": {
90+
"atLeast": 100,
91+
"detail": true,
92+
"strict": true
7993
}
8094
}

test.js

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* @typedef {import('./index.js').KeyFunction} KeyFunction
3+
* @typedef {import('./index.js').TestFunctionAnything} TestFunctionAnything
4+
*/
5+
16
import test from 'tape'
27
import {u} from 'unist-builder'
38
import {select} from 'unist-util-select'
@@ -43,10 +48,12 @@ test('Index', function (t) {
4348

4449
t.end()
4550

51+
/** @type {KeyFunction} */
4652
function keyFn(node) {
4753
return node.id
4854
}
4955

56+
/** @type {TestFunctionAnything} */
5057
function filter(node) {
5158
return node.type === 'a'
5259
}
@@ -193,6 +200,7 @@ test('index.get', function (t) {
193200
sst.deepEqual(index.get('bar'), [select('node[word="bar"]', ast)])
194201
sst.end()
195202

203+
/** @type {TestFunctionAnything} */
196204
function filter(node, index, parent) {
197205
return 'word' in node && index < 2 && parent.type === 'root'
198206
}
@@ -202,15 +210,18 @@ test('index.get', function (t) {
202210
})
203211

204212
t.test('computed keys', function (st) {
213+
/**
214+
* @typedef {{x: number, y: number, z: number}} FunkyNode
215+
*/
216+
205217
var ast = u('root', {x: 0, y: 4, id: 0}, [
206218
u('node', {x: 3, y: 2, id: 1}),
207219
u('node', {x: 2, y: 2, id: 2}),
208220
u('node', {x: 3, y: 1, id: 3}),
209221
u('node', {x: 4, y: 1, id: 4})
210222
])
211-
var index
212-
213-
index = new Index(xPlusY, ast)
223+
// @ts-ignore it’s fine
224+
var index = new Index(xPlusY, ast)
214225
st.deepEqual(index.get(4), [
215226
select('[id=0]', ast),
216227
select('[id=2]', ast),
@@ -219,13 +230,17 @@ test('index.get', function (t) {
219230
st.deepEqual(index.get(0), [])
220231
st.deepEqual(index.get(5), [select('[id=1]', ast), select('[id=4]', ast)])
221232

233+
// @ts-ignore it’s fine
222234
st.deepEqual(new Index(xPlusY, ast, 'node').get(4), [
223235
select('[id=2]', ast),
224236
select('[id=3]', ast)
225237
])
226238

227239
st.end()
228240

241+
/**
242+
* @param {FunkyNode} node
243+
*/
229244
function xPlusY(node) {
230245
return node.x + node.y
231246
}

tsconfig.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"include": ["*.js"],
3+
"compilerOptions": {
4+
"target": "ES2020",
5+
"lib": ["ES2020"],
6+
"module": "ES2020",
7+
"moduleResolution": "node",
8+
"allowJs": true,
9+
"checkJs": true,
10+
"declaration": true,
11+
"emitDeclarationOnly": true,
12+
"allowSyntheticDefaultImports": true,
13+
"skipLibCheck": true
14+
}
15+
}

0 commit comments

Comments
 (0)