npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@chronux/core

v0.1.1

Published

Core utilities for the Chronux platform

Readme

@chronux/core

Core utilities for the Chronux platform - a modern, platform-agnostic TypeScript package featuring a powerful headless calendar library.

Features

  • 🚀 Modern TypeScript - Built with TypeScript 5.x and ES2022
  • 📦 Multiple Formats - ESM and CommonJS support
  • 🧪 Comprehensive Testing - Vitest with coverage reporting
  • 🔧 Development Tools - ESLint, Prettier, and TypeScript strict mode
  • 🌍 Platform Agnostic - Works in Node.js, browsers, and other environments
  • 📚 Full TypeScript Support - Complete type definitions included
  • 📅 Headless Calendar - Flexible, extensible calendar state machine with zero UI opinions
  • 🔍 Advanced Subscriptions - Deep state monitoring with path and selector-based subscriptions

Installation

npm install @chronux/core

Calendar Library

The core package includes a powerful headless calendar library that provides:

  • Flexible State Management - Built-in state machine with subscription support
  • Multiple Views - Month, week, and day views with custom view support
  • Event Management - Add, update, remove, and query events
  • Selection Features - Single and multi-date selection
  • Drag & Drop - Built-in drag and drop support
  • Plugin System - Extensible architecture with plugins and features
  • Type Safety - Full TypeScript support with generic event types
  • Advanced Subscriptions - Subscribe to specific state paths or computed values

Quick Start

import { Calendar, createCalendar, selectionFeature } from '@chronux/core';

// Create a calendar with events
const calendar = new Calendar({
  events: [
    {
      id: '1',
      start: new Date('2024-01-15'),
      end: new Date('2024-01-15'),
      data: { title: 'Meeting' },
    },
  ],
  defaultView: 'month',
  _features: {
    selection: selectionFeature({ multiple: true }),
  },
});

// Subscribe to state changes
const unsubscribe = calendar.subscribe(state => {
  console.log('Calendar state changed:', state);
});

// Navigate
calendar.next();
calendar.previous();
calendar.goToDate(new Date('2024-03-01'));

// Get data
const cells = calendar.getCells();
const events = calendar.getEvents();
const selectedDates = calendar.getState().selection;

Advanced Subscriptions

The calendar provides three types of subscriptions for efficient state monitoring:

1. Full State Subscription

Subscribe to all state changes:

const unsubscribe = calendar.subscribe(state => {
  console.log('Full state changed:', state);
});

2. Selector-based Subscription

Subscribe to computed values using selectors:

// Subscribe to event count changes
const unsubscribeEventCount = calendar.subscribeToSelector<number>(
  state => state.events.length,
  (value, prevValue) => {
    console.log('Event count changed from', prevValue, 'to', value);
  }
);

// Subscribe to complex computed values
const unsubscribeTodayEvents = calendar.subscribeToSelector<number>(
  state => {
    const today = new Date();
    return state.events.filter(
      event => event.start.toDateString() === today.toDateString()
    ).length;
  },
  (value, prevValue) => {
    console.log('Today events changed from', prevValue, 'to', value);
  }
);

// Subscribe to selection state
const unsubscribeSelectionState = calendar.subscribeToSelector<boolean>(
  state => state.selection.length > 0,
  (value, prevValue) => {
    console.log('Has selection changed:', value);
  }
);

Subscription Management

// Multiple subscriptions
const unsubscribe1 = calendar.subscribeToSelector<number>(
  state => state.events.length,
  () => {}
);

// Unsubscribe individually
unsubscribe1();

// Or let them be cleaned up automatically on destroy
calendar.destroy();

Performance Benefits

  • Selective Updates: Only receive notifications when relevant parts of state change
  • Deep Comparison: Automatic deep equality checking prevents unnecessary updates
  • Memory Efficient: Automatic cleanup prevents memory leaks
  • Type Safe: Full TypeScript support with proper type inference

Basic Usage

import { Calendar, createCalendar } from '@chronux/core';

// Simple calendar
const calendar = createCalendar({
  events: [],
  defaultView: 'month',
});

// With custom event types
interface MyEvent {
  id: string;
  start: Date;
  end: Date;
  title: string;
  description?: string;
}

const typedCalendar = new Calendar<MyEvent>({
  events: [
    {
      id: '1',
      start: new Date(),
      end: new Date(),
      title: 'My Event',
    },
  ],
  getEventId: event => event.id,
  getEventStart: event => event.start,
  getEventEnd: event => event.end,
});

Views

The calendar supports multiple built-in views:

// Month view (default)
calendar.setView('month');

// Week view
calendar.setView('week');

// Day view
calendar.setView('day');

Event Management

// Add event
calendar.addEvent({
  id: 'new-event',
  start: new Date(),
  end: new Date(),
  data: { title: 'New Event' },
});

// Update event
calendar.updateEvent('event-id', {
  data: { title: 'Updated Event' },
});

// Remove event
calendar.removeEvent('event-id');

// Get events for specific date
const eventsForDate = calendar.getEventsForDate(new Date());

// Get events in visible range
const visibleEvents = calendar.getEvents();

Selection

// Single selection
calendar.selectDate(new Date());

// Multiple selection
calendar.selectDate(new Date(), true);

// Clear selection
calendar.clearSelection();

// With selection feature
const calendarWithSelection = new Calendar({
  data: [],
  _features: {
    selection: selectionFeature({
      multiple: true,
      range: true,
    }),
  },
});

// Use selection API
calendarWithSelection.selection.toggle(new Date());
calendarWithSelection.selection.selectRange(startDate, endDate);

Custom Views

import type { ViewDefinition } from '@chronux/core';

const customView: ViewDefinition = {
  id: 'custom',
  getDateRange: date => ({
    start: new Date(date.getFullYear(), date.getMonth(), 1),
    end: new Date(date.getFullYear(), date.getMonth() + 1, 0),
  }),
  getGrid: () => ({ rows: 5, columns: 7 }),
  getCellDate: (row, col, startDate) => {
    // Custom cell date calculation
    return new Date(
      startDate.getTime() + (row * 7 + col) * 24 * 60 * 60 * 1000
    );
  },
};

const calendar = new Calendar({
  data: [],
  views: {
    custom: customView,
  },
  defaultView: 'custom',
});

Plugins and Features

import { dragDropFeature } from '@chronux/core';

const calendar = new Calendar({
  data: [],
  _features: {
    dragDrop: dragDropFeature({
      onDrop: (event, newDate) => {
        // Custom drop logic
        return true; // Allow drop
      },
    }),
  },
});

// Use drag and drop API
calendar.dragDrop.startDrag(event);
calendar.dragDrop.drop(newDate);

API Reference

Calendar Class

Constructor

new Calendar<TEvent, TResource>(options: CalendarOptions<TEvent, TResource>)

Methods

State Management

  • getState(): CalendarState<TEvent> - Get current state
  • setState(updater): void - Update state
  • subscribe(listener): () => void - Subscribe to all state changes
  • subscribeToSelector<T>(selector, listener): () => void - Subscribe to computed values
  • destroy(): void - Clean up resources

Navigation

  • next(): void - Go to next period
  • previous(): void - Go to previous period
  • goToDate(date): void - Go to specific date
  • today(): void - Go to today

Views

  • setView(viewId): void - Change view
  • getHeaderGroups(): Array<{id: string, headers: string[]}> - Get header data
  • getRowModel(): {rows: Row<TEvent>[]} - Get row model
  • getCells(): Cell<TEvent>[][] - Get cell data

Events

  • addEvent(event): void - Add event
  • updateEvent(id, updates): void - Update event
  • removeEvent(id): void - Remove event
  • getEventsForDate(date): TEvent[] - Get events for date
  • getEvents(): TEvent[] - Get events in visible range

Selection

  • selectDate(date, multi?): void - Select date
  • clearSelection(): void - Clear selection

Types

CalendarEvent

interface CalendarEvent<T = unknown> {
  id: string;
  start: Date;
  end: Date;
  data?: T;
}

CalendarState

interface CalendarState<
  TEvent extends CalendarEvent<unknown> = CalendarEvent<unknown>,
> {
  currentDate: Date;
  view: ViewConfig;
  events: TEvent[];
  selection: Date[];
  visibleRange: { start: Date; end: Date };
  gridDimensions: { rows: number; columns: number };
  draggedEvent?: TEvent | null;
  dropTarget?: Date | null;
  selectionMode?: 'single' | 'multiple';
}

Cell

interface Cell<TEvent extends CalendarEvent<unknown> = CalendarEvent<unknown>> {
  date: Date;
  row: number;
  col: number;
  events: TEvent[];
  isSelected: boolean;
  isToday: boolean;
  isCurrentMonth: boolean;
  meta: Record<string, unknown>;
  getCellProps?: () => Record<string, unknown>;
}

Features

Selection Feature

selectionFeature(options: {
  multiple?: boolean;
  range?: boolean;
}): Feature

Drag & Drop Feature

dragDropFeature(options: {
  onDrop?: (event: unknown, newDate: Date) => boolean;
}): Feature

Utilities

import {
  addDays,
  startOfMonth,
  endOfMonth,
  startOfWeek,
  isSameDay,
  isToday,
} from '@chronux/core';

Legacy API

The package also includes legacy utility functions for backward compatibility:

import {
  exampleFunction,
  exampleAsyncFunction,
  validateConfig,
} from '@chronux/core';

Development

This package is part of the Chronux monorepo. See the main README for development setup instructions.

License

MIT License - see LICENSE for details.