@gears-frontx/react 0.1.0 → 0.2.0-alpha.2
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/CLAUDE.md +191 -45
- package/dist/index.cjs +1131 -392
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +418 -119
- package/dist/index.d.ts +418 -119
- package/dist/index.js +977 -242
- package/dist/index.js.map +1 -1
- package/dist/testing-Dlmfu6tE.d.cts +56 -0
- package/dist/testing-Dlmfu6tE.d.ts +56 -0
- package/dist/testing.cjs +77 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +4 -0
- package/dist/testing.d.ts +4 -0
- package/dist/testing.js +54 -0
- package/dist/testing.js.map +1 -0
- package/dist/types-Cjd20AT-.d.cts +231 -0
- package/dist/types-Cjd20AT-.d.ts +231 -0
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +2 -2
- package/dist/types.d.ts +2 -2
- package/llms.txt +20 -20
- package/package.json +29 -18
- package/commands/hai3-duplicate-screenset.md +0 -58
- package/commands/hai3-new-component.md +0 -48
- package/commands/hai3-new-mfe.md +0 -166
- package/commands/hai3-new-screen.md +0 -39
- package/commands/hai3-new-screenset.md +0 -47
- package/dist/types-Cp8Zm5s0.d.cts +0 -136
- package/dist/types-Cp8Zm5s0.d.ts +0 -136
package/dist/index.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import { useMemo, useEffect } from "react";
|
|
1
|
+
// src/FrontXProvider.tsx
|
|
2
|
+
import { useMemo as useMemo2, useEffect as useEffect3, useState as useState2 } from "react";
|
|
3
3
|
import { Provider as ReduxProvider } from "react-redux";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
createFrontXApp
|
|
6
|
+
} from "@gears-frontx/framework";
|
|
5
7
|
|
|
6
|
-
// src/
|
|
8
|
+
// src/FrontXContext.tsx
|
|
7
9
|
import { createContext, useContext } from "react";
|
|
8
|
-
var
|
|
9
|
-
function
|
|
10
|
-
const context = useContext(
|
|
10
|
+
var FrontXContext = createContext(null);
|
|
11
|
+
function useFrontX() {
|
|
12
|
+
const context = useContext(FrontXContext);
|
|
11
13
|
if (!context) {
|
|
12
14
|
throw new Error(
|
|
13
|
-
"
|
|
15
|
+
"useFrontX must be used within a FrontXProvider. Wrap your application with <FrontXProvider> to access Gears FrontX features."
|
|
14
16
|
);
|
|
15
17
|
}
|
|
16
18
|
return context;
|
|
@@ -35,34 +37,590 @@ var MfeProvider = ({ value, children }) => {
|
|
|
35
37
|
return /* @__PURE__ */ jsx(MfeContext.Provider, { value, children });
|
|
36
38
|
};
|
|
37
39
|
|
|
38
|
-
// src/
|
|
40
|
+
// src/queryClient.tsx
|
|
41
|
+
import React, {
|
|
42
|
+
createContext as createContext3,
|
|
43
|
+
useContext as useContext3,
|
|
44
|
+
useEffect as useEffect2,
|
|
45
|
+
useLayoutEffect,
|
|
46
|
+
useMemo,
|
|
47
|
+
useState
|
|
48
|
+
} from "react";
|
|
49
|
+
import {
|
|
50
|
+
QueryClientContext,
|
|
51
|
+
QueryClientProvider,
|
|
52
|
+
useInfiniteQuery,
|
|
53
|
+
useMutation,
|
|
54
|
+
useQuery,
|
|
55
|
+
useSuspenseInfiniteQuery,
|
|
56
|
+
useSuspenseQuery
|
|
57
|
+
} from "@tanstack/react-query";
|
|
58
|
+
import {
|
|
59
|
+
subscribeQueryCacheRuntimeChanged
|
|
60
|
+
} from "@gears-frontx/framework";
|
|
61
|
+
|
|
62
|
+
// src/hooks/QueryCache.ts
|
|
63
|
+
import { eventBus } from "@gears-frontx/framework";
|
|
64
|
+
var QUERY_CLIENT_BROADCAST_TARGET = /* @__PURE__ */ Symbol.for("frontx:query-cache:broadcast-target");
|
|
65
|
+
var QUERY_CLIENT_BROADCAST_COUNTER = /* @__PURE__ */ Symbol.for("frontx:query-cache:broadcast-counter");
|
|
66
|
+
function emitCacheEvent(event, payload) {
|
|
67
|
+
eventBus.emit(event, payload);
|
|
68
|
+
}
|
|
69
|
+
function ensureBroadcastSource(queryClient) {
|
|
70
|
+
const clientWithMetadata = queryClient;
|
|
71
|
+
const existingSource = clientWithMetadata[QUERY_CLIENT_BROADCAST_TARGET];
|
|
72
|
+
if (typeof existingSource === "string" && existingSource.length > 0) {
|
|
73
|
+
return existingSource;
|
|
74
|
+
}
|
|
75
|
+
const host = globalThis;
|
|
76
|
+
const nextCounter = (host[QUERY_CLIENT_BROADCAST_COUNTER] ?? 0) + 1;
|
|
77
|
+
host[QUERY_CLIENT_BROADCAST_COUNTER] = nextCounter;
|
|
78
|
+
const source = `query-cache-${nextCounter}`;
|
|
79
|
+
clientWithMetadata[QUERY_CLIENT_BROADCAST_TARGET] = source;
|
|
80
|
+
return source;
|
|
81
|
+
}
|
|
82
|
+
function resolveKey(target) {
|
|
83
|
+
if (target !== null && typeof target === "object" && !Array.isArray(target) && "key" in target && "fetch" in target && Array.isArray(target.key) && typeof target.fetch === "function") {
|
|
84
|
+
return target.key;
|
|
85
|
+
}
|
|
86
|
+
return target;
|
|
87
|
+
}
|
|
88
|
+
function toQueryUpdater(dataOrUpdater) {
|
|
89
|
+
if (typeof dataOrUpdater === "function") {
|
|
90
|
+
return dataOrUpdater;
|
|
91
|
+
}
|
|
92
|
+
return () => dataOrUpdater;
|
|
93
|
+
}
|
|
94
|
+
function mapQueryState(state) {
|
|
95
|
+
return {
|
|
96
|
+
data: state.data,
|
|
97
|
+
dataUpdatedAt: state.dataUpdatedAt,
|
|
98
|
+
error: state.error,
|
|
99
|
+
errorUpdatedAt: state.errorUpdatedAt,
|
|
100
|
+
fetchFailureCount: state.fetchFailureCount,
|
|
101
|
+
fetchFailureReason: state.fetchFailureReason,
|
|
102
|
+
fetchStatus: state.fetchStatus,
|
|
103
|
+
isInvalidated: state.isInvalidated,
|
|
104
|
+
status: state.status
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function createQueryCache(queryClient) {
|
|
108
|
+
return {
|
|
109
|
+
get: (key) => {
|
|
110
|
+
return queryClient.getQueryData(resolveKey(key));
|
|
111
|
+
},
|
|
112
|
+
getState: (key) => {
|
|
113
|
+
const state = queryClient.getQueryState(resolveKey(key));
|
|
114
|
+
return state ? mapQueryState(state) : void 0;
|
|
115
|
+
},
|
|
116
|
+
set: (key, dataOrUpdater) => {
|
|
117
|
+
const resolvedKey = resolveKey(key);
|
|
118
|
+
queryClient.setQueryData(resolvedKey, toQueryUpdater(dataOrUpdater));
|
|
119
|
+
emitCacheEvent("cache/set", {
|
|
120
|
+
queryKey: resolvedKey,
|
|
121
|
+
dataOrUpdater,
|
|
122
|
+
source: ensureBroadcastSource(queryClient)
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
cancel: (key) => {
|
|
126
|
+
return queryClient.cancelQueries({ queryKey: resolveKey(key) });
|
|
127
|
+
},
|
|
128
|
+
invalidate: (key) => {
|
|
129
|
+
const resolvedKey = resolveKey(key);
|
|
130
|
+
const result = queryClient.invalidateQueries({ queryKey: resolvedKey });
|
|
131
|
+
emitCacheEvent("cache/invalidate", {
|
|
132
|
+
queryKey: resolvedKey,
|
|
133
|
+
source: ensureBroadcastSource(queryClient)
|
|
134
|
+
});
|
|
135
|
+
return result;
|
|
136
|
+
},
|
|
137
|
+
invalidateMany: (filters) => {
|
|
138
|
+
if (filters?.queryKey == null) {
|
|
139
|
+
return Promise.resolve();
|
|
140
|
+
}
|
|
141
|
+
const resolvedKey = resolveKey(filters.queryKey);
|
|
142
|
+
if (!Array.isArray(resolvedKey) || resolvedKey.length === 0) {
|
|
143
|
+
return Promise.resolve();
|
|
144
|
+
}
|
|
145
|
+
const payload = {
|
|
146
|
+
...filters,
|
|
147
|
+
queryKey: resolvedKey
|
|
148
|
+
};
|
|
149
|
+
const result = queryClient.invalidateQueries(payload);
|
|
150
|
+
emitCacheEvent("cache/invalidate", {
|
|
151
|
+
...payload,
|
|
152
|
+
source: ensureBroadcastSource(queryClient)
|
|
153
|
+
});
|
|
154
|
+
return result;
|
|
155
|
+
},
|
|
156
|
+
remove: (key) => {
|
|
157
|
+
const resolvedKey = resolveKey(key);
|
|
158
|
+
queryClient.removeQueries({ queryKey: resolvedKey });
|
|
159
|
+
emitCacheEvent("cache/remove", {
|
|
160
|
+
queryKey: resolvedKey,
|
|
161
|
+
source: ensureBroadcastSource(queryClient)
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// src/hooks/useLatest.ts
|
|
168
|
+
import { useEffect, useRef } from "react";
|
|
169
|
+
function useLatest(value) {
|
|
170
|
+
const ref = useRef(value);
|
|
171
|
+
useEffect(() => {
|
|
172
|
+
ref.current = value;
|
|
173
|
+
});
|
|
174
|
+
return ref;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// src/queryClient.tsx
|
|
39
178
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
40
|
-
var
|
|
179
|
+
var APP_QUERY_CLIENT_SYMBOL = /* @__PURE__ */ Symbol.for("frontx:query-cache:app-client");
|
|
180
|
+
var APP_QUERY_CLIENT_RESOLVER_SYMBOL = /* @__PURE__ */ Symbol.for("frontx:query-cache:app-client-resolver");
|
|
181
|
+
var APP_QUERY_CLIENT_ACTIVATOR_SYMBOL = /* @__PURE__ */ Symbol.for("frontx:query-cache:app-client-activator");
|
|
182
|
+
var FrontXQueryClientContext = createContext3(void 0);
|
|
183
|
+
var useCommitEffect = typeof globalThis.window === "undefined" ? useEffect2 : useLayoutEffect;
|
|
184
|
+
function resolveFrontXQueryClient(app) {
|
|
185
|
+
const clientApp = app;
|
|
186
|
+
return clientApp[APP_QUERY_CLIENT_SYMBOL] ?? clientApp[APP_QUERY_CLIENT_RESOLVER_SYMBOL]?.();
|
|
187
|
+
}
|
|
188
|
+
function hasFrontXQueryClientActivator(app) {
|
|
189
|
+
return typeof app[APP_QUERY_CLIENT_ACTIVATOR_SYMBOL] === "function";
|
|
190
|
+
}
|
|
191
|
+
function activateFrontXQueryClient(app) {
|
|
192
|
+
const clientApp = app;
|
|
193
|
+
return clientApp[APP_QUERY_CLIENT_SYMBOL] ?? clientApp[APP_QUERY_CLIENT_ACTIVATOR_SYMBOL]?.();
|
|
194
|
+
}
|
|
195
|
+
async function invalidateQueryCacheForApp(app, target) {
|
|
196
|
+
const queryClient = resolveFrontXQueryClient(app) ?? activateFrontXQueryClient(app);
|
|
197
|
+
if (!queryClient) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
"[invalidateQueryCacheForApp] No QueryClient on app. Ensure queryCache() or queryCacheShared() is in the plugin chain."
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
await createQueryCache(queryClient).invalidate(target);
|
|
203
|
+
}
|
|
204
|
+
function bootstrapFrontXQueryClient(app) {
|
|
205
|
+
return resolveFrontXQueryClient(app);
|
|
206
|
+
}
|
|
207
|
+
function useBootstrappedFrontXQueryClient(app) {
|
|
208
|
+
const fromApp = useMemo(() => bootstrapFrontXQueryClient(app), [app]);
|
|
209
|
+
const [eventResolvedClient, setEventResolvedClient] = useState(
|
|
210
|
+
void 0
|
|
211
|
+
);
|
|
212
|
+
const queryClient = fromApp ?? (eventResolvedClient?.app === app ? eventResolvedClient.queryClient : void 0);
|
|
213
|
+
useCommitEffect(() => {
|
|
214
|
+
if (fromApp || !hasFrontXQueryClientActivator(app)) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const tryResolveQueryClient = () => {
|
|
218
|
+
const nextQueryClient = resolveFrontXQueryClient(app) ?? activateFrontXQueryClient(app);
|
|
219
|
+
if (nextQueryClient) {
|
|
220
|
+
setEventResolvedClient((current) => {
|
|
221
|
+
if (current?.app === app && current.queryClient === nextQueryClient) {
|
|
222
|
+
return current;
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
app,
|
|
226
|
+
queryClient: nextQueryClient
|
|
227
|
+
};
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
tryResolveQueryClient();
|
|
232
|
+
const subscription = subscribeQueryCacheRuntimeChanged(() => {
|
|
233
|
+
tryResolveQueryClient();
|
|
234
|
+
});
|
|
235
|
+
return () => {
|
|
236
|
+
subscription.unsubscribe();
|
|
237
|
+
};
|
|
238
|
+
}, [app, fromApp]);
|
|
239
|
+
return queryClient;
|
|
240
|
+
}
|
|
241
|
+
function FrontXQueryClientProvider({
|
|
242
|
+
queryClient,
|
|
243
|
+
children
|
|
244
|
+
}) {
|
|
245
|
+
if (!queryClient) {
|
|
246
|
+
return /* @__PURE__ */ jsx2(FrontXQueryClientContext.Provider, { value: void 0, children: /* @__PURE__ */ jsx2(QueryClientContext.Provider, { value: void 0, children }) });
|
|
247
|
+
}
|
|
248
|
+
return /* @__PURE__ */ jsx2(FrontXQueryClientContext.Provider, { value: queryClient, children: /* @__PURE__ */ jsx2(QueryClientProvider, { client: queryClient, children }) });
|
|
249
|
+
}
|
|
250
|
+
function useOptionalFrontXQueryClient() {
|
|
251
|
+
return useContext3(FrontXQueryClientContext);
|
|
252
|
+
}
|
|
253
|
+
function useRequiredFrontXQueryClient() {
|
|
254
|
+
const queryClient = useOptionalFrontXQueryClient();
|
|
255
|
+
if (!queryClient) {
|
|
256
|
+
throw new Error(
|
|
257
|
+
"[FrontXProvider] No query cache available. Add queryCache() or queryCacheShared() to your plugin composition."
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
return queryClient;
|
|
261
|
+
}
|
|
262
|
+
function buildPageContext(page, pages, descriptor, descriptors) {
|
|
263
|
+
return {
|
|
264
|
+
page,
|
|
265
|
+
pages,
|
|
266
|
+
descriptor,
|
|
267
|
+
descriptors
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function normalizeFetchStaleTime(staleTime) {
|
|
271
|
+
if (staleTime === "static") {
|
|
272
|
+
return Number.POSITIVE_INFINITY;
|
|
273
|
+
}
|
|
274
|
+
return typeof staleTime === "number" ? staleTime : void 0;
|
|
275
|
+
}
|
|
276
|
+
function resolveFetchStaleTime(queryClient, descriptor, overrideStaleTime) {
|
|
277
|
+
return normalizeFetchStaleTime(
|
|
278
|
+
overrideStaleTime ?? descriptor.staleTime ?? queryClient.getDefaultOptions().queries?.staleTime
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
function fetchDescriptor(descriptor, options) {
|
|
282
|
+
return descriptor.fetch(options);
|
|
283
|
+
}
|
|
284
|
+
function useFrontXQuery(descriptor, overrides) {
|
|
285
|
+
const queryClient = useRequiredFrontXQueryClient();
|
|
286
|
+
const staleTime = resolveFetchStaleTime(queryClient, descriptor, overrides?.staleTime);
|
|
287
|
+
const result = useQuery({
|
|
288
|
+
queryKey: descriptor.key,
|
|
289
|
+
queryFn: ({ signal }) => fetchDescriptor(descriptor, { signal, staleTime }),
|
|
290
|
+
staleTime: overrides?.staleTime ?? descriptor.staleTime,
|
|
291
|
+
gcTime: overrides?.gcTime ?? descriptor.gcTime
|
|
292
|
+
});
|
|
293
|
+
return {
|
|
294
|
+
data: result.data,
|
|
295
|
+
error: result.error,
|
|
296
|
+
isLoading: result.isLoading,
|
|
297
|
+
isFetching: result.isFetching,
|
|
298
|
+
isError: result.isError,
|
|
299
|
+
refetch: result.refetch
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
function useFrontXSuspenseQuery(descriptor, overrides) {
|
|
303
|
+
const queryClient = useRequiredFrontXQueryClient();
|
|
304
|
+
const staleTime = resolveFetchStaleTime(queryClient, descriptor, overrides?.staleTime);
|
|
305
|
+
const result = useSuspenseQuery({
|
|
306
|
+
queryKey: descriptor.key,
|
|
307
|
+
queryFn: ({ signal }) => fetchDescriptor(descriptor, { signal, staleTime }),
|
|
308
|
+
staleTime: overrides?.staleTime ?? descriptor.staleTime,
|
|
309
|
+
gcTime: overrides?.gcTime ?? descriptor.gcTime
|
|
310
|
+
});
|
|
311
|
+
return {
|
|
312
|
+
data: result.data,
|
|
313
|
+
error: result.error,
|
|
314
|
+
isFetching: result.isFetching,
|
|
315
|
+
refetch: async () => {
|
|
316
|
+
await result.refetch();
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
function useFrontXInfiniteQuery(options) {
|
|
321
|
+
const queryClient = useRequiredFrontXQueryClient();
|
|
322
|
+
const result = useInfiniteQuery({
|
|
323
|
+
queryKey: options.initialPage.key,
|
|
324
|
+
initialPageParam: options.initialPage,
|
|
325
|
+
queryFn: ({ pageParam, signal }) => fetchDescriptor(pageParam, {
|
|
326
|
+
signal,
|
|
327
|
+
staleTime: resolveFetchStaleTime(queryClient, pageParam, options.staleTime)
|
|
328
|
+
}),
|
|
329
|
+
getNextPageParam: (lastPage, allPages, lastPageDescriptor, allPageDescriptors) => options.getNextPage(
|
|
330
|
+
buildPageContext(
|
|
331
|
+
lastPage,
|
|
332
|
+
allPages,
|
|
333
|
+
lastPageDescriptor,
|
|
334
|
+
allPageDescriptors
|
|
335
|
+
)
|
|
336
|
+
),
|
|
337
|
+
getPreviousPageParam: options.getPreviousPage ? (firstPage, allPages, firstPageDescriptor, allPageDescriptors) => options.getPreviousPage?.(
|
|
338
|
+
buildPageContext(
|
|
339
|
+
firstPage,
|
|
340
|
+
allPages,
|
|
341
|
+
firstPageDescriptor,
|
|
342
|
+
allPageDescriptors
|
|
343
|
+
)
|
|
344
|
+
) : void 0,
|
|
345
|
+
select: (data) => data.pages,
|
|
346
|
+
staleTime: options.staleTime ?? options.initialPage.staleTime,
|
|
347
|
+
gcTime: options.gcTime ?? options.initialPage.gcTime,
|
|
348
|
+
maxPages: options.maxPages
|
|
349
|
+
});
|
|
350
|
+
return {
|
|
351
|
+
data: result.data,
|
|
352
|
+
error: result.error,
|
|
353
|
+
isLoading: result.isLoading,
|
|
354
|
+
isFetching: result.isFetching,
|
|
355
|
+
isError: result.isError,
|
|
356
|
+
hasNextPage: result.hasNextPage ?? false,
|
|
357
|
+
hasPreviousPage: result.hasPreviousPage ?? false,
|
|
358
|
+
isFetchingNextPage: result.isFetchingNextPage,
|
|
359
|
+
isFetchingPreviousPage: result.isFetchingPreviousPage,
|
|
360
|
+
fetchNextPage: async () => {
|
|
361
|
+
await result.fetchNextPage();
|
|
362
|
+
},
|
|
363
|
+
fetchPreviousPage: async () => {
|
|
364
|
+
await result.fetchPreviousPage();
|
|
365
|
+
},
|
|
366
|
+
refetch: async () => {
|
|
367
|
+
await result.refetch();
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function useFrontXSuspenseInfiniteQuery(options) {
|
|
372
|
+
const queryClient = useRequiredFrontXQueryClient();
|
|
373
|
+
const result = useSuspenseInfiniteQuery({
|
|
374
|
+
queryKey: options.initialPage.key,
|
|
375
|
+
initialPageParam: options.initialPage,
|
|
376
|
+
queryFn: ({ pageParam, signal }) => fetchDescriptor(pageParam, {
|
|
377
|
+
signal,
|
|
378
|
+
staleTime: resolveFetchStaleTime(queryClient, pageParam, options.staleTime)
|
|
379
|
+
}),
|
|
380
|
+
getNextPageParam: (lastPage, allPages, lastPageDescriptor, allPageDescriptors) => options.getNextPage(
|
|
381
|
+
buildPageContext(
|
|
382
|
+
lastPage,
|
|
383
|
+
allPages,
|
|
384
|
+
lastPageDescriptor,
|
|
385
|
+
allPageDescriptors
|
|
386
|
+
)
|
|
387
|
+
),
|
|
388
|
+
getPreviousPageParam: options.getPreviousPage ? (firstPage, allPages, firstPageDescriptor, allPageDescriptors) => options.getPreviousPage?.(
|
|
389
|
+
buildPageContext(
|
|
390
|
+
firstPage,
|
|
391
|
+
allPages,
|
|
392
|
+
firstPageDescriptor,
|
|
393
|
+
allPageDescriptors
|
|
394
|
+
)
|
|
395
|
+
) : void 0,
|
|
396
|
+
select: (data) => data.pages,
|
|
397
|
+
staleTime: options.staleTime ?? options.initialPage.staleTime,
|
|
398
|
+
gcTime: options.gcTime ?? options.initialPage.gcTime,
|
|
399
|
+
maxPages: options.maxPages
|
|
400
|
+
});
|
|
401
|
+
return {
|
|
402
|
+
data: result.data,
|
|
403
|
+
error: result.error,
|
|
404
|
+
isFetching: result.isFetching,
|
|
405
|
+
hasNextPage: result.hasNextPage ?? false,
|
|
406
|
+
hasPreviousPage: result.hasPreviousPage ?? false,
|
|
407
|
+
isFetchingNextPage: result.isFetchingNextPage,
|
|
408
|
+
isFetchingPreviousPage: result.isFetchingPreviousPage,
|
|
409
|
+
fetchNextPage: async () => {
|
|
410
|
+
await result.fetchNextPage();
|
|
411
|
+
},
|
|
412
|
+
fetchPreviousPage: async () => {
|
|
413
|
+
await result.fetchPreviousPage();
|
|
414
|
+
},
|
|
415
|
+
refetch: async () => {
|
|
416
|
+
await result.refetch();
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
function useFrontXMutation(options, callbackCtx) {
|
|
421
|
+
useRequiredFrontXQueryClient();
|
|
422
|
+
const latestRef = useLatest({ options, callbackCtx });
|
|
423
|
+
const fetchAbortControllersRef = React.useRef(/* @__PURE__ */ new Set());
|
|
424
|
+
const abortFetchesOnUnmount = React.useEffectEvent(() => {
|
|
425
|
+
if (options.abortOnUnmount) {
|
|
426
|
+
for (const controller of fetchAbortControllersRef.current) {
|
|
427
|
+
controller.abort();
|
|
428
|
+
}
|
|
429
|
+
fetchAbortControllersRef.current.clear();
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
React.useEffect(() => {
|
|
433
|
+
return () => {
|
|
434
|
+
abortFetchesOnUnmount();
|
|
435
|
+
};
|
|
436
|
+
}, []);
|
|
437
|
+
const mutationFn = React.useCallback((variables, context) => {
|
|
438
|
+
const cancelOnSupersede = latestRef.current.options.cancelOnSupersede;
|
|
439
|
+
if (cancelOnSupersede) {
|
|
440
|
+
for (const controller2 of fetchAbortControllersRef.current) {
|
|
441
|
+
controller2.abort();
|
|
442
|
+
}
|
|
443
|
+
fetchAbortControllersRef.current.clear();
|
|
444
|
+
}
|
|
445
|
+
const controller = new AbortController();
|
|
446
|
+
fetchAbortControllersRef.current.add(controller);
|
|
447
|
+
const librarySignal = context.signal;
|
|
448
|
+
if (cancelOnSupersede && librarySignal) {
|
|
449
|
+
if (librarySignal.aborted) {
|
|
450
|
+
controller.abort();
|
|
451
|
+
} else {
|
|
452
|
+
librarySignal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return latestRef.current.options.endpoint.fetch(variables, { signal: controller.signal }).finally(() => {
|
|
456
|
+
fetchAbortControllersRef.current.delete(controller);
|
|
457
|
+
});
|
|
458
|
+
}, [latestRef]);
|
|
459
|
+
const onMutate = React.useCallback((variables, _context) => {
|
|
460
|
+
const current = latestRef.current;
|
|
461
|
+
if (!current.options.onMutate) {
|
|
462
|
+
return void 0;
|
|
463
|
+
}
|
|
464
|
+
return current.options.onMutate(variables, current.callbackCtx);
|
|
465
|
+
}, [latestRef]);
|
|
466
|
+
const onSuccess = React.useCallback((data, variables, context) => {
|
|
467
|
+
const current = latestRef.current;
|
|
468
|
+
return current.options.onSuccess?.(data, variables, context, current.callbackCtx);
|
|
469
|
+
}, [latestRef]);
|
|
470
|
+
const onError = React.useCallback((error, variables, context) => {
|
|
471
|
+
const current = latestRef.current;
|
|
472
|
+
return current.options.onError?.(error, variables, context, current.callbackCtx);
|
|
473
|
+
}, [latestRef]);
|
|
474
|
+
const onSettled = React.useCallback((data, error, variables, context) => {
|
|
475
|
+
const current = latestRef.current;
|
|
476
|
+
return current.options.onSettled?.(
|
|
477
|
+
data,
|
|
478
|
+
error,
|
|
479
|
+
variables,
|
|
480
|
+
context,
|
|
481
|
+
current.callbackCtx
|
|
482
|
+
);
|
|
483
|
+
}, [latestRef]);
|
|
484
|
+
const mutation = useMutation({
|
|
485
|
+
mutationFn,
|
|
486
|
+
onMutate: options.onMutate ? onMutate : void 0,
|
|
487
|
+
onSuccess: options.onSuccess ? onSuccess : void 0,
|
|
488
|
+
onError: options.onError ? onError : void 0,
|
|
489
|
+
onSettled: options.onSettled ? onSettled : void 0
|
|
490
|
+
});
|
|
491
|
+
return {
|
|
492
|
+
mutate: mutation.mutate,
|
|
493
|
+
mutateAsync: mutation.mutateAsync,
|
|
494
|
+
isPending: mutation.isPending,
|
|
495
|
+
error: mutation.error,
|
|
496
|
+
data: mutation.data,
|
|
497
|
+
reset: mutation.reset
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// src/FrontXProvider.tsx
|
|
502
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
503
|
+
function shallowEqual(a, b) {
|
|
504
|
+
if (a === b) return true;
|
|
505
|
+
if (!a || !b) return false;
|
|
506
|
+
const keysA = Object.keys(a);
|
|
507
|
+
if (keysA.length !== Object.keys(b).length) return false;
|
|
508
|
+
return keysA.every((k) => Object.is(a[k], b[k]));
|
|
509
|
+
}
|
|
510
|
+
function createProviderOwnedApp(config) {
|
|
511
|
+
return createFrontXApp(config);
|
|
512
|
+
}
|
|
513
|
+
var FrontXProvider = ({
|
|
41
514
|
children,
|
|
42
515
|
config,
|
|
43
516
|
app: providedApp,
|
|
44
517
|
mfeBridge
|
|
45
518
|
}) => {
|
|
46
|
-
const
|
|
519
|
+
const [stableConfig, setStableConfig] = useState2(config);
|
|
520
|
+
if (!shallowEqual(
|
|
521
|
+
stableConfig,
|
|
522
|
+
config
|
|
523
|
+
)) {
|
|
524
|
+
setStableConfig(config);
|
|
525
|
+
}
|
|
526
|
+
const app = useMemo2(() => {
|
|
47
527
|
if (providedApp) {
|
|
48
528
|
return providedApp;
|
|
49
529
|
}
|
|
50
|
-
return
|
|
51
|
-
}, [providedApp,
|
|
52
|
-
|
|
530
|
+
return createProviderOwnedApp(stableConfig);
|
|
531
|
+
}, [providedApp, stableConfig]);
|
|
532
|
+
const queryClient = useBootstrappedFrontXQueryClient(app);
|
|
533
|
+
const deferQuerySubtree = hasFrontXQueryClientActivator(app) && queryClient === void 0;
|
|
534
|
+
useEffect3(() => {
|
|
535
|
+
if (queryClient || hasFrontXQueryClientActivator(app) || process.env.NODE_ENV === "production" || process.env.NODE_ENV === "test" || process.env.VITEST === "true") {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
console.warn(
|
|
539
|
+
"[FrontXProvider] No query cache available. Add queryCache() or queryCacheShared() to your plugin composition. useApiQuery/useApiMutation will fail without it."
|
|
540
|
+
);
|
|
541
|
+
}, [app, queryClient]);
|
|
542
|
+
useEffect3(() => {
|
|
53
543
|
return () => {
|
|
54
544
|
if (!providedApp) {
|
|
55
545
|
app.destroy();
|
|
56
546
|
}
|
|
57
547
|
};
|
|
58
548
|
}, [app, providedApp]);
|
|
59
|
-
const content = /* @__PURE__ */
|
|
549
|
+
const content = /* @__PURE__ */ jsx3(FrontXContext.Provider, { value: app, children: /* @__PURE__ */ jsx3(ReduxProvider, { store: app.store, children: /* @__PURE__ */ jsx3(FrontXQueryClientProvider, { queryClient, children: deferQuerySubtree ? null : children }) }) });
|
|
60
550
|
if (mfeBridge) {
|
|
61
|
-
return /* @__PURE__ */
|
|
551
|
+
return /* @__PURE__ */ jsx3(MfeProvider, { value: mfeBridge, children: content });
|
|
62
552
|
}
|
|
63
553
|
return content;
|
|
64
554
|
};
|
|
65
555
|
|
|
556
|
+
// src/hooks/useCanAccess.ts
|
|
557
|
+
import { useEffect as useEffect4, useState as useState3 } from "react";
|
|
558
|
+
function serializeRecordValue(value) {
|
|
559
|
+
if (value === null) return "n:";
|
|
560
|
+
if (typeof value === "string") return `s:${value}`;
|
|
561
|
+
if (typeof value === "number") {
|
|
562
|
+
return `d:${Object.is(value, -0) ? "-0" : String(value)}`;
|
|
563
|
+
}
|
|
564
|
+
return value ? "b:1" : "b:0";
|
|
565
|
+
}
|
|
566
|
+
function accessQueryKey(query) {
|
|
567
|
+
const { action, resource, record } = query;
|
|
568
|
+
const normalizedRecord = record ? Object.entries(record).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => [k, serializeRecordValue(v)]) : null;
|
|
569
|
+
return JSON.stringify([action, resource, normalizedRecord]);
|
|
570
|
+
}
|
|
571
|
+
function getAuthRuntime(app) {
|
|
572
|
+
return app.auth ?? null;
|
|
573
|
+
}
|
|
574
|
+
var DENIED_NO_AUTH = { allow: false, isResolving: false };
|
|
575
|
+
function useCanAccess(query) {
|
|
576
|
+
const app = useFrontX();
|
|
577
|
+
const auth2 = getAuthRuntime(app);
|
|
578
|
+
const stableKey = accessQueryKey(query);
|
|
579
|
+
const [stableQuery, setStableQuery] = useState3(() => query);
|
|
580
|
+
const [runState, setRunState] = useState3({ auth: auth2, stableKey });
|
|
581
|
+
const [result, setResult] = useState3({ allow: false, isResolving: true });
|
|
582
|
+
if (runState.auth !== auth2 || runState.stableKey !== stableKey) {
|
|
583
|
+
setRunState({ auth: auth2, stableKey });
|
|
584
|
+
setStableQuery(query);
|
|
585
|
+
setResult({ allow: false, isResolving: true });
|
|
586
|
+
}
|
|
587
|
+
useEffect4(() => {
|
|
588
|
+
if (!auth2) {
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
let alive = true;
|
|
592
|
+
const controller = new AbortController();
|
|
593
|
+
void auth2.canAccess(stableQuery, { signal: controller.signal }).then((decision) => {
|
|
594
|
+
if (alive) {
|
|
595
|
+
setResult({ allow: decision === "allow", isResolving: false });
|
|
596
|
+
}
|
|
597
|
+
}).catch(() => {
|
|
598
|
+
if (alive) {
|
|
599
|
+
setResult({ allow: false, isResolving: false });
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
return () => {
|
|
603
|
+
alive = false;
|
|
604
|
+
controller.abort();
|
|
605
|
+
};
|
|
606
|
+
}, [auth2, stableQuery]);
|
|
607
|
+
return auth2 ? result : DENIED_NO_AUTH;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// src/components/CanAccess.tsx
|
|
611
|
+
function CanAccess({
|
|
612
|
+
query,
|
|
613
|
+
allowed,
|
|
614
|
+
denied = null,
|
|
615
|
+
loading
|
|
616
|
+
}) {
|
|
617
|
+
const { allow, isResolving } = useCanAccess(query);
|
|
618
|
+
if (isResolving) {
|
|
619
|
+
return loading !== void 0 ? loading : denied;
|
|
620
|
+
}
|
|
621
|
+
return allow ? allowed : denied;
|
|
622
|
+
}
|
|
623
|
+
|
|
66
624
|
// src/hooks/useAppDispatch.ts
|
|
67
625
|
import { useDispatch } from "react-redux";
|
|
68
626
|
function useAppDispatch() {
|
|
@@ -74,9 +632,9 @@ import { useSelector } from "react-redux";
|
|
|
74
632
|
var useAppSelector = useSelector;
|
|
75
633
|
|
|
76
634
|
// src/hooks/useTranslation.ts
|
|
77
|
-
import { useMemo as
|
|
635
|
+
import { useMemo as useMemo3, useCallback, useSyncExternalStore } from "react";
|
|
78
636
|
function useTranslation() {
|
|
79
|
-
const app =
|
|
637
|
+
const app = useFrontX();
|
|
80
638
|
const { i18nRegistry: i18nRegistry2 } = app;
|
|
81
639
|
const version = useSyncExternalStore(
|
|
82
640
|
useCallback(
|
|
@@ -88,7 +646,7 @@ function useTranslation() {
|
|
|
88
646
|
() => i18nRegistry2.getVersion(),
|
|
89
647
|
() => i18nRegistry2.getVersion()
|
|
90
648
|
);
|
|
91
|
-
const language =
|
|
649
|
+
const language = useMemo3(() => {
|
|
92
650
|
void version;
|
|
93
651
|
return i18nRegistry2.getLanguage();
|
|
94
652
|
}, [i18nRegistry2, version]);
|
|
@@ -106,7 +664,7 @@ function useTranslation() {
|
|
|
106
664
|
},
|
|
107
665
|
[app.actions]
|
|
108
666
|
);
|
|
109
|
-
const isRTL =
|
|
667
|
+
const isRTL = useMemo3(() => {
|
|
110
668
|
void language;
|
|
111
669
|
return i18nRegistry2.isRTL();
|
|
112
670
|
}, [i18nRegistry2, language]);
|
|
@@ -119,16 +677,15 @@ function useTranslation() {
|
|
|
119
677
|
}
|
|
120
678
|
|
|
121
679
|
// src/hooks/useScreenTranslations.ts
|
|
122
|
-
import { useState, useEffect as
|
|
680
|
+
import { useState as useState4, useEffect as useEffect5, useMemo as useMemo4, useCallback as useCallback2, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
123
681
|
function isTranslationLoader(input) {
|
|
124
682
|
return typeof input === "function";
|
|
125
683
|
}
|
|
126
684
|
function useScreenTranslations(screensetId, screenId, translations) {
|
|
127
|
-
const app =
|
|
685
|
+
const app = useFrontX();
|
|
128
686
|
const { i18nRegistry: i18nRegistry2 } = app;
|
|
129
|
-
const [loadedLanguage, setLoadedLanguage] =
|
|
130
|
-
const [
|
|
131
|
-
const [error, setError] = useState(null);
|
|
687
|
+
const [loadedLanguage, setLoadedLanguage] = useState4(null);
|
|
688
|
+
const [error, setError] = useState4(null);
|
|
132
689
|
const version = useSyncExternalStore2(
|
|
133
690
|
useCallback2(
|
|
134
691
|
(callback) => i18nRegistry2.subscribe(callback),
|
|
@@ -137,11 +694,11 @@ function useScreenTranslations(screensetId, screenId, translations) {
|
|
|
137
694
|
() => i18nRegistry2.getVersion(),
|
|
138
695
|
() => i18nRegistry2.getVersion()
|
|
139
696
|
);
|
|
140
|
-
const currentLanguage =
|
|
697
|
+
const currentLanguage = useMemo4(() => {
|
|
141
698
|
void version;
|
|
142
699
|
return i18nRegistry2.getLanguage();
|
|
143
700
|
}, [i18nRegistry2, version]);
|
|
144
|
-
const loader =
|
|
701
|
+
const loader = useMemo4(() => {
|
|
145
702
|
if (isTranslationLoader(translations)) {
|
|
146
703
|
return translations;
|
|
147
704
|
}
|
|
@@ -154,12 +711,11 @@ function useScreenTranslations(screensetId, screenId, translations) {
|
|
|
154
711
|
return module.default;
|
|
155
712
|
};
|
|
156
713
|
}, [translations]);
|
|
157
|
-
|
|
714
|
+
useEffect5(() => {
|
|
158
715
|
if (!currentLanguage || currentLanguage === loadedLanguage) {
|
|
159
716
|
return;
|
|
160
717
|
}
|
|
161
718
|
let cancelled = false;
|
|
162
|
-
setIsLoading(true);
|
|
163
719
|
const loadTranslations = async () => {
|
|
164
720
|
try {
|
|
165
721
|
const namespace = `screen.${screensetId}.${screenId}`;
|
|
@@ -168,13 +724,11 @@ function useScreenTranslations(screensetId, screenId, translations) {
|
|
|
168
724
|
i18nRegistry2.register(namespace, currentLanguage, loadedTranslations);
|
|
169
725
|
if (!cancelled) {
|
|
170
726
|
setLoadedLanguage(currentLanguage);
|
|
171
|
-
setIsLoading(false);
|
|
172
727
|
setError(null);
|
|
173
728
|
}
|
|
174
729
|
} catch (err) {
|
|
175
730
|
if (!cancelled) {
|
|
176
731
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
177
|
-
setIsLoading(false);
|
|
178
732
|
}
|
|
179
733
|
}
|
|
180
734
|
};
|
|
@@ -183,12 +737,12 @@ function useScreenTranslations(screensetId, screenId, translations) {
|
|
|
183
737
|
cancelled = true;
|
|
184
738
|
};
|
|
185
739
|
}, [screensetId, screenId, loader, i18nRegistry2, currentLanguage, loadedLanguage]);
|
|
186
|
-
const isLoaded = currentLanguage !== null && currentLanguage === loadedLanguage
|
|
740
|
+
const isLoaded = currentLanguage !== null && currentLanguage === loadedLanguage;
|
|
187
741
|
return { isLoaded, error };
|
|
188
742
|
}
|
|
189
743
|
|
|
190
744
|
// src/hooks/useFormatters.ts
|
|
191
|
-
import { useMemo as
|
|
745
|
+
import { useMemo as useMemo5 } from "react";
|
|
192
746
|
import {
|
|
193
747
|
formatDate as formatDateFn,
|
|
194
748
|
formatTime as formatTimeFn,
|
|
@@ -203,7 +757,7 @@ import {
|
|
|
203
757
|
} from "@gears-frontx/framework";
|
|
204
758
|
function useFormatters() {
|
|
205
759
|
const { language } = useTranslation();
|
|
206
|
-
return
|
|
760
|
+
return useMemo5(
|
|
207
761
|
() => {
|
|
208
762
|
void language;
|
|
209
763
|
return {
|
|
@@ -224,9 +778,9 @@ function useFormatters() {
|
|
|
224
778
|
}
|
|
225
779
|
|
|
226
780
|
// src/hooks/useTheme.ts
|
|
227
|
-
import { useCallback as useCallback3, useMemo as
|
|
781
|
+
import { useCallback as useCallback3, useMemo as useMemo6, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
228
782
|
function useTheme() {
|
|
229
|
-
const app =
|
|
783
|
+
const app = useFrontX();
|
|
230
784
|
const { themeRegistry } = app;
|
|
231
785
|
const version = useSyncExternalStore3(
|
|
232
786
|
useCallback3(
|
|
@@ -238,12 +792,12 @@ function useTheme() {
|
|
|
238
792
|
() => themeRegistry.getVersion(),
|
|
239
793
|
() => themeRegistry.getVersion()
|
|
240
794
|
);
|
|
241
|
-
const currentTheme =
|
|
795
|
+
const currentTheme = useMemo6(() => {
|
|
242
796
|
void version;
|
|
243
797
|
const theme = themeRegistry.getCurrent();
|
|
244
798
|
return theme?.id;
|
|
245
799
|
}, [themeRegistry, version]);
|
|
246
|
-
const themes2 =
|
|
800
|
+
const themes2 = useMemo6(() => {
|
|
247
801
|
return themeRegistry.getAll().map((theme) => ({
|
|
248
802
|
id: theme.id,
|
|
249
803
|
name: theme.name
|
|
@@ -264,6 +818,145 @@ function useTheme() {
|
|
|
264
818
|
};
|
|
265
819
|
}
|
|
266
820
|
|
|
821
|
+
// src/hooks/useApiQuery.ts
|
|
822
|
+
function useApiQuery(descriptor, overrides) {
|
|
823
|
+
return useFrontXQuery(descriptor, overrides);
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
// src/hooks/useApiSuspenseQuery.ts
|
|
827
|
+
function useApiSuspenseQuery(descriptor, overrides) {
|
|
828
|
+
return useFrontXSuspenseQuery(descriptor, overrides);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
// src/hooks/useApiInfiniteQuery.ts
|
|
832
|
+
function useApiInfiniteQuery(options) {
|
|
833
|
+
return useFrontXInfiniteQuery(options);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// src/hooks/useApiSuspenseInfiniteQuery.ts
|
|
837
|
+
function useApiSuspenseInfiniteQuery(options) {
|
|
838
|
+
return useFrontXSuspenseInfiniteQuery(options);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// src/hooks/useApiMutation.ts
|
|
842
|
+
import { useMemo as useMemo7 } from "react";
|
|
843
|
+
function useApiMutation(options) {
|
|
844
|
+
const queryClient = useRequiredFrontXQueryClient();
|
|
845
|
+
const queryCache2 = useMemo7(() => createQueryCache(queryClient), [queryClient]);
|
|
846
|
+
const callbackCtx = useMemo7(() => ({ queryCache: queryCache2 }), [queryCache2]);
|
|
847
|
+
return useFrontXMutation(options, callbackCtx);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// src/hooks/useApiStream.ts
|
|
851
|
+
import { useEffect as useEffect6, useMemo as useMemo8, useRef as useRef2, useState as useState5, useCallback as useCallback4 } from "react";
|
|
852
|
+
function useApiStream(descriptor, options) {
|
|
853
|
+
const mode = options?.mode ?? "latest";
|
|
854
|
+
const enabled = options?.enabled ?? true;
|
|
855
|
+
const [data, setData] = useState5(void 0);
|
|
856
|
+
const [events, setEvents] = useState5([]);
|
|
857
|
+
const [status, setStatus] = useState5(() => enabled ? "connecting" : "idle");
|
|
858
|
+
const [error, setError] = useState5(null);
|
|
859
|
+
const connectPromiseRef = useRef2(null);
|
|
860
|
+
const connectionIdRef = useRef2(null);
|
|
861
|
+
const disconnectRequestedRef = useRef2(false);
|
|
862
|
+
const descriptorRef = useLatest(descriptor);
|
|
863
|
+
const descriptorKey = useMemo8(() => JSON.stringify(descriptor.key), [descriptor.key]);
|
|
864
|
+
const resetKey = `${descriptorKey}:${mode}`;
|
|
865
|
+
const [prevResetKey, setPrevResetKey] = useState5(resetKey);
|
|
866
|
+
if (resetKey !== prevResetKey) {
|
|
867
|
+
setPrevResetKey(resetKey);
|
|
868
|
+
setData(void 0);
|
|
869
|
+
setEvents([]);
|
|
870
|
+
setError(null);
|
|
871
|
+
}
|
|
872
|
+
const connectKey = `${resetKey}:${enabled}`;
|
|
873
|
+
const [prevConnectKey, setPrevConnectKey] = useState5(connectKey);
|
|
874
|
+
if (connectKey !== prevConnectKey) {
|
|
875
|
+
setPrevConnectKey(connectKey);
|
|
876
|
+
if (enabled) {
|
|
877
|
+
setData(void 0);
|
|
878
|
+
setEvents([]);
|
|
879
|
+
setStatus("connecting");
|
|
880
|
+
setError(null);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
const disconnect = useCallback4(() => {
|
|
884
|
+
disconnectRequestedRef.current = true;
|
|
885
|
+
if (connectionIdRef.current) {
|
|
886
|
+
descriptorRef.current.disconnect(connectionIdRef.current);
|
|
887
|
+
connectionIdRef.current = null;
|
|
888
|
+
disconnectRequestedRef.current = false;
|
|
889
|
+
}
|
|
890
|
+
setStatus("disconnected");
|
|
891
|
+
}, [descriptorRef]);
|
|
892
|
+
useEffect6(() => {
|
|
893
|
+
if (!enabled) {
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
let cancelled = false;
|
|
897
|
+
disconnectRequestedRef.current = false;
|
|
898
|
+
const d = descriptorRef.current;
|
|
899
|
+
const connectPromise = d.connect(
|
|
900
|
+
(event) => {
|
|
901
|
+
if (cancelled) return;
|
|
902
|
+
setData(event);
|
|
903
|
+
setStatus("connected");
|
|
904
|
+
if (mode === "accumulate") {
|
|
905
|
+
setEvents((prev) => [...prev, event]);
|
|
906
|
+
}
|
|
907
|
+
},
|
|
908
|
+
() => {
|
|
909
|
+
if (cancelled) return;
|
|
910
|
+
setStatus("disconnected");
|
|
911
|
+
connectionIdRef.current = null;
|
|
912
|
+
}
|
|
913
|
+
);
|
|
914
|
+
connectPromiseRef.current = connectPromise;
|
|
915
|
+
connectPromise.then((id) => {
|
|
916
|
+
if (cancelled) return;
|
|
917
|
+
if (disconnectRequestedRef.current) {
|
|
918
|
+
d.disconnect(id);
|
|
919
|
+
disconnectRequestedRef.current = false;
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
connectionIdRef.current = id;
|
|
923
|
+
setStatus("connected");
|
|
924
|
+
}).catch((err) => {
|
|
925
|
+
if (cancelled) return;
|
|
926
|
+
if (disconnectRequestedRef.current) {
|
|
927
|
+
disconnectRequestedRef.current = false;
|
|
928
|
+
setStatus("disconnected");
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
931
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
932
|
+
setStatus("error");
|
|
933
|
+
});
|
|
934
|
+
return () => {
|
|
935
|
+
cancelled = true;
|
|
936
|
+
connectPromise.then(
|
|
937
|
+
(id) => d.disconnect(id),
|
|
938
|
+
() => {
|
|
939
|
+
}
|
|
940
|
+
);
|
|
941
|
+
connectPromiseRef.current = null;
|
|
942
|
+
connectionIdRef.current = null;
|
|
943
|
+
};
|
|
944
|
+
}, [descriptorKey, enabled, mode, descriptorRef]);
|
|
945
|
+
return { data, events, status: enabled ? status : "idle", error, disconnect };
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
// src/hooks/useQueryCache.ts
|
|
949
|
+
import { useMemo as useMemo9 } from "react";
|
|
950
|
+
function useQueryCache() {
|
|
951
|
+
const queryClient = useOptionalFrontXQueryClient();
|
|
952
|
+
if (!queryClient) {
|
|
953
|
+
throw new Error(
|
|
954
|
+
"[FrontXProvider] No query cache available. Add queryCache() or queryCacheShared() to your plugin composition."
|
|
955
|
+
);
|
|
956
|
+
}
|
|
957
|
+
return useMemo9(() => createQueryCache(queryClient), [queryClient]);
|
|
958
|
+
}
|
|
959
|
+
|
|
267
960
|
// src/mfe/hooks/useMfeBridge.ts
|
|
268
961
|
function useMfeBridge() {
|
|
269
962
|
const { bridge } = useMfeContext();
|
|
@@ -271,15 +964,15 @@ function useMfeBridge() {
|
|
|
271
964
|
}
|
|
272
965
|
|
|
273
966
|
// src/mfe/hooks/useSharedProperty.ts
|
|
274
|
-
import { useSyncExternalStore as useSyncExternalStore4, useCallback as
|
|
967
|
+
import { useSyncExternalStore as useSyncExternalStore4, useCallback as useCallback5 } from "react";
|
|
275
968
|
function useSharedProperty(propertyTypeId) {
|
|
276
969
|
const { bridge } = useMfeContext();
|
|
277
|
-
const subscribe =
|
|
970
|
+
const subscribe = useCallback5((callback) => {
|
|
278
971
|
return bridge.subscribeToProperty(propertyTypeId, () => {
|
|
279
972
|
callback();
|
|
280
973
|
});
|
|
281
974
|
}, [bridge, propertyTypeId]);
|
|
282
|
-
const getSnapshot =
|
|
975
|
+
const getSnapshot = useCallback5(() => {
|
|
283
976
|
const property = bridge.getProperty(propertyTypeId);
|
|
284
977
|
return property?.value;
|
|
285
978
|
}, [bridge, propertyTypeId]);
|
|
@@ -288,14 +981,14 @@ function useSharedProperty(propertyTypeId) {
|
|
|
288
981
|
}
|
|
289
982
|
|
|
290
983
|
// src/mfe/hooks/useHostAction.ts
|
|
291
|
-
import { useCallback as
|
|
984
|
+
import { useCallback as useCallback6 } from "react";
|
|
292
985
|
function useHostAction(actionTypeId) {
|
|
293
986
|
const { bridge } = useMfeContext();
|
|
294
|
-
return
|
|
987
|
+
return useCallback6((payload) => {
|
|
295
988
|
const chain = {
|
|
296
989
|
action: {
|
|
297
990
|
type: actionTypeId,
|
|
298
|
-
target: bridge.
|
|
991
|
+
target: bridge.extDomainId,
|
|
299
992
|
payload
|
|
300
993
|
}
|
|
301
994
|
};
|
|
@@ -309,23 +1002,23 @@ function useHostAction(actionTypeId) {
|
|
|
309
1002
|
}
|
|
310
1003
|
|
|
311
1004
|
// src/mfe/hooks/useDomainExtensions.ts
|
|
312
|
-
import { useSyncExternalStore as useSyncExternalStore5, useCallback as
|
|
1005
|
+
import { useSyncExternalStore as useSyncExternalStore5, useCallback as useCallback7, useRef as useRef3 } from "react";
|
|
313
1006
|
function useDomainExtensions(domainId) {
|
|
314
|
-
const app =
|
|
315
|
-
const registry = app.
|
|
1007
|
+
const app = useFrontX();
|
|
1008
|
+
const registry = app.mfeRegistry;
|
|
316
1009
|
if (!registry) {
|
|
317
1010
|
throw new Error(
|
|
318
|
-
"useDomainExtensions requires the microfrontends plugin. Add microfrontends() to your
|
|
1011
|
+
"useDomainExtensions requires the microfrontends plugin. Add microfrontends() to your Gears FrontX app configuration."
|
|
319
1012
|
);
|
|
320
1013
|
}
|
|
321
|
-
const subscribe =
|
|
1014
|
+
const subscribe = useCallback7(
|
|
322
1015
|
(onStoreChange) => {
|
|
323
1016
|
return app.store.subscribe(onStoreChange);
|
|
324
1017
|
},
|
|
325
1018
|
[app.store]
|
|
326
1019
|
);
|
|
327
|
-
const cacheRef =
|
|
328
|
-
const getSnapshot =
|
|
1020
|
+
const cacheRef = useRef3({ ids: "", extensions: [] });
|
|
1021
|
+
const getSnapshot = useCallback7(() => {
|
|
329
1022
|
const extensions = registry.getExtensionsForDomain(domainId);
|
|
330
1023
|
const ids = extensions.map((e) => e.id).join(",");
|
|
331
1024
|
if (ids !== cacheRef.current.ids) {
|
|
@@ -336,216 +1029,230 @@ function useDomainExtensions(domainId) {
|
|
|
336
1029
|
return useSyncExternalStore5(subscribe, getSnapshot, getSnapshot);
|
|
337
1030
|
}
|
|
338
1031
|
|
|
339
|
-
// src/mfe/hooks/
|
|
340
|
-
import { useSyncExternalStore as useSyncExternalStore6, useCallback as
|
|
341
|
-
function
|
|
342
|
-
const app =
|
|
343
|
-
const registry = app.
|
|
1032
|
+
// src/mfe/hooks/useMountedExtensions.ts
|
|
1033
|
+
import { useSyncExternalStore as useSyncExternalStore6, useCallback as useCallback8, useRef as useRef4 } from "react";
|
|
1034
|
+
function useMountedExtensions(domainId) {
|
|
1035
|
+
const app = useFrontX();
|
|
1036
|
+
const registry = app.mfeRegistry;
|
|
344
1037
|
if (!registry) {
|
|
345
1038
|
throw new Error(
|
|
346
|
-
"
|
|
1039
|
+
"useMountedExtensions requires the microfrontends plugin. Add microfrontends() to your Gears FrontX app configuration."
|
|
347
1040
|
);
|
|
348
1041
|
}
|
|
349
|
-
const subscribe =
|
|
1042
|
+
const subscribe = useCallback8(
|
|
350
1043
|
(onStoreChange) => {
|
|
351
1044
|
return app.store.subscribe(onStoreChange);
|
|
352
1045
|
},
|
|
353
1046
|
[app.store]
|
|
354
1047
|
);
|
|
355
|
-
const cacheRef =
|
|
356
|
-
const getSnapshot =
|
|
357
|
-
const
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
1048
|
+
const cacheRef = useRef4({ key: "", extensions: [] });
|
|
1049
|
+
const getSnapshot = useCallback8(() => {
|
|
1050
|
+
const ids = registry.getMountedExtensions(domainId);
|
|
1051
|
+
const resolved = ids.map((id) => registry.getExtension(id)).filter((ext) => ext !== void 0);
|
|
1052
|
+
const key = ids.join(",");
|
|
1053
|
+
if (key !== cacheRef.current.key) {
|
|
1054
|
+
cacheRef.current = { key, extensions: resolved };
|
|
361
1055
|
}
|
|
362
|
-
return cacheRef.current.
|
|
363
|
-
}, [registry]);
|
|
1056
|
+
return cacheRef.current.extensions;
|
|
1057
|
+
}, [registry, domainId]);
|
|
364
1058
|
return useSyncExternalStore6(subscribe, getSnapshot, getSnapshot);
|
|
365
1059
|
}
|
|
366
1060
|
|
|
367
|
-
// src/mfe/hooks/
|
|
368
|
-
import { useSyncExternalStore as useSyncExternalStore7, useCallback as
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
const
|
|
372
|
-
const registry = app.screensetsRegistry;
|
|
1061
|
+
// src/mfe/hooks/useRegisteredPackages.ts
|
|
1062
|
+
import { useSyncExternalStore as useSyncExternalStore7, useCallback as useCallback9, useRef as useRef5 } from "react";
|
|
1063
|
+
function useRegisteredPackages() {
|
|
1064
|
+
const app = useFrontX();
|
|
1065
|
+
const registry = app.mfeRegistry;
|
|
373
1066
|
if (!registry) {
|
|
374
1067
|
throw new Error(
|
|
375
|
-
"
|
|
1068
|
+
"useRegisteredPackages requires the microfrontends plugin. Add microfrontends() to your Gears FrontX app configuration."
|
|
376
1069
|
);
|
|
377
1070
|
}
|
|
378
|
-
const subscribe =
|
|
1071
|
+
const subscribe = useCallback9(
|
|
379
1072
|
(onStoreChange) => {
|
|
380
1073
|
return app.store.subscribe(onStoreChange);
|
|
381
1074
|
},
|
|
382
1075
|
[app.store]
|
|
383
1076
|
);
|
|
384
|
-
const cacheRef =
|
|
385
|
-
const getSnapshot =
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
cacheRef.current = { activePackage: result };
|
|
391
|
-
}
|
|
392
|
-
return cacheRef.current.activePackage;
|
|
393
|
-
}
|
|
394
|
-
const activePackage = extractGtsPackage(mountedExtensionId);
|
|
395
|
-
if (activePackage !== cacheRef.current.activePackage) {
|
|
396
|
-
cacheRef.current = { activePackage };
|
|
1077
|
+
const cacheRef = useRef5({ packages: "", list: [] });
|
|
1078
|
+
const getSnapshot = useCallback9(() => {
|
|
1079
|
+
const list = registry.getRegisteredPackages();
|
|
1080
|
+
const packages = list.join(",");
|
|
1081
|
+
if (packages !== cacheRef.current.packages) {
|
|
1082
|
+
cacheRef.current = { packages, list };
|
|
397
1083
|
}
|
|
398
|
-
return cacheRef.current.
|
|
1084
|
+
return cacheRef.current.list;
|
|
399
1085
|
}, [registry]);
|
|
400
1086
|
return useSyncExternalStore7(subscribe, getSnapshot, getSnapshot);
|
|
401
1087
|
}
|
|
402
1088
|
|
|
403
|
-
// src/mfe/
|
|
404
|
-
import {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
1089
|
+
// src/mfe/ThemeAwareReactLifecycle.tsx
|
|
1090
|
+
import { createRoot } from "react-dom/client";
|
|
1091
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1092
|
+
function resolveProviderMountOptions(app, bridge, mountContext) {
|
|
1093
|
+
const extensionId = mountContext?.extensionId;
|
|
1094
|
+
const domainId = mountContext?.domainId;
|
|
1095
|
+
const isMountedMfe = typeof extensionId === "string" && typeof domainId === "string";
|
|
1096
|
+
if (isMountedMfe && !resolveFrontXQueryClient(app) && !hasFrontXQueryClientActivator(app)) {
|
|
1097
|
+
throw new Error(
|
|
1098
|
+
"[FrontXProvider] Mounted MFEs require queryCacheShared() in the child app and queryCache() in the host app before loading the MFE app."
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
1101
|
+
return {
|
|
1102
|
+
mfeBridge: isMountedMfe ? { bridge, extensionId, domainId } : void 0
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
function MountRuntimeAwareProvider({
|
|
1106
|
+
app,
|
|
1107
|
+
mfeBridge,
|
|
1108
|
+
children
|
|
1109
|
+
}) {
|
|
1110
|
+
return /* @__PURE__ */ jsx4(FrontXProvider, { app, mfeBridge, children });
|
|
1111
|
+
}
|
|
1112
|
+
var ThemeAwareReactLifecycle = class {
|
|
1113
|
+
constructor(app) {
|
|
1114
|
+
this.app = app;
|
|
409
1115
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
1116
|
+
app;
|
|
1117
|
+
root = null;
|
|
1118
|
+
mount(container, bridge, mountContext) {
|
|
1119
|
+
if (container instanceof ShadowRoot) {
|
|
1120
|
+
this.adoptHostStylesIntoShadowRoot(container);
|
|
413
1121
|
}
|
|
414
|
-
|
|
1122
|
+
this.injectBaseResets(container);
|
|
1123
|
+
this.initializeStyles(container);
|
|
1124
|
+
const providerMountOptions = resolveProviderMountOptions(this.app, bridge, mountContext);
|
|
1125
|
+
this.root = createRoot(container);
|
|
1126
|
+
this.root.render(
|
|
1127
|
+
/* @__PURE__ */ jsx4(
|
|
1128
|
+
MountRuntimeAwareProvider,
|
|
1129
|
+
{
|
|
1130
|
+
app: this.app,
|
|
1131
|
+
mfeBridge: providerMountOptions.mfeBridge,
|
|
1132
|
+
children: this.renderContent(bridge)
|
|
1133
|
+
}
|
|
1134
|
+
)
|
|
1135
|
+
);
|
|
1136
|
+
}
|
|
1137
|
+
unmount(_container) {
|
|
1138
|
+
if (this.root) {
|
|
1139
|
+
this.root.unmount();
|
|
1140
|
+
this.root = null;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* Copy all inline <style> and <link rel="stylesheet"> from the host document
|
|
1145
|
+
* into the shadow root so that Tailwind and component styles apply inside the MFE.
|
|
1146
|
+
*/
|
|
1147
|
+
adoptHostStylesIntoShadowRoot(shadowRoot) {
|
|
1148
|
+
const styleElements = document.head.querySelectorAll("style");
|
|
1149
|
+
styleElements.forEach((el) => {
|
|
1150
|
+
const clone = document.createElement("style");
|
|
1151
|
+
clone.textContent = el.textContent ?? "";
|
|
1152
|
+
shadowRoot.appendChild(clone);
|
|
1153
|
+
});
|
|
1154
|
+
const linkElements = document.head.querySelectorAll('link[rel="stylesheet"]');
|
|
1155
|
+
linkElements.forEach((el) => {
|
|
1156
|
+
const clone = el.cloneNode(true);
|
|
1157
|
+
shadowRoot.appendChild(clone);
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
/**
|
|
1161
|
+
* Box-model resets and :host defaults needed inside every shadow root.
|
|
1162
|
+
* These aren't part of Tailwind's compiled output but are required for
|
|
1163
|
+
* consistent rendering across browsers.
|
|
1164
|
+
*/
|
|
1165
|
+
injectBaseResets(container) {
|
|
1166
|
+
const style = document.createElement("style");
|
|
1167
|
+
style.textContent = `
|
|
1168
|
+
*, *::before, *::after {
|
|
1169
|
+
box-sizing: border-box;
|
|
1170
|
+
border-width: 0;
|
|
1171
|
+
border-style: solid;
|
|
1172
|
+
border-color: currentColor;
|
|
1173
|
+
}
|
|
1174
|
+
* { margin: 0; padding: 0; }
|
|
1175
|
+
:host {
|
|
1176
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
1177
|
+
line-height: 1.5;
|
|
1178
|
+
-webkit-font-smoothing: antialiased;
|
|
1179
|
+
-moz-osx-font-smoothing: grayscale;
|
|
1180
|
+
color: hsl(var(--foreground));
|
|
1181
|
+
background-color: hsl(var(--background));
|
|
1182
|
+
}
|
|
1183
|
+
`;
|
|
1184
|
+
container.appendChild(style);
|
|
415
1185
|
}
|
|
416
|
-
|
|
1186
|
+
/**
|
|
1187
|
+
* Hook for subclasses to inject additional CSS not covered by the adopted host
|
|
1188
|
+
* stylesheet (e.g., MFE-specific @font-face rules or custom animations).
|
|
1189
|
+
* No-op by default: host styles adopted in adoptHostStylesIntoShadowRoot()
|
|
1190
|
+
* already include all Tailwind utilities compiled from MFE source files.
|
|
1191
|
+
*/
|
|
1192
|
+
initializeStyles(_container) {
|
|
417
1193
|
}
|
|
418
1194
|
};
|
|
419
1195
|
|
|
420
1196
|
// src/mfe/components/ExtensionDomainSlot.tsx
|
|
421
|
-
import { useEffect as
|
|
422
|
-
import {
|
|
423
|
-
FRONTX_ACTION_MOUNT_EXT,
|
|
424
|
-
FRONTX_ACTION_UNMOUNT_EXT
|
|
425
|
-
} from "@gears-frontx/framework";
|
|
426
|
-
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
1197
|
+
import { useEffect as useEffect7, useEffectEvent, useRef as useRef6, useState as useState6 } from "react";
|
|
1198
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
427
1199
|
function ExtensionDomainSlot(props) {
|
|
428
1200
|
const {
|
|
429
1201
|
registry,
|
|
430
1202
|
domainId,
|
|
431
|
-
extensionId,
|
|
432
1203
|
className,
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
loadingComponent,
|
|
437
|
-
errorComponent
|
|
1204
|
+
onAttached,
|
|
1205
|
+
onDetached,
|
|
1206
|
+
loadingComponent = null
|
|
438
1207
|
} = props;
|
|
439
|
-
const
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
setIsLoading(true);
|
|
452
|
-
setError(null);
|
|
453
|
-
await registry.executeActionsChain({
|
|
454
|
-
action: {
|
|
455
|
-
type: FRONTX_ACTION_MOUNT_EXT,
|
|
456
|
-
target: domainId,
|
|
457
|
-
payload: {
|
|
458
|
-
extensionId
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
});
|
|
462
|
-
if (!mounted) {
|
|
463
|
-
await registry.executeActionsChain({
|
|
464
|
-
action: {
|
|
465
|
-
type: FRONTX_ACTION_UNMOUNT_EXT,
|
|
466
|
-
target: domainId,
|
|
467
|
-
payload: {
|
|
468
|
-
extensionId
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
});
|
|
472
|
-
return;
|
|
473
|
-
}
|
|
474
|
-
const newBridge = registry.getParentBridge(extensionId);
|
|
475
|
-
if (!newBridge) {
|
|
476
|
-
throw new Error(`Failed to obtain bridge for extension ${extensionId} after mount`);
|
|
477
|
-
}
|
|
478
|
-
currentBridge = newBridge;
|
|
479
|
-
setBridge(newBridge);
|
|
480
|
-
setIsLoading(false);
|
|
481
|
-
if (onMounted) {
|
|
482
|
-
onMounted(newBridge);
|
|
483
|
-
}
|
|
484
|
-
} catch (err) {
|
|
485
|
-
if (!mounted) {
|
|
486
|
-
return;
|
|
487
|
-
}
|
|
488
|
-
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
489
|
-
setError(errorObj);
|
|
490
|
-
setIsLoading(false);
|
|
491
|
-
if (onError) {
|
|
492
|
-
onError(errorObj);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
1208
|
+
const rootRef = useRef6(null);
|
|
1209
|
+
const emitAttached = useEffectEvent((root) => {
|
|
1210
|
+
onAttached?.(root);
|
|
1211
|
+
});
|
|
1212
|
+
const emitDetached = useEffectEvent(() => {
|
|
1213
|
+
onDetached?.();
|
|
1214
|
+
});
|
|
1215
|
+
const [attached, setAttached] = useState6(false);
|
|
1216
|
+
useEffect7(() => {
|
|
1217
|
+
const root = rootRef.current;
|
|
1218
|
+
if (!root) {
|
|
1219
|
+
return;
|
|
495
1220
|
}
|
|
496
|
-
|
|
1221
|
+
const mounter = registry.getMounter(domainId);
|
|
1222
|
+
mounter.attach(root);
|
|
1223
|
+
setAttached(true);
|
|
1224
|
+
emitAttached(root);
|
|
497
1225
|
return () => {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
action: {
|
|
502
|
-
type: FRONTX_ACTION_UNMOUNT_EXT,
|
|
503
|
-
target: domainId,
|
|
504
|
-
payload: {
|
|
505
|
-
extensionId
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
}).then(() => {
|
|
509
|
-
if (onUnmounted) {
|
|
510
|
-
onUnmounted();
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
}
|
|
1226
|
+
void mounter.detach();
|
|
1227
|
+
setAttached(false);
|
|
1228
|
+
emitDetached();
|
|
514
1229
|
};
|
|
515
|
-
}, [registry, domainId
|
|
516
|
-
|
|
517
|
-
return /* @__PURE__ */ jsx3("div", { className, "data-domain-id": domainId, "data-extension-id": extensionId, children: loadingComponent ?? /* @__PURE__ */ jsx3("div", { children: "Loading extension..." }) });
|
|
518
|
-
}
|
|
519
|
-
if (error) {
|
|
520
|
-
return /* @__PURE__ */ jsx3("div", { className, "data-domain-id": domainId, "data-extension-id": extensionId, children: errorComponent ? errorComponent(error) : /* @__PURE__ */ jsxs("div", { children: [
|
|
521
|
-
/* @__PURE__ */ jsx3("strong", { children: "Error loading extension:" }),
|
|
522
|
-
/* @__PURE__ */ jsx3("pre", { children: error.message })
|
|
523
|
-
] }) });
|
|
524
|
-
}
|
|
525
|
-
return /* @__PURE__ */ jsx3(
|
|
1230
|
+
}, [registry, domainId]);
|
|
1231
|
+
return /* @__PURE__ */ jsx5(
|
|
526
1232
|
"div",
|
|
527
1233
|
{
|
|
528
|
-
ref:
|
|
1234
|
+
ref: rootRef,
|
|
529
1235
|
className,
|
|
530
1236
|
"data-domain-id": domainId,
|
|
531
|
-
|
|
532
|
-
"data-bridge-active": bridge !== null
|
|
1237
|
+
children: !attached ? loadingComponent : null
|
|
533
1238
|
}
|
|
534
1239
|
);
|
|
535
1240
|
}
|
|
536
1241
|
|
|
537
1242
|
// src/index.ts
|
|
538
1243
|
import {
|
|
539
|
-
|
|
540
|
-
|
|
1244
|
+
createFrontX,
|
|
1245
|
+
createFrontXApp as createFrontXApp2,
|
|
541
1246
|
presets,
|
|
542
1247
|
ACCOUNTS_DOMAIN,
|
|
543
1248
|
I18nRegistry,
|
|
544
|
-
screensets,
|
|
545
1249
|
themes,
|
|
546
1250
|
layout,
|
|
547
1251
|
i18n,
|
|
548
1252
|
effects,
|
|
1253
|
+
queryCache,
|
|
1254
|
+
queryCacheShared,
|
|
1255
|
+
subscribeQueryCacheRuntimeChanged as subscribeQueryCacheRuntimeChanged2,
|
|
549
1256
|
createThemeRegistry,
|
|
550
1257
|
createStore,
|
|
551
1258
|
getStore,
|
|
@@ -560,14 +1267,12 @@ import {
|
|
|
560
1267
|
footerSlice,
|
|
561
1268
|
menuSlice,
|
|
562
1269
|
sidebarSlice,
|
|
563
|
-
screenSlice,
|
|
564
1270
|
popupSlice,
|
|
565
1271
|
overlaySlice,
|
|
566
1272
|
headerActions,
|
|
567
1273
|
footerActions,
|
|
568
1274
|
menuActions,
|
|
569
1275
|
sidebarActions,
|
|
570
|
-
screenActions,
|
|
571
1276
|
popupActions,
|
|
572
1277
|
overlayActions,
|
|
573
1278
|
setUser,
|
|
@@ -588,10 +1293,6 @@ import {
|
|
|
588
1293
|
setSidebarVisible,
|
|
589
1294
|
setSidebarWidth,
|
|
590
1295
|
setSidebarConfig,
|
|
591
|
-
setActiveScreen,
|
|
592
|
-
setScreenLoading,
|
|
593
|
-
navigateTo,
|
|
594
|
-
clearActiveScreen,
|
|
595
1296
|
openPopup,
|
|
596
1297
|
closePopup,
|
|
597
1298
|
closeTopPopup,
|
|
@@ -617,10 +1318,14 @@ import {
|
|
|
617
1318
|
initMockEffects,
|
|
618
1319
|
toggleMockMode,
|
|
619
1320
|
MockEvents,
|
|
1321
|
+
auth,
|
|
1322
|
+
frontxApiTransport,
|
|
620
1323
|
apiRegistry,
|
|
621
1324
|
BaseApiService,
|
|
622
1325
|
RestProtocol,
|
|
1326
|
+
RestEndpointProtocol,
|
|
623
1327
|
SseProtocol,
|
|
1328
|
+
SseStreamProtocol,
|
|
624
1329
|
RestMockPlugin,
|
|
625
1330
|
SseMockPlugin,
|
|
626
1331
|
MockEventSource,
|
|
@@ -644,7 +1349,7 @@ import {
|
|
|
644
1349
|
} from "@gears-frontx/framework";
|
|
645
1350
|
import { Language, TextDirection, LanguageDisplayMode } from "@gears-frontx/framework";
|
|
646
1351
|
import {
|
|
647
|
-
microfrontends,
|
|
1352
|
+
microfrontends as microfrontends2,
|
|
648
1353
|
mock
|
|
649
1354
|
} from "@gears-frontx/framework";
|
|
650
1355
|
import {
|
|
@@ -657,12 +1362,13 @@ import {
|
|
|
657
1362
|
import {
|
|
658
1363
|
selectExtensionState,
|
|
659
1364
|
selectRegisteredExtensions,
|
|
660
|
-
selectExtensionError
|
|
1365
|
+
selectExtensionError,
|
|
1366
|
+
selectMountedExtensions
|
|
661
1367
|
} from "@gears-frontx/framework";
|
|
662
1368
|
import {
|
|
663
1369
|
FRONTX_POPUP_DOMAIN,
|
|
664
1370
|
FRONTX_SIDEBAR_DOMAIN,
|
|
665
|
-
FRONTX_SCREEN_DOMAIN
|
|
1371
|
+
FRONTX_SCREEN_DOMAIN,
|
|
666
1372
|
FRONTX_OVERLAY_DOMAIN,
|
|
667
1373
|
screenDomain,
|
|
668
1374
|
sidebarDomain,
|
|
@@ -675,51 +1381,67 @@ import {
|
|
|
675
1381
|
} from "@gears-frontx/framework";
|
|
676
1382
|
import {
|
|
677
1383
|
FRONTX_ACTION_LOAD_EXT,
|
|
678
|
-
FRONTX_ACTION_MOUNT_EXT
|
|
679
|
-
FRONTX_ACTION_UNMOUNT_EXT
|
|
1384
|
+
FRONTX_ACTION_MOUNT_EXT,
|
|
1385
|
+
FRONTX_ACTION_UNMOUNT_EXT
|
|
680
1386
|
} from "@gears-frontx/framework";
|
|
681
1387
|
import {
|
|
682
1388
|
FRONTX_SHARED_PROPERTY_THEME,
|
|
683
1389
|
FRONTX_SHARED_PROPERTY_LANGUAGE
|
|
684
1390
|
} from "@gears-frontx/framework";
|
|
685
1391
|
import {
|
|
1392
|
+
ChildMfeBridge,
|
|
1393
|
+
ParentMfeBridge,
|
|
686
1394
|
MfeHandler,
|
|
687
1395
|
MfeBridgeFactory,
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
1396
|
+
MfeRegistry,
|
|
1397
|
+
MfeRegistryFactory,
|
|
1398
|
+
mfeRegistryFactory,
|
|
1399
|
+
ActionHandler,
|
|
1400
|
+
ExtensionDomainImplementation,
|
|
1401
|
+
ExtensionDomainImplementationFactory,
|
|
1402
|
+
ExtensionMounter,
|
|
1403
|
+
MountStrategy,
|
|
1404
|
+
ConcurrentMountStrategy,
|
|
1405
|
+
OptionalMountStrategy,
|
|
1406
|
+
ExclusiveMountStrategy
|
|
692
1407
|
} from "@gears-frontx/framework";
|
|
693
1408
|
import { MfeHandlerMF, gtsPlugin } from "@gears-frontx/framework";
|
|
694
1409
|
import { themeSchema, languageSchema, extensionScreenSchema } from "@gears-frontx/framework";
|
|
695
1410
|
import {
|
|
696
1411
|
createShadowRoot,
|
|
697
1412
|
injectCssVariables,
|
|
698
|
-
extractGtsPackage
|
|
1413
|
+
extractGtsPackage
|
|
699
1414
|
} from "@gears-frontx/framework";
|
|
700
1415
|
import { eventBus as frameworkEventBus } from "@gears-frontx/framework";
|
|
701
|
-
var
|
|
1416
|
+
var eventBus2 = frameworkEventBus;
|
|
702
1417
|
export {
|
|
703
1418
|
ACCOUNTS_DOMAIN,
|
|
1419
|
+
ActionHandler,
|
|
704
1420
|
ApiPlugin,
|
|
705
1421
|
ApiPluginBase,
|
|
706
1422
|
ApiProtocol,
|
|
707
1423
|
BaseApiService,
|
|
708
|
-
|
|
1424
|
+
CanAccess,
|
|
1425
|
+
ChildMfeBridge,
|
|
1426
|
+
ConcurrentMountStrategy,
|
|
1427
|
+
ExclusiveMountStrategy,
|
|
1428
|
+
ExtensionDomainImplementation,
|
|
1429
|
+
ExtensionDomainImplementationFactory,
|
|
709
1430
|
ExtensionDomainSlot,
|
|
1431
|
+
ExtensionMounter,
|
|
710
1432
|
FRONTX_ACTION_LOAD_EXT,
|
|
711
|
-
|
|
712
|
-
|
|
1433
|
+
FRONTX_ACTION_MOUNT_EXT,
|
|
1434
|
+
FRONTX_ACTION_UNMOUNT_EXT,
|
|
713
1435
|
FRONTX_MFE_ENTRY_MF,
|
|
714
1436
|
FRONTX_OVERLAY_DOMAIN,
|
|
715
1437
|
FRONTX_POPUP_DOMAIN,
|
|
716
|
-
|
|
1438
|
+
FRONTX_SCREEN_DOMAIN,
|
|
717
1439
|
FRONTX_SCREEN_EXTENSION_TYPE,
|
|
718
1440
|
FRONTX_SHARED_PROPERTY_LANGUAGE,
|
|
719
1441
|
FRONTX_SHARED_PROPERTY_THEME,
|
|
720
1442
|
FRONTX_SIDEBAR_DOMAIN,
|
|
721
|
-
|
|
722
|
-
|
|
1443
|
+
FrontXContext,
|
|
1444
|
+
FrontXProvider,
|
|
723
1445
|
I18nRegistry,
|
|
724
1446
|
I18nRegistryImpl,
|
|
725
1447
|
LAYOUT_SLICE_NAME,
|
|
@@ -732,45 +1454,51 @@ export {
|
|
|
732
1454
|
MfeHandler,
|
|
733
1455
|
MfeHandlerMF,
|
|
734
1456
|
MfeProvider,
|
|
1457
|
+
MfeRegistry,
|
|
1458
|
+
MfeRegistryFactory,
|
|
735
1459
|
MockEventSource,
|
|
736
1460
|
MockEvents,
|
|
737
|
-
|
|
1461
|
+
MountStrategy,
|
|
1462
|
+
OptionalMountStrategy,
|
|
1463
|
+
ParentMfeBridge,
|
|
1464
|
+
RestEndpointProtocol,
|
|
738
1465
|
RestMockPlugin,
|
|
739
1466
|
RestPlugin,
|
|
740
1467
|
RestPluginWithConfig,
|
|
741
1468
|
RestProtocol,
|
|
742
1469
|
SUPPORTED_LANGUAGES,
|
|
743
|
-
ScreensetsRegistry,
|
|
744
|
-
ScreensetsRegistryFactory,
|
|
745
1470
|
SseMockPlugin,
|
|
746
1471
|
SsePlugin,
|
|
747
1472
|
SsePluginWithConfig,
|
|
748
1473
|
SseProtocol,
|
|
1474
|
+
SseStreamProtocol,
|
|
749
1475
|
TENANT_SLICE_NAME,
|
|
750
1476
|
TenantEvents,
|
|
751
1477
|
TextDirection,
|
|
1478
|
+
ThemeAwareReactLifecycle,
|
|
752
1479
|
apiRegistry,
|
|
1480
|
+
auth,
|
|
753
1481
|
changeTenant,
|
|
754
|
-
clearActiveScreen,
|
|
755
1482
|
clearTenant,
|
|
756
1483
|
clearTenantAction,
|
|
757
1484
|
clearUser,
|
|
758
1485
|
closeAllPopups,
|
|
759
1486
|
closePopup,
|
|
760
1487
|
closeTopPopup,
|
|
761
|
-
|
|
762
|
-
|
|
1488
|
+
createFrontX,
|
|
1489
|
+
createFrontXApp2 as createFrontXApp,
|
|
763
1490
|
createI18nRegistry,
|
|
764
1491
|
createShadowRoot,
|
|
765
1492
|
createSlice,
|
|
766
1493
|
createStore,
|
|
767
1494
|
createThemeRegistry,
|
|
768
1495
|
effects,
|
|
769
|
-
eventBus,
|
|
1496
|
+
eventBus2 as eventBus,
|
|
770
1497
|
extensionScreenSchema,
|
|
771
|
-
|
|
1498
|
+
extractGtsPackage,
|
|
772
1499
|
footerActions,
|
|
773
1500
|
footerSlice,
|
|
1501
|
+
frontxApiTransport,
|
|
774
1502
|
getLanguageMetadata,
|
|
775
1503
|
getStore,
|
|
776
1504
|
gtsPlugin,
|
|
@@ -783,6 +1511,7 @@ export {
|
|
|
783
1511
|
initMockEffects,
|
|
784
1512
|
initTenantEffects,
|
|
785
1513
|
injectCssVariables,
|
|
1514
|
+
invalidateQueryCacheForApp,
|
|
786
1515
|
isMockPlugin,
|
|
787
1516
|
isRestShortCircuit,
|
|
788
1517
|
isShortCircuit,
|
|
@@ -794,12 +1523,12 @@ export {
|
|
|
794
1523
|
loadExtension,
|
|
795
1524
|
menuActions,
|
|
796
1525
|
menuSlice,
|
|
797
|
-
|
|
1526
|
+
mfeRegistryFactory,
|
|
1527
|
+
microfrontends2 as microfrontends,
|
|
798
1528
|
mock,
|
|
799
1529
|
mockActions,
|
|
800
1530
|
mockSlice,
|
|
801
1531
|
mountExtension,
|
|
802
|
-
navigateTo,
|
|
803
1532
|
openPopup,
|
|
804
1533
|
overlayActions,
|
|
805
1534
|
overlayDomain,
|
|
@@ -808,17 +1537,15 @@ export {
|
|
|
808
1537
|
popupDomain,
|
|
809
1538
|
popupSlice,
|
|
810
1539
|
presets,
|
|
1540
|
+
queryCache,
|
|
1541
|
+
queryCacheShared,
|
|
811
1542
|
registerExtension,
|
|
812
1543
|
registerSlice,
|
|
813
|
-
screenActions,
|
|
814
1544
|
screenDomain,
|
|
815
|
-
screenSlice,
|
|
816
|
-
screensets,
|
|
817
|
-
screensetsRegistryFactory,
|
|
818
1545
|
selectExtensionError,
|
|
819
1546
|
selectExtensionState,
|
|
1547
|
+
selectMountedExtensions,
|
|
820
1548
|
selectRegisteredExtensions,
|
|
821
|
-
setActiveScreen,
|
|
822
1549
|
setFooterConfig,
|
|
823
1550
|
setFooterVisible,
|
|
824
1551
|
setHeaderLoading,
|
|
@@ -828,7 +1555,6 @@ export {
|
|
|
828
1555
|
setMenuVisible,
|
|
829
1556
|
setMockEnabled,
|
|
830
1557
|
setOverlayVisible,
|
|
831
|
-
setScreenLoading,
|
|
832
1558
|
setSidebarCollapsed,
|
|
833
1559
|
setSidebarConfig,
|
|
834
1560
|
setSidebarContent,
|
|
@@ -844,6 +1570,7 @@ export {
|
|
|
844
1570
|
sidebarActions,
|
|
845
1571
|
sidebarDomain,
|
|
846
1572
|
sidebarSlice,
|
|
1573
|
+
subscribeQueryCacheRuntimeChanged2 as subscribeQueryCacheRuntimeChanged,
|
|
847
1574
|
tenantActions,
|
|
848
1575
|
tenantReducer,
|
|
849
1576
|
tenantSlice,
|
|
@@ -854,15 +1581,23 @@ export {
|
|
|
854
1581
|
toggleSidebar,
|
|
855
1582
|
unmountExtension,
|
|
856
1583
|
unregisterExtension,
|
|
857
|
-
|
|
1584
|
+
useApiInfiniteQuery,
|
|
1585
|
+
useApiMutation,
|
|
1586
|
+
useApiQuery,
|
|
1587
|
+
useApiStream,
|
|
1588
|
+
useApiSuspenseInfiniteQuery,
|
|
1589
|
+
useApiSuspenseQuery,
|
|
858
1590
|
useAppDispatch,
|
|
859
1591
|
useAppSelector,
|
|
1592
|
+
useCanAccess,
|
|
860
1593
|
useDomainExtensions,
|
|
861
1594
|
useFormatters,
|
|
862
|
-
|
|
1595
|
+
useFrontX,
|
|
863
1596
|
useHostAction,
|
|
864
1597
|
useMfeBridge,
|
|
865
1598
|
useMfeContext,
|
|
1599
|
+
useMountedExtensions,
|
|
1600
|
+
useQueryCache,
|
|
866
1601
|
useRegisteredPackages,
|
|
867
1602
|
useScreenTranslations,
|
|
868
1603
|
useSharedProperty,
|