@camstack/system 1.1.9 → 1.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon-runner.js +1 -1
- package/dist/addon-runner.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +110 -92
- package/dist/builtins/device-manager/device-manager.addon.mjs +110 -92
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{manifest-python-deps-BqId8WrC.mjs → manifest-python-deps-1zTy3vXe.mjs} +9 -1
- package/dist/{manifest-python-deps-Ba_eOEPT.js → manifest-python-deps-Cro19O4u.js} +9 -1
- package/package.json +1 -1
package/dist/addon-runner.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_manifest_python_deps = require("./manifest-python-deps-
|
|
2
|
+
const require_manifest_python_deps = require("./manifest-python-deps-Cro19O4u.js");
|
|
3
3
|
const require_custom_action_registry = require("./custom-action-registry-vLYEFTtv.js");
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
node_fs = require_chunk.__toESM(node_fs);
|
package/dist/addon-runner.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as setWorkerNativeCapsChangeListener, A as createUdsLoggerWithControl, X as getWorkerNativeCapProvider, Z as getWorkerNativeCapSnapshot, i as createUdsAddonContext, j as LocalChildClient, mt as resolveAddonClass, pt as installManifestNativeDeps, t as installManifestPythonDeps, tt as validateProviderRegistrations } from "./manifest-python-deps-
|
|
1
|
+
import { $ as setWorkerNativeCapsChangeListener, A as createUdsLoggerWithControl, X as getWorkerNativeCapProvider, Z as getWorkerNativeCapSnapshot, i as createUdsAddonContext, j as LocalChildClient, mt as resolveAddonClass, pt as installManifestNativeDeps, t as installManifestPythonDeps, tt as validateProviderRegistrations } from "./manifest-python-deps-1zTy3vXe.mjs";
|
|
2
2
|
import { t as CustomActionRegistry } from "./custom-action-registry-BEXwC-oo.mjs";
|
|
3
3
|
import { register } from "node:module";
|
|
4
4
|
import * as fs from "node:fs";
|
|
@@ -239,7 +239,8 @@ function buildLinkIndexes(entries) {
|
|
|
239
239
|
*
|
|
240
240
|
* Addon store layout:
|
|
241
241
|
* deviceIndex → Record<addonId, stableId[]> (which devices exist per addon)
|
|
242
|
-
* deviceMeta → Record<
|
|
242
|
+
* deviceMeta → Record<numericId, DeviceMeta> (keyed by numeric device id;
|
|
243
|
+
* addonId + stableId are FIELDS on the record)
|
|
243
244
|
*
|
|
244
245
|
* Device store (per-device config):
|
|
245
246
|
* readDeviceStore(numericDeviceId) → config blob
|
|
@@ -282,9 +283,6 @@ function shallowEqual(a, b) {
|
|
|
282
283
|
for (const k of ak) if (a[k] !== b[k]) return false;
|
|
283
284
|
return true;
|
|
284
285
|
}
|
|
285
|
-
function deviceKey(addonId, stableId) {
|
|
286
|
-
return `${addonId}:${stableId}`;
|
|
287
|
-
}
|
|
288
286
|
/** Returns true when `x` is a non-null, non-array plain object. */
|
|
289
287
|
function isRecord(x) {
|
|
290
288
|
return x !== null && typeof x === "object" && !Array.isArray(x);
|
|
@@ -777,12 +775,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
777
775
|
* numeric deviceId; this helper is display-only.
|
|
778
776
|
*/
|
|
779
777
|
async lookupPersistedStableId(deviceId) {
|
|
780
|
-
|
|
781
|
-
for (const [key, m] of Object.entries(meta)) if (m.id === deviceId) {
|
|
782
|
-
const sep = key.indexOf(":");
|
|
783
|
-
if (sep < 0) continue;
|
|
784
|
-
return key.slice(sep + 1);
|
|
785
|
-
}
|
|
778
|
+
return ((await this.ctx.settings.readAddonStore()).deviceMeta ?? {})[String(deviceId)]?.stableId;
|
|
786
779
|
}
|
|
787
780
|
async getDeviceAggregate(deviceId, kind) {
|
|
788
781
|
const registry = this.capabilityRegistry;
|
|
@@ -1474,28 +1467,32 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1474
1467
|
* Returns null when no device with that id is known to the hub.
|
|
1475
1468
|
*/
|
|
1476
1469
|
const resolvePersistedById = async (deviceId) => {
|
|
1470
|
+
const m = (await readMeta())[String(deviceId)];
|
|
1471
|
+
if (!m) return null;
|
|
1472
|
+
return {
|
|
1473
|
+
addonId: m.addonId,
|
|
1474
|
+
stableId: m.stableId,
|
|
1475
|
+
meta: m
|
|
1476
|
+
};
|
|
1477
|
+
};
|
|
1478
|
+
/** Direct children of a device: the union of the live registry's children
|
|
1479
|
+
* and the persisted-meta scan (`parentDeviceId === parentId`), deduplicated
|
|
1480
|
+
* and excluding self. Shared by the `remove` cascade and the `resetToSource`
|
|
1481
|
+
* resync purge (#19). */
|
|
1482
|
+
const directChildIds = async (parentId) => {
|
|
1483
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1484
|
+
if (registry) for (const c of registry.getChildren(parentId)) ids.add(c.id);
|
|
1477
1485
|
const meta = await readMeta();
|
|
1478
|
-
for (const
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
return {
|
|
1482
|
-
addonId: key.slice(0, sep),
|
|
1483
|
-
stableId: key.slice(sep + 1),
|
|
1484
|
-
meta: m
|
|
1485
|
-
};
|
|
1486
|
-
}
|
|
1487
|
-
return null;
|
|
1486
|
+
for (const m of Object.values(meta)) if (m.parentDeviceId === parentId) ids.add(m.id);
|
|
1487
|
+
ids.delete(parentId);
|
|
1488
|
+
return [...ids];
|
|
1488
1489
|
};
|
|
1489
1490
|
/** Resolve a link's `sourceKey` to a live device id: the sibling accessory
|
|
1490
1491
|
* whose stableId is `${parentStableId}-${sourceKey}`. Null when absent.
|
|
1491
1492
|
* Pure over a pre-read meta map so a multi-link resolve reads the store once. */
|
|
1492
1493
|
const resolveSourceDeviceId = (parentStableId, sourceKey, meta) => {
|
|
1493
1494
|
const wanted = `${parentStableId}-${sourceKey}`;
|
|
1494
|
-
for (const
|
|
1495
|
-
const sep = key.indexOf(":");
|
|
1496
|
-
if (sep < 0) continue;
|
|
1497
|
-
if (key.slice(sep + 1) === wanted) return m.id;
|
|
1498
|
-
}
|
|
1495
|
+
for (const m of Object.values(meta)) if (m.stableId === wanted) return m.id;
|
|
1499
1496
|
return null;
|
|
1500
1497
|
};
|
|
1501
1498
|
/** Rebuild the `linkTargets` / `linkDependents` reverse-index maps from the
|
|
@@ -1513,12 +1510,9 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1513
1510
|
const allMeta = await readMeta();
|
|
1514
1511
|
const stableIdById = /* @__PURE__ */ new Map();
|
|
1515
1512
|
const idByStableId = /* @__PURE__ */ new Map();
|
|
1516
|
-
for (const
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
const sid = key.slice(sep + 1);
|
|
1520
|
-
stableIdById.set(m.id, sid);
|
|
1521
|
-
idByStableId.set(sid, m.id);
|
|
1513
|
+
for (const m of Object.values(allMeta)) {
|
|
1514
|
+
stableIdById.set(m.id, m.stableId);
|
|
1515
|
+
idByStableId.set(m.stableId, m.id);
|
|
1522
1516
|
}
|
|
1523
1517
|
const entries = [];
|
|
1524
1518
|
const expectedSources = /* @__PURE__ */ new Set();
|
|
@@ -1546,10 +1540,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1546
1540
|
const idToAddonId = /* @__PURE__ */ new Map();
|
|
1547
1541
|
{
|
|
1548
1542
|
const meta = await readMeta();
|
|
1549
|
-
for (const
|
|
1550
|
-
|
|
1551
|
-
if (sep < 0) continue;
|
|
1552
|
-
idToAddonId.set(m.id, key.slice(0, sep));
|
|
1543
|
+
for (const m of Object.values(meta)) {
|
|
1544
|
+
idToAddonId.set(m.id, m.addonId);
|
|
1553
1545
|
if (Array.isArray(m.deviceLinks) && m.deviceLinks.length > 0) this.devicesWithLinks.add(m.id);
|
|
1554
1546
|
}
|
|
1555
1547
|
}
|
|
@@ -1563,8 +1555,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1563
1555
|
await withMetaWriteLock(async () => {
|
|
1564
1556
|
const persisted = await resolvePersistedById(deviceId);
|
|
1565
1557
|
if (!persisted) throw new Error(`[device-manager] stampIntegrationId: unknown device id=${deviceId}`);
|
|
1566
|
-
const {
|
|
1567
|
-
const key =
|
|
1558
|
+
const { meta: m } = persisted;
|
|
1559
|
+
const key = String(deviceId);
|
|
1568
1560
|
const allMeta = await readMeta();
|
|
1569
1561
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1570
1562
|
...allMeta,
|
|
@@ -1645,10 +1637,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1645
1637
|
let containerStableId = persisted.stableId;
|
|
1646
1638
|
const parentId = persisted.meta.parentDeviceId;
|
|
1647
1639
|
if (parentId !== null) {
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
break;
|
|
1651
|
-
}
|
|
1640
|
+
const parentMeta = allMeta[String(parentId)];
|
|
1641
|
+
if (parentMeta) containerStableId = parentMeta.stableId;
|
|
1652
1642
|
}
|
|
1653
1643
|
const resolved = [];
|
|
1654
1644
|
for (const link of links) {
|
|
@@ -1688,15 +1678,16 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1688
1678
|
* `registerDevice` completes. */
|
|
1689
1679
|
allocateDeviceId: async (input) => {
|
|
1690
1680
|
const { addonId, stableId } = input;
|
|
1691
|
-
const key = deviceKey(addonId, stableId);
|
|
1692
1681
|
return await withMetaWriteLock(async () => {
|
|
1693
1682
|
const meta = await readMeta();
|
|
1694
|
-
const existing = meta
|
|
1683
|
+
const existing = Object.values(meta).find((m) => m.addonId === addonId && m.stableId === stableId);
|
|
1695
1684
|
if (existing) return { id: existing.id };
|
|
1696
1685
|
const id = await allocateNextDeviceId();
|
|
1697
1686
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1698
1687
|
...meta,
|
|
1699
|
-
[
|
|
1688
|
+
[String(id)]: {
|
|
1689
|
+
addonId,
|
|
1690
|
+
stableId,
|
|
1700
1691
|
type: "generic",
|
|
1701
1692
|
name: stableId,
|
|
1702
1693
|
location: null,
|
|
@@ -1710,7 +1701,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1710
1701
|
},
|
|
1711
1702
|
registerDevice: async (input) => {
|
|
1712
1703
|
const { addonId, stableId, id, type, name, parentDeviceId, features, config } = input;
|
|
1713
|
-
const key =
|
|
1704
|
+
const key = String(id);
|
|
1714
1705
|
const featuresArr = Array.isArray(features) ? [...features] : [];
|
|
1715
1706
|
const { isFirstRegistration, exportFingerprint, fingerprintChanged } = await withMetaWriteLock(async () => {
|
|
1716
1707
|
const index = await readIndex();
|
|
@@ -1722,6 +1713,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1722
1713
|
} });
|
|
1723
1714
|
const meta = await readMeta();
|
|
1724
1715
|
const existingMeta = meta[key];
|
|
1716
|
+
const wasUserNamed = existingMeta?.userNamed ?? (existingMeta !== void 0 && existingMeta.name !== stableId);
|
|
1717
|
+
const resolvedName = wasUserNamed && existingMeta !== void 0 ? existingMeta.name : name;
|
|
1725
1718
|
const isFirst = !existingMeta || !wasInIndex;
|
|
1726
1719
|
const fingerprint = (0, _camstack_types_node.canonicalDeviceFingerprint)({
|
|
1727
1720
|
deviceId: id,
|
|
@@ -1731,8 +1724,11 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1731
1724
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1732
1725
|
...meta,
|
|
1733
1726
|
[key]: {
|
|
1727
|
+
addonId,
|
|
1728
|
+
stableId,
|
|
1734
1729
|
type,
|
|
1735
|
-
name:
|
|
1730
|
+
name: resolvedName,
|
|
1731
|
+
userNamed: wasUserNamed,
|
|
1736
1732
|
location: existingMeta?.location ?? null,
|
|
1737
1733
|
disabled: existingMeta?.disabled ?? false,
|
|
1738
1734
|
...existingMeta?.integrationId !== void 0 ? { integrationId: existingMeta.integrationId } : {},
|
|
@@ -1807,7 +1803,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1807
1803
|
const persisted = await resolvePersistedById(deviceId);
|
|
1808
1804
|
if (!persisted) return;
|
|
1809
1805
|
const { addonId, stableId, meta: persistedMeta } = persisted;
|
|
1810
|
-
const key =
|
|
1806
|
+
const key = String(deviceId);
|
|
1811
1807
|
const deviceName = persistedMeta.name;
|
|
1812
1808
|
await withMetaWriteLock(async () => {
|
|
1813
1809
|
const index = await readIndex();
|
|
@@ -1888,7 +1884,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1888
1884
|
const persisted = await resolvePersistedById(deviceId);
|
|
1889
1885
|
if (!persisted) return null;
|
|
1890
1886
|
const { addonId, stableId, meta: m } = persisted;
|
|
1891
|
-
const key =
|
|
1887
|
+
const key = String(deviceId);
|
|
1892
1888
|
const metadata = (await readMetadataMap())[key] ?? null;
|
|
1893
1889
|
return {
|
|
1894
1890
|
id: m.id,
|
|
@@ -1917,14 +1913,15 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1917
1913
|
await withMetaWriteLock(async () => {
|
|
1918
1914
|
const persisted = await resolvePersistedById(deviceId);
|
|
1919
1915
|
if (!persisted) throw new Error(`[device-manager] setName: unknown device id=${deviceId}`);
|
|
1920
|
-
const {
|
|
1921
|
-
const key =
|
|
1916
|
+
const { meta: m } = persisted;
|
|
1917
|
+
const key = String(deviceId);
|
|
1922
1918
|
const allMeta = await readMeta();
|
|
1923
1919
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1924
1920
|
...allMeta,
|
|
1925
1921
|
[key]: {
|
|
1926
1922
|
...m,
|
|
1927
|
-
name
|
|
1923
|
+
name,
|
|
1924
|
+
userNamed: true
|
|
1928
1925
|
}
|
|
1929
1926
|
} });
|
|
1930
1927
|
});
|
|
@@ -1954,8 +1951,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1954
1951
|
await withMetaWriteLock(async () => {
|
|
1955
1952
|
const persisted = await resolvePersistedById(deviceId);
|
|
1956
1953
|
if (!persisted) throw new Error(`[device-manager] setLocation: unknown device id=${deviceId}`);
|
|
1957
|
-
const {
|
|
1958
|
-
const key =
|
|
1954
|
+
const { meta: m } = persisted;
|
|
1955
|
+
const key = String(deviceId);
|
|
1959
1956
|
const allMeta = await readMeta();
|
|
1960
1957
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1961
1958
|
...allMeta,
|
|
@@ -1992,8 +1989,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
1992
1989
|
await withMetaWriteLock(async () => {
|
|
1993
1990
|
const persisted = await resolvePersistedById(deviceId);
|
|
1994
1991
|
if (!persisted) throw new Error(`[device-manager] setType: unknown device id=${deviceId}`);
|
|
1995
|
-
const {
|
|
1996
|
-
const key =
|
|
1992
|
+
const { meta: m } = persisted;
|
|
1993
|
+
const key = String(deviceId);
|
|
1997
1994
|
const allMeta = await readMeta();
|
|
1998
1995
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1999
1996
|
...allMeta,
|
|
@@ -2038,8 +2035,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2038
2035
|
await withMetaWriteLock(async () => {
|
|
2039
2036
|
const persisted = await resolvePersistedById(deviceId);
|
|
2040
2037
|
if (!persisted) throw new Error(`[device-manager] setLinkDeviceId: unknown device id=${deviceId}`);
|
|
2041
|
-
const {
|
|
2042
|
-
const key =
|
|
2038
|
+
const { meta: m } = persisted;
|
|
2039
|
+
const key = String(deviceId);
|
|
2043
2040
|
const allMeta = await readMeta();
|
|
2044
2041
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2045
2042
|
...allMeta,
|
|
@@ -2076,8 +2073,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2076
2073
|
await withMetaWriteLock(async () => {
|
|
2077
2074
|
const persisted = await resolvePersistedById(deviceId);
|
|
2078
2075
|
if (!persisted) throw new Error(`[device-manager] setPrimaryChildEntityId: unknown device id=${deviceId}`);
|
|
2079
|
-
const {
|
|
2080
|
-
const key =
|
|
2076
|
+
const { meta: m } = persisted;
|
|
2077
|
+
const key = String(deviceId);
|
|
2081
2078
|
const allMeta = await readMeta();
|
|
2082
2079
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2083
2080
|
...allMeta,
|
|
@@ -2113,8 +2110,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2113
2110
|
await withMetaWriteLock(async () => {
|
|
2114
2111
|
const persisted = await resolvePersistedById(deviceId);
|
|
2115
2112
|
if (!persisted) throw new Error(`[device-manager] setChildLayout: unknown device id=${deviceId}`);
|
|
2116
|
-
const {
|
|
2117
|
-
const key =
|
|
2113
|
+
const { meta: m } = persisted;
|
|
2114
|
+
const key = String(deviceId);
|
|
2118
2115
|
const allMeta = await readMeta();
|
|
2119
2116
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2120
2117
|
...allMeta,
|
|
@@ -2151,8 +2148,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2151
2148
|
await withMetaWriteLock(async () => {
|
|
2152
2149
|
const persisted = await resolvePersistedById(deviceId);
|
|
2153
2150
|
if (!persisted) throw new Error(`[device-manager] setDeviceLinks: unknown device id=${deviceId}`);
|
|
2154
|
-
const {
|
|
2155
|
-
const key =
|
|
2151
|
+
const { meta: m } = persisted;
|
|
2152
|
+
const key = String(deviceId);
|
|
2156
2153
|
const allMeta = await readMeta();
|
|
2157
2154
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2158
2155
|
...allMeta,
|
|
@@ -2191,8 +2188,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2191
2188
|
await withMetaWriteLock(async () => {
|
|
2192
2189
|
const persisted = await resolvePersistedById(deviceId);
|
|
2193
2190
|
if (!persisted) throw new Error(`[device-manager] setRole: unknown device id=${deviceId}`);
|
|
2194
|
-
const {
|
|
2195
|
-
const key =
|
|
2191
|
+
const { meta: m } = persisted;
|
|
2192
|
+
const key = String(deviceId);
|
|
2196
2193
|
const allMeta = await readMeta();
|
|
2197
2194
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2198
2195
|
...allMeta,
|
|
@@ -2238,8 +2235,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2238
2235
|
await withMetaWriteLock(async () => {
|
|
2239
2236
|
const persisted = await resolvePersistedById(deviceId);
|
|
2240
2237
|
if (!persisted) throw new Error(`[device-manager] applyInitialMeta: unknown device id=${deviceId}`);
|
|
2241
|
-
const {
|
|
2242
|
-
const key =
|
|
2238
|
+
const { meta: m } = persisted;
|
|
2239
|
+
const key = String(deviceId);
|
|
2243
2240
|
const allMeta = await readMeta();
|
|
2244
2241
|
const merged = {
|
|
2245
2242
|
...m,
|
|
@@ -2289,10 +2286,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2289
2286
|
setMetadata: async (input) => {
|
|
2290
2287
|
const { deviceId, patch } = input;
|
|
2291
2288
|
const result = await withMetaWriteLock(async () => {
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
const { addonId, stableId } = persisted;
|
|
2295
|
-
const key = deviceKey(addonId, stableId);
|
|
2289
|
+
if (!await resolvePersistedById(deviceId)) throw new Error(`[device-manager] setMetadata: unknown device id=${deviceId}`);
|
|
2290
|
+
const key = String(deviceId);
|
|
2296
2291
|
const map = await readMetadataMap();
|
|
2297
2292
|
const next = { ...map[key] ?? {} };
|
|
2298
2293
|
let changed = false;
|
|
@@ -2343,8 +2338,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2343
2338
|
await withMetaWriteLock(async () => {
|
|
2344
2339
|
const persisted = await resolvePersistedById(deviceId);
|
|
2345
2340
|
if (!persisted) throw new Error(`[device-manager] setDisabled: unknown device id=${deviceId}`);
|
|
2346
|
-
const {
|
|
2347
|
-
const key =
|
|
2341
|
+
const { meta: m } = persisted;
|
|
2342
|
+
const key = String(deviceId);
|
|
2348
2343
|
const allMeta = await readMeta();
|
|
2349
2344
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2350
2345
|
...allMeta,
|
|
@@ -2461,8 +2456,11 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2461
2456
|
listPersistedByAddon: async (input) => {
|
|
2462
2457
|
const { addonId } = input;
|
|
2463
2458
|
const [index, meta] = await Promise.all([readIndex(), readMeta()]);
|
|
2464
|
-
|
|
2465
|
-
|
|
2459
|
+
const stableIds = index[addonId] ?? [];
|
|
2460
|
+
const byStableId = /* @__PURE__ */ new Map();
|
|
2461
|
+
for (const m of Object.values(meta)) if (m.addonId === addonId) byStableId.set(m.stableId, m);
|
|
2462
|
+
return stableIds.map((stableId) => {
|
|
2463
|
+
const m = byStableId.get(stableId);
|
|
2466
2464
|
return {
|
|
2467
2465
|
id: m.id,
|
|
2468
2466
|
stableId,
|
|
@@ -2486,7 +2484,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2486
2484
|
device
|
|
2487
2485
|
})) : registry.getAllWithAddonId();
|
|
2488
2486
|
for (const { addonId: aid, device } of liveEntries) {
|
|
2489
|
-
const key =
|
|
2487
|
+
const key = String(device.id);
|
|
2490
2488
|
const metadata = metadataMap[key] ?? null;
|
|
2491
2489
|
const metaRow = meta[key] ?? null;
|
|
2492
2490
|
results.push(toDeviceInfo(aid, device, metadata, metaRow));
|
|
@@ -2494,11 +2492,13 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2494
2492
|
}
|
|
2495
2493
|
}
|
|
2496
2494
|
const index = await readIndex();
|
|
2495
|
+
const metaByAddonStable = /* @__PURE__ */ new Map();
|
|
2496
|
+
for (const m of Object.values(meta)) metaByAddonStable.set(`${m.addonId}${m.stableId}`, m);
|
|
2497
2497
|
const targetAddons = addonId ? [addonId] : Object.keys(index);
|
|
2498
2498
|
for (const aid of targetAddons) for (const stableId of index[aid] ?? []) {
|
|
2499
|
-
const
|
|
2499
|
+
const m = metaByAddonStable.get(`${aid}${stableId}`);
|
|
2500
|
+
const key = String(m.id);
|
|
2500
2501
|
if (seen.has(key)) continue;
|
|
2501
|
-
const m = meta[key];
|
|
2502
2502
|
const persistedType = m.type;
|
|
2503
2503
|
const persistedConfig = await settings.readDeviceStore(m.id);
|
|
2504
2504
|
const metadata = metadataMap[key] ?? null;
|
|
@@ -2536,7 +2536,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2536
2536
|
if (registry) {
|
|
2537
2537
|
const found = resolveDeviceById(registry, deviceId);
|
|
2538
2538
|
if (found) {
|
|
2539
|
-
const key =
|
|
2539
|
+
const key = String(found.device.id);
|
|
2540
2540
|
const [map, metaMap] = await Promise.all([readMetadataMap(), readMeta()]);
|
|
2541
2541
|
const metadata = map[key] ?? null;
|
|
2542
2542
|
const metaRow = metaMap[key] ?? null;
|
|
@@ -2547,7 +2547,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2547
2547
|
if (!persisted) return null;
|
|
2548
2548
|
const { addonId: aid, stableId, meta: m } = persisted;
|
|
2549
2549
|
const persistedConfig = await settings.readDeviceStore(m.id);
|
|
2550
|
-
const key =
|
|
2550
|
+
const key = String(deviceId);
|
|
2551
2551
|
const metadata = (await readMetadataMap())[key] ?? null;
|
|
2552
2552
|
const sourceInfoGetDevice = buildSourceInfoFromConfig(persistedConfig ?? {}, stableId, aid);
|
|
2553
2553
|
return {
|
|
@@ -2595,18 +2595,20 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2595
2595
|
if (registry) {
|
|
2596
2596
|
const liveChildren = registry.getChildren(parentDeviceId);
|
|
2597
2597
|
for (const device of liveChildren) {
|
|
2598
|
-
const key =
|
|
2598
|
+
const key = String(device.id);
|
|
2599
2599
|
const metadata = metadataMap[key] ?? null;
|
|
2600
2600
|
const metaRow = meta[key] ?? null;
|
|
2601
2601
|
results.push(toDeviceInfo(ownerAddonId, device, metadata, metaRow));
|
|
2602
2602
|
seen.add(key);
|
|
2603
2603
|
}
|
|
2604
2604
|
}
|
|
2605
|
-
const
|
|
2605
|
+
const ownerMetaByStableId = /* @__PURE__ */ new Map();
|
|
2606
|
+
for (const m of Object.values(meta)) if (m.addonId === ownerAddonId) ownerMetaByStableId.set(m.stableId, m);
|
|
2607
|
+
const persistedChildren = (index[ownerAddonId] ?? []).filter((sid) => ownerMetaByStableId.get(sid)?.parentDeviceId === parentDeviceId);
|
|
2606
2608
|
for (const childStableId of persistedChildren) {
|
|
2607
|
-
const
|
|
2609
|
+
const m = ownerMetaByStableId.get(childStableId);
|
|
2610
|
+
const key = String(m.id);
|
|
2608
2611
|
if (seen.has(key)) continue;
|
|
2609
|
-
const m = meta[key];
|
|
2610
2612
|
const persistedConfig = await settings.readDeviceStore(m.id);
|
|
2611
2613
|
const metadata = metadataMap[key] ?? null;
|
|
2612
2614
|
const sourceInfoChild = buildSourceInfoFromConfig(persistedConfig ?? {}, childStableId, ownerAddonId);
|
|
@@ -2712,14 +2714,6 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2712
2714
|
},
|
|
2713
2715
|
remove: async (input) => {
|
|
2714
2716
|
const { deviceId } = input;
|
|
2715
|
-
const directChildIds = async (parentId) => {
|
|
2716
|
-
const ids = /* @__PURE__ */ new Set();
|
|
2717
|
-
if (registry) for (const c of registry.getChildren(parentId)) ids.add(c.id);
|
|
2718
|
-
const meta = await readMeta();
|
|
2719
|
-
for (const m of Object.values(meta)) if (m.parentDeviceId === parentId) ids.add(m.id);
|
|
2720
|
-
ids.delete(parentId);
|
|
2721
|
-
return [...ids];
|
|
2722
|
-
};
|
|
2723
2717
|
const removeOne = async (id) => {
|
|
2724
2718
|
if (registry) {
|
|
2725
2719
|
const live = resolveDeviceById(registry, id);
|
|
@@ -2910,6 +2904,30 @@ var DeviceManagerAddon = class DeviceManagerAddon extends _camstack_types.BaseAd
|
|
|
2910
2904
|
adoptionRelease: async ({ addonId, ...rest }) => {
|
|
2911
2905
|
return (await this.requireDeviceAdoptionProvider(addonId)).release(rest);
|
|
2912
2906
|
},
|
|
2907
|
+
adoptionResync: async ({ camDeviceId, resetToSource }) => {
|
|
2908
|
+
let owningAddonId = registry?.getAddonId(camDeviceId) ?? null;
|
|
2909
|
+
if (!owningAddonId) owningAddonId = (await resolvePersistedById(camDeviceId))?.addonId ?? null;
|
|
2910
|
+
if (!owningAddonId) throw new Error(`adoptionResync: device ${camDeviceId} not found`);
|
|
2911
|
+
let removedChildren = 0;
|
|
2912
|
+
if (resetToSource === true) {
|
|
2913
|
+
const childIds = await directChildIds(camDeviceId);
|
|
2914
|
+
for (const childId of childIds) {
|
|
2915
|
+
await provider.remove({ deviceId: childId });
|
|
2916
|
+
removedChildren += 1;
|
|
2917
|
+
}
|
|
2918
|
+
this.ctx.logger.info("resetToSource purge before resync", { tags: {
|
|
2919
|
+
deviceId: camDeviceId,
|
|
2920
|
+
removedChildren
|
|
2921
|
+
} });
|
|
2922
|
+
}
|
|
2923
|
+
return {
|
|
2924
|
+
...await (await this.requireDeviceAdoptionProvider(owningAddonId)).resync({
|
|
2925
|
+
camDeviceId,
|
|
2926
|
+
resetToSource
|
|
2927
|
+
}),
|
|
2928
|
+
removedChildren
|
|
2929
|
+
};
|
|
2930
|
+
},
|
|
2913
2931
|
testField: async (input) => {
|
|
2914
2932
|
const { deviceId } = input;
|
|
2915
2933
|
let owningAddonId = null;
|
|
@@ -234,7 +234,8 @@ function buildLinkIndexes(entries) {
|
|
|
234
234
|
*
|
|
235
235
|
* Addon store layout:
|
|
236
236
|
* deviceIndex → Record<addonId, stableId[]> (which devices exist per addon)
|
|
237
|
-
* deviceMeta → Record<
|
|
237
|
+
* deviceMeta → Record<numericId, DeviceMeta> (keyed by numeric device id;
|
|
238
|
+
* addonId + stableId are FIELDS on the record)
|
|
238
239
|
*
|
|
239
240
|
* Device store (per-device config):
|
|
240
241
|
* readDeviceStore(numericDeviceId) → config blob
|
|
@@ -277,9 +278,6 @@ function shallowEqual(a, b) {
|
|
|
277
278
|
for (const k of ak) if (a[k] !== b[k]) return false;
|
|
278
279
|
return true;
|
|
279
280
|
}
|
|
280
|
-
function deviceKey(addonId, stableId) {
|
|
281
|
-
return `${addonId}:${stableId}`;
|
|
282
|
-
}
|
|
283
281
|
/** Returns true when `x` is a non-null, non-array plain object. */
|
|
284
282
|
function isRecord(x) {
|
|
285
283
|
return x !== null && typeof x === "object" && !Array.isArray(x);
|
|
@@ -772,12 +770,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
772
770
|
* numeric deviceId; this helper is display-only.
|
|
773
771
|
*/
|
|
774
772
|
async lookupPersistedStableId(deviceId) {
|
|
775
|
-
|
|
776
|
-
for (const [key, m] of Object.entries(meta)) if (m.id === deviceId) {
|
|
777
|
-
const sep = key.indexOf(":");
|
|
778
|
-
if (sep < 0) continue;
|
|
779
|
-
return key.slice(sep + 1);
|
|
780
|
-
}
|
|
773
|
+
return ((await this.ctx.settings.readAddonStore()).deviceMeta ?? {})[String(deviceId)]?.stableId;
|
|
781
774
|
}
|
|
782
775
|
async getDeviceAggregate(deviceId, kind) {
|
|
783
776
|
const registry = this.capabilityRegistry;
|
|
@@ -1469,28 +1462,32 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1469
1462
|
* Returns null when no device with that id is known to the hub.
|
|
1470
1463
|
*/
|
|
1471
1464
|
const resolvePersistedById = async (deviceId) => {
|
|
1465
|
+
const m = (await readMeta())[String(deviceId)];
|
|
1466
|
+
if (!m) return null;
|
|
1467
|
+
return {
|
|
1468
|
+
addonId: m.addonId,
|
|
1469
|
+
stableId: m.stableId,
|
|
1470
|
+
meta: m
|
|
1471
|
+
};
|
|
1472
|
+
};
|
|
1473
|
+
/** Direct children of a device: the union of the live registry's children
|
|
1474
|
+
* and the persisted-meta scan (`parentDeviceId === parentId`), deduplicated
|
|
1475
|
+
* and excluding self. Shared by the `remove` cascade and the `resetToSource`
|
|
1476
|
+
* resync purge (#19). */
|
|
1477
|
+
const directChildIds = async (parentId) => {
|
|
1478
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1479
|
+
if (registry) for (const c of registry.getChildren(parentId)) ids.add(c.id);
|
|
1472
1480
|
const meta = await readMeta();
|
|
1473
|
-
for (const
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
return {
|
|
1477
|
-
addonId: key.slice(0, sep),
|
|
1478
|
-
stableId: key.slice(sep + 1),
|
|
1479
|
-
meta: m
|
|
1480
|
-
};
|
|
1481
|
-
}
|
|
1482
|
-
return null;
|
|
1481
|
+
for (const m of Object.values(meta)) if (m.parentDeviceId === parentId) ids.add(m.id);
|
|
1482
|
+
ids.delete(parentId);
|
|
1483
|
+
return [...ids];
|
|
1483
1484
|
};
|
|
1484
1485
|
/** Resolve a link's `sourceKey` to a live device id: the sibling accessory
|
|
1485
1486
|
* whose stableId is `${parentStableId}-${sourceKey}`. Null when absent.
|
|
1486
1487
|
* Pure over a pre-read meta map so a multi-link resolve reads the store once. */
|
|
1487
1488
|
const resolveSourceDeviceId = (parentStableId, sourceKey, meta) => {
|
|
1488
1489
|
const wanted = `${parentStableId}-${sourceKey}`;
|
|
1489
|
-
for (const
|
|
1490
|
-
const sep = key.indexOf(":");
|
|
1491
|
-
if (sep < 0) continue;
|
|
1492
|
-
if (key.slice(sep + 1) === wanted) return m.id;
|
|
1493
|
-
}
|
|
1490
|
+
for (const m of Object.values(meta)) if (m.stableId === wanted) return m.id;
|
|
1494
1491
|
return null;
|
|
1495
1492
|
};
|
|
1496
1493
|
/** Rebuild the `linkTargets` / `linkDependents` reverse-index maps from the
|
|
@@ -1508,12 +1505,9 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1508
1505
|
const allMeta = await readMeta();
|
|
1509
1506
|
const stableIdById = /* @__PURE__ */ new Map();
|
|
1510
1507
|
const idByStableId = /* @__PURE__ */ new Map();
|
|
1511
|
-
for (const
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
const sid = key.slice(sep + 1);
|
|
1515
|
-
stableIdById.set(m.id, sid);
|
|
1516
|
-
idByStableId.set(sid, m.id);
|
|
1508
|
+
for (const m of Object.values(allMeta)) {
|
|
1509
|
+
stableIdById.set(m.id, m.stableId);
|
|
1510
|
+
idByStableId.set(m.stableId, m.id);
|
|
1517
1511
|
}
|
|
1518
1512
|
const entries = [];
|
|
1519
1513
|
const expectedSources = /* @__PURE__ */ new Set();
|
|
@@ -1541,10 +1535,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1541
1535
|
const idToAddonId = /* @__PURE__ */ new Map();
|
|
1542
1536
|
{
|
|
1543
1537
|
const meta = await readMeta();
|
|
1544
|
-
for (const
|
|
1545
|
-
|
|
1546
|
-
if (sep < 0) continue;
|
|
1547
|
-
idToAddonId.set(m.id, key.slice(0, sep));
|
|
1538
|
+
for (const m of Object.values(meta)) {
|
|
1539
|
+
idToAddonId.set(m.id, m.addonId);
|
|
1548
1540
|
if (Array.isArray(m.deviceLinks) && m.deviceLinks.length > 0) this.devicesWithLinks.add(m.id);
|
|
1549
1541
|
}
|
|
1550
1542
|
}
|
|
@@ -1558,8 +1550,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1558
1550
|
await withMetaWriteLock(async () => {
|
|
1559
1551
|
const persisted = await resolvePersistedById(deviceId);
|
|
1560
1552
|
if (!persisted) throw new Error(`[device-manager] stampIntegrationId: unknown device id=${deviceId}`);
|
|
1561
|
-
const {
|
|
1562
|
-
const key =
|
|
1553
|
+
const { meta: m } = persisted;
|
|
1554
|
+
const key = String(deviceId);
|
|
1563
1555
|
const allMeta = await readMeta();
|
|
1564
1556
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1565
1557
|
...allMeta,
|
|
@@ -1640,10 +1632,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1640
1632
|
let containerStableId = persisted.stableId;
|
|
1641
1633
|
const parentId = persisted.meta.parentDeviceId;
|
|
1642
1634
|
if (parentId !== null) {
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
break;
|
|
1646
|
-
}
|
|
1635
|
+
const parentMeta = allMeta[String(parentId)];
|
|
1636
|
+
if (parentMeta) containerStableId = parentMeta.stableId;
|
|
1647
1637
|
}
|
|
1648
1638
|
const resolved = [];
|
|
1649
1639
|
for (const link of links) {
|
|
@@ -1683,15 +1673,16 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1683
1673
|
* `registerDevice` completes. */
|
|
1684
1674
|
allocateDeviceId: async (input) => {
|
|
1685
1675
|
const { addonId, stableId } = input;
|
|
1686
|
-
const key = deviceKey(addonId, stableId);
|
|
1687
1676
|
return await withMetaWriteLock(async () => {
|
|
1688
1677
|
const meta = await readMeta();
|
|
1689
|
-
const existing = meta
|
|
1678
|
+
const existing = Object.values(meta).find((m) => m.addonId === addonId && m.stableId === stableId);
|
|
1690
1679
|
if (existing) return { id: existing.id };
|
|
1691
1680
|
const id = await allocateNextDeviceId();
|
|
1692
1681
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1693
1682
|
...meta,
|
|
1694
|
-
[
|
|
1683
|
+
[String(id)]: {
|
|
1684
|
+
addonId,
|
|
1685
|
+
stableId,
|
|
1695
1686
|
type: "generic",
|
|
1696
1687
|
name: stableId,
|
|
1697
1688
|
location: null,
|
|
@@ -1705,7 +1696,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1705
1696
|
},
|
|
1706
1697
|
registerDevice: async (input) => {
|
|
1707
1698
|
const { addonId, stableId, id, type, name, parentDeviceId, features, config } = input;
|
|
1708
|
-
const key =
|
|
1699
|
+
const key = String(id);
|
|
1709
1700
|
const featuresArr = Array.isArray(features) ? [...features] : [];
|
|
1710
1701
|
const { isFirstRegistration, exportFingerprint, fingerprintChanged } = await withMetaWriteLock(async () => {
|
|
1711
1702
|
const index = await readIndex();
|
|
@@ -1717,6 +1708,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1717
1708
|
} });
|
|
1718
1709
|
const meta = await readMeta();
|
|
1719
1710
|
const existingMeta = meta[key];
|
|
1711
|
+
const wasUserNamed = existingMeta?.userNamed ?? (existingMeta !== void 0 && existingMeta.name !== stableId);
|
|
1712
|
+
const resolvedName = wasUserNamed && existingMeta !== void 0 ? existingMeta.name : name;
|
|
1720
1713
|
const isFirst = !existingMeta || !wasInIndex;
|
|
1721
1714
|
const fingerprint = canonicalDeviceFingerprint({
|
|
1722
1715
|
deviceId: id,
|
|
@@ -1726,8 +1719,11 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1726
1719
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1727
1720
|
...meta,
|
|
1728
1721
|
[key]: {
|
|
1722
|
+
addonId,
|
|
1723
|
+
stableId,
|
|
1729
1724
|
type,
|
|
1730
|
-
name:
|
|
1725
|
+
name: resolvedName,
|
|
1726
|
+
userNamed: wasUserNamed,
|
|
1731
1727
|
location: existingMeta?.location ?? null,
|
|
1732
1728
|
disabled: existingMeta?.disabled ?? false,
|
|
1733
1729
|
...existingMeta?.integrationId !== void 0 ? { integrationId: existingMeta.integrationId } : {},
|
|
@@ -1802,7 +1798,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1802
1798
|
const persisted = await resolvePersistedById(deviceId);
|
|
1803
1799
|
if (!persisted) return;
|
|
1804
1800
|
const { addonId, stableId, meta: persistedMeta } = persisted;
|
|
1805
|
-
const key =
|
|
1801
|
+
const key = String(deviceId);
|
|
1806
1802
|
const deviceName = persistedMeta.name;
|
|
1807
1803
|
await withMetaWriteLock(async () => {
|
|
1808
1804
|
const index = await readIndex();
|
|
@@ -1883,7 +1879,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1883
1879
|
const persisted = await resolvePersistedById(deviceId);
|
|
1884
1880
|
if (!persisted) return null;
|
|
1885
1881
|
const { addonId, stableId, meta: m } = persisted;
|
|
1886
|
-
const key =
|
|
1882
|
+
const key = String(deviceId);
|
|
1887
1883
|
const metadata = (await readMetadataMap())[key] ?? null;
|
|
1888
1884
|
return {
|
|
1889
1885
|
id: m.id,
|
|
@@ -1912,14 +1908,15 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1912
1908
|
await withMetaWriteLock(async () => {
|
|
1913
1909
|
const persisted = await resolvePersistedById(deviceId);
|
|
1914
1910
|
if (!persisted) throw new Error(`[device-manager] setName: unknown device id=${deviceId}`);
|
|
1915
|
-
const {
|
|
1916
|
-
const key =
|
|
1911
|
+
const { meta: m } = persisted;
|
|
1912
|
+
const key = String(deviceId);
|
|
1917
1913
|
const allMeta = await readMeta();
|
|
1918
1914
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1919
1915
|
...allMeta,
|
|
1920
1916
|
[key]: {
|
|
1921
1917
|
...m,
|
|
1922
|
-
name
|
|
1918
|
+
name,
|
|
1919
|
+
userNamed: true
|
|
1923
1920
|
}
|
|
1924
1921
|
} });
|
|
1925
1922
|
});
|
|
@@ -1949,8 +1946,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1949
1946
|
await withMetaWriteLock(async () => {
|
|
1950
1947
|
const persisted = await resolvePersistedById(deviceId);
|
|
1951
1948
|
if (!persisted) throw new Error(`[device-manager] setLocation: unknown device id=${deviceId}`);
|
|
1952
|
-
const {
|
|
1953
|
-
const key =
|
|
1949
|
+
const { meta: m } = persisted;
|
|
1950
|
+
const key = String(deviceId);
|
|
1954
1951
|
const allMeta = await readMeta();
|
|
1955
1952
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1956
1953
|
...allMeta,
|
|
@@ -1987,8 +1984,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
1987
1984
|
await withMetaWriteLock(async () => {
|
|
1988
1985
|
const persisted = await resolvePersistedById(deviceId);
|
|
1989
1986
|
if (!persisted) throw new Error(`[device-manager] setType: unknown device id=${deviceId}`);
|
|
1990
|
-
const {
|
|
1991
|
-
const key =
|
|
1987
|
+
const { meta: m } = persisted;
|
|
1988
|
+
const key = String(deviceId);
|
|
1992
1989
|
const allMeta = await readMeta();
|
|
1993
1990
|
await settings.writeAddonStore({ deviceMeta: {
|
|
1994
1991
|
...allMeta,
|
|
@@ -2033,8 +2030,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2033
2030
|
await withMetaWriteLock(async () => {
|
|
2034
2031
|
const persisted = await resolvePersistedById(deviceId);
|
|
2035
2032
|
if (!persisted) throw new Error(`[device-manager] setLinkDeviceId: unknown device id=${deviceId}`);
|
|
2036
|
-
const {
|
|
2037
|
-
const key =
|
|
2033
|
+
const { meta: m } = persisted;
|
|
2034
|
+
const key = String(deviceId);
|
|
2038
2035
|
const allMeta = await readMeta();
|
|
2039
2036
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2040
2037
|
...allMeta,
|
|
@@ -2071,8 +2068,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2071
2068
|
await withMetaWriteLock(async () => {
|
|
2072
2069
|
const persisted = await resolvePersistedById(deviceId);
|
|
2073
2070
|
if (!persisted) throw new Error(`[device-manager] setPrimaryChildEntityId: unknown device id=${deviceId}`);
|
|
2074
|
-
const {
|
|
2075
|
-
const key =
|
|
2071
|
+
const { meta: m } = persisted;
|
|
2072
|
+
const key = String(deviceId);
|
|
2076
2073
|
const allMeta = await readMeta();
|
|
2077
2074
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2078
2075
|
...allMeta,
|
|
@@ -2108,8 +2105,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2108
2105
|
await withMetaWriteLock(async () => {
|
|
2109
2106
|
const persisted = await resolvePersistedById(deviceId);
|
|
2110
2107
|
if (!persisted) throw new Error(`[device-manager] setChildLayout: unknown device id=${deviceId}`);
|
|
2111
|
-
const {
|
|
2112
|
-
const key =
|
|
2108
|
+
const { meta: m } = persisted;
|
|
2109
|
+
const key = String(deviceId);
|
|
2113
2110
|
const allMeta = await readMeta();
|
|
2114
2111
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2115
2112
|
...allMeta,
|
|
@@ -2146,8 +2143,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2146
2143
|
await withMetaWriteLock(async () => {
|
|
2147
2144
|
const persisted = await resolvePersistedById(deviceId);
|
|
2148
2145
|
if (!persisted) throw new Error(`[device-manager] setDeviceLinks: unknown device id=${deviceId}`);
|
|
2149
|
-
const {
|
|
2150
|
-
const key =
|
|
2146
|
+
const { meta: m } = persisted;
|
|
2147
|
+
const key = String(deviceId);
|
|
2151
2148
|
const allMeta = await readMeta();
|
|
2152
2149
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2153
2150
|
...allMeta,
|
|
@@ -2186,8 +2183,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2186
2183
|
await withMetaWriteLock(async () => {
|
|
2187
2184
|
const persisted = await resolvePersistedById(deviceId);
|
|
2188
2185
|
if (!persisted) throw new Error(`[device-manager] setRole: unknown device id=${deviceId}`);
|
|
2189
|
-
const {
|
|
2190
|
-
const key =
|
|
2186
|
+
const { meta: m } = persisted;
|
|
2187
|
+
const key = String(deviceId);
|
|
2191
2188
|
const allMeta = await readMeta();
|
|
2192
2189
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2193
2190
|
...allMeta,
|
|
@@ -2233,8 +2230,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2233
2230
|
await withMetaWriteLock(async () => {
|
|
2234
2231
|
const persisted = await resolvePersistedById(deviceId);
|
|
2235
2232
|
if (!persisted) throw new Error(`[device-manager] applyInitialMeta: unknown device id=${deviceId}`);
|
|
2236
|
-
const {
|
|
2237
|
-
const key =
|
|
2233
|
+
const { meta: m } = persisted;
|
|
2234
|
+
const key = String(deviceId);
|
|
2238
2235
|
const allMeta = await readMeta();
|
|
2239
2236
|
const merged = {
|
|
2240
2237
|
...m,
|
|
@@ -2284,10 +2281,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2284
2281
|
setMetadata: async (input) => {
|
|
2285
2282
|
const { deviceId, patch } = input;
|
|
2286
2283
|
const result = await withMetaWriteLock(async () => {
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
const { addonId, stableId } = persisted;
|
|
2290
|
-
const key = deviceKey(addonId, stableId);
|
|
2284
|
+
if (!await resolvePersistedById(deviceId)) throw new Error(`[device-manager] setMetadata: unknown device id=${deviceId}`);
|
|
2285
|
+
const key = String(deviceId);
|
|
2291
2286
|
const map = await readMetadataMap();
|
|
2292
2287
|
const next = { ...map[key] ?? {} };
|
|
2293
2288
|
let changed = false;
|
|
@@ -2338,8 +2333,8 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2338
2333
|
await withMetaWriteLock(async () => {
|
|
2339
2334
|
const persisted = await resolvePersistedById(deviceId);
|
|
2340
2335
|
if (!persisted) throw new Error(`[device-manager] setDisabled: unknown device id=${deviceId}`);
|
|
2341
|
-
const {
|
|
2342
|
-
const key =
|
|
2336
|
+
const { meta: m } = persisted;
|
|
2337
|
+
const key = String(deviceId);
|
|
2343
2338
|
const allMeta = await readMeta();
|
|
2344
2339
|
await settings.writeAddonStore({ deviceMeta: {
|
|
2345
2340
|
...allMeta,
|
|
@@ -2456,8 +2451,11 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2456
2451
|
listPersistedByAddon: async (input) => {
|
|
2457
2452
|
const { addonId } = input;
|
|
2458
2453
|
const [index, meta] = await Promise.all([readIndex(), readMeta()]);
|
|
2459
|
-
|
|
2460
|
-
|
|
2454
|
+
const stableIds = index[addonId] ?? [];
|
|
2455
|
+
const byStableId = /* @__PURE__ */ new Map();
|
|
2456
|
+
for (const m of Object.values(meta)) if (m.addonId === addonId) byStableId.set(m.stableId, m);
|
|
2457
|
+
return stableIds.map((stableId) => {
|
|
2458
|
+
const m = byStableId.get(stableId);
|
|
2461
2459
|
return {
|
|
2462
2460
|
id: m.id,
|
|
2463
2461
|
stableId,
|
|
@@ -2481,7 +2479,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2481
2479
|
device
|
|
2482
2480
|
})) : registry.getAllWithAddonId();
|
|
2483
2481
|
for (const { addonId: aid, device } of liveEntries) {
|
|
2484
|
-
const key =
|
|
2482
|
+
const key = String(device.id);
|
|
2485
2483
|
const metadata = metadataMap[key] ?? null;
|
|
2486
2484
|
const metaRow = meta[key] ?? null;
|
|
2487
2485
|
results.push(toDeviceInfo(aid, device, metadata, metaRow));
|
|
@@ -2489,11 +2487,13 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2489
2487
|
}
|
|
2490
2488
|
}
|
|
2491
2489
|
const index = await readIndex();
|
|
2490
|
+
const metaByAddonStable = /* @__PURE__ */ new Map();
|
|
2491
|
+
for (const m of Object.values(meta)) metaByAddonStable.set(`${m.addonId}${m.stableId}`, m);
|
|
2492
2492
|
const targetAddons = addonId ? [addonId] : Object.keys(index);
|
|
2493
2493
|
for (const aid of targetAddons) for (const stableId of index[aid] ?? []) {
|
|
2494
|
-
const
|
|
2494
|
+
const m = metaByAddonStable.get(`${aid}${stableId}`);
|
|
2495
|
+
const key = String(m.id);
|
|
2495
2496
|
if (seen.has(key)) continue;
|
|
2496
|
-
const m = meta[key];
|
|
2497
2497
|
const persistedType = m.type;
|
|
2498
2498
|
const persistedConfig = await settings.readDeviceStore(m.id);
|
|
2499
2499
|
const metadata = metadataMap[key] ?? null;
|
|
@@ -2531,7 +2531,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2531
2531
|
if (registry) {
|
|
2532
2532
|
const found = resolveDeviceById(registry, deviceId);
|
|
2533
2533
|
if (found) {
|
|
2534
|
-
const key =
|
|
2534
|
+
const key = String(found.device.id);
|
|
2535
2535
|
const [map, metaMap] = await Promise.all([readMetadataMap(), readMeta()]);
|
|
2536
2536
|
const metadata = map[key] ?? null;
|
|
2537
2537
|
const metaRow = metaMap[key] ?? null;
|
|
@@ -2542,7 +2542,7 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2542
2542
|
if (!persisted) return null;
|
|
2543
2543
|
const { addonId: aid, stableId, meta: m } = persisted;
|
|
2544
2544
|
const persistedConfig = await settings.readDeviceStore(m.id);
|
|
2545
|
-
const key =
|
|
2545
|
+
const key = String(deviceId);
|
|
2546
2546
|
const metadata = (await readMetadataMap())[key] ?? null;
|
|
2547
2547
|
const sourceInfoGetDevice = buildSourceInfoFromConfig(persistedConfig ?? {}, stableId, aid);
|
|
2548
2548
|
return {
|
|
@@ -2590,18 +2590,20 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2590
2590
|
if (registry) {
|
|
2591
2591
|
const liveChildren = registry.getChildren(parentDeviceId);
|
|
2592
2592
|
for (const device of liveChildren) {
|
|
2593
|
-
const key =
|
|
2593
|
+
const key = String(device.id);
|
|
2594
2594
|
const metadata = metadataMap[key] ?? null;
|
|
2595
2595
|
const metaRow = meta[key] ?? null;
|
|
2596
2596
|
results.push(toDeviceInfo(ownerAddonId, device, metadata, metaRow));
|
|
2597
2597
|
seen.add(key);
|
|
2598
2598
|
}
|
|
2599
2599
|
}
|
|
2600
|
-
const
|
|
2600
|
+
const ownerMetaByStableId = /* @__PURE__ */ new Map();
|
|
2601
|
+
for (const m of Object.values(meta)) if (m.addonId === ownerAddonId) ownerMetaByStableId.set(m.stableId, m);
|
|
2602
|
+
const persistedChildren = (index[ownerAddonId] ?? []).filter((sid) => ownerMetaByStableId.get(sid)?.parentDeviceId === parentDeviceId);
|
|
2601
2603
|
for (const childStableId of persistedChildren) {
|
|
2602
|
-
const
|
|
2604
|
+
const m = ownerMetaByStableId.get(childStableId);
|
|
2605
|
+
const key = String(m.id);
|
|
2603
2606
|
if (seen.has(key)) continue;
|
|
2604
|
-
const m = meta[key];
|
|
2605
2607
|
const persistedConfig = await settings.readDeviceStore(m.id);
|
|
2606
2608
|
const metadata = metadataMap[key] ?? null;
|
|
2607
2609
|
const sourceInfoChild = buildSourceInfoFromConfig(persistedConfig ?? {}, childStableId, ownerAddonId);
|
|
@@ -2707,14 +2709,6 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2707
2709
|
},
|
|
2708
2710
|
remove: async (input) => {
|
|
2709
2711
|
const { deviceId } = input;
|
|
2710
|
-
const directChildIds = async (parentId) => {
|
|
2711
|
-
const ids = /* @__PURE__ */ new Set();
|
|
2712
|
-
if (registry) for (const c of registry.getChildren(parentId)) ids.add(c.id);
|
|
2713
|
-
const meta = await readMeta();
|
|
2714
|
-
for (const m of Object.values(meta)) if (m.parentDeviceId === parentId) ids.add(m.id);
|
|
2715
|
-
ids.delete(parentId);
|
|
2716
|
-
return [...ids];
|
|
2717
|
-
};
|
|
2718
2712
|
const removeOne = async (id) => {
|
|
2719
2713
|
if (registry) {
|
|
2720
2714
|
const live = resolveDeviceById(registry, id);
|
|
@@ -2905,6 +2899,30 @@ var DeviceManagerAddon = class DeviceManagerAddon extends BaseAddon {
|
|
|
2905
2899
|
adoptionRelease: async ({ addonId, ...rest }) => {
|
|
2906
2900
|
return (await this.requireDeviceAdoptionProvider(addonId)).release(rest);
|
|
2907
2901
|
},
|
|
2902
|
+
adoptionResync: async ({ camDeviceId, resetToSource }) => {
|
|
2903
|
+
let owningAddonId = registry?.getAddonId(camDeviceId) ?? null;
|
|
2904
|
+
if (!owningAddonId) owningAddonId = (await resolvePersistedById(camDeviceId))?.addonId ?? null;
|
|
2905
|
+
if (!owningAddonId) throw new Error(`adoptionResync: device ${camDeviceId} not found`);
|
|
2906
|
+
let removedChildren = 0;
|
|
2907
|
+
if (resetToSource === true) {
|
|
2908
|
+
const childIds = await directChildIds(camDeviceId);
|
|
2909
|
+
for (const childId of childIds) {
|
|
2910
|
+
await provider.remove({ deviceId: childId });
|
|
2911
|
+
removedChildren += 1;
|
|
2912
|
+
}
|
|
2913
|
+
this.ctx.logger.info("resetToSource purge before resync", { tags: {
|
|
2914
|
+
deviceId: camDeviceId,
|
|
2915
|
+
removedChildren
|
|
2916
|
+
} });
|
|
2917
|
+
}
|
|
2918
|
+
return {
|
|
2919
|
+
...await (await this.requireDeviceAdoptionProvider(owningAddonId)).resync({
|
|
2920
|
+
camDeviceId,
|
|
2921
|
+
resetToSource
|
|
2922
|
+
}),
|
|
2923
|
+
removedChildren
|
|
2924
|
+
};
|
|
2925
|
+
},
|
|
2908
2926
|
testField: async (input) => {
|
|
2909
2927
|
const { deviceId } = input;
|
|
2910
2928
|
let owningAddonId = null;
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ const require_builtins_local_auth_local_auth_addon = require("./builtins/local-a
|
|
|
20
20
|
require("./builtins/local-auth/index.js");
|
|
21
21
|
const require_builtins_device_manager_device_manager_addon = require("./builtins/device-manager/device-manager.addon.js");
|
|
22
22
|
require("./builtins/device-manager/index.js");
|
|
23
|
-
const require_manifest_python_deps = require("./manifest-python-deps-
|
|
23
|
+
const require_manifest_python_deps = require("./manifest-python-deps-Cro19O4u.js");
|
|
24
24
|
const require_custom_action_registry = require("./custom-action-registry-vLYEFTtv.js");
|
|
25
25
|
let _camstack_types_node = require("@camstack/types/node");
|
|
26
26
|
let node_http = require("node:http");
|
package/dist/index.mjs
CHANGED
|
@@ -18,7 +18,7 @@ import { LocalAuthAddon, a as require_ms, c as __esmMin, d as __toCommonJS, f as
|
|
|
18
18
|
import "./builtins/local-auth/index.mjs";
|
|
19
19
|
import { DeviceManagerAddon } from "./builtins/device-manager/device-manager.addon.mjs";
|
|
20
20
|
import "./builtins/device-manager/index.mjs";
|
|
21
|
-
import { A as createUdsLoggerWithControl, B as createLocalTransport, C as ipcParentLink, D as createUdsEventBus, E as createUdsEventBridge, F as AGENT_CAP_FWD_SERVICE, G as FrameDecoder, H as UdsLocalTransportServer, I as CapRouteResolver, J as buildUdsNativeCapProxy, K as encodeFrame, L as CapRouteError, M as LocalChildRegistry, N as UDS_NO_ROUTE_PREFIX, O as udsChildLogToWorkerEntry, P as AGENT_CAP_FWD_ACTION, Q as mountNativeCapService, R as classifyCapRoute, S as ipcChildLink, T as createParentUnownedCallHandler, U as SocketChannel, V as UdsLocalTransportClient, W as localEndpointPath, Y as createBrokerDeviceManagerApi, _ as __resetCapUsageRegistryForTests, a as getWorkerDeviceRegistry, at as capBareAction, b as brokerTransportLink, c as setHubConnected, ct as deserializeTypedArrays, d as registerEventBusService, dt as CapabilityHandle, et as createAddonService, f as AddonDepsManager, ft as CapabilityUnavailableError, g as CapUsageRegistry, h as createHwAccelService, i as createUdsAddonContext, it as capActionSuffix, j as LocalChildClient, k as createUdsLogger, l as EVENT_TOPIC_PREFIX, lt as serializeTypedArrays, m as resolveHwAccel, mt as resolveAddonClass, n as adaptBrokerToCluster, nt as NATIVE_PROVIDER_SERVICE_INFIX, o as getOrInitReadinessRegistry, ot as capServiceName, p as createKernelHwAccel, pt as installManifestNativeDeps, q as buildNativeCapProxy, r as createAddonContext, rt as capActionName, s as getOrInitReadinessRegistryForClient, st as parseCapAction, t as installManifestPythonDeps, tt as validateProviderRegistrations, u as getBrokerEventBus, ut as DeviceRegistry, v as getCapUsageRegistry, w as localProviderLink, x as buildLinkChain, y as brokerCallForCap, z as callWithServiceDiscovery } from "./manifest-python-deps-
|
|
21
|
+
import { A as createUdsLoggerWithControl, B as createLocalTransport, C as ipcParentLink, D as createUdsEventBus, E as createUdsEventBridge, F as AGENT_CAP_FWD_SERVICE, G as FrameDecoder, H as UdsLocalTransportServer, I as CapRouteResolver, J as buildUdsNativeCapProxy, K as encodeFrame, L as CapRouteError, M as LocalChildRegistry, N as UDS_NO_ROUTE_PREFIX, O as udsChildLogToWorkerEntry, P as AGENT_CAP_FWD_ACTION, Q as mountNativeCapService, R as classifyCapRoute, S as ipcChildLink, T as createParentUnownedCallHandler, U as SocketChannel, V as UdsLocalTransportClient, W as localEndpointPath, Y as createBrokerDeviceManagerApi, _ as __resetCapUsageRegistryForTests, a as getWorkerDeviceRegistry, at as capBareAction, b as brokerTransportLink, c as setHubConnected, ct as deserializeTypedArrays, d as registerEventBusService, dt as CapabilityHandle, et as createAddonService, f as AddonDepsManager, ft as CapabilityUnavailableError, g as CapUsageRegistry, h as createHwAccelService, i as createUdsAddonContext, it as capActionSuffix, j as LocalChildClient, k as createUdsLogger, l as EVENT_TOPIC_PREFIX, lt as serializeTypedArrays, m as resolveHwAccel, mt as resolveAddonClass, n as adaptBrokerToCluster, nt as NATIVE_PROVIDER_SERVICE_INFIX, o as getOrInitReadinessRegistry, ot as capServiceName, p as createKernelHwAccel, pt as installManifestNativeDeps, q as buildNativeCapProxy, r as createAddonContext, rt as capActionName, s as getOrInitReadinessRegistryForClient, st as parseCapAction, t as installManifestPythonDeps, tt as validateProviderRegistrations, u as getBrokerEventBus, ut as DeviceRegistry, v as getCapUsageRegistry, w as localProviderLink, x as buildLinkChain, y as brokerCallForCap, z as callWithServiceDiscovery } from "./manifest-python-deps-1zTy3vXe.mjs";
|
|
22
22
|
import { t as CustomActionRegistry } from "./custom-action-registry-BEXwC-oo.mjs";
|
|
23
23
|
import { PYTHON_VERSION, buildBinaryPath, downloadBinary, ensureBinary, ensureFfmpeg, ensurePython, findInPath, getFfmpegDownloadUrl, getPlatformInfo, getPythonDownloadUrl, installPythonPackages, installPythonRequirements } from "@camstack/types/node";
|
|
24
24
|
import { request } from "node:http";
|
|
@@ -1288,11 +1288,19 @@ function createBrokerDeviceManagerApi(opts) {
|
|
|
1288
1288
|
deviceId: id,
|
|
1289
1289
|
data: spec.config
|
|
1290
1290
|
}).catch(() => {});
|
|
1291
|
-
const [initialRuntimeState,
|
|
1291
|
+
const [initialRuntimeState, loadedConfig, deviceMeta] = await Promise.all([
|
|
1292
1292
|
callDeviceManager(api, "loadRuntimeState", { deviceId: id }).catch(() => empty),
|
|
1293
1293
|
callDeviceManager(api, "loadConfig", { deviceId: id }).catch(() => empty),
|
|
1294
1294
|
callDeviceManager(api, "loadMeta", { deviceId: id }).catch(() => null)
|
|
1295
1295
|
]);
|
|
1296
|
+
let persistedConfig = loadedConfig;
|
|
1297
|
+
if (!isFirstSpawn && Object.keys(loadedConfig).length === 0 && Object.keys(spec.config).length > 0) {
|
|
1298
|
+
await callDeviceManager(api, "persistConfig", {
|
|
1299
|
+
deviceId: id,
|
|
1300
|
+
data: spec.config
|
|
1301
|
+
}).catch(() => {});
|
|
1302
|
+
persistedConfig = spec.config;
|
|
1303
|
+
}
|
|
1296
1304
|
const childCtx = buildContext(childStableId, id, parent.id, initialRuntimeState, persistedConfig, deviceMeta);
|
|
1297
1305
|
const child = spec.factory(childCtx);
|
|
1298
1306
|
await deviceApi.register(child);
|
|
@@ -1290,11 +1290,19 @@ function createBrokerDeviceManagerApi(opts) {
|
|
|
1290
1290
|
deviceId: id,
|
|
1291
1291
|
data: spec.config
|
|
1292
1292
|
}).catch(() => {});
|
|
1293
|
-
const [initialRuntimeState,
|
|
1293
|
+
const [initialRuntimeState, loadedConfig, deviceMeta] = await Promise.all([
|
|
1294
1294
|
callDeviceManager(api, "loadRuntimeState", { deviceId: id }).catch(() => empty),
|
|
1295
1295
|
callDeviceManager(api, "loadConfig", { deviceId: id }).catch(() => empty),
|
|
1296
1296
|
callDeviceManager(api, "loadMeta", { deviceId: id }).catch(() => null)
|
|
1297
1297
|
]);
|
|
1298
|
+
let persistedConfig = loadedConfig;
|
|
1299
|
+
if (!isFirstSpawn && Object.keys(loadedConfig).length === 0 && Object.keys(spec.config).length > 0) {
|
|
1300
|
+
await callDeviceManager(api, "persistConfig", {
|
|
1301
|
+
deviceId: id,
|
|
1302
|
+
data: spec.config
|
|
1303
|
+
}).catch(() => {});
|
|
1304
|
+
persistedConfig = spec.config;
|
|
1305
|
+
}
|
|
1298
1306
|
const childCtx = buildContext(childStableId, id, parent.id, initialRuntimeState, persistedConfig, deviceMeta);
|
|
1299
1307
|
const child = spec.factory(childCtx);
|
|
1300
1308
|
await deviceApi.register(child);
|