@flareapp/svelte 2.1.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -2
- package/.svelte-kit/__package__/FlareErrorBoundary.svelte +0 -78
- package/.svelte-kit/__package__/FlareErrorBoundary.svelte.d.ts +0 -14
- package/.svelte-kit/__package__/componentTree.d.ts +0 -9
- package/.svelte-kit/__package__/componentTree.js +0 -99
- package/.svelte-kit/__package__/config.d.ts +0 -12
- package/.svelte-kit/__package__/config.js +0 -25
- package/.svelte-kit/__package__/contextToAttributes.d.ts +0 -3
- package/.svelte-kit/__package__/contextToAttributes.js +0 -7
- package/.svelte-kit/__package__/createFlareErrorHandler.d.ts +0 -17
- package/.svelte-kit/__package__/createFlareErrorHandler.js +0 -34
- package/.svelte-kit/__package__/extractComponentInfo.d.ts +0 -8
- package/.svelte-kit/__package__/extractComponentInfo.js +0 -42
- package/.svelte-kit/__package__/getErrorOrigin.d.ts +0 -3
- package/.svelte-kit/__package__/getErrorOrigin.js +0 -64
- package/.svelte-kit/__package__/identify.d.ts +0 -1
- package/.svelte-kit/__package__/identify.js +0 -10
- package/.svelte-kit/__package__/index.d.ts +0 -6
- package/.svelte-kit/__package__/index.js +0 -7
- package/.svelte-kit/__package__/preprocessor.d.ts +0 -5
- package/.svelte-kit/__package__/preprocessor.js +0 -53
- package/.svelte-kit/__package__/types.d.ts +0 -8
- package/.svelte-kit/__package__/types.js +0 -1
- package/.svelte-kit/__package__/version.d.ts +0 -1
- package/.svelte-kit/__package__/version.js +0 -2
- package/test-results/.last-run.json +0 -4
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "2.1
|
|
1
|
+
export declare const PACKAGE_VERSION = "2.2.1";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// generated during release, do not modify
|
|
2
|
-
export const PACKAGE_VERSION = '2.1
|
|
2
|
+
export const PACKAGE_VERSION = '2.2.1';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flareapp/svelte",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Svelte client for flareapp.io",
|
|
5
5
|
"homepage": "https://flareapp.io",
|
|
6
6
|
"bugs": "https://github.com/spatie/flare-client-js/issues",
|
|
@@ -22,6 +22,9 @@
|
|
|
22
22
|
"Sébastien Henau <seba@spatie.be>"
|
|
23
23
|
],
|
|
24
24
|
"type": "module",
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
25
28
|
"main": "./dist/index.js",
|
|
26
29
|
"module": "./dist/index.js",
|
|
27
30
|
"svelte": "./dist/index.js",
|
|
@@ -60,7 +63,7 @@
|
|
|
60
63
|
"vitest": "^4.0.0"
|
|
61
64
|
},
|
|
62
65
|
"peerDependencies": {
|
|
63
|
-
"@flareapp/js": "^2.1
|
|
66
|
+
"@flareapp/js": "^2.2.1",
|
|
64
67
|
"svelte": "^5.3.0"
|
|
65
68
|
},
|
|
66
69
|
"publishConfig": {
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
3
|
-
|
|
4
|
-
import { __flareRegisterComponent, getComponentTreeContext } from './componentTree.js';
|
|
5
|
-
import { createFlareErrorHandler, type FlareErrorHandlerOptions } from './createFlareErrorHandler.js';
|
|
6
|
-
|
|
7
|
-
interface Props {
|
|
8
|
-
children: Snippet;
|
|
9
|
-
failed?: Snippet<[error: Error, reset: () => void]>;
|
|
10
|
-
resetKeys?: unknown[];
|
|
11
|
-
beforeEvaluate?: FlareErrorHandlerOptions['beforeEvaluate'];
|
|
12
|
-
beforeSubmit?: FlareErrorHandlerOptions['beforeSubmit'];
|
|
13
|
-
afterSubmit?: FlareErrorHandlerOptions['afterSubmit'];
|
|
14
|
-
onReset?: (error: Error | null) => void;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
let {
|
|
18
|
-
children,
|
|
19
|
-
failed: fallbackSnippet,
|
|
20
|
-
resetKeys,
|
|
21
|
-
beforeEvaluate,
|
|
22
|
-
beforeSubmit,
|
|
23
|
-
afterSubmit,
|
|
24
|
-
onReset,
|
|
25
|
-
}: Props = $props();
|
|
26
|
-
|
|
27
|
-
let currentError: Error | null = $state(null);
|
|
28
|
-
let resetBoundary: (() => void) | null = $state(null);
|
|
29
|
-
|
|
30
|
-
let previousKeys: unknown[] | undefined;
|
|
31
|
-
$effect(() => {
|
|
32
|
-
if (!currentError || !resetKeys) {
|
|
33
|
-
previousKeys = resetKeys ? [...resetKeys] : undefined;
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const lengthChanged = previousKeys?.length !== resetKeys.length;
|
|
38
|
-
const valuesChanged = resetKeys.some((key, i) => !Object.is(key, previousKeys?.[i]));
|
|
39
|
-
|
|
40
|
-
if (lengthChanged || valuesChanged) {
|
|
41
|
-
handleReset();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
previousKeys = [...resetKeys];
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
function handleReset() {
|
|
48
|
-
const error = currentError;
|
|
49
|
-
currentError = null;
|
|
50
|
-
onReset?.(error);
|
|
51
|
-
resetBoundary?.();
|
|
52
|
-
resetBoundary = null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const ancestor = __flareRegisterComponent('FlareErrorBoundary', '@flareapp/svelte/FlareErrorBoundary.svelte');
|
|
56
|
-
|
|
57
|
-
const handler = $derived(
|
|
58
|
-
createFlareErrorHandler({ ancestor, beforeEvaluate, beforeSubmit, afterSubmit }),
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
function onerror(rawError: unknown, reset: () => void) {
|
|
62
|
-
resetBoundary = reset;
|
|
63
|
-
const error = rawError instanceof Error ? rawError : new Error(String(rawError));
|
|
64
|
-
currentError = error;
|
|
65
|
-
|
|
66
|
-
handler(rawError, reset);
|
|
67
|
-
}
|
|
68
|
-
</script>
|
|
69
|
-
|
|
70
|
-
<svelte:boundary {onerror}>
|
|
71
|
-
{@render children()}
|
|
72
|
-
|
|
73
|
-
{#snippet failed(error, reset)}
|
|
74
|
-
{#if fallbackSnippet}
|
|
75
|
-
{@render fallbackSnippet(error instanceof Error ? error : new Error(String(error)), handleReset)}
|
|
76
|
-
{/if}
|
|
77
|
-
{/snippet}
|
|
78
|
-
</svelte:boundary>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
import { type FlareErrorHandlerOptions } from './createFlareErrorHandler.js';
|
|
3
|
-
interface Props {
|
|
4
|
-
children: Snippet;
|
|
5
|
-
failed?: Snippet<[error: Error, reset: () => void]>;
|
|
6
|
-
resetKeys?: unknown[];
|
|
7
|
-
beforeEvaluate?: FlareErrorHandlerOptions['beforeEvaluate'];
|
|
8
|
-
beforeSubmit?: FlareErrorHandlerOptions['beforeSubmit'];
|
|
9
|
-
afterSubmit?: FlareErrorHandlerOptions['afterSubmit'];
|
|
10
|
-
onReset?: (error: Error | null) => void;
|
|
11
|
-
}
|
|
12
|
-
declare const FlareErrorBoundary: import("svelte").Component<Props, {}, "">;
|
|
13
|
-
type FlareErrorBoundary = ReturnType<typeof FlareErrorBoundary>;
|
|
14
|
-
export default FlareErrorBoundary;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export interface ComponentTreeNode {
|
|
2
|
-
name: string;
|
|
3
|
-
file: string;
|
|
4
|
-
parent: ComponentTreeNode | null;
|
|
5
|
-
}
|
|
6
|
-
export declare function __flareRegisterComponent(name: string, file: string): ComponentTreeNode;
|
|
7
|
-
export declare function getComponentTreeContext(): ComponentTreeNode | null;
|
|
8
|
-
export declare function lookupComponentTree(fileName: string, ancestor?: ComponentTreeNode | null): string[];
|
|
9
|
-
export declare function findNode(fileName: string, ancestor?: ComponentTreeNode | null): ComponentTreeNode | undefined;
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { getContext, onDestroy, setContext } from 'svelte';
|
|
2
|
-
const CONTEXT_KEY = '__flare_component_tree';
|
|
3
|
-
const registry = new Map();
|
|
4
|
-
export function __flareRegisterComponent(name, file) {
|
|
5
|
-
let parent = null;
|
|
6
|
-
try {
|
|
7
|
-
parent = getContext(CONTEXT_KEY) ?? null;
|
|
8
|
-
}
|
|
9
|
-
catch {
|
|
10
|
-
// getContext throws outside component init
|
|
11
|
-
}
|
|
12
|
-
const node = { name, file, parent };
|
|
13
|
-
try {
|
|
14
|
-
setContext(CONTEXT_KEY, node);
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
// setContext throws outside component init
|
|
18
|
-
}
|
|
19
|
-
let nodes = registry.get(file);
|
|
20
|
-
if (!nodes) {
|
|
21
|
-
nodes = new Set();
|
|
22
|
-
registry.set(file, nodes);
|
|
23
|
-
}
|
|
24
|
-
nodes.add(node);
|
|
25
|
-
try {
|
|
26
|
-
onDestroy(() => {
|
|
27
|
-
const set = registry.get(file);
|
|
28
|
-
if (set) {
|
|
29
|
-
set.delete(node);
|
|
30
|
-
if (set.size === 0) {
|
|
31
|
-
registry.delete(file);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
// onDestroy throws outside component init
|
|
38
|
-
}
|
|
39
|
-
return node;
|
|
40
|
-
}
|
|
41
|
-
export function getComponentTreeContext() {
|
|
42
|
-
try {
|
|
43
|
-
return getContext(CONTEXT_KEY) ?? null;
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
export function lookupComponentTree(fileName, ancestor) {
|
|
50
|
-
const node = findNode(fileName, ancestor);
|
|
51
|
-
if (!node) {
|
|
52
|
-
return [];
|
|
53
|
-
}
|
|
54
|
-
const hierarchy = [];
|
|
55
|
-
let current = node;
|
|
56
|
-
const seen = new Set();
|
|
57
|
-
while (current && !seen.has(current)) {
|
|
58
|
-
seen.add(current);
|
|
59
|
-
hierarchy.push(current.name);
|
|
60
|
-
current = current.parent;
|
|
61
|
-
}
|
|
62
|
-
return hierarchy;
|
|
63
|
-
}
|
|
64
|
-
export function findNode(fileName, ancestor) {
|
|
65
|
-
const normalizedLookup = normalizePath(fileName);
|
|
66
|
-
const candidates = [];
|
|
67
|
-
for (const [registeredFile, nodes] of registry) {
|
|
68
|
-
const normalizedFile = normalizePath(registeredFile);
|
|
69
|
-
const match = normalizedLookup === normalizedFile ||
|
|
70
|
-
normalizedLookup.endsWith(normalizedFile) ||
|
|
71
|
-
normalizedFile.endsWith(normalizedLookup);
|
|
72
|
-
if (match) {
|
|
73
|
-
for (const node of nodes) {
|
|
74
|
-
candidates.push(node);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
if (candidates.length === 0) {
|
|
79
|
-
return undefined;
|
|
80
|
-
}
|
|
81
|
-
if (ancestor && candidates.length > 1) {
|
|
82
|
-
return candidates.find((c) => hasAncestor(c, ancestor)) ?? candidates[0];
|
|
83
|
-
}
|
|
84
|
-
return candidates[0];
|
|
85
|
-
}
|
|
86
|
-
function hasAncestor(node, ancestor) {
|
|
87
|
-
let current = node.parent;
|
|
88
|
-
const seen = new Set();
|
|
89
|
-
while (current && !seen.has(current)) {
|
|
90
|
-
if (current === ancestor)
|
|
91
|
-
return true;
|
|
92
|
-
seen.add(current);
|
|
93
|
-
current = current.parent;
|
|
94
|
-
}
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
function normalizePath(filePath) {
|
|
98
|
-
return filePath.replace(/\\/g, '/').replace(/^.*?\/src\//, 'src/');
|
|
99
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { PreprocessorGroup } from 'svelte/compiler';
|
|
2
|
-
import { type FlarePreprocessorOptions } from './preprocessor.js';
|
|
3
|
-
interface SvelteConfig {
|
|
4
|
-
preprocess?: PreprocessorGroup | PreprocessorGroup[];
|
|
5
|
-
[key: string]: unknown;
|
|
6
|
-
}
|
|
7
|
-
export interface WithFlareConfigOptions {
|
|
8
|
-
componentTracking?: boolean;
|
|
9
|
-
exclude?: FlarePreprocessorOptions['exclude'];
|
|
10
|
-
}
|
|
11
|
-
export declare function withFlareConfig(config: SvelteConfig, options?: WithFlareConfigOptions): SvelteConfig;
|
|
12
|
-
export { flarePreprocessor, type FlarePreprocessorOptions } from './preprocessor.js';
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { flarePreprocessor } from './preprocessor.js';
|
|
2
|
-
export function withFlareConfig(config, options) {
|
|
3
|
-
const { componentTracking = true, exclude } = options ?? {};
|
|
4
|
-
if (!componentTracking) {
|
|
5
|
-
return config;
|
|
6
|
-
}
|
|
7
|
-
const existing = normalizePreprocessors(config.preprocess);
|
|
8
|
-
if (existing.some((p) => !!p.__flareId)) {
|
|
9
|
-
return config;
|
|
10
|
-
}
|
|
11
|
-
const preprocessor = flarePreprocessor({ exclude });
|
|
12
|
-
preprocessor.__flareId = true;
|
|
13
|
-
return {
|
|
14
|
-
...config,
|
|
15
|
-
preprocess: [preprocessor, ...existing],
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
function normalizePreprocessors(preprocess) {
|
|
19
|
-
if (!preprocess)
|
|
20
|
-
return [];
|
|
21
|
-
if (Array.isArray(preprocess))
|
|
22
|
-
return preprocess;
|
|
23
|
-
return [preprocess];
|
|
24
|
-
}
|
|
25
|
-
export { flarePreprocessor } from './preprocessor.js';
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { ComponentTreeNode } from './componentTree.js';
|
|
2
|
-
import type { FlareSvelteContext } from './types.js';
|
|
3
|
-
export interface FlareErrorHandlerOptions {
|
|
4
|
-
ancestor?: ComponentTreeNode | null;
|
|
5
|
-
beforeEvaluate?: (params: {
|
|
6
|
-
error: Error;
|
|
7
|
-
}) => void;
|
|
8
|
-
beforeSubmit?: (params: {
|
|
9
|
-
error: Error;
|
|
10
|
-
context: FlareSvelteContext;
|
|
11
|
-
}) => FlareSvelteContext;
|
|
12
|
-
afterSubmit?: (params: {
|
|
13
|
-
error: Error;
|
|
14
|
-
context: FlareSvelteContext;
|
|
15
|
-
}) => void;
|
|
16
|
-
}
|
|
17
|
-
export declare function createFlareErrorHandler(options?: FlareErrorHandlerOptions): (rawError: unknown, _reset: () => void) => Promise<void>;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { convertToError, flare } from '@flareapp/js';
|
|
2
|
-
import ErrorStackParser from 'error-stack-parser';
|
|
3
|
-
import { contextToAttributes } from './contextToAttributes.js';
|
|
4
|
-
import { extractComponentInfo } from './extractComponentInfo.js';
|
|
5
|
-
import { getErrorOrigin } from './getErrorOrigin.js';
|
|
6
|
-
import { registerSvelteSdkIdentity } from './identify.js';
|
|
7
|
-
registerSvelteSdkIdentity();
|
|
8
|
-
export function createFlareErrorHandler(options) {
|
|
9
|
-
return async (rawError, _reset) => {
|
|
10
|
-
const error = convertToError(rawError);
|
|
11
|
-
options?.beforeEvaluate?.({ error });
|
|
12
|
-
let frames = [];
|
|
13
|
-
try {
|
|
14
|
-
frames = ErrorStackParser.parse(error);
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
// unparseable stack
|
|
18
|
-
}
|
|
19
|
-
const { componentName, componentHierarchy } = extractComponentInfo(frames, options?.ancestor);
|
|
20
|
-
const errorOrigin = getErrorOrigin(frames);
|
|
21
|
-
let context = {
|
|
22
|
-
svelte: {
|
|
23
|
-
componentName,
|
|
24
|
-
componentHierarchy,
|
|
25
|
-
errorOrigin,
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
if (options?.beforeSubmit) {
|
|
29
|
-
context = options.beforeSubmit({ error, context });
|
|
30
|
-
}
|
|
31
|
-
flare.reportSilently(error, contextToAttributes(context));
|
|
32
|
-
options?.afterSubmit?.({ error, context });
|
|
33
|
-
};
|
|
34
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type ErrorStackParser from 'error-stack-parser';
|
|
2
|
-
import { type ComponentTreeNode } from './componentTree.js';
|
|
3
|
-
interface ComponentInfo {
|
|
4
|
-
componentName: string | null;
|
|
5
|
-
componentHierarchy: string[];
|
|
6
|
-
}
|
|
7
|
-
export declare function extractComponentInfo(frames: ErrorStackParser.StackFrame[], ancestor?: ComponentTreeNode | null): ComponentInfo;
|
|
8
|
-
export {};
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { lookupComponentTree } from './componentTree.js';
|
|
2
|
-
export function extractComponentInfo(frames, ancestor) {
|
|
3
|
-
const svelteFrames = frames.filter((frame) => frame.fileName && frame.fileName.includes('.svelte'));
|
|
4
|
-
if (svelteFrames.length === 0) {
|
|
5
|
-
return { componentName: null, componentHierarchy: [] };
|
|
6
|
-
}
|
|
7
|
-
// Try the preprocessor-based component tree first.
|
|
8
|
-
// Walk each .svelte frame until we find one that was registered.
|
|
9
|
-
for (const frame of svelteFrames) {
|
|
10
|
-
if (!frame.fileName)
|
|
11
|
-
continue;
|
|
12
|
-
const treeHierarchy = lookupComponentTree(frame.fileName, ancestor);
|
|
13
|
-
if (treeHierarchy.length > 0) {
|
|
14
|
-
return {
|
|
15
|
-
componentName: treeHierarchy[0],
|
|
16
|
-
componentHierarchy: treeHierarchy,
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
// Fallback: extract names from stack frames only (no preprocessor).
|
|
21
|
-
const names = [];
|
|
22
|
-
for (const frame of svelteFrames) {
|
|
23
|
-
const name = extractName(frame);
|
|
24
|
-
if (name && name !== names[names.length - 1]) {
|
|
25
|
-
names.push(name);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return {
|
|
29
|
-
componentName: names[0] ?? null,
|
|
30
|
-
componentHierarchy: names,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
function extractName(frame) {
|
|
34
|
-
if (frame.functionName && frame.functionName !== '<anonymous>' && !frame.functionName.includes('.')) {
|
|
35
|
-
return frame.functionName;
|
|
36
|
-
}
|
|
37
|
-
if (frame.fileName) {
|
|
38
|
-
const match = frame.fileName.match(/([^/]+)\.svelte/);
|
|
39
|
-
return match?.[1] ?? null;
|
|
40
|
-
}
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// Heuristic classification of where a Svelte error originated, based on stack frame inspection.
|
|
2
|
-
//
|
|
3
|
-
// Svelte's onMount/beforeUpdate/$effect callbacks, DOM event handlers, and render functions
|
|
4
|
-
// all produce errors that look identical at the catch site (the error boundary sees a plain Error
|
|
5
|
-
// either way). The only distinguishing signal is the stack trace: different origins leave
|
|
6
|
-
// recognizable function names, file names, or DOM API calls in the frames.
|
|
7
|
-
//
|
|
8
|
-
// We check patterns in priority order: event > effect > render > unknown.
|
|
9
|
-
// Priority matters because an event handler inside a Svelte component would match both
|
|
10
|
-
// EVENT_PATTERNS and the .svelte filename check; we want 'event' to win.
|
|
11
|
-
// Inline event handlers (onclick, onsubmit, ...) and DOM event API calls.
|
|
12
|
-
// Browsers compile `onclick={handler}` to `.onclick = ...` or `addEventListener(...)`,
|
|
13
|
-
// so these patterns catch both Svelte's compiled output and manual DOM calls.
|
|
14
|
-
const EVENT_PATTERNS = [
|
|
15
|
-
/\.onclick\b/i,
|
|
16
|
-
/\.onsubmit\b/i,
|
|
17
|
-
/\.onchange\b/i,
|
|
18
|
-
/\.oninput\b/i,
|
|
19
|
-
/\.onkeydown\b/i,
|
|
20
|
-
/\.onkeyup\b/i,
|
|
21
|
-
/\.onfocus\b/i,
|
|
22
|
-
/\.onblur\b/i,
|
|
23
|
-
/\.onmouse/i,
|
|
24
|
-
/\.onpointer/i,
|
|
25
|
-
/\.ontouch/i,
|
|
26
|
-
/addEventListener/,
|
|
27
|
-
/dispatchEvent/,
|
|
28
|
-
/EventTarget\./,
|
|
29
|
-
/HTMLElement\./,
|
|
30
|
-
/HTMLButtonElement\./,
|
|
31
|
-
/HTMLInputElement\./,
|
|
32
|
-
/HTMLFormElement\./,
|
|
33
|
-
];
|
|
34
|
-
// Async side-effects: $effect callbacks, onMount microtasks, promise continuations.
|
|
35
|
-
// Svelte 5 schedules effects via queueMicrotask; promise chains and MutationObserver
|
|
36
|
-
// callbacks are also async side-effects, not render-phase code.
|
|
37
|
-
const EFFECT_PATTERNS = [/queueMicrotask/, /Promise\.then/, /Promise\.catch/, /MutationObserver/];
|
|
38
|
-
// Inspects a parsed stack trace and classifies the error origin into one of:
|
|
39
|
-
// 'event' - error happened in a DOM event handler
|
|
40
|
-
// 'effect' - error happened in an async side-effect ($effect, onMount, promise)
|
|
41
|
-
// 'render' - error happened during Svelte component render (template/script top-level)
|
|
42
|
-
// 'unknown' - no frames or no recognizable pattern
|
|
43
|
-
export function getErrorOrigin(frames) {
|
|
44
|
-
if (frames.length === 0) {
|
|
45
|
-
return 'unknown';
|
|
46
|
-
}
|
|
47
|
-
// Flatten each frame into a single searchable string so regex matching is straightforward.
|
|
48
|
-
const frameStrings = frames.map((f) => `${f.functionName ?? ''} ${f.fileName ?? ''} ${f.source ?? ''}`);
|
|
49
|
-
// Check event patterns first (highest priority).
|
|
50
|
-
if (frameStrings.some((s) => EVENT_PATTERNS.some((p) => p.test(s)))) {
|
|
51
|
-
return 'event';
|
|
52
|
-
}
|
|
53
|
-
// Then async effect patterns.
|
|
54
|
-
if (frameStrings.some((s) => EFFECT_PATTERNS.some((p) => p.test(s)))) {
|
|
55
|
-
return 'effect';
|
|
56
|
-
}
|
|
57
|
-
// If any frame originates from a .svelte file but didn't match event/effect,
|
|
58
|
-
// the error most likely occurred during the synchronous render phase.
|
|
59
|
-
const hasSvelteFrame = frames.some((f) => f.fileName?.includes('.svelte'));
|
|
60
|
-
if (hasSvelteFrame) {
|
|
61
|
-
return 'render';
|
|
62
|
-
}
|
|
63
|
-
return 'unknown';
|
|
64
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function registerSvelteSdkIdentity(): void;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { flare } from '@flareapp/js';
|
|
2
|
-
import { PACKAGE_VERSION } from './version.js';
|
|
3
|
-
let registered = false;
|
|
4
|
-
export function registerSvelteSdkIdentity() {
|
|
5
|
-
if (registered)
|
|
6
|
-
return;
|
|
7
|
-
registered = true;
|
|
8
|
-
flare.setSdkInfo({ name: '@flareapp/svelte', version: PACKAGE_VERSION });
|
|
9
|
-
flare.setFramework({ name: 'Svelte' });
|
|
10
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { default as FlareErrorBoundary } from './FlareErrorBoundary.svelte';
|
|
2
|
-
export { createFlareErrorHandler, type FlareErrorHandlerOptions } from './createFlareErrorHandler.js';
|
|
3
|
-
export { __flareRegisterComponent, getComponentTreeContext } from './componentTree.js';
|
|
4
|
-
export { withFlareConfig, type WithFlareConfigOptions } from './config.js';
|
|
5
|
-
export { flarePreprocessor, type FlarePreprocessorOptions } from './preprocessor.js';
|
|
6
|
-
export type { FlareSvelteContext, SvelteErrorOrigin } from './types.js';
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { registerSvelteSdkIdentity } from './identify.js';
|
|
2
|
-
registerSvelteSdkIdentity();
|
|
3
|
-
export { default as FlareErrorBoundary } from './FlareErrorBoundary.svelte';
|
|
4
|
-
export { createFlareErrorHandler } from './createFlareErrorHandler.js';
|
|
5
|
-
export { __flareRegisterComponent, getComponentTreeContext } from './componentTree.js';
|
|
6
|
-
export { withFlareConfig } from './config.js';
|
|
7
|
-
export { flarePreprocessor } from './preprocessor.js';
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
export function flarePreprocessor(options) {
|
|
2
|
-
const exclude = options?.exclude;
|
|
3
|
-
return {
|
|
4
|
-
name: 'flare-component-tree',
|
|
5
|
-
markup({ content, filename }) {
|
|
6
|
-
if (!filename?.includes('.svelte')) {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
if (exclude?.test(filename)) {
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
const hasScript = /<script[\s>]/i.test(content);
|
|
13
|
-
if (hasScript) {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
const componentName = extractComponentName(filename);
|
|
17
|
-
const escapedFile = escapeString(filename);
|
|
18
|
-
const injection = `<script>\n` +
|
|
19
|
-
`import { __flareRegisterComponent as __flare_reg__ } from '@flareapp/svelte';\n` +
|
|
20
|
-
`const __flare_node__ = __flare_reg__('${componentName}', '${escapedFile}');\n` +
|
|
21
|
-
`</script>\n`;
|
|
22
|
-
return {
|
|
23
|
-
code: injection + content,
|
|
24
|
-
};
|
|
25
|
-
},
|
|
26
|
-
script({ content, filename, attributes }) {
|
|
27
|
-
if (!filename?.includes('.svelte')) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
if (exclude?.test(filename)) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
if (attributes.context === 'module' || attributes.module != null) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
const componentName = extractComponentName(filename);
|
|
37
|
-
const escapedFile = escapeString(filename);
|
|
38
|
-
const injection = `import { __flareRegisterComponent as __flare_reg__ } from '@flareapp/svelte';\n` +
|
|
39
|
-
`const __flare_node__ = __flare_reg__('${componentName}', '${escapedFile}');\n`;
|
|
40
|
-
return {
|
|
41
|
-
code: injection + content,
|
|
42
|
-
};
|
|
43
|
-
},
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
function extractComponentName(filename) {
|
|
47
|
-
const normalized = filename.replace(/\\/g, '/');
|
|
48
|
-
const base = normalized.split('/').pop() ?? filename;
|
|
49
|
-
return base.replace(/\.svelte$/, '');
|
|
50
|
-
}
|
|
51
|
-
function escapeString(str) {
|
|
52
|
-
return str.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
53
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "2.1.0";
|