diff options
| author | rxliuli <rxliuli@gmail.com> | 2025-11-04 05:03:50 +0800 |
|---|---|---|
| committer | rxliuli <rxliuli@gmail.com> | 2025-11-04 05:03:50 +0800 |
| commit | bce557cc2dc767628bed6aac87301a1be7c5431b (patch) | |
| tree | b51a051228d01fe3306cd7626d4a96768aadb944 /shared/components/src/utils/uniqueId.ts | |
init commit
Diffstat (limited to 'shared/components/src/utils/uniqueId.ts')
| -rw-r--r-- | shared/components/src/utils/uniqueId.ts | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/shared/components/src/utils/uniqueId.ts b/shared/components/src/utils/uniqueId.ts new file mode 100644 index 0000000..3a6d21d --- /dev/null +++ b/shared/components/src/utils/uniqueId.ts @@ -0,0 +1,71 @@ +import { getContext } from 'svelte'; + +export const UNIQUE_ID_CONTEXT_NAME = 'amp-web-unique-id'; + +interface UniqueContext { + nextId: number; +} + +// TODO: rdar://84029606 (Extract logger into shared util) +interface Logger { + warn(...args: any[]): string; +} +interface LoggerFactory { + loggerFor(name: string): Logger; +} + +export function initializeUniqueIdContext( + context: Map<string, unknown>, + loggerFactory: LoggerFactory, +): void { + const logger = loggerFactory.loggerFor('uniqueIdContext'); + + if (context.has(UNIQUE_ID_CONTEXT_NAME)) { + logger.warn( + `${UNIQUE_ID_CONTEXT_NAME} context has already been created. Cannot be created more than once`, + ); + } else { + const INITAL_STATE: UniqueContext = { nextId: 0 }; + context.set(UNIQUE_ID_CONTEXT_NAME, INITAL_STATE); + } +} + +/** + * Creates a unique Id string based on string provided + * + * @returns unique id string + */ +export type UniqueIdGenerator = () => string; + +// Custom elements most likely will not be used in an environment has that initialized the Svelte +// context. Components that are later wrapped by a custom element should use this function so that +// they can generate unique ids automatically when used inside a Svelte app, but not throw an error +// when used in other contexts. +// +export function maybeGetUniqueIdGenerator(): UniqueIdGenerator | undefined { + const UNIQUE_ID_PREFIX = 'uid-'; + const state: UniqueContext = getContext(UNIQUE_ID_CONTEXT_NAME); + const isNextIdANumber = typeof state?.nextId === 'number'; + + if (!isNextIdANumber) { + return; + } + + return () => { + const id = `${UNIQUE_ID_PREFIX}${state.nextId}`; + state.nextId += 1; + return id; + }; +} + +export function getUniqueIdGenerator(): UniqueIdGenerator { + const uniqueIdGenerator = maybeGetUniqueIdGenerator(); + + if (!uniqueIdGenerator) { + throw new Error( + `${UNIQUE_ID_CONTEXT_NAME} context has not been initialized. Initialize at application bootstrap.`, + ); + } + + return uniqueIdGenerator; +} |
