Skip to content

Commit

Permalink
fix: serialization #130 (#131)
Browse files Browse the repository at this point in the history
* fix: serialization #130

* fix: serialization

* fix: serialization improvements
  • Loading branch information
tomicvladan authored Apr 18, 2023
1 parent 5c0f0cd commit 12dfca3
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 34 deletions.
22 changes: 12 additions & 10 deletions library/src/proxy/fdp-storage.proxy.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,25 @@ import { FdpStorage, PersonalStorage } from '../model/fdp-storage.model'
import {
isSerializedUint8Array,
uint8ArrayToSerializedParameter,
stringToUint8Array,
base64ToUint8Array,
isUint8Array,
} from '../utils/serialization'

function serializeParameters(parameters: unknown[]): unknown[] {
return parameters.map(parameter => {
if (isUint8Array(parameter)) {
return uint8ArrayToSerializedParameter(parameter)
}
function serializeParameters(parameters: unknown[]): Promise<unknown[]> {
return Promise.all(
parameters.map(async parameter => {
if (isUint8Array(parameter)) {
return await uint8ArrayToSerializedParameter(parameter)
}

return parameter
})
return parameter
}),
)
}

function deserializeResponse(response: unknown): unknown {
if (isSerializedUint8Array(response)) {
return stringToUint8Array(response.value)
return base64ToUint8Array(response.value)
}

return response
Expand All @@ -36,7 +38,7 @@ function createProxy<T extends object>(path: string, messages: BlossomMessages):
return async (...parameters: unknown[]) => {
const response = await messages.sendMessage(ApiActions.FDP_STORAGE, {
accessor: `${path}.${property}`,
parameters: serializeParameters(parameters),
parameters: await serializeParameters(parameters),
} as FdpStorageRequest)

return deserializeResponse(response)
Expand Down
30 changes: 24 additions & 6 deletions library/src/utils/serialization.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { BytesMessage } from '../model/serialized-message-data'

const BASE64_MIME_TYPE = 'data:application/octet-stream;base64,'

export function isUint8Array(data: unknown): data is Uint8Array {
return ArrayBuffer.isView(data)
}
Expand All @@ -10,17 +12,33 @@ export function isSerializedUint8Array(data: unknown): data is BytesMessage {
return type === 'bytes' && typeof value === 'string'
}

export function uint8ArrayToString(bytes: Uint8Array): string {
return new TextDecoder().decode(bytes)
function convertBlobToBase64(blob: Blob): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(blob)
reader.onloadend = () => resolve(reader.result as string)
reader.onerror = error => reject(error)
})
}

export function uint8ArrayToBase64(bytes: Uint8Array): Promise<string> {
return convertBlobToBase64(new Blob([bytes]))
}

export function stringToUint8Array(serializedBytes: string): Uint8Array {
return new TextEncoder().encode(serializedBytes)
export function base64ToUint8Array(base64String: string): Uint8Array {
return Uint8Array.from(
atob(
base64String.startsWith(BASE64_MIME_TYPE)
? base64String.substring(BASE64_MIME_TYPE.length)
: base64String,
),
c => c.charCodeAt(0),
)
}

export function uint8ArrayToSerializedParameter(bytes: Uint8Array): BytesMessage {
export async function uint8ArrayToSerializedParameter(bytes: Uint8Array): Promise<BytesMessage> {
return {
type: 'bytes',
value: uint8ArrayToString(bytes),
value: await uint8ArrayToBase64(bytes),
}
}
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions src/services/fdp-storage/fdp-storage-access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { isSerializedUint8Array, isString } from '../../messaging/message.assert
import { DappId } from '../../model/general.types'
import { Dapp } from '../../model/storage/dapps.model'
import { isPromise, isUint8Array } from '../../utils/asserts'
import { stringToUint8Array, uint8ArrayToSerializedParameter } from '../../utils/converters'
import { base64ToUint8Array, uint8ArrayToSerializedParameter } from '../../utils/converters'
import { dappIdToPodName } from './fdp-storage.utils'

type FdpStorageHandler = (
Expand All @@ -25,16 +25,16 @@ type FdpStorageProxy = {
function deserializeParameters(parameters: unknown[]): unknown[] {
return parameters.map((parameter) => {
if (isSerializedUint8Array(parameter)) {
return stringToUint8Array(parameter.value)
return base64ToUint8Array(parameter.value)
}

return parameter
})
}

function serializeResponse(response: unknown): unknown {
async function serializeResponse(response: unknown): Promise<unknown> {
if (isUint8Array(response)) {
return uint8ArrayToSerializedParameter(response)
return await uint8ArrayToSerializedParameter(response)
}

return response
Expand Down Expand Up @@ -145,7 +145,7 @@ export function callFdpStorageMethod(
try {
const result = await response

resolve(serializeResponse(result))
resolve(await serializeResponse(result))
} catch (error) {
reject(error)
}
Expand Down
2 changes: 1 addition & 1 deletion src/services/storage/storage-migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ export async function migrate(newVersionString: string): Promise<void> {
await updateObject<AccountDapps>(Storage.dappsKey, updatedAccountDapps)
}

await this.setStorageVesion(newVersionString)
await storage.setStorageVesion(newVersionString)
}
30 changes: 24 additions & 6 deletions src/utils/converters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { isString } from '../messaging/message.asserts'
import { BytesMessage } from '../messaging/scripts.messaging'
import { Version } from '../model/storage/version.model'

const BASE64_MIME_TYPE = 'data:application/octet-stream;base64,'

export function versionFromString(version: string): Version {
if (!isString(version)) {
throw new Error('Invalid version string')
Expand Down Expand Up @@ -36,17 +38,33 @@ export function versionToString(version: Version): string {
return `${major}.${minor}.${patch}`
}

export function uint8ArrayToString(bytes: Uint8Array): string {
return new TextDecoder().decode(bytes)
function convertBlobToBase64(blob: Blob): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(blob)
reader.onloadend = () => resolve(reader.result as string)
reader.onerror = (error) => reject(error)
})
}

export function uint8ArrayToBase64(bytes: Uint8Array): Promise<string> {
return convertBlobToBase64(new Blob([bytes]))
}

export function stringToUint8Array(serializedBytes: string): Uint8Array {
return new TextEncoder().encode(serializedBytes)
export function base64ToUint8Array(base64String: string): Uint8Array {
return Uint8Array.from(
atob(
base64String.startsWith(BASE64_MIME_TYPE)
? base64String.substring(BASE64_MIME_TYPE.length)
: base64String,
),
(c) => c.charCodeAt(0),
)
}

export function uint8ArrayToSerializedParameter(bytes: Uint8Array): BytesMessage {
export async function uint8ArrayToSerializedParameter(bytes: Uint8Array): Promise<BytesMessage> {
return {
type: 'bytes',
value: uint8ArrayToString(bytes),
value: await uint8ArrayToBase64(bytes),
}
}

0 comments on commit 12dfca3

Please sign in to comment.