proxy-storage

Proxy wrapper around GM storage API, with support for nested object by proxy.

Dette scriptet burde ikke installeres direkte. Det er et bibliotek for andre script å inkludere med det nye metadirektivet // @require https://update.greatest.deepsurf.us/scripts/488549/1335042/proxy-storage.js

  1. // ==UserScript==
  2. // @name proxy-storage
  3. // @description Proxy wrapper around GM storage API, with support for nested object by proxy.
  4. // @version 0.0.1
  5. // @namespace owowed.moe
  6. // @author owowed <island@owowed.moe>
  7. // @grant GM_getValue
  8. // @grant GM_setValue
  9. // @grant GM_deleteValue
  10. // @grant GM_listValues
  11. // @license LGPL-3.0
  12. // ==/UserScript==
  13.  
  14. function createGmProxyStorage({
  15. get = GM_getValue,
  16. set = GM_setValue,
  17. deleteValue = GM_deleteValue,
  18. list = GM_listValues
  19. } = {}) {
  20. const storage = { get, set, deleteValue, list };
  21. return new Proxy({}, {
  22. get(target, prop, receiver) {
  23. const value = storage.get(prop);
  24. if (isObjectOrArray(value)) {
  25. return makeNestedTargetProxy(value, prop, storage.set);
  26. }
  27. else {
  28. return value;
  29. }
  30. },
  31. set(target, prop, newValue, receiver) {
  32. storage.set(prop, newValue);
  33. return true;
  34. },
  35. deleteProperty(target, prop) {
  36. storage.deleteValue(prop);
  37. return true;
  38. },
  39. ownKeys(target) {
  40. return storage.list();
  41. },
  42. has(target, prop) {
  43. return this.ownKeys(target).includes(prop);
  44. },
  45. getOwnPropertyDescriptor(target, prop) {
  46. if (this.has(target, prop)) {
  47. return {
  48. enumerable: true,
  49. configurable: true,
  50. writable: false,
  51. value: this.get(target, prop)
  52. };
  53. }
  54. },
  55. });
  56. }
  57.  
  58. function isObjectOrArray(value) {
  59. return Array.isArray(value) || (typeof value == "object" && value != null);
  60. }
  61.  
  62. function makeNestedTargetProxy(rootTarget, rootTargetProp, setter) {
  63. const set = (target, prop, value) => {
  64. target[prop] = value;
  65.  
  66. setter(rootTargetProp, rootTarget); /* `rootTarget` reference will always get updated */
  67.  
  68. return value;
  69. };
  70.  
  71. const get = (target, prop) => {
  72. const value = target[prop];
  73.  
  74. if (isObjectOrArray(value)) {
  75. return new Proxy(value, { get, set });
  76. }
  77.  
  78. return value;
  79. };
  80.  
  81. return new Proxy(rootTarget, { get, set });
  82. }