@solidxai/core-ui 0.1.8 → 0.1.9-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/auth/AuthLayout.d.ts.map +1 -1
- package/dist/components/auth/AuthLayout.js +16 -15
- package/dist/components/auth/AuthLayout.js.map +1 -1
- package/dist/components/auth/AuthLayout.tsx +3 -1
- package/dist/components/auth/ForgotPasswordThankYou.js +1 -1
- package/dist/components/auth/ForgotPasswordThankYou.js.map +1 -1
- package/dist/components/auth/ForgotPasswordThankYou.tsx +2 -2
- package/dist/components/auth/SolidForgotPassword.js +1 -1
- package/dist/components/auth/SolidForgotPassword.js.map +1 -1
- package/dist/components/auth/SolidForgotPassword.tsx +2 -2
- package/dist/components/auth/SolidInitialLoginOtp.js +8 -8
- package/dist/components/auth/SolidInitialLoginOtp.js.map +1 -1
- package/dist/components/auth/SolidInitialLoginOtp.tsx +1 -1
- package/dist/components/auth/SolidInitiateRegisterOtp.js +8 -8
- package/dist/components/auth/SolidInitiateRegisterOtp.js.map +1 -1
- package/dist/components/auth/SolidInitiateRegisterOtp.tsx +1 -1
- package/dist/components/auth/SolidLogin.js +7 -8
- package/dist/components/auth/SolidLogin.js.map +1 -1
- package/dist/components/auth/SolidLogin.tsx +1 -1
- package/dist/components/auth/SolidRegister.js +9 -9
- package/dist/components/auth/SolidRegister.js.map +1 -1
- package/dist/components/auth/SolidRegister.tsx +2 -2
- package/dist/components/common/AuthBanner.js.map +1 -1
- package/dist/components/common/SocialMediaLogin.js +1 -1
- package/dist/components/common/SocialMediaLogin.js.map +1 -1
- package/dist/components/common/SocialMediaLogin.tsx +4 -4
- package/dist/components/core/common/SolidAccountSettings/SolidAccountSettings.module.css +149 -0
- package/dist/components/core/common/SolidAccountSettings/SolidVersionInfo.d.ts.map +1 -1
- package/dist/components/core/common/SolidAccountSettings/SolidVersionInfo.js +21 -4
- package/dist/components/core/common/SolidAccountSettings/SolidVersionInfo.js.map +1 -1
- package/dist/components/core/common/SolidAccountSettings/SolidVersionInfo.tsx +128 -1
- package/dist/components/core/form/SolidFormActionHeader.d.ts.map +1 -1
- package/dist/components/core/form/SolidFormActionHeader.js +5 -2
- package/dist/components/core/form/SolidFormActionHeader.js.map +1 -1
- package/dist/components/core/form/SolidFormActionHeader.tsx +6 -3
- package/dist/components/core/form/SolidFormView.d.ts.map +1 -1
- package/dist/components/core/form/SolidFormView.js +5 -1
- package/dist/components/core/form/SolidFormView.js.map +1 -1
- package/dist/components/core/form/SolidFormView.tsx +4 -1
- package/dist/components/core/form/fields/SolidJsonField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidJsonField.js +4 -1
- package/dist/components/core/form/fields/SolidJsonField.js.map +1 -1
- package/dist/components/core/form/fields/SolidJsonField.tsx +4 -1
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js +2 -2
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.tsx +2 -2
- package/dist/components/core/kanban/SolidManyToOneFilterElement.d.ts.map +1 -1
- package/dist/components/core/kanban/SolidManyToOneFilterElement.js.map +1 -1
- package/dist/components/core/kanban/SolidManyToOneFilterElement.tsx +1 -2
- package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.d.ts.map +1 -1
- package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.js +2 -2
- package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.js.map +1 -1
- package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.tsx +21 -10
- package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.d.ts.map +1 -1
- package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.js +2 -2
- package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.js.map +1 -1
- package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.tsx +18 -10
- package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.d.ts.map +1 -1
- package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.js +3 -6
- package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.js.map +1 -1
- package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.tsx +30 -24
- package/dist/components/core/kanban/kanban-fields/relations/SolidRelationManyToOneKanbanField.js.map +1 -1
- package/dist/components/core/kanban/kanban-fields/relations/SolidRelationManyToOneKanbanField.tsx +2 -2
- package/dist/components/core/list/SolidDataTablePagination.d.ts +15 -0
- package/dist/components/core/list/SolidDataTablePagination.d.ts.map +1 -0
- package/dist/components/core/list/SolidDataTablePagination.js +22 -0
- package/dist/components/core/list/SolidDataTablePagination.js.map +1 -0
- package/dist/components/core/list/SolidDataTablePagination.tsx +71 -0
- package/dist/components/core/list/SolidListViewConfigure.d.ts.map +1 -1
- package/dist/components/core/list/SolidListViewConfigure.js +31 -2
- package/dist/components/core/list/SolidListViewConfigure.js.map +1 -1
- package/dist/components/core/list/SolidListViewConfigure.tsx +34 -2
- package/dist/components/core/list/SolidListViewRowButtonContextMenu.d.ts +1 -1
- package/dist/components/core/list/SolidListViewRowButtonContextMenu.d.ts.map +1 -1
- package/dist/components/core/list/SolidListViewRowButtonContextMenu.js +6 -7
- package/dist/components/core/list/SolidListViewRowButtonContextMenu.js.map +1 -1
- package/dist/components/core/list/SolidListViewRowButtonContextMenu.tsx +9 -10
- package/dist/components/core/tree/SolidTreeTable.d.ts +1 -1
- package/dist/components/core/tree/SolidTreeTable.d.ts.map +1 -1
- package/dist/components/core/tree/SolidTreeTable.js +78 -78
- package/dist/components/core/tree/SolidTreeTable.js.map +1 -1
- package/dist/components/core/tree/SolidTreeTable.tsx +1 -10
- package/dist/components/core/users/CreateUser.css +27 -2
- package/dist/components/core/users/CreateUser.d.ts.map +1 -1
- package/dist/components/core/users/CreateUser.js +14 -12
- package/dist/components/core/users/CreateUser.js.map +1 -1
- package/dist/components/core/users/CreateUser.tsx +18 -2
- package/dist/components/layout/user-profile-menu.d.ts.map +1 -1
- package/dist/components/layout/user-profile-menu.js +2 -1
- package/dist/components/layout/user-profile-menu.js.map +1 -1
- package/dist/components/layout/user-profile-menu.tsx +22 -27
- package/dist/components/shad-cn-ui/SolidButton.d.ts +14 -15
- package/dist/components/shad-cn-ui/SolidButton.d.ts.map +1 -1
- package/dist/components/shad-cn-ui/SolidButton.js +13 -3
- package/dist/components/shad-cn-ui/SolidButton.js.map +1 -1
- package/dist/components/shad-cn-ui/SolidButton.tsx +24 -4
- package/dist/components/solid-ui/SolidButton.d.ts +14 -0
- package/dist/components/solid-ui/SolidButton.d.ts.map +1 -0
- package/dist/components/solid-ui/SolidButton.js +36 -0
- package/dist/components/solid-ui/SolidButton.js.map +1 -0
- package/dist/components/solid-ui/SolidButton.tsx +54 -0
- package/dist/components/solid-ui/SolidTabs.d.ts +18 -0
- package/dist/components/solid-ui/SolidTabs.d.ts.map +1 -0
- package/dist/components/solid-ui/SolidTabs.js +22 -0
- package/dist/components/solid-ui/SolidTabs.js.map +1 -0
- package/dist/components/solid-ui/SolidTabs.tsx +73 -0
- package/dist/components/solid-ui/index.d.ts +3 -0
- package/dist/components/solid-ui/index.d.ts.map +1 -0
- package/dist/components/solid-ui/index.js +3 -0
- package/dist/components/solid-ui/index.js.map +1 -0
- package/dist/components/solid-ui/index.ts +2 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/index.ts +3 -0
- package/dist/redux/api/solidEntityApi.d.ts.map +1 -1
- package/dist/redux/api/solidEntityApi.js +13 -0
- package/dist/redux/api/solidEntityApi.js.map +1 -1
- package/dist/redux/api/solidEntityApi.tsx +16 -0
- package/dist/redux/store/createSolidStore.d.ts +1 -1
- package/dist/redux/store/createSolidStore.d.ts.map +1 -1
- package/dist/redux/store/createSolidStore.js +20 -11
- package/dist/redux/store/createSolidStore.js.map +1 -1
- package/dist/redux/store/createSolidStore.ts +20 -11
- package/dist/redux/store/dynamicEntityApiMiddleware.d.ts +10 -0
- package/dist/redux/store/dynamicEntityApiMiddleware.d.ts.map +1 -0
- package/dist/redux/store/dynamicEntityApiMiddleware.js +44 -0
- package/dist/redux/store/dynamicEntityApiMiddleware.js.map +1 -0
- package/dist/redux/store/dynamicEntityApiMiddleware.ts +58 -0
- package/dist/redux/store/dynamicReducerManager.d.ts +10 -0
- package/dist/redux/store/dynamicReducerManager.d.ts.map +1 -0
- package/dist/redux/store/dynamicReducerManager.js +51 -0
- package/dist/redux/store/dynamicReducerManager.js.map +1 -0
- package/dist/redux/store/dynamicReducerManager.ts +51 -0
- package/dist/redux/store/solidEntityApiPool.d.ts +31 -0
- package/dist/redux/store/solidEntityApiPool.d.ts.map +1 -0
- package/dist/redux/store/solidEntityApiPool.js +123 -0
- package/dist/redux/store/solidEntityApiPool.js.map +1 -0
- package/dist/redux/store/solidEntityApiPool.ts +167 -0
- package/dist/resources/globals.css +7 -1
- package/dist/resources/shadcn-base.css +25 -9
- package/dist/routes/SolidRouteMetadataBoundary.d.ts +5 -0
- package/dist/routes/SolidRouteMetadataBoundary.d.ts.map +1 -0
- package/dist/routes/SolidRouteMetadataBoundary.js +72 -0
- package/dist/routes/SolidRouteMetadataBoundary.js.map +1 -0
- package/dist/routes/SolidRouteMetadataBoundary.tsx +77 -0
- package/dist/routes/pages/admin/core/DiagnosticsPage.d.ts +2 -0
- package/dist/routes/pages/admin/core/DiagnosticsPage.d.ts.map +1 -0
- package/dist/routes/pages/admin/core/DiagnosticsPage.js +48 -0
- package/dist/routes/pages/admin/core/DiagnosticsPage.js.map +1 -0
- package/dist/routes/pages/admin/core/DiagnosticsPage.tsx +167 -0
- package/dist/routes/pages/studio/StudioLandingPage.d.ts.map +1 -1
- package/dist/routes/pages/studio/StudioLandingPage.js +35 -7
- package/dist/routes/pages/studio/StudioLandingPage.js.map +1 -1
- package/dist/routes/pages/studio/StudioLandingPage.tsx +42 -6
- package/dist/routes/solidRoutes.d.ts.map +1 -1
- package/dist/routes/solidRoutes.js +47 -26
- package/dist/routes/solidRoutes.js.map +1 -1
- package/dist/routes/solidRoutes.tsx +47 -26
- package/dist/routes/types.d.ts +7 -0
- package/dist/routes/types.d.ts.map +1 -1
- package/dist/routes/types.js.map +1 -1
- package/dist/routes/types.ts +8 -0
- package/package.json +1 -1
- package/dist/components/auth/SolidOTPVerify.d.ts +0 -3
- package/dist/components/auth/SolidOTPVerify.d.ts.map +0 -1
- package/dist/components/auth/SolidOTPVerify.js +0 -67
- package/dist/components/auth/SolidOTPVerify.js.map +0 -1
- package/dist/components/auth/SolidOTPVerify.tsx +0 -133
- package/dist/components/core/common/LoadDynamicJsxComponent.d.ts +0 -2
- package/dist/components/core/common/LoadDynamicJsxComponent.d.ts.map +0 -1
- package/dist/components/core/common/LoadDynamicJsxComponent.js +0 -50
- package/dist/components/core/common/LoadDynamicJsxComponent.js.map +0 -1
- package/dist/components/core/common/LoadDynamicJsxComponent.tsx +0 -70
- package/dist/nextAuth/authProviders.d.ts +0 -4
- package/dist/nextAuth/authProviders.d.ts.map +0 -1
- package/dist/nextAuth/authProviders.js +0 -198
- package/dist/nextAuth/authProviders.js.map +0 -1
- package/dist/nextAuth/authProviders.tsx +0 -232
- package/dist/nextAuth/handleLogout.d.ts +0 -2
- package/dist/nextAuth/handleLogout.d.ts.map +0 -1
- package/dist/nextAuth/handleLogout.js +0 -36
- package/dist/nextAuth/handleLogout.js.map +0 -1
- package/dist/nextAuth/handleLogout.tsx +0 -39
- package/dist/nextAuth/refreshAccessToken.d.ts +0 -2
- package/dist/nextAuth/refreshAccessToken.d.ts.map +0 -1
- package/dist/nextAuth/refreshAccessToken.js +0 -24
- package/dist/nextAuth/refreshAccessToken.js.map +0 -1
- package/dist/nextAuth/refreshAccessToken.tsx +0 -28
- package/dist/redux/features/settingsSlice.d.ts +0 -20
- package/dist/redux/features/settingsSlice.d.ts.map +0 -1
- package/dist/redux/features/settingsSlice.js +0 -39
- package/dist/redux/features/settingsSlice.js.map +0 -1
- package/dist/redux/features/settingsSlice.ts +0 -60
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Middleware, MiddlewareAPI } from "@reduxjs/toolkit";
|
|
2
|
+
|
|
3
|
+
type MiddlewareWithApi = ReturnType<Middleware>;
|
|
4
|
+
|
|
5
|
+
export type DynamicEntityApiMiddlewareManager = {
|
|
6
|
+
middleware: Middleware;
|
|
7
|
+
add: (key: string, middleware: Middleware) => boolean;
|
|
8
|
+
remove: (key: string) => boolean;
|
|
9
|
+
has: (key: string) => boolean;
|
|
10
|
+
keys: () => string[];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function createDynamicEntityApiMiddlewareManager(): DynamicEntityApiMiddlewareManager {
|
|
14
|
+
const middlewares = new Map<string, Middleware>();
|
|
15
|
+
let middlewareApi: MiddlewareAPI | null = null;
|
|
16
|
+
const handlers = new Map<string, MiddlewareWithApi>();
|
|
17
|
+
|
|
18
|
+
const manager: DynamicEntityApiMiddlewareManager = {
|
|
19
|
+
middleware: (api) => {
|
|
20
|
+
middlewareApi = api;
|
|
21
|
+
middlewares.forEach((middleware, key) => {
|
|
22
|
+
if (!handlers.has(key)) {
|
|
23
|
+
handlers.set(key, middleware(api));
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return (next) => (action) => {
|
|
28
|
+
const chain = Array.from(handlers.values());
|
|
29
|
+
const dynamicNext = chain.reduceRight((nextHandler, handler) => handler(nextHandler), next);
|
|
30
|
+
return dynamicNext(action);
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
add(key, middleware) {
|
|
34
|
+
if (!key || middlewares.has(key)) return false;
|
|
35
|
+
|
|
36
|
+
middlewares.set(key, middleware);
|
|
37
|
+
if (middlewareApi) {
|
|
38
|
+
handlers.set(key, middleware(middlewareApi));
|
|
39
|
+
}
|
|
40
|
+
return true;
|
|
41
|
+
},
|
|
42
|
+
remove(key) {
|
|
43
|
+
if (!middlewares.has(key)) return false;
|
|
44
|
+
|
|
45
|
+
middlewares.delete(key);
|
|
46
|
+
handlers.delete(key);
|
|
47
|
+
return true;
|
|
48
|
+
},
|
|
49
|
+
has(key) {
|
|
50
|
+
return middlewares.has(key);
|
|
51
|
+
},
|
|
52
|
+
keys() {
|
|
53
|
+
return Array.from(middlewares.keys());
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return manager;
|
|
58
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Reducer, ReducersMapObject } from "@reduxjs/toolkit";
|
|
2
|
+
export type DynamicReducerManager = {
|
|
3
|
+
reduce: Reducer;
|
|
4
|
+
add: (key: string, reducer: Reducer) => boolean;
|
|
5
|
+
remove: (key: string) => boolean;
|
|
6
|
+
has: (key: string) => boolean;
|
|
7
|
+
getReducerMap: () => ReducersMapObject;
|
|
8
|
+
};
|
|
9
|
+
export declare function createDynamicReducerManager(initialReducers: ReducersMapObject): DynamicReducerManager;
|
|
10
|
+
//# sourceMappingURL=dynamicReducerManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamicReducerManager.d.ts","sourceRoot":"","sources":["../../../src/redux/store/dynamicReducerManager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAa,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE9E,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;IAChD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACjC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9B,aAAa,EAAE,MAAM,iBAAiB,CAAC;CACxC,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,eAAe,EAAE,iBAAiB,GAAG,qBAAqB,CAuCrG"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { combineReducers } from "@reduxjs/toolkit";
|
|
13
|
+
export function createDynamicReducerManager(initialReducers) {
|
|
14
|
+
var reducers = __assign({}, initialReducers);
|
|
15
|
+
var combinedReducer = combineReducers(reducers);
|
|
16
|
+
var keysToRemove = [];
|
|
17
|
+
return {
|
|
18
|
+
reduce: function (state, action) {
|
|
19
|
+
if (keysToRemove.length > 0 && state) {
|
|
20
|
+
state = __assign({}, state);
|
|
21
|
+
keysToRemove.forEach(function (key) {
|
|
22
|
+
delete state[key];
|
|
23
|
+
});
|
|
24
|
+
keysToRemove = [];
|
|
25
|
+
}
|
|
26
|
+
return combinedReducer(state, action);
|
|
27
|
+
},
|
|
28
|
+
add: function (key, reducer) {
|
|
29
|
+
if (!key || reducers[key])
|
|
30
|
+
return false;
|
|
31
|
+
reducers[key] = reducer;
|
|
32
|
+
combinedReducer = combineReducers(reducers);
|
|
33
|
+
return true;
|
|
34
|
+
},
|
|
35
|
+
remove: function (key) {
|
|
36
|
+
if (!key || !reducers[key])
|
|
37
|
+
return false;
|
|
38
|
+
delete reducers[key];
|
|
39
|
+
keysToRemove.push(key);
|
|
40
|
+
combinedReducer = combineReducers(reducers);
|
|
41
|
+
return true;
|
|
42
|
+
},
|
|
43
|
+
has: function (key) {
|
|
44
|
+
return Boolean(reducers[key]);
|
|
45
|
+
},
|
|
46
|
+
getReducerMap: function () {
|
|
47
|
+
return __assign({}, reducers);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=dynamicReducerManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dynamicReducerManager.js","sourceRoot":"","sources":["../../../src/redux/store/dynamicReducerManager.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAWnD,MAAM,UAAU,2BAA2B,CAAC,eAAkC;IAC5E,IAAM,QAAQ,gBAA2B,eAAe,CAAE,CAAC;IAC3D,IAAI,eAAe,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,YAAY,GAAa,EAAE,CAAC;IAEhC,OAAO;QACL,MAAM,YAAC,KAAU,EAAE,MAAiB;YAClC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,EAAE;gBACpC,KAAK,gBAAQ,KAAK,CAAE,CAAC;gBACrB,YAAY,CAAC,OAAO,CAAC,UAAC,GAAG;oBACvB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;gBACpB,CAAC,CAAC,CAAC;gBACH,YAAY,GAAG,EAAE,CAAC;aACnB;YAED,OAAO,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,GAAG,YAAC,GAAW,EAAE,OAAgB;YAC/B,IAAI,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YAExC,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;YACxB,eAAe,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,YAAC,GAAW;YAChB,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YAEzC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;YACrB,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvB,eAAe,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,GAAG,YAAC,GAAW;YACb,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QAChC,CAAC;QACD,aAAa;YACX,oBAAY,QAAQ,EAAG;QACzB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { combineReducers } from \"@reduxjs/toolkit\";\nimport type { AnyAction, Reducer, ReducersMapObject } from \"@reduxjs/toolkit\";\n\nexport type DynamicReducerManager = {\n reduce: Reducer;\n add: (key: string, reducer: Reducer) => boolean;\n remove: (key: string) => boolean;\n has: (key: string) => boolean;\n getReducerMap: () => ReducersMapObject;\n};\n\nexport function createDynamicReducerManager(initialReducers: ReducersMapObject): DynamicReducerManager {\n const reducers: ReducersMapObject = { ...initialReducers };\n let combinedReducer = combineReducers(reducers);\n let keysToRemove: string[] = [];\n\n return {\n reduce(state: any, action: AnyAction) {\n if (keysToRemove.length > 0 && state) {\n state = { ...state };\n keysToRemove.forEach((key) => {\n delete state[key];\n });\n keysToRemove = [];\n }\n\n return combinedReducer(state, action);\n },\n add(key: string, reducer: Reducer) {\n if (!key || reducers[key]) return false;\n\n reducers[key] = reducer;\n combinedReducer = combineReducers(reducers);\n return true;\n },\n remove(key: string) {\n if (!key || !reducers[key]) return false;\n\n delete reducers[key];\n keysToRemove.push(key);\n combinedReducer = combineReducers(reducers);\n return true;\n },\n has(key: string) {\n return Boolean(reducers[key]);\n },\n getReducerMap() {\n return { ...reducers };\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { combineReducers } from "@reduxjs/toolkit";
|
|
2
|
+
import type { AnyAction, Reducer, ReducersMapObject } from "@reduxjs/toolkit";
|
|
3
|
+
|
|
4
|
+
export type DynamicReducerManager = {
|
|
5
|
+
reduce: Reducer;
|
|
6
|
+
add: (key: string, reducer: Reducer) => boolean;
|
|
7
|
+
remove: (key: string) => boolean;
|
|
8
|
+
has: (key: string) => boolean;
|
|
9
|
+
getReducerMap: () => ReducersMapObject;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function createDynamicReducerManager(initialReducers: ReducersMapObject): DynamicReducerManager {
|
|
13
|
+
const reducers: ReducersMapObject = { ...initialReducers };
|
|
14
|
+
let combinedReducer = combineReducers(reducers);
|
|
15
|
+
let keysToRemove: string[] = [];
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
reduce(state: any, action: AnyAction) {
|
|
19
|
+
if (keysToRemove.length > 0 && state) {
|
|
20
|
+
state = { ...state };
|
|
21
|
+
keysToRemove.forEach((key) => {
|
|
22
|
+
delete state[key];
|
|
23
|
+
});
|
|
24
|
+
keysToRemove = [];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return combinedReducer(state, action);
|
|
28
|
+
},
|
|
29
|
+
add(key: string, reducer: Reducer) {
|
|
30
|
+
if (!key || reducers[key]) return false;
|
|
31
|
+
|
|
32
|
+
reducers[key] = reducer;
|
|
33
|
+
combinedReducer = combineReducers(reducers);
|
|
34
|
+
return true;
|
|
35
|
+
},
|
|
36
|
+
remove(key: string) {
|
|
37
|
+
if (!key || !reducers[key]) return false;
|
|
38
|
+
|
|
39
|
+
delete reducers[key];
|
|
40
|
+
keysToRemove.push(key);
|
|
41
|
+
combinedReducer = combineReducers(reducers);
|
|
42
|
+
return true;
|
|
43
|
+
},
|
|
44
|
+
has(key: string) {
|
|
45
|
+
return Boolean(reducers[key]);
|
|
46
|
+
},
|
|
47
|
+
getReducerMap() {
|
|
48
|
+
return { ...reducers };
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AnyAction, Dispatch, Middleware, Reducer } from "@reduxjs/toolkit";
|
|
2
|
+
import type { DynamicEntityApiMiddlewareManager } from "./dynamicEntityApiMiddleware";
|
|
3
|
+
import type { DynamicReducerManager } from "./dynamicReducerManager";
|
|
4
|
+
export declare const SOLID_ENTITY_API_POOL_LIMIT = 64;
|
|
5
|
+
type SolidEntityApi = {
|
|
6
|
+
reducerPath: string;
|
|
7
|
+
reducer: Reducer;
|
|
8
|
+
middleware: Middleware;
|
|
9
|
+
util?: {
|
|
10
|
+
resetApiState?: () => AnyAction;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
type SolidEntityApiStore = {
|
|
14
|
+
dispatch: Dispatch;
|
|
15
|
+
getState: () => any;
|
|
16
|
+
replaceReducer: (nextReducer: Reducer) => void;
|
|
17
|
+
reducerManager: DynamicReducerManager;
|
|
18
|
+
middlewareManager: DynamicEntityApiMiddlewareManager;
|
|
19
|
+
};
|
|
20
|
+
export declare function setSolidEntityApiStore(store: SolidEntityApiStore): void;
|
|
21
|
+
export declare function ensureSolidEntityApiRegistered(entityName: string, api: SolidEntityApi): void;
|
|
22
|
+
export declare function getSolidEntityApiPoolSnapshot(): {
|
|
23
|
+
entityName: string;
|
|
24
|
+
reducerPath: string;
|
|
25
|
+
registeredAt: number;
|
|
26
|
+
lastAccessedAt: number;
|
|
27
|
+
active: boolean;
|
|
28
|
+
}[];
|
|
29
|
+
export declare function resetSolidEntityApiPoolForTests(): void;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=solidEntityApiPool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solidEntityApiPool.d.ts","sourceRoot":"","sources":["../../../src/redux/store/solidEntityApiPool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,8BAA8B,CAAC;AACtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAErE,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,KAAK,cAAc,GAAG;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,CAAC,EAAE;QACL,aAAa,CAAC,EAAE,MAAM,SAAS,CAAC;KACjC,CAAC;CACH,CAAC;AASF,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,CAAC;IACpB,cAAc,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,qBAAqB,CAAC;IACtC,iBAAiB,EAAE,iCAAiC,CAAC;CACtD,CAAC;AA4FF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,QAEhE;AAED,wBAAgB,8BAA8B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,QAgCrF;AAED,wBAAgB,6BAA6B;;;;;;IAE5C;AAED,wBAAgB,+BAA+B,SAI9C"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
export var SOLID_ENTITY_API_POOL_LIMIT = 64;
|
|
2
|
+
var activeStore = null;
|
|
3
|
+
var clock = 0;
|
|
4
|
+
var pool = new Map();
|
|
5
|
+
function nextTimestamp() {
|
|
6
|
+
clock += 1;
|
|
7
|
+
return clock;
|
|
8
|
+
}
|
|
9
|
+
function log(message, data) {
|
|
10
|
+
// Centralized logs make pool behavior easy to trace in consuming apps.
|
|
11
|
+
console.info("[SolidEntityApiPool] ".concat(message), data !== null && data !== void 0 ? data : {});
|
|
12
|
+
}
|
|
13
|
+
function warn(message, data) {
|
|
14
|
+
console.warn("[SolidEntityApiPool] ".concat(message), data !== null && data !== void 0 ? data : {});
|
|
15
|
+
}
|
|
16
|
+
function getLiveSnapshot() {
|
|
17
|
+
return Array.from(pool.values()).map(function (entry) { return ({
|
|
18
|
+
entityName: entry.entityName,
|
|
19
|
+
reducerPath: entry.api.reducerPath,
|
|
20
|
+
registeredAt: entry.registeredAt,
|
|
21
|
+
lastAccessedAt: entry.lastAccessedAt,
|
|
22
|
+
active: Boolean(activeStore === null || activeStore === void 0 ? void 0 : activeStore.middlewareManager.has(entry.api.reducerPath)),
|
|
23
|
+
}); });
|
|
24
|
+
}
|
|
25
|
+
function getActiveEntries() {
|
|
26
|
+
return Array.from(pool.values()).filter(function (entry) { return activeStore === null || activeStore === void 0 ? void 0 : activeStore.middlewareManager.has(entry.api.reducerPath); });
|
|
27
|
+
}
|
|
28
|
+
function hasActiveUsage(entry) {
|
|
29
|
+
var _a, _b, _c, _d;
|
|
30
|
+
if (!activeStore)
|
|
31
|
+
return false;
|
|
32
|
+
var state = (_a = activeStore.getState()) === null || _a === void 0 ? void 0 : _a[entry.api.reducerPath];
|
|
33
|
+
if (!state)
|
|
34
|
+
return false;
|
|
35
|
+
var hasSubscriptions = Object.values((_b = state.subscriptions) !== null && _b !== void 0 ? _b : {}).some(function (subscription) {
|
|
36
|
+
return subscription && Object.keys(subscription).length > 0;
|
|
37
|
+
});
|
|
38
|
+
var hasPendingQueries = Object.values((_c = state.queries) !== null && _c !== void 0 ? _c : {}).some(function (query) { return (query === null || query === void 0 ? void 0 : query.status) === "pending"; });
|
|
39
|
+
var hasPendingMutations = Object.values((_d = state.mutations) !== null && _d !== void 0 ? _d : {}).some(function (mutation) { return (mutation === null || mutation === void 0 ? void 0 : mutation.status) === "pending"; });
|
|
40
|
+
return hasSubscriptions || hasPendingQueries || hasPendingMutations;
|
|
41
|
+
}
|
|
42
|
+
function findEvictionCandidate() {
|
|
43
|
+
var _a;
|
|
44
|
+
return (_a = getActiveEntries()
|
|
45
|
+
.filter(function (entry) { return !hasActiveUsage(entry); })
|
|
46
|
+
.sort(function (left, right) { return left.lastAccessedAt - right.lastAccessedAt; })[0]) !== null && _a !== void 0 ? _a : null;
|
|
47
|
+
}
|
|
48
|
+
function evictIfNeeded(nextEntityName) {
|
|
49
|
+
var _a;
|
|
50
|
+
if (!activeStore)
|
|
51
|
+
return;
|
|
52
|
+
var activeEntries = getActiveEntries();
|
|
53
|
+
if (activeEntries.length < SOLID_ENTITY_API_POOL_LIMIT)
|
|
54
|
+
return;
|
|
55
|
+
warn("Pool is full; attempting LRU eviction.", {
|
|
56
|
+
limit: SOLID_ENTITY_API_POOL_LIMIT,
|
|
57
|
+
requestedEntityName: nextEntityName,
|
|
58
|
+
activeCount: activeEntries.length,
|
|
59
|
+
});
|
|
60
|
+
var candidate = findEvictionCandidate();
|
|
61
|
+
if (!candidate) {
|
|
62
|
+
warn("Pool is full but all entries look active; allowing temporary overflow.", {
|
|
63
|
+
limit: SOLID_ENTITY_API_POOL_LIMIT,
|
|
64
|
+
requestedEntityName: nextEntityName,
|
|
65
|
+
activeCount: activeEntries.length,
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
var resetApiState = (_a = candidate.api.util) === null || _a === void 0 ? void 0 : _a.resetApiState;
|
|
70
|
+
if (resetApiState) {
|
|
71
|
+
activeStore.dispatch(resetApiState());
|
|
72
|
+
}
|
|
73
|
+
activeStore.middlewareManager.remove(candidate.api.reducerPath);
|
|
74
|
+
activeStore.reducerManager.remove(candidate.api.reducerPath);
|
|
75
|
+
activeStore.replaceReducer(activeStore.reducerManager.reduce);
|
|
76
|
+
log("Evicted entity API from pool.", {
|
|
77
|
+
entityName: candidate.entityName,
|
|
78
|
+
reducerPath: candidate.api.reducerPath,
|
|
79
|
+
requestedEntityName: nextEntityName,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export function setSolidEntityApiStore(store) {
|
|
83
|
+
activeStore = store;
|
|
84
|
+
}
|
|
85
|
+
export function ensureSolidEntityApiRegistered(entityName, api) {
|
|
86
|
+
var timestamp = nextTimestamp();
|
|
87
|
+
var existingEntry = pool.get(entityName);
|
|
88
|
+
if (existingEntry) {
|
|
89
|
+
existingEntry.lastAccessedAt = timestamp;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
pool.set(entityName, {
|
|
93
|
+
entityName: entityName,
|
|
94
|
+
api: api,
|
|
95
|
+
registeredAt: timestamp,
|
|
96
|
+
lastAccessedAt: timestamp,
|
|
97
|
+
});
|
|
98
|
+
log("Created entity API cache entry.", {
|
|
99
|
+
entityName: entityName,
|
|
100
|
+
reducerPath: api.reducerPath,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
if (!activeStore || activeStore.middlewareManager.has(api.reducerPath))
|
|
104
|
+
return;
|
|
105
|
+
evictIfNeeded(entityName);
|
|
106
|
+
activeStore.reducerManager.add(api.reducerPath, api.reducer);
|
|
107
|
+
activeStore.middlewareManager.add(api.reducerPath, api.middleware);
|
|
108
|
+
log("Dynamically registered entity API reducer and middleware.", {
|
|
109
|
+
entityName: entityName,
|
|
110
|
+
reducerPath: api.reducerPath,
|
|
111
|
+
activeCount: getActiveEntries().length,
|
|
112
|
+
limit: SOLID_ENTITY_API_POOL_LIMIT,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
export function getSolidEntityApiPoolSnapshot() {
|
|
116
|
+
return getLiveSnapshot();
|
|
117
|
+
}
|
|
118
|
+
export function resetSolidEntityApiPoolForTests() {
|
|
119
|
+
activeStore = null;
|
|
120
|
+
clock = 0;
|
|
121
|
+
pool.clear();
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=solidEntityApiPool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solidEntityApiPool.js","sourceRoot":"","sources":["../../../src/redux/store/solidEntityApiPool.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnyAction, Dispatch, Middleware, Reducer } from \"@reduxjs/toolkit\";\nimport type { DynamicEntityApiMiddlewareManager } from \"./dynamicEntityApiMiddleware\";\nimport type { DynamicReducerManager } from \"./dynamicReducerManager\";\n\nexport const SOLID_ENTITY_API_POOL_LIMIT = 64;\n\ntype SolidEntityApi = {\n reducerPath: string;\n reducer: Reducer;\n middleware: Middleware;\n util?: {\n resetApiState?: () => AnyAction;\n };\n};\n\ntype SolidEntityApiPoolEntry = {\n entityName: string;\n api: SolidEntityApi;\n registeredAt: number;\n lastAccessedAt: number;\n};\n\ntype SolidEntityApiStore = {\n dispatch: Dispatch;\n getState: () => any;\n replaceReducer: (nextReducer: Reducer) => void;\n reducerManager: DynamicReducerManager;\n middlewareManager: DynamicEntityApiMiddlewareManager;\n};\n\nlet activeStore: SolidEntityApiStore | null = null;\nlet clock = 0;\nconst pool = new Map<string, SolidEntityApiPoolEntry>();\n\nfunction nextTimestamp() {\n clock += 1;\n return clock;\n}\n\nfunction log(message: string, data?: Record<string, unknown>) {\n // Centralized logs make pool behavior easy to trace in consuming apps.\n console.info(`[SolidEntityApiPool] ${message}`, data ?? {});\n}\n\nfunction warn(message: string, data?: Record<string, unknown>) {\n console.warn(`[SolidEntityApiPool] ${message}`, data ?? {});\n}\n\nfunction getLiveSnapshot() {\n return Array.from(pool.values()).map((entry) => ({\n entityName: entry.entityName,\n reducerPath: entry.api.reducerPath,\n registeredAt: entry.registeredAt,\n lastAccessedAt: entry.lastAccessedAt,\n active: Boolean(activeStore?.middlewareManager.has(entry.api.reducerPath)),\n }));\n}\n\nfunction getActiveEntries() {\n return Array.from(pool.values()).filter((entry) => activeStore?.middlewareManager.has(entry.api.reducerPath));\n}\n\nfunction hasActiveUsage(entry: SolidEntityApiPoolEntry) {\n if (!activeStore) return false;\n\n const state = activeStore.getState()?.[entry.api.reducerPath];\n if (!state) return false;\n\n const hasSubscriptions = Object.values(state.subscriptions ?? {}).some((subscription: any) => {\n return subscription && Object.keys(subscription).length > 0;\n });\n const hasPendingQueries = Object.values(state.queries ?? {}).some((query: any) => query?.status === \"pending\");\n const hasPendingMutations = Object.values(state.mutations ?? {}).some((mutation: any) => mutation?.status === \"pending\");\n\n return hasSubscriptions || hasPendingQueries || hasPendingMutations;\n}\n\nfunction findEvictionCandidate() {\n return getActiveEntries()\n .filter((entry) => !hasActiveUsage(entry))\n .sort((left, right) => left.lastAccessedAt - right.lastAccessedAt)[0] ?? null;\n}\n\nfunction evictIfNeeded(nextEntityName: string) {\n if (!activeStore) return;\n\n const activeEntries = getActiveEntries();\n if (activeEntries.length < SOLID_ENTITY_API_POOL_LIMIT) return;\n\n warn(\"Pool is full; attempting LRU eviction.\", {\n limit: SOLID_ENTITY_API_POOL_LIMIT,\n requestedEntityName: nextEntityName,\n activeCount: activeEntries.length,\n });\n\n const candidate = findEvictionCandidate();\n if (!candidate) {\n warn(\"Pool is full but all entries look active; allowing temporary overflow.\", {\n limit: SOLID_ENTITY_API_POOL_LIMIT,\n requestedEntityName: nextEntityName,\n activeCount: activeEntries.length,\n });\n return;\n }\n\n const resetApiState = candidate.api.util?.resetApiState;\n if (resetApiState) {\n activeStore.dispatch(resetApiState());\n }\n activeStore.middlewareManager.remove(candidate.api.reducerPath);\n activeStore.reducerManager.remove(candidate.api.reducerPath);\n activeStore.replaceReducer(activeStore.reducerManager.reduce);\n\n log(\"Evicted entity API from pool.\", {\n entityName: candidate.entityName,\n reducerPath: candidate.api.reducerPath,\n requestedEntityName: nextEntityName,\n });\n}\n\nexport function setSolidEntityApiStore(store: SolidEntityApiStore) {\n activeStore = store;\n}\n\nexport function ensureSolidEntityApiRegistered(entityName: string, api: SolidEntityApi) {\n const timestamp = nextTimestamp();\n const existingEntry = pool.get(entityName);\n\n if (existingEntry) {\n existingEntry.lastAccessedAt = timestamp;\n } else {\n pool.set(entityName, {\n entityName,\n api,\n registeredAt: timestamp,\n lastAccessedAt: timestamp,\n });\n log(\"Created entity API cache entry.\", {\n entityName,\n reducerPath: api.reducerPath,\n });\n }\n\n if (!activeStore || activeStore.middlewareManager.has(api.reducerPath)) return;\n\n evictIfNeeded(entityName);\n\n activeStore.reducerManager.add(api.reducerPath, api.reducer);\n activeStore.middlewareManager.add(api.reducerPath, api.middleware);\n\n log(\"Dynamically registered entity API reducer and middleware.\", {\n entityName,\n reducerPath: api.reducerPath,\n activeCount: getActiveEntries().length,\n limit: SOLID_ENTITY_API_POOL_LIMIT,\n });\n}\n\nexport function getSolidEntityApiPoolSnapshot() {\n return getLiveSnapshot();\n}\n\nexport function resetSolidEntityApiPoolForTests() {\n activeStore = null;\n clock = 0;\n pool.clear();\n}\n"]}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import type { AnyAction, Dispatch, Middleware, Reducer } from "@reduxjs/toolkit";
|
|
2
|
+
import type { DynamicEntityApiMiddlewareManager } from "./dynamicEntityApiMiddleware";
|
|
3
|
+
import type { DynamicReducerManager } from "./dynamicReducerManager";
|
|
4
|
+
|
|
5
|
+
export const SOLID_ENTITY_API_POOL_LIMIT = 64;
|
|
6
|
+
|
|
7
|
+
type SolidEntityApi = {
|
|
8
|
+
reducerPath: string;
|
|
9
|
+
reducer: Reducer;
|
|
10
|
+
middleware: Middleware;
|
|
11
|
+
util?: {
|
|
12
|
+
resetApiState?: () => AnyAction;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
type SolidEntityApiPoolEntry = {
|
|
17
|
+
entityName: string;
|
|
18
|
+
api: SolidEntityApi;
|
|
19
|
+
registeredAt: number;
|
|
20
|
+
lastAccessedAt: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type SolidEntityApiStore = {
|
|
24
|
+
dispatch: Dispatch;
|
|
25
|
+
getState: () => any;
|
|
26
|
+
replaceReducer: (nextReducer: Reducer) => void;
|
|
27
|
+
reducerManager: DynamicReducerManager;
|
|
28
|
+
middlewareManager: DynamicEntityApiMiddlewareManager;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
let activeStore: SolidEntityApiStore | null = null;
|
|
32
|
+
let clock = 0;
|
|
33
|
+
const pool = new Map<string, SolidEntityApiPoolEntry>();
|
|
34
|
+
|
|
35
|
+
function nextTimestamp() {
|
|
36
|
+
clock += 1;
|
|
37
|
+
return clock;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function log(message: string, data?: Record<string, unknown>) {
|
|
41
|
+
// Centralized logs make pool behavior easy to trace in consuming apps.
|
|
42
|
+
console.info(`[SolidEntityApiPool] ${message}`, data ?? {});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function warn(message: string, data?: Record<string, unknown>) {
|
|
46
|
+
console.warn(`[SolidEntityApiPool] ${message}`, data ?? {});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getLiveSnapshot() {
|
|
50
|
+
return Array.from(pool.values()).map((entry) => ({
|
|
51
|
+
entityName: entry.entityName,
|
|
52
|
+
reducerPath: entry.api.reducerPath,
|
|
53
|
+
registeredAt: entry.registeredAt,
|
|
54
|
+
lastAccessedAt: entry.lastAccessedAt,
|
|
55
|
+
active: Boolean(activeStore?.middlewareManager.has(entry.api.reducerPath)),
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getActiveEntries() {
|
|
60
|
+
return Array.from(pool.values()).filter((entry) => activeStore?.middlewareManager.has(entry.api.reducerPath));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function hasActiveUsage(entry: SolidEntityApiPoolEntry) {
|
|
64
|
+
if (!activeStore) return false;
|
|
65
|
+
|
|
66
|
+
const state = activeStore.getState()?.[entry.api.reducerPath];
|
|
67
|
+
if (!state) return false;
|
|
68
|
+
|
|
69
|
+
const hasSubscriptions = Object.values(state.subscriptions ?? {}).some((subscription: any) => {
|
|
70
|
+
return subscription && Object.keys(subscription).length > 0;
|
|
71
|
+
});
|
|
72
|
+
const hasPendingQueries = Object.values(state.queries ?? {}).some((query: any) => query?.status === "pending");
|
|
73
|
+
const hasPendingMutations = Object.values(state.mutations ?? {}).some((mutation: any) => mutation?.status === "pending");
|
|
74
|
+
|
|
75
|
+
return hasSubscriptions || hasPendingQueries || hasPendingMutations;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function findEvictionCandidate() {
|
|
79
|
+
return getActiveEntries()
|
|
80
|
+
.filter((entry) => !hasActiveUsage(entry))
|
|
81
|
+
.sort((left, right) => left.lastAccessedAt - right.lastAccessedAt)[0] ?? null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function evictIfNeeded(nextEntityName: string) {
|
|
85
|
+
if (!activeStore) return;
|
|
86
|
+
|
|
87
|
+
const activeEntries = getActiveEntries();
|
|
88
|
+
if (activeEntries.length < SOLID_ENTITY_API_POOL_LIMIT) return;
|
|
89
|
+
|
|
90
|
+
warn("Pool is full; attempting LRU eviction.", {
|
|
91
|
+
limit: SOLID_ENTITY_API_POOL_LIMIT,
|
|
92
|
+
requestedEntityName: nextEntityName,
|
|
93
|
+
activeCount: activeEntries.length,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const candidate = findEvictionCandidate();
|
|
97
|
+
if (!candidate) {
|
|
98
|
+
warn("Pool is full but all entries look active; allowing temporary overflow.", {
|
|
99
|
+
limit: SOLID_ENTITY_API_POOL_LIMIT,
|
|
100
|
+
requestedEntityName: nextEntityName,
|
|
101
|
+
activeCount: activeEntries.length,
|
|
102
|
+
});
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const resetApiState = candidate.api.util?.resetApiState;
|
|
107
|
+
if (resetApiState) {
|
|
108
|
+
activeStore.dispatch(resetApiState());
|
|
109
|
+
}
|
|
110
|
+
activeStore.middlewareManager.remove(candidate.api.reducerPath);
|
|
111
|
+
activeStore.reducerManager.remove(candidate.api.reducerPath);
|
|
112
|
+
activeStore.replaceReducer(activeStore.reducerManager.reduce);
|
|
113
|
+
|
|
114
|
+
log("Evicted entity API from pool.", {
|
|
115
|
+
entityName: candidate.entityName,
|
|
116
|
+
reducerPath: candidate.api.reducerPath,
|
|
117
|
+
requestedEntityName: nextEntityName,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function setSolidEntityApiStore(store: SolidEntityApiStore) {
|
|
122
|
+
activeStore = store;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function ensureSolidEntityApiRegistered(entityName: string, api: SolidEntityApi) {
|
|
126
|
+
const timestamp = nextTimestamp();
|
|
127
|
+
const existingEntry = pool.get(entityName);
|
|
128
|
+
|
|
129
|
+
if (existingEntry) {
|
|
130
|
+
existingEntry.lastAccessedAt = timestamp;
|
|
131
|
+
} else {
|
|
132
|
+
pool.set(entityName, {
|
|
133
|
+
entityName,
|
|
134
|
+
api,
|
|
135
|
+
registeredAt: timestamp,
|
|
136
|
+
lastAccessedAt: timestamp,
|
|
137
|
+
});
|
|
138
|
+
log("Created entity API cache entry.", {
|
|
139
|
+
entityName,
|
|
140
|
+
reducerPath: api.reducerPath,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (!activeStore || activeStore.middlewareManager.has(api.reducerPath)) return;
|
|
145
|
+
|
|
146
|
+
evictIfNeeded(entityName);
|
|
147
|
+
|
|
148
|
+
activeStore.reducerManager.add(api.reducerPath, api.reducer);
|
|
149
|
+
activeStore.middlewareManager.add(api.reducerPath, api.middleware);
|
|
150
|
+
|
|
151
|
+
log("Dynamically registered entity API reducer and middleware.", {
|
|
152
|
+
entityName,
|
|
153
|
+
reducerPath: api.reducerPath,
|
|
154
|
+
activeCount: getActiveEntries().length,
|
|
155
|
+
limit: SOLID_ENTITY_API_POOL_LIMIT,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function getSolidEntityApiPoolSnapshot() {
|
|
160
|
+
return getLiveSnapshot();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function resetSolidEntityApiPoolForTests() {
|
|
164
|
+
activeStore = null;
|
|
165
|
+
clock = 0;
|
|
166
|
+
pool.clear();
|
|
167
|
+
}
|
|
@@ -2753,6 +2753,10 @@ li.header-li-px {
|
|
|
2753
2753
|
height: auto;
|
|
2754
2754
|
}
|
|
2755
2755
|
|
|
2756
|
+
.solid-custom-filter-wrapper {
|
|
2757
|
+
z-index: 85;
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2756
2760
|
.custom-filter-button {
|
|
2757
2761
|
border-right: 0;
|
|
2758
2762
|
border-top: 0;
|
|
@@ -2897,6 +2901,7 @@ li.header-li-px {
|
|
|
2897
2901
|
.solid-chip-manager-panel {
|
|
2898
2902
|
top: calc(100% + 6px);
|
|
2899
2903
|
left: 0;
|
|
2904
|
+
z-index: 90 !important;
|
|
2900
2905
|
width: min(360px, 100%);
|
|
2901
2906
|
background: var(--card);
|
|
2902
2907
|
border: 1px solid color-mix(in srgb, var(--border) 86%, transparent);
|
|
@@ -3880,7 +3885,8 @@ li.header-li-px {
|
|
|
3880
3885
|
|
|
3881
3886
|
.solid-search-overlay-pannel {
|
|
3882
3887
|
top: calc(100% + 4px) !important;
|
|
3883
|
-
|
|
3888
|
+
/* Keep above datatable sticky headers/columns and other elevated surfaces. */
|
|
3889
|
+
z-index: 1004 !important;
|
|
3884
3890
|
background: var(--card);
|
|
3885
3891
|
border: 1px solid color-mix(in srgb, var(--border) 86%, transparent) !important;
|
|
3886
3892
|
border-radius: 10px;
|
|
@@ -846,13 +846,16 @@ body {
|
|
|
846
846
|
|
|
847
847
|
.solid-toast-viewport {
|
|
848
848
|
position: fixed;
|
|
849
|
-
top:
|
|
850
|
-
|
|
849
|
+
top: 10px;
|
|
850
|
+
left: 50%;
|
|
851
|
+
transform: translateX(-50%);
|
|
851
852
|
z-index: calc(var(--z-overlay) + 6);
|
|
852
853
|
display: flex;
|
|
853
854
|
flex-direction: column;
|
|
855
|
+
align-items: center;
|
|
854
856
|
gap: 10px;
|
|
855
|
-
width:
|
|
857
|
+
width: calc(100vw - 24px);
|
|
858
|
+
max-width: 100%;
|
|
856
859
|
pointer-events: none;
|
|
857
860
|
}
|
|
858
861
|
|
|
@@ -860,7 +863,7 @@ body {
|
|
|
860
863
|
display: flex;
|
|
861
864
|
align-items: flex-start;
|
|
862
865
|
gap: 10px;
|
|
863
|
-
width: 100
|
|
866
|
+
width: min(420px, 100%);
|
|
864
867
|
padding: 12px;
|
|
865
868
|
border-radius: 14px;
|
|
866
869
|
border: 1px solid color-mix(in srgb, var(--border) 88%, transparent);
|
|
@@ -1351,6 +1354,7 @@ body {
|
|
|
1351
1354
|
.solid-autocomplete {
|
|
1352
1355
|
position: relative;
|
|
1353
1356
|
width: 100%;
|
|
1357
|
+
min-width: 0;
|
|
1354
1358
|
}
|
|
1355
1359
|
|
|
1356
1360
|
.solid-autocomplete-control {
|
|
@@ -1358,6 +1362,7 @@ body {
|
|
|
1358
1362
|
display: flex;
|
|
1359
1363
|
align-items: center;
|
|
1360
1364
|
width: 100%;
|
|
1365
|
+
min-width: 0;
|
|
1361
1366
|
}
|
|
1362
1367
|
|
|
1363
1368
|
.solid-autocomplete-chip-control {
|
|
@@ -1385,6 +1390,8 @@ body {
|
|
|
1385
1390
|
min-height: 24px;
|
|
1386
1391
|
height: 24px;
|
|
1387
1392
|
flex: 1 1 110px;
|
|
1393
|
+
min-width: 0;
|
|
1394
|
+
max-width: 100%;
|
|
1388
1395
|
padding: 0 4px;
|
|
1389
1396
|
}
|
|
1390
1397
|
|
|
@@ -1458,6 +1465,8 @@ body {
|
|
|
1458
1465
|
align-items: center;
|
|
1459
1466
|
gap: 4px;
|
|
1460
1467
|
min-height: 22px;
|
|
1468
|
+
min-width: 0;
|
|
1469
|
+
max-width: 100%;
|
|
1461
1470
|
border-radius: 999px;
|
|
1462
1471
|
border: 1px solid color-mix(in srgb, var(--primary) 24%, transparent);
|
|
1463
1472
|
background: color-mix(in srgb, var(--primary) 10%, transparent);
|
|
@@ -1467,6 +1476,8 @@ body {
|
|
|
1467
1476
|
}
|
|
1468
1477
|
|
|
1469
1478
|
.solid-autocomplete-chip-label {
|
|
1479
|
+
min-width: 0;
|
|
1480
|
+
max-width: 100%;
|
|
1470
1481
|
overflow: hidden;
|
|
1471
1482
|
text-overflow: ellipsis;
|
|
1472
1483
|
white-space: nowrap;
|
|
@@ -1860,15 +1871,20 @@ body {
|
|
|
1860
1871
|
}
|
|
1861
1872
|
|
|
1862
1873
|
.solid-auth-social-grid {
|
|
1863
|
-
display:
|
|
1864
|
-
|
|
1874
|
+
display: flex;
|
|
1875
|
+
flex-wrap: wrap;
|
|
1876
|
+
justify-content: center;
|
|
1877
|
+
align-items: center;
|
|
1865
1878
|
gap: 8px;
|
|
1879
|
+
width: 100%;
|
|
1880
|
+
margin-inline: auto;
|
|
1866
1881
|
}
|
|
1867
1882
|
|
|
1868
1883
|
.solid-auth-social-btn.solid-btn {
|
|
1869
|
-
width:
|
|
1884
|
+
width: 88px;
|
|
1870
1885
|
height: 36px;
|
|
1871
1886
|
min-height: 36px;
|
|
1887
|
+
flex: 0 0 88px;
|
|
1872
1888
|
border-radius: 8px;
|
|
1873
1889
|
padding: 0;
|
|
1874
1890
|
display: inline-flex;
|
|
@@ -2826,7 +2842,7 @@ body {
|
|
|
2826
2842
|
opacity: 0.34;
|
|
2827
2843
|
}
|
|
2828
2844
|
|
|
2829
|
-
.solid-auth-theme-wrapper >
|
|
2845
|
+
.solid-auth-theme-wrapper > *:not(.solid-toast-viewport) {
|
|
2830
2846
|
position: relative;
|
|
2831
2847
|
z-index: 1;
|
|
2832
2848
|
}
|
|
@@ -4141,7 +4157,7 @@ html.dark .solid-paginator-btn:hover:not(:disabled),
|
|
|
4141
4157
|
|
|
4142
4158
|
.solid-popover-content[data-side="bottom"][data-align="end"] {
|
|
4143
4159
|
right: 0;
|
|
4144
|
-
left:
|
|
4160
|
+
left: auto;
|
|
4145
4161
|
}
|
|
4146
4162
|
|
|
4147
4163
|
.solid-popover-content[data-side="top"] {
|