@rixl/media-core 1.0.2 → 1.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/README.md +74 -84
- package/dist/chunks/B-QvSqjj.js +1 -0
- package/dist/chunks/B2DDE32u.js +1 -0
- package/dist/chunks/BZFoe94X.js +1 -0
- package/dist/chunks/DMkwQjgA.js +1 -0
- package/dist/index.d.ts +2005 -82
- package/dist/index.js +6 -73
- package/package.json +13 -6
- package/dist/api/analytics.d.ts +0 -16
- package/dist/api/analytics.js +0 -227
- package/dist/api/feed.js +0 -52
- package/dist/api/heatmap.d.ts +0 -6
- package/dist/api/heatmap.js +0 -28
- package/dist/api/hot-segments.d.ts +0 -7
- package/dist/api/hot-segments.js +0 -20
- package/dist/api/image.js +0 -11
- package/dist/api/rixl-client.d.ts +0 -3
- package/dist/api/rixl-client.js +0 -14
- package/dist/api/upload.d.ts +0 -76
- package/dist/api/upload.js +0 -150
- package/dist/api/video.js +0 -11
- package/dist/lib/analytics-builders.d.ts +0 -59
- package/dist/lib/analytics-builders.js +0 -88
- package/dist/lib/analytics-initialize.d.ts +0 -1
- package/dist/lib/analytics-initialize.js +0 -59
- package/dist/lib/analytics-utils.d.ts +0 -43
- package/dist/lib/analytics-utils.js +0 -85
- package/dist/lib/analytics-wire.js +0 -153
- package/dist/lib/buffer-progress.d.ts +0 -20
- package/dist/lib/buffer-progress.js +0 -37
- package/dist/lib/caption-styles.d.ts +0 -20
- package/dist/lib/caption-styles.js +0 -56
- package/dist/lib/caption-utils.d.ts +0 -80
- package/dist/lib/caption-utils.js +0 -111
- package/dist/lib/chapter-utils.d.ts +0 -102
- package/dist/lib/chapter-utils.js +0 -147
- package/dist/lib/click-disambiguation.d.ts +0 -44
- package/dist/lib/click-disambiguation.js +0 -80
- package/dist/lib/click-outside.d.ts +0 -68
- package/dist/lib/click-outside.js +0 -64
- package/dist/lib/colors.d.ts +0 -6
- package/dist/lib/colors.js +0 -16
- package/dist/lib/content-analytics.d.ts +0 -27
- package/dist/lib/content-analytics.js +0 -38
- package/dist/lib/environment-effects.d.ts +0 -89
- package/dist/lib/environment-effects.js +0 -139
- package/dist/lib/feed-autoscroll.d.ts +0 -10
- package/dist/lib/feed-autoscroll.js +0 -13
- package/dist/lib/feed-container-height.d.ts +0 -7
- package/dist/lib/feed-container-height.js +0 -11
- package/dist/lib/feed-description-overflow.d.ts +0 -1
- package/dist/lib/feed-description-overflow.js +0 -9
- package/dist/lib/feed-dwell.d.ts +0 -2
- package/dist/lib/feed-dwell.js +0 -8
- package/dist/lib/feed-loop.d.ts +0 -10
- package/dist/lib/feed-loop.js +0 -21
- package/dist/lib/feed-scroll.d.ts +0 -11
- package/dist/lib/feed-scroll.js +0 -19
- package/dist/lib/feed-transforms.d.ts +0 -5
- package/dist/lib/feed-transforms.js +0 -30
- package/dist/lib/filter-undefined.js +0 -11
- package/dist/lib/fullscreen-utils.d.ts +0 -1
- package/dist/lib/fullscreen-utils.js +0 -7
- package/dist/lib/hls-buffer-flush.js +0 -46
- package/dist/lib/hls-error-recovery.d.ts +0 -35
- package/dist/lib/hls-error-recovery.js +0 -75
- package/dist/lib/hls-event-handlers.js +0 -61
- package/dist/lib/hls-loader.js +0 -23
- package/dist/lib/hls-setup.d.ts +0 -72
- package/dist/lib/hls-setup.js +0 -144
- package/dist/lib/hls-utils.d.ts +0 -31
- package/dist/lib/hls-utils.js +0 -34
- package/dist/lib/image-render.d.ts +0 -29
- package/dist/lib/image-render.js +0 -63
- package/dist/lib/keyboard-config.d.ts +0 -66
- package/dist/lib/keyboard-config.js +0 -127
- package/dist/lib/keyboard-utils.d.ts +0 -4
- package/dist/lib/keyboard-utils.js +0 -11
- package/dist/lib/lifecycle-effects.d.ts +0 -67
- package/dist/lib/lifecycle-effects.js +0 -78
- package/dist/lib/loading-debounce.d.ts +0 -26
- package/dist/lib/loading-debounce.js +0 -38
- package/dist/lib/numbers.d.ts +0 -6
- package/dist/lib/numbers.js +0 -36
- package/dist/lib/pip-utils.d.ts +0 -16
- package/dist/lib/pip-utils.js +0 -32
- package/dist/lib/playback-handlers.d.ts +0 -33
- package/dist/lib/playback-handlers.js +0 -51
- package/dist/lib/playback-slider.d.ts +0 -23
- package/dist/lib/playback-slider.js +0 -24
- package/dist/lib/player-labels.d.ts +0 -23
- package/dist/lib/player-labels.js +0 -132
- package/dist/lib/player-menu-labels.d.ts +0 -80
- package/dist/lib/player-menu-labels.js +0 -829
- package/dist/lib/player-ui-actions.d.ts +0 -10
- package/dist/lib/player-ui-actions.js +0 -58
- package/dist/lib/progress-fraction.d.ts +0 -11
- package/dist/lib/progress-fraction.js +0 -20
- package/dist/lib/progress-persist.d.ts +0 -28
- package/dist/lib/progress-persist.js +0 -54
- package/dist/lib/segment-analytics.d.ts +0 -20
- package/dist/lib/segment-analytics.js +0 -29
- package/dist/lib/subtitle-logic.d.ts +0 -31
- package/dist/lib/subtitle-logic.js +0 -75
- package/dist/lib/subtitle-utils.d.ts +0 -16
- package/dist/lib/subtitle-utils.js +0 -37
- package/dist/lib/time.d.ts +0 -1
- package/dist/lib/time.js +0 -17
- package/dist/lib/track-persistence.d.ts +0 -4
- package/dist/lib/track-persistence.js +0 -35
- package/dist/lib/video-preload-config.d.ts +0 -34
- package/dist/lib/video-preload-config.js +0 -41
- package/dist/lib/video-spinner.d.ts +0 -25
- package/dist/lib/video-spinner.js +0 -35
- package/dist/lib/video-stats.d.ts +0 -28
- package/dist/lib/video-stats.js +0 -44
- package/dist/lib/volume-utils.d.ts +0 -59
- package/dist/lib/volume-utils.js +0 -55
- package/dist/progressbar.d.ts +0 -10
- package/dist/progressbar.js +0 -125
- package/dist/store/analytics-context-store.d.ts +0 -4
- package/dist/store/analytics-context-store.js +0 -13
- package/dist/store/analytics-device-store.d.ts +0 -8
- package/dist/store/analytics-device-store.js +0 -44
- package/dist/store/analytics-session-store.d.ts +0 -8
- package/dist/store/analytics-session-store.js +0 -40
- package/dist/store/analytics-store.d.ts +0 -30
- package/dist/store/analytics-store.js +0 -88
- package/dist/store/controls-store.d.ts +0 -16
- package/dist/store/controls-store.js +0 -53
- package/dist/store/feed-cache-store.d.ts +0 -24
- package/dist/store/feed-cache-store.js +0 -165
- package/dist/store/feed-interaction-store.d.ts +0 -17
- package/dist/store/feed-interaction-store.js +0 -32
- package/dist/store/feed-store.d.ts +0 -16
- package/dist/store/feed-store.js +0 -38
- package/dist/store/generic-store.js +0 -24
- package/dist/store/image-store.d.ts +0 -2
- package/dist/store/image-store.js +0 -8
- package/dist/store/player-container-element-store.d.ts +0 -10
- package/dist/store/player-container-element-store.js +0 -38
- package/dist/store/player-global-actions.js +0 -53
- package/dist/store/player-media-element-store.d.ts +0 -10
- package/dist/store/player-media-element-store.js +0 -38
- package/dist/store/player-store-actions.js +0 -197
- package/dist/store/player-store.d.ts +0 -94
- package/dist/store/player-store.js +0 -127
- package/dist/store/player-track-actions.js +0 -44
- package/dist/store/postStore.d.ts +0 -20
- package/dist/store/postStore.js +0 -112
- package/dist/store/settings/constants.d.ts +0 -15
- package/dist/store/settings/constants.js +0 -47
- package/dist/store/settings/defaults.d.ts +0 -2
- package/dist/store/settings/defaults.js +0 -24
- package/dist/store/settings/storage.d.ts +0 -3
- package/dist/store/settings/storage.js +0 -28
- package/dist/store/settings/store.d.ts +0 -32
- package/dist/store/settings/store.js +0 -59
- package/dist/store/settings/types.d.ts +0 -27
- package/dist/store/settings/validation.d.ts +0 -7
- package/dist/store/settings/validation.js +0 -55
- package/dist/store/settings-menu-store.d.ts +0 -19
- package/dist/store/settings-menu-store.js +0 -30
- package/dist/store/video-store.d.ts +0 -2
- package/dist/store/video-store.js +0 -8
- package/dist/types/analytics.d.ts +0 -113
- package/dist/types/feed.d.ts +0 -21
- package/dist/types/file.d.ts +0 -12
- package/dist/types/heatmap.d.ts +0 -5
- package/dist/types/hot-segments.d.ts +0 -9
- package/dist/types/image.d.ts +0 -9
- package/dist/types/uuid.d.ts +0 -1
- package/dist/types/video.d.ts +0 -22
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { SubtitleTrack } from "../lib/subtitle-logic.js";
|
|
2
|
-
import { AudioTrack } from "../lib/hls-utils.js";
|
|
3
|
-
import { UUID } from "../types/uuid.js";
|
|
4
|
-
import { MapStore } from "nanostores";
|
|
5
|
-
import Hls from "hls.js";
|
|
6
|
-
export interface PlayerState {
|
|
7
|
-
paused: boolean;
|
|
8
|
-
loading: boolean;
|
|
9
|
-
ended: boolean;
|
|
10
|
-
mounted: boolean;
|
|
11
|
-
hasInteracted: boolean;
|
|
12
|
-
whenInteracted: Date;
|
|
13
|
-
isFullscreen: boolean;
|
|
14
|
-
isPictureInPicture: boolean;
|
|
15
|
-
muted: boolean;
|
|
16
|
-
playbackRate: number;
|
|
17
|
-
volume: number;
|
|
18
|
-
previousVolume: number;
|
|
19
|
-
viewport: {
|
|
20
|
-
width: number;
|
|
21
|
-
height: number;
|
|
22
|
-
};
|
|
23
|
-
resolution: number;
|
|
24
|
-
subtitleTrack: number;
|
|
25
|
-
availableSubtitleTracks: SubtitleTrack[];
|
|
26
|
-
currentSubtitleText: string;
|
|
27
|
-
audioTrack: number;
|
|
28
|
-
availableAudioTracks: AudioTrack[];
|
|
29
|
-
hlsInstance: Hls | null;
|
|
30
|
-
}
|
|
31
|
-
export interface PlayerProgressSnapshot {
|
|
32
|
-
currentTime: number;
|
|
33
|
-
duration: number;
|
|
34
|
-
progress: number;
|
|
35
|
-
buffered: number;
|
|
36
|
-
}
|
|
37
|
-
export interface PlayerStateStore {
|
|
38
|
-
state: Map<UUID, MapStore<PlayerState>>;
|
|
39
|
-
get: (id: UUID) => MapStore<PlayerState>;
|
|
40
|
-
deletePlayer: (id: UUID) => void;
|
|
41
|
-
getEffectiveMediaMuted: (player: Pick<PlayerState, "muted" | "volume" | "hasInteracted">) => boolean;
|
|
42
|
-
muteMedia: (id: UUID) => void;
|
|
43
|
-
unmuteMedia: (id: UUID) => void;
|
|
44
|
-
toggleMediaMute: (id: UUID) => void;
|
|
45
|
-
setMediaVolume: (id: UUID, volume: number) => void;
|
|
46
|
-
playMedia: (id: UUID) => Promise<void>;
|
|
47
|
-
pauseMedia: (id: UUID) => void;
|
|
48
|
-
toggleMediaPlayback: (id: UUID) => Promise<void>;
|
|
49
|
-
pauseOtherMedia: (except: UUID) => void;
|
|
50
|
-
setMediaPlaybackRate: (id: UUID, playbackRate: number) => void;
|
|
51
|
-
readProgressSnapshot: (id: UUID) => PlayerProgressSnapshot;
|
|
52
|
-
subscribeToProgress: (id: UUID, onStoreChange: () => void) => () => void;
|
|
53
|
-
seekProgressTo: (id: UUID, seconds: number) => void;
|
|
54
|
-
seekProgressBy: (id: UUID, deltaSeconds: number) => void;
|
|
55
|
-
getTrackOptions: (tracks: {
|
|
56
|
-
label: string;
|
|
57
|
-
language: string;
|
|
58
|
-
kind: string;
|
|
59
|
-
}[]) => {
|
|
60
|
-
index: number;
|
|
61
|
-
label: string;
|
|
62
|
-
language: string;
|
|
63
|
-
kind: string;
|
|
64
|
-
}[];
|
|
65
|
-
selectAudioTrack: (id: UUID, trackIndex: number) => void;
|
|
66
|
-
selectSubtitleTrack: (id: UUID, trackIndex: number) => void;
|
|
67
|
-
setAudioTrack: (id: UUID, audioTrack: number) => void;
|
|
68
|
-
setAvailableAudioTracks: (id: UUID, tracks: AudioTrack[]) => void;
|
|
69
|
-
setGlobalMuted: (muted: boolean) => void;
|
|
70
|
-
setGlobalVolume: (volume: number) => void;
|
|
71
|
-
setGlobalPlaybackRate: (rate: number) => void;
|
|
72
|
-
setGlobalPreferredQuality: (quality: number | undefined) => void;
|
|
73
|
-
setGlobalPreferredAudioLanguage: (language: string | undefined) => void;
|
|
74
|
-
setGlobalPreferredSubtitleLanguage: (language: string | undefined) => void;
|
|
75
|
-
pauseAllPlayers: () => void;
|
|
76
|
-
setMounted: (id: UUID) => void;
|
|
77
|
-
setHasInteracted: (id: UUID) => void;
|
|
78
|
-
setPaused: (id: UUID, paused: boolean) => void;
|
|
79
|
-
setLoading: (id: UUID, loading: boolean) => void;
|
|
80
|
-
setEnded: (id: UUID, ended: boolean) => void;
|
|
81
|
-
setFullscreen: (id: UUID, isFullscreen: boolean) => void;
|
|
82
|
-
setPictureInPicture: (id: UUID, isPictureInPicture: boolean) => void;
|
|
83
|
-
setMuted: (id: UUID, muted: boolean) => void;
|
|
84
|
-
setPlaybackRate: (id: UUID, playbackRate: number) => void;
|
|
85
|
-
setPreviousVolume: (id: UUID, previousVolume: number) => void;
|
|
86
|
-
setVolume: (id: UUID, volume: number) => void;
|
|
87
|
-
setViewport: (id: UUID, width: number, height: number) => void;
|
|
88
|
-
setResolution: (id: UUID, resolution: number) => void;
|
|
89
|
-
setSubtitleTrack: (id: UUID, subtitleTrack: number) => void;
|
|
90
|
-
setAvailableSubtitleTracks: (id: UUID, tracks: SubtitleTrack[]) => void;
|
|
91
|
-
setCurrentSubtitleText: (id: UUID, text: string) => void;
|
|
92
|
-
setHlsInstance: (id: UUID, hlsInstance: Hls | null) => void;
|
|
93
|
-
}
|
|
94
|
-
export declare const playerStateStore: PlayerStateStore;
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { getPersistedSubtitleTrack, persistSubtitleTrack } from "../lib/track-persistence.js";
|
|
2
|
-
import { clamp } from "../lib/numbers.js";
|
|
3
|
-
import { clampVolume } from "../lib/volume-utils.js";
|
|
4
|
-
import { playerGlobalActions } from "./player-global-actions.js";
|
|
5
|
-
import { playerStateActions } from "./player-store-actions.js";
|
|
6
|
-
import { playerTrackActions } from "./player-track-actions.js";
|
|
7
|
-
import { settingsStore } from "./settings/store.js";
|
|
8
|
-
import { map } from "nanostores";
|
|
9
|
-
|
|
10
|
-
// src/store/player-store.ts
|
|
11
|
-
const MIN_PLAYBACK_RATE = .25;
|
|
12
|
-
const MAX_PLAYBACK_RATE = 3;
|
|
13
|
-
const createInitialPlayerState = () => {
|
|
14
|
-
const settings = settingsStore.getSettings();
|
|
15
|
-
const initialVolume = settings.volume;
|
|
16
|
-
return {
|
|
17
|
-
paused: true,
|
|
18
|
-
loading: true,
|
|
19
|
-
ended: false,
|
|
20
|
-
mounted: false,
|
|
21
|
-
hasInteracted: false,
|
|
22
|
-
whenInteracted: /* @__PURE__ */ new Date(0),
|
|
23
|
-
isFullscreen: false,
|
|
24
|
-
isPictureInPicture: false,
|
|
25
|
-
muted: settings.globalMutedPreference,
|
|
26
|
-
playbackRate: clamp(settings.playbackSpeed, MIN_PLAYBACK_RATE, MAX_PLAYBACK_RATE),
|
|
27
|
-
volume: initialVolume,
|
|
28
|
-
previousVolume: initialVolume,
|
|
29
|
-
viewport: {
|
|
30
|
-
width: 0,
|
|
31
|
-
height: 0
|
|
32
|
-
},
|
|
33
|
-
resolution: -1,
|
|
34
|
-
subtitleTrack: getPersistedSubtitleTrack(),
|
|
35
|
-
availableSubtitleTracks: [],
|
|
36
|
-
currentSubtitleText: "",
|
|
37
|
-
audioTrack: 0,
|
|
38
|
-
availableAudioTracks: [],
|
|
39
|
-
hlsInstance: null
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
const createInitialPlayer = () => map(createInitialPlayerState());
|
|
43
|
-
function setPlayerValue(playerId, key, value) {
|
|
44
|
-
playerStateStore.get(playerId).setKey(key, value);
|
|
45
|
-
}
|
|
46
|
-
const playerStateStore = {
|
|
47
|
-
state: /* @__PURE__ */ new Map(),
|
|
48
|
-
get: (id) => {
|
|
49
|
-
let player = playerStateStore.state.get(id);
|
|
50
|
-
if (!player) {
|
|
51
|
-
player = createInitialPlayer();
|
|
52
|
-
playerStateStore.state.set(id, player);
|
|
53
|
-
}
|
|
54
|
-
return player;
|
|
55
|
-
},
|
|
56
|
-
deletePlayer: (id) => {
|
|
57
|
-
playerStateStore.state.delete(id);
|
|
58
|
-
},
|
|
59
|
-
...playerStateActions,
|
|
60
|
-
...playerTrackActions,
|
|
61
|
-
...playerGlobalActions,
|
|
62
|
-
setMounted: (id) => {
|
|
63
|
-
setPlayerValue(id, "mounted", true);
|
|
64
|
-
},
|
|
65
|
-
setHasInteracted: (id) => {
|
|
66
|
-
const player = playerStateStore.get(id);
|
|
67
|
-
player.setKey("hasInteracted", true);
|
|
68
|
-
player.setKey("whenInteracted", /* @__PURE__ */ new Date());
|
|
69
|
-
},
|
|
70
|
-
setPaused: (id, paused) => {
|
|
71
|
-
setPlayerValue(id, "paused", paused);
|
|
72
|
-
},
|
|
73
|
-
setLoading: (id, loading) => {
|
|
74
|
-
setPlayerValue(id, "loading", loading);
|
|
75
|
-
},
|
|
76
|
-
setEnded: (id, ended) => {
|
|
77
|
-
setPlayerValue(id, "ended", ended);
|
|
78
|
-
},
|
|
79
|
-
setFullscreen: (id, isFullscreen) => {
|
|
80
|
-
setPlayerValue(id, "isFullscreen", isFullscreen);
|
|
81
|
-
},
|
|
82
|
-
setPictureInPicture: (id, isPictureInPicture) => {
|
|
83
|
-
setPlayerValue(id, "isPictureInPicture", isPictureInPicture);
|
|
84
|
-
},
|
|
85
|
-
setMuted: (id, muted) => {
|
|
86
|
-
setPlayerValue(id, "muted", muted);
|
|
87
|
-
},
|
|
88
|
-
setPlaybackRate: (id, playbackRate) => {
|
|
89
|
-
setPlayerValue(id, "playbackRate", clamp(playbackRate, MIN_PLAYBACK_RATE, MAX_PLAYBACK_RATE));
|
|
90
|
-
},
|
|
91
|
-
setPreviousVolume: (id, previousVolume) => {
|
|
92
|
-
setPlayerValue(id, "previousVolume", clampVolume(previousVolume));
|
|
93
|
-
},
|
|
94
|
-
setVolume: (id, volume) => {
|
|
95
|
-
setPlayerValue(id, "volume", clampVolume(volume));
|
|
96
|
-
},
|
|
97
|
-
setViewport: (id, width, height) => {
|
|
98
|
-
setPlayerValue(id, "viewport", {
|
|
99
|
-
width,
|
|
100
|
-
height
|
|
101
|
-
});
|
|
102
|
-
},
|
|
103
|
-
setResolution: (id, resolution) => {
|
|
104
|
-
setPlayerValue(id, "resolution", resolution);
|
|
105
|
-
},
|
|
106
|
-
setSubtitleTrack: (id, subtitleTrack) => {
|
|
107
|
-
const player = playerStateStore.get(id);
|
|
108
|
-
player.get().availableSubtitleTracks.forEach((track, index) => {
|
|
109
|
-
track.track.mode = index === subtitleTrack ? "showing" : "disabled";
|
|
110
|
-
});
|
|
111
|
-
player.setKey("subtitleTrack", subtitleTrack);
|
|
112
|
-
persistSubtitleTrack(subtitleTrack);
|
|
113
|
-
},
|
|
114
|
-
setAvailableSubtitleTracks: (id, tracks) => {
|
|
115
|
-
playerStateStore.get(id).setKey("availableSubtitleTracks", tracks);
|
|
116
|
-
const persistedTrack = getPersistedSubtitleTrack();
|
|
117
|
-
if (persistedTrack >= 0 && persistedTrack < tracks.length) playerStateStore.setSubtitleTrack(id, persistedTrack);
|
|
118
|
-
},
|
|
119
|
-
setCurrentSubtitleText: (id, text) => {
|
|
120
|
-
setPlayerValue(id, "currentSubtitleText", text);
|
|
121
|
-
},
|
|
122
|
-
setHlsInstance: (id, hlsInstance) => {
|
|
123
|
-
setPlayerValue(id, "hlsInstance", hlsInstance);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export { createInitialPlayerState, playerStateStore };
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { getPersistedAudioTrack, persistAudioTrack } from "../lib/track-persistence.js";
|
|
2
|
-
|
|
3
|
-
// src/store/player-track-actions.ts
|
|
4
|
-
const EMPTY_TRACKS = [];
|
|
5
|
-
function toTrackOption(track, index) {
|
|
6
|
-
return {
|
|
7
|
-
index,
|
|
8
|
-
label: track.label,
|
|
9
|
-
language: track.language,
|
|
10
|
-
kind: track.kind
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
const playerTrackActions = {
|
|
14
|
-
getTrackOptions(tracks) {
|
|
15
|
-
return tracks.length > 0 ? tracks.map(toTrackOption) : EMPTY_TRACKS;
|
|
16
|
-
},
|
|
17
|
-
selectAudioTrack(id, trackIndex) {
|
|
18
|
-
const { availableAudioTracks } = this.get(id).get();
|
|
19
|
-
if (trackIndex < 0 || trackIndex >= availableAudioTracks.length) return;
|
|
20
|
-
this.setAudioTrack(id, trackIndex);
|
|
21
|
-
},
|
|
22
|
-
selectSubtitleTrack(id, trackIndex) {
|
|
23
|
-
if (trackIndex !== -1) {
|
|
24
|
-
const { availableSubtitleTracks } = this.get(id).get();
|
|
25
|
-
if (trackIndex < 0 || trackIndex >= availableSubtitleTracks.length) return;
|
|
26
|
-
}
|
|
27
|
-
this.setSubtitleTrack(id, trackIndex);
|
|
28
|
-
},
|
|
29
|
-
setAudioTrack(id, audioTrack) {
|
|
30
|
-
const player = this.get(id);
|
|
31
|
-
const currentState = player.get();
|
|
32
|
-
if (currentState.hlsInstance && currentState.hlsInstance.audioTracks && audioTrack >= 0 && audioTrack < currentState.hlsInstance.audioTracks.length) currentState.hlsInstance.audioTrack = audioTrack;
|
|
33
|
-
player.setKey("audioTrack", audioTrack);
|
|
34
|
-
persistAudioTrack(audioTrack);
|
|
35
|
-
},
|
|
36
|
-
setAvailableAudioTracks(id, tracks) {
|
|
37
|
-
this.get(id).setKey("availableAudioTracks", tracks);
|
|
38
|
-
const persistedTrack = getPersistedAudioTrack();
|
|
39
|
-
if (persistedTrack >= 0 && persistedTrack < tracks.length) this.setAudioTrack(id, persistedTrack);
|
|
40
|
-
else if (tracks.length > 0) this.setAudioTrack(id, 0);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export { playerTrackActions };
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { FeedPost } from "../types/feed.js";
|
|
2
|
-
import { WritableAtom } from "nanostores";
|
|
3
|
-
export interface PostStoreState {
|
|
4
|
-
initialized: boolean;
|
|
5
|
-
feedId: string;
|
|
6
|
-
posts: FeedPost[];
|
|
7
|
-
isLoadedInitial: boolean;
|
|
8
|
-
isFetchingVideos: boolean;
|
|
9
|
-
currentIndex: number;
|
|
10
|
-
total: number;
|
|
11
|
-
}
|
|
12
|
-
export declare const postStore: WritableAtom<PostStoreState>;
|
|
13
|
-
interface PostStoreActions {
|
|
14
|
-
init: (feedId: string) => void;
|
|
15
|
-
loadInitialPosts: () => Promise<void>;
|
|
16
|
-
fetchNewVideos: () => Promise<void>;
|
|
17
|
-
setCurrentIndex: (index: number) => void;
|
|
18
|
-
}
|
|
19
|
-
export declare const postStoreActions: PostStoreActions;
|
|
20
|
-
export {};
|
package/dist/store/postStore.js
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { getFeedPosts } from "./feed-store.js";
|
|
2
|
-
import { feedCacheStore } from "./feed-cache-store.js";
|
|
3
|
-
import { atom } from "nanostores";
|
|
4
|
-
|
|
5
|
-
// src/store/postStore.ts
|
|
6
|
-
const postStore = atom({
|
|
7
|
-
initialized: false,
|
|
8
|
-
feedId: "",
|
|
9
|
-
posts: [],
|
|
10
|
-
isLoadedInitial: true,
|
|
11
|
-
isFetchingVideos: false,
|
|
12
|
-
currentIndex: 0,
|
|
13
|
-
total: 0
|
|
14
|
-
});
|
|
15
|
-
/**
|
|
16
|
-
* Identifies the feed a request belongs to.
|
|
17
|
-
*
|
|
18
|
-
* The feed id alone is not enough: switching away and back (A -> B -> A) would
|
|
19
|
-
* let a response from the first visit be accepted on the second, merging posts
|
|
20
|
-
* against a queue that has since been rebuilt. The counter, bumped on every
|
|
21
|
-
* init, keeps each visit distinct.
|
|
22
|
-
*/
|
|
23
|
-
let feedEpoch = 0;
|
|
24
|
-
/** Whether the request that started under this epoch still owns the store. */
|
|
25
|
-
function isCurrent(epoch) {
|
|
26
|
-
return epoch === feedEpoch;
|
|
27
|
-
}
|
|
28
|
-
const postStoreActions = {
|
|
29
|
-
init(feedId) {
|
|
30
|
-
feedEpoch += 1;
|
|
31
|
-
const cachedPosts = feedCacheStore.loadCache(feedId);
|
|
32
|
-
postStore.set({
|
|
33
|
-
...postStore.get(),
|
|
34
|
-
feedId,
|
|
35
|
-
initialized: true,
|
|
36
|
-
posts: cachedPosts,
|
|
37
|
-
currentIndex: 0,
|
|
38
|
-
total: 0,
|
|
39
|
-
isLoadedInitial: cachedPosts.length > 0,
|
|
40
|
-
isFetchingVideos: false
|
|
41
|
-
});
|
|
42
|
-
},
|
|
43
|
-
async loadInitialPosts() {
|
|
44
|
-
const state = postStore.get();
|
|
45
|
-
if (state.isFetchingVideos) return;
|
|
46
|
-
const epoch = feedEpoch;
|
|
47
|
-
const feedId = state.feedId;
|
|
48
|
-
postStore.set({
|
|
49
|
-
...state,
|
|
50
|
-
isFetchingVideos: true
|
|
51
|
-
});
|
|
52
|
-
try {
|
|
53
|
-
const currentState = postStore.get();
|
|
54
|
-
const apiPosts = await getFeedPosts(feedId);
|
|
55
|
-
if (!isCurrent(epoch)) return;
|
|
56
|
-
const allPosts = [...currentState.posts, ...apiPosts.posts];
|
|
57
|
-
const uniquePosts = Array.from(new Map(allPosts.map((post) => [post.id, post])).values());
|
|
58
|
-
feedCacheStore.saveNewPosts(apiPosts.posts, feedId);
|
|
59
|
-
postStore.set({
|
|
60
|
-
...postStore.get(),
|
|
61
|
-
posts: uniquePosts,
|
|
62
|
-
isLoadedInitial: true,
|
|
63
|
-
total: apiPosts.total
|
|
64
|
-
});
|
|
65
|
-
} catch (error) {
|
|
66
|
-
console.error("[PostStore] Error loading posts:", error);
|
|
67
|
-
} finally {
|
|
68
|
-
if (isCurrent(epoch)) postStore.set({
|
|
69
|
-
...postStore.get(),
|
|
70
|
-
isFetchingVideos: false
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
async fetchNewVideos() {
|
|
75
|
-
const state = postStore.get();
|
|
76
|
-
if (state.isFetchingVideos || !state.initialized) return;
|
|
77
|
-
const epoch = feedEpoch;
|
|
78
|
-
const feedId = state.feedId;
|
|
79
|
-
postStore.set({
|
|
80
|
-
...state,
|
|
81
|
-
isFetchingVideos: true
|
|
82
|
-
});
|
|
83
|
-
try {
|
|
84
|
-
const currentState = postStore.get();
|
|
85
|
-
const apiPosts = await getFeedPosts(feedId, currentState.posts ? currentState.posts.length : 0);
|
|
86
|
-
if (!isCurrent(epoch)) return;
|
|
87
|
-
postStore.set({
|
|
88
|
-
...postStore.get(),
|
|
89
|
-
posts: [...postStore.get().posts, ...apiPosts.posts],
|
|
90
|
-
total: apiPosts.total
|
|
91
|
-
});
|
|
92
|
-
} finally {
|
|
93
|
-
if (isCurrent(epoch)) postStore.set({
|
|
94
|
-
...postStore.get(),
|
|
95
|
-
isFetchingVideos: false
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
},
|
|
99
|
-
setCurrentIndex(index) {
|
|
100
|
-
const currentState = postStore.get();
|
|
101
|
-
if (index !== currentState.currentIndex) {
|
|
102
|
-
const currentVideo = currentState.posts[currentState.currentIndex];
|
|
103
|
-
if (currentVideo) feedCacheStore.removePost(currentVideo.id);
|
|
104
|
-
postStore.set({
|
|
105
|
-
...currentState,
|
|
106
|
-
currentIndex: index
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
export { postStore, postStoreActions };
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export declare const FONT_FAMILIES: {
|
|
2
|
-
readonly monospace_serif: "\"Courier New\", Courier, \"Nimbus Mono L\", \"Cutive Mono\", monospace";
|
|
3
|
-
readonly proportional_serif: "\"Times New Roman\", Times, Georgia, Cambria, \"PT Serif Caption\", serif";
|
|
4
|
-
readonly monospace_sans: "\"Deja Vu Sans Mono\", \"Lucida Console\", Monaco, Consolas, \"PT Mono\", monospace";
|
|
5
|
-
readonly proportional_sans: "Roboto, Arial, Helvetica, Verdana, \"PT Sans Caption\", sans-serif";
|
|
6
|
-
readonly casual: "\"Comic Sans MS\", Impact, Handlee, fantasy";
|
|
7
|
-
readonly cursive: "\"Monotype Corsiva\", \"URW Chancery L\", \"Apple Chancery\", \"Dancing Script\", cursive";
|
|
8
|
-
readonly small_caps: "Arial, Helvetica, Verdana, \"Marcellus SC\", sans-serif";
|
|
9
|
-
};
|
|
10
|
-
export type FontFamilyKey = keyof typeof FONT_FAMILIES;
|
|
11
|
-
export declare const FONT_SIZES: number[];
|
|
12
|
-
export declare const COLORS: Record<string, string>;
|
|
13
|
-
export declare const EDGE_STYLES: string[];
|
|
14
|
-
export declare const PLAYBACK_SPEEDS: number[];
|
|
15
|
-
export declare const LANG_TYPES: string[];
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
// src/store/settings/constants.ts
|
|
2
|
-
const FONT_FAMILIES = {
|
|
3
|
-
monospace_serif: "\"Courier New\", Courier, \"Nimbus Mono L\", \"Cutive Mono\", monospace",
|
|
4
|
-
proportional_serif: "\"Times New Roman\", Times, Georgia, Cambria, \"PT Serif Caption\", serif",
|
|
5
|
-
monospace_sans: "\"Deja Vu Sans Mono\", \"Lucida Console\", Monaco, Consolas, \"PT Mono\", monospace",
|
|
6
|
-
proportional_sans: "Roboto, Arial, Helvetica, Verdana, \"PT Sans Caption\", sans-serif",
|
|
7
|
-
casual: "\"Comic Sans MS\", Impact, Handlee, fantasy",
|
|
8
|
-
cursive: "\"Monotype Corsiva\", \"URW Chancery L\", \"Apple Chancery\", \"Dancing Script\", cursive",
|
|
9
|
-
small_caps: "Arial, Helvetica, Verdana, \"Marcellus SC\", sans-serif"
|
|
10
|
-
};
|
|
11
|
-
const FONT_SIZES = [
|
|
12
|
-
50,
|
|
13
|
-
100,
|
|
14
|
-
150,
|
|
15
|
-
200
|
|
16
|
-
];
|
|
17
|
-
const COLORS = {
|
|
18
|
-
white: "#ffffff",
|
|
19
|
-
yellow: "#ffff00",
|
|
20
|
-
green: "#00ff00",
|
|
21
|
-
cyan: "#00ffff",
|
|
22
|
-
blue: "#0000ff",
|
|
23
|
-
magenta: "#ff00ff",
|
|
24
|
-
red: "#ff0000",
|
|
25
|
-
black: "#000000"
|
|
26
|
-
};
|
|
27
|
-
const EDGE_STYLES = [
|
|
28
|
-
"none",
|
|
29
|
-
"drop-shadow",
|
|
30
|
-
"raised",
|
|
31
|
-
"depressed",
|
|
32
|
-
"outline"
|
|
33
|
-
];
|
|
34
|
-
const PLAYBACK_SPEEDS = [
|
|
35
|
-
1,
|
|
36
|
-
1.25,
|
|
37
|
-
1.5,
|
|
38
|
-
2,
|
|
39
|
-
3
|
|
40
|
-
];
|
|
41
|
-
const LANG_TYPES = [
|
|
42
|
-
"off",
|
|
43
|
-
"eng",
|
|
44
|
-
"auto"
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
export { COLORS, EDGE_STYLES, FONT_FAMILIES, FONT_SIZES, LANG_TYPES, PLAYBACK_SPEEDS };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// src/store/settings/defaults.ts
|
|
2
|
-
const defaultSettings = {
|
|
3
|
-
volume: 1,
|
|
4
|
-
playbackSpeed: 1,
|
|
5
|
-
customPlayback: 1,
|
|
6
|
-
allowCaptions: false,
|
|
7
|
-
captionPosition: {
|
|
8
|
-
x: 20,
|
|
9
|
-
y: 90
|
|
10
|
-
},
|
|
11
|
-
captionLang: "off",
|
|
12
|
-
captionFontFamily: "proportional_sans",
|
|
13
|
-
captionFontSize: 100,
|
|
14
|
-
captionFontColor: "#ffffff",
|
|
15
|
-
captionFontOpacity: 100,
|
|
16
|
-
captionBGColor: "#000000",
|
|
17
|
-
captionBGOpacity: 75,
|
|
18
|
-
captionWindowColor: "#000000",
|
|
19
|
-
captionWindowOpacity: 0,
|
|
20
|
-
captionCharacterEdgeStyle: "none",
|
|
21
|
-
globalMutedPreference: false
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export { defaultSettings };
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { defaultSettings } from "./defaults.js";
|
|
2
|
-
import { validateSettings } from "./validation.js";
|
|
3
|
-
|
|
4
|
-
// src/store/settings/storage.ts
|
|
5
|
-
const SETTINGS_STORAGE_KEY = "videosdk_settings";
|
|
6
|
-
const loadSettings = () => {
|
|
7
|
-
if (typeof window === "undefined") return defaultSettings;
|
|
8
|
-
try {
|
|
9
|
-
const storedSettings = localStorage.getItem(SETTINGS_STORAGE_KEY);
|
|
10
|
-
if (storedSettings) {
|
|
11
|
-
const parsedSettings = JSON.parse(storedSettings);
|
|
12
|
-
return validateSettings(parsedSettings);
|
|
13
|
-
}
|
|
14
|
-
} catch (error) {
|
|
15
|
-
console.error("Failed to load settings from localStorage:", error);
|
|
16
|
-
}
|
|
17
|
-
return defaultSettings;
|
|
18
|
-
};
|
|
19
|
-
const saveSettings = (settings) => {
|
|
20
|
-
if (typeof window === "undefined") return;
|
|
21
|
-
try {
|
|
22
|
-
localStorage.setItem(SETTINGS_STORAGE_KEY, JSON.stringify(settings));
|
|
23
|
-
} catch (error) {
|
|
24
|
-
console.error("Failed to save settings to localStorage:", error);
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export { loadSettings, saveSettings };
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { CaptionLangType, SettingsState } from "./types.js";
|
|
2
|
-
import { MapStore } from "nanostores";
|
|
3
|
-
interface SettingsStore {
|
|
4
|
-
state: MapStore<SettingsState>;
|
|
5
|
-
getSettings: () => SettingsState;
|
|
6
|
-
setVolume: (volume: number) => number;
|
|
7
|
-
setPlaybackSpeed: (playbackSpeed: number) => number;
|
|
8
|
-
setCustomPlayback: (customPlayback: number) => number;
|
|
9
|
-
setAllowCaptions: (allowCaptions: boolean) => boolean;
|
|
10
|
-
setCaptionPosition: (x: number, y: number) => {
|
|
11
|
-
x: number;
|
|
12
|
-
y: number;
|
|
13
|
-
};
|
|
14
|
-
setSubtitleLang: (captionLang: CaptionLangType) => CaptionLangType;
|
|
15
|
-
setCaptionFontFamily: (captionFontFamily: string) => string;
|
|
16
|
-
setCaptionFontSize: (captionFontSize: number) => number;
|
|
17
|
-
setCaptionFontColor: (captionFontColor: string) => string;
|
|
18
|
-
setCaptionBGColor: (captionBGColor: string) => string;
|
|
19
|
-
setCaptionBGOpacity: (captionOpacity: number) => number;
|
|
20
|
-
setCaptionWindowColor: (captionWindowColor: string) => string;
|
|
21
|
-
setCaptionWindowOpacity: (captionWindowOpacity: number) => number;
|
|
22
|
-
setCaptionFontOpacity: (captionFontOpacity: number) => number;
|
|
23
|
-
setCaptionCharacterEdgeStyle: (captionCharacterEdgeStyle: string) => string;
|
|
24
|
-
resetCaptionSettings: () => void;
|
|
25
|
-
setSelectedLanguageCode: (languageCode: string) => string | undefined;
|
|
26
|
-
setMuted: (muted: boolean) => boolean;
|
|
27
|
-
setPreferredQuality: (quality: number | undefined) => number | undefined;
|
|
28
|
-
setPreferredAudioLanguage: (language: string | undefined) => string | undefined;
|
|
29
|
-
setPreferredSubtitleLanguage: (language: string | undefined) => string | undefined;
|
|
30
|
-
}
|
|
31
|
-
export declare const settingsStore: SettingsStore;
|
|
32
|
-
export {};
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { defaultSettings } from "./defaults.js";
|
|
2
|
-
import { loadSettings, saveSettings } from "./storage.js";
|
|
3
|
-
import { clampVolume } from "../../lib/volume-utils.js";
|
|
4
|
-
import { map } from "nanostores";
|
|
5
|
-
|
|
6
|
-
// src/store/settings/store.ts
|
|
7
|
-
const updateSettings = (key, value) => {
|
|
8
|
-
settingsStore.state.setKey(key, value);
|
|
9
|
-
saveSettings(settingsStore.state.get());
|
|
10
|
-
return value;
|
|
11
|
-
};
|
|
12
|
-
const settingsState = map(loadSettings());
|
|
13
|
-
const settingsStore = {
|
|
14
|
-
state: settingsState,
|
|
15
|
-
getSettings: () => settingsStore.state.get(),
|
|
16
|
-
setVolume: (volume) => updateSettings("volume", clampVolume(volume)),
|
|
17
|
-
setPlaybackSpeed: (playbackSpeed) => updateSettings("playbackSpeed", playbackSpeed),
|
|
18
|
-
setCustomPlayback: (customPlayback) => updateSettings("customPlayback", customPlayback),
|
|
19
|
-
setAllowCaptions: (allowCaptions) => updateSettings("allowCaptions", allowCaptions),
|
|
20
|
-
setCaptionPosition: (x, y) => updateSettings("captionPosition", {
|
|
21
|
-
x,
|
|
22
|
-
y
|
|
23
|
-
}),
|
|
24
|
-
setSubtitleLang: (captionLang) => updateSettings("captionLang", captionLang),
|
|
25
|
-
setCaptionFontFamily: (captionFontFamily) => updateSettings("captionFontFamily", captionFontFamily),
|
|
26
|
-
setCaptionFontSize: (captionFontSize) => updateSettings("captionFontSize", captionFontSize),
|
|
27
|
-
setCaptionFontColor: (captionFontColor) => updateSettings("captionFontColor", captionFontColor),
|
|
28
|
-
setCaptionBGColor: (captionBGColor) => updateSettings("captionBGColor", captionBGColor),
|
|
29
|
-
setCaptionBGOpacity: (captionOpacity) => updateSettings("captionBGOpacity", captionOpacity),
|
|
30
|
-
setCaptionWindowColor: (captionWindowColor) => updateSettings("captionWindowColor", captionWindowColor),
|
|
31
|
-
setCaptionWindowOpacity: (captionWindowOpacity) => updateSettings("captionWindowOpacity", captionWindowOpacity),
|
|
32
|
-
setCaptionFontOpacity: (captionFontOpacity) => updateSettings("captionFontOpacity", captionFontOpacity),
|
|
33
|
-
setCaptionCharacterEdgeStyle: (captionCharacterEdgeStyle) => updateSettings("captionCharacterEdgeStyle", captionCharacterEdgeStyle),
|
|
34
|
-
resetCaptionSettings: () => {
|
|
35
|
-
const resetSettings = {
|
|
36
|
-
...settingsStore.state.get(),
|
|
37
|
-
captionPosition: defaultSettings.captionPosition,
|
|
38
|
-
captionLang: defaultSettings.captionLang,
|
|
39
|
-
captionFontFamily: defaultSettings.captionFontFamily,
|
|
40
|
-
captionFontSize: defaultSettings.captionFontSize,
|
|
41
|
-
captionFontColor: defaultSettings.captionFontColor,
|
|
42
|
-
captionBGColor: defaultSettings.captionBGColor,
|
|
43
|
-
captionBGOpacity: defaultSettings.captionBGOpacity,
|
|
44
|
-
captionWindowColor: defaultSettings.captionWindowColor,
|
|
45
|
-
captionWindowOpacity: defaultSettings.captionWindowOpacity,
|
|
46
|
-
captionFontOpacity: defaultSettings.captionFontOpacity,
|
|
47
|
-
captionCharacterEdgeStyle: defaultSettings.captionCharacterEdgeStyle
|
|
48
|
-
};
|
|
49
|
-
settingsStore.state.set(resetSettings);
|
|
50
|
-
saveSettings(resetSettings);
|
|
51
|
-
},
|
|
52
|
-
setSelectedLanguageCode: (languageCode) => updateSettings("selectedLanguageCode", languageCode),
|
|
53
|
-
setMuted: (muted) => updateSettings("globalMutedPreference", muted),
|
|
54
|
-
setPreferredQuality: (quality) => updateSettings("preferredQuality", quality),
|
|
55
|
-
setPreferredAudioLanguage: (language) => updateSettings("preferredAudioLanguage", language),
|
|
56
|
-
setPreferredSubtitleLanguage: (language) => updateSettings("preferredSubtitleLanguage", language)
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export { settingsStore };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export type VideoTheme = "default" | "minimal" | "feed" | "hover" | "hideUI";
|
|
2
|
-
export type CaptionLangType = "off" | "eng" | "auto";
|
|
3
|
-
export interface SettingsState {
|
|
4
|
-
volume: number;
|
|
5
|
-
playbackSpeed: number;
|
|
6
|
-
customPlayback: number;
|
|
7
|
-
allowCaptions: boolean;
|
|
8
|
-
captionPosition: {
|
|
9
|
-
x: number;
|
|
10
|
-
y: number;
|
|
11
|
-
};
|
|
12
|
-
captionLang: CaptionLangType;
|
|
13
|
-
captionFontFamily: string;
|
|
14
|
-
captionFontSize: number;
|
|
15
|
-
captionFontColor: string;
|
|
16
|
-
captionFontOpacity: number;
|
|
17
|
-
captionBGColor: string;
|
|
18
|
-
captionBGOpacity: number;
|
|
19
|
-
captionWindowColor: string;
|
|
20
|
-
captionWindowOpacity: number;
|
|
21
|
-
captionCharacterEdgeStyle: string;
|
|
22
|
-
selectedLanguageCode?: string;
|
|
23
|
-
globalMutedPreference: boolean;
|
|
24
|
-
preferredQuality?: number;
|
|
25
|
-
preferredAudioLanguage?: string;
|
|
26
|
-
preferredSubtitleLanguage?: string;
|
|
27
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { SettingsState } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Validate and parse settings, returning defaults for invalid values
|
|
4
|
-
* @param parsed - Raw settings object (e.g., from localStorage)
|
|
5
|
-
* @returns Validated settings with defaults applied for invalid values
|
|
6
|
-
*/
|
|
7
|
-
export declare const validateSettings: (parsed: unknown) => SettingsState;
|