You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
3.5 KiB

1 month ago
  1. import { HOOK_PLUGIN_SETTINGS_SET } from './const.js';
  2. import { now } from './time.js';
  3. export class ApiProxy {
  4. constructor(plugin, hook) {
  5. this.target = null;
  6. this.targetQueue = [];
  7. this.onQueue = [];
  8. this.plugin = plugin;
  9. this.hook = hook;
  10. const defaultSettings = {};
  11. if (plugin.settings) {
  12. for (const id in plugin.settings) {
  13. const item = plugin.settings[id];
  14. defaultSettings[id] = item.defaultValue;
  15. }
  16. }
  17. const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
  18. let currentSettings = Object.assign({}, defaultSettings);
  19. try {
  20. const raw = localStorage.getItem(localSettingsSaveId);
  21. const data = JSON.parse(raw);
  22. Object.assign(currentSettings, data);
  23. }
  24. catch (e) {
  25. // noop
  26. }
  27. this.fallbacks = {
  28. getSettings() {
  29. return currentSettings;
  30. },
  31. setSettings(value) {
  32. try {
  33. localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
  34. }
  35. catch (e) {
  36. // noop
  37. }
  38. currentSettings = value;
  39. },
  40. now() {
  41. return now();
  42. },
  43. };
  44. if (hook) {
  45. hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
  46. if (pluginId === this.plugin.id) {
  47. this.fallbacks.setSettings(value);
  48. }
  49. });
  50. }
  51. this.proxiedOn = new Proxy({}, {
  52. get: (_target, prop) => {
  53. if (this.target) {
  54. return this.target.on[prop];
  55. }
  56. else {
  57. return (...args) => {
  58. this.onQueue.push({
  59. method: prop,
  60. args,
  61. });
  62. };
  63. }
  64. },
  65. });
  66. this.proxiedTarget = new Proxy({}, {
  67. get: (_target, prop) => {
  68. if (this.target) {
  69. return this.target[prop];
  70. }
  71. else if (prop === 'on') {
  72. return this.proxiedOn;
  73. }
  74. else if (Object.keys(this.fallbacks).includes(prop)) {
  75. return (...args) => {
  76. this.targetQueue.push({
  77. method: prop,
  78. args,
  79. resolve: () => { },
  80. });
  81. return this.fallbacks[prop](...args);
  82. };
  83. }
  84. else {
  85. return (...args) => {
  86. return new Promise((resolve) => {
  87. this.targetQueue.push({
  88. method: prop,
  89. args,
  90. resolve,
  91. });
  92. });
  93. };
  94. }
  95. },
  96. });
  97. }
  98. async setRealTarget(target) {
  99. this.target = target;
  100. for (const item of this.onQueue) {
  101. this.target.on[item.method](...item.args);
  102. }
  103. for (const item of this.targetQueue) {
  104. item.resolve(await this.target[item.method](...item.args));
  105. }
  106. }
  107. }