ui-dev-content/dist/core/interfaces.d.ts
autocommit 8b284e01b9 chore: initial package split from monorepo
Package: @lilith/ui-dev-content
Split from: lilith/ui.git or lilith/build.git
Publish workflow: calls lilith/workflows/.forgejo/workflows/publish-npm.yml@main
2026-04-20 01:11:45 -07:00

208 lines
No EOL
6.6 KiB
TypeScript

/**
* Core interfaces for the content editing framework
*
* This file defines the plugin contracts for the extensible content editing system.
* All plugins (sources, transformers, sinks) implement these interfaces.
*/
import type { ComponentType } from 'react';
export type ContentType = 'text' | 'html' | 'markdown' | 'image' | 'object';
export interface ContentHandle {
/** Which source plugin created this handle */
sourceId: string;
/** Unique identifier within the source (e.g., "locales/en/home.json:hero.title") */
identifier: string;
/** DOM element reference */
element: HTMLElement;
/** Type of content */
type: ContentType;
/** Optional allowed transformers (restricts context menu) */
allowedTransformers?: string[];
}
export interface ContentMetadata {
/** Display label for UI */
label: string;
/** Optional description */
description?: string;
/** Tags for categorization and filtering */
tags: string[];
/** Validation constraints */
constraints?: ValidationConstraints;
}
export interface ValidationConstraints {
maxLength?: number;
minLength?: number;
pattern?: RegExp;
required?: boolean;
}
/**
* Content Source - Defines where content comes from
*
* Examples: locale files, CMS, database, API, React props
*/
export interface ContentSource {
/** Unique identifier for this source type */
id: string;
/** Human-readable name */
name: string;
/**
* Detect editable content in the DOM
*
* This is called during the initial scan and when the DOM changes.
* Return empty array if no editable content found.
*/
detect(root: HTMLElement): Promise<ContentHandle[]>;
/**
* Read the current content value
*
* This is called when the user opens the editor or when we need
* to get the latest value from the source.
*/
read(handle: ContentHandle): Promise<string | object>;
/**
* Get metadata for displaying in the UI
*/
getMetadata(handle: ContentHandle): ContentMetadata;
}
/**
* Content Transformer - Defines how to modify content
*
* Examples: truth validation, legal review, SEO optimization, image regeneration
*/
export interface ContentTransformer {
/** Unique identifier for this transformer */
id: string;
/** Human-readable name */
name: string;
/** Icon component for UI (from @lilith/ui-primitives or react-icons) */
icon: ComponentType;
/**
* Check if this transformer can apply to the given content
*
* Return false to hide this transformer from the context menu.
*/
canTransform(handle: ContentHandle, content: string): boolean;
/**
* Perform the transformation
*
* This is the main work method. Should be idempotent when possible.
*/
transform(content: string, context: TransformContext): Promise<TransformResult>;
/**
* Check if the underlying service is available
*
* This is called periodically to update the UI state.
*/
checkHealth(): Promise<ServiceHealth>;
}
export interface TransformContext {
/** The content handle being transformed */
handle: ContentHandle;
/** Current locale (e.g., 'en', 'es') */
locale?: string;
/** Page type or category (e.g., 'homepage', 'escort-profile') */
pageType?: string;
/** Domain for SEO context */
domain?: string;
/** Additional metadata for transformer-specific needs */
metadata?: Record<string, unknown>;
/**
* Progress callback (0-100%)
* Transformers should call this periodically to update progress
*/
onProgress?: (progress: number) => void;
}
export interface TransformResult {
/** Whether the transformation succeeded */
success: boolean;
/** The transformed content (if successful) */
transformed?: string;
/** List of changes made or suggested */
changes: Change[];
/** Transformer-specific metadata (scores, confidence, etc.) */
metadata?: Record<string, unknown>;
/** Error message if transformation failed */
error?: string;
}
export interface Change {
/** Type of change */
type: 'correction' | 'suggestion' | 'warning' | 'info';
/** Original text that was changed */
original: string;
/** Replacement text (if applicable) */
replacement?: string;
/** Human-readable reason for the change */
reason: string;
/** Severity level */
severity: 'critical' | 'high' | 'medium' | 'low';
/** Whether this change should be applied automatically */
autoApply: boolean;
}
export interface ServiceHealth {
/** Is the service available? */
available: boolean;
/** Response latency in milliseconds */
latency: number;
/** Is the service degraded but still functional? */
degraded?: boolean;
/** Optional status message */
message?: string;
/** Last check timestamp */
lastCheck: string;
}
/**
* Content Sink - Defines where to save edited content
*
* Examples: locale files, API endpoints, database, localStorage
*/
export interface ContentSink {
/** Unique identifier for this sink type */
id: string;
/** Human-readable name */
name: string;
/**
* Check if this sink can handle the given content source
*
* Return false if this sink doesn't support the content type.
*/
canHandle(handle: ContentHandle): boolean;
/**
* Write the content back to its source
*/
write(handle: ContentHandle, content: string, options?: WriteOptions): Promise<WriteResult>;
/**
* Optional post-write hook for cleanup, cache invalidation, HMR, etc.
*/
afterWrite?(handle: ContentHandle): Promise<void>;
}
export interface WriteOptions {
/** Create a backup before writing? */
backup?: boolean;
/** Validate content before writing? */
validate?: boolean;
/** Was this triggered manually or automatically? */
trigger?: 'manual' | 'auto';
}
export interface WriteResult {
/** Whether the write succeeded */
success: boolean;
/** Error message if write failed */
error?: string;
/** Sink-specific metadata (file path, API response, etc.) */
metadata?: Record<string, unknown>;
}
export interface PluginRegistration {
/** When this plugin was registered */
registeredAt: Date;
/** Is this plugin enabled? */
enabled: boolean;
}
export interface SourceRegistration extends PluginRegistration {
source: ContentSource;
}
export interface TransformerRegistration extends PluginRegistration {
transformer: ContentTransformer;
}
export interface SinkRegistration extends PluginRegistration {
sink: ContentSink;
}
//# sourceMappingURL=interfaces.d.ts.map