108 lines
3.5 KiB
JavaScript
108 lines
3.5 KiB
JavaScript
|
import { HOOK_PLUGIN_SETTINGS_SET } from './const.js';
|
||
|
import { now } from './time.js';
|
||
|
export class ApiProxy {
|
||
|
constructor(plugin, hook) {
|
||
|
this.target = null;
|
||
|
this.targetQueue = [];
|
||
|
this.onQueue = [];
|
||
|
this.plugin = plugin;
|
||
|
this.hook = hook;
|
||
|
const defaultSettings = {};
|
||
|
if (plugin.settings) {
|
||
|
for (const id in plugin.settings) {
|
||
|
const item = plugin.settings[id];
|
||
|
defaultSettings[id] = item.defaultValue;
|
||
|
}
|
||
|
}
|
||
|
const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
|
||
|
let currentSettings = Object.assign({}, defaultSettings);
|
||
|
try {
|
||
|
const raw = localStorage.getItem(localSettingsSaveId);
|
||
|
const data = JSON.parse(raw);
|
||
|
Object.assign(currentSettings, data);
|
||
|
}
|
||
|
catch (e) {
|
||
|
// noop
|
||
|
}
|
||
|
this.fallbacks = {
|
||
|
getSettings() {
|
||
|
return currentSettings;
|
||
|
},
|
||
|
setSettings(value) {
|
||
|
try {
|
||
|
localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
|
||
|
}
|
||
|
catch (e) {
|
||
|
// noop
|
||
|
}
|
||
|
currentSettings = value;
|
||
|
},
|
||
|
now() {
|
||
|
return now();
|
||
|
},
|
||
|
};
|
||
|
if (hook) {
|
||
|
hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
|
||
|
if (pluginId === this.plugin.id) {
|
||
|
this.fallbacks.setSettings(value);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
this.proxiedOn = new Proxy({}, {
|
||
|
get: (_target, prop) => {
|
||
|
if (this.target) {
|
||
|
return this.target.on[prop];
|
||
|
}
|
||
|
else {
|
||
|
return (...args) => {
|
||
|
this.onQueue.push({
|
||
|
method: prop,
|
||
|
args,
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
},
|
||
|
});
|
||
|
this.proxiedTarget = new Proxy({}, {
|
||
|
get: (_target, prop) => {
|
||
|
if (this.target) {
|
||
|
return this.target[prop];
|
||
|
}
|
||
|
else if (prop === 'on') {
|
||
|
return this.proxiedOn;
|
||
|
}
|
||
|
else if (Object.keys(this.fallbacks).includes(prop)) {
|
||
|
return (...args) => {
|
||
|
this.targetQueue.push({
|
||
|
method: prop,
|
||
|
args,
|
||
|
resolve: () => { },
|
||
|
});
|
||
|
return this.fallbacks[prop](...args);
|
||
|
};
|
||
|
}
|
||
|
else {
|
||
|
return (...args) => {
|
||
|
return new Promise(resolve => {
|
||
|
this.targetQueue.push({
|
||
|
method: prop,
|
||
|
args,
|
||
|
resolve,
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
},
|
||
|
});
|
||
|
}
|
||
|
async setRealTarget(target) {
|
||
|
this.target = target;
|
||
|
for (const item of this.onQueue) {
|
||
|
this.target.on[item.method](...item.args);
|
||
|
}
|
||
|
for (const item of this.targetQueue) {
|
||
|
item.resolve(await this.target[item.method](...item.args));
|
||
|
}
|
||
|
}
|
||
|
}
|