@smartspace/chat-ui 1.13.1-pr.418.0119b54 → 1.13.1-pr.419.f58f7bb

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/index.d.ts CHANGED
@@ -439,13 +439,10 @@ declare function mapMessageDtoToModel(dto: MessageDto): Message;
439
439
  declare function mapMessagesDtoToModels(dto: MessageDto[]): Message[];
440
440
  /**
441
441
  * Merge a streaming delta into a message. `outputs` is a cumulative snapshot
442
- * keyed by value `id` — when an output streams from "He" → "Hel" → "Hello" we
443
- * receive three deltas each carrying the full text-so-far under one id, so we
444
- * replace by id rather than appending. Several blocks can be wired into a
445
- * single flow output (five render blocks feeding one "Files" output, say);
446
- * those arrive under the same NAME but different ids and must all survive,
447
- * which is why the key is not `(name, type)`. Errors aren't documented as
448
- * cumulative, so we append them.
442
+ * keyed by `(name, type)` per the SSE protocol — when an output streams from
443
+ * "He" → "Hel" → "Hello" we receive three deltas each carrying the full
444
+ * text-so-far, so we replace by key rather than appending. Errors aren't
445
+ * documented as cumulative, so we append them.
449
446
  */
450
447
  declare function applyDeltaToMessage(target: Message, delta: {
451
448
  outputs: MessageValue[];
package/dist/index.js CHANGED
@@ -1600,6 +1600,21 @@ function getSchemaNodeType(view, name) {
1600
1600
  return null;
1601
1601
  return t;
1602
1602
  }
1603
+ function findMentionTriggerPos(doc, windowStart, from) {
1604
+ let triggerPos = null;
1605
+ doc.nodesBetween(windowStart, from, (node2, pos) => {
1606
+ if (!node2.isText || !node2.text) {
1607
+ triggerPos = null;
1608
+ return;
1609
+ }
1610
+ for (let i = 0; i < node2.text.length; i++) {
1611
+ const charPos = pos + i;
1612
+ if (charPos < windowStart || charPos >= from) continue;
1613
+ if (node2.text[i] === "@") triggerPos = charPos;
1614
+ }
1615
+ });
1616
+ return triggerPos;
1617
+ }
1603
1618
  function EditorInner({
1604
1619
  value,
1605
1620
  onChange: _onChange,
@@ -1773,7 +1788,7 @@ function EditorInner({
1773
1788
  bottom: coords.bottom
1774
1789
  });
1775
1790
  setMentionPlacement(getMentionPlacement(coords.top));
1776
- setMentionFromPos(Math.max(0, pos - 1));
1791
+ setMentionFromPos(pos);
1777
1792
  setMentionQuery("");
1778
1793
  setMentionIndex(0);
1779
1794
  setMentionOpen(true);
@@ -2267,7 +2282,8 @@ function EditorInner({
2267
2282
  const view = viewRef.current;
2268
2283
  if (!view) return;
2269
2284
  const to = view.state.selection.from;
2270
- const start = mentionFromPos != null ? mentionFromPos : to - 1;
2285
+ if (mentionFromPos == null) return;
2286
+ const start = mentionFromPos;
2271
2287
  const type = view.state.schema.nodes["mention"];
2272
2288
  if (!type) return;
2273
2289
  const node2 = type.create({ id: user.id, label: user.displayName });
@@ -2292,13 +2308,21 @@ function EditorInner({
2292
2308
  if (!isEditable || !view) return;
2293
2309
  const { from } = view.state.selection;
2294
2310
  const windowStart = Math.max(0, from - 200);
2295
- const text6 = view.state.doc.textBetween(windowStart, from, "\n", "\n");
2296
- const at = text6.lastIndexOf("@");
2297
- if (at === -1) {
2311
+ const absoluteFrom = findMentionTriggerPos(
2312
+ view.state.doc,
2313
+ windowStart,
2314
+ from
2315
+ );
2316
+ if (absoluteFrom === null) {
2298
2317
  if (mentionOpen) setMentionOpen(false);
2299
2318
  return;
2300
2319
  }
2301
- const after = text6.slice(at + 1);
2320
+ const after = view.state.doc.textBetween(
2321
+ absoluteFrom + 1,
2322
+ from,
2323
+ "\n",
2324
+ "\n"
2325
+ );
2302
2326
  if (/[\t\r\n]/.test(after)) {
2303
2327
  if (mentionOpen) setMentionOpen(false);
2304
2328
  return;
@@ -2308,7 +2332,6 @@ function EditorInner({
2308
2332
  if (mentionOpen) setMentionOpen(false);
2309
2333
  return;
2310
2334
  }
2311
- const absoluteFrom = windowStart + at;
2312
2335
  if (mentionDismissedAtRef.current === absoluteFrom) {
2313
2336
  return;
2314
2337
  }
@@ -19683,7 +19706,7 @@ var MessageItem = ({
19683
19706
  const slotByKey = /* @__PURE__ */ new Map();
19684
19707
  const values = [];
19685
19708
  for (const v of sortedValues) {
19686
- const key = v.id ? `id|${v.id}` : `nametype|${v.name}|${v.type}`;
19709
+ const key = `${v.name}|${v.type}`;
19687
19710
  const existing = slotByKey.get(key);
19688
19711
  if (existing !== void 0) {
19689
19712
  values[existing] = v;
@@ -20173,11 +20196,7 @@ function applyDeltaToMessage(target, delta) {
20173
20196
  const nextValues = (target.values ?? []).slice();
20174
20197
  for (const incoming of delta.outputs) {
20175
20198
  const idx = nextValues.findIndex(
20176
- (v) => (
20177
- // Values with no id come from a server that predates per-output ids;
20178
- // fall back to the old key so their chunks still replace in place.
20179
- incoming.id ? v.id === incoming.id : v.name === incoming.name && v.type === incoming.type
20180
- )
20199
+ (v) => v.name === incoming.name && v.type === incoming.type
20181
20200
  );
20182
20201
  if (idx === -1) nextValues.push(incoming);
20183
20202
  else nextValues[idx] = incoming;