@waniwani/sdk 0.18.0 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat/embed.js +93 -93
- package/dist/chat/embed.js.map +1 -1
- package/dist/chat/express-js/index.d.ts +1 -23
- package/dist/chat/index.d.ts +101 -24
- package/dist/chat/index.js +7 -7
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/next-js/index.d.ts +1 -23
- package/dist/index.d.ts +2 -24
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy/chat/express-js/index.d.ts +1 -23
- package/dist/legacy/chat/next-js/index.d.ts +1 -23
- package/dist/legacy/index.d.ts +39 -23
- package/dist/legacy/index.js +13 -13
- package/dist/legacy/index.js.map +1 -1
- package/dist/mcp/index.d.ts +16 -23
- package/dist/mcp/index.js +5 -5
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/react/skybridge.d.ts +2 -24
- package/dist/mcp/react/skybridge.js +1 -1
- package/dist/mcp/react/skybridge.js.map +1 -1
- package/dist/mcp/react.d.ts +2 -24
- package/dist/mcp/react.js +4 -4
- package/dist/mcp/react.js.map +1 -1
- package/package.json +1 -1
|
@@ -68,7 +68,7 @@ interface KbClient {
|
|
|
68
68
|
* first-class names at runtime (the widget transport passes these through
|
|
69
69
|
* verbatim instead of namespacing them as custom widget events).
|
|
70
70
|
*/
|
|
71
|
-
declare const EVENT_TYPES: readonly ["session.started", "page.viewed", "tool.called", "
|
|
71
|
+
declare const EVENT_TYPES: readonly ["session.started", "page.viewed", "tool.called", "link.clicked", "widget_render", "user.identified", "price_shown", "prices_compared", "option_selected", "lead_qualified", "converted"];
|
|
72
72
|
type EventType = (typeof EVENT_TYPES)[number];
|
|
73
73
|
/**
|
|
74
74
|
* Properties for `page.viewed` — emitted once when the chat widget initializes
|
|
@@ -97,17 +97,9 @@ interface ToolCalledProperties {
|
|
|
97
97
|
/** Retrieval traces for kb.search() calls made inside this tool handler. */
|
|
98
98
|
kbSearch?: KbSearchTrace[];
|
|
99
99
|
}
|
|
100
|
-
interface QuoteSucceededProperties {
|
|
101
|
-
amount?: number;
|
|
102
|
-
currency?: string;
|
|
103
|
-
}
|
|
104
100
|
interface LinkClickedProperties {
|
|
105
101
|
url?: string;
|
|
106
102
|
}
|
|
107
|
-
interface PurchaseCompletedProperties {
|
|
108
|
-
amount?: number;
|
|
109
|
-
currency?: string;
|
|
110
|
-
}
|
|
111
103
|
interface PriceShownProperties {
|
|
112
104
|
amount: number;
|
|
113
105
|
currency: string;
|
|
@@ -194,19 +186,9 @@ type TrackEvent = ({
|
|
|
194
186
|
} & BaseTrackEvent) | ({
|
|
195
187
|
event: "tool.called";
|
|
196
188
|
properties?: ToolCalledProperties;
|
|
197
|
-
} & BaseTrackEvent) | ({
|
|
198
|
-
event: "quote.requested";
|
|
199
|
-
} & BaseTrackEvent) | ({
|
|
200
|
-
event: "quote.succeeded";
|
|
201
|
-
properties?: QuoteSucceededProperties;
|
|
202
|
-
} & BaseTrackEvent) | ({
|
|
203
|
-
event: "quote.failed";
|
|
204
189
|
} & BaseTrackEvent) | ({
|
|
205
190
|
event: "link.clicked";
|
|
206
191
|
properties?: LinkClickedProperties;
|
|
207
|
-
} & BaseTrackEvent) | ({
|
|
208
|
-
event: "purchase.completed";
|
|
209
|
-
properties?: PurchaseCompletedProperties;
|
|
210
192
|
} & BaseTrackEvent) | ({
|
|
211
193
|
event: "user.identified";
|
|
212
194
|
} & BaseTrackEvent) | ({
|
|
@@ -235,11 +217,7 @@ interface LegacyTrackEvent extends TrackingContext {
|
|
|
235
217
|
properties?: Record<string, unknown>;
|
|
236
218
|
toolName?: string;
|
|
237
219
|
toolType?: ToolCalledProperties["type"];
|
|
238
|
-
quoteAmount?: number;
|
|
239
|
-
quoteCurrency?: string;
|
|
240
220
|
linkUrl?: string;
|
|
241
|
-
purchaseAmount?: number;
|
|
242
|
-
purchaseCurrency?: string;
|
|
243
221
|
}
|
|
244
222
|
/**
|
|
245
223
|
* Public track input accepted by `client.track()`.
|
package/dist/index.d.ts
CHANGED
|
@@ -115,7 +115,7 @@ declare function defineConfig(config: WaniWaniProjectConfig): WaniWaniProjectCon
|
|
|
115
115
|
* first-class names at runtime (the widget transport passes these through
|
|
116
116
|
* verbatim instead of namespacing them as custom widget events).
|
|
117
117
|
*/
|
|
118
|
-
declare const EVENT_TYPES: readonly ["session.started", "page.viewed", "tool.called", "
|
|
118
|
+
declare const EVENT_TYPES: readonly ["session.started", "page.viewed", "tool.called", "link.clicked", "widget_render", "user.identified", "price_shown", "prices_compared", "option_selected", "lead_qualified", "converted"];
|
|
119
119
|
type EventType = (typeof EVENT_TYPES)[number];
|
|
120
120
|
/**
|
|
121
121
|
* Properties for `page.viewed` — emitted once when the chat widget initializes
|
|
@@ -144,17 +144,9 @@ interface ToolCalledProperties {
|
|
|
144
144
|
/** Retrieval traces for kb.search() calls made inside this tool handler. */
|
|
145
145
|
kbSearch?: KbSearchTrace[];
|
|
146
146
|
}
|
|
147
|
-
interface QuoteSucceededProperties {
|
|
148
|
-
amount?: number;
|
|
149
|
-
currency?: string;
|
|
150
|
-
}
|
|
151
147
|
interface LinkClickedProperties {
|
|
152
148
|
url?: string;
|
|
153
149
|
}
|
|
154
|
-
interface PurchaseCompletedProperties {
|
|
155
|
-
amount?: number;
|
|
156
|
-
currency?: string;
|
|
157
|
-
}
|
|
158
150
|
interface PriceShownProperties {
|
|
159
151
|
amount: number;
|
|
160
152
|
currency: string;
|
|
@@ -241,19 +233,9 @@ type TrackEvent = ({
|
|
|
241
233
|
} & BaseTrackEvent) | ({
|
|
242
234
|
event: "tool.called";
|
|
243
235
|
properties?: ToolCalledProperties;
|
|
244
|
-
} & BaseTrackEvent) | ({
|
|
245
|
-
event: "quote.requested";
|
|
246
|
-
} & BaseTrackEvent) | ({
|
|
247
|
-
event: "quote.succeeded";
|
|
248
|
-
properties?: QuoteSucceededProperties;
|
|
249
|
-
} & BaseTrackEvent) | ({
|
|
250
|
-
event: "quote.failed";
|
|
251
236
|
} & BaseTrackEvent) | ({
|
|
252
237
|
event: "link.clicked";
|
|
253
238
|
properties?: LinkClickedProperties;
|
|
254
|
-
} & BaseTrackEvent) | ({
|
|
255
|
-
event: "purchase.completed";
|
|
256
|
-
properties?: PurchaseCompletedProperties;
|
|
257
239
|
} & BaseTrackEvent) | ({
|
|
258
240
|
event: "user.identified";
|
|
259
241
|
} & BaseTrackEvent) | ({
|
|
@@ -282,11 +264,7 @@ interface LegacyTrackEvent extends TrackingContext {
|
|
|
282
264
|
properties?: Record<string, unknown>;
|
|
283
265
|
toolName?: string;
|
|
284
266
|
toolType?: ToolCalledProperties["type"];
|
|
285
|
-
quoteAmount?: number;
|
|
286
|
-
quoteCurrency?: string;
|
|
287
267
|
linkUrl?: string;
|
|
288
|
-
purchaseAmount?: number;
|
|
289
|
-
purchaseCurrency?: string;
|
|
290
268
|
}
|
|
291
269
|
/**
|
|
292
270
|
* Public track input accepted by `client.track()`.
|
|
@@ -569,4 +547,4 @@ interface V2BatchResponse {
|
|
|
569
547
|
*/
|
|
570
548
|
declare function waniwani(config?: WaniWaniConfig | WaniWaniProjectConfig): WaniWaniClient;
|
|
571
549
|
|
|
572
|
-
export { type ComparedPriceOption, type ConvertedProperties, EVENT_TYPES, type EventType, type FrontendClientOptions, type FrontendIdentity, type FrontendTrackingClient, type KbClient, type KbIngestFile, type KbIngestResult, type KbSearchOptions, type KbSource, type LeadQualifiedProperties, type LegacyTrackEvent, type LinkClickedProperties, type OptionSelectedProperties, type PriceShownProperties, type PricesComparedProperties, type
|
|
550
|
+
export { type ComparedPriceOption, type ConvertedProperties, EVENT_TYPES, type EventType, type FrontendClientOptions, type FrontendIdentity, type FrontendTrackingClient, type KbClient, type KbIngestFile, type KbIngestResult, type KbSearchOptions, type KbSource, type LeadQualifiedProperties, type LegacyTrackEvent, type LinkClickedProperties, type OptionSelectedProperties, type PriceShownProperties, type PricesComparedProperties, type RevenueConvertedInput, type RevenueLeadQualifiedInput, type RevenueOptionSelectedInput, type RevenuePriceShownInput, type RevenuePricesComparedInput, type RevenueTrackingApi, type ToolCalledProperties, type TrackEvent, type TrackFn, type TrackInput, type TrackingConfig, type TrackingShutdownOptions, type TrackingShutdownResult, type V2BatchRejectedEvent, type V2BatchRequest, type V2BatchResponse, type V2CorrelationIds, type V2EnvelopeType, type V2EventEnvelope, type WaniWaniClient, type WaniWaniConfig, WaniWaniError, type WaniWaniProjectConfig, createFrontendClient, defineConfig, waniwani };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var T=class extends Error{constructor(n,r){super(n);this.status=r;this.name="WaniWaniError"}};import{existsSync as Y,readFileSync as z}from"fs";import{resolve as $}from"path";var H="waniwani.json",m;function P(){if(m!==void 0)return m;try{let e=$(process.cwd(),H);if(!Y(e))return m=null,null;let t=z(e,"utf-8");return m=JSON.parse(t),m}catch{return m=null,null}}var b="__waniwani_config__";function Q(e){return globalThis[b]=e,e}function C(){return globalThis[b]}var _=["session.started","page.viewed","tool.called","quote.requested","quote.succeeded","quote.failed","link.clicked","purchase.completed","widget_render","user.identified","price_shown","prices_compared","option_selected","lead_qualified","converted"];function v(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.length>0)return r}}var X=["waniwani/sessionId","openai/sessionId","openai/session","sessionId","conversationId","mcp-session-id"],G=["waniwani/requestId","openai/requestId","requestId","mcp/requestId"],J=["waniwani/traceId","openai/traceId","traceId","mcp/traceId","openai/requestId","requestId"],Z=["waniwani/userId","openai/userId","externalUserId","userId","actorId"],ee=["waniwani/visitorId","visitorId"],te=["correlationId","openai/requestId"];function M(e){return e?v(e,X):void 0}function A(e){return e?v(e,G):void 0}function B(e){return e?v(e,J):void 0}function F(e){return e?v(e,Z):void 0}function O(e){return e?v(e,ee):void 0}function D(e){return e?v(e,te):void 0}var ne=[{key:"openai/sessionId",source:"chatgpt"},{key:"openai/session",source:"chatgpt"}],re=[{needle:"claude",source:"claude"},{needle:"chatgpt",source:"chatgpt"},{needle:"openai",source:"chatgpt"},{needle:"gemini",source:"gemini"}];function L(e,t){if(e){let r=e["waniwani/source"];if(typeof r=="string"&&r.length>0)return r;for(let{key:i,source:s}of ne){let a=e[i];if(typeof a=="string"&&a.length>0)return s}}let n=t?.name;if(typeof n=="string"&&n.length>0){let r=n.toLowerCase();for(let{needle:i,source:s}of re)if(r.includes(i))return s}}var ie="@waniwani/sdk";function y(e,t={}){let n=t.now??(()=>new Date),r=t.generateId??U,i=ae(e),s=I(e.meta),a=I(e.metadata),o=ce(e,s),c=p(e.eventId)??r(),g=ue(e.timestamp,n),d=p(e.source)??L(s)??t.source??ie,u=x(e)?{...e}:void 0,h={...a};return Object.keys(s).length>0&&(h.meta=s),u&&(h.rawLegacy=u),{id:c,type:"mcp.event",name:i,source:d,timestamp:g,correlation:o,properties:se(e,i),metadata:h,rawLegacy:u}}function U(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?`evt_${crypto.randomUUID()}`:`evt_${Math.random().toString(36).slice(2,10)}_${Date.now().toString(36)}`}function se(e,t){if(!x(e))return I(e.properties);let n=oe(e,t),r=I(e.properties);return{...n,...r}}function oe(e,t){switch(t){case"tool.called":{let n={};return p(e.toolName)&&(n.name=e.toolName),p(e.toolType)&&(n.type=e.toolType),n}case"quote.succeeded":{let n={};return typeof e.quoteAmount=="number"&&(n.amount=e.quoteAmount),p(e.quoteCurrency)&&(n.currency=e.quoteCurrency),n}case"link.clicked":{let n={};return p(e.linkUrl)&&(n.url=e.linkUrl),n}case"purchase.completed":{let n={};return typeof e.purchaseAmount=="number"&&(n.amount=e.purchaseAmount),p(e.purchaseCurrency)&&(n.currency=e.purchaseCurrency),n}default:return{}}}function ae(e){return x(e)?e.eventType:e.event}function ce(e,t){let n=p(e.requestId)??A(t),r=p(e.sessionId)??M(t),i=p(e.traceId)??B(t),s=p(e.externalUserId)??F(t),a=p(e.visitorId)??O(t),o=p(e.correlationId)??D(t)??n,c={};return r&&(c.sessionId=r),i&&(c.traceId=i),n&&(c.requestId=n),o&&(c.correlationId=o),s&&(c.externalUserId=s),a&&(c.visitorId=a),c}function ue(e,t){if(e instanceof Date)return e.toISOString();if(typeof e=="string"){let n=new Date(e);if(!Number.isNaN(n.getTime()))return n.toISOString()}return t().toISOString()}function I(e){return!e||typeof e!="object"||Array.isArray(e)?{}:e}function p(e){if(typeof e=="string"&&e.trim().length!==0)return e}function x(e){return"eventType"in e}function k(e){return{priceShown:({amount:t,currency:n,itemId:r,label:i,...s})=>e({event:"price_shown",properties:{amount:t,currency:n,itemId:r,label:i},...s}),pricesCompared:({options:t,...n})=>e({event:"prices_compared",properties:{options:t},...n}),optionSelected:({id:t,amount:n,currency:r,...i})=>e({event:"option_selected",properties:{id:t,amount:n,currency:r},...i}),leadQualified:t=>{let{externalId:n,email:r,name:i,...s}=t??{};return e({event:"lead_qualified",properties:{externalId:n,email:r,name:i},...s})},converted:({amount:t,currency:n,occurredAt:r,...i})=>e({event:"converted",properties:{amount:t,currency:n,occurredAt:r},...i})}}var de="/api/mcp/events/v2/batch";var W="@waniwani/sdk";var pe=new Set([401,403]),le=new Set([408,425,429,500,502,503,504]);function w(e){return new R(e)}var R=class{endpointUrl;flushIntervalMs;maxBatchSize;maxBufferSize;maxRetries;retryBaseDelayMs;retryMaxDelayMs;shutdownTimeoutMs;sdkVersion;fetchFn;logger;now;sleep;apiKey;buffer=[];flushTimer;flushScheduled=!1;flushScheduledTimer;flushInFlight;inFlightCount=0;isStopped=!1;isShuttingDown=!1;constructor(t){this.endpointUrl=ge(t.apiUrl,t.endpointPath??de),this.flushIntervalMs=t.flushIntervalMs??1e3,this.maxBatchSize=t.maxBatchSize??20,this.maxBufferSize=t.maxBufferSize??1e3,this.maxRetries=t.maxRetries??3,this.retryBaseDelayMs=t.retryBaseDelayMs??200,this.retryMaxDelayMs=t.retryMaxDelayMs??2e3,this.shutdownTimeoutMs=t.shutdownTimeoutMs??2e3,this.fetchFn=t.fetchFn??fetch,this.logger=t.logger??console,this.now=t.now??(()=>new Date),this.sleep=t.sleep??(n=>new Promise(r=>setTimeout(r,n))),this.apiKey=t.apiKey,this.sdkVersion=t.sdkVersion,this.flushIntervalMs>0&&(this.flushTimer=setInterval(()=>{this.flush()},this.flushIntervalMs)),this.registerBrowserTeardown()}enqueue(t){if(this.isStopped||this.isShuttingDown){this.logger.warn("[Waniwani] Tracking transport is stopped, dropping event %s",t.id);return}if(this.buffer.length>=this.maxBufferSize){let n=this.buffer.length-this.maxBufferSize+1;this.buffer.splice(0,n),this.logger.warn("[Waniwani] Tracking buffer overflow, dropped %d oldest event(s)",n)}if(this.buffer.push(t),this.buffer.length>=this.maxBatchSize){this.flush();return}this.scheduleMicroFlush()}pendingEvents(){return this.buffer.length+this.inFlightCount}async flush(){return this.flushInFlight?this.flushInFlight:(this.flushInFlight=this.flushLoop().finally(()=>{this.flushInFlight=void 0}),this.flushInFlight)}async shutdown(t){this.isShuttingDown=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=void 0),this.flushScheduledTimer&&(clearTimeout(this.flushScheduledTimer),this.flushScheduledTimer=void 0,this.flushScheduled=!1);let n=t?.timeoutMs??this.shutdownTimeoutMs,r=this.flush();if(!Number.isFinite(n)||n<=0)return await r,this.isStopped=!0,{timedOut:!1,pendingEvents:this.pendingEvents()};let i=Symbol("shutdown-timeout");return await Promise.race([r.then(()=>"flushed"),this.sleep(n).then(()=>i)])===i?(this.isStopped=!0,{timedOut:!0,pendingEvents:this.pendingEvents()}):(this.isStopped=!0,{timedOut:!1,pendingEvents:this.pendingEvents()})}registerBrowserTeardown(){if(typeof document>"u"||typeof window>"u")return;let t=()=>{document.visibilityState==="hidden"&&this.keepaliveFlush()};document.addEventListener("visibilitychange",t),window.addEventListener("pagehide",()=>this.keepaliveFlush())}keepaliveFlush(){if(this.isStopped||this.buffer.length===0)return;let t=this.buffer.splice(0,this.buffer.length);this.sendKeepaliveChunk(t)}sendKeepaliveChunk(t){let n=JSON.stringify(this.makeBatchRequest(t));if(n.length>6e4&&t.length>1){let r=Math.ceil(t.length/2);this.sendKeepaliveChunk(t.slice(0,r)),this.sendKeepaliveChunk(t.slice(r));return}try{this.fetchFn(this.endpointUrl,{method:"POST",headers:this.requestHeaders(),body:n,keepalive:!0}).catch(()=>{})}catch{}}requestHeaders(){let t={"Content-Type":"application/json","X-WaniWani-SDK":W};return this.apiKey&&(t.Authorization=`Bearer ${this.apiKey}`),t}scheduleMicroFlush(){this.flushScheduled||(this.flushScheduled=!0,this.flushScheduledTimer=setTimeout(()=>{this.flushScheduledTimer=void 0,this.flushScheduled=!1,this.flush()},0))}async flushLoop(){for(;this.buffer.length>0&&!this.isStopped;){let t=this.buffer.splice(0,this.maxBatchSize);await this.sendBatchWithRetry(t)}}async sendBatchWithRetry(t){let n=0,r=t;for(;r.length>0&&!this.isStopped;){this.inFlightCount=r.length;let i=await this.sendBatchOnce(r);switch(this.inFlightCount=0,i.kind){case"success":return;case"auth":this.stopTransportForAuthFailure(i.status,r.length);return;case"permanent":this.logger.error("[Waniwani] Dropping %d event(s) after permanent failure: %s",r.length,i.reason);return;case"retryable":if(n>=this.maxRetries){this.logger.error("[Waniwani] Dropping %d event(s) after retry exhaustion: %s",r.length,i.reason);return}await this.sleep(this.backoffDelayMs(n)),n+=1;continue;case"partial":if(i.permanent.length>0&&this.logger.error("[Waniwani] Dropping %d event(s) rejected as permanent",i.permanent.length),i.retryable.length===0)return;if(n>=this.maxRetries){this.logger.error("[Waniwani] Dropping %d retryable event(s) after retry exhaustion",i.retryable.length);return}r=i.retryable,await this.sleep(this.backoffDelayMs(n)),n+=1;continue}}}async sendBatchOnce(t){let n;try{n=await this.fetchFn(this.endpointUrl,{method:"POST",headers:this.requestHeaders(),body:JSON.stringify(this.makeBatchRequest(t))})}catch(s){return{kind:"retryable",reason:me(s)}}if(pe.has(n.status))return{kind:"auth",status:n.status};if(le.has(n.status))return{kind:"retryable",reason:`HTTP ${n.status}`};if(!n.ok)return{kind:"permanent",reason:`HTTP ${n.status}`};let r=await he(n);if(!r?.rejected||r.rejected.length===0)return{kind:"success"};let i=this.classifyRejectedEvents(t,r.rejected);return i.retryable.length===0&&i.permanent.length===0?{kind:"success"}:{kind:"partial",retryable:i.retryable,permanent:i.permanent}}makeBatchRequest(t){return{sentAt:this.now().toISOString(),source:{sdk:W,version:this.sdkVersion??"0.0.0"},events:t}}classifyRejectedEvents(t,n){let r=new Map(t.map(a=>[a.id,a])),i=[],s=[];for(let a of n){let o=r.get(a.eventId);if(o){if(fe(a)){i.push(o);continue}s.push(o)}}return{retryable:i,permanent:s}}backoffDelayMs(t){let n=this.retryBaseDelayMs*2**t;return Math.min(n,this.retryMaxDelayMs)}stopTransportForAuthFailure(t,n){this.isStopped=!0;let r=this.buffer.length;this.buffer.splice(0,r),this.logger.error("[Waniwani] Auth failure (HTTP %d). Stopping tracking transport and dropping %d queued event(s)",t,n+r)}};function fe(e){if(e.retryable===!0)return!0;let t=e.code.toLowerCase();return t.includes("timeout")||t.includes("temporary")||t.includes("unavailable")||t.includes("rate_limit")||t.includes("transient")||t.includes("server")}async function he(e){let t=await e.text();if(t)try{return JSON.parse(t)}catch{return}}function ge(e,t){let n=e.endsWith("/")?e:`${e}/`,r=t.startsWith("/")?t.slice(1):t;return`${n}${r}`}function me(e){return e instanceof Error?e.message:String(e)}function ve(e){let{apiUrl:t,endpointPath:n}=ye(e.endpoint),r=w({apiUrl:t,apiKey:e.token,endpointPath:n,flushIntervalMs:e.flushIntervalMs}),i,s=o=>typeof o=="function"?o():o,a=async o=>{let c=e.identity?.()??{},g=s(e.channelId),d=g===void 0?o.properties:{channelId:g,...o.properties},u=y({sessionId:c.sessionId,visitorId:c.visitorId,externalUserId:c.externalUserId??i,traceId:c.traceId,...o,properties:d,metadata:{...e.metadata,...o.metadata}},{source:s(e.source)});return r.enqueue(u),{eventId:u.id}};return{track:Object.assign(a,k(a)),identify(o,c){return i=o,a({event:"user.identified",externalUserId:o,properties:c})},flush:()=>r.flush(),shutdown:o=>r.shutdown(o)}}function ye(e){let t=new URL(e);return{apiUrl:t.origin,endpointPath:`${t.pathname}${t.search}`}}import{AsyncLocalStorage as Te}from"async_hooks";var V=globalThis,E=V.__waniwaniKbRetrievalStore;E||(E=new Te,V.__waniwaniKbRetrievalStore=E);var Ie=E;function K(e){try{Ie.getStore()?.searches.push(e)}catch{}}var ke="@waniwani/sdk";function j(e){let{apiUrl:t,apiKey:n}=e;function r(){if(!n)throw new Error("WANIWANI_API_KEY is not set");return n}async function i(s,a,o){let c=r(),g=`${t.replace(/\/$/,"")}${a}`,d={Authorization:`Bearer ${c}`,"X-WaniWani-SDK":ke},u={method:s,headers:d};o!==void 0&&(d["Content-Type"]="application/json",u.body=JSON.stringify(o));let h=await fetch(g,u);if(!h.ok){let N=await h.text().catch(()=>"");throw new T(N||`KB API error: HTTP ${h.status}`,h.status)}return(await h.json()).data}return{async ingest(s){return i("POST","/api/mcp/kb/ingest",{files:s})},async search(s,a){let o=await i("POST","/api/mcp/kb/search",{query:s,...a});return K({query:s,resultCount:o.length,results:o.map(c=>({source:c.source,heading:c.heading,score:c.score}))}),o},async sources(){return i("GET","/api/mcp/kb/sources")}}}function q(e){let{apiUrl:t,apiKey:n,tracking:r}=e;function i(){if(!n)throw new Error("WANIWANI_API_KEY is not set");return n}let s=n?w({apiUrl:t,apiKey:n,endpointPath:r.endpointPath,flushIntervalMs:r.flushIntervalMs,maxBatchSize:r.maxBatchSize,maxBufferSize:r.maxBufferSize,maxRetries:r.maxRetries,retryBaseDelayMs:r.retryBaseDelayMs,retryMaxDelayMs:r.retryMaxDelayMs,shutdownTimeoutMs:r.shutdownTimeoutMs}):void 0;function a(d){i();let u=y(d);return!u.correlation.sessionId&&!u.correlation.externalUserId&&!u.correlation.visitorId&&console.warn(`[waniwani] event "${u.name}" has no sessionId, externalUserId, or visitorId; the ingest API requires one and will reject it.`),s?.enqueue(u),{eventId:u.id}}let o=async d=>a(d),c=Object.assign(o,k(o)),g={async identify(d,u,h){i();let S=y({event:"user.identified",externalUserId:d,properties:u,meta:h});return s?.enqueue(S),{eventId:S.id}},track:c,async flush(){i(),await s?.flush()},async shutdown(d){return i(),await s?.shutdown({timeoutMs:d?.timeoutMs??r.shutdownTimeoutMs})??{timedOut:!1,pendingEvents:0}}};return s&&we(g,r.shutdownTimeoutMs),g}function we(e,t){if(typeof process>"u"||typeof process.once!="function"||typeof process.on!="function")return;let n=()=>{e.shutdown({timeoutMs:t})};process.once("beforeExit",n),process.once("SIGINT",n),process.once("SIGTERM",n)}function Ee(e){let n=e??P()??C(),r=n?.apiUrl??process.env.WANIWANI_API_URL??"https://app.waniwani.ai",i=n?.apiKey??process.env.WANIWANI_API_KEY,s={endpointPath:n?.tracking?.endpointPath??"/api/mcp/events/v2/batch",flushIntervalMs:n?.tracking?.flushIntervalMs??1e3,maxBatchSize:n?.tracking?.maxBatchSize??20,maxBufferSize:n?.tracking?.maxBufferSize??1e3,maxRetries:n?.tracking?.maxRetries??3,retryBaseDelayMs:n?.tracking?.retryBaseDelayMs??200,retryMaxDelayMs:n?.tracking?.retryMaxDelayMs??2e3,shutdownTimeoutMs:n?.tracking?.shutdownTimeoutMs??2e3},a={apiUrl:r,apiKey:i,tracking:s},o=q(a),c=j(a);return{...o,kb:c,_config:a}}export{_ as EVENT_TYPES,T as WaniWaniError,ve as createFrontendClient,Q as defineConfig,Ee as waniwani};
|
|
1
|
+
var y=class extends Error{constructor(n,r){super(n);this.status=r;this.name="WaniWaniError"}};import{existsSync as Y,readFileSync as z}from"fs";import{resolve as $}from"path";var H="waniwani.json",m;function b(){if(m!==void 0)return m;try{let e=$(process.cwd(),H);if(!Y(e))return m=null,null;let t=z(e,"utf-8");return m=JSON.parse(t),m}catch{return m=null,null}}var C="__waniwani_config__";function X(e){return globalThis[C]=e,e}function P(){return globalThis[C]}var _=["session.started","page.viewed","tool.called","link.clicked","widget_render","user.identified","price_shown","prices_compared","option_selected","lead_qualified","converted"];function v(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.length>0)return r}}var Q=["waniwani/sessionId","openai/sessionId","openai/session","sessionId","conversationId","mcp-session-id"],G=["waniwani/requestId","openai/requestId","requestId","mcp/requestId"],J=["waniwani/traceId","openai/traceId","traceId","mcp/traceId","openai/requestId","requestId"],Z=["waniwani/userId","openai/userId","externalUserId","userId","actorId"],ee=["waniwani/visitorId","visitorId"],te=["correlationId","openai/requestId"];function M(e){return e?v(e,Q):void 0}function A(e){return e?v(e,G):void 0}function B(e){return e?v(e,J):void 0}function F(e){return e?v(e,Z):void 0}function O(e){return e?v(e,ee):void 0}function D(e){return e?v(e,te):void 0}var ne=[{key:"openai/sessionId",source:"chatgpt"},{key:"openai/session",source:"chatgpt"}],re=[{needle:"claude",source:"claude"},{needle:"chatgpt",source:"chatgpt"},{needle:"openai",source:"chatgpt"},{needle:"gemini",source:"gemini"}];function L(e,t){if(e){let r=e["waniwani/source"];if(typeof r=="string"&&r.length>0)return r;for(let{key:i,source:s}of ne){let a=e[i];if(typeof a=="string"&&a.length>0)return s}}let n=t?.name;if(typeof n=="string"&&n.length>0){let r=n.toLowerCase();for(let{needle:i,source:s}of re)if(r.includes(i))return s}}var ie="@waniwani/sdk";function T(e,t={}){let n=t.now??(()=>new Date),r=t.generateId??U,i=ae(e),s=I(e.meta),a=I(e.metadata),o=ce(e,s),c=h(e.eventId)??r(),g=de(e.timestamp,n),u=h(e.source)??L(s)??t.source??ie,d=x(e)?{...e}:void 0,f={...a};return Object.keys(s).length>0&&(f.meta=s),d&&(f.rawLegacy=d),{id:c,type:"mcp.event",name:i,source:u,timestamp:g,correlation:o,properties:se(e,i),metadata:f,rawLegacy:d}}function U(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?`evt_${crypto.randomUUID()}`:`evt_${Math.random().toString(36).slice(2,10)}_${Date.now().toString(36)}`}function se(e,t){if(!x(e))return I(e.properties);let n=oe(e,t),r=I(e.properties);return{...n,...r}}function oe(e,t){switch(t){case"tool.called":{let n={};return h(e.toolName)&&(n.name=e.toolName),h(e.toolType)&&(n.type=e.toolType),n}case"link.clicked":{let n={};return h(e.linkUrl)&&(n.url=e.linkUrl),n}default:return{}}}function ae(e){return x(e)?e.eventType:e.event}function ce(e,t){let n=h(e.requestId)??A(t),r=h(e.sessionId)??M(t),i=h(e.traceId)??B(t),s=h(e.externalUserId)??F(t),a=h(e.visitorId)??O(t),o=h(e.correlationId)??D(t)??n,c={};return r&&(c.sessionId=r),i&&(c.traceId=i),n&&(c.requestId=n),o&&(c.correlationId=o),s&&(c.externalUserId=s),a&&(c.visitorId=a),c}function de(e,t){if(e instanceof Date)return e.toISOString();if(typeof e=="string"){let n=new Date(e);if(!Number.isNaN(n.getTime()))return n.toISOString()}return t().toISOString()}function I(e){return!e||typeof e!="object"||Array.isArray(e)?{}:e}function h(e){if(typeof e=="string"&&e.trim().length!==0)return e}function x(e){return"eventType"in e}function k(e){return{priceShown:({amount:t,currency:n,itemId:r,label:i,...s})=>e({event:"price_shown",properties:{amount:t,currency:n,itemId:r,label:i},...s}),pricesCompared:({options:t,...n})=>e({event:"prices_compared",properties:{options:t},...n}),optionSelected:({id:t,amount:n,currency:r,...i})=>e({event:"option_selected",properties:{id:t,amount:n,currency:r},...i}),leadQualified:t=>{let{externalId:n,email:r,name:i,...s}=t??{};return e({event:"lead_qualified",properties:{externalId:n,email:r,name:i},...s})},converted:({amount:t,currency:n,occurredAt:r,...i})=>e({event:"converted",properties:{amount:t,currency:n,occurredAt:r},...i})}}var ue="/api/mcp/events/v2/batch";var W="@waniwani/sdk";var pe=new Set([401,403]),le=new Set([408,425,429,500,502,503,504]);function w(e){return new R(e)}var R=class{endpointUrl;flushIntervalMs;maxBatchSize;maxBufferSize;maxRetries;retryBaseDelayMs;retryMaxDelayMs;shutdownTimeoutMs;sdkVersion;fetchFn;logger;now;sleep;apiKey;buffer=[];flushTimer;flushScheduled=!1;flushScheduledTimer;flushInFlight;inFlightCount=0;isStopped=!1;isShuttingDown=!1;constructor(t){this.endpointUrl=ge(t.apiUrl,t.endpointPath??ue),this.flushIntervalMs=t.flushIntervalMs??1e3,this.maxBatchSize=t.maxBatchSize??20,this.maxBufferSize=t.maxBufferSize??1e3,this.maxRetries=t.maxRetries??3,this.retryBaseDelayMs=t.retryBaseDelayMs??200,this.retryMaxDelayMs=t.retryMaxDelayMs??2e3,this.shutdownTimeoutMs=t.shutdownTimeoutMs??2e3,this.fetchFn=t.fetchFn??fetch,this.logger=t.logger??console,this.now=t.now??(()=>new Date),this.sleep=t.sleep??(n=>new Promise(r=>setTimeout(r,n))),this.apiKey=t.apiKey,this.sdkVersion=t.sdkVersion,this.flushIntervalMs>0&&(this.flushTimer=setInterval(()=>{this.flush()},this.flushIntervalMs)),this.registerBrowserTeardown()}enqueue(t){if(this.isStopped||this.isShuttingDown){this.logger.warn("[Waniwani] Tracking transport is stopped, dropping event %s",t.id);return}if(this.buffer.length>=this.maxBufferSize){let n=this.buffer.length-this.maxBufferSize+1;this.buffer.splice(0,n),this.logger.warn("[Waniwani] Tracking buffer overflow, dropped %d oldest event(s)",n)}if(this.buffer.push(t),this.buffer.length>=this.maxBatchSize){this.flush();return}this.scheduleMicroFlush()}pendingEvents(){return this.buffer.length+this.inFlightCount}async flush(){return this.flushInFlight?this.flushInFlight:(this.flushInFlight=this.flushLoop().finally(()=>{this.flushInFlight=void 0}),this.flushInFlight)}async shutdown(t){this.isShuttingDown=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=void 0),this.flushScheduledTimer&&(clearTimeout(this.flushScheduledTimer),this.flushScheduledTimer=void 0,this.flushScheduled=!1);let n=t?.timeoutMs??this.shutdownTimeoutMs,r=this.flush();if(!Number.isFinite(n)||n<=0)return await r,this.isStopped=!0,{timedOut:!1,pendingEvents:this.pendingEvents()};let i=Symbol("shutdown-timeout");return await Promise.race([r.then(()=>"flushed"),this.sleep(n).then(()=>i)])===i?(this.isStopped=!0,{timedOut:!0,pendingEvents:this.pendingEvents()}):(this.isStopped=!0,{timedOut:!1,pendingEvents:this.pendingEvents()})}registerBrowserTeardown(){if(typeof document>"u"||typeof window>"u")return;let t=()=>{document.visibilityState==="hidden"&&this.keepaliveFlush()};document.addEventListener("visibilitychange",t),window.addEventListener("pagehide",()=>this.keepaliveFlush())}keepaliveFlush(){if(this.isStopped||this.buffer.length===0)return;let t=this.buffer.splice(0,this.buffer.length);this.sendKeepaliveChunk(t)}sendKeepaliveChunk(t){let n=JSON.stringify(this.makeBatchRequest(t));if(n.length>6e4&&t.length>1){let r=Math.ceil(t.length/2);this.sendKeepaliveChunk(t.slice(0,r)),this.sendKeepaliveChunk(t.slice(r));return}try{this.fetchFn(this.endpointUrl,{method:"POST",headers:this.requestHeaders(),body:n,keepalive:!0}).catch(()=>{})}catch{}}requestHeaders(){let t={"Content-Type":"application/json","X-WaniWani-SDK":W};return this.apiKey&&(t.Authorization=`Bearer ${this.apiKey}`),t}scheduleMicroFlush(){this.flushScheduled||(this.flushScheduled=!0,this.flushScheduledTimer=setTimeout(()=>{this.flushScheduledTimer=void 0,this.flushScheduled=!1,this.flush()},0))}async flushLoop(){for(;this.buffer.length>0&&!this.isStopped;){let t=this.buffer.splice(0,this.maxBatchSize);await this.sendBatchWithRetry(t)}}async sendBatchWithRetry(t){let n=0,r=t;for(;r.length>0&&!this.isStopped;){this.inFlightCount=r.length;let i=await this.sendBatchOnce(r);switch(this.inFlightCount=0,i.kind){case"success":return;case"auth":this.stopTransportForAuthFailure(i.status,r.length);return;case"permanent":this.logger.error("[Waniwani] Dropping %d event(s) after permanent failure: %s",r.length,i.reason);return;case"retryable":if(n>=this.maxRetries){this.logger.error("[Waniwani] Dropping %d event(s) after retry exhaustion: %s",r.length,i.reason);return}await this.sleep(this.backoffDelayMs(n)),n+=1;continue;case"partial":if(i.permanent.length>0&&this.logger.error("[Waniwani] Dropping %d event(s) rejected as permanent",i.permanent.length),i.retryable.length===0)return;if(n>=this.maxRetries){this.logger.error("[Waniwani] Dropping %d retryable event(s) after retry exhaustion",i.retryable.length);return}r=i.retryable,await this.sleep(this.backoffDelayMs(n)),n+=1;continue}}}async sendBatchOnce(t){let n;try{n=await this.fetchFn(this.endpointUrl,{method:"POST",headers:this.requestHeaders(),body:JSON.stringify(this.makeBatchRequest(t))})}catch(s){return{kind:"retryable",reason:me(s)}}if(pe.has(n.status))return{kind:"auth",status:n.status};if(le.has(n.status))return{kind:"retryable",reason:`HTTP ${n.status}`};if(!n.ok)return{kind:"permanent",reason:`HTTP ${n.status}`};let r=await he(n);if(!r?.rejected||r.rejected.length===0)return{kind:"success"};let i=this.classifyRejectedEvents(t,r.rejected);return i.retryable.length===0&&i.permanent.length===0?{kind:"success"}:{kind:"partial",retryable:i.retryable,permanent:i.permanent}}makeBatchRequest(t){return{sentAt:this.now().toISOString(),source:{sdk:W,version:this.sdkVersion??"0.0.0"},events:t}}classifyRejectedEvents(t,n){let r=new Map(t.map(a=>[a.id,a])),i=[],s=[];for(let a of n){let o=r.get(a.eventId);if(o){if(fe(a)){i.push(o);continue}s.push(o)}}return{retryable:i,permanent:s}}backoffDelayMs(t){let n=this.retryBaseDelayMs*2**t;return Math.min(n,this.retryMaxDelayMs)}stopTransportForAuthFailure(t,n){this.isStopped=!0;let r=this.buffer.length;this.buffer.splice(0,r),this.logger.error("[Waniwani] Auth failure (HTTP %d). Stopping tracking transport and dropping %d queued event(s)",t,n+r)}};function fe(e){if(e.retryable===!0)return!0;let t=e.code.toLowerCase();return t.includes("timeout")||t.includes("temporary")||t.includes("unavailable")||t.includes("rate_limit")||t.includes("transient")||t.includes("server")}async function he(e){let t=await e.text();if(t)try{return JSON.parse(t)}catch{return}}function ge(e,t){let n=e.endsWith("/")?e:`${e}/`,r=t.startsWith("/")?t.slice(1):t;return`${n}${r}`}function me(e){return e instanceof Error?e.message:String(e)}function ve(e){let{apiUrl:t,endpointPath:n}=Te(e.endpoint),r=w({apiUrl:t,apiKey:e.token,endpointPath:n,flushIntervalMs:e.flushIntervalMs}),i,s=o=>typeof o=="function"?o():o,a=async o=>{let c=e.identity?.()??{},g=s(e.channelId),u=g===void 0?o.properties:{channelId:g,...o.properties},d=T({sessionId:c.sessionId,visitorId:c.visitorId,externalUserId:c.externalUserId??i,traceId:c.traceId,...o,properties:u,metadata:{...e.metadata,...o.metadata}},{source:s(e.source)});return r.enqueue(d),{eventId:d.id}};return{track:Object.assign(a,k(a)),identify(o,c){return i=o,a({event:"user.identified",externalUserId:o,properties:c})},flush:()=>r.flush(),shutdown:o=>r.shutdown(o)}}function Te(e){let t=new URL(e);return{apiUrl:t.origin,endpointPath:`${t.pathname}${t.search}`}}import{AsyncLocalStorage as ye}from"async_hooks";var V=globalThis,E=V.__waniwaniKbRetrievalStore;E||(E=new ye,V.__waniwaniKbRetrievalStore=E);var Ie=E;function K(e){try{Ie.getStore()?.searches.push(e)}catch{}}var ke="@waniwani/sdk";function j(e){let{apiUrl:t,apiKey:n}=e;function r(){if(!n)throw new Error("WANIWANI_API_KEY is not set");return n}async function i(s,a,o){let c=r(),g=`${t.replace(/\/$/,"")}${a}`,u={Authorization:`Bearer ${c}`,"X-WaniWani-SDK":ke},d={method:s,headers:u};o!==void 0&&(u["Content-Type"]="application/json",d.body=JSON.stringify(o));let f=await fetch(g,d);if(!f.ok){let q=await f.text().catch(()=>"");throw new y(q||`KB API error: HTTP ${f.status}`,f.status)}return(await f.json()).data}return{async ingest(s){return i("POST","/api/mcp/kb/ingest",{files:s})},async search(s,a){let o=await i("POST","/api/mcp/kb/search",{query:s,...a});return K({query:s,resultCount:o.length,results:o.map(c=>({source:c.source,heading:c.heading,score:c.score}))}),o},async sources(){return i("GET","/api/mcp/kb/sources")}}}function N(e){let{apiUrl:t,apiKey:n,tracking:r}=e;function i(){if(!n)throw new Error("WANIWANI_API_KEY is not set");return n}let s=n?w({apiUrl:t,apiKey:n,endpointPath:r.endpointPath,flushIntervalMs:r.flushIntervalMs,maxBatchSize:r.maxBatchSize,maxBufferSize:r.maxBufferSize,maxRetries:r.maxRetries,retryBaseDelayMs:r.retryBaseDelayMs,retryMaxDelayMs:r.retryMaxDelayMs,shutdownTimeoutMs:r.shutdownTimeoutMs}):void 0;function a(u){i();let d=T(u);return!d.correlation.sessionId&&!d.correlation.externalUserId&&!d.correlation.visitorId&&console.warn(`[waniwani] event "${d.name}" has no sessionId, externalUserId, or visitorId; the ingest API requires one and will reject it.`),s?.enqueue(d),{eventId:d.id}}let o=async u=>a(u),c=Object.assign(o,k(o)),g={async identify(u,d,f){i();let S=T({event:"user.identified",externalUserId:u,properties:d,meta:f});return s?.enqueue(S),{eventId:S.id}},track:c,async flush(){i(),await s?.flush()},async shutdown(u){return i(),await s?.shutdown({timeoutMs:u?.timeoutMs??r.shutdownTimeoutMs})??{timedOut:!1,pendingEvents:0}}};return s&&we(g,r.shutdownTimeoutMs),g}function we(e,t){if(typeof process>"u"||typeof process.once!="function"||typeof process.on!="function")return;let n=()=>{e.shutdown({timeoutMs:t})};process.once("beforeExit",n),process.once("SIGINT",n),process.once("SIGTERM",n)}function Ee(e){let n=e??b()??P(),r=n?.apiUrl??process.env.WANIWANI_API_URL??"https://app.waniwani.ai",i=n?.apiKey??process.env.WANIWANI_API_KEY,s={endpointPath:n?.tracking?.endpointPath??"/api/mcp/events/v2/batch",flushIntervalMs:n?.tracking?.flushIntervalMs??1e3,maxBatchSize:n?.tracking?.maxBatchSize??20,maxBufferSize:n?.tracking?.maxBufferSize??1e3,maxRetries:n?.tracking?.maxRetries??3,retryBaseDelayMs:n?.tracking?.retryBaseDelayMs??200,retryMaxDelayMs:n?.tracking?.retryMaxDelayMs??2e3,shutdownTimeoutMs:n?.tracking?.shutdownTimeoutMs??2e3},a={apiUrl:r,apiKey:i,tracking:s},o=N(a),c=j(a);return{...o,kb:c,_config:a}}export{_ as EVENT_TYPES,y as WaniWaniError,ve as createFrontendClient,X as defineConfig,Ee as waniwani};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|