@laplace.live/persona-sdk 1.4.0 → 1.6.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/dist/client/client.d.ts +1 -0
- package/dist/client/client.js +3 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/values/camera.d.ts +13 -0
- package/dist/values/camera.js +19 -0
- package/dist/values/controller.d.ts +11 -11
- package/dist/values/controller.js +24 -44
- package/dist/values/curve.d.ts +4 -4
- package/dist/values/effect-schema.js +4 -4
- package/dist/values/guards.d.ts +12 -0
- package/dist/values/guards.js +16 -0
- package/dist/values/hands.d.ts +22 -22
- package/dist/values/hands.js +30 -58
- package/dist/values/hotkeys.d.ts +14 -0
- package/dist/values/hotkeys.js +13 -1
- package/dist/values/labels.d.ts +12 -5
- package/dist/values/labels.js +29 -9
- package/dist/values/limits.js +1 -0
- package/dist/values/lipsync.d.ts +2 -2
- package/dist/values/lipsync.js +2 -15
- package/dist/values/locale.d.ts +9 -4
- package/dist/values/locale.js +4 -3
- package/dist/values/scene-transition.d.ts +15 -0
- package/dist/values/scene-transition.js +48 -0
- package/dist/wire/errors.js +3 -2
- package/dist/wire/events.d.ts +5 -5
- package/dist/wire/events.js +3 -2
- package/dist/wire/methods.d.ts +14 -24
- package/dist/wire/protocol.d.ts +3 -1
- package/dist/wire/protocol.js +3 -1
- package/dist/wire/schemas.d.ts +20 -8
- package/dist/wire/schemas.js +19 -9
- package/dist/wire/types.d.ts +89 -27
- package/dist/wire/types.js +63 -66
- package/package.json +1 -1
package/dist/values/lipsync.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { finiteOr, isFiniteNumber, isRecord, nonEmptyString } from "./guards.js";
|
|
1
|
+
import { finiteOr, isFiniteNumber, isRecord, keysOf, nonEmptyString } from "./guards.js";
|
|
2
2
|
import { clamp } from "./limits.js";
|
|
3
3
|
export const LIP_SYNC_VOWELS = ['A', 'I', 'U', 'E', 'O'];
|
|
4
4
|
export const LIP_SYNC_PHONEMES = [...LIP_SYNC_VOWELS, 'S'];
|
|
@@ -56,20 +56,6 @@ export function healLipSyncConfig(raw) {
|
|
|
56
56
|
export function isLipSyncMode(value) {
|
|
57
57
|
return LIP_SYNC_MODES.some(mode => mode === value);
|
|
58
58
|
}
|
|
59
|
-
export const VOICE_INPUT_NAMES = [
|
|
60
|
-
'VoiceVolume',
|
|
61
|
-
'VoiceFrequency',
|
|
62
|
-
'VoiceVolumePlusMouthOpen',
|
|
63
|
-
'VoiceFrequencyPlusMouthSmile',
|
|
64
|
-
'VoiceA',
|
|
65
|
-
'VoiceI',
|
|
66
|
-
'VoiceU',
|
|
67
|
-
'VoiceE',
|
|
68
|
-
'VoiceO',
|
|
69
|
-
'VoiceSilence',
|
|
70
|
-
'VoiceMouthOpen',
|
|
71
|
-
'VoiceMouthSpread',
|
|
72
|
-
];
|
|
73
59
|
export const VOICE_INPUT_RANGES = {
|
|
74
60
|
VoiceVolume: [0, 1],
|
|
75
61
|
VoiceFrequency: [0, 1],
|
|
@@ -84,6 +70,7 @@ export const VOICE_INPUT_RANGES = {
|
|
|
84
70
|
VoiceMouthOpen: [0, 1],
|
|
85
71
|
VoiceMouthSpread: [-1, 1],
|
|
86
72
|
};
|
|
73
|
+
export const VOICE_INPUT_NAMES = keysOf(VOICE_INPUT_RANGES);
|
|
87
74
|
/** Semantic import aliases; source analyzer amplitudes need not match Persona's. */
|
|
88
75
|
export const NIZIMA_VOICE_ALIASES = {
|
|
89
76
|
LipSyncVolume: 'VoiceVolume',
|
package/dist/values/locale.d.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const LOCALES: readonly ["en", "ja", "zh-CN", "zh-TW"];
|
|
3
|
-
export type Locale = (typeof LOCALES)[number];
|
|
1
|
+
export type Locale = keyof typeof LOCALE_LABELS;
|
|
4
2
|
/** `ui.language` setting: an explicit locale, or follow the OS language. */
|
|
5
3
|
export type LanguageSetting = 'system' | Locale;
|
|
6
4
|
/** `ui.theme` setting: an explicit appearance, or follow the OS. */
|
|
7
5
|
export type ThemeSetting = 'system' | 'light' | 'dark';
|
|
8
6
|
/** Native-language display names for the language picker (deliberately untranslated). */
|
|
9
|
-
export declare const LOCALE_LABELS:
|
|
7
|
+
export declare const LOCALE_LABELS: {
|
|
8
|
+
en: string;
|
|
9
|
+
ja: string;
|
|
10
|
+
'zh-CN': string;
|
|
11
|
+
'zh-TW': string;
|
|
12
|
+
};
|
|
13
|
+
/** Locales shipped in the compiled catalogs (`pnpm i18n`). */
|
|
14
|
+
export declare const LOCALES: readonly Locale[];
|
|
10
15
|
/** Best supported locale for a BCP 47-ish tag: exact match first, then fuzzy per language. */
|
|
11
16
|
export declare function matchLocaleTag(tag: string): Locale;
|
package/dist/values/locale.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export const LOCALES = ['en', 'ja', 'zh-CN', 'zh-TW'];
|
|
1
|
+
import { isOneOf, keysOf } from "./guards.js";
|
|
3
2
|
/** Native-language display names for the language picker (deliberately untranslated). */
|
|
4
3
|
export const LOCALE_LABELS = {
|
|
5
4
|
en: 'English',
|
|
@@ -7,9 +6,11 @@ export const LOCALE_LABELS = {
|
|
|
7
6
|
'zh-CN': '简体中文',
|
|
8
7
|
'zh-TW': '繁體中文',
|
|
9
8
|
};
|
|
9
|
+
/** Locales shipped in the compiled catalogs (`pnpm i18n`). */
|
|
10
|
+
export const LOCALES = keysOf(LOCALE_LABELS);
|
|
10
11
|
/** Best supported locale for a BCP 47-ish tag: exact match first, then fuzzy per language. */
|
|
11
12
|
export function matchLocaleTag(tag) {
|
|
12
|
-
if (
|
|
13
|
+
if (isOneOf(tag, LOCALES))
|
|
13
14
|
return tag;
|
|
14
15
|
const t = tag.toLowerCase();
|
|
15
16
|
// Most systems/browsers report `zh-TW`/`zh-HK` with no `hant` subtag, so match the regions too.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AssetRef, SceneTransition } from '../wire/types.ts';
|
|
2
|
+
export declare const SCENE_TRANSITION_TYPES: readonly ["cut", "fade", "wipe", "circle", "image", "video"];
|
|
3
|
+
export declare const SCENE_TRANSITION_DURATION_MIN_MS = 100;
|
|
4
|
+
export declare const SCENE_TRANSITION_DURATION_MAX_MS = 10000;
|
|
5
|
+
export declare const SCENE_TRANSITION_FADE_DEFAULT_MS = 300;
|
|
6
|
+
export declare const SCENE_TRANSITION_SWITCH_POINT_MIN = 0.05;
|
|
7
|
+
export declare const SCENE_TRANSITION_SWITCH_POINT_MAX = 0.95;
|
|
8
|
+
/** The destination scene's entrance effect; existing scenes keep an immediate cut. */
|
|
9
|
+
export declare function defaultSceneTransition(): SceneTransition;
|
|
10
|
+
/** The media kind a transition type plays, or null for the built-in effects. */
|
|
11
|
+
export declare function sceneTransitionMedia(type: SceneTransition['type']): 'image' | 'video' | null;
|
|
12
|
+
/** Whether `asset` can back the transition: an available image or video, matching the type when it plays media. */
|
|
13
|
+
export declare function sceneTransitionAssetUsable(transition: SceneTransition, asset: Pick<AssetRef, 'kind' | 'exists'> | null | undefined): boolean;
|
|
14
|
+
/** Heal saved transition settings independently, retaining media while another effect is selected. */
|
|
15
|
+
export declare function healSceneTransition(raw: unknown): SceneTransition;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { finiteOr, isOneOf, isRecord, nonEmptyString } from "./guards.js";
|
|
2
|
+
import { clamp, hexColorOr } from "./limits.js";
|
|
3
|
+
export const SCENE_TRANSITION_TYPES = ['cut', 'fade', 'wipe', 'circle', 'image', 'video'];
|
|
4
|
+
export const SCENE_TRANSITION_DURATION_MIN_MS = 100;
|
|
5
|
+
export const SCENE_TRANSITION_DURATION_MAX_MS = 10_000;
|
|
6
|
+
export const SCENE_TRANSITION_FADE_DEFAULT_MS = 300;
|
|
7
|
+
export const SCENE_TRANSITION_SWITCH_POINT_MIN = 0.05;
|
|
8
|
+
export const SCENE_TRANSITION_SWITCH_POINT_MAX = 0.95;
|
|
9
|
+
/** The destination scene's entrance effect; existing scenes keep an immediate cut. */
|
|
10
|
+
export function defaultSceneTransition() {
|
|
11
|
+
return {
|
|
12
|
+
type: 'cut',
|
|
13
|
+
durationMs: 1000,
|
|
14
|
+
color: '#000000',
|
|
15
|
+
assetId: null,
|
|
16
|
+
switchPoint: 0.5,
|
|
17
|
+
autoFade: false,
|
|
18
|
+
fadeInMs: SCENE_TRANSITION_FADE_DEFAULT_MS,
|
|
19
|
+
fadeOutMs: SCENE_TRANSITION_FADE_DEFAULT_MS,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** The media kind a transition type plays, or null for the built-in effects. */
|
|
23
|
+
export function sceneTransitionMedia(type) {
|
|
24
|
+
return type === 'image' || type === 'video' ? type : null;
|
|
25
|
+
}
|
|
26
|
+
/** Whether `asset` can back the transition: an available image or video, matching the type when it plays media. */
|
|
27
|
+
export function sceneTransitionAssetUsable(transition, asset) {
|
|
28
|
+
if (!asset?.exists || (asset.kind !== 'image' && asset.kind !== 'video'))
|
|
29
|
+
return false;
|
|
30
|
+
const media = sceneTransitionMedia(transition.type);
|
|
31
|
+
return media === null || asset.kind === media;
|
|
32
|
+
}
|
|
33
|
+
/** Heal saved transition settings independently, retaining media while another effect is selected. */
|
|
34
|
+
export function healSceneTransition(raw) {
|
|
35
|
+
const d = defaultSceneTransition();
|
|
36
|
+
if (!isRecord(raw))
|
|
37
|
+
return d;
|
|
38
|
+
return {
|
|
39
|
+
type: isOneOf(raw.type, SCENE_TRANSITION_TYPES) ? raw.type : d.type,
|
|
40
|
+
durationMs: clamp(finiteOr(raw.durationMs, d.durationMs), SCENE_TRANSITION_DURATION_MIN_MS, SCENE_TRANSITION_DURATION_MAX_MS),
|
|
41
|
+
color: hexColorOr(raw.color, d.color),
|
|
42
|
+
assetId: nonEmptyString(raw.assetId),
|
|
43
|
+
switchPoint: clamp(finiteOr(raw.switchPoint, d.switchPoint), SCENE_TRANSITION_SWITCH_POINT_MIN, SCENE_TRANSITION_SWITCH_POINT_MAX),
|
|
44
|
+
autoFade: typeof raw.autoFade === 'boolean' ? raw.autoFade : d.autoFade,
|
|
45
|
+
fadeInMs: clamp(finiteOr(raw.fadeInMs, d.fadeInMs), 0, SCENE_TRANSITION_DURATION_MAX_MS),
|
|
46
|
+
fadeOutMs: clamp(finiteOr(raw.fadeOutMs, d.fadeOutMs), 0, SCENE_TRANSITION_DURATION_MAX_MS),
|
|
47
|
+
};
|
|
48
|
+
}
|
package/dist/wire/errors.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { isOneOf } from "../values/guards.js";
|
|
1
2
|
/** Every error the server can return, as string discriminants (never numeric bands). */
|
|
2
3
|
export const API_ERROR_CODES = [
|
|
3
4
|
'parse-error',
|
|
4
5
|
'invalid-request',
|
|
5
6
|
'unknown-method',
|
|
6
7
|
'invalid-params',
|
|
7
|
-
/** A referenced id (scene, instance, model, asset, hotkey,
|
|
8
|
+
/** A referenced id (scene, instance, model, asset, hotkey, automation, expression) resolves to nothing. */
|
|
8
9
|
'not-found',
|
|
9
10
|
/** The instance's model format cannot perform this method (e.g. MToon on Live2D). */
|
|
10
11
|
'unsupported-for-format',
|
|
@@ -19,7 +20,7 @@ export const API_ERROR_CODES = [
|
|
|
19
20
|
'internal',
|
|
20
21
|
];
|
|
21
22
|
export function isApiErrorCode(v) {
|
|
22
|
-
return
|
|
23
|
+
return isOneOf(v, API_ERROR_CODES);
|
|
23
24
|
}
|
|
24
25
|
/** Thrown by {@link PersonaClient.call} when the server answers with an error envelope. */
|
|
25
26
|
export class PersonaApiError extends Error {
|
package/dist/wire/events.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ExpressionPersistence, HotkeyState, ModelFormat, PoseStatus, SceneState, Settings,
|
|
1
|
+
import type { AutomationInfo, ExpressionPersistence, HotkeyState, ModelFormat, PoseStatus, SceneState, Settings, TrackingStatus } from './types.ts';
|
|
2
2
|
/** Every push event a session can subscribe to, with its payload. */
|
|
3
3
|
export interface EventMap {
|
|
4
|
-
/** Any scene mutation: create/delete/rename/activate
|
|
4
|
+
/** Any scene mutation: create/delete/rename/activate and persisted scene edits. */
|
|
5
5
|
'scene.changed': SceneState;
|
|
6
6
|
'settings.changed': {
|
|
7
7
|
settings: Settings;
|
|
@@ -10,9 +10,9 @@ export interface EventMap {
|
|
|
10
10
|
modelId: string | null;
|
|
11
11
|
config: HotkeyState;
|
|
12
12
|
};
|
|
13
|
-
/** The
|
|
14
|
-
'
|
|
15
|
-
|
|
13
|
+
/** The automation list, its names, or its OS registrations changed. */
|
|
14
|
+
'automation.state': {
|
|
15
|
+
automations: AutomationInfo[];
|
|
16
16
|
};
|
|
17
17
|
/** Network channel aggregates; `sources` includes webcam status and is optional for older servers. */
|
|
18
18
|
'tracking.status': {
|
package/dist/wire/events.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { isOneOf } from "../values/guards.js";
|
|
1
2
|
// Built from a `Record<EventName, …>` so a new EventMap key that is missing
|
|
2
3
|
// here fails the build instead of silently failing `isEventName`.
|
|
3
4
|
export const EVENT_NAMES = Object.keys({
|
|
4
5
|
'scene.changed': true,
|
|
5
6
|
'settings.changed': true,
|
|
6
7
|
'hotkey.state': true,
|
|
7
|
-
'
|
|
8
|
+
'automation.state': true,
|
|
8
9
|
'tracking.status': true,
|
|
9
10
|
'instance.loaded': true,
|
|
10
11
|
'expression.changed': true,
|
|
@@ -18,5 +19,5 @@ export const EVENT_NAMES = Object.keys({
|
|
|
18
19
|
'expression.persistence': true,
|
|
19
20
|
});
|
|
20
21
|
export function isEventName(v) {
|
|
21
|
-
return
|
|
22
|
+
return isOneOf(v, EVENT_NAMES);
|
|
22
23
|
}
|
package/dist/wire/methods.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { ControllerMovementConfig, ControllerState } from '../values/contro
|
|
|
3
3
|
import type { LipSyncCalibrationCommand, LipSyncConfig, LipSyncMode, LipSyncState } from '../values/lipsync.ts';
|
|
4
4
|
import type { SceneInspection } from '../values/stage-info.ts';
|
|
5
5
|
import type { EventName } from './events.ts';
|
|
6
|
-
import type { AnchorOption, AppCapability, AssetKind, AssetRef, Attach, AttachHeadAngle, BindingInput, Expression, ExpressionPersistence, HandTrackingMode, HotkeyConfig, HotkeyState, InjectEntry, InjectTarget, InstanceRuntime, JsonValue, LayerEffectKey, LayerEffects, LayerEffectsPatch, MediaPipeConfig, ModelInfo, ModelRef, MotionGroup, MToonTuning, ObjectContent, ObjectLightOverride, ObjectSpace, Place2D, Place3D, PlayingMotion, PoseSourceId, PoseStatus, Scene, SceneItem, ScenePatch, SceneState, ScreenPlacement, Settings, SettingsPatch,
|
|
6
|
+
import type { AnchorOption, AppCapability, AssetKind, AssetRef, Attach, AttachHeadAngle, AutomationInfo, BindingInput, Expression, ExpressionPersistence, HandTrackingMode, HotkeyConfig, HotkeyState, InjectEntry, InjectTarget, InstanceRuntime, JsonValue, LayerEffectKey, LayerEffects, LayerEffectsPatch, MediaPipeConfig, ModelInfo, ModelRef, MotionGroup, MToonTuning, ObjectContent, ObjectLightOverride, ObjectSpace, Place2D, Place3D, PlayingMotion, PoseSourceId, PoseStatus, Scene, SceneItem, ScenePatch, SceneState, ScreenPlacement, Settings, SettingsPatch, TrackingSourceConfig, TrackingSourceId, TrackingSourceKind, TrackingStatus, VrmPlacement } from './types.ts';
|
|
7
7
|
/** Marker for methods that take no parameters; the client lets you omit the argument. */
|
|
8
8
|
export type EmptyRequest = Record<never, never>;
|
|
9
9
|
/** Marker for methods whose success response carries no data. */
|
|
@@ -36,12 +36,6 @@ export interface SceneDeleteRequest {
|
|
|
36
36
|
sceneId: string;
|
|
37
37
|
}
|
|
38
38
|
export type SceneDeleteResponse = SceneState;
|
|
39
|
-
export interface SceneSetShortcutRequest {
|
|
40
|
-
sceneId: string;
|
|
41
|
-
/** Electron accelerator string, or null to clear. */
|
|
42
|
-
accelerator: string | null;
|
|
43
|
-
}
|
|
44
|
-
export type SceneSetShortcutResponse = SceneState;
|
|
45
39
|
export type ScenePatchRequest = ScenePatch;
|
|
46
40
|
export interface ScenePatchResponse {
|
|
47
41
|
scene: Scene;
|
|
@@ -295,14 +289,14 @@ export interface HotkeyTriggerRequest {
|
|
|
295
289
|
hotkeyId: string;
|
|
296
290
|
}
|
|
297
291
|
export type HotkeyTriggerResponse = EmptyResponse;
|
|
298
|
-
export type
|
|
299
|
-
export interface
|
|
300
|
-
|
|
292
|
+
export type AutomationListRequest = EmptyRequest;
|
|
293
|
+
export interface AutomationListResponse {
|
|
294
|
+
automations: AutomationInfo[];
|
|
301
295
|
}
|
|
302
|
-
export interface
|
|
303
|
-
|
|
296
|
+
export interface AutomationRunRequest {
|
|
297
|
+
automationId: string;
|
|
304
298
|
}
|
|
305
|
-
export type
|
|
299
|
+
export type AutomationRunResponse = EmptyResponse;
|
|
306
300
|
export type ModelListRequest = EmptyRequest;
|
|
307
301
|
export interface ModelListResponse {
|
|
308
302
|
models: ModelRef[];
|
|
@@ -668,10 +662,6 @@ export interface MethodMap {
|
|
|
668
662
|
request: SceneDeleteRequest;
|
|
669
663
|
response: SceneDeleteResponse;
|
|
670
664
|
};
|
|
671
|
-
'scene.setShortcut': {
|
|
672
|
-
request: SceneSetShortcutRequest;
|
|
673
|
-
response: SceneSetShortcutResponse;
|
|
674
|
-
};
|
|
675
665
|
/** Live edit of the active scene's sections; applies next frame, persists debounced. */
|
|
676
666
|
'scene.patch': {
|
|
677
667
|
request: ScenePatchRequest;
|
|
@@ -724,7 +714,7 @@ export interface MethodMap {
|
|
|
724
714
|
request: InstanceSetPrimaryRequest;
|
|
725
715
|
response: InstanceSetPrimaryResponse;
|
|
726
716
|
};
|
|
727
|
-
/** Drives the desktop's editing selection (
|
|
717
|
+
/** Drives the desktop's editing selection (handles and inspector); ephemeral, never persisted. */
|
|
728
718
|
'selection.set': {
|
|
729
719
|
request: SelectionSetRequest;
|
|
730
720
|
response: SelectionSetResponse;
|
|
@@ -842,13 +832,13 @@ export interface MethodMap {
|
|
|
842
832
|
request: HotkeyTriggerRequest;
|
|
843
833
|
response: HotkeyTriggerResponse;
|
|
844
834
|
};
|
|
845
|
-
'
|
|
846
|
-
request:
|
|
847
|
-
response:
|
|
835
|
+
'automation.list': {
|
|
836
|
+
request: AutomationListRequest;
|
|
837
|
+
response: AutomationListResponse;
|
|
848
838
|
};
|
|
849
|
-
'
|
|
850
|
-
request:
|
|
851
|
-
response:
|
|
839
|
+
'automation.run': {
|
|
840
|
+
request: AutomationRunRequest;
|
|
841
|
+
response: AutomationRunResponse;
|
|
852
842
|
};
|
|
853
843
|
'model.list': {
|
|
854
844
|
request: ModelListRequest;
|
package/dist/wire/protocol.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { InjectTarget } from './types.ts';
|
|
2
2
|
/** Bumped on breaking wire changes; the server reports it in `hello` and clients warn on mismatch. */
|
|
3
|
-
export declare const PROTOCOL_VERSION =
|
|
3
|
+
export declare const PROTOCOL_VERSION = 4;
|
|
4
4
|
/** Default port the Persona API server listens on (user-configurable in the app). */
|
|
5
5
|
export declare const DEFAULT_API_PORT = 25034;
|
|
6
6
|
/** Default host clients dial: the server binds loopback unless LAN is opted in. */
|
|
7
7
|
export declare const DEFAULT_API_HOST = "127.0.0.1";
|
|
8
|
+
/** Scene activation waits for asset preparation before committing the new scene. */
|
|
9
|
+
export declare const SCENE_ACTIVATION_TIMEOUT_MS = 120000;
|
|
8
10
|
/** Server close code: the session's API key was revoked. Terminal — the client must not redial. */
|
|
9
11
|
export declare const CLOSE_KEY_REVOKED = 4001;
|
|
10
12
|
/** Server close code: the user disconnected this session from Persona's settings. Terminal — the client must not redial. */
|
package/dist/wire/protocol.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/** Bumped on breaking wire changes; the server reports it in `hello` and clients warn on mismatch. */
|
|
2
|
-
export const PROTOCOL_VERSION =
|
|
2
|
+
export const PROTOCOL_VERSION = 4;
|
|
3
3
|
/** Default port the Persona API server listens on (user-configurable in the app). */
|
|
4
4
|
export const DEFAULT_API_PORT = 25034;
|
|
5
5
|
/** Default host clients dial: the server binds loopback unless LAN is opted in. */
|
|
6
6
|
export const DEFAULT_API_HOST = '127.0.0.1';
|
|
7
|
+
/** Scene activation waits for asset preparation before committing the new scene. */
|
|
8
|
+
export const SCENE_ACTIVATION_TIMEOUT_MS = 120_000;
|
|
7
9
|
/** Server close code: the session's API key was revoked. Terminal — the client must not redial. */
|
|
8
10
|
export const CLOSE_KEY_REVOKED = 4001;
|
|
9
11
|
/** Server close code: the user disconnected this session from Persona's settings. Terminal — the client must not redial. */
|
package/dist/wire/schemas.d.ts
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import * as z from 'zod';
|
|
2
2
|
import type { MethodName } from './methods.ts';
|
|
3
3
|
import type { HotkeyConfig, ObjectContent } from './types.ts';
|
|
4
|
+
/** A complete transition replacement; scene.patch remains stage-owned for its other slices. */
|
|
5
|
+
export declare const SceneTransitionSchema: z.ZodObject<{
|
|
6
|
+
type: z.ZodEnum<{
|
|
7
|
+
circle: "circle";
|
|
8
|
+
image: "image";
|
|
9
|
+
video: "video";
|
|
10
|
+
cut: "cut";
|
|
11
|
+
fade: "fade";
|
|
12
|
+
wipe: "wipe";
|
|
13
|
+
}>;
|
|
14
|
+
durationMs: z.ZodNumber;
|
|
15
|
+
color: z.ZodString;
|
|
16
|
+
assetId: z.ZodNullable<z.ZodString>;
|
|
17
|
+
switchPoint: z.ZodNumber;
|
|
18
|
+
autoFade: z.ZodDefault<z.ZodBoolean>;
|
|
19
|
+
fadeInMs: z.ZodDefault<z.ZodNumber>;
|
|
20
|
+
fadeOutMs: z.ZodDefault<z.ZodNumber>;
|
|
21
|
+
}, z.core.$strip>;
|
|
4
22
|
export declare const InjectTargetSchema: z.ZodObject<{
|
|
5
23
|
type: z.ZodEnum<{
|
|
6
24
|
input: "input";
|
|
@@ -41,7 +59,6 @@ export declare const SettingsPatchSchema: z.ZodObject<{
|
|
|
41
59
|
performance: z.ZodOptional<z.ZodObject<{
|
|
42
60
|
showFps: z.ZodOptional<z.ZodBoolean>;
|
|
43
61
|
fpsLimit: z.ZodOptional<z.ZodNumber>;
|
|
44
|
-
selectionOutline: z.ZodOptional<z.ZodBoolean>;
|
|
45
62
|
effectsQuality: z.ZodOptional<z.ZodEnum<{
|
|
46
63
|
low: "low";
|
|
47
64
|
medium: "medium";
|
|
@@ -128,10 +145,6 @@ export declare const requestSchemas: {
|
|
|
128
145
|
'scene.delete': z.ZodObject<{
|
|
129
146
|
sceneId: z.ZodString;
|
|
130
147
|
}, z.core.$strip>;
|
|
131
|
-
'scene.setShortcut': z.ZodObject<{
|
|
132
|
-
sceneId: z.ZodString;
|
|
133
|
-
accelerator: z.ZodNullable<z.ZodString>;
|
|
134
|
-
}, z.core.$strip>;
|
|
135
148
|
'instance.add': z.ZodObject<{
|
|
136
149
|
modelId: z.ZodString;
|
|
137
150
|
}, z.core.$strip>;
|
|
@@ -164,8 +177,8 @@ export declare const requestSchemas: {
|
|
|
164
177
|
'hotkey.trigger': z.ZodObject<{
|
|
165
178
|
hotkeyId: z.ZodString;
|
|
166
179
|
}, z.core.$strip>;
|
|
167
|
-
'
|
|
168
|
-
|
|
180
|
+
'automation.run': z.ZodObject<{
|
|
181
|
+
automationId: z.ZodString;
|
|
169
182
|
}, z.core.$strip>;
|
|
170
183
|
'tracking.addSource': z.ZodObject<{
|
|
171
184
|
kind: z.ZodEnum<{
|
|
@@ -248,7 +261,6 @@ export declare const requestSchemas: {
|
|
|
248
261
|
performance: z.ZodOptional<z.ZodObject<{
|
|
249
262
|
showFps: z.ZodOptional<z.ZodBoolean>;
|
|
250
263
|
fpsLimit: z.ZodOptional<z.ZodNumber>;
|
|
251
|
-
selectionOutline: z.ZodOptional<z.ZodBoolean>;
|
|
252
264
|
effectsQuality: z.ZodOptional<z.ZodEnum<{
|
|
253
265
|
low: "low";
|
|
254
266
|
medium: "medium";
|
package/dist/wire/schemas.js
CHANGED
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
import * as z from 'zod';
|
|
2
2
|
import { CONTROLLER_DEAD_ZONE_MAX } from "../values/controller.js";
|
|
3
3
|
import { isRecord } from "../values/guards.js";
|
|
4
|
-
import { SPEECH_URL_MAX_LENGTH, STORAGE_KEY_MAX_LENGTH, STORAGE_VALUE_MAX_LENGTH } from "../values/limits.js";
|
|
4
|
+
import { SCENE_COLOR_RE, SPEECH_URL_MAX_LENGTH, STORAGE_KEY_MAX_LENGTH, STORAGE_VALUE_MAX_LENGTH, } from "../values/limits.js";
|
|
5
5
|
import { LIP_SYNC_CALIBRATION_ACTIONS, LIP_SYNC_GAIN_MAX, LIP_SYNC_MODES, LIP_SYNC_NOISE_GATE_MIN, LIP_SYNC_PHONEMES, LIP_SYNC_SMOOTHING_MAX, } from "../values/lipsync.js";
|
|
6
|
-
import {
|
|
6
|
+
import { SCENE_TRANSITION_DURATION_MAX_MS, SCENE_TRANSITION_DURATION_MIN_MS, SCENE_TRANSITION_FADE_DEFAULT_MS, SCENE_TRANSITION_SWITCH_POINT_MAX, SCENE_TRANSITION_SWITCH_POINT_MIN, SCENE_TRANSITION_TYPES, } from "../values/scene-transition.js";
|
|
7
|
+
import { ASSET_KINDS, EFFECTS_QUALITY_LEVELS, INJECT_TARGET_TYPES, LIVE2D_ENGINES, MEDIAPIPE_DELEGATES, POSE_SOURCE_IDS, TRACKING_SOURCE_IDS, TRACKING_SOURCE_KINDS, } from "./types.js";
|
|
7
8
|
// Runtime validation for the request side of the wire. Schemas exist for the
|
|
8
9
|
// methods whose params the app's main process consumes directly; methods without
|
|
9
10
|
// one are stage-owned — the renderer validates and heals them (same rules as the
|
|
10
11
|
// panel). Fields marked z.custom are deliberately gated shallowly here because
|
|
11
12
|
// the app heals them into shape server-side.
|
|
12
13
|
const nonEmpty = z.string().min(1);
|
|
14
|
+
/** A complete transition replacement; scene.patch remains stage-owned for its other slices. */
|
|
15
|
+
export const SceneTransitionSchema = z.object({
|
|
16
|
+
type: z.enum(SCENE_TRANSITION_TYPES),
|
|
17
|
+
durationMs: z.number().min(SCENE_TRANSITION_DURATION_MIN_MS).max(SCENE_TRANSITION_DURATION_MAX_MS),
|
|
18
|
+
color: z.string().regex(SCENE_COLOR_RE),
|
|
19
|
+
assetId: nonEmpty.refine(v => v.trim() !== '', 'assetId must not be blank').nullable(),
|
|
20
|
+
switchPoint: z.number().min(SCENE_TRANSITION_SWITCH_POINT_MIN).max(SCENE_TRANSITION_SWITCH_POINT_MAX),
|
|
21
|
+
autoFade: z.boolean().default(false),
|
|
22
|
+
fadeInMs: z.number().min(0).max(SCENE_TRANSITION_DURATION_MAX_MS).default(SCENE_TRANSITION_FADE_DEFAULT_MS),
|
|
23
|
+
fadeOutMs: z.number().min(0).max(SCENE_TRANSITION_DURATION_MAX_MS).default(SCENE_TRANSITION_FADE_DEFAULT_MS),
|
|
24
|
+
});
|
|
13
25
|
const port = z.number().int().min(1).max(65535);
|
|
14
26
|
const lipSyncCalibration = z.discriminatedUnion('action', [
|
|
15
27
|
z.object({ action: z.enum(LIP_SYNC_CALIBRATION_ACTIONS) }),
|
|
@@ -28,10 +40,10 @@ const mediapipePatch = z.object({
|
|
|
28
40
|
face: z.boolean().optional(),
|
|
29
41
|
hands: z.boolean().optional(),
|
|
30
42
|
body: z.boolean().optional(),
|
|
31
|
-
delegate: z.enum(
|
|
43
|
+
delegate: z.enum(MEDIAPIPE_DELEGATES).optional(),
|
|
32
44
|
});
|
|
33
45
|
export const InjectTargetSchema = z.object({
|
|
34
|
-
type: z.enum(
|
|
46
|
+
type: z.enum(INJECT_TARGET_TYPES),
|
|
35
47
|
id: nonEmpty,
|
|
36
48
|
instanceId: nonEmpty.optional(),
|
|
37
49
|
});
|
|
@@ -48,10 +60,9 @@ export const SettingsPatchSchema = z.object({
|
|
|
48
60
|
.object({
|
|
49
61
|
showFps: z.boolean().optional(),
|
|
50
62
|
fpsLimit: z.number().optional(),
|
|
51
|
-
|
|
52
|
-
effectsQuality: z.enum(['high', 'medium', 'low']).optional(),
|
|
63
|
+
effectsQuality: z.enum(EFFECTS_QUALITY_LEVELS).optional(),
|
|
53
64
|
renderScale: z.number().optional(),
|
|
54
|
-
live2dEngine: z.enum(
|
|
65
|
+
live2dEngine: z.enum(LIVE2D_ENGINES).optional(),
|
|
55
66
|
})
|
|
56
67
|
.optional(),
|
|
57
68
|
});
|
|
@@ -95,7 +106,6 @@ export const requestSchemas = {
|
|
|
95
106
|
'scene.duplicate': z.object({ sceneId: nonEmpty }),
|
|
96
107
|
'scene.rename': z.object({ sceneId: nonEmpty, name: nonEmpty }),
|
|
97
108
|
'scene.delete': z.object({ sceneId: nonEmpty }),
|
|
98
|
-
'scene.setShortcut': z.object({ sceneId: nonEmpty, accelerator: nonEmpty.nullable() }),
|
|
99
109
|
'instance.add': z.object({ modelId: nonEmpty }),
|
|
100
110
|
'instance.setModel': z.object({ instanceId: nonEmpty, modelId: nonEmpty }),
|
|
101
111
|
'object.add': z.object({
|
|
@@ -114,7 +124,7 @@ export const requestSchemas = {
|
|
|
114
124
|
config: z.custom(isRecord, 'config must be a hotkey config'),
|
|
115
125
|
}),
|
|
116
126
|
'hotkey.trigger': z.object({ hotkeyId: nonEmpty }),
|
|
117
|
-
'
|
|
127
|
+
'automation.run': z.object({ automationId: nonEmpty }),
|
|
118
128
|
'tracking.addSource': z.object({
|
|
119
129
|
// Straight off the kind registry, for the same reason as ASSET_KINDS below: a schema
|
|
120
130
|
// narrower than the constant answers invalid-params for a kind the app itself accepts.
|