1+ /**
2+ * Browser compatibility detection and strategy selection
3+ */
4+ export class BrowserCompatibility {
5+ /**
6+ * Check if WebAssembly is supported
7+ */
8+ static hasWebAssembly ( ) : boolean {
9+ return typeof WebAssembly !== 'undefined' &&
10+ typeof WebAssembly . compile === 'function' &&
11+ typeof WebAssembly . instantiate === 'function' ;
12+ }
13+
14+ /**
15+ * Check if Canvas API is supported
16+ */
17+ static hasCanvas ( ) : boolean {
18+ if ( typeof document === 'undefined' ) {
19+ return false ;
20+ }
21+
22+ try {
23+ const canvas = document . createElement ( 'canvas' ) ;
24+ const ctx = canvas . getContext ( '2d' ) ;
25+ return ctx !== null ;
26+ } catch {
27+ return false ;
28+ }
29+ }
30+
31+ /**
32+ * Check if Image constructor is available
33+ */
34+ static hasImage ( ) : boolean {
35+ return typeof Image !== 'undefined' ;
36+ }
37+
38+ /**
39+ * Check if Blob is supported
40+ */
41+ static hasBlob ( ) : boolean {
42+ return typeof Blob !== 'undefined' ;
43+ }
44+
45+ /**
46+ * Check if URL.createObjectURL is supported
47+ */
48+ static hasObjectURL ( ) : boolean {
49+ return typeof URL !== 'undefined' &&
50+ typeof URL . createObjectURL === 'function' &&
51+ typeof URL . revokeObjectURL === 'function' ;
52+ }
53+
54+ /**
55+ * Select the best strategy based on capabilities
56+ */
57+ static selectStrategy ( options : {
58+ hasWebAssembly ?: boolean ;
59+ hasCanvas ?: boolean ;
60+ hasImage ?: boolean ;
61+ preferredStrategy ?: 'wasm' | 'canvas' | 'basic' | 'none' ;
62+ } ) : 'wasm' | 'canvas' | 'basic' | 'none' {
63+ const {
64+ hasWebAssembly = this . hasWebAssembly ( ) ,
65+ hasCanvas = this . hasCanvas ( ) ,
66+ hasImage = this . hasImage ( ) ,
67+ preferredStrategy
68+ } = options ;
69+
70+ // If a preferred strategy is specified and available, use it
71+ if ( preferredStrategy ) {
72+ switch ( preferredStrategy ) {
73+ case 'wasm' :
74+ if ( hasWebAssembly ) return 'wasm' ;
75+ break ;
76+ case 'canvas' :
77+ if ( hasCanvas && hasImage ) return 'canvas' ;
78+ break ;
79+ case 'basic' :
80+ if ( hasImage ) return 'basic' ;
81+ break ;
82+ case 'none' :
83+ return 'none' ;
84+ }
85+ }
86+
87+ // Auto-select based on capabilities
88+ if ( hasWebAssembly ) {
89+ return 'wasm' ;
90+ } else if ( hasCanvas && hasImage ) {
91+ return 'canvas' ;
92+ } else if ( hasImage ) {
93+ return 'basic' ;
94+ } else {
95+ return 'none' ;
96+ }
97+ }
98+
99+ /**
100+ * Get comprehensive capability report
101+ */
102+ static checkCapabilities ( ) : CapabilityReport {
103+ const hasWebAssembly = this . hasWebAssembly ( ) ;
104+ const hasCanvas = this . hasCanvas ( ) ;
105+ const hasImage = this . hasImage ( ) ;
106+ const hasBlob = this . hasBlob ( ) ;
107+ const hasObjectURL = this . hasObjectURL ( ) ;
108+
109+ const recommendedStrategy = this . selectStrategy ( {
110+ hasWebAssembly,
111+ hasCanvas,
112+ hasImage
113+ } ) ;
114+
115+ return {
116+ hasWebAssembly,
117+ hasCanvas,
118+ hasImage,
119+ hasBlob,
120+ hasObjectURL,
121+ recommendedStrategy
122+ } ;
123+ }
124+
125+ /**
126+ * Detect browser type
127+ */
128+ static detectBrowser ( ) : BrowserType {
129+ // Check if we're in Node.js
130+ if ( typeof window === 'undefined' && typeof process !== 'undefined' ) {
131+ return 'node' ;
132+ }
133+
134+ // Check for browser-specific features
135+ const userAgent = typeof navigator !== 'undefined' ? navigator . userAgent : '' ;
136+
137+ if ( userAgent . includes ( 'Chrome' ) && ! userAgent . includes ( 'Edg' ) ) {
138+ return 'chrome' ;
139+ } else if ( userAgent . includes ( 'Firefox' ) ) {
140+ return 'firefox' ;
141+ } else if ( userAgent . includes ( 'Safari' ) && ! userAgent . includes ( 'Chrome' ) ) {
142+ return 'safari' ;
143+ } else if ( userAgent . includes ( 'Edg' ) ) {
144+ return 'edge' ;
145+ } else {
146+ return 'unknown' ;
147+ }
148+ }
149+
150+ /**
151+ * Get browser-specific recommendations
152+ */
153+ static getRecommendations ( ) : string [ ] {
154+ const browser = this . detectBrowser ( ) ;
155+ const capabilities = this . checkCapabilities ( ) ;
156+ const recommendations : string [ ] = [ ] ;
157+
158+ // General recommendations
159+ if ( ! capabilities . hasWebAssembly ) {
160+ recommendations . push ( 'WebAssembly not supported. Using Canvas fallback for image processing.' ) ;
161+ }
162+
163+ if ( ! capabilities . hasCanvas ) {
164+ recommendations . push ( 'Canvas API not available. Limited image processing capabilities.' ) ;
165+ }
166+
167+ // Browser-specific recommendations
168+ switch ( browser ) {
169+ case 'safari' :
170+ recommendations . push ( 'Safari detected. Some WASM features may have reduced performance.' ) ;
171+ break ;
172+ case 'firefox' :
173+ recommendations . push ( 'Firefox detected. Optimal WASM performance available.' ) ;
174+ break ;
175+ case 'chrome' :
176+ case 'edge' :
177+ recommendations . push ( 'Chromium-based browser detected. All features supported.' ) ;
178+ break ;
179+ case 'node' :
180+ recommendations . push ( 'Node.js environment detected. Limited image processing without Canvas libraries.' ) ;
181+ break ;
182+ }
183+
184+ return recommendations ;
185+ }
186+
187+ /**
188+ * Get performance hints based on capabilities
189+ */
190+ static getPerformanceHints ( options ?: {
191+ hasWebAssembly ?: boolean ;
192+ hasCanvas ?: boolean ;
193+ } ) : PerformanceHints {
194+ const capabilities = options || this . checkCapabilities ( ) ;
195+
196+ return {
197+ useWASM : capabilities . hasWebAssembly ?? false ,
198+ maxImageSize : capabilities . hasWebAssembly
199+ ? 50 * 1024 * 1024 // 50MB with WASM
200+ : 10 * 1024 * 1024 , // 10MB with Canvas
201+ cacheStrategy : capabilities . hasWebAssembly ? 'aggressive' : 'conservative' ,
202+ parallelProcessing : capabilities . hasWebAssembly ,
203+ preferredFormats : capabilities . hasWebAssembly
204+ ? [ 'webp' , 'jpeg' , 'png' ]
205+ : [ 'jpeg' , 'png' ]
206+ } ;
207+ }
208+ }
209+
210+ /**
211+ * Browser type enumeration
212+ */
213+ export type BrowserType = 'chrome' | 'firefox' | 'safari' | 'edge' | 'node' | 'unknown' ;
214+
215+ /**
216+ * Capability report interface
217+ */
218+ export interface CapabilityReport {
219+ hasWebAssembly : boolean ;
220+ hasCanvas : boolean ;
221+ hasImage : boolean ;
222+ hasBlob : boolean ;
223+ hasObjectURL : boolean ;
224+ recommendedStrategy : 'wasm' | 'canvas' | 'basic' | 'none' ;
225+ }
226+
227+ /**
228+ * Performance hints interface
229+ */
230+ export interface PerformanceHints {
231+ useWASM : boolean ;
232+ maxImageSize : number ;
233+ cacheStrategy : 'aggressive' | 'conservative' ;
234+ parallelProcessing ?: boolean ;
235+ preferredFormats ?: string [ ] ;
236+ }
0 commit comments