Module: system/storage-base

Methods

(async, static) initStorage(options) → {Promise.<undefined>}

Parameters:
Name Type Description
options object
Properties
Name Type Attributes Default Description
instanceIdHash SHA256IdHash
wipeStorage boolean <optional>
false

If true all files in storage will be deleted when the instance is initialized. All files means every single file. Storage is wiped clean.

name string <optional>

Platform dependent optional identifier of the storage location. One platform where the file system is used, such as node.js, this is a directory. In browsers this is the name component of the IndexedDB database (the other component is the instance ID hash). If this is a directory, independent of the platform always use "/" as path component separator here. (We have to be flexible handling paths we get from the system, but we have to standardize the paths we use in our cross-platform code.)

nHashCharsForSubDirs number <optional>
0

In "object" storage, the first n characters of o files name - a hexadecimal SHA-256 hash string - are used to locate the file in a subdirectory of that name. For example, if a file name (hash) starts with "0fe123...." and n=2, then the file will be located not in directory objects/ but in directory objects/0f/. This hierarchical storage option is only offered on some platforms. When this option has a number higher than 0 on a platform that does not support it an error is thrown.

storageInitTimeout number <optional>
1000

The browser platform accepts this parameter to time out the indexedDB.open() attempt in case the request blocks (found on Safari). Default is 1000ms. This can or should be used together with one.core/util/promise method retry. On other platforms this parameter is ignored.

encryptStorage boolean <optional>
false

Only if the platform supports it. If set to true all items in all storage spaces are encrypted. Storage space "private" is always encrypted.

secretForStorageKey string | null <optional>

This secret is used to derive a key to be used to en- and decrypt all items in all storage spaces, or only the ones in "private", depending on the value of encryptStorage.

The arguments are different depending on the concrete platform. React Native and node.js want a directory (string), for example, the browser wants a name of an IndexedDB database.

Source:
Throws:

Throws an Error if the first parameter is not a hash

Type: Error

Returns:

Type: Promise.<undefined>

(static) setBaseDirOrName(diropt) → {undefined}

Parameters:
Name Type Attributes Default Description
dir string <optional>
DEFAULT_STORAGE_DIRECTORY

Set the base directory, but it can only be set once. Calling this function again with a different value than the first time causes an error. This is for node.js storage-base mostly, to accommodate and aid users who wish to set a base directory before calling instanceInit, usually to use the SettingsStore before instance initialization. The directory is not created. If SettingsStore is called before instanceInit, which would create all missing directories, and the directory does not exist, then it will throw an error.

Source:
Returns:

Type: undefined

(static) getBaseDirOrName() → {string}

Used by module settings-store at least, meant for any module that needs to write outside and above the instance storage directories under BASE_DIR/INSTANCE_ID/[objects|tmp|vmap|rmap|...].

Also useful if setBaseDirOrName was called without a parameter, so that the default name was used. In that case, if app code wants to find out that default, this function can be called.

Source:
Returns:

Type: string

(async, static) deleteStorage(instanceIdHash) → {Promise.<void>}

Parameters:
Name Type Description
instanceIdHash SHA256IdHash.<Instance>
Source:
Returns:

Type: Promise.<void>

(static) doesStorageExist(instanceIdHash) → {Promise.<boolean>}

Parameters:
Name Type Description
instanceIdHash SHA256IdHash.<Instance>

Checks if the instance exists or not.

Source:
Returns:

Type: Promise.<boolean>

(async, static) readUTF8TextFile(filename, typeopt) → {Promise.<string>}

Parameters:
Name Type Attributes Default Description
filename string
type StorageDirTypes <optional>
'objects'

Read the given file as UTF-8 string. If the file has a bOM it is not stripped.

Source:
Throws:
  • Throws an Error if no filename is given

    Type: Error

  • Throws an Error whose name property is set to FileNotFoundError if the file cannot be found

    Type: Error

Returns:

Type: Promise.<string>

(async, static) readTextFileSection(filename, offset, length, typeopt) → {Promise.<string>}

Parameters:
Name Type Attributes Default Description
filename string
offset number

Where to start reading the UTF-8 encoded file. Depending on how the platform stores text files this is a byte offset (node.js) or a character offset (browser, strings stored in IndexedDB). Those are equal if there is no BOM and the stored string only contains characters from the ASCII character set. If the offset is negative it is counted backwards from the end of the file.

length number

How many bytes to read starting at the given offset (always forward).

type StorageDirTypes <optional>
'objects'

Read a section of the given UTF-8 encoded file as string. If the file has a bOM the offset will be off. If a UTF-8 character used in the file uses more than one byte the offset will be off. That is why unless you calculate the byte offset yourself the byte offset only matches the character offset in the Javascript string representation of the file contents if the file only contains characters from the ASCII-compatible section of UTF-8 codes.

Source:
Throws:
  • Throws an Error if a parameter is missing

    Type: Error

  • Throws an Error whose name property is set to FileNotFoundError if the file cannot be found

    Type: Error

Returns:
  • Returns the given section converted to a Javascript string

Type: Promise.<string>

(async, static) writeUTF8TextFile(contents, filename, typeopt) → {Promise.<FileCreationStatus>}

Parameters:
Name Type Attributes Default Description
contents string
filename string

Plain filename relative to STORAGE_DIR[type]

type StorageDirTypes <optional>
'objects'

Note that existing files will not be overwritten! That is because this function is made for our special context, where all files are stored under their SHA-256 hash as name, so overwriting a file would make no sense.

Source:
Throws:

Throws an Error if no filename and/or no contents is given

Type: Error

Returns:

A promise resolving with the enum-type creation status string (new, exists).

Type: Promise.<FileCreationStatus>

(async, static) writeUTF8SystemMapFile(contents, filename, type) → {Promise.<FileCreationStatus>}

Parameters:
Name Type Description
contents string
filename string

Plain filename relative to STORAGE_DIR[type]

type 'vmaps' | 'rmaps'

Note that existing files will be overwritten! The file is silently created if it does not exist.

Source:
Throws:

Throws an Error if no filename and/or no contents is given, or if the 3rd parameter is not "rmaps" or "vmaps"

Type: Error

Returns:

A promise resolving with the enum-type creation status string (new).

Type: Promise.<FileCreationStatus>

(async, static) appendUTF8SystemMapFile(contents, filename, type) → {Promise.<FileCreationStatus>}

Parameters:
Name Type Description
contents string
filename string

Plain filename without directory

type 'vmaps' | 'rmaps'

This function is reserved for system internal version-map and reverse-map files. This function silently creates the file if it does not exist.

Source:
Throws:

Throws an Error if no filename and/or no contents is given, or if the 3rd parameter is not "rmaps" or "vmaps"

Type: Error

Returns:

A promise resolving with the enum-type creation status string which always is "new" to be consistent with the writeUTF8TextFile() method

Type: Promise.<FileCreationStatus>

(async, static) readPrivateBinaryRaw(filename) → {Promise.<ArrayBuffer>}

Parameters:
Name Type Description
filename string

Reads a binary file from storage space "private". Storage encryption is ignored, the raw file is returned.

Platform difference

On node.js the file's contents always is returned as ArrayBuffer, even if it is a UTF-8 text file. On web browser platforms, using IndexedDB as backend, we store either strings or ArrayBuffer and get exactly that back. To ensure the function always returns only ArrayBuffer, on that platform the function includes a check of the type of the returned object and rejects with an Error if it is not ArrayBuffer.

Source:
Returns:

Type: Promise.<ArrayBuffer>

(static) writePrivateBinaryRaw(filename, contents) → {Promise.<void>}

Parameters:
Name Type Description
filename string
contents ArrayBuffer

Write a binary file from storage space "private". Storage encryption is ignored, the raw ArrayBuffer is written. If the file already exists the promise is rejected with an Error.

Source:
Returns:

Type: Promise.<void>

(async, static) getNCharacters(filename, positionopt, lengthopt) → {Promise.<string>}

Parameters:
Name Type Attributes Default Description
filename string
position number <optional>
0
length number <optional>
100

This function supports the higher-level storage function that determines a stored files type. By default, the first 100 bytes are interpreted as UTF-8 characters and returned, but starting position as well as the number of bytes can be adjusted. If the function reads less than length characters it just returns what it was able to get without raising an exception. If the file was shorter so be it, in the context of our main use case, which is to get the beginning of the microdata string of a ONE object in storage to determine the type, this is not an error condition.

Source:
Throws:
  • Throws an Error if no filename is given

    Type: Error

  • Throws an Error whose name property is set to FileNotFoundError if the file cannot be found

    Type: Error

Returns:

Returns length characters of the contents of the given file.

Type: Promise.<string>

(async, static) exists(filename, typeopt) → {Promise.<boolean>}

Parameters:
Name Type Attributes Default Description
filename string

With full path

type StorageDirTypes <optional>
'objects'
Source:
Throws:

Throws an Error if no filename is given

Type: Error

Returns:

Type: Promise.<boolean>

(async, static) fileSize(filename, typeopt) → {Promise.<boolean>}

Parameters:
Name Type Attributes Default Description
filename string

With full path

type StorageDirTypes <optional>
'objects'

Returns the byte size of an object in storage. When storage encryption is enabled the size will only be an approximate value! The main use case for this function is size-based filters for chum exchange, and for that purpose getting the size within a margin of less than a hundred bytes is good enough. This saves us from having to decrypt the contents just to get the size. While the overhead of encryption is fixed and predictable we also add a random padding, and that is the "approximate" part. We simply always subtract the middle value of the maximum possible padding length.

When using unencrypted storage the correct byte sizes are returned. On node.js that is the "size" property of a Stat object. On the browser, where we use IndexedDb and not files, it is the "byteLength" property of an ArrayBuffer, or the value pf new Blob([stringValue]).size, the now most common way to get a byte length for a string in Javascript.

Source:
Throws:

Throws an Error if no filename is given

Type: Error

Returns:

Type: Promise.<boolean>

(async, static) listAllObjectHashes() → {Promise.<Array.<SHA256Hash>>}

Source:
Returns:

Type: Promise.<Array.<SHA256Hash>>

(async, static) listAllIdHashes() → {Promise.<Array.<SHA256IdHash>>}

Source:
Returns:

Type: Promise.<Array.<SHA256IdHash>>

(async, static) listAllReverseMapNames(prefixopt) → {Promise.<Array.<string>>}

Parameters:
Name Type Attributes Description
prefix string <optional>
Source:
Returns:

Type: Promise.<Array.<string>>

(async, static) getFileType(hash) → {Promise.<(string|'BLOB')>}

Parameters:
Name Type Description
hash SHA256Hash

Hash identifying a ONE object in storage

Reads the first 100 characters of the given object and returns its type. If it is not a ONE object it simply returns "BLOB".

Source:
Returns:

The type string of the given microdata object, or 'BLOB' if the given string does not look like ONE object microdata

Type: Promise.<(string|'BLOB')>

(async, static) changeStoragePassword(oldSecret, newSecret) → {Promise.<void>}

Parameters:
Name Type Description
oldSecret string
newSecret string

When storage encryption is supported this function changes the secret used to encrypt the storage keys. The function is called from instance-change-password's changePassword function.

Source:
Returns:

Type: Promise.<void>