wxt 0.12.5 → 0.13.1-alpha1

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.
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "0.12.5";
2
+ var version = "0.13.1-alpha1";
3
3
 
4
4
  // src/core/utils/arrays.ts
5
5
  function every(array, predicate) {
@@ -435,7 +435,7 @@ async function writeMainDeclarationFile(references, config) {
435
435
  filePath,
436
436
  [
437
437
  "// Generated by wxt",
438
- `/// <reference types="vite/client" />`,
438
+ `/// <reference types="wxt/vite-builder-env" />`,
439
439
  ...references.map(
440
440
  (ref) => `/// <reference types="./${normalizePath(relative2(dir, ref))}" />`
441
441
  )
package/dist/cli.js CHANGED
@@ -4,7 +4,7 @@ import "./chunk-VBXJIVYU.js";
4
4
  import cac from "cac";
5
5
 
6
6
  // package.json
7
- var version = "0.12.5";
7
+ var version = "0.13.1-alpha1";
8
8
 
9
9
  // src/core/utils/fs.ts
10
10
  import fs from "fs-extra";
@@ -756,7 +756,7 @@ async function writeMainDeclarationFile(references, config) {
756
756
  filePath,
757
757
  [
758
758
  "// Generated by wxt",
759
- `/// <reference types="vite/client" />`,
759
+ `/// <reference types="wxt/vite-builder-env" />`,
760
760
  ...references.map(
761
761
  (ref) => `/// <reference types="./${normalizePath(relative3(dir, ref))}" />`
762
762
  )
package/dist/index.cjs CHANGED
@@ -3177,7 +3177,7 @@ async function writeMainDeclarationFile(references, config) {
3177
3177
  filePath,
3178
3178
  [
3179
3179
  "// Generated by wxt",
3180
- `/// <reference types="vite/client" />`,
3180
+ `/// <reference types="wxt/vite-builder-env" />`,
3181
3181
  ...references.map(
3182
3182
  (ref) => `/// <reference types="./${normalizePath((0, import_path3.relative)(dir, ref))}" />`
3183
3183
  )
@@ -4334,7 +4334,7 @@ function getChunkSortWeight(filename) {
4334
4334
  var import_picocolors3 = __toESM(require("picocolors"), 1);
4335
4335
 
4336
4336
  // package.json
4337
- var version = "0.12.5";
4337
+ var version = "0.13.1-alpha1";
4338
4338
 
4339
4339
  // src/core/utils/log/printHeader.ts
4340
4340
  var import_consola2 = require("consola");
package/dist/index.d.cts CHANGED
@@ -62,6 +62,6 @@ declare function prepare(config: InlineConfig): Promise<void>;
62
62
  */
63
63
  declare function zip(config?: InlineConfig): Promise<string[]>;
64
64
 
65
- var version = "0.12.5";
65
+ var version = "0.13.1-alpha1";
66
66
 
67
67
  export { BuildOutput, ExtensionRunnerConfig, InlineConfig, UserConfig, WxtDevServer, build, clean, createServer, defineConfig, defineRunnerConfig, initialize, prepare, version, zip };
package/dist/index.d.ts CHANGED
@@ -62,6 +62,6 @@ declare function prepare(config: InlineConfig): Promise<void>;
62
62
  */
63
63
  declare function zip(config?: InlineConfig): Promise<string[]>;
64
64
 
65
- var version = "0.12.5";
65
+ var version = "0.13.1-alpha1";
66
66
 
67
67
  export { BuildOutput, ExtensionRunnerConfig, InlineConfig, UserConfig, WxtDevServer, build, clean, createServer, defineConfig, defineRunnerConfig, initialize, prepare, version, zip };
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  rebuild,
16
16
  resolvePerBrowserOption,
17
17
  version
18
- } from "./chunk-JK5CNMJT.js";
18
+ } from "./chunk-UMDTDPYN.js";
19
19
  import "./chunk-VBXJIVYU.js";
20
20
 
21
21
  // src/core/build.ts
package/dist/storage.cjs CHANGED
@@ -17,7 +17,6 @@ var __copyProps = (to, from, except, desc) => {
17
17
  }
18
18
  return to;
19
19
  };
20
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
21
20
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
21
  // If the importer is in node compatibility mode or this is not an ESM
23
22
  // file that has been converted to a CommonJS file using a Babel-
@@ -31,111 +30,341 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
30
  // src/storage.ts
32
31
  var storage_exports = {};
33
32
  __export(storage_exports, {
34
- storage: () => storage,
35
- webExtensionDriver: () => webExtensionDriver
33
+ storage: () => storage
36
34
  });
37
35
  module.exports = __toCommonJS(storage_exports);
38
- var import_unstorage = require("unstorage");
39
36
 
40
37
  // src/browser.ts
41
38
  var import_webextension_polyfill = __toESM(require("webextension-polyfill"), 1);
42
39
  var browser = import_webextension_polyfill.default;
43
40
 
44
41
  // src/storage.ts
45
- __reExport(storage_exports, require("unstorage"), module.exports);
46
- var webExtensionDriver = (0, import_unstorage.defineDriver)((opts) => {
47
- const checkPermission = () => {
48
- if (browser.storage == null)
42
+ var import_lite = require("dequal/lite");
43
+ var storage = createStorage();
44
+ function createStorage() {
45
+ const drivers = {
46
+ local: createDriver("local"),
47
+ session: createDriver("session"),
48
+ sync: createDriver("sync"),
49
+ managed: createDriver("managed")
50
+ };
51
+ const getDriver = (area) => {
52
+ const driver = drivers[area];
53
+ if (driver == null) {
54
+ const areaNames = Object.keys(drivers).join(", ");
55
+ throw Error(`Invalid area "${area}". Options: ${areaNames}`);
56
+ }
57
+ return driver;
58
+ };
59
+ const resolveKey = (key) => {
60
+ const deliminatorIndex = key.indexOf(":");
61
+ const driverArea = key.substring(0, deliminatorIndex);
62
+ const driverKey = key.substring(deliminatorIndex + 1);
63
+ if (driverKey == null)
49
64
  throw Error(
50
- "You must request the 'storage' permission to use webExtensionDriver"
65
+ `Storage key should be in the form of "area:key", but recieved "${key}"`
51
66
  );
67
+ return {
68
+ driverArea,
69
+ driverKey,
70
+ driver: getDriver(driverArea)
71
+ };
52
72
  };
53
- const _storageListener = (changes) => {
54
- Object.entries(changes).forEach(([key, { newValue }]) => {
55
- _listeners.forEach((callback) => {
56
- callback(newValue ? "update" : "remove", key);
57
- });
73
+ const getMetaKey = (key) => key + "$";
74
+ const getValueOrDefault = (value, defaultValue) => value ?? defaultValue ?? null;
75
+ const getMetaValue = (properties) => typeof properties === "object" && !Array.isArray(properties) ? properties : {};
76
+ const getItem = async (driver, driverKey, opts) => {
77
+ const res = await driver.getItem(driverKey);
78
+ return getValueOrDefault(res, opts?.defaultValue);
79
+ };
80
+ const getMeta = async (driver, driverKey) => {
81
+ const metaKey = getMetaKey(driverKey);
82
+ const res = await driver.getItem(metaKey);
83
+ return getMetaValue(res);
84
+ };
85
+ const setItem = async (driver, driverKey, value) => {
86
+ await driver.setItem(driverKey, value ?? null);
87
+ };
88
+ const setMeta = async (driver, driverKey, properties) => {
89
+ const metaKey = getMetaKey(driverKey);
90
+ const existingFields = getMetaValue(await driver.getItem(metaKey));
91
+ const newFields = { ...existingFields };
92
+ Object.entries(properties).forEach(([key, value]) => {
93
+ if (value == null) {
94
+ delete newFields[key];
95
+ } else {
96
+ newFields[key] = value;
97
+ }
58
98
  });
99
+ await driver.setItem(metaKey, newFields);
59
100
  };
60
- const _listeners = /* @__PURE__ */ new Set();
61
- return {
62
- name: "web-extension:" + opts.storageArea,
63
- async hasItem(key) {
64
- checkPermission();
65
- const res = await browser.storage[opts.storageArea].get(key);
66
- return res[key] != null;
67
- },
68
- async getItem(key) {
69
- checkPermission();
70
- const res = await browser.storage[opts.storageArea].get(key);
71
- return res[key] ?? null;
72
- },
73
- async getItems(items) {
74
- checkPermission();
75
- const res = await browser.storage[opts.storageArea].get(
76
- items.map((item) => item.key)
101
+ const removeItem = async (driver, driverKey, opts) => {
102
+ await driver.removeItem(driverKey);
103
+ if (opts?.removeMeta) {
104
+ const metaKey = getMetaKey(driverKey);
105
+ await driver.removeItem(metaKey);
106
+ }
107
+ };
108
+ const removeMeta = async (driver, driverKey, properties) => {
109
+ const metaKey = getMetaKey(driverKey);
110
+ if (properties == null) {
111
+ await driver.removeItem(metaKey);
112
+ } else {
113
+ const newFields = getMetaValue(await driver.getItem(metaKey));
114
+ [properties].flat().forEach((field) => delete newFields[field]);
115
+ await driver.setItem(metaKey, newFields);
116
+ }
117
+ };
118
+ const watch = (driver, driverKey, cb) => {
119
+ return driver.watch(driverKey, cb);
120
+ };
121
+ const storage2 = {
122
+ getItem: async (key, opts) => {
123
+ const { driver, driverKey } = resolveKey(key);
124
+ return await getItem(driver, driverKey, opts);
125
+ },
126
+ getItems: async (keys) => {
127
+ const areaToKeyMap = /* @__PURE__ */ new Map();
128
+ const keyToOptsMap = /* @__PURE__ */ new Map();
129
+ keys.forEach((key) => {
130
+ let keyStr;
131
+ let opts;
132
+ if (typeof key === "string") {
133
+ keyStr = key;
134
+ } else {
135
+ keyStr = key.key;
136
+ opts = key.options;
137
+ }
138
+ const { driverArea, driverKey } = resolveKey(keyStr);
139
+ const keys2 = areaToKeyMap.get(driverArea) ?? [];
140
+ areaToKeyMap.set(driverArea, keys2.concat(driverKey));
141
+ keyToOptsMap.set(keyStr, opts);
142
+ });
143
+ const results = await Promise.all(
144
+ Array.from(areaToKeyMap.entries()).map(async ([driverArea, keys2]) => {
145
+ const driverResults = await drivers[driverArea].getItems(keys2);
146
+ return driverResults.map((driverResult) => {
147
+ const key = `${driverArea}:${driverResult.key}`;
148
+ const value = getValueOrDefault(
149
+ driverResult.value,
150
+ keyToOptsMap.get(key)?.defaultValue
151
+ );
152
+ return { key, value };
153
+ });
154
+ })
77
155
  );
78
- return items.map((item) => ({
79
- key: item.key,
80
- value: res[item.key] ?? null
81
- }));
82
- },
83
- async setItem(key, value) {
84
- checkPermission();
85
- await browser.storage[opts.storageArea].set({ [key]: value ?? null });
86
- },
87
- async setItems(items) {
88
- checkPermission();
89
- const map = items.reduce((map2, item) => {
90
- map2[item.key] = item.value ?? null;
91
- return map2;
92
- }, {});
93
- await browser.storage[opts.storageArea].set(map);
94
- },
95
- async removeItem(key) {
96
- checkPermission();
97
- await browser.storage[opts.storageArea].remove(key);
98
- },
99
- async getKeys() {
100
- checkPermission();
101
- const all = await browser.storage[opts.storageArea].get();
102
- return Object.keys(all);
103
- },
104
- async clear() {
105
- checkPermission();
106
- await browser.storage[opts.storageArea].clear();
107
- },
108
- watch(callback) {
109
- checkPermission();
110
- _listeners.add(callback);
111
- if (_listeners.size === 1) {
112
- browser.storage[opts.storageArea].onChanged.addListener(
113
- _storageListener
156
+ return results.flat();
157
+ },
158
+ getMeta: async (key) => {
159
+ const { driver, driverKey } = resolveKey(key);
160
+ return await getMeta(driver, driverKey);
161
+ },
162
+ setItem: async (key, value) => {
163
+ const { driver, driverKey } = resolveKey(key);
164
+ await setItem(driver, driverKey, value);
165
+ },
166
+ setItems: async (values) => {
167
+ const areaToKeyValueMap = /* @__PURE__ */ new Map();
168
+ values.forEach(({ key, value }) => {
169
+ const { driverArea, driverKey } = resolveKey(key);
170
+ const values2 = areaToKeyValueMap.get(driverArea) ?? [];
171
+ areaToKeyValueMap.set(
172
+ driverArea,
173
+ values2.concat({ key: driverKey, value })
174
+ );
175
+ });
176
+ await Promise.all(
177
+ Array.from(areaToKeyValueMap.entries()).map(
178
+ async ([driverArea, values2]) => {
179
+ const driver = getDriver(driverArea);
180
+ await driver.setItems(values2);
181
+ }
182
+ )
183
+ );
184
+ },
185
+ setMeta: async (key, properties) => {
186
+ const { driver, driverKey } = resolveKey(key);
187
+ await setMeta(driver, driverKey, properties);
188
+ },
189
+ removeItem: async (key, opts) => {
190
+ const { driver, driverKey } = resolveKey(key);
191
+ await removeItem(driver, driverKey, opts);
192
+ },
193
+ removeItems: async (keys) => {
194
+ const areaToKeysMap = /* @__PURE__ */ new Map();
195
+ keys.forEach((key) => {
196
+ let keyStr;
197
+ let opts;
198
+ if (typeof key === "string") {
199
+ keyStr = key;
200
+ } else {
201
+ keyStr = key.key;
202
+ opts = key.options;
203
+ }
204
+ const { driverArea, driverKey } = resolveKey(keyStr);
205
+ const areaKeys = areaToKeysMap.get(driverArea) ?? [];
206
+ areaKeys.push(driverKey);
207
+ if (opts?.removeMeta) {
208
+ areaKeys.push(getMetaKey(driverKey));
209
+ }
210
+ areaToKeysMap.set(driverArea, areaKeys);
211
+ });
212
+ await Promise.all(
213
+ Array.from(areaToKeysMap.entries()).map(async ([driverArea, keys2]) => {
214
+ const driver = getDriver(driverArea);
215
+ await driver.removeItems(keys2);
216
+ })
217
+ );
218
+ },
219
+ removeMeta: async (key, properties) => {
220
+ const { driver, driverKey } = resolveKey(key);
221
+ await removeMeta(driver, driverKey, properties);
222
+ },
223
+ snapshot: async (base, opts) => {
224
+ const driver = getDriver(base);
225
+ const data = await driver.snapshot();
226
+ opts?.excludeKeys?.forEach((key) => {
227
+ delete data[key];
228
+ delete data[getMetaKey(key)];
229
+ });
230
+ return data;
231
+ },
232
+ restoreSnapshot: async (base, data) => {
233
+ const driver = getDriver(base);
234
+ await driver.restoreSnapshot(data);
235
+ },
236
+ watch: (key, cb) => {
237
+ const { driver, driverKey } = resolveKey(key);
238
+ return watch(driver, driverKey, cb);
239
+ },
240
+ unwatch() {
241
+ Object.values(drivers).forEach((driver) => {
242
+ driver.unwatch();
243
+ });
244
+ },
245
+ defineItem: (key, opts) => {
246
+ const { driver, driverKey } = resolveKey(key);
247
+ const { version: targetVersion = 1, migrations = {} } = opts ?? {};
248
+ if (targetVersion < 1) {
249
+ throw Error(
250
+ "Storage item version cannot be less than 1. Initial versions should be set to 1, not 0."
114
251
  );
115
252
  }
116
- return () => {
117
- _listeners.delete(callback);
118
- if (_listeners.size === 0) {
119
- browser.storage[opts.storageArea].onChanged.removeListener(
120
- _storageListener
253
+ const runMigrations = async () => {
254
+ const [value, meta] = await Promise.all([
255
+ // TODO: Optimize with getItems
256
+ getItem(driver, driverKey, void 0),
257
+ getMeta(driver, driverKey)
258
+ ]);
259
+ if (value == null)
260
+ return;
261
+ const currentVersion = meta.v ?? 1;
262
+ if (currentVersion > targetVersion) {
263
+ throw Error(
264
+ `[wxt/storage] Migration ignored for "${key}", version downgrade detected (${currentVersion} -> ${targetVersion})`
121
265
  );
122
266
  }
267
+ const migrationsToRun = Array.from(
268
+ { length: targetVersion - currentVersion },
269
+ (_, i) => currentVersion + i + 1
270
+ );
271
+ let migratedValue = value;
272
+ for (const migrateToVersion of migrationsToRun) {
273
+ migratedValue = await migrations?.[migrateToVersion]?.(migratedValue) ?? migratedValue;
274
+ }
275
+ await Promise.all([
276
+ // TODO: Optimize with `setItem`
277
+ setItem(driver, driverKey, migratedValue),
278
+ setMeta(driver, driverKey, { v: targetVersion })
279
+ ]);
280
+ };
281
+ let _migrationsCompleted = runMigrations();
282
+ return {
283
+ _migrationsCompleted,
284
+ getValue: () => getItem(driver, driverKey, opts),
285
+ getMeta: () => getMeta(driver, driverKey),
286
+ setValue: (value) => setItem(driver, driverKey, value),
287
+ setMeta: (properties) => setMeta(driver, driverKey, properties),
288
+ removeValue: (opts2) => removeItem(driver, driverKey, opts2),
289
+ removeMeta: (properties) => removeMeta(driver, driverKey, properties),
290
+ watch: (cb) => watch(driver, driverKey, cb)
123
291
  };
124
292
  }
125
293
  };
126
- });
127
- function createWebExtensionStorage() {
128
- const storage2 = (0, import_unstorage.createStorage)();
129
- storage2.mount("local", webExtensionDriver({ storageArea: "local" }));
130
- storage2.mount("session", webExtensionDriver({ storageArea: "session" }));
131
- storage2.mount("sync", webExtensionDriver({ storageArea: "sync" }));
132
- storage2.mount("managed", webExtensionDriver({ storageArea: "managed" }));
133
294
  return storage2;
134
295
  }
135
- var storage = createWebExtensionStorage();
296
+ function createDriver(storageArea) {
297
+ const getStorageArea = () => {
298
+ if (browser.storage == null)
299
+ throw Error(
300
+ "You must add the 'storage' permission to your manifest to use 'wxt/storage'"
301
+ );
302
+ return browser.storage[storageArea];
303
+ };
304
+ const watchListeners = /* @__PURE__ */ new Set();
305
+ return {
306
+ getItem: async (key) => {
307
+ const res = await getStorageArea().get(key);
308
+ return res[key];
309
+ },
310
+ getItems: async (keys) => {
311
+ const result = await getStorageArea().get(keys);
312
+ return keys.map((key) => ({ key, value: result[key] ?? null }));
313
+ },
314
+ setItem: async (key, value) => {
315
+ if (value == null) {
316
+ await getStorageArea().remove(key);
317
+ } else {
318
+ await getStorageArea().set({ [key]: value });
319
+ }
320
+ },
321
+ setItems: async (values) => {
322
+ const map = values.reduce(
323
+ (map2, { key, value }) => {
324
+ map2[key] = value;
325
+ return map2;
326
+ },
327
+ {}
328
+ );
329
+ await getStorageArea().set(map);
330
+ },
331
+ removeItem: async (key) => {
332
+ await getStorageArea().remove(key);
333
+ },
334
+ removeItems: async (keys) => {
335
+ await getStorageArea().remove(keys);
336
+ },
337
+ snapshot: async () => {
338
+ return await getStorageArea().get();
339
+ },
340
+ restoreSnapshot: async (data) => {
341
+ await getStorageArea().set(data);
342
+ },
343
+ watch(key, cb) {
344
+ const listener = (changes) => {
345
+ const change = changes[key];
346
+ if (change == null)
347
+ return;
348
+ if ((0, import_lite.dequal)(change.newValue, change.oldValue))
349
+ return;
350
+ cb(change.newValue ?? null, change.oldValue ?? null);
351
+ };
352
+ getStorageArea().onChanged.addListener(listener);
353
+ watchListeners.add(listener);
354
+ return () => {
355
+ getStorageArea().onChanged.removeListener(listener);
356
+ watchListeners.delete(listener);
357
+ };
358
+ },
359
+ unwatch() {
360
+ watchListeners.forEach((listener) => {
361
+ getStorageArea().onChanged.removeListener(listener);
362
+ });
363
+ watchListeners.clear();
364
+ }
365
+ };
366
+ }
136
367
  // Annotate the CommonJS export names for ESM import in node:
137
368
  0 && (module.exports = {
138
- storage,
139
- webExtensionDriver,
140
- ...require("unstorage")
369
+ storage
141
370
  });