@aikaara/chat-sdk 0.8.1 → 0.8.3

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.
@@ -0,0 +1,3 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=new Map;async function d(e,r){switch(e.kind){case"iife-element":return p(e,r);case"remote-dom":return w(e,r);default:{const t=e;throw new Error(`loadRemoteComponent: unknown kind ${JSON.stringify(t)}`)}}}async function p(e,r){customElements.get(e.tag)||(await f(e.scriptUrl),await h(e.tag));const t=document.createElement(e.tag);return c(t,e.props),c(t,r.props),r.ctx&&c(t,{setCtx:r.ctx}),r.onComplete&&t.addEventListener("complete",n=>r.onComplete?.(n.detail)),r.onError&&t.addEventListener("error",n=>r.onError?.(n.error??new Error("component error"))),r.target.appendChild(t),{el:t,unmount(){t.remove()},update(n){c(t,n)}}}function c(e,r){if(r)for(const[t,n]of Object.entries(r)){const s=e[t];if(typeof s=="function")try{s.call(e,n)}catch(o){console.warn(`[RemoteComponentLoader] ${t}() threw`,o)}}}function f(e){const r=u.get(e);if(r)return r;const t=new Promise((n,s)=>{const o=document.createElement("script");o.src=e,o.async=!0,o.onload=()=>n(),o.onerror=()=>s(new Error(`Failed to load script ${e}`)),document.head.appendChild(o)});return u.set(e,t),t}function h(e,r=5e3){return customElements.get(e)?Promise.resolve():Promise.race([customElements.whenDefined(e).then(()=>{}),new Promise((t,n)=>{setTimeout(()=>n(new Error(`Custom element <${e}> never registered`)),r)})])}const l=1;function w(e,r){const t=document.createElement("iframe");t.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-popups"),t.style.cssText="width:100%;height:100%;border:0;display:block;background:transparent;",t.setAttribute("title",`aikaara-remote:${e.globalName??e.scriptUrl}`);const n=[],s=a=>t.contentWindow?.postMessage(a,"*");let o=!1;const m=a=>{if(a.source!==t.contentWindow)return;const i=a.data;!i||i.aikaara!==l||(i.type==="ready"?s({aikaara:l,type:"bootstrap",ctx:r.ctx,props:{...e.props??{},...r.props??{}}}):i.type==="complete"?r.onComplete?.(i.payload):i.type==="error"&&r.onError?.(new Error(i.message)))};return window.addEventListener("message",m),n.push(()=>window.removeEventListener("message",m)),t.srcdoc=`<!doctype html><html><head><meta charset="utf-8">
2
+ <style>html,body{margin:0;padding:0;height:100%;background:transparent;}</style>
3
+ </head><body><script src="${g(e.scriptUrl)}" defer><\/script></body></html>`,r.target.appendChild(t),{el:t,unmount(){if(!o){o=!0;for(const a of n)try{a()}catch{}t.remove()}},update(a){s({aikaara:l,type:"update",props:a})}}}function g(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;")}exports.loadRemoteComponent=d;
@@ -0,0 +1,68 @@
1
+ export declare interface LoadOptions {
2
+ /** Where the rendered element should be inserted. */
3
+ target: HTMLElement;
4
+ /** Forwarded to the tenant component. */
5
+ props?: Record<string, unknown>;
6
+ /** Forwarded as the `ctx` payload (read-only state from host). */
7
+ ctx?: RemoteHostContext;
8
+ /** Tenant components call this to signal a flow step finished
9
+ * (e.g. screen:login → onComplete({ext_uid, token})). */
10
+ onComplete?: (payload: unknown) => void;
11
+ /** Tenant component error → host can show a banner / fall back. */
12
+ onError?: (err: Error) => void;
13
+ }
14
+
15
+ /** Load + mount one slot's component. Returns a handle for tear-down. */
16
+ export declare function loadRemoteComponent(def: RemoteComponent, opts: LoadOptions): Promise<MountedComponent>;
17
+
18
+ export declare interface MountedComponent {
19
+ /** The DOM node added to `target` (custom element or iframe). */
20
+ el: HTMLElement;
21
+ /** Tear down + remove from DOM. Idempotent. */
22
+ unmount(): void;
23
+ /** Push a new `props` payload to the mounted component. */
24
+ update(props: Record<string, unknown>): void;
25
+ }
26
+
27
+ /**
28
+ * One slot's component pointer. The `kind` discriminator picks which
29
+ * loader runs. Both kinds resolve to a `Promise<HTMLElement>` after load,
30
+ * which the runtime appends into the slot anchor.
31
+ */
32
+ export declare type RemoteComponent = {
33
+ kind: 'iife-element';
34
+ /** URL of an IIFE bundle that calls `customElements.define(tag, …)`. */
35
+ scriptUrl: string;
36
+ /** Custom-element tag the bundle registers. */
37
+ tag: string;
38
+ /** Optional method-call map: `{ setLayout: "stacked" }` becomes
39
+ * `el.setLayout("stacked")` after mount. */
40
+ props?: Record<string, unknown>;
41
+ } | {
42
+ kind: 'remote-dom';
43
+ /** URL of an IIFE bundle that, when executed, leaves a global at
44
+ * `globalName` exposing `mount({ target, ctx, complete, props })`.
45
+ * Authored via `@aikaara/chat-sdk/remote-author`. */
46
+ scriptUrl: string;
47
+ /** Optional global name; defaults to the slot id with non-alphanumeric
48
+ * chars replaced by underscores (e.g. "screen:login" → "screen_login"). */
49
+ globalName?: string;
50
+ /** Sandbox kind. Today only `iframe`; `worker` reserved for later. */
51
+ sandbox?: 'iframe' | 'worker';
52
+ /** Forwarded to the bundle's `mount({ props })` call. */
53
+ props?: Record<string, unknown>;
54
+ };
55
+
56
+ export declare interface RemoteHostContext {
57
+ /** Project slug currently mounted. */
58
+ slug: string;
59
+ /** Theme tokens from descriptor.theme — passed for tenant components
60
+ * to render in-brand without re-fetching the descriptor. */
61
+ theme?: Record<string, unknown>;
62
+ /** Identity bag (already-resolved user info). */
63
+ identity?: Record<string, unknown>;
64
+ /** Free-form: descriptor block(s) the tenant component might need. */
65
+ extras?: Record<string, unknown>;
66
+ }
67
+
68
+ export { }
@@ -0,0 +1,104 @@
1
+ const u = /* @__PURE__ */ new Map();
2
+ async function g(e, r) {
3
+ switch (e.kind) {
4
+ case "iife-element":
5
+ return p(e, r);
6
+ case "remote-dom":
7
+ return h(e, r);
8
+ default: {
9
+ const t = e;
10
+ throw new Error(`loadRemoteComponent: unknown kind ${JSON.stringify(t)}`);
11
+ }
12
+ }
13
+ }
14
+ async function p(e, r) {
15
+ customElements.get(e.tag) || (await d(e.scriptUrl), await f(e.tag));
16
+ const t = document.createElement(e.tag);
17
+ return i(t, e.props), i(t, r.props), r.ctx && i(t, { setCtx: r.ctx }), r.onComplete && t.addEventListener("complete", (n) => r.onComplete?.(n.detail)), r.onError && t.addEventListener("error", (n) => r.onError?.(n.error ?? new Error("component error"))), r.target.appendChild(t), {
18
+ el: t,
19
+ unmount() {
20
+ t.remove();
21
+ },
22
+ update(n) {
23
+ i(t, n);
24
+ }
25
+ };
26
+ }
27
+ function i(e, r) {
28
+ if (r)
29
+ for (const [t, n] of Object.entries(r)) {
30
+ const s = e[t];
31
+ if (typeof s == "function")
32
+ try {
33
+ s.call(e, n);
34
+ } catch (o) {
35
+ console.warn(`[RemoteComponentLoader] ${t}() threw`, o);
36
+ }
37
+ }
38
+ }
39
+ function d(e) {
40
+ const r = u.get(e);
41
+ if (r) return r;
42
+ const t = new Promise((n, s) => {
43
+ const o = document.createElement("script");
44
+ o.src = e, o.async = !0, o.onload = () => n(), o.onerror = () => s(new Error(`Failed to load script ${e}`)), document.head.appendChild(o);
45
+ });
46
+ return u.set(e, t), t;
47
+ }
48
+ function f(e, r = 5e3) {
49
+ return customElements.get(e) ? Promise.resolve() : Promise.race([
50
+ customElements.whenDefined(e).then(() => {
51
+ }),
52
+ new Promise((t, n) => {
53
+ setTimeout(() => n(new Error(`Custom element <${e}> never registered`)), r);
54
+ })
55
+ ]);
56
+ }
57
+ const l = 1;
58
+ function h(e, r) {
59
+ const t = document.createElement("iframe");
60
+ t.setAttribute(
61
+ "sandbox",
62
+ // Restrictive set: scripts (run the bundle), same-origin (so the
63
+ // bundle can use localStorage/cookies on its own srcdoc origin),
64
+ // forms (login submits), popups (when tenant code opens external
65
+ // links). NOT allow-top-navigation — the bundle can't break out.
66
+ "allow-scripts allow-same-origin allow-forms allow-popups"
67
+ ), t.style.cssText = "width:100%;height:100%;border:0;display:block;background:transparent;", t.setAttribute("title", `aikaara-remote:${e.globalName ?? e.scriptUrl}`);
68
+ const n = [], s = (a) => t.contentWindow?.postMessage(a, "*");
69
+ let o = !1;
70
+ const m = (a) => {
71
+ if (a.source !== t.contentWindow) return;
72
+ const c = a.data;
73
+ !c || c.aikaara !== l || (c.type === "ready" ? s({
74
+ aikaara: l,
75
+ type: "bootstrap",
76
+ ctx: r.ctx,
77
+ props: { ...e.props ?? {}, ...r.props ?? {} }
78
+ }) : c.type === "complete" ? r.onComplete?.(c.payload) : c.type === "error" && r.onError?.(new Error(c.message)));
79
+ };
80
+ return window.addEventListener("message", m), n.push(() => window.removeEventListener("message", m)), t.srcdoc = `<!doctype html><html><head><meta charset="utf-8">
81
+ <style>html,body{margin:0;padding:0;height:100%;background:transparent;}</style>
82
+ </head><body><script src="${w(e.scriptUrl)}" defer><\/script></body></html>`, r.target.appendChild(t), {
83
+ el: t,
84
+ unmount() {
85
+ if (!o) {
86
+ o = !0;
87
+ for (const a of n) try {
88
+ a();
89
+ } catch {
90
+ }
91
+ t.remove();
92
+ }
93
+ },
94
+ update(a) {
95
+ s({ aikaara: l, type: "update", props: a });
96
+ }
97
+ };
98
+ }
99
+ function w(e) {
100
+ return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
101
+ }
102
+ export {
103
+ g as loadRemoteComponent
104
+ };
package/dist/ui.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./MountTenant-BrBxPpjb.cjs");exports.AikaaraChat=a.AikaaraChat;exports.AikaaraChatBubble=a.AikaaraChatBubble;exports.AikaaraChatHeader=a.AikaaraChatHeader;exports.AikaaraChatInput=a.AikaaraChatInput;exports.AikaaraChatWidget=a.AikaaraChatWidget;exports.AikaaraComparePlans=a.AikaaraComparePlans;exports.AikaaraErrorBanner=a.AikaaraErrorBanner;exports.AikaaraLinkModal=a.AikaaraLinkModal;exports.AikaaraMessageBubble=a.AikaaraMessageBubble;exports.AikaaraMessageList=a.AikaaraMessageList;exports.AikaaraModalAction=a.AikaaraModalAction;exports.AikaaraOptionList=a.AikaaraOptionList;exports.AikaaraStreamingMessage=a.AikaaraStreamingMessage;exports.AikaaraSubmitAction=a.AikaaraSubmitAction;exports.AikaaraSystemPill=a.AikaaraSystemPill;exports.AikaaraTemplateRenderer=a.AikaaraTemplateRenderer;exports.AikaaraTypingIndicator=a.AikaaraTypingIndicator;exports.registerComponents=a.registerComponents;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./MountTenant-BCjKRkD8.cjs");exports.AikaaraChat=a.AikaaraChat;exports.AikaaraChatBubble=a.AikaaraChatBubble;exports.AikaaraChatHeader=a.AikaaraChatHeader;exports.AikaaraChatInput=a.AikaaraChatInput;exports.AikaaraChatWidget=a.AikaaraChatWidget;exports.AikaaraComparePlans=a.AikaaraComparePlans;exports.AikaaraErrorBanner=a.AikaaraErrorBanner;exports.AikaaraLinkModal=a.AikaaraLinkModal;exports.AikaaraMessageBubble=a.AikaaraMessageBubble;exports.AikaaraMessageList=a.AikaaraMessageList;exports.AikaaraModalAction=a.AikaaraModalAction;exports.AikaaraOptionList=a.AikaaraOptionList;exports.AikaaraStreamingMessage=a.AikaaraStreamingMessage;exports.AikaaraSubmitAction=a.AikaaraSubmitAction;exports.AikaaraSystemPill=a.AikaaraSystemPill;exports.AikaaraTemplateRenderer=a.AikaaraTemplateRenderer;exports.AikaaraTypingIndicator=a.AikaaraTypingIndicator;exports.registerComponents=a.registerComponents;
package/dist/ui.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { B as i, a as s, c as e, d as t, e as A, D as k, f as n, F as o, g, h as l, G as d, H as m, i as p, I as C, J as h, K as b, j as M, r as c } from "./MountTenant-BVimPLfY.mjs";
1
+ import { G as i, a as s, c as e, d as t, e as A, H as k, f as n, I as o, g, h as l, J as d, K as m, i as p, L as C, N as h, O as b, j as M, r as c } from "./MountTenant-CxO7hJgs.mjs";
2
2
  export {
3
3
  i as AikaaraChat,
4
4
  s as AikaaraChatBubble,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aikaara/chat-sdk",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "type": "module",
5
5
  "description": "Aikaara Chat SDK — embeddable chat widget and headless client",
6
6
  "license": "MIT",
@@ -19,6 +19,16 @@
19
19
  "types": "./dist/ui.d.ts",
20
20
  "import": "./dist/ui.mjs",
21
21
  "require": "./dist/ui.cjs"
22
+ },
23
+ "./remote-host": {
24
+ "types": "./dist/remote-host.d.ts",
25
+ "import": "./dist/remote-host.mjs",
26
+ "require": "./dist/remote-host.cjs"
27
+ },
28
+ "./remote-author": {
29
+ "types": "./dist/remote-author.d.ts",
30
+ "import": "./dist/remote-author.mjs",
31
+ "require": "./dist/remote-author.cjs"
22
32
  }
23
33
  },
24
34
  "main": "./dist/index.cjs",