Skip to content

Commit 7201b76

Browse files
use iterative for migration
1 parent 7f0aa10 commit 7201b76

1 file changed

Lines changed: 37 additions & 17 deletions

File tree

src/fs_impl/localstorage.ts

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ export class LocalStorageFS extends AbstractFileSystem {
472472

473473
if (!migrations.array_to_b64) {
474474
// eslint-disable-next-line @typescript-eslint/no-use-before-define
475-
migrate_old_array_fs(JSON.parse(localStorage.getItem("fs")), true);
475+
migrate_old_array_fs(JSON.parse(localStorage.getItem("fs")));
476476
}
477477

478478
// mark all migrations as done
@@ -491,6 +491,7 @@ const migrate_old_string_fs = (state: object, is_outer = false) => {
491491
// migration step: we used to use a string but now we use an array for files
492492
// need to iterate DEEPLY into nested objects and convert string values to arrays
493493
// (so recurse)
494+
// TODO make iterative
494495

495496
for (const key of Object.keys(state)) {
496497
if (typeof state[key] === "object" && !Array.isArray(state[key])) {
@@ -507,26 +508,45 @@ const migrate_old_string_fs = (state: object, is_outer = false) => {
507508
}
508509
}
509510

510-
const migrate_old_array_fs = (state: object, is_outer = false) => {
511-
// migration step: we used to use an array for files but now we use base64 strings (not the same as old comma string format)
511+
const migrate_old_array_fs = (state: object) => {
512+
// migration step: we used to use an array for files but now we use base64 strings
512513
// need to iterate DEEPLY into nested objects and convert array values to strings
513-
// (so recurse)
514514

515-
for (const key of Object.keys(state)) {
516-
if (typeof state[key] === "object" && !Array.isArray(state[key])) {
517-
migrate_old_array_fs(state[key]);
518-
} else if (Array.isArray(state[key])) {
519-
console.log(`Migration: converting ${key} to byte string`);
515+
// use a stack to avoid recursion limit issues
516+
const stack = [state];
517+
518+
while (stack.length > 0) {
519+
// get the next object to process
520+
const current_obj = stack.pop();
520521

521-
const values = state[key].map((x: string) => parseInt(x));
522-
const uint = new Uint8Array(values);
523-
// uint.toBase64() isnt mainstream yet
524-
state[key] = btoa(String.fromCharCode.apply(null, uint));
522+
if (current_obj === null || typeof current_obj !== "object" || Array.isArray(current_obj)) {
523+
continue;
525524
}
526-
}
527525

528-
if (is_outer) {
529-
// only save if we are at the outermost level
530-
localStorage.setItem("fs", JSON.stringify(state));
526+
// iterate over the keys of the current object
527+
for (const key of Object.keys(current_obj)) {
528+
const value = current_obj[key];
529+
530+
if (!value) {
531+
continue;
532+
} else if (typeof value === "object" && !Array.isArray(value)) {
533+
// if the value is a nested object, add it to the stack to be processed later (depth first)
534+
stack.push(value);
535+
} else if (Array.isArray(value)) {
536+
console.log(`Migration: converting ${key} to b64 string`);
537+
538+
try {
539+
const values = value.map((x: string) => parseInt(x));
540+
const uint = new Uint8Array(values);
541+
// uint.toBase64() isnt mainstream yet
542+
current_obj[key] = btoa(String.fromCharCode.apply(null, uint));
543+
} catch (e) {
544+
console.error(`Migration failed for key "${key}":`, e);
545+
}
546+
}
547+
}
531548
}
549+
550+
// only save after the whole traversal
551+
localStorage.setItem("fs", JSON.stringify(state));
532552
}

0 commit comments

Comments
 (0)