wxt 0.19.13 → 0.19.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.d.ts +1 -1
- package/dist/client/content-scripts/content-script-context.mjs +3 -1
- package/dist/client/content-scripts/ui/index.d.ts +1 -1
- package/dist/core/generate-wxt-dir.mjs +1 -1
- package/dist/core/resolve-config.mjs +3 -0
- package/dist/core/runners/web-ext.mjs +4 -1
- package/dist/core/utils/building/find-entrypoints.mjs +2 -2
- package/dist/core/utils/content-scripts.mjs +0 -3
- package/dist/storage.d.ts +2 -224
- package/dist/storage.mjs +1 -390
- package/dist/version.mjs +1 -1
- package/package.json +17 -17
package/dist/browser/index.d.ts
CHANGED
|
@@ -23,4 +23,4 @@ export interface WxtI18n {
|
|
|
23
23
|
export declare const browser: AugmentedBrowser;
|
|
24
24
|
/** @ignore */
|
|
25
25
|
export type { ActivityLog, Alarms, Bookmarks, Action, BrowserAction, BrowserSettings, BrowsingData, CaptivePortal, Clipboard, Commands, ContentScripts, ContextualIdentities, Cookies, DeclarativeNetRequest, Devtools, Dns, Downloads, Events, Experiments, Extension, ExtensionTypes, Find, GeckoProfiler, History, I18n, Identity, Idle, Management, Manifest, // TODO: Export custom manifest types that are valid for both Chrome and Firefox.
|
|
26
|
-
ContextMenus, Menus, NetworkStatus, NormandyAddonStudy, Notifications, Omnibox, PageAction, Permissions, Pkcs11, Privacy, Proxy, Runtime, Scripting, Search, Sessions, SidebarAction, Storage, Tabs, Theme, TopSites, Types,
|
|
26
|
+
ContextMenus, Menus, NetworkStatus, NormandyAddonStudy, Notifications, Omnibox, PageAction, Permissions, Pkcs11, Privacy, Proxy, Runtime, Scripting, Search, Sessions, SidebarAction, Storage, Tabs, Theme, TopSites, Types, UserScripts, WebNavigation, WebRequest, Windows, } from 'webextension-polyfill';
|
|
@@ -14,7 +14,9 @@ export class ContentScriptContext {
|
|
|
14
14
|
this.listenForNewerScripts();
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
static SCRIPT_STARTED_MESSAGE_TYPE =
|
|
17
|
+
static SCRIPT_STARTED_MESSAGE_TYPE = getUniqueEventName(
|
|
18
|
+
"wxt:content-script-started"
|
|
19
|
+
);
|
|
18
20
|
isTopFrame = window.self === window.top;
|
|
19
21
|
abortController;
|
|
20
22
|
locationWatcher = createLocationWatcher(this);
|
|
@@ -18,6 +18,6 @@ export declare function createIframeUi<TMounted>(ctx: ContentScriptContext, opti
|
|
|
18
18
|
*
|
|
19
19
|
* > This function is async because it has to load the CSS via a network call.
|
|
20
20
|
*
|
|
21
|
-
* @see https://wxt.dev/guide/essentials/content-scripts.html#
|
|
21
|
+
* @see https://wxt.dev/guide/essentials/content-scripts.html#shadow-root
|
|
22
22
|
*/
|
|
23
23
|
export declare function createShadowRootUi<TMounted>(ctx: ContentScriptContext, options: ShadowRootContentScriptUiOptions<TMounted>): Promise<ShadowRootContentScriptUi<TMounted>>;
|
|
@@ -43,7 +43,7 @@ async function getPathsDeclarationEntry(entrypoints) {
|
|
|
43
43
|
wxt.config.outDir,
|
|
44
44
|
isHtmlEntrypoint(entry) ? ".html" : ".js"
|
|
45
45
|
)
|
|
46
|
-
).concat(await getPublicFiles());
|
|
46
|
+
).concat([""]).concat(await getPublicFiles());
|
|
47
47
|
await wxt.hooks.callHook("prepare:publicPaths", wxt, paths);
|
|
48
48
|
const unions = paths.map(normalizePath).sort().map((path2) => ` | "/${path2}"`).join("\n");
|
|
49
49
|
const template = `// Generated by wxt
|
|
@@ -23,6 +23,9 @@ export async function resolveConfig(inlineConfig, command) {
|
|
|
23
23
|
esmResolve: true
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
|
+
if (inlineConfig.configFile && metadata.layers?.length === 0) {
|
|
27
|
+
throw Error(`Config file "${inlineConfig.configFile}" not found`);
|
|
28
|
+
}
|
|
26
29
|
userConfig = loadedConfig ?? {};
|
|
27
30
|
userConfigMetadata = metadata;
|
|
28
31
|
}
|
|
@@ -34,7 +34,10 @@ export function createWebExtRunner() {
|
|
|
34
34
|
wxtUserConfig?.chromiumPref,
|
|
35
35
|
DEFAULT_CHROMIUM_PREFS
|
|
36
36
|
),
|
|
37
|
-
args:
|
|
37
|
+
args: [
|
|
38
|
+
"--unsafely-disable-devtools-self-xss-warnings",
|
|
39
|
+
...wxtUserConfig?.chromiumArgs ?? []
|
|
40
|
+
]
|
|
38
41
|
}
|
|
39
42
|
};
|
|
40
43
|
const finalConfig = {
|
|
@@ -176,7 +176,7 @@ async function getPopupEntrypoint(info) {
|
|
|
176
176
|
const options = await getHtmlEntrypointOptions(
|
|
177
177
|
info,
|
|
178
178
|
{
|
|
179
|
-
browserStyle: "
|
|
179
|
+
browserStyle: "browser_style",
|
|
180
180
|
exclude: "exclude",
|
|
181
181
|
include: "include",
|
|
182
182
|
defaultIcon: "default_icon",
|
|
@@ -204,7 +204,7 @@ async function getOptionsEntrypoint(info) {
|
|
|
204
204
|
const options = await getHtmlEntrypointOptions(
|
|
205
205
|
info,
|
|
206
206
|
{
|
|
207
|
-
browserStyle: "
|
|
207
|
+
browserStyle: "browser_style",
|
|
208
208
|
chromeStyle: "chrome_style",
|
|
209
209
|
exclude: "exclude",
|
|
210
210
|
include: "include",
|
|
@@ -15,7 +15,6 @@ export function hashContentScriptOptions(options) {
|
|
|
15
15
|
match_about_blank: false,
|
|
16
16
|
run_at: "document_idle",
|
|
17
17
|
all_frames: false,
|
|
18
|
-
// @ts-expect-error - not in type
|
|
19
18
|
match_origin_as_fallback: false,
|
|
20
19
|
world: "ISOLATED",
|
|
21
20
|
...simplifiedOptions
|
|
@@ -38,7 +37,6 @@ export function mapWxtOptionsToContentScript(options, js, css) {
|
|
|
38
37
|
run_at: options.runAt,
|
|
39
38
|
css,
|
|
40
39
|
js,
|
|
41
|
-
// @ts-expect-error: untyped chrome options
|
|
42
40
|
match_origin_as_fallback: options.matchOriginAsFallback,
|
|
43
41
|
world: options.world
|
|
44
42
|
};
|
|
@@ -51,7 +49,6 @@ export function mapWxtOptionsToRegisteredContentScript(options, js, css) {
|
|
|
51
49
|
runAt: options.runAt,
|
|
52
50
|
js,
|
|
53
51
|
css,
|
|
54
|
-
// @ts-expect-error: Chrome accepts this, not typed in webextension-polyfill (https://developer.chrome.com/docs/extensions/reference/scripting/#type-RegisteredContentScript)
|
|
55
52
|
world: options.world
|
|
56
53
|
};
|
|
57
54
|
}
|
package/dist/storage.d.ts
CHANGED
|
@@ -1,226 +1,4 @@
|
|
|
1
|
-
export declare const storage: WxtStorage;
|
|
2
|
-
export interface WxtStorage {
|
|
3
|
-
/**
|
|
4
|
-
* Get an item from storage, or return `null` if it doesn't exist.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* await storage.getItem<number>("local:installDate");
|
|
8
|
-
*/
|
|
9
|
-
getItem<TValue>(key: StorageItemKey, opts: GetItemOptions<TValue> & {
|
|
10
|
-
fallback: TValue;
|
|
11
|
-
}): Promise<TValue>;
|
|
12
|
-
getItem<TValue>(key: StorageItemKey, opts?: GetItemOptions<TValue>): Promise<TValue | null>;
|
|
13
|
-
/**
|
|
14
|
-
* Get multiple items from storage. The return order is guaranteed to be the same as the order
|
|
15
|
-
* requested.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* await storage.getItems(["local:installDate", "session:someCounter"]);
|
|
19
|
-
*/
|
|
20
|
-
getItems(keys: Array<StorageItemKey | {
|
|
21
|
-
key: StorageItemKey;
|
|
22
|
-
options?: GetItemOptions<any>;
|
|
23
|
-
}>): Promise<Array<{
|
|
24
|
-
key: StorageItemKey;
|
|
25
|
-
value: any;
|
|
26
|
-
}>>;
|
|
27
|
-
/**
|
|
28
|
-
* Return an object containing metadata about the key. Object is stored at `key + "$"`. If value
|
|
29
|
-
* is not an object, it returns an empty object.
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* await storage.getMeta("local:installDate");
|
|
33
|
-
*/
|
|
34
|
-
getMeta<T extends Record<string, unknown>>(key: StorageItemKey): Promise<T>;
|
|
35
|
-
/**
|
|
36
|
-
* Set a value in storage. Setting a value to `null` or `undefined` is equivalent to calling
|
|
37
|
-
* `removeItem`.
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* await storage.setItem<number>("local:installDate", Date.now());
|
|
41
|
-
*/
|
|
42
|
-
setItem<T>(key: StorageItemKey, value: T | null): Promise<void>;
|
|
43
|
-
/**
|
|
44
|
-
* Set multiple values in storage. If a value is set to `null` or `undefined`, the key is removed.
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* await storage.setItem([
|
|
48
|
-
* { key: "local:installDate", value: Date.now() },
|
|
49
|
-
* { key: "session:someCounter, value: 5 },
|
|
50
|
-
* ]);
|
|
51
|
-
*/
|
|
52
|
-
setItems(values: Array<{
|
|
53
|
-
key: StorageItemKey;
|
|
54
|
-
value: any;
|
|
55
|
-
}>): Promise<void>;
|
|
56
|
-
/**
|
|
57
|
-
* Sets metadata properties. If some properties are already set, but are not included in the
|
|
58
|
-
* `properties` parameter, they will not be removed.
|
|
59
|
-
*
|
|
60
|
-
* @example
|
|
61
|
-
* await storage.setMeta("local:installDate", { appVersion });
|
|
62
|
-
*/
|
|
63
|
-
setMeta<T extends Record<string, unknown>>(key: StorageItemKey, properties: T | null): Promise<void>;
|
|
64
|
-
/**
|
|
65
|
-
* Removes an item from storage.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* await storage.removeItem("local:installDate");
|
|
69
|
-
*/
|
|
70
|
-
removeItem(key: StorageItemKey, opts?: RemoveItemOptions): Promise<void>;
|
|
71
|
-
/**
|
|
72
|
-
* Remove a list of keys from storage.
|
|
73
|
-
*/
|
|
74
|
-
removeItems(keys: Array<StorageItemKey | {
|
|
75
|
-
key: StorageItemKey;
|
|
76
|
-
options?: RemoveItemOptions;
|
|
77
|
-
}>): Promise<void>;
|
|
78
|
-
/**
|
|
79
|
-
* Remove the entire metadata for a key, or specific properties by name.
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* // Remove all metadata properties from the item
|
|
83
|
-
* await storage.removeMeta("local:installDate");
|
|
84
|
-
*
|
|
85
|
-
* // Remove only specific the "v" field
|
|
86
|
-
* await storage.removeMeta("local:installDate", "v")
|
|
87
|
-
*/
|
|
88
|
-
removeMeta(key: StorageItemKey, properties?: string | string[]): Promise<void>;
|
|
89
|
-
/**
|
|
90
|
-
* Return all the items in storage.
|
|
91
|
-
*/
|
|
92
|
-
snapshot(base: StorageArea, opts?: SnapshotOptions): Promise<Record<string, unknown>>;
|
|
93
|
-
/**
|
|
94
|
-
* Restores the results of `snapshot`. If new properties have been saved since the snapshot, they are
|
|
95
|
-
* not overridden. Only values existing in the snapshot are overridden.
|
|
96
|
-
*/
|
|
97
|
-
restoreSnapshot(base: StorageArea, data: any): Promise<void>;
|
|
98
|
-
/**
|
|
99
|
-
* Watch for changes to a specific key in storage.
|
|
100
|
-
*/
|
|
101
|
-
watch<T>(key: StorageItemKey, cb: WatchCallback<T | null>): Unwatch;
|
|
102
|
-
/**
|
|
103
|
-
* Remove all watch listeners.
|
|
104
|
-
*/
|
|
105
|
-
unwatch(): void;
|
|
106
|
-
/**
|
|
107
|
-
* Define a storage item with a default value, type, or versioning.
|
|
108
|
-
*
|
|
109
|
-
* Read full docs: https://wxt.dev/guide/extension-apis/storage.html#defining-storage-items
|
|
110
|
-
*/
|
|
111
|
-
defineItem<TValue, TMetadata extends Record<string, unknown> = {}>(key: StorageItemKey): WxtStorageItem<TValue | null, TMetadata>;
|
|
112
|
-
defineItem<TValue, TMetadata extends Record<string, unknown> = {}>(key: StorageItemKey, options: WxtStorageItemOptions<TValue>): WxtStorageItem<TValue, TMetadata>;
|
|
113
|
-
}
|
|
114
|
-
export interface WxtStorageItem<TValue, TMetadata extends Record<string, unknown>> {
|
|
115
|
-
/**
|
|
116
|
-
* @deprecated Renamed to `fallback`, use it instead.
|
|
117
|
-
*/
|
|
118
|
-
defaultValue: TValue;
|
|
119
|
-
/**
|
|
120
|
-
* The value provided by the `fallback` option.
|
|
121
|
-
*/
|
|
122
|
-
fallback: TValue;
|
|
123
|
-
/**
|
|
124
|
-
* Get the latest value from storage.
|
|
125
|
-
*/
|
|
126
|
-
getValue(): Promise<TValue>;
|
|
127
|
-
/**
|
|
128
|
-
* Get metadata.
|
|
129
|
-
*/
|
|
130
|
-
getMeta(): Promise<NullablePartial<TMetadata>>;
|
|
131
|
-
/**
|
|
132
|
-
* Set the value in storage.
|
|
133
|
-
*/
|
|
134
|
-
setValue(value: TValue): Promise<void>;
|
|
135
|
-
/**
|
|
136
|
-
* Set metadata properties.
|
|
137
|
-
*/
|
|
138
|
-
setMeta(properties: NullablePartial<TMetadata>): Promise<void>;
|
|
139
|
-
/**
|
|
140
|
-
* Remove the value from storage.
|
|
141
|
-
*/
|
|
142
|
-
removeValue(opts?: RemoveItemOptions): Promise<void>;
|
|
143
|
-
/**
|
|
144
|
-
* Remove all metadata or certain properties from metadata.
|
|
145
|
-
*/
|
|
146
|
-
removeMeta(properties?: string[]): Promise<void>;
|
|
147
|
-
/**
|
|
148
|
-
* Listen for changes to the value in storage.
|
|
149
|
-
*/
|
|
150
|
-
watch(cb: WatchCallback<TValue>): Unwatch;
|
|
151
|
-
/**
|
|
152
|
-
* If there are migrations defined on the storage item, migrate to the latest version.
|
|
153
|
-
*
|
|
154
|
-
* **This function is ran automatically whenever the extension updates**, so you don't have to call it
|
|
155
|
-
* manually.
|
|
156
|
-
*/
|
|
157
|
-
migrate(): Promise<void>;
|
|
158
|
-
}
|
|
159
|
-
export type StorageArea = 'local' | 'session' | 'sync' | 'managed';
|
|
160
|
-
export type StorageItemKey = `${StorageArea}:${string}`;
|
|
161
|
-
export interface GetItemOptions<T> {
|
|
162
|
-
/**
|
|
163
|
-
* @deprecated Renamed to `fallback`, use it instead.
|
|
164
|
-
*/
|
|
165
|
-
defaultValue?: T;
|
|
166
|
-
/**
|
|
167
|
-
* Default value returned when `getItem` would otherwise return `null`.
|
|
168
|
-
*/
|
|
169
|
-
fallback?: T;
|
|
170
|
-
}
|
|
171
|
-
export interface RemoveItemOptions {
|
|
172
|
-
/**
|
|
173
|
-
* Optionally remove metadata when deleting a key.
|
|
174
|
-
*
|
|
175
|
-
* @default false
|
|
176
|
-
*/
|
|
177
|
-
removeMeta?: boolean;
|
|
178
|
-
}
|
|
179
|
-
export interface SnapshotOptions {
|
|
180
|
-
/**
|
|
181
|
-
* Exclude a list of keys. The storage area prefix should be removed since the snapshot is for a
|
|
182
|
-
* specific storage area already.
|
|
183
|
-
*/
|
|
184
|
-
excludeKeys?: string[];
|
|
185
|
-
}
|
|
186
|
-
export interface WxtStorageItemOptions<T> {
|
|
187
|
-
/**
|
|
188
|
-
* @deprecated Renamed to `fallback`, use it instead.
|
|
189
|
-
*/
|
|
190
|
-
defaultValue?: T;
|
|
191
|
-
/**
|
|
192
|
-
* Default value returned when `getValue` would otherwise return `null`.
|
|
193
|
-
*/
|
|
194
|
-
fallback?: T;
|
|
195
|
-
/**
|
|
196
|
-
* If passed, a value in storage will be initialized immediately after
|
|
197
|
-
* defining the storage item. This function returns the value that will be
|
|
198
|
-
* saved to storage during the initialization process if a value doesn't
|
|
199
|
-
* already exist.
|
|
200
|
-
*/
|
|
201
|
-
init?: () => T | Promise<T>;
|
|
202
|
-
/**
|
|
203
|
-
* Provide a version number for the storage item to enable migrations. When changing the version
|
|
204
|
-
* in the future, migration functions will be ran on application startup.
|
|
205
|
-
*/
|
|
206
|
-
version?: number;
|
|
207
|
-
/**
|
|
208
|
-
* A map of version numbers to the functions used to migrate the data to that version.
|
|
209
|
-
*/
|
|
210
|
-
migrations?: Record<number, (oldValue: any) => any>;
|
|
211
|
-
}
|
|
212
1
|
/**
|
|
213
|
-
*
|
|
214
|
-
* nullable.
|
|
2
|
+
* @module @wxt-dev/storage
|
|
215
3
|
*/
|
|
216
|
-
export
|
|
217
|
-
[key in keyof T]+?: T[key] | undefined | null;
|
|
218
|
-
};
|
|
219
|
-
/**
|
|
220
|
-
* Callback called when a value in storage is changed.
|
|
221
|
-
*/
|
|
222
|
-
export type WatchCallback<T> = (newValue: T, oldValue: T) => void;
|
|
223
|
-
/**
|
|
224
|
-
* Call to remove a watch listener
|
|
225
|
-
*/
|
|
226
|
-
export type Unwatch = () => void;
|
|
4
|
+
export * from '@wxt-dev/storage';
|
package/dist/storage.mjs
CHANGED
|
@@ -1,390 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { dequal } from "dequal/lite";
|
|
3
|
-
import { logger } from "./sandbox/utils/logger.mjs";
|
|
4
|
-
import { toArray } from "./core/utils/arrays.mjs";
|
|
5
|
-
import { Mutex } from "async-mutex";
|
|
6
|
-
export const storage = createStorage();
|
|
7
|
-
function createStorage() {
|
|
8
|
-
const drivers = {
|
|
9
|
-
local: createDriver("local"),
|
|
10
|
-
session: createDriver("session"),
|
|
11
|
-
sync: createDriver("sync"),
|
|
12
|
-
managed: createDriver("managed")
|
|
13
|
-
};
|
|
14
|
-
const getDriver = (area) => {
|
|
15
|
-
const driver = drivers[area];
|
|
16
|
-
if (driver == null) {
|
|
17
|
-
const areaNames = Object.keys(drivers).join(", ");
|
|
18
|
-
throw Error(`Invalid area "${area}". Options: ${areaNames}`);
|
|
19
|
-
}
|
|
20
|
-
return driver;
|
|
21
|
-
};
|
|
22
|
-
const resolveKey = (key) => {
|
|
23
|
-
const deliminatorIndex = key.indexOf(":");
|
|
24
|
-
const driverArea = key.substring(0, deliminatorIndex);
|
|
25
|
-
const driverKey = key.substring(deliminatorIndex + 1);
|
|
26
|
-
if (driverKey == null)
|
|
27
|
-
throw Error(
|
|
28
|
-
`Storage key should be in the form of "area:key", but received "${key}"`
|
|
29
|
-
);
|
|
30
|
-
return {
|
|
31
|
-
driverArea,
|
|
32
|
-
driverKey,
|
|
33
|
-
driver: getDriver(driverArea)
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
const getMetaKey = (key) => key + "$";
|
|
37
|
-
const getValueOrFallback = (value, fallback) => value ?? fallback ?? null;
|
|
38
|
-
const getMetaValue = (properties) => typeof properties === "object" && !Array.isArray(properties) ? properties : {};
|
|
39
|
-
const getItem = async (driver, driverKey, opts) => {
|
|
40
|
-
const res = await driver.getItem(driverKey);
|
|
41
|
-
return getValueOrFallback(res, opts?.fallback ?? opts?.defaultValue);
|
|
42
|
-
};
|
|
43
|
-
const getMeta = async (driver, driverKey) => {
|
|
44
|
-
const metaKey = getMetaKey(driverKey);
|
|
45
|
-
const res = await driver.getItem(metaKey);
|
|
46
|
-
return getMetaValue(res);
|
|
47
|
-
};
|
|
48
|
-
const setItem = async (driver, driverKey, value) => {
|
|
49
|
-
await driver.setItem(driverKey, value ?? null);
|
|
50
|
-
};
|
|
51
|
-
const setMeta = async (driver, driverKey, properties) => {
|
|
52
|
-
const metaKey = getMetaKey(driverKey);
|
|
53
|
-
const existingFields = getMetaValue(await driver.getItem(metaKey));
|
|
54
|
-
const newFields = { ...existingFields };
|
|
55
|
-
Object.entries(properties).forEach(([key, value]) => {
|
|
56
|
-
if (value == null) {
|
|
57
|
-
delete newFields[key];
|
|
58
|
-
} else {
|
|
59
|
-
newFields[key] = value;
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
await driver.setItem(metaKey, newFields);
|
|
63
|
-
};
|
|
64
|
-
const removeItem = async (driver, driverKey, opts) => {
|
|
65
|
-
await driver.removeItem(driverKey);
|
|
66
|
-
if (opts?.removeMeta) {
|
|
67
|
-
const metaKey = getMetaKey(driverKey);
|
|
68
|
-
await driver.removeItem(metaKey);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
const removeMeta = async (driver, driverKey, properties) => {
|
|
72
|
-
const metaKey = getMetaKey(driverKey);
|
|
73
|
-
if (properties == null) {
|
|
74
|
-
await driver.removeItem(metaKey);
|
|
75
|
-
} else {
|
|
76
|
-
const newFields = getMetaValue(await driver.getItem(metaKey));
|
|
77
|
-
toArray(properties).forEach((field) => delete newFields[field]);
|
|
78
|
-
await driver.setItem(metaKey, newFields);
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
const watch = (driver, driverKey, cb) => {
|
|
82
|
-
return driver.watch(driverKey, cb);
|
|
83
|
-
};
|
|
84
|
-
const storage2 = {
|
|
85
|
-
getItem: async (key, opts) => {
|
|
86
|
-
const { driver, driverKey } = resolveKey(key);
|
|
87
|
-
return await getItem(driver, driverKey, opts);
|
|
88
|
-
},
|
|
89
|
-
getItems: async (keys) => {
|
|
90
|
-
const areaToKeyMap = /* @__PURE__ */ new Map();
|
|
91
|
-
const keyToOptsMap = /* @__PURE__ */ new Map();
|
|
92
|
-
keys.forEach((key) => {
|
|
93
|
-
let keyStr;
|
|
94
|
-
let opts;
|
|
95
|
-
if (typeof key === "string") {
|
|
96
|
-
keyStr = key;
|
|
97
|
-
} else {
|
|
98
|
-
keyStr = key.key;
|
|
99
|
-
opts = key.options;
|
|
100
|
-
}
|
|
101
|
-
const { driverArea, driverKey } = resolveKey(keyStr);
|
|
102
|
-
const keys2 = areaToKeyMap.get(driverArea) ?? [];
|
|
103
|
-
areaToKeyMap.set(driverArea, keys2.concat(driverKey));
|
|
104
|
-
keyToOptsMap.set(keyStr, opts);
|
|
105
|
-
});
|
|
106
|
-
const results = await Promise.all(
|
|
107
|
-
Array.from(areaToKeyMap.entries()).map(async ([driverArea, keys2]) => {
|
|
108
|
-
const driverResults = await drivers[driverArea].getItems(keys2);
|
|
109
|
-
return driverResults.map((driverResult) => {
|
|
110
|
-
const key = `${driverArea}:${driverResult.key}`;
|
|
111
|
-
const opts = keyToOptsMap.get(key);
|
|
112
|
-
const value = getValueOrFallback(
|
|
113
|
-
driverResult.value,
|
|
114
|
-
opts?.fallback ?? opts?.defaultValue
|
|
115
|
-
);
|
|
116
|
-
return { key, value };
|
|
117
|
-
});
|
|
118
|
-
})
|
|
119
|
-
);
|
|
120
|
-
return results.flat();
|
|
121
|
-
},
|
|
122
|
-
getMeta: async (key) => {
|
|
123
|
-
const { driver, driverKey } = resolveKey(key);
|
|
124
|
-
return await getMeta(driver, driverKey);
|
|
125
|
-
},
|
|
126
|
-
setItem: async (key, value) => {
|
|
127
|
-
const { driver, driverKey } = resolveKey(key);
|
|
128
|
-
await setItem(driver, driverKey, value);
|
|
129
|
-
},
|
|
130
|
-
setItems: async (values) => {
|
|
131
|
-
const areaToKeyValueMap = /* @__PURE__ */ new Map();
|
|
132
|
-
values.forEach(({ key, value }) => {
|
|
133
|
-
const { driverArea, driverKey } = resolveKey(key);
|
|
134
|
-
const values2 = areaToKeyValueMap.get(driverArea) ?? [];
|
|
135
|
-
areaToKeyValueMap.set(
|
|
136
|
-
driverArea,
|
|
137
|
-
values2.concat({ key: driverKey, value })
|
|
138
|
-
);
|
|
139
|
-
});
|
|
140
|
-
await Promise.all(
|
|
141
|
-
Array.from(areaToKeyValueMap.entries()).map(
|
|
142
|
-
async ([driverArea, values2]) => {
|
|
143
|
-
const driver = getDriver(driverArea);
|
|
144
|
-
await driver.setItems(values2);
|
|
145
|
-
}
|
|
146
|
-
)
|
|
147
|
-
);
|
|
148
|
-
},
|
|
149
|
-
setMeta: async (key, properties) => {
|
|
150
|
-
const { driver, driverKey } = resolveKey(key);
|
|
151
|
-
await setMeta(driver, driverKey, properties);
|
|
152
|
-
},
|
|
153
|
-
removeItem: async (key, opts) => {
|
|
154
|
-
const { driver, driverKey } = resolveKey(key);
|
|
155
|
-
await removeItem(driver, driverKey, opts);
|
|
156
|
-
},
|
|
157
|
-
removeItems: async (keys) => {
|
|
158
|
-
const areaToKeysMap = /* @__PURE__ */ new Map();
|
|
159
|
-
keys.forEach((key) => {
|
|
160
|
-
let keyStr;
|
|
161
|
-
let opts;
|
|
162
|
-
if (typeof key === "string") {
|
|
163
|
-
keyStr = key;
|
|
164
|
-
} else {
|
|
165
|
-
keyStr = key.key;
|
|
166
|
-
opts = key.options;
|
|
167
|
-
}
|
|
168
|
-
const { driverArea, driverKey } = resolveKey(keyStr);
|
|
169
|
-
const areaKeys = areaToKeysMap.get(driverArea) ?? [];
|
|
170
|
-
areaKeys.push(driverKey);
|
|
171
|
-
if (opts?.removeMeta) {
|
|
172
|
-
areaKeys.push(getMetaKey(driverKey));
|
|
173
|
-
}
|
|
174
|
-
areaToKeysMap.set(driverArea, areaKeys);
|
|
175
|
-
});
|
|
176
|
-
await Promise.all(
|
|
177
|
-
Array.from(areaToKeysMap.entries()).map(async ([driverArea, keys2]) => {
|
|
178
|
-
const driver = getDriver(driverArea);
|
|
179
|
-
await driver.removeItems(keys2);
|
|
180
|
-
})
|
|
181
|
-
);
|
|
182
|
-
},
|
|
183
|
-
removeMeta: async (key, properties) => {
|
|
184
|
-
const { driver, driverKey } = resolveKey(key);
|
|
185
|
-
await removeMeta(driver, driverKey, properties);
|
|
186
|
-
},
|
|
187
|
-
snapshot: async (base, opts) => {
|
|
188
|
-
const driver = getDriver(base);
|
|
189
|
-
const data = await driver.snapshot();
|
|
190
|
-
opts?.excludeKeys?.forEach((key) => {
|
|
191
|
-
delete data[key];
|
|
192
|
-
delete data[getMetaKey(key)];
|
|
193
|
-
});
|
|
194
|
-
return data;
|
|
195
|
-
},
|
|
196
|
-
restoreSnapshot: async (base, data) => {
|
|
197
|
-
const driver = getDriver(base);
|
|
198
|
-
await driver.restoreSnapshot(data);
|
|
199
|
-
},
|
|
200
|
-
watch: (key, cb) => {
|
|
201
|
-
const { driver, driverKey } = resolveKey(key);
|
|
202
|
-
return watch(driver, driverKey, cb);
|
|
203
|
-
},
|
|
204
|
-
unwatch() {
|
|
205
|
-
Object.values(drivers).forEach((driver) => {
|
|
206
|
-
driver.unwatch();
|
|
207
|
-
});
|
|
208
|
-
},
|
|
209
|
-
defineItem: (key, opts) => {
|
|
210
|
-
const { driver, driverKey } = resolveKey(key);
|
|
211
|
-
const { version: targetVersion = 1, migrations = {} } = opts ?? {};
|
|
212
|
-
if (targetVersion < 1) {
|
|
213
|
-
throw Error(
|
|
214
|
-
"Storage item version cannot be less than 1. Initial versions should be set to 1, not 0."
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
const migrate = async () => {
|
|
218
|
-
const driverMetaKey = getMetaKey(driverKey);
|
|
219
|
-
const [{ value }, { value: meta }] = await driver.getItems([
|
|
220
|
-
driverKey,
|
|
221
|
-
driverMetaKey
|
|
222
|
-
]);
|
|
223
|
-
if (value == null) return;
|
|
224
|
-
const currentVersion = meta?.v ?? 1;
|
|
225
|
-
if (currentVersion > targetVersion) {
|
|
226
|
-
throw Error(
|
|
227
|
-
`Version downgrade detected (v${currentVersion} -> v${targetVersion}) for "${key}"`
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
logger.debug(
|
|
231
|
-
`Running storage migration for ${key}: v${currentVersion} -> v${targetVersion}`
|
|
232
|
-
);
|
|
233
|
-
const migrationsToRun = Array.from(
|
|
234
|
-
{ length: targetVersion - currentVersion },
|
|
235
|
-
(_, i) => currentVersion + i + 1
|
|
236
|
-
);
|
|
237
|
-
let migratedValue = value;
|
|
238
|
-
for (const migrateToVersion of migrationsToRun) {
|
|
239
|
-
migratedValue = await migrations?.[migrateToVersion]?.(migratedValue) ?? migratedValue;
|
|
240
|
-
}
|
|
241
|
-
await driver.setItems([
|
|
242
|
-
{ key: driverKey, value: migratedValue },
|
|
243
|
-
{ key: driverMetaKey, value: { ...meta, v: targetVersion } }
|
|
244
|
-
]);
|
|
245
|
-
logger.debug(
|
|
246
|
-
`Storage migration completed for ${key} v${targetVersion}`,
|
|
247
|
-
{ migratedValue }
|
|
248
|
-
);
|
|
249
|
-
};
|
|
250
|
-
const migrationsDone = opts?.migrations == null ? Promise.resolve() : migrate().catch((err) => {
|
|
251
|
-
logger.error(`Migration failed for ${key}`, err);
|
|
252
|
-
});
|
|
253
|
-
const initMutex = new Mutex();
|
|
254
|
-
const getFallback = () => opts?.fallback ?? opts?.defaultValue ?? null;
|
|
255
|
-
const getOrInitValue = () => initMutex.runExclusive(async () => {
|
|
256
|
-
const value = await driver.getItem(driverKey);
|
|
257
|
-
if (value != null || opts?.init == null) return value;
|
|
258
|
-
const newValue = await opts.init();
|
|
259
|
-
await driver.setItem(driverKey, newValue);
|
|
260
|
-
return newValue;
|
|
261
|
-
});
|
|
262
|
-
migrationsDone.then(getOrInitValue);
|
|
263
|
-
return {
|
|
264
|
-
get defaultValue() {
|
|
265
|
-
return getFallback();
|
|
266
|
-
},
|
|
267
|
-
get fallback() {
|
|
268
|
-
return getFallback();
|
|
269
|
-
},
|
|
270
|
-
getValue: async () => {
|
|
271
|
-
await migrationsDone;
|
|
272
|
-
if (opts?.init) {
|
|
273
|
-
return await getOrInitValue();
|
|
274
|
-
} else {
|
|
275
|
-
return await getItem(driver, driverKey, opts);
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
getMeta: async () => {
|
|
279
|
-
await migrationsDone;
|
|
280
|
-
return await getMeta(driver, driverKey);
|
|
281
|
-
},
|
|
282
|
-
setValue: async (value) => {
|
|
283
|
-
await migrationsDone;
|
|
284
|
-
return await setItem(driver, driverKey, value);
|
|
285
|
-
},
|
|
286
|
-
setMeta: async (properties) => {
|
|
287
|
-
await migrationsDone;
|
|
288
|
-
return await setMeta(driver, driverKey, properties);
|
|
289
|
-
},
|
|
290
|
-
removeValue: async (opts2) => {
|
|
291
|
-
await migrationsDone;
|
|
292
|
-
return await removeItem(driver, driverKey, opts2);
|
|
293
|
-
},
|
|
294
|
-
removeMeta: async (properties) => {
|
|
295
|
-
await migrationsDone;
|
|
296
|
-
return await removeMeta(driver, driverKey, properties);
|
|
297
|
-
},
|
|
298
|
-
watch: (cb) => watch(
|
|
299
|
-
driver,
|
|
300
|
-
driverKey,
|
|
301
|
-
(newValue, oldValue) => cb(newValue ?? getFallback(), oldValue ?? getFallback())
|
|
302
|
-
),
|
|
303
|
-
migrate
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
};
|
|
307
|
-
return storage2;
|
|
308
|
-
}
|
|
309
|
-
function createDriver(storageArea) {
|
|
310
|
-
const getStorageArea = () => {
|
|
311
|
-
if (browser.runtime == null) {
|
|
312
|
-
throw Error(
|
|
313
|
-
[
|
|
314
|
-
"'wxt/storage' must be loaded in a web extension environment",
|
|
315
|
-
"\n - If thrown during a build, see https://github.com/wxt-dev/wxt/issues/371",
|
|
316
|
-
" - If thrown during tests, mock 'wxt/browser' correctly. See https://wxt.dev/guide/go-further/testing.html\n"
|
|
317
|
-
].join("\n")
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
if (browser.storage == null) {
|
|
321
|
-
throw Error(
|
|
322
|
-
"You must add the 'storage' permission to your manifest to use 'wxt/storage'"
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
|
-
const area = browser.storage[storageArea];
|
|
326
|
-
if (area == null)
|
|
327
|
-
throw Error(`"browser.storage.${storageArea}" is undefined`);
|
|
328
|
-
return area;
|
|
329
|
-
};
|
|
330
|
-
const watchListeners = /* @__PURE__ */ new Set();
|
|
331
|
-
return {
|
|
332
|
-
getItem: async (key) => {
|
|
333
|
-
const res = await getStorageArea().get(key);
|
|
334
|
-
return res[key];
|
|
335
|
-
},
|
|
336
|
-
getItems: async (keys) => {
|
|
337
|
-
const result = await getStorageArea().get(keys);
|
|
338
|
-
return keys.map((key) => ({ key, value: result[key] ?? null }));
|
|
339
|
-
},
|
|
340
|
-
setItem: async (key, value) => {
|
|
341
|
-
if (value == null) {
|
|
342
|
-
await getStorageArea().remove(key);
|
|
343
|
-
} else {
|
|
344
|
-
await getStorageArea().set({ [key]: value });
|
|
345
|
-
}
|
|
346
|
-
},
|
|
347
|
-
setItems: async (values) => {
|
|
348
|
-
const map = values.reduce(
|
|
349
|
-
(map2, { key, value }) => {
|
|
350
|
-
map2[key] = value;
|
|
351
|
-
return map2;
|
|
352
|
-
},
|
|
353
|
-
{}
|
|
354
|
-
);
|
|
355
|
-
await getStorageArea().set(map);
|
|
356
|
-
},
|
|
357
|
-
removeItem: async (key) => {
|
|
358
|
-
await getStorageArea().remove(key);
|
|
359
|
-
},
|
|
360
|
-
removeItems: async (keys) => {
|
|
361
|
-
await getStorageArea().remove(keys);
|
|
362
|
-
},
|
|
363
|
-
snapshot: async () => {
|
|
364
|
-
return await getStorageArea().get();
|
|
365
|
-
},
|
|
366
|
-
restoreSnapshot: async (data) => {
|
|
367
|
-
await getStorageArea().set(data);
|
|
368
|
-
},
|
|
369
|
-
watch(key, cb) {
|
|
370
|
-
const listener = (changes) => {
|
|
371
|
-
const change = changes[key];
|
|
372
|
-
if (change == null) return;
|
|
373
|
-
if (dequal(change.newValue, change.oldValue)) return;
|
|
374
|
-
cb(change.newValue ?? null, change.oldValue ?? null);
|
|
375
|
-
};
|
|
376
|
-
getStorageArea().onChanged.addListener(listener);
|
|
377
|
-
watchListeners.add(listener);
|
|
378
|
-
return () => {
|
|
379
|
-
getStorageArea().onChanged.removeListener(listener);
|
|
380
|
-
watchListeners.delete(listener);
|
|
381
|
-
};
|
|
382
|
-
},
|
|
383
|
-
unwatch() {
|
|
384
|
-
watchListeners.forEach((listener) => {
|
|
385
|
-
getStorageArea().onChanged.removeListener(listener);
|
|
386
|
-
});
|
|
387
|
-
watchListeners.clear();
|
|
388
|
-
}
|
|
389
|
-
};
|
|
390
|
-
}
|
|
1
|
+
export * from "@wxt-dev/storage";
|
package/dist/version.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "0.19.
|
|
1
|
+
export const version = "0.19.15";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wxt",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.19.
|
|
4
|
+
"version": "0.19.15",
|
|
5
5
|
"description": "Next gen framework for developing web extensions",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -71,19 +71,19 @@
|
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@aklinker1/rollup-plugin-visualizer": "5.12.0",
|
|
74
|
-
"@types/chrome": "^0.0.
|
|
75
|
-
"@types/webextension-polyfill": "^0.
|
|
74
|
+
"@types/chrome": "^0.0.280",
|
|
75
|
+
"@types/webextension-polyfill": "^0.12.1",
|
|
76
76
|
"@webext-core/fake-browser": "^1.3.1",
|
|
77
77
|
"@webext-core/isolated-element": "^1.1.2",
|
|
78
78
|
"@webext-core/match-patterns": "^1.0.3",
|
|
79
|
+
"@wxt-dev/storage": "^1.0.0",
|
|
79
80
|
"async-mutex": "^0.5.0",
|
|
80
81
|
"c12": "^1.11.2",
|
|
81
82
|
"cac": "^6.7.14",
|
|
82
83
|
"chokidar": "^3.6.0",
|
|
83
|
-
"ci-info": "^4.
|
|
84
|
+
"ci-info": "^4.1.0",
|
|
84
85
|
"consola": "^3.2.3",
|
|
85
86
|
"defu": "^6.1.4",
|
|
86
|
-
"dequal": "^2.0.3",
|
|
87
87
|
"dotenv": "^16.4.5",
|
|
88
88
|
"esbuild": "^0.21.5",
|
|
89
89
|
"fast-glob": "^3.3.2",
|
|
@@ -99,40 +99,40 @@
|
|
|
99
99
|
"linkedom": "^0.18.5",
|
|
100
100
|
"magicast": "^0.3.5",
|
|
101
101
|
"minimatch": "^10.0.1",
|
|
102
|
-
"nano-spawn": "^0.
|
|
102
|
+
"nano-spawn": "^0.2.0",
|
|
103
103
|
"normalize-path": "^3.0.0",
|
|
104
104
|
"nypm": "^0.3.12",
|
|
105
105
|
"ohash": "^1.1.4",
|
|
106
106
|
"open": "^10.1.0",
|
|
107
|
-
"ora": "^8.1.
|
|
107
|
+
"ora": "^8.1.1",
|
|
108
108
|
"perfect-debounce": "^1.0.0",
|
|
109
|
-
"picocolors": "^1.1.
|
|
109
|
+
"picocolors": "^1.1.1",
|
|
110
110
|
"prompts": "^2.4.2",
|
|
111
111
|
"publish-browser-extension": "^2.2.2",
|
|
112
112
|
"scule": "^1.3.0",
|
|
113
113
|
"unimport": "^3.13.1",
|
|
114
|
-
"vite": "^5.4.
|
|
115
|
-
"vite-node": "^2.1.
|
|
114
|
+
"vite": "^5.4.11",
|
|
115
|
+
"vite-node": "^2.1.4",
|
|
116
116
|
"web-ext-run": "^0.2.1",
|
|
117
117
|
"webextension-polyfill": "^0.12.0"
|
|
118
118
|
},
|
|
119
119
|
"devDependencies": {
|
|
120
120
|
"@aklinker1/check": "^1.4.5",
|
|
121
|
-
"@faker-js/faker": "^
|
|
121
|
+
"@faker-js/faker": "^9.2.0",
|
|
122
122
|
"@types/fs-extra": "^11.0.4",
|
|
123
123
|
"@types/lodash.merge": "^4.6.9",
|
|
124
|
-
"@types/node": "^20.
|
|
124
|
+
"@types/node": "^20.17.6",
|
|
125
125
|
"@types/normalize-path": "^3.0.2",
|
|
126
126
|
"@types/prompts": "^2.4.9",
|
|
127
127
|
"extract-zip": "^2.0.1",
|
|
128
|
-
"happy-dom": "^
|
|
128
|
+
"happy-dom": "^15.11.4",
|
|
129
129
|
"lodash.merge": "^4.6.2",
|
|
130
|
-
"oxlint": "^0.
|
|
131
|
-
"publint": "^0.2.
|
|
130
|
+
"oxlint": "^0.11.1",
|
|
131
|
+
"publint": "^0.2.12",
|
|
132
132
|
"tsx": "4.15.7",
|
|
133
|
-
"typescript": "^5.6.
|
|
133
|
+
"typescript": "^5.6.3",
|
|
134
134
|
"unbuild": "^2.0.0",
|
|
135
|
-
"vitest": "^2.1.
|
|
135
|
+
"vitest": "^2.1.4",
|
|
136
136
|
"vitest-plugin-random-seed": "^1.1.0"
|
|
137
137
|
},
|
|
138
138
|
"peerDependenciesMeta": {
|