@camera.ui/sdk 0.0.2 → 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 +3 -3
  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,72 @@
1
+ import { Sensor, SensorType, SensorCategory } from './base.js';
2
+ /**
3
+ * Properties for switch controls
4
+ *
5
+ * @internal
6
+ */
7
+ export var SwitchProperty;
8
+ (function (SwitchProperty) {
9
+ /** Whether the switch is on */
10
+ SwitchProperty["On"] = "on";
11
+ })(SwitchProperty || (SwitchProperty = {}));
12
+ /**
13
+ * Generic on/off switch control. Override `setOn()` / `setOff()` to drive
14
+ * hardware and call `await super.setOn()` / `await super.setOff()` after
15
+ * success to sync the SDK state. For hardware-pushed updates, call the `super`
16
+ * methods from your event handler.
17
+ */
18
+ export class SwitchControl extends Sensor {
19
+ type = SensorType.Switch;
20
+ category = SensorCategory.Control;
21
+ constructor(name = 'Switch') {
22
+ super(name);
23
+ this._writeState({ [SwitchProperty.On]: false });
24
+ }
25
+ get on() {
26
+ return this.props.on;
27
+ }
28
+ /**
29
+ * Turn the switch on. Override to drive hardware and call `await super.setOn()`
30
+ * after success to sync the SDK state.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * await sw.setOn();
35
+ * ```
36
+ */
37
+ async setOn() {
38
+ this._writeState({ [SwitchProperty.On]: true });
39
+ }
40
+ /**
41
+ * Turn the switch off. Override to drive hardware and call `await super.setOff()`
42
+ * after success to sync the SDK state.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * await sw.setOff();
47
+ * ```
48
+ */
49
+ async setOff() {
50
+ this._writeState({ [SwitchProperty.On]: false });
51
+ }
52
+ /**
53
+ * Cross-process consumer entry point. Dispatches writable properties
54
+ * to semantic methods so plugin overrides (hardware actions) are honored.
55
+ * Unknown properties are ignored — only `On` is externally writable.
56
+ *
57
+ * @param property - Property name to write.
58
+ *
59
+ * @param value - New value for the property.
60
+ *
61
+ * @internal
62
+ */
63
+ async updateValue(property, value) {
64
+ if (property === SwitchProperty.On) {
65
+ if (value)
66
+ await this.setOn();
67
+ else
68
+ await this.setOff();
69
+ }
70
+ // Unknown / non-writable property — ignored.
71
+ }
72
+ }
@@ -0,0 +1,52 @@
1
+ import { Sensor, SensorType, SensorCategory } from './base.js';
2
+ /**
3
+ * Properties for temperature sensors
4
+ *
5
+ * @internal
6
+ */
7
+ export var TemperatureProperty;
8
+ (function (TemperatureProperty) {
9
+ /** Current temperature in degrees Celsius */
10
+ TemperatureProperty["Current"] = "current";
11
+ })(TemperatureProperty || (TemperatureProperty = {}));
12
+ /** Temperature info sensor. Reports current temperature in °C. */
13
+ export class TemperatureInfo extends Sensor {
14
+ type = SensorType.Temperature;
15
+ category = SensorCategory.Info;
16
+ constructor(name = 'Temperature') {
17
+ super(name);
18
+ this._writeState({ [TemperatureProperty.Current]: 20 });
19
+ }
20
+ get current() {
21
+ return this.props.current;
22
+ }
23
+ /**
24
+ * Report a new temperature reading. Clamped to [-270, 100] °C.
25
+ *
26
+ * @param value - Temperature reading in degrees Celsius.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * temperature.setCurrent(21.5);
31
+ * ```
32
+ */
33
+ setCurrent(value) {
34
+ this._writeState({ [TemperatureProperty.Current]: Math.max(-270, Math.min(100, value)) });
35
+ }
36
+ /**
37
+ * Read-only sensor: external writes are ignored. Reading via `setCurrent` is plugin-only.
38
+ *
39
+ * Called by the cross-process plugin host when a generic property write is received.
40
+ * Temperature sensors have no externally writable properties, so the parameters are
41
+ * unused (underscore-prefixed) and the call is a no-op.
42
+ *
43
+ * @param _property - Unused — temperature sensors expose no writable properties.
44
+ *
45
+ * @param _value - Unused — temperature sensors expose no writable properties.
46
+ *
47
+ * @internal
48
+ */
49
+ updateValue(_property, _value) {
50
+ // No-op — temperature is reported by the plugin, not set externally.
51
+ }
52
+ }
@@ -1,2 +1 @@
1
- export * from './schema.js';
2
- export * from './storages.js';
1
+ export {};
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,77 @@
1
+ import { createRequire } from 'node:module';
2
+ import { defineConfig } from 'vitepress';
3
+
4
+ const require = createRequire(import.meta.url);
5
+ const typedocSidebar = require('../api/typedoc-sidebar.json');
6
+
7
+ // https://vitepress.dev/reference/site-config
8
+ export default defineConfig({
9
+ srcDir: '.',
10
+ base: '/sdk/node/',
11
+ title: 'camera.ui Node SDK',
12
+ description: 'TypeScript SDK for building camera.ui plugins',
13
+ lastUpdated: true,
14
+ head: [
15
+ ['link', { rel: 'icon', type: 'image/x-icon', sizes: '32x32', href: '/sdk/node/favicon.ico' }],
16
+ ['link', { rel: 'icon', type: 'image/x-icon', sizes: '16x16', href: '/sdk/node/favicon-16.ico' }],
17
+ ['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/sdk/node/apple-touch-icon.png' }],
18
+ ['meta', { name: 'theme-color', content: '#df2a4c' }],
19
+ ],
20
+ themeConfig: {
21
+ logo: '/logo.svg',
22
+
23
+ // typedocSidebar entries are alphabetical:
24
+ // [0] camera, [1] manager, [2] observable, [3] plugin,
25
+ // [4] sensor, [5] storage, [6] types
26
+ sidebar: [
27
+ {
28
+ text: 'Plugin API',
29
+ items: typedocSidebar[3].items,
30
+ },
31
+ {
32
+ text: 'Camera',
33
+ items: typedocSidebar[0].items,
34
+ },
35
+ {
36
+ text: 'Sensors',
37
+ items: typedocSidebar[4].items,
38
+ },
39
+ {
40
+ text: 'Storage & Schema',
41
+ items: typedocSidebar[5].items,
42
+ },
43
+ {
44
+ text: 'Manager',
45
+ items: typedocSidebar[1].items,
46
+ },
47
+ {
48
+ text: 'Observable',
49
+ items: typedocSidebar[2].items,
50
+ },
51
+ {
52
+ text: 'Types',
53
+ items: typedocSidebar[6].items,
54
+ },
55
+ {
56
+ text: 'Plugin Guide',
57
+ link: '/examples/getting-started',
58
+ },
59
+ ],
60
+
61
+ search: {
62
+ provider: 'local',
63
+ },
64
+
65
+ socialLinks: [
66
+ { icon: 'github', link: 'https://github.com/seydx/camera.ui' },
67
+ { icon: 'discord', link: 'https://discord.gg/bBGnGcbz8N' },
68
+ {
69
+ icon: {
70
+ svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path fill="currentColor" d="M20 10.04a2.18 2.18 0 0 0-3.7-1.55a10.7 10.7 0 0 0-5.79-1.83l.99-4.65l3.23.69a1.55 1.55 0 1 0 .15-.74l-3.59-.76a.37.37 0 0 0-.44.28l-1.1 5.18a10.74 10.74 0 0 0-5.87 1.83a2.19 2.19 0 1 0-2.41 3.59a4 4 0 0 0-.05.66c0 3.36 3.91 6.09 8.74 6.09s8.74-2.73 8.74-6.09a4 4 0 0 0-.05-.66A2.19 2.19 0 0 0 20 10.04m-15 1.56a1.56 1.56 0 1 1 1.56 1.56A1.56 1.56 0 0 1 5 11.6m8.71 4.13c-1.07.81-2.39 1.21-3.71 1.16a5.85 5.85 0 0 1-3.71-1.16a.4.4 0 1 1 .55-.59A4.94 4.94 0 0 0 10 16.1a4.94 4.94 0 0 0 3.16-.96a.41.41 0 0 1 .57.04a.41.41 0 0 1-.02.55m-.16-2.55a1.56 1.56 0 1 1 1.56-1.56a1.56 1.56 0 0 1-1.55 1.56z"/></svg>',
71
+ },
72
+ link: 'https://www.reddit.com/r/cameraui/',
73
+ ariaLabel: 'Reddit',
74
+ },
75
+ ],
76
+ },
77
+ });
@@ -0,0 +1,5 @@
1
+ import DefaultTheme from 'vitepress/theme';
2
+
3
+ import './style.css';
4
+
5
+ export default DefaultTheme;
@@ -0,0 +1,117 @@
1
+ @import 'vitepress/dist/client/theme-default/styles/vars.css';
2
+
3
+ /* camera.ui brand colors — mirror ui/src/plugins/preset.ts */
4
+ :root {
5
+ --cui-primary-50: #fdf4f6;
6
+ --cui-primary-100: #f7ccd4;
7
+ --cui-primary-200: #f1a3b2;
8
+ --cui-primary-300: #eb7b90;
9
+ --cui-primary-400: #e5526e;
10
+ --cui-primary-500: #df2a4c;
11
+ --cui-primary-600: #be2441;
12
+ --cui-primary-700: #9c1d35;
13
+ --cui-primary-800: #7b172a;
14
+ --cui-primary-900: #59111e;
15
+ --cui-primary-950: #380b13;
16
+ }
17
+
18
+ :root {
19
+ --vp-c-brand-1: var(--cui-primary-500);
20
+ --vp-c-brand-2: var(--cui-primary-600);
21
+ --vp-c-brand-3: var(--cui-primary-700);
22
+ --vp-c-brand-soft: rgba(223, 42, 76, 0.14);
23
+
24
+ --vp-c-default-1: var(--vp-c-gray-1);
25
+ --vp-c-default-2: var(--vp-c-gray-2);
26
+ --vp-c-default-3: var(--vp-c-gray-3);
27
+ --vp-c-default-soft: var(--vp-c-gray-soft);
28
+
29
+ --vp-button-brand-border: transparent;
30
+ --vp-button-brand-text: #ffffff;
31
+ --vp-button-brand-bg: var(--cui-primary-500);
32
+ --vp-button-brand-hover-border: transparent;
33
+ --vp-button-brand-hover-text: #ffffff;
34
+ --vp-button-brand-hover-bg: var(--cui-primary-600);
35
+ --vp-button-brand-active-border: transparent;
36
+ --vp-button-brand-active-text: #ffffff;
37
+ --vp-button-brand-active-bg: var(--cui-primary-700);
38
+
39
+ --vp-home-hero-name-color: transparent;
40
+ --vp-home-hero-name-background: linear-gradient(
41
+ 135deg,
42
+ var(--cui-primary-500) 0%,
43
+ var(--cui-primary-700) 100%
44
+ );
45
+ --vp-home-hero-image-background-image: linear-gradient(
46
+ 135deg,
47
+ rgba(223, 42, 76, 0.32) 0%,
48
+ rgba(123, 23, 42, 0.32) 100%
49
+ );
50
+ --vp-home-hero-image-filter: blur(56px);
51
+
52
+ --vp-custom-block-tip-border: transparent;
53
+ --vp-custom-block-tip-text: var(--cui-primary-700);
54
+ --vp-custom-block-tip-bg: var(--vp-c-brand-soft);
55
+ --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
56
+ }
57
+
58
+ /* dark surface palette mirrors ui preset.ts (neutral grey, not slate) */
59
+ .dark {
60
+ --cui-surface-0: #ffffff;
61
+ --cui-surface-50: #f5f5f5;
62
+ --cui-surface-100: #d1d1d1;
63
+ --cui-surface-200: #adadad;
64
+ --cui-surface-300: #898989;
65
+ --cui-surface-400: #646464;
66
+ --cui-surface-500: #404040;
67
+ --cui-surface-600: #363636;
68
+ --cui-surface-700: #2d2d2d;
69
+ --cui-surface-800: #232323;
70
+ --cui-surface-850: #1d1d1d;
71
+ --cui-surface-900: #1a1a1a;
72
+ --cui-surface-925: #161616;
73
+ --cui-surface-950: #101010;
74
+ --cui-surface-1000: #0d0d0d;
75
+
76
+ --vp-c-brand-1: var(--cui-primary-400);
77
+ --vp-c-brand-2: var(--cui-primary-300);
78
+ --vp-c-brand-3: var(--cui-primary-200);
79
+ --vp-c-brand-soft: rgba(229, 82, 110, 0.16);
80
+
81
+ --vp-c-bg: var(--cui-surface-900);
82
+ --vp-c-bg-alt: var(--cui-surface-950);
83
+ --vp-c-bg-elv: var(--cui-surface-800);
84
+ --vp-c-bg-soft: var(--cui-surface-850);
85
+
86
+ --vp-c-divider: var(--cui-surface-800);
87
+ --vp-c-gutter: var(--cui-surface-950);
88
+ --vp-c-border: var(--cui-surface-700);
89
+
90
+ --vp-c-default-1: var(--cui-surface-800);
91
+ --vp-c-default-2: var(--cui-surface-700);
92
+ --vp-c-default-3: var(--cui-surface-600);
93
+ --vp-c-default-soft: rgba(64, 64, 64, 0.4);
94
+
95
+ --vp-c-text-1: rgba(255, 255, 255, 0.92);
96
+ --vp-c-text-2: rgba(255, 255, 255, 0.66);
97
+ --vp-c-text-3: rgba(255, 255, 255, 0.42);
98
+
99
+ --vp-code-bg: var(--cui-surface-925);
100
+ --vp-code-block-bg: var(--cui-surface-925);
101
+
102
+ --vp-button-brand-text: #ffffff;
103
+ --vp-button-brand-bg: var(--cui-primary-500);
104
+ --vp-button-brand-hover-bg: var(--cui-primary-400);
105
+ --vp-button-brand-active-bg: var(--cui-primary-600);
106
+
107
+ --vp-custom-block-tip-text: var(--cui-primary-200);
108
+ }
109
+
110
+ /* Pull search/box accents in line with brand */
111
+ .dark .DocSearch {
112
+ --docsearch-primary-color: var(--cui-primary-400);
113
+ }
114
+
115
+ .DocSearch {
116
+ --docsearch-primary-color: var(--cui-primary-500);
117
+ }
package/docs/index.md ADDED
@@ -0,0 +1,16 @@
1
+ # camera.ui Node SDK
2
+
3
+ TypeScript SDK for building plugins that extend [camera.ui](https://github.com/seydx/camera.ui) — add cameras, run motion / object / face / license-plate / audio detection, deliver notifications, and more.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @camera.ui/sdk
9
+ ```
10
+
11
+ ## Next steps
12
+
13
+ - **[Plugin Guide](/examples/getting-started)** — everything you need to ship a Node plugin in one page: contract, lifecycle, sensors, storage, optional interfaces.
14
+ - **[API Reference](/api/)** — module-by-module reference auto-generated from JSDoc.
15
+
16
+ For complete production plugins to study, see [`plugins/`](https://github.com/seydx/camera.ui/tree/main/plugins) in the camera.ui repo.
package/docs/logo.png ADDED
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 233.63 233.63"><defs><style>.cls-1{fill:url(#dark_wine);}.cls-2{fill:url(#light_wine);}.cls-3{fill:none;stroke:#000;stroke-miterlimit:10;opacity:0;}.cls-4{fill:#c5c6c8;}.cls-5{fill:#1a1e21;stroke:#3a3a3a;stroke-width:2px;}.cls-6{fill:#fff;}</style><linearGradient id="dark_wine" x1="87.36" y1="158.67" x2="87.36" y2="59.85" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#730000"/><stop offset="0.49" stop-color="#a51733"/></linearGradient><linearGradient id="light_wine" x1="113.06" y1="197.59" x2="113.06" y2="80.87" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f44a6b"/><stop offset="0.28" stop-color="#df294c"/></linearGradient></defs><g id="CameraUI_U"><path id="U_Left" class="cls-1" d="M47.05,119.47s7.58,16,14.12,23.42a45.28,45.28,0,0,0,16.37,11.86A49.46,49.46,0,0,0,99,158.62c9.43-.46,20.55-3.87,29.24-11.86-3.9,2.5-9.87,5.1-15.9,4.77a25.63,25.63,0,0,1-18.38-9.09c-9.39-10.31-7.62-28.35-7.75-32.68-.35-11.42.77-21.92-1.76-36.19-.46-2.64-1.79-5.19-4.55-8-1.83-1.86-8.4-5.75-13.42-5.74-7.31,0-12.95,3.71-15.38,7.84-2,3.41-3.06,4.22-4.23,25.08a217.23,217.23,0,0,0,.22,26.76Z" transform="translate(0.5 0.5)"/><path id="U_Right" class="cls-2" d="M144.12,89.6a16.24,16.24,0,0,1,4.06-4.9c4.16-3.4,9-3.67,10.92-3.82a19.7,19.7,0,0,1,12.53,4.58c1.19,1,6.11,5.58,7.13,17.29.73,8.51,3.31,65.93-37,87.14-4.22,2.22-18,9.25-35.66,7.38a62.43,62.43,0,0,1-20.8-6.11,65.8,65.8,0,0,1-18.89-14.23c-20.21-21.67-19.36-57.46-19.36-57.46s7.58,16,14.12,23.42a45.28,45.28,0,0,0,16.37,11.86A49.46,49.46,0,0,0,99,158.62c11.66-.57,25.93-5.64,35-18.32C143.52,126.8,138.46,100.51,144.12,89.6Z" transform="translate(0.5 0.5)"/></g><g id="CameraUI_Lens"><circle id="ellipse" class="cls-3" cx="116.81" cy="116.81" r="116.31"/><g id="lens"><circle id="lens_bg" class="cls-4" cx="159.13" cy="58.39" r="18.66"/><path id="lens_inner" class="cls-5" d="M169.64,58.31a11,11,0,1,1-22,0c0-6.08,4.93-11.86,11-11.86S169.64,52.23,169.64,58.31Z" transform="translate(0.5 0.5)"/><g id="reflections"><ellipse id="dot_1" class="cls-6" cx="174.36" cy="53.69" rx="1.84" ry="1.42"/><ellipse id="dot_2" class="cls-6" cx="174.36" cy="57.08" rx="1.84" ry="1.42"/><ellipse id="dot_3" class="cls-6" cx="174.36" cy="60.46" rx="1.84" ry="1.42"/><circle id="dot_4" class="cls-6" cx="164.09" cy="63.77" r="1.66"/><path id="wide_1" class="cls-6" d="M156.63,48.9c-1.07-.88-5.52,3.09-6.31,5.43a1.53,1.53,0,0,0,0,1.26c.43.69,1.73.61,2.19.54,2.68-.44,4.71-4.09,4.8-4.37A3.21,3.21,0,0,0,156.63,48.9Z" transform="translate(0.5 0.5)"/></g></g></g></svg>
@@ -0,0 +1,7 @@
1
+ # Plugin Guide
2
+
3
+ Everything you need to ship a camera.ui plugin in one page: contract, lifecycle, sensors, storage, optional interfaces (discovery, notifier, detection), and inter-plugin communication.
4
+
5
+ [Read the guide →](./getting-started.md)
6
+
7
+ For complete production plugins to read alongside, see [`plugins/`](https://github.com/seydx/camera.ui/tree/main/plugins) in the camera.ui repo.