@sensiblestats/widget-sdk 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @sensiblestats/widget-sdk
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add to slip on betting insight cards.
8
+
9
+ The operator supplies an `onAddToSlip` callback; the widget hands it one selection
10
+ keyed by `matchOddsId` (the operator's own odds-row id) and maps the callback's
11
+ typed result to a localized (en/tr) toast. Two server fields drive it:
12
+ `odds.matchOddsId` and the per-operator gate `addToSlipEnabled` — the button
13
+ renders only when the gate is true, a handler is supplied, and the insight carries
14
+ a usable odds id. The widget never touches stake, balance, or bet placement.
15
+
16
+ - **widget-sdk:** add `SlipSelection`, `AddToSlipResult`, `AddToSlipRejectReason`,
17
+ and the `isAddToSlipResult` runtime guard; extend `BettingInsight` with
18
+ `addToSlipEnabled` and `odds.matchOddsId`.
19
+ - **widget-react:** add `AddToSlipButton` and `Toast`, the `slip.ts` result→toast
20
+ mapping (which honours `price_changed.accepted`), en/tr copy, `conversationId`
21
+ capture on `turn_complete`, and the `onAddToSlip` config entry. Malformed
22
+ results, throws, and a 10s timeout all fail closed to a retryable button.
23
+ - **widget-embed:** re-bundles widget-react, so it is republished. Add-to-slip is
24
+ not exposed to script-tag hosts, because a callback cannot be expressed in a
25
+ `data-*` attribute.
26
+
27
+ This shipped to master in `dd2da0e1` (#248) but never reached npm, because the
28
+ version was not bumped in the merged commit and the release workflow's
29
+ `--tolerate-republish` therefore skipped every package.
30
+
31
+ ## 0.5.0
32
+
33
+ ### Minor Changes
34
+
35
+ - Show competition name on betting insight cards. This shipped to master in
36
+ `6d629e6b` but never reached npm because the version wasn't bumped, so the
37
+ release workflow's `--tolerate-republish` skipped every package. This changeset
38
+ bumps all three so the change actually publishes (widget-embed re-bundles
39
+ widget-react, so it must be republished too).
40
+
3
41
  ## 0.4.0
4
42
 
5
43
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -30,7 +30,8 @@ __export(index_exports, {
30
30
  SIGNAL_TYPE_CODES: () => SIGNAL_TYPE_CODES,
31
31
  StatsWidgetClient: () => StatsWidgetClient,
32
32
  UpstreamError: () => UpstreamError,
33
- WidgetSdkError: () => WidgetSdkError
33
+ WidgetSdkError: () => WidgetSdkError,
34
+ isAddToSlipResult: () => isAddToSlipResult
34
35
  });
35
36
  module.exports = __toCommonJS(index_exports);
36
37
 
@@ -336,6 +337,24 @@ var StatsWidgetClient = class {
336
337
  return new Conversation(this.cfg, context);
337
338
  }
338
339
  };
340
+
341
+ // src/types.ts
342
+ var REJECT_REASONS = ["suspended", "closed", "login_required", "not_found", "limit", "unsupported"];
343
+ function isAddToSlipResult(v) {
344
+ if (typeof v !== "object" || v === null) return false;
345
+ const o = v;
346
+ switch (o.status) {
347
+ case "added":
348
+ case "duplicate":
349
+ return true;
350
+ case "price_changed":
351
+ return typeof o.newOddsDecimal === "number" && Number.isFinite(o.newOddsDecimal) && typeof o.accepted === "boolean";
352
+ case "rejected":
353
+ return typeof o.reason === "string" && REJECT_REASONS.includes(o.reason);
354
+ default:
355
+ return false;
356
+ }
357
+ }
339
358
  // Annotate the CommonJS export names for ESM import in node:
340
359
  0 && (module.exports = {
341
360
  AuthError,
@@ -348,6 +367,7 @@ var StatsWidgetClient = class {
348
367
  SIGNAL_TYPE_CODES,
349
368
  StatsWidgetClient,
350
369
  UpstreamError,
351
- WidgetSdkError
370
+ WidgetSdkError,
371
+ isAddToSlipResult
352
372
  });
353
373
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/ndjson.ts","../src/chat.ts","../src/signals.ts","../src/conversation.ts","../src/client.ts"],"sourcesContent":["export { StatsWidgetClient } from './client'\nexport { Conversation } from './conversation'\nexport type { ChatCallbacks, ChatHandle } from './chat'\nexport { SIGNAL_TYPE_CODES, ENTITY_TYPE_CODES } from './signals'\nexport {\n WidgetSdkError, AuthError, ForbiddenError, RateLimitError, UpstreamError, NetworkError, ParseError,\n} from './errors'\nexport type {\n StatsWidgetClientOptions, FetchLike, UserContext, ChatInput,\n SignalType, SignalEntityType, SignalInput,\n} from './types'\nexport type {\n ChatEvent, ProgressEventData, AnswerEventData, EntityCard, EntityCardStat, EntityCardEventData,\n ActionButtonEventData, IntentChipEventData, ActionsLoadingEventData,\n TurnCompleteEventData, StreamErrorEventData,\n BettingInsight, BettingInsightOdds, BettingInsightStat, BettingInsightEventData,\n} from './events'\n","export class WidgetSdkError extends Error {\n readonly code: string\n readonly status?: number\n constructor(message: string, code: string, status?: number) {\n super(message)\n this.name = new.target.name\n this.code = code\n this.status = status\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\nexport class AuthError extends WidgetSdkError {\n constructor(message = 'Invalid or missing public key') { super(message, 'unauthorized', 401) }\n}\nexport class ForbiddenError extends WidgetSdkError {\n constructor(message = 'Origin not allowed or widget disabled') { super(message, 'forbidden', 403) }\n}\nexport class RateLimitError extends WidgetSdkError {\n readonly retryAfter?: number\n constructor(retryAfter?: number, message = 'Rate limited') { super(message, 'rate_limited', 429); this.retryAfter = retryAfter }\n}\nexport class UpstreamError extends WidgetSdkError {\n constructor(status: number, message = 'Upstream error') { super(message, 'upstream_error', status) }\n}\nexport class NetworkError extends WidgetSdkError {\n readonly cause?: unknown\n constructor(message = 'Network request failed', cause?: unknown) { super(message, 'network_error'); this.cause = cause }\n}\nexport class ParseError extends WidgetSdkError {\n readonly line?: string\n constructor(message = 'Malformed NDJSON line', line?: string) { super(message, 'parse_error'); this.line = line }\n}\n","import { AuthError, ForbiddenError, NetworkError, RateLimitError, UpstreamError, WidgetSdkError } from './errors'\nimport type { ChatInput, FetchLike } from './types'\n\nexport interface ResolvedConfig {\n operatorId: string\n publicKey: string\n baseUrl: string\n fetch: FetchLike\n}\n\nfunction endpoint(cfg: ResolvedConfig, path: string): string {\n return `${cfg.baseUrl.replace(/\\/+$/, '')}/v1/${encodeURIComponent(cfg.operatorId)}/${path}`\n}\n\nexport function toWidgetError(status: number, retryAfterHeader: string | null): WidgetSdkError {\n switch (status) {\n case 401: return new AuthError()\n case 403: return new ForbiddenError()\n case 429: {\n const n = retryAfterHeader != null ? Number(retryAfterHeader) : undefined\n return new RateLimitError(Number.isFinite(n) ? (n as number) : undefined)\n }\n default: return new UpstreamError(status)\n }\n}\n\nfunction isAbort(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n\nasync function send(cfg: ResolvedConfig, path: string, body: object, signal?: AbortSignal): Promise<Response> {\n try {\n return await cfg.fetch(endpoint(cfg, path), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-SS-Public-Key': cfg.publicKey },\n body: JSON.stringify(body),\n signal,\n })\n } catch (error) {\n if (isAbort(error)) throw error\n throw new NetworkError('Network request failed', error)\n }\n}\n\nexport async function postChat(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): Promise<Response> {\n const res = await send(cfg, 'chat', input, signal)\n if (!res.ok || res.body == null) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n return res\n}\n\nexport async function postSignal(cfg: ResolvedConfig, wireBody: object, signal?: AbortSignal): Promise<void> {\n const res = await send(cfg, 'signals', wireBody, signal)\n if (!res.ok) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n}\n","import { ParseError } from './errors'\n\nexport interface NdjsonParser {\n push(text: string): unknown[]\n flush(): unknown[]\n}\n\nfunction parseLine(line: string): unknown | undefined {\n const trimmed = line.trim()\n if (trimmed === '') return undefined\n try {\n return JSON.parse(trimmed)\n } catch {\n throw new ParseError('Malformed NDJSON line', line)\n }\n}\n\nexport function createNdjsonParser(): NdjsonParser {\n let buffer = ''\n return {\n push(text: string): unknown[] {\n buffer += text\n const out: unknown[] = []\n let idx: number\n while ((idx = buffer.indexOf('\\n')) >= 0) {\n const line = buffer.slice(0, idx)\n buffer = buffer.slice(idx + 1)\n const parsed = parseLine(line)\n if (parsed !== undefined) out.push(parsed)\n }\n return out\n },\n flush(): unknown[] {\n const rest = buffer\n buffer = ''\n const parsed = parseLine(rest)\n return parsed === undefined ? [] : [parsed]\n },\n }\n}\n","import { WidgetSdkError } from './errors'\nimport type {\n ActionButtonEventData, ActionsLoadingEventData, AnswerEventData, ChatEvent,\n EntityCardEventData, IntentChipEventData, ProgressEventData, StreamErrorEventData, TurnCompleteEventData,\n} from './events'\nimport { postChat, type ResolvedConfig } from './http'\nimport { createNdjsonParser } from './ndjson'\nimport type { ChatInput } from './types'\n\nexport interface ChatCallbacks {\n onProgress?(data: ProgressEventData): void\n onAnswer?(data: AnswerEventData): void\n onEntityCard?(data: EntityCardEventData): void\n onActionButton?(data: ActionButtonEventData): void\n onIntentChip?(data: IntentChipEventData): void\n onActionsLoading?(data: ActionsLoadingEventData): void\n onError?(error: StreamErrorEventData | WidgetSdkError): void\n onComplete?(data: TurnCompleteEventData): void\n}\n\nexport interface ChatHandle extends AsyncIterable<ChatEvent>, PromiseLike<void> {\n cancel(): void\n}\n\nfunction dispatch(ev: ChatEvent, cb: ChatCallbacks): void {\n switch (ev.type) {\n case 'progress': cb.onProgress?.(ev.data); break\n case 'answer': cb.onAnswer?.(ev.data); break\n case 'entity_card': cb.onEntityCard?.(ev.data); break\n case 'action_button': cb.onActionButton?.(ev.data); break\n case 'intent_chip': cb.onIntentChip?.(ev.data); break\n case 'actions_loading': cb.onActionsLoading?.(ev.data); break\n case 'turn_complete': cb.onComplete?.(ev.data); break\n case 'error': cb.onError?.(ev.data); break\n }\n}\n\nasync function* streamEvents(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): AsyncGenerator<ChatEvent> {\n const res = await postChat(cfg, input, signal)\n const reader = res.body!.getReader()\n const decoder = new TextDecoder()\n const parser = createNdjsonParser()\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n for (const obj of parser.push(decoder.decode(value, { stream: true }))) yield obj as ChatEvent\n }\n for (const obj of parser.flush()) yield obj as ChatEvent\n } finally {\n await reader.cancel().catch(() => {})\n }\n}\n\nexport function runChat(\n cfg: ResolvedConfig,\n input: ChatInput,\n callbacks?: ChatCallbacks,\n opts?: { signal?: AbortSignal; tap?: (ev: ChatEvent) => void },\n): ChatHandle {\n const controller = new AbortController()\n const external = opts?.signal\n if (external) {\n if (external.aborted) controller.abort()\n else external.addEventListener('abort', () => controller.abort(), { once: true })\n }\n\n async function* source(): AsyncGenerator<ChatEvent> {\n for await (const ev of streamEvents(cfg, input, controller.signal)) {\n opts?.tap?.(ev)\n yield ev\n }\n }\n\n const iterator = source()\n let consumed = false\n\n async function drive(): Promise<void> {\n try {\n for await (const ev of iterator) { if (callbacks) dispatch(ev, callbacks) }\n } catch (error) {\n if (callbacks?.onError && error instanceof WidgetSdkError) { callbacks.onError(error); return }\n throw error\n }\n }\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<ChatEvent> {\n if (consumed) throw new Error('chat stream already consumed')\n consumed = true\n return iterator\n },\n then<TResult1 = void, TResult2 = never>(\n onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n if (consumed) return Promise.resolve().then(onfulfilled, onrejected)\n consumed = true\n return drive().then(onfulfilled, onrejected)\n },\n cancel(): void { controller.abort() },\n }\n}\n","import type { SignalEntityType, SignalInput, SignalType } from './types'\n\nexport const SIGNAL_TYPE_CODES: Record<SignalType, number> = {\n MatchPageView: 1, PlayerPageView: 2, TeamPageView: 3, MarketView: 4,\n SearchQuery: 5, SessionDepth: 6, TimeOnPage: 7, InsightViewed: 8,\n InsightMarketClicked: 9, BetPlacedFromInsight: 10, InsightScrollDepth: 11,\n ToolCall: 12, EntityMention: 13, Handoff: 14, FollowUpQuery: 15, RecommendationDismissed: 16,\n}\n\nexport const ENTITY_TYPE_CODES: Record<SignalEntityType, number> = {\n Match: 1, Team: 2, Player: 3, Competition: 4, Market: 5,\n Article: 6, Session: 7, Query: 8, Conversation: 9,\n}\n\nexport function toSignalWireBody(input: SignalInput): {\n signalType: number; entityType: number; entityName: string; operatorUserId: string\n} {\n const signalType = SIGNAL_TYPE_CODES[input.signalType]\n const entityType = ENTITY_TYPE_CODES[input.entityType]\n if (signalType === undefined) throw new Error(`Unknown signalType: ${String(input.signalType)}`)\n if (entityType === undefined) throw new Error(`Unknown entityType: ${String(input.entityType)}`)\n return { signalType, entityType, entityName: input.entityName, operatorUserId: input.operatorUserId }\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport { postSignal, type ResolvedConfig } from './http'\nimport { toSignalWireBody } from './signals'\nimport type { ChatInput, SignalInput, UserContext } from './types'\n\nexport class Conversation {\n conversationId?: string\n\n constructor(private readonly cfg: ResolvedConfig, private readonly context?: UserContext) {}\n\n send(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n const mergedContext: UserContext = { ...this.context, ...input.userContext }\n const full: ChatInput = {\n ...input,\n conversationId: input.conversationId ?? this.conversationId,\n userContext: Object.keys(mergedContext).length > 0 ? mergedContext : undefined,\n }\n return runChat(this.cfg, full, callbacks, {\n tap: (ev) => { if (ev.type === 'turn_complete') this.conversationId = ev.data.conversationId },\n })\n }\n\n sendSignal(input: Omit<SignalInput, 'operatorUserId'> & { operatorUserId?: string }): Promise<void> {\n const operatorUserId = input.operatorUserId ?? this.context?.operatorUserId\n if (!operatorUserId) throw new Error('operatorUserId is required (set it on conversation() or pass it to sendSignal)')\n return postSignal(this.cfg, toSignalWireBody({ ...input, operatorUserId }))\n }\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport { Conversation } from './conversation'\nimport { postSignal, type ResolvedConfig } from './http'\nimport { toSignalWireBody } from './signals'\nimport type { ChatInput, SignalInput, StatsWidgetClientOptions, UserContext } from './types'\n\nconst DEFAULT_BASE_URL = 'https://widget.sensiblestats.com'\n\nexport class StatsWidgetClient {\n private readonly cfg: ResolvedConfig\n\n constructor(options: StatsWidgetClientOptions) {\n if (!options.operatorId) throw new Error('operatorId is required')\n if (!options.publicKey) throw new Error('publicKey is required')\n const fetchImpl = options.fetch ?? (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined)\n if (!fetchImpl) throw new Error('No fetch implementation available; pass options.fetch')\n this.cfg = {\n operatorId: options.operatorId,\n publicKey: options.publicKey,\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n fetch: fetchImpl,\n }\n }\n\n chat(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n return runChat(this.cfg, input, callbacks)\n }\n\n async sendSignal(input: SignalInput): Promise<void> {\n await postSignal(this.cfg, toSignalWireBody(input))\n }\n\n conversation(context?: UserContext): Conversation {\n return new Conversation(this.cfg, context)\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/ndjson.ts","../src/chat.ts","../src/signals.ts","../src/conversation.ts","../src/client.ts","../src/types.ts"],"sourcesContent":["export { StatsWidgetClient } from './client'\nexport { Conversation } from './conversation'\nexport type { ChatCallbacks, ChatHandle } from './chat'\nexport { SIGNAL_TYPE_CODES, ENTITY_TYPE_CODES } from './signals'\nexport {\n WidgetSdkError, AuthError, ForbiddenError, RateLimitError, UpstreamError, NetworkError, ParseError,\n} from './errors'\nexport type {\n StatsWidgetClientOptions, FetchLike, UserContext, ChatInput,\n SignalType, SignalEntityType, SignalInput,\n SlipSelection, AddToSlipRejectReason, AddToSlipResult, AddToSlipHandler,\n} from './types'\nexport { isAddToSlipResult } from './types'\nexport type {\n ChatEvent, ProgressEventData, AnswerEventData, EntityCard, EntityCardStat, EntityCardEventData,\n ActionButtonEventData, IntentChipEventData, ActionsLoadingEventData,\n TurnCompleteEventData, StreamErrorEventData,\n BettingInsight, BettingInsightOdds, BettingInsightStat, BettingInsightEventData,\n} from './events'\n","export class WidgetSdkError extends Error {\n readonly code: string\n readonly status?: number\n constructor(message: string, code: string, status?: number) {\n super(message)\n this.name = new.target.name\n this.code = code\n this.status = status\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\nexport class AuthError extends WidgetSdkError {\n constructor(message = 'Invalid or missing public key') { super(message, 'unauthorized', 401) }\n}\nexport class ForbiddenError extends WidgetSdkError {\n constructor(message = 'Origin not allowed or widget disabled') { super(message, 'forbidden', 403) }\n}\nexport class RateLimitError extends WidgetSdkError {\n readonly retryAfter?: number\n constructor(retryAfter?: number, message = 'Rate limited') { super(message, 'rate_limited', 429); this.retryAfter = retryAfter }\n}\nexport class UpstreamError extends WidgetSdkError {\n constructor(status: number, message = 'Upstream error') { super(message, 'upstream_error', status) }\n}\nexport class NetworkError extends WidgetSdkError {\n readonly cause?: unknown\n constructor(message = 'Network request failed', cause?: unknown) { super(message, 'network_error'); this.cause = cause }\n}\nexport class ParseError extends WidgetSdkError {\n readonly line?: string\n constructor(message = 'Malformed NDJSON line', line?: string) { super(message, 'parse_error'); this.line = line }\n}\n","import { AuthError, ForbiddenError, NetworkError, RateLimitError, UpstreamError, WidgetSdkError } from './errors'\nimport type { ChatInput, FetchLike } from './types'\n\nexport interface ResolvedConfig {\n operatorId: string\n publicKey: string\n baseUrl: string\n fetch: FetchLike\n}\n\nfunction endpoint(cfg: ResolvedConfig, path: string): string {\n return `${cfg.baseUrl.replace(/\\/+$/, '')}/v1/${encodeURIComponent(cfg.operatorId)}/${path}`\n}\n\nexport function toWidgetError(status: number, retryAfterHeader: string | null): WidgetSdkError {\n switch (status) {\n case 401: return new AuthError()\n case 403: return new ForbiddenError()\n case 429: {\n const n = retryAfterHeader != null ? Number(retryAfterHeader) : undefined\n return new RateLimitError(Number.isFinite(n) ? (n as number) : undefined)\n }\n default: return new UpstreamError(status)\n }\n}\n\nfunction isAbort(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n\nasync function send(cfg: ResolvedConfig, path: string, body: object, signal?: AbortSignal): Promise<Response> {\n try {\n return await cfg.fetch(endpoint(cfg, path), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-SS-Public-Key': cfg.publicKey },\n body: JSON.stringify(body),\n signal,\n })\n } catch (error) {\n if (isAbort(error)) throw error\n throw new NetworkError('Network request failed', error)\n }\n}\n\nexport async function postChat(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): Promise<Response> {\n const res = await send(cfg, 'chat', input, signal)\n if (!res.ok || res.body == null) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n return res\n}\n\nexport async function postSignal(cfg: ResolvedConfig, wireBody: object, signal?: AbortSignal): Promise<void> {\n const res = await send(cfg, 'signals', wireBody, signal)\n if (!res.ok) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n}\n","import { ParseError } from './errors'\n\nexport interface NdjsonParser {\n push(text: string): unknown[]\n flush(): unknown[]\n}\n\nfunction parseLine(line: string): unknown | undefined {\n const trimmed = line.trim()\n if (trimmed === '') return undefined\n try {\n return JSON.parse(trimmed)\n } catch {\n throw new ParseError('Malformed NDJSON line', line)\n }\n}\n\nexport function createNdjsonParser(): NdjsonParser {\n let buffer = ''\n return {\n push(text: string): unknown[] {\n buffer += text\n const out: unknown[] = []\n let idx: number\n while ((idx = buffer.indexOf('\\n')) >= 0) {\n const line = buffer.slice(0, idx)\n buffer = buffer.slice(idx + 1)\n const parsed = parseLine(line)\n if (parsed !== undefined) out.push(parsed)\n }\n return out\n },\n flush(): unknown[] {\n const rest = buffer\n buffer = ''\n const parsed = parseLine(rest)\n return parsed === undefined ? [] : [parsed]\n },\n }\n}\n","import { WidgetSdkError } from './errors'\nimport type {\n ActionButtonEventData, ActionsLoadingEventData, AnswerEventData, ChatEvent,\n EntityCardEventData, IntentChipEventData, ProgressEventData, StreamErrorEventData, TurnCompleteEventData,\n} from './events'\nimport { postChat, type ResolvedConfig } from './http'\nimport { createNdjsonParser } from './ndjson'\nimport type { ChatInput } from './types'\n\nexport interface ChatCallbacks {\n onProgress?(data: ProgressEventData): void\n onAnswer?(data: AnswerEventData): void\n onEntityCard?(data: EntityCardEventData): void\n onActionButton?(data: ActionButtonEventData): void\n onIntentChip?(data: IntentChipEventData): void\n onActionsLoading?(data: ActionsLoadingEventData): void\n onError?(error: StreamErrorEventData | WidgetSdkError): void\n onComplete?(data: TurnCompleteEventData): void\n}\n\nexport interface ChatHandle extends AsyncIterable<ChatEvent>, PromiseLike<void> {\n cancel(): void\n}\n\nfunction dispatch(ev: ChatEvent, cb: ChatCallbacks): void {\n switch (ev.type) {\n case 'progress': cb.onProgress?.(ev.data); break\n case 'answer': cb.onAnswer?.(ev.data); break\n case 'entity_card': cb.onEntityCard?.(ev.data); break\n case 'action_button': cb.onActionButton?.(ev.data); break\n case 'intent_chip': cb.onIntentChip?.(ev.data); break\n case 'actions_loading': cb.onActionsLoading?.(ev.data); break\n case 'turn_complete': cb.onComplete?.(ev.data); break\n case 'error': cb.onError?.(ev.data); break\n }\n}\n\nasync function* streamEvents(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): AsyncGenerator<ChatEvent> {\n const res = await postChat(cfg, input, signal)\n const reader = res.body!.getReader()\n const decoder = new TextDecoder()\n const parser = createNdjsonParser()\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n for (const obj of parser.push(decoder.decode(value, { stream: true }))) yield obj as ChatEvent\n }\n for (const obj of parser.flush()) yield obj as ChatEvent\n } finally {\n await reader.cancel().catch(() => {})\n }\n}\n\nexport function runChat(\n cfg: ResolvedConfig,\n input: ChatInput,\n callbacks?: ChatCallbacks,\n opts?: { signal?: AbortSignal; tap?: (ev: ChatEvent) => void },\n): ChatHandle {\n const controller = new AbortController()\n const external = opts?.signal\n if (external) {\n if (external.aborted) controller.abort()\n else external.addEventListener('abort', () => controller.abort(), { once: true })\n }\n\n async function* source(): AsyncGenerator<ChatEvent> {\n for await (const ev of streamEvents(cfg, input, controller.signal)) {\n opts?.tap?.(ev)\n yield ev\n }\n }\n\n const iterator = source()\n let consumed = false\n\n async function drive(): Promise<void> {\n try {\n for await (const ev of iterator) { if (callbacks) dispatch(ev, callbacks) }\n } catch (error) {\n if (callbacks?.onError && error instanceof WidgetSdkError) { callbacks.onError(error); return }\n throw error\n }\n }\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<ChatEvent> {\n if (consumed) throw new Error('chat stream already consumed')\n consumed = true\n return iterator\n },\n then<TResult1 = void, TResult2 = never>(\n onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n if (consumed) return Promise.resolve().then(onfulfilled, onrejected)\n consumed = true\n return drive().then(onfulfilled, onrejected)\n },\n cancel(): void { controller.abort() },\n }\n}\n","import type { SignalEntityType, SignalInput, SignalType } from './types'\n\nexport const SIGNAL_TYPE_CODES: Record<SignalType, number> = {\n MatchPageView: 1, PlayerPageView: 2, TeamPageView: 3, MarketView: 4,\n SearchQuery: 5, SessionDepth: 6, TimeOnPage: 7, InsightViewed: 8,\n InsightMarketClicked: 9, BetPlacedFromInsight: 10, InsightScrollDepth: 11,\n ToolCall: 12, EntityMention: 13, Handoff: 14, FollowUpQuery: 15, RecommendationDismissed: 16,\n}\n\nexport const ENTITY_TYPE_CODES: Record<SignalEntityType, number> = {\n Match: 1, Team: 2, Player: 3, Competition: 4, Market: 5,\n Article: 6, Session: 7, Query: 8, Conversation: 9,\n}\n\nexport function toSignalWireBody(input: SignalInput): {\n signalType: number; entityType: number; entityName: string; operatorUserId: string\n} {\n const signalType = SIGNAL_TYPE_CODES[input.signalType]\n const entityType = ENTITY_TYPE_CODES[input.entityType]\n if (signalType === undefined) throw new Error(`Unknown signalType: ${String(input.signalType)}`)\n if (entityType === undefined) throw new Error(`Unknown entityType: ${String(input.entityType)}`)\n return { signalType, entityType, entityName: input.entityName, operatorUserId: input.operatorUserId }\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport { postSignal, type ResolvedConfig } from './http'\nimport { toSignalWireBody } from './signals'\nimport type { ChatInput, SignalInput, UserContext } from './types'\n\nexport class Conversation {\n conversationId?: string\n\n constructor(private readonly cfg: ResolvedConfig, private readonly context?: UserContext) {}\n\n send(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n const mergedContext: UserContext = { ...this.context, ...input.userContext }\n const full: ChatInput = {\n ...input,\n conversationId: input.conversationId ?? this.conversationId,\n userContext: Object.keys(mergedContext).length > 0 ? mergedContext : undefined,\n }\n return runChat(this.cfg, full, callbacks, {\n tap: (ev) => { if (ev.type === 'turn_complete') this.conversationId = ev.data.conversationId },\n })\n }\n\n sendSignal(input: Omit<SignalInput, 'operatorUserId'> & { operatorUserId?: string }): Promise<void> {\n const operatorUserId = input.operatorUserId ?? this.context?.operatorUserId\n if (!operatorUserId) throw new Error('operatorUserId is required (set it on conversation() or pass it to sendSignal)')\n return postSignal(this.cfg, toSignalWireBody({ ...input, operatorUserId }))\n }\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport { Conversation } from './conversation'\nimport { postSignal, type ResolvedConfig } from './http'\nimport { toSignalWireBody } from './signals'\nimport type { ChatInput, SignalInput, StatsWidgetClientOptions, UserContext } from './types'\n\nconst DEFAULT_BASE_URL = 'https://widget.sensiblestats.com'\n\nexport class StatsWidgetClient {\n private readonly cfg: ResolvedConfig\n\n constructor(options: StatsWidgetClientOptions) {\n if (!options.operatorId) throw new Error('operatorId is required')\n if (!options.publicKey) throw new Error('publicKey is required')\n const fetchImpl = options.fetch ?? (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined)\n if (!fetchImpl) throw new Error('No fetch implementation available; pass options.fetch')\n this.cfg = {\n operatorId: options.operatorId,\n publicKey: options.publicKey,\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n fetch: fetchImpl,\n }\n }\n\n chat(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n return runChat(this.cfg, input, callbacks)\n }\n\n async sendSignal(input: SignalInput): Promise<void> {\n await postSignal(this.cfg, toSignalWireBody(input))\n }\n\n conversation(context?: UserContext): Conversation {\n return new Conversation(this.cfg, context)\n }\n}\n","export type FetchLike = (input: string, init: RequestInit) => Promise<Response>\n\nexport interface StatsWidgetClientOptions {\n operatorId: string\n publicKey: string\n baseUrl?: string\n /** Advanced/testing: inject a fetch implementation. Defaults to globalThis.fetch. */\n fetch?: FetchLike\n}\n\nexport interface UserContext {\n operatorUserId?: string\n defaultLanguage?: string\n}\n\nexport interface ChatInput {\n message: string\n conversationId?: string\n actionId?: string\n userContext?: UserContext\n}\n\nexport type SignalType =\n | 'MatchPageView' | 'PlayerPageView' | 'TeamPageView' | 'MarketView'\n | 'SearchQuery' | 'SessionDepth' | 'TimeOnPage' | 'InsightViewed'\n | 'InsightMarketClicked' | 'BetPlacedFromInsight' | 'InsightScrollDepth'\n | 'ToolCall' | 'EntityMention' | 'Handoff' | 'FollowUpQuery' | 'RecommendationDismissed'\n\nexport type SignalEntityType =\n | 'Match' | 'Team' | 'Player' | 'Competition' | 'Market'\n | 'Article' | 'Session' | 'Query' | 'Conversation'\n\nexport interface SignalInput {\n signalType: SignalType\n entityType: SignalEntityType\n entityName: string\n operatorUserId: string\n}\n\nexport interface SlipSelection {\n matchOddsId: number\n matchId: number\n oddsDecimal: number\n quotedAtUtc?: string\n insightId?: string\n conversationId?: string\n}\n\nexport type AddToSlipRejectReason =\n | 'suspended' | 'closed' | 'login_required'\n | 'not_found' | 'limit' | 'unsupported'\n\nexport type AddToSlipResult =\n | { status: 'added'; slip?: { selectionCount: number; totalOddsDecimal?: number } }\n | { status: 'duplicate' }\n | { status: 'price_changed'; newOddsDecimal: number; accepted: boolean }\n | { status: 'rejected'; reason: AddToSlipRejectReason; message?: string }\n\nexport type AddToSlipHandler = (\n selection: SlipSelection,\n) => Promise<AddToSlipResult | void> | AddToSlipResult | void\n\nconst REJECT_REASONS = ['suspended', 'closed', 'login_required', 'not_found', 'limit', 'unsupported']\n\nexport function isAddToSlipResult(v: unknown): v is AddToSlipResult {\n if (typeof v !== 'object' || v === null) return false\n const o = v as Record<string, unknown>\n switch (o.status) {\n case 'added':\n case 'duplicate':\n return true\n case 'price_changed':\n return typeof o.newOddsDecimal === 'number'\n && Number.isFinite(o.newOddsDecimal)\n && typeof o.accepted === 'boolean'\n case 'rejected':\n return typeof o.reason === 'string'\n && REJECT_REASONS.includes(o.reason)\n default:\n return false\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -77,6 +77,7 @@ interface BettingInsightOdds {
77
77
  bookmakerName?: string;
78
78
  quotedAtUtc?: string;
79
79
  isLive?: boolean;
80
+ matchOddsId?: number;
80
81
  }
81
82
  interface BettingInsightStat {
82
83
  label: string;
@@ -99,11 +100,13 @@ interface BettingInsight {
99
100
  disclaimer?: string | null;
100
101
  homeTeamName?: string;
101
102
  awayTeamName?: string;
103
+ competitionName?: string;
102
104
  scopes?: {
103
105
  key: string;
104
106
  label: string;
105
107
  stats: BettingInsightStat[];
106
108
  }[];
109
+ addToSlipEnabled?: boolean;
107
110
  [key: string]: unknown;
108
111
  }
109
112
  interface BettingInsightEventData {
@@ -143,6 +146,34 @@ interface SignalInput {
143
146
  entityName: string;
144
147
  operatorUserId: string;
145
148
  }
149
+ interface SlipSelection {
150
+ matchOddsId: number;
151
+ matchId: number;
152
+ oddsDecimal: number;
153
+ quotedAtUtc?: string;
154
+ insightId?: string;
155
+ conversationId?: string;
156
+ }
157
+ type AddToSlipRejectReason = 'suspended' | 'closed' | 'login_required' | 'not_found' | 'limit' | 'unsupported';
158
+ type AddToSlipResult = {
159
+ status: 'added';
160
+ slip?: {
161
+ selectionCount: number;
162
+ totalOddsDecimal?: number;
163
+ };
164
+ } | {
165
+ status: 'duplicate';
166
+ } | {
167
+ status: 'price_changed';
168
+ newOddsDecimal: number;
169
+ accepted: boolean;
170
+ } | {
171
+ status: 'rejected';
172
+ reason: AddToSlipRejectReason;
173
+ message?: string;
174
+ };
175
+ type AddToSlipHandler = (selection: SlipSelection) => Promise<AddToSlipResult | void> | AddToSlipResult | void;
176
+ declare function isAddToSlipResult(v: unknown): v is AddToSlipResult;
146
177
 
147
178
  interface ResolvedConfig {
148
179
  operatorId: string;
@@ -187,4 +218,4 @@ declare class StatsWidgetClient {
187
218
  declare const SIGNAL_TYPE_CODES: Record<SignalType, number>;
188
219
  declare const ENTITY_TYPE_CODES: Record<SignalEntityType, number>;
189
220
 
190
- export { type ActionButtonEventData, type ActionsLoadingEventData, type AnswerEventData, AuthError, type BettingInsight, type BettingInsightEventData, type BettingInsightOdds, type BettingInsightStat, type ChatCallbacks, type ChatEvent, type ChatHandle, type ChatInput, Conversation, ENTITY_TYPE_CODES, type EntityCard, type EntityCardEventData, type EntityCardStat, type FetchLike, ForbiddenError, type IntentChipEventData, NetworkError, ParseError, type ProgressEventData, RateLimitError, SIGNAL_TYPE_CODES, type SignalEntityType, type SignalInput, type SignalType, StatsWidgetClient, type StatsWidgetClientOptions, type StreamErrorEventData, type TurnCompleteEventData, UpstreamError, type UserContext, WidgetSdkError };
221
+ export { type ActionButtonEventData, type ActionsLoadingEventData, type AddToSlipHandler, type AddToSlipRejectReason, type AddToSlipResult, type AnswerEventData, AuthError, type BettingInsight, type BettingInsightEventData, type BettingInsightOdds, type BettingInsightStat, type ChatCallbacks, type ChatEvent, type ChatHandle, type ChatInput, Conversation, ENTITY_TYPE_CODES, type EntityCard, type EntityCardEventData, type EntityCardStat, type FetchLike, ForbiddenError, type IntentChipEventData, NetworkError, ParseError, type ProgressEventData, RateLimitError, SIGNAL_TYPE_CODES, type SignalEntityType, type SignalInput, type SignalType, type SlipSelection, StatsWidgetClient, type StatsWidgetClientOptions, type StreamErrorEventData, type TurnCompleteEventData, UpstreamError, type UserContext, WidgetSdkError, isAddToSlipResult };
package/dist/index.d.ts CHANGED
@@ -77,6 +77,7 @@ interface BettingInsightOdds {
77
77
  bookmakerName?: string;
78
78
  quotedAtUtc?: string;
79
79
  isLive?: boolean;
80
+ matchOddsId?: number;
80
81
  }
81
82
  interface BettingInsightStat {
82
83
  label: string;
@@ -99,11 +100,13 @@ interface BettingInsight {
99
100
  disclaimer?: string | null;
100
101
  homeTeamName?: string;
101
102
  awayTeamName?: string;
103
+ competitionName?: string;
102
104
  scopes?: {
103
105
  key: string;
104
106
  label: string;
105
107
  stats: BettingInsightStat[];
106
108
  }[];
109
+ addToSlipEnabled?: boolean;
107
110
  [key: string]: unknown;
108
111
  }
109
112
  interface BettingInsightEventData {
@@ -143,6 +146,34 @@ interface SignalInput {
143
146
  entityName: string;
144
147
  operatorUserId: string;
145
148
  }
149
+ interface SlipSelection {
150
+ matchOddsId: number;
151
+ matchId: number;
152
+ oddsDecimal: number;
153
+ quotedAtUtc?: string;
154
+ insightId?: string;
155
+ conversationId?: string;
156
+ }
157
+ type AddToSlipRejectReason = 'suspended' | 'closed' | 'login_required' | 'not_found' | 'limit' | 'unsupported';
158
+ type AddToSlipResult = {
159
+ status: 'added';
160
+ slip?: {
161
+ selectionCount: number;
162
+ totalOddsDecimal?: number;
163
+ };
164
+ } | {
165
+ status: 'duplicate';
166
+ } | {
167
+ status: 'price_changed';
168
+ newOddsDecimal: number;
169
+ accepted: boolean;
170
+ } | {
171
+ status: 'rejected';
172
+ reason: AddToSlipRejectReason;
173
+ message?: string;
174
+ };
175
+ type AddToSlipHandler = (selection: SlipSelection) => Promise<AddToSlipResult | void> | AddToSlipResult | void;
176
+ declare function isAddToSlipResult(v: unknown): v is AddToSlipResult;
146
177
 
147
178
  interface ResolvedConfig {
148
179
  operatorId: string;
@@ -187,4 +218,4 @@ declare class StatsWidgetClient {
187
218
  declare const SIGNAL_TYPE_CODES: Record<SignalType, number>;
188
219
  declare const ENTITY_TYPE_CODES: Record<SignalEntityType, number>;
189
220
 
190
- export { type ActionButtonEventData, type ActionsLoadingEventData, type AnswerEventData, AuthError, type BettingInsight, type BettingInsightEventData, type BettingInsightOdds, type BettingInsightStat, type ChatCallbacks, type ChatEvent, type ChatHandle, type ChatInput, Conversation, ENTITY_TYPE_CODES, type EntityCard, type EntityCardEventData, type EntityCardStat, type FetchLike, ForbiddenError, type IntentChipEventData, NetworkError, ParseError, type ProgressEventData, RateLimitError, SIGNAL_TYPE_CODES, type SignalEntityType, type SignalInput, type SignalType, StatsWidgetClient, type StatsWidgetClientOptions, type StreamErrorEventData, type TurnCompleteEventData, UpstreamError, type UserContext, WidgetSdkError };
221
+ export { type ActionButtonEventData, type ActionsLoadingEventData, type AddToSlipHandler, type AddToSlipRejectReason, type AddToSlipResult, type AnswerEventData, AuthError, type BettingInsight, type BettingInsightEventData, type BettingInsightOdds, type BettingInsightStat, type ChatCallbacks, type ChatEvent, type ChatHandle, type ChatInput, Conversation, ENTITY_TYPE_CODES, type EntityCard, type EntityCardEventData, type EntityCardStat, type FetchLike, ForbiddenError, type IntentChipEventData, NetworkError, ParseError, type ProgressEventData, RateLimitError, SIGNAL_TYPE_CODES, type SignalEntityType, type SignalInput, type SignalType, type SlipSelection, StatsWidgetClient, type StatsWidgetClientOptions, type StreamErrorEventData, type TurnCompleteEventData, UpstreamError, type UserContext, WidgetSdkError, isAddToSlipResult };
package/dist/index.js CHANGED
@@ -300,6 +300,24 @@ var StatsWidgetClient = class {
300
300
  return new Conversation(this.cfg, context);
301
301
  }
302
302
  };
303
+
304
+ // src/types.ts
305
+ var REJECT_REASONS = ["suspended", "closed", "login_required", "not_found", "limit", "unsupported"];
306
+ function isAddToSlipResult(v) {
307
+ if (typeof v !== "object" || v === null) return false;
308
+ const o = v;
309
+ switch (o.status) {
310
+ case "added":
311
+ case "duplicate":
312
+ return true;
313
+ case "price_changed":
314
+ return typeof o.newOddsDecimal === "number" && Number.isFinite(o.newOddsDecimal) && typeof o.accepted === "boolean";
315
+ case "rejected":
316
+ return typeof o.reason === "string" && REJECT_REASONS.includes(o.reason);
317
+ default:
318
+ return false;
319
+ }
320
+ }
303
321
  export {
304
322
  AuthError,
305
323
  Conversation,
@@ -311,6 +329,7 @@ export {
311
329
  SIGNAL_TYPE_CODES,
312
330
  StatsWidgetClient,
313
331
  UpstreamError,
314
- WidgetSdkError
332
+ WidgetSdkError,
333
+ isAddToSlipResult
315
334
  };
316
335
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/ndjson.ts","../src/chat.ts","../src/signals.ts","../src/conversation.ts","../src/client.ts"],"sourcesContent":["export class WidgetSdkError extends Error {\n readonly code: string\n readonly status?: number\n constructor(message: string, code: string, status?: number) {\n super(message)\n this.name = new.target.name\n this.code = code\n this.status = status\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\nexport class AuthError extends WidgetSdkError {\n constructor(message = 'Invalid or missing public key') { super(message, 'unauthorized', 401) }\n}\nexport class ForbiddenError extends WidgetSdkError {\n constructor(message = 'Origin not allowed or widget disabled') { super(message, 'forbidden', 403) }\n}\nexport class RateLimitError extends WidgetSdkError {\n readonly retryAfter?: number\n constructor(retryAfter?: number, message = 'Rate limited') { super(message, 'rate_limited', 429); this.retryAfter = retryAfter }\n}\nexport class UpstreamError extends WidgetSdkError {\n constructor(status: number, message = 'Upstream error') { super(message, 'upstream_error', status) }\n}\nexport class NetworkError extends WidgetSdkError {\n readonly cause?: unknown\n constructor(message = 'Network request failed', cause?: unknown) { super(message, 'network_error'); this.cause = cause }\n}\nexport class ParseError extends WidgetSdkError {\n readonly line?: string\n constructor(message = 'Malformed NDJSON line', line?: string) { super(message, 'parse_error'); this.line = line }\n}\n","import { AuthError, ForbiddenError, NetworkError, RateLimitError, UpstreamError, WidgetSdkError } from './errors'\nimport type { ChatInput, FetchLike } from './types'\n\nexport interface ResolvedConfig {\n operatorId: string\n publicKey: string\n baseUrl: string\n fetch: FetchLike\n}\n\nfunction endpoint(cfg: ResolvedConfig, path: string): string {\n return `${cfg.baseUrl.replace(/\\/+$/, '')}/v1/${encodeURIComponent(cfg.operatorId)}/${path}`\n}\n\nexport function toWidgetError(status: number, retryAfterHeader: string | null): WidgetSdkError {\n switch (status) {\n case 401: return new AuthError()\n case 403: return new ForbiddenError()\n case 429: {\n const n = retryAfterHeader != null ? Number(retryAfterHeader) : undefined\n return new RateLimitError(Number.isFinite(n) ? (n as number) : undefined)\n }\n default: return new UpstreamError(status)\n }\n}\n\nfunction isAbort(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n\nasync function send(cfg: ResolvedConfig, path: string, body: object, signal?: AbortSignal): Promise<Response> {\n try {\n return await cfg.fetch(endpoint(cfg, path), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-SS-Public-Key': cfg.publicKey },\n body: JSON.stringify(body),\n signal,\n })\n } catch (error) {\n if (isAbort(error)) throw error\n throw new NetworkError('Network request failed', error)\n }\n}\n\nexport async function postChat(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): Promise<Response> {\n const res = await send(cfg, 'chat', input, signal)\n if (!res.ok || res.body == null) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n return res\n}\n\nexport async function postSignal(cfg: ResolvedConfig, wireBody: object, signal?: AbortSignal): Promise<void> {\n const res = await send(cfg, 'signals', wireBody, signal)\n if (!res.ok) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n}\n","import { ParseError } from './errors'\n\nexport interface NdjsonParser {\n push(text: string): unknown[]\n flush(): unknown[]\n}\n\nfunction parseLine(line: string): unknown | undefined {\n const trimmed = line.trim()\n if (trimmed === '') return undefined\n try {\n return JSON.parse(trimmed)\n } catch {\n throw new ParseError('Malformed NDJSON line', line)\n }\n}\n\nexport function createNdjsonParser(): NdjsonParser {\n let buffer = ''\n return {\n push(text: string): unknown[] {\n buffer += text\n const out: unknown[] = []\n let idx: number\n while ((idx = buffer.indexOf('\\n')) >= 0) {\n const line = buffer.slice(0, idx)\n buffer = buffer.slice(idx + 1)\n const parsed = parseLine(line)\n if (parsed !== undefined) out.push(parsed)\n }\n return out\n },\n flush(): unknown[] {\n const rest = buffer\n buffer = ''\n const parsed = parseLine(rest)\n return parsed === undefined ? [] : [parsed]\n },\n }\n}\n","import { WidgetSdkError } from './errors'\nimport type {\n ActionButtonEventData, ActionsLoadingEventData, AnswerEventData, ChatEvent,\n EntityCardEventData, IntentChipEventData, ProgressEventData, StreamErrorEventData, TurnCompleteEventData,\n} from './events'\nimport { postChat, type ResolvedConfig } from './http'\nimport { createNdjsonParser } from './ndjson'\nimport type { ChatInput } from './types'\n\nexport interface ChatCallbacks {\n onProgress?(data: ProgressEventData): void\n onAnswer?(data: AnswerEventData): void\n onEntityCard?(data: EntityCardEventData): void\n onActionButton?(data: ActionButtonEventData): void\n onIntentChip?(data: IntentChipEventData): void\n onActionsLoading?(data: ActionsLoadingEventData): void\n onError?(error: StreamErrorEventData | WidgetSdkError): void\n onComplete?(data: TurnCompleteEventData): void\n}\n\nexport interface ChatHandle extends AsyncIterable<ChatEvent>, PromiseLike<void> {\n cancel(): void\n}\n\nfunction dispatch(ev: ChatEvent, cb: ChatCallbacks): void {\n switch (ev.type) {\n case 'progress': cb.onProgress?.(ev.data); break\n case 'answer': cb.onAnswer?.(ev.data); break\n case 'entity_card': cb.onEntityCard?.(ev.data); break\n case 'action_button': cb.onActionButton?.(ev.data); break\n case 'intent_chip': cb.onIntentChip?.(ev.data); break\n case 'actions_loading': cb.onActionsLoading?.(ev.data); break\n case 'turn_complete': cb.onComplete?.(ev.data); break\n case 'error': cb.onError?.(ev.data); break\n }\n}\n\nasync function* streamEvents(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): AsyncGenerator<ChatEvent> {\n const res = await postChat(cfg, input, signal)\n const reader = res.body!.getReader()\n const decoder = new TextDecoder()\n const parser = createNdjsonParser()\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n for (const obj of parser.push(decoder.decode(value, { stream: true }))) yield obj as ChatEvent\n }\n for (const obj of parser.flush()) yield obj as ChatEvent\n } finally {\n await reader.cancel().catch(() => {})\n }\n}\n\nexport function runChat(\n cfg: ResolvedConfig,\n input: ChatInput,\n callbacks?: ChatCallbacks,\n opts?: { signal?: AbortSignal; tap?: (ev: ChatEvent) => void },\n): ChatHandle {\n const controller = new AbortController()\n const external = opts?.signal\n if (external) {\n if (external.aborted) controller.abort()\n else external.addEventListener('abort', () => controller.abort(), { once: true })\n }\n\n async function* source(): AsyncGenerator<ChatEvent> {\n for await (const ev of streamEvents(cfg, input, controller.signal)) {\n opts?.tap?.(ev)\n yield ev\n }\n }\n\n const iterator = source()\n let consumed = false\n\n async function drive(): Promise<void> {\n try {\n for await (const ev of iterator) { if (callbacks) dispatch(ev, callbacks) }\n } catch (error) {\n if (callbacks?.onError && error instanceof WidgetSdkError) { callbacks.onError(error); return }\n throw error\n }\n }\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<ChatEvent> {\n if (consumed) throw new Error('chat stream already consumed')\n consumed = true\n return iterator\n },\n then<TResult1 = void, TResult2 = never>(\n onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n if (consumed) return Promise.resolve().then(onfulfilled, onrejected)\n consumed = true\n return drive().then(onfulfilled, onrejected)\n },\n cancel(): void { controller.abort() },\n }\n}\n","import type { SignalEntityType, SignalInput, SignalType } from './types'\n\nexport const SIGNAL_TYPE_CODES: Record<SignalType, number> = {\n MatchPageView: 1, PlayerPageView: 2, TeamPageView: 3, MarketView: 4,\n SearchQuery: 5, SessionDepth: 6, TimeOnPage: 7, InsightViewed: 8,\n InsightMarketClicked: 9, BetPlacedFromInsight: 10, InsightScrollDepth: 11,\n ToolCall: 12, EntityMention: 13, Handoff: 14, FollowUpQuery: 15, RecommendationDismissed: 16,\n}\n\nexport const ENTITY_TYPE_CODES: Record<SignalEntityType, number> = {\n Match: 1, Team: 2, Player: 3, Competition: 4, Market: 5,\n Article: 6, Session: 7, Query: 8, Conversation: 9,\n}\n\nexport function toSignalWireBody(input: SignalInput): {\n signalType: number; entityType: number; entityName: string; operatorUserId: string\n} {\n const signalType = SIGNAL_TYPE_CODES[input.signalType]\n const entityType = ENTITY_TYPE_CODES[input.entityType]\n if (signalType === undefined) throw new Error(`Unknown signalType: ${String(input.signalType)}`)\n if (entityType === undefined) throw new Error(`Unknown entityType: ${String(input.entityType)}`)\n return { signalType, entityType, entityName: input.entityName, operatorUserId: input.operatorUserId }\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport { postSignal, type ResolvedConfig } from './http'\nimport { toSignalWireBody } from './signals'\nimport type { ChatInput, SignalInput, UserContext } from './types'\n\nexport class Conversation {\n conversationId?: string\n\n constructor(private readonly cfg: ResolvedConfig, private readonly context?: UserContext) {}\n\n send(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n const mergedContext: UserContext = { ...this.context, ...input.userContext }\n const full: ChatInput = {\n ...input,\n conversationId: input.conversationId ?? this.conversationId,\n userContext: Object.keys(mergedContext).length > 0 ? mergedContext : undefined,\n }\n return runChat(this.cfg, full, callbacks, {\n tap: (ev) => { if (ev.type === 'turn_complete') this.conversationId = ev.data.conversationId },\n })\n }\n\n sendSignal(input: Omit<SignalInput, 'operatorUserId'> & { operatorUserId?: string }): Promise<void> {\n const operatorUserId = input.operatorUserId ?? this.context?.operatorUserId\n if (!operatorUserId) throw new Error('operatorUserId is required (set it on conversation() or pass it to sendSignal)')\n return postSignal(this.cfg, toSignalWireBody({ ...input, operatorUserId }))\n }\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport { Conversation } from './conversation'\nimport { postSignal, type ResolvedConfig } from './http'\nimport { toSignalWireBody } from './signals'\nimport type { ChatInput, SignalInput, StatsWidgetClientOptions, UserContext } from './types'\n\nconst DEFAULT_BASE_URL = 'https://widget.sensiblestats.com'\n\nexport class StatsWidgetClient {\n private readonly cfg: ResolvedConfig\n\n constructor(options: StatsWidgetClientOptions) {\n if (!options.operatorId) throw new Error('operatorId is required')\n if (!options.publicKey) throw new Error('publicKey is required')\n const fetchImpl = options.fetch ?? (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined)\n if (!fetchImpl) throw new Error('No fetch implementation available; pass options.fetch')\n this.cfg = {\n operatorId: options.operatorId,\n publicKey: options.publicKey,\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n fetch: fetchImpl,\n }\n }\n\n chat(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n return runChat(this.cfg, input, callbacks)\n }\n\n async sendSignal(input: SignalInput): Promise<void> {\n await postSignal(this.cfg, toSignalWireBody(input))\n }\n\n conversation(context?: UserContext): Conversation {\n return new Conversation(this.cfg, context)\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/ndjson.ts","../src/chat.ts","../src/signals.ts","../src/conversation.ts","../src/client.ts","../src/types.ts"],"sourcesContent":["export class WidgetSdkError extends Error {\n readonly code: string\n readonly status?: number\n constructor(message: string, code: string, status?: number) {\n super(message)\n this.name = new.target.name\n this.code = code\n this.status = status\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\nexport class AuthError extends WidgetSdkError {\n constructor(message = 'Invalid or missing public key') { super(message, 'unauthorized', 401) }\n}\nexport class ForbiddenError extends WidgetSdkError {\n constructor(message = 'Origin not allowed or widget disabled') { super(message, 'forbidden', 403) }\n}\nexport class RateLimitError extends WidgetSdkError {\n readonly retryAfter?: number\n constructor(retryAfter?: number, message = 'Rate limited') { super(message, 'rate_limited', 429); this.retryAfter = retryAfter }\n}\nexport class UpstreamError extends WidgetSdkError {\n constructor(status: number, message = 'Upstream error') { super(message, 'upstream_error', status) }\n}\nexport class NetworkError extends WidgetSdkError {\n readonly cause?: unknown\n constructor(message = 'Network request failed', cause?: unknown) { super(message, 'network_error'); this.cause = cause }\n}\nexport class ParseError extends WidgetSdkError {\n readonly line?: string\n constructor(message = 'Malformed NDJSON line', line?: string) { super(message, 'parse_error'); this.line = line }\n}\n","import { AuthError, ForbiddenError, NetworkError, RateLimitError, UpstreamError, WidgetSdkError } from './errors'\nimport type { ChatInput, FetchLike } from './types'\n\nexport interface ResolvedConfig {\n operatorId: string\n publicKey: string\n baseUrl: string\n fetch: FetchLike\n}\n\nfunction endpoint(cfg: ResolvedConfig, path: string): string {\n return `${cfg.baseUrl.replace(/\\/+$/, '')}/v1/${encodeURIComponent(cfg.operatorId)}/${path}`\n}\n\nexport function toWidgetError(status: number, retryAfterHeader: string | null): WidgetSdkError {\n switch (status) {\n case 401: return new AuthError()\n case 403: return new ForbiddenError()\n case 429: {\n const n = retryAfterHeader != null ? Number(retryAfterHeader) : undefined\n return new RateLimitError(Number.isFinite(n) ? (n as number) : undefined)\n }\n default: return new UpstreamError(status)\n }\n}\n\nfunction isAbort(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n\nasync function send(cfg: ResolvedConfig, path: string, body: object, signal?: AbortSignal): Promise<Response> {\n try {\n return await cfg.fetch(endpoint(cfg, path), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-SS-Public-Key': cfg.publicKey },\n body: JSON.stringify(body),\n signal,\n })\n } catch (error) {\n if (isAbort(error)) throw error\n throw new NetworkError('Network request failed', error)\n }\n}\n\nexport async function postChat(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): Promise<Response> {\n const res = await send(cfg, 'chat', input, signal)\n if (!res.ok || res.body == null) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n return res\n}\n\nexport async function postSignal(cfg: ResolvedConfig, wireBody: object, signal?: AbortSignal): Promise<void> {\n const res = await send(cfg, 'signals', wireBody, signal)\n if (!res.ok) throw toWidgetError(res.status, res.headers.get('Retry-After'))\n}\n","import { ParseError } from './errors'\n\nexport interface NdjsonParser {\n push(text: string): unknown[]\n flush(): unknown[]\n}\n\nfunction parseLine(line: string): unknown | undefined {\n const trimmed = line.trim()\n if (trimmed === '') return undefined\n try {\n return JSON.parse(trimmed)\n } catch {\n throw new ParseError('Malformed NDJSON line', line)\n }\n}\n\nexport function createNdjsonParser(): NdjsonParser {\n let buffer = ''\n return {\n push(text: string): unknown[] {\n buffer += text\n const out: unknown[] = []\n let idx: number\n while ((idx = buffer.indexOf('\\n')) >= 0) {\n const line = buffer.slice(0, idx)\n buffer = buffer.slice(idx + 1)\n const parsed = parseLine(line)\n if (parsed !== undefined) out.push(parsed)\n }\n return out\n },\n flush(): unknown[] {\n const rest = buffer\n buffer = ''\n const parsed = parseLine(rest)\n return parsed === undefined ? [] : [parsed]\n },\n }\n}\n","import { WidgetSdkError } from './errors'\nimport type {\n ActionButtonEventData, ActionsLoadingEventData, AnswerEventData, ChatEvent,\n EntityCardEventData, IntentChipEventData, ProgressEventData, StreamErrorEventData, TurnCompleteEventData,\n} from './events'\nimport { postChat, type ResolvedConfig } from './http'\nimport { createNdjsonParser } from './ndjson'\nimport type { ChatInput } from './types'\n\nexport interface ChatCallbacks {\n onProgress?(data: ProgressEventData): void\n onAnswer?(data: AnswerEventData): void\n onEntityCard?(data: EntityCardEventData): void\n onActionButton?(data: ActionButtonEventData): void\n onIntentChip?(data: IntentChipEventData): void\n onActionsLoading?(data: ActionsLoadingEventData): void\n onError?(error: StreamErrorEventData | WidgetSdkError): void\n onComplete?(data: TurnCompleteEventData): void\n}\n\nexport interface ChatHandle extends AsyncIterable<ChatEvent>, PromiseLike<void> {\n cancel(): void\n}\n\nfunction dispatch(ev: ChatEvent, cb: ChatCallbacks): void {\n switch (ev.type) {\n case 'progress': cb.onProgress?.(ev.data); break\n case 'answer': cb.onAnswer?.(ev.data); break\n case 'entity_card': cb.onEntityCard?.(ev.data); break\n case 'action_button': cb.onActionButton?.(ev.data); break\n case 'intent_chip': cb.onIntentChip?.(ev.data); break\n case 'actions_loading': cb.onActionsLoading?.(ev.data); break\n case 'turn_complete': cb.onComplete?.(ev.data); break\n case 'error': cb.onError?.(ev.data); break\n }\n}\n\nasync function* streamEvents(cfg: ResolvedConfig, input: ChatInput, signal: AbortSignal): AsyncGenerator<ChatEvent> {\n const res = await postChat(cfg, input, signal)\n const reader = res.body!.getReader()\n const decoder = new TextDecoder()\n const parser = createNdjsonParser()\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n for (const obj of parser.push(decoder.decode(value, { stream: true }))) yield obj as ChatEvent\n }\n for (const obj of parser.flush()) yield obj as ChatEvent\n } finally {\n await reader.cancel().catch(() => {})\n }\n}\n\nexport function runChat(\n cfg: ResolvedConfig,\n input: ChatInput,\n callbacks?: ChatCallbacks,\n opts?: { signal?: AbortSignal; tap?: (ev: ChatEvent) => void },\n): ChatHandle {\n const controller = new AbortController()\n const external = opts?.signal\n if (external) {\n if (external.aborted) controller.abort()\n else external.addEventListener('abort', () => controller.abort(), { once: true })\n }\n\n async function* source(): AsyncGenerator<ChatEvent> {\n for await (const ev of streamEvents(cfg, input, controller.signal)) {\n opts?.tap?.(ev)\n yield ev\n }\n }\n\n const iterator = source()\n let consumed = false\n\n async function drive(): Promise<void> {\n try {\n for await (const ev of iterator) { if (callbacks) dispatch(ev, callbacks) }\n } catch (error) {\n if (callbacks?.onError && error instanceof WidgetSdkError) { callbacks.onError(error); return }\n throw error\n }\n }\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<ChatEvent> {\n if (consumed) throw new Error('chat stream already consumed')\n consumed = true\n return iterator\n },\n then<TResult1 = void, TResult2 = never>(\n onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,\n ): PromiseLike<TResult1 | TResult2> {\n if (consumed) return Promise.resolve().then(onfulfilled, onrejected)\n consumed = true\n return drive().then(onfulfilled, onrejected)\n },\n cancel(): void { controller.abort() },\n }\n}\n","import type { SignalEntityType, SignalInput, SignalType } from './types'\n\nexport const SIGNAL_TYPE_CODES: Record<SignalType, number> = {\n MatchPageView: 1, PlayerPageView: 2, TeamPageView: 3, MarketView: 4,\n SearchQuery: 5, SessionDepth: 6, TimeOnPage: 7, InsightViewed: 8,\n InsightMarketClicked: 9, BetPlacedFromInsight: 10, InsightScrollDepth: 11,\n ToolCall: 12, EntityMention: 13, Handoff: 14, FollowUpQuery: 15, RecommendationDismissed: 16,\n}\n\nexport const ENTITY_TYPE_CODES: Record<SignalEntityType, number> = {\n Match: 1, Team: 2, Player: 3, Competition: 4, Market: 5,\n Article: 6, Session: 7, Query: 8, Conversation: 9,\n}\n\nexport function toSignalWireBody(input: SignalInput): {\n signalType: number; entityType: number; entityName: string; operatorUserId: string\n} {\n const signalType = SIGNAL_TYPE_CODES[input.signalType]\n const entityType = ENTITY_TYPE_CODES[input.entityType]\n if (signalType === undefined) throw new Error(`Unknown signalType: ${String(input.signalType)}`)\n if (entityType === undefined) throw new Error(`Unknown entityType: ${String(input.entityType)}`)\n return { signalType, entityType, entityName: input.entityName, operatorUserId: input.operatorUserId }\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport { postSignal, type ResolvedConfig } from './http'\nimport { toSignalWireBody } from './signals'\nimport type { ChatInput, SignalInput, UserContext } from './types'\n\nexport class Conversation {\n conversationId?: string\n\n constructor(private readonly cfg: ResolvedConfig, private readonly context?: UserContext) {}\n\n send(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n const mergedContext: UserContext = { ...this.context, ...input.userContext }\n const full: ChatInput = {\n ...input,\n conversationId: input.conversationId ?? this.conversationId,\n userContext: Object.keys(mergedContext).length > 0 ? mergedContext : undefined,\n }\n return runChat(this.cfg, full, callbacks, {\n tap: (ev) => { if (ev.type === 'turn_complete') this.conversationId = ev.data.conversationId },\n })\n }\n\n sendSignal(input: Omit<SignalInput, 'operatorUserId'> & { operatorUserId?: string }): Promise<void> {\n const operatorUserId = input.operatorUserId ?? this.context?.operatorUserId\n if (!operatorUserId) throw new Error('operatorUserId is required (set it on conversation() or pass it to sendSignal)')\n return postSignal(this.cfg, toSignalWireBody({ ...input, operatorUserId }))\n }\n}\n","import { runChat, type ChatCallbacks, type ChatHandle } from './chat'\nimport { Conversation } from './conversation'\nimport { postSignal, type ResolvedConfig } from './http'\nimport { toSignalWireBody } from './signals'\nimport type { ChatInput, SignalInput, StatsWidgetClientOptions, UserContext } from './types'\n\nconst DEFAULT_BASE_URL = 'https://widget.sensiblestats.com'\n\nexport class StatsWidgetClient {\n private readonly cfg: ResolvedConfig\n\n constructor(options: StatsWidgetClientOptions) {\n if (!options.operatorId) throw new Error('operatorId is required')\n if (!options.publicKey) throw new Error('publicKey is required')\n const fetchImpl = options.fetch ?? (globalThis.fetch ? globalThis.fetch.bind(globalThis) : undefined)\n if (!fetchImpl) throw new Error('No fetch implementation available; pass options.fetch')\n this.cfg = {\n operatorId: options.operatorId,\n publicKey: options.publicKey,\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n fetch: fetchImpl,\n }\n }\n\n chat(input: ChatInput, callbacks?: ChatCallbacks): ChatHandle {\n return runChat(this.cfg, input, callbacks)\n }\n\n async sendSignal(input: SignalInput): Promise<void> {\n await postSignal(this.cfg, toSignalWireBody(input))\n }\n\n conversation(context?: UserContext): Conversation {\n return new Conversation(this.cfg, context)\n }\n}\n","export type FetchLike = (input: string, init: RequestInit) => Promise<Response>\n\nexport interface StatsWidgetClientOptions {\n operatorId: string\n publicKey: string\n baseUrl?: string\n /** Advanced/testing: inject a fetch implementation. Defaults to globalThis.fetch. */\n fetch?: FetchLike\n}\n\nexport interface UserContext {\n operatorUserId?: string\n defaultLanguage?: string\n}\n\nexport interface ChatInput {\n message: string\n conversationId?: string\n actionId?: string\n userContext?: UserContext\n}\n\nexport type SignalType =\n | 'MatchPageView' | 'PlayerPageView' | 'TeamPageView' | 'MarketView'\n | 'SearchQuery' | 'SessionDepth' | 'TimeOnPage' | 'InsightViewed'\n | 'InsightMarketClicked' | 'BetPlacedFromInsight' | 'InsightScrollDepth'\n | 'ToolCall' | 'EntityMention' | 'Handoff' | 'FollowUpQuery' | 'RecommendationDismissed'\n\nexport type SignalEntityType =\n | 'Match' | 'Team' | 'Player' | 'Competition' | 'Market'\n | 'Article' | 'Session' | 'Query' | 'Conversation'\n\nexport interface SignalInput {\n signalType: SignalType\n entityType: SignalEntityType\n entityName: string\n operatorUserId: string\n}\n\nexport interface SlipSelection {\n matchOddsId: number\n matchId: number\n oddsDecimal: number\n quotedAtUtc?: string\n insightId?: string\n conversationId?: string\n}\n\nexport type AddToSlipRejectReason =\n | 'suspended' | 'closed' | 'login_required'\n | 'not_found' | 'limit' | 'unsupported'\n\nexport type AddToSlipResult =\n | { status: 'added'; slip?: { selectionCount: number; totalOddsDecimal?: number } }\n | { status: 'duplicate' }\n | { status: 'price_changed'; newOddsDecimal: number; accepted: boolean }\n | { status: 'rejected'; reason: AddToSlipRejectReason; message?: string }\n\nexport type AddToSlipHandler = (\n selection: SlipSelection,\n) => Promise<AddToSlipResult | void> | AddToSlipResult | void\n\nconst REJECT_REASONS = ['suspended', 'closed', 'login_required', 'not_found', 'limit', 'unsupported']\n\nexport function isAddToSlipResult(v: unknown): v is AddToSlipResult {\n if (typeof v !== 'object' || v === null) return false\n const o = v as Record<string, unknown>\n switch (o.status) {\n case 'added':\n case 'duplicate':\n return true\n case 'price_changed':\n return typeof o.newOddsDecimal === 'number'\n && Number.isFinite(o.newOddsDecimal)\n && typeof o.accepted === 'boolean'\n case 'rejected':\n return typeof o.reason === 'string'\n && REJECT_REASONS.includes(o.reason)\n default:\n return false\n }\n}\n"],"mappings":";AAAO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EAGxC,YAAY,SAAiB,MAAc,QAAiB;AAC1D,UAAM,OAAO;AACb,SAAK,OAAO,WAAW;AACvB,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,WAAO,eAAe,MAAM,WAAW,SAAS;AAAA,EAClD;AACF;AACO,IAAM,YAAN,cAAwB,eAAe;AAAA,EAC5C,YAAY,UAAU,iCAAiC;AAAE,UAAM,SAAS,gBAAgB,GAAG;AAAA,EAAE;AAC/F;AACO,IAAM,iBAAN,cAA6B,eAAe;AAAA,EACjD,YAAY,UAAU,yCAAyC;AAAE,UAAM,SAAS,aAAa,GAAG;AAAA,EAAE;AACpG;AACO,IAAM,iBAAN,cAA6B,eAAe;AAAA,EAEjD,YAAY,YAAqB,UAAU,gBAAgB;AAAE,UAAM,SAAS,gBAAgB,GAAG;AAAG,SAAK,aAAa;AAAA,EAAW;AACjI;AACO,IAAM,gBAAN,cAA4B,eAAe;AAAA,EAChD,YAAY,QAAgB,UAAU,kBAAkB;AAAE,UAAM,SAAS,kBAAkB,MAAM;AAAA,EAAE;AACrG;AACO,IAAM,eAAN,cAA2B,eAAe;AAAA,EAE/C,YAAY,UAAU,0BAA0B,OAAiB;AAAE,UAAM,SAAS,eAAe;AAAG,SAAK,QAAQ;AAAA,EAAM;AACzH;AACO,IAAM,aAAN,cAAyB,eAAe;AAAA,EAE7C,YAAY,UAAU,yBAAyB,MAAe;AAAE,UAAM,SAAS,aAAa;AAAG,SAAK,OAAO;AAAA,EAAK;AAClH;;;ACrBA,SAAS,SAAS,KAAqB,MAAsB;AAC3D,SAAO,GAAG,IAAI,QAAQ,QAAQ,QAAQ,EAAE,CAAC,OAAO,mBAAmB,IAAI,UAAU,CAAC,IAAI,IAAI;AAC5F;AAEO,SAAS,cAAc,QAAgB,kBAAiD;AAC7F,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAK,aAAO,IAAI,UAAU;AAAA,IAC/B,KAAK;AAAK,aAAO,IAAI,eAAe;AAAA,IACpC,KAAK,KAAK;AACR,YAAM,IAAI,oBAAoB,OAAO,OAAO,gBAAgB,IAAI;AAChE,aAAO,IAAI,eAAe,OAAO,SAAS,CAAC,IAAK,IAAe,MAAS;AAAA,IAC1E;AAAA,IACA;AAAS,aAAO,IAAI,cAAc,MAAM;AAAA,EAC1C;AACF;AAEA,SAAS,QAAQ,OAAyB;AACxC,SAAO,iBAAiB,SAAS,MAAM,SAAS;AAClD;AAEA,eAAe,KAAK,KAAqB,MAAc,MAAc,QAAyC;AAC5G,MAAI;AACF,WAAO,MAAM,IAAI,MAAM,SAAS,KAAK,IAAI,GAAG;AAAA,MAC1C,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,oBAAoB,mBAAmB,IAAI,UAAU;AAAA,MAChF,MAAM,KAAK,UAAU,IAAI;AAAA,MACzB;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,QAAI,QAAQ,KAAK,EAAG,OAAM;AAC1B,UAAM,IAAI,aAAa,0BAA0B,KAAK;AAAA,EACxD;AACF;AAEA,eAAsB,SAAS,KAAqB,OAAkB,QAAwC;AAC5G,QAAM,MAAM,MAAM,KAAK,KAAK,QAAQ,OAAO,MAAM;AACjD,MAAI,CAAC,IAAI,MAAM,IAAI,QAAQ,KAAM,OAAM,cAAc,IAAI,QAAQ,IAAI,QAAQ,IAAI,aAAa,CAAC;AAC/F,SAAO;AACT;AAEA,eAAsB,WAAW,KAAqB,UAAkB,QAAqC;AAC3G,QAAM,MAAM,MAAM,KAAK,KAAK,WAAW,UAAU,MAAM;AACvD,MAAI,CAAC,IAAI,GAAI,OAAM,cAAc,IAAI,QAAQ,IAAI,QAAQ,IAAI,aAAa,CAAC;AAC7E;;;AC9CA,SAAS,UAAU,MAAmC;AACpD,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,YAAY,GAAI,QAAO;AAC3B,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,UAAM,IAAI,WAAW,yBAAyB,IAAI;AAAA,EACpD;AACF;AAEO,SAAS,qBAAmC;AACjD,MAAI,SAAS;AACb,SAAO;AAAA,IACL,KAAK,MAAyB;AAC5B,gBAAU;AACV,YAAM,MAAiB,CAAC;AACxB,UAAI;AACJ,cAAQ,MAAM,OAAO,QAAQ,IAAI,MAAM,GAAG;AACxC,cAAM,OAAO,OAAO,MAAM,GAAG,GAAG;AAChC,iBAAS,OAAO,MAAM,MAAM,CAAC;AAC7B,cAAM,SAAS,UAAU,IAAI;AAC7B,YAAI,WAAW,OAAW,KAAI,KAAK,MAAM;AAAA,MAC3C;AACA,aAAO;AAAA,IACT;AAAA,IACA,QAAmB;AACjB,YAAM,OAAO;AACb,eAAS;AACT,YAAM,SAAS,UAAU,IAAI;AAC7B,aAAO,WAAW,SAAY,CAAC,IAAI,CAAC,MAAM;AAAA,IAC5C;AAAA,EACF;AACF;;;ACfA,SAAS,SAAS,IAAe,IAAyB;AACxD,UAAQ,GAAG,MAAM;AAAA,IACf,KAAK;AAAY,SAAG,aAAa,GAAG,IAAI;AAAG;AAAA,IAC3C,KAAK;AAAU,SAAG,WAAW,GAAG,IAAI;AAAG;AAAA,IACvC,KAAK;AAAe,SAAG,eAAe,GAAG,IAAI;AAAG;AAAA,IAChD,KAAK;AAAiB,SAAG,iBAAiB,GAAG,IAAI;AAAG;AAAA,IACpD,KAAK;AAAe,SAAG,eAAe,GAAG,IAAI;AAAG;AAAA,IAChD,KAAK;AAAmB,SAAG,mBAAmB,GAAG,IAAI;AAAG;AAAA,IACxD,KAAK;AAAiB,SAAG,aAAa,GAAG,IAAI;AAAG;AAAA,IAChD,KAAK;AAAS,SAAG,UAAU,GAAG,IAAI;AAAG;AAAA,EACvC;AACF;AAEA,gBAAgB,aAAa,KAAqB,OAAkB,QAAgD;AAClH,QAAM,MAAM,MAAM,SAAS,KAAK,OAAO,MAAM;AAC7C,QAAM,SAAS,IAAI,KAAM,UAAU;AACnC,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,SAAS,mBAAmB;AAClC,MAAI;AACF,eAAS;AACP,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,iBAAW,OAAO,OAAO,KAAK,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,CAAC,EAAG,OAAM;AAAA,IAChF;AACA,eAAW,OAAO,OAAO,MAAM,EAAG,OAAM;AAAA,EAC1C,UAAE;AACA,UAAM,OAAO,OAAO,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACtC;AACF;AAEO,SAAS,QACd,KACA,OACA,WACA,MACY;AACZ,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,WAAW,MAAM;AACvB,MAAI,UAAU;AACZ,QAAI,SAAS,QAAS,YAAW,MAAM;AAAA,QAClC,UAAS,iBAAiB,SAAS,MAAM,WAAW,MAAM,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,EAClF;AAEA,kBAAgB,SAAoC;AAClD,qBAAiB,MAAM,aAAa,KAAK,OAAO,WAAW,MAAM,GAAG;AAClE,YAAM,MAAM,EAAE;AACd,YAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,WAAW,OAAO;AACxB,MAAI,WAAW;AAEf,iBAAe,QAAuB;AACpC,QAAI;AACF,uBAAiB,MAAM,UAAU;AAAE,YAAI,UAAW,UAAS,IAAI,SAAS;AAAA,MAAE;AAAA,IAC5E,SAAS,OAAO;AACd,UAAI,WAAW,WAAW,iBAAiB,gBAAgB;AAAE,kBAAU,QAAQ,KAAK;AAAG;AAAA,MAAO;AAC9F,YAAM;AAAA,IACR;AAAA,EACF;AAEA,SAAO;AAAA,IACL,CAAC,OAAO,aAAa,IAA8B;AACjD,UAAI,SAAU,OAAM,IAAI,MAAM,8BAA8B;AAC5D,iBAAW;AACX,aAAO;AAAA,IACT;AAAA,IACA,KACE,aACA,YACkC;AAClC,UAAI,SAAU,QAAO,QAAQ,QAAQ,EAAE,KAAK,aAAa,UAAU;AACnE,iBAAW;AACX,aAAO,MAAM,EAAE,KAAK,aAAa,UAAU;AAAA,IAC7C;AAAA,IACA,SAAe;AAAE,iBAAW,MAAM;AAAA,IAAE;AAAA,EACtC;AACF;;;ACpGO,IAAM,oBAAgD;AAAA,EAC3D,eAAe;AAAA,EAAG,gBAAgB;AAAA,EAAG,cAAc;AAAA,EAAG,YAAY;AAAA,EAClE,aAAa;AAAA,EAAG,cAAc;AAAA,EAAG,YAAY;AAAA,EAAG,eAAe;AAAA,EAC/D,sBAAsB;AAAA,EAAG,sBAAsB;AAAA,EAAI,oBAAoB;AAAA,EACvE,UAAU;AAAA,EAAI,eAAe;AAAA,EAAI,SAAS;AAAA,EAAI,eAAe;AAAA,EAAI,yBAAyB;AAC5F;AAEO,IAAM,oBAAsD;AAAA,EACjE,OAAO;AAAA,EAAG,MAAM;AAAA,EAAG,QAAQ;AAAA,EAAG,aAAa;AAAA,EAAG,QAAQ;AAAA,EACtD,SAAS;AAAA,EAAG,SAAS;AAAA,EAAG,OAAO;AAAA,EAAG,cAAc;AAClD;AAEO,SAAS,iBAAiB,OAE/B;AACA,QAAM,aAAa,kBAAkB,MAAM,UAAU;AACrD,QAAM,aAAa,kBAAkB,MAAM,UAAU;AACrD,MAAI,eAAe,OAAW,OAAM,IAAI,MAAM,uBAAuB,OAAO,MAAM,UAAU,CAAC,EAAE;AAC/F,MAAI,eAAe,OAAW,OAAM,IAAI,MAAM,uBAAuB,OAAO,MAAM,UAAU,CAAC,EAAE;AAC/F,SAAO,EAAE,YAAY,YAAY,YAAY,MAAM,YAAY,gBAAgB,MAAM,eAAe;AACtG;;;ACjBO,IAAM,eAAN,MAAmB;AAAA,EAGxB,YAA6B,KAAsC,SAAuB;AAA7D;AAAsC;AAAA,EAAwB;AAAA,EAE3F,KAAK,OAAkB,WAAuC;AAC5D,UAAM,gBAA6B,EAAE,GAAG,KAAK,SAAS,GAAG,MAAM,YAAY;AAC3E,UAAM,OAAkB;AAAA,MACtB,GAAG;AAAA,MACH,gBAAgB,MAAM,kBAAkB,KAAK;AAAA,MAC7C,aAAa,OAAO,KAAK,aAAa,EAAE,SAAS,IAAI,gBAAgB;AAAA,IACvE;AACA,WAAO,QAAQ,KAAK,KAAK,MAAM,WAAW;AAAA,MACxC,KAAK,CAAC,OAAO;AAAE,YAAI,GAAG,SAAS,gBAAiB,MAAK,iBAAiB,GAAG,KAAK;AAAA,MAAe;AAAA,IAC/F,CAAC;AAAA,EACH;AAAA,EAEA,WAAW,OAAyF;AAClG,UAAM,iBAAiB,MAAM,kBAAkB,KAAK,SAAS;AAC7D,QAAI,CAAC,eAAgB,OAAM,IAAI,MAAM,gFAAgF;AACrH,WAAO,WAAW,KAAK,KAAK,iBAAiB,EAAE,GAAG,OAAO,eAAe,CAAC,CAAC;AAAA,EAC5E;AACF;;;ACrBA,IAAM,mBAAmB;AAElB,IAAM,oBAAN,MAAwB;AAAA,EAG7B,YAAY,SAAmC;AAC7C,QAAI,CAAC,QAAQ,WAAY,OAAM,IAAI,MAAM,wBAAwB;AACjE,QAAI,CAAC,QAAQ,UAAW,OAAM,IAAI,MAAM,uBAAuB;AAC/D,UAAM,YAAY,QAAQ,UAAU,WAAW,QAAQ,WAAW,MAAM,KAAK,UAAU,IAAI;AAC3F,QAAI,CAAC,UAAW,OAAM,IAAI,MAAM,uDAAuD;AACvF,SAAK,MAAM;AAAA,MACT,YAAY,QAAQ;AAAA,MACpB,WAAW,QAAQ;AAAA,MACnB,SAAS,QAAQ,WAAW;AAAA,MAC5B,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,KAAK,OAAkB,WAAuC;AAC5D,WAAO,QAAQ,KAAK,KAAK,OAAO,SAAS;AAAA,EAC3C;AAAA,EAEA,MAAM,WAAW,OAAmC;AAClD,UAAM,WAAW,KAAK,KAAK,iBAAiB,KAAK,CAAC;AAAA,EACpD;AAAA,EAEA,aAAa,SAAqC;AAChD,WAAO,IAAI,aAAa,KAAK,KAAK,OAAO;AAAA,EAC3C;AACF;;;AC2BA,IAAM,iBAAiB,CAAC,aAAa,UAAU,kBAAkB,aAAa,SAAS,aAAa;AAE7F,SAAS,kBAAkB,GAAkC;AAClE,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,IAAI;AACV,UAAQ,EAAE,QAAQ;AAAA,IAChB,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,OAAO,EAAE,mBAAmB,YAC9B,OAAO,SAAS,EAAE,cAAc,KAChC,OAAO,EAAE,aAAa;AAAA,IAC7B,KAAK;AACH,aAAO,OAAO,EAAE,WAAW,YACtB,eAAe,SAAS,EAAE,MAAM;AAAA,IACvC;AACE,aAAO;AAAA,EACX;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sensiblestats/widget-sdk",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Headless browser SDK for the SensibleStats chat widget gateway.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",