cosmic-eye 0.3.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -53
- package/dist/index.cjs +633 -170
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +283 -47
- package/dist/index.d.ts +283 -47
- package/dist/index.js +631 -165
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +3 -3
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +10 -12
- package/dist/react.d.ts +10 -12
- package/dist/react.js +3 -3
- package/dist/react.js.map +1 -1
- package/package.json +15 -5
package/README.md
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
# CosmicEye
|
|
2
2
|
|
|
3
|
-
A set of RUM metrics for SPAs. Two independent modules:
|
|
3
|
+
A set of RUM metrics for SPAs. Two independent modules + extensions:
|
|
4
4
|
|
|
5
5
|
- **RDR** (RUM Duplicate Requests) — detects and logs duplicate API requests.
|
|
6
6
|
- **RT** (Route Transition Metrics) — measures route transition timing (render + TTI).
|
|
7
|
+
- **Extensions** — `observeHistory`, `RouteRenderObserver`, `mobxSpy`.
|
|
7
8
|
|
|
8
9
|
**Key properties:**
|
|
9
10
|
|
|
10
|
-
- Zero runtime dependencies for the core (React
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
- `RouteTracker` — "dumb" React provider for both modules (post-render)
|
|
11
|
+
- Zero runtime dependencies for the core (React and MobX are optional peers)
|
|
12
|
+
- Config-driven sampling, send functions, enrichers, tags
|
|
13
|
+
- All public methods return result objects with `initialized` status
|
|
14
14
|
- `observeHistory` — neutral pre-render navigation observer (history v4/v5)
|
|
15
|
+
- `RouteRenderObserver` — post-render React provider
|
|
16
|
+
- `mobxSpy` — MobX spy integration (no-op if MobX absent)
|
|
15
17
|
|
|
16
18
|
## Installation
|
|
17
19
|
|
|
@@ -24,83 +26,82 @@ npm install cosmic-eye
|
|
|
24
26
|
### RDR
|
|
25
27
|
|
|
26
28
|
```ts
|
|
27
|
-
import rdr,
|
|
29
|
+
import { rdr, initRDR } from 'cosmic-eye';
|
|
28
30
|
|
|
29
|
-
initRDR();
|
|
30
|
-
|
|
31
|
+
const ok = initRDR({ samplingRate: 0.05, send: (p) => analytics.send('rdr', p) });
|
|
32
|
+
|
|
33
|
+
// RPC-style
|
|
34
|
+
rdr.reqHandlerRpc({ s: 'UserService', m: 'getProfile', p: { id: 42 }, b: {} });
|
|
35
|
+
// HTTP-style
|
|
36
|
+
rdr.reqHandlerHttp({ httpMethod: 'GET', endpoint: '/api/users/42' });
|
|
31
37
|
```
|
|
32
38
|
|
|
33
|
-
### RT + observeHistory +
|
|
39
|
+
### RT + observeHistory + RouteRenderObserver
|
|
34
40
|
|
|
35
41
|
```ts
|
|
36
42
|
import { initRT, rt, observeHistory } from 'cosmic-eye';
|
|
37
43
|
import { createBrowserHistory } from 'history';
|
|
38
44
|
|
|
39
45
|
const history = createBrowserHistory();
|
|
40
|
-
initRT();
|
|
46
|
+
initRT({ send: (p) => analytics.send('rt', p), includePathname: true });
|
|
41
47
|
|
|
42
|
-
// Pre-render: observer emits navigation events before React render
|
|
43
48
|
const observer = observeHistory(history);
|
|
44
49
|
observer.subscribe(({ pathname, search }) => {
|
|
45
50
|
rt.startTransition(pathname, search);
|
|
46
|
-
rdr.resetTiming();
|
|
47
|
-
rdr.resetActions();
|
|
48
51
|
});
|
|
49
52
|
```
|
|
50
53
|
|
|
51
54
|
```tsx
|
|
52
|
-
import {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
]}
|
|
60
|
-
>
|
|
61
|
-
<Switch>...</Switch>
|
|
62
|
-
</RouteTracker>
|
|
63
|
-
</Router>
|
|
55
|
+
import { RouteRenderObserver } from 'cosmic-eye/react';
|
|
56
|
+
|
|
57
|
+
<RouteRenderObserver
|
|
58
|
+
onRouteChange={[(pathname) => { rt.markRendered(pathname); }]}
|
|
59
|
+
>
|
|
60
|
+
{children}
|
|
61
|
+
</RouteRenderObserver>
|
|
64
62
|
```
|
|
65
63
|
|
|
66
64
|
## How duplicate detection works
|
|
67
65
|
|
|
68
|
-
1. Each incoming payload is hashed into a `reqHash` (
|
|
69
|
-
2. If the same `reqHash` was seen within `
|
|
66
|
+
1. Each incoming payload is hashed into a `reqHash` (FNV-1a of endpoint + params + body)
|
|
67
|
+
2. If the same `reqHash` was seen within `duplicateThresholdMs` (default 1 000 ms), a log entry is created
|
|
70
68
|
3. Log entries accumulate in a buffer and are flushed:
|
|
71
|
-
- Every `
|
|
72
|
-
- When buffer reaches `
|
|
69
|
+
- Every `flushIntervalMs` (15 s)
|
|
70
|
+
- When buffer reaches `flushMaxEvents` (50)
|
|
73
71
|
- On `visibilitychange` (tab hidden)
|
|
74
72
|
- On `pagehide` (page close)
|
|
75
|
-
- On `destroy()`
|
|
73
|
+
- On `destroy()` or `flush()`
|
|
76
74
|
|
|
77
75
|
## Sampling
|
|
78
76
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
In **development** (`NODE_ENV !== 'production'`), sampling is always enabled.
|
|
77
|
+
Sampling is **config-driven** via `samplingRate` (0..1). Default is `1` (always enabled). The decision is deterministic when a stable client ID is available (`clientId` from config or persisted `localStorage`). If storage is unavailable and no explicit `clientId` is provided, fallback ID generation may produce non-deterministic results between calls.
|
|
82
78
|
|
|
83
79
|
## API
|
|
84
80
|
|
|
85
81
|
### RDR
|
|
86
82
|
|
|
87
|
-
| Function | Description |
|
|
88
|
-
|
|
89
|
-
| `initRDR()` |
|
|
90
|
-
| `rdr.
|
|
91
|
-
| `rdr.
|
|
92
|
-
| `rdr.
|
|
93
|
-
| `rdr.
|
|
83
|
+
| Function | Returns | Description |
|
|
84
|
+
|----------|---------|-------------|
|
|
85
|
+
| `initRDR(config?)` | `boolean` | Initialize with optional config. |
|
|
86
|
+
| `rdr.isInitialized()` | `boolean` | Check if active. |
|
|
87
|
+
| `rdr.reqHandlerRpc(payload)` | `RdrReqHandlerResult` | Process RPC request. |
|
|
88
|
+
| `rdr.reqHandlerHttp(payload)` | `RdrReqHandlerResult` | Process HTTP request. |
|
|
89
|
+
| `rdr.flush(trigger?, meta?)` | `RdrFlushResult` | Manual flush. |
|
|
90
|
+
| `rdr.resetTiming()` | `RdrResetTimingResult` | Reset page load timestamp. |
|
|
91
|
+
| `rdr.resetActions()` | `RdrResetActionsResult` | Clear action buffer. |
|
|
92
|
+
| `rdr.destroy()` | `RdrDestroyResult` | Stop, flush, clean up. |
|
|
94
93
|
|
|
95
94
|
### RT
|
|
96
95
|
|
|
97
|
-
| Function | Description |
|
|
98
|
-
|
|
99
|
-
| `initRT()` |
|
|
100
|
-
| `rt.
|
|
101
|
-
| `rt.
|
|
102
|
-
| `
|
|
103
|
-
| `rt.
|
|
96
|
+
| Function | Returns | Description |
|
|
97
|
+
|----------|---------|-------------|
|
|
98
|
+
| `initRT(config?)` | `boolean` | Initialize with optional config. |
|
|
99
|
+
| `rt.isInitialized()` | `boolean` | Check if active. |
|
|
100
|
+
| `rt.startTransition(pathname, search?)` | `RtStartTransitionResult` | Start transition timing. |
|
|
101
|
+
| `rt.markRendered(pathname)` | `RtMarkRenderedResult` | Mark render completion. |
|
|
102
|
+
| `rt.trackCritical(promise?)` | `RtTrackCriticalResult` | Track critical operation. |
|
|
103
|
+
| `rt.abortPending(reason?)` | `RtAbortPendingResult` | Abort active transition. |
|
|
104
|
+
| `rt.destroy()` | `RtDestroyResult` | Clean up. |
|
|
104
105
|
|
|
105
106
|
### observeHistory
|
|
106
107
|
|
|
@@ -110,7 +111,7 @@ In **development** (`NODE_ENV !== 'production'`), sampling is always enabled.
|
|
|
110
111
|
| `observer.subscribe(listener)` | Subscribe to `INIT/PUSH/REPLACE/POP`. Returns `unsubscribe` |
|
|
111
112
|
| `observer.unpatch()` | Remove patch, clean up |
|
|
112
113
|
|
|
113
|
-
###
|
|
114
|
+
### RouteRenderObserver (`cosmic-eye/react`)
|
|
114
115
|
|
|
115
116
|
| Prop | Type | Description |
|
|
116
117
|
|------|------|-------------|
|
|
@@ -125,15 +126,17 @@ See [src/rdr/README.md](src/rdr/README.md) and [src/rt/README.md](src/rt/README.
|
|
|
125
126
|
src/
|
|
126
127
|
index.ts — public API (re-exports only, no React)
|
|
127
128
|
react.ts — React extensions entry point (cosmic-eye/react)
|
|
129
|
+
shared/ — shared utilities (time, hash, sampling, enrichers, env)
|
|
128
130
|
rdr/ — RDR module: duplicate request detection
|
|
129
131
|
rt/ — RT module: route transition metrics
|
|
130
132
|
extensions/
|
|
131
133
|
history-route-observer/ — navigation observer (pre-render)
|
|
132
|
-
route-
|
|
134
|
+
route-render-observer/ — RouteRenderObserver React component (post-render)
|
|
135
|
+
mobx-spy/ — MobX spy extension (optional peer)
|
|
133
136
|
tests/
|
|
134
|
-
rdr/ — RDR tests
|
|
135
|
-
rt/ — RT tests
|
|
136
|
-
extensions/ — extension tests (
|
|
137
|
+
rdr/ — RDR tests
|
|
138
|
+
rt/ — RT tests
|
|
139
|
+
extensions/ — extension tests (observer, route-render, mobx-spy)
|
|
137
140
|
```
|
|
138
141
|
|
|
139
142
|
## Test commands
|
|
@@ -153,7 +156,8 @@ Each module has its own README with integration guide, configuration reference,
|
|
|
153
156
|
- [src/rdr/README.md](src/rdr/README.md) — RDR documentation
|
|
154
157
|
- [src/rt/README.md](src/rt/README.md) — RT documentation
|
|
155
158
|
- [src/extensions/history-route-observer/README.md](src/extensions/history-route-observer/README.md) — observer documentation
|
|
156
|
-
- [src/extensions/route-
|
|
159
|
+
- [src/extensions/route-render-observer/README.md](src/extensions/route-render-observer/README.md) — RouteRenderObserver documentation
|
|
160
|
+
- [src/extensions/mobx-spy/README.md](src/extensions/mobx-spy/README.md) — mobxSpy documentation
|
|
157
161
|
- [CHANGELOG.md](CHANGELOG.md) — change history
|
|
158
162
|
|
|
159
163
|
## License
|