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

querymon

v1.0.3

Published

Javascript library for logging events for Querymon (https://querymon.com) search product analytics.

Downloads

14

Readme

Overview

If you are working in a Javascript environment, either frontend or backend, you can use the vanilla JS module in NPM. The module should work in any environment or framework due to its simplicity. The library has a single dependency, uuid, is extremely simple and is designed to be a very light wrapper around the Querymon API.

📘 You can find a full demo app with the integration on Github

Querymon Demo App

Note that the above shows a search-as-type implementation with all appropriate Querymon tracking implemented. All below sample code is pulled from this demo application.

Install the module (required)

The Javascript SDK should work in any environment, and can be added quickly from NPM.

npm install querymon
yarn add querymon

Initialize the SDK (required)

Initializing the SDK is simple, but needs to be done in a location that will persist the instance of Querymon throughout the lifecycle of search, returning results and clicking. It should NOT re-instantiate mid cycle.

Below is a sample of initializing the SDK in App.js of a simple React app.

// Once added via NPM
import { Querymon } from 'querymon';


/* @param {object} configuration
 * REQUIRED @param {string} configuration.searchInterfaceKey - The Search Interface Key
 * OPTIONAL @param {integer} configuration.debounceTime - The debounce time in ms for the search, defaults to 1000ms
 * OPTIONAL @param {string} configuration.userId - The userId to log for all events. If not provided, a random uuid will be generated
 */
const querymon = new Querymon({
  searchInterfaceKey: 'Your API key from https://app.querymon.com/search',
  userId: 'the persistent user ID to tie conversions, and do other reporting like cohorts'
});


export default function MyApp() {
  // Your application code

Note that for convenience, you can pass the userId here a single time, and it will automatically be appended to all future requests. If inconvenient, you can always pass the userId along with each request below.

Log search (required)

The most basic logging can happen with a simple call to logSearch with the user query as show below.

Basic method invocation

// Register query with Querymon. Async fire and forget
querymon.logSearch('search query here');

All method options

If you need further customization, such as analytics tagging and segmentation, to pass the user ID or override the timestamp that the query occurred, you can pass these parameters via the options object.

/* Method to log search query
 * REQUIRED @param {string} query - The search query
 * OPTIONAL @param {object} options - An object of optional parameters
 *   OPTIONAL @param {list of strings} options.metadata - An array of up to 4 strings to categorize the search query
 *   OPTIONAL @param {string} options.userId - The userId to log for all events to override the userId provided in the constructor
 *   OPTIONAL @param {int} options.queryTime - The time the query began (ms since 1970), defaults to the time of method invocation
 */
querymon.logSearch('search query here', {
  metadata: ['variant A', 'split C'],
  userId: 'user 1234',
  queryTime: 1695674081849
});

Log the results (required)

When the results are returned from the query, you can pass them to the result logging method call as shown below. Be careful to mind the format of the result objects.

Basic method invocation

// Register results with Querymon. Fire and forget.
querymon.logResults('search query here', yourResults.map((item, index) => {
  return {
    entityId: item.id,
    name: item.name,
    description: item.description,
    url: item.url,
    index: index
  };
}));

All method options

You also have the ability to specify the userIdand pass a specific timestamp if being logged later. Full example below:

/* Method to log results that were returned
 * REQUIRED @param  {string}  query   - The search query
 * REQUIRED @param  {list}    results - The list of the results returned from the search engine
 *                              Example format: [{index: row number integer, entityId: 'identifier for the result', name: 'name of result string', description: 'short description of the result', url: 'url for result'}]
 * OPTIONAL @param  {object}  options - An object of optional parameters
 *   OPTIONAL @param   {string}  options.userId           - The userId to log for all events to override the userId provided in the constructor
 *   OPTIONAL @param   {int}  options.resultReturnTime - The time the results were returned (ms since 1970), defaults to the time of method invocation
 */
querymon.logResults('search query here', yourResults.map((item, index) => {
  return {
    entityId: item.id,
    name: item.name,
    description: item.description,
    url: item.url,
    index: index
  };
}), {
  userId: 'user 1234',
  resultReturnTime: 1695674081849
});

Log click (required)

After you return the results to the user, if the user selects one of the results, you can log the click on the results with the following method.

Basic method invocation

The simplest version just logs the result row and name for matching.

// Register interaction with Querymon
querymon.logClick('search query here', result.index, result.name);

All method options

Again, you also have the ability to pass further parameters to specify the userId or interaction time if logging later than the actual event.

/* Method to log clicks on results
 * REQUIRED @param  {string}  query   - The search query
 * REQUIRED @param  {int}  resultRow - The row for the result that was clicked
 * REQUIRED @param  {string}  resultName - The name of the result that was clicked
 * OPTIONAL @param  {object}  options - An object of optional parameters
 *   OPTIONAL @param   {string}  options.userId           - The userId to log for all events to override the userId provided in the constructor
 *   OPTIONAL @param   {int}  options.interactionTime - The time the result was clicked (ms since 1970), defaults to the time of method invocation
 */
querymon.logClick('search query here', result.index, result.name, {
	userId: 'user 1234',
  interactionTime: 1695674081849
});

Log conversion event (optional)

Presumably this will happen later, on a different page from the search experience. Because of that, there is no need to pass the search query. Please do ensure to use the same searchInterfaceKey as used before to map the conversion data back to you search interface.

Basic method invocation

// Register conversion event with Querymon
querymon.logConversion('purchase');

All method options

Again, you also have the ability to pass further parameters to specify the userId or event time if logging the event later. We also recommend that you pass the eventValue in cents to track revenue attribution.

 /* Method to log a conversion event tied to the specific search interface
  * REQUIRED @param  {string}  eventName   - The name of the conversion event
  * OPTIONAL @param  {object}  options - An object of optional parameters
  *   OPTIONAL @param   {string}  options.eventValue - The value of the conversion event, in cents. No decimals.
  *   OPTIONAL @param   {string}  options.userId     - The userId to log for all events to override the userId provided in the constructor
  *   OPTIONAL @param   {int}  options.eventTime  - The time the conversion event occurred (ms since 1970), defaults to the time of method invocation
  */
querymon.logConversion('purchase', {
  eventValue: 999,
	userId: 'user 1234',
  eventTime: 1695674081849
});