akanjs 2.2.4-rc.4 → 2.2.4
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/base/base.test.ts +135 -0
- package/base/base.ts +1 -1
- package/base/baseEnv.test.ts +146 -0
- package/base/primitiveRegistry.test.ts +127 -0
- package/base/primitiveRegistry.ts +10 -6
- package/base/symbols.test.ts +29 -0
- package/base/types.ts +4 -1
- package/base/utils.test.ts +30 -0
- package/build.ts +318 -0
- package/capacitor.base.config.test.ts +83 -0
- package/capacitor.base.config.ts +1 -1
- package/client/capacitor.ts +1 -1
- package/client/client.auth-storage.test.ts +210 -0
- package/client/client.decorators.test.ts +74 -0
- package/client/client.device.test.ts +181 -0
- package/client/client.page.test.tsx +175 -0
- package/client/client.pure.test.ts +146 -0
- package/client/client.router.test.ts +290 -0
- package/client/cookie.ts +4 -2
- package/client/createFont.ts +2 -2
- package/client/csrTypes.ts +8 -2
- package/client/makePageProto.tsx +10 -4
- package/client/router.ts +8 -3
- package/client/translator.ts +12 -4
- package/common/Logger.test.ts +45 -0
- package/common/Logger.ts +4 -1
- package/common/formatAndValidation.test.ts +61 -0
- package/common/formatNumber.ts +5 -2
- package/common/hmrPhase.ts +1 -1
- package/common/httpClient.test.ts +91 -0
- package/common/isValidDate.ts +3 -0
- package/common/objectPath.test.ts +108 -0
- package/common/routeConvention.test.ts +132 -0
- package/common/runtimeConfig.test.ts +84 -0
- package/constant/constant.test.ts +374 -0
- package/constant/fieldInfo.ts +3 -3
- package/constant/purify.ts +2 -1
- package/constant/types.ts +4 -0
- package/constant/via.ts +12 -6
- package/dictionary/dictionary.test.ts +352 -0
- package/document/databaseRegistry.ts +8 -0
- package/document/document.test.ts +698 -0
- package/document/into.ts +1 -0
- package/fetch/client/fetchClient.ts +6 -1
- package/fetch/client/httpClient.ts +2 -1
- package/fetch/fetch.test.ts +838 -0
- package/fetch/fetchType/appliedReturn.type.ts +1 -0
- package/fetch/fetchType/endpointFetch.type.ts +3 -0
- package/fetch/fetchType/sliceFetch.type.ts +8 -0
- package/fetch/requestStorage.ts +10 -2
- package/package.json +24 -67
- package/server/akanApp.test.ts +130 -0
- package/server/akanApp.ts +5 -2
- package/server/akanLib.ts +1 -0
- package/server/akanServer.test.ts +157 -0
- package/server/akanServer.ts +4 -3
- package/server/artifact/builderRpc.ts +2 -2
- package/server/artifact/ipcTypes.ts +4 -0
- package/server/artifact/routeClientCache.test.ts +265 -0
- package/server/artifact/routeSeedIndex.test.ts +56 -0
- package/server/artifact/routesManifest.test.ts +64 -0
- package/server/decorators.ts +1 -1
- package/server/di/diLifecycle.contract.test.ts +168 -0
- package/server/di/diLifecycle.ts +6 -3
- package/server/hmr/clientScript.ts +20 -2
- package/server/hmr/devHmrController.ts +4 -0
- package/server/logging/rotatingLogWriter.test.ts +119 -0
- package/server/processMetrics.test.ts +24 -0
- package/server/processMetricsCollector.ts +1 -1
- package/server/proxy/webProxyRunner.test.ts +66 -0
- package/server/resolver/database.resolver.ts +2 -2
- package/server/resolver/resolver.contract.fixture.ts +1 -0
- package/server/resolver/resolver.contract.test.ts +594 -0
- package/server/resolver/signal.resolver.ts +10 -2
- package/server/robots.test.ts +16 -0
- package/server/routeTree.test.tsx +198 -0
- package/server/routing/apiRouter.test.ts +136 -0
- package/server/routing/apiRouter.ts +4 -2
- package/server/rscClient.tsx +7 -1
- package/server/rscWorkerHost.ts +33 -11
- package/server/sitemap.test.ts +61 -0
- package/server/ssrFromRscRenderer.tsx +35 -3
- package/server/systemPages.test.tsx +93 -0
- package/server/types/react-server-dom-webpack.d.ts +7 -1
- package/server/vendor/react-dom-client.ts +1 -1
- package/server/vendor/react-dom.ts +3 -2
- package/server/vendor/react-jsx-dev-runtime.ts +1 -1
- package/server/vendor/react-jsx-runtime.ts +1 -1
- package/server/vendor/react-refresh-runtime.ts +2 -2
- package/server/vendor/react-server-dom-webpack-client-browser.ts +1 -1
- package/server/vendor/react.ts +9 -2
- package/server/vendor/scheduler.ts +3 -2
- package/server/webRouter.test.ts +49 -0
- package/server/webRouter.ts +3 -2
- package/service/adapt.ts +5 -1
- package/service/predefinedAdaptor/cache.adaptor.ts +2 -1
- package/service/predefinedAdaptor/compress.adaptor.test.ts +184 -0
- package/service/predefinedAdaptor/database.adaptor.ts +20 -8
- package/service/predefinedAdaptor/solidCache.adaptor.test.ts +107 -0
- package/service/predefinedAdaptor/solidSqlite.test.ts +457 -0
- package/service/predefinedAdaptor/solidSqlite.ts +2 -1
- package/service/predefinedAdaptor/websocket.adaptor.ts +15 -3
- package/service/serve.ts +7 -3
- package/service/service.test.ts +732 -0
- package/signal/base.signal.ts +1 -0
- package/signal/endpointInfo.ts +7 -0
- package/signal/intercept.ts +2 -0
- package/signal/middleware.ts +2 -1
- package/signal/serverSignal.ts +15 -1
- package/signal/signal.test.ts +892 -0
- package/signal/signalContext.ts +1 -1
- package/signal/signalRegistry.ts +5 -0
- package/signal/sliceInfo.ts +3 -0
- package/signal/trace.ts +11 -0
- package/signal/types.ts +11 -2
- package/store/action.ts +5 -3
- package/store/stateBuilder.test.ts +168 -0
- package/store/stateBuilder.ts +2 -0
- package/store/stateInfo.ts +2 -1
- package/store/store.test.ts +427 -0
- package/store/types.ts +1 -1
- package/test/playwright.config.base.ts +28 -5
- package/test/playwright.pageAgent.ts +1 -1
- package/test/sampleOf.ts +1 -1
- package/test/testServer.ts +1 -1
- package/tsconfig.json +5 -0
- package/ui/BottomSheet.tsx +1 -1
- package/ui/Clipboard.tsx +1 -1
- package/ui/Constant/schemaDoc.test.ts +113 -0
- package/ui/CsrImage.tsx +14 -3
- package/ui/Data/ListContainer.tsx +1 -1
- package/ui/Data/Pagination.tsx +1 -1
- package/ui/Data/QueryMaker.tsx +339 -0
- package/ui/Data/index.ts +1 -0
- package/ui/DatePicker.tsx +95 -1
- package/ui/Dialog/Modal.tsx +1 -1
- package/ui/DraggableList.tsx +5 -5
- package/ui/Field.tsx +3 -2
- package/ui/Image.tsx +3 -2
- package/ui/InfiniteScroll.test.tsx +155 -0
- package/ui/InfiniteScroll.tsx +1 -0
- package/ui/Input.tsx +8 -1
- package/ui/Layout/BottomTab.tsx +2 -2
- package/ui/Link/SsrLink.tsx +2 -1
- package/ui/Load/Page.tsx +1 -1
- package/ui/Load/PageCSR.tsx +1 -0
- package/ui/Load/Units.tsx +2 -1
- package/ui/Load/View.tsx +2 -1
- package/ui/Menu.tsx +8 -5
- package/ui/Model/EditModal.tsx +5 -2
- package/ui/Popconfirm.tsx +4 -2
- package/ui/ScreenNavigator.tsx +3 -2
- package/ui/Signal/Message.tsx +3 -2
- package/ui/Signal/PubSub.tsx +2 -0
- package/ui/Signal/Response.tsx +1 -1
- package/ui/Signal/WebSocket.tsx +11 -2
- package/ui/System/Client.tsx +41 -7
- package/ui/System/Common.test.ts +37 -0
- package/ui/System/Gtag.tsx +5 -2
- package/ui/System/Messages.tsx +2 -2
- package/ui/System/Reconnect.tsx +6 -5
- package/ui/System/Root.tsx +1 -0
- package/ui/System/SSR.tsx +7 -1
- package/ui/ToggleSelect.tsx +8 -3
- package/ui/Unauthorized.tsx +1 -1
- package/webkit/bootCsr.test.tsx +153 -0
- package/webkit/bootCsr.tsx +6 -3
- package/webkit/lazy.tsx +8 -1
- package/webkit/native.test.tsx +341 -0
- package/webkit/useCamera.tsx +1 -0
- package/webkit/useCodepush.tsx +9 -4
- package/webkit/useContact.tsx +1 -0
- package/webkit/useCsrValues.ts +10 -6
- package/webkit/useDebounce.ts +2 -2
- package/webkit/usePurchase.tsx +9 -5
- package/webkit/usePushNoti.tsx +1 -0
- package/webkit/webkit.test.tsx +531 -0
- package/types/base/base.d.ts +0 -53
- package/types/base/baseEnv.d.ts +0 -68
- package/types/base/index.d.ts +0 -6
- package/types/base/primitiveRegistry.d.ts +0 -134
- package/types/base/symbols.d.ts +0 -11
- package/types/base/types.d.ts +0 -68
- package/types/base/utils.d.ts +0 -4
- package/types/base.d.ts +0 -1
- package/types/capacitor.base.config.d.ts +0 -3
- package/types/client/capacitor.d.ts +0 -233
- package/types/client/clientRuntime.d.ts +0 -63
- package/types/client/cookie.d.ts +0 -33
- package/types/client/createFont.d.ts +0 -6
- package/types/client/csrTypes.d.ts +0 -262
- package/types/client/decorators.d.ts +0 -7
- package/types/client/device.d.ts +0 -41
- package/types/client/fetch.d.ts +0 -1
- package/types/client/index.d.ts +0 -14
- package/types/client/locale.d.ts +0 -5
- package/types/client/makePageProto.d.ts +0 -17002
- package/types/client/router.d.ts +0 -66
- package/types/client/rscNavigation.d.ts +0 -19
- package/types/client/storage.d.ts +0 -5
- package/types/client/translator.d.ts +0 -18
- package/types/client/types.d.ts +0 -145
- package/types/client/useClient.d.ts +0 -1
- package/types/client.d.ts +0 -1
- package/types/common/Logger.d.ts +0 -41
- package/types/common/applyMixins.d.ts +0 -3
- package/types/common/capitalize.d.ts +0 -2
- package/types/common/deepObjectify.d.ts +0 -4
- package/types/common/fileUpload.d.ts +0 -28
- package/types/common/formatNumber.d.ts +0 -1
- package/types/common/formatPhone.d.ts +0 -2
- package/types/common/getAllPropertyDescriptors.d.ts +0 -5
- package/types/common/hmrPhase.d.ts +0 -6
- package/types/common/httpClient.d.ts +0 -20
- package/types/common/index.d.ts +0 -29
- package/types/common/isDayjs.d.ts +0 -2
- package/types/common/isEmail.d.ts +0 -2
- package/types/common/isPhoneNumber.d.ts +0 -2
- package/types/common/isQueryEqual.d.ts +0 -1
- package/types/common/isValidDate.d.ts +0 -2
- package/types/common/jwtDecode.d.ts +0 -2
- package/types/common/localeConfig.d.ts +0 -11
- package/types/common/lowerlize.d.ts +0 -2
- package/types/common/mergeVersion.d.ts +0 -10
- package/types/common/objectify.d.ts +0 -1
- package/types/common/pathGet.d.ts +0 -1
- package/types/common/pathSet.d.ts +0 -3
- package/types/common/randomPick.d.ts +0 -1
- package/types/common/randomPicks.d.ts +0 -1
- package/types/common/routeConvention.d.ts +0 -35
- package/types/common/sleep.d.ts +0 -2
- package/types/common/splitVersion.d.ts +0 -11
- package/types/common/subRoute.d.ts +0 -7
- package/types/common/types.d.ts +0 -14
- package/types/common.d.ts +0 -1
- package/types/constant/constantRegistry.d.ts +0 -89
- package/types/constant/crystalize.d.ts +0 -4
- package/types/constant/deserialize.d.ts +0 -7
- package/types/constant/fieldInfo.d.ts +0 -153
- package/types/constant/getDefault.d.ts +0 -3
- package/types/constant/immerify.d.ts +0 -2
- package/types/constant/index.d.ts +0 -10
- package/types/constant/purify.d.ts +0 -12
- package/types/constant/serialize.d.ts +0 -11
- package/types/constant/types.d.ts +0 -77
- package/types/constant/via.d.ts +0 -52
- package/types/constant.d.ts +0 -1
- package/types/dictionary/base.dictionary.d.ts +0 -1
- package/types/dictionary/dictInfo.d.ts +0 -206
- package/types/dictionary/dictionary.d.ts +0 -11
- package/types/dictionary/index.d.ts +0 -4
- package/types/dictionary/locale.d.ts +0 -128
- package/types/dictionary/trans.d.ts +0 -82
- package/types/dictionary.d.ts +0 -1
- package/types/document/by.d.ts +0 -20
- package/types/document/dataLoader.d.ts +0 -36
- package/types/document/database.d.ts +0 -96
- package/types/document/databaseRegistry.d.ts +0 -36
- package/types/document/documentQuery.d.ts +0 -105
- package/types/document/documentSchema.d.ts +0 -33
- package/types/document/filterMeta.d.ts +0 -84
- package/types/document/index.d.ts +0 -11
- package/types/document/into.d.ts +0 -65
- package/types/document/loaderInfo.d.ts +0 -35
- package/types/document/schema.d.ts +0 -5
- package/types/document/types.d.ts +0 -36
- package/types/document.d.ts +0 -1
- package/types/fetch/client/fetchClient.d.ts +0 -78
- package/types/fetch/client/httpClient.d.ts +0 -39
- package/types/fetch/client/index.d.ts +0 -3
- package/types/fetch/client/wsClient.d.ts +0 -37
- package/types/fetch/client.d.ts +0 -1
- package/types/fetch/fetchType/appliedReturn.type.d.ts +0 -67
- package/types/fetch/fetchType/buildFetch.type.d.ts +0 -11
- package/types/fetch/fetchType/clientSignal.type.d.ts +0 -16
- package/types/fetch/fetchType/endpointFetch.type.d.ts +0 -29
- package/types/fetch/fetchType/index.d.ts +0 -5
- package/types/fetch/fetchType/sliceFetch.type.d.ts +0 -76
- package/types/fetch/fetchType.d.ts +0 -1
- package/types/fetch/index.d.ts +0 -4
- package/types/fetch/requestStorage.d.ts +0 -29
- package/types/fetch/serializer/fetch.serializer.d.ts +0 -14
- package/types/fetch/serializer/index.d.ts +0 -1
- package/types/fetch/serializer.d.ts +0 -1
- package/types/fetch/types.d.ts +0 -19
- package/types/fetch.d.ts +0 -1
- package/types/index.d.ts +0 -213
- package/types/server/akanApp.d.ts +0 -17
- package/types/server/akanAppHeaders.d.ts +0 -1
- package/types/server/akanLib.d.ts +0 -33
- package/types/server/akanOption.d.ts +0 -15
- package/types/server/akanServer.d.ts +0 -47
- package/types/server/artifact/builderRpc.d.ts +0 -42
- package/types/server/artifact/index.d.ts +0 -6
- package/types/server/artifact/ipcTypes.d.ts +0 -73
- package/types/server/artifact/manifestTypes.d.ts +0 -16
- package/types/server/artifact/routeClientCache.d.ts +0 -45
- package/types/server/artifact/routeSeedIndexStore.d.ts +0 -43
- package/types/server/artifact/routesManifestStore.d.ts +0 -16
- package/types/server/artifact.d.ts +0 -1
- package/types/server/decorators.d.ts +0 -6
- package/types/server/di/diLifecycle.d.ts +0 -45
- package/types/server/di/index.d.ts +0 -4
- package/types/server/di/predefinedAdaptor.d.ts +0 -33
- package/types/server/di/resolveAdaptorHierarchy.d.ts +0 -21
- package/types/server/di/resolveHierarchy.d.ts +0 -11
- package/types/server/di/resolveServiceHierarchy.d.ts +0 -13
- package/types/server/di/utils.d.ts +0 -14
- package/types/server/di.d.ts +0 -1
- package/types/server/hmr/changeBatch.d.ts +0 -13
- package/types/server/hmr/clientScript.d.ts +0 -1
- package/types/server/hmr/devHmrController.d.ts +0 -24
- package/types/server/hmr/index.d.ts +0 -4
- package/types/server/hmr/wsHub.d.ts +0 -45
- package/types/server/hmr.d.ts +0 -1
- package/types/server/imageOptimizer.d.ts +0 -12
- package/types/server/imageOptimizerError.d.ts +0 -4
- package/types/server/index.d.ts +0 -14
- package/types/server/lifecycle/shutdownManager.d.ts +0 -13
- package/types/server/logging/rotatingLogWriter.d.ts +0 -20
- package/types/server/processMetricsCollector.d.ts +0 -10
- package/types/server/proxy/akanResponse.d.ts +0 -7
- package/types/server/proxy/bunRequestFields.d.ts +0 -1
- package/types/server/proxy/hostBasePathWebProxy.d.ts +0 -6
- package/types/server/proxy/index.d.ts +0 -6
- package/types/server/proxy/localeWebProxy.d.ts +0 -5
- package/types/server/proxy/types.d.ts +0 -37
- package/types/server/proxy/webProxyRunner.d.ts +0 -7
- package/types/server/proxy.d.ts +0 -1
- package/types/server/resolver/database.resolver.d.ts +0 -6
- package/types/server/resolver/index.d.ts +0 -3
- package/types/server/resolver/service.resolver.d.ts +0 -7
- package/types/server/resolver/signal.resolver.d.ts +0 -29
- package/types/server/resolver.d.ts +0 -1
- package/types/server/robots.d.ts +0 -1
- package/types/server/routeElementComposer.d.ts +0 -41
- package/types/server/routeTreeBuilder.d.ts +0 -28
- package/types/server/routing/apiRouter.d.ts +0 -61
- package/types/server/rscClient.d.ts +0 -15
- package/types/server/rscWorker.d.ts +0 -3
- package/types/server/rscWorkerHost.d.ts +0 -83
- package/types/server/sitemap.d.ts +0 -13
- package/types/server/ssrFromRscRenderer.d.ts +0 -6
- package/types/server/ssrTypes.d.ts +0 -47
- package/types/server/systemPages.d.ts +0 -27
- package/types/server/types/react-server-dom-webpack.d.ts +0 -91
- package/types/server/types.d.ts +0 -67
- package/types/server/vendor/akanjs-base.d.ts +0 -1
- package/types/server/vendor/akanjs-common.d.ts +0 -1
- package/types/server/vendor/akanjs-constant.d.ts +0 -1
- package/types/server/vendor/akanjs-store.d.ts +0 -1
- package/types/server/vendor/react-dom-client.d.ts +0 -3
- package/types/server/vendor/react-dom.d.ts +0 -3
- package/types/server/vendor/react-jsx-dev-runtime.d.ts +0 -3
- package/types/server/vendor/react-jsx-runtime.d.ts +0 -3
- package/types/server/vendor/react-refresh-runtime.d.ts +0 -3
- package/types/server/vendor/react-server-dom-webpack-client-browser.d.ts +0 -3
- package/types/server/vendor/react.d.ts +0 -11
- package/types/server/vendor/scheduler.d.ts +0 -3
- package/types/server/webRouter.d.ts +0 -44
- package/types/server.d.ts +0 -1
- package/types/service/adapt.d.ts +0 -15
- package/types/service/base.service.d.ts +0 -18
- package/types/service/index.d.ts +0 -10
- package/types/service/injectInfo.d.ts +0 -102
- package/types/service/ipcTypes.d.ts +0 -194
- package/types/service/predefinedAdaptor/cache.adaptor.d.ts +0 -46
- package/types/service/predefinedAdaptor/compress.adaptor.d.ts +0 -22
- package/types/service/predefinedAdaptor/database.adaptor.d.ts +0 -329
- package/types/service/predefinedAdaptor/index.d.ts +0 -13
- package/types/service/predefinedAdaptor/logging.adaptor.d.ts +0 -20
- package/types/service/predefinedAdaptor/queue.adaptor.d.ts +0 -22
- package/types/service/predefinedAdaptor/role.adaptor.d.ts +0 -17
- package/types/service/predefinedAdaptor/schedule.adaptor.d.ts +0 -60
- package/types/service/predefinedAdaptor/solidCache.adaptor.d.ts +0 -25
- package/types/service/predefinedAdaptor/solidPubsub.adaptor.d.ts +0 -20
- package/types/service/predefinedAdaptor/solidQueue.adaptor.d.ts +0 -19
- package/types/service/predefinedAdaptor/solidSqlite.d.ts +0 -24
- package/types/service/predefinedAdaptor/sqlitePath.d.ts +0 -9
- package/types/service/predefinedAdaptor/storage.adaptor.d.ts +0 -80
- package/types/service/predefinedAdaptor/websocket.adaptor.d.ts +0 -49
- package/types/service/predefinedAdaptor.d.ts +0 -1
- package/types/service/serve.d.ts +0 -31
- package/types/service/serviceModule.d.ts +0 -50
- package/types/service/serviceRegistry.d.ts +0 -9
- package/types/service/types.d.ts +0 -55
- package/types/service.d.ts +0 -1
- package/types/signal/base.signal.d.ts +0 -41
- package/types/signal/endpoint.d.ts +0 -28
- package/types/signal/endpointInfo.d.ts +0 -77
- package/types/signal/exception.d.ts +0 -54786
- package/types/signal/guard.d.ts +0 -10
- package/types/signal/guards.d.ts +0 -10
- package/types/signal/index.d.ts +0 -19
- package/types/signal/intercept.d.ts +0 -17
- package/types/signal/internal.d.ts +0 -18
- package/types/signal/internalArg.d.ts +0 -31
- package/types/signal/internalInfo.d.ts +0 -45
- package/types/signal/middleware.d.ts +0 -51
- package/types/signal/serializer/fetch.serializer.d.ts +0 -14
- package/types/signal/serializer/index.d.ts +0 -1
- package/types/signal/serializer.d.ts +0 -1
- package/types/signal/serverSignal.d.ts +0 -36
- package/types/signal/signalContext.d.ts +0 -96
- package/types/signal/signalRegistry.d.ts +0 -49
- package/types/signal/slice.d.ts +0 -42
- package/types/signal/sliceInfo.d.ts +0 -51
- package/types/signal/trace.d.ts +0 -97
- package/types/signal/types.d.ts +0 -142
- package/types/signal.d.ts +0 -1
- package/types/store/action.d.ts +0 -145
- package/types/store/baseSt.d.ts +0 -412
- package/types/store/hooks.d.ts +0 -1
- package/types/store/index.d.ts +0 -8
- package/types/store/rootStore.d.ts +0 -22
- package/types/store/state.d.ts +0 -91
- package/types/store/stateBuilder.d.ts +0 -141
- package/types/store/stateInfo.d.ts +0 -23
- package/types/store/store.d.ts +0 -36
- package/types/store/storeInstance.d.ts +0 -38
- package/types/store/storeRegistry.d.ts +0 -13
- package/types/store/types.d.ts +0 -42
- package/types/store/withSelector.d.ts +0 -42
- package/types/store.d.ts +0 -1
- package/types/test/index.d.ts +0 -4
- package/types/test/playwright.config.base.d.ts +0 -9
- package/types/test/playwright.pageAgent.d.ts +0 -12
- package/types/test/sample.d.ts +0 -15
- package/types/test/sampleOf.d.ts +0 -5
- package/types/test/signalTest.preload.d.ts +0 -1
- package/types/test/signalTestRuntime.d.ts +0 -29
- package/types/test/testServer.d.ts +0 -26
- package/types/test.d.ts +0 -1
- package/types/ui/BottomSheet.d.ts +0 -13
- package/types/ui/Button.d.ts +0 -11
- package/types/ui/ClientSide.d.ts +0 -8
- package/types/ui/Clipboard.d.ts +0 -7
- package/types/ui/Constant/Doc.d.ts +0 -29
- package/types/ui/Constant/Mermaid.d.ts +0 -8
- package/types/ui/Constant/index.d.ts +0 -6
- package/types/ui/Constant/schemaDoc.d.ts +0 -84
- package/types/ui/Constant.d.ts +0 -1
- package/types/ui/Copy.d.ts +0 -10
- package/types/ui/CsrImage.d.ts +0 -18
- package/types/ui/Data/CardList.d.ts +0 -36
- package/types/ui/Data/Dashboard.d.ts +0 -11
- package/types/ui/Data/Insight.d.ts +0 -9
- package/types/ui/Data/Item.d.ts +0 -75
- package/types/ui/Data/ListContainer.d.ts +0 -49
- package/types/ui/Data/Pagination.d.ts +0 -9
- package/types/ui/Data/QueryMaker.d.ts +0 -8
- package/types/ui/Data/TableList.d.ts +0 -26
- package/types/ui/Data/index.d.ts +0 -9
- package/types/ui/Data/index_.d.ts +0 -8
- package/types/ui/Data.d.ts +0 -1
- package/types/ui/DatePicker.d.ts +0 -36
- package/types/ui/Dialog/Action.d.ts +0 -5
- package/types/ui/Dialog/Close.d.ts +0 -6
- package/types/ui/Dialog/Content.d.ts +0 -6
- package/types/ui/Dialog/Modal.d.ts +0 -9
- package/types/ui/Dialog/Provider.d.ts +0 -11
- package/types/ui/Dialog/Title.d.ts +0 -5
- package/types/ui/Dialog/Trigger.d.ts +0 -6
- package/types/ui/Dialog/context.d.ts +0 -10
- package/types/ui/Dialog/index.d.ts +0 -9
- package/types/ui/Dialog.d.ts +0 -1
- package/types/ui/DragAction.d.ts +0 -24
- package/types/ui/DraggableList.d.ts +0 -31
- package/types/ui/Dropdown.d.ts +0 -14
- package/types/ui/Empty.d.ts +0 -12
- package/types/ui/Field.d.ts +0 -411
- package/types/ui/FontFace.d.ts +0 -6
- package/types/ui/Image.d.ts +0 -49
- package/types/ui/InfiniteScroll.d.ts +0 -10
- package/types/ui/Input.d.ts +0 -95
- package/types/ui/KeyboardAvoiding.d.ts +0 -8
- package/types/ui/Layout/BottomAction.d.ts +0 -6
- package/types/ui/Layout/BottomInset.d.ts +0 -7
- package/types/ui/Layout/BottomTab.d.ts +0 -14
- package/types/ui/Layout/Header.d.ts +0 -8
- package/types/ui/Layout/LeftSider.d.ts +0 -9
- package/types/ui/Layout/Navbar.d.ts +0 -11
- package/types/ui/Layout/RightSider.d.ts +0 -10
- package/types/ui/Layout/Sider.d.ts +0 -7
- package/types/ui/Layout/Template.d.ts +0 -7
- package/types/ui/Layout/TopLeftAction.d.ts +0 -6
- package/types/ui/Layout/Unit.d.ts +0 -9
- package/types/ui/Layout/View.d.ts +0 -8
- package/types/ui/Layout/Zone.d.ts +0 -6
- package/types/ui/Layout/index.d.ts +0 -14
- package/types/ui/Layout.d.ts +0 -1
- package/types/ui/Link/Back.d.ts +0 -7
- package/types/ui/Link/Close.d.ts +0 -7
- package/types/ui/Link/CsrLink.d.ts +0 -2
- package/types/ui/Link/Lang.d.ts +0 -8
- package/types/ui/Link/SsrLink.d.ts +0 -2
- package/types/ui/Link/index.d.ts +0 -10
- package/types/ui/Link/types.d.ts +0 -42
- package/types/ui/Link.d.ts +0 -1
- package/types/ui/Load/Edit.d.ts +0 -4
- package/types/ui/Load/Edit_Client.d.ts +0 -27
- package/types/ui/Load/Page.d.ts +0 -15
- package/types/ui/Load/PageCSR.d.ts +0 -3
- package/types/ui/Load/Pagination.d.ts +0 -8
- package/types/ui/Load/Units.d.ts +0 -30
- package/types/ui/Load/View.d.ts +0 -22
- package/types/ui/Load/index.d.ts +0 -8
- package/types/ui/Load/index_.d.ts +0 -3
- package/types/ui/Load.d.ts +0 -1
- package/types/ui/Loading/Area.d.ts +0 -1
- package/types/ui/Loading/Button.d.ts +0 -7
- package/types/ui/Loading/Input.d.ts +0 -7
- package/types/ui/Loading/ProgressBar.d.ts +0 -6
- package/types/ui/Loading/Skeleton.d.ts +0 -7
- package/types/ui/Loading/Spin.d.ts +0 -7
- package/types/ui/Loading/index.d.ts +0 -8
- package/types/ui/Loading.d.ts +0 -1
- package/types/ui/Menu.d.ts +0 -26
- package/types/ui/Modal.d.ts +0 -19
- package/types/ui/Model/AdminPanel.d.ts +0 -31
- package/types/ui/Model/Edit.d.ts +0 -16
- package/types/ui/Model/EditModal.d.ts +0 -52
- package/types/ui/Model/EditWrapper.d.ts +0 -13
- package/types/ui/Model/LoadInit.d.ts +0 -10
- package/types/ui/Model/New.d.ts +0 -16
- package/types/ui/Model/NewWrapper.d.ts +0 -13
- package/types/ui/Model/NewWrapper_Client.d.ts +0 -13
- package/types/ui/Model/Remove.d.ts +0 -13
- package/types/ui/Model/RemoveWrapper.d.ts +0 -12
- package/types/ui/Model/SureToRemove.d.ts +0 -11
- package/types/ui/Model/View.d.ts +0 -19
- package/types/ui/Model/ViewEditModal.d.ts +0 -12
- package/types/ui/Model/ViewModal.d.ts +0 -14
- package/types/ui/Model/ViewWrapper.d.ts +0 -12
- package/types/ui/Model/index.d.ts +0 -16
- package/types/ui/Model/index_.d.ts +0 -14
- package/types/ui/Model.d.ts +0 -1
- package/types/ui/More.d.ts +0 -12
- package/types/ui/ObjectId.d.ts +0 -5
- package/types/ui/Pagination.d.ts +0 -20
- package/types/ui/Popconfirm.d.ts +0 -28
- package/types/ui/Portal.d.ts +0 -6
- package/types/ui/Radio.d.ts +0 -19
- package/types/ui/RecentTime.d.ts +0 -12
- package/types/ui/Refresh.d.ts +0 -7
- package/types/ui/ScreenNavigator.d.ts +0 -18
- package/types/ui/Select.d.ts +0 -43
- package/types/ui/Signal/Arg.d.ts +0 -78
- package/types/ui/Signal/Doc.d.ts +0 -33
- package/types/ui/Signal/Listener.d.ts +0 -9
- package/types/ui/Signal/Message.d.ts +0 -23
- package/types/ui/Signal/Object.d.ts +0 -20
- package/types/ui/Signal/PubSub.d.ts +0 -24
- package/types/ui/Signal/Request.d.ts +0 -8
- package/types/ui/Signal/Response.d.ts +0 -14
- package/types/ui/Signal/RestApi.d.ts +0 -40
- package/types/ui/Signal/WebSocket.d.ts +0 -11
- package/types/ui/Signal/index.d.ts +0 -18
- package/types/ui/Signal/makeExample.d.ts +0 -4
- package/types/ui/Signal/style.d.ts +0 -15
- package/types/ui/Signal.d.ts +0 -1
- package/types/ui/System/CSR.d.ts +0 -32
- package/types/ui/System/Client.d.ts +0 -47
- package/types/ui/System/Common.d.ts +0 -47
- package/types/ui/System/DevModeToggle.d.ts +0 -1
- package/types/ui/System/Gtag.d.ts +0 -4
- package/types/ui/System/Messages.d.ts +0 -1
- package/types/ui/System/Reconnect.d.ts +0 -1
- package/types/ui/System/Root.d.ts +0 -6
- package/types/ui/System/SSR.d.ts +0 -24
- package/types/ui/System/SelectLanguage.d.ts +0 -5
- package/types/ui/System/ThemeToggle.d.ts +0 -4
- package/types/ui/System/index.d.ts +0 -12
- package/types/ui/System.d.ts +0 -1
- package/types/ui/Tab/Menu.d.ts +0 -12
- package/types/ui/Tab/Menus.d.ts +0 -6
- package/types/ui/Tab/Panel.d.ts +0 -8
- package/types/ui/Tab/Provider.d.ts +0 -10
- package/types/ui/Tab/context.d.ts +0 -9
- package/types/ui/Tab/index.d.ts +0 -7
- package/types/ui/Tab.d.ts +0 -1
- package/types/ui/Table.d.ts +0 -41
- package/types/ui/ToggleSelect.d.ts +0 -33
- package/types/ui/Unauthorized.d.ts +0 -9
- package/types/ui/animated.d.ts +0 -5
- package/types/ui/fontCss.d.ts +0 -11
- package/types/ui/index.d.ts +0 -44
- package/types/ui.d.ts +0 -1
- package/types/webkit/bootCsr.d.ts +0 -16
- package/types/webkit/createRobotPage.d.ts +0 -15
- package/types/webkit/createSitemapPage.d.ts +0 -4
- package/types/webkit/index.d.ts +0 -17
- package/types/webkit/lazy.d.ts +0 -11
- package/types/webkit/types.d.ts +0 -7
- package/types/webkit/useCamera.d.ts +0 -19
- package/types/webkit/useCodepush.d.ts +0 -16
- package/types/webkit/useContact.d.ts +0 -11
- package/types/webkit/useCsrValues.d.ts +0 -30
- package/types/webkit/useDebounce.d.ts +0 -2
- package/types/webkit/useFetch.d.ts +0 -18
- package/types/webkit/useGeoLocation.d.ts +0 -8
- package/types/webkit/useHistory.d.ts +0 -23
- package/types/webkit/useInterval.d.ts +0 -2
- package/types/webkit/useLocation.d.ts +0 -8
- package/types/webkit/usePurchase.d.ts +0 -19
- package/types/webkit/usePushNoti.d.ts +0 -7
- package/types/webkit/useThrottle.d.ts +0 -2
- package/types/webkit.d.ts +0 -1
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { Database, type SQLQueryBindings, type Statement } from "bun:sqlite";
|
|
2
|
+
import { describe, expect, test } from "bun:test";
|
|
3
|
+
import { dayjs, Int } from "akanjs/base";
|
|
4
|
+
import { ConstantRegistry, via } from "akanjs/constant";
|
|
5
|
+
import { by, type DatabaseCls, DatabaseRegistry, DocumentSchema, from, into } from "akanjs/document";
|
|
6
|
+
import { type AkanSqlClient, type AkanSqlStatement, SqliteDocumentStore } from "./database.adaptor";
|
|
7
|
+
import { decodeSolidValue, encodeSolidValue, getSolidConfig, toEpochMs } from "./solidSqlite";
|
|
8
|
+
import { resolveDefaultSqliteFile } from "./sqlitePath";
|
|
9
|
+
|
|
10
|
+
const InsightTestStatus = ["active", "failed", "deploying"] as const;
|
|
11
|
+
class InsightTestInput extends via((f) => ({
|
|
12
|
+
title: f(String),
|
|
13
|
+
score: f(Int, { default: 0 }),
|
|
14
|
+
status: f(String, { default: "active" }),
|
|
15
|
+
tags: f([String], { default: [] }),
|
|
16
|
+
})) {}
|
|
17
|
+
class InsightTestObject extends via(InsightTestInput, (f) => ({})) {}
|
|
18
|
+
class InsightTestLight extends via(InsightTestObject, ["title"] as const, () => ({})) {}
|
|
19
|
+
class InsightTestFull extends via(InsightTestObject, InsightTestLight, () => ({})) {}
|
|
20
|
+
class InsightTestInsight extends via(InsightTestFull, (f) => ({
|
|
21
|
+
count: f(Int, { default: 0, accumulate: {} }),
|
|
22
|
+
activeCount: f(Int, { default: 0, accumulate: { status: "active" } }),
|
|
23
|
+
runningCount: f(Int, { default: 0, accumulate: { status: { oneOf: ["active", "deploying"] } } }),
|
|
24
|
+
taggedCount: f(Int, { default: 0, accumulate: { tags: { oneOf: ["featured", "urgent"] } } }),
|
|
25
|
+
})) {}
|
|
26
|
+
const insightTestConstant = ConstantRegistry.buildModel(
|
|
27
|
+
"sqliteInsightTest",
|
|
28
|
+
InsightTestInput,
|
|
29
|
+
InsightTestObject,
|
|
30
|
+
InsightTestFull,
|
|
31
|
+
InsightTestLight,
|
|
32
|
+
InsightTestInsight,
|
|
33
|
+
{ InsightTestInput, InsightTestObject, InsightTestFull, InsightTestLight, InsightTestInsight, InsightTestStatus },
|
|
34
|
+
);
|
|
35
|
+
class InsightTestFilter extends from(InsightTestFull, () => ({})) {}
|
|
36
|
+
class InsightTestDoc extends by(InsightTestFull) {}
|
|
37
|
+
class InsightTestModel extends into(InsightTestDoc, InsightTestFilter, insightTestConstant, () => ({})) {}
|
|
38
|
+
const insightTestDatabase = DatabaseRegistry.buildModel(
|
|
39
|
+
"sqliteInsightTest",
|
|
40
|
+
InsightTestInput as unknown as DatabaseCls<InstanceType<typeof InsightTestInput>>,
|
|
41
|
+
InsightTestDoc,
|
|
42
|
+
InsightTestModel,
|
|
43
|
+
InsightTestObject,
|
|
44
|
+
InsightTestInsight,
|
|
45
|
+
InsightTestFilter,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
class TicketHistory extends via((f) => ({
|
|
49
|
+
action: f(String),
|
|
50
|
+
content: f([String], { default: [] }),
|
|
51
|
+
count: f(Int, { default: 0 }),
|
|
52
|
+
flag: f(Boolean, { default: false }),
|
|
53
|
+
})) {}
|
|
54
|
+
class TicketTestInput extends via((f) => ({
|
|
55
|
+
title: f(String),
|
|
56
|
+
status: f(String, { default: "active" }),
|
|
57
|
+
issuedAt: f(Date).optional(),
|
|
58
|
+
transactionAt: f(Date, { default: dayjs(0) }),
|
|
59
|
+
histories: f([TicketHistory]),
|
|
60
|
+
})) {}
|
|
61
|
+
class TicketTestObject extends via(TicketTestInput, (f) => ({})) {}
|
|
62
|
+
class TicketTestLight extends via(TicketTestObject, ["title"] as const, () => ({})) {}
|
|
63
|
+
class TicketTestFull extends via(TicketTestObject, TicketTestLight, () => ({})) {}
|
|
64
|
+
class TicketTestInsight extends via(TicketTestFull, (f) => ({
|
|
65
|
+
count: f(Int, { default: 0, accumulate: {} }),
|
|
66
|
+
})) {}
|
|
67
|
+
const ticketTestConstant = ConstantRegistry.buildModel(
|
|
68
|
+
"sqliteTicketTest",
|
|
69
|
+
TicketTestInput,
|
|
70
|
+
TicketTestObject,
|
|
71
|
+
TicketTestFull,
|
|
72
|
+
TicketTestLight,
|
|
73
|
+
TicketTestInsight,
|
|
74
|
+
{ TicketTestInput, TicketTestObject, TicketTestFull, TicketTestLight, TicketTestInsight, TicketHistory },
|
|
75
|
+
);
|
|
76
|
+
class TicketTestFilter extends from(TicketTestFull, () => ({})) {}
|
|
77
|
+
class TicketTestDoc extends by(TicketTestFull) {}
|
|
78
|
+
class TicketTestModel extends into(TicketTestDoc, TicketTestFilter, ticketTestConstant, () => ({})) {}
|
|
79
|
+
const ticketTestDatabase = DatabaseRegistry.buildModel(
|
|
80
|
+
"sqliteTicketTest",
|
|
81
|
+
TicketTestInput as unknown as DatabaseCls<InstanceType<typeof TicketTestInput>>,
|
|
82
|
+
TicketTestDoc,
|
|
83
|
+
TicketTestModel,
|
|
84
|
+
TicketTestObject,
|
|
85
|
+
TicketTestInsight,
|
|
86
|
+
TicketTestFilter,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
class TestSqliteStatement implements AkanSqlStatement {
|
|
90
|
+
constructor(private readonly statement: Statement) {}
|
|
91
|
+
|
|
92
|
+
async run(...params: unknown[]) {
|
|
93
|
+
return this.statement.run(...(params as SQLQueryBindings[]));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async get<Row = Record<string, unknown>>(...params: unknown[]): Promise<Row | null> {
|
|
97
|
+
return (this.statement.get(...(params as SQLQueryBindings[])) as Row | null) ?? null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async all<Row = Record<string, unknown>>(...params: unknown[]): Promise<Row[]> {
|
|
101
|
+
return this.statement.all(...(params as SQLQueryBindings[])) as Row[];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
class TestSqliteClient implements AkanSqlClient {
|
|
106
|
+
constructor(readonly db: Database) {}
|
|
107
|
+
|
|
108
|
+
async execute(sql: string, params: unknown[] | Record<string, unknown> = []) {
|
|
109
|
+
const values = Array.isArray(params) ? params : Object.values(params);
|
|
110
|
+
return this.db.query(sql).run(...(values as SQLQueryBindings[]));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
prepare(sql: string): AkanSqlStatement {
|
|
114
|
+
return new TestSqliteStatement(this.db.query(sql));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async close() {
|
|
118
|
+
this.db.close();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
class TestDatabaseOwner {
|
|
123
|
+
private readonly meta = new Map<string, string>();
|
|
124
|
+
readonly afterCommitCallbacks: (() => unknown)[] = [];
|
|
125
|
+
|
|
126
|
+
constructor(private readonly client: AkanSqlClient) {}
|
|
127
|
+
|
|
128
|
+
getConnection() {
|
|
129
|
+
return this.client;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
getMeta(key: string) {
|
|
133
|
+
return this.meta.get(key);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
setMeta(key: string, value: string) {
|
|
137
|
+
this.meta.set(key, value);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async afterCommit(fn: () => unknown) {
|
|
141
|
+
this.afterCommitCallbacks.push(fn);
|
|
142
|
+
await fn();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
describe("solid sqlite utilities", () => {
|
|
147
|
+
test("encodes and decodes solid values", () => {
|
|
148
|
+
const buffer = Buffer.from("hello");
|
|
149
|
+
|
|
150
|
+
expect(encodeSolidValue("value")).toEqual({ type: "string", value: "value" });
|
|
151
|
+
expect(encodeSolidValue(12)).toEqual({ type: "number", value: "12" });
|
|
152
|
+
expect(encodeSolidValue(buffer)).toEqual({ type: "buffer", value: buffer });
|
|
153
|
+
|
|
154
|
+
expect(decodeSolidValue<string>("string", "value")).toBe("value");
|
|
155
|
+
expect(decodeSolidValue<number>("number", "12")).toBe(12);
|
|
156
|
+
expect(decodeSolidValue<Buffer>("buffer", buffer)).toEqual(buffer);
|
|
157
|
+
expect(decodeSolidValue<Buffer>("buffer", "hello")).toEqual(buffer);
|
|
158
|
+
expect(decodeSolidValue<string>("string", null)).toBeUndefined();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("round-trips structured (object/array) solid values as json", () => {
|
|
162
|
+
// Refresh-session storage writes objects/arrays through the cache, which bun:sqlite
|
|
163
|
+
// cannot bind directly; they must be JSON-encoded so callers get the value back intact.
|
|
164
|
+
const session = { id: "s1", subject: "admin", expiresAt: "2026-01-01T00:00:00.000Z", userAgent: undefined };
|
|
165
|
+
const encodedObj = encodeSolidValue(session);
|
|
166
|
+
expect(encodedObj.type).toBe("json");
|
|
167
|
+
expect(typeof encodedObj.value).toBe("string");
|
|
168
|
+
expect(decodeSolidValue<typeof session>("json", encodedObj.value)).toEqual({
|
|
169
|
+
id: "s1",
|
|
170
|
+
subject: "admin",
|
|
171
|
+
expiresAt: "2026-01-01T00:00:00.000Z",
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const hashes = ["a", "b", "c"];
|
|
175
|
+
const encodedArr = encodeSolidValue(hashes);
|
|
176
|
+
expect(encodedArr.type).toBe("json");
|
|
177
|
+
expect(decodeSolidValue<string[]>("json", encodedArr.value)).toEqual(hashes);
|
|
178
|
+
|
|
179
|
+
// Top-level undefined is coerced to JSON null rather than producing an invalid binding.
|
|
180
|
+
expect(encodeSolidValue(undefined)).toEqual({ type: "json", value: "null" });
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test("converts optional expiration values to epoch ms", () => {
|
|
184
|
+
const date = dayjs("2026-01-01T00:00:00.000Z");
|
|
185
|
+
|
|
186
|
+
expect(toEpochMs()).toBeNull();
|
|
187
|
+
expect(toEpochMs(null)).toBeNull();
|
|
188
|
+
expect(toEpochMs(1234)).toBe(1234);
|
|
189
|
+
expect(toEpochMs(date)).toBe(date.valueOf());
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test("resolves default sqlite paths and solid config", () => {
|
|
193
|
+
const previousSqliteDir = process.env.AKAN_SQLITE_DIR;
|
|
194
|
+
const previousSolidDbPath = process.env.AKAN_SOLID_DB_PATH;
|
|
195
|
+
const previousOperationMode = process.env.AKAN_PUBLIC_OPERATION_MODE;
|
|
196
|
+
try {
|
|
197
|
+
process.env.AKAN_SQLITE_DIR = "/tmp/akan-sqlite";
|
|
198
|
+
expect(
|
|
199
|
+
resolveDefaultSqliteFile({
|
|
200
|
+
appName: "demo",
|
|
201
|
+
fileName: "demo.db",
|
|
202
|
+
isProduction: false,
|
|
203
|
+
workspaceRoot: "/workspace",
|
|
204
|
+
}),
|
|
205
|
+
).toBe("/tmp/akan-sqlite/demo.db");
|
|
206
|
+
|
|
207
|
+
delete process.env.AKAN_SQLITE_DIR;
|
|
208
|
+
expect(
|
|
209
|
+
resolveDefaultSqliteFile({
|
|
210
|
+
appName: "demo",
|
|
211
|
+
fileName: "demo.db",
|
|
212
|
+
isProduction: false,
|
|
213
|
+
workspaceRoot: "/workspace",
|
|
214
|
+
}),
|
|
215
|
+
).toBe("/workspace/local/apps/demo/demo.db");
|
|
216
|
+
|
|
217
|
+
expect(
|
|
218
|
+
resolveDefaultSqliteFile({
|
|
219
|
+
appName: "demo",
|
|
220
|
+
fileName: "demo.db",
|
|
221
|
+
isProduction: true,
|
|
222
|
+
operationMode: "local",
|
|
223
|
+
workspaceRoot: "/workspace",
|
|
224
|
+
}),
|
|
225
|
+
).toBe("/workspace/local/apps/demo/demo.db");
|
|
226
|
+
|
|
227
|
+
process.env.AKAN_PUBLIC_OPERATION_MODE = "local";
|
|
228
|
+
expect(
|
|
229
|
+
resolveDefaultSqliteFile({
|
|
230
|
+
appName: "demo",
|
|
231
|
+
fileName: "demo.db",
|
|
232
|
+
isProduction: true,
|
|
233
|
+
workspaceRoot: "/workspace",
|
|
234
|
+
}),
|
|
235
|
+
).toBe("/workspace/local/apps/demo/demo.db");
|
|
236
|
+
|
|
237
|
+
expect(
|
|
238
|
+
resolveDefaultSqliteFile({
|
|
239
|
+
appName: "demo",
|
|
240
|
+
fileName: "demo.db",
|
|
241
|
+
isProduction: true,
|
|
242
|
+
operationMode: "cloud",
|
|
243
|
+
workspaceRoot: "/workspace",
|
|
244
|
+
}),
|
|
245
|
+
).toBe(`${process.cwd()}/sqlite/demo.db`);
|
|
246
|
+
|
|
247
|
+
process.env.AKAN_SOLID_DB_PATH = "/tmp/solid.db";
|
|
248
|
+
expect(
|
|
249
|
+
getSolidConfig({
|
|
250
|
+
appName: "demo",
|
|
251
|
+
environment: "test",
|
|
252
|
+
solid: { queueLeaseMs: 7, journalMode: "MEMORY" },
|
|
253
|
+
}).filePath,
|
|
254
|
+
).toBe("/tmp/solid.db");
|
|
255
|
+
expect(
|
|
256
|
+
getSolidConfig({
|
|
257
|
+
appName: "demo",
|
|
258
|
+
environment: "test",
|
|
259
|
+
solid: { queueLeaseMs: 7, journalMode: "MEMORY" },
|
|
260
|
+
}),
|
|
261
|
+
).toMatchObject({
|
|
262
|
+
journalMode: "MEMORY",
|
|
263
|
+
queueLeaseMs: 7,
|
|
264
|
+
busyTimeoutMs: 5000,
|
|
265
|
+
synchronous: "NORMAL",
|
|
266
|
+
});
|
|
267
|
+
} finally {
|
|
268
|
+
if (previousSqliteDir === undefined) delete process.env.AKAN_SQLITE_DIR;
|
|
269
|
+
else process.env.AKAN_SQLITE_DIR = previousSqliteDir;
|
|
270
|
+
if (previousSolidDbPath === undefined) delete process.env.AKAN_SOLID_DB_PATH;
|
|
271
|
+
else process.env.AKAN_SOLID_DB_PATH = previousSolidDbPath;
|
|
272
|
+
if (previousOperationMode === undefined) delete process.env.AKAN_PUBLIC_OPERATION_MODE;
|
|
273
|
+
else process.env.AKAN_PUBLIC_OPERATION_MODE = previousOperationMode;
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
test("hydrates new documents with schema defaults before save", async () => {
|
|
278
|
+
const db = new Database(":memory:", { strict: true, create: true });
|
|
279
|
+
const client = new TestSqliteClient(db);
|
|
280
|
+
const owner = new TestDatabaseOwner(client);
|
|
281
|
+
const store = new SqliteDocumentStore(owner, insightTestConstant, insightTestDatabase, new DocumentSchema());
|
|
282
|
+
|
|
283
|
+
try {
|
|
284
|
+
await client.execute(
|
|
285
|
+
`CREATE TABLE IF NOT EXISTS "_akan_meta" ("key" TEXT PRIMARY KEY NOT NULL, "value" TEXT NOT NULL, "updatedAt" INTEGER NOT NULL)`,
|
|
286
|
+
);
|
|
287
|
+
await store.ensure();
|
|
288
|
+
|
|
289
|
+
const doc = store.hydrate({ title: "Draft" });
|
|
290
|
+
|
|
291
|
+
expect(doc.score).toBe(0);
|
|
292
|
+
expect(doc.status).toBe("active");
|
|
293
|
+
expect(doc.tags).toEqual([]);
|
|
294
|
+
await expect(doc.save()).resolves.toMatchObject({
|
|
295
|
+
title: "Draft",
|
|
296
|
+
score: 0,
|
|
297
|
+
status: "active",
|
|
298
|
+
tags: [],
|
|
299
|
+
});
|
|
300
|
+
} finally {
|
|
301
|
+
await client.close();
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
test("fills nested constant defaults inside arrays on save", async () => {
|
|
306
|
+
const db = new Database(":memory:", { strict: true, create: true });
|
|
307
|
+
const client = new TestSqliteClient(db);
|
|
308
|
+
const owner = new TestDatabaseOwner(client);
|
|
309
|
+
const store = new SqliteDocumentStore(owner, ticketTestConstant, ticketTestDatabase, new DocumentSchema());
|
|
310
|
+
|
|
311
|
+
try {
|
|
312
|
+
await client.execute(
|
|
313
|
+
`CREATE TABLE IF NOT EXISTS "_akan_meta" ("key" TEXT PRIMARY KEY NOT NULL, "value" TEXT NOT NULL, "updatedAt" INTEGER NOT NULL)`,
|
|
314
|
+
);
|
|
315
|
+
await store.ensure();
|
|
316
|
+
|
|
317
|
+
const created = await store.create({ title: "Ticket", histories: [{ action: "open" }] });
|
|
318
|
+
expect(created.histories[0]).toMatchObject({ action: "open", content: [], count: 0, flag: false });
|
|
319
|
+
|
|
320
|
+
created.histories.push({ action: "close" });
|
|
321
|
+
const saved = await created.save();
|
|
322
|
+
expect(saved.histories[1]).toMatchObject({ action: "close", content: [], count: 0, flag: false });
|
|
323
|
+
|
|
324
|
+
const fetched = await store.pickById(created.id);
|
|
325
|
+
expect(fetched.histories[0]).toMatchObject({ action: "open", content: [], count: 0, flag: false });
|
|
326
|
+
expect(fetched.histories[1]).toMatchObject({ action: "close", content: [], count: 0, flag: false });
|
|
327
|
+
} finally {
|
|
328
|
+
await client.close();
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
test("fills missing nested and top-level defaults when loading legacy rows", async () => {
|
|
333
|
+
const db = new Database(":memory:", { strict: true, create: true });
|
|
334
|
+
const client = new TestSqliteClient(db);
|
|
335
|
+
const owner = new TestDatabaseOwner(client);
|
|
336
|
+
const store = new SqliteDocumentStore(owner, ticketTestConstant, ticketTestDatabase, new DocumentSchema());
|
|
337
|
+
|
|
338
|
+
try {
|
|
339
|
+
await client.execute(
|
|
340
|
+
`CREATE TABLE IF NOT EXISTS "_akan_meta" ("key" TEXT PRIMARY KEY NOT NULL, "value" TEXT NOT NULL, "updatedAt" INTEGER NOT NULL)`,
|
|
341
|
+
);
|
|
342
|
+
await store.ensure();
|
|
343
|
+
|
|
344
|
+
const now = Date.now();
|
|
345
|
+
// Legacy row: nested `content`/`count`/`flag` and top-level `status` were never persisted.
|
|
346
|
+
const legacyDoc = JSON.stringify({ title: "Legacy", histories: [{ action: "open" }] });
|
|
347
|
+
await client.execute(
|
|
348
|
+
`INSERT INTO "sqliteTicketTest" ("id", "createdAt", "updatedAt", "removedAt", "_doc") VALUES (?, ?, ?, ?, ?)`,
|
|
349
|
+
["legacy-1", now, now, null, legacyDoc],
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
const fetched = await store.pickById("legacy-1");
|
|
353
|
+
expect(fetched.status).toBe("active");
|
|
354
|
+
expect(fetched.histories[0]).toMatchObject({ action: "open", content: [], count: 0, flag: false });
|
|
355
|
+
} finally {
|
|
356
|
+
await client.close();
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
test("normalizes date fields to epoch storage regardless of input shape", async () => {
|
|
361
|
+
const db = new Database(":memory:", { strict: true, create: true });
|
|
362
|
+
const client = new TestSqliteClient(db);
|
|
363
|
+
const owner = new TestDatabaseOwner(client);
|
|
364
|
+
const store = new SqliteDocumentStore(owner, ticketTestConstant, ticketTestDatabase, new DocumentSchema());
|
|
365
|
+
|
|
366
|
+
try {
|
|
367
|
+
await client.execute(
|
|
368
|
+
`CREATE TABLE IF NOT EXISTS "_akan_meta" ("key" TEXT PRIMARY KEY NOT NULL, "value" TEXT NOT NULL, "updatedAt" INTEGER NOT NULL)`,
|
|
369
|
+
);
|
|
370
|
+
await store.ensure();
|
|
371
|
+
|
|
372
|
+
const iso = "2026-06-06T13:52:39.747Z";
|
|
373
|
+
// `issuedAt` arrives as an ISO string while `transactionAt` falls back to its dayjs(0) default.
|
|
374
|
+
const created = await store.create({ title: "Dated", issuedAt: iso, histories: [] });
|
|
375
|
+
expect(dayjs.isDayjs(created.issuedAt)).toBe(true);
|
|
376
|
+
expect(created.issuedAt.valueOf()).toBe(dayjs(iso).valueOf());
|
|
377
|
+
expect(created.transactionAt.valueOf()).toBe(0);
|
|
378
|
+
|
|
379
|
+
// Both dates must persist as epoch numbers, not a string/number mix.
|
|
380
|
+
const row = await client
|
|
381
|
+
.prepare(`SELECT "_doc" FROM "sqliteTicketTest" WHERE "id" = ?`)
|
|
382
|
+
.get<{ _doc: string }>(created.id);
|
|
383
|
+
const stored = JSON.parse(row?._doc ?? "{}");
|
|
384
|
+
expect(typeof stored.issuedAt).toBe("number");
|
|
385
|
+
expect(stored.issuedAt).toBe(dayjs(iso).valueOf());
|
|
386
|
+
expect(typeof stored.transactionAt).toBe("number");
|
|
387
|
+
expect(stored.transactionAt).toBe(0);
|
|
388
|
+
|
|
389
|
+
const fetched = await store.pickById(created.id);
|
|
390
|
+
expect(fetched.issuedAt.valueOf()).toBe(dayjs(iso).valueOf());
|
|
391
|
+
expect(fetched.transactionAt.valueOf()).toBe(0);
|
|
392
|
+
} finally {
|
|
393
|
+
await client.close();
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
test("reads legacy ISO-string dates as valid dayjs", async () => {
|
|
398
|
+
const db = new Database(":memory:", { strict: true, create: true });
|
|
399
|
+
const client = new TestSqliteClient(db);
|
|
400
|
+
const owner = new TestDatabaseOwner(client);
|
|
401
|
+
const store = new SqliteDocumentStore(owner, ticketTestConstant, ticketTestDatabase, new DocumentSchema());
|
|
402
|
+
|
|
403
|
+
try {
|
|
404
|
+
await client.execute(
|
|
405
|
+
`CREATE TABLE IF NOT EXISTS "_akan_meta" ("key" TEXT PRIMARY KEY NOT NULL, "value" TEXT NOT NULL, "updatedAt" INTEGER NOT NULL)`,
|
|
406
|
+
);
|
|
407
|
+
await store.ensure();
|
|
408
|
+
|
|
409
|
+
const iso = "2026-06-06T13:52:39.747Z";
|
|
410
|
+
const now = Date.now();
|
|
411
|
+
// Legacy row persisted `issuedAt` as an ISO string instead of epoch ms.
|
|
412
|
+
const legacyDoc = JSON.stringify({ title: "Legacy", issuedAt: iso, histories: [] });
|
|
413
|
+
await client.execute(
|
|
414
|
+
`INSERT INTO "sqliteTicketTest" ("id", "createdAt", "updatedAt", "removedAt", "_doc") VALUES (?, ?, ?, ?, ?)`,
|
|
415
|
+
["legacy-date-1", now, now, null, legacyDoc],
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
const fetched = await store.pickById("legacy-date-1");
|
|
419
|
+
expect(fetched.issuedAt.isValid()).toBe(true);
|
|
420
|
+
expect(fetched.issuedAt.valueOf()).toBe(dayjs(iso).valueOf());
|
|
421
|
+
} finally {
|
|
422
|
+
await client.close();
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
test("counts insight fields with document query accumulates", async () => {
|
|
427
|
+
const db = new Database(":memory:", { strict: true, create: true });
|
|
428
|
+
const client = new TestSqliteClient(db);
|
|
429
|
+
const owner = new TestDatabaseOwner(client);
|
|
430
|
+
const store = new SqliteDocumentStore(owner, insightTestConstant, insightTestDatabase, new DocumentSchema());
|
|
431
|
+
|
|
432
|
+
try {
|
|
433
|
+
await client.execute(
|
|
434
|
+
`CREATE TABLE IF NOT EXISTS "_akan_meta" ("key" TEXT PRIMARY KEY NOT NULL, "value" TEXT NOT NULL, "updatedAt" INTEGER NOT NULL)`,
|
|
435
|
+
);
|
|
436
|
+
await store.ensure();
|
|
437
|
+
await store.create({ title: "Alpha", score: 12, status: "active", tags: ["featured"] });
|
|
438
|
+
await store.create({ title: "Beta", score: 4, status: "failed", tags: ["cold"] });
|
|
439
|
+
await store.create({ title: "Gamma", score: 20, status: "deploying", tags: ["urgent"] });
|
|
440
|
+
|
|
441
|
+
await expect(store.insight()).resolves.toEqual({
|
|
442
|
+
count: 3,
|
|
443
|
+
activeCount: 1,
|
|
444
|
+
runningCount: 2,
|
|
445
|
+
taggedCount: 2,
|
|
446
|
+
});
|
|
447
|
+
await expect(store.insight({ score: { gte: 10 } })).resolves.toEqual({
|
|
448
|
+
count: 2,
|
|
449
|
+
activeCount: 1,
|
|
450
|
+
runningCount: 2,
|
|
451
|
+
taggedCount: 2,
|
|
452
|
+
});
|
|
453
|
+
} finally {
|
|
454
|
+
await client.close();
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
});
|
|
@@ -67,7 +67,8 @@ export const encodeSolidValue = (value: unknown): { type: SolidValueType; value:
|
|
|
67
67
|
if (Buffer.isBuffer(value)) return { type: "buffer", value };
|
|
68
68
|
if (typeof value === "number") return { type: "number", value: String(value) };
|
|
69
69
|
if (typeof value === "string") return { type: "string", value };
|
|
70
|
-
|
|
70
|
+
// Objects, arrays, booleans, null: stored as JSON so callers can round-trip
|
|
71
|
+
// structured values (e.g. refresh sessions) through the SQLite-backed cache.
|
|
71
72
|
return { type: "json", value: JSON.stringify(value ?? null) };
|
|
72
73
|
};
|
|
73
74
|
|
|
@@ -63,7 +63,7 @@ export class WebSocketRedisAdaptor
|
|
|
63
63
|
#heartbeatInterval: Timer | null = null;
|
|
64
64
|
|
|
65
65
|
override async onInit() {
|
|
66
|
-
|
|
66
|
+
// Publisher lifecycle
|
|
67
67
|
this.publisher.on("connect", () => {
|
|
68
68
|
this.#publisherReady = true;
|
|
69
69
|
this.logger.verbose("Publisher connected");
|
|
@@ -77,6 +77,7 @@ export class WebSocketRedisAdaptor
|
|
|
77
77
|
this.logger.warn(`Publisher error: ${err.message}`);
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
+
// Subscriber lifecycle
|
|
80
81
|
this.subscriber.on("error", (err: Error) => {
|
|
81
82
|
this.logger.warn(`Subscriber error: ${err.message}`);
|
|
82
83
|
});
|
|
@@ -84,6 +85,7 @@ export class WebSocketRedisAdaptor
|
|
|
84
85
|
await this.publisher.connect();
|
|
85
86
|
await this.subscriber.connect();
|
|
86
87
|
|
|
88
|
+
// Subscribe to broadcast channel
|
|
87
89
|
await this.subscriber.subscribe(BROADCAST_CHANNEL, (err?: Error | null) => {
|
|
88
90
|
if (err) this.logger.warn(`Subscribe error: ${err.message}`);
|
|
89
91
|
});
|
|
@@ -105,6 +107,8 @@ export class WebSocketRedisAdaptor
|
|
|
105
107
|
}
|
|
106
108
|
});
|
|
107
109
|
|
|
110
|
+
// Server heartbeat — expire server key every 60s, refresh every 30s
|
|
111
|
+
// If a pod crashes without graceful shutdown, its keys expire after 60s
|
|
108
112
|
await this.redis.set(`${WEBSOCKET_PREFIX}server:${this.serverId}`, Date.now().toString(), "EX", 60);
|
|
109
113
|
this.#heartbeatInterval = setInterval(async () => {
|
|
110
114
|
try {
|
|
@@ -119,12 +123,13 @@ export class WebSocketRedisAdaptor
|
|
|
119
123
|
}
|
|
120
124
|
|
|
121
125
|
override async onDestroy() {
|
|
122
|
-
|
|
126
|
+
// Stop heartbeat
|
|
123
127
|
if (this.#heartbeatInterval) {
|
|
124
128
|
clearInterval(this.#heartbeatInterval);
|
|
125
129
|
this.#heartbeatInterval = null;
|
|
126
130
|
}
|
|
127
131
|
|
|
132
|
+
// Clean up all sockets registered to this server
|
|
128
133
|
await this.#cleanupServer();
|
|
129
134
|
|
|
130
135
|
if (this.subscriber) {
|
|
@@ -142,6 +147,8 @@ export class WebSocketRedisAdaptor
|
|
|
142
147
|
this.logger.verbose("WebSocket Redis adaptor destroyed");
|
|
143
148
|
}
|
|
144
149
|
|
|
150
|
+
// ── Pub/Sub ──
|
|
151
|
+
|
|
145
152
|
publish(roomId: string, data: unknown): void {
|
|
146
153
|
const endpointKey = this.#getEndpointKey(roomId);
|
|
147
154
|
const endpointInfo = endpointKey ? this.#endpointMap.get(endpointKey) : null;
|
|
@@ -180,6 +187,8 @@ export class WebSocketRedisAdaptor
|
|
|
180
187
|
return idx >= 0 ? roomId.substring(0, idx) : roomId;
|
|
181
188
|
}
|
|
182
189
|
|
|
190
|
+
// ── Room membership ──
|
|
191
|
+
|
|
183
192
|
async joinRoom(ws: Bun.ServerWebSocket<unknown>, room: string): Promise<void> {
|
|
184
193
|
const socketId = this.#getSocketId(ws);
|
|
185
194
|
const pipeline = this.redis.multi();
|
|
@@ -209,6 +218,7 @@ export class WebSocketRedisAdaptor
|
|
|
209
218
|
await pipeline.exec();
|
|
210
219
|
}
|
|
211
220
|
|
|
221
|
+
// ── Socket registration ──
|
|
212
222
|
#getSocketId(ws: Bun.ServerWebSocket<unknown>): string {
|
|
213
223
|
const data = ws.data as WsSocketData;
|
|
214
224
|
if (!data.socketId) data.socketId = `${this.serverId}-${Bun.randomUUIDv7()}`;
|
|
@@ -231,6 +241,8 @@ export class WebSocketRedisAdaptor
|
|
|
231
241
|
await this.leaveAllRooms(ws);
|
|
232
242
|
}
|
|
233
243
|
|
|
244
|
+
// ── Internal helpers ──
|
|
245
|
+
|
|
234
246
|
#packMessage(origin: string, roomId: string, payload: Buffer): Buffer {
|
|
235
247
|
const originBuf = Buffer.from(origin, "utf-8");
|
|
236
248
|
const roomIdBuf = Buffer.from(roomId, "utf-8");
|
|
@@ -294,7 +306,7 @@ export class WebSocketRedisAdaptor
|
|
|
294
306
|
const sockets = await this.redis.smembers(`${WEBSOCKET_PREFIX}server:${this.serverId}:sockets`);
|
|
295
307
|
const pipeline = this.redis.multi();
|
|
296
308
|
for (const socketId of sockets) {
|
|
297
|
-
|
|
309
|
+
// Get rooms for each socket and remove from room sets
|
|
298
310
|
const rooms = await this.redis.smembers(`${WEBSOCKET_PREFIX}socket:${socketId}:rooms`);
|
|
299
311
|
for (const room of rooms) {
|
|
300
312
|
pipeline.srem(`${WEBSOCKET_PREFIX}room:${room}`, socketId);
|
package/service/serve.ts
CHANGED
|
@@ -38,7 +38,7 @@ const avoidKeys = new Set([
|
|
|
38
38
|
|
|
39
39
|
export interface Service {
|
|
40
40
|
readonly logger: Logger;
|
|
41
|
-
|
|
41
|
+
// readonly connection: Connection;
|
|
42
42
|
onInit(): Promise<void>;
|
|
43
43
|
_libsOnInit(): Promise<void>;
|
|
44
44
|
onDestroy(): Promise<void>;
|
|
@@ -47,9 +47,9 @@ export interface Service {
|
|
|
47
47
|
|
|
48
48
|
export type ServiceCls<
|
|
49
49
|
RefName extends string = string,
|
|
50
|
-
|
|
50
|
+
// biome-ignore lint/complexity/noBannedTypes: `{}` keeps generated service types from gaining object prototype keys.
|
|
51
51
|
Methods = {},
|
|
52
|
-
|
|
52
|
+
// biome-ignore lint/complexity/noBannedTypes: `{}` keeps services with no injections assignable.
|
|
53
53
|
InjectMap extends { [key: string]: InjectInfo } = {},
|
|
54
54
|
> = Cls<
|
|
55
55
|
Methods & ExtractInjectInfoObject<InjectMap> & Service,
|
|
@@ -65,12 +65,14 @@ export function serve<RefName extends string, Injection extends InjectBuilder>(
|
|
|
65
65
|
refName: RefName,
|
|
66
66
|
injectBuilder: Injection,
|
|
67
67
|
...extendSrvs: Cls[]
|
|
68
|
+
// biome-ignore lint/complexity/noBannedTypes: `{}` preserves plain service method inference.
|
|
68
69
|
): ServiceCls<RefName, {}, ReturnType<Injection>>;
|
|
69
70
|
export function serve<RefName extends string, Injection extends InjectBuilder>(
|
|
70
71
|
refName: RefName,
|
|
71
72
|
option: ServiceOptions,
|
|
72
73
|
injectBuilder: Injection,
|
|
73
74
|
...extendSrvs: Cls[]
|
|
75
|
+
// biome-ignore lint/complexity/noBannedTypes: `{}` preserves plain service method inference.
|
|
74
76
|
): ServiceCls<RefName, {}, ReturnType<Injection>>;
|
|
75
77
|
export function serve<
|
|
76
78
|
T extends string,
|
|
@@ -153,8 +155,10 @@ export function serve(
|
|
|
153
155
|
static [INJECT_META] = {};
|
|
154
156
|
readonly logger = new Logger(this.constructor.name);
|
|
155
157
|
async onInit() {
|
|
158
|
+
//
|
|
156
159
|
}
|
|
157
160
|
async onDestroy() {
|
|
161
|
+
//
|
|
158
162
|
}
|
|
159
163
|
};
|
|
160
164
|
applyMixins(srvRef, extSrvs, avoidKeys);
|