@hai3/studio 0.3.0-alpha.2 → 0.4.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React3 = require('react');
3
+ var React2 = require('react');
4
4
  var react = require('@hai3/react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var uikit = require('@hai3/uikit');
@@ -8,7 +8,7 @@ var lodash = require('lodash');
8
8
 
9
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
10
 
11
- var React3__default = /*#__PURE__*/_interopDefault(React3);
11
+ var React2__default = /*#__PURE__*/_interopDefault(React2);
12
12
 
13
13
  var __create = Object.create;
14
14
  var __defProp = Object.defineProperty;
@@ -51,7 +51,8 @@ var require_en = __commonJS({
51
51
  screenset: "Screenset:",
52
52
  theme: "Theme:",
53
53
  language: "Language:",
54
- mockApi: "Mock API"
54
+ mockApi: "Mock API",
55
+ gts_package: "GTS Package"
55
56
  }
56
57
  };
57
58
  }
@@ -72,7 +73,8 @@ var require_ar = __commonJS({
72
73
  screenset: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0627\u0644\u0634\u0627\u0634\u0627\u062A:",
73
74
  theme: "\u0627\u0644\u0633\u0645\u0629:",
74
75
  language: "\u0627\u0644\u0644\u063A\u0629:",
75
- mockApi: "\u0648\u0627\u062C\u0647\u0629 \u0628\u0631\u0645\u062C\u064A\u0629 \u0648\u0647\u0645\u064A\u0629"
76
+ mockApi: "\u0648\u0627\u062C\u0647\u0629 \u0628\u0631\u0645\u062C\u064A\u0629 \u0648\u0647\u0645\u064A\u0629",
77
+ gts_package: "GTS Package"
76
78
  }
77
79
  };
78
80
  }
@@ -93,7 +95,8 @@ var require_bn = __commonJS({
93
95
  screenset: "\u09B8\u09CD\u0995\u09CD\u09B0\u09BF\u09A8\u09B8\u09C7\u099F:",
94
96
  theme: "\u09A5\u09BF\u09AE:",
95
97
  language: "\u09AD\u09BE\u09B7\u09BE:",
96
- mockApi: "\u09AE\u0995 API"
98
+ mockApi: "\u09AE\u0995 API",
99
+ gts_package: "GTS Package"
97
100
  }
98
101
  };
99
102
  }
@@ -114,7 +117,8 @@ var require_cs = __commonJS({
114
117
  screenset: "Sada obrazovek:",
115
118
  theme: "Motiv:",
116
119
  language: "Jazyk:",
117
- mockApi: "Simulovan\xE9 API"
120
+ mockApi: "Simulovan\xE9 API",
121
+ gts_package: "GTS Package"
118
122
  }
119
123
  };
120
124
  }
@@ -135,7 +139,8 @@ var require_da = __commonJS({
135
139
  screenset: "Sk\xE6rms\xE6t:",
136
140
  theme: "Tema:",
137
141
  language: "Sprog:",
138
- mockApi: "Mock-API"
142
+ mockApi: "Mock-API",
143
+ gts_package: "GTS Package"
139
144
  }
140
145
  };
141
146
  }
@@ -156,7 +161,8 @@ var require_de = __commonJS({
156
161
  screenset: "Bildschirmset:",
157
162
  theme: "Design:",
158
163
  language: "Sprache:",
159
- mockApi: "Mock-API"
164
+ mockApi: "Mock-API",
165
+ gts_package: "GTS Package"
160
166
  }
161
167
  };
162
168
  }
@@ -177,7 +183,8 @@ var require_el = __commonJS({
177
183
  screenset: "\u03A3\u03CD\u03BD\u03BF\u03BB\u03BF \u039F\u03B8\u03BF\u03BD\u03CE\u03BD:",
178
184
  theme: "\u0398\u03AD\u03BC\u03B1:",
179
185
  language: "\u0393\u03BB\u03CE\u03C3\u03C3\u03B1:",
180
- mockApi: "Mock API"
186
+ mockApi: "Mock API",
187
+ gts_package: "GTS Package"
181
188
  }
182
189
  };
183
190
  }
@@ -198,7 +205,8 @@ var require_es = __commonJS({
198
205
  screenset: "Conjunto de Pantallas:",
199
206
  theme: "Tema:",
200
207
  language: "Idioma:",
201
- mockApi: "API Simulada"
208
+ mockApi: "API Simulada",
209
+ gts_package: "GTS Package"
202
210
  }
203
211
  };
204
212
  }
@@ -219,7 +227,8 @@ var require_fa = __commonJS({
219
227
  screenset: "\u0645\u062C\u0645\u0648\u0639\u0647 \u0635\u0641\u062D\u0647\u200C\u0646\u0645\u0627\u06CC\u0634:",
220
228
  theme: "\u067E\u0648\u0633\u062A\u0647:",
221
229
  language: "\u0632\u0628\u0627\u0646:",
222
- mockApi: "API \u0633\u0627\u062E\u062A\u06AF\u06CC"
230
+ mockApi: "API \u0633\u0627\u062E\u062A\u06AF\u06CC",
231
+ gts_package: "GTS Package"
223
232
  }
224
233
  };
225
234
  }
@@ -240,7 +249,8 @@ var require_fi = __commonJS({
240
249
  screenset: "N\xE4ytt\xF6sarja:",
241
250
  theme: "Teema:",
242
251
  language: "Kieli:",
243
- mockApi: "Mock-API"
252
+ mockApi: "Mock-API",
253
+ gts_package: "GTS Package"
244
254
  }
245
255
  };
246
256
  }
@@ -261,7 +271,8 @@ var require_fr = __commonJS({
261
271
  screenset: "Ensemble d'\xC9crans:",
262
272
  theme: "Th\xE8me:",
263
273
  language: "Langue:",
264
- mockApi: "API Simul\xE9e"
274
+ mockApi: "API Simul\xE9e",
275
+ gts_package: "GTS Package"
265
276
  }
266
277
  };
267
278
  }
@@ -282,7 +293,8 @@ var require_he = __commonJS({
282
293
  screenset: "\u05E2\u05E8\u05DB\u05EA \u05DE\u05E1\u05DB\u05D9\u05DD:",
283
294
  theme: "\u05E2\u05E8\u05DB\u05EA \u05E0\u05D5\u05E9\u05D0:",
284
295
  language: "\u05E9\u05E4\u05D4:",
285
- mockApi: "API \u05DE\u05D3\u05D5\u05DE\u05D4"
296
+ mockApi: "API \u05DE\u05D3\u05D5\u05DE\u05D4",
297
+ gts_package: "GTS Package"
286
298
  }
287
299
  };
288
300
  }
@@ -303,7 +315,8 @@ var require_hi = __commonJS({
303
315
  screenset: "\u0938\u094D\u0915\u094D\u0930\u0940\u0928\u0938\u0947\u091F:",
304
316
  theme: "\u0925\u0940\u092E:",
305
317
  language: "\u092D\u093E\u0937\u093E:",
306
- mockApi: "\u092E\u0949\u0915 API"
318
+ mockApi: "\u092E\u0949\u0915 API",
319
+ gts_package: "GTS Package"
307
320
  }
308
321
  };
309
322
  }
@@ -324,7 +337,8 @@ var require_hu = __commonJS({
324
337
  screenset: "K\xE9perny\u0151k\xE9szlet:",
325
338
  theme: "T\xE9ma:",
326
339
  language: "Nyelv:",
327
- mockApi: "Mock API"
340
+ mockApi: "Mock API",
341
+ gts_package: "GTS Package"
328
342
  }
329
343
  };
330
344
  }
@@ -345,7 +359,8 @@ var require_id = __commonJS({
345
359
  screenset: "Set Layar:",
346
360
  theme: "Tema:",
347
361
  language: "Bahasa:",
348
- mockApi: "API Tiruan"
362
+ mockApi: "API Tiruan",
363
+ gts_package: "GTS Package"
349
364
  }
350
365
  };
351
366
  }
@@ -366,7 +381,8 @@ var require_it = __commonJS({
366
381
  screenset: "Set di Schermate:",
367
382
  theme: "Tema:",
368
383
  language: "Lingua:",
369
- mockApi: "API Simulata"
384
+ mockApi: "API Simulata",
385
+ gts_package: "GTS Package"
370
386
  }
371
387
  };
372
388
  }
@@ -387,7 +403,8 @@ var require_ja = __commonJS({
387
403
  screenset: "\u30B9\u30AF\u30EA\u30FC\u30F3\u30BB\u30C3\u30C8:",
388
404
  theme: "\u30C6\u30FC\u30DE:",
389
405
  language: "\u8A00\u8A9E:",
390
- mockApi: "\u30E2\u30C3\u30AF API"
406
+ mockApi: "\u30E2\u30C3\u30AF API",
407
+ gts_package: "GTS Package"
391
408
  }
392
409
  };
393
410
  }
@@ -408,7 +425,8 @@ var require_ko = __commonJS({
408
425
  screenset: "\uD654\uBA74 \uC138\uD2B8:",
409
426
  theme: "\uD14C\uB9C8:",
410
427
  language: "\uC5B8\uC5B4:",
411
- mockApi: "\uBAA8\uC758 API"
428
+ mockApi: "\uBAA8\uC758 API",
429
+ gts_package: "GTS Package"
412
430
  }
413
431
  };
414
432
  }
@@ -429,7 +447,8 @@ var require_ms = __commonJS({
429
447
  screenset: "Set Skrin:",
430
448
  theme: "Tema:",
431
449
  language: "Bahasa:",
432
- mockApi: "API Palsu"
450
+ mockApi: "API Palsu",
451
+ gts_package: "GTS Package"
433
452
  }
434
453
  };
435
454
  }
@@ -450,7 +469,8 @@ var require_nl = __commonJS({
450
469
  screenset: "Schermset:",
451
470
  theme: "Thema:",
452
471
  language: "Taal:",
453
- mockApi: "Nep-API"
472
+ mockApi: "Nep-API",
473
+ gts_package: "GTS Package"
454
474
  }
455
475
  };
456
476
  }
@@ -471,7 +491,8 @@ var require_no = __commonJS({
471
491
  screenset: "Skjermsett:",
472
492
  theme: "Tema:",
473
493
  language: "Spr\xE5k:",
474
- mockApi: "Mock-API"
494
+ mockApi: "Mock-API",
495
+ gts_package: "GTS Package"
475
496
  }
476
497
  };
477
498
  }
@@ -492,7 +513,8 @@ var require_pl = __commonJS({
492
513
  screenset: "Zestaw ekran\xF3w:",
493
514
  theme: "Motyw:",
494
515
  language: "J\u0119zyk:",
495
- mockApi: "Fikcyjne API"
516
+ mockApi: "Fikcyjne API",
517
+ gts_package: "GTS Package"
496
518
  }
497
519
  };
498
520
  }
@@ -513,7 +535,8 @@ var require_pt = __commonJS({
513
535
  screenset: "Conjunto de Telas:",
514
536
  theme: "Tema:",
515
537
  language: "Idioma:",
516
- mockApi: "API Simulada"
538
+ mockApi: "API Simulada",
539
+ gts_package: "GTS Package"
517
540
  }
518
541
  };
519
542
  }
@@ -534,7 +557,8 @@ var require_ro = __commonJS({
534
557
  screenset: "Set de Ecrane:",
535
558
  theme: "Tem\u0103:",
536
559
  language: "Limb\u0103:",
537
- mockApi: "API Simulat"
560
+ mockApi: "API Simulat",
561
+ gts_package: "GTS Package"
538
562
  }
539
563
  };
540
564
  }
@@ -555,7 +579,8 @@ var require_ru = __commonJS({
555
579
  screenset: "\u041D\u0430\u0431\u043E\u0440 \u044D\u043A\u0440\u0430\u043D\u043E\u0432:",
556
580
  theme: "\u0422\u0435\u043C\u0430:",
557
581
  language: "\u042F\u0437\u044B\u043A:",
558
- mockApi: "\u0424\u0438\u043A\u0442\u0438\u0432\u043D\u044B\u0439 API"
582
+ mockApi: "\u0424\u0438\u043A\u0442\u0438\u0432\u043D\u044B\u0439 API",
583
+ gts_package: "GTS Package"
559
584
  }
560
585
  };
561
586
  }
@@ -576,7 +601,8 @@ var require_sv = __commonJS({
576
601
  screenset: "Sk\xE4rmupps\xE4ttning:",
577
602
  theme: "Tema:",
578
603
  language: "Spr\xE5k:",
579
- mockApi: "Mock-API"
604
+ mockApi: "Mock-API",
605
+ gts_package: "GTS Package"
580
606
  }
581
607
  };
582
608
  }
@@ -597,7 +623,8 @@ var require_sw = __commonJS({
597
623
  screenset: "Seti ya Skrini:",
598
624
  theme: "Mandhari:",
599
625
  language: "Lugha:",
600
- mockApi: "API ya Majaribio"
626
+ mockApi: "API ya Majaribio",
627
+ gts_package: "GTS Package"
601
628
  }
602
629
  };
603
630
  }
@@ -618,7 +645,8 @@ var require_ta = __commonJS({
618
645
  screenset: "\u0BA4\u0BBF\u0BB0\u0BC8\u0BA4\u0BCD \u0BA4\u0BCA\u0B95\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1:",
619
646
  theme: "\u0BA4\u0BC0\u0BAE\u0BCD:",
620
647
  language: "\u0BAE\u0BCA\u0BB4\u0BBF:",
621
- mockApi: "\u0BAA\u0BCB\u0BB2\u0BBF API"
648
+ mockApi: "\u0BAA\u0BCB\u0BB2\u0BBF API",
649
+ gts_package: "GTS Package"
622
650
  }
623
651
  };
624
652
  }
@@ -639,7 +667,8 @@ var require_th = __commonJS({
639
667
  screenset: "\u0E0A\u0E38\u0E14\u0E2B\u0E19\u0E49\u0E32\u0E08\u0E2D:",
640
668
  theme: "\u0E18\u0E35\u0E21:",
641
669
  language: "\u0E20\u0E32\u0E29\u0E32:",
642
- mockApi: "API \u0E08\u0E33\u0E25\u0E2D\u0E07"
670
+ mockApi: "API \u0E08\u0E33\u0E25\u0E2D\u0E07",
671
+ gts_package: "GTS Package"
643
672
  }
644
673
  };
645
674
  }
@@ -660,7 +689,8 @@ var require_tl = __commonJS({
660
689
  screenset: "Hanay ng Screen:",
661
690
  theme: "Tema:",
662
691
  language: "Wika:",
663
- mockApi: "Mock API"
692
+ mockApi: "Mock API",
693
+ gts_package: "GTS Package"
664
694
  }
665
695
  };
666
696
  }
@@ -681,7 +711,8 @@ var require_tr = __commonJS({
681
711
  screenset: "Ekran Seti:",
682
712
  theme: "Tema:",
683
713
  language: "Dil:",
684
- mockApi: "Sahte API"
714
+ mockApi: "Sahte API",
715
+ gts_package: "GTS Package"
685
716
  }
686
717
  };
687
718
  }
@@ -702,7 +733,8 @@ var require_uk = __commonJS({
702
733
  screenset: "\u041D\u0430\u0431\u0456\u0440 \u0435\u043A\u0440\u0430\u043D\u0456\u0432:",
703
734
  theme: "\u0422\u0435\u043C\u0430:",
704
735
  language: "\u041C\u043E\u0432\u0430:",
705
- mockApi: "\u0424\u0456\u043A\u0442\u0438\u0432\u043D\u0438\u0439 API"
736
+ mockApi: "\u0424\u0456\u043A\u0442\u0438\u0432\u043D\u0438\u0439 API",
737
+ gts_package: "GTS Package"
706
738
  }
707
739
  };
708
740
  }
@@ -723,7 +755,8 @@ var require_ur = __commonJS({
723
755
  screenset: "\u0627\u0633\u06A9\u0631\u06CC\u0646 \u0633\u06CC\u0679:",
724
756
  theme: "\u062A\u06BE\u06CC\u0645:",
725
757
  language: "\u0632\u0628\u0627\u0646:",
726
- mockApi: "\u0641\u0631\u0636\u06CC API"
758
+ mockApi: "\u0641\u0631\u0636\u06CC API",
759
+ gts_package: "GTS Package"
727
760
  }
728
761
  };
729
762
  }
@@ -744,7 +777,8 @@ var require_vi = __commonJS({
744
777
  screenset: "B\u1ED9 M\xE0n h\xECnh:",
745
778
  theme: "Ch\u1EE7 \u0111\u1EC1:",
746
779
  language: "Ng\xF4n ng\u1EEF:",
747
- mockApi: "API Gi\u1EA3 l\u1EADp"
780
+ mockApi: "API Gi\u1EA3 l\u1EADp",
781
+ gts_package: "GTS Package"
748
782
  }
749
783
  };
750
784
  }
@@ -765,7 +799,8 @@ var require_zh_TW = __commonJS({
765
799
  screenset: "\u87A2\u5E55\u96C6:",
766
800
  theme: "\u4E3B\u984C:",
767
801
  language: "\u8A9E\u8A00:",
768
- mockApi: "\u6A21\u64EC API"
802
+ mockApi: "\u6A21\u64EC API",
803
+ gts_package: "GTS Package"
769
804
  }
770
805
  };
771
806
  }
@@ -786,7 +821,8 @@ var require_zh = __commonJS({
786
821
  screenset: "\u5C4F\u5E55\u96C6:",
787
822
  theme: "\u4E3B\u9898:",
788
823
  language: "\u8BED\u8A00:",
789
- mockApi: "\u6A21\u62DF API"
824
+ mockApi: "\u6A21\u62DF API",
825
+ gts_package: "GTS Package"
790
826
  }
791
827
  };
792
828
  }
@@ -828,14 +864,19 @@ var STORAGE_KEYS = {
828
864
  POSITION: `${STORAGE_PREFIX}position`,
829
865
  SIZE: `${STORAGE_PREFIX}size`,
830
866
  COLLAPSED: `${STORAGE_PREFIX}collapsed`,
831
- BUTTON_POSITION: `${STORAGE_PREFIX}buttonPosition`
867
+ BUTTON_POSITION: `${STORAGE_PREFIX}buttonPosition`,
868
+ THEME: `${STORAGE_PREFIX}theme`,
869
+ LANGUAGE: `${STORAGE_PREFIX}language`,
870
+ MOCK_ENABLED: `${STORAGE_PREFIX}mockEnabled`,
871
+ ACTIVE_PACKAGE_ID: `${STORAGE_PREFIX}activePackageId`
832
872
  };
833
873
 
834
874
  // src/events/studioEvents.ts
835
875
  var StudioEvents = {
836
876
  PositionChanged: "studio/positionChanged",
837
877
  SizeChanged: "studio/sizeChanged",
838
- ButtonPositionChanged: "studio/buttonPositionChanged"
878
+ ButtonPositionChanged: "studio/buttonPositionChanged",
879
+ ActivePackageChanged: "studio/activePackageChanged"
839
880
  };
840
881
 
841
882
  // src/effects/persistenceEffects.ts
@@ -858,12 +899,82 @@ var initPersistenceEffects = () => {
858
899
  saveStudioState(STORAGE_KEYS.BUTTON_POSITION, position);
859
900
  }
860
901
  );
902
+ const themeSubscription = react.eventBus.on("theme/changed", (payload) => {
903
+ saveStudioState(STORAGE_KEYS.THEME, payload.themeId);
904
+ });
905
+ const languageSubscription = react.eventBus.on("i18n/language/changed", (payload) => {
906
+ saveStudioState(STORAGE_KEYS.LANGUAGE, payload.language);
907
+ });
908
+ const mockSubscription = react.eventBus.on("mock/toggle", (payload) => {
909
+ saveStudioState(STORAGE_KEYS.MOCK_ENABLED, payload.enabled);
910
+ });
911
+ const activePackageSubscription = react.eventBus.on(
912
+ StudioEvents.ActivePackageChanged,
913
+ ({ activePackageId }) => {
914
+ saveStudioState(STORAGE_KEYS.ACTIVE_PACKAGE_ID, activePackageId);
915
+ }
916
+ );
861
917
  return () => {
862
918
  positionSubscription.unsubscribe();
863
919
  sizeSubscription.unsubscribe();
864
920
  buttonPositionSubscription.unsubscribe();
921
+ themeSubscription.unsubscribe();
922
+ languageSubscription.unsubscribe();
923
+ mockSubscription.unsubscribe();
924
+ activePackageSubscription.unsubscribe();
865
925
  };
866
926
  };
927
+ function isScreenExtension(ext) {
928
+ return "presentation" in ext && typeof ext.presentation === "object";
929
+ }
930
+ var useRestoreStudioSettings = () => {
931
+ const restoredRef = React2.useRef(false);
932
+ React2.useEffect(() => {
933
+ if (restoredRef.current) return;
934
+ restoredRef.current = true;
935
+ const themeId = loadStudioState(STORAGE_KEYS.THEME, null);
936
+ if (themeId != null && typeof themeId === "string" && themeId.length > 0) {
937
+ react.eventBus.emit("theme/changed", { themeId });
938
+ }
939
+ const language = loadStudioState(STORAGE_KEYS.LANGUAGE, null);
940
+ if (language != null && typeof language === "string" && language.length > 0) {
941
+ react.eventBus.emit("i18n/language/changed", { language });
942
+ }
943
+ const mockEnabled = loadStudioState(STORAGE_KEYS.MOCK_ENABLED, null);
944
+ if (typeof mockEnabled === "boolean") {
945
+ react.eventBus.emit("mock/toggle", { enabled: mockEnabled });
946
+ }
947
+ }, []);
948
+ };
949
+ var useRestoreGtsPackage = (registry) => {
950
+ const restoredRef = React2.useRef(false);
951
+ React2.useEffect(() => {
952
+ if (restoredRef.current || !registry) return;
953
+ const activePackageId = loadStudioState(STORAGE_KEYS.ACTIVE_PACKAGE_ID, null);
954
+ if (!activePackageId || typeof activePackageId !== "string") return;
955
+ restoredRef.current = true;
956
+ const restore = async () => {
957
+ try {
958
+ const extensions = registry.getExtensionsForPackage(activePackageId);
959
+ const screenExtensions = extensions.filter(
960
+ (ext) => ext.domain === react.HAI3_SCREEN_DOMAIN && isScreenExtension(ext)
961
+ );
962
+ if (screenExtensions.length === 0) return;
963
+ screenExtensions.sort((a, b) => (a.presentation.order ?? 0) - (b.presentation.order ?? 0));
964
+ const firstExtension = screenExtensions[0];
965
+ await registry.executeActionsChain({
966
+ action: {
967
+ type: react.HAI3_ACTION_MOUNT_EXT,
968
+ target: react.HAI3_SCREEN_DOMAIN,
969
+ payload: { extensionId: firstExtension.id }
970
+ }
971
+ });
972
+ } catch {
973
+ }
974
+ };
975
+ void restore();
976
+ }, [registry]);
977
+ };
867
978
  var studioTranslations = react.I18nRegistry.createLoader({
868
979
  [react.Language.English]: () => Promise.resolve().then(() => __toESM(require_en())),
869
980
  [react.Language.Arabic]: () => Promise.resolve().then(() => __toESM(require_ar())),
@@ -903,31 +1014,37 @@ var studioTranslations = react.I18nRegistry.createLoader({
903
1014
  [react.Language.ChineseSimplified]: () => Promise.resolve().then(() => __toESM(require_zh()))
904
1015
  });
905
1016
  react.i18nRegistry.registerLoader("studio", studioTranslations);
906
- var StudioContext = React3.createContext(void 0);
1017
+ var StudioContext = React2.createContext(void 0);
1018
+ var RestoreGtsPackageOnMount = () => {
1019
+ const app = react.useHAI3();
1020
+ useRestoreGtsPackage(app.screensetsRegistry);
1021
+ return null;
1022
+ };
907
1023
  var useStudioContext = () => {
908
- const context = React3.useContext(StudioContext);
1024
+ const context = React2.useContext(StudioContext);
909
1025
  if (!context) {
910
1026
  throw new Error("useStudioContext must be used within StudioProvider");
911
1027
  }
912
1028
  return context;
913
1029
  };
914
1030
  var StudioProvider = ({ children }) => {
915
- const [collapsed, setCollapsed] = React3.useState(
1031
+ const [collapsed, setCollapsed] = React2.useState(
916
1032
  () => loadStudioState(STORAGE_KEYS.COLLAPSED, false)
917
1033
  );
918
- const [portalContainer, setPortalContainer] = React3.useState(null);
919
- React3.useEffect(() => {
1034
+ const [portalContainer, setPortalContainer] = React2.useState(null);
1035
+ React2.useEffect(() => {
920
1036
  const cleanup = initPersistenceEffects();
921
1037
  return cleanup;
922
1038
  }, []);
923
- const toggleCollapsed = React3.useCallback(() => {
1039
+ useRestoreStudioSettings();
1040
+ const toggleCollapsed = React2.useCallback(() => {
924
1041
  setCollapsed((prev) => {
925
1042
  const newValue = !prev;
926
1043
  saveStudioState(STORAGE_KEYS.COLLAPSED, newValue);
927
1044
  return newValue;
928
1045
  });
929
1046
  }, []);
930
- return /* @__PURE__ */ jsxRuntime.jsx(
1047
+ return /* @__PURE__ */ jsxRuntime.jsxs(
931
1048
  StudioContext.Provider,
932
1049
  {
933
1050
  value: {
@@ -936,7 +1053,10 @@ var StudioProvider = ({ children }) => {
936
1053
  portalContainer,
937
1054
  setPortalContainer
938
1055
  },
939
- children
1056
+ children: [
1057
+ /* @__PURE__ */ jsxRuntime.jsx(RestoreGtsPackageOnMount, {}),
1058
+ children
1059
+ ]
940
1060
  }
941
1061
  );
942
1062
  };
@@ -955,19 +1075,19 @@ var useDraggable = ({ panelSize, storageKey = STORAGE_KEYS.POSITION }) => {
955
1075
  x: window.innerWidth - panelSize.width - VIEWPORT_MARGIN,
956
1076
  y: window.innerHeight - panelSize.height - VIEWPORT_MARGIN
957
1077
  });
958
- const [position, setPosition] = React3.useState(
1078
+ const [position, setPosition] = React2.useState(
959
1079
  () => clampToViewport(loadStudioState(storageKey, getDefaultPosition()), panelSize)
960
1080
  );
961
- const [isDragging, setIsDragging] = React3.useState(false);
962
- const dragStartPos = React3.useRef({ x: 0, y: 0 });
963
- const handleMouseDown = React3.useCallback((e) => {
1081
+ const [isDragging, setIsDragging] = React2.useState(false);
1082
+ const dragStartPos = React2.useRef({ x: 0, y: 0 });
1083
+ const handleMouseDown = React2.useCallback((e) => {
964
1084
  setIsDragging(true);
965
1085
  dragStartPos.current = {
966
1086
  x: e.clientX - position.x,
967
1087
  y: e.clientY - position.y
968
1088
  };
969
1089
  }, [position]);
970
- React3.useEffect(() => {
1090
+ React2.useEffect(() => {
971
1091
  if (!isDragging) return;
972
1092
  const handleMouseMove = (e) => {
973
1093
  const maxX = Math.max(VIEWPORT_MARGIN, window.innerWidth - panelSize.width - VIEWPORT_MARGIN);
@@ -989,7 +1109,7 @@ var useDraggable = ({ panelSize, storageKey = STORAGE_KEYS.POSITION }) => {
989
1109
  window.removeEventListener("mouseup", handleMouseUp);
990
1110
  };
991
1111
  }, [isDragging, panelSize.width, panelSize.height, storageKey]);
992
- React3.useEffect(() => {
1112
+ React2.useEffect(() => {
993
1113
  const handleResize = () => {
994
1114
  setPosition((prev) => {
995
1115
  const clamped = clampToViewport(prev, panelSize);
@@ -1009,15 +1129,15 @@ var useDraggable = ({ panelSize, storageKey = STORAGE_KEYS.POSITION }) => {
1009
1129
  };
1010
1130
  };
1011
1131
  var useResizable = () => {
1012
- const [size, setSize] = React3.useState(
1132
+ const [size, setSize] = React2.useState(
1013
1133
  () => loadStudioState(STORAGE_KEYS.SIZE, {
1014
1134
  width: PANEL_CONSTRAINTS.DEFAULT_WIDTH,
1015
1135
  height: PANEL_CONSTRAINTS.DEFAULT_HEIGHT
1016
1136
  })
1017
1137
  );
1018
- const [isResizing, setIsResizing] = React3.useState(false);
1019
- const resizeStartRef = React3.useRef(null);
1020
- const handleMouseDown = React3.useCallback((e) => {
1138
+ const [isResizing, setIsResizing] = React2.useState(false);
1139
+ const resizeStartRef = React2.useRef(null);
1140
+ const handleMouseDown = React2.useCallback((e) => {
1021
1141
  e.stopPropagation();
1022
1142
  resizeStartRef.current = {
1023
1143
  mouseX: e.clientX,
@@ -1027,7 +1147,7 @@ var useResizable = () => {
1027
1147
  };
1028
1148
  setIsResizing(true);
1029
1149
  }, [size.width, size.height]);
1030
- React3.useEffect(() => {
1150
+ React2.useEffect(() => {
1031
1151
  if (!isResizing || !resizeStartRef.current) return;
1032
1152
  const startState = resizeStartRef.current;
1033
1153
  document.body.style.userSelect = "none";
@@ -1070,6 +1190,64 @@ var useResizable = () => {
1070
1190
  handleMouseDown
1071
1191
  };
1072
1192
  };
1193
+ function isScreenExtension2(ext) {
1194
+ return "presentation" in ext && typeof ext.presentation === "object";
1195
+ }
1196
+ var MfePackageSelector = ({
1197
+ className = ""
1198
+ }) => {
1199
+ const app = react.useHAI3();
1200
+ const registry = app.screensetsRegistry;
1201
+ const { portalContainer } = useStudioContext();
1202
+ const { t } = react.useTranslation();
1203
+ const packages = react.useRegisteredPackages();
1204
+ const activePackage = react.useActivePackage();
1205
+ if (!registry) {
1206
+ return null;
1207
+ }
1208
+ const handlePackageChange = async (selectedPackageId) => {
1209
+ const extensions = registry.getExtensionsForPackage(selectedPackageId);
1210
+ const screenExtensions = extensions.filter(
1211
+ (ext) => ext.domain === react.HAI3_SCREEN_DOMAIN && isScreenExtension2(ext)
1212
+ );
1213
+ if (screenExtensions.length === 0) {
1214
+ console.warn(`No screen extensions found for package: ${selectedPackageId}`);
1215
+ return;
1216
+ }
1217
+ screenExtensions.sort((a, b) => (a.presentation.order ?? 0) - (b.presentation.order ?? 0));
1218
+ const firstExtension = screenExtensions[0];
1219
+ await registry.executeActionsChain({
1220
+ action: {
1221
+ type: react.HAI3_ACTION_MOUNT_EXT,
1222
+ target: react.HAI3_SCREEN_DOMAIN,
1223
+ payload: { extensionId: firstExtension.id }
1224
+ }
1225
+ });
1226
+ react.eventBus.emit(StudioEvents.ActivePackageChanged, { activePackageId: selectedPackageId });
1227
+ };
1228
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
1229
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.gts_package") }),
1230
+ /* @__PURE__ */ jsxRuntime.jsxs(uikit.DropdownMenu, { children: [
1231
+ /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1232
+ uikit.DropdownButton,
1233
+ {
1234
+ variant: uikit.ButtonVariant.Outline,
1235
+ disabled: packages.length <= 1,
1236
+ children: activePackage || "No package"
1237
+ }
1238
+ ) }),
1239
+ /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: packages.map((pkg) => /* @__PURE__ */ jsxRuntime.jsx(
1240
+ uikit.DropdownMenuItem,
1241
+ {
1242
+ onClick: () => handlePackageChange(pkg),
1243
+ children: pkg
1244
+ },
1245
+ pkg
1246
+ )) })
1247
+ ] })
1248
+ ] });
1249
+ };
1250
+ MfePackageSelector.displayName = "MfePackageSelector";
1073
1251
  var ThemeSelector = ({
1074
1252
  className = ""
1075
1253
  }) => {
@@ -1095,46 +1273,6 @@ var ThemeSelector = ({
1095
1273
  ] });
1096
1274
  };
1097
1275
  ThemeSelector.displayName = "ThemeSelector";
1098
- var ScreensetSelector = ({
1099
- options,
1100
- currentValue,
1101
- onChange,
1102
- className = ""
1103
- }) => {
1104
- const { portalContainer } = useStudioContext();
1105
- const { t, isRTL } = react.useTranslation();
1106
- const formatName = (name) => {
1107
- return name.split(/[-_]/).map((word) => lodash.upperFirst(word)).join(" ");
1108
- };
1109
- const getCurrentDisplay = () => {
1110
- const [category, itemId] = currentValue.split(":");
1111
- if (!category || !itemId) return "Select";
1112
- const categoryGroup = options.find((opt) => opt.category === category);
1113
- const item = categoryGroup?.screensets.find((i) => i.id === itemId);
1114
- return item ? item.name : "Select";
1115
- };
1116
- const handleItemClick = (category, itemId) => {
1117
- onChange(`${category}:${itemId}`);
1118
- };
1119
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
1120
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.screenset") }),
1121
- /* @__PURE__ */ jsxRuntime.jsxs(uikit.DropdownMenu, { dir: isRTL ? "rtl" : "ltr", children: [
1122
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownButton, { variant: uikit.ButtonVariant.Outline, children: formatName(getCurrentDisplay()) }) }),
1123
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: options.map((categoryGroup) => /* @__PURE__ */ jsxRuntime.jsxs(uikit.DropdownMenuSub, { children: [
1124
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuSubTrigger, { disabled: categoryGroup.screensets.length === 0, children: formatName(categoryGroup.category) }),
1125
- /* @__PURE__ */ jsxRuntime.jsx(uikit.DropdownMenuSubContent, { container: portalContainer, className: "z-[99999] pointer-events-auto", children: categoryGroup.screensets.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
1126
- uikit.DropdownMenuItem,
1127
- {
1128
- onClick: () => handleItemClick(categoryGroup.category, item.id),
1129
- children: formatName(item.name)
1130
- },
1131
- item.id
1132
- )) })
1133
- ] }, categoryGroup.category)) })
1134
- ] })
1135
- ] });
1136
- };
1137
- ScreensetSelector.displayName = "ScreensetSelector";
1138
1276
  var FALLBACK_SELECT_LANGUAGE_TEXT = "Select language";
1139
1277
  var RTL_INDICATOR_SUFFIX = " (RTL)";
1140
1278
  function LanguageSelector({
@@ -1192,48 +1330,12 @@ var ApiModeToggle = ({
1192
1330
  ] });
1193
1331
  };
1194
1332
  ApiModeToggle.displayName = "ApiModeToggle";
1195
- var ALL_CATEGORIES = [react.ScreensetCategory.Drafts, react.ScreensetCategory.Mockups, react.ScreensetCategory.Production];
1196
- var buildScreensetOptions = () => {
1197
- const allScreensets = react.screensetRegistry.getAll();
1198
- return ALL_CATEGORIES.map((category) => ({
1199
- category,
1200
- screensets: allScreensets.filter((s) => s.category === category).map((s) => ({
1201
- id: s.id,
1202
- name: s.name
1203
- }))
1204
- }));
1205
- };
1206
1333
  var ControlPanel = () => {
1207
- const { currentScreenset, navigateToScreenset } = react.useNavigation();
1208
- const [screensetOptions, setScreensetOptions] = React3.useState([]);
1209
1334
  const { t } = react.useTranslation();
1210
- React3.useEffect(() => {
1211
- const options = buildScreensetOptions();
1212
- setScreensetOptions(options);
1213
- }, []);
1214
- const getCurrentValue = () => {
1215
- if (!currentScreenset) return "";
1216
- const screenset = react.screensetRegistry.get(currentScreenset);
1217
- if (!screenset) return "";
1218
- return `${screenset.category}:${screenset.id}`;
1219
- };
1220
- const handleScreensetChange = (value) => {
1221
- const [, screensetId] = value.split(":");
1222
- if (screensetId) {
1223
- navigateToScreenset(screensetId);
1224
- }
1225
- };
1226
1335
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
1227
1336
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: t("studio:controls.heading") }),
1228
1337
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
1229
- screensetOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1230
- ScreensetSelector,
1231
- {
1232
- options: screensetOptions,
1233
- currentValue: getCurrentValue(),
1234
- onChange: handleScreensetChange
1235
- }
1236
- ),
1338
+ /* @__PURE__ */ jsxRuntime.jsx(MfePackageSelector, {}),
1237
1339
  /* @__PURE__ */ jsxRuntime.jsx(ApiModeToggle, {}),
1238
1340
  /* @__PURE__ */ jsxRuntime.jsx(ThemeSelector, {}),
1239
1341
  /* @__PURE__ */ jsxRuntime.jsx(LanguageSelector, {})
@@ -1244,13 +1346,13 @@ ControlPanel.displayName = "ControlPanel";
1244
1346
  var StudioPanel = () => {
1245
1347
  const { toggleCollapsed, setPortalContainer } = useStudioContext();
1246
1348
  const { t } = react.useTranslation();
1247
- const portalRef = React3__default.default.useRef(null);
1349
+ const portalRef = React2__default.default.useRef(null);
1248
1350
  const { size, handleMouseDown: handleResizeMouseDown } = useResizable();
1249
1351
  const { position, isDragging, handleMouseDown: handleDragMouseDown } = useDraggable({
1250
1352
  panelSize: size,
1251
1353
  storageKey: STORAGE_KEYS.POSITION
1252
1354
  });
1253
- React3__default.default.useEffect(() => {
1355
+ React2__default.default.useEffect(() => {
1254
1356
  setPortalContainer(portalRef.current);
1255
1357
  return () => setPortalContainer(null);
1256
1358
  }, [setPortalContainer]);
@@ -1341,7 +1443,7 @@ var StudioPanel = () => {
1341
1443
  };
1342
1444
  StudioPanel.displayName = "StudioPanel";
1343
1445
  var useKeyboardShortcut = (handler) => {
1344
- React3.useEffect(() => {
1446
+ React2.useEffect(() => {
1345
1447
  const handleKeyDown = (e) => {
1346
1448
  if (e.shiftKey && e.code === "Backquote") {
1347
1449
  e.preventDefault();
@@ -1401,7 +1503,7 @@ var CollapsedButton = ({ toggleCollapsed }) => {
1401
1503
  panelSize: BUTTON_SIZE,
1402
1504
  storageKey: STORAGE_KEYS.BUTTON_POSITION
1403
1505
  });
1404
- const dragStartPosition = React3.useRef(null);
1506
+ const dragStartPosition = React2.useRef(null);
1405
1507
  const handleButtonMouseDown = (e) => {
1406
1508
  dragStartPosition.current = { x: e.clientX, y: e.clientY };
1407
1509
  handleMouseDown(e);