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,585 @@
|
|
|
1
|
+
# Model Store Implementation Guide
|
|
2
|
+
|
|
3
|
+
## Purpose and Role of model.store.ts
|
|
4
|
+
|
|
5
|
+
The `model.store.ts` file is a crucial component in the Akan.js framework that serves as the state management layer connecting your UI components with GraphQL operations. Built on Zustand, model stores provide:
|
|
6
|
+
|
|
7
|
+
1. **Centralized State Management**: Single source of truth for model data
|
|
8
|
+
2. **GraphQL Integration**: Automatic CRUD operations with backend services
|
|
9
|
+
3. **Form Handling**: Comprehensive form state, validation, and submission
|
|
10
|
+
4. **Reactive UI Updates**: Optimized re-rendering through selectors
|
|
11
|
+
5. **Business Logic**: Centralized place for domain-specific operations
|
|
12
|
+
6. **Sliced Data Access**: Contextual data lists with pagination, filtering, and sorting
|
|
13
|
+
|
|
14
|
+
## Store Architecture Overview
|
|
15
|
+
|
|
16
|
+
Model stores follow a consistent architecture pattern:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
20
|
+
│ model.store.ts │ ←── │ fetch.ts │ ←─ │ model.signal.ts│
|
|
21
|
+
│ (Zustand) │ │ (GraphQL API) │ │ (Backend API) │
|
|
22
|
+
└────────┬────────┘ └─────────────────┘ └─────────────────┘
|
|
23
|
+
│
|
|
24
|
+
▼
|
|
25
|
+
┌─────────────────┐ ┌─────────────────┐
|
|
26
|
+
│ st.ts │ ──→ │ Components │
|
|
27
|
+
│(Store Registry) │ │ (React/UI) │
|
|
28
|
+
└─────────────────┘ └─────────────────┘
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Basic Store Implementation
|
|
32
|
+
|
|
33
|
+
### Store Structure
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { stateOf, Store } from "akanjs/store";
|
|
37
|
+
import * as cnst from "../cnst";
|
|
38
|
+
import { fetch } from "../useServer";
|
|
39
|
+
|
|
40
|
+
export class ProductStore extends stateOf(fetch.productGql, {
|
|
41
|
+
// Custom state properties
|
|
42
|
+
featuredProducts: [] as cnst.LightProduct[],
|
|
43
|
+
viewMode: "grid" as "grid" | "list",
|
|
44
|
+
}) {
|
|
45
|
+
// Custom actions
|
|
46
|
+
async featureProduct(id: string) {
|
|
47
|
+
const product = await fetch.featureProduct(id);
|
|
48
|
+
this.set({
|
|
49
|
+
featuredProducts: [...this.get().featuredProducts, product],
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Core Components
|
|
56
|
+
|
|
57
|
+
1. **`@Store` Decorator**: Registers the store class with metadata
|
|
58
|
+
2. **`stateOf` Function**: Creates the base store with generated state and actions
|
|
59
|
+
3. **Custom State**: Additional state properties specific to your model
|
|
60
|
+
4. **Custom Actions**: Business logic methods for model operations
|
|
61
|
+
|
|
62
|
+
## State Management
|
|
63
|
+
|
|
64
|
+
### Base State (Automatically Generated)
|
|
65
|
+
|
|
66
|
+
Each store automatically creates the following state properties:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// Standard state properties
|
|
70
|
+
{
|
|
71
|
+
model: null, // Current active model instance
|
|
72
|
+
modelList: [], // Main list of models
|
|
73
|
+
modelForm: {}, // Form state for create/update
|
|
74
|
+
modelLoading: false, // Loading state for current model
|
|
75
|
+
modelListLoading: false, // Loading state for model list
|
|
76
|
+
modelFormLoading: false, // Loading state for form submission
|
|
77
|
+
modelTotal: 0, // Total count of models
|
|
78
|
+
modelPage: 1, // Current page number
|
|
79
|
+
modelLimit: 20, // Items per page
|
|
80
|
+
modelSort: "createdAt", // Current sort field
|
|
81
|
+
modelQuery: {}, // Query arguments for filtering
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Custom State
|
|
86
|
+
|
|
87
|
+
Add custom state properties in the second parameter of `stateOf`:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
extends stateOf(fetch.productGql, {
|
|
91
|
+
// UI state
|
|
92
|
+
productViewMode: "grid" as "grid" | "list",
|
|
93
|
+
selectedProductIds: [] as string[],
|
|
94
|
+
|
|
95
|
+
// Business state
|
|
96
|
+
featuredProducts: [] as cnst.LightProduct[],
|
|
97
|
+
productAnalytics: null as ProductAnalytics | null,
|
|
98
|
+
|
|
99
|
+
// Complex state
|
|
100
|
+
productCategoryMap: new Map<string, cnst.ProductCategory[]>(),
|
|
101
|
+
})
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Accessing State
|
|
105
|
+
|
|
106
|
+
In your store actions, use these methods to access state:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// Get the entire state
|
|
110
|
+
const state = this.get();
|
|
111
|
+
|
|
112
|
+
// Get specific properties
|
|
113
|
+
const { productList, selectedProductIds } = this.pick("productList", "selectedProductIds");
|
|
114
|
+
|
|
115
|
+
// Set state (triggers UI updates)
|
|
116
|
+
this.set({ productViewMode: "list" });
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Store Actions
|
|
120
|
+
|
|
121
|
+
### Core Actions (Automatically Generated)
|
|
122
|
+
|
|
123
|
+
Each store comes with standard CRUD operations:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// Core model actions
|
|
127
|
+
st.do.createModel(); // Create a new model
|
|
128
|
+
st.do.updateModel(); // Update an existing model
|
|
129
|
+
st.do.removeModel(); // Delete a model
|
|
130
|
+
st.do.getModel(); // Get a single model by ID
|
|
131
|
+
st.do.listModel(); // Get a list of models
|
|
132
|
+
|
|
133
|
+
// Initialization
|
|
134
|
+
st.do.initModel(); // Initialize the store
|
|
135
|
+
st.do.refreshModel(); // Refresh data
|
|
136
|
+
|
|
137
|
+
// Pagination/Sorting
|
|
138
|
+
st.do.setPageOfModel(); // Change page number
|
|
139
|
+
st.do.setLimitOfModel(); // Change items per page
|
|
140
|
+
st.do.setSortOfModel(); // Change sort field
|
|
141
|
+
st.do.setQueryArgsOfModel(); // Set filter query arguments
|
|
142
|
+
|
|
143
|
+
// Form management
|
|
144
|
+
st.do.setFieldOnModel(); // Set a form field
|
|
145
|
+
st.do.addFieldOnModel(); // Add to an array field
|
|
146
|
+
st.do.submitModel(); // Submit the form
|
|
147
|
+
st.do.checkModelSubmitable(); // Check form validity
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Custom Actions
|
|
151
|
+
|
|
152
|
+
Define custom business logic by adding methods to your store class:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// Basic custom action
|
|
156
|
+
async archiveProduct(id: string) {
|
|
157
|
+
const product = await fetch.archiveProduct(id);
|
|
158
|
+
this.setProduct(product);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Action with loading state
|
|
162
|
+
async generateProductReport(id: string) {
|
|
163
|
+
this.set({ productReportLoading: true });
|
|
164
|
+
try {
|
|
165
|
+
const report = await fetch.generateProductReport(id);
|
|
166
|
+
this.set({ productReport: report });
|
|
167
|
+
} finally {
|
|
168
|
+
this.set({ productReportLoading: false });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Action with notification
|
|
173
|
+
@Toast({ root: "product" })
|
|
174
|
+
async bulkUpdatePrices(percentage: number) {
|
|
175
|
+
const { selectedProductIds } = this.pick("selectedProductIds");
|
|
176
|
+
await fetch.updatePrices(selectedProductIds, percentage);
|
|
177
|
+
this.refreshProductList();
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Using Slices for List Operations
|
|
182
|
+
|
|
183
|
+
Slices are specialized query operations for retrieving contextual lists of data.
|
|
184
|
+
|
|
185
|
+
### Slice Definition
|
|
186
|
+
|
|
187
|
+
Slices are defined in your GraphQL fetch operations:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
// In fetch.ts
|
|
191
|
+
export const productGql = {
|
|
192
|
+
// Basic operations
|
|
193
|
+
product: (id: string) => [id],
|
|
194
|
+
productList: () => [],
|
|
195
|
+
|
|
196
|
+
// Slice operations (contextual lists)
|
|
197
|
+
productListByCategory: (categoryId: string) => [categoryId],
|
|
198
|
+
productListByVendor: (vendorId: string) => [vendorId],
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Slice State
|
|
203
|
+
|
|
204
|
+
Each slice automatically creates these state properties:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
{
|
|
208
|
+
productListByCategory: [], // Slice data
|
|
209
|
+
productListByCategoryLoading: false, // Loading state
|
|
210
|
+
productListByCategoryTotal: 0, // Total count
|
|
211
|
+
productListByCategoryPage: 1, // Current page
|
|
212
|
+
productListByCategoryLimit: 20, // Items per page
|
|
213
|
+
productListByCategorySort: "createdAt", // Sort field
|
|
214
|
+
productListByCategoryQuery: {}, // Query args
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Using Slice State in Components
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
const ProductCategoryPage = ({ categoryId }) => {
|
|
222
|
+
// Initialize slice when component mounts
|
|
223
|
+
useEffect(() => {
|
|
224
|
+
st.do.initProductListByCategory(categoryId);
|
|
225
|
+
}, [categoryId]);
|
|
226
|
+
|
|
227
|
+
// Access slice state
|
|
228
|
+
const products = st.use.productListByCategory();
|
|
229
|
+
const loading = st.use.productListByCategoryLoading();
|
|
230
|
+
const total = st.use.productListByCategoryTotal();
|
|
231
|
+
|
|
232
|
+
// Pagination control
|
|
233
|
+
const handlePageChange = (page: number) => {
|
|
234
|
+
st.do.setPageOfProductListByCategory(page);
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
// Rendering
|
|
238
|
+
return (
|
|
239
|
+
<div>
|
|
240
|
+
{loading ? (
|
|
241
|
+
<Spinner />
|
|
242
|
+
) : (
|
|
243
|
+
<ProductGrid products={products} />
|
|
244
|
+
)}
|
|
245
|
+
|
|
246
|
+
<Pagination
|
|
247
|
+
total={total}
|
|
248
|
+
onChange={handlePageChange}
|
|
249
|
+
/>
|
|
250
|
+
</div>
|
|
251
|
+
);
|
|
252
|
+
};
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Slice Actions
|
|
256
|
+
|
|
257
|
+
Each slice gets these automatically generated actions:
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
// Initialize slice
|
|
261
|
+
st.do.initProductListByCategory(categoryId);
|
|
262
|
+
|
|
263
|
+
// Refresh slice data
|
|
264
|
+
st.do.refreshProductListByCategory(categoryId);
|
|
265
|
+
|
|
266
|
+
// Pagination/Sorting
|
|
267
|
+
st.do.setPageOfProductListByCategory(2);
|
|
268
|
+
st.do.setLimitOfProductListByCategory(50);
|
|
269
|
+
st.do.setSortOfProductListByCategory("price");
|
|
270
|
+
|
|
271
|
+
// Filtering
|
|
272
|
+
st.do.setQueryArgsOfProductListByCategory({
|
|
273
|
+
minPrice: 100,
|
|
274
|
+
inStock: true,
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Form Management
|
|
279
|
+
|
|
280
|
+
Stores provide comprehensive form handling capabilities.
|
|
281
|
+
|
|
282
|
+
### Form State Handling
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
// Form initialization
|
|
286
|
+
useEffect(() => {
|
|
287
|
+
if (productId) {
|
|
288
|
+
st.do.getProduct(productId);
|
|
289
|
+
} else {
|
|
290
|
+
st.do.initProduct(); // Create empty form
|
|
291
|
+
}
|
|
292
|
+
}, [productId]);
|
|
293
|
+
|
|
294
|
+
// Access form state
|
|
295
|
+
const productForm = st.use.productForm();
|
|
296
|
+
const loading = st.use.productFormLoading();
|
|
297
|
+
const submitable = st.use.productSubmitable();
|
|
298
|
+
|
|
299
|
+
// Form component
|
|
300
|
+
return (
|
|
301
|
+
<Form onSubmit={st.do.submitProduct}>
|
|
302
|
+
<Input
|
|
303
|
+
value={productForm.name}
|
|
304
|
+
onChange={(value) => st.do.setNameOnProduct(value)}
|
|
305
|
+
/>
|
|
306
|
+
|
|
307
|
+
<Select
|
|
308
|
+
value={productForm.category}
|
|
309
|
+
onChange={(value) => st.do.setCategoryOnProduct(value)}
|
|
310
|
+
options={categories}
|
|
311
|
+
/>
|
|
312
|
+
|
|
313
|
+
<FileUpload
|
|
314
|
+
files={productForm.images || []}
|
|
315
|
+
onAdd={(files) => st.do.addImagesOnProduct(files)}
|
|
316
|
+
onRemove={(index) => st.do.removeImagesOnProduct(index)}
|
|
317
|
+
/>
|
|
318
|
+
|
|
319
|
+
<Button
|
|
320
|
+
type="submit"
|
|
321
|
+
disabled={!submitable || loading}
|
|
322
|
+
>
|
|
323
|
+
Save Product
|
|
324
|
+
</Button>
|
|
325
|
+
</Form>
|
|
326
|
+
);
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Form Submission
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
// Basic submission
|
|
333
|
+
st.do.submitProduct();
|
|
334
|
+
|
|
335
|
+
// With callbacks
|
|
336
|
+
st.do.submitProduct({
|
|
337
|
+
onSuccess: (product) => {
|
|
338
|
+
router.push(`/products/${product.id}`);
|
|
339
|
+
},
|
|
340
|
+
onError: (error) => {
|
|
341
|
+
console.error("Failed to save product:", error);
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
// With validation
|
|
346
|
+
useEffect(() => {
|
|
347
|
+
st.do.checkProductSubmitable();
|
|
348
|
+
}, [st.sel((s) => s.productForm)]);
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## Advanced Store Patterns
|
|
352
|
+
|
|
353
|
+
### Store Composition
|
|
354
|
+
|
|
355
|
+
For complex applications, compose multiple stores:
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
// In store.ts
|
|
359
|
+
export class RootStore extends MixStore(ProductStore, CategoryStore, VendorStore, CartStore) {}
|
|
360
|
+
|
|
361
|
+
export const storeRoot = rootStoreOf(RootStore);
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Cross-Store Operations
|
|
365
|
+
|
|
366
|
+
Access other stores from within a store:
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
async addToCart(productId: string, quantity: number) {
|
|
370
|
+
const product = await fetch.getProduct(productId);
|
|
371
|
+
|
|
372
|
+
// Access another store
|
|
373
|
+
(this as unknown as RootStore).do.addItemToCart({
|
|
374
|
+
productId: product.id,
|
|
375
|
+
name: product.name,
|
|
376
|
+
price: product.price,
|
|
377
|
+
quantity
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Optimistic Updates
|
|
383
|
+
|
|
384
|
+
Update UI before API operations complete:
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
async toggleProductFavorite(id: string) {
|
|
388
|
+
const { productList } = this.pick("productList");
|
|
389
|
+
|
|
390
|
+
// Find product in list
|
|
391
|
+
const index = productList.findIndex(p => p.id === id);
|
|
392
|
+
if (index === -1) return;
|
|
393
|
+
|
|
394
|
+
// Clone the list
|
|
395
|
+
const newList = [...productList];
|
|
396
|
+
|
|
397
|
+
// Optimistically update
|
|
398
|
+
newList[index] = {
|
|
399
|
+
...newList[index],
|
|
400
|
+
isFavorite: !newList[index].isFavorite
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
// Update UI immediately
|
|
404
|
+
this.set({ productList: newList });
|
|
405
|
+
|
|
406
|
+
// Perform actual API call
|
|
407
|
+
try {
|
|
408
|
+
await fetch.toggleProductFavorite(id);
|
|
409
|
+
} catch (error) {
|
|
410
|
+
// Revert on error
|
|
411
|
+
this.refreshProductList();
|
|
412
|
+
throw error;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Real-time Updates
|
|
418
|
+
|
|
419
|
+
Connect stores with GraphQL subscriptions:
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
initProductChat(productId: string) {
|
|
423
|
+
this.set({ productChatLoading: true });
|
|
424
|
+
|
|
425
|
+
// Set up subscription
|
|
426
|
+
fetch.subscribeToProductChat(productId, (message) => {
|
|
427
|
+
const { productChatMessages } = this.pick("productChatMessages");
|
|
428
|
+
this.set({
|
|
429
|
+
productChatMessages: [...productChatMessages, message]
|
|
430
|
+
});
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
this.set({ productChatLoading: false });
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
## Best Practices
|
|
438
|
+
|
|
439
|
+
1. **Naming Conventions**:
|
|
440
|
+
- Use `modelList{Context}` for slice names (e.g., `productListByCategory`)
|
|
441
|
+
- Use camelCase for state properties
|
|
442
|
+
- Use action verbs for method names
|
|
443
|
+
|
|
444
|
+
2. **State Management**:
|
|
445
|
+
- Keep UI state (loading, selected items) in the store
|
|
446
|
+
- Use `this.pick()` for accessing multiple properties
|
|
447
|
+
- Create new references for objects/arrays when updating
|
|
448
|
+
|
|
449
|
+
3. **Performance**:
|
|
450
|
+
- Use selective subscriptions in components:
|
|
451
|
+
```typescript
|
|
452
|
+
// Subscribe to specific state properties
|
|
453
|
+
const name = st.use.product((s) => s.name);
|
|
454
|
+
```
|
|
455
|
+
- Initialize slices only when needed
|
|
456
|
+
- Clean up subscriptions when components unmount
|
|
457
|
+
|
|
458
|
+
4. **Error Handling**:
|
|
459
|
+
- Use the `@Toast` decorator for user notifications
|
|
460
|
+
- Always reset loading states in finally blocks
|
|
461
|
+
- Implement retry logic for critical operations
|
|
462
|
+
|
|
463
|
+
5. **Testing**:
|
|
464
|
+
- Mock stores with initial state for unit tests
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
const testStore = makeStore(
|
|
468
|
+
{
|
|
469
|
+
productList: [mockProduct1, mockProduct2],
|
|
470
|
+
},
|
|
471
|
+
ProductStore
|
|
472
|
+
);
|
|
473
|
+
|
|
474
|
+
await testStore.do.submitProduct();
|
|
475
|
+
expect(testStore.get().product).toEqual(expectedProduct);
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
## Complete Example
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
import { stateOf, Store, Toast } from "akanjs/store";
|
|
482
|
+
import * as cnst from "../cnst";
|
|
483
|
+
import { fetch } from "../useServer";
|
|
484
|
+
import { msg } from "../msg";
|
|
485
|
+
|
|
486
|
+
export class ProductStore extends stateOf(fetch.productGql, {
|
|
487
|
+
// UI State
|
|
488
|
+
productViewMode: "grid" as "grid" | "list",
|
|
489
|
+
selectedProductIds: [] as string[],
|
|
490
|
+
productFilterDrawerOpen: false,
|
|
491
|
+
|
|
492
|
+
// Business State
|
|
493
|
+
featuredProducts: [] as cnst.LightProduct[],
|
|
494
|
+
relatedProductMap: new Map<string, cnst.LightProduct[]>(),
|
|
495
|
+
|
|
496
|
+
// Reports
|
|
497
|
+
productAnalytics: null as ProductAnalytics | null,
|
|
498
|
+
productReportLoading: false,
|
|
499
|
+
}) {
|
|
500
|
+
// Selection Management
|
|
501
|
+
selectProduct(id: string) {
|
|
502
|
+
const { selectedProductIds } = this.pick("selectedProductIds");
|
|
503
|
+
this.set({
|
|
504
|
+
selectedProductIds: [...selectedProductIds, id],
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
deselectProduct(id: string) {
|
|
509
|
+
const { selectedProductIds } = this.pick("selectedProductIds");
|
|
510
|
+
this.set({
|
|
511
|
+
selectedProductIds: selectedProductIds.filter((pid) => pid !== id),
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
clearSelectedProducts() {
|
|
516
|
+
this.set({ selectedProductIds: [] });
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Business Operations
|
|
520
|
+
@Toast({ root: "product" })
|
|
521
|
+
async featureProduct(id: string) {
|
|
522
|
+
const product = await fetch.featureProduct(id);
|
|
523
|
+
const { featuredProducts } = this.pick("featuredProducts");
|
|
524
|
+
|
|
525
|
+
this.set({
|
|
526
|
+
featuredProducts: [...featuredProducts, product],
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
@Toast({ root: "product" })
|
|
531
|
+
async bulkUpdatePrices(percentage: number) {
|
|
532
|
+
const { selectedProductIds } = this.pick("selectedProductIds");
|
|
533
|
+
|
|
534
|
+
if (selectedProductIds.length === 0) {
|
|
535
|
+
msg.error("product.noProductsSelectedError");
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
await fetch.updatePrices(selectedProductIds, percentage);
|
|
540
|
+
this.refreshProductList();
|
|
541
|
+
this.clearSelectedProducts();
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Analytics
|
|
545
|
+
async loadProductAnalytics(id: string) {
|
|
546
|
+
this.set({ productReportLoading: true });
|
|
547
|
+
|
|
548
|
+
try {
|
|
549
|
+
const analytics = await fetch.getProductAnalytics(id);
|
|
550
|
+
this.set({ productAnalytics: analytics });
|
|
551
|
+
} catch (error) {
|
|
552
|
+
msg.error("product.analyticsLoadError");
|
|
553
|
+
this.set({ productAnalytics: null });
|
|
554
|
+
} finally {
|
|
555
|
+
this.set({ productReportLoading: false });
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Related Products
|
|
560
|
+
async loadRelatedProducts(id: string) {
|
|
561
|
+
const { relatedProductMap } = this.pick("relatedProductMap");
|
|
562
|
+
|
|
563
|
+
// Check cache
|
|
564
|
+
if (relatedProductMap.has(id)) return;
|
|
565
|
+
|
|
566
|
+
const relatedProducts = await fetch.getRelatedProducts(id);
|
|
567
|
+
|
|
568
|
+
// Update map immutably
|
|
569
|
+
const newMap = new Map(relatedProductMap);
|
|
570
|
+
newMap.set(id, relatedProducts);
|
|
571
|
+
|
|
572
|
+
this.set({ relatedProductMap: newMap });
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
## File Structure Convention
|
|
578
|
+
|
|
579
|
+
Store files should follow this pattern:
|
|
580
|
+
`{apps,libs}/*/lib/{feature}/{feature}.store.ts`
|
|
581
|
+
|
|
582
|
+
Examples:
|
|
583
|
+
|
|
584
|
+
- `apps/commerce/lib/products/product.store.ts`
|
|
585
|
+
- `libs/shared/lib/auth/auth.store.ts`
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Model Template",
|
|
3
|
+
"description": "How to create and implement Model.Template.ts files in Akan.js",
|
|
4
|
+
"scans": [
|
|
5
|
+
{
|
|
6
|
+
"type": "example",
|
|
7
|
+
"description": "Model Template examples",
|
|
8
|
+
"path": "{apps,libs}/*/lib/*/*.Template.ts{,x}",
|
|
9
|
+
"sample": 5
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"type": "usage",
|
|
13
|
+
"description": "Model Template usage in pages",
|
|
14
|
+
"path": "apps/*/page/**/_index.tsx",
|
|
15
|
+
"filterText": ".Template.",
|
|
16
|
+
"sample": 3
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"type": "usage",
|
|
20
|
+
"description": "Model Template usage in Utils",
|
|
21
|
+
"path": "{apps,libs}/*/lib/*/*.Util.tsx",
|
|
22
|
+
"filterText": ".Template.",
|
|
23
|
+
"sample": 3
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"type": "usage",
|
|
27
|
+
"description": "Model Template usage in Zones",
|
|
28
|
+
"path": "{apps,libs}/*/lib/*/*.Zone.tsx",
|
|
29
|
+
"filterText": ".Template.",
|
|
30
|
+
"sample": 3
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "reference",
|
|
34
|
+
"description": "Form Field components",
|
|
35
|
+
"path": "libs/shared/ui/Field.tsx",
|
|
36
|
+
"sample": 5
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"type": "reference",
|
|
40
|
+
"description": "Form validation examples",
|
|
41
|
+
"path": "{apps,libs}/*/lib/**/*.Template.tsx",
|
|
42
|
+
"filterText": "validate",
|
|
43
|
+
"sample": 3
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"type": "reference",
|
|
47
|
+
"description": "Store integration examples",
|
|
48
|
+
"path": "{apps,libs}/*/lib/**/*.store.ts",
|
|
49
|
+
"filterText": "Form",
|
|
50
|
+
"sample": 3
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"type": "reference",
|
|
54
|
+
"description": "Internationalization with usePage",
|
|
55
|
+
"path": "{apps,libs}/*/lib/**/usePage.{ts,tsx}",
|
|
56
|
+
"sample": 1
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"type": "reference",
|
|
60
|
+
"description": "Integration with Model.constant.ts",
|
|
61
|
+
"path": "{apps,libs}/*/lib/**/*.constant.ts",
|
|
62
|
+
"filterText": "@Model.Input",
|
|
63
|
+
"sample": 3
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"update": {
|
|
67
|
+
"filePath": "./modelTemplate.instruction.md",
|
|
68
|
+
"contents": [
|
|
69
|
+
"Purpose and role of Model.Template.tsx files",
|
|
70
|
+
"File location and naming conventions",
|
|
71
|
+
"Basic structure and component patterns",
|
|
72
|
+
"Integration with store state management",
|
|
73
|
+
"Field types and form components",
|
|
74
|
+
"Form validation approaches",
|
|
75
|
+
"Internationalization with usePage",
|
|
76
|
+
"Form layout patterns and best practices",
|
|
77
|
+
"Using templates in pages, utilities, and zones",
|
|
78
|
+
"State management and lifecycle methods",
|
|
79
|
+
"Performance optimization techniques",
|
|
80
|
+
"Accessibility considerations",
|
|
81
|
+
"Common patterns and reusable components",
|
|
82
|
+
"Form state integration with database models",
|
|
83
|
+
"Troubleshooting common issues",
|
|
84
|
+
"Integration with API calls and form submission"
|
|
85
|
+
],
|
|
86
|
+
"rules": [
|
|
87
|
+
"Model.Template.tsx is a client component, so it should include 'use client' directive",
|
|
88
|
+
"Model.Template.tsx components should accept an optional id parameter to support both creation and editing",
|
|
89
|
+
"Use Form components from the Field namespace for consistent UI and validation",
|
|
90
|
+
"Always connect form state to Zustand store via st.use.[model]Form()",
|
|
91
|
+
"Update form state using st.do.set[Field]On[Model]() actions",
|
|
92
|
+
"Use usePage() hook for internationalization of labels and messages",
|
|
93
|
+
"Implement form validation at field level when possible",
|
|
94
|
+
"Reset form state on component unmount to prevent stale data",
|
|
95
|
+
"Split complex forms into smaller, focused components",
|
|
96
|
+
"Follow accessibility best practices for all form fields",
|
|
97
|
+
"Use consistent layout patterns across the application",
|
|
98
|
+
"Provide clear validation feedback and error messages",
|
|
99
|
+
"Initialize form data from API when editing existing models",
|
|
100
|
+
"Implement proper error handling for form submissions"
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
"page": "/akanjs/(docs)/docs/module/template/_index.tsx"
|
|
104
|
+
}
|