From 05e7746bb57c820cdfcd93594c02bce792dff0f7 Mon Sep 17 00:00:00 2001 From: "Josefo (jozrftamson)" <107008476+jozrftamson@users.noreply.github.com> Date: Sat, 14 Mar 2026 03:25:15 +0100 Subject: [PATCH] feat load existing agent (#9) --- README.md | 5 ++++- src/agent.ts | 22 ++++++++++++++++++++++ src/index.ts | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5b57f61..5497ee6 100755 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ You can use ClippyJS directly in the browser using CDN: Install and import an agent: ```js -import { initAgent } from "clippyjs"; +import { initAgent, loadExistingAgent } from "clippyjs"; import { Clippy } from "clippyjs/agents"; // Load and show the agent @@ -106,6 +106,9 @@ agent.resume(); // Remove the agent from the DOM agent.dispose(); + +// Recover a previously created agent instance +const sameAgent = loadExistingAgent(agent._el); ``` ## Text-to-Speech diff --git a/src/agent.ts b/src/agent.ts index 6ac2205..249d7ff 100755 --- a/src/agent.ts +++ b/src/agent.ts @@ -2,6 +2,9 @@ import Queue from "./queue.ts"; import Animator from "./animator.ts"; import Balloon from "./balloon.ts"; +const agentRegistry = new WeakMap(); +const activeAgents = new Set(); + export interface AgentLoaders { agent: () => Promise<{ default: any }>; sound: () => Promise<{ default: any }>; @@ -49,6 +52,8 @@ export default class Agent { }); document.body.appendChild(this._el); + agentRegistry.set(this._el, this); + activeAgents.add(this); this._animator = new Animator(this._el, mapUrl, data, sounds); this._balloon = new Balloon(this._el); @@ -700,6 +705,8 @@ export default class Agent { this._animator.dispose(); this._balloon.dispose(); this._queue.dispose(); + activeAgents.delete(this); + agentRegistry.delete(this._el); this._el.remove(); } @@ -729,6 +736,21 @@ export async function initAgent(loaders: AgentLoaders): Promise { return new Agent(map, data, sounds); } +export function loadExistingAgent(element?: HTMLElement | null): Agent | undefined { + if (!element) { + return activeAgents.values().next().value; + } + + let current: HTMLElement | null = element; + while (current) { + const agent = agentRegistry.get(current); + if (agent) { + return agent; + } + current = current.parentElement; + } +} + async function _loadSounds(loaders: AgentLoaders): Promise> { const audio = document.createElement("audio"); const canPlayMp3 = !!audio.canPlayType && audio.canPlayType("audio/mp3") !== ""; diff --git a/src/index.ts b/src/index.ts index f86396a..2d0815e 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1 @@ -export { initAgent } from "./agent.ts"; +export { initAgent, loadExistingAgent } from "./agent.ts";