@runtypelabs/persona 4.4.2 → 4.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/dist/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/{types-C6tFDxKy.d.cts → types-8RICZWQe.d.cts} +6 -0
- package/dist/animations/{types-C6tFDxKy.d.ts → types-8RICZWQe.d.ts} +6 -0
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/chunk-DFBSCFYN.js +1 -0
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.js +1 -1
- package/dist/index.cjs +50 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +286 -11
- package/dist/index.d.ts +286 -11
- package/dist/index.global.js +39 -39
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +51 -51
- package/dist/index.js.map +1 -1
- package/dist/launcher.global.js.map +1 -1
- package/dist/markdown-parsers-entry-NVFT3TE6.js +1 -0
- package/dist/runtype-tts-entry-HFUV2UF7.js +1 -0
- package/dist/session-reconnect-U77QFUR7.js +1 -0
- package/dist/smart-dom-reader.d.cts +147 -8
- package/dist/smart-dom-reader.d.ts +147 -8
- package/dist/theme-editor-preview.cjs +48 -48
- package/dist/theme-editor-preview.d.cts +187 -9
- package/dist/theme-editor-preview.d.ts +187 -9
- package/dist/theme-editor-preview.js +48 -48
- package/dist/theme-editor.cjs +1 -1
- package/dist/theme-editor.d.cts +147 -8
- package/dist/theme-editor.d.ts +147 -8
- package/dist/theme-editor.js +1 -1
- package/package.json +2 -2
- package/src/client.ts +48 -7
- package/src/defaults.ts +9 -1
- package/src/generated/runtype-openapi-contract.ts +6 -0
- package/src/index-core.ts +5 -0
- package/src/reconnect-wake.test.ts +162 -0
- package/src/reconnect.test.ts +430 -0
- package/src/session-reconnect.ts +282 -0
- package/src/session.ts +408 -5
- package/src/types.ts +165 -9
- package/src/ui.scroll-additive.test.ts +451 -0
- package/src/ui.scroll.test.ts +8 -2
- package/src/ui.stream-animation-update.test.ts +99 -0
- package/src/ui.ts +371 -41
- package/src/utils/constants.ts +3 -1
package/src/ui.scroll.test.ts
CHANGED
|
@@ -912,9 +912,12 @@ describe("createAgentExperience streaming scroll", () => {
|
|
|
912
912
|
it("re-sticks to the bottom when the user sends a message after scrolling up", () => {
|
|
913
913
|
const raf = installRafMock();
|
|
914
914
|
const mount = createMount();
|
|
915
|
+
// Follow-specific: a user send re-sticks to the bottom (anchor-top, the
|
|
916
|
+
// default, would pin the sent message near the top instead).
|
|
915
917
|
const controller = createAgentExperience(mount, {
|
|
916
918
|
apiUrl: "https://api.example.com/chat",
|
|
917
|
-
launcher: { enabled: false }
|
|
919
|
+
launcher: { enabled: false },
|
|
920
|
+
features: { scrollBehavior: { mode: "follow" } }
|
|
918
921
|
});
|
|
919
922
|
|
|
920
923
|
const scrollContainer = mount.querySelector<HTMLElement>("#persona-scroll-container");
|
|
@@ -941,9 +944,12 @@ describe("createAgentExperience streaming scroll", () => {
|
|
|
941
944
|
it("shows a count badge for messages that arrive while paused", () => {
|
|
942
945
|
const raf = installRafMock();
|
|
943
946
|
const mount = createMount();
|
|
947
|
+
// Follow-specific paused-badge semantics (wheel-up pauses auto-follow, then
|
|
948
|
+
// a message arrives while paused and below the fold).
|
|
944
949
|
const controller = createAgentExperience(mount, {
|
|
945
950
|
apiUrl: "https://api.example.com/chat",
|
|
946
|
-
launcher: { enabled: false }
|
|
951
|
+
launcher: { enabled: false },
|
|
952
|
+
features: { scrollBehavior: { mode: "follow" } }
|
|
947
953
|
});
|
|
948
954
|
|
|
949
955
|
const scrollContainer = mount.querySelector<HTMLElement>("#persona-scroll-container");
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
|
|
5
|
+
import { createAgentExperience } from "./ui";
|
|
6
|
+
import {
|
|
7
|
+
registerStreamAnimationPlugin,
|
|
8
|
+
unregisterStreamAnimationPlugin,
|
|
9
|
+
} from "./utils/stream-animation";
|
|
10
|
+
import type { StreamAnimationPlugin } from "./types";
|
|
11
|
+
|
|
12
|
+
// A plugin animation carries its own CSS (built-in animations live in
|
|
13
|
+
// widget.css). Plugin styles are injected only via ensurePluginActive, which the
|
|
14
|
+
// initial mount runs but controller.update() historically skipped — so switching
|
|
15
|
+
// to a plugin animation live used to set the type without ever injecting the CSS.
|
|
16
|
+
const TEST_PLUGIN: StreamAnimationPlugin = {
|
|
17
|
+
name: "test-reveal",
|
|
18
|
+
containerClass: "test-reveal-stream",
|
|
19
|
+
wrap: "char",
|
|
20
|
+
styles: ".test-reveal-stream .persona-stream-char { opacity: 0; }",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const createMount = () => {
|
|
24
|
+
const mount = document.createElement("div");
|
|
25
|
+
document.body.appendChild(mount);
|
|
26
|
+
return mount;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const styleTag = (mount: HTMLElement) =>
|
|
30
|
+
mount.querySelector('style[data-persona-animation="test-reveal"]');
|
|
31
|
+
|
|
32
|
+
describe("createAgentExperience: stream-animation plugin activation on update()", () => {
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
vi.stubGlobal("requestAnimationFrame", (cb: (time: number) => void) => {
|
|
35
|
+
cb(0);
|
|
36
|
+
return 1;
|
|
37
|
+
});
|
|
38
|
+
vi.stubGlobal("cancelAnimationFrame", () => {});
|
|
39
|
+
window.scrollTo = vi.fn();
|
|
40
|
+
registerStreamAnimationPlugin(TEST_PLUGIN);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
unregisterStreamAnimationPlugin("test-reveal");
|
|
45
|
+
document.body.innerHTML = "";
|
|
46
|
+
vi.restoreAllMocks();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("injects a plugin animation's styles when switched in via update()", () => {
|
|
50
|
+
const mount = createMount();
|
|
51
|
+
const controller = createAgentExperience(mount, {
|
|
52
|
+
apiUrl: "https://api.example.com/chat",
|
|
53
|
+
launcher: { enabled: false },
|
|
54
|
+
features: { streamAnimation: { type: "none" } },
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Nothing injected while the type is "none".
|
|
58
|
+
expect(styleTag(mount)).toBeNull();
|
|
59
|
+
|
|
60
|
+
controller.update({
|
|
61
|
+
features: { streamAnimation: { type: "test-reveal" } },
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// The plugin's <style> is now present, so the animation can actually render.
|
|
65
|
+
expect(styleTag(mount)).not.toBeNull();
|
|
66
|
+
|
|
67
|
+
controller.destroy();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("activates the plugin at mount when configured up front", () => {
|
|
71
|
+
const mount = createMount();
|
|
72
|
+
const controller = createAgentExperience(mount, {
|
|
73
|
+
apiUrl: "https://api.example.com/chat",
|
|
74
|
+
launcher: { enabled: false },
|
|
75
|
+
features: { streamAnimation: { type: "test-reveal" } },
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
expect(styleTag(mount)).not.toBeNull();
|
|
79
|
+
controller.destroy();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("does not duplicate the style tag when the same plugin is re-selected", () => {
|
|
83
|
+
const mount = createMount();
|
|
84
|
+
const controller = createAgentExperience(mount, {
|
|
85
|
+
apiUrl: "https://api.example.com/chat",
|
|
86
|
+
launcher: { enabled: false },
|
|
87
|
+
features: { streamAnimation: { type: "test-reveal" } },
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
controller.update({ features: { streamAnimation: { type: "none" } } });
|
|
91
|
+
controller.update({ features: { streamAnimation: { type: "test-reveal" } } });
|
|
92
|
+
|
|
93
|
+
expect(
|
|
94
|
+
mount.querySelectorAll('style[data-persona-animation="test-reveal"]'),
|
|
95
|
+
).toHaveLength(1);
|
|
96
|
+
|
|
97
|
+
controller.destroy();
|
|
98
|
+
});
|
|
99
|
+
});
|