Botmation Documentation
IndexedDB
IndexedDB
These BotAction's interact with the Page's IndexedDB.
Except for the assembling indexedDBStore()(), these BotAction's are BotIndexedDBAction's. They are designed to accept customization through their higher-order params, injects, and even piping.
Higher-order params override all. Piping params override injects. Therefore, injects is a nice way to set the defaults for the majority, then on a case by case basis, can be overrideen by either other way.
IndexedDBStore
This sets the first few injects for BotIndexedDBAction's.
const indexedDBStore = (databaseName: string, storeName: string, databaseVersion?: number) => (...actions: BotAction<PipeValue|void>[]): BotAction<any> => pipe()( inject(databaseVersion, databaseName, storeName)( ...actions ) )
The second call assembles all BotAction's for running in a Pipe with the databaseVersion
, databaseName
, and storeName
injected, in that order.
This is not required, in order to assemble BotIndexedDBAction's. It simply allows you to express those injected values once, for the assembled BotAction's.
For an usage example, see the Instagram isGuest BotAction.
Set IndexedDB Value
This sets a value by key in a Store for a particular Database name and optionally version.
The storeName
, databaseName
, databaseVersion
can be passed through their higher-order params or by injecting. Higher-order params override injected ones.
The key
and value
can be passed through their higher-order params or by piping. Higher-order params override piped values.
const setIndexedDBValue = (key?: string, value?: any, storeName?: string, databaseName?: string, databaseVersion?: number): BotIndexedDBAction<void> => async(page, ...injects) => { const [pipedValue, injectDatabaseVersion, injectDatabaseName, injectStoreName] = unpipeInjects<getQueryKeyValue>(injects, 3) if (!value) { if (pipedValue) { if (isObjectWithValue(pipedValue)) { value = pipedValue.value } else { value = pipedValue } } } if (!key) { if (isObjectWithKey(pipedValue)) { key = pipedValue.key } } await page.evaluate( setIndexedDBStoreValue, databaseName ? databaseName : injectDatabaseName ? injectDatabaseName : 'missing-db-name', databaseVersion ? databaseVersion : injectDatabaseVersion ? injectDatabaseVersion : undefined, storeName ? storeName : injectStoreName ? injectStoreName : 'missing-store', key ? key : 'missing-key', value ? value : 'missing-value' ) }
If a value is missing to complete the operation, a safe
missing-*
default is used.
For an usage example, see Pipe BotAction.
Get IndexedDB Value
This gets a value by key in a Store for a particular Database name and optionally version.
The storeName
, databaseName
, databaseVersion
can be passed through their higher-order params or by injecting. Higher-order params override injected ones.
The key
and value
can be passed through their higher-order params or by piping. Higher-order params override piped values.
const getIndexedDBValue = (key?: string, storeName?: string, databaseName?: string, databaseVersion?: number): BotIndexedDBAction<PipeValue> => async(page, ...injects) => { const [pipeValue, injectDatabaseVersion, injectDatabaseName, injectStoreName] = unpipeInjects<getQueryKey>(injects, 3) if (!key) { if (pipeValue) { if (isObjectWithKey(pipeValue)) { key = pipeValue.key } else { key = pipeValue } } } return page.evaluate( getIndexedDBStoreValue, databaseName ? databaseName : injectDatabaseName ? injectDatabaseName : 'missing-db-name', databaseVersion ? databaseVersion : injectDatabaseVersion ? injectDatabaseVersion : undefined, storeName ? storeName : injectStoreName ? injectStoreName : 'missing-store', key ? key : 'missing-key' ) as PipeValue }
If a value is missing to complete the operation, a safe
missing-*
default is used.
For an usage example, see the Instagram isGuest BotAction.
Helpers
In order to interact with IndexedDB in the Puppeteer Page, separate functions need to be "evaluated" in the Page. Therefore, the following Helper functions are setup as if running inside a Browser Page, instead of NodeJS.
If you
console.log()
in an evaluated Page function, don't look for it in NodeJS's console, but the Puppeteer Page's console.
setIndexedDBStoreValue()
function setIndexedDBStoreValue(databaseName: string, databaseVersion: number, storeName: string, key: string, value: any) { return new Promise((resolve, reject) => { const openRequest = indexedDB.open(databaseName, databaseVersion) openRequest.onerror = function(this: IDBRequest<IDBDatabase>, ev: Event) { ev.stopPropagation() return reject(this.error) } openRequest.onupgradeneeded = function(this: IDBOpenDBRequest, ev: IDBVersionChangeEvent): any { if (!this.result.objectStoreNames.contains(storeName)) { this.result.createObjectStore(storeName) } } openRequest.onsuccess = function(this: IDBRequest<IDBDatabase>, ev: Event) { const db = this.result try { db.transaction(storeName, 'readwrite') .objectStore(storeName) .put(value, key) .onsuccess = function(this, ev) { db.close() return resolve() } } catch (error) { db.close() return reject(error) } } })}
getIndexedDBStoreValue()
function getIndexedDBStoreValue(databaseName: string, databaseVersion: number, storeName: string, key: string) { return new Promise((resolve, reject) => { const openRequest = indexedDB.open(databaseName, databaseVersion) openRequest.onerror = function(this: IDBRequest<IDBDatabase>, ev: Event) { return reject(this.error) } openRequest.onsuccess = function(this: IDBRequest<IDBDatabase>, ev: Event) { const db = this.result try { const tx = db.transaction(storeName, 'readonly') .objectStore(storeName) .get(key) tx.onsuccess = function(this: IDBRequest<any>, ev: Event) { const result = this.result db.close() return resolve(result) } } catch (error) { db.close() return reject(error) } } })}