@symbiote-native/app-metrics 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +183 -2
- package/build/angular/app-metrics-root.d.ts +5 -0
- package/build/angular/app-metrics-root.js +62 -0
- package/build/angular/index.d.ts +3 -0
- package/build/angular/index.js +5 -0
- package/build/angular/inject-network-request-observer.d.ts +5 -0
- package/build/angular/inject-network-request-observer.js +7 -0
- package/build/core/app-metrics.d.ts +24 -0
- package/build/core/app-metrics.js +47 -0
- package/build/core/index.d.ts +5 -0
- package/build/core/index.js +6 -0
- package/build/core/install-error-handler.d.ts +2 -0
- package/build/core/install-error-handler.js +45 -0
- package/build/core/native-module.d.ts +19 -0
- package/build/core/native-module.js +3 -0
- package/build/core/network-request-observer-lifecycle.d.ts +8 -0
- package/build/core/network-request-observer-lifecycle.js +19 -0
- package/build/core/network-request-observer-subscription.d.ts +15 -0
- package/build/core/network-request-observer-subscription.js +22 -0
- package/build/core/network-request-observer.d.ts +7 -0
- package/build/core/network-request-observer.js +1 -0
- package/build/core/report-caught-error.d.ts +2 -0
- package/build/core/report-caught-error.js +20 -0
- package/build/core/session.d.ts +12 -0
- package/build/core/session.js +1 -0
- package/build/core/types.d.ts +168 -0
- package/build/core/types.js +3 -0
- package/build/react/app-metrics-error-boundary.d.ts +26 -0
- package/build/react/app-metrics-error-boundary.js +28 -0
- package/build/react/app-metrics-root.d.ts +12 -0
- package/build/react/app-metrics-root.js +24 -0
- package/build/react/index.d.ts +4 -0
- package/build/react/index.js +4 -0
- package/build/react/use-network-request-observer.d.ts +5 -0
- package/build/react/use-network-request-observer.js +23 -0
- package/build/solid/app-metrics-error-boundary.d.ts +15 -0
- package/build/solid/app-metrics-error-boundary.js +17 -0
- package/build/solid/app-metrics-root.d.ts +9 -0
- package/build/solid/app-metrics-root.js +18 -0
- package/build/solid/index.d.ts +4 -0
- package/build/solid/index.js +4 -0
- package/build/solid/use-network-request-observer.d.ts +5 -0
- package/build/solid/use-network-request-observer.js +6 -0
- package/build/svelte/AppMetricsErrorBoundary.svelte +17 -0
- package/build/svelte/AppMetricsErrorBoundary.svelte.d.ts +4 -0
- package/build/svelte/AppMetricsRoot.svelte +22 -0
- package/build/svelte/AppMetricsRoot.svelte.d.ts +4 -0
- package/build/svelte/app-metrics-error-boundary-props.d.ts +12 -0
- package/build/svelte/app-metrics-error-boundary-props.js +3 -0
- package/build/svelte/app-metrics-root-props.d.ts +9 -0
- package/build/svelte/app-metrics-root-props.js +1 -0
- package/build/svelte/index.d.ts +7 -0
- package/build/svelte/index.js +4 -0
- package/build/svelte/use-network-request-observer.svelte.d.ts +3 -0
- package/build/svelte/use-network-request-observer.svelte.js +14 -0
- package/build/vue/app-metrics-error-boundary.d.ts +14 -0
- package/build/vue/app-metrics-error-boundary.js +27 -0
- package/build/vue/app-metrics-root.d.ts +7 -0
- package/build/vue/app-metrics-root.js +15 -0
- package/build/vue/index.d.ts +4 -0
- package/build/vue/index.js +4 -0
- package/build/vue/use-network-request-observer.d.ts +5 -0
- package/build/vue/use-network-request-observer.js +6 -0
- package/build-ngc/angular/app-metrics-root.d.ts +8 -0
- package/build-ngc/angular/app-metrics-root.js +20 -0
- package/build-ngc/angular/app-metrics-root.js.map +1 -0
- package/build-ngc/angular/index.d.ts +3 -0
- package/build-ngc/angular/index.js +6 -0
- package/build-ngc/angular/index.js.map +1 -0
- package/build-ngc/angular/inject-network-request-observer.d.ts +5 -0
- package/build-ngc/angular/inject-network-request-observer.js +8 -0
- package/build-ngc/angular/inject-network-request-observer.js.map +1 -0
- package/build-ngc/core/app-metrics.d.ts +24 -0
- package/build-ngc/core/app-metrics.js +48 -0
- package/build-ngc/core/app-metrics.js.map +1 -0
- package/build-ngc/core/index.d.ts +5 -0
- package/build-ngc/core/index.js +7 -0
- package/build-ngc/core/index.js.map +1 -0
- package/build-ngc/core/install-error-handler.d.ts +2 -0
- package/build-ngc/core/install-error-handler.js +46 -0
- package/build-ngc/core/install-error-handler.js.map +1 -0
- package/build-ngc/core/native-module.d.ts +19 -0
- package/build-ngc/core/native-module.js +4 -0
- package/build-ngc/core/native-module.js.map +1 -0
- package/build-ngc/core/network-request-observer-lifecycle.d.ts +8 -0
- package/build-ngc/core/network-request-observer-lifecycle.js +20 -0
- package/build-ngc/core/network-request-observer-lifecycle.js.map +1 -0
- package/build-ngc/core/network-request-observer-subscription.d.ts +15 -0
- package/build-ngc/core/network-request-observer-subscription.js +23 -0
- package/build-ngc/core/network-request-observer-subscription.js.map +1 -0
- package/build-ngc/core/network-request-observer.d.ts +7 -0
- package/build-ngc/core/network-request-observer.js +2 -0
- package/build-ngc/core/network-request-observer.js.map +1 -0
- package/build-ngc/core/report-caught-error.d.ts +2 -0
- package/build-ngc/core/report-caught-error.js +21 -0
- package/build-ngc/core/report-caught-error.js.map +1 -0
- package/build-ngc/core/session.d.ts +12 -0
- package/build-ngc/core/session.js +2 -0
- package/build-ngc/core/session.js.map +1 -0
- package/build-ngc/core/types.d.ts +168 -0
- package/build-ngc/core/types.js +4 -0
- package/build-ngc/core/types.js.map +1 -0
- package/native-link.json +12 -0
- package/package.json +147 -3
- package/src/angular/app-metrics-root.ts +14 -0
- package/src/angular/index.ts +8 -0
- package/src/angular/inject-network-request-observer.ts +18 -0
- package/src/core/app-metrics.ts +74 -0
- package/src/core/index.ts +52 -0
- package/src/core/install-error-handler.ts +55 -0
- package/src/core/native-module.ts +36 -0
- package/src/core/network-request-observer-lifecycle.ts +37 -0
- package/src/core/network-request-observer-subscription.ts +53 -0
- package/src/core/network-request-observer.ts +15 -0
- package/src/core/report-caught-error.ts +26 -0
- package/src/core/session.ts +17 -0
- package/src/core/types.ts +200 -0
- package/src/react/app-metrics-error-boundary.tsx +67 -0
- package/src/react/app-metrics-root.tsx +53 -0
- package/src/react/index.ts +11 -0
- package/src/react/use-network-request-observer.ts +41 -0
- package/src/solid/app-metrics-error-boundary.tsx +36 -0
- package/src/solid/app-metrics-root.tsx +29 -0
- package/src/solid/index.ts +12 -0
- package/src/solid/use-network-request-observer.ts +17 -0
- package/src/svelte/AppMetricsErrorBoundary.svelte +17 -0
- package/src/svelte/AppMetricsRoot.svelte +21 -0
- package/src/svelte/app-metrics-error-boundary-props.ts +17 -0
- package/src/svelte/app-metrics-root-props.ts +10 -0
- package/src/svelte/index.ts +10 -0
- package/src/svelte/svelte-compile.test-helper.ts +7 -0
- package/src/svelte/use-network-request-observer.svelte.ts +26 -0
- package/src/vue/app-metrics-error-boundary.ts +56 -0
- package/src/vue/app-metrics-root.ts +32 -0
- package/src/vue/index.ts +12 -0
- package/src/vue/use-network-request-observer.ts +17 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 A. Prokopenko
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,184 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @symbiote-native/app-metrics
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
See how your app really performs on users' devices: how long it takes to start and become
|
|
4
|
+
interactive, how it handles network requests, when it crashes. One API for every
|
|
5
|
+
[SymbioteNative](../../README.md) adapter (React, Vue, Svelte, Solid and Angular).
|
|
6
|
+
|
|
7
|
+
It wraps [`expo-app-metrics`](https://github.com/expo/expo/tree/main/packages/expo-app-metrics)
|
|
8
|
+
(app startup, frame rate, memory, network-request, crash, and session metrics): the core surface on
|
|
9
|
+
every adapter, plus an `AppMetricsRoot` on all five and an `AppMetricsErrorBoundary` on React, Vue,
|
|
10
|
+
Solid, and Svelte, each wrapping that framework's own catch primitive.
|
|
11
|
+
|
|
12
|
+
## Scope decision (2026-09-28)
|
|
13
|
+
|
|
14
|
+
Unlike every other package in this catalog, `expo-app-metrics` ships real per-framework
|
|
15
|
+
surface, not just a thin async-function wrapper. React, Vue, Solid, and Svelte each already have
|
|
16
|
+
a subtree-scoped error-catch mechanism (React's class boundary, Vue's `onErrorCaptured`, Solid's
|
|
17
|
+
built-in `ErrorBoundary`, Svelte 5's `<svelte:boundary>`), so `AppMetricsErrorBoundary` wraps
|
|
18
|
+
that mechanism on all four, sharing the report-building logic through
|
|
19
|
+
`core/report-caught-error.ts`. `useNetworkRequestObserver`/`injectNetworkRequestObserver` ship on
|
|
20
|
+
all five adapters (see "API" below).
|
|
21
|
+
|
|
22
|
+
**Angular is NOT a permanent gap - it is version-gated.** Angular's own `@boundary`/`@error`
|
|
23
|
+
template primitive (stable `@publicApi` since `@angular/core` 22.2.0) is a real, DI-resolved
|
|
24
|
+
subtree error boundary (`ErrorHandler.onViewError`), the same caught-vs-uncaught split this
|
|
25
|
+
package already uses elsewhere. This repo pins `@angular/core` to `~22.0.8`
|
|
26
|
+
(`pnpm-workspace.yaml`) because `@angular/compiler-cli` >=22.1.0 bundles its own
|
|
27
|
+
`@babel/core@8` and its AOT linker asserts Babel 8, while this repo loads that linker INSIDE
|
|
28
|
+
Metro's own Babel 7 pipeline - re-tried bumping to 22.2.0 for this package (2026-09-28),
|
|
29
|
+
reproduced the exact `assertVersion(8)` throw directly against the real installed Babel, no
|
|
30
|
+
legacy Babel-7 linker build exists, reverted. `AppMetricsRoot` needed no version bump (it is a
|
|
31
|
+
plain `<ng-content>` wrapper marking first render in `ngOnInit`) and ships on `./angular` now.
|
|
32
|
+
`AppMetricsErrorBoundary` for Angular - as an `AppMetricsBoundaryErrorHandler` the consumer
|
|
33
|
+
provides on their own `@boundary`-owning component, since Angular's own docs mark
|
|
34
|
+
`<ng-content>` inside `@boundary`/`@error` an antipattern, so a reusable wrapper COMPONENT is
|
|
35
|
+
not the right shape there either - ships once the catalog can move past 22.0.8.
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
**New app:**
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx @symbiote-native/cli new my-app --app-metrics
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Existing SymbioteNative app:**
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx @symbiote-native/cli add --app-metrics
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Either way: installs `@symbiote-native/app-metrics` and wires the native autolinking
|
|
52
|
+
automatically, see [`@symbiote-native/cli`](../cli).
|
|
53
|
+
|
|
54
|
+
<details>
|
|
55
|
+
<summary>Manual install (no CLI, wiring native autolinking by hand)</summary>
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install @symbiote-native/app-metrics
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`expo-app-metrics` and `expo-modules-core` come along as regular dependencies, pinned to exact
|
|
62
|
+
versions. Never install either yourself, and never add the `expo` meta-package to your project
|
|
63
|
+
(it bundles its own Metro/Babel pipeline, which conflicts with this project's own).
|
|
64
|
+
|
|
65
|
+
## Required one-time step: native autolinking wiring
|
|
66
|
+
|
|
67
|
+
Unlike a plain RN native module, `expo-app-metrics`'s native code is discovered by
|
|
68
|
+
`expo-modules-autolinking`, not RN's own `react-native.config.cjs` mechanism. This needs wiring
|
|
69
|
+
into the native host app **once**, covering this package and every other `expo-modules-core`
|
|
70
|
+
package with zero further changes. Full mechanics live in the `symbiote-expo-native-module`
|
|
71
|
+
project skill.
|
|
72
|
+
|
|
73
|
+
No app-level permission strings are needed for this package.
|
|
74
|
+
|
|
75
|
+
</details>
|
|
76
|
+
|
|
77
|
+
## Shape
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
src/core/ markFirstRender / markInteractive / logEvent / setGlobalAttributes /
|
|
81
|
+
clearStoredEntries / getInactiveSessions / getAllCrashReports (android) /
|
|
82
|
+
reportError / getMainSession / getForegroundSession, the Session and
|
|
83
|
+
NetworkRequestObserver classes (re-exported straight off the native module, same
|
|
84
|
+
pattern as @symbiote-native/audio), installErrorHandler (wraps global ErrorUtils,
|
|
85
|
+
installed automatically on import), plus every public type
|
|
86
|
+
src/react/ AppMetricsRoot, AppMetricsErrorBoundary, useNetworkRequestObserver
|
|
87
|
+
src/vue/ AppMetricsRoot, AppMetricsErrorBoundary (over onErrorCaptured), useNetworkRequestObserver
|
|
88
|
+
src/solid/ AppMetricsRoot, AppMetricsErrorBoundary (over solid-js's own ErrorBoundary), useNetworkRequestObserver
|
|
89
|
+
src/svelte/ AppMetricsRoot.svelte, AppMetricsErrorBoundary.svelte (over <svelte:boundary>), useNetworkRequestObserver
|
|
90
|
+
src/angular/ AppMetricsRoot (plain <ng-content> wrapper), injectNetworkRequestObserver, no boundary yet (see Scope decision)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## API
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
markFirstRender(): void
|
|
97
|
+
markInteractive(attributes?: IMetricAttributes): void
|
|
98
|
+
logEvent(name: string, options?: ILogEventOptions): void
|
|
99
|
+
setGlobalAttributes(attributes?: Record<string, ILogAttributeValue> | null): void
|
|
100
|
+
clearStoredEntries(): Promise<void>
|
|
101
|
+
getInactiveSessions(): Promise<IDebugSession[]> // debug-only
|
|
102
|
+
getAllCrashReports(): Promise<ICrashReport[]> // android only, debug-only
|
|
103
|
+
reportError(error: IReportErrorInput): void
|
|
104
|
+
getMainSession(): Session
|
|
105
|
+
getForegroundSession(): Promise<Session | null>
|
|
106
|
+
installErrorHandler(): void // called automatically on import
|
|
107
|
+
|
|
108
|
+
class Session { id; type; startDate; isActive(); getEndDate(); getMetrics(); getLogs(); addMetric(metric) }
|
|
109
|
+
class NetworkRequestObserver { constructor(filter?); setFilter(filter) } // + addListener/removeListener
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`AppMetricsRoot` ships on all five adapters. `AppMetricsErrorBoundary` ships on `./react`,
|
|
113
|
+
`./vue`, `./solid`, and `./svelte` only (see Scope decision for `./angular`):
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
<AppMetricsRoot errorBoundaryFallback={...}>{children}</AppMetricsRoot>
|
|
117
|
+
<AppMetricsErrorBoundary fallback={...}>{children}</AppMetricsErrorBoundary>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Angular's `AppMetricsRoot` takes no `errorBoundaryFallback` (no boundary to gate yet) - just
|
|
121
|
+
`<app-metrics-root><ng-content /></app-metrics-root>` in a template.
|
|
122
|
+
|
|
123
|
+
`AppMetricsRoot.wrap(App)` is React-only (a static helper on the class).
|
|
124
|
+
|
|
125
|
+
`useNetworkRequestObserver` ships on React, Vue, Solid, and Svelte, taking a getter of
|
|
126
|
+
`{ filter?, onStarted?, onCompleted? }` (a plain object on React) and returning the
|
|
127
|
+
`NetworkRequestObserver`; Angular's twin is `injectNetworkRequestObserver`, same shape.
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import { markFirstRender, reportError } from '@symbiote-native/app-metrics';
|
|
131
|
+
import { AppMetricsRoot, AppMetricsErrorBoundary } from '@symbiote-native/app-metrics/react';
|
|
132
|
+
// or '/vue', '/solid', '/svelte'; '/angular' exports AppMetricsRoot + injectNetworkRequestObserver only
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Notes
|
|
136
|
+
|
|
137
|
+
- **`getForegroundSession` is typed `@platform ios` in upstream's own JSDoc, but its native
|
|
138
|
+
module implements it on both platforms**, confirmed by reading `AppMetricsModule.swift` and
|
|
139
|
+
`AppMetricsModule.kt` directly, not the comment. Ported as unconditionally available here.
|
|
140
|
+
- **`getAllCrashReports` is Android-only** on the native module; calling it off Android throws
|
|
141
|
+
`UnavailabilityError`, matching this repo's own convention for every other platform-gated
|
|
142
|
+
function. Upstream itself has no such guard, since it never wraps the raw native module in
|
|
143
|
+
per-platform checks; this package normalizes it the same way every sibling package does.
|
|
144
|
+
- **`installErrorHandler` runs automatically the moment this package is imported**, an eager
|
|
145
|
+
side effect in `src/core/index.ts` matching upstream's own `index.ts`, wrapping React
|
|
146
|
+
Native's global `ErrorUtils` handler so an unhandled JS error reaches `reportError` before
|
|
147
|
+
chaining to whatever handler ran before it.
|
|
148
|
+
- **`AppMetricsErrorBoundary` reports through `core/report-caught-error.ts`, independent of this
|
|
149
|
+
engine's `reportUncaughtError` channel** (`core/engine/src/report-error.ts`). A caught error
|
|
150
|
+
never reaches this engine's own uncaught-error reporting, by design, on any of the four
|
|
151
|
+
adapters that have one - see each adapter's own `render-error-reporting.test.*`.
|
|
152
|
+
- **Vue's `onErrorCaptured` gives no component stack** (its `info` argument is a lifecycle-phase
|
|
153
|
+
string, not a real trace), so the Vue and Solid boundaries call `reportCaughtError(error)` with
|
|
154
|
+
no second argument; only React's class boundary has a real `componentStack` to forward.
|
|
155
|
+
- **Solid's `mount()` and Svelte's `mount()` both rethrow an uncaught error** rather than
|
|
156
|
+
swallowing it (each adapter's own tested contract) - `AppMetricsRoot` without
|
|
157
|
+
`errorBoundaryFallback` on those two adapters leaves that throw to reach the caller, same as
|
|
158
|
+
not wrapping the tree at all.
|
|
159
|
+
- `Session` and `NetworkRequestObserver` are native `SharedObject` classes exposed as class
|
|
160
|
+
properties on the native module (see the `symbiote-expo-native-module` skill's SharedObject
|
|
161
|
+
section) - there is no JS logic to port beyond the re-export, same as
|
|
162
|
+
`@symbiote-native/audio`'s `AudioPlaylist`.
|
|
163
|
+
- The canary `AppMetricsScreen` in the `examples/expo-*` apps exercises the root, the boundary and
|
|
164
|
+
the network observer.
|
|
165
|
+
|
|
166
|
+
## Common questions
|
|
167
|
+
|
|
168
|
+
- **What does it collect?** Startup (cold/warm launch, bundle load, time to first render), frame
|
|
169
|
+
rate, memory, sessions, and your own events.
|
|
170
|
+
- **Where do the numbers go?** EAS Observe, or any OpenTelemetry-compatible backend.
|
|
171
|
+
- **Time to interactive missing.** You must mark the app interactive yourself.
|
|
172
|
+
|
|
173
|
+
Sources: [Expo docs: Introduction to EAS Observe](https://docs.expo.dev/eas/observe/introduction/),
|
|
174
|
+
[Introducing Observe](https://expo.dev/blog/introducing-observe).
|
|
175
|
+
|
|
176
|
+
## Test it
|
|
177
|
+
|
|
178
|
+
Core is tested the same way as every other package in this catalog: a fake native-module object
|
|
179
|
+
in place of `requireNativeModule` (`src/core/app-metrics.test.ts`, `src/core/
|
|
180
|
+
install-error-handler.test.ts`). The React layer is a real mount through this repo's own
|
|
181
|
+
Fabric-recording harness (`mount`/`unmount` + `installRecordingFabric`, ADR 0025):
|
|
182
|
+
`src/react/app-metrics-root.test.tsx`, `src/react/app-metrics-error-boundary.test.tsx`, and
|
|
183
|
+
`src/react/use-network-request-observer.test.tsx`, adapted from upstream's own
|
|
184
|
+
`@testing-library/react-native` test suites onto this project's harness.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { Component } from '@angular/core';
|
|
36
|
+
import { markFirstRender } from '../core/index.js';
|
|
37
|
+
/** Marks the first render, so time-to-first-render is measured without a manual call */
|
|
38
|
+
let AppMetricsRoot = (() => {
|
|
39
|
+
let _classDecorators = [Component({
|
|
40
|
+
selector: 'app-metrics-root',
|
|
41
|
+
standalone: true,
|
|
42
|
+
template: '<ng-content />',
|
|
43
|
+
})];
|
|
44
|
+
let _classDescriptor;
|
|
45
|
+
let _classExtraInitializers = [];
|
|
46
|
+
let _classThis;
|
|
47
|
+
var AppMetricsRoot = class {
|
|
48
|
+
static { _classThis = this; }
|
|
49
|
+
static {
|
|
50
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
51
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
52
|
+
AppMetricsRoot = _classThis = _classDescriptor.value;
|
|
53
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
54
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
55
|
+
}
|
|
56
|
+
ngOnInit() {
|
|
57
|
+
markFirstRender();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return AppMetricsRoot = _classThis;
|
|
61
|
+
})();
|
|
62
|
+
export { AppMetricsRoot };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// No `AppMetricsErrorBoundary` here - blocked on `@angular/core` >=22.2
|
|
2
|
+
// (this package's README "Scope decision")
|
|
3
|
+
export * from '../core/index.js';
|
|
4
|
+
export { AppMetricsRoot } from './app-metrics-root.js';
|
|
5
|
+
export { injectNetworkRequestObserver, } from './inject-network-request-observer.js';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { NetworkRequestObserver } from '../core';
|
|
2
|
+
import type { IUseNetworkRequestObserverOptions } from '../core/network-request-observer-lifecycle';
|
|
3
|
+
export type { IUseNetworkRequestObserverOptions } from '../core/network-request-observer-lifecycle';
|
|
4
|
+
/** Angular twin of `expo-app-metrics`'s `useNetworkRequestObserver` */
|
|
5
|
+
export declare function injectNetworkRequestObserver(getOptions?: () => IUseNetworkRequestObserverOptions): NetworkRequestObserver;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DestroyRef, effect, inject } from '@angular/core';
|
|
2
|
+
import { createNetworkRequestObserverLifecycle } from '../core/network-request-observer-lifecycle.js';
|
|
3
|
+
/** Angular twin of `expo-app-metrics`'s `useNetworkRequestObserver` */
|
|
4
|
+
export function injectNetworkRequestObserver(getOptions = () => ({})) {
|
|
5
|
+
const destroyRef = inject(DestroyRef);
|
|
6
|
+
return createNetworkRequestObserverLifecycle(getOptions, filterEffect => effect(filterEffect), cleanup => destroyRef.onDestroy(cleanup));
|
|
7
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ICrashReport, IDebugSession, ILogAttributeValue, ILogEventOptions, IMetricAttributes, IReportErrorInput } from './types';
|
|
2
|
+
/** Marks the moment the app is ready to measure time to first render */
|
|
3
|
+
export declare function markFirstRender(): void;
|
|
4
|
+
export declare function markInteractive(attributes?: IMetricAttributes): void;
|
|
5
|
+
/** Persisted locally, dispatched on the next flush as an OpenTelemetry log record */
|
|
6
|
+
export declare function logEvent(name: string, options?: ILogEventOptions): void;
|
|
7
|
+
/** Merged into every subsequent metric and log event, per-record keys win on collision */
|
|
8
|
+
export declare function setGlobalAttributes(attributes?: Record<string, ILogAttributeValue> | null): void;
|
|
9
|
+
export declare function clearStoredEntries(): Promise<void>;
|
|
10
|
+
/** Debug-only, ordered most-recent-first, each session eagerly includes metrics/logs/crash */
|
|
11
|
+
export declare function getInactiveSessions(): Promise<IDebugSession[]>;
|
|
12
|
+
/** Debug-only, includes orphan crashes with `sessionId: null`. @platform android */
|
|
13
|
+
export declare function getAllCrashReports(): Promise<ICrashReport[]>;
|
|
14
|
+
/** Called by `installErrorHandler`'s global handler and `AppMetricsErrorBoundary` */
|
|
15
|
+
export declare function reportError(error: IReportErrorInput): void;
|
|
16
|
+
/** The per-launch session, a static reference: repeated calls return the same object */
|
|
17
|
+
export declare function getMainSession(): import("./session").Session;
|
|
18
|
+
/** Created when the app becomes active, ended when backgrounded, `null` when none is active */
|
|
19
|
+
export declare function getForegroundSession(): Promise<import("./session").Session | null>;
|
|
20
|
+
export declare const NetworkRequestObserver: typeof import("./network-request-observer").NetworkRequestObserver;
|
|
21
|
+
export type NetworkRequestObserver = InstanceType<typeof NetworkRequestObserver>;
|
|
22
|
+
/** Not intended to be constructed from user code, see `getMainSession`/`getForegroundSession` */
|
|
23
|
+
export declare const Session: typeof import("./session").Session;
|
|
24
|
+
export type Session = InstanceType<typeof Session>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Platform, UnavailabilityError } from 'expo-modules-core';
|
|
2
|
+
import { expoAppMetrics } from './native-module.js';
|
|
3
|
+
const NATIVE_MODULE_NAME = 'expo-app-metrics';
|
|
4
|
+
/** Marks the moment the app is ready to measure time to first render */
|
|
5
|
+
export function markFirstRender() {
|
|
6
|
+
expoAppMetrics.markFirstRender();
|
|
7
|
+
}
|
|
8
|
+
export function markInteractive(attributes) {
|
|
9
|
+
expoAppMetrics.markInteractive(attributes);
|
|
10
|
+
}
|
|
11
|
+
/** Persisted locally, dispatched on the next flush as an OpenTelemetry log record */
|
|
12
|
+
export function logEvent(name, options) {
|
|
13
|
+
expoAppMetrics.logEvent(name, options);
|
|
14
|
+
}
|
|
15
|
+
/** Merged into every subsequent metric and log event, per-record keys win on collision */
|
|
16
|
+
export function setGlobalAttributes(attributes) {
|
|
17
|
+
expoAppMetrics.setGlobalAttributes(attributes);
|
|
18
|
+
}
|
|
19
|
+
export async function clearStoredEntries() {
|
|
20
|
+
return expoAppMetrics.clearStoredEntries();
|
|
21
|
+
}
|
|
22
|
+
/** Debug-only, ordered most-recent-first, each session eagerly includes metrics/logs/crash */
|
|
23
|
+
export async function getInactiveSessions() {
|
|
24
|
+
return expoAppMetrics.getInactiveSessions();
|
|
25
|
+
}
|
|
26
|
+
/** Debug-only, includes orphan crashes with `sessionId: null`. @platform android */
|
|
27
|
+
export async function getAllCrashReports() {
|
|
28
|
+
if (Platform.OS !== 'android' || !expoAppMetrics.getAllCrashReports) {
|
|
29
|
+
throw new UnavailabilityError(NATIVE_MODULE_NAME, 'getAllCrashReports');
|
|
30
|
+
}
|
|
31
|
+
return expoAppMetrics.getAllCrashReports();
|
|
32
|
+
}
|
|
33
|
+
/** Called by `installErrorHandler`'s global handler and `AppMetricsErrorBoundary` */
|
|
34
|
+
export function reportError(error) {
|
|
35
|
+
expoAppMetrics.reportError(error);
|
|
36
|
+
}
|
|
37
|
+
/** The per-launch session, a static reference: repeated calls return the same object */
|
|
38
|
+
export function getMainSession() {
|
|
39
|
+
return expoAppMetrics.getMainSession();
|
|
40
|
+
}
|
|
41
|
+
/** Created when the app becomes active, ended when backgrounded, `null` when none is active */
|
|
42
|
+
export async function getForegroundSession() {
|
|
43
|
+
return expoAppMetrics.getForegroundSession();
|
|
44
|
+
}
|
|
45
|
+
export const NetworkRequestObserver = expoAppMetrics.NetworkRequestObserver;
|
|
46
|
+
/** Not intended to be constructed from user code, see `getMainSession`/`getForegroundSession` */
|
|
47
|
+
export const Session = expoAppMetrics.Session;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { clearStoredEntries, getAllCrashReports, getForegroundSession, getInactiveSessions, getMainSession, logEvent, markFirstRender, markInteractive, NetworkRequestObserver, reportError, Session, setGlobalAttributes, } from './app-metrics';
|
|
2
|
+
export { filterKeyOf, subscribeNetworkRequestObserverEvents, } from './network-request-observer-subscription';
|
|
3
|
+
export type { INetworkRequestObserverCallbacks, ISubscribableNetworkRequestObserver, } from './network-request-observer-subscription';
|
|
4
|
+
export type { IAppStartupTimes, ICallStack, ICallStackFrame, ICallStackTree, ICrashReport, IDebugSession, IFrameRateMetrics, ILogAttributeValue, ILogEventOptions, ILogRecord, ILogSeverity, IMemoryUsageSnapshot, IMetric, IMetricAttributes, IMetricInput, INetworkRequestCompletedEvent, INetworkRequestFilter, INetworkRequestObserverEvents, INetworkRequestRedirect, INetworkRequestStartedEvent, IReportErrorInput, ISessionType, } from './types';
|
|
5
|
+
export { installErrorHandler } from './install-error-handler';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { installErrorHandler } from './install-error-handler.js';
|
|
2
|
+
export { clearStoredEntries, getAllCrashReports, getForegroundSession, getInactiveSessions, getMainSession, logEvent, markFirstRender, markInteractive, NetworkRequestObserver, reportError, Session, setGlobalAttributes, } from './app-metrics.js';
|
|
3
|
+
export { filterKeyOf, subscribeNetworkRequestObserverEvents, } from './network-request-observer-subscription.js';
|
|
4
|
+
export { installErrorHandler } from './install-error-handler.js';
|
|
5
|
+
// Live as early as the app pulls this module in, matching upstream's own side effect
|
|
6
|
+
installErrorHandler();
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { reportError } from './app-metrics.js';
|
|
2
|
+
let installed = false;
|
|
3
|
+
// react-native ships its own ambient `ErrorUtils` global, so a package whose tsconfig pulls
|
|
4
|
+
// that in conflicts with a local `declare global` here (core/engine/src/report-error.ts hit
|
|
5
|
+
// this, TS2451) - reading it off `globalThis` through Reflect sidesteps the whole ambient type
|
|
6
|
+
function globalErrorUtils() {
|
|
7
|
+
const utils = Reflect.get(globalThis, 'ErrorUtils');
|
|
8
|
+
if (typeof utils !== 'object' || utils === null)
|
|
9
|
+
return null;
|
|
10
|
+
const getGlobalHandler = Reflect.get(utils, 'getGlobalHandler');
|
|
11
|
+
const setGlobalHandler = Reflect.get(utils, 'setGlobalHandler');
|
|
12
|
+
if (typeof getGlobalHandler !== 'function' ||
|
|
13
|
+
typeof setGlobalHandler !== 'function') {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
getGlobalHandler: () => Reflect.apply(getGlobalHandler, utils, []),
|
|
18
|
+
setGlobalHandler: handler => Reflect.apply(setGlobalHandler, utils, [handler]),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Wraps React Native's global `ErrorUtils` handler, chaining to whatever ran before it */
|
|
22
|
+
export function installErrorHandler() {
|
|
23
|
+
if (installed)
|
|
24
|
+
return;
|
|
25
|
+
const errorUtils = globalErrorUtils();
|
|
26
|
+
if (!errorUtils)
|
|
27
|
+
return;
|
|
28
|
+
installed = true;
|
|
29
|
+
const previousHandler = errorUtils.getGlobalHandler();
|
|
30
|
+
errorUtils.setGlobalHandler((error, isFatal) => {
|
|
31
|
+
try {
|
|
32
|
+
const asError = error instanceof Error ? error : undefined;
|
|
33
|
+
reportError({
|
|
34
|
+
source: 'global',
|
|
35
|
+
type: asError?.name,
|
|
36
|
+
message: asError?.message ?? String(error),
|
|
37
|
+
stacktrace: asError?.stack,
|
|
38
|
+
isFatal: isFatal ?? false,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
previousHandler?.(error, isFatal);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { NetworkRequestObserver } from './network-request-observer';
|
|
2
|
+
import type { Session } from './session';
|
|
3
|
+
import type { ICrashReport, IDebugSession, ILogAttributeValue, ILogEventOptions, IMetricAttributes, IReportErrorInput } from './types';
|
|
4
|
+
export type INativeAppMetricsModule = {
|
|
5
|
+
markFirstRender(): void;
|
|
6
|
+
markInteractive(attributes?: IMetricAttributes): void;
|
|
7
|
+
logEvent(name: string, options?: ILogEventOptions): void;
|
|
8
|
+
setGlobalAttributes(attributes?: Record<string, ILogAttributeValue> | null): void;
|
|
9
|
+
clearStoredEntries(): Promise<void>;
|
|
10
|
+
getInactiveSessions(): Promise<IDebugSession[]>;
|
|
11
|
+
/** Android's native module only, app-metrics.ts gates it on Platform.OS */
|
|
12
|
+
getAllCrashReports?(): Promise<ICrashReport[]>;
|
|
13
|
+
reportError(error: IReportErrorInput): void;
|
|
14
|
+
getMainSession(): Session;
|
|
15
|
+
getForegroundSession(): Promise<Session | null>;
|
|
16
|
+
NetworkRequestObserver: typeof NetworkRequestObserver;
|
|
17
|
+
Session: typeof Session;
|
|
18
|
+
};
|
|
19
|
+
export declare const expoAppMetrics: INativeAppMetricsModule;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { NetworkRequestObserver } from './app-metrics';
|
|
2
|
+
import type { INetworkRequestObserverCallbacks } from './network-request-observer-subscription';
|
|
3
|
+
import type { INetworkRequestFilter } from './types';
|
|
4
|
+
export type IUseNetworkRequestObserverOptions = INetworkRequestObserverCallbacks & {
|
|
5
|
+
/** Applied natively. Omit or pass `null` to observe every request */
|
|
6
|
+
filter?: INetworkRequestFilter | null;
|
|
7
|
+
};
|
|
8
|
+
export declare function createNetworkRequestObserverLifecycle(getOptions: () => IUseNetworkRequestObserverOptions, runFilterEffect: (effect: () => void) => void, registerCleanup: (cleanup: () => void) => void): NetworkRequestObserver;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { NetworkRequestObserver } from './app-metrics.js';
|
|
2
|
+
import { filterKeyOf, subscribeNetworkRequestObserverEvents, } from './network-request-observer-subscription.js';
|
|
3
|
+
// Shared by adapters whose reactivity auto-tracks reads inside a plain effect (Vue's
|
|
4
|
+
// `watchEffect`, Solid's `createEffect`); React's render model doesn't, so it keeps its own wiring
|
|
5
|
+
export function createNetworkRequestObserverLifecycle(getOptions, runFilterEffect, registerCleanup) {
|
|
6
|
+
const initialFilter = getOptions().filter;
|
|
7
|
+
const observer = new NetworkRequestObserver(initialFilter);
|
|
8
|
+
let appliedFilterKey = filterKeyOf(initialFilter);
|
|
9
|
+
runFilterEffect(() => {
|
|
10
|
+
const nextKey = filterKeyOf(getOptions().filter);
|
|
11
|
+
if (appliedFilterKey === nextKey)
|
|
12
|
+
return;
|
|
13
|
+
appliedFilterKey = nextKey;
|
|
14
|
+
observer.setFilter(getOptions().filter ?? null);
|
|
15
|
+
});
|
|
16
|
+
registerCleanup(subscribeNetworkRequestObserverEvents(observer, getOptions));
|
|
17
|
+
registerCleanup(() => observer.release());
|
|
18
|
+
return observer;
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { INetworkRequestCompletedEvent, INetworkRequestFilter, INetworkRequestStartedEvent } from './types';
|
|
2
|
+
export declare function filterKeyOf(filter: INetworkRequestFilter | null | undefined): string;
|
|
3
|
+
export type INetworkRequestObserverCallbacks = {
|
|
4
|
+
onStarted?: (event: INetworkRequestStartedEvent) => void;
|
|
5
|
+
onCompleted?: (event: INetworkRequestCompletedEvent) => void;
|
|
6
|
+
};
|
|
7
|
+
export type ISubscribableNetworkRequestObserver = {
|
|
8
|
+
addListener(event: 'requestStarted', listener: (event: INetworkRequestStartedEvent) => void): {
|
|
9
|
+
remove: () => void;
|
|
10
|
+
};
|
|
11
|
+
addListener(event: 'requestCompleted', listener: (event: INetworkRequestCompletedEvent) => void): {
|
|
12
|
+
remove: () => void;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export declare function subscribeNetworkRequestObserverEvents(observer: ISubscribableNetworkRequestObserver, getCallbacks: () => INetworkRequestObserverCallbacks): () => void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Field-listed rather than a bare JSON.stringify(filter) so `{ hosts, methods }` and
|
|
2
|
+
// `{ methods, hosts }` (the same filter) don't produce different keys
|
|
3
|
+
export function filterKeyOf(filter) {
|
|
4
|
+
return JSON.stringify({
|
|
5
|
+
hosts: filter?.hosts ?? null,
|
|
6
|
+
methods: filter?.methods ?? null,
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
// `getCallbacks` is read fresh on every event, so a caller never needs to resubscribe just
|
|
10
|
+
// because its own callbacks changed identity between renders
|
|
11
|
+
export function subscribeNetworkRequestObserverEvents(observer, getCallbacks) {
|
|
12
|
+
const startedSubscription = observer.addListener('requestStarted', event => {
|
|
13
|
+
getCallbacks().onStarted?.(event);
|
|
14
|
+
});
|
|
15
|
+
const completedSubscription = observer.addListener('requestCompleted', event => {
|
|
16
|
+
getCallbacks().onCompleted?.(event);
|
|
17
|
+
});
|
|
18
|
+
return () => {
|
|
19
|
+
startedSubscription.remove();
|
|
20
|
+
completedSubscription.remove();
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SharedObject } from 'expo-modules-core';
|
|
2
|
+
import type { INetworkRequestFilter, INetworkRequestObserverEvents } from './types';
|
|
3
|
+
export declare class NetworkRequestObserver extends SharedObject<INetworkRequestObserverEvents> {
|
|
4
|
+
constructor(filter?: INetworkRequestFilter | null);
|
|
5
|
+
/** Applies atomically, in-flight events are emitted under either the old or new filter */
|
|
6
|
+
setFilter(filter: INetworkRequestFilter | null): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { reportError } from './app-metrics.js';
|
|
2
|
+
/** Shared by every adapter's error-boundary equivalent, builds and reports a caught render error */
|
|
3
|
+
export function reportCaughtError(error, componentStack) {
|
|
4
|
+
const caught = error instanceof Error ? error : undefined;
|
|
5
|
+
try {
|
|
6
|
+
reportError({
|
|
7
|
+
source: 'errorBoundary',
|
|
8
|
+
type: caught?.name,
|
|
9
|
+
message: caught?.message ?? String(error),
|
|
10
|
+
stacktrace: caught?.stack,
|
|
11
|
+
componentStack,
|
|
12
|
+
isFatal: false,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
catch (reportingError) {
|
|
16
|
+
if (__DEV__) {
|
|
17
|
+
console.warn('[app-metrics] Failed to report a caught error:', reportingError);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SharedObject } from 'expo-modules-core';
|
|
2
|
+
import type { ILogRecord, IMetric, IMetricInput, ISessionType } from './types';
|
|
3
|
+
export declare class Session extends SharedObject {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly type: ISessionType;
|
|
6
|
+
readonly startDate: string;
|
|
7
|
+
isActive(): Promise<boolean>;
|
|
8
|
+
getEndDate(): Promise<string | null>;
|
|
9
|
+
getMetrics(): Promise<IMetric[]>;
|
|
10
|
+
getLogs(): Promise<ILogRecord[]>;
|
|
11
|
+
addMetric(metric: IMetricInput): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|