@convosite/client 0.1.0 → 0.2.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/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # @convosite/client
2
2
 
3
- Framework-agnostic runtime client for Convosite. It has no runtime dependencies and uses the platform `fetch` API, so the same client works in browsers, Node 18+, React, Next.js, Vue, Nuxt, Svelte, SvelteKit, Astro, Bun and other modern JavaScript runtimes.
3
+ Framework-agnostic JavaScript and TypeScript client for building Convosite conversational experiences. It has no runtime dependencies and uses the platform `fetch` API, so it works in browsers, Node 18+, React, Next.js, Vue, Nuxt, Svelte, SvelteKit, Astro, Bun and other modern JavaScript runtimes.
4
+
5
+ Convosite's client-side runtime is intentionally small: developers define **blocks** and **endpoints** through the CLI, content is managed as **knowledge** inside Convosite, and applications consume conversations and invoke public endpoint actions. Knowledge is retrieved internally by the conversation runtime and is not exposed as a headless CMS API.
4
6
 
5
7
  ## Install
6
8
 
@@ -17,86 +19,23 @@ const convosite = createConvosite({
17
19
  site: 'YOUR_SITE_ULID',
18
20
  });
19
21
 
20
- const { page } = await convosite.pages.get('/about');
21
- ```
22
-
23
- Production defaults to `https://app.convosite.io/api`. No API token belongs in frontend code: the runtime API is public and Convosite actions resolve protected site variables on the server.
24
-
25
- ## Site
26
-
27
- ```ts
28
- const site = await convosite.site.get();
29
- console.log(site.global);
30
- ```
31
-
32
- ## Pages
33
-
34
- Get by path:
35
-
36
- ```ts
37
- const { site, page } = await convosite.pages.get('/news/my-article');
38
- ```
39
-
40
- Get by page ID:
41
-
42
- ```ts
43
- const { page } = await convosite.pages.find('PAGE_ULID');
44
- ```
45
-
46
- List full, resolved pages with pagination:
47
-
48
- ```ts
49
- const result = await convosite.pages.list({
50
- parentId: 'NEWS_PAGE_ULID',
51
- sort: 'created_at',
52
- direction: 'desc',
53
- page: 1,
54
- perPage: 12,
55
- });
22
+ const conversation = convosite.conversations.create();
56
23
 
57
- for (const page of result.pages) {
58
- console.log(page.blocks, page.meta);
24
+ for await (const event of conversation.send('What services do you offer?')) {
25
+ console.log(event);
59
26
  }
60
27
  ```
61
28
 
62
- Supported list sorts are `name`, `slug`, `title`, `created_at`, and `updated_at`. `perPage` can be 1–100.
63
-
64
- ## Menus
65
-
66
- ```ts
67
- const { menu } = await convosite.menus.get('MENU_ULID');
68
- console.log(menu.items);
69
- console.log(menu.structured);
70
- ```
71
-
72
- ## Search
73
-
74
- ```ts
75
- const { pages } = await convosite.search('pricing', { limit: 10 });
76
- ```
77
-
78
- Search returns full resolved pages, including their relevance score.
79
-
80
- ## Actions
81
-
82
- ```ts
83
- await convosite.actions.run('ENDPOINT_ULID', {
84
- name: 'Joe',
85
- email: 'joe@example.com',
86
- message: 'Hello',
87
- });
88
- ```
89
-
90
- Only public input is sent by the client. Site variables such as API tokens remain server-side and are resolved by Convosite when the endpoint action runs.
29
+ Production defaults to `https://app.convosite.io/api`. No API token belongs in frontend code. Protected site variables remain server-side and can be used by endpoint actions without being exposed to the browser.
91
30
 
92
31
  ## Conversations
93
32
 
94
- Conversations are streamed from the Convosite Cloudflare Worker as NDJSON. The SDK parses the stream and manages the `X-Conversation-Session` header automatically.
33
+ Conversations are streamed from the Convosite runtime as NDJSON. The SDK parses the stream and manages the `X-Conversation-Session` header automatically.
95
34
 
96
35
  ```ts
97
36
  const conversation = convosite.conversations.create();
98
37
 
99
- for await (const event of conversation.send('What services do you offer?')) {
38
+ for await (const event of conversation.send('Help me choose the right service.')) {
100
39
  if (event.type === 'field_delta') {
101
40
  console.log(event.path, event.delta);
102
41
  }
@@ -104,6 +43,14 @@ for await (const event of conversation.send('What services do you offer?')) {
104
43
  if (event.type === 'field_complete') {
105
44
  console.log(event.path, event.value);
106
45
  }
46
+
47
+ if (event.type === 'conversation_usage') {
48
+ console.log(event.user_turns, event.max_user_turns);
49
+ }
50
+
51
+ if (event.type === 'complete') {
52
+ console.log('Turn complete');
53
+ }
107
54
  }
108
55
 
109
56
  // Continues the same server-side conversation.
@@ -114,7 +61,9 @@ for await (const event of conversation.send('Tell me more.')) {
114
61
  await conversation.end();
115
62
  ```
116
63
 
117
- You can also use the stateless surface when you want to manage session IDs yourself:
64
+ Use `conversation.sessionId` to inspect the current session. `conversation.reset()` forgets the session locally without ending it on the server.
65
+
66
+ ### Manage session IDs yourself
118
67
 
119
68
  ```ts
120
69
  for await (const event of convosite.conversations.send('Hello', {
@@ -126,25 +75,42 @@ for await (const event of convosite.conversations.send('Hello', {
126
75
  await convosite.conversations.end('SESSION_UUID');
127
76
  ```
128
77
 
129
- Use `conversation.sessionId` to inspect the current session and `conversation.reset()` to forget it locally without ending it on the server.
78
+ ## Actions
79
+
80
+ Invoke an endpoint defined by the developer and pushed through `@convosite/cli`:
81
+
82
+ ```ts
83
+ await convosite.actions.run('ENDPOINT_ULID', {
84
+ name: 'Joe',
85
+ email: 'joe@example.com',
86
+ message: 'Hello',
87
+ });
88
+ ```
89
+
90
+ Only public input is sent by the client. Site variables such as API tokens remain server-side and are resolved by Convosite when the endpoint action runs.
91
+
92
+ ## Knowledge
93
+
94
+ Knowledge is intentionally not exposed by this package. Knowledge and Knowledge Items are managed in Convosite and indexed for retrieval. The conversation runtime uses that knowledge when generating conversational experiences.
95
+
96
+ This keeps application code focused on conversations rather than turning Knowledge into another public content API.
130
97
 
131
98
  ## Cancellation
132
99
 
133
- All methods accept an `AbortSignal`:
100
+ Actions and conversation streams accept an `AbortSignal`:
134
101
 
135
102
  ```ts
136
103
  const controller = new AbortController();
137
104
 
138
- const request = convosite.pages.get('/about', {
105
+ for await (const event of convosite.conversations.send('Hello', {
139
106
  signal: controller.signal,
140
- });
107
+ })) {
108
+ console.log(event);
109
+ }
141
110
 
142
111
  controller.abort();
143
- await request;
144
112
  ```
145
113
 
146
- Conversation streams support the same pattern.
147
-
148
114
  ## SSR and custom fetch
149
115
 
150
116
  A custom `fetch` can be supplied for framework runtimes, instrumentation or tests:
@@ -162,7 +128,7 @@ const convosite = createConvosite({
162
128
  import { ConvositeError } from '@convosite/client';
163
129
 
164
130
  try {
165
- await convosite.pages.get('/missing');
131
+ await convosite.actions.run('ENDPOINT_ULID', {});
166
132
  } catch (error) {
167
133
  if (error instanceof ConvositeError) {
168
134
  console.log(error.status);
@@ -174,17 +140,17 @@ try {
174
140
  }
175
141
  ```
176
142
 
177
- Validation errors are available through `details`. Worker error codes such as `conversation_ended` and `conversation_limit_reached` are exposed through `code`.
143
+ Validation errors are available through `details`. Conversation error codes such as `conversation_ended` and `conversation_limit_reached` are exposed through `code` when returned by the runtime.
178
144
 
179
145
  ## Raw request escape hatch
180
146
 
181
- For new runtime endpoints that are not yet wrapped by the SDK:
147
+ For public Laravel API endpoints that are not yet wrapped by the SDK:
182
148
 
183
149
  ```ts
184
150
  const data = await convosite.request('/some/runtime/endpoint');
185
151
  ```
186
152
 
187
- The path is relative to `baseUrl` and uses the same error handling and configured headers.
153
+ The path is relative to `baseUrl` and uses the same error handling, timeout and configured headers as actions.
188
154
 
189
155
  ## Configuration
190
156
 
@@ -199,4 +165,6 @@ const convosite = createConvosite({
199
165
  });
200
166
  ```
201
167
 
202
- The timeout applies to normal JSON requests. Conversation streams are intentionally not given a fixed SDK timeout; use an `AbortSignal` when you need one.
168
+ `baseUrl` is used for actions and raw requests. `conversationUrl` is used for streamed conversations and defaults to `baseUrl`.
169
+
170
+ The timeout applies to normal JSON requests. Conversation streams intentionally have no fixed SDK timeout; use an `AbortSignal` when needed.
package/dist/index.cjs CHANGED
@@ -52,14 +52,6 @@ function joinUrl(base, path) {
52
52
  function encodeSegment(value) {
53
53
  return encodeURIComponent(value);
54
54
  }
55
- function queryString(values) {
56
- const params = new URLSearchParams();
57
- for (const [key, value] of Object.entries(values)) {
58
- if (value !== void 0 && value !== null) params.set(key, String(value));
59
- }
60
- const query = params.toString();
61
- return query ? `?${query}` : "";
62
- }
63
55
  function timeoutSignal(signal, timeout) {
64
56
  if (timeout <= 0) return signal ? { signal, cleanup: () => void 0 } : { cleanup: () => void 0 };
65
57
  const controller = new AbortController();
@@ -262,52 +254,52 @@ var ConversationsClient = class {
262
254
  var DEFAULT_BASE_URL = "https://app.convosite.io/api";
263
255
  function createConvosite(config) {
264
256
  if (!config || typeof config.site !== "string" || !config.site.trim()) {
265
- throw new ConvositeError({ message: "A Convosite site ID is required.", code: "invalid_config" });
257
+ throw new ConvositeError({
258
+ message: "A Convosite site ID is required.",
259
+ code: "invalid_config"
260
+ });
266
261
  }
267
262
  const fetcher = config.fetch ?? globalThis.fetch?.bind(globalThis);
268
- if (!fetcher) throw new ConvositeError({ message: "No fetch implementation is available.", code: "invalid_config" });
263
+ if (!fetcher) {
264
+ throw new ConvositeError({
265
+ message: "No fetch implementation is available.",
266
+ code: "invalid_config"
267
+ });
268
+ }
269
269
  const siteId = config.site.trim();
270
+ const site = encodeSegment(siteId);
270
271
  const baseUrl = normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL);
271
272
  const conversationUrl = normalizeBaseUrl(config.conversationUrl ?? baseUrl);
272
- const http = new HttpClient(fetcher, baseUrl, config.headers ?? {}, config.timeout ?? 3e4);
273
+ const http = new HttpClient(
274
+ fetcher,
275
+ baseUrl,
276
+ config.headers ?? {},
277
+ config.timeout ?? 3e4
278
+ );
273
279
  const conversations = new ConversationsClient(fetcher, conversationUrl, siteId);
274
- const site = encodeSegment(siteId);
275
280
  const requestOptions = (options) => options?.signal ? { signal: options.signal } : {};
276
281
  return {
277
- site: {
278
- get: (options) => http.api(`/${site}`, requestOptions(options))
279
- },
280
- pages: {
281
- get: (path, options) => {
282
- if (typeof path !== "string") throw new ConvositeError({ message: "Page path must be a string.", code: "validation_error" });
283
- return http.api(`/content/${site}/pages${queryString({ path })}`, requestOptions(options));
284
- },
285
- find: (id, options) => http.api(`/content/${site}/pages/${encodeSegment(id)}`, requestOptions(options)),
286
- list: (options = {}) => {
287
- const { parentId, sort, direction, page, perPage, signal } = options;
288
- return http.api(`/content/${site}/pages${queryString({
289
- parent_id: parentId,
290
- sort,
291
- direction,
292
- page,
293
- per_page: perPage
294
- })}`, requestOptions(signal ? { signal } : void 0));
295
- }
296
- },
297
- menus: {
298
- get: (id, options) => http.api(`/content/${site}/menus/${encodeSegment(id)}`, requestOptions(options))
299
- },
300
- search: (query, options = {}) => {
301
- const { limit, signal } = options;
302
- return http.api(`/search/${site}${queryString({ query, limit })}`, requestOptions(signal ? { signal } : void 0));
303
- },
304
282
  actions: {
305
- run: (endpointId, input, options) => http.api(`/actions/${site}/${encodeSegment(endpointId)}`, {
306
- method: "POST",
307
- headers: { "Content-Type": "application/json", "Accept": "application/json" },
308
- body: JSON.stringify(input),
309
- ...requestOptions(options)
310
- })
283
+ run: (endpointId, input, options) => {
284
+ if (typeof endpointId !== "string" || !endpointId.trim()) {
285
+ throw new ConvositeError({
286
+ message: "An endpoint ID is required.",
287
+ code: "validation_error"
288
+ });
289
+ }
290
+ return http.api(
291
+ `/actions/${site}/${encodeSegment(endpointId.trim())}`,
292
+ {
293
+ method: "POST",
294
+ headers: {
295
+ "Content-Type": "application/json",
296
+ Accept: "application/json"
297
+ },
298
+ body: JSON.stringify(input),
299
+ ...requestOptions(options)
300
+ }
301
+ );
302
+ }
311
303
  },
312
304
  conversations: {
313
305
  create: (sessionId) => conversations.create(sessionId),
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/conversations.ts","../src/client.ts"],"sourcesContent":["export { createConvosite } from './client';\nexport { ConvositeError } from './errors';\nexport type {\n ActionResponse,\n Conversation,\n ConversationCompleteEvent,\n ConversationEndResponse,\n ConversationErrorEvent,\n ConversationEvent,\n ConversationFieldEvent,\n ConversationSendOptions,\n ConversationUsageEvent,\n ConvositeClient,\n ConvositeConfig,\n Fetch,\n JsonPrimitive,\n JsonValue,\n Media,\n Menu,\n MenuItem,\n MenuResponse,\n Page,\n PageBlock,\n PageListOptions,\n PageListResponse,\n PageMetaValue,\n PageResponse,\n PageSort,\n Pagination,\n RawRequestOptions,\n RequestOptions,\n SearchOptions,\n SearchResponse,\n Site,\n SiteMetaValue,\n SortDirection,\n StructuredMenuItem,\n} from './types';\n","export class ConvositeError extends Error {\n readonly status: number;\n readonly code: string | null;\n readonly details: unknown;\n readonly requestId: string | null;\n\n constructor(options: {\n message: string;\n status?: number;\n code?: string | null;\n details?: unknown;\n requestId?: string | null;\n cause?: unknown;\n }) {\n super(options.message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = 'ConvositeError';\n this.status = options.status ?? 0;\n this.code = options.code ?? null;\n this.details = options.details ?? null;\n this.requestId = options.requestId ?? null;\n }\n}\n","import { ConvositeError } from './errors';\nimport type { Fetch, RawRequestOptions } from './types';\n\ninterface ApiEnvelope<T> {\n success: boolean;\n message: string;\n data: T;\n errors: unknown;\n}\n\nexport function normalizeBaseUrl(value: string): string {\n return value.replace(/\\/+$/, '');\n}\n\nexport function joinUrl(base: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${normalizeBaseUrl(base)}/${path.replace(/^\\/+/, '')}`;\n}\n\nexport function encodeSegment(value: string): string {\n return encodeURIComponent(value);\n}\n\nexport function queryString(values: Record<string, string | number | null | undefined>): string {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(values)) {\n if (value !== undefined && value !== null) params.set(key, String(value));\n }\n const query = params.toString();\n return query ? `?${query}` : '';\n}\n\nfunction timeoutSignal(signal: AbortSignal | undefined, timeout: number): { signal?: AbortSignal; cleanup: () => void } {\n if (timeout <= 0) return signal ? { signal, cleanup: () => undefined } : { cleanup: () => undefined };\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(new DOMException('Request timed out.', 'TimeoutError')), timeout);\n const abort = () => controller.abort(signal?.reason);\n if (signal) {\n if (signal.aborted) abort();\n else signal.addEventListener('abort', abort, { once: true });\n }\n return {\n signal: controller.signal,\n cleanup: () => {\n clearTimeout(timer);\n signal?.removeEventListener('abort', abort);\n },\n };\n}\n\nasync function responseBody(response: Response): Promise<unknown> {\n const text = await response.text();\n if (!text) return null;\n try { return JSON.parse(text); } catch { return text; }\n}\n\nfunction errorFrom(response: Response, body: unknown): ConvositeError {\n const object = body && typeof body === 'object' ? body as Record<string, unknown> : {};\n const message = typeof object.message === 'string' ? object.message : `Convosite request failed with status ${response.status}.`;\n const code = typeof object.error === 'string' ? object.error : null;\n const details = object.errors ?? body;\n return new ConvositeError({\n message,\n status: response.status,\n code,\n details,\n requestId: response.headers.get('X-Request-ID'),\n });\n}\n\nexport class HttpClient {\n constructor(\n private readonly fetcher: Fetch,\n private readonly baseUrl: string,\n private readonly headers: HeadersInit,\n private readonly timeout: number,\n ) {}\n\n async api<T>(path: string, init: RequestInit = {}): Promise<T> {\n const response = await this.fetch(path, init, true);\n const body = await responseBody(response);\n if (!response.ok) throw errorFrom(response, body);\n if (!body || typeof body !== 'object' || !('success' in body)) {\n throw new ConvositeError({ message: 'Convosite returned an invalid API response.', status: response.status, details: body });\n }\n const envelope = body as ApiEnvelope<T>;\n if (envelope.success !== true) {\n throw new ConvositeError({ message: envelope.message || 'Convosite request failed.', status: response.status, details: envelope.errors });\n }\n return envelope.data;\n }\n\n async raw<T>(path: string, options: RawRequestOptions = {}): Promise<T> {\n const { parseAs = 'json', ...init } = options;\n const response = await this.fetch(path, init, true);\n if (!response.ok) throw errorFrom(response, await responseBody(response));\n if (parseAs === 'response') return response as T;\n if (parseAs === 'text') return await response.text() as T;\n if (response.status === 204) return undefined as T;\n return await response.json() as T;\n }\n\n async fetch(path: string, init: RequestInit = {}, useTimeout = false): Promise<Response> {\n const headers = new Headers(this.headers);\n new Headers(init.headers).forEach((value, key) => headers.set(key, value));\n const timed = useTimeout ? timeoutSignal(init.signal ?? undefined, this.timeout) : timeoutSignal(init.signal ?? undefined, 0);\n try {\n const requestInit: RequestInit = { ...init, headers };\n if (timed.signal) requestInit.signal = timed.signal;\n return await this.fetcher(joinUrl(this.baseUrl, path), requestInit);\n } catch (cause) {\n if (cause instanceof ConvositeError) throw cause;\n const aborted = timed.signal?.aborted;\n throw new ConvositeError({\n message: aborted ? 'Convosite request was aborted.' : 'Unable to connect to Convosite.',\n code: aborted ? 'request_aborted' : 'network_error',\n cause,\n });\n } finally {\n timed.cleanup();\n }\n }\n}\n\nexport async function workerError(response: Response): Promise<ConvositeError> {\n return errorFrom(response, await responseBody(response));\n}\n","import { ConvositeError } from './errors';\nimport { encodeSegment, joinUrl, workerError } from './http';\nimport type {\n Conversation,\n ConversationEndResponse,\n ConversationEvent,\n ConversationSendOptions,\n Fetch,\n RequestOptions,\n} from './types';\n\nasync function* parseNdjson(response: Response): AsyncGenerator<ConversationEvent> {\n if (!response.body) throw new ConvositeError({ message: 'Conversation response did not contain a stream.', status: response.status });\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (true) {\n const { value, done } = await reader.read();\n buffer += decoder.decode(value, { stream: !done });\n let newline: number;\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n if (line) yield parseEvent(line);\n }\n if (done) break;\n }\n const tail = buffer.trim();\n if (tail) yield parseEvent(tail);\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction parseEvent(line: string): ConversationEvent {\n try {\n const event = JSON.parse(line) as unknown;\n if (!event || typeof event !== 'object' || typeof (event as { type?: unknown }).type !== 'string') {\n throw new Error('Event has no type.');\n }\n return event as ConversationEvent;\n } catch (cause) {\n throw new ConvositeError({ message: 'Conversation stream contained an invalid event.', code: 'invalid_stream', details: line, cause });\n }\n}\n\nexport class ConversationsClient {\n constructor(\n private readonly fetcher: Fetch,\n private readonly baseUrl: string,\n private readonly siteId: string,\n ) {}\n\n create(sessionId?: string): Conversation {\n let currentSession = sessionId?.trim() || null;\n const client = this;\n return {\n get sessionId() { return currentSession; },\n async *send(query: string, options: RequestOptions = {}) {\n const stream = client.send(query, { ...options, ...(currentSession ? { sessionId: currentSession } : {}) }, (id) => { currentSession = id; });\n yield* stream;\n },\n async end(options: RequestOptions = {}) {\n if (!currentSession) return { ended: false };\n const result = await client.end(currentSession, options);\n if (result.ended) currentSession = null;\n return result;\n },\n reset() { currentSession = null; },\n };\n }\n\n async *send(\n query: string,\n options: ConversationSendOptions = {},\n onSession?: (sessionId: string) => void,\n ): AsyncGenerator<ConversationEvent> {\n const trimmed = query.trim();\n if (!trimmed) throw new ConvositeError({ message: 'Conversation query is required.', code: 'validation_error' });\n const headers = new Headers({ 'Content-Type': 'application/json', 'Accept': 'application/x-ndjson' });\n if (options.sessionId) headers.set('X-Conversation-Session', options.sessionId);\n let response: Response;\n try {\n const init: RequestInit = { method: 'POST', headers, body: JSON.stringify({ query: trimmed }) };\n if (options.signal) init.signal = options.signal;\n response = await this.fetcher(joinUrl(this.baseUrl, `/conversations/${encodeSegment(this.siteId)}`), init);\n } catch (cause) {\n throw new ConvositeError({ message: options.signal?.aborted ? 'Conversation request was aborted.' : 'Unable to connect to Convosite conversations.', code: options.signal?.aborted ? 'request_aborted' : 'network_error', cause });\n }\n if (!response.ok) throw await workerError(response);\n const session = response.headers.get('X-Conversation-Session');\n if (session) onSession?.(session);\n yield* parseNdjson(response);\n }\n\n async end(sessionId: string, options: RequestOptions = {}): Promise<ConversationEndResponse> {\n const headers = new Headers({ 'Accept': 'application/json', 'X-Conversation-Session': sessionId });\n let response: Response;\n try {\n const init: RequestInit = { method: 'POST', headers };\n if (options.signal) init.signal = options.signal;\n response = await this.fetcher(joinUrl(this.baseUrl, `/conversations/${encodeSegment(this.siteId)}/end`), init);\n } catch (cause) {\n throw new ConvositeError({ message: options.signal?.aborted ? 'Conversation request was aborted.' : 'Unable to connect to Convosite conversations.', code: options.signal?.aborted ? 'request_aborted' : 'network_error', cause });\n }\n if (!response.ok) throw await workerError(response);\n return await response.json() as ConversationEndResponse;\n }\n}\n","import { ConvositeError } from './errors';\nimport { ConversationsClient } from './conversations';\nimport { encodeSegment, HttpClient, normalizeBaseUrl, queryString } from './http';\nimport type {\n ActionResponse,\n ConvositeClient,\n ConvositeConfig,\n MenuResponse,\n PageListOptions,\n PageListResponse,\n PageResponse,\n RawRequestOptions,\n RequestOptions,\n SearchOptions,\n SearchResponse,\n Site,\n} from './types';\n\nconst DEFAULT_BASE_URL = 'https://app.convosite.io/api';\n\nexport function createConvosite(config: ConvositeConfig): ConvositeClient {\n if (!config || typeof config.site !== 'string' || !config.site.trim()) {\n throw new ConvositeError({ message: 'A Convosite site ID is required.', code: 'invalid_config' });\n }\n const fetcher = config.fetch ?? globalThis.fetch?.bind(globalThis);\n if (!fetcher) throw new ConvositeError({ message: 'No fetch implementation is available.', code: 'invalid_config' });\n const siteId = config.site.trim();\n const baseUrl = normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL);\n const conversationUrl = normalizeBaseUrl(config.conversationUrl ?? baseUrl);\n const http = new HttpClient(fetcher, baseUrl, config.headers ?? {}, config.timeout ?? 30_000);\n const conversations = new ConversationsClient(fetcher, conversationUrl, siteId);\n const site = encodeSegment(siteId);\n\n const requestOptions = (options?: RequestOptions): RequestInit => options?.signal ? { signal: options.signal } : {};\n\n return {\n site: {\n get: (options) => http.api<Site>(`/${site}`, requestOptions(options)),\n },\n pages: {\n get: (path, options) => {\n if (typeof path !== 'string') throw new ConvositeError({ message: 'Page path must be a string.', code: 'validation_error' });\n return http.api<PageResponse>(`/content/${site}/pages${queryString({ path })}`, requestOptions(options));\n },\n find: (id, options) => http.api<PageResponse>(`/content/${site}/pages/${encodeSegment(id)}`, requestOptions(options)),\n list: (options: PageListOptions = {}) => {\n const { parentId, sort, direction, page, perPage, signal } = options;\n return http.api<PageListResponse>(`/content/${site}/pages${queryString({\n parent_id: parentId,\n sort,\n direction,\n page,\n per_page: perPage,\n })}`, requestOptions(signal ? { signal } : undefined));\n },\n },\n menus: {\n get: (id, options) => http.api<MenuResponse>(`/content/${site}/menus/${encodeSegment(id)}`, requestOptions(options)),\n },\n search: (query: string, options: SearchOptions = {}) => {\n const { limit, signal } = options;\n return http.api<SearchResponse>(`/search/${site}${queryString({ query, limit })}`, requestOptions(signal ? { signal } : undefined));\n },\n actions: {\n run: (endpointId, input, options) => http.api<ActionResponse>(`/actions/${site}/${encodeSegment(endpointId)}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n body: JSON.stringify(input),\n ...requestOptions(options),\n }),\n },\n conversations: {\n create: (sessionId) => conversations.create(sessionId),\n send: (query, options) => conversations.send(query, options),\n end: (sessionId, options) => conversations.end(sessionId, options),\n },\n request: <T = unknown>(path: string, options: RawRequestOptions = {}) => http.raw<T>(path, options),\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/conversations.ts","../src/client.ts"],"sourcesContent":["export { createConvosite } from './client';\nexport { ConvositeError } from './errors';\nexport type {\n ActionResponse,\n Conversation,\n ConversationCompleteEvent,\n ConversationEndResponse,\n ConversationErrorEvent,\n ConversationEvent,\n ConversationFieldEvent,\n ConversationSendOptions,\n ConversationUsageEvent,\n ConvositeClient,\n ConvositeConfig,\n Fetch,\n JsonPrimitive,\n JsonValue,\n RawRequestOptions,\n RequestOptions,\n} from './types';\n","export class ConvositeError extends Error {\n readonly status: number;\n readonly code: string | null;\n readonly details: unknown;\n readonly requestId: string | null;\n\n constructor(options: {\n message: string;\n status?: number;\n code?: string | null;\n details?: unknown;\n requestId?: string | null;\n cause?: unknown;\n }) {\n super(options.message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = 'ConvositeError';\n this.status = options.status ?? 0;\n this.code = options.code ?? null;\n this.details = options.details ?? null;\n this.requestId = options.requestId ?? null;\n }\n}\n","import { ConvositeError } from './errors';\nimport type { Fetch, RawRequestOptions } from './types';\n\ninterface ApiEnvelope<T> {\n success: boolean;\n message: string;\n data: T;\n errors: unknown;\n}\n\nexport function normalizeBaseUrl(value: string): string {\n return value.replace(/\\/+$/, '');\n}\n\nexport function joinUrl(base: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${normalizeBaseUrl(base)}/${path.replace(/^\\/+/, '')}`;\n}\n\nexport function encodeSegment(value: string): string {\n return encodeURIComponent(value);\n}\n\nfunction timeoutSignal(signal: AbortSignal | undefined, timeout: number): { signal?: AbortSignal; cleanup: () => void } {\n if (timeout <= 0) return signal ? { signal, cleanup: () => undefined } : { cleanup: () => undefined };\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(new DOMException('Request timed out.', 'TimeoutError')), timeout);\n const abort = () => controller.abort(signal?.reason);\n if (signal) {\n if (signal.aborted) abort();\n else signal.addEventListener('abort', abort, { once: true });\n }\n return {\n signal: controller.signal,\n cleanup: () => {\n clearTimeout(timer);\n signal?.removeEventListener('abort', abort);\n },\n };\n}\n\nasync function responseBody(response: Response): Promise<unknown> {\n const text = await response.text();\n if (!text) return null;\n try { return JSON.parse(text); } catch { return text; }\n}\n\nfunction errorFrom(response: Response, body: unknown): ConvositeError {\n const object = body && typeof body === 'object' ? body as Record<string, unknown> : {};\n const message = typeof object.message === 'string' ? object.message : `Convosite request failed with status ${response.status}.`;\n const code = typeof object.error === 'string' ? object.error : null;\n const details = object.errors ?? body;\n return new ConvositeError({\n message,\n status: response.status,\n code,\n details,\n requestId: response.headers.get('X-Request-ID'),\n });\n}\n\nexport class HttpClient {\n constructor(\n private readonly fetcher: Fetch,\n private readonly baseUrl: string,\n private readonly headers: HeadersInit,\n private readonly timeout: number,\n ) {}\n\n async api<T>(path: string, init: RequestInit = {}): Promise<T> {\n const response = await this.fetch(path, init, true);\n const body = await responseBody(response);\n if (!response.ok) throw errorFrom(response, body);\n if (!body || typeof body !== 'object' || !('success' in body)) {\n throw new ConvositeError({ message: 'Convosite returned an invalid API response.', status: response.status, details: body });\n }\n const envelope = body as ApiEnvelope<T>;\n if (envelope.success !== true) {\n throw new ConvositeError({ message: envelope.message || 'Convosite request failed.', status: response.status, details: envelope.errors });\n }\n return envelope.data;\n }\n\n async raw<T>(path: string, options: RawRequestOptions = {}): Promise<T> {\n const { parseAs = 'json', ...init } = options;\n const response = await this.fetch(path, init, true);\n if (!response.ok) throw errorFrom(response, await responseBody(response));\n if (parseAs === 'response') return response as T;\n if (parseAs === 'text') return await response.text() as T;\n if (response.status === 204) return undefined as T;\n return await response.json() as T;\n }\n\n async fetch(path: string, init: RequestInit = {}, useTimeout = false): Promise<Response> {\n const headers = new Headers(this.headers);\n new Headers(init.headers).forEach((value, key) => headers.set(key, value));\n const timed = useTimeout ? timeoutSignal(init.signal ?? undefined, this.timeout) : timeoutSignal(init.signal ?? undefined, 0);\n try {\n const requestInit: RequestInit = { ...init, headers };\n if (timed.signal) requestInit.signal = timed.signal;\n return await this.fetcher(joinUrl(this.baseUrl, path), requestInit);\n } catch (cause) {\n if (cause instanceof ConvositeError) throw cause;\n const aborted = timed.signal?.aborted;\n throw new ConvositeError({\n message: aborted ? 'Convosite request was aborted.' : 'Unable to connect to Convosite.',\n code: aborted ? 'request_aborted' : 'network_error',\n cause,\n });\n } finally {\n timed.cleanup();\n }\n }\n}\n\nexport async function workerError(response: Response): Promise<ConvositeError> {\n return errorFrom(response, await responseBody(response));\n}\n","import { ConvositeError } from './errors';\nimport { encodeSegment, joinUrl, workerError } from './http';\nimport type {\n Conversation,\n ConversationEndResponse,\n ConversationEvent,\n ConversationSendOptions,\n Fetch,\n RequestOptions,\n} from './types';\n\nasync function* parseNdjson(response: Response): AsyncGenerator<ConversationEvent> {\n if (!response.body) throw new ConvositeError({ message: 'Conversation response did not contain a stream.', status: response.status });\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (true) {\n const { value, done } = await reader.read();\n buffer += decoder.decode(value, { stream: !done });\n let newline: number;\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n if (line) yield parseEvent(line);\n }\n if (done) break;\n }\n const tail = buffer.trim();\n if (tail) yield parseEvent(tail);\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction parseEvent(line: string): ConversationEvent {\n try {\n const event = JSON.parse(line) as unknown;\n if (!event || typeof event !== 'object' || typeof (event as { type?: unknown }).type !== 'string') {\n throw new Error('Event has no type.');\n }\n return event as ConversationEvent;\n } catch (cause) {\n throw new ConvositeError({ message: 'Conversation stream contained an invalid event.', code: 'invalid_stream', details: line, cause });\n }\n}\n\nexport class ConversationsClient {\n constructor(\n private readonly fetcher: Fetch,\n private readonly baseUrl: string,\n private readonly siteId: string,\n ) {}\n\n create(sessionId?: string): Conversation {\n let currentSession = sessionId?.trim() || null;\n const client = this;\n return {\n get sessionId() { return currentSession; },\n async *send(query: string, options: RequestOptions = {}) {\n const stream = client.send(query, { ...options, ...(currentSession ? { sessionId: currentSession } : {}) }, (id) => { currentSession = id; });\n yield* stream;\n },\n async end(options: RequestOptions = {}) {\n if (!currentSession) return { ended: false };\n const result = await client.end(currentSession, options);\n if (result.ended) currentSession = null;\n return result;\n },\n reset() { currentSession = null; },\n };\n }\n\n async *send(\n query: string,\n options: ConversationSendOptions = {},\n onSession?: (sessionId: string) => void,\n ): AsyncGenerator<ConversationEvent> {\n const trimmed = query.trim();\n if (!trimmed) throw new ConvositeError({ message: 'Conversation query is required.', code: 'validation_error' });\n const headers = new Headers({ 'Content-Type': 'application/json', 'Accept': 'application/x-ndjson' });\n if (options.sessionId) headers.set('X-Conversation-Session', options.sessionId);\n let response: Response;\n try {\n const init: RequestInit = { method: 'POST', headers, body: JSON.stringify({ query: trimmed }) };\n if (options.signal) init.signal = options.signal;\n response = await this.fetcher(joinUrl(this.baseUrl, `/conversations/${encodeSegment(this.siteId)}`), init);\n } catch (cause) {\n throw new ConvositeError({ message: options.signal?.aborted ? 'Conversation request was aborted.' : 'Unable to connect to Convosite conversations.', code: options.signal?.aborted ? 'request_aborted' : 'network_error', cause });\n }\n if (!response.ok) throw await workerError(response);\n const session = response.headers.get('X-Conversation-Session');\n if (session) onSession?.(session);\n yield* parseNdjson(response);\n }\n\n async end(sessionId: string, options: RequestOptions = {}): Promise<ConversationEndResponse> {\n const headers = new Headers({ 'Accept': 'application/json', 'X-Conversation-Session': sessionId });\n let response: Response;\n try {\n const init: RequestInit = { method: 'POST', headers };\n if (options.signal) init.signal = options.signal;\n response = await this.fetcher(joinUrl(this.baseUrl, `/conversations/${encodeSegment(this.siteId)}/end`), init);\n } catch (cause) {\n throw new ConvositeError({ message: options.signal?.aborted ? 'Conversation request was aborted.' : 'Unable to connect to Convosite conversations.', code: options.signal?.aborted ? 'request_aborted' : 'network_error', cause });\n }\n if (!response.ok) throw await workerError(response);\n return await response.json() as ConversationEndResponse;\n }\n}\n","import { ConversationsClient } from './conversations';\nimport { ConvositeError } from './errors';\nimport { encodeSegment, HttpClient, normalizeBaseUrl } from './http';\nimport type {\n ActionResponse,\n ConvositeClient,\n ConvositeConfig,\n RawRequestOptions,\n RequestOptions,\n} from './types';\n\nconst DEFAULT_BASE_URL = 'https://app.convosite.io/api';\n\nexport function createConvosite(config: ConvositeConfig): ConvositeClient {\n if (!config || typeof config.site !== 'string' || !config.site.trim()) {\n throw new ConvositeError({\n message: 'A Convosite site ID is required.',\n code: 'invalid_config',\n });\n }\n\n const fetcher = config.fetch ?? globalThis.fetch?.bind(globalThis);\n if (!fetcher) {\n throw new ConvositeError({\n message: 'No fetch implementation is available.',\n code: 'invalid_config',\n });\n }\n\n const siteId = config.site.trim();\n const site = encodeSegment(siteId);\n const baseUrl = normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL);\n const conversationUrl = normalizeBaseUrl(config.conversationUrl ?? baseUrl);\n const http = new HttpClient(\n fetcher,\n baseUrl,\n config.headers ?? {},\n config.timeout ?? 30_000,\n );\n const conversations = new ConversationsClient(fetcher, conversationUrl, siteId);\n\n const requestOptions = (options?: RequestOptions): RequestInit =>\n options?.signal ? { signal: options.signal } : {};\n\n return {\n actions: {\n run: (endpointId, input, options) => {\n if (typeof endpointId !== 'string' || !endpointId.trim()) {\n throw new ConvositeError({\n message: 'An endpoint ID is required.',\n code: 'validation_error',\n });\n }\n\n return http.api<ActionResponse>(\n `/actions/${site}/${encodeSegment(endpointId.trim())}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify(input),\n ...requestOptions(options),\n },\n );\n },\n },\n conversations: {\n create: (sessionId) => conversations.create(sessionId),\n send: (query, options) => conversations.send(query, options),\n end: (sessionId, options) => conversations.end(sessionId, options),\n },\n request: <T = unknown>(path: string, options: RawRequestOptions = {}) =>\n http.raw<T>(path, options),\n };\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -2,109 +2,6 @@ type JsonPrimitive = string | number | boolean | null;
2
2
  type JsonValue = JsonPrimitive | JsonValue[] | {
3
3
  [key: string]: JsonValue;
4
4
  };
5
- interface SiteMetaValue<T = unknown> {
6
- type: string;
7
- key: string;
8
- value: T;
9
- }
10
- interface Site {
11
- name: string;
12
- global: Record<string, SiteMetaValue>;
13
- }
14
- interface Media {
15
- id: string;
16
- url: string;
17
- alt?: string | null;
18
- caption?: string | null;
19
- width?: number | null;
20
- height?: number | null;
21
- mime?: string | null;
22
- bytes?: number | null;
23
- metadata?: Record<string, unknown> | null;
24
- [key: string]: unknown;
25
- }
26
- interface PageBlock<TData extends Record<string, unknown> = Record<string, unknown>> {
27
- key: string;
28
- name: string;
29
- data: TData;
30
- }
31
- interface PageMetaValue<T = unknown> {
32
- type: string;
33
- key: string;
34
- value: T;
35
- }
36
- interface Page {
37
- id: string;
38
- name: string;
39
- slug: string;
40
- active: boolean;
41
- is_home: boolean;
42
- path: string;
43
- seo: {
44
- title: string | null;
45
- description: string | null;
46
- };
47
- blocks: PageBlock[];
48
- meta: Record<string, PageMetaValue>;
49
- score?: number;
50
- [key: string]: unknown;
51
- }
52
- interface PageResponse {
53
- site: Site;
54
- page: Page;
55
- }
56
- interface Pagination {
57
- current_page: number;
58
- per_page: number;
59
- total: number;
60
- last_page: number;
61
- from: number | null;
62
- to: number | null;
63
- }
64
- type PageSort = 'name' | 'slug' | 'title' | 'created_at' | 'updated_at';
65
- type SortDirection = 'asc' | 'desc';
66
- interface PageListOptions extends RequestOptions {
67
- parentId?: string | null;
68
- sort?: PageSort;
69
- direction?: SortDirection;
70
- page?: number;
71
- perPage?: number;
72
- }
73
- interface PageListResponse {
74
- site: Site;
75
- pages: Page[];
76
- pagination: Pagination;
77
- }
78
- interface MenuItem {
79
- id: string;
80
- parent_id: string | null;
81
- name: string;
82
- description: string | null;
83
- classes: string | null;
84
- type: string;
85
- position: number;
86
- href: string | null;
87
- }
88
- interface StructuredMenuItem extends MenuItem {
89
- children: StructuredMenuItem[];
90
- }
91
- interface Menu {
92
- name: string;
93
- active: boolean;
94
- items: MenuItem[];
95
- structured: StructuredMenuItem[];
96
- }
97
- interface MenuResponse {
98
- site: Site;
99
- menu: Menu;
100
- }
101
- interface SearchOptions extends RequestOptions {
102
- limit?: number;
103
- }
104
- interface SearchResponse {
105
- site: Site;
106
- pages: Page[];
107
- }
108
5
  interface ActionResponse {
109
6
  message: string;
110
7
  }
@@ -167,11 +64,11 @@ interface Conversation {
167
64
  }
168
65
  type Fetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
169
66
  interface ConvositeConfig {
170
- /** Site ULID used by the Convosite runtime API. */
67
+ /** Site ULID used by the Convosite runtime. */
171
68
  site: string;
172
- /** Laravel runtime API base. Defaults to https://app.convosite.io/api. */
69
+ /** Laravel public API base. Defaults to https://app.convosite.io/api. */
173
70
  baseUrl?: string;
174
- /** Conversations Worker base. Defaults to baseUrl (the production Worker is routed through app.convosite.io). */
71
+ /** Conversations Worker base. Defaults to baseUrl. */
175
72
  conversationUrl?: string;
176
73
  /** Custom fetch implementation for SSR runtimes, tests, proxies, etc. */
177
74
  fetch?: Fetch;
@@ -181,18 +78,6 @@ interface ConvositeConfig {
181
78
  timeout?: number;
182
79
  }
183
80
  interface ConvositeClient {
184
- readonly site: {
185
- get(options?: RequestOptions): Promise<Site>;
186
- };
187
- readonly pages: {
188
- get(path: string, options?: RequestOptions): Promise<PageResponse>;
189
- find(id: string, options?: RequestOptions): Promise<PageResponse>;
190
- list(options?: PageListOptions): Promise<PageListResponse>;
191
- };
192
- readonly menus: {
193
- get(id: string, options?: RequestOptions): Promise<MenuResponse>;
194
- };
195
- search(query: string, options?: SearchOptions): Promise<SearchResponse>;
196
81
  readonly actions: {
197
82
  run<TInput extends Record<string, unknown> = Record<string, unknown>>(endpointId: string, input: TInput, options?: RequestOptions): Promise<ActionResponse>;
198
83
  };
@@ -201,6 +86,7 @@ interface ConvositeClient {
201
86
  send(query: string, options?: ConversationSendOptions): AsyncIterable<ConversationEvent>;
202
87
  end(sessionId: string, options?: RequestOptions): Promise<ConversationEndResponse>;
203
88
  };
89
+ /** Escape hatch for public Laravel API endpoints not yet wrapped by the SDK. */
204
90
  request<T = unknown>(path: string, options?: RawRequestOptions): Promise<T>;
205
91
  }
206
92
 
@@ -221,4 +107,4 @@ declare class ConvositeError extends Error {
221
107
  });
222
108
  }
223
109
 
224
- export { type ActionResponse, type Conversation, type ConversationCompleteEvent, type ConversationEndResponse, type ConversationErrorEvent, type ConversationEvent, type ConversationFieldEvent, type ConversationSendOptions, type ConversationUsageEvent, type ConvositeClient, type ConvositeConfig, ConvositeError, type Fetch, type JsonPrimitive, type JsonValue, type Media, type Menu, type MenuItem, type MenuResponse, type Page, type PageBlock, type PageListOptions, type PageListResponse, type PageMetaValue, type PageResponse, type PageSort, type Pagination, type RawRequestOptions, type RequestOptions, type SearchOptions, type SearchResponse, type Site, type SiteMetaValue, type SortDirection, type StructuredMenuItem, createConvosite };
110
+ export { type ActionResponse, type Conversation, type ConversationCompleteEvent, type ConversationEndResponse, type ConversationErrorEvent, type ConversationEvent, type ConversationFieldEvent, type ConversationSendOptions, type ConversationUsageEvent, type ConvositeClient, type ConvositeConfig, ConvositeError, type Fetch, type JsonPrimitive, type JsonValue, type RawRequestOptions, type RequestOptions, createConvosite };
package/dist/index.d.ts CHANGED
@@ -2,109 +2,6 @@ type JsonPrimitive = string | number | boolean | null;
2
2
  type JsonValue = JsonPrimitive | JsonValue[] | {
3
3
  [key: string]: JsonValue;
4
4
  };
5
- interface SiteMetaValue<T = unknown> {
6
- type: string;
7
- key: string;
8
- value: T;
9
- }
10
- interface Site {
11
- name: string;
12
- global: Record<string, SiteMetaValue>;
13
- }
14
- interface Media {
15
- id: string;
16
- url: string;
17
- alt?: string | null;
18
- caption?: string | null;
19
- width?: number | null;
20
- height?: number | null;
21
- mime?: string | null;
22
- bytes?: number | null;
23
- metadata?: Record<string, unknown> | null;
24
- [key: string]: unknown;
25
- }
26
- interface PageBlock<TData extends Record<string, unknown> = Record<string, unknown>> {
27
- key: string;
28
- name: string;
29
- data: TData;
30
- }
31
- interface PageMetaValue<T = unknown> {
32
- type: string;
33
- key: string;
34
- value: T;
35
- }
36
- interface Page {
37
- id: string;
38
- name: string;
39
- slug: string;
40
- active: boolean;
41
- is_home: boolean;
42
- path: string;
43
- seo: {
44
- title: string | null;
45
- description: string | null;
46
- };
47
- blocks: PageBlock[];
48
- meta: Record<string, PageMetaValue>;
49
- score?: number;
50
- [key: string]: unknown;
51
- }
52
- interface PageResponse {
53
- site: Site;
54
- page: Page;
55
- }
56
- interface Pagination {
57
- current_page: number;
58
- per_page: number;
59
- total: number;
60
- last_page: number;
61
- from: number | null;
62
- to: number | null;
63
- }
64
- type PageSort = 'name' | 'slug' | 'title' | 'created_at' | 'updated_at';
65
- type SortDirection = 'asc' | 'desc';
66
- interface PageListOptions extends RequestOptions {
67
- parentId?: string | null;
68
- sort?: PageSort;
69
- direction?: SortDirection;
70
- page?: number;
71
- perPage?: number;
72
- }
73
- interface PageListResponse {
74
- site: Site;
75
- pages: Page[];
76
- pagination: Pagination;
77
- }
78
- interface MenuItem {
79
- id: string;
80
- parent_id: string | null;
81
- name: string;
82
- description: string | null;
83
- classes: string | null;
84
- type: string;
85
- position: number;
86
- href: string | null;
87
- }
88
- interface StructuredMenuItem extends MenuItem {
89
- children: StructuredMenuItem[];
90
- }
91
- interface Menu {
92
- name: string;
93
- active: boolean;
94
- items: MenuItem[];
95
- structured: StructuredMenuItem[];
96
- }
97
- interface MenuResponse {
98
- site: Site;
99
- menu: Menu;
100
- }
101
- interface SearchOptions extends RequestOptions {
102
- limit?: number;
103
- }
104
- interface SearchResponse {
105
- site: Site;
106
- pages: Page[];
107
- }
108
5
  interface ActionResponse {
109
6
  message: string;
110
7
  }
@@ -167,11 +64,11 @@ interface Conversation {
167
64
  }
168
65
  type Fetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
169
66
  interface ConvositeConfig {
170
- /** Site ULID used by the Convosite runtime API. */
67
+ /** Site ULID used by the Convosite runtime. */
171
68
  site: string;
172
- /** Laravel runtime API base. Defaults to https://app.convosite.io/api. */
69
+ /** Laravel public API base. Defaults to https://app.convosite.io/api. */
173
70
  baseUrl?: string;
174
- /** Conversations Worker base. Defaults to baseUrl (the production Worker is routed through app.convosite.io). */
71
+ /** Conversations Worker base. Defaults to baseUrl. */
175
72
  conversationUrl?: string;
176
73
  /** Custom fetch implementation for SSR runtimes, tests, proxies, etc. */
177
74
  fetch?: Fetch;
@@ -181,18 +78,6 @@ interface ConvositeConfig {
181
78
  timeout?: number;
182
79
  }
183
80
  interface ConvositeClient {
184
- readonly site: {
185
- get(options?: RequestOptions): Promise<Site>;
186
- };
187
- readonly pages: {
188
- get(path: string, options?: RequestOptions): Promise<PageResponse>;
189
- find(id: string, options?: RequestOptions): Promise<PageResponse>;
190
- list(options?: PageListOptions): Promise<PageListResponse>;
191
- };
192
- readonly menus: {
193
- get(id: string, options?: RequestOptions): Promise<MenuResponse>;
194
- };
195
- search(query: string, options?: SearchOptions): Promise<SearchResponse>;
196
81
  readonly actions: {
197
82
  run<TInput extends Record<string, unknown> = Record<string, unknown>>(endpointId: string, input: TInput, options?: RequestOptions): Promise<ActionResponse>;
198
83
  };
@@ -201,6 +86,7 @@ interface ConvositeClient {
201
86
  send(query: string, options?: ConversationSendOptions): AsyncIterable<ConversationEvent>;
202
87
  end(sessionId: string, options?: RequestOptions): Promise<ConversationEndResponse>;
203
88
  };
89
+ /** Escape hatch for public Laravel API endpoints not yet wrapped by the SDK. */
204
90
  request<T = unknown>(path: string, options?: RawRequestOptions): Promise<T>;
205
91
  }
206
92
 
@@ -221,4 +107,4 @@ declare class ConvositeError extends Error {
221
107
  });
222
108
  }
223
109
 
224
- export { type ActionResponse, type Conversation, type ConversationCompleteEvent, type ConversationEndResponse, type ConversationErrorEvent, type ConversationEvent, type ConversationFieldEvent, type ConversationSendOptions, type ConversationUsageEvent, type ConvositeClient, type ConvositeConfig, ConvositeError, type Fetch, type JsonPrimitive, type JsonValue, type Media, type Menu, type MenuItem, type MenuResponse, type Page, type PageBlock, type PageListOptions, type PageListResponse, type PageMetaValue, type PageResponse, type PageSort, type Pagination, type RawRequestOptions, type RequestOptions, type SearchOptions, type SearchResponse, type Site, type SiteMetaValue, type SortDirection, type StructuredMenuItem, createConvosite };
110
+ export { type ActionResponse, type Conversation, type ConversationCompleteEvent, type ConversationEndResponse, type ConversationErrorEvent, type ConversationEvent, type ConversationFieldEvent, type ConversationSendOptions, type ConversationUsageEvent, type ConvositeClient, type ConvositeConfig, ConvositeError, type Fetch, type JsonPrimitive, type JsonValue, type RawRequestOptions, type RequestOptions, createConvosite };
package/dist/index.js CHANGED
@@ -25,14 +25,6 @@ function joinUrl(base, path) {
25
25
  function encodeSegment(value) {
26
26
  return encodeURIComponent(value);
27
27
  }
28
- function queryString(values) {
29
- const params = new URLSearchParams();
30
- for (const [key, value] of Object.entries(values)) {
31
- if (value !== void 0 && value !== null) params.set(key, String(value));
32
- }
33
- const query = params.toString();
34
- return query ? `?${query}` : "";
35
- }
36
28
  function timeoutSignal(signal, timeout) {
37
29
  if (timeout <= 0) return signal ? { signal, cleanup: () => void 0 } : { cleanup: () => void 0 };
38
30
  const controller = new AbortController();
@@ -235,52 +227,52 @@ var ConversationsClient = class {
235
227
  var DEFAULT_BASE_URL = "https://app.convosite.io/api";
236
228
  function createConvosite(config) {
237
229
  if (!config || typeof config.site !== "string" || !config.site.trim()) {
238
- throw new ConvositeError({ message: "A Convosite site ID is required.", code: "invalid_config" });
230
+ throw new ConvositeError({
231
+ message: "A Convosite site ID is required.",
232
+ code: "invalid_config"
233
+ });
239
234
  }
240
235
  const fetcher = config.fetch ?? globalThis.fetch?.bind(globalThis);
241
- if (!fetcher) throw new ConvositeError({ message: "No fetch implementation is available.", code: "invalid_config" });
236
+ if (!fetcher) {
237
+ throw new ConvositeError({
238
+ message: "No fetch implementation is available.",
239
+ code: "invalid_config"
240
+ });
241
+ }
242
242
  const siteId = config.site.trim();
243
+ const site = encodeSegment(siteId);
243
244
  const baseUrl = normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL);
244
245
  const conversationUrl = normalizeBaseUrl(config.conversationUrl ?? baseUrl);
245
- const http = new HttpClient(fetcher, baseUrl, config.headers ?? {}, config.timeout ?? 3e4);
246
+ const http = new HttpClient(
247
+ fetcher,
248
+ baseUrl,
249
+ config.headers ?? {},
250
+ config.timeout ?? 3e4
251
+ );
246
252
  const conversations = new ConversationsClient(fetcher, conversationUrl, siteId);
247
- const site = encodeSegment(siteId);
248
253
  const requestOptions = (options) => options?.signal ? { signal: options.signal } : {};
249
254
  return {
250
- site: {
251
- get: (options) => http.api(`/${site}`, requestOptions(options))
252
- },
253
- pages: {
254
- get: (path, options) => {
255
- if (typeof path !== "string") throw new ConvositeError({ message: "Page path must be a string.", code: "validation_error" });
256
- return http.api(`/content/${site}/pages${queryString({ path })}`, requestOptions(options));
257
- },
258
- find: (id, options) => http.api(`/content/${site}/pages/${encodeSegment(id)}`, requestOptions(options)),
259
- list: (options = {}) => {
260
- const { parentId, sort, direction, page, perPage, signal } = options;
261
- return http.api(`/content/${site}/pages${queryString({
262
- parent_id: parentId,
263
- sort,
264
- direction,
265
- page,
266
- per_page: perPage
267
- })}`, requestOptions(signal ? { signal } : void 0));
268
- }
269
- },
270
- menus: {
271
- get: (id, options) => http.api(`/content/${site}/menus/${encodeSegment(id)}`, requestOptions(options))
272
- },
273
- search: (query, options = {}) => {
274
- const { limit, signal } = options;
275
- return http.api(`/search/${site}${queryString({ query, limit })}`, requestOptions(signal ? { signal } : void 0));
276
- },
277
255
  actions: {
278
- run: (endpointId, input, options) => http.api(`/actions/${site}/${encodeSegment(endpointId)}`, {
279
- method: "POST",
280
- headers: { "Content-Type": "application/json", "Accept": "application/json" },
281
- body: JSON.stringify(input),
282
- ...requestOptions(options)
283
- })
256
+ run: (endpointId, input, options) => {
257
+ if (typeof endpointId !== "string" || !endpointId.trim()) {
258
+ throw new ConvositeError({
259
+ message: "An endpoint ID is required.",
260
+ code: "validation_error"
261
+ });
262
+ }
263
+ return http.api(
264
+ `/actions/${site}/${encodeSegment(endpointId.trim())}`,
265
+ {
266
+ method: "POST",
267
+ headers: {
268
+ "Content-Type": "application/json",
269
+ Accept: "application/json"
270
+ },
271
+ body: JSON.stringify(input),
272
+ ...requestOptions(options)
273
+ }
274
+ );
275
+ }
284
276
  },
285
277
  conversations: {
286
278
  create: (sessionId) => conversations.create(sessionId),
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/conversations.ts","../src/client.ts"],"sourcesContent":["export class ConvositeError extends Error {\n readonly status: number;\n readonly code: string | null;\n readonly details: unknown;\n readonly requestId: string | null;\n\n constructor(options: {\n message: string;\n status?: number;\n code?: string | null;\n details?: unknown;\n requestId?: string | null;\n cause?: unknown;\n }) {\n super(options.message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = 'ConvositeError';\n this.status = options.status ?? 0;\n this.code = options.code ?? null;\n this.details = options.details ?? null;\n this.requestId = options.requestId ?? null;\n }\n}\n","import { ConvositeError } from './errors';\nimport type { Fetch, RawRequestOptions } from './types';\n\ninterface ApiEnvelope<T> {\n success: boolean;\n message: string;\n data: T;\n errors: unknown;\n}\n\nexport function normalizeBaseUrl(value: string): string {\n return value.replace(/\\/+$/, '');\n}\n\nexport function joinUrl(base: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${normalizeBaseUrl(base)}/${path.replace(/^\\/+/, '')}`;\n}\n\nexport function encodeSegment(value: string): string {\n return encodeURIComponent(value);\n}\n\nexport function queryString(values: Record<string, string | number | null | undefined>): string {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(values)) {\n if (value !== undefined && value !== null) params.set(key, String(value));\n }\n const query = params.toString();\n return query ? `?${query}` : '';\n}\n\nfunction timeoutSignal(signal: AbortSignal | undefined, timeout: number): { signal?: AbortSignal; cleanup: () => void } {\n if (timeout <= 0) return signal ? { signal, cleanup: () => undefined } : { cleanup: () => undefined };\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(new DOMException('Request timed out.', 'TimeoutError')), timeout);\n const abort = () => controller.abort(signal?.reason);\n if (signal) {\n if (signal.aborted) abort();\n else signal.addEventListener('abort', abort, { once: true });\n }\n return {\n signal: controller.signal,\n cleanup: () => {\n clearTimeout(timer);\n signal?.removeEventListener('abort', abort);\n },\n };\n}\n\nasync function responseBody(response: Response): Promise<unknown> {\n const text = await response.text();\n if (!text) return null;\n try { return JSON.parse(text); } catch { return text; }\n}\n\nfunction errorFrom(response: Response, body: unknown): ConvositeError {\n const object = body && typeof body === 'object' ? body as Record<string, unknown> : {};\n const message = typeof object.message === 'string' ? object.message : `Convosite request failed with status ${response.status}.`;\n const code = typeof object.error === 'string' ? object.error : null;\n const details = object.errors ?? body;\n return new ConvositeError({\n message,\n status: response.status,\n code,\n details,\n requestId: response.headers.get('X-Request-ID'),\n });\n}\n\nexport class HttpClient {\n constructor(\n private readonly fetcher: Fetch,\n private readonly baseUrl: string,\n private readonly headers: HeadersInit,\n private readonly timeout: number,\n ) {}\n\n async api<T>(path: string, init: RequestInit = {}): Promise<T> {\n const response = await this.fetch(path, init, true);\n const body = await responseBody(response);\n if (!response.ok) throw errorFrom(response, body);\n if (!body || typeof body !== 'object' || !('success' in body)) {\n throw new ConvositeError({ message: 'Convosite returned an invalid API response.', status: response.status, details: body });\n }\n const envelope = body as ApiEnvelope<T>;\n if (envelope.success !== true) {\n throw new ConvositeError({ message: envelope.message || 'Convosite request failed.', status: response.status, details: envelope.errors });\n }\n return envelope.data;\n }\n\n async raw<T>(path: string, options: RawRequestOptions = {}): Promise<T> {\n const { parseAs = 'json', ...init } = options;\n const response = await this.fetch(path, init, true);\n if (!response.ok) throw errorFrom(response, await responseBody(response));\n if (parseAs === 'response') return response as T;\n if (parseAs === 'text') return await response.text() as T;\n if (response.status === 204) return undefined as T;\n return await response.json() as T;\n }\n\n async fetch(path: string, init: RequestInit = {}, useTimeout = false): Promise<Response> {\n const headers = new Headers(this.headers);\n new Headers(init.headers).forEach((value, key) => headers.set(key, value));\n const timed = useTimeout ? timeoutSignal(init.signal ?? undefined, this.timeout) : timeoutSignal(init.signal ?? undefined, 0);\n try {\n const requestInit: RequestInit = { ...init, headers };\n if (timed.signal) requestInit.signal = timed.signal;\n return await this.fetcher(joinUrl(this.baseUrl, path), requestInit);\n } catch (cause) {\n if (cause instanceof ConvositeError) throw cause;\n const aborted = timed.signal?.aborted;\n throw new ConvositeError({\n message: aborted ? 'Convosite request was aborted.' : 'Unable to connect to Convosite.',\n code: aborted ? 'request_aborted' : 'network_error',\n cause,\n });\n } finally {\n timed.cleanup();\n }\n }\n}\n\nexport async function workerError(response: Response): Promise<ConvositeError> {\n return errorFrom(response, await responseBody(response));\n}\n","import { ConvositeError } from './errors';\nimport { encodeSegment, joinUrl, workerError } from './http';\nimport type {\n Conversation,\n ConversationEndResponse,\n ConversationEvent,\n ConversationSendOptions,\n Fetch,\n RequestOptions,\n} from './types';\n\nasync function* parseNdjson(response: Response): AsyncGenerator<ConversationEvent> {\n if (!response.body) throw new ConvositeError({ message: 'Conversation response did not contain a stream.', status: response.status });\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (true) {\n const { value, done } = await reader.read();\n buffer += decoder.decode(value, { stream: !done });\n let newline: number;\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n if (line) yield parseEvent(line);\n }\n if (done) break;\n }\n const tail = buffer.trim();\n if (tail) yield parseEvent(tail);\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction parseEvent(line: string): ConversationEvent {\n try {\n const event = JSON.parse(line) as unknown;\n if (!event || typeof event !== 'object' || typeof (event as { type?: unknown }).type !== 'string') {\n throw new Error('Event has no type.');\n }\n return event as ConversationEvent;\n } catch (cause) {\n throw new ConvositeError({ message: 'Conversation stream contained an invalid event.', code: 'invalid_stream', details: line, cause });\n }\n}\n\nexport class ConversationsClient {\n constructor(\n private readonly fetcher: Fetch,\n private readonly baseUrl: string,\n private readonly siteId: string,\n ) {}\n\n create(sessionId?: string): Conversation {\n let currentSession = sessionId?.trim() || null;\n const client = this;\n return {\n get sessionId() { return currentSession; },\n async *send(query: string, options: RequestOptions = {}) {\n const stream = client.send(query, { ...options, ...(currentSession ? { sessionId: currentSession } : {}) }, (id) => { currentSession = id; });\n yield* stream;\n },\n async end(options: RequestOptions = {}) {\n if (!currentSession) return { ended: false };\n const result = await client.end(currentSession, options);\n if (result.ended) currentSession = null;\n return result;\n },\n reset() { currentSession = null; },\n };\n }\n\n async *send(\n query: string,\n options: ConversationSendOptions = {},\n onSession?: (sessionId: string) => void,\n ): AsyncGenerator<ConversationEvent> {\n const trimmed = query.trim();\n if (!trimmed) throw new ConvositeError({ message: 'Conversation query is required.', code: 'validation_error' });\n const headers = new Headers({ 'Content-Type': 'application/json', 'Accept': 'application/x-ndjson' });\n if (options.sessionId) headers.set('X-Conversation-Session', options.sessionId);\n let response: Response;\n try {\n const init: RequestInit = { method: 'POST', headers, body: JSON.stringify({ query: trimmed }) };\n if (options.signal) init.signal = options.signal;\n response = await this.fetcher(joinUrl(this.baseUrl, `/conversations/${encodeSegment(this.siteId)}`), init);\n } catch (cause) {\n throw new ConvositeError({ message: options.signal?.aborted ? 'Conversation request was aborted.' : 'Unable to connect to Convosite conversations.', code: options.signal?.aborted ? 'request_aborted' : 'network_error', cause });\n }\n if (!response.ok) throw await workerError(response);\n const session = response.headers.get('X-Conversation-Session');\n if (session) onSession?.(session);\n yield* parseNdjson(response);\n }\n\n async end(sessionId: string, options: RequestOptions = {}): Promise<ConversationEndResponse> {\n const headers = new Headers({ 'Accept': 'application/json', 'X-Conversation-Session': sessionId });\n let response: Response;\n try {\n const init: RequestInit = { method: 'POST', headers };\n if (options.signal) init.signal = options.signal;\n response = await this.fetcher(joinUrl(this.baseUrl, `/conversations/${encodeSegment(this.siteId)}/end`), init);\n } catch (cause) {\n throw new ConvositeError({ message: options.signal?.aborted ? 'Conversation request was aborted.' : 'Unable to connect to Convosite conversations.', code: options.signal?.aborted ? 'request_aborted' : 'network_error', cause });\n }\n if (!response.ok) throw await workerError(response);\n return await response.json() as ConversationEndResponse;\n }\n}\n","import { ConvositeError } from './errors';\nimport { ConversationsClient } from './conversations';\nimport { encodeSegment, HttpClient, normalizeBaseUrl, queryString } from './http';\nimport type {\n ActionResponse,\n ConvositeClient,\n ConvositeConfig,\n MenuResponse,\n PageListOptions,\n PageListResponse,\n PageResponse,\n RawRequestOptions,\n RequestOptions,\n SearchOptions,\n SearchResponse,\n Site,\n} from './types';\n\nconst DEFAULT_BASE_URL = 'https://app.convosite.io/api';\n\nexport function createConvosite(config: ConvositeConfig): ConvositeClient {\n if (!config || typeof config.site !== 'string' || !config.site.trim()) {\n throw new ConvositeError({ message: 'A Convosite site ID is required.', code: 'invalid_config' });\n }\n const fetcher = config.fetch ?? globalThis.fetch?.bind(globalThis);\n if (!fetcher) throw new ConvositeError({ message: 'No fetch implementation is available.', code: 'invalid_config' });\n const siteId = config.site.trim();\n const baseUrl = normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL);\n const conversationUrl = normalizeBaseUrl(config.conversationUrl ?? baseUrl);\n const http = new HttpClient(fetcher, baseUrl, config.headers ?? {}, config.timeout ?? 30_000);\n const conversations = new ConversationsClient(fetcher, conversationUrl, siteId);\n const site = encodeSegment(siteId);\n\n const requestOptions = (options?: RequestOptions): RequestInit => options?.signal ? { signal: options.signal } : {};\n\n return {\n site: {\n get: (options) => http.api<Site>(`/${site}`, requestOptions(options)),\n },\n pages: {\n get: (path, options) => {\n if (typeof path !== 'string') throw new ConvositeError({ message: 'Page path must be a string.', code: 'validation_error' });\n return http.api<PageResponse>(`/content/${site}/pages${queryString({ path })}`, requestOptions(options));\n },\n find: (id, options) => http.api<PageResponse>(`/content/${site}/pages/${encodeSegment(id)}`, requestOptions(options)),\n list: (options: PageListOptions = {}) => {\n const { parentId, sort, direction, page, perPage, signal } = options;\n return http.api<PageListResponse>(`/content/${site}/pages${queryString({\n parent_id: parentId,\n sort,\n direction,\n page,\n per_page: perPage,\n })}`, requestOptions(signal ? { signal } : undefined));\n },\n },\n menus: {\n get: (id, options) => http.api<MenuResponse>(`/content/${site}/menus/${encodeSegment(id)}`, requestOptions(options)),\n },\n search: (query: string, options: SearchOptions = {}) => {\n const { limit, signal } = options;\n return http.api<SearchResponse>(`/search/${site}${queryString({ query, limit })}`, requestOptions(signal ? { signal } : undefined));\n },\n actions: {\n run: (endpointId, input, options) => http.api<ActionResponse>(`/actions/${site}/${encodeSegment(endpointId)}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n body: JSON.stringify(input),\n ...requestOptions(options),\n }),\n },\n conversations: {\n create: (sessionId) => conversations.create(sessionId),\n send: (query, options) => conversations.send(query, options),\n end: (sessionId, options) => conversations.end(sessionId, options),\n },\n request: <T = unknown>(path: string, options: RawRequestOptions = {}) => http.raw<T>(path, options),\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/conversations.ts","../src/client.ts"],"sourcesContent":["export class ConvositeError extends Error {\n readonly status: number;\n readonly code: string | null;\n readonly details: unknown;\n readonly requestId: string | null;\n\n constructor(options: {\n message: string;\n status?: number;\n code?: string | null;\n details?: unknown;\n requestId?: string | null;\n cause?: unknown;\n }) {\n super(options.message, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = 'ConvositeError';\n this.status = options.status ?? 0;\n this.code = options.code ?? null;\n this.details = options.details ?? null;\n this.requestId = options.requestId ?? null;\n }\n}\n","import { ConvositeError } from './errors';\nimport type { Fetch, RawRequestOptions } from './types';\n\ninterface ApiEnvelope<T> {\n success: boolean;\n message: string;\n data: T;\n errors: unknown;\n}\n\nexport function normalizeBaseUrl(value: string): string {\n return value.replace(/\\/+$/, '');\n}\n\nexport function joinUrl(base: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${normalizeBaseUrl(base)}/${path.replace(/^\\/+/, '')}`;\n}\n\nexport function encodeSegment(value: string): string {\n return encodeURIComponent(value);\n}\n\nfunction timeoutSignal(signal: AbortSignal | undefined, timeout: number): { signal?: AbortSignal; cleanup: () => void } {\n if (timeout <= 0) return signal ? { signal, cleanup: () => undefined } : { cleanup: () => undefined };\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(new DOMException('Request timed out.', 'TimeoutError')), timeout);\n const abort = () => controller.abort(signal?.reason);\n if (signal) {\n if (signal.aborted) abort();\n else signal.addEventListener('abort', abort, { once: true });\n }\n return {\n signal: controller.signal,\n cleanup: () => {\n clearTimeout(timer);\n signal?.removeEventListener('abort', abort);\n },\n };\n}\n\nasync function responseBody(response: Response): Promise<unknown> {\n const text = await response.text();\n if (!text) return null;\n try { return JSON.parse(text); } catch { return text; }\n}\n\nfunction errorFrom(response: Response, body: unknown): ConvositeError {\n const object = body && typeof body === 'object' ? body as Record<string, unknown> : {};\n const message = typeof object.message === 'string' ? object.message : `Convosite request failed with status ${response.status}.`;\n const code = typeof object.error === 'string' ? object.error : null;\n const details = object.errors ?? body;\n return new ConvositeError({\n message,\n status: response.status,\n code,\n details,\n requestId: response.headers.get('X-Request-ID'),\n });\n}\n\nexport class HttpClient {\n constructor(\n private readonly fetcher: Fetch,\n private readonly baseUrl: string,\n private readonly headers: HeadersInit,\n private readonly timeout: number,\n ) {}\n\n async api<T>(path: string, init: RequestInit = {}): Promise<T> {\n const response = await this.fetch(path, init, true);\n const body = await responseBody(response);\n if (!response.ok) throw errorFrom(response, body);\n if (!body || typeof body !== 'object' || !('success' in body)) {\n throw new ConvositeError({ message: 'Convosite returned an invalid API response.', status: response.status, details: body });\n }\n const envelope = body as ApiEnvelope<T>;\n if (envelope.success !== true) {\n throw new ConvositeError({ message: envelope.message || 'Convosite request failed.', status: response.status, details: envelope.errors });\n }\n return envelope.data;\n }\n\n async raw<T>(path: string, options: RawRequestOptions = {}): Promise<T> {\n const { parseAs = 'json', ...init } = options;\n const response = await this.fetch(path, init, true);\n if (!response.ok) throw errorFrom(response, await responseBody(response));\n if (parseAs === 'response') return response as T;\n if (parseAs === 'text') return await response.text() as T;\n if (response.status === 204) return undefined as T;\n return await response.json() as T;\n }\n\n async fetch(path: string, init: RequestInit = {}, useTimeout = false): Promise<Response> {\n const headers = new Headers(this.headers);\n new Headers(init.headers).forEach((value, key) => headers.set(key, value));\n const timed = useTimeout ? timeoutSignal(init.signal ?? undefined, this.timeout) : timeoutSignal(init.signal ?? undefined, 0);\n try {\n const requestInit: RequestInit = { ...init, headers };\n if (timed.signal) requestInit.signal = timed.signal;\n return await this.fetcher(joinUrl(this.baseUrl, path), requestInit);\n } catch (cause) {\n if (cause instanceof ConvositeError) throw cause;\n const aborted = timed.signal?.aborted;\n throw new ConvositeError({\n message: aborted ? 'Convosite request was aborted.' : 'Unable to connect to Convosite.',\n code: aborted ? 'request_aborted' : 'network_error',\n cause,\n });\n } finally {\n timed.cleanup();\n }\n }\n}\n\nexport async function workerError(response: Response): Promise<ConvositeError> {\n return errorFrom(response, await responseBody(response));\n}\n","import { ConvositeError } from './errors';\nimport { encodeSegment, joinUrl, workerError } from './http';\nimport type {\n Conversation,\n ConversationEndResponse,\n ConversationEvent,\n ConversationSendOptions,\n Fetch,\n RequestOptions,\n} from './types';\n\nasync function* parseNdjson(response: Response): AsyncGenerator<ConversationEvent> {\n if (!response.body) throw new ConvositeError({ message: 'Conversation response did not contain a stream.', status: response.status });\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (true) {\n const { value, done } = await reader.read();\n buffer += decoder.decode(value, { stream: !done });\n let newline: number;\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n if (line) yield parseEvent(line);\n }\n if (done) break;\n }\n const tail = buffer.trim();\n if (tail) yield parseEvent(tail);\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction parseEvent(line: string): ConversationEvent {\n try {\n const event = JSON.parse(line) as unknown;\n if (!event || typeof event !== 'object' || typeof (event as { type?: unknown }).type !== 'string') {\n throw new Error('Event has no type.');\n }\n return event as ConversationEvent;\n } catch (cause) {\n throw new ConvositeError({ message: 'Conversation stream contained an invalid event.', code: 'invalid_stream', details: line, cause });\n }\n}\n\nexport class ConversationsClient {\n constructor(\n private readonly fetcher: Fetch,\n private readonly baseUrl: string,\n private readonly siteId: string,\n ) {}\n\n create(sessionId?: string): Conversation {\n let currentSession = sessionId?.trim() || null;\n const client = this;\n return {\n get sessionId() { return currentSession; },\n async *send(query: string, options: RequestOptions = {}) {\n const stream = client.send(query, { ...options, ...(currentSession ? { sessionId: currentSession } : {}) }, (id) => { currentSession = id; });\n yield* stream;\n },\n async end(options: RequestOptions = {}) {\n if (!currentSession) return { ended: false };\n const result = await client.end(currentSession, options);\n if (result.ended) currentSession = null;\n return result;\n },\n reset() { currentSession = null; },\n };\n }\n\n async *send(\n query: string,\n options: ConversationSendOptions = {},\n onSession?: (sessionId: string) => void,\n ): AsyncGenerator<ConversationEvent> {\n const trimmed = query.trim();\n if (!trimmed) throw new ConvositeError({ message: 'Conversation query is required.', code: 'validation_error' });\n const headers = new Headers({ 'Content-Type': 'application/json', 'Accept': 'application/x-ndjson' });\n if (options.sessionId) headers.set('X-Conversation-Session', options.sessionId);\n let response: Response;\n try {\n const init: RequestInit = { method: 'POST', headers, body: JSON.stringify({ query: trimmed }) };\n if (options.signal) init.signal = options.signal;\n response = await this.fetcher(joinUrl(this.baseUrl, `/conversations/${encodeSegment(this.siteId)}`), init);\n } catch (cause) {\n throw new ConvositeError({ message: options.signal?.aborted ? 'Conversation request was aborted.' : 'Unable to connect to Convosite conversations.', code: options.signal?.aborted ? 'request_aborted' : 'network_error', cause });\n }\n if (!response.ok) throw await workerError(response);\n const session = response.headers.get('X-Conversation-Session');\n if (session) onSession?.(session);\n yield* parseNdjson(response);\n }\n\n async end(sessionId: string, options: RequestOptions = {}): Promise<ConversationEndResponse> {\n const headers = new Headers({ 'Accept': 'application/json', 'X-Conversation-Session': sessionId });\n let response: Response;\n try {\n const init: RequestInit = { method: 'POST', headers };\n if (options.signal) init.signal = options.signal;\n response = await this.fetcher(joinUrl(this.baseUrl, `/conversations/${encodeSegment(this.siteId)}/end`), init);\n } catch (cause) {\n throw new ConvositeError({ message: options.signal?.aborted ? 'Conversation request was aborted.' : 'Unable to connect to Convosite conversations.', code: options.signal?.aborted ? 'request_aborted' : 'network_error', cause });\n }\n if (!response.ok) throw await workerError(response);\n return await response.json() as ConversationEndResponse;\n }\n}\n","import { ConversationsClient } from './conversations';\nimport { ConvositeError } from './errors';\nimport { encodeSegment, HttpClient, normalizeBaseUrl } from './http';\nimport type {\n ActionResponse,\n ConvositeClient,\n ConvositeConfig,\n RawRequestOptions,\n RequestOptions,\n} from './types';\n\nconst DEFAULT_BASE_URL = 'https://app.convosite.io/api';\n\nexport function createConvosite(config: ConvositeConfig): ConvositeClient {\n if (!config || typeof config.site !== 'string' || !config.site.trim()) {\n throw new ConvositeError({\n message: 'A Convosite site ID is required.',\n code: 'invalid_config',\n });\n }\n\n const fetcher = config.fetch ?? globalThis.fetch?.bind(globalThis);\n if (!fetcher) {\n throw new ConvositeError({\n message: 'No fetch implementation is available.',\n code: 'invalid_config',\n });\n }\n\n const siteId = config.site.trim();\n const site = encodeSegment(siteId);\n const baseUrl = normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL);\n const conversationUrl = normalizeBaseUrl(config.conversationUrl ?? baseUrl);\n const http = new HttpClient(\n fetcher,\n baseUrl,\n config.headers ?? {},\n config.timeout ?? 30_000,\n );\n const conversations = new ConversationsClient(fetcher, conversationUrl, siteId);\n\n const requestOptions = (options?: RequestOptions): RequestInit =>\n options?.signal ? { signal: options.signal } : {};\n\n return {\n actions: {\n run: (endpointId, input, options) => {\n if (typeof endpointId !== 'string' || !endpointId.trim()) {\n throw new ConvositeError({\n message: 'An endpoint ID is required.',\n code: 'validation_error',\n });\n }\n\n return http.api<ActionResponse>(\n `/actions/${site}/${encodeSegment(endpointId.trim())}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify(input),\n ...requestOptions(options),\n },\n );\n },\n },\n conversations: {\n create: (sessionId) => conversations.create(sessionId),\n send: (query, options) => conversations.send(query, options),\n end: (sessionId, options) => conversations.end(sessionId, options),\n },\n request: <T = unknown>(path: string, options: RawRequestOptions = {}) =>\n http.raw<T>(path, options),\n };\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "@convosite/client",
3
- "version": "0.1.0",
4
- "description": "Framework-agnostic JavaScript and TypeScript client for the Convosite runtime API.",
3
+ "version": "0.2.0",
4
+ "description": "Framework-agnostic JavaScript and TypeScript client for building Convosite conversational experiences.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "sideEffects": false,
8
- "files": ["dist", "README.md", "LICENSE"],
8
+ "files": [
9
+ "dist",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
9
13
  "main": "./dist/index.cjs",
10
14
  "module": "./dist/index.js",
11
15
  "types": "./dist/index.d.ts",
@@ -24,11 +28,19 @@
24
28
  "check": "npm run typecheck && npm test && npm run build",
25
29
  "prepublishOnly": "npm run check"
26
30
  },
27
- "engines": { "node": ">=18" },
31
+ "engines": {
32
+ "node": ">=18"
33
+ },
28
34
  "devDependencies": {
29
35
  "tsup": "^8.5.0",
30
36
  "typescript": "^5.9.3",
31
37
  "vitest": "^3.2.4"
32
38
  },
33
- "keywords": ["convosite", "cms", "headless-cms", "sdk", "typescript"]
39
+ "keywords": [
40
+ "convosite",
41
+ "conversational-ui",
42
+ "conversational-ai",
43
+ "sdk",
44
+ "typescript"
45
+ ]
34
46
  }