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

sineql

v1.0.5

Published

A simple to use graphQL clone

Downloads

361

Readme

sineQL

sineQL is a web API query language that mimics graphQL, designed solely for fun.

sineQL consists of two languages - the schema language, and the query language. sineQL assumes that the records are related in a non-looping tree-structure, defined by the schema language. Also, each non-scalar type queried is returned as an array.

The handler's definition is left up to the user.

Feature List

  • Easy to use schema language
  • Easy to use query language
  • Simple to set-up a server
  • Each top-level keyword (and queries) is optional
  • No package dependencies

Live Demo

Using the following schema:

type Weather {
	String city
	Float latitude
	Float longitude

	String last_updated
	Float temp_c
	Float temp_f
	String condition
	Float wind_mph
	Float wind_kph
	String wind_dir
}

You can match any city OR any latitude + longitude, then query any of the other fields.

curl sineql-demo.krgamestudios.com/sineql -L -X POST -H "Content-Type: text/plain" -d 'Weather { match city "Sydney" temp_c condition }'

Example Server

A simple express server using sineQL.

//express for testing
const express = require('express');
const app = express();

//uses text input
app.use(express.text());

//test the library
const sineQL = require('sineql');
const schema = require('./schema.js');
const queryHandlers = require('./query-handlers.js');

//omit 'createHandlers', 'updateHandlers' or 'deleteHandlers' to disable those methods
const sine = sineQL(schema, { queryHandlers }, { debug: true });

//open the endpoint
app.post('/sineql', async (req, res) => {
	const [code, result] = await sine(req.body);
	res.status(code).send(result);
});

//startup
const port = process.env.WEB_PORT || 4000;
app.listen(port, err => {
	console.log(`listening to *:${port}`);
});
const schema = `
scalar Date

type Book {
	String title
	Date published
	Float score
}

type Author {
	String name
	Boolean alive
	Book books
}
`;

module.exports = schema;
//there's a different handler object for query, create, update and delete
const queryHandlers = {
	Author: (query, graph) => {
		//TODO: implement this
	},
	Book: (query, graph) => {
		//TODO: implement this
	},
};

module.exports = queryHandlers;

Create a matching client-side function pointing to the server.

//create the wave function, wrapping a fetch to the server
const wave = body => fetch('http://example.com/sineql', {
	method: 'POST',
	headers: {
		'Content-Type': 'text/plain'
	},
	body: body
});

//get a list of content
wave('Author { name books { title } }')
	.then(blob => blob.text())
	.then(text => console.log(text))
	.catch(e => console.error(e))
;

The Schema Language

The schema language is a layout of how queries should be made, as well as what can be made with them. There are several built-in keywords for the schema language:

  • type
  • scalar
  • unique
  • typeName (this is a reserved keyword - it is not used in either language, but rather is used internally)

type is used for defining new compound types. scalar is for defining new scalar types, such as Date. unique is a modifier on a field, indicating that it is unique in the database.

The built-in types for the schema language are:

  • String
  • Integer
  • Float
  • Boolean

These can be combined into compound types as so:

scalar Date

type Book {
	unique String title
	Date published
}

type Author {
	unique String name
	Book books
}

The Query Language

The query langauge can be used to request data from a server, either in whole or in part by listing its type and its needed fields:

Author {
	name
	books {
		title
		published
	}
}

The fields can be altered as well, using the query language's built-in keywords:

  • create
  • update
  • delete
  • match

Create

When using create, match finds an existing record and associates that with the created values:

create Author {
	create name "Kenneth Grahame"
	match books {
		match title "The Wind in the Willows"
	}
}

You can create multiple records at once by surrounding them with []:

create Book [
	{
		create title "The Philosopher's Kidney Stone"
	}
	{
		create title "The Chamber Pot of Secrets"
	}
	{
		create title "The Prisoner of Aunt Kazban"
	}
	{
		create title "The Goblet of the Fire Cocktail"
	}
	{
		create title "The Order for Kleenex"
	}
	{
		create title "The Half-Priced Pharmacy"
	}
	{
		create title "Yeah, I Got Nothing"
	}
]

Update

When using update, match finds all existing records and updates those using the update keyword:

update Book {
	match title "The Wind in the Willows"
	update published "1908-04-01"
}
update Book {
	match title "The Wind in the Willows"
	update title "The Fart in the Fronds"
}

You can run multiple updates at once by surrounding them with []:

update Book [
	{
		match title "The Philosopher's Kidney Stone"
		update published "1997-06-26"
	}
	{
		match title "The Chamber Pot of Secrets"
		update published "1998-07-02"
	}
	{
		match title "The Prisoner of Aunt Kazban"
		update published "1999-07-08"
	}
	{
		match title "The Goblet of the Fire Cocktail"
		update published "2000-07-08"
	}
	{
		match title "The Order for Kleenex"
		update published "2003-06-21"
	}
	{
		match title "The Half-Priced Pharmacy"
		update published "2005-07-16"
	}
	{
		match title "Yeah, I Got Nothing"
		update published "2007-07-21"
	}
]

Delete

When using delete, only match is valid, and will delete all matching records:

delete Book {
	match title "The Fart in the Fronds"
}

You can run multiple deletes at once by surrounding them with []:

delete Book [
	{
		match title "The Philosopher's Kidney Stone"
	}
	{
		match title "The Chamber Pot of Secrets"
	}
	{
		match title "The Prisoner of Aunt Kazban"
	}
	{
		match title "The Goblet of the Fire Cocktail"
	}
	{
		match title "The Order for Kleenex"
	}
	{
		match title "The Half-Priced Pharmacy"
	}
	{
		match title "Yeah, I Got Nothing"
	}
]