camstack 1.2.197 → 1.2.199

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.
@@ -24024,9 +24024,9 @@ var require_zod = __commonJS({
24024
24024
  }
24025
24025
  });
24026
24026
 
24027
- // ../system/dist/dist-Bn-RNanh.js
24028
- var require_dist_Bn_RNanh = __commonJS({
24029
- "../system/dist/dist-Bn-RNanh.js"(exports) {
24027
+ // ../system/dist/dist-Ct-4tTeX.js
24028
+ var require_dist_Ct_4tTeX = __commonJS({
24029
+ "../system/dist/dist-Ct-4tTeX.js"(exports) {
24030
24030
  "use strict";
24031
24031
  var zod = require_zod();
24032
24032
  __require("crypto");
@@ -37046,19 +37046,6 @@ var require_dist_Bn_RNanh = __commonJS({
37046
37046
  /** The whole declaration, secret paths and entry descriptor included (the entries service builds its handle from it). */
37047
37047
  declaration: RecordKindDeclarationSchema
37048
37048
  });
37049
- var STORAGE_ADMIN_MOVED_COLLECTIONS = [
37050
- "stream-broker:probe-snapshots",
37051
- "stream-broker:profile-map",
37052
- "stream-broker:rtsp-tokens",
37053
- "notification-center:device-mutes",
37054
- "recorder:recording-configs",
37055
- "pipeline-orchestrator:device-features"
37056
- ];
37057
- var STORAGE_ADMIN_SCOPED_BASES = [
37058
- "addon-settings",
37059
- "addon-devices",
37060
- "sections"
37061
- ];
37062
37049
  var storageAdminCapability = {
37063
37050
  name: "storage-admin",
37064
37051
  scope: "system",
@@ -37070,26 +37057,6 @@ var require_dist_Bn_RNanh = __commonJS({
37070
37057
  * optionally only those owned by `ownerPrefix`. Reads only.
37071
37058
  */
37072
37059
  listTables: method(zod.z.object({ ownerPrefix: zod.z.string().min(1).optional() }), zod.z.object({ tables: zod.z.array(StorageTableSchema) }), { auth: "admin" }),
37073
- /**
37074
- * Drop one table. REFUSES when an addon declared it since the engine
37075
- * started (a running addon still owns it), when it is an engine or
37076
- * canonical table, when it does not exist, or when its row count is not
37077
- * `expectRows` - the caller states what it believes it is deleting. The
37078
- * engine also refuses anything but `<owner>:(addon-settings|addon-devices|
37079
- * sections)`, the retired collections by name, and tables of owners that
37080
- * are not installed (and refuses when it cannot read the installed list).
37081
- * Removed with the D870 migration script once the last hub ran it.
37082
- */
37083
- dropCollection: method(zod.z.object({
37084
- collection: zod.z.string().min(1),
37085
- expectRows: zod.z.number().int().nonnegative()
37086
- }), zod.z.object({
37087
- dropped: zod.z.literal(true),
37088
- rows: zod.z.number().int().nonnegative()
37089
- }), {
37090
- kind: "mutation",
37091
- auth: "admin"
37092
- }),
37093
37060
  /** Every record kind of both files with rows, a size estimate, class and retention (D881). */
37094
37061
  listKinds: method(zod.z.object({
37095
37062
  owner: zod.z.string().min(1).optional(),
@@ -63642,6 +63609,15 @@ var require_dist_Bn_RNanh = __commonJS({
63642
63609
  * Replaces `zoneCrop`.
63643
63610
  */
63644
63611
  showTriggerZone: zod.z.boolean().optional(),
63612
+ /**
63613
+ * Draw the SUBJECT'S PATH on the picture — a line in the subject's colour
63614
+ * through the track's positions up to the frame shown, the same path the
63615
+ * debug views draw (`buildSubjectPath`, D903). Every picture mode a subject
63616
+ * is drawn on: a `crop` maps the path into the crop and clips it. Valid only
63617
+ * on a rule whose subject is a tracked object (refused on a sound rule);
63618
+ * dropped on `image: 'none'`. Absent = off.
63619
+ */
63620
+ showSubjectPath: zod.z.boolean().optional(),
63645
63621
  /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
63646
63622
  attach: zod.z.enum([
63647
63623
  "best",
@@ -94558,12 +94534,6 @@ var require_dist_Bn_RNanh = __commonJS({
94558
94534
  addonId: null,
94559
94535
  access: "create"
94560
94536
  },
94561
- "storageAdmin.dropCollection": {
94562
- capName: "storage-admin",
94563
- capScope: "system",
94564
- addonId: null,
94565
- access: "delete"
94566
- },
94567
94537
  "storageAdmin.listKinds": {
94568
94538
  capName: "storage-admin",
94569
94539
  capScope: "system",
@@ -101340,18 +101310,6 @@ var require_dist_Bn_RNanh = __commonJS({
101340
101310
  return STORAGE_ACCESS_FALLBACK;
101341
101311
  }
101342
101312
  });
101343
- Object.defineProperty(exports, "STORAGE_ADMIN_MOVED_COLLECTIONS", {
101344
- enumerable: true,
101345
- get: function() {
101346
- return STORAGE_ADMIN_MOVED_COLLECTIONS;
101347
- }
101348
- });
101349
- Object.defineProperty(exports, "STORAGE_ADMIN_SCOPED_BASES", {
101350
- enumerable: true,
101351
- get: function() {
101352
- return STORAGE_ADMIN_SCOPED_BASES;
101353
- }
101354
- });
101355
101313
  Object.defineProperty(exports, "STREAM_PROFILE_META", {
101356
101314
  enumerable: true,
101357
101315
  get: function() {
@@ -114066,11 +114024,11 @@ ${values.join("\n")}` : `${blockName} :`;
114066
114024
  }
114067
114025
  });
114068
114026
 
114069
- // ../system/dist/device-ca-CPTDs--d.js
114070
- var require_device_ca_CPTDs_d = __commonJS({
114071
- "../system/dist/device-ca-CPTDs--d.js"(exports) {
114027
+ // ../system/dist/device-ca-CUEx7sti.js
114028
+ var require_device_ca_CUEx7sti = __commonJS({
114029
+ "../system/dist/device-ca-CUEx7sti.js"(exports) {
114072
114030
  "use strict";
114073
- var require_dist10 = require_dist_Bn_RNanh();
114031
+ var require_dist10 = require_dist_Ct_4tTeX();
114074
114032
  var require_x509_es = require_x509_es_C4cOo48M();
114075
114033
  var node_crypto = __require("crypto");
114076
114034
  var SYSTEM_SECRET_OWNER = "system";
@@ -114494,7 +114452,7 @@ var require_alerts_addon = __commonJS({
114494
114452
  [Symbol.toStringTag]: { value: "Module" }
114495
114453
  });
114496
114454
  require_chunk_Cek0wNdY();
114497
- var require_dist10 = require_dist_Bn_RNanh();
114455
+ var require_dist10 = require_dist_Ct_4tTeX();
114498
114456
  var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
114499
114457
  function nextEpisodeId(input) {
114500
114458
  const { previous } = input;
@@ -115899,7 +115857,7 @@ var require_calendars_addon = __commonJS({
115899
115857
  [Symbol.toStringTag]: { value: "Module" }
115900
115858
  });
115901
115859
  require_chunk_Cek0wNdY();
115902
- var require_dist10 = require_dist_Bn_RNanh();
115860
+ var require_dist10 = require_dist_Ct_4tTeX();
115903
115861
  var require_settle_sources = require_settle_sources_Bhsy57y();
115904
115862
  var zod = require_zod();
115905
115863
  var CALENDAR_COLOR_PALETTE = [
@@ -116115,11 +116073,11 @@ var require_calendars = __commonJS({
116115
116073
  }
116116
116074
  });
116117
116075
 
116118
- // ../system/dist/composition-sources-b0e_2I-D.js
116119
- var require_composition_sources_b0e_2I_D = __commonJS({
116120
- "../system/dist/composition-sources-b0e_2I-D.js"(exports) {
116076
+ // ../system/dist/composition-sources-BPnpB9XG.js
116077
+ var require_composition_sources_BPnpB9XG = __commonJS({
116078
+ "../system/dist/composition-sources-BPnpB9XG.js"(exports) {
116121
116079
  "use strict";
116122
- var require_dist10 = require_dist_Bn_RNanh();
116080
+ var require_dist10 = require_dist_Ct_4tTeX();
116123
116081
  function normalizedNativeOwner(owner) {
116124
116082
  const trimmed = owner?.trim();
116125
116083
  return trimmed ? trimmed : null;
@@ -116234,8 +116192,8 @@ var require_composer_addon = __commonJS({
116234
116192
  [Symbol.toStringTag]: { value: "Module" }
116235
116193
  });
116236
116194
  require_chunk_Cek0wNdY();
116237
- var require_dist10 = require_dist_Bn_RNanh();
116238
- var require_composition_sources = require_composition_sources_b0e_2I_D();
116195
+ var require_dist10 = require_dist_Ct_4tTeX();
116196
+ var require_composition_sources = require_composition_sources_BPnpB9XG();
116239
116197
  var zod = require_zod();
116240
116198
  function isRecord$2(value) {
116241
116199
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -120045,7 +120003,7 @@ var require_console_logging = __commonJS({
120045
120003
  [Symbol.toStringTag]: { value: "Module" }
120046
120004
  });
120047
120005
  require_chunk_Cek0wNdY();
120048
- var require_dist10 = require_dist_Bn_RNanh();
120006
+ var require_dist10 = require_dist_Ct_4tTeX();
120049
120007
  var require_formatter = require_formatter_DqAKDlvN();
120050
120008
  var LEVEL_RANK = {
120051
120009
  debug: 0,
@@ -124709,9 +124667,9 @@ var require_core_blocks_addon = __commonJS({
124709
124667
  "use strict";
124710
124668
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
124711
124669
  var require_chunk = require_chunk_Cek0wNdY();
124712
- var require_dist10 = require_dist_Bn_RNanh();
124670
+ var require_dist10 = require_dist_Ct_4tTeX();
124713
124671
  var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
124714
- var require_composition_sources = require_composition_sources_b0e_2I_D();
124672
+ var require_composition_sources = require_composition_sources_BPnpB9XG();
124715
124673
  var require_prefix_range = require_prefix_range_D_KueXbQ();
124716
124674
  var require_prefix_walk = require_prefix_walk_Dv6MLZlM();
124717
124675
  var zod = require_zod();
@@ -136984,9 +136942,9 @@ var require_addon = __commonJS({
136984
136942
  }
136985
136943
  });
136986
136944
 
136987
- // ../system/dist/retired-settings-keys-D_VwZiDt.js
136988
- var require_retired_settings_keys_D_VwZiDt = __commonJS({
136989
- "../system/dist/retired-settings-keys-D_VwZiDt.js"(exports) {
136945
+ // ../system/dist/retired-settings-keys-CGUqX-Oz.js
136946
+ var require_retired_settings_keys_CGUqX_Oz = __commonJS({
136947
+ "../system/dist/retired-settings-keys-CGUqX-Oz.js"(exports) {
136990
136948
  "use strict";
136991
136949
  var _camstack_types_addon = require_addon();
136992
136950
  function settingsStoreIsAuthoritativeHere(env) {
@@ -137247,12 +137205,6 @@ var require_retired_settings_keys_D_VwZiDt = __commonJS({
137247
137205
  function errText(err) {
137248
137206
  return err instanceof Error ? err.message : String(err);
137249
137207
  }
137250
- Object.defineProperty(exports, "RETIRED_SETTINGS_KEYS", {
137251
- enumerable: true,
137252
- get: function() {
137253
- return RETIRED_SETTINGS_KEYS;
137254
- }
137255
- });
137256
137208
  Object.defineProperty(exports, "purgeRetiredSettingsKeys", {
137257
137209
  enumerable: true,
137258
137210
  get: function() {
@@ -137283,11 +137235,11 @@ var require_device_manager_addon = __commonJS({
137283
137235
  [Symbol.toStringTag]: { value: "Module" }
137284
137236
  });
137285
137237
  require_chunk_Cek0wNdY();
137286
- var require_dist10 = require_dist_Bn_RNanh();
137238
+ var require_dist10 = require_dist_Ct_4tTeX();
137287
137239
  var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
137288
137240
  var require_prefix_range = require_prefix_range_D_KueXbQ();
137289
137241
  var require_prefix_walk = require_prefix_walk_Dv6MLZlM();
137290
- var require_retired_settings_keys = require_retired_settings_keys_D_VwZiDt();
137242
+ var require_retired_settings_keys = require_retired_settings_keys_CGUqX_Oz();
137291
137243
  var zod = require_zod();
137292
137244
  var node_crypto = __require("crypto");
137293
137245
  var _camstack_types_node = require_node();
@@ -146355,7 +146307,7 @@ var require_hub_forwarder = __commonJS({
146355
146307
  [Symbol.toStringTag]: { value: "Module" }
146356
146308
  });
146357
146309
  require_chunk_Cek0wNdY();
146358
- var require_dist10 = require_dist_Bn_RNanh();
146310
+ var require_dist10 = require_dist_Ct_4tTeX();
146359
146311
  var require_formatter = require_formatter_DqAKDlvN();
146360
146312
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
146361
146313
  var HubForwarderDestination = class {
@@ -146489,7 +146441,7 @@ var require_liveness_monitor_addon = __commonJS({
146489
146441
  "use strict";
146490
146442
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
146491
146443
  require_chunk_Cek0wNdY();
146492
- var require_dist10 = require_dist_Bn_RNanh();
146444
+ var require_dist10 = require_dist_Ct_4tTeX();
146493
146445
  var NO_DEVICES = "liveness:no-devices";
146494
146446
  var ALL_OFFLINE = "liveness:all-devices-offline";
146495
146447
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -146852,11 +146804,11 @@ var require_local_auth_addon = __commonJS({
146852
146804
  [Symbol.toStringTag]: { value: "Module" }
146853
146805
  });
146854
146806
  var require_chunk = require_chunk_Cek0wNdY();
146855
- var require_dist10 = require_dist_Bn_RNanh();
146807
+ var require_dist10 = require_dist_Ct_4tTeX();
146856
146808
  var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
146857
146809
  var require_safe_buffer$1 = require_safe_buffer_D3aoa_7X();
146858
146810
  var require_ms$1 = require_ms_LB3giGoU();
146859
- var require_device_ca = require_device_ca_CPTDs_d();
146811
+ var require_device_ca = require_device_ca_CUEx7sti();
146860
146812
  var zod = require_zod();
146861
146813
  var node_crypto = __require("crypto");
146862
146814
  node_crypto = require_chunk.__toESM(node_crypto);
@@ -152443,7 +152395,6 @@ var require_local_auth_addon = __commonJS({
152443
152395
  var USERS_COLLECTION$1 = "users";
152444
152396
  var API_KEYS_COLLECTION = "api_keys";
152445
152397
  var SCOPED_TOKENS_COLLECTION = "scoped_tokens";
152446
- var OAUTH_SESSIONS_COLLECTION = "oauth_sessions";
152447
152398
  var USER_TOTP_COLLECTION = "user_totp";
152448
152399
  var USER_EXTERNAL_IDENTITIES_COLLECTION = "user_external_identities";
152449
152400
  var USERS_COLUMNS = [
@@ -152643,47 +152594,6 @@ var require_local_auth_addon = __commonJS({
152643
152594
  notNull: true
152644
152595
  }
152645
152596
  ];
152646
- var OAUTH_SESSIONS_COLUMNS = [
152647
- {
152648
- name: "id",
152649
- type: "TEXT",
152650
- primaryKey: true,
152651
- notNull: true
152652
- },
152653
- {
152654
- name: "userId",
152655
- type: "TEXT",
152656
- notNull: true
152657
- },
152658
- {
152659
- name: "username",
152660
- type: "TEXT",
152661
- notNull: true
152662
- },
152663
- {
152664
- name: "integrationId",
152665
- type: "TEXT",
152666
- notNull: true
152667
- },
152668
- {
152669
- name: "scopes",
152670
- type: "JSON"
152671
- },
152672
- {
152673
- name: "createdAt",
152674
- type: "INTEGER",
152675
- notNull: true
152676
- },
152677
- {
152678
- name: "lastUsedAt",
152679
- type: "INTEGER",
152680
- notNull: true
152681
- },
152682
- {
152683
- name: "revokedAt",
152684
- type: "INTEGER"
152685
- }
152686
- ];
152687
152597
  async function declareAuthSchema(store, options) {
152688
152598
  const skip = new Set(options?.skipCollections ?? []);
152689
152599
  if (!skip.has("users")) await store.declareCollection.mutate({
@@ -152718,14 +152628,6 @@ var require_local_auth_addon = __commonJS({
152718
152628
  columns: ["userId"]
152719
152629
  }]
152720
152630
  });
152721
- if (!skip.has("oauth_sessions")) await store.declareCollection.mutate({
152722
- collection: OAUTH_SESSIONS_COLLECTION,
152723
- columns: OAUTH_SESSIONS_COLUMNS,
152724
- indexes: [{
152725
- name: "idx_oauth_sessions_user_id",
152726
- columns: ["userId"]
152727
- }]
152728
- });
152729
152631
  if (!skip.has("login_sessions")) await store.declareCollection.mutate({
152730
152632
  collection: LOGIN_SESSIONS_COLLECTION,
152731
152633
  columns: LOGIN_SESSIONS_COLUMNS,
@@ -152926,16 +152828,19 @@ var require_local_auth_addon = __commonJS({
152926
152828
  "oauth-sessions": {
152927
152829
  schema: OauthSessionBodySchema,
152928
152830
  class: "ledger",
152929
- writeTrigger: "OAuth code exchange; refresh touches lastUsedAt",
152831
+ writeTrigger: "OAuth code exchange; refresh touches lastUsedAt; revoke stamps revokedAt",
152930
152832
  device: "none",
152931
152833
  at: "none",
152932
152834
  indexes: [{
152933
152835
  name: "user",
152934
152836
  fields: ["userId"]
152837
+ }, {
152838
+ name: "revoked",
152839
+ fields: ["revokedAt"]
152935
152840
  }],
152936
152841
  retention: {
152937
152842
  owner: "local-auth",
152938
- reason: "daily reap deletes revoked sessions older than 30 days; active rows never expire"
152843
+ reason: "daily reap deletes sessions revoked more than 30 days ago; an active session has no lifetime, so no engine TTL"
152939
152844
  }
152940
152845
  },
152941
152846
  "user-totp": {
@@ -153015,7 +152920,6 @@ var require_local_auth_addon = __commonJS({
153015
152920
  ADMIN_TOKENS_COLLECTION,
153016
152921
  LOGIN_SESSIONS_COLLECTION,
153017
152922
  LOGIN_SESSION_CUTOFFS_COLLECTION,
153018
- OAUTH_SESSIONS_COLLECTION,
153019
152923
  USER_TOTP_COLLECTION,
153020
152924
  USER_EXTERNAL_IDENTITIES_COLLECTION,
153021
152925
  DEVICE_CREDENTIALS_COLLECTION,
@@ -153163,7 +153067,7 @@ var require_local_auth_addon = __commonJS({
153163
153067
  const value = data[key];
153164
153068
  return typeof value === "number" && Number.isFinite(value) ? value : null;
153165
153069
  }
153166
- function parseSession$1(data) {
153070
+ function parseSession(data) {
153167
153071
  const id = str(data, "id");
153168
153072
  const userId = str(data, "userId");
153169
153073
  const createdAt = num(data, "createdAt");
@@ -153226,7 +153130,7 @@ var require_local_auth_addon = __commonJS({
153226
153130
  if (sessionsKind !== null) {
153227
153131
  const rows2 = await (0, import_read_all_rows.readAllRows)(sessionsKind);
153228
153132
  for (const row of rows2) {
153229
- const record = parseSession$1({
153133
+ const record = parseSession({
153230
153134
  id: row.id,
153231
153135
  ...row.data
153232
153136
  });
@@ -153238,7 +153142,7 @@ var require_local_auth_addon = __commonJS({
153238
153142
  }
153239
153143
  const rows = await this.store.query.query({ collection: LOGIN_SESSIONS_COLLECTION });
153240
153144
  for (const row of rows) {
153241
- const record = parseSession$1(row.data);
153145
+ const record = parseSession(row.data);
153242
153146
  if (record !== null) this.remember(record);
153243
153147
  }
153244
153148
  const cutoffs = await this.store.query.query({ collection: LOGIN_SESSION_CUTOFFS_COLLECTION });
@@ -156565,33 +156469,6 @@ var require_local_auth_addon = __commonJS({
156565
156469
  }
156566
156470
  };
156567
156471
  }
156568
- function parseSession(data) {
156569
- const id = data["id"];
156570
- const userId = data["userId"];
156571
- const username = data["username"];
156572
- const integrationId = data["integrationId"];
156573
- const scopes = data["scopes"];
156574
- const createdAt = data["createdAt"];
156575
- const lastUsedAt = data["lastUsedAt"];
156576
- const revokedAt = data["revokedAt"];
156577
- if (typeof id !== "string") throw new Error("oauth_sessions row: missing id");
156578
- if (typeof userId !== "string") throw new Error("oauth_sessions row: missing userId");
156579
- if (typeof username !== "string") throw new Error("oauth_sessions row: missing username");
156580
- if (typeof integrationId !== "string") throw new Error("oauth_sessions row: missing integrationId");
156581
- if (!Array.isArray(scopes)) throw new Error("oauth_sessions row: scopes must be an array");
156582
- if (typeof createdAt !== "number") throw new Error("oauth_sessions row: missing createdAt");
156583
- if (typeof lastUsedAt !== "number") throw new Error("oauth_sessions row: missing lastUsedAt");
156584
- return {
156585
- id,
156586
- userId,
156587
- username,
156588
- integrationId,
156589
- scopes,
156590
- createdAt,
156591
- lastUsedAt,
156592
- revokedAt: typeof revokedAt === "number" ? revokedAt : null
156593
- };
156594
- }
156595
156472
  function sessionToBody(session) {
156596
156473
  return {
156597
156474
  userId: session.userId,
@@ -156604,22 +156481,29 @@ var require_local_auth_addon = __commonJS({
156604
156481
  };
156605
156482
  }
156606
156483
  function rowToSession(id, body) {
156607
- return parseSession({
156484
+ return {
156608
156485
  id,
156609
- ...body
156610
- });
156486
+ userId: body.userId,
156487
+ username: body.username,
156488
+ integrationId: body.integrationId,
156489
+ scopes: body.scopes,
156490
+ createdAt: body.createdAt,
156491
+ lastUsedAt: body.lastUsedAt,
156492
+ revokedAt: typeof body.revokedAt === "number" ? body.revokedAt : null
156493
+ };
156611
156494
  }
156612
156495
  var OauthSessionManager = class {
156613
156496
  kind;
156614
- store;
156615
156497
  constructor(deps) {
156616
- if ("oauthSessionsKind" in deps) {
156617
- this.kind = deps.oauthSessionsKind;
156618
- this.store = deps.legacyStore ?? null;
156619
- } else {
156620
- this.kind = null;
156621
- this.store = deps;
156622
- }
156498
+ this.kind = deps.oauthSessionsKind;
156499
+ }
156500
+ async write(session) {
156501
+ const parsed = localAuthRecordKinds["oauth-sessions"].schema.safeParse(sessionToBody(session));
156502
+ if (!parsed.success) throw new Error(parsed.error.message);
156503
+ await this.kind.put({
156504
+ id: session.id,
156505
+ data: parsed.data
156506
+ });
156623
156507
  }
156624
156508
  async create(input) {
156625
156509
  const now = Date.now();
@@ -156633,117 +156517,53 @@ var require_local_auth_addon = __commonJS({
156633
156517
  lastUsedAt: now,
156634
156518
  revokedAt: null
156635
156519
  };
156636
- const kind = this.kind;
156637
- if (kind !== null) {
156638
- const parsed = localAuthRecordKinds["oauth-sessions"].schema.safeParse(sessionToBody(session));
156639
- if (!parsed.success) throw new Error(parsed.error.message);
156640
- await kind.put({
156641
- id: session.id,
156642
- data: parsed.data
156643
- });
156644
- return session;
156645
- }
156646
- await this.store.insert.mutate({
156647
- collection: OAUTH_SESSIONS_COLLECTION,
156648
- record: {
156649
- id: session.id,
156650
- data: { ...session }
156651
- }
156652
- });
156520
+ await this.write(session);
156653
156521
  return session;
156654
156522
  }
156655
156523
  async list() {
156656
- const kind = this.kind;
156657
- if (kind !== null) return (await (0, import_read_all_rows.readAllRows)(kind)).map((row) => rowToSession(row.id, row.data));
156658
- return (await this.store.query.query({
156659
- collection: OAUTH_SESSIONS_COLLECTION,
156660
- filter: {}
156661
- })).map((r2) => parseSession(r2.data));
156524
+ return (await (0, import_read_all_rows.readAllRows)(this.kind)).map((row) => rowToSession(row.id, row.data));
156662
156525
  }
156663
156526
  async getById(id) {
156664
- const kind = this.kind;
156665
- if (kind !== null) {
156666
- const row = await kind.get(id);
156667
- return row === null ? null : rowToSession(row.id, row.data);
156668
- }
156669
- const results = await this.store.query.query({
156670
- collection: OAUTH_SESSIONS_COLLECTION,
156671
- filter: { where: { id } }
156672
- });
156673
- if (results.length === 0) return null;
156674
- return parseSession(results[0].data);
156527
+ const row = await this.kind.get(id);
156528
+ return row === null ? null : rowToSession(row.id, row.data);
156675
156529
  }
156676
156530
  async markRevoked(id) {
156677
156531
  const existing = await this.getById(id);
156678
156532
  if (existing === null) return false;
156679
156533
  if (existing.revokedAt !== null) return true;
156680
- const updated = {
156534
+ await this.write({
156681
156535
  ...existing,
156682
156536
  revokedAt: Date.now()
156683
- };
156684
- const kind = this.kind;
156685
- if (kind !== null) {
156686
- const parsed = localAuthRecordKinds["oauth-sessions"].schema.safeParse(sessionToBody(updated));
156687
- if (!parsed.success) throw new Error(parsed.error.message);
156688
- await kind.put({
156689
- id,
156690
- data: parsed.data
156691
- });
156692
- return true;
156693
- }
156694
- await this.store.update.mutate({
156695
- collection: OAUTH_SESSIONS_COLLECTION,
156696
- id,
156697
- data: { ...updated }
156698
156537
  });
156699
156538
  return true;
156700
156539
  }
156701
156540
  async remove(id) {
156702
156541
  if (await this.getById(id) === null) return false;
156703
- const kind = this.kind;
156704
- if (kind !== null) {
156705
- await kind.delete(id);
156706
- return true;
156707
- }
156708
- await this.store.delete.mutate({
156709
- collection: OAUTH_SESSIONS_COLLECTION,
156710
- key: id
156711
- });
156542
+ await this.kind.delete(id);
156712
156543
  return true;
156713
156544
  }
156545
+ /**
156546
+ * Delete the sessions revoked at or before `horizonMs`. An active session
156547
+ * (`revokedAt` null) is never matched: it has no lifetime of its own, which
156548
+ * is why this is the owner's sweep and not an engine TTL.
156549
+ */
156714
156550
  async reapRevoked(horizonMs) {
156715
- const kind = this.kind;
156716
- if (kind !== null) return kind.deleteWhere({ where: { revokedAt: {
156551
+ return this.kind.deleteWhere({ where: { revokedAt: {
156717
156552
  gte: 1,
156718
156553
  lte: horizonMs
156719
156554
  } } });
156720
- const { deleted } = await this.store.deleteWhere.mutate({
156721
- collection: OAUTH_SESSIONS_COLLECTION,
156722
- filter: { whereBetween: { revokedAt: [1, horizonMs] } }
156723
- });
156724
- return deleted;
156725
156555
  }
156726
156556
  async touch(id) {
156727
156557
  const existing = await this.getById(id);
156728
156558
  if (existing === null) return;
156729
- const updated = {
156559
+ const parsed = localAuthRecordKinds["oauth-sessions"].schema.safeParse(sessionToBody({
156730
156560
  ...existing,
156731
156561
  lastUsedAt: Date.now()
156732
- };
156733
- const kind = this.kind;
156734
- if (kind !== null) {
156735
- const parsed = localAuthRecordKinds["oauth-sessions"].schema.safeParse(sessionToBody(updated));
156736
- if (!parsed.success) return;
156737
- await kind.put({
156738
- id,
156739
- data: parsed.data
156740
- });
156741
- return;
156742
- }
156743
- await this.store.update.mutate({
156744
- collection: OAUTH_SESSIONS_COLLECTION,
156562
+ }));
156563
+ if (!parsed.success) return;
156564
+ await this.kind.put({
156745
156565
  id,
156746
- data: { ...updated }
156566
+ data: parsed.data
156747
156567
  });
156748
156568
  }
156749
156569
  };
@@ -156800,10 +156620,7 @@ var require_local_auth_addon = __commonJS({
156800
156620
  apiKeysKind: authStores.apiKeys,
156801
156621
  legacyStore: store
156802
156622
  });
156803
- this.oauthSessionManager = new OauthSessionManager({
156804
- oauthSessionsKind: authStores.oauthSessions,
156805
- legacyStore: store
156806
- });
156623
+ this.oauthSessionManager = new OauthSessionManager({ oauthSessionsKind: authStores.oauthSessions });
156807
156624
  this.totpManager = new TotpManager({
156808
156625
  userTotpKind: authStores.userTotp,
156809
156626
  legacyStore: store
@@ -157523,7 +157340,7 @@ var require_loki_logging = __commonJS({
157523
157340
  [Symbol.toStringTag]: { value: "Module" }
157524
157341
  });
157525
157342
  require_chunk_Cek0wNdY();
157526
- var require_dist10 = require_dist_Bn_RNanh();
157343
+ var require_dist10 = require_dist_Ct_4tTeX();
157527
157344
  var require_log_read_filter = require_log_read_filter_Bi066jwU();
157528
157345
  var zod = require_zod();
157529
157346
  function sanitizeLabelName(raw) {
@@ -158484,7 +158301,7 @@ var require_native_metrics_addon = __commonJS({
158484
158301
  [Symbol.toStringTag]: { value: "Module" }
158485
158302
  });
158486
158303
  var require_chunk = require_chunk_Cek0wNdY();
158487
- var require_dist10 = require_dist_Bn_RNanh();
158304
+ var require_dist10 = require_dist_Ct_4tTeX();
158488
158305
  var node_fs_promises = __require("fs/promises");
158489
158306
  var node_util = __require("util");
158490
158307
  var node_os = __require("os");
@@ -161051,7 +160868,7 @@ var require_device_history_addon = __commonJS({
161051
160868
  [Symbol.toStringTag]: { value: "Module" }
161052
160869
  });
161053
160870
  require_chunk_Cek0wNdY();
161054
- var require_dist10 = require_dist_Bn_RNanh();
160871
+ var require_dist10 = require_dist_Ct_4tTeX();
161055
160872
  var FIVE_MINUTES_MS = 5 * 6e4;
161056
160873
  var HOUR_MS = 60 * 6e4;
161057
160874
  var DAY_MS = 24 * HOUR_MS;
@@ -164097,7 +163914,7 @@ var require_filesystem_storage_addon = __commonJS({
164097
163914
  [Symbol.toStringTag]: { value: "Module" }
164098
163915
  });
164099
163916
  var require_chunk = require_chunk_Cek0wNdY();
164100
- var require_dist10 = require_dist_Bn_RNanh();
163917
+ var require_dist10 = require_dist_Ct_4tTeX();
164101
163918
  var node_crypto = __require("crypto");
164102
163919
  var node_fs_promises = __require("fs/promises");
164103
163920
  var node_path = __require("path");
@@ -165207,12 +165024,12 @@ var require_lib = __commonJS({
165207
165024
  }
165208
165025
  });
165209
165026
 
165210
- // ../system/dist/wal-maintenance-CaJjuLHq.js
165211
- var require_wal_maintenance_CaJjuLHq = __commonJS({
165212
- "../system/dist/wal-maintenance-CaJjuLHq.js"(exports) {
165027
+ // ../system/dist/wal-maintenance-DBvuVU9s.js
165028
+ var require_wal_maintenance_DBvuVU9s = __commonJS({
165029
+ "../system/dist/wal-maintenance-DBvuVU9s.js"(exports) {
165213
165030
  "use strict";
165214
165031
  var require_chunk = require_chunk_Cek0wNdY();
165215
- var require_dist10 = require_dist_Bn_RNanh();
165032
+ var require_dist10 = require_dist_Ct_4tTeX();
165216
165033
  var require_prefix_range = require_prefix_range_D_KueXbQ();
165217
165034
  var node_crypto = __require("crypto");
165218
165035
  var node_module = __require("module");
@@ -165496,7 +165313,6 @@ var require_wal_maintenance_CaJjuLHq = __commonJS({
165496
165313
  function controlTargetOf(backend, threadId) {
165497
165314
  return {
165498
165315
  hasTable: ({ name }) => backend.hasTable(name),
165499
- dropRetiredTable: ({ name }) => backend.dropRetiredTable(name),
165500
165316
  threadId: () => threadId,
165501
165317
  listPhysicalTables: ({ ownerPrefix }) => backend.listTables(ownerPrefix)
165502
165318
  };
@@ -165588,9 +165404,6 @@ var require_wal_maintenance_CaJjuLHq = __commonJS({
165588
165404
  params
165589
165405
  };
165590
165406
  }
165591
- var RECORDS_TABLE = "records";
165592
- var RECORD_KINDS_TABLE = "_record_kinds";
165593
- var RECORD_SEQUENCES_TABLE = "_record_sequences";
165594
165407
  var RECORDS_SCHEMA_SQL = `
165595
165408
  CREATE TABLE IF NOT EXISTS records (
165596
165409
  rid INTEGER PRIMARY KEY,
@@ -165626,11 +165439,6 @@ CREATE TABLE IF NOT EXISTS _record_sequences (
165626
165439
  next INTEGER NOT NULL
165627
165440
  );
165628
165441
  `;
165629
- var RECORDS_ENGINE_TABLES = [
165630
- RECORDS_TABLE,
165631
- RECORD_KINDS_TABLE,
165632
- RECORD_SEQUENCES_TABLE
165633
- ];
165634
165442
  var INDEX_KIND_DEVICE_AT = "records_kind_device_at";
165635
165443
  var INDEX_KIND_AT = "records_kind_at";
165636
165444
  var FIELD_PATH = /^[A-Za-z_][A-Za-z0-9_]{0,63}(\.[A-Za-z_][A-Za-z0-9_]{0,63}){0,3}$/;
@@ -166634,7 +166442,6 @@ CREATE TABLE IF NOT EXISTS _record_sequences (
166634
166442
  ];
166635
166443
  var CONTROL_OPS = [
166636
166444
  "hasTable",
166637
- "dropRetiredTable",
166638
166445
  "threadId",
166639
166446
  "listPhysicalTables"
166640
166447
  ];
@@ -166883,9 +166690,6 @@ CREATE TABLE IF NOT EXISTS _record_sequences (
166883
166690
  kind: kind === "table" || kind === "index" ? kind : "unknown"
166884
166691
  };
166885
166692
  }
166886
- function isCountRow(raw) {
166887
- return raw !== null && typeof raw === "object" && typeof Reflect.get(raw, "n") === "number";
166888
- }
166889
166693
  function parseRowData(raw) {
166890
166694
  return require_dist10.asJsonObject(require_dist10.parseJsonUnknown(raw)) ?? {};
166891
166695
  }
@@ -167848,28 +167652,6 @@ CREATE TABLE IF NOT EXISTS _record_sequences (
167848
167652
  return out;
167849
167653
  }
167850
167654
  /**
167851
- * Drop one table nobody owns (D870 migration, one-shot). Refuses a canonical
167852
- * or engine table, one a running addon declared since boot, a table that is
167853
- * not there, and a row count other than the one the caller stated.
167854
- */
167855
- dropTable(name, expectRows) {
167856
- if (name.startsWith("sqlite_") || name === SqliteSettingsBackend2.DECLARATIONS_TABLE) throw new Error(`drop refused: "${name}" is an engine table`);
167857
- if (RECORDS_ENGINE_TABLES.includes(name)) throw new Error(`drop refused: "${name}" is a table of the records engine`);
167858
- if (SqliteSettingsBackend2.CANONICAL_KV_COLLECTIONS.includes(name)) throw new Error(`drop refused: "${name}" is a canonical collection`);
167859
- if (this.declaredThisBoot.has(name)) throw new Error(`drop refused: "${name}" is declared by a running addon`);
167860
- if (!this.hasTable(name)) throw new Error(`drop refused: no table "${name}"`);
167861
- const db = this.getDb();
167862
- const rows = db.prepare(`SELECT COUNT(*) AS c FROM "${name}"`).get()?.c ?? 0;
167863
- if (rows !== expectRows) throw new Error(`drop refused: "${name}" holds ${rows} rows, the caller expected ${expectRows}`);
167864
- db.transaction(() => {
167865
- db.exec(`DROP TABLE "${name}"`);
167866
- this.ensureDeclarationsTable();
167867
- db.prepare(`DELETE FROM "${SqliteSettingsBackend2.DECLARATIONS_TABLE}" WHERE name = ?`).run(name);
167868
- })();
167869
- this.declaredCollections.delete(name);
167870
- return rows;
167871
- }
167872
- /**
167873
167655
  * The tables this file's own `_collection_declarations` names — the
167874
167656
  * placement authority (D851). Read from DISK, not from memory, so a table
167875
167657
  * created and declared by an earlier life of the process still counts.
@@ -168289,31 +168071,6 @@ CREATE TABLE IF NOT EXISTS _record_sequences (
168289
168071
  }
168290
168072
  this.structuredTables.set(table, fingerprint);
168291
168073
  }
168292
- /**
168293
- * Drop a table nothing declares any more, reporting what went with it.
168294
- *
168295
- * The DDL lives here because the engine owns the handle AND the two memos
168296
- * that outlive a table: `structuredTables` (schema fingerprint) and
168297
- * `declaredCollections` (the column set `compileFilter` resolves against).
168298
- * Dropping behind their backs would leave a ghost — a later declaration of
168299
- * the same name would be memoised as "already materialised" against a table
168300
- * that no longer exists.
168301
- *
168302
- * WHICH tables are retired, and the logging, are policy: they live in
168303
- * `retired-collections.ts`. This method knows only how to drop one.
168304
- *
168305
- * Answers `null` when the table is not there — the steady state after the
168306
- * first boot that ran the purge, and the case on a fresh install.
168307
- */
168308
- dropRetiredTable(table) {
168309
- if (this.getDb().prepare(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`).get(table) === void 0) return null;
168310
- const counted = this.getDb().prepare(`SELECT COUNT(*) AS n FROM "${table}"`).get();
168311
- const rows = isCountRow(counted) ? counted.n : 0;
168312
- this.getDb().exec(`DROP TABLE "${table}"`);
168313
- this.structuredTables.delete(table);
168314
- this.declaredCollections.delete(table);
168315
- return { rows };
168316
- }
168317
168074
  /** Returns SQLite's `lastInsertRowid` — the only place an auto-assigned key
168318
168075
  * is knowable (D473). */
168319
168076
  async tableInsert(table, row) {
@@ -169389,9 +169146,9 @@ var require_sqlite_settings_addon = __commonJS({
169389
169146
  [Symbol.toStringTag]: { value: "Module" }
169390
169147
  });
169391
169148
  var require_chunk = require_chunk_Cek0wNdY();
169392
- var require_dist10 = require_dist_Bn_RNanh();
169393
- var require_retired_settings_keys = require_retired_settings_keys_D_VwZiDt();
169394
- var require_wal_maintenance = require_wal_maintenance_CaJjuLHq();
169149
+ var require_dist10 = require_dist_Ct_4tTeX();
169150
+ var require_retired_settings_keys = require_retired_settings_keys_CGUqX_Oz();
169151
+ var require_wal_maintenance = require_wal_maintenance_DBvuVU9s();
169395
169152
  var require_sqlite_snapshot_protocol = require_sqlite_snapshot_protocol_B9OndqZv();
169396
169153
  var require_wal_checkpoint_policy = require_wal_checkpoint_policy_d2z2qPqx();
169397
169154
  var node_fs_promises = __require("fs/promises");
@@ -170277,9 +170034,6 @@ var require_sqlite_settings_addon = __commonJS({
170277
170034
  listPhysicalTables(ownerPrefix) {
170278
170035
  return Promise.resolve(require_wal_maintenance.callControl(require_wal_maintenance.controlTargetOf(this.backend, 0), "listPhysicalTables", { ownerPrefix }));
170279
170036
  }
170280
- async dropRetiredTable(name) {
170281
- return require_wal_maintenance.callControl(require_wal_maintenance.controlTargetOf(this.backend, 0), "dropRetiredTable", { name });
170282
- }
170283
170037
  async servingThreadId() {
170284
170038
  return 0;
170285
170039
  }
@@ -170333,9 +170087,6 @@ var require_sqlite_settings_addon = __commonJS({
170333
170087
  listPhysicalTables(ownerPrefix) {
170334
170088
  return this.client.control("listPhysicalTables", { ownerPrefix });
170335
170089
  }
170336
- dropRetiredTable(name) {
170337
- return this.client.control("dropRetiredTable", { name });
170338
- }
170339
170090
  servingThreadId() {
170340
170091
  return this.client.control("threadId", {});
170341
170092
  }
@@ -170808,13 +170559,11 @@ var require_sqlite_settings_addon = __commonJS({
170808
170559
  var StorageAdminProvider = class {
170809
170560
  backend;
170810
170561
  logger;
170811
- installedOwners;
170812
170562
  records;
170813
170563
  peerFiles;
170814
- constructor(backend, logger, installedOwners, records, peerFiles = async () => []) {
170564
+ constructor(backend, logger, records, peerFiles = async () => []) {
170815
170565
  this.backend = backend;
170816
170566
  this.logger = logger;
170817
- this.installedOwners = installedOwners;
170818
170567
  this.records = records;
170819
170568
  this.peerFiles = peerFiles;
170820
170569
  }
@@ -170824,19 +170573,6 @@ var require_sqlite_settings_addon = __commonJS({
170824
170573
  readRecords(input) {
170825
170574
  return this.records.readRecords(input);
170826
170575
  }
170827
- /** May this table be dropped AT ALL? Throws with the reason when not. */
170828
- async assertDroppable(collection) {
170829
- const colon = collection.indexOf(":");
170830
- const base = colon > 0 ? collection.slice(colon + 1) : "";
170831
- if (colon > 0 && require_dist10.STORAGE_ADMIN_SCOPED_BASES.includes(base)) return;
170832
- if (require_dist10.STORAGE_ADMIN_MOVED_COLLECTIONS.includes(collection)) return;
170833
- if (colon <= 0) throw new Error(`drop refused: "${collection}" is not a scoped table`);
170834
- const installed = await this.installedOwners().catch((err) => {
170835
- throw new Error(`drop refused: the installed addons could not be read (${err instanceof Error ? err.message : String(err)})`);
170836
- });
170837
- const owner = collection.slice(0, colon);
170838
- if (installed.has(owner)) throw new Error(`drop refused: "${collection}" belongs to the installed addon "${owner}"`);
170839
- }
170840
170576
  async listTables(input) {
170841
170577
  const tables = [...this.backend.listTables(input.ownerPrefix)];
170842
170578
  for (const file of await this.peerFiles()) tables.push(...await file.listPhysicalTables(input.ownerPrefix));
@@ -170847,98 +170583,7 @@ var require_sqlite_settings_addon = __commonJS({
170847
170583
  } });
170848
170584
  return { tables };
170849
170585
  }
170850
- async dropCollection(input) {
170851
- try {
170852
- await this.assertDroppable(input.collection);
170853
- const rows = this.backend.dropTable(input.collection, input.expectRows);
170854
- this.logger.warn("storage-admin: DROPPED a table", { meta: {
170855
- collection: input.collection,
170856
- rows
170857
- } });
170858
- return {
170859
- dropped: true,
170860
- rows
170861
- };
170862
- } catch (err) {
170863
- this.logger.warn("storage-admin: drop refused", { meta: {
170864
- collection: input.collection,
170865
- expectRows: input.expectRows,
170866
- error: err instanceof Error ? err.message : String(err)
170867
- } });
170868
- throw err;
170869
- }
170870
- }
170871
170586
  };
170872
- var RETIRED_COLLECTIONS = [
170873
- {
170874
- collection: "devices",
170875
- owner: "integration-registry",
170876
- reason: "the device half of the integration-registry is deleted; the fleet is `device-manager:devices` and always was (0 rows here against 974 live devices)"
170877
- },
170878
- {
170879
- collection: "device_settings_kv",
170880
- owner: "integration-registry",
170881
- reason: "per-device settings of a device table that never had a row; the live per-camera store is the device-manager row plus `addon-device-settings`"
170882
- },
170883
- {
170884
- collection: "pipeline-analytics:track-groups",
170885
- owner: "pipeline-analytics",
170886
- reason: "the co-moving group entity is deleted (operator decision 2026-09-01, after the 2026-08-24 kill switch); nothing declares, writes or reads it"
170887
- },
170888
- {
170889
- collection: "pipeline-analytics:track-group-members",
170890
- owner: "pipeline-analytics",
170891
- reason: "membership rows of the deleted group entity; the track cascade that used to carry them away no longer has a group leg"
170892
- },
170893
- {
170894
- collection: "pipeline-analytics:summaries",
170895
- owner: "pipeline-analytics",
170896
- reason: "the session summary (proximity track grouping, D489/D490) is deleted (operator decision 2026-09-29, D680, after the 2026-09-16 switch-off); nothing declares, writes or reads it"
170897
- },
170898
- {
170899
- collection: "pipeline-analytics:summary-members",
170900
- owner: "pipeline-analytics",
170901
- reason: "membership rows of the deleted session summary; the track cascade no longer has a summary leg (D680)"
170902
- }
170903
- ];
170904
- function retiredCollectionStoreOfFile(file) {
170905
- return { async drop(collection) {
170906
- return file.dropRetiredTable(collection);
170907
- } };
170908
- }
170909
- async function purgeRetiredCollections(store, logger, specs = RETIRED_COLLECTIONS) {
170910
- const results = [];
170911
- for (const spec of specs) {
170912
- let dropped;
170913
- try {
170914
- dropped = await store.drop(spec.collection);
170915
- } catch (err) {
170916
- logger.warn("retired collection \u2014 drop failed, table left in place", { meta: {
170917
- addon: spec.owner,
170918
- collection: spec.collection,
170919
- error: err instanceof Error ? err.message : String(err)
170920
- } });
170921
- continue;
170922
- }
170923
- if (dropped === null) continue;
170924
- const result = {
170925
- collection: spec.collection,
170926
- owner: spec.owner,
170927
- rows: dropped.rows
170928
- };
170929
- results.push(result);
170930
- const line = "dropped a retired collection";
170931
- if (dropped.rows > 0) logger.warn(`${line} \u2014 it still held rows`, { meta: {
170932
- ...result,
170933
- reason: spec.reason
170934
- } });
170935
- else logger.info(line, { meta: {
170936
- ...result,
170937
- reason: spec.reason
170938
- } });
170939
- }
170940
- return results;
170941
- }
170942
170587
  var DATABASE_FILE_NAMES = {
170943
170588
  settings: "camstack.db",
170944
170589
  events: "events.db",
@@ -171028,14 +170673,13 @@ var require_sqlite_settings_addon = __commonJS({
171028
170673
  },
171029
170674
  {
171030
170675
  capability: require_dist10.storageAdminCapability,
171031
- provider: new StorageAdminProvider(settings.backend, this.ctx.logger.child("StorageAdmin"), async () => new Set((await this.ctx.api.addons.list.query()).map((addon) => addon.manifest.id)), records, async () => router.openFiles().filter((file) => file.databaseId !== "settings"))
170676
+ provider: new StorageAdminProvider(settings.backend, this.ctx.logger.child("StorageAdmin"), records, async () => router.openFiles().filter((file) => file.databaseId !== "settings"))
171032
170677
  }
171033
170678
  ];
171034
170679
  }
171035
170680
  /**
171036
170681
  * Housekeeping that must happen BEFORE anything can read a file: the
171037
- * retired-key purge (settings only) and the retired-table purge (every
171038
- * open file).
170682
+ * retired-key purge (settings file only).
171039
170683
  */
171040
170684
  async purgeBeforeServing(file) {
171041
170685
  if (file instanceof InlineOwnedFile && file.databaseId === "settings") try {
@@ -171043,7 +170687,6 @@ var require_sqlite_settings_addon = __commonJS({
171043
170687
  } catch (err) {
171044
170688
  this.ctx.logger.warn("Retired-key purge failed", { meta: { error: require_dist10.errMsg(err) } });
171045
170689
  }
171046
- await purgeRetiredCollections(retiredCollectionStoreOfFile(file), this.ctx.logger.child("RetiredCollections").withTags({ database: file.databaseId }));
171047
170690
  }
171048
170691
  /**
171049
170692
  * The engine's TTL sweep (D881): every 10 minutes, off the boot path (the
@@ -171118,7 +170761,7 @@ var require_sqlite_storage = __commonJS({
171118
170761
  });
171119
170762
  require_chunk_Cek0wNdY();
171120
170763
  var require_builtins_sqlite_storage_filesystem_storage_addon = require_filesystem_storage_addon();
171121
- var require_wal_maintenance = require_wal_maintenance_CaJjuLHq();
170764
+ var require_wal_maintenance = require_wal_maintenance_DBvuVU9s();
171122
170765
  var require_builtins_sqlite_storage_sqlite_settings_addon = require_sqlite_settings_addon();
171123
170766
  var ConfigStore = class {
171124
170767
  db;
@@ -171202,7 +170845,7 @@ var require_storage_orchestrator_addon = __commonJS({
171202
170845
  [Symbol.toStringTag]: { value: "Module" }
171203
170846
  });
171204
170847
  var require_chunk = require_chunk_Cek0wNdY();
171205
- var require_dist10 = require_dist_Bn_RNanh();
170848
+ var require_dist10 = require_dist_Ct_4tTeX();
171206
170849
  var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
171207
170850
  var zod = require_zod();
171208
170851
  var node_crypto = __require("crypto");
@@ -175789,12 +175432,12 @@ var require_storage_orchestrator = __commonJS({
175789
175432
  }
175790
175433
  });
175791
175434
 
175792
- // ../system/dist/agent-https-Dnr_nIVx.js
175793
- var require_agent_https_Dnr_nIVx = __commonJS({
175794
- "../system/dist/agent-https-Dnr_nIVx.js"(exports) {
175435
+ // ../system/dist/agent-https-C6M6apPV.js
175436
+ var require_agent_https_C6M6apPV = __commonJS({
175437
+ "../system/dist/agent-https-C6M6apPV.js"(exports) {
175795
175438
  "use strict";
175796
175439
  var require_chunk = require_chunk_Cek0wNdY();
175797
- var require_dist10 = require_dist_Bn_RNanh();
175440
+ var require_dist10 = require_dist_Ct_4tTeX();
175798
175441
  var require_x509_es = require_x509_es_C4cOo48M();
175799
175442
  var zod = require_zod();
175800
175443
  var node_crypto = __require("crypto");
@@ -176852,11 +176495,11 @@ var require_agent_https_Dnr_nIVx = __commonJS({
176852
176495
  }
176853
176496
  });
176854
176497
 
176855
- // ../system/dist/constants-6OeJiZgi.js
176856
- var require_constants_6OeJiZgi = __commonJS({
176857
- "../system/dist/constants-6OeJiZgi.js"(exports) {
176498
+ // ../system/dist/constants-7ZMxWr8Z.js
176499
+ var require_constants_7ZMxWr8Z = __commonJS({
176500
+ "../system/dist/constants-7ZMxWr8Z.js"(exports) {
176858
176501
  "use strict";
176859
- var MESH_CA_KEY_REF = require_dist_Bn_RNanh().buildSecretRef({
176502
+ var MESH_CA_KEY_REF = require_dist_Ct_4tTeX().buildSecretRef({
176860
176503
  owner: "system",
176861
176504
  scope: { kind: "global" },
176862
176505
  fieldPath: "meshCaKey"
@@ -193953,11 +193596,11 @@ var require_system_config_addon = __commonJS({
193953
193596
  [Symbol.toStringTag]: { value: "Module" }
193954
193597
  });
193955
193598
  var require_chunk = require_chunk_Cek0wNdY();
193956
- var require_dist10 = require_dist_Bn_RNanh();
193599
+ var require_dist10 = require_dist_Ct_4tTeX();
193957
193600
  var require_safe_buffer$1 = require_safe_buffer_D3aoa_7X();
193958
193601
  var require_x509_es = require_x509_es_C4cOo48M();
193959
- var require_agent_https = require_agent_https_Dnr_nIVx();
193960
- var require_constants$8 = require_constants_6OeJiZgi();
193602
+ var require_agent_https = require_agent_https_C6M6apPV();
193603
+ var require_constants$8 = require_constants_7ZMxWr8Z();
193961
193604
  var require_src$1 = require_src_CnAqG6EF();
193962
193605
  var zod = require_zod();
193963
193606
  var node_crypto = __require("crypto");
@@ -275009,7 +274652,7 @@ var require_winston_logging = __commonJS({
275009
274652
  [Symbol.toStringTag]: { value: "Module" }
275010
274653
  });
275011
274654
  var require_chunk = require_chunk_Cek0wNdY();
275012
- var require_dist10 = require_dist_Bn_RNanh();
274655
+ var require_dist10 = require_dist_Ct_4tTeX();
275013
274656
  var require_formatter = require_formatter_DqAKDlvN();
275014
274657
  var require_log_file_read_protocol = require_log_file_read_protocol_D0WcLbIV();
275015
274658
  var node_path = __require("path");
@@ -275306,9 +274949,9 @@ var require_winston_logging = __commonJS({
275306
274949
  }
275307
274950
  });
275308
274951
 
275309
- // ../system/dist/custom-action-registry-COyb49zm.js
275310
- var require_custom_action_registry_COyb49zm = __commonJS({
275311
- "../system/dist/custom-action-registry-COyb49zm.js"(exports) {
274952
+ // ../system/dist/custom-action-registry-MRyes5j0.js
274953
+ var require_custom_action_registry_MRyes5j0 = __commonJS({
274954
+ "../system/dist/custom-action-registry-MRyes5j0.js"(exports) {
275312
274955
  "use strict";
275313
274956
  var require_chunk = require_chunk_Cek0wNdY();
275314
274957
  var node_crypto = __require("crypto");
@@ -275431,6 +275074,8 @@ var require_custom_action_registry_COyb49zm = __commonJS({
275431
275074
  "objectDetection/yolov9/openvino/camstack-yolov9t-320-int8.xml": "ee465e0ee5c6ad7c4edc481b506a076045b82236ada80efcf8601a6ba0a7ee86",
275432
275075
  "objectDetection/yolov9/openvino/camstack-yolov9t-640-fp16.xml": "d4dd2278941ccb210d0763d822353f6d951c6a4f4f5a1604d7e3536ce6ffb954",
275433
275076
  "objectDetection/yolov9/openvino/camstack-yolov9t-640-int8.xml": "be2c95951a9f3a6d408bbabd551c99b8a6190f9ff659ae614b9e58cf0e51202c",
275077
+ "objectDetection/yolov9/tflite/yolov9-s-relu6-best_320_int8_edgetpu.tflite": "49a38e77439b475d0d259a6d9fe7ea32fcaa58de3748499dd120aceebad9c591",
275078
+ "objectDetection/yolov9/tflite/yolov9-s-relu6-tpumax_512_int8_edgetpu.tflite": "f634f60259101556825fd69662f96282e74364b507f83e6382cc34d5d0e6170e",
275434
275079
  "packageDetection/rfdetr-package/coreml/camstack-rfdetr-package.mlpackage": "73e42f03d66011a311bd83a0a3d1890e7eb1b9b2ba2b5688552a5d4fd60e0e72",
275435
275080
  "packageDetection/rfdetr-package/onnx/camstack-rfdetr-package.onnx": "5af96c6b5936f179e317c9e3915b7c7f74ea3625355f97f6a071c3cd5af2475c",
275436
275081
  "packageDetection/rfdetr-package/openvino/camstack-rfdetr-package.xml": "e2cb5bbccb7809d5c7e691a957bc5e008084119bdf29e2c95d6b6b0791e3061a",
@@ -282810,14 +282455,14 @@ var require_lib_8oZrELLm = __commonJS({
282810
282455
  }
282811
282456
  });
282812
282457
 
282813
- // ../system/dist/hub-mdns-ciao-CTBTlia4.js
282814
- var require_hub_mdns_ciao_CTBTlia4 = __commonJS({
282815
- "../system/dist/hub-mdns-ciao-CTBTlia4.js"(exports) {
282458
+ // ../system/dist/hub-mdns-ciao-DJ-Amqd7.js
282459
+ var require_hub_mdns_ciao_DJ_Amqd7 = __commonJS({
282460
+ "../system/dist/hub-mdns-ciao-DJ-Amqd7.js"(exports) {
282816
282461
  "use strict";
282817
282462
  var require_chunk = require_chunk_Cek0wNdY();
282818
- var require_dist10 = require_dist_Bn_RNanh();
282463
+ var require_dist10 = require_dist_Ct_4tTeX();
282819
282464
  var require_x509_es = require_x509_es_C4cOo48M();
282820
- var require_agent_https = require_agent_https_Dnr_nIVx();
282465
+ var require_agent_https = require_agent_https_C6M6apPV();
282821
282466
  var node_crypto = __require("crypto");
282822
282467
  var _camstack_types_node = require_node();
282823
282468
  var node_fs_promises = __require("fs/promises");
@@ -283829,12 +283474,12 @@ var require_platform_key_source_Di7HrlGR = __commonJS({
283829
283474
  }
283830
283475
  });
283831
283476
 
283832
- // ../system/dist/restore-archive-DM1OBYq4.js
283833
- var require_restore_archive_DM1OBYq4 = __commonJS({
283834
- "../system/dist/restore-archive-DM1OBYq4.js"(exports) {
283477
+ // ../system/dist/restore-archive-HwOA83v3.js
283478
+ var require_restore_archive_HwOA83v3 = __commonJS({
283479
+ "../system/dist/restore-archive-HwOA83v3.js"(exports) {
283835
283480
  "use strict";
283836
283481
  var require_chunk = require_chunk_Cek0wNdY();
283837
- var require_dist10 = require_dist_Bn_RNanh();
283482
+ var require_dist10 = require_dist_Ct_4tTeX();
283838
283483
  var zod = require_zod();
283839
283484
  var node_crypto = __require("crypto");
283840
283485
  var buffer = __require("buffer");
@@ -295075,9 +294720,9 @@ var require_dist3 = __commonJS({
295075
294720
  "use strict";
295076
294721
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
295077
294722
  var require_chunk = require_chunk_Cek0wNdY();
295078
- var require_dist10 = require_dist_Bn_RNanh();
294723
+ var require_dist10 = require_dist_Ct_4tTeX();
295079
294724
  var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
295080
- var require_device_ca = require_device_ca_CPTDs_d();
294725
+ var require_device_ca = require_device_ca_CUEx7sti();
295081
294726
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
295082
294727
  require_alerts();
295083
294728
  var require_builtins_calendars_calendars_addon = require_calendars_addon();
@@ -295086,11 +294731,9 @@ var require_dist3 = __commonJS({
295086
294731
  require_composer();
295087
294732
  var require_formatter = require_formatter_DqAKDlvN();
295088
294733
  var require_builtins_console_logging_index = require_console_logging();
295089
- var require_prefix_range = require_prefix_range_D_KueXbQ();
295090
294734
  var require_prefix_walk = require_prefix_walk_Dv6MLZlM();
295091
294735
  var require_builtins_core_blocks_core_blocks_addon = require_core_blocks_addon();
295092
294736
  require_core_blocks();
295093
- var require_retired_settings_keys = require_retired_settings_keys_D_VwZiDt();
295094
294737
  var require_builtins_device_manager_device_manager_addon = require_device_manager_addon();
295095
294738
  require_device_manager();
295096
294739
  var require_builtins_hub_forwarder_index = require_hub_forwarder();
@@ -295103,21 +294746,21 @@ var require_dist3 = __commonJS({
295103
294746
  var require_builtins_native_metrics_native_metrics_addon = require_native_metrics_addon();
295104
294747
  var require_builtins_device_history_device_history_addon = require_device_history_addon();
295105
294748
  var require_builtins_sqlite_storage_filesystem_storage_addon = require_filesystem_storage_addon();
295106
- var require_wal_maintenance = require_wal_maintenance_CaJjuLHq();
294749
+ var require_wal_maintenance = require_wal_maintenance_DBvuVU9s();
295107
294750
  var require_builtins_sqlite_storage_sqlite_settings_addon = require_sqlite_settings_addon();
295108
294751
  var require_builtins_sqlite_storage_index = require_sqlite_storage();
295109
294752
  var require_builtins_storage_orchestrator_storage_orchestrator_addon = require_storage_orchestrator_addon();
295110
294753
  require_storage_orchestrator();
295111
- var require_agent_https = require_agent_https_Dnr_nIVx();
295112
- var require_constants15 = require_constants_6OeJiZgi();
294754
+ var require_agent_https = require_agent_https_C6M6apPV();
294755
+ var require_constants15 = require_constants_7ZMxWr8Z();
295113
294756
  var require_builtins_system_config_system_config_addon = require_system_config_addon();
295114
294757
  require_system_config();
295115
294758
  var require_builtins_winston_logging_index = require_winston_logging();
295116
- var require_custom_action_registry = require_custom_action_registry_COyb49zm();
295117
- var require_hub_mdns_ciao = require_hub_mdns_ciao_CTBTlia4();
294759
+ var require_custom_action_registry = require_custom_action_registry_MRyes5j0();
294760
+ var require_hub_mdns_ciao = require_hub_mdns_ciao_DJ_Amqd7();
295118
294761
  var require_platform_key_source = require_platform_key_source_Di7HrlGR();
295119
294762
  var require_resource_monitor = require_resource_monitor_mio9dSCT();
295120
- var require_restore_archive = require_restore_archive_DM1OBYq4();
294763
+ var require_restore_archive = require_restore_archive_HwOA83v3();
295121
294764
  var require_coral_accelerators = require_coral_accelerators_oUXmmbc2();
295122
294765
  var zod = require_zod();
295123
294766
  var node_crypto = __require("crypto");
@@ -295907,22 +295550,22 @@ var require_dist3 = __commonJS({
295907
295550
  const queuedTop = window2.queued.top.map((p) => `${p.peerId}:${kb$1(p.bytes)}`).join(",");
295908
295551
  return ` socketPeers=${window2.peersMeasured}/${window2.peersConnected} socketTx=${formatDirection(window2.tx)} socketRx=${formatDirection(window2.rx)}` + (top.length === 0 ? "" : ` socketTop=${top}`) + (topBytes.length === 0 ? "" : ` socketTopBytes=${topBytes}`) + ` socketQueued=${kb$1(window2.queued.totalBytes)}kB` + (window2.queued.unmeasured === 0 ? "" : ` socketQueuedUnmeasured=${window2.queued.unmeasured}`) + (queuedTop.length === 0 ? "" : ` socketQueuedTop=${queuedTop}`) + (window2.forward === void 0 ? "" : ` socketFwd=${window2.forward.raw}/${window2.forward.decoded}`) + (window2.actions === void 0 ? "" : ` socketActions=${kb$1(window2.actions.labelledBytes)}/${kb$1(window2.actions.totalBytes)}kB` + (window2.actions.top.length === 0 ? "" : ` socketTopActions=${window2.actions.top.map(formatAction).join(",")}`));
295909
295552
  }
295910
- function isRecord$7(value) {
295553
+ function isRecord$6(value) {
295911
295554
  return typeof value === "object" && value !== null;
295912
295555
  }
295913
295556
  function writerSocketsOf(broker) {
295914
- if (!isRecord$7(broker)) return void 0;
295557
+ if (!isRecord$6(broker)) return void 0;
295915
295558
  const transit = broker["transit"];
295916
- if (!isRecord$7(transit)) return void 0;
295559
+ if (!isRecord$6(transit)) return void 0;
295917
295560
  const transporter = transit["tx"];
295918
- if (!isRecord$7(transporter)) return void 0;
295561
+ if (!isRecord$6(transporter)) return void 0;
295919
295562
  const writer = transporter["writer"];
295920
- if (!isRecord$7(writer)) return void 0;
295563
+ if (!isRecord$6(writer)) return void 0;
295921
295564
  const sockets = writer["sockets"];
295922
295565
  return sockets instanceof Map ? sockets : void 0;
295923
295566
  }
295924
295567
  function readSocket(nodeId, socket) {
295925
- if (typeof nodeId !== "string" || !isRecord$7(socket)) return void 0;
295568
+ if (typeof nodeId !== "string" || !isRecord$6(socket)) return void 0;
295926
295569
  const queuedBytes = socket["writableLength"];
295927
295570
  const bytesWritten = socket["bytesWritten"];
295928
295571
  if (typeof queuedBytes !== "number" || typeof bytesWritten !== "number") return void 0;
@@ -299528,7 +299171,6 @@ var require_dist3 = __commonJS({
299528
299171
  };
299529
299172
  }
299530
299173
  };
299531
- var CLUSTER_NODE_HISTORY_COLLECTION = "cluster-node-history";
299532
299174
  var NodePackageEntrySchema = zod.z.object({
299533
299175
  name: zod.z.string(),
299534
299176
  version: zod.z.string().nullable()
@@ -299821,27 +299463,27 @@ var require_dist3 = __commonJS({
299821
299463
  throw new Error(`no system npm on PATH and the npm bootstrap failed \u2014 cannot install addon dependencies on this node: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
299822
299464
  }
299823
299465
  }
299824
- function isRecord$6(value) {
299466
+ function isRecord$5(value) {
299825
299467
  return typeof value === "object" && value !== null && !Array.isArray(value);
299826
299468
  }
299827
299469
  function isAddonConstructor(fn) {
299828
299470
  if (typeof fn !== "function") return false;
299829
299471
  const proto = fn.prototype;
299830
- if (!isRecord$6(proto)) return false;
299472
+ if (!isRecord$5(proto)) return false;
299831
299473
  return typeof proto["initialize"] === "function";
299832
299474
  }
299833
299475
  function resolveAddonClass(mod) {
299834
299476
  let candidate = mod["default"];
299835
- if (isRecord$6(candidate) && "default" in candidate) candidate = candidate["default"];
299477
+ if (isRecord$5(candidate) && "default" in candidate) candidate = candidate["default"];
299836
299478
  if (isAddonConstructor(candidate)) return candidate;
299837
- if (isRecord$6(candidate)) {
299479
+ if (isRecord$5(candidate)) {
299838
299480
  const fn = Object.values(candidate).find(isAddonConstructor);
299839
299481
  if (fn) return fn;
299840
299482
  }
299841
299483
  const namedAddon = Object.values(mod).find(isAddonConstructor);
299842
299484
  if (namedAddon) return namedAddon;
299843
299485
  }
299844
- function isRecord$5(value) {
299486
+ function isRecord$4(value) {
299845
299487
  return typeof value === "object" && value !== null && !Array.isArray(value);
299846
299488
  }
299847
299489
  var PACKAGE_JSON_LOOKUP_DEPTH = 4;
@@ -299881,12 +299523,12 @@ var require_dist3 = __commonJS({
299881
299523
  return import(`${(0, node_url.pathToFileURL)(entryPath).href}?v=${encodeURIComponent(bust)}`);
299882
299524
  }
299883
299525
  function isAddonPackageManifest(value) {
299884
- if (!isRecord$5(value)) return false;
299526
+ if (!isRecord$4(value)) return false;
299885
299527
  if (!Array.isArray(value.addons)) return false;
299886
- return value.addons.every((a) => isRecord$5(a) && typeof a.id === "string");
299528
+ return value.addons.every((a) => isRecord$4(a) && typeof a.id === "string");
299887
299529
  }
299888
299530
  function toAddonPackageManifest(value) {
299889
- if (!isRecord$5(value)) return void 0;
299531
+ if (!isRecord$4(value)) return void 0;
299890
299532
  if (!isAddonPackageManifest(value)) return void 0;
299891
299533
  return value;
299892
299534
  }
@@ -300043,7 +299685,7 @@ var require_dist3 = __commonJS({
300043
299685
  }
300044
299686
  if (!node_fs.existsSync(entryPath)) throw new Error(`Entry not found: ${entryPath}`);
300045
299687
  const modUnknown = await importAddonModuleFresh(entryPath);
300046
- const mod = isRecord$5(modUnknown) ? modUnknown : {};
299688
+ const mod = isRecord$4(modUnknown) ? modUnknown : {};
300047
299689
  const AddonClass = resolveAddonClass(mod);
300048
299690
  if (!AddonClass) throw new Error(`No addon class in ${entryPath}`);
300049
299691
  this.addons.set(declaration.id, {
@@ -300059,7 +299701,7 @@ var require_dist3 = __commonJS({
300059
299701
  /** Load addon from a direct path (for development/testing) */
300060
299702
  async loadFromPath(addonId, modulePath, packageName, declaration, packageVersion = "0.0.0") {
300061
299703
  const modUnknown = await importAddonModuleFresh(modulePath);
300062
- const mod = isRecord$5(modUnknown) ? modUnknown : {};
299704
+ const mod = isRecord$4(modUnknown) ? modUnknown : {};
300063
299705
  const AddonClass = resolveAddonClass(mod);
300064
299706
  if (!AddonClass) throw new Error(`Module ${modulePath} has no default export`);
300065
299707
  this.addons.set(addonId, {
@@ -304330,11 +303972,11 @@ var require_dist3 = __commonJS({
304330
303972
  await steps.bootInProcessConsumers();
304331
303973
  await steps.spawnIsolatedConsumers();
304332
303974
  }
304333
- function isRecord$4(value) {
303975
+ function isRecord$3(value) {
304334
303976
  return typeof value === "object" && value !== null && !Array.isArray(value);
304335
303977
  }
304336
303978
  function asBlob(value) {
304337
- return isRecord$4(value) ? value : {};
303979
+ return isRecord$3(value) ? value : {};
304338
303980
  }
304339
303981
  async function loadSystemSettingsPrefix(door, prefix, mayRead = () => true) {
304340
303982
  const listed = await require_prefix_walk.loadPrefixed(door, "system-settings", prefix, () => null);
@@ -306882,7 +306524,7 @@ var require_dist3 = __commonJS({
306882
306524
  })))(), 1);
306883
306525
  var { Type, Schema, FAILSAFE_SCHEMA, JSON_SCHEMA, CORE_SCHEMA, DEFAULT_SCHEMA, load: load2, loadAll, dump, YAMLException, types, safeLoad, safeLoadAll, safeDump } = import_js_yaml.default;
306884
306526
  import_js_yaml.default;
306885
- function isRecord$3(value) {
306527
+ function isRecord$2(value) {
306886
306528
  return typeof value === "object" && value !== null && !Array.isArray(value);
306887
306529
  }
306888
306530
  var BOOTSTRAP_SECTIONS = /* @__PURE__ */ new Set([
@@ -306959,7 +306601,7 @@ var require_dist3 = __commonJS({
306959
306601
  [head]: value
306960
306602
  };
306961
306603
  const existing = obj[head];
306962
- const child = isRecord$3(existing) ? existing : {};
306604
+ const child = isRecord$2(existing) ? existing : {};
306963
306605
  return {
306964
306606
  ...obj,
306965
306607
  [head]: setNested(child, rest.join("."), value)
@@ -307168,7 +306810,7 @@ var require_dist3 = __commonJS({
307168
306810
  }
307169
306811
  }
307170
306812
  };
307171
- function isRecord$2(value) {
306813
+ function isRecord$1(value) {
307172
306814
  return typeof value === "object" && value !== null && !Array.isArray(value);
307173
306815
  }
307174
306816
  function errorText(err) {
@@ -307533,7 +307175,7 @@ var require_dist3 = __commonJS({
307533
307175
  const keys = configPath.split(".");
307534
307176
  let current = this.bootstrapConfig;
307535
307177
  for (const key of keys) {
307536
- if (!isRecord$2(current)) return void 0;
307178
+ if (!isRecord$1(current)) return void 0;
307537
307179
  current = current[key];
307538
307180
  }
307539
307181
  return current;
@@ -308302,7 +307944,7 @@ var require_dist3 = __commonJS({
308302
307944
  this.name = "RuntimeStateLoadError";
308303
307945
  }
308304
307946
  };
308305
- function isRecord$1(value) {
307947
+ function isRecord(value) {
308306
307948
  return typeof value === "object" && value !== null && !Array.isArray(value);
308307
307949
  }
308308
307950
  function errorMessage(err) {
@@ -308328,7 +307970,7 @@ var require_dist3 = __commonJS({
308328
307970
  } catch (err) {
308329
307971
  return refuse2(errorMessage(err), err);
308330
307972
  }
308331
- if (!isRecord$1(answer)) return refuse2(`answered ${answer === null ? "null" : typeof answer}`);
307973
+ if (!isRecord(answer)) return refuse2(`answered ${answer === null ? "null" : typeof answer}`);
308332
307974
  return answer;
308333
307975
  }
308334
307976
  var ACCESSORY_SPAWN_CONCURRENCY = 12;
@@ -314241,8 +313883,7 @@ var require_dist3 = __commonJS({
314241
313883
  }
314242
313884
  };
314243
313885
  }
314244
- function createRunnerAddonSettings(client, addonId, before = async () => {
314245
- }) {
313886
+ function createRunnerAddonSettings(client, addonId) {
314246
313887
  if (client === void 0) {
314247
313888
  const refuse2 = async () => {
314248
313889
  throw new Error(`settings of "${addonId}": settings store not wired`);
@@ -314264,22 +313905,10 @@ var require_dist3 = __commonJS({
314264
313905
  };
314265
313906
  }
314266
313907
  const door = {
314267
- query: async (input) => {
314268
- await before();
314269
- return client.query.query(input);
314270
- },
314271
- get: async (input) => {
314272
- await before();
314273
- return client.get.query(input);
314274
- },
314275
- set: async (input) => {
314276
- await before();
314277
- return client.set.mutate(input);
314278
- },
314279
- transact: async (input) => {
314280
- await before();
314281
- return client.transact.mutate(input);
314282
- }
313908
+ query: (input) => client.query.query(input),
313909
+ get: (input) => client.get.query(input),
313910
+ set: (input) => client.set.mutate(input),
313911
+ transact: (input) => client.transact.mutate(input)
314283
313912
  };
314284
313913
  const store = require_builtins_core_blocks_core_blocks_addon.createAddonSettingsStore(door, addonId);
314285
313914
  const sections = createSectionsStore(door);
@@ -314325,141 +313954,14 @@ var require_dist3 = __commonJS({
314325
313954
  setSection: (section, patch) => sections.write(section, patch)
314326
313955
  };
314327
313956
  }
314328
- var AddonRefusedError = class extends Error {
314329
- /** Stable, greppable cause, e.g. `unmigrated-settings`. */
314330
- code;
314331
- /** What the operator does about it. */
314332
- remedy;
314333
- constructor(code, message, remedy, options) {
314334
- super(message, options);
314335
- this.name = "AddonRefusedError";
314336
- this.code = code;
314337
- this.remedy = remedy;
314338
- }
314339
- };
314340
- function findAddonRefusal(err) {
314341
- const seen = /* @__PURE__ */ new Set();
314342
- let current = err;
314343
- while (current !== null && current !== void 0 && !seen.has(current)) {
314344
- if (current instanceof AddonRefusedError) return current;
314345
- seen.add(current);
314346
- current = current instanceof Error ? current.cause : void 0;
314347
- }
314348
- return null;
314349
- }
314350
- var OWN_RETIRED_ROOT_KEYS = /* @__PURE__ */ new Set([
314351
- "recordingConfigs",
314352
- "recordingExports",
314353
- "recordingOpsLog",
314354
- "probeSnapshots",
314355
- "rtspTokens",
314356
- "profileMap"
314357
- ]);
314358
- function isRetiredRootKey(addonId, key) {
314359
- if (OWN_RETIRED_ROOT_KEYS.has(key)) return true;
314360
- return require_retired_settings_keys.RETIRED_SETTINGS_KEYS.some((spec) => spec.namespace === addonId && (spec.keys.includes(key) || spec.perNodeKeys.some((k) => key === k || key.startsWith(`${k}@`))));
314361
- }
314362
- var UNMIGRATED_SETTINGS_CODE = "unmigrated-settings";
314363
- var UNMIGRATED_SETTINGS_REMEDY = "Run scripts/hub/migrate-device-store.ts --copy --apply (D870), then restart the addon.";
314364
- var UnmigratedSettingsError = class extends AddonRefusedError {
314365
- constructor(addonId, what) {
314366
- super(UNMIGRATED_SETTINGS_CODE, `addon "${addonId}" refuses to start: ${what} - the settings it had are still in the per-addon tables and the standard store holds none. Run scripts/hub/migrate-device-store.ts --copy --apply (D870) before starting it.`, UNMIGRATED_SETTINGS_REMEDY);
314367
- this.name = "UnmigratedSettingsError";
314368
- }
314369
- };
314370
- async function countOf(client, input) {
314371
- const n = await client.count.query(input);
314372
- if (typeof n !== "number") throw new Error("settings store answered a non-number to a count");
314373
- return n;
314374
- }
314375
- var LEGACY_PAGE = 500;
314376
- var LEGACY_PAGE_BUDGET = 200;
314377
- var ID_TAIL = "\x7F";
314378
- function isRecord(value) {
314379
- return typeof value === "object" && value !== null && !Array.isArray(value);
314380
- }
314381
- async function hasMigratableDeviceRow(client, addonId) {
314382
- let cursor = "";
314383
- for (let page = 0; page < LEGACY_PAGE_BUDGET; page++) {
314384
- const rows = await client.query.query({
314385
- namespace: addonId,
314386
- collection: "addon-devices",
314387
- filter: {
314388
- whereBetween: { id: [cursor, ID_TAIL] },
314389
- orderBy: {
314390
- field: "id",
314391
- direction: "asc"
314392
- },
314393
- limit: LEGACY_PAGE
314394
- }
314395
- });
314396
- if (!Array.isArray(rows)) throw new Error("settings store answered a non-list to a query");
314397
- let lastId = cursor;
314398
- for (const row of rows) {
314399
- if (!isRecord(row) || typeof row["id"] !== "string") continue;
314400
- lastId = row["id"];
314401
- const id = Number(row["id"]);
314402
- const data = row["data"];
314403
- if (Number.isInteger(id) && id > 0 && isRecord(data) && Object.keys(data).length > 0) return true;
314404
- }
314405
- if (rows.length < LEGACY_PAGE || lastId === cursor) return false;
314406
- cursor = lastId;
314407
- }
314408
- throw new Error(`addon "${addonId}": more legacy blob pages than the guard will read`);
314409
- }
314410
- async function assertLegacyBlobsMigrated(client, addonId, logger) {
314411
- const legacyDevices = await hasMigratableDeviceRow(client, addonId);
314412
- const root = await client.get.query({
314413
- namespace: addonId,
314414
- collection: "addon-settings",
314415
- key: "root"
314416
- });
314417
- const legacySettings = isRecord(root) && Object.keys(root).some((key) => !isRetiredRootKey(addonId, key));
314418
- if (!legacyDevices && !legacySettings) return;
314419
- const rangeOf = (prefix) => {
314420
- const range = require_prefix_range.prefixRange(prefix);
314421
- if (range === null) throw new Error(`no id range for addon "${addonId}"`);
314422
- return { whereBetween: { id: [range.lo, range.hi] } };
314423
- };
314424
- const newDevices = await countOf(client, {
314425
- collection: "addon-device-settings",
314426
- filter: rangeOf(`${addonId}:`)
314427
- });
314428
- const newSettings = await countOf(client, {
314429
- collection: "addon-settings",
314430
- filter: rangeOf(`${addonId}.`)
314431
- });
314432
- const problems = [];
314433
- if (legacyDevices && newDevices === 0) problems.push("per-device blobs");
314434
- if (legacySettings && newSettings === 0) problems.push("an addon settings blob");
314435
- if (problems.length === 0) return;
314436
- const error = new UnmigratedSettingsError(addonId, problems.join(" and "));
314437
- logger.error(error.message, { meta: {
314438
- addonId,
314439
- newDevices,
314440
- newSettings
314441
- } });
314442
- throw error;
314443
- }
314444
- function doorOverClient(client, before = async () => {
314445
- }) {
313957
+ function doorOverClient(client) {
314446
313958
  return {
314447
- query: async (input) => {
314448
- await before();
314449
- return client.query.query(input);
314450
- },
314451
- transact: async (input) => {
314452
- await before();
314453
- return client.transact.mutate(input);
314454
- },
314455
- deleteWhere: async (input) => {
314456
- await before();
314457
- return client.deleteWhere.mutate(input);
314458
- }
313959
+ query: (input) => client.query.query(input),
313960
+ transact: (input) => client.transact.mutate(input),
313961
+ deleteWhere: (input) => client.deleteWhere.mutate(input)
314459
313962
  };
314460
313963
  }
314461
- function createRunnerDeviceSettings(client, addonId, before = async () => {
314462
- }) {
313964
+ function createRunnerDeviceSettings(client, addonId) {
314463
313965
  if (client === void 0) {
314464
313966
  const refuse2 = () => {
314465
313967
  throw new Error(`device settings of "${addonId}": settings store not wired`);
@@ -314472,7 +313974,7 @@ var require_dist3 = __commonJS({
314472
313974
  clearDeviceStore: async () => refuse2()
314473
313975
  };
314474
313976
  }
314475
- const store = require_builtins_device_manager_device_manager_addon.createDeviceSettingsStore(doorOverClient(client, before), addonId);
313977
+ const store = require_builtins_device_manager_device_manager_addon.createDeviceSettingsStore(doorOverClient(client), addonId);
314476
313978
  return {
314477
313979
  readDeviceStore: (deviceId) => require_builtins_device_manager_device_manager_addon.readDeviceOrThrow(store, deviceId),
314478
313980
  readDeviceStoreBatch: (ids) => store.readBatch(ids),
@@ -314674,23 +314176,9 @@ var require_dist3 = __commonJS({
314674
314176
  }
314675
314177
  };
314676
314178
  const deviceSettingsClient = Reflect.get(api, "settingsStore");
314677
- let blobsChecked = null;
314678
- const bootGuard = () => {
314679
- const client = deviceSettingsClient;
314680
- if (client === void 0) return Promise.resolve();
314681
- blobsChecked ??= assertLegacyBlobsMigrated({
314682
- get: { query: (input) => client.get.query(input) },
314683
- query: { query: (input) => client.query.query(input) },
314684
- count: { query: (input) => client.count.query(input) }
314685
- }, addonId, scopedLogger).catch((err) => {
314686
- blobsChecked = null;
314687
- throw err;
314688
- });
314689
- return blobsChecked;
314690
- };
314691
314179
  const settingsView = {
314692
- ...createRunnerAddonSettings(deviceSettingsClient, addonId, bootGuard),
314693
- ...createRunnerDeviceSettings(deviceSettingsClient, addonId, bootGuard),
314180
+ ...createRunnerAddonSettings(deviceSettingsClient, addonId),
314181
+ ...createRunnerDeviceSettings(deviceSettingsClient, addonId),
314694
314182
  async readDeviceRuntimeState(deviceId) {
314695
314183
  return readBlob("device-runtime-state", String(deviceId));
314696
314184
  },
@@ -316778,6 +316266,28 @@ var require_dist3 = __commonJS({
316778
316266
  }
316779
316267
  };
316780
316268
  }
316269
+ var AddonRefusedError = class extends Error {
316270
+ /** Stable, greppable cause, e.g. `unmigrated-settings`. */
316271
+ code;
316272
+ /** What the operator does about it. */
316273
+ remedy;
316274
+ constructor(code, message, remedy, options) {
316275
+ super(message, options);
316276
+ this.name = "AddonRefusedError";
316277
+ this.code = code;
316278
+ this.remedy = remedy;
316279
+ }
316280
+ };
316281
+ function findAddonRefusal(err) {
316282
+ const seen = /* @__PURE__ */ new Set();
316283
+ let current = err;
316284
+ while (current !== null && current !== void 0 && !seen.has(current)) {
316285
+ if (current instanceof AddonRefusedError) return current;
316286
+ seen.add(current);
316287
+ current = current instanceof Error ? current.cause : void 0;
316288
+ }
316289
+ return null;
316290
+ }
316781
316291
  function createScopedProcessManager(broker, addonId) {
316782
316292
  return {
316783
316293
  async spawn(config) {
@@ -317866,7 +317376,6 @@ var require_dist3 = __commonJS({
317866
317376
  exports.CAP_METHOD_NOT_IMPLEMENTED = CAP_METHOD_NOT_IMPLEMENTED;
317867
317377
  exports.CA_COMMON_NAME = require_agent_https.CA_COMMON_NAME;
317868
317378
  exports.CA_VALIDITY_DAYS = require_agent_https.CA_VALIDITY_DAYS;
317869
- exports.CLUSTER_NODE_HISTORY_COLLECTION = CLUSTER_NODE_HISTORY_COLLECTION;
317870
317379
  exports.CORE_CAP_SERVICE_NAME = CORE_CAP_SERVICE_NAME;
317871
317380
  exports.CalendarsAddon = require_builtins_calendars_calendars_addon.CalendarsAddon;
317872
317381
  exports.CapRouteError = CapRouteError;
@@ -318042,14 +317551,11 @@ var require_dist3 = __commonJS({
318042
317551
  exports.ToastService = ToastService;
318043
317552
  exports.UDS_NO_ROUTE_PREFIX = UDS_NO_ROUTE_PREFIX;
318044
317553
  exports.UNCLAIMED = UNCLAIMED;
318045
- exports.UNMIGRATED_SETTINGS_CODE = UNMIGRATED_SETTINGS_CODE;
318046
- exports.UNMIGRATED_SETTINGS_REMEDY = UNMIGRATED_SETTINGS_REMEDY;
318047
317554
  exports.UPLOADED_CA_FILE = require_hub_mdns_ciao.UPLOADED_CA_FILE;
318048
317555
  exports.USER_MANAGEMENT_INTERNAL = require_builtins_local_auth_local_auth_addon.USER_MANAGEMENT_INTERNAL;
318049
317556
  exports.UdsLocalTransportClient = UdsLocalTransportClient;
318050
317557
  exports.UdsLocalTransportServer = UdsLocalTransportServer;
318051
317558
  exports.UnlockTicketJtiStore = require_builtins_system_config_system_config_addon.UnlockTicketJtiStore;
318052
- exports.UnmigratedSettingsError = UnmigratedSettingsError;
318053
317559
  exports.UserManager = require_builtins_local_auth_local_auth_addon.UserManager;
318054
317560
  exports.WinstonDestination = require_builtins_winston_logging_index.WinstonDestination$1;
318055
317561
  exports.WinstonLoggingAddon = require_builtins_winston_logging_index.WinstonLoggingAddon$1;
@@ -318067,7 +317573,6 @@ var require_dist3 = __commonJS({
318067
317573
  exports.applyCertificateToListener = require_hub_mdns_ciao.applyCertificateToListener;
318068
317574
  exports.applyLanHttp = require_hub_mdns_ciao.applyLanHttp;
318069
317575
  exports.asBrokerLike = asBrokerLike;
318070
- exports.assertLegacyBlobsMigrated = assertLegacyBlobsMigrated;
318071
317576
  exports.attachUserManagementInternal = require_builtins_local_auth_local_auth_addon.attachUserManagementInternal;
318072
317577
  exports.attributeStall = require_custom_action_registry.attributeStall;
318073
317578
  exports.backupOrchestratorRecordKinds = require_restore_archive.backupOrchestratorRecordKinds;
@@ -329229,19 +328734,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
329229
328734
  /** The whole declaration, secret paths and entry descriptor included (the entries service builds its handle from it). */
329230
328735
  declaration: require_sleep.RecordKindDeclarationSchema
329231
328736
  });
329232
- var STORAGE_ADMIN_MOVED_COLLECTIONS = [
329233
- "stream-broker:probe-snapshots",
329234
- "stream-broker:profile-map",
329235
- "stream-broker:rtsp-tokens",
329236
- "notification-center:device-mutes",
329237
- "recorder:recording-configs",
329238
- "pipeline-orchestrator:device-features"
329239
- ];
329240
- var STORAGE_ADMIN_SCOPED_BASES = [
329241
- "addon-settings",
329242
- "addon-devices",
329243
- "sections"
329244
- ];
329245
328737
  var storageAdminCapability = {
329246
328738
  name: "storage-admin",
329247
328739
  scope: "system",
@@ -329253,26 +328745,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
329253
328745
  * optionally only those owned by `ownerPrefix`. Reads only.
329254
328746
  */
329255
328747
  listTables: require_sleep.method(zod.z.object({ ownerPrefix: zod.z.string().min(1).optional() }), zod.z.object({ tables: zod.z.array(StorageTableSchema) }), { auth: "admin" }),
329256
- /**
329257
- * Drop one table. REFUSES when an addon declared it since the engine
329258
- * started (a running addon still owns it), when it is an engine or
329259
- * canonical table, when it does not exist, or when its row count is not
329260
- * `expectRows` - the caller states what it believes it is deleting. The
329261
- * engine also refuses anything but `<owner>:(addon-settings|addon-devices|
329262
- * sections)`, the retired collections by name, and tables of owners that
329263
- * are not installed (and refuses when it cannot read the installed list).
329264
- * Removed with the D870 migration script once the last hub ran it.
329265
- */
329266
- dropCollection: require_sleep.method(zod.z.object({
329267
- collection: zod.z.string().min(1),
329268
- expectRows: zod.z.number().int().nonnegative()
329269
- }), zod.z.object({
329270
- dropped: zod.z.literal(true),
329271
- rows: zod.z.number().int().nonnegative()
329272
- }), {
329273
- kind: "mutation",
329274
- auth: "admin"
329275
- }),
329276
328748
  /** Every record kind of both files with rows, a size estimate, class and retention (D881). */
329277
328749
  listKinds: require_sleep.method(zod.z.object({
329278
328750
  owner: zod.z.string().min(1).optional(),
@@ -356573,6 +356045,15 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
356573
356045
  * Replaces `zoneCrop`.
356574
356046
  */
356575
356047
  showTriggerZone: zod.z.boolean().optional(),
356048
+ /**
356049
+ * Draw the SUBJECT'S PATH on the picture — a line in the subject's colour
356050
+ * through the track's positions up to the frame shown, the same path the
356051
+ * debug views draw (`buildSubjectPath`, D903). Every picture mode a subject
356052
+ * is drawn on: a `crop` maps the path into the crop and clips it. Valid only
356053
+ * on a rule whose subject is a tracked object (refused on a sound rule);
356054
+ * dropped on `image: 'none'`. Absent = off.
356055
+ */
356056
+ showSubjectPath: zod.z.boolean().optional(),
356576
356057
  /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
356577
356058
  attach: zod.z.enum([
356578
356059
  "best",
@@ -390228,12 +389709,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
390228
389709
  addonId: null,
390229
389710
  access: "create"
390230
389711
  },
390231
- "storageAdmin.dropCollection": {
390232
- capName: "storage-admin",
390233
- capScope: "system",
390234
- addonId: null,
390235
- access: "delete"
390236
- },
390237
389712
  "storageAdmin.listKinds": {
390238
389713
  capName: "storage-admin",
390239
389714
  capScope: "system",
@@ -400576,15 +400051,22 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
400576
400051
  return clampToKind(legacyImageMode(media), kind);
400577
400052
  }
400578
400053
  function normalizeNcMediaPolicy(media, rule) {
400579
- const image = resolveNcMediaImage(media, ruleKindOf(rule));
400580
- const { attach: _attach, frame: _frame, zoneCrop, showTriggerZone, image: _image, ...rest } = media;
400054
+ const kind = ruleKindOf(rule);
400055
+ const image = resolveNcMediaImage(media, kind);
400056
+ const { attach: _attach, frame: _frame, zoneCrop, showTriggerZone, showSubjectPath, image: _image, ...rest } = media;
400581
400057
  const drawable = (showTriggerZone === true || media.image === void 0 && zoneCrop === true) && image !== "crop" && image !== "none" && ruleTriggerZoneIds(rule.conditions).length > 0;
400058
+ const pathDrawable = showSubjectPath === true && image !== "none" && subjectHasPath(kind);
400582
400059
  return {
400583
400060
  ...rest,
400584
400061
  image,
400585
- ...drawable ? { showTriggerZone: true } : {}
400062
+ ...drawable ? { showTriggerZone: true } : {},
400063
+ ...pathDrawable ? { showSubjectPath: true } : {}
400586
400064
  };
400587
400065
  }
400066
+ function subjectHasPath(kind) {
400067
+ const spec = ruleKindSpec(kind);
400068
+ return spec.carriesMedia && spec.carriesSubjectCrop;
400069
+ }
400588
400070
  function ncMediaPolicyError(media, rule) {
400589
400071
  const kind = ruleKindOf(rule);
400590
400072
  if (media.image !== void 0) {
@@ -400592,6 +400074,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
400592
400074
  if (offered.length > 0 && !offered.includes(media.image)) return `media.image '${media.image}' is not available for a ${kind} rule (offered: ${offered.join(", ")})`;
400593
400075
  }
400594
400076
  if (media.showTriggerZone === true && ruleTriggerZoneIds(rule.conditions).length === 0) return "media.showTriggerZone needs a rule triggered by a zone (a zones condition or an occupancy zone)";
400077
+ if (media.showSubjectPath === true && !subjectHasPath(kind)) return `media.showSubjectPath needs a rule whose subject is a tracked object (not a ${kind} rule)`;
400595
400078
  return null;
400596
400079
  }
400597
400080
  var WEEKDAY_TO_DAY = {
@@ -400649,17 +400132,181 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
400649
400132
  if (schedule === void 0) return true;
400650
400133
  const { day, minute } = localDayMinute(atMs, schedule.timezone);
400651
400134
  const prevDay = (day + 6) % 7;
400652
- let inside = false;
400135
+ let inside2 = false;
400653
400136
  for (const w of schedule.windows) if (w.startMinute <= w.endMinute) {
400654
400137
  if (w.days.includes(day) && minute >= w.startMinute && minute < w.endMinute) {
400655
- inside = true;
400138
+ inside2 = true;
400656
400139
  break;
400657
400140
  }
400658
400141
  } else if (w.days.includes(day) && minute >= w.startMinute || w.days.includes(prevDay) && minute < w.endMinute) {
400659
- inside = true;
400142
+ inside2 = true;
400660
400143
  break;
400661
400144
  }
400662
- return schedule.invert === true ? !inside : inside;
400145
+ return schedule.invert === true ? !inside2 : inside2;
400146
+ }
400147
+ var SUBJECT_PATH_FULL_FRAME_COVERAGE = 0.85;
400148
+ var SUBJECT_PATH_DWELL_EPS = 5e-3;
400149
+ var SUBJECT_PATH_MAX_POINTS = 120;
400150
+ var clamp01 = (n) => n < 0 ? 0 : n > 1 ? 1 : n;
400151
+ function subjectPathSampleFromBox(bbox, timestamp) {
400152
+ return {
400153
+ x: bbox.x + bbox.w / 2,
400154
+ y: bbox.y + bbox.h / 2,
400155
+ w: bbox.w,
400156
+ h: bbox.h,
400157
+ ...timestamp !== void 0 ? { timestamp } : {}
400158
+ };
400159
+ }
400160
+ function isPlaceholder(s) {
400161
+ return s.w !== void 0 && s.h !== void 0 && s.w >= 0.85 && s.h >= 0.85;
400162
+ }
400163
+ function downsample(xs, max) {
400164
+ if (xs.length <= max || max < 2) return xs;
400165
+ const step = (xs.length - 1) / (max - 1);
400166
+ const out = [];
400167
+ for (let i = 0; i < max - 1; i++) {
400168
+ const x = xs[Math.round(i * step)];
400169
+ if (x !== void 0) out.push(x);
400170
+ }
400171
+ const last = xs[xs.length - 1];
400172
+ if (last !== void 0) out.push(last);
400173
+ return out;
400174
+ }
400175
+ function isFiniteSample(s) {
400176
+ return Number.isFinite(s.x) && Number.isFinite(s.y);
400177
+ }
400178
+ function buildSubjectPath(samples, opts) {
400179
+ const until = opts?.untilTimestamp;
400180
+ const nodes = [];
400181
+ let unlocalized = 0;
400182
+ let tail = null;
400183
+ for (let index = 0; index < samples.length; index++) {
400184
+ const s = samples[index];
400185
+ if (s === void 0 || !isFiniteSample(s)) continue;
400186
+ if (until !== void 0 && s.timestamp !== void 0 && s.timestamp > until) continue;
400187
+ if (isPlaceholder(s)) {
400188
+ unlocalized += 1;
400189
+ continue;
400190
+ }
400191
+ const ts = s.timestamp !== void 0 && Number.isFinite(s.timestamp) ? s.timestamp : index;
400192
+ const x = clamp01(s.x);
400193
+ const y = clamp01(s.y);
400194
+ const prev = nodes[nodes.length - 1];
400195
+ if (prev !== void 0 && Math.hypot(x - prev.x, y - prev.y) < 5e-3) {
400196
+ nodes[nodes.length - 1] = {
400197
+ ...prev,
400198
+ samples: prev.samples + 1,
400199
+ lastTs: Math.max(prev.lastTs, ts)
400200
+ };
400201
+ tail = {
400202
+ x,
400203
+ y,
400204
+ samples: 1,
400205
+ firstTs: ts,
400206
+ lastTs: ts
400207
+ };
400208
+ continue;
400209
+ }
400210
+ tail = null;
400211
+ nodes.push({
400212
+ x,
400213
+ y,
400214
+ samples: 1,
400215
+ firstTs: ts,
400216
+ lastTs: ts
400217
+ });
400218
+ }
400219
+ const end = nodes[nodes.length - 1];
400220
+ if (tail !== null && end !== void 0 && end.samples > 1 && (tail.x !== end.x || tail.y !== end.y)) {
400221
+ nodes[nodes.length - 1] = {
400222
+ ...end,
400223
+ samples: end.samples - 1
400224
+ };
400225
+ nodes.push(tail);
400226
+ }
400227
+ return {
400228
+ nodes: downsample(nodes, opts?.maxPoints ?? 120),
400229
+ unlocalized
400230
+ };
400231
+ }
400232
+ function isDrawableSubjectPath(path) {
400233
+ return path.nodes.length >= 2;
400234
+ }
400235
+ function inside(p) {
400236
+ return p.x >= 0 && p.x <= 1 && p.y >= 0 && p.y <= 1;
400237
+ }
400238
+ function clipSegment(a, b) {
400239
+ const dx = b.x - a.x;
400240
+ const dy = b.y - a.y;
400241
+ let t0 = 0;
400242
+ let t1 = 1;
400243
+ const edges = [
400244
+ [-dx, a.x],
400245
+ [dx, 1 - a.x],
400246
+ [-dy, a.y],
400247
+ [dy, 1 - a.y]
400248
+ ];
400249
+ for (const [p, q] of edges) {
400250
+ if (p === 0) {
400251
+ if (q < 0) return null;
400252
+ continue;
400253
+ }
400254
+ const r = q / p;
400255
+ if (p < 0) {
400256
+ if (r > t1) return null;
400257
+ if (r > t0) t0 = r;
400258
+ } else {
400259
+ if (r < t0) return null;
400260
+ if (r < t1) t1 = r;
400261
+ }
400262
+ }
400263
+ return [{
400264
+ x: a.x + t0 * dx,
400265
+ y: a.y + t0 * dy
400266
+ }, {
400267
+ x: a.x + t1 * dx,
400268
+ y: a.y + t1 * dy
400269
+ }];
400270
+ }
400271
+ function samePoint(a, b) {
400272
+ return Math.abs(a.x - b.x) < 1e-9 && Math.abs(a.y - b.y) < 1e-9;
400273
+ }
400274
+ function projectSubjectPath(points, view) {
400275
+ if (points.length < 2 || !(view.w > 0) || !(view.h > 0)) return [];
400276
+ const local = points.map((p) => ({
400277
+ x: (p.x - view.x) / view.w,
400278
+ y: (p.y - view.y) / view.h
400279
+ }));
400280
+ const runs = [];
400281
+ let run = [];
400282
+ for (let i = 1; i < local.length; i++) {
400283
+ const a = local[i - 1];
400284
+ const b = local[i];
400285
+ if (a === void 0 || b === void 0) continue;
400286
+ const seg = clipSegment(a, b);
400287
+ if (seg === null) {
400288
+ if (run.length >= 2) runs.push(run);
400289
+ run = [];
400290
+ continue;
400291
+ }
400292
+ const [from2, to] = seg;
400293
+ const last = run[run.length - 1];
400294
+ if (last === void 0 || !samePoint(last, from2)) {
400295
+ if (run.length >= 2) runs.push(run);
400296
+ run = [from2];
400297
+ }
400298
+ run.push(to);
400299
+ if (!inside(b)) {
400300
+ if (run.length >= 2) runs.push(run);
400301
+ run = [];
400302
+ }
400303
+ }
400304
+ if (run.length >= 2) runs.push(run);
400305
+ return runs;
400306
+ }
400307
+ function subjectPathSvgPoints(run, width, height) {
400308
+ const fmt = (v) => String(Math.round(v * 100) / 100);
400309
+ return run.map((p) => `${fmt(p.x * width)},${fmt(p.y * height)}`).join(" ");
400663
400310
  }
400664
400311
  var ARMED_WORD_PREFIX = "armed_";
400665
400312
  var ALARM_PANEL_CAP = "alarm-panel";
@@ -406100,14 +405747,14 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
406100
405747
  }
406101
405748
  function pointInPolygon(point, polygon) {
406102
405749
  if (polygon.length < 3) return false;
406103
- let inside = false;
405750
+ let inside2 = false;
406104
405751
  const { x, y } = point;
406105
405752
  for (let i = 0, j2 = polygon.length - 1; i < polygon.length; j2 = i++) {
406106
405753
  const a = polygon[i];
406107
405754
  const b = polygon[j2];
406108
- if (a.y > y !== b.y > y && x < (b.x - a.x) * (y - a.y) / (b.y - a.y || Number.EPSILON) + a.x) inside = !inside;
405755
+ if (a.y > y !== b.y > y && x < (b.x - a.x) * (y - a.y) / (b.y - a.y || Number.EPSILON) + a.x) inside2 = !inside2;
406109
405756
  }
406110
- return inside;
405757
+ return inside2;
406111
405758
  }
406112
405759
  function bindAddonActions(api, addonId, catalog) {
406113
405760
  const out = {};
@@ -408040,12 +407687,13 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
408040
407687
  exports.STATE_LABEL_KEYS = STATE_LABEL_KEYS;
408041
407688
  exports.STATIONARY_OVERLAY_STYLE = STATIONARY_OVERLAY_STYLE;
408042
407689
  exports.STORAGE_ACCESS_FALLBACK = STORAGE_ACCESS_FALLBACK;
408043
- exports.STORAGE_ADMIN_MOVED_COLLECTIONS = STORAGE_ADMIN_MOVED_COLLECTIONS;
408044
- exports.STORAGE_ADMIN_SCOPED_BASES = STORAGE_ADMIN_SCOPED_BASES;
408045
407690
  exports.STORAGE_BYTES_PER_GB = STORAGE_BYTES_PER_GB;
408046
407691
  exports.STORAGE_LOCATION_MODES = STORAGE_LOCATION_MODES;
408047
407692
  exports.STREAM_PROFILE_META = STREAM_PROFILE_META;
408048
407693
  exports.STREAM_QUALITY_LABELS = STREAM_QUALITY_LABELS;
407694
+ exports.SUBJECT_PATH_DWELL_EPS = SUBJECT_PATH_DWELL_EPS;
407695
+ exports.SUBJECT_PATH_FULL_FRAME_COVERAGE = SUBJECT_PATH_FULL_FRAME_COVERAGE;
407696
+ exports.SUBJECT_PATH_MAX_POINTS = SUBJECT_PATH_MAX_POINTS;
408049
407697
  exports.SUB_DETECTION_TYPES = SUB_DETECTION_TYPES;
408050
407698
  exports.SYSTEM_CAP_NAMES = SYSTEM_CAP_NAMES;
408051
407699
  exports.SYSTEM_SCOPE_DEVICE_METHODS = SYSTEM_SCOPE_DEVICE_METHODS;
@@ -408437,6 +408085,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
408437
408085
  exports.buildRoleScopes = buildRoleScopes;
408438
408086
  exports.buildSecretRef = require_sleep.buildSecretRef;
408439
408087
  exports.buildStreamParamsConfigSchema = buildStreamParamsConfigSchema;
408088
+ exports.buildSubjectPath = buildSubjectPath;
408440
408089
  exports.buildVideoArgs = require_composition.buildVideoArgs;
408441
408090
  exports.buildViewerLink = buildViewerLink;
408442
408091
  exports.builtCapabilityBlockers = builtCapabilityBlockers;
@@ -408758,6 +408407,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
408758
408407
  exports.isDeviceScopedCap = require_sleep.isDeviceScopedCap;
408759
408408
  exports.isDoActionActuatable = isDoActionActuatable;
408760
408409
  exports.isDoPickerDeviceType = isDoPickerDeviceType;
408410
+ exports.isDrawableSubjectPath = isDrawableSubjectPath;
408761
408411
  exports.isEmbeddingModelFailed = isEmbeddingModelFailed;
408762
408412
  exports.isEvent = require_sleep.isEvent;
408763
408413
  exports.isEventKindLabelKey = isEventKindLabelKey;
@@ -408971,6 +408621,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
408971
408621
  exports.principalMayReachAddon = principalMayReachAddon;
408972
408622
  exports.privacyMaskCapability = privacyMaskCapability;
408973
408623
  exports.procedureAuthKey = procedureAuthKey;
408624
+ exports.projectSubjectPath = projectSubjectPath;
408974
408625
  exports.providerMotionEvent = providerMotionEvent;
408975
408626
  exports.ptzAutotrackCapability = ptzAutotrackCapability;
408976
408627
  exports.ptzCapability = ptzCapability;
@@ -409150,6 +408801,9 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
409150
408801
  exports.stripRetiredBandPreBufferSec = stripRetiredBandPreBufferSec;
409151
408802
  exports.strippedOfLegacyReadOnly = strippedOfLegacyReadOnly;
409152
408803
  exports.subKindsOf = subKindsOf;
408804
+ exports.subjectHasPath = subjectHasPath;
408805
+ exports.subjectPathSampleFromBox = subjectPathSampleFromBox;
408806
+ exports.subjectPathSvgPoints = subjectPathSvgPoints;
409153
408807
  exports.summarisePrivacyAudio = summarisePrivacyAudio;
409154
408808
  exports.summarizeEffectiveScope = summarizeEffectiveScope;
409155
408809
  exports.summarizeReview = summarizeReview;
@@ -590919,10 +590573,6 @@ var require_addon_registry_service = __commonJS({
590919
590573
  plannedRunnerIds() {
590920
590574
  return [...this.buildAddonGroupPlan([...this.addonEntries.keys()]).keys()];
590921
590575
  }
590922
- /** The forked addon ids (the ones whose Init the D870 guard gates). */
590923
- forkedAddonIds() {
590924
- return [...this.buildAddonGroupPlan([...this.addonEntries.keys()]).values()].flatMap((roster) => roster.map((r) => r.addonId));
590925
- }
590926
590576
  /**
590927
590577
  * Snapshot of the live runner subprocesses (`$process.list`), reduced to the
590928
590578
  * `{ runnerId, addonIds }` shape the convergence planner needs. Returns `[]`
@@ -595513,7 +595163,6 @@ var require_cluster_node_history_store = __commonJS({
595513
595163
  lastActive: zod_1.z.number(),
595514
595164
  descriptor: DescriptorSchema
595515
595165
  });
595516
- var COLLECTION = "cluster-node-history";
595517
595166
  var LAST_ACTIVE_HEARTBEAT_MS = 5 * 6e4;
595518
595167
  function descriptorsEqual(a, b) {
595519
595168
  return a.id === b.id && a.name === b.name && a.hostname === b.hostname && a.platform === b.platform && a.arch === b.arch && a.cpuModel === b.cpuModel && a.cpuCores === b.cpuCores && a.memoryMB === b.memoryMB && a.isHub === b.isHub && sameStrings(a.engines, b.engines) && sameStrings(a.localIps, b.localIps) && sameStrings(a.addonIds, b.addonIds) && samePackages(a.packages, b.packages);
@@ -595527,12 +595176,9 @@ var require_cluster_node_history_store = __commonJS({
595527
595176
  return a.length === b.length && a.every((p, i) => p.name === b[i]?.name && p.version === b[i]?.version);
595528
595177
  }
595529
595178
  var ClusterNodeHistoryStore = class _ClusterNodeHistoryStore {
595530
- resolveSettingsStore;
595531
595179
  logger;
595532
- declared = false;
595533
595180
  resolveKind;
595534
- constructor(resolveSettingsStore, logger, resolveKind = () => null) {
595535
- this.resolveSettingsStore = resolveSettingsStore;
595181
+ constructor(logger, resolveKind = () => null) {
595536
595182
  this.logger = logger;
595537
595183
  this.resolveKind = resolveKind;
595538
595184
  }
@@ -595540,37 +595186,6 @@ var require_cluster_node_history_store = __commonJS({
595540
595186
  bindRecordsKind(resolver) {
595541
595187
  this.resolveKind = resolver;
595542
595188
  }
595543
- /**
595544
- * Idempotently declare the typed collection. Returns the resolved provider
595545
- * or null if the settings-store isn't available yet (early boot / hub
595546
- * unreachable) — callers treat null as "skip, best-effort".
595547
- */
595548
- async ensureDeclared() {
595549
- if (this.resolveKind() !== null)
595550
- return this.resolveSettingsStore();
595551
- const store = this.resolveSettingsStore();
595552
- if (!store)
595553
- return null;
595554
- if (this.declared)
595555
- return store;
595556
- try {
595557
- await store.declareCollection({
595558
- collection: COLLECTION,
595559
- columns: [
595560
- { name: "id", type: "TEXT", primaryKey: true, notNull: true },
595561
- { name: "lastActive", type: "INTEGER", notNull: true },
595562
- { name: "descriptor", type: "JSON", notNull: true }
595563
- ]
595564
- });
595565
- this.declared = true;
595566
- return store;
595567
- } catch (err) {
595568
- this.logger.warn("declareCollection failed (best-effort)", {
595569
- meta: { error: (0, types_1.errMsg)(err) }
595570
- });
595571
- return null;
595572
- }
595573
- }
595574
595189
  /**
595575
595190
  * Upsert a node's descriptor + addon roster while it is ONLINE, stamping
595576
595191
  * `lastActive = Date.now()`. Called on each `listNodes()` refresh for every
@@ -595590,16 +595205,16 @@ var require_cluster_node_history_store = __commonJS({
595590
595205
  * `$node.disconnected`, and buys 288 writes/day/node instead of 2,880.
595591
595206
  */
595592
595207
  async snapshot(descriptor) {
595593
- const store = await this.ensureDeclared();
595594
- if (!store)
595208
+ const kind = this.resolveKind();
595209
+ if (kind === null)
595595
595210
  return;
595596
595211
  try {
595597
- const existing = await this.readStored(descriptor.id);
595212
+ const existing = await this.readStored(kind, descriptor.id);
595598
595213
  const packages = descriptor.packages ?? existing?.descriptor.packages;
595599
595214
  const next = packages === void 0 ? descriptor : { ...descriptor, packages };
595600
595215
  if (existing !== null && !this.worthWriting(existing, next))
595601
595216
  return;
595602
- await this.writeStored(descriptor.id, Date.now(), next);
595217
+ await this.writeStored(kind, descriptor.id, Date.now(), next);
595603
595218
  } catch (err) {
595604
595219
  this.logger.warn("snapshot upsert failed (best-effort)", {
595605
595220
  tags: { nodeId: descriptor.id },
@@ -595618,47 +595233,21 @@ var require_cluster_node_history_store = __commonJS({
595618
595233
  return !descriptorsEqual(existing.descriptor, next);
595619
595234
  }
595620
595235
  /** Read one node's row, validated. `null` when absent or malformed. */
595621
- async readStored(nodeId) {
595622
- const kind = this.resolveKind();
595623
- if (kind !== null) {
595624
- const row = await kind.get(nodeId);
595625
- if (row === null)
595626
- return null;
595627
- const parsed = RowDataSchema.safeParse({
595628
- lastActive: row.at ?? 0,
595629
- descriptor: row.data.descriptor
595630
- });
595631
- return parsed.success ? parsed.data : null;
595632
- }
595633
- const store = this.resolveSettingsStore();
595634
- if (!store)
595635
- return null;
595636
- return this.readRowLegacy(store, nodeId);
595637
- }
595638
- async readRowLegacy(store, nodeId) {
595639
- const raw = await store.get({ collection: COLLECTION, key: nodeId });
595640
- if (raw === null || raw === void 0)
595236
+ async readStored(kind, nodeId) {
595237
+ const row = await kind.get(nodeId);
595238
+ if (row === null)
595641
595239
  return null;
595642
- const parsed = RowDataSchema.safeParse(raw);
595240
+ const parsed = RowDataSchema.safeParse({
595241
+ lastActive: row.at ?? 0,
595242
+ descriptor: row.data.descriptor
595243
+ });
595643
595244
  return parsed.success ? parsed.data : null;
595644
595245
  }
595645
- async writeStored(nodeId, lastActive, descriptor) {
595646
- const kind = this.resolveKind();
595647
- if (kind !== null) {
595648
- const body = system_1.ClusterNodeHistoryBodySchema.safeParse({ descriptor });
595649
- if (!body.success)
595650
- return;
595651
- await kind.put({ id: nodeId, at: lastActive, data: body.data });
595652
- return;
595653
- }
595654
- const store = this.resolveSettingsStore();
595655
- if (!store)
595246
+ async writeStored(kind, nodeId, lastActive, descriptor) {
595247
+ const body = system_1.ClusterNodeHistoryBodySchema.safeParse({ descriptor });
595248
+ if (!body.success)
595656
595249
  return;
595657
- await store.set({
595658
- collection: COLLECTION,
595659
- key: nodeId,
595660
- value: { lastActive, descriptor }
595661
- });
595250
+ await kind.put({ id: nodeId, at: lastActive, data: body.data });
595662
595251
  }
595663
595252
  /** A placeholder descriptor for a node the topology pass has not seen yet. */
595664
595253
  static placeholderDescriptor(nodeId) {
@@ -595683,11 +595272,11 @@ var require_cluster_node_history_store = __commonJS({
595683
595272
  * nothing is delivered rather than something guessed.
595684
595273
  */
595685
595274
  async getPackages(nodeId) {
595686
- const store = await this.ensureDeclared();
595687
- if (!store)
595275
+ const kind = this.resolveKind();
595276
+ if (kind === null)
595688
595277
  return [];
595689
595278
  try {
595690
- return (await this.readStored(nodeId))?.descriptor.packages ?? [];
595279
+ return (await this.readStored(kind, nodeId))?.descriptor.packages ?? [];
595691
595280
  } catch (err) {
595692
595281
  this.logger.warn("getPackages failed (best-effort)", {
595693
595282
  tags: { nodeId },
@@ -595707,11 +595296,11 @@ var require_cluster_node_history_store = __commonJS({
595707
595296
  async recordPackages(nodeId, packages) {
595708
595297
  if (packages.length === 0)
595709
595298
  return;
595710
- const store = await this.ensureDeclared();
595711
- if (!store)
595299
+ const kind = this.resolveKind();
595300
+ if (kind === null)
595712
595301
  return;
595713
595302
  try {
595714
- const existing = await this.readStored(nodeId);
595303
+ const existing = await this.readStored(kind, nodeId);
595715
595304
  const merged = new Map((existing?.descriptor.packages ?? []).map((p) => [p.name, p]));
595716
595305
  for (const entry of packages)
595717
595306
  merged.set(entry.name, entry);
@@ -595719,7 +595308,7 @@ var require_cluster_node_history_store = __commonJS({
595719
595308
  ...existing?.descriptor ?? _ClusterNodeHistoryStore.placeholderDescriptor(nodeId),
595720
595309
  packages: [...merged.values()]
595721
595310
  };
595722
- await this.writeStored(nodeId, existing?.lastActive ?? Date.now(), descriptor);
595311
+ await this.writeStored(kind, nodeId, existing?.lastActive ?? Date.now(), descriptor);
595723
595312
  } catch (err) {
595724
595313
  this.logger.warn("recordPackages failed (best-effort)", {
595725
595314
  tags: { nodeId },
@@ -595735,11 +595324,11 @@ var require_cluster_node_history_store = __commonJS({
595735
595324
  async prunePackages(nodeId, names) {
595736
595325
  if (names.length === 0)
595737
595326
  return;
595738
- const store = await this.ensureDeclared();
595739
- if (!store)
595327
+ const kind = this.resolveKind();
595328
+ if (kind === null)
595740
595329
  return;
595741
595330
  try {
595742
- const existing = await this.readStored(nodeId);
595331
+ const existing = await this.readStored(kind, nodeId);
595743
595332
  if (existing === null)
595744
595333
  return;
595745
595334
  const current = existing.descriptor.packages;
@@ -595749,7 +595338,7 @@ var require_cluster_node_history_store = __commonJS({
595749
595338
  const remaining = current.filter((p) => !drop.has(p.name));
595750
595339
  if (remaining.length === current.length)
595751
595340
  return;
595752
- await this.writeStored(nodeId, existing.lastActive, {
595341
+ await this.writeStored(kind, nodeId, existing.lastActive, {
595753
595342
  ...existing.descriptor,
595754
595343
  packages: remaining
595755
595344
  });
@@ -595770,27 +595359,14 @@ var require_cluster_node_history_store = __commonJS({
595770
595359
  * time. A no-op if the node was never snapshotted (nothing to update).
595771
595360
  */
595772
595361
  async touch(nodeId) {
595773
- const store = await this.ensureDeclared();
595774
- if (!store)
595362
+ const kind = this.resolveKind();
595363
+ if (kind === null)
595775
595364
  return;
595776
595365
  try {
595777
- const existing = await this.readStored(nodeId);
595366
+ const existing = await this.readStored(kind, nodeId);
595778
595367
  if (existing === null)
595779
595368
  return;
595780
- const kind = this.resolveKind();
595781
- if (kind !== null) {
595782
- await kind.put({
595783
- id: nodeId,
595784
- at: Date.now(),
595785
- data: { descriptor: existing.descriptor }
595786
- });
595787
- return;
595788
- }
595789
- await store.update({
595790
- collection: COLLECTION,
595791
- id: nodeId,
595792
- data: { lastActive: Date.now() }
595793
- });
595369
+ await this.writeStored(kind, nodeId, Date.now(), existing.descriptor);
595794
595370
  } catch (err) {
595795
595371
  this.logger.warn("touch failed (best-effort)", {
595796
595372
  tags: { nodeId },
@@ -595804,24 +595380,20 @@ var require_cluster_node_history_store = __commonJS({
595804
595380
  }
595805
595381
  /**
595806
595382
  * Read the full persisted history, validated, or `null` when the store did
595807
- * not ANSWER (unavailable, or the query threw). A caller that must not claim
595383
+ * not ANSWER (the kind is not bound yet, or the read threw). A caller that must not claim
595808
595384
  * a node absent from an unanswered read (D315) uses this; `getAll` folds the
595809
595385
  * `null` into `[]` for the callers that only render what exists. Malformed
595810
595386
  * rows are dropped (and logged) — the rest of the answer still stands.
595811
595387
  */
595812
595388
  async tryGetAll() {
595813
- const store = await this.ensureDeclared();
595814
- if (!store)
595389
+ const kind = this.resolveKind();
595390
+ if (kind === null)
595815
595391
  return null;
595816
595392
  try {
595817
- const kind = this.resolveKind();
595818
595393
  const result = [];
595819
- const rows = kind !== null ? (await (0, system_1.readAllRows)(kind)).map((row) => ({
595394
+ const rows = (await (0, system_1.readAllRows)(kind)).map((row) => ({
595820
595395
  id: row.id,
595821
595396
  data: { lastActive: row.at ?? 0, descriptor: row.data.descriptor }
595822
- })) : (await store.query({ collection: COLLECTION })).map((row) => ({
595823
- id: row.id,
595824
- data: row.data
595825
595397
  }));
595826
595398
  for (const row of rows) {
595827
595399
  const parsed = RowDataSchema.safeParse(row.data);
@@ -595848,17 +595420,12 @@ var require_cluster_node_history_store = __commonJS({
595848
595420
  * 2026-09-01 all three reached the UI as `{"success": true}`.
595849
595421
  */
595850
595422
  async forget(nodeId) {
595851
- const store = await this.ensureDeclared();
595852
- if (!store)
595423
+ const kind = this.resolveKind();
595424
+ if (kind === null)
595853
595425
  return "store-unavailable";
595854
595426
  try {
595855
- const existed = await this.readStored(nodeId) !== null;
595856
- const kind = this.resolveKind();
595857
- if (kind !== null) {
595858
- await kind.delete(nodeId);
595859
- } else {
595860
- await store.delete({ collection: COLLECTION, key: nodeId });
595861
- }
595427
+ const existed = await this.readStored(kind, nodeId) !== null;
595428
+ await kind.delete(nodeId);
595862
595429
  if (!existed) {
595863
595430
  this.logger.info("cluster node had no history row to forget", { tags: { nodeId } });
595864
595431
  return "not-found";
@@ -595995,52 +595562,6 @@ var require_toast_wrapper_service = __commonJS({
595995
595562
  }
595996
595563
  });
595997
595564
 
595998
- // ../../server/backend/dist/core/runner-health/update-preflight.js
595999
- var require_update_preflight = __commonJS({
596000
- "../../server/backend/dist/core/runner-health/update-preflight.js"(exports) {
596001
- "use strict";
596002
- Object.defineProperty(exports, "__esModule", { value: true });
596003
- exports.LEGACY_BLOB_GUARD_SINCE = void 0;
596004
- exports.buildUpdatePreflight = buildUpdatePreflight;
596005
- exports.legacyGuardClientOf = legacyGuardClientOf;
596006
- var system_1 = require_dist3();
596007
- var index_js_1 = require_server_root();
596008
- exports.LEGACY_BLOB_GUARD_SINCE = "1.2.585";
596009
- function buildUpdatePreflight(deps) {
596010
- return async (targetVersion) => {
596011
- if ((0, index_js_1.compareSemver)(targetVersion, exports.LEGACY_BLOB_GUARD_SINCE) < 0)
596012
- return [];
596013
- const store = deps.store();
596014
- if (store === null) {
596015
- throw new Error("the settings store is not available to pre-check the update");
596016
- }
596017
- const blockers = [];
596018
- for (const addonId of deps.forkedAddonIds()) {
596019
- try {
596020
- await (0, system_1.assertLegacyBlobsMigrated)(store, addonId, deps.logger);
596021
- } catch (err) {
596022
- if (!(err instanceof system_1.UnmigratedSettingsError))
596023
- throw err;
596024
- blockers.push({
596025
- addonId,
596026
- reason: err.message,
596027
- remedy: system_1.UNMIGRATED_SETTINGS_REMEDY
596028
- });
596029
- }
596030
- }
596031
- return blockers;
596032
- };
596033
- }
596034
- function legacyGuardClientOf(store) {
596035
- return {
596036
- query: { query: (input) => store.query(input) },
596037
- get: { query: (input) => store.get(input) },
596038
- count: { query: (input) => store.count(input) }
596039
- };
596040
- }
596041
- }
596042
- });
596043
-
596044
595565
  // ../../server/backend/dist/core/topology/topology-emitter.service.js
596045
595566
  var require_topology_emitter_service = __commonJS({
596046
595567
  "../../server/backend/dist/core/topology/topology-emitter.service.js"(exports) {
@@ -596270,7 +595791,6 @@ var require_manual_boot = __commonJS({
596270
595791
  var repl_engine_service_1 = require_repl_engine_service();
596271
595792
  var server_update_service_1 = require_server_update_service();
596272
595793
  var runner_boot_check_1 = require_runner_boot_check();
596273
- var update_preflight_1 = require_update_preflight();
596274
595794
  var storage_service_1 = require_storage_service();
596275
595795
  var stream_probe_service_1 = require_stream_probe_service();
596276
595796
  var topology_emitter_service_1 = require_topology_emitter_service();
@@ -596324,7 +595844,7 @@ var require_manual_boot = __commonJS({
596324
595844
  const addonRegistryService = new addon_registry_service_1.AddonRegistryService(loggingService, eventBusService, configService, storageService, capabilityService, moleculerService, streamProbeService);
596325
595845
  agentRegistryService.setAddonRegistry(addonRegistryService);
596326
595846
  agentRegistryService.setLogger(loggingService.createLogger("ClusterNodes"));
596327
- const clusterNodeHistoryStore = new cluster_node_history_store_1.ClusterNodeHistoryStore(() => capabilityService.getRegistry()?.getSingleton("settings-store") ?? null, loggingService.createLogger("cluster-node-history"));
595847
+ const clusterNodeHistoryStore = new cluster_node_history_store_1.ClusterNodeHistoryStore(loggingService.createLogger("cluster-node-history"));
596328
595848
  agentRegistryService.setClusterNodeHistoryStore(clusterNodeHistoryStore);
596329
595849
  addonRegistryService.setClusterNodeHistoryStore(clusterNodeHistoryStore);
596330
595850
  const addonWidgetsService = new addon_widgets_service_1.AddonWidgetsService(loggingService, capabilityService, addonRegistryService);
@@ -596410,16 +595930,7 @@ var require_manual_boot = __commonJS({
596410
595930
  });
596411
595931
  }
596412
595932
  });
596413
- const settingsStoreOrNull = () => capabilityService.getRegistry()?.getSingleton("settings-store") ?? null;
596414
595933
  const serverUpdateService = new server_update_service_1.ServerUpdateService({
596415
- updatePreflight: (0, update_preflight_1.buildUpdatePreflight)({
596416
- logger: loggingService.createLogger("UpdatePreflight"),
596417
- forkedAddonIds: () => addonRegistryService.forkedAddonIds(),
596418
- store: () => {
596419
- const store = settingsStoreOrNull();
596420
- return store === null ? null : (0, update_preflight_1.legacyGuardClientOf)(store);
596421
- }
596422
- }),
596423
595934
  runnerBootCheck: () => hubRunnerBootCheck.current(),
596424
595935
  logger: loggingService.createLogger("ServerUpdate"),
596425
595936
  restartServer: (requestedBy, update) => addonPackageService.restartServer(requestedBy, update),