@enbox/browser 0.3.69 → 0.3.71

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.
@@ -0,0 +1,82 @@
1
+ export type ObjectUrlLease = Readonly<{
2
+ url: string;
3
+ /** Release immediately, cancelling any deferred release. Idempotent. */
4
+ release(): void;
5
+ /** Release after a grace period. The first deferred release wins. */
6
+ releaseAfter(delayMs: number): void;
7
+ }>;
8
+
9
+ const MAX_TIMER_DELAY_MS = 2_147_483_647;
10
+
11
+ function assertReleaseDelay(delayMs: number): void {
12
+ if (!Number.isSafeInteger(delayMs) || delayMs < 0 || delayMs > MAX_TIMER_DELAY_MS) {
13
+ throw new TypeError(`delayMs must be an integer between 0 and ${MAX_TIMER_DELAY_MS}.`);
14
+ }
15
+ }
16
+
17
+ /** Private reference-counted ownership for one object URL. */
18
+ export class ObjectUrlReference {
19
+ public readonly url: string;
20
+ private _isRevoked = false;
21
+ private _references = 0;
22
+ private readonly _releaseTimers = new Set<ReturnType<typeof setTimeout>>();
23
+
24
+ public constructor(blob: Blob, private readonly _onEmpty: (reference: ObjectUrlReference) => void) {
25
+ this.url = globalThis.URL.createObjectURL(blob);
26
+ }
27
+
28
+ public get references(): number {
29
+ return this._references;
30
+ }
31
+
32
+ public acquire(): ObjectUrlLease {
33
+ if (this._isRevoked) {
34
+ throw new Error('Object URL has been revoked.');
35
+ }
36
+
37
+ this._references += 1;
38
+ let released = false;
39
+ let releaseTimer: ReturnType<typeof setTimeout> | undefined;
40
+ const release = (): void => {
41
+ if (released) {
42
+ return;
43
+ }
44
+ released = true;
45
+ if (releaseTimer !== undefined) {
46
+ clearTimeout(releaseTimer);
47
+ this._releaseTimers.delete(releaseTimer);
48
+ }
49
+ if (this._isRevoked) {
50
+ return;
51
+ }
52
+ this._references -= 1;
53
+ if (this._references === 0) {
54
+ this._onEmpty(this);
55
+ }
56
+ };
57
+ return Object.freeze({
58
+ url : this.url,
59
+ release,
60
+ releaseAfter : (delayMs: number): void => {
61
+ assertReleaseDelay(delayMs);
62
+ if (released || this._isRevoked || releaseTimer !== undefined) {
63
+ return;
64
+ }
65
+ releaseTimer = setTimeout(release, delayMs);
66
+ this._releaseTimers.add(releaseTimer);
67
+ },
68
+ });
69
+ }
70
+
71
+ public revoke(): void {
72
+ if (!this._isRevoked) {
73
+ this._isRevoked = true;
74
+ for (const timer of this._releaseTimers) {
75
+ clearTimeout(timer);
76
+ }
77
+ this._releaseTimers.clear();
78
+ this._references = 0;
79
+ globalThis.URL.revokeObjectURL(this.url);
80
+ }
81
+ }
82
+ }
@@ -6,7 +6,7 @@
6
6
 
7
7
  import type { DidMethodResolver } from '@enbox/dids';
8
8
 
9
- import { DidDht, DidWeb, UniversalResolver } from '@enbox/dids';
9
+ import { DidDht, DidResolverCacheMemory, DidWeb, resolveDwnEndpointStatus, UniversalResolver } from '@enbox/dids';
10
10
 
11
11
  /**
12
12
  * Result returned by the `onCacheCheck` callback.
@@ -62,7 +62,10 @@ interface DrlMediaElement extends HTMLElement {
62
62
  __src__?: string;
63
63
  }
64
64
 
65
- let didResolver = new UniversalResolver({ didResolvers: [DidDht, DidWeb] });
65
+ let didResolver = new UniversalResolver({
66
+ didResolvers : [DidDht, DidWeb],
67
+ cache : new DidResolverCacheMemory(),
68
+ });
66
69
 
67
70
  import { parseDrlUrl } from './drl-url-parser.js';
68
71
  export { parseDrlUrl } from './drl-url-parser.js';
@@ -73,14 +76,8 @@ const DRL_CACHE_NAME = 'drl';
73
76
 
74
77
  /** @internal Exported for testing. Resolves DWN service endpoints from a DID. */
75
78
  export async function getDwnEndpoints(did: string): Promise<string[]> {
76
- const { didDocument } = await didResolver.resolve(did);
77
- const endpoints = didDocument?.service?.find(
78
- (service) => service.type === 'DecentralizedWebNode'
79
- )?.serviceEndpoint;
80
- if (!endpoints) {return [];}
81
- return (Array.isArray(endpoints) ? endpoints : [endpoints]).filter(
82
- (url) => typeof url === 'string' && url.startsWith('http')
83
- );
79
+ const result = await resolveDwnEndpointStatus(did, didResolver);
80
+ return result.status === 'ready' ? result.endpoints : [];
84
81
  }
85
82
 
86
83
  /** Returns an open DRL cache, or `undefined` if the Cache API is unavailable. */
@@ -585,7 +582,10 @@ async function resetContextMenuTarget(e?: Event): Promise<void> {
585
582
  */
586
583
  export function activatePolyfills(options: ActivatePolyfillsOptions = {}): void {
587
584
  if (options.didResolvers) {
588
- didResolver = new UniversalResolver({ didResolvers: options.didResolvers });
585
+ didResolver = new UniversalResolver({
586
+ didResolvers : options.didResolvers,
587
+ cache : new DidResolverCacheMemory(),
588
+ });
589
589
  }
590
590
  if (options.serviceWorker !== false) {
591
591
  installWorker(options);