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 🙏

© 2025 – Pkg Stats / Ryan Hefner

sable-smart-links

v1.5.11

Published

Product walkthroughs triggered by a specified link, integrated directly with your platform.

Readme

Sable Smart Links

Product walkthroughs triggered by a specified link, integrated directly with your platform.

Overview

Sable Smart Links is a JavaScript library that enables you to create interactive product walkthroughs that can be triggered via URL parameters. It's designed to help your users navigate and understand your web application through guided tours that highlight UI elements, display informative tooltips, and automate interactions.

Features

  • URL-Triggered Walkthroughs: Start walkthroughs automatically when users visit a specific URL
  • Interactive UI Elements: Highlight important UI components to draw user attention
  • Spotlight Effect: Focus user attention by darkening everything except the highlighted element
  • Clean, Modern Tooltips: Display helpful information with customizable tooltips
  • Realistic Input Simulation: Type text character-by-character for more natural demonstrations
  • Step-by-Step Guidance: Guide users through complex workflows with sequential steps
  • Automated Interactions: Simulate clicks and form form inputs to demonstrate functionality
  • Global Popup Management: Ensures only one popup is active at a time, preventing conflicts
  • Responsive Design: Works across different screen sizes and devices
  • Easy Integration: Simple to add to any web application

Installation

npm install sable-smart-links

or

yarn add sable-smart-links

Basic Usage

// Import the library
import SableSmartLinks from "sable-smart-links";

// Register a walkthrough
SableSmartLinks.registerWalkthrough("new-user-onboarding", [
  {
    stepId: "welcome-step",
    selector: "#welcome-panel",
    highlight: true,
    spotlight: true,
    tooltip: {
      title: "Welcome to Our Platform",
      content: "This dashboard gives you an overview of all your activities.",
      nextButton: "Next",
    },
  },
  {
    stepId: "navigation-step",
    selector: ".navigation-menu",
    highlight: true,
    tooltip: {
      title: "Navigation",
      content: "Use this menu to access different sections of the application.",
      nextButton: "Continue",
    },
  },
  {
    stepId: "create-step",
    selector: "#create-button",
    highlight: true,
    tooltip: {
      title: "Create New Items",
      content: "Click here to create new items in your workspace.",
      nextButton: "Try it",
    },
    action: {
      type: "click",
      autoAdvance: true,
    },
  },
]);

When a user visits your application with the URL parameter ?walkthrough=new-user-onboarding, the walkthrough will automatically start.

Configuration

You can customize the behavior of Sable Smart Links by passing a configuration object when initializing:

import { SableSmartLinks } from "sable-smart-links";

const smartLinks = new SableSmartLinks({
  paramName: "tour", // Custom URL parameter name (default: 'walkthrough')
  autoStart: true, // Start walkthrough automatically if parameter is found
  stepDelay: 800, // Delay between steps in milliseconds
});

Walkthrough Step Options

Each step in a walkthrough can have the following options:

{
  // Required: Unique identifier for the step (used in analytics)
  stepId: 'welcome-step',        // Unique identifier for analytics tracking

  // Element targeting
  selector: '#element-id',       // CSS selector, XPath, or element ID

  // Visual highlighting
  highlight: true,               // Whether to highlight the element
  highlightOptions: {            // Highlight customization
    padding: 5,                  // Padding around element in pixels
    color: '#3498db',            // Highlight color
    animate: true                // Whether to animate the highlight
  },

  // Spotlight effect (darkens everything except the target element)
  spotlight: true,               // Whether to create a spotlight effect
  spotlightPadding: 5,           // Padding around element for spotlight (pixels)
  spotlightAnimate: true,        // Whether to animate the spotlight
  overlayOpacity: 0.5,           // Opacity of the darkened overlay (0-1)

  // Tooltip configuration
  tooltip: {
    title: 'Step Title',         // Tooltip title
    content: 'Step content...',   // Tooltip content (supports HTML)
    nextButton: 'Next',          // Text for the next button
    skipButton: 'Skip Tour'      // Text for the skip button (optional)
  },
  position: 'bottom',            // Tooltip position (top, right, bottom, left)

  // Element interaction
  action: {
    type: 'click',               // Action type (click, input, focus, hover, custom)
    value: 'Text input',         // For input actions
    typeEffect: true,            // Type text character-by-character (for input actions)
    typeDelay: 50,               // Delay between characters when typing (ms)
    delay: 500,                  // Delay before action in milliseconds
    autoAdvance: true,           // Automatically advance to next step after action
    handler: function(el) {}     // Custom action handler function
  },

  // Advanced options
  timeout: 5000,                 // Time to wait for element to appear (ms)
  autoAdvance: true,             // Auto-advance to next step
  autoAdvanceDelay: 3000,        // Delay before auto-advancing (ms)
  continueOnError: false,        // Continue to next step if this one fails
  callback: function(el) {}      // Custom callback function
}

End Tour Button

When a walkthrough is running, an "End Tour" button automatically appears at the bottom center of the screen. This button allows users to terminate the walkthrough at any time.

Features

  • Fixed Positioning: The button is positioned at the bottom center of the screen
  • Modern Design: Dark glassmorphism styling with backdrop blur for a modern look
  • High Visibility: Semi-transparent design with hover effects to ensure it's easily noticeable
  • Automatic Management: Appears when a walkthrough starts and disappears when it ends
  • Responsive Design: Works across different screen sizes and devices
  • Smooth Animations: Includes entrance and exit animations for better UX

Behavior

  • Appears: Automatically when a walkthrough starts via startWalkthrough() or when restored from localStorage
  • Disappears: Automatically when a walkthrough ends via endWalkthrough() or when the user clicks the button
  • Functionality: Clicking the button immediately terminates the current walkthrough and cleans up all UI elements

Customization

The end tour button is automatically managed by the walkthrough engine and doesn't require any additional configuration. It's designed to be unobtrusive while providing an easy way for users to exit walkthroughs.

// The end tour button appears automatically when you start a walkthrough
smartLinks.startWalkthrough("my-walkthrough");

// It disappears automatically when the walkthrough ends
smartLinks.endWalkthrough();

## Menu Trigger System

The library includes a menu trigger system that creates and manages a button that acts as a menu trigger. The button will automatically hide when any popup is active and show a menu popup when clicked. The button can be positioned in corners or attached to specific DOM elements.

### Features

- **Automatic Visibility Management**: Trigger buttons are hidden when popups are active
- **Flexible Positioning**: Position buttons in corners or attach to specific DOM elements
- **URL Path Filtering**: Show/hide buttons based on current URL paths
- **Center-Screen Menu Popups**: Menu popups appear in the center of the screen
- **Configurable Menu Content**: Define sections and items with custom handlers
- **Chat Integration**: Optional chat functionality in menu popups
- **Custom Styling**: Fully customizable button appearance

### Usage

```javascript
import SableSmartLinks from "sable-smart-links";

const sable = new SableSmartLinks({
  menu: {
    enabled: true,
    text: "Open Menu",
    position: "bottom-right",
    targetElement: {
      selector: ".menu-container",
      position: "top",
    },
    urlPaths: [], // Show on all paths
    style: {
      backgroundColor: "#4A90E2",
      color: "#FFFFFF",
      borderRadius: "20px",
      padding: "8px 16px",
      fontSize: "14px",
      boxShadow: "0 2px 10px rgba(0,0,0,0.2)",
    },
    popupConfig: {
      sections: [
        {
          title: "Quick Actions",
          icon: "⚡",
          items: [
            { text: "Action 1", data: { action: "action1" } },
            { text: "Action 2", data: { action: "action2" } },
          ],
                  onSelect: (item) => {
          // Selected: item
        },
        },
      ],
    },
  },
});

React Integration

import { SableSmartLinksProvider } from "sable-smart-links/react";

function App() {
  return (
    <SableSmartLinksProvider
      menu={{
        enabled: true,
        text: "Open Menu",
        position: "bottom-right",
        targetElement: {
          selector: ".menu-container",
          position: "top",
        },
        urlPaths: [],
        style: {
          backgroundColor: "#4A90E2",
          color: "#FFFFFF",
          borderRadius: "20px",
          padding: "8px 16px",
          fontSize: "14px",
          boxShadow: "0 2px 10px rgba(0,0,0,0.2)",
        },
        popupConfig: {
          sections: [
            {
              title: "Actions",
              items: [{ text: "Do Something", data: { action: "something" } }],
              onSelect: (item) => { /* item selected */ },
            },
          ],
        },
      }}
    >
      <YourApp />
    </SableSmartLinksProvider>
  );
}

Global Popup Manager

The library includes a global popup manager that ensures only one popup is active at a time across your entire application. This prevents issues with multiple popups being created simultaneously, which can happen during viewport resizing or rapid user interactions.

Features

  • Single Popup Guarantee: Only one popup can be active at any time
  • Automatic Cleanup: Previous popups are automatically closed when new ones are shown
  • State Tracking: Track whether a popup is active
  • Event Listeners: Subscribe to popup state changes

Usage

import globalPopupManager from "sable-smart-links/ui/GlobalPopupManager.js";

// Show a popup (automatically closes any existing popup)
const popup = globalPopupManager.showPopup({
  text: "This is a popup message",
  boxWidth: 300,
  buttonType: "arrow",
        onProceed: () => { /* proceed clicked */ },
});

// Check popup state
const state = globalPopupManager.getState();
// Has active popup: state.hasActivePopup

// Listen for state changes
globalPopupManager.addListener((state) => {
  // Popup state changed: state
});

// Close all popups
globalPopupManager.closeActivePopup();

React Integration

When using the React provider, you can access popup state through the context:

import { useSableSmartLinks } from "sable-smart-links/react";

function MyComponent() {
  const { hasActivePopup, closeAllPopups } = useSableSmartLinks();

  return (
    <div>
      <p>Popup active: {hasActivePopup ? "Yes" : "No"}</p>
      <button onClick={closeAllPopups}>Close All Popups</button>
    </div>
  );
}

Text Agent

Sable Smart Links includes a powerful text agent system that can guide users through interactive popup-based workflows.

Basic Usage

import SableSmartLinks from "sable-smart-links";

const sable = new SableSmartLinks();

// Register a text agent
sable.registerTextAgent(
  "onboarding",
  [
    {
      id: "welcome",
      text: "Welcome to our platform! Let's get you started.",
      buttonType: "arrow",
    },
    {
      id: "step1",
      text: "This is the first step of your onboarding.",
      buttonType: "arrow",
    },
    {
      id: "final",
      text: "You're all set! Welcome aboard.",
      buttonType: "arrow",
    },
  ],
  true,
  true,
  null,
  "#onboarding-container"
);

Advanced Configuration

The registerTextAgent method accepts several configuration options:

sable.registerTextAgent(
  "agentId", // Unique identifier for the agent
  steps, // Array of step objects
  autoStart, // Whether to start automatically (default: false)
  autoStartOnce, // Only auto-start once per session (default: true)
  beforeStart, // Optional function to run before starting
  requiredSelector // CSS selector that must exist for agent to run
);

Step Configuration

Each step can have various options:

{
  id: 'unique-step-id',
  text: 'Step content or function that returns content',
  secondaryText: 'Optional secondary text',
  buttonType: 'arrow' | 'yes-no',
  boxWidth: 300,
  primaryColor: '#FFFFFF',
  targetElement: {
    selector: '#target-element',
    position: 'top' | 'right' | 'bottom' | 'left'
  },
  autoAdvance: true,
  autoAdvanceDelay: 1000,
  onProceed: (textInput) => {
    // Handle proceed action
  },
  onYesNo: (isYes) => {
    // Handle yes/no selection
  }
}

Tavily Helper Functions

Sable Smart Links includes helper functions for optimizing Tavily search and crawl parameters using AWS Bedrock. These functions can help you get the best results from Tavily's API by automatically determining optimal parameters based on your query or crawl instructions.

Installation

The tavily helper functions are included in the main package and can be imported separately:

import {
  getOptimalCrawlParameters,
  getOptimalSearchParameters,
} from "sable-smart-links/tavily";

Usage

getOptimalCrawlParameters

Get optimal crawl parameters for a given URL and instructions:

import { getOptimalCrawlParameters } from "sable-smart-links/tavily";

const bedrockApiKey = "YOUR_ACCESS_KEY:YOUR_SECRET_KEY"; // AWS Bedrock credentials

try {
  const params = await getOptimalCrawlParameters(
    "https://example.com/docs",
    "Crawl the documentation to understand the API structure and available endpoints",
    bedrockApiKey
  );

  // Crawl Parameters: params
  // {
  //   extractDepth: "advanced",
  //   categories: ["Documentation", "Blogs"],
  //   explanation: "I've set the following parameters:<br> **Extract Depth is advanced** — Documentation sites need detailed extraction.<br> **Categories include Documentation** — API docs are the primary target.<br>",
  //   otherCrawls: [
  //     { url: "https://example.com/api", instructions: "Crawl the API reference documentation" },
  //     { url: "https://example.com/tutorials", instructions: "Crawl tutorials and guides" }
  //   ]
  // }

  // Use the parameters for your Tavily crawl
  const tavilyCrawlConfig = {
    extractDepth: params.extractDepth,
    categories: params.categories,
  };
} catch (error) {
  // Error occurred
}

getOptimalSearchParameters

Get optimal search parameters for a given query:

import { getOptimalSearchParameters } from "sable-smart-links/tavily";

const bedrockApiKey = "YOUR_ACCESS_KEY:YOUR_SECRET_KEY"; // AWS Bedrock credentials

try {
  const params = await getOptimalSearchParameters(
    "latest developments in artificial intelligence and machine learning",
    bedrockApiKey
  );

  // Search Parameters: params
  // {
  //   searchTopic: "news",
  //   searchDepth: "advanced",
  //   timeRange: "month",
  //   includeAnswer: "advanced",
  //   explanation: "I've set the following parameters:<br> **Search Topic is news** — AI/ML developments are current events.<br> **Search Depth is advanced** — Complex topic needs detailed analysis.<br> **Time Range is month** — Recent developments are most relevant.<br>",
  //   otherQueries: [
  //     "AI breakthroughs 2024",
  //     "machine learning research papers",
  //     "artificial intelligence industry trends"
  //   ]
  // }

  // Use the parameters for your Tavily search
  const tavilySearchConfig = {
    searchTopic: params.searchTopic,
    searchDepth: params.searchDepth,
    timeRange: params.timeRange,
    includeAnswer: params.includeAnswer,
  };
} catch (error) {
  // Error occurred
}

Next.js API Route Example

Here's how to use these functions in a Next.js API route:

// pages/api/tavily-optimize.js
import {
  getOptimalCrawlParameters,
  getOptimalSearchParameters,
} from "sable-smart-links/tavily";

export default async function handler(req, res) {
  if (req.method !== "POST") {
    return res.status(405).json({ error: "Method not allowed" });
  }

  try {
    const { url, instructions, query, type } = req.body;
    const bedrockApiKey = process.env.BEDROCK_API_KEY; // Set in your environment variables

    if (!bedrockApiKey) {
      return res
        .status(500)
        .json({ error: "BEDROCK_API_KEY environment variable is required" });
    }

    if (type === "crawl") {
      if (!url || !instructions) {
        return res.status(400).json({
          error: "URL and instructions are required for crawl optimization",
        });
      }

      const params = await getOptimalCrawlParameters(
        url,
        instructions,
        bedrockApiKey
      );

      return res.status(200).json({
        success: true,
        data: {
          explanation: params.explanation,
          otherCrawls: params.otherCrawls,
          crawlParams: {
            extractDepth: params.extractDepth,
            categories: params.categories,
          },
        },
      });
    } else if (type === "search") {
      if (!query) {
        return res
          .status(400)
          .json({ error: "Query is required for search optimization" });
      }

      const params = await getOptimalSearchParameters(query, bedrockApiKey);

      return res.status(200).json({
        success: true,
        data: {
          explanation: params.explanation,
          otherQueries: params.otherQueries,
          searchParams: {
            searchTopic: params.searchTopic,
            searchDepth: params.searchDepth,
            timeRange: params.timeRange,
            includeAnswer: params.includeAnswer,
          },
        },
      });
    } else {
      return res
        .status(400)
        .json({ error: 'Type must be either "crawl" or "search"' });
    }
  } catch (error) {
    return res.status(500).json({
      error: "Failed to process optimization",
      details: error instanceof Error ? error.message : "Unknown error",
    });
  }
}

Requirements

  • AWS Bedrock API credentials in the format ACCESS_KEY:SECRET_KEY
  • The @aws-sdk/client-bedrock-runtime package (included as a dependency)

Types

The functions return typed objects with the following interfaces:

interface CrawlParameters {
  extractDepth: "basic" | "advanced";
  categories: (
    | "Documentation"
    | "Blogs"
    | "Community"
    | "About"
    | "Contact"
    | "Pricing"
    | "Enterprise"
    | "Careers"
    | "E-Commerce"
    | "Media"
    | "People"
  )[];
  explanation: string;
  otherCrawls: { url: string; instructions: string }[];
}

interface SearchParameters {
  searchTopic: "general" | "news" | "finance";
  searchDepth: "basic" | "advanced";
  timeRange: "none" | "day" | "week" | "month" | "year";
  includeAnswer: "none" | "basic" | "advanced";
  explanation: string;
  otherQueries: string[];
}

API Reference

SableSmartLinks

Methods

  • registerWalkthrough(id, steps): Register a new walkthrough
  • start(walkthroughId): Start a walkthrough by ID
  • next(): Go to the next step in the current walkthrough
  • end(): End the current walkthrough
  • registerTextAgent(id, steps, autoStart, autoStartOnce, beforeStart, requiredSelector): Register a text agent
  • startTextAgent(agentId, stepId, skipTrigger): Start a text agent
  • nextTextAgentStep(): Go to next step in current text agent
  • previousTextAgentStep(): Go to previous step in current text agent
  • endTextAgent(): End the current text agent
  • showPopup(options): Show a popup (uses global popup manager)
  • closeAllPopups(): Close all active popups

Browser Support

Sable Smart Links supports all modern browsers:

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

License

MIT