tap-sdk-staging
v0.0.10
Published
A vanilla JS SDK
Readme
@coxwave/tap-sdk
TapSDK is a lightweight JavaScript SDK for embedding the EduTap AI tutor inside any web property. It renders the toggle button, manages the iframe chat surface, and provides a structured messaging layer for bi-directional communication with the host page.
Installation
npm install @coxwave/tap-sdk
# or
pnpm add @coxwave/tap-sdk
# or
yarn add @coxwave/tap-sdkQuick Start
import TapSDK from "@coxwave/tap-sdk";
const sdk = new TapSDK({
apiKey: "your-plugin-key",
});
await sdk.init({
buttonId: "tap-button", // ID of the HTML element to attach the toggle button to
course: {
userId: "user-123",
courseId: "course-456",
clipId: null,
},
customStyles: {
chatBody: {
position: { top: "64px", right: "32px" },
width: "360px",
height: "calc(100% - 128px)",
borderRadius: "18px",
},
},
});On initialization the SDK:
- ensures it is running in a browser (guards against SSR)
- injects the chat container into
document.body - renders the EduTap iframe and performs a handshake for authentication
- attaches to the element with the provided
buttonId
Customisation
Toggle button
The SDK will attach alarm badges and click handlers to the element with the provided buttonId.
Chat body
The chat surface is a fixed container (#cw-chat-body). You can override:
position— partial{ top/right/bottom/left }values (strings with units)width/height— strings with CSS unitsborderRadius
The container gracefully hides itself when the chat closes and expands when EduTap opens embedded PDFs.
Alarm notifications & pop-ups
EduTap can send rich alarm notifications and HTML pop-ups over the iframe channel. The SDK fades alarms in/out, handles clicks, and renders pop-ups next to the chat container while inheriting relevant sizing from chatBody styles.
Runtime API
init(options)
Initializes the iframe, performs the handshake, and wires up UI controls. Required options:
buttonId– string (required) - ID of the HTML element to attach the toggle button tocourse– minimal course context (userId,courseId,clipId)customStyles?–{ chatBody? }- optional UI customization
events.seekTimeline({ clipId, clipPlayHead })
For VOD integrations you can push timeline updates back to EduTap so that it can stay in sync with the host player.
sdk.events.seekTimeline({ clipId: "clip-42", clipPlayHead: 132.4 });destroy()
Unhooks all listeners, removes the iframe and toggle button decorations, and resets the internal state. Call this when unmounting a single-page application route.
Event system
Events are exposed via the sdk.events helper. Every listener returns an unsubscribe function.
// Chat lifecycle events
sdk.events.onChatInitiated(() => console.log("chat initialized"));
sdk.events.onChatOpened(() => console.log("chat opened"));
sdk.events.onChatClosed(() => console.log("chat closed"));
// Timeline synchronization
sdk.events.onTimelineSeek((playHead, clipId) => {
console.log("EduTap requested timeline seek", playHead, clipId);
});
// Notifications and overlays
sdk.events.onAlarmFadeIn((alarm) => {
console.log("Alarm", alarm.message);
});
sdk.events.onPopUpOpen((popUp) => {
// popUp.html contains the rendered snippet
});
sdk.events.onPdfOpen(() => console.log("PDF overlay opened"));
sdk.events.onPdfClose(() => console.log("PDF overlay closed"));TypeScript support
Type definitions ship with the package. Notable exports:
TapSDKConfigCourseCustomStylesChatBodyStyleSeekTimelineParamsTypeAlarmMessageInstanceType
All message contracts are sourced from @coxwave/tap-messages and validated with valibot during the iframe handshake.
Browser support
- Chrome 60+
- Firefox 60+
- Safari 12+
- Edge 79+
License
MIT © 2025 Coxwave
Properties
isOpen
Returns true if the chat interface is currently open.
if (sdk.isOpen) {
console.log("Chat is currently open");
}isInitialized
Returns true if the SDK has been successfully initialized.
if (sdk.isInitialized) {
console.log("SDK is ready to use");
}Deprecated helpers
initChat(options)– useinit(options)instead; scheduled for removal in v1.0.0postChatInfo({ clipId, clipPlayHead })– alias forevents.seekTimeline; scheduled for removal in v1.0.0getTimelineInfo({ callback })– usesdk.events.onTimelineSeekinstead; scheduled for removal in v1.0.0
