@crediball/elements 0.4.0 → 0.4.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.
|
@@ -1,30 +1,9 @@
|
|
|
1
1
|
// src/base.ts
|
|
2
2
|
import {
|
|
3
|
-
getCrediballClient
|
|
3
|
+
getCrediballClient,
|
|
4
|
+
loadRemoteFont,
|
|
5
|
+
themeToCssVars
|
|
4
6
|
} from "@crediball/core";
|
|
5
|
-
var THEME_VARS = [
|
|
6
|
-
["accent", "--crediball-accent", String],
|
|
7
|
-
["onAccent", "--crediball-on-accent", String],
|
|
8
|
-
["ink", "--crediball-ink", String],
|
|
9
|
-
["canvas", "--crediball-canvas", String],
|
|
10
|
-
["hairline", "--crediball-hairline", String],
|
|
11
|
-
["radius", "--crediball-radius", (v) => `${v}px`],
|
|
12
|
-
["radiusCard", "--crediball-radius-card", (v) => `${v}px`],
|
|
13
|
-
["fontStack", "--crediball-font", String]
|
|
14
|
-
];
|
|
15
|
-
function loadRemoteFont(url) {
|
|
16
|
-
if (typeof document === "undefined") return;
|
|
17
|
-
const existing = document.querySelector("link[data-crediball-font]");
|
|
18
|
-
if (existing?.href === url) return;
|
|
19
|
-
if (existing) existing.href = url;
|
|
20
|
-
else {
|
|
21
|
-
const link = document.createElement("link");
|
|
22
|
-
link.rel = "stylesheet";
|
|
23
|
-
link.href = url;
|
|
24
|
-
link.setAttribute("data-crediball-font", "");
|
|
25
|
-
document.head.appendChild(link);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
7
|
var _CrediballElement = class _CrediballElement extends HTMLElement {
|
|
29
8
|
constructor() {
|
|
30
9
|
super(...arguments);
|
|
@@ -85,9 +64,8 @@ var _CrediballElement = class _CrediballElement extends HTMLElement {
|
|
|
85
64
|
if (this.getAttribute("apply-remote-theme") === "false") return;
|
|
86
65
|
const theme = this.getSnapshot()?.packages?.ui?.theme;
|
|
87
66
|
if (!theme) return;
|
|
88
|
-
for (const [
|
|
89
|
-
|
|
90
|
-
if (value != null && value !== "") this.style.setProperty(cssVar, fmt(value));
|
|
67
|
+
for (const [cssVar, value] of Object.entries(themeToCssVars(theme))) {
|
|
68
|
+
this.style.setProperty(cssVar, value);
|
|
91
69
|
}
|
|
92
70
|
if (theme.fontUrl) loadRemoteFont(theme.fontUrl);
|
|
93
71
|
}
|
|
@@ -110,9 +88,7 @@ _CrediballElement.CLIENT_ATTRS = /* @__PURE__ */ new Set([
|
|
|
110
88
|
var CrediballElement = _CrediballElement;
|
|
111
89
|
|
|
112
90
|
// src/format.ts
|
|
113
|
-
|
|
114
|
-
return new Intl.NumberFormat(void 0).format(Math.round(credits));
|
|
115
|
-
}
|
|
91
|
+
import { formatCredits } from "@crediball/core";
|
|
116
92
|
|
|
117
93
|
// src/balance.ts
|
|
118
94
|
var CrediballBalanceElement = class extends CrediballElement {
|
|
@@ -186,6 +162,7 @@ var CrediballTopUpButtonElement = class extends CrediballElement {
|
|
|
186
162
|
};
|
|
187
163
|
|
|
188
164
|
// src/low-credit-warning.ts
|
|
165
|
+
import { isBalanceLow } from "@crediball/core";
|
|
189
166
|
var CrediballLowCreditWarningElement = class extends CrediballElement {
|
|
190
167
|
static get observedAttributes() {
|
|
191
168
|
return [...CrediballElement.observedAttributes, "threshold"];
|
|
@@ -200,7 +177,7 @@ var CrediballLowCreditWarningElement = class extends CrediballElement {
|
|
|
200
177
|
const content = snapshot?.packages?.ui?.content;
|
|
201
178
|
const thresholdAttr = this.getAttribute("threshold");
|
|
202
179
|
const threshold = thresholdAttr != null ? Number(thresholdAttr) : content?.lowCreditThreshold;
|
|
203
|
-
const isLow =
|
|
180
|
+
const isLow = isBalanceLow(snapshot?.balance ?? null, threshold, !!snapshot?.isLow);
|
|
204
181
|
this.style.display = isLow ? "" : "none";
|
|
205
182
|
const slot = this.shadowRoot?.querySelector("slot");
|
|
206
183
|
if (slot) slot.textContent = content?.lowCreditMessage ?? "Low credit balance \u2014 top up to keep going.";
|
|
@@ -208,13 +185,7 @@ var CrediballLowCreditWarningElement = class extends CrediballElement {
|
|
|
208
185
|
};
|
|
209
186
|
|
|
210
187
|
// src/paywall.ts
|
|
211
|
-
|
|
212
|
-
try {
|
|
213
|
-
return new Intl.NumberFormat(void 0, { style: "currency", currency }).format(amount);
|
|
214
|
-
} catch {
|
|
215
|
-
return `${amount.toFixed(2)} ${currency}`;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
188
|
+
import { formatMoney } from "@crediball/core";
|
|
218
189
|
var CURRENCY_SYMBOLS = { EUR: "\u20AC", USD: "$", GBP: "\xA3" };
|
|
219
190
|
function currencySymbolFor(currency) {
|
|
220
191
|
return CURRENCY_SYMBOLS[currency.toUpperCase()] ?? currency;
|
|
@@ -68,8 +68,21 @@ var Crediball = (() => {
|
|
|
68
68
|
return () => window.removeEventListener(BALANCE_CHANGED_EVENT, listener);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
// ../core/dist/
|
|
71
|
+
// ../core/dist/http.js
|
|
72
72
|
var DEFAULT_API_URL = "https://www.crediball.ai/api";
|
|
73
|
+
async function errorMessage(res, fallback) {
|
|
74
|
+
const body = await res.json().catch(() => null);
|
|
75
|
+
return body && typeof body === "object" && "error" in body && String(body.error) || fallback;
|
|
76
|
+
}
|
|
77
|
+
async function fetchJson(url, init, failureLabel = `Request to ${url}`) {
|
|
78
|
+
const res = await fetch(url, init);
|
|
79
|
+
if (!res.ok) {
|
|
80
|
+
throw new Error(await errorMessage(res, `${failureLabel} failed with ${res.status}`));
|
|
81
|
+
}
|
|
82
|
+
return res.json();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ../core/dist/client.js
|
|
73
86
|
var DEFAULT_POLL_MS = 3e4;
|
|
74
87
|
var SSE_HEALTHY_POLL_MULTIPLIER = 2;
|
|
75
88
|
var MAX_SSE_FAILURES = 2;
|
|
@@ -85,15 +98,6 @@ var Crediball = (() => {
|
|
|
85
98
|
error: null
|
|
86
99
|
};
|
|
87
100
|
}
|
|
88
|
-
async function fetchJson(url, headers) {
|
|
89
|
-
const res = await fetch(url, { headers });
|
|
90
|
-
if (!res.ok) {
|
|
91
|
-
const body = await res.json().catch(() => null);
|
|
92
|
-
const message = body && typeof body === "object" && "error" in body && String(body.error) || `Request to ${url} failed with ${res.status}`;
|
|
93
|
-
throw new Error(message);
|
|
94
|
-
}
|
|
95
|
-
return res.json();
|
|
96
|
-
}
|
|
97
101
|
function computeIsLow(balance, costs, explicitThreshold) {
|
|
98
102
|
if (balance == null)
|
|
99
103
|
return false;
|
|
@@ -134,10 +138,10 @@ var Crediball = (() => {
|
|
|
134
138
|
const qs = `userId=${encodeURIComponent(userId)}`;
|
|
135
139
|
try {
|
|
136
140
|
const [balanceRes, usageRes, costsRes, packagesRes] = await Promise.all([
|
|
137
|
-
fetchJson(`${this.apiUrl}/public/balance?${qs}`, headers),
|
|
138
|
-
fetchJson(`${this.apiUrl}/public/usage?${qs}`, headers),
|
|
139
|
-
fetchJson(`${this.apiUrl}/public/costs`, headers),
|
|
140
|
-
fetchJson(`${this.apiUrl}/public/packages?${qs}`, headers)
|
|
141
|
+
fetchJson(`${this.apiUrl}/public/balance?${qs}`, { headers }),
|
|
142
|
+
fetchJson(`${this.apiUrl}/public/usage?${qs}`, { headers }),
|
|
143
|
+
fetchJson(`${this.apiUrl}/public/costs`, { headers }),
|
|
144
|
+
fetchJson(`${this.apiUrl}/public/packages?${qs}`, { headers })
|
|
141
145
|
]);
|
|
142
146
|
const costs = {};
|
|
143
147
|
for (const e of costsRes.events)
|
|
@@ -188,22 +192,16 @@ var Crediball = (() => {
|
|
|
188
192
|
this.apiUrl = (config.apiUrl ?? DEFAULT_API_URL).replace(/\/$/, "");
|
|
189
193
|
this.pollIntervalMs = config.pollIntervalMs ?? DEFAULT_POLL_MS;
|
|
190
194
|
}
|
|
191
|
-
|
|
195
|
+
postCheckout(path, input) {
|
|
192
196
|
const { publishableKey, userId } = this.config;
|
|
193
|
-
|
|
197
|
+
return fetchJson(`${this.apiUrl}${path}`, {
|
|
194
198
|
method: "POST",
|
|
195
199
|
headers: {
|
|
196
200
|
"Content-Type": "application/json",
|
|
197
201
|
Authorization: `Bearer ${publishableKey}`
|
|
198
202
|
},
|
|
199
203
|
body: JSON.stringify({ userId, ...input })
|
|
200
|
-
});
|
|
201
|
-
if (!res.ok) {
|
|
202
|
-
const body = await res.json().catch(() => null);
|
|
203
|
-
const message = body && typeof body === "object" && "error" in body && String(body.error) || `Checkout request failed with ${res.status}`;
|
|
204
|
-
throw new Error(message);
|
|
205
|
-
}
|
|
206
|
-
return res.json();
|
|
204
|
+
}, "Checkout request");
|
|
207
205
|
}
|
|
208
206
|
pause() {
|
|
209
207
|
this.stopPolling();
|
|
@@ -303,8 +301,23 @@ var Crediball = (() => {
|
|
|
303
301
|
return client;
|
|
304
302
|
}
|
|
305
303
|
|
|
306
|
-
//
|
|
307
|
-
|
|
304
|
+
// ../core/dist/format.js
|
|
305
|
+
function formatCredits(credits) {
|
|
306
|
+
return new Intl.NumberFormat(void 0).format(Math.round(credits));
|
|
307
|
+
}
|
|
308
|
+
function formatMoney(amount, currency) {
|
|
309
|
+
try {
|
|
310
|
+
return new Intl.NumberFormat(void 0, { style: "currency", currency }).format(amount);
|
|
311
|
+
} catch {
|
|
312
|
+
return `${amount.toFixed(2)} ${currency}`;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function isBalanceLow(balance, threshold, fallback) {
|
|
316
|
+
return threshold != null && balance != null ? balance < threshold : fallback;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// ../core/dist/theme.js
|
|
320
|
+
var THEME_CSS_VAR_ENTRIES = [
|
|
308
321
|
["accent", "--crediball-accent", String],
|
|
309
322
|
["onAccent", "--crediball-on-accent", String],
|
|
310
323
|
["ink", "--crediball-ink", String],
|
|
@@ -314,11 +327,25 @@ var Crediball = (() => {
|
|
|
314
327
|
["radiusCard", "--crediball-radius-card", (v) => `${v}px`],
|
|
315
328
|
["fontStack", "--crediball-font", String]
|
|
316
329
|
];
|
|
330
|
+
function themeToCssVars(theme) {
|
|
331
|
+
const vars = {};
|
|
332
|
+
if (!theme)
|
|
333
|
+
return vars;
|
|
334
|
+
for (const [key, cssVar, fmt] of THEME_CSS_VAR_ENTRIES) {
|
|
335
|
+
const value = theme[key];
|
|
336
|
+
if (value != null && value !== "")
|
|
337
|
+
vars[cssVar] = fmt(value);
|
|
338
|
+
}
|
|
339
|
+
return vars;
|
|
340
|
+
}
|
|
317
341
|
function loadRemoteFont(url) {
|
|
318
|
-
if (typeof document === "undefined")
|
|
342
|
+
if (typeof document === "undefined")
|
|
343
|
+
return;
|
|
319
344
|
const existing = document.querySelector("link[data-crediball-font]");
|
|
320
|
-
if (existing?.href === url)
|
|
321
|
-
|
|
345
|
+
if (existing?.href === url)
|
|
346
|
+
return;
|
|
347
|
+
if (existing)
|
|
348
|
+
existing.href = url;
|
|
322
349
|
else {
|
|
323
350
|
const link = document.createElement("link");
|
|
324
351
|
link.rel = "stylesheet";
|
|
@@ -327,6 +354,8 @@ var Crediball = (() => {
|
|
|
327
354
|
document.head.appendChild(link);
|
|
328
355
|
}
|
|
329
356
|
}
|
|
357
|
+
|
|
358
|
+
// src/base.ts
|
|
330
359
|
var _CrediballElement = class _CrediballElement extends HTMLElement {
|
|
331
360
|
constructor() {
|
|
332
361
|
super(...arguments);
|
|
@@ -387,9 +416,8 @@ var Crediball = (() => {
|
|
|
387
416
|
if (this.getAttribute("apply-remote-theme") === "false") return;
|
|
388
417
|
const theme = this.getSnapshot()?.packages?.ui?.theme;
|
|
389
418
|
if (!theme) return;
|
|
390
|
-
for (const [
|
|
391
|
-
|
|
392
|
-
if (value != null && value !== "") this.style.setProperty(cssVar, fmt(value));
|
|
419
|
+
for (const [cssVar, value] of Object.entries(themeToCssVars(theme))) {
|
|
420
|
+
this.style.setProperty(cssVar, value);
|
|
393
421
|
}
|
|
394
422
|
if (theme.fontUrl) loadRemoteFont(theme.fontUrl);
|
|
395
423
|
}
|
|
@@ -411,11 +439,6 @@ var Crediball = (() => {
|
|
|
411
439
|
]);
|
|
412
440
|
var CrediballElement = _CrediballElement;
|
|
413
441
|
|
|
414
|
-
// src/format.ts
|
|
415
|
-
function formatCredits(credits) {
|
|
416
|
-
return new Intl.NumberFormat(void 0).format(Math.round(credits));
|
|
417
|
-
}
|
|
418
|
-
|
|
419
442
|
// src/balance.ts
|
|
420
443
|
var CrediballBalanceElement = class extends CrediballElement {
|
|
421
444
|
constructor() {
|
|
@@ -502,7 +525,7 @@ var Crediball = (() => {
|
|
|
502
525
|
const content = snapshot?.packages?.ui?.content;
|
|
503
526
|
const thresholdAttr = this.getAttribute("threshold");
|
|
504
527
|
const threshold = thresholdAttr != null ? Number(thresholdAttr) : content?.lowCreditThreshold;
|
|
505
|
-
const isLow =
|
|
528
|
+
const isLow = isBalanceLow(snapshot?.balance ?? null, threshold, !!snapshot?.isLow);
|
|
506
529
|
this.style.display = isLow ? "" : "none";
|
|
507
530
|
const slot = this.shadowRoot?.querySelector("slot");
|
|
508
531
|
if (slot) slot.textContent = content?.lowCreditMessage ?? "Low credit balance \u2014 top up to keep going.";
|
|
@@ -510,13 +533,6 @@ var Crediball = (() => {
|
|
|
510
533
|
};
|
|
511
534
|
|
|
512
535
|
// src/paywall.ts
|
|
513
|
-
function formatMoney(amount, currency) {
|
|
514
|
-
try {
|
|
515
|
-
return new Intl.NumberFormat(void 0, { style: "currency", currency }).format(amount);
|
|
516
|
-
} catch {
|
|
517
|
-
return `${amount.toFixed(2)} ${currency}`;
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
536
|
var CURRENCY_SYMBOLS = { EUR: "\u20AC", USD: "$", GBP: "\xA3" };
|
|
521
537
|
function currencySymbolFor(currency) {
|
|
522
538
|
return CURRENCY_SYMBOLS[currency.toUpperCase()] ?? currency;
|
package/dist/index.js
CHANGED
package/dist/register.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crediball/elements",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Framework-agnostic web components for showing Crediball credits inside your AI app.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Filippo Rezzadore <filipporezzadore@gmail.com>",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"prepublishOnly": "npm run build"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@crediball/core": "^0.
|
|
59
|
+
"@crediball/core": "^0.4.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"tsup": "^8.3.5",
|