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

@t8n/gql

v1.0.3

Published

A professional, high-performance GraphQL execution extension for TitanPL. Built to seamlessly integrate GraphQL queries with Titan's synchronous Gravity engine and native `drift` asynchronous suspender.

Readme

@t8n/gql

A professional, high-performance GraphQL execution extension for TitanPL. Built to seamlessly integrate GraphQL queries with Titan's synchronous Gravity engine and native drift asynchronous suspender.

Key Features

  1. Drift Suspend Integration: Integrated with the Titan PL Drift runner. Run the gql init command to patch the graphql-js executor to cleanly handle __SUSPEND__ signals, allowing standard drift(...) async operations to resolve synchronously within query and field resolvers.
  2. Zero-Import Schema Builder: Declare GraphQL types cleanly as JavaScript scope constants using gql.builder(). Core scalars (builder.ID, builder.String, builder.Boolean, builder.Int, builder.Float) and lists (builder.list(Type)) are exposed directly on the builder instance, eliminating the need to import a separate type registry.
  3. Zero-Annotation Resolver Autocomplete: In JS files, parameters in field resolvers default to any. By using the standard JavaScript default parameter syntax todo = Todo, the type compiler automatically infers the parameter's type as the exact shape of Todo. At runtime, the GraphQL executor passes the parent object, so the default value is never evaluated. This yields 100% type safety and IDE autocomplete with zero JSDoc annotations.
  4. Type-Level Resolvers: Keep schema execution separate and clean. You can pass a standard type-level resolvers map configuration (e.g. { Todo: { user: resolver } }) rather than writing manual .map() loops and inline field methods inside your root query resolvers.
  5. Pure Native Titan Runtime: Fully optimized for Gravity sandboxes. Action execution is completely decoupled from filesystem dependencies and Node.js shims, running seamlessly within restricted V8 action isolates.

Installation

npm i @t8n/gql

Initialize GQL Patcher

After installing the package, run the initialization command to patch the graphql executor files in your project:

npx gql init

Usage Guide

Here is a complete type-safe, drift-integrated action implementation using @t8n/gql:

/* eslint-disable titanpl/drift-only-titan-async */
import { defineAction, fetch } from "@titanpl/native";
import Gql, { gql } from "@t8n/gql";

// 1. Initialize the Schema Builder
const builder = gql.builder();

// 2. Define Schema Types as JS Constants (using builder scalars)
const User = builder.type("User", {
    id: builder.ID.required,
    name: builder.String.required,
    username: builder.String.required,
    email: builder.String.required,
    phone: builder.String.required
});

const Todo = builder.type("Todo", {
    userId: builder.String.required,
    id: builder.ID.required,
    title: builder.String.required,
    completed: builder.Boolean,
    user: User // Reference User type directly
});

const Query = builder.type("Query", {
    getTodos: builder.list(Todo), // Define lists
    "getTodo(id: ID!)": Todo,
    "getUserTodos(userId: String!)": builder.list(Todo)
});

// 3. Compile the GraphQL Schema SDL
const schema = builder.build();

// 4. Define Root Resolvers
const root = {
    getTodos() {
        // Perform synchronous-like native fetch suspended under drift
        const res = drift(fetch("https://jsonplaceholder.typicode.com/todos"));
        return JSON.parse(res.body);
    },
    getTodo({ id }) {
        const res = drift(fetch(`https://jsonplaceholder.typicode.com/todos/${id}`));
        return JSON.parse(res.body);
    },
    getUserTodos({ userId }) {
        const res = drift(fetch(`https://jsonplaceholder.typicode.com/todos?userId=${userId}`));
        return JSON.parse(res.body);
    }
};

// 5. Define Nested Type-Level Field Resolvers
const resolvers = {
    Todo: {
        // Use default parameter 'todo = Todo' to gain perfect IDE autocomplete
        user(todo = Todo) {
            // todo.userId, todo.id, todo.title will autocomplete automatically!
            const res = drift(fetch(`https://jsonplaceholder.typicode.com/users/${todo.userId}`));
            return JSON.parse(res.body);
        }
    }
};

// 6. Instantiate the GraphQL service
const gqlService = new Gql({
    schema,
    rootValue: root,
    resolvers
});

// 7. Define and export the Titan Action
export default defineAction((req) => {
    return gqlService.execute({
        query: req.body.query,
        variables: req.body.variables
    });
});

Connecting to a React Frontend (Vite)

To connect your React frontend to your TitanPl GraphQL action, follow this standard pattern:

1. Define a POST Route in TitanPl

Since GraphQL query payloads contain JSON requests, ensure your TitanPl router (app.js) exposes the action via a POST route:

import t from "@titanpl/route";

// Maps POST /test HTTP requests directly to your graphql action 'test.js'
t.post("/test").action("test");

2. Configure Vite Local Proxy

To avoid CORS issues when making local network requests between the Vite dev server (e.g. http://localhost:5173) and the TitanPl server (e.g. http://localhost:5100), configure a proxy in vite.config.js:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  server: {
    proxy: {
      '/test': {
        target: 'http://localhost:5100', // Redirects local /test calls to Titan server
        changeOrigin: true
      }
    }
  }
})

3. Make HTTP Fetch Queries in React

Submit your query and variables using a standard POST request:

const handleExecute = async () => {
  const query = `
    query GetTodo($todoId: ID!) {
      getTodo(id: $todoId) {
        id
        title
        completed
        user {
          name
        }
      }
    }
  `;

  const variables = { todoId: "5" };

  const res = await fetch('/test', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ query, variables }),
  });

  const response = await res.json();
  console.log("GraphQL Data:", response.data);
};

How It Works Under The Hood

  • Isolation and Suspend Handling: Standard GraphQL engines expect async resolvers to return Promises, which breaks the Gravity Engine's synchronous isolate design. The patched execution runtime intercepts resolver errors and propagates the __SUSPEND__ signal all the way up to the top handler of the engine.
  • CLI-Driven Patcher: The gql init command patches both CJS (Executor.js) and ESM (Executor.mjs) inside the graphql package folder on the local file system. Doing this via CLI ensures that the engine runtime remains clean, fast, and compatible with sandboxed isolates.
  • Contextual Auto-Suggestions: By declaring GraphQL types as JavaScript variables (User = builder.type(...)), the IDE natively tracks type scopes and references. This allows clicking a field reference to navigate to its definition and gives you instant hover previews.