camstack 1.2.84 → 1.2.86

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.
@@ -14522,7 +14522,7 @@ function date4(params) {
14522
14522
  // ../../node_modules/zod/v4/classic/external.js
14523
14523
  config(en_default());
14524
14524
 
14525
- // ../types/dist/sleep-Cwo3fRlv.mjs
14525
+ // ../types/dist/sleep-B195W080.mjs
14526
14526
  var WELL_KNOWN_TABS = [
14527
14527
  {
14528
14528
  id: "overview",
@@ -20364,7 +20364,26 @@ var DiscoveryCandidateSchema = external_exports.object({
20364
20364
  * identity ahead of adoption. Rendering metadata (unit, precision)
20365
20365
  * flows live through the cap STATUS SLICE after adoption.
20366
20366
  */
20367
- sourceInfo: SourceInfoSchema.optional()
20367
+ sourceInfo: SourceInfoSchema.optional(),
20368
+ /**
20369
+ * Set when this candidate is a device the provider ALREADY owns.
20370
+ *
20371
+ * A scan cannot generally produce the identity a device was onboarded under
20372
+ * (Reolink keys on `mac-<mac>`, learned at adopt time), so a stableId
20373
+ * comparison never matches and an owned device looks addable. Re-adopting one
20374
+ * overwrites its config with scan-derived values — that is how a Home Hub's
20375
+ * Baichuan port was overwritten with its ONVIF port, taking the hub and its
20376
+ * three child cameras offline for four hours.
20377
+ *
20378
+ * A provider that can recognise its own devices says so here. Absent means
20379
+ * "not recognised", which is not the same as "known to be new" — a provider
20380
+ * that cannot tell simply never sets it.
20381
+ */
20382
+ alreadyOnboarded: external_exports.boolean().optional(),
20383
+ /** Numeric id of the device this candidate was matched to. Set with `alreadyOnboarded`. */
20384
+ onboardedDeviceId: external_exports.number().optional(),
20385
+ /** Operator-facing name of the matched device, so the UI can say WHICH one it is. */
20386
+ onboardedName: external_exports.string().optional()
20368
20387
  });
20369
20388
  var DeviceSummarySchema = external_exports.object({
20370
20389
  id: external_exports.number(),
@@ -20401,6 +20420,35 @@ var deviceProviderCapability = {
20401
20420
  name: external_exports.string(),
20402
20421
  type: external_exports.string()
20403
20422
  }))),
20423
+ /**
20424
+ * Tear down and reconstruct ONE device in place from its persisted rows —
20425
+ * touching no other device this provider owns.
20426
+ *
20427
+ * The primitive `deviceManager.migrateDevice` uses to flush the two
20428
+ * migrated numbers: after `swapIds` the runner's live instance still
20429
+ * carries the PRE-swap numeric id (baked into the object, its native-cap
20430
+ * registrations and its log tags), and a live object cannot be renumbered.
20431
+ * Before this method the only flush was restarting the whole owning addon
20432
+ * — which took every camera the provider owns down with it (28 devices
20433
+ * for one migrated camera, measured 2026-09-04, and the morning of the
20434
+ * same day ~27 devices' native caps did not come back on their own).
20435
+ *
20436
+ * Keyed by `stableId`, deliberately: the numeric id is exactly the thing
20437
+ * that changes. The reply carries the id the device answers on NOW.
20438
+ * Implemented once in `BaseDeviceProvider` — decommission the live
20439
+ * instance (if any), then re-create from the persisted row: the same
20440
+ * teardown/rehydrate pair every graceful shutdown + boot already uses.
20441
+ * An RPC, never an event: a dropped event would leave the runner writing
20442
+ * against the wrong camera (D8).
20443
+ *
20444
+ * Construction can dial hardware, and the migrated source is
20445
+ * characteristically dead — the timeout covers a full activate window
20446
+ * rather than the 60 s default.
20447
+ */
20448
+ reloadDevice: method(external_exports.object({ stableId: external_exports.string() }), external_exports.object({ deviceId: external_exports.number() }), {
20449
+ kind: "mutation",
20450
+ timeoutMs: 3 * 6e4
20451
+ }),
20404
20452
  supportsDiscovery: method(external_exports.object({}), external_exports.boolean()),
20405
20453
  /**
20406
20454
  * Run a network scan. `params` carries optional provider-specific scan
@@ -20721,13 +20769,21 @@ var deviceManagerCapability = {
20721
20769
  * `sourceStillLive` names what stayed live; empty is the only value that
20722
20770
  * means the old hardware is quiet. The migration proceeds either way —
20723
20771
  * refusing would refuse the case this exists for.
20772
+ *
20773
+ * **Safe to retry.** A duplicate call while a migration involving either
20774
+ * device is in flight is REFUSED, never queued; a repeat of a swap that
20775
+ * already completed (matched against the `addonId`/`stableId` fingerprint
20776
+ * the swap left on the rows, within 15 min) is a no-op returning the
20777
+ * original report. A blind re-run can no longer silently undo the
20778
+ * migration it retried.
20724
20779
  */
20725
20780
  migrateDevice: method(external_exports.object({
20726
20781
  sourceId: external_exports.number(),
20727
20782
  targetId: external_exports.number()
20728
20783
  }), MigrateDeviceResultSchema, {
20729
20784
  kind: "mutation",
20730
- auth: "admin"
20785
+ auth: "admin",
20786
+ timeoutMs: 12 * 6e4
20731
20787
  }),
20732
20788
  /** Register a device in the DB + in-memory registry. Called by DeviceManagerApi.register(). */
20733
20789
  registerDevice: method(DeviceRegisterPayloadSchema, external_exports.void(), { kind: "mutation" }),
@@ -41144,6 +41200,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
41144
41200
  addonId: null,
41145
41201
  access: "view"
41146
41202
  },
41203
+ "deviceProvider.reloadDevice": {
41204
+ capName: "device-provider",
41205
+ capScope: "system",
41206
+ addonId: null,
41207
+ access: "create"
41208
+ },
41147
41209
  "deviceProvider.start": {
41148
41210
  capName: "device-provider",
41149
41211
  capScope: "system",
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-O7PXXZZ7.js";
4
+ } from "./chunk-I6O2CHPR.js";
5
5
  import "./chunk-LMMQX4CK.js";
6
6
 
7
7
  // src/cli.ts
@@ -38,7 +38,7 @@ async function runServe(args) {
38
38
  ...typeof values.data === "string" ? { data: values.data } : {}
39
39
  };
40
40
  Object.assign(process.env, buildServeEnv(opts));
41
- await import("./launcher-EQ3SI35Z.js");
41
+ await import("./launcher-3OHBVI43.js");
42
42
  }
43
43
 
44
44
  // src/commands/agent.ts
@@ -83,7 +83,7 @@ async function runAgent(args) {
83
83
  ...typeof values.port === "string" ? { port: values.port } : {}
84
84
  };
85
85
  Object.assign(process.env, buildAgentEnv(opts));
86
- await import("./launcher-EQ3SI35Z.js");
86
+ await import("./launcher-3OHBVI43.js");
87
87
  }
88
88
 
89
89
  // src/commands/setup.ts
@@ -1130,7 +1130,7 @@ function isUnknown(_value) {
1130
1130
  return true;
1131
1131
  }
1132
1132
  async function resolveServerInteractive(presetNamespace) {
1133
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-E5HX2QAP.js");
1133
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-LZJPQBVA.js");
1134
1134
  if (presetNamespace) {
1135
1135
  const spinner4 = clack.spinner();
1136
1136
  spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-O7PXXZZ7.js";
8
+ } from "./chunk-I6O2CHPR.js";
9
9
  import "./chunk-LMMQX4CK.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,