autovisualizer 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -1
- package/package.json +1 -1
- package/public/embed/assets/auto-visualizer-C-FJ6u_a.js +89 -0
- package/public/embed/assets/{auto-visualizer-CJ_NYyWq.js.map → auto-visualizer-C-FJ6u_a.js.map} +1 -1
- package/public/embed/assets/{in-page-CzJDUAyD.js → in-page-C6bs-yMR.js} +2 -2
- package/public/embed/assets/{in-page-CzJDUAyD.js.map → in-page-C6bs-yMR.js.map} +1 -1
- package/public/embed/custom-elements.json +107 -3
- package/public/embed/embed.d.ts +29 -2
- package/public/embed/embed.js +1 -1
- package/public/embed/assets/auto-visualizer-CJ_NYyWq.js +0 -89
package/README.md
CHANGED
|
@@ -81,12 +81,56 @@ export const door = createMachine({ id: "door", initial: "closed", states: { clo
|
|
|
81
81
|
| `snapshot` | Resume exactly where an actor left off: the JSON from `actor.getPersistedSnapshot()`. Its state, context, history and pending timers come back as they were, and no entry actions run again, which `state` and `context` can't promise. Wins over both. A snapshot that doesn't fit the machine (another machine's id or version, or a state it doesn't have) shows why. |
|
|
82
82
|
| `events` | Events to send before the chart shows, space-separated: `events="ADD_ITEM CHECKOUT"` opens at `address`. For events that carry data, write a JSON array of names and whole events: `events='["ADD_ITEM",{"type":"xstate.done.actor.pay","output":{"id":"tx_1"}}]'`. |
|
|
83
83
|
| `walkthrough` | Steps to walk through, as JSON: `[{"event":"SUBMIT","note":"take payment"}]`. Adds previous, play and next under the chart, with each step's note. An event that carries data is written whole: `{"event":{"type":"xstate.done.actor.pay","output":{"id":"tx_1"}}}`. |
|
|
84
|
-
| `autoplay` | Steps through the walkthrough on its own. Readers who ask for less motion step themselves. |
|
|
84
|
+
| `autoplay` | Steps through the walkthrough on its own. Readers who ask for less motion step themselves. With narration, each step waits for its audio to end. |
|
|
85
|
+
| `speak` | Reads each step's note aloud with the browser's voice. |
|
|
86
|
+
| `voice` | Part of the browser voice's name for `speak`, matched case-insensitively: `voice="samantha"`. |
|
|
87
|
+
| `rate` | Speaking rate for `speak`, `0.1` to `10`. |
|
|
88
|
+
| `audio-src` | A recorded clip per step: `audio-src="audio/{step}.wav"`. A clip that can't play falls back to `speak`. |
|
|
85
89
|
| `counts` | How often each transition was taken, as JSON keyed by state then event: `{"payment":{"PAID":120,"DECLINED":0}}`. Each count shows on its event, and a transition taken 0 times is drawn dashed: a path the code allows that nothing took. Name a state by its key or its full id (`checkout.payment`). |
|
|
86
90
|
| `direction` | `auto` (default), `right` or `down`. `auto` lays the chart out both ways and keeps the one that shows it larger in its space: a long chain goes top to bottom in a wide column, a wide machine left to right in a short box, and a small machine that fits either way goes right. |
|
|
87
91
|
|
|
88
92
|
An event the machine doesn't accept, or a `machine` id it doesn't create, shows an error in the chart.
|
|
89
93
|
|
|
94
|
+
**Narrate the walkthrough.** Each step's note is its script. Add `speak` and the browser reads each note aloud, and `autoplay` moves on when the sentence ends:
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<auto-visualizer src="/machines/checkout.ts" speak voice="samantha" rate="0.9"
|
|
98
|
+
walkthrough='[{"event":"CHECKOUT","note":"The cart is ready, so we ask for an address."},{"event":"SUBMIT","note":"Then we take payment."}]'
|
|
99
|
+
></auto-visualizer>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
For a voice model, record a clip per step and point `audio-src` at them: `audio-src="audio/{step}.wav"`, where `{step}` is the step's number. `element.getSteps()` returns each step's `index`, `event`, `note` and `text` (the note, or the event when there's no note). Send the text to any speech model and save the clips. This records them with [Phonon](https://ollama.com/library/phonon) in Ollama, through [ai-sdk-ollama](https://github.com/jagreehal/ai-sdk-ollama):
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
import { writeFile } from "node:fs/promises"
|
|
106
|
+
import { generateSpeech } from "ai"
|
|
107
|
+
import { ollama } from "ai-sdk-ollama"
|
|
108
|
+
|
|
109
|
+
// The chart's steps: JSON.stringify(document.querySelector("auto-visualizer").getSteps()) in the browser console.
|
|
110
|
+
for (const step of steps) {
|
|
111
|
+
const { audio } = await generateSpeech({
|
|
112
|
+
model: ollama.speech("phonon:40m-multilingual"),
|
|
113
|
+
text: step.text,
|
|
114
|
+
voice: "Hugh",
|
|
115
|
+
outputFormat: "wav"
|
|
116
|
+
})
|
|
117
|
+
await writeFile(`audio/${step.index}.wav`, audio.uint8Array)
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
To voice steps live, set `narrate` to a function that returns each step's audio as a URL or a `Blob`, for example from your own speech endpoint:
|
|
122
|
+
|
|
123
|
+
```js
|
|
124
|
+
const chart = document.querySelector("auto-visualizer")
|
|
125
|
+
chart.narrate = async (step) => {
|
|
126
|
+
const response = await fetch("/api/speak", { method: "POST", body: step.text })
|
|
127
|
+
return response.ok ? response.blob() : undefined
|
|
128
|
+
}
|
|
129
|
+
chart.addEventListener("step", (event) => console.log(event.detail.index, event.detail.text))
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The chart tries `narrate` first, then the `audio-src` clip, then `speak`, and waits for each step's audio before autoplay moves on. The `step` event fires on every walkthrough step, played or stepped by hand. Browsers play sound only after the reader interacts with the page, so narration starts when they press play or next.
|
|
133
|
+
|
|
90
134
|
The events `events` and a walkthrough send are drawn as a path: each transition they took is highlighted, so a walkthrough that replays a real run shows its whole route, not only where it ended.
|
|
91
135
|
|
|
92
136
|
From React, set `walkthrough`, `counts`, `input` and `context` as JSON strings with `setAttribute` (or as attributes in markup). React renders before `embed.js` defines the element, so an object passed as a prop arrives as the text `[object Object]`.
|