Documentation
v1.0.0GitHub
Core Primitive
Content Types
Structured data formats and validation schemas for different block types and their content.
Content Type System
The Content Type system provides structured data formats for different kinds of block content. It ensures type safety, validation, and consistent data handling across the entire application.
Key Benefits: Type safety with TypeScript, runtime validation, structured data for complex blocks, and extensible schema system.
Content Categories
Simple String Content
Basic blocks that store plain text content
Block Types
rolegoalcontextconstraintcapabilitytextheading
// Simple string content
interface SimpleBlock {
id: string;
type: 'role' | 'goal' | 'context' | 'constraint' | 'capability';
content: string; // Plain text content
metadata?: {
placeholder?: string;
maxLength?: number;
minLength?: number;
};
}Example Usage
const roleBlock: Block = {
id: 'role-1',
type: 'role',
content: 'You are an expert TypeScript developer with 10+ years of experience.',
metadata: {
placeholder: 'Define the AI role and expertise...',
maxLength: 500
}
};Content Validation
Runtime Validation
Ensuring content integrity with runtime validation
lib/content-validator.ts
import { z } from 'zod';
import type { BlockType } from '@/types/prompt-blocks';
// Base schemas for different content types
const StringContentSchema = z.string();
const VariableContentSchema = z.object({
name: z.string().min(1),
type: z.enum(['string', 'number', 'boolean', 'select']),
required: z.boolean(),
default: z.string().optional(),
options: z.array(z.string()).optional(),
description: z.string().optional()
});
const ExampleContentSchema = z.object({
input: z.string().min(1),
output: z.string().min(1),
explanation: z.string().optional()
});
// Content validation registry
const CONTENT_SCHEMAS: Record<BlockType, z.ZodSchema> = {
role: StringContentSchema,
goal: StringContentSchema,
context: StringContentSchema,
constraint: StringContentSchema,
capability: StringContentSchema,
variable: VariableContentSchema,
example: ExampleContentSchema,
instructions: z.object({
steps: z.array(z.string().min(1))
}),
// ... other schemas
};
// Validation function
export function validateBlockContent(type: BlockType, content: any) {
const schema = CONTENT_SCHEMAS[type];
if (!schema) {
throw new Error(`No validation schema found for block type: ${type}`);
}
try {
return schema.parse(content);
} catch (error) {
if (error instanceof z.ZodError) {
throw new Error(`Content validation failed for ${type}: ${error.message}`);
}
throw error;
}
}
// Usage in block operations
export function createValidatedBlock(type: BlockType, content: any): Block {
const validatedContent = validateBlockContent(type, content);
return {
id: nanoid(),
type,
content: validatedContent,
metadata: {
createdAt: new Date().toISOString(),
validated: true
}
};
}Type Inference
TypeScript Type Guards
Runtime type checking and TypeScript inference
lib/type-guards.ts
import type { Block, BlockType, VariableContent, ExampleContent } from '@/types/prompt-blocks';
// Type guard functions
export function isStringContent(block: Block): block is Block & { content: string } {
return typeof block.content === 'string';
}
export function isVariableBlock(block: Block): block is Block & {
type: 'variable';
content: VariableContent
} {
return block.type === 'variable' &&
typeof block.content === 'object' &&
'name' in block.content;
}
export function isExampleBlock(block: Block): block is Block & {
type: 'example';
content: ExampleContent
} {
return block.type === 'example' &&
typeof block.content === 'object' &&
'input' in block.content &&
'output' in block.content;
}
export function isInstructionBlock(block: Block): block is Block & {
type: 'instructions';
content: { steps: string[] }
} {
return block.type === 'instructions' &&
typeof block.content === 'object' &&
'steps' in block.content &&
Array.isArray(block.content.steps);
}
// Generic type guard creator
export function createTypeGuard<T extends BlockType>(blockType: T) {
return (block: Block): block is Block & { type: T } => {
return block.type === blockType;
};
}
// Usage examples
export function processBlock(block: Block) {
if (isVariableBlock(block)) {
// TypeScript knows block.content is VariableContent
console.log(`Variable ${block.content.name} is ${block.content.required ? 'required' : 'optional'}`);
} else if (isExampleBlock(block)) {
// TypeScript knows block.content is ExampleContent
console.log(`Example: ${block.content.input} -> ${block.content.output}`);
} else if (isStringContent(block)) {
// TypeScript knows block.content is string
console.log(`Content length: ${block.content.length}`);
}
}Best Practices
Do
- Always validate content before storing in blocks
- Use TypeScript interfaces for structured content
- Provide default values for optional fields
- Use type guards for runtime type checking
Don't
- Store unvalidated content in blocks
- Use 'any' type for content - always define proper interfaces
- Modify content structure without updating validation schemas
- Assume content structure - always check types at runtime