1515 */
1616
1717import type * as channels from '@protocol/channels' ;
18+ import type { source } from './isomorphic/utilityScriptSerializers' ;
1819
1920export type Storage = Omit < channels . OriginStorage , 'origin' > ;
2021
21- export async function collect ( ) : Promise < Storage > {
22+ export async function collect ( serializers : ReturnType < typeof source > ) : Promise < Storage > {
2223 const idbResult = await Promise . all ( ( await indexedDB . databases ( ) ) . map ( async dbInfo => {
2324 if ( ! dbInfo . name )
2425 throw new Error ( 'Database name is empty' ) ;
@@ -32,17 +33,53 @@ export async function collect(): Promise<Storage> {
3233 } ) ;
3334 }
3435
36+ function trySerialize ( value : any ) : { trivial ?: any , encoded ?: any } {
37+ let trivial = true ;
38+ const encoded = serializers . serializeAsCallArgument ( value , v => {
39+ const isTrivial = (
40+ v ?. constructor === Object
41+ || Array . isArray ( v )
42+ || typeof v === 'string'
43+ || typeof v === 'number'
44+ || typeof v === 'boolean'
45+ || Object . is ( v , null )
46+ ) ;
47+
48+ if ( ! isTrivial )
49+ trivial = false ;
50+
51+ return { fallThrough : v } ;
52+ } ) ;
53+ if ( trivial )
54+ return { trivial : value } ;
55+ return { encoded } ;
56+ }
57+
3558 const db = await idbRequestToPromise ( indexedDB . open ( dbInfo . name ) ) ;
3659 const transaction = db . transaction ( db . objectStoreNames , 'readonly' ) ;
3760 const stores = await Promise . all ( [ ...db . objectStoreNames ] . map ( async storeName => {
3861 const objectStore = transaction . objectStore ( storeName ) ;
3962
4063 const keys = await idbRequestToPromise ( objectStore . getAllKeys ( ) ) ;
4164 const records = await Promise . all ( keys . map ( async key => {
42- return {
43- key : objectStore . keyPath === null ? key : undefined ,
44- value : await idbRequestToPromise ( objectStore . get ( key ) )
45- } ;
65+ const record : channels . OriginStorage [ 'indexedDB' ] [ 0 ] [ 'stores' ] [ 0 ] [ 'records' ] [ 0 ] = { } ;
66+
67+ if ( objectStore . keyPath === null ) {
68+ const { encoded, trivial } = trySerialize ( key ) ;
69+ if ( trivial )
70+ record . key = trivial ;
71+ else
72+ record . keyEncoded = encoded ;
73+ }
74+
75+ const value = await idbRequestToPromise ( objectStore . get ( key ) ) ;
76+ const { encoded, trivial } = trySerialize ( value ) ;
77+ if ( trivial )
78+ record . value = trivial ;
79+ else
80+ record . valueEncoded = encoded ;
81+
82+ return record ;
4683 } ) ) ;
4784
4885 const indexes = [ ...objectStore . indexNames ] . map ( indexName => {
@@ -81,7 +118,7 @@ export async function collect(): Promise<Storage> {
81118 } ;
82119}
83120
84- export async function restore ( originState : channels . SetOriginStorage ) {
121+ export async function restore ( originState : channels . SetOriginStorage , serializers : ReturnType < typeof source > ) {
85122 for ( const { name, value } of ( originState . localStorage || [ ] ) )
86123 localStorage . setItem ( name , value ) ;
87124
@@ -111,8 +148,8 @@ export async function restore(originState: channels.SetOriginStorage) {
111148 await Promise . all ( store . records . map ( async record => {
112149 await idbRequestToPromise (
113150 objectStore . add (
114- record . value ,
115- objectStore . keyPath === null ? record . key : undefined
151+ record . value ?? serializers . parseEvaluationResultValue ( record . valueEncoded ) ,
152+ record . key ?? serializers . parseEvaluationResultValue ( record . keyEncoded ) ,
116153 )
117154 ) ;
118155 } ) ) ;
0 commit comments