@chuzi/shared 1.3.22 → 1.3.23

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.
@@ -284,6 +284,18 @@ interface PaginatedResponse<T> {
284
284
  to: number | null;
285
285
  total: number;
286
286
  }
287
+ interface TextLine {
288
+ id: string;
289
+ html: string;
290
+ appear_at_ms: number;
291
+ fade_in_ms: number;
292
+ fade_out_ms: number;
293
+ duration_ms: number;
294
+ }
295
+ interface SceneTextContent {
296
+ html: string;
297
+ lines?: TextLine[];
298
+ }
287
299
  interface SceneListItem {
288
300
  id: string;
289
301
  story_id: string;
@@ -295,9 +307,7 @@ interface SceneListItem {
295
307
  media_id: string | null;
296
308
  alt_media_id: string | null;
297
309
  media_mode: "text" | "imagery" | "film" | null;
298
- text_content: {
299
- html: string;
300
- } | null;
310
+ text_content: SceneTextContent | null;
301
311
  text_style: {
302
312
  font_family?: string | null;
303
313
  text_color?: string | null;
@@ -312,9 +322,7 @@ interface UpdateSceneRequest {
312
322
  media_id?: string | null;
313
323
  alt_media_id?: string | null;
314
324
  media_mode?: "text" | "imagery" | "film" | null;
315
- text_content?: {
316
- html: string;
317
- } | null;
325
+ text_content?: SceneTextContent | null;
318
326
  text_style?: {
319
327
  font_family?: string | null;
320
328
  text_color?: string | null;
@@ -559,4 +567,4 @@ declare function computeSceneVisibility(sceneList: Pick<SceneListItem, "is_title
559
567
  endingSeen: boolean;
560
568
  }): SceneVisibility[];
561
569
 
562
- export { type AcceptGenerationRequest, type AcceptGenerationResponse, type AiGeneration, type AiGenerationShowResponse, type AiGenerationStatus, type BookmarkListItem, type BookmarkListResponse, type BookmarkResponse, type CatalogResponse, type ContentRating, type ContentRatingDefinition, type CreateSceneActionRequest, type CreateSceneRequest, type CreateStoryRequest, type EngagementResponse, type GenerateImageRequest, type GenerateImageResponse, type HistoryEntry, type LocaleId, type MagicLinkRequest, type MagicLinkRequestResponse, type MagicLinkVerifyRequest, type MagicLinkVerifyResponse, type MediaItem, type MineResponse, type OidcExchangeRequest, type OidcExchangeResponse, type PaginatedLink, type PaginatedResponse, type PasswordLoginRequest, type PasswordLoginResponse, type PlayUrlResponse, type PopularChoice, type PublicDirectorProfile, type RealmConfigResponse, type RealmDefinition, type RealmId, type RegisterMediaRequest, type RegisterMediaResponse, type RejectGenerationRequest, type RejectGenerationResponse, type SaveBookmarkRequest, type SceneActionItem, type SceneActionPayload, type SceneChoice, type SceneListItem, type SceneMapEntry, type SceneMapResponse, type SceneNode, type SceneVisibility, type SourceUrlResponse, type StateUpdate, type StoryListItem, type StoryPreview, type StoryProgress, type StoryStyleResponse, type TagListResponse, type TrackEngagementRequest, type TranscodeRequest, type TranscodeResponse, type TreeGraph, type TreeGraphEdge, type TreeGraphNode, type UpdateLocaleRequest, type UpdateLocaleResponse, type UpdateProfileRequest, type UpdateProfileResponse, type UpdateRealmRequest, type UpdateRealmResponse, type UpdateSceneActionRequest, type UpdateSceneRequest, type UpdateStoryRequest, type UploadUrlRequest, type UploadUrlResponse, type UserProfile, type UsernameAvailabilityResponse, type VisibilityCondition, type VisibilityRules, type WatchSnapshot, computeSceneVisibility };
570
+ export { type AcceptGenerationRequest, type AcceptGenerationResponse, type AiGeneration, type AiGenerationShowResponse, type AiGenerationStatus, type BookmarkListItem, type BookmarkListResponse, type BookmarkResponse, type CatalogResponse, type ContentRating, type ContentRatingDefinition, type CreateSceneActionRequest, type CreateSceneRequest, type CreateStoryRequest, type EngagementResponse, type GenerateImageRequest, type GenerateImageResponse, type HistoryEntry, type LocaleId, type MagicLinkRequest, type MagicLinkRequestResponse, type MagicLinkVerifyRequest, type MagicLinkVerifyResponse, type MediaItem, type MineResponse, type OidcExchangeRequest, type OidcExchangeResponse, type PaginatedLink, type PaginatedResponse, type PasswordLoginRequest, type PasswordLoginResponse, type PlayUrlResponse, type PopularChoice, type PublicDirectorProfile, type RealmConfigResponse, type RealmDefinition, type RealmId, type RegisterMediaRequest, type RegisterMediaResponse, type RejectGenerationRequest, type RejectGenerationResponse, type SaveBookmarkRequest, type SceneActionItem, type SceneActionPayload, type SceneChoice, type SceneListItem, type SceneMapEntry, type SceneMapResponse, type SceneNode, type SceneTextContent, type SceneVisibility, type SourceUrlResponse, type StateUpdate, type StoryListItem, type StoryPreview, type StoryProgress, type StoryStyleResponse, type TagListResponse, type TextLine, type TrackEngagementRequest, type TranscodeRequest, type TranscodeResponse, type TreeGraph, type TreeGraphEdge, type TreeGraphNode, type UpdateLocaleRequest, type UpdateLocaleResponse, type UpdateProfileRequest, type UpdateProfileResponse, type UpdateRealmRequest, type UpdateRealmResponse, type UpdateSceneActionRequest, type UpdateSceneRequest, type UpdateStoryRequest, type UploadUrlRequest, type UploadUrlResponse, type UserProfile, type UsernameAvailabilityResponse, type VisibilityCondition, type VisibilityRules, type WatchSnapshot, computeSceneVisibility };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/index.ts"],"names":[],"mappings":";AAmpBO,SAAS,sBAAA,CACd,WACA,IAAA,EACmB;AACnB,EAAA,IAAI,IAAA,CAAK,SAAA,IAAa,IAAA,CAAK,UAAA,EAAY;AACrC,IAAA,OAAO,SAAA,CAAU,IAAI,OAAO,EAAE,WAAW,IAAA,EAAM,MAAA,EAAQ,OAAM,CAAE,CAAA;AAAA,EACjE;AACA,EAAA,OAAO,SAAA,CAAU,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,IAC/B,WAAW,KAAA,CAAM,QAAA;AAAA,IACjB,MAAA,EAAQ,CAAC,KAAA,CAAM;AAAA,GACjB,CAAE,CAAA;AACJ","file":"index.js","sourcesContent":["// ── Auth ──\n\nexport interface MagicLinkRequest {\n email: string;\n username?: string;\n device_name?: string;\n}\n\nexport interface MagicLinkRequestResponse {\n message: string;\n}\n\nexport interface MagicLinkVerifyRequest {\n email: string;\n token: string;\n device_name?: string;\n}\n\nexport interface MagicLinkVerifyResponse {\n token?: string;\n user: UserProfile;\n}\n\nexport interface OidcExchangeRequest {\n code: string;\n code_verifier: string;\n redirect_uri: string;\n device_name?: string;\n}\n\nexport interface OidcExchangeResponse {\n token?: string;\n user: UserProfile;\n}\n\nexport interface PasswordLoginRequest {\n email: string;\n password: string;\n device_name?: string;\n}\n\nexport interface PasswordLoginResponse {\n token?: string;\n user: UserProfile;\n}\n\n// ── User ──\n\nexport interface UserProfile {\n id: string;\n name: string;\n username: string;\n email: string;\n realm: RealmId | null;\n needs_realm_choice: boolean;\n locale: LocaleId | null;\n avatar_url: string | null;\n is_admin: boolean;\n created_at: string;\n}\n\nexport interface UpdateRealmRequest {\n realm: RealmId;\n}\n\nexport interface UpdateRealmResponse {\n realm: RealmId;\n user: UserProfile;\n}\n\nexport interface UpdateProfileRequest {\n name?: string;\n username?: string;\n}\n\nexport interface UpdateProfileResponse {\n user: UserProfile;\n}\n\nexport interface UsernameAvailabilityResponse {\n username: string;\n available: boolean;\n suggestion?: string;\n}\n\nexport interface PublicDirectorProfile {\n id: string;\n name: string;\n avatar_url: string | null;\n realm: RealmId | null;\n stories_count: number;\n}\n\n// ── Catalog ──\n\nexport interface StoryListItem {\n id: string;\n title: string;\n description: string | null;\n genre: string | null;\n content_rating: ContentRating | null;\n published: boolean;\n published_version: number;\n watch_starts_count: number;\n choice_clicks_count: number;\n scenes_count: number;\n choices_count: number;\n tags: string[];\n creator: {\n id: string;\n name: string;\n } | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface StoryPreview {\n source: \"trailer\" | \"title_scene\" | \"none\";\n title: string;\n preview_url: string | null;\n media_type: string | null;\n is_ready: boolean;\n}\n\nexport interface PopularChoice {\n label: string;\n click_count: number;\n}\n\nexport interface StoryProgress {\n last_scene_id: string | null;\n bookmark_code: string | null;\n playback_seconds: number;\n watched_version: number;\n last_watched_at: string | null;\n}\n\nexport interface CatalogResponse {\n data: StoryListItem[];\n meta: {\n previews: Record<string, StoryPreview>;\n popular_choices: Record<string, PopularChoice[]>;\n creator_avatars: Record<string, string>;\n coverboxes: Record<string, string | null>;\n progress: Record<string, StoryProgress>;\n };\n}\n\nexport interface MineResponse {\n stories: StoryListItem[];\n data?: StoryListItem[];\n progress?: Record<string, StoryProgress>;\n meta: {\n coverboxes: Record<string, string | null>;\n };\n}\n\n// ── Watch / Scene Map ──\n\nexport interface SceneChoice {\n id: string;\n label: string;\n choice_type: string;\n choice_icon: string | null;\n choice_icon_media_id: string | null;\n choice_icon_url: string | null;\n reveal_mode: string;\n start_time_seconds: number | null;\n pause_for_choice: boolean;\n end_time_seconds: number | null;\n target_scene_id: string;\n x: number;\n y: number;\n w: number;\n h: number;\n visibility_rules: VisibilityRules | null;\n state_updates: StateUpdate[];\n}\n\nexport interface VisibilityRules {\n mode: \"all\" | \"any\";\n conditions: VisibilityCondition[];\n}\n\nexport interface VisibilityCondition {\n variable?: string;\n key?: string;\n operator?: string;\n value?: string;\n}\n\nexport interface StateUpdate {\n variable?: string;\n key?: string;\n action?: string;\n value?: string;\n}\n\nexport interface SceneNode {\n type: string;\n properties?: Record<string, unknown>;\n children?: SceneNode[];\n}\n\nexport type SceneActionPayload = Record<string, unknown> | unknown[];\n\nexport interface SceneMapEntry {\n scene_id: string;\n scene_title: string;\n color: string | null;\n is_title: boolean;\n media_title: string | null;\n media_type: string | null;\n media_url: string | null;\n stream_status: string | null;\n choice_style: string;\n choice_overlay_mode: string;\n goto_scene_id: string | null;\n choices: SceneChoice[];\n nodes: SceneNode[];\n}\n\nexport interface TreeGraphNode {\n id: string;\n title: string;\n is_title: boolean;\n is_end: boolean;\n level: number;\n index: number;\n x: number;\n y: number;\n color: string | null;\n}\n\nexport interface TreeGraphEdge {\n id: string;\n source: string;\n target: string;\n type: \"choice\" | \"go_to_scene\";\n}\n\nexport interface TreeGraph {\n nodes: TreeGraphNode[];\n edges: TreeGraphEdge[];\n meta: {\n root_id: string | null;\n level_count: number;\n };\n}\n\nexport interface WatchSnapshot {\n scene_id: string | null;\n state: Record<string, string>;\n history: HistoryEntry[];\n path: string[];\n visited_scene_ids?: string[];\n playback_seconds: number;\n}\n\nexport interface HistoryEntry {\n choice_id: string;\n scene_id: string;\n target_scene_id: string | null;\n at: string | null;\n path_index: number | null;\n}\n\nexport interface SceneMapResponse {\n story: {\n id: string;\n title: string;\n description: string | null;\n genre: string | null;\n content_rating: ContentRating | null;\n published_version: number;\n watch_starts_count: number;\n choice_clicks_count: number;\n };\n start_scene_id: string;\n scene_map: Record<string, SceneMapEntry>;\n tree_graph: TreeGraph;\n initial_snapshot: WatchSnapshot;\n initial_bookmark_code: string | null;\n}\n\n// ── Engagement ──\n\nexport interface TrackEngagementRequest {\n event: \"play_start\" | \"choice_click\";\n choice_id?: string;\n}\n\nexport interface EngagementResponse {\n watch_starts_count: number;\n choice_clicks_count: number;\n}\n\n// ── Bookmarks ──\n\nexport interface SaveBookmarkRequest {\n snapshot: WatchSnapshot;\n}\n\nexport interface BookmarkResponse {\n code: string;\n snapshot: WatchSnapshot;\n}\n\nexport interface BookmarkListItem {\n code: string;\n snapshot: WatchSnapshot;\n updated_at: string;\n}\n\nexport interface BookmarkListResponse {\n bookmarks: BookmarkListItem[];\n}\n\n// ── Pagination ──\n\nexport interface PaginatedLink {\n url: string | null;\n label: string;\n active: boolean;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n current_page: number;\n first_page_url: string;\n from: number | null;\n last_page: number;\n last_page_url: string;\n links: PaginatedLink[];\n next_page_url: string | null;\n path: string;\n per_page: number;\n prev_page_url: string | null;\n to: number | null;\n total: number;\n}\n\n// ── Scenes ──\n\nexport interface SceneListItem {\n id: string;\n story_id: string;\n title: string;\n order: number;\n is_title: boolean;\n is_end: boolean;\n color: string | null;\n media_id: string | null;\n alt_media_id: string | null;\n media_mode: \"text\" | \"imagery\" | \"film\" | null;\n text_content: {\n html: string;\n } | null;\n text_style: {\n font_family?: string | null;\n text_color?: string | null;\n background_color?: string | null;\n } | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UpdateSceneRequest {\n title?: string;\n order?: number;\n media_id?: string | null;\n alt_media_id?: string | null;\n media_mode?: \"text\" | \"imagery\" | \"film\" | null;\n text_content?: {\n html: string;\n } | null;\n text_style?: {\n font_family?: string | null;\n text_color?: string | null;\n background_color?: string | null;\n } | null;\n color?: string | null;\n is_title?: boolean;\n is_end?: boolean;\n choice_style?: string | null;\n choice_overlay_mode?: string | null;\n choice_reveal_mode?: string | null;\n choice_start_time_seconds?: number | null;\n choice_pause_for_choice?: boolean;\n choice_end_time_seconds?: number | null;\n}\n\nexport interface CreateSceneRequest {\n story_id: string;\n title: string;\n order?: number;\n is_title?: boolean;\n is_end?: boolean;\n}\n\nexport interface SceneActionItem {\n id: string;\n scene_id: string;\n name: string;\n type: string | null;\n scene_choice_id: string | null;\n order: number;\n duration: number;\n properties: SceneActionPayload | null;\n subproperties: SceneActionPayload | null;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface CreateSceneActionRequest {\n scene_id: string;\n name: string;\n type?: string | null;\n order?: number;\n duration?: number;\n properties?: SceneActionPayload | null;\n subproperties?: SceneActionPayload | null;\n}\n\nexport interface UpdateSceneActionRequest {\n name?: string;\n type?: string | null;\n order?: number;\n duration?: number;\n properties?: SceneActionPayload;\n subproperties?: SceneActionPayload;\n}\n\n// ── AI Generation ──\n\nexport type AiGenerationStatus =\n | \"pending\"\n | \"generating\"\n | \"ready\"\n | \"failed\"\n | \"accepted\"\n | \"rejected\";\n\nexport interface GenerateImageRequest {\n story_id: string;\n scene_id?: string;\n prompt: string;\n mood?: string;\n visual_style?: string;\n rejection_feedback?: string;\n previous_generation_id?: string;\n}\n\nexport interface AiGeneration {\n id: string;\n story_id: string;\n scene_id: string | null;\n status: AiGenerationStatus;\n user_prompt: string;\n style_context: {\n mood?: string;\n visual_style?: string;\n subject_prompt: string;\n full_prompt: string;\n negative_prompt?: string;\n };\n preview_url?: string;\n rejection_feedback: string | null;\n media_id: string | null;\n attempt_number: number;\n credits_charged: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface GenerateImageResponse {\n generation: AiGeneration;\n balance: { watch: number; create: number };\n}\n\nexport interface AiGenerationShowResponse {\n generation: AiGeneration;\n}\n\nexport interface AcceptGenerationRequest {\n scene_id: string;\n}\n\nexport interface AcceptGenerationResponse {\n generation: AiGeneration;\n scene: SceneListItem;\n media: MediaItem;\n}\n\nexport interface RejectGenerationRequest {\n feedback: string;\n}\n\nexport interface RejectGenerationResponse {\n generation: AiGeneration;\n}\n\nexport interface StoryStyleResponse {\n has_style: boolean;\n style_context: AiGeneration[\"style_context\"] | null;\n}\n\n// ── Media ──\n\nexport interface MediaItem {\n id: string;\n user_id: string;\n s3_key: string;\n source_path: string;\n output_prefix: string | null;\n status: \"uploaded\" | \"processing\" | \"ready\" | \"error\";\n meta: Record<string, unknown>;\n order: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UploadUrlRequest {\n filename: string;\n contentType: string;\n}\n\nexport interface UploadUrlResponse {\n key: string;\n uploadUrl: string;\n}\n\nexport interface RegisterMediaRequest {\n key: string;\n s3_key: string;\n filename: string;\n content_type?: string;\n title?: string;\n file_size?: number;\n}\n\nexport interface RegisterMediaResponse extends MediaItem {\n credits_charged: number;\n balance: number;\n}\n\nexport interface TranscodeRequest {\n media_id: string;\n}\n\nexport interface TranscodeResponse {\n message: string;\n job_id: string | null;\n manifest_path?: string;\n}\n\nexport interface PlayUrlResponse {\n play_url: string;\n status: string;\n}\n\nexport interface SourceUrlResponse {\n url: string;\n}\n\n// ── Story authoring ──\n\nexport interface CreateStoryRequest {\n title: string;\n description?: string | null;\n genre?: string | null;\n content_rating?: ContentRating | null;\n}\n\nexport interface UpdateStoryRequest {\n title?: string;\n description?: string | null;\n genre?: string | null;\n content_rating?: ContentRating | null;\n published?: boolean;\n tags?: string[];\n}\n\nexport interface TagListResponse {\n data: string[];\n}\n\n// ── Content Ratings ──\n\nexport type ContentRating = \"G\" | \"PG\" | \"PG-13\" | \"R\" | \"NC-17\";\n\nexport interface ContentRatingDefinition {\n id: ContentRating;\n label: string;\n description: string;\n}\n\n// ── Realm Config ──\n\nexport type RealmId = \"cosmos\" | \"wilds\";\n\n/** Supported UI locales — matches PHP `chuzi_realms.supported_locales`. */\nexport type LocaleId = \"en\" | \"es\" | \"fr\" | \"de\" | \"pt\";\n\nexport interface RealmDefinition {\n label: string;\n short_label: string;\n /** Canonical English lexicon (always present). */\n lexicon: Record<string, string>;\n /** Optional per-locale overrides; missing keys fall through to `lexicon`. */\n locales?: Partial<Record<LocaleId, Record<string, string>>>;\n}\n\nexport interface RealmConfigResponse {\n realms: Record<RealmId, RealmDefinition>;\n fallback_lexicon: Record<string, string>;\n fallback_locales?: Partial<Record<LocaleId, Record<string, string>>>;\n intro: {\n line1: string;\n line2: string;\n };\n intro_locales?: Partial<Record<LocaleId, { line1: string; line2: string }>>;\n profile: {\n title: string;\n current_prefix: string;\n switch_prompt: string;\n };\n profile_locales?: Partial<Record<LocaleId, { title: string; current_prefix: string; switch_prompt: string }>>;\n allowed_realm_ids: RealmId[];\n supported_locales: LocaleId[];\n locale_labels?: Partial<Record<LocaleId, string>>;\n}\n\nexport interface UpdateLocaleRequest {\n locale: LocaleId;\n}\n\nexport interface UpdateLocaleResponse {\n locale: LocaleId;\n}\n\n// ── Scene Visibility ──\n\nexport interface SceneVisibility {\n /** Whether the user can navigate to this scene-star. */\n navigable: boolean;\n /** Whether the star/edge should render at reduced opacity. */\n dimmed: boolean;\n}\n\n/**\n * Compute per-scene navigable/dimmed flags for a constellation.\n *\n * Rules:\n * - If `isCreator` is true, everything is navigable and bright.\n * - Title scenes are always navigable and bright.\n * - If the user has watched the ending (`endingSeen`), all scenes unlock.\n * - Otherwise non-title scenes are locked and dimmed.\n */\nexport function computeSceneVisibility(\n sceneList: Pick<SceneListItem, \"is_title\" | \"is_end\">[],\n opts: { isCreator: boolean; endingSeen: boolean },\n): SceneVisibility[] {\n if (opts.isCreator || opts.endingSeen) {\n return sceneList.map(() => ({ navigable: true, dimmed: false }));\n }\n return sceneList.map((scene) => ({\n navigable: scene.is_title,\n dimmed: !scene.is_title,\n }));\n}\n"]}
1
+ {"version":3,"sources":["../../src/types/index.ts"],"names":[],"mappings":";AA6pBO,SAAS,sBAAA,CACd,WACA,IAAA,EACmB;AACnB,EAAA,IAAI,IAAA,CAAK,SAAA,IAAa,IAAA,CAAK,UAAA,EAAY;AACrC,IAAA,OAAO,SAAA,CAAU,IAAI,OAAO,EAAE,WAAW,IAAA,EAAM,MAAA,EAAQ,OAAM,CAAE,CAAA;AAAA,EACjE;AACA,EAAA,OAAO,SAAA,CAAU,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,IAC/B,WAAW,KAAA,CAAM,QAAA;AAAA,IACjB,MAAA,EAAQ,CAAC,KAAA,CAAM;AAAA,GACjB,CAAE,CAAA;AACJ","file":"index.js","sourcesContent":["// ── Auth ──\n\nexport interface MagicLinkRequest {\n email: string;\n username?: string;\n device_name?: string;\n}\n\nexport interface MagicLinkRequestResponse {\n message: string;\n}\n\nexport interface MagicLinkVerifyRequest {\n email: string;\n token: string;\n device_name?: string;\n}\n\nexport interface MagicLinkVerifyResponse {\n token?: string;\n user: UserProfile;\n}\n\nexport interface OidcExchangeRequest {\n code: string;\n code_verifier: string;\n redirect_uri: string;\n device_name?: string;\n}\n\nexport interface OidcExchangeResponse {\n token?: string;\n user: UserProfile;\n}\n\nexport interface PasswordLoginRequest {\n email: string;\n password: string;\n device_name?: string;\n}\n\nexport interface PasswordLoginResponse {\n token?: string;\n user: UserProfile;\n}\n\n// ── User ──\n\nexport interface UserProfile {\n id: string;\n name: string;\n username: string;\n email: string;\n realm: RealmId | null;\n needs_realm_choice: boolean;\n locale: LocaleId | null;\n avatar_url: string | null;\n is_admin: boolean;\n created_at: string;\n}\n\nexport interface UpdateRealmRequest {\n realm: RealmId;\n}\n\nexport interface UpdateRealmResponse {\n realm: RealmId;\n user: UserProfile;\n}\n\nexport interface UpdateProfileRequest {\n name?: string;\n username?: string;\n}\n\nexport interface UpdateProfileResponse {\n user: UserProfile;\n}\n\nexport interface UsernameAvailabilityResponse {\n username: string;\n available: boolean;\n suggestion?: string;\n}\n\nexport interface PublicDirectorProfile {\n id: string;\n name: string;\n avatar_url: string | null;\n realm: RealmId | null;\n stories_count: number;\n}\n\n// ── Catalog ──\n\nexport interface StoryListItem {\n id: string;\n title: string;\n description: string | null;\n genre: string | null;\n content_rating: ContentRating | null;\n published: boolean;\n published_version: number;\n watch_starts_count: number;\n choice_clicks_count: number;\n scenes_count: number;\n choices_count: number;\n tags: string[];\n creator: {\n id: string;\n name: string;\n } | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface StoryPreview {\n source: \"trailer\" | \"title_scene\" | \"none\";\n title: string;\n preview_url: string | null;\n media_type: string | null;\n is_ready: boolean;\n}\n\nexport interface PopularChoice {\n label: string;\n click_count: number;\n}\n\nexport interface StoryProgress {\n last_scene_id: string | null;\n bookmark_code: string | null;\n playback_seconds: number;\n watched_version: number;\n last_watched_at: string | null;\n}\n\nexport interface CatalogResponse {\n data: StoryListItem[];\n meta: {\n previews: Record<string, StoryPreview>;\n popular_choices: Record<string, PopularChoice[]>;\n creator_avatars: Record<string, string>;\n coverboxes: Record<string, string | null>;\n progress: Record<string, StoryProgress>;\n };\n}\n\nexport interface MineResponse {\n stories: StoryListItem[];\n data?: StoryListItem[];\n progress?: Record<string, StoryProgress>;\n meta: {\n coverboxes: Record<string, string | null>;\n };\n}\n\n// ── Watch / Scene Map ──\n\nexport interface SceneChoice {\n id: string;\n label: string;\n choice_type: string;\n choice_icon: string | null;\n choice_icon_media_id: string | null;\n choice_icon_url: string | null;\n reveal_mode: string;\n start_time_seconds: number | null;\n pause_for_choice: boolean;\n end_time_seconds: number | null;\n target_scene_id: string;\n x: number;\n y: number;\n w: number;\n h: number;\n visibility_rules: VisibilityRules | null;\n state_updates: StateUpdate[];\n}\n\nexport interface VisibilityRules {\n mode: \"all\" | \"any\";\n conditions: VisibilityCondition[];\n}\n\nexport interface VisibilityCondition {\n variable?: string;\n key?: string;\n operator?: string;\n value?: string;\n}\n\nexport interface StateUpdate {\n variable?: string;\n key?: string;\n action?: string;\n value?: string;\n}\n\nexport interface SceneNode {\n type: string;\n properties?: Record<string, unknown>;\n children?: SceneNode[];\n}\n\nexport type SceneActionPayload = Record<string, unknown> | unknown[];\n\nexport interface SceneMapEntry {\n scene_id: string;\n scene_title: string;\n color: string | null;\n is_title: boolean;\n media_title: string | null;\n media_type: string | null;\n media_url: string | null;\n stream_status: string | null;\n choice_style: string;\n choice_overlay_mode: string;\n goto_scene_id: string | null;\n choices: SceneChoice[];\n nodes: SceneNode[];\n}\n\nexport interface TreeGraphNode {\n id: string;\n title: string;\n is_title: boolean;\n is_end: boolean;\n level: number;\n index: number;\n x: number;\n y: number;\n color: string | null;\n}\n\nexport interface TreeGraphEdge {\n id: string;\n source: string;\n target: string;\n type: \"choice\" | \"go_to_scene\";\n}\n\nexport interface TreeGraph {\n nodes: TreeGraphNode[];\n edges: TreeGraphEdge[];\n meta: {\n root_id: string | null;\n level_count: number;\n };\n}\n\nexport interface WatchSnapshot {\n scene_id: string | null;\n state: Record<string, string>;\n history: HistoryEntry[];\n path: string[];\n visited_scene_ids?: string[];\n playback_seconds: number;\n}\n\nexport interface HistoryEntry {\n choice_id: string;\n scene_id: string;\n target_scene_id: string | null;\n at: string | null;\n path_index: number | null;\n}\n\nexport interface SceneMapResponse {\n story: {\n id: string;\n title: string;\n description: string | null;\n genre: string | null;\n content_rating: ContentRating | null;\n published_version: number;\n watch_starts_count: number;\n choice_clicks_count: number;\n };\n start_scene_id: string;\n scene_map: Record<string, SceneMapEntry>;\n tree_graph: TreeGraph;\n initial_snapshot: WatchSnapshot;\n initial_bookmark_code: string | null;\n}\n\n// ── Engagement ──\n\nexport interface TrackEngagementRequest {\n event: \"play_start\" | \"choice_click\";\n choice_id?: string;\n}\n\nexport interface EngagementResponse {\n watch_starts_count: number;\n choice_clicks_count: number;\n}\n\n// ── Bookmarks ──\n\nexport interface SaveBookmarkRequest {\n snapshot: WatchSnapshot;\n}\n\nexport interface BookmarkResponse {\n code: string;\n snapshot: WatchSnapshot;\n}\n\nexport interface BookmarkListItem {\n code: string;\n snapshot: WatchSnapshot;\n updated_at: string;\n}\n\nexport interface BookmarkListResponse {\n bookmarks: BookmarkListItem[];\n}\n\n// ── Pagination ──\n\nexport interface PaginatedLink {\n url: string | null;\n label: string;\n active: boolean;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n current_page: number;\n first_page_url: string;\n from: number | null;\n last_page: number;\n last_page_url: string;\n links: PaginatedLink[];\n next_page_url: string | null;\n path: string;\n per_page: number;\n prev_page_url: string | null;\n to: number | null;\n total: number;\n}\n\n// ── Scenes ──\n\nexport interface TextLine {\n id: string;\n html: string;\n appear_at_ms: number;\n fade_in_ms: number;\n fade_out_ms: number;\n duration_ms: number;\n}\n\nexport interface SceneTextContent {\n html: string;\n lines?: TextLine[];\n}\n\nexport interface SceneListItem {\n id: string;\n story_id: string;\n title: string;\n order: number;\n is_title: boolean;\n is_end: boolean;\n color: string | null;\n media_id: string | null;\n alt_media_id: string | null;\n media_mode: \"text\" | \"imagery\" | \"film\" | null;\n text_content: SceneTextContent | null;\n text_style: {\n font_family?: string | null;\n text_color?: string | null;\n background_color?: string | null;\n } | null;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UpdateSceneRequest {\n title?: string;\n order?: number;\n media_id?: string | null;\n alt_media_id?: string | null;\n media_mode?: \"text\" | \"imagery\" | \"film\" | null;\n text_content?: SceneTextContent | null;\n text_style?: {\n font_family?: string | null;\n text_color?: string | null;\n background_color?: string | null;\n } | null;\n color?: string | null;\n is_title?: boolean;\n is_end?: boolean;\n choice_style?: string | null;\n choice_overlay_mode?: string | null;\n choice_reveal_mode?: string | null;\n choice_start_time_seconds?: number | null;\n choice_pause_for_choice?: boolean;\n choice_end_time_seconds?: number | null;\n}\n\nexport interface CreateSceneRequest {\n story_id: string;\n title: string;\n order?: number;\n is_title?: boolean;\n is_end?: boolean;\n}\n\nexport interface SceneActionItem {\n id: string;\n scene_id: string;\n name: string;\n type: string | null;\n scene_choice_id: string | null;\n order: number;\n duration: number;\n properties: SceneActionPayload | null;\n subproperties: SceneActionPayload | null;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface CreateSceneActionRequest {\n scene_id: string;\n name: string;\n type?: string | null;\n order?: number;\n duration?: number;\n properties?: SceneActionPayload | null;\n subproperties?: SceneActionPayload | null;\n}\n\nexport interface UpdateSceneActionRequest {\n name?: string;\n type?: string | null;\n order?: number;\n duration?: number;\n properties?: SceneActionPayload;\n subproperties?: SceneActionPayload;\n}\n\n// ── AI Generation ──\n\nexport type AiGenerationStatus =\n | \"pending\"\n | \"generating\"\n | \"ready\"\n | \"failed\"\n | \"accepted\"\n | \"rejected\";\n\nexport interface GenerateImageRequest {\n story_id: string;\n scene_id?: string;\n prompt: string;\n mood?: string;\n visual_style?: string;\n rejection_feedback?: string;\n previous_generation_id?: string;\n}\n\nexport interface AiGeneration {\n id: string;\n story_id: string;\n scene_id: string | null;\n status: AiGenerationStatus;\n user_prompt: string;\n style_context: {\n mood?: string;\n visual_style?: string;\n subject_prompt: string;\n full_prompt: string;\n negative_prompt?: string;\n };\n preview_url?: string;\n rejection_feedback: string | null;\n media_id: string | null;\n attempt_number: number;\n credits_charged: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface GenerateImageResponse {\n generation: AiGeneration;\n balance: { watch: number; create: number };\n}\n\nexport interface AiGenerationShowResponse {\n generation: AiGeneration;\n}\n\nexport interface AcceptGenerationRequest {\n scene_id: string;\n}\n\nexport interface AcceptGenerationResponse {\n generation: AiGeneration;\n scene: SceneListItem;\n media: MediaItem;\n}\n\nexport interface RejectGenerationRequest {\n feedback: string;\n}\n\nexport interface RejectGenerationResponse {\n generation: AiGeneration;\n}\n\nexport interface StoryStyleResponse {\n has_style: boolean;\n style_context: AiGeneration[\"style_context\"] | null;\n}\n\n// ── Media ──\n\nexport interface MediaItem {\n id: string;\n user_id: string;\n s3_key: string;\n source_path: string;\n output_prefix: string | null;\n status: \"uploaded\" | \"processing\" | \"ready\" | \"error\";\n meta: Record<string, unknown>;\n order: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UploadUrlRequest {\n filename: string;\n contentType: string;\n}\n\nexport interface UploadUrlResponse {\n key: string;\n uploadUrl: string;\n}\n\nexport interface RegisterMediaRequest {\n key: string;\n s3_key: string;\n filename: string;\n content_type?: string;\n title?: string;\n file_size?: number;\n}\n\nexport interface RegisterMediaResponse extends MediaItem {\n credits_charged: number;\n balance: number;\n}\n\nexport interface TranscodeRequest {\n media_id: string;\n}\n\nexport interface TranscodeResponse {\n message: string;\n job_id: string | null;\n manifest_path?: string;\n}\n\nexport interface PlayUrlResponse {\n play_url: string;\n status: string;\n}\n\nexport interface SourceUrlResponse {\n url: string;\n}\n\n// ── Story authoring ──\n\nexport interface CreateStoryRequest {\n title: string;\n description?: string | null;\n genre?: string | null;\n content_rating?: ContentRating | null;\n}\n\nexport interface UpdateStoryRequest {\n title?: string;\n description?: string | null;\n genre?: string | null;\n content_rating?: ContentRating | null;\n published?: boolean;\n tags?: string[];\n}\n\nexport interface TagListResponse {\n data: string[];\n}\n\n// ── Content Ratings ──\n\nexport type ContentRating = \"G\" | \"PG\" | \"PG-13\" | \"R\" | \"NC-17\";\n\nexport interface ContentRatingDefinition {\n id: ContentRating;\n label: string;\n description: string;\n}\n\n// ── Realm Config ──\n\nexport type RealmId = \"cosmos\" | \"wilds\";\n\n/** Supported UI locales — matches PHP `chuzi_realms.supported_locales`. */\nexport type LocaleId = \"en\" | \"es\" | \"fr\" | \"de\" | \"pt\";\n\nexport interface RealmDefinition {\n label: string;\n short_label: string;\n /** Canonical English lexicon (always present). */\n lexicon: Record<string, string>;\n /** Optional per-locale overrides; missing keys fall through to `lexicon`. */\n locales?: Partial<Record<LocaleId, Record<string, string>>>;\n}\n\nexport interface RealmConfigResponse {\n realms: Record<RealmId, RealmDefinition>;\n fallback_lexicon: Record<string, string>;\n fallback_locales?: Partial<Record<LocaleId, Record<string, string>>>;\n intro: {\n line1: string;\n line2: string;\n };\n intro_locales?: Partial<Record<LocaleId, { line1: string; line2: string }>>;\n profile: {\n title: string;\n current_prefix: string;\n switch_prompt: string;\n };\n profile_locales?: Partial<Record<LocaleId, { title: string; current_prefix: string; switch_prompt: string }>>;\n allowed_realm_ids: RealmId[];\n supported_locales: LocaleId[];\n locale_labels?: Partial<Record<LocaleId, string>>;\n}\n\nexport interface UpdateLocaleRequest {\n locale: LocaleId;\n}\n\nexport interface UpdateLocaleResponse {\n locale: LocaleId;\n}\n\n// ── Scene Visibility ──\n\nexport interface SceneVisibility {\n /** Whether the user can navigate to this scene-star. */\n navigable: boolean;\n /** Whether the star/edge should render at reduced opacity. */\n dimmed: boolean;\n}\n\n/**\n * Compute per-scene navigable/dimmed flags for a constellation.\n *\n * Rules:\n * - If `isCreator` is true, everything is navigable and bright.\n * - Title scenes are always navigable and bright.\n * - If the user has watched the ending (`endingSeen`), all scenes unlock.\n * - Otherwise non-title scenes are locked and dimmed.\n */\nexport function computeSceneVisibility(\n sceneList: Pick<SceneListItem, \"is_title\" | \"is_end\">[],\n opts: { isCreator: boolean; endingSeen: boolean },\n): SceneVisibility[] {\n if (opts.isCreator || opts.endingSeen) {\n return sceneList.map(() => ({ navigable: true, dimmed: false }));\n }\n return sceneList.map((scene) => ({\n navigable: scene.is_title,\n dimmed: !scene.is_title,\n }));\n}\n"]}
package/dist/ui/index.js CHANGED
@@ -107,6 +107,15 @@ var REALMS = {
107
107
  editor_text_color_label: "Text Color",
108
108
  editor_text_background_label: "Background",
109
109
  editor_text_placeholder: "Start writing scene media...",
110
+ editor_line_add: "Add Transmission",
111
+ editor_line_timestamp: "Appears at",
112
+ editor_line_fade_in: "Fade In",
113
+ editor_line_fade_out: "Fade Out",
114
+ editor_line_duration: "Duration",
115
+ editor_timeline_label: "Timeline",
116
+ editor_preview_label: "Preview",
117
+ editor_preview_play: "Play",
118
+ editor_preview_pause: "Pause",
110
119
  editor_media_placeholder_imagery: "Imagery authoring is coming soon.",
111
120
  editor_media_placeholder_film: "Film authoring is coming soon.",
112
121
  constellation_no_coverbox: "Uncharted",
@@ -366,6 +375,15 @@ var REALMS = {
366
375
  editor_text_color_label: "Text Color",
367
376
  editor_text_background_label: "Background",
368
377
  editor_text_placeholder: "Start writing scene media...",
378
+ editor_line_add: "Add Verse",
379
+ editor_line_timestamp: "Appears at",
380
+ editor_line_fade_in: "Fade In",
381
+ editor_line_fade_out: "Fade Out",
382
+ editor_line_duration: "Duration",
383
+ editor_timeline_label: "Timeline",
384
+ editor_preview_label: "Preview",
385
+ editor_preview_play: "Play",
386
+ editor_preview_pause: "Pause",
369
387
  editor_media_placeholder_imagery: "Imagery authoring is coming soon.",
370
388
  editor_media_placeholder_film: "Film authoring is coming soon.",
371
389
  constellation_no_coverbox: "Unseen",
@@ -623,6 +641,15 @@ var FALLBACK_LEXICON = {
623
641
  editor_text_color_label: "Text Color",
624
642
  editor_text_background_label: "Background",
625
643
  editor_text_placeholder: "Start writing scene media...",
644
+ editor_line_add: "Add Line",
645
+ editor_line_timestamp: "Appears at",
646
+ editor_line_fade_in: "Fade In",
647
+ editor_line_fade_out: "Fade Out",
648
+ editor_line_duration: "Duration",
649
+ editor_timeline_label: "Timeline",
650
+ editor_preview_label: "Preview",
651
+ editor_preview_play: "Play",
652
+ editor_preview_pause: "Pause",
626
653
  editor_media_placeholder_imagery: "Imagery authoring is coming soon.",
627
654
  editor_media_placeholder_film: "Film authoring is coming soon.",
628
655
  constellation_no_coverbox: "No cover",