bridge.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. class Bridge extends EventTarget {
  2. #analysis(string) {
  3. let data = { type: '', payload: null, callbackId: '' };
  4. try {
  5. data = JSON.parse(string);
  6. } catch (e) {
  7. console.log('log:bridge:js', `[analysis] 解析消息错误: ${e.message}`);
  8. }
  9. if (
  10. data.payload
  11. && typeof data.payload === 'object'
  12. && data.payload['__code__'] != null
  13. && data.payload['__message__'] != null
  14. ) {
  15. data.error = { code: data.payload['__code__'], message: data.payload['__message__'] };
  16. }
  17. return data;
  18. }
  19. #pool = new Map();
  20. static getInstance() {
  21. return Bridge._instance ?? (Bridge._instance = new Bridge());
  22. }
  23. static get Platform() {
  24. return window['AndroidBridge'];
  25. }
  26. static get UUID() {
  27. return crypto.randomUUID();
  28. }
  29. static pulse(userId) {
  30. const { promise, ...resolvers } = Promise.withResolvers();
  31. this.getInstance().#postMessage('pulse', { userId }, resolvers);
  32. return promise;
  33. }
  34. static print(payload) {
  35. const { promise, ...resolvers } = Promise.withResolvers();
  36. this.getInstance().#postMessage('print', payload, resolvers);
  37. return promise;
  38. }
  39. dispatch(message) {
  40. console.log('log:bridge:js', `[dispatch] 接收到消息: ${message}`);
  41. const { type, callbackId, payload, error } = this.#analysis(message);
  42. if (callbackId) {
  43. const { resolve, reject } = this.#pool.get(callbackId) ?? {};
  44. if (error) { reject?.(error); } else { resolve?.(payload); }
  45. this.#pool.delete(callbackId);
  46. } else {
  47. let event;
  48. if (error) event = new ErrorEvent(type, { error, message: error.message });
  49. else event = new CustomEvent(type, { detail: payload });
  50. super.dispatchEvent(event);
  51. }
  52. }
  53. addEventListener(type, callback, options) {
  54. super.addEventListener(type, callback, options);
  55. return () => super.removeEventListener(type, callback);
  56. }
  57. #postMessage(type, payload, resolvers) {
  58. const callbackId = `${type}:${Bridge.UUID}`;
  59. this.#pool.set(callbackId, resolvers);
  60. const message = JSON.stringify({ type, payload, callbackId })
  61. Bridge.Platform.postMessage(message);
  62. console.log('log:bridge:js', `[post] 发送的消息: ${message}`);
  63. }
  64. }
  65. window['Bridge'] = Bridge;
  66. window['bridge'] = Bridge.getInstance();
  67. window.print = Bridge.print.bind(Bridge);