rivia 0.0.83 → 0.0.85

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.
Files changed (3) hide show
  1. package/dist/index.js +362 -2
  2. package/index.d.ts +23 -1
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3658,7 +3658,7 @@ function injectBanner(banner = {}, opts = {}, userId, bannerId) {
3658
3658
  let uploadVisitedPagesInBackground2 = function(bannerId2) {
3659
3659
  console.log("Uploading visited pages in background for banner ID: and user_var:", userId);
3660
3660
  let user_var2 = userId;
3661
- const backendUrl22 = `https://staging-demoapi.rivia.ai/banners_clients/${bannerId2}`;
3661
+ const backendUrl22 = `https://demoapi.rivia.ai/banners_clients/${bannerId2}`;
3662
3662
  try {
3663
3663
  const payload = {
3664
3664
  name: user_var2,
@@ -3978,7 +3978,7 @@ async function Banner(workspace_id, obj) {
3978
3978
  };
3979
3979
  var doesRouteMatch = doesRouteMatch2, escapeRegex = escapeRegex2, buildContext = buildContext2;
3980
3980
  const res = await fetch(
3981
- `https://staging-demoapi.rivia.ai/banner_by_workspace2/${workspace_id}`,
3981
+ `https://demoapi.rivia.ai/banner_by_workspace2/${workspace_id}`,
3982
3982
  {
3983
3983
  method: "GET",
3984
3984
  headers: { "Content-Type": "application/json" }
@@ -4124,15 +4124,375 @@ var triggerEvent = async (message) => {
4124
4124
  }
4125
4125
  };
4126
4126
 
4127
+ // src/utils/canny.js
4128
+ var CannyLite = /* @__PURE__ */ function() {
4129
+ const defaults = {
4130
+ apiUrl: "/api/changelog",
4131
+ // backend endpoint to fetch changelog JSON (base URL)
4132
+ appID: null,
4133
+ authToken: null,
4134
+ // optional Authorization header
4135
+ buttonSelector: "[data-canny-changelog]",
4136
+ position: "bottom",
4137
+ // or 'top'
4138
+ align: "right",
4139
+ // or 'left' or 'center'
4140
+ theme: "light",
4141
+ // light | dark | auto
4142
+ initialData: null,
4143
+ // optional pre-fetched object to avoid network call
4144
+ fetchOptions: {},
4145
+ // additional fetch options
4146
+ workspace: null,
4147
+ // optional workspace identifier to send to backend for multi-tenant support
4148
+ cannyUserId: null,
4149
+ // optional user identifier to send to backend for personalization
4150
+ name: "abc",
4151
+ user_avatar: null,
4152
+ url: "https://img.freepik.com/free-photo/closeup-scarlet-macaw-from-side-view-scarlet-macaw-closeup-head_488145-3540.jpg?semt=ais_hybrid&w=740&q=80",
4153
+ email: "priyanshu@yopmail.com"
4154
+ };
4155
+ const state = {
4156
+ initialized: false,
4157
+ config: {},
4158
+ widgetEl: null,
4159
+ backdropEl: null,
4160
+ cannyUserId: null
4161
+ };
4162
+ function mergeConfig(cfg) {
4163
+ state.config = Object.assign({}, defaults, cfg || {});
4164
+ }
4165
+ function ensureStyles() {
4166
+ if (document.getElementById("canny-lite-styles")) return;
4167
+ const css = `
4168
+ .canny-lite-backdrop{position:fixed;inset:0;background:rgba(0,0,0,0.4);display:none;z-index:9998}
4169
+ .canny-lite-widget{position:fixed;z-index:9999;max-width:420px;width:clamp(280px,30vw,420px);box-shadow:0 10px 40px rgba(0,0,0,0.2);border-radius:12px;overflow:hidden;font-family:Inter,system-ui,Segoe UI,Roboto,Arial,sans-serif}
4170
+ .canny-lite-widget.light{background:#fff;color:#111}
4171
+ .canny-lite-widget.dark{background:#111;color:#eee}
4172
+ .canny-lite-header{padding:12px 16px;font-weight:600;border-bottom:1px solid rgba(0,0,0,0.06);position:relative}
4173
+ .canny-lite-badge{font-size:12px;margin-left:8px;color:rgba(0,0,0,0.6)}
4174
+ .canny-lite-body{max-height:60vh;overflow:auto;padding:12px 16px}
4175
+ .canny-lite-item{margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid rgba(0,0,0,0.04)}
4176
+ .canny-lite-item.unread{background:linear-gradient(90deg,rgba(255,245,235,0.6),transparent)}
4177
+ .canny-lite-close{position:absolute;right:8px;top:8px;border:none;background:transparent;font-size:16px;cursor:pointer}
4178
+ .canny-lite-tags{font-size:12px;opacity:0.8;margin-top:6px}
4179
+ .canny-lite-link{display:inline-block;margin-top:6px;font-size:13px}
4180
+ `;
4181
+ const style = document.createElement("style");
4182
+ style.id = "canny-lite-styles";
4183
+ style.appendChild(document.createTextNode(css));
4184
+ document.head.appendChild(style);
4185
+ }
4186
+ function createWidgetShell() {
4187
+ if (state.widgetEl) return;
4188
+ ensureStyles();
4189
+ const backdrop = document.createElement("div");
4190
+ backdrop.className = "canny-lite-backdrop";
4191
+ backdrop.addEventListener("click", closeWidget);
4192
+ const widget = document.createElement("div");
4193
+ widget.className = "canny-lite-widget " + (state.config.theme === "dark" ? "dark" : "light");
4194
+ widget.setAttribute("role", "dialog");
4195
+ const header = document.createElement("div");
4196
+ header.className = "canny-lite-header";
4197
+ header.innerText = "Changelog";
4198
+ const badge = document.createElement("span");
4199
+ badge.className = "canny-lite-badge";
4200
+ badge.style.display = "none";
4201
+ header.appendChild(badge);
4202
+ const closeBtn = document.createElement("button");
4203
+ closeBtn.className = "canny-lite-close";
4204
+ closeBtn.innerHTML = "\u2715";
4205
+ closeBtn.addEventListener("click", closeWidget);
4206
+ const body = document.createElement("div");
4207
+ body.className = "canny-lite-body";
4208
+ body.innerHTML = '<div class="canny-lite-loading">Loading\u2026</div>';
4209
+ const riviaBtn = document.createElement("button");
4210
+ riviaBtn.className = "canny-lite-rivia-btn";
4211
+ riviaBtn.innerText = "Open Rivia";
4212
+ riviaBtn.addEventListener("click", () => {
4213
+ const baseUrl = `http://${state.config.workspace}.rivia.ai/users/changelog?userId=${state.cannyUserId || ""}`;
4214
+ const url = new URL(baseUrl);
4215
+ window.open(url.toString(), "_blank");
4216
+ });
4217
+ widget.appendChild(header);
4218
+ widget.appendChild(closeBtn);
4219
+ widget.appendChild(riviaBtn);
4220
+ widget.appendChild(body);
4221
+ document.body.appendChild(backdrop);
4222
+ document.body.appendChild(widget);
4223
+ state.backdropEl = backdrop;
4224
+ state.widgetEl = widget;
4225
+ state.widgetBody = body;
4226
+ state.widgetHeader = header;
4227
+ state.widgetBadge = badge;
4228
+ positionWidget();
4229
+ window.addEventListener("resize", positionWidget);
4230
+ }
4231
+ function positionWidget() {
4232
+ if (!state.widgetEl) return;
4233
+ const { position, align } = state.config;
4234
+ const offset = 20;
4235
+ state.widgetEl.style.bottom = "";
4236
+ state.widgetEl.style.top = "";
4237
+ state.widgetEl.style.left = "";
4238
+ state.widgetEl.style.right = "";
4239
+ state.widgetEl.style.transform = "";
4240
+ if (position === "bottom") {
4241
+ state.widgetEl.style.bottom = offset + "px";
4242
+ } else {
4243
+ state.widgetEl.style.top = offset + "px";
4244
+ }
4245
+ if (align === "left") {
4246
+ state.widgetEl.style.left = offset + "px";
4247
+ } else if (align === "center") {
4248
+ state.widgetEl.style.left = "50%";
4249
+ state.widgetEl.style.transform = "translateX(-50%)";
4250
+ } else {
4251
+ state.widgetEl.style.right = offset + "px";
4252
+ }
4253
+ }
4254
+ async function fetchChangelog(id) {
4255
+ if (state.config.initialData) {
4256
+ const candidate = state.config.initialData.canny_integration ? state.config.initialData.canny_integration : state.config.initialData;
4257
+ if (candidate && (candidate.integration_id === id || candidate.id === id || candidate.integration_id === candidate.id && !id)) {
4258
+ return candidate;
4259
+ }
4260
+ }
4261
+ let urlStr = state.config.apiUrl || "";
4262
+ if (!urlStr) throw new Error("apiUrl is not configured");
4263
+ if (id) {
4264
+ if (urlStr.includes("{id}")) urlStr = urlStr.replace("{id}", encodeURIComponent(id));
4265
+ else if (urlStr.includes(":id")) urlStr = urlStr.replace(":id", encodeURIComponent(id));
4266
+ else urlStr = urlStr.replace(/\/$/, "") + "/" + encodeURIComponent(id);
4267
+ }
4268
+ try {
4269
+ const url = new URL(urlStr, window.location.origin);
4270
+ const headers = Object.assign({}, state.config.fetchOptions.headers || {});
4271
+ const opts = Object.assign({ method: "GET", headers }, state.config.fetchOptions);
4272
+ const res = await fetch(url.toString(), opts);
4273
+ if (!res.ok) throw new Error("Failed to fetch changelog: " + res.status + " " + res.statusText);
4274
+ const payload = await res.json();
4275
+ const data = payload && payload.canny_integration ? payload.canny_integration : payload;
4276
+ return data;
4277
+ } catch (err) {
4278
+ throw err;
4279
+ }
4280
+ }
4281
+ function renderChangelog(data) {
4282
+ if (!state.widgetBody) return;
4283
+ state.widgetHeader.childNodes[0] && (state.widgetHeader.childNodes[0].nodeValue = data.title || "Changelog");
4284
+ if (typeof data.unread_count === "number" && data.unread_count > 0) {
4285
+ state.widgetBadge.style.display = "inline-block";
4286
+ state.widgetBadge.innerText = `(${data.unread_count} new)`;
4287
+ } else {
4288
+ state.widgetBadge.style.display = "none";
4289
+ }
4290
+ const items = data.items || [];
4291
+ if (!items.length) {
4292
+ state.widgetBody.innerHTML = '<div class="canny-lite-empty">No updates yet.</div>';
4293
+ return;
4294
+ }
4295
+ const frag = document.createDocumentFragment();
4296
+ items.forEach((it) => {
4297
+ const div = document.createElement("div");
4298
+ const unreadClass = it.is_read === false ? " unread" : "";
4299
+ div.className = "canny-lite-item" + unreadClass;
4300
+ const header = document.createElement("div");
4301
+ header.style.fontWeight = "600";
4302
+ header.innerText = (it.version || "") + (it.date ? ` \xB7 ${it.date}` : "");
4303
+ const content = document.createElement("div");
4304
+ content.innerHTML = escapeHtml(it.content || it.text || "");
4305
+ div.appendChild(header);
4306
+ div.appendChild(content);
4307
+ if (Array.isArray(it.tags) && it.tags.length) {
4308
+ const tags = document.createElement("div");
4309
+ tags.className = "canny-lite-tags";
4310
+ tags.innerHTML = it.tags.map((t) => `<span>#${escapeHtml(t)}</span>`).join(" ");
4311
+ div.appendChild(tags);
4312
+ }
4313
+ if (it.url) {
4314
+ const a = document.createElement("a");
4315
+ a.className = "canny-lite-link";
4316
+ a.href = it.url;
4317
+ a.target = "_blank";
4318
+ a.rel = "noopener noreferrer";
4319
+ a.innerText = "Read more";
4320
+ div.appendChild(a);
4321
+ }
4322
+ frag.appendChild(div);
4323
+ });
4324
+ state.widgetBody.innerHTML = "";
4325
+ state.widgetBody.appendChild(frag);
4326
+ }
4327
+ function escapeHtml(str) {
4328
+ if (!str) return "";
4329
+ return String(str).replace(/[&<>\"']/g, function(s) {
4330
+ return { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[s];
4331
+ });
4332
+ }
4333
+ function showWidget() {
4334
+ if (!state.widgetEl) createWidgetShell();
4335
+ state.backdropEl.style.display = "block";
4336
+ state.widgetEl.style.display = "block";
4337
+ }
4338
+ function closeWidget() {
4339
+ if (!state.widgetEl) return;
4340
+ state.backdropEl.style.display = "none";
4341
+ state.widgetEl.style.display = "none";
4342
+ }
4343
+ function computePlacement(triggerRect, widgetRect, cfg) {
4344
+ const offset = cfg && cfg.attachOffset || 8;
4345
+ const vw = window.innerWidth;
4346
+ const vh = window.innerHeight;
4347
+ let top = triggerRect.bottom + offset;
4348
+ let left;
4349
+ const align = cfg && cfg.align ? cfg.align : state.config.align || "right";
4350
+ if (align === "left") {
4351
+ left = triggerRect.left;
4352
+ } else if (align === "center") {
4353
+ left = triggerRect.left + triggerRect.width / 2 - widgetRect.width / 2;
4354
+ } else {
4355
+ left = triggerRect.right - widgetRect.width;
4356
+ }
4357
+ if (top + widgetRect.height > vh) {
4358
+ top = triggerRect.top - widgetRect.height - offset;
4359
+ }
4360
+ if (top < 6) top = 6;
4361
+ const margin = 6;
4362
+ if (left + widgetRect.width > vw - margin) left = vw - widgetRect.width - margin;
4363
+ if (left < margin) left = margin;
4364
+ return { top, left };
4365
+ }
4366
+ async function openWidgetFor(id) {
4367
+ try {
4368
+ showWidget();
4369
+ state.widgetBody.innerHTML = '<div class="canny-lite-loading">Loading\u2026</div>';
4370
+ const data = await fetchChangelog(id);
4371
+ renderChangelog(data);
4372
+ const active = document.activeElement;
4373
+ const selector = state.config.buttonSelector || "[data-canny-changelog]";
4374
+ const isTrigger = active && active instanceof Element && active.matches && active.matches(selector);
4375
+ if (isTrigger) {
4376
+ state.widgetEl.style.visibility = "hidden";
4377
+ state.widgetEl.style.display = "block";
4378
+ await new Promise((r) => requestAnimationFrame(r));
4379
+ const widgetRect = state.widgetEl.getBoundingClientRect();
4380
+ const triggerRect = active.getBoundingClientRect();
4381
+ const { top, left } = computePlacement(triggerRect, widgetRect, state.config);
4382
+ state.widgetEl.style.position = "fixed";
4383
+ state.widgetEl.style.top = Math.round(top) + "px";
4384
+ state.widgetEl.style.left = Math.round(left) + "px";
4385
+ state.widgetEl.style.right = "auto";
4386
+ state.widgetEl.style.bottom = "auto";
4387
+ state.widgetEl.style.transform = "none";
4388
+ state.widgetEl.style.visibility = "visible";
4389
+ } else {
4390
+ positionWidget();
4391
+ }
4392
+ } catch (err) {
4393
+ state.widgetBody.innerHTML = `<div class="canny-lite-error">Error loading changelog: ${escapeHtml(err.message)}</div>`;
4394
+ console.error(err);
4395
+ }
4396
+ }
4397
+ function bindClicks() {
4398
+ document.addEventListener("click", function onDocClick(e) {
4399
+ const el = e.target.closest(state.config.buttonSelector);
4400
+ if (!el) return;
4401
+ e.preventDefault();
4402
+ if (el.hasAttribute("data-canny-changelog")) {
4403
+ const baseUrl = `http://${state.config.workspace}.rivia.ai/users/changelog?userId=${state.cannyUserId || ""}`;
4404
+ const url = new URL(baseUrl);
4405
+ window.open(url.toString(), "_blank");
4406
+ }
4407
+ });
4408
+ }
4409
+ async function syncUserFromConfig() {
4410
+ const cfg = state.config;
4411
+ if (!cfg.workspace || !cfg.email) {
4412
+ console.warn("CannyLite: workspace/email missing, skipping user sync");
4413
+ return;
4414
+ }
4415
+ const payload = {
4416
+ workspace: cfg.workspace,
4417
+ cannyUserId: cfg.cannyUserId,
4418
+ name: cfg.name,
4419
+ email: cfg.email,
4420
+ user_avatar: cfg.user_avatar,
4421
+ url: cfg.url
4422
+ };
4423
+ try {
4424
+ const res = await fetch(cfg.userApiUrl, {
4425
+ method: "POST",
4426
+ headers: {
4427
+ "Content-Type": "application/json"
4428
+ },
4429
+ body: JSON.stringify(payload)
4430
+ });
4431
+ if (!res.ok) {
4432
+ throw new Error(`Failed to sync user (${res.status})`);
4433
+ }
4434
+ const data = await res.json();
4435
+ if (data?.canny_user?.canny_user_id) {
4436
+ state.cannyUserId = data.canny_user.canny_user_id;
4437
+ } else {
4438
+ state.cannyUserId = cfg.canny_user_id;
4439
+ }
4440
+ } catch (err) {
4441
+ console.error("CannyLite user sync failed:", err);
4442
+ }
4443
+ }
4444
+ function init(cfg) {
4445
+ if (state.initialized) {
4446
+ console.warn("CannyLite already initialized \u2014 ignoring subsequent init call.");
4447
+ return;
4448
+ }
4449
+ mergeConfig(cfg);
4450
+ syncUserFromConfig();
4451
+ bindClicks();
4452
+ state.initialized = true;
4453
+ }
4454
+ function setConfig(cfg) {
4455
+ mergeConfig(Object.assign({}, state.config, cfg));
4456
+ if (state.widgetEl) {
4457
+ state.widgetEl.className = "canny-lite-widget " + (state.config.theme === "dark" ? "dark" : "light");
4458
+ positionWidget();
4459
+ }
4460
+ }
4461
+ function attachButton(selector) {
4462
+ state.config.buttonSelector = selector;
4463
+ }
4464
+ function destroy() {
4465
+ if (state.widgetEl) state.widgetEl.remove();
4466
+ if (state.backdropEl) state.backdropEl.remove();
4467
+ const style = document.getElementById("canny-lite-styles");
4468
+ if (style) style.remove();
4469
+ state.widgetEl = null;
4470
+ state.backdropEl = null;
4471
+ state.initialized = false;
4472
+ }
4473
+ return {
4474
+ init,
4475
+ open: openWidgetFor,
4476
+ close: closeWidget,
4477
+ setConfig,
4478
+ attachButton,
4479
+ destroy
4480
+ };
4481
+ }();
4482
+ if (typeof window !== "undefined") window.CannyLite = CannyLite;
4483
+ var canny_default = CannyLite;
4484
+
4127
4485
  // src/utils/index.js
4128
4486
  if (typeof window !== "undefined") {
4129
4487
  window.Checklist = rivia_default;
4130
4488
  window.Tours = rivia_tour_default;
4131
4489
  window.Banner = banner_default;
4132
4490
  window.triggerEvent = triggerEvent;
4491
+ window.CannyLite = canny_default;
4133
4492
  }
4134
4493
  export {
4135
4494
  banner_default as Banner,
4495
+ canny_default as CannyLite,
4136
4496
  rivia_default as Checklist,
4137
4497
  rivia_tour_default as Tours,
4138
4498
  triggerEvent
package/index.d.ts CHANGED
@@ -24,8 +24,30 @@ declare global {
24
24
  }
25
25
  }
26
26
 
27
+ export type CannyLiteTheme = "light" | "dark" | "auto";
28
+ export type CannyLitePosition = "top" | "bottom";
29
+ export type CannyLiteAlign = "left" | "right" | "center";
30
+
31
+ export interface CannyLiteConfig {
32
+ apiUrl: string;
33
+ appID: string;
34
+ authToken?: string;
35
+ position?: CannyLitePosition;
36
+ align?: CannyLiteAlign;
37
+ theme?: CannyLiteTheme;
38
+ }
39
+
40
+ declare function CannyLite(): {
41
+ init(config: CannyLiteConfig): void;
42
+ open(id?: string): void;
43
+ close(): void;
44
+ setConfig(config: Partial<CannyLiteConfig>): void;
45
+ attachButton(): void;
46
+ destroy(): void;
47
+ };
48
+
27
49
  declare function Tours(tourId: string, userId: string): void ;
28
- export { Checklist,Banner, Tours };
50
+ export { Checklist,Banner, Tours, CannyLite};
29
51
 
30
52
  // declare function Checklist(
31
53
  // checklist_id: string,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rivia",
3
- "version": "0.0.83",
3
+ "version": "0.0.85",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",