@camstack/types 1.2.447 → 1.2.449

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.
@@ -641,6 +641,8 @@ export interface SystemReadyStatePayload {
641
641
  readonly ts: number;
642
642
  readonly [key: string]: unknown;
643
643
  }
644
+ /** What a node update replaces — see {@link PendingRestartMarkerPayload.what}. */
645
+ export type NodeUpdateTarget = 'server' | 'desktop-shell' | 'container-image';
644
646
  /**
645
647
  * Payload carried on `system.restarting` (when the restart is being
646
648
  * scheduled) and `system.restart-completed` (after the new process
@@ -659,6 +661,13 @@ export interface SystemReadyStatePayload {
659
661
  */
660
662
  export interface PendingRestartMarkerPayload {
661
663
  readonly kind: 'framework-update' | 'manual' | 'system' | 'framework-bulk-update';
664
+ /**
665
+ * WHAT is being replaced when the restart is an update. Absent means the
666
+ * `@camstack/server` closure (every announcement predating the field):
667
+ * `desktop-shell` is the Electron app's own self-update, `container-image` a
668
+ * container that booted on a different image than its previous boot.
669
+ */
670
+ readonly what?: NodeUpdateTarget;
662
671
  readonly packageName?: string;
663
672
  readonly fromVersion?: string;
664
673
  readonly toVersion?: string;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The built-in palette of remote layout components (D973): what the template
3
+ * editor's "Add component" offers before any addon contributes more. The
4
+ * core-blocks builtin serves this list through the `remote-layout-components`
5
+ * cap; the built-in layout presets are composed from the same entries with
6
+ * `insertComponent`, so a preset and a hand-built layout use one vocabulary.
7
+ *
8
+ * Roles are the existing remote roles; where the vocabulary has no word
9
+ * (a generic minus / plus, a colour key, an app slot) the key is `custom:<key>`.
10
+ * Printed legends are data, not interface strings, so they are not translated.
11
+ */
12
+ import type { RemoteLayoutComponent } from './remote-components.js';
13
+ export declare const BUILTIN_REMOTE_COMPONENTS: readonly RemoteLayoutComponent[];
14
+ /** A built-in component by id (the presets compose from these). */
15
+ export declare function builtinRemoteComponent(id: string): RemoteLayoutComponent;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * A remote layout COMPONENT (D973): a reusable, named chunk of a remote — a
3
+ * D-pad, a keypad, a section divider — offered in the template editor's
4
+ * "Add component" palette. Pure data: the buttons are placed RELATIVE to the
5
+ * component, and the frame, shape and tone are names from the closed
6
+ * vocabularies the UI draws. An addon contributes components through the
7
+ * `remote-layout-components` cap and ships no UI code.
8
+ */
9
+ import { z } from 'zod';
10
+ export declare const REMOTE_COMPONENT_CATEGORIES: readonly ['power', 'navigation', 'volume', 'numbers', 'media', 'colour', 'apps', 'layout'];
11
+ export declare const RemoteComponentCategorySchema: z.ZodEnum<{
12
+ apps: "apps";
13
+ colour: "colour";
14
+ layout: "layout";
15
+ media: "media";
16
+ navigation: "navigation";
17
+ numbers: "numbers";
18
+ power: "power";
19
+ volume: "volume";
20
+ }>;
21
+ export type RemoteComponentCategory = z.infer<typeof RemoteComponentCategorySchema>;
22
+ export declare const MAX_COMPONENT_BUTTONS = 40;
23
+ export declare const RemoteComponentButtonSchema: z.ZodObject<{
24
+ idSuffix: z.ZodString;
25
+ row: z.ZodNumber;
26
+ col: z.ZodNumber;
27
+ rowSpan: z.ZodNumber;
28
+ colSpan: z.ZodNumber;
29
+ role: z.ZodString;
30
+ icon: z.ZodOptional<z.ZodString>;
31
+ label: z.ZodOptional<z.ZodString>;
32
+ shape: z.ZodOptional<z.ZodEnum<{
33
+ pill: "pill";
34
+ rect: "rect";
35
+ round: "round";
36
+ rounded: "rounded";
37
+ }>>;
38
+ tone: z.ZodOptional<z.ZodEnum<{
39
+ accent: "accent";
40
+ blue: "blue";
41
+ danger: "danger";
42
+ green: "green";
43
+ neutral: "neutral";
44
+ red: "red";
45
+ yellow: "yellow";
46
+ }>>;
47
+ }, z.core.$strip>;
48
+ export type RemoteComponentButton = z.infer<typeof RemoteComponentButtonSchema>;
49
+ export declare const RemoteLayoutComponentSchema: z.ZodObject<{
50
+ id: z.ZodString;
51
+ name: z.ZodString;
52
+ nameI18n: z.ZodOptional<z.ZodObject<{
53
+ en: z.ZodString;
54
+ it: z.ZodString;
55
+ }, z.core.$strip>>;
56
+ icon: z.ZodString;
57
+ category: z.ZodEnum<{
58
+ apps: "apps";
59
+ colour: "colour";
60
+ layout: "layout";
61
+ media: "media";
62
+ navigation: "navigation";
63
+ numbers: "numbers";
64
+ power: "power";
65
+ volume: "volume";
66
+ }>;
67
+ size: z.ZodObject<{
68
+ rows: z.ZodNumber;
69
+ cols: z.ZodNumber;
70
+ }, z.core.$strip>;
71
+ group: z.ZodNullable<z.ZodObject<{
72
+ frame: z.ZodEnum<{
73
+ divider: "divider";
74
+ dpad: "dpad";
75
+ keypad: "keypad";
76
+ none: "none";
77
+ panel: "panel";
78
+ "rocker-h": "rocker-h";
79
+ "rocker-v": "rocker-v";
80
+ }>;
81
+ title: z.ZodOptional<z.ZodString>;
82
+ }, z.core.$strip>>;
83
+ buttons: z.ZodArray<z.ZodObject<{
84
+ idSuffix: z.ZodString;
85
+ row: z.ZodNumber;
86
+ col: z.ZodNumber;
87
+ rowSpan: z.ZodNumber;
88
+ colSpan: z.ZodNumber;
89
+ role: z.ZodString;
90
+ icon: z.ZodOptional<z.ZodString>;
91
+ label: z.ZodOptional<z.ZodString>;
92
+ shape: z.ZodOptional<z.ZodEnum<{
93
+ pill: "pill";
94
+ rect: "rect";
95
+ round: "round";
96
+ rounded: "rounded";
97
+ }>>;
98
+ tone: z.ZodOptional<z.ZodEnum<{
99
+ accent: "accent";
100
+ blue: "blue";
101
+ danger: "danger";
102
+ green: "green";
103
+ neutral: "neutral";
104
+ red: "red";
105
+ yellow: "yellow";
106
+ }>>;
107
+ }, z.core.$strip>>;
108
+ }, z.core.$strip>;
109
+ export type RemoteLayoutComponent = z.infer<typeof RemoteLayoutComponentSchema>;
@@ -91,6 +91,42 @@ export declare const RemoteAssumedStateSchema: z.ZodObject<{
91
91
  export type RemoteAssumedState = z.infer<typeof RemoteAssumedStateSchema>;
92
92
  export declare const EMPTY_REMOTE_ASSUMED_STATE: RemoteAssumedState;
93
93
  export declare const MAX_LAYOUT_SPAN = 24;
94
+ export declare const MAX_LAYOUT_GROUPS = 50;
95
+ /**
96
+ * Closed vocabularies the UI knows how to DRAW (D973). A layout names a shape,
97
+ * a tone or a frame; it never carries a style. An addon that contributes a
98
+ * component picks from these lists — it ships no UI code.
99
+ */
100
+ export declare const REMOTE_BUTTON_SHAPES: readonly ['rect', 'rounded', 'round', 'pill'];
101
+ export declare const RemoteButtonShapeSchema: z.ZodEnum<{
102
+ pill: "pill";
103
+ rect: "rect";
104
+ round: "round";
105
+ rounded: "rounded";
106
+ }>;
107
+ export type RemoteButtonShape = z.infer<typeof RemoteButtonShapeSchema>;
108
+ export declare const REMOTE_BUTTON_TONES: readonly ['neutral', 'accent', 'danger', 'red', 'green', 'yellow', 'blue'];
109
+ export declare const RemoteButtonToneSchema: z.ZodEnum<{
110
+ accent: "accent";
111
+ blue: "blue";
112
+ danger: "danger";
113
+ green: "green";
114
+ neutral: "neutral";
115
+ red: "red";
116
+ yellow: "yellow";
117
+ }>;
118
+ export type RemoteButtonTone = z.infer<typeof RemoteButtonToneSchema>;
119
+ export declare const REMOTE_GROUP_FRAMES: readonly ['none', 'panel', 'divider', 'dpad', 'rocker-v', 'rocker-h', 'keypad'];
120
+ export declare const RemoteGroupFrameSchema: z.ZodEnum<{
121
+ divider: "divider";
122
+ dpad: "dpad";
123
+ keypad: "keypad";
124
+ none: "none";
125
+ panel: "panel";
126
+ "rocker-h": "rocker-h";
127
+ "rocker-v": "rocker-v";
128
+ }>;
129
+ export type RemoteGroupFrame = z.infer<typeof RemoteGroupFrameSchema>;
94
130
  export declare const RemoteLayoutButtonSchema: z.ZodObject<{
95
131
  id: z.ZodString;
96
132
  row: z.ZodNumber;
@@ -100,8 +136,56 @@ export declare const RemoteLayoutButtonSchema: z.ZodObject<{
100
136
  icon: z.ZodOptional<z.ZodString>;
101
137
  label: z.ZodOptional<z.ZodString>;
102
138
  role: z.ZodString;
139
+ shape: z.ZodOptional<z.ZodEnum<{
140
+ pill: "pill";
141
+ rect: "rect";
142
+ round: "round";
143
+ rounded: "rounded";
144
+ }>>;
145
+ tone: z.ZodOptional<z.ZodEnum<{
146
+ accent: "accent";
147
+ blue: "blue";
148
+ danger: "danger";
149
+ green: "green";
150
+ neutral: "neutral";
151
+ red: "red";
152
+ yellow: "yellow";
153
+ }>>;
154
+ groupId: z.ZodOptional<z.ZodString>;
103
155
  }, z.core.$strip>;
104
156
  export type RemoteLayoutButton = z.infer<typeof RemoteLayoutButtonSchema>;
157
+ /**
158
+ * A rectangle of the grid that moves as ONE thing and is drawn with a frame: a
159
+ * titled panel, a section divider, a D-pad ring. `componentId` names the palette
160
+ * entry it came from (informational: the layout is self-contained).
161
+ */
162
+ export declare const RemoteLayoutGroupSchema: z.ZodObject<{
163
+ id: z.ZodString;
164
+ componentId: z.ZodString;
165
+ frame: z.ZodEnum<{
166
+ divider: "divider";
167
+ dpad: "dpad";
168
+ keypad: "keypad";
169
+ none: "none";
170
+ panel: "panel";
171
+ "rocker-h": "rocker-h";
172
+ "rocker-v": "rocker-v";
173
+ }>;
174
+ row: z.ZodNumber;
175
+ col: z.ZodNumber;
176
+ rowSpan: z.ZodNumber;
177
+ colSpan: z.ZodNumber;
178
+ title: z.ZodOptional<z.ZodString>;
179
+ }, z.core.$strip>;
180
+ export type RemoteLayoutGroup = z.infer<typeof RemoteLayoutGroupSchema>;
181
+ export interface LayoutRect {
182
+ readonly row: number;
183
+ readonly col: number;
184
+ readonly rowSpan: number;
185
+ readonly colSpan: number;
186
+ }
187
+ export declare function rectsOverlap(a: LayoutRect, b: LayoutRect): boolean;
188
+ export declare function rectContains(outer: LayoutRect, inner: LayoutRect): boolean;
105
189
  export declare const RemoteLayoutPayloadSchema: z.ZodObject<{
106
190
  columns: z.ZodNumber;
107
191
  rows: z.ZodNumber;
@@ -114,6 +198,40 @@ export declare const RemoteLayoutPayloadSchema: z.ZodObject<{
114
198
  icon: z.ZodOptional<z.ZodString>;
115
199
  label: z.ZodOptional<z.ZodString>;
116
200
  role: z.ZodString;
201
+ shape: z.ZodOptional<z.ZodEnum<{
202
+ pill: "pill";
203
+ rect: "rect";
204
+ round: "round";
205
+ rounded: "rounded";
206
+ }>>;
207
+ tone: z.ZodOptional<z.ZodEnum<{
208
+ accent: "accent";
209
+ blue: "blue";
210
+ danger: "danger";
211
+ green: "green";
212
+ neutral: "neutral";
213
+ red: "red";
214
+ yellow: "yellow";
215
+ }>>;
216
+ groupId: z.ZodOptional<z.ZodString>;
117
217
  }, z.core.$strip>>;
218
+ groups: z.ZodOptional<z.ZodArray<z.ZodObject<{
219
+ id: z.ZodString;
220
+ componentId: z.ZodString;
221
+ frame: z.ZodEnum<{
222
+ divider: "divider";
223
+ dpad: "dpad";
224
+ keypad: "keypad";
225
+ none: "none";
226
+ panel: "panel";
227
+ "rocker-h": "rocker-h";
228
+ "rocker-v": "rocker-v";
229
+ }>;
230
+ row: z.ZodNumber;
231
+ col: z.ZodNumber;
232
+ rowSpan: z.ZodNumber;
233
+ colSpan: z.ZodNumber;
234
+ title: z.ZodOptional<z.ZodString>;
235
+ }, z.core.$strip>>>;
118
236
  }, z.core.$strip>;
119
237
  export type RemoteLayoutPayload = z.infer<typeof RemoteLayoutPayloadSchema>;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Pure edits of a remote layout that involve groups and components (D973).
3
+ * Shared by the template editor, the built-in presets and the server so an
4
+ * accepted edit is always a payload `RemoteLayoutPayloadSchema` accepts.
5
+ * Every function returns a NEW layout or a typed refusal; none mutates.
6
+ */
7
+ import type { RemoteLayoutComponent } from './remote-components.js';
8
+ import { type RemoteLayoutPayload } from './remote-config.js';
9
+ export declare const LAYOUT_EDIT_REFUSALS: readonly ['outside', 'overlap', 'unknown-group', 'too-many'];
10
+ export type LayoutEditRefusal = (typeof LAYOUT_EDIT_REFUSALS)[number];
11
+ export type LayoutEditResult = {
12
+ readonly ok: true;
13
+ readonly layout: RemoteLayoutPayload;
14
+ } | {
15
+ readonly ok: false;
16
+ readonly reason: LayoutEditRefusal;
17
+ };
18
+ export interface InsertedComponent {
19
+ readonly ok: true;
20
+ readonly layout: RemoteLayoutPayload;
21
+ /** The group created for the component, or null for a component of loose buttons. */
22
+ readonly groupId: string | null;
23
+ readonly buttonIds: readonly string[];
24
+ }
25
+ export type InsertComponentResult = InsertedComponent | {
26
+ readonly ok: false;
27
+ readonly reason: LayoutEditRefusal;
28
+ };
29
+ /** A button of a component, positioned relative to it. */
30
+ export type ComponentButtonSpec = RemoteLayoutComponent['buttons'][number];
31
+ export interface InsertOptions {
32
+ /** Multiply the component's rows / columns (and every button's span), e.g. a D-pad on a 12-column grid. */
33
+ readonly scale?: {
34
+ readonly rows?: number;
35
+ readonly cols?: number;
36
+ };
37
+ /** Extra relative buttons joined to this instance (the keypad's bottom-corner keys). */
38
+ readonly extras?: readonly ComponentButtonSpec[];
39
+ /** Replaces the component's own frame title ("Section" -> "Volume"). */
40
+ readonly title?: string;
41
+ }
42
+ /** The columns a component must be scaled by to span the whole grid width, or null when it does not divide. */
43
+ export declare function fillWidthScale(layout: RemoteLayoutPayload, component: RemoteLayoutComponent): number | null;
44
+ /**
45
+ * Put `component` on the layout with its top-left cell at `at`. A component
46
+ * with a group becomes one group whose rectangle is the whole component and
47
+ * whose members are its buttons; one without is a set of loose buttons. The
48
+ * grid does not grow: a component that does not fit is refused `outside`, one
49
+ * that would sit on an existing key or group `overlap`.
50
+ */
51
+ export declare function insertComponent(layout: RemoteLayoutPayload, component: RemoteLayoutComponent, at: {
52
+ readonly row: number;
53
+ readonly col: number;
54
+ }, options?: InsertOptions): InsertComponentResult;
55
+ /** Move a group and every member by the same offset, atomically. */
56
+ export declare function moveGroup(layout: RemoteLayoutPayload, groupId: string, to: {
57
+ readonly row: number;
58
+ readonly col: number;
59
+ }): LayoutEditResult;
60
+ /**
61
+ * Delete a group. With `keepButtons` its members stay where they are as loose
62
+ * keys; without, they go with it.
63
+ */
64
+ export declare function removeGroup(layout: RemoteLayoutPayload, groupId: string, options: {
65
+ readonly keepButtons: boolean;
66
+ }): LayoutEditResult;
67
+ /** Dissolve a group, keeping its buttons in place. */
68
+ export declare function ungroup(layout: RemoteLayoutPayload, groupId: string): LayoutEditResult;
@@ -6877,6 +6877,7 @@ var CAP_NAMES = Object.freeze([
6877
6877
  "recording-signal",
6878
6878
  "records",
6879
6879
  "remote",
6880
+ "remote-layout-components",
6880
6881
  "running-state",
6881
6882
  "scene-monitor",
6882
6883
  "script-runner",
@@ -6877,6 +6877,7 @@ var CAP_NAMES = Object.freeze([
6877
6877
  "recording-signal",
6878
6878
  "records",
6879
6879
  "remote",
6880
+ "remote-layout-components",
6880
6881
  "running-state",
6881
6882
  "scene-monitor",
6882
6883
  "script-runner",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.447",
3
+ "version": "1.2.449",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",