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
package/ui/System/Reconnect.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { clsx, fetch, usePage } from "akanjs/client";
|
|
3
3
|
import { useInterval } from "akanjs/webkit";
|
|
4
|
-
|
|
4
|
+
// import { client } from "akanjs/signal";
|
|
5
5
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
6
6
|
import { TbPlugConnected, TbPlugConnectedX } from "react-icons/tb";
|
|
7
7
|
|
|
@@ -22,7 +22,7 @@ export const Reconnect = () => {
|
|
|
22
22
|
}, []);
|
|
23
23
|
|
|
24
24
|
const handleDisconnect = async () => {
|
|
25
|
-
|
|
25
|
+
// 페이지가 백그라운드 상태에서 disconnect가 발생하면 무시
|
|
26
26
|
if (document.hidden) {
|
|
27
27
|
wasHiddenOnDisconnect.current = true;
|
|
28
28
|
return;
|
|
@@ -39,14 +39,14 @@ export const Reconnect = () => {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
const handleVisibilityChange = useCallback(() => {
|
|
42
|
-
|
|
42
|
+
// 페이지가 다시 보이게 될 때
|
|
43
43
|
if (!document.hidden && wasHiddenOnDisconnect.current) {
|
|
44
|
-
|
|
44
|
+
// socket이 연결되어 있으면 문제없음
|
|
45
45
|
if (fetch.ws.connected) {
|
|
46
46
|
wasHiddenOnDisconnect.current = false;
|
|
47
47
|
setConnectStatus("normal");
|
|
48
48
|
} else {
|
|
49
|
-
|
|
49
|
+
// socket이 끊어져 있으면 실제 서버 문제인지 확인
|
|
50
50
|
void handleDisconnect();
|
|
51
51
|
}
|
|
52
52
|
}
|
|
@@ -56,6 +56,7 @@ export const Reconnect = () => {
|
|
|
56
56
|
fetch.ws.on("connect", handleConnect);
|
|
57
57
|
fetch.ws.on("disconnect", () => handleDisconnect());
|
|
58
58
|
|
|
59
|
+
// Page Visibility API 이벤트 리스너 추가
|
|
59
60
|
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
60
61
|
|
|
61
62
|
setTimeout(() => {
|
package/ui/System/Root.tsx
CHANGED
package/ui/System/SSR.tsx
CHANGED
|
@@ -35,10 +35,16 @@ const SSRProvider = ({
|
|
|
35
35
|
}: SSRProviderProps) => {
|
|
36
36
|
setRequestTheme(theme);
|
|
37
37
|
|
|
38
|
+
// Resolve the active locale exactly like `l()` does (getPageInfo / request), not via `params.lang`,
|
|
39
|
+
// which is only populated when the matched route pattern contains `:lang` and can otherwise diverge.
|
|
38
40
|
const { lang: activeLocale } = usePage();
|
|
39
41
|
|
|
42
|
+
// Server (RSC worker) renders server components: seed every locale into the shared Translator. This is
|
|
43
|
+
// free on the server (it never reaches the browser bundle) and makes server-component translations
|
|
44
|
+
// resolve no matter how the locale is routed.
|
|
40
45
|
if (allDictionary) for (const [lng, dict] of Object.entries(allDictionary)) Translator.seed(lng, dict);
|
|
41
46
|
|
|
47
|
+
// Only the active locale is serialized to the client (Flight payload) to keep the browser bundle lean.
|
|
42
48
|
const activeDictionary = allDictionary?.[activeLocale] ?? dictionary;
|
|
43
49
|
|
|
44
50
|
return (
|
|
@@ -87,7 +93,7 @@ const ServerFontFace = ({ fonts }: { fonts: ReactFont[] }) => {
|
|
|
87
93
|
<link key={preload.href} rel="preload" href={preload.href} as="font" type={preload.type} crossOrigin="" />
|
|
88
94
|
))}
|
|
89
95
|
{css ? (
|
|
90
|
-
|
|
96
|
+
// biome-ignore lint/security/noDangerouslySetInnerHtml: injecting @font-face CSS
|
|
91
97
|
<style data-akan-fonts dangerouslySetInnerHTML={{ __html: css }} />
|
|
92
98
|
) : null}
|
|
93
99
|
</>
|
package/ui/ToggleSelect.tsx
CHANGED
|
@@ -22,7 +22,8 @@ export const ToggleSelect = <I extends string | number | boolean | null>({
|
|
|
22
22
|
}: ToggleSelectProps<I>) => {
|
|
23
23
|
const { l } = usePage();
|
|
24
24
|
const validateResult = value !== null ? validate(value) : false;
|
|
25
|
-
|
|
25
|
+
// const status: "error" | "warning" | "success" =
|
|
26
|
+
// !nullable && !value?.length ? "warning" : validateResult === true ? "success" : "error";
|
|
26
27
|
const invalidMessage =
|
|
27
28
|
value === null || (typeof value === "string" && !value.length) || validateResult === true
|
|
28
29
|
? null
|
|
@@ -54,7 +55,10 @@ export const ToggleSelect = <I extends string | number | boolean | null>({
|
|
|
54
55
|
className={clsx(
|
|
55
56
|
"btn btn-sm",
|
|
56
57
|
{ "bg-success/70 text-success-content": isSelected, "btn-disabled cursor-not-allowed": isDisabled },
|
|
57
|
-
|
|
58
|
+
// {
|
|
59
|
+
// "btn-error": status === "error",
|
|
60
|
+
// "btn-warning": status === "warning",
|
|
61
|
+
// },
|
|
58
62
|
btnClassName,
|
|
59
63
|
)}
|
|
60
64
|
onClick={() => {
|
|
@@ -85,7 +89,8 @@ interface MultiProps {
|
|
|
85
89
|
const Multi = ({ className, btnClassName, items, nullable, validate, value, onChange, disabled }: MultiProps) => {
|
|
86
90
|
const { l } = usePage();
|
|
87
91
|
const validateResult = validate(value);
|
|
88
|
-
|
|
92
|
+
// const status: "error" | "warning" | "success" =
|
|
93
|
+
// !nullable && !value.length ? "warning" : validateResult === true ? "success" : "error";
|
|
89
94
|
const invalidMessage =
|
|
90
95
|
!value.length || validateResult === true
|
|
91
96
|
? null
|
package/ui/Unauthorized.tsx
CHANGED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { afterEach, beforeAll, describe, expect, mock, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
const originalWindow = globalThis.window;
|
|
4
|
+
const originalDocument = globalThis.document;
|
|
5
|
+
const originalEnv = { ...process.env };
|
|
6
|
+
|
|
7
|
+
const deviceState = {
|
|
8
|
+
lang: "en",
|
|
9
|
+
platform: "web",
|
|
10
|
+
};
|
|
11
|
+
const storageState = {
|
|
12
|
+
jwt: null as string | null,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
beforeAll(() => {
|
|
16
|
+
mock.module("akanjs/client", () => ({
|
|
17
|
+
DEFAULT_BOTTOM_INSET: 34,
|
|
18
|
+
DEFAULT_TOP_INSET: 44,
|
|
19
|
+
csrContext: { Provider: ({ children }: { children: unknown }) => children },
|
|
20
|
+
defaultPageState: {
|
|
21
|
+
transition: "none",
|
|
22
|
+
topSafeArea: 0,
|
|
23
|
+
bottomSafeArea: 0,
|
|
24
|
+
topInset: 0,
|
|
25
|
+
bottomInset: 0,
|
|
26
|
+
gesture: true,
|
|
27
|
+
cache: false,
|
|
28
|
+
},
|
|
29
|
+
router: {
|
|
30
|
+
state: {},
|
|
31
|
+
set: () => undefined,
|
|
32
|
+
emit: () => undefined,
|
|
33
|
+
on: () => undefined,
|
|
34
|
+
off: () => undefined,
|
|
35
|
+
},
|
|
36
|
+
Device: {
|
|
37
|
+
load: async () => ({
|
|
38
|
+
lang: deviceState.lang,
|
|
39
|
+
info: { platform: deviceState.platform },
|
|
40
|
+
topSafeArea: 11,
|
|
41
|
+
bottomSafeArea: 22,
|
|
42
|
+
}),
|
|
43
|
+
getDevice: () => ({
|
|
44
|
+
info: { platform: deviceState.platform },
|
|
45
|
+
}),
|
|
46
|
+
},
|
|
47
|
+
initAuth: () => undefined,
|
|
48
|
+
storage: {
|
|
49
|
+
getItem: async (key: string) => (key === "jwt" ? storageState.jwt : null),
|
|
50
|
+
},
|
|
51
|
+
}));
|
|
52
|
+
mock.module("react-dom/client", () => ({
|
|
53
|
+
createRoot: () => ({ render: () => undefined }),
|
|
54
|
+
}));
|
|
55
|
+
mock.module("@capacitor/app", () => ({
|
|
56
|
+
App: {
|
|
57
|
+
addListener: () => ({ remove: () => undefined }),
|
|
58
|
+
},
|
|
59
|
+
}));
|
|
60
|
+
mock.module("@react-spring/web", () => ({
|
|
61
|
+
useSpringValue: () => ({ to: () => 0, start: async () => undefined }),
|
|
62
|
+
}));
|
|
63
|
+
mock.module("@use-gesture/react", () => ({
|
|
64
|
+
useDrag: () => () => ({}),
|
|
65
|
+
}));
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const installWindow = ({
|
|
69
|
+
href,
|
|
70
|
+
replace,
|
|
71
|
+
root = true,
|
|
72
|
+
}: {
|
|
73
|
+
href: string;
|
|
74
|
+
replace?: (href: string) => void;
|
|
75
|
+
root?: boolean;
|
|
76
|
+
}) => {
|
|
77
|
+
const url = new URL(href);
|
|
78
|
+
const body = { style: {} } as HTMLBodyElement;
|
|
79
|
+
const document = {
|
|
80
|
+
body,
|
|
81
|
+
getElementById: (id: string) => (root && id === "root" ? ({ nodeType: 1 } as HTMLElement) : null),
|
|
82
|
+
} as unknown as Document;
|
|
83
|
+
const window = {
|
|
84
|
+
document,
|
|
85
|
+
location: {
|
|
86
|
+
href,
|
|
87
|
+
origin: url.origin,
|
|
88
|
+
pathname: url.pathname,
|
|
89
|
+
search: url.search,
|
|
90
|
+
hash: url.hash,
|
|
91
|
+
replace: replace ?? (() => undefined),
|
|
92
|
+
},
|
|
93
|
+
} as unknown as Window & typeof globalThis;
|
|
94
|
+
Object.defineProperty(globalThis, "window", { value: window, configurable: true });
|
|
95
|
+
Object.defineProperty(globalThis, "document", { value: document, configurable: true });
|
|
96
|
+
Object.defineProperty(globalThis, "location", { value: window.location, configurable: true });
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
afterEach(() => {
|
|
100
|
+
Object.defineProperty(globalThis, "window", { value: originalWindow, configurable: true });
|
|
101
|
+
Object.defineProperty(globalThis, "document", { value: originalDocument, configurable: true });
|
|
102
|
+
Object.defineProperty(globalThis, "location", { value: originalWindow?.location, configurable: true });
|
|
103
|
+
process.env = { ...originalEnv };
|
|
104
|
+
deviceState.lang = "en";
|
|
105
|
+
deviceState.platform = "web";
|
|
106
|
+
storageState.jwt = null;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe("bootCsr", () => {
|
|
110
|
+
test("exits early on 404 before route loading", async () => {
|
|
111
|
+
installWindow({ href: "https://example.test/404" });
|
|
112
|
+
let loaded = false;
|
|
113
|
+
const { bootCsr } = await import("./bootCsr");
|
|
114
|
+
|
|
115
|
+
await bootCsr({
|
|
116
|
+
"./_index.tsx": async () => {
|
|
117
|
+
loaded = true;
|
|
118
|
+
return { default: () => null };
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
expect(loaded).toBe(false);
|
|
123
|
+
expect(document.body.style.overflow).toBe("hidden");
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("redirects to language-prefixed path when missing language prefix", async () => {
|
|
127
|
+
const replacements: string[] = [];
|
|
128
|
+
installWindow({ href: "https://example.test/home?a=1#top", replace: (href) => replacements.push(href) });
|
|
129
|
+
const { bootCsr } = await import("./bootCsr");
|
|
130
|
+
|
|
131
|
+
await bootCsr({
|
|
132
|
+
"./_index.tsx": async () => ({ default: () => null }),
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
expect(replacements).toEqual(["/en/home?a=1#top"]);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test("initializes mobile target from local Capacitor CSR URL", async () => {
|
|
139
|
+
const replacements: string[] = [];
|
|
140
|
+
installWindow({
|
|
141
|
+
href: "https://example.test/en/?csr=true&akanMobileTarget=default&akanMobileBasePath=minimal",
|
|
142
|
+
replace: (href) => replacements.push(href),
|
|
143
|
+
});
|
|
144
|
+
const { bootCsr } = await import("./bootCsr");
|
|
145
|
+
|
|
146
|
+
await bootCsr({
|
|
147
|
+
"./_index.tsx": async () => ({ default: () => null }),
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
expect(window.__AKAN_MOBILE_TARGET__).toEqual({ name: "default", basePath: "minimal" });
|
|
151
|
+
expect(replacements).toEqual([]);
|
|
152
|
+
});
|
|
153
|
+
});
|
package/webkit/bootCsr.tsx
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
parseRouteModuleKey,
|
|
25
25
|
routeSegmentToTreePath,
|
|
26
26
|
} from "akanjs/common";
|
|
27
|
-
import { createElement, memo, type ReactNode, useRef } from "react";
|
|
27
|
+
import { createElement, memo, type ReactNode, useRef } from "react"; // import React 꼭 필요함. 안그러면 csr에서 에러남
|
|
28
28
|
import * as ReactDOM from "react-dom/client";
|
|
29
29
|
import { useCsrValues } from "./useCsrValues";
|
|
30
30
|
import { useFetch } from "./useFetch";
|
|
@@ -85,6 +85,7 @@ export const bootCsr = async (context: Record<string, CsrRouteModuleEntry>) => {
|
|
|
85
85
|
const pathname = mobileBasePath && window.location.pathname === "/" ? `/${mobileBasePath}` : window.location.pathname;
|
|
86
86
|
if (pathname === "/404") return;
|
|
87
87
|
|
|
88
|
+
// 1. Collect Device Information
|
|
88
89
|
const [device, jwt] = await Promise.all([Device.load({ supportLanguages: i18n.locales }), storage.getItem("jwt")]);
|
|
89
90
|
if (!window.__AKAN_MOBILE_TARGET__ && !pathname.startsWith(`/${device.lang}`))
|
|
90
91
|
window.location.replace(`/${device.lang}${pathname}${window.location.search}${window.location.hash}`);
|
|
@@ -92,6 +93,7 @@ export const bootCsr = async (context: Record<string, CsrRouteModuleEntry>) => {
|
|
|
92
93
|
if (jwt) initAuth({ jwt });
|
|
93
94
|
Logger.verbose(`Set default language: ${device.lang}`);
|
|
94
95
|
|
|
96
|
+
// 2. Create Route Map
|
|
95
97
|
const basePaths = process.env.AKAN_PUBLIC_BASE_PATHS ? parseBasePaths(process.env.AKAN_PUBLIC_BASE_PATHS) : null;
|
|
96
98
|
const currentBasePath = basePaths ? pathname.split("/")[2] : undefined;
|
|
97
99
|
if (currentBasePath && basePaths && !basePaths.includes(currentBasePath))
|
|
@@ -106,7 +108,7 @@ export const bootCsr = async (context: Record<string, CsrRouteModuleEntry>) => {
|
|
|
106
108
|
const parsed = parseRouteModuleKey(key);
|
|
107
109
|
if (basePaths) {
|
|
108
110
|
const pageBasePath = parsed.sourceRouteSegments.find((segment) => !/^\(.+\)$/.test(segment));
|
|
109
|
-
if (pageBasePath && otherBasePaths.includes(pageBasePath)) return;
|
|
111
|
+
if (pageBasePath && otherBasePaths.includes(pageBasePath)) return; // ignore other base paths
|
|
110
112
|
}
|
|
111
113
|
const entry = typeof value === "function" ? { loader: value } : value;
|
|
112
114
|
const pageContent = await entry.loader();
|
|
@@ -173,7 +175,8 @@ export const bootCsr = async (context: Record<string, CsrRouteModuleEntry>) => {
|
|
|
173
175
|
resolveError: layoutPage ? () => layoutPage.Error : undefined,
|
|
174
176
|
};
|
|
175
177
|
targetRouteMap.set(targetPath, {
|
|
176
|
-
|
|
178
|
+
// action: pages[path]?.action,
|
|
179
|
+
// ErrorBoundary: pages[path]?.ErrorBoundary,
|
|
177
180
|
...(targetRouteMap.get(targetPath) ?? { path: targetPath, children: new Map<string, Route>() }),
|
|
178
181
|
...(parsed.kind === "layout"
|
|
179
182
|
? { renderLayout: routeRender }
|
package/webkit/lazy.tsx
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { ComponentType, ReactNode } from "react";
|
|
2
|
-
|
|
2
|
+
// `useState` / `useEffect` are NOT exported from `react.react-server.js`
|
|
3
|
+
// (the build Bun resolves `react` to under `--conditions react-server`).
|
|
4
|
+
// Named-importing them here would crash RSC worker evaluation with
|
|
5
|
+
// "Export named 'useEffect' not found". They're only ever called on the
|
|
6
|
+
// browser anyway (the `ssr: false` gate below is the only path that calls
|
|
7
|
+
// them, and it short-circuits on the server), so we dereference them
|
|
8
|
+
// through a namespace import — the namespace itself is always importable,
|
|
9
|
+
// and the lookup only happens when the gated Wrapper actually renders.
|
|
3
10
|
import * as React from "react";
|
|
4
11
|
import { forwardRef, lazy as reactLazy } from "react";
|
|
5
12
|
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { afterEach, beforeAll, describe, expect, mock, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
type RenderHookResult<T> = {
|
|
4
|
+
get current(): T;
|
|
5
|
+
unmount: () => void;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
type Permission = "prompt" | "granted" | "denied";
|
|
9
|
+
|
|
10
|
+
const originalWindow = globalThis.window;
|
|
11
|
+
const originalDocument = globalThis.document;
|
|
12
|
+
const effectCleanups: Array<() => void> = [];
|
|
13
|
+
let hookIndex = 0;
|
|
14
|
+
const hookStates: unknown[] = [];
|
|
15
|
+
let hookMemoStates: Array<{ deps: unknown[]; value: unknown }> = [];
|
|
16
|
+
|
|
17
|
+
const sameDeps = (a: unknown[] | undefined, b: unknown[] | undefined) =>
|
|
18
|
+
!!a && !!b && a.length === b.length && a.every((value, index) => Object.is(value, b[index]));
|
|
19
|
+
|
|
20
|
+
const cameraState = {
|
|
21
|
+
permissions: { camera: "prompt" as Permission, photos: "prompt" as Permission },
|
|
22
|
+
requested: 0,
|
|
23
|
+
photoSource: "",
|
|
24
|
+
cancelled: false,
|
|
25
|
+
};
|
|
26
|
+
const contactsState = {
|
|
27
|
+
platform: "web",
|
|
28
|
+
permissions: { contacts: "prompt" as Permission },
|
|
29
|
+
checked: 0,
|
|
30
|
+
requested: 0,
|
|
31
|
+
};
|
|
32
|
+
const geolocationState = {
|
|
33
|
+
permissions: { location: "granted", coarseLocation: "granted" },
|
|
34
|
+
};
|
|
35
|
+
const pushState = {
|
|
36
|
+
platform: "web",
|
|
37
|
+
receive: "granted" as "granted" | "denied",
|
|
38
|
+
registered: 0,
|
|
39
|
+
autoInit: 0,
|
|
40
|
+
};
|
|
41
|
+
const assigned: string[] = [];
|
|
42
|
+
|
|
43
|
+
beforeAll(() => {
|
|
44
|
+
mock.module("react", () => ({
|
|
45
|
+
Fragment: ({ children }: { children: unknown }) => children,
|
|
46
|
+
useCallback: <T,>(fn: T, deps?: unknown[]) => {
|
|
47
|
+
const index = hookIndex++;
|
|
48
|
+
const memo = hookMemoStates[index];
|
|
49
|
+
if (memo && sameDeps(memo.deps, deps)) return memo.value as T;
|
|
50
|
+
hookMemoStates[index] = { deps: deps ?? [], value: fn };
|
|
51
|
+
return fn;
|
|
52
|
+
},
|
|
53
|
+
useMemo: <T,>(factory: () => T, deps?: unknown[]) => {
|
|
54
|
+
const index = hookIndex++;
|
|
55
|
+
const memo = hookMemoStates[index];
|
|
56
|
+
if (memo && sameDeps(memo.deps, deps)) return memo.value as T;
|
|
57
|
+
const value = factory();
|
|
58
|
+
hookMemoStates[index] = { deps: deps ?? [], value };
|
|
59
|
+
return value;
|
|
60
|
+
},
|
|
61
|
+
useRef: <T,>(initial: T) => {
|
|
62
|
+
const index = hookIndex++;
|
|
63
|
+
if (!hookStates[index]) hookStates[index] = { current: initial };
|
|
64
|
+
return hookStates[index] as { current: T };
|
|
65
|
+
},
|
|
66
|
+
useState: <T,>(initial: T) => {
|
|
67
|
+
const index = hookIndex++;
|
|
68
|
+
if (hookStates[index] === undefined)
|
|
69
|
+
hookStates[index] = typeof initial === "function" ? (initial as () => T)() : initial;
|
|
70
|
+
const setState = (next: T | ((prev: T) => T)) => {
|
|
71
|
+
const state = hookStates[index] as T;
|
|
72
|
+
const nextState = typeof next === "function" ? (next as (prev: T) => T)(state) : next;
|
|
73
|
+
if (typeof state === "object" && state && typeof nextState === "object" && nextState) {
|
|
74
|
+
Object.assign(state, nextState);
|
|
75
|
+
} else {
|
|
76
|
+
hookStates[index] = nextState;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
return [hookStates[index] as T, setState] as const;
|
|
80
|
+
},
|
|
81
|
+
useEffect: (fn: () => (() => undefined) | undefined) => {
|
|
82
|
+
const cleanup = fn();
|
|
83
|
+
if (cleanup) effectCleanups.push(cleanup);
|
|
84
|
+
},
|
|
85
|
+
forwardRef: (fn: unknown) => fn,
|
|
86
|
+
lazy: (loader: unknown) => ({ loader }),
|
|
87
|
+
memo: <T,>(component: T) => component,
|
|
88
|
+
act: async (fn: () => void | Promise<void>) => await fn(),
|
|
89
|
+
}));
|
|
90
|
+
mock.module("akanjs/client", () => ({
|
|
91
|
+
DEFAULT_BOTTOM_INSET: 34,
|
|
92
|
+
DEFAULT_TOP_INSET: 44,
|
|
93
|
+
csrContext: { Provider: ({ children }: { children: unknown }) => children },
|
|
94
|
+
defaultPageState: {
|
|
95
|
+
transition: "none",
|
|
96
|
+
topSafeArea: 0,
|
|
97
|
+
bottomSafeArea: 0,
|
|
98
|
+
topInset: 0,
|
|
99
|
+
bottomInset: 0,
|
|
100
|
+
gesture: true,
|
|
101
|
+
cache: false,
|
|
102
|
+
},
|
|
103
|
+
Device: {
|
|
104
|
+
load: async () => ({
|
|
105
|
+
lang: "en",
|
|
106
|
+
info: { platform: contactsState.platform },
|
|
107
|
+
topSafeArea: 11,
|
|
108
|
+
bottomSafeArea: 22,
|
|
109
|
+
}),
|
|
110
|
+
getDevice: () => ({
|
|
111
|
+
info: { platform: contactsState.platform },
|
|
112
|
+
}),
|
|
113
|
+
},
|
|
114
|
+
initAuth: () => undefined,
|
|
115
|
+
router: {
|
|
116
|
+
state: {},
|
|
117
|
+
set: () => undefined,
|
|
118
|
+
emit: () => undefined,
|
|
119
|
+
on: () => undefined,
|
|
120
|
+
off: () => undefined,
|
|
121
|
+
},
|
|
122
|
+
storage: {
|
|
123
|
+
getItem: async () => null,
|
|
124
|
+
},
|
|
125
|
+
isMobileDevice: () => true,
|
|
126
|
+
}));
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const installCapacitorBridge = () => {
|
|
130
|
+
Object.defineProperty(globalThis, "Capacitor", {
|
|
131
|
+
value: {
|
|
132
|
+
Plugins: {
|
|
133
|
+
Camera: {
|
|
134
|
+
checkPermissions: async () => cameraState.permissions,
|
|
135
|
+
requestPermissions: async () => {
|
|
136
|
+
cameraState.requested += 1;
|
|
137
|
+
return cameraState.permissions;
|
|
138
|
+
},
|
|
139
|
+
getPhoto: async (options: { source: string }) => {
|
|
140
|
+
cameraState.photoSource = options.source;
|
|
141
|
+
if (cameraState.cancelled) throw "User cancelled photos app";
|
|
142
|
+
return { dataUrl: "data:image/png;base64,test" };
|
|
143
|
+
},
|
|
144
|
+
pickImages: async () => ({ photos: [{ webPath: "image.png" }] }),
|
|
145
|
+
},
|
|
146
|
+
Contacts: {
|
|
147
|
+
checkPermissions: async () => {
|
|
148
|
+
contactsState.checked += 1;
|
|
149
|
+
return contactsState.permissions;
|
|
150
|
+
},
|
|
151
|
+
requestPermissions: async () => {
|
|
152
|
+
contactsState.requested += 1;
|
|
153
|
+
return contactsState.permissions;
|
|
154
|
+
},
|
|
155
|
+
getContacts: async () => ({ contacts: [{ name: { display: "Ada" }, phones: [{ number: "123" }] }] }),
|
|
156
|
+
},
|
|
157
|
+
Geolocation: {
|
|
158
|
+
requestPermissions: async () => geolocationState.permissions,
|
|
159
|
+
getCurrentPosition: async () => ({ coords: { latitude: 37, longitude: 127 } }),
|
|
160
|
+
},
|
|
161
|
+
Device: {
|
|
162
|
+
getInfo: async () => ({ platform: pushState.platform }),
|
|
163
|
+
},
|
|
164
|
+
PushNotifications: {
|
|
165
|
+
requestPermissions: async () => ({ receive: pushState.receive }),
|
|
166
|
+
checkPermissions: async () => ({ receive: pushState.receive }),
|
|
167
|
+
register: async () => {
|
|
168
|
+
pushState.registered += 1;
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
FCM: {
|
|
172
|
+
setAutoInit: async () => {
|
|
173
|
+
pushState.autoInit += 1;
|
|
174
|
+
},
|
|
175
|
+
getToken: async () => ({ token: "token-1" }),
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
configurable: true,
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const installWindow = () => {
|
|
184
|
+
const createElement = (tagName = "div") =>
|
|
185
|
+
({
|
|
186
|
+
nodeType: 1,
|
|
187
|
+
nodeName: tagName.toUpperCase(),
|
|
188
|
+
tagName: tagName.toUpperCase(),
|
|
189
|
+
namespaceURI: "http://www.w3.org/1999/xhtml",
|
|
190
|
+
ownerDocument: null,
|
|
191
|
+
style: {},
|
|
192
|
+
childNodes: [],
|
|
193
|
+
addEventListener: () => undefined,
|
|
194
|
+
removeEventListener: () => undefined,
|
|
195
|
+
appendChild: () => undefined,
|
|
196
|
+
removeChild: () => undefined,
|
|
197
|
+
insertBefore: () => undefined,
|
|
198
|
+
setAttribute: () => undefined,
|
|
199
|
+
removeAttribute: () => undefined,
|
|
200
|
+
}) as unknown as HTMLDivElement;
|
|
201
|
+
const document = {
|
|
202
|
+
nodeType: 9,
|
|
203
|
+
documentElement: createElement("html"),
|
|
204
|
+
defaultView: null,
|
|
205
|
+
createElement,
|
|
206
|
+
addEventListener: () => undefined,
|
|
207
|
+
removeEventListener: () => undefined,
|
|
208
|
+
} as unknown as Document;
|
|
209
|
+
(document.documentElement as unknown as { ownerDocument: Document }).ownerDocument = document;
|
|
210
|
+
const window = {
|
|
211
|
+
location: { assign: (href: string) => assigned.push(href) },
|
|
212
|
+
document,
|
|
213
|
+
Capacitor: (globalThis as typeof globalThis & { Capacitor?: unknown }).Capacitor,
|
|
214
|
+
HTMLIFrameElement: class HTMLIFrameElement {},
|
|
215
|
+
Node: class Node {},
|
|
216
|
+
addEventListener: () => undefined,
|
|
217
|
+
removeEventListener: () => undefined,
|
|
218
|
+
} as unknown as Window & typeof globalThis;
|
|
219
|
+
(document as unknown as { defaultView: Window }).defaultView = window;
|
|
220
|
+
installCapacitorBridge();
|
|
221
|
+
(window as unknown as { Capacitor: unknown }).Capacitor = (
|
|
222
|
+
globalThis as typeof globalThis & { Capacitor?: unknown }
|
|
223
|
+
).Capacitor;
|
|
224
|
+
Object.defineProperty(globalThis, "window", { value: window, configurable: true });
|
|
225
|
+
Object.defineProperty(globalThis, "document", { value: document, configurable: true });
|
|
226
|
+
Object.defineProperty(globalThis, "location", { value: window.location, configurable: true });
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const renderHook = <T,>(hook: () => T): RenderHookResult<T> => {
|
|
230
|
+
hookIndex = 0;
|
|
231
|
+
const current = hook();
|
|
232
|
+
return {
|
|
233
|
+
get current() {
|
|
234
|
+
return current;
|
|
235
|
+
},
|
|
236
|
+
unmount: () =>
|
|
237
|
+
effectCleanups.splice(0).forEach((cleanup) => {
|
|
238
|
+
cleanup();
|
|
239
|
+
}),
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
afterEach(() => {
|
|
244
|
+
Object.defineProperty(globalThis, "window", { value: originalWindow, configurable: true });
|
|
245
|
+
Object.defineProperty(globalThis, "document", { value: originalDocument, configurable: true });
|
|
246
|
+
Object.defineProperty(globalThis, "location", { value: originalWindow?.location, configurable: true });
|
|
247
|
+
Object.defineProperty(globalThis, "Capacitor", { value: undefined, configurable: true });
|
|
248
|
+
globalThis.__AKAN_CAPACITOR_IMPORTS__ = undefined;
|
|
249
|
+
cameraState.permissions = { camera: "prompt", photos: "prompt" };
|
|
250
|
+
cameraState.requested = 0;
|
|
251
|
+
cameraState.photoSource = "";
|
|
252
|
+
cameraState.cancelled = false;
|
|
253
|
+
contactsState.platform = "web";
|
|
254
|
+
contactsState.permissions = { contacts: "prompt" };
|
|
255
|
+
contactsState.checked = 0;
|
|
256
|
+
contactsState.requested = 0;
|
|
257
|
+
geolocationState.permissions = { location: "granted", coarseLocation: "granted" };
|
|
258
|
+
pushState.platform = "web";
|
|
259
|
+
pushState.receive = "granted";
|
|
260
|
+
pushState.registered = 0;
|
|
261
|
+
pushState.autoInit = 0;
|
|
262
|
+
assigned.length = 0;
|
|
263
|
+
effectCleanups.splice(0);
|
|
264
|
+
hookIndex = 0;
|
|
265
|
+
hookStates.length = 0;
|
|
266
|
+
hookMemoStates = [];
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
describe("native hooks", () => {
|
|
270
|
+
test("useCamera requests permissions, uses web photo source, opens settings, and handles cancellation", async () => {
|
|
271
|
+
installWindow();
|
|
272
|
+
const { useCamera } = await import("./useCamera");
|
|
273
|
+
const hook = renderHook(() => useCamera());
|
|
274
|
+
|
|
275
|
+
expect(await hook.current.getPhoto("prompt")).toEqual({ dataUrl: "data:image/png;base64,test" });
|
|
276
|
+
expect(cameraState.photoSource).toBe("PHOTOS");
|
|
277
|
+
expect(cameraState.requested).toBe(1);
|
|
278
|
+
|
|
279
|
+
cameraState.permissions = { camera: "denied", photos: "denied" };
|
|
280
|
+
await hook.current.checkPermission("all");
|
|
281
|
+
await hook.current.checkPermission("all");
|
|
282
|
+
expect(assigned).toEqual(["app-settings:"]);
|
|
283
|
+
|
|
284
|
+
cameraState.cancelled = true;
|
|
285
|
+
expect(await hook.current.getPhoto("photos")).toBeUndefined();
|
|
286
|
+
hook.unmount();
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
test("useContact skips web initial check, requests permission, opens settings, and returns contacts", async () => {
|
|
290
|
+
installWindow();
|
|
291
|
+
const { useContact } = await import("./useContact");
|
|
292
|
+
const hook = renderHook(() => useContact());
|
|
293
|
+
|
|
294
|
+
expect(contactsState.checked).toBe(0);
|
|
295
|
+
expect(await hook.current.getContacts()).toEqual([{ name: { display: "Ada" }, phones: [{ number: "123" }] }]);
|
|
296
|
+
expect(contactsState.requested).toBe(1);
|
|
297
|
+
|
|
298
|
+
contactsState.permissions = { contacts: "denied" };
|
|
299
|
+
await hook.current.checkPermission();
|
|
300
|
+
await hook.current.checkPermission();
|
|
301
|
+
expect(assigned).toEqual(["app-settings:"]);
|
|
302
|
+
hook.unmount();
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
test("useGeoLocation returns permission and current position or opens settings", async () => {
|
|
306
|
+
installWindow();
|
|
307
|
+
const { useGeoLocation } = await import("./useGeoLocation");
|
|
308
|
+
const hook = renderHook(() => useGeoLocation());
|
|
309
|
+
|
|
310
|
+
expect(await hook.current.checkPermission()).toEqual({ geolocation: "granted", coarseLocation: "granted" });
|
|
311
|
+
expect(await hook.current.getPosition()).toEqual({ coords: { latitude: 37, longitude: 127 } });
|
|
312
|
+
geolocationState.permissions = { location: "denied", coarseLocation: "granted" };
|
|
313
|
+
expect(await hook.current.getPosition()).toBeUndefined();
|
|
314
|
+
expect(assigned).toEqual(["app-settings:"]);
|
|
315
|
+
hook.unmount();
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
test("usePushNoti is web no-op, registers native device, opens settings, and reads token", async () => {
|
|
319
|
+
installWindow();
|
|
320
|
+
const { usePushNoti } = await import("./usePushNoti");
|
|
321
|
+
const hook = renderHook(() => usePushNoti());
|
|
322
|
+
|
|
323
|
+
await hook.current.init();
|
|
324
|
+
await hook.current.register();
|
|
325
|
+
expect(await hook.current.getToken()).toBeUndefined();
|
|
326
|
+
expect(pushState.registered).toBe(0);
|
|
327
|
+
|
|
328
|
+
pushState.platform = "ios";
|
|
329
|
+
await hook.current.init();
|
|
330
|
+
await Promise.resolve();
|
|
331
|
+
await hook.current.register();
|
|
332
|
+
expect(pushState.autoInit).toBe(1);
|
|
333
|
+
expect(pushState.registered).toBe(2);
|
|
334
|
+
expect(await hook.current.getToken()).toBe("token-1");
|
|
335
|
+
|
|
336
|
+
pushState.receive = "denied";
|
|
337
|
+
await hook.current.register();
|
|
338
|
+
expect(assigned).toEqual(["app-settings:"]);
|
|
339
|
+
hook.unmount();
|
|
340
|
+
});
|
|
341
|
+
});
|