UNPKG

@crescender/calendar

Version:

A comprehensive TypeScript calendar library with musician-specific capabilities, architected for client/server separation.

380 lines (295 loc) • 9.6 kB
# Migration Guide: v0.2.x → v0.3.0 ## Overview Version 0.3.0 introduces a significant architectural change with **client/server separation**. The package is now structured to provide clean separation between browser-safe client code and Node.js server code. ## 🚨 Breaking Changes ### 1. Import Structure Changes **Before (v0.2.x):** ```typescript import { createEvent, Event, Calendar, addEventIncome, calculateEventProfit, generateIcs, validateEvent, formatDateAustralian } from '@crescender/calendar'; ``` **After (v0.3.0):** ```typescript // For server-side operations (Node.js only) import { createEvent, Event, Calendar, addEventIncome, calculateEventProfit, generateIcs, initDb } from '@crescender/calendar/server'; // For client-side operations (browser-safe) import { validateEvent, formatDateAustralian, enhanceClientEvent, expandRecurrence, EventCard } from '@crescender/calendar/client'; // For shared utilities (both environments) import { EVENT_TYPES, PAYMENT_STATUS, EventType, IEvent } from '@crescender/calendar/shared'; // OR from main entry: import { EVENT_TYPES, PAYMENT_STATUS } from '@crescender/calendar'; ``` ### 2. Module Separation | Functionality | v0.2.x Location | v0.3.0 Location | |---------------|-----------------|-----------------| | Database operations | Main package | `/server` | | ICS generation | Main package | `/server` | | Event validation | Main package | `/client` | | Date formatting | Main package | `/client` | | React components | Main package | `/client` | | Types & constants | Main package | `/shared` (or main) | ### 3. Database Initialization Changes **Before (v0.2.x):** ```typescript import { initDb, createEvent } from '@crescender/calendar'; await initDb(dataSource); const event = await createEvent('calendar-id', eventData); ``` **After (v0.3.0):** ```typescript import { initDb, createEvent } from '@crescender/calendar/server'; await initDb(dataSource); const event = await createEvent('calendar-id', eventData); ``` ### 4. Client-Side Event Processing **Before (v0.2.x):** ```typescript import { validateEvent, formatDateAustralian } from '@crescender/calendar'; const validation = validateEvent(formData); const formattedDate = formatDateAustralian(new Date()); ``` **After (v0.3.0):** ```typescript import { validateEvent, formatDateAustralian } from '@crescender/calendar/client'; const validation = validateEvent(formData); const formattedDate = formatDateAustralian(new Date()); ``` ## šŸŽÆ New Features in v0.3.0 ### Enhanced Client-Side Capabilities ```typescript import { enhanceClientEvent, expandRecurrence, filterEvents, sortEvents, groupEventsByDate, calculateFinancials } from '@crescender/calendar/client'; // Enhanced event processing with computed properties const enhancedEvent = enhanceClientEvent(rawEvent); console.log(enhancedEvent.duration); // Computed duration console.log(enhancedEvent.profit); // Computed profit console.log(enhancedEvent.formattedDate); // Australian date format // Recurrence expansion const occurrences = expandRecurrence(recurringEvent, startDate, endDate); // Advanced filtering and sorting const filteredEvents = filterEvents(events, { type: 'gig', status: 'confirmed' }); const sortedEvents = sortEvents(events, 'date', 'asc'); const groupedEvents = groupEventsByDate(events); // Financial calculations const financials = calculateFinancials(events); ``` ### React Components (New) ```typescript import { EventCard, CalendarView } from '@crescender/calendar/client'; function MyCalendar({ events }) { return ( <div> {events.map(event => ( <EventCard key={event.id} event={event} onEdit={handleEdit} onDelete={handleDelete} /> ))} </div> ); } ``` ### Enhanced Server-Side Operations ```typescript import { createEvent, updateEvent, deleteEvent, getEventsByType, getUpcomingGigs, getFinancialSummary, generateIcs } from '@crescender/calendar/server'; // All existing server operations remain the same // but now properly separated from client code ``` ## šŸ“¦ Package Structure ### v0.2.x Structure ``` @crescender/calendar ā”œā”€ā”€ index.js (everything mixed together) └── types.d.ts ``` ### v0.3.0 Structure ``` @crescender/calendar ā”œā”€ā”€ index.js (shared functionality only) ā”œā”€ā”€ client/ │ └── index.js (browser-safe code) ā”œā”€ā”€ server/ │ └── index.js (Node.js only code) └── shared/ └── index.js (common utilities) ``` ## šŸ”„ Migration Steps ### Step 1: Update Imports 1. **Identify your usage context:** - Server-side (API routes, Node.js scripts) → use `/server` - Client-side (React components, browser) → use `/client` - Shared (types, constants) → use `/shared` or main import 2. **Update import statements:** ```typescript // Before import { createEvent, validateEvent, EVENT_TYPES } from '@crescender/calendar'; // After - separate by context import { createEvent } from '@crescender/calendar/server'; import { validateEvent } from '@crescender/calendar/client'; import { EVENT_TYPES } from '@crescender/calendar'; // or /shared ``` ### Step 2: Update TypeScript Configuration If using TypeScript with module resolution, ensure your `tsconfig.json` supports the new export structure: ```json { "compilerOptions": { "moduleResolution": "node", "esModuleInterop": true, "allowSyntheticDefaultImports": true } } ``` ### Step 3: Bundle Configuration (Webpack/Vite) For client-side builds, the `/client` module is optimized to exclude Node.js dependencies: ```typescript // Webpack/Vite will automatically tree-shake Node.js dependencies // when importing from /client import { validateEvent } from '@crescender/calendar/client'; ``` ### Step 4: Test Your Changes 1. **Server-side code** should import from `/server` 2. **Client-side code** should import from `/client` 3. **Shared utilities** can import from main package or `/shared` ## šŸ†• New Type Definitions ### Enhanced Event Types ```typescript import type { ClientEvent, ServerEvent, IEvent } from '@crescender/calendar/shared'; // ClientEvent: Browser-optimized with computed properties // ServerEvent: Full database entity with relations // IEvent: Shared interface for both ``` ### Validation Types ```typescript import type { EventFormData, ValidationResult, IncomeFormData, ExpenseFormData } from '@crescender/calendar/client'; ``` ## šŸ”§ Compatibility Notes ### Backward Compatibility - **Main entry point** still exports shared functionality for basic compatibility - **Core types** remain unchanged - **Database schema** is unchanged ### What's Not Backward Compatible - **Import paths** for specific functionality - **Mixed client/server** operations in the same import - **Direct access** to internal modules ## šŸ“š Updated Usage Examples ### Full-Stack Application ```typescript // api/events.ts (Server-side) import { createEvent, getEventsByType } from '@crescender/calendar/server'; export async function POST(request: Request) { const eventData = await request.json(); const event = await createEvent('calendar-id', eventData); return Response.json(event); } export async function GET() { const events = await getEventsByType('calendar-id', 'gig'); return Response.json(events); } ``` ```typescript // components/EventList.tsx (Client-side) import { EventCard, enhanceClientEvent } from '@crescender/calendar/client'; import type { IEvent } from '@crescender/calendar/shared'; interface Props { events: IEvent[]; } export function EventList({ events }: Props) { const enhancedEvents = events.map(enhanceClientEvent); return ( <div> {enhancedEvents.map(event => ( <EventCard key={event.id} event={event} /> ))} </div> ); } ``` ### Node.js Script ```typescript // scripts/generate-report.ts import { initDb, getEventsByType, getFinancialSummary } from '@crescender/calendar/server'; const dataSource = new DataSource(config); await dataSource.initialize(); initDb(dataSource); const gigs = await getEventsByType('calendar-id', 'gig'); const summary = await getFinancialSummary(gigs.map(g => g.id)); console.log('Financial Summary:', summary); ``` ## šŸ†˜ Troubleshooting ### Common Issues 1. **"Cannot resolve module"** error - Update import paths to use `/client`, `/server`, or `/shared` 2. **Node.js dependencies in browser** - Use `/client` imports for browser code - Check bundler configuration 3. **TypeScript errors** - Update type imports to use specific modules - Ensure `moduleResolution: "node"` in tsconfig.json 4. **Mixed environment code** - Separate client and server logic into different files - Use appropriate module imports for each environment ### Getting Help If you encounter issues during migration: 1. Check the [examples](./examples/) directory 2. Review the [API documentation](./docs/api.md) 3. Open an issue on [GitHub](https://github.com/lincalinca/Crescalendar/issues) ## šŸŽ‰ Benefits of v0.3.0 - **Smaller bundle sizes** for client applications - **Better tree-shaking** support - **Cleaner separation** of concerns - **Enhanced type safety** with environment-specific types - **New React components** for rapid development - **Improved developer experience** with clear module boundaries The migration effort pays off with better performance, clearer code organization, and enhanced development experience!