@observertc/observer-js 1.0.0-beta.4 → 1.0.0-beta.5
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 +36 -17
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2795 -0
- package/dist/index.js +3765 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +53 -73
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -7
package/README.md
CHANGED
|
@@ -15,8 +15,9 @@ and emits a single, unified stream of typed events the application can react to.
|
|
|
15
15
|
> agent) should be able to integrate the library, or develop it further, from this file alone.
|
|
16
16
|
> A companion doc, [`docs/logging.md`](./docs/logging.md), covers logging integration in depth.
|
|
17
17
|
|
|
18
|
-
> **Packaging:**
|
|
19
|
-
>
|
|
18
|
+
> **Packaging:** server-side, **Node.js ≥ 22**, shipped as a **dual ESM + CommonJS** build — so it
|
|
19
|
+
> works whether your project uses `import` (ESM) or `require()` (CommonJS). Everything — including
|
|
20
|
+
> the built-in file sink — is exported from the single `@observertc/observer-js` entry.
|
|
20
21
|
|
|
21
22
|
---
|
|
22
23
|
|
|
@@ -51,22 +52,20 @@ npm install @observertc/observer-js
|
|
|
51
52
|
yarn add @observertc/observer-js
|
|
52
53
|
```
|
|
53
54
|
|
|
54
|
-
**
|
|
55
|
-
|
|
56
|
-
compiled to ESM. Everything is exported from the single `@observertc/observer-js` entry:
|
|
55
|
+
**Server-side, Node.js ≥ 22, dual ESM + CommonJS.** The package ships both module formats, so it
|
|
56
|
+
works the same whether your project is ESM or CommonJS — your import line is unchanged either way:
|
|
57
57
|
|
|
58
58
|
```ts
|
|
59
59
|
import { Observer, ClientSample, createJsonlFileSinkFactory } from '@observertc/observer-js';
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
In an ESM project this resolves to the `.mjs` build; in a CommonJS project (where TypeScript
|
|
63
|
+
compiles your `import` down to `require()`) it resolves to the `.js` build. Everything is exported
|
|
64
|
+
from the single `@observertc/observer-js` entry. Written in TypeScript; ships type declarations for
|
|
65
|
+
both formats (`dist/index.d.ts` for `require`, `dist/index.d.mts` for `import`). Runtime
|
|
63
66
|
dependencies: `@bufbuild/protobuf`, `events`, `uuid`. The library does **not** bundle a logger or
|
|
64
67
|
any transport — see [Logging](#logging).
|
|
65
68
|
|
|
66
|
-
> **Note on `require()`.** Being ESM-only, the package can't be loaded with CommonJS
|
|
67
|
-
> `require('@observertc/observer-js')`; consume it with `import` (or `await import()` from a CJS
|
|
68
|
-
> module). If you need a CommonJS build, a dual ESM+CJS output is a small change — ask.
|
|
69
|
-
|
|
70
69
|
`ClientSample` and friends are re-exported from this package, and are also published as the
|
|
71
70
|
shared schema in [`@observertc/schemas`](https://github.com/observertc/schemas); samples
|
|
72
71
|
produced on the client (e.g. by `@observertc/client-monitor-js`) conform to the same shape.
|
|
@@ -733,12 +732,32 @@ observer.on('client-sink-created', ({ observedClient, sink }) => {
|
|
|
733
732
|
|--------|-----------|-------|
|
|
734
733
|
| `createJsonlFileSinkFactory` | `({ directory, flags?, getFileName?, serializeSample? }) => ClientSampleSinkFactory` | per-client JSONL files; path defaults to `${callId}__${clientId}.jsonl` under `directory` (which **must exist**) |
|
|
735
734
|
| `createJsonlFileSink` | `({ path, flags?, serializeSample? }) => ClientSampleSink` | a single JSONL file; wraps `fs.WriteStream` and re-emits its `close`/`finish`/`drain`/`error` |
|
|
736
|
-
| `JsonlFileSink` | `class extends ClientSampleSink` | the underlying class
|
|
735
|
+
| `JsonlFileSink` | `class extends ClientSampleSink` | the underlying class; exposes `readonly path` so a `close` handler knows which file is ready |
|
|
737
736
|
| `createInMemorySink` / `InMemorySink` | `(samples?: ClientSample[]) => InMemorySink` | collects the accepted **sample objects** into `.samples: ClientSample[]`; emits `close` on `end()` |
|
|
738
737
|
|
|
739
738
|
`serializeSample?: (sample: ClientSample) => string` overrides the default `JSON.stringify` for
|
|
740
739
|
the JSONL sinks (e.g. to redact or reshape before writing).
|
|
741
740
|
|
|
741
|
+
### Reading sink-specific info (e.g. the file path)
|
|
742
|
+
|
|
743
|
+
The bus hands you the sink as the base `ClientSampleSink`. To read information specific to a sink
|
|
744
|
+
type — for a file sink, where it was written — **narrow with `instanceof`** and read the sink's
|
|
745
|
+
public fields. `JsonlFileSink` exposes `path`:
|
|
746
|
+
|
|
747
|
+
```ts
|
|
748
|
+
import { JsonlFileSink } from '@observertc/observer-js';
|
|
749
|
+
|
|
750
|
+
observer.on('client-sink-created', ({ observedClient, sink }) => {
|
|
751
|
+
if (sink instanceof JsonlFileSink) {
|
|
752
|
+
const { path } = sink; // the file this client's samples go to
|
|
753
|
+
sink.once('close', () => uploadFile(path)); // close = flushed & fd closed → ready
|
|
754
|
+
}
|
|
755
|
+
});
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
The general pattern: each concrete sink exposes whatever it wants as `public readonly` fields, and
|
|
759
|
+
consumers narrow (`instanceof YourSink`) to read them. Your own sinks do the same.
|
|
760
|
+
|
|
742
761
|
### Writing your own sink
|
|
743
762
|
|
|
744
763
|
Subclass `ClientSampleSink` and emit the lifecycle events yourself — for any non-file
|
|
@@ -853,23 +872,23 @@ export type { TrackReport, ClientReport } from './Reports';
|
|
|
853
872
|
|
|
854
873
|
```bash
|
|
855
874
|
yarn install
|
|
856
|
-
yarn build # tsup → dist/ (ESM
|
|
875
|
+
yarn build # tsup → dist/ (dual ESM .mjs + CJS .js, single entry, .d.ts/.d.mts + sourcemaps)
|
|
857
876
|
yarn lint # eslint -c .eslintrc.json "src/**/*.ts"
|
|
858
877
|
yarn typecheck # tsc --noEmit
|
|
859
878
|
yarn test # jest
|
|
860
879
|
```
|
|
861
880
|
|
|
862
881
|
The build is driven by [`tsup`](https://tsup.egoist.dev) (config in `tsup.config.ts`): a single
|
|
863
|
-
entry (`src/index.ts`), ESM output to `dist/`
|
|
864
|
-
|
|
882
|
+
entry (`src/index.ts`), dual ESM + CommonJS output to `dist/` (`index.mjs` / `index.js`) with
|
|
883
|
+
`.d.mts` / `.d.ts` types and sourcemaps, targeting Node 22. CI (`.github/workflows/ci.yml`) runs
|
|
884
|
+
lint + typecheck + **build** + test on every push/PR.
|
|
865
885
|
|
|
866
886
|
**Project layout** (`src/`): `Observer.ts`, `ObservedCall.ts`, `ObservedClient.ts`,
|
|
867
887
|
`ObservedPeerConnection.ts`, the `Observed*` sub-stat classes, `ObserverEvents.ts` (the typed
|
|
868
888
|
event map + scope types), `detectors/` (`Detector`, `Detectors`), `scores/`, `updaters/`
|
|
869
889
|
(update-policy strategies), `utils/` (remote-track resolvers), `common/` (`logger`, `utils`,
|
|
870
|
-
`Middleware`), `schema/` (sample/event/meta types), and `sinks/` (the
|
|
871
|
-
`
|
|
872
|
-
`@observertc/observer-js/sinks` subpath).
|
|
890
|
+
`Middleware`), `schema/` (sample/event/meta types), and `sinks/` (the `ClientSampleSink` base +
|
|
891
|
+
`JsonlFileSink` / `InMemorySink`, re-exported from the package root).
|
|
873
892
|
|
|
874
893
|
**Conventions to follow when developing further:**
|
|
875
894
|
|
package/dist/index.d.mts
CHANGED
|
@@ -2751,6 +2751,8 @@ type JsonlFileSinkOptions = {
|
|
|
2751
2751
|
* and its descriptor is closed (file ready) and `error` surfaces file errors.
|
|
2752
2752
|
*/
|
|
2753
2753
|
declare class JsonlFileSink extends ClientSampleSink {
|
|
2754
|
+
/** The file this sink writes to. Read it (e.g. in a `close` handler) to upload/move the file. */
|
|
2755
|
+
readonly path: string;
|
|
2754
2756
|
private readonly _stream;
|
|
2755
2757
|
private readonly _serializeSample;
|
|
2756
2758
|
constructor(options: JsonlFileSinkOptions);
|