**feat: enhance threading compatibility and refactor module loading**
- Refactored `TextEncoder` and `TextDecoder` in `src/utils/tensorflowUtils.ts` to handle environments without global availability, logging warnings and providing fallback implementations. - Enhanced threading utilities in `src/utils/environment.ts`: - Introduced `areWorkerThreadsAvailableSync()` and `isThreadingAvailableAsync()` for synchronous and asynchronous checks. - Improved compatibility across browser and Node.js environments. - Migrated `fileSystemStorage.ts` to use dynamic imports for Node.js modules, removing synchronous loading mechanisms to align with ES module standards. - Updated `cli-package/package.json` keywords to include `browser` and `container`, improving discoverability. - Added `worker_threads` as an external dependency in `cli-package/rollup.config.js` and `rollup.config.js`. - Updated `.gitignore` to ignore all `tgz` files dynamically under main and CLI package. This update improves threading compatibility, enhances environment-specific support, and aligns with modern module loading practices.
This commit is contained in:
parent
be56ea52b7
commit
ac82c55a6b
8 changed files with 89 additions and 104 deletions
|
|
@ -6,53 +6,75 @@
|
|||
* Check if code is running in a browser environment
|
||||
*/
|
||||
export function isBrowser(): boolean {
|
||||
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
||||
return typeof window !== 'undefined' && typeof document !== 'undefined'
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if code is running in a Node.js environment
|
||||
*/
|
||||
export function isNode(): boolean {
|
||||
return typeof process !== 'undefined' &&
|
||||
process.versions != null &&
|
||||
process.versions.node != null;
|
||||
return (
|
||||
typeof process !== 'undefined' &&
|
||||
process.versions != null &&
|
||||
process.versions.node != null
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if code is running in a Web Worker environment
|
||||
*/
|
||||
export function isWebWorker(): boolean {
|
||||
return typeof self === 'object' &&
|
||||
self.constructor &&
|
||||
self.constructor.name === 'DedicatedWorkerGlobalScope';
|
||||
return (
|
||||
typeof self === 'object' &&
|
||||
self.constructor &&
|
||||
self.constructor.name === 'DedicatedWorkerGlobalScope'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Web Workers are available in the current environment
|
||||
*/
|
||||
export function areWebWorkersAvailable(): boolean {
|
||||
return isBrowser() && typeof Worker !== 'undefined';
|
||||
return isBrowser() && typeof Worker !== 'undefined'
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Worker Threads are available in the current environment (Node.js)
|
||||
*/
|
||||
export function areWorkerThreadsAvailable(): boolean {
|
||||
if (!isNode()) return false;
|
||||
export async function areWorkerThreadsAvailable(): Promise<boolean> {
|
||||
if (!isNode()) return false
|
||||
|
||||
try {
|
||||
// Dynamic import to avoid errors in browser environments
|
||||
require('worker_threads');
|
||||
return true;
|
||||
// Use dynamic import to avoid errors in browser environments
|
||||
await import('worker_threads')
|
||||
return true
|
||||
} catch (e) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronous version that doesn't actually try to load the module
|
||||
* This is safer in ES module environments
|
||||
*/
|
||||
export function areWorkerThreadsAvailableSync(): boolean {
|
||||
if (!isNode()) return false
|
||||
|
||||
// In Node.js 12+, worker_threads is available without requiring a flag
|
||||
return parseInt(process.versions.node.split('.')[0]) >= 12
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if threading is available in the current environment
|
||||
* Returns true if either Web Workers (browser) or Worker Threads (Node.js) are available
|
||||
*/
|
||||
export function isThreadingAvailable(): boolean {
|
||||
return areWebWorkersAvailable() || areWorkerThreadsAvailable();
|
||||
return areWebWorkersAvailable() || areWorkerThreadsAvailableSync()
|
||||
}
|
||||
|
||||
/**
|
||||
* Async version of isThreadingAvailable
|
||||
*/
|
||||
export async function isThreadingAvailableAsync(): Promise<boolean> {
|
||||
return areWebWorkersAvailable() || (await areWorkerThreadsAvailable())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,13 +33,40 @@ if (
|
|||
isFloat32Array,
|
||||
isTypedArray,
|
||||
// Use the global TextEncoder/TextDecoder directly
|
||||
TextEncoder: typeof TextEncoder !== 'undefined' ? TextEncoder : null,
|
||||
TextDecoder: typeof TextDecoder !== 'undefined' ? TextDecoder : null
|
||||
TextEncoder:
|
||||
typeof TextEncoder !== 'undefined'
|
||||
? TextEncoder
|
||||
: function () {
|
||||
console.warn(
|
||||
'TextEncoder constructor called but not available'
|
||||
)
|
||||
return { encode: (str: string) => new Uint8Array([]) }
|
||||
},
|
||||
TextDecoder:
|
||||
typeof TextDecoder !== 'undefined'
|
||||
? TextDecoder
|
||||
: function () {
|
||||
console.warn(
|
||||
'TextDecoder constructor called but not available'
|
||||
)
|
||||
return { decode: (bytes: Uint8Array) => '' }
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize TextEncoder/TextDecoder directly from globals
|
||||
this.textEncoder = new TextEncoder()
|
||||
this.textDecoder = new TextDecoder()
|
||||
if (typeof TextEncoder !== 'undefined') {
|
||||
this.textEncoder = new TextEncoder()
|
||||
} else {
|
||||
console.warn('TextEncoder is not available in this environment')
|
||||
this.textEncoder = { encode: (str: string) => new Uint8Array([]) }
|
||||
}
|
||||
|
||||
if (typeof TextDecoder !== 'undefined') {
|
||||
this.textDecoder = new TextDecoder()
|
||||
} else {
|
||||
console.warn('TextDecoder is not available in this environment')
|
||||
this.textDecoder = { decode: (bytes: Uint8Array) => '' }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue