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

@dataworks-technology/moments

v0.1.1

Published

Dataworks Moments Engine SDK — authenticate, query triggers/moments, and subscribe to real-time moment events

Readme

@dataworks-technology/moments

npm version license bundle size

Official SDK for the Dataworks Moments Engine — authenticate, query triggers and moments, and subscribe to real-time moment events.

Features

  • Zero dependencies — fully self-contained, no transitive installs
  • Dual format — ESM and CommonJS bundles included
  • TypeScript-first — complete type declarations shipped with the package
  • Real-time subscriptions — GraphQL WebSocket-based live moment streaming
  • Cognito authentication — secure login with automatic token management

Prerequisites

You need a Dataworks developer account. Contact your Dataworks administrator to receive:

| Credential | Description | |---|---| | cognitoEndpoint | Cognito User Pool endpoint URL | | clientId | Cognito app client ID | | graphqlUrl | Moments Engine AppSync GraphQL endpoint | | Username + password | Your developer login credentials |

Installation

npm install @dataworks-technology/moments
yarn add @dataworks-technology/moments
pnpm add @dataworks-technology/moments
bun add @dataworks-technology/moments

Quick Start

import { MomentsClient } from "@dataworks-technology/moments";

const client = new MomentsClient({
  cognitoEndpoint: "https://cognito-idp.eu-west-1.amazonaws.com/",
  clientId: "your-client-id",
  graphqlUrl: "https://your-appsync-endpoint.amazonaws.com/graphql",
});

// Authenticate
await client.login("username", "password");

// List recent moments
const { items: moments } = await client.listMoments({ limit: 10 });
console.log(`${moments.length} moments found`);

// Subscribe to new moments in real-time
const subscription = client.onMoments((moment) => {
  console.log(`New moment: ${moment.moment}`);
  console.log(`  Athlete: ${moment.athleteId}, Event: ${moment.eventId}`);
  console.log(`  Trigger: ${moment.triggerName}`);
});

// Later: close the subscription
subscription.close();

API

new MomentsClient(config)

Create a new client instance.

const client = new MomentsClient({
  cognitoEndpoint: "https://cognito-idp.eu-west-1.amazonaws.com/",
  clientId: "your-client-id",
  graphqlUrl: "https://your-appsync-endpoint.amazonaws.com/graphql",
  realtimeUrl: "wss://...", // Optional — derived from graphqlUrl if omitted
});

client.login(username, password)

Authenticate with Cognito. Must be called before any other operation.

const result = await client.login("username", "password");
// result: { accessToken, idToken, refreshToken, tenant }

client.listTriggers(options?)

List configured trigger rules with optional filtering, pagination, and ordering.

const { items, totalCount, nextToken } = await client.listTriggers({
  filter: { isActive: { eq: 1 } },
  limit: 25,
  orderBy: [{ createdAt: "DESC" }],
});

client.getTrigger(publicId)

Fetch a single trigger by its public ID.

const trigger = await client.getTrigger("abc-123-def");
console.log(trigger.name, trigger.criteria);

client.listMoments(options?)

List matched moments with optional filtering, pagination, and ordering.

const { items, totalCount, nextToken } = await client.listMoments({
  filter: { eventId: { eq: 7 } },
  limit: 50,
  orderBy: [{ createdAt: "DESC" }],
});

client.getMoment(publicId)

Fetch a single moment by its public ID.

const moment = await client.getMoment("moment-456");
console.log(moment.moment); // Hydrated output template
console.log(moment.matches); // Metric values that triggered

client.onMoments(callback)

Subscribe to real-time moment creation events. The callback fires each time the Flink engine matches a trigger.

const subscription = client.onMoments((moment) => {
  console.log(`[${moment.createdAt}] ${moment.moment}`);
  console.log(`  Athlete ${moment.athleteId} matched trigger ${moment.triggerName}`);
});

// Clean up
subscription.close();

client.onTriggerCreated(callback)

Subscribe to new trigger creation events.

const sub = client.onTriggerCreated((trigger) => {
  console.log(`New trigger: ${trigger.name}`);
});

client.onTriggerUpdated(callback)

Subscribe to trigger update events.

const sub = client.onTriggerUpdated((trigger) => {
  console.log(`Trigger updated: ${trigger.name} (active: ${trigger.isActive})`);
});

client.isAuthenticated

Check if the client has valid credentials.

if (client.isAuthenticated) {
  const triggers = await client.listTriggers();
}

client.tenant

Get the tenant from the authenticated session (or null).

console.log(`Logged in as tenant: ${client.tenant}`);

Types

All types are exported for use in your application:

import type {
  MomentsClientConfig,
  LoginResult,
  Trigger,
  Moment,
  MomentValue,
  MomentTriggerSnapshot,
  TriggerMarker,
  TriggerCriteria,
  TriggerCriteriaType,
  TriggerConnection,
  MomentConnection,
  TriggerFilter,
  MomentFilter,
  ListTriggersOptions,
  ListMomentsOptions,
  Subscription,
} from "@dataworks-technology/moments";

Key Interfaces

interface Trigger {
  publicId: string;
  clientId: number;
  isActive: number; // 1 = active, 0 = disabled
  name: string;
  outputTemplate: string; // Template with {{variable}} placeholders
  labels?: string[];
  marker?: TriggerMarker; // { color, icon? }
  criteria: TriggerCriteria[];
  timeWindowSeconds?: number;
  cooldownSeconds?: number;
  criteriaLogic?: "AND" | "OR";
  metricStalenessSeconds?: number;
  createdAt: string; // ISO timestamp
  updatedAt: string;
}

interface Moment {
  publicId: string;
  triggerPublicId?: string;
  clientId: number;
  athleteId: number;
  eventId: number;
  matches: MomentValue[]; // Metric values that triggered
  moment: string; // Hydrated output (template + values)
  triggerObject: MomentTriggerSnapshot;
  triggerName?: string;
  triggerMarker?: TriggerMarker;
  createdAt: string;
}

interface TriggerCriteria {
  datasetDatasourceId?: number;
  metric: string; // e.g. "heartrate", "speed", "power"
  subMetric: string; // e.g. "current", "average", "max"
  type: TriggerCriteriaType; // "gt" | "lt" | "eq" | "ge" | "le" | ...
  threshold: number;
}

Trigger Criteria Types

| Type | Description | Example | |------|-------------|---------| | eq | Equal to | heartrate.current == 170 | | ne | Not equal to | status != 0 | | gt | Greater than | heartrate.current > 170 | | ge | Greater than or equal | speed.average >= 30 | | lt | Less than | power.current < 100 | | le | Less than or equal | heartrate.max <= 200 | | between | Between two values | heartrate.current between [150, 180] | | exists | Metric exists | heartrate exists | | avg_window | Time-windowed average | avg(heartrate) over 5min > 160 | | trend_up | Trending upward | heartrate trending up | | trend_down | Trending downward | speed trending down |

Error Handling

All async methods throw on failure. Wrap calls in try/catch:

try {
  await client.login("user", "pass");
} catch (err) {
  // Authentication failed
}

try {
  const triggers = await client.listTriggers();
} catch (err) {
  // GraphQL error, network failure, or 401 expired token
}

Calling any query/subscription method before login() throws immediately.

Requirements

  • Node.js ≥ 18 (uses native fetch and WebSocket)
  • ESM or CommonJS — both module formats included
  • TypeScript ≥ 5.0 (optional — works with plain JavaScript too)
  • Browser — compatible with any environment that has fetch and WebSocket

Real-Time Moments — End-to-End Example

A core use case: subscribe to live moment events as they fire, process them externally (alerting, analytics, dashboards), and integrate with your own systems.

Concept

Live Metrics → Kinesis → Flink (trigger evaluation) → Moment Created → AppSync Subscription → Your App

The Moments Engine evaluates configurable trigger rules against live athlete metrics using Apache Flink. When metrics match trigger criteria, a moment is created with a hydrated output template and pushed to all subscribers in real-time.

TypeScript Example

import { MomentsClient } from "@dataworks-technology/moments";

const client = new MomentsClient({
  cognitoEndpoint: "https://cognito-idp.eu-west-1.amazonaws.com/",
  clientId: "your-client-id",
  clientSecret: "your-client-secret",
  graphqlUrl: "https://your-appsync-endpoint.amazonaws.com/graphql",
});

await client.login("developer", "password");

// 1. List active triggers to understand what we're monitoring
const { items: triggers } = await client.listTriggers({
  filter: { isActive: { eq: 1 } },
});
console.log(`Monitoring ${triggers.length} active triggers`);

// 2. Subscribe to live moments — fires each time a trigger matches
client.onMoments((moment) => {
  console.log(`🎯 [${moment.createdAt}] ${moment.triggerName}`);
  console.log(`   Athlete: ${moment.athleteId}, Event: ${moment.eventId}`);
  console.log(`   Output: ${moment.moment}`);
  console.log(`   Matches: ${moment.matches.map(m => `${m.metric}.${m.subMetric}=${m.value}`).join(", ")}`);

  // 3. Forward to your alerting system, dashboard, or analytics
  sendToSlack(`${moment.triggerName}: ${moment.moment}`);
  writeToDatabase(moment);
});

Python Example (Cross-Platform)

The same flow works from any language. A full working Python demo is included at test/demo/round-trip.py — it proves every SDK capability end-to-end:

| Phase | What it does | SDK equivalent | |-------|-------------|----------------| | 1. Authenticate | Cognito USER_PASSWORD_AUTH | client.login() | | 2. List triggers | GraphQL query with auth | client.listTriggers() | | 3. List moments | GraphQL query with filter | client.listMoments() | | 4. Subscribe | WebSocket → AppSync GraphQL subscriptions | client.onMoments() |

Run the demo

pip install websocket-client requests
python test/demo/round-trip.py

Output

PHASE 2: LIST TRIGGERS
  Found 3 triggers:
    → HR > 170 (active, 2 criteria)
    → Speed < 2.0 (active, 1 criteria)

PHASE 3: LIST MOMENTS
  Found 12 moments for the last hour

PHASE 4: SUBSCRIBE TO LIVE MOMENTS
  ✓ Connected to real-time endpoint
  Waiting for moments (10s)...
    🎯 HR > 170: Heart rate alert — 182 bpm (athlete 7)
  ✓ Received 1 live moment

See test/demo/README.md for full setup and Google Sheets integration.

Use Cases for Moments

| Use case | How | |---|---| | Real-time alerts | Subscribe to moments, forward to Slack/PagerDuty | | Live dashboard | Subscribe + render moment cards in your UI | | Post-event analysis | List moments filtered by event, athlete, trigger | | Trigger management | List/get triggers to show active monitoring rules | | Cross-platform integration | Python/Go/Rust via raw GraphQL + WebSocket |

Development

Internal contributors only — this section covers building, testing, and publishing the package.

This package publishes to public npm (registry.npmjs.org), not to the internal CodeArtifact registry used by @dataworks/sdk. The publishConfig in package.json enforces this.

Build

bunx tsup         # → dist/ (ESM + CJS + DTS)
bunx vitest run   # unit + E2E tests

Publish

Login to npm first (one-time):

npm login --registry https://registry.npmjs.org/

Then from packages/sdk/:

bun run publish:patch   # bump patch + publish
bun run publish:minor   # bump minor + publish
bun run publish:major   # bump major + publish

E2E Tests

The test suite (test/moments-client.test.ts) includes both unit tests (mocked fetch) and E2E tests that validate the full flow against deployed infrastructure.

Prerequisites

Deploy the Moments stack — make deploy generates test.env with the required env vars:

| Env var | Source | Purpose | |---|---|---| | CLIENT_ID | Shared stack → Cognito | App client for USER_PASSWORD_AUTH | | CLIENT_SECRET | Shared stack → Cognito | App client secret | | COGNITO_BASE_DOMAIN | Shared stack → Cognito | IDP endpoint for auth | | GRAPHQL_ENDPOINT | Moments stack → AppSync | GraphQL API endpoint | | WSS_ENDPOINT | Moments stack → AppSync | WebSocket real-time endpoint | | USERNAME | Shared stack → Cognito | Test user credentials | | USERPASSWORD | Shared stack → Cognito | Test user password |

Run

cd packages/sdk && bunx vitest run

What each test proves

| # | Area | What it validates | |---|---|---| | 1 | Login | USER_PASSWORD_AUTH flow, tenant extracted from JWT | | 2 | Login | Invalid credentials rejected cleanly | | 3 | getTrigger | GraphQL query with Bearer auth + tenant context | | 4 | getMoment | Query pattern for moments | | 5 | listTriggers | Filter, limit, nextToken, orderBy serialisation | | 6 | listMoments | Event/athlete filtering | | 7 | Errors | HTTP/GraphQL error propagation | | 8 | onMoments | WebSocket protocol (init → ack → start → data) | | 9–10 | E2E login | Live Cognito auth + bad credential rejection | | 11–12 | E2E queries | Full round-trip against deployed AppSync |

Related Packages