@camstack/addon-post-analysis 1.1.12 → 1.1.14
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/{dist-d6siFYqC.js → dist-DrqXmZjI.js} +316 -18
- package/dist/{dist-CdflY87D.mjs → dist-XlUdQXHn.mjs} +311 -19
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/enrichment-engine/index.js +2 -2
- package/dist/enrichment-engine/index.mjs +1 -1
- package/dist/node-BGfIE_Il.js +150 -0
- package/dist/node-BuPMb-ti.mjs +145 -0
- package/dist/pipeline-analytics/_stub.js +45 -45
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-BIz6KjXS.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DrUOlPHq.mjs} +3 -3
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-C67yOF0e.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-DtijJmgD.mjs → hostInit-BhdwiKng.mjs} +3 -3
- package/dist/pipeline-analytics/index.js +10 -7
- package/dist/pipeline-analytics/index.mjs +9 -6
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/dist/{resolve-frame-BACRPcr1.js → resolve-frame-Dciml-ds.js} +1 -1
- package/package.json +3 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-C3Bc8Uy_.mjs +0 -26
|
@@ -4627,7 +4627,7 @@ function _instanceof(cls, params = {}) {
|
|
|
4627
4627
|
return inst;
|
|
4628
4628
|
}
|
|
4629
4629
|
//#endregion
|
|
4630
|
-
//#region ../types/dist/sleep-
|
|
4630
|
+
//#region ../types/dist/sleep-MHm--th-.mjs
|
|
4631
4631
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4632
4632
|
EventCategory["SystemBoot"] = "system.boot";
|
|
4633
4633
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -5889,6 +5889,7 @@ var CamStreamKindSchema = _enum([
|
|
|
5889
5889
|
"pull-rtsp",
|
|
5890
5890
|
"pull-rtmp",
|
|
5891
5891
|
"pull-http",
|
|
5892
|
+
"pull-flv",
|
|
5892
5893
|
"pull-rfc4571",
|
|
5893
5894
|
"push-annexb",
|
|
5894
5895
|
"derived"
|
|
@@ -6810,6 +6811,25 @@ var ConvertResultSchema = object({
|
|
|
6810
6811
|
})).readonly()
|
|
6811
6812
|
});
|
|
6812
6813
|
/**
|
|
6814
|
+
* THE canonical event-clip pad: the time window a single-timestamp analytics
|
|
6815
|
+
* event expands to when joined with footage (clip window = `[timestamp - preMs,
|
|
6816
|
+
* timestamp + postMs]`). Matches the admin-ui clip window (−5s/+10s).
|
|
6817
|
+
*
|
|
6818
|
+
* Every consumer derives from this ONE constant so event↔footage boundaries
|
|
6819
|
+
* agree everywhere (C1):
|
|
6820
|
+
* - the `videoclips` default provider (addon-post-analysis) pads its clip
|
|
6821
|
+
* windows with it;
|
|
6822
|
+
* - the recorder's ephemeral in-RAM `EventMap` markers (addon-pipeline) pad
|
|
6823
|
+
* their `startMs/endMs` with it.
|
|
6824
|
+
*
|
|
6825
|
+
* NOTE: this is a UI/JOIN convention, NOT the `events`-band keep/discard gate —
|
|
6826
|
+
* that uses the per-device `preBufferSec`/`postBufferSec` config.
|
|
6827
|
+
*/
|
|
6828
|
+
var EVENT_PAD_MS = {
|
|
6829
|
+
preMs: 5e3,
|
|
6830
|
+
postMs: 1e4
|
|
6831
|
+
};
|
|
6832
|
+
/**
|
|
6813
6833
|
* Numeric day-of-week: 0 = Sunday … 6 = Saturday (matches `Date.getDay`).
|
|
6814
6834
|
* Named `RecordingWeekday` to avoid collision with the string-union
|
|
6815
6835
|
* `Weekday` exported from `interfaces/timezones.ts`.
|
|
@@ -7049,7 +7069,21 @@ var StorageLocationDeclarationSchema = object({
|
|
|
7049
7069
|
* slots (e.g. `recordingsLow` → `recordings`) so operators only need to
|
|
7050
7070
|
* configure the primary location.
|
|
7051
7071
|
*/
|
|
7052
|
-
defaultsTo: string().optional()
|
|
7072
|
+
defaultsTo: string().optional(),
|
|
7073
|
+
/**
|
|
7074
|
+
* Which node root the seeded `<id>:default` instance is placed under on a
|
|
7075
|
+
* FRESH install:
|
|
7076
|
+
* - `'data'` (default) — the node's data dir (`CAMSTACK_DATA` / boot dir),
|
|
7077
|
+
* the appData volume. Right for small/durable data (backups, logs, models).
|
|
7078
|
+
* - `'media'` — the dedicated media volume (`CAMSTACK_MEDIA_ROOT`) when that
|
|
7079
|
+
* env is set, else falls back to the data root. Right for bulky, hot media
|
|
7080
|
+
* (recordings, event media) that should stay off the appData disk.
|
|
7081
|
+
*
|
|
7082
|
+
* Only affects the seeded default's `basePath`; operators can repoint any
|
|
7083
|
+
* location afterwards, and a `defaultsTo` slot inherits its parent's root
|
|
7084
|
+
* regardless of this field. Absent (the common case) is treated as `'data'`.
|
|
7085
|
+
*/
|
|
7086
|
+
defaultRoot: _enum(["data", "media"]).optional()
|
|
7053
7087
|
});
|
|
7054
7088
|
var DecoderStatsSchema = object({
|
|
7055
7089
|
inputFps: number(),
|
|
@@ -7942,6 +7976,10 @@ var RtspRestreamEntrySchema = object({
|
|
|
7942
7976
|
var BrokerRtspClientSchema = object({
|
|
7943
7977
|
sessionId: string(),
|
|
7944
7978
|
remoteAddr: string(),
|
|
7979
|
+
/** Client `User-Agent` (e.g. `recorder` for the recorder's RTSP pull), or
|
|
7980
|
+
* null/absent when the client sent none. Lets the UI label a consumer by
|
|
7981
|
+
* purpose. Optional so a client built against an older schema stays valid. */
|
|
7982
|
+
userAgent: string().nullish(),
|
|
7945
7983
|
playing: boolean(),
|
|
7946
7984
|
muted: boolean(),
|
|
7947
7985
|
connectedAt: number(),
|
|
@@ -9822,6 +9860,31 @@ var ReportMotionInputSchema = object({
|
|
|
9822
9860
|
regions: array(MotionRegionSchema).readonly().optional()
|
|
9823
9861
|
});
|
|
9824
9862
|
/**
|
|
9863
|
+
* Where a runner gets a camera's decoded frames (cross-node Phase 2,
|
|
9864
|
+
* restream-owner model — P2c).
|
|
9865
|
+
*
|
|
9866
|
+
* - `local-broker` (DEFAULT): today's path — subscribe to the co-located
|
|
9867
|
+
* stream-broker's shm frame plane. Every pre-P2c attach payload (no
|
|
9868
|
+
* `frameSource` key) parses to this, so the field is additive with zero
|
|
9869
|
+
* behavior change.
|
|
9870
|
+
* - `remote-restream`: the detect node is NOT the camera's source-owner.
|
|
9871
|
+
* The runner acquires the owner's COMPRESSED passthrough restream
|
|
9872
|
+
* (`streamBroker.getStreamWithCodec({video:'copy'})` — refcounted, the
|
|
9873
|
+
* double-pull guard) and decodes LOCALLY via a satellite frame plane +
|
|
9874
|
+
* pull-mode decoder session pinned to its own node. The shm ring stays
|
|
9875
|
+
* node-local; only H.264/H.265 packets cross the wire.
|
|
9876
|
+
* `hubHostnameOverride` mirrors the recorder's `recordingHubHostname`:
|
|
9877
|
+
* when set it overrides the `CAMSTACK_HUB_URL`-derived host the runner
|
|
9878
|
+
* dials for the owner's restream.
|
|
9879
|
+
*/
|
|
9880
|
+
var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal("local-broker") }), object({
|
|
9881
|
+
kind: literal("remote-restream"),
|
|
9882
|
+
/** The camera's source-owner node (slice 1: always the hub). */
|
|
9883
|
+
ownerNodeId: string(),
|
|
9884
|
+
/** Operator override for the owner host the runner dials. */
|
|
9885
|
+
hubHostnameOverride: string().optional()
|
|
9886
|
+
})]).describe("Per-camera frame-source mode for the runner (P2c)");
|
|
9887
|
+
/**
|
|
9825
9888
|
* Camera assignment payload sent by `addon-pipeline-orchestrator` to a
|
|
9826
9889
|
* specific runner instance via `attachCamera`. Carries everything the
|
|
9827
9890
|
* runner needs to subscribe to the local broker and execute inference.
|
|
@@ -9919,7 +9982,15 @@ var RunnerCameraConfigSchema = object({
|
|
|
9919
9982
|
*/
|
|
9920
9983
|
onboardMotionDrivesAnalyzer: boolean().default(true),
|
|
9921
9984
|
occupancyRecheckSec: number().min(occupancyRecheckSecField.min).max(occupancyRecheckSecField.max).default(occupancyRecheckSecField.default),
|
|
9922
|
-
occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default)
|
|
9985
|
+
occupancyRecheckFrames: number().min(occupancyRecheckFramesField.min).max(occupancyRecheckFramesField.max).default(occupancyRecheckFramesField.default),
|
|
9986
|
+
/**
|
|
9987
|
+
* Where this runner gets the camera's decoded frames (P2c). Defaulted so
|
|
9988
|
+
* every existing payload behaves as `local-broker` — the pre-Phase-2 path.
|
|
9989
|
+
* Populated with `remote-restream` by the orchestrator ONLY when the
|
|
9990
|
+
* camera's detect node differs from its source-owner (P2d, gated by the
|
|
9991
|
+
* `remoteSourcingNodes` rollout setting).
|
|
9992
|
+
*/
|
|
9993
|
+
frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
|
|
9923
9994
|
});
|
|
9924
9995
|
motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
|
|
9925
9996
|
/**
|
|
@@ -13296,7 +13367,7 @@ var AddBrokerInputSchema = object({
|
|
|
13296
13367
|
});
|
|
13297
13368
|
var AddBrokerResultSchema = object({ id: string() });
|
|
13298
13369
|
var IdInputSchema = object({ id: string() });
|
|
13299
|
-
var TestResultSchema = discriminatedUnion("ok", [object({
|
|
13370
|
+
var TestResultSchema$1 = discriminatedUnion("ok", [object({
|
|
13300
13371
|
ok: literal(true),
|
|
13301
13372
|
latencyMs: number()
|
|
13302
13373
|
}), object({
|
|
@@ -13319,7 +13390,7 @@ var StatusSchema = object({
|
|
|
13319
13390
|
brokerCount: number(),
|
|
13320
13391
|
embeddedRunning: boolean()
|
|
13321
13392
|
});
|
|
13322
|
-
method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema), method(AddBrokerInputSchema, AddBrokerResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(IdInputSchema, TestResultSchema, { kind: "mutation" }), method(StartEmbeddedInputSchema, StartEmbeddedResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(_void(), StatusSchema);
|
|
13393
|
+
method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema), method(AddBrokerInputSchema, AddBrokerResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(IdInputSchema, TestResultSchema$1, { kind: "mutation" }), method(StartEmbeddedInputSchema, StartEmbeddedResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(_void(), StatusSchema);
|
|
13323
13394
|
var NetworkEndpointSchema = object({
|
|
13324
13395
|
url: string(),
|
|
13325
13396
|
hostname: string(),
|
|
@@ -13353,23 +13424,198 @@ var NetworkEndpointEntrySchema = NetworkEndpointSchema.extend({
|
|
|
13353
13424
|
sourcePort: number().optional()
|
|
13354
13425
|
});
|
|
13355
13426
|
method(_void(), NetworkEndpointSchema, { kind: "mutation" }), method(_void(), _void(), { kind: "mutation" }), method(_void(), NetworkEndpointSchema.nullable()), method(_void(), NetworkAccessStatusSchema), method(_void(), array(NetworkEndpointEntrySchema).readonly());
|
|
13356
|
-
|
|
13357
|
-
|
|
13427
|
+
/**
|
|
13428
|
+
* notification-output — canonical, capability-gated notification delivery.
|
|
13429
|
+
*
|
|
13430
|
+
* Apprise-derived model (see
|
|
13431
|
+
* `docs/superpowers/specs/2026-07-03-notification-output-notifier-matrix.md`):
|
|
13432
|
+
* callers emit ONE canonical `Notification`; each provider declares a
|
|
13433
|
+
* per-kind capability descriptor (`TargetKind`), and the pure degrade
|
|
13434
|
+
* engine (`@camstack/types` `prepareNotification`) transcodes / degrades the
|
|
13435
|
+
* message to what the kind supports — callers never special-case a service.
|
|
13436
|
+
*
|
|
13437
|
+
* DESIGN DECISIONS (locked):
|
|
13438
|
+
* - Target CRUD lives on THIS cap (`upsertTarget` / `deleteTarget` /
|
|
13439
|
+
* `setTargetEnabled`), each provider persisting via the `settings-store`
|
|
13440
|
+
* cap. Rationale: the admin UI needs one uniform surface across the
|
|
13441
|
+
* notifiers addon AND the HA addon; the addon-`globalSettingsSchema`-array
|
|
13442
|
+
* alternative would fork the UI per addon and cannot host the
|
|
13443
|
+
* discovery→adopt flow.
|
|
13444
|
+
* - `listTargetKinds` / `listTargets` / `discoverTargets` return arrays →
|
|
13445
|
+
* the generated cap-mount auto-`concatCollection`-fans them across every
|
|
13446
|
+
* registered provider (notifiers addon + HA addon) so one catalog is
|
|
13447
|
+
* routable. `send` / `testTarget` / CRUD route to ONE provider by the
|
|
13448
|
+
* `addonId` the generated collection router extracts from the call input.
|
|
13449
|
+
* - `Attachment.bytes` is `Uint8Array`. Transport-safe: superjson (the tRPC
|
|
13450
|
+
* transformer) + UDS MsgPack both round-trip typed arrays — already used by
|
|
13451
|
+
* `storage` / `storage-provider` / `recording` caps over the same path. No
|
|
13452
|
+
* base64 fallback needed.
|
|
13453
|
+
*
|
|
13454
|
+
* TODO (deferred, closed-set change — separate decision): add
|
|
13455
|
+
* `providerKind: 'notify'` so notification providers surface on the unified
|
|
13456
|
+
* admin "Integrations" page.
|
|
13457
|
+
*/
|
|
13458
|
+
/**
|
|
13459
|
+
* Zentik-derived typed-media enum — the superset across every kind. Each
|
|
13460
|
+
* adapter picks what it supports and the degrade engine filters the rest.
|
|
13461
|
+
*/
|
|
13462
|
+
var AttachmentMediaTypeSchema = _enum([
|
|
13463
|
+
"image",
|
|
13464
|
+
"video",
|
|
13465
|
+
"gif",
|
|
13466
|
+
"audio",
|
|
13467
|
+
"icon"
|
|
13468
|
+
]);
|
|
13469
|
+
/**
|
|
13470
|
+
* A single attachment. Exactly one of `url` (remote source, most adapters
|
|
13471
|
+
* prefer this) or `bytes` (inline source; required for Pushover-style
|
|
13472
|
+
* bytes-only kinds) MUST be present — the degrade engine expresses a
|
|
13473
|
+
* url→bytes fetch as a `needsFetch` directive the adapter executes.
|
|
13474
|
+
*/
|
|
13475
|
+
var AttachmentSchema = object({
|
|
13476
|
+
mediaType: AttachmentMediaTypeSchema,
|
|
13477
|
+
url: string().optional(),
|
|
13478
|
+
bytes: _instanceof(Uint8Array).optional(),
|
|
13479
|
+
mime: string().optional(),
|
|
13480
|
+
name: string().optional()
|
|
13481
|
+
}).refine((a) => a.url !== void 0 || a.bytes !== void 0, { message: "Attachment requires either `url` or `bytes`" });
|
|
13482
|
+
var NotificationFormatSchema = _enum([
|
|
13483
|
+
"text",
|
|
13484
|
+
"markdown",
|
|
13485
|
+
"html"
|
|
13486
|
+
]);
|
|
13487
|
+
/** A single tap-through action button. */
|
|
13488
|
+
var NotificationActionSchema = object({
|
|
13489
|
+
id: string(),
|
|
13490
|
+
label: string(),
|
|
13491
|
+
url: string().optional()
|
|
13492
|
+
});
|
|
13493
|
+
/**
|
|
13494
|
+
* The canonical notification. `body` is the only hard field (Apprise model).
|
|
13495
|
+
* `priority` is a 5-level ORDINAL (1=lowest … 3=normal(default) … 5=urgent),
|
|
13496
|
+
* NOT a fixed severity enum — each kind declares its own `caps.levels` and
|
|
13497
|
+
* the adapter maps this ordinal onto its native level. `level?` is an
|
|
13498
|
+
* optional kind-native level id (`emergency`, `silent`, …) that overrides
|
|
13499
|
+
* `priority` for that one target.
|
|
13500
|
+
*/
|
|
13501
|
+
var NotificationSchema = object({
|
|
13358
13502
|
body: string(),
|
|
13359
|
-
|
|
13503
|
+
title: string().optional(),
|
|
13504
|
+
format: NotificationFormatSchema.default("text"),
|
|
13505
|
+
priority: number().int().min(1).max(5).default(3),
|
|
13506
|
+
level: string().optional(),
|
|
13507
|
+
attachments: array(AttachmentSchema).optional(),
|
|
13508
|
+
clickUrl: string().optional(),
|
|
13509
|
+
actions: array(NotificationActionSchema).optional(),
|
|
13510
|
+
sound: string().optional(),
|
|
13511
|
+
ttl: number().optional(),
|
|
13512
|
+
tag: string().optional(),
|
|
13360
13513
|
deviceId: number().optional(),
|
|
13361
13514
|
eventId: string().optional(),
|
|
13362
|
-
priority: _enum([
|
|
13363
|
-
"low",
|
|
13364
|
-
"normal",
|
|
13365
|
-
"high",
|
|
13366
|
-
"critical"
|
|
13367
|
-
]).default("normal"),
|
|
13368
13515
|
metadata: record(string(), unknown()).optional()
|
|
13369
|
-
})
|
|
13516
|
+
});
|
|
13517
|
+
/** One declared native severity/priority level for a kind. */
|
|
13518
|
+
var TargetKindLevelSchema = object({
|
|
13519
|
+
id: string(),
|
|
13520
|
+
label: string(),
|
|
13521
|
+
/** Which canonical priority (1..5) this level maps to. `null` = qualitative-only. */
|
|
13522
|
+
ordinal: number().int().min(1).max(5).nullable(),
|
|
13523
|
+
flags: object({
|
|
13524
|
+
critical: boolean().optional(),
|
|
13525
|
+
silent: boolean().optional(),
|
|
13526
|
+
noPush: boolean().optional()
|
|
13527
|
+
}).optional(),
|
|
13528
|
+
/** e.g. Pushover `emergency` requires `retry` / `expire`. */
|
|
13529
|
+
requires: array(string()).optional(),
|
|
13530
|
+
description: string().optional()
|
|
13531
|
+
});
|
|
13532
|
+
/** The full capability block consulted before dispatch. */
|
|
13533
|
+
var TargetKindCapsSchema = object({
|
|
13534
|
+
attachments: object({
|
|
13535
|
+
mediaTypes: array(AttachmentMediaTypeSchema),
|
|
13536
|
+
mode: _enum([
|
|
13537
|
+
"url",
|
|
13538
|
+
"bytes",
|
|
13539
|
+
"both"
|
|
13540
|
+
]),
|
|
13541
|
+
max: number().int().nonnegative(),
|
|
13542
|
+
maxBytes: number().int().positive().optional()
|
|
13543
|
+
}),
|
|
13544
|
+
/** Max action buttons (0 = none). */
|
|
13545
|
+
actions: number().int().nonnegative(),
|
|
13546
|
+
levels: array(TargetKindLevelSchema),
|
|
13547
|
+
format: array(NotificationFormatSchema),
|
|
13548
|
+
clickUrl: boolean(),
|
|
13549
|
+
sound: boolean(),
|
|
13550
|
+
ttl: boolean(),
|
|
13551
|
+
bodyMaxLen: number().int().positive()
|
|
13552
|
+
});
|
|
13553
|
+
/**
|
|
13554
|
+
* `configSchema` is a `ConfigUISchema` tree passed through to the admin
|
|
13555
|
+
* FormBuilder. Stored as `z.unknown()` at the cap seam (mirrors
|
|
13556
|
+
* `device-provider.getChildCreationSchema` `CreationSchemaOutputSchema`) —
|
|
13557
|
+
* the union is large and not meant for runtime validation here; the exported
|
|
13558
|
+
* `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
|
|
13559
|
+
*/
|
|
13560
|
+
var ConfigSchemaPassthrough = unknown();
|
|
13561
|
+
var TargetKindSchema = object({
|
|
13562
|
+
kind: string(),
|
|
13563
|
+
label: string(),
|
|
13564
|
+
icon: string(),
|
|
13565
|
+
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
13566
|
+
addonId: string(),
|
|
13567
|
+
configSchema: ConfigSchemaPassthrough,
|
|
13568
|
+
supportsDiscovery: boolean(),
|
|
13569
|
+
caps: TargetKindCapsSchema
|
|
13570
|
+
});
|
|
13571
|
+
/**
|
|
13572
|
+
* A persisted target. `config` holds secrets; providers REDACT secret fields
|
|
13573
|
+
* (return a presence marker only) when serving `listTargets` — never
|
|
13574
|
+
* round-trip a stored secret to the UI.
|
|
13575
|
+
*/
|
|
13576
|
+
var TargetSchema = object({
|
|
13577
|
+
id: string(),
|
|
13578
|
+
name: string(),
|
|
13579
|
+
kind: string(),
|
|
13580
|
+
addonId: string(),
|
|
13581
|
+
enabled: boolean(),
|
|
13582
|
+
config: record(string(), unknown())
|
|
13583
|
+
});
|
|
13584
|
+
/** A discovery-surfaced candidate (config is partial + non-secret). */
|
|
13585
|
+
var DiscoveredTargetSchema = object({
|
|
13586
|
+
kind: string(),
|
|
13587
|
+
suggestedName: string(),
|
|
13588
|
+
config: record(string(), unknown())
|
|
13589
|
+
});
|
|
13590
|
+
/** The degrade engine's report — what was resolved / dropped / degraded. */
|
|
13591
|
+
var RenderedAsSchema = object({
|
|
13592
|
+
level: string(),
|
|
13593
|
+
format: NotificationFormatSchema,
|
|
13594
|
+
attachmentsSent: number().int().nonnegative(),
|
|
13595
|
+
actionsSent: number().int().nonnegative(),
|
|
13596
|
+
truncated: boolean(),
|
|
13597
|
+
dropped: array(string())
|
|
13598
|
+
});
|
|
13599
|
+
var SendResultSchema = object({
|
|
13370
13600
|
success: boolean(),
|
|
13371
|
-
error: string().optional()
|
|
13372
|
-
|
|
13601
|
+
error: string().optional(),
|
|
13602
|
+
renderedAs: RenderedAsSchema.optional()
|
|
13603
|
+
});
|
|
13604
|
+
/** Same shape as SendResult — kept as a distinct name for the test panel. */
|
|
13605
|
+
var TestResultSchema = SendResultSchema;
|
|
13606
|
+
method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSchema)), method(object({
|
|
13607
|
+
kind: string(),
|
|
13608
|
+
config: record(string(), unknown()).optional()
|
|
13609
|
+
}), array(DiscoveredTargetSchema)), method(object({
|
|
13610
|
+
targetId: string(),
|
|
13611
|
+
notification: NotificationSchema
|
|
13612
|
+
}), SendResultSchema, { kind: "mutation" }), method(object({
|
|
13613
|
+
targetId: string(),
|
|
13614
|
+
sample: NotificationSchema.optional()
|
|
13615
|
+
}), TestResultSchema, { kind: "mutation" }), method(object({ target: TargetSchema }), TargetSchema, { kind: "mutation" }), method(object({ targetId: string() }), _void(), { kind: "mutation" }), method(object({
|
|
13616
|
+
targetId: string(),
|
|
13617
|
+
enabled: boolean()
|
|
13618
|
+
}), _void(), { kind: "mutation" });
|
|
13373
13619
|
/**
|
|
13374
13620
|
* Zod schemas for persisted record types.
|
|
13375
13621
|
*
|
|
@@ -16676,6 +16922,16 @@ DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceI
|
|
|
16676
16922
|
kind: "mutation",
|
|
16677
16923
|
auth: "admin"
|
|
16678
16924
|
});
|
|
16925
|
+
/**
|
|
16926
|
+
* `recording` cap — footage availability + HLS playback manifests + per-device
|
|
16927
|
+
* recording config. NOTE on events (source of truth, R5/C3): this cap carries
|
|
16928
|
+
* NO event surface — `getPlaybackManifest` returns playlist URLs only. Timeline
|
|
16929
|
+
* events (motion/object/audio) come from `pipelineAnalytics` (durable SQLite
|
|
16930
|
+
* rows); the recorder's internal EventMap markers are ephemeral in-RAM
|
|
16931
|
+
* annotations that are not exposed here and must not be treated as an event
|
|
16932
|
+
* feed. Event<->footage joins are by time, padded with the shared `EVENT_PAD_MS`
|
|
16933
|
+
* (`interfaces/recording-config.ts`).
|
|
16934
|
+
*/
|
|
16679
16935
|
var RecordingStatusSchema = object({
|
|
16680
16936
|
deviceId: number(),
|
|
16681
16937
|
enabled: boolean(),
|
|
@@ -19482,13 +19738,49 @@ Object.freeze({
|
|
|
19482
19738
|
addonId: null,
|
|
19483
19739
|
access: "create"
|
|
19484
19740
|
},
|
|
19741
|
+
"notificationOutput.deleteTarget": {
|
|
19742
|
+
capName: "notification-output",
|
|
19743
|
+
capScope: "system",
|
|
19744
|
+
addonId: null,
|
|
19745
|
+
access: "delete"
|
|
19746
|
+
},
|
|
19747
|
+
"notificationOutput.discoverTargets": {
|
|
19748
|
+
capName: "notification-output",
|
|
19749
|
+
capScope: "system",
|
|
19750
|
+
addonId: null,
|
|
19751
|
+
access: "view"
|
|
19752
|
+
},
|
|
19753
|
+
"notificationOutput.listTargetKinds": {
|
|
19754
|
+
capName: "notification-output",
|
|
19755
|
+
capScope: "system",
|
|
19756
|
+
addonId: null,
|
|
19757
|
+
access: "view"
|
|
19758
|
+
},
|
|
19759
|
+
"notificationOutput.listTargets": {
|
|
19760
|
+
capName: "notification-output",
|
|
19761
|
+
capScope: "system",
|
|
19762
|
+
addonId: null,
|
|
19763
|
+
access: "view"
|
|
19764
|
+
},
|
|
19485
19765
|
"notificationOutput.send": {
|
|
19486
19766
|
capName: "notification-output",
|
|
19487
19767
|
capScope: "system",
|
|
19488
19768
|
addonId: null,
|
|
19489
19769
|
access: "create"
|
|
19490
19770
|
},
|
|
19491
|
-
"notificationOutput.
|
|
19771
|
+
"notificationOutput.setTargetEnabled": {
|
|
19772
|
+
capName: "notification-output",
|
|
19773
|
+
capScope: "system",
|
|
19774
|
+
addonId: null,
|
|
19775
|
+
access: "create"
|
|
19776
|
+
},
|
|
19777
|
+
"notificationOutput.testTarget": {
|
|
19778
|
+
capName: "notification-output",
|
|
19779
|
+
capScope: "system",
|
|
19780
|
+
addonId: null,
|
|
19781
|
+
access: "create"
|
|
19782
|
+
},
|
|
19783
|
+
"notificationOutput.upsertTarget": {
|
|
19492
19784
|
capName: "notification-output",
|
|
19493
19785
|
capScope: "system",
|
|
19494
19786
|
addonId: null,
|
|
@@ -21474,4 +21766,4 @@ object({
|
|
|
21474
21766
|
schemaVersion: literal(1)
|
|
21475
21767
|
});
|
|
21476
21768
|
//#endregion
|
|
21477
|
-
export {
|
|
21769
|
+
export { object as C, number as S, tuple as T, createEvent as _, embeddingEncoderCapability as a, array as b, pipelineAnalyticsCapability as c, zoneAnalyticsCapability as d, errMsg as f, asJsonObject as g, EventCategory as h, cosineSimilarity as i, plateGalleryCapability as l, DeviceType as m, addonWidgetsSourceCapability as n, faceGalleryCapability as o, BaseAddon as p, audioMetricsCapability as r, hfModelUrl as s, EVENT_PAD_MS as t, videoclipsCapability as u, hydrateSchema as v, string as w, boolean as x, _enum as y };
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-DrqXmZjI.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
let node_fs$1 = require_dist.__toESM(node_fs, 1);
|
|
8
8
|
node_fs = require_dist.__toESM(node_fs);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as embeddingEncoderCapability, p as BaseAddon, s as hfModelUrl } from "../dist-XlUdQXHn.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
6
|
-
const require_resolve_frame = require("../resolve-frame-
|
|
5
|
+
const require_dist = require("../dist-DrqXmZjI.js");
|
|
6
|
+
const require_resolve_frame = require("../resolve-frame-Dciml-ds.js");
|
|
7
7
|
let _camstack_shm_ring = require("@camstack/shm-ring");
|
|
8
8
|
//#region src/enrichment-engine/types.ts
|
|
9
9
|
var DEFAULT_ENRICHMENT_CONFIG = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as object, S as number, T as tuple, _ as createEvent, b as array, g as asJsonObject, h as EventCategory, p as BaseAddon, w as string, x as boolean, y as _enum } from "../dist-XlUdQXHn.mjs";
|
|
2
2
|
import { n as extractCrop, t as resolveFrame } from "../resolve-frame-CT1T1tWy.mjs";
|
|
3
3
|
import { FrameRingReaderCache } from "@camstack/shm-ring";
|
|
4
4
|
//#region src/enrichment-engine/types.ts
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
const require_dist = require("./dist-DrqXmZjI.js");
|
|
2
|
+
let node_fs = require("node:fs");
|
|
3
|
+
node_fs = require_dist.__toESM(node_fs, 1);
|
|
4
|
+
let node_path = require("node:path");
|
|
5
|
+
node_path = require_dist.__toESM(node_path, 1);
|
|
6
|
+
require("node:crypto");
|
|
7
|
+
require("node:child_process");
|
|
8
|
+
var STORAGE_LOCATION_TYPES = [
|
|
9
|
+
"data",
|
|
10
|
+
"media",
|
|
11
|
+
"recordings",
|
|
12
|
+
"recordings-high",
|
|
13
|
+
"recordings-low",
|
|
14
|
+
"recordings-clips",
|
|
15
|
+
"event-images",
|
|
16
|
+
"models",
|
|
17
|
+
"addons-data",
|
|
18
|
+
"cache",
|
|
19
|
+
"logs",
|
|
20
|
+
"backups"
|
|
21
|
+
];
|
|
22
|
+
var DEFAULT_LOCATION_SUBDIRS = {
|
|
23
|
+
data: "db",
|
|
24
|
+
media: "media",
|
|
25
|
+
recordings: "recordings",
|
|
26
|
+
"recordings-high": "recordings-high",
|
|
27
|
+
"recordings-low": "recordings-low",
|
|
28
|
+
"recordings-clips": "recordings-clips",
|
|
29
|
+
"event-images": "event-images",
|
|
30
|
+
models: "models",
|
|
31
|
+
"addons-data": "addons-data",
|
|
32
|
+
cache: "/tmp/camstack-cache",
|
|
33
|
+
logs: "logs",
|
|
34
|
+
backups: "backups"
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Filesystem storage provider — serves all location types from a local directory tree.
|
|
38
|
+
*
|
|
39
|
+
* Default layout:
|
|
40
|
+
* {rootPath}/recordings-high/
|
|
41
|
+
* {rootPath}/recordings-low/
|
|
42
|
+
* {rootPath}/recordings-clips/
|
|
43
|
+
* {rootPath}/event-images/
|
|
44
|
+
* {rootPath}/models/
|
|
45
|
+
* {rootPath}/addons-data/
|
|
46
|
+
* {rootPath}/logs/
|
|
47
|
+
* /tmp/camstack-cache/ (cache is always local)
|
|
48
|
+
*
|
|
49
|
+
* Individual location paths can be overridden.
|
|
50
|
+
*/
|
|
51
|
+
var FilesystemStorageProvider = class {
|
|
52
|
+
id = "local";
|
|
53
|
+
name = "Local Filesystem";
|
|
54
|
+
supportedLocations = [...STORAGE_LOCATION_TYPES];
|
|
55
|
+
rootPath;
|
|
56
|
+
locationPaths;
|
|
57
|
+
constructor(rootPath, overrides) {
|
|
58
|
+
this.rootPath = node_path.resolve(rootPath);
|
|
59
|
+
this.locationPaths = /* @__PURE__ */ new Map();
|
|
60
|
+
for (const loc of STORAGE_LOCATION_TYPES) {
|
|
61
|
+
const override = overrides?.[loc];
|
|
62
|
+
if (override) this.locationPaths.set(loc, node_path.resolve(override));
|
|
63
|
+
else {
|
|
64
|
+
const subdir = DEFAULT_LOCATION_SUBDIRS[loc] ?? loc;
|
|
65
|
+
this.locationPaths.set(loc, node_path.isAbsolute(subdir) ? subdir : node_path.join(this.rootPath, subdir));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async resolve({ location, relativePath }) {
|
|
70
|
+
const base = this.locationPaths.get(location) ?? node_path.join(this.rootPath, location);
|
|
71
|
+
return node_path.join(base, relativePath);
|
|
72
|
+
}
|
|
73
|
+
async write({ location, relativePath, data }) {
|
|
74
|
+
const filePath = await this.resolve({
|
|
75
|
+
location,
|
|
76
|
+
relativePath
|
|
77
|
+
});
|
|
78
|
+
await node_fs.promises.mkdir(node_path.dirname(filePath), { recursive: true });
|
|
79
|
+
if (Buffer.isBuffer(data)) await node_fs.promises.writeFile(filePath, data);
|
|
80
|
+
else {
|
|
81
|
+
const writeStream = node_fs.createWriteStream(filePath);
|
|
82
|
+
await new Promise((resolve, reject) => {
|
|
83
|
+
data.pipe(writeStream);
|
|
84
|
+
writeStream.on("finish", resolve);
|
|
85
|
+
writeStream.on("error", reject);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async read({ location, relativePath }) {
|
|
90
|
+
return node_fs.promises.readFile(await this.resolve({
|
|
91
|
+
location,
|
|
92
|
+
relativePath
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
async exists({ location, relativePath }) {
|
|
96
|
+
try {
|
|
97
|
+
await node_fs.promises.access(await this.resolve({
|
|
98
|
+
location,
|
|
99
|
+
relativePath
|
|
100
|
+
}));
|
|
101
|
+
return true;
|
|
102
|
+
} catch {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async list({ location, prefix }) {
|
|
107
|
+
const base = this.locationPaths.get(location);
|
|
108
|
+
if (!base) return [];
|
|
109
|
+
const dir = prefix ? node_path.join(base, prefix) : base;
|
|
110
|
+
try {
|
|
111
|
+
return (await node_fs.promises.readdir(dir, { withFileTypes: true })).map((e) => prefix ? `${prefix}/${e.name}` : e.name);
|
|
112
|
+
} catch {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async delete({ location, relativePath }) {
|
|
117
|
+
const filePath = await this.resolve({
|
|
118
|
+
location,
|
|
119
|
+
relativePath
|
|
120
|
+
});
|
|
121
|
+
await node_fs.promises.rm(filePath, { force: true });
|
|
122
|
+
}
|
|
123
|
+
async getAvailableSpace({ location }) {
|
|
124
|
+
const base = this.locationPaths.get(location);
|
|
125
|
+
if (!base) return null;
|
|
126
|
+
try {
|
|
127
|
+
let target = base;
|
|
128
|
+
while (!node_fs.existsSync(target)) {
|
|
129
|
+
const parent = node_path.dirname(target);
|
|
130
|
+
if (!parent || parent === target) return null;
|
|
131
|
+
target = parent;
|
|
132
|
+
}
|
|
133
|
+
const stats = await node_fs.promises.statfs(target);
|
|
134
|
+
return stats.bavail * stats.bsize;
|
|
135
|
+
} catch {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/** Get the resolved path for a location type (addon-declared ids fall back
|
|
140
|
+
* to `<rootPath>/<id>`). */
|
|
141
|
+
getLocationPath(location) {
|
|
142
|
+
return this.locationPaths.get(location) ?? node_path.join(this.rootPath, location);
|
|
143
|
+
}
|
|
144
|
+
/** Get the root path */
|
|
145
|
+
getRootPath() {
|
|
146
|
+
return this.rootPath;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
//#endregion
|
|
150
|
+
exports.FilesystemStorageProvider = FilesystemStorageProvider;
|