receta
Collection

Common Patterns & Production Recipes

Real-world patterns from GitHub, Reddit, Stripe, and more.

Social Media: Reddit-Style Comments

import { nest, paginate } from '@ontologyio/receta/collection'
import { getPath } from '@ontologyio/receta/object'
import { unwrapOr as unwrapOptionOr } from '@ontologyio/receta/option'
import { pipe } from 'remeda'

// Hierarchical comment display
const displayComments = (comments: Comment[], userId: number, postId: number) =>
  pipe(
    comments,
    nest<Comment>(['userId', 'postId']),
    getPath<Comment[]>([userId, postId]),
    unwrapOptionOr<Comment[]>([]),
    paginate({ page: 1, pageSize: 20 })
  )

E-commerce: Order Tracking

import { diff } from '@ontologyio/receta/collection'

// Detect order status changes for notifications
const trackOrderChanges = (oldOrders: Order[], newOrders: Order[]) => {
  const changes = diff(oldOrders, newOrders, o => o.id)
  
  for (const { old, new: updated } of changes.updated) {
    if (old.status !== updated.status) {
      sendNotification({
        orderId: updated.id,
        oldStatus: old.status,
        newStatus: updated.status,
        customer: updated.customerId
      })
    }
  }
  
  return changes
}

API Design: GitHub-Style Pagination

import { paginateCursor } from '@ontologyio/receta/collection'

// Cursor-based API endpoint
app.get('/api/events', (req, res) => {
  const result = paginateCursor(
    events,
    e => e.id,
    {
      cursor: req.query.cursor as string,
      limit: Number(req.query.limit) || 50
    }
  )
  
  res.json({
    data: result.items,
    pagination: {
      next_cursor: result.nextCursor,
      has_more: result.hasMore
    }
  })
})

State Management: Redux Normalization

import { indexByUnique } from '@ontologyio/receta/collection'
import { unwrapOr } from '@ontologyio/receta/result'

const normalizeEntities = <T extends { id: string }>(entities: T[]) =>
  pipe(
    entities,
    indexByUnique(e => e.id, { onCollision: 'last' }),
    unwrapOr({})
  )

const store = {
  users: normalizeEntities(users),
  posts: normalizeEntities(posts),
  comments: normalizeEntities(comments)
}

Access Control: Permission Merging

import { union } from '@ontologyio/receta/collection'

type Permission = { resource: string; action: string }

const getUserPermissions = (userId: string) => {
  const roles = getUserRoles(userId)
  const permissions: Permission[] = roles.flatMap(role => getRolePermissions(role))
  
  // union checks the second list against what it has kept so far,
  // so the list to deduplicate goes second
  return union<Permission>(
    [],
    permissions,
    (a, b) => a.resource === b.resource && a.action === b.action
  )
}

On this page