edgeflowjs 0.1.0 → 0.3.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.
- package/README.md +200 -66
- package/dist/backends/index.d.ts +9 -2
- package/dist/backends/index.d.ts.map +1 -1
- package/dist/backends/index.js +13 -13
- package/dist/backends/index.js.map +1 -1
- package/dist/backends/onnx.d.ts +49 -4
- package/dist/backends/onnx.d.ts.map +1 -1
- package/dist/backends/onnx.js +165 -76
- package/dist/backends/onnx.js.map +1 -1
- package/dist/backends/transformers-adapter.d.ts +99 -0
- package/dist/backends/transformers-adapter.d.ts.map +1 -0
- package/dist/backends/transformers-adapter.js +171 -0
- package/dist/backends/transformers-adapter.js.map +1 -0
- package/dist/backends/webgpu.d.ts +7 -5
- package/dist/backends/webgpu.d.ts.map +1 -1
- package/dist/backends/webgpu.js +7 -5
- package/dist/backends/webgpu.js.map +1 -1
- package/dist/backends/webnn.d.ts +6 -5
- package/dist/backends/webnn.d.ts.map +1 -1
- package/dist/backends/webnn.js +6 -5
- package/dist/backends/webnn.js.map +1 -1
- package/dist/core/composer.d.ts +118 -0
- package/dist/core/composer.d.ts.map +1 -0
- package/dist/core/composer.js +163 -0
- package/dist/core/composer.js.map +1 -0
- package/dist/core/device-profiler.d.ts +75 -0
- package/dist/core/device-profiler.d.ts.map +1 -0
- package/dist/core/device-profiler.js +131 -0
- package/dist/core/device-profiler.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/memory.d.ts +22 -2
- package/dist/core/memory.d.ts.map +1 -1
- package/dist/core/memory.js +49 -13
- package/dist/core/memory.js.map +1 -1
- package/dist/core/plugin.d.ts +100 -0
- package/dist/core/plugin.d.ts.map +1 -0
- package/dist/core/plugin.js +106 -0
- package/dist/core/plugin.js.map +1 -0
- package/dist/core/runtime.d.ts +4 -0
- package/dist/core/runtime.d.ts.map +1 -1
- package/dist/core/runtime.js +18 -0
- package/dist/core/runtime.js.map +1 -1
- package/dist/core/scheduler.d.ts +17 -0
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +101 -3
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/types.d.ts +14 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker.d.ts +202 -0
- package/dist/core/worker.d.ts.map +1 -0
- package/dist/core/worker.js +477 -0
- package/dist/core/worker.js.map +1 -0
- package/dist/edgeflow.browser.js +9789 -4379
- package/dist/edgeflow.browser.js.map +4 -4
- package/dist/edgeflow.browser.min.js +435 -5
- package/dist/edgeflow.browser.min.js.map +4 -4
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -12
- package/dist/index.js.map +1 -1
- package/dist/pipelines/automatic-speech-recognition.d.ts +63 -0
- package/dist/pipelines/automatic-speech-recognition.d.ts.map +1 -0
- package/dist/pipelines/automatic-speech-recognition.js +269 -0
- package/dist/pipelines/automatic-speech-recognition.js.map +1 -0
- package/dist/pipelines/base.d.ts +6 -1
- package/dist/pipelines/base.d.ts.map +1 -1
- package/dist/pipelines/base.js +12 -2
- package/dist/pipelines/base.js.map +1 -1
- package/dist/pipelines/feature-extraction.d.ts +5 -40
- package/dist/pipelines/feature-extraction.d.ts.map +1 -1
- package/dist/pipelines/feature-extraction.js +44 -63
- package/dist/pipelines/feature-extraction.js.map +1 -1
- package/dist/pipelines/image-classification.d.ts +4 -36
- package/dist/pipelines/image-classification.d.ts.map +1 -1
- package/dist/pipelines/image-classification.js +22 -60
- package/dist/pipelines/image-classification.js.map +1 -1
- package/dist/pipelines/image-segmentation.d.ts +221 -0
- package/dist/pipelines/image-segmentation.d.ts.map +1 -0
- package/dist/pipelines/image-segmentation.js +535 -0
- package/dist/pipelines/image-segmentation.js.map +1 -0
- package/dist/pipelines/index.d.ts +18 -0
- package/dist/pipelines/index.d.ts.map +1 -1
- package/dist/pipelines/index.js +51 -2
- package/dist/pipelines/index.js.map +1 -1
- package/dist/pipelines/object-detection.d.ts +44 -0
- package/dist/pipelines/object-detection.d.ts.map +1 -0
- package/dist/pipelines/object-detection.js +218 -0
- package/dist/pipelines/object-detection.js.map +1 -0
- package/dist/pipelines/question-answering.d.ts +41 -0
- package/dist/pipelines/question-answering.d.ts.map +1 -0
- package/dist/pipelines/question-answering.js +164 -0
- package/dist/pipelines/question-answering.js.map +1 -0
- package/dist/pipelines/text-classification.d.ts +3 -39
- package/dist/pipelines/text-classification.d.ts.map +1 -1
- package/dist/pipelines/text-classification.js +29 -67
- package/dist/pipelines/text-classification.js.map +1 -1
- package/dist/pipelines/text-generation.d.ts +281 -0
- package/dist/pipelines/text-generation.d.ts.map +1 -0
- package/dist/pipelines/text-generation.js +766 -0
- package/dist/pipelines/text-generation.js.map +1 -0
- package/dist/pipelines/zero-shot-classification.d.ts +45 -0
- package/dist/pipelines/zero-shot-classification.d.ts.map +1 -0
- package/dist/pipelines/zero-shot-classification.js +140 -0
- package/dist/pipelines/zero-shot-classification.js.map +1 -0
- package/dist/tools/benchmark.d.ts +92 -0
- package/dist/tools/benchmark.d.ts.map +1 -0
- package/dist/tools/benchmark.js +213 -0
- package/dist/tools/benchmark.js.map +1 -0
- package/dist/tools/debugger.d.ts +258 -0
- package/dist/tools/debugger.d.ts.map +1 -0
- package/dist/tools/debugger.js +624 -0
- package/dist/tools/debugger.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +16 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/monitor.d.ts +284 -0
- package/dist/tools/monitor.d.ts.map +1 -0
- package/dist/tools/monitor.js +921 -0
- package/dist/tools/monitor.js.map +1 -0
- package/dist/tools/quantization.d.ts +235 -0
- package/dist/tools/quantization.d.ts.map +1 -0
- package/dist/tools/quantization.js +830 -0
- package/dist/tools/quantization.js.map +1 -0
- package/dist/utils/hub.d.ts +162 -0
- package/dist/utils/hub.d.ts.map +1 -0
- package/dist/utils/hub.js +311 -0
- package/dist/utils/hub.js.map +1 -0
- package/dist/utils/index.d.ts +3 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +5 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/model-loader.d.ts.map +1 -1
- package/dist/utils/model-loader.js +106 -30
- package/dist/utils/model-loader.js.map +1 -1
- package/dist/utils/offline.d.ts +147 -0
- package/dist/utils/offline.d.ts.map +1 -0
- package/dist/utils/offline.js +405 -0
- package/dist/utils/offline.js.map +1 -0
- package/dist/utils/preprocessor.d.ts +82 -6
- package/dist/utils/preprocessor.d.ts.map +1 -1
- package/dist/utils/preprocessor.js +278 -21
- package/dist/utils/preprocessor.js.map +1 -1
- package/dist/utils/tokenizer.d.ts +197 -72
- package/dist/utils/tokenizer.d.ts.map +1 -1
- package/dist/utils/tokenizer.js +558 -274
- package/dist/utils/tokenizer.js.map +1 -1
- package/package.json +26 -11
package/dist/backends/onnx.js
CHANGED
|
@@ -2,69 +2,78 @@
|
|
|
2
2
|
* edgeFlow.js - ONNX Runtime Backend
|
|
3
3
|
*
|
|
4
4
|
* Uses onnxruntime-web for real ONNX model inference.
|
|
5
|
-
*
|
|
5
|
+
* onnxruntime-web is an optional peer dependency loaded dynamically.
|
|
6
6
|
*/
|
|
7
7
|
import { EdgeFlowError, ErrorCodes, } from '../core/types.js';
|
|
8
8
|
import { LoadedModelImpl } from '../core/runtime.js';
|
|
9
9
|
import { EdgeFlowTensor } from '../core/tensor.js';
|
|
10
10
|
import { getMemoryManager } from '../core/memory.js';
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
const ONNX_CDN_BASE = `https://cdn.jsdelivr.net/npm/onnxruntime-web@${ONNX_VERSION}/dist/`;
|
|
14
|
-
const ONNX_SCRIPT_URL = `${ONNX_CDN_BASE}ort.min.js`;
|
|
15
|
-
// Global ONNX Runtime reference (loaded dynamically)
|
|
11
|
+
// Lazy-loaded onnxruntime-web module
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
13
|
let ort = null;
|
|
17
|
-
|
|
14
|
+
// A consumer-injected onnxruntime-web module. Bundlers like Vite don't
|
|
15
|
+
// always preserve the dynamic `import('onnxruntime-web/wasm')` below
|
|
16
|
+
// inside a Web Worker chunk; when that import is dropped the backend
|
|
17
|
+
// silently reports "no runtime available". Consumers that statically
|
|
18
|
+
// import ORT in their worker can inject it here so getOrt() never has to
|
|
19
|
+
// rely on the dynamic import.
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
let injectedOrt = null;
|
|
22
|
+
let onnxAssetPaths = null;
|
|
18
23
|
/**
|
|
19
|
-
*
|
|
24
|
+
* Inject a pre-imported onnxruntime-web module — the recommended
|
|
25
|
+
* integration path for Web Workers and custom bundler setups, where the
|
|
26
|
+
* internal dynamic `import('onnxruntime-web/wasm')` may be dropped.
|
|
27
|
+
*
|
|
28
|
+
* ONNX Runtime is an optional peer dependency that the consumer owns:
|
|
29
|
+
* once you inject a module, **you** own its configuration. Configure it
|
|
30
|
+
* first (`ort.env.wasm.wasmPaths`, `numThreads`, execution providers,
|
|
31
|
+
* ...) and the backend will use it as-is without overriding anything.
|
|
32
|
+
*
|
|
33
|
+
* import * as ort from "onnxruntime-web/wasm";
|
|
34
|
+
* ort.env.wasm.wasmPaths = { wasm: wasmUrl, mjs: mjsUrl };
|
|
35
|
+
* ort.env.wasm.numThreads = 1;
|
|
36
|
+
* setOnnxModule(ort);
|
|
20
37
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return ort;
|
|
25
|
-
// Return existing load promise to avoid duplicate loading
|
|
26
|
-
if (ortLoadPromise)
|
|
27
|
-
return ortLoadPromise;
|
|
28
|
-
ortLoadPromise = new Promise((resolve, reject) => {
|
|
29
|
-
// Check if already loaded globally (e.g., via script tag)
|
|
30
|
-
if (typeof window !== 'undefined' && window.ort) {
|
|
31
|
-
ort = window.ort;
|
|
32
|
-
// Configure WASM paths
|
|
33
|
-
ort.env.wasm.wasmPaths = ONNX_CDN_BASE;
|
|
34
|
-
resolve(ort);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
// Dynamically load the script
|
|
38
|
-
const script = document.createElement('script');
|
|
39
|
-
script.src = ONNX_SCRIPT_URL;
|
|
40
|
-
script.async = true;
|
|
41
|
-
script.onload = () => {
|
|
42
|
-
if (window.ort) {
|
|
43
|
-
ort = window.ort;
|
|
44
|
-
// Configure WASM paths
|
|
45
|
-
ort.env.wasm.wasmPaths = ONNX_CDN_BASE;
|
|
46
|
-
console.log(`✓ ONNX Runtime v${ONNX_VERSION} loaded from CDN`);
|
|
47
|
-
resolve(ort);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
reject(new Error('ONNX Runtime loaded but ort global not found'));
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
script.onerror = () => {
|
|
54
|
-
reject(new Error(`Failed to load ONNX Runtime from ${ONNX_SCRIPT_URL}`));
|
|
55
|
-
};
|
|
56
|
-
document.head.appendChild(script);
|
|
57
|
-
});
|
|
58
|
-
return ortLoadPromise;
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
|
+
export function setOnnxModule(module) {
|
|
40
|
+
injectedOrt = module;
|
|
59
41
|
}
|
|
60
42
|
/**
|
|
61
|
-
*
|
|
43
|
+
* Configure the onnxruntime-web WASM asset locations (sets
|
|
44
|
+
* `env.wasm.wasmPaths` during init). Primarily for the auto-load path —
|
|
45
|
+
* when you let the backend import ORT itself but your bundler content-
|
|
46
|
+
* hashes the `.wasm` / `.mjs` files (e.g. Vite `?url` imports), so the
|
|
47
|
+
* default `/ort/` prefix can't resolve them. If you inject your own
|
|
48
|
+
* module via {@link setOnnxModule}, prefer configuring it directly.
|
|
49
|
+
* An explicit call here is still honored even for an injected module.
|
|
62
50
|
*/
|
|
51
|
+
export function configureOnnxAssets(paths) {
|
|
52
|
+
onnxAssetPaths = paths;
|
|
53
|
+
}
|
|
63
54
|
async function getOrt() {
|
|
64
|
-
if (
|
|
65
|
-
|
|
55
|
+
if (injectedOrt)
|
|
56
|
+
return injectedOrt;
|
|
57
|
+
if (ort)
|
|
58
|
+
return ort;
|
|
59
|
+
try {
|
|
60
|
+
// Import the WASM-only sub-path so Vite rewrites the bare specifier
|
|
61
|
+
// to ort.wasm.bundle.min.mjs. This avoids loading the JSEP/WebGPU
|
|
62
|
+
// worker module (jsep.mjs) that ort.bundle.min.mjs eagerly fetches
|
|
63
|
+
// whenever navigator.gpu exists — which causes a 404 in dev servers
|
|
64
|
+
// that restrict ES module imports from /public.
|
|
65
|
+
ort = await import('onnxruntime-web/wasm');
|
|
66
|
+
return ort;
|
|
66
67
|
}
|
|
67
|
-
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Check whether onnxruntime-web is importable.
|
|
74
|
+
*/
|
|
75
|
+
export async function isOnnxAvailable() {
|
|
76
|
+
return (await getOrt()) != null;
|
|
68
77
|
}
|
|
69
78
|
const sessionStore = new Map();
|
|
70
79
|
// ============================================================================
|
|
@@ -72,7 +81,6 @@ const sessionStore = new Map();
|
|
|
72
81
|
// ============================================================================
|
|
73
82
|
/**
|
|
74
83
|
* ONNXRuntime - Real ONNX model inference using onnxruntime-web
|
|
75
|
-
* Automatically loads ONNX Runtime from CDN when first used.
|
|
76
84
|
*/
|
|
77
85
|
export class ONNXRuntime {
|
|
78
86
|
name = 'wasm'; // Register as wasm since it's the fallback
|
|
@@ -89,24 +97,58 @@ export class ONNXRuntime {
|
|
|
89
97
|
};
|
|
90
98
|
}
|
|
91
99
|
/**
|
|
92
|
-
* Check if ONNX Runtime is available (
|
|
100
|
+
* Check if ONNX Runtime is available (peer dependency installed)
|
|
93
101
|
*/
|
|
94
102
|
async isAvailable() {
|
|
95
|
-
|
|
96
|
-
return true;
|
|
103
|
+
return isOnnxAvailable();
|
|
97
104
|
}
|
|
98
105
|
/**
|
|
99
|
-
* Initialize the ONNX runtime
|
|
106
|
+
* Initialize the ONNX runtime
|
|
100
107
|
*/
|
|
101
108
|
async initialize() {
|
|
102
109
|
if (this.initialized)
|
|
103
110
|
return;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
const ortModule = await getOrt();
|
|
112
|
+
if (!ortModule) {
|
|
113
|
+
// Two distinct causes land here, and the fix differs — say both so
|
|
114
|
+
// a consumer who DID install ORT isn't sent chasing a phantom
|
|
115
|
+
// missing dependency:
|
|
116
|
+
// 1. onnxruntime-web genuinely isn't installed.
|
|
117
|
+
// 2. It's installed, but the internal dynamic import was dropped /
|
|
118
|
+
// not resolved by the bundler — common in Web Workers and some
|
|
119
|
+
// Vite setups. The fix there is to inject it, not reinstall.
|
|
120
|
+
throw new EdgeFlowError('onnxruntime-web could not be loaded.\n' +
|
|
121
|
+
' - If it is not installed: `npm install onnxruntime-web`.\n' +
|
|
122
|
+
' - If it IS installed (e.g. you see this inside a Web Worker, or ' +
|
|
123
|
+
'with a bundler that drops the internal dynamic import): import it ' +
|
|
124
|
+
'yourself and inject it before use — `import * as ort from ' +
|
|
125
|
+
'"onnxruntime-web/wasm"; setOnnxModule(ort);`', ErrorCodes.RUNTIME_NOT_AVAILABLE);
|
|
126
|
+
}
|
|
127
|
+
// onnxruntime-web is an optional peer dependency the CONSUMER owns.
|
|
128
|
+
// When they inject a module via setOnnxModule(), they're responsible
|
|
129
|
+
// for its configuration (wasmPaths, numThreads, execution providers),
|
|
130
|
+
// so we don't touch it — the library defers entirely. We only apply
|
|
131
|
+
// convenience defaults when WE auto-loaded ORT ourselves, and even
|
|
132
|
+
// then never clobber a value the consumer already set.
|
|
133
|
+
//
|
|
134
|
+
// An explicit configureOnnxAssets() call is honored regardless of how
|
|
135
|
+
// ORT was loaded — it's an explicit consumer request, not us guessing.
|
|
136
|
+
//
|
|
137
|
+
// Note this is intentionally NOT gated on `typeof window`: Web Workers
|
|
138
|
+
// have no `window`, and the old gate left ORT unconfigured (hence
|
|
139
|
+
// unusable) in exactly that context.
|
|
140
|
+
const wasmEnv = ortModule.env?.wasm;
|
|
141
|
+
if (wasmEnv) {
|
|
142
|
+
if (onnxAssetPaths) {
|
|
143
|
+
wasmEnv.wasmPaths = { ...onnxAssetPaths };
|
|
144
|
+
}
|
|
145
|
+
else if (!injectedOrt && wasmEnv.wasmPaths === undefined) {
|
|
146
|
+
wasmEnv.wasmPaths = '/ort/';
|
|
147
|
+
}
|
|
148
|
+
if (!injectedOrt && wasmEnv.numThreads === undefined) {
|
|
149
|
+
wasmEnv.numThreads = 1;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
110
152
|
this.initialized = true;
|
|
111
153
|
}
|
|
112
154
|
/**
|
|
@@ -116,16 +158,20 @@ export class ONNXRuntime {
|
|
|
116
158
|
if (!this.initialized) {
|
|
117
159
|
await this.initialize();
|
|
118
160
|
}
|
|
119
|
-
const ortInstance = await getOrt();
|
|
120
161
|
try {
|
|
121
|
-
|
|
162
|
+
const ortModule = await getOrt();
|
|
163
|
+
if (!ortModule) {
|
|
164
|
+
throw new Error('onnxruntime-web is not installed');
|
|
165
|
+
}
|
|
166
|
+
// WASM-only execution provider — WebGPU acceleration can be added
|
|
167
|
+
// later via the dedicated WebGPURuntime backend.
|
|
122
168
|
const sessionOptions = {
|
|
123
|
-
executionProviders: [
|
|
169
|
+
executionProviders: ['wasm'],
|
|
124
170
|
graphOptimizationLevel: 'all',
|
|
125
171
|
};
|
|
126
|
-
// Create inference session (convert ArrayBuffer to Uint8Array)
|
|
127
172
|
const modelBytes = new Uint8Array(modelData);
|
|
128
|
-
|
|
173
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
174
|
+
const session = await ortModule.InferenceSession.create(modelBytes, sessionOptions);
|
|
129
175
|
// Get input/output names
|
|
130
176
|
const inputNames = session.inputNames;
|
|
131
177
|
const outputNames = session.outputNames;
|
|
@@ -141,12 +187,12 @@ export class ONNXRuntime {
|
|
|
141
187
|
const metadata = {
|
|
142
188
|
name: options.metadata?.name ?? 'onnx-model',
|
|
143
189
|
version: '1.0.0',
|
|
144
|
-
inputs: inputNames.map(name => ({
|
|
190
|
+
inputs: inputNames.map((name) => ({
|
|
145
191
|
name,
|
|
146
192
|
dtype: 'float32',
|
|
147
193
|
shape: [-1], // Dynamic shape
|
|
148
194
|
})),
|
|
149
|
-
outputs: outputNames.map(name => ({
|
|
195
|
+
outputs: outputNames.map((name) => ({
|
|
150
196
|
name,
|
|
151
197
|
dtype: 'float32',
|
|
152
198
|
shape: [-1],
|
|
@@ -175,35 +221,31 @@ export class ONNXRuntime {
|
|
|
175
221
|
if (!sessionData) {
|
|
176
222
|
throw new EdgeFlowError(`ONNX session not found for model ${model.id}`, ErrorCodes.MODEL_NOT_LOADED, { modelId: model.id });
|
|
177
223
|
}
|
|
178
|
-
const ortInstance = await getOrt();
|
|
179
224
|
const { session, inputNames, outputNames } = sessionData;
|
|
180
225
|
try {
|
|
181
|
-
|
|
226
|
+
const ortModule = await getOrt();
|
|
182
227
|
const feeds = {};
|
|
183
228
|
for (let i = 0; i < Math.min(inputs.length, inputNames.length); i++) {
|
|
184
229
|
const inputName = inputNames[i];
|
|
185
230
|
const inputTensor = inputs[i];
|
|
186
231
|
if (inputName && inputTensor) {
|
|
187
|
-
// Convert to ONNX tensor with correct dtype
|
|
188
232
|
const dtype = inputTensor.dtype;
|
|
189
233
|
let ortTensor;
|
|
190
234
|
if (dtype === 'int64') {
|
|
191
|
-
// Get raw BigInt64Array data directly
|
|
192
235
|
const data = inputTensor.data;
|
|
193
|
-
ortTensor = new
|
|
236
|
+
ortTensor = new ortModule.Tensor('int64', data, inputTensor.shape);
|
|
194
237
|
}
|
|
195
238
|
else if (dtype === 'int32') {
|
|
196
239
|
const data = inputTensor.data;
|
|
197
|
-
ortTensor = new
|
|
240
|
+
ortTensor = new ortModule.Tensor('int32', data, inputTensor.shape);
|
|
198
241
|
}
|
|
199
242
|
else {
|
|
200
243
|
const data = inputTensor.toFloat32Array();
|
|
201
|
-
ortTensor = new
|
|
244
|
+
ortTensor = new ortModule.Tensor('float32', data, inputTensor.shape);
|
|
202
245
|
}
|
|
203
246
|
feeds[inputName] = ortTensor;
|
|
204
247
|
}
|
|
205
248
|
}
|
|
206
|
-
// Run inference
|
|
207
249
|
const results = await session.run(feeds);
|
|
208
250
|
// Convert outputs to EdgeFlowTensor
|
|
209
251
|
const outputs = [];
|
|
@@ -221,6 +263,53 @@ export class ONNXRuntime {
|
|
|
221
263
|
throw new EdgeFlowError(`ONNX inference failed: ${error instanceof Error ? error.message : String(error)}`, ErrorCodes.INFERENCE_FAILED, { modelId: model.id, error });
|
|
222
264
|
}
|
|
223
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* Run inference with named inputs
|
|
268
|
+
*/
|
|
269
|
+
async runNamed(model, namedInputs) {
|
|
270
|
+
const sessionData = sessionStore.get(model.id);
|
|
271
|
+
if (!sessionData) {
|
|
272
|
+
throw new EdgeFlowError(`ONNX session not found for model ${model.id}`, ErrorCodes.MODEL_NOT_LOADED, { modelId: model.id });
|
|
273
|
+
}
|
|
274
|
+
const { session, inputNames, outputNames } = sessionData;
|
|
275
|
+
try {
|
|
276
|
+
const ortModule = await getOrt();
|
|
277
|
+
const feeds = {};
|
|
278
|
+
for (const [inputName, inputTensor] of namedInputs) {
|
|
279
|
+
const tensor = inputTensor;
|
|
280
|
+
const dtype = tensor.dtype;
|
|
281
|
+
let ortTensor;
|
|
282
|
+
if (dtype === 'int64') {
|
|
283
|
+
const data = tensor.data;
|
|
284
|
+
ortTensor = new ortModule.Tensor('int64', data, tensor.shape);
|
|
285
|
+
}
|
|
286
|
+
else if (dtype === 'int32') {
|
|
287
|
+
const data = tensor.data;
|
|
288
|
+
ortTensor = new ortModule.Tensor('int32', data, tensor.shape);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
const data = tensor.toFloat32Array();
|
|
292
|
+
ortTensor = new ortModule.Tensor('float32', data, tensor.shape);
|
|
293
|
+
}
|
|
294
|
+
feeds[inputName] = ortTensor;
|
|
295
|
+
}
|
|
296
|
+
const results = await session.run(feeds);
|
|
297
|
+
// Convert outputs to EdgeFlowTensor
|
|
298
|
+
const outputs = [];
|
|
299
|
+
for (const outputName of outputNames) {
|
|
300
|
+
const ortTensor = results[outputName];
|
|
301
|
+
if (ortTensor) {
|
|
302
|
+
const data = ortTensor.data;
|
|
303
|
+
const shape = Array.from(ortTensor.dims).map(d => Number(d));
|
|
304
|
+
outputs.push(new EdgeFlowTensor(new Float32Array(data), shape, 'float32'));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return outputs;
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
throw new EdgeFlowError(`ONNX inference failed: ${error instanceof Error ? error.message : String(error)}`, ErrorCodes.INFERENCE_FAILED, { modelId: model.id, expectedInputs: inputNames, providedInputs: Array.from(namedInputs.keys()), error });
|
|
311
|
+
}
|
|
312
|
+
}
|
|
224
313
|
/**
|
|
225
314
|
* Unload a model
|
|
226
315
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onnx.js","sourceRoot":"","sources":["../../src/backends/onnx.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAQL,aAAa,EACb,UAAU,GAEX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,
|
|
1
|
+
{"version":3,"file":"onnx.js","sourceRoot":"","sources":["../../src/backends/onnx.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* edgeFlow.js - transformers.js Adapter Backend
|
|
3
|
+
*
|
|
4
|
+
* Wraps transformers.js (by Hugging Face) as an inference backend, giving
|
|
5
|
+
* users access to 1000+ HuggingFace models while adding edgeFlow.js's
|
|
6
|
+
* orchestration layer (scheduling, caching, memory management, workers).
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { useTransformersBackend } from 'edgeflowjs';
|
|
11
|
+
* import { pipeline as tfPipeline } from '@xenova/transformers';
|
|
12
|
+
*
|
|
13
|
+
* // Register the adapter
|
|
14
|
+
* useTransformersBackend();
|
|
15
|
+
*
|
|
16
|
+
* // Now use edgeFlow.js pipeline API — inference delegates to transformers.js
|
|
17
|
+
* const classifier = await pipeline('text-classification', {
|
|
18
|
+
* model: 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* // edgeFlow.js handles scheduling, batching, memory, caching
|
|
22
|
+
* const results = await classifier.runBatch(thousandsOfTexts);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
import { Runtime, RuntimeType, RuntimeCapabilities, LoadedModel, ModelLoadOptions, Tensor } from '../core/types.js';
|
|
26
|
+
/**
|
|
27
|
+
* Minimal interface for a transformers.js pipeline instance.
|
|
28
|
+
* We avoid importing @xenova/transformers directly so edgeFlow.js
|
|
29
|
+
* does not add it as a hard dependency.
|
|
30
|
+
*/
|
|
31
|
+
interface TransformersPipelineInstance {
|
|
32
|
+
(input: unknown, options?: unknown): Promise<unknown>;
|
|
33
|
+
dispose?: () => Promise<void> | void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A factory that creates a transformers.js pipeline.
|
|
37
|
+
* Users pass this so we don't hard-depend on the library.
|
|
38
|
+
*/
|
|
39
|
+
export type TransformersPipelineFactory = (task: string, model?: string, options?: Record<string, unknown>) => Promise<TransformersPipelineInstance>;
|
|
40
|
+
/**
|
|
41
|
+
* Options for configuring the transformers.js adapter.
|
|
42
|
+
*/
|
|
43
|
+
export interface TransformersAdapterOptions {
|
|
44
|
+
/** The pipeline factory from transformers.js (e.g. the `pipeline` function) */
|
|
45
|
+
pipelineFactory: TransformersPipelineFactory;
|
|
46
|
+
/** Default device ('webgpu' | 'wasm' | 'cpu') — passed to transformers.js */
|
|
47
|
+
device?: string;
|
|
48
|
+
/** Default dtype ('fp32' | 'fp16' | 'q8' | 'q4') */
|
|
49
|
+
dtype?: string;
|
|
50
|
+
/** Cache directory (browser IndexedDB path) */
|
|
51
|
+
cacheDir?: string;
|
|
52
|
+
}
|
|
53
|
+
export declare class TransformersAdapterRuntime implements Runtime {
|
|
54
|
+
readonly name: RuntimeType;
|
|
55
|
+
get capabilities(): RuntimeCapabilities;
|
|
56
|
+
isAvailable(): Promise<boolean>;
|
|
57
|
+
initialize(): Promise<void>;
|
|
58
|
+
loadModel(modelData: ArrayBuffer, options?: ModelLoadOptions): Promise<LoadedModel>;
|
|
59
|
+
/**
|
|
60
|
+
* Load a transformers.js pipeline by task + model name
|
|
61
|
+
* (called by the higher-level adapter pipeline, not via the
|
|
62
|
+
* standard loadModel path).
|
|
63
|
+
*/
|
|
64
|
+
loadPipeline(task: string, model: string, pipelineOptions?: Record<string, unknown>): Promise<string>;
|
|
65
|
+
/**
|
|
66
|
+
* Run inference by passing the raw input to the transformers.js pipeline.
|
|
67
|
+
* The result is returned as a single EdgeFlowTensor wrapping the JSON-encoded output
|
|
68
|
+
* (since transformers.js returns task-specific objects, not raw tensors).
|
|
69
|
+
*/
|
|
70
|
+
run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]>;
|
|
71
|
+
/**
|
|
72
|
+
* High-level: run the transformers.js pipeline directly with arbitrary input.
|
|
73
|
+
* Returns the raw result object (not a tensor).
|
|
74
|
+
*/
|
|
75
|
+
runDirect(modelId: string, input: unknown, options?: Record<string, unknown>): Promise<unknown>;
|
|
76
|
+
dispose(): void;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Register the transformers.js adapter as the default inference backend.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* import { pipeline } from '@xenova/transformers';
|
|
84
|
+
* import { useTransformersBackend } from 'edgeflowjs';
|
|
85
|
+
*
|
|
86
|
+
* useTransformersBackend({
|
|
87
|
+
* pipelineFactory: pipeline,
|
|
88
|
+
* device: 'webgpu',
|
|
89
|
+
* dtype: 'fp16',
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export declare function useTransformersBackend(options: TransformersAdapterOptions): void;
|
|
94
|
+
/**
|
|
95
|
+
* Get the adapter runtime instance (for advanced use).
|
|
96
|
+
*/
|
|
97
|
+
export declare function getTransformersAdapter(): TransformersAdapterRuntime | null;
|
|
98
|
+
export {};
|
|
99
|
+
//# sourceMappingURL=transformers-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformers-adapter.d.ts","sourceRoot":"","sources":["../../src/backends/transformers-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EACL,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAEhB,MAAM,EAGP,MAAM,kBAAkB,CAAC;AAU1B;;;;GAIG;AACH,UAAU,4BAA4B;IACpC,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,MAAM,2BAA2B,GAAG,CACxC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC9B,OAAO,CAAC,4BAA4B,CAAC,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,+EAA+E;IAC/E,eAAe,EAAE,2BAA2B,CAAC;IAC7C,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAkBD,qBAAa,0BAA2B,YAAW,OAAO;IACxD,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAU;IAEpC,IAAI,YAAY,IAAI,mBAAmB,CAStC;IAEK,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B,SAAS,CACb,SAAS,EAAE,WAAW,EACtB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,WAAW,CAAC;IA6BvB;;;;OAIG;IACG,YAAY,CAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACxC,OAAO,CAAC,MAAM,CAAC;IAmBlB;;;;OAIG;IACG,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAqBlE;;;OAGG;IACG,SAAS,CACb,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,OAAO,CAAC;IAWnB,OAAO,IAAI,IAAI;CAQhB;AAQD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI,CAIhF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,0BAA0B,GAAG,IAAI,CAE1E"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* edgeFlow.js - transformers.js Adapter Backend
|
|
3
|
+
*
|
|
4
|
+
* Wraps transformers.js (by Hugging Face) as an inference backend, giving
|
|
5
|
+
* users access to 1000+ HuggingFace models while adding edgeFlow.js's
|
|
6
|
+
* orchestration layer (scheduling, caching, memory management, workers).
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { useTransformersBackend } from 'edgeflowjs';
|
|
11
|
+
* import { pipeline as tfPipeline } from '@xenova/transformers';
|
|
12
|
+
*
|
|
13
|
+
* // Register the adapter
|
|
14
|
+
* useTransformersBackend();
|
|
15
|
+
*
|
|
16
|
+
* // Now use edgeFlow.js pipeline API — inference delegates to transformers.js
|
|
17
|
+
* const classifier = await pipeline('text-classification', {
|
|
18
|
+
* model: 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* // edgeFlow.js handles scheduling, batching, memory, caching
|
|
22
|
+
* const results = await classifier.runBatch(thousandsOfTexts);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
import { EdgeFlowError, ErrorCodes, } from '../core/types.js';
|
|
26
|
+
import { LoadedModelImpl } from '../core/runtime.js';
|
|
27
|
+
import { EdgeFlowTensor } from '../core/tensor.js';
|
|
28
|
+
import { getMemoryManager } from '../core/memory.js';
|
|
29
|
+
import { registerRuntime } from '../core/runtime.js';
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Session store: maps model IDs to transformers.js pipeline instances
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
const sessionStore = new Map();
|
|
34
|
+
let adapterOptions = null;
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Runtime implementation
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
export class TransformersAdapterRuntime {
|
|
39
|
+
name = 'wasm'; // registers under the wasm slot
|
|
40
|
+
get capabilities() {
|
|
41
|
+
return {
|
|
42
|
+
concurrency: true,
|
|
43
|
+
quantization: true,
|
|
44
|
+
float16: true,
|
|
45
|
+
dynamicShapes: true,
|
|
46
|
+
maxBatchSize: 128,
|
|
47
|
+
availableMemory: 1024 * 1024 * 1024,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async isAvailable() {
|
|
51
|
+
return adapterOptions?.pipelineFactory != null;
|
|
52
|
+
}
|
|
53
|
+
async initialize() {
|
|
54
|
+
if (!adapterOptions?.pipelineFactory) {
|
|
55
|
+
throw new EdgeFlowError('TransformersAdapterRuntime requires a pipelineFactory. ' +
|
|
56
|
+
'Call useTransformersBackend({ pipelineFactory }) first.', ErrorCodes.RUNTIME_INIT_FAILED);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async loadModel(modelData, options = {}) {
|
|
60
|
+
// modelData is unused — transformers.js downloads its own models.
|
|
61
|
+
// Instead the model identifier comes via metadata.name or the URL.
|
|
62
|
+
const modelName = options.metadata?.name ?? 'default';
|
|
63
|
+
const metadata = {
|
|
64
|
+
name: modelName,
|
|
65
|
+
version: '1.0.0',
|
|
66
|
+
inputs: [{ name: 'input', dtype: 'float32', shape: [-1] }],
|
|
67
|
+
outputs: [{ name: 'output', dtype: 'float32', shape: [-1] }],
|
|
68
|
+
sizeBytes: modelData.byteLength || 0,
|
|
69
|
+
quantization: options.quantization ?? 'float32',
|
|
70
|
+
format: 'onnx',
|
|
71
|
+
};
|
|
72
|
+
const modelId = `tjs_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
|
|
73
|
+
const model = new LoadedModelImpl(metadata, this.name, () => {
|
|
74
|
+
const session = sessionStore.get(modelId);
|
|
75
|
+
if (session?.instance.dispose) {
|
|
76
|
+
session.instance.dispose();
|
|
77
|
+
}
|
|
78
|
+
sessionStore.delete(modelId);
|
|
79
|
+
});
|
|
80
|
+
getMemoryManager().trackModel(model, () => model.dispose());
|
|
81
|
+
return model;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Load a transformers.js pipeline by task + model name
|
|
85
|
+
* (called by the higher-level adapter pipeline, not via the
|
|
86
|
+
* standard loadModel path).
|
|
87
|
+
*/
|
|
88
|
+
async loadPipeline(task, model, pipelineOptions) {
|
|
89
|
+
if (!adapterOptions?.pipelineFactory) {
|
|
90
|
+
throw new EdgeFlowError('Adapter not initialised', ErrorCodes.RUNTIME_NOT_INITIALIZED);
|
|
91
|
+
}
|
|
92
|
+
const opts = { ...pipelineOptions };
|
|
93
|
+
if (adapterOptions.device)
|
|
94
|
+
opts['device'] = adapterOptions.device;
|
|
95
|
+
if (adapterOptions.dtype)
|
|
96
|
+
opts['dtype'] = adapterOptions.dtype;
|
|
97
|
+
const instance = await adapterOptions.pipelineFactory(task, model, opts);
|
|
98
|
+
const modelId = `tjs_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
|
|
99
|
+
sessionStore.set(modelId, { instance, task, model });
|
|
100
|
+
return modelId;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Run inference by passing the raw input to the transformers.js pipeline.
|
|
104
|
+
* The result is returned as a single EdgeFlowTensor wrapping the JSON-encoded output
|
|
105
|
+
* (since transformers.js returns task-specific objects, not raw tensors).
|
|
106
|
+
*/
|
|
107
|
+
async run(model, inputs) {
|
|
108
|
+
const session = sessionStore.get(model.id);
|
|
109
|
+
if (!session) {
|
|
110
|
+
throw new EdgeFlowError(`No transformers.js session for model ${model.id}`, ErrorCodes.MODEL_NOT_LOADED);
|
|
111
|
+
}
|
|
112
|
+
// Reconstruct input from tensor (simple: use the float data as-is)
|
|
113
|
+
const inputData = inputs[0]?.toFloat32Array() ?? new Float32Array(0);
|
|
114
|
+
const result = await session.instance(inputData);
|
|
115
|
+
// Wrap the result in a tensor — downstream pipelines can interpret it
|
|
116
|
+
const resultArray = Array.isArray(result)
|
|
117
|
+
? new Float32Array(result.flat(Infinity))
|
|
118
|
+
: new Float32Array([0]);
|
|
119
|
+
return [new EdgeFlowTensor(resultArray, [resultArray.length], 'float32')];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* High-level: run the transformers.js pipeline directly with arbitrary input.
|
|
123
|
+
* Returns the raw result object (not a tensor).
|
|
124
|
+
*/
|
|
125
|
+
async runDirect(modelId, input, options) {
|
|
126
|
+
const session = sessionStore.get(modelId);
|
|
127
|
+
if (!session) {
|
|
128
|
+
throw new EdgeFlowError(`No transformers.js session for model ${modelId}`, ErrorCodes.MODEL_NOT_LOADED);
|
|
129
|
+
}
|
|
130
|
+
return session.instance(input, options);
|
|
131
|
+
}
|
|
132
|
+
dispose() {
|
|
133
|
+
for (const [id, session] of sessionStore) {
|
|
134
|
+
if (session.instance.dispose) {
|
|
135
|
+
session.instance.dispose();
|
|
136
|
+
}
|
|
137
|
+
sessionStore.delete(id);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
// Public API
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
let adapterRuntime = null;
|
|
145
|
+
/**
|
|
146
|
+
* Register the transformers.js adapter as the default inference backend.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* import { pipeline } from '@xenova/transformers';
|
|
151
|
+
* import { useTransformersBackend } from 'edgeflowjs';
|
|
152
|
+
*
|
|
153
|
+
* useTransformersBackend({
|
|
154
|
+
* pipelineFactory: pipeline,
|
|
155
|
+
* device: 'webgpu',
|
|
156
|
+
* dtype: 'fp16',
|
|
157
|
+
* });
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
export function useTransformersBackend(options) {
|
|
161
|
+
adapterOptions = options;
|
|
162
|
+
adapterRuntime = new TransformersAdapterRuntime();
|
|
163
|
+
registerRuntime('wasm', () => adapterRuntime);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get the adapter runtime instance (for advanced use).
|
|
167
|
+
*/
|
|
168
|
+
export function getTransformersAdapter() {
|
|
169
|
+
return adapterRuntime;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=transformers-adapter.js.map
|