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 🙏

© 2024 – Pkg Stats / Ryan Hefner

graphql-ssg

v0.4.8

Published

Simple data feed HTML bundler

Downloads

81

Readme

GraphQL SSG

NPM Version Build

It is the missing ingredient of Web Components architecture. Simple bundler for GraphQL based website using esmodules. What makes it unique? It uses browser for bundling (not node). Remember in ESModules you can use URL imports and relative imports. You can also provide importmap for other imports

Installation

Install globally

npm i -g graphql-ssg

How to use

Init a new project. This will create graphql-ssg.json in current directory. You don't need a package.json but you can add one for type completions.

graphql-ssg --init .

Set up config.

{
  "graphql": {
    "pokemon": {
      "url": "https://graphql-pokemon2.vercel.app/"
    }
  },
  "in": "./pages",
  "out": "./out",
  "websocketPort": 1414,
  "port": 8080
}

So you need to provide your schema url ( you can declare multiple schemas ) ,in and out dirs for graphql-ssg

You can also add headers if needed:

{
  "graphql": {
    "pokemon": {
      "url": "https://graphql-pokemon2.vercel.app/",
      "headers": {
        "Authorization": "Bearer MyToken"
      }
    }
  },
  "in": "./pages",
  "out": "./out",
  "websocketPort": 1414,
  "port": 8080
}

Watch

graphql-ssg

Build

graphql-ssg --build

How it works?

File must contain export default

String returned in contained in file export default is generated via SSG phase.

import { html } from './ssg/basic.js';
export default () => {
  return html`
    <div>Hello world</div>
  `;
};

To have syntax coloring in html pleas install appropriate litelement extension for your IDE.

Config

Config file can be generated or created manually. It should contain all the following values.

{
  "graphql": {
    "feature-mole": {
      "url": "https://faker.graphqleditor.com/explore-projects/feature-mole/graphql"
    }
  },
  "in": "./pages",
  "out": "./out",
  "websocketPort": 1416,
  "port": 8082
}

Typescript

Turn on typescript support URL imports also works here. Of course you can still import relative modules.

{
  "graphql": {
    "feature-mole": {
      "url": "https://faker.graphqleditor.com/explore-projects/feature-mole/graphql"
    }
  },
  "in": "./pages",
  "out": "./out",
  "websocketPort": 1416,
  "port": 8082,
  "mode": "typescript"
}

Config Injection

Config file is injected and typed. It is available only inside export default and export const head function to prevent leaking of secrets.

Usage in JS example:

const graphQLClient = Chain(ssg.config.HOST, {
  headers: {
    Authorization: `Bearer ${ssg.config.TOKEN}`,
  },
});

Environment variables

Environment variables must be put side by side to graphql-ssg.json in .env file.It is available only inside export default and export const head .

Usage in JS example:

const graphQLClient = Chain(ssg.env.HOST, {
  headers: {
    Authorization: `Bearer ${ssg.env.TOKEN}`,
  },
});

It is available only inside export default and export const head function to prevent leaking of secrets.

Injected built in helper code syntax functions

GraphQL SSG comes with generated library

Chain

Works like fetch to GraphQL, where you need to provide host and/or options to receive fully Autocompleted client for schema url from your config.

import { Chain } from './ssg/main-schema/index.js';
const graphQLClient = Chain(ssg.config.graphql['main-schema'].url);

const response = await graphQLClient.query({ people: true });

html

It doesnt transform html in any way, but gives you syntax coloring

import { html } from './ssg/basic.js';
const ADiv = html`
  <div>Hello world</div>
`;

md

It renders markdown using remarkable renderer so it is transformed to html.

import { md } from './ssg/md.js';
const MarkdownContent = md`
# Title of my Story

blah blah blah blah blah blah

## How to read it?
`;

head

import { html } from './ssg/basic.js';
export const head = () => html`<title>Hello world!</div>`;

data, hydrate

Data function is used for so called data hydration in JSX frameworks and others also. It is used for Static Site rendered websites to be able to consume the data and work on client side. So you need to handle both data and hydrate functions yourself so they can be executed on output script.

// Create your app
export const data = async () => {
  const Fetch = Chain(ssg.config.graphql.pokemon.url, {
    headers: {
      'Content-Type': 'application/json',
    },
  });
  return Fetch.query({
    pokemons: [
      { first: 151 },
      {
        number: true,
        name: true,
        image: true,
        types: true,
        resistant: true,
        weaknesses: true,
      },
    ],
  });
};

type DataType = ReturnType<typeof data> extends Promise<infer R> ? R : never;

export const hydrate = async (staticData: DataType) =>
  ReactDOM.hydrate(<PokemonApp response={staticData} />, document.body);

export default async (staticData: DataType) => {
  const renderBody = document.createElement('div');
  ReactDOM.render(<PokemonApp response={staticData} />, renderBody);
  return renderBody.innerHTML;
};

pages

If you export pages function you can generate multiple pages per one file. This is useful for example for single blog post page. It takes

export const data = async () => {
  const Fetch = Chain(ssg.config.graphql.pokemon.url, {
    headers: {
      'Content-Type': 'application/json',
    },
  });
  return Fetch.query({
    pokemons: [
      { first: 5 },
      {
        number: true,
        name: true,
        image: true,
        types: true,
        resistant: true,
        weaknesses: true,
      },
    ],
  });
};

type DataType = ReturnType<typeof data> extends Promise<infer R> ? R : never;

export const pages = (staticData: DataType) => {
  return staticData.pokemons?.map((p) => {
    const renderBody = document.createElement('div');
    ReactDOM.render(<PokemonApp {...p} />, renderBody);
    return {
      slug: p.name?.split(' ')[0],
      body: renderBody.innerHTML,
      data: p,
      head: html`
        <title>${p.name || ''}</title>
        <link href="../index.css" rel="stylesheet" type="text/css" />
      `,
    };
  });
};

Assets

You can use them as normally.

Type Streaming

For example: If you use url that begins with https://cdn.skypack.dev in your import. It will try to fetch typings from skypack and save them in typings folder referencing to jsconfig. This should provide typings for example in VSCode.

Roadmap

  • [x] Add esbuild
  • [x] Add TS support
  • [x] Add intelligent .d.ts autocompletion for imported es modules
  • [x] Add image supports
  • [x] Generate tsconfig
  • [x] Relative imports
  • [x] Allow head modification
  • [x] Pass env to browser
  • [x] Provide a way to inject config
  • [x] TSConfig generation for included declarations to work
  • [x] Make zeus configurable and importable file
  • [ ] Clear error handling with line numbers
  • [x] split utility functions css,html,md from zeus
  • [x] allow to auto-zeus multiple schemas
  • [x] Types from url streaming
  • [x] JSX, TSX support
  • [ ] Provide verbose info levels
  • [ ] Create docs deployable to pages
  • [ ] Resolve imports with no extension
  • [ ] generate ts functions for ts projects
  • [ ] catch esbuild transform errors
  • [x] support files exporting multiple static pages
  • [ ] Add possibility to override html tag