@camstack/system 1.2.439 → 1.2.440
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 +743 -79
- package/dist/addon-runner.mjs +743 -79
- package/dist/addon-utils.js +1 -1
- package/dist/addon-utils.mjs +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/block-settings-store.d.ts +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +77 -11
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +77 -12
- package/dist/builtins/core-blocks/index.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +181 -59
- package/dist/builtins/device-manager/device-manager.addon.mjs +180 -60
- package/dist/builtins/device-manager/device-removal-hooks.d.ts +0 -11
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +29 -11
- package/dist/builtins/keychain/index.mjs +29 -11
- package/dist/builtins/keychain/keychain-service.d.ts +8 -0
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +2 -2
- package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
- package/dist/builtins/local-network/local-network.addon.js +2 -2
- package/dist/builtins/local-network/local-network.addon.mjs +2 -2
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +38 -7
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +69 -3
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +69 -3
- package/dist/builtins/sqlite-storage/storage-admin-provider.d.ts +31 -0
- package/dist/builtins/storage-orchestrator/hub-settings-forward.d.ts +3 -3
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +4 -4
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +4 -4
- package/dist/builtins/system-config/system-config.addon.js +2 -2
- package/dist/builtins/system-config/system-config.addon.mjs +283 -283
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-BGOSCGWa.mjs → composition-sources-CS0D7imL.mjs} +1 -1
- package/dist/{composition-sources-B4jC2FC7.js → composition-sources-cBG8fBTu.js} +1 -1
- package/dist/{constants-B92BjObl.mjs → constants-CIzPjw7L.mjs} +1 -1
- package/dist/{constants-BRsjQwi-.js → constants-CRI3QzT4.js} +1 -1
- package/dist/{device-ca-46BUsWD1.mjs → device-ca-DLKXYseS.mjs} +1 -1
- package/dist/{device-ca-DHG9OW2m.js → device-ca-DNHjts4_.js} +1 -1
- package/dist/{dist-yI6kF6r6.mjs → dist-9fcsrFU3.mjs} +237 -25
- package/dist/{dist-BOWdLjoK.js → dist-BKhlcYz6.js} +254 -24
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-D7S5AJRU.js → hub-mdns-ciao-3Zc9G9MS.js} +1 -1
- package/dist/{hub-mdns-ciao-DGwVc2uh.mjs → hub-mdns-ciao-Dy2YjRqC.mjs} +1 -1
- package/dist/index.js +336 -336
- package/dist/index.mjs +337 -337
- package/dist/kernel/addon-settings-store.d.ts +43 -0
- package/dist/kernel/config-manager.d.ts +0 -19
- package/dist/kernel/device-settings-store.d.ts +74 -0
- package/dist/kernel/legacy-blob-guard.d.ts +58 -0
- package/dist/kernel/moleculer/runner-addon-settings.d.ts +34 -0
- package/dist/kernel/moleculer/runner-device-settings.d.ts +39 -0
- package/dist/kernel/prefix-walk.d.ts +39 -0
- package/dist/kernel/sections-store.d.ts +20 -0
- package/dist/kernel/settings-door-view.d.ts +2 -2
- package/dist/kernel/settings-view-types.d.ts +5 -30
- package/dist/kernel/store-settings-view.d.ts +0 -3
- package/dist/prefix-range-D_KueXbQ.js +27 -0
- package/dist/prefix-range-Dl0znowN.mjs +22 -0
- package/dist/prefix-walk-DAOBSyH1.mjs +88 -0
- package/dist/prefix-walk-Dv6MLZlM.js +99 -0
- package/dist/{restore-archive-DiGiI6Jp.js → restore-archive-49aZwkp8.js} +1 -1
- package/dist/{restore-archive-CpdUO-uS.mjs → restore-archive-DgvDecXM.mjs} +82 -82
- package/dist/{retired-settings-keys-UsVtLOT0.mjs → retired-settings-keys-Bhwe4ymb.mjs} +2 -2
- package/dist/{retired-settings-keys-CyQ7uvta.js → retired-settings-keys-D_VwZiDt.js} +10 -4
- package/dist/{wal-maintenance-xsvdT5Go.mjs → wal-maintenance-BZGmF-3U.mjs} +0 -0
- package/dist/{wal-maintenance-DEL_jeG0.js → wal-maintenance-C041zn6V.js} +0 -0
- package/package.json +5 -2
- package/dist/{custom-action-registry-Bf_YnagS.js → custom-action-registry-BKmoaqG0.js} +1 -1
- package/dist/{custom-action-registry-BQnbN0DP.mjs → custom-action-registry-CyUuhATc.mjs} +1 -1
|
@@ -3,8 +3,10 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
7
|
-
const
|
|
6
|
+
const require_dist = require("../../dist-BKhlcYz6.js");
|
|
7
|
+
const require_prefix_range = require("../../prefix-range-D_KueXbQ.js");
|
|
8
|
+
const require_prefix_walk = require("../../prefix-walk-Dv6MLZlM.js");
|
|
9
|
+
const require_retired_settings_keys = require("../../retired-settings-keys-D_VwZiDt.js");
|
|
8
10
|
let zod = require("zod");
|
|
9
11
|
let node_crypto = require("node:crypto");
|
|
10
12
|
let _camstack_types_node = require("@camstack/types/node");
|
|
@@ -2730,30 +2732,13 @@ async function listPersistedByAddon(pctx, input) {
|
|
|
2730
2732
|
return saved;
|
|
2731
2733
|
}
|
|
2732
2734
|
/**
|
|
2733
|
-
* Every requested device's persisted config
|
|
2734
|
-
*
|
|
2735
|
-
*
|
|
2736
|
-
* One call when the view can batch (the in-process door, which keys
|
|
2737
|
-
* `addon-device-settings` by `<addonId>:<deviceId>.` and answers a whole addon
|
|
2738
|
-
* with one indexed range scan). Otherwise the per-device form, unchanged — a
|
|
2739
|
-
* fallback and not a silent downgrade: `readDeviceStoreBatch` is optional
|
|
2740
|
-
* precisely because a forked addon's view has nothing to batch, and refusing
|
|
2741
|
-
* would break the only implementation that cannot comply.
|
|
2742
|
-
*
|
|
2743
|
-
* A read that THROWS yields `{}` for that device rather than failing the whole
|
|
2744
|
-
* listing: one unreadable settings row must not make the fleet unlistable.
|
|
2735
|
+
* Every requested device's persisted config in ONE store round trip (D870). A
|
|
2736
|
+
* store that cannot be asked THROWS and the listing fails with it: an
|
|
2737
|
+
* unreadable row is not a device with no settings (D49).
|
|
2745
2738
|
*/
|
|
2746
2739
|
async function readDeviceConfigs(pctx, deviceIds) {
|
|
2747
2740
|
if (deviceIds.length === 0) return /* @__PURE__ */ new Map();
|
|
2748
|
-
|
|
2749
|
-
if (batch !== void 0) return batch.call(pctx.settings, deviceIds);
|
|
2750
|
-
const out = /* @__PURE__ */ new Map();
|
|
2751
|
-
for (const id of deviceIds) try {
|
|
2752
|
-
out.set(id, await pctx.settings.readDeviceStore(id));
|
|
2753
|
-
} catch {
|
|
2754
|
-
out.set(id, {});
|
|
2755
|
-
}
|
|
2756
|
-
return out;
|
|
2741
|
+
return pctx.settings.readDeviceStoreBatch(deviceIds);
|
|
2757
2742
|
}
|
|
2758
2743
|
async function listAll(pctx, input) {
|
|
2759
2744
|
const ownerFilter = Reflect.get(input, "addonId");
|
|
@@ -4856,6 +4841,170 @@ function createDeviceManagerExtensionProvider(pctx) {
|
|
|
4856
4841
|
});
|
|
4857
4842
|
}
|
|
4858
4843
|
//#endregion
|
|
4844
|
+
//#region src/kernel/device-settings-store.ts
|
|
4845
|
+
/** The collection every addon's per-device settings share. Named nowhere else. */
|
|
4846
|
+
var DEVICE_SETTINGS_COLLECTION = "addon-device-settings";
|
|
4847
|
+
function scopeOf(addonId, deviceId) {
|
|
4848
|
+
return `${addonId}:${String(deviceId)}.`;
|
|
4849
|
+
}
|
|
4850
|
+
function assertDeviceId(deviceId) {
|
|
4851
|
+
if (!Number.isInteger(deviceId) || deviceId <= 0) throw new Error(`device settings: "${String(deviceId)}" is not a device id`);
|
|
4852
|
+
}
|
|
4853
|
+
function deviceIdOfSuffix(suffix) {
|
|
4854
|
+
const dot = suffix.indexOf(".");
|
|
4855
|
+
if (dot <= 0) return null;
|
|
4856
|
+
const id = Number(suffix.slice(0, dot));
|
|
4857
|
+
return Number.isInteger(id) && id > 0 ? id : null;
|
|
4858
|
+
}
|
|
4859
|
+
/** Every field row of one device scope, or a throw. */
|
|
4860
|
+
async function readScope(door, addonId, deviceId) {
|
|
4861
|
+
return require_prefix_walk.loadPrefixed(door, DEVICE_SETTINGS_COLLECTION, scopeOf(addonId, deviceId));
|
|
4862
|
+
}
|
|
4863
|
+
function createDeviceSettingsStore(door, addonId) {
|
|
4864
|
+
return {
|
|
4865
|
+
async read(deviceId) {
|
|
4866
|
+
try {
|
|
4867
|
+
assertDeviceId(deviceId);
|
|
4868
|
+
const value = await readScope(door, addonId, deviceId);
|
|
4869
|
+
return Object.keys(value).length === 0 ? { kind: "absent" } : {
|
|
4870
|
+
kind: "present",
|
|
4871
|
+
value
|
|
4872
|
+
};
|
|
4873
|
+
} catch (err) {
|
|
4874
|
+
return {
|
|
4875
|
+
kind: "unreadable",
|
|
4876
|
+
error: err instanceof Error ? err.message : String(err)
|
|
4877
|
+
};
|
|
4878
|
+
}
|
|
4879
|
+
},
|
|
4880
|
+
async readBatch(deviceIds) {
|
|
4881
|
+
const out = /* @__PURE__ */ new Map();
|
|
4882
|
+
if (deviceIds.length === 0) return out;
|
|
4883
|
+
for (const id of deviceIds) out.set(id, {});
|
|
4884
|
+
const wanted = new Set(deviceIds);
|
|
4885
|
+
const all = await require_prefix_walk.loadPrefixed(door, DEVICE_SETTINGS_COLLECTION, `${addonId}:`);
|
|
4886
|
+
for (const [suffix, value] of Object.entries(all)) {
|
|
4887
|
+
const id = deviceIdOfSuffix(suffix);
|
|
4888
|
+
if (id === null || !wanted.has(id)) continue;
|
|
4889
|
+
const blob = out.get(id);
|
|
4890
|
+
if (blob !== void 0) blob[suffix.slice(suffix.indexOf(".") + 1)] = value;
|
|
4891
|
+
}
|
|
4892
|
+
return out;
|
|
4893
|
+
},
|
|
4894
|
+
async listIds() {
|
|
4895
|
+
const all = await require_prefix_walk.loadPrefixed(door, DEVICE_SETTINGS_COLLECTION, `${addonId}:`, () => null);
|
|
4896
|
+
const ids = /* @__PURE__ */ new Set();
|
|
4897
|
+
for (const suffix of Object.keys(all)) {
|
|
4898
|
+
const id = deviceIdOfSuffix(suffix);
|
|
4899
|
+
if (id !== null) ids.add(id);
|
|
4900
|
+
}
|
|
4901
|
+
return [...ids].toSorted((a, b) => a - b);
|
|
4902
|
+
},
|
|
4903
|
+
async merge(deviceId, patch) {
|
|
4904
|
+
assertDeviceId(deviceId);
|
|
4905
|
+
const scope = scopeOf(addonId, deviceId);
|
|
4906
|
+
const records = [];
|
|
4907
|
+
const removed = [];
|
|
4908
|
+
for (const [key, value] of Object.entries(patch)) if (value === void 0) removed.push(`${scope}${key}`);
|
|
4909
|
+
else records.push({
|
|
4910
|
+
id: `${scope}${key}`,
|
|
4911
|
+
data: {
|
|
4912
|
+
addonId,
|
|
4913
|
+
deviceId: String(deviceId),
|
|
4914
|
+
key,
|
|
4915
|
+
value
|
|
4916
|
+
}
|
|
4917
|
+
});
|
|
4918
|
+
if (records.length === 0 && removed.length === 0) return;
|
|
4919
|
+
await door.transact({ ops: [...removed.length > 0 ? [{
|
|
4920
|
+
op: "deleteWhere",
|
|
4921
|
+
collection: DEVICE_SETTINGS_COLLECTION,
|
|
4922
|
+
filter: { whereIn: { id: removed } }
|
|
4923
|
+
}] : [], ...records.length > 0 ? [{
|
|
4924
|
+
op: "upsertMany",
|
|
4925
|
+
collection: DEVICE_SETTINGS_COLLECTION,
|
|
4926
|
+
conflict: ["id"],
|
|
4927
|
+
records
|
|
4928
|
+
}] : []] });
|
|
4929
|
+
},
|
|
4930
|
+
async clear(deviceId) {
|
|
4931
|
+
assertDeviceId(deviceId);
|
|
4932
|
+
const range = require_prefix_range.prefixRange(scopeOf(addonId, deviceId));
|
|
4933
|
+
if (range === null) throw new Error(`device settings: no id range for addon "${addonId}"`);
|
|
4934
|
+
await door.deleteWhere({
|
|
4935
|
+
collection: DEVICE_SETTINGS_COLLECTION,
|
|
4936
|
+
filter: { whereBetween: { id: [range.lo, range.hi] } }
|
|
4937
|
+
});
|
|
4938
|
+
}
|
|
4939
|
+
};
|
|
4940
|
+
}
|
|
4941
|
+
/** The `Record` form of a read: `{}` for a store that answered with no row, a THROW for one that did not. */
|
|
4942
|
+
async function readDeviceOrThrow(store, deviceId) {
|
|
4943
|
+
const read = await store.read(deviceId);
|
|
4944
|
+
switch (read.kind) {
|
|
4945
|
+
case "present": return { ...read.value };
|
|
4946
|
+
case "absent": return {};
|
|
4947
|
+
case "unreadable": throw new Error(`device settings of ${String(deviceId)} could not be read: ${read.error}`);
|
|
4948
|
+
}
|
|
4949
|
+
}
|
|
4950
|
+
/**
|
|
4951
|
+
* Remove a device's rows for EVERY addon, in one statement (D865's central
|
|
4952
|
+
* delete). Matched on the device id each row carries, so no addon needs a
|
|
4953
|
+
* handler. Returns how many rows went.
|
|
4954
|
+
*/
|
|
4955
|
+
async function clearDeviceSettings(door, deviceId) {
|
|
4956
|
+
assertDeviceId(deviceId);
|
|
4957
|
+
const { deleted } = await door.deleteWhere({
|
|
4958
|
+
collection: DEVICE_SETTINGS_COLLECTION,
|
|
4959
|
+
filter: { where: { deviceId: String(deviceId) } }
|
|
4960
|
+
});
|
|
4961
|
+
return deleted;
|
|
4962
|
+
}
|
|
4963
|
+
/** Rows one page of the scope walk asks for. */
|
|
4964
|
+
var SCOPE_PAGE_ROWS = 1e3;
|
|
4965
|
+
/** Pages the walk may take before it refuses (a bound, never a silent cut). */
|
|
4966
|
+
var SCOPE_PAGE_BUDGET = 512;
|
|
4967
|
+
/** Above every id: ids are ASCII. */
|
|
4968
|
+
var SCOPE_TAIL = "";
|
|
4969
|
+
/**
|
|
4970
|
+
* Every (addon, device) pair holding rows, across all addons - the admin
|
|
4971
|
+
* "deleted devices" listing. A keyset walk by primary key (never one query cut
|
|
4972
|
+
* at a row cap): a read that cannot be completed THROWS.
|
|
4973
|
+
*/
|
|
4974
|
+
async function listDeviceSettingsScopes(door) {
|
|
4975
|
+
const seen = /* @__PURE__ */ new Map();
|
|
4976
|
+
let cursor = "";
|
|
4977
|
+
for (let page = 0;; page++) {
|
|
4978
|
+
if (page >= SCOPE_PAGE_BUDGET) throw new Error(`device settings scopes: more than ${SCOPE_PAGE_BUDGET} pages - refusing a partial list`);
|
|
4979
|
+
const rows = await door.query({
|
|
4980
|
+
collection: DEVICE_SETTINGS_COLLECTION,
|
|
4981
|
+
filter: {
|
|
4982
|
+
whereBetween: { id: [cursor, SCOPE_TAIL] },
|
|
4983
|
+
orderBy: {
|
|
4984
|
+
field: "id",
|
|
4985
|
+
direction: "asc"
|
|
4986
|
+
},
|
|
4987
|
+
limit: SCOPE_PAGE_ROWS
|
|
4988
|
+
}
|
|
4989
|
+
});
|
|
4990
|
+
for (const row of rows) {
|
|
4991
|
+
const addonId = row.data["addonId"];
|
|
4992
|
+
const raw = row.data["deviceId"];
|
|
4993
|
+
if (typeof addonId !== "string" || typeof raw !== "string") continue;
|
|
4994
|
+
const deviceId = Number(raw);
|
|
4995
|
+
if (!Number.isInteger(deviceId) || deviceId <= 0) continue;
|
|
4996
|
+
seen.set(`${addonId}:${deviceId}`, {
|
|
4997
|
+
deviceId,
|
|
4998
|
+
addonId
|
|
4999
|
+
});
|
|
5000
|
+
}
|
|
5001
|
+
const last = rows[rows.length - 1];
|
|
5002
|
+
if (rows.length < SCOPE_PAGE_ROWS || last === void 0) return [...seen.values()];
|
|
5003
|
+
if (last.id === cursor) throw new Error(`device settings scopes: no progress at "${last.id}"`);
|
|
5004
|
+
cursor = last.id;
|
|
5005
|
+
}
|
|
5006
|
+
}
|
|
5007
|
+
//#endregion
|
|
4859
5008
|
//#region src/builtins/device-manager/migration-refused.ts
|
|
4860
5009
|
/**
|
|
4861
5010
|
* A migration step that REFUSED with nothing moved.
|
|
@@ -5788,41 +5937,16 @@ async function cleanupDeletedDevicesData(deps, input) {
|
|
|
5788
5937
|
unreachable: [...unreachable]
|
|
5789
5938
|
};
|
|
5790
5939
|
}
|
|
5791
|
-
/** The settings-store collection every addon's per-device settings share. */
|
|
5792
|
-
var ADDON_DEVICE_SETTINGS_COLLECTION = "addon-device-settings";
|
|
5793
|
-
/** The engine's hard ceiling on one read; a result this long may be a truncated one. */
|
|
5794
|
-
var SCOPE_READ_LIMIT = 2e4;
|
|
5795
5940
|
/** Scope access over the settings store; undefined when the store is unavailable. */
|
|
5796
5941
|
function settingsScopes(store) {
|
|
5797
5942
|
if (store === void 0) return void 0;
|
|
5943
|
+
const door = {
|
|
5944
|
+
query: (input) => store.query.query(input),
|
|
5945
|
+
deleteWhere: (input) => store.deleteWhere.mutate(input)
|
|
5946
|
+
};
|
|
5798
5947
|
return {
|
|
5799
|
-
list:
|
|
5800
|
-
|
|
5801
|
-
collection: ADDON_DEVICE_SETTINGS_COLLECTION,
|
|
5802
|
-
filter: { limit: SCOPE_READ_LIMIT }
|
|
5803
|
-
});
|
|
5804
|
-
if (rows.length >= SCOPE_READ_LIMIT) throw new Error(`the settings read returned ${rows.length} rows — possibly truncated`);
|
|
5805
|
-
const seen = /* @__PURE__ */ new Map();
|
|
5806
|
-
for (const row of rows) {
|
|
5807
|
-
const addonId = row.data["addonId"];
|
|
5808
|
-
const raw = row.data["deviceId"];
|
|
5809
|
-
if (typeof addonId !== "string" || typeof raw !== "string") continue;
|
|
5810
|
-
const deviceId = Number(raw);
|
|
5811
|
-
if (!Number.isInteger(deviceId) || deviceId <= 0) continue;
|
|
5812
|
-
seen.set(`${addonId}:${deviceId}`, {
|
|
5813
|
-
deviceId,
|
|
5814
|
-
addonId
|
|
5815
|
-
});
|
|
5816
|
-
}
|
|
5817
|
-
return [...seen.values()];
|
|
5818
|
-
},
|
|
5819
|
-
clear: async (deviceId) => {
|
|
5820
|
-
const { deleted } = await store.deleteWhere.mutate({
|
|
5821
|
-
collection: ADDON_DEVICE_SETTINGS_COLLECTION,
|
|
5822
|
-
filter: { where: { deviceId: String(deviceId) } }
|
|
5823
|
-
});
|
|
5824
|
-
return deleted;
|
|
5825
|
-
}
|
|
5948
|
+
list: () => listDeviceSettingsScopes(door),
|
|
5949
|
+
clear: (deviceId) => clearDeviceSettings(door, deviceId)
|
|
5826
5950
|
};
|
|
5827
5951
|
}
|
|
5828
5952
|
//#endregion
|
|
@@ -6267,11 +6391,7 @@ function removalSteps(pctx, deviceId, providerAddonId, deletedAt) {
|
|
|
6267
6391
|
run: async () => {
|
|
6268
6392
|
const api = pctx.host.ctx.api?.settingsStore;
|
|
6269
6393
|
if (api === void 0) throw new Error("settings-store api not available");
|
|
6270
|
-
|
|
6271
|
-
collection: "addon-device-settings",
|
|
6272
|
-
filter: { where: { deviceId: String(deviceId) } }
|
|
6273
|
-
});
|
|
6274
|
-
return deleted;
|
|
6394
|
+
return clearDeviceSettings({ deleteWhere: (input) => api.deleteWhere.mutate(input) }, deviceId);
|
|
6275
6395
|
}
|
|
6276
6396
|
},
|
|
6277
6397
|
{
|
|
@@ -11089,5 +11209,7 @@ var DeviceManagerAddon = class extends require_dist.BaseAddon {
|
|
|
11089
11209
|
//#endregion
|
|
11090
11210
|
exports.DeviceManagerAddon = DeviceManagerAddon;
|
|
11091
11211
|
exports.default = DeviceManagerAddon;
|
|
11212
|
+
exports.createDeviceSettingsStore = createDeviceSettingsStore;
|
|
11092
11213
|
exports.mergeAggregates = mergeAggregates;
|
|
11214
|
+
exports.readDeviceOrThrow = readDeviceOrThrow;
|
|
11093
11215
|
exports.setWrapperActive = setWrapperActive;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Ar as errMsg, Br as WELL_KNOWN_TAB_MAP, Bt as deviceStatusCapability, C as DAY_NAMES, Dr as DeviceFeature, En as normalizeUnit, Gn as runtimeStatePolicyFor, Ht as enumerateItemArrayFields, Kr as collectZodSecretPaths, Kt as expandContainer, Lt as deviceExtensionCapability, N as FieldClaimModeSchema, Nt as defineExtensionSlotProvider, Or as DeviceRole, Ot as createDeviceExtensionProvider, P as FieldClaimSchema, Qt as formatMinutes, Rt as deviceManagerCapability, Si as EventCategory, Ut as enumerateSchemaFields, V as MINUTES_PER_DAY, Y as STREAM_PROFILE_META, Zn as siteZoneKey, _i as sleep$1, ai as isSecretMarker, bi as transformSecretWrite, c as CAMERA_SWITCH_ORDER, dn as legacyAutoLinkIds, gi as secretTreeFromPaths, hn as locationIconKey, ht as buildStreamParamsConfigSchema, ii as isSecretClear, j as DeviceStatusSchema, jr as BaseAddon, kn as parseStreamParamsFormPatch, kr as DeviceType, mi as resolveSecretMarkers, oi as isSecretMarkerLike, r as ALL_CAPABILITY_DEFINITIONS, ri as isKeychainStoredField, ti as isDeviceConfigCap, u as CAP_NAMES_WITH_STATUS, vt as canonicalIconKey, xi as userError, yi as toSecretFieldView, zr as SECRET_CLEAR, zt as deviceStateCapability } from "../../dist-9fcsrFU3.mjs";
|
|
2
|
+
import { t as prefixRange } from "../../prefix-range-Dl0znowN.mjs";
|
|
3
|
+
import { t as loadPrefixed } from "../../prefix-walk-DAOBSyH1.mjs";
|
|
4
|
+
import { r as purgeRetiredSettingsRows } from "../../retired-settings-keys-Bhwe4ymb.mjs";
|
|
3
5
|
import { z } from "zod";
|
|
4
6
|
import { randomUUID } from "node:crypto";
|
|
5
7
|
import { canonicalDeviceFingerprint } from "@camstack/types/node";
|
|
@@ -2725,30 +2727,13 @@ async function listPersistedByAddon(pctx, input) {
|
|
|
2725
2727
|
return saved;
|
|
2726
2728
|
}
|
|
2727
2729
|
/**
|
|
2728
|
-
* Every requested device's persisted config
|
|
2729
|
-
*
|
|
2730
|
-
*
|
|
2731
|
-
* One call when the view can batch (the in-process door, which keys
|
|
2732
|
-
* `addon-device-settings` by `<addonId>:<deviceId>.` and answers a whole addon
|
|
2733
|
-
* with one indexed range scan). Otherwise the per-device form, unchanged — a
|
|
2734
|
-
* fallback and not a silent downgrade: `readDeviceStoreBatch` is optional
|
|
2735
|
-
* precisely because a forked addon's view has nothing to batch, and refusing
|
|
2736
|
-
* would break the only implementation that cannot comply.
|
|
2737
|
-
*
|
|
2738
|
-
* A read that THROWS yields `{}` for that device rather than failing the whole
|
|
2739
|
-
* listing: one unreadable settings row must not make the fleet unlistable.
|
|
2730
|
+
* Every requested device's persisted config in ONE store round trip (D870). A
|
|
2731
|
+
* store that cannot be asked THROWS and the listing fails with it: an
|
|
2732
|
+
* unreadable row is not a device with no settings (D49).
|
|
2740
2733
|
*/
|
|
2741
2734
|
async function readDeviceConfigs(pctx, deviceIds) {
|
|
2742
2735
|
if (deviceIds.length === 0) return /* @__PURE__ */ new Map();
|
|
2743
|
-
|
|
2744
|
-
if (batch !== void 0) return batch.call(pctx.settings, deviceIds);
|
|
2745
|
-
const out = /* @__PURE__ */ new Map();
|
|
2746
|
-
for (const id of deviceIds) try {
|
|
2747
|
-
out.set(id, await pctx.settings.readDeviceStore(id));
|
|
2748
|
-
} catch {
|
|
2749
|
-
out.set(id, {});
|
|
2750
|
-
}
|
|
2751
|
-
return out;
|
|
2736
|
+
return pctx.settings.readDeviceStoreBatch(deviceIds);
|
|
2752
2737
|
}
|
|
2753
2738
|
async function listAll(pctx, input) {
|
|
2754
2739
|
const ownerFilter = Reflect.get(input, "addonId");
|
|
@@ -4851,6 +4836,170 @@ function createDeviceManagerExtensionProvider(pctx) {
|
|
|
4851
4836
|
});
|
|
4852
4837
|
}
|
|
4853
4838
|
//#endregion
|
|
4839
|
+
//#region src/kernel/device-settings-store.ts
|
|
4840
|
+
/** The collection every addon's per-device settings share. Named nowhere else. */
|
|
4841
|
+
var DEVICE_SETTINGS_COLLECTION = "addon-device-settings";
|
|
4842
|
+
function scopeOf(addonId, deviceId) {
|
|
4843
|
+
return `${addonId}:${String(deviceId)}.`;
|
|
4844
|
+
}
|
|
4845
|
+
function assertDeviceId(deviceId) {
|
|
4846
|
+
if (!Number.isInteger(deviceId) || deviceId <= 0) throw new Error(`device settings: "${String(deviceId)}" is not a device id`);
|
|
4847
|
+
}
|
|
4848
|
+
function deviceIdOfSuffix(suffix) {
|
|
4849
|
+
const dot = suffix.indexOf(".");
|
|
4850
|
+
if (dot <= 0) return null;
|
|
4851
|
+
const id = Number(suffix.slice(0, dot));
|
|
4852
|
+
return Number.isInteger(id) && id > 0 ? id : null;
|
|
4853
|
+
}
|
|
4854
|
+
/** Every field row of one device scope, or a throw. */
|
|
4855
|
+
async function readScope(door, addonId, deviceId) {
|
|
4856
|
+
return loadPrefixed(door, DEVICE_SETTINGS_COLLECTION, scopeOf(addonId, deviceId));
|
|
4857
|
+
}
|
|
4858
|
+
function createDeviceSettingsStore(door, addonId) {
|
|
4859
|
+
return {
|
|
4860
|
+
async read(deviceId) {
|
|
4861
|
+
try {
|
|
4862
|
+
assertDeviceId(deviceId);
|
|
4863
|
+
const value = await readScope(door, addonId, deviceId);
|
|
4864
|
+
return Object.keys(value).length === 0 ? { kind: "absent" } : {
|
|
4865
|
+
kind: "present",
|
|
4866
|
+
value
|
|
4867
|
+
};
|
|
4868
|
+
} catch (err) {
|
|
4869
|
+
return {
|
|
4870
|
+
kind: "unreadable",
|
|
4871
|
+
error: err instanceof Error ? err.message : String(err)
|
|
4872
|
+
};
|
|
4873
|
+
}
|
|
4874
|
+
},
|
|
4875
|
+
async readBatch(deviceIds) {
|
|
4876
|
+
const out = /* @__PURE__ */ new Map();
|
|
4877
|
+
if (deviceIds.length === 0) return out;
|
|
4878
|
+
for (const id of deviceIds) out.set(id, {});
|
|
4879
|
+
const wanted = new Set(deviceIds);
|
|
4880
|
+
const all = await loadPrefixed(door, DEVICE_SETTINGS_COLLECTION, `${addonId}:`);
|
|
4881
|
+
for (const [suffix, value] of Object.entries(all)) {
|
|
4882
|
+
const id = deviceIdOfSuffix(suffix);
|
|
4883
|
+
if (id === null || !wanted.has(id)) continue;
|
|
4884
|
+
const blob = out.get(id);
|
|
4885
|
+
if (blob !== void 0) blob[suffix.slice(suffix.indexOf(".") + 1)] = value;
|
|
4886
|
+
}
|
|
4887
|
+
return out;
|
|
4888
|
+
},
|
|
4889
|
+
async listIds() {
|
|
4890
|
+
const all = await loadPrefixed(door, DEVICE_SETTINGS_COLLECTION, `${addonId}:`, () => null);
|
|
4891
|
+
const ids = /* @__PURE__ */ new Set();
|
|
4892
|
+
for (const suffix of Object.keys(all)) {
|
|
4893
|
+
const id = deviceIdOfSuffix(suffix);
|
|
4894
|
+
if (id !== null) ids.add(id);
|
|
4895
|
+
}
|
|
4896
|
+
return [...ids].toSorted((a, b) => a - b);
|
|
4897
|
+
},
|
|
4898
|
+
async merge(deviceId, patch) {
|
|
4899
|
+
assertDeviceId(deviceId);
|
|
4900
|
+
const scope = scopeOf(addonId, deviceId);
|
|
4901
|
+
const records = [];
|
|
4902
|
+
const removed = [];
|
|
4903
|
+
for (const [key, value] of Object.entries(patch)) if (value === void 0) removed.push(`${scope}${key}`);
|
|
4904
|
+
else records.push({
|
|
4905
|
+
id: `${scope}${key}`,
|
|
4906
|
+
data: {
|
|
4907
|
+
addonId,
|
|
4908
|
+
deviceId: String(deviceId),
|
|
4909
|
+
key,
|
|
4910
|
+
value
|
|
4911
|
+
}
|
|
4912
|
+
});
|
|
4913
|
+
if (records.length === 0 && removed.length === 0) return;
|
|
4914
|
+
await door.transact({ ops: [...removed.length > 0 ? [{
|
|
4915
|
+
op: "deleteWhere",
|
|
4916
|
+
collection: DEVICE_SETTINGS_COLLECTION,
|
|
4917
|
+
filter: { whereIn: { id: removed } }
|
|
4918
|
+
}] : [], ...records.length > 0 ? [{
|
|
4919
|
+
op: "upsertMany",
|
|
4920
|
+
collection: DEVICE_SETTINGS_COLLECTION,
|
|
4921
|
+
conflict: ["id"],
|
|
4922
|
+
records
|
|
4923
|
+
}] : []] });
|
|
4924
|
+
},
|
|
4925
|
+
async clear(deviceId) {
|
|
4926
|
+
assertDeviceId(deviceId);
|
|
4927
|
+
const range = prefixRange(scopeOf(addonId, deviceId));
|
|
4928
|
+
if (range === null) throw new Error(`device settings: no id range for addon "${addonId}"`);
|
|
4929
|
+
await door.deleteWhere({
|
|
4930
|
+
collection: DEVICE_SETTINGS_COLLECTION,
|
|
4931
|
+
filter: { whereBetween: { id: [range.lo, range.hi] } }
|
|
4932
|
+
});
|
|
4933
|
+
}
|
|
4934
|
+
};
|
|
4935
|
+
}
|
|
4936
|
+
/** The `Record` form of a read: `{}` for a store that answered with no row, a THROW for one that did not. */
|
|
4937
|
+
async function readDeviceOrThrow(store, deviceId) {
|
|
4938
|
+
const read = await store.read(deviceId);
|
|
4939
|
+
switch (read.kind) {
|
|
4940
|
+
case "present": return { ...read.value };
|
|
4941
|
+
case "absent": return {};
|
|
4942
|
+
case "unreadable": throw new Error(`device settings of ${String(deviceId)} could not be read: ${read.error}`);
|
|
4943
|
+
}
|
|
4944
|
+
}
|
|
4945
|
+
/**
|
|
4946
|
+
* Remove a device's rows for EVERY addon, in one statement (D865's central
|
|
4947
|
+
* delete). Matched on the device id each row carries, so no addon needs a
|
|
4948
|
+
* handler. Returns how many rows went.
|
|
4949
|
+
*/
|
|
4950
|
+
async function clearDeviceSettings(door, deviceId) {
|
|
4951
|
+
assertDeviceId(deviceId);
|
|
4952
|
+
const { deleted } = await door.deleteWhere({
|
|
4953
|
+
collection: DEVICE_SETTINGS_COLLECTION,
|
|
4954
|
+
filter: { where: { deviceId: String(deviceId) } }
|
|
4955
|
+
});
|
|
4956
|
+
return deleted;
|
|
4957
|
+
}
|
|
4958
|
+
/** Rows one page of the scope walk asks for. */
|
|
4959
|
+
var SCOPE_PAGE_ROWS = 1e3;
|
|
4960
|
+
/** Pages the walk may take before it refuses (a bound, never a silent cut). */
|
|
4961
|
+
var SCOPE_PAGE_BUDGET = 512;
|
|
4962
|
+
/** Above every id: ids are ASCII. */
|
|
4963
|
+
var SCOPE_TAIL = "";
|
|
4964
|
+
/**
|
|
4965
|
+
* Every (addon, device) pair holding rows, across all addons - the admin
|
|
4966
|
+
* "deleted devices" listing. A keyset walk by primary key (never one query cut
|
|
4967
|
+
* at a row cap): a read that cannot be completed THROWS.
|
|
4968
|
+
*/
|
|
4969
|
+
async function listDeviceSettingsScopes(door) {
|
|
4970
|
+
const seen = /* @__PURE__ */ new Map();
|
|
4971
|
+
let cursor = "";
|
|
4972
|
+
for (let page = 0;; page++) {
|
|
4973
|
+
if (page >= SCOPE_PAGE_BUDGET) throw new Error(`device settings scopes: more than ${SCOPE_PAGE_BUDGET} pages - refusing a partial list`);
|
|
4974
|
+
const rows = await door.query({
|
|
4975
|
+
collection: DEVICE_SETTINGS_COLLECTION,
|
|
4976
|
+
filter: {
|
|
4977
|
+
whereBetween: { id: [cursor, SCOPE_TAIL] },
|
|
4978
|
+
orderBy: {
|
|
4979
|
+
field: "id",
|
|
4980
|
+
direction: "asc"
|
|
4981
|
+
},
|
|
4982
|
+
limit: SCOPE_PAGE_ROWS
|
|
4983
|
+
}
|
|
4984
|
+
});
|
|
4985
|
+
for (const row of rows) {
|
|
4986
|
+
const addonId = row.data["addonId"];
|
|
4987
|
+
const raw = row.data["deviceId"];
|
|
4988
|
+
if (typeof addonId !== "string" || typeof raw !== "string") continue;
|
|
4989
|
+
const deviceId = Number(raw);
|
|
4990
|
+
if (!Number.isInteger(deviceId) || deviceId <= 0) continue;
|
|
4991
|
+
seen.set(`${addonId}:${deviceId}`, {
|
|
4992
|
+
deviceId,
|
|
4993
|
+
addonId
|
|
4994
|
+
});
|
|
4995
|
+
}
|
|
4996
|
+
const last = rows[rows.length - 1];
|
|
4997
|
+
if (rows.length < SCOPE_PAGE_ROWS || last === void 0) return [...seen.values()];
|
|
4998
|
+
if (last.id === cursor) throw new Error(`device settings scopes: no progress at "${last.id}"`);
|
|
4999
|
+
cursor = last.id;
|
|
5000
|
+
}
|
|
5001
|
+
}
|
|
5002
|
+
//#endregion
|
|
4854
5003
|
//#region src/builtins/device-manager/migration-refused.ts
|
|
4855
5004
|
/**
|
|
4856
5005
|
* A migration step that REFUSED with nothing moved.
|
|
@@ -5783,41 +5932,16 @@ async function cleanupDeletedDevicesData(deps, input) {
|
|
|
5783
5932
|
unreachable: [...unreachable]
|
|
5784
5933
|
};
|
|
5785
5934
|
}
|
|
5786
|
-
/** The settings-store collection every addon's per-device settings share. */
|
|
5787
|
-
var ADDON_DEVICE_SETTINGS_COLLECTION = "addon-device-settings";
|
|
5788
|
-
/** The engine's hard ceiling on one read; a result this long may be a truncated one. */
|
|
5789
|
-
var SCOPE_READ_LIMIT = 2e4;
|
|
5790
5935
|
/** Scope access over the settings store; undefined when the store is unavailable. */
|
|
5791
5936
|
function settingsScopes(store) {
|
|
5792
5937
|
if (store === void 0) return void 0;
|
|
5938
|
+
const door = {
|
|
5939
|
+
query: (input) => store.query.query(input),
|
|
5940
|
+
deleteWhere: (input) => store.deleteWhere.mutate(input)
|
|
5941
|
+
};
|
|
5793
5942
|
return {
|
|
5794
|
-
list:
|
|
5795
|
-
|
|
5796
|
-
collection: ADDON_DEVICE_SETTINGS_COLLECTION,
|
|
5797
|
-
filter: { limit: SCOPE_READ_LIMIT }
|
|
5798
|
-
});
|
|
5799
|
-
if (rows.length >= SCOPE_READ_LIMIT) throw new Error(`the settings read returned ${rows.length} rows — possibly truncated`);
|
|
5800
|
-
const seen = /* @__PURE__ */ new Map();
|
|
5801
|
-
for (const row of rows) {
|
|
5802
|
-
const addonId = row.data["addonId"];
|
|
5803
|
-
const raw = row.data["deviceId"];
|
|
5804
|
-
if (typeof addonId !== "string" || typeof raw !== "string") continue;
|
|
5805
|
-
const deviceId = Number(raw);
|
|
5806
|
-
if (!Number.isInteger(deviceId) || deviceId <= 0) continue;
|
|
5807
|
-
seen.set(`${addonId}:${deviceId}`, {
|
|
5808
|
-
deviceId,
|
|
5809
|
-
addonId
|
|
5810
|
-
});
|
|
5811
|
-
}
|
|
5812
|
-
return [...seen.values()];
|
|
5813
|
-
},
|
|
5814
|
-
clear: async (deviceId) => {
|
|
5815
|
-
const { deleted } = await store.deleteWhere.mutate({
|
|
5816
|
-
collection: ADDON_DEVICE_SETTINGS_COLLECTION,
|
|
5817
|
-
filter: { where: { deviceId: String(deviceId) } }
|
|
5818
|
-
});
|
|
5819
|
-
return deleted;
|
|
5820
|
-
}
|
|
5943
|
+
list: () => listDeviceSettingsScopes(door),
|
|
5944
|
+
clear: (deviceId) => clearDeviceSettings(door, deviceId)
|
|
5821
5945
|
};
|
|
5822
5946
|
}
|
|
5823
5947
|
//#endregion
|
|
@@ -6262,11 +6386,7 @@ function removalSteps(pctx, deviceId, providerAddonId, deletedAt) {
|
|
|
6262
6386
|
run: async () => {
|
|
6263
6387
|
const api = pctx.host.ctx.api?.settingsStore;
|
|
6264
6388
|
if (api === void 0) throw new Error("settings-store api not available");
|
|
6265
|
-
|
|
6266
|
-
collection: "addon-device-settings",
|
|
6267
|
-
filter: { where: { deviceId: String(deviceId) } }
|
|
6268
|
-
});
|
|
6269
|
-
return deleted;
|
|
6389
|
+
return clearDeviceSettings({ deleteWhere: (input) => api.deleteWhere.mutate(input) }, deviceId);
|
|
6270
6390
|
}
|
|
6271
6391
|
},
|
|
6272
6392
|
{
|
|
@@ -11082,4 +11202,4 @@ var DeviceManagerAddon = class extends BaseAddon {
|
|
|
11082
11202
|
}
|
|
11083
11203
|
};
|
|
11084
11204
|
//#endregion
|
|
11085
|
-
export { DeviceManagerAddon, DeviceManagerAddon as default, mergeAggregates, setWrapperActive as t };
|
|
11205
|
+
export { DeviceManagerAddon, DeviceManagerAddon as default, mergeAggregates, readDeviceOrThrow as n, setWrapperActive as r, createDeviceSettingsStore as t };
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* device-manager's side of `device-removal-hook` (D865): tell every implementer
|
|
3
|
-
* a device was deleted, and answer the admin question "which stored data belongs
|
|
4
|
-
* to devices that no longer exist?".
|
|
5
|
-
*
|
|
6
|
-
* Two entry points, one rule: **an implementer is told to delete only on a
|
|
7
|
-
* recorded delete (a tombstone), or on an explicit operator confirm.** Nothing
|
|
8
|
-
* here infers a deletion from a device being absent from a single read.
|
|
9
|
-
*/
|
|
10
1
|
import { type CleanupDeletedDevicesResult, type DeviceDataEntry, type DeviceRemovedInput, type DeviceRemovedResult, type IScopedLogger, type OrphanDeviceData, type SettingsStoreClient } from "@camstack/types";
|
|
11
2
|
import type { RemovalCleanup, RemovalStep } from "./removal-cleanup.js";
|
|
12
3
|
/** The capability name implementers register under. */
|
|
@@ -97,7 +88,5 @@ export interface CleanupDeps {
|
|
|
97
88
|
export declare function cleanupDeletedDevicesData(deps: CleanupDeps, input: {
|
|
98
89
|
readonly confirm: boolean;
|
|
99
90
|
}): Promise<CleanupDeletedDevicesResult>;
|
|
100
|
-
/** The settings-store collection every addon's per-device settings share. */
|
|
101
|
-
export declare const ADDON_DEVICE_SETTINGS_COLLECTION = "addon-device-settings";
|
|
102
91
|
/** Scope access over the settings store; undefined when the store is unavailable. */
|
|
103
92
|
export declare function settingsScopes(store: Pick<SettingsStoreClient, "query" | "deleteWhere"> | undefined): SettingsScopeAccess | undefined;
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BKhlcYz6.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
9
9
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { gn as logDestinationCapability, jr as BaseAddon } from "../../dist-9fcsrFU3.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
4
4
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|