@camstack/ui-library 1.2.291 → 1.2.292

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.
Files changed (88) hide show
  1. package/dist/{MaskShapeCanvas-DI4BY7W2.js → MaskShapeCanvas-C9cJlxvG.js} +3 -1
  2. package/dist/{MaskShapeCanvas-BByN3jvt.cjs → MaskShapeCanvas-NCNwu9_5.cjs} +3 -1
  3. package/dist/{MotionZonesSettings-CiYjd-yl.js → MotionZonesSettings-Bv8XzCa3.js} +45 -48
  4. package/dist/{MotionZonesSettings-BK9R9NIr.cjs → MotionZonesSettings-CPRH536-.cjs} +44 -47
  5. package/dist/{PrivacyMaskSettings-DuXUCUev.cjs → PrivacyMaskSettings-BUWvVF_n.cjs} +33 -42
  6. package/dist/{PrivacyMaskSettings-BmRdUrPp.js → PrivacyMaskSettings-BlkbESYj.js} +34 -43
  7. package/dist/{SceneMonitorEditor-COgAjtq5.cjs → SceneMonitorEditor-D_jkzQ2o.cjs} +189 -86
  8. package/dist/{SceneMonitorEditor-J4Ix_0tu.js → SceneMonitorEditor-i3-nXAEU.js} +190 -87
  9. package/dist/composites/addon-global-settings-form.d.ts +0 -12
  10. package/dist/composites/cap-settings/AutotrackSection.d.ts +0 -16
  11. package/dist/composites/cap-settings/CameraGridLayoutEditor.d.ts +0 -21
  12. package/dist/composites/cap-settings/ConsumablesPanel.d.ts +0 -18
  13. package/dist/composites/cap-settings/MaskShapeCanvas.d.ts +0 -102
  14. package/dist/composites/cap-settings/MotionZonesSettings.d.ts +0 -38
  15. package/dist/composites/cap-settings/SceneReferenceGallery.d.ts +0 -38
  16. package/dist/composites/cap-settings/scene-monitor-copy.d.ts +12 -6
  17. package/dist/composites/clips/clip-source-state.d.ts +3 -2
  18. package/dist/composites/clips/clip-thumbnail-fetch.d.ts +2 -1
  19. package/dist/composites/clips/clip-tile-media.d.ts +3 -2
  20. package/dist/composites/clips/clip-view-state.d.ts +2 -1
  21. package/dist/composites/confirm-dialog.d.ts +0 -62
  22. package/dist/composites/data-table.d.ts +2 -11
  23. package/dist/composites/detection-canvas.d.ts +0 -9
  24. package/dist/composites/detection-result-tree.d.ts +0 -12
  25. package/dist/composites/device-controls/container-primary-hero.d.ts +0 -17
  26. package/dist/composites/device-controls/humidifier-control.d.ts +0 -17
  27. package/dist/composites/device-controls/lawn-mower-control.d.ts +2 -1
  28. package/dist/composites/device-controls/pet-feeder-panel.d.ts +0 -18
  29. package/dist/composites/device-controls/script-automation-controls.d.ts +2 -1
  30. package/dist/composites/device-controls/sensor-hero-card.d.ts +0 -18
  31. package/dist/composites/device-controls/update-control.d.ts +0 -13
  32. package/dist/composites/device-controls/vacuum-control.d.ts +2 -1
  33. package/dist/composites/device-controls/valve-control.d.ts +2 -1
  34. package/dist/composites/device-controls/weather-control.d.ts +2 -1
  35. package/dist/composites/device-item/actions.d.ts +0 -22
  36. package/dist/composites/device-item/helpers.d.ts +2 -1
  37. package/dist/composites/device-item/index.d.ts +0 -9
  38. package/dist/composites/device-list/batch-actions-bar.d.ts +0 -11
  39. package/dist/composites/device-list/filter-chips.d.ts +0 -13
  40. package/dist/composites/device-list/page-size-select.d.ts +2 -1
  41. package/dist/composites/device-list/url-state.d.ts +2 -3
  42. package/dist/composites/device-meta.d.ts +14 -7
  43. package/dist/composites/device-picker/DevicePicker.d.ts +1 -1
  44. package/dist/composites/device-picker/device-filter-bar.d.ts +2 -1
  45. package/dist/composites/device-picker/device-parent.d.ts +2 -1
  46. package/dist/composites/device-picker/device-selection-rows.d.ts +6 -1
  47. package/dist/composites/device-selector-picker.d.ts +25 -1
  48. package/dist/composites/device-step-matrix.d.ts +0 -26
  49. package/dist/composites/error-box.d.ts +0 -15
  50. package/dist/composites/event-stream.d.ts +2 -1
  51. package/dist/composites/extensions/extensions-view-state.d.ts +2 -1
  52. package/dist/composites/hls-quality.d.ts +3 -2
  53. package/dist/composites/index.d.ts +0 -2
  54. package/dist/composites/notification-targets-field.d.ts +2 -2
  55. package/dist/composites/pipeline-matrix-shared.d.ts +2 -1
  56. package/dist/composites/provider-entries/AddProviderEntryDialog.d.ts +1 -1
  57. package/dist/composites/provider-entries/ProviderEntryPills.d.ts +1 -1
  58. package/dist/composites/ptz-overlay.d.ts +0 -19
  59. package/dist/composites/qr-code.d.ts +0 -14
  60. package/dist/composites/scope-picker.d.ts +2 -1
  61. package/dist/composites/step-inspector/layered-settings-form.d.ts +0 -11
  62. package/dist/composites/step-inspector/step-inspector-panel.d.ts +0 -6
  63. package/dist/composites/stream-broker-selector.d.ts +0 -21
  64. package/dist/composites/training/TrainingBaseModelPicker.d.ts +0 -10
  65. package/dist/composites/training/retrain-review-badge.d.ts +2 -1
  66. package/dist/composites/webrtc-diagnostics/endpoint-test.d.ts +2 -1
  67. package/dist/composites/webrtc-diagnostics/nat-mapping.d.ts +2 -1
  68. package/dist/composites/webrtc-diagnostics/session-run.d.ts +2 -1
  69. package/dist/composites/webrtc-diagnostics/session-verdict.d.ts +2 -1
  70. package/dist/contexts/ui-text.d.ts +49 -0
  71. package/dist/generated/system-hooks.d.ts +4 -0
  72. package/dist/i18n/addon-i18n.d.ts +46 -0
  73. package/dist/i18n/index.d.ts +2 -0
  74. package/dist/i18n/use-addon-t.d.ts +57 -0
  75. package/dist/index.cjs +3287 -2356
  76. package/dist/index.d.ts +2 -0
  77. package/dist/index.js +3275 -2356
  78. package/dist/lib/format-last-seen.d.ts +15 -1
  79. package/dist/lib/phase-config.d.ts +9 -3
  80. package/dist/lib/pipeline-mirror.d.ts +2 -1
  81. package/package.json +1 -1
  82. package/dist/composites/data-table/data-table-header.d.ts +0 -11
  83. package/dist/composites/data-table/data-table-pagination.d.ts +0 -10
  84. package/dist/composites/data-table/data-table-row.d.ts +0 -11
  85. package/dist/composites/data-table/data-table.d.ts +0 -3
  86. package/dist/composites/data-table/index.d.ts +0 -2
  87. package/dist/composites/data-table/types.d.ts +0 -34
  88. package/dist/composites/data-table-layout.d.ts +0 -31
@@ -1,24 +1,3 @@
1
- /**
2
- * StreamBrokerSelector — reusable per-device "preferred stream" picker.
3
- *
4
- * Renders a single `<Select>` with options sourced from the device's
5
- * camera-streams cap (`getRtspEntries`). The first option is always
6
- * "Auto (best available)"; remaining options are one per enabled
7
- * RTSP restream entry, labelled by stream profile (`High` / `Mid` /
8
- * `Low` …) and tagged with codec + resolution when the broker reports
9
- * them.
10
- *
11
- * Used by addon-built panels that don't flow through the form-builder
12
- * `ConfigUISchema` aggregator (the cap-driven aggregator already
13
- * embeds an equivalent `select` field with server-resolved options —
14
- * the addons return the same list inline). Reach for this composite
15
- * when you need an out-of-form selector in a bespoke React tree (e.g.
16
- * an addon's wizard page, a debug panel, etc.).
17
- *
18
- * Loading / empty / error states all render a degraded select rather
19
- * than vanishing — the operator can always pick `Auto` even if the
20
- * device's broker is currently unreachable.
21
- */
22
1
  import { type ReactElement } from "react";
23
2
  export interface StreamBrokerSelectorProps {
24
3
  readonly deviceId: number;
@@ -1,13 +1,3 @@
1
- /**
2
- * TrainingBaseModelPicker — select trainable base models for a new training
3
- * job. Each row lists every cluster placement where that model is the
4
- * effective root detector (`node · device`), or “Not in use on any node”.
5
- *
6
- * Default is multi-select: Select-all-roots picks the roots the cluster
7
- * actually runs; Clear empties. Pass `multiple={false}` for one model at a
8
- * time (radio-like); “Select cluster root” picks the first cluster root (or
9
- * a recommended root when present).
10
- */
11
1
  import type { JSX } from "react";
12
2
  import { type TrainingBaseModelPlacement } from "./root-detector-placements";
13
3
  export type { TrainingBaseModelPlacement };
@@ -17,6 +17,7 @@
17
17
  import type { ReactElement } from "react";
18
18
  import type { RetrainReviewStatusName } from "@camstack/types";
19
19
  import { type BadgeProps, type BadgeSize, type BadgeStyle, type BadgeVariant } from "../../primitives/badge";
20
+ import { type UiTextFn } from "../../contexts/ui-text";
20
21
  /** A review verdict, plus the pre-confirmation `draft` state. */
21
22
  export type RetrainReviewBadgeKind = RetrainReviewStatusName | "draft";
22
23
  export interface RetrainReviewBadgeLook {
@@ -27,7 +28,7 @@ export interface RetrainReviewBadgeLook {
27
28
  readonly className: string;
28
29
  }
29
30
  /** The badge look for a verdict. Pure. */
30
- export declare function retrainReviewBadgeLook(kind: RetrainReviewBadgeKind): RetrainReviewBadgeLook;
31
+ export declare function retrainReviewBadgeLook(kind: RetrainReviewBadgeKind, t?: UiTextFn): RetrainReviewBadgeLook;
31
32
  export interface RetrainReviewBadgeProps extends Omit<BadgeProps, "variant" | "style" | "children" | "dashed"> {
32
33
  readonly kind: RetrainReviewBadgeKind;
33
34
  readonly approximate?: boolean;
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import { type GatherResult, type IceServerConfig, type RelayLoopbackResult } from "./endpoint-probe";
7
7
  import { type NatMappingVerdict, type SrflxObservation } from "./nat-mapping";
8
+ import { type UiTextFn } from "../../contexts/ui-text";
8
9
  export type IceEndpointScheme = "stun" | "turn" | "turns" | "other";
9
10
  export interface IceEndpoint extends IceServerConfig {
10
11
  /** Stable key: the URL is unique within the flattened list. */
@@ -56,4 +57,4 @@ export declare function testEndpoint(endpoint: IceEndpoint): Promise<EndpointTes
56
57
  /** The STUN destinations the NAT check queries: configured first, public fallbacks to reach two. */
57
58
  export declare function natCheckDestinations(endpoints: readonly IceEndpoint[]): readonly string[];
58
59
  export declare function srflxObservations(gather: GatherResult): readonly SrflxObservation[];
59
- export declare function runNatCheck(endpoints: readonly IceEndpoint[]): Promise<NatCheckResult>;
60
+ export declare function runNatCheck(endpoints: readonly IceEndpoint[], t?: UiTextFn): Promise<NatCheckResult>;
@@ -16,6 +16,7 @@
16
16
  * `likely`, never `confirmed`, because it cannot be told apart from the second
17
17
  * server simply not answering.
18
18
  */
19
+ import { type UiTextFn } from "../../contexts/ui-text";
19
20
  export interface SrflxObservation {
20
21
  readonly address: string;
21
22
  readonly port: number;
@@ -41,4 +42,4 @@ export interface NatMappingVerdict {
41
42
  * this check is about plain STUN binding.
42
43
  */
43
44
  export declare function distinctStunDestinations(urls: readonly string[]): readonly string[];
44
- export declare function compareSrflxMappings(observations: readonly SrflxObservation[], stunDestinationsQueried: number): NatMappingVerdict;
45
+ export declare function compareSrflxMappings(observations: readonly SrflxObservation[], stunDestinationsQueried: number, t?: UiTextFn): NatMappingVerdict;
@@ -12,6 +12,7 @@
12
12
  * Every number in the report is `null` until something measured it (D393).
13
13
  */
14
14
  import type { WebrtcSessionDebug } from "@camstack/types";
15
+ import { type UiTextFn } from "../../contexts/ui-text";
15
16
  import type { StreamDebugSample, WebrtcDebugStats } from "../stream-debug/webrtc-debug-stats";
16
17
  import { type HubCandidateSummary, type IceCandidateType, type ParsedIceCandidate } from "./ice-candidates";
17
18
  import { type DiagnosticIcePolicy, type SessionVerdict } from "./session-verdict";
@@ -135,4 +136,4 @@ export interface HubSessionRunReport {
135
136
  readonly serverError: string | null;
136
137
  readonly verdict: SessionVerdict;
137
138
  }
138
- export declare function finalizeSessionRun(state: SessionRunState, durationMs: number): HubSessionRunReport;
139
+ export declare function finalizeSessionRun(state: SessionRunState, durationMs: number, t?: UiTextFn): HubSessionRunReport;
@@ -7,6 +7,7 @@
7
7
  * A layer whose deciding number was not measured makes the verdict `unknown`
8
8
  * — a guessed verdict is the thing an operator trusts and stops measuring.
9
9
  */
10
+ import { type UiTextFn } from "../../contexts/ui-text";
10
11
  import type { HubReachabilityFlag } from "./ice-candidates";
11
12
  export type SessionVerdictLayer = "transport" | "hub-dtls" | "media-black-hole" | "hub-not-sending" | "loss-keyframe" | "healthy" | "unknown";
12
13
  export interface SessionVerdict {
@@ -35,4 +36,4 @@ export interface VerdictInput {
35
36
  export declare const PLI_STORM_COUNT = 3;
36
37
  /** Packet loss over the run above which a freeze is attributed to loss. */
37
38
  export declare const LOSS_PERCENT_HIGH = 2;
38
- export declare function classifySessionVerdict(input: VerdictInput): SessionVerdict;
39
+ export declare function classifySessionVerdict(input: VerdictInput, t?: UiTextFn): SessionVerdict;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * The words a shared composite shows, resolved by the HOST.
3
+ *
4
+ * Serves the strings of ui-library's OWN components (tables, pickers, badges
5
+ * and the like). The strings of an addon's pages and widgets are served by
6
+ * `createAddonI18n` / `useAddonT` in `../i18n`; both follow the admin language
7
+ * (the admin sets `<html lang>` AND mounts `AdminUiTextProvider`).
8
+ *
9
+ * This package ships no catalogue and no i18n dependency. A composite asks
10
+ * `useUiText()` for `t(key, english, vars?)`: the English text is the fallback
11
+ * and the key is what the host's catalogue (the admin UI's `i18n/*.json`, under
12
+ * `uiLibrary.*`) translates. Without a provider the English fallback is
13
+ * rendered, `{{var}}` interpolated, so a spec or a standalone page needs no
14
+ * set-up.
15
+ *
16
+ * - Plurals: pass `count` and a `{ one, other }` fallback; the host resolves
17
+ * `key_one` / `key_other`. Never build a plural with a ternary suffix.
18
+ * - Sentences with inline elements: `<UiTrans uiKey fallback components />`,
19
+ * the fallback marks each element as `<0>…</0>`, `<1>…</1>` and the host
20
+ * translates the whole sentence. Never concatenate fragments around elements.
21
+ */
22
+ import { type ReactElement, type ReactNode } from "react";
23
+ export type UiTextVars = Readonly<Record<string, string | number | boolean | null | undefined>>;
24
+ /** The English fallback: one string, or `{ one, other }` for a counted noun. */
25
+ export type UiTextFallback = string | {
26
+ readonly one: string;
27
+ readonly other: string;
28
+ };
29
+ export interface UiTextOptions extends UiTextVars {
30
+ readonly count?: number;
31
+ }
32
+ export type UiTextFn = (key: string, fallback: UiTextFallback, vars?: UiTextOptions) => string;
33
+ /** English fallback with `{{var}}` interpolation; what renders without a host. */
34
+ export declare const defaultUiText: UiTextFn;
35
+ export declare function UiTextProvider({ t, children }: {
36
+ readonly t: UiTextFn;
37
+ readonly children: ReactNode;
38
+ }): ReactElement;
39
+ export declare function useUiText(): UiTextFn;
40
+ /** Split `a <0>b</0> c` into text and `components[0]` wrapped around `b`. */
41
+ export declare function renderTagged(text: string, components: readonly ReactElement[]): readonly ReactNode[];
42
+ export interface UiTransProps {
43
+ readonly uiKey: string;
44
+ readonly fallback: UiTextFallback;
45
+ readonly components?: readonly ReactElement[];
46
+ readonly values?: UiTextOptions;
47
+ }
48
+ /** A translated sentence whose `<0>…</0>` spans are wrapped in `components[0]`. */
49
+ export declare function UiTrans({ uiKey, fallback, components, values }: UiTransProps): ReactElement;
@@ -597,6 +597,10 @@ export declare const useDeviceManagerEnable: typeof trpc.deviceManager.enable.us
597
597
  export declare const useDeviceManagerDisable: typeof trpc.deviceManager.disable.useMutation;
598
598
  /** Generated alias around `trpc.deviceManager.remove.useMutation`. */
599
599
  export declare const useDeviceManagerRemove: typeof trpc.deviceManager.remove.useMutation;
600
+ /** Generated alias around `trpc.deviceManager.listDeletedSince.useQuery`. */
601
+ export declare const useDeviceManagerListDeletedSince: typeof trpc.deviceManager.listDeletedSince.useQuery;
602
+ /** Generated alias around `trpc.deviceManager.cleanupDeletedDevicesData.useMutation`. */
603
+ export declare const useDeviceManagerCleanupDeletedDevicesData: typeof trpc.deviceManager.cleanupDeletedDevicesData.useMutation;
600
604
  /** Generated alias around `trpc.deviceManager.removeByIntegration.useMutation`. */
601
605
  export declare const useDeviceManagerRemoveByIntegration: typeof trpc.deviceManager.removeByIntegration.useMutation;
602
606
  /** Generated alias around `trpc.deviceManager.getStreamProfileMap.useQuery`. */
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Translation core for the pages and widgets an addon ships.
3
+ *
4
+ * Serves the strings of an ADDON's own pages and widgets. The strings of
5
+ * ui-library's own components are served by `useUiText` in
6
+ * `../contexts/ui-text`; both follow the admin language (the admin sets
7
+ * `<html lang>` AND mounts `AdminUiTextProvider`).
8
+ *
9
+ * Why this is not i18next: an addon page is a Module Federation remote and
10
+ * i18next is NOT a shared singleton (`addon-admin-ui/vite.config.ts`), so a
11
+ * remote cannot reach the host's instance. This module lives in the ui-library,
12
+ * which IS the host-shared singleton, so every remote sees the same registry.
13
+ *
14
+ * Two seams keep call sites stable when the hub starts serving bundles
15
+ * (`translations.getBundle({ lang, ns })`):
16
+ * - bundles enter ONLY through {@link registerAddonBundle}; a call site never
17
+ * imports a JSON file, it asks `useAddonT(ns)`;
18
+ * - the language comes ONLY from {@link currentAddonLanguage}, which reads the
19
+ * `lang` attribute the host admin sets on `<html>` (and falls back to the
20
+ * browser language for a host-less page such as the agent dashboard).
21
+ */
22
+ /** A translation bundle: nested keys, leaves are message strings. */
23
+ export interface TranslationTree {
24
+ readonly [key: string]: string | TranslationTree;
25
+ }
26
+ /** Values interpolated into `{{name}}` placeholders; a numeric `count` also picks the plural form. */
27
+ export type TranslationVars = Readonly<Record<string, string | number>>;
28
+ /** `status.ok_one` / `status.ok_other` are addressed as `status.ok`. */
29
+ type StripPlural<K extends string> = K extends `${infer Base}_${"zero" | "one" | "two" | "few" | "many" | "other"}` ? Base : K;
30
+ /** Every dotted key a bundle answers, plural variants collapsed to their base. */
31
+ export type TranslationKey<T> = { [K in keyof T & string]: T[K] extends string ? StripPlural<K> : `${K}.${TranslationKey<T[K]>}` }[keyof T & string];
32
+ /** Lower-cased primary subtag: `it-IT` -> `it`. */
33
+ export declare function normalizeLanguage(raw: string | null | undefined): string;
34
+ /** The language the host admin shows, else the browser's, else English. */
35
+ export declare function currentAddonLanguage(): string;
36
+ /** Install (or replace) one language of one namespace. Subscribers re-render. */
37
+ export declare function registerAddonBundle(ns: string, lang: string, tree: TranslationTree): void;
38
+ /** Subscribe to bundle changes AND to the host switching language. */
39
+ export declare function subscribeAddonI18n(listener: () => void): () => void;
40
+ /** Changes whenever a rendered string could differ (new bundle, new language). */
41
+ export declare function addonI18nSnapshot(): string;
42
+ /** Replace `{{name}}` placeholders; an unknown name is left visible. */
43
+ export declare function interpolate(message: string, vars: TranslationVars | undefined): string;
44
+ /** Resolve a key in `lang`, then in English; an unknown key answers itself. */
45
+ export declare function translateAddonKey(ns: string, lang: string, key: string, vars?: TranslationVars): string;
46
+ export {};
@@ -0,0 +1,2 @@
1
+ export { currentAddonLanguage, normalizeLanguage, registerAddonBundle, type TranslationKey, type TranslationTree, type TranslationVars, translateAddonKey } from "./addon-i18n";
2
+ export { type AddonBundles, type AddonI18n, type AddonT, type AddonTFunction, type AddonTransProps, createAddonI18n, renderMarkup, useAddonT } from "./use-addon-t";
@@ -0,0 +1,57 @@
1
+ import { type ReactElement, type ReactNode } from "react";
2
+ import { type TranslationKey, type TranslationTree, type TranslationVars } from "./addon-i18n";
3
+ /** Translate one key of the namespace this function was made for. */
4
+ export type AddonTFunction<K extends string = string> = (key: K, vars?: TranslationVars) => string;
5
+ export interface AddonT<K extends string = string> {
6
+ readonly t: AddonTFunction<K>;
7
+ /** The language in effect (`en`, `it`, ...). */
8
+ readonly lang: string;
9
+ }
10
+ /**
11
+ * `t` for one addon namespace. The language is the host's; `langOverride` is
12
+ * for a widget the host hands an explicit language (the pre-auth login page).
13
+ * Prefer the typed `useT` that
14
+ * {@link createAddonI18n} returns; this is the untyped form behind it.
15
+ */
16
+ export declare function useAddonT<K extends string = string>(ns: string, langOverride?: string): AddonT<K>;
17
+ /**
18
+ * Render a message that mixes text with inline elements. The message marks them
19
+ * with named tags (`Delete <b>{{name}}</b>?`); `components` maps each tag name
20
+ * to the element that wraps its content. Placeholders are interpolated into
21
+ * the text nodes only, so a value containing `<` can never become markup.
22
+ */
23
+ export declare function renderMarkup(message: string, components: Readonly<Record<string, ReactElement>>, vars: TranslationVars | undefined): ReactNode[];
24
+ export interface AddonTransProps<K extends string> {
25
+ readonly i18nKey: K;
26
+ readonly values?: TranslationVars;
27
+ /** Tag name used in the message -> the element wrapping that tag's content. */
28
+ readonly components?: Readonly<Record<string, ReactElement>>;
29
+ }
30
+ export interface AddonI18n<K extends string> {
31
+ readonly ns: string;
32
+ /** Typed `t` bound to this addon's namespace. */
33
+ readonly useT: (langOverride?: string) => AddonT<K>;
34
+ /**
35
+ * `t` outside React (a class component, a helper that builds an error
36
+ * message): answers in the language in effect NOW, does not re-render.
37
+ */
38
+ readonly translate: AddonTFunction<K>;
39
+ /** A sentence with inline elements; never concatenate translated fragments. */
40
+ readonly Trans: (props: AddonTransProps<K>) => ReactElement;
41
+ }
42
+ export type AddonBundles<T extends TranslationTree> = {
43
+ readonly en: T;
44
+ } & Readonly<Record<string, TranslationTree>>;
45
+ /**
46
+ * Register an addon's bundled JSON under its namespace and return the hooks its
47
+ * components use. The bundles are only the INITIAL content of the registry: a
48
+ * later hub-served bundle replaces them through `registerAddonBundle` and no
49
+ * call site changes.
50
+ *
51
+ * ```ts
52
+ * import en from './en.json'
53
+ * import it from './it.json'
54
+ * export const { useT, Trans } = createAddonI18n('model-studio', { en, it })
55
+ * ```
56
+ */
57
+ export declare function createAddonI18n<T extends TranslationTree>(ns: string, bundles: AddonBundles<T>): AddonI18n<TranslationKey<T>>;