Monkey Storage

Useful library for dealing with the storage.

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/405831/821709/Monkey%20Storage.js

  1. // ==UserScript==
  2. // @name Persistent Storage
  3. // @namespace https://rafaelgssa.gitlab.io/monkey-scripts
  4. // @version 3.0.2
  5. // @author rafaelgssa
  6. // @description Useful library for dealing with the storage.
  7. // @match *://*/*
  8. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
  9. // @require https://gf.qytechs.cn/scripts/405813-monkey-utils/code/Monkey%20Utils.js
  10. // @grant GM.setValue
  11. // @grant GM.getValue
  12. // @grant GM.deleteValue
  13. // @grant GM_setValue
  14. // @grant GM_getValue
  15. // @grant GM_deleteValue
  16. // ==/UserScript==
  17.  
  18. /* global Utils */
  19.  
  20. /**
  21. * @typedef {Record<string, unknown> & StorageValuesBase} StorageValues
  22. *
  23. * @typedef {Object} StorageValuesBase
  24. * @property {Record<string, unknown>} settings
  25. */
  26.  
  27. // eslint-disable-next-line
  28. const PersistentStorage = (() => {
  29. let _id = '';
  30.  
  31. const _defaultValues = /** @type {StorageValues} */ ({
  32. settings: {},
  33. });
  34.  
  35. const _cache = /** @type {StorageValues} */ ({
  36. settings: {},
  37. });
  38.  
  39. /**
  40. * Initializes the storage.
  41. * @param {string} id The ID to use for the local storage.
  42. * @param {Partial<StorageValues>} [defaultValues] Any default values to set.
  43. * @returns {Promise<void>}
  44. */
  45. const init = (id, defaultValues) => {
  46. _id = id;
  47. if (defaultValues) {
  48. for (const [key, value] of Object.entries(defaultValues)) {
  49. setDefaultValue(key, value);
  50. }
  51. }
  52. return _updateCache('settings');
  53. };
  54.  
  55. /**
  56. * Sets a default value.
  57. * @param {string} key The key of the default value to set.
  58. * @param {unknown} value The default value to set.
  59. */
  60. const setDefaultValue = (key, value) => {
  61. _defaultValues[key] = value;
  62. };
  63.  
  64. /**
  65. * Sets a value in the storage.
  66. * @param {string} key The key of the value to set.
  67. * @param {unknown} value The value to set.
  68. * @returns {Promise<void>}
  69. */
  70. const setValue = async (key, value) => {
  71. const stringifiedValue = JSON.stringify(value);
  72. await GM.setValue(key, stringifiedValue);
  73. _cache[key] = value;
  74. };
  75.  
  76. /**
  77. * Gets a value from the cache.
  78. * @param {string} key The key of the value to get.
  79. * @param {boolean} [updateCache] Whether to update the cache with the storage or not.
  80. * @returns {Promise<unknown>} The value.
  81. */
  82. const getValue = async (key, updateCache = false) => {
  83. if (!Utils.isSet(_cache[key]) || updateCache) {
  84. await _updateCache(key);
  85. }
  86. return _cache[key];
  87. };
  88.  
  89. /**
  90. * Updates a value in the cache with the storage.
  91. * @param {string} key The key of the value to update.
  92. * @returns {Promise<void>}
  93. */
  94. const _updateCache = async (key) => {
  95. let value = await GM.getValue(key);
  96. if (typeof value === 'string') {
  97. try {
  98. value = JSON.parse(value);
  99. } catch (err) {
  100. // Value is already parsed, just ignore.
  101. }
  102. }
  103. _cache[key] = Utils.isSet(value) ? value : _defaultValues[key];
  104. };
  105.  
  106. /**
  107. * Deletes a value from the storage.
  108. * @param {string} key The key of the value to delete.
  109. * @returns {Promise<void>}
  110. */
  111. const deleteValue = async (key) => {
  112. await GM.deleteValue(key);
  113. delete _cache[key];
  114. };
  115.  
  116. /**
  117. * Sets a value in the local storage.
  118. * @param {string} key The key of the value to set.
  119. * @param {unknown} value The value to set.
  120. */
  121. const setLocalValue = (key, value) => {
  122. const stringifiedValue = JSON.stringify(value);
  123. window.localStorage.setItem(`${_id}_${key}`, stringifiedValue);
  124. _cache[key] = value;
  125. };
  126.  
  127. /**
  128. * Gets a value from the cache.
  129. * @param {string} key The key of the value to get.
  130. * @param {boolean} [updateCache] Whether to update the cache with the local storage or not.
  131. * @returns {unknown} The value.
  132. */
  133. const getLocalValue = (key, updateCache = false) => {
  134. if (!Utils.isSet(_cache[key]) || updateCache) {
  135. _updateLocalCache(key);
  136. }
  137. return _cache[key];
  138. };
  139.  
  140. /**
  141. * Updates a value in the cache with the local storage.
  142. * @param {string} key The key of the value to update.
  143. */
  144. const _updateLocalCache = (key) => {
  145. let value = window.localStorage.getItem(`${_id}_${key}`);
  146. if (typeof value === 'string') {
  147. try {
  148. value = JSON.parse(value);
  149. } catch (err) {
  150. // Value is already parsed, just ignore.
  151. }
  152. }
  153. _cache[key] = Utils.isSet(value) ? value : _defaultValues[key];
  154. };
  155.  
  156. /**
  157. * Deletes a value from the local storage.
  158. * @param {string} key The key of the value to delete.
  159. */
  160. const deleteLocalValue = (key) => {
  161. window.localStorage.removeItem(`${_id}_${key}`);
  162. delete _cache[key];
  163. };
  164.  
  165. /**
  166. * Sets a default setting.
  167. * @param {string} key The key of the default setting to set.
  168. * @param {unknown} setting The default setting to set.
  169. */
  170. const setDefaultSetting = (key, setting) => {
  171. _defaultValues.settings[key] = setting;
  172. };
  173.  
  174. /**
  175. * Sets a setting in the cache.
  176. * @param {string} key The key of the setting to set.
  177. * @param {unknown} setting The setting to set.
  178. */
  179. const setSetting = (key, setting) => {
  180. _cache.settings[key] = setting;
  181. };
  182.  
  183. /**
  184. * Gets a setting from the cache.
  185. * @param {string} key The key of the setting to get.
  186. * @param {boolean} [updateCache] Whether to update the settings cache with the storage or not.
  187. * @returns {Promise<unknown>} The setting.
  188. */
  189. const getSetting = async (key, updateCache = false) => {
  190. if (isSettingsEmpty() || !Utils.isSet(_cache.settings[key]) || updateCache) {
  191. await _updateCache('settings');
  192. }
  193. return _cache.settings[key];
  194. };
  195.  
  196. /**
  197. * Deletes a setting from the cache.
  198. * @param {string} key The key of the setting to delete.
  199. */
  200. const deleteSetting = (key) => {
  201. delete _cache.settings[key];
  202. };
  203.  
  204. /**
  205. * Saves the settings from the cache.
  206. * @returns {Promise<void>}
  207. */
  208. const saveSettings = () => {
  209. return setValue('settings', _cache.settings);
  210. };
  211.  
  212. /**
  213. * Checks if the settings cache is empty.
  214. * @returns {boolean} Whether the settings cache is empty or not.
  215. */
  216. const isSettingsEmpty = () => {
  217. return Object.keys(_cache.settings).length === 0;
  218. };
  219.  
  220. return {
  221. init,
  222. setDefaultValue,
  223. setValue,
  224. getValue,
  225. deleteValue,
  226. setLocalValue,
  227. getLocalValue,
  228. deleteLocalValue,
  229. setDefaultSetting,
  230. setSetting,
  231. getSetting,
  232. deleteSetting,
  233. saveSettings,
  234. isSettingsEmpty,
  235. };
  236. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址