@fluid-app/portal-core 0.1.19 → 0.1.21

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.
@@ -0,0 +1,373 @@
1
+ import { a as WidgetSchema, o as WidgetType } from "./widget-schema-BSX2fVhW.cjs";
2
+ import { d as ColorOptions, n as AlignOptions, p as FontSizeOptions, t as StrictOmit, x as SectionLayoutType } from "./index-B5cTNde-.cjs";
3
+ import { ComponentType } from "react";
4
+ import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
5
+
6
+ //#region src/registries/property-schema-types.d.ts
7
+ /**
8
+ * Tab configuration for organizing properties
9
+ */
10
+ interface TabConfig {
11
+ /** Unique identifier for the tab */
12
+ id: string;
13
+ /** Display label for the tab */
14
+ label: string;
15
+ }
16
+ /**
17
+ * Property field type constant - single source of truth for field types.
18
+ * Use PROPERTY_FIELD_TYPES.text instead of "text" for type-safe comparisons.
19
+ */
20
+ declare const PROPERTY_FIELD_TYPES: {
21
+ readonly text: "text";
22
+ readonly textarea: "textarea";
23
+ readonly number: "number";
24
+ readonly boolean: "boolean";
25
+ readonly select: "select";
26
+ readonly color: "color";
27
+ readonly range: "range";
28
+ readonly dataSource: "dataSource";
29
+ readonly resource: "resource";
30
+ readonly image: "image";
31
+ readonly alignment: "alignment";
32
+ readonly slider: "slider";
33
+ readonly colorPicker: "colorPicker";
34
+ readonly sectionHeader: "sectionHeader";
35
+ readonly separator: "separator";
36
+ readonly buttonGroup: "buttonGroup";
37
+ readonly colorSelect: "colorSelect";
38
+ readonly sectionLayoutSelect: "sectionLayoutSelect";
39
+ readonly background: "background";
40
+ readonly contentPosition: "contentPosition";
41
+ readonly textSizeSelect: "textSizeSelect";
42
+ readonly cssUnit: "cssUnit";
43
+ };
44
+ /**
45
+ * Union type of all property field types, derived from PROPERTY_FIELD_TYPES constant.
46
+ * @see deriving-typeof-for-object-keys pattern
47
+ */
48
+ type PropertyFieldType = (typeof PROPERTY_FIELD_TYPES)[keyof typeof PROPERTY_FIELD_TYPES];
49
+ /**
50
+ * Runtime validation for property field types.
51
+ * @param value - The value to check
52
+ * @returns true if value is a valid PropertyFieldType
53
+ */
54
+ declare function isPropertyFieldType(value: string): value is PropertyFieldType;
55
+ /**
56
+ * Base schema for a property field
57
+ */
58
+ interface PropertyFieldSchema {
59
+ /** Property key in the widget props */
60
+ key: string;
61
+ /** Display label for the field */
62
+ label: string;
63
+ /** Field type determines the input control */
64
+ type: PropertyFieldType;
65
+ /** Optional description/help text */
66
+ description?: string;
67
+ /** Optional default value */
68
+ defaultValue?: unknown;
69
+ /** Optional tab ID (must match a TabConfig id if widget has tabsConfig) */
70
+ tab?: string;
71
+ /** Optional group for organizing fields within a tab */
72
+ group?: string;
73
+ /**
74
+ * @deprecated Use requiresKeyValue instead
75
+ */
76
+ requiresKeyToBeTrue?: string;
77
+ /** Optional requires a specific key to have a specific value */
78
+ requiresKeyValue?: {
79
+ key: string;
80
+ value: unknown;
81
+ };
82
+ }
83
+ /**
84
+ * Text field schema
85
+ */
86
+ interface TextFieldSchema extends PropertyFieldSchema {
87
+ type: "text";
88
+ placeholder?: string;
89
+ maxLength?: number;
90
+ }
91
+ /**
92
+ * Textarea field schema
93
+ */
94
+ interface TextareaFieldSchema extends PropertyFieldSchema {
95
+ type: "textarea";
96
+ placeholder?: string;
97
+ rows?: number;
98
+ maxLength?: number;
99
+ }
100
+ /**
101
+ * Number field schema
102
+ */
103
+ interface NumberFieldSchema extends PropertyFieldSchema {
104
+ type: "number";
105
+ min?: number;
106
+ max?: number;
107
+ step?: number;
108
+ }
109
+ /**
110
+ * Boolean field schema
111
+ */
112
+ interface BooleanFieldSchema extends PropertyFieldSchema {
113
+ type: "boolean";
114
+ }
115
+ /**
116
+ * Select field schema with type-safe option values.
117
+ * Uses StrictOmit to ensure "defaultValue" key exists on PropertyFieldSchema.
118
+ */
119
+ interface SelectFieldSchema<T extends string | number = string | number> extends StrictOmit<PropertyFieldSchema, "defaultValue"> {
120
+ type: "select";
121
+ options: Array<{
122
+ label: string;
123
+ value: T;
124
+ }>;
125
+ defaultValue?: T;
126
+ }
127
+ /**
128
+ * Color field schema
129
+ */
130
+ interface ColorFieldSchema extends PropertyFieldSchema {
131
+ type: "color";
132
+ }
133
+ /**
134
+ * Range slider field schema
135
+ */
136
+ interface RangeFieldSchema extends PropertyFieldSchema {
137
+ type: "range";
138
+ min: number;
139
+ max: number;
140
+ step?: number;
141
+ }
142
+ /**
143
+ * Data source field schema for configuring widget data sources
144
+ */
145
+ interface DataSourceFieldSchema extends PropertyFieldSchema {
146
+ type: "dataSource";
147
+ }
148
+ /**
149
+ * Resource field schema for selecting a single resource from the selection modal
150
+ */
151
+ interface ResourceFieldSchema extends PropertyFieldSchema {
152
+ type: "resource";
153
+ /** Optional filter to specific shareable types */
154
+ allowedTypes?: string[];
155
+ }
156
+ /**
157
+ * Image field schema for selecting a single image from the image picker
158
+ */
159
+ interface ImageFieldSchema extends PropertyFieldSchema {
160
+ type: "image";
161
+ }
162
+ /**
163
+ * Alignment field schema
164
+ */
165
+ interface AlignmentFieldSchema extends PropertyFieldSchema {
166
+ type: "alignment";
167
+ options: {
168
+ verticalEnabled: boolean;
169
+ horizontalEnabled: boolean;
170
+ };
171
+ defaultValue?: AlignOptions;
172
+ }
173
+ /**
174
+ * Slider field schema with optional unit suffix (e.g., "rem", "px")
175
+ */
176
+ interface SliderFieldSchema extends PropertyFieldSchema {
177
+ type: "slider";
178
+ min: number;
179
+ max: number;
180
+ step?: number;
181
+ unit?: string;
182
+ }
183
+ /**
184
+ * Color picker field schema with optional swatches
185
+ */
186
+ interface ColorPickerFieldSchema extends PropertyFieldSchema {
187
+ type: "colorPicker";
188
+ swatches?: string[];
189
+ }
190
+ /**
191
+ * Section header field schema for visual grouping
192
+ */
193
+ interface SectionHeaderFieldSchema extends PropertyFieldSchema {
194
+ type: "sectionHeader";
195
+ subtitle?: string;
196
+ }
197
+ /**
198
+ * Separator field schema for visual separation
199
+ */
200
+ interface SeparatorFieldSchema extends PropertyFieldSchema {
201
+ type: "separator";
202
+ }
203
+ /**
204
+ * Button group field schema.
205
+ * Uses StrictOmit to ensure "defaultValue" key exists on PropertyFieldSchema.
206
+ */
207
+ interface ButtonGroupFieldSchema<T extends string | number = string | number> extends StrictOmit<PropertyFieldSchema, "defaultValue"> {
208
+ type: "buttonGroup";
209
+ options: Array<{
210
+ label?: string;
211
+ icon?: IconDefinition;
212
+ value: T;
213
+ }>;
214
+ defaultValue?: T;
215
+ }
216
+ /**
217
+ * Color select field schema
218
+ */
219
+ interface ColorSelectFieldSchema extends PropertyFieldSchema {
220
+ type: "colorSelect";
221
+ defaultValue?: ColorOptions;
222
+ }
223
+ /**
224
+ * Section layout select field schema for visual masonry layout selector
225
+ */
226
+ interface SectionLayoutSelectFieldSchema extends PropertyFieldSchema {
227
+ type: "sectionLayoutSelect";
228
+ defaultValue?: SectionLayoutType;
229
+ }
230
+ /**
231
+ * Background field combines resource selection and color properties.
232
+ * Uses StrictOmit to exclude conflicting "type" discriminant from parents.
233
+ */
234
+ interface BackgroundFieldSchema extends StrictOmit<ResourceFieldSchema, "type">, StrictOmit<ColorFieldSchema, "type"> {
235
+ type: "background";
236
+ }
237
+ /**
238
+ * Content position field schema for 3x3 grid position picker
239
+ */
240
+ interface ContentPositionFieldSchema extends PropertyFieldSchema {
241
+ type: "contentPosition";
242
+ defaultValue?: string;
243
+ }
244
+ /**
245
+ * Text size select field schema for visual font size selector
246
+ */
247
+ interface TextSizeSelectFieldSchema extends PropertyFieldSchema {
248
+ type: "textSizeSelect";
249
+ defaultValue?: FontSizeOptions;
250
+ }
251
+ /**
252
+ * CSS unit type for height/width fields
253
+ */
254
+ type CssUnit = "px" | "rem" | "vh" | "%";
255
+ /**
256
+ * CSS unit field schema for numeric values with selectable units (px, rem, vh, %)
257
+ */
258
+ interface CssUnitFieldSchema extends PropertyFieldSchema {
259
+ type: "cssUnit";
260
+ minByUnit?: Partial<Record<CssUnit, number>>;
261
+ maxByUnit?: Partial<Record<CssUnit, number>>;
262
+ stepByUnit?: Partial<Record<CssUnit, number>>;
263
+ allowedUnits?: CssUnit[];
264
+ defaultUnit?: CssUnit;
265
+ }
266
+ /**
267
+ * Union of all field schema types
268
+ */
269
+ type PropertyField = TextFieldSchema | TextareaFieldSchema | NumberFieldSchema | BooleanFieldSchema | SelectFieldSchema<string | number> | ColorFieldSchema | RangeFieldSchema | DataSourceFieldSchema | ResourceFieldSchema | ImageFieldSchema | AlignmentFieldSchema | SliderFieldSchema | ColorPickerFieldSchema | SectionHeaderFieldSchema | SeparatorFieldSchema | ButtonGroupFieldSchema<string | number> | ColorSelectFieldSchema | SectionLayoutSelectFieldSchema | BackgroundFieldSchema | ContentPositionFieldSchema | TextSizeSelectFieldSchema | CssUnitFieldSchema;
270
+ /**
271
+ * Schema for per-item configuration in custom data sources.
272
+ * Widgets can define this to allow users to configure widget-specific
273
+ * settings for each selected item (e.g., title, description, button).
274
+ */
275
+ interface ItemConfigSchema {
276
+ /** Fields available for per-item configuration */
277
+ fields: PropertyField[];
278
+ /** Optional description shown at top of item config panel */
279
+ description?: string;
280
+ }
281
+ /**
282
+ * Schema for a widget's editable properties
283
+ */
284
+ interface WidgetPropertySchema {
285
+ /** Widget type this schema applies to */
286
+ widgetType: WidgetType;
287
+ /** Display name for the widget */
288
+ displayName: string;
289
+ /** Optional tab configuration - if present, tabs are enabled */
290
+ tabsConfig?: TabConfig[];
291
+ /** Editable property fields */
292
+ fields: PropertyField[];
293
+ /** Optional custom validator function */
294
+ validate?: (props: Record<string, unknown>) => string | null;
295
+ /** Props that can be populated from data sources */
296
+ dataSourceTargetProps?: string[];
297
+ /** Optional schema for per-item configurations in custom data sources */
298
+ itemConfigSchema?: ItemConfigSchema;
299
+ }
300
+ /**
301
+ * Registry mapping widget types to their property schemas
302
+ */
303
+ type PropertySchemaRegistry = Record<WidgetType, WidgetPropertySchema>;
304
+ /**
305
+ * Group property fields by their group property
306
+ */
307
+ declare function groupPropertyFields(fields: readonly PropertyField[]): Record<string, PropertyField[]>;
308
+ /**
309
+ * Extract current values from widget props based on property fields
310
+ */
311
+ declare function extractPropertyValues(widget: Readonly<WidgetSchema>, fields: readonly PropertyField[]): Record<string, unknown>;
312
+ /**
313
+ * Apply property values to widget props
314
+ */
315
+ declare function applyPropertyValues(widget: Readonly<WidgetSchema>, values: Readonly<Record<string, unknown>>): WidgetSchema;
316
+ //#endregion
317
+ //#region src/registries/container-types.d.ts
318
+ /**
319
+ * Interface for container widget behavior.
320
+ * Container widgets can hold and manage child widgets.
321
+ * Note: Children can be null for sparse arrays (e.g., grid layouts with empty cells)
322
+ */
323
+ interface ContainerWidgetBehavior {
324
+ /** Identifies this widget type as a container */
325
+ isContainer: true;
326
+ /** Gets children from the widget's props */
327
+ getChildren: (props: Record<string, unknown>) => (WidgetSchema | null)[];
328
+ /** Creates new props with updated children */
329
+ setChildren: (props: Record<string, unknown>, children: (WidgetSchema | null)[]) => Record<string, unknown>;
330
+ /** Optional: Check if this container accepts a specific widget type */
331
+ canAcceptChild?: (childType: string) => boolean;
332
+ }
333
+ //#endregion
334
+ //#region src/registries/widget-manifest.d.ts
335
+ /**
336
+ * The manifest a plugin author provides to register a custom widget.
337
+ * Required fields ensure the widget works in both builder and SDK contexts.
338
+ * Optional fields enable advanced behavior (containers, min SDK version).
339
+ */
340
+ interface WidgetManifest {
341
+ /** Schema version for forward compatibility. Currently must be 1. */
342
+ manifestVersion: number;
343
+ /** Unique widget type identifier (e.g., "StockTickerWidget"). */
344
+ type: string;
345
+ /** The React component that renders this widget. */
346
+ component: ComponentType<any>;
347
+ /** Human-readable name shown in the builder palette. */
348
+ displayName: string;
349
+ /** Brief description shown in the builder palette. */
350
+ description: string;
351
+ /** Icon identifier for the builder palette (e.g., "chart-line"). */
352
+ icon: string;
353
+ /** Category ID for palette grouping (e.g., "components", "blocks", "utility"). */
354
+ category: string;
355
+ /** Property schema defining editable fields in the builder's property panel. */
356
+ propertySchema: WidgetPropertySchema;
357
+ /** Default prop values when the widget is first created. */
358
+ defaultProps: Record<string, unknown>;
359
+ /** Container behavior — only if this widget can hold child widgets. */
360
+ container?: ContainerWidgetBehavior;
361
+ /** Minimum SDK version required (e.g., "1.0.0"). */
362
+ minSdkVersion?: string;
363
+ /** Resizable configuration. */
364
+ resizable?: {
365
+ horizontal?: boolean;
366
+ vertical?: boolean;
367
+ minWidth?: number;
368
+ minHeight?: number;
369
+ };
370
+ }
371
+ //#endregion
372
+ export { TextFieldSchema as A, ResourceFieldSchema as C, SeparatorFieldSchema as D, SelectFieldSchema as E, extractPropertyValues as F, groupPropertyFields as I, isPropertyFieldType as L, TextareaFieldSchema as M, WidgetPropertySchema as N, SliderFieldSchema as O, applyPropertyValues as P, RangeFieldSchema as S, SectionLayoutSelectFieldSchema as T, PROPERTY_FIELD_TYPES as _, BooleanFieldSchema as a, PropertyFieldType as b, ColorPickerFieldSchema as c, CssUnit as d, CssUnitFieldSchema as f, NumberFieldSchema as g, ItemConfigSchema as h, BackgroundFieldSchema as i, TextSizeSelectFieldSchema as j, TabConfig as k, ColorSelectFieldSchema as l, ImageFieldSchema as m, ContainerWidgetBehavior as n, ButtonGroupFieldSchema as o, DataSourceFieldSchema as p, AlignmentFieldSchema as r, ColorFieldSchema as s, WidgetManifest as t, ContentPositionFieldSchema as u, PropertyField as v, SectionHeaderFieldSchema as w, PropertySchemaRegistry as x, PropertyFieldSchema as y };
373
+ //# sourceMappingURL=widget-manifest-Ei8Wnspj.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-manifest-Ei8Wnspj.d.cts","names":[],"sources":["../src/registries/property-schema-types.ts","../src/registries/container-types.ts","../src/registries/widget-manifest.ts"],"mappings":"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"}
@@ -87,8 +87,13 @@ function groupChildrenByColumn(children, columnCount) {
87
87
  }
88
88
  //#endregion
89
89
  //#region src/widget-utils/utils.ts
90
- function createWidgetRegistry(registry) {
91
- return registry;
90
+ function createWidgetRegistry(registry, plugins) {
91
+ if (!plugins || plugins.length === 0) return registry;
92
+ const pluginEntries = Object.fromEntries(plugins.map((p) => [p.type, p.component]));
93
+ return {
94
+ ...registry,
95
+ ...pluginEntries
96
+ };
92
97
  }
93
98
  function createScreen(registry, widgets) {
94
99
  widgets.forEach((widget) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["isWidgetType","WIDGET_TYPE_NAMES"],"sources":["../../src/widget-utils/widget-utils.ts","../../src/widget-utils/utils.ts"],"sourcesContent":["import type { WidgetSchema, WidgetPath } from \"../types\";\nimport { WIDGET_TYPE_NAMES, isWidgetType } from \"../types\";\n\n/**\n * Generates a unique ID for a widget\n */\nexport function generateWidgetId(type?: string): string {\n const uuid = crypto.randomUUID();\n return type ? `${type}-${uuid}` : uuid;\n}\n\n/**\n * Converts a widget path to a unique string identifier\n */\nexport function pathToId(path: WidgetPath): string {\n return path.join(\"-\");\n}\n\n/**\n * Converts a path string back to a WidgetPath array\n */\nexport function idToPath(id: string): WidgetPath {\n return id.split(\"-\").map((segment) => parseInt(segment, 10));\n}\n\n/**\n * Ensures all widgets in an array have valid IDs\n * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)\n */\nexport function ensureWidgetIds(\n widgets: readonly (WidgetSchema | null)[],\n): (WidgetSchema | null)[] {\n return widgets?.map((widget, index) => {\n if (!widget) return null;\n return {\n ...widget,\n id: widget.id || `widget-${index}-${crypto.randomUUID()}`,\n };\n });\n}\n\n/**\n * Deep clones a widget and regenerates all IDs (including nested children)\n */\nexport function deepCloneWidget(widget: WidgetSchema): WidgetSchema {\n // Handle LayoutWidget children recursively\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (\n isWidgetType(widget, WIDGET_TYPE_NAMES.Layout) &&\n Array.isArray(widget.props.children)\n ) {\n // Build cloned widget with recursively cloned children\n return {\n type: widget.type,\n props: {\n ...widget.props,\n children: (\n widget.props.children as readonly (WidgetSchema | null)[]\n ).map((child) => (child ? deepCloneWidget(child) : null)),\n },\n id: generateWidgetId(widget.type),\n };\n }\n\n // Clone non-container widget\n return {\n type: widget.type,\n props: { ...widget.props },\n id: generateWidgetId(widget.type),\n };\n}\n\n/**\n * Deep clones an array of widgets and regenerates all IDs\n */\nexport function deepCloneWidgets(\n widgets: readonly WidgetSchema[],\n): WidgetSchema[] {\n return widgets.map((widget) => deepCloneWidget(widget));\n}\n\n/**\n * Gets a widget at a specific path in the widget tree\n */\nexport function getWidgetByPath(\n screen: readonly (WidgetSchema | null)[],\n path: WidgetPath,\n): WidgetSchema | null {\n if (path.length === 0 || path[0] === undefined) return null;\n\n let current: WidgetSchema | null = screen[path[0]] ?? null;\n\n for (let i = 1; i < path.length; i++) {\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (!isWidgetType(current, WIDGET_TYPE_NAMES.Layout)) return null;\n\n const children = (current.props.children ??\n []) as readonly (WidgetSchema | null)[];\n const index = path[i];\n if (index === undefined) return null;\n current = children[index] ?? null;\n }\n\n return current;\n}\n\n/**\n * Groups children by column index.\n * Accepts nullable children (sparse arrays from grid layouts) and filters them out.\n */\nexport function groupChildrenByColumn(\n children: readonly (WidgetSchema | null)[],\n columnCount: number,\n): WidgetSchema[][] {\n // Use explicit type annotation to avoid never[] inference (narrowing-empty-array-type rule)\n const columns: WidgetSchema[][] = Array.from(\n { length: columnCount },\n (): WidgetSchema[] => [],\n );\n\n // Filter out nulls first, then process (truthiness narrowing rule)\n // This avoids the narrowing-callback-scope issue since we work with non-null array\n const nonNullChildren = children.filter(\n (child): child is WidgetSchema => child !== null,\n );\n\n for (const child of nonNullChildren) {\n // Default to column 0 if no columnIndex specified\n const colIndex = Math.min(child.columnIndex ?? 0, columnCount - 1);\n const column = columns[colIndex];\n if (column) {\n column.push(child);\n }\n }\n\n return columns;\n}\n","import type { ComponentType } from \"react\";\nimport type { WidgetSchema, TypedWidgetSchema } from \"../types\";\nimport type { ShareableItem } from \"../types/shareable-item\";\n\nexport function createWidgetRegistry<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends Record<string, ComponentType<any>>,\n>(registry: T): T {\n // Return the registry with its original type intact for type inference\n return registry;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createScreen<T extends Record<string, ComponentType<any>>>(\n registry: T,\n widgets: TypedWidgetSchema<T>[],\n): TypedWidgetSchema<T>[] {\n // Validate that all widget types exist in the registry at runtime\n widgets.forEach((widget) => {\n if (!(widget.type in registry)) {\n throw new Error(\n `Widget type \"${String(widget.type)}\" not found in registry`,\n );\n }\n });\n return widgets;\n}\n\n// Helper to create WidgetSchema from shareable item\nexport function createWidgetFromShareable(item: ShareableItem): WidgetSchema {\n const isVideo = item.kind === \"video\" || !!item.videoUrl;\n\n if (isVideo && item.videoUrl) {\n return {\n type: \"VideoWidget\",\n props: {\n src: item.videoUrl,\n poster: item.imageUrl,\n caption: item.title,\n },\n };\n }\n\n return {\n type: \"ImageWidget\",\n props: {\n src: item.imageUrl,\n alt: item.title || \"Image\",\n objectFit: \"cover\",\n },\n };\n}\n"],"mappings":";;;;;;AAMA,SAAgB,iBAAiB,MAAuB;CACtD,MAAM,OAAO,OAAO,YAAY;AAChC,QAAO,OAAO,GAAG,KAAK,GAAG,SAAS;;;;;AAMpC,SAAgB,SAAS,MAA0B;AACjD,QAAO,KAAK,KAAK,IAAI;;;;;AAMvB,SAAgB,SAAS,IAAwB;AAC/C,QAAO,GAAG,MAAM,IAAI,CAAC,KAAK,YAAY,SAAS,SAAS,GAAG,CAAC;;;;;;AAO9D,SAAgB,gBACd,SACyB;AACzB,QAAO,SAAS,KAAK,QAAQ,UAAU;AACrC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO;GACL,GAAG;GACH,IAAI,OAAO,MAAM,UAAU,MAAM,GAAG,OAAO,YAAY;GACxD;GACD;;;;;AAMJ,SAAgB,gBAAgB,QAAoC;AAGlE,KACEA,cAAAA,aAAa,QAAQC,cAAAA,kBAAkB,OAAO,IAC9C,MAAM,QAAQ,OAAO,MAAM,SAAS,CAGpC,QAAO;EACL,MAAM,OAAO;EACb,OAAO;GACL,GAAG,OAAO;GACV,UACE,OAAO,MAAM,SACb,KAAK,UAAW,QAAQ,gBAAgB,MAAM,GAAG,KAAM;GAC1D;EACD,IAAI,iBAAiB,OAAO,KAAK;EAClC;AAIH,QAAO;EACL,MAAM,OAAO;EACb,OAAO,EAAE,GAAG,OAAO,OAAO;EAC1B,IAAI,iBAAiB,OAAO,KAAK;EAClC;;;;;AAMH,SAAgB,iBACd,SACgB;AAChB,QAAO,QAAQ,KAAK,WAAW,gBAAgB,OAAO,CAAC;;;;;AAMzD,SAAgB,gBACd,QACA,MACqB;AACrB,KAAI,KAAK,WAAW,KAAK,KAAK,OAAO,KAAA,EAAW,QAAO;CAEvD,IAAI,UAA+B,OAAO,KAAK,OAAO;AAEtD,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAEpC,MAAI,CAACD,cAAAA,aAAa,SAASC,cAAAA,kBAAkB,OAAO,CAAE,QAAO;EAE7D,MAAM,WAAY,QAAQ,MAAM,YAC9B,EAAE;EACJ,MAAM,QAAQ,KAAK;AACnB,MAAI,UAAU,KAAA,EAAW,QAAO;AAChC,YAAU,SAAS,UAAU;;AAG/B,QAAO;;;;;;AAOT,SAAgB,sBACd,UACA,aACkB;CAElB,MAAM,UAA4B,MAAM,KACtC,EAAE,QAAQ,aAAa,QACD,EAAE,CACzB;CAID,MAAM,kBAAkB,SAAS,QAC9B,UAAiC,UAAU,KAC7C;AAED,MAAK,MAAM,SAAS,iBAAiB;EAGnC,MAAM,SAAS,QADE,KAAK,IAAI,MAAM,eAAe,GAAG,cAAc,EAAE;AAElE,MAAI,OACF,QAAO,KAAK,MAAM;;AAItB,QAAO;;;;ACnIT,SAAgB,qBAGd,UAAgB;AAEhB,QAAO;;AAIT,SAAgB,aACd,UACA,SACwB;AAExB,SAAQ,SAAS,WAAW;AAC1B,MAAI,EAAE,OAAO,QAAQ,UACnB,OAAM,IAAI,MACR,gBAAgB,OAAO,OAAO,KAAK,CAAC,yBACrC;GAEH;AACF,QAAO;;AAIT,SAAgB,0BAA0B,MAAmC;AAG3E,MAFgB,KAAK,SAAS,WAAW,CAAC,CAAC,KAAK,aAEjC,KAAK,SAClB,QAAO;EACL,MAAM;EACN,OAAO;GACL,KAAK,KAAK;GACV,QAAQ,KAAK;GACb,SAAS,KAAK;GACf;EACF;AAGH,QAAO;EACL,MAAM;EACN,OAAO;GACL,KAAK,KAAK;GACV,KAAK,KAAK,SAAS;GACnB,WAAW;GACZ;EACF"}
1
+ {"version":3,"file":"index.cjs","names":["isWidgetType","WIDGET_TYPE_NAMES"],"sources":["../../src/widget-utils/widget-utils.ts","../../src/widget-utils/utils.ts"],"sourcesContent":["import type { WidgetSchema, WidgetPath } from \"../types\";\nimport { WIDGET_TYPE_NAMES, isWidgetType } from \"../types\";\n\n/**\n * Generates a unique ID for a widget\n */\nexport function generateWidgetId(type?: string): string {\n const uuid = crypto.randomUUID();\n return type ? `${type}-${uuid}` : uuid;\n}\n\n/**\n * Converts a widget path to a unique string identifier\n */\nexport function pathToId(path: WidgetPath): string {\n return path.join(\"-\");\n}\n\n/**\n * Converts a path string back to a WidgetPath array\n */\nexport function idToPath(id: string): WidgetPath {\n return id.split(\"-\").map((segment) => parseInt(segment, 10));\n}\n\n/**\n * Ensures all widgets in an array have valid IDs\n * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)\n */\nexport function ensureWidgetIds(\n widgets: readonly (WidgetSchema | null)[],\n): (WidgetSchema | null)[] {\n return widgets?.map((widget, index) => {\n if (!widget) return null;\n return {\n ...widget,\n id: widget.id || `widget-${index}-${crypto.randomUUID()}`,\n };\n });\n}\n\n/**\n * Deep clones a widget and regenerates all IDs (including nested children)\n */\nexport function deepCloneWidget(widget: WidgetSchema): WidgetSchema {\n // Handle LayoutWidget children recursively\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (\n isWidgetType(widget, WIDGET_TYPE_NAMES.Layout) &&\n Array.isArray(widget.props.children)\n ) {\n // Build cloned widget with recursively cloned children\n return {\n type: widget.type,\n props: {\n ...widget.props,\n children: (\n widget.props.children as readonly (WidgetSchema | null)[]\n ).map((child) => (child ? deepCloneWidget(child) : null)),\n },\n id: generateWidgetId(widget.type),\n };\n }\n\n // Clone non-container widget\n return {\n type: widget.type,\n props: { ...widget.props },\n id: generateWidgetId(widget.type),\n };\n}\n\n/**\n * Deep clones an array of widgets and regenerates all IDs\n */\nexport function deepCloneWidgets(\n widgets: readonly WidgetSchema[],\n): WidgetSchema[] {\n return widgets.map((widget) => deepCloneWidget(widget));\n}\n\n/**\n * Gets a widget at a specific path in the widget tree\n */\nexport function getWidgetByPath(\n screen: readonly (WidgetSchema | null)[],\n path: WidgetPath,\n): WidgetSchema | null {\n if (path.length === 0 || path[0] === undefined) return null;\n\n let current: WidgetSchema | null = screen[path[0]] ?? null;\n\n for (let i = 1; i < path.length; i++) {\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (!isWidgetType(current, WIDGET_TYPE_NAMES.Layout)) return null;\n\n const children = (current.props.children ??\n []) as readonly (WidgetSchema | null)[];\n const index = path[i];\n if (index === undefined) return null;\n current = children[index] ?? null;\n }\n\n return current;\n}\n\n/**\n * Groups children by column index.\n * Accepts nullable children (sparse arrays from grid layouts) and filters them out.\n */\nexport function groupChildrenByColumn(\n children: readonly (WidgetSchema | null)[],\n columnCount: number,\n): WidgetSchema[][] {\n // Use explicit type annotation to avoid never[] inference (narrowing-empty-array-type rule)\n const columns: WidgetSchema[][] = Array.from(\n { length: columnCount },\n (): WidgetSchema[] => [],\n );\n\n // Filter out nulls first, then process (truthiness narrowing rule)\n // This avoids the narrowing-callback-scope issue since we work with non-null array\n const nonNullChildren = children.filter(\n (child): child is WidgetSchema => child !== null,\n );\n\n for (const child of nonNullChildren) {\n // Default to column 0 if no columnIndex specified\n const colIndex = Math.min(child.columnIndex ?? 0, columnCount - 1);\n const column = columns[colIndex];\n if (column) {\n column.push(child);\n }\n }\n\n return columns;\n}\n","import type { ComponentType } from \"react\";\nimport type { WidgetSchema, TypedWidgetSchema } from \"../types\";\nimport type { ShareableItem } from \"../types/shareable-item\";\nimport type { WidgetManifest } from \"../registries/widget-manifest\";\n\nexport function createWidgetRegistry<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends Record<string, ComponentType<any>>,\n>(registry: T, plugins?: WidgetManifest[]): T {\n if (!plugins || plugins.length === 0) {\n return registry;\n }\n\n const pluginEntries = Object.fromEntries(\n plugins.map((p) => [p.type, p.component]),\n );\n\n return { ...registry, ...pluginEntries } as T;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createScreen<T extends Record<string, ComponentType<any>>>(\n registry: T,\n widgets: TypedWidgetSchema<T>[],\n): TypedWidgetSchema<T>[] {\n // Validate that all widget types exist in the registry at runtime\n widgets.forEach((widget) => {\n if (!(widget.type in registry)) {\n throw new Error(\n `Widget type \"${String(widget.type)}\" not found in registry`,\n );\n }\n });\n return widgets;\n}\n\n// Helper to create WidgetSchema from shareable item\nexport function createWidgetFromShareable(item: ShareableItem): WidgetSchema {\n const isVideo = item.kind === \"video\" || !!item.videoUrl;\n\n if (isVideo && item.videoUrl) {\n return {\n type: \"VideoWidget\",\n props: {\n src: item.videoUrl,\n poster: item.imageUrl,\n caption: item.title,\n },\n };\n }\n\n return {\n type: \"ImageWidget\",\n props: {\n src: item.imageUrl,\n alt: item.title || \"Image\",\n objectFit: \"cover\",\n },\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { a as WidgetSchema, r as WidgetPath, t as TypedWidgetSchema } from "../widget-schema-BSX2fVhW.cjs";
2
2
  import { T as ShareableItem } from "../index-B5cTNde-.cjs";
3
+ import { t as WidgetManifest } from "../widget-manifest-Ei8Wnspj.cjs";
3
4
  import { ComponentType } from "react";
4
5
 
5
6
  //#region src/widget-utils/widget-utils.d.ts
@@ -39,7 +40,7 @@ declare function getWidgetByPath(screen: readonly (WidgetSchema | null)[], path:
39
40
  declare function groupChildrenByColumn(children: readonly (WidgetSchema | null)[], columnCount: number): WidgetSchema[][];
40
41
  //#endregion
41
42
  //#region src/widget-utils/utils.d.ts
42
- declare function createWidgetRegistry<T extends Record<string, ComponentType<any>>>(registry: T): T;
43
+ declare function createWidgetRegistry<T extends Record<string, ComponentType<any>>>(registry: T, plugins?: WidgetManifest[]): T;
43
44
  declare function createScreen<T extends Record<string, ComponentType<any>>>(registry: T, widgets: TypedWidgetSchema<T>[]): TypedWidgetSchema<T>[];
44
45
  declare function createWidgetFromShareable(item: ShareableItem): WidgetSchema;
45
46
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/widget-utils/widget-utils.ts","../../src/widget-utils/utils.ts"],"mappings":";;;;;;;;iBAMgB,gBAAA,CAAiB,IAAA;AAAjC;;;AAAA,iBAQgB,QAAA,CAAS,IAAA,EAAM,UAAA;;AAA/B;;iBAOgB,QAAA,CAAS,EAAA,WAAa,UAAA;;;AAAtC;;iBAQgB,eAAA,CACd,OAAA,YAAmB,YAAA,cACjB,YAAA;;;AAFJ;iBAegB,eAAA,CAAgB,MAAA,EAAQ,YAAA,GAAe,YAAA;;;;iBA+BvC,gBAAA,CACd,OAAA,WAAkB,YAAA,KACjB,YAAA;;;;iBAOa,eAAA,CACd,MAAA,YAAkB,YAAA,YAClB,IAAA,EAAM,UAAA,GACL,YAAA;;;;;iBAuBa,qBAAA,CACd,QAAA,YAAoB,YAAA,YACpB,WAAA,WACC,YAAA;;;iBC7Ga,oBAAA,WAEJ,MAAA,SAAe,aAAA,OAAA,CACzB,QAAA,EAAU,CAAA,GAAI,CAAA;AAAA,iBAMA,YAAA,WAAuB,MAAA,SAAe,aAAA,OAAA,CACpD,QAAA,EAAU,CAAA,EACV,OAAA,EAAS,iBAAA,CAAkB,CAAA,MAC1B,iBAAA,CAAkB,CAAA;AAAA,iBAaL,yBAAA,CAA0B,IAAA,EAAM,aAAA,GAAgB,YAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/widget-utils/widget-utils.ts","../../src/widget-utils/utils.ts"],"mappings":";;;;;;;;;iBAMgB,gBAAA,CAAiB,IAAA;;AAAjC;;iBAQgB,QAAA,CAAS,IAAA,EAAM,UAAA;;;AAA/B;iBAOgB,QAAA,CAAS,EAAA,WAAa,UAAA;;;;AAAtC;iBAQgB,eAAA,CACd,OAAA,YAAmB,YAAA,cACjB,YAAA;;;;iBAaY,eAAA,CAAgB,MAAA,EAAQ,YAAA,GAAe,YAAA;;;;iBA+BvC,gBAAA,CACd,OAAA,WAAkB,YAAA,KACjB,YAAA;;;;iBAOa,eAAA,CACd,MAAA,YAAkB,YAAA,YAClB,IAAA,EAAM,UAAA,GACL,YAAA;AA3CH;;;;AAAA,iBAkEgB,qBAAA,CACd,QAAA,YAAoB,YAAA,YACpB,WAAA,WACC,YAAA;;;iBC5Ga,oBAAA,WAEJ,MAAA,SAAe,aAAA,OAAA,CACzB,QAAA,EAAU,CAAA,EAAG,OAAA,GAAU,cAAA,KAAmB,CAAA;AAAA,iBAa5B,YAAA,WAAuB,MAAA,SAAe,aAAA,OAAA,CACpD,QAAA,EAAU,CAAA,EACV,OAAA,EAAS,iBAAA,CAAkB,CAAA,MAC1B,iBAAA,CAAkB,CAAA;AAAA,iBAaL,yBAAA,CAA0B,IAAA,EAAM,aAAA,GAAgB,YAAA"}
@@ -1,5 +1,6 @@
1
1
  import { a as WidgetSchema, r as WidgetPath, t as TypedWidgetSchema } from "../widget-schema-BKZgsNG7.mjs";
2
2
  import { T as ShareableItem } from "../index-Cqt2JzkQ.mjs";
3
+ import { t as WidgetManifest } from "../widget-manifest-DQmTtAF1.mjs";
3
4
  import { ComponentType } from "react";
4
5
 
5
6
  //#region src/widget-utils/widget-utils.d.ts
@@ -39,7 +40,7 @@ declare function getWidgetByPath(screen: readonly (WidgetSchema | null)[], path:
39
40
  declare function groupChildrenByColumn(children: readonly (WidgetSchema | null)[], columnCount: number): WidgetSchema[][];
40
41
  //#endregion
41
42
  //#region src/widget-utils/utils.d.ts
42
- declare function createWidgetRegistry<T extends Record<string, ComponentType<any>>>(registry: T): T;
43
+ declare function createWidgetRegistry<T extends Record<string, ComponentType<any>>>(registry: T, plugins?: WidgetManifest[]): T;
43
44
  declare function createScreen<T extends Record<string, ComponentType<any>>>(registry: T, widgets: TypedWidgetSchema<T>[]): TypedWidgetSchema<T>[];
44
45
  declare function createWidgetFromShareable(item: ShareableItem): WidgetSchema;
45
46
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/widget-utils/widget-utils.ts","../../src/widget-utils/utils.ts"],"mappings":";;;;;;;;iBAMgB,gBAAA,CAAiB,IAAA;;AAAjC;;iBAQgB,QAAA,CAAS,IAAA,EAAM,UAAA;;;AAA/B;iBAOgB,QAAA,CAAS,EAAA,WAAa,UAAA;;;;AAAtC;iBAQgB,eAAA,CACd,OAAA,YAAmB,YAAA,cACjB,YAAA;;;;iBAaY,eAAA,CAAgB,MAAA,EAAQ,YAAA,GAAe,YAAA;;;;iBA+BvC,gBAAA,CACd,OAAA,WAAkB,YAAA,KACjB,YAAA;;;;iBAOa,eAAA,CACd,MAAA,YAAkB,YAAA,YAClB,IAAA,EAAM,UAAA,GACL,YAAA;AA3CH;;;;AAAA,iBAkEgB,qBAAA,CACd,QAAA,YAAoB,YAAA,YACpB,WAAA,WACC,YAAA;;;iBC7Ga,oBAAA,WAEJ,MAAA,SAAe,aAAA,OAAA,CACzB,QAAA,EAAU,CAAA,GAAI,CAAA;AAAA,iBAMA,YAAA,WAAuB,MAAA,SAAe,aAAA,OAAA,CACpD,QAAA,EAAU,CAAA,EACV,OAAA,EAAS,iBAAA,CAAkB,CAAA,MAC1B,iBAAA,CAAkB,CAAA;AAAA,iBAaL,yBAAA,CAA0B,IAAA,EAAM,aAAA,GAAgB,YAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/widget-utils/widget-utils.ts","../../src/widget-utils/utils.ts"],"mappings":";;;;;;;;;iBAMgB,gBAAA,CAAiB,IAAA;;;AAAjC;iBAQgB,QAAA,CAAS,IAAA,EAAM,UAAA;;;;iBAOf,QAAA,CAAS,EAAA,WAAa,UAAA;;;;;iBAQtB,eAAA,CACd,OAAA,YAAmB,YAAA,cACjB,YAAA;;;;iBAaY,eAAA,CAAgB,MAAA,EAAQ,YAAA,GAAe,YAAA;AAfvD;;;AAAA,iBA8CgB,gBAAA,CACd,OAAA,WAAkB,YAAA,KACjB,YAAA;;;;iBAOa,eAAA,CACd,MAAA,YAAkB,YAAA,YAClB,IAAA,EAAM,UAAA,GACL,YAAA;;AA3CH;;;iBAkEgB,qBAAA,CACd,QAAA,YAAoB,YAAA,YACpB,WAAA,WACC,YAAA;;;iBC5Ga,oBAAA,WAEJ,MAAA,SAAe,aAAA,OAAA,CACzB,QAAA,EAAU,CAAA,EAAG,OAAA,GAAU,cAAA,KAAmB,CAAA;AAAA,iBAa5B,YAAA,WAAuB,MAAA,SAAe,aAAA,OAAA,CACpD,QAAA,EAAU,CAAA,EACV,OAAA,EAAS,iBAAA,CAAkB,CAAA,MAC1B,iBAAA,CAAkB,CAAA;AAAA,iBAaL,yBAAA,CAA0B,IAAA,EAAM,aAAA,GAAgB,YAAA"}
@@ -86,8 +86,13 @@ function groupChildrenByColumn(children, columnCount) {
86
86
  }
87
87
  //#endregion
88
88
  //#region src/widget-utils/utils.ts
89
- function createWidgetRegistry(registry) {
90
- return registry;
89
+ function createWidgetRegistry(registry, plugins) {
90
+ if (!plugins || plugins.length === 0) return registry;
91
+ const pluginEntries = Object.fromEntries(plugins.map((p) => [p.type, p.component]));
92
+ return {
93
+ ...registry,
94
+ ...pluginEntries
95
+ };
91
96
  }
92
97
  function createScreen(registry, widgets) {
93
98
  widgets.forEach((widget) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/widget-utils/widget-utils.ts","../../src/widget-utils/utils.ts"],"sourcesContent":["import type { WidgetSchema, WidgetPath } from \"../types\";\nimport { WIDGET_TYPE_NAMES, isWidgetType } from \"../types\";\n\n/**\n * Generates a unique ID for a widget\n */\nexport function generateWidgetId(type?: string): string {\n const uuid = crypto.randomUUID();\n return type ? `${type}-${uuid}` : uuid;\n}\n\n/**\n * Converts a widget path to a unique string identifier\n */\nexport function pathToId(path: WidgetPath): string {\n return path.join(\"-\");\n}\n\n/**\n * Converts a path string back to a WidgetPath array\n */\nexport function idToPath(id: string): WidgetPath {\n return id.split(\"-\").map((segment) => parseInt(segment, 10));\n}\n\n/**\n * Ensures all widgets in an array have valid IDs\n * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)\n */\nexport function ensureWidgetIds(\n widgets: readonly (WidgetSchema | null)[],\n): (WidgetSchema | null)[] {\n return widgets?.map((widget, index) => {\n if (!widget) return null;\n return {\n ...widget,\n id: widget.id || `widget-${index}-${crypto.randomUUID()}`,\n };\n });\n}\n\n/**\n * Deep clones a widget and regenerates all IDs (including nested children)\n */\nexport function deepCloneWidget(widget: WidgetSchema): WidgetSchema {\n // Handle LayoutWidget children recursively\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (\n isWidgetType(widget, WIDGET_TYPE_NAMES.Layout) &&\n Array.isArray(widget.props.children)\n ) {\n // Build cloned widget with recursively cloned children\n return {\n type: widget.type,\n props: {\n ...widget.props,\n children: (\n widget.props.children as readonly (WidgetSchema | null)[]\n ).map((child) => (child ? deepCloneWidget(child) : null)),\n },\n id: generateWidgetId(widget.type),\n };\n }\n\n // Clone non-container widget\n return {\n type: widget.type,\n props: { ...widget.props },\n id: generateWidgetId(widget.type),\n };\n}\n\n/**\n * Deep clones an array of widgets and regenerates all IDs\n */\nexport function deepCloneWidgets(\n widgets: readonly WidgetSchema[],\n): WidgetSchema[] {\n return widgets.map((widget) => deepCloneWidget(widget));\n}\n\n/**\n * Gets a widget at a specific path in the widget tree\n */\nexport function getWidgetByPath(\n screen: readonly (WidgetSchema | null)[],\n path: WidgetPath,\n): WidgetSchema | null {\n if (path.length === 0 || path[0] === undefined) return null;\n\n let current: WidgetSchema | null = screen[path[0]] ?? null;\n\n for (let i = 1; i < path.length; i++) {\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (!isWidgetType(current, WIDGET_TYPE_NAMES.Layout)) return null;\n\n const children = (current.props.children ??\n []) as readonly (WidgetSchema | null)[];\n const index = path[i];\n if (index === undefined) return null;\n current = children[index] ?? null;\n }\n\n return current;\n}\n\n/**\n * Groups children by column index.\n * Accepts nullable children (sparse arrays from grid layouts) and filters them out.\n */\nexport function groupChildrenByColumn(\n children: readonly (WidgetSchema | null)[],\n columnCount: number,\n): WidgetSchema[][] {\n // Use explicit type annotation to avoid never[] inference (narrowing-empty-array-type rule)\n const columns: WidgetSchema[][] = Array.from(\n { length: columnCount },\n (): WidgetSchema[] => [],\n );\n\n // Filter out nulls first, then process (truthiness narrowing rule)\n // This avoids the narrowing-callback-scope issue since we work with non-null array\n const nonNullChildren = children.filter(\n (child): child is WidgetSchema => child !== null,\n );\n\n for (const child of nonNullChildren) {\n // Default to column 0 if no columnIndex specified\n const colIndex = Math.min(child.columnIndex ?? 0, columnCount - 1);\n const column = columns[colIndex];\n if (column) {\n column.push(child);\n }\n }\n\n return columns;\n}\n","import type { ComponentType } from \"react\";\nimport type { WidgetSchema, TypedWidgetSchema } from \"../types\";\nimport type { ShareableItem } from \"../types/shareable-item\";\n\nexport function createWidgetRegistry<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends Record<string, ComponentType<any>>,\n>(registry: T): T {\n // Return the registry with its original type intact for type inference\n return registry;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createScreen<T extends Record<string, ComponentType<any>>>(\n registry: T,\n widgets: TypedWidgetSchema<T>[],\n): TypedWidgetSchema<T>[] {\n // Validate that all widget types exist in the registry at runtime\n widgets.forEach((widget) => {\n if (!(widget.type in registry)) {\n throw new Error(\n `Widget type \"${String(widget.type)}\" not found in registry`,\n );\n }\n });\n return widgets;\n}\n\n// Helper to create WidgetSchema from shareable item\nexport function createWidgetFromShareable(item: ShareableItem): WidgetSchema {\n const isVideo = item.kind === \"video\" || !!item.videoUrl;\n\n if (isVideo && item.videoUrl) {\n return {\n type: \"VideoWidget\",\n props: {\n src: item.videoUrl,\n poster: item.imageUrl,\n caption: item.title,\n },\n };\n }\n\n return {\n type: \"ImageWidget\",\n props: {\n src: item.imageUrl,\n alt: item.title || \"Image\",\n objectFit: \"cover\",\n },\n };\n}\n"],"mappings":";;;;;AAMA,SAAgB,iBAAiB,MAAuB;CACtD,MAAM,OAAO,OAAO,YAAY;AAChC,QAAO,OAAO,GAAG,KAAK,GAAG,SAAS;;;;;AAMpC,SAAgB,SAAS,MAA0B;AACjD,QAAO,KAAK,KAAK,IAAI;;;;;AAMvB,SAAgB,SAAS,IAAwB;AAC/C,QAAO,GAAG,MAAM,IAAI,CAAC,KAAK,YAAY,SAAS,SAAS,GAAG,CAAC;;;;;;AAO9D,SAAgB,gBACd,SACyB;AACzB,QAAO,SAAS,KAAK,QAAQ,UAAU;AACrC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO;GACL,GAAG;GACH,IAAI,OAAO,MAAM,UAAU,MAAM,GAAG,OAAO,YAAY;GACxD;GACD;;;;;AAMJ,SAAgB,gBAAgB,QAAoC;AAGlE,KACE,aAAa,QAAQ,kBAAkB,OAAO,IAC9C,MAAM,QAAQ,OAAO,MAAM,SAAS,CAGpC,QAAO;EACL,MAAM,OAAO;EACb,OAAO;GACL,GAAG,OAAO;GACV,UACE,OAAO,MAAM,SACb,KAAK,UAAW,QAAQ,gBAAgB,MAAM,GAAG,KAAM;GAC1D;EACD,IAAI,iBAAiB,OAAO,KAAK;EAClC;AAIH,QAAO;EACL,MAAM,OAAO;EACb,OAAO,EAAE,GAAG,OAAO,OAAO;EAC1B,IAAI,iBAAiB,OAAO,KAAK;EAClC;;;;;AAMH,SAAgB,iBACd,SACgB;AAChB,QAAO,QAAQ,KAAK,WAAW,gBAAgB,OAAO,CAAC;;;;;AAMzD,SAAgB,gBACd,QACA,MACqB;AACrB,KAAI,KAAK,WAAW,KAAK,KAAK,OAAO,KAAA,EAAW,QAAO;CAEvD,IAAI,UAA+B,OAAO,KAAK,OAAO;AAEtD,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAEpC,MAAI,CAAC,aAAa,SAAS,kBAAkB,OAAO,CAAE,QAAO;EAE7D,MAAM,WAAY,QAAQ,MAAM,YAC9B,EAAE;EACJ,MAAM,QAAQ,KAAK;AACnB,MAAI,UAAU,KAAA,EAAW,QAAO;AAChC,YAAU,SAAS,UAAU;;AAG/B,QAAO;;;;;;AAOT,SAAgB,sBACd,UACA,aACkB;CAElB,MAAM,UAA4B,MAAM,KACtC,EAAE,QAAQ,aAAa,QACD,EAAE,CACzB;CAID,MAAM,kBAAkB,SAAS,QAC9B,UAAiC,UAAU,KAC7C;AAED,MAAK,MAAM,SAAS,iBAAiB;EAGnC,MAAM,SAAS,QADE,KAAK,IAAI,MAAM,eAAe,GAAG,cAAc,EAAE;AAElE,MAAI,OACF,QAAO,KAAK,MAAM;;AAItB,QAAO;;;;ACnIT,SAAgB,qBAGd,UAAgB;AAEhB,QAAO;;AAIT,SAAgB,aACd,UACA,SACwB;AAExB,SAAQ,SAAS,WAAW;AAC1B,MAAI,EAAE,OAAO,QAAQ,UACnB,OAAM,IAAI,MACR,gBAAgB,OAAO,OAAO,KAAK,CAAC,yBACrC;GAEH;AACF,QAAO;;AAIT,SAAgB,0BAA0B,MAAmC;AAG3E,MAFgB,KAAK,SAAS,WAAW,CAAC,CAAC,KAAK,aAEjC,KAAK,SAClB,QAAO;EACL,MAAM;EACN,OAAO;GACL,KAAK,KAAK;GACV,QAAQ,KAAK;GACb,SAAS,KAAK;GACf;EACF;AAGH,QAAO;EACL,MAAM;EACN,OAAO;GACL,KAAK,KAAK;GACV,KAAK,KAAK,SAAS;GACnB,WAAW;GACZ;EACF"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/widget-utils/widget-utils.ts","../../src/widget-utils/utils.ts"],"sourcesContent":["import type { WidgetSchema, WidgetPath } from \"../types\";\nimport { WIDGET_TYPE_NAMES, isWidgetType } from \"../types\";\n\n/**\n * Generates a unique ID for a widget\n */\nexport function generateWidgetId(type?: string): string {\n const uuid = crypto.randomUUID();\n return type ? `${type}-${uuid}` : uuid;\n}\n\n/**\n * Converts a widget path to a unique string identifier\n */\nexport function pathToId(path: WidgetPath): string {\n return path.join(\"-\");\n}\n\n/**\n * Converts a path string back to a WidgetPath array\n */\nexport function idToPath(id: string): WidgetPath {\n return id.split(\"-\").map((segment) => parseInt(segment, 10));\n}\n\n/**\n * Ensures all widgets in an array have valid IDs\n * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)\n */\nexport function ensureWidgetIds(\n widgets: readonly (WidgetSchema | null)[],\n): (WidgetSchema | null)[] {\n return widgets?.map((widget, index) => {\n if (!widget) return null;\n return {\n ...widget,\n id: widget.id || `widget-${index}-${crypto.randomUUID()}`,\n };\n });\n}\n\n/**\n * Deep clones a widget and regenerates all IDs (including nested children)\n */\nexport function deepCloneWidget(widget: WidgetSchema): WidgetSchema {\n // Handle LayoutWidget children recursively\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (\n isWidgetType(widget, WIDGET_TYPE_NAMES.Layout) &&\n Array.isArray(widget.props.children)\n ) {\n // Build cloned widget with recursively cloned children\n return {\n type: widget.type,\n props: {\n ...widget.props,\n children: (\n widget.props.children as readonly (WidgetSchema | null)[]\n ).map((child) => (child ? deepCloneWidget(child) : null)),\n },\n id: generateWidgetId(widget.type),\n };\n }\n\n // Clone non-container widget\n return {\n type: widget.type,\n props: { ...widget.props },\n id: generateWidgetId(widget.type),\n };\n}\n\n/**\n * Deep clones an array of widgets and regenerates all IDs\n */\nexport function deepCloneWidgets(\n widgets: readonly WidgetSchema[],\n): WidgetSchema[] {\n return widgets.map((widget) => deepCloneWidget(widget));\n}\n\n/**\n * Gets a widget at a specific path in the widget tree\n */\nexport function getWidgetByPath(\n screen: readonly (WidgetSchema | null)[],\n path: WidgetPath,\n): WidgetSchema | null {\n if (path.length === 0 || path[0] === undefined) return null;\n\n let current: WidgetSchema | null = screen[path[0]] ?? null;\n\n for (let i = 1; i < path.length; i++) {\n // Use type guard for discriminated union narrowing (narrowing-discriminated-unions rule)\n if (!isWidgetType(current, WIDGET_TYPE_NAMES.Layout)) return null;\n\n const children = (current.props.children ??\n []) as readonly (WidgetSchema | null)[];\n const index = path[i];\n if (index === undefined) return null;\n current = children[index] ?? null;\n }\n\n return current;\n}\n\n/**\n * Groups children by column index.\n * Accepts nullable children (sparse arrays from grid layouts) and filters them out.\n */\nexport function groupChildrenByColumn(\n children: readonly (WidgetSchema | null)[],\n columnCount: number,\n): WidgetSchema[][] {\n // Use explicit type annotation to avoid never[] inference (narrowing-empty-array-type rule)\n const columns: WidgetSchema[][] = Array.from(\n { length: columnCount },\n (): WidgetSchema[] => [],\n );\n\n // Filter out nulls first, then process (truthiness narrowing rule)\n // This avoids the narrowing-callback-scope issue since we work with non-null array\n const nonNullChildren = children.filter(\n (child): child is WidgetSchema => child !== null,\n );\n\n for (const child of nonNullChildren) {\n // Default to column 0 if no columnIndex specified\n const colIndex = Math.min(child.columnIndex ?? 0, columnCount - 1);\n const column = columns[colIndex];\n if (column) {\n column.push(child);\n }\n }\n\n return columns;\n}\n","import type { ComponentType } from \"react\";\nimport type { WidgetSchema, TypedWidgetSchema } from \"../types\";\nimport type { ShareableItem } from \"../types/shareable-item\";\nimport type { WidgetManifest } from \"../registries/widget-manifest\";\n\nexport function createWidgetRegistry<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends Record<string, ComponentType<any>>,\n>(registry: T, plugins?: WidgetManifest[]): T {\n if (!plugins || plugins.length === 0) {\n return registry;\n }\n\n const pluginEntries = Object.fromEntries(\n plugins.map((p) => [p.type, p.component]),\n );\n\n return { ...registry, ...pluginEntries } as T;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createScreen<T extends Record<string, ComponentType<any>>>(\n registry: T,\n widgets: TypedWidgetSchema<T>[],\n): TypedWidgetSchema<T>[] {\n // Validate that all widget types exist in the registry at runtime\n widgets.forEach((widget) => {\n if (!(widget.type in registry)) {\n throw new Error(\n `Widget type \"${String(widget.type)}\" not found in registry`,\n );\n }\n });\n return widgets;\n}\n\n// Helper to create WidgetSchema from shareable item\nexport function createWidgetFromShareable(item: ShareableItem): WidgetSchema {\n const isVideo = item.kind === \"video\" || !!item.videoUrl;\n\n if (isVideo && item.videoUrl) {\n return {\n type: \"VideoWidget\",\n props: {\n src: item.videoUrl,\n poster: item.imageUrl,\n caption: item.title,\n },\n };\n }\n\n return {\n type: \"ImageWidget\",\n props: {\n src: item.imageUrl,\n alt: item.title || \"Image\",\n objectFit: \"cover\",\n },\n };\n}\n"],"mappings":";;;;;AAMA,SAAgB,iBAAiB,MAAuB;CACtD,MAAM,OAAO,OAAO,YAAY;AAChC,QAAO,OAAO,GAAG,KAAK,GAAG,SAAS;;;;;AAMpC,SAAgB,SAAS,MAA0B;AACjD,QAAO,KAAK,KAAK,IAAI;;;;;AAMvB,SAAgB,SAAS,IAAwB;AAC/C,QAAO,GAAG,MAAM,IAAI,CAAC,KAAK,YAAY,SAAS,SAAS,GAAG,CAAC;;;;;;AAO9D,SAAgB,gBACd,SACyB;AACzB,QAAO,SAAS,KAAK,QAAQ,UAAU;AACrC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO;GACL,GAAG;GACH,IAAI,OAAO,MAAM,UAAU,MAAM,GAAG,OAAO,YAAY;GACxD;GACD;;;;;AAMJ,SAAgB,gBAAgB,QAAoC;AAGlE,KACE,aAAa,QAAQ,kBAAkB,OAAO,IAC9C,MAAM,QAAQ,OAAO,MAAM,SAAS,CAGpC,QAAO;EACL,MAAM,OAAO;EACb,OAAO;GACL,GAAG,OAAO;GACV,UACE,OAAO,MAAM,SACb,KAAK,UAAW,QAAQ,gBAAgB,MAAM,GAAG,KAAM;GAC1D;EACD,IAAI,iBAAiB,OAAO,KAAK;EAClC;AAIH,QAAO;EACL,MAAM,OAAO;EACb,OAAO,EAAE,GAAG,OAAO,OAAO;EAC1B,IAAI,iBAAiB,OAAO,KAAK;EAClC;;;;;AAMH,SAAgB,iBACd,SACgB;AAChB,QAAO,QAAQ,KAAK,WAAW,gBAAgB,OAAO,CAAC;;;;;AAMzD,SAAgB,gBACd,QACA,MACqB;AACrB,KAAI,KAAK,WAAW,KAAK,KAAK,OAAO,KAAA,EAAW,QAAO;CAEvD,IAAI,UAA+B,OAAO,KAAK,OAAO;AAEtD,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAEpC,MAAI,CAAC,aAAa,SAAS,kBAAkB,OAAO,CAAE,QAAO;EAE7D,MAAM,WAAY,QAAQ,MAAM,YAC9B,EAAE;EACJ,MAAM,QAAQ,KAAK;AACnB,MAAI,UAAU,KAAA,EAAW,QAAO;AAChC,YAAU,SAAS,UAAU;;AAG/B,QAAO;;;;;;AAOT,SAAgB,sBACd,UACA,aACkB;CAElB,MAAM,UAA4B,MAAM,KACtC,EAAE,QAAQ,aAAa,QACD,EAAE,CACzB;CAID,MAAM,kBAAkB,SAAS,QAC9B,UAAiC,UAAU,KAC7C;AAED,MAAK,MAAM,SAAS,iBAAiB;EAGnC,MAAM,SAAS,QADE,KAAK,IAAI,MAAM,eAAe,GAAG,cAAc,EAAE;AAElE,MAAI,OACF,QAAO,KAAK,MAAM;;AAItB,QAAO;;;;AClIT,SAAgB,qBAGd,UAAa,SAA+B;AAC5C,KAAI,CAAC,WAAW,QAAQ,WAAW,EACjC,QAAO;CAGT,MAAM,gBAAgB,OAAO,YAC3B,QAAQ,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAC1C;AAED,QAAO;EAAE,GAAG;EAAU,GAAG;EAAe;;AAI1C,SAAgB,aACd,UACA,SACwB;AAExB,SAAQ,SAAS,WAAW;AAC1B,MAAI,EAAE,OAAO,QAAQ,UACnB,OAAM,IAAI,MACR,gBAAgB,OAAO,OAAO,KAAK,CAAC,yBACrC;GAEH;AACF,QAAO;;AAIT,SAAgB,0BAA0B,MAAmC;AAG3E,MAFgB,KAAK,SAAS,WAAW,CAAC,CAAC,KAAK,aAEjC,KAAK,SAClB,QAAO;EACL,MAAM;EACN,OAAO;GACL,KAAK,KAAK;GACV,QAAQ,KAAK;GACb,SAAS,KAAK;GACf;EACF;AAGH,QAAO;EACL,MAAM;EACN,OAAO;GACL,KAAK,KAAK;GACV,KAAK,KAAK,SAAS;GACnB,WAAW;GACZ;EACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluid-app/portal-core",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "Core types, theme engine, and widget utilities for the Fluid portal platform",
5
5
  "files": [
6
6
  "dist",
@@ -165,11 +165,16 @@
165
165
  "@fortawesome/fontawesome-svg-core": "^6.7.2",
166
166
  "@fortawesome/pro-regular-svg-icons": "^6.7.2",
167
167
  "@fortawesome/react-fontawesome": "^0.2.2",
168
+ "@swc/core": "^1.15.18",
169
+ "@swc/jest": "^0.2.39",
168
170
  "@tanstack/react-query": "^5.90.11",
171
+ "@types/jest": "^29.5.14",
169
172
  "@types/react": "^19.2.13",
173
+ "jest": "^29.7.0",
170
174
  "react": "^19.2.4",
171
175
  "tsdown": "^0.21.0",
172
176
  "typescript": "^5",
177
+ "zod": "4.3.5",
173
178
  "@fluid-app/typescript-config": "0.0.0"
174
179
  },
175
180
  "peerDependencies": {
@@ -192,6 +197,8 @@
192
197
  "dev": "tsdown --watch",
193
198
  "lint": "oxlint",
194
199
  "lint:fix": "oxlint --fix",
200
+ "test": "jest",
201
+ "test:watch": "jest --watch",
195
202
  "typecheck": "tsgo --noEmit"
196
203
  },
197
204
  "main": "./dist/types/index.cjs",