@goflowstate/widget-sdk 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/dist/canvas-widget-sdk.js +212 -3
- package/dist/canvas-widget-sdk.js.map +3 -3
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +372 -4
- package/dist/index.mjs.map +3 -3
- package/dist/ingest.d.ts +22 -0
- package/dist/ingest.d.ts.map +1 -0
- package/dist/ingest.test.d.ts +2 -0
- package/dist/ingest.test.d.ts.map +1 -0
- package/dist/sdk.d.ts +15 -0
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.namespace.test.d.ts +2 -0
- package/dist/sdk.namespace.test.d.ts.map +1 -0
- package/dist/session.d.ts +129 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.test.d.ts +2 -0
- package/dist/session.test.d.ts.map +1 -0
- package/dist/theme.d.ts +30 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.test.d.ts +2 -0
- package/dist/theme.test.d.ts.map +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @goflowstate/widget-sdk v0.
|
|
1
|
+
// @goflowstate/widget-sdk v0.2.0
|
|
2
2
|
// https://github.com/starteryllp/goflowstate-sdk
|
|
3
3
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -39,10 +39,288 @@ function createServiceClient(opts) {
|
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
// src/session.ts
|
|
43
|
+
function readSessionLaunchParams() {
|
|
44
|
+
if (typeof window === "undefined") return null;
|
|
45
|
+
const q = new URLSearchParams(window.location.search);
|
|
46
|
+
const slug = q.get("slug") ?? q.get("tripId") ?? "";
|
|
47
|
+
if (!slug) return null;
|
|
48
|
+
return {
|
|
49
|
+
slug,
|
|
50
|
+
ticket: q.get("ticket"),
|
|
51
|
+
apiBase: (q.get("api") ?? "http://localhost:13002").replace(/\/$/, ""),
|
|
52
|
+
webBase: (q.get("web") ?? "http://localhost:14321").replace(/\/$/, "")
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
var SESSION_INIT_TIMEOUT_MS = 1e4;
|
|
56
|
+
var DEFAULT_POLL_INTERVAL_MS = 4e3;
|
|
57
|
+
function awaitInitTicket(webBase) {
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
if (typeof window === "undefined" || window.parent === window) {
|
|
60
|
+
reject(new Error("no parent page to receive a ticket from"));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const webOrigin = new URL(webBase).origin;
|
|
64
|
+
const timer = setTimeout(() => {
|
|
65
|
+
window.removeEventListener("message", onMessage);
|
|
66
|
+
reject(new Error("timed out waiting for the session handoff"));
|
|
67
|
+
}, SESSION_INIT_TIMEOUT_MS);
|
|
68
|
+
const onMessage = (e) => {
|
|
69
|
+
if (e.origin !== webOrigin) return;
|
|
70
|
+
const data = e.data;
|
|
71
|
+
if (data?.type !== "flowstate:init" || typeof data.ticket !== "string") return;
|
|
72
|
+
clearTimeout(timer);
|
|
73
|
+
window.removeEventListener("message", onMessage);
|
|
74
|
+
resolve(data.ticket);
|
|
75
|
+
};
|
|
76
|
+
window.addEventListener("message", onMessage);
|
|
77
|
+
window.parent.postMessage({ type: "flowstate:ready" }, webOrigin);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
var WIRE_PHASE = {
|
|
81
|
+
setup: "setup",
|
|
82
|
+
wishlist: "open",
|
|
83
|
+
sealed: "sealed",
|
|
84
|
+
plan: "resolved"
|
|
85
|
+
};
|
|
86
|
+
function toStateView(s) {
|
|
87
|
+
return {
|
|
88
|
+
slug: s.tripId,
|
|
89
|
+
phase: WIRE_PHASE[s.phase] ?? "open",
|
|
90
|
+
status: s.status,
|
|
91
|
+
setup: s.setup ?? null,
|
|
92
|
+
members: s.members,
|
|
93
|
+
sealedCount: s.sealedCount,
|
|
94
|
+
memberCount: s.memberCount,
|
|
95
|
+
allSealed: s.allSealed,
|
|
96
|
+
quorumMet: s.quorumMet ?? s.allSealed,
|
|
97
|
+
gate: s.gate ?? null,
|
|
98
|
+
flow: s.flow ?? null,
|
|
99
|
+
myContribution: s.myWishlist ?? null,
|
|
100
|
+
doc: s.plan ?? null,
|
|
101
|
+
artifactId: s.artifactId,
|
|
102
|
+
extension: s.extension ?? null
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
var parentOpener = (webBase) => {
|
|
106
|
+
return (url) => {
|
|
107
|
+
if (typeof window !== "undefined" && window.parent !== window) {
|
|
108
|
+
window.parent.postMessage({ type: "flowstate:navigate", url }, webBase);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (typeof window !== "undefined") window.open(url, "_blank", "noopener");
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
var HttpSessionClient = class {
|
|
115
|
+
constructor(params, opener) {
|
|
116
|
+
__publicField(this, "slug");
|
|
117
|
+
__publicField(this, "webBase");
|
|
118
|
+
__publicField(this, "apiBase");
|
|
119
|
+
__publicField(this, "tokenPromise");
|
|
120
|
+
__publicField(this, "opener");
|
|
121
|
+
this.slug = params.slug;
|
|
122
|
+
this.webBase = params.webBase;
|
|
123
|
+
this.apiBase = params.apiBase;
|
|
124
|
+
this.opener = opener ?? parentOpener(params.webBase);
|
|
125
|
+
this.tokenPromise = this.acquireTicket(params).then((t) => this.redeem(t));
|
|
126
|
+
}
|
|
127
|
+
async acquireTicket(params) {
|
|
128
|
+
if (params.ticket) return params.ticket;
|
|
129
|
+
return awaitInitTicket(params.webBase);
|
|
130
|
+
}
|
|
131
|
+
async redeem(ticket) {
|
|
132
|
+
const res = await fetch(`${this.apiBase}/api/auth/ticket/redeem`, {
|
|
133
|
+
method: "POST",
|
|
134
|
+
headers: { "content-type": "application/json" },
|
|
135
|
+
body: JSON.stringify({ ticket })
|
|
136
|
+
});
|
|
137
|
+
if (!res.ok) throw new Error(`ticket redeem failed (${res.status})`);
|
|
138
|
+
const json = await res.json();
|
|
139
|
+
return json.data.token;
|
|
140
|
+
}
|
|
141
|
+
async call(path, init = {}) {
|
|
142
|
+
const token = await this.tokenPromise;
|
|
143
|
+
const res = await fetch(`${this.apiBase}/api/w/${this.slug}${path}`, {
|
|
144
|
+
...init,
|
|
145
|
+
headers: {
|
|
146
|
+
authorization: `Bearer ${token}`,
|
|
147
|
+
...init.body ? { "content-type": "application/json" } : {},
|
|
148
|
+
...init.headers ?? {}
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
if (!res.ok) {
|
|
152
|
+
const body = await res.json().catch(() => ({}));
|
|
153
|
+
throw new Error(body.message ?? `session service ${res.status}`);
|
|
154
|
+
}
|
|
155
|
+
const json = await res.json();
|
|
156
|
+
const data = json.data;
|
|
157
|
+
return toStateView(data.state ?? data);
|
|
158
|
+
}
|
|
159
|
+
join() {
|
|
160
|
+
return this.call("/enter", { method: "POST" });
|
|
161
|
+
}
|
|
162
|
+
state() {
|
|
163
|
+
return this.call("/state");
|
|
164
|
+
}
|
|
165
|
+
poll(onState, opts) {
|
|
166
|
+
const interval = opts?.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
167
|
+
let stopped = false;
|
|
168
|
+
let timer = null;
|
|
169
|
+
const tick = async () => {
|
|
170
|
+
try {
|
|
171
|
+
const s = await this.state();
|
|
172
|
+
if (!stopped) onState(s);
|
|
173
|
+
} catch (err) {
|
|
174
|
+
opts?.onError?.(err);
|
|
175
|
+
}
|
|
176
|
+
if (!stopped) timer = setTimeout(tick, interval);
|
|
177
|
+
};
|
|
178
|
+
void tick();
|
|
179
|
+
return () => {
|
|
180
|
+
stopped = true;
|
|
181
|
+
if (timer) clearTimeout(timer);
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
commitSetup(setup) {
|
|
185
|
+
return this.call("/setup", { method: "POST", body: JSON.stringify({ setup }) });
|
|
186
|
+
}
|
|
187
|
+
contribute(payload) {
|
|
188
|
+
return this.call("/contribute", { method: "POST", body: JSON.stringify({ payload }) });
|
|
189
|
+
}
|
|
190
|
+
close() {
|
|
191
|
+
return this.call("/close", { method: "POST" });
|
|
192
|
+
}
|
|
193
|
+
action(verb, body) {
|
|
194
|
+
return this.call(`/${verb.replace(/^\//, "")}`, {
|
|
195
|
+
method: "POST",
|
|
196
|
+
body: JSON.stringify(body ?? {})
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
async request(verb, body) {
|
|
200
|
+
const token = await this.tokenPromise;
|
|
201
|
+
const res = await fetch(`${this.apiBase}/api/w/${this.slug}/${verb.replace(/^\//, "")}`, {
|
|
202
|
+
method: "POST",
|
|
203
|
+
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
|
|
204
|
+
body: JSON.stringify(body ?? {})
|
|
205
|
+
});
|
|
206
|
+
if (!res.ok) {
|
|
207
|
+
const errBody = await res.json().catch(() => ({}));
|
|
208
|
+
throw new Error(errBody.message ?? `session service ${res.status}`);
|
|
209
|
+
}
|
|
210
|
+
const json = await res.json();
|
|
211
|
+
return json.data;
|
|
212
|
+
}
|
|
213
|
+
openExternal(url) {
|
|
214
|
+
this.opener(url);
|
|
215
|
+
}
|
|
216
|
+
revealUrl(artifactId) {
|
|
217
|
+
return `${this.webBase}/a/${artifactId}`;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
function createMockSession(opts = {}) {
|
|
221
|
+
const palette = ["#8b7ef8", "#f8a34d", "#4dc9a4", "#f26d8f", "#5aa9e6"];
|
|
222
|
+
const members = [
|
|
223
|
+
{ userId: "mock-me", name: opts.me ?? "You", color: palette[0], sealed: false, isMe: true, isHost: true },
|
|
224
|
+
...(opts.others ?? []).map((name, i) => ({
|
|
225
|
+
userId: `mock-${i + 1}`,
|
|
226
|
+
name,
|
|
227
|
+
color: palette[(i + 1) % palette.length],
|
|
228
|
+
sealed: false,
|
|
229
|
+
isMe: false,
|
|
230
|
+
isHost: false
|
|
231
|
+
}))
|
|
232
|
+
];
|
|
233
|
+
let setup = opts.setup ?? null;
|
|
234
|
+
let myContribution = null;
|
|
235
|
+
let doc = null;
|
|
236
|
+
let status = "open";
|
|
237
|
+
const view = () => {
|
|
238
|
+
const sealedCount = members.filter((m) => m.sealed).length;
|
|
239
|
+
const allSealed = members.length > 0 && sealedCount >= members.length;
|
|
240
|
+
const phase = status === "closed" && doc ? "resolved" : !setup ? "setup" : allSealed ? "sealed" : "open";
|
|
241
|
+
return {
|
|
242
|
+
slug: "mock-session",
|
|
243
|
+
phase,
|
|
244
|
+
status,
|
|
245
|
+
setup,
|
|
246
|
+
members: members.map((m) => ({ ...m })),
|
|
247
|
+
sealedCount,
|
|
248
|
+
memberCount: members.length,
|
|
249
|
+
allSealed,
|
|
250
|
+
quorumMet: allSealed,
|
|
251
|
+
gate: null,
|
|
252
|
+
flow: null,
|
|
253
|
+
myContribution,
|
|
254
|
+
doc,
|
|
255
|
+
artifactId: doc ? "mock-artifact" : null,
|
|
256
|
+
extension: null
|
|
257
|
+
};
|
|
258
|
+
};
|
|
259
|
+
return {
|
|
260
|
+
slug: "mock-session",
|
|
261
|
+
webBase: "http://localhost:14321",
|
|
262
|
+
async join() {
|
|
263
|
+
return view();
|
|
264
|
+
},
|
|
265
|
+
async state() {
|
|
266
|
+
return view();
|
|
267
|
+
},
|
|
268
|
+
poll(onState, pollOpts) {
|
|
269
|
+
const interval = pollOpts?.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
270
|
+
const timer = setInterval(() => onState(view()), interval);
|
|
271
|
+
onState(view());
|
|
272
|
+
return () => clearInterval(timer);
|
|
273
|
+
},
|
|
274
|
+
async commitSetup(s) {
|
|
275
|
+
setup = s;
|
|
276
|
+
return view();
|
|
277
|
+
},
|
|
278
|
+
async contribute(payload) {
|
|
279
|
+
myContribution = payload;
|
|
280
|
+
const me = members.find((m) => m.isMe);
|
|
281
|
+
if (me) me.sealed = true;
|
|
282
|
+
return view();
|
|
283
|
+
},
|
|
284
|
+
async close() {
|
|
285
|
+
status = "closed";
|
|
286
|
+
doc = opts.synthesize ? opts.synthesize([myContribution]) : { mock: true };
|
|
287
|
+
return view();
|
|
288
|
+
},
|
|
289
|
+
async action() {
|
|
290
|
+
return view();
|
|
291
|
+
},
|
|
292
|
+
async request() {
|
|
293
|
+
return {};
|
|
294
|
+
},
|
|
295
|
+
openExternal(url) {
|
|
296
|
+
if (typeof window !== "undefined") window.open(url, "_blank", "noopener");
|
|
297
|
+
},
|
|
298
|
+
revealUrl(artifactId) {
|
|
299
|
+
return `http://localhost:14321/a/${artifactId}`;
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
function initSession() {
|
|
304
|
+
const params = readSessionLaunchParams();
|
|
305
|
+
if (!params) return null;
|
|
306
|
+
return new HttpSessionClient(params);
|
|
307
|
+
}
|
|
308
|
+
|
|
42
309
|
// src/sdk.ts
|
|
43
310
|
var PROTOCOL = "canvas-widget-v1";
|
|
44
311
|
var DEV_MODE_TOKEN = "dev-mode-skip";
|
|
45
312
|
var INIT_TIMEOUT_MS = 5e3;
|
|
313
|
+
function safeRandomUUID() {
|
|
314
|
+
const c = globalThis.crypto;
|
|
315
|
+
if (c && typeof c.randomUUID === "function") return c.randomUUID();
|
|
316
|
+
const b = new Uint8Array(16);
|
|
317
|
+
if (c && typeof c.getRandomValues === "function") c.getRandomValues(b);
|
|
318
|
+
else for (let i = 0; i < 16; i++) b[i] = Math.floor(Math.random() * 256);
|
|
319
|
+
b[6] = b[6] & 15 | 64;
|
|
320
|
+
b[8] = b[8] & 63 | 128;
|
|
321
|
+
const h = Array.from(b, (x) => x.toString(16).padStart(2, "0"));
|
|
322
|
+
return `${h[0]}${h[1]}${h[2]}${h[3]}-${h[4]}${h[5]}-${h[6]}${h[7]}-${h[8]}${h[9]}-${h[10]}${h[11]}${h[12]}${h[13]}${h[14]}${h[15]}`;
|
|
323
|
+
}
|
|
46
324
|
var cachedKey = null;
|
|
47
325
|
async function getHmacKey(secret) {
|
|
48
326
|
if (cachedKey && cachedKey.secret === secret) return cachedKey.key;
|
|
@@ -69,6 +347,7 @@ var CanvasWidgetSDKImpl = class {
|
|
|
69
347
|
__publicField(this, "_state");
|
|
70
348
|
__publicField(this, "_hmacSecret");
|
|
71
349
|
__publicField(this, "_user");
|
|
350
|
+
__publicField(this, "_namespace");
|
|
72
351
|
__publicField(this, "_widgetApiUrl");
|
|
73
352
|
__publicField(this, "_widgetApiToken");
|
|
74
353
|
__publicField(this, "_installationId");
|
|
@@ -89,6 +368,7 @@ var CanvasWidgetSDKImpl = class {
|
|
|
89
368
|
this._state = init.state;
|
|
90
369
|
this._hmacSecret = init.hmacSecret;
|
|
91
370
|
this._user = init.user;
|
|
371
|
+
this._namespace = init.namespace ?? null;
|
|
92
372
|
this._widgetApiUrl = init.widgetApiUrl;
|
|
93
373
|
this._widgetApiToken = init.widgetApiToken ?? null;
|
|
94
374
|
this._installationId = init.installationId;
|
|
@@ -114,6 +394,11 @@ var CanvasWidgetSDKImpl = class {
|
|
|
114
394
|
get user() {
|
|
115
395
|
return this._user;
|
|
116
396
|
}
|
|
397
|
+
/** Namespace (office) context — id and owner-inclusive member count — or
|
|
398
|
+
* null on a personal canvas. What the `canvas.context` permission grants. */
|
|
399
|
+
get namespace() {
|
|
400
|
+
return this._namespace;
|
|
401
|
+
}
|
|
117
402
|
/** Subscribe to display state changes; returns an unsubscribe function. */
|
|
118
403
|
onStateChange(cb) {
|
|
119
404
|
this._stateListeners.push(cb);
|
|
@@ -377,7 +662,7 @@ var CanvasWidgetSDKImpl = class {
|
|
|
377
662
|
});
|
|
378
663
|
}
|
|
379
664
|
async buildMessage(type, payload) {
|
|
380
|
-
const nonce =
|
|
665
|
+
const nonce = safeRandomUUID();
|
|
381
666
|
const timestamp = Date.now();
|
|
382
667
|
let token;
|
|
383
668
|
if (this._hmacSecret) {
|
|
@@ -407,6 +692,13 @@ var CanvasWidgetSDKImpl = class {
|
|
|
407
692
|
}
|
|
408
693
|
};
|
|
409
694
|
var CanvasWidget = {
|
|
695
|
+
/**
|
|
696
|
+
* Initialize a group-session client for widgets hosted on the /w/[slug]
|
|
697
|
+
* session page (ticket handshake + session REST rails). Returns null when
|
|
698
|
+
* the launch context carries no session params — see `initSession` in
|
|
699
|
+
* ./session for details and `createMockSession` for standalone dev.
|
|
700
|
+
*/
|
|
701
|
+
initSession,
|
|
410
702
|
/**
|
|
411
703
|
* Initialize the SDK and establish communication with the canvas host.
|
|
412
704
|
*
|
|
@@ -436,7 +728,7 @@ var CanvasWidget = {
|
|
|
436
728
|
type: "READY",
|
|
437
729
|
widgetId: "",
|
|
438
730
|
// Not yet known — host identifies us by iframe source
|
|
439
|
-
nonce:
|
|
731
|
+
nonce: safeRandomUUID(),
|
|
440
732
|
timestamp: Date.now(),
|
|
441
733
|
token: DEV_MODE_TOKEN,
|
|
442
734
|
// READY is always allowed, token doesn't matter
|
|
@@ -446,8 +738,84 @@ var CanvasWidget = {
|
|
|
446
738
|
});
|
|
447
739
|
}
|
|
448
740
|
};
|
|
741
|
+
|
|
742
|
+
// src/theme.ts
|
|
743
|
+
var THEME_MESSAGE_TYPE = "flowstate:theme";
|
|
744
|
+
var DEFAULT_THEME = "glass";
|
|
745
|
+
function isWidgetTheme(value) {
|
|
746
|
+
return value === "light" || value === "dark" || value === "glass";
|
|
747
|
+
}
|
|
748
|
+
function getInitialTheme() {
|
|
749
|
+
if (typeof window === "undefined") return DEFAULT_THEME;
|
|
750
|
+
try {
|
|
751
|
+
const param = new URLSearchParams(window.location.search).get("theme");
|
|
752
|
+
return isWidgetTheme(param) ? param : DEFAULT_THEME;
|
|
753
|
+
} catch {
|
|
754
|
+
return DEFAULT_THEME;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
function onThemeChange(cb, opts) {
|
|
758
|
+
if (typeof window === "undefined") return () => {
|
|
759
|
+
};
|
|
760
|
+
const listener = (event) => {
|
|
761
|
+
if (event.source !== window.parent) return;
|
|
762
|
+
if (opts?.allowedOrigin && event.origin !== opts.allowedOrigin) return;
|
|
763
|
+
const data = event.data;
|
|
764
|
+
if (typeof data !== "object" || data === null) return;
|
|
765
|
+
const message = data;
|
|
766
|
+
if (message.type !== THEME_MESSAGE_TYPE) return;
|
|
767
|
+
if (!isWidgetTheme(message.theme)) return;
|
|
768
|
+
cb(message.theme);
|
|
769
|
+
};
|
|
770
|
+
window.addEventListener("message", listener);
|
|
771
|
+
return () => window.removeEventListener("message", listener);
|
|
772
|
+
}
|
|
773
|
+
function applyWidgetTheme(theme) {
|
|
774
|
+
if (typeof document === "undefined") return;
|
|
775
|
+
if (theme === "glass") {
|
|
776
|
+
delete document.documentElement.dataset.theme;
|
|
777
|
+
} else {
|
|
778
|
+
document.documentElement.dataset.theme = theme;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
function initWidgetTheme() {
|
|
782
|
+
applyWidgetTheme(getInitialTheme());
|
|
783
|
+
return onThemeChange(applyWidgetTheme);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// src/ingest.ts
|
|
787
|
+
var INGEST_MESSAGE_TYPE = "flowstate:ingest";
|
|
788
|
+
function onArtifactIngested(cb, opts) {
|
|
789
|
+
if (typeof window === "undefined") return () => {
|
|
790
|
+
};
|
|
791
|
+
const listener = (event) => {
|
|
792
|
+
if (event.source !== window.parent) return;
|
|
793
|
+
if (opts?.allowedOrigin && event.origin !== opts.allowedOrigin) return;
|
|
794
|
+
const data = event.data;
|
|
795
|
+
if (typeof data !== "object" || data === null) return;
|
|
796
|
+
const message = data;
|
|
797
|
+
if (message.type !== INGEST_MESSAGE_TYPE) return;
|
|
798
|
+
if (typeof message.artifactId !== "string" || !message.artifactId) return;
|
|
799
|
+
cb({
|
|
800
|
+
artifactId: message.artifactId,
|
|
801
|
+
kind: typeof message.kind === "string" ? message.kind : void 0,
|
|
802
|
+
payload: message.payload
|
|
803
|
+
});
|
|
804
|
+
};
|
|
805
|
+
window.addEventListener("message", listener);
|
|
806
|
+
return () => window.removeEventListener("message", listener);
|
|
807
|
+
}
|
|
449
808
|
export {
|
|
450
809
|
CanvasWidget,
|
|
451
|
-
|
|
810
|
+
INGEST_MESSAGE_TYPE,
|
|
811
|
+
applyWidgetTheme,
|
|
812
|
+
createMockSession,
|
|
813
|
+
createServiceClient,
|
|
814
|
+
getInitialTheme,
|
|
815
|
+
initSession,
|
|
816
|
+
initWidgetTheme,
|
|
817
|
+
onArtifactIngested,
|
|
818
|
+
onThemeChange,
|
|
819
|
+
readSessionLaunchParams
|
|
452
820
|
};
|
|
453
821
|
//# sourceMappingURL=index.mjs.map
|