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

@facetlayer/qc

v0.1.1

Published

(Yet another) config file format.

Downloads

29

Readme

@facetlayer/qc

Overview

(Yet another) config file format.

Notable features are:

  • Every line has a 'command'.
  • It's possible for a 'command' to appear multiple times. (which makes this format more similar to XML than JSON/YAML/etc).
  • The command syntax is easy to type and would work great in a CLI or REPL.

Quick Start

import { toQuery, parseFile } from '@facetlayer/qc'

// Parse a simple query
const query = toQuery("deploy app=myapp env=prod")
console.log(query.command) // "deploy"
console.log(query.getStringValue("app")) // "myapp"
console.log(query.getStringValue("env")) // "prod"

// Parse a file with multiple queries
const queries = parseFile(`
  config host=localhost port=3000
  deploy app=frontend
  # This is a comment
  notify [email protected]
`)

QC Syntax

Basic Syntax

command arg1 arg2=value arg3="quoted value"
  • Command: The first element (required)
  • Tags: Space-separated attributes with optional values
  • Values: Can be strings, numbers, or nested structures
  • Comments: Lines starting with # are ignored

Examples

# Simple command with arguments
start server port=8080

# String values (quotes optional unless containing spaces)
config name="My App" debug=true timeout=30

# Nested structures using parentheses
deploy app=(
  name=frontend
  version=1.2.3
  env=production
)

# Parameters (for substitution)
connect db host=$DB_HOST port=$DB_PORT

# Optional attributes
backup database? retention=7days

API Reference

Core Classes

Query

Represents a query with a command and tags.

class Query {
  command: string
  tags: QueryTag[]

  // Get tag value by attribute name
  getStringValue(attr: string): string
  getNumberValue(attr: string): number
  getStringOptional(attr: string, defaultValue?: string): string | undefined

  // Check for attributes
  hasAttr(attr: string): boolean
  getAttr(attr: string): QueryTag | null

  // Get nested structures
  getNestedQuery(attr: string): Query
  getNestedTagList(attr: string): TagList

  // Parameter substitution
  withInlinedParams(params: Map<string, any>): Query

  // Serialization
  toQueryString(): string
}

TagList

Represents a list of tags without a command.

class TagList {
  tags: QueryTag[]

  // Same methods as Query (except command-related)
  getStringValue(attr: string): string
  hasAttr(attr: string): boolean
  withInlinedParams(params: Map<string, any>): TagList
  toQueryString(): string
}

QueryTag

Represents an individual tag with an attribute and optional value.

class QueryTag {
  attr: string
  value: TagValue
  paramName?: string

  // Type checks
  hasValue(): boolean
  isParameter(): boolean
  isQuery(): boolean
  isTagList(): boolean

  // Value getters
  getStringValue(): string
  getNumberValue(): number
  getQuery(): Query
  getTagList(): TagList

  // Serialization
  toQueryString(): string
}

Parsing Functions

// Parse a single query
function toQuery(str: string): Query

// Parse multiple queries from a string/file
function parseFile(content: string): Query[]

// Parse individual tags
function parseQueryTag(str: string): QueryTag

Usage Examples

Basic Parsing

import { toQuery } from '@facetlayer/qc'

const query = toQuery("config host=localhost port=3000 debug=true")

console.log(query.command)                    // "config"
console.log(query.getStringValue("host"))     // "localhost"
console.log(query.getNumberValue("port"))     // 3000
console.log(query.hasAttr("debug"))           // true

Nested Commands with Multiple Tags

QC handles complex nested structures by parsing indented blocks as single queries with multiple tags:

after-deploy
  pm2-start name=TestPM2App
    command(npm start)

This is parsed as one query with command after-deploy and three tags:

  • pm2-start (marker tag, no value)
  • name=TestPM2App (string value)
  • command(npm start) (nested value)
import { parseFile } from '@facetlayer/qc'

const content = `
after-deploy
  pm2-start name=TestPM2App
    command(npm start)
`;

const parsed = parseFile(content);
const config = parsed[0]; // Single query object

// Check for pm2-start marker
if (config.hasAttr('pm2-start')) {
    const name = config.getStringValue('name');       // "TestPM2App"
    const command = config.getAttr('command').toOriginalString(); // "npm start"
    
    console.log(`PM2 app: ${name} -> ${command}`);
}