@goliapkg/sentori-solid 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +47 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +84 -0
- package/lib/index.js.map +1 -0
- package/package.json +60 -0
- package/src/__tests__/smoke.test.ts +33 -0
- package/src/index.ts +101 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 45 sub-D — SolidJS adapter for Sentori.
|
|
3
|
+
*
|
|
4
|
+
* import { initSentori, captureException } from '@goliapkg/sentori-solid'
|
|
5
|
+
*
|
|
6
|
+
* initSentori({ token: 'st_pk_...', release: 'myapp@1.0.0' })
|
|
7
|
+
*
|
|
8
|
+
* What's in this package vs `@goliapkg/sentori-javascript`:
|
|
9
|
+
*
|
|
10
|
+
* - `initSentori` / `captureException` re-exported as-is (no
|
|
11
|
+
* Solid-specific transform needed; Solid uses ES2020 modules
|
|
12
|
+
* and the JS SDK is framework-agnostic)
|
|
13
|
+
* - `wrapWithBoundary(props)` — adapter that hands an error
|
|
14
|
+
* callback to Solid's built-in `<ErrorBoundary>` so anything
|
|
15
|
+
* thrown in render lands in Sentori. Apps import Solid's
|
|
16
|
+
* `<ErrorBoundary>` directly; this is just the `onCatch`
|
|
17
|
+
* callback they pass.
|
|
18
|
+
* - `traceSolidRouter(routerLocation)` — pass `useLocation()`
|
|
19
|
+
* from `@solidjs/router` and we open a `solid.navigation` span
|
|
20
|
+
* per route. SDK consumers wire it inside a `createEffect`.
|
|
21
|
+
*
|
|
22
|
+
* SolidJS is a small enough framework that we deliberately don't
|
|
23
|
+
* ship a giant API. Most users will just need `initSentori` +
|
|
24
|
+
* `captureException`.
|
|
25
|
+
*/
|
|
26
|
+
import { type InitOptions } from '@goliapkg/sentori-javascript';
|
|
27
|
+
export type SentoriSolidOptions = InitOptions;
|
|
28
|
+
export declare function initSentori(options: SentoriSolidOptions): void;
|
|
29
|
+
/**
|
|
30
|
+
* Callback to wire into Solid's built-in `<ErrorBoundary onCatch={...}>`.
|
|
31
|
+
*
|
|
32
|
+
* import { ErrorBoundary } from 'solid-js'
|
|
33
|
+
* import { sentoriOnCatch } from '@goliapkg/sentori-solid'
|
|
34
|
+
*
|
|
35
|
+
* <ErrorBoundary fallback={...} onCatch={sentoriOnCatch}>
|
|
36
|
+
* <App />
|
|
37
|
+
* </ErrorBoundary>
|
|
38
|
+
*
|
|
39
|
+
* (Solid's `<ErrorBoundary>` exposes the onCatch hook via
|
|
40
|
+
* `solidjs.ErrorBoundary`; the callback fires on `Error` thrown in
|
|
41
|
+
* render / lifecycle and is the SolidJS-idiomatic place to forward
|
|
42
|
+
* into a monitoring service.)
|
|
43
|
+
*/
|
|
44
|
+
export declare function sentoriOnCatch(err: unknown): void;
|
|
45
|
+
export declare function traceSolidRouter(pathname: string): void;
|
|
46
|
+
export { addBreadcrumb, captureException, captureException as captureError, captureStep, getUser, setUser, } from '@goliapkg/sentori-javascript';
|
|
47
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAA;AAErC,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAA;AAE7C,wBAAgB,WAAW,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAE9D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAGjD;AAeD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAkBvD;AAED,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,IAAI,YAAY,EAChC,WAAW,EACX,OAAO,EACP,OAAO,GACR,MAAM,8BAA8B,CAAA"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 45 sub-D — SolidJS adapter for Sentori.
|
|
3
|
+
*
|
|
4
|
+
* import { initSentori, captureException } from '@goliapkg/sentori-solid'
|
|
5
|
+
*
|
|
6
|
+
* initSentori({ token: 'st_pk_...', release: 'myapp@1.0.0' })
|
|
7
|
+
*
|
|
8
|
+
* What's in this package vs `@goliapkg/sentori-javascript`:
|
|
9
|
+
*
|
|
10
|
+
* - `initSentori` / `captureException` re-exported as-is (no
|
|
11
|
+
* Solid-specific transform needed; Solid uses ES2020 modules
|
|
12
|
+
* and the JS SDK is framework-agnostic)
|
|
13
|
+
* - `wrapWithBoundary(props)` — adapter that hands an error
|
|
14
|
+
* callback to Solid's built-in `<ErrorBoundary>` so anything
|
|
15
|
+
* thrown in render lands in Sentori. Apps import Solid's
|
|
16
|
+
* `<ErrorBoundary>` directly; this is just the `onCatch`
|
|
17
|
+
* callback they pass.
|
|
18
|
+
* - `traceSolidRouter(routerLocation)` — pass `useLocation()`
|
|
19
|
+
* from `@solidjs/router` and we open a `solid.navigation` span
|
|
20
|
+
* per route. SDK consumers wire it inside a `createEffect`.
|
|
21
|
+
*
|
|
22
|
+
* SolidJS is a small enough framework that we deliberately don't
|
|
23
|
+
* ship a giant API. Most users will just need `initSentori` +
|
|
24
|
+
* `captureException`.
|
|
25
|
+
*/
|
|
26
|
+
import { setActiveSpan, startSpan } from '@goliapkg/sentori-core';
|
|
27
|
+
import { captureException as captureExceptionJs, captureStep, initSentori as initSentoriJs, } from '@goliapkg/sentori-javascript';
|
|
28
|
+
export function initSentori(options) {
|
|
29
|
+
initSentoriJs(options);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Callback to wire into Solid's built-in `<ErrorBoundary onCatch={...}>`.
|
|
33
|
+
*
|
|
34
|
+
* import { ErrorBoundary } from 'solid-js'
|
|
35
|
+
* import { sentoriOnCatch } from '@goliapkg/sentori-solid'
|
|
36
|
+
*
|
|
37
|
+
* <ErrorBoundary fallback={...} onCatch={sentoriOnCatch}>
|
|
38
|
+
* <App />
|
|
39
|
+
* </ErrorBoundary>
|
|
40
|
+
*
|
|
41
|
+
* (Solid's `<ErrorBoundary>` exposes the onCatch hook via
|
|
42
|
+
* `solidjs.ErrorBoundary`; the callback fires on `Error` thrown in
|
|
43
|
+
* render / lifecycle and is the SolidJS-idiomatic place to forward
|
|
44
|
+
* into a monitoring service.)
|
|
45
|
+
*/
|
|
46
|
+
export function sentoriOnCatch(err) {
|
|
47
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
48
|
+
captureExceptionJs(e);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Trace navigation by calling this from a `createEffect` whenever
|
|
52
|
+
* `useLocation().pathname` changes:
|
|
53
|
+
*
|
|
54
|
+
* import { useLocation } from '@solidjs/router'
|
|
55
|
+
* import { createEffect } from 'solid-js'
|
|
56
|
+
* import { traceSolidRouter } from '@goliapkg/sentori-solid'
|
|
57
|
+
*
|
|
58
|
+
* const loc = useLocation()
|
|
59
|
+
* createEffect(() => traceSolidRouter(loc.pathname))
|
|
60
|
+
*/
|
|
61
|
+
let _active = null;
|
|
62
|
+
let _lastPath = null;
|
|
63
|
+
export function traceSolidRouter(pathname) {
|
|
64
|
+
if (pathname === _lastPath)
|
|
65
|
+
return;
|
|
66
|
+
if (_active) {
|
|
67
|
+
_active.finish({ status: 'ok' });
|
|
68
|
+
_active = null;
|
|
69
|
+
}
|
|
70
|
+
const from = _lastPath ?? '/';
|
|
71
|
+
const span = startSpan('solid.navigation', {
|
|
72
|
+
name: `${from} → ${pathname}`,
|
|
73
|
+
parent: null,
|
|
74
|
+
tags: { 'nav.from': from, 'nav.to': pathname },
|
|
75
|
+
});
|
|
76
|
+
_active = span;
|
|
77
|
+
setActiveSpan(span);
|
|
78
|
+
captureStep(`route:${pathname}`, {
|
|
79
|
+
breadcrumb: { type: 'navigation', message: `${from} → ${pathname}` },
|
|
80
|
+
});
|
|
81
|
+
_lastPath = pathname;
|
|
82
|
+
}
|
|
83
|
+
export { addBreadcrumb, captureException, captureException as captureError, captureStep, getUser, setUser, } from '@goliapkg/sentori-javascript';
|
|
84
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAmB,MAAM,wBAAwB,CAAA;AAClF,OAAO,EACL,gBAAgB,IAAI,kBAAkB,EACtC,WAAW,EACX,WAAW,IAAI,aAAa,GAE7B,MAAM,8BAA8B,CAAA;AAIrC,MAAM,UAAU,WAAW,CAAC,OAA4B;IACtD,aAAa,CAAC,OAAO,CAAC,CAAA;AACxB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,MAAM,CAAC,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IAC7D,kBAAkB,CAAC,CAAC,CAAC,CAAA;AACvB,CAAC;AAED;;;;;;;;;;GAUG;AACH,IAAI,OAAO,GAAsB,IAAI,CAAA;AACrC,IAAI,SAAS,GAAkB,IAAI,CAAA;AACnC,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAM;IAClC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QAChC,OAAO,GAAG,IAAI,CAAA;IAChB,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,IAAI,GAAG,CAAA;IAC7B,MAAM,IAAI,GAAG,SAAS,CAAC,kBAAkB,EAAE;QACzC,IAAI,EAAE,GAAG,IAAI,MAAM,QAAQ,EAAE;QAC7B,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE;KAC/C,CAAC,CAAA;IACF,OAAO,GAAG,IAAI,CAAA;IACd,aAAa,CAAC,IAAI,CAAC,CAAA;IACnB,WAAW,CAAC,SAAS,QAAQ,EAAE,EAAE;QAC/B,UAAU,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,IAAI,MAAM,QAAQ,EAAE,EAAE;KACrE,CAAC,CAAA;IACF,SAAS,GAAG,QAAQ,CAAA;AACtB,CAAC;AAED,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,gBAAgB,IAAI,YAAY,EAChC,WAAW,EACX,OAAO,EACP,OAAO,GACR,MAAM,8BAA8B,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@goliapkg/sentori-solid",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SolidJS adapter for Sentori — ErrorBoundary helper, solid-router navigation tracing.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://sentori.golia.jp",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/goliajp/sentori.git",
|
|
10
|
+
"directory": "sdk/solid"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/goliajp/sentori/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"sentori",
|
|
17
|
+
"solid",
|
|
18
|
+
"solidjs",
|
|
19
|
+
"error-tracking"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "./lib/index.js",
|
|
23
|
+
"types": "./lib/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./lib/index.d.ts",
|
|
27
|
+
"default": "./lib/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"lib/",
|
|
32
|
+
"src/",
|
|
33
|
+
"README.md"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc -p tsconfig.json",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"test": "bun test",
|
|
39
|
+
"prepack": "bun run build"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"solid-js": ">=1.8"
|
|
43
|
+
},
|
|
44
|
+
"peerDependenciesMeta": {
|
|
45
|
+
"solid-js": {
|
|
46
|
+
"optional": true
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@goliapkg/sentori-core": "0.6.0",
|
|
51
|
+
"@goliapkg/sentori-javascript": "0.4.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/bun": "latest",
|
|
55
|
+
"typescript": "^5"
|
|
56
|
+
},
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
addBreadcrumb,
|
|
5
|
+
captureException,
|
|
6
|
+
initSentori,
|
|
7
|
+
sentoriOnCatch,
|
|
8
|
+
traceSolidRouter,
|
|
9
|
+
} from '../index.js'
|
|
10
|
+
|
|
11
|
+
describe('@goliapkg/sentori-solid exports', () => {
|
|
12
|
+
test('exports the SDK init + capture surface', () => {
|
|
13
|
+
expect(typeof initSentori).toBe('function')
|
|
14
|
+
expect(typeof captureException).toBe('function')
|
|
15
|
+
expect(typeof addBreadcrumb).toBe('function')
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('sentoriOnCatch normalises non-Error throws', () => {
|
|
19
|
+
expect(() => {
|
|
20
|
+
sentoriOnCatch(new Error('explicit'))
|
|
21
|
+
sentoriOnCatch('strung')
|
|
22
|
+
sentoriOnCatch({ unexpected: 'shape' })
|
|
23
|
+
}).not.toThrow()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test('traceSolidRouter is idempotent across same pathname', () => {
|
|
27
|
+
expect(() => {
|
|
28
|
+
traceSolidRouter('/a')
|
|
29
|
+
traceSolidRouter('/a')
|
|
30
|
+
traceSolidRouter('/b')
|
|
31
|
+
}).not.toThrow()
|
|
32
|
+
})
|
|
33
|
+
})
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 45 sub-D — SolidJS adapter for Sentori.
|
|
3
|
+
*
|
|
4
|
+
* import { initSentori, captureException } from '@goliapkg/sentori-solid'
|
|
5
|
+
*
|
|
6
|
+
* initSentori({ token: 'st_pk_...', release: 'myapp@1.0.0' })
|
|
7
|
+
*
|
|
8
|
+
* What's in this package vs `@goliapkg/sentori-javascript`:
|
|
9
|
+
*
|
|
10
|
+
* - `initSentori` / `captureException` re-exported as-is (no
|
|
11
|
+
* Solid-specific transform needed; Solid uses ES2020 modules
|
|
12
|
+
* and the JS SDK is framework-agnostic)
|
|
13
|
+
* - `wrapWithBoundary(props)` — adapter that hands an error
|
|
14
|
+
* callback to Solid's built-in `<ErrorBoundary>` so anything
|
|
15
|
+
* thrown in render lands in Sentori. Apps import Solid's
|
|
16
|
+
* `<ErrorBoundary>` directly; this is just the `onCatch`
|
|
17
|
+
* callback they pass.
|
|
18
|
+
* - `traceSolidRouter(routerLocation)` — pass `useLocation()`
|
|
19
|
+
* from `@solidjs/router` and we open a `solid.navigation` span
|
|
20
|
+
* per route. SDK consumers wire it inside a `createEffect`.
|
|
21
|
+
*
|
|
22
|
+
* SolidJS is a small enough framework that we deliberately don't
|
|
23
|
+
* ship a giant API. Most users will just need `initSentori` +
|
|
24
|
+
* `captureException`.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { setActiveSpan, startSpan, type SpanHandle } from '@goliapkg/sentori-core'
|
|
28
|
+
import {
|
|
29
|
+
captureException as captureExceptionJs,
|
|
30
|
+
captureStep,
|
|
31
|
+
initSentori as initSentoriJs,
|
|
32
|
+
type InitOptions,
|
|
33
|
+
} from '@goliapkg/sentori-javascript'
|
|
34
|
+
|
|
35
|
+
export type SentoriSolidOptions = InitOptions
|
|
36
|
+
|
|
37
|
+
export function initSentori(options: SentoriSolidOptions): void {
|
|
38
|
+
initSentoriJs(options)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Callback to wire into Solid's built-in `<ErrorBoundary onCatch={...}>`.
|
|
43
|
+
*
|
|
44
|
+
* import { ErrorBoundary } from 'solid-js'
|
|
45
|
+
* import { sentoriOnCatch } from '@goliapkg/sentori-solid'
|
|
46
|
+
*
|
|
47
|
+
* <ErrorBoundary fallback={...} onCatch={sentoriOnCatch}>
|
|
48
|
+
* <App />
|
|
49
|
+
* </ErrorBoundary>
|
|
50
|
+
*
|
|
51
|
+
* (Solid's `<ErrorBoundary>` exposes the onCatch hook via
|
|
52
|
+
* `solidjs.ErrorBoundary`; the callback fires on `Error` thrown in
|
|
53
|
+
* render / lifecycle and is the SolidJS-idiomatic place to forward
|
|
54
|
+
* into a monitoring service.)
|
|
55
|
+
*/
|
|
56
|
+
export function sentoriOnCatch(err: unknown): void {
|
|
57
|
+
const e = err instanceof Error ? err : new Error(String(err))
|
|
58
|
+
captureExceptionJs(e)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Trace navigation by calling this from a `createEffect` whenever
|
|
63
|
+
* `useLocation().pathname` changes:
|
|
64
|
+
*
|
|
65
|
+
* import { useLocation } from '@solidjs/router'
|
|
66
|
+
* import { createEffect } from 'solid-js'
|
|
67
|
+
* import { traceSolidRouter } from '@goliapkg/sentori-solid'
|
|
68
|
+
*
|
|
69
|
+
* const loc = useLocation()
|
|
70
|
+
* createEffect(() => traceSolidRouter(loc.pathname))
|
|
71
|
+
*/
|
|
72
|
+
let _active: SpanHandle | null = null
|
|
73
|
+
let _lastPath: null | string = null
|
|
74
|
+
export function traceSolidRouter(pathname: string): void {
|
|
75
|
+
if (pathname === _lastPath) return
|
|
76
|
+
if (_active) {
|
|
77
|
+
_active.finish({ status: 'ok' })
|
|
78
|
+
_active = null
|
|
79
|
+
}
|
|
80
|
+
const from = _lastPath ?? '/'
|
|
81
|
+
const span = startSpan('solid.navigation', {
|
|
82
|
+
name: `${from} → ${pathname}`,
|
|
83
|
+
parent: null,
|
|
84
|
+
tags: { 'nav.from': from, 'nav.to': pathname },
|
|
85
|
+
})
|
|
86
|
+
_active = span
|
|
87
|
+
setActiveSpan(span)
|
|
88
|
+
captureStep(`route:${pathname}`, {
|
|
89
|
+
breadcrumb: { type: 'navigation', message: `${from} → ${pathname}` },
|
|
90
|
+
})
|
|
91
|
+
_lastPath = pathname
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export {
|
|
95
|
+
addBreadcrumb,
|
|
96
|
+
captureException,
|
|
97
|
+
captureException as captureError,
|
|
98
|
+
captureStep,
|
|
99
|
+
getUser,
|
|
100
|
+
setUser,
|
|
101
|
+
} from '@goliapkg/sentori-javascript'
|