this repo has no description
1import { getContext } from 'svelte';
2
3export const UNIQUE_ID_CONTEXT_NAME = 'amp-web-unique-id';
4
5interface UniqueContext {
6 nextId: number;
7}
8
9// TODO: rdar://84029606 (Extract logger into shared util)
10interface Logger {
11 warn(...args: any[]): string;
12}
13interface LoggerFactory {
14 loggerFor(name: string): Logger;
15}
16
17export function initializeUniqueIdContext(
18 context: Map<string, unknown>,
19 loggerFactory: LoggerFactory,
20): void {
21 const logger = loggerFactory.loggerFor('uniqueIdContext');
22
23 if (context.has(UNIQUE_ID_CONTEXT_NAME)) {
24 logger.warn(
25 `${UNIQUE_ID_CONTEXT_NAME} context has already been created. Cannot be created more than once`,
26 );
27 } else {
28 const INITAL_STATE: UniqueContext = { nextId: 0 };
29 context.set(UNIQUE_ID_CONTEXT_NAME, INITAL_STATE);
30 }
31}
32
33/**
34 * Creates a unique Id string based on string provided
35 *
36 * @returns unique id string
37 */
38export type UniqueIdGenerator = () => string;
39
40// Custom elements most likely will not be used in an environment has that initialized the Svelte
41// context. Components that are later wrapped by a custom element should use this function so that
42// they can generate unique ids automatically when used inside a Svelte app, but not throw an error
43// when used in other contexts.
44//
45export function maybeGetUniqueIdGenerator(): UniqueIdGenerator | undefined {
46 const UNIQUE_ID_PREFIX = 'uid-';
47 const state: UniqueContext = getContext(UNIQUE_ID_CONTEXT_NAME);
48 const isNextIdANumber = typeof state?.nextId === 'number';
49
50 if (!isNextIdANumber) {
51 return;
52 }
53
54 return () => {
55 const id = `${UNIQUE_ID_PREFIX}${state.nextId}`;
56 state.nextId += 1;
57 return id;
58 };
59}
60
61export function getUniqueIdGenerator(): UniqueIdGenerator {
62 const uniqueIdGenerator = maybeGetUniqueIdGenerator();
63
64 if (!uniqueIdGenerator) {
65 throw new Error(
66 `${UNIQUE_ID_CONTEXT_NAME} context has not been initialized. Initialize at application bootstrap.`,
67 );
68 }
69
70 return uniqueIdGenerator;
71}