ankiconnect

A simple implementation of AnkiConnect client, with TypeScript typing (using // @ts-check in an IME.)

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/452285/1099556/ankiconnect.js

  1. class AnkiConnect {
  2. baseURL;
  3. version;
  4.  
  5. constructor(baseURL = 'http://localhost:8765', version = 6) {
  6. this.baseURL = baseURL;
  7. this.version = version;
  8. }
  9.  
  10. async send(action, params, version = this.version) {
  11. return new Promise((resolve, reject) => {
  12. const xhr = new XMLHttpRequest();
  13. xhr.addEventListener('error', () => reject('failed to issue request'));
  14. xhr.addEventListener('load', () => {
  15. try {
  16. const response = JSON.parse(xhr.responseText);
  17. if (Object.getOwnPropertyNames(response).length != 2) {
  18. throw 'response has an unexpected number of fields';
  19. }
  20. if (!response.hasOwnProperty('error')) {
  21. throw 'response is missing required error field';
  22. }
  23. if (!response.hasOwnProperty('result')) {
  24. throw 'response is missing required result field';
  25. }
  26. if (response.error) {
  27. throw response.error;
  28. }
  29. resolve(response.result);
  30. } catch (e) {
  31. reject(e);
  32. }
  33. });
  34.  
  35. xhr.open('POST', this.baseURL);
  36. xhr.send(JSON.stringify({ action, version, params }));
  37. });
  38. }
  39.  
  40. chain(action, params, version = this.version) {
  41. const actions = [{ action, params }];
  42.  
  43. const chainable = {
  44. commit: async () => {
  45. if (actions.length > 1) {
  46. return this.send('multi', { actions }, version);
  47. }
  48.  
  49. return this.send(action, params, version);
  50. },
  51. add: async (action, params) => {
  52. actions.push({ action, params });
  53. return chainable;
  54. },
  55. };
  56.  
  57. return chainable;
  58. }
  59. }