@drakkar.software/dk-spaces-analytics-sdk 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/README.md +102 -0
- package/dist/index.d.ts +89 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/index.native.d.ts +87 -0
- package/dist/index.native.js +70 -0
- package/dist/index.native.js.map +1 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# @drakkar.software/dk-spaces-analytics-sdk
|
|
2
|
+
|
|
3
|
+
Generic telemetry client setup for dk-spaces apps — detailed error catching/upload and manually-triggered event capture, via [SunGlasses](https://github.com/Drakkar-Software/SunGlasses) wired to a Starfish transport. Not headless — ships React provider + error boundary.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @drakkar.software/dk-spaces-analytics-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Optional native peer deps (Expo / React Native only):
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx expo install @drakkar.software/sunglasses-react-native @drakkar.software/sunglasses-storage-async-storage
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Metro resolves `.native.ts`/`.native.tsx` automatically — no conditional imports needed in app code.
|
|
18
|
+
|
|
19
|
+
## Setup
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { createTelemetry, createTelemetryClient } from '@drakkar.software/dk-spaces-analytics-sdk';
|
|
23
|
+
|
|
24
|
+
// Module-level lazy singleton — safe to call capture()/captureException() before init() resolves.
|
|
25
|
+
export const telemetry = createTelemetryClient();
|
|
26
|
+
|
|
27
|
+
const client = await createTelemetry({
|
|
28
|
+
syncBaseUrl: process.env.EXPO_PUBLIC_STARFISH_URL, // base host, NOT including /v1
|
|
29
|
+
app: 'octochat',
|
|
30
|
+
environment: process.env.NODE_ENV,
|
|
31
|
+
});
|
|
32
|
+
telemetry.init(client);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Manual capture
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { captureException } from '@drakkar.software/dk-spaces-analytics-sdk';
|
|
39
|
+
|
|
40
|
+
telemetry.capture('message_sent', { threadId });
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
risky();
|
|
44
|
+
} catch (err) {
|
|
45
|
+
captureException(telemetry, err, { handled: true });
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Unhandled errors and render-phase crashes don't need `captureException` — `<TelemetryProvider>` captures those automatically.
|
|
50
|
+
|
|
51
|
+
## React wiring
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { TelemetryProvider } from '@drakkar.software/dk-spaces-analytics-sdk';
|
|
55
|
+
|
|
56
|
+
export default function App({ children }) {
|
|
57
|
+
return (
|
|
58
|
+
<TelemetryProvider client={client} fallback={<CrashScreen />}>
|
|
59
|
+
{children}
|
|
60
|
+
</TelemetryProvider>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`TelemetryProvider` composes SunGlasses' `<SunglassesProvider>` (global `error`/`unhandledrejection` handlers + console patching) with `<SunglassesGlobalErrorBoundary>` (render-phase fallback UI) — no double-capture.
|
|
66
|
+
|
|
67
|
+
Screen tracking:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { useTelemetryScreenTracking } from '@drakkar.software/dk-spaces-analytics-sdk';
|
|
71
|
+
|
|
72
|
+
useTelemetryScreenTracking(client); // History API (web) / Expo Router pathname (native)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## `TelemetryConfig`
|
|
76
|
+
|
|
77
|
+
| Field | Default | Notes |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| `syncBaseUrl` | — | Starfish base host. Must **not** include `/v1` — `StarfishClient` prepends it. |
|
|
80
|
+
| `app` | — | Embedded in the Starfish storage path. |
|
|
81
|
+
| `namespace` | `'analytics'` | Starfish namespace for the analytics silo. |
|
|
82
|
+
| `pathTemplate` | `'/push/events/{app}/{batchId}'` | Must keep the `/push/` prefix — `push()` only auto-prepends `/v1/{namespace}`. |
|
|
83
|
+
| `defaultOptIn` | `true` | Events flow immediately, no consent gate. |
|
|
84
|
+
| `debug` | `false` | Verbose console logging — never enable in production. |
|
|
85
|
+
|
|
86
|
+
## Peer dependencies
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
react >=18.0.0
|
|
90
|
+
@drakkar.software/starfish-client >=3.0.0-alpha.43
|
|
91
|
+
@drakkar.software/sunglasses-react-native >=0.14.0 (optional, native only)
|
|
92
|
+
@drakkar.software/sunglasses-storage-async-storage >=0.9.1 (optional, native only)
|
|
93
|
+
react-native >=0.73.0 (optional, native only)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## ESM only
|
|
97
|
+
|
|
98
|
+
This package ships ESM only. Requires a bundler (Vite, Metro, etc.).
|
|
99
|
+
|
|
100
|
+
## Changelog
|
|
101
|
+
|
|
102
|
+
See [CHANGELOG.md](./CHANGELOG.md).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { ISunglassesClient, CaptureExceptionOptions, EventMap, ISunglassesTypedClient } from '@drakkar.software/sunglasses-core';
|
|
2
|
+
export { CaptureExceptionOptions, ISunglassesClient, SunglassesEvent } from '@drakkar.software/sunglasses-core';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
export { useSunglasses as useTelemetry } from '@drakkar.software/sunglasses-react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Shared, platform-agnostic telemetry surface — no React, no storage/transport
|
|
8
|
+
* wiring. Re-exported by both `index.ts` (web) and `index.native.ts` (native).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Config accepted by `createTelemetry()` (web) / `createTelemetry()` (native). */
|
|
12
|
+
interface TelemetryConfig {
|
|
13
|
+
/** Starfish sync base URL, e.g. `https://sync.example.com/v1`. */
|
|
14
|
+
syncBaseUrl: string;
|
|
15
|
+
/** App/workspace identifier embedded in the Starfish storage path. Keep short and URL-safe. */
|
|
16
|
+
app: string;
|
|
17
|
+
/** Starfish namespace for the analytics silo. Default: `'analytics'`. */
|
|
18
|
+
namespace?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Starfish storage-path template. Default: `'/push/events/{app}/{batchId}'`.
|
|
21
|
+
* Must keep the `/push/` prefix — `StarfishClient.push()` does not add it, only
|
|
22
|
+
* `/v1/{namespace}` is prepended automatically.
|
|
23
|
+
*/
|
|
24
|
+
pathTemplate?: string;
|
|
25
|
+
appName?: string;
|
|
26
|
+
appVersion?: string;
|
|
27
|
+
/** Deployment environment, e.g. `'production'` | `'staging'`. */
|
|
28
|
+
environment?: string;
|
|
29
|
+
/** Default: `true` — events flow immediately with no consent gate. */
|
|
30
|
+
defaultOptIn?: boolean;
|
|
31
|
+
/** Enables verbose console logging. Never enable in production. Default: `false`. */
|
|
32
|
+
debug?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Module-level telemetry singleton factory. Every method is a safe no-op until
|
|
36
|
+
* `.init(client)` is called with the client returned by `createTelemetry()` —
|
|
37
|
+
* so call-sites can `capture()` / `captureException()` at any time, including
|
|
38
|
+
* before initialization resolves.
|
|
39
|
+
*/
|
|
40
|
+
declare function createTelemetryClient<T extends EventMap = Record<string, Record<string, unknown> | undefined>>(): ISunglassesTypedClient<T> & {
|
|
41
|
+
init(client: ISunglassesClient): void;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Manually capture a handled exception as a `$error` event (detailed error
|
|
45
|
+
* catching + upload). Thin wrapper over SunGlasses' `captureException` —
|
|
46
|
+
* defaults `handled: true`. Safe to call on a not-yet-initialized lazy client
|
|
47
|
+
* (from `createTelemetryClient()`), which silently no-ops.
|
|
48
|
+
*
|
|
49
|
+
* Unhandled errors and render-phase crashes don't need this call — they're
|
|
50
|
+
* captured automatically by `<TelemetryProvider>`.
|
|
51
|
+
*/
|
|
52
|
+
declare function captureException(client: ISunglassesClient, error: unknown, options?: CaptureExceptionOptions): void;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Build an initialized SunGlasses client wired to Starfish + `localStorage`.
|
|
56
|
+
*
|
|
57
|
+
* Pair with `createTelemetryClient()` + `.init(client)` for the module-level
|
|
58
|
+
* lazy-singleton pattern (safe to call `capture()` before this resolves).
|
|
59
|
+
*/
|
|
60
|
+
declare function createTelemetry(config: TelemetryConfig): Promise<ISunglassesClient>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Web telemetry provider — composes SunGlasses' `<SunglassesProvider>`
|
|
64
|
+
* (auto error capture + auto screen tracking) with
|
|
65
|
+
* `<SunglassesGlobalErrorBoundary>` (render-phase + fatal global error
|
|
66
|
+
* fallback UI), mirroring the pattern used in OctoChat's `app/_layout.tsx`.
|
|
67
|
+
* Mirrors `provider.native.tsx` — same props, same behavior, native swaps in
|
|
68
|
+
* `@drakkar.software/sunglasses-react-native`.
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
interface TelemetryProviderProps {
|
|
72
|
+
/** An initialized client — from `createTelemetry()` (after `.init()` on the lazy client). */
|
|
73
|
+
client: ISunglassesClient;
|
|
74
|
+
/** Rendered instead of the crashed tree on an uncaught render or fatal global error. */
|
|
75
|
+
fallback?: React.ReactNode;
|
|
76
|
+
children: React.ReactNode;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Wrap the app root. Enables automatic capture + upload of unhandled errors
|
|
80
|
+
* (global handlers + `console.error`) and renders `fallback` on a fatal
|
|
81
|
+
* crash. For manually-triggered captures, use `captureException()` or a
|
|
82
|
+
* typed `.capture()` call on the client from `createTelemetry()`.
|
|
83
|
+
*/
|
|
84
|
+
declare function TelemetryProvider({ client, fallback, children, }: TelemetryProviderProps): React.ReactElement;
|
|
85
|
+
|
|
86
|
+
/** Automatic screen-view tracking via the browser History API. */
|
|
87
|
+
declare function useTelemetryScreenTracking(client: ISunglassesClient): void;
|
|
88
|
+
|
|
89
|
+
export { type TelemetryConfig, TelemetryProvider, type TelemetryProviderProps, captureException, createTelemetry, createTelemetryClient, useTelemetryScreenTracking };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// src/telemetry.ts
|
|
2
|
+
import { SunglassesCore } from "@drakkar.software/sunglasses-core";
|
|
3
|
+
import { LocalStorageAdapter } from "@drakkar.software/sunglasses-storage-localstorage";
|
|
4
|
+
import { StarfishAnalyticsAdapter } from "@drakkar.software/sunglasses-adapter-starfish";
|
|
5
|
+
import { StarfishClient } from "@drakkar.software/starfish-client";
|
|
6
|
+
var DEFAULT_NAMESPACE = "analytics";
|
|
7
|
+
var DEFAULT_PATH_TEMPLATE = "/push/events/{app}/{batchId}";
|
|
8
|
+
async function createTelemetry(config) {
|
|
9
|
+
const syncClient = new StarfishClient({
|
|
10
|
+
baseUrl: config.syncBaseUrl,
|
|
11
|
+
namespace: config.namespace ?? DEFAULT_NAMESPACE
|
|
12
|
+
});
|
|
13
|
+
return SunglassesCore.create({
|
|
14
|
+
storage: new LocalStorageAdapter(),
|
|
15
|
+
adapters: [
|
|
16
|
+
new StarfishAnalyticsAdapter({
|
|
17
|
+
client: syncClient,
|
|
18
|
+
app: config.app,
|
|
19
|
+
pathTemplate: config.pathTemplate ?? DEFAULT_PATH_TEMPLATE
|
|
20
|
+
})
|
|
21
|
+
],
|
|
22
|
+
platform: "web",
|
|
23
|
+
appName: config.appName,
|
|
24
|
+
appVersion: config.appVersion,
|
|
25
|
+
environment: config.environment,
|
|
26
|
+
defaultOptIn: config.defaultOptIn ?? true,
|
|
27
|
+
enableSessionTracking: true,
|
|
28
|
+
debug: config.debug ?? false
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// src/events.ts
|
|
33
|
+
import {
|
|
34
|
+
createLazyClient,
|
|
35
|
+
captureException as sgCaptureException
|
|
36
|
+
} from "@drakkar.software/sunglasses-core";
|
|
37
|
+
function createTelemetryClient() {
|
|
38
|
+
return createLazyClient();
|
|
39
|
+
}
|
|
40
|
+
function captureException(client, error, options) {
|
|
41
|
+
sgCaptureException(client, error, options);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/provider.tsx
|
|
45
|
+
import React from "react";
|
|
46
|
+
import {
|
|
47
|
+
SunglassesProvider,
|
|
48
|
+
SunglassesGlobalErrorBoundary,
|
|
49
|
+
useSunglasses,
|
|
50
|
+
useScreenTracking
|
|
51
|
+
} from "@drakkar.software/sunglasses-react";
|
|
52
|
+
function TelemetryProvider({
|
|
53
|
+
client,
|
|
54
|
+
fallback,
|
|
55
|
+
children
|
|
56
|
+
}) {
|
|
57
|
+
return /* @__PURE__ */ React.createElement(SunglassesProvider, { client, autoCaptureErrors: { globalHandlers: true, console: true } }, /* @__PURE__ */ React.createElement(SunglassesGlobalErrorBoundary, { fallback, includeNonFatalGlobalErrors: true }, children));
|
|
58
|
+
}
|
|
59
|
+
function useTelemetryScreenTracking(client) {
|
|
60
|
+
useScreenTracking(client);
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
TelemetryProvider,
|
|
64
|
+
captureException,
|
|
65
|
+
createTelemetry,
|
|
66
|
+
createTelemetryClient,
|
|
67
|
+
useSunglasses as useTelemetry,
|
|
68
|
+
useTelemetryScreenTracking
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/telemetry.ts","../src/events.ts","../src/provider.tsx"],"sourcesContent":["/**\n * Web telemetry client factory — SunGlasses core wired to a Starfish\n * event-push transport and `localStorage` persistence. Mirrors\n * `telemetry.native.ts` (native swaps in `AsyncStorage`) — storage is the\n * only real web/native difference; everything else is shared.\n */\nimport { SunglassesCore } from '@drakkar.software/sunglasses-core';\nimport type { ISunglassesClient } from '@drakkar.software/sunglasses-core';\nimport { LocalStorageAdapter } from '@drakkar.software/sunglasses-storage-localstorage';\nimport { StarfishAnalyticsAdapter } from '@drakkar.software/sunglasses-adapter-starfish';\nimport { StarfishClient } from '@drakkar.software/starfish-client';\nimport type { TelemetryConfig } from './events.js';\n\nconst DEFAULT_NAMESPACE = 'analytics';\n// StarfishClient.push() does NOT add the /push/ prefix; only /v1/{namespace} is\n// prepended by applyNamespace(). Keep /push/ explicit to reach the events collection.\nconst DEFAULT_PATH_TEMPLATE = '/push/events/{app}/{batchId}';\n\n/**\n * Build an initialized SunGlasses client wired to Starfish + `localStorage`.\n *\n * Pair with `createTelemetryClient()` + `.init(client)` for the module-level\n * lazy-singleton pattern (safe to call `capture()` before this resolves).\n */\nexport async function createTelemetry(config: TelemetryConfig): Promise<ISunglassesClient> {\n const syncClient = new StarfishClient({\n baseUrl: config.syncBaseUrl,\n namespace: config.namespace ?? DEFAULT_NAMESPACE,\n });\n\n return SunglassesCore.create({\n storage: new LocalStorageAdapter(),\n adapters: [\n new StarfishAnalyticsAdapter({\n client: syncClient,\n app: config.app,\n pathTemplate: config.pathTemplate ?? DEFAULT_PATH_TEMPLATE,\n }),\n ],\n platform: 'web',\n appName: config.appName,\n appVersion: config.appVersion,\n environment: config.environment,\n defaultOptIn: config.defaultOptIn ?? true,\n enableSessionTracking: true,\n debug: config.debug ?? false,\n });\n}\n","/**\n * Shared, platform-agnostic telemetry surface — no React, no storage/transport\n * wiring. Re-exported by both `index.ts` (web) and `index.native.ts` (native).\n */\nimport {\n createLazyClient,\n captureException as sgCaptureException,\n type CaptureExceptionOptions,\n type ISunglassesClient,\n type ISunglassesTypedClient,\n type EventMap,\n type SunglassesEvent,\n} from '@drakkar.software/sunglasses-core';\n\nexport type { CaptureExceptionOptions, ISunglassesClient, SunglassesEvent };\n\n/** Config accepted by `createTelemetry()` (web) / `createTelemetry()` (native). */\nexport interface TelemetryConfig {\n /** Starfish sync base URL, e.g. `https://sync.example.com/v1`. */\n syncBaseUrl: string;\n /** App/workspace identifier embedded in the Starfish storage path. Keep short and URL-safe. */\n app: string;\n /** Starfish namespace for the analytics silo. Default: `'analytics'`. */\n namespace?: string;\n /**\n * Starfish storage-path template. Default: `'/push/events/{app}/{batchId}'`.\n * Must keep the `/push/` prefix — `StarfishClient.push()` does not add it, only\n * `/v1/{namespace}` is prepended automatically.\n */\n pathTemplate?: string;\n appName?: string;\n appVersion?: string;\n /** Deployment environment, e.g. `'production'` | `'staging'`. */\n environment?: string;\n /** Default: `true` — events flow immediately with no consent gate. */\n defaultOptIn?: boolean;\n /** Enables verbose console logging. Never enable in production. Default: `false`. */\n debug?: boolean;\n}\n\n/**\n * Module-level telemetry singleton factory. Every method is a safe no-op until\n * `.init(client)` is called with the client returned by `createTelemetry()` —\n * so call-sites can `capture()` / `captureException()` at any time, including\n * before initialization resolves.\n */\nexport function createTelemetryClient<\n T extends EventMap = Record<string, Record<string, unknown> | undefined>,\n>(): ISunglassesTypedClient<T> & { init(client: ISunglassesClient): void } {\n return createLazyClient<T>();\n}\n\n/**\n * Manually capture a handled exception as a `$error` event (detailed error\n * catching + upload). Thin wrapper over SunGlasses' `captureException` —\n * defaults `handled: true`. Safe to call on a not-yet-initialized lazy client\n * (from `createTelemetryClient()`), which silently no-ops.\n *\n * Unhandled errors and render-phase crashes don't need this call — they're\n * captured automatically by `<TelemetryProvider>`.\n */\nexport function captureException(\n client: ISunglassesClient,\n error: unknown,\n options?: CaptureExceptionOptions,\n): void {\n sgCaptureException(client, error, options);\n}\n","/**\n * Web telemetry provider — composes SunGlasses' `<SunglassesProvider>`\n * (auto error capture + auto screen tracking) with\n * `<SunglassesGlobalErrorBoundary>` (render-phase + fatal global error\n * fallback UI), mirroring the pattern used in OctoChat's `app/_layout.tsx`.\n * Mirrors `provider.native.tsx` — same props, same behavior, native swaps in\n * `@drakkar.software/sunglasses-react-native`.\n */\nimport React from 'react';\nimport {\n SunglassesProvider,\n SunglassesGlobalErrorBoundary,\n useSunglasses,\n useScreenTracking,\n} from '@drakkar.software/sunglasses-react';\nimport type { ISunglassesClient } from '@drakkar.software/sunglasses-core';\n\nexport interface TelemetryProviderProps {\n /** An initialized client — from `createTelemetry()` (after `.init()` on the lazy client). */\n client: ISunglassesClient;\n /** Rendered instead of the crashed tree on an uncaught render or fatal global error. */\n fallback?: React.ReactNode;\n children: React.ReactNode;\n}\n\n/**\n * Wrap the app root. Enables automatic capture + upload of unhandled errors\n * (global handlers + `console.error`) and renders `fallback` on a fatal\n * crash. For manually-triggered captures, use `captureException()` or a\n * typed `.capture()` call on the client from `createTelemetry()`.\n */\nexport function TelemetryProvider({\n client,\n fallback,\n children,\n}: TelemetryProviderProps): React.ReactElement {\n return (\n <SunglassesProvider client={client} autoCaptureErrors={{ globalHandlers: true, console: true }}>\n <SunglassesGlobalErrorBoundary fallback={fallback} includeNonFatalGlobalErrors>\n {children}\n </SunglassesGlobalErrorBoundary>\n </SunglassesProvider>\n );\n}\n\n/** Access the telemetry client provided by the nearest `<TelemetryProvider>`. */\nexport { useSunglasses as useTelemetry };\n\n/** Automatic screen-view tracking via the browser History API. */\nexport function useTelemetryScreenTracking(client: ISunglassesClient): void {\n useScreenTracking(client);\n}\n"],"mappings":";AAMA,SAAS,sBAAsB;AAE/B,SAAS,2BAA2B;AACpC,SAAS,gCAAgC;AACzC,SAAS,sBAAsB;AAG/B,IAAM,oBAAoB;AAG1B,IAAM,wBAAwB;AAQ9B,eAAsB,gBAAgB,QAAqD;AACzF,QAAM,aAAa,IAAI,eAAe;AAAA,IACpC,SAAS,OAAO;AAAA,IAChB,WAAW,OAAO,aAAa;AAAA,EACjC,CAAC;AAED,SAAO,eAAe,OAAO;AAAA,IAC3B,SAAS,IAAI,oBAAoB;AAAA,IACjC,UAAU;AAAA,MACR,IAAI,yBAAyB;AAAA,QAC3B,QAAQ;AAAA,QACR,KAAK,OAAO;AAAA,QACZ,cAAc,OAAO,gBAAgB;AAAA,MACvC,CAAC;AAAA,IACH;AAAA,IACA,UAAU;AAAA,IACV,SAAS,OAAO;AAAA,IAChB,YAAY,OAAO;AAAA,IACnB,aAAa,OAAO;AAAA,IACpB,cAAc,OAAO,gBAAgB;AAAA,IACrC,uBAAuB;AAAA,IACvB,OAAO,OAAO,SAAS;AAAA,EACzB,CAAC;AACH;;;AC3CA;AAAA,EACE;AAAA,EACA,oBAAoB;AAAA,OAMf;AAkCA,SAAS,wBAE2D;AACzE,SAAO,iBAAoB;AAC7B;AAWO,SAAS,iBACd,QACA,OACA,SACM;AACN,qBAAmB,QAAQ,OAAO,OAAO;AAC3C;;;AC3DA,OAAO,WAAW;AAClB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAiBA,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACF,GAA+C;AAC7C,SACE,oCAAC,sBAAmB,QAAgB,mBAAmB,EAAE,gBAAgB,MAAM,SAAS,KAAK,KAC3F,oCAAC,iCAA8B,UAAoB,6BAA2B,QAC3E,QACH,CACF;AAEJ;AAMO,SAAS,2BAA2B,QAAiC;AAC1E,oBAAkB,MAAM;AAC1B;","names":[]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ISunglassesClient, CaptureExceptionOptions, EventMap, ISunglassesTypedClient } from '@drakkar.software/sunglasses-core';
|
|
2
|
+
export { CaptureExceptionOptions, ISunglassesClient, SunglassesEvent } from '@drakkar.software/sunglasses-core';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
export { useSunglasses as useTelemetry } from '@drakkar.software/sunglasses-react-native';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Shared, platform-agnostic telemetry surface — no React, no storage/transport
|
|
8
|
+
* wiring. Re-exported by both `index.ts` (web) and `index.native.ts` (native).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Config accepted by `createTelemetry()` (web) / `createTelemetry()` (native). */
|
|
12
|
+
interface TelemetryConfig {
|
|
13
|
+
/** Starfish sync base URL, e.g. `https://sync.example.com/v1`. */
|
|
14
|
+
syncBaseUrl: string;
|
|
15
|
+
/** App/workspace identifier embedded in the Starfish storage path. Keep short and URL-safe. */
|
|
16
|
+
app: string;
|
|
17
|
+
/** Starfish namespace for the analytics silo. Default: `'analytics'`. */
|
|
18
|
+
namespace?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Starfish storage-path template. Default: `'/push/events/{app}/{batchId}'`.
|
|
21
|
+
* Must keep the `/push/` prefix — `StarfishClient.push()` does not add it, only
|
|
22
|
+
* `/v1/{namespace}` is prepended automatically.
|
|
23
|
+
*/
|
|
24
|
+
pathTemplate?: string;
|
|
25
|
+
appName?: string;
|
|
26
|
+
appVersion?: string;
|
|
27
|
+
/** Deployment environment, e.g. `'production'` | `'staging'`. */
|
|
28
|
+
environment?: string;
|
|
29
|
+
/** Default: `true` — events flow immediately with no consent gate. */
|
|
30
|
+
defaultOptIn?: boolean;
|
|
31
|
+
/** Enables verbose console logging. Never enable in production. Default: `false`. */
|
|
32
|
+
debug?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Module-level telemetry singleton factory. Every method is a safe no-op until
|
|
36
|
+
* `.init(client)` is called with the client returned by `createTelemetry()` —
|
|
37
|
+
* so call-sites can `capture()` / `captureException()` at any time, including
|
|
38
|
+
* before initialization resolves.
|
|
39
|
+
*/
|
|
40
|
+
declare function createTelemetryClient<T extends EventMap = Record<string, Record<string, unknown> | undefined>>(): ISunglassesTypedClient<T> & {
|
|
41
|
+
init(client: ISunglassesClient): void;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Manually capture a handled exception as a `$error` event (detailed error
|
|
45
|
+
* catching + upload). Thin wrapper over SunGlasses' `captureException` —
|
|
46
|
+
* defaults `handled: true`. Safe to call on a not-yet-initialized lazy client
|
|
47
|
+
* (from `createTelemetryClient()`), which silently no-ops.
|
|
48
|
+
*
|
|
49
|
+
* Unhandled errors and render-phase crashes don't need this call — they're
|
|
50
|
+
* captured automatically by `<TelemetryProvider>`.
|
|
51
|
+
*/
|
|
52
|
+
declare function captureException(client: ISunglassesClient, error: unknown, options?: CaptureExceptionOptions): void;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Build an initialized SunGlasses client wired to Starfish + `AsyncStorage`.
|
|
56
|
+
*
|
|
57
|
+
* Pair with `createTelemetryClient()` + `.init(client)` for the module-level
|
|
58
|
+
* lazy-singleton pattern (safe to call `capture()` before this resolves).
|
|
59
|
+
*/
|
|
60
|
+
declare function createTelemetry(config: TelemetryConfig): Promise<ISunglassesClient>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Native telemetry provider. Mirrors `provider.tsx` — swaps in
|
|
64
|
+
* `@drakkar.software/sunglasses-react-native`'s provider/boundary. Screen
|
|
65
|
+
* tracking uses Expo Router's pathname instead of the History API.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
interface TelemetryProviderProps {
|
|
69
|
+
/** An initialized client — from `createTelemetry()` (after `.init()` on the lazy client). */
|
|
70
|
+
client: ISunglassesClient;
|
|
71
|
+
/** Rendered instead of the crashed tree on an uncaught render or fatal global error. */
|
|
72
|
+
fallback?: React.ReactNode;
|
|
73
|
+
children: React.ReactNode;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Wrap the app root (typically `app/_layout.tsx`). Enables automatic capture
|
|
77
|
+
* + upload of unhandled errors (global handlers + `console.error`) and
|
|
78
|
+
* renders `fallback` on a fatal crash. For manually-triggered captures, use
|
|
79
|
+
* `captureException()` or a typed `.capture()` call on the client from
|
|
80
|
+
* `createTelemetry()`.
|
|
81
|
+
*/
|
|
82
|
+
declare function TelemetryProvider({ client, fallback, children, }: TelemetryProviderProps): React.ReactElement;
|
|
83
|
+
|
|
84
|
+
/** Requires `expo-router`. Call once, inside your root `_layout.tsx`. */
|
|
85
|
+
declare function useTelemetryScreenTracking(client: ISunglassesClient): void;
|
|
86
|
+
|
|
87
|
+
export { type TelemetryConfig, TelemetryProvider, type TelemetryProviderProps, captureException, createTelemetry, createTelemetryClient, useTelemetryScreenTracking };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// src/telemetry.native.ts
|
|
2
|
+
import { SunglassesCore } from "@drakkar.software/sunglasses-core";
|
|
3
|
+
import { AsyncStorageAdapter } from "@drakkar.software/sunglasses-storage-async-storage";
|
|
4
|
+
import { StarfishAnalyticsAdapter } from "@drakkar.software/sunglasses-adapter-starfish";
|
|
5
|
+
import { StarfishClient } from "@drakkar.software/starfish-client";
|
|
6
|
+
var DEFAULT_NAMESPACE = "analytics";
|
|
7
|
+
var DEFAULT_PATH_TEMPLATE = "/push/events/{app}/{batchId}";
|
|
8
|
+
async function createTelemetry(config) {
|
|
9
|
+
const syncClient = new StarfishClient({
|
|
10
|
+
baseUrl: config.syncBaseUrl,
|
|
11
|
+
namespace: config.namespace ?? DEFAULT_NAMESPACE
|
|
12
|
+
});
|
|
13
|
+
return SunglassesCore.create({
|
|
14
|
+
storage: new AsyncStorageAdapter(),
|
|
15
|
+
adapters: [
|
|
16
|
+
new StarfishAnalyticsAdapter({
|
|
17
|
+
client: syncClient,
|
|
18
|
+
app: config.app,
|
|
19
|
+
pathTemplate: config.pathTemplate ?? DEFAULT_PATH_TEMPLATE
|
|
20
|
+
})
|
|
21
|
+
],
|
|
22
|
+
platform: "react-native",
|
|
23
|
+
appName: config.appName,
|
|
24
|
+
appVersion: config.appVersion,
|
|
25
|
+
environment: config.environment,
|
|
26
|
+
defaultOptIn: config.defaultOptIn ?? true,
|
|
27
|
+
enableSessionTracking: true,
|
|
28
|
+
debug: config.debug ?? false
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// src/events.ts
|
|
33
|
+
import {
|
|
34
|
+
createLazyClient,
|
|
35
|
+
captureException as sgCaptureException
|
|
36
|
+
} from "@drakkar.software/sunglasses-core";
|
|
37
|
+
function createTelemetryClient() {
|
|
38
|
+
return createLazyClient();
|
|
39
|
+
}
|
|
40
|
+
function captureException(client, error, options) {
|
|
41
|
+
sgCaptureException(client, error, options);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/provider.native.tsx
|
|
45
|
+
import React from "react";
|
|
46
|
+
import {
|
|
47
|
+
SunglassesProvider,
|
|
48
|
+
SunglassesGlobalErrorBoundary,
|
|
49
|
+
useSunglasses,
|
|
50
|
+
useExpoRouterScreenTracking
|
|
51
|
+
} from "@drakkar.software/sunglasses-react-native";
|
|
52
|
+
function TelemetryProvider({
|
|
53
|
+
client,
|
|
54
|
+
fallback,
|
|
55
|
+
children
|
|
56
|
+
}) {
|
|
57
|
+
return /* @__PURE__ */ React.createElement(SunglassesProvider, { client, autoCaptureErrors: { globalHandlers: true, console: true } }, /* @__PURE__ */ React.createElement(SunglassesGlobalErrorBoundary, { fallback, includeNonFatalGlobalErrors: true }, children));
|
|
58
|
+
}
|
|
59
|
+
function useTelemetryScreenTracking(client) {
|
|
60
|
+
useExpoRouterScreenTracking(client);
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
TelemetryProvider,
|
|
64
|
+
captureException,
|
|
65
|
+
createTelemetry,
|
|
66
|
+
createTelemetryClient,
|
|
67
|
+
useSunglasses as useTelemetry,
|
|
68
|
+
useTelemetryScreenTracking
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=index.native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/telemetry.native.ts","../src/events.ts","../src/provider.native.tsx"],"sourcesContent":["/**\n * Native telemetry client factory — SunGlasses core wired to a Starfish\n * event-push transport and `AsyncStorage` persistence. Mirrors `telemetry.ts`\n * (web uses `localStorage`) — storage is the only real web/native difference;\n * everything else is shared.\n */\nimport { SunglassesCore } from '@drakkar.software/sunglasses-core';\nimport type { ISunglassesClient } from '@drakkar.software/sunglasses-core';\n// @ts-ignore — optional peer dep; only present in native builds\nimport { AsyncStorageAdapter } from '@drakkar.software/sunglasses-storage-async-storage';\nimport { StarfishAnalyticsAdapter } from '@drakkar.software/sunglasses-adapter-starfish';\nimport { StarfishClient } from '@drakkar.software/starfish-client';\nimport type { TelemetryConfig } from './events.js';\n\nconst DEFAULT_NAMESPACE = 'analytics';\n// StarfishClient.push() does NOT add the /push/ prefix; only /v1/{namespace} is\n// prepended by applyNamespace(). Keep /push/ explicit to reach the events collection.\nconst DEFAULT_PATH_TEMPLATE = '/push/events/{app}/{batchId}';\n\n/**\n * Build an initialized SunGlasses client wired to Starfish + `AsyncStorage`.\n *\n * Pair with `createTelemetryClient()` + `.init(client)` for the module-level\n * lazy-singleton pattern (safe to call `capture()` before this resolves).\n */\nexport async function createTelemetry(config: TelemetryConfig): Promise<ISunglassesClient> {\n const syncClient = new StarfishClient({\n baseUrl: config.syncBaseUrl,\n namespace: config.namespace ?? DEFAULT_NAMESPACE,\n });\n\n return SunglassesCore.create({\n storage: new AsyncStorageAdapter(),\n adapters: [\n new StarfishAnalyticsAdapter({\n client: syncClient,\n app: config.app,\n pathTemplate: config.pathTemplate ?? DEFAULT_PATH_TEMPLATE,\n }),\n ],\n platform: 'react-native',\n appName: config.appName,\n appVersion: config.appVersion,\n environment: config.environment,\n defaultOptIn: config.defaultOptIn ?? true,\n enableSessionTracking: true,\n debug: config.debug ?? false,\n });\n}\n","/**\n * Shared, platform-agnostic telemetry surface — no React, no storage/transport\n * wiring. Re-exported by both `index.ts` (web) and `index.native.ts` (native).\n */\nimport {\n createLazyClient,\n captureException as sgCaptureException,\n type CaptureExceptionOptions,\n type ISunglassesClient,\n type ISunglassesTypedClient,\n type EventMap,\n type SunglassesEvent,\n} from '@drakkar.software/sunglasses-core';\n\nexport type { CaptureExceptionOptions, ISunglassesClient, SunglassesEvent };\n\n/** Config accepted by `createTelemetry()` (web) / `createTelemetry()` (native). */\nexport interface TelemetryConfig {\n /** Starfish sync base URL, e.g. `https://sync.example.com/v1`. */\n syncBaseUrl: string;\n /** App/workspace identifier embedded in the Starfish storage path. Keep short and URL-safe. */\n app: string;\n /** Starfish namespace for the analytics silo. Default: `'analytics'`. */\n namespace?: string;\n /**\n * Starfish storage-path template. Default: `'/push/events/{app}/{batchId}'`.\n * Must keep the `/push/` prefix — `StarfishClient.push()` does not add it, only\n * `/v1/{namespace}` is prepended automatically.\n */\n pathTemplate?: string;\n appName?: string;\n appVersion?: string;\n /** Deployment environment, e.g. `'production'` | `'staging'`. */\n environment?: string;\n /** Default: `true` — events flow immediately with no consent gate. */\n defaultOptIn?: boolean;\n /** Enables verbose console logging. Never enable in production. Default: `false`. */\n debug?: boolean;\n}\n\n/**\n * Module-level telemetry singleton factory. Every method is a safe no-op until\n * `.init(client)` is called with the client returned by `createTelemetry()` —\n * so call-sites can `capture()` / `captureException()` at any time, including\n * before initialization resolves.\n */\nexport function createTelemetryClient<\n T extends EventMap = Record<string, Record<string, unknown> | undefined>,\n>(): ISunglassesTypedClient<T> & { init(client: ISunglassesClient): void } {\n return createLazyClient<T>();\n}\n\n/**\n * Manually capture a handled exception as a `$error` event (detailed error\n * catching + upload). Thin wrapper over SunGlasses' `captureException` —\n * defaults `handled: true`. Safe to call on a not-yet-initialized lazy client\n * (from `createTelemetryClient()`), which silently no-ops.\n *\n * Unhandled errors and render-phase crashes don't need this call — they're\n * captured automatically by `<TelemetryProvider>`.\n */\nexport function captureException(\n client: ISunglassesClient,\n error: unknown,\n options?: CaptureExceptionOptions,\n): void {\n sgCaptureException(client, error, options);\n}\n","/**\n * Native telemetry provider. Mirrors `provider.tsx` — swaps in\n * `@drakkar.software/sunglasses-react-native`'s provider/boundary. Screen\n * tracking uses Expo Router's pathname instead of the History API.\n */\nimport React from 'react';\nimport {\n SunglassesProvider,\n SunglassesGlobalErrorBoundary,\n useSunglasses,\n useExpoRouterScreenTracking,\n} from '@drakkar.software/sunglasses-react-native';\nimport type { ISunglassesClient } from '@drakkar.software/sunglasses-core';\n\nexport interface TelemetryProviderProps {\n /** An initialized client — from `createTelemetry()` (after `.init()` on the lazy client). */\n client: ISunglassesClient;\n /** Rendered instead of the crashed tree on an uncaught render or fatal global error. */\n fallback?: React.ReactNode;\n children: React.ReactNode;\n}\n\n/**\n * Wrap the app root (typically `app/_layout.tsx`). Enables automatic capture\n * + upload of unhandled errors (global handlers + `console.error`) and\n * renders `fallback` on a fatal crash. For manually-triggered captures, use\n * `captureException()` or a typed `.capture()` call on the client from\n * `createTelemetry()`.\n */\nexport function TelemetryProvider({\n client,\n fallback,\n children,\n}: TelemetryProviderProps): React.ReactElement {\n return (\n <SunglassesProvider client={client} autoCaptureErrors={{ globalHandlers: true, console: true }}>\n <SunglassesGlobalErrorBoundary fallback={fallback} includeNonFatalGlobalErrors>\n {children}\n </SunglassesGlobalErrorBoundary>\n </SunglassesProvider>\n );\n}\n\n/** Access the telemetry client provided by the nearest `<TelemetryProvider>`. */\nexport { useSunglasses as useTelemetry };\n\n/** Requires `expo-router`. Call once, inside your root `_layout.tsx`. */\nexport function useTelemetryScreenTracking(client: ISunglassesClient): void {\n useExpoRouterScreenTracking(client);\n}\n"],"mappings":";AAMA,SAAS,sBAAsB;AAG/B,SAAS,2BAA2B;AACpC,SAAS,gCAAgC;AACzC,SAAS,sBAAsB;AAG/B,IAAM,oBAAoB;AAG1B,IAAM,wBAAwB;AAQ9B,eAAsB,gBAAgB,QAAqD;AACzF,QAAM,aAAa,IAAI,eAAe;AAAA,IACpC,SAAS,OAAO;AAAA,IAChB,WAAW,OAAO,aAAa;AAAA,EACjC,CAAC;AAED,SAAO,eAAe,OAAO;AAAA,IAC3B,SAAS,IAAI,oBAAoB;AAAA,IACjC,UAAU;AAAA,MACR,IAAI,yBAAyB;AAAA,QAC3B,QAAQ;AAAA,QACR,KAAK,OAAO;AAAA,QACZ,cAAc,OAAO,gBAAgB;AAAA,MACvC,CAAC;AAAA,IACH;AAAA,IACA,UAAU;AAAA,IACV,SAAS,OAAO;AAAA,IAChB,YAAY,OAAO;AAAA,IACnB,aAAa,OAAO;AAAA,IACpB,cAAc,OAAO,gBAAgB;AAAA,IACrC,uBAAuB;AAAA,IACvB,OAAO,OAAO,SAAS;AAAA,EACzB,CAAC;AACH;;;AC5CA;AAAA,EACE;AAAA,EACA,oBAAoB;AAAA,OAMf;AAkCA,SAAS,wBAE2D;AACzE,SAAO,iBAAoB;AAC7B;AAWO,SAAS,iBACd,QACA,OACA,SACM;AACN,qBAAmB,QAAQ,OAAO,OAAO;AAC3C;;;AC9DA,OAAO,WAAW;AAClB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAkBA,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACF,GAA+C;AAC7C,SACE,oCAAC,sBAAmB,QAAgB,mBAAmB,EAAE,gBAAgB,MAAM,SAAS,KAAK,KAC3F,oCAAC,iCAA8B,UAAoB,6BAA2B,QAC3E,QACH,CACF;AAEJ;AAMO,SAAS,2BAA2B,QAAiC;AAC1E,8BAA4B,MAAM;AACpC;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@drakkar.software/dk-spaces-analytics-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Generic telemetry client setup for dk-spaces apps — detailed error catching/upload and manually-triggered event capture, via SunGlasses wired to a Starfish transport.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"react-native": {
|
|
13
|
+
"types": "./dist/index.native.d.ts",
|
|
14
|
+
"import": "./dist/index.native.js"
|
|
15
|
+
},
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@drakkar.software/sunglasses-core": "^0.14.0",
|
|
22
|
+
"@drakkar.software/sunglasses-adapter-starfish": "^0.9.2",
|
|
23
|
+
"@drakkar.software/sunglasses-storage-localstorage": "^0.9.1",
|
|
24
|
+
"@drakkar.software/sunglasses-react": "^0.14.0"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"react": ">=18.0.0",
|
|
28
|
+
"@drakkar.software/starfish-client": ">=3.0.0-alpha.43",
|
|
29
|
+
"@drakkar.software/sunglasses-react-native": ">=0.14.0",
|
|
30
|
+
"@drakkar.software/sunglasses-storage-async-storage": ">=0.9.1",
|
|
31
|
+
"react-native": ">=0.73.0"
|
|
32
|
+
},
|
|
33
|
+
"peerDependenciesMeta": {
|
|
34
|
+
"@drakkar.software/sunglasses-react-native": {
|
|
35
|
+
"optional": true
|
|
36
|
+
},
|
|
37
|
+
"@drakkar.software/sunglasses-storage-async-storage": {
|
|
38
|
+
"optional": true
|
|
39
|
+
},
|
|
40
|
+
"react-native": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@drakkar.software/starfish-client": "3.0.0-alpha.65",
|
|
46
|
+
"@drakkar.software/sunglasses-react-native": "0.14.0",
|
|
47
|
+
"@drakkar.software/sunglasses-storage-async-storage": "0.9.1",
|
|
48
|
+
"@types/node": "^22.0.0",
|
|
49
|
+
"@types/react": "^18.0.0",
|
|
50
|
+
"react": "19.2.7",
|
|
51
|
+
"tsup": "^8.3.0",
|
|
52
|
+
"typescript": "~6.0.3"
|
|
53
|
+
},
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsup",
|
|
59
|
+
"typecheck": "tsc --noEmit"
|
|
60
|
+
}
|
|
61
|
+
}
|