@floegence/floe-webapp-core 0.27.4 → 0.27.5

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.
@@ -6,6 +6,7 @@ export interface ChatContextValue {
6
6
  isLoadingHistory: Accessor<boolean>;
7
7
  hasMoreHistory: Accessor<boolean>;
8
8
  streamingMessageId: Accessor<string | null>;
9
+ isPreparing: Accessor<boolean>;
9
10
  isWorking: Accessor<boolean>;
10
11
  config: Accessor<ChatConfig>;
11
12
  virtualListConfig: Accessor<VirtualListConfig>;
@@ -1,60 +1,79 @@
1
- import { createComponent as N } from "solid-js/web";
2
- import { createMemo as x, createEffect as W, on as _, createSignal as I, useContext as O, createContext as V, batch as H } from "solid-js";
3
- import { createStore as G, reconcile as S, produce as y } from "solid-js/store";
4
- import { deferNonBlocking as h } from "../../utils/defer.js";
5
- import { DEFAULT_VIRTUAL_LIST_CONFIG as J } from "./types.js";
6
- const L = V();
7
- function ue() {
8
- const r = O(L);
9
- if (!r)
1
+ import { createComponent as X } from "solid-js/web";
2
+ import { createMemo as b, createEffect as Y, on as Z, createSignal as C, useContext as $, createContext as ee, batch as E } from "solid-js";
3
+ import { createStore as te, reconcile as v, produce as M } from "solid-js/store";
4
+ import { deferNonBlocking as p } from "../../utils/defer.js";
5
+ import { DEFAULT_VIRTUAL_LIST_CONFIG as se } from "./types.js";
6
+ const F = ee();
7
+ function Ce() {
8
+ const o = $(F);
9
+ if (!o)
10
10
  throw new Error("useChatContext must be used within a ChatProvider");
11
- return r;
11
+ return o;
12
12
  }
13
- const ge = (r) => {
14
- const k = x(() => ({
13
+ const Me = (o) => {
14
+ const S = b(() => ({
15
15
  placeholder: "Type a message...",
16
16
  allowAttachments: !0,
17
17
  maxAttachments: 10,
18
18
  maxAttachmentSize: 10485760,
19
19
  // 10MB
20
- ...r.config
21
- })), d = x(() => ({
22
- ...J,
23
- ...r.config?.virtualList
24
- })), [c, u] = G(r.initialMessages || []), U = /* @__PURE__ */ new Map();
25
- W(_(() => r.initialMessages, (e) => {
26
- e && e.length > 0 && u(S(e));
20
+ ...o.config
21
+ })), d = b(() => ({
22
+ ...se,
23
+ ...o.config?.virtualList
24
+ })), [c, u] = te(o.initialMessages || []), z = /* @__PURE__ */ new Map();
25
+ Y(Z(() => o.initialMessages, (e) => {
26
+ e && e.length > 0 && u(v(e));
27
27
  }, {
28
28
  defer: !0
29
29
  }));
30
- const [w, A] = I(!1), [T, E] = I(!0), [v, b] = I(null), g = /* @__PURE__ */ new Map(), F = x(() => v() !== null), m = (e) => {
31
- u(y((t) => {
30
+ const [A, H] = C(!1), [P, R] = C(!0), [L, x] = C(null), [B, I] = C(0);
31
+ let D = 0;
32
+ const g = /* @__PURE__ */ new Set(), h = [], f = /* @__PURE__ */ new Map(), O = (e) => {
33
+ if (!g.delete(e)) return;
34
+ const t = h.indexOf(e);
35
+ t >= 0 && h.splice(t, 1), I(g.size);
36
+ }, j = () => {
37
+ const e = ++D;
38
+ return g.add(e), h.push(e), I(g.size), e;
39
+ }, q = () => {
40
+ for (; h.length > 0; ) {
41
+ const e = h.shift();
42
+ if (e === void 0) return;
43
+ if (g.has(e)) {
44
+ g.delete(e), I(g.size);
45
+ return;
46
+ }
47
+ }
48
+ }, U = b(() => B() > 0), N = b(() => U() || L() !== null), k = (e) => {
49
+ u(M((t) => {
32
50
  t.push(e);
33
51
  }));
34
52
  }, l = (e, t) => {
35
- u(y((s) => {
36
- const o = s.findIndex((n) => n.id === e);
37
- o !== -1 && (s[o] = t(s[o]));
53
+ u(M((s) => {
54
+ const n = s.findIndex((a) => a.id === e);
55
+ n !== -1 && (s[n] = t(s[n]));
38
56
  }));
39
- }, P = (e) => {
40
- u(y((t) => {
41
- const s = t.findIndex((o) => o.id === e);
57
+ }, W = (e) => {
58
+ u(M((t) => {
59
+ const s = t.findIndex((n) => n.id === e);
42
60
  s !== -1 && t.splice(s, 1);
43
- })), g.delete(e);
44
- }, R = () => {
45
- u(S([])), g.clear();
46
- }, B = (e) => {
47
- u(S(e));
61
+ })), f.delete(e);
62
+ }, _ = () => {
63
+ u(v([])), f.clear();
64
+ }, V = (e) => {
65
+ u(v(e));
48
66
  };
49
- let M = [], C = null;
50
- const z = () => {
51
- const e = M;
52
- M = [], C = null, H(() => {
53
- e.forEach(D);
67
+ let T = [], w = null;
68
+ const G = () => {
69
+ const e = T;
70
+ T = [], w = null, E(() => {
71
+ e.forEach(Q);
54
72
  });
55
- }, D = (e) => {
73
+ }, Q = (e) => {
56
74
  switch (e.type) {
57
75
  case "message-start": {
76
+ q();
58
77
  const t = {
59
78
  id: e.messageId,
60
79
  role: "assistant",
@@ -62,20 +81,20 @@ const ge = (r) => {
62
81
  status: "streaming",
63
82
  timestamp: Date.now()
64
83
  };
65
- m(t), b(e.messageId);
84
+ k(t), x(e.messageId);
66
85
  break;
67
86
  }
68
87
  case "block-start": {
69
88
  l(e.messageId, (t) => ({
70
89
  ...t,
71
- blocks: [...t.blocks, K(e.blockType)]
90
+ blocks: [...t.blocks, ne(e.blockType)]
72
91
  }));
73
92
  break;
74
93
  }
75
94
  case "block-delta": {
76
95
  l(e.messageId, (t) => {
77
- const s = [...t.blocks], o = s[e.blockIndex];
78
- return o && "content" in o && typeof o.content == "string" && (o.content += e.delta), {
96
+ const s = [...t.blocks], n = s[e.blockIndex];
97
+ return n && "content" in n && typeof n.content == "string" && (n.content += e.delta), {
79
98
  ...t,
80
99
  blocks: s
81
100
  };
@@ -98,7 +117,7 @@ const ge = (r) => {
98
117
  l(e.messageId, (t) => ({
99
118
  ...t,
100
119
  status: "complete"
101
- })), b(null);
120
+ })), x(null);
102
121
  break;
103
122
  }
104
123
  case "error": {
@@ -106,69 +125,72 @@ const ge = (r) => {
106
125
  ...t,
107
126
  status: "error",
108
127
  error: e.error
109
- })), b(null);
128
+ })), x(null);
110
129
  break;
111
130
  }
112
131
  }
113
- }, j = {
132
+ }, J = {
114
133
  messages: () => c,
115
- coldMessages: U,
116
- isLoadingHistory: w,
117
- hasMoreHistory: T,
118
- streamingMessageId: v,
119
- isWorking: F,
120
- config: k,
134
+ coldMessages: z,
135
+ isLoadingHistory: A,
136
+ hasMoreHistory: P,
137
+ streamingMessageId: L,
138
+ isPreparing: U,
139
+ isWorking: N,
140
+ config: S,
121
141
  virtualListConfig: d,
122
142
  sendMessage: async (e, t = []) => {
123
143
  const s = {
124
144
  id: crypto.randomUUID(),
125
145
  role: "user",
126
- blocks: Q(e, t),
146
+ blocks: oe(e, t),
127
147
  status: "sending",
128
148
  timestamp: Date.now()
129
149
  };
130
- H(() => {
131
- m(s), l(s.id, (i) => ({
150
+ E(() => {
151
+ k(s), l(s.id, (i) => ({
132
152
  ...i,
133
153
  status: "complete"
134
154
  }));
135
155
  });
136
156
  try {
137
- r.callbacks?.onWillSend?.(e, t);
157
+ o.callbacks?.onWillSend?.(e, t);
138
158
  } catch (i) {
139
159
  console.error("onWillSend error:", i);
140
160
  }
141
- const o = r.callbacks?.onSendMessage;
142
- if (!o) return;
143
- const n = e, a = [...t];
144
- h(() => {
145
- Promise.resolve(o(n, a, m)).catch((i) => {
161
+ const n = o.callbacks?.onSendMessage;
162
+ if (!n) return;
163
+ const a = j(), r = e, m = [...t];
164
+ p(() => {
165
+ Promise.resolve().then(() => n(r, m, k)).catch((i) => {
146
166
  console.error("Failed to send message:", i);
167
+ }).finally(() => {
168
+ O(a);
147
169
  });
148
170
  });
149
171
  },
150
172
  loadMoreHistory: async () => {
151
- if (w() || !T()) return;
152
- const e = r.callbacks?.onLoadMore;
153
- e && (A(!0), h(() => {
173
+ if (A() || !P()) return;
174
+ const e = o.callbacks?.onLoadMore;
175
+ e && (H(!0), p(() => {
154
176
  Promise.resolve(e()).then((t) => {
155
177
  if (t.length === 0) {
156
- E(!1);
178
+ R(!1);
157
179
  return;
158
180
  }
159
- u(y((s) => {
181
+ u(M((s) => {
160
182
  s.unshift(...t);
161
183
  }));
162
184
  }).catch((t) => {
163
185
  console.error("Failed to load history:", t);
164
186
  }).finally(() => {
165
- A(!1);
187
+ H(!1);
166
188
  });
167
189
  }));
168
190
  },
169
191
  retryMessage: (e) => {
170
- const t = r.callbacks?.onRetry;
171
- t && h(() => {
192
+ const t = o.callbacks?.onRetry;
193
+ t && p(() => {
172
194
  try {
173
195
  t(e);
174
196
  } catch (s) {
@@ -176,97 +198,97 @@ const ge = (r) => {
176
198
  }
177
199
  });
178
200
  },
179
- addMessage: m,
201
+ addMessage: k,
180
202
  updateMessage: l,
181
- deleteMessage: P,
182
- clearMessages: R,
183
- setMessages: B,
203
+ deleteMessage: W,
204
+ clearMessages: _,
205
+ setMessages: V,
184
206
  handleStreamEvent: (e) => {
185
- M.push(e), C || (C = requestAnimationFrame(z));
207
+ T.push(e), w || (w = requestAnimationFrame(G));
186
208
  },
187
209
  uploadAttachment: async (e) => {
188
- const t = r.callbacks?.onUploadAttachment;
210
+ const t = o.callbacks?.onUploadAttachment;
189
211
  return t ? await t(e) : URL.createObjectURL(e);
190
212
  },
191
213
  toggleToolCollapse: (e, t) => {
192
214
  l(e, (s) => ({
193
215
  ...s,
194
- blocks: s.blocks.map((o) => {
195
- if (o.type === "tool-call" && o.toolId === t) {
196
- const n = o.collapsed === void 0 ? !1 : !o.collapsed;
216
+ blocks: s.blocks.map((n) => {
217
+ if (n.type === "tool-call" && n.toolId === t) {
218
+ const a = n.collapsed === void 0 ? !1 : !n.collapsed;
197
219
  return {
198
- ...o,
199
- collapsed: n
220
+ ...n,
221
+ collapsed: a
200
222
  };
201
223
  }
202
- return o;
224
+ return n;
203
225
  })
204
226
  }));
205
227
  },
206
228
  approveToolCall: (e, t, s) => {
207
- l(e, (n) => ({
208
- ...n,
209
- blocks: n.blocks.map((a) => a.type !== "tool-call" || a.toolId !== t || a.requiresApproval !== !0 || a.approvalState !== "required" ? a : s ? {
210
- ...a,
229
+ l(e, (a) => ({
230
+ ...a,
231
+ blocks: a.blocks.map((r) => r.type !== "tool-call" || r.toolId !== t || r.requiresApproval !== !0 || r.approvalState !== "required" ? r : s ? {
232
+ ...r,
211
233
  approvalState: "approved",
212
234
  status: "running"
213
235
  } : {
214
- ...a,
236
+ ...r,
215
237
  approvalState: "rejected",
216
238
  status: "error",
217
- error: a.error || "Rejected by user"
239
+ error: r.error || "Rejected by user"
218
240
  })
219
241
  }));
220
- const o = r.callbacks?.onToolApproval;
221
- o && h(() => {
222
- Promise.resolve(o(e, t, s)).catch((n) => {
223
- console.error("Failed to approve tool call:", n);
242
+ const n = o.callbacks?.onToolApproval;
243
+ n && p(() => {
244
+ Promise.resolve(n(e, t, s)).catch((a) => {
245
+ console.error("Failed to approve tool call:", a);
224
246
  });
225
247
  });
226
248
  },
227
- heightCache: g,
249
+ heightCache: f,
228
250
  setMessageHeight: (e, t) => {
229
- g.set(e, t);
251
+ f.set(e, t);
230
252
  },
231
- getMessageHeight: (e) => g.get(e) || d().defaultItemHeight,
253
+ getMessageHeight: (e) => f.get(e) || d().defaultItemHeight,
232
254
  toggleChecklistItem: (e, t, s) => {
233
- let o = null;
234
- l(e, (a) => {
235
- const i = [...a.blocks], f = i[t];
236
- if (f && f.type === "checklist") {
237
- const q = f.items.map((p) => p.id === s ? (o = !p.checked, {
238
- ...p,
239
- checked: o
240
- }) : p);
241
- i[t] = {
242
- ...f,
243
- items: q
255
+ let n = null;
256
+ l(e, (r) => {
257
+ const m = [...r.blocks], i = m[t];
258
+ if (i && i.type === "checklist") {
259
+ const K = i.items.map((y) => y.id === s ? (n = !y.checked, {
260
+ ...y,
261
+ checked: n
262
+ }) : y);
263
+ m[t] = {
264
+ ...i,
265
+ items: K
244
266
  };
245
267
  }
246
268
  return {
247
- ...a,
248
- blocks: i
269
+ ...r,
270
+ blocks: m
249
271
  };
250
272
  });
251
- const n = r.callbacks?.onChecklistChange;
252
- !n || o === null || h(() => {
273
+ const a = o.callbacks?.onChecklistChange;
274
+ !a || n === null || p(() => {
253
275
  try {
254
- n(e, t, s, o);
255
- } catch (a) {
256
- console.error("Failed to handle checklist change:", a);
276
+ a(e, t, s, n);
277
+ } catch (r) {
278
+ console.error("Failed to handle checklist change:", r);
257
279
  }
258
280
  });
259
281
  }
260
282
  };
261
- return N(L.Provider, {
262
- value: j,
283
+ return X(F.Provider, {
284
+ value: J,
263
285
  get children() {
264
- return r.children;
286
+ return o.children;
265
287
  }
266
288
  });
267
289
  };
268
- function K(r) {
269
- switch (r) {
290
+ function ne(o) {
291
+ switch (o) {
270
292
  case "text":
271
293
  return {
272
294
  type: "text",
@@ -342,9 +364,9 @@ function K(r) {
342
364
  };
343
365
  }
344
366
  }
345
- function Q(r, k) {
367
+ function oe(o, S) {
346
368
  const d = [];
347
- for (const c of k)
369
+ for (const c of S)
348
370
  c.type === "image" ? d.push({
349
371
  type: "image",
350
372
  src: c.url || c.preview || "",
@@ -356,12 +378,12 @@ function Q(r, k) {
356
378
  mimeType: c.file.type,
357
379
  url: c.url
358
380
  });
359
- return r.trim() && d.push({
381
+ return o.trim() && d.push({
360
382
  type: "text",
361
- content: r.trim()
383
+ content: o.trim()
362
384
  }), d;
363
385
  }
364
386
  export {
365
- ge as ChatProvider,
366
- ue as useChatContext
387
+ Me as ChatProvider,
388
+ Ce as useChatContext
367
389
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floegence/floe-webapp-core",
3
- "version": "0.27.4",
3
+ "version": "0.27.5",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",