@superatomai/application-react 0.0.2 → 0.0.4
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.cjs +823 -197
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +210 -8
- package/dist/index.d.ts +210 -8
- package/dist/index.js +822 -199
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5454,34 +5454,34 @@ function subcontent(events, eventIndex) {
|
|
|
5454
5454
|
let stream;
|
|
5455
5455
|
let previous3;
|
|
5456
5456
|
let index2 = -1;
|
|
5457
|
-
let
|
|
5457
|
+
let current3 = token;
|
|
5458
5458
|
let adjust = 0;
|
|
5459
5459
|
let start2 = 0;
|
|
5460
5460
|
const breaks = [start2];
|
|
5461
|
-
while (
|
|
5462
|
-
while (events.get(++startPosition)[1] !==
|
|
5461
|
+
while (current3) {
|
|
5462
|
+
while (events.get(++startPosition)[1] !== current3) {
|
|
5463
5463
|
}
|
|
5464
5464
|
startPositions.push(startPosition);
|
|
5465
|
-
if (!
|
|
5466
|
-
stream = context.sliceStream(
|
|
5467
|
-
if (!
|
|
5465
|
+
if (!current3._tokenizer) {
|
|
5466
|
+
stream = context.sliceStream(current3);
|
|
5467
|
+
if (!current3.next) {
|
|
5468
5468
|
stream.push(null);
|
|
5469
5469
|
}
|
|
5470
5470
|
if (previous3) {
|
|
5471
|
-
tokenizer.defineSkip(
|
|
5471
|
+
tokenizer.defineSkip(current3.start);
|
|
5472
5472
|
}
|
|
5473
|
-
if (
|
|
5473
|
+
if (current3._isInFirstContentOfListItem) {
|
|
5474
5474
|
tokenizer._gfmTasklistFirstContentOfListItem = true;
|
|
5475
5475
|
}
|
|
5476
5476
|
tokenizer.write(stream);
|
|
5477
|
-
if (
|
|
5477
|
+
if (current3._isInFirstContentOfListItem) {
|
|
5478
5478
|
tokenizer._gfmTasklistFirstContentOfListItem = void 0;
|
|
5479
5479
|
}
|
|
5480
5480
|
}
|
|
5481
|
-
previous3 =
|
|
5482
|
-
|
|
5481
|
+
previous3 = current3;
|
|
5482
|
+
current3 = current3.next;
|
|
5483
5483
|
}
|
|
5484
|
-
|
|
5484
|
+
current3 = token;
|
|
5485
5485
|
while (++index2 < childEvents.length) {
|
|
5486
5486
|
if (
|
|
5487
5487
|
// Find a void token that includes a break.
|
|
@@ -5489,15 +5489,15 @@ function subcontent(events, eventIndex) {
|
|
|
5489
5489
|
) {
|
|
5490
5490
|
start2 = index2 + 1;
|
|
5491
5491
|
breaks.push(start2);
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5492
|
+
current3._tokenizer = void 0;
|
|
5493
|
+
current3.previous = void 0;
|
|
5494
|
+
current3 = current3.next;
|
|
5495
5495
|
}
|
|
5496
5496
|
}
|
|
5497
5497
|
tokenizer.events = [];
|
|
5498
|
-
if (
|
|
5499
|
-
|
|
5500
|
-
|
|
5498
|
+
if (current3) {
|
|
5499
|
+
current3._tokenizer = void 0;
|
|
5500
|
+
current3.previous = void 0;
|
|
5501
5501
|
} else {
|
|
5502
5502
|
breaks.pop();
|
|
5503
5503
|
}
|
|
@@ -13512,9 +13512,9 @@ function isAsciiAlphaNumeric(code4) {
|
|
|
13512
13512
|
function isEntityInAttributeInvalidEnd(code4) {
|
|
13513
13513
|
return code4 === CharCodes.EQUALS || isAsciiAlphaNumeric(code4);
|
|
13514
13514
|
}
|
|
13515
|
-
function determineBranch(decodeTree,
|
|
13516
|
-
const branchCount = (
|
|
13517
|
-
const jumpOffset =
|
|
13515
|
+
function determineBranch(decodeTree, current3, nodeIndex, char) {
|
|
13516
|
+
const branchCount = (current3 & BinTrieFlags.BRANCH_LENGTH) >> 7;
|
|
13517
|
+
const jumpOffset = current3 & BinTrieFlags.JUMP_TABLE;
|
|
13518
13518
|
if (branchCount === 0) {
|
|
13519
13519
|
return jumpOffset !== 0 && char === jumpOffset ? nodeIndex : -1;
|
|
13520
13520
|
}
|
|
@@ -13753,19 +13753,19 @@ var init_decode = __esm({
|
|
|
13753
13753
|
*/
|
|
13754
13754
|
stateNamedEntity(input, offset) {
|
|
13755
13755
|
const { decodeTree } = this;
|
|
13756
|
-
let
|
|
13757
|
-
let valueLength = (
|
|
13756
|
+
let current3 = decodeTree[this.treeIndex];
|
|
13757
|
+
let valueLength = (current3 & BinTrieFlags.VALUE_LENGTH) >> 14;
|
|
13758
13758
|
for (; offset < input.length; offset++, this.excess++) {
|
|
13759
13759
|
const char = input.charCodeAt(offset);
|
|
13760
|
-
this.treeIndex = determineBranch(decodeTree,
|
|
13760
|
+
this.treeIndex = determineBranch(decodeTree, current3, this.treeIndex + Math.max(1, valueLength), char);
|
|
13761
13761
|
if (this.treeIndex < 0) {
|
|
13762
13762
|
return this.result === 0 || // If we are parsing an attribute
|
|
13763
13763
|
this.decodeMode === DecodingMode.Attribute && // We shouldn't have consumed any characters after the entity,
|
|
13764
13764
|
(valueLength === 0 || // And there should be no invalid characters.
|
|
13765
13765
|
isEntityInAttributeInvalidEnd(char)) ? 0 : this.emitNotTerminatedNamedEntity();
|
|
13766
13766
|
}
|
|
13767
|
-
|
|
13768
|
-
valueLength = (
|
|
13767
|
+
current3 = decodeTree[this.treeIndex];
|
|
13768
|
+
valueLength = (current3 & BinTrieFlags.VALUE_LENGTH) >> 14;
|
|
13769
13769
|
if (valueLength !== 0) {
|
|
13770
13770
|
if (char === CharCodes.SEMI) {
|
|
13771
13771
|
return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
|
|
@@ -19821,8 +19821,8 @@ function startTagInForeignContent(p, token) {
|
|
|
19821
19821
|
popUntilHtmlOrIntegrationPoint(p);
|
|
19822
19822
|
p._startTagOutsideForeignContent(token);
|
|
19823
19823
|
} else {
|
|
19824
|
-
const
|
|
19825
|
-
const currentNs = p.treeAdapter.getNamespaceURI(
|
|
19824
|
+
const current3 = p._getAdjustedCurrentElement();
|
|
19825
|
+
const currentNs = p.treeAdapter.getNamespaceURI(current3);
|
|
19826
19826
|
if (currentNs === NS.MATHML) {
|
|
19827
19827
|
adjustTokenMathMLAttrs(token);
|
|
19828
19828
|
} else if (currentNs === NS.SVG) {
|
|
@@ -20010,21 +20010,21 @@ var init_parser = __esm({
|
|
|
20010
20010
|
}
|
|
20011
20011
|
(_b = (_a4 = this.treeAdapter).onItemPop) === null || _b === void 0 ? void 0 : _b.call(_a4, node2, this.openElements.current);
|
|
20012
20012
|
if (isTop) {
|
|
20013
|
-
let
|
|
20013
|
+
let current3;
|
|
20014
20014
|
let currentTagId;
|
|
20015
20015
|
if (this.openElements.stackTop === 0 && this.fragmentContext) {
|
|
20016
|
-
|
|
20016
|
+
current3 = this.fragmentContext;
|
|
20017
20017
|
currentTagId = this.fragmentContextID;
|
|
20018
20018
|
} else {
|
|
20019
|
-
({ current, currentTagId } = this.openElements);
|
|
20019
|
+
({ current: current3, currentTagId } = this.openElements);
|
|
20020
20020
|
}
|
|
20021
|
-
this._setContextModes(
|
|
20021
|
+
this._setContextModes(current3, currentTagId);
|
|
20022
20022
|
}
|
|
20023
20023
|
}
|
|
20024
|
-
_setContextModes(
|
|
20025
|
-
const isHTML =
|
|
20024
|
+
_setContextModes(current3, tid) {
|
|
20025
|
+
const isHTML = current3 === this.document || current3 && this.treeAdapter.getNamespaceURI(current3) === NS.HTML;
|
|
20026
20026
|
this.currentNotInHTML = !isHTML;
|
|
20027
|
-
this.tokenizer.inForeignNode = !isHTML &&
|
|
20027
|
+
this.tokenizer.inForeignNode = !isHTML && current3 !== void 0 && tid !== void 0 && !this._isIntegrationPoint(tid, current3);
|
|
20028
20028
|
}
|
|
20029
20029
|
/** @protected */
|
|
20030
20030
|
_switchToTextParsing(currentToken, nextTokenizerState) {
|
|
@@ -20222,22 +20222,22 @@ var init_parser = __esm({
|
|
|
20222
20222
|
shouldProcessStartTagTokenInForeignContent(token) {
|
|
20223
20223
|
if (!this.currentNotInHTML)
|
|
20224
20224
|
return false;
|
|
20225
|
-
let
|
|
20225
|
+
let current3;
|
|
20226
20226
|
let currentTagId;
|
|
20227
20227
|
if (this.openElements.stackTop === 0 && this.fragmentContext) {
|
|
20228
|
-
|
|
20228
|
+
current3 = this.fragmentContext;
|
|
20229
20229
|
currentTagId = this.fragmentContextID;
|
|
20230
20230
|
} else {
|
|
20231
|
-
({ current, currentTagId } = this.openElements);
|
|
20231
|
+
({ current: current3, currentTagId } = this.openElements);
|
|
20232
20232
|
}
|
|
20233
|
-
if (token.tagID === TAG_ID.SVG && this.treeAdapter.getTagName(
|
|
20233
|
+
if (token.tagID === TAG_ID.SVG && this.treeAdapter.getTagName(current3) === TAG_NAMES.ANNOTATION_XML && this.treeAdapter.getNamespaceURI(current3) === NS.MATHML) {
|
|
20234
20234
|
return false;
|
|
20235
20235
|
}
|
|
20236
20236
|
return (
|
|
20237
20237
|
// Check that `current` is not an integration point for HTML or MathML elements.
|
|
20238
20238
|
this.tokenizer.inForeignNode || // If it _is_ an integration point, then we might have to check that it is not an HTML
|
|
20239
20239
|
// integration point.
|
|
20240
|
-
(token.tagID === TAG_ID.MGLYPH || token.tagID === TAG_ID.MALIGNMARK) && currentTagId !== void 0 && !this._isIntegrationPoint(currentTagId,
|
|
20240
|
+
(token.tagID === TAG_ID.MGLYPH || token.tagID === TAG_ID.MALIGNMARK) && currentTagId !== void 0 && !this._isIntegrationPoint(currentTagId, current3, NS.HTML)
|
|
20241
20241
|
);
|
|
20242
20242
|
}
|
|
20243
20243
|
/** @protected */
|
|
@@ -21197,8 +21197,8 @@ function startTag(node2, state) {
|
|
|
21197
21197
|
const tagName = node2.tagName.toLowerCase();
|
|
21198
21198
|
if (state.parser.tokenizer.state === TokenizerMode.PLAINTEXT) return;
|
|
21199
21199
|
resetTokenizer(state, pointStart(node2));
|
|
21200
|
-
const
|
|
21201
|
-
let ns = "namespaceURI" in
|
|
21200
|
+
const current3 = state.parser.openElements.current;
|
|
21201
|
+
let ns = "namespaceURI" in current3 ? current3.namespaceURI : webNamespaces.html;
|
|
21202
21202
|
if (ns === webNamespaces.html && tagName === "svg") {
|
|
21203
21203
|
ns = webNamespaces.svg;
|
|
21204
21204
|
}
|
|
@@ -50467,11 +50467,13 @@ var init_Markdown = __esm({
|
|
|
50467
50467
|
// Suppress the default <pre> wrapper — code renderer owns the full block structure
|
|
50468
50468
|
pre: ({ node: _node, children }) => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children }),
|
|
50469
50469
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
50470
|
-
code: ({ node: _node,
|
|
50470
|
+
code: ({ node: _node, className, children, ...props }) => {
|
|
50471
50471
|
const langMatch = /language-(\w+)/.exec(className || "");
|
|
50472
50472
|
const language = langMatch ? langMatch[1] : "";
|
|
50473
|
-
|
|
50474
|
-
|
|
50473
|
+
const isBlock = Boolean(language) || String(children).includes("\n");
|
|
50474
|
+
const codeText2 = String(children).replace(/^\s*\n+/, "").replace(/\s+$/, "");
|
|
50475
|
+
if (isBlock) {
|
|
50476
|
+
return language ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sa-code-block not-prose my-4 rounded-lg overflow-hidden border border-base-300", children: [
|
|
50475
50477
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-neutral px-4 py-2 text-xs text-neutral-content font-mono", children: language }),
|
|
50476
50478
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
50477
50479
|
prism_default2,
|
|
@@ -50481,13 +50483,13 @@ var init_Markdown = __esm({
|
|
|
50481
50483
|
PreTag: "div",
|
|
50482
50484
|
className: "!my-0 !rounded-none text-sm",
|
|
50483
50485
|
customStyle: { margin: 0, borderRadius: 0, padding: "1rem" },
|
|
50484
|
-
codeTagProps: { style: { backgroundColor: "transparent", padding: 0, fontSize: "inherit"
|
|
50486
|
+
codeTagProps: { style: { backgroundColor: "transparent", padding: 0, fontSize: "inherit" } },
|
|
50485
50487
|
wrapLongLines: false,
|
|
50486
50488
|
...props,
|
|
50487
|
-
children:
|
|
50489
|
+
children: codeText2
|
|
50488
50490
|
}
|
|
50489
50491
|
) })
|
|
50490
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "not-prose my-4 rounded-lg overflow-hidden border border-base-300", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "bg-base-200 text-base-content p-4 overflow-x-auto text-sm font-mono whitespace-pre-wrap break-words", children: /* @__PURE__ */ jsxRuntime.jsx("code", { ...props, children }) }) });
|
|
50492
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sa-code-block not-prose my-4 rounded-lg overflow-hidden border border-base-300", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "bg-base-200 text-base-content p-4 overflow-x-auto text-sm font-mono whitespace-pre-wrap break-words", children: /* @__PURE__ */ jsxRuntime.jsx("code", { ...props, children: codeText2 }) }) });
|
|
50491
50493
|
}
|
|
50492
50494
|
return /* @__PURE__ */ jsxRuntime.jsx("code", { className: "bg-base-200 text-teal-700 px-1.5 py-0.5 rounded text-sm font-mono break-words", ...props, children });
|
|
50493
50495
|
},
|
|
@@ -66197,6 +66199,7 @@ __export(services_exports, {
|
|
|
66197
66199
|
deleteArtifact: () => deleteArtifact,
|
|
66198
66200
|
deleteBookmark: () => deleteBookmark,
|
|
66199
66201
|
deleteThread: () => deleteThread,
|
|
66202
|
+
deleteUserConversation: () => deleteUserConversation,
|
|
66200
66203
|
getActions: () => getActions,
|
|
66201
66204
|
getAllArtifacts: () => getAllArtifacts,
|
|
66202
66205
|
getAllBookmarks: () => getAllBookmarks,
|
|
@@ -66336,6 +66339,34 @@ function injectBundleStyles() {
|
|
|
66336
66339
|
daisyThemes.type = "text/css";
|
|
66337
66340
|
daisyThemes.href = "https://cdn.jsdelivr.net/npm/daisyui@5/themes.css";
|
|
66338
66341
|
document.head.appendChild(daisyThemes);
|
|
66342
|
+
const codeStyles = document.createElement("style");
|
|
66343
|
+
codeStyles.setAttribute("data-sa-code-styles", "true");
|
|
66344
|
+
codeStyles.textContent = `
|
|
66345
|
+
.sa-code-block, .sa-code-block * {
|
|
66346
|
+
text-decoration: none !important;
|
|
66347
|
+
text-shadow: none !important;
|
|
66348
|
+
border: 0;
|
|
66349
|
+
list-style: none;
|
|
66350
|
+
}
|
|
66351
|
+
.sa-code-block pre, .sa-code-block code, .sa-code-block span {
|
|
66352
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace !important;
|
|
66353
|
+
line-height: 1.5 !important;
|
|
66354
|
+
letter-spacing: normal !important;
|
|
66355
|
+
}
|
|
66356
|
+
.sa-code-block code { background: transparent !important; }
|
|
66357
|
+
|
|
66358
|
+
/* Tailwind v4 dropped the browser default of cursor:pointer on buttons, so
|
|
66359
|
+
anything clickable in our components would otherwise show an arrow. */
|
|
66360
|
+
.sa-ui button:not(:disabled),
|
|
66361
|
+
.sa-ui [role="button"]:not([aria-disabled="true"]),
|
|
66362
|
+
.sa-ui summary,
|
|
66363
|
+
.sa-ui label[for],
|
|
66364
|
+
.sa-ui select {
|
|
66365
|
+
cursor: pointer;
|
|
66366
|
+
}
|
|
66367
|
+
.sa-ui button:disabled { cursor: not-allowed; }
|
|
66368
|
+
`;
|
|
66369
|
+
document.head.appendChild(codeStyles);
|
|
66339
66370
|
}
|
|
66340
66371
|
async function requestBundle(client, options) {
|
|
66341
66372
|
injectBundleStyles();
|
|
@@ -67152,6 +67183,29 @@ async function deleteThread(client, userId, threadId, clearCache = true, timeout
|
|
|
67152
67183
|
};
|
|
67153
67184
|
}
|
|
67154
67185
|
}
|
|
67186
|
+
async function deleteUserConversation(client, userPrompt, userId, clearCache = true, timeout = 3e4) {
|
|
67187
|
+
try {
|
|
67188
|
+
const response = await client.requestData({
|
|
67189
|
+
collection: "user-conversations",
|
|
67190
|
+
operation: "deleteByUserPrompt",
|
|
67191
|
+
params: { userPrompt, userId, clearCache },
|
|
67192
|
+
timeout
|
|
67193
|
+
});
|
|
67194
|
+
if (response.error) {
|
|
67195
|
+
return { success: false, error: response.error };
|
|
67196
|
+
}
|
|
67197
|
+
const data = response.data;
|
|
67198
|
+
if (data?.success === false) {
|
|
67199
|
+
return { success: false, error: data.message || "Failed to delete the message" };
|
|
67200
|
+
}
|
|
67201
|
+
return { success: true, message: data?.message, queriesDeleted: data?.queriesDeleted };
|
|
67202
|
+
} catch (error51) {
|
|
67203
|
+
return {
|
|
67204
|
+
success: false,
|
|
67205
|
+
error: error51 instanceof Error ? error51.message : "Failed to delete the message"
|
|
67206
|
+
};
|
|
67207
|
+
}
|
|
67208
|
+
}
|
|
67155
67209
|
async function updateThreadTitle(client, userId, threadId, title, timeout = 15e3) {
|
|
67156
67210
|
try {
|
|
67157
67211
|
const response = await client.requestData({
|
|
@@ -67212,6 +67266,10 @@ var SuperatomClient = class {
|
|
|
67212
67266
|
this.errorHandlers = /* @__PURE__ */ new Set();
|
|
67213
67267
|
this.connectPromise = null;
|
|
67214
67268
|
this.connectResolve = null;
|
|
67269
|
+
// Supplies a valid session token before each (re)connect — see ClientConfig.getAccessToken.
|
|
67270
|
+
this.getAccessToken = null;
|
|
67271
|
+
// Waiting for getAccessToken; the socket does not exist yet.
|
|
67272
|
+
this.fetchingToken = false;
|
|
67215
67273
|
// Heartbeat — detects zombie sockets that readyState=OPEN can't catch.
|
|
67216
67274
|
this.heartbeatInterval = null;
|
|
67217
67275
|
this.pongDeadline = null;
|
|
@@ -67230,6 +67288,7 @@ var SuperatomClient = class {
|
|
|
67230
67288
|
this.boundHandlePageShow = null;
|
|
67231
67289
|
const parsed = ClientConfigSchema.parse(config2);
|
|
67232
67290
|
this.config = parsed;
|
|
67291
|
+
this.getAccessToken = config2.getAccessToken ?? null;
|
|
67233
67292
|
this.registerGlobals();
|
|
67234
67293
|
}
|
|
67235
67294
|
registerGlobals() {
|
|
@@ -67381,21 +67440,7 @@ var SuperatomClient = class {
|
|
|
67381
67440
|
* callbacks so the eventual real close doesn't double-fire everything.
|
|
67382
67441
|
*/
|
|
67383
67442
|
markAsDead(reasonMessage) {
|
|
67384
|
-
|
|
67385
|
-
const dying = this.socket;
|
|
67386
|
-
this.socket = null;
|
|
67387
|
-
try {
|
|
67388
|
-
dying.onopen = null;
|
|
67389
|
-
dying.onmessage = null;
|
|
67390
|
-
dying.onerror = null;
|
|
67391
|
-
dying.onclose = null;
|
|
67392
|
-
if (dying.readyState === WebSocket.OPEN || dying.readyState === WebSocket.CONNECTING) {
|
|
67393
|
-
dying.close();
|
|
67394
|
-
}
|
|
67395
|
-
} catch (err) {
|
|
67396
|
-
this.log("error", "Failed to detach dying socket:", err);
|
|
67397
|
-
}
|
|
67398
|
-
}
|
|
67443
|
+
this.discardSocket();
|
|
67399
67444
|
this.stopHeartbeat();
|
|
67400
67445
|
this.failPendingRequests(new Error(reasonMessage));
|
|
67401
67446
|
this.disconnectionHandlers.forEach((handler) => handler());
|
|
@@ -67412,21 +67457,39 @@ var SuperatomClient = class {
|
|
|
67412
67457
|
this.cancelReconnectTimer();
|
|
67413
67458
|
this.reconnectAttempts = 0;
|
|
67414
67459
|
this.shouldReconnect = true;
|
|
67415
|
-
|
|
67416
|
-
try {
|
|
67417
|
-
const old = this.socket;
|
|
67418
|
-
this.socket = null;
|
|
67419
|
-
if (old.readyState === WebSocket.OPEN || old.readyState === WebSocket.CONNECTING) {
|
|
67420
|
-
old.close();
|
|
67421
|
-
}
|
|
67422
|
-
} catch (err) {
|
|
67423
|
-
this.log("error", "Failed to close old socket during forceReconnect:", err);
|
|
67424
|
-
}
|
|
67425
|
-
}
|
|
67460
|
+
const wasOpen = this.discardSocket();
|
|
67426
67461
|
this.stopHeartbeat();
|
|
67427
67462
|
this.failPendingRequests(new Error("Connection reset"));
|
|
67463
|
+
if (wasOpen) this.disconnectionHandlers.forEach((handler) => handler());
|
|
67428
67464
|
return this.connect();
|
|
67429
67465
|
}
|
|
67466
|
+
/**
|
|
67467
|
+
* Drop the current socket without triggering its handlers: they are detached
|
|
67468
|
+
* first, so its eventual real close is a no-op (on Linux/Chrome that close
|
|
67469
|
+
* can arrive 30-60s later). Returns whether it was open.
|
|
67470
|
+
*/
|
|
67471
|
+
discardSocket() {
|
|
67472
|
+
const old = this.socket;
|
|
67473
|
+
if (!old) return false;
|
|
67474
|
+
this.socket = null;
|
|
67475
|
+
const wasOpen = old.readyState === WebSocket.OPEN;
|
|
67476
|
+
try {
|
|
67477
|
+
old.onopen = null;
|
|
67478
|
+
old.onmessage = null;
|
|
67479
|
+
old.onerror = null;
|
|
67480
|
+
old.onclose = null;
|
|
67481
|
+
if (wasOpen || old.readyState === WebSocket.CONNECTING) {
|
|
67482
|
+
old.close();
|
|
67483
|
+
}
|
|
67484
|
+
} catch (err) {
|
|
67485
|
+
this.log("error", "Failed to detach old socket:", err);
|
|
67486
|
+
}
|
|
67487
|
+
return wasOpen;
|
|
67488
|
+
}
|
|
67489
|
+
/** A connection attempt is under way — fetching the session token, or the socket handshake. */
|
|
67490
|
+
isConnecting() {
|
|
67491
|
+
return this.fetchingToken || this.socket?.readyState === WebSocket.CONNECTING;
|
|
67492
|
+
}
|
|
67430
67493
|
/**
|
|
67431
67494
|
* Attach window-level listeners that catch network changes faster than
|
|
67432
67495
|
* the socket's own onclose. The browser's onclose for a half-open TCP can
|
|
@@ -67448,15 +67511,18 @@ var SuperatomClient = class {
|
|
|
67448
67511
|
this.boundHandleVisibilityChange = () => {
|
|
67449
67512
|
if (typeof document === "undefined") return;
|
|
67450
67513
|
if (document.visibilityState !== "visible") return;
|
|
67451
|
-
if (
|
|
67514
|
+
if (this.socket?.readyState === WebSocket.OPEN) {
|
|
67515
|
+
this.sendHeartbeatProbe();
|
|
67516
|
+
} else if (this.isConnecting()) {
|
|
67517
|
+
return;
|
|
67518
|
+
} else if (this.shouldReconnect) {
|
|
67452
67519
|
this.forceReconnect().catch((err) => {
|
|
67453
67520
|
this.log("error", "forceReconnect from visibility failed:", err);
|
|
67454
67521
|
});
|
|
67455
|
-
} else {
|
|
67456
|
-
this.sendHeartbeatProbe();
|
|
67457
67522
|
}
|
|
67458
67523
|
};
|
|
67459
|
-
this.boundHandlePageShow = (() => {
|
|
67524
|
+
this.boundHandlePageShow = ((event) => {
|
|
67525
|
+
if (!event.persisted) return;
|
|
67460
67526
|
this.forceReconnect().catch((err) => {
|
|
67461
67527
|
this.log("error", "forceReconnect from pageshow failed:", err);
|
|
67462
67528
|
});
|
|
@@ -67571,13 +67637,50 @@ var SuperatomClient = class {
|
|
|
67571
67637
|
this.log("warn", "Already connected");
|
|
67572
67638
|
return Promise.resolve();
|
|
67573
67639
|
}
|
|
67574
|
-
if (this.socket?.readyState === WebSocket.CONNECTING && this.connectPromise) {
|
|
67640
|
+
if ((this.socket?.readyState === WebSocket.CONNECTING || this.fetchingToken) && this.connectPromise) {
|
|
67575
67641
|
this.log("warn", "Connection already in progress");
|
|
67576
67642
|
return this.connectPromise;
|
|
67577
67643
|
}
|
|
67578
67644
|
this.connectPromise = new Promise((resolve) => {
|
|
67579
67645
|
this.connectResolve = resolve;
|
|
67580
67646
|
});
|
|
67647
|
+
if (this.getAccessToken) {
|
|
67648
|
+
void this.openWithFreshToken();
|
|
67649
|
+
} else {
|
|
67650
|
+
this.openSocket();
|
|
67651
|
+
}
|
|
67652
|
+
return this.connectPromise;
|
|
67653
|
+
}
|
|
67654
|
+
/**
|
|
67655
|
+
* Get a valid session token, then open the socket. The relay checks the token
|
|
67656
|
+
* only at handshake, so every (re)connect must present one that is still valid.
|
|
67657
|
+
*
|
|
67658
|
+
* A fatal auth failure (see SuperAtomAuthError.fatal) stops reconnecting — the
|
|
67659
|
+
* session reports it to the host, and retrying would only repeat it. Anything
|
|
67660
|
+
* else goes through the normal back-off.
|
|
67661
|
+
*/
|
|
67662
|
+
async openWithFreshToken() {
|
|
67663
|
+
this.fetchingToken = true;
|
|
67664
|
+
try {
|
|
67665
|
+
this.config.token = await this.getAccessToken();
|
|
67666
|
+
} catch (error51) {
|
|
67667
|
+
this.fetchingToken = false;
|
|
67668
|
+
const err = error51 instanceof Error ? error51 : new Error("Could not get a session token");
|
|
67669
|
+
this.errorHandlers.forEach((handler) => handler(err));
|
|
67670
|
+
if (error51?.fatal) {
|
|
67671
|
+
this.log("error", "Sign-in failed; not reconnecting:", err.message);
|
|
67672
|
+
this.shouldReconnect = false;
|
|
67673
|
+
this.cancelReconnectTimer();
|
|
67674
|
+
} else {
|
|
67675
|
+
this.scheduleReconnect();
|
|
67676
|
+
}
|
|
67677
|
+
return;
|
|
67678
|
+
}
|
|
67679
|
+
this.fetchingToken = false;
|
|
67680
|
+
if (!this.shouldReconnect) return;
|
|
67681
|
+
this.openSocket();
|
|
67682
|
+
}
|
|
67683
|
+
openSocket() {
|
|
67581
67684
|
try {
|
|
67582
67685
|
this.socket = new WebSocket(this.getWebSocketUrl());
|
|
67583
67686
|
this.setupSocketHandlers();
|
|
@@ -67588,7 +67691,6 @@ var SuperatomClient = class {
|
|
|
67588
67691
|
this.errorHandlers.forEach((handler) => handler(err));
|
|
67589
67692
|
this.scheduleReconnect();
|
|
67590
67693
|
}
|
|
67591
|
-
return this.connectPromise;
|
|
67592
67694
|
}
|
|
67593
67695
|
/**
|
|
67594
67696
|
* Disconnect from WebSocket server
|
|
@@ -67612,6 +67714,7 @@ var SuperatomClient = class {
|
|
|
67612
67714
|
const merged = { ...this.config, ...config2 };
|
|
67613
67715
|
const parsed = ClientConfigSchema.parse(merged);
|
|
67614
67716
|
this.config = parsed;
|
|
67717
|
+
if ("getAccessToken" in config2) this.getAccessToken = config2.getAccessToken ?? null;
|
|
67615
67718
|
}
|
|
67616
67719
|
/**
|
|
67617
67720
|
* Reconnect with new configuration
|
|
@@ -68038,6 +68141,197 @@ var SuperatomClient = class {
|
|
|
68038
68141
|
}
|
|
68039
68142
|
};
|
|
68040
68143
|
|
|
68144
|
+
// src/auth.ts
|
|
68145
|
+
var DEFAULT_API_URL = "https://sa-api.superatom.ai";
|
|
68146
|
+
var SuperAtomAuthError = class extends Error {
|
|
68147
|
+
constructor(code4, message, options) {
|
|
68148
|
+
super(message);
|
|
68149
|
+
this.name = "SuperAtomAuthError";
|
|
68150
|
+
this.code = code4;
|
|
68151
|
+
this.reason = options.reason;
|
|
68152
|
+
this.status = options.status;
|
|
68153
|
+
this.fatal = options.fatal;
|
|
68154
|
+
if (options.cause !== void 0) this.cause = options.cause;
|
|
68155
|
+
}
|
|
68156
|
+
};
|
|
68157
|
+
var MIN_REMAINING_MS = 6e4;
|
|
68158
|
+
var RENEW_AHEAD_MS = 12e4;
|
|
68159
|
+
var RENEW_RETRY_MS = 3e4;
|
|
68160
|
+
var RETRIES_BEFORE_REPORTING = 2;
|
|
68161
|
+
var EXCHANGE_TIMEOUT_MS = 15e3;
|
|
68162
|
+
function expiryOf(token) {
|
|
68163
|
+
try {
|
|
68164
|
+
const payload = token.split(".")[1];
|
|
68165
|
+
if (!payload) return null;
|
|
68166
|
+
const json3 = JSON.parse(atob(payload.replace(/-/g, "+").replace(/_/g, "/")));
|
|
68167
|
+
return typeof json3.exp === "number" ? json3.exp * 1e3 : null;
|
|
68168
|
+
} catch {
|
|
68169
|
+
return null;
|
|
68170
|
+
}
|
|
68171
|
+
}
|
|
68172
|
+
var SdkSession = class {
|
|
68173
|
+
constructor(opts) {
|
|
68174
|
+
this.token = null;
|
|
68175
|
+
this.expiresAt = 0;
|
|
68176
|
+
this.currentUser = null;
|
|
68177
|
+
/** The one renewal in flight — every caller shares it. */
|
|
68178
|
+
this.inFlight = null;
|
|
68179
|
+
this.fatalError = null;
|
|
68180
|
+
/** Retryable failures in a row; reset by a successful exchange. */
|
|
68181
|
+
this.retries = 0;
|
|
68182
|
+
this.renewTimer = null;
|
|
68183
|
+
this.stopped = false;
|
|
68184
|
+
this.opts = opts;
|
|
68185
|
+
this.apiUrl = (opts.apiUrl || DEFAULT_API_URL).replace(/\/+$/, "");
|
|
68186
|
+
}
|
|
68187
|
+
get user() {
|
|
68188
|
+
return this.currentUser;
|
|
68189
|
+
}
|
|
68190
|
+
/** The fatal error that stopped the session, if any. */
|
|
68191
|
+
get error() {
|
|
68192
|
+
return this.fatalError;
|
|
68193
|
+
}
|
|
68194
|
+
/**
|
|
68195
|
+
* A token with at least a minute left — the cached one, or a fresh exchange.
|
|
68196
|
+
* Rejects with SuperAtomAuthError.
|
|
68197
|
+
*/
|
|
68198
|
+
getAccessToken() {
|
|
68199
|
+
if (this.fatalError) return Promise.reject(this.fatalError);
|
|
68200
|
+
if (this.token && this.expiresAt - Date.now() > MIN_REMAINING_MS) {
|
|
68201
|
+
return Promise.resolve(this.token);
|
|
68202
|
+
}
|
|
68203
|
+
return this.renew();
|
|
68204
|
+
}
|
|
68205
|
+
/** Clear a fatal error so the next getAccessToken() tries again (e.g. after the user signs in again). */
|
|
68206
|
+
reset() {
|
|
68207
|
+
this.fatalError = null;
|
|
68208
|
+
this.stopped = false;
|
|
68209
|
+
}
|
|
68210
|
+
/** Stop renewing — the host unmounted or disconnected. */
|
|
68211
|
+
stop() {
|
|
68212
|
+
this.stopped = true;
|
|
68213
|
+
this.clearRenewTimer();
|
|
68214
|
+
}
|
|
68215
|
+
renew() {
|
|
68216
|
+
if (!this.inFlight) {
|
|
68217
|
+
this.opts.onSigningIn?.(true);
|
|
68218
|
+
this.inFlight = this.exchange().finally(() => {
|
|
68219
|
+
this.inFlight = null;
|
|
68220
|
+
this.opts.onSigningIn?.(false);
|
|
68221
|
+
});
|
|
68222
|
+
}
|
|
68223
|
+
return this.inFlight;
|
|
68224
|
+
}
|
|
68225
|
+
async exchange() {
|
|
68226
|
+
let customerToken;
|
|
68227
|
+
try {
|
|
68228
|
+
customerToken = await this.opts.getToken();
|
|
68229
|
+
} catch (err) {
|
|
68230
|
+
throw this.fail(new SuperAtomAuthError("get_token_failed", "getToken() failed", { fatal: true, cause: err }));
|
|
68231
|
+
}
|
|
68232
|
+
if (typeof customerToken !== "string" || !customerToken.trim()) {
|
|
68233
|
+
throw this.fail(new SuperAtomAuthError("get_token_failed", "getToken() returned no token", { fatal: true }));
|
|
68234
|
+
}
|
|
68235
|
+
const controller = new AbortController();
|
|
68236
|
+
const timeout = setTimeout(() => controller.abort(), EXCHANGE_TIMEOUT_MS);
|
|
68237
|
+
let res;
|
|
68238
|
+
try {
|
|
68239
|
+
res = await fetch(`${this.apiUrl}/auth/sdk/exchange`, {
|
|
68240
|
+
method: "POST",
|
|
68241
|
+
headers: { "Content-Type": "application/json" },
|
|
68242
|
+
body: JSON.stringify({ projectId: this.opts.projectId, token: customerToken.trim() }),
|
|
68243
|
+
signal: controller.signal
|
|
68244
|
+
});
|
|
68245
|
+
} catch (err) {
|
|
68246
|
+
throw this.fail(new SuperAtomAuthError("network", "Could not reach Superatom to sign in", { fatal: false, cause: err }));
|
|
68247
|
+
} finally {
|
|
68248
|
+
clearTimeout(timeout);
|
|
68249
|
+
}
|
|
68250
|
+
const body = await res.json().catch(() => ({}));
|
|
68251
|
+
if (!res.ok) {
|
|
68252
|
+
const message = typeof body?.error === "string" ? body.error : `Sign-in failed (${res.status})`;
|
|
68253
|
+
const fatal = res.status >= 400 && res.status < 500 && res.status !== 429;
|
|
68254
|
+
throw this.fail(
|
|
68255
|
+
new SuperAtomAuthError(fatal ? "exchange_rejected" : "exchange_unavailable", message, {
|
|
68256
|
+
status: res.status,
|
|
68257
|
+
reason: typeof body?.code === "string" ? body.code : void 0,
|
|
68258
|
+
fatal
|
|
68259
|
+
})
|
|
68260
|
+
);
|
|
68261
|
+
}
|
|
68262
|
+
if (typeof body?.token !== "string" || !body.user?.id) {
|
|
68263
|
+
throw this.fail(
|
|
68264
|
+
new SuperAtomAuthError("exchange_unavailable", "Unexpected sign-in response", { status: res.status, fatal: false })
|
|
68265
|
+
);
|
|
68266
|
+
}
|
|
68267
|
+
if (Array.isArray(body.warnings)) {
|
|
68268
|
+
for (const w of body.warnings) console.warn("[SuperAtom] Sign-in warning:", w);
|
|
68269
|
+
}
|
|
68270
|
+
this.token = body.token;
|
|
68271
|
+
this.expiresAt = expiryOf(body.token) ?? Date.now() + 15 * 6e4;
|
|
68272
|
+
this.currentUser = {
|
|
68273
|
+
id: body.user.id,
|
|
68274
|
+
email: body.user.email,
|
|
68275
|
+
name: body.user.name,
|
|
68276
|
+
role: body.user.role,
|
|
68277
|
+
externalRoles: Array.isArray(body.user.externalRoles) ? body.user.externalRoles : []
|
|
68278
|
+
};
|
|
68279
|
+
this.log(`Signed in as ${this.currentUser.email}; token valid until ${new Date(this.expiresAt).toISOString()}`);
|
|
68280
|
+
if (this.retries) {
|
|
68281
|
+
this.retries = 0;
|
|
68282
|
+
this.opts.onRetrying?.(null);
|
|
68283
|
+
}
|
|
68284
|
+
this.opts.onSession?.(this.currentUser);
|
|
68285
|
+
this.scheduleRenew(this.expiresAt - RENEW_AHEAD_MS - Date.now());
|
|
68286
|
+
return body.token;
|
|
68287
|
+
}
|
|
68288
|
+
/** Record a failure: a fatal one stops the session and is reported once. */
|
|
68289
|
+
fail(error51) {
|
|
68290
|
+
if (error51.fatal) {
|
|
68291
|
+
this.fatalError = error51;
|
|
68292
|
+
this.clearRenewTimer();
|
|
68293
|
+
console.error(`[SuperAtom] Sign-in failed: ${error51.message}`, error51);
|
|
68294
|
+
try {
|
|
68295
|
+
this.opts.onAuthError?.(error51);
|
|
68296
|
+
} catch (err) {
|
|
68297
|
+
console.error("[SuperAtom] onAuthError threw:", err);
|
|
68298
|
+
}
|
|
68299
|
+
} else {
|
|
68300
|
+
this.retries++;
|
|
68301
|
+
if (this.retries === RETRIES_BEFORE_REPORTING) {
|
|
68302
|
+
console.warn(`[SuperAtom] ${error51.message} (${this.apiUrl}) \u2014 retrying`);
|
|
68303
|
+
}
|
|
68304
|
+
if (this.retries >= RETRIES_BEFORE_REPORTING) this.opts.onRetrying?.(error51);
|
|
68305
|
+
this.log(`Sign-in attempt failed, will retry: ${error51.message}`);
|
|
68306
|
+
this.scheduleRenew(RENEW_RETRY_MS);
|
|
68307
|
+
}
|
|
68308
|
+
return error51;
|
|
68309
|
+
}
|
|
68310
|
+
/**
|
|
68311
|
+
* Renew in the background ahead of expiry. Timers are paused while the machine
|
|
68312
|
+
* sleeps and fire on wake; a reconnect after wake also renews first if needed.
|
|
68313
|
+
*/
|
|
68314
|
+
scheduleRenew(inMs) {
|
|
68315
|
+
this.clearRenewTimer();
|
|
68316
|
+
if (this.stopped || this.fatalError) return;
|
|
68317
|
+
this.renewTimer = setTimeout(() => {
|
|
68318
|
+
this.renewTimer = null;
|
|
68319
|
+
if (this.stopped || this.fatalError) return;
|
|
68320
|
+
this.renew().catch(() => {
|
|
68321
|
+
});
|
|
68322
|
+
}, Math.max(inMs, 5e3));
|
|
68323
|
+
}
|
|
68324
|
+
clearRenewTimer() {
|
|
68325
|
+
if (this.renewTimer) {
|
|
68326
|
+
clearTimeout(this.renewTimer);
|
|
68327
|
+
this.renewTimer = null;
|
|
68328
|
+
}
|
|
68329
|
+
}
|
|
68330
|
+
log(message) {
|
|
68331
|
+
if (this.opts.debug) console.log(`[SuperAtom] ${message}`);
|
|
68332
|
+
}
|
|
68333
|
+
};
|
|
68334
|
+
|
|
68041
68335
|
// src/setup.ts
|
|
68042
68336
|
function setup(components) {
|
|
68043
68337
|
if (typeof window === "undefined") {
|
|
@@ -68674,13 +68968,13 @@ var ExpressionEvaluator = class {
|
|
|
68674
68968
|
resolveDataPath(path2, data) {
|
|
68675
68969
|
if (!path2 || !data) return void 0;
|
|
68676
68970
|
try {
|
|
68677
|
-
return path2.split(".").reduce((
|
|
68678
|
-
if (
|
|
68971
|
+
return path2.split(".").reduce((current3, key) => {
|
|
68972
|
+
if (current3 === null || current3 === void 0) return void 0;
|
|
68679
68973
|
if (!isNaN(Number(key))) {
|
|
68680
68974
|
const index2 = parseInt(key, 10);
|
|
68681
|
-
return Array.isArray(
|
|
68975
|
+
return Array.isArray(current3) ? current3[index2] : current3;
|
|
68682
68976
|
}
|
|
68683
|
-
return
|
|
68977
|
+
return current3[key];
|
|
68684
68978
|
}, data);
|
|
68685
68979
|
} catch (error51) {
|
|
68686
68980
|
console.warn("Error resolving data path:", path2, error51);
|
|
@@ -69159,6 +69453,125 @@ function resetRegistration() {
|
|
|
69159
69453
|
registeredKeys.forEach((key) => delete COMP_REGISTRY[key]);
|
|
69160
69454
|
registeredKeys.clear();
|
|
69161
69455
|
}
|
|
69456
|
+
var current = null;
|
|
69457
|
+
var retrying = null;
|
|
69458
|
+
var signingIn = false;
|
|
69459
|
+
var chatReady = false;
|
|
69460
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
69461
|
+
function setAuthStatus(error51) {
|
|
69462
|
+
if (current === error51) return;
|
|
69463
|
+
current = error51;
|
|
69464
|
+
if (error51) retrying = null;
|
|
69465
|
+
listeners.forEach((l) => l());
|
|
69466
|
+
}
|
|
69467
|
+
function setRetryingStatus(error51) {
|
|
69468
|
+
if (retrying === error51) return;
|
|
69469
|
+
retrying = error51;
|
|
69470
|
+
listeners.forEach((l) => l());
|
|
69471
|
+
}
|
|
69472
|
+
function setSigningIn(value) {
|
|
69473
|
+
if (signingIn === value) return;
|
|
69474
|
+
signingIn = value;
|
|
69475
|
+
listeners.forEach((l) => l());
|
|
69476
|
+
}
|
|
69477
|
+
function useSigningIn() {
|
|
69478
|
+
return React6.useSyncExternalStore(
|
|
69479
|
+
(l) => {
|
|
69480
|
+
listeners.add(l);
|
|
69481
|
+
return () => listeners.delete(l);
|
|
69482
|
+
},
|
|
69483
|
+
() => signingIn,
|
|
69484
|
+
() => false
|
|
69485
|
+
);
|
|
69486
|
+
}
|
|
69487
|
+
function setChatReady(value) {
|
|
69488
|
+
if (chatReady === value) return;
|
|
69489
|
+
chatReady = value;
|
|
69490
|
+
listeners.forEach((l) => l());
|
|
69491
|
+
}
|
|
69492
|
+
function useStartingUp() {
|
|
69493
|
+
return React6.useSyncExternalStore(
|
|
69494
|
+
(l) => {
|
|
69495
|
+
listeners.add(l);
|
|
69496
|
+
return () => listeners.delete(l);
|
|
69497
|
+
},
|
|
69498
|
+
() => !chatReady,
|
|
69499
|
+
() => false
|
|
69500
|
+
);
|
|
69501
|
+
}
|
|
69502
|
+
function useRetryingStatus() {
|
|
69503
|
+
return React6.useSyncExternalStore(
|
|
69504
|
+
(l) => {
|
|
69505
|
+
listeners.add(l);
|
|
69506
|
+
return () => listeners.delete(l);
|
|
69507
|
+
},
|
|
69508
|
+
() => retrying,
|
|
69509
|
+
() => null
|
|
69510
|
+
);
|
|
69511
|
+
}
|
|
69512
|
+
function useAuthStatus() {
|
|
69513
|
+
return React6.useSyncExternalStore(
|
|
69514
|
+
(l) => {
|
|
69515
|
+
listeners.add(l);
|
|
69516
|
+
return () => listeners.delete(l);
|
|
69517
|
+
},
|
|
69518
|
+
() => current,
|
|
69519
|
+
() => null
|
|
69520
|
+
);
|
|
69521
|
+
}
|
|
69522
|
+
var SETUP_REASONS = /* @__PURE__ */ new Set([
|
|
69523
|
+
"bad_request",
|
|
69524
|
+
"bad_project_id",
|
|
69525
|
+
"unknown_project",
|
|
69526
|
+
"bad_sub",
|
|
69527
|
+
"bad_email",
|
|
69528
|
+
"bad_roles",
|
|
69529
|
+
"bad_access",
|
|
69530
|
+
"bad_access_values",
|
|
69531
|
+
"bad_access_filters",
|
|
69532
|
+
"access_not_set_up",
|
|
69533
|
+
"lifetime_too_long",
|
|
69534
|
+
"issued_in_future",
|
|
69535
|
+
"email_linked_elsewhere"
|
|
69536
|
+
]);
|
|
69537
|
+
function authStatusMessage(error51) {
|
|
69538
|
+
switch (error51.code) {
|
|
69539
|
+
case "get_token_failed":
|
|
69540
|
+
return "Your session has ended. Please sign in again to continue.";
|
|
69541
|
+
case "exchange_rejected":
|
|
69542
|
+
if (error51.reason === "inactive") return "This account has been deactivated.";
|
|
69543
|
+
if (error51.reason === "sdk_not_enabled" || error51.status === 403) {
|
|
69544
|
+
return "This account cannot use the chat. Please contact your administrator.";
|
|
69545
|
+
}
|
|
69546
|
+
if (error51.reason && SETUP_REASONS.has(error51.reason)) {
|
|
69547
|
+
return `This app\u2019s Superatom sign-in is not set up correctly: ${error51.message}`;
|
|
69548
|
+
}
|
|
69549
|
+
return "Your session is no longer valid. Please sign in again to continue.";
|
|
69550
|
+
default:
|
|
69551
|
+
return "Could not connect to Superatom. Please try again in a moment.";
|
|
69552
|
+
}
|
|
69553
|
+
}
|
|
69554
|
+
function retryingStatusMessage(error51) {
|
|
69555
|
+
return error51.code === "network" ? "Cannot reach Superatom \u2014 retrying\u2026" : "Superatom is not responding \u2014 retrying\u2026";
|
|
69556
|
+
}
|
|
69557
|
+
var current2 = {};
|
|
69558
|
+
var listeners2 = /* @__PURE__ */ new Set();
|
|
69559
|
+
function setMessageActions(actions) {
|
|
69560
|
+
current2 = actions;
|
|
69561
|
+
listeners2.forEach((l) => l());
|
|
69562
|
+
}
|
|
69563
|
+
function useMessageActions() {
|
|
69564
|
+
return React6.useSyncExternalStore(
|
|
69565
|
+
(l) => {
|
|
69566
|
+
listeners2.add(l);
|
|
69567
|
+
return () => listeners2.delete(l);
|
|
69568
|
+
},
|
|
69569
|
+
() => current2,
|
|
69570
|
+
() => current2
|
|
69571
|
+
);
|
|
69572
|
+
}
|
|
69573
|
+
|
|
69574
|
+
// src/ui/hooks/useSuperAtom.ts
|
|
69162
69575
|
function newThreadId() {
|
|
69163
69576
|
return `thread_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
69164
69577
|
}
|
|
@@ -69318,17 +69731,41 @@ function buildResponseIssueSchema(response, messageId) {
|
|
|
69318
69731
|
var MAX_ABORTED_TRACKED = 100;
|
|
69319
69732
|
var THREADS_LIMIT = 50;
|
|
69320
69733
|
var THREAD_MESSAGES_LIMIT = 50;
|
|
69321
|
-
function useSuperAtom({
|
|
69322
|
-
|
|
69734
|
+
function useSuperAtom({
|
|
69735
|
+
token,
|
|
69736
|
+
userId,
|
|
69737
|
+
projectId,
|
|
69738
|
+
getToken,
|
|
69739
|
+
onAuthError,
|
|
69740
|
+
apiUrl,
|
|
69741
|
+
wsUrl,
|
|
69742
|
+
debug = false,
|
|
69743
|
+
streaming = false
|
|
69744
|
+
}) {
|
|
69745
|
+
const sdkSignIn = !!getToken;
|
|
69746
|
+
if (sdkSignIn && token) throw new Error("[SuperAtom] Pass either token or getToken, not both");
|
|
69747
|
+
const [user, setUser] = React6.useState(null);
|
|
69748
|
+
const [authError, setAuthError] = React6.useState(null);
|
|
69749
|
+
const [isSigningIn, setIsSigningIn] = React6.useState(false);
|
|
69750
|
+
const [signInAttempt, setSignInAttempt] = React6.useState(0);
|
|
69751
|
+
const directUserId = (() => {
|
|
69752
|
+
if (sdkSignIn) return void 0;
|
|
69323
69753
|
if (token) {
|
|
69324
69754
|
const payload = decodeJWT(token);
|
|
69325
69755
|
const id = payload.sub ?? payload.userId;
|
|
69326
69756
|
if (!id) throw new Error("[SuperAtom] JWT decoded but no userId or sub field found in payload");
|
|
69327
69757
|
return id;
|
|
69328
69758
|
}
|
|
69329
|
-
if (!userId) throw new Error("[SuperAtom] Either token or userId must be provided");
|
|
69759
|
+
if (!userId) throw new Error("[SuperAtom] Either token, getToken or userId must be provided");
|
|
69330
69760
|
return userId;
|
|
69331
69761
|
})();
|
|
69762
|
+
const resolvedUserId = directUserId ?? user?.id ?? "";
|
|
69763
|
+
const getTokenRef = React6.useRef(getToken);
|
|
69764
|
+
getTokenRef.current = getToken;
|
|
69765
|
+
const onAuthErrorRef = React6.useRef(onAuthError);
|
|
69766
|
+
onAuthErrorRef.current = onAuthError;
|
|
69767
|
+
const sessionRef = React6.useRef(null);
|
|
69768
|
+
const setupDoneRef = React6.useRef(false);
|
|
69332
69769
|
const clientRef = React6.useRef(null);
|
|
69333
69770
|
const tokenRef = React6.useRef(token);
|
|
69334
69771
|
tokenRef.current = token;
|
|
@@ -69355,7 +69792,60 @@ function useSuperAtom({ token, userId, projectId, debug = false, streaming = fal
|
|
|
69355
69792
|
injectBundleStyles();
|
|
69356
69793
|
const timeoutId = setTimeout(async () => {
|
|
69357
69794
|
if (cancelled) return;
|
|
69358
|
-
|
|
69795
|
+
let clientUserId = directUserId;
|
|
69796
|
+
let session = null;
|
|
69797
|
+
if (sdkSignIn) {
|
|
69798
|
+
session = new SdkSession({
|
|
69799
|
+
projectId,
|
|
69800
|
+
apiUrl,
|
|
69801
|
+
debug,
|
|
69802
|
+
getToken: () => getTokenRef.current(),
|
|
69803
|
+
onAuthError: (err) => {
|
|
69804
|
+
setAuthError(err);
|
|
69805
|
+
setAuthStatus(err);
|
|
69806
|
+
onAuthErrorRef.current?.(err);
|
|
69807
|
+
},
|
|
69808
|
+
onSession: (u) => {
|
|
69809
|
+
setAuthError(null);
|
|
69810
|
+
setAuthStatus(null);
|
|
69811
|
+
setUser(u);
|
|
69812
|
+
},
|
|
69813
|
+
// Superatom unreachable or down, after a couple of tries: say so in the
|
|
69814
|
+
// chat instead of sitting on "Connecting…".
|
|
69815
|
+
onRetrying: (err) => setRetryingStatus(err),
|
|
69816
|
+
// Lets the chat show "Signing in…" instead of an empty chat while a
|
|
69817
|
+
// sign-in — including one after reconnect() — is in flight.
|
|
69818
|
+
onSigningIn: (value) => {
|
|
69819
|
+
setSigningIn(value);
|
|
69820
|
+
setIsSigningIn(value);
|
|
69821
|
+
}
|
|
69822
|
+
});
|
|
69823
|
+
sessionRef.current = session;
|
|
69824
|
+
for (let delay = 1e3; ; delay = Math.min(delay * 2, 3e4)) {
|
|
69825
|
+
try {
|
|
69826
|
+
await session.getAccessToken();
|
|
69827
|
+
break;
|
|
69828
|
+
} catch (err) {
|
|
69829
|
+
if (cancelled || err?.fatal) return;
|
|
69830
|
+
await new Promise((r2) => setTimeout(r2, delay));
|
|
69831
|
+
if (cancelled) return;
|
|
69832
|
+
}
|
|
69833
|
+
}
|
|
69834
|
+
if (cancelled) {
|
|
69835
|
+
session.stop();
|
|
69836
|
+
return;
|
|
69837
|
+
}
|
|
69838
|
+
clientUserId = session.user.id;
|
|
69839
|
+
}
|
|
69840
|
+
const activeSession = session;
|
|
69841
|
+
const client = new SuperatomClient({
|
|
69842
|
+
userId: clientUserId,
|
|
69843
|
+
projectId,
|
|
69844
|
+
type: "runtime",
|
|
69845
|
+
debug,
|
|
69846
|
+
...wsUrl ? { baseUrl: wsUrl } : {},
|
|
69847
|
+
...activeSession ? { getAccessToken: () => activeSession.getAccessToken() } : { token: tokenRef.current }
|
|
69848
|
+
});
|
|
69359
69849
|
clientRef.current = client;
|
|
69360
69850
|
client.onError((err) => console.error("[SuperAtom] Error:", err));
|
|
69361
69851
|
try {
|
|
@@ -69372,11 +69862,11 @@ function useSuperAtom({ token, userId, projectId, debug = false, streaming = fal
|
|
|
69372
69862
|
};
|
|
69373
69863
|
const unsub = client.onConnect(done);
|
|
69374
69864
|
const cancelPoll = setInterval(() => {
|
|
69375
|
-
if (cancelled) done();
|
|
69865
|
+
if (cancelled || activeSession?.error) done();
|
|
69376
69866
|
}, 50);
|
|
69377
69867
|
});
|
|
69378
|
-
if (cancelled) {
|
|
69379
|
-
client.disconnect();
|
|
69868
|
+
if (cancelled || activeSession?.error) {
|
|
69869
|
+
if (cancelled) client.disconnect();
|
|
69380
69870
|
return;
|
|
69381
69871
|
}
|
|
69382
69872
|
window.dispatchEvent(new CustomEvent("sa:client-connected"));
|
|
@@ -69452,7 +69942,11 @@ function useSuperAtom({ token, userId, projectId, debug = false, streaming = fal
|
|
|
69452
69942
|
]);
|
|
69453
69943
|
};
|
|
69454
69944
|
}
|
|
69455
|
-
if (!cancelled)
|
|
69945
|
+
if (!cancelled) {
|
|
69946
|
+
setupDoneRef.current = true;
|
|
69947
|
+
setBundleReady(true);
|
|
69948
|
+
setChatReady(true);
|
|
69949
|
+
}
|
|
69456
69950
|
} catch (err) {
|
|
69457
69951
|
console.error("[SuperAtom] Setup failed:", err);
|
|
69458
69952
|
}
|
|
@@ -69466,9 +69960,26 @@ function useSuperAtom({ token, userId, projectId, debug = false, streaming = fal
|
|
|
69466
69960
|
}
|
|
69467
69961
|
clientRef.current?.disconnect();
|
|
69468
69962
|
clientRef.current = null;
|
|
69963
|
+
sessionRef.current?.stop();
|
|
69964
|
+
sessionRef.current = null;
|
|
69965
|
+
setAuthStatus(null);
|
|
69966
|
+
setupDoneRef.current = false;
|
|
69469
69967
|
setBundleReady(false);
|
|
69968
|
+
setChatReady(false);
|
|
69470
69969
|
};
|
|
69471
|
-
}, [
|
|
69970
|
+
}, [directUserId, sdkSignIn, projectId, apiUrl, wsUrl, debug, signInAttempt]);
|
|
69971
|
+
const reconnect = React6.useCallback(() => {
|
|
69972
|
+
const session = sessionRef.current;
|
|
69973
|
+
const client = clientRef.current;
|
|
69974
|
+
session?.reset();
|
|
69975
|
+
setAuthError(null);
|
|
69976
|
+
setAuthStatus(null);
|
|
69977
|
+
if (client && setupDoneRef.current) {
|
|
69978
|
+
client.forceReconnect().catch((err) => console.error("[SuperAtom] Reconnect failed:", err));
|
|
69979
|
+
} else {
|
|
69980
|
+
setSignInAttempt((n) => n + 1);
|
|
69981
|
+
}
|
|
69982
|
+
}, []);
|
|
69472
69983
|
const sendMessage = React6.useCallback(async () => {
|
|
69473
69984
|
const text9 = input.trim();
|
|
69474
69985
|
const client = clientRef.current;
|
|
@@ -69860,6 +70371,39 @@ function useSuperAtom({ token, userId, projectId, debug = false, streaming = fal
|
|
|
69860
70371
|
if (threadId.current === id) newChat();
|
|
69861
70372
|
return { success: true };
|
|
69862
70373
|
}, [resolvedUserId, newChat]);
|
|
70374
|
+
const deleteMessage = React6.useCallback(async (messageId) => {
|
|
70375
|
+
const client = clientRef.current;
|
|
70376
|
+
if (!client) return { success: false, error: "Not connected" };
|
|
70377
|
+
const list4 = messagesRef.current;
|
|
70378
|
+
const index2 = list4.findIndex((m) => m.id === messageId);
|
|
70379
|
+
if (index2 === -1) return { success: false, error: "Message not found" };
|
|
70380
|
+
let questionIndex = list4[index2]?.role === "user" ? index2 : -1;
|
|
70381
|
+
if (questionIndex === -1) {
|
|
70382
|
+
for (let i = index2 - 1; i >= 0; i--) {
|
|
70383
|
+
if (list4[i]?.role === "user") {
|
|
70384
|
+
questionIndex = i;
|
|
70385
|
+
break;
|
|
70386
|
+
}
|
|
70387
|
+
}
|
|
70388
|
+
}
|
|
70389
|
+
const question = questionIndex >= 0 ? list4[questionIndex]?.text ?? "" : "";
|
|
70390
|
+
if (!question.trim()) return { success: false, error: "Could not find the question for this answer" };
|
|
70391
|
+
const res = await deleteUserConversation(client, question, resolvedUserId);
|
|
70392
|
+
if (!res.success) return res;
|
|
70393
|
+
const removed = /* @__PURE__ */ new Set();
|
|
70394
|
+
for (let i = questionIndex; i < list4.length; i++) {
|
|
70395
|
+
const msg = list4[i];
|
|
70396
|
+
if (!msg) continue;
|
|
70397
|
+
if (i > questionIndex && msg.role === "user") break;
|
|
70398
|
+
removed.add(msg.id);
|
|
70399
|
+
}
|
|
70400
|
+
setMessages((prev) => prev.filter((m) => !removed.has(m.id)));
|
|
70401
|
+
return { success: true };
|
|
70402
|
+
}, [resolvedUserId]);
|
|
70403
|
+
React6.useEffect(() => {
|
|
70404
|
+
setMessageActions({ deleteMessage });
|
|
70405
|
+
return () => setMessageActions({});
|
|
70406
|
+
}, [deleteMessage]);
|
|
69863
70407
|
const renameThread = React6.useCallback(async (id, title) => {
|
|
69864
70408
|
const client = clientRef.current;
|
|
69865
70409
|
if (!client) return { success: false, error: "Not connected" };
|
|
@@ -69883,7 +70427,12 @@ function useSuperAtom({ token, userId, projectId, debug = false, streaming = fal
|
|
|
69883
70427
|
isLoadingThread,
|
|
69884
70428
|
refreshThreads,
|
|
69885
70429
|
deleteThread: deleteThread2,
|
|
69886
|
-
renameThread
|
|
70430
|
+
renameThread,
|
|
70431
|
+
isNewChat: bundleReady && !isLoadingThread && messages2.length === 0,
|
|
70432
|
+
user,
|
|
70433
|
+
authError,
|
|
70434
|
+
isSigningIn,
|
|
70435
|
+
reconnect
|
|
69887
70436
|
};
|
|
69888
70437
|
}
|
|
69889
70438
|
|
|
@@ -69979,6 +70528,9 @@ function ChatInput({
|
|
|
69979
70528
|
isResponding = false,
|
|
69980
70529
|
onStop
|
|
69981
70530
|
}) {
|
|
70531
|
+
const authError = useAuthStatus();
|
|
70532
|
+
const startingUp = useStartingUp();
|
|
70533
|
+
const isLocked = disabled || !!authError;
|
|
69982
70534
|
const textareaRef = React6.useRef(null);
|
|
69983
70535
|
const historyRef = React6.useRef(null);
|
|
69984
70536
|
const [isMultiline, setIsMultiline] = React6.useState(false);
|
|
@@ -70032,14 +70584,16 @@ function ChatInput({
|
|
|
70032
70584
|
}, 0);
|
|
70033
70585
|
};
|
|
70034
70586
|
const handleSend = React6.useCallback(() => {
|
|
70035
|
-
if (!input.trim() ||
|
|
70587
|
+
if (!input.trim() || isLocked) return;
|
|
70036
70588
|
const history = getOrCreateHistory();
|
|
70037
70589
|
history?.addCommand(input.trim());
|
|
70038
70590
|
history?.resetNavigation();
|
|
70039
70591
|
onSend();
|
|
70040
|
-
}, [input,
|
|
70592
|
+
}, [input, isLocked, onSend, getOrCreateHistory]);
|
|
70041
70593
|
const themeColor = getThemeColor();
|
|
70042
|
-
|
|
70594
|
+
const effectivePlaceholder = authError ? authStatusMessage(authError) : placeholder;
|
|
70595
|
+
if (startingUp) return null;
|
|
70596
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `sa-ui shrink-0 bg-base-100 border-t border-base-300 px-4 py-2 ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `group ${isMultiline ? "rounded-3xl" : "rounded-full"} bg-base-200 transition-all duration-200 w-full max-w-2xl mx-auto`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
70043
70597
|
"div",
|
|
70044
70598
|
{
|
|
70045
70599
|
className: `flex flex-col ${isMultiline ? "rounded-3xl" : "rounded-full"} border-2 shadow-sm transition-all duration-200 hover:shadow-md`,
|
|
@@ -70059,7 +70613,7 @@ function ChatInput({
|
|
|
70059
70613
|
autoCapitalize: "off",
|
|
70060
70614
|
ref: textareaRef,
|
|
70061
70615
|
value: input,
|
|
70062
|
-
placeholder,
|
|
70616
|
+
placeholder: effectivePlaceholder,
|
|
70063
70617
|
onChange: (e) => setInput(e.currentTarget.value),
|
|
70064
70618
|
onBlur: () => setIsFocused(false),
|
|
70065
70619
|
onFocus: () => setIsFocused(true),
|
|
@@ -70090,7 +70644,7 @@ function ChatInput({
|
|
|
70090
70644
|
},
|
|
70091
70645
|
rows: 1,
|
|
70092
70646
|
className: "textarea textarea-ghost w-full focus:outline-none focus:bg-transparent min-h-[40px] resize-none overflow-y-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
|
|
70093
|
-
disabled,
|
|
70647
|
+
disabled: isLocked,
|
|
70094
70648
|
style: { maxHeight: "200px" }
|
|
70095
70649
|
}
|
|
70096
70650
|
),
|
|
@@ -70112,11 +70666,11 @@ function ChatInput({
|
|
|
70112
70666
|
"button",
|
|
70113
70667
|
{
|
|
70114
70668
|
onClick: handleSend,
|
|
70115
|
-
disabled: !input.trim() ||
|
|
70669
|
+
disabled: !input.trim() || isLocked,
|
|
70116
70670
|
className: `transition-colors duration-150 rounded-full p-2 flex-shrink-0 ${isMultiline ? "mb-1" : ""} disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-transparent disabled:text-base-content/40`,
|
|
70117
70671
|
style: {
|
|
70118
|
-
backgroundColor: input.trim() && !
|
|
70119
|
-
color: input.trim() && !
|
|
70672
|
+
backgroundColor: input.trim() && !isLocked ? themeColor : "transparent",
|
|
70673
|
+
color: input.trim() && !isLocked ? "white" : themeColor
|
|
70120
70674
|
},
|
|
70121
70675
|
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: "ph:paper-plane-right-fill", width: 20, height: 20, className: "sm:w-6 sm:h-6" })
|
|
70122
70676
|
}
|
|
@@ -70132,6 +70686,86 @@ init_iconify();
|
|
|
70132
70686
|
// src/ui/components/MessageBubble.tsx
|
|
70133
70687
|
init_iconify();
|
|
70134
70688
|
init_Markdown();
|
|
70689
|
+
|
|
70690
|
+
// src/ui/components/ConfirmDeleteModal.tsx
|
|
70691
|
+
init_iconify();
|
|
70692
|
+
function ConfirmDeleteModal({
|
|
70693
|
+
isOpen,
|
|
70694
|
+
onClose,
|
|
70695
|
+
onConfirm,
|
|
70696
|
+
isDeleting,
|
|
70697
|
+
title = "Delete",
|
|
70698
|
+
message = "Are you sure you want to delete this?"
|
|
70699
|
+
}) {
|
|
70700
|
+
React6.useEffect(() => {
|
|
70701
|
+
if (!isOpen) return;
|
|
70702
|
+
const handleEscape = (e) => {
|
|
70703
|
+
if (e.key === "Escape" && !isDeleting) {
|
|
70704
|
+
onClose();
|
|
70705
|
+
}
|
|
70706
|
+
};
|
|
70707
|
+
document.addEventListener("keydown", handleEscape);
|
|
70708
|
+
document.body.style.overflow = "hidden";
|
|
70709
|
+
return () => {
|
|
70710
|
+
document.removeEventListener("keydown", handleEscape);
|
|
70711
|
+
document.body.style.overflow = "unset";
|
|
70712
|
+
};
|
|
70713
|
+
}, [isOpen, onClose, isDeleting]);
|
|
70714
|
+
const handleBackdropClick = (e) => {
|
|
70715
|
+
if (e.target === e.currentTarget && !isDeleting) {
|
|
70716
|
+
onClose();
|
|
70717
|
+
}
|
|
70718
|
+
};
|
|
70719
|
+
if (!isOpen) return null;
|
|
70720
|
+
return reactDom.createPortal(
|
|
70721
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
70722
|
+
"div",
|
|
70723
|
+
{
|
|
70724
|
+
className: "sa-ui fixed inset-0 flex items-center justify-center bg-black/50 backdrop-blur-sm",
|
|
70725
|
+
style: { zIndex: 9999 },
|
|
70726
|
+
onClick: handleBackdropClick,
|
|
70727
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-base-100 rounded-xl shadow-2xl w-full max-w-sm mx-4 overflow-hidden", children: [
|
|
70728
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b border-base-300", children: [
|
|
70729
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-base-content", children: title }),
|
|
70730
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
70731
|
+
"button",
|
|
70732
|
+
{
|
|
70733
|
+
type: "button",
|
|
70734
|
+
disabled: isDeleting,
|
|
70735
|
+
onClick: onClose,
|
|
70736
|
+
className: "p-1 rounded-lg hover:bg-base-200 transition-colors",
|
|
70737
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: "ph:x-bold", width: 20, height: 20, className: "text-base-content/60" })
|
|
70738
|
+
}
|
|
70739
|
+
)
|
|
70740
|
+
] }),
|
|
70741
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base-content/80", children: message }) }),
|
|
70742
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 p-4 border-t border-base-300", children: [
|
|
70743
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
70744
|
+
"button",
|
|
70745
|
+
{
|
|
70746
|
+
type: "button",
|
|
70747
|
+
onClick: onClose,
|
|
70748
|
+
disabled: isDeleting,
|
|
70749
|
+
className: "px-4 py-2 rounded-lg text-base-content hover:bg-base-200 transition-colors",
|
|
70750
|
+
children: "Cancel"
|
|
70751
|
+
}
|
|
70752
|
+
),
|
|
70753
|
+
isDeleting ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-20 px-4 py-2 rounded-lg bg-red-600 text-white flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: "eos-icons:loading", width: 20, height: 20, className: "animate-spin" }) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
70754
|
+
"button",
|
|
70755
|
+
{
|
|
70756
|
+
type: "button",
|
|
70757
|
+
onClick: onConfirm,
|
|
70758
|
+
className: "min-w-20 px-4 py-2 rounded-lg bg-red-600 text-white hover:bg-red-700 transition-colors",
|
|
70759
|
+
children: "Delete"
|
|
70760
|
+
}
|
|
70761
|
+
)
|
|
70762
|
+
] })
|
|
70763
|
+
] })
|
|
70764
|
+
}
|
|
70765
|
+
),
|
|
70766
|
+
document.body
|
|
70767
|
+
);
|
|
70768
|
+
}
|
|
70135
70769
|
function StopButton({ onStop }) {
|
|
70136
70770
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
70137
70771
|
"button",
|
|
@@ -70157,17 +70791,40 @@ function MessageBubble({ message, onStop }) {
|
|
|
70157
70791
|
const isTextOnly = message.isTextOnlyResponse === true;
|
|
70158
70792
|
const isAborted = message.aborted === true;
|
|
70159
70793
|
const responseComplete = hasComponent || isTextOnly || !isStreaming && hasText;
|
|
70794
|
+
const [watchedGeneration] = React6.useState(() => !responseComplete);
|
|
70160
70795
|
React6.useEffect(() => {
|
|
70161
|
-
if (message.role !== "assistant") return;
|
|
70162
|
-
startTime.current = Date.now();
|
|
70796
|
+
if (message.role !== "assistant" || !watchedGeneration) return;
|
|
70163
70797
|
if (responseComplete) {
|
|
70164
70798
|
setElapsedMs(Date.now() - startTime.current);
|
|
70165
70799
|
return;
|
|
70166
70800
|
}
|
|
70801
|
+
setElapsedMs(Date.now() - startTime.current);
|
|
70167
70802
|
const interval = setInterval(() => setElapsedMs(Date.now() - startTime.current), 100);
|
|
70168
70803
|
return () => clearInterval(interval);
|
|
70169
|
-
}, [message.role, responseComplete]);
|
|
70804
|
+
}, [message.role, responseComplete, watchedGeneration]);
|
|
70170
70805
|
const formatMs = (ms) => ms < 1e3 ? `${ms}ms` : `${(ms / 1e3).toFixed(1)}s`;
|
|
70806
|
+
const { deleteMessage } = useMessageActions();
|
|
70807
|
+
const [confirmOpen, setConfirmOpen] = React6.useState(false);
|
|
70808
|
+
const [isDeleting, setIsDeleting] = React6.useState(false);
|
|
70809
|
+
const handleDelete2 = async () => {
|
|
70810
|
+
if (!deleteMessage) return;
|
|
70811
|
+
setIsDeleting(true);
|
|
70812
|
+
const res = await deleteMessage(message.id);
|
|
70813
|
+
setIsDeleting(false);
|
|
70814
|
+
setConfirmOpen(false);
|
|
70815
|
+
if (!res.success) console.error("[SuperAtom] Could not delete the message:", res.error);
|
|
70816
|
+
};
|
|
70817
|
+
const deleteButton = deleteMessage && responseComplete && !isAborted ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end mt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
70818
|
+
"button",
|
|
70819
|
+
{
|
|
70820
|
+
onClick: () => setConfirmOpen(true),
|
|
70821
|
+
disabled: isDeleting,
|
|
70822
|
+
title: "Delete this answer",
|
|
70823
|
+
"aria-label": "Delete this answer",
|
|
70824
|
+
className: "cursor-pointer p-2 rounded-lg shadow-md bg-base-100 text-base-content/40 hover:text-red-500 hover:shadow-lg transition-colors duration-150 disabled:opacity-50 disabled:cursor-wait",
|
|
70825
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) })
|
|
70826
|
+
}
|
|
70827
|
+
) }) : null;
|
|
70171
70828
|
const accordionHeader = React6.useMemo(() => {
|
|
70172
70829
|
if (isAborted) return hasText ? "Stopped" : "Stopped (no response yet)";
|
|
70173
70830
|
if (!hasText) return "Thinking...";
|
|
@@ -70203,7 +70860,7 @@ function MessageBubble({ message, onStop }) {
|
|
|
70203
70860
|
children: [
|
|
70204
70861
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-base-content truncate text-left flex-1", children: accordionHeader }),
|
|
70205
70862
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 shrink-0", children: [
|
|
70206
|
-
!message.fromHistory && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-teal-50 border border-teal-200", children: [
|
|
70863
|
+
!message.fromHistory && watchedGeneration && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-teal-50 border border-teal-200", children: [
|
|
70207
70864
|
responseComplete ? /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "text-teal-600", width: 12, height: 12, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "loading loading-spinner loading-xs text-teal-600" }),
|
|
70208
70865
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-teal-700 font-medium font-mono", children: formatMs(elapsedMs) })
|
|
70209
70866
|
] }),
|
|
@@ -70253,8 +70910,25 @@ function MessageBubble({ message, onStop }) {
|
|
|
70253
70910
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-base-content/70", children: "Generating component..." })
|
|
70254
70911
|
] })
|
|
70255
70912
|
] }) }),
|
|
70256
|
-
hasComponent && /* @__PURE__ */ jsxRuntime.
|
|
70257
|
-
|
|
70913
|
+
hasComponent && /* @__PURE__ */ jsxRuntime.jsxs("div", { id: `box-${message.id}`, className: "w-full px-4 lg:px-16 xl:px-24 2xl:px-32", children: [
|
|
70914
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl shadow-sm bg-base-100 border-2 border-base-300 min-h-[85vh] overflow-auto flex items-center justify-center p-5", children: /* @__PURE__ */ jsxRuntime.jsx(DSLRenderer, { dsl: message.schema.ui, data: message.schema.data ?? {} }) }),
|
|
70915
|
+
deleteButton
|
|
70916
|
+
] }),
|
|
70917
|
+
!isStreaming && !hasComponent && hasText && isTextOnly && !isAborted && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center w-full px-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full md:w-[60vw]", children: [
|
|
70918
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl shadow-sm bg-base-100 border-2 border-base-300 p-4 text-base-content", children: /* @__PURE__ */ jsxRuntime.jsx(Markdown_default, { content: fullText, isStreaming: false }) }),
|
|
70919
|
+
deleteButton
|
|
70920
|
+
] }) }),
|
|
70921
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
70922
|
+
ConfirmDeleteModal,
|
|
70923
|
+
{
|
|
70924
|
+
isOpen: confirmOpen,
|
|
70925
|
+
onClose: () => setConfirmOpen(false),
|
|
70926
|
+
onConfirm: handleDelete2,
|
|
70927
|
+
isDeleting,
|
|
70928
|
+
title: "Delete this answer?",
|
|
70929
|
+
message: "The question and its answer are removed from this chat and from your history. Anything cached for it is cleared too, so asking again re-runs it."
|
|
70930
|
+
}
|
|
70931
|
+
)
|
|
70258
70932
|
] });
|
|
70259
70933
|
}
|
|
70260
70934
|
function DynamicSpacer({ messages: messages2 }) {
|
|
@@ -70268,6 +70942,7 @@ function MessageList({
|
|
|
70268
70942
|
bundleReady,
|
|
70269
70943
|
connectingText = "Connecting to SuperAtom...",
|
|
70270
70944
|
emptyText = "Start a conversation",
|
|
70945
|
+
emptyState,
|
|
70271
70946
|
className = "",
|
|
70272
70947
|
isResponding = false,
|
|
70273
70948
|
onStop,
|
|
@@ -70351,11 +71026,20 @@ function MessageList({
|
|
|
70351
71026
|
}
|
|
70352
71027
|
}, 300);
|
|
70353
71028
|
}, [messages2]);
|
|
70354
|
-
|
|
70355
|
-
|
|
71029
|
+
const authError = useAuthStatus();
|
|
71030
|
+
const retrying2 = useRetryingStatus();
|
|
71031
|
+
const signingIn2 = useSigningIn();
|
|
71032
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `sa-ui flex-1 relative overflow-hidden ${className}`, children: [
|
|
71033
|
+
/* @__PURE__ */ jsxRuntime.jsx("main", { ref: containerRef, className: "h-full overflow-y-auto py-6", children: signingIn2 && !bundleReady ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col items-center justify-center gap-3 text-base-content/50", children: [
|
|
71034
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "loading loading-spinner loading-lg" }),
|
|
71035
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "Signing in to Superatom\u2026" })
|
|
71036
|
+
] }) : authError ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col items-center justify-center gap-3 px-6 text-center", children: [
|
|
71037
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: "mdi:lock-alert-outline", width: 28, height: 28, className: "text-base-content/40" }),
|
|
71038
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-base-content/70 max-w-sm", children: authStatusMessage(authError) })
|
|
71039
|
+
] }) : !bundleReady || isLoadingThread && messages2.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col items-center justify-center gap-3 text-base-content/50", children: [
|
|
70356
71040
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "loading loading-spinner loading-md" }),
|
|
70357
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: !bundleReady ? connectingText : loadingThreadText })
|
|
70358
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
71041
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: !bundleReady ? retrying2 ? retryingStatusMessage(retrying2) : connectingText : loadingThreadText })
|
|
71042
|
+
] }) : messages2.length === 0 && emptyState ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full flex flex-col", children: emptyState }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
70359
71043
|
messages2.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center mt-24", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base-content/40 text-sm", children: emptyText }) }),
|
|
70360
71044
|
messages2.map((msg) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
70361
71045
|
MessageBubble,
|
|
@@ -70737,87 +71421,8 @@ var MenuV1RendererCollapsed = ({ items, onItemClick }) => {
|
|
|
70737
71421
|
groupIndex < groupedItems.length - 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 border-t border-base-300 my-2" })
|
|
70738
71422
|
] }, groupIndex)) });
|
|
70739
71423
|
};
|
|
70740
|
-
|
|
70741
|
-
// src/ui/components/ConfirmDeleteModal.tsx
|
|
70742
|
-
init_iconify();
|
|
70743
|
-
function ConfirmDeleteModal({
|
|
70744
|
-
isOpen,
|
|
70745
|
-
onClose,
|
|
70746
|
-
onConfirm,
|
|
70747
|
-
isDeleting,
|
|
70748
|
-
title = "Delete",
|
|
70749
|
-
message = "Are you sure you want to delete this?"
|
|
70750
|
-
}) {
|
|
70751
|
-
React6.useEffect(() => {
|
|
70752
|
-
if (!isOpen) return;
|
|
70753
|
-
const handleEscape = (e) => {
|
|
70754
|
-
if (e.key === "Escape" && !isDeleting) {
|
|
70755
|
-
onClose();
|
|
70756
|
-
}
|
|
70757
|
-
};
|
|
70758
|
-
document.addEventListener("keydown", handleEscape);
|
|
70759
|
-
document.body.style.overflow = "hidden";
|
|
70760
|
-
return () => {
|
|
70761
|
-
document.removeEventListener("keydown", handleEscape);
|
|
70762
|
-
document.body.style.overflow = "unset";
|
|
70763
|
-
};
|
|
70764
|
-
}, [isOpen, onClose, isDeleting]);
|
|
70765
|
-
const handleBackdropClick = (e) => {
|
|
70766
|
-
if (e.target === e.currentTarget && !isDeleting) {
|
|
70767
|
-
onClose();
|
|
70768
|
-
}
|
|
70769
|
-
};
|
|
70770
|
-
if (!isOpen) return null;
|
|
70771
|
-
return reactDom.createPortal(
|
|
70772
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
70773
|
-
"div",
|
|
70774
|
-
{
|
|
70775
|
-
className: "fixed inset-0 flex items-center justify-center bg-black/50 backdrop-blur-sm",
|
|
70776
|
-
style: { zIndex: 9999 },
|
|
70777
|
-
onClick: handleBackdropClick,
|
|
70778
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-base-100 rounded-xl shadow-2xl w-full max-w-sm mx-4 overflow-hidden", children: [
|
|
70779
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between p-4 border-b border-base-300", children: [
|
|
70780
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-base-content", children: title }),
|
|
70781
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
70782
|
-
"button",
|
|
70783
|
-
{
|
|
70784
|
-
type: "button",
|
|
70785
|
-
disabled: isDeleting,
|
|
70786
|
-
onClick: onClose,
|
|
70787
|
-
className: "p-1 rounded-lg hover:bg-base-200 transition-colors",
|
|
70788
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: "ph:x-bold", width: 20, height: 20, className: "text-base-content/60" })
|
|
70789
|
-
}
|
|
70790
|
-
)
|
|
70791
|
-
] }),
|
|
70792
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base-content/80", children: message }) }),
|
|
70793
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 p-4 border-t border-base-300", children: [
|
|
70794
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
70795
|
-
"button",
|
|
70796
|
-
{
|
|
70797
|
-
type: "button",
|
|
70798
|
-
onClick: onClose,
|
|
70799
|
-
disabled: isDeleting,
|
|
70800
|
-
className: "px-4 py-2 rounded-lg text-base-content hover:bg-base-200 transition-colors",
|
|
70801
|
-
children: "Cancel"
|
|
70802
|
-
}
|
|
70803
|
-
),
|
|
70804
|
-
isDeleting ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-20 px-4 py-2 rounded-lg bg-red-600 text-white flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon: "eos-icons:loading", width: 20, height: 20, className: "animate-spin" }) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
70805
|
-
"button",
|
|
70806
|
-
{
|
|
70807
|
-
type: "button",
|
|
70808
|
-
onClick: onConfirm,
|
|
70809
|
-
className: "min-w-20 px-4 py-2 rounded-lg bg-red-600 text-white hover:bg-red-700 transition-colors",
|
|
70810
|
-
children: "Delete"
|
|
70811
|
-
}
|
|
70812
|
-
)
|
|
70813
|
-
] })
|
|
70814
|
-
] })
|
|
70815
|
-
}
|
|
70816
|
-
),
|
|
70817
|
-
document.body
|
|
70818
|
-
);
|
|
70819
|
-
}
|
|
70820
71424
|
var CHATS_OPEN_KEY = "chats-section-open";
|
|
71425
|
+
var SIDEBAR_COLLAPSED_KEY = "sa-sidebar-collapsed";
|
|
70821
71426
|
function Sidebar({
|
|
70822
71427
|
children,
|
|
70823
71428
|
className = "",
|
|
@@ -70879,8 +71484,21 @@ function Sidebar({
|
|
|
70879
71484
|
setThreadToDelete(null);
|
|
70880
71485
|
}
|
|
70881
71486
|
};
|
|
70882
|
-
const
|
|
70883
|
-
const [
|
|
71487
|
+
const startingUp = useStartingUp();
|
|
71488
|
+
const [collapsed, setCollapsed] = React6.useState(() => {
|
|
71489
|
+
try {
|
|
71490
|
+
return localStorage.getItem(SIDEBAR_COLLAPSED_KEY) === "true";
|
|
71491
|
+
} catch {
|
|
71492
|
+
return false;
|
|
71493
|
+
}
|
|
71494
|
+
});
|
|
71495
|
+
const [showContent, setShowContent] = React6.useState(() => {
|
|
71496
|
+
try {
|
|
71497
|
+
return localStorage.getItem(SIDEBAR_COLLAPSED_KEY) !== "true";
|
|
71498
|
+
} catch {
|
|
71499
|
+
return true;
|
|
71500
|
+
}
|
|
71501
|
+
});
|
|
70884
71502
|
const [menuV1Data, setMenuV1Data] = React6.useState(null);
|
|
70885
71503
|
const [isChatsOpen, setIsChatsOpen] = React6.useState(() => {
|
|
70886
71504
|
try {
|
|
@@ -70924,6 +71542,10 @@ function Sidebar({
|
|
|
70924
71542
|
function toggle() {
|
|
70925
71543
|
const next2 = !collapsed;
|
|
70926
71544
|
setCollapsed(next2);
|
|
71545
|
+
try {
|
|
71546
|
+
localStorage.setItem(SIDEBAR_COLLAPSED_KEY, String(next2));
|
|
71547
|
+
} catch {
|
|
71548
|
+
}
|
|
70927
71549
|
if (!next2) {
|
|
70928
71550
|
setTimeout(() => setShowContent(true), 150);
|
|
70929
71551
|
} else {
|
|
@@ -70947,10 +71569,11 @@ function Sidebar({
|
|
|
70947
71569
|
});
|
|
70948
71570
|
}
|
|
70949
71571
|
}
|
|
71572
|
+
if (startingUp) return null;
|
|
70950
71573
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
70951
71574
|
"aside",
|
|
70952
71575
|
{
|
|
70953
|
-
className: `flex flex-col shrink-0 border-r border-base-300 transition-all duration-300 ease-in-out overflow-hidden bg-base-200 ${collapsed ? "w-16" : "w-60"} ${className}`,
|
|
71576
|
+
className: `sa-ui flex flex-col shrink-0 border-r border-base-300 transition-all duration-300 ease-in-out overflow-hidden bg-base-200 ${collapsed ? "w-16" : "w-60"} ${className}`,
|
|
70954
71577
|
children: [
|
|
70955
71578
|
!collapsed && showContent && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full w-60", children: [
|
|
70956
71579
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-3 py-3 border-b border-base-300 flex-shrink-0", children: [
|
|
@@ -71120,7 +71743,7 @@ function NewChatHero({
|
|
|
71120
71743
|
subtitle = "Ask a question to start a new chat",
|
|
71121
71744
|
className = ""
|
|
71122
71745
|
}) {
|
|
71123
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex-1 min-h-0 flex flex-col items-center justify-center gap-6 px-4 ${className}`, children: [
|
|
71746
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `sa-ui flex-1 min-h-0 flex flex-col items-center justify-center gap-6 px-4 ${className}`, children: [
|
|
71124
71747
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2 text-center", children: [
|
|
71125
71748
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl md:text-3xl font-semibold text-base-content", children: title }),
|
|
71126
71749
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-base-content/50", children: subtitle })
|
|
@@ -71130,7 +71753,7 @@ function NewChatHero({
|
|
|
71130
71753
|
}
|
|
71131
71754
|
|
|
71132
71755
|
// src/index.ts
|
|
71133
|
-
var SDK_VERSION = "0.0.
|
|
71756
|
+
var SDK_VERSION = "0.0.3";
|
|
71134
71757
|
|
|
71135
71758
|
exports.ActionsRequestMessageSchema = ActionsRequestMessageSchema;
|
|
71136
71759
|
exports.ActionsRequestPayloadSchema = ActionsRequestPayloadSchema;
|
|
@@ -71150,6 +71773,7 @@ exports.ComponentSchema = ComponentSchema;
|
|
|
71150
71773
|
exports.ComponentsSendMessageSchema = ComponentsSendMessageSchema;
|
|
71151
71774
|
exports.ComponentsSendPayloadSchema = ComponentsSendPayloadSchema;
|
|
71152
71775
|
exports.ConfirmDeleteModal = ConfirmDeleteModal;
|
|
71776
|
+
exports.DEFAULT_API_URL = DEFAULT_API_URL;
|
|
71153
71777
|
exports.DSLErrorBoundary = DSLErrorBoundary;
|
|
71154
71778
|
exports.DSLRenderer = DSLRenderer;
|
|
71155
71779
|
exports.DSLRendererPropsSchema = DSLRendererPropsSchema3;
|
|
@@ -71175,7 +71799,9 @@ exports.MessageSchema = MessageSchema;
|
|
|
71175
71799
|
exports.NewChatHero = NewChatHero;
|
|
71176
71800
|
exports.QuerySpecSchema = QuerySpecSchema3;
|
|
71177
71801
|
exports.SDK_VERSION = SDK_VERSION;
|
|
71802
|
+
exports.SdkSession = SdkSession;
|
|
71178
71803
|
exports.Sidebar = Sidebar;
|
|
71804
|
+
exports.SuperAtomAuthError = SuperAtomAuthError;
|
|
71179
71805
|
exports.SuperatomClient = SuperatomClient;
|
|
71180
71806
|
exports.UIComponentSchema = UIComponentSchema3;
|
|
71181
71807
|
exports.UIElementSchema = UIElementSchema3;
|