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
|
@@ -2,6 +2,7 @@ import type { PromiseOrObject } from "akanjs/base";
|
|
|
2
2
|
import { applyMixins, capitalize } from "akanjs/common";
|
|
3
3
|
import { type ConstantModel, DEFAULT_PAGE_SIZE, type QueryOf } from "akanjs/constant";
|
|
4
4
|
import {
|
|
5
|
+
assertFilterFitsCrud,
|
|
5
6
|
CacheDatabase,
|
|
6
7
|
type CRUDEventType,
|
|
7
8
|
type DatabaseInstance,
|
|
@@ -19,7 +20,9 @@ import {
|
|
|
19
20
|
getLoaderInfos,
|
|
20
21
|
type ListQueryOption,
|
|
21
22
|
type Mdl,
|
|
23
|
+
NoDocumentError,
|
|
22
24
|
type SaveEventType,
|
|
25
|
+
type UpdateChain,
|
|
23
26
|
} from "akanjs/document";
|
|
24
27
|
import {
|
|
25
28
|
type AdaptorCls,
|
|
@@ -220,9 +223,9 @@ export class DatabaseResolver {
|
|
|
220
223
|
refName: modelName,
|
|
221
224
|
pickOne: (query: QueryOf<any>, projection?: any) => store.pickOne(query, { select: projection }),
|
|
222
225
|
pickById: (id: string | undefined, projection?: any) => {
|
|
223
|
-
if (!id) throw new
|
|
226
|
+
if (!id) throw new NoDocumentError("No Document ID");
|
|
224
227
|
return store.findOne({ id }, { select: projection }).then((doc) => {
|
|
225
|
-
if (!doc) throw new
|
|
228
|
+
if (!doc) throw new NoDocumentError(`No Document (${modelName}): ${id}`);
|
|
226
229
|
return doc;
|
|
227
230
|
});
|
|
228
231
|
},
|
|
@@ -232,11 +235,17 @@ export class DatabaseResolver {
|
|
|
232
235
|
find: (query: QueryOf<any>) => createFindManyChain(query),
|
|
233
236
|
findOne: (query: QueryOf<any>) => createFindOneChain(query),
|
|
234
237
|
findById: (id: string | undefined) => (id ? store.findOne({ id }) : Promise.resolve(null)),
|
|
235
|
-
|
|
238
|
+
count: (query: QueryOf<any>) => store.count(query),
|
|
236
239
|
updateOne: (query: QueryOf<any>, update: DocumentUpdateInput, options?: { upsert?: boolean }) =>
|
|
237
240
|
store.updateOneByQuery(query, update, options),
|
|
238
241
|
updateMany: (query: QueryOf<any>, update: DocumentUpdateInput) => store.updateManyByQuery(query, update),
|
|
242
|
+
removeOne: (query: QueryOf<any>) => store.removeOneByQuery(query),
|
|
239
243
|
removeMany: (query: QueryOf<any>) => store.removeManyByQuery(query),
|
|
244
|
+
updateById: (id: string, update: DocumentUpdateInput, options?: { upsert?: boolean }) =>
|
|
245
|
+
store.updateOneByQuery({ id }, update, options),
|
|
246
|
+
removeById: (id: string) => store.removeOneByQuery({ id }),
|
|
247
|
+
|
|
248
|
+
countDocuments: (query: QueryOf<any>) => store.count(query),
|
|
240
249
|
bulkWrite: (
|
|
241
250
|
operations: { updateOne: { filter: QueryOf<any>; update: DocumentUpdateInput; upsert?: boolean } }[],
|
|
242
251
|
) => store.bulkWrite(operations),
|
|
@@ -274,7 +283,7 @@ export class DatabaseResolver {
|
|
|
274
283
|
async __pickId(query?: QueryOf<any>, queryOption?: FindQueryOption): Promise<string> {
|
|
275
284
|
const { find, sort, skip, sample } = getFindQuery(query, queryOption);
|
|
276
285
|
const id = await this.__store.findId(find, { sort, skip, sample });
|
|
277
|
-
if (!id) throw new
|
|
286
|
+
if (!id) throw new NoDocumentError(`No Document (${database.refName}): ${JSON.stringify(query)}`);
|
|
278
287
|
return id;
|
|
279
288
|
}
|
|
280
289
|
async __exists(query?: QueryOf<any>): Promise<string | null> {
|
|
@@ -300,7 +309,7 @@ export class DatabaseResolver {
|
|
|
300
309
|
}
|
|
301
310
|
async __get(id: string) {
|
|
302
311
|
const doc = await this.__loader.load(id);
|
|
303
|
-
if (!doc) throw new
|
|
312
|
+
if (!doc) throw new NoDocumentError(`No Document (${database.refName}): ${id}`);
|
|
304
313
|
return doc;
|
|
305
314
|
}
|
|
306
315
|
async [`get${className}`](id: string) {
|
|
@@ -339,6 +348,15 @@ export class DatabaseResolver {
|
|
|
339
348
|
async __removeMany(query: QueryOf<any>) {
|
|
340
349
|
return await timedQuery(() => this.__store.removeManyByQuery(query));
|
|
341
350
|
}
|
|
351
|
+
async __removeOne(query: QueryOf<any>) {
|
|
352
|
+
return await timedQuery(() => this.__store.removeOneByQuery(query));
|
|
353
|
+
}
|
|
354
|
+
async __updateMany(query: QueryOf<any>, update: DocumentUpdateInput) {
|
|
355
|
+
return await timedQuery(() => this.__store.updateManyByQuery(query, update));
|
|
356
|
+
}
|
|
357
|
+
async __updateOne(query: QueryOf<any>, update: DocumentUpdateInput) {
|
|
358
|
+
return await timedQuery(() => this.__store.updateOneByQuery(query, update));
|
|
359
|
+
}
|
|
342
360
|
async [`remove${className}`](id: string) {
|
|
343
361
|
return this.__remove(id);
|
|
344
362
|
}
|
|
@@ -364,6 +382,7 @@ export class DatabaseResolver {
|
|
|
364
382
|
Object.entries(filterMeta.query).forEach(([queryKey, filterInfo]) => {
|
|
365
383
|
const queryFn = filterInfo.queryFn;
|
|
366
384
|
if (!queryFn) throw new Error(`No query function for key: ${queryKey}`);
|
|
385
|
+
assertFilterFitsCrud(modelName, queryKey, className);
|
|
367
386
|
Object.assign(DatabaseModelInstance.prototype, {
|
|
368
387
|
[`list${capitalize(queryKey)}`]: async function (...args: any) {
|
|
369
388
|
const { query, queryOption } = getQueryDataFromKey(queryKey, args);
|
|
@@ -403,6 +422,24 @@ export class DatabaseResolver {
|
|
|
403
422
|
},
|
|
404
423
|
[`query${capitalize(queryKey)}`]: (...args: any) =>
|
|
405
424
|
queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper),
|
|
425
|
+
[`remove${capitalize(queryKey)}`]: async function (...args: any) {
|
|
426
|
+
const query = queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper);
|
|
427
|
+
return (this as unknown as DatabaseInstance).__removeMany(query);
|
|
428
|
+
},
|
|
429
|
+
[`removeOne${capitalize(queryKey)}`]: async function (...args: any) {
|
|
430
|
+
const query = queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper);
|
|
431
|
+
return (this as unknown as DatabaseInstance).__removeOne(query);
|
|
432
|
+
},
|
|
433
|
+
[`update${capitalize(queryKey)}`]: function (...args: any): UpdateChain {
|
|
434
|
+
const instance = this as unknown as DatabaseInstance;
|
|
435
|
+
const query = queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper);
|
|
436
|
+
return { set: (update) => instance.__updateMany(query, update) };
|
|
437
|
+
},
|
|
438
|
+
[`updateOne${capitalize(queryKey)}`]: function (...args: any): UpdateChain {
|
|
439
|
+
const instance = this as unknown as DatabaseInstance;
|
|
440
|
+
const query = queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper);
|
|
441
|
+
return { set: (update) => instance.__updateOne(query, update) };
|
|
442
|
+
},
|
|
406
443
|
});
|
|
407
444
|
});
|
|
408
445
|
applyMixins(DatabaseModelInstance, [database.model]);
|
|
@@ -2,10 +2,12 @@ import type { PromiseOrObject } from "akanjs/base";
|
|
|
2
2
|
import { capitalize } from "akanjs/common";
|
|
3
3
|
import type { QueryOf } from "akanjs/constant";
|
|
4
4
|
import {
|
|
5
|
+
assertFilterFitsCrud,
|
|
5
6
|
type CRUDEventType,
|
|
6
7
|
type DatabaseModel,
|
|
7
8
|
type DataInputOf,
|
|
8
9
|
type Doc,
|
|
10
|
+
type DocumentUpdateInput,
|
|
9
11
|
documentQueryHelper,
|
|
10
12
|
type FindQueryOption,
|
|
11
13
|
fillMissingFilterArgs,
|
|
@@ -13,6 +15,7 @@ import {
|
|
|
13
15
|
getFilterMeta,
|
|
14
16
|
type ListQueryOption,
|
|
15
17
|
type SaveEventType,
|
|
18
|
+
type UpdateChain,
|
|
16
19
|
} from "akanjs/document";
|
|
17
20
|
import type { DatabaseService, ServiceCls } from "akanjs/service";
|
|
18
21
|
import type { CascadeRunner } from "./CascadeRunner";
|
|
@@ -108,6 +111,15 @@ export class ServiceResolver {
|
|
|
108
111
|
async __removeMany(this: DatabaseService, query: QueryOf<any>) {
|
|
109
112
|
return await this.__databaseModel.__removeMany(query);
|
|
110
113
|
},
|
|
114
|
+
async __removeOne(this: DatabaseService, query: QueryOf<any>) {
|
|
115
|
+
return await this.__databaseModel.__removeOne(query);
|
|
116
|
+
},
|
|
117
|
+
async __updateMany(this: DatabaseService, query: QueryOf<any>, update: DocumentUpdateInput) {
|
|
118
|
+
return await this.__databaseModel.__updateMany(query, update);
|
|
119
|
+
},
|
|
120
|
+
async __updateOne(this: DatabaseService, query: QueryOf<any>, update: DocumentUpdateInput) {
|
|
121
|
+
return await this.__databaseModel.__updateOne(query, update);
|
|
122
|
+
},
|
|
111
123
|
};
|
|
112
124
|
return dbServiceMethods;
|
|
113
125
|
}
|
|
@@ -138,6 +150,7 @@ export class ServiceResolver {
|
|
|
138
150
|
const queryFn = filterInfo.queryFn;
|
|
139
151
|
if (!queryFn) throw new Error(`No query function for key: ${queryKey}`);
|
|
140
152
|
const capitalizedQueryKey = capitalize(queryKey);
|
|
153
|
+
assertFilterFitsCrud(database.refName, queryKey, className);
|
|
141
154
|
Object.assign(srvRef.prototype, {
|
|
142
155
|
[`list${capitalizedQueryKey}`]: async function (this: DatabaseService, ...args: any) {
|
|
143
156
|
const { query, queryOption } = getQueryDataFromKey(queryKey, args);
|
|
@@ -178,6 +191,22 @@ export class ServiceResolver {
|
|
|
178
191
|
[`query${capitalize(queryKey)}`]: function (this: DatabaseService, ...args: any) {
|
|
179
192
|
return queryFn(...fillMissingFilterArgs(filterInfo, args), documentQueryHelper);
|
|
180
193
|
},
|
|
194
|
+
[`remove${capitalizedQueryKey}`]: async function (this: DatabaseService, ...args: any) {
|
|
195
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
196
|
+
return this.__removeMany(query);
|
|
197
|
+
},
|
|
198
|
+
[`removeOne${capitalizedQueryKey}`]: async function (this: DatabaseService, ...args: any) {
|
|
199
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
200
|
+
return this.__removeOne(query);
|
|
201
|
+
},
|
|
202
|
+
[`update${capitalizedQueryKey}`]: function (this: DatabaseService, ...args: any): UpdateChain {
|
|
203
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
204
|
+
return { set: (update) => this.__updateMany(query, update) };
|
|
205
|
+
},
|
|
206
|
+
[`updateOne${capitalizedQueryKey}`]: function (this: DatabaseService, ...args: any): UpdateChain {
|
|
207
|
+
const { query } = getQueryDataFromKey(queryKey, args);
|
|
208
|
+
return { set: (update) => this.__updateOne(query, update) };
|
|
209
|
+
},
|
|
181
210
|
});
|
|
182
211
|
});
|
|
183
212
|
return srvRef;
|
|
@@ -362,6 +362,16 @@ export class SignalResolver {
|
|
|
362
362
|
POST: normalHttpHandler,
|
|
363
363
|
};
|
|
364
364
|
break;
|
|
365
|
+
case "prompt":
|
|
366
|
+
|
|
367
|
+
if (!(endpointInfo.signalOption.guards ?? []).length)
|
|
368
|
+
SignalResolver.logger.warn(
|
|
369
|
+
`Prompt "${key}" declares no guards, and its GET route is mounted whether or not this app enables MCP.`,
|
|
370
|
+
);
|
|
371
|
+
routes[path] = {
|
|
372
|
+
GET: normalHttpHandler,
|
|
373
|
+
};
|
|
374
|
+
break;
|
|
365
375
|
case "pubsub":
|
|
366
376
|
wsRoutes[key] = async (ws, message, event) => {
|
|
367
377
|
const websocket = SignalResolver.#getWebsocket(registry);
|
|
@@ -429,10 +439,15 @@ export class SignalResolver {
|
|
|
429
439
|
return trimmed ? `/${trimmed}` : "";
|
|
430
440
|
}
|
|
431
441
|
|
|
442
|
+
static #selectCache = new WeakMap<Cls, Record<string, true>>();
|
|
432
443
|
static #selectForConstant(constant: Cls): Record<string, true> | undefined {
|
|
444
|
+
const cached = SignalResolver.#selectCache.get(constant);
|
|
445
|
+
if (cached) return cached;
|
|
433
446
|
const fields = (constant as { [FIELD_META]?: Record<string, unknown> })[FIELD_META];
|
|
434
447
|
if (!fields) return undefined;
|
|
435
|
-
|
|
448
|
+
const select = Object.fromEntries(Object.keys(fields).map((field) => [field, true] as const));
|
|
449
|
+
SignalResolver.#selectCache.set(constant, select);
|
|
450
|
+
return select;
|
|
436
451
|
}
|
|
437
452
|
|
|
438
453
|
static #canUsePrimitiveQueryFastPath(endpointInfo: EndpointInfo, middleware: Map<string, MiddlewareCls>) {
|
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
import {
|
|
14
14
|
assertUniqueRoutePatterns,
|
|
15
15
|
compareRouteSpecificity,
|
|
16
|
+
getRouteExports,
|
|
16
17
|
matchRoutePattern,
|
|
17
18
|
parseBasePaths,
|
|
18
19
|
parseRouteModuleKey,
|
|
@@ -49,44 +50,6 @@ export interface RouteModuleCacheStats {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
export class RouteTreeBuilder {
|
|
52
|
-
static readonly #pageRouteExports = new Set([
|
|
53
|
-
"default",
|
|
54
|
-
"pageConfig",
|
|
55
|
-
"head",
|
|
56
|
-
"metadata",
|
|
57
|
-
"generateHead",
|
|
58
|
-
"generateMetadata",
|
|
59
|
-
"Loading",
|
|
60
|
-
]);
|
|
61
|
-
static readonly #rootLayoutExports = new Set([
|
|
62
|
-
"default",
|
|
63
|
-
"pageConfig",
|
|
64
|
-
"head",
|
|
65
|
-
"metadata",
|
|
66
|
-
"generateHead",
|
|
67
|
-
"generateMetadata",
|
|
68
|
-
"fonts",
|
|
69
|
-
"manifest",
|
|
70
|
-
"theme",
|
|
71
|
-
"reconnect",
|
|
72
|
-
"wsConnect",
|
|
73
|
-
"layoutStyle",
|
|
74
|
-
"gaTrackingId",
|
|
75
|
-
"Loading",
|
|
76
|
-
"NotFound",
|
|
77
|
-
"Error",
|
|
78
|
-
]);
|
|
79
|
-
static readonly #layoutRouteExports = new Set([
|
|
80
|
-
"default",
|
|
81
|
-
"pageConfig",
|
|
82
|
-
"head",
|
|
83
|
-
"metadata",
|
|
84
|
-
"generateHead",
|
|
85
|
-
"generateMetadata",
|
|
86
|
-
"Loading",
|
|
87
|
-
"NotFound",
|
|
88
|
-
"Error",
|
|
89
|
-
]);
|
|
90
53
|
static readonly #moduleCacheStats: RouteModuleCacheStats = {
|
|
91
54
|
moduleCount: 0,
|
|
92
55
|
loadedModuleCount: 0,
|
|
@@ -309,12 +272,7 @@ export class RouteTreeBuilder {
|
|
|
309
272
|
return;
|
|
310
273
|
}
|
|
311
274
|
const parsed = parseRouteModuleKey(key);
|
|
312
|
-
const allowed =
|
|
313
|
-
kind === "page"
|
|
314
|
-
? RouteTreeBuilder.#pageRouteExports
|
|
315
|
-
: parsed.isInternalRootLayout
|
|
316
|
-
? RouteTreeBuilder.#rootLayoutExports
|
|
317
|
-
: RouteTreeBuilder.#layoutRouteExports;
|
|
275
|
+
const allowed = getRouteExports(kind, { rootLayout: parsed.isInternalRootLayout });
|
|
318
276
|
for (const exportName of Object.keys(mod)) {
|
|
319
277
|
if (!allowed.has(exportName)) {
|
|
320
278
|
throw new Error(`[route-convention] unsupported export "${exportName}" in ${key}`);
|
package/server/rscWorker.tsx
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
getRequestFrameState,
|
|
14
14
|
getRequestPolicy,
|
|
15
15
|
getRequestTheme,
|
|
16
|
+
pushRequestFallback,
|
|
16
17
|
requestStorage,
|
|
17
18
|
setRequestFrameState,
|
|
18
19
|
untrackedCookies,
|
|
@@ -1182,8 +1183,11 @@ export class RscRenderer {
|
|
|
1182
1183
|
}
|
|
1183
1184
|
|
|
1184
1185
|
#runWithRequest<T>(request: Request, fn: () => Promise<T>): Promise<T> {
|
|
1185
|
-
|
|
1186
|
-
|
|
1186
|
+
|
|
1187
|
+
const cleanup = pushRequestFallback(request);
|
|
1188
|
+
const run = () => Promise.resolve(fn()).finally(() => cleanup());
|
|
1189
|
+
if (requestStorage) return Promise.resolve(requestStorage.run(request, run));
|
|
1190
|
+
return run();
|
|
1187
1191
|
}
|
|
1188
1192
|
|
|
1189
1193
|
async #renderFallbackDocument({
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { SYSTEM_PAGE_STYLE } from "./systemPageDocument";
|
|
3
|
+
|
|
4
|
+
export interface SubRouteIndexOptions {
|
|
5
|
+
locale: string;
|
|
6
|
+
basePaths: string[];
|
|
7
|
+
subRoutes?: Record<string, string[]>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const SUB_ROUTE_INDEX_STYLE = `
|
|
11
|
+
.akan-sub-route-list { margin: 26px 0 0; padding: 0; list-style: none; display: grid; gap: 10px; }
|
|
12
|
+
.akan-sub-route-link { display: grid; gap: 4px; border: 1px solid rgba(255, 255, 255, 0.12); border-radius: 18px; background: rgba(26, 26, 26, 0.72); padding: 16px 18px; text-decoration: none; }
|
|
13
|
+
.akan-sub-route-link:hover { border-color: var(--akan-primary); background: rgba(255, 73, 59, 0.08); }
|
|
14
|
+
.akan-sub-route-name { color: var(--akan-foreground); font-size: 1.1rem; font-weight: 800; letter-spacing: -0.02em; }
|
|
15
|
+
.akan-sub-route-path { color: rgba(255, 255, 255, 0.66); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 0.85rem; }
|
|
16
|
+
.akan-sub-route-hosts { color: var(--akan-accent); font-size: 0.76rem; letter-spacing: 0.06em; overflow-wrap: anywhere; }
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
export const getSubRouteIndexHref = (locale: string, basePath: string): string => `/${locale}/${basePath}`;
|
|
20
|
+
|
|
21
|
+
export function createSubRouteIndexDocument({ locale, basePaths, subRoutes = {} }: SubRouteIndexOptions): ReactNode {
|
|
22
|
+
return (
|
|
23
|
+
<html lang={locale}>
|
|
24
|
+
<head>
|
|
25
|
+
<meta charSet="utf-8" />
|
|
26
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
27
|
+
<meta name="robots" content="noindex" />
|
|
28
|
+
<title>Sub routes</title>
|
|
29
|
+
<style data-akan-system-page>{`${SYSTEM_PAGE_STYLE}${SUB_ROUTE_INDEX_STYLE}`}</style>
|
|
30
|
+
</head>
|
|
31
|
+
<body>
|
|
32
|
+
<main className="akan-system-page">
|
|
33
|
+
<section className="akan-system-card" aria-labelledby="akan-sub-route-title">
|
|
34
|
+
<p className="akan-system-eyebrow">Local dev</p>
|
|
35
|
+
<h1 id="akan-sub-route-title" className="akan-system-title">
|
|
36
|
+
Pick a sub route.
|
|
37
|
+
</h1>
|
|
38
|
+
<p className="akan-system-description">
|
|
39
|
+
This app serves every route under a sub path, so the site root has no page of its own. Only local runs see
|
|
40
|
+
this list; deployed hosts map straight onto one sub route.
|
|
41
|
+
</p>
|
|
42
|
+
<ul className="akan-sub-route-list">
|
|
43
|
+
{basePaths.map((basePath) => {
|
|
44
|
+
const hosts = subRoutes[basePath] ?? [];
|
|
45
|
+
return (
|
|
46
|
+
<li key={basePath}>
|
|
47
|
+
<a className="akan-sub-route-link" href={getSubRouteIndexHref(locale, basePath)}>
|
|
48
|
+
<span className="akan-sub-route-name">{basePath}</span>
|
|
49
|
+
<span className="akan-sub-route-path">{getSubRouteIndexHref(locale, basePath)}</span>
|
|
50
|
+
{hosts.length ? <span className="akan-sub-route-hosts">{hosts.join(", ")}</span> : null}
|
|
51
|
+
</a>
|
|
52
|
+
</li>
|
|
53
|
+
);
|
|
54
|
+
})}
|
|
55
|
+
</ul>
|
|
56
|
+
</section>
|
|
57
|
+
</main>
|
|
58
|
+
</body>
|
|
59
|
+
</html>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
@@ -38,7 +38,7 @@ export const SYSTEM_PAGE_STATUS_COPY = {
|
|
|
38
38
|
},
|
|
39
39
|
} as const;
|
|
40
40
|
|
|
41
|
-
const
|
|
41
|
+
export const SYSTEM_PAGE_STYLE = `
|
|
42
42
|
:root { color-scheme: dark; --akan-primary: #ff493b; --akan-secondary: #2b2e33; --akan-accent: #d1a23b; --akan-foreground: #ffffff; --akan-background: #1a1a1a; --akan-base-200: #2a2a2a; --akan-error: #f02020; }
|
|
43
43
|
body { margin: 0; min-height: 100vh; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: var(--akan-background); color: var(--akan-foreground); }
|
|
44
44
|
a { color: inherit; }
|
|
@@ -70,7 +70,7 @@ export function createSystemPageDocument(options: SystemPageOptions): ReactNode
|
|
|
70
70
|
{options.stylesheetHref ? (
|
|
71
71
|
<link rel="stylesheet" href={options.stylesheetHref} precedence="default" data-akan-css="active" />
|
|
72
72
|
) : null}
|
|
73
|
-
<style data-akan-system-page>{
|
|
73
|
+
<style data-akan-system-page>{SYSTEM_PAGE_STYLE}</style>
|
|
74
74
|
</head>
|
|
75
75
|
<body>
|
|
76
76
|
<main className="akan-system-page min-h-screen bg-background text-foreground">
|
package/server/systemPages.tsx
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { createSubRouteIndexDocument, getSubRouteIndexHref, type SubRouteIndexOptions } from "./subRouteIndexDocument";
|
|
1
3
|
import {
|
|
2
4
|
createSystemPageDocument,
|
|
3
5
|
SYSTEM_PAGE_STATUS_COPY,
|
|
@@ -9,26 +11,28 @@ export interface SystemPageResponseOptions extends SystemPageOptions {
|
|
|
9
11
|
method?: string;
|
|
10
12
|
}
|
|
11
13
|
|
|
14
|
+
export interface SubRouteIndexResponseOptions extends SubRouteIndexOptions {
|
|
15
|
+
method?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
export { createSystemPageDocument, getSystemPageHomeHref } from "./systemPageDocument";
|
|
13
19
|
|
|
14
20
|
export async function createSystemPageResponse(options: SystemPageResponseOptions): Promise<Response> {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
return await renderDocumentResponse({
|
|
22
|
+
status: SYSTEM_PAGE_STATUS_COPY[options.kind].status,
|
|
23
|
+
method: options.method,
|
|
24
|
+
document: () => createSystemPageDocument(options),
|
|
25
|
+
fallbackText: () => createSystemPageFallbackText(options.kind),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
18
28
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
headers: {
|
|
27
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
28
|
-
"Cache-Control": "no-store",
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
}
|
|
29
|
+
export async function createSubRouteIndexResponse(options: SubRouteIndexResponseOptions): Promise<Response> {
|
|
30
|
+
return await renderDocumentResponse({
|
|
31
|
+
status: 200,
|
|
32
|
+
method: options.method,
|
|
33
|
+
document: () => createSubRouteIndexDocument(options),
|
|
34
|
+
fallbackText: () => options.basePaths.map((basePath) => getSubRouteIndexHref(options.locale, basePath)).join("\n"),
|
|
35
|
+
});
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
export function createSystemPageHeaders(): Headers {
|
|
@@ -42,3 +46,32 @@ export function createSystemPageFallbackText(kind: SystemPageKind): string {
|
|
|
42
46
|
const copy = SYSTEM_PAGE_STATUS_COPY[kind];
|
|
43
47
|
return `${copy.status} ${copy.eyebrow}`;
|
|
44
48
|
}
|
|
49
|
+
|
|
50
|
+
async function renderDocumentResponse({
|
|
51
|
+
status,
|
|
52
|
+
method,
|
|
53
|
+
document,
|
|
54
|
+
fallbackText,
|
|
55
|
+
}: {
|
|
56
|
+
status: number;
|
|
57
|
+
method?: string;
|
|
58
|
+
document: () => ReactNode;
|
|
59
|
+
fallbackText: () => string;
|
|
60
|
+
}): Promise<Response> {
|
|
61
|
+
const headers = createSystemPageHeaders();
|
|
62
|
+
if (method === "HEAD") return new Response(null, { status, headers });
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const { renderToReadableStream } = await import("react-dom/server.browser");
|
|
66
|
+
const stream = await renderToReadableStream(document());
|
|
67
|
+
return new Response(stream, { status, headers });
|
|
68
|
+
} catch {
|
|
69
|
+
return new Response(fallbackText(), {
|
|
70
|
+
status,
|
|
71
|
+
headers: {
|
|
72
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
73
|
+
"Cache-Control": "no-store",
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "akanjs/fetch";
|