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

neuroline-nextjs

v0.5.1

Published

Next.js App Router handlers for Neuroline pipeline APIs.

Readme

Next.js App Router handlers for Neuroline pipeline APIs.

English | Русский

neuroline-nextjs

Demo GitHub

Next.js App Router integration for Neuroline - provides route handlers for API routes.

Installation

yarn add neuroline neuroline-nextjs

Features

  • App Router Support - native Next.js 14+ App Router integration
  • Type-Safe Handlers - full TypeScript support with NextRequest/Response
  • One Route = One Pipeline - each route handles exactly one pipeline type
  • Job Details API - get input, options, and artifacts for individual jobs
  • Stateless Design - works with serverless deployments

Quick Start

1. Create Pipeline Manager

// lib/neuroline.ts
import { PipelineManager, InMemoryPipelineStorage } from 'neuroline';

const storage = new InMemoryPipelineStorage();
export const manager = new PipelineManager({ storage });
export { storage };

2. Create API Route Handler

Create a separate route for each pipeline. For example app/api/pipeline/my-pipeline/route.ts:

import { createPipelineRouteHandler } from 'neuroline-nextjs';
import { manager, storage } from '@/lib/neuroline';
import { myPipelineConfig } from '@/pipelines';

const handlers = createPipelineRouteHandler({
    manager,
    storage,
    pipeline: myPipelineConfig, // One pipeline per route
});

export const GET = handlers.GET;
export const POST = handlers.POST;

That's it! Your pipeline API is ready at /api/pipeline/my-pipeline.

API Endpoints

Each route handles one pipeline. The URL determines which pipeline to use.

POST /api/pipeline/my-pipeline

Start a new pipeline or return existing one.

Request body:

{
  input: unknown;        // Input data
  jobOptions?: Record<string, unknown>;  // Optional job options
}

Example:

const response = await fetch('/api/pipeline/my-pipeline', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    input: {
      url: 'https://api.example.com/data',
      userId: 'user-123',
    },
    jobOptions: {
      'fetch-data': { timeout: 10000 },
    },
  }),
});

const result = await response.json();
// { success: true, data: { pipelineId: "abc123", isNew: true } }

GET /api/pipeline/my-pipeline?action=status&id=:id

Get current pipeline status.

Example:

const response = await fetch('/api/pipeline/my-pipeline?action=status&id=abc123');
const { data } = await response.json();
// { status: "processing", currentJobIndex: 1, totalJobs: 4, stages: [...] }

GET /api/pipeline/my-pipeline?action=result&id=:id[&jobName=:name]

Get a job result (artifact). If jobName is not provided, returns the last job result.

Example:

// Last job result
const response = await fetch('/api/pipeline/my-pipeline?action=result&id=abc123');
const { data } = await response.json();
// { pipelineId: "abc123", jobName: "save-result", status: "done", artifact: {...} }

// Result by job name
const response2 = await fetch('/api/pipeline/my-pipeline?action=result&id=abc123&jobName=fetch-data');
const { data: jobResult } = await response2.json();
// { pipelineId: "abc123", jobName: "fetch-data", status: "done", artifact: {...} }

Debug Endpoints

The following endpoints return sensitive data (input, options, artifacts) and are disabled by default. To enable them, set enableDebugEndpoints: true.

⚠️ WARNING: Do not enable in production unless you have proper authentication/authorization!

GET /api/pipeline/my-pipeline?action=job&id=:id&jobName=:name

Get detailed job data including input and options.

Example:

const response = await fetch('/api/pipeline/my-pipeline?action=job&id=abc123&jobName=fetch-data');
const { data } = await response.json();
// { name: "fetch-data", status: "done", input: {...}, options: {...}, artifact: {...} }

GET /api/pipeline/my-pipeline?action=pipeline&id=:id

Get full pipeline state.

Example:

const response = await fetch('/api/pipeline/my-pipeline?action=pipeline&id=abc123');
const { data } = await response.json();
// Full PipelineState object

GET /api/pipeline/my-pipeline?action=list

Get paginated list of pipelines of this type.

Query parameters:

  • page - Page number (default: 1)
  • limit - Items per page (default: 10, max: 100)

Example:

const response = await fetch('/api/pipeline/my-pipeline?action=list&page=1&limit=10');
const { data } = await response.json();
// { items: [...], total: 50, page: 1, limit: 10, totalPages: 5 }

With MongoDB Storage

For production, use MongoDB storage:

// lib/neuroline.ts
import mongoose from 'mongoose';
import { PipelineManager, MongoPipelineStorage, PipelineSchema } from 'neuroline';
import { myPipelineConfig } from './pipelines';

// Connect to MongoDB
await mongoose.connect(process.env.MONGODB_URI!);

// Create model
const PipelineModel = mongoose.model('Pipeline', PipelineSchema);

// Create manager
const storage = new MongoPipelineStorage(PipelineModel);
export const manager = new PipelineManager({ storage });

manager.registerPipeline(myPipelineConfig);

Client-Side Usage

Use neuroline/client for client-side integration. One client per pipeline:

'use client';

import { useMemo, useState, useCallback } from 'react';
import { PipelineClient } from 'neuroline/client';

export function PipelineDemo() {
  // Client URL points to specific pipeline route
  const client = useMemo(() => new PipelineClient({ baseUrl: '/api/pipeline/my-pipeline' }), []);
  const [status, setStatus] = useState(null);
  const [isRunning, setIsRunning] = useState(false);

  const handleStart = useCallback(async () => {
    setIsRunning(true);
    
    const { pipelineId, stop, completed } = await client.startAndPoll(
      {
        input: { url: 'https://api.example.com/data' },
      },
      (event) => setStatus(event.status),
      (error) => console.error(error),
    );

    await completed;
    setIsRunning(false);
  }, [client]);

  return (
    <div>
      <button onClick={handleStart} disabled={isRunning}>
        Start Pipeline
      </button>
      {status && (
        <div>
          Status: {status.status}
          {status.currentJobName && ` - ${status.currentJobName}`}
        </div>
      )}
    </div>
  );
}

Configuration Options

createPipelineRouteHandler({
  manager: PipelineManager,     // Required - pipeline manager instance
  storage: PipelineStorage,     // Required - storage for job details and list
  pipeline: PipelineConfig,     // Required - pipeline config for this route
  enableDebugEndpoints: false,  // Optional - enable action=job and action=pipeline (default: false)
});

Enabling Debug Endpoints

For development or internal tools, you can enable debug endpoints:

const handlers = createPipelineRouteHandler({
  manager,
  storage,
  pipeline: myPipeline,
  enableDebugEndpoints: process.env.NODE_ENV === 'development',
});

Error Handling

The handler automatically returns appropriate HTTP status codes:

  • 200 - Success
  • 400 - Bad request (invalid input)
  • 404 - Pipeline not found
  • 500 - Internal server error

All errors return JSON format:

{
  "error": "Error message"
}

Serverless Deployment

This package is fully compatible with serverless deployments (Vercel, Netlify, etc.):

// Use MongoDB or external storage
// In-memory storage will not persist across function invocations
const storage = new MongoPipelineStorage(PipelineModel);
const manager = new PipelineManager({ storage });

API Reference

createPipelineRouteHandler(options)

Creates GET and POST handlers for Next.js App Router.

Parameters:

  • manager: PipelineManager - Required. The pipeline manager instance.
  • storage: PipelineStorage - Required. Storage for job details and list operations.
  • pipeline: PipelineConfig - Required. Pipeline config for this route.

Returns:

{
  GET: (request: NextRequest) => Promise<Response>,
  POST: (request: NextRequest) => Promise<Response>
}

Multiple Pipelines

Create separate routes for each pipeline:

app/
  api/
    pipeline/
      my-pipeline/
        route.ts    → handles /api/pipeline/my-pipeline
      another/
        route.ts    → handles /api/pipeline/another

Each route exports handlers for its specific pipeline.

Individual Handlers

You can also use individual handlers for custom routing:

import {
  handleStartPipeline,
  handleGetStatus,
  handleGetResult,
  handleGetJob,
  handleGetPipeline,
  handleGetList,
} from 'neuroline-nextjs';

License

UNLICENSED


neuroline-nextjs

Demo GitHub

Интеграция с Next.js App Router для Neuroline - предоставляет обработчики маршрутов для API.

Установка

yarn add neuroline neuroline-nextjs

Возможности

  • Поддержка App Router - нативная интеграция с Next.js 14+ App Router
  • Типобезопасные обработчики - полная поддержка TypeScript с NextRequest/Response
  • Один route = один pipeline - каждый маршрут обрабатывает ровно один тип pipeline
  • API деталей job - получение input, options и артефактов для отдельных jobs
  • Stateless дизайн - работает с serverless деплоями

Быстрый старт

1. Создайте Pipeline Manager

// lib/neuroline.ts
import { PipelineManager, InMemoryPipelineStorage } from 'neuroline';

const storage = new InMemoryPipelineStorage();
export const manager = new PipelineManager({ storage });
export { storage };

2. Создайте обработчик API маршрута

Создайте отдельный маршрут для каждого pipeline. Например app/api/pipeline/my-pipeline/route.ts:

import { createPipelineRouteHandler } from 'neuroline-nextjs';
import { manager, storage } from '@/lib/neuroline';
import { myPipelineConfig } from '@/pipelines';

const handlers = createPipelineRouteHandler({
    manager,
    storage,
    pipeline: myPipelineConfig, // Один pipeline на route
});

export const GET = handlers.GET;
export const POST = handlers.POST;

Готово! Ваш pipeline API доступен по адресу /api/pipeline/my-pipeline.

API Эндпоинты

Каждый route обрабатывает один pipeline. URL определяет какой pipeline использовать.

POST /api/pipeline/my-pipeline

Запустить новый pipeline или вернуть существующий.

Тело запроса:

{
  input: unknown;        // Входные данные
  jobOptions?: Record<string, unknown>;  // Опционально: опции для jobs
}

Пример:

const response = await fetch('/api/pipeline/my-pipeline', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    input: {
      url: 'https://api.example.com/data',
      userId: 'user-123',
    },
    jobOptions: {
      'fetch-data': { timeout: 10000 },
    },
  }),
});

const result = await response.json();
// { success: true, data: { pipelineId: "abc123", isNew: true } }

GET /api/pipeline/my-pipeline?action=status&id=:id

Получить текущий статус pipeline.

Пример:

const response = await fetch('/api/pipeline/my-pipeline?action=status&id=abc123');
const { data } = await response.json();
// { status: "processing", currentJobIndex: 1, totalJobs: 4, stages: [...] }

GET /api/pipeline/my-pipeline?action=result&id=:id[&jobName=:name]

Получить результат (артефакт) job. Если jobName не передан, возвращается результат последней job.

Пример:

// Результат последней job
const response = await fetch('/api/pipeline/my-pipeline?action=result&id=abc123');
const { data } = await response.json();
// { pipelineId: "abc123", jobName: "save-result", status: "done", artifact: {...} }

// Результат по имени job
const response2 = await fetch('/api/pipeline/my-pipeline?action=result&id=abc123&jobName=fetch-data');
const { data: jobResult } = await response2.json();
// { pipelineId: "abc123", jobName: "fetch-data", status: "done", artifact: {...} }

Debug-эндпоинты

Следующие эндпоинты возвращают чувствительные данные (input, options, artifacts) и отключены по умолчанию. Для включения установите enableDebugEndpoints: true.

⚠️ ВНИМАНИЕ: Не включайте в production без надлежащей аутентификации/авторизации!

GET /api/pipeline/my-pipeline?action=job&id=:id&jobName=:name

Получить детальные данные job включая input и options.

Пример:

const response = await fetch('/api/pipeline/my-pipeline?action=job&id=abc123&jobName=fetch-data');
const { data } = await response.json();
// { name: "fetch-data", status: "done", input: {...}, options: {...}, artifact: {...} }

GET /api/pipeline/my-pipeline?action=pipeline&id=:id

Получить полное состояние pipeline.

Пример:

const response = await fetch('/api/pipeline/my-pipeline?action=pipeline&id=abc123');
const { data } = await response.json();
// Полный объект PipelineState

GET /api/pipeline/my-pipeline?action=list

Получить пагинированный список pipelines этого типа.

Query-параметры:

  • page - Номер страницы (по умолчанию: 1)
  • limit - Элементов на странице (по умолчанию: 10, макс: 100)

Пример:

const response = await fetch('/api/pipeline/my-pipeline?action=list&page=1&limit=10');
const { data } = await response.json();
// { items: [...], total: 50, page: 1, limit: 10, totalPages: 5 }

С MongoDB хранилищем

Для продакшена используйте MongoDB:

// lib/neuroline.ts
import mongoose from 'mongoose';
import { PipelineManager, MongoPipelineStorage, PipelineSchema } from 'neuroline';
import { myPipelineConfig } from './pipelines';

// Подключение к MongoDB
await mongoose.connect(process.env.MONGODB_URI!);

// Создание модели
const PipelineModel = mongoose.model('Pipeline', PipelineSchema);

// Создание manager
const storage = new MongoPipelineStorage(PipelineModel);
export const manager = new PipelineManager({ storage });

manager.registerPipeline(myPipelineConfig);

Использование на клиенте

Используйте neuroline/client для клиентской интеграции. Один клиент на pipeline:

'use client';

import { useMemo, useState, useCallback } from 'react';
import { PipelineClient } from 'neuroline/client';

export function PipelineDemo() {
  // URL клиента указывает на конкретный route pipeline
  const client = useMemo(() => new PipelineClient({ baseUrl: '/api/pipeline/my-pipeline' }), []);
  const [status, setStatus] = useState(null);
  const [isRunning, setIsRunning] = useState(false);

  const handleStart = useCallback(async () => {
    setIsRunning(true);
    
    const { pipelineId, stop, completed } = await client.startAndPoll(
      {
        input: { url: 'https://api.example.com/data' },
      },
      (event) => setStatus(event.status),
      (error) => console.error(error),
    );

    await completed;
    setIsRunning(false);
  }, [client]);

  return (
    <div>
      <button onClick={handleStart} disabled={isRunning}>
        Запустить Pipeline
      </button>
      {status && (
        <div>
          Статус: {status.status}
          {status.currentJobName && ` - ${status.currentJobName}`}
        </div>
      )}
    </div>
  );
}

Опции конфигурации

createPipelineRouteHandler({
  manager: PipelineManager,     // Обязательно - экземпляр pipeline manager
  storage: PipelineStorage,     // Обязательно - хранилище для деталей job и списка
  pipeline: PipelineConfig,     // Обязательно - конфиг pipeline для этого route
  enableDebugEndpoints: false,  // Опционально - включить action=job и action=pipeline (по умолчанию: false)
});

Включение debug-эндпоинтов

Для разработки или внутренних инструментов можно включить debug-эндпоинты:

const handlers = createPipelineRouteHandler({
  manager,
  storage,
  pipeline: myPipeline,
  enableDebugEndpoints: process.env.NODE_ENV === 'development',
});

Обработка ошибок

Обработчик автоматически возвращает соответствующие HTTP коды:

  • 200 - Успех
  • 400 - Неверный запрос (невалидные данные)
  • 404 - Pipeline не найден
  • 500 - Внутренняя ошибка сервера

Все ошибки возвращаются в JSON формате:

{
  "error": "Сообщение об ошибке"
}

Serverless деплой

Этот пакет полностью совместим с serverless деплоями (Vercel, Netlify и др.):

// Используйте MongoDB или внешнее хранилище
// In-memory хранилище не сохраняется между вызовами функций
const storage = new MongoPipelineStorage(PipelineModel);
const manager = new PipelineManager({ storage });

API Reference

createPipelineRouteHandler(options)

Создаёт GET и POST обработчики для Next.js App Router.

Параметры:

  • manager: PipelineManager - Обязательно. Экземпляр pipeline manager.
  • storage: PipelineStorage - Обязательно. Хранилище для деталей job и операций списка.
  • pipeline: PipelineConfig - Обязательно. Конфиг pipeline для этого route.

Возвращает:

{
  GET: (request: NextRequest) => Promise<Response>,
  POST: (request: NextRequest) => Promise<Response>
}

Несколько Pipelines

Создайте отдельные routes для каждого pipeline:

app/
  api/
    pipeline/
      my-pipeline/
        route.ts    → обрабатывает /api/pipeline/my-pipeline
      another/
        route.ts    → обрабатывает /api/pipeline/another

Каждый route экспортирует обработчики для своего конкретного pipeline.

Отдельные обработчики

Вы также можете использовать отдельные обработчики для кастомной маршрутизации:

import {
  handleStartPipeline,
  handleGetStatus,
  handleGetResult,
  handleGetJob,
  handleGetPipeline,
  handleGetList,
} from 'neuroline-nextjs';

License

UNLICENSED