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

flowsjackpot

v2.10.0

Published

Flows Jackpot Library

Readme

FlowsJackpots

A TypeScript script for integrating jackpot functionality into web application. The script enables the display of a customizable UI widget with real-time event handling, and player opt-in management.

Installation

The FlowsJackpots script is hosted on Flows's own CDN (https://cdn.flows.world). Flows hosts a staging and a production version of the script, where the former is connected to the staging FlowsPlay API and contains the latest code from the main branch, while the latter is the latest stable version, which is connected to the production FlowsPlay API. There is no particular installation needed to utilize the script. One must simply reference the script via a <script> tag in their main HTML file.

<!-- Staging -->
<script type="text/javascript" src="https://cdn.flows.world/js/jackpot-v2-beta.js" id="flows-jackpot"></script>

<!-- Production -->
<script type="text/javascript" src="https://cdn.flows.world/js/jackpot-v2-latest.js" id="flows-jackpot"></script>

This exposes flowsJackpots as a global object which should be used to start and interact with the widget.

Quick Start

  1. Reference the script for the target environment as in the Installation section.

  2. Call the startJackpotWidget function of the exposed flowsJackpots object, passing at least the first 3 parameters - orgId, gameId, and playerId:

    flowsJackpots.startJackpotWidget(
      "{{orgId}}",
      "{{gameId}}",
      "{{playerId}}",
    );

See the Examples section for more examples on how to use startJackpotWidget

Features

Core Functionality

Widget Management

  • startJackpotWidget() - Initialize and display the jackpot widget
  • closeJackpotWidget() - Close widget and clean up resources
  • lock(), unlock(), minimize(), expand() - Control and limit frontend widget behaviour
  • gameRoundStart(), gameRoundEnd() - Run control logic intended to run for the lifetime of a game round (e.g. spin)
  • Automatic positioning and responsive layout support
  • Drag-and-drop widget repositioning
  • Mobile-optimized modal display

Real-time Event Handling

Loading the jackpot widget using startJackpotWidget subscribes to server-sent events for jackpot value updates and win events. Events are of type JackpotEvent. There are two types of server-sent events that the widget subscribes to: user event, which listen to events on the channel user_${playerId}, and broadcast events, which listen to events on the channel broadcast_${baseData.jackpotGroupId}. Each event has its own reason property which is checked to determine what the event is about. Supported event reasons are linked with a callback function which is called every time that event is received

Below is a breakdown of the events:

  • User events: 1 event reasons is supported:

    • When event.reason is 'jackpot_won', this indicates that the current player has won one of the jackpots of the game they are playing. In this case, the widget appearance changes to notify and congratulate the user of the jackpot win and fireworks appear on screen which disappear after a few seconds or when the 'OK' button is clicked on the widget. Note: if the widget state is locked (lock() or gameRoundStart() have been called), this behaviour will not occur. Instead, the event is queued and the described behaviour only executes after gameRoundEnd() has been called. If there were multiple wins, only the latest win will be shown to the user.
  • Broadcast events: 3 event reasons are supported:

    • When event.reason is 'jackpot_won_other', this indicates that one of the jackpots of the game the current user is playing, has been won by another user. In this case, a small notification is shown on the widget which disappears after a few seconds. Note: if the widget state is locked (lock() or gameRoundStart() have been called), this behaviour will not occur. Instead, the event is queued and the described behaviour only executes after gameRoundEnd() has been called and only if there is no 'jackpot_won' event queued. If there were multiple wins, only the latest win will be shown to the user.
    • When event.reason is 'jackpot_value', this indicates that the total amount of a particular jackpot has changed. In this case, the widget will update to display the latest total amount for that jackpot.
    • When event.reason is jackpot_closed, this indicates that a jackpot level is completed and further spins will not contribute to the level's pot. When this event is received, the widget re-retrieves the jackpot data and removes the closed jackpot level from the UI, i.e. if the widget is showing a jackpot with MEGA, MAJOR, and MINI jackpot levels, and a jackpot_closed event is received for the MAJOR jackpot level, the widget will remove the details of the MAJOR jackpot level from view such that only MAJOR and MINI jackpot levels will be shown on the widget. Additionally, if jackpot_closed events have been received for all jackpot levels, then the jackpot is considered to be finished and closeJackpotWidget() is called to shut down the widget. Currently, this event is only being sent when a jackpot is hosted on the Light & Wonder Development site (site ID UiET6N4gQkahyph3vW_2HQ).

Calling closeJackpotWidget(), whilst removing the widget from the screen, also unsubscribes from all event streams.

Player Opt-in Management

The opt-in feature can be enabled via the FlowsPlay editor. When enabled, an Opt In/Opt Out button appears on the widget. Upon loading, the widget automatically checks the player's opt-in status; by default, player are opted out. Players can manage their participation by clicking the button, which opens a modal displaying a text description customizable via the FlowsPlay editor. From this modal, players can choose to opt in or opt out by clicking the appropriate button.

API Integration

The library includes a comprehensive API service with the following endpoints:

Game Data

  • Retrieve jackpot game configuration
  • Fetch localized appearance settings

Player Management

  • Get player's opt-in status
  • Update opt-in preferences

UI Components

Multi-level Jackpot Display

Supports 1-5 jackpot levels with customizable titles and styling:

  • Level 1: Mega jackpot (primary display)
  • Level 2: Major jackpot
  • Level 3: Minor jackpot
  • Level 4: Mini jackpot
  • Level 5: Rapid jackpot

Navigation System

  • Jackpot: Live jackpot values and participation status
  • News: Announcements and updates
  • Help: User guidance and terms

Visual Effects

  • Fireworks animation on jackpot wins
  • Winner announcements with customizable messaging
  • Responsive animations and transitions
  • Mobile-optimized interactions

Configuration Options

Language Support

  • Automatic browser language detection
  • Custom language specification
  • Localized text assets for all UI elements

Positioning

e.g.

{
  top: '20px',     // Distance from top
  bottom: '20px',  // Distance from bottom
  left: '20px',    // Distance from left
  right: '20px'    // Distance from right
}

Device Variants

The widget can be customized for 2 different screen sizes: Desktop and Mobile.

  • Desktop: Renders jackpot desktop styles when viewport width exceeds variantBreakingPoint
  • Mobile: Renders jackpot mobile styles when viewport width is equal to or below variantBreakingPoint

The default variantBreakingPoint is 480px (this can be changed by passing the deviceBreakingPoint parameter in startJackpotWidget)

Jackpot Layout Variants

Each jackpot has an associated jackpot layout variant which can be set via the FlowsPlay editor. This variant determines the appearance of the jackpot widget when it is loaded in the browser:

  • Small, Medium, Large: All of these 3 variants render a pop-up widget which is draggable and can be minimized and expanded. However, they differ in size and appearance in the closed version of the widget, the smallest closed widget of all being the Small layout variant.
  • StickyTop: Fixed top positioning. Widget appears as an horizontally elongated bar, taking the width of its container. The default container is document.body, thus by default the widget will appear at the uppermost part of the browser window. The target container for where the widget should appear can be customized using the rootElement parameter in startJackpotWidget.
  • StickyLeft: Fixed left sidebar positioning. Widget appears as an vertically elongated bar, taking the height of its container. The default container is document.body, thus by default the widget will appear at the uppermost part of the browser window. The target container for where the widget should appear can be customized using the rootElement parameter in startJackpotWidget.

API Reference

Methods

startJackpotWidget(orgId, gameId, playerId, language?, brandId?, startingPosition?, deviceBreakingPoint?, rootElement?)

Initialize and display the jackpot widget.

Parameters:

  • orgId (string, required): Organization identifier
  • gameId (string, required): Game identifier
  • playerId (string, required): Player identifier
  • language (string, optional): Language code (e.g., 'en', 'fr-FR')
  • brandId - (string, optional) Brand/Sub-brand identifier, if organization supports sub-brands
  • startingPosition (Position, optional): Initial widget position
  • deviceBreakingPoint (number, optional): Mobile breakpoint in pixels
  • rootElement - (HTMLElement, optional) Root element for StickyLeft layout; if not provided, document.body is used.
Advanced Usage
  • Start jackpot widget with brandId param
    flowsJackpots.startJackpotWidget(
      "{{orgId}}",
      "{{gameId}}",
      "{{playerId}}",
      "en",
      '{{brandId}}',
    );
  • Start jackpot widget with language and startingPosition params
    flowsJackpots.startJackpotWidget(
      "{{orgId}}",
      "{{gameId}}",
      "{{playerId}}",
      "en",
      "", // Brand id parameter has been set to empty string to not use subbrands
      { bottom: "20px", right: "20px" },
    );

closeJackpotWidget()

Close the widget and clean up all resources including event listeners and stylesheets.

showPreview(jackpotGame, jackpotGameAppearance, layout, deviceVariant, languageCode, optedIn?)

Renders the widget into view, whose data and appearance are passed through as parameters (rather than them being retrieved through API calls via startJackpotWidget), that has no functionality (cannot be expanded, does not react to events). The main use of this function is for embedding the widget in the FlowsPlay editor without exposing any functional aspects of it.

Parameters:

  • jackpotGame (JackpotGame): Jackpot data including org id, jackpot kind, jackpot values, and more.
  • jackpotGameAppearance (JackpotGameAppearance): Jackpot appearance data including desktop + mobile stylesheets and text assets, and more.
  • layout (JackpotLayoutVariant): The display variant of the jackpot widget e.g."Large" or "StickyTop".
  • deviceVariant (BrowserVariant): Either "Desktop" or "Mobile". Renders the widget with Desktop or Mobile appearance.
  • languageCode (string): Language code/locale e.g. "en-GB".
  • optedIn (boolean, optional): If the jackpot has opt in enabled, this parameter controls the internal opted in state of the jackpot (in order to show different text assets of being opted in/out).

lock()

Locks the widget, preventing user interaction. If already locked, returns true without performing additional operations.

Behaviour:

  • Sets internal widget locked state to true
  • Prevents user from dragging, minimizing, or expanding the widget
  • Hides the opt-in modal (if opt-in is enabled and opt-in modal is visible on screen)
  • Returns true if:
    • Widget was already locked
    • Lock operation completed successfully
  • Returns false if:
    • Widget initialization verification fails

Requires the widget to be initialized – i.e. flowsJackpots.startJackpotWidget(...) has been previously called

unlock()

Unlocks the widget, restoring user interaction. If already unlocked, returns true without performing additional operations

Behaviour:

  • Sets internal widget locked state to false
  • Allows user to drag, minimize, and expand the widget
  • Returns true if:
    • Widget was already unlocked
    • Unlock operation completed successfully
  • Returns false if:
    • Widget initialization verification fails

Requires the widget to be initialized – i.e. flowsJackpots.startJackpotWidget(...) has been previously called

minimize()

Minimizes the widget. If already minimized, returns true without performing additional operations. Behaviour:

  • Closes any active winner message
  • Updates widget appearance to minimized size
  • Returns true if:
    • Widget was already minimized
    • Minimize operation completed successfully
  • Returns false if:
    • Widget is currently locked
    • Widget initialization verification fails

Requires the widget to be initialized – i.e. flowsJackpots.startJackpotWidget(...) has been previously called

expand()

Expands the widget. If already expanded, returns true without performing additional operations. Behaviour:

  • Updates widget appearance to expanded full size
  • Returns true if:
    • Widget was already expanded
    • Expand operation completed successfully
  • Returns false if:
    • Widget is currently locked
    • Widget initialization verification fails

Requires the widget to be initialized – i.e. flowsJackpots.startJackpotWidget(...) has been previously called

gameRoundStart()

Prepares the widget for a game round. Executes the following sequence:

  1. Unlocks the widget (calls unlock())
  2. Minimizes the widget (if unlock succeeds) (calls minimize())
  3. Locks the widget (if minimize succeeds) (calls lock())

Behaviour:

  • While locked, jackpot user wins do not get communicated to the user, i.e. fireworks and jackpot won message will not be shown, and the widget will not expand to full size. Instead, the latest jackpot user win gets quietly queued. gameRoundEnd() must be called in order to process queued jackpot user win and show regular jackpot user win behaviour.

Use Case: Call before initiating a game round to ensure the widget is in the correct state.

gameRoundEnd()

Finalizes a game round. Executes the following:

  1. Unlocks the widget (calls unlock())
  2. If a jackpot win event is queued, processes it Use Case: Call after a game round completes to unlock the widget and handle any pending win notifications.

Event Types

Jackpot Events

  • jackpot_won: Player wins jackpot (triggers animations)
  • jackpot_won_other: Another player wins jackpot
  • jackpot_value: Live jackpot value update
  • jackpot_closed: A jackpot level has just been won and has been marked as closed

Custom Browser Events

The widget dispatches custom browser events that can be listened to using standard DOM event listeners:

  • flowsJackpotWidgetJackpotWonByUser: Dispatched when the current player wins a jackpot. event.detail contains JackpotEvent data with win details.
  • flowsJackpotWidgetLoaded: Dispatched when startJackpotWidget() successfully initializes. Use this to coordinate with other application logic.

Example:

document.addEventListener('flowsJackpotWidgetLoaded', (event) => {
  console.log('Widget loaded and ready');
});

document.addEventListener('flowsJackpotWidgetJackpotWonByUser', (event) => {
  console.log('Player won jackpot!', event.detail);
});

Examples

Basic Implementation

<script type="text/javascript" src="https://cdn.flows.world/js/jackpot-v2-latest.js" id="flows-jackpot"></script>
<script>
       flowsJackpots.startJackpotWidget("{{orgId}}", "{{gameId}}", "{{playerId}}", "{{locale}}");
</script>

Advanced Configuration

<script type="text/javascript" src="https://cdn.flows.world/js/jackpot-v2-latest.js" id="flows-jackpot"></script>
<script>
      // Custom language, positioning, and mobile breakpoint
       flowsJackpots.startJackpotWidget("Sv5L9-UJTUeYPV7iQpoZ3A", "Golden Shamrock", "[email protected]", "fr-FR", "", { top: "50px", left: "50px" }, 768);

      // Clean up when done
      flowsJackpots.closeJackpotWidget();
</script>

Development

This project uses Bun as its package manager. Before starting development:

  • Install Bun

  • Run the following commands in your terminal:

    bun run dev-setup

Use bun for all commands:

bun add package-name
bun run build

Testing

First run:

bun run serve:staging

to build & host a local version of the script connected to the staging FlowsPlay API

or

bun run serve:production

to build & host a local version of the script connected to the production FlowsPlay API

This should open a Node.JS server on port 3001. Navigate to http://localhost:3001 and you should be greeted with a test page which will allow you to enter configurations for a particular jackpot, start, display, and control the widget, view live server-side event logs, and trigger game spins to demonstrate widget functionality.

flowsplay-jackpot-widget-integration-lab

Widget UI testing

  1. After successfully opening the widget test page, go to the FlowsPlay admin panel (https://app.flowsplay.world/ - Production environment, https://stage-app.flowsplay.world/ - Staging environment). Use of the Production environment is highly recommended since the Staging environment has very limited capability to host jackpots.

  2. Switch to the site/organisation you want to host your jackpot on (to successfully host jackpots, the site you choose must be linked to Flows. Please contact Flows support to link your organisation). It is recommended to use the 'Demo Casino' site (site id Sv5L9-UJTUeYPV7iQpoZ3A). If you don't have access to this site please ask someone from the Flows team to invite you to it. You need the Editor or Owner role to create jackpots on sites.

  3. Take note of your site's name and site ID by going in the settings page.

  4. Go to the home page by clicking on the FlowsPlay logo. A table displaying a list of jackpots should be visible. Click an existing jackpot in the jackpots list, or create a new one.

    • To create a new jackpot, click the 'Create new' button. When prompted with creating a new jackpot, click the 'Use the FlowsPlay Widget' button then click 'Create'.
  5. If the jackpot is in the 'Draft' state, fill in the required inputs in the jackpot forms with necessary and valid information. After doing so, click the 'Publish changes' button on the top right to publish your jackpot.

  6. In the jackpot 'Target' tab, take note of the game ID(s) that has/have been set for this jackpot.

  7. Go back to http://localhost:3001. Fill in the 'Jackpot Configuration' section on the left side of the test page:

    • You can choose which version of the widget script to use from the 'Script source' dropdown.
    • The 'Organisation' section allows you to select the organisation where your jackpot lives in. You can either select an organisation from the visible dropdown or enter the organisation id manually in the input box. In this example, a jackpot has been created in the 'Demo Casino' organisation, so that organisation has been selected from the dropdown list. (Note: selecting an organisation from the list populates some inputs under the 'Game Actions' section to facilitate triggering of game spins, which will be discussed in a future step.)
    • The 'Player ID' input box allows you to associate jackpot events with a personal ID. This can be left as default or changed to any custom value
    • The 'Locale' input box allows you to select the locale for which text assets for the widget should be displayed. By default this is 'en-gb'.
    • The 'Brand ID' input box allows you to set the brand for which a jackpot is associated with. It should be noted that not all organisations have brands. To check if your organisation has brands, simply go back to the FlowsPlay admin panel and click on any jackpot in the jackpots list. Click on the 'Target' tab, and if a 'Sub-brands (operators)' dropdown is visible, then the organisation supports the use of sub-brands. You will need to acquire the underlying brand ID for the brand(s) listed in this dropdown and enter it in the 'Brand ID' input box in order to correctly render the widget. If this dropdown does not appear then your organisation does not use sub-brands and the 'Brand ID' input box should be left empty.
  8. With the jackpot configuration complete, we can now move onto the 'Widget Controls' section.

    • Click the green 'Start Widget' button under the 'Widget Controls' section. The widget should be visible now, in the minimized form. If the widget is not visible, make sure to rectify any errors that become visible via toast notifications on screen or via error messages in the browser console.
    • To close/shut down the widget, simply click the red 'Close Widget' button.
    • The 'Show widget preview' allows one to call the widget's showPreview function, though this function is particularly reserved for use within the appearance section of the jackpot editor on FlowsPlay.
    • The 'Lock', 'Unlock', 'Minimize', 'Expand', 'Game Round Start', and 'Game Round End' buttons execute functionalities detailed in the API Reference section.
  9. The 'Live SSE Messages' section allows one to display a live server-side event log. This event log will display any events (detailed in the section Real-time Event Handling). To start displaying an SSE event log, perform the following steps:

    • Open the browser console and navigate to the network tab. It may be useful to clear the network log.
    • Start the widget by clicking the green 'Start Widget' button. Look for a GET HTTP call with the following URL https://api.flowsplay.world/game/v1.1/sites/{your_site_id}/jackpots/games/{your-jackpot-id} or https://api.flowsplay.world/game/v1.1/sites/{your_site_id}/jackpots/games/{your-jackpot-id}/brand/{your_brand_id} if your site uses brands.
    • Click on it from the list and view the 'Response' tab to view the response body.
    • Copy the value for the 'workspaceId' property and paste it into the 'Workspace ID' input box, and copy the value for the 'jackpotGroupId' property and paste it into the 'Jackpot Group ID' input box (both can be found under the 'Live SSE Messages' section on the widget demo web page).
    • Finally, click the green 'Start SSE' button.
  10. The 'Game Actions' section currently only contains 1 action - to trigger a game spin, as if it you were playing a real jackpot game. The 'Site ID', 'GameEndRound Flow ID', and 'x-api-key' input boxes in this section are populated by selecting an organisation from the 'Organisation' dropdown list from the 'Jackpot Configuration' section. The 'Site ID' in this case is the same as the jackpot's Organisation ID (same value as in 'Organisation' input box from the 'Jackpot Configuration' section). If you don't choose an organisation from the dropdown list, then you will need to acquire the necessary values for these inputs from someone at Flows (CSM team or possibly Backend team).

Testing the code

All unit tests can be found in the \_\_tests\_\_ directory. Run these tests using bun run test which will run the TypeScript compiler to detect TypeScript errors because bun test does not natively check Typescript. Therefore any code changes in src/ that cause errors in unit tests will be caught before the tests even run.

Testing local CSS changes

To test local CSS changes, you need to override the base CSS URL:

  1. Open FlowsJackpots.class.ts
  2. Find the line: baseCSS: WidgetConstants.baseCSSUrl,
  3. Comment it out
  4. Uncomment the line: baseCSS: './assets/css/baseStyle.css', //DEBUG ONLY

This bypasses the environment-based CSS URL and loads styles directly from assets/css/ for local development.

Browser Support

  • Modern browsers with ES2015+ support
  • Mobile Safari and Chrome for mobile optimization
  • Automatic fallbacks for older browsers

License

ISC License

Contributors


Version: 2.0.0
Author: Flows LTD