@fluid-app/portal-core 0.1.16

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 (195) hide show
  1. package/dist/chunk-CKQMccvm.cjs +28 -0
  2. package/dist/data-sources/DataAwareWidget.cjs +50 -0
  3. package/dist/data-sources/DataAwareWidget.cjs.map +1 -0
  4. package/dist/data-sources/DataAwareWidget.d.cts +24 -0
  5. package/dist/data-sources/DataAwareWidget.d.cts.map +1 -0
  6. package/dist/data-sources/DataAwareWidget.d.mts +24 -0
  7. package/dist/data-sources/DataAwareWidget.d.mts.map +1 -0
  8. package/dist/data-sources/DataAwareWidget.mjs +48 -0
  9. package/dist/data-sources/DataAwareWidget.mjs.map +1 -0
  10. package/dist/data-sources/ErrorState.cjs +20 -0
  11. package/dist/data-sources/ErrorState.cjs.map +1 -0
  12. package/dist/data-sources/ErrorState.d.cts +7 -0
  13. package/dist/data-sources/ErrorState.d.cts.map +1 -0
  14. package/dist/data-sources/ErrorState.d.mts +7 -0
  15. package/dist/data-sources/ErrorState.d.mts.map +1 -0
  16. package/dist/data-sources/ErrorState.mjs +18 -0
  17. package/dist/data-sources/ErrorState.mjs.map +1 -0
  18. package/dist/data-sources/context.cjs +24 -0
  19. package/dist/data-sources/context.cjs.map +1 -0
  20. package/dist/data-sources/context.d.cts +21 -0
  21. package/dist/data-sources/context.d.cts.map +1 -0
  22. package/dist/data-sources/context.d.mts +21 -0
  23. package/dist/data-sources/context.d.mts.map +1 -0
  24. package/dist/data-sources/context.mjs +21 -0
  25. package/dist/data-sources/context.mjs.map +1 -0
  26. package/dist/data-sources/fetchers/api.cjs +65 -0
  27. package/dist/data-sources/fetchers/api.cjs.map +1 -0
  28. package/dist/data-sources/fetchers/api.d.cts +10 -0
  29. package/dist/data-sources/fetchers/api.d.cts.map +1 -0
  30. package/dist/data-sources/fetchers/api.d.mts +10 -0
  31. package/dist/data-sources/fetchers/api.d.mts.map +1 -0
  32. package/dist/data-sources/fetchers/api.mjs +64 -0
  33. package/dist/data-sources/fetchers/api.mjs.map +1 -0
  34. package/dist/data-sources/fetchers/custom.cjs +108 -0
  35. package/dist/data-sources/fetchers/custom.cjs.map +1 -0
  36. package/dist/data-sources/fetchers/custom.d.cts +17 -0
  37. package/dist/data-sources/fetchers/custom.d.cts.map +1 -0
  38. package/dist/data-sources/fetchers/custom.d.mts +17 -0
  39. package/dist/data-sources/fetchers/custom.d.mts.map +1 -0
  40. package/dist/data-sources/fetchers/custom.mjs +107 -0
  41. package/dist/data-sources/fetchers/custom.mjs.map +1 -0
  42. package/dist/data-sources/fetchers/static.cjs +161 -0
  43. package/dist/data-sources/fetchers/static.cjs.map +1 -0
  44. package/dist/data-sources/fetchers/static.d.cts +40 -0
  45. package/dist/data-sources/fetchers/static.d.cts.map +1 -0
  46. package/dist/data-sources/fetchers/static.d.mts +40 -0
  47. package/dist/data-sources/fetchers/static.d.mts.map +1 -0
  48. package/dist/data-sources/fetchers/static.mjs +158 -0
  49. package/dist/data-sources/fetchers/static.mjs.map +1 -0
  50. package/dist/data-sources/preview-context.cjs +21 -0
  51. package/dist/data-sources/preview-context.cjs.map +1 -0
  52. package/dist/data-sources/preview-context.d.cts +13 -0
  53. package/dist/data-sources/preview-context.d.cts.map +1 -0
  54. package/dist/data-sources/preview-context.d.mts +13 -0
  55. package/dist/data-sources/preview-context.d.mts.map +1 -0
  56. package/dist/data-sources/preview-context.mjs +18 -0
  57. package/dist/data-sources/preview-context.mjs.map +1 -0
  58. package/dist/data-sources/registry-context.cjs +53 -0
  59. package/dist/data-sources/registry-context.cjs.map +1 -0
  60. package/dist/data-sources/registry-context.d.cts +48 -0
  61. package/dist/data-sources/registry-context.d.cts.map +1 -0
  62. package/dist/data-sources/registry-context.d.mts +48 -0
  63. package/dist/data-sources/registry-context.d.mts.map +1 -0
  64. package/dist/data-sources/registry-context.mjs +49 -0
  65. package/dist/data-sources/registry-context.mjs.map +1 -0
  66. package/dist/data-sources/registry.cjs +31 -0
  67. package/dist/data-sources/registry.cjs.map +1 -0
  68. package/dist/data-sources/registry.d.cts +19 -0
  69. package/dist/data-sources/registry.d.cts.map +1 -0
  70. package/dist/data-sources/registry.d.mts +19 -0
  71. package/dist/data-sources/registry.d.mts.map +1 -0
  72. package/dist/data-sources/registry.mjs +29 -0
  73. package/dist/data-sources/registry.mjs.map +1 -0
  74. package/dist/data-sources/transformers.cjs +154 -0
  75. package/dist/data-sources/transformers.cjs.map +1 -0
  76. package/dist/data-sources/transformers.d.cts +10 -0
  77. package/dist/data-sources/transformers.d.cts.map +1 -0
  78. package/dist/data-sources/transformers.d.mts +10 -0
  79. package/dist/data-sources/transformers.d.mts.map +1 -0
  80. package/dist/data-sources/transformers.mjs +153 -0
  81. package/dist/data-sources/transformers.mjs.map +1 -0
  82. package/dist/data-sources/types.cjs +0 -0
  83. package/dist/data-sources/types.d.cts +2 -0
  84. package/dist/data-sources/types.d.mts +2 -0
  85. package/dist/data-sources/types.mjs +1 -0
  86. package/dist/data-sources/use-widget-data.cjs +111 -0
  87. package/dist/data-sources/use-widget-data.cjs.map +1 -0
  88. package/dist/data-sources/use-widget-data.d.cts +17 -0
  89. package/dist/data-sources/use-widget-data.d.cts.map +1 -0
  90. package/dist/data-sources/use-widget-data.d.mts +17 -0
  91. package/dist/data-sources/use-widget-data.d.mts.map +1 -0
  92. package/dist/data-sources/use-widget-data.mjs +109 -0
  93. package/dist/data-sources/use-widget-data.mjs.map +1 -0
  94. package/dist/index-B5cTNde-.d.cts +246 -0
  95. package/dist/index-B5cTNde-.d.cts.map +1 -0
  96. package/dist/index-Cqt2JzkQ.d.mts +246 -0
  97. package/dist/index-Cqt2JzkQ.d.mts.map +1 -0
  98. package/dist/registries/index.cjs +243 -0
  99. package/dist/registries/index.cjs.map +1 -0
  100. package/dist/registries/index.d.cts +338 -0
  101. package/dist/registries/index.d.cts.map +1 -0
  102. package/dist/registries/index.d.mts +338 -0
  103. package/dist/registries/index.d.mts.map +1 -0
  104. package/dist/registries/index.mjs +229 -0
  105. package/dist/registries/index.mjs.map +1 -0
  106. package/dist/shell/AppShellLayout.cjs +49 -0
  107. package/dist/shell/AppShellLayout.cjs.map +1 -0
  108. package/dist/shell/AppShellLayout.d.cts +39 -0
  109. package/dist/shell/AppShellLayout.d.cts.map +1 -0
  110. package/dist/shell/AppShellLayout.d.mts +39 -0
  111. package/dist/shell/AppShellLayout.d.mts.map +1 -0
  112. package/dist/shell/AppShellLayout.mjs +46 -0
  113. package/dist/shell/AppShellLayout.mjs.map +1 -0
  114. package/dist/shell/ScreenHeader.cjs +44 -0
  115. package/dist/shell/ScreenHeader.cjs.map +1 -0
  116. package/dist/shell/ScreenHeader.d.cts +12 -0
  117. package/dist/shell/ScreenHeader.d.cts.map +1 -0
  118. package/dist/shell/ScreenHeader.d.mts +12 -0
  119. package/dist/shell/ScreenHeader.d.mts.map +1 -0
  120. package/dist/shell/ScreenHeader.mjs +42 -0
  121. package/dist/shell/ScreenHeader.mjs.map +1 -0
  122. package/dist/shell/ScreenHeaderContext.cjs +91 -0
  123. package/dist/shell/ScreenHeaderContext.cjs.map +1 -0
  124. package/dist/shell/ScreenHeaderContext.d.cts +35 -0
  125. package/dist/shell/ScreenHeaderContext.d.cts.map +1 -0
  126. package/dist/shell/ScreenHeaderContext.d.mts +35 -0
  127. package/dist/shell/ScreenHeaderContext.d.mts.map +1 -0
  128. package/dist/shell/ScreenHeaderContext.mjs +86 -0
  129. package/dist/shell/ScreenHeaderContext.mjs.map +1 -0
  130. package/dist/shell/ThemeModeContext.cjs +70 -0
  131. package/dist/shell/ThemeModeContext.cjs.map +1 -0
  132. package/dist/shell/ThemeModeContext.d.cts +33 -0
  133. package/dist/shell/ThemeModeContext.d.cts.map +1 -0
  134. package/dist/shell/ThemeModeContext.d.mts +33 -0
  135. package/dist/shell/ThemeModeContext.d.mts.map +1 -0
  136. package/dist/shell/ThemeModeContext.mjs +66 -0
  137. package/dist/shell/ThemeModeContext.mjs.map +1 -0
  138. package/dist/shell/index.cjs +43 -0
  139. package/dist/shell/index.d.cts +7 -0
  140. package/dist/shell/index.d.mts +7 -0
  141. package/dist/shell/index.mjs +7 -0
  142. package/dist/shell/sidebar.cjs +390 -0
  143. package/dist/shell/sidebar.cjs.map +1 -0
  144. package/dist/shell/sidebar.d.cts +85 -0
  145. package/dist/shell/sidebar.d.cts.map +1 -0
  146. package/dist/shell/sidebar.d.mts +85 -0
  147. package/dist/shell/sidebar.d.mts.map +1 -0
  148. package/dist/shell/sidebar.mjs +364 -0
  149. package/dist/shell/sidebar.mjs.map +1 -0
  150. package/dist/shell/use-mobile.cjs +51 -0
  151. package/dist/shell/use-mobile.cjs.map +1 -0
  152. package/dist/shell/use-mobile.d.cts +7 -0
  153. package/dist/shell/use-mobile.d.cts.map +1 -0
  154. package/dist/shell/use-mobile.d.mts +7 -0
  155. package/dist/shell/use-mobile.d.mts.map +1 -0
  156. package/dist/shell/use-mobile.mjs +47 -0
  157. package/dist/shell/use-mobile.mjs.map +1 -0
  158. package/dist/theme/index.cjs +758 -0
  159. package/dist/theme/index.cjs.map +1 -0
  160. package/dist/theme/index.d.cts +131 -0
  161. package/dist/theme/index.d.cts.map +1 -0
  162. package/dist/theme/index.d.mts +131 -0
  163. package/dist/theme/index.d.mts.map +1 -0
  164. package/dist/theme/index.mjs +728 -0
  165. package/dist/theme/index.mjs.map +1 -0
  166. package/dist/types/index.cjs +18 -0
  167. package/dist/types/index.d.cts +4 -0
  168. package/dist/types/index.d.mts +4 -0
  169. package/dist/types/index.mjs +2 -0
  170. package/dist/types-27AHMek-.d.cts +85 -0
  171. package/dist/types-27AHMek-.d.cts.map +1 -0
  172. package/dist/types-BXFX9bXp.cjs +303 -0
  173. package/dist/types-BXFX9bXp.cjs.map +1 -0
  174. package/dist/types-Bjmd7Fdx.mjs +208 -0
  175. package/dist/types-Bjmd7Fdx.mjs.map +1 -0
  176. package/dist/types-C5Zs5V3E.d.mts +155 -0
  177. package/dist/types-C5Zs5V3E.d.mts.map +1 -0
  178. package/dist/types-CeCPKvOv.d.mts +85 -0
  179. package/dist/types-CeCPKvOv.d.mts.map +1 -0
  180. package/dist/types-DrzvahW8.d.cts +155 -0
  181. package/dist/types-DrzvahW8.d.cts.map +1 -0
  182. package/dist/widget-schema-BKZgsNG7.d.mts +119 -0
  183. package/dist/widget-schema-BKZgsNG7.d.mts.map +1 -0
  184. package/dist/widget-schema-BSX2fVhW.d.cts +119 -0
  185. package/dist/widget-schema-BSX2fVhW.d.cts.map +1 -0
  186. package/dist/widget-utils/index.cjs +130 -0
  187. package/dist/widget-utils/index.cjs.map +1 -0
  188. package/dist/widget-utils/index.d.cts +47 -0
  189. package/dist/widget-utils/index.d.cts.map +1 -0
  190. package/dist/widget-utils/index.d.mts +47 -0
  191. package/dist/widget-utils/index.d.mts.map +1 -0
  192. package/dist/widget-utils/index.mjs +119 -0
  193. package/dist/widget-utils/index.mjs.map +1 -0
  194. package/package.json +200 -0
  195. package/src/styles/globals.css +1 -0
@@ -0,0 +1,119 @@
1
+ import { a as DataSourceConfig } from "./types-C5Zs5V3E.mjs";
2
+ import { ComponentType } from "react";
3
+
4
+ //#region src/types/widget-schema.d.ts
5
+ /**
6
+ * Widget type names as a const object.
7
+ * This serves as the single source of truth for widget discriminants.
8
+ * Use `as const` for literal type inference (safety-as-const-deep-readonly rule).
9
+ */
10
+ declare const WIDGET_TYPE_NAMES: {
11
+ readonly Alert: "AlertWidget";
12
+ readonly Calendar: "CalendarWidget";
13
+ readonly Carousel: "CarouselWidget";
14
+ readonly CatchUp: "CatchUpWidget";
15
+ readonly Chart: "ChartWidget";
16
+ readonly Container: "ContainerWidget";
17
+ readonly Embed: "EmbedWidget";
18
+ readonly Image: "ImageWidget";
19
+ readonly Layout: "LayoutWidget";
20
+ readonly List: "ListWidget";
21
+ readonly MySite: "MySiteWidget";
22
+ readonly Nested: "NestedWidget";
23
+ readonly QuickShare: "QuickShareWidget";
24
+ readonly RecentActivity: "RecentActivityWidget";
25
+ readonly Spacer: "SpacerWidget";
26
+ readonly Table: "TableWidget";
27
+ readonly Text: "TextWidget";
28
+ readonly ToDo: "ToDoWidget";
29
+ readonly Video: "VideoWidget";
30
+ };
31
+ /**
32
+ * Union of all known widget type names.
33
+ * Derived from WIDGET_TYPE_NAMES to avoid duplication (deriving-typeof-for-object-keys rule).
34
+ */
35
+ type WidgetTypeName = (typeof WIDGET_TYPE_NAMES)[keyof typeof WIDGET_TYPE_NAMES];
36
+ /**
37
+ * Legacy alias for backwards compatibility.
38
+ * Prefer using WidgetTypeName for new code when you need the union type.
39
+ */
40
+ type WidgetType = string;
41
+ type WidgetRegistry = Record<WidgetType, ComponentType<any>>;
42
+ /**
43
+ * Base widget schema with loose typing for runtime data.
44
+ * Use TypedWidgetSchema<T> when you have a known registry for better type safety.
45
+ */
46
+ type WidgetSchema = {
47
+ readonly type: WidgetType;
48
+ readonly props: Readonly<Record<string, unknown>>;
49
+ readonly id?: string; /** Optional data source configuration for data-bound widgets */
50
+ readonly dataSource?: DataSourceConfig | undefined; /** Column index for masonry layouts (0-indexed) */
51
+ readonly columnIndex?: number;
52
+ };
53
+ /**
54
+ * Type-safe widget schema based on registry.
55
+ * Uses discriminated unions - the `type` field serves as discriminant.
56
+ * When narrowed (e.g., `if (widget.type === "AlertWidget")`),
57
+ * TypeScript automatically knows the correct props type.
58
+ */
59
+ type TypedWidgetSchema<T extends Record<string, ComponentType<any>>> = { [K in keyof T]: {
60
+ readonly type: K;
61
+ readonly props: Readonly<React.ComponentProps<T[K]>>;
62
+ readonly id?: string;
63
+ readonly dataSource?: DataSourceConfig | undefined; /** Column index for masonry layouts (0-indexed) */
64
+ readonly columnIndex?: number;
65
+ } }[keyof T];
66
+ /**
67
+ * Widget path in the tree - array of indices.
68
+ * Readonly tuple to prevent accidental mutation.
69
+ */
70
+ type WidgetPath = readonly number[];
71
+ /**
72
+ * Type predicate to check if a string is a known widget type name.
73
+ * Use for runtime validation of widget types.
74
+ *
75
+ * @example
76
+ * if (isWidgetTypeName(widget.type)) {
77
+ * // TypeScript knows widget.type is WidgetTypeName
78
+ * }
79
+ */
80
+ declare function isWidgetTypeName(type: string): type is WidgetTypeName;
81
+ /**
82
+ * Type predicate to check if a widget has a specific type.
83
+ * Enables type-safe widget narrowing without `as` assertions.
84
+ *
85
+ * @example
86
+ * if (isWidgetType(widget, "LayoutWidget")) {
87
+ * // TypeScript knows widget.type === "LayoutWidget"
88
+ * // and widget.props is LayoutWidget props
89
+ * }
90
+ */
91
+ declare function isWidgetType<T extends WidgetTypeName>(widget: WidgetSchema | null | undefined, typeName: T): widget is WidgetSchema & {
92
+ readonly type: T;
93
+ };
94
+ /**
95
+ * Helper for exhaustive switch statements on widget types.
96
+ * Use in the default case to ensure all widget types are handled.
97
+ *
98
+ * @example
99
+ * switch (widget.type) {
100
+ * case "AlertWidget": return handleAlert();
101
+ * case "TextWidget": return handleText();
102
+ * // ... all other widget types
103
+ * default: return assertNever(widget.type, "widget type");
104
+ * }
105
+ */
106
+ declare function assertNever(value: never, context?: string): never;
107
+ /**
108
+ * Assertion function that throws if value is undefined.
109
+ * Narrows the type to exclude undefined.
110
+ *
111
+ * @example
112
+ * const widget = screen[0];
113
+ * assertDefined(widget, "widget at index 0");
114
+ * // TypeScript knows widget is defined here
115
+ */
116
+ declare function assertDefined<T>(value: T | undefined | null, name?: string): asserts value is T;
117
+ //#endregion
118
+ export { WidgetSchema as a, assertDefined as c, isWidgetTypeName as d, WidgetRegistry as i, assertNever as l, WIDGET_TYPE_NAMES as n, WidgetType as o, WidgetPath as r, WidgetTypeName as s, TypedWidgetSchema as t, isWidgetType as u };
119
+ //# sourceMappingURL=widget-schema-BKZgsNG7.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-schema-BKZgsNG7.d.mts","names":[],"sources":["../src/types/widget-schema.ts"],"mappings":";;;;;;AAQA;;;cAAa,iBAAA;EAAA,SACX,KAAA;EAAA,SACA,QAAA;EAAA,SACA,QAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA;EAAA,SACA,KAAA;EAAA,SACA,KAAA;EAAA,SACA,MAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;EAAA,SACA,MAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;EAAA,SACA,MAAA;EAAA,SACA,KAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;AAAA;;AAOF;;;KAAY,cAAA,WACF,iBAAA,eAAgC,iBAAA;;AAM1C;;;KAAY,UAAA;AAAA,KAGA,cAAA,GAAiB,MAAA,CAAO,UAAA,EAAY,aAAA;AAAhD;;;;AAAA,KAMY,YAAA;EAAA,SACD,IAAA,EAAM,UAAA;EAAA,SACN,KAAA,EAAO,QAAA,CAAS,MAAA;EAAA,SAChB,EAAA;WAEA,UAAA,GAAa,gBAAA;WAEb,WAAA;AAAA;AAPX;;;;;;AAAA,KAiBY,iBAAA,WAA4B,MAAA,SAAe,aAAA,wBACzC,CAAA;EAAA,SACD,IAAA,EAAM,CAAA;EAAA,SACN,KAAA,EAAO,QAAA,CAAS,KAAA,CAAM,cAAA,CAAe,CAAA,CAAE,CAAA;EAAA,SACvC,EAAA;EAAA,SACA,UAAA,GAAa,gBAAA;WAEb,WAAA;AAAA,UAEL,CAAA;;;;;KAMI,UAAA;;AAfZ;;;;;;;;iBA8BgB,gBAAA,CAAiB,IAAA,WAAe,IAAA,IAAQ,cAAA;;;;;;;;;;;iBAiBxC,YAAA,WAAuB,cAAA,CAAA,CACrC,MAAA,EAAQ,YAAA,qBACR,QAAA,EAAU,CAAA,GACT,MAAA,IAAU,YAAA;EAAA,SAA0B,IAAA,EAAM,CAAA;AAAA;;;;;;;;;;;;;iBAgB7B,WAAA,CAAY,KAAA,SAAc,OAAA;AAnD1C;;;;;AAeA;;;;AAfA,iBAmEgB,aAAA,GAAA,CACd,KAAA,EAAO,CAAA,qBACP,IAAA,oBACS,KAAA,IAAS,CAAA"}
@@ -0,0 +1,119 @@
1
+ import { a as DataSourceConfig } from "./types-DrzvahW8.cjs";
2
+ import { ComponentType } from "react";
3
+
4
+ //#region src/types/widget-schema.d.ts
5
+ /**
6
+ * Widget type names as a const object.
7
+ * This serves as the single source of truth for widget discriminants.
8
+ * Use `as const` for literal type inference (safety-as-const-deep-readonly rule).
9
+ */
10
+ declare const WIDGET_TYPE_NAMES: {
11
+ readonly Alert: "AlertWidget";
12
+ readonly Calendar: "CalendarWidget";
13
+ readonly Carousel: "CarouselWidget";
14
+ readonly CatchUp: "CatchUpWidget";
15
+ readonly Chart: "ChartWidget";
16
+ readonly Container: "ContainerWidget";
17
+ readonly Embed: "EmbedWidget";
18
+ readonly Image: "ImageWidget";
19
+ readonly Layout: "LayoutWidget";
20
+ readonly List: "ListWidget";
21
+ readonly MySite: "MySiteWidget";
22
+ readonly Nested: "NestedWidget";
23
+ readonly QuickShare: "QuickShareWidget";
24
+ readonly RecentActivity: "RecentActivityWidget";
25
+ readonly Spacer: "SpacerWidget";
26
+ readonly Table: "TableWidget";
27
+ readonly Text: "TextWidget";
28
+ readonly ToDo: "ToDoWidget";
29
+ readonly Video: "VideoWidget";
30
+ };
31
+ /**
32
+ * Union of all known widget type names.
33
+ * Derived from WIDGET_TYPE_NAMES to avoid duplication (deriving-typeof-for-object-keys rule).
34
+ */
35
+ type WidgetTypeName = (typeof WIDGET_TYPE_NAMES)[keyof typeof WIDGET_TYPE_NAMES];
36
+ /**
37
+ * Legacy alias for backwards compatibility.
38
+ * Prefer using WidgetTypeName for new code when you need the union type.
39
+ */
40
+ type WidgetType = string;
41
+ type WidgetRegistry = Record<WidgetType, ComponentType<any>>;
42
+ /**
43
+ * Base widget schema with loose typing for runtime data.
44
+ * Use TypedWidgetSchema<T> when you have a known registry for better type safety.
45
+ */
46
+ type WidgetSchema = {
47
+ readonly type: WidgetType;
48
+ readonly props: Readonly<Record<string, unknown>>;
49
+ readonly id?: string; /** Optional data source configuration for data-bound widgets */
50
+ readonly dataSource?: DataSourceConfig | undefined; /** Column index for masonry layouts (0-indexed) */
51
+ readonly columnIndex?: number;
52
+ };
53
+ /**
54
+ * Type-safe widget schema based on registry.
55
+ * Uses discriminated unions - the `type` field serves as discriminant.
56
+ * When narrowed (e.g., `if (widget.type === "AlertWidget")`),
57
+ * TypeScript automatically knows the correct props type.
58
+ */
59
+ type TypedWidgetSchema<T extends Record<string, ComponentType<any>>> = { [K in keyof T]: {
60
+ readonly type: K;
61
+ readonly props: Readonly<React.ComponentProps<T[K]>>;
62
+ readonly id?: string;
63
+ readonly dataSource?: DataSourceConfig | undefined; /** Column index for masonry layouts (0-indexed) */
64
+ readonly columnIndex?: number;
65
+ } }[keyof T];
66
+ /**
67
+ * Widget path in the tree - array of indices.
68
+ * Readonly tuple to prevent accidental mutation.
69
+ */
70
+ type WidgetPath = readonly number[];
71
+ /**
72
+ * Type predicate to check if a string is a known widget type name.
73
+ * Use for runtime validation of widget types.
74
+ *
75
+ * @example
76
+ * if (isWidgetTypeName(widget.type)) {
77
+ * // TypeScript knows widget.type is WidgetTypeName
78
+ * }
79
+ */
80
+ declare function isWidgetTypeName(type: string): type is WidgetTypeName;
81
+ /**
82
+ * Type predicate to check if a widget has a specific type.
83
+ * Enables type-safe widget narrowing without `as` assertions.
84
+ *
85
+ * @example
86
+ * if (isWidgetType(widget, "LayoutWidget")) {
87
+ * // TypeScript knows widget.type === "LayoutWidget"
88
+ * // and widget.props is LayoutWidget props
89
+ * }
90
+ */
91
+ declare function isWidgetType<T extends WidgetTypeName>(widget: WidgetSchema | null | undefined, typeName: T): widget is WidgetSchema & {
92
+ readonly type: T;
93
+ };
94
+ /**
95
+ * Helper for exhaustive switch statements on widget types.
96
+ * Use in the default case to ensure all widget types are handled.
97
+ *
98
+ * @example
99
+ * switch (widget.type) {
100
+ * case "AlertWidget": return handleAlert();
101
+ * case "TextWidget": return handleText();
102
+ * // ... all other widget types
103
+ * default: return assertNever(widget.type, "widget type");
104
+ * }
105
+ */
106
+ declare function assertNever(value: never, context?: string): never;
107
+ /**
108
+ * Assertion function that throws if value is undefined.
109
+ * Narrows the type to exclude undefined.
110
+ *
111
+ * @example
112
+ * const widget = screen[0];
113
+ * assertDefined(widget, "widget at index 0");
114
+ * // TypeScript knows widget is defined here
115
+ */
116
+ declare function assertDefined<T>(value: T | undefined | null, name?: string): asserts value is T;
117
+ //#endregion
118
+ export { WidgetSchema as a, assertDefined as c, isWidgetTypeName as d, WidgetRegistry as i, assertNever as l, WIDGET_TYPE_NAMES as n, WidgetType as o, WidgetPath as r, WidgetTypeName as s, TypedWidgetSchema as t, isWidgetType as u };
119
+ //# sourceMappingURL=widget-schema-BSX2fVhW.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-schema-BSX2fVhW.d.cts","names":[],"sources":["../src/types/widget-schema.ts"],"mappings":";;;;;;AAQA;;;cAAa,iBAAA;EAAA,SACX,KAAA;EAAA,SACA,QAAA;EAAA,SACA,QAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA;EAAA,SACA,KAAA;EAAA,SACA,KAAA;EAAA,SACA,MAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;EAAA,SACA,MAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;EAAA,SACA,MAAA;EAAA,SACA,KAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;AAAA;;AAOF;;;KAAY,cAAA,WACF,iBAAA,eAAgC,iBAAA;;AAM1C;;;KAAY,UAAA;AAAA,KAGA,cAAA,GAAiB,MAAA,CAAO,UAAA,EAAY,aAAA;AAAhD;;;;AAAA,KAMY,YAAA;EAAA,SACD,IAAA,EAAM,UAAA;EAAA,SACN,KAAA,EAAO,QAAA,CAAS,MAAA;EAAA,SAChB,EAAA;WAEA,UAAA,GAAa,gBAAA;WAEb,WAAA;AAAA;AAPX;;;;;;AAAA,KAiBY,iBAAA,WAA4B,MAAA,SAAe,aAAA,wBACzC,CAAA;EAAA,SACD,IAAA,EAAM,CAAA;EAAA,SACN,KAAA,EAAO,QAAA,CAAS,KAAA,CAAM,cAAA,CAAe,CAAA,CAAE,CAAA;EAAA,SACvC,EAAA;EAAA,SACA,UAAA,GAAa,gBAAA;WAEb,WAAA;AAAA,UAEL,CAAA;;;;;KAMI,UAAA;;AAfZ;;;;;;;;iBA8BgB,gBAAA,CAAiB,IAAA,WAAe,IAAA,IAAQ,cAAA;;;;;;;;;;;iBAiBxC,YAAA,WAAuB,cAAA,CAAA,CACrC,MAAA,EAAQ,YAAA,qBACR,QAAA,EAAU,CAAA,GACT,MAAA,IAAU,YAAA;EAAA,SAA0B,IAAA,EAAM,CAAA;AAAA;;;;;;;;;;;;;iBAgB7B,WAAA,CAAY,KAAA,SAAc,OAAA;AAnD1C;;;;;AAeA;;;;AAfA,iBAmEgB,aAAA,GAAA,CACd,KAAA,EAAO,CAAA,qBACP,IAAA,oBACS,KAAA,IAAS,CAAA"}
@@ -0,0 +1,130 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_types = require("../types-BXFX9bXp.cjs");
3
+ //#region src/widget-utils/widget-utils.ts
4
+ /**
5
+ * Generates a unique ID for a widget
6
+ */
7
+ function generateWidgetId(type) {
8
+ const uuid = crypto.randomUUID();
9
+ return type ? `${type}-${uuid}` : uuid;
10
+ }
11
+ /**
12
+ * Converts a widget path to a unique string identifier
13
+ */
14
+ function pathToId(path) {
15
+ return path.join("-");
16
+ }
17
+ /**
18
+ * Converts a path string back to a WidgetPath array
19
+ */
20
+ function idToPath(id) {
21
+ return id.split("-").map((segment) => parseInt(segment, 10));
22
+ }
23
+ /**
24
+ * Ensures all widgets in an array have valid IDs
25
+ * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)
26
+ */
27
+ function ensureWidgetIds(widgets) {
28
+ return widgets?.map((widget, index) => {
29
+ if (!widget) return null;
30
+ return {
31
+ ...widget,
32
+ id: widget.id || `widget-${index}-${crypto.randomUUID()}`
33
+ };
34
+ });
35
+ }
36
+ /**
37
+ * Deep clones a widget and regenerates all IDs (including nested children)
38
+ */
39
+ function deepCloneWidget(widget) {
40
+ if (require_types.isWidgetType(widget, require_types.WIDGET_TYPE_NAMES.Layout) && Array.isArray(widget.props.children)) return {
41
+ type: widget.type,
42
+ props: {
43
+ ...widget.props,
44
+ children: widget.props.children.map((child) => child ? deepCloneWidget(child) : null)
45
+ },
46
+ id: generateWidgetId(widget.type)
47
+ };
48
+ return {
49
+ type: widget.type,
50
+ props: { ...widget.props },
51
+ id: generateWidgetId(widget.type)
52
+ };
53
+ }
54
+ /**
55
+ * Deep clones an array of widgets and regenerates all IDs
56
+ */
57
+ function deepCloneWidgets(widgets) {
58
+ return widgets.map((widget) => deepCloneWidget(widget));
59
+ }
60
+ /**
61
+ * Gets a widget at a specific path in the widget tree
62
+ */
63
+ function getWidgetByPath(screen, path) {
64
+ if (path.length === 0 || path[0] === void 0) return null;
65
+ let current = screen[path[0]] ?? null;
66
+ for (let i = 1; i < path.length; i++) {
67
+ if (!require_types.isWidgetType(current, require_types.WIDGET_TYPE_NAMES.Layout)) return null;
68
+ const children = current.props.children ?? [];
69
+ const index = path[i];
70
+ if (index === void 0) return null;
71
+ current = children[index] ?? null;
72
+ }
73
+ return current;
74
+ }
75
+ /**
76
+ * Groups children by column index.
77
+ * Accepts nullable children (sparse arrays from grid layouts) and filters them out.
78
+ */
79
+ function groupChildrenByColumn(children, columnCount) {
80
+ const columns = Array.from({ length: columnCount }, () => []);
81
+ const nonNullChildren = children.filter((child) => child !== null);
82
+ for (const child of nonNullChildren) {
83
+ const column = columns[Math.min(child.columnIndex ?? 0, columnCount - 1)];
84
+ if (column) column.push(child);
85
+ }
86
+ return columns;
87
+ }
88
+ //#endregion
89
+ //#region src/widget-utils/utils.ts
90
+ function createWidgetRegistry(registry) {
91
+ return registry;
92
+ }
93
+ function createScreen(registry, widgets) {
94
+ widgets.forEach((widget) => {
95
+ if (!(widget.type in registry)) throw new Error(`Widget type "${String(widget.type)}" not found in registry`);
96
+ });
97
+ return widgets;
98
+ }
99
+ function createWidgetFromShareable(item) {
100
+ if ((item.kind === "video" || !!item.videoUrl) && item.videoUrl) return {
101
+ type: "VideoWidget",
102
+ props: {
103
+ src: item.videoUrl,
104
+ poster: item.imageUrl,
105
+ caption: item.title
106
+ }
107
+ };
108
+ return {
109
+ type: "ImageWidget",
110
+ props: {
111
+ src: item.imageUrl,
112
+ alt: item.title || "Image",
113
+ objectFit: "cover"
114
+ }
115
+ };
116
+ }
117
+ //#endregion
118
+ exports.createScreen = createScreen;
119
+ exports.createWidgetFromShareable = createWidgetFromShareable;
120
+ exports.createWidgetRegistry = createWidgetRegistry;
121
+ exports.deepCloneWidget = deepCloneWidget;
122
+ exports.deepCloneWidgets = deepCloneWidgets;
123
+ exports.ensureWidgetIds = ensureWidgetIds;
124
+ exports.generateWidgetId = generateWidgetId;
125
+ exports.getWidgetByPath = getWidgetByPath;
126
+ exports.groupChildrenByColumn = groupChildrenByColumn;
127
+ exports.idToPath = idToPath;
128
+ exports.pathToId = pathToId;
129
+
130
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +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"}
@@ -0,0 +1,47 @@
1
+ import { a as WidgetSchema, r as WidgetPath, t as TypedWidgetSchema } from "../widget-schema-BSX2fVhW.cjs";
2
+ import { T as ShareableItem } from "../index-B5cTNde-.cjs";
3
+ import { ComponentType } from "react";
4
+
5
+ //#region src/widget-utils/widget-utils.d.ts
6
+ /**
7
+ * Generates a unique ID for a widget
8
+ */
9
+ declare function generateWidgetId(type?: string): string;
10
+ /**
11
+ * Converts a widget path to a unique string identifier
12
+ */
13
+ declare function pathToId(path: WidgetPath): string;
14
+ /**
15
+ * Converts a path string back to a WidgetPath array
16
+ */
17
+ declare function idToPath(id: string): WidgetPath;
18
+ /**
19
+ * Ensures all widgets in an array have valid IDs
20
+ * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)
21
+ */
22
+ declare function ensureWidgetIds(widgets: readonly (WidgetSchema | null)[]): (WidgetSchema | null)[];
23
+ /**
24
+ * Deep clones a widget and regenerates all IDs (including nested children)
25
+ */
26
+ declare function deepCloneWidget(widget: WidgetSchema): WidgetSchema;
27
+ /**
28
+ * Deep clones an array of widgets and regenerates all IDs
29
+ */
30
+ declare function deepCloneWidgets(widgets: readonly WidgetSchema[]): WidgetSchema[];
31
+ /**
32
+ * Gets a widget at a specific path in the widget tree
33
+ */
34
+ declare function getWidgetByPath(screen: readonly (WidgetSchema | null)[], path: WidgetPath): WidgetSchema | null;
35
+ /**
36
+ * Groups children by column index.
37
+ * Accepts nullable children (sparse arrays from grid layouts) and filters them out.
38
+ */
39
+ declare function groupChildrenByColumn(children: readonly (WidgetSchema | null)[], columnCount: number): WidgetSchema[][];
40
+ //#endregion
41
+ //#region src/widget-utils/utils.d.ts
42
+ declare function createWidgetRegistry<T extends Record<string, ComponentType<any>>>(registry: T): T;
43
+ declare function createScreen<T extends Record<string, ComponentType<any>>>(registry: T, widgets: TypedWidgetSchema<T>[]): TypedWidgetSchema<T>[];
44
+ declare function createWidgetFromShareable(item: ShareableItem): WidgetSchema;
45
+ //#endregion
46
+ export { createScreen, createWidgetFromShareable, createWidgetRegistry, deepCloneWidget, deepCloneWidgets, ensureWidgetIds, generateWidgetId, getWidgetByPath, groupChildrenByColumn, idToPath, pathToId };
47
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +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"}
@@ -0,0 +1,47 @@
1
+ import { a as WidgetSchema, r as WidgetPath, t as TypedWidgetSchema } from "../widget-schema-BKZgsNG7.mjs";
2
+ import { T as ShareableItem } from "../index-Cqt2JzkQ.mjs";
3
+ import { ComponentType } from "react";
4
+
5
+ //#region src/widget-utils/widget-utils.d.ts
6
+ /**
7
+ * Generates a unique ID for a widget
8
+ */
9
+ declare function generateWidgetId(type?: string): string;
10
+ /**
11
+ * Converts a widget path to a unique string identifier
12
+ */
13
+ declare function pathToId(path: WidgetPath): string;
14
+ /**
15
+ * Converts a path string back to a WidgetPath array
16
+ */
17
+ declare function idToPath(id: string): WidgetPath;
18
+ /**
19
+ * Ensures all widgets in an array have valid IDs
20
+ * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)
21
+ */
22
+ declare function ensureWidgetIds(widgets: readonly (WidgetSchema | null)[]): (WidgetSchema | null)[];
23
+ /**
24
+ * Deep clones a widget and regenerates all IDs (including nested children)
25
+ */
26
+ declare function deepCloneWidget(widget: WidgetSchema): WidgetSchema;
27
+ /**
28
+ * Deep clones an array of widgets and regenerates all IDs
29
+ */
30
+ declare function deepCloneWidgets(widgets: readonly WidgetSchema[]): WidgetSchema[];
31
+ /**
32
+ * Gets a widget at a specific path in the widget tree
33
+ */
34
+ declare function getWidgetByPath(screen: readonly (WidgetSchema | null)[], path: WidgetPath): WidgetSchema | null;
35
+ /**
36
+ * Groups children by column index.
37
+ * Accepts nullable children (sparse arrays from grid layouts) and filters them out.
38
+ */
39
+ declare function groupChildrenByColumn(children: readonly (WidgetSchema | null)[], columnCount: number): WidgetSchema[][];
40
+ //#endregion
41
+ //#region src/widget-utils/utils.d.ts
42
+ declare function createWidgetRegistry<T extends Record<string, ComponentType<any>>>(registry: T): T;
43
+ declare function createScreen<T extends Record<string, ComponentType<any>>>(registry: T, widgets: TypedWidgetSchema<T>[]): TypedWidgetSchema<T>[];
44
+ declare function createWidgetFromShareable(item: ShareableItem): WidgetSchema;
45
+ //#endregion
46
+ export { createScreen, createWidgetFromShareable, createWidgetRegistry, deepCloneWidget, deepCloneWidgets, ensureWidgetIds, generateWidgetId, getWidgetByPath, groupChildrenByColumn, idToPath, pathToId };
47
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +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"}
@@ -0,0 +1,119 @@
1
+ import { f as WIDGET_TYPE_NAMES, h as isWidgetType } from "../types-Bjmd7Fdx.mjs";
2
+ //#region src/widget-utils/widget-utils.ts
3
+ /**
4
+ * Generates a unique ID for a widget
5
+ */
6
+ function generateWidgetId(type) {
7
+ const uuid = crypto.randomUUID();
8
+ return type ? `${type}-${uuid}` : uuid;
9
+ }
10
+ /**
11
+ * Converts a widget path to a unique string identifier
12
+ */
13
+ function pathToId(path) {
14
+ return path.join("-");
15
+ }
16
+ /**
17
+ * Converts a path string back to a WidgetPath array
18
+ */
19
+ function idToPath(id) {
20
+ return id.split("-").map((segment) => parseInt(segment, 10));
21
+ }
22
+ /**
23
+ * Ensures all widgets in an array have valid IDs
24
+ * Note: Handles null values for sparse arrays (e.g., grid layouts with empty cells)
25
+ */
26
+ function ensureWidgetIds(widgets) {
27
+ return widgets?.map((widget, index) => {
28
+ if (!widget) return null;
29
+ return {
30
+ ...widget,
31
+ id: widget.id || `widget-${index}-${crypto.randomUUID()}`
32
+ };
33
+ });
34
+ }
35
+ /**
36
+ * Deep clones a widget and regenerates all IDs (including nested children)
37
+ */
38
+ function deepCloneWidget(widget) {
39
+ if (isWidgetType(widget, WIDGET_TYPE_NAMES.Layout) && Array.isArray(widget.props.children)) return {
40
+ type: widget.type,
41
+ props: {
42
+ ...widget.props,
43
+ children: widget.props.children.map((child) => child ? deepCloneWidget(child) : null)
44
+ },
45
+ id: generateWidgetId(widget.type)
46
+ };
47
+ return {
48
+ type: widget.type,
49
+ props: { ...widget.props },
50
+ id: generateWidgetId(widget.type)
51
+ };
52
+ }
53
+ /**
54
+ * Deep clones an array of widgets and regenerates all IDs
55
+ */
56
+ function deepCloneWidgets(widgets) {
57
+ return widgets.map((widget) => deepCloneWidget(widget));
58
+ }
59
+ /**
60
+ * Gets a widget at a specific path in the widget tree
61
+ */
62
+ function getWidgetByPath(screen, path) {
63
+ if (path.length === 0 || path[0] === void 0) return null;
64
+ let current = screen[path[0]] ?? null;
65
+ for (let i = 1; i < path.length; i++) {
66
+ if (!isWidgetType(current, WIDGET_TYPE_NAMES.Layout)) return null;
67
+ const children = current.props.children ?? [];
68
+ const index = path[i];
69
+ if (index === void 0) return null;
70
+ current = children[index] ?? null;
71
+ }
72
+ return current;
73
+ }
74
+ /**
75
+ * Groups children by column index.
76
+ * Accepts nullable children (sparse arrays from grid layouts) and filters them out.
77
+ */
78
+ function groupChildrenByColumn(children, columnCount) {
79
+ const columns = Array.from({ length: columnCount }, () => []);
80
+ const nonNullChildren = children.filter((child) => child !== null);
81
+ for (const child of nonNullChildren) {
82
+ const column = columns[Math.min(child.columnIndex ?? 0, columnCount - 1)];
83
+ if (column) column.push(child);
84
+ }
85
+ return columns;
86
+ }
87
+ //#endregion
88
+ //#region src/widget-utils/utils.ts
89
+ function createWidgetRegistry(registry) {
90
+ return registry;
91
+ }
92
+ function createScreen(registry, widgets) {
93
+ widgets.forEach((widget) => {
94
+ if (!(widget.type in registry)) throw new Error(`Widget type "${String(widget.type)}" not found in registry`);
95
+ });
96
+ return widgets;
97
+ }
98
+ function createWidgetFromShareable(item) {
99
+ if ((item.kind === "video" || !!item.videoUrl) && item.videoUrl) return {
100
+ type: "VideoWidget",
101
+ props: {
102
+ src: item.videoUrl,
103
+ poster: item.imageUrl,
104
+ caption: item.title
105
+ }
106
+ };
107
+ return {
108
+ type: "ImageWidget",
109
+ props: {
110
+ src: item.imageUrl,
111
+ alt: item.title || "Image",
112
+ objectFit: "cover"
113
+ }
114
+ };
115
+ }
116
+ //#endregion
117
+ export { createScreen, createWidgetFromShareable, createWidgetRegistry, deepCloneWidget, deepCloneWidgets, ensureWidgetIds, generateWidgetId, getWidgetByPath, groupChildrenByColumn, idToPath, pathToId };
118
+
119
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +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"}