@@ -4,10 +4,24 @@ const {
44 createStore,
55 findLevelJs
66} = require ( '../../src/utils' )
7- const { Key } = require ( 'interface-datastore' )
87const fromString = require ( 'uint8arrays/from-string' )
98const 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+ */
1125async 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+ */
3155async 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+ */
5187async 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 } */
78120module . 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 */
102141function 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}
0 commit comments