vitallens 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rouast Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,241 @@
1
+ # vitallens.js
2
+
3
+ [![NPM Version](https://badge.fury.io/js/vitallens.js.svg)](https://www.npmjs.com/package/vitallens.js)
4
+ [![Website](https://img.shields.io/badge/Website-rouast.com/api-blue.svg?logo=data:image/svg%2bxml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+Cjxzdmcgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDI0IDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zOnNlcmlmPSJodHRwOi8vd3d3LnNlcmlmLmNvbS8iIHN0eWxlPSJmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MjsiPgogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4xODc5OTgsMCwwLDAuMTg3OTk4LDIzLjMyOTYsMTIuMjQ1MykiPgogICAgICAgIDxwYXRoIGQ9Ik0wLC0yLjgyOEMwLjMzOSwtMi41OTYgMC42NzQsLTIuMzk3IDEuMDA1LC0yLjIyNkwzLjU2NiwtMTUuODczQzAuMjY5LC0yMy42NTYgLTMuMTc1LC0zMS42MTUgLTkuNjU1LC0zMS42MTVDLTE2LjQ2MiwtMzEuNjE1IC0xNy41NDgsLTIzLjk0MiAtMTkuOTQ3LDAuMzEyQy0yMC40MjEsNS4wODEgLTIxLjAzOCwxMS4zMDggLTIxLjcxMSwxNi4wMzFDLTI0LjAxNiwxMS45NTQgLTI2LjY3NSw2LjU0OSAtMjguNDIsMy4wMDJDLTMzLjQ3OSwtNy4yNzggLTM0LjY2NSwtOS4zOTQgLTM2Ljg4OCwtMTAuNTM0Qy0zOS4wMzMsLTExLjYzOSAtNDAuOTk1LC0xMS41OTEgLTQyLjM3MSwtMTEuNDA4Qy00My4wMzcsLTEzIC00My45NDQsLTE1LjQzMSAtNDQuNjY4LC0xNy4zNjdDLTQ5LjUyOSwtMzAuMzkxIC01MS43NzIsLTM1LjQxMiAtNTYuMDY2LC0zNi40NTNDLTU3LjU2NiwtMzYuODE3IC01OS4xNDYsLTM2LjQ5MSAtNjAuMzk5LC0zNS41NjJDLTYzLjQyOCwtMzMuMzI0IC02NC4wMTYsLTI5LjYwMSAtNjUuNjUsLTIuMzcxQy02Ni4wMTcsMy43NDcgLTY2LjQ5NSwxMS43MTMgLTY3LjA1NiwxNy43NzZDLTY5LjE4MiwxNC4xMDggLTcxLjUyNiw5Ljc4MiAtNzMuMjY5LDYuNTcxQy04MS4wNTgsLTcuNzk0IC04Mi42ODcsLTEwLjQyMiAtODUuNzE5LC0xMS4zMUMtODcuNjQ2LC0xMS44NzcgLTg5LjIyMywtMTEuNjYgLTkwLjQyNSwtMTEuMjQ0Qy05MS4yOTYsLTEzLjM3NCAtOTIuNDM0LC0xNi45NzkgLTkzLjI1NSwtMTkuNTgzQy05Ni42LC0zMC4xODkgLTk4LjYyLC0zNi41ODggLTEwNC4xMzUsLTM2LjU4OEMtMTEwLjQ4NCwtMzYuNTg4IC0xMTAuODQzLC0zMC4zOTEgLTExMi4zNTUsLTQuMzExQy0xMTIuNzA3LDEuNzUgLTExMy4xNjksOS43NDIgLTExMy43NDEsMTUuNTUxQy0xMTYuMywxMS43ODEgLTExOS4yOSw2Ljk3OSAtMTIxLjQ1LDMuNDlMLTEyNC4wOTUsMTcuNTc2Qy0xMTcuNjA3LDI3LjU4NSAtMTE0Ljc2NiwzMC40NTggLTExMS4yMDQsMzAuNDU4Qy0xMDQuNjAzLDMwLjQ1OCAtMTA0LjIyMiwyMy44OTMgLTEwMi42MjEsLTMuNzQ3Qy0xMDIuNDIyLC03LjE3IC0xMDIuMTk3LC0xMS4wNDYgLTEwMS45NDYsLTE0LjcyOUMtOTkuNTUxLC03LjIxNiAtOTguMTkyLC0zLjY4NSAtOTUuNTQxLC0yLjA1Qy05Mi42OTgsLTAuMjk3IC05MC4zOTgsLTAuNTQ3IC04OC44MTMsLTEuMTU3Qy04Ny4wNCwxLjYyOSAtODQuMTExLDcuMDMgLTgxLjg0LDExLjIyQy03MS45NTUsMjkuNDQ2IC02OS4yMDIsMzMuNzM1IC02NC44NDYsMzMuOTc1Qy02NC42NjEsMzMuOTg1IC02NC40OCwzMy45ODkgLTY0LjMwNSwzMy45ODlDLTU4LjA2NCwzMy45ODkgLTU3LjY2MiwyNy4zMDQgLTU1LjkxNywtMS43ODdDLTU1LjYzMSwtNi41MyAtNTUuMywtMTIuMDcgLTU0LjkyNywtMTYuOTQ4Qy01NC41MTIsLTE1Ljg1MiAtNTQuMTI5LC0xNC44MjkgLTUzLjgwMywtMTMuOTU1Qy01MS4wNTYsLTYuNTk0IC01MC4xODcsLTQuNDExIC00OC40NzMsLTMuMDQyQy00NS44NywtMC45NjIgLTQzLjE0OSwtMS4zNjkgLTQxLjczNywtMS42MjhDLTQwLjYwMiwwLjMyOSAtMzguNjY0LDQuMjcxIC0zNy4xNjksNy4zMDZDLTI4LjgyNSwyNC4yNjQgLTI1LjE2OCwzMC42NzMgLTE5LjgxMiwzMC42NzNDLTEzLjE1NSwzMC42NzMgLTEyLjM2MiwyMi42NjYgLTEwLjI0NCwxLjI3MkMtOS42NjMsLTQuNjA2IC04Ljg4MiwtMTIuNDk2IC03Ljk5NiwtMTcuODMxQy02Ljk2MywtMTUuNzI5IC01Ljk1NCwtMTMuMzUgLTUuMzA3LC0xMS44MkMtMy4xNDUsLTYuNzIxIC0yLjAxNywtNC4yMDkgMCwtMi44MjgiIHN0eWxlPSJmaWxsOnJnYigwLDE2NCwyMjQpO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgPC9nPgo8L3N2Zz4K)](https://www.rouast.com/api/)
5
+ [![Documentation](https://img.shields.io/badge/Docs-docs.rouast.com-blue.svg?logo=data:image/svg%2bxml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+Cjxzdmcgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDI0IDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zOnNlcmlmPSJodHRwOi8vd3d3LnNlcmlmLmNvbS8iIHN0eWxlPSJmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MjsiPgogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4xODc5OTgsMCwwLDAuMTg3OTk4LDIzLjMyOTYsMTIuMjQ1MykiPgogICAgICAgIDxwYXRoIGQ9Ik0wLC0yLjgyOEMwLjMzOSwtMi41OTYgMC42NzQsLTIuMzk3IDEuMDA1LC0yLjIyNkwzLjU2NiwtMTUuODczQzAuMjY5LC0yMy42NTYgLTMuMTc1LC0zMS42MTUgLTkuNjU1LC0zMS42MTVDLTE2LjQ2MiwtMzEuNjE1IC0xNy41NDgsLTIzLjk0MiAtMTkuOTQ3LDAuMzEyQy0yMC40MjEsNS4wODEgLTIxLjAzOCwxMS4zMDggLTIxLjcxMSwxNi4wMzFDLTI0LjAxNiwxMS45NTQgLTI2LjY3NSw2LjU0OSAtMjguNDIsMy4wMDJDLTMzLjQ3OSwtNy4yNzggLTM0LjY2NSwtOS4zOTQgLTM2Ljg4OCwtMTAuNTM0Qy0zOS4wMzMsLTExLjYzOSAtNDAuOTk1LC0xMS41OTEgLTQyLjM3MSwtMTEuNDA4Qy00My4wMzcsLTEzIC00My45NDQsLTE1LjQzMSAtNDQuNjY4LC0xNy4zNjdDLTQ5LjUyOSwtMzAuMzkxIC01MS43NzIsLTM1LjQxMiAtNTYuMDY2LC0zNi40NTNDLTU3LjU2NiwtMzYuODE3IC01OS4xNDYsLTM2LjQ5MSAtNjAuMzk5LC0zNS41NjJDLTYzLjQyOCwtMzMuMzI0IC02NC4wMTYsLTI5LjYwMSAtNjUuNjUsLTIuMzcxQy02Ni4wMTcsMy43NDcgLTY2LjQ5NSwxMS43MTMgLTY3LjA1NiwxNy43NzZDLTY5LjE4MiwxNC4xMDggLTcxLjUyNiw5Ljc4MiAtNzMuMjY5LDYuNTcxQy04MS4wNTgsLTcuNzk0IC04Mi42ODcsLTEwLjQyMiAtODUuNzE5LC0xMS4zMUMtODcuNjQ2LC0xMS44NzcgLTg5LjIyMywtMTEuNjYgLTkwLjQyNSwtMTEuMjQ0Qy05MS4yOTYsLTEzLjM3NCAtOTIuNDM0LC0xNi45NzkgLTkzLjI1NSwtMTkuNTgzQy05Ni42LC0zMC4xODkgLTk4LjYyLC0zNi41ODggLTEwNC4xMzUsLTM2LjU4OEMtMTEwLjQ4NCwtMzYuNTg4IC0xMTAuODQzLC0zMC4zOTEgLTExMi4zNTUsLTQuMzExQy0xMTIuNzA3LDEuNzUgLTExMy4xNjksOS43NDIgLTExMy43NDEsMTUuNTUxQy0xMTYuMywxMS43ODEgLTExOS4yOSw2Ljk3OSAtMTIxLjQ1LDMuNDlMLTEyNC4wOTUsMTcuNTc2Qy0xMTcuNjA3LDI3LjU4NSAtMTE0Ljc2NiwzMC40NTggLTExMS4yMDQsMzAuNDU4Qy0xMDQuNjAzLDMwLjQ1OCAtMTA0LjIyMiwyMy44OTMgLTEwMi42MjEsLTMuNzQ3Qy0xMDIuNDIyLC03LjE3IC0xMDIuMTk3LC0xMS4wNDYgLTEwMS45NDYsLTE0LjcyOUMtOTkuNTUxLC03LjIxNiAtOTguMTkyLC0zLjY4NSAtOTUuNTQxLC0yLjA1Qy05Mi42OTgsLTAuMjk3IC05MC4zOTgsLTAuNTQ3IC04OC44MTMsLTEuMTU3Qy04Ny4wNCwxLjYyOSAtODQuMTExLDcuMDMgLTgxLjg0LDExLjIyQy03MS45NTUsMjkuNDQ2IC02OS4yMDIsMzMuNzM1IC02NC44NDYsMzMuOTc1Qy02NC42NjEsMzMuOTg1IC02NC40OCwzMy45ODkgLTY0LjMwNSwzMy45ODlDLTU4LjA2NCwzMy45ODkgLTU3LjY2MiwyNy4zMDQgLTU1LjkxNywtMS43ODdDLTU1LjYzMSwtNi41MyAtNTUuMywtMTIuMDcgLTU0LjkyNywtMTYuOTQ4Qy01NC41MTIsLTE1Ljg1MiAtNTQuMTI5LC0xNC44MjkgLTUzLjgwMywtMTMuOTU1Qy01MS4wNTYsLTYuNTk0IC01MC4xODcsLTQuNDExIC00OC40NzMsLTMuMDQyQy00NS44NywtMC45NjIgLTQzLjE0OSwtMS4zNjkgLTQxLjczNywtMS42MjhDLTQwLjYwMiwwLjMyOSAtMzguNjY0LDQuMjcxIC0zNy4xNjksNy4zMDZDLTI4LjgyNSwyNC4yNjQgLTI1LjE2OCwzMC42NzMgLTE5LjgxMiwzMC42NzNDLTEzLjE1NSwzMC42NzMgLTEyLjM2MiwyMi42NjYgLTEwLjI0NCwxLjI3MkMtOS42NjMsLTQuNjA2IC04Ljg4MiwtMTIuNDk2IC03Ljk5NiwtMTcuODMxQy02Ljk2MywtMTUuNzI5IC01Ljk1NCwtMTMuMzUgLTUuMzA3LC0xMS44MkMtMy4xNDUsLTYuNzIxIC0yLjAxNywtNC4yMDkgMCwtMi44MjgiIHN0eWxlPSJmaWxsOnJnYigwLDE2NCwyMjQpO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgPC9nPgo8L3N2Zz4K)](https://docs.rouast.com/)
6
+ [![DOI](http://img.shields.io/:DOI-10.48550/arXiv.2312.06892-blue.svg?style=flat&logo=arxiv)](https://doi.org/10.48550/arXiv.2312.06892)
7
+
8
+ Estimate vital signs such as heart rate and respiratory rate from video in JavaScript.
9
+
10
+ `vitallens.js` is a JavaScript client for the [**VitalLens API**](https://www.rouast.com/api/), which leverages the same inference engine as our [free iOS app VitalLens](https://apps.apple.com/us/app/vitallens/id6472757649).
11
+ Furthermore, it includes fast implementations of several other heart rate estimation methods from video such as `G`, `CHROM`, and `POS`.
12
+
13
+ This library works both in browser environments and in Node.js, and comes with a set of examples for file-based processing and real-time webcam streaming.
14
+
15
+ Using a different language or platform? We also have a [Python client](https://github.com/Rouast-Labs/vitallens-python).
16
+
17
+ ## Features
18
+
19
+ - **Cross-Platform Compatibility:**
20
+ Use vitallens.js in the browser or Node.js.
21
+
22
+ - **Flexible Input Support:**
23
+ Process video files or live streams from a webcam or any MediaStream.
24
+
25
+ - **Multiple Estimation Methods:**
26
+ Choose the method that fits your needs:
27
+ - **`vitallens`** provides *heart rate*, *respiratory rate*, *pulse waveform*, and *respiratory waveform* estimation. In addition, it returns an estimation confidence for each vital. We are working to support more vital signs in the future.
28
+ - **`g`**, **`chrom`**, **`pos`** provides support faster, but less accurate *heart rate* and *pulse waveform* estimation.
29
+ - While `vitallens` requires an API Key, `g`, `chrom`, and `pos` do not. [Register on our website to get a free API Key.](https://www.rouast.com/api/)
30
+
31
+ - **Fast Face Detection & ROI Support:**
32
+ Perform rapid face detection when required—or optionally, pass a global region of interest (ROI) to skip detection for even faster processing.
33
+
34
+ - **Event-Driven API:**
35
+ Register event listeners to receive real-time updates on estimated vitals.
36
+
37
+ - **TypeScript-Ready:**
38
+ Written in TypeScript with complete type definitions for enhanced developer experience.
39
+
40
+ ### Disclaimer
41
+
42
+ **Important:** vitallens.js provides vital sign estimates for general wellness purposes only. It is **not intended for medical use**. Always consult a healthcare professional for any medical concerns or precise clinical measurements.
43
+
44
+ Please review our [Terms of Service](https://www.rouast.com/api/terms) and [Privacy Policy](https://www.rouast.com/privacy) for more details.
45
+
46
+ ## Installation
47
+
48
+ Install vitallens.js via npm:
49
+
50
+ ```bash
51
+ npm install vitallens
52
+ ```
53
+
54
+ Or using yarn:
55
+
56
+ ```bash
57
+ yarn add vitallens
58
+ ```
59
+
60
+ ## Usage
61
+
62
+ ### Importing the Library
63
+
64
+ #### In Browser (ES Modules)
65
+
66
+ Include vitallens.js in your HTML as follows:
67
+
68
+ ```html
69
+ <script type="module">
70
+ import { VitalLens } from 'vitallens.browser.js';
71
+ // Your code here
72
+ </script>
73
+ ```
74
+
75
+ #### In Node.js (ESM)
76
+
77
+ ```js
78
+ import { VitalLens } from 'vitallens.esm.js';
79
+ // Your code here
80
+ ```
81
+
82
+ ### Processing a Video File (Node.js Example)
83
+
84
+ ```js
85
+ import { VitalLens } from 'vitallens.esm.js';
86
+
87
+ const options = {
88
+ method: 'vitallens', // Choose from 'vitallens', 'g', 'chrom', or 'pos'
89
+ apiKey: 'YOUR_API_KEY', // Required when using the 'vitallens' method
90
+ };
91
+
92
+ const vitallens = new VitalLens(options);
93
+
94
+ async function processVideoFile(filePath) {
95
+ try {
96
+ const result = await vitallens.processFile(filePath);
97
+ console.log('Processing complete!', result);
98
+ } catch (error) {
99
+ console.error('Error processing video:', error);
100
+ }
101
+ }
102
+
103
+ processVideoFile('./examples/sample_video_1.mp4');
104
+ ```
105
+
106
+ ### Real-Time Vital Estimation (Browser Example)
107
+
108
+ Below is a minimal example that uses a webcam stream:
109
+
110
+ ```html
111
+ <!DOCTYPE html>
112
+ <html lang="en">
113
+ <head>
114
+ <meta charset="UTF-8">
115
+ <title>vitallens.js Webcam Example</title>
116
+ </head>
117
+ <body>
118
+ <video id="video" autoplay muted playsinline style="width:100%; max-width:600px;"></video>
119
+ <script type="module">
120
+ import { VitalLens } from 'vitallens.browser.js';
121
+
122
+ const options = {
123
+ method: 'vitallens', // 'vitallens' requires an API key
124
+ apiKey: 'YOUR_API_KEY',
125
+ };
126
+
127
+ const vitallens = new VitalLens(options);
128
+
129
+ async function startVitals() {
130
+ try {
131
+ const video = document.getElementById('video');
132
+ const stream = await navigator.mediaDevices.getUserMedia({
133
+ video: { facingMode: 'user' },
134
+ audio: false
135
+ });
136
+ video.srcObject = stream;
137
+
138
+ // Add the stream to vitallens.js
139
+ await vitallens.addStream(stream, video);
140
+
141
+ // Listen for vitals events
142
+ vitallens.addEventListener('vitals', (data) => {
143
+ console.log('Detected vitals:', data);
144
+ });
145
+
146
+ // Start processing
147
+ vitallens.start();
148
+ } catch (error) {
149
+ console.error('Error initializing webcam:', error);
150
+ }
151
+ }
152
+
153
+ startVitals();
154
+ </script>
155
+ </body>
156
+ </html>
157
+ ```
158
+
159
+ ### Configuration Options
160
+
161
+ When creating a new `VitalLens` instance, you can configure various options:
162
+
163
+ | Parameter | Description | Default |
164
+ | ------------- | ------------------------------------------------------------------------------------------------ | ------------- |
165
+ | `method` | Inference method: `'vitallens'`, `'G'`, `'CHROM'`, or `'POS'`. | `'vitallens'` |
166
+ | `apiKey` | API key for the VitalLens API (required for method `'vitallens'`). | `null` |
167
+ | `globalRoi` | Optional region of interest for face detection (object with `{ x0, y0, x1, y1 }`). | `undefined` |
168
+ | *Others* | Additional options (e.g., face detection settings, buffering) are available. See [docs](https://docs.rouast.com/) for details. | |
169
+
170
+ ## Examples
171
+
172
+ The repository contains several ready-to-run examples:
173
+
174
+ - **Browser File Input:**
175
+ [examples/browser/file.html](examples/browser/file.html)
176
+ To run this example, execute:
177
+ ```bash
178
+ npm run start:browser-file
179
+ ```
180
+
181
+ - **Minimal Webcam Example:**
182
+ [examples/browser/webcam_minimal.html](examples/browser/webcam_minimal.html)
183
+ To run this example, execute:
184
+ ```bash
185
+ npm run start:browser-webcam-minimal
186
+ ```
187
+
188
+ - **Advanced Webcam with Visualizations:**
189
+ [examples/browser/webcam.html](examples/browser/webcam.html)
190
+ To run this example, execute:
191
+ ```bash
192
+ npm run start:browser-webcam
193
+ ```
194
+
195
+ - **Node File Processing:**
196
+ [examples/node/file.js](examples/node/file.js)
197
+ To run this example, execute:
198
+ ```bash
199
+ npm run start:node-file
200
+ ```
201
+
202
+ Try opening the HTML examples in your browser or running the Node script to see vitallens.js in action.
203
+
204
+ ## Development
205
+
206
+ ### Building the Library
207
+
208
+ To build the project from source, run:
209
+
210
+ ```bash
211
+ npm run build
212
+ ```
213
+
214
+ This compiles the TypeScript source and bundles the output for Node (both ESM and CommonJS), and the browser.
215
+
216
+ ### Running Tests
217
+
218
+ Execute the test suite with:
219
+
220
+ ```bash
221
+ npm run test
222
+ ```
223
+
224
+ For environment-specific tests, you can use:
225
+
226
+ ```bash
227
+ npm run test:browser
228
+ npm run test:node
229
+ ```
230
+
231
+ ### Linting
232
+
233
+ Lint the code using:
234
+
235
+ ```bash
236
+ npm run lint
237
+ ```
238
+
239
+ ## License
240
+
241
+ This project is licensed under the [MIT License](LICENSE).
@@ -0,0 +1,4 @@
1
+ export { VitalLens } from './core/VitalLens.browser';
2
+ export type { VitalLensOptions, VitalLensResult } from './types/core';
3
+ export { Frame } from './processing/Frame';
4
+ //# sourceMappingURL=index.browser.d.ts.map
@@ -0,0 +1,5 @@
1
+ import './utils/suppressTfLogs';
2
+ export { VitalLens } from './core/VitalLens.node';
3
+ export type { VitalLensOptions, VitalLensResult } from './types/core';
4
+ export { Frame } from './processing/Frame';
5
+ //# sourceMappingURL=index.node.d.ts.map