Skip to content
This repository was archived by the owner on Oct 1, 2021. It is now read-only.

Commit 349f3c8

Browse files
authored
feat: add types (#66)
Uses new aegir, swaps protons for protobufjs and adds types. BREAKING CHANGE: where there were previously no types, now there are types
1 parent 425d53c commit 349f3c8

28 files changed

+771
-190
lines changed

.aegir.js

+38-11
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,44 @@
11
'use strict'
22

3-
module.exports = {
4-
karma: {
5-
// multi-bucket pinset migrations are slow
6-
browserNoActivityTimeout: 240 * 1000
7-
},
8-
webpack: {
9-
node: {
10-
// this is needed until level stops using node buffers in browser code
11-
Buffer: true,
3+
const path = require('path')
124

13-
// needed by cbor, binary-parse-stream and nofilter
14-
stream: true
5+
const esbuild = {
6+
// this will inject all the named exports from 'node-globals.js' as globals
7+
inject: [path.join(__dirname, 'scripts/node-globals.js')],
8+
plugins: [
9+
{
10+
name: 'node built ins', // this will make the bundler resolve node builtins to the respective browser polyfill
11+
setup (build) {
12+
build.onResolve({ filter: /^stream$/ }, () => {
13+
return { path: require.resolve('readable-stream') }
14+
})
15+
build.onResolve({ filter: /^multiformats\/hashes\/digest$/ }, () => {
16+
// remove when https://github.com/evanw/esbuild/issues/187 is fixed
17+
return { path: require.resolve('multiformats/hashes/digest') }
18+
})
19+
build.onResolve({ filter: /^multiformats$/ }, () => {
20+
// remove when https://github.com/evanw/esbuild/issues/187 is fixed
21+
return { path: require.resolve('multiformats') }
22+
})
23+
build.onResolve({ filter: /^cborg$/ }, () => {
24+
// remove when https://github.com/evanw/esbuild/issues/187 is fixed
25+
return { path: require.resolve('cborg') }
26+
})
27+
}
1528
}
29+
]
30+
}
31+
32+
/** @type {import('aegir').PartialOptions} */
33+
module.exports = {
34+
test: {
35+
browser: {
36+
config: {
37+
buildConfig: esbuild
38+
}
39+
}
40+
},
41+
build: {
42+
config: esbuild
1643
}
1744
}

.travis.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
language: node_js
22
cache: npm
3+
dist: bionic
34

45
branches:
56
only:
@@ -27,7 +28,6 @@ jobs:
2728
include:
2829
- stage: check
2930
script:
30-
- npx aegir commitlint --travis
3131
- npx aegir dep-check
3232
- npm run lint
3333

@@ -41,7 +41,7 @@ jobs:
4141
name: firefox
4242
addons:
4343
firefox: latest
44-
script: npx aegir test -t browser -- --browsers FirefoxHeadless
44+
script: npx aegir test -t browser -- --browser firefox
4545

4646
- stage: test
4747
name: electron-main

migrations/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
'use strict'
22

3+
/**
4+
* @type {import('../src/types').Migration}
5+
*/
36
const emptyMigration = {
47
description: 'Empty migration.',
8+
// @ts-ignore
59
migrate: () => {},
10+
// @ts-ignore
611
revert: () => {},
712
empty: true
813
}

migrations/migration-10/index.js

+80-19
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,24 @@ const {
44
createStore,
55
findLevelJs
66
} = require('../../src/utils')
7-
const { Key } = require('interface-datastore')
87
const fromString = require('uint8arrays/from-string')
98
const toString = require('uint8arrays/to-string')
109

10+
/**
11+
* @typedef {import('../../src/types').Migration} Migration
12+
* @typedef {import('interface-datastore').Datastore} Datastore
13+
* @typedef {import('../../src/types').MigrationProgressCallback} MigrationProgressCallback
14+
*
15+
* @typedef {{ type: 'del', key: string | Uint8Array } | { type: 'put', key: string | Uint8Array, value: Uint8Array }} Operation
16+
* @typedef {function (string, Uint8Array): Operation[]} UpgradeFunction
17+
* @typedef {function (Uint8Array, Uint8Array): Operation[]} DowngradeFunction
18+
*/
19+
20+
/**
21+
* @param {string} name
22+
* @param {Datastore} store
23+
* @param {(message: string) => void} onProgress
24+
*/
1125
async function keysToBinary (name, store, onProgress = () => {}) {
1226
let db = findLevelJs(store)
1327

@@ -20,14 +34,24 @@ async function keysToBinary (name, store, onProgress = () => {}) {
2034

2135
onProgress(`Upgrading ${name}`)
2236

23-
await withEach(db, (key, value) => {
37+
/**
38+
* @type {UpgradeFunction}
39+
*/
40+
const upgrade = (key, value) => {
2441
return [
2542
{ type: 'del', key: key },
2643
{ type: 'put', key: fromString(key), value: value }
2744
]
28-
})
45+
}
46+
47+
await withEach(db, upgrade)
2948
}
3049

50+
/**
51+
* @param {string} name
52+
* @param {Datastore} store
53+
* @param {(message: string) => void} onProgress
54+
*/
3155
async function keysToStrings (name, store, onProgress = () => {}) {
3256
let db = findLevelJs(store)
3357

@@ -40,14 +64,26 @@ async function keysToStrings (name, store, onProgress = () => {}) {
4064

4165
onProgress(`Downgrading ${name}`)
4266

43-
await withEach(db, (key, value) => {
67+
/**
68+
* @type {DowngradeFunction}
69+
*/
70+
const downgrade = (key, value) => {
4471
return [
4572
{ type: 'del', key: key },
4673
{ type: 'put', key: toString(key), value: value }
4774
]
48-
})
75+
}
76+
77+
await withEach(db, downgrade)
4978
}
5079

80+
/**
81+
*
82+
* @param {string} repoPath
83+
* @param {any} repoOptions
84+
* @param {MigrationProgressCallback} onProgress
85+
* @param {*} fn
86+
*/
5187
async function process (repoPath, repoOptions, onProgress, fn) {
5288
const datastores = Object.keys(repoOptions.storageBackends)
5389
.filter(key => repoOptions.storageBackends[key].name === 'LevelDatastore')
@@ -63,9 +99,14 @@ async function process (repoPath, repoOptions, onProgress, fn) {
6399
await store.open()
64100

65101
try {
66-
await fn(name, store, (message) => {
67-
onProgress(parseInt((migrated / datastores.length) * 100), message)
68-
})
102+
/**
103+
* @param {string} message
104+
*/
105+
const progress = (message) => {
106+
onProgress(Math.round((migrated / datastores.length) * 100), message)
107+
}
108+
109+
await fn(name, store, progress)
69110
} finally {
70111
migrated++
71112
store.close()
@@ -75,6 +116,7 @@ async function process (repoPath, repoOptions, onProgress, fn) {
75116
onProgress(100, `Migrated ${datastores.length} dbs`)
76117
}
77118

119+
/** @type {Migration} */
78120
module.exports = {
79121
version: 10,
80122
description: 'Migrates datastore-level keys to binary',
@@ -87,23 +129,25 @@ module.exports = {
87129
}
88130

89131
/**
90-
* @typedef {Uint8Array|string} Key
91-
* @typedef {Uint8Array} Value
92-
* @typedef {{ type: 'del', key: Key } | { type: 'put', key: Key, value: Value }} Operation
93-
*
94132
* Uses the upgrade strategy from [email protected] - note we can't call the `.upgrade` command
95133
* directly because it will be removed in [email protected] and we can't guarantee users will
96134
* have migrated by then - e.g. they may jump from [email protected] straight to [email protected]
97135
* so we have to duplicate the code here.
98136
*
99-
* @param {import('interface-datastore').Datastore} db
100-
* @param {function (Key, Value): Operation[]} fn
137+
* @param {any} db
138+
* @param {UpgradeFunction | DowngradeFunction} fn
139+
* @return {Promise<void>}
101140
*/
102141
function withEach (db, fn) {
142+
/**
143+
* @param {Operation[]} operations
144+
* @param {(error?: Error) => void} next
145+
*/
103146
function batch (operations, next) {
104147
const store = db.store('readwrite')
105148
const transaction = store.transaction
106149
let index = 0
150+
/** @type {Error | undefined} */
107151
let error
108152

109153
transaction.onabort = () => next(error || transaction.error || new Error('aborted by user'))
@@ -132,26 +176,43 @@ function withEach (db, fn) {
132176
return new Promise((resolve, reject) => {
133177
const it = db.iterator()
134178
// raw keys and values only
135-
it._deserializeKey = it._deserializeValue = (data) => data
179+
/**
180+
* @template T
181+
* @param {T} data
182+
*/
183+
const id = (data) => data
184+
it._deserializeKey = it._deserializeValue = id
136185
next()
137186

138187
function next () {
139-
it.next((err, key, value) => {
188+
/**
189+
* @param {Error | undefined} err
190+
* @param {string | undefined} key
191+
* @param {Uint8Array} value
192+
*/
193+
const handleNext = (err, key, value) => {
140194
if (err || key === undefined) {
141-
it.end((err2) => {
195+
/**
196+
* @param {Error | undefined} err2
197+
*/
198+
const handleEnd = (err2) => {
142199
if (err2) {
143200
reject(err2)
144201
return
145202
}
146203

147204
resolve()
148-
})
205+
}
206+
207+
it.end(handleEnd)
149208

150209
return
151210
}
152211

212+
// @ts-ignore
153213
batch(fn(key, value), next)
154-
})
214+
}
215+
it.next(handleNext)
155216
}
156217
})
157218
}

migrations/migration-8/index.js

+27-14
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ const uint8ArrayToString = require('uint8arrays/to-string')
88
const { createStore } = require('../../src/utils')
99
const length = require('it-length')
1010

11+
/**
12+
* @typedef {import('../../src/types').Migration} Migration
13+
*/
14+
15+
/**
16+
* @param {Key} key
17+
*/
1118
function keyToMultihash (key) {
1219
const buf = mb.decode(`b${key.toString().slice(1)}`)
1320

@@ -18,11 +25,14 @@ function keyToMultihash (key) {
1825
multihash = mb.encode('base32', multihash).slice(1)
1926

2027
// Should be uppercase for interop with go
21-
multihash = uint8ArrayToString(multihash).toUpperCase()
28+
const multihashStr = uint8ArrayToString(multihash).toUpperCase()
2229

23-
return new Key(`/${multihash}`, false)
30+
return new Key(`/${multihashStr}`, false)
2431
}
2532

33+
/**
34+
* @param {Key} key
35+
*/
2636
function keyToCid (key) {
2737
const buf = mb.decode(`b${key.toString().slice(1)}`)
2838

@@ -32,22 +42,26 @@ function keyToCid (key) {
3242
return new Key(`/${uint8ArrayToString(multihash)}`.toUpperCase(), false)
3343
}
3444

45+
/**
46+
* @param {string} repoPath
47+
* @param {*} repoOptions
48+
* @param {(percent: number, message: string) => void} onProgress
49+
* @param {(key: Key) => Key} keyFunction
50+
*/
3551
async function process (repoPath, repoOptions, onProgress, keyFunction) {
3652
const blockstore = createStore(repoPath, 'blocks', repoOptions)
3753
await blockstore.open()
3854

3955
let blockCount
4056

41-
if (onProgress) {
42-
blockCount = await length(blockstore.query({
43-
keysOnly: true,
44-
filters: [({ key }) => {
45-
const newKey = keyFunction(key)
57+
blockCount = await length(blockstore.query({
58+
keysOnly: true,
59+
filters: [({ key }) => {
60+
const newKey = keyFunction(key)
4661

47-
return newKey.toString() !== key.toString()
48-
}]
49-
}))
50-
}
62+
return newKey.toString() !== key.toString()
63+
}]
64+
}))
5165

5266
try {
5367
let counter = 0
@@ -62,16 +76,15 @@ async function process (repoPath, repoOptions, onProgress, keyFunction) {
6276
await blockstore.delete(block.key)
6377
await blockstore.put(newKey, block.value)
6478

65-
if (onProgress) {
66-
onProgress((counter / blockCount) * 100, `Migrated Block from ${block.key} to ${newKey}`)
67-
}
79+
onProgress((counter / blockCount) * 100, `Migrated Block from ${block.key} to ${newKey}`)
6880
}
6981
}
7082
} finally {
7183
await blockstore.close()
7284
}
7385
}
7486

87+
/** @type {Migration} */
7588
module.exports = {
7689
version: 8,
7790
description: 'Transforms key names into base32 encoding and converts Block store to use bare multihashes encoded as base32',

0 commit comments

Comments
 (0)