@camstack/addon-pipeline 1.2.107 → 1.2.115
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-utils-Vv2dCqA2.js → addon-utils-C0ht2KPO.js} +51 -15
- package/dist/{addon-utils-A2S9D7pu.mjs → addon-utils-CgBCF-mE.mjs} +50 -14
- package/dist/audio-analyzer/index.js +3 -3
- package/dist/audio-analyzer/index.mjs +3 -3
- package/dist/detection-pipeline/index.js +170 -31
- package/dist/detection-pipeline/index.mjs +169 -30
- package/dist/{dist-L-1LMGQs.js → dist-BqIbYW1A.js} +130 -17
- package/dist/{dist-CkXAzTZ2.mjs → dist-DGQkkWc6.mjs} +130 -17
- package/dist/{event-loop-stall-monitor-fHkfgmlw.mjs → event-loop-stall-monitor-D5jK5v4Z.mjs} +223 -2
- package/dist/{event-loop-stall-monitor-DwAho7HD.js → event-loop-stall-monitor-ylMGpz48.js} +234 -1
- package/dist/{lazy-sharp-DfbyQxET.js → lazy-sharp-cOsy7l_P.js} +1 -1
- package/dist/motion-wasm/index.js +2 -2
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +915 -107
- package/dist/pipeline-runner/index.mjs +914 -106
- package/dist/{process-memory-CgrbLo3l.js → process-memory-45juuHpN.js} +1 -1
- package/dist/{process-memory-DlSOzuHP.mjs → process-memory-BtT7WfbJ.mjs} +1 -1
- package/dist/recorder/index.js +187 -47
- package/dist/recorder/index.mjs +187 -47
- package/dist/session-decode/decode-worker-child.js +30 -10
- package/dist/session-decode/decode-worker-child.mjs +29 -9
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BeL4_jgH.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-C_SFFNGT.mjs} +3 -3
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B1LDFHY9.mjs +26 -0
- package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CmHtm5CX.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BAMyzCWw.mjs} +1 -1
- package/dist/stream-broker/{hostInit-BK9nzKAG.mjs → hostInit-CG28NvlV.mjs} +3 -3
- package/dist/stream-broker/index.js +279 -198
- package/dist/stream-broker/index.mjs +279 -198
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/{worker-protocol-GGnzfWu3.js → worker-protocol-CIrqGbpG.js} +6 -3
- package/dist/{worker-protocol-bEipQT9l.mjs → worker-protocol-DyocTIx_.mjs} +6 -3
- package/package.json +1 -1
- package/python/inference_pool.py +4 -1
- package/python/test_inference_pool_preprocess.py +87 -16
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DjndFc5V.mjs +0 -26
|
@@ -9058,6 +9058,15 @@ var LabelDefinitionSchema = object({
|
|
|
9058
9058
|
description: string().optional(),
|
|
9059
9059
|
icon: string().optional()
|
|
9060
9060
|
});
|
|
9061
|
+
var ClassMapDefinitionSchema = object({
|
|
9062
|
+
mapping: record(string(), _enum([
|
|
9063
|
+
"person",
|
|
9064
|
+
"vehicle",
|
|
9065
|
+
"animal",
|
|
9066
|
+
"package"
|
|
9067
|
+
])),
|
|
9068
|
+
preserveOriginal: boolean()
|
|
9069
|
+
});
|
|
9061
9070
|
var MODEL_FORMATS = [
|
|
9062
9071
|
"onnx",
|
|
9063
9072
|
"coreml",
|
|
@@ -9236,7 +9245,13 @@ var ModelCatalogEntrySchema = object({
|
|
|
9236
9245
|
* `id` stays the source of truth for resolution/download/persistence; grouping
|
|
9237
9246
|
* is a presentation overlay resolved back to an `id`.
|
|
9238
9247
|
*/
|
|
9239
|
-
group: ModelVariantGroupSchema.optional()
|
|
9248
|
+
group: ModelVariantGroupSchema.optional(),
|
|
9249
|
+
/**
|
|
9250
|
+
* Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
|
|
9251
|
+
* applies (Frigate / COCO public catalog). Set on a custom model whose raw
|
|
9252
|
+
* labels already ARE the CamStack macros (Scrypted identity map).
|
|
9253
|
+
*/
|
|
9254
|
+
classMap: ClassMapDefinitionSchema.optional()
|
|
9240
9255
|
});
|
|
9241
9256
|
var ConvertTargetSchema = discriminatedUnion("format", [object({
|
|
9242
9257
|
format: literal("openvino"),
|
|
@@ -9265,7 +9280,8 @@ var ModelConvertMetadataSchema = object({
|
|
|
9265
9280
|
"ocr",
|
|
9266
9281
|
"segmentation"
|
|
9267
9282
|
]),
|
|
9268
|
-
faceAlignment: boolean().optional()
|
|
9283
|
+
faceAlignment: boolean().optional(),
|
|
9284
|
+
classMap: ClassMapDefinitionSchema.optional()
|
|
9269
9285
|
});
|
|
9270
9286
|
var ConvertResultSchema = object({
|
|
9271
9287
|
entry: ModelCatalogEntrySchema,
|
|
@@ -19049,6 +19065,33 @@ var NativeCropRefSchema = object({
|
|
|
19049
19065
|
h: number()
|
|
19050
19066
|
})
|
|
19051
19067
|
});
|
|
19068
|
+
object({
|
|
19069
|
+
crop: object({
|
|
19070
|
+
left: number(),
|
|
19071
|
+
top: number(),
|
|
19072
|
+
width: number().positive(),
|
|
19073
|
+
height: number().positive()
|
|
19074
|
+
}).optional(),
|
|
19075
|
+
content: object({
|
|
19076
|
+
width: number().int().positive(),
|
|
19077
|
+
height: number().int().positive()
|
|
19078
|
+
}),
|
|
19079
|
+
fit: _enum(["stretch", "contain"]),
|
|
19080
|
+
format: _enum([
|
|
19081
|
+
"rgb",
|
|
19082
|
+
"gray",
|
|
19083
|
+
"jpeg"
|
|
19084
|
+
])
|
|
19085
|
+
});
|
|
19086
|
+
var FrameRefSchema = object({
|
|
19087
|
+
registryId: string().min(1),
|
|
19088
|
+
id: string().min(1),
|
|
19089
|
+
width: number().int().positive(),
|
|
19090
|
+
height: number().int().positive(),
|
|
19091
|
+
format: _enum(["rgb", "gray"]),
|
|
19092
|
+
timestamp: number(),
|
|
19093
|
+
capturedAt: number().optional()
|
|
19094
|
+
});
|
|
19052
19095
|
var ModelFormatSchema$1 = _enum([
|
|
19053
19096
|
"onnx",
|
|
19054
19097
|
"coreml",
|
|
@@ -19369,7 +19412,7 @@ var pipelineExecutorCapability = {
|
|
|
19369
19412
|
* legacy call shape used by existing benchmark code; once all
|
|
19370
19413
|
* callers pass it explicitly we make it required.
|
|
19371
19414
|
*
|
|
19372
|
-
* Exactly one of `frame`, `frameHandle`, `imageBase64`,
|
|
19415
|
+
* Exactly one of `frame`, `frameRef`, `frameHandle`, `imageBase64`,
|
|
19373
19416
|
* `referenceImage` must be provided:
|
|
19374
19417
|
* - `frame`: runtime dispatch path (runner → decoded broker frame).
|
|
19375
19418
|
* Carries the raw buffer, dimensions, and format; the executor
|
|
@@ -19391,6 +19434,12 @@ var pipelineExecutorCapability = {
|
|
|
19391
19434
|
steps: array(PipelineStepInputSchema).min(1),
|
|
19392
19435
|
frame: FrameInputSchema.optional(),
|
|
19393
19436
|
/**
|
|
19437
|
+
* Process-local lazy frame. Valid only when caller and provider resolve
|
|
19438
|
+
* in the same execution-group process; split/cross-node callers use
|
|
19439
|
+
* `frame`/`image` inline compatibility instead.
|
|
19440
|
+
*/
|
|
19441
|
+
frameRef: FrameRefSchema.optional(),
|
|
19442
|
+
/**
|
|
19394
19443
|
* CB5 shm passthrough — a `FrameHandle` naming the same ring slot
|
|
19395
19444
|
* the decoded pixels live in. One more member of the one-of
|
|
19396
19445
|
* frame/frameHandle/image/imageBase64/referenceImage group.
|
|
@@ -19700,7 +19749,10 @@ var NativeCropResultSchema = object({
|
|
|
19700
19749
|
* Which source served this crop, so a quality-sensitive consumer (the native
|
|
19701
19750
|
* `keyFrame`) can reject a degraded fallback:
|
|
19702
19751
|
* - `native` — cut from the decode worker's retained NATIVE surface (the
|
|
19703
|
-
* quality path).
|
|
19752
|
+
* quality path). A subject-tile serve is also native-resolution and stays
|
|
19753
|
+
* `native` here: the public enum cannot name `tile` without a breaking cap
|
|
19754
|
+
* change. Runner telemetry distinguishes lease vs tile via `source` on the
|
|
19755
|
+
* internal crop result (`nativeHits` vs `tileHits`).
|
|
19704
19756
|
* - `ram-fullframe` — the native surface MISSED but the request was full-frame,
|
|
19705
19757
|
* so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
|
|
19706
19758
|
* the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
|
|
@@ -20191,12 +20243,41 @@ var RunnerLocalLoadSchema = object({
|
|
|
20191
20243
|
* legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
|
|
20192
20244
|
* working unchanged when they switch to reading from the runner cap.
|
|
20193
20245
|
*/
|
|
20246
|
+
var FrameLazyCountersSchema = object({
|
|
20247
|
+
framesDecoded: number(),
|
|
20248
|
+
framesAdmitted: number(),
|
|
20249
|
+
framesDroppedPixelFree: number(),
|
|
20250
|
+
viewsMaterialized: number(),
|
|
20251
|
+
viewsSkipped: number(),
|
|
20252
|
+
workerToRunnerBytes: number(),
|
|
20253
|
+
runnerToPoolRawBytes: number(),
|
|
20254
|
+
runnerToPoolJpegBytes: number(),
|
|
20255
|
+
onDemandFullFrameRequests: number(),
|
|
20256
|
+
onDemandCropRequests: number(),
|
|
20257
|
+
nativeHits: number(),
|
|
20258
|
+
nativeMisses: number(),
|
|
20259
|
+
tileHits: number(),
|
|
20260
|
+
tileMisses: number(),
|
|
20261
|
+
fallbackHits: number(),
|
|
20262
|
+
fallbackMisses: number(),
|
|
20263
|
+
retainedWritesAvoided: number(),
|
|
20264
|
+
residentRefs: number(),
|
|
20265
|
+
residentBytes: number(),
|
|
20266
|
+
releases: number(),
|
|
20267
|
+
evictions: number(),
|
|
20268
|
+
staleMisses: number()
|
|
20269
|
+
});
|
|
20270
|
+
var FrameLazyMetricsSchema = object({
|
|
20271
|
+
node: FrameLazyCountersSchema,
|
|
20272
|
+
cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
|
|
20273
|
+
});
|
|
20194
20274
|
var RunnerLocalMetricsSchema = object({
|
|
20195
20275
|
nodeId: string(),
|
|
20196
20276
|
activeCameras: number(),
|
|
20197
20277
|
throttledCameras: number(),
|
|
20198
20278
|
avgInferenceTimeMs: number(),
|
|
20199
|
-
queueDepth: number()
|
|
20279
|
+
queueDepth: number(),
|
|
20280
|
+
frameLazy: FrameLazyMetricsSchema.optional()
|
|
20200
20281
|
});
|
|
20201
20282
|
/**
|
|
20202
20283
|
* Pipeline Runner capability — runtime detection workhorse.
|
|
@@ -21653,6 +21734,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
|
|
|
21653
21734
|
location: StorageLocationSchema,
|
|
21654
21735
|
relativePath: string()
|
|
21655
21736
|
}), _void(), { kind: "mutation" }), method(object({ location: StorageLocationSchema }), number().nullable()), method(BeginUploadInputSchema, BeginUploadResultSchema, { kind: "mutation" }), method(WriteChunkInputSchema, _void(), { kind: "mutation" }), method(FinalizeUploadInputSchema, _void(), { kind: "mutation" }), method(AbortUploadInputSchema, _void(), { kind: "mutation" }), method(BeginDownloadInputSchema, BeginDownloadResultSchema, { kind: "mutation" }), method(ReadChunkInputSchema, _instanceof(Uint8Array)), method(EndDownloadInputSchema, _void(), { kind: "mutation" });
|
|
21737
|
+
/** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
|
|
21738
|
+
var ProfileSettingsSchemaBridge = unknown().nullable();
|
|
21739
|
+
var ProfileSettingsBagSchema = record(string(), unknown());
|
|
21656
21740
|
/**
|
|
21657
21741
|
* A live terminal session hosted by the provider addon. Output and input do
|
|
21658
21742
|
* NOT flow through the capability — they use the addon data plane
|
|
@@ -21687,7 +21771,9 @@ var TerminalProfileInfoSchema = object({
|
|
|
21687
21771
|
executable: string().optional(),
|
|
21688
21772
|
args: array(string()).readonly().optional(),
|
|
21689
21773
|
cwd: string().optional(),
|
|
21690
|
-
environment: array(string()).readonly().optional()
|
|
21774
|
+
environment: array(string()).readonly().optional(),
|
|
21775
|
+
/** ConfigUISchema for instance knobs, or null when the profile has none. */
|
|
21776
|
+
settingsSchema: ProfileSettingsSchemaBridge.optional()
|
|
21691
21777
|
});
|
|
21692
21778
|
/**
|
|
21693
21779
|
* A durable operator-created Terminal instance. Profiles are templates; only
|
|
@@ -21704,7 +21790,8 @@ var TerminalInstanceInfoSchema = object({
|
|
|
21704
21790
|
executable: string(),
|
|
21705
21791
|
args: array(string()).readonly(),
|
|
21706
21792
|
cwd: string(),
|
|
21707
|
-
environment: array(string()).readonly()
|
|
21793
|
+
environment: array(string()).readonly(),
|
|
21794
|
+
profileSettings: ProfileSettingsBagSchema
|
|
21708
21795
|
});
|
|
21709
21796
|
var TerminalLegacyCameraSchema = object({
|
|
21710
21797
|
stableId: string(),
|
|
@@ -21738,7 +21825,8 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
|
|
|
21738
21825
|
executable: string().max(1024).optional(),
|
|
21739
21826
|
args: array(string().max(2048)).max(64).optional(),
|
|
21740
21827
|
cwd: string().max(1024).optional(),
|
|
21741
|
-
environment: array(string().max(4096)).max(64).optional()
|
|
21828
|
+
environment: array(string().max(4096)).max(64).optional(),
|
|
21829
|
+
profileSettings: ProfileSettingsBagSchema.optional()
|
|
21742
21830
|
}), TerminalInstanceInfoSchema, {
|
|
21743
21831
|
kind: "mutation",
|
|
21744
21832
|
auth: "admin"
|
|
@@ -21748,7 +21836,8 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
|
|
|
21748
21836
|
executable: string().max(1024).optional(),
|
|
21749
21837
|
args: array(string().max(2048)).max(64).optional(),
|
|
21750
21838
|
cwd: string().max(1024).optional(),
|
|
21751
|
-
environment: array(string().max(4096)).max(64).optional()
|
|
21839
|
+
environment: array(string().max(4096)).max(64).optional(),
|
|
21840
|
+
profileSettings: ProfileSettingsBagSchema.optional()
|
|
21752
21841
|
}), TerminalInstanceInfoSchema, {
|
|
21753
21842
|
kind: "mutation",
|
|
21754
21843
|
auth: "admin"
|
|
@@ -24703,10 +24792,10 @@ DeviceType.LawnMower, method(object({ deviceId: number().int().nonnegative() }),
|
|
|
24703
24792
|
*
|
|
24704
24793
|
* • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
|
|
24705
24794
|
* to receive an ordered list of candidate base URLs it should race
|
|
24706
|
-
* on connect — LAN IPv4 first (lowest latency
|
|
24707
|
-
* then public hostname (if a tunnel is
|
|
24708
|
-
* race them with short timeouts and stick with the
|
|
24709
|
-
* session.
|
|
24795
|
+
* on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
|
|
24796
|
+
* when on the same network), then public hostname (if a tunnel is
|
|
24797
|
+
* up). The SDK can race them with short timeouts and stick with the
|
|
24798
|
+
* winner for the session.
|
|
24710
24799
|
*
|
|
24711
24800
|
* Why hub-only: agents are not directly addressable by the operator's
|
|
24712
24801
|
* clients — they reverse-connect to the hub. Exposing their interfaces
|
|
@@ -24861,6 +24950,17 @@ var NotificationEndpointSchema = object({
|
|
|
24861
24950
|
/** What the ranking currently resolves to (null when nothing is reachable). */
|
|
24862
24951
|
resolved: string().nullable()
|
|
24863
24952
|
});
|
|
24953
|
+
/**
|
|
24954
|
+
* The URLs the SDK / viewer should race for API access. `baseUrls` empty =
|
|
24955
|
+
* AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
|
|
24956
|
+
* currently expands to, so the UI can show the effective set either way.
|
|
24957
|
+
*/
|
|
24958
|
+
var ViewerEndpointsSchema = object({
|
|
24959
|
+
/** The operator's explicit race set, or empty for AUTO. */
|
|
24960
|
+
baseUrls: array(string()).readonly(),
|
|
24961
|
+
/** What the ranking currently resolves to (may be empty if nothing is up). */
|
|
24962
|
+
resolved: array(string()).readonly()
|
|
24963
|
+
});
|
|
24864
24964
|
var AllowedAddressesSchema = object({
|
|
24865
24965
|
/**
|
|
24866
24966
|
* Allowlist of interface addresses operators have explicitly opted
|
|
@@ -24892,17 +24992,18 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
24892
24992
|
*/
|
|
24893
24993
|
port: number().int().min(1).max(65535).optional(),
|
|
24894
24994
|
/** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
|
|
24895
|
-
* candidate. Default `
|
|
24995
|
+
* candidate. Default `false` — loopback is not a client route. */
|
|
24896
24996
|
includeLoopback: boolean().optional(),
|
|
24897
|
-
/** Skip IPv6 entries.
|
|
24898
|
-
*
|
|
24997
|
+
/** Skip IPv6 entries. Default `false` — the palette includes stable
|
|
24998
|
+
* LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
|
|
24999
|
+
* hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
|
|
24899
25000
|
ipv4Only: boolean().optional(),
|
|
24900
25001
|
/** Scheme to emit for LAN/loopback URLs. Default `'http'`.
|
|
24901
25002
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
24902
25003
|
* to avoid mixed-content blocks in the browser. The public
|
|
24903
25004
|
* tunnel always emits `https://` regardless. */
|
|
24904
25005
|
scheme: _enum(["http", "https"]).optional()
|
|
24905
|
-
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
25006
|
+
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
24906
25007
|
kind: "mutation",
|
|
24907
25008
|
auth: "admin"
|
|
24908
25009
|
}), method(object({
|
|
@@ -30886,6 +30987,12 @@ Object.freeze({
|
|
|
30886
30987
|
addonId: null,
|
|
30887
30988
|
access: "view"
|
|
30888
30989
|
},
|
|
30990
|
+
"localNetwork.getViewerEndpoints": {
|
|
30991
|
+
capName: "local-network",
|
|
30992
|
+
capScope: "system",
|
|
30993
|
+
addonId: null,
|
|
30994
|
+
access: "view"
|
|
30995
|
+
},
|
|
30889
30996
|
"localNetwork.list": {
|
|
30890
30997
|
capName: "local-network",
|
|
30891
30998
|
capScope: "system",
|
|
@@ -30922,6 +31029,12 @@ Object.freeze({
|
|
|
30922
31029
|
addonId: null,
|
|
30923
31030
|
access: "create"
|
|
30924
31031
|
},
|
|
31032
|
+
"localNetwork.setViewerEndpoints": {
|
|
31033
|
+
capName: "local-network",
|
|
31034
|
+
capScope: "system",
|
|
31035
|
+
addonId: null,
|
|
31036
|
+
access: "create"
|
|
31037
|
+
},
|
|
30925
31038
|
"localNetwork.uploadCertificate": {
|
|
30926
31039
|
capName: "local-network",
|
|
30927
31040
|
capScope: "system",
|
package/dist/{event-loop-stall-monitor-fHkfgmlw.mjs → event-loop-stall-monitor-D5jK5v4Z.mjs}
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { K as hfModelUrl, a as COCO_80_LABELS, j as audioKindId, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS } from "./dist-
|
|
1
|
+
import { K as hfModelUrl, a as COCO_80_LABELS, j as audioKindId, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS } from "./dist-DGQkkWc6.mjs";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
2
3
|
import { PerformanceObserver } from "node:perf_hooks";
|
|
3
4
|
//#region src/detection-pipeline/registry/model-catalogs.ts
|
|
4
5
|
var HF_REPO = "camstack/camstack-models";
|
|
@@ -1890,6 +1891,226 @@ function resolveModelForFormat(stepId, chosenModelId, format) {
|
|
|
1890
1891
|
return getDefaultModelForFormat(stepId, format);
|
|
1891
1892
|
}
|
|
1892
1893
|
//#endregion
|
|
1894
|
+
//#region src/session-decode/frame-view-geometry.ts
|
|
1895
|
+
function positiveInteger(value, label) {
|
|
1896
|
+
if (!Number.isFinite(value) || value <= 0) throw new Error(`${label} must be positive`);
|
|
1897
|
+
return Math.max(1, Math.round(value));
|
|
1898
|
+
}
|
|
1899
|
+
function clampCrop(sourceWidth, sourceHeight, crop) {
|
|
1900
|
+
if (!crop) return {
|
|
1901
|
+
left: 0,
|
|
1902
|
+
top: 0,
|
|
1903
|
+
width: sourceWidth,
|
|
1904
|
+
height: sourceHeight
|
|
1905
|
+
};
|
|
1906
|
+
const left = Math.max(0, Math.min(sourceWidth - 1, Math.floor(crop.left)));
|
|
1907
|
+
const top = Math.max(0, Math.min(sourceHeight - 1, Math.floor(crop.top)));
|
|
1908
|
+
const right = Math.max(left + 1, Math.min(sourceWidth, Math.ceil(crop.left + crop.width)));
|
|
1909
|
+
const bottom = Math.max(top + 1, Math.min(sourceHeight, Math.ceil(crop.top + crop.height)));
|
|
1910
|
+
return {
|
|
1911
|
+
left,
|
|
1912
|
+
top,
|
|
1913
|
+
width: right - left,
|
|
1914
|
+
height: bottom - top
|
|
1915
|
+
};
|
|
1916
|
+
}
|
|
1917
|
+
/** Pure geometry for worker-side crop/resize without model padding. */
|
|
1918
|
+
function resolveFrameViewGeometry(sourceWidthInput, sourceHeightInput, spec) {
|
|
1919
|
+
const sourceWidth = positiveInteger(sourceWidthInput, "source width");
|
|
1920
|
+
const sourceHeight = positiveInteger(sourceHeightInput, "source height");
|
|
1921
|
+
const targetWidth = positiveInteger(spec.content.width, "content width");
|
|
1922
|
+
const targetHeight = positiveInteger(spec.content.height, "content height");
|
|
1923
|
+
const sourceCrop = clampCrop(sourceWidth, sourceHeight, spec.crop);
|
|
1924
|
+
const output = spec.fit === "stretch" ? {
|
|
1925
|
+
width: targetWidth,
|
|
1926
|
+
height: targetHeight
|
|
1927
|
+
} : (() => {
|
|
1928
|
+
const scale = Math.min(targetWidth / sourceCrop.width, targetHeight / sourceCrop.height);
|
|
1929
|
+
return {
|
|
1930
|
+
width: Math.max(1, Math.round(sourceCrop.width * scale)),
|
|
1931
|
+
height: Math.max(1, Math.round(sourceCrop.height * scale))
|
|
1932
|
+
};
|
|
1933
|
+
})();
|
|
1934
|
+
return {
|
|
1935
|
+
source: {
|
|
1936
|
+
width: sourceWidth,
|
|
1937
|
+
height: sourceHeight
|
|
1938
|
+
},
|
|
1939
|
+
sourceCrop,
|
|
1940
|
+
output,
|
|
1941
|
+
scale: {
|
|
1942
|
+
x: output.width / sourceCrop.width,
|
|
1943
|
+
y: output.height / sourceCrop.height
|
|
1944
|
+
}
|
|
1945
|
+
};
|
|
1946
|
+
}
|
|
1947
|
+
//#endregion
|
|
1948
|
+
//#region src/session-decode/local-frame-registry.ts
|
|
1949
|
+
var DEFAULT_MAX_FRAMES = 24;
|
|
1950
|
+
var DEFAULT_MAX_BYTES = 512 * 1024 * 1024;
|
|
1951
|
+
function estimateFrameBytes(image) {
|
|
1952
|
+
return image.width * image.height * (image.format === "gray" ? 1 : 3);
|
|
1953
|
+
}
|
|
1954
|
+
function releasesNative(reason) {
|
|
1955
|
+
return reason !== "success";
|
|
1956
|
+
}
|
|
1957
|
+
/**
|
|
1958
|
+
* Bounded process-local registry. A serialized ref from another process misses
|
|
1959
|
+
* by registry id; an evicted id never aliases a newer frame. View resolution
|
|
1960
|
+
* is lease-only ({@link acquire} → {@link LocalFrameLease.resolve}) so an
|
|
1961
|
+
* in-flight `toBuffer()` is covered by `refs > 1` and cannot be LRU-evicted.
|
|
1962
|
+
*/
|
|
1963
|
+
var LocalFrameRegistry = class {
|
|
1964
|
+
registryId;
|
|
1965
|
+
maxFrames;
|
|
1966
|
+
maxBytes;
|
|
1967
|
+
entries = /* @__PURE__ */ new Map();
|
|
1968
|
+
bytes = 0;
|
|
1969
|
+
releaseCount = 0;
|
|
1970
|
+
evictionCount = 0;
|
|
1971
|
+
staleMissCount = 0;
|
|
1972
|
+
constructor(options = {}) {
|
|
1973
|
+
this.registryId = options.registryId ?? `${process.pid}-${randomUUID()}`;
|
|
1974
|
+
this.maxFrames = options.maxFrames ?? DEFAULT_MAX_FRAMES;
|
|
1975
|
+
this.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
1976
|
+
}
|
|
1977
|
+
get size() {
|
|
1978
|
+
return this.entries.size;
|
|
1979
|
+
}
|
|
1980
|
+
get estimatedBytes() {
|
|
1981
|
+
return this.bytes;
|
|
1982
|
+
}
|
|
1983
|
+
getStats() {
|
|
1984
|
+
let residentRefs = 0;
|
|
1985
|
+
for (const entry of this.entries.values()) residentRefs += entry.refs;
|
|
1986
|
+
return {
|
|
1987
|
+
residentFrames: this.entries.size,
|
|
1988
|
+
residentRefs,
|
|
1989
|
+
residentBytes: this.bytes,
|
|
1990
|
+
releases: this.releaseCount,
|
|
1991
|
+
evictions: this.evictionCount,
|
|
1992
|
+
staleMisses: this.staleMissCount
|
|
1993
|
+
};
|
|
1994
|
+
}
|
|
1995
|
+
register(image, metadata) {
|
|
1996
|
+
const estimatedBytes = estimateFrameBytes(image);
|
|
1997
|
+
if (this.maxFrames < 1 || estimatedBytes > this.maxBytes) {
|
|
1998
|
+
image.close();
|
|
1999
|
+
image.releaseNativeLease?.();
|
|
2000
|
+
return null;
|
|
2001
|
+
}
|
|
2002
|
+
const ref = {
|
|
2003
|
+
registryId: this.registryId,
|
|
2004
|
+
id: randomUUID(),
|
|
2005
|
+
width: image.width,
|
|
2006
|
+
height: image.height,
|
|
2007
|
+
format: image.format,
|
|
2008
|
+
timestamp: metadata.timestamp,
|
|
2009
|
+
...metadata.capturedAt !== void 0 ? { capturedAt: metadata.capturedAt } : {}
|
|
2010
|
+
};
|
|
2011
|
+
this.entries.set(ref.id, {
|
|
2012
|
+
ref,
|
|
2013
|
+
image,
|
|
2014
|
+
estimatedBytes,
|
|
2015
|
+
refs: 1,
|
|
2016
|
+
releaseNativeOnClose: false
|
|
2017
|
+
});
|
|
2018
|
+
this.bytes += estimatedBytes;
|
|
2019
|
+
this.evictToBounds();
|
|
2020
|
+
return this.entries.has(ref.id) ? ref : null;
|
|
2021
|
+
}
|
|
2022
|
+
acquire(ref) {
|
|
2023
|
+
if (ref.registryId === this.registryId && !this.entries.has(ref.id)) this.staleMissCount += 1;
|
|
2024
|
+
const entry = this.getEntry(ref);
|
|
2025
|
+
if (!entry) return null;
|
|
2026
|
+
entry.refs += 1;
|
|
2027
|
+
this.touch(entry);
|
|
2028
|
+
let released = false;
|
|
2029
|
+
return {
|
|
2030
|
+
resolve: (spec) => this.resolveFromLease(entry, spec),
|
|
2031
|
+
release: (reason) => {
|
|
2032
|
+
if (released) return;
|
|
2033
|
+
released = true;
|
|
2034
|
+
this.release(ref, reason);
|
|
2035
|
+
}
|
|
2036
|
+
};
|
|
2037
|
+
}
|
|
2038
|
+
release(ref, reason) {
|
|
2039
|
+
const entry = this.getEntry(ref);
|
|
2040
|
+
if (!entry) return;
|
|
2041
|
+
this.releaseCount += 1;
|
|
2042
|
+
if (releasesNative(reason)) entry.releaseNativeOnClose = true;
|
|
2043
|
+
entry.refs = Math.max(0, entry.refs - 1);
|
|
2044
|
+
if (entry.refs === 0) this.drop(entry);
|
|
2045
|
+
}
|
|
2046
|
+
clear(reason = "detach") {
|
|
2047
|
+
for (const entry of [...this.entries.values()]) {
|
|
2048
|
+
if (releasesNative(reason)) entry.releaseNativeOnClose = true;
|
|
2049
|
+
this.drop(entry);
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
getEntry(ref) {
|
|
2053
|
+
if (ref.registryId !== this.registryId) return null;
|
|
2054
|
+
return this.entries.get(ref.id) ?? null;
|
|
2055
|
+
}
|
|
2056
|
+
touch(entry) {
|
|
2057
|
+
this.entries.delete(entry.ref.id);
|
|
2058
|
+
this.entries.set(entry.ref.id, entry);
|
|
2059
|
+
}
|
|
2060
|
+
/**
|
|
2061
|
+
* Materialize a view for a live lease only. Public callers must go through
|
|
2062
|
+
* {@link acquire} so `refs > 1` covers the whole `toBuffer()` window.
|
|
2063
|
+
*/
|
|
2064
|
+
async resolveFromLease(entry, spec) {
|
|
2065
|
+
if (!this.entries.has(entry.ref.id)) return {
|
|
2066
|
+
kind: "miss",
|
|
2067
|
+
reason: "stale-ref"
|
|
2068
|
+
};
|
|
2069
|
+
this.touch(entry);
|
|
2070
|
+
const geometry = resolveFrameViewGeometry(entry.image.width, entry.image.height, spec);
|
|
2071
|
+
return {
|
|
2072
|
+
kind: "view",
|
|
2073
|
+
data: await entry.image.toBuffer({
|
|
2074
|
+
crop: geometry.sourceCrop,
|
|
2075
|
+
resize: geometry.output,
|
|
2076
|
+
format: spec.format
|
|
2077
|
+
}),
|
|
2078
|
+
width: geometry.output.width,
|
|
2079
|
+
height: geometry.output.height,
|
|
2080
|
+
format: spec.format,
|
|
2081
|
+
geometry
|
|
2082
|
+
};
|
|
2083
|
+
}
|
|
2084
|
+
/** Oldest owner-only / queued entry (`refs === 1`). Consumer leases (`refs > 1`) stay. */
|
|
2085
|
+
findOwnerOnlyVictim() {
|
|
2086
|
+
for (const entry of this.entries.values()) if (entry.refs <= 1) return entry;
|
|
2087
|
+
}
|
|
2088
|
+
evictToBounds() {
|
|
2089
|
+
while (this.entries.size > this.maxFrames || this.bytes > this.maxBytes) {
|
|
2090
|
+
const victim = this.findOwnerOnlyVictim();
|
|
2091
|
+
if (!victim) break;
|
|
2092
|
+
victim.releaseNativeOnClose = true;
|
|
2093
|
+
this.evictionCount += 1;
|
|
2094
|
+
this.drop(victim);
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
drop(entry) {
|
|
2098
|
+
if (!this.entries.delete(entry.ref.id)) return;
|
|
2099
|
+
this.bytes = Math.max(0, this.bytes - entry.estimatedBytes);
|
|
2100
|
+
entry.image.close();
|
|
2101
|
+
if (entry.releaseNativeOnClose) entry.image.releaseNativeLease?.();
|
|
2102
|
+
}
|
|
2103
|
+
};
|
|
2104
|
+
function envPositiveInt(name, fallback) {
|
|
2105
|
+
const parsed = Number(process.env[name]);
|
|
2106
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;
|
|
2107
|
+
}
|
|
2108
|
+
/** Shared only by addons in the same grouped runner process. */
|
|
2109
|
+
var localFrameRegistry = new LocalFrameRegistry({
|
|
2110
|
+
maxFrames: envPositiveInt("CAMSTACK_LOCAL_FRAME_MAX_FRAMES", DEFAULT_MAX_FRAMES),
|
|
2111
|
+
maxBytes: envPositiveInt("CAMSTACK_LOCAL_FRAME_BUDGET_MB", DEFAULT_MAX_BYTES / 1048576) * 1048576
|
|
2112
|
+
});
|
|
2113
|
+
//#endregion
|
|
1893
2114
|
//#region src/detection-pipeline/diagnostics/event-loop-stall-monitor.ts
|
|
1894
2115
|
/**
|
|
1895
2116
|
* event-loop-stall-monitor — names the thing that freezes the detection process.
|
|
@@ -2026,4 +2247,4 @@ function startEventLoopStallMonitor(logger, reportThresholdMs = STALL_REPORT_MS)
|
|
|
2026
2247
|
};
|
|
2027
2248
|
}
|
|
2028
2249
|
//#endregion
|
|
2029
|
-
export {
|
|
2250
|
+
export { ALL_PIPELINE_STEPS as a, getDefaultModelForFormatFromDef as c, resolveModelForFormat as d, landmarkPrecisionVerdict as f, resolveFrameViewGeometry as i, getStep as l, startEventLoopStallMonitor as n, ALL_STEPS as o, localFrameRegistry as r, getDefaultModelForFormat as s, attributeStall as t, getStepDefinition as u };
|