mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 19:55:39 +00:00
3d2f150743
This gives us performance wins in sevaral areas: - Creating a structured clone blob of storage data directly from the source compartment allows us to avoid X-ray and JSON serialization overhead when storing new values. - Storing the intermediate StructuredCloneBlob, rather than JSON values, in-memory saves us additional JSON and structured clone overhead when passing the values to listeners and API callers, and saves us a fair amount of memory to boot. - Serializing storage values before sending them over a message manager allows us to deserialize them directly into an extension scope on the other side, saving us a lot of additional structured clone overhead and intermediate garbage generation. - Using JSONFile.jsm for storage lets us consolidate multiple storage file write operations, rather than performing a separate JSON serialization for each individual storage write. - Additionally, this paves the way for us to transition to IndexedDB as a storage backend, with full support for arbitrary structured-clone-compatible data structures. MozReview-Commit-ID: JiRE7EFMYxn --HG-- extra : rebase_source : caed13b099e7cb05de8d516761e32298a7a81ee5 extra : source : 42d3c1599af53b047d7ccd6b1c92ab08975284d7
85 lines
2.9 KiB
JavaScript
85 lines
2.9 KiB
JavaScript
"use strict";
|
|
|
|
// The ext-* files are imported into the same scopes.
|
|
/* import-globals-from ext-toolkit.js */
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionStorage",
|
|
"resource://gre/modules/ExtensionStorage.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "extensionStorageSync",
|
|
"resource://gre/modules/ExtensionStorageSync.jsm");
|
|
XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
|
|
"resource://gre/modules/AddonManager.jsm");
|
|
|
|
var {
|
|
ExtensionError,
|
|
} = ExtensionUtils;
|
|
|
|
const enforceNoTemporaryAddon = extensionId => {
|
|
const EXCEPTION_MESSAGE =
|
|
"The storage API will not work with a temporary addon ID. " +
|
|
"Please add an explicit addon ID to your manifest. " +
|
|
"For more information see https://bugzil.la/1323228.";
|
|
if (AddonManagerPrivate.isTemporaryInstallID(extensionId)) {
|
|
throw new ExtensionError(EXCEPTION_MESSAGE);
|
|
}
|
|
};
|
|
|
|
this.storage = class extends ExtensionAPI {
|
|
getAPI(context) {
|
|
let {extension} = context;
|
|
return {
|
|
storage: {
|
|
local: {
|
|
get: function(spec) {
|
|
return ExtensionStorage.get(extension.id, spec);
|
|
},
|
|
set: function(items) {
|
|
return ExtensionStorage.set(extension.id, items);
|
|
},
|
|
remove: function(keys) {
|
|
return ExtensionStorage.remove(extension.id, keys);
|
|
},
|
|
clear: function() {
|
|
return ExtensionStorage.clear(extension.id);
|
|
},
|
|
},
|
|
|
|
sync: {
|
|
get: function(spec) {
|
|
enforceNoTemporaryAddon(extension.id);
|
|
return extensionStorageSync.get(extension, spec, context);
|
|
},
|
|
set: function(items) {
|
|
enforceNoTemporaryAddon(extension.id);
|
|
return extensionStorageSync.set(extension, items, context);
|
|
},
|
|
remove: function(keys) {
|
|
enforceNoTemporaryAddon(extension.id);
|
|
return extensionStorageSync.remove(extension, keys, context);
|
|
},
|
|
clear: function() {
|
|
enforceNoTemporaryAddon(extension.id);
|
|
return extensionStorageSync.clear(extension, context);
|
|
},
|
|
},
|
|
|
|
onChanged: new EventManager(context, "storage.onChanged", fire => {
|
|
let listenerLocal = changes => {
|
|
fire.raw(changes, "local");
|
|
};
|
|
let listenerSync = changes => {
|
|
fire.async(changes, "sync");
|
|
};
|
|
|
|
ExtensionStorage.addOnChangedListener(extension.id, listenerLocal);
|
|
extensionStorageSync.addOnChangedListener(extension, listenerSync, context);
|
|
return () => {
|
|
ExtensionStorage.removeOnChangedListener(extension.id, listenerLocal);
|
|
extensionStorageSync.removeOnChangedListener(extension, listenerSync);
|
|
};
|
|
}).api(),
|
|
},
|
|
};
|
|
}
|
|
};
|