data-layer | Skill Performance & Reviews | TopRankSkills

TopRank Skills

Home / Skills / tools / data-layer

data-layer

maintained by ethereum

star 5.8k account_tree 5.4k verified_user MIT License
bolt View GitHub

name: data-layer description: This skill provides patterns for working with the data-layer module. Use when creating/editing files in src/data-layer/, src/lib/data/, or adding new data sources.

Data Layer

Architecture

src/data-layer/
├── fetchers/         # Fetch functions (one per data source)
├── index.ts          # Public API - typed getter functions
├── tasks.ts          # KEYS constant + Trigger.dev scheduled tasks
├── storage.ts        # get/set abstraction (Netlify Blobs or mock files)
└── mocks/            # Mock data files for local development

src/lib/data/
└── index.ts          # Next.js caching adapter (createCachedGetter)

Key Files

tasks.ts - Single Source of Truth

Defines all task keys and scheduled jobs:

export const KEYS = {
  ETH_PRICE: "fetch-eth-price",
  L2BEAT: "fetch-l2beat",
  // ...
} as const

const DAILY: Task[] = [
  [KEYS.APPS, fetchApps],
  [KEYS.EVENTS, fetchEvents],
]

const HOURLY: Task[] = [
  [KEYS.ETH_PRICE, fetchEthPrice],
  [KEYS.BEACONCHAIN, fetchBeaconChain],
]

index.ts - Simple Getters

One-liner passthrough functions:

export const getEthPrice = () => get<MetricReturnData>(KEYS.ETH_PRICE)
export const getL2beatData = () => get<L2beatData>(KEYS.L2BEAT)

storage.ts - Storage Abstraction

Simple get/set that switches between Netlify Blobs (prod) and local JSON files (dev):

export async function get<T>(key: string): Promise<T | null>
export async function set(key: string, data: unknown): Promise<void>

Uses USE_MOCK_DATA=true env var for local development.

Rules

1. Getters must be pure passthrough

No transformations in index.ts - just get<T>(KEYS.X):

// Correct
export const getEventsData = () => get<EventItem[]>(KEYS.EVENTS)

// Wrong - no transformations in getters
export const getEventsData = () => {
  const data = await get<EventItem[]>(KEYS.EVENTS)
  return data?.map(transform) ?? null
}

All transformations belong in the fetcher (src/data-layer/fetchers/).

2. KEYS is the single source of truth

All task IDs are defined in KEYS in tasks.ts. The getter in index.ts and the task tuple in DAILY/HOURLY must use the same key.

3. Expose via lib/data for caching

Add cached wrapper in src/lib/data/index.ts:

export const getEventsData = createCachedGetter(
  dataLayer.getEventsData,
  ["events-data"],
  CACHE_REVALIDATE_DAY  // or CACHE_REVALIDATE_HOUR
)

Adding a New Data Source

  1. Create fetcher in src/data-layer/fetchers/fetchNewData.ts:

    export async function fetchNewData(): Promise<YourDataType> {
      // Fetch and transform data here
    }
    
  2. Add key to KEYS in src/data-layer/tasks.ts:

    export const KEYS = {
      // ...existing keys
      NEW_DATA: "fetch-new-data",
    } as const
    
  3. Add task tuple to DAILY or HOURLY in tasks.ts:

    const DAILY: Task[] = [
      // ...existing tasks
      [KEYS.NEW_DATA, fetchNewData],
    ]
    
  4. Add getter in src/data-layer/index.ts:

    export const getNewData = () => get<YourDataType>(KEYS.NEW_DATA)
    
  5. Add mock file at src/data-layer/mocks/fetch-new-data.json for local development

  6. Add cached wrapper in src/lib/data/index.ts:

    export const getNewData = createCachedGetter(
      dataLayer.getNewData,
      ["new-data"],
      CACHE_REVALIDATE_HOUR
    )
    

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!

Skill Details

GitHub Stars 5.8k
GitHub Forks 5.4k
Created Jan 2026
Last Updated 6个月前
tools tools data engineering

Related Skills

prisma-expert
chevron_right
dbt-migration-transact
chevron_right
execplan
chevron_right
manus-project-expert
chevron_right
vespertide
chevron_right

Build your own?

Join 12,000+ developers contributing to the Claude ecosystem.