@pie-players/pie-players-shared 0.3.61 → 0.3.63
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/config/profile.js +0 -1
- package/dist/i18n/index.js +0 -1
- package/dist/i18n/loader.js +0 -1
- package/dist/i18n/simple-i18n.js +0 -1
- package/dist/i18n/types.js +0 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/instrumentation/debug-panel-stream.js +0 -1
- package/dist/instrumentation/index.js +0 -1
- package/dist/instrumentation/provider-guards.js +0 -1
- package/dist/instrumentation/providers/BaseInstrumentationProvider.js +0 -1
- package/dist/instrumentation/providers/CompositeInstrumentationProvider.js +0 -1
- package/dist/instrumentation/providers/ConsoleInstrumentationProvider.js +0 -1
- package/dist/instrumentation/providers/DebugPanelInstrumentationProvider.js +0 -1
- package/dist/instrumentation/providers/NewRelicInstrumentationProvider.js +0 -1
- package/dist/instrumentation/providers/index.js +0 -1
- package/dist/instrumentation/types.js +0 -1
- package/dist/loader-config.js +0 -1
- package/dist/loaders/ElementLoader.js +0 -1
- package/dist/loaders/element-loader-types.js +0 -1
- package/dist/loaders/element-loader.js +0 -1
- package/dist/loaders/element-package-policy.js +0 -1
- package/dist/loaders/esm-adapter.js +0 -1
- package/dist/loaders/iife-adapter.js +0 -1
- package/dist/loaders/index.js +0 -1
- package/dist/object/index.js +0 -1
- package/dist/pie/asset-handler.js +0 -1
- package/dist/pie/authoring-tag.js +0 -1
- package/dist/pie/authoring.js +0 -1
- package/dist/pie/component-context.js +0 -1
- package/dist/pie/config.js +0 -1
- package/dist/pie/configure-initialization.js +0 -1
- package/dist/pie/correct-response-env.js +0 -1
- package/dist/pie/custom-element-define.js +0 -1
- package/dist/pie/index.js +0 -1
- package/dist/pie/initialization.js +0 -1
- package/dist/pie/instrumentation-event-bridge.js +0 -1
- package/dist/pie/instrumentation-event-map.js +0 -1
- package/dist/pie/instrumentation-provider-resolution.js +0 -1
- package/dist/pie/item-controller-storage.js +0 -1
- package/dist/pie/item-controller.js +0 -1
- package/dist/pie/item-session-contract.js +0 -1
- package/dist/pie/logger.js +0 -1
- package/dist/pie/math-rendering.js +0 -1
- package/dist/pie/overrides.js +0 -1
- package/dist/pie/player-initializer.js +0 -1
- package/dist/pie/registry.js +0 -1
- package/dist/pie/resource-monitor.js +0 -1
- package/dist/pie/scoring.js +0 -1
- package/dist/pie/stage-tracker.js +0 -1
- package/dist/pie/stages.js +0 -1
- package/dist/pie/tag-names.js +0 -1
- package/dist/pie/types.js +0 -1
- package/dist/pie/updates.js +0 -1
- package/dist/pie/utils.js +0 -1
- package/dist/pie/versioned-tag.js +0 -1
- package/dist/player-strategy.js +0 -1
- package/dist/security/index.js +0 -1
- package/dist/security/sanitize-item-markup.d.ts +11 -0
- package/dist/security/sanitize-item-markup.js +5 -3
- package/dist/security/sanitize-svg-icon.js +0 -1
- package/dist/security/validate-style-url.js +0 -1
- package/dist/security/wrap-model-rich-content.js +0 -1
- package/dist/security/wrap-overwide-images.js +0 -1
- package/dist/security/wrap-overwide-tables.js +0 -1
- package/dist/server/npm-registry.js +0 -1
- package/dist/types/index.js +0 -1
- package/dist/ui/content-styles.js +0 -1
- package/dist/ui/debug-panel-persistence.js +0 -1
- package/dist/ui/first-focusable.js +0 -1
- package/dist/ui/focus-trap.js +0 -1
- package/dist/ui/safe-storage.js +0 -1
- package/dist/ui/scope-css.d.ts +56 -0
- package/dist/ui/scope-css.js +310 -0
- package/dist/ui/zoom-compensation.js +0 -1
- package/package.json +4 -4
- package/dist/config/profile.js.map +0 -1
- package/dist/i18n/index.js.map +0 -1
- package/dist/i18n/loader.js.map +0 -1
- package/dist/i18n/simple-i18n.js.map +0 -1
- package/dist/i18n/types.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/instrumentation/debug-panel-stream.js.map +0 -1
- package/dist/instrumentation/index.js.map +0 -1
- package/dist/instrumentation/provider-guards.js.map +0 -1
- package/dist/instrumentation/providers/BaseInstrumentationProvider.js.map +0 -1
- package/dist/instrumentation/providers/CompositeInstrumentationProvider.js.map +0 -1
- package/dist/instrumentation/providers/ConsoleInstrumentationProvider.js.map +0 -1
- package/dist/instrumentation/providers/DebugPanelInstrumentationProvider.js.map +0 -1
- package/dist/instrumentation/providers/NewRelicInstrumentationProvider.js.map +0 -1
- package/dist/instrumentation/providers/index.js.map +0 -1
- package/dist/instrumentation/types.js.map +0 -1
- package/dist/loader-config.js.map +0 -1
- package/dist/loaders/ElementLoader.js.map +0 -1
- package/dist/loaders/element-loader-types.js.map +0 -1
- package/dist/loaders/element-loader.js.map +0 -1
- package/dist/loaders/element-package-policy.js.map +0 -1
- package/dist/loaders/esm-adapter.js.map +0 -1
- package/dist/loaders/iife-adapter.js.map +0 -1
- package/dist/loaders/index.js.map +0 -1
- package/dist/object/index.js.map +0 -1
- package/dist/pie/asset-handler.js.map +0 -1
- package/dist/pie/authoring-tag.js.map +0 -1
- package/dist/pie/authoring.js.map +0 -1
- package/dist/pie/component-context.js.map +0 -1
- package/dist/pie/config.js.map +0 -1
- package/dist/pie/configure-initialization.js.map +0 -1
- package/dist/pie/correct-response-env.js.map +0 -1
- package/dist/pie/custom-element-define.js.map +0 -1
- package/dist/pie/index.js.map +0 -1
- package/dist/pie/initialization.js.map +0 -1
- package/dist/pie/instrumentation-event-bridge.js.map +0 -1
- package/dist/pie/instrumentation-event-map.js.map +0 -1
- package/dist/pie/instrumentation-provider-resolution.js.map +0 -1
- package/dist/pie/item-controller-storage.js.map +0 -1
- package/dist/pie/item-controller.js.map +0 -1
- package/dist/pie/item-session-contract.js.map +0 -1
- package/dist/pie/logger.js.map +0 -1
- package/dist/pie/math-rendering.js.map +0 -1
- package/dist/pie/overrides.js.map +0 -1
- package/dist/pie/player-initializer.js.map +0 -1
- package/dist/pie/registry.js.map +0 -1
- package/dist/pie/resource-monitor.js.map +0 -1
- package/dist/pie/scoring.js.map +0 -1
- package/dist/pie/stage-tracker.js.map +0 -1
- package/dist/pie/stages.js.map +0 -1
- package/dist/pie/tag-names.js.map +0 -1
- package/dist/pie/types.js.map +0 -1
- package/dist/pie/updates.js.map +0 -1
- package/dist/pie/utils.js.map +0 -1
- package/dist/pie/versioned-tag.js.map +0 -1
- package/dist/player-strategy.js.map +0 -1
- package/dist/security/index.js.map +0 -1
- package/dist/security/sanitize-item-markup.js.map +0 -1
- package/dist/security/sanitize-svg-icon.js.map +0 -1
- package/dist/security/validate-style-url.js.map +0 -1
- package/dist/security/wrap-model-rich-content.js.map +0 -1
- package/dist/security/wrap-overwide-images.js.map +0 -1
- package/dist/security/wrap-overwide-tables.js.map +0 -1
- package/dist/server/npm-registry.js.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/ui/content-styles.js.map +0 -1
- package/dist/ui/debug-panel-persistence.js.map +0 -1
- package/dist/ui/first-focusable.js.map +0 -1
- package/dist/ui/focus-trap.js.map +0 -1
- package/dist/ui/safe-storage.js.map +0 -1
- package/dist/ui/zoom-compensation.js.map +0 -1
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope an external stylesheet's rules to a single player instance, so a
|
|
3
|
+
* partner-authored stylesheet loaded via `<pie-item-player
|
|
4
|
+
* external-style-urls="...">` or `itemConfig.resources.stylesheets[*].url`
|
|
5
|
+
* styles that player's subtree instead of the whole host document.
|
|
6
|
+
*
|
|
7
|
+
* This replaces a single-regex implementation that prefixed every
|
|
8
|
+
* selector-like fragment. That is correct for flat selector rules and wrong for
|
|
9
|
+
* everything else: `@media screen { ... }` became
|
|
10
|
+
* `.scope @media screen { ... }`, an invalid selector, so the browser dropped
|
|
11
|
+
* the whole block and every rule inside it; `@font-face` and `@keyframes` were
|
|
12
|
+
* corrupted the same way; and `:root` became `.scope :root`, which can never
|
|
13
|
+
* match, because `:root` is `<html>` and is not a descendant of the player.
|
|
14
|
+
* At-rules and `:root` custom properties therefore never applied at all.
|
|
15
|
+
*
|
|
16
|
+
* The QTI player's `scopeCssRules` (`pie-qti` -
|
|
17
|
+
* `packages/item-player/src/components/utils/stylesheetRender.ts`) is not a
|
|
18
|
+
* drop-in either. Its `:root` handling is the behaviour we want and is adopted
|
|
19
|
+
* here, but it excludes `@` from its selector pattern rather than understanding
|
|
20
|
+
* at-rules, so `@media` and `@supports` lose their condition and their inner
|
|
21
|
+
* rules are hoisted and applied unconditionally — a mobile-only rule then
|
|
22
|
+
* applies at every viewport width, which is a subtler failure than dropping it.
|
|
23
|
+
*
|
|
24
|
+
* So this walks the stylesheet brace-by-brace instead of pattern-matching it.
|
|
25
|
+
* A real CSS parser would be the textbook answer and is deliberately not used:
|
|
26
|
+
* `@pie-players/pie-item-player` ships with two workspace dependencies, this
|
|
27
|
+
* runs in the delivery path, and scoping needs to know about rule boundaries
|
|
28
|
+
* only — not about property grammar.
|
|
29
|
+
*
|
|
30
|
+
* Known limits, all preserving existing behaviour rather than adding policy:
|
|
31
|
+
*
|
|
32
|
+
* - `@import` is passed through untouched, exactly as the old regex left it. It
|
|
33
|
+
* pulls in an unscoped stylesheet, so it defeats scoping, but blocking it is
|
|
34
|
+
* a security policy decision and not this function's job. Callers gate
|
|
35
|
+
* stylesheet URLs with `validateExternalStyleUrl` before fetching.
|
|
36
|
+
* - Declaration blocks are emitted verbatim, so `url(...)` references are left
|
|
37
|
+
* as authored and resolve against the stylesheet's own URL as before.
|
|
38
|
+
* - A style rule's block is never rewritten, which is also what native CSS
|
|
39
|
+
* nesting needs: nested selectors are relative to a parent that has already
|
|
40
|
+
* been scoped.
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* At-rules whose block contains nested *rules*, so scoping has to recurse into
|
|
44
|
+
* the block while the prelude is preserved verbatim.
|
|
45
|
+
*
|
|
46
|
+
* Everything not listed here is passed through untouched. That is the safe
|
|
47
|
+
* default in both directions: at-rules whose block holds declarations rather
|
|
48
|
+
* than rules (`@font-face`, `@page`, `@property`, `@counter-style`) or
|
|
49
|
+
* non-selector keys (`@keyframes` percentages) must not be scoped, and an
|
|
50
|
+
* at-rule this list has never heard of is more safely left alone than guessed
|
|
51
|
+
* at.
|
|
52
|
+
*/
|
|
53
|
+
const NESTED_RULE_AT_RULES = new Set([
|
|
54
|
+
"media",
|
|
55
|
+
"supports",
|
|
56
|
+
"container",
|
|
57
|
+
"layer",
|
|
58
|
+
"scope",
|
|
59
|
+
]);
|
|
60
|
+
/** Matches a leading `:root`, `html` or `body` not followed by more name characters. */
|
|
61
|
+
const DOCUMENT_ROOT_PREFIX = /^(?::root|html|body)(?![\w-])/;
|
|
62
|
+
/** Matches an at-rule name, with any vendor prefix, at the start of a prelude. */
|
|
63
|
+
const AT_RULE_NAME = /^@(?:-[a-z]+-)?([\w-]+)/i;
|
|
64
|
+
/**
|
|
65
|
+
* Rewrite `cssText` so every selector it contains is confined to
|
|
66
|
+
* `scopeSelector`.
|
|
67
|
+
*
|
|
68
|
+
* Returns `cssText` unchanged when there is no scope selector to apply, and
|
|
69
|
+
* `""` for empty or non-string input.
|
|
70
|
+
*/
|
|
71
|
+
export function scopeStylesheetCss(cssText, scopeSelector) {
|
|
72
|
+
if (typeof cssText !== "string" || cssText.length === 0)
|
|
73
|
+
return "";
|
|
74
|
+
const scope = scopeSelector?.trim();
|
|
75
|
+
if (!scope)
|
|
76
|
+
return cssText;
|
|
77
|
+
return scopeRuleList(stripComments(cssText), scope);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Confine a single selector to `scopeSelector`.
|
|
81
|
+
*
|
|
82
|
+
* Exported for tests and for callers that scope a selector they built
|
|
83
|
+
* themselves; `scopeStylesheetCss` is the entry point for stylesheet text.
|
|
84
|
+
*/
|
|
85
|
+
export function scopeSelector(selector, scopeSelector) {
|
|
86
|
+
const sel = selector.trim();
|
|
87
|
+
const scope = scopeSelector.trim();
|
|
88
|
+
if (!sel || !scope)
|
|
89
|
+
return "";
|
|
90
|
+
// Idempotent: re-scoping already-scoped CSS must not nest the scope twice.
|
|
91
|
+
// Deliberately narrow — a bare `startsWith` would also skip an authored
|
|
92
|
+
// selector that merely shares the scope's leading characters.
|
|
93
|
+
if (sel === scope || sel.startsWith(`${scope} `))
|
|
94
|
+
return sel;
|
|
95
|
+
// `:root`/`html`/`body` are replaced rather than prefixed. Prefixing yields
|
|
96
|
+
// `.scope :root`, a selector that cannot match, which is how external
|
|
97
|
+
// `:root { --var: ... }` custom properties used to disappear. Any compound
|
|
98
|
+
// or combinator that followed is preserved: `html.dark .a` -> `.scope.dark .a`.
|
|
99
|
+
const rootPrefix = DOCUMENT_ROOT_PREFIX.exec(sel);
|
|
100
|
+
if (rootPrefix)
|
|
101
|
+
return `${scope}${sel.slice(rootPrefix[0].length)}`;
|
|
102
|
+
// Everything else becomes a descendant, including a leading pseudo-class or
|
|
103
|
+
// pseudo-element. `pie-qti`'s scoper attaches those to the scope instead,
|
|
104
|
+
// which is not the same selector: `:is(.a, .b) .c` authored at stylesheet
|
|
105
|
+
// level means "some element matching .a or .b", so attaching it demands that
|
|
106
|
+
// the *player root* carry the partner's class, and it never does. The same
|
|
107
|
+
// holds for `:hover` and `::selection` — the author meant an element in the
|
|
108
|
+
// content, not the player's own box. Root selectors are the one case where
|
|
109
|
+
// attaching is right, and they are handled above.
|
|
110
|
+
return `${scope} ${sel}`;
|
|
111
|
+
}
|
|
112
|
+
function scopeRuleList(css, scope) {
|
|
113
|
+
let out = "";
|
|
114
|
+
let index = 0;
|
|
115
|
+
while (index < css.length) {
|
|
116
|
+
const node = readNode(css, index);
|
|
117
|
+
if (node.end <= index)
|
|
118
|
+
break;
|
|
119
|
+
out += renderNode(node, scope);
|
|
120
|
+
index = node.end;
|
|
121
|
+
}
|
|
122
|
+
return out;
|
|
123
|
+
}
|
|
124
|
+
function renderNode(node, scope) {
|
|
125
|
+
if (node.kind === "statement") {
|
|
126
|
+
const text = node.text.trim();
|
|
127
|
+
// A stray `;` at rule-list level carries nothing worth re-emitting.
|
|
128
|
+
return text === ";" ? "" : `${text}\n`;
|
|
129
|
+
}
|
|
130
|
+
if (node.kind === "trailing") {
|
|
131
|
+
// Only whitespace is expected here; anything else is malformed CSS that
|
|
132
|
+
// is better passed through than dropped.
|
|
133
|
+
return node.text.trim() ? `${node.text.trim()}\n` : "";
|
|
134
|
+
}
|
|
135
|
+
const prelude = node.prelude.trim();
|
|
136
|
+
if (!prelude)
|
|
137
|
+
return "";
|
|
138
|
+
if (prelude.startsWith("@")) {
|
|
139
|
+
const name = AT_RULE_NAME.exec(prelude)?.[1]?.toLowerCase();
|
|
140
|
+
if (name && NESTED_RULE_AT_RULES.has(name)) {
|
|
141
|
+
const inner = scopeRuleList(node.block, scope);
|
|
142
|
+
if (!inner.trim())
|
|
143
|
+
return "";
|
|
144
|
+
return `${prelude} {\n${inner}}\n`;
|
|
145
|
+
}
|
|
146
|
+
return `${prelude} {${node.block}}\n`;
|
|
147
|
+
}
|
|
148
|
+
const selectors = splitTopLevel(prelude, ",")
|
|
149
|
+
.map((selector) => scopeSelector(selector, scope))
|
|
150
|
+
.filter(Boolean);
|
|
151
|
+
if (selectors.length === 0)
|
|
152
|
+
return "";
|
|
153
|
+
return `${selectors.join(", ")} {${node.block}}\n`;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Read one node starting at `start`, tracking strings and parentheses so a `{`
|
|
157
|
+
* inside `content: "{"` or a `,` inside `:is(a, b)` is not mistaken for
|
|
158
|
+
* structure.
|
|
159
|
+
*/
|
|
160
|
+
function readNode(css, start) {
|
|
161
|
+
let index = start;
|
|
162
|
+
let quote = null;
|
|
163
|
+
let parenDepth = 0;
|
|
164
|
+
while (index < css.length) {
|
|
165
|
+
const char = css[index];
|
|
166
|
+
if (quote) {
|
|
167
|
+
if (char === "\\")
|
|
168
|
+
index += 1;
|
|
169
|
+
else if (char === quote)
|
|
170
|
+
quote = null;
|
|
171
|
+
}
|
|
172
|
+
else if (char === '"' || char === "'") {
|
|
173
|
+
quote = char;
|
|
174
|
+
}
|
|
175
|
+
else if (char === "(") {
|
|
176
|
+
parenDepth += 1;
|
|
177
|
+
}
|
|
178
|
+
else if (char === ")") {
|
|
179
|
+
if (parenDepth > 0)
|
|
180
|
+
parenDepth -= 1;
|
|
181
|
+
}
|
|
182
|
+
else if (parenDepth === 0 && char === ";") {
|
|
183
|
+
return {
|
|
184
|
+
kind: "statement",
|
|
185
|
+
text: css.slice(start, index + 1),
|
|
186
|
+
end: index + 1,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
else if (parenDepth === 0 && char === "{") {
|
|
190
|
+
const blockEnd = findBlockEnd(css, index);
|
|
191
|
+
return {
|
|
192
|
+
kind: "rule",
|
|
193
|
+
prelude: css.slice(start, index),
|
|
194
|
+
block: css.slice(index + 1, blockEnd.contentEnd),
|
|
195
|
+
end: blockEnd.end,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
index += 1;
|
|
199
|
+
}
|
|
200
|
+
return { kind: "trailing", text: css.slice(start), end: css.length };
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Find the `}` matching the `{` at `openIndex`. Unbalanced input (a truncated
|
|
204
|
+
* stylesheet) is treated as running to the end rather than throwing.
|
|
205
|
+
*/
|
|
206
|
+
function findBlockEnd(css, openIndex) {
|
|
207
|
+
let depth = 0;
|
|
208
|
+
let quote = null;
|
|
209
|
+
for (let index = openIndex; index < css.length; index += 1) {
|
|
210
|
+
const char = css[index];
|
|
211
|
+
if (quote) {
|
|
212
|
+
if (char === "\\")
|
|
213
|
+
index += 1;
|
|
214
|
+
else if (char === quote)
|
|
215
|
+
quote = null;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (char === '"' || char === "'") {
|
|
219
|
+
quote = char;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
if (char === "{")
|
|
223
|
+
depth += 1;
|
|
224
|
+
else if (char === "}") {
|
|
225
|
+
depth -= 1;
|
|
226
|
+
if (depth === 0)
|
|
227
|
+
return { contentEnd: index, end: index + 1 };
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return { contentEnd: css.length, end: css.length };
|
|
231
|
+
}
|
|
232
|
+
/** Split on `separator` at paren depth zero and outside strings. */
|
|
233
|
+
function splitTopLevel(value, separator) {
|
|
234
|
+
const parts = [];
|
|
235
|
+
let current = "";
|
|
236
|
+
let quote = null;
|
|
237
|
+
let parenDepth = 0;
|
|
238
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
239
|
+
const char = value[index];
|
|
240
|
+
if (quote) {
|
|
241
|
+
current += char;
|
|
242
|
+
if (char === "\\" && index + 1 < value.length) {
|
|
243
|
+
current += value[index + 1];
|
|
244
|
+
index += 1;
|
|
245
|
+
}
|
|
246
|
+
else if (char === quote) {
|
|
247
|
+
quote = null;
|
|
248
|
+
}
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
if (char === '"' || char === "'") {
|
|
252
|
+
quote = char;
|
|
253
|
+
current += char;
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
if (char === "(")
|
|
257
|
+
parenDepth += 1;
|
|
258
|
+
else if (char === ")" && parenDepth > 0)
|
|
259
|
+
parenDepth -= 1;
|
|
260
|
+
if (char === separator && parenDepth === 0) {
|
|
261
|
+
parts.push(current);
|
|
262
|
+
current = "";
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
current += char;
|
|
266
|
+
}
|
|
267
|
+
parts.push(current);
|
|
268
|
+
return parts;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Remove comments before walking, so a comment sitting between two rules is not
|
|
272
|
+
* absorbed into the next rule's selector list. String-aware, so a literal
|
|
273
|
+
* `content: "/*"` survives.
|
|
274
|
+
*/
|
|
275
|
+
function stripComments(css) {
|
|
276
|
+
let out = "";
|
|
277
|
+
let quote = null;
|
|
278
|
+
let index = 0;
|
|
279
|
+
while (index < css.length) {
|
|
280
|
+
const char = css[index];
|
|
281
|
+
if (quote) {
|
|
282
|
+
out += char;
|
|
283
|
+
if (char === "\\" && index + 1 < css.length) {
|
|
284
|
+
out += css[index + 1];
|
|
285
|
+
index += 2;
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (char === quote)
|
|
289
|
+
quote = null;
|
|
290
|
+
index += 1;
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (char === '"' || char === "'") {
|
|
294
|
+
quote = char;
|
|
295
|
+
out += char;
|
|
296
|
+
index += 1;
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (char === "/" && css[index + 1] === "*") {
|
|
300
|
+
const close = css.indexOf("*/", index + 2);
|
|
301
|
+
index = close === -1 ? css.length : close + 2;
|
|
302
|
+
// Keep a space so `a/**/b` does not become the single token `ab`.
|
|
303
|
+
out += " ";
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
out += char;
|
|
307
|
+
index += 1;
|
|
308
|
+
}
|
|
309
|
+
return out;
|
|
310
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-players-shared",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.63",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared runtime + UI utilities for PIE players",
|
|
6
6
|
"license": "MIT",
|
|
@@ -89,11 +89,11 @@
|
|
|
89
89
|
"scan-hardcoded": "bun run src/i18n/scripts/scan-hardcoded.ts"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
|
-
"@biomejs/biome": "^2.
|
|
93
|
-
"@happy-dom/global-registrator": "^20.
|
|
92
|
+
"@biomejs/biome": "^2.5.6",
|
|
93
|
+
"@happy-dom/global-registrator": "^20.11.1",
|
|
94
94
|
"@types/semver": "^7.7.1",
|
|
95
95
|
"glob": "^13.0.0",
|
|
96
|
-
"svelte": "^5.
|
|
96
|
+
"svelte": "^5.56.8",
|
|
97
97
|
"typescript": "^5.9.3"
|
|
98
98
|
},
|
|
99
99
|
"homepage": "https://github.com/pie-framework/pie-players/tree/master/packages/players-shared#readme",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/config/profile.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,8EAA8E;AAC9E,4EAA4E;AAC5E,MAAM,0BAA0B,GAAG,2BAA2B,CAAC;AAC/D,MAAM,0BAA0B,GAAG,GAAG,0BAA0B,WAAW,CAAC;AAS5E,SAAS,aAAa,CAAC,GAAW;IACjC,IAAI,CAAC;QACJ,sBAAsB;QACtB,MAAM,CAAC,GAAI,MAAM,CAAC,IAAY,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAC9B,CAAC,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,sBAAsB,CAAC;IAChE,aAAa,CAAC,2BAA2B,CAAC;IAC1C,0BAA0B,CAAC;AAE5B,MAAM,CAAC,MAAM,kBAAkB,GAC9B,CAAC,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,sBAAsB,CAAC;IAChE,aAAa,CAAC,2BAA2B,CAAC;IAC1C,0BAA0B,CAAC","sourcesContent":["/**\n * Minimal, frontend-safe defaults for PIE build service URLs.\n *\n * In PIEOneer, these come from `$env/dynamic/public`. In `pie-players` we avoid\n * SvelteKit env dependencies so this can be consumed by any bundler.\n */\n\n// Default public bundle host. Keep this aligned with the IIFE loader default.\n// (We prefer the proxy endpoint, which is stable/cached for browser usage.)\nconst DEFAULT_BUILDER_ORIGIN_URL = \"https://proxy.pie-api.com\";\nconst DEFAULT_BUILDER_BUNDLE_URL = `${DEFAULT_BUILDER_ORIGIN_URL}/bundles/`;\n\ndeclare global {\n\tinterface Window {\n\t\tPIE_BUILDER_ORIGIN_URL?: string;\n\t\tPIE_BUILDER_BUNDLE_URL?: string;\n\t}\n}\n\nfunction readPublicEnv(key: string): string | undefined {\n\ttry {\n\t\t// Vite/SvelteKit-like\n\t\tconst v = (import.meta as any)?.env?.[key];\n\t\tif (typeof v === \"string\" && v.length > 0) return v;\n\t} catch {}\n\treturn undefined;\n}\n\nexport const BUILDER_ORIGIN_URL =\n\t(typeof window !== \"undefined\" && window.PIE_BUILDER_ORIGIN_URL) ||\n\treadPublicEnv(\"PUBLIC_BUILDER_ORIGIN_URL\") ||\n\tDEFAULT_BUILDER_ORIGIN_URL;\n\nexport const BUILDER_BUNDLE_URL =\n\t(typeof window !== \"undefined\" && window.PIE_BUILDER_BUNDLE_URL) ||\n\treadPublicEnv(\"PUBLIC_BUILDER_BUNDLE_URL\") ||\n\tDEFAULT_BUILDER_BUNDLE_URL;\n"]}
|
package/dist/i18n/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/i18n/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACN,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["/**\n * I18n Module\n *\n * Internationalization system for PIE Players.\n *\n * @module @pie-players/pie-players-shared/i18n\n */\n\nexport {\n\tBUNDLED_TRANSLATIONS,\n\tgetAvailableLocales,\n\tisRTLLocale,\n\tloadTranslations,\n} from \"./loader.js\";\nexport { SimpleI18n } from \"./simple-i18n.js\";\nexport type {\n\tI18nConfig,\n\tI18nServiceApi,\n\tPluralTranslation,\n\tTranslationBundle,\n} from \"./types.js\";\n"]}
|
package/dist/i18n/loader.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/i18n/loader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Translation Loader\n *\n * Implements hybrid loading strategy:\n * - English bundled with application\n * - Other languages loaded on demand\n *\n * Part of PIE Players i18n system.\n */\n\n// Import English translations (bundled)\nimport enCommon from \"./translations/en/common.json\" with { type: \"json\" };\nimport enToolkit from \"./translations/en/toolkit.json\" with { type: \"json\" };\nimport enTools from \"./translations/en/tools.json\" with { type: \"json\" };\nimport type { TranslationBundle } from \"./types.js\";\n\n// RTL locales\nconst RTL_LOCALES = [\"ar\", \"he\", \"fa\", \"ur\"];\n\n/**\n * Bundled English translations\n * Available immediately without network request\n */\nexport const BUNDLED_TRANSLATIONS: Record<string, TranslationBundle> = {\n\ten: {\n\t\tlocale: \"en\",\n\t\tdirection: \"ltr\",\n\t\ttranslations: {\n\t\t\t...flattenTranslations(enCommon),\n\t\t\t...flattenTranslations(enToolkit),\n\t\t\t...flattenTranslations(enTools),\n\t\t},\n\t},\n};\n\nconst LOCALE_IMPORTS: Record<string, () => Promise<[any, any, any]>> = {\n\tes: () =>\n\t\tPromise.all([\n\t\t\timport(\"./translations/es/common.json\"),\n\t\t\timport(\"./translations/es/toolkit.json\"),\n\t\t\timport(\"./translations/es/tools.json\"),\n\t\t]),\n\tzh: () =>\n\t\tPromise.all([\n\t\t\timport(\"./translations/zh/common.json\"),\n\t\t\timport(\"./translations/zh/toolkit.json\"),\n\t\t\timport(\"./translations/zh/tools.json\"),\n\t\t]),\n\tar: () =>\n\t\tPromise.all([\n\t\t\timport(\"./translations/ar/common.json\"),\n\t\t\timport(\"./translations/ar/toolkit.json\"),\n\t\t\timport(\"./translations/ar/tools.json\"),\n\t\t]),\n};\n\n/**\n * Load translations for a locale\n *\n * @param locale Locale code (e.g., 'en', 'es', 'zh', 'ar')\n * @returns Translation bundle with flattened keys\n */\nexport async function loadTranslations(\n\tlocale: string,\n): Promise<TranslationBundle> {\n\t// Return bundled English immediately\n\tif (locale === \"en\") {\n\t\treturn BUNDLED_TRANSLATIONS.en;\n\t}\n\n\tconst importer = LOCALE_IMPORTS[locale];\n\tif (!importer) {\n\t\tthrow new Error(\n\t\t\t`Translation files not found for locale: ${locale}. Ensure translation files exist in packages/players-shared/src/i18n/translations/${locale}/`,\n\t\t);\n\t}\n\n\t// Lazy load other locales\n\ttry {\n\t\tconst [common, toolkit, tools] = await importer();\n\n\t\treturn {\n\t\t\tlocale,\n\t\t\tdirection: RTL_LOCALES.includes(locale) ? \"rtl\" : \"ltr\",\n\t\t\ttranslations: {\n\t\t\t\t...flattenTranslations(common.default || common),\n\t\t\t\t...flattenTranslations(toolkit.default || toolkit),\n\t\t\t\t...flattenTranslations(tools.default || tools),\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tconsole.error(`Failed to load translations for locale: ${locale}`, error);\n\t\tthrow new Error(\n\t\t\t`Translation files not found for locale: ${locale}. Ensure translation files exist in packages/players-shared/src/i18n/translations/${locale}/`,\n\t\t);\n\t}\n}\n\n/**\n * Flatten nested JSON to dot notation\n *\n * Converts:\n * { \"common\": { \"save\": \"Save\" } }\n *\n * To:\n * { \"common.save\": \"Save\" }\n *\n * @param obj Nested translation object\n * @param prefix Current key prefix\n * @param result Accumulated result\n * @returns Flattened translation object\n */\nfunction flattenTranslations(\n\tobj: any,\n\tprefix = \"\",\n\tresult: Record<string, any> = {},\n): Record<string, any> {\n\tfor (const [key, value] of Object.entries(obj)) {\n\t\tconst newKey = prefix ? `${prefix}.${key}` : key;\n\n\t\tif (value && typeof value === \"object\" && !Array.isArray(value)) {\n\t\t\t// Check if it's a plural form (has 'one' or 'other' keys)\n\t\t\tif (\"one\" in value || \"other\" in value) {\n\t\t\t\t// This is a plural translation, keep it as an object\n\t\t\t\tresult[newKey] = value;\n\t\t\t} else {\n\t\t\t\t// This is a nested object, flatten recursively\n\t\t\t\tflattenTranslations(value, newKey, result);\n\t\t\t}\n\t\t} else {\n\t\t\t// This is a leaf value\n\t\t\tresult[newKey] = value;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Get available locales\n *\n * @returns Array of locale codes\n */\nexport function getAvailableLocales(): string[] {\n\treturn [\"en\", \"es\", \"zh\", \"ar\"];\n}\n\n/**\n * Check if locale is RTL\n *\n * @param locale Locale code\n * @returns True if locale is right-to-left\n */\nexport function isRTLLocale(locale: string): boolean {\n\treturn RTL_LOCALES.includes(locale);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"simple-i18n.js","sourceRoot":"","sources":["../../src/i18n/simple-i18n.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Simple I18n Implementation\n *\n * Lightweight i18n without external dependencies.\n * Used for standalone components that don't need the full service architecture.\n */\n\nimport type {\n\tI18nConfig,\n\tPluralTranslation,\n\tTranslationBundle,\n} from \"./types.js\";\n\n/**\n * Simple I18n class for standalone use\n */\nexport class SimpleI18n {\n\tprivate locale: string = \"en\";\n\tprivate fallbackLocale: string = \"en\";\n\tprivate direction: \"ltr\" | \"rtl\" = \"ltr\";\n\tprivate translations = new Map<string, TranslationBundle>();\n\tprivate listeners = new Set<() => void>();\n\tprivate loadingPromises = new Map<string, Promise<void>>();\n\tprivate config: I18nConfig;\n\n\tconstructor(config: I18nConfig = {}) {\n\t\tthis.config = config;\n\t\tthis.fallbackLocale = config.fallbackLocale || \"en\";\n\n\t\t// Load bundled translations\n\t\tif (config.bundledTranslations) {\n\t\t\tfor (const [locale, bundle] of Object.entries(\n\t\t\t\tconfig.bundledTranslations,\n\t\t\t)) {\n\t\t\t\tthis.translations.set(locale, bundle);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Initialize with locale\n\t */\n\tasync initialize(config: I18nConfig): Promise<void> {\n\t\tObject.assign(this.config, config);\n\n\t\tconst locale = config.locale || this.detectBrowserLocale();\n\t\tawait this.setLocale(locale);\n\t}\n\n\t/**\n\t * Translate a key\n\t */\n\tt(key: string, params?: Record<string, any>): string {\n\t\tconst translation = this.getTranslation(key);\n\t\treturn this.interpolate(translation as string, params);\n\t}\n\n\t/**\n\t * Translate with pluralization\n\t */\n\ttn(key: string, count: number, params?: Record<string, any>): string {\n\t\tconst translation = this.getTranslation(key);\n\n\t\tif (typeof translation === \"object\") {\n\t\t\tconst pluralForm = this.selectPluralForm(count, this.locale);\n\t\t\tconst text = translation[pluralForm] || translation.other;\n\t\t\treturn this.interpolate(text, { ...params, count });\n\t\t}\n\n\t\treturn this.interpolate(translation as string, { ...params, count });\n\t}\n\n\t/**\n\t * Get current locale\n\t */\n\tgetLocale(): string {\n\t\treturn this.locale;\n\t}\n\n\t/**\n\t * Change locale\n\t */\n\tasync setLocale(locale: string): Promise<void> {\n\t\t// Check if already loading\n\t\tif (this.loadingPromises.has(locale)) {\n\t\t\tawait this.loadingPromises.get(locale);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if already loaded\n\t\tif (this.translations.has(locale)) {\n\t\t\tthis.applyLocale(locale);\n\t\t\treturn;\n\t\t}\n\n\t\t// Load translations\n\t\tconst loadingPromise = this.loadTranslationsForLocale(locale);\n\t\tthis.loadingPromises.set(locale, loadingPromise);\n\n\t\ttry {\n\t\t\tawait loadingPromise;\n\t\t\tthis.applyLocale(locale);\n\t\t} finally {\n\t\t\tthis.loadingPromises.delete(locale);\n\t\t}\n\t}\n\n\t/**\n\t * Get current direction\n\t */\n\tgetDirection(): \"ltr\" | \"rtl\" {\n\t\treturn this.direction;\n\t}\n\n\t/**\n\t * Get available locales\n\t */\n\tgetAvailableLocales(): string[] {\n\t\treturn Array.from(this.translations.keys());\n\t}\n\n\t/**\n\t * Check if locale is loaded\n\t */\n\tisLocaleLoaded(locale: string): boolean {\n\t\treturn this.translations.has(locale);\n\t}\n\n\t/**\n\t * Subscribe to changes\n\t */\n\tsubscribe(listener: () => void): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\t/**\n\t * Check if key exists\n\t */\n\thasKey(key: string): boolean {\n\t\tconst bundle = this.translations.get(this.locale);\n\t\treturn !!bundle?.translations[key];\n\t}\n\n\tprivate notifyListeners(): void {\n\t\tfor (const listener of this.listeners) {\n\t\t\tlistener();\n\t\t}\n\t}\n\n\tprivate applyLocale(locale: string): void {\n\t\tconst bundle = this.translations.get(locale);\n\t\tif (!bundle) return;\n\n\t\tthis.locale = locale;\n\t\tthis.direction = bundle.direction;\n\n\t\tthis.applyDOMDirection();\n\t\tthis.notifyListeners();\n\t}\n\n\tprivate applyDOMDirection(): void {\n\t\tif (typeof document === \"undefined\") return;\n\n\t\tdocument.documentElement.setAttribute(\"dir\", this.direction);\n\t\tdocument.documentElement.setAttribute(\"lang\", this.locale);\n\t}\n\n\tprivate async loadTranslationsForLocale(locale: string): Promise<void> {\n\t\tif (!this.config.loadTranslations) {\n\t\t\tthrow new Error(`No translation loader configured for locale: ${locale}`);\n\t\t}\n\n\t\tconst bundle = await this.config.loadTranslations(locale);\n\t\tthis.translations.set(locale, bundle);\n\t}\n\n\tprivate getTranslation(key: string): string | PluralTranslation {\n\t\t// Try current locale\n\t\tconst currentBundle = this.translations.get(this.locale);\n\t\tif (currentBundle?.translations[key]) {\n\t\t\treturn currentBundle.translations[key];\n\t\t}\n\n\t\t// Try fallback locale\n\t\tconst fallbackBundle = this.translations.get(this.fallbackLocale);\n\t\tif (fallbackBundle?.translations[key]) {\n\t\t\treturn fallbackBundle.translations[key];\n\t\t}\n\n\t\t// Missing key\n\t\tif (this.config.onMissingKey) {\n\t\t\tthis.config.onMissingKey(key, this.locale);\n\t\t}\n\n\t\treturn key;\n\t}\n\n\tprivate interpolate(text: string, params?: Record<string, any>): string {\n\t\tif (!params) return text;\n\n\t\treturn text.replace(/\\{(\\w+)\\}/g, (match, key) => {\n\t\t\treturn params[key]?.toString() || match;\n\t\t});\n\t}\n\n\tprivate selectPluralForm(\n\t\tcount: number,\n\t\tlocale: string,\n\t): keyof PluralTranslation {\n\t\t// Use Intl.PluralRules if available\n\t\tif (typeof Intl !== \"undefined\" && Intl.PluralRules) {\n\t\t\ttry {\n\t\t\t\tconst rules = new Intl.PluralRules(locale);\n\t\t\t\tconst category = rules.select(count);\n\t\t\t\treturn category as keyof PluralTranslation;\n\t\t\t} catch {\n\t\t\t\t// Fall through to simple rules\n\t\t\t}\n\t\t}\n\n\t\t// Fallback to simple rules\n\t\tif (count === 0) return \"zero\";\n\t\tif (count === 1) return \"one\";\n\t\treturn \"other\";\n\t}\n\n\tprivate detectBrowserLocale(): string {\n\t\tif (typeof navigator === \"undefined\") return \"en\";\n\n\t\tconst browserLang =\n\t\t\tnavigator.language ||\n\t\t\t(navigator.languages && navigator.languages[0]) ||\n\t\t\t\"en\";\n\n\t\treturn browserLang.split(\"-\")[0];\n\t}\n}\n"]}
|
package/dist/i18n/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/i18n/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG","sourcesContent":["/**\n * I18n Type Definitions\n *\n * Shared types for internationalization system.\n * Defined in players-shared to avoid circular dependencies.\n */\n\n/**\n * Plural translation forms\n * Follows ICU MessageFormat plural rules\n */\nexport interface PluralTranslation {\n\tzero?: string;\n\tone: string;\n\tfew?: string;\n\tmany?: string;\n\tother: string;\n}\n\n/**\n * Translation bundle structure\n */\nexport interface TranslationBundle {\n\tlocale: string;\n\ttranslations: Record<string, string | PluralTranslation>;\n\tdirection: \"ltr\" | \"rtl\";\n}\n\n/**\n * I18n configuration\n */\nexport interface I18nConfig {\n\t/** Initial locale (default: browser language) */\n\tlocale?: string;\n\n\t/** Fallback locale (default: 'en') */\n\tfallbackLocale?: string;\n\n\t/** Translation loader function */\n\tloadTranslations?: (locale: string) => Promise<TranslationBundle>;\n\n\t/** Bundled translations (for hybrid loading) */\n\tbundledTranslations?: Record<string, TranslationBundle>;\n\n\t/** Missing key handler */\n\tonMissingKey?: (key: string, locale: string) => void;\n\n\t/** Debug mode */\n\tdebug?: boolean;\n}\n\n/**\n * I18nService API contract\n */\nexport interface I18nServiceApi {\n\tinitialize(config: I18nConfig): Promise<void>;\n\tt(key: string, params?: Record<string, any>): string;\n\ttn(key: string, count: number, params?: Record<string, any>): string;\n\tgetLocale(): string;\n\tsetLocale(locale: string): Promise<void>;\n\tgetDirection(): \"ltr\" | \"rtl\";\n\tgetAvailableLocales(): string[];\n\tisLocaleLoaded(locale: string): boolean;\n\tsubscribe(listener: () => void): () => void;\n\thasKey(key: string): boolean;\n}\n"]}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,0CAA0C;AAC1C,cAAc,gBAAgB,CAAC;AAuB/B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iCAAiC,CAAC;AAChD,cAAc,sBAAsB,CAAC","sourcesContent":["export * from \"./config/profile.js\";\nexport * from \"./instrumentation/index.js\";\nexport * from \"./loader-config.js\";\nexport * from \"./player-strategy.js\";\nexport * from \"./security/index.js\";\nexport * from \"./loaders/index.js\";\nexport * from \"./object/index.js\";\n// Barrel export for PIE runtime utilities\nexport * from \"./pie/index.js\";\nexport type {\n\tAssessmentEntity,\n\tAssessmentItemRef,\n\tAssessmentSection,\n\tAdvancedItemConfig,\n\tConfigEntity,\n\tConfigResource,\n\tEnv,\n\tItemConfig,\n\tItemEntity,\n\tItemSession,\n\tOutcomeResponse,\n\tPassageEntity,\n\tPieController,\n\tPieContent,\n\tPieDefaultModel,\n\tPieItemElement,\n\tPieModel,\n\tQuestionEntity,\n\tRubricBlock,\n\tTestPart,\n} from \"./types/index.js\";\nexport { editorPostFix } from \"./types/index.js\";\nexport * from \"./ui/content-styles.js\";\nexport * from \"./ui/focus-trap.js\";\nexport * from \"./ui/first-focusable.js\";\nexport * from \"./ui/debug-panel-persistence.js\";\nexport * from \"./ui/safe-storage.js\";\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"debug-panel-stream.js","sourceRoot":"","sources":["../../src/instrumentation/debug-panel-stream.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tErrorAttributes,\n\tEventAttributes,\n\tMetricAttributes,\n} from \"./types.js\";\n\nexport const INSTRUMENTATION_DEBUG_EVENT_NAME =\n\t\"pie-instrumentation-debug-record\";\nconst MAX_DEBUG_RECORDS = 500;\n\ntype DebugRecordKind =\n\t| \"event\"\n\t| \"error\"\n\t| \"metric\"\n\t| \"user-context\"\n\t| \"global-attributes\";\n\nexport type InstrumentationDebugRecord = {\n\tid: number;\n\tkind: DebugRecordKind;\n\tproviderId: string;\n\tproviderName: string;\n\ttimestamp: string;\n\tname: string;\n\tattributes?: Record<string, unknown>;\n\terrorMessage?: string;\n\terrorStack?: string;\n\tvalue?: number;\n};\n\nexport type InstrumentationDebugRecordInput = Omit<\n\tInstrumentationDebugRecord,\n\t\"id\"\n>;\n\ntype DebugWindowState = {\n\tnextId: number;\n\trecords: InstrumentationDebugRecord[];\n};\n\ntype PieDebugWindow = Window & {\n\t__pieInstrumentationDebugState?: DebugWindowState;\n};\n\nfunction getDebugWindow(): PieDebugWindow | null {\n\tif (typeof window === \"undefined\") return null;\n\treturn window as PieDebugWindow;\n}\n\nfunction getDebugState(debugWindow: PieDebugWindow): DebugWindowState {\n\tif (!debugWindow.__pieInstrumentationDebugState) {\n\t\tdebugWindow.__pieInstrumentationDebugState = {\n\t\t\tnextId: 1,\n\t\t\trecords: [],\n\t\t};\n\t}\n\treturn debugWindow.__pieInstrumentationDebugState;\n}\n\nfunction cloneRecord(\n\trecord: InstrumentationDebugRecord,\n): InstrumentationDebugRecord {\n\treturn {\n\t\t...record,\n\t\tattributes: record.attributes ? { ...record.attributes } : undefined,\n\t};\n}\n\nexport function emitInstrumentationDebugRecord(\n\trecord: InstrumentationDebugRecordInput,\n): void {\n\tconst debugWindow = getDebugWindow();\n\tif (!debugWindow) return;\n\tconst state = getDebugState(debugWindow);\n\tconst nextRecord: InstrumentationDebugRecord = {\n\t\t...record,\n\t\tid: state.nextId++,\n\t};\n\tstate.records.push(nextRecord);\n\tif (state.records.length > MAX_DEBUG_RECORDS) {\n\t\tstate.records.splice(0, state.records.length - MAX_DEBUG_RECORDS);\n\t}\n\tdebugWindow.dispatchEvent(\n\t\tnew CustomEvent<InstrumentationDebugRecord>(\n\t\t\tINSTRUMENTATION_DEBUG_EVENT_NAME,\n\t\t\t{\n\t\t\t\tdetail: cloneRecord(nextRecord),\n\t\t\t},\n\t\t),\n\t);\n}\n\nexport function getBufferedInstrumentationDebugRecords(): InstrumentationDebugRecord[] {\n\tconst debugWindow = getDebugWindow();\n\tif (!debugWindow) return [];\n\tconst state = getDebugState(debugWindow);\n\treturn state.records.map(cloneRecord);\n}\n\nexport function clearBufferedInstrumentationDebugRecords(): void {\n\tconst debugWindow = getDebugWindow();\n\tif (!debugWindow) return;\n\tconst state = getDebugState(debugWindow);\n\tstate.records = [];\n}\n\nexport function subscribeInstrumentationDebugRecords(args: {\n\tlistener: (record: InstrumentationDebugRecord) => void;\n\treplayBuffered?: boolean;\n}): () => void {\n\tconst debugWindow = getDebugWindow();\n\tif (!debugWindow) return () => {};\n\n\tif (args.replayBuffered !== false) {\n\t\tconst records = getBufferedInstrumentationDebugRecords();\n\t\tfor (const record of records) {\n\t\t\targs.listener(record);\n\t\t}\n\t}\n\n\tconst onDebugRecord = (event: Event) => {\n\t\tconst customEvent = event as CustomEvent<InstrumentationDebugRecord>;\n\t\tif (!customEvent.detail) return;\n\t\targs.listener(cloneRecord(customEvent.detail));\n\t};\n\tdebugWindow.addEventListener(INSTRUMENTATION_DEBUG_EVENT_NAME, onDebugRecord);\n\treturn () => {\n\t\tdebugWindow.removeEventListener(\n\t\t\tINSTRUMENTATION_DEBUG_EVENT_NAME,\n\t\t\tonDebugRecord,\n\t\t);\n\t};\n}\n\nexport function createEventDebugRecord(args: {\n\tproviderId: string;\n\tproviderName: string;\n\teventName: string;\n\tattributes: EventAttributes;\n}): InstrumentationDebugRecordInput {\n\treturn {\n\t\tkind: \"event\",\n\t\tproviderId: args.providerId,\n\t\tproviderName: args.providerName,\n\t\tname: args.eventName,\n\t\ttimestamp: new Date().toISOString(),\n\t\tattributes: { ...(args.attributes as Record<string, unknown>) },\n\t};\n}\n\nexport function createErrorDebugRecord(args: {\n\tproviderId: string;\n\tproviderName: string;\n\terror: Error;\n\tattributes: ErrorAttributes;\n}): InstrumentationDebugRecordInput {\n\treturn {\n\t\tkind: \"error\",\n\t\tproviderId: args.providerId,\n\t\tproviderName: args.providerName,\n\t\tname: args.attributes.errorType || \"unknown-error\",\n\t\ttimestamp: new Date().toISOString(),\n\t\tattributes: { ...(args.attributes as Record<string, unknown>) },\n\t\terrorMessage: args.error?.message || \"Unknown error\",\n\t\terrorStack: args.error?.stack,\n\t};\n}\n\nexport function createMetricDebugRecord(args: {\n\tproviderId: string;\n\tproviderName: string;\n\tmetricName: string;\n\tvalue: number;\n\tattributes?: MetricAttributes;\n}): InstrumentationDebugRecordInput {\n\treturn {\n\t\tkind: \"metric\",\n\t\tproviderId: args.providerId,\n\t\tproviderName: args.providerName,\n\t\tname: args.metricName,\n\t\ttimestamp: new Date().toISOString(),\n\t\tvalue: args.value,\n\t\tattributes: args.attributes\n\t\t\t? { ...(args.attributes as Record<string, unknown>) }\n\t\t\t: undefined,\n\t};\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/instrumentation/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,YAAY;AACZ,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EACN,wCAAwC,EACxC,sCAAsC,EACtC,gCAAgC,EAChC,oCAAoC,GACpC,MAAM,yBAAyB,CAAC","sourcesContent":["/**\n * Instrumentation Module\n *\n * Provides pluggable instrumentation for PIE players.\n * Supports multiple providers (New Relic, console logging, custom, etc.)\n *\n * @example Using New Relic (default)\n * ```typescript\n * import { NewRelicInstrumentationProvider } from '@pie-players/pie-players-shared';\n *\n * const provider = new NewRelicInstrumentationProvider();\n * await provider.initialize();\n *\n * const monitor = new ResourceMonitor({\n * trackPageActions: true,\n * instrumentationProvider: provider\n * });\n * ```\n * @example Using console logger for development\n * ```typescript\n * import { ConsoleInstrumentationProvider } from '@pie-players/pie-players-shared';\n *\n * const provider = new ConsoleInstrumentationProvider();\n * await provider.initialize({ debug: true });\n *\n * const monitor = new ResourceMonitor({\n * trackPageActions: true,\n * instrumentationProvider: provider\n * });\n * ```\n */\n\n// Providers\nexport * from \"./providers/index.js\";\nexport { isInstrumentationProvider } from \"./provider-guards.js\";\nexport {\n\tclearBufferedInstrumentationDebugRecords,\n\tgetBufferedInstrumentationDebugRecords,\n\tINSTRUMENTATION_DEBUG_EVENT_NAME,\n\tsubscribeInstrumentationDebugRecords,\n} from \"./debug-panel-stream.js\";\nexport type { InstrumentationDebugRecord } from \"./debug-panel-stream.js\";\n// Core types\nexport type {\n\tErrorAttributes,\n\tEventAttributes,\n\tInstrumentationConfig,\n\tInstrumentationProvider,\n\tMetricAttributes,\n} from \"./types.js\";\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provider-guards.js","sourceRoot":"","sources":["../../src/instrumentation/provider-guards.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,yBAAyB,CACxC,KAAc;IAEd,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,SAAS,GAAG,KAAgC,CAAC;IACnD,OAAO,CACN,OAAO,SAAS,CAAC,UAAU,KAAK,QAAQ;QACxC,OAAO,SAAS,CAAC,YAAY,KAAK,QAAQ;QAC1C,OAAO,SAAS,CAAC,UAAU,KAAK,UAAU;QAC1C,OAAO,SAAS,CAAC,UAAU,KAAK,UAAU;QAC1C,OAAO,SAAS,CAAC,UAAU,KAAK,UAAU;QAC1C,OAAO,SAAS,CAAC,OAAO,KAAK,UAAU;QACvC,OAAO,SAAS,CAAC,OAAO,KAAK,UAAU,CACvC,CAAC;AACH,CAAC","sourcesContent":["import type { InstrumentationProvider } from \"./types.js\";\n\nexport function isInstrumentationProvider(\n\tvalue: unknown,\n): value is InstrumentationProvider {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst candidate = value as Record<string, unknown>;\n\treturn (\n\t\ttypeof candidate.providerId === \"string\" &&\n\t\ttypeof candidate.providerName === \"string\" &&\n\t\ttypeof candidate.initialize === \"function\" &&\n\t\ttypeof candidate.trackError === \"function\" &&\n\t\ttypeof candidate.trackEvent === \"function\" &&\n\t\ttypeof candidate.destroy === \"function\" &&\n\t\ttypeof candidate.isReady === \"function\"\n\t);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BaseInstrumentationProvider.js","sourceRoot":"","sources":["../../../src/instrumentation/providers/BaseInstrumentationProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH;;;;;;;;;GASG;AACH,MAAM,OAAgB,2BAA2B;IAMtC,WAAW,GAAG,KAAK,CAAC;IACpB,MAAM,CAAyB;IAwFzC,+EAA+E;IAC/E,wCAAwC;IACxC,+EAA+E;IAE/E;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,KAAY,EAAE,UAA2B;QACnD,oCAAoC;QACpC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;YAC7D,OAAO;QACR,CAAC;QAED,qBAAqB;QACrB,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;YAC/C,OAAO;QACR,CAAC;QAED,uBAAuB;QACvB,MAAM,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAE7D,gCAAgC;QAChC,IAAI,CAAC;YACJ,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;YAE1C,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CACV,IAAI,IAAI,CAAC,YAAY,kBAAkB,EACvC,KAAK,EACL,eAAe,CACf,CAAC;YACH,CAAC;QACF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,yBAAyB,EAAE,GAAG,CAAC,CAAC;QACpE,CAAC;IACF,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,SAAiB,EAAE,UAA2B;QACxD,oCAAoC;QACpC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;YACjE,OAAO;QACR,CAAC;QAED,qBAAqB;QACrB,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC;YACnD,OAAO;QACR,CAAC;QAED,iBAAiB;QACjB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,OAAO;QACR,CAAC;QAED,uBAAuB;QACvB,IAAI,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAE3D,+BAA+B;QAC/B,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC;YAChC,eAAe,GAAG;gBACjB,GAAG,eAAe;gBAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACnC,CAAC;QACH,CAAC;QAED,gCAAgC;QAChC,IAAI,CAAC;YACJ,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;YAE9C,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CACV,IAAI,IAAI,CAAC,YAAY,kBAAkB,EACvC,SAAS,EACT,eAAe,CACf,CAAC;YACH,CAAC;QACF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,yBAAyB,EAAE,GAAG,CAAC,CAAC;QACpE,CAAC;IACF,CAAC;IAED;;;;;;;;;;OAUG;IACH,WAAW,CACV,UAAkB,EAClB,KAAa,EACb,UAA6B;QAE7B,yCAAyC;QACzC,IAAI,CAAC,UAAU,CAAC,UAAU,UAAU,EAAE,EAAE;YACvC,GAAG,UAAU;YACb,WAAW,EAAE,KAAK;YAClB,UAAU;SACV,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,cAAc,CAAC,MAAc,EAAE,UAAgC;QAC9D,oCAAoC;QACpC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;YAClE,OAAO;QACR,CAAC;QAED,gCAAgC;QAChC,IAAI,CAAC;YACJ,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAE1C,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CACV,IAAI,IAAI,CAAC,YAAY,qBAAqB,EAC1C,MAAM,EACN,UAAU,CACV,CAAC;YACH,CAAC;QACF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,+BAA+B,EAAE,GAAG,CAAC,CAAC;QAC1E,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACH,mBAAmB,CAAC,UAA+B;QAClD,oCAAoC;QACpC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAAE,CAAC;YAC/D,OAAO;QACR,CAAC;QAED,gCAAgC;QAChC,IAAI,CAAC;YACJ,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;YAEvC,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CACV,IAAI,IAAI,CAAC,YAAY,0BAA0B,EAC/C,UAAU,CACV,CAAC;YACH,CAAC;QACF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CACZ,IAAI,IAAI,CAAC,YAAY,oCAAoC,EACzD,GAAG,CACH,CAAC;QACH,CAAC;IACF,CAAC;IAED,+EAA+E;IAC/E,2CAA2C;IAC3C,+EAA+E;IAE/E;;;;;;;;OAQG;IACO,gBAAgB,CAAC,SAAiB,EAAE,GAAG,IAAW;QAC3D,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACrB,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,CACX,IAAI,IAAI,CAAC,YAAY,kBAAkB,SAAS,0BAA0B,EAC1E,GAAG,IAAI,CACP,CAAC;YACH,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;;;OAQG;IACO,gBAAgB,CACzB,KAAY,EACZ,UAA2B;QAE3B,IACC,IAAI,CAAC,MAAM,EAAE,WAAW;YACxB,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,EAC1C,CAAC;YACF,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CACV,IAAI,IAAI,CAAC,YAAY,uBAAuB,EAC5C,KAAK,EACL,UAAU,CACV,CAAC;YACH,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;;;OAQG;IACO,gBAAgB,CACzB,SAAiB,EACjB,UAA2B;QAE3B,IACC,IAAI,CAAC,MAAM,EAAE,WAAW;YACxB,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,UAAU,CAAC,EAC9C,CAAC;YACF,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CACV,IAAI,IAAI,CAAC,YAAY,uBAAuB,EAC5C,SAAS,EACT,UAAU,CACV,CAAC;YACH,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;;OAOG;IACO,aAAa,CAAC,SAAiB;QACxC,IAAI,IAAI,CAAC,MAAM,EAAE,UAAU,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC;YAC3E,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;gBAC5C,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;oBACxB,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,YAAY,sBAAsB,EAAE,SAAS,CAAC,CAAC;gBACrE,CAAC;gBACD,OAAO,KAAK,CAAC;YACd,CAAC;QACF,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACO,mBAAmB,CAC5B,UAA+B;QAE/B,IAAI,IAAI,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,UAAiC,CAAC;IAC1C,CAAC;CACD","sourcesContent":["/**\n * Base Instrumentation Provider\n *\n * Abstract base class that implements common instrumentation logic for all providers.\n * Provides a template method pattern for tracking errors and events with consistent\n * filtering, transformation, and sampling behavior.\n *\n * Concrete providers only need to implement the actual tracking methods specific\n * to their instrumentation backend (New Relic, DataDog, etc.)\n */\n\nimport type {\n\tErrorAttributes,\n\tEventAttributes,\n\tInstrumentationConfig,\n\tInstrumentationProvider,\n\tMetricAttributes,\n} from \"../types.js\";\n\n/**\n * Abstract base class for instrumentation providers\n *\n * Implements the template method pattern:\n * 1. Checks if provider is ready\n * 2. Applies filters (errorFilter, eventFilter)\n * 3. Applies sampling (sampleRate)\n * 4. Transforms attributes (attributeTransformer)\n * 5. Delegates to concrete provider implementation (doTrackError, doTrackEvent, etc.)\n */\nexport abstract class BaseInstrumentationProvider\n\timplements InstrumentationProvider\n{\n\tabstract readonly providerId: string;\n\tabstract readonly providerName: string;\n\n\tprotected initialized = false;\n\tprotected config?: InstrumentationConfig;\n\n\t/**\n\t * Initialize the provider with configuration\n\t *\n\t * Concrete providers should override this method to perform provider-specific\n\t * initialization (e.g., loading SDK, checking global objects, etc.)\n\t *\n\t * @param config Optional configuration\n\t */\n\tabstract initialize(config?: InstrumentationConfig): Promise<void>;\n\n\t/**\n\t * Check if provider is ready to track events\n\t *\n\t * Concrete providers should override this method to check provider-specific\n\t * readiness (e.g., SDK loaded, global object available, etc.)\n\t *\n\t * @returns true if provider is ready\n\t */\n\tabstract isReady(): boolean;\n\n\t/**\n\t * Cleanup provider resources\n\t *\n\t * Concrete providers should override this method to perform provider-specific\n\t * cleanup (e.g., disconnect SDK, clear listeners, etc.)\n\t */\n\tabstract destroy(): void;\n\n\t// ============================================================================\n\t// Abstract methods that concrete providers MUST implement\n\t// ============================================================================\n\n\t/**\n\t * Track an error with the instrumentation backend\n\t *\n\t * Called by trackError() after all filters and transforms have been applied.\n\t * Concrete providers should implement the actual error tracking here.\n\t *\n\t * @param error The error to track\n\t * @param attributes Transformed and filtered attributes\n\t */\n\tprotected abstract doTrackError(\n\t\terror: Error,\n\t\tattributes: Record<string, any>,\n\t): void;\n\n\t/**\n\t * Track an event with the instrumentation backend\n\t *\n\t * Called by trackEvent() after all filters and transforms have been applied.\n\t * Concrete providers should implement the actual event tracking here.\n\t *\n\t * @param eventName Name of the event\n\t * @param attributes Transformed and filtered attributes\n\t */\n\tprotected abstract doTrackEvent(\n\t\teventName: string,\n\t\tattributes: Record<string, any>,\n\t): void;\n\n\t/**\n\t * Set user context in the instrumentation backend\n\t *\n\t * Called by setUserContext() after readiness check.\n\t * Concrete providers should implement the actual user context setting here.\n\t *\n\t * @param userId User identifier\n\t * @param attributes Optional user attributes\n\t */\n\tprotected abstract doSetUserContext(\n\t\tuserId: string,\n\t\tattributes?: Record<string, any>,\n\t): void;\n\n\t/**\n\t * Set global attributes in the instrumentation backend\n\t *\n\t * Called by setGlobalAttributes() after readiness check.\n\t * Concrete providers should implement the actual global attribute setting here.\n\t *\n\t * @param attributes Attributes to set globally\n\t */\n\tprotected abstract doSetGlobalAttributes(\n\t\tattributes: Record<string, any>,\n\t): void;\n\n\t// ============================================================================\n\t// Public API methods (template methods)\n\t// ============================================================================\n\n\t/**\n\t * Track an error with the instrumentation provider\n\t *\n\t * Template method that:\n\t * 1. Checks if provider is ready\n\t * 2. Applies error filter if configured\n\t * 3. Transforms attributes if configured\n\t * 4. Delegates to concrete provider implementation (doTrackError)\n\t *\n\t * @param error The error to track\n\t * @param attributes Contextual attributes\n\t */\n\ttrackError(error: Error, attributes: ErrorAttributes): void {\n\t\t// Guard: check if provider is ready\n\t\tif (!this.guardedOperation(\"trackError\", error, attributes)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Apply error filter\n\t\tif (!this.applyErrorFilter(error, attributes)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Transform attributes\n\t\tconst finalAttributes = this.transformAttributes(attributes);\n\n\t\t// Delegate to concrete provider\n\t\ttry {\n\t\t\tthis.doTrackError(error, finalAttributes);\n\n\t\t\tif (this.config?.debug) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[${this.providerName}] Tracked error:`,\n\t\t\t\t\terror,\n\t\t\t\t\tfinalAttributes,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(`[${this.providerName}] Error tracking error:`, err);\n\t\t}\n\t}\n\n\t/**\n\t * Track a custom event with the instrumentation provider\n\t *\n\t * Template method that:\n\t * 1. Checks if provider is ready\n\t * 2. Applies event filter if configured\n\t * 3. Applies sampling if configured\n\t * 4. Transforms attributes if configured\n\t * 5. Adds timestamp if not present\n\t * 6. Delegates to concrete provider implementation (doTrackEvent)\n\t *\n\t * @param eventName Name of the event\n\t * @param attributes Event attributes\n\t */\n\ttrackEvent(eventName: string, attributes: EventAttributes): void {\n\t\t// Guard: check if provider is ready\n\t\tif (!this.guardedOperation(\"trackEvent\", eventName, attributes)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Apply event filter\n\t\tif (!this.applyEventFilter(eventName, attributes)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Apply sampling\n\t\tif (!this.applySampling(eventName)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Transform attributes\n\t\tlet finalAttributes = this.transformAttributes(attributes);\n\n\t\t// Add timestamp if not present\n\t\tif (!finalAttributes.timestamp) {\n\t\t\tfinalAttributes = {\n\t\t\t\t...finalAttributes,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t};\n\t\t}\n\n\t\t// Delegate to concrete provider\n\t\ttry {\n\t\t\tthis.doTrackEvent(eventName, finalAttributes);\n\n\t\t\tif (this.config?.debug) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[${this.providerName}] Tracked event:`,\n\t\t\t\t\teventName,\n\t\t\t\t\tfinalAttributes,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(`[${this.providerName}] Error tracking event:`, err);\n\t\t}\n\t}\n\n\t/**\n\t * Track a performance metric\n\t *\n\t * Default implementation tracks metrics as events with a `metric:` prefix.\n\t * Concrete providers can override this method if their backend has a\n\t * dedicated metric API.\n\t *\n\t * @param metricName Name of the metric\n\t * @param value Numeric value\n\t * @param attributes Optional metric attributes\n\t */\n\ttrackMetric(\n\t\tmetricName: string,\n\t\tvalue: number,\n\t\tattributes?: MetricAttributes,\n\t): void {\n\t\t// Default implementation: track as event\n\t\tthis.trackEvent(`metric:${metricName}`, {\n\t\t\t...attributes,\n\t\t\tmetricValue: value,\n\t\t\tmetricName,\n\t\t});\n\t}\n\n\t/**\n\t * Set user context for session tracking\n\t *\n\t * Template method that checks if provider is ready then delegates\n\t * to concrete provider implementation.\n\t *\n\t * @param userId User identifier\n\t * @param attributes Optional user attributes\n\t */\n\tsetUserContext(userId: string, attributes?: Record<string, any>): void {\n\t\t// Guard: check if provider is ready\n\t\tif (!this.guardedOperation(\"setUserContext\", userId, attributes)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Delegate to concrete provider\n\t\ttry {\n\t\t\tthis.doSetUserContext(userId, attributes);\n\n\t\t\tif (this.config?.debug) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[${this.providerName}] Set user context:`,\n\t\t\t\t\tuserId,\n\t\t\t\t\tattributes,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(`[${this.providerName}] Error setting user context:`, err);\n\t\t}\n\t}\n\n\t/**\n\t * Set global custom attributes\n\t *\n\t * Template method that checks if provider is ready then delegates\n\t * to concrete provider implementation.\n\t *\n\t * @param attributes Attributes to set globally\n\t */\n\tsetGlobalAttributes(attributes: Record<string, any>): void {\n\t\t// Guard: check if provider is ready\n\t\tif (!this.guardedOperation(\"setGlobalAttributes\", attributes)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Delegate to concrete provider\n\t\ttry {\n\t\t\tthis.doSetGlobalAttributes(attributes);\n\n\t\t\tif (this.config?.debug) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[${this.providerName}] Set global attributes:`,\n\t\t\t\t\tattributes,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error(\n\t\t\t\t`[${this.providerName}] Error setting global attributes:`,\n\t\t\t\terr,\n\t\t\t);\n\t\t}\n\t}\n\n\t// ============================================================================\n\t// Protected utility methods (shared logic)\n\t// ============================================================================\n\n\t/**\n\t * Guard operation - check if provider is ready\n\t *\n\t * Returns false if provider is not ready, logging a warning in debug mode.\n\t *\n\t * @param operation Name of the operation for logging\n\t * @param args Arguments for logging\n\t * @returns true if provider is ready, false otherwise\n\t */\n\tprotected guardedOperation(operation: string, ...args: any[]): boolean {\n\t\tif (!this.isReady()) {\n\t\t\tif (this.config?.debug) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[${this.providerName}] Attempted to ${operation} but provider not ready:`,\n\t\t\t\t\t...args,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Apply error filter if configured\n\t *\n\t * Returns false if error should be filtered out, logging in debug mode.\n\t *\n\t * @param error The error\n\t * @param attributes Error attributes\n\t * @returns true if error should be tracked, false if filtered out\n\t */\n\tprotected applyErrorFilter(\n\t\terror: Error,\n\t\tattributes: ErrorAttributes,\n\t): boolean {\n\t\tif (\n\t\t\tthis.config?.errorFilter &&\n\t\t\t!this.config.errorFilter(error, attributes)\n\t\t) {\n\t\t\tif (this.config?.debug) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[${this.providerName}] Error filtered out:`,\n\t\t\t\t\terror,\n\t\t\t\t\tattributes,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Apply event filter if configured\n\t *\n\t * Returns false if event should be filtered out, logging in debug mode.\n\t *\n\t * @param eventName Event name\n\t * @param attributes Event attributes\n\t * @returns true if event should be tracked, false if filtered out\n\t */\n\tprotected applyEventFilter(\n\t\teventName: string,\n\t\tattributes: EventAttributes,\n\t): boolean {\n\t\tif (\n\t\t\tthis.config?.eventFilter &&\n\t\t\t!this.config.eventFilter(eventName, attributes)\n\t\t) {\n\t\t\tif (this.config?.debug) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[${this.providerName}] Event filtered out:`,\n\t\t\t\t\teventName,\n\t\t\t\t\tattributes,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Apply sampling if configured\n\t *\n\t * Returns false if event should be sampled out, logging in debug mode.\n\t *\n\t * @param eventName Event name for logging\n\t * @returns true if event should be tracked, false if sampled out\n\t */\n\tprotected applySampling(eventName: string): boolean {\n\t\tif (this.config?.sampleRate !== undefined && this.config.sampleRate < 1.0) {\n\t\t\tif (Math.random() > this.config.sampleRate) {\n\t\t\t\tif (this.config?.debug) {\n\t\t\t\t\tconsole.log(`[${this.providerName}] Event sampled out:`, eventName);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Transform attributes if transformer is configured\n\t *\n\t * @param attributes Original attributes\n\t * @returns Transformed attributes or original if no transformer\n\t */\n\tprotected transformAttributes(\n\t\tattributes: Record<string, any>,\n\t): Record<string, any> {\n\t\tif (this.config?.attributeTransformer) {\n\t\t\treturn this.config.attributeTransformer(attributes);\n\t\t}\n\t\treturn attributes as Record<string, any>;\n\t}\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CompositeInstrumentationProvider.js","sourceRoot":"","sources":["../../../src/instrumentation/providers/CompositeInstrumentationProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tErrorAttributes,\n\tEventAttributes,\n\tInstrumentationConfig,\n\tInstrumentationProvider,\n\tMetricAttributes,\n} from \"../types.js\";\n\nexport class CompositeInstrumentationProvider\n\timplements InstrumentationProvider\n{\n\treadonly providerId = \"composite\";\n\treadonly providerName = \"Composite Provider\";\n\n\tprivate initialized = false;\n\tprivate readonly providers: InstrumentationProvider[];\n\n\tconstructor(providers: InstrumentationProvider[]) {\n\t\tthis.providers = providers.filter(Boolean);\n\t}\n\n\tasync initialize(config?: InstrumentationConfig): Promise<void> {\n\t\tconst results = await Promise.allSettled(\n\t\t\tthis.providers.map((provider) => provider.initialize(config)),\n\t\t);\n\t\tthis.initialized = true;\n\t\tif (config?.debug) {\n\t\t\tfor (const [index, result] of results.entries()) {\n\t\t\t\tif (result.status === \"rejected\") {\n\t\t\t\t\tconst provider = this.providers[index];\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[CompositeProvider] Failed to initialize ${provider?.providerName || \"unknown\"} (${provider?.providerId || \"unknown\"})`,\n\t\t\t\t\t\tresult.reason,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tisReady(): boolean {\n\t\tif (!this.initialized) return false;\n\t\treturn this.providers.some((provider) => {\n\t\t\ttry {\n\t\t\t\treturn provider.isReady();\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t}\n\n\tdestroy(): void {\n\t\tthis.initialized = false;\n\t\tfor (const provider of this.providers) {\n\t\t\ttry {\n\t\t\t\tprovider.destroy();\n\t\t\t} catch {\n\t\t\t\t// Best effort: a broken child provider should not block others.\n\t\t\t}\n\t\t}\n\t}\n\n\ttrackError(error: Error, attributes: ErrorAttributes): void {\n\t\tthis.forEachProvider((provider) => provider.trackError(error, attributes));\n\t}\n\n\ttrackEvent(eventName: string, attributes: EventAttributes): void {\n\t\tthis.forEachProvider((provider) =>\n\t\t\tprovider.trackEvent(eventName, attributes),\n\t\t);\n\t}\n\n\ttrackMetric(\n\t\tmetricName: string,\n\t\tvalue: number,\n\t\tattributes?: MetricAttributes,\n\t): void {\n\t\tthis.forEachProvider((provider) => {\n\t\t\tif (provider.trackMetric) {\n\t\t\t\tprovider.trackMetric(metricName, value, attributes);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tprovider.trackEvent(`metric:${metricName}`, {\n\t\t\t\t...(attributes as Record<string, unknown>),\n\t\t\t\tmetricName,\n\t\t\t\tmetricValue: value,\n\t\t\t});\n\t\t});\n\t}\n\n\tsetUserContext(userId: string, attributes?: Record<string, any>): void {\n\t\tthis.forEachProvider((provider) =>\n\t\t\tprovider.setUserContext?.(userId, attributes),\n\t\t);\n\t}\n\n\tsetGlobalAttributes(attributes: Record<string, any>): void {\n\t\tthis.forEachProvider((provider) =>\n\t\t\tprovider.setGlobalAttributes?.(attributes),\n\t\t);\n\t}\n\n\tprivate forEachProvider(\n\t\tcallback: (provider: InstrumentationProvider) => void,\n\t): void {\n\t\tif (!this.initialized) return;\n\t\tfor (const provider of this.providers) {\n\t\t\ttry {\n\t\t\t\tcallback(provider);\n\t\t\t} catch {\n\t\t\t\t// Best effort fan-out.\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ConsoleInstrumentationProvider.js","sourceRoot":"","sources":["../../../src/instrumentation/providers/ConsoleInstrumentationProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Console Instrumentation Provider\n *\n * Development provider that logs instrumentation events to the console.\n * Useful for debugging and testing without requiring external instrumentation services.\n *\n * @example\n * ```typescript\n * const provider = new ConsoleInstrumentationProvider();\n * await provider.initialize({ debug: true });\n *\n * provider.trackError(new Error('Test error'), {\n * component: 'test-component',\n * errorType: 'TestError'\n * });\n * // Outputs: [Instrumentation Error] test-component: TestError\n * // Error: Test error\n * // { component: 'test-component', errorType: 'TestError' }\n * ```\n */\n\nimport type { InstrumentationConfig, MetricAttributes } from \"../types.js\";\nimport { BaseInstrumentationProvider } from \"./BaseInstrumentationProvider.js\";\n\nexport interface ConsoleProviderConfig {\n\t/**\n\t * Use colored output in console\n\t *\n\t * @default true\n\t */\n\tuseColors?: boolean;\n\n\t/**\n\t * Include stack traces with errors\n\t *\n\t * @default true\n\t */\n\tincludeStackTrace?: boolean;\n\n\t/**\n\t * Group related logs together\n\t *\n\t * @default false\n\t */\n\tuseGroups?: boolean;\n}\n\nexport class ConsoleInstrumentationProvider extends BaseInstrumentationProvider {\n\treadonly providerId = \"console\";\n\treadonly providerName = \"Console Logger\";\n\n\tprivate providerConfig: ConsoleProviderConfig;\n\n\tconstructor(providerConfig: ConsoleProviderConfig = {}) {\n\t\tsuper();\n\t\tthis.providerConfig = {\n\t\t\tuseColors: providerConfig.useColors !== false,\n\t\t\tincludeStackTrace: providerConfig.includeStackTrace !== false,\n\t\t\tuseGroups: providerConfig.useGroups === true,\n\t\t};\n\t}\n\n\t/**\n\t * Initialize the console provider\n\t *\n\t * @param config Optional configuration\n\t */\n\tasync initialize(config?: InstrumentationConfig): Promise<void> {\n\t\tthis.config = config;\n\t\tthis.initialized = true;\n\n\t\t// Merge provider-specific config if provided\n\t\tif (config?.providerSettings) {\n\t\t\tthis.providerConfig = {\n\t\t\t\t...this.providerConfig,\n\t\t\t\t...config.providerSettings,\n\t\t\t};\n\t\t}\n\n\t\tconsole.log(\n\t\t\t\"%c[ConsoleProvider] Initialized\",\n\t\t\tthis.providerConfig.useColors ? \"color: green; font-weight: bold\" : \"\",\n\t\t);\n\t}\n\n\t/**\n\t * Check if provider is ready\n\t *\n\t * @returns true if initialized\n\t */\n\tisReady(): boolean {\n\t\treturn this.initialized;\n\t}\n\n\t/**\n\t * Cleanup provider resources\n\t */\n\tdestroy(): void {\n\t\tthis.initialized = false;\n\t\tconsole.log(\n\t\t\t\"%c[ConsoleProvider] Destroyed\",\n\t\t\tthis.providerConfig.useColors ? \"color: gray\" : \"\",\n\t\t);\n\t}\n\n\t/**\n\t * Track an error to console\n\t *\n\t * @param error The error to track\n\t * @param attributes Transformed attributes (already filtered and transformed by base class)\n\t */\n\tprotected doTrackError(error: Error, attributes: Record<string, any>): void {\n\t\tconst style = this.providerConfig.useColors\n\t\t\t? \"color: red; font-weight: bold\"\n\t\t\t: \"\";\n\t\tconst timestamp = new Date().toISOString();\n\n\t\tif (this.providerConfig.useGroups) {\n\t\t\tconsole.groupCollapsed(\n\t\t\t\t`%c[Instrumentation Error] ${attributes.component}: ${attributes.errorType}`,\n\t\t\t\tstyle,\n\t\t\t);\n\t\t\tconsole.error(\"Error:\", error.message);\n\t\t\tif (this.providerConfig.includeStackTrace && error.stack) {\n\t\t\t\tconsole.error(\"Stack:\", error.stack);\n\t\t\t}\n\t\t\tconsole.log(\"Attributes:\", attributes);\n\t\t\tconsole.log(\"Timestamp:\", timestamp);\n\t\t\tconsole.groupEnd();\n\t\t} else {\n\t\t\tconsole.error(\n\t\t\t\t`%c[Instrumentation Error] ${attributes.component}: ${attributes.errorType}`,\n\t\t\t\tstyle,\n\t\t\t);\n\t\t\tconsole.error(\"Error:\", error.message);\n\t\t\tif (this.providerConfig.includeStackTrace && error.stack) {\n\t\t\t\tconsole.error(\"Stack:\", error.stack);\n\t\t\t}\n\t\t\tconsole.error(\"Attributes:\", attributes);\n\t\t\tconsole.error(\"Timestamp:\", timestamp);\n\t\t}\n\t}\n\n\t/**\n\t * Track an event to console\n\t *\n\t * @param eventName Name of the event\n\t * @param attributes Transformed attributes (already filtered and transformed by base class)\n\t */\n\tprotected doTrackEvent(\n\t\teventName: string,\n\t\tattributes: Record<string, any>,\n\t): void {\n\t\tconst style = this.providerConfig.useColors ? \"color: blue\" : \"\";\n\t\tconst timestamp = new Date().toISOString();\n\n\t\tif (this.providerConfig.useGroups) {\n\t\t\tconsole.groupCollapsed(`%c[Instrumentation Event] ${eventName}`, style);\n\t\t\tconsole.log(\"Attributes:\", attributes);\n\t\t\tconsole.log(\"Timestamp:\", timestamp);\n\t\t\tconsole.groupEnd();\n\t\t} else {\n\t\t\tconsole.log(`%c[Instrumentation Event] ${eventName}`, style);\n\t\t\tconsole.log(\"Attributes:\", attributes);\n\t\t\tconsole.log(\"Timestamp:\", timestamp);\n\t\t}\n\t}\n\n\t/**\n\t * Track a metric to console\n\t *\n\t * Overrides base class to provide custom formatting.\n\t *\n\t * @param metricName Name of the metric\n\t * @param value Numeric value\n\t * @param attributes Optional metric attributes\n\t */\n\ttrackMetric(\n\t\tmetricName: string,\n\t\tvalue: number,\n\t\tattributes?: MetricAttributes,\n\t): void {\n\t\tif (!this.isReady()) return;\n\n\t\tconst style = this.providerConfig.useColors ? \"color: green\" : \"\";\n\t\tconst timestamp = new Date().toISOString();\n\t\tconst unit = attributes?.unit || \"\";\n\t\tconst displayValue = unit ? `${value} ${unit}` : value;\n\n\t\tif (this.providerConfig.useGroups) {\n\t\t\tconsole.groupCollapsed(\n\t\t\t\t`%c[Instrumentation Metric] ${metricName}: ${displayValue}`,\n\t\t\t\tstyle,\n\t\t\t);\n\t\t\tif (attributes) {\n\t\t\t\tconsole.log(\"Attributes:\", attributes);\n\t\t\t}\n\t\t\tconsole.log(\"Timestamp:\", timestamp);\n\t\t\tconsole.groupEnd();\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`%c[Instrumentation Metric] ${metricName}:`,\n\t\t\t\tstyle,\n\t\t\t\tdisplayValue,\n\t\t\t);\n\t\t\tif (attributes) {\n\t\t\t\tconsole.log(\"Attributes:\", attributes);\n\t\t\t}\n\t\t\tconsole.log(\"Timestamp:\", timestamp);\n\t\t}\n\t}\n\n\t/**\n\t * Set user context\n\t *\n\t * Logs user context to console.\n\t *\n\t * @param userId User identifier\n\t * @param attributes Optional user attributes\n\t */\n\tprotected doSetUserContext(\n\t\tuserId: string,\n\t\tattributes?: Record<string, any>,\n\t): void {\n\t\tconst style = this.providerConfig.useColors\n\t\t\t? \"color: purple; font-weight: bold\"\n\t\t\t: \"\";\n\t\tconsole.log(`%c[Instrumentation] Set User Context: ${userId}`, style);\n\t\tif (attributes) {\n\t\t\tconsole.log(\"User Attributes:\", attributes);\n\t\t}\n\t}\n\n\t/**\n\t * Set global attributes\n\t *\n\t * Logs global attributes to console.\n\t *\n\t * @param attributes Attributes to set globally\n\t */\n\tprotected doSetGlobalAttributes(attributes: Record<string, any>): void {\n\t\tconst style = this.providerConfig.useColors\n\t\t\t? \"color: orange; font-weight: bold\"\n\t\t\t: \"\";\n\t\tconsole.log(\"%c[Instrumentation] Set Global Attributes\", style);\n\t\tconsole.log(\"Attributes:\", attributes);\n\t}\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DebugPanelInstrumentationProvider.js","sourceRoot":"","sources":["../../../src/instrumentation/providers/DebugPanelInstrumentationProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,8BAA8B,GAC9B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,MAAM,OAAO,iCAAkC,SAAQ,2BAA2B;IACxE,UAAU,GAAG,aAAa,CAAC;IAC3B,YAAY,GAAG,aAAa,CAAC;IAEtC,KAAK,CAAC,UAAU,CAAC,MAA8B;QAC9C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,OAAO;QACN,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAED,OAAO;QACN,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC1B,CAAC;IAES,YAAY,CAAC,KAAY,EAAE,UAA+B;QACnE,8BAA8B,CAC7B,sBAAsB,CAAC;YACtB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,KAAK;YACL,UAAU,EAAE,UAA6B;SACzC,CAAC,CACF,CAAC;IACH,CAAC;IAES,YAAY,CACrB,SAAiB,EACjB,UAA+B;QAE/B,8BAA8B,CAC7B,sBAAsB,CAAC;YACtB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,SAAS;YACT,UAAU;SACV,CAAC,CACF,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACtC,OAAO;QACR,CAAC;QACD,MAAM,cAAc,GAAG,UAAU,CAAC,WAAW,CAAC;QAC9C,IACC,OAAO,cAAc,KAAK,QAAQ;YAClC,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,EAC/B,CAAC;YACF,OAAO;QACR,CAAC;QACD,MAAM,UAAU,GACf,OAAO,UAAU,CAAC,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,UAAU;YACjE,CAAC,CAAC,UAAU,CAAC,UAAU;YACvB,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACtC,8BAA8B,CAC7B,uBAAuB,CAAC;YACvB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,UAAU;YACV,KAAK,EAAE,cAAc;YACrB,UAAU;SACV,CAAC,CACF,CAAC;IACH,CAAC;IAES,gBAAgB,CACzB,MAAc,EACd,UAAgC;QAEhC,8BAA8B,CAAC;YAC9B,IAAI,EAAE,cAAc;YACpB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,IAAI,EAAE,MAAM;YACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,UAAU,EAAE,UAAU;gBACrB,CAAC,CAAC,EAAE,GAAI,UAAsC,EAAE;gBAChD,CAAC,CAAC,SAAS;SACZ,CAAC,CAAC;IACJ,CAAC;IAES,qBAAqB,CAAC,UAA+B;QAC9D,8BAA8B,CAAC;YAC9B,IAAI,EAAE,mBAAmB;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,IAAI,EAAE,uBAAuB;YAC7B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,UAAU,EAAE,EAAE,GAAI,UAAsC,EAAE;SAC1D,CAAC,CAAC;IACJ,CAAC;CACD","sourcesContent":["import {\n\tcreateErrorDebugRecord,\n\tcreateEventDebugRecord,\n\tcreateMetricDebugRecord,\n\temitInstrumentationDebugRecord,\n} from \"../debug-panel-stream.js\";\nimport type { ErrorAttributes, InstrumentationConfig } from \"../types.js\";\nimport { BaseInstrumentationProvider } from \"./BaseInstrumentationProvider.js\";\n\nexport class DebugPanelInstrumentationProvider extends BaseInstrumentationProvider {\n\treadonly providerId = \"debug-panel\";\n\treadonly providerName = \"Debug Panel\";\n\n\tasync initialize(config?: InstrumentationConfig): Promise<void> {\n\t\tthis.config = config;\n\t\tthis.initialized = true;\n\t}\n\n\tisReady(): boolean {\n\t\treturn this.initialized;\n\t}\n\n\tdestroy(): void {\n\t\tthis.initialized = false;\n\t}\n\n\tprotected doTrackError(error: Error, attributes: Record<string, any>): void {\n\t\temitInstrumentationDebugRecord(\n\t\t\tcreateErrorDebugRecord({\n\t\t\t\tproviderId: this.providerId,\n\t\t\t\tproviderName: this.providerName,\n\t\t\t\terror,\n\t\t\t\tattributes: attributes as ErrorAttributes,\n\t\t\t}),\n\t\t);\n\t}\n\n\tprotected doTrackEvent(\n\t\teventName: string,\n\t\tattributes: Record<string, any>,\n\t): void {\n\t\temitInstrumentationDebugRecord(\n\t\t\tcreateEventDebugRecord({\n\t\t\t\tproviderId: this.providerId,\n\t\t\t\tproviderName: this.providerName,\n\t\t\t\teventName,\n\t\t\t\tattributes,\n\t\t\t}),\n\t\t);\n\t\tif (!eventName.startsWith(\"metric:\")) {\n\t\t\treturn;\n\t\t}\n\t\tconst rawMetricValue = attributes.metricValue;\n\t\tif (\n\t\t\ttypeof rawMetricValue !== \"number\" ||\n\t\t\t!Number.isFinite(rawMetricValue)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tconst metricName =\n\t\t\ttypeof attributes.metricName === \"string\" && attributes.metricName\n\t\t\t\t? attributes.metricName\n\t\t\t\t: eventName.replace(/^metric:/, \"\");\n\t\temitInstrumentationDebugRecord(\n\t\t\tcreateMetricDebugRecord({\n\t\t\t\tproviderId: this.providerId,\n\t\t\t\tproviderName: this.providerName,\n\t\t\t\tmetricName,\n\t\t\t\tvalue: rawMetricValue,\n\t\t\t\tattributes,\n\t\t\t}),\n\t\t);\n\t}\n\n\tprotected doSetUserContext(\n\t\tuserId: string,\n\t\tattributes?: Record<string, any>,\n\t): void {\n\t\temitInstrumentationDebugRecord({\n\t\t\tkind: \"user-context\",\n\t\t\tproviderId: this.providerId,\n\t\t\tproviderName: this.providerName,\n\t\t\tname: userId,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tattributes: attributes\n\t\t\t\t? { ...(attributes as Record<string, unknown>) }\n\t\t\t\t: undefined,\n\t\t});\n\t}\n\n\tprotected doSetGlobalAttributes(attributes: Record<string, any>): void {\n\t\temitInstrumentationDebugRecord({\n\t\t\tkind: \"global-attributes\",\n\t\t\tproviderId: this.providerId,\n\t\t\tproviderName: this.providerName,\n\t\t\tname: \"set-global-attributes\",\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tattributes: { ...(attributes as Record<string, unknown>) },\n\t\t});\n\t}\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NewRelicInstrumentationProvider.js","sourceRoot":"","sources":["../../../src/instrumentation/providers/NewRelicInstrumentationProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,MAAM,OAAO,+BAAgC,SAAQ,2BAA2B;IACtE,UAAU,GAAG,UAAU,CAAC;IACxB,YAAY,GAAG,WAAW,CAAC;IAEpC;;;;;;;OAOG;IACH,KAAK,CAAC,UAAU,CAAC,MAA8B;QAC9C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,kCAAkC;QAClC,IAAI,OAAO,MAAM,KAAK,WAAW,IAAK,MAAc,CAAC,QAAQ,EAAE,CAAC;YAC/D,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;YAC5D,CAAC;QACF,CAAC;aAAM,CAAC;YACP,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,CACX,wEAAwE,CACxE,CAAC;YACH,CAAC;YACD,2CAA2C;YAC3C,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QAC1B,CAAC;IACF,CAAC;IAED;;;;OAIG;IACH,OAAO;QACN,OAAO,CACN,IAAI,CAAC,WAAW;YAChB,OAAO,MAAM,KAAK,WAAW;YAC7B,CAAC,CAAE,MAAc,CAAC,QAAQ,CAC1B,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,OAAO;QACN,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC7C,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACO,YAAY,CAAC,KAAY,EAAE,UAA+B;QACnE,MAAM,QAAQ,GAAI,MAAc,CAAC,QAAQ,CAAC;QAC1C,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;;OAOG;IACO,YAAY,CACrB,SAAiB,EACjB,UAA+B;QAE/B,MAAM,QAAQ,GAAI,MAAc,CAAC,QAAQ,CAAC;QAC1C,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;;;OAOG;IACO,gBAAgB,CACzB,MAAc,EACd,UAAgC;QAEhC,MAAM,QAAQ,GAAI,MAAc,CAAC,QAAQ,CAAC;QAE1C,+BAA+B;QAC/B,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACxB,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAED,iCAAiC;QACjC,IAAI,UAAU,IAAI,QAAQ,CAAC,kBAAkB,EAAE,CAAC;YAC/C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBACvD,QAAQ,CAAC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACzC,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACO,qBAAqB,CAAC,UAA+B;QAC9D,MAAM,QAAQ,GAAI,MAAc,CAAC,QAAQ,CAAC;QAE1C,IAAI,QAAQ,CAAC,kBAAkB,EAAE,CAAC;YACjC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBACvD,QAAQ,CAAC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACzC,CAAC;QACF,CAAC;IACF,CAAC;CACD","sourcesContent":["/**\n * New Relic Instrumentation Provider\n *\n * Default provider for existing New Relic Browser Agent instrumentation.\n *\n * This provider wraps the global `window.newrelic` object provided by\n * the New Relic Browser Agent.\n *\n * @example\n * ```typescript\n * const provider = new NewRelicInstrumentationProvider();\n * await provider.initialize();\n *\n * if (provider.isReady()) {\n * provider.trackError(new Error('Something went wrong'), {\n * component: 'my-component',\n * errorType: 'ValidationError'\n * });\n * }\n * ```\n */\n\nimport type { InstrumentationConfig } from \"../types.js\";\nimport { BaseInstrumentationProvider } from \"./BaseInstrumentationProvider.js\";\n\nexport class NewRelicInstrumentationProvider extends BaseInstrumentationProvider {\n\treadonly providerId = \"newrelic\";\n\treadonly providerName = \"New Relic\";\n\n\t/**\n\t * Initialize the New Relic provider\n\t *\n\t * Checks if the New Relic Browser Agent is available via `window.newrelic`.\n\t * If not available, initialization succeeds but `isReady()` will return false.\n\t *\n\t * @param config Optional configuration\n\t */\n\tasync initialize(config?: InstrumentationConfig): Promise<void> {\n\t\tthis.config = config;\n\n\t\t// Check if New Relic is available\n\t\tif (typeof window !== \"undefined\" && (window as any).newrelic) {\n\t\t\tthis.initialized = true;\n\t\t\tif (this.config?.debug) {\n\t\t\t\tconsole.log(\"[NewRelicProvider] Initialized successfully\");\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.config?.debug) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t\"[NewRelicProvider] New Relic not available (window.newrelic not found)\",\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Don't throw - allow graceful degradation\n\t\t\tthis.initialized = false;\n\t\t}\n\t}\n\n\t/**\n\t * Check if provider is ready\n\t *\n\t * @returns true if New Relic is available and initialized\n\t */\n\tisReady(): boolean {\n\t\treturn (\n\t\t\tthis.initialized &&\n\t\t\ttypeof window !== \"undefined\" &&\n\t\t\t!!(window as any).newrelic\n\t\t);\n\t}\n\n\t/**\n\t * Cleanup provider resources\n\t *\n\t * Marks provider as uninitialized. The global `window.newrelic` object\n\t * is not modified.\n\t */\n\tdestroy(): void {\n\t\tthis.initialized = false;\n\t\tif (this.config?.debug) {\n\t\t\tconsole.log(\"[NewRelicProvider] Destroyed\");\n\t\t}\n\t}\n\n\t/**\n\t * Track an error with New Relic\n\t *\n\t * Calls `newrelic.noticeError(error, attributes)`\n\t *\n\t * @param error The error to track\n\t * @param attributes Transformed attributes (already filtered and transformed by base class)\n\t */\n\tprotected doTrackError(error: Error, attributes: Record<string, any>): void {\n\t\tconst newrelic = (window as any).newrelic;\n\t\tnewrelic.noticeError(error, attributes);\n\t}\n\n\t/**\n\t * Track a custom event/page action with New Relic\n\t *\n\t * Calls `newrelic.addPageAction(eventName, attributes)`\n\t *\n\t * @param eventName Name of the event\n\t * @param attributes Transformed attributes (already filtered and transformed by base class)\n\t */\n\tprotected doTrackEvent(\n\t\teventName: string,\n\t\tattributes: Record<string, any>,\n\t): void {\n\t\tconst newrelic = (window as any).newrelic;\n\t\tnewrelic.addPageAction(eventName, attributes);\n\t}\n\n\t/**\n\t * Set user context for session tracking\n\t *\n\t * Calls `newrelic.setUserId()` and `newrelic.setCustomAttribute()` for user attributes.\n\t *\n\t * @param userId User identifier\n\t * @param attributes Optional user attributes\n\t */\n\tprotected doSetUserContext(\n\t\tuserId: string,\n\t\tattributes?: Record<string, any>,\n\t): void {\n\t\tconst newrelic = (window as any).newrelic;\n\n\t\t// Set user ID if method exists\n\t\tif (newrelic.setUserId) {\n\t\t\tnewrelic.setUserId(userId);\n\t\t}\n\n\t\t// Set custom attributes for user\n\t\tif (attributes && newrelic.setCustomAttribute) {\n\t\t\tfor (const [key, value] of Object.entries(attributes)) {\n\t\t\t\tnewrelic.setCustomAttribute(key, value);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set global custom attributes\n\t *\n\t * Calls `newrelic.setCustomAttribute()` for each attribute.\n\t *\n\t * @param attributes Attributes to set globally\n\t */\n\tprotected doSetGlobalAttributes(attributes: Record<string, any>): void {\n\t\tconst newrelic = (window as any).newrelic;\n\n\t\tif (newrelic.setCustomAttribute) {\n\t\t\tfor (const [key, value] of Object.entries(attributes)) {\n\t\t\t\tnewrelic.setCustomAttribute(key, value);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/instrumentation/providers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2CAA2C;AAC3C,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,qBAAqB;AACrB,OAAO,EAAE,gCAAgC,EAAE,MAAM,uCAAuC,CAAC;AACzF,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,OAAO,EAAE,iCAAiC,EAAE,MAAM,wCAAwC,CAAC;AAC3F,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC","sourcesContent":["/**\n * Instrumentation Providers\n *\n * This module exports all available instrumentation providers.\n */\n\n// Base class for creating custom providers\nexport { BaseInstrumentationProvider } from \"./BaseInstrumentationProvider.js\";\nexport type { ConsoleProviderConfig } from \"./ConsoleInstrumentationProvider.js\";\n// Built-in providers\nexport { CompositeInstrumentationProvider } from \"./CompositeInstrumentationProvider.js\";\nexport { ConsoleInstrumentationProvider } from \"./ConsoleInstrumentationProvider.js\";\nexport { DebugPanelInstrumentationProvider } from \"./DebugPanelInstrumentationProvider.js\";\nexport { NewRelicInstrumentationProvider } from \"./NewRelicInstrumentationProvider.js\";\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/instrumentation/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG","sourcesContent":["/**\n * Instrumentation Types\n *\n * Core interfaces and types for pluggable instrumentation system.\n * Abstracts vendor-specific APIs (New Relic and custom providers)\n * to enable clients to use any instrumentation provider.\n */\n\n/**\n * Pluggable instrumentation provider interface\n *\n * All instrumentation providers must implement this interface.\n * Provides methods for tracking errors, events, and metrics.\n *\n * @example\n * ```typescript\n * class CustomProvider implements InstrumentationProvider {\n * readonly providerId = 'custom';\n * readonly providerName = 'Custom Analytics';\n *\n * async initialize(config?: InstrumentationConfig): Promise<void> {\n * // Initialize your analytics SDK\n * }\n *\n * trackError(error: Error, attributes: ErrorAttributes): void {\n * // Send error to your analytics backend\n * }\n *\n * trackEvent(eventName: string, attributes: EventAttributes): void {\n * // Send event to your analytics backend\n * }\n *\n * isReady(): boolean {\n * return true;\n * }\n *\n * destroy(): void {\n * // Cleanup\n * }\n * }\n * ```\n */\nexport interface InstrumentationProvider {\n\t/**\n\t * Unique identifier for the provider (e.g., 'newrelic', 'console')\n\t */\n\treadonly providerId: string;\n\n\t/**\n\t * Human-readable provider name (e.g., 'New Relic')\n\t */\n\treadonly providerName: string;\n\n\t/**\n\t * Initialize the provider (load SDKs, configure clients, etc.)\n\t *\n\t * @param config Optional configuration for the provider\n\t */\n\tinitialize(config?: InstrumentationConfig): Promise<void>;\n\n\t/**\n\t * Track an error with contextual attributes\n\t *\n\t * @param error The error to track\n\t * @param attributes Contextual attributes about the error\n\t */\n\ttrackError(error: Error, attributes: ErrorAttributes): void;\n\n\t/**\n\t * Track a custom event/page action\n\t *\n\t * @param eventName Name of the event (e.g., 'pie-resource-load', 'pie-resource-retry')\n\t * @param attributes Contextual attributes about the event\n\t */\n\ttrackEvent(eventName: string, attributes: EventAttributes): void;\n\n\t/**\n\t * Track a performance metric\n\t *\n\t * Optional - not all providers support direct metrics.\n\t * For providers without metric support, consider tracking as custom events instead.\n\t *\n\t * @param metricName Name of the metric\n\t * @param value Numeric value of the metric\n\t * @param attributes Optional attributes about the metric\n\t */\n\ttrackMetric?(\n\t\tmetricName: string,\n\t\tvalue: number,\n\t\tattributes?: MetricAttributes,\n\t): void;\n\n\t/**\n\t * Set user context for session tracking\n\t *\n\t * Optional - associates user information with subsequent events/errors.\n\t *\n\t * @param userId User identifier\n\t * @param attributes Optional user attributes\n\t */\n\tsetUserContext?(userId: string, attributes?: Record<string, any>): void;\n\n\t/**\n\t * Set custom attributes that apply to all subsequent events\n\t *\n\t * Optional - useful for setting context like environment, version, etc.\n\t *\n\t * @param attributes Attributes to set globally\n\t */\n\tsetGlobalAttributes?(attributes: Record<string, any>): void;\n\n\t/**\n\t * Cleanup provider resources\n\t *\n\t * Called when the provider is being destroyed or replaced.\n\t */\n\tdestroy(): void;\n\n\t/**\n\t * Check if provider is ready to track events\n\t *\n\t * @returns true if provider is initialized and ready, false otherwise\n\t */\n\tisReady(): boolean;\n}\n\n/**\n * Configuration for instrumentation providers\n */\nexport interface InstrumentationConfig {\n\t/**\n\t * Enable/disable instrumentation\n\t *\n\t * @default true\n\t */\n\tenabled?: boolean;\n\n\t/**\n\t * Enable debug logging\n\t *\n\t * @default false\n\t */\n\tdebug?: boolean;\n\n\t/**\n\t * Sample rate for events (0.0 to 1.0)\n\t *\n\t * 1.0 = 100% of events tracked\n\t * 0.5 = 50% of events tracked\n\t * 0.1 = 10% of events tracked\n\t *\n\t * @default 1.0\n\t */\n\tsampleRate?: number;\n\n\t/**\n\t * Provider-specific settings\n\t *\n\t * Each provider can define its own configuration structure.\n\t *\n\t * @example New Relic\n\t * ```typescript\n\t * providerSettings: {\n\t * // New Relic doesn't need additional config (uses global newrelic object)\n\t * }\n\t * ```\n\t *\n\t * @example Console provider\n\t * ```typescript\n\t * providerSettings: {\n\t * useColors: true\n\t * }\n\t * ```\n\t */\n\tproviderSettings?: Record<string, any>;\n\n\t/**\n\t * Filter function for errors\n\t *\n\t * Return false to skip tracking the error.\n\t *\n\t * @param error The error being tracked\n\t * @param attributes The error attributes\n\t * @returns true to track, false to skip\n\t */\n\terrorFilter?: (error: Error, attributes: ErrorAttributes) => boolean;\n\n\t/**\n\t * Filter function for events\n\t *\n\t * Return false to skip tracking the event.\n\t *\n\t * @param eventName The event name\n\t * @param attributes The event attributes\n\t * @returns true to track, false to skip\n\t */\n\teventFilter?: (eventName: string, attributes: EventAttributes) => boolean;\n\n\t/**\n\t * Transform function for attributes\n\t *\n\t * Allows modifying or enriching attributes before they're sent to the provider.\n\t *\n\t * @param attributes The original attributes\n\t * @returns The transformed attributes\n\t */\n\tattributeTransformer?: (\n\t\tattributes: Record<string, any>,\n\t) => Record<string, any>;\n}\n\n/**\n * Common error attributes\n *\n * These attributes are sent with error tracking calls.\n * All providers should support these base attributes.\n */\nexport interface ErrorAttributes {\n\t/**\n\t * Component that generated the error\n\t *\n\t * Examples: 'pie-item-player', 'pie-resource-monitor'\n\t */\n\tcomponent: string;\n\n\t/**\n\t * Type/category of error\n\t *\n\t * Examples: 'InvalidConfig', 'ConfigParseError', 'EsmLoadingError',\n\t * 'IifeLoadingError', 'ResourceLoadError'\n\t */\n\terrorType: string;\n\n\t// Contextual data (all optional, depends on error type)\n\n\t/**\n\t * Single item ID (if error relates to a specific item)\n\t */\n\titemId?: string;\n\n\t/**\n\t * Multiple item IDs (if error relates to multiple items)\n\t */\n\titemIds?: string[];\n\n\t/**\n\t * PIE element type (if error relates to a specific element)\n\t *\n\t * Examples: '@pie-element/inline-choice', '@pie-element/match'\n\t */\n\telementType?: string;\n\n\t/**\n\t * CDN base URL (for ESM loading errors)\n\t */\n\tcdnBaseUrl?: string;\n\n\t/**\n\t * Bundle host URL (for IIFE loading errors)\n\t */\n\tbundleHost?: string;\n\n\t/**\n\t * Resource URL (for resource loading errors)\n\t */\n\tresourceUrl?: string;\n\n\t/**\n\t * Resource type (for resource loading errors)\n\t *\n\t * Examples: 'img', 'audio', 'video', 'link', 'source'\n\t */\n\tresourceType?: string;\n\n\t/**\n\t * Duration in milliseconds (for timing-related errors)\n\t */\n\tduration?: number;\n\n\t/**\n\t * Retry count (for retry-related errors)\n\t */\n\tretryCount?: number;\n\n\t/**\n\t * Whether retry was attempted (for resource errors)\n\t */\n\twasRetried?: boolean;\n\n\t/**\n\t * Extensible for additional context-specific attributes\n\t */\n\t[key: string]: any;\n}\n\n/**\n * Common event attributes\n *\n * These attributes are sent with event tracking calls.\n */\nexport interface EventAttributes {\n\t/**\n\t * Component that generated the event\n\t *\n\t * Optional - some events may be component-agnostic\n\t */\n\tcomponent?: string;\n\n\t/**\n\t * Timestamp of the event\n\t *\n\t * ISO 8601 format string\n\t */\n\ttimestamp?: string;\n\n\t// Resource loading events\n\n\t/**\n\t * Resource URL\n\t */\n\turl?: string;\n\n\t/**\n\t * Load duration in milliseconds\n\t */\n\tduration?: number;\n\n\t/**\n\t * Transfer size in bytes\n\t */\n\tsize?: number;\n\n\t/**\n\t * Resource type\n\t *\n\t * Examples: 'img', 'audio', 'video', 'link', 'script', 'stylesheet'\n\t */\n\ttype?: string;\n\n\t/**\n\t * Whether the resource load failed\n\t */\n\tfailed?: boolean;\n\n\t/**\n\t * Whether retry was attempted\n\t */\n\twasRetried?: boolean;\n\n\t/**\n\t * Retry count\n\t */\n\tretryCount?: number;\n\n\t/**\n\t * Retry attempt number\n\t */\n\tattempt?: number;\n\n\t/**\n\t * Delay before retry in milliseconds\n\t */\n\tdelay?: number;\n\n\t/**\n\t * Extensible for additional event-specific attributes\n\t */\n\t[key: string]: any;\n}\n\n/**\n * Metric attributes\n *\n * These attributes are sent with metric tracking calls.\n */\nexport interface MetricAttributes {\n\t/**\n\t * Unit of measurement\n\t *\n\t * Examples: 'ms', 'bytes', 'count', 'percent'\n\t */\n\tunit?: string;\n\n\t/**\n\t * Category of metric\n\t *\n\t * Examples: 'performance', 'resource', 'error', 'user-action'\n\t */\n\tcategory?: string;\n\n\t/**\n\t * Extensible for additional metric-specific attributes\n\t */\n\t[key: string]: any;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loader-config.js","sourceRoot":"","sources":["../src/loader-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwEH,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC/C,YAAY,EAAE,IAAI;IAClB,SAAS,EAAE,MAAM;CACR,CAAC;AAEX,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACpC,gBAAgB,EAAE,KAAK;IACvB,uBAAuB,EAAE,SAAS;IAClC,kBAAkB,EAAE,CAAC;IACrB,kBAAkB,EAAE,GAAG;IACvB,eAAe,EAAE,gCAAgC;CACxC,CAAC","sourcesContent":["/**\n * Shared loader configuration for PIE custom elements.\n *\n * Mirrors the `LoaderConfig` used by PIEOneer's custom element tags.\n */\n\nimport type { InstrumentationProvider } from \"./instrumentation/types.js\";\n\nexport type IifeBundleRetryConfig = {\n\t/**\n\t * Delay in ms between IIFE bundle retry attempts.\n\t */\n\tretryDelayMs?: number;\n\n\t/**\n\t * Total timeout in ms before IIFE bundle load retries fail permanently.\n\t */\n\ttimeoutMs?: number;\n};\n\nexport type LoaderConfig = {\n\t/**\n\t * Enable tracking page actions/events.\n\t *\n\t * When true, instrumentation events will be sent to the instrumentation provider.\n\t */\n\ttrackPageActions?: boolean;\n\n\t/**\n\t * Instrumentation provider for tracking events and errors.\n\t *\n\t * Optional. If not provided, defaults to NewRelicInstrumentationProvider.\n\t * The provider handles instrumentation gracefully - if New Relic (or the configured\n\t * backend) is not available, it will simply not track events (no errors thrown).\n\t *\n\t * @example Using New Relic (default - no configuration needed)\n\t * ```typescript\n\t * // Just enable tracking - will use New Relic if window.newrelic is available\n\t * const loaderConfig = {\n\t * trackPageActions: true\n\t * };\n\t * ```\n\t * @example Using Console provider (for development/debugging)\n\t * ```typescript\n\t * import { ConsoleInstrumentationProvider } from '@pie-players/pie-players-shared';\n\t *\n\t * const provider = new ConsoleInstrumentationProvider({ useColors: true });\n\t * await provider.initialize({ debug: true });\n\t *\n\t * const loaderConfig = {\n\t * trackPageActions: true,\n\t * instrumentationProvider: provider\n\t * };\n\t * ```\n\t */\n\tinstrumentationProvider?: InstrumentationProvider;\n\n\t/**\n\t * Maximum number of retry attempts for failed resources (images/audio/video).\n\t */\n\tmaxResourceRetries?: number;\n\n\t/**\n\t * Initial delay in ms before first resource retry attempt (exponential backoff).\n\t */\n\tresourceRetryDelay?: number;\n\n\t/**\n\t * Retry policy for IIFE bundle loads.\n\t *\n\t * Kept separate from resource retry settings so bundle-build polling can be tuned\n\t * independently from media/resource retries.\n\t */\n\tiifeBundleRetry?: IifeBundleRetryConfig;\n};\n\nexport const DEFAULT_IIFE_BUNDLE_RETRY_CONFIG = {\n\tretryDelayMs: 3000,\n\ttimeoutMs: 120000,\n} as const;\n\nexport const DEFAULT_LOADER_CONFIG = {\n\ttrackPageActions: false,\n\tinstrumentationProvider: undefined,\n\tmaxResourceRetries: 3,\n\tresourceRetryDelay: 500,\n\tiifeBundleRetry: DEFAULT_IIFE_BUNDLE_RETRY_CONFIG,\n} as const;\n"]}
|