akanjs 0.0.1 → 2.0.0-beta.0
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/CODE_OF_CONDUCT.md +54 -0
- package/CONTRIBUTING.md +83 -0
- package/LICENSE +21 -0
- package/README.ko.md +244 -0
- package/README.md +237 -6
- package/base/base.ts +194 -0
- package/base/baseEnv.ts +162 -0
- package/base/index.ts +6 -0
- package/base/primitiveRegistry.ts +342 -0
- package/base/symbols.ts +11 -0
- package/base/types.ts +137 -0
- package/base/utils.ts +30 -0
- package/cli/application/application.command.ts +213 -0
- package/cli/application/application.interface.tsx +225 -0
- package/cli/application/application.runner.ts +359 -0
- package/cli/application/application.script.ts +244 -0
- package/cli/build.ts +25 -0
- package/cli/cloud/cloud.command.ts +48 -0
- package/cli/cloud/cloud.runner.ts +158 -0
- package/cli/cloud/cloud.script.ts +40 -0
- package/cli/guideline/guideline.command.ts +31 -0
- package/cli/guideline/guideline.prompt.ts +212 -0
- package/cli/guideline/guideline.runner.ts +53 -0
- package/cli/guideline/guideline.script.ts +33 -0
- package/cli/guidelines/___library/sharedUiStructureDescription.en.md +767 -0
- package/cli/guidelines/___library/utilUiStructureDescription.en.md +395 -0
- package/cli/guidelines/___lint/lintRuleDescription.en.md +64 -0
- package/cli/guidelines/___module/moduleStructureDescription.en.md +80 -0
- package/cli/guidelines/componentRule/componentRule.generate.json +131 -0
- package/cli/guidelines/componentRule/componentRule.instruction.md +637 -0
- package/cli/guidelines/cssRule/cssRule.generate.json +93 -0
- package/cli/guidelines/cssRule/cssRule.instruction.md +435 -0
- package/cli/guidelines/databaseModule/databaseModule.generate.json +51 -0
- package/cli/guidelines/databaseModule/databaseModule.instruction.md +612 -0
- package/cli/guidelines/docPageRule/docPageRule.generate.json +72 -0
- package/cli/guidelines/docPageRule/docPageRule.instruction.md +389 -0
- package/cli/guidelines/enumConstant/enumConstant.generate.json +24 -0
- package/cli/guidelines/enumConstant/enumConstant.instruction.md +232 -0
- package/cli/guidelines/framework/framework.generate.json +119 -0
- package/cli/guidelines/framework/framework.instruction.md +1110 -0
- package/cli/guidelines/howToUseStore/howToUseStore.generate.json +0 -0
- package/cli/guidelines/modelConstant/modelConstant.generate.json +128 -0
- package/cli/guidelines/modelConstant/modelConstant.instruction.md +506 -0
- package/cli/guidelines/modelDictionary/modelDictionary.generate.json +108 -0
- package/cli/guidelines/modelDictionary/modelDictionary.instruction.md +547 -0
- package/cli/guidelines/modelDocument/modelDocument.generate.json +129 -0
- package/cli/guidelines/modelDocument/modelDocument.instruction.md +536 -0
- package/cli/guidelines/modelService/modelService.generate.json +135 -0
- package/cli/guidelines/modelService/modelService.instruction.md +708 -0
- package/cli/guidelines/modelSignal/modelSignal.generate.json +201 -0
- package/cli/guidelines/modelSignal/modelSignal.instruction.md +552 -0
- package/cli/guidelines/modelStore/modelStore.generate.json +130 -0
- package/cli/guidelines/modelStore/modelStore.instruction.md +585 -0
- package/cli/guidelines/modelTemplate/modelTemplate.generate.json +104 -0
- package/cli/guidelines/modelTemplate/modelTemplate.instruction.md +604 -0
- package/cli/guidelines/modelUnit/modelUnit.generate.json +92 -0
- package/cli/guidelines/modelUnit/modelUnit.instruction.md +541 -0
- package/cli/guidelines/modelUtil/modelUtil.generate.json +93 -0
- package/cli/guidelines/modelUtil/modelUtil.instruction.md +752 -0
- package/cli/guidelines/modelView/modelView.generate.json +80 -0
- package/cli/guidelines/modelView/modelView.instruction.md +1005 -0
- package/cli/guidelines/modelZone/modelZone.generate.json +126 -0
- package/cli/guidelines/modelZone/modelZone.instruction.md +528 -0
- package/cli/guidelines/scalarConstant/scalarConstant.generate.json +106 -0
- package/cli/guidelines/scalarConstant/scalarConstant.instruction.md +442 -0
- package/cli/guidelines/scalarDictionary/scalarDictionary.generate.json +83 -0
- package/cli/guidelines/scalarDictionary/scalarDictionary.instruction.md +273 -0
- package/cli/guidelines/scalarModule/scalarModule.generate.json +35 -0
- package/cli/guidelines/scalarModule/scalarModule.instruction.md +81 -0
- package/cli/guidelines/sharedUiUsage/sharedUiUsage.generate.json +108 -0
- package/cli/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +310 -0
- package/cli/guidelines/utilUiUsage/utilUiUsage.generate.json +140 -0
- package/cli/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
- package/cli/index.js +11401 -0
- package/cli/index.ts +24 -0
- package/cli/library/library.command.ts +28 -0
- package/cli/library/library.runner.ts +69 -0
- package/cli/library/library.script.ts +39 -0
- package/cli/module/module.command.ts +35 -0
- package/cli/module/module.prompt.ts +18 -0
- package/cli/module/module.request.ts +319 -0
- package/cli/module/module.runner.ts +76 -0
- package/cli/module/module.script.ts +161 -0
- package/cli/package/package.command.ts +32 -0
- package/cli/package/package.runner.ts +64 -0
- package/cli/package/package.script.ts +35 -0
- package/cli/page/page.command.ts +14 -0
- package/cli/page/page.runner.ts +14 -0
- package/cli/page/page.script.ts +12 -0
- package/cli/scalar/scalar.command.ts +21 -0
- package/cli/scalar/scalar.prompt.ts +131 -0
- package/cli/scalar/scalar.runner.ts +38 -0
- package/cli/scalar/scalar.script.ts +16 -0
- package/cli/templates/__scalar/__model__/__model__.constant.ts +15 -0
- package/cli/templates/__scalar/__model__/__model__.dictionary.ts +19 -0
- package/cli/templates/__scalar/__model__/__model__.document.ts +15 -0
- package/cli/templates/app/akan.config.ts +14 -0
- package/cli/templates/app/capacitor.config.ts.template +8 -0
- package/cli/templates/app/common/commonLogic.ts +12 -0
- package/cli/templates/app/common/index.ts +10 -0
- package/cli/templates/app/env/env.client.debug.ts.template +7 -0
- package/cli/templates/app/env/env.client.develop.ts.template +7 -0
- package/cli/templates/app/env/env.client.local.ts.template +7 -0
- package/cli/templates/app/env/env.client.main.ts.template +7 -0
- package/cli/templates/app/env/env.client.testing.ts.template +7 -0
- package/cli/templates/app/env/env.client.ts +21 -0
- package/cli/templates/app/env/env.client.type.ts +16 -0
- package/cli/templates/app/env/env.server.debug.ts.template +7 -0
- package/cli/templates/app/env/env.server.develop.ts.template +9 -0
- package/cli/templates/app/env/env.server.local.ts.template +14 -0
- package/cli/templates/app/env/env.server.main.ts.template +9 -0
- package/cli/templates/app/env/env.server.testing.ts.template +6 -0
- package/cli/templates/app/env/env.server.ts +20 -0
- package/cli/templates/app/lib/___appName__/__appName__.dictionary.ts +17 -0
- package/cli/templates/app/lib/___appName__/__appName__.service.ts +13 -0
- package/cli/templates/app/lib/___appName__/__appName__.signal.ts +17 -0
- package/cli/templates/app/lib/___appName__/__appName__.store.ts +15 -0
- package/cli/templates/app/lib/option.ts +17 -0
- package/cli/templates/app/main.ts +16 -0
- package/cli/templates/app/package.json.template +5 -0
- package/cli/templates/app/page/_index.tsx +172 -0
- package/cli/templates/app/page/_layout.tsx +32 -0
- package/cli/templates/app/page/styles.css.template +53 -0
- package/cli/templates/app/public/favicon.ico +0 -0
- package/cli/templates/app/public/logo.png +0 -0
- package/cli/templates/app/srvkit/backendLogic.ts +12 -0
- package/cli/templates/app/srvkit/index.ts +10 -0
- package/cli/templates/app/tsconfig.json.template +21 -0
- package/cli/templates/app/ui/UiComponent.ts +16 -0
- package/cli/templates/app/ui/index.ts +10 -0
- package/cli/templates/app/webkit/frontendLogic.ts +12 -0
- package/cli/templates/app/webkit/index.ts +10 -0
- package/cli/templates/client.ts +46 -0
- package/cli/templates/crudPages/[__model__Id]/edit/page.tsx +47 -0
- package/cli/templates/crudPages/[__model__Id]/page.tsx +52 -0
- package/cli/templates/crudPages/new/page.tsx +42 -0
- package/cli/templates/crudPages/page.tsx +43 -0
- package/cli/templates/crudSinglePage/page.tsx +37 -0
- package/cli/templates/env/_env.server.type.ts +16 -0
- package/cli/templates/facetIndex/index.ts +32 -0
- package/cli/templates/index.ts +10 -0
- package/cli/templates/lib/__lib/lib.constant.ts +38 -0
- package/cli/templates/lib/__lib/lib.dictionary.ts +33 -0
- package/cli/templates/lib/__lib/lib.document.ts +35 -0
- package/cli/templates/lib/__lib/lib.service.ts +33 -0
- package/cli/templates/lib/__lib/lib.signal.ts +34 -0
- package/cli/templates/lib/__lib/lib.store.ts +33 -0
- package/cli/templates/lib/cnst.ts +29 -0
- package/cli/templates/lib/db.ts +32 -0
- package/cli/templates/lib/dict.ts +49 -0
- package/cli/templates/lib/sig.ts +60 -0
- package/cli/templates/lib/srv.ts +34 -0
- package/cli/templates/lib/st.ts +31 -0
- package/cli/templates/lib/useClient.ts +19 -0
- package/cli/templates/lib/useServer.ts +7 -0
- package/cli/templates/libRoot/.gitignore.template +16 -0
- package/cli/templates/libRoot/akan.config.ts +12 -0
- package/cli/templates/libRoot/base/baseLogic.ts +10 -0
- package/cli/templates/libRoot/base/index.ts +8 -0
- package/cli/templates/libRoot/common/commonLogic.ts +10 -0
- package/cli/templates/libRoot/common/index.ts +8 -0
- package/cli/templates/libRoot/env/env.server.example.ts.template +6 -0
- package/cli/templates/libRoot/env/env.server.testing.ts.template +6 -0
- package/cli/templates/libRoot/lib/___libName__/__libName__.dictionary.ts +15 -0
- package/cli/templates/libRoot/lib/___libName__/__libName__.service.ts +11 -0
- package/cli/templates/libRoot/lib/___libName__/__libName__.store.ts +13 -0
- package/cli/templates/libRoot/lib/option.ts +17 -0
- package/cli/templates/libRoot/package.json.template +5 -0
- package/cli/templates/libRoot/srvkit/backendLogic.ts +10 -0
- package/cli/templates/libRoot/srvkit/index.ts +8 -0
- package/cli/templates/libRoot/tsconfig.json.template +11 -0
- package/cli/templates/libRoot/ui/index.ts +7 -0
- package/cli/templates/libRoot/webkit/frontendLogic.ts +10 -0
- package/cli/templates/libRoot/webkit/index.ts +8 -0
- package/cli/templates/localDev/docker-compose.yaml.template +37 -0
- package/cli/templates/module/__Model__.Template.tsx +36 -0
- package/cli/templates/module/__Model__.Unit.tsx +26 -0
- package/cli/templates/module/__Model__.Util.tsx +30 -0
- package/cli/templates/module/__Model__.View.tsx +29 -0
- package/cli/templates/module/__Model__.Zone.tsx +43 -0
- package/cli/templates/module/__model__.constant.ts +24 -0
- package/cli/templates/module/__model__.dictionary.ts +30 -0
- package/cli/templates/module/__model__.document.ts +23 -0
- package/cli/templates/module/__model__.service.ts +16 -0
- package/cli/templates/module/__model__.signal.ts +27 -0
- package/cli/templates/module/__model__.store.ts +19 -0
- package/cli/templates/module/index.tsx +44 -0
- package/cli/templates/moduleRoot/index.tsx +31 -0
- package/cli/templates/pkgRoot/tsconfig.json.template +10 -0
- package/cli/templates/server.ts +45 -0
- package/cli/templates/workspaceRoot/.env.template +14 -0
- package/cli/templates/workspaceRoot/.gitignore.template +130 -0
- package/cli/templates/workspaceRoot/.vscode/settings.json.template +23 -0
- package/cli/templates/workspaceRoot/biome.json.template +175 -0
- package/cli/templates/workspaceRoot/bunfig.toml +4 -0
- package/cli/templates/workspaceRoot/infra/app/Chart.yaml.template +6 -0
- package/cli/templates/workspaceRoot/infra/app/templates/frontend.yaml.template +182 -0
- package/cli/templates/workspaceRoot/infra/app/values/_common-values.yaml.template +183 -0
- package/cli/templates/workspaceRoot/package.json.template +7 -0
- package/cli/templates/workspaceRoot/tsconfig.json.template +26 -0
- package/cli/testHelpers.ts +171 -0
- package/cli/workspace/workspace.command.ts +60 -0
- package/cli/workspace/workspace.runner.ts +57 -0
- package/cli/workspace/workspace.script.ts +68 -0
- package/client/capacitor.ts +68 -0
- package/client/clientRuntime.ts +141 -0
- package/client/cookie.ts +121 -0
- package/client/createFont.ts +8 -0
- package/client/csrTypes.ts +259 -0
- package/client/decorators.ts +25 -0
- package/client/device.ts +147 -0
- package/client/fetch.ts +1 -0
- package/client/index.ts +15 -0
- package/client/locale.ts +4 -0
- package/client/makePageProto.tsx +178 -0
- package/client/router.ts +286 -0
- package/client/rscNavigation.ts +19 -0
- package/client/storage.ts +33 -0
- package/client/translator.ts +43 -0
- package/client/types.ts +228 -0
- package/client/useClient.ts +1 -0
- package/common/Logger.ts +177 -0
- package/common/applyMixins.ts +14 -0
- package/common/capitalize.ts +4 -0
- package/common/deepObjectify.ts +27 -0
- package/common/formatNumber.ts +14 -0
- package/common/formatPhone.ts +7 -0
- package/common/getAllPropertyDescriptors.ts +13 -0
- package/common/hmrPhase.ts +17 -0
- package/common/httpClient.ts +101 -0
- package/common/index.ts +50 -0
- package/common/isDayjs.ts +3 -0
- package/common/isEmail.ts +2 -0
- package/common/isPhoneNumber.ts +8 -0
- package/common/isQueryEqual.ts +23 -0
- package/common/isValidDate.ts +14 -0
- package/common/localeConfig.ts +41 -0
- package/common/lowerlize.ts +4 -0
- package/common/mergeVersion.ts +10 -0
- package/common/objectify.ts +7 -0
- package/common/pathGet.ts +13 -0
- package/common/pathSet.ts +16 -0
- package/common/randomPick.ts +1 -0
- package/common/randomPicks.ts +12 -0
- package/common/routeConvention.ts +203 -0
- package/common/sleep.ts +8 -0
- package/common/splitVersion.ts +11 -0
- package/common/subRoute.ts +34 -0
- package/common/types.ts +15 -0
- package/constant/constantRegistry.ts +334 -0
- package/constant/crystalize.ts +45 -0
- package/constant/deserialize.ts +70 -0
- package/constant/fieldInfo.ts +415 -0
- package/constant/getDefault.ts +18 -0
- package/constant/immerify.ts +16 -0
- package/constant/index.ts +10 -0
- package/constant/purify.ts +118 -0
- package/constant/serialize.ts +87 -0
- package/constant/types.ts +105 -0
- package/constant/via.ts +360 -0
- package/devkit/aiEditor.ts +299 -0
- package/devkit/akanApp/akanApp.host.ts +356 -0
- package/devkit/akanApp/index.ts +1 -0
- package/devkit/akanConfig/akanConfig.ts +332 -0
- package/devkit/akanConfig/index.ts +2 -0
- package/devkit/akanConfig/types.ts +187 -0
- package/devkit/applicationBuildReporter.ts +69 -0
- package/devkit/applicationBuildRunner.ts +302 -0
- package/devkit/applicationReleasePackager.ts +205 -0
- package/devkit/artifact/implicitRootLayout.ts +155 -0
- package/devkit/artifact/index.ts +1 -0
- package/devkit/artifact/routeSeedIndex.ts +128 -0
- package/devkit/auth.ts +41 -0
- package/devkit/builder.ts +164 -0
- package/devkit/capacitor.base.config.ts +74 -0
- package/devkit/capacitorApp.ts +385 -0
- package/devkit/commandDecorators/argMeta.ts +88 -0
- package/devkit/commandDecorators/command.ts +314 -0
- package/devkit/commandDecorators/commandBuilder.ts +188 -0
- package/devkit/commandDecorators/commandMeta.ts +6 -0
- package/devkit/commandDecorators/dependencyBuilder.ts +100 -0
- package/devkit/commandDecorators/helpFormatter.ts +217 -0
- package/devkit/commandDecorators/index.ts +8 -0
- package/devkit/commandDecorators/targetMeta.ts +31 -0
- package/devkit/commandDecorators/types.ts +10 -0
- package/devkit/constants.ts +25 -0
- package/devkit/createTunnel.ts +36 -0
- package/devkit/dependencyScanner.ts +339 -0
- package/devkit/executors.ts +1326 -0
- package/devkit/extractDeps.ts +85 -0
- package/devkit/fileEditor.ts +106 -0
- package/devkit/fileSys.ts +39 -0
- package/devkit/frontendBuild/allRoutesBuilder.ts +103 -0
- package/devkit/frontendBuild/clientBuildTypes.ts +114 -0
- package/devkit/frontendBuild/clientEntriesBundler.ts +300 -0
- package/devkit/frontendBuild/clientEntryDiscovery.ts +196 -0
- package/devkit/frontendBuild/csrArtifactBuilder.ts +237 -0
- package/devkit/frontendBuild/cssCompiler.ts +279 -0
- package/devkit/frontendBuild/cssImportResolver.ts +116 -0
- package/devkit/frontendBuild/fontOptimizer.ts +427 -0
- package/devkit/frontendBuild/hmrChangeClassifier.ts +28 -0
- package/devkit/frontendBuild/hmrWatcher.ts +101 -0
- package/devkit/frontendBuild/index.ts +18 -0
- package/devkit/frontendBuild/pagesBundleBuilder.ts +137 -0
- package/devkit/frontendBuild/pagesEntrySourceGenerator.ts +37 -0
- package/devkit/frontendBuild/precompressArtifacts.ts +59 -0
- package/devkit/frontendBuild/routeClientBuilder.ts +290 -0
- package/devkit/frontendBuild/routesManifestArtifactSerializer.ts +62 -0
- package/devkit/frontendBuild/ssrBaseArtifactBuilder.ts +139 -0
- package/devkit/frontendBuild/vendorSpecifiers.ts +16 -0
- package/devkit/frontendBuild/watchRootResolver.ts +28 -0
- package/devkit/getCredentials.ts +19 -0
- package/devkit/getDirname.ts +3 -0
- package/devkit/getModelFileData.ts +59 -0
- package/devkit/getRelatedCnsts.ts +300 -0
- package/devkit/guideline.ts +19 -0
- package/devkit/incrementalBuilder/incrementalBuilder.host.ts +78 -0
- package/devkit/incrementalBuilder/incrementalBuilder.proc.ts +330 -0
- package/devkit/incrementalBuilder/index.ts +1 -0
- package/devkit/index.ts +36 -0
- package/devkit/lint/no-import-client-functions.grit +32 -0
- package/devkit/lint/no-import-external-library.grit +21 -0
- package/devkit/lint/no-js-private-class-method.grit +42 -0
- package/devkit/lint/no-use-client-in-server.grit +7 -0
- package/devkit/lint/non-scalar-props-restricted.grit +13 -0
- package/devkit/linter.ts +248 -0
- package/devkit/mobile/index.ts +1 -0
- package/devkit/mobile/mobileTarget.ts +47 -0
- package/devkit/prompter.ts +71 -0
- package/devkit/scanInfo.ts +605 -0
- package/devkit/selectModel.ts +11 -0
- package/devkit/spinner.ts +54 -0
- package/devkit/sshTunnel.ts +151 -0
- package/devkit/streamAi.ts +45 -0
- package/devkit/transforms/barrelAnalyzer.ts +249 -0
- package/devkit/transforms/barrelImportsPlugin.ts +451 -0
- package/devkit/transforms/externalizeFrameworkPlugin.ts +159 -0
- package/devkit/transforms/index.ts +5 -0
- package/devkit/transforms/rscUseClientTransform.ts +52 -0
- package/devkit/transforms/useClientBundlePlugin.ts +47 -0
- package/devkit/typeChecker.ts +260 -0
- package/devkit/types.ts +42 -0
- package/devkit/ui/MultiScrollList.tsx +228 -0
- package/devkit/ui/ScrollList.tsx +106 -0
- package/devkit/ui/index.ts +2 -0
- package/devkit/uploadRelease.ts +95 -0
- package/devkit/useStdoutDimensions.ts +20 -0
- package/dictionary/base.dictionary.ts +91 -0
- package/dictionary/dictInfo.ts +1079 -0
- package/dictionary/dictionary.ts +10 -0
- package/dictionary/index.ts +12 -0
- package/dictionary/locale.ts +230 -0
- package/dictionary/trans.ts +196 -0
- package/document/by.ts +39 -0
- package/document/dataLoader.ts +91 -0
- package/document/database.ts +168 -0
- package/document/databaseRegistry.ts +113 -0
- package/document/documentQuery.ts +143 -0
- package/document/documentSchema.ts +91 -0
- package/document/filterMeta.ts +210 -0
- package/document/index.ts +11 -0
- package/document/into.ts +169 -0
- package/document/loaderInfo.ts +50 -0
- package/document/schema.ts +24 -0
- package/document/types.ts +41 -0
- package/fetch/client/fetchClient.ts +600 -0
- package/fetch/client/httpClient.ts +157 -0
- package/fetch/client/index.ts +3 -0
- package/fetch/client/wsClient.ts +246 -0
- package/fetch/fetchType/appliedReturn.type.ts +108 -0
- package/fetch/fetchType/buildFetch.type.ts +24 -0
- package/fetch/fetchType/clientSignal.type.ts +22 -0
- package/fetch/fetchType/endpointFetch.type.ts +56 -0
- package/fetch/fetchType/index.ts +5 -0
- package/fetch/fetchType/sliceFetch.type.ts +173 -0
- package/fetch/index.ts +4 -0
- package/fetch/requestStorage.ts +127 -0
- package/fetch/serializer/fetch.serializer.ts +131 -0
- package/fetch/serializer/index.ts +1 -0
- package/fetch/types.ts +28 -0
- package/package.json +202 -5
- package/server/SSR_MEMORY_DIAGNOSIS.md +107 -0
- package/server/akanApp.ts +855 -0
- package/server/akanLib.ts +43 -0
- package/server/akanOption.ts +42 -0
- package/server/akanServer.ts +369 -0
- package/server/artifact/builderRpc.ts +124 -0
- package/server/artifact/index.ts +6 -0
- package/server/artifact/ipcTypes.ts +46 -0
- package/server/artifact/manifestTypes.ts +19 -0
- package/server/artifact/routeClientCache.ts +224 -0
- package/server/artifact/routeSeedIndexStore.ts +89 -0
- package/server/artifact/routesManifestStore.ts +120 -0
- package/server/decorators.ts +95 -0
- package/server/di/diLifecycle.ts +520 -0
- package/server/di/index.ts +4 -0
- package/server/di/predefinedAdaptor.ts +77 -0
- package/server/di/resolveAdaptorHierarchy.ts +82 -0
- package/server/di/resolveHierarchy.ts +89 -0
- package/server/di/resolveServiceHierarchy.ts +47 -0
- package/server/di/utils.ts +40 -0
- package/server/hmr/changeBatch.ts +14 -0
- package/server/hmr/clientScript.ts +310 -0
- package/server/hmr/devHmrController.ts +395 -0
- package/server/hmr/index.ts +4 -0
- package/server/hmr/wsHub.ts +56 -0
- package/server/imageOptimizer.ts +427 -0
- package/server/imageOptimizerError.ts +8 -0
- package/server/index.ts +14 -0
- package/server/lifecycle/shutdownManager.ts +52 -0
- package/server/logging/rotatingLogWriter.ts +190 -0
- package/server/processMetricsCollector.ts +78 -0
- package/server/proxy/akanResponse.ts +16 -0
- package/server/proxy/bunRequestFields.ts +12 -0
- package/server/proxy/hostBasePathWebProxy.ts +112 -0
- package/server/proxy/index.ts +15 -0
- package/server/proxy/localeWebProxy.ts +71 -0
- package/server/proxy/types.ts +41 -0
- package/server/proxy/webProxyRunner.ts +90 -0
- package/server/resolver/database.resolver.ts +340 -0
- package/server/resolver/index.ts +3 -0
- package/server/resolver/resolver.contract.fixture.ts +222 -0
- package/server/resolver/service.resolver.ts +176 -0
- package/server/resolver/signal.resolver.ts +386 -0
- package/server/robots.ts +32 -0
- package/server/routeElementComposer.tsx +91 -0
- package/server/routeTreeBuilder.ts +279 -0
- package/server/routing/apiRouter.ts +226 -0
- package/server/rscClient.tsx +140 -0
- package/server/rscWorker.tsx +625 -0
- package/server/rscWorkerHost.ts +616 -0
- package/server/sitemap.ts +90 -0
- package/server/ssrFromRscRenderer.tsx +285 -0
- package/server/ssrTypes.ts +48 -0
- package/server/types/react-server-dom-webpack.d.ts +91 -0
- package/server/types.tsx +109 -0
- package/server/vendor/akanjs-base.ts +1 -0
- package/server/vendor/akanjs-common.ts +1 -0
- package/server/vendor/akanjs-constant.ts +1 -0
- package/server/vendor/akanjs-store.ts +1 -0
- package/server/vendor/react-dom-client.ts +5 -0
- package/server/vendor/react-dom.ts +21 -0
- package/server/vendor/react-jsx-dev-runtime.ts +5 -0
- package/server/vendor/react-jsx-runtime.ts +5 -0
- package/server/vendor/react-refresh-runtime.ts +6 -0
- package/server/vendor/react-server-dom-webpack-client-browser.ts +12 -0
- package/server/vendor/react.ts +51 -0
- package/server/vendor/scheduler.ts +23 -0
- package/server/webRouter.ts +712 -0
- package/service/adapt.ts +47 -0
- package/service/base.service.ts +18 -0
- package/service/index.ts +10 -0
- package/service/injectInfo.ts +393 -0
- package/service/ipcTypes.ts +127 -0
- package/service/predefinedAdaptor/cache.adaptor.ts +105 -0
- package/service/predefinedAdaptor/compress.adaptor.ts +357 -0
- package/service/predefinedAdaptor/database.adaptor.ts +1310 -0
- package/service/predefinedAdaptor/index.ts +13 -0
- package/service/predefinedAdaptor/logging.adaptor.ts +36 -0
- package/service/predefinedAdaptor/queue.adaptor.ts +42 -0
- package/service/predefinedAdaptor/role.adaptor.ts +18 -0
- package/service/predefinedAdaptor/schedule.adaptor.ts +188 -0
- package/service/predefinedAdaptor/solidCache.adaptor.ts +143 -0
- package/service/predefinedAdaptor/solidPubsub.adaptor.ts +98 -0
- package/service/predefinedAdaptor/solidQueue.adaptor.ts +203 -0
- package/service/predefinedAdaptor/solidSqlite.ts +85 -0
- package/service/predefinedAdaptor/sqlitePath.ts +20 -0
- package/service/predefinedAdaptor/storage.adaptor.ts +121 -0
- package/service/predefinedAdaptor/websocket.adaptor.ts +313 -0
- package/service/serve.ts +223 -0
- package/service/serviceModule.ts +221 -0
- package/service/serviceRegistry.ts +26 -0
- package/service/types.ts +113 -0
- package/signal/base.signal.ts +46 -0
- package/signal/endpoint.ts +122 -0
- package/signal/endpointInfo.ts +374 -0
- package/signal/exception.ts +50 -0
- package/signal/guard.ts +18 -0
- package/signal/guards.ts +16 -0
- package/signal/index.ts +18 -0
- package/signal/intercept.ts +39 -0
- package/signal/internal.ts +56 -0
- package/signal/internalArg.ts +38 -0
- package/signal/internalInfo.ts +208 -0
- package/signal/middleware.ts +108 -0
- package/signal/serializer/fetch.serializer.ts +128 -0
- package/signal/serializer/index.ts +1 -0
- package/signal/serverSignal.ts +114 -0
- package/signal/signalContext.ts +446 -0
- package/signal/signalRegistry.ts +82 -0
- package/signal/slice.ts +158 -0
- package/signal/sliceInfo.ts +254 -0
- package/signal/types.ts +131 -0
- package/store/action.ts +1067 -0
- package/store/baseSt.ts +81 -0
- package/store/hooks.ts +2 -0
- package/store/index.ts +8 -0
- package/store/rootStore.ts +26 -0
- package/store/state.ts +226 -0
- package/store/stateBuilder.ts +429 -0
- package/store/stateInfo.ts +66 -0
- package/store/store.ts +194 -0
- package/store/storeInstance.ts +382 -0
- package/store/storeRegistry.ts +84 -0
- package/store/types.ts +69 -0
- package/store/withSelector.ts +62 -0
- package/test/index.ts +16 -0
- package/test/playwright.config.base.ts +48 -0
- package/test/playwright.pageAgent.ts +41 -0
- package/test/sample.ts +19 -0
- package/test/sampleOf.ts +70 -0
- package/test/signalTest.preload.ts +10 -0
- package/test/signalTestRuntime.ts +126 -0
- package/test/testServer.ts +187 -0
- package/ui/BottomSheet.tsx +103 -0
- package/ui/Button.tsx +70 -0
- package/ui/ClientSide.tsx +11 -0
- package/ui/Clipboard.tsx +49 -0
- package/ui/Constant/Doc.tsx +696 -0
- package/ui/Constant/Mermaid.tsx +149 -0
- package/ui/Constant/index.ts +6 -0
- package/ui/Constant/schemaDoc.ts +324 -0
- package/ui/Copy.tsx +27 -0
- package/ui/CsrImage.tsx +38 -0
- package/ui/Data/CardList.tsx +141 -0
- package/ui/Data/Dashboard.tsx +72 -0
- package/ui/Data/Insight.tsx +35 -0
- package/ui/Data/Item.tsx +285 -0
- package/ui/Data/ListContainer.tsx +320 -0
- package/ui/Data/Pagination.tsx +54 -0
- package/ui/Data/QueryMaker.tsx +21 -0
- package/ui/Data/TableList.tsx +161 -0
- package/ui/Data/index.ts +11 -0
- package/ui/Data/index_.tsx +11 -0
- package/ui/DatePicker.tsx +184 -0
- package/ui/Dialog/Action.tsx +15 -0
- package/ui/Dialog/Close.tsx +22 -0
- package/ui/Dialog/Content.tsx +11 -0
- package/ui/Dialog/Modal.tsx +137 -0
- package/ui/Dialog/Provider.tsx +33 -0
- package/ui/Dialog/Title.tsx +15 -0
- package/ui/Dialog/Trigger.tsx +22 -0
- package/ui/Dialog/context.ts +20 -0
- package/ui/Dialog/index.tsx +15 -0
- package/ui/DragAction.tsx +129 -0
- package/ui/DraggableList.tsx +230 -0
- package/ui/Dropdown.tsx +51 -0
- package/ui/Empty.tsx +32 -0
- package/ui/Field.tsx +1556 -0
- package/ui/FontFace.tsx +26 -0
- package/ui/Image.tsx +185 -0
- package/ui/InfiniteScroll.tsx +67 -0
- package/ui/Input.tsx +636 -0
- package/ui/KeyboardAvoiding.tsx +62 -0
- package/ui/Layout/BottomAction.tsx +15 -0
- package/ui/Layout/BottomInset.tsx +42 -0
- package/ui/Layout/BottomTab.tsx +71 -0
- package/ui/Layout/Header.tsx +38 -0
- package/ui/Layout/LeftSider.tsx +34 -0
- package/ui/Layout/Navbar.tsx +46 -0
- package/ui/Layout/RightSider.tsx +41 -0
- package/ui/Layout/Sider.tsx +69 -0
- package/ui/Layout/Template.tsx +11 -0
- package/ui/Layout/TopLeftAction.tsx +28 -0
- package/ui/Layout/Unit.tsx +19 -0
- package/ui/Layout/View.tsx +12 -0
- package/ui/Layout/Zone.tsx +10 -0
- package/ui/Layout/index.ts +27 -0
- package/ui/Link/Back.tsx +15 -0
- package/ui/Link/Close.tsx +20 -0
- package/ui/Link/CsrLink.tsx +41 -0
- package/ui/Link/Lang.tsx +16 -0
- package/ui/Link/SsrLink.tsx +68 -0
- package/ui/Link/index.tsx +32 -0
- package/ui/Link/types.ts +47 -0
- package/ui/Load/Edit.tsx +19 -0
- package/ui/Load/Edit_Client.tsx +120 -0
- package/ui/Load/Page.tsx +40 -0
- package/ui/Load/PageCSR.tsx +39 -0
- package/ui/Load/Pagination.tsx +89 -0
- package/ui/Load/Units.tsx +330 -0
- package/ui/Load/View.tsx +115 -0
- package/ui/Load/index.ts +11 -0
- package/ui/Load/index_.tsx +6 -0
- package/ui/Loading/Area.tsx +10 -0
- package/ui/Loading/Button.tsx +17 -0
- package/ui/Loading/Input.tsx +17 -0
- package/ui/Loading/ProgressBar.tsx +14 -0
- package/ui/Loading/Skeleton.tsx +22 -0
- package/ui/Loading/Spin.tsx +22 -0
- package/ui/Loading/index.tsx +8 -0
- package/ui/Menu.tsx +273 -0
- package/ui/Modal.tsx +87 -0
- package/ui/Model/AdminPanel.tsx +51 -0
- package/ui/Model/Edit.tsx +46 -0
- package/ui/Model/EditModal.tsx +301 -0
- package/ui/Model/EditWrapper.tsx +48 -0
- package/ui/Model/LoadInit.tsx +11 -0
- package/ui/Model/New.tsx +46 -0
- package/ui/Model/NewWrapper.tsx +20 -0
- package/ui/Model/NewWrapper_Client.tsx +57 -0
- package/ui/Model/Remove.tsx +75 -0
- package/ui/Model/RemoveWrapper.tsx +38 -0
- package/ui/Model/SureToRemove.tsx +108 -0
- package/ui/Model/View.tsx +65 -0
- package/ui/Model/ViewEditModal.tsx +125 -0
- package/ui/Model/ViewModal.tsx +71 -0
- package/ui/Model/ViewWrapper.tsx +38 -0
- package/ui/Model/index.ts +33 -0
- package/ui/Model/index_.tsx +16 -0
- package/ui/More.tsx +56 -0
- package/ui/ObjectId.tsx +29 -0
- package/ui/Pagination.tsx +120 -0
- package/ui/Popconfirm.tsx +135 -0
- package/ui/Portal.tsx +10 -0
- package/ui/Radio.tsx +53 -0
- package/ui/RecentTime.tsx +123 -0
- package/ui/Refresh.tsx +24 -0
- package/ui/ScreenNavigator.tsx +129 -0
- package/ui/Select.tsx +322 -0
- package/ui/Signal/Arg.tsx +352 -0
- package/ui/Signal/Doc.tsx +231 -0
- package/ui/Signal/Listener.tsx +74 -0
- package/ui/Signal/Message.tsx +267 -0
- package/ui/Signal/Object.tsx +131 -0
- package/ui/Signal/PubSub.tsx +247 -0
- package/ui/Signal/Request.tsx +30 -0
- package/ui/Signal/Response.tsx +76 -0
- package/ui/Signal/RestApi.tsx +390 -0
- package/ui/Signal/WebSocket.tsx +47 -0
- package/ui/Signal/index.ts +10 -0
- package/ui/Signal/makeExample.ts +75 -0
- package/ui/System/CSR.tsx +420 -0
- package/ui/System/Client.tsx +296 -0
- package/ui/System/Common.tsx +83 -0
- package/ui/System/DevModeToggle.tsx +21 -0
- package/ui/System/Gtag.tsx +69 -0
- package/ui/System/Messages.tsx +175 -0
- package/ui/System/Reconnect.tsx +156 -0
- package/ui/System/Root.tsx +10 -0
- package/ui/System/SSR.tsx +163 -0
- package/ui/System/SelectLanguage.tsx +47 -0
- package/ui/System/ThemeToggle.tsx +98 -0
- package/ui/System/index.tsx +23 -0
- package/ui/Tab/Menu.tsx +56 -0
- package/ui/Tab/Menus.tsx +10 -0
- package/ui/Tab/Panel.tsx +25 -0
- package/ui/Tab/Provider.tsx +25 -0
- package/ui/Tab/context.ts +16 -0
- package/ui/Tab/index.tsx +11 -0
- package/ui/Table.tsx +131 -0
- package/ui/ToggleSelect.tsx +144 -0
- package/ui/Unauthorized.tsx +29 -0
- package/ui/animated.tsx +8 -0
- package/ui/fontCss.ts +86 -0
- package/ui/index.ts +44 -0
- package/ui/styles.css +617 -0
- package/webkit/bootCsr.tsx +275 -0
- package/webkit/createRobotPage.ts +15 -0
- package/webkit/createSitemapPage.ts +4 -0
- package/webkit/index.ts +19 -0
- package/webkit/lazy.tsx +37 -0
- package/webkit/types.ts +7 -0
- package/webkit/useCamera.tsx +99 -0
- package/webkit/useCodepush.tsx +99 -0
- package/webkit/useContact.tsx +48 -0
- package/webkit/useCsrValues.ts +661 -0
- package/webkit/useDebounce.ts +24 -0
- package/webkit/useFetch.ts +48 -0
- package/webkit/useGeoLocation.tsx +24 -0
- package/webkit/useHistory.ts +76 -0
- package/webkit/useInterval.ts +21 -0
- package/webkit/useLocation.ts +69 -0
- package/webkit/usePurchase.tsx +156 -0
- package/webkit/usePushNoti.tsx +48 -0
- package/webkit/useThrottle.ts +22 -0
- package/src/index.js +0 -2
- package/src/index.js.map +0 -1
- package/src/lib/akan2.js +0 -4
- package/src/lib/akan2.js.map +0 -1
- package/src/run.js +0 -4
- package/src/run.js.map +0 -1
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Cls,
|
|
3
|
+
DataList,
|
|
4
|
+
type EnumInstance,
|
|
5
|
+
getEnv,
|
|
6
|
+
getNonArrayModel,
|
|
7
|
+
isEnum,
|
|
8
|
+
PRIMITIVE_DEFAULT_VALUE,
|
|
9
|
+
PrimitiveRegistry,
|
|
10
|
+
type PrimitiveScalar,
|
|
11
|
+
} from "akanjs/base";
|
|
12
|
+
import { ConstantRegistry } from "akanjs/constant";
|
|
13
|
+
|
|
14
|
+
export type StateInitializer = () => unknown;
|
|
15
|
+
export type StateInitializerMap = Record<string, StateInitializer>;
|
|
16
|
+
export type SearchParamsState = Record<string, string | string[]>;
|
|
17
|
+
|
|
18
|
+
export interface PersistSessionMeta {
|
|
19
|
+
kind: "persist" | "session";
|
|
20
|
+
key: string;
|
|
21
|
+
storageKey: string;
|
|
22
|
+
parse: (value: unknown) => unknown;
|
|
23
|
+
serialize: (value: unknown) => unknown;
|
|
24
|
+
getDefault: () => unknown;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SearchMeta {
|
|
28
|
+
kind: "search";
|
|
29
|
+
key: string;
|
|
30
|
+
paramKey: string;
|
|
31
|
+
parseSearch: (searchParams: SearchParamsState) => unknown;
|
|
32
|
+
getDefault: () => unknown;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ComputedMeta {
|
|
36
|
+
kind: "computed";
|
|
37
|
+
key: string;
|
|
38
|
+
deps: readonly string[];
|
|
39
|
+
selector: (...values: any[]) => any;
|
|
40
|
+
equals: (a: any, b: any) => boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface StateDerivedMeta {
|
|
44
|
+
persistSession: Record<string, PersistSessionMeta>;
|
|
45
|
+
search: Record<string, SearchMeta>;
|
|
46
|
+
computed: Record<string, ComputedMeta>;
|
|
47
|
+
derivedKeys: Set<string>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const STATE_BUILDER_MARK = Symbol.for("akanjs.store.builder.marker");
|
|
51
|
+
|
|
52
|
+
type Marker =
|
|
53
|
+
| { [STATE_BUILDER_MARK]: true; kind: "persist" | "session"; type: any; options: PersistSessionOptions<any> }
|
|
54
|
+
| { [STATE_BUILDER_MARK]: true; kind: "search"; paramKey: string; type: any; options: SearchOptions<any> }
|
|
55
|
+
| {
|
|
56
|
+
[STATE_BUILDER_MARK]: true;
|
|
57
|
+
kind: "computed";
|
|
58
|
+
deps: readonly string[];
|
|
59
|
+
selector: (...values: any[]) => any;
|
|
60
|
+
options: ComputedOptions<any>;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export interface PersistSessionOptions<T> {
|
|
64
|
+
default?: T | (() => T);
|
|
65
|
+
key?: string;
|
|
66
|
+
nullable?: boolean;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface SearchOptions<T> {
|
|
70
|
+
default?: T | (() => T);
|
|
71
|
+
nullable?: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface ComputedOptions<T> {
|
|
75
|
+
equals?: (a: T, b: T) => boolean;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
type PrimitiveInput = typeof PrimitiveScalar | StringConstructor | BooleanConstructor | DateConstructor;
|
|
79
|
+
type FieldTypeInput = PrimitiveInput | Cls | EnumInstance | FieldTypeInput[];
|
|
80
|
+
|
|
81
|
+
type ValueOfType<T> = T extends readonly (infer V)[]
|
|
82
|
+
? ValueOfType<V>[]
|
|
83
|
+
: T extends { [PRIMITIVE_DEFAULT_VALUE]: infer V }
|
|
84
|
+
? V
|
|
85
|
+
: T extends EnumInstance<any, infer V>
|
|
86
|
+
? V
|
|
87
|
+
: T extends new (
|
|
88
|
+
...args: any[]
|
|
89
|
+
) => infer V
|
|
90
|
+
? V
|
|
91
|
+
: any;
|
|
92
|
+
|
|
93
|
+
type NullableValue<Value, Options> = Options extends { nullable: true } ? Value | null : Value;
|
|
94
|
+
|
|
95
|
+
export type WritableStateOf<State> = {
|
|
96
|
+
[K in keyof State]: State[K] extends Marker ? MarkerValue<State[K]> : State[K];
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
type MarkerValue<M> = M extends { kind: "persist" | "session"; type: infer T; options: infer O }
|
|
100
|
+
? NullableValue<ValueOfType<T>, O>
|
|
101
|
+
: M extends { kind: "search"; type: infer T; options: infer O }
|
|
102
|
+
? NullableValue<ValueOfType<T>, O>
|
|
103
|
+
: M extends { kind: "computed"; selector: (...args: any[]) => infer R }
|
|
104
|
+
? R
|
|
105
|
+
: never;
|
|
106
|
+
|
|
107
|
+
export type DerivedStateOf<State> = {
|
|
108
|
+
[K in keyof State]: State[K] extends Marker ? MarkerValue<State[K]> : never;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export type DepValues<State, Keys extends readonly (keyof State)[]> = {
|
|
112
|
+
[I in keyof Keys]: Keys[I] extends keyof State ? State[Keys[I]] : never;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export interface WritableStateBuilder {
|
|
116
|
+
persist<T extends FieldTypeInput, Options extends PersistSessionOptions<any>>(
|
|
117
|
+
type: T,
|
|
118
|
+
options?: Options,
|
|
119
|
+
): { [STATE_BUILDER_MARK]: true; kind: "persist"; type: T; options: Options };
|
|
120
|
+
session<T extends FieldTypeInput, Options extends PersistSessionOptions<any>>(
|
|
121
|
+
type: T,
|
|
122
|
+
options?: Options,
|
|
123
|
+
): { [STATE_BUILDER_MARK]: true; kind: "session"; type: T; options: Options };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface DerivedStateBuilder<WritableState> {
|
|
127
|
+
search<T extends FieldTypeInput, Options extends SearchOptions<any>>(
|
|
128
|
+
paramKey: string,
|
|
129
|
+
type: T,
|
|
130
|
+
options?: Options,
|
|
131
|
+
): { [STATE_BUILDER_MARK]: true; kind: "search"; paramKey: string; type: T; options: Options };
|
|
132
|
+
computed<const Keys extends readonly (keyof WritableState & string)[], Result>(
|
|
133
|
+
deps: Keys,
|
|
134
|
+
selector: (...values: DepValues<WritableState, Keys>) => Result,
|
|
135
|
+
options?: ComputedOptions<Result>,
|
|
136
|
+
): {
|
|
137
|
+
[STATE_BUILDER_MARK]: true;
|
|
138
|
+
kind: "computed";
|
|
139
|
+
deps: Keys;
|
|
140
|
+
selector: (...values: any[]) => Result;
|
|
141
|
+
options: ComputedOptions<Result>;
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export const createEmptyDerivedMeta = (): StateDerivedMeta => ({
|
|
146
|
+
persistSession: {},
|
|
147
|
+
search: {},
|
|
148
|
+
computed: {},
|
|
149
|
+
derivedKeys: new Set(),
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
export const mergeDerivedMeta = (...metas: (StateDerivedMeta | undefined)[]): StateDerivedMeta => {
|
|
153
|
+
const merged = createEmptyDerivedMeta();
|
|
154
|
+
for (const meta of metas) {
|
|
155
|
+
if (!meta) continue;
|
|
156
|
+
mergeMetaRecord(merged.persistSession, meta.persistSession);
|
|
157
|
+
mergeMetaRecord(merged.search, meta.search);
|
|
158
|
+
mergeMetaRecord(merged.computed, meta.computed);
|
|
159
|
+
for (const key of meta.derivedKeys) {
|
|
160
|
+
if (merged.derivedKeys.has(key)) throw new Error(`Duplicate derived state key: ${key}`);
|
|
161
|
+
merged.derivedKeys.add(key);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return merged;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const mergeMetaRecord = <T>(target: Record<string, T>, source: Record<string, T>) => {
|
|
168
|
+
for (const [key, value] of Object.entries(source)) {
|
|
169
|
+
if (key in target) throw new Error(`Duplicate state metadata key: ${key}`);
|
|
170
|
+
target[key] = value;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export const createWritableStateBuilder = (): WritableStateBuilder => ({
|
|
175
|
+
persist: (type, options) => ({ [STATE_BUILDER_MARK]: true, kind: "persist", type, options: options ?? {} }) as any,
|
|
176
|
+
session: (type, options) => ({ [STATE_BUILDER_MARK]: true, kind: "session", type, options: options ?? {} }) as any,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
export const createDerivedStateBuilder = <WritableState>(): DerivedStateBuilder<WritableState> => ({
|
|
180
|
+
search: (paramKey, type, options) =>
|
|
181
|
+
({ [STATE_BUILDER_MARK]: true, kind: "search", paramKey, type, options: options ?? {} }) as any,
|
|
182
|
+
computed: (deps, selector, options) =>
|
|
183
|
+
({ [STATE_BUILDER_MARK]: true, kind: "computed", deps, selector, options: options ?? {} }) as any,
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
export const isStateBuilderMarker = (value: unknown): value is Marker =>
|
|
187
|
+
Boolean(value && typeof value === "object" && (value as { [STATE_BUILDER_MARK]?: boolean })[STATE_BUILDER_MARK]);
|
|
188
|
+
|
|
189
|
+
export const createStateInitializerMap = (state: Record<string, unknown>): StateInitializerMap =>
|
|
190
|
+
Object.fromEntries(Object.entries(state).map(([key, value]) => [key, makeDefaultFactory(value)]));
|
|
191
|
+
|
|
192
|
+
export const evaluateInitializers = (initializers: StateInitializerMap): Record<string, unknown> =>
|
|
193
|
+
Object.fromEntries(Object.entries(initializers).map(([key, init]) => [key, init()]));
|
|
194
|
+
|
|
195
|
+
export const resolveWritableState = (
|
|
196
|
+
refName: string,
|
|
197
|
+
state: Record<string, unknown>,
|
|
198
|
+
): { shape: Record<string, unknown>; initializers: StateInitializerMap; meta: StateDerivedMeta } => {
|
|
199
|
+
const shape: Record<string, unknown> = {};
|
|
200
|
+
const initializers: StateInitializerMap = {};
|
|
201
|
+
const meta = createEmptyDerivedMeta();
|
|
202
|
+
|
|
203
|
+
for (const [key, value] of Object.entries(state)) {
|
|
204
|
+
if (isStateBuilderMarker(value)) {
|
|
205
|
+
if (value.kind !== "persist" && value.kind !== "session") throw new Error(`${value.kind} is not writable state`);
|
|
206
|
+
const codec = createCodec(value.type, value.options);
|
|
207
|
+
const defaultFactory = createTypedDefaultFactory(value.type, value.options);
|
|
208
|
+
const storageKey = createStorageKey(refName, value.options.key ?? key);
|
|
209
|
+
shape[key] = defaultFactory();
|
|
210
|
+
initializers[key] = defaultFactory;
|
|
211
|
+
meta.persistSession[key] = {
|
|
212
|
+
kind: value.kind,
|
|
213
|
+
key,
|
|
214
|
+
storageKey,
|
|
215
|
+
parse: codec.parse,
|
|
216
|
+
serialize: codec.serialize,
|
|
217
|
+
getDefault: defaultFactory,
|
|
218
|
+
};
|
|
219
|
+
} else {
|
|
220
|
+
shape[key] = value;
|
|
221
|
+
initializers[key] = makeDefaultFactory(value);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return { shape, initializers, meta };
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export const resolveDerivedState = <WritableState>(
|
|
228
|
+
state: Record<string, unknown>,
|
|
229
|
+
writableKeys: Set<string>,
|
|
230
|
+
): { shape: Record<string, unknown>; meta: StateDerivedMeta } => {
|
|
231
|
+
const shape: Record<string, unknown> = {};
|
|
232
|
+
const meta = createEmptyDerivedMeta();
|
|
233
|
+
|
|
234
|
+
for (const [key, value] of Object.entries(state)) {
|
|
235
|
+
if (!isStateBuilderMarker(value))
|
|
236
|
+
throw new Error(`Derived state ${key} must be declared with search() or computed()`);
|
|
237
|
+
if (writableKeys.has(key)) throw new Error(`Derived state key conflicts with writable state: ${key}`);
|
|
238
|
+
meta.derivedKeys.add(key);
|
|
239
|
+
if (value.kind === "search") {
|
|
240
|
+
const defaultFactory = createTypedDefaultFactory(value.type, value.options);
|
|
241
|
+
shape[key] = defaultFactory();
|
|
242
|
+
meta.search[key] = {
|
|
243
|
+
kind: "search",
|
|
244
|
+
key,
|
|
245
|
+
paramKey: value.paramKey,
|
|
246
|
+
getDefault: defaultFactory,
|
|
247
|
+
parseSearch: createSearchParser(value.type, value.options, value.paramKey),
|
|
248
|
+
};
|
|
249
|
+
} else if (value.kind === "computed") {
|
|
250
|
+
const invalidDeps = value.deps.filter((dep) => !writableKeys.has(dep));
|
|
251
|
+
if (invalidDeps.length) throw new Error(`Computed ${key} has invalid deps: ${invalidDeps.join(", ")}`);
|
|
252
|
+
shape[key] = undefined;
|
|
253
|
+
meta.computed[key] = {
|
|
254
|
+
kind: "computed",
|
|
255
|
+
key,
|
|
256
|
+
deps: value.deps,
|
|
257
|
+
selector: value.selector,
|
|
258
|
+
equals: value.options.equals ?? Object.is,
|
|
259
|
+
};
|
|
260
|
+
} else throw new Error(`${value.kind} is not derived state`);
|
|
261
|
+
}
|
|
262
|
+
return { shape, meta };
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
export const makeDefaultFactory = (value: unknown): StateInitializer => {
|
|
266
|
+
if (typeof value === "function") return value as StateInitializer;
|
|
267
|
+
if (value === null || value === undefined) return () => value;
|
|
268
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return () => value;
|
|
269
|
+
if (value instanceof Date) return () => new Date(value);
|
|
270
|
+
if (Array.isArray(value)) return () => value.map((v) => makeDefaultFactory(v)());
|
|
271
|
+
if (value instanceof Map) return () => new Map(value);
|
|
272
|
+
if (value instanceof DataList) return () => new DataList(value);
|
|
273
|
+
if (typeof value === "object") {
|
|
274
|
+
if (isConstantInstance(value)) return () => new (value.constructor as new (arg: unknown) => object)(value);
|
|
275
|
+
if (!isPlainObject(value)) return () => value;
|
|
276
|
+
return () => {
|
|
277
|
+
if (typeof structuredClone === "function") {
|
|
278
|
+
try {
|
|
279
|
+
return structuredClone(value);
|
|
280
|
+
} catch {
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return Object.fromEntries(Object.entries(value).map(([key, val]) => [key, makeDefaultFactory(val)()]));
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
return () => value;
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const isConstantInstance = (value: object) => ConstantRegistry.has(value.constructor as Cls);
|
|
290
|
+
|
|
291
|
+
const isPlainObject = (value: object) => {
|
|
292
|
+
const proto = Object.getPrototypeOf(value);
|
|
293
|
+
return proto === Object.prototype || proto === null;
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const createTypedDefaultFactory = (type: any, options: { default?: any; nullable?: boolean }): StateInitializer => {
|
|
297
|
+
if (options.default !== undefined) return makeDefaultFactory(options.default);
|
|
298
|
+
if (options.nullable) return () => null;
|
|
299
|
+
const [modelRef, arrDepth] = getNonArrayModel(type);
|
|
300
|
+
if (arrDepth > 0) return () => [];
|
|
301
|
+
if (isEnum(modelRef)) return () => (modelRef as EnumInstance).values[0];
|
|
302
|
+
if (PrimitiveRegistry.has(modelRef as Cls)) {
|
|
303
|
+
const defaultValue = (modelRef as typeof PrimitiveScalar)[PRIMITIVE_DEFAULT_VALUE];
|
|
304
|
+
return makeDefaultFactory(defaultValue);
|
|
305
|
+
}
|
|
306
|
+
if (ConstantRegistry.has(modelRef as Cls)) return () => new (modelRef as Cls)();
|
|
307
|
+
throw new Error(`Invalid state type: ${String(modelRef)}`);
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
const createCodec = (type: any, options: { nullable?: boolean }) => {
|
|
311
|
+
const parse = (value: unknown) => {
|
|
312
|
+
if (options.nullable && (value === null || value === undefined)) return null;
|
|
313
|
+
return parseTypedValue(type, value, options);
|
|
314
|
+
};
|
|
315
|
+
const serialize = (value: unknown) => {
|
|
316
|
+
if (options.nullable && (value === null || value === undefined)) return null;
|
|
317
|
+
return serializeTypedValue(type, value, options);
|
|
318
|
+
};
|
|
319
|
+
return { parse, serialize };
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
const parseTypedValue = (type: any, value: any, options: { nullable?: boolean }): any => {
|
|
323
|
+
const [modelRef, arrDepth] = getNonArrayModel(type);
|
|
324
|
+
if (arrDepth > 0) {
|
|
325
|
+
if (!Array.isArray(value)) throw new Error("Expected array value");
|
|
326
|
+
return value.map((v) => parseTypedValue(modelRef, v, options));
|
|
327
|
+
}
|
|
328
|
+
if (isEnum(modelRef)) {
|
|
329
|
+
const enumRef = modelRef as EnumInstance;
|
|
330
|
+
const parsed = parseTypedValue(enumRef.type, value, options);
|
|
331
|
+
if (!enumRef.has(parsed)) throw new Error(`Invalid enum value: ${parsed}`);
|
|
332
|
+
return parsed;
|
|
333
|
+
}
|
|
334
|
+
if (PrimitiveRegistry.has(modelRef as Cls))
|
|
335
|
+
return (modelRef as typeof PrimitiveScalar)._parse(value, { optional: options.nullable });
|
|
336
|
+
if (ConstantRegistry.has(modelRef as Cls))
|
|
337
|
+
return ConstantRegistry.deserialize(modelRef as Cls, value, Boolean(options.nullable));
|
|
338
|
+
throw new Error(`Invalid state type: ${String(modelRef)}`);
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
const serializeTypedValue = (type: any, value: any, options: { nullable?: boolean }): any => {
|
|
342
|
+
const [modelRef, arrDepth] = getNonArrayModel(type);
|
|
343
|
+
if (arrDepth > 0) {
|
|
344
|
+
if (!Array.isArray(value)) throw new Error("Expected array value");
|
|
345
|
+
return value.map((v) => serializeTypedValue(modelRef, v, options));
|
|
346
|
+
}
|
|
347
|
+
if (isEnum(modelRef)) return serializeTypedValue((modelRef as EnumInstance).type, value, options);
|
|
348
|
+
if (PrimitiveRegistry.has(modelRef as Cls))
|
|
349
|
+
return (modelRef as typeof PrimitiveScalar)._serialize(value, { optional: options.nullable });
|
|
350
|
+
if (ConstantRegistry.has(modelRef as Cls))
|
|
351
|
+
return ConstantRegistry.serialize(modelRef as Cls, value, Boolean(options.nullable));
|
|
352
|
+
throw new Error(`Invalid state type: ${String(modelRef)}`);
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const createSearchParser =
|
|
356
|
+
(type: any, options: SearchOptions<any>, paramKey: string) => (searchParams: SearchParamsState) => {
|
|
357
|
+
const raw = searchParams[paramKey];
|
|
358
|
+
if (raw === undefined || raw === "") return createTypedDefaultFactory(type, options)();
|
|
359
|
+
try {
|
|
360
|
+
return parseSearchValue(type, raw, options);
|
|
361
|
+
} catch (error) {
|
|
362
|
+
warnDev(`Failed to parse search param ${paramKey}: ${error instanceof Error ? error.message : String(error)}`);
|
|
363
|
+
return createTypedDefaultFactory(type, options)();
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
const parseSearchValue = (type: any, raw: string | string[], options: SearchOptions<any>): any => {
|
|
368
|
+
const [modelRef, arrDepth] = getNonArrayModel(type);
|
|
369
|
+
if (arrDepth > 0) {
|
|
370
|
+
if (isPrimitiveOrEnum(modelRef)) {
|
|
371
|
+
const values = Array.isArray(raw) ? raw : tryParseSearchArray(raw);
|
|
372
|
+
return values.map((value) => parseSearchValue(modelRef, value, options));
|
|
373
|
+
}
|
|
374
|
+
const parsed = JSON.parse(firstSearchParam(raw) ?? "[]");
|
|
375
|
+
return parseTypedValue(type, parsed, options);
|
|
376
|
+
}
|
|
377
|
+
if (isEnum(modelRef)) return parseSearchValue((modelRef as EnumInstance).type, raw, options);
|
|
378
|
+
if (modelRef === Boolean) {
|
|
379
|
+
const value = firstSearchParam(raw);
|
|
380
|
+
if (value === "true") return true;
|
|
381
|
+
if (value === "false") return false;
|
|
382
|
+
throw new Error(`Invalid boolean search value: ${value}`);
|
|
383
|
+
}
|
|
384
|
+
if (PrimitiveRegistry.has(modelRef as Cls)) return parseTypedValue(modelRef, firstSearchParam(raw), options);
|
|
385
|
+
const parsed = JSON.parse(firstSearchParam(raw) ?? "{}");
|
|
386
|
+
return parseTypedValue(type, parsed, options);
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
const isPrimitiveOrEnum = (modelRef: any) => PrimitiveRegistry.has(modelRef as Cls) || isEnum(modelRef);
|
|
390
|
+
|
|
391
|
+
const tryParseSearchArray = (raw: string): string[] => {
|
|
392
|
+
try {
|
|
393
|
+
const parsed = JSON.parse(raw);
|
|
394
|
+
return Array.isArray(parsed) ? parsed : [raw];
|
|
395
|
+
} catch {
|
|
396
|
+
return [raw];
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
export const getSearchParam = (searchParams: SearchParamsState, key: string): string | undefined =>
|
|
401
|
+
firstSearchParam(searchParams[key]);
|
|
402
|
+
|
|
403
|
+
const firstSearchParam = (value: string | string[] | undefined): string | undefined =>
|
|
404
|
+
Array.isArray(value) ? value[0] : value;
|
|
405
|
+
|
|
406
|
+
let memorySessionKey: string | undefined;
|
|
407
|
+
const getSessionKey = () => {
|
|
408
|
+
const key = "akanjs.sessionKey";
|
|
409
|
+
if (typeof sessionStorage !== "undefined") {
|
|
410
|
+
try {
|
|
411
|
+
const stored = sessionStorage.getItem(key);
|
|
412
|
+
if (stored) return stored;
|
|
413
|
+
const next = Math.random().toString(36).slice(2);
|
|
414
|
+
sessionStorage.setItem(key, next);
|
|
415
|
+
return next;
|
|
416
|
+
} catch {
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
memorySessionKey ??= Math.random().toString(36).slice(2);
|
|
420
|
+
return memorySessionKey;
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
const createStorageKey = (refName: string, key: string) =>
|
|
424
|
+
`${getEnv().appName}.${getEnv().environment}.${getSessionKey()}.${refName}.${key}`;
|
|
425
|
+
|
|
426
|
+
const warnDev = (message: string) => {
|
|
427
|
+
if (getEnv().environment === "main") return;
|
|
428
|
+
console.warn(message);
|
|
429
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { EnumInstance, PrimitiveScalar } from "akanjs/base";
|
|
2
|
+
import type { ConstantFieldTypeInput, PlainTypeToFieldType } from "akanjs/constant";
|
|
3
|
+
|
|
4
|
+
export type StateType = "normal" | "storage" | "cookie" | "param" | "searchParam";
|
|
5
|
+
|
|
6
|
+
export interface StateProps<FieldValue = any, MapValue = any, Nullable extends boolean = false> {
|
|
7
|
+
nullable: Nullable;
|
|
8
|
+
default?: FieldValue | ((doc: { id: string }) => FieldValue);
|
|
9
|
+
enum?: EnumInstance;
|
|
10
|
+
of?: MapValue;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class StateInfo<
|
|
14
|
+
Type extends StateType = StateType,
|
|
15
|
+
Value extends ConstantFieldTypeInput = any,
|
|
16
|
+
MapValue = Value extends MapConstructor ? typeof PrimitiveScalar : never,
|
|
17
|
+
Nullable extends boolean = boolean,
|
|
18
|
+
> {
|
|
19
|
+
readonly type: Type;
|
|
20
|
+
readonly value: Value;
|
|
21
|
+
readonly option: StateProps<Value, MapValue, Nullable>;
|
|
22
|
+
constructor(type: Type, value: Value, option?: StateProps<Value, MapValue, Nullable>) {
|
|
23
|
+
this.type = type;
|
|
24
|
+
this.value = value;
|
|
25
|
+
this.option = option ?? ({} as StateProps<Value, MapValue, Nullable>);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const buildState = {
|
|
30
|
+
storage: <
|
|
31
|
+
ExplicitType,
|
|
32
|
+
Value extends ConstantFieldTypeInput = PlainTypeToFieldType<ExplicitType>,
|
|
33
|
+
MapValue = Value extends MapConstructor ? typeof PrimitiveScalar : never,
|
|
34
|
+
Nullable extends boolean = false,
|
|
35
|
+
>(
|
|
36
|
+
value: Value,
|
|
37
|
+
option?: StateProps<Value, MapValue, Nullable>,
|
|
38
|
+
) => new StateInfo<"storage", Value, MapValue, Nullable>("storage", value, option),
|
|
39
|
+
cookie: <
|
|
40
|
+
ExplicitType,
|
|
41
|
+
Value extends ConstantFieldTypeInput = PlainTypeToFieldType<ExplicitType>,
|
|
42
|
+
MapValue = Value extends MapConstructor ? typeof PrimitiveScalar : never,
|
|
43
|
+
Nullable extends boolean = false,
|
|
44
|
+
>(
|
|
45
|
+
value: Value,
|
|
46
|
+
option?: StateProps<Value, MapValue, Nullable>,
|
|
47
|
+
) => new StateInfo<"cookie", Value, MapValue, Nullable>("cookie", value, option),
|
|
48
|
+
param: <
|
|
49
|
+
ExplicitType,
|
|
50
|
+
Value extends ConstantFieldTypeInput = PlainTypeToFieldType<ExplicitType>,
|
|
51
|
+
MapValue = Value extends MapConstructor ? typeof PrimitiveScalar : never,
|
|
52
|
+
Nullable extends boolean = false,
|
|
53
|
+
>(
|
|
54
|
+
value: Value,
|
|
55
|
+
option?: StateProps<Value, MapValue, Nullable>,
|
|
56
|
+
) => new StateInfo<"param", Value, MapValue, Nullable>("param", value, option),
|
|
57
|
+
searchParam: <
|
|
58
|
+
ExplicitType,
|
|
59
|
+
Value extends ConstantFieldTypeInput = PlainTypeToFieldType<ExplicitType>,
|
|
60
|
+
MapValue = Value extends MapConstructor ? typeof PrimitiveScalar : never,
|
|
61
|
+
Nullable extends boolean = false,
|
|
62
|
+
>(
|
|
63
|
+
value: Value,
|
|
64
|
+
option?: StateProps<Value, MapValue, Nullable>,
|
|
65
|
+
) => new StateInfo<"searchParam", Value, MapValue, Nullable>("searchParam", value, option),
|
|
66
|
+
};
|
package/store/store.ts
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACTION_META,
|
|
3
|
+
type Cls,
|
|
4
|
+
type MergeAllActionTypes,
|
|
5
|
+
type MergeAllKeyOfObjects,
|
|
6
|
+
type SLICE_META,
|
|
7
|
+
STATE_DERIVED_META,
|
|
8
|
+
STATE_INIT_META,
|
|
9
|
+
STATE_META,
|
|
10
|
+
} from "akanjs/base";
|
|
11
|
+
import { applyMixins } from "akanjs/common";
|
|
12
|
+
import type { FilterInstance } from "akanjs/document";
|
|
13
|
+
import type { ClientSignal } from "akanjs/fetch";
|
|
14
|
+
import type { SerializedSlice, SliceCls } from "akanjs/signal";
|
|
15
|
+
import { type DefaultAction, makeActions, makeFormSetter } from "./action";
|
|
16
|
+
import { createDatabaseState, createSliceState, type DefaultState } from "./state";
|
|
17
|
+
import {
|
|
18
|
+
createDerivedStateBuilder,
|
|
19
|
+
createEmptyDerivedMeta,
|
|
20
|
+
createStateInitializerMap,
|
|
21
|
+
createWritableStateBuilder,
|
|
22
|
+
type DerivedStateBuilder,
|
|
23
|
+
type DerivedStateOf,
|
|
24
|
+
mergeDerivedMeta,
|
|
25
|
+
resolveDerivedState,
|
|
26
|
+
resolveWritableState,
|
|
27
|
+
type StateDerivedMeta,
|
|
28
|
+
type StateInitializerMap,
|
|
29
|
+
type WritableStateBuilder,
|
|
30
|
+
type WritableStateOf,
|
|
31
|
+
} from "./stateBuilder";
|
|
32
|
+
import type { InternalSlice, SetGet, SetGetWritable } from "./types";
|
|
33
|
+
|
|
34
|
+
export type StoreCls<
|
|
35
|
+
RefName extends string = string,
|
|
36
|
+
WritableState = any,
|
|
37
|
+
Action = unknown,
|
|
38
|
+
SlceCls extends SliceCls = any,
|
|
39
|
+
DerivedState = unknown,
|
|
40
|
+
State = WritableState & DerivedState,
|
|
41
|
+
_Input = SlceCls["srv"]["cnst"]["_Input"],
|
|
42
|
+
_Full = SlceCls["srv"]["cnst"]["_Full"],
|
|
43
|
+
_Light extends { id: string } = SlceCls["srv"]["cnst"]["_Light"],
|
|
44
|
+
_Insight = SlceCls["srv"]["cnst"]["_Insight"],
|
|
45
|
+
_Filter extends FilterInstance = SlceCls["srv"]["db"]["_Filter"],
|
|
46
|
+
_CapitalizedRefName extends string = Capitalize<RefName>,
|
|
47
|
+
_Default = SlceCls["srv"]["cnst"]["_Default"],
|
|
48
|
+
_Sort = SlceCls["srv"]["db"]["_Sort"],
|
|
49
|
+
> = Cls<
|
|
50
|
+
SetGetWritable<WritableState, State> &
|
|
51
|
+
Action & {
|
|
52
|
+
slice: {
|
|
53
|
+
[Suffix in keyof SlceCls[typeof SLICE_META] as Suffix extends string
|
|
54
|
+
? `${RefName}${Capitalize<Suffix>}`
|
|
55
|
+
: never]: InternalSlice<
|
|
56
|
+
SlceCls[typeof SLICE_META][Suffix],
|
|
57
|
+
RefName,
|
|
58
|
+
Suffix & string,
|
|
59
|
+
_Input,
|
|
60
|
+
_Full,
|
|
61
|
+
_Light,
|
|
62
|
+
_Insight,
|
|
63
|
+
_Filter,
|
|
64
|
+
_CapitalizedRefName,
|
|
65
|
+
_Default,
|
|
66
|
+
_Sort
|
|
67
|
+
>;
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
readonly type: "module";
|
|
72
|
+
readonly refName: RefName;
|
|
73
|
+
[STATE_META]: State;
|
|
74
|
+
[STATE_INIT_META]: StateInitializerMap;
|
|
75
|
+
[STATE_DERIVED_META]: StateDerivedMeta;
|
|
76
|
+
[ACTION_META]: { [key: string]: (...args: any[]) => any };
|
|
77
|
+
slice: { [key: string]: SerializedSlice };
|
|
78
|
+
_slice: SlceCls[typeof SLICE_META];
|
|
79
|
+
}
|
|
80
|
+
>;
|
|
81
|
+
|
|
82
|
+
export type ModelStore<
|
|
83
|
+
Sig extends ClientSignal<any, any, any> | string,
|
|
84
|
+
WritableState,
|
|
85
|
+
Action,
|
|
86
|
+
DerivedState = unknown,
|
|
87
|
+
> = Sig extends string
|
|
88
|
+
? StoreCls<Sig, WritableState, Action, any, DerivedState>
|
|
89
|
+
: Sig extends ClientSignal<any, any, any>
|
|
90
|
+
? StoreCls<
|
|
91
|
+
Sig["refName"],
|
|
92
|
+
WritableState & DefaultState<Sig["_slice"]>,
|
|
93
|
+
Action & DefaultAction<Sig["_slice"]>,
|
|
94
|
+
Sig["_slice"],
|
|
95
|
+
DerivedState
|
|
96
|
+
>
|
|
97
|
+
: never;
|
|
98
|
+
|
|
99
|
+
export type StoreReturn<
|
|
100
|
+
Sig extends ClientSignal<any, any, any> | string,
|
|
101
|
+
WritableState,
|
|
102
|
+
LibStores extends StoreCls[], // TODO: Change Type for LibStores' state and action
|
|
103
|
+
DerivedState = unknown,
|
|
104
|
+
_LibState = MergeAllKeyOfObjects<LibStores, typeof STATE_META>,
|
|
105
|
+
_LibAction = MergeAllActionTypes<LibStores, keyof SetGet | "slice">,
|
|
106
|
+
> = ModelStore<Sig, WritableState & _LibState, _LibAction, DerivedState>;
|
|
107
|
+
|
|
108
|
+
type StateFactory<State> = (builder: WritableStateBuilder) => State;
|
|
109
|
+
type DerivedStateFactory<WritableState, DerivedState> = (builder: DerivedStateBuilder<WritableState>) => DerivedState;
|
|
110
|
+
|
|
111
|
+
export function store<Sig extends ClientSignal<any, any, any> | string, State, LibStores extends StoreCls[]>(
|
|
112
|
+
sigRefOrRefName: Sig,
|
|
113
|
+
state: StateFactory<State>,
|
|
114
|
+
...libStores: LibStores
|
|
115
|
+
): StoreReturn<Sig, WritableStateOf<State>, LibStores>;
|
|
116
|
+
export function store<
|
|
117
|
+
Sig extends ClientSignal<any, any, any> | string,
|
|
118
|
+
State,
|
|
119
|
+
DerivedState,
|
|
120
|
+
LibStores extends StoreCls[],
|
|
121
|
+
>(
|
|
122
|
+
sigRefOrRefName: Sig,
|
|
123
|
+
state: StateFactory<State>,
|
|
124
|
+
derivedState: DerivedStateFactory<WritableStateOf<State>, DerivedState>,
|
|
125
|
+
...libStores: LibStores
|
|
126
|
+
): StoreReturn<Sig, WritableStateOf<State>, LibStores, DerivedStateOf<DerivedState>>;
|
|
127
|
+
export function store<Sig extends ClientSignal<any, any, any> | string, State>(
|
|
128
|
+
sigRefOrRefName: Sig,
|
|
129
|
+
stateFactory: StateFactory<State>,
|
|
130
|
+
...args: any[]
|
|
131
|
+
): any {
|
|
132
|
+
const refName = typeof sigRefOrRefName === "string" ? sigRefOrRefName : sigRefOrRefName.refName;
|
|
133
|
+
const signal: ClientSignal<any, any, any> | null = typeof sigRefOrRefName === "string" ? null : sigRefOrRefName;
|
|
134
|
+
if (typeof stateFactory !== "function")
|
|
135
|
+
throw new Error("store() now requires a state factory: store(sig, ({ persist, session }) => ({ ... }))");
|
|
136
|
+
const [derivedStateFactory, libStores] =
|
|
137
|
+
args.length && typeof args[0] === "function" && !isStoreCls(args[0]) ? [args[0], args.slice(1)] : [null, args];
|
|
138
|
+
const storeCls = class Store {
|
|
139
|
+
static refName = refName;
|
|
140
|
+
static [STATE_META] = {};
|
|
141
|
+
static [STATE_INIT_META] = {};
|
|
142
|
+
static [STATE_DERIVED_META] = createEmptyDerivedMeta();
|
|
143
|
+
static [ACTION_META] = {};
|
|
144
|
+
static slice = {};
|
|
145
|
+
} as StoreCls;
|
|
146
|
+
const writableStateRaw = stateFactory(createWritableStateBuilder());
|
|
147
|
+
const writable = resolveWritableState(refName, writableStateRaw as Record<string, any>);
|
|
148
|
+
Object.assign(storeCls[STATE_META], ...libStores.map((libStore: StoreCls) => libStore[STATE_META]), writable.shape);
|
|
149
|
+
Object.assign(
|
|
150
|
+
storeCls[STATE_INIT_META],
|
|
151
|
+
...libStores.map(
|
|
152
|
+
(libStore: StoreCls) => libStore[STATE_INIT_META] ?? createStateInitializerMap(libStore[STATE_META]),
|
|
153
|
+
),
|
|
154
|
+
writable.initializers,
|
|
155
|
+
);
|
|
156
|
+
storeCls[STATE_DERIVED_META] = mergeDerivedMeta(
|
|
157
|
+
...libStores.map((libStore: StoreCls) => libStore[STATE_DERIVED_META]),
|
|
158
|
+
writable.meta,
|
|
159
|
+
);
|
|
160
|
+
Object.assign(storeCls[ACTION_META], ...libStores.map((libStore) => libStore[ACTION_META]));
|
|
161
|
+
applyMixins(storeCls, libStores);
|
|
162
|
+
if (signal) {
|
|
163
|
+
const signalState = {
|
|
164
|
+
...createDatabaseState(refName),
|
|
165
|
+
...createSliceState(refName, signal.serializedSignal.slice ?? {}),
|
|
166
|
+
};
|
|
167
|
+
Object.assign(storeCls[STATE_META], signalState);
|
|
168
|
+
Object.assign(storeCls[STATE_INIT_META], createStateInitializerMap(signalState));
|
|
169
|
+
const actions = {
|
|
170
|
+
...makeFormSetter(refName, signal.fetch),
|
|
171
|
+
...makeActions(refName, signal.serializedSignal.slice ?? {}, signal.fetch),
|
|
172
|
+
};
|
|
173
|
+
Object.assign(storeCls.prototype, actions);
|
|
174
|
+
Object.assign(storeCls[ACTION_META], actions);
|
|
175
|
+
Object.assign(storeCls.slice, signal.serializedSignal.slice ?? {});
|
|
176
|
+
}
|
|
177
|
+
if (derivedStateFactory) {
|
|
178
|
+
const writableKeys = new Set(Object.keys(storeCls[STATE_META]));
|
|
179
|
+
const derivedState = derivedStateFactory(createDerivedStateBuilder());
|
|
180
|
+
const derived = resolveDerivedState(derivedState, writableKeys);
|
|
181
|
+
Object.assign(storeCls[STATE_META], derived.shape);
|
|
182
|
+
storeCls[STATE_DERIVED_META] = mergeDerivedMeta(storeCls[STATE_DERIVED_META], derived.meta);
|
|
183
|
+
}
|
|
184
|
+
return storeCls as any;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const isStoreCls = (value: unknown): value is StoreCls =>
|
|
188
|
+
Boolean(
|
|
189
|
+
value &&
|
|
190
|
+
typeof value === "function" &&
|
|
191
|
+
(value as StoreCls)[STATE_META] &&
|
|
192
|
+
(value as StoreCls)[ACTION_META] &&
|
|
193
|
+
"refName" in (value as StoreCls),
|
|
194
|
+
);
|