mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 21:27:05 +00:00
core ran in a worker thread
This commit is contained in:
parent
73d6213427
commit
de9577efe5
6 changed files with 102 additions and 38 deletions
|
|
@ -5,24 +5,22 @@ const React = require('react');
|
||||||
const { Router } = require('stremio-router');
|
const { Router } = require('stremio-router');
|
||||||
const { Core, Shell, Chromecast, KeyboardShortcuts, ServicesProvider } = require('stremio/services');
|
const { Core, Shell, Chromecast, KeyboardShortcuts, ServicesProvider } = require('stremio/services');
|
||||||
const { NotFound } = require('stremio/routes');
|
const { NotFound } = require('stremio/routes');
|
||||||
const { ToastProvider, sanitizeLocationPath, CONSTANTS } = require('stremio/common');
|
const { ToastProvider, CONSTANTS } = require('stremio/common');
|
||||||
const CoreEventsToaster = require('./CoreEventsToaster');
|
const CoreEventsToaster = require('./CoreEventsToaster');
|
||||||
const ErrorDialog = require('./ErrorDialog');
|
const ErrorDialog = require('./ErrorDialog');
|
||||||
const routerViewsConfig = require('./routerViewsConfig');
|
const routerViewsConfig = require('./routerViewsConfig');
|
||||||
const styles = require('./styles');
|
const styles = require('./styles');
|
||||||
|
|
||||||
window.core_imports = {
|
|
||||||
app_version: process.env.VERSION,
|
|
||||||
shell_version: null,
|
|
||||||
sanitize_location_path: sanitizeLocationPath
|
|
||||||
};
|
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const onPathNotMatch = React.useCallback(() => {
|
const onPathNotMatch = React.useCallback(() => {
|
||||||
return NotFound;
|
return NotFound;
|
||||||
}, []);
|
}, []);
|
||||||
const services = React.useMemo(() => ({
|
const services = React.useMemo(() => ({
|
||||||
core: new Core(),
|
core: new Core({
|
||||||
|
baseURI: document.baseURI,
|
||||||
|
appVersion: process.env.VERSION,
|
||||||
|
shellVersion: null
|
||||||
|
}),
|
||||||
shell: new Shell(),
|
shell: new Shell(),
|
||||||
chromecast: new Chromecast(),
|
chromecast: new Chromecast(),
|
||||||
keyboardShortcuts: new KeyboardShortcuts()
|
keyboardShortcuts: new KeyboardShortcuts()
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
const EventEmitter = require('eventemitter3');
|
const EventEmitter = require('eventemitter3');
|
||||||
const CoreTransport = require('./CoreTransport');
|
const CoreTransport = require('./CoreTransport');
|
||||||
|
|
||||||
function Core() {
|
function Core(args) {
|
||||||
let active = false;
|
let active = false;
|
||||||
let error = null;
|
let error = null;
|
||||||
let starting = false;
|
let starting = false;
|
||||||
|
|
@ -66,7 +66,7 @@ function Core() {
|
||||||
}
|
}
|
||||||
|
|
||||||
starting = true;
|
starting = true;
|
||||||
transport = new CoreTransport();
|
transport = new CoreTransport(args);
|
||||||
transport.on('init', onTransportInit);
|
transport.on('init', onTransportInit);
|
||||||
transport.on('error', onTransportError);
|
transport.on('error', onTransportError);
|
||||||
onStateChanged();
|
onStateChanged();
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,22 @@
|
||||||
// Copyright (C) 2017-2022 Smart code 203358507
|
// Copyright (C) 2017-2022 Smart code 203358507
|
||||||
|
|
||||||
const EventEmitter = require('eventemitter3');
|
const EventEmitter = require('eventemitter3');
|
||||||
const { default: initialize_api, initialize_runtime, get_state, get_debug_state, dispatch, analytics, decode_stream } = require('@stremio/stremio-core-web');
|
const Bridge = require('./bridge');
|
||||||
|
|
||||||
function CoreTransport() {
|
function CoreTransport(args) {
|
||||||
const events = new EventEmitter();
|
const events = new EventEmitter();
|
||||||
|
const worker = new Worker(`${process.env.COMMIT_HASH}/scripts/worker.js`);
|
||||||
|
const bridge = new Bridge(worker, window);
|
||||||
|
|
||||||
initialize_api(require('@stremio/stremio-core-web/stremio_core_web_bg.wasm'))
|
window.onCoreEvent = ({ name, args }) => {
|
||||||
.then(() => initialize_runtime(({ name, args }) => {
|
try {
|
||||||
try {
|
events.emit(name, args);
|
||||||
events.emit(name, args);
|
} catch (error) {
|
||||||
} catch (error) {
|
console.error('CoreTransport', error);
|
||||||
console.error('CoreTransport', error);
|
}
|
||||||
}
|
};
|
||||||
}))
|
|
||||||
|
bridge.call(['init'], [args])
|
||||||
.then(() => {
|
.then(() => {
|
||||||
try {
|
try {
|
||||||
events.emit('init');
|
events.emit('init');
|
||||||
|
|
@ -35,27 +38,19 @@ function CoreTransport() {
|
||||||
events.removeAllListeners();
|
events.removeAllListeners();
|
||||||
};
|
};
|
||||||
this.getState = async function(field) {
|
this.getState = async function(field) {
|
||||||
return Promise.resolve(get_state(field));
|
return bridge.call(['getState'], [field]);
|
||||||
};
|
};
|
||||||
this.getDebugState = function() {
|
this.getDebugState = async function() {
|
||||||
return get_debug_state();
|
return bridge.call(['getDebugState'], []);
|
||||||
};
|
};
|
||||||
this.dispatch = function(action, field) {
|
this.dispatch = async function(action, field) {
|
||||||
try {
|
return bridge.call(['dispatch'], [action, field, location.hash]);
|
||||||
dispatch(action, field);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('CoreTransport', error);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
this.analytics = function(event) {
|
this.analytics = async function(event) {
|
||||||
try {
|
return bridge.call(['analytics'], [event, location.hash]);
|
||||||
analytics(event);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('CoreTransport', error);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
this.decodeStream = function(stream) {
|
this.decodeStream = async function(stream) {
|
||||||
return decode_stream(stream);
|
return bridge.call(['decodeStream'], [stream]);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
45
src/services/Core/bridge.js
Normal file
45
src/services/Core/bridge.js
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
function getId() {
|
||||||
|
return Math.random().toString(32).slice(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Bridge(context, scope) {
|
||||||
|
context.addEventListener('message', async ({ data: { request } }) => {
|
||||||
|
if (!request) return;
|
||||||
|
|
||||||
|
const { id, path, args } = request;
|
||||||
|
try {
|
||||||
|
const object = path.reduce((obj, prop) => obj[prop], scope);
|
||||||
|
let data;
|
||||||
|
if (typeof object === 'function') {
|
||||||
|
const thisArg = path.slice(0, path.length - 1).reduce((obj, prop) => obj[prop], scope);
|
||||||
|
data = await object.apply(thisArg, args);
|
||||||
|
} else {
|
||||||
|
data = await object;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.postMessage({ response: { id, result: { data } } });
|
||||||
|
} catch (error) {
|
||||||
|
context.postMessage({ response: { id, result: { error } } });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.call = async (path, args) => {
|
||||||
|
const id = getId();
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const onMessage = ({ data: { response } }) => {
|
||||||
|
if (!response || response.id !== id) return;
|
||||||
|
|
||||||
|
context.removeEventListener('message', onMessage);
|
||||||
|
if ('error' in response.result) {
|
||||||
|
reject(response.result.error);
|
||||||
|
} else {
|
||||||
|
resolve(response.result.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
context.addEventListener('message', onMessage);
|
||||||
|
context.postMessage({ request: { id, path, args } });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Bridge;
|
||||||
23
src/services/Core/worker.js
Normal file
23
src/services/Core/worker.js
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
const sanitizeLocationPath = require('stremio/common/sanitizeLocationPath');
|
||||||
|
const Bridge = require('./bridge');
|
||||||
|
|
||||||
|
const bridge = new Bridge(self, self);
|
||||||
|
|
||||||
|
self.init = async ({ baseURI, appVersion, shellVersion }) => {
|
||||||
|
self.document = { baseURI };
|
||||||
|
self.app_version = appVersion;
|
||||||
|
self.shell_version = shellVersion;
|
||||||
|
self.sanitize_location_path = sanitizeLocationPath;
|
||||||
|
self.get_location_hash = async () => bridge.call(['location', 'hash'], []);
|
||||||
|
self.local_storage_get_item = async (key) => bridge.call(['localStorage', 'getItem'], [key]);
|
||||||
|
self.local_storage_set_item = async (key, value) => bridge.call(['localStorage', 'setItem'], [key, value]);
|
||||||
|
self.local_storage_remove_item = async (key) => bridge.call(['localStorage', 'removeItem'], [key]);
|
||||||
|
const { default: initialize_api, initialize_runtime, get_state, get_debug_state, dispatch, analytics, decode_stream } = require('@stremio/stremio-core-web');
|
||||||
|
self.getState = get_state;
|
||||||
|
self.getDebugState = get_debug_state;
|
||||||
|
self.dispatch = dispatch;
|
||||||
|
self.analytics = analytics;
|
||||||
|
self.decodeStream = decode_stream;
|
||||||
|
await initialize_api(require('@stremio/stremio-core-web/stremio_core_web_bg.wasm'));
|
||||||
|
await initialize_runtime((event) => bridge.call(['onCoreEvent'], [event]));
|
||||||
|
};
|
||||||
|
|
@ -15,7 +15,10 @@ const COMMIT_HASH = execSync('git rev-parse HEAD').toString().trim();
|
||||||
module.exports = (env, argv) => ({
|
module.exports = (env, argv) => ({
|
||||||
mode: argv.mode,
|
mode: argv.mode,
|
||||||
devtool: argv.mode === 'production' ? 'source-map' : 'eval-source-map',
|
devtool: argv.mode === 'production' ? 'source-map' : 'eval-source-map',
|
||||||
entry: './src/index.js',
|
entry: {
|
||||||
|
main: './src/index.js',
|
||||||
|
worker: './src/services/Core/worker.js'
|
||||||
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, 'build'),
|
path: path.join(__dirname, 'build'),
|
||||||
filename: `${COMMIT_HASH}/scripts/[name].js`
|
filename: `${COMMIT_HASH}/scripts/[name].js`
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue