@portablecore/chat 0.2.15 → 0.3.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.
Files changed (40) hide show
  1. package/dist/chat-interface-core.d.ts +5 -0
  2. package/dist/chat-interface-core.d.ts.map +1 -1
  3. package/dist/chat-interface-core.js +96 -9
  4. package/dist/chat-interface-core.js.map +1 -1
  5. package/dist/components/density-control.d.ts +14 -0
  6. package/dist/components/density-control.d.ts.map +1 -0
  7. package/dist/components/density-control.js +18 -0
  8. package/dist/components/density-control.js.map +1 -0
  9. package/dist/components/focus-mode-control.d.ts +3 -10
  10. package/dist/components/focus-mode-control.d.ts.map +1 -1
  11. package/dist/components/focus-mode-control.js +5 -10
  12. package/dist/components/focus-mode-control.js.map +1 -1
  13. package/dist/components/message-bubble.d.ts.map +1 -1
  14. package/dist/components/message-bubble.js +2 -2
  15. package/dist/components/message-bubble.js.map +1 -1
  16. package/dist/components/message-list.d.ts +16 -2
  17. package/dist/components/message-list.d.ts.map +1 -1
  18. package/dist/components/message-list.js +44 -6
  19. package/dist/components/message-list.js.map +1 -1
  20. package/dist/hooks/use-chat-scroll.d.ts +10 -1
  21. package/dist/hooks/use-chat-scroll.d.ts.map +1 -1
  22. package/dist/hooks/use-chat-scroll.js +99 -32
  23. package/dist/hooks/use-chat-scroll.js.map +1 -1
  24. package/dist/hooks/use-content-density.d.ts +35 -0
  25. package/dist/hooks/use-content-density.d.ts.map +1 -0
  26. package/dist/hooks/use-content-density.js +96 -0
  27. package/dist/hooks/use-content-density.js.map +1 -0
  28. package/dist/hooks/use-focus-mode.d.ts +4 -26
  29. package/dist/hooks/use-focus-mode.d.ts.map +1 -1
  30. package/dist/hooks/use-focus-mode.js +5 -75
  31. package/dist/hooks/use-focus-mode.js.map +1 -1
  32. package/dist/hooks/use-virtual-messages.d.ts +34 -0
  33. package/dist/hooks/use-virtual-messages.d.ts.map +1 -0
  34. package/dist/hooks/use-virtual-messages.js +149 -0
  35. package/dist/hooks/use-virtual-messages.js.map +1 -0
  36. package/dist/index.d.ts +8 -3
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +17 -6
  39. package/dist/index.js.map +1 -1
  40. package/package.json +20 -19
@@ -0,0 +1,149 @@
1
+ "use client";
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PRE_MEASURE_THRESHOLD = exports.VIRTUALIZATION_THRESHOLD = void 0;
5
+ exports.useVirtualMessages = useVirtualMessages;
6
+ /**
7
+ * useVirtualMessages — Battle-tested virtualizer for large chat histories.
8
+ *
9
+ * Ported from the legacy ChatInterface's tanstack/react-virtual integration,
10
+ * which included workarounds for variable-height messages, mode transitions,
11
+ * and mobile scrolling. Gated behind config.features.jsVirtualization.
12
+ *
13
+ * Key patterns ported from legacy:
14
+ * - Overscan 100 (pre-render many items above/below viewport)
15
+ * - Content-length-based height estimation with short/long awareness
16
+ * - Mode version in getItemKey for cache invalidation on view mode changes
17
+ * - isResetting state (count-to-0) for mode transitions
18
+ * - Settlement polling (50ms, 4-stable, 40-max) with 2.5s fallback
19
+ * - Pre-measured heights map integration for accurate initial positioning
20
+ */
21
+ const react_1 = require("react");
22
+ const react_virtual_1 = require("@tanstack/react-virtual");
23
+ exports.VIRTUALIZATION_THRESHOLD = 100;
24
+ exports.PRE_MEASURE_THRESHOLD = 100;
25
+ function estimateMessageHeight(rm, preMeasuredHeights, isExpanded) {
26
+ const msg = rm.message;
27
+ const PADDING = 24;
28
+ if (preMeasuredHeights) {
29
+ const cached = preMeasuredHeights.get(msg.id);
30
+ if (cached) {
31
+ if (typeof cached === "object") {
32
+ return isExpanded ? cached.long : cached.short;
33
+ }
34
+ return cached;
35
+ }
36
+ }
37
+ let base = 0;
38
+ if (rm.showDateSeparator)
39
+ base += 48;
40
+ if (msg.role === "user") {
41
+ const hasDocuments = msg.metadata?.hasDocuments;
42
+ return base + (hasDocuments ? 150 : 80) + PADDING;
43
+ }
44
+ const relevantContent = !isExpanded && msg.shortContent ? msg.shortContent : msg.content;
45
+ const contentLength = relevantContent?.length || 0;
46
+ if (contentLength < 200)
47
+ return base + 100 + PADDING;
48
+ if (contentLength < 500)
49
+ return base + 150 + PADDING;
50
+ if (contentLength < 1000)
51
+ return base + 250 + PADDING;
52
+ if (contentLength < 2000)
53
+ return base + 400 + PADDING;
54
+ return base + 600 + PADDING;
55
+ }
56
+ function useVirtualMessages({ renderableMessages, scrollRef, measureVersion = 0, enabled = true, preMeasuredHeights, getMessageIsExpanded, }) {
57
+ const count = renderableMessages.length;
58
+ const shouldVirtualize = enabled && count >= exports.VIRTUALIZATION_THRESHOLD;
59
+ const messagesRef = (0, react_1.useRef)(renderableMessages);
60
+ messagesRef.current = renderableMessages;
61
+ const preMeasuredRef = (0, react_1.useRef)(preMeasuredHeights);
62
+ preMeasuredRef.current = preMeasuredHeights;
63
+ const getExpandedRef = (0, react_1.useRef)(getMessageIsExpanded);
64
+ getExpandedRef.current = getMessageIsExpanded;
65
+ const [modeVersion, setModeVersion] = (0, react_1.useState)(0);
66
+ const [isResetting, setIsResetting] = (0, react_1.useState)(false);
67
+ const [isSettled, setIsSettled] = (0, react_1.useState)(!shouldVirtualize);
68
+ const prevMeasureVersion = (0, react_1.useRef)(measureVersion);
69
+ (0, react_1.useEffect)(() => {
70
+ if (prevMeasureVersion.current !== measureVersion && shouldVirtualize) {
71
+ prevMeasureVersion.current = measureVersion;
72
+ setIsResetting(true);
73
+ setIsSettled(false);
74
+ setModeVersion((v) => v + 1);
75
+ requestAnimationFrame(() => {
76
+ setIsResetting(false);
77
+ });
78
+ }
79
+ }, [measureVersion, shouldVirtualize]);
80
+ const virtualizer = (0, react_virtual_1.useVirtualizer)({
81
+ count: isResetting ? 0 : shouldVirtualize ? count : 0,
82
+ getScrollElement: () => scrollRef.current,
83
+ estimateSize: (0, react_1.useCallback)((index) => {
84
+ const rm = messagesRef.current[index];
85
+ if (!rm)
86
+ return 100;
87
+ const isExpanded = getExpandedRef.current?.(rm.message.id, index) ?? true;
88
+ return estimateMessageHeight(rm, preMeasuredRef.current, isExpanded);
89
+ }, []),
90
+ getItemKey: (0, react_1.useCallback)((index) => {
91
+ const rm = messagesRef.current[index];
92
+ return `${rm?.message.id ?? index}-v${modeVersion}`;
93
+ }, [modeVersion]),
94
+ overscan: 100,
95
+ });
96
+ // Settlement polling: watch for scrollHeight stability after initial render.
97
+ // 50ms polling, need 4 consecutive stable checks (~200ms), give up after 40 (~2s).
98
+ (0, react_1.useEffect)(() => {
99
+ if (!shouldVirtualize || isResetting || isSettled)
100
+ return;
101
+ const container = scrollRef.current;
102
+ if (!container) {
103
+ setIsSettled(true);
104
+ return;
105
+ }
106
+ let lastScrollHeight = container.scrollHeight;
107
+ let stableCount = 0;
108
+ const STABLE_THRESHOLD = 4;
109
+ const MAX_CHECKS = 40;
110
+ let checkCount = 0;
111
+ let pollTimer;
112
+ const checkSettlement = () => {
113
+ checkCount++;
114
+ const currentScrollHeight = container.scrollHeight;
115
+ if (currentScrollHeight !== lastScrollHeight) {
116
+ lastScrollHeight = currentScrollHeight;
117
+ stableCount = 0;
118
+ }
119
+ else {
120
+ stableCount++;
121
+ }
122
+ if (stableCount >= STABLE_THRESHOLD || checkCount >= MAX_CHECKS) {
123
+ setIsSettled(true);
124
+ return;
125
+ }
126
+ pollTimer = setTimeout(checkSettlement, 50);
127
+ };
128
+ pollTimer = setTimeout(checkSettlement, 50);
129
+ const fallbackTimer = setTimeout(() => {
130
+ setIsSettled(true);
131
+ }, 2500);
132
+ return () => {
133
+ clearTimeout(pollTimer);
134
+ clearTimeout(fallbackTimer);
135
+ };
136
+ }, [shouldVirtualize, isResetting, isSettled, scrollRef]);
137
+ if (!shouldVirtualize) {
138
+ return { active: false };
139
+ }
140
+ return {
141
+ active: true,
142
+ virtualizer,
143
+ virtualItems: virtualizer.getVirtualItems(),
144
+ totalSize: virtualizer.getTotalSize(),
145
+ isSettled,
146
+ isResetting,
147
+ };
148
+ }
149
+ //# sourceMappingURL=use-virtual-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-virtual-messages.js","sourceRoot":"","sources":["../../src/hooks/use-virtual-messages.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -38,9 +38,14 @@ export { useProviderSelection } from "./hooks/use-provider-selection.js";
38
38
  export type { ProviderSelectionState } from "./hooks/use-provider-selection.js";
39
39
  export { ThreadFilterHeader } from "./components/thread-filter-header.js";
40
40
  export { useThreadFilter } from "./hooks/use-thread-filter.js";
41
- export { FocusModeControl } from "./components/focus-mode-control.js";
42
- export { useFocusMode } from "./hooks/use-focus-mode.js";
43
- export type { FocusModeState } from "./hooks/use-focus-mode.js";
41
+ export { DensityControl } from "./components/density-control.js";
42
+ export { useContentDensity, getDefaultViewMode } from "./hooks/use-content-density.js";
43
+ export type { ContentDensityState } from "./hooks/use-content-density.js";
44
+ export { DensityControl as FocusModeControl } from "./components/density-control.js";
45
+ export { useContentDensity as useFocusMode } from "./hooks/use-content-density.js";
46
+ export type { ContentDensityState as FocusModeState } from "./hooks/use-content-density.js";
47
+ export { useVirtualMessages, VIRTUALIZATION_THRESHOLD, PRE_MEASURE_THRESHOLD } from "./hooks/use-virtual-messages.js";
48
+ export type { VirtualState, MessageHeights } from "./hooks/use-virtual-messages.js";
44
49
  export { formatTime, getDateSeparator, isDifferentDay } from "./utils/time.js";
45
50
  export { groupMessages } from "./utils/message-grouping.js";
46
51
  export { remarkPlugins, rehypePlugins, defaultMarkdownComponents } from "./utils/markdown-config.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAG5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAG3E,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAG1D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AAGtE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAGjE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAA;AACtE,YAAY,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAA;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAChE,YAAY,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAA;AACjF,YAAY,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAA;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAGzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AACxE,YAAY,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAG/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAA;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAG9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAG/D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAA;AAGpG,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,cAAc,EACd,eAAe,EACf,WAAW,EACX,WAAW,EACX,QAAQ,EACR,SAAS,EACT,iBAAiB,GAClB,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@
11
11
  * slots, resolvers, handlers).
12
12
  */
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.defaultMarkdownComponents = exports.rehypePlugins = exports.remarkPlugins = exports.groupMessages = exports.isDifferentDay = exports.getDateSeparator = exports.formatTime = exports.useFocusMode = exports.FocusModeControl = exports.useThreadFilter = exports.ThreadFilterHeader = exports.useProviderSelection = exports.ProviderSelector = exports.useWhisperMode = exports.WhisperRecipientPicker = exports.EmptyState = exports.MessageActions = exports.CodeBlock = exports.SkillIndicator = exports.ThinkingIndicator = exports.BouncingDots = exports.StreamingText = exports.InputArea = exports.MessageBubble = exports.MessageList = exports.useAttachments = exports.AutocompletePopup = exports.useAutocomplete = exports.useChatScroll = exports.useChatSession = exports.ChatInterfaceCore = void 0;
14
+ exports.defaultMarkdownComponents = exports.rehypePlugins = exports.remarkPlugins = exports.groupMessages = exports.isDifferentDay = exports.getDateSeparator = exports.formatTime = exports.PRE_MEASURE_THRESHOLD = exports.VIRTUALIZATION_THRESHOLD = exports.useVirtualMessages = exports.useFocusMode = exports.FocusModeControl = exports.getDefaultViewMode = exports.useContentDensity = exports.DensityControl = exports.useThreadFilter = exports.ThreadFilterHeader = exports.useProviderSelection = exports.ProviderSelector = exports.useWhisperMode = exports.WhisperRecipientPicker = exports.EmptyState = exports.MessageActions = exports.CodeBlock = exports.SkillIndicator = exports.ThinkingIndicator = exports.BouncingDots = exports.StreamingText = exports.InputArea = exports.MessageBubble = exports.MessageList = exports.useAttachments = exports.AutocompletePopup = exports.useAutocomplete = exports.useChatScroll = exports.useChatSession = exports.ChatInterfaceCore = void 0;
15
15
  // The main product
16
16
  var chat_interface_core_js_1 = require("./chat-interface-core.js");
17
17
  Object.defineProperty(exports, "ChatInterfaceCore", { enumerable: true, get: function () { return chat_interface_core_js_1.ChatInterfaceCore; } });
@@ -64,11 +64,22 @@ var thread_filter_header_js_1 = require("./components/thread-filter-header.js");
64
64
  Object.defineProperty(exports, "ThreadFilterHeader", { enumerable: true, get: function () { return thread_filter_header_js_1.ThreadFilterHeader; } });
65
65
  var use_thread_filter_js_1 = require("./hooks/use-thread-filter.js");
66
66
  Object.defineProperty(exports, "useThreadFilter", { enumerable: true, get: function () { return use_thread_filter_js_1.useThreadFilter; } });
67
- // Focus mode
68
- var focus_mode_control_js_1 = require("./components/focus-mode-control.js");
69
- Object.defineProperty(exports, "FocusModeControl", { enumerable: true, get: function () { return focus_mode_control_js_1.FocusModeControl; } });
70
- var use_focus_mode_js_1 = require("./hooks/use-focus-mode.js");
71
- Object.defineProperty(exports, "useFocusMode", { enumerable: true, get: function () { return use_focus_mode_js_1.useFocusMode; } });
67
+ // Content Density (replaces Focus Mode)
68
+ var density_control_js_1 = require("./components/density-control.js");
69
+ Object.defineProperty(exports, "DensityControl", { enumerable: true, get: function () { return density_control_js_1.DensityControl; } });
70
+ var use_content_density_js_1 = require("./hooks/use-content-density.js");
71
+ Object.defineProperty(exports, "useContentDensity", { enumerable: true, get: function () { return use_content_density_js_1.useContentDensity; } });
72
+ Object.defineProperty(exports, "getDefaultViewMode", { enumerable: true, get: function () { return use_content_density_js_1.getDefaultViewMode; } });
73
+ // Legacy aliases for backward compat
74
+ var density_control_js_2 = require("./components/density-control.js");
75
+ Object.defineProperty(exports, "FocusModeControl", { enumerable: true, get: function () { return density_control_js_2.DensityControl; } });
76
+ var use_content_density_js_2 = require("./hooks/use-content-density.js");
77
+ Object.defineProperty(exports, "useFocusMode", { enumerable: true, get: function () { return use_content_density_js_2.useContentDensity; } });
78
+ // Virtualization
79
+ var use_virtual_messages_js_1 = require("./hooks/use-virtual-messages.js");
80
+ Object.defineProperty(exports, "useVirtualMessages", { enumerable: true, get: function () { return use_virtual_messages_js_1.useVirtualMessages; } });
81
+ Object.defineProperty(exports, "VIRTUALIZATION_THRESHOLD", { enumerable: true, get: function () { return use_virtual_messages_js_1.VIRTUALIZATION_THRESHOLD; } });
82
+ Object.defineProperty(exports, "PRE_MEASURE_THRESHOLD", { enumerable: true, get: function () { return use_virtual_messages_js_1.PRE_MEASURE_THRESHOLD; } });
72
83
  // Utilities
73
84
  var time_js_1 = require("./utils/time.js");
74
85
  Object.defineProperty(exports, "formatTime", { enumerable: true, get: function () { return time_js_1.formatTime; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAEH,mBAAmB;AACnB,mEAA4D;AAAnD,2HAAA,iBAAiB,OAAA;AAE1B,qEAAqE;AACrE,mEAA4D;AAAnD,qHAAA,cAAc,OAAA;AAGvB,oBAAoB;AACpB,iEAA0D;AAAjD,mHAAA,aAAa,OAAA;AAEtB,eAAe;AACf,mEAA6D;AAApD,sHAAA,eAAe,OAAA;AACxB,4EAAsE;AAA7D,0HAAA,iBAAiB,OAAA;AAE1B,cAAc;AACd,iEAA2D;AAAlD,oHAAA,cAAc,OAAA;AAGvB,sEAAsE;AACtE,gEAA0D;AAAjD,8GAAA,WAAW,OAAA;AACpB,oEAA8D;AAArD,kHAAA,aAAa,OAAA;AACtB,4DAAsD;AAA7C,0GAAA,SAAS,OAAA;AAClB,oEAA8D;AAArD,kHAAA,aAAa,OAAA;AACtB,kEAA4D;AAAnD,gHAAA,YAAY,OAAA;AACrB,4EAAsE;AAA7D,0HAAA,iBAAiB,OAAA;AAE1B,sEAAgE;AAAvD,oHAAA,cAAc,OAAA;AACvB,4DAAsD;AAA7C,0GAAA,SAAS,OAAA;AAClB,sEAAgE;AAAvD,oHAAA,cAAc,OAAA;AAEvB,8DAAwD;AAA/C,4GAAA,UAAU,OAAA;AACnB,wFAAiF;AAAxE,qIAAA,sBAAsB,OAAA;AAE/B,mEAA4D;AAAnD,qHAAA,cAAc,OAAA;AAGvB,qBAAqB;AACrB,0EAAoE;AAA3D,wHAAA,gBAAgB,OAAA;AACzB,+EAAwE;AAA/D,iIAAA,oBAAoB,OAAA;AAG7B,mBAAmB;AACnB,gFAAyE;AAAhE,6HAAA,kBAAkB,OAAA;AAC3B,qEAA8D;AAArD,uHAAA,eAAe,OAAA;AAExB,aAAa;AACb,4EAAqE;AAA5D,yHAAA,gBAAgB,OAAA;AACzB,+DAAwD;AAA/C,iHAAA,YAAY,OAAA;AAGrB,YAAY;AACZ,2CAA8E;AAArE,qGAAA,UAAU,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,yGAAA,cAAc,OAAA;AACrD,mEAA2D;AAAlD,oHAAA,aAAa,OAAA;AACtB,iEAAoG;AAA3F,mHAAA,aAAa,OAAA;AAAE,mHAAA,aAAa,OAAA;AAAE,+HAAA,yBAAyB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAEH,mBAAmB;AACnB,mEAA4D;AAAnD,2HAAA,iBAAiB,OAAA;AAE1B,qEAAqE;AACrE,mEAA4D;AAAnD,qHAAA,cAAc,OAAA;AAGvB,oBAAoB;AACpB,iEAA0D;AAAjD,mHAAA,aAAa,OAAA;AAEtB,eAAe;AACf,mEAA6D;AAApD,sHAAA,eAAe,OAAA;AACxB,4EAAsE;AAA7D,0HAAA,iBAAiB,OAAA;AAE1B,cAAc;AACd,iEAA2D;AAAlD,oHAAA,cAAc,OAAA;AAGvB,sEAAsE;AACtE,gEAA0D;AAAjD,8GAAA,WAAW,OAAA;AACpB,oEAA8D;AAArD,kHAAA,aAAa,OAAA;AACtB,4DAAsD;AAA7C,0GAAA,SAAS,OAAA;AAClB,oEAA8D;AAArD,kHAAA,aAAa,OAAA;AACtB,kEAA4D;AAAnD,gHAAA,YAAY,OAAA;AACrB,4EAAsE;AAA7D,0HAAA,iBAAiB,OAAA;AAE1B,sEAAgE;AAAvD,oHAAA,cAAc,OAAA;AACvB,4DAAsD;AAA7C,0GAAA,SAAS,OAAA;AAClB,sEAAgE;AAAvD,oHAAA,cAAc,OAAA;AAEvB,8DAAwD;AAA/C,4GAAA,UAAU,OAAA;AACnB,wFAAiF;AAAxE,qIAAA,sBAAsB,OAAA;AAE/B,mEAA4D;AAAnD,qHAAA,cAAc,OAAA;AAGvB,qBAAqB;AACrB,0EAAoE;AAA3D,wHAAA,gBAAgB,OAAA;AACzB,+EAAwE;AAA/D,iIAAA,oBAAoB,OAAA;AAG7B,mBAAmB;AACnB,gFAAyE;AAAhE,6HAAA,kBAAkB,OAAA;AAC3B,qEAA8D;AAArD,uHAAA,eAAe,OAAA;AAExB,wCAAwC;AACxC,sEAAgE;AAAvD,oHAAA,cAAc,OAAA;AACvB,yEAAsF;AAA7E,2HAAA,iBAAiB,OAAA;AAAE,4HAAA,kBAAkB,OAAA;AAG9C,qCAAqC;AACrC,sEAAoF;AAA3E,sHAAA,cAAc,OAAoB;AAC3C,yEAAkF;AAAzE,sHAAA,iBAAiB,OAAgB;AAG1C,iBAAiB;AACjB,2EAAqH;AAA5G,6HAAA,kBAAkB,OAAA;AAAE,mIAAA,wBAAwB,OAAA;AAAE,gIAAA,qBAAqB,OAAA;AAG5E,YAAY;AACZ,2CAA8E;AAArE,qGAAA,UAAU,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,yGAAA,cAAc,OAAA;AACrD,mEAA2D;AAAlD,oHAAA,aAAa,OAAA;AACtB,iEAAoG;AAA3F,mHAAA,aAAa,OAAA;AAAE,mHAAA,aAAa,OAAA;AAAE,+HAAA,yBAAyB,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portablecore/chat",
3
- "version": "0.2.15",
3
+ "version": "0.3.0",
4
4
  "description": "Unified chat UI for Portable platforms — composable ChatInterface with extension points",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -13,6 +13,12 @@
13
13
  "files": [
14
14
  "dist"
15
15
  ],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "dev": "tsc --watch",
19
+ "clean": "rm -rf dist",
20
+ "typecheck": "tsc --noEmit"
21
+ },
16
22
  "keywords": [
17
23
  "portable",
18
24
  "chat",
@@ -23,31 +29,26 @@
23
29
  "author": "Portable",
24
30
  "license": "UNLICENSED",
25
31
  "dependencies": {
26
- "remark-gfm": "^4.0.1",
27
- "remark-breaks": "^4.0.0",
28
- "rehype-raw": "^7.0.0",
32
+ "@portablecore/chat-runtime": "workspace:*",
33
+ "@portablecore/types": "workspace:*",
34
+ "@tanstack/react-virtual": "^3.13.22",
29
35
  "rehype-highlight": "^7.0.2",
30
- "@portablecore/chat-runtime": "0.1.0",
31
- "@portablecore/types": "0.11.6"
36
+ "rehype-raw": "^7.0.0",
37
+ "remark-breaks": "^4.0.0",
38
+ "remark-gfm": "^4.0.1"
32
39
  },
33
40
  "peerDependencies": {
34
- "react": ">=18.0.0",
35
- "react-markdown": ">=9.0.0",
36
41
  "@nvq/flowtoken": ">=2.0.0",
37
- "lucide-react": ">=0.300.0"
42
+ "lucide-react": ">=0.300.0",
43
+ "react": ">=18.0.0",
44
+ "react-markdown": ">=9.0.0"
38
45
  },
39
46
  "devDependencies": {
40
- "typescript": "^5.3.0",
47
+ "@nvq/flowtoken": "^2.0.6",
41
48
  "@types/react": "^18.0.0",
49
+ "lucide-react": "^0.562.0",
42
50
  "react": "^18.0.0",
43
51
  "react-markdown": "^10.1.0",
44
- "@nvq/flowtoken": "^2.0.6",
45
- "lucide-react": "^0.562.0"
46
- },
47
- "scripts": {
48
- "build": "tsc",
49
- "dev": "tsc --watch",
50
- "clean": "rm -rf dist",
51
- "typecheck": "tsc --noEmit"
52
+ "typescript": "^5.3.0"
52
53
  }
53
- }
54
+ }