@camera.ui/sdk 0.0.3 → 0.0.4

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.
Files changed (76) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +2 -2
  3. package/dist/camera/events.js +2 -0
  4. package/dist/camera/index.js +3 -1
  5. package/dist/external.js +7 -0
  6. package/dist/index.d.ts +7132 -4248
  7. package/dist/index.js +3 -11
  8. package/dist/internal/contract-validators.js +21 -0
  9. package/dist/internal/index.d.ts +915 -0
  10. package/dist/internal/index.js +9 -0
  11. package/dist/internal/sensor-triggers.js +2 -0
  12. package/dist/internal/shared-utils.js +86 -0
  13. package/dist/internal/streaming-internal.js +1 -0
  14. package/dist/manager/index.js +1 -1
  15. package/dist/observable/index.js +419 -0
  16. package/dist/plugin/api.js +21 -0
  17. package/dist/plugin/contract.js +101 -114
  18. package/dist/plugin/helper.js +277 -0
  19. package/dist/plugin/index.js +4 -1
  20. package/dist/plugin/interfaces.js +51 -1
  21. package/dist/plugin/notifier.js +23 -0
  22. package/dist/plugin/oauth.js +1 -0
  23. package/dist/sensor/audio.js +103 -81
  24. package/dist/sensor/base.js +350 -318
  25. package/dist/sensor/battery.js +73 -59
  26. package/dist/sensor/classifier.js +117 -0
  27. package/dist/sensor/clip.js +30 -0
  28. package/dist/sensor/contact.js +37 -18
  29. package/dist/sensor/detection.js +4 -0
  30. package/dist/sensor/doorbell.js +52 -38
  31. package/dist/sensor/face.js +71 -86
  32. package/dist/sensor/garage.js +121 -0
  33. package/dist/sensor/humidity.js +52 -0
  34. package/dist/sensor/index.js +17 -11
  35. package/dist/sensor/leak.js +52 -0
  36. package/dist/sensor/licensePlate.js +70 -79
  37. package/dist/sensor/light.js +82 -38
  38. package/dist/sensor/lock.js +99 -0
  39. package/dist/sensor/motion.js +85 -70
  40. package/dist/sensor/object.js +73 -94
  41. package/dist/sensor/occupancy.js +52 -0
  42. package/dist/sensor/ptz.js +114 -100
  43. package/dist/sensor/securitySystem.js +98 -0
  44. package/dist/sensor/siren.js +75 -43
  45. package/dist/sensor/smoke.js +52 -0
  46. package/dist/sensor/spec.js +1 -0
  47. package/dist/sensor/switch.js +72 -0
  48. package/dist/sensor/temperature.js +52 -0
  49. package/dist/storage/index.js +1 -2
  50. package/dist/types.js +1 -0
  51. package/docs/.vitepress/config.ts +77 -0
  52. package/docs/.vitepress/theme/index.ts +5 -0
  53. package/docs/.vitepress/theme/style.css +117 -0
  54. package/docs/index.md +16 -0
  55. package/docs/logo.png +0 -0
  56. package/docs/public/apple-touch-icon.png +0 -0
  57. package/docs/public/favicon-16.ico +0 -0
  58. package/docs/public/favicon.ico +0 -0
  59. package/docs/public/logo.svg +1 -0
  60. package/examples/README.md +7 -0
  61. package/examples/getting-started.md +535 -0
  62. package/package.json +36 -23
  63. package/scripts/build-example-docs.mjs +62 -0
  64. package/tsconfig.node.json +3 -2
  65. package/typedoc.json +42 -0
  66. package/dist/sensor/guards.js +0 -133
  67. package/dist/sensor/types.js +0 -46
  68. package/dist/service/base.js +0 -96
  69. package/dist/service/index.js +0 -3
  70. /package/dist/camera/{types.js → enums.js} +0 -0
  71. /package/dist/{manager/types.js → camera/frames.js} +0 -0
  72. /package/dist/{plugin/types.js → internal/camera-config-internal.js} +0 -0
  73. /package/dist/{service/services.js → internal/camera-enums.js} +0 -0
  74. /package/dist/{service/types.js → internal/camera-wire.js} +0 -0
  75. /package/dist/{storage/schema.js → internal/manager-rpc.js} +0 -0
  76. /package/dist/{storage/storages.js → internal/sensor-rpc.js} +0 -0
@@ -0,0 +1,62 @@
1
+ /* eslint-disable @stylistic/max-len */
2
+ import { readdirSync, readFileSync, writeFileSync, mkdirSync, statSync, rmSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const here = dirname(fileURLToPath(import.meta.url));
7
+ const examplesDir = join(here, '..', 'examples');
8
+ const outDir = join(here, '..', 'docs', 'examples');
9
+ const apiDir = join(here, '..', 'docs', 'api');
10
+
11
+ const apiIndex = `# API Reference
12
+
13
+ Module-by-module reference, auto-generated from the JSDoc in \`@camera.ui/sdk\`.
14
+
15
+ | Module | What's in it |
16
+ | --- | --- |
17
+ | [Plugin API](./plugin/) | \`BasePlugin\`, the manifest contract, optional interfaces (discovery, notifier, detection). |
18
+ | [Camera](./camera/) | Camera config, frames, streaming sessions, detection events, runtime device API. |
19
+ | [Sensors](./sensor/) | Detection sensors (motion, object, face, license-plate, audio, classifier, clip) and smart-home sensors (contact, doorbell, lock, garage, light, switch, ptz, security system, environmental). |
20
+ | [Storage & Schema](./storage/) | Schema-driven per-device config rendered as UI forms by the host. |
21
+ | [Manager](./manager/) | \`CoreManager\` / \`DeviceManager\` / \`DownloadManager\` for system-level services. |
22
+ | [Observable](./observable/) | Reactive primitives — \`Observable\`, \`Subject\`, \`BehaviorSubject\`, \`ReplaySubject\` — and operators. |
23
+ | [Types](./types/) | Shared types (\`LoggerService\`, \`PluginAPI\`, …). |
24
+
25
+ If you're new to the SDK, start with the [Plugin Guide](/examples/getting-started) instead — it walks through these modules in the order you'll actually use them.
26
+ `;
27
+
28
+ writeFileSync(join(apiDir, 'index.md'), apiIndex);
29
+
30
+ rmSync(outDir, { recursive: true, force: true });
31
+ mkdirSync(outDir, { recursive: true });
32
+
33
+ const indexSrc = readFileSync(join(examplesDir, 'README.md'), 'utf8');
34
+ const indexOut = indexSrc.replace(/\[`([^`]+)\/`\]\(\.\/\1\/\)/g, '[`$1`](/examples/$1)').replace(/^# .+/m, '# Examples');
35
+ writeFileSync(join(outDir, 'index.md'), indexOut);
36
+
37
+ const entries = readdirSync(examplesDir).sort();
38
+
39
+ for (const name of entries) {
40
+ const full = join(examplesDir, name);
41
+ const stat = statSync(full);
42
+
43
+ if (stat.isFile() && name.endsWith('.md') && name !== 'README.md') {
44
+ const src = readFileSync(full, 'utf8');
45
+ writeFileSync(join(outDir, name), src);
46
+ continue;
47
+ }
48
+
49
+ if (!stat.isDirectory()) continue;
50
+
51
+ const readme = readFileSync(join(full, 'README.md'), 'utf8');
52
+ const contract = readFileSync(join(full, 'contract.ts'), 'utf8');
53
+ const index = readFileSync(join(full, 'index.ts'), 'utf8');
54
+
55
+ const page = [readme.trimEnd(), '', '## `contract.ts`', '', '```ts', contract.trimEnd(), '```', '', '## `index.ts`', '', '```ts', index.trimEnd(), '```', ''].join(
56
+ '\n',
57
+ );
58
+
59
+ writeFileSync(join(outDir, `${name}.md`), page);
60
+ }
61
+
62
+ console.log(`Built example pages to ${outDir}`);
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "outDir": "./dist",
4
- "target": "ES2022",
4
+ "target": "es2024",
5
5
  "moduleResolution": "NodeNext",
6
6
  "module": "NodeNext",
7
7
  "lib": [
8
- "ES2022",
8
+ "ES2024",
9
9
  ],
10
10
  "declaration": false,
11
11
  "strict": true,
@@ -26,5 +26,6 @@
26
26
  "exclude": [
27
27
  "node_modules",
28
28
  "dist",
29
+ "src/**/*.test.ts",
29
30
  ],
30
31
  }
package/typedoc.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "plugin": [
3
+ "typedoc-plugin-markdown",
4
+ "typedoc-vitepress-theme"
5
+ ],
6
+ "entryPoints": [
7
+ "./src/camera/index.ts",
8
+ "./src/sensor/index.ts",
9
+ "./src/plugin/index.ts",
10
+ "./src/manager/index.ts",
11
+ "./src/storage/index.ts",
12
+ "./src/observable/index.ts",
13
+ "./src/types.ts"
14
+ ],
15
+ "exclude": [
16
+ "**/*.test.ts",
17
+ "**/dist/**",
18
+ "**/node_modules/**"
19
+ ],
20
+ "externalPattern": [
21
+ "**/*.test.ts",
22
+ "**/dist/**",
23
+ "**/node_modules/**"
24
+ ],
25
+ "excludeExternals": true,
26
+ "excludeInternal": true,
27
+ "out": "./docs/api",
28
+ "docsRoot": "./docs",
29
+ "sidebar": {
30
+ "autoConfiguration": true,
31
+ "format": "vitepress",
32
+ "pretty": false,
33
+ "collapsed": true
34
+ },
35
+ "validation": {
36
+ "notExported": true,
37
+ "invalidLink": true,
38
+ "rewrittenLink": true,
39
+ "notDocumented": false,
40
+ "unusedMergeModuleWith": true
41
+ }
42
+ }
@@ -1,133 +0,0 @@
1
- import { SensorType } from './types.js';
2
- /**
3
- * Type guard for Motion sensors
4
- *
5
- * Narrows a SensorLike to MotionSensorLike for type-safe property access.
6
- *
7
- * @param sensor - The sensor to check
8
- *
9
- * @returns True if the sensor is a Motion sensor
10
- */
11
- export function isMotionSensor(sensor) {
12
- return sensor.type === SensorType.Motion;
13
- }
14
- /**
15
- * Type guard for Object detection sensors
16
- *
17
- * Narrows a SensorLike to ObjectSensorLike for type-safe property access.
18
- *
19
- * @param sensor - The sensor to check
20
- *
21
- * @returns True if the sensor is an Object sensor
22
- */
23
- export function isObjectSensor(sensor) {
24
- return sensor.type === SensorType.Object;
25
- }
26
- /**
27
- * Type guard for Audio sensors
28
- *
29
- * Narrows a SensorLike to AudioSensorLike for type-safe property access.
30
- *
31
- * @param sensor - The sensor to check
32
- *
33
- * @returns True if the sensor is an Audio sensor
34
- */
35
- export function isAudioSensor(sensor) {
36
- return sensor.type === SensorType.Audio;
37
- }
38
- /**
39
- * Type guard for Face detection sensors
40
- *
41
- * Narrows a SensorLike to FaceSensorLike for type-safe property access.
42
- *
43
- * @param sensor - The sensor to check
44
- *
45
- * @returns True if the sensor is a Face sensor
46
- */
47
- export function isFaceSensor(sensor) {
48
- return sensor.type === SensorType.Face;
49
- }
50
- /**
51
- * Type guard for License Plate detection sensors
52
- *
53
- * Narrows a SensorLike to LicensePlateSensorLike for type-safe property access.
54
- *
55
- * @param sensor - The sensor to check
56
- *
57
- * @returns True if the sensor is a License Plate sensor
58
- */
59
- export function isLicensePlateSensor(sensor) {
60
- return sensor.type === SensorType.LicensePlate;
61
- }
62
- /**
63
- * Type guard for Contact sensors
64
- *
65
- * Narrows a SensorLike to ContactSensorLike for type-safe property access.
66
- *
67
- * @param sensor - The sensor to check
68
- *
69
- * @returns True if the sensor is a Contact sensor
70
- */
71
- export function isContactSensor(sensor) {
72
- return sensor.type === SensorType.Contact;
73
- }
74
- /**
75
- * Type guard for Light controls
76
- *
77
- * Narrows a SensorLike to LightControlLike for type-safe property access.
78
- *
79
- * @param sensor - The sensor to check
80
- *
81
- * @returns True if the sensor is a Light control
82
- */
83
- export function isLightControl(sensor) {
84
- return sensor.type === SensorType.Light;
85
- }
86
- /**
87
- * Type guard for Siren controls
88
- *
89
- * Narrows a SensorLike to SirenControlLike for type-safe property access.
90
- *
91
- * @param sensor - The sensor to check
92
- *
93
- * @returns True if the sensor is a Siren control
94
- */
95
- export function isSirenControl(sensor) {
96
- return sensor.type === SensorType.Siren;
97
- }
98
- /**
99
- * Type guard for PTZ controls
100
- *
101
- * Narrows a SensorLike to PTZControlLike for type-safe property access.
102
- *
103
- * @param sensor - The sensor to check
104
- *
105
- * @returns True if the sensor is a PTZ control
106
- */
107
- export function isPTZControl(sensor) {
108
- return sensor.type === SensorType.PTZ;
109
- }
110
- /**
111
- * Type guard for Doorbell triggers
112
- *
113
- * Narrows a SensorLike to DoorbellTriggerLike for type-safe property access.
114
- *
115
- * @param sensor - The sensor to check
116
- *
117
- * @returns True if the sensor is a Doorbell trigger
118
- */
119
- export function isDoorbellTrigger(sensor) {
120
- return sensor.type === SensorType.Doorbell;
121
- }
122
- /**
123
- * Type guard for Battery info sensors
124
- *
125
- * Narrows a SensorLike to BatteryInfoLike for type-safe property access.
126
- *
127
- * @param sensor - The sensor to check
128
- *
129
- * @returns True if the sensor is a Battery info sensor
130
- */
131
- export function isBatteryInfo(sensor) {
132
- return sensor.type === SensorType.Battery;
133
- }
@@ -1,46 +0,0 @@
1
- /**
2
- * Charging state for battery
3
- */
4
- export var ChargingState;
5
- (function (ChargingState) {
6
- ChargingState["NotChargeable"] = "NOT_CHARGEABLE";
7
- ChargingState["NotCharging"] = "NOT_CHARGING";
8
- ChargingState["Charging"] = "CHARGING";
9
- ChargingState["Full"] = "FULL";
10
- })(ChargingState || (ChargingState = {}));
11
- // ========== Sensor Types ==========
12
- /**
13
- * Sensor Type Enum - identifies the type of sensor/control/trigger/info
14
- */
15
- export var SensorType;
16
- (function (SensorType) {
17
- // Detection Sensors
18
- SensorType["Motion"] = "motion";
19
- SensorType["Object"] = "object";
20
- SensorType["Audio"] = "audio";
21
- SensorType["Face"] = "face";
22
- SensorType["LicensePlate"] = "licensePlate";
23
- SensorType["Contact"] = "contact";
24
- // Controls
25
- SensorType["Light"] = "light";
26
- SensorType["Siren"] = "siren";
27
- SensorType["PTZ"] = "ptz";
28
- // Triggers
29
- SensorType["Doorbell"] = "doorbell";
30
- // Info
31
- SensorType["Battery"] = "battery";
32
- })(SensorType || (SensorType = {}));
33
- /**
34
- * Sensor Category - categorizes sensors by their behavior
35
- */
36
- export var SensorCategory;
37
- (function (SensorCategory) {
38
- /** Detection sensors (read-only, 1 provider) */
39
- SensorCategory["Sensor"] = "sensor";
40
- /** Bidirectional controls */
41
- SensorCategory["Control"] = "control";
42
- /** Event-based triggers */
43
- SensorCategory["Trigger"] = "trigger";
44
- /** Read-only hardware status */
45
- SensorCategory["Info"] = "info";
46
- })(SensorCategory || (SensorCategory = {}));
@@ -1,96 +0,0 @@
1
- /**
2
- * Service types that can be registered by plugins
3
- */
4
- export var ServiceType;
5
- (function (ServiceType) {
6
- /** Streaming URL generation */
7
- ServiceType["Streaming"] = "streaming";
8
- /** Snapshot capture */
9
- ServiceType["Snapshot"] = "snapshot";
10
- })(ServiceType || (ServiceType = {}));
11
- /**
12
- * Abstract base class for all camera services
13
- *
14
- * Plugins extend this class to implement custom service functionality.
15
- * The service communicates with the server via RPC, with the base class
16
- * handling online/offline status management.
17
- *
18
- * @example
19
- * ```typescript
20
- * class MyStreamingService extends Service implements StreamingService {
21
- * readonly type = ServiceType.Streaming;
22
- *
23
- * async streamUrl(sourceName: string): Promise<string> {
24
- * return `rtsp://my-camera/${sourceName}`;
25
- * }
26
- * }
27
- *
28
- * // In plugin:
29
- * const service = new MyStreamingService(camera.id, this.pluginId);
30
- * await camera.registerService(service);
31
- * ```
32
- */
33
- export class Service {
34
- /**
35
- * Camera ID this service is associated with
36
- */
37
- cameraId;
38
- /**
39
- * Plugin ID that provides this service
40
- */
41
- pluginId;
42
- /**
43
- * Internal online state
44
- */
45
- _online = false;
46
- /**
47
- * Callback for online status changes (set by runtime)
48
- */
49
- _onlineChangeFn;
50
- /**
51
- * Create a new service instance
52
- *
53
- * @param cameraId - ID of the camera this service is for
54
- *
55
- * @param pluginId - ID of the plugin providing this service
56
- */
57
- constructor(cameraId, pluginId) {
58
- this.cameraId = cameraId;
59
- this.pluginId = pluginId;
60
- }
61
- /**
62
- * Whether the service is currently online/available
63
- *
64
- * Setting this property notifies the server of the status change.
65
- */
66
- get online() {
67
- return this._online;
68
- }
69
- set online(value) {
70
- if (this._online !== value) {
71
- this._online = value;
72
- this._onlineChangeFn?.(value);
73
- }
74
- }
75
- /**
76
- * Internal initialization - sets up the online status callback
77
- *
78
- * Called by the runtime when the service is registered.
79
- *
80
- * @param onlineChangeFn - Callback to notify server of online status changes
81
- *
82
- * @internal
83
- */
84
- _init(onlineChangeFn) {
85
- this._onlineChangeFn = onlineChangeFn;
86
- }
87
- /**
88
- * Internal cleanup - called when service is unregistered
89
- *
90
- * @internal
91
- */
92
- _cleanup() {
93
- this._onlineChangeFn = undefined;
94
- this._online = false;
95
- }
96
- }
@@ -1,3 +0,0 @@
1
- export * from './base.js';
2
- export * from './services.js';
3
- export * from './types.js';
File without changes
File without changes