mirror of
https://github.com/cryptpad/cryptpad.git
synced 2026-09-14 11:05:41 +05:00
Add async store
This commit is contained in:
parent
b9b94a1c31
commit
dcc790535a
52
src/worker/core/async-connector.js
Normal file
52
src/worker/core/async-connector.js
Normal file
@ -0,0 +1,52 @@
|
||||
// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
/* global importScripts */
|
||||
|
||||
const Interface = require('./interface');
|
||||
const Util = require('../../common/common-util');
|
||||
let start = (setConfig) => {
|
||||
let ready = false;
|
||||
let closed = false;
|
||||
let onMsg;
|
||||
const sendMsgEv = Util.mkEvent();
|
||||
const closeStore = () => { closed = true; };
|
||||
const onMessage = (f) => {
|
||||
sendMsgEv.reg((data) => {
|
||||
setTimeout(() => {
|
||||
f(data);
|
||||
});
|
||||
});
|
||||
};
|
||||
const postMsg = (data) => {
|
||||
if (closed) { return; }
|
||||
sendMsgEv.fire(data);
|
||||
};
|
||||
const query = () => {
|
||||
if (!onMsg || closed) { return; }
|
||||
onMsg.fire({data, origin:''});
|
||||
};
|
||||
|
||||
let init = (cfg) => {
|
||||
if (ready) { return; }
|
||||
setConfig(cfg);
|
||||
Interface.init(closeStore);
|
||||
ready = true;
|
||||
Interface.initClient({
|
||||
postMsg
|
||||
}, function (_onMsg) {
|
||||
onMsg = _onMsg;
|
||||
postMsg('STORE_READY');
|
||||
});
|
||||
};
|
||||
return {
|
||||
init,
|
||||
onMessage,
|
||||
query
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = { start };
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@ import * as Store from './async-store.js';
|
||||
import * as StoreRpc from './core/store-rpc.js';
|
||||
import * as Interface from './core/interface.js';
|
||||
import * as SWConnector from './core/sw-connector.js';
|
||||
import * as AsyncConnector from './core/async-connector.js';
|
||||
|
||||
// Components
|
||||
import * as Migrate from './components/migrate-user-object.js';
|
||||
@ -107,6 +108,7 @@ let start = (cfg: StoreConfig):void => {
|
||||
|
||||
let inWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
|
||||
let inSharedWorker = typeof SharedWorkerGlobalScope !== 'undefined' && self instanceof SharedWorkerGlobalScope;
|
||||
let storeObject = {};
|
||||
if (inSharedWorker) {
|
||||
console.error('SHAREDWORKER');
|
||||
SWConnector.start(start);
|
||||
@ -116,10 +118,11 @@ if (inSharedWorker) {
|
||||
console.error('NODEJS');
|
||||
} else {
|
||||
console.error('BROWSER');
|
||||
storeObject = AsyncConnector.start(start);
|
||||
}
|
||||
|
||||
|
||||
export {
|
||||
start
|
||||
storeObject
|
||||
};
|
||||
|
||||
|
||||
147
www/common/store-interface.js
Normal file
147
www/common/store-interface.js
Normal file
@ -0,0 +1,147 @@
|
||||
(() => {
|
||||
const factory = function () {
|
||||
// XXX TODO
|
||||
// Support NodeJS
|
||||
// Support WebWorker
|
||||
// Return a usable API instead of postMsg/msgEv
|
||||
// XXX handle AppConfig, ApiConfig, MEssages and Broadcast in this file directly?
|
||||
// --> pull them using require if browser or... ?
|
||||
|
||||
let create = function (cfg = {}) {
|
||||
let { noWorker, noSharedWorker, AppConfig,
|
||||
ApiConfig, Messages, Broadcast } = cfg;
|
||||
|
||||
const mkEvent = function () {
|
||||
var handlers = [];
|
||||
return {
|
||||
reg: function (cb) {
|
||||
handlers.push(cb);
|
||||
},
|
||||
unreg: function (cb) {
|
||||
if (handlers.indexOf(cb) === -1) { return; }
|
||||
handlers.splice(handlers.indexOf(cb), 1);
|
||||
},
|
||||
fire: function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
handlers.forEach(function (h) {
|
||||
h.apply(null, args);
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
let called = false;
|
||||
let msgEv = mkEvent();
|
||||
let todo = (resolve, reject) => {
|
||||
if (called) { return; }
|
||||
called = true;
|
||||
|
||||
if (!noWorker && !noSharedWorker && typeof(SharedWorker) !== "undefined") {
|
||||
worker = new SharedWorker('/common/worker.bundle.js?' + urlArgs);
|
||||
worker.onerror = function (e) {
|
||||
console.error(e.message);
|
||||
};
|
||||
worker.port.onmessage = function (ev) {
|
||||
if (ev.data === "SW_READY") {
|
||||
return;
|
||||
}
|
||||
msgEv.fire(ev);
|
||||
};
|
||||
postMsg = function (data) {
|
||||
worker.port.postMessage(Util.clone(data));
|
||||
};
|
||||
postMsg({
|
||||
type: 'INIT',
|
||||
cfg: {
|
||||
AppConfig,
|
||||
ApiConfig,
|
||||
Messages,
|
||||
Broadcast
|
||||
}
|
||||
});
|
||||
window.addEventListener('unload', function () {
|
||||
postMsg('CLOSE');
|
||||
});
|
||||
return void resolve(postMsg, msgEv);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
if (!noWorker && Worker) {
|
||||
worker = new Worker('/common/worker.bundle.js?' + urlArgs);
|
||||
worker.onerror = function (e) {
|
||||
console.error(e.message);
|
||||
};
|
||||
worker.onmessage = function (ev) {
|
||||
msgEv.fire(ev);
|
||||
};
|
||||
postMsg = function (data) {
|
||||
worker.postMessage(data);
|
||||
};
|
||||
return void resolve(postMsg, msgEv);
|
||||
}
|
||||
|
||||
// Use the async store in the main thread if workers
|
||||
// aren't available
|
||||
if (typeof(require) === "undefined") { return; }
|
||||
require(['/common/worker.bundle.js'], function (Store) {
|
||||
Store.onMessage(function (data) {
|
||||
msgEv.fire({data: data, origin: ''});
|
||||
});
|
||||
postMsg = function (d) {
|
||||
setTimeout(function () {
|
||||
Store.query(d);
|
||||
});
|
||||
};
|
||||
Store.init({
|
||||
AppConfig,
|
||||
ApiConfig,
|
||||
Messages,
|
||||
Broadcast
|
||||
});
|
||||
resolve(postMsg, msgEv);
|
||||
});
|
||||
};
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof(SharedWorker) !== "undefined") {
|
||||
try {
|
||||
new SharedWorker('');
|
||||
} catch (e) {
|
||||
noSharedWorker = true;
|
||||
console.log('Disabling SharedWorker because of privacy settings.');
|
||||
}
|
||||
}
|
||||
if (typeof(Worker) !== "undefined") {
|
||||
try {
|
||||
worker = new Worker('/common/outer/testworker.js?' + urlArgs);
|
||||
worker.onerror = function (errEv) {
|
||||
errEv.preventDefault();
|
||||
errEv.stopPropagation();
|
||||
noWorker = true;
|
||||
worker.terminate();
|
||||
todo(resolve, reject);
|
||||
};
|
||||
worker.onmessage = function (ev) {
|
||||
if (ev.data === "OK") {
|
||||
worker.terminate();
|
||||
todo(resolve, reject);
|
||||
}
|
||||
};
|
||||
} catch (e) {
|
||||
noWorker = true;
|
||||
todo(resolve, reject);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return create;
|
||||
};
|
||||
|
||||
|
||||
if (typeof(module) !== 'undefined' && module.exports) {
|
||||
module.exports = factory();
|
||||
} else if ((typeof(define) !== 'undefined' && define !== null) && (define.amd !== null)) {
|
||||
define([], factory);
|
||||
}
|
||||
})();
|
||||
Loading…
Reference in New Issue
Block a user