@gxp-dev/tools 2.0.6 → 2.0.7

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 (99) hide show
  1. package/browser-extensions/README.md +1 -0
  2. package/browser-extensions/chrome/background.js +857 -0
  3. package/browser-extensions/chrome/content.js +51 -0
  4. package/browser-extensions/chrome/devtools.html +9 -0
  5. package/browser-extensions/chrome/devtools.js +23 -0
  6. package/browser-extensions/chrome/icons/gx_off_128.png +0 -0
  7. package/browser-extensions/chrome/icons/gx_off_16.png +0 -0
  8. package/browser-extensions/chrome/icons/gx_off_32.png +0 -0
  9. package/browser-extensions/chrome/icons/gx_off_64.png +0 -0
  10. package/browser-extensions/chrome/icons/gx_on_128.png +0 -0
  11. package/browser-extensions/chrome/icons/gx_on_16.png +0 -0
  12. package/browser-extensions/chrome/icons/gx_on_32.png +0 -0
  13. package/browser-extensions/chrome/icons/gx_on_64.png +0 -0
  14. package/browser-extensions/chrome/inspector.js +1087 -0
  15. package/browser-extensions/chrome/manifest.json +70 -0
  16. package/browser-extensions/chrome/panel.html +638 -0
  17. package/browser-extensions/chrome/panel.js +862 -0
  18. package/browser-extensions/chrome/popup.html +399 -0
  19. package/browser-extensions/chrome/popup.js +515 -0
  20. package/browser-extensions/chrome/rules.json +1 -0
  21. package/browser-extensions/chrome/test-chrome.html +145 -0
  22. package/browser-extensions/chrome/test-mixed-content.html +190 -0
  23. package/browser-extensions/chrome/test-uri-pattern.html +199 -0
  24. package/browser-extensions/firefox/README.md +134 -0
  25. package/browser-extensions/firefox/background.js +804 -0
  26. package/browser-extensions/firefox/content.js +120 -0
  27. package/browser-extensions/firefox/debug-errors.html +229 -0
  28. package/browser-extensions/firefox/debug-https.html +113 -0
  29. package/browser-extensions/firefox/devtools.html +9 -0
  30. package/browser-extensions/firefox/devtools.js +24 -0
  31. package/browser-extensions/firefox/icons/gx_off_128.png +0 -0
  32. package/browser-extensions/firefox/icons/gx_off_16.png +0 -0
  33. package/browser-extensions/firefox/icons/gx_off_32.png +0 -0
  34. package/browser-extensions/firefox/icons/gx_off_64.png +0 -0
  35. package/browser-extensions/firefox/icons/gx_on_128.png +0 -0
  36. package/browser-extensions/firefox/icons/gx_on_16.png +0 -0
  37. package/browser-extensions/firefox/icons/gx_on_32.png +0 -0
  38. package/browser-extensions/firefox/icons/gx_on_64.png +0 -0
  39. package/browser-extensions/firefox/inspector.js +1087 -0
  40. package/browser-extensions/firefox/manifest.json +67 -0
  41. package/browser-extensions/firefox/panel.html +638 -0
  42. package/browser-extensions/firefox/panel.js +862 -0
  43. package/browser-extensions/firefox/popup.html +525 -0
  44. package/browser-extensions/firefox/popup.js +536 -0
  45. package/browser-extensions/firefox/test-gramercy.html +126 -0
  46. package/browser-extensions/firefox/test-imports.html +58 -0
  47. package/browser-extensions/firefox/test-masking.html +147 -0
  48. package/browser-extensions/firefox/test-uri-pattern.html +199 -0
  49. package/package.json +7 -2
  50. package/runtime/PortalContainer.vue +326 -0
  51. package/runtime/dev-tools/DevToolsModal.vue +217 -0
  52. package/runtime/dev-tools/LayoutSwitcher.vue +221 -0
  53. package/runtime/dev-tools/MockDataEditor.vue +621 -0
  54. package/runtime/dev-tools/SocketSimulator.vue +562 -0
  55. package/runtime/dev-tools/StoreInspector.vue +644 -0
  56. package/runtime/dev-tools/index.js +6 -0
  57. package/runtime/gxpStringsPlugin.js +428 -0
  58. package/runtime/index.html +22 -0
  59. package/runtime/main.js +32 -0
  60. package/runtime/mock-api/auth-middleware.js +97 -0
  61. package/runtime/mock-api/image-generator.js +221 -0
  62. package/runtime/mock-api/index.js +197 -0
  63. package/runtime/mock-api/response-generator.js +394 -0
  64. package/runtime/mock-api/route-generator.js +323 -0
  65. package/runtime/mock-api/socket-triggers.js +371 -0
  66. package/runtime/mock-api/spec-loader.js +300 -0
  67. package/runtime/server.js +180 -0
  68. package/runtime/stores/gxpPortalConfigStore.js +554 -0
  69. package/runtime/stores/index.js +6 -0
  70. package/runtime/vite-inspector-plugin.js +749 -0
  71. package/runtime/vite-source-tracker-plugin.js +232 -0
  72. package/runtime/vite.config.js +402 -0
  73. package/scripts/launch-chrome.js +90 -0
  74. package/scripts/pack-chrome.js +91 -0
  75. package/socket-events/AiSessionMessageCreated.json +18 -0
  76. package/socket-events/SocialStreamPostCreated.json +24 -0
  77. package/socket-events/SocialStreamPostVariantCompleted.json +23 -0
  78. package/template/README.md +332 -0
  79. package/template/app-manifest.json +32 -0
  80. package/template/dev-assets/images/avatar-placeholder.png +0 -0
  81. package/template/dev-assets/images/background-placeholder.jpg +0 -0
  82. package/template/dev-assets/images/banner-placeholder.jpg +0 -0
  83. package/template/dev-assets/images/icon-placeholder.png +0 -0
  84. package/template/dev-assets/images/logo-placeholder.png +0 -0
  85. package/template/dev-assets/images/product-placeholder.jpg +0 -0
  86. package/template/dev-assets/images/thumbnail-placeholder.jpg +0 -0
  87. package/template/env.example +51 -0
  88. package/template/gitignore +53 -0
  89. package/template/index.html +22 -0
  90. package/template/main.js +28 -0
  91. package/template/src/DemoPage.vue +459 -0
  92. package/template/src/Plugin.vue +38 -0
  93. package/template/src/stores/index.js +9 -0
  94. package/template/src/stores/test-data.json +173 -0
  95. package/template/theme-layouts/AdditionalStyling.css +0 -0
  96. package/template/theme-layouts/PrivateLayout.vue +39 -0
  97. package/template/theme-layouts/PublicLayout.vue +39 -0
  98. package/template/theme-layouts/SystemLayout.vue +39 -0
  99. package/template/vite.config.js +333 -0
@@ -0,0 +1,554 @@
1
+ import { defineStore } from "pinia";
2
+ import { ref, computed, reactive } from "vue";
3
+ import axios from "axios";
4
+ import { io } from "socket.io-client";
5
+
6
+ // Environment URL configuration (matches constants.js ENVIRONMENT_URLS)
7
+ const ENVIRONMENT_URLS = {
8
+ production: {
9
+ apiBaseUrl: "https://api.gramercy.cloud",
10
+ },
11
+ staging: {
12
+ apiBaseUrl: "https://api.efz-staging.env.eventfinity.app",
13
+ },
14
+ testing: {
15
+ apiBaseUrl: "https://api.zenith-develop-testing.env.eventfinity.app",
16
+ },
17
+ develop: {
18
+ apiBaseUrl: "https://api.zenith-develop.env.eventfinity.app",
19
+ },
20
+ local: {
21
+ apiBaseUrl: "https://dashboard.eventfinity.test",
22
+ },
23
+ };
24
+
25
+ /**
26
+ * Generate a random bearer token for mock API
27
+ */
28
+ function generateMockToken() {
29
+ const chars =
30
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
31
+ let token = "";
32
+ for (let i = 0; i < 32; i++) {
33
+ token += chars.charAt(Math.floor(Math.random() * chars.length));
34
+ }
35
+ return token;
36
+ }
37
+
38
+ /**
39
+ * Get API configuration based on API_ENV environment variable
40
+ * During development, non-mock environments use Vite's proxy at /api-proxy
41
+ * which handles CORS and forwards requests to the actual API server.
42
+ * The proxy also injects the Authorization header, so authToken is not needed client-side.
43
+ * @returns {{ apiBaseUrl: string, authToken: string, projectId: string }}
44
+ */
45
+ function getApiConfig() {
46
+ const apiEnv = import.meta.env.VITE_API_ENV || "mock";
47
+ const apiKey = import.meta.env.VITE_API_KEY || "";
48
+ const projectId = import.meta.env.VITE_API_PROJECT_ID || "";
49
+ const useHttps = import.meta.env.VITE_USE_HTTPS !== "false";
50
+ const nodePort = import.meta.env.VITE_NODE_PORT || "3060";
51
+
52
+ // Check if we're in development mode (Vite dev server)
53
+ const isDev = import.meta.env.DEV;
54
+
55
+ if (apiEnv === "mock") {
56
+ // Mock API: use local dev server with random token
57
+ const protocol = useHttps ? "https" : "http";
58
+ return {
59
+ apiBaseUrl: `${protocol}://localhost:${nodePort}/mock-api`,
60
+ authToken: generateMockToken(),
61
+ projectId: "team/project",
62
+ };
63
+ }
64
+
65
+ // For non-mock environments in development, use the local Vite proxy
66
+ // The proxy handles CORS and injects the Authorization header
67
+ if (isDev) {
68
+ const protocol = useHttps ? "https" : "http";
69
+ return {
70
+ apiBaseUrl: `${protocol}://localhost:${nodePort}/api-proxy`,
71
+ authToken: "", // Proxy injects the token server-side
72
+ projectId: projectId,
73
+ };
74
+ }
75
+
76
+ // Production build: use the actual API URL directly
77
+ const envConfig = ENVIRONMENT_URLS[apiEnv];
78
+ if (!envConfig) {
79
+ console.warn(
80
+ `[GxP Store] Unknown API_ENV "${apiEnv}", falling back to production`
81
+ );
82
+ return {
83
+ apiBaseUrl: ENVIRONMENT_URLS.production.apiBaseUrl,
84
+ authToken: apiKey,
85
+ projectId: projectId,
86
+ };
87
+ }
88
+
89
+ return {
90
+ apiBaseUrl: envConfig.apiBaseUrl,
91
+ authToken: apiKey,
92
+ projectId: projectId,
93
+ };
94
+ }
95
+
96
+ // Default values used when app-manifest.json doesn't exist or is missing keys
97
+ const defaultData = {
98
+ pluginVars: {
99
+ primary_color: "#FFD600",
100
+ background_color: "#ffffff",
101
+ text_color: "#333333",
102
+ },
103
+ stringsList: {},
104
+ assetList: {},
105
+ dependencyList: {},
106
+ permissionFlags: [],
107
+ triggerState: {},
108
+ auth: null,
109
+ userSession: null,
110
+ pluginData: {},
111
+ portalAssets: {},
112
+ portal: null,
113
+ };
114
+
115
+ export const useGxpStore = defineStore("gxp-portal-app", () => {
116
+ // Core configuration - these will be injected by the platform in production
117
+ const pluginVars = ref({ ...defaultData.pluginVars });
118
+ const stringsList = ref({ ...defaultData.stringsList });
119
+ const assetList = ref({ ...defaultData.assetList });
120
+ const dependencyList = ref({ ...defaultData.dependencyList });
121
+ const dependencies = ref([]); // Store full dependency objects for socket initialization
122
+ const permissionFlags = ref([...defaultData.permissionFlags]);
123
+ const triggerState = ref({ ...defaultData.triggerState });
124
+
125
+ // User session data (injected by platform in production)
126
+ const auth = ref(defaultData.auth);
127
+ const userSession = ref(defaultData.userSession);
128
+ const pluginData = ref({ ...defaultData.pluginData });
129
+ const portalAssets = ref({ ...defaultData.portalAssets });
130
+ const portal = ref(defaultData.portal);
131
+
132
+ // Loading state for manifest
133
+ const manifestLoaded = ref(false);
134
+ const manifestError = ref(null);
135
+
136
+ // API configuration - initialized from environment
137
+ const apiConfig = getApiConfig();
138
+ const apiBaseUrl = ref(apiConfig.apiBaseUrl);
139
+ const authToken = ref(apiConfig.authToken);
140
+ pluginVars.value.projectId = apiConfig.projectId;
141
+ pluginVars.value.apiPageAuthId = apiConfig.authToken;
142
+ pluginVars.value.apiBaseUrl = apiConfig.apiBaseUrl;
143
+
144
+ // Log API configuration for debugging
145
+ console.log(
146
+ `[GxP Store] API Environment: ${import.meta.env.VITE_API_ENV || "mock"}`
147
+ );
148
+ console.log(`[GxP Store] API Base URL: ${apiConfig.apiBaseUrl}`);
149
+
150
+ // WebSocket configuration - initialized as reactive objects immediately
151
+ const sockets = reactive({});
152
+ const socketConnections = reactive({});
153
+
154
+ // API client setup
155
+ const apiClient = axios.create({
156
+ timeout: 30000,
157
+ headers: {
158
+ "Content-Type": "application/json",
159
+ },
160
+ });
161
+
162
+ // Add auth token to requests
163
+ apiClient.interceptors.request.use((config) => {
164
+ if (authToken.value) {
165
+ config.headers.Authorization = `Bearer ${authToken.value}`;
166
+ }
167
+ config.baseURL = apiBaseUrl.value;
168
+ return config;
169
+ });
170
+
171
+ // Response interceptor for error handling
172
+ apiClient.interceptors.response.use(
173
+ (response) => response,
174
+ (error) => {
175
+ console.error("API Error:", error.response?.data || error.message);
176
+ throw error;
177
+ }
178
+ );
179
+
180
+ /**
181
+ * Load configuration from app-manifest.json
182
+ * Maps manifest keys to store properties:
183
+ * - settings -> pluginVars
184
+ * - strings.default -> stringsList
185
+ * - assets -> assetList
186
+ */
187
+ async function loadManifest() {
188
+ try {
189
+ const response = await fetch("/app-manifest.json");
190
+ if (!response.ok) {
191
+ if (response.status === 404) {
192
+ console.log("[GxP Store] No app-manifest.json found, using defaults");
193
+ manifestLoaded.value = true;
194
+ return;
195
+ }
196
+ throw new Error(`HTTP ${response.status}`);
197
+ }
198
+
199
+ const manifest = await response.json();
200
+ applyManifest(manifest);
201
+ manifestLoaded.value = true;
202
+ manifestError.value = null;
203
+ console.log("[GxP Store] Loaded configuration from app-manifest.json");
204
+
205
+ // Re-initialize dependency sockets after manifest loads
206
+ initializeDependencySockets();
207
+ } catch (error) {
208
+ console.warn(
209
+ "[GxP Store] Could not load app-manifest.json:",
210
+ error.message
211
+ );
212
+ manifestError.value = error.message;
213
+ manifestLoaded.value = true;
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Apply manifest data to store
219
+ */
220
+ function applyManifest(manifest) {
221
+ if (manifest.settings && typeof manifest.settings === "object") {
222
+ pluginVars.value = { ...defaultData.pluginVars, ...manifest.settings };
223
+ }
224
+
225
+ // Handle strings - can be { default: {...} } or flat object
226
+ if (manifest.strings) {
227
+ if (
228
+ manifest.strings.default &&
229
+ typeof manifest.strings.default === "object"
230
+ ) {
231
+ stringsList.value = { ...manifest.strings.default };
232
+ } else if (typeof manifest.strings === "object") {
233
+ stringsList.value = { ...manifest.strings };
234
+ }
235
+ }
236
+
237
+ if (manifest.assets && typeof manifest.assets === "object") {
238
+ assetList.value = { ...manifest.assets };
239
+ }
240
+
241
+ if (manifest.dependencies && Array.isArray(manifest.dependencies)) {
242
+ dependencies.value = manifest.dependencies; // Store full dependency objects
243
+ dependencyList.value = manifest.dependencies.reduce((acc, dependency) => {
244
+ acc[dependency.identifier] = "1";
245
+ return acc;
246
+ }, {});
247
+ console.log("[GxP Store] Dependency List:", dependencyList.value);
248
+ }
249
+
250
+ if (manifest.permissions && Array.isArray(manifest.permissions)) {
251
+ permissionFlags.value = [...manifest.permissions];
252
+ }
253
+
254
+ if (manifest.triggerState && typeof manifest.triggerState === "object") {
255
+ triggerState.value = { ...manifest.triggerState };
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Initialize primary WebSocket connection
261
+ * Called synchronously when store is created
262
+ */
263
+ function initializeSockets() {
264
+ // Primary socket connection
265
+ // Use the same protocol as the current page for Socket.IO connection
266
+ const socketProtocol =
267
+ typeof window !== "undefined" && window.location.protocol === "https:"
268
+ ? "https"
269
+ : "http";
270
+ const socketPort = import.meta.env.VITE_SOCKET_IO_PORT || 3069;
271
+ console.log(`[GxP Store] Connecting to Socket.IO on port ${socketPort}`);
272
+ const primarySocket = io(`${socketProtocol}://localhost:${socketPort}`);
273
+
274
+ sockets.primary = {
275
+ broadcast: function (event, data) {
276
+ primarySocket.emit(event, data);
277
+ },
278
+ listen: function (event, callback) {
279
+ return primarySocket.on(event, callback);
280
+ },
281
+ listenForStateChange: function (callback) {
282
+ return primarySocket.on("state-change", callback);
283
+ },
284
+ };
285
+
286
+ socketConnections.primary = primarySocket;
287
+ }
288
+
289
+ /**
290
+ * Initialize dependency-based sockets
291
+ * Called after manifest loads to set up dependency-specific listeners
292
+ */
293
+ function initializeDependencySockets() {
294
+ const primarySocket = socketConnections.primary;
295
+ if (!primarySocket) return;
296
+
297
+ // Initialize dependency-based sockets based on the new structure
298
+ if (Array.isArray(dependencies.value)) {
299
+ dependencies.value.forEach((dependency) => {
300
+ if (dependency.events && Object.keys(dependency.events).length > 0) {
301
+ // Create socket listeners for each event type
302
+ sockets[dependency.identifier] = {};
303
+
304
+ Object.keys(dependency.events).forEach((eventType) => {
305
+ const eventName = dependency.events[eventType];
306
+ const channel = `private.${dependency.model}.${dependency.identifier}`;
307
+
308
+ sockets[dependency.identifier][eventType] = {
309
+ listen: function (callback) {
310
+ // Listen for the specific event on the primary socket
311
+ return primarySocket.on(eventName, (data) => {
312
+ console.log(
313
+ `Socket event received: ${eventName} on ${channel}`,
314
+ data
315
+ );
316
+ callback(data);
317
+ });
318
+ },
319
+ };
320
+ });
321
+ } else {
322
+ // For dependencies without events, create empty listeners
323
+ sockets[dependency.identifier] = {
324
+ created: { listen: () => () => {} },
325
+ updated: { listen: () => () => {} },
326
+ deleted: { listen: () => () => {} },
327
+ };
328
+ }
329
+ });
330
+ }
331
+ }
332
+
333
+ // API methods for common operations
334
+ async function apiGet(endpoint, params = {}) {
335
+ try {
336
+ const response = await apiClient.get(endpoint, { params });
337
+ return response.data;
338
+ } catch (error) {
339
+ throw new Error(`GET ${endpoint}: ${error.message}`);
340
+ }
341
+ }
342
+
343
+ async function apiPost(endpoint, data = {}) {
344
+ try {
345
+ const response = await apiClient.post(endpoint, data);
346
+ return response.data;
347
+ } catch (error) {
348
+ throw new Error(`POST ${endpoint}: ${error.message}`);
349
+ }
350
+ }
351
+
352
+ async function apiPut(endpoint, data = {}) {
353
+ try {
354
+ const response = await apiClient.put(endpoint, data);
355
+ return response.data;
356
+ } catch (error) {
357
+ throw new Error(`PUT ${endpoint}: ${error.message}`);
358
+ }
359
+ }
360
+
361
+ async function apiPatch(endpoint, data = {}) {
362
+ try {
363
+ const response = await apiClient.patch(endpoint, data);
364
+ return response.data;
365
+ } catch (error) {
366
+ throw new Error(`PATCH ${endpoint}: ${error.message}`);
367
+ }
368
+ }
369
+
370
+ async function apiDelete(endpoint) {
371
+ try {
372
+ const response = await apiClient.delete(endpoint);
373
+ return response.data;
374
+ } catch (error) {
375
+ throw new Error(`DELETE ${endpoint}: ${error.message}`);
376
+ }
377
+ }
378
+
379
+ // Utility methods
380
+ function getString(key, fallback = "") {
381
+ return stringsList.value[key] || fallback;
382
+ }
383
+
384
+ function getSetting(key, fallback = null) {
385
+ return pluginVars.value[key] || fallback;
386
+ }
387
+
388
+ function getAsset(key, fallback = "") {
389
+ return assetList.value[key] || fallback;
390
+ }
391
+
392
+ function getState(key, fallback = null) {
393
+ return triggerState.value[key] || fallback;
394
+ }
395
+ function findDependency(identifier) {
396
+ if (Array.isArray(dependencyList.value)) {
397
+ return dependencyList.value.find((dep) => dep.identifier === identifier);
398
+ }
399
+ return null;
400
+ }
401
+ function hasPermission(flag) {
402
+ return permissionFlags.value.includes(flag);
403
+ }
404
+
405
+ // Update methods - these replace the entire object to ensure Vue reactivity triggers
406
+ // Used by DevTools and for programmatic updates
407
+ function updateString(key, value) {
408
+ stringsList.value = { ...stringsList.value, [key]: value };
409
+ }
410
+
411
+ function updateSetting(key, value) {
412
+ pluginVars.value = { ...pluginVars.value, [key]: value };
413
+ }
414
+
415
+ function updateAsset(key, value) {
416
+ assetList.value = { ...assetList.value, [key]: value };
417
+ }
418
+
419
+ function updateState(key, value) {
420
+ triggerState.value = { ...triggerState.value, [key]: value };
421
+ }
422
+
423
+ // Convenience method to add dev assets with proper URL
424
+ function addDevAsset(key, filename) {
425
+ const appPort =
426
+ typeof window !== "undefined" ? window.location.port || 3000 : 3000;
427
+ const appProtocol =
428
+ typeof window !== "undefined" ? window.location.protocol : "http:";
429
+ const assetUrl = `${appProtocol}//localhost:${appPort}/dev-assets/images/${filename}`;
430
+ updateAsset(key, assetUrl);
431
+ }
432
+
433
+ // Socket helper methods
434
+ function emitSocket(socketName, event, data) {
435
+ if (sockets[socketName] && sockets[socketName].broadcast) {
436
+ sockets[socketName].broadcast(event, data);
437
+ } else {
438
+ console.warn(`Socket not found: ${socketName}`);
439
+ }
440
+ }
441
+
442
+ function listenSocket(socketName, event, callback) {
443
+ if (sockets[socketName] && sockets[socketName].listen) {
444
+ return sockets[socketName].listen(event, callback);
445
+ } else {
446
+ console.warn(`Socket not found: ${socketName}`);
447
+ return () => {};
448
+ }
449
+ }
450
+
451
+ // Component helper - allows components to register socket listeners easily
452
+ function useSocketListener(socketName, event, callback) {
453
+ return listenSocket(socketName, event, callback);
454
+ }
455
+
456
+ // Theme configuration
457
+ const theme = computed(() => ({
458
+ background_color: getSetting("background_color", "#ffffff"),
459
+ text_color: getSetting("text_color", "#333333"),
460
+ primary_color: getSetting("primary_color", "#FFD600"),
461
+ start_background_color: getSetting(
462
+ "start_background_color",
463
+ "linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
464
+ ),
465
+ start_text_color: getSetting("start_text_color", "#ffffff"),
466
+ final_background_color: getSetting("final_background_color", "#4CAF50"),
467
+ final_text_color: getSetting("final_text_color", "#ffffff"),
468
+ }));
469
+
470
+ function listAssets() {
471
+ console.log("📁 Current Assets:");
472
+ Object.entries(assetList.value).forEach(([key, url]) => {
473
+ console.log(` ${key}: ${url}`);
474
+ });
475
+ return assetList.value;
476
+ }
477
+
478
+ // Initialize sockets SYNCHRONOUSLY when store is created
479
+ // This ensures sockets is available immediately
480
+ initializeSockets();
481
+
482
+ // Load manifest ASYNCHRONOUSLY in the background
483
+ // This allows the store to be used immediately while manifest loads
484
+ loadManifest();
485
+
486
+ // Setup Vite HMR for app-manifest.json hot-reload
487
+ if (import.meta.hot) {
488
+ // Listen for custom HMR event from Vite plugin
489
+ import.meta.hot.on("gxp:manifest-update", (data) => {
490
+ console.log("[GxP Store] Hot-reloading app-manifest.json");
491
+ applyManifest(data);
492
+ initializeDependencySockets();
493
+ });
494
+
495
+ // Also support full-reload trigger if needed
496
+ import.meta.hot.on("gxp:manifest-reload", () => {
497
+ console.log("[GxP Store] Reloading app-manifest.json");
498
+ loadManifest();
499
+ });
500
+ }
501
+
502
+ return {
503
+ // State
504
+ pluginVars,
505
+ stringsList,
506
+ assetList,
507
+ dependencyList,
508
+ permissionFlags,
509
+ auth,
510
+ userSession,
511
+ pluginData,
512
+ portalAssets,
513
+ portal,
514
+ sockets,
515
+ theme,
516
+ triggerState,
517
+ manifestLoaded,
518
+ manifestError,
519
+
520
+ // API methods
521
+ apiGet,
522
+ apiPost,
523
+ apiPatch,
524
+ apiPut,
525
+ apiDelete,
526
+
527
+ // Utility methods
528
+ getString,
529
+ getSetting,
530
+ getAsset,
531
+ getState,
532
+ hasPermission,
533
+ findDependency,
534
+
535
+ // Update methods (for DevTools and programmatic updates)
536
+ updateString,
537
+ updateSetting,
538
+ updateAsset,
539
+ updateState,
540
+ addDevAsset,
541
+
542
+ // Socket methods
543
+ emitSocket,
544
+ listenSocket,
545
+ useSocketListener,
546
+
547
+ // Manifest methods
548
+ loadManifest,
549
+ applyManifest,
550
+
551
+ // Development methods
552
+ listAssets,
553
+ };
554
+ });
@@ -0,0 +1,6 @@
1
+ // Import from package runtime directory by default
2
+ // To customize, run: gxdev publish gxpPortalConfigStore.js
3
+ // Then update this import to: import { useGxpStore } from './gxpPortalConfigStore.js';
4
+ import { useGxpStore } from "@gx-runtime/stores/gxpPortalConfigStore";
5
+
6
+ export { useGxpStore };