@@ -12,11 +12,12 @@ https://github.com/curiousdannii/asyncglk
12
12
import { decode as base32768_decode , encode as base32768_encode } from 'base32768'
13
13
14
14
import { DirBrowser , NullProvider } from './common.js'
15
- import type { Provider } from './interface.js'
15
+ import type { FilesMetadata , Provider } from './interface.js'
16
16
17
17
//type WebStorageFileMetadata = Pick<FileData, 'atime' | 'mtime'>
18
18
19
19
const METADATA_KEY = 'dialog_metadata'
20
+ const STORAGE_VERSION_KEY = 'dialog_storage_version'
20
21
21
22
const enum MetadataUpdateOperation {
22
23
DELETE = 1 ,
@@ -35,7 +36,9 @@ export class WebStorageProvider implements Provider {
35
36
this . prefix = prefix
36
37
this . store = store
37
38
38
- // TODO: upgrade storage
39
+ if ( store === localStorage ) {
40
+ migrate_localStorage ( )
41
+ }
39
42
}
40
43
41
44
async browse ( ) : Promise < DirBrowser > {
@@ -99,7 +102,7 @@ export class WebStorageProvider implements Provider {
99
102
100
103
private update_metadata ( path : string , op : MetadataUpdateOperation ) {
101
104
const now = Date . now ( )
102
- const metadata = this . metadata ( )
105
+ const metadata : FilesMetadata = this . metadata ( )
103
106
switch ( op ) {
104
107
case MetadataUpdateOperation . DELETE :
105
108
delete metadata [ path ]
@@ -118,4 +121,48 @@ export class WebStorageProvider implements Provider {
118
121
}
119
122
this . store . setItem ( METADATA_KEY , JSON . stringify ( metadata ) )
120
123
}
124
+ }
125
+
126
+ const DIALOG_V1_TYPES_TO_EXTS : Record < string , string > = {
127
+ data : 'glkdata' ,
128
+ save : 'glksave' ,
129
+ transcript : 'txt' ,
130
+ }
131
+ export function migrate_localStorage ( ) {
132
+ const now = Date . now ( )
133
+ const version = parseInt ( localStorage . getItem ( STORAGE_VERSION_KEY ) || '' , 10 )
134
+ if ( version < 2 ) {
135
+ console . log ( 'Dialog: updating localStorage to version 2' )
136
+ const metadata : FilesMetadata = { }
137
+ for ( let [ key , data ] of Object . entries < string > ( localStorage ) ) {
138
+ if ( key . startsWith ( 'autosave:' ) ) {
139
+ // We're not keeping any old autosaves
140
+ localStorage . removeItem ( key )
141
+ }
142
+ if ( key . startsWith ( 'content:' ) ) {
143
+ const key_data = / ^ c o n t e n t : ( \w + ) : ( \w * ) : ( .+ ) $ / . exec ( key )
144
+ if ( key_data ) {
145
+ const path = `/usr/${ key_data [ 3 ] } .${ DIALOG_V1_TYPES_TO_EXTS [ key_data [ 1 ] ] || key_data [ 1 ] } `
146
+ if ( data !== '' && version < 1 ) {
147
+ data = base32768_encode ( / \[ [ , \d ] * \] / . test ( data ) ? JSON . parse ( data ) : Uint8Array . from ( data , ch => ch . charCodeAt ( 0 ) ) )
148
+ }
149
+ localStorage . setItem ( path , data )
150
+ const dirent_key = 'dirent' + key . substring ( 7 )
151
+ const dirent = localStorage . getItem ( dirent_key ) || ''
152
+ const dirent_data = / ^ c r e a t e d : \d + , m o d i f i e d : ( \d + ) $ / . exec ( dirent )
153
+ metadata [ path ] = {
154
+ atime : parseInt ( dirent_data ?. [ 1 ] || '' , 10 ) || now ,
155
+ mtime : parseInt ( dirent_data ?. [ 1 ] || '' , 10 ) || now ,
156
+ }
157
+ localStorage . removeItem ( dirent_key )
158
+ }
159
+ localStorage . removeItem ( key )
160
+ }
161
+ }
162
+ localStorage . setItem ( METADATA_KEY , JSON . stringify ( metadata ) )
163
+ localStorage . setItem ( STORAGE_VERSION_KEY , '2' )
164
+ }
165
+ if ( version > 2 ) {
166
+ throw new Error ( 'dialog_storage_version is newer than this library supports' )
167
+ }
121
168
}
0 commit comments