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

mulmocast-viewer

v0.2.4

Published

[![npm version](https://badge.fury.io/js/mulmocast-viewer.svg)](https://badge.fury.io/js/mulmocast-viewer) # MulmoCast Viewer

Readme

npm version

MulmoCast Viewer

MulmoCast Viewer is a Vue 3 component library for playing and displaying bundles (JSON and media files) generated by mulmocast-cli in a browser.

Note: For application-specific features (ListView, Digest mode, mobile optimization, etc.), see APP_FEATURES.md.

Installation

npm install mulmocast-viewer
# or
yarn add mulmocast-viewer

Usage

Basic Usage

You can easily use the MulmoViewer component in your Vue application.

Default UI (with navigation buttons)

<template>
  <div>
    <MulmoViewer
      :data-set="data"
      :base-path="basePath"
      :audio-lang="audioLang"
      :text-lang="textLang"
    />
    <div>
      Audio: <SelectLanguage v-model="audioLang" />
      Text: <SelectLanguage v-model="textLang" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { MulmoViewer, SelectLanguage } from 'mulmocast-viewer'
import 'mulmocast-viewer/style.css'

import data from './path/to/mulmo_view.json'
const basePath = '/media_bundle'
const audioLang = ref('en')
const textLang = ref('en')
</script>

Text box theming (default UI)

You can theme the default text box via CSS variables or by targeting the built-in classes.

Built-in classes:

  • mulmo-text-box
  • mulmo-text-primary
  • mulmo-text-secondary

Supported CSS variables:

  • --mulmo-text-bg
  • --mulmo-text-primary
  • --mulmo-text-secondary-opacity

Example (Tailwind arbitrary properties on a wrapper):

<template>
  <div class="[--mulmo-text-bg:#1f2937] [--mulmo-text-primary:#fff]">
    <MulmoViewer :data-set="data" :base-path="basePath" />
  </div>
</template>

Custom UI

You can customize navigation buttons and layout using slots.

<template>
  <MulmoViewer
    :data-set="data"
    :base-path="basePath"
    :audio-lang="audioLang"
    :text-lang="textLang"
    v-slot="{ MulmoPlayer, pageProps, pageMove, currentPage, pageCount }"
  >
    <div class="my-custom-layout">
      <button @click="pageMove(-1)" :disabled="currentPage === 0">
        ← Previous
      </button>

      <component :is="MulmoPlayer" v-bind="pageProps" />

      <button @click="pageMove(1)" :disabled="currentPage >= pageCount - 1">
        Next →
      </button>

      <div class="page-info">
        {{ currentPage + 1 }} / {{ pageCount }}
      </div>
    </div>
  </MulmoViewer>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { MulmoViewer } from 'mulmocast-viewer'
import 'mulmocast-viewer/style.css'

import data from './path/to/mulmo_view.json'
const basePath = '/media_bundle'
const audioLang = ref('en')
const textLang = ref('en')
</script>

Setup Guide

1. Create a Bundle with mulmocast-cli

mulmocast bundle path/to/your/file.json

2. Place the Generated Folder

Place the generated bundle folder in your project's public directory.

  • Vue projects: /public/media_bundle/
  • Other projects: Any public directory

You can freely change the directory name (e.g., /public/demo_bundle/).

3. Load JSON Data

Load mulmo_view.json using one of the following methods:

Method 1: Direct Import

import data from './path/to/mulmo_view.json'

Method 2: Dynamic Loading

const response = await fetch('/media_bundle/mulmo_view.json')
const data = await response.json()

4. Configure basePath

Set basePath to the directory or URL where media files are located.

// Local path example
const basePath = '/media_bundle'

// External URL example
const basePath = 'https://example.com/bundle_demo'

MulmoViewer references media files (images, audio, video) relative to this basePath.

Additional Components

BeatGridView & BeatListView

Display a list of beats in grid or list format. These components are perfect for creating a beat catalog or overview page.

Simplest Usage

<template>
  <div>
    <BeatGridView
      :beats="beatsWithIndex"
      base-path="/my-content"
      text-lang="en"
    />
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { BeatGridView } from 'mulmocast-viewer'
import 'mulmocast-viewer/style.css'

import data from './path/to/mulmo_view.json'

// Transform beats array to include original indices
const beatsWithIndex = computed(() =>
  data.beats.map((beat, index) => ({ beat, originalIndex: index }))
)
</script>

With Router Integration

For Vue Router applications, pass a link builder function and RouterLink component:

<template>
  <div>
    <BeatGridView
      :beats="beatsWithIndex"
      base-path="/my-content"
      text-lang="en"
      :link-url-builder="buildBeatUrl"
      :link-component="RouterLink"
    />
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { RouterLink } from 'vue-router'
import { BeatGridView } from 'mulmocast-viewer'
import 'mulmocast-viewer/style.css'

import data from './path/to/mulmo_view.json'

const beatsWithIndex = computed(() =>
  data.beats.map((beat, index) => ({ beat, originalIndex: index }))
)

// Simple function to build URLs - no HTML needed!
const buildBeatUrl = (index: number) => {
  return `/viewer/${index}`
}
</script>

Key Points:

  • beats: Array of { beat: BundleItem, originalIndex: number } - preserves original indices for linking
  • basePath: Base path for media files. Images are resolved from beat.imageSource if available (e.g., /my-content/horse.png), otherwise falls back to sequential numbering (/my-content/1.jpg, /my-content/2.jpg, etc.)
  • textLang: Language for text display
  • linkUrlBuilder: Optional function (index: number) => string - returns URL for each beat
  • linkComponent: Optional component for links - use RouterLink for Vue Router, or 'a' (default) for regular links

BeatListView has the same API but displays beats in a newspaper-style layout with text wrapping around images.

MulmoViewerHeader

A shared header component with language/speed controls and mobile settings modal.

Simplest Usage

<template>
  <MulmoViewerHeader
    v-model:audio-lang="audioLang"
    v-model:text-lang="textLang"
    v-model:playback-speed="playbackSpeed"
    v-model:show-mobile-settings="showSettings"
  >
    <template #left>
      <h1>My Viewer</h1>
    </template>
  </MulmoViewerHeader>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { MulmoViewerHeader } from 'mulmocast-viewer'
import 'mulmocast-viewer/style.css'

const audioLang = ref('en')
const textLang = ref('en')
const playbackSpeed = ref(1)
const showSettings = ref(false)
</script>

With Custom Actions

<template>
  <MulmoViewerHeader
    v-model:audio-lang="audioLang"
    v-model:text-lang="textLang"
    v-model:playback-speed="playbackSpeed"
    v-model:show-mobile-settings="showSettings"
    :sticky="true"
  >
    <template #left>
      <h1>Beat Viewer</h1>
    </template>

    <template #actions>
      <button @click="handlePlay">Play All</button>
      <button @click="toggleDigest">Digest</button>
    </template>

    <template #mobile-actions>
      <button @click="showSettings = true">⚙️</button>
    </template>
  </MulmoViewerHeader>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { MulmoViewerHeader } from 'mulmocast-viewer'
import 'mulmocast-viewer/style.css'

const audioLang = ref('en')
const textLang = ref('en')
const playbackSpeed = ref(1)
const showSettings = ref(false)

const handlePlay = () => { /* ... */ }
const toggleDigest = () => { /* ... */ }
</script>

Key Points:

  • All language/speed controls are built-in with v-model bindings
  • #left slot: For title or custom content on the left
  • #actions slot: For custom buttons/controls (desktop)
  • #mobile-actions slot: For mobile-only buttons
  • sticky: Makes header sticky at top
  • showSpeedControl, showAudioLang, hideDesktopControls: Control visibility of built-in controls
  • Mobile settings modal is automatically included and managed via v-model:show-mobile-settings

API Reference

MulmoViewer Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | dataSet | ViewerData | Yes | - | Data loaded from mulmo_view.json | | basePath | string | Yes | - | Base path for media files (local or URL) | | initPage | number | No | 0 | Initial page to display | | audioLang | string | No | 'en' | Audio language | | textLang | string | No | 'en' | Text language | | playbackSpeed | number | No | 1 | Playback speed (1, 1.25, 1.5, 1.75, 2) |

MulmoViewer Events

| Event | Parameters | Description | |-------|------------|-------------| | updatedPage | nextPage: number | Emitted when the page is changed |

MulmoViewer Slot Props (for Custom UI)

The default slot exposes the following properties and components:

| Prop | Type | Description | |------|------|-------------| | MulmoPlayer | Component | Player component for displaying media | | pageProps | Object | Props to pass to the MulmoPlayer component | | currentPage | number | Current page number (0-indexed) | | pageCount | number | Total number of pages | | pageMove | (delta: number) => boolean | Function to move pages (-1: previous, 1: next) | | isPlaying | boolean | Whether media is currently playing | | audioLang | Ref<string> | Audio language (mutable) | | textLang | Ref<string> | Text language (mutable) | | SelectLanguage | Component | Language selection component |

BeatGridView / BeatListView Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | beats | Array<{ beat: BundleItem, originalIndex: number }> | Yes | - | Array of beats with original indices | | basePath | string | No | '' | Base path for media files. Uses beat.imageSource if available, otherwise {index+1}.jpg | | textLang | string | No | 'en' | Text language | | linkUrlBuilder | (index: number) => string | No | - | Function to generate link URLs | | linkComponent | string \| Component | No | 'a' | Link component (e.g., RouterLink or 'a') |

BeatGridView / BeatListView Events

| Event | Parameters | Description | |-------|------------|-------------| | beat-click | index: number | Emitted when a beat is clicked |

MulmoViewerHeader Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | audioLang | string | Yes | - | Audio language (v-model) | | textLang | string | Yes | - | Text language (v-model) | | playbackSpeed | number | No | 1 | Playback speed (v-model) | | showMobileSettings | boolean | No | false | Mobile settings modal visibility (v-model) | | showSpeedControl | boolean | No | true | Show speed control | | showAudioLang | boolean | No | true | Show audio language control | | hideDesktopControls | boolean | No | false | Hide desktop controls | | sticky | boolean | No | false | Make header sticky |

MulmoViewerHeader Slots

| Slot | Description | |------|-------------| | left | Content for left side (title, logo, etc.) | | actions | Custom action buttons (desktop) | | mobile-actions | Custom action buttons (mobile only) |

For Developers

This repository provides a development environment for the viewer component.

Development Environment Setup

  1. Create a Bundle
mulmocast bundle scripts/foo/bar.json
  1. Place the Generated Folder

Place the bundle folder under public/. Ensure the path looks like this:

public/bar/mulmo_view.json
  1. Update Data List
yarn run fileList
  1. Start Development Server
yarn run dev

Build

# Library build
yarn run build:lib

# Application build
yarn run build:app

# Build both
yarn run build

License

MIT