Skip to content

Commit

Permalink
Add .browserslistrc and refactor code to work in target browsers.
Browse files Browse the repository at this point in the history
  • Loading branch information
dero committed Feb 11, 2021
1 parent 4013574 commit 0cefbed
Show file tree
Hide file tree
Showing 8 changed files with 11,016 additions and 109 deletions.
4 changes: 1 addition & 3 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
{
"presets": ["@babel/env"],
"plugins": [
"@babel/plugin-syntax-class-properties"
]
"plugins": []
}
9 changes: 9 additions & 0 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
last 2 Chrome versions
last 2 Android versions
last 2 ChromeAndroid versions
last 2 Firefox versions
last 2 FirefoxAndroid versions
last 2 iOS versions
last 2 Opera versions
last 2 Safari versions
last 2 Samsung versions
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"extends": [
"airbnb-base",
"plugin:jest/recommended",
"plugin:jsdoc/recommended"
"plugin:jsdoc/recommended",
"plugin:compat/recommended"
],
"env": {
"browser": true,
Expand Down
10,904 changes: 10,903 additions & 1 deletion package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
"devDependencies": {
"@babel/eslint-parser": "^7.12.13",
"@babel/eslint-plugin": "^7.12.13",
"@babel/plugin-syntax-class-properties": "^7.12.13",
"@babel/preset-env": "^7.12.13",
"eslint": "^7.18.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-compat": "^3.9.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.1.3",
"eslint-plugin-jsdoc": "^30.7.13",
Expand Down
10 changes: 5 additions & 5 deletions src/js/components/VideoDownloader.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import IDBConnection from '../modules/IDBConnection.module';
import getIDBConnection from '../modules/IDBConnection.module';

const style = `
<style>
Expand Down Expand Up @@ -305,7 +305,7 @@ export default class extends HTMLElement {
async storeVideoChunk({
data, offset, done, mime, sizeInBytes, index, url,
}) {
const db = await IDBConnection.getConnection();
const db = await getIDBConnection();
const size = data ? data.length : 0;

db.meta.put({
Expand Down Expand Up @@ -354,7 +354,7 @@ export default class extends HTMLElement {
* @returns {Promise} Promise that resolves with the last chunk data.
*/
async getLastChunk() {
const db = await IDBConnection.getConnection();
const db = await getIDBConnection();
const rawDb = db.unwrap();
const transaction = rawDb.transaction([db.data.name], 'readonly');
const store = transaction.objectStore(db.data.name);
Expand All @@ -374,7 +374,7 @@ export default class extends HTMLElement {
* @returns {Promise} Promise that resolves with the total video size in bytes.
*/
async getTotalSize() {
const db = await IDBConnection.getConnection();
const db = await getIDBConnection();
const rawDb = db.unwrap();
const transaction = rawDb.transaction([db.data.name], 'readonly');
const store = transaction.objectStore(db.data.name);
Expand Down Expand Up @@ -424,7 +424,7 @@ export default class extends HTMLElement {
* component's `state` and `progress` attribute values.
*/
async _setDownloadState() {
const db = await IDBConnection.getConnection();
const db = await getIDBConnection();
const url = this.getDownloadableURL();
const videoMeta = await db.meta.get(url);

Expand Down
187 changes: 92 additions & 95 deletions src/js/modules/IDBConnection.module.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,120 +38,117 @@ const dataAccessorFactory = (abstractedIDB) => ({
},
});

let dbConnection = null;

/**
* Provides access to video data stored in IDB.
*
* @returns {null|Promise} Promise that resolved with `IDBDatabase` instance.
*/
export default class {
static dbConnection = null
export default () => {
if (dbConnection) return dbConnection;

/**
* @returns {Promise} Resolves to IDBDatabase instance.
* Abstraction on top of raw `IDBDatabase` providing convenience access
* to video meta and data stores.
*
* @param {IDBDatabase} idbConnection Connection to an IDB.
*
* @returns {object} IDB abstraction instance.
*/
static getConnection() {
if (this.dbConnection) return this.dbConnection;

/**
* Abstraction on top of raw `IDBDatabase` providing convenience access
* to video meta and data stores.
*
* @param {IDBDatabase} idbConnection Connection to an IDB.
*
* @returns {object} IDB abstraction instance.
*/
const dbFactory = (idbConnection) => {
const abstractedIDB = new class {
constructor(db) {
this.db = db;
}
const dbFactory = (idbConnection) => {
const abstractedIDB = new class {
constructor(db) {
this.db = db;

unwrap() {
return this.db;
}

defaultAccesor = {
this.defaultAccesor = {
async put(data, storeName) {
const transaction = abstractedIDB.db.transaction([storeName], 'readwrite');
const store = transaction.objectStore(storeName);

return store.put(data);
},
}
}(idbConnection);
};
}

abstractedIDB.meta = metaAccessorFactory(abstractedIDB);
abstractedIDB.data = dataAccessorFactory(abstractedIDB);
unwrap() {
return this.db;
}
}(idbConnection);

return abstractedIDB;
};
abstractedIDB.meta = metaAccessorFactory(abstractedIDB);
abstractedIDB.data = dataAccessorFactory(abstractedIDB);

this.dbConnection = new Promise((resolve, reject) => {
const dbRequest = indexedDB.open(dbName, schemaVersion);
return abstractedIDB;
};

dbRequest.onsuccess = () => resolve(dbFactory(dbRequest.result));
dbRequest.onerror = (e) => reject(e);
dbConnection = new Promise((resolve, reject) => {
const dbRequest = indexedDB.open(dbName, schemaVersion);

dbRequest.onsuccess = () => resolve(dbFactory(dbRequest.result));
dbRequest.onerror = (e) => reject(e);

/**
* @see https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#creating_or_updating_the_version_of_the_database
*
* @param {*} e Event object.
*/
dbRequest.onupgradeneeded = (e) => {
const db = e.target.result;

/**
* @see https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#creating_or_updating_the_version_of_the_database
* The `videoMeta` store holds video metadata related to offline serving.
*
* Example:
*
* Key: sample-video-3
* Value: { done: true, offset: 5524488, videoId: "sample-video-3" }
*
* Value properties:
*
* @param {*} e Event object.
* - done (bool) Whether the video is done downloading.
* - offset (int) Current download progress in bytes.
* - videoId (string) Video ID.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/createObjectStore
*/
dbRequest.onupgradeneeded = (e) => {
const db = e.target.result;

/**
* The `videoMeta` store holds video metadata related to offline serving.
*
* Example:
*
* Key: sample-video-3
* Value: { done: true, offset: 5524488, videoId: "sample-video-3" }
*
* Value properties:
*
* - done (bool) Whether the video is done downloading.
* - offset (int) Current download progress in bytes.
* - videoId (string) Video ID.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/createObjectStore
*/
db.createObjectStore(
STORAGE_SCHEMA.meta.name,
{ keyPath: STORAGE_SCHEMA.meta.key },
);

/**
* The `videoData` store holds actual video data chunks. This one store is used
* to store video data for all offline videos. Keys are auto generated.
*
* Example:
*
* Key: <autogenerated>
* Value: { data: Uint8Array(32547) [...], index: 5, size: 32547, videoId: "video-1" }
*
* Value properties:
*
* - data (Uint8Array) Typed array holding video chunk byte values.
* - index (int) Chunk order in the whole video file.
* - size (int) Chunk size in bytes.
* - videoId (string) Video ID.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/createObjectStore
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
*/
const dataOS = db.createObjectStore(STORAGE_SCHEMA.data.name, { autoIncrement: true });

/**
* Create a `video ID` index in the data store to be able to
* retrieve video data chunks by the `videoId` property later.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#structuring_the_database
*/
dataOS.createIndex('url', 'url', { unique: false });
dataOS.createIndex('index', 'index', { unique: false });
dataOS.createIndex('offset', 'offset', { unique: false });
};
});
db.createObjectStore(
STORAGE_SCHEMA.meta.name,
{ keyPath: STORAGE_SCHEMA.meta.key },
);

/**
* The `videoData` store holds actual video data chunks. This one store is used
* to store video data for all offline videos. Keys are auto generated.
*
* Example:
*
* Key: <autogenerated>
* Value: { data: Uint8Array(32547) [...], index: 5, size: 32547, videoId: "video-1" }
*
* Value properties:
*
* - data (Uint8Array) Typed array holding video chunk byte values.
* - index (int) Chunk order in the whole video file.
* - size (int) Chunk size in bytes.
* - videoId (string) Video ID.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/createObjectStore
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
*/
const dataOS = db.createObjectStore(STORAGE_SCHEMA.data.name, { autoIncrement: true });

/**
* Create a `video ID` index in the data store to be able to
* retrieve video data chunks by the `videoId` property later.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#structuring_the_database
*/
dataOS.createIndex('url', 'url', { unique: false });
dataOS.createIndex('index', 'index', { unique: false });
dataOS.createIndex('offset', 'offset', { unique: false });
};
});

return this.dbConnection;
}
}
return dbConnection;
};
6 changes: 3 additions & 3 deletions src/js/sw/sw.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { SW_CACHE_NAME, STORAGE_SCHEMA } from '../constants';
import IDBConnection from '../modules/IDBConnection.module';
import getIDBConnection from '../modules/IDBConnection.module';

/**
* Respond to a request to fetch offline video and contruct a response stream.
*
* Includes support for `Range` requests.
*
* @param {Request} request Request object.
* @param {IDBConnection} db IDBConnection instance.
* @param {IDBDatabase} db IDBDatabase instance.
* @param {object} metaEntry Video metadata from the IDB.
*
* @returns {Response} Response object.
Expand Down Expand Up @@ -81,7 +81,7 @@ const getResponseStream = (request, db, metaEntry) => {
* @returns {Response|null} Response stream or null.
*/
const maybeGetVideoResponse = async (event) => {
const db = await IDBConnection.getConnection();
const db = await getIDBConnection();
const metaEntry = await db.meta.get(event.request.url);

return metaEntry.done ? getResponseStream(event.request, db, metaEntry) : null;
Expand Down

0 comments on commit 0cefbed

Please sign in to comment.