@refraction-ui/react 0.19.1 → 0.20.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/chunk-533MCMSU.js +2355 -0
- package/dist/chunk-533MCMSU.js.map +7 -0
- package/dist/chunk-AMK4VCBG.js +250 -0
- package/dist/chunk-AMK4VCBG.js.map +7 -0
- package/dist/chunk-BOLFYVI6.js +90 -0
- package/dist/chunk-BOLFYVI6.js.map +7 -0
- package/dist/chunk-F7B64KT3.js +187 -0
- package/dist/chunk-F7B64KT3.js.map +7 -0
- package/dist/chunk-FD37DFCC.js +77 -0
- package/dist/chunk-FD37DFCC.js.map +7 -0
- package/dist/chunk-H54FLNAF.js +132 -0
- package/dist/chunk-H54FLNAF.js.map +7 -0
- package/dist/chunk-INP46354.js +664 -0
- package/dist/chunk-INP46354.js.map +7 -0
- package/dist/chunk-ONACRMG4.js +116 -0
- package/dist/chunk-ONACRMG4.js.map +7 -0
- package/dist/chunk-SDZ3LROZ.js +7 -0
- package/dist/chunk-SDZ3LROZ.js.map +7 -0
- package/dist/chunk-TOZBR4GL.js +154 -0
- package/dist/chunk-TOZBR4GL.js.map +7 -0
- package/dist/chunk-UNEM2TRI.js +225 -0
- package/dist/chunk-UNEM2TRI.js.map +7 -0
- package/dist/chunk-VK3EQ34F.js +92 -0
- package/dist/chunk-VK3EQ34F.js.map +7 -0
- package/dist/chunk-WK2IIUFO.js +316 -0
- package/dist/chunk-WK2IIUFO.js.map +7 -0
- package/dist/chunk-WSPJTQAV.js +59 -0
- package/dist/chunk-WSPJTQAV.js.map +7 -0
- package/dist/chunk-XWP763SH.js +3 -2
- package/dist/chunk-XWP763SH.js.map +7 -1
- package/dist/chunk-Y2FNNAIL.js +80 -0
- package/dist/chunk-Y2FNNAIL.js.map +1 -0
- package/dist/{chunk-4A4BW3GR.js → chunk-ZF3OHCGV.js} +28 -5
- package/dist/chunk-ZF3OHCGV.js.map +7 -0
- package/dist/form.cjs +5 -11
- package/dist/form.cjs.map +1 -1
- package/dist/form.js +6 -12
- package/dist/form.js.map +1 -1
- package/dist/index.cjs +2879 -33936
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +126 -28780
- package/dist/internal/react-app-shell/index.d.cts +2 -22
- package/dist/internal/react-app-shell/index.d.ts +2 -22
- package/dist/internal/react-badge/index.d.cts +5 -0
- package/dist/internal/react-badge/index.d.ts +5 -0
- package/dist/internal/react-callout/index.d.cts +4 -0
- package/dist/internal/react-callout/index.d.ts +4 -0
- package/dist/internal/react-card/index.d.cts +8 -1
- package/dist/internal/react-card/index.d.ts +8 -1
- package/dist/internal/react-collapsible/index.d.cts +0 -3
- package/dist/internal/react-collapsible/index.d.ts +0 -3
- package/dist/internal/react-combobox/index.d.cts +0 -3
- package/dist/internal/react-combobox/index.d.ts +0 -3
- package/dist/internal/react-command/index.d.cts +0 -3
- package/dist/internal/react-command/index.d.ts +0 -3
- package/dist/internal/react-data-table/index.d.cts +0 -3
- package/dist/internal/react-data-table/index.d.ts +0 -3
- package/dist/internal/react-dialog/index.d.cts +0 -3
- package/dist/internal/react-dialog/index.d.ts +0 -3
- package/dist/internal/react-dropdown-menu/index.d.cts +0 -3
- package/dist/internal/react-dropdown-menu/index.d.ts +0 -3
- package/dist/internal/react-feedback-dialog/index.d.cts +0 -3
- package/dist/internal/react-feedback-dialog/index.d.ts +0 -3
- package/dist/internal/react-form/index.d.cts +2 -21
- package/dist/internal/react-form/index.d.ts +2 -21
- package/dist/internal/react-keyboard-shortcut/index.d.cts +0 -6
- package/dist/internal/react-keyboard-shortcut/index.d.ts +0 -6
- package/dist/internal/react-link-card/index.d.cts +8 -2
- package/dist/internal/react-link-card/index.d.ts +8 -2
- package/dist/internal/react-popover/index.d.cts +0 -3
- package/dist/internal/react-popover/index.d.ts +0 -3
- package/dist/internal/react-sheet/index.d.cts +0 -3
- package/dist/internal/react-sheet/index.d.ts +0 -3
- package/dist/internal/react-slot/index.d.cts +23 -0
- package/dist/internal/react-slot/index.d.ts +23 -0
- package/dist/internal/react-toast/index.d.cts +0 -3
- package/dist/internal/react-toast/index.d.ts +0 -3
- package/dist/internal/react-tooltip/index.d.cts +0 -3
- package/dist/internal/react-tooltip/index.d.ts +0 -3
- package/dist/react-accordion.js +125 -0
- package/dist/react-accordion.js.map +7 -0
- package/dist/react-ai.js +257 -0
- package/dist/react-ai.js.map +7 -0
- package/dist/react-analytics.js +1698 -0
- package/dist/react-analytics.js.map +7 -0
- package/dist/react-animated-text.js +164 -0
- package/dist/react-animated-text.js.map +7 -0
- package/dist/react-app-shell.js +631 -0
- package/dist/react-app-shell.js.map +7 -0
- package/dist/react-audience-feature-card.js +53 -0
- package/dist/react-audience-feature-card.js.map +7 -0
- package/dist/react-audio-room.js +166 -0
- package/dist/react-audio-room.js.map +7 -0
- package/dist/react-auth.js +211 -0
- package/dist/react-auth.js.map +7 -0
- package/dist/react-avatar-group.js +154 -0
- package/dist/react-avatar-group.js.map +7 -0
- package/dist/react-avatar.js +168 -0
- package/dist/react-avatar.js.map +7 -0
- package/dist/react-badge.js +86 -0
- package/dist/react-badge.js.map +7 -0
- package/dist/react-bottom-nav.js +67 -0
- package/dist/react-bottom-nav.js.map +7 -0
- package/dist/react-brand-network-cell.js +92 -0
- package/dist/react-brand-network-cell.js.map +7 -0
- package/dist/react-breadcrumbs.js +104 -0
- package/dist/react-breadcrumbs.js.map +7 -0
- package/dist/react-browser-chrome-mock.js +89 -0
- package/dist/react-browser-chrome-mock.js.map +7 -0
- package/dist/react-button.js +13 -0
- package/dist/react-button.js.map +7 -0
- package/dist/react-calendar.js +301 -0
- package/dist/react-calendar.js.map +7 -0
- package/dist/react-call-controls.js +113 -0
- package/dist/react-call-controls.js.map +7 -0
- package/dist/react-callout.js +152 -0
- package/dist/react-callout.js.map +7 -0
- package/dist/react-card-grid.js +34 -0
- package/dist/react-card-grid.js.map +7 -0
- package/dist/react-card.js +200 -0
- package/dist/react-card.js.map +7 -0
- package/dist/react-carousel.js +132 -0
- package/dist/react-carousel.js.map +7 -0
- package/dist/react-charts.js +509 -0
- package/dist/react-charts.js.map +7 -0
- package/dist/react-checkbox.js +156 -0
- package/dist/react-checkbox.js.map +7 -0
- package/dist/react-checklist.js +168 -0
- package/dist/react-checklist.js.map +7 -0
- package/dist/react-code-block.js +78 -0
- package/dist/react-code-block.js.map +7 -0
- package/dist/react-code-editor.js +184 -0
- package/dist/react-code-editor.js.map +7 -0
- package/dist/react-collapsible.js +192 -0
- package/dist/react-collapsible.js.map +7 -0
- package/dist/react-combobox.js +609 -0
- package/dist/react-combobox.js.map +7 -0
- package/dist/react-command-input.js +202 -0
- package/dist/react-command-input.js.map +7 -0
- package/dist/react-command.js +364 -0
- package/dist/react-command.js.map +7 -0
- package/dist/react-composer.js +2036 -0
- package/dist/react-composer.js.map +7 -0
- package/dist/react-content-protection.js +133 -0
- package/dist/react-content-protection.js.map +7 -0
- package/dist/react-conversation.js +1226 -0
- package/dist/react-conversation.js.map +7 -0
- package/dist/react-cookie-consent.js +291 -0
- package/dist/react-cookie-consent.js.map +7 -0
- package/dist/react-data-table.js +310 -0
- package/dist/react-data-table.js.map +7 -0
- package/dist/react-date-picker.js +95 -0
- package/dist/react-date-picker.js.map +7 -0
- package/dist/react-device-frame.js +137 -0
- package/dist/react-device-frame.js.map +7 -0
- package/dist/react-dialog.js +218 -0
- package/dist/react-dialog.js.map +7 -0
- package/dist/react-diff-viewer.js +460 -0
- package/dist/react-diff-viewer.js.map +7 -0
- package/dist/react-dropdown-menu.js +292 -0
- package/dist/react-dropdown-menu.js.map +7 -0
- package/dist/react-editor-status-bar.js +148 -0
- package/dist/react-editor-status-bar.js.map +7 -0
- package/dist/react-editor-tabs.js +159 -0
- package/dist/react-editor-tabs.js.map +7 -0
- package/dist/react-emoji-picker.js +238 -0
- package/dist/react-emoji-picker.js.map +7 -0
- package/dist/react-empty-state.js +90 -0
- package/dist/react-empty-state.js.map +7 -0
- package/dist/react-feedback-dialog.js +275 -0
- package/dist/react-feedback-dialog.js.map +7 -0
- package/dist/react-file-tree.js +376 -0
- package/dist/react-file-tree.js.map +7 -0
- package/dist/react-file-upload.js +360 -0
- package/dist/react-file-upload.js.map +7 -0
- package/dist/react-floating-reactions.js +124 -0
- package/dist/react-floating-reactions.js.map +7 -0
- package/dist/react-flow-editor.js +198 -0
- package/dist/react-flow-editor.js.map +7 -0
- package/dist/react-footer.js +67 -0
- package/dist/react-footer.js.map +7 -0
- package/dist/react-graph-view.js +197 -0
- package/dist/react-graph-view.js.map +7 -0
- package/dist/react-icon-system.js +9 -0
- package/dist/react-icon-system.js.map +7 -0
- package/dist/react-infinite-canvas.js +8 -0
- package/dist/react-infinite-canvas.js.map +7 -0
- package/dist/react-inline-editor.js +216 -0
- package/dist/react-inline-editor.js.map +7 -0
- package/dist/react-input-group.js +150 -0
- package/dist/react-input-group.js.map +7 -0
- package/dist/react-input.js +10 -0
- package/dist/react-input.js.map +7 -0
- package/dist/react-install-prompt.js +132 -0
- package/dist/react-install-prompt.js.map +7 -0
- package/dist/react-kanban-board.js +198 -0
- package/dist/react-kanban-board.js.map +7 -0
- package/dist/react-keyboard-shortcut.js +36 -0
- package/dist/react-keyboard-shortcut.js.map +7 -0
- package/dist/react-language-selector.js +311 -0
- package/dist/react-language-selector.js.map +7 -0
- package/dist/react-link-card.js +48 -0
- package/dist/react-link-card.js.map +7 -0
- package/dist/react-live-captions.js +92 -0
- package/dist/react-live-captions.js.map +7 -0
- package/dist/react-live-cursors.js +145 -0
- package/dist/react-live-cursors.js.map +7 -0
- package/dist/react-live-transcript.js +117 -0
- package/dist/react-live-transcript.js.map +7 -0
- package/dist/react-location-selector.js +252 -0
- package/dist/react-location-selector.js.map +7 -0
- package/dist/react-logger.js +415 -0
- package/dist/react-logger.js.map +7 -0
- package/dist/react-markdown-renderer.js +12 -0
- package/dist/react-markdown-renderer.js.map +7 -0
- package/dist/react-marquee-strip.js +62 -0
- package/dist/react-marquee-strip.js.map +7 -0
- package/dist/react-mascot.js +367 -0
- package/dist/react-mascot.js.map +7 -0
- package/dist/react-mastery-bar.js +97 -0
- package/dist/react-mastery-bar.js.map +7 -0
- package/dist/react-mini-map.js +207 -0
- package/dist/react-mini-map.js.map +7 -0
- package/dist/react-mobile-nav.js +216 -0
- package/dist/react-mobile-nav.js.map +7 -0
- package/dist/react-navbar.js +96 -0
- package/dist/react-navbar.js.map +7 -0
- package/dist/react-numbered-steps.js +67 -0
- package/dist/react-numbered-steps.js.map +7 -0
- package/dist/react-otp-input.js +318 -0
- package/dist/react-otp-input.js.map +7 -0
- package/dist/react-pagination.js +199 -0
- package/dist/react-pagination.js.map +7 -0
- package/dist/react-password-input.js +104 -0
- package/dist/react-password-input.js.map +7 -0
- package/dist/react-payment.js +81 -0
- package/dist/react-payment.js.map +7 -0
- package/dist/react-popover.js +176 -0
- package/dist/react-popover.js.map +7 -0
- package/dist/react-pre-call-lobby.js +309 -0
- package/dist/react-pre-call-lobby.js.map +7 -0
- package/dist/react-presence-indicator.js +86 -0
- package/dist/react-presence-indicator.js.map +7 -0
- package/dist/react-pricing-card.js +142 -0
- package/dist/react-pricing-card.js.map +7 -0
- package/dist/react-progress-display.js +188 -0
- package/dist/react-progress-display.js.map +7 -0
- package/dist/react-radial-gauge.js +193 -0
- package/dist/react-radial-gauge.js.map +7 -0
- package/dist/react-radio.js +169 -0
- package/dist/react-radio.js.map +7 -0
- package/dist/react-rating-scale.js +171 -0
- package/dist/react-rating-scale.js.map +7 -0
- package/dist/react-reaction-bar.js +111 -0
- package/dist/react-reaction-bar.js.map +7 -0
- package/dist/react-resizable-layout.js +298 -0
- package/dist/react-resizable-layout.js.map +7 -0
- package/dist/react-rich-editor.js +1 -0
- package/dist/react-rich-editor.js.map +7 -0
- package/dist/react-search-bar.js +285 -0
- package/dist/react-search-bar.js.map +7 -0
- package/dist/react-section-head.js +65 -0
- package/dist/react-section-head.js.map +7 -0
- package/dist/react-segmented-control.js +215 -0
- package/dist/react-segmented-control.js.map +7 -0
- package/dist/react-select.js +389 -0
- package/dist/react-select.js.map +7 -0
- package/dist/react-separator.js +86 -0
- package/dist/react-separator.js.map +7 -0
- package/dist/react-sheet.js +310 -0
- package/dist/react-sheet.js.map +7 -0
- package/dist/react-sidebar.js +100 -0
- package/dist/react-sidebar.js.map +7 -0
- package/dist/react-skeleton.js +91 -0
- package/dist/react-skeleton.js.map +7 -0
- package/dist/react-skip-to-content.js +38 -0
- package/dist/react-skip-to-content.js.map +7 -0
- package/dist/react-slide-viewer.js +264 -0
- package/dist/react-slide-viewer.js.map +7 -0
- package/dist/react-slider.js +105 -0
- package/dist/react-slider.js.map +7 -0
- package/dist/react-slot-picker.js +184 -0
- package/dist/react-slot-picker.js.map +7 -0
- package/dist/react-slot.js +7 -0
- package/dist/react-slot.js.map +7 -0
- package/dist/react-social-auth-button.js +169 -0
- package/dist/react-social-auth-button.js.map +7 -0
- package/dist/react-sortable-list.js +204 -0
- package/dist/react-sortable-list.js.map +7 -0
- package/dist/react-stat-grid.js +69 -0
- package/dist/react-stat-grid.js.map +7 -0
- package/dist/react-status-indicator.js +117 -0
- package/dist/react-status-indicator.js.map +7 -0
- package/dist/react-steps.js +167 -0
- package/dist/react-steps.js.map +7 -0
- package/dist/react-sticky-note.js +131 -0
- package/dist/react-sticky-note.js.map +7 -0
- package/dist/react-switch.js +139 -0
- package/dist/react-switch.js.map +7 -0
- package/dist/react-table-of-contents.js +80 -0
- package/dist/react-table-of-contents.js.map +7 -0
- package/dist/react-tabs.js +230 -0
- package/dist/react-tabs.js.map +7 -0
- package/dist/react-terminal.js +101 -0
- package/dist/react-terminal.js.map +7 -0
- package/dist/react-test-results.js +158 -0
- package/dist/react-test-results.js.map +7 -0
- package/dist/react-textarea.js +89 -0
- package/dist/react-textarea.js.map +7 -0
- package/dist/react-thread-view.js +139 -0
- package/dist/react-thread-view.js.map +7 -0
- package/dist/react-timeline.js +153 -0
- package/dist/react-timeline.js.map +7 -0
- package/dist/react-toast.js +253 -0
- package/dist/react-toast.js.map +7 -0
- package/dist/react-tooltip.js +221 -0
- package/dist/react-tooltip.js.map +7 -0
- package/dist/react-version-selector.js +270 -0
- package/dist/react-version-selector.js.map +7 -0
- package/dist/react-video-grid.js +129 -0
- package/dist/react-video-grid.js.map +7 -0
- package/dist/react-video-player.js +206 -0
- package/dist/react-video-player.js.map +7 -0
- package/dist/react-video-tile.js +8 -0
- package/dist/react-video-tile.js.map +7 -0
- package/dist/react-voice-pill.js +314 -0
- package/dist/react-voice-pill.js.map +7 -0
- package/dist/react-waveform.js +558 -0
- package/dist/react-waveform.js.map +7 -0
- package/dist/react-wizard.js +337 -0
- package/dist/react-wizard.js.map +7 -0
- package/dist/styles.css +7 -0
- package/dist/theme.js +1 -1
- package/package.json +3 -2
- package/dist/applicationinsights-web-H7OBLIVJ.js +0 -23393
- package/dist/applicationinsights-web-H7OBLIVJ.js.map +0 -1
- package/dist/chunk-4A4BW3GR.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/module-X3HTTRQK.js +0 -6438
- package/dist/module-X3HTTRQK.js.map +0 -1
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createFaroSink
|
|
3
|
+
} from "./chunk-XWP763SH.js";
|
|
4
|
+
import {
|
|
5
|
+
devWarn
|
|
6
|
+
} from "./chunk-ZF3OHCGV.js";
|
|
7
|
+
|
|
8
|
+
// ../react-logger/dist/index.js
|
|
9
|
+
import * as React from "react";
|
|
10
|
+
|
|
11
|
+
// ../logger/dist/index.js
|
|
12
|
+
var LEVEL_ORDER = {
|
|
13
|
+
debug: 10,
|
|
14
|
+
info: 20,
|
|
15
|
+
warn: 30,
|
|
16
|
+
error: 40,
|
|
17
|
+
fatal: 50
|
|
18
|
+
};
|
|
19
|
+
var METHOD = {
|
|
20
|
+
debug: "debug",
|
|
21
|
+
info: "info",
|
|
22
|
+
warn: "warn",
|
|
23
|
+
error: "error",
|
|
24
|
+
fatal: "error"
|
|
25
|
+
};
|
|
26
|
+
function createConsoleSink(opts) {
|
|
27
|
+
const pretty = opts?.pretty ?? true;
|
|
28
|
+
const out = opts?.console ?? console;
|
|
29
|
+
function emit(level, line, payload) {
|
|
30
|
+
out[METHOD[level]](line, payload);
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
name: "console",
|
|
34
|
+
log(record) {
|
|
35
|
+
if (pretty) {
|
|
36
|
+
const ts = new Date(record.timestamp).toISOString();
|
|
37
|
+
emit(
|
|
38
|
+
record.level,
|
|
39
|
+
`${ts} ${record.level.toUpperCase()} [${record.app}] ${record.message}`,
|
|
40
|
+
record.context
|
|
41
|
+
);
|
|
42
|
+
} else {
|
|
43
|
+
emit(record.level, JSON.stringify({ type: "log", ...record }), record.context);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
span(record) {
|
|
47
|
+
const level = record.status === "error" ? "error" : "debug";
|
|
48
|
+
if (pretty) {
|
|
49
|
+
emit(
|
|
50
|
+
level,
|
|
51
|
+
`[span] ${record.name} ${record.durationMs.toFixed(2)}ms (${record.status})`,
|
|
52
|
+
record.context
|
|
53
|
+
);
|
|
54
|
+
} else {
|
|
55
|
+
emit(level, JSON.stringify({ type: "span", ...record }), record.context);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
async flush() {
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
var NOOP_SPAN = {
|
|
63
|
+
end() {
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
function createNoopTelemetry() {
|
|
67
|
+
const noop = {
|
|
68
|
+
debug() {
|
|
69
|
+
},
|
|
70
|
+
info() {
|
|
71
|
+
},
|
|
72
|
+
warn() {
|
|
73
|
+
},
|
|
74
|
+
error() {
|
|
75
|
+
},
|
|
76
|
+
fatal() {
|
|
77
|
+
},
|
|
78
|
+
child() {
|
|
79
|
+
return noop;
|
|
80
|
+
},
|
|
81
|
+
startSpan() {
|
|
82
|
+
return NOOP_SPAN;
|
|
83
|
+
},
|
|
84
|
+
async flush() {
|
|
85
|
+
},
|
|
86
|
+
get sinks() {
|
|
87
|
+
return [];
|
|
88
|
+
},
|
|
89
|
+
addSink() {
|
|
90
|
+
},
|
|
91
|
+
removeSink() {
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
return noop;
|
|
95
|
+
}
|
|
96
|
+
var PRESETS = {
|
|
97
|
+
development: {
|
|
98
|
+
minLevel: "debug",
|
|
99
|
+
batch: false,
|
|
100
|
+
batchSize: 1,
|
|
101
|
+
sampleRate: 1,
|
|
102
|
+
pretty: true,
|
|
103
|
+
beaconFlush: false
|
|
104
|
+
},
|
|
105
|
+
production: {
|
|
106
|
+
minLevel: "warn",
|
|
107
|
+
batch: true,
|
|
108
|
+
batchSize: 20,
|
|
109
|
+
sampleRate: 0.25,
|
|
110
|
+
pretty: false,
|
|
111
|
+
beaconFlush: true
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
function resolvePreset(env) {
|
|
115
|
+
return { ...PRESETS[env] };
|
|
116
|
+
}
|
|
117
|
+
function redact(value, keys) {
|
|
118
|
+
if (keys.length === 0) return value;
|
|
119
|
+
const lookup = new Set(keys.map((k) => k.toLowerCase()));
|
|
120
|
+
return walk(value, lookup, /* @__PURE__ */ new WeakSet());
|
|
121
|
+
}
|
|
122
|
+
function walk(value, keys, seen) {
|
|
123
|
+
if (value === null || typeof value !== "object") return value;
|
|
124
|
+
if (seen.has(value)) return "[Circular]";
|
|
125
|
+
seen.add(value);
|
|
126
|
+
if (Array.isArray(value)) {
|
|
127
|
+
return value.map((item) => walk(item, keys, seen));
|
|
128
|
+
}
|
|
129
|
+
const out = {};
|
|
130
|
+
for (const [k, v] of Object.entries(value)) {
|
|
131
|
+
if (keys.has(k.toLowerCase())) {
|
|
132
|
+
out[k] = "[REDACTED]";
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
out[k] = walk(v, keys, seen);
|
|
136
|
+
}
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
139
|
+
function createTelemetry(config) {
|
|
140
|
+
if (config.enabled === false) {
|
|
141
|
+
return createNoopTelemetry();
|
|
142
|
+
}
|
|
143
|
+
const preset = resolvePreset(config.env);
|
|
144
|
+
const sampleRate = config.sampleRate ?? preset.sampleRate;
|
|
145
|
+
const redactKeys = config.redactKeys ?? [];
|
|
146
|
+
const now = config.now ?? (() => Date.now());
|
|
147
|
+
const random = config.random ?? (() => Math.random());
|
|
148
|
+
const sinks = /* @__PURE__ */ new Map();
|
|
149
|
+
const sinkOrder = [];
|
|
150
|
+
const buffer = [];
|
|
151
|
+
function addSinkInternal(sink) {
|
|
152
|
+
if (sinks.has(sink.name)) {
|
|
153
|
+
sinks.set(sink.name, sink);
|
|
154
|
+
} else {
|
|
155
|
+
sinks.set(sink.name, sink);
|
|
156
|
+
sinkOrder.push(sink.name);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
addSinkInternal(createConsoleSink({ pretty: preset.pretty }));
|
|
160
|
+
if (config.endpoint) {
|
|
161
|
+
const endpoint = config.endpoint;
|
|
162
|
+
void import("./chunk-SDZ3LROZ.js").then(({ createFaroSink: createFaroSink2 }) => createFaroSink2({ app: config.app, endpoint })).then((faro) => {
|
|
163
|
+
if (faro) addSinkInternal(faro);
|
|
164
|
+
}).catch(() => {
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function shouldSample() {
|
|
168
|
+
if (sampleRate >= 1) return true;
|
|
169
|
+
if (sampleRate <= 0) return false;
|
|
170
|
+
return random() < sampleRate;
|
|
171
|
+
}
|
|
172
|
+
function dispatch(entry) {
|
|
173
|
+
if (preset.batch) {
|
|
174
|
+
buffer.push(entry);
|
|
175
|
+
if (buffer.length >= preset.batchSize) {
|
|
176
|
+
void flushBuffer();
|
|
177
|
+
}
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
deliver(entry);
|
|
181
|
+
}
|
|
182
|
+
function deliver(entry) {
|
|
183
|
+
for (const name of sinkOrder) {
|
|
184
|
+
const sink = sinks.get(name);
|
|
185
|
+
if (!sink) continue;
|
|
186
|
+
if (entry.kind === "log") sink.log(entry.record);
|
|
187
|
+
else sink.span(entry.record);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async function flushBuffer() {
|
|
191
|
+
if (buffer.length > 0) {
|
|
192
|
+
const pending = buffer.splice(0, buffer.length);
|
|
193
|
+
for (const entry of pending) deliver(entry);
|
|
194
|
+
}
|
|
195
|
+
await Promise.all(
|
|
196
|
+
sinkOrder.map((name) => sinks.get(name)?.flush() ?? Promise.resolve())
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
const root = globalThis;
|
|
200
|
+
if (preset.beaconFlush && typeof root.addEventListener === "function") {
|
|
201
|
+
const onExit = () => {
|
|
202
|
+
void flushBuffer();
|
|
203
|
+
};
|
|
204
|
+
root.addEventListener("pagehide", onExit);
|
|
205
|
+
root.addEventListener("visibilitychange", () => {
|
|
206
|
+
if (root.document?.visibilityState === "hidden") onExit();
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
function makeLogger(boundContext) {
|
|
210
|
+
function emit(level, message, context) {
|
|
211
|
+
if (LEVEL_ORDER[level] < LEVEL_ORDER[preset.minLevel]) return;
|
|
212
|
+
if (!shouldSample()) return;
|
|
213
|
+
const merged = redact({ ...boundContext, ...context }, redactKeys);
|
|
214
|
+
const record = {
|
|
215
|
+
level,
|
|
216
|
+
message,
|
|
217
|
+
timestamp: now(),
|
|
218
|
+
app: config.app,
|
|
219
|
+
env: config.env,
|
|
220
|
+
context: merged
|
|
221
|
+
};
|
|
222
|
+
dispatch({ kind: "log", record });
|
|
223
|
+
}
|
|
224
|
+
const logger = {
|
|
225
|
+
debug(message, context) {
|
|
226
|
+
emit("debug", message, context);
|
|
227
|
+
},
|
|
228
|
+
info(message, context) {
|
|
229
|
+
emit("info", message, context);
|
|
230
|
+
},
|
|
231
|
+
warn(message, context) {
|
|
232
|
+
emit("warn", message, context);
|
|
233
|
+
},
|
|
234
|
+
error(message, context) {
|
|
235
|
+
emit("error", message, context);
|
|
236
|
+
},
|
|
237
|
+
fatal(message, context) {
|
|
238
|
+
emit("fatal", message, context);
|
|
239
|
+
},
|
|
240
|
+
child(context) {
|
|
241
|
+
return makeLogger({ ...boundContext, ...context });
|
|
242
|
+
},
|
|
243
|
+
startSpan(name, attributes) {
|
|
244
|
+
const startTime = now();
|
|
245
|
+
let ended = false;
|
|
246
|
+
return {
|
|
247
|
+
end(opts) {
|
|
248
|
+
if (ended) return;
|
|
249
|
+
ended = true;
|
|
250
|
+
const endTime = now();
|
|
251
|
+
const merged = redact(
|
|
252
|
+
{ ...boundContext, ...attributes, ...opts?.attributes },
|
|
253
|
+
redactKeys
|
|
254
|
+
);
|
|
255
|
+
const err = opts?.error;
|
|
256
|
+
const record = {
|
|
257
|
+
name,
|
|
258
|
+
startTime,
|
|
259
|
+
endTime,
|
|
260
|
+
durationMs: endTime - startTime,
|
|
261
|
+
app: config.app,
|
|
262
|
+
env: config.env,
|
|
263
|
+
context: merged,
|
|
264
|
+
status: err ? "error" : "ok",
|
|
265
|
+
...err ? {
|
|
266
|
+
error: {
|
|
267
|
+
name: err instanceof Error ? err.name : "Error",
|
|
268
|
+
message: err instanceof Error ? err.message : String(err)
|
|
269
|
+
}
|
|
270
|
+
} : {}
|
|
271
|
+
};
|
|
272
|
+
dispatch({ kind: "span", record });
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
},
|
|
276
|
+
flush() {
|
|
277
|
+
return flushBuffer();
|
|
278
|
+
},
|
|
279
|
+
get sinks() {
|
|
280
|
+
return [...sinkOrder];
|
|
281
|
+
},
|
|
282
|
+
addSink(sink) {
|
|
283
|
+
addSinkInternal(sink);
|
|
284
|
+
},
|
|
285
|
+
removeSink(name) {
|
|
286
|
+
if (sinks.has(name)) {
|
|
287
|
+
sinks.delete(name);
|
|
288
|
+
const idx = sinkOrder.indexOf(name);
|
|
289
|
+
if (idx !== -1) sinkOrder.splice(idx, 1);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
return logger;
|
|
294
|
+
}
|
|
295
|
+
return makeLogger({});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// ../react-logger/dist/index.js
|
|
299
|
+
var noopTelemetry = null;
|
|
300
|
+
function getNoopTelemetry() {
|
|
301
|
+
return noopTelemetry ??= createNoopTelemetry();
|
|
302
|
+
}
|
|
303
|
+
var TelemetryContext = React.createContext(null);
|
|
304
|
+
function TelemetryProvider({ children, ...config }) {
|
|
305
|
+
const telemetryRef = React.useRef(null);
|
|
306
|
+
if (!telemetryRef.current) {
|
|
307
|
+
telemetryRef.current = createTelemetry(config);
|
|
308
|
+
}
|
|
309
|
+
const value = React.useMemo(
|
|
310
|
+
() => ({ telemetry: telemetryRef.current }),
|
|
311
|
+
[]
|
|
312
|
+
);
|
|
313
|
+
return React.createElement(TelemetryContext.Provider, { value }, children);
|
|
314
|
+
}
|
|
315
|
+
function useTelemetry() {
|
|
316
|
+
const ctx = React.useContext(TelemetryContext);
|
|
317
|
+
if (!ctx) {
|
|
318
|
+
devWarn(
|
|
319
|
+
"react-logger/use-telemetry-outside-provider",
|
|
320
|
+
"useTelemetry() (or useLogger()/useSpan(), which depend on it) was called outside a <TelemetryProvider>. Telemetry is a no-op here; wrap your app (or the consuming subtree) in <TelemetryProvider> to enable it."
|
|
321
|
+
);
|
|
322
|
+
return getNoopTelemetry();
|
|
323
|
+
}
|
|
324
|
+
return ctx.telemetry;
|
|
325
|
+
}
|
|
326
|
+
function useLogger(scope) {
|
|
327
|
+
const telemetry = useTelemetry();
|
|
328
|
+
const scopeKey = scope ? JSON.stringify(scope) : "";
|
|
329
|
+
return React.useMemo(
|
|
330
|
+
() => scope ? telemetry.child(scope) : telemetry,
|
|
331
|
+
[telemetry, scope, scopeKey]
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
function useSpan() {
|
|
335
|
+
const telemetry = useTelemetry();
|
|
336
|
+
const spanRef = React.useRef(null);
|
|
337
|
+
const [isActive, setIsActive] = React.useState(false);
|
|
338
|
+
const end = React.useCallback(
|
|
339
|
+
(opts) => {
|
|
340
|
+
if (!spanRef.current) return;
|
|
341
|
+
spanRef.current.end(opts);
|
|
342
|
+
spanRef.current = null;
|
|
343
|
+
setIsActive(false);
|
|
344
|
+
},
|
|
345
|
+
[]
|
|
346
|
+
);
|
|
347
|
+
const start = React.useCallback(
|
|
348
|
+
(name, attributes) => {
|
|
349
|
+
if (spanRef.current) {
|
|
350
|
+
spanRef.current.end();
|
|
351
|
+
}
|
|
352
|
+
const span = telemetry.startSpan(name, attributes);
|
|
353
|
+
spanRef.current = span;
|
|
354
|
+
setIsActive(true);
|
|
355
|
+
return span;
|
|
356
|
+
},
|
|
357
|
+
[telemetry]
|
|
358
|
+
);
|
|
359
|
+
React.useEffect(() => {
|
|
360
|
+
return () => {
|
|
361
|
+
if (spanRef.current) {
|
|
362
|
+
spanRef.current.end();
|
|
363
|
+
spanRef.current = null;
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
}, []);
|
|
367
|
+
return React.useMemo(
|
|
368
|
+
() => ({ start, end, isActive }),
|
|
369
|
+
[start, end, isActive]
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
var TelemetryErrorBoundary = class extends React.Component {
|
|
373
|
+
static contextType = TelemetryContext;
|
|
374
|
+
state = { error: null };
|
|
375
|
+
static getDerivedStateFromError(error) {
|
|
376
|
+
return { error };
|
|
377
|
+
}
|
|
378
|
+
componentDidCatch(error, info) {
|
|
379
|
+
const telemetry = this.context?.telemetry;
|
|
380
|
+
if (telemetry) {
|
|
381
|
+
telemetry.error(error.message, {
|
|
382
|
+
...this.props.context,
|
|
383
|
+
name: error.name,
|
|
384
|
+
stack: error.stack,
|
|
385
|
+
componentStack: info.componentStack
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
this.props.onError?.(error, info);
|
|
389
|
+
}
|
|
390
|
+
reset = () => {
|
|
391
|
+
this.setState({ error: null });
|
|
392
|
+
};
|
|
393
|
+
render() {
|
|
394
|
+
const { error } = this.state;
|
|
395
|
+
if (error) {
|
|
396
|
+
const { fallback } = this.props;
|
|
397
|
+
if (typeof fallback === "function") {
|
|
398
|
+
return fallback(error, this.reset);
|
|
399
|
+
}
|
|
400
|
+
return fallback ?? null;
|
|
401
|
+
}
|
|
402
|
+
return this.props.children;
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
export {
|
|
406
|
+
TelemetryErrorBoundary,
|
|
407
|
+
TelemetryProvider,
|
|
408
|
+
createConsoleSink,
|
|
409
|
+
createFaroSink,
|
|
410
|
+
createTelemetry,
|
|
411
|
+
useLogger,
|
|
412
|
+
useSpan,
|
|
413
|
+
useTelemetry
|
|
414
|
+
};
|
|
415
|
+
//# sourceMappingURL=react-logger.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../logger/src/types.ts", "../../logger/src/console-sink.ts", "../../logger/src/noop.ts", "../../logger/src/presets.ts", "../../logger/src/redact.ts", "../../logger/src/telemetry-manager.ts", "../../logger/src/mock-sink.ts", "../../react-logger/src/telemetry-provider.tsx", "../../react-logger/src/use-span.ts", "../../react-logger/src/error-boundary.tsx"],
|
|
4
|
+
"sourcesContent": ["/** Severity levels, ordered low -> high. */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal'\n\n/** Numeric ordering used for level threshold comparisons. */\nexport const LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n fatal: 50,\n}\n\n/** Bound key/value pairs attached to every record emitted by a logger. */\nexport type LogContext = Record<string, unknown>\n\n/** A single structured log record handed to a sink. */\nexport interface LogRecord {\n level: LogLevel\n message: string\n timestamp: number\n app: string\n env: TelemetryEnv\n /** Merged bound context (child loggers) + per-call context, post-redaction. */\n context: LogContext\n}\n\n/** A span record handed to a sink when a span ends. */\nexport interface SpanRecord {\n name: string\n startTime: number\n endTime: number\n durationMs: number\n app: string\n env: TelemetryEnv\n /** Merged bound context + span attributes, post-redaction. */\n context: LogContext\n /** 'ok' unless ended with an error. */\n status: 'ok' | 'error'\n error?: { name: string; message: string }\n}\n\n/**\n * Vendor-neutral telemetry sink. Engines (console, Faro, custom) implement\n * this — no vendor type ever leaks across this boundary.\n */\nexport interface TelemetrySink {\n /** Engine name, for diagnostics. */\n name: string\n /** Receive a log record. May buffer; honor flush(). */\n log(record: LogRecord): void\n /** Receive a finished span. May buffer; honor flush(). */\n span(record: SpanRecord): void\n /** Force-deliver any buffered records. Resolves once delivery is attempted. */\n flush(): Promise<void>\n}\n\n/** Telemetry environment — selects a behavior preset. */\nexport type TelemetryEnv = 'development' | 'production'\n\n/** Config for {@link createTelemetry} — mirrors `createAI`'s config shape. */\nexport interface TelemetryConfig {\n /** Logical app/service name attached to every record. */\n app: string\n /** Environment preset selector. */\n env: TelemetryEnv\n /**\n * Remote collector endpoint. When omitted, telemetry stays console-only\n * (no network engine is constructed).\n */\n endpoint?: string\n /**\n * Master kill switch. When `false`, a tree-shakeable noop logger is\n * returned and zero records are ever produced. Defaults to `true`.\n */\n enabled?: boolean\n /**\n * Fraction of records kept, 0..1. Defaults to the preset value\n * (1 in development, 0.25 in production). Records below the sample\n * are dropped before reaching any sink.\n */\n sampleRate?: number\n /**\n * Context keys to strip (deep) before a record is emitted. Use for\n * PII / secrets, e.g. `['password', 'token', 'authorization']`.\n */\n redactKeys?: string[]\n /** Clock for record timestamps and span timing (ms epoch). Default: ambient `Date.now()` — inject for deterministic tests. */\n now?: () => number\n /** RNG for sample-rate decisions. Default: ambient `Math.random` — inject for deterministic tests. */\n random?: () => number\n}\n\n/** A logger bound to a context. Child loggers inherit + extend that context. */\nexport interface Logger {\n debug(message: string, context?: LogContext): void\n info(message: string, context?: LogContext): void\n warn(message: string, context?: LogContext): void\n error(message: string, context?: LogContext): void\n fatal(message: string, context?: LogContext): void\n /**\n * Derive a logger with additional bound context (e.g.\n * `{ sessionId, interviewId, turnId }`). Merges over the parent's context.\n */\n child(context: LogContext): Logger\n /** Begin a span. Call {@link Span.end} to record its duration. */\n startSpan(name: string, attributes?: LogContext): Span\n /** Force-deliver buffered records on every sink. */\n flush(): Promise<void>\n}\n\n/** An in-flight span returned by {@link Logger.startSpan}. */\nexport interface Span {\n /** End the span and emit a {@link SpanRecord}. Optionally attach error/attrs. */\n end(opts?: { error?: unknown; attributes?: LogContext }): void\n}\n\n/** Return type of {@link createTelemetry}. */\nexport interface Telemetry extends Logger {\n /** Registered sink names, in insertion order. */\n readonly sinks: string[]\n /** Register an additional sink (e.g. a custom collector). */\n addSink(sink: TelemetrySink): void\n /** Remove a sink by name. */\n removeSink(name: string): void\n}\n", "import type { LogLevel, LogRecord, SpanRecord, TelemetrySink } from './types.js'\n\n/** Console method used for each level. */\nconst METHOD: Record<LogLevel, 'debug' | 'info' | 'warn' | 'error'> = {\n debug: 'debug',\n info: 'info',\n warn: 'warn',\n error: 'error',\n fatal: 'error',\n}\n\nexport interface ConsoleSinkOptions {\n /** Single-line pretty output (vs. structured JSON). */\n pretty?: boolean\n /** Console to write to (injectable for tests). Defaults to global console. */\n console?: Pick<Console, 'debug' | 'info' | 'warn' | 'error'>\n}\n\n/**\n * Default zero-dependency transport. Used whenever no `endpoint` is set.\n * Synchronous; `flush()` is a resolved no-op (nothing is buffered).\n */\nexport function createConsoleSink(opts?: ConsoleSinkOptions): TelemetrySink {\n const pretty = opts?.pretty ?? true\n const out = opts?.console ?? console\n\n function emit(level: LogLevel, line: string, payload: unknown): void {\n out[METHOD[level]](line, payload)\n }\n\n return {\n name: 'console',\n\n log(record: LogRecord): void {\n if (pretty) {\n const ts = new Date(record.timestamp).toISOString()\n emit(\n record.level,\n `${ts} ${record.level.toUpperCase()} [${record.app}] ${record.message}`,\n record.context,\n )\n } else {\n emit(record.level, JSON.stringify({ type: 'log', ...record }), record.context)\n }\n },\n\n span(record: SpanRecord): void {\n const level: LogLevel = record.status === 'error' ? 'error' : 'debug'\n if (pretty) {\n emit(\n level,\n `[span] ${record.name} ${record.durationMs.toFixed(2)}ms (${record.status})`,\n record.context,\n )\n } else {\n emit(level, JSON.stringify({ type: 'span', ...record }), record.context)\n }\n },\n\n async flush(): Promise<void> {\n // Console is synchronous — nothing buffered.\n },\n }\n}\n", "import type { Span, Telemetry } from './types.js'\n\n/** Shared no-op span — emits nothing, allocates nothing per call. */\nconst NOOP_SPAN: Span = {\n end(): void {\n /* no-op */\n },\n}\n\n/**\n * Returned by {@link createTelemetry} when `enabled: false`. Every method is\n * an empty stub, so a bundler can dead-code-eliminate call sites and the\n * engines (console/Faro) are never imported at runtime. Zero emissions.\n */\nexport function createNoopTelemetry(): Telemetry {\n const noop: Telemetry = {\n debug(): void {\n /* no-op */\n },\n info(): void {\n /* no-op */\n },\n warn(): void {\n /* no-op */\n },\n error(): void {\n /* no-op */\n },\n fatal(): void {\n /* no-op */\n },\n child(): Telemetry {\n return noop\n },\n startSpan(): Span {\n return NOOP_SPAN\n },\n async flush(): Promise<void> {\n /* no-op */\n },\n get sinks(): string[] {\n return []\n },\n addSink(): void {\n /* no-op */\n },\n removeSink(): void {\n /* no-op */\n },\n }\n return noop\n}\n", "import type { LogLevel, TelemetryEnv } from './types.js'\n\n/**\n * Behavior derived from {@link TelemetryConfig.env}. The manager reads these\n * fields to decide level filtering, batching, sampling, and flush triggers.\n */\nexport interface TelemetryPreset {\n /** Records strictly below this level are dropped. */\n minLevel: LogLevel\n /** Buffer records and deliver in batches instead of synchronously. */\n batch: boolean\n /** Batch size before an automatic flush (only when `batch`). */\n batchSize: number\n /** Default sample rate when config omits `sampleRate`. */\n sampleRate: number\n /** Pretty, single-line console output (vs. structured JSON). */\n pretty: boolean\n /**\n * Flush buffered records on `pagehide` + `visibilitychange` (hidden),\n * using `navigator.sendBeacon` when available.\n */\n beaconFlush: boolean\n}\n\n/**\n * - development: sync, pretty, level=debug, no batching, sample everything.\n * - production: batched + sampled, level>=warn, beacon flush on page exit.\n */\nexport const PRESETS: Record<TelemetryEnv, TelemetryPreset> = {\n development: {\n minLevel: 'debug',\n batch: false,\n batchSize: 1,\n sampleRate: 1,\n pretty: true,\n beaconFlush: false,\n },\n production: {\n minLevel: 'warn',\n batch: true,\n batchSize: 20,\n sampleRate: 0.25,\n pretty: false,\n beaconFlush: true,\n },\n}\n\n/** Resolve the preset for an env (defensive copy so callers can't mutate it). */\nexport function resolvePreset(env: TelemetryEnv): TelemetryPreset {\n return { ...PRESETS[env] }\n}\n", "import type { LogContext } from './types.js'\n\n/**\n * Deep-strip any object key whose name (case-insensitive) is in `keys`.\n * Arrays are walked; cycles are guarded; non-matching values pass through\n * unchanged. Returns a new structure — the input is never mutated.\n */\nexport function redact(value: LogContext, keys: string[]): LogContext {\n if (keys.length === 0) return value\n const lookup = new Set(keys.map((k) => k.toLowerCase()))\n return walk(value, lookup, new WeakSet()) as LogContext\n}\n\nfunction walk(value: unknown, keys: Set<string>, seen: WeakSet<object>): unknown {\n if (value === null || typeof value !== 'object') return value\n\n if (seen.has(value as object)) return '[Circular]'\n seen.add(value as object)\n\n if (Array.isArray(value)) {\n return value.map((item) => walk(item, keys, seen))\n }\n\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (keys.has(k.toLowerCase())) {\n out[k] = '[REDACTED]'\n continue\n }\n out[k] = walk(v, keys, seen)\n }\n return out\n}\n", "import { createConsoleSink } from './console-sink.js'\nimport { createNoopTelemetry } from './noop.js'\nimport { resolvePreset, type TelemetryPreset } from './presets.js'\nimport { redact } from './redact.js'\nimport {\n LEVEL_ORDER,\n type LogContext,\n type LogLevel,\n type LogRecord,\n type Span,\n type SpanRecord,\n type Telemetry,\n type TelemetryConfig,\n type TelemetrySink,\n} from './types.js'\n\n/**\n * createTelemetry — creates a telemetry manager that fans records out to\n * registered sinks. Manager/provider pattern, mirroring `createAI`.\n *\n * - `enabled: false` -> tree-shakeable noop (zero emissions, no engines).\n * - no `endpoint` -> console-only transport.\n * - `endpoint` set -> async Faro engine is registered when the optional\n * peers exist; console stays as a safe fallback until then.\n *\n * The returned object IS a logger (root context = `{}`); `child()` derives\n * loggers with bound context (sessionId / interviewId / turnId / ...).\n */\nexport function createTelemetry(config: TelemetryConfig): Telemetry {\n if (config.enabled === false) {\n return createNoopTelemetry()\n }\n\n const preset = resolvePreset(config.env)\n const sampleRate = config.sampleRate ?? preset.sampleRate\n const redactKeys = config.redactKeys ?? []\n // Injection boundary: ambient time/randomness default here; inject `now`/`random` for determinism.\n const now = config.now ?? (() => Date.now())\n const random = config.random ?? (() => Math.random())\n\n const sinks = new Map<string, TelemetrySink>()\n /** Insertion-ordered sink names. */\n const sinkOrder: string[] = []\n /** Batch buffer (production preset only). */\n const buffer: Array<{ kind: 'log'; record: LogRecord } | { kind: 'span'; record: SpanRecord }> = []\n\n function addSinkInternal(sink: TelemetrySink): void {\n if (sinks.has(sink.name)) {\n sinks.set(sink.name, sink)\n } else {\n sinks.set(sink.name, sink)\n sinkOrder.push(sink.name)\n }\n }\n\n // Console transport is always present as the zero-dependency baseline.\n addSinkInternal(createConsoleSink({ pretty: preset.pretty }))\n\n // When an endpoint is configured, attempt to attach the Faro engine. The\n // import is lazy + dynamic so the optional peers never become required and\n // Faro names stay out of the public API.\n if (config.endpoint) {\n const endpoint = config.endpoint\n void import('./faro-engine.js')\n .then(({ createFaroSink }) => createFaroSink({ app: config.app, endpoint }))\n .then((faro) => {\n if (faro) addSinkInternal(faro)\n })\n .catch(() => {\n /* peers absent or init failed — console remains */\n })\n }\n\n function shouldSample(): boolean {\n if (sampleRate >= 1) return true\n if (sampleRate <= 0) return false\n return random() < sampleRate\n }\n\n function dispatch(\n entry: { kind: 'log'; record: LogRecord } | { kind: 'span'; record: SpanRecord },\n ): void {\n if (preset.batch) {\n buffer.push(entry)\n if (buffer.length >= preset.batchSize) {\n void flushBuffer()\n }\n return\n }\n deliver(entry)\n }\n\n function deliver(\n entry: { kind: 'log'; record: LogRecord } | { kind: 'span'; record: SpanRecord },\n ): void {\n for (const name of sinkOrder) {\n const sink = sinks.get(name)\n if (!sink) continue\n if (entry.kind === 'log') sink.log(entry.record)\n else sink.span(entry.record)\n }\n }\n\n async function flushBuffer(): Promise<void> {\n if (buffer.length > 0) {\n const pending = buffer.splice(0, buffer.length)\n for (const entry of pending) deliver(entry)\n }\n await Promise.all(\n sinkOrder.map((name) => sinks.get(name)?.flush() ?? Promise.resolve()),\n )\n }\n\n // ---- page-exit beacon flush (production preset) -------------------------\n // Browser only — `navigator.sendBeacon` is used by the underlying engine\n // transport; here we just trigger a flush on the page-exit signals.\n const root = globalThis as {\n addEventListener?: (type: string, listener: () => void) => void\n document?: { visibilityState?: string }\n navigator?: { sendBeacon?: unknown }\n }\n if (preset.beaconFlush && typeof root.addEventListener === 'function') {\n const onExit = (): void => {\n void flushBuffer()\n }\n root.addEventListener('pagehide', onExit)\n root.addEventListener('visibilitychange', () => {\n if (root.document?.visibilityState === 'hidden') onExit()\n })\n }\n\n function makeLogger(boundContext: LogContext): Telemetry {\n function emit(level: LogLevel, message: string, context?: LogContext): void {\n if (LEVEL_ORDER[level] < LEVEL_ORDER[preset.minLevel]) return\n if (!shouldSample()) return\n const merged = redact({ ...boundContext, ...context }, redactKeys)\n const record: LogRecord = {\n level,\n message,\n timestamp: now(),\n app: config.app,\n env: config.env,\n context: merged,\n }\n dispatch({ kind: 'log', record })\n }\n\n const logger: Telemetry = {\n debug(message, context?) {\n emit('debug', message, context)\n },\n info(message, context?) {\n emit('info', message, context)\n },\n warn(message, context?) {\n emit('warn', message, context)\n },\n error(message, context?) {\n emit('error', message, context)\n },\n fatal(message, context?) {\n emit('fatal', message, context)\n },\n\n child(context: LogContext): Telemetry {\n return makeLogger({ ...boundContext, ...context })\n },\n\n startSpan(name: string, attributes?: LogContext): Span {\n const startTime = now()\n let ended = false\n return {\n end(opts?: { error?: unknown; attributes?: LogContext }): void {\n if (ended) return\n ended = true\n const endTime = now()\n const merged = redact(\n { ...boundContext, ...attributes, ...opts?.attributes },\n redactKeys,\n )\n const err = opts?.error\n const record: SpanRecord = {\n name,\n startTime,\n endTime,\n durationMs: endTime - startTime,\n app: config.app,\n env: config.env,\n context: merged,\n status: err ? 'error' : 'ok',\n ...(err\n ? {\n error: {\n name: err instanceof Error ? err.name : 'Error',\n message: err instanceof Error ? err.message : String(err),\n },\n }\n : {}),\n }\n dispatch({ kind: 'span', record })\n },\n }\n },\n\n flush(): Promise<void> {\n return flushBuffer()\n },\n\n get sinks(): string[] {\n return [...sinkOrder]\n },\n\n addSink(sink: TelemetrySink): void {\n addSinkInternal(sink)\n },\n\n removeSink(name: string): void {\n if (sinks.has(name)) {\n sinks.delete(name)\n const idx = sinkOrder.indexOf(name)\n if (idx !== -1) sinkOrder.splice(idx, 1)\n }\n },\n }\n\n return logger\n }\n\n return makeLogger({})\n}\n\nexport type { TelemetryPreset }\n", "import type { LogRecord, SpanRecord, TelemetrySink } from './types.js'\n\nexport interface MockSinkExtended extends TelemetrySink {\n /** Every log record received, in order. */\n logs: LogRecord[]\n /** Every span record received, in order. */\n spans: SpanRecord[]\n /** Number of times {@link TelemetrySink.flush} was called. */\n flushCalls: number\n}\n\n/**\n * createMockSink — a {@link TelemetrySink} that records everything for\n * assertions instead of doing I/O. Used to test the manager and the Faro\n * engine without any network. Mirrors `createMockAIProvider` in `packages/ai`.\n */\nexport function createMockSink(name: string = 'mock'): MockSinkExtended {\n const sink: MockSinkExtended = {\n name,\n logs: [],\n spans: [],\n flushCalls: 0,\n\n log(record: LogRecord): void {\n sink.logs.push(record)\n },\n\n span(record: SpanRecord): void {\n sink.spans.push(record)\n },\n\n async flush(): Promise<void> {\n sink.flushCalls++\n },\n }\n\n return sink\n}\n", "import * as React from 'react'\nimport { devWarn } from '@refraction-ui/shared'\nimport {\n createTelemetry,\n createNoopTelemetry,\n type TelemetryConfig,\n type Telemetry,\n type Logger,\n type LogContext,\n} from '@refraction-ui/logger'\n\n/**\n * Shared no-op telemetry used when a hook is called outside a\n * <TelemetryProvider>. Lazily created once and reused so the reference is\n * stable across renders. The hooks degrade gracefully (no-op) instead of\n * throwing, so components instrumented with useLogger/useSpan/useTelemetry\n * render fine without a provider (e.g. in tests, or standalone usage).\n */\nlet noopTelemetry: Telemetry | null = null\nfunction getNoopTelemetry(): Telemetry {\n return (noopTelemetry ??= createNoopTelemetry())\n}\n\nexport interface TelemetryContextValue {\n /** The root telemetry instance (a logger bound to the empty root context). */\n telemetry: Telemetry\n}\n\nexport const TelemetryContext = React.createContext<TelemetryContextValue | null>(null)\n\nexport interface TelemetryProviderProps extends TelemetryConfig {\n children: React.ReactNode\n}\n\n/**\n * TelemetryProvider — wraps your app with telemetry context.\n *\n * ```tsx\n * <TelemetryProvider app=\"interview-service\" env=\"production\">\n * <App />\n * </TelemetryProvider>\n * ```\n */\nexport function TelemetryProvider({ children, ...config }: TelemetryProviderProps) {\n const telemetryRef = React.useRef<Telemetry | null>(null)\n\n if (!telemetryRef.current) {\n telemetryRef.current = createTelemetry(config)\n }\n\n const value = React.useMemo<TelemetryContextValue>(\n () => ({ telemetry: telemetryRef.current! }),\n [],\n )\n\n return React.createElement(TelemetryContext.Provider, { value }, children)\n}\n\n/**\n * useTelemetry — access the root telemetry instance.\n *\n * If called outside a <TelemetryProvider> it does NOT throw: it returns a\n * shared no-op telemetry (a dev-only warn-once hint is emitted so the missing\n * provider is discoverable). This lets components instrumented with\n * useLogger/useSpan/useTelemetry render safely without a provider.\n */\nexport function useTelemetry(): Telemetry {\n const ctx = React.useContext(TelemetryContext)\n if (!ctx) {\n devWarn(\n 'react-logger/use-telemetry-outside-provider',\n 'useTelemetry() (or useLogger()/useSpan(), which depend on it) was called outside a <TelemetryProvider>. Telemetry is a no-op here; wrap your app (or the consuming subtree) in <TelemetryProvider> to enable it.',\n )\n return getNoopTelemetry()\n }\n return ctx.telemetry\n}\n\n/**\n * useLogger — derive a scoped child logger with bound context (e.g.\n * `{ sessionId, interviewId, turnId }`). The logger is memoized so it stays\n * stable across renders for the same scope. With no scope, the root telemetry\n * logger is returned.\n *\n * Must be used within <TelemetryProvider>.\n */\nexport function useLogger(scope?: LogContext): Logger {\n const telemetry = useTelemetry()\n const scopeKey = scope ? JSON.stringify(scope) : ''\n return React.useMemo<Logger>(\n () => (scope ? telemetry.child(scope) : telemetry),\n [telemetry, scope, scopeKey],\n )\n}\n", "import * as React from 'react'\nimport type { LogContext, Span } from '@refraction-ui/logger'\nimport { useTelemetry } from './telemetry-provider.js'\n\nexport interface UseSpanAPI {\n /**\n * Begin a span tied to the provider's telemetry instance. Returns the\n * {@link Span}; call {@link Span.end} (or {@link UseSpanAPI.end}) to record\n * its duration. Starting a new span while one is active ends the previous\n * one first so a single hook owns at most one in-flight span.\n */\n start: (name: string, attributes?: LogContext) => Span\n /** End the active span (no-op if none is in flight). Idempotent per span. */\n end: (opts?: { error?: unknown; attributes?: LogContext }) => void\n /** Whether a span started by this hook is currently in flight. */\n isActive: boolean\n}\n\n/**\n * useSpan — start/end a telemetry span tied to the provider's telemetry\n * instance. The active span is cleaned up automatically on unmount.\n *\n * ```tsx\n * const span = useSpan()\n * useEffect(() => {\n * span.start('llm-call', { model: 'gpt' })\n * return () => span.end()\n * }, [])\n * ```\n *\n * Must be used within <TelemetryProvider>.\n */\nexport function useSpan(): UseSpanAPI {\n const telemetry = useTelemetry()\n const spanRef = React.useRef<Span | null>(null)\n const [isActive, setIsActive] = React.useState(false)\n\n const end = React.useCallback(\n (opts?: { error?: unknown; attributes?: LogContext }) => {\n if (!spanRef.current) return\n spanRef.current.end(opts)\n spanRef.current = null\n setIsActive(false)\n },\n [],\n )\n\n const start = React.useCallback(\n (name: string, attributes?: LogContext): Span => {\n if (spanRef.current) {\n spanRef.current.end()\n }\n const span = telemetry.startSpan(name, attributes)\n spanRef.current = span\n setIsActive(true)\n return span\n },\n [telemetry],\n )\n\n React.useEffect(() => {\n return () => {\n if (spanRef.current) {\n spanRef.current.end()\n spanRef.current = null\n }\n }\n }, [])\n\n return React.useMemo<UseSpanAPI>(\n () => ({ start, end, isActive }),\n [start, end, isActive],\n )\n}\n", "import * as React from 'react'\nimport type { LogContext } from '@refraction-ui/logger'\nimport { TelemetryContext, type TelemetryContextValue } from './telemetry-provider.js'\n\nexport interface TelemetryErrorBoundaryProps {\n children: React.ReactNode\n /**\n * Fallback UI rendered after an error is caught. May be a node or a render\n * function receiving the captured error and a reset callback.\n */\n fallback?:\n | React.ReactNode\n | ((error: Error, reset: () => void) => React.ReactNode)\n /** Extra bound context attached to the reported error record. */\n context?: LogContext\n /** Invoked after the error has been reported to the telemetry sink. */\n onError?: (error: Error, info: React.ErrorInfo) => void\n}\n\ninterface TelemetryErrorBoundaryState {\n error: Error | null\n}\n\n/**\n * TelemetryErrorBoundary — a React error boundary that reports caught render\n * errors to the provider's telemetry sink (at `error` level) before showing\n * an optional fallback.\n *\n * ```tsx\n * <TelemetryErrorBoundary fallback={<p>Something broke.</p>}>\n * <App />\n * </TelemetryErrorBoundary>\n * ```\n *\n * Must be used within <TelemetryProvider>.\n */\nexport class TelemetryErrorBoundary extends React.Component<\n TelemetryErrorBoundaryProps,\n TelemetryErrorBoundaryState\n> {\n static contextType = TelemetryContext\n declare context: TelemetryContextValue | null\n\n state: TelemetryErrorBoundaryState = { error: null }\n\n static getDerivedStateFromError(error: Error): TelemetryErrorBoundaryState {\n return { error }\n }\n\n componentDidCatch(error: Error, info: React.ErrorInfo): void {\n const telemetry = this.context?.telemetry\n if (telemetry) {\n telemetry.error(error.message, {\n ...this.props.context,\n name: error.name,\n stack: error.stack,\n componentStack: info.componentStack,\n })\n }\n this.props.onError?.(error, info)\n }\n\n reset = (): void => {\n this.setState({ error: null })\n }\n\n render(): React.ReactNode {\n const { error } = this.state\n if (error) {\n const { fallback } = this.props\n if (typeof fallback === 'function') {\n return fallback(error, this.reset)\n }\n return fallback ?? null\n }\n return this.props.children\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["createFaroSink", "React2"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MarkdownRenderer,
|
|
3
|
+
markdownRendererTokens,
|
|
4
|
+
proseVariants
|
|
5
|
+
} from "./chunk-UNEM2TRI.js";
|
|
6
|
+
import "./chunk-ZF3OHCGV.js";
|
|
7
|
+
export {
|
|
8
|
+
MarkdownRenderer,
|
|
9
|
+
markdownRendererTokens,
|
|
10
|
+
proseVariants
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=react-markdown-renderer.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cn,
|
|
3
|
+
cva
|
|
4
|
+
} from "./chunk-ZF3OHCGV.js";
|
|
5
|
+
|
|
6
|
+
// ../react-marquee-strip/dist/index.js
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
|
|
9
|
+
// ../marquee-strip/dist/index.js
|
|
10
|
+
function createMarqueeStrip(props = {}) {
|
|
11
|
+
const { scroll = false } = props;
|
|
12
|
+
const ariaProps = {
|
|
13
|
+
role: "group"
|
|
14
|
+
};
|
|
15
|
+
const dataAttributes = {
|
|
16
|
+
"data-scroll": String(scroll)
|
|
17
|
+
};
|
|
18
|
+
return { ariaProps, dataAttributes };
|
|
19
|
+
}
|
|
20
|
+
var marqueeStripVariants = cva({
|
|
21
|
+
base: "w-full bg-muted/30 border-y border-border py-3",
|
|
22
|
+
variants: {
|
|
23
|
+
scroll: {
|
|
24
|
+
true: "",
|
|
25
|
+
false: ""
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: {
|
|
29
|
+
scroll: "false"
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
var marqueeStripInnerClass = "flex flex-wrap items-center gap-3 px-4";
|
|
33
|
+
var marqueeStripScrollOuterClass = "overflow-hidden px-4";
|
|
34
|
+
var marqueeStripScrollTrackClass = "flex items-center gap-3 w-max animate-[marquee_30s_linear_infinite]";
|
|
35
|
+
var marqueeStripLabelClass = "text-xs font-semibold uppercase tracking-widest text-muted-foreground shrink-0";
|
|
36
|
+
var marqueeStripItemClass = "text-sm text-foreground";
|
|
37
|
+
|
|
38
|
+
// ../react-marquee-strip/dist/index.js
|
|
39
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
40
|
+
var MarqueeStrip = React.forwardRef(
|
|
41
|
+
function MarqueeStrip2({ label, items, scroll = false, className, ...props }, ref) {
|
|
42
|
+
const api = createMarqueeStrip({ scroll });
|
|
43
|
+
return /* @__PURE__ */ jsx(
|
|
44
|
+
"div",
|
|
45
|
+
{
|
|
46
|
+
ref,
|
|
47
|
+
className: cn(marqueeStripVariants({ scroll: scroll ? "true" : "false" }), className),
|
|
48
|
+
...api.ariaProps,
|
|
49
|
+
...api.dataAttributes,
|
|
50
|
+
...props,
|
|
51
|
+
children: scroll ? /* @__PURE__ */ jsx("div", { className: marqueeStripScrollOuterClass, children: /* @__PURE__ */ jsx("div", { className: marqueeStripScrollTrackClass, children: [...items, ...items].map((item, index) => /* @__PURE__ */ jsx("span", { className: marqueeStripItemClass, children: item }, index)) }) }) : /* @__PURE__ */ jsxs("div", { className: marqueeStripInnerClass, children: [
|
|
52
|
+
label != null && /* @__PURE__ */ jsx("span", { className: marqueeStripLabelClass, children: label }),
|
|
53
|
+
items.map((item, index) => /* @__PURE__ */ jsx("span", { className: marqueeStripItemClass, children: item }, index))
|
|
54
|
+
] })
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
export {
|
|
60
|
+
MarqueeStrip
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=react-marquee-strip.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../marquee-strip/src/marquee-strip.ts", "../../marquee-strip/src/marquee-strip.styles.ts", "../../react-marquee-strip/src/marquee-strip.tsx"],
|
|
4
|
+
"sourcesContent": ["import type { AccessibilityProps } from '@refraction-ui/shared'\n\nexport interface MarqueeStripProps {\n /** Whether to continuously scroll the items. */\n scroll?: boolean\n}\n\nexport interface MarqueeStripAPI {\n /** ARIA attributes to spread on the container element (`role=\"group\"`). */\n ariaProps: Partial<AccessibilityProps>\n /** Data attributes for styling hooks. */\n dataAttributes: Record<string, string>\n}\n\n/**\n * Build the framework-agnostic container props for a marquee strip.\n *\n * Returns `role=\"group\"` plus a `data-scroll` attribute. Adapters spread these\n * onto their container and render the label and items themselves. In scroll mode\n * the adapter is responsible for duplicating items once to achieve a seamless\n * loop (the CSS `marquee` keyframe translates from 0 to –50%).\n */\nexport function createMarqueeStrip(props: MarqueeStripProps = {}): MarqueeStripAPI {\n const { scroll = false } = props\n\n const ariaProps: Partial<AccessibilityProps> = {\n role: 'group',\n }\n\n const dataAttributes: Record<string, string> = {\n 'data-scroll': String(scroll),\n }\n\n return { ariaProps, dataAttributes }\n}\n", "import { cva } from '@refraction-ui/shared'\n\n/**\n * Container — a full-width band with a subtle muted background and border.\n *\n * The `scroll` variant switches the inner track from wrapping flex to an\n * overflow-hidden marquee track. See {@link marqueeStripInnerClass} and\n * {@link marqueeStripScrollTrackClass} for the corresponding track classes.\n */\nexport const marqueeStripVariants = cva({\n base: 'w-full bg-muted/30 border-y border-border py-3',\n variants: {\n scroll: {\n true: '',\n false: '',\n },\n },\n defaultVariants: {\n scroll: 'false',\n },\n})\n\n/**\n * Inner wrapper for static (non-scroll) mode.\n *\n * Items wrap naturally so they never overflow on narrow viewports.\n */\nexport const marqueeStripInnerClass =\n 'flex flex-wrap items-center gap-3 px-4'\n\n/**\n * Outer clip track for scroll mode — hides overflow so the looping animation\n * is invisible at the edges.\n */\nexport const marqueeStripScrollOuterClass = 'overflow-hidden px-4'\n\n/**\n * Moving track for scroll mode.\n *\n * The `marquee` keyframe must be defined in the consuming app's global CSS\n * (or via a Tailwind plugin). The canonical definition is:\n *\n * ```css\n * @keyframes marquee {\n * from { transform: translateX(0); }\n * to { transform: translateX(-50%); }\n * }\n * ```\n *\n * Items are duplicated once by the adapter so the strip appears seamless\n * (the track is effectively 200 % wide and translates to –50 %).\n */\nexport const marqueeStripScrollTrackClass =\n 'flex items-center gap-3 w-max animate-[marquee_30s_linear_infinite]'\n\n/** Strip label — shown before the items (uppercase eyebrow style). */\nexport const marqueeStripLabelClass =\n 'text-xs font-semibold uppercase tracking-widest text-muted-foreground shrink-0'\n\n/** Individual item text. */\nexport const marqueeStripItemClass = 'text-sm text-foreground'\n", "import * as React from 'react'\nimport {\n createMarqueeStrip,\n marqueeStripVariants,\n marqueeStripInnerClass,\n marqueeStripScrollOuterClass,\n marqueeStripScrollTrackClass,\n marqueeStripLabelClass,\n marqueeStripItemClass,\n} from '@refraction-ui/marquee-strip'\nimport { cn } from '@refraction-ui/shared'\n\nexport interface MarqueeStripProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'content'> {\n /** Eyebrow label shown before the items. */\n label?: string\n /** List of text items to display. */\n items: string[]\n /**\n * When `true` the items scroll continuously using a CSS `marquee` keyframe.\n * The keyframe must be defined in the consuming app's global CSS:\n *\n * ```css\n * @keyframes marquee {\n * from { transform: translateX(0); }\n * to { transform: translateX(-50%); }\n * }\n * ```\n *\n * @default false\n */\n scroll?: boolean\n}\n\n/**\n * MarqueeStrip — a full-width label + tag strip, optionally scrolling.\n *\n * Static mode (`scroll={false}`, default): items flex-wrap in a row after the\n * label. Scroll mode: items loop continuously via a CSS marquee animation;\n * items are duplicated once internally for a seamless loop. Logic and\n * data attributes come from the headless `@refraction-ui/marquee-strip` core.\n */\nexport const MarqueeStrip = React.forwardRef<HTMLDivElement, MarqueeStripProps>(\n function MarqueeStrip({ label, items, scroll = false, className, ...props }, ref) {\n const api = createMarqueeStrip({ scroll })\n\n return (\n <div\n ref={ref}\n className={cn(marqueeStripVariants({ scroll: scroll ? 'true' : 'false' }), className)}\n {...api.ariaProps}\n {...api.dataAttributes}\n {...props}\n >\n {scroll ? (\n <div className={marqueeStripScrollOuterClass}>\n <div className={marqueeStripScrollTrackClass}>\n {[...items, ...items].map((item, index) => (\n <span key={index} className={marqueeStripItemClass}>\n {item}\n </span>\n ))}\n </div>\n </div>\n ) : (\n <div className={marqueeStripInnerClass}>\n {label != null && (\n <span className={marqueeStripLabelClass}>{label}</span>\n )}\n {items.map((item, index) => (\n <span key={index} className={marqueeStripItemClass}>\n {item}\n </span>\n ))}\n </div>\n )}\n </div>\n )\n },\n)\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;AAsBO,SAAS,mBAAmB,QAA2B,CAAA,GAAqB;AACjF,QAAM,EAAE,SAAS,MAAA,IAAU;AAE3B,QAAM,YAAyC;IAC7C,MAAM;EAAA;AAGR,QAAM,iBAAyC;IAC7C,eAAe,OAAO,MAAM;EAAA;AAG9B,SAAO,EAAE,WAAW,eAAA;AACtB;ACzBO,IAAM,uBAAuB,IAAI;EACtC,MAAM;EACN,UAAU;IACR,QAAQ;MACN,MAAM;MACN,OAAO;IAAA;EACT;EAEF,iBAAiB;IACf,QAAQ;EAAA;AAEZ,CAAC;AAOM,IAAM,yBACX;AAMK,IAAM,+BAA+B;AAkBrC,IAAM,+BACX;AAGK,IAAM,yBACX;AAGK,IAAM,wBAAwB;;;;AClB9B,IAAM,eAAqB;EAChC,SAASA,cAAa,EAAE,OAAO,OAAO,SAAS,OAAO,WAAW,GAAG,MAAA,GAAS,KAAK;AAChF,UAAM,MAAM,mBAAmB,EAAE,OAAA,CAAQ;AAEzC,WACE;MAAC;MAAA;QACC;QACA,WAAW,GAAG,qBAAqB,EAAE,QAAQ,SAAS,SAAS,QAAA,CAAS,GAAG,SAAS;QACnF,GAAG,IAAI;QACP,GAAG,IAAI;QACP,GAAG;QAEH,UAAA,SACC,oBAAC,OAAA,EAAI,WAAW,8BACd,UAAA,oBAAC,OAAA,EAAI,WAAW,8BACb,UAAA,CAAC,GAAG,OAAO,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,UAC/B,oBAAC,QAAA,EAAiB,WAAW,uBAC1B,UAAA,KAAA,GADQ,KAEX,CACD,EAAA,CACH,EAAA,CACF,IAEA,qBAAC,OAAA,EAAI,WAAW,wBACb,UAAA;UAAA,SAAS,QACR,oBAAC,QAAA,EAAK,WAAW,wBAAyB,UAAA,MAAA,CAAM;UAEjD,MAAM,IAAI,CAAC,MAAM,UAChB,oBAAC,QAAA,EAAiB,WAAW,uBAC1B,UAAA,KAAA,GADQ,KAEX,CACD;QAAA,EAAA,CACH;MAAA;IAAA;EAIR;AACF;",
|
|
6
|
+
"names": ["MarqueeStrip"]
|
|
7
|
+
}
|