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

@edynamix/exsto-insights-sdk

v0.1.0-rc.1

Published

Typed SDK for Exsto Insights: queries, aggregates, grain-safe joins, and module registries.

Downloads

117

Readme

@edynamix/exsto-insights-sdk

Typed SDK for the Exsto Insights API: queries, aggregates, grain-safe joins, and a discoverable schema registry. Every table and field is described in TypeScript, so your editor autocompletes table names, field names, and result shapes, and invalid specs fail at compile time instead of at runtime.

Requirements

  • Node.js 18 or newer (uses the global fetch), or any modern browser runtime
  • ESM only: import works everywhere, require() is not supported
  • TypeScript 5.0+ recommended for the full typed surface (plain JavaScript works too)

Install

npm install @edynamix/exsto-insights-sdk

Quickstart

Create an API token in the Exsto Insights dashboard (Settings, admin only), then:

import { createExsto } from '@edynamix/exsto-insights-sdk';

const exsto = createExsto({
  url: 'https://your-exsto-insights-host',
  token: process.env.EXSTO_TOKEN,
});

const page = await exsto.query('stockVehicles', {
  select: ['importDate', 'centerName', 'brand', 'profit'],
  where: { importDate: { gte: new Date('2026-06-01') } },
  orderBy: { field: 'profit', dir: 'desc' },
  limit: 50,
});

for (const row of page.rows) {
  // row is exactly { importDate: Date; centerName: string; brand: string; profit: number }
  console.log(row.centerName, row.brand, row.profit);
}

Field names are always the clean camelCase names from the registry; raw warehouse column names never appear in specs or results. Date fields arrive as real Date objects.

Aggregate

const byBrand = await exsto.aggregate('stockVehicles', {
  groupBy: ['brand'],
  aggregate: { totalProfit: { sum: 'profit' }, vehicles: { count: 'id' } },
  having: { vehicles: { gte: 5 } },
  orderBy: { field: 'totalProfit', dir: 'desc' },
});

groupBy also accepts calendar buckets on date fields: 'importDate:day', 'importDate:week', 'importDate:month'.

Join

Joins are grain-safe: the on key must exist in both tables AND cover the joined table's declared grain, checked at compile time (and asserted again at runtime). Results are namespaced per table:

const joined = await exsto.join({
  from: 'customerReach',
  join: [{ with: 'messaging', on: ['periodId'] }],
  select: { customerReach: ['periodId', 'emailCount'], messaging: ['smsCount'] },
});

const row = joined.rows[0];
// row.customerReach.emailCount, row.messaging.smsCount

Discover the schema

const schema = exsto.schema();
// Every table with its fields, kinds, grain, and tenancy; safe to serialize for codegen.

Modules

The default client is typed against every built-in module. The full catalog is exported from the main entry when you need it directly (narrowed clients, offline tests):

import { BUILTIN_MODULES, BUILTIN_REGISTRY } from '@edynamix/exsto-insights-sdk';

const stockOnly = BUILTIN_MODULES['stock-master'];

Configuration

createExsto({
  url: 'https://your-exsto-insights-host',
  // Machine API token, sent as `Authorization: Bearer <token>`. Omit in the browser:
  // the HttpOnly session cookie authenticates same-origin requests instead.
  token: '...',
  // Optional client-side narrowing; the server only ever narrows further.
  centerIds: [1, 2],
  // Extra headers for every request; a function is re-read per request.
  headers: () => ({ 'x-request-source': 'nightly-report' }),
});

Advanced

  • createExstoFromRegistry(registry, config) builds a client over your own registry subset (e.g. a single module) with the same typed surface.
  • createMemoryTransport(registry, rowsByTable) runs the full query engine in memory over fixture rows, for unit tests without a network.
  • IExstoClient<R> names the client type when you need to pass it around.
  • Failed HTTP requests throw Error with the status and response body in the message; invalid specs throw ExstoValidationError.

License

Apache-2.0. Copyright 2026 eDynamix.