@gears-frontx/react 0.1.0 → 0.2.0-alpha.15
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 +247 -64
- package/dist/index.cjs +1338 -434
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +653 -146
- package/dist/index.d.ts +653 -146
- package/dist/index.js +1179 -276
- 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 +56 -0
- package/dist/testing.js.map +1 -0
- package/dist/types-JtpziA_B.d.cts +224 -0
- package/dist/types-JtpziA_B.d.ts +224 -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 +49 -23
- package/package.json +40 -23
- 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,15 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import {
|
|
1
|
+
// src/FrontXProvider.tsx
|
|
2
|
+
import { useEffect as useEffect3 } from "react";
|
|
3
3
|
import { Provider as ReduxProvider } from "react-redux";
|
|
4
|
-
import { createHAI3App } from "@gears-frontx/framework";
|
|
5
4
|
|
|
6
|
-
// src/
|
|
5
|
+
// src/FrontXContext.tsx
|
|
7
6
|
import { createContext, useContext } from "react";
|
|
8
|
-
var
|
|
9
|
-
function
|
|
10
|
-
const context = useContext(
|
|
7
|
+
var FrontXContext = createContext(null);
|
|
8
|
+
function useFrontX() {
|
|
9
|
+
const context = useContext(FrontXContext);
|
|
11
10
|
if (!context) {
|
|
12
11
|
throw new Error(
|
|
13
|
-
"
|
|
12
|
+
"useFrontX must be used within a FrontXProvider. Wrap your application with <FrontXProvider> to access Gears FrontX features."
|
|
14
13
|
);
|
|
15
14
|
}
|
|
16
15
|
return context;
|
|
@@ -35,34 +34,644 @@ var MfeProvider = ({ value, children }) => {
|
|
|
35
34
|
return /* @__PURE__ */ jsx(MfeContext.Provider, { value, children });
|
|
36
35
|
};
|
|
37
36
|
|
|
38
|
-
// src/
|
|
39
|
-
import {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
// src/queryClient.tsx
|
|
38
|
+
import React, {
|
|
39
|
+
createContext as createContext3,
|
|
40
|
+
useContext as useContext3,
|
|
41
|
+
useEffect as useEffect2,
|
|
42
|
+
useLayoutEffect,
|
|
43
|
+
useMemo,
|
|
44
|
+
useState
|
|
45
|
+
} from "react";
|
|
46
|
+
import {
|
|
47
|
+
QueryClientContext,
|
|
48
|
+
QueryClientProvider,
|
|
49
|
+
useInfiniteQuery,
|
|
50
|
+
useMutation,
|
|
51
|
+
useQuery,
|
|
52
|
+
useSuspenseInfiniteQuery,
|
|
53
|
+
useSuspenseQuery
|
|
54
|
+
} from "@tanstack/react-query";
|
|
55
|
+
import {
|
|
56
|
+
readQueryCacheScopeGeneration,
|
|
57
|
+
recordQueryCacheScopeWriteDropped,
|
|
58
|
+
subscribeQueryCacheRuntimeChanged
|
|
59
|
+
} from "@gears-frontx/framework";
|
|
60
|
+
|
|
61
|
+
// src/hooks/QueryCache.ts
|
|
62
|
+
import { eventBus } from "@gears-frontx/framework";
|
|
63
|
+
var QUERY_CLIENT_BROADCAST_TARGET = /* @__PURE__ */ Symbol.for("frontx:query-cache:broadcast-target");
|
|
64
|
+
var QUERY_CLIENT_BROADCAST_COUNTER = /* @__PURE__ */ Symbol.for("frontx:query-cache:broadcast-counter");
|
|
65
|
+
function emitCacheEvent(event, payload) {
|
|
66
|
+
eventBus.emit(event, payload);
|
|
67
|
+
}
|
|
68
|
+
function ensureBroadcastSource(queryClient) {
|
|
69
|
+
const clientWithMetadata = queryClient;
|
|
70
|
+
const existingSource = clientWithMetadata[QUERY_CLIENT_BROADCAST_TARGET];
|
|
71
|
+
if (typeof existingSource === "string" && existingSource.length > 0) {
|
|
72
|
+
return existingSource;
|
|
73
|
+
}
|
|
74
|
+
const host = globalThis;
|
|
75
|
+
const nextCounter = (host[QUERY_CLIENT_BROADCAST_COUNTER] ?? 0) + 1;
|
|
76
|
+
host[QUERY_CLIENT_BROADCAST_COUNTER] = nextCounter;
|
|
77
|
+
const source = `query-cache-${nextCounter}`;
|
|
78
|
+
clientWithMetadata[QUERY_CLIENT_BROADCAST_TARGET] = source;
|
|
79
|
+
return source;
|
|
80
|
+
}
|
|
81
|
+
function resolveKey(target) {
|
|
82
|
+
if (target !== null && typeof target === "object" && !Array.isArray(target) && "key" in target && "fetch" in target && Array.isArray(target.key) && typeof target.fetch === "function") {
|
|
83
|
+
return target.key;
|
|
84
|
+
}
|
|
85
|
+
return target;
|
|
86
|
+
}
|
|
87
|
+
function toQueryUpdater(dataOrUpdater) {
|
|
88
|
+
if (typeof dataOrUpdater === "function") {
|
|
89
|
+
return dataOrUpdater;
|
|
90
|
+
}
|
|
91
|
+
return () => dataOrUpdater;
|
|
92
|
+
}
|
|
93
|
+
function mapQueryState(state) {
|
|
94
|
+
return {
|
|
95
|
+
data: state.data,
|
|
96
|
+
dataUpdatedAt: state.dataUpdatedAt,
|
|
97
|
+
error: state.error,
|
|
98
|
+
errorUpdatedAt: state.errorUpdatedAt,
|
|
99
|
+
fetchFailureCount: state.fetchFailureCount,
|
|
100
|
+
fetchFailureReason: state.fetchFailureReason,
|
|
101
|
+
fetchStatus: state.fetchStatus,
|
|
102
|
+
isInvalidated: state.isInvalidated,
|
|
103
|
+
status: state.status
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function createQueryCache(queryClient) {
|
|
107
|
+
return {
|
|
108
|
+
get: (key) => {
|
|
109
|
+
return queryClient.getQueryData(resolveKey(key));
|
|
110
|
+
},
|
|
111
|
+
getState: (key) => {
|
|
112
|
+
const state = queryClient.getQueryState(resolveKey(key));
|
|
113
|
+
return state ? mapQueryState(state) : void 0;
|
|
114
|
+
},
|
|
115
|
+
set: (key, dataOrUpdater) => {
|
|
116
|
+
const resolvedKey = resolveKey(key);
|
|
117
|
+
queryClient.setQueryData(resolvedKey, toQueryUpdater(dataOrUpdater));
|
|
118
|
+
emitCacheEvent("cache/set", {
|
|
119
|
+
queryKey: resolvedKey,
|
|
120
|
+
dataOrUpdater,
|
|
121
|
+
source: ensureBroadcastSource(queryClient)
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
cancel: (key) => {
|
|
125
|
+
return queryClient.cancelQueries({ queryKey: resolveKey(key) });
|
|
126
|
+
},
|
|
127
|
+
invalidate: (key) => {
|
|
128
|
+
const resolvedKey = resolveKey(key);
|
|
129
|
+
const result = queryClient.invalidateQueries({ queryKey: resolvedKey });
|
|
130
|
+
emitCacheEvent("cache/invalidate", {
|
|
131
|
+
queryKey: resolvedKey,
|
|
132
|
+
source: ensureBroadcastSource(queryClient)
|
|
133
|
+
});
|
|
134
|
+
return result;
|
|
135
|
+
},
|
|
136
|
+
invalidateMany: (filters) => {
|
|
137
|
+
if (filters?.queryKey == null) {
|
|
138
|
+
return Promise.resolve();
|
|
139
|
+
}
|
|
140
|
+
const resolvedKey = resolveKey(filters.queryKey);
|
|
141
|
+
if (!Array.isArray(resolvedKey) || resolvedKey.length === 0) {
|
|
142
|
+
return Promise.resolve();
|
|
143
|
+
}
|
|
144
|
+
const payload = {
|
|
145
|
+
...filters,
|
|
146
|
+
queryKey: resolvedKey
|
|
147
|
+
};
|
|
148
|
+
const result = queryClient.invalidateQueries(payload);
|
|
149
|
+
emitCacheEvent("cache/invalidate", {
|
|
150
|
+
...payload,
|
|
151
|
+
source: ensureBroadcastSource(queryClient)
|
|
152
|
+
});
|
|
153
|
+
return result;
|
|
154
|
+
},
|
|
155
|
+
remove: (key) => {
|
|
156
|
+
const resolvedKey = resolveKey(key);
|
|
157
|
+
queryClient.removeQueries({ queryKey: resolvedKey });
|
|
158
|
+
emitCacheEvent("cache/remove", {
|
|
159
|
+
queryKey: resolvedKey,
|
|
160
|
+
source: ensureBroadcastSource(queryClient)
|
|
161
|
+
});
|
|
49
162
|
}
|
|
50
|
-
|
|
51
|
-
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/hooks/useLatest.ts
|
|
167
|
+
import { useEffect, useRef } from "react";
|
|
168
|
+
function useLatest(value) {
|
|
169
|
+
const ref = useRef(value);
|
|
52
170
|
useEffect(() => {
|
|
171
|
+
ref.current = value;
|
|
172
|
+
});
|
|
173
|
+
return ref;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/queryClient.tsx
|
|
177
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
178
|
+
var APP_QUERY_CLIENT_SYMBOL = /* @__PURE__ */ Symbol.for("frontx:query-cache:app-client");
|
|
179
|
+
var APP_QUERY_CLIENT_RESOLVER_SYMBOL = /* @__PURE__ */ Symbol.for("frontx:query-cache:app-client-resolver");
|
|
180
|
+
var APP_QUERY_CLIENT_ACTIVATOR_SYMBOL = /* @__PURE__ */ Symbol.for("frontx:query-cache:app-client-activator");
|
|
181
|
+
var FrontXQueryClientContext = createContext3(void 0);
|
|
182
|
+
var useCommitEffect = typeof globalThis.window === "undefined" ? useEffect2 : useLayoutEffect;
|
|
183
|
+
function resolveFrontXQueryClient(app) {
|
|
184
|
+
const clientApp = app;
|
|
185
|
+
return clientApp[APP_QUERY_CLIENT_SYMBOL] ?? clientApp[APP_QUERY_CLIENT_RESOLVER_SYMBOL]?.();
|
|
186
|
+
}
|
|
187
|
+
function hasFrontXQueryClientActivator(app) {
|
|
188
|
+
return typeof app[APP_QUERY_CLIENT_ACTIVATOR_SYMBOL] === "function";
|
|
189
|
+
}
|
|
190
|
+
function activateFrontXQueryClient(app) {
|
|
191
|
+
const clientApp = app;
|
|
192
|
+
return clientApp[APP_QUERY_CLIENT_SYMBOL] ?? clientApp[APP_QUERY_CLIENT_ACTIVATOR_SYMBOL]?.();
|
|
193
|
+
}
|
|
194
|
+
async function invalidateQueryCacheForApp(app, target) {
|
|
195
|
+
const queryClient = resolveFrontXQueryClient(app) ?? activateFrontXQueryClient(app);
|
|
196
|
+
if (!queryClient) {
|
|
197
|
+
throw new Error(
|
|
198
|
+
"[invalidateQueryCacheForApp] No QueryClient on app. Ensure queryCache() or queryCacheShared() is in the plugin chain."
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
await createQueryCache(queryClient).invalidate(target);
|
|
202
|
+
}
|
|
203
|
+
function bootstrapFrontXQueryClient(app) {
|
|
204
|
+
return resolveFrontXQueryClient(app);
|
|
205
|
+
}
|
|
206
|
+
function useBootstrappedFrontXQueryClient(app) {
|
|
207
|
+
const fromApp = useMemo(() => bootstrapFrontXQueryClient(app), [app]);
|
|
208
|
+
const [eventResolvedClient, setEventResolvedClient] = useState(
|
|
209
|
+
void 0
|
|
210
|
+
);
|
|
211
|
+
const queryClient = fromApp ?? (eventResolvedClient?.app === app ? eventResolvedClient.queryClient : void 0);
|
|
212
|
+
useCommitEffect(() => {
|
|
213
|
+
if (fromApp || !hasFrontXQueryClientActivator(app)) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const tryResolveQueryClient = () => {
|
|
217
|
+
const nextQueryClient = resolveFrontXQueryClient(app) ?? activateFrontXQueryClient(app);
|
|
218
|
+
if (nextQueryClient) {
|
|
219
|
+
setEventResolvedClient((current) => {
|
|
220
|
+
if (current?.app === app && current.queryClient === nextQueryClient) {
|
|
221
|
+
return current;
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
app,
|
|
225
|
+
queryClient: nextQueryClient
|
|
226
|
+
};
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
tryResolveQueryClient();
|
|
231
|
+
const subscription = subscribeQueryCacheRuntimeChanged(() => {
|
|
232
|
+
tryResolveQueryClient();
|
|
233
|
+
});
|
|
234
|
+
return () => {
|
|
235
|
+
subscription.unsubscribe();
|
|
236
|
+
};
|
|
237
|
+
}, [app, fromApp]);
|
|
238
|
+
return queryClient;
|
|
239
|
+
}
|
|
240
|
+
function FrontXQueryClientProvider({
|
|
241
|
+
queryClient,
|
|
242
|
+
children
|
|
243
|
+
}) {
|
|
244
|
+
if (!queryClient) {
|
|
245
|
+
return /* @__PURE__ */ jsx2(FrontXQueryClientContext.Provider, { value: void 0, children: /* @__PURE__ */ jsx2(QueryClientContext.Provider, { value: void 0, children }) });
|
|
246
|
+
}
|
|
247
|
+
return /* @__PURE__ */ jsx2(FrontXQueryClientContext.Provider, { value: queryClient, children: /* @__PURE__ */ jsx2(QueryClientProvider, { client: queryClient, children }) });
|
|
248
|
+
}
|
|
249
|
+
function useOptionalFrontXQueryClient() {
|
|
250
|
+
return useContext3(FrontXQueryClientContext);
|
|
251
|
+
}
|
|
252
|
+
function useRequiredFrontXQueryClient() {
|
|
253
|
+
const queryClient = useOptionalFrontXQueryClient();
|
|
254
|
+
if (!queryClient) {
|
|
255
|
+
throw new Error(
|
|
256
|
+
"[FrontXProvider] No query cache available. Add queryCache() or queryCacheShared() to your plugin composition."
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
return queryClient;
|
|
260
|
+
}
|
|
261
|
+
function buildPageContext(page, pages, descriptor, descriptors) {
|
|
262
|
+
return {
|
|
263
|
+
page,
|
|
264
|
+
pages,
|
|
265
|
+
descriptor,
|
|
266
|
+
descriptors
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
function normalizeFetchStaleTime(staleTime) {
|
|
270
|
+
if (staleTime === "static") {
|
|
271
|
+
return Number.POSITIVE_INFINITY;
|
|
272
|
+
}
|
|
273
|
+
if (typeof staleTime === "function") {
|
|
274
|
+
return 0;
|
|
275
|
+
}
|
|
276
|
+
return typeof staleTime === "number" ? staleTime : void 0;
|
|
277
|
+
}
|
|
278
|
+
function resolveFetchStaleTime(queryClient, queryKey, descriptor, overrideStaleTime) {
|
|
279
|
+
const clientDefaults = {
|
|
280
|
+
...queryClient.getDefaultOptions().queries,
|
|
281
|
+
...queryClient.getQueryDefaults(queryKey)
|
|
282
|
+
};
|
|
283
|
+
return normalizeFetchStaleTime(
|
|
284
|
+
overrideStaleTime ?? descriptor.staleTime ?? clientDefaults.staleTime
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
function cacheTimeOptions(staleTime, gcTime) {
|
|
288
|
+
return {
|
|
289
|
+
...staleTime === void 0 ? {} : { staleTime },
|
|
290
|
+
...gcTime === void 0 ? {} : { gcTime }
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function fetchDescriptor(descriptor, options) {
|
|
294
|
+
return descriptor.fetch(options);
|
|
295
|
+
}
|
|
296
|
+
function useFrontXQuery(descriptor, overrides) {
|
|
297
|
+
const queryClient = useRequiredFrontXQueryClient();
|
|
298
|
+
const staleTime = resolveFetchStaleTime(
|
|
299
|
+
queryClient,
|
|
300
|
+
descriptor.key,
|
|
301
|
+
descriptor,
|
|
302
|
+
overrides?.staleTime
|
|
303
|
+
);
|
|
304
|
+
const result = useQuery({
|
|
305
|
+
queryKey: descriptor.key,
|
|
306
|
+
queryFn: ({ signal }) => fetchDescriptor(descriptor, { signal, staleTime }),
|
|
307
|
+
...cacheTimeOptions(
|
|
308
|
+
overrides?.staleTime ?? descriptor.staleTime,
|
|
309
|
+
overrides?.gcTime ?? descriptor.gcTime
|
|
310
|
+
),
|
|
311
|
+
...overrides?.enabled === void 0 ? {} : { enabled: overrides.enabled }
|
|
312
|
+
});
|
|
313
|
+
return {
|
|
314
|
+
data: result.data,
|
|
315
|
+
error: result.error,
|
|
316
|
+
isLoading: result.isLoading,
|
|
317
|
+
isFetching: result.isFetching,
|
|
318
|
+
isError: result.isError,
|
|
319
|
+
refetch: result.refetch
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
function useFrontXSuspenseQuery(descriptor, overrides) {
|
|
323
|
+
const queryClient = useRequiredFrontXQueryClient();
|
|
324
|
+
const staleTime = resolveFetchStaleTime(
|
|
325
|
+
queryClient,
|
|
326
|
+
descriptor.key,
|
|
327
|
+
descriptor,
|
|
328
|
+
overrides?.staleTime
|
|
329
|
+
);
|
|
330
|
+
const result = useSuspenseQuery({
|
|
331
|
+
queryKey: descriptor.key,
|
|
332
|
+
queryFn: ({ signal }) => fetchDescriptor(descriptor, { signal, staleTime }),
|
|
333
|
+
...cacheTimeOptions(
|
|
334
|
+
overrides?.staleTime ?? descriptor.staleTime,
|
|
335
|
+
overrides?.gcTime ?? descriptor.gcTime
|
|
336
|
+
)
|
|
337
|
+
});
|
|
338
|
+
return {
|
|
339
|
+
data: result.data,
|
|
340
|
+
error: result.error,
|
|
341
|
+
isFetching: result.isFetching,
|
|
342
|
+
refetch: async () => {
|
|
343
|
+
await result.refetch();
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
function useFrontXInfiniteQuery(options) {
|
|
348
|
+
const queryClient = useRequiredFrontXQueryClient();
|
|
349
|
+
const result = useInfiniteQuery({
|
|
350
|
+
queryKey: options.initialPage.key,
|
|
351
|
+
initialPageParam: options.initialPage,
|
|
352
|
+
queryFn: ({ pageParam, signal }) => fetchDescriptor(pageParam, {
|
|
353
|
+
signal,
|
|
354
|
+
staleTime: resolveFetchStaleTime(
|
|
355
|
+
queryClient,
|
|
356
|
+
options.initialPage.key,
|
|
357
|
+
pageParam,
|
|
358
|
+
options.staleTime
|
|
359
|
+
)
|
|
360
|
+
}),
|
|
361
|
+
getNextPageParam: (lastPage, allPages, lastPageDescriptor, allPageDescriptors) => options.getNextPage(
|
|
362
|
+
buildPageContext(
|
|
363
|
+
lastPage,
|
|
364
|
+
allPages,
|
|
365
|
+
lastPageDescriptor,
|
|
366
|
+
allPageDescriptors
|
|
367
|
+
)
|
|
368
|
+
),
|
|
369
|
+
getPreviousPageParam: options.getPreviousPage ? (firstPage, allPages, firstPageDescriptor, allPageDescriptors) => options.getPreviousPage?.(
|
|
370
|
+
buildPageContext(
|
|
371
|
+
firstPage,
|
|
372
|
+
allPages,
|
|
373
|
+
firstPageDescriptor,
|
|
374
|
+
allPageDescriptors
|
|
375
|
+
)
|
|
376
|
+
) : void 0,
|
|
377
|
+
select: (data) => data.pages,
|
|
378
|
+
...cacheTimeOptions(
|
|
379
|
+
options.staleTime ?? options.initialPage.staleTime,
|
|
380
|
+
options.gcTime ?? options.initialPage.gcTime
|
|
381
|
+
),
|
|
382
|
+
maxPages: options.maxPages,
|
|
383
|
+
...options.enabled === void 0 ? {} : { enabled: options.enabled }
|
|
384
|
+
});
|
|
385
|
+
return {
|
|
386
|
+
data: result.data,
|
|
387
|
+
error: result.error,
|
|
388
|
+
isLoading: result.isLoading,
|
|
389
|
+
isFetching: result.isFetching,
|
|
390
|
+
isError: result.isError,
|
|
391
|
+
hasNextPage: result.hasNextPage ?? false,
|
|
392
|
+
hasPreviousPage: result.hasPreviousPage ?? false,
|
|
393
|
+
isFetchingNextPage: result.isFetchingNextPage,
|
|
394
|
+
isFetchingPreviousPage: result.isFetchingPreviousPage,
|
|
395
|
+
fetchNextPage: async () => {
|
|
396
|
+
await result.fetchNextPage();
|
|
397
|
+
},
|
|
398
|
+
fetchPreviousPage: async () => {
|
|
399
|
+
await result.fetchPreviousPage();
|
|
400
|
+
},
|
|
401
|
+
refetch: async () => {
|
|
402
|
+
await result.refetch();
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
function useFrontXSuspenseInfiniteQuery(options) {
|
|
407
|
+
const queryClient = useRequiredFrontXQueryClient();
|
|
408
|
+
const result = useSuspenseInfiniteQuery({
|
|
409
|
+
queryKey: options.initialPage.key,
|
|
410
|
+
initialPageParam: options.initialPage,
|
|
411
|
+
queryFn: ({ pageParam, signal }) => fetchDescriptor(pageParam, {
|
|
412
|
+
signal,
|
|
413
|
+
staleTime: resolveFetchStaleTime(
|
|
414
|
+
queryClient,
|
|
415
|
+
options.initialPage.key,
|
|
416
|
+
pageParam,
|
|
417
|
+
options.staleTime
|
|
418
|
+
)
|
|
419
|
+
}),
|
|
420
|
+
getNextPageParam: (lastPage, allPages, lastPageDescriptor, allPageDescriptors) => options.getNextPage(
|
|
421
|
+
buildPageContext(
|
|
422
|
+
lastPage,
|
|
423
|
+
allPages,
|
|
424
|
+
lastPageDescriptor,
|
|
425
|
+
allPageDescriptors
|
|
426
|
+
)
|
|
427
|
+
),
|
|
428
|
+
getPreviousPageParam: options.getPreviousPage ? (firstPage, allPages, firstPageDescriptor, allPageDescriptors) => options.getPreviousPage?.(
|
|
429
|
+
buildPageContext(
|
|
430
|
+
firstPage,
|
|
431
|
+
allPages,
|
|
432
|
+
firstPageDescriptor,
|
|
433
|
+
allPageDescriptors
|
|
434
|
+
)
|
|
435
|
+
) : void 0,
|
|
436
|
+
select: (data) => data.pages,
|
|
437
|
+
...cacheTimeOptions(
|
|
438
|
+
options.staleTime ?? options.initialPage.staleTime,
|
|
439
|
+
options.gcTime ?? options.initialPage.gcTime
|
|
440
|
+
),
|
|
441
|
+
maxPages: options.maxPages
|
|
442
|
+
});
|
|
443
|
+
return {
|
|
444
|
+
data: result.data,
|
|
445
|
+
error: result.error,
|
|
446
|
+
isFetching: result.isFetching,
|
|
447
|
+
hasNextPage: result.hasNextPage ?? false,
|
|
448
|
+
hasPreviousPage: result.hasPreviousPage ?? false,
|
|
449
|
+
isFetchingNextPage: result.isFetchingNextPage,
|
|
450
|
+
isFetchingPreviousPage: result.isFetchingPreviousPage,
|
|
451
|
+
fetchNextPage: async () => {
|
|
452
|
+
await result.fetchNextPage();
|
|
453
|
+
},
|
|
454
|
+
fetchPreviousPage: async () => {
|
|
455
|
+
await result.fetchPreviousPage();
|
|
456
|
+
},
|
|
457
|
+
refetch: async () => {
|
|
458
|
+
await result.refetch();
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
var mutationScopes = /* @__PURE__ */ new WeakMap();
|
|
463
|
+
function scopeBoundQueryCache(queryCache2, scope) {
|
|
464
|
+
const scopeChanged = () => readQueryCacheScopeGeneration(scope.queryClient) !== scope.generation;
|
|
465
|
+
const dropped = () => {
|
|
466
|
+
if (!scopeChanged()) return false;
|
|
467
|
+
recordQueryCacheScopeWriteDropped(scope.queryClient, scope.generation);
|
|
468
|
+
return true;
|
|
469
|
+
};
|
|
470
|
+
return {
|
|
471
|
+
get: queryCache2.get,
|
|
472
|
+
getState: queryCache2.getState,
|
|
473
|
+
set: (key, dataOrUpdater) => {
|
|
474
|
+
if (!dropped()) queryCache2.set(key, dataOrUpdater);
|
|
475
|
+
},
|
|
476
|
+
cancel: (key) => scopeChanged() ? Promise.resolve() : queryCache2.cancel(key),
|
|
477
|
+
invalidate: (key) => dropped() ? Promise.resolve() : queryCache2.invalidate(key),
|
|
478
|
+
invalidateMany: (filters) => dropped() ? Promise.resolve() : queryCache2.invalidateMany(filters),
|
|
479
|
+
remove: (key) => {
|
|
480
|
+
if (!dropped()) queryCache2.remove(key);
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
function scopeBoundCallbackCtx(callbackCtx, scope) {
|
|
485
|
+
return scope ? { queryCache: scopeBoundQueryCache(createQueryCache(scope.queryClient), scope) } : callbackCtx;
|
|
486
|
+
}
|
|
487
|
+
function useFrontXMutation(options, callbackCtx) {
|
|
488
|
+
const queryClient = useRequiredFrontXQueryClient();
|
|
489
|
+
const latestRef = useLatest({ options, callbackCtx, queryClient });
|
|
490
|
+
const fetchAbortControllersRef = React.useRef(/* @__PURE__ */ new Set());
|
|
491
|
+
const abortFetchesOnUnmount = React.useEffectEvent(() => {
|
|
492
|
+
if (options.abortOnUnmount) {
|
|
493
|
+
for (const controller of fetchAbortControllersRef.current) {
|
|
494
|
+
controller.abort();
|
|
495
|
+
}
|
|
496
|
+
fetchAbortControllersRef.current.clear();
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
React.useEffect(() => {
|
|
53
500
|
return () => {
|
|
54
|
-
|
|
55
|
-
|
|
501
|
+
abortFetchesOnUnmount();
|
|
502
|
+
};
|
|
503
|
+
}, []);
|
|
504
|
+
const mutationFn = React.useCallback((variables, context) => {
|
|
505
|
+
const cancelOnSupersede = latestRef.current.options.cancelOnSupersede;
|
|
506
|
+
if (cancelOnSupersede) {
|
|
507
|
+
for (const controller2 of fetchAbortControllersRef.current) {
|
|
508
|
+
controller2.abort();
|
|
509
|
+
}
|
|
510
|
+
fetchAbortControllersRef.current.clear();
|
|
511
|
+
}
|
|
512
|
+
const controller = new AbortController();
|
|
513
|
+
fetchAbortControllersRef.current.add(controller);
|
|
514
|
+
const librarySignal = context.signal;
|
|
515
|
+
if (cancelOnSupersede && librarySignal) {
|
|
516
|
+
if (librarySignal.aborted) {
|
|
517
|
+
controller.abort();
|
|
518
|
+
} else {
|
|
519
|
+
librarySignal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
56
520
|
}
|
|
521
|
+
}
|
|
522
|
+
return latestRef.current.options.endpoint.fetch(variables, { signal: controller.signal }).finally(() => {
|
|
523
|
+
fetchAbortControllersRef.current.delete(controller);
|
|
524
|
+
});
|
|
525
|
+
}, [latestRef]);
|
|
526
|
+
const onMutate = React.useCallback(async (variables, mutationFnContext) => {
|
|
527
|
+
const current = latestRef.current;
|
|
528
|
+
const scope = {
|
|
529
|
+
queryClient: current.queryClient,
|
|
530
|
+
generation: readQueryCacheScopeGeneration(current.queryClient)
|
|
57
531
|
};
|
|
58
|
-
|
|
59
|
-
|
|
532
|
+
mutationScopes.set(mutationFnContext, scope);
|
|
533
|
+
return current.options.onMutate?.(
|
|
534
|
+
variables,
|
|
535
|
+
scopeBoundCallbackCtx(current.callbackCtx, scope)
|
|
536
|
+
);
|
|
537
|
+
}, [latestRef]);
|
|
538
|
+
const onSuccess = React.useCallback((data, variables, context, mutationFnContext) => {
|
|
539
|
+
const current = latestRef.current;
|
|
540
|
+
return current.options.onSuccess?.(
|
|
541
|
+
data,
|
|
542
|
+
variables,
|
|
543
|
+
context,
|
|
544
|
+
scopeBoundCallbackCtx(current.callbackCtx, mutationScopes.get(mutationFnContext))
|
|
545
|
+
);
|
|
546
|
+
}, [latestRef]);
|
|
547
|
+
const onError = React.useCallback((error, variables, context, mutationFnContext) => {
|
|
548
|
+
const current = latestRef.current;
|
|
549
|
+
return current.options.onError?.(
|
|
550
|
+
error,
|
|
551
|
+
variables,
|
|
552
|
+
context,
|
|
553
|
+
scopeBoundCallbackCtx(current.callbackCtx, mutationScopes.get(mutationFnContext))
|
|
554
|
+
);
|
|
555
|
+
}, [latestRef]);
|
|
556
|
+
const onSettled = React.useCallback((data, error, variables, context, mutationFnContext) => {
|
|
557
|
+
const current = latestRef.current;
|
|
558
|
+
return current.options.onSettled?.(
|
|
559
|
+
data,
|
|
560
|
+
error,
|
|
561
|
+
variables,
|
|
562
|
+
context,
|
|
563
|
+
scopeBoundCallbackCtx(current.callbackCtx, mutationScopes.get(mutationFnContext))
|
|
564
|
+
);
|
|
565
|
+
}, [latestRef]);
|
|
566
|
+
const mutation = useMutation({
|
|
567
|
+
mutationFn,
|
|
568
|
+
onMutate,
|
|
569
|
+
onSuccess: options.onSuccess ? onSuccess : void 0,
|
|
570
|
+
onError: options.onError ? onError : void 0,
|
|
571
|
+
onSettled: options.onSettled ? onSettled : void 0
|
|
572
|
+
});
|
|
573
|
+
return {
|
|
574
|
+
mutate: mutation.mutate,
|
|
575
|
+
mutateAsync: mutation.mutateAsync,
|
|
576
|
+
isPending: mutation.isPending,
|
|
577
|
+
error: mutation.error,
|
|
578
|
+
data: mutation.data,
|
|
579
|
+
reset: mutation.reset
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// src/FrontXProvider.tsx
|
|
584
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
585
|
+
var FrontXProvider = ({
|
|
586
|
+
children,
|
|
587
|
+
app,
|
|
588
|
+
mfeBridge
|
|
589
|
+
}) => {
|
|
590
|
+
const queryClient = useBootstrappedFrontXQueryClient(app);
|
|
591
|
+
const deferQuerySubtree = hasFrontXQueryClientActivator(app) && queryClient === void 0;
|
|
592
|
+
useEffect3(() => {
|
|
593
|
+
if (queryClient || hasFrontXQueryClientActivator(app) || process.env.NODE_ENV === "production" || process.env.NODE_ENV === "test" || process.env.VITEST === "true") {
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
console.warn(
|
|
597
|
+
"[FrontXProvider] No query cache available. Add queryCache() or queryCacheShared() to your plugin composition. useApiQuery/useApiMutation will fail without it."
|
|
598
|
+
);
|
|
599
|
+
}, [app, queryClient]);
|
|
600
|
+
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
601
|
if (mfeBridge) {
|
|
61
|
-
return /* @__PURE__ */
|
|
602
|
+
return /* @__PURE__ */ jsx3(MfeProvider, { value: mfeBridge, children: content });
|
|
62
603
|
}
|
|
63
604
|
return content;
|
|
64
605
|
};
|
|
65
606
|
|
|
607
|
+
// src/hooks/useCanAccess.ts
|
|
608
|
+
import { useEffect as useEffect4, useState as useState2 } from "react";
|
|
609
|
+
function serializeRecordValue(value) {
|
|
610
|
+
if (value === null) return "n:";
|
|
611
|
+
if (typeof value === "string") return `s:${value}`;
|
|
612
|
+
if (typeof value === "number") {
|
|
613
|
+
return `d:${Object.is(value, -0) ? "-0" : String(value)}`;
|
|
614
|
+
}
|
|
615
|
+
return value ? "b:1" : "b:0";
|
|
616
|
+
}
|
|
617
|
+
function accessQueryKey(query) {
|
|
618
|
+
const { action, resource, record } = query;
|
|
619
|
+
const normalizedRecord = record ? Object.entries(record).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => [k, serializeRecordValue(v)]) : null;
|
|
620
|
+
return JSON.stringify([action, resource, normalizedRecord]);
|
|
621
|
+
}
|
|
622
|
+
function getAuthRuntime(app) {
|
|
623
|
+
return app.auth ?? null;
|
|
624
|
+
}
|
|
625
|
+
var DENIED_NO_AUTH = { allow: false, isResolving: false };
|
|
626
|
+
function useCanAccess(query) {
|
|
627
|
+
const app = useFrontX();
|
|
628
|
+
const auth2 = getAuthRuntime(app);
|
|
629
|
+
const stableKey = accessQueryKey(query);
|
|
630
|
+
const [stableQuery, setStableQuery] = useState2(() => query);
|
|
631
|
+
const [runState, setRunState] = useState2({ auth: auth2, stableKey });
|
|
632
|
+
const [result, setResult] = useState2({ allow: false, isResolving: true });
|
|
633
|
+
if (runState.auth !== auth2 || runState.stableKey !== stableKey) {
|
|
634
|
+
setRunState({ auth: auth2, stableKey });
|
|
635
|
+
setStableQuery(query);
|
|
636
|
+
setResult({ allow: false, isResolving: true });
|
|
637
|
+
}
|
|
638
|
+
useEffect4(() => {
|
|
639
|
+
if (!auth2) {
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
let alive = true;
|
|
643
|
+
const controller = new AbortController();
|
|
644
|
+
void auth2.canAccess(stableQuery, { signal: controller.signal }).then((decision) => {
|
|
645
|
+
if (alive) {
|
|
646
|
+
setResult({ allow: decision === "allow", isResolving: false });
|
|
647
|
+
}
|
|
648
|
+
}).catch(() => {
|
|
649
|
+
if (alive) {
|
|
650
|
+
setResult({ allow: false, isResolving: false });
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
return () => {
|
|
654
|
+
alive = false;
|
|
655
|
+
controller.abort();
|
|
656
|
+
};
|
|
657
|
+
}, [auth2, stableQuery]);
|
|
658
|
+
return auth2 ? result : DENIED_NO_AUTH;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// src/components/CanAccess.tsx
|
|
662
|
+
function CanAccess({
|
|
663
|
+
query,
|
|
664
|
+
allowed,
|
|
665
|
+
denied = null,
|
|
666
|
+
loading
|
|
667
|
+
}) {
|
|
668
|
+
const { allow, isResolving } = useCanAccess(query);
|
|
669
|
+
if (isResolving) {
|
|
670
|
+
return loading !== void 0 ? loading : denied;
|
|
671
|
+
}
|
|
672
|
+
return allow ? allowed : denied;
|
|
673
|
+
}
|
|
674
|
+
|
|
66
675
|
// src/hooks/useAppDispatch.ts
|
|
67
676
|
import { useDispatch } from "react-redux";
|
|
68
677
|
function useAppDispatch() {
|
|
@@ -76,7 +685,7 @@ var useAppSelector = useSelector;
|
|
|
76
685
|
// src/hooks/useTranslation.ts
|
|
77
686
|
import { useMemo as useMemo2, useCallback, useSyncExternalStore } from "react";
|
|
78
687
|
function useTranslation() {
|
|
79
|
-
const app =
|
|
688
|
+
const app = useFrontX();
|
|
80
689
|
const { i18nRegistry: i18nRegistry2 } = app;
|
|
81
690
|
const version = useSyncExternalStore(
|
|
82
691
|
useCallback(
|
|
@@ -119,16 +728,15 @@ function useTranslation() {
|
|
|
119
728
|
}
|
|
120
729
|
|
|
121
730
|
// src/hooks/useScreenTranslations.ts
|
|
122
|
-
import { useState, useEffect as
|
|
731
|
+
import { useState as useState3, useEffect as useEffect5, useMemo as useMemo3, useCallback as useCallback2, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
123
732
|
function isTranslationLoader(input) {
|
|
124
733
|
return typeof input === "function";
|
|
125
734
|
}
|
|
126
735
|
function useScreenTranslations(screensetId, screenId, translations) {
|
|
127
|
-
const app =
|
|
736
|
+
const app = useFrontX();
|
|
128
737
|
const { i18nRegistry: i18nRegistry2 } = app;
|
|
129
|
-
const [loadedLanguage, setLoadedLanguage] =
|
|
130
|
-
const [
|
|
131
|
-
const [error, setError] = useState(null);
|
|
738
|
+
const [loadedLanguage, setLoadedLanguage] = useState3(null);
|
|
739
|
+
const [error, setError] = useState3(null);
|
|
132
740
|
const version = useSyncExternalStore2(
|
|
133
741
|
useCallback2(
|
|
134
742
|
(callback) => i18nRegistry2.subscribe(callback),
|
|
@@ -154,12 +762,11 @@ function useScreenTranslations(screensetId, screenId, translations) {
|
|
|
154
762
|
return module.default;
|
|
155
763
|
};
|
|
156
764
|
}, [translations]);
|
|
157
|
-
|
|
765
|
+
useEffect5(() => {
|
|
158
766
|
if (!currentLanguage || currentLanguage === loadedLanguage) {
|
|
159
767
|
return;
|
|
160
768
|
}
|
|
161
769
|
let cancelled = false;
|
|
162
|
-
setIsLoading(true);
|
|
163
770
|
const loadTranslations = async () => {
|
|
164
771
|
try {
|
|
165
772
|
const namespace = `screen.${screensetId}.${screenId}`;
|
|
@@ -168,13 +775,11 @@ function useScreenTranslations(screensetId, screenId, translations) {
|
|
|
168
775
|
i18nRegistry2.register(namespace, currentLanguage, loadedTranslations);
|
|
169
776
|
if (!cancelled) {
|
|
170
777
|
setLoadedLanguage(currentLanguage);
|
|
171
|
-
setIsLoading(false);
|
|
172
778
|
setError(null);
|
|
173
779
|
}
|
|
174
780
|
} catch (err) {
|
|
175
781
|
if (!cancelled) {
|
|
176
782
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
177
|
-
setIsLoading(false);
|
|
178
783
|
}
|
|
179
784
|
}
|
|
180
785
|
};
|
|
@@ -183,7 +788,7 @@ function useScreenTranslations(screensetId, screenId, translations) {
|
|
|
183
788
|
cancelled = true;
|
|
184
789
|
};
|
|
185
790
|
}, [screensetId, screenId, loader, i18nRegistry2, currentLanguage, loadedLanguage]);
|
|
186
|
-
const isLoaded = currentLanguage !== null && currentLanguage === loadedLanguage
|
|
791
|
+
const isLoaded = currentLanguage !== null && currentLanguage === loadedLanguage;
|
|
187
792
|
return { isLoaded, error };
|
|
188
793
|
}
|
|
189
794
|
|
|
@@ -226,7 +831,7 @@ function useFormatters() {
|
|
|
226
831
|
// src/hooks/useTheme.ts
|
|
227
832
|
import { useCallback as useCallback3, useMemo as useMemo5, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
228
833
|
function useTheme() {
|
|
229
|
-
const app =
|
|
834
|
+
const app = useFrontX();
|
|
230
835
|
const { themeRegistry } = app;
|
|
231
836
|
const version = useSyncExternalStore3(
|
|
232
837
|
useCallback3(
|
|
@@ -264,6 +869,145 @@ function useTheme() {
|
|
|
264
869
|
};
|
|
265
870
|
}
|
|
266
871
|
|
|
872
|
+
// src/hooks/useApiQuery.ts
|
|
873
|
+
function useApiQuery(descriptor, overrides) {
|
|
874
|
+
return useFrontXQuery(descriptor, overrides);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
// src/hooks/useApiSuspenseQuery.ts
|
|
878
|
+
function useApiSuspenseQuery(descriptor, overrides) {
|
|
879
|
+
return useFrontXSuspenseQuery(descriptor, overrides);
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
// src/hooks/useApiInfiniteQuery.ts
|
|
883
|
+
function useApiInfiniteQuery(options) {
|
|
884
|
+
return useFrontXInfiniteQuery(options);
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
// src/hooks/useApiSuspenseInfiniteQuery.ts
|
|
888
|
+
function useApiSuspenseInfiniteQuery(options) {
|
|
889
|
+
return useFrontXSuspenseInfiniteQuery(options);
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
// src/hooks/useApiMutation.ts
|
|
893
|
+
import { useMemo as useMemo6 } from "react";
|
|
894
|
+
function useApiMutation(options) {
|
|
895
|
+
const queryClient = useRequiredFrontXQueryClient();
|
|
896
|
+
const queryCache2 = useMemo6(() => createQueryCache(queryClient), [queryClient]);
|
|
897
|
+
const callbackCtx = useMemo6(() => ({ queryCache: queryCache2 }), [queryCache2]);
|
|
898
|
+
return useFrontXMutation(options, callbackCtx);
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
// src/hooks/useApiStream.ts
|
|
902
|
+
import { useEffect as useEffect6, useMemo as useMemo7, useRef as useRef2, useState as useState4, useCallback as useCallback4 } from "react";
|
|
903
|
+
function useApiStream(descriptor, options) {
|
|
904
|
+
const mode = options?.mode ?? "latest";
|
|
905
|
+
const enabled = options?.enabled ?? true;
|
|
906
|
+
const [data, setData] = useState4(void 0);
|
|
907
|
+
const [events, setEvents] = useState4([]);
|
|
908
|
+
const [status, setStatus] = useState4(() => enabled ? "connecting" : "idle");
|
|
909
|
+
const [error, setError] = useState4(null);
|
|
910
|
+
const connectPromiseRef = useRef2(null);
|
|
911
|
+
const connectionIdRef = useRef2(null);
|
|
912
|
+
const disconnectRequestedRef = useRef2(false);
|
|
913
|
+
const descriptorRef = useLatest(descriptor);
|
|
914
|
+
const descriptorKey = useMemo7(() => JSON.stringify(descriptor.key), [descriptor.key]);
|
|
915
|
+
const resetKey = `${descriptorKey}:${mode}`;
|
|
916
|
+
const [prevResetKey, setPrevResetKey] = useState4(resetKey);
|
|
917
|
+
if (resetKey !== prevResetKey) {
|
|
918
|
+
setPrevResetKey(resetKey);
|
|
919
|
+
setData(void 0);
|
|
920
|
+
setEvents([]);
|
|
921
|
+
setError(null);
|
|
922
|
+
}
|
|
923
|
+
const connectKey = `${resetKey}:${enabled}`;
|
|
924
|
+
const [prevConnectKey, setPrevConnectKey] = useState4(connectKey);
|
|
925
|
+
if (connectKey !== prevConnectKey) {
|
|
926
|
+
setPrevConnectKey(connectKey);
|
|
927
|
+
if (enabled) {
|
|
928
|
+
setData(void 0);
|
|
929
|
+
setEvents([]);
|
|
930
|
+
setStatus("connecting");
|
|
931
|
+
setError(null);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
const disconnect = useCallback4(() => {
|
|
935
|
+
disconnectRequestedRef.current = true;
|
|
936
|
+
if (connectionIdRef.current) {
|
|
937
|
+
descriptorRef.current.disconnect(connectionIdRef.current);
|
|
938
|
+
connectionIdRef.current = null;
|
|
939
|
+
disconnectRequestedRef.current = false;
|
|
940
|
+
}
|
|
941
|
+
setStatus("disconnected");
|
|
942
|
+
}, [descriptorRef]);
|
|
943
|
+
useEffect6(() => {
|
|
944
|
+
if (!enabled) {
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
let cancelled = false;
|
|
948
|
+
disconnectRequestedRef.current = false;
|
|
949
|
+
const d = descriptorRef.current;
|
|
950
|
+
const connectPromise = d.connect(
|
|
951
|
+
(event) => {
|
|
952
|
+
if (cancelled) return;
|
|
953
|
+
setData(event);
|
|
954
|
+
setStatus("connected");
|
|
955
|
+
if (mode === "accumulate") {
|
|
956
|
+
setEvents((prev) => [...prev, event]);
|
|
957
|
+
}
|
|
958
|
+
},
|
|
959
|
+
() => {
|
|
960
|
+
if (cancelled) return;
|
|
961
|
+
setStatus("disconnected");
|
|
962
|
+
connectionIdRef.current = null;
|
|
963
|
+
}
|
|
964
|
+
);
|
|
965
|
+
connectPromiseRef.current = connectPromise;
|
|
966
|
+
connectPromise.then((id) => {
|
|
967
|
+
if (cancelled) return;
|
|
968
|
+
if (disconnectRequestedRef.current) {
|
|
969
|
+
d.disconnect(id);
|
|
970
|
+
disconnectRequestedRef.current = false;
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
973
|
+
connectionIdRef.current = id;
|
|
974
|
+
setStatus("connected");
|
|
975
|
+
}).catch((err) => {
|
|
976
|
+
if (cancelled) return;
|
|
977
|
+
if (disconnectRequestedRef.current) {
|
|
978
|
+
disconnectRequestedRef.current = false;
|
|
979
|
+
setStatus("disconnected");
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
983
|
+
setStatus("error");
|
|
984
|
+
});
|
|
985
|
+
return () => {
|
|
986
|
+
cancelled = true;
|
|
987
|
+
connectPromise.then(
|
|
988
|
+
(id) => d.disconnect(id),
|
|
989
|
+
() => {
|
|
990
|
+
}
|
|
991
|
+
);
|
|
992
|
+
connectPromiseRef.current = null;
|
|
993
|
+
connectionIdRef.current = null;
|
|
994
|
+
};
|
|
995
|
+
}, [descriptorKey, enabled, mode, descriptorRef]);
|
|
996
|
+
return { data, events, status: enabled ? status : "idle", error, disconnect };
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
// src/hooks/useQueryCache.ts
|
|
1000
|
+
import { useMemo as useMemo8 } from "react";
|
|
1001
|
+
function useQueryCache() {
|
|
1002
|
+
const queryClient = useOptionalFrontXQueryClient();
|
|
1003
|
+
if (!queryClient) {
|
|
1004
|
+
throw new Error(
|
|
1005
|
+
"[FrontXProvider] No query cache available. Add queryCache() or queryCacheShared() to your plugin composition."
|
|
1006
|
+
);
|
|
1007
|
+
}
|
|
1008
|
+
return useMemo8(() => createQueryCache(queryClient), [queryClient]);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
267
1011
|
// src/mfe/hooks/useMfeBridge.ts
|
|
268
1012
|
function useMfeBridge() {
|
|
269
1013
|
const { bridge } = useMfeContext();
|
|
@@ -271,61 +1015,73 @@ function useMfeBridge() {
|
|
|
271
1015
|
}
|
|
272
1016
|
|
|
273
1017
|
// src/mfe/hooks/useSharedProperty.ts
|
|
274
|
-
import {
|
|
275
|
-
function useSharedProperty(propertyTypeId) {
|
|
276
|
-
const
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
1018
|
+
import { useCallback as useCallback5, useContext as useContext4, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
1019
|
+
function useSharedProperty(propertyTypeId, options) {
|
|
1020
|
+
const contextValue = useContext4(MfeContext);
|
|
1021
|
+
const bridge = options?.bridge ?? contextValue?.bridge;
|
|
1022
|
+
const fallback = options?.fallback;
|
|
1023
|
+
if (!bridge) {
|
|
1024
|
+
throw new Error(
|
|
1025
|
+
"useSharedProperty must be used within a MfeProvider, or given an explicit `bridge` option, for components that never mount MfeProvider."
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
1028
|
+
const subscribe = useCallback5(
|
|
1029
|
+
(onStoreChange) => bridge.subscribeToProperty(propertyTypeId, () => {
|
|
1030
|
+
onStoreChange();
|
|
1031
|
+
}),
|
|
1032
|
+
[bridge, propertyTypeId]
|
|
1033
|
+
);
|
|
1034
|
+
const getSnapshot = useCallback5(() => {
|
|
1035
|
+
const raw = bridge.getProperty(propertyTypeId)?.value;
|
|
1036
|
+
return raw === void 0 ? fallback : raw;
|
|
1037
|
+
}, [bridge, propertyTypeId, fallback]);
|
|
1038
|
+
return useSyncExternalStore4(subscribe, getSnapshot, getSnapshot);
|
|
288
1039
|
}
|
|
289
1040
|
|
|
290
1041
|
// src/mfe/hooks/useHostAction.ts
|
|
291
|
-
import { useCallback as
|
|
1042
|
+
import { useCallback as useCallback6 } from "react";
|
|
292
1043
|
function useHostAction(actionTypeId) {
|
|
293
1044
|
const { bridge } = useMfeContext();
|
|
294
|
-
return
|
|
1045
|
+
return useCallback6((payload) => {
|
|
295
1046
|
const chain = {
|
|
296
1047
|
action: {
|
|
297
1048
|
type: actionTypeId,
|
|
298
|
-
target: bridge.
|
|
1049
|
+
target: bridge.extDomainId,
|
|
299
1050
|
payload
|
|
300
1051
|
}
|
|
301
1052
|
};
|
|
302
|
-
bridge.executeActionsChain(chain)
|
|
303
|
-
console.error(
|
|
304
|
-
`[useHostAction] Failed to send action '${actionTypeId}':`,
|
|
305
|
-
error
|
|
306
|
-
);
|
|
307
|
-
});
|
|
1053
|
+
bridge.executeActionsChain(chain);
|
|
308
1054
|
}, [actionTypeId, bridge]);
|
|
309
1055
|
}
|
|
310
1056
|
|
|
311
|
-
// src/mfe/hooks/
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
const app = useHAI3();
|
|
315
|
-
const registry = app.screensetsRegistry;
|
|
1057
|
+
// src/mfe/hooks/useMfeRegistry.ts
|
|
1058
|
+
function resolveMfeRegistry(app, callerName) {
|
|
1059
|
+
const registry = app.mfeRegistry;
|
|
316
1060
|
if (!registry) {
|
|
317
1061
|
throw new Error(
|
|
318
|
-
|
|
1062
|
+
`${callerName} requires the microfrontends plugin. Add microfrontends() to your Gears FrontX app configuration.`
|
|
319
1063
|
);
|
|
320
1064
|
}
|
|
321
|
-
|
|
1065
|
+
return registry;
|
|
1066
|
+
}
|
|
1067
|
+
function useMfeRegistry() {
|
|
1068
|
+
const app = useFrontX();
|
|
1069
|
+
return resolveMfeRegistry(app, "useMfeRegistry");
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// src/mfe/hooks/useDomainExtensions.ts
|
|
1073
|
+
import { useSyncExternalStore as useSyncExternalStore5, useCallback as useCallback7, useRef as useRef3 } from "react";
|
|
1074
|
+
function useDomainExtensions(domainId) {
|
|
1075
|
+
const app = useFrontX();
|
|
1076
|
+
const registry = resolveMfeRegistry(app, "useDomainExtensions");
|
|
1077
|
+
const subscribe = useCallback7(
|
|
322
1078
|
(onStoreChange) => {
|
|
323
1079
|
return app.store.subscribe(onStoreChange);
|
|
324
1080
|
},
|
|
325
1081
|
[app.store]
|
|
326
1082
|
);
|
|
327
|
-
const cacheRef =
|
|
328
|
-
const getSnapshot =
|
|
1083
|
+
const cacheRef = useRef3({ ids: "", extensions: [] });
|
|
1084
|
+
const getSnapshot = useCallback7(() => {
|
|
329
1085
|
const extensions = registry.getExtensionsForDomain(domainId);
|
|
330
1086
|
const ids = extensions.map((e) => e.id).join(",");
|
|
331
1087
|
if (ids !== cacheRef.current.ids) {
|
|
@@ -337,23 +1093,18 @@ function useDomainExtensions(domainId) {
|
|
|
337
1093
|
}
|
|
338
1094
|
|
|
339
1095
|
// src/mfe/hooks/useRegisteredPackages.ts
|
|
340
|
-
import { useSyncExternalStore as useSyncExternalStore6, useCallback as
|
|
1096
|
+
import { useSyncExternalStore as useSyncExternalStore6, useCallback as useCallback8, useRef as useRef4 } from "react";
|
|
341
1097
|
function useRegisteredPackages() {
|
|
342
|
-
const app =
|
|
343
|
-
const registry = app
|
|
344
|
-
|
|
345
|
-
throw new Error(
|
|
346
|
-
"useRegisteredPackages requires the microfrontends plugin. Add microfrontends() to your HAI3 app configuration."
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
const subscribe = useCallback7(
|
|
1098
|
+
const app = useFrontX();
|
|
1099
|
+
const registry = resolveMfeRegistry(app, "useRegisteredPackages");
|
|
1100
|
+
const subscribe = useCallback8(
|
|
350
1101
|
(onStoreChange) => {
|
|
351
1102
|
return app.store.subscribe(onStoreChange);
|
|
352
1103
|
},
|
|
353
1104
|
[app.store]
|
|
354
1105
|
);
|
|
355
|
-
const cacheRef =
|
|
356
|
-
const getSnapshot =
|
|
1106
|
+
const cacheRef = useRef4({ packages: "", list: [] });
|
|
1107
|
+
const getSnapshot = useCallback8(() => {
|
|
357
1108
|
const list = registry.getRegisteredPackages();
|
|
358
1109
|
const packages = list.join(",");
|
|
359
1110
|
if (packages !== cacheRef.current.packages) {
|
|
@@ -364,195 +1115,331 @@ function useRegisteredPackages() {
|
|
|
364
1115
|
return useSyncExternalStore6(subscribe, getSnapshot, getSnapshot);
|
|
365
1116
|
}
|
|
366
1117
|
|
|
367
|
-
// src/mfe/
|
|
368
|
-
import {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
1118
|
+
// src/mfe/ThemeAwareReactLifecycle.tsx
|
|
1119
|
+
import { createRoot } from "react-dom/client";
|
|
1120
|
+
|
|
1121
|
+
// src/mfe/domainTeardownCollector.ts
|
|
1122
|
+
var activeCollector;
|
|
1123
|
+
function collectDomainTeardowns(fn) {
|
|
1124
|
+
const previousCollector = activeCollector;
|
|
1125
|
+
const collector = [];
|
|
1126
|
+
activeCollector = collector;
|
|
1127
|
+
try {
|
|
1128
|
+
fn();
|
|
1129
|
+
} finally {
|
|
1130
|
+
activeCollector = previousCollector;
|
|
1131
|
+
}
|
|
1132
|
+
return collector;
|
|
1133
|
+
}
|
|
1134
|
+
function registerDomainTeardown(promise) {
|
|
1135
|
+
activeCollector?.push(promise);
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
// src/mfe/ThemeAwareReactLifecycle.tsx
|
|
1139
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1140
|
+
var ADOPTED_HOST_STYLE_ATTR = "data-frontx-adopted-host-style";
|
|
1141
|
+
var BASE_RESETS_STYLE_ID = "__frontx-base-resets__";
|
|
1142
|
+
var SHELL_OWNED_SHADOW_STYLE_IDS = ["__frontx-shadow-isolation__", "__frontx-css-variables__"];
|
|
1143
|
+
function cssToCopy(style) {
|
|
1144
|
+
const text = style.textContent ?? "";
|
|
1145
|
+
const sheet = style.sheet;
|
|
1146
|
+
if (text.trim() || !sheet) return text;
|
|
1147
|
+
return Array.from(sheet.cssRules, (rule) => rule.cssText).join("\n");
|
|
1148
|
+
}
|
|
1149
|
+
function resolveProviderMountOptions(app, bridge, mountContext) {
|
|
1150
|
+
const extensionId = mountContext?.extensionId;
|
|
1151
|
+
const domainId = mountContext?.domainId;
|
|
1152
|
+
const isMountedMfe = typeof extensionId === "string" && typeof domainId === "string";
|
|
1153
|
+
if (isMountedMfe && !resolveFrontXQueryClient(app) && !hasFrontXQueryClientActivator(app)) {
|
|
374
1154
|
throw new Error(
|
|
375
|
-
"
|
|
1155
|
+
"[FrontXProvider] Mounted MFEs require queryCacheShared() in the child app and queryCache() in the host app before loading the MFE app."
|
|
376
1156
|
);
|
|
377
1157
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
},
|
|
382
|
-
[app.store]
|
|
383
|
-
);
|
|
384
|
-
const cacheRef = useRef3({ activePackage: void 0 });
|
|
385
|
-
const getSnapshot = useCallback8(() => {
|
|
386
|
-
const mountedExtensionId = registry.getMountedExtension(FRONTX_SCREEN_DOMAIN);
|
|
387
|
-
if (!mountedExtensionId) {
|
|
388
|
-
const result = void 0;
|
|
389
|
-
if (result !== cacheRef.current.activePackage) {
|
|
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 };
|
|
397
|
-
}
|
|
398
|
-
return cacheRef.current.activePackage;
|
|
399
|
-
}, [registry]);
|
|
400
|
-
return useSyncExternalStore7(subscribe, getSnapshot, getSnapshot);
|
|
1158
|
+
return {
|
|
1159
|
+
mfeBridge: isMountedMfe ? { bridge, extensionId, domainId } : void 0
|
|
1160
|
+
};
|
|
401
1161
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
1162
|
+
function MountRuntimeAwareProvider({
|
|
1163
|
+
app,
|
|
1164
|
+
mfeBridge,
|
|
1165
|
+
children
|
|
1166
|
+
}) {
|
|
1167
|
+
return /* @__PURE__ */ jsx4(FrontXProvider, { app, mfeBridge, children });
|
|
1168
|
+
}
|
|
1169
|
+
var ThemeAwareReactLifecycle = class {
|
|
1170
|
+
constructor(app) {
|
|
1171
|
+
this.app = app;
|
|
409
1172
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
1173
|
+
app;
|
|
1174
|
+
root = null;
|
|
1175
|
+
mount(container, bridge, mountContext) {
|
|
1176
|
+
void this.app.mfeRegistry;
|
|
1177
|
+
if (container instanceof ShadowRoot) {
|
|
1178
|
+
this.adoptHostStylesIntoShadowRoot(container);
|
|
413
1179
|
}
|
|
414
|
-
|
|
1180
|
+
this.injectBaseResets(container);
|
|
1181
|
+
this.initializeStyles(container);
|
|
1182
|
+
const providerMountOptions = resolveProviderMountOptions(this.app, bridge, mountContext);
|
|
1183
|
+
this.root = createRoot(container);
|
|
1184
|
+
this.root.render(
|
|
1185
|
+
/* @__PURE__ */ jsx4(
|
|
1186
|
+
MountRuntimeAwareProvider,
|
|
1187
|
+
{
|
|
1188
|
+
app: this.app,
|
|
1189
|
+
mfeBridge: providerMountOptions.mfeBridge,
|
|
1190
|
+
children: this.renderContent(bridge)
|
|
1191
|
+
}
|
|
1192
|
+
)
|
|
1193
|
+
);
|
|
415
1194
|
}
|
|
416
|
-
|
|
1195
|
+
/**
|
|
1196
|
+
* `Root.unmount()` itself is synchronous, but a nested `ExtensionDomainSlot`
|
|
1197
|
+
* mounted anywhere in this root's own tree cannot make ITS cleanup
|
|
1198
|
+
* synchronous too — its mounter's own `detach()` awaits per-extension
|
|
1199
|
+
* unmounts. Collecting whatever that cleanup fire-and-forgets (through
|
|
1200
|
+
* `domainTeardownCollector`, scoped to this one `Root.unmount()` call) and
|
|
1201
|
+
* awaiting it here is what makes this method's own returned promise settle
|
|
1202
|
+
* only once every nested domain this root owns has actually finished
|
|
1203
|
+
* tearing down — never before. A root with no routed nested domain
|
|
1204
|
+
* collects nothing, and this resolves exactly as before (a microtask after
|
|
1205
|
+
* the synchronous unmount, same observable timing `void | Promise<void>`
|
|
1206
|
+
* already allows).
|
|
1207
|
+
*/
|
|
1208
|
+
async unmount(_container) {
|
|
1209
|
+
if (!this.root) return;
|
|
1210
|
+
const root = this.root;
|
|
1211
|
+
this.root = null;
|
|
1212
|
+
const pendingTeardowns = collectDomainTeardowns(() => root.unmount());
|
|
1213
|
+
const settled = await Promise.allSettled(pendingTeardowns);
|
|
1214
|
+
const failed = settled.find((result) => result.status === "rejected");
|
|
1215
|
+
if (failed) throw failed.reason;
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* Copy all inline <style> and <link rel="stylesheet"> from the host document
|
|
1219
|
+
* into the shadow root so that Tailwind and component styles apply inside the MFE.
|
|
1220
|
+
*
|
|
1221
|
+
* The clones are inserted ahead of everything already in the shadow root, never
|
|
1222
|
+
* appended, because adopted host styles are context rather than authority: where
|
|
1223
|
+
* they and the MFE's own CSS declare the same property at equal specificity, the
|
|
1224
|
+
* MFE has to win. Appending inverted that. `MfeHandlerMF` injects the MFE's
|
|
1225
|
+
* compiled stylesheet into the shadow root before it calls mount, so an appended
|
|
1226
|
+
* clone of the shell's Tailwind preflight - whose
|
|
1227
|
+
* `button, [type='button'], [type='reset'], [type='submit']` rule sets
|
|
1228
|
+
* `background-color: transparent` at specificity (0,1,0) - tied with
|
|
1229
|
+
* `@gears-frontx/ui-kit`'s single-class button rule and won on document order,
|
|
1230
|
+
* leaving every kit Button transparent until it was hovered.
|
|
1231
|
+
*
|
|
1232
|
+
* Inserting at the front rather than pushing MFE styles to the back is what makes
|
|
1233
|
+
* the invariant hold for stylesheets that appear after mount too - a lazily
|
|
1234
|
+
* imported component's CSS module, or whatever initializeStyles() adds - since
|
|
1235
|
+
* those land behind the adopted block by construction.
|
|
1236
|
+
*
|
|
1237
|
+
* A cascade layer around the adopted CSS was the alternative and is rejected:
|
|
1238
|
+
* layered rules lose to unlayered ones at *any* specificity, so a host utility
|
|
1239
|
+
* class would stop overriding an MFE element selector. Document order keeps
|
|
1240
|
+
* specificity in charge and only settles the ties.
|
|
1241
|
+
*
|
|
1242
|
+
* The block replaces its predecessor instead of stacking on it, the same
|
|
1243
|
+
* upsert shape `injectStylesheet` and `injectCssVariables` use in
|
|
1244
|
+
* `@gears-frontx/mfes`' shadow utilities, widened from one id-keyed node to a
|
|
1245
|
+
* marked block. Replacement is required rather than tidy: `createShadowRoot`
|
|
1246
|
+
* hands back an existing `element.shadowRoot` instead of attaching a new one,
|
|
1247
|
+
* so remounting the same container runs this method again on a shadow root
|
|
1248
|
+
* that already holds a full adopted block, and appending would grow it once
|
|
1249
|
+
* per mount with no bound. It does not save re-resolving the cloned `<link>`s -
|
|
1250
|
+
* every mount clones them afresh and the browser resolves each clone; what
|
|
1251
|
+
* replacement buys is that the count stays at one block instead of one per
|
|
1252
|
+
* mount.
|
|
1253
|
+
*
|
|
1254
|
+
* The block is rebuilt from the host head rather than left in place, because
|
|
1255
|
+
* the head is not fixed: a lazily imported chunk adds stylesheets to it after
|
|
1256
|
+
* the first mount, and the second mount has to pick those up.
|
|
1257
|
+
*
|
|
1258
|
+
* A `<style>` is copied into a new element that holds the host's CSS - see
|
|
1259
|
+
* `cssToCopy` - and takes three things from the host element: `media`,
|
|
1260
|
+
* without which a print-only host style applies on screen inside the MFE;
|
|
1261
|
+
* `type`, which keeps the copy of a non-CSS element as inert as the original;
|
|
1262
|
+
* and the nonce, without which a nonce-based CSP blocks the copy. The nonce is read from the `nonce` property, because
|
|
1263
|
+
* browsers blank the attribute in a document served with a CSP header.
|
|
1264
|
+
* Nothing else is carried over, because libraries look for their own
|
|
1265
|
+
* attributes inside the shadow root: styled-components, rendering into it,
|
|
1266
|
+
* puts its tag right after the last `style[data-styled]` there, so a copy of
|
|
1267
|
+
* the host's tag would pull the MFE's rules ahead of the base resets and the
|
|
1268
|
+
* MFE's own CSS. A `<link>` is a deep clone and is loaded from its `href`
|
|
1269
|
+
* again.
|
|
1270
|
+
*
|
|
1271
|
+
* The fresh block goes in before the previous one comes out. Removing first
|
|
1272
|
+
* leaves the shadow root with no host CSS at all, and everything between that
|
|
1273
|
+
* removal and the insertion is synchronous work in this same task - so the gap
|
|
1274
|
+
* never reaches a paint, but any code that reads computed styles from the tree
|
|
1275
|
+
* in between sees an unstyled one. Inserting first costs one moment with two
|
|
1276
|
+
* blocks present, which changes nothing: the old block is a clone of the same
|
|
1277
|
+
* host head and loses every tie to the new one on document order anyway.
|
|
1278
|
+
*/
|
|
1279
|
+
adoptHostStylesIntoShadowRoot(shadowRoot) {
|
|
1280
|
+
const supersededStyles = Array.from(shadowRoot.querySelectorAll(`[${ADOPTED_HOST_STYLE_ATTR}]`));
|
|
1281
|
+
const adoptedStyles = document.createDocumentFragment();
|
|
1282
|
+
const hostStyleNodes = document.head.querySelectorAll('style, link[rel="stylesheet"]');
|
|
1283
|
+
hostStyleNodes.forEach((el) => {
|
|
1284
|
+
if (el instanceof HTMLStyleElement) {
|
|
1285
|
+
const copy = document.createElement("style");
|
|
1286
|
+
if (el.media) copy.media = el.media;
|
|
1287
|
+
if (el.type) copy.type = el.type;
|
|
1288
|
+
if (el.nonce) copy.nonce = el.nonce;
|
|
1289
|
+
copy.textContent = cssToCopy(el);
|
|
1290
|
+
copy.setAttribute(ADOPTED_HOST_STYLE_ATTR, "");
|
|
1291
|
+
adoptedStyles.appendChild(copy);
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
const linkClone = el.cloneNode(true);
|
|
1295
|
+
linkClone.setAttribute(ADOPTED_HOST_STYLE_ATTR, "");
|
|
1296
|
+
adoptedStyles.appendChild(linkClone);
|
|
1297
|
+
});
|
|
1298
|
+
shadowRoot.insertBefore(adoptedStyles, shadowRoot.firstChild);
|
|
1299
|
+
supersededStyles.forEach((el) => el.remove());
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Box-model resets and :host defaults needed inside every shadow root.
|
|
1303
|
+
* These aren't part of Tailwind's compiled output but are required for
|
|
1304
|
+
* consistent rendering across browsers.
|
|
1305
|
+
*
|
|
1306
|
+
* Reuses the node a previous mount left behind, exactly as `injectStylesheet`
|
|
1307
|
+
* does in `@gears-frontx/mfes`' shadow utilities: a remount runs against a
|
|
1308
|
+
* shadow root that `createShadowRoot` handed back intact, and appending a
|
|
1309
|
+
* second copy would add one node per mount forever.
|
|
1310
|
+
*
|
|
1311
|
+
* Reuse alone is not enough, which is why the node is also positioned on every
|
|
1312
|
+
* mount rather than left where the previous one sat. These resets are context
|
|
1313
|
+
* like the adopted block is - `border-color: currentColor` on `*` is a 0-0-0
|
|
1314
|
+
* declaration that beats an MFE preflight's own 0-0-0 reset purely on document
|
|
1315
|
+
* order - so they have to stay ahead of the MFE's CSS, and where they land is
|
|
1316
|
+
* not stable on its own. `MfeHandlerMF.wrapLifecycleWithStylesheets` removes the
|
|
1317
|
+
* MFE's stylesheet on unmount and appends a fresh one before the next mount, so
|
|
1318
|
+
* a node merely left in place ends up ahead of that stylesheet on a remount and
|
|
1319
|
+
* behind it on the first mount: two different cascades for one component.
|
|
1320
|
+
* Anchoring it to the end of the shell-owned head gives every mount the same
|
|
1321
|
+
* order - adopted block, isolation, resets, MFE - which is also the order the
|
|
1322
|
+
* adoption method's invariant is written against.
|
|
1323
|
+
*
|
|
1324
|
+
* With no shell-owned node to anchor to, the resets go to the front. That is the
|
|
1325
|
+
* plain-`Element` container: no adopted block, no isolation style, and the MFE
|
|
1326
|
+
* stylesheet already appended by the handler, so the front is again the only
|
|
1327
|
+
* position that leaves the MFE winning ties.
|
|
1328
|
+
*
|
|
1329
|
+
* Looked up by attribute-selector form rather than `getElementById`, which
|
|
1330
|
+
* `ShadowRoot` has but `Element` does not, and this hook takes either.
|
|
1331
|
+
*/
|
|
1332
|
+
injectBaseResets(container) {
|
|
1333
|
+
const existing = container.querySelector(
|
|
1334
|
+
`style[id="${BASE_RESETS_STYLE_ID}"]`
|
|
1335
|
+
);
|
|
1336
|
+
const style = existing ?? document.createElement("style");
|
|
1337
|
+
style.id = BASE_RESETS_STYLE_ID;
|
|
1338
|
+
style.textContent = `
|
|
1339
|
+
*, *::before, *::after {
|
|
1340
|
+
box-sizing: border-box;
|
|
1341
|
+
border-width: 0;
|
|
1342
|
+
border-style: solid;
|
|
1343
|
+
border-color: currentColor;
|
|
1344
|
+
}
|
|
1345
|
+
* { margin: 0; padding: 0; }
|
|
1346
|
+
:host {
|
|
1347
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
1348
|
+
line-height: 1.5;
|
|
1349
|
+
-webkit-font-smoothing: antialiased;
|
|
1350
|
+
-moz-osx-font-smoothing: grayscale;
|
|
1351
|
+
color: var(--foreground);
|
|
1352
|
+
background-color: var(--background);
|
|
1353
|
+
}
|
|
1354
|
+
`;
|
|
1355
|
+
const shellOwnedHead = container.querySelectorAll(
|
|
1356
|
+
[
|
|
1357
|
+
`[${ADOPTED_HOST_STYLE_ATTR}]`,
|
|
1358
|
+
...SHELL_OWNED_SHADOW_STYLE_IDS.map((id) => `[id="${id}"]`)
|
|
1359
|
+
].join(", ")
|
|
1360
|
+
);
|
|
1361
|
+
const lastShellOwnedNode = shellOwnedHead[shellOwnedHead.length - 1];
|
|
1362
|
+
container.insertBefore(
|
|
1363
|
+
style,
|
|
1364
|
+
lastShellOwnedNode ? lastShellOwnedNode.nextSibling : container.firstChild
|
|
1365
|
+
);
|
|
1366
|
+
}
|
|
1367
|
+
/**
|
|
1368
|
+
* Hook for subclasses to inject additional CSS not covered by the adopted host
|
|
1369
|
+
* stylesheet (e.g., MFE-specific @font-face rules or custom animations).
|
|
1370
|
+
* No-op by default: host styles adopted in adoptHostStylesIntoShadowRoot()
|
|
1371
|
+
* already include all Tailwind utilities compiled from MFE source files.
|
|
1372
|
+
*/
|
|
1373
|
+
initializeStyles(_container) {
|
|
417
1374
|
}
|
|
418
1375
|
};
|
|
419
1376
|
|
|
420
1377
|
// 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";
|
|
1378
|
+
import { useEffect as useEffect7, useEffectEvent, useRef as useRef5, useState as useState5 } from "react";
|
|
1379
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
427
1380
|
function ExtensionDomainSlot(props) {
|
|
428
1381
|
const {
|
|
429
1382
|
registry,
|
|
430
1383
|
domainId,
|
|
431
|
-
extensionId,
|
|
432
1384
|
className,
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
loadingComponent,
|
|
437
|
-
errorComponent
|
|
1385
|
+
onAttached,
|
|
1386
|
+
onDetached,
|
|
1387
|
+
loadingComponent = null
|
|
438
1388
|
} = 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
|
-
}
|
|
1389
|
+
const rootRef = useRef5(null);
|
|
1390
|
+
const emitAttached = useEffectEvent((root) => {
|
|
1391
|
+
onAttached?.(root);
|
|
1392
|
+
});
|
|
1393
|
+
const emitDetached = useEffectEvent(() => {
|
|
1394
|
+
onDetached?.();
|
|
1395
|
+
});
|
|
1396
|
+
const [attached, setAttached] = useState5(false);
|
|
1397
|
+
useEffect7(() => {
|
|
1398
|
+
const root = rootRef.current;
|
|
1399
|
+
if (!root) {
|
|
1400
|
+
return;
|
|
495
1401
|
}
|
|
496
|
-
|
|
1402
|
+
const mounter = registry.getMounter(domainId);
|
|
1403
|
+
mounter.attach(root);
|
|
1404
|
+
setAttached(true);
|
|
1405
|
+
emitAttached(root);
|
|
497
1406
|
return () => {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
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
|
-
}
|
|
1407
|
+
const detachPromise = mounter.detach();
|
|
1408
|
+
registerDomainTeardown(detachPromise);
|
|
1409
|
+
setAttached(false);
|
|
1410
|
+
emitDetached();
|
|
514
1411
|
};
|
|
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(
|
|
1412
|
+
}, [registry, domainId]);
|
|
1413
|
+
return /* @__PURE__ */ jsx5(
|
|
526
1414
|
"div",
|
|
527
1415
|
{
|
|
528
|
-
ref:
|
|
1416
|
+
ref: rootRef,
|
|
529
1417
|
className,
|
|
530
1418
|
"data-domain-id": domainId,
|
|
531
|
-
|
|
532
|
-
"data-bridge-active": bridge !== null
|
|
1419
|
+
children: !attached ? loadingComponent : null
|
|
533
1420
|
}
|
|
534
1421
|
);
|
|
535
1422
|
}
|
|
536
1423
|
|
|
537
1424
|
// src/index.ts
|
|
538
1425
|
import {
|
|
539
|
-
|
|
540
|
-
createHAI3App as createHAI3App2,
|
|
1426
|
+
createFrontX,
|
|
541
1427
|
presets,
|
|
542
1428
|
ACCOUNTS_DOMAIN,
|
|
543
1429
|
I18nRegistry,
|
|
544
|
-
screensets,
|
|
545
1430
|
themes,
|
|
546
1431
|
layout,
|
|
547
1432
|
i18n,
|
|
548
1433
|
effects,
|
|
1434
|
+
queryCache,
|
|
1435
|
+
queryCacheShared,
|
|
1436
|
+
subscribeQueryCacheRuntimeChanged as subscribeQueryCacheRuntimeChanged2,
|
|
549
1437
|
createThemeRegistry,
|
|
550
1438
|
createStore,
|
|
551
1439
|
getStore,
|
|
552
1440
|
registerSlice,
|
|
553
1441
|
hasSlice,
|
|
554
1442
|
createSlice,
|
|
555
|
-
LayoutDomain,
|
|
556
1443
|
layoutReducer,
|
|
557
1444
|
layoutDomainReducers,
|
|
558
1445
|
LAYOUT_SLICE_NAME,
|
|
@@ -560,14 +1447,12 @@ import {
|
|
|
560
1447
|
footerSlice,
|
|
561
1448
|
menuSlice,
|
|
562
1449
|
sidebarSlice,
|
|
563
|
-
screenSlice,
|
|
564
1450
|
popupSlice,
|
|
565
1451
|
overlaySlice,
|
|
566
1452
|
headerActions,
|
|
567
1453
|
footerActions,
|
|
568
1454
|
menuActions,
|
|
569
1455
|
sidebarActions,
|
|
570
|
-
screenActions,
|
|
571
1456
|
popupActions,
|
|
572
1457
|
overlayActions,
|
|
573
1458
|
setUser,
|
|
@@ -588,10 +1473,6 @@ import {
|
|
|
588
1473
|
setSidebarVisible,
|
|
589
1474
|
setSidebarWidth,
|
|
590
1475
|
setSidebarConfig,
|
|
591
|
-
setActiveScreen,
|
|
592
|
-
setScreenLoading,
|
|
593
|
-
navigateTo,
|
|
594
|
-
clearActiveScreen,
|
|
595
1476
|
openPopup,
|
|
596
1477
|
closePopup,
|
|
597
1478
|
closeTopPopup,
|
|
@@ -617,13 +1498,15 @@ import {
|
|
|
617
1498
|
initMockEffects,
|
|
618
1499
|
toggleMockMode,
|
|
619
1500
|
MockEvents,
|
|
1501
|
+
auth,
|
|
1502
|
+
AuthEvents,
|
|
1503
|
+
frontxApiTransport,
|
|
620
1504
|
apiRegistry,
|
|
621
1505
|
BaseApiService,
|
|
622
1506
|
RestProtocol,
|
|
1507
|
+
RestEndpointProtocol,
|
|
623
1508
|
SseProtocol,
|
|
624
|
-
|
|
625
|
-
SseMockPlugin,
|
|
626
|
-
MockEventSource,
|
|
1509
|
+
SseStreamProtocol,
|
|
627
1510
|
ApiPluginBase,
|
|
628
1511
|
ApiPlugin,
|
|
629
1512
|
ApiProtocol,
|
|
@@ -662,7 +1545,7 @@ import {
|
|
|
662
1545
|
import {
|
|
663
1546
|
FRONTX_POPUP_DOMAIN,
|
|
664
1547
|
FRONTX_SIDEBAR_DOMAIN,
|
|
665
|
-
FRONTX_SCREEN_DOMAIN
|
|
1548
|
+
FRONTX_SCREEN_DOMAIN,
|
|
666
1549
|
FRONTX_OVERLAY_DOMAIN,
|
|
667
1550
|
screenDomain,
|
|
668
1551
|
sidebarDomain,
|
|
@@ -675,102 +1558,118 @@ import {
|
|
|
675
1558
|
} from "@gears-frontx/framework";
|
|
676
1559
|
import {
|
|
677
1560
|
FRONTX_ACTION_LOAD_EXT,
|
|
678
|
-
FRONTX_ACTION_MOUNT_EXT
|
|
679
|
-
FRONTX_ACTION_UNMOUNT_EXT
|
|
1561
|
+
FRONTX_ACTION_MOUNT_EXT,
|
|
1562
|
+
FRONTX_ACTION_UNMOUNT_EXT
|
|
680
1563
|
} from "@gears-frontx/framework";
|
|
681
1564
|
import {
|
|
682
1565
|
FRONTX_SHARED_PROPERTY_THEME,
|
|
683
1566
|
FRONTX_SHARED_PROPERTY_LANGUAGE
|
|
684
1567
|
} from "@gears-frontx/framework";
|
|
685
1568
|
import {
|
|
1569
|
+
ChildMfeBridge,
|
|
1570
|
+
ParentMfeBridge,
|
|
686
1571
|
MfeHandler,
|
|
687
1572
|
MfeBridgeFactory,
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
1573
|
+
MfeRegistry,
|
|
1574
|
+
MfeRegistryFactory,
|
|
1575
|
+
mfeRegistryFactory,
|
|
1576
|
+
ActionHandler,
|
|
1577
|
+
ExtensionDomainImplementation,
|
|
1578
|
+
ExtensionDomainImplementationFactory,
|
|
1579
|
+
ExtensionMounter,
|
|
1580
|
+
MountStrategy,
|
|
1581
|
+
ConcurrentMountStrategy,
|
|
1582
|
+
OptionalMountStrategy,
|
|
1583
|
+
ExclusiveMountStrategy
|
|
692
1584
|
} from "@gears-frontx/framework";
|
|
693
1585
|
import { MfeHandlerMF, gtsPlugin } from "@gears-frontx/framework";
|
|
694
|
-
import { themeSchema, languageSchema, extensionScreenSchema } from "@gears-frontx/framework";
|
|
695
1586
|
import {
|
|
696
1587
|
createShadowRoot,
|
|
697
1588
|
injectCssVariables,
|
|
698
|
-
extractGtsPackage
|
|
1589
|
+
extractGtsPackage
|
|
699
1590
|
} from "@gears-frontx/framework";
|
|
700
1591
|
import { eventBus as frameworkEventBus } from "@gears-frontx/framework";
|
|
701
|
-
var
|
|
1592
|
+
var eventBus2 = frameworkEventBus;
|
|
702
1593
|
export {
|
|
703
1594
|
ACCOUNTS_DOMAIN,
|
|
1595
|
+
ActionHandler,
|
|
704
1596
|
ApiPlugin,
|
|
705
1597
|
ApiPluginBase,
|
|
706
1598
|
ApiProtocol,
|
|
1599
|
+
AuthEvents,
|
|
707
1600
|
BaseApiService,
|
|
708
|
-
|
|
1601
|
+
CanAccess,
|
|
1602
|
+
ChildMfeBridge,
|
|
1603
|
+
ConcurrentMountStrategy,
|
|
1604
|
+
ExclusiveMountStrategy,
|
|
1605
|
+
ExtensionDomainImplementation,
|
|
1606
|
+
ExtensionDomainImplementationFactory,
|
|
709
1607
|
ExtensionDomainSlot,
|
|
1608
|
+
ExtensionMounter,
|
|
710
1609
|
FRONTX_ACTION_LOAD_EXT,
|
|
711
|
-
|
|
712
|
-
|
|
1610
|
+
FRONTX_ACTION_MOUNT_EXT,
|
|
1611
|
+
FRONTX_ACTION_UNMOUNT_EXT,
|
|
713
1612
|
FRONTX_MFE_ENTRY_MF,
|
|
714
1613
|
FRONTX_OVERLAY_DOMAIN,
|
|
715
1614
|
FRONTX_POPUP_DOMAIN,
|
|
716
|
-
|
|
1615
|
+
FRONTX_SCREEN_DOMAIN,
|
|
717
1616
|
FRONTX_SCREEN_EXTENSION_TYPE,
|
|
718
1617
|
FRONTX_SHARED_PROPERTY_LANGUAGE,
|
|
719
1618
|
FRONTX_SHARED_PROPERTY_THEME,
|
|
720
1619
|
FRONTX_SIDEBAR_DOMAIN,
|
|
721
|
-
|
|
722
|
-
|
|
1620
|
+
FrontXContext,
|
|
1621
|
+
FrontXProvider,
|
|
723
1622
|
I18nRegistry,
|
|
724
1623
|
I18nRegistryImpl,
|
|
725
1624
|
LAYOUT_SLICE_NAME,
|
|
726
1625
|
Language,
|
|
727
1626
|
LanguageDisplayMode,
|
|
728
|
-
LayoutDomain,
|
|
729
1627
|
MOCK_PLUGIN,
|
|
730
1628
|
MfeBridgeFactory,
|
|
731
1629
|
MfeContext,
|
|
732
1630
|
MfeHandler,
|
|
733
1631
|
MfeHandlerMF,
|
|
734
1632
|
MfeProvider,
|
|
735
|
-
|
|
1633
|
+
MfeRegistry,
|
|
1634
|
+
MfeRegistryFactory,
|
|
736
1635
|
MockEvents,
|
|
737
|
-
|
|
738
|
-
|
|
1636
|
+
MountStrategy,
|
|
1637
|
+
OptionalMountStrategy,
|
|
1638
|
+
ParentMfeBridge,
|
|
1639
|
+
RestEndpointProtocol,
|
|
739
1640
|
RestPlugin,
|
|
740
1641
|
RestPluginWithConfig,
|
|
741
1642
|
RestProtocol,
|
|
742
1643
|
SUPPORTED_LANGUAGES,
|
|
743
|
-
ScreensetsRegistry,
|
|
744
|
-
ScreensetsRegistryFactory,
|
|
745
|
-
SseMockPlugin,
|
|
746
1644
|
SsePlugin,
|
|
747
1645
|
SsePluginWithConfig,
|
|
748
1646
|
SseProtocol,
|
|
1647
|
+
SseStreamProtocol,
|
|
749
1648
|
TENANT_SLICE_NAME,
|
|
750
1649
|
TenantEvents,
|
|
751
1650
|
TextDirection,
|
|
1651
|
+
ThemeAwareReactLifecycle,
|
|
752
1652
|
apiRegistry,
|
|
1653
|
+
auth,
|
|
753
1654
|
changeTenant,
|
|
754
|
-
clearActiveScreen,
|
|
755
1655
|
clearTenant,
|
|
756
1656
|
clearTenantAction,
|
|
757
1657
|
clearUser,
|
|
758
1658
|
closeAllPopups,
|
|
759
1659
|
closePopup,
|
|
760
1660
|
closeTopPopup,
|
|
761
|
-
|
|
762
|
-
createHAI3App2 as createHAI3App,
|
|
1661
|
+
createFrontX,
|
|
763
1662
|
createI18nRegistry,
|
|
764
1663
|
createShadowRoot,
|
|
765
1664
|
createSlice,
|
|
766
1665
|
createStore,
|
|
767
1666
|
createThemeRegistry,
|
|
768
1667
|
effects,
|
|
769
|
-
eventBus,
|
|
770
|
-
|
|
771
|
-
extractGtsPackage2 as extractGtsPackage,
|
|
1668
|
+
eventBus2 as eventBus,
|
|
1669
|
+
extractGtsPackage,
|
|
772
1670
|
footerActions,
|
|
773
1671
|
footerSlice,
|
|
1672
|
+
frontxApiTransport,
|
|
774
1673
|
getLanguageMetadata,
|
|
775
1674
|
getStore,
|
|
776
1675
|
gtsPlugin,
|
|
@@ -783,23 +1682,23 @@ export {
|
|
|
783
1682
|
initMockEffects,
|
|
784
1683
|
initTenantEffects,
|
|
785
1684
|
injectCssVariables,
|
|
1685
|
+
invalidateQueryCacheForApp,
|
|
786
1686
|
isMockPlugin,
|
|
787
1687
|
isRestShortCircuit,
|
|
788
1688
|
isShortCircuit,
|
|
789
1689
|
isSseShortCircuit,
|
|
790
|
-
languageSchema,
|
|
791
1690
|
layout,
|
|
792
1691
|
layoutDomainReducers,
|
|
793
1692
|
layoutReducer,
|
|
794
1693
|
loadExtension,
|
|
795
1694
|
menuActions,
|
|
796
1695
|
menuSlice,
|
|
1696
|
+
mfeRegistryFactory,
|
|
797
1697
|
microfrontends,
|
|
798
1698
|
mock,
|
|
799
1699
|
mockActions,
|
|
800
1700
|
mockSlice,
|
|
801
1701
|
mountExtension,
|
|
802
|
-
navigateTo,
|
|
803
1702
|
openPopup,
|
|
804
1703
|
overlayActions,
|
|
805
1704
|
overlayDomain,
|
|
@@ -808,17 +1707,14 @@ export {
|
|
|
808
1707
|
popupDomain,
|
|
809
1708
|
popupSlice,
|
|
810
1709
|
presets,
|
|
1710
|
+
queryCache,
|
|
1711
|
+
queryCacheShared,
|
|
811
1712
|
registerExtension,
|
|
812
1713
|
registerSlice,
|
|
813
|
-
screenActions,
|
|
814
1714
|
screenDomain,
|
|
815
|
-
screenSlice,
|
|
816
|
-
screensets,
|
|
817
|
-
screensetsRegistryFactory,
|
|
818
1715
|
selectExtensionError,
|
|
819
1716
|
selectExtensionState,
|
|
820
1717
|
selectRegisteredExtensions,
|
|
821
|
-
setActiveScreen,
|
|
822
1718
|
setFooterConfig,
|
|
823
1719
|
setFooterVisible,
|
|
824
1720
|
setHeaderLoading,
|
|
@@ -828,7 +1724,6 @@ export {
|
|
|
828
1724
|
setMenuVisible,
|
|
829
1725
|
setMockEnabled,
|
|
830
1726
|
setOverlayVisible,
|
|
831
|
-
setScreenLoading,
|
|
832
1727
|
setSidebarCollapsed,
|
|
833
1728
|
setSidebarConfig,
|
|
834
1729
|
setSidebarContent,
|
|
@@ -844,25 +1739,33 @@ export {
|
|
|
844
1739
|
sidebarActions,
|
|
845
1740
|
sidebarDomain,
|
|
846
1741
|
sidebarSlice,
|
|
1742
|
+
subscribeQueryCacheRuntimeChanged2 as subscribeQueryCacheRuntimeChanged,
|
|
847
1743
|
tenantActions,
|
|
848
1744
|
tenantReducer,
|
|
849
1745
|
tenantSlice,
|
|
850
|
-
themeSchema,
|
|
851
1746
|
themes,
|
|
852
1747
|
toggleMenu,
|
|
853
1748
|
toggleMockMode,
|
|
854
1749
|
toggleSidebar,
|
|
855
1750
|
unmountExtension,
|
|
856
1751
|
unregisterExtension,
|
|
857
|
-
|
|
1752
|
+
useApiInfiniteQuery,
|
|
1753
|
+
useApiMutation,
|
|
1754
|
+
useApiQuery,
|
|
1755
|
+
useApiStream,
|
|
1756
|
+
useApiSuspenseInfiniteQuery,
|
|
1757
|
+
useApiSuspenseQuery,
|
|
858
1758
|
useAppDispatch,
|
|
859
1759
|
useAppSelector,
|
|
1760
|
+
useCanAccess,
|
|
860
1761
|
useDomainExtensions,
|
|
861
1762
|
useFormatters,
|
|
862
|
-
|
|
1763
|
+
useFrontX,
|
|
863
1764
|
useHostAction,
|
|
864
1765
|
useMfeBridge,
|
|
865
1766
|
useMfeContext,
|
|
1767
|
+
useMfeRegistry,
|
|
1768
|
+
useQueryCache,
|
|
866
1769
|
useRegisteredPackages,
|
|
867
1770
|
useScreenTranslations,
|
|
868
1771
|
useSharedProperty,
|