/** * Text Encoding Service Implementation * * Provides shared encoder/decoder instances with automatic polyfill fallback * * @module text-encoding@1.0.0 */ import type { ITextDecoder, ITextEncoder, ITextEncodingService } from './interfaces'; import { TextDecoderPolyfill } from './TextDecoderPolyfill'; import { TextEncoderPolyfill } from './TextEncoderPolyfill'; export class TextEncodingService implements ITextEncodingService { readonly encoder: ITextEncoder; readonly decoder: ITextDecoder; constructor() { // Check for native support and use it if available if (this.hasNativeSupport()) { // Use native implementations if available // @ts-expect-error - TextEncoder might exist globally this.encoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : new TextEncoderPolyfill(); // @ts-expect-error - TextDecoder might exist globally this.decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder() : new TextDecoderPolyfill(); } else { // Use polyfills this.encoder = new TextEncoderPolyfill(); this.decoder = new TextDecoderPolyfill(); } } /** * Check if native TextEncoder/TextDecoder are available */ private hasNativeSupport(): boolean { // @ts-expect-error - Check global scope return typeof TextEncoder !== 'undefined' && typeof TextDecoder !== 'undefined'; } /** * Encode string to UTF-8 bytes */ encode(text: string): Uint8Array { return this.encoder.encode(text); } /** * Decode bytes to string */ decode(bytes: Uint8Array | ArrayBuffer | number[]): string { if (Array.isArray(bytes)) { // Convert number array to Uint8Array return this.decoder.decode(new Uint8Array(bytes)); } return this.decoder.decode(bytes as Uint8Array | ArrayBuffer); } /** * Convenience method: string to UTF-8 */ stringToUtf8(text: string): Uint8Array { return this.encode(text); } /** * Convenience method: UTF-8 to string */ utf8ToString(bytes: Uint8Array | number[]): string { return this.decode(bytes); } } /** * Singleton instance for shared use */ let serviceInstance: TextEncodingService | null = null; /** * Get or create the singleton service instance */ export function getTextEncodingService(): ITextEncodingService { if (!serviceInstance) { serviceInstance = new TextEncodingService(); } return serviceInstance; }