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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@cocrafts/graphql-lambda

v0.3.1

Published

GraphQL Lambda adapters for AWS Lambda functions with support for HTTP and WebSocket APIs, Redis storage, and distributed pub/sub.

Readme

@cocrafts/graphql-lambda

GraphQL Lambda adapters for AWS Lambda functions with support for HTTP and WebSocket APIs, Redis storage, and distributed pub/sub.

Installation

npm install @cocrafts/graphql-lambda

Features

  • Unified GraphQL Interface: Single schema works across HTTP, WebSocket, and Lambda environments
  • AWS Lambda Support: Native adapters for API Gateway HTTP and WebSocket APIs
  • Redis Integration: Distributed storage and pub/sub for serverless environments
  • Cross-Environment: Same GraphQL schema runs locally and on AWS Lambda

Serverless Considerations

Context Serialization Requirements

Context must be JSON serializable: All context data is persisted to Redis between Lambda invocations using flattened dot-notation (e.g., extra.user.id). Functions, classes, and circular references are not supported.

// Supported: Plain JSON data
ctx.extra.user = { id: '123', name: 'John', roles: ['admin'] };

// Not supported: Functions, circular references
ctx.extra.callback = () => console.log('hello');
ctx.extra.user.parent = ctx.extra.user;

Subscription Execution Model

No async iterators: Unlike server implementations, serverless uses a custom pubsub engine. Each subscription resolver runs once during setup, not for each published event. Published events are sent directly to clients without re-running GraphQL execution or validation.

// Server: Re-executes GraphQL for each event
for await (const event of asyncIterator) {
	yield await execute({ schema, document, rootValue: event });
}

// Serverless: Direct event forwarding
await pubsub.publish('topic', payload); // No re-execution

Key Limitations

  • No field-level filtering: Server implementations can filter/transform fields per event; serverless sends raw published payloads
  • No real-time validation: Schema changes don't affect in-flight subscriptions until reconnection
  • No per-event context: Published events don't have access to subscription-time context or variables
  • Context reconstruction: Context is rebuilt from Redis on each Lambda invocation

Best Practices

Context Management

onConnect: async ctx => {
	ctx.extra = {
		userId: await authenticateUser(ctx.connectionParams?.token),
		subscriptionCount: 0,
	};
	return true;
};

Subscription Design

// Design for direct payload forwarding
subscribe: () => pubsub.subscribe('CHAT_MESSAGE');

// Publish complete, typed payloads
await pubsub.publish('CHAT_MESSAGE', {
	messageAdded: {
		id: '123',
		text: 'Hello',
		timestamp: new Date().toISOString(),
	},
});

When to Use

Good for: Event-driven applications, infrequent real-time updates, variable traffic patterns, cost optimization.

Consider alternatives for: High-frequency updates, complex field filtering, low-latency requirements, heavy context usage.

Usage

Local Development

import { createHandler } from 'graphql-http/lib/use/http';
import { useServer } from 'graphql-ws/use/ws';
import { DefaultGraphQLPubSub } from '@cocrafts/graphql-pubsub';

const graphqlHandler = createHandler(graphqlHttpOptions);
useServer(graphqlWsOptions, wss);

AWS Lambda WebSocket

import { AWSGraphQLWsAdapter } from '@cocrafts/graphql-lambda';

const mergedOptions = {
	...graphqlWsOptions,
	storage,
	gateway,
	pubsub,
};

export const handler = AWSGraphQLWsAdapter(mergedOptions);

Shared Infrastructure

import { ApiGatewayManagementApiClient } from '@aws-sdk/client-apigatewaymanagementapi';
import { createClient } from 'redis';

export const redis = createClient({ url: 'redis://localhost:6379' });
export const gateway = new ApiGatewayManagementApiClient({
	region: 'us-east-1',
});

export const storage = {
	set: async (key: string, value: string) => await redis.set(key, value),
	get: async (key: string) => await redis.get(key),
};

Build

bun run build

Generates ESM, CommonJS, and TypeScript declaration files in the dist/ directory.