Repository: exadel-inc/esl
Pull request #226 (2021-06-02 09:43:45)

feat: extend UID utilities
BREAKING CHANGE: `generateUId` renamed to `randUID`


Patch:
diff --git a/src/modules/esl-media/providers/brightcove-provider.ts b/src/modules/esl-media/providers/brightcove-provider.ts
index 1221d8759..666c92400 100644
--- a/src/modules/esl-media/providers/brightcove-provider.ts
+++ b/src/modules/esl-media/providers/brightcove-provider.ts
@@ -1,6 +1,6 @@
 import {loadScript} from '../../esl-utils/dom/script';
 import {BaseProvider, PlayerStates} from '../core/esl-media-provider';
-import {generateUId} from '../../esl-utils/misc/uid';
+import {randUID} from '../../esl-utils/misc/uid';
 
 import type {ESLMedia} from '../core/esl-media';
 import type {ProviderObservedParams} from '../core/esl-media-provider';
@@ -55,7 +55,7 @@ export class BrightcoveProvider extends BaseProvider {
    */
   protected buildVideo() {
     const el = document.createElement('video-js');
-    el.id = 'esl-media-brightcove-' + generateUId();
+    el.id = 'esl-media-brightcove-' + randUID();
     el.className = 'esl-media-inner esl-media-brightcove ' + this.videojsClasses;
     el.title = this.config.title;
     el.toggleAttribute('loop', this.config.loop);
diff --git a/src/modules/esl-media/providers/iframe-provider.ts b/src/modules/esl-media/providers/iframe-provider.ts
index 510a0d57e..272871d28 100644
--- a/src/modules/esl-media/providers/iframe-provider.ts
+++ b/src/modules/esl-media/providers/iframe-provider.ts
@@ -1,5 +1,5 @@
 import {BaseProvider, PlayerStates} from '../core/esl-media-provider';
-import {generateUId} from '../../esl-utils/misc/uid';
+import {randUID} from '../../esl-utils/misc/uid';
 
 /**
  * Simple Basic Iframe provider for {@link ESLMedia}
@@ -25,7 +25,7 @@ export class IframeBasicProvider extends BaseProvider {
 
   protected buildIframe() {
     const el = document.createElement('iframe');
-    el.id = 'esl-media-iframe-' + generateUId();
+    el.id = 'esl-media-iframe-' + randUID();
     el.className = 'esl-media-inner esl-media-iframe';
     el.title = this.config.title;
     el.setAttribute('aria-label', this.config.title);
diff --git a/src/modules/esl-media/providers/youtube-provider.ts b/src/modules/esl-media/providers/youtube-provider.ts
index b48447b15..816407a4c 100644
--- a/src/modules/esl-media/providers/youtube-provider.ts
+++ b/src/modules/esl-media/providers/youtube-provider.ts
@@ -1,6 +1,6 @@
 import {loadScript} from '../../esl-utils/dom/script';
 import {BaseProvider, PlayerStates} from '../core/esl-media-provider';
-import {generateUId} from '../../esl-utils/misc/uid';
+import {randUID} from '../../esl-utils/misc/uid';
 import PlayerVars = YT.PlayerVars;
 
 import type {MediaProviderConfig, ProviderObservedParams} from '../core/esl-media-provider';
@@ -65,7 +65,7 @@ export class YouTubeProvider extends BaseProvider {
 
   protected static buildIframe(sm: MediaProviderConfig) {
     const el = document.createElement('div');
-    el.id = 'esl-media-yt-' + generateUId();
+    el.id = 'esl-media-yt-' + randUID();
     el.className = 'esl-media-inner esl-media-youtube';
     el.title = sm.title;
     el.setAttribute('aria-label', el.title);
diff --git a/src/modules/esl-utils/misc/uid.ts b/src/modules/esl-utils/misc/uid.ts
index b920ef154..ab93b210e 100644
--- a/src/modules/esl-utils/misc/uid.ts
+++ b/src/modules/esl-utils/misc/uid.ts
@@ -1,6 +1,30 @@
-/** Generate unique id */
-export function generateUId(): string {
-  const fp = Date.now().toString(32);
-  const sp = Math.round(Math.random() * 1024 * 1024).toString(32);
-  return fp + '-' + sp;
-}
+const sequences = new Map<string, number>();
+
+/** Create and return sequential id */
+export const sequentialUID = (name: string, prefix: string = name) => {
+  const uid = (sequences.get(name) || 0) + 1;
+  sequences.set(name, uid);
+  return prefix + uid;
+};
+
+/** Reset {@link sequentialUID} generator */
+export const resetSequentialUID = (name?: string) => {
+  if (typeof name === 'string') {
+    sequences.delete(name);
+  } else {
+    sequences.clear();
+  }
+};
+
+/** Return random unique identifier */
+export const randUID = (): string => {
+  const time = Date.now().toString(32);
+  const rand = Math.round(Math.random() * 1024 * 1024).toString(32);
+  return time + '-' + rand;
+};
+
+/**
+ * Generate unique id
+ * @deprecated Alias for {@link randUID}
+ */
+export const generateUId = randUID;


Test patch:
diff --git a/src/modules/esl-utils/misc/test/uid.test.ts b/src/modules/esl-utils/misc/test/uid.test.ts
index 9a500d55b..d07693865 100644
--- a/src/modules/esl-utils/misc/test/uid.test.ts
+++ b/src/modules/esl-utils/misc/test/uid.test.ts
@@ -1,12 +1,36 @@
-import {generateUId} from '../uid';
+import {randUID, resetSequentialUID, sequentialUID} from '../uid';
 
 const TRY_COUNT = 5;
 
 describe('misc/uid helper tests', () => {
-  test('uid', () => {
+  test('randUID', () => {
     const set = new Set();
     for (let i = 0; i < TRY_COUNT; ++i) {
-      set.add(generateUId());
+      set.add(randUID());
+    }
+    expect(set.size).toBe(TRY_COUNT);
+  });
+  test('seqUID', () => {
+    const set = new Set();
+    for (let i = 0; i < TRY_COUNT; ++i) {
+      set.add(sequentialUID('a'));
+    }
+    expect(set.size).toBe(TRY_COUNT);
+    for (let i = 0; i < TRY_COUNT; ++i) {
+      set.add(sequentialUID('b'));
+    }
+    expect(set.size).toBe(TRY_COUNT * 2);
+  });
+
+  test('reset seqUID', () => {
+    const set = new Set();
+    for (let i = 0; i < TRY_COUNT; ++i) {
+      set.add(sequentialUID('c'));
+    }
+    expect(set.size).toBe(TRY_COUNT);
+    resetSequentialUID('c');
+    for (let i = 0; i < TRY_COUNT; ++i) {
+      set.add(sequentialUID('c'));
     }
     expect(set.size).toBe(TRY_COUNT);
   });