@cossistant/react 0.0.17 → 0.0.19
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/README.md +1 -1
- package/hooks/private/use-rest-client.js +2 -2
- package/hooks/private/use-rest-client.js.map +1 -1
- package/package.json +4 -8
- package/primitives/avatar/image.d.ts +1 -1
- package/primitives/multimodal-input.d.ts +2 -2
- package/primitives/multimodal-input.d.ts.map +1 -1
- package/realtime/provider.js +1 -1
- package/realtime/provider.js.map +1 -1
- package/support/components/conversation-timeline.js +1 -1
- package/support/components/conversation-timeline.js.map +1 -1
- package/support/{support-BQhCt9Za.css → support-D2EgfIts.css} +25 -3
- package/support/support-D2EgfIts.css.map +1 -0
- package/support.css +1 -1
- package/tailwind.css +24 -2
- package/utils/use-render-element.d.ts.map +1 -1
- package/support/support-BQhCt9Za.css.map +0 -1
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ import "@cossistant/react/support.css";
|
|
|
48
48
|
|
|
49
49
|
export function App() {
|
|
50
50
|
return (
|
|
51
|
-
<SupportProvider publicKey={process.env.
|
|
51
|
+
<SupportProvider publicKey={process.env.NEXT_PUBLIC_COSSISTANT_API_KEY}>
|
|
52
52
|
<Support />
|
|
53
53
|
</SupportProvider>
|
|
54
54
|
);
|
|
@@ -14,9 +14,9 @@ import { CossistantClient } from "@cossistant/core";
|
|
|
14
14
|
function useClient(publicKey, apiUrl = "https://api.cossistant.com/v1", wsUrl = "wss://api.cossistant.com/ws") {
|
|
15
15
|
return {
|
|
16
16
|
client: useMemo(() => {
|
|
17
|
-
const keyFromEnv = process.env.
|
|
17
|
+
const keyFromEnv = process.env.NEXT_PUBLIC_COSSISTANT_API_KEY || process.env.COSSISTANT_PUBLIC_KEY;
|
|
18
18
|
const keyToUse = publicKey ?? keyFromEnv;
|
|
19
|
-
if (!keyToUse) throw new Error("Public key is required. Please provide it as a prop or set
|
|
19
|
+
if (!keyToUse) throw new Error("Public key is required. Please provide it as a prop or set NEXT_PUBLIC_COSSISTANT_API_KEY environment variable.");
|
|
20
20
|
const config = {
|
|
21
21
|
apiUrl,
|
|
22
22
|
wsUrl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-rest-client.js","names":["config: CossistantConfig","err: unknown"],"sources":["../../../src/hooks/private/use-rest-client.ts"],"sourcesContent":["\"use client\";\n\nimport { CossistantClient } from \"@cossistant/core\";\nimport type { CossistantConfig } from \"@cossistant/types\";\nimport { useMemo } from \"react\";\n\nexport type UseClientResult = {\n\tclient: CossistantClient;\n\terror: Error | null;\n};\n\n/**\n * Creates a memoised `CossistantClient` instance using the provided endpoints\n * and public key. When no key is passed the hook falls back to environment\n * variables and surfaces missing configuration errors through the returned\n * `error` field.\n */\nexport function useClient(\n\tpublicKey: string | undefined,\n\tapiUrl = \"https://api.cossistant.com/v1\",\n\twsUrl = \"wss://api.cossistant.com/ws\"\n): UseClientResult {\n\tconst client = useMemo(() => {\n\t\tconst keyFromEnv =\n\t\t\tprocess.env.
|
|
1
|
+
{"version":3,"file":"use-rest-client.js","names":["config: CossistantConfig","err: unknown"],"sources":["../../../src/hooks/private/use-rest-client.ts"],"sourcesContent":["\"use client\";\n\nimport { CossistantClient } from \"@cossistant/core\";\nimport type { CossistantConfig } from \"@cossistant/types\";\nimport { useMemo } from \"react\";\n\nexport type UseClientResult = {\n\tclient: CossistantClient;\n\terror: Error | null;\n};\n\n/**\n * Creates a memoised `CossistantClient` instance using the provided endpoints\n * and public key. When no key is passed the hook falls back to environment\n * variables and surfaces missing configuration errors through the returned\n * `error` field.\n */\nexport function useClient(\n\tpublicKey: string | undefined,\n\tapiUrl = \"https://api.cossistant.com/v1\",\n\twsUrl = \"wss://api.cossistant.com/ws\"\n): UseClientResult {\n\tconst client = useMemo(() => {\n\t\tconst keyFromEnv =\n\t\t\tprocess.env.NEXT_PUBLIC_COSSISTANT_API_KEY ||\n\t\t\tprocess.env.COSSISTANT_PUBLIC_KEY;\n\t\tconst keyToUse = publicKey ?? keyFromEnv;\n\n\t\tif (!keyToUse) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Public key is required. Please provide it as a prop or set NEXT_PUBLIC_COSSISTANT_API_KEY environment variable.\"\n\t\t\t);\n\t\t}\n\n\t\tconst config: CossistantConfig = {\n\t\t\tapiUrl,\n\t\t\twsUrl,\n\t\t\tpublicKey: keyToUse,\n\t\t};\n\n\t\ttry {\n\t\t\treturn new CossistantClient(config);\n\t\t} catch (err: unknown) {\n\t\t\tthrow err instanceof Error\n\t\t\t\t? err\n\t\t\t\t: new Error(\"Failed to initialize Cossistant client\");\n\t\t}\n\t}, [publicKey, apiUrl, wsUrl]);\n\n\treturn { client, error: null };\n}\n"],"mappings":";;;;;;;;;;;;;AAiBA,SAAgB,UACf,WACA,SAAS,iCACT,QAAQ,+BACU;AA4BlB,QAAO;EAAE,QA3BM,cAAc;GAC5B,MAAM,aACL,QAAQ,IAAI,kCACZ,QAAQ,IAAI;GACb,MAAM,WAAW,aAAa;AAE9B,OAAI,CAAC,SACJ,OAAM,IAAI,MACT,kHACA;GAGF,MAAMA,SAA2B;IAChC;IACA;IACA,WAAW;IACX;AAED,OAAI;AACH,WAAO,IAAI,iBAAiB,OAAO;YAC3BC,KAAc;AACtB,UAAM,eAAe,QAClB,sBACA,IAAI,MAAM,yCAAyC;;KAErD;GAAC;GAAW;GAAQ;GAAM,CAAC;EAEb,OAAO;EAAM"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cossistant/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.19",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Cossistant team",
|
|
7
7
|
"description": "Headless React SDK for building AI-powered support/chat widgets. Hooks + primitives, WS-driven, TypeScript-first. Next.js-ready, Tailwind optional.",
|
|
@@ -88,8 +88,8 @@
|
|
|
88
88
|
"*.css"
|
|
89
89
|
],
|
|
90
90
|
"dependencies": {
|
|
91
|
-
"@cossistant/core": "0.0.
|
|
92
|
-
"@cossistant/types": "0.0.
|
|
91
|
+
"@cossistant/core": "0.0.19",
|
|
92
|
+
"@cossistant/types": "0.0.19",
|
|
93
93
|
"class-variance-authority": "^0.7.1",
|
|
94
94
|
"clsx": "^2.1.1",
|
|
95
95
|
"nanoid": "^5.1.5",
|
|
@@ -103,8 +103,7 @@
|
|
|
103
103
|
"react-dom": ">=18 <20",
|
|
104
104
|
"@types/react": "",
|
|
105
105
|
"motion": "^12.18.1",
|
|
106
|
-
"tailwindcss": "*"
|
|
107
|
-
"tailwind-scrollbar": "*"
|
|
106
|
+
"tailwindcss": "*"
|
|
108
107
|
},
|
|
109
108
|
"peerDependenciesMeta": {
|
|
110
109
|
"@types/react": {
|
|
@@ -112,9 +111,6 @@
|
|
|
112
111
|
},
|
|
113
112
|
"tailwindcss": {
|
|
114
113
|
"optional": true
|
|
115
|
-
},
|
|
116
|
-
"tailwind-scrollbar": {
|
|
117
|
-
"optional": true
|
|
118
114
|
}
|
|
119
115
|
},
|
|
120
116
|
"browserslist": {
|
|
@@ -15,7 +15,7 @@ type AvatarImageProps = Omit<React$1.ImgHTMLAttributes<HTMLImageElement>, "src"
|
|
|
15
15
|
* Controlled `<img>` that syncs its loading status back to the avatar context
|
|
16
16
|
* so fallbacks know when to display.
|
|
17
17
|
*/
|
|
18
|
-
declare const AvatarImage: React$1.ForwardRefExoticComponent<Omit<React$1.ImgHTMLAttributes<HTMLImageElement>, "
|
|
18
|
+
declare const AvatarImage: React$1.ForwardRefExoticComponent<Omit<React$1.ImgHTMLAttributes<HTMLImageElement>, "alt" | "src"> & {
|
|
19
19
|
src: string;
|
|
20
20
|
alt?: string;
|
|
21
21
|
asChild?: boolean;
|
|
@@ -16,7 +16,7 @@ type MultimodalInputProps = Omit<React$1.TextareaHTMLAttributes<HTMLTextAreaElem
|
|
|
16
16
|
* clipboard uploads and auto-resizing while remaining composable via
|
|
17
17
|
* `asChild`.
|
|
18
18
|
*/
|
|
19
|
-
declare const MultimodalInput: React$1.ForwardRefExoticComponent<Omit<React$1.TextareaHTMLAttributes<HTMLTextAreaElement>, "
|
|
19
|
+
declare const MultimodalInput: React$1.ForwardRefExoticComponent<Omit<React$1.TextareaHTMLAttributes<HTMLTextAreaElement>, "onChange" | "value"> & {
|
|
20
20
|
value: string;
|
|
21
21
|
onChange: (value: string) => void;
|
|
22
22
|
onSubmit?: () => void;
|
|
@@ -38,7 +38,7 @@ declare const FileInput: React$1.ForwardRefExoticComponent<React$1.InputHTMLAttr
|
|
|
38
38
|
onFileSelect?: (files: File[]) => void;
|
|
39
39
|
asChild?: boolean;
|
|
40
40
|
} & React$1.RefAttributes<HTMLInputElement>>;
|
|
41
|
-
declare const SupportInput: React$1.ForwardRefExoticComponent<Omit<React$1.TextareaHTMLAttributes<HTMLTextAreaElement>, "
|
|
41
|
+
declare const SupportInput: React$1.ForwardRefExoticComponent<Omit<React$1.TextareaHTMLAttributes<HTMLTextAreaElement>, "onChange" | "value"> & {
|
|
42
42
|
value: string;
|
|
43
43
|
onChange: (value: string) => void;
|
|
44
44
|
onSubmit?: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multimodal-input.d.ts","names":[],"sources":["../../src/primitives/multimodal-input.tsx"],"sourcesContent":[],"mappings":";;;KAGY,oBAAA,GAAuB,KAClC,OAAA,CAAM,uBAAuB;;EADlB,QAAA,EAAA,CAAA,KAAA,EAAA,MAAoB,EAAA,GAAA,IAAA;EACF,QAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EAA7B,YAAM,CAAA,EAAA,CAAA,KAAA,EAMiB,IANjB,EAAA,EAAA,GAAA,IAAA;EAD4B,OAAA,CAAA,EAAA,OAAA;EAOX,SAAA,CAAA,EAAA,MAAA;EAGf,KAAA,CAAA,EAAA,KAAA,GAAA,IAAA;EAAK,QAAA,CAAA,EAAA,OAAA;AASd,CAAA;;;;;;cAAa,iBAAe,OAAA,CAAA,0BAAA,KAAA,OAAA,CAAA,uBAAA;;EAAA,QAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAA,QAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EA4GhB,YAAA,CAAA,EAAA,CAAA,KAAc,EAxHF,IAwHE,EAAA,EAAA,GAAA,IAAA;EAA6B,OAAA,CAAA,EAAA,OAAA;EAA1B,SAAM,CAAA,EAAA,MAAA;EACX,KAAA,CAAA,EAtHf,KAsHe,GAAA,IAAA;EAAI,QAAA,CAAA,EAAA,OAAA;AAQ5B,CAAA,wBAkCI,oBAAA,CAAA,CAAA;AAlCkB,KATV,cAAA,GAAiB,OAAA,CAAM,mBASb,CATiC,gBASjC,CAAA,GAAA;EAAA,YAAA,CAAA,EAAA,CAAA,KAAA,EARE,IAQF,EAAA,EAAA,GAAA,IAAA;EARE,OAAA,CAAA,EAAA,OAAA;;;;;AA6CxB;AAAyB,cArCZ,SAqCY,EArCH,OAAA,CAAA,yBAqCG,CArCH,OAAA,CAAA,mBAqCG,CArCH,gBAqCG,CAAA,GAAA;EAAA,YAAA,CAAA,EAAA,CAAA,KAAA,EA7CD,IA6CC,EAAA,EAAA,GAAA,IAAA;EAAA,OAAA,CAAA,EAAA,OAAA;CAtKD,wBAAA,iBAAA,CAAA,CAAA;AAGf,cAmKI,YAnKJ,EAmKgB,OAAA,CAAA,yBAnKhB,CAmKgB,IAnKhB,CAmKgB,OAAA,CAAA,sBAnKhB,CAmKgB,mBAnKhB,CAAA,EAAA,
|
|
1
|
+
{"version":3,"file":"multimodal-input.d.ts","names":[],"sources":["../../src/primitives/multimodal-input.tsx"],"sourcesContent":[],"mappings":";;;KAGY,oBAAA,GAAuB,KAClC,OAAA,CAAM,uBAAuB;;EADlB,QAAA,EAAA,CAAA,KAAA,EAAA,MAAoB,EAAA,GAAA,IAAA;EACF,QAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EAA7B,YAAM,CAAA,EAAA,CAAA,KAAA,EAMiB,IANjB,EAAA,EAAA,GAAA,IAAA;EAD4B,OAAA,CAAA,EAAA,OAAA;EAOX,SAAA,CAAA,EAAA,MAAA;EAGf,KAAA,CAAA,EAAA,KAAA,GAAA,IAAA;EAAK,QAAA,CAAA,EAAA,OAAA;AASd,CAAA;;;;;;cAAa,iBAAe,OAAA,CAAA,0BAAA,KAAA,OAAA,CAAA,uBAAA;;EAAA,QAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EAAA,QAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EA4GhB,YAAA,CAAA,EAAA,CAAA,KAAc,EAxHF,IAwHE,EAAA,EAAA,GAAA,IAAA;EAA6B,OAAA,CAAA,EAAA,OAAA;EAA1B,SAAM,CAAA,EAAA,MAAA;EACX,KAAA,CAAA,EAtHf,KAsHe,GAAA,IAAA;EAAI,QAAA,CAAA,EAAA,OAAA;AAQ5B,CAAA,wBAkCI,oBAAA,CAAA,CAAA;AAlCkB,KATV,cAAA,GAAiB,OAAA,CAAM,mBASb,CATiC,gBASjC,CAAA,GAAA;EAAA,YAAA,CAAA,EAAA,CAAA,KAAA,EARE,IAQF,EAAA,EAAA,GAAA,IAAA;EARE,OAAA,CAAA,EAAA,OAAA;;;;;AA6CxB;AAAyB,cArCZ,SAqCY,EArCH,OAAA,CAAA,yBAqCG,CArCH,OAAA,CAAA,mBAqCG,CArCH,gBAqCG,CAAA,GAAA;EAAA,YAAA,CAAA,EAAA,CAAA,KAAA,EA7CD,IA6CC,EAAA,EAAA,GAAA,IAAA;EAAA,OAAA,CAAA,EAAA,OAAA;CAtKD,wBAAA,iBAAA,CAAA,CAAA;AAGf,cAmKI,YAnKJ,EAmKgB,OAAA,CAAA,yBAnKhB,CAmKgB,IAnKhB,CAmKgB,OAAA,CAAA,sBAnKhB,CAmKgB,mBAnKhB,CAAA,EAAA,UAAA,GAAA,OAAA,CAAA,GAAA;;;EAmKgB,QAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EAAA,YAAA,CAAA,EAAA,CAAA,KAAA,EAtKD,IAsKC,EAAA,EAAA,GAAA,IAAA;;;UAnKhB"}
|
package/realtime/provider.js
CHANGED
|
@@ -134,7 +134,7 @@ function isHeartbeatTimedOut(lastHeartbeat, timeoutMs) {
|
|
|
134
134
|
function resolvePublicKey(explicit) {
|
|
135
135
|
const trimmed = explicit?.trim();
|
|
136
136
|
if (trimmed) return trimmed;
|
|
137
|
-
const normalized = (process.env.
|
|
137
|
+
const normalized = (process.env.NEXT_PUBLIC_COSSISTANT_API_KEY || process.env.COSSISTANT_PUBLIC_KEY || null)?.trim();
|
|
138
138
|
return normalized && normalized.length > 0 ? normalized : null;
|
|
139
139
|
}
|
|
140
140
|
function normalizeAuth(auth) {
|
package/realtime/provider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","names":["payload: unknown"],"sources":["../../src/realtime/provider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n\ttype AnyRealtimeEvent,\n\tisValidEventType,\n\ttype RealtimeEvent,\n\tvalidateRealtimeEvent,\n} from \"@cossistant/types/realtime-events\";\nimport type React from \"react\";\nimport {\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport useWebSocket, { ReadyState } from \"react-use-websocket\";\n\nconst DEFAULT_HEARTBEAT_INTERVAL_MS = 15_000;\nconst DEFAULT_HEARTBEAT_TIMEOUT_MS = 45_000;\n\ntype SubscribeHandler = (event: AnyRealtimeEvent) => void;\n\ntype MessageDecodeResult =\n\t| {\n\t\t\ttype: \"raw-text\";\n\t\t\tdata: string;\n\t }\n\t| {\n\t\t\ttype: \"unsupported\";\n\t };\n\ntype ParsedMessage =\n\t| {\n\t\t\ttype: \"pong\";\n\t }\n\t| {\n\t\t\ttype: \"connection-established\";\n\t\t\tconnectionId: string | null;\n\t }\n\t| {\n\t\t\ttype: \"error\";\n\t\t\tmessage: string;\n\t }\n\t| {\n\t\t\ttype: \"event\";\n\t\t\tevent: AnyRealtimeEvent;\n\t }\n\t| {\n\t\t\ttype: \"invalid\";\n\t };\n\ntype VisitorAuthConfig = {\n\tkind: \"visitor\";\n\tvisitorId: string | null;\n\twebsiteId?: string | null;\n\tpublicKey?: string | null;\n};\n\ntype SessionAuthConfig = {\n\tkind: \"session\";\n\tsessionToken: string | null;\n\twebsiteId?: string | null;\n\tuserId?: string | null;\n};\n\ntype RealtimeAuthConfig = VisitorAuthConfig | SessionAuthConfig;\n\ntype ResolvedAuthConfig = {\n\ttype: \"visitor\" | \"session\";\n\tvisitorId: string | null;\n\twebsiteId: string | null;\n\tuserId: string | null;\n\tsessionToken: string | null;\n\tpublicKey: string | null;\n};\n\ntype RealtimeProviderProps = {\n\tchildren: React.ReactNode;\n\twsUrl?: string;\n\tauth: RealtimeAuthConfig | null;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\ntype RealtimeConnectionState = {\n\tisConnected: boolean;\n\tisConnecting: boolean;\n\terror: Error | null;\n\tsend: (event: AnyRealtimeEvent) => void;\n\tsendRaw: (data: string) => void;\n\tsubscribe: (handler: SubscribeHandler) => () => void;\n\tlastEvent: AnyRealtimeEvent | null;\n\tconnectionId: string | null;\n\treconnect: () => void;\n};\n\ntype RealtimeContextValue = RealtimeConnectionState & {\n\tvisitorId: string | null;\n\twebsiteId: string | null;\n\tuserId: string | null;\n};\n\nconst DEFAULT_WS_URL = \"wss://api.cossistant.com/ws\";\n\nconst RealtimeContext = createContext<RealtimeContextValue | null>(null);\n\n/**\n * Decodes WebSocket message data into a string.\n * Handles string, ArrayBuffer, and ArrayBufferView formats.\n */\nfunction decodeMessageData(data: unknown): MessageDecodeResult {\n\tif (typeof data === \"string\") {\n\t\treturn { type: \"raw-text\", data };\n\t}\n\n\tif (data instanceof ArrayBuffer) {\n\t\ttry {\n\t\t\treturn { type: \"raw-text\", data: new TextDecoder().decode(data) };\n\t\t} catch {\n\t\t\treturn { type: \"unsupported\" };\n\t\t}\n\t}\n\n\tif (ArrayBuffer.isView(data)) {\n\t\ttry {\n\t\t\treturn { type: \"raw-text\", data: new TextDecoder().decode(data.buffer) };\n\t\t} catch {\n\t\t\treturn { type: \"unsupported\" };\n\t\t}\n\t}\n\n\treturn { type: \"unsupported\" };\n}\n\n/**\n * Safely parses JSON string, returning null if invalid.\n */\nfunction parseJson(raw: string): unknown {\n\ttry {\n\t\treturn JSON.parse(raw);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Extracts a string field from an unknown object, with optional validation.\n */\nfunction extractStringField(\n\tobj: unknown,\n\tfield: string,\n\trequired = false\n): string | null {\n\tif (!obj || typeof obj !== \"object\" || !(field in obj)) {\n\t\treturn required ? null : null;\n\t}\n\tconst value = (obj as Record<string, unknown>)[field];\n\tif (typeof value === \"string\" && value.length > 0) {\n\t\treturn value;\n\t}\n\treturn required ? null : null;\n}\n\n/**\n * Parses a WebSocket message and determines its type and content.\n */\nfunction parseWebSocketMessage(rawText: string): ParsedMessage {\n\t// Handle pong heartbeat\n\tif (rawText === \"pong\") {\n\t\treturn { type: \"pong\" };\n\t}\n\n\t// Try to parse as JSON\n\tconst parsed = parseJson(rawText);\n\tif (!parsed || typeof parsed !== \"object\") {\n\t\treturn { type: \"invalid\" };\n\t}\n\n\tconst messageType = extractStringField(parsed, \"type\");\n\n\t// Handle CONNECTION_ESTABLISHED\n\tif (messageType === \"CONNECTION_ESTABLISHED\") {\n\t\tconst payload = (parsed as { payload?: unknown }).payload;\n\t\tconst connectionId = extractStringField(payload, \"connectionId\");\n\t\treturn { type: \"connection-established\", connectionId };\n\t}\n\n\t// Handle error messages\n\tif (\"error\" in parsed && \"message\" in parsed) {\n\t\tconst message =\n\t\t\textractStringField(parsed, \"message\") || \"Realtime connection error\";\n\t\treturn { type: \"error\", message };\n\t}\n\n\t// Handle realtime events\n\tif (messageType && isValidEventType(messageType)) {\n\t\ttry {\n\t\t\tconst event = constructRealtimeEvent(parsed);\n\t\t\tif (!event) {\n\t\t\t\treturn { type: \"invalid\" };\n\t\t\t}\n\t\t\treturn { type: \"event\", event };\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[Realtime] Failed to construct event\", error);\n\t\t\treturn { type: \"invalid\" };\n\t\t}\n\t}\n\n\treturn { type: \"invalid\" };\n}\n\n/**\n * Constructs a RealtimeEvent from parsed JSON data.\n * Returns null if required fields are missing or validation fails.\n */\nfunction constructRealtimeEvent(parsed: unknown): AnyRealtimeEvent | null {\n\tif (!parsed || typeof parsed !== \"object\" || !(\"type\" in parsed)) {\n\t\treturn null;\n\t}\n\n\tconst type = (parsed as { type: unknown }).type;\n\tif (!isValidEventType(type)) {\n\t\treturn null;\n\t}\n\n\tconst eventType = type;\n\n\t// Extract payload directly\n\tconst payloadSource = (parsed as { payload?: unknown }).payload;\n\n\tlet payload: unknown;\n\ttry {\n\t\tpayload = validateRealtimeEvent(eventType, payloadSource);\n\t} catch (error) {\n\t\tconsole.error(\"[Realtime] Received invalid event payload\", error);\n\t\treturn null;\n\t}\n\n\tconst organizationId = extractStringField(\n\t\tpayloadSource,\n\t\t\"organizationId\",\n\t\ttrue\n\t);\n\tconst websiteId = extractStringField(payloadSource, \"websiteId\", true);\n\n\tif (!organizationId) {\n\t\tconsole.error(\"[Realtime] Received event without organizationId\", parsed);\n\t\treturn null;\n\t}\n\n\tif (!websiteId) {\n\t\tconsole.error(\"[Realtime] Received event without websiteId\", parsed);\n\t\treturn null;\n\t}\n\n\tconst visitorId = extractStringField(parsed, \"visitorId\");\n\n\treturn {\n\t\ttype: eventType,\n\t\tpayload,\n\t\torganizationId,\n\t\twebsiteId,\n\t\tvisitorId,\n\t} as AnyRealtimeEvent;\n}\n\n/**\n * Checks if heartbeat has timed out.\n */\nfunction isHeartbeatTimedOut(\n\tlastHeartbeat: number,\n\ttimeoutMs: number\n): boolean {\n\tconst elapsed = Date.now() - lastHeartbeat;\n\treturn elapsed > timeoutMs;\n}\n\nfunction resolvePublicKey(explicit?: string | null): string | null {\n\tconst trimmed = explicit?.trim();\n\tif (trimmed) {\n\t\treturn trimmed;\n\t}\n\n\tconst fromEnv =\n\t\tprocess.env.NEXT_PUBLIC_COSSISTANT_KEY ||\n\t\tprocess.env.COSSISTANT_PUBLIC_KEY ||\n\t\tnull;\n\n\tconst normalized = fromEnv?.trim();\n\treturn normalized && normalized.length > 0 ? normalized : null;\n}\n\nfunction normalizeAuth(\n\tauth: RealtimeAuthConfig | null\n): ResolvedAuthConfig | null {\n\tif (!auth) {\n\t\treturn null;\n\t}\n\n\tif (auth.kind === \"visitor\") {\n\t\tconst visitorId = auth.visitorId?.trim() || null;\n\n\t\tif (!visitorId) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\ttype: \"visitor\",\n\t\t\tvisitorId,\n\t\t\twebsiteId: auth.websiteId?.trim() || null,\n\t\t\tuserId: null,\n\t\t\tsessionToken: null,\n\t\t\tpublicKey: resolvePublicKey(auth.publicKey ?? null),\n\t\t} satisfies ResolvedAuthConfig;\n\t}\n\n\tconst sessionToken = auth.sessionToken?.trim() || null;\n\n\tif (!sessionToken) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\ttype: \"session\",\n\t\tvisitorId: null,\n\t\twebsiteId: auth.websiteId?.trim() || null,\n\t\tuserId: auth.userId?.trim() || null,\n\t\tsessionToken,\n\t\tpublicKey: null,\n\t} satisfies ResolvedAuthConfig;\n}\n\nfunction buildSocketUrl(\n\tbaseUrl: string,\n\tauth: ResolvedAuthConfig | null\n): string | null {\n\tif (!auth) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst url = new URL(baseUrl);\n\n\t\tif (auth.type === \"visitor\") {\n\t\t\turl.searchParams.set(\"visitorId\", auth.visitorId ?? \"\");\n\t\t\tconst publicKey = auth.publicKey;\n\t\t\tif (publicKey) {\n\t\t\t\turl.searchParams.set(\"publicKey\", publicKey);\n\t\t\t}\n\t\t} else {\n\t\t\turl.searchParams.set(\"sessionToken\", auth.sessionToken ?? \"\");\n\t\t\tif (auth.websiteId) {\n\t\t\t\turl.searchParams.set(\"websiteId\", auth.websiteId);\n\t\t\t}\n\t\t}\n\n\t\treturn url.toString();\n\t} catch (error) {\n\t\tconsole.error(\"[Realtime] Failed to build WebSocket URL\", error);\n\t\treturn null;\n\t}\n}\n\n/**\n * Provides websocket connectivity and heartbeating logic for realtime events.\n */\nexport function RealtimeProvider({\n\tchildren,\n\twsUrl = DEFAULT_WS_URL,\n\tauth,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}: RealtimeProviderProps): React.ReactElement {\n\tconst normalizedAuth = normalizeAuth(auth);\n\n\tconst socketUrl = buildSocketUrl(wsUrl, normalizedAuth);\n\tconst eventHandlersRef = useRef<Set<SubscribeHandler>>(new Set());\n\tconst lastHeartbeatRef = useRef<number>(Date.now());\n\tconst hasOpenedRef = useRef(false);\n\tconst previousUrlRef = useRef<string | null>(null);\n\tconst [connectionError, setConnectionError] = useState<Error | null>(null);\n\tconst [lastEvent, setLastEvent] = useState<AnyRealtimeEvent | null>(null);\n\tconst [connectionId, setConnectionId] = useState<string | null>(null);\n\n\tconst heartbeatIntervalMs = DEFAULT_HEARTBEAT_INTERVAL_MS;\n\tconst heartbeatTimeoutMs = DEFAULT_HEARTBEAT_TIMEOUT_MS;\n\n\tconst canConnect = Boolean(autoConnect && socketUrl);\n\tconst connectionUrl = canConnect ? socketUrl : null;\n\n\t// Track URL changes to detect when connection is being replaced\n\tuseEffect(() => {\n\t\tif (connectionUrl !== previousUrlRef.current) {\n\t\t\tpreviousUrlRef.current = connectionUrl;\n\t\t\t// Reset hasOpenedRef when URL changes so we know a new connection is starting\n\t\t\thasOpenedRef.current = false;\n\t\t}\n\t}, [connectionUrl]);\n\n\tconst {\n\t\tsendMessage,\n\t\tsendJsonMessage,\n\t\tlastMessage,\n\t\treadyState,\n\t\tgetWebSocket,\n\t} = useWebSocket(\n\t\tconnectionUrl,\n\t\t{\n\t\t\tshouldReconnect: (closeEvent) => {\n\t\t\t\tif (!canConnect) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (closeEvent.code === 1008 || closeEvent.code === 1011) {\n\t\t\t\t\tconst err = new Error(\n\t\t\t\t\t\tcloseEvent.reason ||\n\t\t\t\t\t\t\t\"Realtime connection closed by server. Please check your credentials.\"\n\t\t\t\t\t);\n\t\t\t\t\tsetConnectionError(err);\n\t\t\t\t\tonError?.(err);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\treconnectAttempts: autoConnect ? undefined : 0,\n\t\t\treconnectInterval: (attempt) => {\n\t\t\t\tconst base = 500 * 2 ** attempt;\n\t\t\t\treturn Math.min(base, 30_000);\n\t\t\t},\n\t\t\tretryOnError: false,\n\t\t\tonOpen: () => {\n\t\t\t\thasOpenedRef.current = true;\n\t\t\t\tsetConnectionError(null);\n\t\t\t\tlastHeartbeatRef.current = Date.now();\n\t\t\t\tonConnect?.();\n\t\t\t},\n\t\t\tonClose: () => {\n\t\t\t\tsetConnectionId(null);\n\t\t\t\tonDisconnect?.();\n\t\t\t},\n\t\t\tonError: (event) => {\n\t\t\t\tif (!canConnect) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst socketLike = event.target;\n\t\t\t\tconst currentSocket = getWebSocket();\n\t\t\t\tconst isBrowserSocket =\n\t\t\t\t\ttypeof WebSocket !== \"undefined\" && socketLike instanceof WebSocket;\n\t\t\t\tconst socketState = isBrowserSocket ? socketLike.readyState : undefined;\n\n\t\t\t\t// Only suppress errors for THIS provider's socket, not other nested providers\n\t\t\t\t// Check if the errored socket belongs to this provider instance\n\t\t\t\tconst isThisProvidersSocket = currentSocket === socketLike;\n\n\t\t\t\t// Suppress errors if:\n\t\t\t\t// 1. This socket was replaced (URL changed while connecting) - only for this provider\n\t\t\t\t// 2. Connection URL is null (component unmounting or disabled)\n\t\t\t\t// 3. Socket is in CLOSING/CLOSED state and hasn't opened (cleanup/unmount) - only for this provider\n\t\t\t\tif (\n\t\t\t\t\t(!isThisProvidersSocket && currentSocket) ||\n\t\t\t\t\t!connectionUrl ||\n\t\t\t\t\t(isThisProvidersSocket &&\n\t\t\t\t\t\t!hasOpenedRef.current &&\n\t\t\t\t\t\t(socketState === WebSocket.CLOSING ||\n\t\t\t\t\t\t\tsocketState === WebSocket.CLOSED))\n\t\t\t\t) {\n\t\t\t\t\t// Suppress these expected errors during connection replacement or cleanup\n\t\t\t\t\t// But only if it's THIS provider's socket being replaced\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// For errors that occur during CONNECTING state, check if URL changed\n\t\t\t\t// Only suppress if it's this provider's socket\n\t\t\t\tif (\n\t\t\t\t\tisThisProvidersSocket &&\n\t\t\t\t\t!hasOpenedRef.current &&\n\t\t\t\t\tsocketState === WebSocket.CONNECTING &&\n\t\t\t\t\tconnectionUrl !== previousUrlRef.current\n\t\t\t\t) {\n\t\t\t\t\t// URL changed while connecting, suppress error\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst err = new Error(`WebSocket error: ${event.type}`);\n\t\t\t\tsetConnectionError(err);\n\t\t\t\tonError?.(err);\n\t\t\t},\n\t\t},\n\t\tcanConnect\n\t);\n\n\tuseEffect(() => {\n\t\tif (!lastMessage) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Decode message data from various formats\n\t\tconst decoded = decodeMessageData(lastMessage.data);\n\t\tif (decoded.type === \"unsupported\") {\n\t\t\treturn;\n\t\t}\n\n\t\t// Parse the message and determine its type\n\t\tconst message = parseWebSocketMessage(decoded.data);\n\n\t\t// Handle different message types\n\t\tswitch (message.type) {\n\t\t\tcase \"pong\":\n\t\t\t\tlastHeartbeatRef.current = Date.now();\n\t\t\t\tbreak;\n\n\t\t\tcase \"connection-established\":\n\t\t\t\tsetConnectionId(message.connectionId);\n\t\t\t\tlastHeartbeatRef.current = Date.now();\n\t\t\t\tbreak;\n\n\t\t\tcase \"error\": {\n\t\t\t\tconst err = new Error(message.message);\n\t\t\t\tsetConnectionError(err);\n\t\t\t\tonError?.(err);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"event\":\n\t\t\t\tlastHeartbeatRef.current = Date.now();\n\t\t\t\tsetLastEvent(message.event);\n\t\t\t\tfor (const handler of eventHandlersRef.current) {\n\t\t\t\t\tPromise.resolve(handler(message.event)).catch((error) => {\n\t\t\t\t\t\tconst err =\n\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t: new Error(`Subscriber threw an exception: ${String(error)}`);\n\t\t\t\t\t\tonError?.(err);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// Silently ignore invalid or unknown messages\n\t\t\t\tbreak;\n\t\t}\n\t}, [lastMessage, onError]);\n\n\tuseEffect(() => {\n\t\tif (!canConnect) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst interval = window.setInterval(() => {\n\t\t\tif (readyState !== ReadyState.OPEN) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check if heartbeat has timed out\n\t\t\tif (isHeartbeatTimedOut(lastHeartbeatRef.current, heartbeatTimeoutMs)) {\n\t\t\t\tconst socket = getWebSocket();\n\t\t\t\tsocket?.close(4000, \"Heartbeat timeout\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Send ping to keep connection alive\n\t\t\ttry {\n\t\t\t\tsendMessage(\"ping\");\n\t\t\t} catch {\n\t\t\t\t// Ignore send failures; reconnect logic will handle it\n\t\t\t}\n\t\t}, heartbeatIntervalMs);\n\n\t\treturn () => {\n\t\t\twindow.clearInterval(interval);\n\t\t};\n\t}, [\n\t\tcanConnect,\n\t\theartbeatIntervalMs,\n\t\theartbeatTimeoutMs,\n\t\treadyState,\n\t\tsendMessage,\n\t\tgetWebSocket,\n\t]);\n\n\tconst send = useCallback(\n\t\t(event: AnyRealtimeEvent) => {\n\t\t\tif (!connectionUrl) {\n\t\t\t\tthrow new Error(\"Realtime connection is disabled\");\n\t\t\t}\n\n\t\t\tif (readyState !== ReadyState.OPEN) {\n\t\t\t\tthrow new Error(\"Realtime connection is not established\");\n\t\t\t}\n\n\t\t\tsendJsonMessage(event);\n\t\t},\n\t\t[connectionUrl, readyState, sendJsonMessage]\n\t);\n\n\tconst sendRaw = useCallback(\n\t\t(data: string) => {\n\t\t\tif (!connectionUrl) {\n\t\t\t\tthrow new Error(\"Realtime connection is disabled\");\n\t\t\t}\n\n\t\t\tif (readyState !== ReadyState.OPEN) {\n\t\t\t\tthrow new Error(\"Realtime connection is not established\");\n\t\t\t}\n\n\t\t\tsendMessage(data);\n\t\t},\n\t\t[connectionUrl, readyState, sendMessage]\n\t);\n\n\tconst subscribe = useCallback((handler: SubscribeHandler) => {\n\t\teventHandlersRef.current.add(handler);\n\t\treturn () => {\n\t\t\teventHandlersRef.current.delete(handler);\n\t\t};\n\t}, []);\n\n\tconst reconnect = useCallback(() => {\n\t\tconst socket = getWebSocket();\n\t\tsocket?.close();\n\t}, [getWebSocket]);\n\n\tconst connection = useMemo<RealtimeConnectionState>(\n\t\t() => ({\n\t\t\tisConnected: readyState === ReadyState.OPEN,\n\t\t\tisConnecting: readyState === ReadyState.CONNECTING,\n\t\t\terror: connectionError,\n\t\t\tsend,\n\t\t\tsendRaw,\n\t\t\tsubscribe,\n\t\t\tlastEvent,\n\t\t\tconnectionId,\n\t\t\treconnect,\n\t\t}),\n\t\t[\n\t\t\treadyState,\n\t\t\tconnectionError,\n\t\t\tsend,\n\t\t\tsendRaw,\n\t\t\tsubscribe,\n\t\t\tlastEvent,\n\t\t\tconnectionId,\n\t\t\treconnect,\n\t\t]\n\t);\n\n\tconst value = useMemo<RealtimeContextValue>(\n\t\t() => ({\n\t\t\t...connection,\n\t\t\tvisitorId: normalizedAuth?.visitorId ?? null,\n\t\t\twebsiteId: normalizedAuth?.websiteId ?? null,\n\t\t\tuserId: normalizedAuth?.userId ?? null,\n\t\t}),\n\t\t[\n\t\t\tconnection,\n\t\t\tnormalizedAuth?.visitorId,\n\t\t\tnormalizedAuth?.websiteId,\n\t\t\tnormalizedAuth?.userId,\n\t\t]\n\t);\n\n\treturn (\n\t\t<RealtimeContext.Provider value={value}>\n\t\t\t{children}\n\t\t</RealtimeContext.Provider>\n\t);\n}\n\n/**\n * Returns the realtime connection context.\n */\nexport function useRealtimeConnection(): RealtimeContextValue {\n\tconst context = useContext(RealtimeContext);\n\tif (!context) {\n\t\tthrow new Error(\n\t\t\t\"useRealtimeConnection must be used within RealtimeProvider\"\n\t\t);\n\t}\n\n\treturn context;\n}\n\nexport type { RealtimeContextValue };\nexport type { RealtimeAuthConfig };\nexport type { RealtimeProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":";;;;;;;;;AAoBA,MAAM,gCAAgC;AACtC,MAAM,+BAA+B;AAsFrC,MAAM,iBAAiB;AAEvB,MAAM,kBAAkB,cAA2C,KAAK;;;;;AAMxE,SAAS,kBAAkB,MAAoC;AAC9D,KAAI,OAAO,SAAS,SACnB,QAAO;EAAE,MAAM;EAAY;EAAM;AAGlC,KAAI,gBAAgB,YACnB,KAAI;AACH,SAAO;GAAE,MAAM;GAAY,MAAM,IAAI,aAAa,CAAC,OAAO,KAAK;GAAE;SAC1D;AACP,SAAO,EAAE,MAAM,eAAe;;AAIhC,KAAI,YAAY,OAAO,KAAK,CAC3B,KAAI;AACH,SAAO;GAAE,MAAM;GAAY,MAAM,IAAI,aAAa,CAAC,OAAO,KAAK,OAAO;GAAE;SACjE;AACP,SAAO,EAAE,MAAM,eAAe;;AAIhC,QAAO,EAAE,MAAM,eAAe;;;;;AAM/B,SAAS,UAAU,KAAsB;AACxC,KAAI;AACH,SAAO,KAAK,MAAM,IAAI;SACf;AACP,SAAO;;;;;;AAOT,SAAS,mBACR,KACA,OACA,WAAW,OACK;AAChB,KAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,EAAE,SAAS,KACjD,QAAO,WAAW,OAAO;CAE1B,MAAM,QAAS,IAAgC;AAC/C,KAAI,OAAO,UAAU,YAAY,MAAM,SAAS,EAC/C,QAAO;AAER,QAAO,WAAW,OAAO;;;;;AAM1B,SAAS,sBAAsB,SAAgC;AAE9D,KAAI,YAAY,OACf,QAAO,EAAE,MAAM,QAAQ;CAIxB,MAAM,SAAS,UAAU,QAAQ;AACjC,KAAI,CAAC,UAAU,OAAO,WAAW,SAChC,QAAO,EAAE,MAAM,WAAW;CAG3B,MAAM,cAAc,mBAAmB,QAAQ,OAAO;AAGtD,KAAI,gBAAgB,0BAA0B;EAC7C,MAAM,UAAW,OAAiC;AAElD,SAAO;GAAE,MAAM;GAA0B,cADpB,mBAAmB,SAAS,eAAe;GACT;;AAIxD,KAAI,WAAW,UAAU,aAAa,OAGrC,QAAO;EAAE,MAAM;EAAS,SADvB,mBAAmB,QAAQ,UAAU,IAAI;EACT;AAIlC,KAAI,eAAe,iBAAiB,YAAY,CAC/C,KAAI;EACH,MAAM,QAAQ,uBAAuB,OAAO;AAC5C,MAAI,CAAC,MACJ,QAAO,EAAE,MAAM,WAAW;AAE3B,SAAO;GAAE,MAAM;GAAS;GAAO;UACvB,OAAO;AACf,UAAQ,MAAM,wCAAwC,MAAM;AAC5D,SAAO,EAAE,MAAM,WAAW;;AAI5B,QAAO,EAAE,MAAM,WAAW;;;;;;AAO3B,SAAS,uBAAuB,QAA0C;AACzE,KAAI,CAAC,UAAU,OAAO,WAAW,YAAY,EAAE,UAAU,QACxD,QAAO;CAGR,MAAM,OAAQ,OAA6B;AAC3C,KAAI,CAAC,iBAAiB,KAAK,CAC1B,QAAO;CAGR,MAAM,YAAY;CAGlB,MAAM,gBAAiB,OAAiC;CAExD,IAAIA;AACJ,KAAI;AACH,YAAU,sBAAsB,WAAW,cAAc;UACjD,OAAO;AACf,UAAQ,MAAM,6CAA6C,MAAM;AACjE,SAAO;;CAGR,MAAM,iBAAiB,mBACtB,eACA,kBACA,KACA;CACD,MAAM,YAAY,mBAAmB,eAAe,aAAa,KAAK;AAEtE,KAAI,CAAC,gBAAgB;AACpB,UAAQ,MAAM,oDAAoD,OAAO;AACzE,SAAO;;AAGR,KAAI,CAAC,WAAW;AACf,UAAQ,MAAM,+CAA+C,OAAO;AACpE,SAAO;;CAGR,MAAM,YAAY,mBAAmB,QAAQ,YAAY;AAEzD,QAAO;EACN,MAAM;EACN;EACA;EACA;EACA;EACA;;;;;AAMF,SAAS,oBACR,eACA,WACU;AAEV,QADgB,KAAK,KAAK,GAAG,gBACZ;;AAGlB,SAAS,iBAAiB,UAAyC;CAClE,MAAM,UAAU,UAAU,MAAM;AAChC,KAAI,QACH,QAAO;CAQR,MAAM,cAJL,QAAQ,IAAI,8BACZ,QAAQ,IAAI,yBACZ,OAE2B,MAAM;AAClC,QAAO,cAAc,WAAW,SAAS,IAAI,aAAa;;AAG3D,SAAS,cACR,MAC4B;AAC5B,KAAI,CAAC,KACJ,QAAO;AAGR,KAAI,KAAK,SAAS,WAAW;EAC5B,MAAM,YAAY,KAAK,WAAW,MAAM,IAAI;AAE5C,MAAI,CAAC,UACJ,QAAO;AAGR,SAAO;GACN,MAAM;GACN;GACA,WAAW,KAAK,WAAW,MAAM,IAAI;GACrC,QAAQ;GACR,cAAc;GACd,WAAW,iBAAiB,KAAK,aAAa,KAAK;GACnD;;CAGF,MAAM,eAAe,KAAK,cAAc,MAAM,IAAI;AAElD,KAAI,CAAC,aACJ,QAAO;AAGR,QAAO;EACN,MAAM;EACN,WAAW;EACX,WAAW,KAAK,WAAW,MAAM,IAAI;EACrC,QAAQ,KAAK,QAAQ,MAAM,IAAI;EAC/B;EACA,WAAW;EACX;;AAGF,SAAS,eACR,SACA,MACgB;AAChB,KAAI,CAAC,KACJ,QAAO;AAGR,KAAI;EACH,MAAM,MAAM,IAAI,IAAI,QAAQ;AAE5B,MAAI,KAAK,SAAS,WAAW;AAC5B,OAAI,aAAa,IAAI,aAAa,KAAK,aAAa,GAAG;GACvD,MAAM,YAAY,KAAK;AACvB,OAAI,UACH,KAAI,aAAa,IAAI,aAAa,UAAU;SAEvC;AACN,OAAI,aAAa,IAAI,gBAAgB,KAAK,gBAAgB,GAAG;AAC7D,OAAI,KAAK,UACR,KAAI,aAAa,IAAI,aAAa,KAAK,UAAU;;AAInD,SAAO,IAAI,UAAU;UACb,OAAO;AACf,UAAQ,MAAM,4CAA4C,MAAM;AAChE,SAAO;;;;;;AAOT,SAAgB,iBAAiB,EAChC,UACA,QAAQ,gBACR,MACA,cAAc,MACd,WACA,cACA,WAC6C;CAC7C,MAAM,iBAAiB,cAAc,KAAK;CAE1C,MAAM,YAAY,eAAe,OAAO,eAAe;CACvD,MAAM,mBAAmB,uBAA8B,IAAI,KAAK,CAAC;CACjE,MAAM,mBAAmB,OAAe,KAAK,KAAK,CAAC;CACnD,MAAM,eAAe,OAAO,MAAM;CAClC,MAAM,iBAAiB,OAAsB,KAAK;CAClD,MAAM,CAAC,iBAAiB,sBAAsB,SAAuB,KAAK;CAC1E,MAAM,CAAC,WAAW,gBAAgB,SAAkC,KAAK;CACzE,MAAM,CAAC,cAAc,mBAAmB,SAAwB,KAAK;CAErE,MAAM,sBAAsB;CAC5B,MAAM,qBAAqB;CAE3B,MAAM,aAAa,QAAQ,eAAe,UAAU;CACpD,MAAM,gBAAgB,aAAa,YAAY;AAG/C,iBAAgB;AACf,MAAI,kBAAkB,eAAe,SAAS;AAC7C,kBAAe,UAAU;AAEzB,gBAAa,UAAU;;IAEtB,CAAC,cAAc,CAAC;CAEnB,MAAM,EACL,aACA,iBACA,aACA,YACA,iBACG,aACH,eACA;EACC,kBAAkB,eAAe;AAChC,OAAI,CAAC,WACJ,QAAO;AAGR,OAAI,WAAW,SAAS,QAAQ,WAAW,SAAS,MAAM;IACzD,MAAM,MAAM,IAAI,MACf,WAAW,UACV,uEACD;AACD,uBAAmB,IAAI;AACvB,cAAU,IAAI;AACd,WAAO;;AAGR,UAAO;;EAER,mBAAmB,cAAc,SAAY;EAC7C,oBAAoB,YAAY;GAC/B,MAAM,OAAO,MAAM,KAAK;AACxB,UAAO,KAAK,IAAI,MAAM,IAAO;;EAE9B,cAAc;EACd,cAAc;AACb,gBAAa,UAAU;AACvB,sBAAmB,KAAK;AACxB,oBAAiB,UAAU,KAAK,KAAK;AACrC,gBAAa;;EAEd,eAAe;AACd,mBAAgB,KAAK;AACrB,mBAAgB;;EAEjB,UAAU,UAAU;AACnB,OAAI,CAAC,WACJ;GAGD,MAAM,aAAa,MAAM;GACzB,MAAM,gBAAgB,cAAc;GAGpC,MAAM,cADL,OAAO,cAAc,eAAe,sBAAsB,YACrB,WAAW,aAAa;GAI9D,MAAM,wBAAwB,kBAAkB;AAMhD,OACE,CAAC,yBAAyB,iBAC3B,CAAC,iBACA,yBACA,CAAC,aAAa,YACb,gBAAgB,UAAU,WAC1B,gBAAgB,UAAU,QAI5B;AAKD,OACC,yBACA,CAAC,aAAa,WACd,gBAAgB,UAAU,cAC1B,kBAAkB,eAAe,QAGjC;GAGD,MAAM,sBAAM,IAAI,MAAM,oBAAoB,MAAM,OAAO;AACvD,sBAAmB,IAAI;AACvB,aAAU,IAAI;;EAEf,EACD,WACA;AAED,iBAAgB;AACf,MAAI,CAAC,YACJ;EAID,MAAM,UAAU,kBAAkB,YAAY,KAAK;AACnD,MAAI,QAAQ,SAAS,cACpB;EAID,MAAM,UAAU,sBAAsB,QAAQ,KAAK;AAGnD,UAAQ,QAAQ,MAAhB;GACC,KAAK;AACJ,qBAAiB,UAAU,KAAK,KAAK;AACrC;GAED,KAAK;AACJ,oBAAgB,QAAQ,aAAa;AACrC,qBAAiB,UAAU,KAAK,KAAK;AACrC;GAED,KAAK,SAAS;IACb,MAAM,MAAM,IAAI,MAAM,QAAQ,QAAQ;AACtC,uBAAmB,IAAI;AACvB,cAAU,IAAI;AACd;;GAGD,KAAK;AACJ,qBAAiB,UAAU,KAAK,KAAK;AACrC,iBAAa,QAAQ,MAAM;AAC3B,SAAK,MAAM,WAAW,iBAAiB,QACtC,SAAQ,QAAQ,QAAQ,QAAQ,MAAM,CAAC,CAAC,OAAO,UAAU;KACxD,MAAM,MACL,iBAAiB,QACd,wBACA,IAAI,MAAM,kCAAkC,OAAO,MAAM,GAAG;AAChE,eAAU,IAAI;MACb;AAEH;GAED,QAEC;;IAEA,CAAC,aAAa,QAAQ,CAAC;AAE1B,iBAAgB;AACf,MAAI,CAAC,WACJ;EAGD,MAAM,WAAW,OAAO,kBAAkB;AACzC,OAAI,eAAe,WAAW,KAC7B;AAID,OAAI,oBAAoB,iBAAiB,SAAS,mBAAmB,EAAE;AAEtE,IADe,cAAc,EACrB,MAAM,KAAM,oBAAoB;AACxC;;AAID,OAAI;AACH,gBAAY,OAAO;WACZ;KAGN,oBAAoB;AAEvB,eAAa;AACZ,UAAO,cAAc,SAAS;;IAE7B;EACF;EACA;EACA;EACA;EACA;EACA;EACA,CAAC;CAEF,MAAM,OAAO,aACX,UAA4B;AAC5B,MAAI,CAAC,cACJ,OAAM,IAAI,MAAM,kCAAkC;AAGnD,MAAI,eAAe,WAAW,KAC7B,OAAM,IAAI,MAAM,yCAAyC;AAG1D,kBAAgB,MAAM;IAEvB;EAAC;EAAe;EAAY;EAAgB,CAC5C;CAED,MAAM,UAAU,aACd,SAAiB;AACjB,MAAI,CAAC,cACJ,OAAM,IAAI,MAAM,kCAAkC;AAGnD,MAAI,eAAe,WAAW,KAC7B,OAAM,IAAI,MAAM,yCAAyC;AAG1D,cAAY,KAAK;IAElB;EAAC;EAAe;EAAY;EAAY,CACxC;CAED,MAAM,YAAY,aAAa,YAA8B;AAC5D,mBAAiB,QAAQ,IAAI,QAAQ;AACrC,eAAa;AACZ,oBAAiB,QAAQ,OAAO,QAAQ;;IAEvC,EAAE,CAAC;CAEN,MAAM,YAAY,kBAAkB;AAEnC,EADe,cAAc,EACrB,OAAO;IACb,CAAC,aAAa,CAAC;CAElB,MAAM,aAAa,eACX;EACN,aAAa,eAAe,WAAW;EACvC,cAAc,eAAe,WAAW;EACxC,OAAO;EACP;EACA;EACA;EACA;EACA;EACA;EACA,GACD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,CACD;CAED,MAAM,QAAQ,eACN;EACN,GAAG;EACH,WAAW,gBAAgB,aAAa;EACxC,WAAW,gBAAgB,aAAa;EACxC,QAAQ,gBAAgB,UAAU;EAClC,GACD;EACC;EACA,gBAAgB;EAChB,gBAAgB;EAChB,gBAAgB;EAChB,CACD;AAED,QACC,oBAAC,gBAAgB;EAAgB;EAC/B;GACyB;;;;;AAO7B,SAAgB,wBAA8C;CAC7D,MAAM,UAAU,WAAW,gBAAgB;AAC3C,KAAI,CAAC,QACJ,OAAM,IAAI,MACT,6DACA;AAGF,QAAO"}
|
|
1
|
+
{"version":3,"file":"provider.js","names":["payload: unknown"],"sources":["../../src/realtime/provider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n\ttype AnyRealtimeEvent,\n\tisValidEventType,\n\ttype RealtimeEvent,\n\tvalidateRealtimeEvent,\n} from \"@cossistant/types/realtime-events\";\nimport type React from \"react\";\nimport {\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport useWebSocket, { ReadyState } from \"react-use-websocket\";\n\nconst DEFAULT_HEARTBEAT_INTERVAL_MS = 15_000;\nconst DEFAULT_HEARTBEAT_TIMEOUT_MS = 45_000;\n\ntype SubscribeHandler = (event: AnyRealtimeEvent) => void;\n\ntype MessageDecodeResult =\n\t| {\n\t\t\ttype: \"raw-text\";\n\t\t\tdata: string;\n\t }\n\t| {\n\t\t\ttype: \"unsupported\";\n\t };\n\ntype ParsedMessage =\n\t| {\n\t\t\ttype: \"pong\";\n\t }\n\t| {\n\t\t\ttype: \"connection-established\";\n\t\t\tconnectionId: string | null;\n\t }\n\t| {\n\t\t\ttype: \"error\";\n\t\t\tmessage: string;\n\t }\n\t| {\n\t\t\ttype: \"event\";\n\t\t\tevent: AnyRealtimeEvent;\n\t }\n\t| {\n\t\t\ttype: \"invalid\";\n\t };\n\ntype VisitorAuthConfig = {\n\tkind: \"visitor\";\n\tvisitorId: string | null;\n\twebsiteId?: string | null;\n\tpublicKey?: string | null;\n};\n\ntype SessionAuthConfig = {\n\tkind: \"session\";\n\tsessionToken: string | null;\n\twebsiteId?: string | null;\n\tuserId?: string | null;\n};\n\ntype RealtimeAuthConfig = VisitorAuthConfig | SessionAuthConfig;\n\ntype ResolvedAuthConfig = {\n\ttype: \"visitor\" | \"session\";\n\tvisitorId: string | null;\n\twebsiteId: string | null;\n\tuserId: string | null;\n\tsessionToken: string | null;\n\tpublicKey: string | null;\n};\n\ntype RealtimeProviderProps = {\n\tchildren: React.ReactNode;\n\twsUrl?: string;\n\tauth: RealtimeAuthConfig | null;\n\tautoConnect?: boolean;\n\tonConnect?: () => void;\n\tonDisconnect?: () => void;\n\tonError?: (error: Error) => void;\n};\n\ntype RealtimeConnectionState = {\n\tisConnected: boolean;\n\tisConnecting: boolean;\n\terror: Error | null;\n\tsend: (event: AnyRealtimeEvent) => void;\n\tsendRaw: (data: string) => void;\n\tsubscribe: (handler: SubscribeHandler) => () => void;\n\tlastEvent: AnyRealtimeEvent | null;\n\tconnectionId: string | null;\n\treconnect: () => void;\n};\n\ntype RealtimeContextValue = RealtimeConnectionState & {\n\tvisitorId: string | null;\n\twebsiteId: string | null;\n\tuserId: string | null;\n};\n\nconst DEFAULT_WS_URL = \"wss://api.cossistant.com/ws\";\n\nconst RealtimeContext = createContext<RealtimeContextValue | null>(null);\n\n/**\n * Decodes WebSocket message data into a string.\n * Handles string, ArrayBuffer, and ArrayBufferView formats.\n */\nfunction decodeMessageData(data: unknown): MessageDecodeResult {\n\tif (typeof data === \"string\") {\n\t\treturn { type: \"raw-text\", data };\n\t}\n\n\tif (data instanceof ArrayBuffer) {\n\t\ttry {\n\t\t\treturn { type: \"raw-text\", data: new TextDecoder().decode(data) };\n\t\t} catch {\n\t\t\treturn { type: \"unsupported\" };\n\t\t}\n\t}\n\n\tif (ArrayBuffer.isView(data)) {\n\t\ttry {\n\t\t\treturn { type: \"raw-text\", data: new TextDecoder().decode(data.buffer) };\n\t\t} catch {\n\t\t\treturn { type: \"unsupported\" };\n\t\t}\n\t}\n\n\treturn { type: \"unsupported\" };\n}\n\n/**\n * Safely parses JSON string, returning null if invalid.\n */\nfunction parseJson(raw: string): unknown {\n\ttry {\n\t\treturn JSON.parse(raw);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Extracts a string field from an unknown object, with optional validation.\n */\nfunction extractStringField(\n\tobj: unknown,\n\tfield: string,\n\trequired = false\n): string | null {\n\tif (!obj || typeof obj !== \"object\" || !(field in obj)) {\n\t\treturn required ? null : null;\n\t}\n\tconst value = (obj as Record<string, unknown>)[field];\n\tif (typeof value === \"string\" && value.length > 0) {\n\t\treturn value;\n\t}\n\treturn required ? null : null;\n}\n\n/**\n * Parses a WebSocket message and determines its type and content.\n */\nfunction parseWebSocketMessage(rawText: string): ParsedMessage {\n\t// Handle pong heartbeat\n\tif (rawText === \"pong\") {\n\t\treturn { type: \"pong\" };\n\t}\n\n\t// Try to parse as JSON\n\tconst parsed = parseJson(rawText);\n\tif (!parsed || typeof parsed !== \"object\") {\n\t\treturn { type: \"invalid\" };\n\t}\n\n\tconst messageType = extractStringField(parsed, \"type\");\n\n\t// Handle CONNECTION_ESTABLISHED\n\tif (messageType === \"CONNECTION_ESTABLISHED\") {\n\t\tconst payload = (parsed as { payload?: unknown }).payload;\n\t\tconst connectionId = extractStringField(payload, \"connectionId\");\n\t\treturn { type: \"connection-established\", connectionId };\n\t}\n\n\t// Handle error messages\n\tif (\"error\" in parsed && \"message\" in parsed) {\n\t\tconst message =\n\t\t\textractStringField(parsed, \"message\") || \"Realtime connection error\";\n\t\treturn { type: \"error\", message };\n\t}\n\n\t// Handle realtime events\n\tif (messageType && isValidEventType(messageType)) {\n\t\ttry {\n\t\t\tconst event = constructRealtimeEvent(parsed);\n\t\t\tif (!event) {\n\t\t\t\treturn { type: \"invalid\" };\n\t\t\t}\n\t\t\treturn { type: \"event\", event };\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[Realtime] Failed to construct event\", error);\n\t\t\treturn { type: \"invalid\" };\n\t\t}\n\t}\n\n\treturn { type: \"invalid\" };\n}\n\n/**\n * Constructs a RealtimeEvent from parsed JSON data.\n * Returns null if required fields are missing or validation fails.\n */\nfunction constructRealtimeEvent(parsed: unknown): AnyRealtimeEvent | null {\n\tif (!parsed || typeof parsed !== \"object\" || !(\"type\" in parsed)) {\n\t\treturn null;\n\t}\n\n\tconst type = (parsed as { type: unknown }).type;\n\tif (!isValidEventType(type)) {\n\t\treturn null;\n\t}\n\n\tconst eventType = type;\n\n\t// Extract payload directly\n\tconst payloadSource = (parsed as { payload?: unknown }).payload;\n\n\tlet payload: unknown;\n\ttry {\n\t\tpayload = validateRealtimeEvent(eventType, payloadSource);\n\t} catch (error) {\n\t\tconsole.error(\"[Realtime] Received invalid event payload\", error);\n\t\treturn null;\n\t}\n\n\tconst organizationId = extractStringField(\n\t\tpayloadSource,\n\t\t\"organizationId\",\n\t\ttrue\n\t);\n\tconst websiteId = extractStringField(payloadSource, \"websiteId\", true);\n\n\tif (!organizationId) {\n\t\tconsole.error(\"[Realtime] Received event without organizationId\", parsed);\n\t\treturn null;\n\t}\n\n\tif (!websiteId) {\n\t\tconsole.error(\"[Realtime] Received event without websiteId\", parsed);\n\t\treturn null;\n\t}\n\n\tconst visitorId = extractStringField(parsed, \"visitorId\");\n\n\treturn {\n\t\ttype: eventType,\n\t\tpayload,\n\t\torganizationId,\n\t\twebsiteId,\n\t\tvisitorId,\n\t} as AnyRealtimeEvent;\n}\n\n/**\n * Checks if heartbeat has timed out.\n */\nfunction isHeartbeatTimedOut(\n\tlastHeartbeat: number,\n\ttimeoutMs: number\n): boolean {\n\tconst elapsed = Date.now() - lastHeartbeat;\n\treturn elapsed > timeoutMs;\n}\n\nfunction resolvePublicKey(explicit?: string | null): string | null {\n\tconst trimmed = explicit?.trim();\n\tif (trimmed) {\n\t\treturn trimmed;\n\t}\n\n\tconst fromEnv =\n\t\tprocess.env.NEXT_PUBLIC_COSSISTANT_API_KEY ||\n\t\tprocess.env.COSSISTANT_PUBLIC_KEY ||\n\t\tnull;\n\n\tconst normalized = fromEnv?.trim();\n\treturn normalized && normalized.length > 0 ? normalized : null;\n}\n\nfunction normalizeAuth(\n\tauth: RealtimeAuthConfig | null\n): ResolvedAuthConfig | null {\n\tif (!auth) {\n\t\treturn null;\n\t}\n\n\tif (auth.kind === \"visitor\") {\n\t\tconst visitorId = auth.visitorId?.trim() || null;\n\n\t\tif (!visitorId) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\ttype: \"visitor\",\n\t\t\tvisitorId,\n\t\t\twebsiteId: auth.websiteId?.trim() || null,\n\t\t\tuserId: null,\n\t\t\tsessionToken: null,\n\t\t\tpublicKey: resolvePublicKey(auth.publicKey ?? null),\n\t\t} satisfies ResolvedAuthConfig;\n\t}\n\n\tconst sessionToken = auth.sessionToken?.trim() || null;\n\n\tif (!sessionToken) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\ttype: \"session\",\n\t\tvisitorId: null,\n\t\twebsiteId: auth.websiteId?.trim() || null,\n\t\tuserId: auth.userId?.trim() || null,\n\t\tsessionToken,\n\t\tpublicKey: null,\n\t} satisfies ResolvedAuthConfig;\n}\n\nfunction buildSocketUrl(\n\tbaseUrl: string,\n\tauth: ResolvedAuthConfig | null\n): string | null {\n\tif (!auth) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst url = new URL(baseUrl);\n\n\t\tif (auth.type === \"visitor\") {\n\t\t\turl.searchParams.set(\"visitorId\", auth.visitorId ?? \"\");\n\t\t\tconst publicKey = auth.publicKey;\n\t\t\tif (publicKey) {\n\t\t\t\turl.searchParams.set(\"publicKey\", publicKey);\n\t\t\t}\n\t\t} else {\n\t\t\turl.searchParams.set(\"sessionToken\", auth.sessionToken ?? \"\");\n\t\t\tif (auth.websiteId) {\n\t\t\t\turl.searchParams.set(\"websiteId\", auth.websiteId);\n\t\t\t}\n\t\t}\n\n\t\treturn url.toString();\n\t} catch (error) {\n\t\tconsole.error(\"[Realtime] Failed to build WebSocket URL\", error);\n\t\treturn null;\n\t}\n}\n\n/**\n * Provides websocket connectivity and heartbeating logic for realtime events.\n */\nexport function RealtimeProvider({\n\tchildren,\n\twsUrl = DEFAULT_WS_URL,\n\tauth,\n\tautoConnect = true,\n\tonConnect,\n\tonDisconnect,\n\tonError,\n}: RealtimeProviderProps): React.ReactElement {\n\tconst normalizedAuth = normalizeAuth(auth);\n\n\tconst socketUrl = buildSocketUrl(wsUrl, normalizedAuth);\n\tconst eventHandlersRef = useRef<Set<SubscribeHandler>>(new Set());\n\tconst lastHeartbeatRef = useRef<number>(Date.now());\n\tconst hasOpenedRef = useRef(false);\n\tconst previousUrlRef = useRef<string | null>(null);\n\tconst [connectionError, setConnectionError] = useState<Error | null>(null);\n\tconst [lastEvent, setLastEvent] = useState<AnyRealtimeEvent | null>(null);\n\tconst [connectionId, setConnectionId] = useState<string | null>(null);\n\n\tconst heartbeatIntervalMs = DEFAULT_HEARTBEAT_INTERVAL_MS;\n\tconst heartbeatTimeoutMs = DEFAULT_HEARTBEAT_TIMEOUT_MS;\n\n\tconst canConnect = Boolean(autoConnect && socketUrl);\n\tconst connectionUrl = canConnect ? socketUrl : null;\n\n\t// Track URL changes to detect when connection is being replaced\n\tuseEffect(() => {\n\t\tif (connectionUrl !== previousUrlRef.current) {\n\t\t\tpreviousUrlRef.current = connectionUrl;\n\t\t\t// Reset hasOpenedRef when URL changes so we know a new connection is starting\n\t\t\thasOpenedRef.current = false;\n\t\t}\n\t}, [connectionUrl]);\n\n\tconst {\n\t\tsendMessage,\n\t\tsendJsonMessage,\n\t\tlastMessage,\n\t\treadyState,\n\t\tgetWebSocket,\n\t} = useWebSocket(\n\t\tconnectionUrl,\n\t\t{\n\t\t\tshouldReconnect: (closeEvent) => {\n\t\t\t\tif (!canConnect) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (closeEvent.code === 1008 || closeEvent.code === 1011) {\n\t\t\t\t\tconst err = new Error(\n\t\t\t\t\t\tcloseEvent.reason ||\n\t\t\t\t\t\t\t\"Realtime connection closed by server. Please check your credentials.\"\n\t\t\t\t\t);\n\t\t\t\t\tsetConnectionError(err);\n\t\t\t\t\tonError?.(err);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\treconnectAttempts: autoConnect ? undefined : 0,\n\t\t\treconnectInterval: (attempt) => {\n\t\t\t\tconst base = 500 * 2 ** attempt;\n\t\t\t\treturn Math.min(base, 30_000);\n\t\t\t},\n\t\t\tretryOnError: false,\n\t\t\tonOpen: () => {\n\t\t\t\thasOpenedRef.current = true;\n\t\t\t\tsetConnectionError(null);\n\t\t\t\tlastHeartbeatRef.current = Date.now();\n\t\t\t\tonConnect?.();\n\t\t\t},\n\t\t\tonClose: () => {\n\t\t\t\tsetConnectionId(null);\n\t\t\t\tonDisconnect?.();\n\t\t\t},\n\t\t\tonError: (event) => {\n\t\t\t\tif (!canConnect) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst socketLike = event.target;\n\t\t\t\tconst currentSocket = getWebSocket();\n\t\t\t\tconst isBrowserSocket =\n\t\t\t\t\ttypeof WebSocket !== \"undefined\" && socketLike instanceof WebSocket;\n\t\t\t\tconst socketState = isBrowserSocket ? socketLike.readyState : undefined;\n\n\t\t\t\t// Only suppress errors for THIS provider's socket, not other nested providers\n\t\t\t\t// Check if the errored socket belongs to this provider instance\n\t\t\t\tconst isThisProvidersSocket = currentSocket === socketLike;\n\n\t\t\t\t// Suppress errors if:\n\t\t\t\t// 1. This socket was replaced (URL changed while connecting) - only for this provider\n\t\t\t\t// 2. Connection URL is null (component unmounting or disabled)\n\t\t\t\t// 3. Socket is in CLOSING/CLOSED state and hasn't opened (cleanup/unmount) - only for this provider\n\t\t\t\tif (\n\t\t\t\t\t(!isThisProvidersSocket && currentSocket) ||\n\t\t\t\t\t!connectionUrl ||\n\t\t\t\t\t(isThisProvidersSocket &&\n\t\t\t\t\t\t!hasOpenedRef.current &&\n\t\t\t\t\t\t(socketState === WebSocket.CLOSING ||\n\t\t\t\t\t\t\tsocketState === WebSocket.CLOSED))\n\t\t\t\t) {\n\t\t\t\t\t// Suppress these expected errors during connection replacement or cleanup\n\t\t\t\t\t// But only if it's THIS provider's socket being replaced\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// For errors that occur during CONNECTING state, check if URL changed\n\t\t\t\t// Only suppress if it's this provider's socket\n\t\t\t\tif (\n\t\t\t\t\tisThisProvidersSocket &&\n\t\t\t\t\t!hasOpenedRef.current &&\n\t\t\t\t\tsocketState === WebSocket.CONNECTING &&\n\t\t\t\t\tconnectionUrl !== previousUrlRef.current\n\t\t\t\t) {\n\t\t\t\t\t// URL changed while connecting, suppress error\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst err = new Error(`WebSocket error: ${event.type}`);\n\t\t\t\tsetConnectionError(err);\n\t\t\t\tonError?.(err);\n\t\t\t},\n\t\t},\n\t\tcanConnect\n\t);\n\n\tuseEffect(() => {\n\t\tif (!lastMessage) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Decode message data from various formats\n\t\tconst decoded = decodeMessageData(lastMessage.data);\n\t\tif (decoded.type === \"unsupported\") {\n\t\t\treturn;\n\t\t}\n\n\t\t// Parse the message and determine its type\n\t\tconst message = parseWebSocketMessage(decoded.data);\n\n\t\t// Handle different message types\n\t\tswitch (message.type) {\n\t\t\tcase \"pong\":\n\t\t\t\tlastHeartbeatRef.current = Date.now();\n\t\t\t\tbreak;\n\n\t\t\tcase \"connection-established\":\n\t\t\t\tsetConnectionId(message.connectionId);\n\t\t\t\tlastHeartbeatRef.current = Date.now();\n\t\t\t\tbreak;\n\n\t\t\tcase \"error\": {\n\t\t\t\tconst err = new Error(message.message);\n\t\t\t\tsetConnectionError(err);\n\t\t\t\tonError?.(err);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"event\":\n\t\t\t\tlastHeartbeatRef.current = Date.now();\n\t\t\t\tsetLastEvent(message.event);\n\t\t\t\tfor (const handler of eventHandlersRef.current) {\n\t\t\t\t\tPromise.resolve(handler(message.event)).catch((error) => {\n\t\t\t\t\t\tconst err =\n\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t? error\n\t\t\t\t\t\t\t\t: new Error(`Subscriber threw an exception: ${String(error)}`);\n\t\t\t\t\t\tonError?.(err);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// Silently ignore invalid or unknown messages\n\t\t\t\tbreak;\n\t\t}\n\t}, [lastMessage, onError]);\n\n\tuseEffect(() => {\n\t\tif (!canConnect) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst interval = window.setInterval(() => {\n\t\t\tif (readyState !== ReadyState.OPEN) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check if heartbeat has timed out\n\t\t\tif (isHeartbeatTimedOut(lastHeartbeatRef.current, heartbeatTimeoutMs)) {\n\t\t\t\tconst socket = getWebSocket();\n\t\t\t\tsocket?.close(4000, \"Heartbeat timeout\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Send ping to keep connection alive\n\t\t\ttry {\n\t\t\t\tsendMessage(\"ping\");\n\t\t\t} catch {\n\t\t\t\t// Ignore send failures; reconnect logic will handle it\n\t\t\t}\n\t\t}, heartbeatIntervalMs);\n\n\t\treturn () => {\n\t\t\twindow.clearInterval(interval);\n\t\t};\n\t}, [\n\t\tcanConnect,\n\t\theartbeatIntervalMs,\n\t\theartbeatTimeoutMs,\n\t\treadyState,\n\t\tsendMessage,\n\t\tgetWebSocket,\n\t]);\n\n\tconst send = useCallback(\n\t\t(event: AnyRealtimeEvent) => {\n\t\t\tif (!connectionUrl) {\n\t\t\t\tthrow new Error(\"Realtime connection is disabled\");\n\t\t\t}\n\n\t\t\tif (readyState !== ReadyState.OPEN) {\n\t\t\t\tthrow new Error(\"Realtime connection is not established\");\n\t\t\t}\n\n\t\t\tsendJsonMessage(event);\n\t\t},\n\t\t[connectionUrl, readyState, sendJsonMessage]\n\t);\n\n\tconst sendRaw = useCallback(\n\t\t(data: string) => {\n\t\t\tif (!connectionUrl) {\n\t\t\t\tthrow new Error(\"Realtime connection is disabled\");\n\t\t\t}\n\n\t\t\tif (readyState !== ReadyState.OPEN) {\n\t\t\t\tthrow new Error(\"Realtime connection is not established\");\n\t\t\t}\n\n\t\t\tsendMessage(data);\n\t\t},\n\t\t[connectionUrl, readyState, sendMessage]\n\t);\n\n\tconst subscribe = useCallback((handler: SubscribeHandler) => {\n\t\teventHandlersRef.current.add(handler);\n\t\treturn () => {\n\t\t\teventHandlersRef.current.delete(handler);\n\t\t};\n\t}, []);\n\n\tconst reconnect = useCallback(() => {\n\t\tconst socket = getWebSocket();\n\t\tsocket?.close();\n\t}, [getWebSocket]);\n\n\tconst connection = useMemo<RealtimeConnectionState>(\n\t\t() => ({\n\t\t\tisConnected: readyState === ReadyState.OPEN,\n\t\t\tisConnecting: readyState === ReadyState.CONNECTING,\n\t\t\terror: connectionError,\n\t\t\tsend,\n\t\t\tsendRaw,\n\t\t\tsubscribe,\n\t\t\tlastEvent,\n\t\t\tconnectionId,\n\t\t\treconnect,\n\t\t}),\n\t\t[\n\t\t\treadyState,\n\t\t\tconnectionError,\n\t\t\tsend,\n\t\t\tsendRaw,\n\t\t\tsubscribe,\n\t\t\tlastEvent,\n\t\t\tconnectionId,\n\t\t\treconnect,\n\t\t]\n\t);\n\n\tconst value = useMemo<RealtimeContextValue>(\n\t\t() => ({\n\t\t\t...connection,\n\t\t\tvisitorId: normalizedAuth?.visitorId ?? null,\n\t\t\twebsiteId: normalizedAuth?.websiteId ?? null,\n\t\t\tuserId: normalizedAuth?.userId ?? null,\n\t\t}),\n\t\t[\n\t\t\tconnection,\n\t\t\tnormalizedAuth?.visitorId,\n\t\t\tnormalizedAuth?.websiteId,\n\t\t\tnormalizedAuth?.userId,\n\t\t]\n\t);\n\n\treturn (\n\t\t<RealtimeContext.Provider value={value}>\n\t\t\t{children}\n\t\t</RealtimeContext.Provider>\n\t);\n}\n\n/**\n * Returns the realtime connection context.\n */\nexport function useRealtimeConnection(): RealtimeContextValue {\n\tconst context = useContext(RealtimeContext);\n\tif (!context) {\n\t\tthrow new Error(\n\t\t\t\"useRealtimeConnection must be used within RealtimeProvider\"\n\t\t);\n\t}\n\n\treturn context;\n}\n\nexport type { RealtimeContextValue };\nexport type { RealtimeAuthConfig };\nexport type { RealtimeProviderProps };\nexport type { RealtimeEvent } from \"@cossistant/types/realtime-events\";\n"],"mappings":"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"}
|
|
@@ -45,7 +45,7 @@ const ConversationTimelineList = ({ conversationId, items: timelineItems, classN
|
|
|
45
45
|
}, [seenNameLookup]);
|
|
46
46
|
return /* @__PURE__ */ jsx(ConversationTimeline, {
|
|
47
47
|
autoScroll: true,
|
|
48
|
-
className: cn("overflow-y-scroll scroll-smooth px-3 py-6", "
|
|
48
|
+
className: cn("overflow-y-scroll scroll-smooth px-3 py-6", "co-scrollbar-thin", "h-full w-full", className),
|
|
49
49
|
id: "conversation-timeline",
|
|
50
50
|
items: timelineItems,
|
|
51
51
|
children: /* @__PURE__ */ jsxs(ConversationTimelineContainer, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-timeline.js","names":["EMPTY_SEEN_BY_IDS: readonly string[]","EMPTY_SEEN_BY_NAMES: readonly string[]","ConversationTimelineList: React.FC<ConversationTimelineProps>","names: string[]","PrimitiveConversationTimeline"],"sources":["../../../src/support/components/conversation-timeline.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport type {\n\tTimelineItem,\n\tTimelinePartEvent,\n} from \"@cossistant/types/api/timeline-item\";\nimport type React from \"react\";\nimport { useCallback, useMemo } from \"react\";\nimport { useConversationTimeline } from \"../../hooks/use-conversation-timeline\";\nimport {\n\tConversationTimelineContainer,\n\tConversationTimeline as PrimitiveConversationTimeline,\n} from \"../../primitives/conversation-timeline\";\nimport { cn } from \"../utils\";\nimport { ConversationEvent } from \"./conversation-event\";\nimport { TimelineMessageGroup } from \"./timeline-message-group\";\nimport { TypingIndicator, type TypingParticipant } from \"./typing-indicator\";\n\n// Helper to extract event part from timeline item\nfunction extractEventPart(item: TimelineItem): TimelinePartEvent | null {\n\tif (item.type !== \"event\") {\n\t\treturn null;\n\t}\n\n\tconst eventPart = item.parts.find(\n\t\t(part): part is TimelinePartEvent => part.type === \"event\"\n\t);\n\n\treturn eventPart || null;\n}\n\nconst EMPTY_SEEN_BY_IDS: readonly string[] = Object.freeze([]);\nconst EMPTY_SEEN_BY_NAMES: readonly string[] = Object.freeze([]);\n\nexport type ConversationTimelineToolProps = {\n\titem: TimelineItem;\n\tconversationId: string;\n};\n\nexport type ConversationTimelineToolDefinition = {\n\tcomponent: React.ComponentType<ConversationTimelineToolProps>;\n};\n\nexport type ConversationTimelineTools = Record<\n\tstring,\n\tConversationTimelineToolDefinition\n>;\n\nexport type ConversationTimelineProps = {\n\tconversationId: string;\n\titems: TimelineItem[];\n\tclassName?: string;\n\tavailableAIAgents: AvailableAIAgent[];\n\tavailableHumanAgents: AvailableHumanAgent[];\n\tcurrentVisitorId?: string;\n\ttools?: ConversationTimelineTools;\n};\n\nexport const ConversationTimelineList: React.FC<ConversationTimelineProps> = ({\n\tconversationId,\n\titems: timelineItems,\n\tclassName,\n\tavailableAIAgents = [],\n\tavailableHumanAgents = [],\n\tcurrentVisitorId,\n\ttools,\n}) => {\n\tconst timeline = useConversationTimeline({\n\t\tconversationId,\n\t\titems: timelineItems,\n\t\tcurrentVisitorId,\n\t});\n\n\tconst typingIndicatorParticipants = useMemo(\n\t\t() =>\n\t\t\ttimeline.typingParticipants.map<TypingParticipant>((participant) => ({\n\t\t\t\tid: participant.id,\n\t\t\t\ttype: participant.type,\n\t\t\t})),\n\t\t[timeline.typingParticipants]\n\t);\n\n\tconst seenNameLookup = useMemo(() => {\n\t\tconst map = new Map<string, string>();\n\n\t\tfor (const agent of availableHumanAgents) {\n\t\t\tif (agent.name) {\n\t\t\t\tmap.set(agent.id, agent.name);\n\t\t\t}\n\t\t}\n\n\t\tfor (const agent of availableAIAgents) {\n\t\t\tif (agent.name) {\n\t\t\t\tmap.set(agent.id, agent.name);\n\t\t\t}\n\t\t}\n\n\t\treturn map;\n\t}, [availableHumanAgents, availableAIAgents]);\n\n\tconst getSeenByNames = useCallback(\n\t\t(ids: readonly string[] = EMPTY_SEEN_BY_IDS): readonly string[] => {\n\t\t\tif (ids.length === 0 || seenNameLookup.size === 0) {\n\t\t\t\treturn EMPTY_SEEN_BY_NAMES;\n\t\t\t}\n\n\t\t\tconst uniqueNames = new Set<string>();\n\t\t\tconst names: string[] = [];\n\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst name = seenNameLookup.get(id);\n\t\t\t\tif (!name || uniqueNames.has(name)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tuniqueNames.add(name);\n\t\t\t\tnames.push(name);\n\t\t\t}\n\n\t\t\tif (names.length === 0) {\n\t\t\t\treturn EMPTY_SEEN_BY_NAMES;\n\t\t\t}\n\n\t\t\treturn Object.freeze(names);\n\t\t},\n\t\t[seenNameLookup]\n\t);\n\n\treturn (\n\t\t<PrimitiveConversationTimeline\n\t\t\tautoScroll={true}\n\t\t\tclassName={cn(\n\t\t\t\t\"overflow-y-scroll scroll-smooth px-3 py-6\",\n\t\t\t\t\"
|
|
1
|
+
{"version":3,"file":"conversation-timeline.js","names":["EMPTY_SEEN_BY_IDS: readonly string[]","EMPTY_SEEN_BY_NAMES: readonly string[]","ConversationTimelineList: React.FC<ConversationTimelineProps>","names: string[]","PrimitiveConversationTimeline"],"sources":["../../../src/support/components/conversation-timeline.tsx"],"sourcesContent":["import type { AvailableAIAgent, AvailableHumanAgent } from \"@cossistant/types\";\nimport type {\n\tTimelineItem,\n\tTimelinePartEvent,\n} from \"@cossistant/types/api/timeline-item\";\nimport type React from \"react\";\nimport { useCallback, useMemo } from \"react\";\nimport { useConversationTimeline } from \"../../hooks/use-conversation-timeline\";\nimport {\n\tConversationTimelineContainer,\n\tConversationTimeline as PrimitiveConversationTimeline,\n} from \"../../primitives/conversation-timeline\";\nimport { cn } from \"../utils\";\nimport { ConversationEvent } from \"./conversation-event\";\nimport { TimelineMessageGroup } from \"./timeline-message-group\";\nimport { TypingIndicator, type TypingParticipant } from \"./typing-indicator\";\n\n// Helper to extract event part from timeline item\nfunction extractEventPart(item: TimelineItem): TimelinePartEvent | null {\n\tif (item.type !== \"event\") {\n\t\treturn null;\n\t}\n\n\tconst eventPart = item.parts.find(\n\t\t(part): part is TimelinePartEvent => part.type === \"event\"\n\t);\n\n\treturn eventPart || null;\n}\n\nconst EMPTY_SEEN_BY_IDS: readonly string[] = Object.freeze([]);\nconst EMPTY_SEEN_BY_NAMES: readonly string[] = Object.freeze([]);\n\nexport type ConversationTimelineToolProps = {\n\titem: TimelineItem;\n\tconversationId: string;\n};\n\nexport type ConversationTimelineToolDefinition = {\n\tcomponent: React.ComponentType<ConversationTimelineToolProps>;\n};\n\nexport type ConversationTimelineTools = Record<\n\tstring,\n\tConversationTimelineToolDefinition\n>;\n\nexport type ConversationTimelineProps = {\n\tconversationId: string;\n\titems: TimelineItem[];\n\tclassName?: string;\n\tavailableAIAgents: AvailableAIAgent[];\n\tavailableHumanAgents: AvailableHumanAgent[];\n\tcurrentVisitorId?: string;\n\ttools?: ConversationTimelineTools;\n};\n\nexport const ConversationTimelineList: React.FC<ConversationTimelineProps> = ({\n\tconversationId,\n\titems: timelineItems,\n\tclassName,\n\tavailableAIAgents = [],\n\tavailableHumanAgents = [],\n\tcurrentVisitorId,\n\ttools,\n}) => {\n\tconst timeline = useConversationTimeline({\n\t\tconversationId,\n\t\titems: timelineItems,\n\t\tcurrentVisitorId,\n\t});\n\n\tconst typingIndicatorParticipants = useMemo(\n\t\t() =>\n\t\t\ttimeline.typingParticipants.map<TypingParticipant>((participant) => ({\n\t\t\t\tid: participant.id,\n\t\t\t\ttype: participant.type,\n\t\t\t})),\n\t\t[timeline.typingParticipants]\n\t);\n\n\tconst seenNameLookup = useMemo(() => {\n\t\tconst map = new Map<string, string>();\n\n\t\tfor (const agent of availableHumanAgents) {\n\t\t\tif (agent.name) {\n\t\t\t\tmap.set(agent.id, agent.name);\n\t\t\t}\n\t\t}\n\n\t\tfor (const agent of availableAIAgents) {\n\t\t\tif (agent.name) {\n\t\t\t\tmap.set(agent.id, agent.name);\n\t\t\t}\n\t\t}\n\n\t\treturn map;\n\t}, [availableHumanAgents, availableAIAgents]);\n\n\tconst getSeenByNames = useCallback(\n\t\t(ids: readonly string[] = EMPTY_SEEN_BY_IDS): readonly string[] => {\n\t\t\tif (ids.length === 0 || seenNameLookup.size === 0) {\n\t\t\t\treturn EMPTY_SEEN_BY_NAMES;\n\t\t\t}\n\n\t\t\tconst uniqueNames = new Set<string>();\n\t\t\tconst names: string[] = [];\n\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst name = seenNameLookup.get(id);\n\t\t\t\tif (!name || uniqueNames.has(name)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tuniqueNames.add(name);\n\t\t\t\tnames.push(name);\n\t\t\t}\n\n\t\t\tif (names.length === 0) {\n\t\t\t\treturn EMPTY_SEEN_BY_NAMES;\n\t\t\t}\n\n\t\t\treturn Object.freeze(names);\n\t\t},\n\t\t[seenNameLookup]\n\t);\n\n\treturn (\n\t\t<PrimitiveConversationTimeline\n\t\t\tautoScroll={true}\n\t\t\tclassName={cn(\n\t\t\t\t\"overflow-y-scroll scroll-smooth px-3 py-6\",\n\t\t\t\t\"co-scrollbar-thin\",\n\t\t\t\t\"h-full w-full\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tid=\"conversation-timeline\"\n\t\t\titems={timelineItems}\n\t\t>\n\t\t\t<ConversationTimelineContainer className=\"flex min-h-full w-full flex-col gap-3\">\n\t\t\t\t{timeline.groupedMessages.items.map((item, index) => {\n\t\t\t\t\tif (item.type === \"timeline_event\") {\n\t\t\t\t\t\t// Extract event data from parts\n\t\t\t\t\t\tconst eventPart = extractEventPart(item.item);\n\n\t\t\t\t\t\t// Only render if we have valid event data\n\t\t\t\t\t\tif (!eventPart) {\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<ConversationEvent\n\t\t\t\t\t\t\t\tavailableAIAgents={availableAIAgents}\n\t\t\t\t\t\t\t\tavailableHumanAgents={availableHumanAgents}\n\t\t\t\t\t\t\t\tcreatedAt={item.item.createdAt}\n\t\t\t\t\t\t\t\tevent={eventPart}\n\t\t\t\t\t\t\t\tkey={item.item.id ?? `timeline-event-${item.item.createdAt}`}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (item.type === \"timeline_tool\") {\n\t\t\t\t\t\tconst toolName = item.tool ?? item.item.tool ?? item.item.type;\n\t\t\t\t\t\tconst toolDefinition = toolName ? tools?.[toolName] : undefined;\n\n\t\t\t\t\t\tif (!toolDefinition) {\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst ToolComponent = toolDefinition.component;\n\n\t\t\t\t\t\tconst toolKey =\n\t\t\t\t\t\t\titem.item.id ?? `${toolName}-${item.item.createdAt}-${index}`;\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<ToolComponent\n\t\t\t\t\t\t\t\tconversationId={conversationId}\n\t\t\t\t\t\t\t\titem={item.item}\n\t\t\t\t\t\t\t\tkey={toolKey}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only show seen indicator on the LAST message group sent by the visitor\n\t\t\t\t\tconst isLastVisitorGroup =\n\t\t\t\t\t\tindex === timeline.lastVisitorMessageGroupIndex;\n\t\t\t\t\tconst seenByIds =\n\t\t\t\t\t\tisLastVisitorGroup && item.lastMessageId\n\t\t\t\t\t\t\t? timeline.groupedMessages.getMessageSeenBy(item.lastMessageId)\n\t\t\t\t\t\t\t: EMPTY_SEEN_BY_IDS;\n\t\t\t\t\tconst seenByNames =\n\t\t\t\t\t\tseenByIds.length > 0\n\t\t\t\t\t\t\t? getSeenByNames(seenByIds)\n\t\t\t\t\t\t\t: EMPTY_SEEN_BY_NAMES;\n\n\t\t\t\t\t// Use first timeline item ID as stable key\n\t\t\t\t\tconst groupKey =\n\t\t\t\t\t\titem.lastMessageId ??\n\t\t\t\t\t\titem.items?.[0]?.id ??\n\t\t\t\t\t\t`group-${item.items?.[0]?.createdAt ?? index}`;\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TimelineMessageGroup\n\t\t\t\t\t\t\tavailableAIAgents={availableAIAgents}\n\t\t\t\t\t\t\tavailableHumanAgents={availableHumanAgents}\n\t\t\t\t\t\t\tcurrentVisitorId={currentVisitorId}\n\t\t\t\t\t\t\titems={item.items || []}\n\t\t\t\t\t\t\tkey={groupKey}\n\t\t\t\t\t\t\tseenByIds={seenByIds}\n\t\t\t\t\t\t\tseenByNames={seenByNames}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t\t<div className=\"h-6 w-full\">\n\t\t\t\t\t{typingIndicatorParticipants.length > 0 ? (\n\t\t\t\t\t\t<TypingIndicator\n\t\t\t\t\t\t\tavailableAIAgents={availableAIAgents}\n\t\t\t\t\t\t\tavailableHumanAgents={availableHumanAgents}\n\t\t\t\t\t\t\tclassName=\"mt-2\"\n\t\t\t\t\t\t\tparticipants={typingIndicatorParticipants}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</ConversationTimelineContainer>\n\t\t</PrimitiveConversationTimeline>\n\t);\n};\n"],"mappings":"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"}
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
@source "./components";
|
|
6
6
|
@source "./pages";
|
|
7
7
|
|
|
8
|
-
@plugin 'tailwind-scrollbar';
|
|
9
|
-
|
|
10
8
|
@layer base {
|
|
11
9
|
.cossistant {
|
|
12
10
|
@apply scroll-smooth;
|
|
@@ -324,6 +322,30 @@
|
|
|
324
322
|
|
|
325
323
|
@layer utilities {
|
|
326
324
|
.cossistant {
|
|
325
|
+
/* Native scrollbar styling */
|
|
326
|
+
.co-scrollbar-thin {
|
|
327
|
+
scrollbar-width: thin;
|
|
328
|
+
scrollbar-color: oklch(from var(--co-primary) l c h / 0.3) transparent;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.co-scrollbar-thin::-webkit-scrollbar {
|
|
332
|
+
width: 8px;
|
|
333
|
+
height: 8px;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.co-scrollbar-thin::-webkit-scrollbar-track {
|
|
337
|
+
background: transparent;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.co-scrollbar-thin::-webkit-scrollbar-thumb {
|
|
341
|
+
background-color: oklch(from var(--co-primary) l c h / 0.3);
|
|
342
|
+
border-radius: 4px;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.co-scrollbar-thin::-webkit-scrollbar-thumb:hover {
|
|
346
|
+
background-color: oklch(from var(--co-primary) l c h / 0.5);
|
|
347
|
+
}
|
|
348
|
+
|
|
327
349
|
.animation-delay-0 {
|
|
328
350
|
animation-delay: 0ms;
|
|
329
351
|
}
|
|
@@ -363,4 +385,4 @@
|
|
|
363
385
|
}
|
|
364
386
|
|
|
365
387
|
|
|
366
|
-
/*# sourceMappingURL=support-
|
|
388
|
+
/*# sourceMappingURL=support-D2EgfIts.css.map*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"support-D2EgfIts.css","names":[],"sources":["../../src/support/support.css"],"sourcesContent":["/*\n* This indicates to tailwind to\n* compile classes from Cossistant with the host tailwind config\n*/\n@source \"./components\";\n@source \"./pages\";\n\n@layer base {\n\t.cossistant {\n\t\t@apply scroll-smooth;\n\t\t@apply text-co-primary;\n\n\t\tcolor-scheme: inherit;\n\n\t\t/* Typeface tokens */\n\t\t--co-font-sans: var(--co-theme-font-sans, \"Geist\", \"Inter\", sans-serif);\n\t\t--co-font-mono: var(\n\t\t\t--co-theme-font-mono,\n\t\t\t\"Geist Mono\",\n\t\t\t\"Inter Mono\",\n\t\t\tmonospace\n\t\t);\n\n\t\t/* Core surfaces */\n\t\t--co-radius: var(--co-theme-radius, 0.625rem);\n\t\t--co-background-base: var(--co-theme-background, oklch(99% 0 0));\n\t\t--co-foreground-base: var(--co-theme-foreground, oklch(20.5% 0 0));\n\t\t--co-popover-base: var(--co-theme-popover, var(--co-background-base));\n\t\t--co-popover-foreground-base: var(\n\t\t\t--co-theme-popover-foreground,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-primary-base: var(--co-theme-primary, oklch(14.5% 0 0));\n\t\t--co-primary-foreground-base: var(\n\t\t\t--co-theme-primary-foreground,\n\t\t\toklch(98.5% 0 0)\n\t\t);\n\t\t--co-secondary-base: var(--co-theme-secondary, oklch(97% 0 0));\n\t\t--co-secondary-foreground-base: var(\n\t\t\t--co-theme-secondary-foreground,\n\t\t\toklch(14.5% 0 0)\n\t\t);\n\t\t--co-border-base: var(--co-theme-border, oklch(92.2% 0 0));\n\t\t--co-input-base: var(--co-theme-input, oklch(92.2% 0 0));\n\t\t--co-ring-base: var(--co-theme-ring, var(--co-primary-base));\n\t\t--co-accent-base: var(--co-theme-accent, var(--co-primary-base));\n\t\t--co-accent-foreground-base: var(\n\t\t\t--co-theme-accent-foreground,\n\t\t\tvar(--co-primary-foreground-base)\n\t\t);\n\n\t\t/* Neutral shades derived from the background */\n\t\t--co-background-50-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 98%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-100-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 97%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-200-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 96%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-300-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 95%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-400-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 94%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-500-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 93%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-600-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 92%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\n\t\t/* Muted tones */\n\t\t--co-muted-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 85%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-muted-foreground-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-foreground-base) 70%,\n\t\t\twhite\n\t\t);\n\n\t\t/* Public tokens consumed by Tailwind theme */\n\t\t--co-background: var(--co-background-base);\n\t\t--co-background-50: var(\n\t\t\t--co-theme-background-50,\n\t\t\tvar(--co-background-50-mix, oklch(92% 0 0))\n\t\t);\n\t\t--co-background-100: var(\n\t\t\t--co-theme-background-100,\n\t\t\tvar(--co-background-100-mix, oklch(93% 0 0))\n\t\t);\n\t\t--co-background-200: var(\n\t\t\t--co-theme-background-200,\n\t\t\tvar(--co-background-200-mix, oklch(94% 0 0))\n\t\t);\n\t\t--co-background-300: var(\n\t\t\t--co-theme-background-300,\n\t\t\tvar(--co-background-300-mix, oklch(95% 0 0))\n\t\t);\n\t\t--co-background-400: var(\n\t\t\t--co-theme-background-400,\n\t\t\tvar(--co-background-400-mix, oklch(96% 0 0))\n\t\t);\n\t\t--co-background-500: var(\n\t\t\t--co-theme-background-500,\n\t\t\tvar(--co-background-500-mix, oklch(97% 0 0))\n\t\t);\n\t\t--co-background-600: var(\n\t\t\t--co-theme-background-600,\n\t\t\tvar(--co-background-600-mix, oklch(98% 0 0))\n\t\t);\n\n\t\t--co-foreground: var(--co-foreground-base);\n\t\t--co-popover: var(--co-popover-base);\n\t\t--co-popover-foreground: var(--co-popover-foreground-base);\n\t\t--co-primary: var(--co-primary-base);\n\t\t--co-primary-foreground: var(--co-primary-foreground-base);\n\t\t--co-secondary: var(--co-secondary-base);\n\t\t--co-secondary-foreground: var(--co-secondary-foreground-base);\n\t\t--co-muted: var(--co-theme-muted, var(--co-muted-mix, oklch(97% 0 0)));\n\t\t--co-muted-foreground: var(\n\t\t\t--co-theme-muted-foreground,\n\t\t\tvar(--co-muted-foreground-mix, oklch(55.6% 0 0))\n\t\t);\n\t\t--co-border: var(--co-border-base);\n\t\t--co-input: var(--co-input-base);\n\t\t--co-ring: var(--co-ring-base);\n\t\t--co-accent: var(--co-accent-base);\n\t\t--co-accent-foreground: var(--co-accent-foreground-base);\n\n\t\t/* Accent palette */\n\t\t--co-pink: var(--co-theme-pink, oklch(76.3% 0.152 354));\n\t\t--co-yellow: var(--co-theme-yellow, oklch(86.4% 0.144 99));\n\t\t--co-blue: var(--co-theme-blue, oklch(72.5% 0.132 241));\n\t\t--co-orange: var(--co-theme-orange, oklch(74.5% 0.166 50));\n\n\t\t/* Status colors */\n\t\t--co-destructive: var(--co-theme-destructive, oklch(57.7% 0.245 27.325));\n\t\t--co-destructive-foreground: var(\n\t\t\t--co-theme-destructive-foreground,\n\t\t\toklch(57.7% 0.245 27.325)\n\t\t);\n\t\t--co-success: var(--co-theme-success, oklch(71.7% 0.18 142));\n\t\t--co-success-foreground: var(\n\t\t\t--co-theme-success-foreground,\n\t\t\toklch(26.5% 0.052 142.7)\n\t\t);\n\t\t--co-neutral: var(--co-theme-neutral, oklch(60.8% 0 0));\n\t\t--co-neutral-foreground: var(\n\t\t\t--co-theme-neutral-foreground,\n\t\t\toklch(25.6% 0 0)\n\t\t);\n\t\t--co-warning: var(--co-theme-warning, oklch(86.4% 0.144 99));\n\t\t--co-warning-foreground: var(\n\t\t\t--co-theme-warning-foreground,\n\t\t\toklch(41.4% 0.071 99)\n\t\t);\n\n\t\t/* Tailwind theme mapping - scoped to widget */\n\t\t@theme inline {\n\t\t\t--font-co-sans: var(--co-font-sans);\n\t\t\t--font-co-mono: var(--co-font-mono);\n\t\t\t--color-co-background: var(--co-background);\n\t\t\t--color-co-background-50: var(--co-background-50);\n\t\t\t--color-co-background-100: var(--co-background-100);\n\t\t\t--color-co-background-200: var(--co-background-200);\n\t\t\t--color-co-background-300: var(--co-background-300);\n\t\t\t--color-co-background-400: var(--co-background-400);\n\t\t\t--color-co-background-500: var(--co-background-500);\n\t\t\t--color-co-background-600: var(--co-background-600);\n\n\t\t\t--color-co-foreground: var(--co-foreground);\n\n\t\t\t--color-co-primary: var(--co-primary);\n\t\t\t--color-co-primary-foreground: var(--co-primary-foreground);\n\t\t\t--color-co-secondary: var(--co-secondary);\n\t\t\t--color-co-secondary-foreground: var(--co-secondary-foreground);\n\t\t\t--color-co-muted: var(--co-muted);\n\t\t\t--color-co-muted-foreground: var(--co-muted-foreground);\n\t\t\t--color-co-border: var(--co-border);\n\t\t\t--color-co-input: var(--co-input);\n\t\t\t--color-co-ring: var(--co-ring);\n\t\t\t--radius-co: var(--co-radius);\n\n\t\t\t/* custom colors */\n\t\t\t--color-co-pink: var(--co-pink);\n\t\t\t--color-co-yellow: var(--co-yellow);\n\t\t\t--color-co-blue: var(--co-blue);\n\t\t\t--color-co-orange: var(--co-orange);\n\n\t\t\t/* status colors */\n\t\t\t--color-co-destructive: var(--co-destructive);\n\t\t\t--color-co-destructive-foreground: var(--co-destructive-foreground);\n\t\t\t--color-co-success: var(--co-success);\n\t\t\t--color-co-success-foreground: var(--co-success-foreground);\n\t\t\t--color-co-neutral: var(--co-neutral);\n\t\t\t--color-co-neutral-foreground: var(--co-neutral-foreground);\n\t\t\t--color-co-warning: var(--co-warning);\n\t\t\t--color-co-warning-foreground: var(--co-warning-foreground);\n\t\t}\n\t}\n\n\t.dark .cossistant,\n\t.cossistant[data-color-scheme=\"dark\"] {\n\t\t/* Dark mode defaults */\n\t\t--co-background-base: var(--co-theme-background, oklch(15.5% 0 0));\n\t\t--co-foreground-base: var(--co-theme-foreground, oklch(95% 0 0));\n\t\t--co-popover-base: var(--co-theme-popover, oklch(14.5% 0 0));\n\t\t--co-popover-foreground-base: var(\n\t\t\t--co-theme-popover-foreground,\n\t\t\toklch(95% 0 0)\n\t\t);\n\t\t--co-primary-base: var(--co-theme-primary, oklch(98.5% 0 0));\n\t\t--co-primary-foreground-base: var(\n\t\t\t--co-theme-primary-foreground,\n\t\t\toklch(14.5% 0 0)\n\t\t);\n\t\t--co-secondary-base: var(--co-theme-secondary, oklch(26.9% 0 0));\n\t\t--co-secondary-foreground-base: var(\n\t\t\t--co-theme-secondary-foreground,\n\t\t\toklch(95% 0 0)\n\t\t);\n\t\t--co-border-base: var(--co-theme-border, oklch(26.9% 0 0));\n\t\t--co-input-base: var(--co-theme-input, oklch(26.9% 0 0));\n\t\t--co-ring-base: var(--co-theme-ring, var(--co-primary-base));\n\t\t--co-accent-base: var(--co-theme-accent, var(--co-primary-base));\n\t\t--co-accent-foreground-base: var(\n\t\t\t--co-theme-accent-foreground,\n\t\t\tvar(--co-primary-foreground-base)\n\t\t);\n\n\t\t--co-muted-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 55%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-muted-foreground-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-foreground-base) 65%,\n\t\t\twhite\n\t\t);\n\n\t\t--co-background-50-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 98%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-100-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 96%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-200-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 94%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-300-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 92%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-400-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 90%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-500-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 88%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-600-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 86%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\n\t\t--co-pink: var(--co-theme-pink, oklch(84.2% 0.109 354));\n\t\t--co-yellow: var(--co-theme-yellow, oklch(90.3% 0.111 99));\n\t\t--co-blue: var(--co-theme-blue, oklch(79.8% 0.089 241));\n\t\t--co-orange: var(--co-theme-orange, oklch(68.2% 0.194 50));\n\n\t\t--co-destructive: var(--co-theme-destructive, oklch(39.6% 0.141 25.723));\n\t\t--co-destructive-foreground: var(\n\t\t\t--co-theme-destructive-foreground,\n\t\t\toklch(63.7% 0.237 25.331)\n\t\t);\n\t\t--co-success: var(--co-theme-success, oklch(60% 0.15 142));\n\t\t--co-success-foreground: var(\n\t\t\t--co-theme-success-foreground,\n\t\t\toklch(85% 0.12 142)\n\t\t);\n\t\t--co-neutral: var(--co-theme-neutral, oklch(50% 0 0));\n\t\t--co-neutral-foreground: var(--co-theme-neutral-foreground, oklch(85% 0 0));\n\t\t--co-warning: var(--co-theme-warning, oklch(90.3% 0.111 99));\n\t\t--co-warning-foreground: var(\n\t\t\t--co-theme-warning-foreground,\n\t\t\toklch(85% 0.1 99)\n\t\t);\n\t}\n}\n\n@layer utilities {\n\t.cossistant {\n\t\t/* Native scrollbar styling */\n\t\t.co-scrollbar-thin {\n\t\t\tscrollbar-width: thin;\n\t\t\tscrollbar-color: oklch(from var(--co-primary) l c h / 0.3) transparent;\n\t\t}\n\n\t\t.co-scrollbar-thin::-webkit-scrollbar {\n\t\t\twidth: 8px;\n\t\t\theight: 8px;\n\t\t}\n\n\t\t.co-scrollbar-thin::-webkit-scrollbar-track {\n\t\t\tbackground: transparent;\n\t\t}\n\n\t\t.co-scrollbar-thin::-webkit-scrollbar-thumb {\n\t\t\tbackground-color: oklch(from var(--co-primary) l c h / 0.3);\n\t\t\tborder-radius: 4px;\n\t\t}\n\n\t\t.co-scrollbar-thin::-webkit-scrollbar-thumb:hover {\n\t\t\tbackground-color: oklch(from var(--co-primary) l c h / 0.5);\n\t\t}\n\n\t\t.animation-delay-0 {\n\t\t\tanimation-delay: 0ms;\n\t\t}\n\t\t.animation-delay-200 {\n\t\t\tanimation-delay: 200ms;\n\t\t}\n\t\t.animation-delay-400 {\n\t\t\tanimation-delay: 400ms;\n\t\t}\n\n\t\t@keyframes bounce-dot {\n\t\t\t0%,\n\t\t\t80%,\n\t\t\t100% {\n\t\t\t\ttransform: translateY(0);\n\t\t\t}\n\t\t\t40% {\n\t\t\t\ttransform: translateY(-6px);\n\t\t\t}\n\t\t}\n\n\t\t.dot-bounce-1 {\n\t\t\tanimation: bounce-dot 1.4s infinite;\n\t\t\tanimation-delay: 0s;\n\t\t}\n\n\t\t.dot-bounce-2 {\n\t\t\tanimation: bounce-dot 1.4s infinite;\n\t\t\tanimation-delay: 0.16s;\n\t\t}\n\n\t\t.dot-bounce-3 {\n\t\t\tanimation: bounce-dot 1.4s infinite;\n\t\t\tanimation-delay: 0.32s;\n\t\t}\n\t}\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA"}
|
package/support.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.1.17 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer base{.cossistant{scroll-behavior:smooth;color:var(--co-primary);color-scheme:normal;--co-font-sans:var(--co-theme-font-sans,"Geist","Inter",sans-serif);--co-font-mono:var(--co-theme-font-mono,"Geist Mono","Inter Mono",monospace);--co-radius:var(--co-theme-radius,.625rem);--co-background-base:var(--co-theme-background,oklch(99% 0 0));--co-foreground-base:var(--co-theme-foreground,oklch(20.5% 0 0));--co-popover-base:var(--co-theme-popover,var(--co-background-base));--co-popover-foreground-base:var(--co-theme-popover-foreground,var(--co-foreground-base));--co-primary-base:var(--co-theme-primary,oklch(14.5% 0 0));--co-primary-foreground-base:var(--co-theme-primary-foreground,oklch(98.5% 0 0));--co-secondary-base:var(--co-theme-secondary,oklch(97% 0 0));--co-secondary-foreground-base:var(--co-theme-secondary-foreground,oklch(14.5% 0 0));--co-border-base:var(--co-theme-border,oklch(92.2% 0 0));--co-input-base:var(--co-theme-input,oklch(92.2% 0 0));--co-ring-base:var(--co-theme-ring,var(--co-primary-base));--co-accent-base:var(--co-theme-accent,var(--co-primary-base));--co-accent-foreground-base:var(--co-theme-accent-foreground,var(--co-primary-foreground-base));--co-background-50-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-50-mix:color-mix(in oklch,var(--co-background-base)98%,var(--co-foreground-base))}}.cossistant{--co-background-100-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-100-mix:color-mix(in oklch,var(--co-background-base)97%,var(--co-foreground-base))}}.cossistant{--co-background-200-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-200-mix:color-mix(in oklch,var(--co-background-base)96%,var(--co-foreground-base))}}.cossistant{--co-background-300-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-300-mix:color-mix(in oklch,var(--co-background-base)95%,var(--co-foreground-base))}}.cossistant{--co-background-400-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-400-mix:color-mix(in oklch,var(--co-background-base)94%,var(--co-foreground-base))}}.cossistant{--co-background-500-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-500-mix:color-mix(in oklch,var(--co-background-base)93%,var(--co-foreground-base))}}.cossistant{--co-background-600-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-600-mix:color-mix(in oklch,var(--co-background-base)92%,var(--co-foreground-base))}}.cossistant{--co-muted-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-muted-mix:color-mix(in oklch,var(--co-background-base)85%,var(--co-foreground-base))}}.cossistant{--co-muted-foreground-mix:var(--co-foreground-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-muted-foreground-mix:color-mix(in oklch,var(--co-foreground-base)70%,white)}}.cossistant{--co-background:var(--co-background-base);--co-background-50:var(--co-theme-background-50,var(--co-background-50-mix,oklch(92% 0 0)));--co-background-100:var(--co-theme-background-100,var(--co-background-100-mix,oklch(93% 0 0)));--co-background-200:var(--co-theme-background-200,var(--co-background-200-mix,oklch(94% 0 0)));--co-background-300:var(--co-theme-background-300,var(--co-background-300-mix,oklch(95% 0 0)));--co-background-400:var(--co-theme-background-400,var(--co-background-400-mix,oklch(96% 0 0)));--co-background-500:var(--co-theme-background-500,var(--co-background-500-mix,oklch(97% 0 0)));--co-background-600:var(--co-theme-background-600,var(--co-background-600-mix,oklch(98% 0 0)));--co-foreground:var(--co-foreground-base);--co-popover:var(--co-popover-base);--co-popover-foreground:var(--co-popover-foreground-base);--co-primary:var(--co-primary-base);--co-primary-foreground:var(--co-primary-foreground-base);--co-secondary:var(--co-secondary-base);--co-secondary-foreground:var(--co-secondary-foreground-base);--co-muted:var(--co-theme-muted,var(--co-muted-mix,oklch(97% 0 0)));--co-muted-foreground:var(--co-theme-muted-foreground,var(--co-muted-foreground-mix,oklch(55.6% 0 0)));--co-border:var(--co-border-base);--co-input:var(--co-input-base);--co-ring:var(--co-ring-base);--co-accent:var(--co-accent-base);--co-accent-foreground:var(--co-accent-foreground-base);--co-pink:var(--co-theme-pink,oklch(76.3% .152 354));--co-yellow:var(--co-theme-yellow,oklch(86.4% .144 99));--co-blue:var(--co-theme-blue,oklch(72.5% .132 241));--co-orange:var(--co-theme-orange,oklch(74.5% .166 50));--co-destructive:var(--co-theme-destructive,oklch(57.7% .245 27.325));--co-destructive-foreground:var(--co-theme-destructive-foreground,oklch(57.7% .245 27.325));--co-success:var(--co-theme-success,oklch(71.7% .18 142));--co-success-foreground:var(--co-theme-success-foreground,oklch(26.5% .052 142.7));--co-neutral:var(--co-theme-neutral,oklch(60.8% 0 0));--co-neutral-foreground:var(--co-theme-neutral-foreground,oklch(25.6% 0 0));--co-warning:var(--co-theme-warning,oklch(86.4% .144 99));--co-warning-foreground:var(--co-theme-warning-foreground,oklch(41.4% .071 99))}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-base:var(--co-theme-background,oklch(15.5% 0 0));--co-foreground-base:var(--co-theme-foreground,oklch(95% 0 0));--co-popover-base:var(--co-theme-popover,oklch(14.5% 0 0));--co-popover-foreground-base:var(--co-theme-popover-foreground,oklch(95% 0 0));--co-primary-base:var(--co-theme-primary,oklch(98.5% 0 0));--co-primary-foreground-base:var(--co-theme-primary-foreground,oklch(14.5% 0 0));--co-secondary-base:var(--co-theme-secondary,oklch(26.9% 0 0));--co-secondary-foreground-base:var(--co-theme-secondary-foreground,oklch(95% 0 0));--co-border-base:var(--co-theme-border,oklch(26.9% 0 0));--co-input-base:var(--co-theme-input,oklch(26.9% 0 0));--co-ring-base:var(--co-theme-ring,var(--co-primary-base));--co-accent-base:var(--co-theme-accent,var(--co-primary-base));--co-accent-foreground-base:var(--co-theme-accent-foreground,var(--co-primary-foreground-base));--co-muted-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-muted-mix:color-mix(in oklch,var(--co-background-base)55%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-muted-foreground-mix:var(--co-foreground-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-muted-foreground-mix:color-mix(in oklch,var(--co-foreground-base)65%,white)}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-50-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-50-mix:color-mix(in oklch,var(--co-background-base)98%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-100-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-100-mix:color-mix(in oklch,var(--co-background-base)96%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-200-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-200-mix:color-mix(in oklch,var(--co-background-base)94%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-300-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-300-mix:color-mix(in oklch,var(--co-background-base)92%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-400-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-400-mix:color-mix(in oklch,var(--co-background-base)90%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-500-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-500-mix:color-mix(in oklch,var(--co-background-base)88%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-600-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-600-mix:color-mix(in oklch,var(--co-background-base)86%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-pink:var(--co-theme-pink,oklch(84.2% .109 354));--co-yellow:var(--co-theme-yellow,oklch(90.3% .111 99));--co-blue:var(--co-theme-blue,oklch(79.8% .089 241));--co-orange:var(--co-theme-orange,oklch(68.2% .194 50));--co-destructive:var(--co-theme-destructive,oklch(39.6% .141 25.723));--co-destructive-foreground:var(--co-theme-destructive-foreground,oklch(63.7% .237 25.331));--co-success:var(--co-theme-success,oklch(60% .15 142));--co-success-foreground:var(--co-theme-success-foreground,oklch(85% .12 142));--co-neutral:var(--co-theme-neutral,oklch(50% 0 0));--co-neutral-foreground:var(--co-theme-neutral-foreground,oklch(85% 0 0));--co-warning:var(--co-theme-warning,oklch(90.3% .111 99));--co-warning-foreground:var(--co-theme-warning-foreground,oklch(85% .1 99))}*{scrollbar-color:initial;scrollbar-width:initial}}@layer utilities{.cossistant .animation-delay-0{animation-delay:0s}.cossistant .animation-delay-200{animation-delay:.2s}.cossistant .animation-delay-400{animation-delay:.4s}.cossistant .dot-bounce-1{animation:1.4s infinite bounce-dot}.cossistant .dot-bounce-2{animation:1.4s .16s infinite bounce-dot}.cossistant .dot-bounce-3{animation:1.4s .32s infinite bounce-dot}}
|
|
2
|
+
@layer base{.cossistant{scroll-behavior:smooth;color:var(--co-primary);color-scheme:normal;--co-font-sans:var(--co-theme-font-sans,"Geist","Inter",sans-serif);--co-font-mono:var(--co-theme-font-mono,"Geist Mono","Inter Mono",monospace);--co-radius:var(--co-theme-radius,.625rem);--co-background-base:var(--co-theme-background,oklch(99% 0 0));--co-foreground-base:var(--co-theme-foreground,oklch(20.5% 0 0));--co-popover-base:var(--co-theme-popover,var(--co-background-base));--co-popover-foreground-base:var(--co-theme-popover-foreground,var(--co-foreground-base));--co-primary-base:var(--co-theme-primary,oklch(14.5% 0 0));--co-primary-foreground-base:var(--co-theme-primary-foreground,oklch(98.5% 0 0));--co-secondary-base:var(--co-theme-secondary,oklch(97% 0 0));--co-secondary-foreground-base:var(--co-theme-secondary-foreground,oklch(14.5% 0 0));--co-border-base:var(--co-theme-border,oklch(92.2% 0 0));--co-input-base:var(--co-theme-input,oklch(92.2% 0 0));--co-ring-base:var(--co-theme-ring,var(--co-primary-base));--co-accent-base:var(--co-theme-accent,var(--co-primary-base));--co-accent-foreground-base:var(--co-theme-accent-foreground,var(--co-primary-foreground-base));--co-background-50-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-50-mix:color-mix(in oklch,var(--co-background-base)98%,var(--co-foreground-base))}}.cossistant{--co-background-100-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-100-mix:color-mix(in oklch,var(--co-background-base)97%,var(--co-foreground-base))}}.cossistant{--co-background-200-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-200-mix:color-mix(in oklch,var(--co-background-base)96%,var(--co-foreground-base))}}.cossistant{--co-background-300-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-300-mix:color-mix(in oklch,var(--co-background-base)95%,var(--co-foreground-base))}}.cossistant{--co-background-400-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-400-mix:color-mix(in oklch,var(--co-background-base)94%,var(--co-foreground-base))}}.cossistant{--co-background-500-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-500-mix:color-mix(in oklch,var(--co-background-base)93%,var(--co-foreground-base))}}.cossistant{--co-background-600-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-background-600-mix:color-mix(in oklch,var(--co-background-base)92%,var(--co-foreground-base))}}.cossistant{--co-muted-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-muted-mix:color-mix(in oklch,var(--co-background-base)85%,var(--co-foreground-base))}}.cossistant{--co-muted-foreground-mix:var(--co-foreground-base)}@supports (color:color-mix(in lab, red, red)){.cossistant{--co-muted-foreground-mix:color-mix(in oklch,var(--co-foreground-base)70%,white)}}.cossistant{--co-background:var(--co-background-base);--co-background-50:var(--co-theme-background-50,var(--co-background-50-mix,oklch(92% 0 0)));--co-background-100:var(--co-theme-background-100,var(--co-background-100-mix,oklch(93% 0 0)));--co-background-200:var(--co-theme-background-200,var(--co-background-200-mix,oklch(94% 0 0)));--co-background-300:var(--co-theme-background-300,var(--co-background-300-mix,oklch(95% 0 0)));--co-background-400:var(--co-theme-background-400,var(--co-background-400-mix,oklch(96% 0 0)));--co-background-500:var(--co-theme-background-500,var(--co-background-500-mix,oklch(97% 0 0)));--co-background-600:var(--co-theme-background-600,var(--co-background-600-mix,oklch(98% 0 0)));--co-foreground:var(--co-foreground-base);--co-popover:var(--co-popover-base);--co-popover-foreground:var(--co-popover-foreground-base);--co-primary:var(--co-primary-base);--co-primary-foreground:var(--co-primary-foreground-base);--co-secondary:var(--co-secondary-base);--co-secondary-foreground:var(--co-secondary-foreground-base);--co-muted:var(--co-theme-muted,var(--co-muted-mix,oklch(97% 0 0)));--co-muted-foreground:var(--co-theme-muted-foreground,var(--co-muted-foreground-mix,oklch(55.6% 0 0)));--co-border:var(--co-border-base);--co-input:var(--co-input-base);--co-ring:var(--co-ring-base);--co-accent:var(--co-accent-base);--co-accent-foreground:var(--co-accent-foreground-base);--co-pink:var(--co-theme-pink,oklch(76.3% .152 354));--co-yellow:var(--co-theme-yellow,oklch(86.4% .144 99));--co-blue:var(--co-theme-blue,oklch(72.5% .132 241));--co-orange:var(--co-theme-orange,oklch(74.5% .166 50));--co-destructive:var(--co-theme-destructive,oklch(57.7% .245 27.325));--co-destructive-foreground:var(--co-theme-destructive-foreground,oklch(57.7% .245 27.325));--co-success:var(--co-theme-success,oklch(71.7% .18 142));--co-success-foreground:var(--co-theme-success-foreground,oklch(26.5% .052 142.7));--co-neutral:var(--co-theme-neutral,oklch(60.8% 0 0));--co-neutral-foreground:var(--co-theme-neutral-foreground,oklch(25.6% 0 0));--co-warning:var(--co-theme-warning,oklch(86.4% .144 99));--co-warning-foreground:var(--co-theme-warning-foreground,oklch(41.4% .071 99))}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-base:var(--co-theme-background,oklch(15.5% 0 0));--co-foreground-base:var(--co-theme-foreground,oklch(95% 0 0));--co-popover-base:var(--co-theme-popover,oklch(14.5% 0 0));--co-popover-foreground-base:var(--co-theme-popover-foreground,oklch(95% 0 0));--co-primary-base:var(--co-theme-primary,oklch(98.5% 0 0));--co-primary-foreground-base:var(--co-theme-primary-foreground,oklch(14.5% 0 0));--co-secondary-base:var(--co-theme-secondary,oklch(26.9% 0 0));--co-secondary-foreground-base:var(--co-theme-secondary-foreground,oklch(95% 0 0));--co-border-base:var(--co-theme-border,oklch(26.9% 0 0));--co-input-base:var(--co-theme-input,oklch(26.9% 0 0));--co-ring-base:var(--co-theme-ring,var(--co-primary-base));--co-accent-base:var(--co-theme-accent,var(--co-primary-base));--co-accent-foreground-base:var(--co-theme-accent-foreground,var(--co-primary-foreground-base));--co-muted-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-muted-mix:color-mix(in oklch,var(--co-background-base)55%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-muted-foreground-mix:var(--co-foreground-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-muted-foreground-mix:color-mix(in oklch,var(--co-foreground-base)65%,white)}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-50-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-50-mix:color-mix(in oklch,var(--co-background-base)98%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-100-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-100-mix:color-mix(in oklch,var(--co-background-base)96%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-200-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-200-mix:color-mix(in oklch,var(--co-background-base)94%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-300-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-300-mix:color-mix(in oklch,var(--co-background-base)92%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-400-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-400-mix:color-mix(in oklch,var(--co-background-base)90%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-500-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-500-mix:color-mix(in oklch,var(--co-background-base)88%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-600-mix:var(--co-background-base)}@supports (color:color-mix(in lab, red, red)){.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-background-600-mix:color-mix(in oklch,var(--co-background-base)86%,var(--co-foreground-base))}}.dark .cossistant,.cossistant[data-color-scheme=dark]{--co-pink:var(--co-theme-pink,oklch(84.2% .109 354));--co-yellow:var(--co-theme-yellow,oklch(90.3% .111 99));--co-blue:var(--co-theme-blue,oklch(79.8% .089 241));--co-orange:var(--co-theme-orange,oklch(68.2% .194 50));--co-destructive:var(--co-theme-destructive,oklch(39.6% .141 25.723));--co-destructive-foreground:var(--co-theme-destructive-foreground,oklch(63.7% .237 25.331));--co-success:var(--co-theme-success,oklch(60% .15 142));--co-success-foreground:var(--co-theme-success-foreground,oklch(85% .12 142));--co-neutral:var(--co-theme-neutral,oklch(50% 0 0));--co-neutral-foreground:var(--co-theme-neutral-foreground,oklch(85% 0 0));--co-warning:var(--co-theme-warning,oklch(90.3% .111 99));--co-warning-foreground:var(--co-theme-warning-foreground,oklch(85% .1 99))}}@layer utilities{.cossistant .co-scrollbar-thin{scrollbar-width:thin;scrollbar-color:oklch(from var(--co-primary)l c h/.3)transparent}.cossistant .co-scrollbar-thin::-webkit-scrollbar{width:8px;height:8px}.cossistant .co-scrollbar-thin::-webkit-scrollbar-track{background:0 0}.cossistant .co-scrollbar-thin::-webkit-scrollbar-thumb{background-color:oklch(from var(--co-primary)l c h/.3);border-radius:4px}.cossistant .co-scrollbar-thin::-webkit-scrollbar-thumb:hover{background-color:oklch(from var(--co-primary)l c h/.5)}.cossistant .animation-delay-0{animation-delay:0s}.cossistant .animation-delay-200{animation-delay:.2s}.cossistant .animation-delay-400{animation-delay:.4s}.cossistant .dot-bounce-1{animation:1.4s infinite bounce-dot}.cossistant .dot-bounce-2{animation:1.4s .16s infinite bounce-dot}.cossistant .dot-bounce-3{animation:1.4s .32s infinite bounce-dot}}
|
package/tailwind.css
CHANGED
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
@source "./components";
|
|
6
6
|
@source "./pages";
|
|
7
7
|
|
|
8
|
-
@plugin 'tailwind-scrollbar';
|
|
9
|
-
|
|
10
8
|
@layer base {
|
|
11
9
|
.cossistant {
|
|
12
10
|
@apply scroll-smooth;
|
|
@@ -324,6 +322,30 @@
|
|
|
324
322
|
|
|
325
323
|
@layer utilities {
|
|
326
324
|
.cossistant {
|
|
325
|
+
/* Native scrollbar styling */
|
|
326
|
+
.co-scrollbar-thin {
|
|
327
|
+
scrollbar-width: thin;
|
|
328
|
+
scrollbar-color: oklch(from var(--co-primary) l c h / 0.3) transparent;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.co-scrollbar-thin::-webkit-scrollbar {
|
|
332
|
+
width: 8px;
|
|
333
|
+
height: 8px;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.co-scrollbar-thin::-webkit-scrollbar-track {
|
|
337
|
+
background: transparent;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.co-scrollbar-thin::-webkit-scrollbar-thumb {
|
|
341
|
+
background-color: oklch(from var(--co-primary) l c h / 0.3);
|
|
342
|
+
border-radius: 4px;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.co-scrollbar-thin::-webkit-scrollbar-thumb:hover {
|
|
346
|
+
background-color: oklch(from var(--co-primary) l c h / 0.5);
|
|
347
|
+
}
|
|
348
|
+
|
|
327
349
|
.animation-delay-0 {
|
|
328
350
|
animation-delay: 0ms;
|
|
329
351
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-render-element.d.ts","names":[],"sources":["../../src/utils/use-render-element.tsx"],"sourcesContent":[],"mappings":";;;;AAI+B,KAE1B,YAAA,GAAY,MAAS,GAAA,CAAI,iBAAA;AAAiB,KAE1C,SAAA,CAAA,KAAS,CAAA,GAAA,MAAA,
|
|
1
|
+
{"version":3,"file":"use-render-element.d.ts","names":[],"sources":["../../src/utils/use-render-element.tsx"],"sourcesContent":[],"mappings":";;;;AAI+B,KAE1B,YAAA,GAAY,MAAS,GAAA,CAAI,iBAAA;AAAiB,KAE1C,SAAA,CAAA,KAAS,CAAA,GAAA,MAAA,GAAA,CAA4B,CAAA,KAAK,EAAL,KAAK,EAAA,GAAA,MAAA,CAAA;AAAA,KAE1C,QAAA,CAAA,KAAQ,EAAA,KAAA,CAAA,GAAA,CAAA,KAAA,EACL,KADK,EAAA,KAAA,EAEL,KAFK,EAAA,GAGR,OAAA,CAAM,YAHE;KAKR,WAJG,CAAA,KAAA,EAAA,YAI4B,YAJ5B,CAAA,GAAA;EACA,MAAA,CAAA,EAIE,OAAA,CAAM,YAJR,GAIuB,QAJvB,CAIgC,GAAA,CAAI,iBAJpC,CAIsD,GAJtD,CAAA,EAI4D,KAJ5D,CAAA;EACH,SAAM,CAAA,EAIE,SAJF,CAIY,KAJZ,CAAA;EAAY,OAAA,CAAA,EAAA,OAAA;AAAA,CAAA;KAQlB,YAN+B,CAAA,KAAA,EAAA,YAMC,YAND,CAAA,GAAA;EAC1B,KAAM,CAAA,EAMP,KANO;EAAwB,GAAI,CAAA,EAOrC,OAAA,CAAM,GAP+B,CAAA,GAAA,CAAA;EAAkB,KAAA,CAAA,EAQrD,OARqD,CAQ7C,GAAA,CAAI,iBARyC,CAQvB,GARuB,CAAA,CAAA;EAAM,OAAA,CAAA,EAAA,OAAA;CAArC;;;;AAK1B,iBAyBW,gBAzBC,CAAA,cA0BF,MA1BE,CAAA,MAAA,EAAA,GAAA,CAAA,EAAA,YA2BJ,YA3BI,CAAA,CAAA,GAAA,EA6BX,GA7BW,EAAA,cAAA,EA8BA,WA9BA,CA8BY,KA9BZ,EA8BmB,GA9BnB,CAAA,EAAA,MAAA,CAAA,EA+BP,YA/BO,CA+BM,KA/BN,EA+Ba,GA/Bb,CAAA,CAAA,EAgCd,OAAA,CAAM,YAhCQ,GAAA,IAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"support-BQhCt9Za.css","names":[],"sources":["../../src/support/support.css"],"sourcesContent":["/*\n* This indicates to tailwind to\n* compile classes from Cossistant with the host tailwind config\n*/\n@source \"./components\";\n@source \"./pages\";\n\n@plugin 'tailwind-scrollbar';\n\n@layer base {\n\t.cossistant {\n\t\t@apply scroll-smooth;\n\t\t@apply text-co-primary;\n\n\t\tcolor-scheme: inherit;\n\n\t\t/* Typeface tokens */\n\t\t--co-font-sans: var(--co-theme-font-sans, \"Geist\", \"Inter\", sans-serif);\n\t\t--co-font-mono: var(\n\t\t\t--co-theme-font-mono,\n\t\t\t\"Geist Mono\",\n\t\t\t\"Inter Mono\",\n\t\t\tmonospace\n\t\t);\n\n\t\t/* Core surfaces */\n\t\t--co-radius: var(--co-theme-radius, 0.625rem);\n\t\t--co-background-base: var(--co-theme-background, oklch(99% 0 0));\n\t\t--co-foreground-base: var(--co-theme-foreground, oklch(20.5% 0 0));\n\t\t--co-popover-base: var(--co-theme-popover, var(--co-background-base));\n\t\t--co-popover-foreground-base: var(\n\t\t\t--co-theme-popover-foreground,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-primary-base: var(--co-theme-primary, oklch(14.5% 0 0));\n\t\t--co-primary-foreground-base: var(\n\t\t\t--co-theme-primary-foreground,\n\t\t\toklch(98.5% 0 0)\n\t\t);\n\t\t--co-secondary-base: var(--co-theme-secondary, oklch(97% 0 0));\n\t\t--co-secondary-foreground-base: var(\n\t\t\t--co-theme-secondary-foreground,\n\t\t\toklch(14.5% 0 0)\n\t\t);\n\t\t--co-border-base: var(--co-theme-border, oklch(92.2% 0 0));\n\t\t--co-input-base: var(--co-theme-input, oklch(92.2% 0 0));\n\t\t--co-ring-base: var(--co-theme-ring, var(--co-primary-base));\n\t\t--co-accent-base: var(--co-theme-accent, var(--co-primary-base));\n\t\t--co-accent-foreground-base: var(\n\t\t\t--co-theme-accent-foreground,\n\t\t\tvar(--co-primary-foreground-base)\n\t\t);\n\n\t\t/* Neutral shades derived from the background */\n\t\t--co-background-50-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 98%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-100-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 97%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-200-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 96%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-300-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 95%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-400-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 94%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-500-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 93%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-600-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 92%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\n\t\t/* Muted tones */\n\t\t--co-muted-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 85%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-muted-foreground-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-foreground-base) 70%,\n\t\t\twhite\n\t\t);\n\n\t\t/* Public tokens consumed by Tailwind theme */\n\t\t--co-background: var(--co-background-base);\n\t\t--co-background-50: var(\n\t\t\t--co-theme-background-50,\n\t\t\tvar(--co-background-50-mix, oklch(92% 0 0))\n\t\t);\n\t\t--co-background-100: var(\n\t\t\t--co-theme-background-100,\n\t\t\tvar(--co-background-100-mix, oklch(93% 0 0))\n\t\t);\n\t\t--co-background-200: var(\n\t\t\t--co-theme-background-200,\n\t\t\tvar(--co-background-200-mix, oklch(94% 0 0))\n\t\t);\n\t\t--co-background-300: var(\n\t\t\t--co-theme-background-300,\n\t\t\tvar(--co-background-300-mix, oklch(95% 0 0))\n\t\t);\n\t\t--co-background-400: var(\n\t\t\t--co-theme-background-400,\n\t\t\tvar(--co-background-400-mix, oklch(96% 0 0))\n\t\t);\n\t\t--co-background-500: var(\n\t\t\t--co-theme-background-500,\n\t\t\tvar(--co-background-500-mix, oklch(97% 0 0))\n\t\t);\n\t\t--co-background-600: var(\n\t\t\t--co-theme-background-600,\n\t\t\tvar(--co-background-600-mix, oklch(98% 0 0))\n\t\t);\n\n\t\t--co-foreground: var(--co-foreground-base);\n\t\t--co-popover: var(--co-popover-base);\n\t\t--co-popover-foreground: var(--co-popover-foreground-base);\n\t\t--co-primary: var(--co-primary-base);\n\t\t--co-primary-foreground: var(--co-primary-foreground-base);\n\t\t--co-secondary: var(--co-secondary-base);\n\t\t--co-secondary-foreground: var(--co-secondary-foreground-base);\n\t\t--co-muted: var(--co-theme-muted, var(--co-muted-mix, oklch(97% 0 0)));\n\t\t--co-muted-foreground: var(\n\t\t\t--co-theme-muted-foreground,\n\t\t\tvar(--co-muted-foreground-mix, oklch(55.6% 0 0))\n\t\t);\n\t\t--co-border: var(--co-border-base);\n\t\t--co-input: var(--co-input-base);\n\t\t--co-ring: var(--co-ring-base);\n\t\t--co-accent: var(--co-accent-base);\n\t\t--co-accent-foreground: var(--co-accent-foreground-base);\n\n\t\t/* Accent palette */\n\t\t--co-pink: var(--co-theme-pink, oklch(76.3% 0.152 354));\n\t\t--co-yellow: var(--co-theme-yellow, oklch(86.4% 0.144 99));\n\t\t--co-blue: var(--co-theme-blue, oklch(72.5% 0.132 241));\n\t\t--co-orange: var(--co-theme-orange, oklch(74.5% 0.166 50));\n\n\t\t/* Status colors */\n\t\t--co-destructive: var(--co-theme-destructive, oklch(57.7% 0.245 27.325));\n\t\t--co-destructive-foreground: var(\n\t\t\t--co-theme-destructive-foreground,\n\t\t\toklch(57.7% 0.245 27.325)\n\t\t);\n\t\t--co-success: var(--co-theme-success, oklch(71.7% 0.18 142));\n\t\t--co-success-foreground: var(\n\t\t\t--co-theme-success-foreground,\n\t\t\toklch(26.5% 0.052 142.7)\n\t\t);\n\t\t--co-neutral: var(--co-theme-neutral, oklch(60.8% 0 0));\n\t\t--co-neutral-foreground: var(\n\t\t\t--co-theme-neutral-foreground,\n\t\t\toklch(25.6% 0 0)\n\t\t);\n\t\t--co-warning: var(--co-theme-warning, oklch(86.4% 0.144 99));\n\t\t--co-warning-foreground: var(\n\t\t\t--co-theme-warning-foreground,\n\t\t\toklch(41.4% 0.071 99)\n\t\t);\n\n\t\t/* Tailwind theme mapping - scoped to widget */\n\t\t@theme inline {\n\t\t\t--font-co-sans: var(--co-font-sans);\n\t\t\t--font-co-mono: var(--co-font-mono);\n\t\t\t--color-co-background: var(--co-background);\n\t\t\t--color-co-background-50: var(--co-background-50);\n\t\t\t--color-co-background-100: var(--co-background-100);\n\t\t\t--color-co-background-200: var(--co-background-200);\n\t\t\t--color-co-background-300: var(--co-background-300);\n\t\t\t--color-co-background-400: var(--co-background-400);\n\t\t\t--color-co-background-500: var(--co-background-500);\n\t\t\t--color-co-background-600: var(--co-background-600);\n\n\t\t\t--color-co-foreground: var(--co-foreground);\n\n\t\t\t--color-co-primary: var(--co-primary);\n\t\t\t--color-co-primary-foreground: var(--co-primary-foreground);\n\t\t\t--color-co-secondary: var(--co-secondary);\n\t\t\t--color-co-secondary-foreground: var(--co-secondary-foreground);\n\t\t\t--color-co-muted: var(--co-muted);\n\t\t\t--color-co-muted-foreground: var(--co-muted-foreground);\n\t\t\t--color-co-border: var(--co-border);\n\t\t\t--color-co-input: var(--co-input);\n\t\t\t--color-co-ring: var(--co-ring);\n\t\t\t--radius-co: var(--co-radius);\n\n\t\t\t/* custom colors */\n\t\t\t--color-co-pink: var(--co-pink);\n\t\t\t--color-co-yellow: var(--co-yellow);\n\t\t\t--color-co-blue: var(--co-blue);\n\t\t\t--color-co-orange: var(--co-orange);\n\n\t\t\t/* status colors */\n\t\t\t--color-co-destructive: var(--co-destructive);\n\t\t\t--color-co-destructive-foreground: var(--co-destructive-foreground);\n\t\t\t--color-co-success: var(--co-success);\n\t\t\t--color-co-success-foreground: var(--co-success-foreground);\n\t\t\t--color-co-neutral: var(--co-neutral);\n\t\t\t--color-co-neutral-foreground: var(--co-neutral-foreground);\n\t\t\t--color-co-warning: var(--co-warning);\n\t\t\t--color-co-warning-foreground: var(--co-warning-foreground);\n\t\t}\n\t}\n\n\t.dark .cossistant,\n\t.cossistant[data-color-scheme=\"dark\"] {\n\t\t/* Dark mode defaults */\n\t\t--co-background-base: var(--co-theme-background, oklch(15.5% 0 0));\n\t\t--co-foreground-base: var(--co-theme-foreground, oklch(95% 0 0));\n\t\t--co-popover-base: var(--co-theme-popover, oklch(14.5% 0 0));\n\t\t--co-popover-foreground-base: var(\n\t\t\t--co-theme-popover-foreground,\n\t\t\toklch(95% 0 0)\n\t\t);\n\t\t--co-primary-base: var(--co-theme-primary, oklch(98.5% 0 0));\n\t\t--co-primary-foreground-base: var(\n\t\t\t--co-theme-primary-foreground,\n\t\t\toklch(14.5% 0 0)\n\t\t);\n\t\t--co-secondary-base: var(--co-theme-secondary, oklch(26.9% 0 0));\n\t\t--co-secondary-foreground-base: var(\n\t\t\t--co-theme-secondary-foreground,\n\t\t\toklch(95% 0 0)\n\t\t);\n\t\t--co-border-base: var(--co-theme-border, oklch(26.9% 0 0));\n\t\t--co-input-base: var(--co-theme-input, oklch(26.9% 0 0));\n\t\t--co-ring-base: var(--co-theme-ring, var(--co-primary-base));\n\t\t--co-accent-base: var(--co-theme-accent, var(--co-primary-base));\n\t\t--co-accent-foreground-base: var(\n\t\t\t--co-theme-accent-foreground,\n\t\t\tvar(--co-primary-foreground-base)\n\t\t);\n\n\t\t--co-muted-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 55%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-muted-foreground-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-foreground-base) 65%,\n\t\t\twhite\n\t\t);\n\n\t\t--co-background-50-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 98%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-100-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 96%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-200-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 94%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-300-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 92%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-400-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 90%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-500-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 88%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\t\t--co-background-600-mix: color-mix(\n\t\t\tin oklch,\n\t\t\tvar(--co-background-base) 86%,\n\t\t\tvar(--co-foreground-base)\n\t\t);\n\n\t\t--co-pink: var(--co-theme-pink, oklch(84.2% 0.109 354));\n\t\t--co-yellow: var(--co-theme-yellow, oklch(90.3% 0.111 99));\n\t\t--co-blue: var(--co-theme-blue, oklch(79.8% 0.089 241));\n\t\t--co-orange: var(--co-theme-orange, oklch(68.2% 0.194 50));\n\n\t\t--co-destructive: var(--co-theme-destructive, oklch(39.6% 0.141 25.723));\n\t\t--co-destructive-foreground: var(\n\t\t\t--co-theme-destructive-foreground,\n\t\t\toklch(63.7% 0.237 25.331)\n\t\t);\n\t\t--co-success: var(--co-theme-success, oklch(60% 0.15 142));\n\t\t--co-success-foreground: var(\n\t\t\t--co-theme-success-foreground,\n\t\t\toklch(85% 0.12 142)\n\t\t);\n\t\t--co-neutral: var(--co-theme-neutral, oklch(50% 0 0));\n\t\t--co-neutral-foreground: var(--co-theme-neutral-foreground, oklch(85% 0 0));\n\t\t--co-warning: var(--co-theme-warning, oklch(90.3% 0.111 99));\n\t\t--co-warning-foreground: var(\n\t\t\t--co-theme-warning-foreground,\n\t\t\toklch(85% 0.1 99)\n\t\t);\n\t}\n}\n\n@layer utilities {\n\t.cossistant {\n\t\t.animation-delay-0 {\n\t\t\tanimation-delay: 0ms;\n\t\t}\n\t\t.animation-delay-200 {\n\t\t\tanimation-delay: 200ms;\n\t\t}\n\t\t.animation-delay-400 {\n\t\t\tanimation-delay: 400ms;\n\t\t}\n\n\t\t@keyframes bounce-dot {\n\t\t\t0%,\n\t\t\t80%,\n\t\t\t100% {\n\t\t\t\ttransform: translateY(0);\n\t\t\t}\n\t\t\t40% {\n\t\t\t\ttransform: translateY(-6px);\n\t\t\t}\n\t\t}\n\n\t\t.dot-bounce-1 {\n\t\t\tanimation: bounce-dot 1.4s infinite;\n\t\t\tanimation-delay: 0s;\n\t\t}\n\n\t\t.dot-bounce-2 {\n\t\t\tanimation: bounce-dot 1.4s infinite;\n\t\t\tanimation-delay: 0.16s;\n\t\t}\n\n\t\t.dot-bounce-3 {\n\t\t\tanimation: bounce-dot 1.4s infinite;\n\t\t\tanimation-delay: 0.32s;\n\t\t}\n\t}\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA"}
|