- Import LoggerComponent from ior:gitea:gitea.metatrom.net:universal-components/logger@1.0.0 - Replace console.warn and console.info with appropriate logger methods - Use warn level for fallback scenarios when native implementations fail - Use info level for polyfill installation notifications 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
136 lines
3.9 KiB
TypeScript
136 lines
3.9 KiB
TypeScript
/**
|
|
* Text Encoding Factory
|
|
*
|
|
* Creates encoder/decoder instances with automatic polyfill selection
|
|
*
|
|
* @module text-encoding@1.0.0
|
|
*/
|
|
|
|
import { LoggerComponent } from 'ior:gitea:gitea.metatrom.net:universal-components/logger@1.0.0';
|
|
import { TextDecoderPolyfill } from './TextDecoderPolyfill';
|
|
import { TextEncoderPolyfill } from './TextEncoderPolyfill';
|
|
import type {
|
|
ITextDecoder,
|
|
ITextEncoder,
|
|
ITextEncodingFactory,
|
|
TextDecoderOptions,
|
|
} from './interfaces';
|
|
|
|
export class TextEncodingFactory implements ITextEncodingFactory {
|
|
private static instance: TextEncodingFactory;
|
|
private static logger = new LoggerComponent('TextEncodingFactory');
|
|
|
|
/**
|
|
* Get factory singleton instance
|
|
*/
|
|
static getInstance(): TextEncodingFactory {
|
|
if (!TextEncodingFactory.instance) {
|
|
TextEncodingFactory.instance = new TextEncodingFactory();
|
|
}
|
|
return TextEncodingFactory.instance;
|
|
}
|
|
|
|
/**
|
|
* Create a new TextEncoder instance
|
|
* Uses native implementation if available, otherwise polyfill
|
|
*/
|
|
createEncoder(): ITextEncoder {
|
|
// @ts-expect-error - Check for native TextEncoder
|
|
if (typeof TextEncoder !== 'undefined') {
|
|
try {
|
|
// @ts-expect-error - Try to use native
|
|
return new TextEncoder();
|
|
} catch (e) {
|
|
// Fall back to polyfill if native fails
|
|
TextEncodingFactory.logger.warn('Native TextEncoder failed, using polyfill:', e);
|
|
}
|
|
}
|
|
|
|
return new TextEncoderPolyfill();
|
|
}
|
|
|
|
/**
|
|
* Create a new TextDecoder instance
|
|
* Uses native implementation if available, otherwise polyfill
|
|
*/
|
|
createDecoder(label: string = 'utf-8', options?: TextDecoderOptions): ITextDecoder {
|
|
// @ts-expect-error - Check for native TextDecoder
|
|
if (typeof TextDecoder !== 'undefined') {
|
|
try {
|
|
// @ts-expect-error - Try to use native
|
|
return new TextDecoder(label, options);
|
|
} catch (e) {
|
|
// Fall back to polyfill if native fails
|
|
TextEncodingFactory.logger.warn('Native TextDecoder failed, using polyfill:', e);
|
|
}
|
|
}
|
|
|
|
return new TextDecoderPolyfill(label, options);
|
|
}
|
|
|
|
/**
|
|
* Check if native TextEncoder/TextDecoder are available
|
|
*/
|
|
isNativelySupported(): boolean {
|
|
// @ts-expect-error - Check global scope
|
|
if (typeof TextEncoder === 'undefined' || typeof TextDecoder === 'undefined') {
|
|
return false;
|
|
}
|
|
|
|
// Try to instantiate to make sure they work
|
|
try {
|
|
// @ts-expect-error
|
|
const encoder = new TextEncoder();
|
|
// @ts-expect-error
|
|
const decoder = new TextDecoder();
|
|
|
|
// Basic functionality test
|
|
const testString = 'test';
|
|
const encoded = encoder.encode(testString);
|
|
const decoded = decoder.decode(encoded);
|
|
|
|
return decoded === testString;
|
|
} catch (_e) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convenience function to create an encoder
|
|
*/
|
|
export function createTextEncoder(): ITextEncoder {
|
|
return TextEncodingFactory.getInstance().createEncoder();
|
|
}
|
|
|
|
/**
|
|
* Convenience function to create a decoder
|
|
*/
|
|
export function createTextDecoder(label?: string, options?: TextDecoderOptions): ITextDecoder {
|
|
return TextEncodingFactory.getInstance().createDecoder(label, options);
|
|
}
|
|
|
|
/**
|
|
* Install polyfills globally if not present
|
|
* This makes TextEncoder/TextDecoder available everywhere
|
|
*/
|
|
export function installTextEncodingPolyfills(): void {
|
|
const logger = new LoggerComponent('TextEncodingPolyfills');
|
|
|
|
// @ts-expect-error
|
|
if (typeof global !== 'undefined') {
|
|
// @ts-expect-error
|
|
if (typeof global.TextEncoder === 'undefined') {
|
|
// @ts-expect-error
|
|
global.TextEncoder = TextEncoderPolyfill;
|
|
logger.info('Installed TextEncoder polyfill globally');
|
|
}
|
|
|
|
// @ts-expect-error
|
|
if (typeof global.TextDecoder === 'undefined') {
|
|
// @ts-expect-error
|
|
global.TextDecoder = TextDecoderPolyfill;
|
|
logger.info('Installed TextDecoder polyfill globally');
|
|
}
|
|
}
|
|
} |