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

@primoia/vocall-vue

v1.0.0

Published

Vocall Vue 3 SDK - WebSocket UI automation platform

Readme

Vocall SDK for Vue

Vue 3 SDK for the Vocall platform -- connect your Vue application to a Vocall engine over WebSocket and let the AI assistant read, fill, and navigate your UI in real time.


Features

  • Reactive composables built on Vue 3 Composition API (ref, inject, watch)
  • Plugin-based setup with a shared VocallClient instance across your application
  • Two-way field binding: register any <input>, <select>, or <textarea> so the engine can fill, clear, focus, and highlight it
  • Action registration: expose buttons and callbacks the engine can trigger remotely
  • Pre-built UI components (VocallChat, VocallFab, VocallStatus) with scoped styles
  • Streaming chat tokens with automatic message assembly
  • Automatic WebSocket reconnection with exponential back-off (up to 10 attempts)
  • Full TypeScript support with exported types for every protocol message

Installation

npm install @vocall/vue-sdk

Peer dependency: Vue >= 3.4.0


Quick Start

1. Register the plugin

// main.ts
import { createApp } from 'vue';
import { VocallPlugin } from '@vocall/vue-sdk';
import App from './App.vue';

const app = createApp(App);

app.use(VocallPlugin, {
  url: 'ws://localhost:12900/connect',
  token: 'my-api-token',        // optional
  visitorId: 'visitor-abc-123',  // optional, auto-generated if omitted
});

app.mount('#app');

2. Connect and send messages

<script setup lang="ts">
import { onMounted } from 'vue';
import { useVocall, useVocallField, type ManifestMessage } from '@vocall/vue-sdk';

const {
  status, messages, connected,
  connect, disconnect, sendText, client,
} = useVocall();

// Register a field so the engine can fill it
const { fieldRef, value: nameValue } = useVocallField({
  fieldId: 'customer_name',
  client,
});

// Build the manifest and connect
onMounted(() => {
  const manifest: ManifestMessage = {
    type: 'manifest',
    app: 'my-app',
    screens: {
      home: {
        id: 'home',
        label: 'Home',
        fields: [
          { id: 'customer_name', type: 'text', label: 'Customer Name', required: true },
        ],
      },
    },
    currentScreen: 'home',
  };
  connect(manifest);
});
</script>

<template>
  <p>Status: {{ status }}</p>
  <input ref="fieldRef" v-model="nameValue" placeholder="Customer Name" />
  <button @click="sendText('Fill the customer name with John Doe')">
    Ask Vocall
  </button>
</template>

Composables API

useVocall(options?)

Main composable for connecting to the Vocall server. If the VocallPlugin was installed, the shared client is injected automatically; otherwise a new client is created from the provided options.

Options (UseVocallOptions):

| Property | Type | Default | Description | |---|---|---|---| | serverUrl | string | ws://localhost:12900/connect | WebSocket server URL | | token | string | -- | Optional auth token | | visitorId | string | auto-generated | Persistent visitor identifier | | autoDispose | boolean | true | Dispose the client when the component unmounts |

Returns (UseVocallReturn):

| Property | Type | Description | |---|---|---| | status | Ref<VocallStatus> | Current connection/processing status (readonly) | | messages | Ref<ChatMessage[]> | Reactive chat message list | | connected | Ref<boolean> | Whether the WebSocket is connected (readonly) | | sessionId | Ref<string \| null> | Session ID assigned by the server (readonly) | | pendingConfirmSeq | Ref<number> | Sequence number of a pending confirmation (-1 if none) | | pendingConfirmMessage | Ref<string \| null> | Text of a pending confirmation dialog | | sendText(text) | (text: string) => void | Send a chat message to the engine | | sendConfirm(seq, confirmed) | (seq: number, confirmed: boolean) => void | Respond to a confirmation request | | connect(manifest) | (manifest: ManifestMessage) => void | Open the WebSocket and send the manifest | | disconnect() | () => void | Close the connection | | sendState(screen) | (screen: string) => void | Send current field state to the server | | clearMessages() | () => void | Clear the local chat history | | client | VocallClient | Underlying client instance for advanced use |


useVocallField(options)

Registers a form field with the Vocall client so the engine can fill, clear, focus, and highlight it.

Options (UseVocallFieldOptions):

| Property | Type | Description | |---|---|---| | fieldId | string | Unique identifier matching a field in the manifest | | client | VocallClient | Client instance from useVocall().client | | initialValue | string | Optional initial value |

Returns (UseVocallFieldReturn):

| Property | Type | Description | |---|---|---| | fieldRef | Ref<HTMLInputElement \| HTMLSelectElement \| HTMLTextAreaElement \| null> | Template ref to bind to the element | | value | Ref<string> | Reactive model value (use with v-model) |

Example:

<script setup lang="ts">
import { useVocall, useVocallField } from '@vocall/vue-sdk';

const { client } = useVocall();

const { fieldRef: emailRef, value: emailValue } = useVocallField({
  fieldId: 'email',
  client,
});
</script>

<template>
  <input ref="emailRef" v-model="emailValue" type="email" />
</template>

useVocallAction(options)

Registers an action handler with the Vocall client so the engine can trigger it via the click command.

Options (UseVocallActionOptions):

| Property | Type | Description | |---|---|---| | actionId | string | Unique identifier matching an action in the manifest | | client | VocallClient | Client instance from useVocall().client | | handler | () => void \| Promise<void> | Callback invoked when the engine triggers this action |

Example:

<script setup lang="ts">
import { useVocall, useVocallAction } from '@vocall/vue-sdk';

const { client } = useVocall();

useVocallAction({
  actionId: 'submit_form',
  client,
  handler: async () => {
    await saveData();
    console.log('Form submitted by Vocall');
  },
});
</script>

Plugin

VocallPlugin

Install Vocall as a Vue plugin to create a single shared VocallClient instance that is provided to all components via inject.

import { createApp } from 'vue';
import { VocallPlugin } from '@vocall/vue-sdk';

const app = createApp(App);

app.use(VocallPlugin, {
  url: 'ws://localhost:12900/connect',
  token: 'my-api-token',
  visitorId: 'visitor-abc-123',
});

app.mount('#app');

Options (VocallPluginOptions):

| Property | Type | Required | Description | |---|---|---|---| | url | string | No | WebSocket server URL. Defaults to ws://localhost:12900/connect | | token | string | No | Optional authentication token | | visitorId | string | No | Visitor identifier. Auto-generated and persisted in localStorage if omitted |

When the plugin is installed, the client is also available on this.$vocall for Options API components.


Components

VocallChat

A full chat panel with message list, text input, and header showing connection status.

Props:

| Prop | Type | Description | |---|---|---| | messages | ChatMessage[] | Array of chat messages to display | | status | VocallStatus | Current engine status | | connected | boolean | Whether the client is connected | | sessionId | string \| null | Optional session identifier |

Events:

| Event | Payload | Description | |---|---|---| | send | text: string | Emitted when the user submits a message | | clear | -- | Emitted when the user clicks the clear button | | close | -- | Emitted when the user clicks the close button |

<template>
  <VocallChat
    :messages="messages"
    :status="status"
    :connected="connected"
    @send="sendText"
    @clear="clearMessages"
    @close="chatOpen = false"
  />
</template>

VocallFab

A floating action button (fixed bottom-right) that changes color based on the engine status and shows a spinner during thinking or executing states.

Props:

| Prop | Type | Description | |---|---|---| | status | VocallStatus | Current engine status | | connected | boolean | Whether the client is connected |

Events:

| Event | Description | |---|---| | click | Emitted when the FAB is clicked |

<template>
  <VocallFab :status="status" :connected="connected" @click="toggleChat" />
</template>

VocallStatus

A small status pill that becomes visible when the engine is actively processing (thinking, executing, speaking, listening, or recording). Hidden during idle and disconnected states.

Props:

| Prop | Type | Description | |---|---|---| | status | VocallStatus | Current engine status | | connected | boolean | Whether the client is connected |

<template>
  <VocallStatus :status="status" :connected="connected" />
</template>

VocallClient API

The VocallClient class manages the WebSocket connection, field/action registry, and command execution. It is typically accessed via useVocall().client.

Properties

| Property | Type | Description | |---|---|---| | status | VocallStatus | Current status | | messages | ChatMessage[] | Chat message history | | sessionId | string \| null | Server-assigned session ID | | connected | boolean | Connection state | | registry | VocallFieldRegistry | Field and action registry | | events | EventEmitter | Internal event bus | | serverUrl | string | WebSocket server URL (read/write) | | token | string \| undefined | Auth token (read/write) | | visitorId | string | Visitor identifier (read-only) |

Methods

| Method | Description | |---|---| | connect(manifest) | Open the WebSocket and send the manifest | | disconnect() | Close the connection intentionally | | sendText(text) | Send a chat message | | sendConfirm(seq, confirmed) | Respond to a confirmation dialog | | sendResult(seq, results, currentScreen?) | Send command execution results | | sendState(screen) | Send current field state snapshot | | dispose() | Disconnect, remove listeners, and clear registries |

Events

Subscribe to events via client.events.on(event, handler):

| Event | Arguments | Description | |---|---|---| | change | -- | Fired whenever any reactive state changes | | confirm | seq: number, message: string | A confirmation dialog was requested | | toast | message: string, level: string, duration: number | A toast notification was requested |


Manifest Structure

The manifest describes your application's screens, fields, and actions. It is sent to the engine on connection.

import type { ManifestMessage } from '@vocall/vue-sdk';

const manifest: ManifestMessage = {
  type: 'manifest',
  app: 'invoice-app',
  version: '1.0.0',
  currentScreen: 'dashboard',
  user: {
    name: 'Jane Doe',
    email: '[email protected]',
    org: 'Acme Corp',
    role: 'admin',
  },
  persona: {
    name: 'Emma',
    role: 'Invoice Assistant',
    instructions: 'Help the user issue invoices and manage taxpayers.',
  },
  context: {
    locale: 'en-US',
    timezone: 'America/New_York',
  },
  screens: {
    dashboard: {
      id: 'dashboard',
      label: 'Dashboard',
      route: '/dashboard',
      fields: [
        { id: 'search', type: 'text', label: 'Search', placeholder: 'Search...' },
      ],
      actions: [
        { id: 'new_invoice', label: 'New Invoice' },
      ],
    },
    invoice_form: {
      id: 'invoice_form',
      label: 'Issue Invoice',
      route: '/invoices/new',
      fields: [
        { id: 'customer_name', type: 'text', label: 'Customer', required: true },
        { id: 'amount', type: 'currency', label: 'Amount', required: true },
        { id: 'due_date', type: 'date', label: 'Due Date' },
        { id: 'notes', type: 'textarea', label: 'Notes', maxLength: 500 },
        {
          id: 'status',
          type: 'select',
          label: 'Status',
          options: [
            { value: 'draft', label: 'Draft' },
            { value: 'sent', label: 'Sent' },
          ],
        },
      ],
      actions: [
        { id: 'save_invoice', label: 'Save', requiresConfirmation: true },
        { id: 'cancel', label: 'Cancel', destructive: true },
      ],
      modals: [
        { id: 'customer_search', label: 'Search Customer', searchable: true },
      ],
    },
  },
};

Field Types

The FieldType enum defines all supported field types:

| Type | Value | Description | |---|---|---| | Text | text | Plain text input | | Number | number | Numeric input | | Currency | currency | Monetary value input | | Date | date | Date picker | | Datetime | datetime | Date and time picker | | Email | email | Email address input | | Phone | phone | Phone number input | | Masked | masked | Input with a custom mask pattern | | Select | select | Dropdown select | | Autocomplete | autocomplete | Autocomplete / typeahead | | Checkbox | checkbox | Boolean checkbox | | Radio | radio | Radio button group | | Textarea | textarea | Multi-line text area | | File | file | File upload | | Hidden | hidden | Hidden field (not visible to the user) |


UI Actions

The engine can send commands containing one or more of the following 14 UI actions:

| Action | Target | Description | |---|---|---| | navigate | screen | Navigate to a different screen | | fill | field | Fill a field with a value (supports typewriter animation) | | clear | field | Clear a field's value | | select | field | Set the value of a select/dropdown field | | click | action | Trigger a registered action handler | | highlight | field | Temporarily highlight a field element | | focus | field | Focus a field element | | scroll_to | field | Scroll the viewport to a field | | show_toast | -- | Display a toast notification | | ask_confirm | -- | Show a confirmation dialog and wait for user response | | open_modal | modal | Open a modal by ID with an optional search query | | close_modal | -- | Close the currently open modal | | enable | field | Enable a disabled field | | disable | field | Disable a field |

Sequential actions (navigate, click, open_modal, close_modal, ask_confirm, show_toast) are executed one at a time. All other actions run in parallel for optimal performance. Failed actions are retried up to 3 times with a 300 ms delay.


Demo

A demo application is available in the demo/ directory. It demonstrates plugin setup, field registration, action handling, and the chat overlay using all three provided components.


Testing

The SDK includes a comprehensive test suite with ~184 tests covering protocol types, WebSocket client, Vue composables, plugin integration, and voice utilities.

Running Tests

npm test                # Run all tests
npm test -- --coverage  # Run with coverage report

Test Structure

| File | Tests | What it covers | |---|---|---| | src/protocol/__tests__/types.test.ts | 24 | Protocol type enums, message interfaces, field types | | src/client/__tests__/vocall-client.test.ts | 94 | WebSocket connection, reconnection, command execution, streaming | | src/composables/__tests__/use-vocall.test.ts | 25 | useVocall composable, reactive state | | src/composables/__tests__/use-vocall-field.test.ts | 13 | useVocallField composable, template ref binding | | src/composables/__tests__/use-vocall-action.test.ts | 7 | useVocallAction composable, callback registration | | src/plugin/__tests__/vocall-plugin.test.ts | 8 | VocallPlugin installation, provide/inject | | src/voice/__tests__/frame-splitter.test.ts | 13 | Audio frame splitting for voice pipeline |

Test Configuration


Development

Building the SDK

npm install
npm run build

Running the Demo

The demo application is in the demo/ directory:

cd demo
npm install
npm run dev        # http://localhost:5173

The demo connects to a Vocall server at ws://localhost:12900/connect. See the workspace README for local server setup.

Docker

When running from the workspace, the demo is available as a Docker container:

# From the workspace root
make serve-all     # Starts engine + all demos
# Vue demo at http://localhost:21004

Related

This SDK is part of the Primoia Vocall Workspace.

| Resource | Link | |---|---| | Workspace (setup, Docker) | primoia-vocall-workspace | | Angular SDK | vocall-sdk-angular | | Next.js SDK | vocall-sdk-nextjs | | Kotlin SDK | vocall-sdk-kotlin | | Swift SDK | vocall-sdk-swift | | Flutter SDK | jarvis-sdk-flutter |


License

Proprietary. All rights reserved.