summaryrefslogtreecommitdiff
path: root/ext/js
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2023-12-22 10:58:37 -0500
committerGitHub <noreply@github.com>2023-12-22 15:58:37 +0000
commit2b29df7a8ecd95384dbee30e27743cf25703e447 (patch)
tree8bccc8c822f740325830496aca4855b75f37e6ed /ext/js
parent8d2aaf2757f69bdf85281319813ff57db276f71a (diff)
API map updates (#418)
* Simplify some types * Organize * Add additional types for explicit sync and async handlers * Rename ApiItem to ApiDescriptor * Simplify template names * Remove lax types * Document * Add support for extra params * Update APIs * Make handler explicitly async * Add comments * Add more types * Description fixes, add ApiParam * Type updates * Add invokeApiMapHandler * Fixes
Diffstat (limited to 'ext/js')
-rw-r--r--ext/js/background/offscreen.js2
-rw-r--r--ext/js/core/api-map.js58
2 files changed, 53 insertions, 7 deletions
diff --git a/ext/js/background/offscreen.js b/ext/js/background/offscreen.js
index 44b0af77..1cab5929 100644
--- a/ext/js/background/offscreen.js
+++ b/ext/js/background/offscreen.js
@@ -138,7 +138,7 @@ export class Offscreen {
}
/** @type {import('offscreen').OffscreenApiHandler<'findTermsOffscreen'>} */
- _findTermsHandler({mode, text, options}) {
+ async _findTermsHandler({mode, text, options}) {
const enabledDictionaryMap = new Map(options.enabledDictionaryMap);
const excludeDictionaryDefinitions = (
options.excludeDictionaryDefinitions !== null ?
diff --git a/ext/js/core/api-map.js b/ext/js/core/api-map.js
index eb4abeea..09be8035 100644
--- a/ext/js/core/api-map.js
+++ b/ext/js/core/api-map.js
@@ -15,10 +15,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {ExtensionError} from './extension-error.js';
+
/**
* @template {import('api-map').ApiSurface} [TApiSurface=never]
- * @param {import('api-map').ApiMapInit<TApiSurface>} init
- * @returns {import('api-map').ApiMap<TApiSurface>}
+ * @template {unknown[]} [TExtraParams=[]]
+ * @param {import('api-map').ApiMapInit<TApiSurface, TExtraParams>} init
+ * @returns {import('api-map').ApiMap<TApiSurface, TExtraParams>}
*/
export function createApiMap(init) {
return new Map(init);
@@ -26,8 +29,9 @@ export function createApiMap(init) {
/**
* @template {import('api-map').ApiSurface} [TApiSurface=never]
- * @param {import('api-map').ApiMap<TApiSurface>} map
- * @param {import('api-map').ApiMapInit<TApiSurface>} init
+ * @template {unknown[]} [TExtraParams=[]]
+ * @param {import('api-map').ApiMap<TApiSurface, TExtraParams>} map
+ * @param {import('api-map').ApiMapInit<TApiSurface, TExtraParams>} init
* @throws {Error}
*/
export function extendApiMap(map, init) {
@@ -39,10 +43,52 @@ export function extendApiMap(map, init) {
/**
* @template {import('api-map').ApiSurface} [TApiSurface=never]
- * @param {import('api-map').ApiMap<TApiSurface>} map
+ * @template {unknown[]} [TExtraParams=[]]
+ * @param {import('api-map').ApiMap<TApiSurface, TExtraParams>} map
* @param {string} name
- * @returns {import('api-map').ApiHandlerAny<TApiSurface>|undefined}
+ * @returns {import('api-map').ApiHandlerAny<TApiSurface, TExtraParams>|undefined}
*/
export function getApiMapHandler(map, name) {
return map.get(/** @type {import('api-map').ApiNames<TApiSurface>} */ (name));
}
+
+/**
+ * @template {import('api-map').ApiSurface} [TApiSurface=never]
+ * @template {unknown[]} [TExtraParams=[]]
+ * @param {import('api-map').ApiMap<TApiSurface, TExtraParams>} map
+ * @param {string} name
+ * @param {import('api-map').ApiParamsAny<TApiSurface>} params
+ * @param {TExtraParams} extraParams
+ * @param {(response: import('core').Response<import('api-map').ApiReturnAny<TApiSurface>>) => void} callback
+ * @param {() => void} [handlerNotFoundCallback]
+ * @returns {boolean} `true` if async, `false` otherwise.
+ */
+export function invokeApiMapHandler(map, name, params, extraParams, callback, handlerNotFoundCallback) {
+ const handler = getApiMapHandler(map, name);
+ if (typeof handler === 'undefined') {
+ if (typeof handlerNotFoundCallback === 'function') {
+ try {
+ handlerNotFoundCallback();
+ } catch (error) {
+ // NOP
+ }
+ }
+ return false;
+ }
+ try {
+ const promiseOrResult = handler(/** @type {import('core').SafeAny} */ (params), ...extraParams);
+ if (promiseOrResult instanceof Promise) {
+ /** @type {Promise<unknown>} */ (promiseOrResult).then(
+ (result) => { callback({result}); },
+ (error) => { callback({error: ExtensionError.serialize(error)}); }
+ );
+ return true;
+ } else {
+ callback({result: promiseOrResult});
+ return false;
+ }
+ } catch (error) {
+ callback({error: ExtensionError.serialize(error)});
+ return false;
+ }
+}