inferis-ml 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,271 @@
1
+ type ModelState = 'idle' | 'loading' | 'ready' | 'inferring' | 'unloading' | 'error' | 'disposed';
2
+ interface WebGpuCapability {
3
+ readonly supported: boolean;
4
+ readonly adapter: {
5
+ readonly vendor: string;
6
+ readonly architecture: string;
7
+ readonly device: string;
8
+ readonly description: string;
9
+ } | null;
10
+ readonly limits: {
11
+ readonly maxBufferSize: number;
12
+ readonly maxStorageBufferBindingSize: number;
13
+ } | null;
14
+ readonly isFallback: boolean;
15
+ }
16
+ interface WasmCapability {
17
+ readonly supported: boolean;
18
+ readonly simd: boolean;
19
+ readonly threads: boolean;
20
+ }
21
+ interface CapabilityReport {
22
+ readonly webgpu: WebGpuCapability;
23
+ readonly wasm: WasmCapability;
24
+ readonly sharedWorker: boolean;
25
+ readonly broadcastChannel: boolean;
26
+ readonly webLocks: boolean;
27
+ readonly hardwareConcurrency: number;
28
+ }
29
+ type Device = 'webgpu' | 'wasm';
30
+ interface LoadProgressEvent {
31
+ readonly phase: string;
32
+ readonly loaded: number;
33
+ readonly total: number;
34
+ }
35
+ interface InferenceOptions {
36
+ readonly signal?: AbortSignal;
37
+ readonly priority?: 'high' | 'normal' | 'low';
38
+ }
39
+ interface PoolConfig {
40
+ /** Adapter factory for the AI runtime. Required. */
41
+ readonly adapter: ModelAdapterFactory;
42
+ /**
43
+ * URL to the pre-built dedicated worker file.
44
+ * Default: resolves `inferis/worker` relative to import.meta.url if available.
45
+ */
46
+ readonly workerUrl?: URL | string;
47
+ /** Maximum number of dedicated workers. Default: hardwareConcurrency - 1, min 1. */
48
+ readonly maxWorkers?: number;
49
+ /** Maximum combined memory budget in MB. Default: 2048. */
50
+ readonly maxMemoryMB?: number;
51
+ /** Default inference device. 'auto' tries WebGPU first, falls back to WASM. Default: 'auto'. */
52
+ readonly defaultDevice?: Device | 'auto';
53
+ /** Enable cross-tab model deduplication. Default: false. */
54
+ readonly crossTab?: boolean;
55
+ /** Per-task timeout in milliseconds. Default: 120_000. */
56
+ readonly taskTimeout?: number;
57
+ }
58
+ interface ModelLoadConfig {
59
+ /** Model identifier (e.g. HuggingFace model ID or URL). */
60
+ readonly model: string;
61
+ /** Estimated memory usage in MB. Used for pre-eviction budgeting. */
62
+ readonly estimatedMemoryMB?: number;
63
+ /** Progress callback for download and load phases. */
64
+ readonly onProgress?: (event: LoadProgressEvent) => void;
65
+ /** Additional adapter-specific config. */
66
+ readonly [key: string]: unknown;
67
+ }
68
+ interface ModelHandle<TOutput = unknown> {
69
+ /** Unique model instance ID. */
70
+ readonly id: string;
71
+ /** Current lifecycle state. */
72
+ readonly state: ModelState;
73
+ /** Approximate memory usage in MB. */
74
+ readonly memoryMB: number;
75
+ /** Resolved inference device. */
76
+ readonly device: Device;
77
+ /**
78
+ * Run non-streaming inference.
79
+ * @throws {InferisError} if the model is not in 'ready' state.
80
+ * @throws {AbortError} if the signal is aborted.
81
+ */
82
+ run: (input: unknown, options?: InferenceOptions) => Promise<TOutput>;
83
+ /**
84
+ * Run streaming inference. Returns a ReadableStream that emits output chunks.
85
+ * @throws {InferisError} if the model is not in 'ready' state.
86
+ */
87
+ stream: (input: unknown, options?: InferenceOptions) => ReadableStream<TOutput>;
88
+ /**
89
+ * Dispose the model and free its memory.
90
+ * Waits for any in-flight inference to complete before unloading.
91
+ */
92
+ dispose: () => Promise<void>;
93
+ /**
94
+ * Subscribe to state changes.
95
+ * @returns unsubscribe function
96
+ */
97
+ onStateChange: (callback: (state: ModelState) => void) => () => void;
98
+ }
99
+ interface WorkerPoolInterface {
100
+ /**
101
+ * Load a model and return a handle for inference.
102
+ * If the model is already loaded (same task + config), returns the existing handle.
103
+ */
104
+ load: <TOutput = unknown>(task: string, config: ModelLoadConfig) => Promise<ModelHandle<TOutput>>;
105
+ /**
106
+ * Return snapshot of detected browser capabilities.
107
+ */
108
+ capabilities: () => CapabilityReport;
109
+ /**
110
+ * Gracefully terminate all workers and dispose all models.
111
+ */
112
+ terminate: () => Promise<void>;
113
+ }
114
+ interface LoadedModel {
115
+ /** Opaque runtime-specific handle (pipeline instance, MLCEngine, etc.). */
116
+ readonly instance: unknown;
117
+ /** Actual memory consumed after loading, in MB. */
118
+ readonly memoryMB: number;
119
+ }
120
+ /**
121
+ * Adapter interface — implemented INSIDE the worker via the factory pattern.
122
+ * Never instantiated on the main thread.
123
+ */
124
+ interface ModelAdapter {
125
+ readonly name: string;
126
+ /**
127
+ * Load model into memory. Called inside the worker.
128
+ * Must call `onProgress` during download to forward progress to the main thread.
129
+ * @throws on load failure
130
+ */
131
+ load: (task: string, config: Record<string, unknown>, device: Device, onProgress: (event: LoadProgressEvent) => void) => Promise<LoadedModel>;
132
+ /**
133
+ * Run non-streaming inference.
134
+ * Return value must be structured-cloneable.
135
+ */
136
+ run: (model: LoadedModel, input: unknown, options?: unknown) => Promise<unknown>;
137
+ /**
138
+ * Run streaming inference.
139
+ * Call `onChunk` for each output chunk (token, image tile, etc.).
140
+ * onChunk values must be structured-cloneable.
141
+ * Resolve the promise when the stream is complete.
142
+ */
143
+ stream: (model: LoadedModel, input: unknown, onChunk: (chunk: unknown) => void, options?: unknown) => Promise<void>;
144
+ /**
145
+ * Unload model and release all resources.
146
+ * MUST call GPUBuffer.destroy() / GPUDevice.destroy() where applicable.
147
+ */
148
+ unload: (model: LoadedModel) => Promise<void>;
149
+ /**
150
+ * Estimate memory usage before loading. Used by MemoryBudget for pre-eviction.
151
+ */
152
+ estimateMemoryMB: (task: string, config: Record<string, unknown>) => number;
153
+ }
154
+ /**
155
+ * Factory that creates a ModelAdapter inside the worker.
156
+ * The factory itself is lightweight and runs on the main thread.
157
+ * create() is called inside the worker and does the heavy dynamic import().
158
+ */
159
+ interface ModelAdapterFactory {
160
+ readonly name: string;
161
+ create: () => Promise<ModelAdapter>;
162
+ }
163
+ type MainToWorkerMessage = {
164
+ readonly type: 'load-model';
165
+ readonly reqId: string;
166
+ readonly modelId: string;
167
+ readonly task: string;
168
+ readonly config: Record<string, unknown>;
169
+ readonly device: Device;
170
+ } | {
171
+ readonly type: 'unload-model';
172
+ readonly reqId: string;
173
+ readonly modelId: string;
174
+ } | {
175
+ readonly type: 'run';
176
+ readonly reqId: string;
177
+ readonly modelId: string;
178
+ readonly input: unknown;
179
+ readonly options?: unknown;
180
+ } | {
181
+ readonly type: 'run-stream';
182
+ readonly reqId: string;
183
+ readonly modelId: string;
184
+ readonly input: unknown;
185
+ readonly options?: unknown;
186
+ } | {
187
+ readonly type: 'abort';
188
+ readonly reqId: string;
189
+ } | {
190
+ readonly type: 'probe';
191
+ readonly reqId: string;
192
+ } | {
193
+ readonly type: 'ping';
194
+ };
195
+ type WorkerToMainMessage = {
196
+ readonly type: 'load-progress';
197
+ readonly reqId: string;
198
+ readonly progress: LoadProgressEvent;
199
+ } | {
200
+ readonly type: 'load-complete';
201
+ readonly reqId: string;
202
+ readonly memoryMB: number;
203
+ } | {
204
+ readonly type: 'load-error';
205
+ readonly reqId: string;
206
+ readonly error: SerializedError;
207
+ } | {
208
+ readonly type: 'unload-complete';
209
+ readonly reqId: string;
210
+ } | {
211
+ readonly type: 'unload-error';
212
+ readonly reqId: string;
213
+ readonly error: SerializedError;
214
+ } | {
215
+ readonly type: 'run-result';
216
+ readonly reqId: string;
217
+ readonly output: unknown;
218
+ } | {
219
+ readonly type: 'run-error';
220
+ readonly reqId: string;
221
+ readonly error: SerializedError;
222
+ } | {
223
+ readonly type: 'stream-chunk';
224
+ readonly reqId: string;
225
+ readonly chunk: unknown;
226
+ } | {
227
+ readonly type: 'stream-end';
228
+ readonly reqId: string;
229
+ readonly usage?: unknown;
230
+ } | {
231
+ readonly type: 'stream-error';
232
+ readonly reqId: string;
233
+ readonly error: SerializedError;
234
+ } | {
235
+ readonly type: 'probe-result';
236
+ readonly reqId: string;
237
+ readonly capabilities: unknown;
238
+ } | {
239
+ readonly type: 'device-lost';
240
+ readonly modelId: string;
241
+ readonly reason: string;
242
+ } | {
243
+ readonly type: 'pong';
244
+ };
245
+ interface SerializedError {
246
+ readonly name: string;
247
+ readonly message: string;
248
+ readonly code?: string;
249
+ readonly stack?: string | undefined;
250
+ }
251
+ interface ModelEntry {
252
+ readonly id: string;
253
+ readonly task: string;
254
+ readonly config: Record<string, unknown>;
255
+ state: ModelState;
256
+ device: Device;
257
+ memoryMB: number;
258
+ workerId: number | null;
259
+ stateListeners: Set<(state: ModelState) => void>;
260
+ }
261
+ type TaskPriority = 'high' | 'normal' | 'low';
262
+ interface ScheduledTask {
263
+ readonly reqId: string;
264
+ readonly modelId: string;
265
+ readonly priority: TaskPriority;
266
+ readonly enqueuedAt: number;
267
+ execute: (workerId: number) => void;
268
+ reject: (error: Error) => void;
269
+ }
270
+
271
+ export type { CapabilityReport as C, Device as D, InferenceOptions as I, LoadProgressEvent as L, MainToWorkerMessage as M, PoolConfig as P, SerializedError as S, TaskPriority as T, WorkerToMainMessage as W, ModelState as a, ModelEntry as b, ScheduledTask as c, ModelLoadConfig as d, ModelHandle as e, LoadedModel as f, ModelAdapter as g, ModelAdapterFactory as h, WasmCapability as i, WebGpuCapability as j, WorkerPoolInterface as k };
@@ -0,0 +1,2 @@
1
+ 'use strict';var w=Object.defineProperty;var k=(r,e)=>()=>(r&&(e=r(r=0)),e);var M=(r,e)=>{for(var t in e)w(r,t,{get:e[t],enumerable:true});};var f={};M(f,{clearCapabilitiesCache:()=>R,detectCapabilities:()=>P});function A(){return typeof WebAssembly>"u"?{simd:false,supported:false,threads:false}:{simd:WebAssembly.validate(v),supported:true,threads:WebAssembly.validate(E)}}async function _(){if(typeof navigator>"u"||!("gpu"in navigator))return {adapter:null,isFallback:false,limits:null,supported:false};let r=navigator.gpu;if(r==null)return {adapter:null,isFallback:false,limits:null,supported:false};try{let e=await r.requestAdapter();if(!e)return {adapter:null,isFallback:!1,limits:null,supported:!1};let t=await e.requestAdapterInfo?.()??{},a=e.isFallbackAdapter??!1;return {adapter:{architecture:t.architecture??"",description:t.description??"",device:t.device??"",vendor:t.vendor??""},isFallback:a,limits:{maxBufferSize:e.limits?.maxBufferSize??0,maxStorageBufferBindingSize:e.limits?.maxStorageBufferBindingSize??0},supported:!0}}catch{return {adapter:null,isFallback:false,limits:null,supported:false}}}function W(){return typeof SharedWorker<"u"}function F(){return typeof BroadcastChannel<"u"}function S(){return typeof navigator<"u"&&"locks"in navigator}async function P(){if(l)return l;let[r,e]=await Promise.all([_(),Promise.resolve(A())]);return l=Object.freeze({broadcastChannel:F(),hardwareConcurrency:typeof navigator<"u"?navigator.hardwareConcurrency??1:1,sharedWorker:W(),wasm:e,webgpu:r,webLocks:S()}),l}function R(){l=null;}var v,E,l,x=k(()=>{v=new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,10,1,8,0,65,0,253,15,0,0,11]),E=new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,4,1,3,1,1,10,11,1,9,0,254,1,2,0,65,0,11]);l=null;});var m=class r extends Error{code;constructor(e,t){super(e),this.name="InferisError",this.code=t;}static fromSerialized(e){let t=new r(e.message,e.code??"UNKNOWN");return t.name=e.name,e.stack&&(t.stack=e.stack),t}serialize(){let e={code:this.code,message:this.message,name:this.name};return this.stack!==void 0?{...e,stack:this.stack}:e}};function o(r){if(r instanceof m)return r.serialize();if(r instanceof Error){let e={code:"UNKNOWN",message:r.message,name:r.name};return r.stack!==void 0?{...e,stack:r.stack}:e}return {code:"UNKNOWN",message:String(r),name:"Error"}}var p=class{models=new Map;adapter=null;async initAdapter(e){this.adapter&&this.adapter.name===e.name||(this.adapter=await e.create());}isReady(){return this.adapter!==null}async load(e,t,a,n,s){if(!this.adapter)throw new Error("Adapter not initialized");if(this.models.has(e))return this.models.get(e);let i=await this.adapter.load(t,a,n,s);return this.models.set(e,i),i}async run(e,t,a){if(!this.adapter)throw new Error("Adapter not initialized");let n=this.getOrThrow(e);return this.adapter.run(n,t,a)}async stream(e,t,a,n){if(!this.adapter)throw new Error("Adapter not initialized");let s=this.getOrThrow(e);return this.adapter.stream(s,t,a,n)}async unload(e){let t=this.models.get(e);t&&(await this.adapter?.unload(t),this.models.delete(e));}has(e){return this.models.has(e)}getOrThrow(e){let t=this.models.get(e);if(!t)throw new Error(`Model "${e}" is not loaded in this worker`);return t}estimateMemoryMB(e,t){return this.adapter?.estimateMemoryMB(e,t)??0}};var c=class{constructor(e){this.post=e;}post;host=new p;adapterFactory=null;pending=new Map;async init(e,t){this.adapterFactory=e,await this.host.initAdapter(e);}async handle(e){switch(e.type){case "ping":this.post({type:"pong"});break;case "probe":await this.handleProbe(e.reqId);break;case "load-model":await this.handleLoad(e.reqId,e.modelId,e.task,e.config,e.device);break;case "unload-model":await this.handleUnload(e.reqId,e.modelId);break;case "run":await this.handleRun(e.reqId,e.modelId,e.input,e.options);break;case "run-stream":await this.handleStream(e.reqId,e.modelId,e.input,e.options);break;case "abort":this.handleAbort(e.reqId);break}}async handleProbe(e){let{detectCapabilities:t}=await Promise.resolve().then(()=>(x(),f)),a=await t();this.post({capabilities:a,reqId:e,type:"probe-result"});}async handleLoad(e,t,a,n,s){if(!this.adapterFactory){this.post({error:o(new Error("Worker not initialized")),reqId:e,type:"load-error"});return}try{await this.host.initAdapter(this.adapterFactory);let i=await this.host.load(t,a,n,s,h=>{this.post({progress:h,reqId:e,type:"load-progress"});});this.post({memoryMB:i.memoryMB,reqId:e,type:"load-complete"});}catch(i){this.post({error:o(i),reqId:e,type:"load-error"});}}async handleUnload(e,t){try{await this.host.unload(t),this.post({reqId:e,type:"unload-complete"});}catch(a){this.post({error:o(a),reqId:e,type:"unload-error"});}}async handleRun(e,t,a,n){try{let s=!1;this.pending.set(e,{reject:h=>{s=!0,this.post({error:o(h),reqId:e,type:"run-error"});}});let i=await this.host.run(t,a,n);this.pending.delete(e),s||this.post({output:i,reqId:e,type:"run-result"});}catch(s){this.pending.delete(e),this.post({error:o(s),reqId:e,type:"run-error"});}}async handleStream(e,t,a,n){let s=false;this.pending.set(e,{reject:i=>{s=true,this.post({error:o(i),reqId:e,type:"stream-error"});}});try{await this.host.stream(t,a,i=>{s||this.post({chunk:i,reqId:e,type:"stream-chunk"});},n),this.pending.delete(e),s||this.post({reqId:e,type:"stream-end"});}catch(i){this.pending.delete(e),s||this.post({error:o(i),reqId:e,type:"stream-error"});}}handleAbort(e){let t=this.pending.get(e);if(!t)return;this.pending.delete(e);let a=Object.assign(new Error("AbortError"),{name:"AbortError"});t.reject(a);}};var g=null;function j(r){g=r;}var d=null,u=false,b=[],y=null;async function D(r){if(!g){u=true,console.error("[inferis worker] no adapter factory registered"),self.postMessage({error:{code:"NO_ADAPTER",message:"No adapter factory registered. Call registerAdapterFactory() in your worker entry file.",name:"InferisError"},reqId:"__init__",type:"load-error"});return}try{d=new c(e=>self.postMessage(e)),await d.init(g,r);}catch(e){u=true,d=null,console.error("[inferis worker] init failed:",e),self.postMessage({error:o(e),reqId:"__init__",type:"load-error"});return}for(let e of b.splice(0))await d.handle(e);}function I(r){self.postMessage({error:{code:"INIT_FAILED",message:"Worker initialization failed",name:"InferisError"},reqId:r,type:"load-error"});}self.onmessage=async r=>{let e=r.data;if(e.type==="__init__"){y=D(e.device);return}if(e.type==="ping"){self.postMessage({type:"pong"});return}if(!d&&!u){b.push(e);return}if(y&&await y,u||!d){"reqId"in e&&I(e.reqId);return}await d.handle(e);};exports.registerAdapterFactory=j;//# sourceMappingURL=dedicated.worker.cjs.map
2
+ //# sourceMappingURL=dedicated.worker.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/capabilities.ts","../../src/core/errors.ts","../../src/worker/model-host.ts","../../src/worker/handler.ts","../../src/worker/dedicated.worker.ts"],"names":["capabilities_exports","__export","clearCapabilitiesCache","detectCapabilities","detectWasm","WASM_SIMD_PROBE","WASM_THREADS_PROBE","detectWebGpu","gpu","adapter","info","isFallback","detectSharedWorker","detectBroadcastChannel","detectWebLocks","cachedReport","webgpu","wasm","init_capabilities","__esmMin","InferisError","_InferisError","message","code","err","instance","result","serializeError","base","ModelHost","factory","modelId","task","config","device","onProgress","loaded","input","options","model","onChunk","WorkerMessageHandler","post","_device","msg","reqId","capabilities","progress","aborted","e","output","chunk","entry","abortError","registeredFactory","registerAdapterFactory","handler","initFailed","pendingMessages","initPromise","onInit","postInitError","event"],"mappings":"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","file":"dedicated.worker.cjs","sourcesContent":["import type { CapabilityReport, WasmCapability, WebGpuCapability } from './types.js';\n\nconst WASM_SIMD_PROBE = new Uint8Array([\n 0x00,\n 0x61,\n 0x73,\n 0x6D,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n 0x01,\n 0x05,\n 0x01,\n 0x60,\n 0x00,\n 0x01,\n 0x7B,\n 0x03,\n 0x02,\n 0x01,\n 0x00,\n 0x0A,\n 0x0A,\n 0x01,\n 0x08,\n 0x00,\n 0x41,\n 0x00,\n 0xFD,\n 0x0F,\n 0x00,\n 0x00,\n 0x0B,\n]);\n\nconst WASM_THREADS_PROBE = new Uint8Array([\n 0x00,\n 0x61,\n 0x73,\n 0x6D,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n 0x01,\n 0x04,\n 0x01,\n 0x60,\n 0x00,\n 0x00,\n 0x03,\n 0x02,\n 0x01,\n 0x00,\n 0x05,\n 0x04,\n 0x01,\n 0x03,\n 0x01,\n 0x01,\n 0x0A,\n 0x0B,\n 0x01,\n 0x09,\n 0x00,\n 0xFE,\n 0x01,\n 0x02,\n 0x00,\n 0x41,\n 0x00,\n 0x0B,\n]);\n\nfunction detectWasm(): WasmCapability {\n if (typeof WebAssembly === 'undefined') {\n return { simd: false, supported: false, threads: false };\n }\n return {\n simd: WebAssembly.validate(WASM_SIMD_PROBE),\n supported: true,\n threads: WebAssembly.validate(WASM_THREADS_PROBE),\n };\n}\n\nasync function detectWebGpu(): Promise<WebGpuCapability> {\n if (typeof navigator === 'undefined' || !('gpu' in navigator)) {\n return { adapter: null, isFallback: false, limits: null, supported: false };\n }\n\n // eslint-disable-next-line ts/no-explicit-any\n const gpu = (navigator as any).gpu;\n if (gpu == null) {\n return { adapter: null, isFallback: false, limits: null, supported: false };\n }\n\n try {\n const adapter = await gpu.requestAdapter();\n if (!adapter) {\n return { adapter: null, isFallback: false, limits: null, supported: false };\n }\n\n // eslint-disable-next-line ts/no-explicit-any\n const info = await adapter.requestAdapterInfo?.() as any ?? {};\n const isFallback: boolean = adapter.isFallbackAdapter ?? false;\n\n return {\n adapter: {\n architecture: (info.architecture as string) ?? '',\n description: (info.description as string) ?? '',\n device: (info.device as string) ?? '',\n vendor: (info.vendor as string) ?? '',\n },\n isFallback,\n limits: {\n maxBufferSize: adapter.limits?.maxBufferSize ?? 0,\n maxStorageBufferBindingSize: adapter.limits?.maxStorageBufferBindingSize ?? 0,\n },\n supported: true,\n };\n }\n catch {\n return { adapter: null, isFallback: false, limits: null, supported: false };\n }\n}\n\nfunction detectSharedWorker(): boolean {\n return typeof SharedWorker !== 'undefined';\n}\n\nfunction detectBroadcastChannel(): boolean {\n return typeof BroadcastChannel !== 'undefined';\n}\n\nfunction detectWebLocks(): boolean {\n return typeof navigator !== 'undefined' && 'locks' in navigator;\n}\n\nlet cachedReport: CapabilityReport | null = null;\n\n/**\n * Detect browser capabilities for AI inference.\n * Result is cached after first call.\n *\n * @example\n * const caps = await detectCapabilities();\n * if (caps.webgpu.supported) {\n * console.log('GPU vendor:', caps.webgpu.adapter?.vendor);\n * }\n */\nexport async function detectCapabilities(): Promise<CapabilityReport> {\n if (cachedReport)\n return cachedReport;\n\n const [webgpu, wasm] = await Promise.all([detectWebGpu(), Promise.resolve(detectWasm())]);\n\n cachedReport = Object.freeze({\n broadcastChannel: detectBroadcastChannel(),\n hardwareConcurrency: typeof navigator !== 'undefined' ? (navigator.hardwareConcurrency ?? 1) : 1,\n sharedWorker: detectSharedWorker(),\n wasm,\n webgpu,\n webLocks: detectWebLocks(),\n });\n\n return cachedReport;\n}\n\n/** Clear the cached capability report. Useful for testing. */\nexport function clearCapabilitiesCache(): void {\n cachedReport = null;\n}\n","import type { SerializedError } from './types.js';\n\nexport class InferisError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = 'InferisError';\n this.code = code;\n }\n\n static fromSerialized(err: SerializedError): InferisError {\n const instance = new InferisError(err.message, err.code ?? 'UNKNOWN');\n instance.name = err.name;\n if (err.stack)\n instance.stack = err.stack;\n return instance;\n }\n\n serialize(): SerializedError {\n const result: SerializedError = {\n code: this.code,\n message: this.message,\n name: this.name,\n };\n if (this.stack !== undefined) {\n return { ...result, stack: this.stack };\n }\n return result;\n }\n}\n\nexport class ModelLoadError extends InferisError {\n readonly modelId: string;\n\n constructor(modelId: string, message: string) {\n super(message, 'MODEL_LOAD_ERROR');\n this.name = 'ModelLoadError';\n this.modelId = modelId;\n }\n}\n\nexport class ModelNotReadyError extends InferisError {\n readonly modelId: string;\n\n constructor(modelId: string, state: string) {\n super(`Model \"${modelId}\" is not ready (state: ${state})`, 'MODEL_NOT_READY');\n this.name = 'ModelNotReadyError';\n this.modelId = modelId;\n }\n}\n\nexport class ModelDisposedError extends InferisError {\n readonly modelId: string;\n\n constructor(modelId: string) {\n super(`Model \"${modelId}\" has been disposed`, 'MODEL_DISPOSED');\n this.name = 'ModelDisposedError';\n this.modelId = modelId;\n }\n}\n\nexport class InferenceError extends InferisError {\n readonly modelId: string;\n\n constructor(modelId: string, message: string) {\n super(message, 'INFERENCE_ERROR');\n this.name = 'InferenceError';\n this.modelId = modelId;\n }\n}\n\nexport class BudgetExceededError extends InferisError {\n readonly requestedMB: number;\n readonly budgetMB: number;\n\n constructor(requestedMB: number, budgetMB: number) {\n super(\n `Cannot load model: requested ${requestedMB}MB exceeds memory budget ${budgetMB}MB`,\n 'BUDGET_EXCEEDED',\n );\n this.name = 'BudgetExceededError';\n this.budgetMB = budgetMB;\n this.requestedMB = requestedMB;\n }\n}\n\nexport class TaskTimeoutError extends InferisError {\n readonly reqId: string;\n\n constructor(reqId: string, timeoutMs: number) {\n super(`Task \"${reqId}\" timed out after ${timeoutMs}ms`, 'TASK_TIMEOUT');\n this.name = 'TaskTimeoutError';\n this.reqId = reqId;\n }\n}\n\nexport class WorkerError extends InferisError {\n readonly workerId: number;\n\n constructor(workerId: number, message: string) {\n super(message, 'WORKER_ERROR');\n this.name = 'WorkerError';\n this.workerId = workerId;\n }\n}\n\nexport class DeviceLostError extends InferisError {\n readonly modelId: string;\n readonly reason: string;\n\n constructor(modelId: string, reason: string) {\n super(`GPU device lost for model \"${modelId}\": ${reason}`, 'DEVICE_LOST');\n this.name = 'DeviceLostError';\n this.modelId = modelId;\n this.reason = reason;\n }\n}\n\nexport class InvalidStateTransitionError extends InferisError {\n constructor(from: string, to: string) {\n super(`Invalid state transition: ${from} -> ${to}`, 'INVALID_STATE_TRANSITION');\n this.name = 'InvalidStateTransitionError';\n }\n}\n\n/** Serialize any error for postMessage transmission. */\nexport function serializeError(err: unknown): SerializedError {\n if (err instanceof InferisError)\n return err.serialize();\n if (err instanceof Error) {\n const base: SerializedError = { code: 'UNKNOWN', message: err.message, name: err.name };\n return err.stack !== undefined ? { ...base, stack: err.stack } : base;\n }\n return { code: 'UNKNOWN', message: String(err), name: 'Error' };\n}\n","import type { LoadedModel, ModelAdapter, ModelAdapterFactory } from '../core/types.js';\n\n/**\n * Holds loaded model instances inside the worker.\n * A single worker may host multiple models simultaneously.\n */\nexport class ModelHost {\n private readonly models: Map<string, LoadedModel> = new Map();\n private adapter: ModelAdapter | null = null;\n\n /**\n * Initialize the adapter. Must be called once before loading models.\n */\n async initAdapter(factory: ModelAdapterFactory): Promise<void> {\n if (this.adapter && this.adapter.name === factory.name)\n return;\n this.adapter = await factory.create();\n }\n\n /**\n * Check if the adapter has been initialized.\n */\n isReady(): boolean {\n return this.adapter !== null;\n }\n\n /**\n * Load a model and store it by ID.\n */\n async load(\n modelId: string,\n task: string,\n config: Record<string, unknown>,\n device: 'webgpu' | 'wasm',\n onProgress: (event: { phase: string; loaded: number; total: number }) => void,\n ): Promise<LoadedModel> {\n if (!this.adapter)\n throw new Error('Adapter not initialized');\n if (this.models.has(modelId))\n return this.models.get(modelId)!;\n\n const loaded = await this.adapter.load(task, config, device, onProgress);\n this.models.set(modelId, loaded);\n return loaded;\n }\n\n /**\n * Run non-streaming inference on a loaded model.\n */\n async run(modelId: string, input: unknown, options?: unknown): Promise<unknown> {\n if (!this.adapter)\n throw new Error('Adapter not initialized');\n const model = this.getOrThrow(modelId);\n return this.adapter.run(model, input, options);\n }\n\n /**\n * Run streaming inference. Calls `onChunk` for each output chunk.\n */\n async stream(\n modelId: string,\n input: unknown,\n onChunk: (chunk: unknown) => void,\n options?: unknown,\n ): Promise<void> {\n if (!this.adapter)\n throw new Error('Adapter not initialized');\n const model = this.getOrThrow(modelId);\n return this.adapter.stream(model, input, onChunk, options);\n }\n\n /**\n * Unload a model and free its resources.\n */\n async unload(modelId: string): Promise<void> {\n const model = this.models.get(modelId);\n if (!model)\n return;\n\n await this.adapter?.unload(model);\n this.models.delete(modelId);\n }\n\n /**\n * Check if a model is currently loaded.\n */\n has(modelId: string): boolean {\n return this.models.has(modelId);\n }\n\n private getOrThrow(modelId: string): LoadedModel {\n const model = this.models.get(modelId);\n if (!model)\n throw new Error(`Model \"${modelId}\" is not loaded in this worker`);\n return model;\n }\n\n /** Estimate memory for a model before loading. */\n estimateMemoryMB(task: string, config: Record<string, unknown>): number {\n return this.adapter?.estimateMemoryMB(task, config) ?? 0;\n }\n}\n","import type {\n Device,\n MainToWorkerMessage,\n ModelAdapterFactory,\n WorkerToMainMessage,\n} from '../core/types.js';\nimport { serializeError } from '../core/errors.js';\nimport { ModelHost } from './model-host.js';\n\ntype PostFn = (msg: WorkerToMainMessage) => void;\n\ninterface AbortEntry {\n reject: (reason: Error) => void;\n}\n\n/**\n * Message dispatcher that runs inside a Web Worker.\n * Receives MainToWorkerMessage, dispatches to ModelHost, and posts responses.\n */\nexport class WorkerMessageHandler {\n private readonly host = new ModelHost();\n private adapterFactory: ModelAdapterFactory | null = null;\n private readonly pending = new Map<string, AbortEntry>();\n\n constructor(private readonly post: PostFn) {}\n\n /**\n * Initialize the handler with the adapter factory and resolved device.\n * Must be called once before handling any messages.\n */\n async init(factory: ModelAdapterFactory, _device: Device): Promise<void> {\n this.adapterFactory = factory;\n await this.host.initAdapter(factory);\n }\n\n /**\n * Handle an incoming message from the main thread.\n */\n async handle(msg: MainToWorkerMessage): Promise<void> {\n switch (msg.type) {\n case 'ping':\n this.post({ type: 'pong' });\n break;\n case 'probe':\n await this.handleProbe(msg.reqId);\n break;\n case 'load-model':\n await this.handleLoad(msg.reqId, msg.modelId, msg.task, msg.config, msg.device);\n break;\n case 'unload-model':\n await this.handleUnload(msg.reqId, msg.modelId);\n break;\n case 'run':\n await this.handleRun(msg.reqId, msg.modelId, msg.input, msg.options);\n break;\n case 'run-stream':\n await this.handleStream(msg.reqId, msg.modelId, msg.input, msg.options);\n break;\n case 'abort':\n this.handleAbort(msg.reqId);\n break;\n }\n }\n\n private async handleProbe(reqId: string): Promise<void> {\n const { detectCapabilities } = await import('../core/capabilities.js');\n const capabilities = await detectCapabilities();\n this.post({ capabilities, reqId, type: 'probe-result' });\n }\n\n private async handleLoad(\n reqId: string,\n modelId: string,\n task: string,\n config: Record<string, unknown>,\n device: Device,\n ): Promise<void> {\n if (!this.adapterFactory) {\n this.post({\n error: serializeError(new Error('Worker not initialized')),\n reqId,\n type: 'load-error',\n });\n return;\n }\n\n try {\n await this.host.initAdapter(this.adapterFactory);\n const model = await this.host.load(modelId, task, config, device, (progress) => {\n this.post({ progress, reqId, type: 'load-progress' });\n });\n this.post({ memoryMB: model.memoryMB, reqId, type: 'load-complete' });\n }\n catch (err) {\n this.post({ error: serializeError(err), reqId, type: 'load-error' });\n }\n }\n\n private async handleUnload(reqId: string, modelId: string): Promise<void> {\n try {\n await this.host.unload(modelId);\n this.post({ reqId, type: 'unload-complete' });\n }\n catch (err) {\n this.post({ error: serializeError(err), reqId, type: 'unload-error' });\n }\n }\n\n private async handleRun(\n reqId: string,\n modelId: string,\n input: unknown,\n options: unknown,\n ): Promise<void> {\n try {\n let aborted = false;\n this.pending.set(reqId, {\n reject: (e) => {\n aborted = true;\n this.post({ error: serializeError(e), reqId, type: 'run-error' });\n },\n });\n\n const output = await this.host.run(modelId, input, options);\n\n this.pending.delete(reqId);\n if (!aborted) {\n this.post({ output, reqId, type: 'run-result' });\n }\n }\n catch (err) {\n this.pending.delete(reqId);\n this.post({ error: serializeError(err), reqId, type: 'run-error' });\n }\n }\n\n private async handleStream(\n reqId: string,\n modelId: string,\n input: unknown,\n options: unknown,\n ): Promise<void> {\n let aborted = false;\n\n this.pending.set(reqId, {\n reject: (e) => {\n aborted = true;\n this.post({ error: serializeError(e), reqId, type: 'stream-error' });\n },\n });\n\n try {\n await this.host.stream(\n modelId,\n input,\n (chunk) => {\n if (!aborted) {\n this.post({ chunk, reqId, type: 'stream-chunk' });\n }\n },\n options,\n );\n\n this.pending.delete(reqId);\n if (!aborted) {\n this.post({ reqId, type: 'stream-end' });\n }\n }\n catch (err) {\n this.pending.delete(reqId);\n if (!aborted) {\n this.post({ error: serializeError(err), reqId, type: 'stream-error' });\n }\n }\n }\n\n private handleAbort(reqId: string): void {\n const entry = this.pending.get(reqId);\n if (!entry)\n return;\n\n this.pending.delete(reqId);\n const abortError = Object.assign(new Error('AbortError'), { name: 'AbortError' });\n entry.reject(abortError);\n }\n}\n","import type { Device, MainToWorkerMessage, ModelAdapterFactory } from '../core/types.js';\nimport { serializeError } from '../core/errors.js';\nimport { WorkerMessageHandler } from './handler.js';\n\ndeclare const self: DedicatedWorkerGlobalScope;\n\ninterface InitMessage {\n type: '__init__';\n device: Device;\n}\n\ntype AnyMessage = MainToWorkerMessage | InitMessage;\n\n/**\n * Adapter factory registered by the worker entry file.\n * Must be set via `registerAdapterFactory()` before the pool sends `__init__`.\n */\nlet registeredFactory: ModelAdapterFactory | null = null;\n\n/**\n * Register the adapter factory for this dedicated worker.\n * Call this in your custom worker entry file before any messages arrive.\n *\n * @example\n * ```ts\n * // my-worker.ts\n * import { registerAdapterFactory } from 'inferis-ml/worker-runtime';\n * import { transformersAdapter } from 'inferis-ml/adapters/transformers';\n * registerAdapterFactory(transformersAdapter());\n * ```\n */\nexport function registerAdapterFactory(factory: ModelAdapterFactory): void {\n registeredFactory = factory;\n}\n\nlet handler: WorkerMessageHandler | null = null;\nlet initFailed = false;\nconst pendingMessages: MainToWorkerMessage[] = [];\nlet initPromise: Promise<void> | null = null;\n\nasync function onInit(device: Device): Promise<void> {\n if (!registeredFactory) {\n initFailed = true;\n console.error('[inferis worker] no adapter factory registered');\n self.postMessage({\n error: {\n code: 'NO_ADAPTER',\n message: 'No adapter factory registered. Call registerAdapterFactory() in your worker entry file.',\n name: 'InferisError',\n },\n reqId: '__init__',\n type: 'load-error',\n });\n return;\n }\n\n try {\n handler = new WorkerMessageHandler(msg => self.postMessage(msg));\n await handler.init(registeredFactory, device);\n }\n catch (err) {\n initFailed = true;\n handler = null;\n console.error('[inferis worker] init failed:', err);\n self.postMessage({\n error: serializeError(err),\n reqId: '__init__',\n type: 'load-error',\n });\n return;\n }\n\n for (const msg of pendingMessages.splice(0)) {\n await handler.handle(msg);\n }\n}\n\nfunction postInitError(reqId: string): void {\n self.postMessage({\n error: { code: 'INIT_FAILED', message: 'Worker initialization failed', name: 'InferisError' },\n reqId,\n type: 'load-error',\n });\n}\n\nself.onmessage = async (event: MessageEvent<AnyMessage>) => {\n const msg = event.data;\n\n if (msg.type === '__init__') {\n initPromise = onInit(msg.device);\n return;\n }\n\n if (msg.type === 'ping') {\n self.postMessage({ type: 'pong' });\n return;\n }\n\n if (!handler && !initFailed) {\n pendingMessages.push(msg);\n return;\n }\n\n if (initPromise)\n await initPromise;\n\n if (initFailed || !handler) {\n if ('reqId' in msg) {\n postInitError(msg.reqId);\n }\n return;\n }\n\n await handler.handle(msg);\n};\n"]}
@@ -0,0 +1,17 @@
1
+ import { h as ModelAdapterFactory } from '../types-Y6Ytjh7U.cjs';
2
+
3
+ /**
4
+ * Register the adapter factory for this dedicated worker.
5
+ * Call this in your custom worker entry file before any messages arrive.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * // my-worker.ts
10
+ * import { registerAdapterFactory } from 'inferis-ml/worker-runtime';
11
+ * import { transformersAdapter } from 'inferis-ml/adapters/transformers';
12
+ * registerAdapterFactory(transformersAdapter());
13
+ * ```
14
+ */
15
+ declare function registerAdapterFactory(factory: ModelAdapterFactory): void;
16
+
17
+ export { registerAdapterFactory };
@@ -0,0 +1,17 @@
1
+ import { h as ModelAdapterFactory } from '../types-Y6Ytjh7U.js';
2
+
3
+ /**
4
+ * Register the adapter factory for this dedicated worker.
5
+ * Call this in your custom worker entry file before any messages arrive.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * // my-worker.ts
10
+ * import { registerAdapterFactory } from 'inferis-ml/worker-runtime';
11
+ * import { transformersAdapter } from 'inferis-ml/adapters/transformers';
12
+ * registerAdapterFactory(transformersAdapter());
13
+ * ```
14
+ */
15
+ declare function registerAdapterFactory(factory: ModelAdapterFactory): void;
16
+
17
+ export { registerAdapterFactory };