@camstack/types 1.2.41 → 1.2.43
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/dist/addon.js +1 -1
- package/dist/addon.mjs +1 -1
- package/dist/canonical-hash-7nfBbEqR.mjs +35 -0
- package/dist/canonical-hash-BcZHRHIx.js +40 -0
- package/dist/cap-call-context.d.ts +26 -0
- package/dist/capabilities/index.d.ts +5 -5
- package/dist/capabilities/notification-rules.cap.d.ts +41 -0
- package/dist/capabilities/pipeline-analytics.cap.d.ts +92 -4
- package/dist/capabilities/pipeline-orchestrator.cap.d.ts +149 -0
- package/dist/capabilities/pipeline-runner.cap.d.ts +119 -1
- package/dist/capabilities/platform-probe.cap.d.ts +3 -3
- package/dist/capabilities/privacy-mask.cap.d.ts +69 -9
- package/dist/capabilities/recording.cap.d.ts +30 -0
- package/dist/capabilities/snapshot.cap.d.ts +1 -1
- package/dist/capabilities/stream-broker.cap.d.ts +304 -0
- package/dist/capabilities/stream-params.cap.d.ts +8 -4
- package/dist/device/device-profile.d.ts +12 -4
- package/dist/device/system-mirror.d.ts +11 -0
- package/dist/encode-profile.d.ts +2 -0
- package/dist/ffmpeg/encode-defaults.d.ts +107 -0
- package/dist/ffmpeg/hwaccel.d.ts +98 -0
- package/dist/ffmpeg/invocation.d.ts +348 -0
- package/dist/ffmpeg/process.d.ts +135 -0
- package/dist/ffmpeg/sharing-key.d.ts +91 -0
- package/dist/generated/addon-api.d.ts +92 -4
- package/dist/generated/device-proxy.d.ts +2 -2
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/system-proxy.d.ts +2 -2
- package/dist/index.d.ts +7 -0
- package/dist/index.js +2069 -42
- package/dist/index.mjs +2006 -43
- package/dist/interfaces/camera-switches.d.ts +375 -0
- package/dist/interfaces/inference-engine.d.ts +24 -3
- package/dist/interfaces/ops-log.d.ts +4 -0
- package/dist/interfaces/pipeline-runner-capability.d.ts +9 -1
- package/dist/node.d.ts +2 -0
- package/dist/node.js +270 -36
- package/dist/node.mjs +269 -36
- package/dist/pipeline/native-lease.d.ts +150 -0
- package/dist/{sleep-DTce7-ch.js → sleep-Bx9IIoT0.js} +43 -1
- package/dist/{sleep-CXimb854.mjs → sleep-DtstvzWm.mjs} +38 -2
- package/dist/utils/addon-id.d.ts +30 -0
- package/package.json +1 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE native-frame **lease** knobs — TTL, RAM budget and demand window for the
|
|
3
|
+
* decode worker's native-resolution frame retention.
|
|
4
|
+
*
|
|
5
|
+
* ## Why they live here and not in the addon that reads them
|
|
6
|
+
*
|
|
7
|
+
* The WRITER is `pipeline-orchestrator` (the cluster-wide settings authority);
|
|
8
|
+
* the READER is a private child process of `addon-pipeline`'s pipeline-runner.
|
|
9
|
+
* Addons never import each other, so a key owned by either side would have to
|
|
10
|
+
* be hand-copied by the other — and a hand-copied key is how a setting silently
|
|
11
|
+
* stops arriving while both sides still look correct. Same reasoning, same
|
|
12
|
+
* placement as `detail-crop.ts` (D52's "one cluster-wide orchestrator setting").
|
|
13
|
+
*
|
|
14
|
+
* ## Why cluster-wide and not per-node
|
|
15
|
+
*
|
|
16
|
+
* The lease is a per-decode-worker RAM window. Its purpose — the late
|
|
17
|
+
* cross-process native crop landing on a full-resolution frame rather than the
|
|
18
|
+
* ≤640 detection fallback — is a property of the PIPELINE, not of a node's
|
|
19
|
+
* hardware: a per-node TTL would mean the same camera produces different crop
|
|
20
|
+
* quality depending on which node the balancer placed it on, and nobody could
|
|
21
|
+
* tell that from the stored media. Node-level RAM pressure is already handled
|
|
22
|
+
* by the per-session budget ceiling, which is itself one of these knobs.
|
|
23
|
+
*
|
|
24
|
+
* ## What each knob costs
|
|
25
|
+
*
|
|
26
|
+
* A retained frame is a full NATIVE-resolution copy in system RAM. With the
|
|
27
|
+
* default pinned-RGB24 lease path (`CAMSTACK_SESSION_PINNED_RGB_CROP`, on):
|
|
28
|
+
* 4K ≈ 24.9 MB/frame, 1080p ≈ 6.2 MB/frame. On the YUV420P path (flag off, and
|
|
29
|
+
* for software-decoded sessions): 4K ≈ 12.4 MB, 1080p ≈ 3.1 MB. Worst-case
|
|
30
|
+
* resident RAM for ONE busy camera ≈ frameBytes × deliveredFps × ttlSeconds,
|
|
31
|
+
* clamped by the budget ceiling. See `docs/design/decode-path.md` → "Lease
|
|
32
|
+
* admission" for what actually gets admitted.
|
|
33
|
+
*/
|
|
34
|
+
import { z } from 'zod';
|
|
35
|
+
import type { HydratedSettingsView } from './detail-crop.js';
|
|
36
|
+
/**
|
|
37
|
+
* Store identity of the lease knobs in `pipeline-orchestrator`'s GLOBAL
|
|
38
|
+
* (cluster-wide) settings. Keys are unique across that addon's whole schema, so
|
|
39
|
+
* the reader can walk every section instead of trusting the section id.
|
|
40
|
+
*/
|
|
41
|
+
export declare const NATIVE_LEASE_SECTION_ID = "native-lease";
|
|
42
|
+
export declare const NATIVE_LEASE_TTL_KEY = "nativeLeaseTtlMs";
|
|
43
|
+
export declare const NATIVE_LEASE_BUDGET_KEY = "nativeLeaseBudgetMb";
|
|
44
|
+
export declare const NATIVE_LEASE_ACTIVITY_KEY = "nativeLeaseActivityMs";
|
|
45
|
+
export declare const NATIVE_LEASE_ADMISSION_KEY = "nativeLeaseAdmission";
|
|
46
|
+
/**
|
|
47
|
+
* WHICH delivered frames the decode worker retains a native copy of.
|
|
48
|
+
*
|
|
49
|
+
* - `all` — every frame the worker delivered to the runner. The shipped
|
|
50
|
+
* behaviour, and the only correct one if something can ask for a crop of a
|
|
51
|
+
* frame the runner never sent to inference.
|
|
52
|
+
* - `inferred` — only the frames the runner ADMITTED to its detection queue.
|
|
53
|
+
* A native-crop request always names a `frameId` that rode an inference
|
|
54
|
+
* result, so that is the only set a request can name. How much it drops is
|
|
55
|
+
* the two-plane governor's admit ratio and nothing else: measured at ~50% on
|
|
56
|
+
* this cluster, not the ~80% the design sketch assumed, because the governor
|
|
57
|
+
* was not throttling as hard as the sketch supposed. Read
|
|
58
|
+
* `leaseAdmitted`/`leaseOffered` off the metrics line for the camera in front
|
|
59
|
+
* of you rather than quoting a number from here. The newest delivered frame is
|
|
60
|
+
* croppable regardless — it is still the worker's reserved slot, not a lease —
|
|
61
|
+
* which covers the one-frame race between a mark and the supersede that
|
|
62
|
+
* consumes it.
|
|
63
|
+
*/
|
|
64
|
+
export declare const NativeLeaseAdmissionSchema: z.ZodEnum<{
|
|
65
|
+
all: "all";
|
|
66
|
+
inferred: "inferred";
|
|
67
|
+
}>;
|
|
68
|
+
export type NativeLeaseAdmission = z.infer<typeof NativeLeaseAdmissionSchema>;
|
|
69
|
+
/**
|
|
70
|
+
* Operator-tunable native-lease settings. Bounds are enforced HERE (not only in
|
|
71
|
+
* the slider) because the value also travels to a forked child process, where a
|
|
72
|
+
* junk number would silently become a 0-length or unbounded retention window.
|
|
73
|
+
*/
|
|
74
|
+
export declare const NativeLeaseSettingsSchema: z.ZodObject<{
|
|
75
|
+
ttlMs: z.ZodNumber;
|
|
76
|
+
budgetMb: z.ZodNumber;
|
|
77
|
+
activityMs: z.ZodNumber;
|
|
78
|
+
admission: z.ZodEnum<{
|
|
79
|
+
all: "all";
|
|
80
|
+
inferred: "inferred";
|
|
81
|
+
}>;
|
|
82
|
+
}, z.core.$strip>;
|
|
83
|
+
export type NativeLeaseSettings = z.infer<typeof NativeLeaseSettingsSchema>;
|
|
84
|
+
/**
|
|
85
|
+
* The values in force when the operator has set nothing — byte-for-byte the
|
|
86
|
+
* constants the decode worker shipped with as env-var defaults, so making these
|
|
87
|
+
* settings changed no behaviour on the day it landed.
|
|
88
|
+
*/
|
|
89
|
+
export declare const DEFAULT_NATIVE_LEASE_SETTINGS: NativeLeaseSettings;
|
|
90
|
+
/**
|
|
91
|
+
* Only the knobs the operator has ACTUALLY set. Distinguishing "set" from
|
|
92
|
+
* "absent" is what makes the documented precedence (setting > env > default)
|
|
93
|
+
* expressible: an absent knob leaves the env-var escape hatch working.
|
|
94
|
+
*/
|
|
95
|
+
export type NativeLeaseSettingsOverride = Partial<NativeLeaseSettings>;
|
|
96
|
+
/** Slider bounds for the operator-facing knobs (orchestrator settings UI). */
|
|
97
|
+
export declare const NATIVE_LEASE_TTL_FIELD: {
|
|
98
|
+
readonly min: 250;
|
|
99
|
+
readonly max: 10000;
|
|
100
|
+
readonly step: 50;
|
|
101
|
+
readonly default: number;
|
|
102
|
+
};
|
|
103
|
+
export declare const NATIVE_LEASE_BUDGET_FIELD: {
|
|
104
|
+
readonly min: 0;
|
|
105
|
+
readonly max: 4096;
|
|
106
|
+
readonly step: 64;
|
|
107
|
+
readonly default: number;
|
|
108
|
+
};
|
|
109
|
+
export declare const NATIVE_LEASE_ACTIVITY_FIELD: {
|
|
110
|
+
readonly min: 0;
|
|
111
|
+
readonly max: 120000;
|
|
112
|
+
readonly step: 1000;
|
|
113
|
+
readonly default: number;
|
|
114
|
+
};
|
|
115
|
+
/** Select options for the admission knob (orchestrator settings UI). */
|
|
116
|
+
export declare const NATIVE_LEASE_ADMISSION_FIELD: {
|
|
117
|
+
readonly options: readonly [{
|
|
118
|
+
readonly value: "all";
|
|
119
|
+
readonly label: "Every delivered frame";
|
|
120
|
+
}, {
|
|
121
|
+
readonly value: "inferred";
|
|
122
|
+
readonly label: "Only frames sent to inference";
|
|
123
|
+
}];
|
|
124
|
+
readonly default: "all" | "inferred";
|
|
125
|
+
};
|
|
126
|
+
/** The four knobs, as a key union. */
|
|
127
|
+
export type NativeLeaseKnob = keyof NativeLeaseSettings;
|
|
128
|
+
/** The three knobs whose value is a bounded integer (everything but `admission`). */
|
|
129
|
+
export type NativeLeaseNumberKnob = 'ttlMs' | 'budgetMb' | 'activityMs';
|
|
130
|
+
/**
|
|
131
|
+
* Narrow a FLAT settings record to the knobs the operator set.
|
|
132
|
+
*
|
|
133
|
+
* Per-FIELD parse, deliberately: a junk TTL must not also discard a valid
|
|
134
|
+
* budget. An absent, out-of-bounds or default-valued knob is OMITTED (not
|
|
135
|
+
* clamped, not defaulted) so the caller can still fall through to the env
|
|
136
|
+
* override — clamping here would turn a typo into a value nobody chose. See
|
|
137
|
+
* {@link readKnob} for why the default counts as unset.
|
|
138
|
+
*/
|
|
139
|
+
export declare function readNativeLeaseOverride(config: Readonly<Record<string, unknown>>): NativeLeaseSettingsOverride;
|
|
140
|
+
/**
|
|
141
|
+
* Extract the operator's lease overrides from an
|
|
142
|
+
* `addon-settings.getGlobalSettings` payload.
|
|
143
|
+
*
|
|
144
|
+
* Walks EVERY section rather than looking inside {@link NATIVE_LEASE_SECTION_ID}
|
|
145
|
+
* alone: the keys are unique across the addon's schema, and a section rename
|
|
146
|
+
* must not silently revert the whole cluster to the defaults. A `null` payload
|
|
147
|
+
* (addon mid-boot) means "operator set nothing" — the env/default fallback then
|
|
148
|
+
* applies, which is the correct read of "I could not ask".
|
|
149
|
+
*/
|
|
150
|
+
export declare function pickNativeLeaseOverride(view: HydratedSettingsView | null): NativeLeaseSettingsOverride;
|
|
@@ -1934,9 +1934,38 @@ var CAP_NODE_PIN_CONTEXT_KEY = "__camstackNodePin";
|
|
|
1934
1934
|
/**
|
|
1935
1935
|
* Build the tRPC request options that pin a single capability call to `nodeId`.
|
|
1936
1936
|
* Pass as the second argument to `.query(input, …)` / `.mutate(input, …)`.
|
|
1937
|
+
*
|
|
1938
|
+
* ## The id is normalised here, and it has to be
|
|
1939
|
+
*
|
|
1940
|
+
* A forked addon reads its own node from `ctx.kernel.localNodeId`, and inside a
|
|
1941
|
+
* worker that value is a RUNNER id — `hub/export-hap`, not `hub`. Routing
|
|
1942
|
+
* compares a pin against real node ids, so such a pin matches nothing and the
|
|
1943
|
+
* call fails with `no provider registered for cap "…"`. The local-first
|
|
1944
|
+
* resolver already guarded against this (`localNodeId.split('/')[0]`), which
|
|
1945
|
+
* made the hazard invisible: unpinned calls worked, and only an explicit pin —
|
|
1946
|
+
* the thing you reach for when you specifically need THIS node — silently
|
|
1947
|
+
* addressed a node that does not exist.
|
|
1948
|
+
*
|
|
1949
|
+
* Cost of it being missing: `addon-export-hap` pinned `decoder.getInfo` to its
|
|
1950
|
+
* own node to read the host's hardware-decode backend. It never once answered,
|
|
1951
|
+
* so every HomeKit egress transcode decoded in SOFTWARE — including 4K H.265 —
|
|
1952
|
+
* while D67's whole premise was that the decoder addon is the authority on
|
|
1953
|
+
* hardware. The warn said `decoding in SOFTWARE` and read as "this node has no
|
|
1954
|
+
* hardware", which was false.
|
|
1955
|
+
*
|
|
1956
|
+
* Normalising in the ONE constructor fixes every caller at once, which is why
|
|
1957
|
+
* it is here and not at the call sites.
|
|
1937
1958
|
*/
|
|
1938
1959
|
function nodePin(nodeId) {
|
|
1939
|
-
return { context: { [CAP_NODE_PIN_CONTEXT_KEY]: nodeId } };
|
|
1960
|
+
return { context: { [CAP_NODE_PIN_CONTEXT_KEY]: toNodeId(nodeId) } };
|
|
1961
|
+
}
|
|
1962
|
+
/**
|
|
1963
|
+
* A runner id is `<nodeId>/<addonId>`; a node id has no slash. Taking the head
|
|
1964
|
+
* is idempotent, so passing an already-clean id costs nothing.
|
|
1965
|
+
*/
|
|
1966
|
+
function toNodeId(idOrRunnerId) {
|
|
1967
|
+
const head = idOrRunnerId.split("/")[0];
|
|
1968
|
+
return head === void 0 || head.length === 0 ? idOrRunnerId : head;
|
|
1940
1969
|
}
|
|
1941
1970
|
/**
|
|
1942
1971
|
* Read a per-call node pin out of a tRPC `op.context` (transport side).
|
|
@@ -3103,6 +3132,8 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3103
3132
|
updateRule: (input) => dispatch("notification-rules", "notificationRules", "updateRule", "mutation", input),
|
|
3104
3133
|
deleteRule: (input) => dispatch("notification-rules", "notificationRules", "deleteRule", "mutation", input),
|
|
3105
3134
|
setRuleEnabled: (input) => dispatch("notification-rules", "notificationRules", "setRuleEnabled", "mutation", input),
|
|
3135
|
+
listDeviceMutes: (input) => dispatch("notification-rules", "notificationRules", "listDeviceMutes", "query", input),
|
|
3136
|
+
setDeviceMuted: (input) => dispatch("notification-rules", "notificationRules", "setDeviceMuted", "mutation", input),
|
|
3106
3137
|
testRule: (input) => dispatch("notification-rules", "notificationRules", "testRule", "mutation", input),
|
|
3107
3138
|
getConditionCatalog: (input) => dispatch("notification-rules", "notificationRules", "getConditionCatalog", "query", input),
|
|
3108
3139
|
getHistory: (input) => dispatch("notification-rules", "notificationRules", "getHistory", "query", input),
|
|
@@ -3153,6 +3184,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3153
3184
|
pruneTracksBefore: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneTracksBefore", "mutation", input),
|
|
3154
3185
|
wipeAllAnalytics: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "wipeAllAnalytics", "mutation", input),
|
|
3155
3186
|
deleteTracks: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "deleteTracks", "mutation", input),
|
|
3187
|
+
setTrackFlags: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "setTrackFlags", "mutation", input),
|
|
3156
3188
|
getEventStoreFootprint: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventStoreFootprint", "query", input),
|
|
3157
3189
|
pruneEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneEvents", "mutation", input),
|
|
3158
3190
|
deleteDeviceEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "deleteDeviceEvents", "mutation", input),
|
|
@@ -3177,6 +3209,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3177
3209
|
privacyMask: {
|
|
3178
3210
|
getOptions: (input) => dispatch("privacy-mask", "privacyMask", "getOptions", "query", input),
|
|
3179
3211
|
setMask: (input) => dispatch("privacy-mask", "privacyMask", "setMask", "mutation", input),
|
|
3212
|
+
setAudioEnabled: (input) => dispatch("privacy-mask", "privacyMask", "setAudioEnabled", "mutation", input),
|
|
3180
3213
|
getStatus: (input) => dispatch("privacy-mask", "privacyMask", "getStatus", "query", input)
|
|
3181
3214
|
},
|
|
3182
3215
|
ptz: {
|
|
@@ -3388,6 +3421,8 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3388
3421
|
setCameraStepOverride: (input) => dispatchSystem("pipelineOrchestrator", "setCameraStepOverride", "mutation", input),
|
|
3389
3422
|
setCameraPipelineForAgent: (input) => dispatchSystem("pipelineOrchestrator", "setCameraPipelineForAgent", "mutation", input),
|
|
3390
3423
|
resolvePipeline: (input) => dispatchSystem("pipelineOrchestrator", "resolvePipeline", "query", input),
|
|
3424
|
+
getCameraSwitches: (input) => dispatchSystem("pipelineOrchestrator", "getCameraSwitches", "query", input),
|
|
3425
|
+
setCameraSwitch: (input) => dispatchSystem("pipelineOrchestrator", "setCameraSwitch", "mutation", input),
|
|
3391
3426
|
getCameraStatus: (input) => dispatchSystem("pipelineOrchestrator", "getCameraStatus", "query", input),
|
|
3392
3427
|
getDeviceSettingsContribution: (input) => dispatchSystem("pipelineOrchestrator", "getDeviceSettingsContribution", "query", input),
|
|
3393
3428
|
getDeviceLiveContribution: (input) => dispatchSystem("pipelineOrchestrator", "getDeviceLiveContribution", "query", input),
|
|
@@ -3409,6 +3444,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3409
3444
|
getDeviceConfig: (input) => dispatchSystem("recording", "getDeviceConfig", "query", input),
|
|
3410
3445
|
locateSegment: (input) => dispatchSystem("recording", "locateSegment", "query", input),
|
|
3411
3446
|
readSegmentBytes: (input) => dispatchSystem("recording", "readSegmentBytes", "query", input),
|
|
3447
|
+
readGopBytes: (input) => dispatchSystem("recording", "readGopBytes", "query", input),
|
|
3412
3448
|
setDeviceConfig: (input) => dispatchSystem("recording", "setDeviceConfig", "mutation", input),
|
|
3413
3449
|
rescanStorage: (input) => dispatchSystem("recording", "rescanStorage", "mutation", input),
|
|
3414
3450
|
pruneFootage: (input) => dispatchSystem("recording", "pruneFootage", "mutation", input),
|
|
@@ -4124,6 +4160,12 @@ Object.defineProperty(exports, "systemMethod", {
|
|
|
4124
4160
|
return systemMethod;
|
|
4125
4161
|
}
|
|
4126
4162
|
});
|
|
4163
|
+
Object.defineProperty(exports, "toNodeId", {
|
|
4164
|
+
enumerable: true,
|
|
4165
|
+
get: function() {
|
|
4166
|
+
return toNodeId;
|
|
4167
|
+
}
|
|
4168
|
+
});
|
|
4127
4169
|
Object.defineProperty(exports, "viewerUiCapability", {
|
|
4128
4170
|
enumerable: true,
|
|
4129
4171
|
get: function() {
|
|
@@ -1934,9 +1934,38 @@ var CAP_NODE_PIN_CONTEXT_KEY = "__camstackNodePin";
|
|
|
1934
1934
|
/**
|
|
1935
1935
|
* Build the tRPC request options that pin a single capability call to `nodeId`.
|
|
1936
1936
|
* Pass as the second argument to `.query(input, …)` / `.mutate(input, …)`.
|
|
1937
|
+
*
|
|
1938
|
+
* ## The id is normalised here, and it has to be
|
|
1939
|
+
*
|
|
1940
|
+
* A forked addon reads its own node from `ctx.kernel.localNodeId`, and inside a
|
|
1941
|
+
* worker that value is a RUNNER id — `hub/export-hap`, not `hub`. Routing
|
|
1942
|
+
* compares a pin against real node ids, so such a pin matches nothing and the
|
|
1943
|
+
* call fails with `no provider registered for cap "…"`. The local-first
|
|
1944
|
+
* resolver already guarded against this (`localNodeId.split('/')[0]`), which
|
|
1945
|
+
* made the hazard invisible: unpinned calls worked, and only an explicit pin —
|
|
1946
|
+
* the thing you reach for when you specifically need THIS node — silently
|
|
1947
|
+
* addressed a node that does not exist.
|
|
1948
|
+
*
|
|
1949
|
+
* Cost of it being missing: `addon-export-hap` pinned `decoder.getInfo` to its
|
|
1950
|
+
* own node to read the host's hardware-decode backend. It never once answered,
|
|
1951
|
+
* so every HomeKit egress transcode decoded in SOFTWARE — including 4K H.265 —
|
|
1952
|
+
* while D67's whole premise was that the decoder addon is the authority on
|
|
1953
|
+
* hardware. The warn said `decoding in SOFTWARE` and read as "this node has no
|
|
1954
|
+
* hardware", which was false.
|
|
1955
|
+
*
|
|
1956
|
+
* Normalising in the ONE constructor fixes every caller at once, which is why
|
|
1957
|
+
* it is here and not at the call sites.
|
|
1937
1958
|
*/
|
|
1938
1959
|
function nodePin(nodeId) {
|
|
1939
|
-
return { context: { [CAP_NODE_PIN_CONTEXT_KEY]: nodeId } };
|
|
1960
|
+
return { context: { [CAP_NODE_PIN_CONTEXT_KEY]: toNodeId(nodeId) } };
|
|
1961
|
+
}
|
|
1962
|
+
/**
|
|
1963
|
+
* A runner id is `<nodeId>/<addonId>`; a node id has no slash. Taking the head
|
|
1964
|
+
* is idempotent, so passing an already-clean id costs nothing.
|
|
1965
|
+
*/
|
|
1966
|
+
function toNodeId(idOrRunnerId) {
|
|
1967
|
+
const head = idOrRunnerId.split("/")[0];
|
|
1968
|
+
return head === void 0 || head.length === 0 ? idOrRunnerId : head;
|
|
1940
1969
|
}
|
|
1941
1970
|
/**
|
|
1942
1971
|
* Read a per-call node pin out of a tRPC `op.context` (transport side).
|
|
@@ -3103,6 +3132,8 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3103
3132
|
updateRule: (input) => dispatch("notification-rules", "notificationRules", "updateRule", "mutation", input),
|
|
3104
3133
|
deleteRule: (input) => dispatch("notification-rules", "notificationRules", "deleteRule", "mutation", input),
|
|
3105
3134
|
setRuleEnabled: (input) => dispatch("notification-rules", "notificationRules", "setRuleEnabled", "mutation", input),
|
|
3135
|
+
listDeviceMutes: (input) => dispatch("notification-rules", "notificationRules", "listDeviceMutes", "query", input),
|
|
3136
|
+
setDeviceMuted: (input) => dispatch("notification-rules", "notificationRules", "setDeviceMuted", "mutation", input),
|
|
3106
3137
|
testRule: (input) => dispatch("notification-rules", "notificationRules", "testRule", "mutation", input),
|
|
3107
3138
|
getConditionCatalog: (input) => dispatch("notification-rules", "notificationRules", "getConditionCatalog", "query", input),
|
|
3108
3139
|
getHistory: (input) => dispatch("notification-rules", "notificationRules", "getHistory", "query", input),
|
|
@@ -3153,6 +3184,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3153
3184
|
pruneTracksBefore: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneTracksBefore", "mutation", input),
|
|
3154
3185
|
wipeAllAnalytics: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "wipeAllAnalytics", "mutation", input),
|
|
3155
3186
|
deleteTracks: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "deleteTracks", "mutation", input),
|
|
3187
|
+
setTrackFlags: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "setTrackFlags", "mutation", input),
|
|
3156
3188
|
getEventStoreFootprint: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventStoreFootprint", "query", input),
|
|
3157
3189
|
pruneEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneEvents", "mutation", input),
|
|
3158
3190
|
deleteDeviceEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "deleteDeviceEvents", "mutation", input),
|
|
@@ -3177,6 +3209,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3177
3209
|
privacyMask: {
|
|
3178
3210
|
getOptions: (input) => dispatch("privacy-mask", "privacyMask", "getOptions", "query", input),
|
|
3179
3211
|
setMask: (input) => dispatch("privacy-mask", "privacyMask", "setMask", "mutation", input),
|
|
3212
|
+
setAudioEnabled: (input) => dispatch("privacy-mask", "privacyMask", "setAudioEnabled", "mutation", input),
|
|
3180
3213
|
getStatus: (input) => dispatch("privacy-mask", "privacyMask", "getStatus", "query", input)
|
|
3181
3214
|
},
|
|
3182
3215
|
ptz: {
|
|
@@ -3388,6 +3421,8 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3388
3421
|
setCameraStepOverride: (input) => dispatchSystem("pipelineOrchestrator", "setCameraStepOverride", "mutation", input),
|
|
3389
3422
|
setCameraPipelineForAgent: (input) => dispatchSystem("pipelineOrchestrator", "setCameraPipelineForAgent", "mutation", input),
|
|
3390
3423
|
resolvePipeline: (input) => dispatchSystem("pipelineOrchestrator", "resolvePipeline", "query", input),
|
|
3424
|
+
getCameraSwitches: (input) => dispatchSystem("pipelineOrchestrator", "getCameraSwitches", "query", input),
|
|
3425
|
+
setCameraSwitch: (input) => dispatchSystem("pipelineOrchestrator", "setCameraSwitch", "mutation", input),
|
|
3391
3426
|
getCameraStatus: (input) => dispatchSystem("pipelineOrchestrator", "getCameraStatus", "query", input),
|
|
3392
3427
|
getDeviceSettingsContribution: (input) => dispatchSystem("pipelineOrchestrator", "getDeviceSettingsContribution", "query", input),
|
|
3393
3428
|
getDeviceLiveContribution: (input) => dispatchSystem("pipelineOrchestrator", "getDeviceLiveContribution", "query", input),
|
|
@@ -3409,6 +3444,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3409
3444
|
getDeviceConfig: (input) => dispatchSystem("recording", "getDeviceConfig", "query", input),
|
|
3410
3445
|
locateSegment: (input) => dispatchSystem("recording", "locateSegment", "query", input),
|
|
3411
3446
|
readSegmentBytes: (input) => dispatchSystem("recording", "readSegmentBytes", "query", input),
|
|
3447
|
+
readGopBytes: (input) => dispatchSystem("recording", "readGopBytes", "query", input),
|
|
3412
3448
|
setDeviceConfig: (input) => dispatchSystem("recording", "setDeviceConfig", "mutation", input),
|
|
3413
3449
|
rescanStorage: (input) => dispatchSystem("recording", "rescanStorage", "mutation", input),
|
|
3414
3450
|
pruneFootage: (input) => dispatchSystem("recording", "pruneFootage", "mutation", input),
|
|
@@ -3656,4 +3692,4 @@ function sleepCancellable(ms, signal) {
|
|
|
3656
3692
|
});
|
|
3657
3693
|
}
|
|
3658
3694
|
//#endregion
|
|
3659
|
-
export {
|
|
3695
|
+
export { FrameHandleSchema as $, method as A, readinessKey as B, DeviceType as C, collectHydratedFieldEntries as Ct, event as D, DEVICE_STATUS_METHOD as E, resolveHydratedFieldValue as Et, readNodePin as F, CamProfileSchema as G, BrokerStatsSchema as H, toNodeId as I, CameraStreamSchema as J, CamStreamKindSchema as K, ReadinessRegistry as L, systemMethod as M, CAP_NODE_PIN_CONTEXT_KEY as N, expandCapMethods as O, nodePin as P, FrameHandleFormatSchema as Q, ReadinessTimeoutError as R, DeviceRole as S, WELL_KNOWN_TAB_MAP as St, DEVICE_SETTINGS_CONTRIBUTION_METHODS as T, hydrateSchema as Tt, BrokerStatusSchema as U, scopeKey as V, CAM_PROFILE_ORDER as W, DecodedFrameSchema as X, DecodedAudioChunkSchema as Y, EncodedPacketSchema as Z, RawStateResultSchema as _, createDurableState as _t, asJsonObject as a, SubscribeAudioChunksInputSchema as at, ChargingStatus as b, isEvent as bt, parseJsonArray as c, SubscribeFramesResultSchema as ct, DEVICE_SCOPED_CAPS as d, parseProfileBrokerId as dt, ProfileRtspEntrySchema as et, isDeviceScopedCap as f, selectAssignedProfileSlots as ft, createSliceHandle as g, normalizeAddonInitResult as gt, createMirrorSource as h, BaseAddon as ht, asJsonArray as i, StreamSourceSchema as it, resolveCapMount as j, isDeviceConfigCap as k, parseJsonObject as l, makeProfileBrokerId as lt, createLazyTrpcSource as m, DisposerChain as mt, sleepCancellable as n, ProfileSlotStatusSchema as nt, asNumber as o, SubscribeAudioChunksResultSchema as ot, createDeviceProxy as p, DATAPLANE_SECRET_HEADER as pt, CamStreamResolutionSchema as q, asBoolean as r, StreamSourceEntrySchema$1 as rt, asString as s, SubscribeFramesInputSchema as st, sleep as t, ProfileSlotSchema as tt, parseJsonUnknown as u, makeSourceBrokerId as ut, deviceOpsCapability as v, createEvent as vt, adminUiCapability as w, collectHydratedFieldValues as wt, DeviceFeature as x, WELL_KNOWN_TABS as xt, viewerUiCapability as y, emitReadiness as yt, emitDownForOwnedCaps as z };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The addon id as the REGISTRY, the wire and the durable stores spell it.
|
|
3
|
+
*
|
|
4
|
+
* `AddonContext.id` does not agree with itself across the two context
|
|
5
|
+
* factories:
|
|
6
|
+
*
|
|
7
|
+
* - a FORKED addon gets the bare manifest id
|
|
8
|
+
* (`kernel/moleculer/addon-context-factory.ts` → `id: addonId`);
|
|
9
|
+
* - an addon co-located in hub-main gets it PREFIXED
|
|
10
|
+
* (`server/backend/src/core/addon/addon-registry.service.ts` →
|
|
11
|
+
* ``id: `addon:${addonId}` ``).
|
|
12
|
+
*
|
|
13
|
+
* Everything an addon might compare `ctx.id` AGAINST carries the bare form:
|
|
14
|
+
* `DeviceBindingEntry.providerAddonId`, the `device-manager` bindings store's
|
|
15
|
+
* `wrapperAddonId`, `CapabilityRegistry` provider keys, manifest ids.
|
|
16
|
+
*
|
|
17
|
+
* So `entry.providerAddonId === this.ctx.id` is silently, permanently false
|
|
18
|
+
* for a builtin — and only for a builtin, which is why it survives a green
|
|
19
|
+
* suite whose fake supplies the bare id. That is exactly how camera 615's
|
|
20
|
+
* virtual doorbell latched `unbound` for twelve hours on 2026-08-07 while its
|
|
21
|
+
* binding was intact ([D72](../../../../docs/decisions/adr-0072.md)).
|
|
22
|
+
*
|
|
23
|
+
* Route every comparison between `ctx.id` and a registry/store addon id
|
|
24
|
+
* through {@link isSameAddonId}. `scripts/check-addon-id-comparison.ts`
|
|
25
|
+
* enforces it in the processes where the prefix exists.
|
|
26
|
+
*/
|
|
27
|
+
/** The manifest id, whichever spelling of `ctx.id` you were handed. */
|
|
28
|
+
export declare function bareAddonId(id: string): string;
|
|
29
|
+
/** True when both ids name the same addon, prefixed or not. */
|
|
30
|
+
export declare function isSameAddonId(a: string, b: string): boolean;
|