@enbox/browser 0.0.6 → 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,202 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright 2025 Liran Cohen
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
@@ -1,4 +1,8 @@
1
- //@ts-nocheck
1
+ /*
2
+ This file is run in dual environments to make installation of the Service Worker code easier.
3
+ Be mindful that code placed in any open excution space may be evaluated multiple times in different contexts,
4
+ so take care to gate additions to only activate code in the right env, such as a Service Worker scope or page window.
5
+ */
2
6
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
7
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
8
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -8,47 +12,47 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
12
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
13
  });
10
14
  };
11
- /*
12
- This file is run in dual environments to make installation of the Service Worker code easier.
13
- Be mindful that code placed in any open excution space may be evaluated multiple times in different contexts,
14
- so take care to gate additions to only activate code in the right env, such as a Service Worker scope or page window.
15
- */
16
15
  import { DidDht, DidWeb, UniversalResolver } from '@enbox/dids';
17
- // This is in place to prevent our `bundler-bonanza` repo from failing for Node CJS builds
18
- // Not sure if this is working as expected in all environments, crated an issue
19
- // TODO: https://github.com/enboxorg/enbox/issues/767
20
- function importMetaIfSupported() {
21
- try {
22
- return new Function('return import.meta')();
23
- }
24
- catch (_a) {
25
- return undefined;
26
- }
27
- }
28
- const DidResolver = new UniversalResolver({ didResolvers: [DidDht, DidWeb] });
16
+ let didResolver = new UniversalResolver({ didResolvers: [DidDht, DidWeb] });
29
17
  const didUrlRegex = /^https?:\/\/dweb\/([^/]+)\/?(.*)?$/;
30
18
  const httpToHttpsRegex = /^http:/;
31
19
  const trailingSlashRegex = /\/$/;
32
- function getDwnEndpoints(did) {
20
+ const DRL_CACHE_NAME = 'drl';
21
+ /** @internal Exported for testing. Resolves DWN service endpoints from a DID. */
22
+ export function getDwnEndpoints(did) {
33
23
  return __awaiter(this, void 0, void 0, function* () {
34
24
  var _a, _b;
35
- const { didDocument } = yield DidResolver.resolve(did);
25
+ const { didDocument } = yield didResolver.resolve(did);
36
26
  const endpoints = (_b = (_a = didDocument === null || didDocument === void 0 ? void 0 : didDocument.service) === null || _a === void 0 ? void 0 : _a.find((service) => service.type === 'DecentralizedWebNode')) === null || _b === void 0 ? void 0 : _b.serviceEndpoint;
37
- return (Array.isArray(endpoints) ? endpoints : [endpoints]).filter((url) => url.startsWith('http'));
27
+ if (!endpoints) {
28
+ return [];
29
+ }
30
+ return (Array.isArray(endpoints) ? endpoints : [endpoints]).filter((url) => typeof url === 'string' && url.startsWith('http'));
38
31
  });
39
32
  }
40
- function handleEvent(event, did, path, options) {
33
+ /** Returns an open DRL cache, or `undefined` if the Cache API is unavailable. */
34
+ function openDrlCache() {
41
35
  return __awaiter(this, void 0, void 0, function* () {
36
+ if (typeof caches === 'undefined') {
37
+ return undefined;
38
+ }
39
+ return caches.open(DRL_CACHE_NAME);
40
+ });
41
+ }
42
+ /** @internal Exported for testing. Handles a DRL fetch event. */
43
+ export function handleEvent(event, did, path, options) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ var _a;
42
46
  const drl = event.request.url
43
47
  .replace(httpToHttpsRegex, 'https:')
44
48
  .replace(trailingSlashRegex, '');
45
- const responseCache = yield caches.open('drl');
46
- const cachedResponse = yield responseCache.match(drl);
49
+ const responseCache = yield openDrlCache();
50
+ const cachedResponse = yield (responseCache === null || responseCache === void 0 ? void 0 : responseCache.match(drl));
47
51
  if (cachedResponse) {
48
52
  if (!navigator.onLine) {
49
53
  return cachedResponse;
50
54
  }
51
- const match = yield (options === null || options === void 0 ? void 0 : options.onCacheCheck(event, drl));
55
+ const match = yield ((_a = options === null || options === void 0 ? void 0 : options.onCacheCheck) === null || _a === void 0 ? void 0 : _a.call(options, event, drl));
52
56
  if (match) {
53
57
  const cacheTime = cachedResponse.headers.get('dwn-cache-time');
54
58
  if (cacheTime &&
@@ -59,7 +63,7 @@ function handleEvent(event, did, path, options) {
59
63
  }
60
64
  try {
61
65
  if (!path) {
62
- const response = yield DidResolver.resolve(did);
66
+ const response = yield didResolver.resolve(did);
63
67
  return new Response(JSON.stringify(response), {
64
68
  status: 200,
65
69
  headers: {
@@ -80,51 +84,61 @@ function handleEvent(event, did, path, options) {
80
84
  }
81
85
  });
82
86
  }
83
- function fetchResource(event, did, drl, path, responseCache, options) {
87
+ /** @internal Exported for testing. Fetches a resource from DWN endpoints. */
88
+ export function fetchResource(event, did, drl, path, responseCache, options) {
84
89
  return __awaiter(this, void 0, void 0, function* () {
90
+ var _a;
85
91
  const endpoints = yield getDwnEndpoints(did);
86
92
  if (!(endpoints === null || endpoints === void 0 ? void 0 : endpoints.length)) {
87
93
  throw new Response('DWeb Node resolution failed: no valid endpoints found.', { status: 530 });
88
94
  }
95
+ let lastError;
89
96
  for (const endpoint of endpoints) {
90
97
  try {
91
98
  const url = `${endpoint.replace(trailingSlashRegex, '')}/${did}/${path}`;
92
99
  const response = yield fetch(url, { headers: event.request.headers });
93
100
  if (response.ok) {
94
- const match = yield (options === null || options === void 0 ? void 0 : options.onCacheCheck(event, drl));
95
- if (match) {
101
+ const match = yield ((_a = options === null || options === void 0 ? void 0 : options.onCacheCheck) === null || _a === void 0 ? void 0 : _a.call(options, event, drl));
102
+ if (match && responseCache) {
96
103
  cacheResponse(drl, url, response, responseCache);
97
104
  }
98
105
  return response;
99
106
  }
100
107
  console.log(`DWN endpoint error: ${response.status}`);
101
- return new Response('DWeb Node request failed', {
108
+ lastError = new Response('DWeb Node request failed', {
102
109
  status: response.status,
103
110
  });
104
111
  }
105
112
  catch (error) {
106
113
  console.log(`DWN endpoint error: ${error}`);
107
- return new Response('DWeb Node request failed: ' + error, {
114
+ lastError = new Response('DWeb Node request failed', {
108
115
  status: 500,
109
116
  });
110
117
  }
111
118
  }
119
+ return lastError;
112
120
  });
113
121
  }
114
- function cacheResponse(drl, url, response, cache) {
122
+ /** @internal Exported for testing. Caches a DRL response with metadata headers. */
123
+ export function cacheResponse(drl, url, response, cache) {
115
124
  return __awaiter(this, void 0, void 0, function* () {
116
- const clonedResponse = response.clone();
117
- const headers = new Headers(clonedResponse.headers);
118
- headers.append('dwn-cache-time', Date.now().toString());
119
- headers.append('dwn-composed-url', url);
120
- const modifiedResponse = new Response(clonedResponse.body, { headers });
121
- cache.put(drl, modifiedResponse);
125
+ try {
126
+ const clonedResponse = response.clone();
127
+ const headers = new Headers(clonedResponse.headers);
128
+ headers.append('dwn-cache-time', Date.now().toString());
129
+ headers.append('dwn-composed-url', url);
130
+ const modifiedResponse = new Response(clonedResponse.body, { headers });
131
+ yield cache.put(drl, modifiedResponse);
132
+ }
133
+ catch (error) {
134
+ console.log(`Failed to cache DRL response: ${error}`);
135
+ }
122
136
  });
123
137
  }
124
138
  /* Service Worker-based features */
125
139
  function installWorker() {
126
140
  return __awaiter(this, arguments, void 0, function* (options = {}) {
127
- var _a, _b, _c;
141
+ var _a, _b;
128
142
  try {
129
143
  // Check to see if we are in a Service Worker already, if so, proceed
130
144
  // You can call the activatePolyfills() function in your own worker, or standalone as a root worker
@@ -148,11 +162,9 @@ function installWorker() {
148
162
  const registration = yield navigator.serviceWorker.getRegistration('/');
149
163
  // You can only have one worker per path, so check to see if one is already registered
150
164
  if (!registration) {
151
- // @ts-ignore
152
165
  const installUrl = options.path ||
153
- (globalThis.document
154
- ? (_b = document === null || document === void 0 ? void 0 : document.currentScript) === null || _b === void 0 ? void 0 : _b.src
155
- : (_c = importMetaIfSupported()) === null || _c === void 0 ? void 0 : _c.url);
166
+ ((_b = document === null || document === void 0 ? void 0 : document.currentScript) === null || _b === void 0 ? void 0 : _b.src) ||
167
+ import.meta.url;
156
168
  if (installUrl) {
157
169
  navigator.serviceWorker
158
170
  .register(installUrl, { type: 'module' })
@@ -309,12 +321,14 @@ const tabContent = `
309
321
  </html>
310
322
  `;
311
323
  let elementsInjected = false;
324
+ let overlayElement = null;
325
+ let styleElement = null;
312
326
  function injectElements() {
313
327
  if (elementsInjected) {
314
328
  return;
315
329
  }
316
- const style = document.createElement('style');
317
- style.innerHTML = `
330
+ styleElement = document.createElement('style');
331
+ styleElement.innerHTML = `
318
332
  ${loaderStyles}
319
333
 
320
334
  .drl-loading-overlay {
@@ -328,30 +342,44 @@ function injectElements() {
328
342
  pointer-events: all;
329
343
  }
330
344
  `;
331
- document.head.append(style);
332
- const overlay = document.createElement('div');
333
- overlay.classList.add('drl-loading-overlay');
334
- overlay.innerHTML = `
345
+ document.head.append(styleElement);
346
+ overlayElement = document.createElement('div');
347
+ overlayElement.classList.add('drl-loading-overlay');
348
+ overlayElement.innerHTML = `
335
349
  <div class='drl-loading-spinner'>
336
350
  <div></div>
337
351
  Loading DRL
338
352
  </div>
339
353
  <span tabindex='0'></span>
340
354
  `;
341
- overlay.lastElementChild.addEventListener('click', cancelNavigation);
342
- document.body.prepend(overlay);
355
+ overlayElement.lastElementChild.addEventListener('click', cancelNavigation);
356
+ document.body.prepend(overlayElement);
343
357
  elementsInjected = true;
344
358
  }
359
+ function removeElements() {
360
+ if (!elementsInjected) {
361
+ return;
362
+ }
363
+ styleElement === null || styleElement === void 0 ? void 0 : styleElement.remove();
364
+ styleElement = null;
365
+ overlayElement === null || overlayElement === void 0 ? void 0 : overlayElement.remove();
366
+ overlayElement = null;
367
+ elementsInjected = false;
368
+ }
345
369
  function cancelNavigation() {
346
370
  document.documentElement.removeAttribute('drl-link-loading');
347
371
  activeNavigation = null;
348
372
  }
349
- let activeNavigation;
373
+ let activeNavigation = null;
350
374
  let linkFeaturesActive = false;
375
+ // Stored references for listener cleanup in deactivatePolyfills()
376
+ let clickHandler = null;
377
+ let pointerdownHandler = null;
351
378
  function addLinkFeatures() {
352
379
  if (!linkFeaturesActive) {
353
- document.addEventListener('click', (event) => __awaiter(this, void 0, void 0, function* () {
354
- const anchor = event.target.closest('a');
380
+ clickHandler = (event) => __awaiter(this, void 0, void 0, function* () {
381
+ var _a;
382
+ const anchor = (_a = event.target) === null || _a === void 0 ? void 0 : _a.closest('a');
355
383
  if (anchor) {
356
384
  const href = anchor.href;
357
385
  const match = href.match(didUrlRegex);
@@ -361,10 +389,12 @@ function addLinkFeatures() {
361
389
  const openAsTab = anchor.target === '_blank';
362
390
  event.preventDefault();
363
391
  try {
364
- let tab;
392
+ let tab = null;
365
393
  if (openAsTab) {
366
394
  tab = window.open('', '_blank');
367
- tab.document.write(tabContent);
395
+ if (tab) {
396
+ tab.document.write(tabContent);
397
+ }
368
398
  }
369
399
  else {
370
400
  activeNavigation = path;
@@ -373,11 +403,11 @@ function addLinkFeatures() {
373
403
  }
374
404
  const endpoints = yield getDwnEndpoints(did);
375
405
  if (!endpoints.length) {
376
- throw null;
406
+ throw new Error('no valid DWN endpoints found');
377
407
  }
378
408
  const url = `${endpoints[0].replace(trailingSlashRegex, '')}/${did}/${path}`;
379
409
  if (openAsTab) {
380
- if (!tab.closed) {
410
+ if (tab && !tab.closed) {
381
411
  tab.location.href = url;
382
412
  }
383
413
  }
@@ -385,7 +415,7 @@ function addLinkFeatures() {
385
415
  window.location.href = url;
386
416
  }
387
417
  }
388
- catch (_a) {
418
+ catch (_b) {
389
419
  if (activeNavigation === path) {
390
420
  cancelNavigation();
391
421
  }
@@ -393,25 +423,26 @@ function addLinkFeatures() {
393
423
  }
394
424
  }
395
425
  }
396
- }));
397
- document.addEventListener('pointercancel', resetContextMenuTarget);
398
- document.addEventListener('pointerdown', (event) => __awaiter(this, void 0, void 0, function* () {
426
+ });
427
+ pointerdownHandler = (event) => __awaiter(this, void 0, void 0, function* () {
399
428
  var _a;
400
429
  const target = event.composedPath()[0];
401
430
  if ((event.pointerType === 'mouse' && event.button === 2) ||
402
431
  (event.pointerType === 'touch' && event.isPrimary)) {
403
432
  resetContextMenuTarget();
404
- if (target && ((_a = target === null || target === void 0 ? void 0 : target.src) === null || _a === void 0 ? void 0 : _a.match(didUrlRegex))) {
433
+ if ((_a = target === null || target === void 0 ? void 0 : target.src) === null || _a === void 0 ? void 0 : _a.match(didUrlRegex)) {
405
434
  contextMenuTarget = target;
406
435
  target.__src__ = target.src;
407
436
  const drl = target.src
408
437
  .replace(httpToHttpsRegex, 'https:')
409
438
  .replace(trailingSlashRegex, '');
410
- const responseCache = yield caches.open('drl');
411
- const response = yield responseCache.match(drl);
412
- const url = response.headers.get('dwn-composed-url');
413
- if (url) {
414
- target.src = url;
439
+ const responseCache = yield openDrlCache();
440
+ const response = yield (responseCache === null || responseCache === void 0 ? void 0 : responseCache.match(drl));
441
+ if (response) {
442
+ const url = response.headers.get('dwn-composed-url');
443
+ if (url) {
444
+ target.src = url;
445
+ }
415
446
  }
416
447
  target.addEventListener('pointerup', resetContextMenuTarget, {
417
448
  once: true,
@@ -421,15 +452,35 @@ function addLinkFeatures() {
421
452
  else if (target === contextMenuTarget) {
422
453
  resetContextMenuTarget();
423
454
  }
424
- }));
455
+ });
456
+ document.addEventListener('click', clickHandler);
457
+ document.addEventListener('pointercancel', resetContextMenuTarget);
458
+ document.addEventListener('pointerdown', pointerdownHandler);
425
459
  linkFeaturesActive = true;
426
460
  }
427
461
  }
428
- let contextMenuTarget;
462
+ function removeLinkFeatures() {
463
+ if (!linkFeaturesActive) {
464
+ return;
465
+ }
466
+ if (clickHandler) {
467
+ document.removeEventListener('click', clickHandler);
468
+ clickHandler = null;
469
+ }
470
+ if (pointerdownHandler) {
471
+ document.removeEventListener('pointerdown', pointerdownHandler);
472
+ pointerdownHandler = null;
473
+ }
474
+ document.removeEventListener('pointercancel', resetContextMenuTarget);
475
+ resetContextMenuTarget();
476
+ cancelNavigation();
477
+ linkFeaturesActive = false;
478
+ }
479
+ let contextMenuTarget = null;
429
480
  function resetContextMenuTarget(e) {
430
481
  return __awaiter(this, void 0, void 0, function* () {
431
482
  if ((e === null || e === void 0 ? void 0 : e.type) === 'pointerup') {
432
- yield new Promise((r) => requestAnimationFrame(r));
483
+ yield new Promise((r) => requestAnimationFrame(() => r()));
433
484
  }
434
485
  if (contextMenuTarget) {
435
486
  contextMenuTarget.src = contextMenuTarget.__src__;
@@ -441,19 +492,7 @@ function resetContextMenuTarget(e) {
441
492
  /**
442
493
  * Activates various polyfills to enable Web5 features in Web environments.
443
494
  *
444
- * @param {object} [options={}] - Configuration options to control the activation of polyfills.
445
- * @param {boolean} [options.serviceWorker=true] - Option to avoid installation of the Service Worker.
446
- * Defaults to true, installing the Service Worker.
447
- * @param {boolean} [options.injectStyles=true] - Option to skip injection of styles for UI related UX polyfills. Defaults to true, injecting styles.
448
- * @param {boolean} [options.links=true] - Option to skip activation of DRL link features. Defaults to true, activating link features.
449
- * @param {function} [options.onCacheCheck] - Callback function to handle cache check events,
450
- * allowing fine-grained control over what DRL request to cache, and for how long.
451
- * @param {object} [options.onCacheCheck.event] - The event object passed to the callback.
452
- * @param {object} [options.onCacheCheck.route] - The route object passed to the callback.
453
- * @returns {object} [options.onCacheCheck.return] - The return object from the callback.
454
- * @returns {number} [options.onCacheCheck.return.ttl] - Time-to-live for the cached DRL response, in milliseconds.
455
- *
456
- * @returns {void}
495
+ * @param options - Configuration options to control the activation of polyfills.
457
496
  *
458
497
  * @example
459
498
  * // Activate all polyfills with default options, and cache every DRL for 1 minute
@@ -468,8 +507,15 @@ function resetContextMenuTarget(e) {
468
507
  * @example
469
508
  * // Activate polyfills, but without Service Worker activation
470
509
  * activatePolyfills({ serviceWorker: false });
510
+ *
511
+ * @example
512
+ * // Use custom DID resolvers
513
+ * activatePolyfills({ didResolvers: [DidDht, DidWeb, DidJwk] });
471
514
  */
472
515
  export function activatePolyfills(options = {}) {
516
+ if (options.didResolvers) {
517
+ didResolver = new UniversalResolver({ didResolvers: options.didResolvers });
518
+ }
473
519
  if (options.serviceWorker !== false) {
474
520
  installWorker(options);
475
521
  }
@@ -489,4 +535,32 @@ export function activatePolyfills(options = {}) {
489
535
  }
490
536
  }
491
537
  }
538
+ /**
539
+ * Removes all polyfill event listeners, injected DOM elements, and resets internal state.
540
+ * Call this to fully clean up after {@link activatePolyfills}.
541
+ *
542
+ * Does **not** unregister an installed Service Worker — use
543
+ * `navigator.serviceWorker.getRegistration('/').then(r => r?.unregister())` for that.
544
+ */
545
+ export function deactivatePolyfills() {
546
+ if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
547
+ removeLinkFeatures();
548
+ removeElements();
549
+ }
550
+ }
551
+ /**
552
+ * Deletes the entire DRL response cache.
553
+ * Useful for clearing stale cached DWN responses.
554
+ *
555
+ * @returns `true` if the cache existed and was deleted, `false` otherwise.
556
+ * Returns `false` if the Cache API is unavailable.
557
+ */
558
+ export function clearDrlCache() {
559
+ return __awaiter(this, void 0, void 0, function* () {
560
+ if (typeof caches === 'undefined') {
561
+ return false;
562
+ }
563
+ return caches.delete(DRL_CACHE_NAME);
564
+ });
565
+ }
492
566
  //# sourceMappingURL=web-features.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"web-features.js","sourceRoot":"","sources":["../../src/web-features.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"web-features.js","sourceRoot":"","sources":["../../src/web-features.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,55 @@
1
+ import type { DidMethodResolver } from '@enbox/dids';
2
+ /**
3
+ * Result returned by the `onCacheCheck` callback.
4
+ * When returned, it signals that the response for the given DRL should be cached.
5
+ */
6
+ export type CacheCheckResult = {
7
+ /** Time-to-live for the cached DRL response, in milliseconds. */
8
+ ttl?: number;
9
+ };
10
+ /**
11
+ * Callback invoked to determine whether a DRL response should be cached and for how long.
12
+ * Returning a truthy `CacheCheckResult` opts in to caching; returning a falsy value skips it.
13
+ */
14
+ export type CacheCheckCallback = (event: FetchEvent | Event, drl: string) => CacheCheckResult | undefined | null | Promise<CacheCheckResult | undefined | null>;
15
+ /**
16
+ * Configuration options for {@link activatePolyfills}.
17
+ */
18
+ export type ActivatePolyfillsOptions = {
19
+ /**
20
+ * Path to the script to register as a Service Worker.
21
+ * Falls back to `document.currentScript.src` or `import.meta.url`.
22
+ *
23
+ * **Required in strict CSP environments** where `new Function()` is blocked and `import.meta`
24
+ * cannot be evaluated dynamically.
25
+ */
26
+ path?: string;
27
+ /** Set to `false` to skip Service Worker installation. Defaults to `true`. */
28
+ serviceWorker?: boolean;
29
+ /** Set to `false` to skip injection of DRL loading-overlay styles. Defaults to `true`. */
30
+ injectStyles?: boolean;
31
+ /** Set to `false` to skip activation of DRL anchor/link click handling. Defaults to `true`. */
32
+ links?: boolean;
33
+ /** Callback to control per-request caching behaviour. */
34
+ onCacheCheck?: CacheCheckCallback;
35
+ /**
36
+ * DID method resolvers to use for DRL resolution. Defaults to `[DidDht, DidWeb]`.
37
+ * Pass a custom array to add or replace DID methods (e.g., `[DidDht, DidWeb, DidJwk]`).
38
+ */
39
+ didResolvers?: DidMethodResolver[];
40
+ };
41
+ /** @internal Exported for testing. Resolves DWN service endpoints from a DID. */
42
+ export declare function getDwnEndpoints(did: string): Promise<string[]>;
43
+ /** @internal Exported for testing. Handles a DRL fetch event. */
44
+ export declare function handleEvent(event: FetchEvent, did: string, path: string, options?: ActivatePolyfillsOptions): Promise<Response>;
45
+ /** @internal Exported for testing. Fetches a resource from DWN endpoints. */
46
+ export declare function fetchResource(event: FetchEvent, did: string, drl: string, path: string, responseCache: Cache | undefined, options?: ActivatePolyfillsOptions): Promise<Response>;
47
+ /** @internal Exported for testing. Caches a DRL response with metadata headers. */
48
+ export declare function cacheResponse(drl: string, url: string, response: Response, cache: Cache): Promise<void>;
1
49
  /**
2
50
  * Activates various polyfills to enable Web5 features in Web environments.
3
51
  *
4
- * @param {object} [options={}] - Configuration options to control the activation of polyfills.
5
- * @param {boolean} [options.serviceWorker=true] - Option to avoid installation of the Service Worker.
6
- * Defaults to true, installing the Service Worker.
7
- * @param {boolean} [options.injectStyles=true] - Option to skip injection of styles for UI related UX polyfills. Defaults to true, injecting styles.
8
- * @param {boolean} [options.links=true] - Option to skip activation of DRL link features. Defaults to true, activating link features.
9
- * @param {function} [options.onCacheCheck] - Callback function to handle cache check events,
10
- * allowing fine-grained control over what DRL request to cache, and for how long.
11
- * @param {object} [options.onCacheCheck.event] - The event object passed to the callback.
12
- * @param {object} [options.onCacheCheck.route] - The route object passed to the callback.
13
- * @returns {object} [options.onCacheCheck.return] - The return object from the callback.
14
- * @returns {number} [options.onCacheCheck.return.ttl] - Time-to-live for the cached DRL response, in milliseconds.
15
- *
16
- * @returns {void}
52
+ * @param options - Configuration options to control the activation of polyfills.
17
53
  *
18
54
  * @example
19
55
  * // Activate all polyfills with default options, and cache every DRL for 1 minute
@@ -28,6 +64,26 @@
28
64
  * @example
29
65
  * // Activate polyfills, but without Service Worker activation
30
66
  * activatePolyfills({ serviceWorker: false });
67
+ *
68
+ * @example
69
+ * // Use custom DID resolvers
70
+ * activatePolyfills({ didResolvers: [DidDht, DidWeb, DidJwk] });
71
+ */
72
+ export declare function activatePolyfills(options?: ActivatePolyfillsOptions): void;
73
+ /**
74
+ * Removes all polyfill event listeners, injected DOM elements, and resets internal state.
75
+ * Call this to fully clean up after {@link activatePolyfills}.
76
+ *
77
+ * Does **not** unregister an installed Service Worker — use
78
+ * `navigator.serviceWorker.getRegistration('/').then(r => r?.unregister())` for that.
79
+ */
80
+ export declare function deactivatePolyfills(): void;
81
+ /**
82
+ * Deletes the entire DRL response cache.
83
+ * Useful for clearing stale cached DWN responses.
84
+ *
85
+ * @returns `true` if the cache existed and was deleted, `false` otherwise.
86
+ * Returns `false` if the Cache API is unavailable.
31
87
  */
32
- export declare function activatePolyfills(options?: any): void;
88
+ export declare function clearDrlCache(): Promise<boolean>;
33
89
  //# sourceMappingURL=web-features.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"web-features.d.ts","sourceRoot":"","sources":["../../src/web-features.ts"],"names":[],"mappings":"AA4bA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,GAAQ,GAAG,IAAI,CAezD"}
1
+ {"version":3,"file":"web-features.d.ts","sourceRoot":"","sources":["../../src/web-features.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAC/B,KAAK,EAAE,UAAU,GAAG,KAAK,EACzB,GAAG,EAAE,MAAM,KACR,gBAAgB,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;AAExF;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,0FAA0F;IAC1F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+FAA+F;IAC/F,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yDAAyD;IACzD,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACpC,CAAC;AAiBF,iFAAiF;AACjF,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CASpE;AAQD,iEAAiE;AACjE,wBAAsB,WAAW,CAC/B,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAC/E,OAAO,CAAC,QAAQ,CAAC,CAqCnB;AAED,6EAA6E;AAC7E,wBAAsB,aAAa,CACjC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EACzD,aAAa,EAAE,KAAK,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,wBAAwB,GACnE,OAAO,CAAC,QAAQ,CAAC,CAgCnB;AAED,mFAAmF;AACnF,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAW7G;AA8WD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,IAAI,CAkB9E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAGtD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enbox/browser",
3
- "version": "0.0.6",
3
+ "version": "0.1.1",
4
4
  "description": "Web5 tools and features to use in the browser",
5
5
  "type": "module",
6
6
  "main": "./dist/esm/index.js",
@@ -55,7 +55,7 @@
55
55
  "access": "public"
56
56
  },
57
57
  "dependencies": {
58
- "@enbox/dids": "0.0.6"
58
+ "@enbox/dids": "0.0.8"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@typescript-eslint/eslint-plugin": "8.32.1",
@@ -1,50 +1,103 @@
1
- //@ts-nocheck
2
-
3
1
  /*
4
2
  This file is run in dual environments to make installation of the Service Worker code easier.
5
3
  Be mindful that code placed in any open excution space may be evaluated multiple times in different contexts,
6
4
  so take care to gate additions to only activate code in the right env, such as a Service Worker scope or page window.
7
5
  */
8
6
 
7
+ import type { DidMethodResolver } from '@enbox/dids';
8
+
9
9
  import { DidDht, DidWeb, UniversalResolver } from '@enbox/dids';
10
10
 
11
- // This is in place to prevent our `bundler-bonanza` repo from failing for Node CJS builds
12
- // Not sure if this is working as expected in all environments, crated an issue
13
- // TODO: https://github.com/enboxorg/enbox/issues/767
14
- function importMetaIfSupported(): any {
15
- try {
16
- return new Function('return import.meta')();
17
- } catch {
18
- return undefined;
19
- }
20
- }
11
+ /**
12
+ * Result returned by the `onCacheCheck` callback.
13
+ * When returned, it signals that the response for the given DRL should be cached.
14
+ */
15
+ export type CacheCheckResult = {
16
+ /** Time-to-live for the cached DRL response, in milliseconds. */
17
+ ttl?: number;
18
+ };
19
+
20
+ /**
21
+ * Callback invoked to determine whether a DRL response should be cached and for how long.
22
+ * Returning a truthy `CacheCheckResult` opts in to caching; returning a falsy value skips it.
23
+ */
24
+ export type CacheCheckCallback = (
25
+ event: FetchEvent | Event,
26
+ drl: string,
27
+ ) => CacheCheckResult | undefined | null | Promise<CacheCheckResult | undefined | null>;
28
+
29
+ /**
30
+ * Configuration options for {@link activatePolyfills}.
31
+ */
32
+ export type ActivatePolyfillsOptions = {
33
+ /**
34
+ * Path to the script to register as a Service Worker.
35
+ * Falls back to `document.currentScript.src` or `import.meta.url`.
36
+ *
37
+ * **Required in strict CSP environments** where `new Function()` is blocked and `import.meta`
38
+ * cannot be evaluated dynamically.
39
+ */
40
+ path?: string;
41
+ /** Set to `false` to skip Service Worker installation. Defaults to `true`. */
42
+ serviceWorker?: boolean;
43
+ /** Set to `false` to skip injection of DRL loading-overlay styles. Defaults to `true`. */
44
+ injectStyles?: boolean;
45
+ /** Set to `false` to skip activation of DRL anchor/link click handling. Defaults to `true`. */
46
+ links?: boolean;
47
+ /** Callback to control per-request caching behaviour. */
48
+ onCacheCheck?: CacheCheckCallback;
49
+ /**
50
+ * DID method resolvers to use for DRL resolution. Defaults to `[DidDht, DidWeb]`.
51
+ * Pass a custom array to add or replace DID methods (e.g., `[DidDht, DidWeb, DidJwk]`).
52
+ */
53
+ didResolvers?: DidMethodResolver[];
54
+ };
21
55
 
22
- declare const ServiceWorkerGlobalScope: any;
56
+ /**
57
+ * An `HTMLElement` that has a `src` property (e.g., `<img>`, `<video>`, `<audio>`).
58
+ * Extended with `__src__` to stash the original DRL src during context-menu swaps.
59
+ */
60
+ interface DrlMediaElement extends HTMLElement {
61
+ src: string;
62
+ __src__?: string;
63
+ }
23
64
 
24
- const DidResolver = new UniversalResolver({ didResolvers: [DidDht, DidWeb] });
65
+ let didResolver = new UniversalResolver({ didResolvers: [DidDht, DidWeb] });
25
66
  const didUrlRegex = /^https?:\/\/dweb\/([^/]+)\/?(.*)?$/;
26
67
  const httpToHttpsRegex = /^http:/;
27
68
  const trailingSlashRegex = /\/$/;
69
+ const DRL_CACHE_NAME = 'drl';
28
70
 
29
- async function getDwnEndpoints(did: any): Promise<string[]> {
30
- const { didDocument } = await DidResolver.resolve(did);
71
+ /** @internal Exported for testing. Resolves DWN service endpoints from a DID. */
72
+ export async function getDwnEndpoints(did: string): Promise<string[]> {
73
+ const { didDocument } = await didResolver.resolve(did);
31
74
  const endpoints = didDocument?.service?.find(
32
75
  (service) => service.type === 'DecentralizedWebNode'
33
76
  )?.serviceEndpoint;
34
- return (Array.isArray(endpoints) ? endpoints : [endpoints]).filter((url) =>
35
- url.startsWith('http')
77
+ if (!endpoints) {return [];}
78
+ return (Array.isArray(endpoints) ? endpoints : [endpoints]).filter(
79
+ (url) => typeof url === 'string' && url.startsWith('http')
36
80
  );
37
81
  }
38
82
 
39
- async function handleEvent(event: any, did: any, path: any, options: any): Promise<Response> {
83
+ /** Returns an open DRL cache, or `undefined` if the Cache API is unavailable. */
84
+ async function openDrlCache(): Promise<Cache | undefined> {
85
+ if (typeof caches === 'undefined') {return undefined;}
86
+ return caches.open(DRL_CACHE_NAME);
87
+ }
88
+
89
+ /** @internal Exported for testing. Handles a DRL fetch event. */
90
+ export async function handleEvent(
91
+ event: FetchEvent, did: string, path: string, options?: ActivatePolyfillsOptions
92
+ ): Promise<Response> {
40
93
  const drl = event.request.url
41
94
  .replace(httpToHttpsRegex, 'https:')
42
95
  .replace(trailingSlashRegex, '');
43
- const responseCache = await caches.open('drl');
44
- const cachedResponse = await responseCache.match(drl);
96
+ const responseCache = await openDrlCache();
97
+ const cachedResponse = await responseCache?.match(drl);
45
98
  if (cachedResponse) {
46
99
  if (!navigator.onLine) {return cachedResponse;}
47
- const match = await options?.onCacheCheck(event, drl);
100
+ const match = await options?.onCacheCheck?.(event, drl);
48
101
  if (match) {
49
102
  const cacheTime = cachedResponse.headers.get('dwn-cache-time');
50
103
  if (
@@ -57,7 +110,7 @@ async function handleEvent(event: any, did: any, path: any, options: any): Promi
57
110
  }
58
111
  try {
59
112
  if (!path) {
60
- const response = await DidResolver.resolve(did);
113
+ const response = await didResolver.resolve(did);
61
114
  return new Response(JSON.stringify(response), {
62
115
  status : 200,
63
116
  headers : {
@@ -75,7 +128,11 @@ async function handleEvent(event: any, did: any, path: any, options: any): Promi
75
128
  }
76
129
  }
77
130
 
78
- async function fetchResource(event: any, did: any, drl: any, path: any, responseCache: any, options: any): Promise<Response | undefined> {
131
+ /** @internal Exported for testing. Fetches a resource from DWN endpoints. */
132
+ export async function fetchResource(
133
+ event: FetchEvent, did: string, drl: string, path: string,
134
+ responseCache: Cache | undefined, options?: ActivatePolyfillsOptions
135
+ ): Promise<Response> {
79
136
  const endpoints = await getDwnEndpoints(did);
80
137
  if (!endpoints?.length) {
81
138
  throw new Response(
@@ -83,42 +140,49 @@ async function fetchResource(event: any, did: any, drl: any, path: any, response
83
140
  { status: 530 }
84
141
  );
85
142
  }
143
+ let lastError: Response | undefined;
86
144
  for (const endpoint of endpoints) {
87
145
  try {
88
146
  const url = `${endpoint.replace(trailingSlashRegex, '')}/${did}/${path}`;
89
147
  const response = await fetch(url, { headers: event.request.headers });
90
148
  if (response.ok) {
91
- const match = await options?.onCacheCheck(event, drl);
92
- if (match) {
149
+ const match = await options?.onCacheCheck?.(event, drl);
150
+ if (match && responseCache) {
93
151
  cacheResponse(drl, url, response, responseCache);
94
152
  }
95
153
  return response;
96
154
  }
97
155
  console.log(`DWN endpoint error: ${response.status}`);
98
- return new Response('DWeb Node request failed', {
156
+ lastError = new Response('DWeb Node request failed', {
99
157
  status: response.status,
100
158
  });
101
159
  } catch (error) {
102
160
  console.log(`DWN endpoint error: ${error}`);
103
- return new Response('DWeb Node request failed: ' + error, {
161
+ lastError = new Response('DWeb Node request failed', {
104
162
  status: 500,
105
163
  });
106
164
  }
107
165
  }
166
+ return lastError!;
108
167
  }
109
168
 
110
- async function cacheResponse(drl: any, url: any, response: any, cache: any): Promise<void> {
111
- const clonedResponse = response.clone();
112
- const headers = new Headers(clonedResponse.headers);
113
- headers.append('dwn-cache-time', Date.now().toString());
114
- headers.append('dwn-composed-url', url);
115
- const modifiedResponse = new Response(clonedResponse.body, { headers });
116
- cache.put(drl, modifiedResponse);
169
+ /** @internal Exported for testing. Caches a DRL response with metadata headers. */
170
+ export async function cacheResponse(drl: string, url: string, response: Response, cache: Cache): Promise<void> {
171
+ try {
172
+ const clonedResponse = response.clone();
173
+ const headers = new Headers(clonedResponse.headers);
174
+ headers.append('dwn-cache-time', Date.now().toString());
175
+ headers.append('dwn-composed-url', url);
176
+ const modifiedResponse = new Response(clonedResponse.body, { headers });
177
+ await cache.put(drl, modifiedResponse);
178
+ } catch (error) {
179
+ console.log(`Failed to cache DRL response: ${error}`);
180
+ }
117
181
  }
118
182
 
119
183
  /* Service Worker-based features */
120
184
 
121
- async function installWorker(options: any = {}): Promise<void> {
185
+ async function installWorker(options: ActivatePolyfillsOptions = {}): Promise<void> {
122
186
  try {
123
187
  // Check to see if we are in a Service Worker already, if so, proceed
124
188
  // You can call the activatePolyfills() function in your own worker, or standalone as a root worker
@@ -126,13 +190,13 @@ async function installWorker(options: any = {}): Promise<void> {
126
190
  typeof ServiceWorkerGlobalScope !== 'undefined' &&
127
191
  self instanceof ServiceWorkerGlobalScope
128
192
  ) {
129
- const workerSelf = self as ServiceWorkerGlobalScope;
193
+ const workerSelf = self as unknown as ServiceWorkerGlobalScope;
130
194
  workerSelf.skipWaiting();
131
- workerSelf.addEventListener('activate', (event) => {
195
+ workerSelf.addEventListener('activate', (event: ExtendableEvent) => {
132
196
  // Claim clients to make the service worker take control immediately
133
197
  event.waitUntil(workerSelf.clients.claim());
134
198
  });
135
- workerSelf.addEventListener('fetch', (event) => {
199
+ workerSelf.addEventListener('fetch', (event: FetchEvent) => {
136
200
  const match = event.request.url.match(didUrlRegex);
137
201
  if (match) {
138
202
  event.respondWith(handleEvent(event, match[1], match[2], options));
@@ -144,16 +208,14 @@ async function installWorker(options: any = {}): Promise<void> {
144
208
  const registration = await navigator.serviceWorker.getRegistration('/');
145
209
  // You can only have one worker per path, so check to see if one is already registered
146
210
  if (!registration) {
147
- // @ts-ignore
148
- const installUrl =
211
+ const installUrl: string | undefined =
149
212
  options.path ||
150
- (globalThis.document
151
- ? document?.currentScript?.src
152
- : importMetaIfSupported()?.url);
213
+ (document?.currentScript as HTMLScriptElement | null)?.src ||
214
+ import.meta.url;
153
215
  if (installUrl)
154
216
  {navigator.serviceWorker
155
217
  .register(installUrl, { type: 'module' })
156
- .catch((error) => {
218
+ .catch((error: unknown) => {
157
219
  console.error(
158
220
  'DWeb networking feature installation failed: ',
159
221
  error
@@ -310,10 +372,13 @@ const tabContent = `
310
372
  `;
311
373
 
312
374
  let elementsInjected = false;
375
+ let overlayElement: HTMLDivElement | null = null;
376
+ let styleElement: HTMLStyleElement | null = null;
377
+
313
378
  function injectElements(): void {
314
379
  if (elementsInjected) {return;}
315
- const style = document.createElement('style');
316
- style.innerHTML = `
380
+ styleElement = document.createElement('style');
381
+ styleElement.innerHTML = `
317
382
  ${loaderStyles}
318
383
 
319
384
  .drl-loading-overlay {
@@ -327,33 +392,47 @@ function injectElements(): void {
327
392
  pointer-events: all;
328
393
  }
329
394
  `;
330
- document.head.append(style);
395
+ document.head.append(styleElement);
331
396
 
332
- const overlay = document.createElement('div');
333
- overlay.classList.add('drl-loading-overlay');
334
- overlay.innerHTML = `
397
+ overlayElement = document.createElement('div');
398
+ overlayElement.classList.add('drl-loading-overlay');
399
+ overlayElement.innerHTML = `
335
400
  <div class='drl-loading-spinner'>
336
401
  <div></div>
337
402
  Loading DRL
338
403
  </div>
339
404
  <span tabindex='0'></span>
340
405
  `;
341
- overlay.lastElementChild.addEventListener('click', cancelNavigation);
342
- document.body.prepend(overlay);
406
+ overlayElement.lastElementChild!.addEventListener('click', cancelNavigation);
407
+ document.body.prepend(overlayElement);
343
408
  elementsInjected = true;
344
409
  }
345
410
 
411
+ function removeElements(): void {
412
+ if (!elementsInjected) {return;}
413
+ styleElement?.remove();
414
+ styleElement = null;
415
+ overlayElement?.remove();
416
+ overlayElement = null;
417
+ elementsInjected = false;
418
+ }
419
+
346
420
  function cancelNavigation(): void {
347
421
  document.documentElement.removeAttribute('drl-link-loading');
348
422
  activeNavigation = null;
349
423
  }
350
424
 
351
- let activeNavigation;
425
+ let activeNavigation: string | null = null;
352
426
  let linkFeaturesActive = false;
427
+
428
+ // Stored references for listener cleanup in deactivatePolyfills()
429
+ let clickHandler: ((event: MouseEvent) => Promise<void>) | null = null;
430
+ let pointerdownHandler: ((event: PointerEvent) => Promise<void>) | null = null;
431
+
353
432
  function addLinkFeatures(): void {
354
433
  if (!linkFeaturesActive) {
355
- document.addEventListener('click', async (event: any) => {
356
- const anchor = event.target.closest('a');
434
+ clickHandler = async (event: MouseEvent): Promise<void> => {
435
+ const anchor = (event.target as Element)?.closest('a');
357
436
  if (anchor) {
358
437
  const href = anchor.href;
359
438
  const match = href.match(didUrlRegex);
@@ -363,10 +442,10 @@ function addLinkFeatures(): void {
363
442
  const openAsTab = anchor.target === '_blank';
364
443
  event.preventDefault();
365
444
  try {
366
- let tab;
445
+ let tab: Window | null = null;
367
446
  if (openAsTab) {
368
447
  tab = window.open('', '_blank');
369
- tab.document.write(tabContent);
448
+ if (tab) {tab.document.write(tabContent);}
370
449
  } else {
371
450
  activeNavigation = path;
372
451
  // this is to allow for cached DIDs to instantly load without any flash of loading UI
@@ -377,13 +456,15 @@ function addLinkFeatures(): void {
377
456
  );
378
457
  }
379
458
  const endpoints = await getDwnEndpoints(did);
380
- if (!endpoints.length) {throw null;}
459
+ if (!endpoints.length) {
460
+ throw new Error('no valid DWN endpoints found');
461
+ }
381
462
  const url = `${endpoints[0].replace(
382
463
  trailingSlashRegex,
383
464
  ''
384
465
  )}/${did}/${path}`;
385
466
  if (openAsTab) {
386
- if (!tab.closed) {tab.location.href = url;}
467
+ if (tab && !tab.closed) {tab.location.href = url;}
387
468
  } else if (activeNavigation === path) {
388
469
  window.location.href = url;
389
470
  }
@@ -397,26 +478,27 @@ function addLinkFeatures(): void {
397
478
  }
398
479
  }
399
480
  }
400
- });
481
+ };
401
482
 
402
- document.addEventListener('pointercancel', resetContextMenuTarget);
403
- document.addEventListener('pointerdown', async (event: any) => {
404
- const target = event.composedPath()[0];
483
+ pointerdownHandler = async (event: PointerEvent): Promise<void> => {
484
+ const target = event.composedPath()[0] as DrlMediaElement | undefined;
405
485
  if (
406
486
  (event.pointerType === 'mouse' && event.button === 2) ||
407
487
  (event.pointerType === 'touch' && event.isPrimary)
408
488
  ) {
409
489
  resetContextMenuTarget();
410
- if (target && target?.src?.match(didUrlRegex)) {
490
+ if (target?.src?.match(didUrlRegex)) {
411
491
  contextMenuTarget = target;
412
492
  target.__src__ = target.src;
413
493
  const drl = target.src
414
494
  .replace(httpToHttpsRegex, 'https:')
415
495
  .replace(trailingSlashRegex, '');
416
- const responseCache = await caches.open('drl');
417
- const response = await responseCache.match(drl);
418
- const url = response.headers.get('dwn-composed-url');
419
- if (url) {target.src = url;}
496
+ const responseCache = await openDrlCache();
497
+ const response = await responseCache?.match(drl);
498
+ if (response) {
499
+ const url = response.headers.get('dwn-composed-url');
500
+ if (url) {target.src = url;}
501
+ }
420
502
  target.addEventListener('pointerup', resetContextMenuTarget, {
421
503
  once: true,
422
504
  });
@@ -424,19 +506,39 @@ function addLinkFeatures(): void {
424
506
  } else if (target === contextMenuTarget) {
425
507
  resetContextMenuTarget();
426
508
  }
427
- });
509
+ };
510
+
511
+ document.addEventListener('click', clickHandler);
512
+ document.addEventListener('pointercancel', resetContextMenuTarget);
513
+ document.addEventListener('pointerdown', pointerdownHandler);
428
514
 
429
515
  linkFeaturesActive = true;
430
516
  }
431
517
  }
432
518
 
433
- let contextMenuTarget;
434
- async function resetContextMenuTarget(e?: any): Promise<void> {
519
+ function removeLinkFeatures(): void {
520
+ if (!linkFeaturesActive) {return;}
521
+ if (clickHandler) {
522
+ document.removeEventListener('click', clickHandler);
523
+ clickHandler = null;
524
+ }
525
+ if (pointerdownHandler) {
526
+ document.removeEventListener('pointerdown', pointerdownHandler);
527
+ pointerdownHandler = null;
528
+ }
529
+ document.removeEventListener('pointercancel', resetContextMenuTarget);
530
+ resetContextMenuTarget();
531
+ cancelNavigation();
532
+ linkFeaturesActive = false;
533
+ }
534
+
535
+ let contextMenuTarget: DrlMediaElement | null = null;
536
+ async function resetContextMenuTarget(e?: Event): Promise<void> {
435
537
  if (e?.type === 'pointerup') {
436
- await new Promise((r) => requestAnimationFrame(r));
538
+ await new Promise<void>((r) => requestAnimationFrame(() => r()));
437
539
  }
438
540
  if (contextMenuTarget) {
439
- contextMenuTarget.src = contextMenuTarget.__src__;
541
+ contextMenuTarget.src = contextMenuTarget.__src__!;
440
542
  delete contextMenuTarget.__src__;
441
543
  contextMenuTarget = null;
442
544
  }
@@ -445,19 +547,7 @@ async function resetContextMenuTarget(e?: any): Promise<void> {
445
547
  /**
446
548
  * Activates various polyfills to enable Web5 features in Web environments.
447
549
  *
448
- * @param {object} [options={}] - Configuration options to control the activation of polyfills.
449
- * @param {boolean} [options.serviceWorker=true] - Option to avoid installation of the Service Worker.
450
- * Defaults to true, installing the Service Worker.
451
- * @param {boolean} [options.injectStyles=true] - Option to skip injection of styles for UI related UX polyfills. Defaults to true, injecting styles.
452
- * @param {boolean} [options.links=true] - Option to skip activation of DRL link features. Defaults to true, activating link features.
453
- * @param {function} [options.onCacheCheck] - Callback function to handle cache check events,
454
- * allowing fine-grained control over what DRL request to cache, and for how long.
455
- * @param {object} [options.onCacheCheck.event] - The event object passed to the callback.
456
- * @param {object} [options.onCacheCheck.route] - The route object passed to the callback.
457
- * @returns {object} [options.onCacheCheck.return] - The return object from the callback.
458
- * @returns {number} [options.onCacheCheck.return.ttl] - Time-to-live for the cached DRL response, in milliseconds.
459
- *
460
- * @returns {void}
550
+ * @param options - Configuration options to control the activation of polyfills.
461
551
  *
462
552
  * @example
463
553
  * // Activate all polyfills with default options, and cache every DRL for 1 minute
@@ -472,8 +562,15 @@ async function resetContextMenuTarget(e?: any): Promise<void> {
472
562
  * @example
473
563
  * // Activate polyfills, but without Service Worker activation
474
564
  * activatePolyfills({ serviceWorker: false });
565
+ *
566
+ * @example
567
+ * // Use custom DID resolvers
568
+ * activatePolyfills({ didResolvers: [DidDht, DidWeb, DidJwk] });
475
569
  */
476
- export function activatePolyfills(options: any = {}): void {
570
+ export function activatePolyfills(options: ActivatePolyfillsOptions = {}): void {
571
+ if (options.didResolvers) {
572
+ didResolver = new UniversalResolver({ didResolvers: options.didResolvers });
573
+ }
477
574
  if (options.serviceWorker !== false) {
478
575
  installWorker(options);
479
576
  }
@@ -489,3 +586,29 @@ export function activatePolyfills(options: any = {}): void {
489
586
  if (options.links !== false) {addLinkFeatures();}
490
587
  }
491
588
  }
589
+
590
+ /**
591
+ * Removes all polyfill event listeners, injected DOM elements, and resets internal state.
592
+ * Call this to fully clean up after {@link activatePolyfills}.
593
+ *
594
+ * Does **not** unregister an installed Service Worker — use
595
+ * `navigator.serviceWorker.getRegistration('/').then(r => r?.unregister())` for that.
596
+ */
597
+ export function deactivatePolyfills(): void {
598
+ if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
599
+ removeLinkFeatures();
600
+ removeElements();
601
+ }
602
+ }
603
+
604
+ /**
605
+ * Deletes the entire DRL response cache.
606
+ * Useful for clearing stale cached DWN responses.
607
+ *
608
+ * @returns `true` if the cache existed and was deleted, `false` otherwise.
609
+ * Returns `false` if the Cache API is unavailable.
610
+ */
611
+ export async function clearDrlCache(): Promise<boolean> {
612
+ if (typeof caches === 'undefined') {return false;}
613
+ return caches.delete(DRL_CACHE_NAME);
614
+ }