@camstack/sdk 1.2.18 → 1.2.20
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 +78 -44
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,56 +1,90 @@
|
|
|
1
1
|
# @camstack/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The client library for talking to a **CamStack hub**.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
It gives you `System` — a connected client that owns the transport (tRPC over
|
|
6
|
+
WebSocket, or HTTP), the login flow, a warm cache of the hub's devices, and live
|
|
7
|
+
event subscriptions — plus the shared TypeScript types (detections, timeline,
|
|
8
|
+
devices, cameras) that the hub's API speaks.
|
|
6
9
|
|
|
7
|
-
This
|
|
10
|
+
This is what the CamStack Viewer app is built on.
|
|
8
11
|
|
|
9
|
-
##
|
|
12
|
+
## Install
|
|
10
13
|
|
|
11
14
|
```bash
|
|
12
|
-
npm install @camstack/sdk
|
|
15
|
+
npm install @camstack/sdk @camstack/types @trpc/client
|
|
13
16
|
```
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
18
|
+
`@camstack/types` and `@trpc/client` are not bundled: the published build imports
|
|
19
|
+
both at runtime, so they must be installed alongside.
|
|
20
|
+
|
|
21
|
+
## Quickstart
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { createSystem } from '@camstack/sdk'
|
|
25
|
+
import { EventCategory } from '@camstack/types'
|
|
26
|
+
|
|
27
|
+
// Log in (a tokenless System is enough — `login` is a public procedure).
|
|
28
|
+
const { token } = await createSystem({ serverUrl: 'http://hub.local:4443' })
|
|
29
|
+
.login('admin', 'hunter2')
|
|
30
|
+
|
|
31
|
+
const system = createSystem({
|
|
32
|
+
serverUrl: 'http://hub.local:4443',
|
|
33
|
+
token,
|
|
34
|
+
onConnectionChange: (state) => console.info('transport:', state),
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// Warm-boot the device mirror, then read devices synchronously.
|
|
38
|
+
await system.init()
|
|
39
|
+
for (const info of system.listDeviceInfos()) {
|
|
40
|
+
console.info(info.id, info.name, info.online)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Fully typed calls against the hub's tRPC router.
|
|
44
|
+
const snapshot = await system.trpcClient.snapshot.getSnapshot.query({ deviceId: 42 })
|
|
45
|
+
|
|
46
|
+
// Live events, one subscription per category, fanned out to all listeners.
|
|
47
|
+
const unsubscribe = system.subscribeEvent(EventCategory.MotionOnMotionChanged, (event) => {
|
|
48
|
+
console.info(event.source, event.data)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// …later
|
|
52
|
+
unsubscribe()
|
|
53
|
+
system.close()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
If `login` returns `requiresTotp`, the returned `token` is a challenge — pass it
|
|
57
|
+
to `system.loginVerifyTotp(challengeToken, code)` to exchange it for a session
|
|
58
|
+
token. Passkeys have an equivalent pair of methods.
|
|
59
|
+
|
|
60
|
+
## What's exported
|
|
61
|
+
|
|
62
|
+
`packages/sdk/src/index.ts` is the authoritative list. In broad strokes:
|
|
63
|
+
|
|
64
|
+
| Surface | What it is |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `System`, `createSystem`, `SystemConfig` | The client. Connection lifecycle, auth, devices, live events. |
|
|
67
|
+
| `raceFastestEndpoint` | Probes candidate base URLs against `/trpc/health` and returns the first to answer. For clients that reach the same hub over several routes. |
|
|
68
|
+
| `BackendAppRouter` (alias `AppRouter`) | Type-only. The hub's tRPC router type — use it to type your own tRPC client if you don't want `System`. |
|
|
69
|
+
| `DetectionClass` + classifiers | The detection-class vocabulary (`isPersonClassname`, `getParentClass`, timeline presets, …). |
|
|
70
|
+
| Device types | `CanonicalDeviceType`, `getCanonicalDeviceType`, and the raw→canonical maps. |
|
|
71
|
+
| Timeline / NVR / camera types | Type-only shapes for events, clusters, recordings, clips, PTZ, camera status. |
|
|
72
|
+
| `FEATURE_MATRIX`, `isFeatureAvailable` | Static table of which features a given source/platform supports. |
|
|
73
|
+
|
|
74
|
+
`System` also exposes the hub's system-scoped capabilities as typed namespaces
|
|
75
|
+
(`system.storage`, `system.userManagement`, `system.streamBroker`, …), and
|
|
76
|
+
`system.trpcClient` as the escape hatch for anything not wrapped.
|
|
77
|
+
|
|
78
|
+
## What it is not
|
|
79
|
+
|
|
80
|
+
- **Not a REST wrapper.** Everything goes over tRPC to a CamStack hub. There is
|
|
81
|
+
no stable HTTP surface here to call by hand.
|
|
82
|
+
- **Not a standalone NVR client.** It does not talk to Frigate, Scrypted, ONVIF
|
|
83
|
+
or a camera directly — the hub does that. Names like `CameraSourceType` are
|
|
84
|
+
how the hub *describes* a source, not clients for it.
|
|
85
|
+
- **Not versioned independently of the hub.** The router types are generated
|
|
86
|
+
from the server, so an SDK build matches the hub it was built against. Expect
|
|
87
|
+
to keep the two roughly in step; no compatibility window is promised.
|
|
54
88
|
|
|
55
89
|
## License
|
|
56
90
|
|