@vizor-vr/shared 0.1.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/LICENSE +21 -0
- package/README.md +21 -0
- package/dist/__tests__/defaults.test.d.ts +2 -0
- package/dist/__tests__/defaults.test.d.ts.map +1 -0
- package/dist/__tests__/defaults.test.js +78 -0
- package/dist/__tests__/defaults.test.js.map +1 -0
- package/dist/__tests__/events.test.d.ts +2 -0
- package/dist/__tests__/events.test.d.ts.map +1 -0
- package/dist/__tests__/events.test.js +56 -0
- package/dist/__tests__/events.test.js.map +1 -0
- package/dist/__tests__/formats.test.d.ts +2 -0
- package/dist/__tests__/formats.test.d.ts.map +1 -0
- package/dist/__tests__/formats.test.js +75 -0
- package/dist/__tests__/formats.test.js.map +1 -0
- package/dist/__tests__/keybindings.test.d.ts +2 -0
- package/dist/__tests__/keybindings.test.d.ts.map +1 -0
- package/dist/__tests__/keybindings.test.js +59 -0
- package/dist/__tests__/keybindings.test.js.map +1 -0
- package/dist/__tests__/license.test.d.ts +2 -0
- package/dist/__tests__/license.test.d.ts.map +1 -0
- package/dist/__tests__/license.test.js +57 -0
- package/dist/__tests__/license.test.js.map +1 -0
- package/dist/__tests__/math.test.d.ts +2 -0
- package/dist/__tests__/math.test.d.ts.map +1 -0
- package/dist/__tests__/math.test.js +131 -0
- package/dist/__tests__/math.test.js.map +1 -0
- package/dist/__tests__/media.test.d.ts +2 -0
- package/dist/__tests__/media.test.d.ts.map +1 -0
- package/dist/__tests__/media.test.js +32 -0
- package/dist/__tests__/media.test.js.map +1 -0
- package/dist/constants/defaults.d.ts +31 -0
- package/dist/constants/defaults.d.ts.map +1 -0
- package/dist/constants/defaults.js +55 -0
- package/dist/constants/defaults.js.map +1 -0
- package/dist/constants/events.d.ts +5 -0
- package/dist/constants/events.d.ts.map +1 -0
- package/dist/constants/events.js +45 -0
- package/dist/constants/events.js.map +1 -0
- package/dist/constants/formats.d.ts +9 -0
- package/dist/constants/formats.d.ts.map +1 -0
- package/dist/constants/formats.js +206 -0
- package/dist/constants/formats.js.map +1 -0
- package/dist/constants/index.d.ts +7 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +7 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants/keybindings.d.ts +10 -0
- package/dist/constants/keybindings.d.ts.map +1 -0
- package/dist/constants/keybindings.js +26 -0
- package/dist/constants/keybindings.js.map +1 -0
- package/dist/constants/license.d.ts +8 -0
- package/dist/constants/license.d.ts.map +1 -0
- package/dist/constants/license.js +111 -0
- package/dist/constants/license.js.map +1 -0
- package/dist/constants/media.d.ts +23 -0
- package/dist/constants/media.d.ts.map +1 -0
- package/dist/constants/media.js +20 -0
- package/dist/constants/media.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/types/analytics.d.ts +30 -0
- package/dist/types/analytics.d.ts.map +1 -0
- package/dist/types/analytics.js +2 -0
- package/dist/types/analytics.js.map +1 -0
- package/dist/types/annotations.d.ts +22 -0
- package/dist/types/annotations.d.ts.map +1 -0
- package/dist/types/annotations.js +2 -0
- package/dist/types/annotations.js.map +1 -0
- package/dist/types/collaborative.d.ts +77 -0
- package/dist/types/collaborative.d.ts.map +1 -0
- package/dist/types/collaborative.js +2 -0
- package/dist/types/collaborative.js.map +1 -0
- package/dist/types/events.d.ts +60 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +2 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/formats.d.ts +41 -0
- package/dist/types/formats.d.ts.map +1 -0
- package/dist/types/formats.js +33 -0
- package/dist/types/formats.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/license.d.ts +39 -0
- package/dist/types/license.d.ts.map +1 -0
- package/dist/types/license.js +2 -0
- package/dist/types/license.js.map +1 -0
- package/dist/types/player.d.ts +107 -0
- package/dist/types/player.d.ts.map +1 -0
- package/dist/types/player.js +2 -0
- package/dist/types/player.js.map +1 -0
- package/dist/types/tour.d.ts +21 -0
- package/dist/types/tour.d.ts.map +1 -0
- package/dist/types/tour.js +2 -0
- package/dist/types/tour.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/math.d.ts +28 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +46 -0
- package/dist/utils/math.js.map +1 -0
- package/package.json +42 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 UTG Networks
|
|
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,21 @@
|
|
|
1
|
+
# @vizor-vr/shared
|
|
2
|
+
|
|
3
|
+
Shared types, constants, and utilities used across the Vizor VR packages and platform — projection-format definitions, license tiers and feature flags, Zod validation schemas, and small VR math/utility helpers.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @vizor-vr/shared
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { VZ_FORMATS, type LicenseTier, TIER_FEATURES } from '@vizor-vr/shared';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This package is primarily an internal dependency of the Vizor packages; it is published so the framework wrappers and player share a single source of truth for types and constants.
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
MIT — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/defaults.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { DEFAULT_CONFIG, SPHERE_DEFAULTS, CAMERA_DEFAULTS, CONTROLS_HIDE_TIMEOUT, ANALYTICS_BATCH_INTERVAL, GAZE_SAMPLE_INTERVAL, GAZE_BATCH_INTERVAL, } from '../constants/defaults.js';
|
|
3
|
+
import { VzFormat } from '../types/formats.js';
|
|
4
|
+
describe('default constants', () => {
|
|
5
|
+
describe('DEFAULT_CONFIG', () => {
|
|
6
|
+
it('has MONO_360 as default format', () => {
|
|
7
|
+
expect(DEFAULT_CONFIG.format).toBe(VzFormat.MONO_360);
|
|
8
|
+
});
|
|
9
|
+
it('starts with playback defaults', () => {
|
|
10
|
+
expect(DEFAULT_CONFIG.loop).toBe(false);
|
|
11
|
+
expect(DEFAULT_CONFIG.muted).toBe(false);
|
|
12
|
+
expect(DEFAULT_CONFIG.preload).toBe('metadata');
|
|
13
|
+
expect(DEFAULT_CONFIG.fps).toBe(30);
|
|
14
|
+
});
|
|
15
|
+
it('starts at center of sphere', () => {
|
|
16
|
+
expect(DEFAULT_CONFIG.startLat).toBe(0);
|
|
17
|
+
expect(DEFAULT_CONFIG.startLon).toBe(0);
|
|
18
|
+
});
|
|
19
|
+
it('has sensible FOV range', () => {
|
|
20
|
+
expect(DEFAULT_CONFIG.focalLength).toBe(75);
|
|
21
|
+
expect(DEFAULT_CONFIG.minFocalLength).toBe(30);
|
|
22
|
+
expect(DEFAULT_CONFIG.maxFocalLength).toBe(120);
|
|
23
|
+
expect(DEFAULT_CONFIG.minFocalLength).toBeLessThan(DEFAULT_CONFIG.focalLength);
|
|
24
|
+
expect(DEFAULT_CONFIG.maxFocalLength).toBeGreaterThan(DEFAULT_CONFIG.focalLength);
|
|
25
|
+
});
|
|
26
|
+
it('starts in inline display mode', () => {
|
|
27
|
+
expect(DEFAULT_CONFIG.displayMode).toBe('inline');
|
|
28
|
+
});
|
|
29
|
+
it('has all UI visibility flags set to false (visible)', () => {
|
|
30
|
+
expect(DEFAULT_CONFIG.hideCompass).toBe(false);
|
|
31
|
+
expect(DEFAULT_CONFIG.hideVrButton).toBe(false);
|
|
32
|
+
expect(DEFAULT_CONFIG.hideSettings).toBe(false);
|
|
33
|
+
expect(DEFAULT_CONFIG.hideFullscreen).toBe(false);
|
|
34
|
+
expect(DEFAULT_CONFIG.hideControls).toBe(false);
|
|
35
|
+
expect(DEFAULT_CONFIG.hideTitle).toBe(false);
|
|
36
|
+
expect(DEFAULT_CONFIG.hideBrandLogo).toBe(false);
|
|
37
|
+
expect(DEFAULT_CONFIG.hideWatermark).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe('SPHERE_DEFAULTS', () => {
|
|
41
|
+
it('has expected geometry params', () => {
|
|
42
|
+
expect(SPHERE_DEFAULTS.radius).toBe(500);
|
|
43
|
+
expect(SPHERE_DEFAULTS.widthSegments).toBe(64);
|
|
44
|
+
expect(SPHERE_DEFAULTS.heightSegments).toBe(32);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe('CAMERA_DEFAULTS', () => {
|
|
48
|
+
it('has 75 degree FOV', () => {
|
|
49
|
+
expect(CAMERA_DEFAULTS.fov).toBe(75);
|
|
50
|
+
});
|
|
51
|
+
it('has near/far clipping planes', () => {
|
|
52
|
+
expect(CAMERA_DEFAULTS.near).toBe(0.1);
|
|
53
|
+
expect(CAMERA_DEFAULTS.far).toBe(1000);
|
|
54
|
+
});
|
|
55
|
+
it('has input sensitivity values', () => {
|
|
56
|
+
expect(CAMERA_DEFAULTS.dampingFactor).toBeGreaterThan(0);
|
|
57
|
+
expect(CAMERA_DEFAULTS.dragSensitivity).toBeGreaterThan(0);
|
|
58
|
+
expect(CAMERA_DEFAULTS.touchSensitivity).toBeGreaterThan(0);
|
|
59
|
+
expect(CAMERA_DEFAULTS.keyboardPanSpeed).toBeGreaterThan(0);
|
|
60
|
+
expect(CAMERA_DEFAULTS.zoomSpeed).toBeGreaterThan(0);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe('timing constants', () => {
|
|
64
|
+
it('controls hide after 3 seconds', () => {
|
|
65
|
+
expect(CONTROLS_HIDE_TIMEOUT).toBe(3000);
|
|
66
|
+
});
|
|
67
|
+
it('analytics batch interval is 10 seconds', () => {
|
|
68
|
+
expect(ANALYTICS_BATCH_INTERVAL).toBe(10000);
|
|
69
|
+
});
|
|
70
|
+
it('gaze samples at ~3Hz', () => {
|
|
71
|
+
expect(GAZE_SAMPLE_INTERVAL).toBe(333);
|
|
72
|
+
});
|
|
73
|
+
it('gaze batch interval is 5 seconds', () => {
|
|
74
|
+
expect(GAZE_BATCH_INTERVAL).toBe(5000);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=defaults.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.test.js","sourceRoot":"","sources":["../../src/__tests__/defaults.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/events.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { MEDIA_EVENTS, CUSTOM_EVENTS } from '../constants/events.js';
|
|
3
|
+
describe('event constants', () => {
|
|
4
|
+
describe('MEDIA_EVENTS', () => {
|
|
5
|
+
it('contains standard HTML5 media events', () => {
|
|
6
|
+
expect(MEDIA_EVENTS).toContain('play');
|
|
7
|
+
expect(MEDIA_EVENTS).toContain('pause');
|
|
8
|
+
expect(MEDIA_EVENTS).toContain('ended');
|
|
9
|
+
expect(MEDIA_EVENTS).toContain('timeupdate');
|
|
10
|
+
expect(MEDIA_EVENTS).toContain('volumechange');
|
|
11
|
+
expect(MEDIA_EVENTS).toContain('loadeddata');
|
|
12
|
+
expect(MEDIA_EVENTS).toContain('canplay');
|
|
13
|
+
expect(MEDIA_EVENTS).toContain('waiting');
|
|
14
|
+
});
|
|
15
|
+
it('has 23 media events', () => {
|
|
16
|
+
expect(MEDIA_EVENTS).toHaveLength(23);
|
|
17
|
+
});
|
|
18
|
+
it('does not contain Vizor custom events', () => {
|
|
19
|
+
for (const event of MEDIA_EVENTS) {
|
|
20
|
+
expect(event).not.toMatch(/^vz-/);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('CUSTOM_EVENTS', () => {
|
|
25
|
+
it('all events have vz- prefix', () => {
|
|
26
|
+
for (const event of CUSTOM_EVENTS) {
|
|
27
|
+
expect(event).toMatch(/^vz-/);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
it('contains core lifecycle events', () => {
|
|
31
|
+
expect(CUSTOM_EVENTS).toContain('vz-ready');
|
|
32
|
+
expect(CUSTOM_EVENTS).toContain('vz-error');
|
|
33
|
+
});
|
|
34
|
+
it('contains XR events', () => {
|
|
35
|
+
expect(CUSTOM_EVENTS).toContain('vz-xr-enter');
|
|
36
|
+
expect(CUSTOM_EVENTS).toContain('vz-xr-exit');
|
|
37
|
+
});
|
|
38
|
+
it('contains loading events', () => {
|
|
39
|
+
expect(CUSTOM_EVENTS).toContain('vz-loading-start');
|
|
40
|
+
expect(CUSTOM_EVENTS).toContain('vz-loading-progress');
|
|
41
|
+
expect(CUSTOM_EVENTS).toContain('vz-loading-complete');
|
|
42
|
+
});
|
|
43
|
+
it('contains fullscreen events', () => {
|
|
44
|
+
expect(CUSTOM_EVENTS).toContain('vz-fullscreen-enter');
|
|
45
|
+
expect(CUSTOM_EVENTS).toContain('vz-fullscreen-exit');
|
|
46
|
+
});
|
|
47
|
+
it('contains tour event', () => {
|
|
48
|
+
expect(CUSTOM_EVENTS).toContain('vz-tour-navigate');
|
|
49
|
+
});
|
|
50
|
+
it('has no duplicate entries', () => {
|
|
51
|
+
const unique = new Set(CUSTOM_EVENTS);
|
|
52
|
+
expect(unique.size).toBe(CUSTOM_EVENTS.length);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=events.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.test.js","sourceRoot":"","sources":["../../src/__tests__/events.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/formats.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { VzFormat, parseFormat, getFormatMeta, FORMAT_REGISTRY } from '../index.js';
|
|
3
|
+
describe('formats', () => {
|
|
4
|
+
describe('VzFormat enum', () => {
|
|
5
|
+
it('has 19 format values', () => {
|
|
6
|
+
const values = Object.values(VzFormat);
|
|
7
|
+
expect(values.length).toBe(19);
|
|
8
|
+
});
|
|
9
|
+
it('enum keys match values (string enum)', () => {
|
|
10
|
+
for (const [key, value] of Object.entries(VzFormat)) {
|
|
11
|
+
expect(key).toBe(value);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
describe('parseFormat', () => {
|
|
16
|
+
it('parses valid format strings', () => {
|
|
17
|
+
expect(parseFormat('MONO_360')).toBe(VzFormat.MONO_360);
|
|
18
|
+
expect(parseFormat('STEREO_360_LR')).toBe(VzFormat.STEREO_360_LR);
|
|
19
|
+
});
|
|
20
|
+
it('returns undefined for invalid format', () => {
|
|
21
|
+
expect(parseFormat('INVALID')).toBeUndefined();
|
|
22
|
+
expect(parseFormat('')).toBeUndefined();
|
|
23
|
+
});
|
|
24
|
+
it('is case-sensitive', () => {
|
|
25
|
+
expect(parseFormat('mono_360')).toBeUndefined();
|
|
26
|
+
expect(parseFormat('Mono_360')).toBeUndefined();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe('FORMAT_REGISTRY', () => {
|
|
30
|
+
it('has metadata for every VzFormat value', () => {
|
|
31
|
+
for (const format of Object.values(VzFormat)) {
|
|
32
|
+
expect(FORMAT_REGISTRY).toHaveProperty(format);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
it('MONO_360 is not flat and is mono', () => {
|
|
36
|
+
const meta = FORMAT_REGISTRY[VzFormat.MONO_360];
|
|
37
|
+
expect(meta.isFlat).toBe(false);
|
|
38
|
+
expect(meta.stereoMode).toBe('mono');
|
|
39
|
+
});
|
|
40
|
+
it('STEREO_360_LR is not flat and is stereo', () => {
|
|
41
|
+
const meta = FORMAT_REGISTRY[VzFormat.STEREO_360_LR];
|
|
42
|
+
expect(meta.isFlat).toBe(false);
|
|
43
|
+
expect(meta.stereoMode).not.toBe('mono');
|
|
44
|
+
});
|
|
45
|
+
it('MONO_FLAT is flat and mono', () => {
|
|
46
|
+
const meta = FORMAT_REGISTRY[VzFormat.MONO_FLAT];
|
|
47
|
+
expect(meta.isFlat).toBe(true);
|
|
48
|
+
expect(meta.stereoMode).toBe('mono');
|
|
49
|
+
});
|
|
50
|
+
it('all entries have required properties', () => {
|
|
51
|
+
for (const meta of Object.values(FORMAT_REGISTRY)) {
|
|
52
|
+
expect(meta).toHaveProperty('format');
|
|
53
|
+
expect(meta).toHaveProperty('projection');
|
|
54
|
+
expect(meta).toHaveProperty('stereoMode');
|
|
55
|
+
expect(meta).toHaveProperty('fovH');
|
|
56
|
+
expect(meta).toHaveProperty('fovV');
|
|
57
|
+
expect(meta).toHaveProperty('supportsVideo');
|
|
58
|
+
expect(meta).toHaveProperty('supportsImage');
|
|
59
|
+
expect(meta).toHaveProperty('isFlat');
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe('getFormatMeta', () => {
|
|
64
|
+
it('returns metadata for a valid format', () => {
|
|
65
|
+
const meta = getFormatMeta(VzFormat.MONO_360);
|
|
66
|
+
expect(meta).toBeDefined();
|
|
67
|
+
expect(meta.isFlat).toBe(false);
|
|
68
|
+
});
|
|
69
|
+
it('returns undefined for invalid format string', () => {
|
|
70
|
+
const meta = getFormatMeta('INVALID_FORMAT');
|
|
71
|
+
expect(meta).toBeUndefined();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=formats.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.test.js","sourceRoot":"","sources":["../../src/__tests__/formats.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keybindings.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/keybindings.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { DEFAULT_KEYBINDINGS, SEEK_STEP, SEEK_STEP_LARGE, VOLUME_STEP, PLAYBACK_RATE_STEP, } from '../constants/keybindings.js';
|
|
3
|
+
describe('keybinding constants', () => {
|
|
4
|
+
describe('DEFAULT_KEYBINDINGS', () => {
|
|
5
|
+
it('maps Space to togglePlay', () => {
|
|
6
|
+
expect(DEFAULT_KEYBINDINGS['Space']).toBe('togglePlay');
|
|
7
|
+
});
|
|
8
|
+
it('maps K to togglePlay (YouTube-like)', () => {
|
|
9
|
+
expect(DEFAULT_KEYBINDINGS['KeyK']).toBe('togglePlay');
|
|
10
|
+
});
|
|
11
|
+
it('maps M to toggleMute', () => {
|
|
12
|
+
expect(DEFAULT_KEYBINDINGS['KeyM']).toBe('toggleMute');
|
|
13
|
+
});
|
|
14
|
+
it('maps F to toggleFullscreen', () => {
|
|
15
|
+
expect(DEFAULT_KEYBINDINGS['KeyF']).toBe('toggleFullscreen');
|
|
16
|
+
});
|
|
17
|
+
it('maps V to toggleVR', () => {
|
|
18
|
+
expect(DEFAULT_KEYBINDINGS['KeyV']).toBe('toggleVR');
|
|
19
|
+
});
|
|
20
|
+
it('maps arrow keys to seek/volume', () => {
|
|
21
|
+
expect(DEFAULT_KEYBINDINGS['ArrowLeft']).toBe('seekBackward');
|
|
22
|
+
expect(DEFAULT_KEYBINDINGS['ArrowRight']).toBe('seekForward');
|
|
23
|
+
expect(DEFAULT_KEYBINDINGS['ArrowUp']).toBe('volumeUp');
|
|
24
|
+
expect(DEFAULT_KEYBINDINGS['ArrowDown']).toBe('volumeDown');
|
|
25
|
+
});
|
|
26
|
+
it('maps Escape to exitFullscreen', () => {
|
|
27
|
+
expect(DEFAULT_KEYBINDINGS['Escape']).toBe('exitFullscreen');
|
|
28
|
+
});
|
|
29
|
+
it('maps Home/End to seek start/end', () => {
|
|
30
|
+
expect(DEFAULT_KEYBINDINGS['Home']).toBe('seekStart');
|
|
31
|
+
expect(DEFAULT_KEYBINDINGS['End']).toBe('seekEnd');
|
|
32
|
+
});
|
|
33
|
+
it('maps Comma/Period to playback rate', () => {
|
|
34
|
+
expect(DEFAULT_KEYBINDINGS['Comma']).toBe('decreasePlaybackRate');
|
|
35
|
+
expect(DEFAULT_KEYBINDINGS['Period']).toBe('increasePlaybackRate');
|
|
36
|
+
});
|
|
37
|
+
it('maps C to toggleCaptions', () => {
|
|
38
|
+
expect(DEFAULT_KEYBINDINGS['KeyC']).toBe('toggleCaptions');
|
|
39
|
+
});
|
|
40
|
+
it('has 15 keybindings', () => {
|
|
41
|
+
expect(Object.keys(DEFAULT_KEYBINDINGS)).toHaveLength(15);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('step constants', () => {
|
|
45
|
+
it('seek step is 5 seconds', () => {
|
|
46
|
+
expect(SEEK_STEP).toBe(5);
|
|
47
|
+
});
|
|
48
|
+
it('large seek step is 10 seconds', () => {
|
|
49
|
+
expect(SEEK_STEP_LARGE).toBe(10);
|
|
50
|
+
});
|
|
51
|
+
it('volume step is 0.05', () => {
|
|
52
|
+
expect(VOLUME_STEP).toBe(0.05);
|
|
53
|
+
});
|
|
54
|
+
it('playback rate step is 0.25', () => {
|
|
55
|
+
expect(PLAYBACK_RATE_STEP).toBe(0.25);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=keybindings.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keybindings.test.js","sourceRoot":"","sources":["../../src/__tests__/keybindings.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/license.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { getFeaturesForTier, TIER_FEATURES } from '../constants/license.js';
|
|
3
|
+
describe('license constants', () => {
|
|
4
|
+
describe('TIER_FEATURES', () => {
|
|
5
|
+
it('defines all four tiers', () => {
|
|
6
|
+
expect(TIER_FEATURES).toHaveProperty('free');
|
|
7
|
+
expect(TIER_FEATURES).toHaveProperty('starter');
|
|
8
|
+
expect(TIER_FEATURES).toHaveProperty('pro');
|
|
9
|
+
expect(TIER_FEATURES).toHaveProperty('enterprise');
|
|
10
|
+
});
|
|
11
|
+
it('all tiers have the same set of feature keys', () => {
|
|
12
|
+
const tiers = Object.keys(TIER_FEATURES);
|
|
13
|
+
const freeKeys = Object.keys(TIER_FEATURES.free).sort();
|
|
14
|
+
for (const tier of tiers) {
|
|
15
|
+
const keys = Object.keys(TIER_FEATURES[tier]).sort();
|
|
16
|
+
expect(keys).toEqual(freeKeys);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
it('all feature values are booleans', () => {
|
|
20
|
+
for (const tier of Object.values(TIER_FEATURES)) {
|
|
21
|
+
for (const value of Object.values(tier)) {
|
|
22
|
+
expect(typeof value).toBe('boolean');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
it('tiers are progressively more permissive', () => {
|
|
27
|
+
const countEnabled = (features) => Object.values(features).filter(Boolean).length;
|
|
28
|
+
expect(countEnabled(TIER_FEATURES.free)).toBeLessThan(countEnabled(TIER_FEATURES.starter));
|
|
29
|
+
expect(countEnabled(TIER_FEATURES.starter)).toBeLessThan(countEnabled(TIER_FEATURES.pro));
|
|
30
|
+
expect(countEnabled(TIER_FEATURES.pro)).toBeLessThan(countEnabled(TIER_FEATURES.enterprise));
|
|
31
|
+
});
|
|
32
|
+
it('enterprise has all features enabled', () => {
|
|
33
|
+
for (const [key, value] of Object.entries(TIER_FEATURES.enterprise)) {
|
|
34
|
+
expect(value).toBe(true);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
it('free tier has watermark (removeWatermark = false)', () => {
|
|
38
|
+
expect(TIER_FEATURES.free.removeWatermark).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
it('starter tier removes watermark', () => {
|
|
41
|
+
expect(TIER_FEATURES.starter.removeWatermark).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('getFeaturesForTier', () => {
|
|
45
|
+
it('returns correct features for each tier', () => {
|
|
46
|
+
expect(getFeaturesForTier('free')).toEqual(TIER_FEATURES.free);
|
|
47
|
+
expect(getFeaturesForTier('starter')).toEqual(TIER_FEATURES.starter);
|
|
48
|
+
expect(getFeaturesForTier('pro')).toEqual(TIER_FEATURES.pro);
|
|
49
|
+
expect(getFeaturesForTier('enterprise')).toEqual(TIER_FEATURES.enterprise);
|
|
50
|
+
});
|
|
51
|
+
it('returns a reference to the TIER_FEATURES entry', () => {
|
|
52
|
+
// Should be same object reference (not a copy)
|
|
53
|
+
expect(getFeaturesForTier('free')).toBe(TIER_FEATURES.free);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=license.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.test.js","sourceRoot":"","sources":["../../src/__tests__/license.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"math.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/math.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { degToRad, radToDeg, clamp, lerp, latLonToSpherical, sphericalToLatLon, normalizeAngle, } from '../utils/math.js';
|
|
3
|
+
describe('math utilities', () => {
|
|
4
|
+
describe('degToRad', () => {
|
|
5
|
+
it('converts 0 degrees to 0 radians', () => {
|
|
6
|
+
expect(degToRad(0)).toBe(0);
|
|
7
|
+
});
|
|
8
|
+
it('converts 180 degrees to PI', () => {
|
|
9
|
+
expect(degToRad(180)).toBeCloseTo(Math.PI);
|
|
10
|
+
});
|
|
11
|
+
it('converts 90 degrees to PI/2', () => {
|
|
12
|
+
expect(degToRad(90)).toBeCloseTo(Math.PI / 2);
|
|
13
|
+
});
|
|
14
|
+
it('converts 360 degrees to 2*PI', () => {
|
|
15
|
+
expect(degToRad(360)).toBeCloseTo(2 * Math.PI);
|
|
16
|
+
});
|
|
17
|
+
it('handles negative degrees', () => {
|
|
18
|
+
expect(degToRad(-90)).toBeCloseTo(-Math.PI / 2);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
describe('radToDeg', () => {
|
|
22
|
+
it('converts 0 radians to 0 degrees', () => {
|
|
23
|
+
expect(radToDeg(0)).toBe(0);
|
|
24
|
+
});
|
|
25
|
+
it('converts PI to 180 degrees', () => {
|
|
26
|
+
expect(radToDeg(Math.PI)).toBeCloseTo(180);
|
|
27
|
+
});
|
|
28
|
+
it('converts PI/2 to 90 degrees', () => {
|
|
29
|
+
expect(radToDeg(Math.PI / 2)).toBeCloseTo(90);
|
|
30
|
+
});
|
|
31
|
+
it('is inverse of degToRad', () => {
|
|
32
|
+
expect(radToDeg(degToRad(45))).toBeCloseTo(45);
|
|
33
|
+
expect(radToDeg(degToRad(270))).toBeCloseTo(270);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
describe('clamp', () => {
|
|
37
|
+
it('clamps value below min', () => {
|
|
38
|
+
expect(clamp(-5, 0, 100)).toBe(0);
|
|
39
|
+
});
|
|
40
|
+
it('clamps value above max', () => {
|
|
41
|
+
expect(clamp(150, 0, 100)).toBe(100);
|
|
42
|
+
});
|
|
43
|
+
it('returns value when within range', () => {
|
|
44
|
+
expect(clamp(50, 0, 100)).toBe(50);
|
|
45
|
+
});
|
|
46
|
+
it('returns min when value equals min', () => {
|
|
47
|
+
expect(clamp(0, 0, 100)).toBe(0);
|
|
48
|
+
});
|
|
49
|
+
it('returns max when value equals max', () => {
|
|
50
|
+
expect(clamp(100, 0, 100)).toBe(100);
|
|
51
|
+
});
|
|
52
|
+
it('handles negative ranges', () => {
|
|
53
|
+
expect(clamp(-5, -10, -1)).toBe(-5);
|
|
54
|
+
expect(clamp(-15, -10, -1)).toBe(-10);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe('lerp', () => {
|
|
58
|
+
it('returns a when t=0', () => {
|
|
59
|
+
expect(lerp(10, 20, 0)).toBe(10);
|
|
60
|
+
});
|
|
61
|
+
it('returns b when t=1', () => {
|
|
62
|
+
expect(lerp(10, 20, 1)).toBe(20);
|
|
63
|
+
});
|
|
64
|
+
it('returns midpoint when t=0.5', () => {
|
|
65
|
+
expect(lerp(0, 100, 0.5)).toBe(50);
|
|
66
|
+
});
|
|
67
|
+
it('interpolates correctly at t=0.25', () => {
|
|
68
|
+
expect(lerp(0, 100, 0.25)).toBe(25);
|
|
69
|
+
});
|
|
70
|
+
it('handles negative values', () => {
|
|
71
|
+
expect(lerp(-10, 10, 0.5)).toBe(0);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('latLonToSpherical', () => {
|
|
75
|
+
it('converts equator center to PI/2 phi and 0 theta', () => {
|
|
76
|
+
const result = latLonToSpherical(0, 0);
|
|
77
|
+
expect(result.phi).toBeCloseTo(Math.PI / 2);
|
|
78
|
+
expect(result.theta).toBeCloseTo(0);
|
|
79
|
+
});
|
|
80
|
+
it('converts north pole (lat=90) to phi=0', () => {
|
|
81
|
+
const result = latLonToSpherical(90, 0);
|
|
82
|
+
expect(result.phi).toBeCloseTo(0);
|
|
83
|
+
});
|
|
84
|
+
it('converts south pole (lat=-90) to phi=PI', () => {
|
|
85
|
+
const result = latLonToSpherical(-90, 0);
|
|
86
|
+
expect(result.phi).toBeCloseTo(Math.PI);
|
|
87
|
+
});
|
|
88
|
+
it('converts lon=180 to theta=PI', () => {
|
|
89
|
+
const result = latLonToSpherical(0, 180);
|
|
90
|
+
expect(result.theta).toBeCloseTo(Math.PI);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe('sphericalToLatLon', () => {
|
|
94
|
+
it('is inverse of latLonToSpherical', () => {
|
|
95
|
+
const { phi, theta } = latLonToSpherical(45, -30);
|
|
96
|
+
const { lat, lon } = sphericalToLatLon(phi, theta);
|
|
97
|
+
expect(lat).toBeCloseTo(45);
|
|
98
|
+
expect(lon).toBeCloseTo(-30);
|
|
99
|
+
});
|
|
100
|
+
it('converts phi=0 to lat=90 (north pole)', () => {
|
|
101
|
+
const result = sphericalToLatLon(0, 0);
|
|
102
|
+
expect(result.lat).toBeCloseTo(90);
|
|
103
|
+
});
|
|
104
|
+
it('converts phi=PI to lat=-90 (south pole)', () => {
|
|
105
|
+
const result = sphericalToLatLon(Math.PI, 0);
|
|
106
|
+
expect(result.lat).toBeCloseTo(-90);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe('normalizeAngle', () => {
|
|
110
|
+
it('returns angle in range as-is', () => {
|
|
111
|
+
expect(normalizeAngle(45)).toBe(45);
|
|
112
|
+
expect(normalizeAngle(-90)).toBe(-90);
|
|
113
|
+
expect(normalizeAngle(0)).toBe(0);
|
|
114
|
+
});
|
|
115
|
+
it('wraps angle above 180', () => {
|
|
116
|
+
expect(normalizeAngle(270)).toBe(-90);
|
|
117
|
+
expect(normalizeAngle(360)).toBe(0);
|
|
118
|
+
expect(normalizeAngle(181)).toBe(-179);
|
|
119
|
+
});
|
|
120
|
+
it('wraps angle below -180', () => {
|
|
121
|
+
expect(normalizeAngle(-270)).toBe(90);
|
|
122
|
+
expect(normalizeAngle(-360)).toBe(0);
|
|
123
|
+
expect(normalizeAngle(-181)).toBe(179);
|
|
124
|
+
});
|
|
125
|
+
it('wraps large angles', () => {
|
|
126
|
+
expect(normalizeAngle(720)).toBe(0);
|
|
127
|
+
expect(normalizeAngle(-720)).toBe(0);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
//# sourceMappingURL=math.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"math.test.js","sourceRoot":"","sources":["../../src/__tests__/math.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/media.test.ts"],"names":[],"mappings":""}
|