akanjs 3.0.0-alpha.2 → 3.0.0-alpha.21
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/README.ko.md +1 -1
- package/README.md +1 -1
- package/base/symbols.ts +4 -0
- package/client/clientRuntime.ts +8 -0
- package/client/cn.ts +7 -0
- package/client/csrTypes.ts +2 -0
- package/client/frameDebug.ts +3 -2
- package/common/Logger.ts +4 -0
- package/common/deepObjectify.ts +21 -7
- package/common/index.ts +14 -0
- package/common/mcpExposure.ts +99 -0
- package/common/pathSet.ts +17 -5
- package/common/routeConvention.ts +30 -0
- package/constant/crystalize.ts +3 -1
- package/constant/fieldInfo.ts +6 -0
- package/constant/getDefault.ts +37 -9
- package/constant/immerify.ts +1 -1
- package/constant/index.ts +2 -0
- package/constant/labelOf.ts +17 -0
- package/constant/mask.ts +60 -0
- package/constant/purify.ts +17 -11
- package/constant/types.ts +14 -12
- package/dictionary/DictionaryLookup.ts +30 -0
- package/dictionary/agent.dictionary.ts +31 -0
- package/dictionary/agentTurn.dictionary.ts +29 -0
- package/dictionary/base.dictionary.ts +8 -0
- package/dictionary/dictInfo.ts +8 -0
- package/dictionary/dictionary.ts +9 -3
- package/dictionary/index.ts +1 -0
- package/document/database.ts +21 -0
- package/document/filterMeta.ts +7 -0
- package/document/index.ts +1 -0
- package/document/into.ts +7 -1
- package/document/noDocumentError.ts +12 -0
- package/fetch/agentTurn.ts +19 -0
- package/fetch/client/fetchClient.ts +71 -13
- package/fetch/client/wsClient.ts +17 -2
- package/fetch/fetchType/endpointFetch.type.ts +10 -4
- package/fetch/index.ts +1 -0
- package/local/apps/serverLifecycle/serverLifecycle-local.db +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local.db-shm +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local.db-wal +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-shm +0 -0
- package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-wal +0 -0
- package/package.json +11 -9
- package/server/akanApp.ts +30 -34
- package/server/akanOption.ts +65 -7
- package/server/akanServer.ts +172 -7
- package/server/animatedImage.ts +83 -0
- package/server/artifact/routeClientCache.ts +14 -0
- package/server/assetEncoding.ts +47 -0
- package/server/devtools/signalSerializer.ts +2 -2
- package/server/devtools/types.ts +2 -2
- package/server/di/diLifecycle.ts +31 -3
- package/server/di/predefinedAdaptor.ts +6 -0
- package/server/imageOptimizer.ts +33 -46
- package/server/index.ts +1 -2
- package/server/mcp/McpAuth.ts +177 -0
- package/server/mcp/McpDispatcher.ts +245 -0
- package/server/mcp/McpEventStream.ts +76 -0
- package/server/mcp/McpExecutionContext.ts +105 -0
- package/server/mcp/McpRouter.ts +591 -0
- package/server/mcp/index.ts +5 -0
- package/server/resolver/CascadeRunner.ts +1 -1
- package/server/resolver/database.resolver.ts +42 -5
- package/server/resolver/service.resolver.ts +29 -0
- package/server/resolver/signal.resolver.ts +16 -1
- package/server/routeTreeBuilder.ts +2 -44
- package/server/rscWorker.tsx +6 -2
- package/server/subRouteIndexDocument.tsx +61 -0
- package/server/systemPageDocument.tsx +2 -2
- package/server/systemPages.tsx +49 -16
- package/server/vendor/akanjs-fetch.ts +1 -0
- package/server/webRouter.ts +159 -35
- package/service/agent.service.ts +14 -0
- package/service/base.service.ts +2 -1
- package/service/index.ts +1 -0
- package/service/predefinedAdaptor/database.adaptor.ts +78 -24
- package/service/predefinedAdaptor/deepseekLlm.ts +230 -0
- package/service/predefinedAdaptor/index.ts +3 -0
- package/service/predefinedAdaptor/insightQuery.ts +183 -0
- package/service/predefinedAdaptor/llm.adaptor.ts +76 -0
- package/service/predefinedAdaptor/role.adaptor.ts +2 -0
- package/service/predefinedAdaptor/schedule.adaptor.ts +12 -5
- package/service/serviceModule.ts +17 -0
- package/service/types.ts +4 -0
- package/signal/agent/AgentCatalogue.ts +165 -0
- package/signal/agent/index.ts +1 -0
- package/signal/agent.signal.ts +42 -0
- package/signal/agentTurn.ts +8 -0
- package/signal/agentTurnStream.ts +48 -0
- package/signal/base.signal.ts +2 -1
- package/signal/endpointInfo.ts +38 -2
- package/signal/guard.ts +13 -1
- package/signal/guards.ts +52 -1
- package/signal/index.ts +6 -0
- package/signal/mcp/McpDocument.ts +286 -0
- package/signal/mcp/McpProgress.ts +106 -0
- package/signal/mcp/McpUriTemplate.ts +85 -0
- package/signal/mcp/Msg.ts +368 -0
- package/signal/mcp/index.ts +5 -0
- package/signal/mcp/mcpProtocol.ts +120 -0
- package/signal/middleware.ts +7 -3
- package/signal/openapi/openapi.ts +32 -171
- package/signal/schema/JsonSchemaBuilder.ts +211 -0
- package/signal/schema/index.ts +1 -0
- package/signal/signalContext.ts +85 -9
- package/signal/slice.ts +9 -9
- package/signal/types.ts +1 -1
- package/store/action.ts +11 -22
- package/store/actionTag.ts +33 -0
- package/store/agent/AgentBridge.ts +323 -0
- package/store/agent/AgentContext.ts +74 -0
- package/store/agent/AgentPrompts.ts +82 -0
- package/store/agent/AgentVisibility.ts +68 -0
- package/store/agent/ScreenReader.ts +208 -0
- package/store/agent/StoreCatalogue.ts +351 -0
- package/store/agent/StoreSurfaceSource.ts +122 -0
- package/store/agent/index.ts +9 -0
- package/store/agent/storeSurface.ts +28 -0
- package/store/agent/types.ts +50 -0
- package/store/agentic/StToolBuilder.ts +199 -0
- package/store/agentic/attachAgentic.ts +22 -0
- package/store/agentic/index.ts +5 -0
- package/store/agentic/readableValue.ts +17 -0
- package/store/agentic/useStExpose.ts +18 -0
- package/store/agentic/useStState.ts +35 -0
- package/store/baseSt.ts +7 -0
- package/store/databaseStateNames.ts +31 -0
- package/store/formSetterNames.ts +21 -0
- package/store/index.ts +8 -0
- package/store/rootStore.ts +3 -1
- package/store/sliceRole.ts +36 -0
- package/store/state.ts +2 -12
- package/store/store.ts +19 -1
- package/store/storeInstance.ts +165 -20
- package/store/storeRegistry.ts +16 -1
- package/store/types.ts +18 -0
- package/store/withSelector.ts +7 -8
- package/test/registerDom.ts +4 -0
- package/types/base/symbols.d.ts +4 -0
- package/types/client/cn.d.ts +5 -0
- package/types/client/csrTypes.d.ts +2 -0
- package/types/common/Logger.d.ts +2 -0
- package/types/common/deepObjectify.d.ts +4 -2
- package/types/common/index.d.ts +2 -1
- package/types/common/mcpExposure.d.ts +60 -0
- package/types/common/routeConvention.d.ts +8 -0
- package/types/constant/fieldInfo.d.ts +1 -0
- package/types/constant/getDefault.d.ts +5 -0
- package/types/constant/index.d.ts +2 -0
- package/types/constant/labelOf.d.ts +6 -0
- package/types/constant/mask.d.ts +34 -0
- package/types/constant/purify.d.ts +2 -2
- package/types/constant/types.d.ts +2 -2
- package/types/dictionary/DictionaryLookup.d.ts +14 -0
- package/types/dictionary/agent.dictionary.d.ts +1 -0
- package/types/dictionary/agentTurn.dictionary.d.ts +1 -0
- package/types/dictionary/base.dictionary.d.ts +1 -1
- package/types/dictionary/dictInfo.d.ts +6 -0
- package/types/dictionary/dictionary.d.ts +11 -9
- package/types/dictionary/index.d.ts +1 -0
- package/types/document/database.d.ts +20 -0
- package/types/document/filterMeta.d.ts +1 -0
- package/types/document/index.d.ts +1 -0
- package/types/document/into.d.ts +6 -1
- package/types/document/noDocumentError.d.ts +12 -0
- package/types/fetch/agentTurn.d.ts +593 -0
- package/types/fetch/client/fetchClient.d.ts +10 -0
- package/types/fetch/fetchType/endpointFetch.type.d.ts +5 -3
- package/types/fetch/index.d.ts +1 -0
- package/types/server/akanOption.d.ts +35 -7
- package/types/server/akanServer.d.ts +44 -1
- package/types/server/animatedImage.d.ts +7 -0
- package/types/server/artifact/routeClientCache.d.ts +6 -0
- package/types/server/assetEncoding.d.ts +7 -0
- package/types/server/devtools/types.d.ts +2 -2
- package/types/server/di/predefinedAdaptor.d.ts +4 -1
- package/types/server/index.d.ts +0 -2
- package/types/server/mcp/McpAuth.d.ts +62 -0
- package/types/server/mcp/McpDispatcher.d.ts +54 -0
- package/types/server/mcp/McpEventStream.d.ts +18 -0
- package/types/server/mcp/McpExecutionContext.d.ts +44 -0
- package/types/server/mcp/McpRouter.d.ts +60 -0
- package/types/server/mcp/index.d.ts +5 -0
- package/types/server/mcp.d.ts +1 -0
- package/types/server/subRouteIndexDocument.d.ts +8 -0
- package/types/server/systemPageDocument.d.ts +1 -0
- package/types/server/systemPages.d.ts +5 -0
- package/types/server/vendor/akanjs-fetch.d.ts +1 -0
- package/types/service/agent.service.d.ts +12 -0
- package/types/service/base.service.d.ts +4 -0
- package/types/service/index.d.ts +1 -0
- package/types/service/predefinedAdaptor/database.adaptor.d.ts +24 -2
- package/types/service/predefinedAdaptor/deepseekLlm.d.ts +64 -0
- package/types/service/predefinedAdaptor/index.d.ts +3 -0
- package/types/service/predefinedAdaptor/insightQuery.d.ts +50 -0
- package/types/service/predefinedAdaptor/llm.adaptor.d.ts +68 -0
- package/types/service/predefinedAdaptor/role.adaptor.d.ts +2 -0
- package/types/service/predefinedAdaptor/schedule.adaptor.d.ts +10 -6
- package/types/service/types.d.ts +4 -1
- package/types/signal/agent/AgentCatalogue.d.ts +100 -0
- package/types/signal/agent/index.d.ts +1 -0
- package/types/signal/agent.d.ts +1 -0
- package/types/signal/agent.signal.d.ts +29 -0
- package/types/signal/agentTurn.d.ts +9 -0
- package/types/signal/agentTurnStream.d.ts +16 -0
- package/types/signal/base.signal.d.ts +1 -1
- package/types/signal/endpointInfo.d.ts +21 -3
- package/types/signal/guard.d.ts +11 -0
- package/types/signal/guards.d.ts +22 -1
- package/types/signal/index.d.ts +6 -0
- package/types/signal/mcp/McpDocument.d.ts +65 -0
- package/types/signal/mcp/McpProgress.d.ts +40 -0
- package/types/signal/mcp/McpUriTemplate.d.ts +26 -0
- package/types/signal/mcp/Msg.d.ts +143 -0
- package/types/signal/mcp/index.d.ts +5 -0
- package/types/signal/mcp/mcpProtocol.d.ts +107 -0
- package/types/signal/mcp.d.ts +1 -0
- package/types/signal/openapi/openapi.d.ts +3 -3
- package/types/signal/schema/JsonSchemaBuilder.d.ts +47 -0
- package/types/signal/schema/index.d.ts +1 -0
- package/types/signal/schema.d.ts +1 -0
- package/types/signal/signalContext.d.ts +16 -1
- package/types/signal/slice.d.ts +8 -8
- package/types/signal/types.d.ts +1 -1
- package/types/store/actionTag.d.ts +21 -0
- package/types/store/agent/AgentBridge.d.ts +77 -0
- package/types/store/agent/AgentContext.d.ts +16 -0
- package/types/store/agent/AgentPrompts.d.ts +31 -0
- package/types/store/agent/AgentVisibility.d.ts +21 -0
- package/types/store/agent/ScreenReader.d.ts +11 -0
- package/types/store/agent/StoreCatalogue.d.ts +26 -0
- package/types/store/agent/StoreSurfaceSource.d.ts +18 -0
- package/types/store/agent/index.d.ts +9 -0
- package/types/store/agent/storeSurface.d.ts +14 -0
- package/types/store/agent/types.d.ts +49 -0
- package/types/store/agent.d.ts +1 -0
- package/types/store/agentic/StToolBuilder.d.ts +41 -0
- package/types/store/agentic/attachAgentic.d.ts +14 -0
- package/types/store/agentic/index.d.ts +5 -0
- package/types/store/agentic/readableValue.d.ts +3 -0
- package/types/store/agentic/useStExpose.d.ts +8 -0
- package/types/store/agentic/useStState.d.ts +12 -0
- package/types/store/agentic.d.ts +1 -0
- package/types/store/baseSt.d.ts +29 -22
- package/types/store/databaseStateNames.d.ts +25 -0
- package/types/store/formSetterNames.d.ts +16 -0
- package/types/store/index.d.ts +7 -0
- package/types/store/rootStore.d.ts +5 -1
- package/types/store/sliceRole.d.ts +25 -0
- package/types/store/store.d.ts +7 -2
- package/types/store/storeInstance.d.ts +33 -1
- package/types/store/storeRegistry.d.ts +5 -0
- package/types/store/types.d.ts +15 -0
- package/types/store/withSelector.d.ts +7 -8
- package/types/test/registerDom.d.ts +1 -0
- package/types/ui/Agent/Approval.d.ts +7 -0
- package/types/ui/Agent/Bubble.d.ts +13 -0
- package/types/ui/Agent/Chat.d.ts +24 -0
- package/types/ui/Agent/Context.d.ts +9 -0
- package/types/ui/Agent/Dock.d.ts +16 -0
- package/types/ui/Agent/Guide.d.ts +9 -0
- package/types/ui/Agent/Section.d.ts +10 -0
- package/types/ui/Agent/StateKey.d.ts +16 -0
- package/types/ui/Agent/Tool.d.ts +15 -0
- package/types/ui/Agent/Transcript.d.ts +13 -0
- package/types/ui/Agent/Zone.d.ts +23 -0
- package/types/ui/Agent/fetchRunner.d.ts +12 -0
- package/types/ui/Agent/index.d.ts +17 -0
- package/types/ui/Agent/index_.d.ts +1 -0
- package/types/ui/Agent/sessionHistory.d.ts +12 -0
- package/types/ui/Agent.d.ts +1 -0
- package/types/ui/Badge.d.ts +1 -1
- package/types/ui/Button.d.ts +1 -1
- package/types/ui/CsrImage.d.ts +1 -1
- package/types/ui/Dropdown.d.ts +2 -0
- package/types/ui/Image.d.ts +3 -3
- package/types/ui/Layout/BottomInset.d.ts +2 -1
- package/types/ui/Layout/index.d.ts +1 -1
- package/types/ui/Signal/style.d.ts +4 -1
- package/types/ui/UiOverride/context.d.ts +14 -2
- package/types/ui/agentAttrs.d.ts +14 -0
- package/types/ui/index.d.ts +4 -1
- package/types/ui/overlayLayer.d.ts +24 -0
- package/types/ui/recipe/badgeRecipe.d.ts +7 -3
- package/types/ui/recipe/buttonRecipe.d.ts +7 -3
- package/types/ui/recipe/inputRecipe.d.ts +5 -1
- package/types/vendor/use-agentic/AgentProvider.d.ts +18 -0
- package/types/vendor/use-agentic/AgentScope.d.ts +9 -0
- package/types/vendor/use-agentic/AgentSession.d.ts +50 -0
- package/types/vendor/use-agentic/Agentic.d.ts +21 -0
- package/types/vendor/use-agentic/AgenticSurface.d.ts +44 -0
- package/types/vendor/use-agentic/httpRunner.d.ts +15 -0
- package/types/vendor/use-agentic/index.d.ts +13 -0
- package/types/vendor/use-agentic/surfaceContext.d.ts +5 -0
- package/types/vendor/use-agentic/types.d.ts +133 -0
- package/types/vendor/use-agentic/useAgent.d.ts +4 -0
- package/types/vendor/use-agentic/useAgentGuide.d.ts +6 -0
- package/types/vendor/use-agentic/useAgentResource.d.ts +7 -0
- package/types/vendor/use-agentic/useAgentState.d.ts +13 -0
- package/types/vendor/use-agentic/useAgentTool.d.ts +16 -0
- package/types/vendor/use-agentic.d.ts +1 -0
- package/types/webkit/index.d.ts +3 -0
- package/types/webkit/lazy.d.ts +12 -0
- package/types/webkit/useCsrValues.d.ts +3 -3
- package/types/webkit/useEscapeKey.d.ts +5 -0
- package/types/webkit/useFrameRuntime.d.ts +6 -1
- package/types/webkit/useScreenScope.d.ts +18 -0
- package/ui/Agent/Approval.tsx +29 -0
- package/ui/Agent/Bubble.tsx +74 -0
- package/ui/Agent/Chat.tsx +225 -0
- package/ui/Agent/Context.tsx +38 -0
- package/ui/Agent/Dock.tsx +72 -0
- package/ui/Agent/Guide.tsx +16 -0
- package/ui/Agent/Section.tsx +24 -0
- package/ui/Agent/StateKey.tsx +44 -0
- package/ui/Agent/Tool.tsx +66 -0
- package/ui/Agent/Transcript.tsx +33 -0
- package/ui/Agent/Zone.tsx +48 -0
- package/ui/Agent/fetchRunner.ts +30 -0
- package/ui/Agent/index.ts +12 -0
- package/ui/Agent/index_.tsx +4 -0
- package/ui/Agent/sessionHistory.ts +33 -0
- package/ui/Badge.tsx +3 -3
- package/ui/BottomSheet.tsx +5 -0
- package/ui/Button.tsx +6 -2
- package/ui/Constant/Doc.tsx +1 -1
- package/ui/CsrImage.tsx +1 -1
- package/ui/Data/ListContainer.tsx +1 -1
- package/ui/DatePicker.tsx +5 -4
- package/ui/Dialog/Modal.tsx +12 -15
- package/ui/DraggableList.tsx +3 -1
- package/ui/Dropdown.tsx +33 -11
- package/ui/Field.tsx +30 -16
- package/ui/Image.tsx +3 -3
- package/ui/Input.tsx +14 -5
- package/ui/Layout/BottomInset.tsx +6 -1
- package/ui/Load/Units.tsx +11 -2
- package/ui/Load/View.tsx +7 -2
- package/ui/Loading/ProgressBar.tsx +8 -1
- package/ui/Menu.tsx +7 -8
- package/ui/Model/EditModal.tsx +37 -2
- package/ui/Model/SureToRemove.tsx +2 -1
- package/ui/Model/index_.tsx +42 -15
- package/ui/ObjectId.tsx +3 -4
- package/ui/Pagination.tsx +3 -4
- package/ui/Popconfirm.tsx +8 -7
- package/ui/Select.tsx +6 -4
- package/ui/Signal/RestApi.tsx +43 -16
- package/ui/Signal/WebSocket.tsx +1 -1
- package/ui/Signal/style.ts +6 -1
- package/ui/Switch.tsx +2 -0
- package/ui/System/CSR.tsx +6 -2
- package/ui/System/ThemeToggle.tsx +55 -33
- package/ui/ToggleSelect.tsx +4 -3
- package/ui/Tooltip.tsx +2 -1
- package/ui/UiOverride/context.ts +14 -2
- package/ui/agentAttrs.ts +19 -0
- package/ui/index.ts +10 -1
- package/ui/overlayLayer.ts +39 -0
- package/ui/recipe/badgeRecipe.ts +22 -3
- package/ui/recipe/buttonRecipe.ts +51 -2
- package/ui/recipe/factory.ts +2 -2
- package/ui/recipe/inputRecipe.ts +18 -4
- package/vendor/use-agentic/AgentProvider.tsx +39 -0
- package/vendor/use-agentic/AgentScope.tsx +20 -0
- package/vendor/use-agentic/AgentSession.ts +292 -0
- package/vendor/use-agentic/Agentic.tsx +44 -0
- package/vendor/use-agentic/AgenticSurface.ts +294 -0
- package/vendor/use-agentic/WIRE.md +57 -0
- package/vendor/use-agentic/httpRunner.ts +115 -0
- package/vendor/use-agentic/index.ts +14 -0
- package/vendor/use-agentic/surfaceContext.ts +9 -0
- package/vendor/use-agentic/types.ts +144 -0
- package/vendor/use-agentic/useAgent.ts +17 -0
- package/vendor/use-agentic/useAgentGuide.ts +16 -0
- package/vendor/use-agentic/useAgentResource.ts +30 -0
- package/vendor/use-agentic/useAgentState.ts +61 -0
- package/vendor/use-agentic/useAgentTool.ts +55 -0
- package/webkit/bootCsr.tsx +2 -33
- package/webkit/index.ts +3 -0
- package/webkit/lazy.tsx +27 -3
- package/webkit/useCsrValues.ts +121 -4
- package/webkit/useEscapeKey.tsx +42 -0
- package/webkit/useFrameRuntime.ts +65 -32
- package/webkit/useScreenScope.tsx +49 -0
package/store/state.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
SlceDbSort,
|
|
15
15
|
SliceCls,
|
|
16
16
|
} from "akanjs/signal";
|
|
17
|
+
import { databaseStateNames } from "./databaseStateNames";
|
|
17
18
|
import type { StoreSliceArgs, StoreSliceMap, StoreSliceSuffixCap, Submit } from "./types";
|
|
18
19
|
|
|
19
20
|
export type SliceStateKey =
|
|
@@ -151,18 +152,7 @@ export type DefaultState<
|
|
|
151
152
|
|
|
152
153
|
export const createDatabaseState = (refName: string) => {
|
|
153
154
|
const cnst = ConstantRegistry.getDatabase(refName);
|
|
154
|
-
const
|
|
155
|
-
const names = {
|
|
156
|
-
model: fieldName,
|
|
157
|
-
Model: className,
|
|
158
|
-
modelLoading: `${fieldName}Loading`,
|
|
159
|
-
modelForm: `${fieldName}Form`,
|
|
160
|
-
modelFormLoading: `${fieldName}FormLoading`,
|
|
161
|
-
modelSubmit: `${fieldName}Submit`,
|
|
162
|
-
modelViewAt: `${fieldName}ViewAt`,
|
|
163
|
-
modelModal: `${fieldName}Modal`,
|
|
164
|
-
modelOperation: `${fieldName}Operation`,
|
|
165
|
-
};
|
|
155
|
+
const names = databaseStateNames(refName);
|
|
166
156
|
const baseState = {
|
|
167
157
|
[names.model]: null,
|
|
168
158
|
[names.modelLoading]: true,
|
package/store/store.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ACTION_META,
|
|
3
|
+
ACTION_OWNER_META,
|
|
3
4
|
type Cls,
|
|
4
5
|
type MergeAllActionTypes,
|
|
5
6
|
type MergeAllKeyOfObjects,
|
|
@@ -24,6 +25,7 @@ import type {
|
|
|
24
25
|
SliceCls,
|
|
25
26
|
} from "akanjs/signal";
|
|
26
27
|
import { type DefaultAction, makeActions, makeFormSetter } from "./action";
|
|
28
|
+
import type { ActionOwner } from "./actionTag";
|
|
27
29
|
import { createDatabaseState, createSliceState, type DefaultState } from "./state";
|
|
28
30
|
import {
|
|
29
31
|
createDerivedStateBuilder,
|
|
@@ -40,7 +42,15 @@ import {
|
|
|
40
42
|
type WritableStateBuilder,
|
|
41
43
|
type WritableStateOf,
|
|
42
44
|
} from "./stateBuilder";
|
|
43
|
-
import type {
|
|
45
|
+
import type {
|
|
46
|
+
InternalSlice,
|
|
47
|
+
SetGet,
|
|
48
|
+
SetGetWritable,
|
|
49
|
+
StoreAgentExposure,
|
|
50
|
+
StoreSliceMap,
|
|
51
|
+
StoreSliceName,
|
|
52
|
+
StoreSliceSuffix,
|
|
53
|
+
} from "./types";
|
|
44
54
|
|
|
45
55
|
type _SliceMap<S extends SliceCls> = StoreSliceMap<S>;
|
|
46
56
|
type _StoreInput<S extends SliceCls> = SlceCnstInput<S>;
|
|
@@ -120,8 +130,10 @@ export type StoreCls<
|
|
|
120
130
|
[STATE_INIT_META]: StateInitializerMap;
|
|
121
131
|
[STATE_DERIVED_META]: StateDerivedMeta;
|
|
122
132
|
[ACTION_META]: { [key: string]: (...args: any[]) => any };
|
|
133
|
+
[ACTION_OWNER_META]: { [key: string]: ActionOwner };
|
|
123
134
|
slice: { [key: string]: SerializedSlice };
|
|
124
135
|
_slice: SlceCls[typeof SLICE_META];
|
|
136
|
+
agent?: StoreAgentExposure;
|
|
125
137
|
}
|
|
126
138
|
>;
|
|
127
139
|
|
|
@@ -187,6 +199,7 @@ export function store<Sig extends ClientSignal<any, any, any> | string, State>(
|
|
|
187
199
|
static [STATE_INIT_META] = {};
|
|
188
200
|
static [STATE_DERIVED_META] = createEmptyDerivedMeta();
|
|
189
201
|
static [ACTION_META] = {};
|
|
202
|
+
static [ACTION_OWNER_META] = {};
|
|
190
203
|
static slice = {};
|
|
191
204
|
} as StoreCls;
|
|
192
205
|
const writableStateRaw = stateFactory(createWritableStateBuilder());
|
|
@@ -204,6 +217,7 @@ export function store<Sig extends ClientSignal<any, any, any> | string, State>(
|
|
|
204
217
|
writable.meta,
|
|
205
218
|
);
|
|
206
219
|
Object.assign(storeCls[ACTION_META], ...libStores.map((libStore) => libStore[ACTION_META]));
|
|
220
|
+
Object.assign(storeCls[ACTION_OWNER_META], ...libStores.map((libStore) => libStore[ACTION_OWNER_META] ?? {}));
|
|
207
221
|
applyMixins(storeCls, libStores);
|
|
208
222
|
if (signal) {
|
|
209
223
|
const signalState = {
|
|
@@ -218,6 +232,10 @@ export function store<Sig extends ClientSignal<any, any, any> | string, State>(
|
|
|
218
232
|
};
|
|
219
233
|
Object.assign(storeCls.prototype, actions);
|
|
220
234
|
Object.assign(storeCls[ACTION_META], actions);
|
|
235
|
+
Object.assign(
|
|
236
|
+
storeCls[ACTION_OWNER_META],
|
|
237
|
+
Object.fromEntries(Object.keys(actions).map((key) => [key, { refName }])),
|
|
238
|
+
);
|
|
221
239
|
Object.assign(storeCls.slice, signal.serializedSignal.slice ?? {});
|
|
222
240
|
}
|
|
223
241
|
if (derivedStateFactory) {
|
package/store/storeInstance.ts
CHANGED
|
@@ -1,27 +1,24 @@
|
|
|
1
|
-
import { ACTION_META, STATE_DERIVED_META, STATE_INIT_META } from "akanjs/base";
|
|
1
|
+
import { ACTION_META, ACTION_OWNER_META, STATE_DERIVED_META, STATE_INIT_META } from "akanjs/base";
|
|
2
2
|
import { Translator } from "akanjs/client";
|
|
3
3
|
import { capitalize, Logger, parseAkanI18nEnv } from "akanjs/common";
|
|
4
|
-
import {
|
|
4
|
+
import type { SerializedArg } from "akanjs/signal";
|
|
5
|
+
import { enableMapSet, produce } from "immer";
|
|
5
6
|
import type { RefObject } from "react";
|
|
7
|
+
import { useScopePath } from "../vendor/use-agentic";
|
|
8
|
+
import { type ActionOwner, actionTagOf, tagAction } from "./actionTag";
|
|
6
9
|
import { useEffect, useRef, useSyncExternalStore } from "./hooks";
|
|
7
10
|
import type { RootStoreCls } from "./rootStore";
|
|
11
|
+
import type { SliceActionKey, SliceActionRole, SliceStateRole } from "./sliceRole";
|
|
8
12
|
import type { SliceStateKey } from "./state";
|
|
9
13
|
import { evaluateInitializers, type SearchParamsState, type StateDerivedMeta } from "./stateBuilder";
|
|
14
|
+
import type { StoreUseOptions } from "./types";
|
|
15
|
+
|
|
16
|
+
enableMapSet();
|
|
10
17
|
|
|
11
18
|
type StoreStateRecord = Record<string, unknown>;
|
|
12
19
|
type StoreAction = (...args: unknown[]) => unknown;
|
|
13
20
|
type TranslationParam = Record<string, string | number>;
|
|
14
21
|
|
|
15
|
-
type SliceActionKey =
|
|
16
|
-
| "initModel"
|
|
17
|
-
| "refreshModel"
|
|
18
|
-
| "selectModel"
|
|
19
|
-
| "setPageOfModel"
|
|
20
|
-
| "addPageOfModel"
|
|
21
|
-
| "setLimitOfModel"
|
|
22
|
-
| "setQueryArgsOfModel"
|
|
23
|
-
| "setSortOfModel";
|
|
24
|
-
|
|
25
22
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
26
23
|
Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
27
24
|
|
|
@@ -136,6 +133,11 @@ export class StoreInstance {
|
|
|
136
133
|
}) as any;
|
|
137
134
|
|
|
138
135
|
sel = <U>(selector: (state: StoreStateRecord) => U, equals?: (a: U, b: U) => boolean) => {
|
|
136
|
+
this.#useLiveSelector(selector);
|
|
137
|
+
return this.#sel(selector, equals);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
#sel = <U>(selector: (state: StoreStateRecord) => U, equals?: (a: U, b: U) => boolean) => {
|
|
139
141
|
const eq = equals ?? Object.is;
|
|
140
142
|
return useSyncExternalStore(
|
|
141
143
|
(onStoreChange: () => void) => {
|
|
@@ -154,7 +156,66 @@ export class StoreInstance {
|
|
|
154
156
|
);
|
|
155
157
|
};
|
|
156
158
|
|
|
159
|
+
retainLive = (key: string, scopeKey = "") => {
|
|
160
|
+
const scopes = this.#liveKeys.get(key) ?? new Map<string, number>();
|
|
161
|
+
scopes.set(scopeKey, (scopes.get(scopeKey) ?? 0) + 1);
|
|
162
|
+
this.#liveKeys.set(key, scopes);
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
releaseLive = (key: string, scopeKey = "") => {
|
|
166
|
+
const scopes = this.#liveKeys.get(key);
|
|
167
|
+
if (!scopes) return;
|
|
168
|
+
const count = scopes.get(scopeKey) ?? 0;
|
|
169
|
+
if (count <= 1) scopes.delete(scopeKey);
|
|
170
|
+
else scopes.set(scopeKey, count - 1);
|
|
171
|
+
if (!scopes.size) this.#liveKeys.delete(key);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
#useLive(key: string, count = true) {
|
|
175
|
+
|
|
176
|
+
const scopeKey = useScopePath().join(".");
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
if (!count) return;
|
|
179
|
+
this.retainLive(key, scopeKey);
|
|
180
|
+
return () => {
|
|
181
|
+
this.releaseLive(key, scopeKey);
|
|
182
|
+
};
|
|
183
|
+
}, [key, count, scopeKey]);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* `sel` and `ref` take an opaque selector, so the keys it reads are learned by running it once over a recording
|
|
188
|
+
* proxy. Captured at mount, like every surface declaration: the retained set must equal the released set, and a
|
|
189
|
+
* selector is a new closure every render.
|
|
190
|
+
*/
|
|
191
|
+
#useLiveSelector(selector: (state: StoreStateRecord) => unknown) {
|
|
192
|
+
const scopeKey = useScopePath().join(".");
|
|
193
|
+
useEffect(() => {
|
|
194
|
+
const keys = [...this.#touched(selector)];
|
|
195
|
+
for (const key of keys) this.retainLive(key, scopeKey);
|
|
196
|
+
return () => {
|
|
197
|
+
for (const key of keys) this.releaseLive(key, scopeKey);
|
|
198
|
+
};
|
|
199
|
+
}, [scopeKey]);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
#touched(selector: (state: StoreStateRecord) => unknown) {
|
|
203
|
+
const touched = new Set<string>();
|
|
204
|
+
const proxy = new Proxy(this.#state, {
|
|
205
|
+
get: (target, key) => {
|
|
206
|
+
if (typeof key === "string") touched.add(key);
|
|
207
|
+
return Reflect.get(target, key);
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
try {
|
|
211
|
+
selector(proxy as StoreStateRecord);
|
|
212
|
+
} catch {
|
|
213
|
+
}
|
|
214
|
+
return touched;
|
|
215
|
+
}
|
|
216
|
+
|
|
157
217
|
ref = <U>(selector: (state: StoreStateRecord) => U): RefObject<U> => {
|
|
218
|
+
this.#useLiveSelector(selector);
|
|
158
219
|
const ref = useRef(selector(this.get()));
|
|
159
220
|
useEffect(
|
|
160
221
|
() =>
|
|
@@ -166,10 +227,77 @@ export class StoreInstance {
|
|
|
166
227
|
return ref as RefObject<U>;
|
|
167
228
|
};
|
|
168
229
|
|
|
169
|
-
use: { [key: string]: () => unknown } = {};
|
|
230
|
+
use: { [key: string]: (options?: StoreUseOptions) => unknown } = {};
|
|
170
231
|
do: { [key: string]: StoreAction } = {};
|
|
171
232
|
slice: { [key: string]: unknown } = {};
|
|
172
233
|
|
|
234
|
+
readonly #sliceActionRoles = new Map<string, SliceActionRole>();
|
|
235
|
+
readonly #sliceStateRoles = new Map<string, SliceStateRole>();
|
|
236
|
+
readonly #actionArity = new Map<string, number>();
|
|
237
|
+
readonly #actionOwners = new Map<string, ActionOwner>();
|
|
238
|
+
readonly #liveKeys = new Map<string, Map<string, number>>();
|
|
239
|
+
readonly #generatedSetters = new Set<string>();
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* How many mounted components are reading each state key right now. `st.use.*` is a hook, so subscription is
|
|
243
|
+
* presence — this is how an agent context knows which keys the screen is actually built from.
|
|
244
|
+
*/
|
|
245
|
+
get liveKeys(): ReadonlyMap<string, number> {
|
|
246
|
+
return this.liveKeysIn("");
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* The live keys as one zone view sees them: retentions tagged at the view's scope or below. The empty view is the
|
|
251
|
+
* whole screen. Zones are views, not walls — a key read inside a zone counts for that zone and for the root alike.
|
|
252
|
+
*/
|
|
253
|
+
liveKeysIn(viewKey: string): ReadonlyMap<string, number> {
|
|
254
|
+
const keys = new Map<string, number>();
|
|
255
|
+
for (const [key, scopes] of this.#liveKeys) {
|
|
256
|
+
let total = 0;
|
|
257
|
+
for (const [scopeKey, count] of scopes) {
|
|
258
|
+
if (viewKey && scopeKey !== viewKey && !scopeKey.startsWith(`${viewKey}.`)) continue;
|
|
259
|
+
total += count;
|
|
260
|
+
}
|
|
261
|
+
if (total > 0) keys.set(key, total);
|
|
262
|
+
}
|
|
263
|
+
return keys;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** Which module declared each action. See `ActionOwner`. */
|
|
267
|
+
get actionOwners(): ReadonlyMap<string, ActionOwner> {
|
|
268
|
+
return this.#actionOwners;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* How many arguments each action declares.
|
|
273
|
+
*
|
|
274
|
+
* Recorded because `do[key]` is a rest-argument wrapper around the real method, so its own `length` is zero for
|
|
275
|
+
* everything — the arity is gone by the time anyone holding the instance could ask. A rest parameter on the method
|
|
276
|
+
* itself still reads as zero; nothing can recover that.
|
|
277
|
+
*/
|
|
278
|
+
get actionArity(): ReadonlyMap<string, number> {
|
|
279
|
+
return this.#actionArity;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/** What each generated slice key is, for a reader that has only the finished store. See `SliceActionRole`. */
|
|
283
|
+
get sliceActionRoles(): ReadonlyMap<string, SliceActionRole> {
|
|
284
|
+
return this.#sliceActionRoles;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
get sliceStateRoles(): ReadonlyMap<string, SliceStateRole> {
|
|
288
|
+
return this.#sliceStateRoles;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/** Keys the store materializes from a computation, the URL, or storage. `set` throws on them. */
|
|
292
|
+
get derivedKeys(): ReadonlySet<string> {
|
|
293
|
+
return this.#derivedMeta.derivedKeys;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/** The `set<Key>` conveniences `#extendAccessors` writes for every plain state key. Their value is untyped. */
|
|
297
|
+
get generatedSetters(): ReadonlySet<string> {
|
|
298
|
+
return this.#generatedSetters;
|
|
299
|
+
}
|
|
300
|
+
|
|
173
301
|
constructor(store?: RootStoreCls) {
|
|
174
302
|
if (store) this.addStore(store);
|
|
175
303
|
}
|
|
@@ -187,6 +315,7 @@ export class StoreInstance {
|
|
|
187
315
|
hasNewStateKey = true;
|
|
188
316
|
}
|
|
189
317
|
if (hasNewStateKey) this.#state = nextState;
|
|
318
|
+
for (const [key, owner] of Object.entries(store[ACTION_OWNER_META] ?? {})) this.#actionOwners.set(key, owner);
|
|
190
319
|
this.#mergeActions(store[ACTION_META]);
|
|
191
320
|
this.#extendAccessors(derivedState, store[ACTION_META]);
|
|
192
321
|
this.#buildSlices(store);
|
|
@@ -197,32 +326,42 @@ export class StoreInstance {
|
|
|
197
326
|
#mergeActions(actions: { [key: string]: StoreAction }) {
|
|
198
327
|
for (const [k, method] of Object.entries(actions)) {
|
|
199
328
|
this.#ctx[k] = (...args: unknown[]) => method.call(this.#ctx, ...args);
|
|
329
|
+
this.#actionArity.set(k, method.length);
|
|
200
330
|
}
|
|
201
331
|
}
|
|
202
332
|
|
|
203
333
|
#extendAccessors(state: StoreStateRecord, actions: { [key: string]: StoreAction }) {
|
|
204
334
|
for (const k of Object.keys(state)) {
|
|
205
335
|
if (typeof state[k] !== "function") {
|
|
206
|
-
this.use[k] = (
|
|
336
|
+
this.use[k] = (options?: StoreUseOptions) => {
|
|
337
|
+
this.#useLive(k, options?.agent !== false);
|
|
338
|
+
return this.#sel((s) => s[k]);
|
|
339
|
+
};
|
|
207
340
|
if (this.#derivedMeta.derivedKeys.has(k)) continue;
|
|
208
341
|
const setKey = `set${capitalize(k)}`;
|
|
209
|
-
|
|
342
|
+
|
|
343
|
+
if (setKey in actions) continue;
|
|
344
|
+
this.do[setKey] = tagAction((value: unknown) => this.set({ [k]: value }), { action: setKey, state: k });
|
|
345
|
+
this.#actionArity.set(setKey, 1);
|
|
346
|
+
this.#generatedSetters.add(setKey);
|
|
210
347
|
}
|
|
211
348
|
}
|
|
212
349
|
for (const k of Object.keys(actions)) {
|
|
213
|
-
|
|
350
|
+
const dispatch = async (...args: unknown[]) => {
|
|
214
351
|
Logger.verbose(`${k} action loading...`);
|
|
215
352
|
const start = Date.now();
|
|
216
353
|
try {
|
|
354
|
+
|
|
217
355
|
const result = await (this.#ctx[k] as StoreAction)(...args);
|
|
218
356
|
Logger.verbose(`=> ${k} action dispatched (${Date.now() - start}ms)`);
|
|
219
|
-
return result;
|
|
220
357
|
} catch (error) {
|
|
221
358
|
this.#showActionErrorMessage(k, error);
|
|
222
359
|
Logger.error(`${k} action error return: ${error instanceof Error ? error.message : String(error)}`);
|
|
223
360
|
throw error;
|
|
224
361
|
}
|
|
225
362
|
};
|
|
363
|
+
|
|
364
|
+
this.do[k] = tagAction(dispatch, actionTagOf(actions[k]) ?? { action: k });
|
|
226
365
|
}
|
|
227
366
|
}
|
|
228
367
|
|
|
@@ -252,7 +391,7 @@ export class StoreInstance {
|
|
|
252
391
|
});
|
|
253
392
|
}
|
|
254
393
|
|
|
255
|
-
#buildSlice(refName: string, sliceName: string, serializedSlice: { args?:
|
|
394
|
+
#buildSlice(refName: string, sliceName: string, serializedSlice: { args?: SerializedArg[] }) {
|
|
256
395
|
const [fieldName, className] = [refName, capitalize(refName)];
|
|
257
396
|
const names: { [key in SliceStateKey | SliceActionKey | "model" | "Model"]: string } = {
|
|
258
397
|
model: fieldName,
|
|
@@ -322,14 +461,20 @@ export class StoreInstance {
|
|
|
322
461
|
argLength: serializedSlice.args?.length ?? 0,
|
|
323
462
|
};
|
|
324
463
|
|
|
464
|
+
const args = serializedSlice.args ?? [];
|
|
325
465
|
for (const key of Object.keys(namesOfSliceAction) as SliceActionKey[]) {
|
|
326
466
|
const rootActionKey = namesOfSliceAction[key];
|
|
327
|
-
if (this.do[rootActionKey])
|
|
467
|
+
if (!this.do[rootActionKey]) continue;
|
|
468
|
+
targetSlice.do[names[key]] = this.do[rootActionKey];
|
|
469
|
+
this.#sliceActionRoles.set(rootActionKey, { role: key, refName, sliceName, args });
|
|
328
470
|
}
|
|
329
471
|
|
|
330
472
|
for (const key of Object.keys(namesOfSliceState) as SliceStateKey[]) {
|
|
331
473
|
const rootStateKey = namesOfSliceState[key];
|
|
332
|
-
if (this.use[rootStateKey])
|
|
474
|
+
if (this.use[rootStateKey]) {
|
|
475
|
+
targetSlice.use[names[key]] = this.use[rootStateKey];
|
|
476
|
+
this.#sliceStateRoles.set(rootStateKey, { role: key, refName, sliceName });
|
|
477
|
+
}
|
|
333
478
|
const setRootKey = `set${capitalize(rootStateKey)}`;
|
|
334
479
|
const setLocalKey = `set${capitalize(names[key])}`;
|
|
335
480
|
if (this.do[setRootKey]) targetSlice.do[setLocalKey] = this.do[setRootKey];
|
package/store/storeRegistry.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ACTION_META,
|
|
3
|
+
ACTION_OWNER_META,
|
|
3
4
|
type MergeAllKeyOfObjects,
|
|
4
5
|
type MergeAllKeyOfTypes,
|
|
5
6
|
type MergeAllTypes,
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
STATE_META,
|
|
9
10
|
} from "akanjs/base";
|
|
10
11
|
import { applyMixins } from "akanjs/common";
|
|
12
|
+
import { attachAgentic } from "./agentic";
|
|
11
13
|
import type { RootStoreCls } from "./rootStore";
|
|
12
14
|
import type { StoreCls } from "./store";
|
|
13
15
|
import { StoreInstance } from "./storeInstance";
|
|
@@ -37,21 +39,33 @@ function getStoreRegistryState(): StoreRegistryState {
|
|
|
37
39
|
|
|
38
40
|
export class StoreRegistry {
|
|
39
41
|
static #state = getStoreRegistryState();
|
|
42
|
+
/** The one store every `st.use` / `st.do` in the process goes through. What an agent bridge drives. */
|
|
43
|
+
static get instance(): StoreInstance {
|
|
44
|
+
return StoreRegistry.#state.instance;
|
|
45
|
+
}
|
|
40
46
|
static register<StrCls extends StoreCls>(store: StrCls): StrCls {
|
|
41
47
|
const parentStore = Object.getPrototypeOf(store) as StoreCls | null;
|
|
42
48
|
const actions = { ...(parentStore?.[ACTION_META] ?? {}) };
|
|
49
|
+
|
|
50
|
+
const owners = { ...(parentStore?.[ACTION_OWNER_META] ?? {}) };
|
|
43
51
|
Object.entries(Object.getOwnPropertyDescriptors(store.prototype)).forEach(([key, descriptor]) => {
|
|
44
52
|
if (key === "constructor") return;
|
|
45
53
|
if (!descriptor.value || typeof descriptor.value !== "function") return;
|
|
46
54
|
actions[key] = descriptor.value;
|
|
55
|
+
owners[key] = { refName: store.refName };
|
|
47
56
|
});
|
|
48
57
|
store[ACTION_META] = actions;
|
|
58
|
+
store[ACTION_OWNER_META] = owners;
|
|
49
59
|
StoreRegistry.#state.store.set(store.refName, store);
|
|
50
60
|
return store;
|
|
51
61
|
}
|
|
52
62
|
static get(refName: string) {
|
|
53
63
|
return StoreRegistry.#state.store.get(refName);
|
|
54
64
|
}
|
|
65
|
+
/** Every registered module store by refName. What the agent surface derives key ownership and exposure from. */
|
|
66
|
+
static get stores(): ReadonlyMap<string, StoreCls> {
|
|
67
|
+
return StoreRegistry.#state.store;
|
|
68
|
+
}
|
|
55
69
|
static merge<RefName extends string, StoreClses extends (StoreCls | RootStoreCls)[]>(
|
|
56
70
|
refName: RefName,
|
|
57
71
|
...stores: StoreClses
|
|
@@ -69,6 +83,7 @@ export class StoreRegistry {
|
|
|
69
83
|
static [STATE_INIT_META] = Object.assign({}, ...stores.map((store) => store[STATE_INIT_META]));
|
|
70
84
|
static [STATE_DERIVED_META] = mergeDerivedMeta(...stores.map((store) => store[STATE_DERIVED_META]));
|
|
71
85
|
static [ACTION_META] = Object.assign({}, ...stores.map((store) => store[ACTION_META]));
|
|
86
|
+
static [ACTION_OWNER_META] = Object.assign({}, ...stores.map((store) => store[ACTION_OWNER_META] ?? {}));
|
|
72
87
|
static slice: { [key: string]: { [key: string]: SerializedSlice } } = {};
|
|
73
88
|
}
|
|
74
89
|
stores.forEach((store) => {
|
|
@@ -79,6 +94,6 @@ export class StoreRegistry {
|
|
|
79
94
|
return RootStore as any;
|
|
80
95
|
}
|
|
81
96
|
static build<RtStoreCls extends RootStoreCls>(store: RtStoreCls): WithSelectors<RtStoreCls> {
|
|
82
|
-
return StoreRegistry.#state.instance.addStore(store) as unknown as WithSelectors<RtStoreCls>;
|
|
97
|
+
return attachAgentic(StoreRegistry.#state.instance.addStore(store)) as unknown as WithSelectors<RtStoreCls>;
|
|
83
98
|
}
|
|
84
99
|
}
|
package/store/types.ts
CHANGED
|
@@ -11,6 +11,17 @@ export interface Submit {
|
|
|
11
11
|
times: number;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
/** `agent: false` subscribes without joining the agent surface — the read stays out of the live-key derivation. */
|
|
15
|
+
export interface StoreUseOptions {
|
|
16
|
+
agent?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A store class's own exposure declaration, read off `static agent`. `false` keeps the whole module off the agent
|
|
21
|
+
* surface; `exclude` withholds the named state keys and actions while the rest stay derived. Absent means exposed.
|
|
22
|
+
*/
|
|
23
|
+
export type StoreAgentExposure = false | { exclude: string[] };
|
|
24
|
+
|
|
14
25
|
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
15
26
|
type PickFunc<
|
|
16
27
|
State,
|
|
@@ -36,6 +47,13 @@ export type Get<State, Actions> = {
|
|
|
36
47
|
get: () => State & Actions;
|
|
37
48
|
};
|
|
38
49
|
|
|
50
|
+
type VoidAction<T> = T extends (...args: infer Args) => infer Ret
|
|
51
|
+
? [Ret] extends [PromiseLike<unknown>]
|
|
52
|
+
? (...args: Args) => Promise<void>
|
|
53
|
+
: (...args: Args) => void
|
|
54
|
+
: T;
|
|
55
|
+
export type VoidActions<Action> = { [K in keyof Action]: VoidAction<Action[K]> };
|
|
56
|
+
|
|
39
57
|
export type StoreSliceMap<SlceCls extends SliceCls> = SlceCls[typeof SLICE_META];
|
|
40
58
|
export type StoreSliceSuffix<SlceCls extends SliceCls, Suffix extends keyof StoreSliceMap<SlceCls>> = Suffix & string;
|
|
41
59
|
export type StoreSliceSuffixCap<SlceCls extends SliceCls, Suffix extends keyof StoreSliceMap<SlceCls>> = Capitalize<
|
package/store/withSelector.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Prettify } from "akanjs/base";
|
|
2
2
|
import type { FieldState } from "akanjs/constant";
|
|
3
3
|
import type { RefObject } from "react";
|
|
4
|
+
import type { StAgentic } from "./agentic";
|
|
4
5
|
import type { RootStoreCls } from "./rootStore";
|
|
5
|
-
import type { SliceStateAction } from "./types";
|
|
6
|
+
import type { SliceStateAction, StoreUseOptions, VoidActions } from "./types";
|
|
6
7
|
|
|
7
8
|
type SetKey<Key extends string> = `set${Capitalize<Key>}`;
|
|
8
9
|
|
|
@@ -11,7 +12,7 @@ export type WithSelectors<RtStoreCls extends RootStoreCls> =
|
|
|
11
12
|
? WithSelectorsOf<State, WritableState, Action, InternalSliceObj>
|
|
12
13
|
: never;
|
|
13
14
|
|
|
14
|
-
type WithSelectorsOf<State, WritableState, Action, InternalSliceObj> = {
|
|
15
|
+
type WithSelectorsOf<State, WritableState, Action, InternalSliceObj> = StAgentic & {
|
|
15
16
|
sub: {
|
|
16
17
|
(listener: (state: State, prev: State) => void): () => void;
|
|
17
18
|
<U>(
|
|
@@ -26,9 +27,9 @@ type WithSelectorsOf<State, WritableState, Action, InternalSliceObj> = {
|
|
|
26
27
|
ref: <U>(selector: (state: State) => U) => RefObject<U>;
|
|
27
28
|
sel: <U>(selector: (state: State) => U, equals?: (a: U, b: U) => boolean) => U;
|
|
28
29
|
use: {
|
|
29
|
-
[K in keyof State]: () => State[K];
|
|
30
|
+
[K in keyof State]: (options?: StoreUseOptions) => State[K];
|
|
30
31
|
};
|
|
31
|
-
do: Action & {
|
|
32
|
+
do: VoidActions<Action> & {
|
|
32
33
|
[K in keyof WritableState as K extends string ? SetKey<K> : never]: (value: FieldState<WritableState[K]>) => void;
|
|
33
34
|
};
|
|
34
35
|
get: () => State;
|
|
@@ -49,12 +50,10 @@ type WithSelectorsOf<State, WritableState, Action, InternalSliceObj> = {
|
|
|
49
50
|
export interface SliceSelectors<RefName extends string, State, Action> {
|
|
50
51
|
refName: RefName;
|
|
51
52
|
use: {
|
|
52
|
-
[K in keyof State]: () => State[K];
|
|
53
|
+
[K in keyof State]: (options?: StoreUseOptions) => State[K];
|
|
53
54
|
};
|
|
54
55
|
do: Prettify<
|
|
55
|
-
{
|
|
56
|
-
[K in keyof Action]: Action[K];
|
|
57
|
-
} & {
|
|
56
|
+
VoidActions<Action> & {
|
|
58
57
|
[K in keyof State as K extends string ? SetKey<K> : never]: (value: FieldState<State[K]>) => void;
|
|
59
58
|
}
|
|
60
59
|
>;
|
package/types/base/symbols.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ export declare const STATE_META: unique symbol;
|
|
|
13
13
|
export declare const STATE_INIT_META: unique symbol;
|
|
14
14
|
export declare const STATE_DERIVED_META: unique symbol;
|
|
15
15
|
export declare const ACTION_META: unique symbol;
|
|
16
|
+
/** Which module declared each action. See `ActionOwner`. */
|
|
17
|
+
export declare const ACTION_OWNER_META: unique symbol;
|
|
18
|
+
/** What a dispatcher does, carried on the function so a component handed one can annotate the DOM with it. */
|
|
19
|
+
export declare const ACTION_TAG: unique symbol;
|
|
16
20
|
export declare const SERVER_VALUE: unique symbol;
|
|
17
21
|
export declare const CLIENT_VALUE: unique symbol;
|
|
18
22
|
export declare const DEFAULT_VALUE: unique symbol;
|
package/types/client/cn.d.ts
CHANGED
|
@@ -6,6 +6,11 @@ import { type ClassNameValue } from "tailwind-merge";
|
|
|
6
6
|
* `cn("bg-primary", "bg-open")` correctly resolves to `"bg-open"` instead of keeping both.
|
|
7
7
|
*/
|
|
8
8
|
export declare const colorTokens: string[];
|
|
9
|
+
/**
|
|
10
|
+
* Akan's semantic radius tokens (`--radius-box` / `--radius-field` in ui/styles.css). Without them
|
|
11
|
+
* `cn("rounded-field", "rounded-full")` keeps both classes and stylesheet order decides the winner.
|
|
12
|
+
*/
|
|
13
|
+
export declare const radiusTokens: string[];
|
|
9
14
|
/** The one class-combining function: joins strings/arrays/conditional parts (`cond && "x"`) and
|
|
10
15
|
* resolves Tailwind conflicts with a shared tailwind-merge instance that knows Akan's semantic
|
|
11
16
|
* color tokens. clsx-style object syntax (`{ x: cond }`) is not supported — write `cond && "x"`. */
|
|
@@ -428,6 +428,7 @@ export interface FrameLayoutState {
|
|
|
428
428
|
keyboard: KeyboardFrameState;
|
|
429
429
|
contentViewport: FrameContentViewportState;
|
|
430
430
|
keyboardAccessory: KeyboardAccessoryFrameState;
|
|
431
|
+
contentAnchor?: "bottom";
|
|
431
432
|
platformProfile: FramePlatformProfile;
|
|
432
433
|
zIndex: FrameLayerZIndex;
|
|
433
434
|
pageStateByPath: Map<string, PageState>;
|
|
@@ -436,6 +437,7 @@ export interface FrameSlotRegistration {
|
|
|
436
437
|
scope?: FrameSlotScope;
|
|
437
438
|
type: FrameSlotType;
|
|
438
439
|
role?: FrameSlotRole;
|
|
440
|
+
contentAnchor?: "bottom";
|
|
439
441
|
height?: number;
|
|
440
442
|
estimatedHeight?: number;
|
|
441
443
|
source?: "navbar" | "topInset" | "bottomInset" | "bottomTab" | (string & {});
|
package/types/common/Logger.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export declare class Logger {
|
|
|
17
17
|
static removeSink(sink: LoggerSink): void;
|
|
18
18
|
static setFileLevel(level: LogLevel): void;
|
|
19
19
|
static isVerbose(): boolean;
|
|
20
|
+
/** For hot-path callers that would otherwise build a message the level is about to discard. */
|
|
21
|
+
static shouldLog(logLevel: LogLevel): boolean;
|
|
20
22
|
name?: string;
|
|
21
23
|
constructor(name?: string);
|
|
22
24
|
trace(msg: string, context?: string, name?: string): void;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
interface DeepObjectifyOption {
|
|
2
2
|
serializable?: boolean;
|
|
3
3
|
convertDate?: "string" | "number";
|
|
4
|
-
}
|
|
4
|
+
}
|
|
5
|
+
export declare const deepObjectify: <T = unknown>(obj: T | null | undefined, option?: DeepObjectifyOption) => T;
|
|
6
|
+
export {};
|
package/types/common/index.d.ts
CHANGED
|
@@ -17,13 +17,14 @@ export { decodeJwtPayload } from "./jwtDecode.d.ts";
|
|
|
17
17
|
export { Logger, type LoggerSink, type LoggerSinkEntry, type LogLevel } from "./Logger.d.ts";
|
|
18
18
|
export { type AkanI18nConfig, type AkanI18nConfigInput, DEFAULT_AKAN_I18N, parseAkanI18nEnv, resolveAkanI18nConfig, } from "./localeConfig.d.ts";
|
|
19
19
|
export { lowerlize } from "./lowerlize.d.ts";
|
|
20
|
+
export { isMcpDescribableArg, type McpExposureEndpoint, type McpExposureOption, mcpBaseVerbOf, mcpHintsOf, mcpPromptRefusalOf, mcpRefusalOf, } from "./mcpExposure.d.ts";
|
|
20
21
|
export { mergeVersion } from "./mergeVersion.d.ts";
|
|
21
22
|
export { objectify } from "./objectify.d.ts";
|
|
22
23
|
export { pathGet } from "./pathGet.d.ts";
|
|
23
24
|
export { pathSet } from "./pathSet.d.ts";
|
|
24
25
|
export { randomPick } from "./randomPick.d.ts";
|
|
25
26
|
export { randomPicks } from "./randomPicks.d.ts";
|
|
26
|
-
export { assertUniqueRoutePatterns, compareRouteSpecificity, isRouteSourceFile, isSpecialRouteLeaf, matchRoutePattern, normalizeRoutePattern, type ParsedRouteModuleKey, parseRouteModuleKey, type RouteModuleKind, routeSegmentToPatternPart, routeSegmentToTreePath, tryParseRouteModuleKey, type ValidatePageSourceFileOptions, type ValidateSubRoutePageKeyOptions, validatePageSourceFile, validateSubRoutePageKey, } from "./routeConvention.d.ts";
|
|
27
|
+
export { assertUniqueRoutePatterns, compareRouteSpecificity, getRouteExports, isRouteSourceFile, isSpecialRouteLeaf, LAYOUT_ROUTE_EXPORTS, matchRoutePattern, normalizeRoutePattern, PAGE_ROUTE_EXPORTS, type ParsedRouteModuleKey, parseRouteModuleKey, RESERVED_ROUTE_CONFIG_EXPORTS, ROOT_LAYOUT_ROUTE_EXPORTS, type RouteModuleKind, routeSegmentToPatternPart, routeSegmentToTreePath, tryParseRouteModuleKey, type ValidatePageSourceFileOptions, type ValidateSubRoutePageKeyOptions, validatePageSourceFile, validateSubRoutePageKey, } from "./routeConvention.d.ts";
|
|
27
28
|
export { sleep } from "./sleep.d.ts";
|
|
28
29
|
export { splitVersion } from "./splitVersion.d.ts";
|
|
29
30
|
export { getBasePathFromPathname, parseBasePaths, parseSubRouteHosts, resolveSubRouteHosts } from "./subRoute.d.ts";
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What MCP says about one endpoint: whether it is published, why it is not, and the hints it carries.
|
|
3
|
+
*
|
|
4
|
+
* Structurally typed like the rest of `common/` so the same rules answer on both sides — the server builds its
|
|
5
|
+
* catalogue from them and the browser API explorer badges an endpoint from them. A second implementation would
|
|
6
|
+
* eventually disagree, and an audit surface that disagrees with the catalogue is worse than none.
|
|
7
|
+
*
|
|
8
|
+
* Every rejection returns the sentence an author reads, at boot in the server log and in the explorer. Fail-closed
|
|
9
|
+
* with no reason leaves an author whose endpoint is missing from the catalogue nowhere to look but the source.
|
|
10
|
+
*/
|
|
11
|
+
export interface McpExposureEndpoint {
|
|
12
|
+
type: string;
|
|
13
|
+
returns: {
|
|
14
|
+
refName: string;
|
|
15
|
+
};
|
|
16
|
+
args: {
|
|
17
|
+
name: string;
|
|
18
|
+
refName: string;
|
|
19
|
+
type: string;
|
|
20
|
+
arrDepth?: number;
|
|
21
|
+
nullable?: boolean;
|
|
22
|
+
}[];
|
|
23
|
+
guards?: string[];
|
|
24
|
+
fileUpload?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface McpExposureOption {
|
|
27
|
+
/**
|
|
28
|
+
* The read-only deployment valve, which is server configuration. The browser explorer cannot know it and so
|
|
29
|
+
* badges what the code decided; the boot log is where a read-only deployment says what it dropped.
|
|
30
|
+
*/
|
|
31
|
+
readOnly?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/** `Any` publishes as the empty schema, which tells a model nothing — so it is left out rather than described. */
|
|
34
|
+
export declare const isMcpDescribableArg: (arg: {
|
|
35
|
+
refName: string;
|
|
36
|
+
}) => boolean;
|
|
37
|
+
/** Which CRUD verb a generated endpoint key is, or `null` when the key is not one of the five. */
|
|
38
|
+
export declare const mcpBaseVerbOf: (refName: string, key: string) => "get" | "create" | "update" | "remove" | null;
|
|
39
|
+
/**
|
|
40
|
+
* The hints a client renders beside a tool. Hints only — clients are told to distrust them, so they inform a UI
|
|
41
|
+
* and never stand in for a guard. `openWorldHint` is always false: every endpoint reaches this app's own
|
|
42
|
+
* database, not the wider internet.
|
|
43
|
+
*/
|
|
44
|
+
export declare const mcpHintsOf: (key: string, endpoint: {
|
|
45
|
+
type: string;
|
|
46
|
+
}) => {
|
|
47
|
+
readOnlyHint: boolean;
|
|
48
|
+
destructiveHint: boolean;
|
|
49
|
+
idempotentHint: boolean;
|
|
50
|
+
openWorldHint: boolean;
|
|
51
|
+
};
|
|
52
|
+
/** The sentence explaining why this endpoint is not in the catalogue, or `null` when it is. */
|
|
53
|
+
export declare const mcpRefusalOf: (endpoint: McpExposureEndpoint, { readOnly }?: McpExposureOption) => string | null;
|
|
54
|
+
/**
|
|
55
|
+
* A prompt is a read exposed on the same terms as a query, so every rejection here is one thing: an argument
|
|
56
|
+
* `prompts/get` cannot carry. Its `arguments` is a flat string map — one string per name, and no schema beside it
|
|
57
|
+
* — which rules out the argument *kinds* the builder already refuses and, just as surely, two argument *types* it
|
|
58
|
+
* accepts. A tool escapes both because it publishes a real JSON Schema.
|
|
59
|
+
*/
|
|
60
|
+
export declare const mcpPromptRefusalOf: (endpoint: McpExposureEndpoint) => string | null;
|