@addonova/browser 0.1.0 → 0.2.0

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.
Files changed (99) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +259 -0
  3. package/dist/api/scripting/index.d.ts.map +1 -1
  4. package/dist/api/scripting/index.js.map +1 -1
  5. package/dist/api/storage/area.d.ts +4 -0
  6. package/dist/api/storage/area.d.ts.map +1 -0
  7. package/dist/api/storage/area.js +29 -0
  8. package/dist/api/storage/area.js.map +1 -0
  9. package/dist/api/storage/index.d.ts +4 -3
  10. package/dist/api/storage/index.d.ts.map +1 -1
  11. package/dist/api/storage/index.js +7 -27
  12. package/dist/api/storage/index.js.map +1 -1
  13. package/dist/api/storage/item.d.ts +4 -0
  14. package/dist/api/storage/item.d.ts.map +1 -0
  15. package/dist/api/storage/item.js +109 -0
  16. package/dist/api/storage/item.js.map +1 -0
  17. package/dist/content/context.d.ts +24 -0
  18. package/dist/content/context.d.ts.map +1 -0
  19. package/dist/content/context.js +157 -0
  20. package/dist/content/context.js.map +1 -0
  21. package/dist/content/index.d.ts +7 -0
  22. package/dist/content/index.d.ts.map +1 -0
  23. package/dist/content/index.js +4 -0
  24. package/dist/content/index.js.map +1 -0
  25. package/dist/content/inject-root.d.ts +2 -0
  26. package/dist/content/inject-root.d.ts.map +1 -0
  27. package/dist/content/inject-root.js +4 -0
  28. package/dist/content/inject-root.js.map +1 -0
  29. package/dist/content/inject-script.d.ts +16 -0
  30. package/dist/content/inject-script.d.ts.map +1 -0
  31. package/dist/content/inject-script.js +39 -0
  32. package/dist/content/inject-script.js.map +1 -0
  33. package/dist/content/ui.d.ts +50 -0
  34. package/dist/content/ui.d.ts.map +1 -0
  35. package/dist/content/ui.js +331 -0
  36. package/dist/content/ui.js.map +1 -0
  37. package/dist/entries/chrome.d.ts +3 -0
  38. package/dist/entries/chrome.d.ts.map +1 -1
  39. package/dist/entries/chrome.js +7 -0
  40. package/dist/entries/chrome.js.map +1 -1
  41. package/dist/entries/chromium.d.ts +3 -0
  42. package/dist/entries/chromium.d.ts.map +1 -1
  43. package/dist/entries/chromium.js +7 -0
  44. package/dist/entries/chromium.js.map +1 -1
  45. package/dist/entries/edge.d.ts +3 -0
  46. package/dist/entries/edge.d.ts.map +1 -1
  47. package/dist/entries/edge.js +7 -0
  48. package/dist/entries/edge.js.map +1 -1
  49. package/dist/entries/firefox.d.ts +3 -0
  50. package/dist/entries/firefox.d.ts.map +1 -1
  51. package/dist/entries/firefox.js +7 -0
  52. package/dist/entries/firefox.js.map +1 -1
  53. package/dist/entries/shared-exports.d.ts +10 -0
  54. package/dist/entries/shared-exports.d.ts.map +1 -1
  55. package/dist/entries/shared-exports.js +5 -0
  56. package/dist/entries/shared-exports.js.map +1 -1
  57. package/dist/entries/utilities.d.ts +6 -0
  58. package/dist/entries/utilities.d.ts.map +1 -0
  59. package/dist/entries/utilities.js +7 -0
  60. package/dist/entries/utilities.js.map +1 -0
  61. package/dist/i18n/index.d.ts +16 -0
  62. package/dist/i18n/index.d.ts.map +1 -0
  63. package/dist/i18n/index.js +52 -0
  64. package/dist/i18n/index.js.map +1 -0
  65. package/dist/index.d.ts +13 -0
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +8 -0
  68. package/dist/index.js.map +1 -1
  69. package/dist/messaging/index.d.ts +22 -0
  70. package/dist/messaging/index.d.ts.map +1 -0
  71. package/dist/messaging/index.js +100 -0
  72. package/dist/messaging/index.js.map +1 -0
  73. package/dist/messaging/proxy.d.ts +17 -0
  74. package/dist/messaging/proxy.d.ts.map +1 -0
  75. package/dist/messaging/proxy.js +61 -0
  76. package/dist/messaging/proxy.js.map +1 -0
  77. package/dist/messaging/root.d.ts +4 -0
  78. package/dist/messaging/root.d.ts.map +1 -0
  79. package/dist/messaging/root.js +9 -0
  80. package/dist/messaging/root.js.map +1 -0
  81. package/dist/testing/fake-browser.d.ts +184 -0
  82. package/dist/testing/fake-browser.d.ts.map +1 -0
  83. package/dist/testing/fake-browser.js +994 -0
  84. package/dist/testing/fake-browser.js.map +1 -0
  85. package/dist/testing/index.d.ts +3 -0
  86. package/dist/testing/index.d.ts.map +1 -0
  87. package/dist/testing/index.js +2 -0
  88. package/dist/testing/index.js.map +1 -0
  89. package/dist/testing/setup.d.ts +2 -0
  90. package/dist/testing/setup.d.ts.map +1 -0
  91. package/dist/testing/setup.js +6 -0
  92. package/dist/testing/setup.js.map +1 -0
  93. package/dist/types/index.d.ts +1 -1
  94. package/dist/types/index.d.ts.map +1 -1
  95. package/dist/types/scripting.d.ts +5 -5
  96. package/dist/types/scripting.d.ts.map +1 -1
  97. package/dist/types/storage.d.ts +23 -0
  98. package/dist/types/storage.d.ts.map +1 -1
  99. package/package.json +30 -2
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 hemanta-gayen
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CodeHemu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
package/README.md CHANGED
@@ -1,5 +1,19 @@
1
1
  [![Addonova Browser Social Banner](https://raw.githubusercontent.com/addonova/.github/refs/heads/main/profile/image/addonova_browser_banner.png)](https://github.com/addonova)
2
2
 
3
+ <div align="center">
4
+ <p>
5
+ <a href="https://www.npmjs.com/package/@addonova/browser"><img src="https://img.shields.io/npm/v/@addonova/browser?labelColor=%23153c26&color=%23ccff00" alt="Version"></a>
6
+ <a href="https://nodejs.org/en/about/previous-releases"><img src="https://img.shields.io/node/v/@addonova/browser?labelColor=%23153c26&color=%23ccff00" alt="node compatibility"></a>
7
+ <a href="https://raw.githubusercontent.com/addonova/browser/refs/heads/main/LICENSE"><img src="https://img.shields.io/github/license/addonova/browser?labelColor=%23153c26&color=%23ccff00" alt="License"></a>
8
+ <a href="https://github.com/addonova/browser/issues"><img src="https://img.shields.io/github/issues/addonova/browser?labelColor=%23153c26&color=%23ccff00" alt="Issues"></a>
9
+ <a href="https://github.com/addonova/browser/graphs/contributors"><img src="https://img.shields.io/github/contributors/addonova/browser?labelColor=%23153c26&color=%23ccff00" alt="Contributors"></a>
10
+ <a href="https://github.com/sponsors/code-hemu"><img src="https://img.shields.io/badge/Sponsor-GitHub-red?labelColor=%23153c26&color=%23ccff00" alt="Sponsor"></a>
11
+ </p>
12
+
13
+ **Unified API's for cross-browser extensions.**
14
+
15
+ </div>
16
+
3
17
  Browser extension APIs are similar but not identical. `@addonova/browser`
4
18
  normalizes the differences that can be normalized safely:
5
19
 
@@ -69,6 +83,251 @@ runtime.onInstalled.addListener((details) => {
69
83
  });
70
84
  ```
71
85
 
86
+ ## Runtime utilities
87
+
88
+ ### Typed storage
89
+
90
+ Use `storage.defineItem()` to keep a value typed, provide a fallback or lazy
91
+ initializer, and run versioned migrations:
92
+
93
+ ```ts
94
+ import { storage } from '@addonova/browser';
95
+
96
+ interface Settings {
97
+ theme: 'light' | 'dark';
98
+ compact: boolean;
99
+ }
100
+
101
+ const settings = storage.defineItem<Settings>('settings', {
102
+ area: 'local',
103
+ fallback: { theme: 'light', compact: false },
104
+ version: 2,
105
+ migrations: {
106
+ 2(value) {
107
+ return { compact: false, ...(value as Partial<Settings>) };
108
+ },
109
+ },
110
+ });
111
+
112
+ const current = await settings.getValue();
113
+ await settings.setValue({ ...current, theme: 'dark' });
114
+
115
+ const stop = settings.watch((newValue, oldValue) => {
116
+ console.log('settings changed', oldValue, newValue);
117
+ });
118
+ stop();
119
+ ```
120
+
121
+ `getMeta()` and `setMeta()` expose the stored item version. `removeValue()`
122
+ deletes the value; the next read falls back or initializes again.
123
+
124
+ ### Type-safe messaging
125
+
126
+ Define a message protocol once and share it between the sender and receiver:
127
+
128
+ ```ts
129
+ import { defineExtensionMessaging } from '@addonova/browser';
130
+
131
+ interface Protocol {
132
+ ping(data: { at: number }): { at: number };
133
+ add(a: number, b: number): number;
134
+ }
135
+
136
+ const messaging = defineExtensionMessaging<Protocol>();
137
+
138
+ // Background or any context with a listener.
139
+ messaging.onMessage('ping', ({ data, sender }) => {
140
+ console.log('ping from', sender.id, data.at);
141
+
142
+ return { at: Date.now() };
143
+ });
144
+
145
+ // Any extension context.
146
+ const response = await messaging.sendMessage('ping', { at: Date.now() });
147
+ ```
148
+
149
+ Errors thrown by a handler are serialized and rethrown on the sender. Use
150
+ `defineProxyService()` when the service has many methods:
151
+
152
+ ```ts
153
+ import { defineProxyService } from '@addonova/browser';
154
+
155
+ const [registerCounter, getCounter] = defineProxyService(
156
+ 'counter',
157
+ () => {
158
+ let value = 0;
159
+
160
+ return {
161
+ add(amount: number) {
162
+ value += amount;
163
+ return value;
164
+ },
165
+ read() {
166
+ return value;
167
+ },
168
+ };
169
+ },
170
+ );
171
+
172
+ registerCounter();
173
+ const counter = getCounter();
174
+
175
+ await counter.add(2);
176
+ await counter.read();
177
+ registerCounter.dispose();
178
+ ```
179
+
180
+ ### Content scripts
181
+
182
+ `createContentScriptContext()` tracks timers, animation frames, and listeners
183
+ and invalidates them together when the content script is unloaded:
184
+
185
+ ```ts
186
+ import {
187
+ createContentScriptContext,
188
+ injectScript,
189
+ } from '@addonova/browser';
190
+
191
+ const ctx = createContentScriptContext();
192
+
193
+ ctx.setTimeout(() => {
194
+ console.log('still valid:', ctx.isValid);
195
+ }, 1000);
196
+
197
+ ctx.addEventListener(document, 'click', () => {
198
+ console.log('clicked');
199
+ });
200
+
201
+ ctx.onInvalidated(() => {
202
+ console.log('content script invalidated');
203
+ });
204
+
205
+ await injectScript('/injected.js', { allFrames: false });
206
+ ```
207
+
208
+ Add `validateRuntime: false` when a test environment does not expose
209
+ `runtime.id`.
210
+
211
+ ### Content-script UI
212
+
213
+ Mount UI into the page, a shadow root, or an iframe:
214
+
215
+ ```ts
216
+ import {
217
+ createIntegratedUi,
218
+ createShadowRootUi,
219
+ } from '@addonova/browser';
220
+
221
+ const inline = createIntegratedUi(ctx, {
222
+ anchor: '#app',
223
+ append: 'last',
224
+ onMount(container) {
225
+ const button = document.createElement('button');
226
+ button.textContent = 'Addonova';
227
+ container.append(button);
228
+
229
+ return button;
230
+ },
231
+ });
232
+
233
+ await inline.mount();
234
+ inline.remove();
235
+
236
+ const panel = createShadowRootUi(ctx, {
237
+ anchor: 'body',
238
+ position: 'overlay',
239
+ alignment: 'bottom-right',
240
+ css: ':host { all: initial; } .panel { font: 14px sans-serif; }',
241
+ onMount(container) {
242
+ const element = document.createElement('div');
243
+ element.className = 'panel';
244
+ element.textContent = 'Shadow UI';
245
+ container.append(element);
246
+
247
+ return element;
248
+ },
249
+ });
250
+
251
+ await panel.mount();
252
+ panel.autoMount();
253
+ ```
254
+
255
+ UI helpers support `anchor` selectors or elements, `append` modes
256
+ (`first`, `last`, `before`, `after`, `replace`), `position`
257
+ (`inline`, `overlay`, `modal`), `alignment`, `zIndex`, and `onRemove`.
258
+ `autoMount()` mounts when the anchor appears, remounts when it is removed, and
259
+ stops on context invalidation.
260
+
261
+ ### i18n
262
+
263
+ ```ts
264
+ import { createI18nHelper, formatMessage, t } from '@addonova/browser';
265
+
266
+ const i18nHelper = createI18nHelper({ fallbackToKey: true });
267
+
268
+ i18nHelper.locale;
269
+ i18nHelper.t('greeting', 'Ada');
270
+ i18nHelper.raw('greeting', 'Ada');
271
+
272
+ t('items_selected', ['3']);
273
+ formatMessage('Selected $1 item(s)', '3');
274
+ ```
275
+
276
+ `t()` falls back to the message name when the browser returns an empty string.
277
+
278
+ ## Testing
279
+
280
+ ### Fake browser
281
+
282
+ `@addonova/browser/testing` provides an in-memory implementation of the runtime
283
+ API. It records storage, tabs, permissions, notifications, alarms, and events,
284
+ and routes `runtime.sendMessage()` through `onMessage` listeners.
285
+
286
+ ```ts
287
+ import {
288
+ createFakeBrowser,
289
+ installFakeBrowser,
290
+ resetFakeBrowser,
291
+ uninstallFakeBrowser,
292
+ } from '@addonova/browser/testing';
293
+
294
+ const fake = installFakeBrowser({ target: 'chrome' });
295
+
296
+ await fake.storage.local.set({ enabled: true });
297
+ fake.runtime.onMessage.addListener((message, _sender, sendResponse) => {
298
+ sendResponse({ ok: true });
299
+ return true;
300
+ });
301
+
302
+ resetFakeBrowser();
303
+ uninstallFakeBrowser();
304
+ ```
305
+
306
+ Use `createFakeBrowser()` for isolated instances and `fakeBrowser` for the
307
+ shared default. `reset()` clears state while keeping listeners.
308
+
309
+ ### Guchho Test setup
310
+
311
+ Register the setup file so the fake browser is installed before each test:
312
+
313
+ ```ts
314
+ // guchho.test.config.ts
315
+ import { defineConfig } from '@guchho/test';
316
+
317
+ export default defineConfig({
318
+ setupFiles: ['@addonova/browser/testing/setup'],
319
+ });
320
+ ```
321
+
322
+ The setup entry installs the fake browser before the suite, resets it before
323
+ each test, and uninstalls it afterwards. `@guchho/test` remains an optional peer
324
+ dependency.
325
+
326
+ ### End-to-end tests
327
+
328
+ See [`docs/playwright-e2e.md`](docs/playwright-e2e.md) for a Playwright guide
329
+ that loads the built extension into a persistent Chromium context.
330
+
72
331
  ## Browser compatibility
73
332
 
74
333
  The verified matrix is in
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/scripting/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAIV,YAAY,EACb,MAAM,0BAA0B,CAAC;AAGlC,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,cAAc,GACtB,YAAY,CA8Bd;AAGD,YAAY,EACV,YAAY,EACZ,eAAe,EACf,eAAe,EACf,eAAe,EACf,YAAY,GACb,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/scripting/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAIV,YAAY,EACb,MAAM,0BAA0B,CAAC;AAGlC,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,cAAc,GACtB,YAAY,CAiCd;AAGD,YAAY,EACV,YAAY,EACZ,eAAe,EACf,eAAe,EACf,eAAe,EACf,YAAY,GACb,MAAM,0BAA0B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/scripting/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,UAAU,kBAAkB,CAChC,OAAuB;IAEvB,OAAO;QACL,aAAa,CACX,SAAuD;YAEvD,OAAO,SAAS,CACd,OAAO,EACP,CAAC,WAAW,EAAE,eAAe,CAAC,EAC9B,SAAS,CACV,CAAC;QACJ,CAAC;QACD,SAAS,CACP,SAAiD;YAEjD,OAAO,SAAS,CACd,OAAO,EACP,CAAC,WAAW,EAAE,WAAW,CAAC,EAC1B,SAAS,CACV,CAAC;QACJ,CAAC;QACD,SAAS,CACP,SAAiD;YAEjD,OAAO,SAAS,CACd,OAAO,EACP,CAAC,WAAW,EAAE,WAAW,CAAC,EAC1B,SAAS,CACV,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/scripting/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,UAAU,kBAAkB,CAChC,OAAuB;IAEvB,OAAO;QACL,aAAa,CAIX,SAAmE;YAEnE,OAAO,SAAS,CACd,OAAO,EACP,CAAC,WAAW,EAAE,eAAe,CAAC,EAC9B,SAAS,CACV,CAAC;QACJ,CAAC;QACD,SAAS,CACP,SAAiD;YAEjD,OAAO,SAAS,CACd,OAAO,EACP,CAAC,WAAW,EAAE,WAAW,CAAC,EAC1B,SAAS,CACV,CAAC;QACJ,CAAC;QACD,SAAS,CACP,SAAiD;YAEjD,OAAO,SAAS,CACd,OAAO,EACP,CAAC,WAAW,EAAE,WAAW,CAAC,EAC1B,SAAS,CACV,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { BrowserAdapter } from '../../adapters/types.ts';
2
+ import type { StorageArea, StorageAreaName, StorageItems } from '../../types/storage.ts';
3
+ export declare function createStorageArea<T extends StorageItems = StorageItems>(adapter: BrowserAdapter, area: StorageAreaName): StorageArea<T>;
4
+ //# sourceMappingURL=area.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"area.d.ts","sourceRoot":"","sources":["../../../src/api/storage/area.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,YAAY,EAEb,MAAM,wBAAwB,CAAC;AAGhC,wBAAgB,iBAAiB,CAC/B,CAAC,SAAS,YAAY,GAAG,YAAY,EAErC,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,eAAe,GACpB,WAAW,CAAC,CAAC,CAAC,CAqChB"}
@@ -0,0 +1,29 @@
1
+ import { callAsync } from '../helpers.js';
2
+ export function createStorageArea(adapter, area) {
3
+ const path = (method) => ['storage', area, method];
4
+ const get = ((keys) => {
5
+ const target = path('get');
6
+ return keys === undefined
7
+ ? callAsync(adapter, target)
8
+ : callAsync(adapter, target, keys);
9
+ });
10
+ return {
11
+ get,
12
+ set(items) {
13
+ return callAsync(adapter, path('set'), items);
14
+ },
15
+ remove(keys) {
16
+ return callAsync(adapter, path('remove'), keys);
17
+ },
18
+ clear() {
19
+ return callAsync(adapter, path('clear'));
20
+ },
21
+ getBytesInUse(keys) {
22
+ const target = path('getBytesInUse');
23
+ return keys === undefined || keys === null
24
+ ? callAsync(adapter, target)
25
+ : callAsync(adapter, target, keys);
26
+ },
27
+ };
28
+ }
29
+ //# sourceMappingURL=area.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"area.js","sourceRoot":"","sources":["../../../src/api/storage/area.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,UAAU,iBAAiB,CAG/B,OAAuB,EACvB,IAAqB;IAErB,MAAM,IAAI,GAAG,CAAC,MAAc,EAAE,EAAE,CAC9B,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAU,CAAC;IAErC,MAAM,GAAG,GAAG,CAAC,CAAC,IAAc,EAAyB,EAAE;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAE3B,OAAO,IAAI,KAAK,SAAS;YACvB,CAAC,CAAC,SAAS,CAAe,OAAO,EAAE,MAAM,CAAC;YAC1C,CAAC,CAAC,SAAS,CAAe,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC,CAAqC,CAAC;IAEvC,OAAO;QACL,GAAG;QACH,GAAG,CAAC,KAAgC;YAClC,OAAO,SAAS,CAAO,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,CACJ,IAIQ;YAER,OAAO,SAAS,CAAO,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;QACxD,CAAC;QACD,KAAK;YACH,OAAO,SAAS,CAAO,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,aAAa,CAAC,IAAyB;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;YAErC,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;gBACxC,CAAC,CAAC,SAAS,CAAS,OAAO,EAAE,MAAM,CAAC;gBACpC,CAAC,CAAC,SAAS,CAAS,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import type { BrowserAdapter } from '../../adapters/types.ts';
2
- import type { StorageApi, StorageArea, StorageAreaName, StorageItems } from '../../types/storage.ts';
3
- export declare function createStorageArea<T extends StorageItems = StorageItems>(adapter: BrowserAdapter, area: StorageAreaName): StorageArea<T>;
2
+ import type { StorageApi } from '../../types/storage.ts';
4
3
  export declare function createStorageApi(adapter: BrowserAdapter): StorageApi;
5
- export type { StorageApi, StorageArea, StorageAreaName, StorageChange, StorageChanges, StorageItems, StorageKeys, } from '../../types/storage.ts';
4
+ export { createStorageArea } from './area.ts';
5
+ export { createStorageItem } from './item.ts';
6
+ export type { StorageApi, StorageAreaName, StorageChange, StorageChanges, StorageItem, StorageItemMeta, StorageItemOptions, StorageItemValue, StorageItems, StorageKeys, } from '../../types/storage.ts';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,eAAe,EACf,YAAY,EAEb,MAAM,wBAAwB,CAAC;AAOhC,wBAAgB,iBAAiB,CAC/B,CAAC,SAAS,YAAY,GAAG,YAAY,EAErC,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,eAAe,GACpB,WAAW,CAAC,CAAC,CAAC,CAqChB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,UAAU,CAiCpE;AAGD,YAAY,EACV,UAAU,EACV,WAAW,EACX,eAAe,EACf,aAAa,EACb,cAAc,EACd,YAAY,EACZ,WAAW,GACZ,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,wBAAwB,CAAC;AAShC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,UAAU,CAuCpE;AAGD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,YAAY,EACV,UAAU,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,WAAW,GACZ,MAAM,wBAAwB,CAAC"}
@@ -1,33 +1,11 @@
1
1
  import { callAsync, isCapabilityAvailable, requireEvent, } from '../helpers.js';
2
- export function createStorageArea(adapter, area) {
3
- const path = (method) => ['storage', area, method];
4
- const get = ((keys) => {
5
- const target = path('get');
6
- return keys === undefined
7
- ? callAsync(adapter, target)
8
- : callAsync(adapter, target, keys);
9
- });
10
- return {
11
- get,
12
- set(items) {
13
- return callAsync(adapter, path('set'), items);
14
- },
15
- remove(keys) {
16
- return callAsync(adapter, path('remove'), keys);
17
- },
18
- clear() {
19
- return callAsync(adapter, path('clear'));
20
- },
21
- getBytesInUse(keys) {
22
- const target = path('getBytesInUse');
23
- return keys === undefined || keys === null
24
- ? callAsync(adapter, target)
25
- : callAsync(adapter, target, keys);
26
- },
27
- };
28
- }
2
+ import { createStorageArea } from './area.js';
3
+ import { createStorageItem } from './item.js';
29
4
  export function createStorageApi(adapter) {
30
5
  return {
6
+ defineItem(key, options) {
7
+ return createStorageItem(adapter, key, options);
8
+ },
31
9
  get local() {
32
10
  return createStorageArea(adapter, 'local');
33
11
  },
@@ -54,4 +32,6 @@ export function createStorageApi(adapter) {
54
32
  },
55
33
  };
56
34
  }
35
+ export { createStorageArea } from './area.js';
36
+ export { createStorageItem } from './item.js';
57
37
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/storage/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,SAAS,EACT,qBAAqB,EACrB,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,MAAM,UAAU,iBAAiB,CAG/B,OAAuB,EACvB,IAAqB;IAErB,MAAM,IAAI,GAAG,CAAC,MAAc,EAAE,EAAE,CAC9B,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAU,CAAC;IAErC,MAAM,GAAG,GAAG,CAAC,CAAC,IAAc,EAAyB,EAAE;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAE3B,OAAO,IAAI,KAAK,SAAS;YACvB,CAAC,CAAC,SAAS,CAAe,OAAO,EAAE,MAAM,CAAC;YAC1C,CAAC,CAAC,SAAS,CAAe,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC,CAAqC,CAAC;IAEvC,OAAO;QACL,GAAG;QACH,GAAG,CAAC,KAAgC;YAClC,OAAO,SAAS,CAAO,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,CACJ,IAIQ;YAER,OAAO,SAAS,CAAO,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;QACxD,CAAC;QACD,KAAK;YACH,OAAO,SAAS,CAAO,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,aAAa,CAAC,IAAyB;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;YAErC,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;gBACxC,CAAC,CAAC,SAAS,CAAS,OAAO,EAAE,MAAM,CAAC;gBACpC,CAAC,CAAC,SAAS,CAAS,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAuB;IACtD,OAAO;QACL,IAAI,KAAK;YACP,OAAO,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,IAAI;YACN,OAAO,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,OAAO;YACT,OAAO,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,OAAO;YACT,OAAO,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/C,CAAC;QACD,eAAe,CAAC,IAAqB;YACnC,OAAO,qBAAqB,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;QAC3D,CAAC;QACD,aAAa,CACX,IAAqB,EACrB,IAAyB;YAEzB,MAAM,MAAM,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,eAAe,CAAU,CAAC;YAE3D,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;gBACxC,CAAC,CAAC,SAAS,CAAS,OAAO,EAAE,MAAM,CAAC;gBACpC,CAAC,CAAC,SAAS,CAAS,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,SAAS;YACX,OAAO,YAAY,CAEjB,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/storage/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,SAAS,EACT,qBAAqB,EACrB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,MAAM,UAAU,gBAAgB,CAAC,OAAuB;IACtD,OAAO;QACL,UAAU,CACR,GAAW,EACX,OAA+B;YAE/B,OAAO,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,KAAK;YACP,OAAO,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,IAAI;YACN,OAAO,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,OAAO;YACT,OAAO,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,OAAO;YACT,OAAO,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/C,CAAC;QACD,eAAe,CAAC,IAAqB;YACnC,OAAO,qBAAqB,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;QAC3D,CAAC;QACD,aAAa,CACX,IAAqB,EACrB,IAAyB;YAEzB,MAAM,MAAM,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,eAAe,CAAU,CAAC;YAE3D,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;gBACxC,CAAC,CAAC,SAAS,CAAS,OAAO,EAAE,MAAM,CAAC;gBACpC,CAAC,CAAC,SAAS,CAAS,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,SAAS;YACX,OAAO,YAAY,CAEjB,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC;AAGD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { BrowserAdapter } from '../../adapters/types.ts';
2
+ import type { StorageItem, StorageItemOptions } from '../../types/storage.ts';
3
+ export declare function createStorageItem<T>(adapter: BrowserAdapter, key: string, options?: StorageItemOptions<T>): StorageItem<T>;
4
+ //# sourceMappingURL=item.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../../../src/api/storage/item.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAIV,WAAW,EAEX,kBAAkB,EACnB,MAAM,wBAAwB,CAAC;AAOhC,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAkB,CAAC,CAAC,CAAM,GAClC,WAAW,CAAC,CAAC,CAAC,CA8IhB"}
@@ -0,0 +1,109 @@
1
+ import { BrowserApiError } from '../../shared/errors.js';
2
+ import { requireEvent } from '../helpers.js';
3
+ import { createStorageArea } from './area.js';
4
+ const META_SUFFIX = '::meta';
5
+ export function createStorageItem(adapter, key, options = {}) {
6
+ const area = options.area ?? 'local';
7
+ const storageArea = createStorageArea(adapter, area);
8
+ const metaKey = `${key}${META_SUFFIX}`;
9
+ const targetVersion = options.version ?? 1;
10
+ const readValue = async () => {
11
+ const items = await storageArea.get(key);
12
+ return Object.prototype.hasOwnProperty.call(items, key)
13
+ ? items[key]
14
+ : undefined;
15
+ };
16
+ const getMeta = async () => {
17
+ const raw = await storageArea.get(metaKey);
18
+ const value = raw[metaKey];
19
+ if (isStorageItemMeta(value)) {
20
+ return value;
21
+ }
22
+ return { version: 1 };
23
+ };
24
+ const setMeta = async (meta) => {
25
+ await storageArea.set({ [metaKey]: meta });
26
+ };
27
+ const resolveInitialValue = async () => {
28
+ if (options.init !== undefined) {
29
+ const value = await options.init();
30
+ await setValue(value);
31
+ return value;
32
+ }
33
+ if ('fallback' in options) {
34
+ return options.fallback;
35
+ }
36
+ throw new BrowserApiError('BROWSER_API_FAILED', `Storage item "${key}" has no value and no fallback or init option.`, { api: `storage.${area}.get` });
37
+ };
38
+ const migrate = async (value) => {
39
+ const meta = await getMeta();
40
+ if (meta.version >= targetVersion) {
41
+ return value;
42
+ }
43
+ let migrated = value;
44
+ for (let version = meta.version + 1; version <= targetVersion; version += 1) {
45
+ const migration = options.migrations?.[version];
46
+ if (migration !== undefined) {
47
+ migrated = await migration(migrated);
48
+ }
49
+ }
50
+ await storageArea.set({ [key]: migrated });
51
+ await setMeta({ ...meta, version: targetVersion });
52
+ return migrated;
53
+ };
54
+ const setValue = async (value) => {
55
+ await storageArea.set({ [key]: value });
56
+ if (targetVersion !== 1 || options.migrations !== undefined) {
57
+ await setMeta({ ...(await getMeta()), version: targetVersion });
58
+ }
59
+ };
60
+ const getValue = async () => {
61
+ const value = await readValue();
62
+ if (value === undefined) {
63
+ return resolveInitialValue();
64
+ }
65
+ return (await migrate(value));
66
+ };
67
+ return {
68
+ key,
69
+ area,
70
+ getValue,
71
+ setValue,
72
+ async removeValue() {
73
+ await storageArea.remove(key);
74
+ },
75
+ getMeta,
76
+ setMeta,
77
+ watch(callback) {
78
+ const event = requireEvent(adapter, ['storage', 'onChanged']);
79
+ const listener = (changes, areaName) => {
80
+ if (areaName !== area) {
81
+ return;
82
+ }
83
+ const change = changes[key];
84
+ if (change === undefined) {
85
+ return;
86
+ }
87
+ void resolveChangedValue(change, getValue)
88
+ .then((newValue) => {
89
+ callback(newValue, change.oldValue);
90
+ })
91
+ .catch(() => { });
92
+ };
93
+ event.addListener(listener);
94
+ return () => event.removeListener(listener);
95
+ },
96
+ };
97
+ }
98
+ async function resolveChangedValue(change, getValue) {
99
+ if (change.newValue !== undefined) {
100
+ return change.newValue;
101
+ }
102
+ return getValue();
103
+ }
104
+ function isStorageItemMeta(value) {
105
+ return (typeof value === 'object' &&
106
+ value !== null &&
107
+ typeof value.version === 'number');
108
+ }
109
+ //# sourceMappingURL=item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item.js","sourceRoot":"","sources":["../../../src/api/storage/item.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export type ContentScriptTimer = ReturnType<typeof globalThis.setTimeout>;
2
+ export interface ContentScriptRuntime {
3
+ readonly id?: string;
4
+ }
5
+ export interface ContentScriptContextOptions {
6
+ readonly validateRuntime?: boolean;
7
+ readonly runtime?: ContentScriptRuntime;
8
+ }
9
+ export interface ContentScriptContext {
10
+ readonly isValid: boolean;
11
+ readonly signal: AbortSignal;
12
+ setTimeout(callback: (...args: unknown[]) => void, timeout?: number, ...args: unknown[]): ContentScriptTimer;
13
+ clearTimeout(timer: ContentScriptTimer): void;
14
+ setInterval(callback: (...args: unknown[]) => void, timeout?: number, ...args: unknown[]): ContentScriptTimer;
15
+ clearInterval(timer: ContentScriptTimer): void;
16
+ requestAnimationFrame(callback: FrameRequestCallback): number;
17
+ cancelAnimationFrame(id: number): void;
18
+ addEventListener<Target extends EventTarget>(target: Target, type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): () => void;
19
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): () => void;
20
+ onInvalidated(callback: () => void): () => void;
21
+ invalidate(): void;
22
+ }
23
+ export declare function createContentScriptContext(options?: ContentScriptContextOptions): ContentScriptContext;
24
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/content/context.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,UAAU,CAAC,CAAC;AAE1E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,oBAAoB,CAAC;CACzC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,UAAU,CACR,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,EACtC,OAAO,CAAC,EAAE,MAAM,EAChB,GAAG,IAAI,EAAE,OAAO,EAAE,GACjB,kBAAkB,CAAC;IACtB,YAAY,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC9C,WAAW,CACT,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,EACtC,OAAO,CAAC,EAAE,MAAM,EAChB,GAAG,IAAI,EAAE,OAAO,EAAE,GACjB,kBAAkB,CAAC;IACtB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC/C,qBAAqB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,CAAC;IAC9D,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,gBAAgB,CAAC,MAAM,SAAS,WAAW,EACzC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,kCAAkC,EAC5C,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,MAAM,IAAI,CAAC;IACd,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,kCAAkC,EAC5C,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,MAAM,IAAI,CAAC;IACd,aAAa,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAChD,UAAU,IAAI,IAAI,CAAC;CACpB;AASD,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,2BAAgC,GACxC,oBAAoB,CA2LtB"}