@camstack/types 1.2.42 → 1.2.44
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 +8 -2
- package/dist/addon.mjs +8 -2
- package/dist/cap-call-context.d.ts +26 -0
- package/dist/capabilities/index.d.ts +8 -5
- package/dist/capabilities/osd-manager.cap.d.ts +900 -0
- package/dist/capabilities/pipeline-analytics.cap.d.ts +171 -4
- package/dist/capabilities/pipeline-orchestrator.cap.d.ts +36 -0
- package/dist/capabilities/privacy-mask.cap.d.ts +69 -9
- package/dist/capabilities/recording.cap.d.ts +27 -0
- package/dist/capabilities/schemas/streaming-shared.d.ts +2 -0
- package/dist/capabilities/server-management.cap.d.ts +3 -3
- package/dist/capabilities/snapshot.cap.d.ts +1 -1
- package/dist/capabilities/stream-broker.cap.d.ts +36 -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/ffmpeg/encode-defaults.d.ts +18 -0
- package/dist/ffmpeg/fmp4-box-splitter.d.ts +113 -0
- package/dist/ffmpeg/fmp4-fragment-child.d.ts +85 -0
- package/dist/ffmpeg/fmp4-fragment-plane.d.ts +142 -0
- package/dist/ffmpeg/invocation.d.ts +102 -2
- package/dist/ffmpeg/sharing-key.d.ts +54 -2
- package/dist/fmp4-box-splitter-B53u9-Nu.mjs +615 -0
- package/dist/fmp4-box-splitter-BkWH7O3L.js +686 -0
- package/dist/generated/addon-api.d.ts +117 -0
- package/dist/generated/cap-input-defaults.d.ts +1 -1
- package/dist/generated/capability-router-map.d.ts +5 -2
- package/dist/generated/device-proxy.d.ts +4 -2
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/system-proxy.d.ts +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1264 -394
- package/dist/index.mjs +1217 -385
- package/dist/interfaces/camera-switches.d.ts +211 -5
- package/dist/interfaces/inference-engine.d.ts +24 -3
- package/dist/interfaces/stream-broker.d.ts +18 -0
- package/dist/node.d.ts +4 -0
- package/dist/node.js +509 -3
- package/dist/node.mjs +507 -3
- package/dist/notification/schedule.d.ts +20 -0
- package/dist/pipeline/native-lease.d.ts +150 -0
- package/dist/{sleep-BmNKsY7v.mjs → sleep-cC4Fuup8.mjs} +59 -3
- package/dist/{sleep-Cvi1JxZp.js → sleep-eiC10_cX.js} +64 -2
- package/dist/types/pipeline-step.d.ts +1 -1
- package/dist/utils/addon-id.d.ts +30 -0
- package/package.json +1 -1
- package/dist/canonical-hash-7nfBbEqR.mjs +0 -35
- package/dist/canonical-hash-BcZHRHIx.js +0 -40
|
@@ -1445,7 +1445,20 @@ var BrokerStatsSchema = z.object({
|
|
|
1445
1445
|
sampleRate: z.number(),
|
|
1446
1446
|
channels: z.number(),
|
|
1447
1447
|
supported: z.boolean()
|
|
1448
|
-
}).nullable().optional()
|
|
1448
|
+
}).nullable().optional(),
|
|
1449
|
+
/**
|
|
1450
|
+
* BROKER-SIDE AUDIO MUTE (D83). `true` = this broker is deliberately
|
|
1451
|
+
* distributing none of the device's audio, on live or recording.
|
|
1452
|
+
*
|
|
1453
|
+
* Present so a silent camera can be told apart from a broken one on the
|
|
1454
|
+
* stream panel itself, without cross-referencing the switch group: a
|
|
1455
|
+
* broker holding an `audio` track descriptor while `audioMuted` is true is
|
|
1456
|
+
* working exactly as asked. `audioMutedDropped` counts the audio units
|
|
1457
|
+
* thrown away since the current dial — it is how you confirm from stats
|
|
1458
|
+
* alone that the mute is on the packet path and not merely persisted.
|
|
1459
|
+
*/
|
|
1460
|
+
audioMuted: z.boolean().optional(),
|
|
1461
|
+
audioMutedDropped: z.number().optional()
|
|
1449
1462
|
});
|
|
1450
1463
|
/**
|
|
1451
1464
|
* Exporter-facing "profile restream" entry. Returned by
|
|
@@ -1934,9 +1947,38 @@ var CAP_NODE_PIN_CONTEXT_KEY = "__camstackNodePin";
|
|
|
1934
1947
|
/**
|
|
1935
1948
|
* Build the tRPC request options that pin a single capability call to `nodeId`.
|
|
1936
1949
|
* Pass as the second argument to `.query(input, …)` / `.mutate(input, …)`.
|
|
1950
|
+
*
|
|
1951
|
+
* ## The id is normalised here, and it has to be
|
|
1952
|
+
*
|
|
1953
|
+
* A forked addon reads its own node from `ctx.kernel.localNodeId`, and inside a
|
|
1954
|
+
* worker that value is a RUNNER id — `hub/export-hap`, not `hub`. Routing
|
|
1955
|
+
* compares a pin against real node ids, so such a pin matches nothing and the
|
|
1956
|
+
* call fails with `no provider registered for cap "…"`. The local-first
|
|
1957
|
+
* resolver already guarded against this (`localNodeId.split('/')[0]`), which
|
|
1958
|
+
* made the hazard invisible: unpinned calls worked, and only an explicit pin —
|
|
1959
|
+
* the thing you reach for when you specifically need THIS node — silently
|
|
1960
|
+
* addressed a node that does not exist.
|
|
1961
|
+
*
|
|
1962
|
+
* Cost of it being missing: `addon-export-hap` pinned `decoder.getInfo` to its
|
|
1963
|
+
* own node to read the host's hardware-decode backend. It never once answered,
|
|
1964
|
+
* so every HomeKit egress transcode decoded in SOFTWARE — including 4K H.265 —
|
|
1965
|
+
* while D67's whole premise was that the decoder addon is the authority on
|
|
1966
|
+
* hardware. The warn said `decoding in SOFTWARE` and read as "this node has no
|
|
1967
|
+
* hardware", which was false.
|
|
1968
|
+
*
|
|
1969
|
+
* Normalising in the ONE constructor fixes every caller at once, which is why
|
|
1970
|
+
* it is here and not at the call sites.
|
|
1937
1971
|
*/
|
|
1938
1972
|
function nodePin(nodeId) {
|
|
1939
|
-
return { context: { [CAP_NODE_PIN_CONTEXT_KEY]: nodeId } };
|
|
1973
|
+
return { context: { [CAP_NODE_PIN_CONTEXT_KEY]: toNodeId(nodeId) } };
|
|
1974
|
+
}
|
|
1975
|
+
/**
|
|
1976
|
+
* A runner id is `<nodeId>/<addonId>`; a node id has no slash. Taking the head
|
|
1977
|
+
* is idempotent, so passing an already-clean id costs nothing.
|
|
1978
|
+
*/
|
|
1979
|
+
function toNodeId(idOrRunnerId) {
|
|
1980
|
+
const head = idOrRunnerId.split("/")[0];
|
|
1981
|
+
return head === void 0 || head.length === 0 ? idOrRunnerId : head;
|
|
1940
1982
|
}
|
|
1941
1983
|
/**
|
|
1942
1984
|
* Read a per-call node pin out of a tRPC `op.context` (transport side).
|
|
@@ -3163,6 +3205,8 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3163
3205
|
getMediaRelocateStatus: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getMediaRelocateStatus", "query", input),
|
|
3164
3206
|
cancelMediaRelocate: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "cancelMediaRelocate", "mutation", input),
|
|
3165
3207
|
listOpsLog: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listOpsLog", "query", input),
|
|
3208
|
+
getTrainingExportSummary: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getTrainingExportSummary", "query", input),
|
|
3209
|
+
getTrainingExportUrl: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getTrainingExportUrl", "query", input),
|
|
3166
3210
|
getEventMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventMedia", "query", input),
|
|
3167
3211
|
getTrackMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getTrackMedia", "query", input),
|
|
3168
3212
|
listTrackMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listTrackMedia", "query", input),
|
|
@@ -3180,6 +3224,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3180
3224
|
privacyMask: {
|
|
3181
3225
|
getOptions: (input) => dispatch("privacy-mask", "privacyMask", "getOptions", "query", input),
|
|
3182
3226
|
setMask: (input) => dispatch("privacy-mask", "privacyMask", "setMask", "mutation", input),
|
|
3227
|
+
setAudioEnabled: (input) => dispatch("privacy-mask", "privacyMask", "setAudioEnabled", "mutation", input),
|
|
3183
3228
|
getStatus: (input) => dispatch("privacy-mask", "privacyMask", "getStatus", "query", input)
|
|
3184
3229
|
},
|
|
3185
3230
|
ptz: {
|
|
@@ -3370,6 +3415,14 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3370
3415
|
getDeviceStats: (input) => dispatchSystem("networkQuality", "getDeviceStats", "query", input),
|
|
3371
3416
|
reportClientStats: (input) => dispatchSystem("networkQuality", "reportClientStats", "mutation", input)
|
|
3372
3417
|
},
|
|
3418
|
+
osdManager: {
|
|
3419
|
+
getDeviceOsd: (input) => dispatchSystem("osdManager", "getDeviceOsd", "query", input),
|
|
3420
|
+
getSourceCatalog: (input) => dispatchSystem("osdManager", "getSourceCatalog", "query", input),
|
|
3421
|
+
setSlotBinding: (input) => dispatchSystem("osdManager", "setSlotBinding", "mutation", input),
|
|
3422
|
+
clearSlotBinding: (input) => dispatchSystem("osdManager", "clearSlotBinding", "mutation", input),
|
|
3423
|
+
previewSlot: (input) => dispatchSystem("osdManager", "previewSlot", "mutation", input),
|
|
3424
|
+
renderDevice: (input) => dispatchSystem("osdManager", "renderDevice", "mutation", input)
|
|
3425
|
+
},
|
|
3373
3426
|
pipelineExecutor: {
|
|
3374
3427
|
runPipeline: (input) => dispatchSystem("pipelineExecutor", "runPipeline", "mutation", input),
|
|
3375
3428
|
runPipelineBatch: (input) => dispatchSystem("pipelineExecutor", "runPipelineBatch", "mutation", input)
|
|
@@ -3414,6 +3467,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3414
3467
|
getDeviceConfig: (input) => dispatchSystem("recording", "getDeviceConfig", "query", input),
|
|
3415
3468
|
locateSegment: (input) => dispatchSystem("recording", "locateSegment", "query", input),
|
|
3416
3469
|
readSegmentBytes: (input) => dispatchSystem("recording", "readSegmentBytes", "query", input),
|
|
3470
|
+
readGopBytes: (input) => dispatchSystem("recording", "readGopBytes", "query", input),
|
|
3417
3471
|
setDeviceConfig: (input) => dispatchSystem("recording", "setDeviceConfig", "mutation", input),
|
|
3418
3472
|
rescanStorage: (input) => dispatchSystem("recording", "rescanStorage", "mutation", input),
|
|
3419
3473
|
pruneFootage: (input) => dispatchSystem("recording", "pruneFootage", "mutation", input),
|
|
@@ -3436,6 +3490,8 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3436
3490
|
unassignProfile: (input) => dispatchSystem("streamBroker", "unassignProfile", "mutation", input),
|
|
3437
3491
|
renderPreBufferClip: (input) => dispatchSystem("streamBroker", "renderPreBufferClip", "mutation", input),
|
|
3438
3492
|
restartProfile: (input) => dispatchSystem("streamBroker", "restartProfile", "mutation", input),
|
|
3493
|
+
getDeviceAudioMute: (input) => dispatchSystem("streamBroker", "getDeviceAudioMute", "query", input),
|
|
3494
|
+
setDeviceAudioMute: (input) => dispatchSystem("streamBroker", "setDeviceAudioMute", "mutation", input),
|
|
3439
3495
|
getDeviceSettingsContribution: (input) => dispatchSystem("streamBroker", "getDeviceSettingsContribution", "query", input),
|
|
3440
3496
|
getDeviceLiveContribution: (input) => dispatchSystem("streamBroker", "getDeviceLiveContribution", "query", input),
|
|
3441
3497
|
applyDeviceSettingsPatch: (input) => dispatchSystem("streamBroker", "applyDeviceSettingsPatch", "mutation", input)
|
|
@@ -3661,4 +3717,4 @@ function sleepCancellable(ms, signal) {
|
|
|
3661
3717
|
});
|
|
3662
3718
|
}
|
|
3663
3719
|
//#endregion
|
|
3664
|
-
export {
|
|
3720
|
+
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 };
|
|
@@ -1445,7 +1445,20 @@ var BrokerStatsSchema = zod.z.object({
|
|
|
1445
1445
|
sampleRate: zod.z.number(),
|
|
1446
1446
|
channels: zod.z.number(),
|
|
1447
1447
|
supported: zod.z.boolean()
|
|
1448
|
-
}).nullable().optional()
|
|
1448
|
+
}).nullable().optional(),
|
|
1449
|
+
/**
|
|
1450
|
+
* BROKER-SIDE AUDIO MUTE (D83). `true` = this broker is deliberately
|
|
1451
|
+
* distributing none of the device's audio, on live or recording.
|
|
1452
|
+
*
|
|
1453
|
+
* Present so a silent camera can be told apart from a broken one on the
|
|
1454
|
+
* stream panel itself, without cross-referencing the switch group: a
|
|
1455
|
+
* broker holding an `audio` track descriptor while `audioMuted` is true is
|
|
1456
|
+
* working exactly as asked. `audioMutedDropped` counts the audio units
|
|
1457
|
+
* thrown away since the current dial — it is how you confirm from stats
|
|
1458
|
+
* alone that the mute is on the packet path and not merely persisted.
|
|
1459
|
+
*/
|
|
1460
|
+
audioMuted: zod.z.boolean().optional(),
|
|
1461
|
+
audioMutedDropped: zod.z.number().optional()
|
|
1449
1462
|
});
|
|
1450
1463
|
/**
|
|
1451
1464
|
* Exporter-facing "profile restream" entry. Returned by
|
|
@@ -1934,9 +1947,38 @@ var CAP_NODE_PIN_CONTEXT_KEY = "__camstackNodePin";
|
|
|
1934
1947
|
/**
|
|
1935
1948
|
* Build the tRPC request options that pin a single capability call to `nodeId`.
|
|
1936
1949
|
* Pass as the second argument to `.query(input, …)` / `.mutate(input, …)`.
|
|
1950
|
+
*
|
|
1951
|
+
* ## The id is normalised here, and it has to be
|
|
1952
|
+
*
|
|
1953
|
+
* A forked addon reads its own node from `ctx.kernel.localNodeId`, and inside a
|
|
1954
|
+
* worker that value is a RUNNER id — `hub/export-hap`, not `hub`. Routing
|
|
1955
|
+
* compares a pin against real node ids, so such a pin matches nothing and the
|
|
1956
|
+
* call fails with `no provider registered for cap "…"`. The local-first
|
|
1957
|
+
* resolver already guarded against this (`localNodeId.split('/')[0]`), which
|
|
1958
|
+
* made the hazard invisible: unpinned calls worked, and only an explicit pin —
|
|
1959
|
+
* the thing you reach for when you specifically need THIS node — silently
|
|
1960
|
+
* addressed a node that does not exist.
|
|
1961
|
+
*
|
|
1962
|
+
* Cost of it being missing: `addon-export-hap` pinned `decoder.getInfo` to its
|
|
1963
|
+
* own node to read the host's hardware-decode backend. It never once answered,
|
|
1964
|
+
* so every HomeKit egress transcode decoded in SOFTWARE — including 4K H.265 —
|
|
1965
|
+
* while D67's whole premise was that the decoder addon is the authority on
|
|
1966
|
+
* hardware. The warn said `decoding in SOFTWARE` and read as "this node has no
|
|
1967
|
+
* hardware", which was false.
|
|
1968
|
+
*
|
|
1969
|
+
* Normalising in the ONE constructor fixes every caller at once, which is why
|
|
1970
|
+
* it is here and not at the call sites.
|
|
1937
1971
|
*/
|
|
1938
1972
|
function nodePin(nodeId) {
|
|
1939
|
-
return { context: { [CAP_NODE_PIN_CONTEXT_KEY]: nodeId } };
|
|
1973
|
+
return { context: { [CAP_NODE_PIN_CONTEXT_KEY]: toNodeId(nodeId) } };
|
|
1974
|
+
}
|
|
1975
|
+
/**
|
|
1976
|
+
* A runner id is `<nodeId>/<addonId>`; a node id has no slash. Taking the head
|
|
1977
|
+
* is idempotent, so passing an already-clean id costs nothing.
|
|
1978
|
+
*/
|
|
1979
|
+
function toNodeId(idOrRunnerId) {
|
|
1980
|
+
const head = idOrRunnerId.split("/")[0];
|
|
1981
|
+
return head === void 0 || head.length === 0 ? idOrRunnerId : head;
|
|
1940
1982
|
}
|
|
1941
1983
|
/**
|
|
1942
1984
|
* Read a per-call node pin out of a tRPC `op.context` (transport side).
|
|
@@ -3163,6 +3205,8 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3163
3205
|
getMediaRelocateStatus: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getMediaRelocateStatus", "query", input),
|
|
3164
3206
|
cancelMediaRelocate: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "cancelMediaRelocate", "mutation", input),
|
|
3165
3207
|
listOpsLog: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listOpsLog", "query", input),
|
|
3208
|
+
getTrainingExportSummary: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getTrainingExportSummary", "query", input),
|
|
3209
|
+
getTrainingExportUrl: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getTrainingExportUrl", "query", input),
|
|
3166
3210
|
getEventMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventMedia", "query", input),
|
|
3167
3211
|
getTrackMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getTrackMedia", "query", input),
|
|
3168
3212
|
listTrackMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listTrackMedia", "query", input),
|
|
@@ -3180,6 +3224,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3180
3224
|
privacyMask: {
|
|
3181
3225
|
getOptions: (input) => dispatch("privacy-mask", "privacyMask", "getOptions", "query", input),
|
|
3182
3226
|
setMask: (input) => dispatch("privacy-mask", "privacyMask", "setMask", "mutation", input),
|
|
3227
|
+
setAudioEnabled: (input) => dispatch("privacy-mask", "privacyMask", "setAudioEnabled", "mutation", input),
|
|
3183
3228
|
getStatus: (input) => dispatch("privacy-mask", "privacyMask", "getStatus", "query", input)
|
|
3184
3229
|
},
|
|
3185
3230
|
ptz: {
|
|
@@ -3370,6 +3415,14 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3370
3415
|
getDeviceStats: (input) => dispatchSystem("networkQuality", "getDeviceStats", "query", input),
|
|
3371
3416
|
reportClientStats: (input) => dispatchSystem("networkQuality", "reportClientStats", "mutation", input)
|
|
3372
3417
|
},
|
|
3418
|
+
osdManager: {
|
|
3419
|
+
getDeviceOsd: (input) => dispatchSystem("osdManager", "getDeviceOsd", "query", input),
|
|
3420
|
+
getSourceCatalog: (input) => dispatchSystem("osdManager", "getSourceCatalog", "query", input),
|
|
3421
|
+
setSlotBinding: (input) => dispatchSystem("osdManager", "setSlotBinding", "mutation", input),
|
|
3422
|
+
clearSlotBinding: (input) => dispatchSystem("osdManager", "clearSlotBinding", "mutation", input),
|
|
3423
|
+
previewSlot: (input) => dispatchSystem("osdManager", "previewSlot", "mutation", input),
|
|
3424
|
+
renderDevice: (input) => dispatchSystem("osdManager", "renderDevice", "mutation", input)
|
|
3425
|
+
},
|
|
3373
3426
|
pipelineExecutor: {
|
|
3374
3427
|
runPipeline: (input) => dispatchSystem("pipelineExecutor", "runPipeline", "mutation", input),
|
|
3375
3428
|
runPipelineBatch: (input) => dispatchSystem("pipelineExecutor", "runPipelineBatch", "mutation", input)
|
|
@@ -3414,6 +3467,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3414
3467
|
getDeviceConfig: (input) => dispatchSystem("recording", "getDeviceConfig", "query", input),
|
|
3415
3468
|
locateSegment: (input) => dispatchSystem("recording", "locateSegment", "query", input),
|
|
3416
3469
|
readSegmentBytes: (input) => dispatchSystem("recording", "readSegmentBytes", "query", input),
|
|
3470
|
+
readGopBytes: (input) => dispatchSystem("recording", "readGopBytes", "query", input),
|
|
3417
3471
|
setDeviceConfig: (input) => dispatchSystem("recording", "setDeviceConfig", "mutation", input),
|
|
3418
3472
|
rescanStorage: (input) => dispatchSystem("recording", "rescanStorage", "mutation", input),
|
|
3419
3473
|
pruneFootage: (input) => dispatchSystem("recording", "pruneFootage", "mutation", input),
|
|
@@ -3436,6 +3490,8 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3436
3490
|
unassignProfile: (input) => dispatchSystem("streamBroker", "unassignProfile", "mutation", input),
|
|
3437
3491
|
renderPreBufferClip: (input) => dispatchSystem("streamBroker", "renderPreBufferClip", "mutation", input),
|
|
3438
3492
|
restartProfile: (input) => dispatchSystem("streamBroker", "restartProfile", "mutation", input),
|
|
3493
|
+
getDeviceAudioMute: (input) => dispatchSystem("streamBroker", "getDeviceAudioMute", "query", input),
|
|
3494
|
+
setDeviceAudioMute: (input) => dispatchSystem("streamBroker", "setDeviceAudioMute", "mutation", input),
|
|
3439
3495
|
getDeviceSettingsContribution: (input) => dispatchSystem("streamBroker", "getDeviceSettingsContribution", "query", input),
|
|
3440
3496
|
getDeviceLiveContribution: (input) => dispatchSystem("streamBroker", "getDeviceLiveContribution", "query", input),
|
|
3441
3497
|
applyDeviceSettingsPatch: (input) => dispatchSystem("streamBroker", "applyDeviceSettingsPatch", "mutation", input)
|
|
@@ -4129,6 +4185,12 @@ Object.defineProperty(exports, "systemMethod", {
|
|
|
4129
4185
|
return systemMethod;
|
|
4130
4186
|
}
|
|
4131
4187
|
});
|
|
4188
|
+
Object.defineProperty(exports, "toNodeId", {
|
|
4189
|
+
enumerable: true,
|
|
4190
|
+
get: function() {
|
|
4191
|
+
return toNodeId;
|
|
4192
|
+
}
|
|
4193
|
+
});
|
|
4132
4194
|
Object.defineProperty(exports, "viewerUiCapability", {
|
|
4133
4195
|
enumerable: true,
|
|
4134
4196
|
get: function() {
|
|
@@ -12,7 +12,7 @@ export interface IPipelineStep {
|
|
|
12
12
|
readonly definition: StepDefinition;
|
|
13
13
|
getConfigSchema(): readonly ConfigField[];
|
|
14
14
|
}
|
|
15
|
-
export type PostprocessorType = 'yolo' | 'ssd' | 'yolo-seg' | 'scrfd' | 'arcface' | 'clip' | 'softmax' | 'ctc' | 'saliency' | 'yamnet';
|
|
15
|
+
export type PostprocessorType = 'yolo' | 'ssd' | 'rfdetr' | 'yolo-seg' | 'scrfd' | 'arcface' | 'clip' | 'softmax' | 'ctc' | 'saliency' | 'yamnet';
|
|
16
16
|
export interface StepDefinition {
|
|
17
17
|
/** Unique step identifier (e.g., 'object-detection', 'face-detection') */
|
|
18
18
|
readonly id: string;
|
|
@@ -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;
|
package/package.json
CHANGED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
//#region src/utils/canonical-hash.ts
|
|
3
|
-
/**
|
|
4
|
-
* Deterministic SHA-256 hash of an arbitrary serialisable value. The
|
|
5
|
-
* canonical form sorts object keys alphabetically at every depth so two
|
|
6
|
-
* structurally-equal inputs with different key insertion orders produce
|
|
7
|
-
* the same hash. Returns a 64-char lowercase hex digest.
|
|
8
|
-
*
|
|
9
|
-
* Used by export adapters (Alexa, HAP) to short-circuit re-discovery /
|
|
10
|
-
* accessory-rebuild work when the upstream shape is byte-identical to
|
|
11
|
-
* the last applied state — preventing user-visible "re-discovery"
|
|
12
|
-
* notifications on every addon-runner respawn. Each respawn re-fires
|
|
13
|
-
* `DeviceBindingsChanged` for every cap registration, which without
|
|
14
|
-
* this guard would propagate redundant pushes.
|
|
15
|
-
*
|
|
16
|
-
* Note: this is a SYMPTOMATIC fix layered on top of the binding-change
|
|
17
|
-
* subscription. The proper fix is a single "device ready" lifecycle
|
|
18
|
-
* barrier so exports react only when the full cap set has landed —
|
|
19
|
-
* tracked separately for post-HA-integration work.
|
|
20
|
-
*/
|
|
21
|
-
function canonicalHash(value) {
|
|
22
|
-
const canonical = JSON.stringify(value, replaceWithSortedKeys);
|
|
23
|
-
return createHash("sha256").update(canonical ?? "").digest("hex");
|
|
24
|
-
}
|
|
25
|
-
function replaceWithSortedKeys(_key, value) {
|
|
26
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
27
|
-
const obj = value;
|
|
28
|
-
const out = {};
|
|
29
|
-
for (const k of Object.keys(obj).toSorted()) out[k] = obj[k];
|
|
30
|
-
return out;
|
|
31
|
-
}
|
|
32
|
-
return value;
|
|
33
|
-
}
|
|
34
|
-
//#endregion
|
|
35
|
-
export { canonicalHash as t };
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
let node_crypto = require("node:crypto");
|
|
2
|
-
//#region src/utils/canonical-hash.ts
|
|
3
|
-
/**
|
|
4
|
-
* Deterministic SHA-256 hash of an arbitrary serialisable value. The
|
|
5
|
-
* canonical form sorts object keys alphabetically at every depth so two
|
|
6
|
-
* structurally-equal inputs with different key insertion orders produce
|
|
7
|
-
* the same hash. Returns a 64-char lowercase hex digest.
|
|
8
|
-
*
|
|
9
|
-
* Used by export adapters (Alexa, HAP) to short-circuit re-discovery /
|
|
10
|
-
* accessory-rebuild work when the upstream shape is byte-identical to
|
|
11
|
-
* the last applied state — preventing user-visible "re-discovery"
|
|
12
|
-
* notifications on every addon-runner respawn. Each respawn re-fires
|
|
13
|
-
* `DeviceBindingsChanged` for every cap registration, which without
|
|
14
|
-
* this guard would propagate redundant pushes.
|
|
15
|
-
*
|
|
16
|
-
* Note: this is a SYMPTOMATIC fix layered on top of the binding-change
|
|
17
|
-
* subscription. The proper fix is a single "device ready" lifecycle
|
|
18
|
-
* barrier so exports react only when the full cap set has landed —
|
|
19
|
-
* tracked separately for post-HA-integration work.
|
|
20
|
-
*/
|
|
21
|
-
function canonicalHash(value) {
|
|
22
|
-
const canonical = JSON.stringify(value, replaceWithSortedKeys);
|
|
23
|
-
return (0, node_crypto.createHash)("sha256").update(canonical ?? "").digest("hex");
|
|
24
|
-
}
|
|
25
|
-
function replaceWithSortedKeys(_key, value) {
|
|
26
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
27
|
-
const obj = value;
|
|
28
|
-
const out = {};
|
|
29
|
-
for (const k of Object.keys(obj).toSorted()) out[k] = obj[k];
|
|
30
|
-
return out;
|
|
31
|
-
}
|
|
32
|
-
return value;
|
|
33
|
-
}
|
|
34
|
-
//#endregion
|
|
35
|
-
Object.defineProperty(exports, "canonicalHash", {
|
|
36
|
-
enumerable: true,
|
|
37
|
-
get: function() {
|
|
38
|
-
return canonicalHash;
|
|
39
|
-
}
|
|
40
|
-
});
|