JSPM

@echoes-io/models

1.2.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3
  • Score
    100M100P100Q37411F
  • License MIT

TypeScript models and validation schemas for Echoes - Multi-POV storytelling platform. Provides shared types, interfaces, and Zod schemas.

Package Exports

  • @echoes-io/models

Readme

@echoes-io/models

TypeScript models and validation schemas for Echoes - a multi-POV digital storytelling platform.

Table of Contents

Overview

This package provides shared TypeScript interfaces, types, and validation schemas used across the Echoes ecosystem:

  • Timeline repositories (content storage)
  • Tracker service (content management and API)
  • RAG service (semantic search and AI context)
  • Web application (frontend)
  • CLI tools and utilities

Architecture Context

Echoes is organized as a multi-repository system:

@echoes-io/utils     # Shared utilities (markdown parsing, text stats)
@echoes-io/models    # This package - shared types and schemas
@echoes-io/tracker   # Content management API and database
@echoes-io/rag       # Semantic search and AI context
echoes-timeline-*    # Individual timeline content repositories
echoes-web-app       # Frontend application

Content Structure

Echoes organizes storytelling content in a hierarchical structure:

erDiagram
    Timeline ||--o{ Arc : contains
    Arc ||--o{ Episode : contains
    Episode ||--o{ Part : contains
    Episode ||--o{ Chapter : contains
    Part ||--o{ Chapter : "belongs to"
    
    Timeline {
        string name PK
        string description
    }
    
    Arc {
        string timelineName FK
        string name PK
        int number
        string description
    }
    
    Episode {
        string timelineName FK
        string arcName FK
        int number PK
        string slug
        string title
        string description
    }
    
    Part {
        string timelineName FK
        string arcName FK
        int episodeNumber FK
        int number PK
        string slug
        string title
        string description
    }
    
    Chapter {
        string timelineName FK
        string arcName FK
        int episodeNumber FK
        int partNumber FK
        int number PK
        string pov
        string title
        string date
        string summary
        string location
        string outfit "optional"
        string kink "optional"
        int words
        int characters
        int charactersNoSpaces
        int paragraphs
        int sentences
        int readingTimeMinutes
    }

Hierarchy

Timeline
  └─ Arc (ordered)
      └─ Episode (numbered)
          ├─ Part (numbered, optional subdivision)
          └─ Chapter (numbered, continuous within episode)

Note: Chapter numbering is continuous within an episode and does NOT reset per part.

File Structure Convention

timeline-repo/
├── content/
│   ├── <arc-name>/
│   │   └── <ep01-episode-title>/
│   │       └── <ep01-ch001-pov-title>.md

Naming Conventions:

  • Episode numbers: 2-digit padding (ep01, ep02, ep12)
  • Chapter numbers: 3-digit padding (ch001, ch005, ch123)
  • Slugification: lowercase, hyphens, no special characters
  • Example: content/introduction-arc/ep01-first-meeting/ep01-ch005-alice-first-meeting.md

Models

This package defines TypeScript interfaces for:

Core Content Models

  • Timeline - Root story container with name and description
  • Arc - Story arc within timeline with ordering
  • Episode - Episode within arc with numbering, slug, title, description
  • Part - Part within episode with numbering, slug, title, description
  • Chapter - Individual content file with metadata and stats (content stored in .md files)

Metadata Models

  • ChapterMetadata - Frontmatter structure for .md files:
    • Required fields: pov, title, date, timeline, arc, episode (number), part (number), chapter (number), summary, location
    • Optional fields: outfit, kink
  • TextStats - Text statistics from content analysis:
    • words, characters, charactersNoSpaces, paragraphs, sentences, readingTimeMinutes

Compatibility with @echoes-io/utils

This package provides the same interfaces as @echoes-io/utils but adds:

  • Database-ready models with IDs and relationships
  • Zod validation schemas for runtime type checking
  • API request/response types for the tracker service
  • Extended metadata for content management
// These interfaces match @echoes-io/utils exactly
import type { ChapterMetadata, TextStats } from '@echoes-io/models';

// These are new database models
import type { Timeline, Arc, Episode, Chapter } from '@echoes-io/models';

// These are new validation schemas
import { validateChapterMetadata, validateTimeline } from '@echoes-io/models';

Installation

npm install @echoes-io/models

Models Reference

Timeline

Root container for a story universe.

Field Type Key Description
name string PK Timeline name (unique identifier)
description string Timeline description

Example:

const timeline: Timeline = {
  name: 'main-story',
  description: 'The primary storyline',
};

Arc

Story arc within a timeline. Represents major story phases (e.g., "Introduction", "Rising Action").

Field Type Key Description
timelineName string FK, PK Timeline name (foreign key)
name string PK Arc name
number number Arc order/number within timeline
description string Arc description

Primary Key: (timelineName, name)

Example:

const arc: Arc = {
  timelineName: 'main-story',
  name: 'introduction',
  number: 1,
  description: 'The beginning of the story',
};

Episode

Episode within an arc. Represents story events or time periods.

Field Type Key Description
timelineName string FK, PK Timeline name (foreign key)
arcName string FK, PK Arc name (foreign key)
number number PK Episode number (e.g., 1, 2, 3)
slug string Episode slug (URL-friendly)
title string Episode title
description string Episode description

Primary Key: (timelineName, arcName, number)

Example:

const episode: Episode = {
  timelineName: 'main-story',
  arcName: 'introduction',
  number: 1,
  slug: 'first-meeting',
  title: 'First Meeting',
  description: 'Alice and Bob meet for the first time',
};

Part

Part within an episode. Used for organizing longer episodes into subdivisions.

Field Type Key Description
timelineName string FK, PK Timeline name (foreign key)
arcName string FK, PK Arc name (foreign key)
episodeNumber number FK, PK Episode number (foreign key)
number number PK Part number within episode
slug string Part slug (URL-friendly)
title string Part title
description string Part description

Primary Key: (timelineName, arcName, episodeNumber, number)

Example:

const part: Part = {
  timelineName: 'main-story',
  arcName: 'introduction',
  episodeNumber: 1,
  number: 1,
  slug: 'morning',
  title: 'Morning',
  description: 'The morning scene',
};

Chapter

Individual content file (.md with frontmatter). Extends ChapterMetadata and TextStats from @echoes-io/utils.

Note: Chapter numbering is continuous within an episode and does NOT reset per part.

Structure:

interface Chapter extends ChapterMetadata, TextStats {
  timelineName: string;
  arcName: string;
  episodeNumber: number;
  partNumber: number;
  number: number;
}
Field Type Key Required Description
Database Keys
timelineName string FK, PK Timeline name (foreign key)
arcName string FK, PK Arc name (foreign key)
episodeNumber number FK, PK Episode number (foreign key)
partNumber number FK Part number (indicates which part the chapter belongs to)
number number PK Chapter number (unique within episode)
From ChapterMetadata
pov string Point of view character
title string Chapter title
date string Chapter date (free text, e.g., "2025-01-01 Monday")
timeline string Timeline name (from frontmatter)
arc string Arc name (from frontmatter)
episode number Episode number (from frontmatter)
part number Part number (from frontmatter)
chapter number Chapter number (from frontmatter)
summary string Brief chapter description
location string Chapter location/setting
outfit string Character outfit description (optional)
kink string Content tags/kinks (optional)
From TextStats
words number Total word count
characters number Total character count (including spaces)
charactersNoSpaces number Character count excluding spaces
paragraphs number Number of paragraphs
sentences number Number of sentences
readingTimeMinutes number Estimated reading time in minutes (200 words/min)

Primary Key: (timelineName, arcName, episodeNumber, number)

Example:

const chapter: Chapter = {
  // Database keys
  timelineName: 'main-story',
  arcName: 'introduction',
  episodeNumber: 1,
  partNumber: 1,
  number: 1,
  // Metadata (from ChapterMetadata)
  pov: 'Alice',
  title: 'First Meeting',
  date: '2025-01-01 Monday',
  timeline: 'main-story',
  arc: 'introduction',
  episode: 1,
  part: 1,
  chapter: 1,
  summary: 'Alice meets Bob at the coffee shop',
  location: 'Coffee Shop',
  outfit: 'Blue dress', // optional
  kink: 'romance', // optional
  // Text statistics (from TextStats)
  words: 1000,
  characters: 5000,
  charactersNoSpaces: 4000,
  paragraphs: 10,
  sentences: 50,
  readingTimeMinutes: 5,
};

ChapterMetadata

Frontmatter structure for .md files. This is the source of truth that gets replicated into the database.

Field Type Required Description
pov string Point of view character
title string Chapter title
date string Chapter date (free text, e.g., "2025-01-01 Monday")
timeline string Timeline name
arc string Arc name
episode number Episode number
part number Part number
chapter number Chapter number
summary string Brief chapter description
location string Chapter location/setting
outfit string Character outfit description (optional)
kink string Content tags/kinks (optional)

Example:

const metadata: ChapterMetadata = {
  pov: 'Alice',
  title: 'First Meeting',
  date: '2025-01-01 Monday',
  timeline: 'main-story',
  arc: 'introduction',
  episode: 1,
  part: 1,
  chapter: 1,
  summary: 'Alice meets Bob at the coffee shop',
  location: 'Coffee Shop',
};

TextStats

Text statistics calculated from content analysis (via @echoes-io/utils).

Field Type Description
words number Total word count
characters number Total character count (including spaces)
charactersNoSpaces number Character count excluding spaces
paragraphs number Number of paragraphs
sentences number Number of sentences
readingTimeMinutes number Estimated reading time in minutes (200 words/min)

Example:

const stats: TextStats = {
  words: 1000,
  characters: 5000,
  charactersNoSpaces: 4000,
  paragraphs: 10,
  sentences: 50,
  readingTimeMinutes: 5,
};

Usage

import { 
  Timeline, 
  Arc, 
  Episode, 
  Part, 
  Chapter, 
  ChapterMetadata,
  validateTimeline,
  validateChapter,
} from '@echoes-io/models';

// Type-safe content structures
const timeline: Timeline = {
  name: 'main-story',
  description: 'The primary storyline',
};

const arc: Arc = {
  timelineName: 'main-story',
  name: 'introduction',
  number: 1,
  description: 'The beginning of the story',
};

const episode: Episode = {
  timelineName: 'main-story',
  arcName: 'introduction',
  number: 1,
  slug: 'first-meeting',
  title: 'First Meeting',
  description: 'Alice and Bob meet for the first time',
};

const part: Part = {
  timelineName: 'main-story',
  arcName: 'introduction',
  episodeNumber: 1,
  number: 1,
  slug: 'morning',
  title: 'Morning',
  description: 'The morning scene',
};

const chapter: Chapter = {
  timelineName: 'main-story',
  arcName: 'introduction',
  episodeNumber: 1,
  partNumber: 1,
  number: 1,
  pov: 'Alice',
  title: 'First Meeting',
  date: '2025-01-01 Monday',
  timeline: 'main-story',
  arc: 'introduction',
  episode: 1,
  part: 1,
  chapter: 1,
  summary: 'Alice meets Bob at the coffee shop',
  location: 'Coffee Shop',
  words: 1000,
  characters: 5000,
  charactersNoSpaces: 4000,
  paragraphs: 10,
  sentences: 50,
  readingTimeMinutes: 5,
};

// Validation with Zod
try {
  validateTimeline(timeline);
  validateChapter(chapter);
  console.log('Valid!');
} catch (error) {
  console.error('Validation error:', error);
}

Development

Tech Stack

  • Language: TypeScript (strict mode)
  • Validation: Zod (planned)
  • Testing: Vitest
  • Linting: Biome

Scripts

# Run tests
npm test

# Type checking
npm run type-check

# Lint code
npm run lint

Integration

With @echoes-io/utils

  • Uses ChapterMetadata interface from this package
  • Provides validation for parsed frontmatter

With @echoes-io/tracker

  • Implements these models in database schema
  • Uses types for API endpoints and operations

With @echoes-io/rag

  • Uses models for content indexing
  • Provides types for semantic search results

License

MIT