aboutsummaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/bg/js/backend.js5
-rw-r--r--ext/mixed/js/api.js28
2 files changed, 33 insertions, 0 deletions
diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js
index 07dca370..e849bc69 100644
--- a/ext/bg/js/backend.js
+++ b/ext/bg/js/backend.js
@@ -48,6 +48,7 @@ class Backend {
this.messageToken = yomichan.generateId(16);
this._messageHandlers = new Map([
+ ['isBackendReady', this._onApiIsBackendReady.bind(this)],
['optionsSchemaGet', this._onApiOptionsSchemaGet.bind(this)],
['optionsGet', this._onApiOptionsGet.bind(this)],
['optionsGetFull', this._onApiOptionsGetFull.bind(this)],
@@ -267,6 +268,10 @@ class Backend {
// Message handlers
+ async _onApiIsBackendReady() {
+ return true;
+ }
+
async _onApiOptionsSchemaGet() {
return this.getOptionsSchema();
}
diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js
index 26f4389d..fa61a1e2 100644
--- a/ext/mixed/js/api.js
+++ b/ext/mixed/js/api.js
@@ -122,6 +122,30 @@ function apiGetDefaultAnkiFieldTemplates() {
}
function _apiInvoke(action, params={}) {
+ if (!_isBackendReady) {
+ if (_isBackendReadyPromise === null) {
+ _isBackendReadyPromise = new Promise((resolve) => (_isBackendReadyResolve = resolve));
+ const checkBackendReady = async () => {
+ try {
+ if (await _apiInvokeRaw('isBackendReady')) {
+ _isBackendReady = true;
+ _isBackendReadyResolve();
+ }
+ } catch (e) {
+ // NOP
+ }
+ setTimeout(checkBackendReady, 100); // poll Backend until it responds
+ };
+ checkBackendReady();
+ }
+ return _isBackendReadyPromise.then(
+ () => _apiInvokeRaw(action, params)
+ );
+ }
+ return _apiInvokeRaw(action, params);
+}
+
+function _apiInvokeRaw(action, params={}) {
const data = {action, params};
return new Promise((resolve, reject) => {
try {
@@ -148,3 +172,7 @@ function _apiInvoke(action, params={}) {
function _apiCheckLastError() {
// NOP
}
+
+let _isBackendReady = false;
+let _isBackendReadyResolve = null;
+let _isBackendReadyPromise = null;