@akanjs/cli 0.0.142 → 0.0.144

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.
Files changed (349) hide show
  1. package/README.md +8 -0
  2. package/cjs/index.js +2437 -3204
  3. package/cjs/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
  4. package/cjs/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
  5. package/cjs/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
  6. package/cjs/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
  7. package/cjs/src/guidelines/componentRule/componentRule.instruction.md +732 -0
  8. package/cjs/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
  9. package/cjs/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
  10. package/cjs/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
  11. package/cjs/src/guidelines/framework/framework.instruction.md +1112 -0
  12. package/cjs/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
  13. package/cjs/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
  14. package/cjs/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
  15. package/cjs/src/guidelines/modelService/modelService.instruction.md +935 -0
  16. package/cjs/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
  17. package/cjs/src/guidelines/modelStore/modelStore.instruction.md +591 -0
  18. package/cjs/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
  19. package/cjs/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
  20. package/cjs/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
  21. package/cjs/src/guidelines/modelView/modelView.instruction.md +1005 -0
  22. package/cjs/src/guidelines/modelZone/modelZone.instruction.md +528 -0
  23. package/cjs/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
  24. package/cjs/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
  25. package/cjs/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
  26. package/cjs/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
  27. package/cjs/src/templates/module/__model__.dictionary.js +4 -5
  28. package/esm/index.js +2524 -3286
  29. package/esm/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
  30. package/esm/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
  31. package/esm/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
  32. package/esm/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
  33. package/esm/src/guidelines/componentRule/componentRule.instruction.md +732 -0
  34. package/esm/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
  35. package/esm/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
  36. package/esm/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
  37. package/esm/src/guidelines/framework/framework.instruction.md +1112 -0
  38. package/esm/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
  39. package/esm/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
  40. package/esm/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
  41. package/esm/src/guidelines/modelService/modelService.instruction.md +935 -0
  42. package/esm/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
  43. package/esm/src/guidelines/modelStore/modelStore.instruction.md +591 -0
  44. package/esm/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
  45. package/esm/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
  46. package/esm/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
  47. package/esm/src/guidelines/modelView/modelView.instruction.md +1005 -0
  48. package/esm/src/guidelines/modelZone/modelZone.instruction.md +528 -0
  49. package/esm/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
  50. package/esm/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
  51. package/esm/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
  52. package/esm/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
  53. package/esm/src/templates/module/__model__.dictionary.js +4 -5
  54. package/package.json +3 -1
  55. package/src/guideline/guideline.command.d.ts +7 -0
  56. package/src/guideline/guideline.prompt.d.ts +15 -0
  57. package/src/guideline/guideline.runner.d.ts +5 -0
  58. package/src/guideline/guideline.script.d.ts +6 -0
  59. package/src/guidelines/___library/sharedUiStructureDescription.en.md +786 -0
  60. package/src/guidelines/___library/utilUiStructureDescription.en.md +395 -0
  61. package/src/guidelines/___lint/lintRuleDescription.en.md +64 -0
  62. package/src/guidelines/___module/moduleStructureDescription.en.md +80 -0
  63. package/src/guidelines/componentRule/componentRule.instruction.md +732 -0
  64. package/src/guidelines/databaseModule/databaseModule.instruction.md +691 -0
  65. package/src/guidelines/enumConstant/enumConstant.instruction.md +232 -0
  66. package/src/guidelines/fieldDecorator/fieldDecorator.instruction.md +611 -0
  67. package/src/guidelines/framework/framework.instruction.md +1112 -0
  68. package/src/guidelines/modelConstant/modelConstant.instruction.md +958 -0
  69. package/src/guidelines/modelDictionary/modelDictionary.instruction.md +583 -0
  70. package/src/guidelines/modelDocument/modelDocument.instruction.md +683 -0
  71. package/src/guidelines/modelService/modelService.instruction.md +935 -0
  72. package/src/guidelines/modelSignal/modelSignal.instruction.md +588 -0
  73. package/src/guidelines/modelStore/modelStore.instruction.md +591 -0
  74. package/src/guidelines/modelTemplate/modelTemplate.instruction.md +577 -0
  75. package/src/guidelines/modelUnit/modelUnit.instruction.md +833 -0
  76. package/src/guidelines/modelUtil/modelUtil.instruction.md +752 -0
  77. package/src/guidelines/modelView/modelView.instruction.md +1005 -0
  78. package/src/guidelines/modelZone/modelZone.instruction.md +528 -0
  79. package/src/guidelines/scalarConstant/scalarConstant.instruction.md +489 -0
  80. package/src/guidelines/scalarDictionary/scalarDictionary.instruction.md +347 -0
  81. package/src/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +318 -0
  82. package/src/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
  83. package/src/module/module.command.d.ts +6 -8
  84. package/src/module/module.prompt.d.ts +2 -15
  85. package/src/module/module.request.d.ts +22 -18
  86. package/src/module/module.runner.d.ts +4 -20
  87. package/src/module/module.script.d.ts +6 -7
  88. package/src/scalar/scalar.command.d.ts +7 -0
  89. package/src/scalar/scalar.prompt.d.ts +23 -0
  90. package/src/scalar/scalar.runner.d.ts +13 -0
  91. package/src/scalar/scalar.script.d.ts +6 -0
  92. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -47
  93. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -128
  94. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -42
  95. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -50
  96. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -41
  97. package/cjs/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -51
  98. package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -43
  99. package/cjs/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -60
  100. package/cjs/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -54
  101. package/cjs/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
  102. package/cjs/src/templates/app/app/[lang]/admin/layout.js +0 -54
  103. package/cjs/src/templates/app/app/[lang]/admin/page.js +0 -63
  104. package/cjs/src/templates/app/app/csr.js +0 -34
  105. package/cjs/src/templates/app/app/index.html.template +0 -13
  106. package/cjs/src/templates/app/app/layout.js +0 -38
  107. package/cjs/src/templates/app/capacitor.config.ts.template +0 -8
  108. package/cjs/src/templates/app/env/env.client.debug.ts.template +0 -7
  109. package/cjs/src/templates/app/env/env.client.develop.ts.template +0 -7
  110. package/cjs/src/templates/app/env/env.client.local.ts.template +0 -7
  111. package/cjs/src/templates/app/env/env.client.main.ts.template +0 -7
  112. package/cjs/src/templates/app/env/env.client.testing.ts.template +0 -7
  113. package/cjs/src/templates/app/env/env.server.debug.ts.template +0 -15
  114. package/cjs/src/templates/app/env/env.server.develop.ts.template +0 -15
  115. package/cjs/src/templates/app/env/env.server.local.ts.template +0 -15
  116. package/cjs/src/templates/app/env/env.server.main.ts.template +0 -15
  117. package/cjs/src/templates/app/env/env.server.testing.ts.template +0 -7
  118. package/cjs/src/templates/app/lib/setting/Setting.Template.js +0 -57
  119. package/cjs/src/templates/app/lib/setting/Setting.Unit.js +0 -38
  120. package/cjs/src/templates/app/lib/setting/Setting.Util.js +0 -34
  121. package/cjs/src/templates/app/lib/setting/Setting.View.js +0 -51
  122. package/cjs/src/templates/app/lib/setting/Setting.Zone.js +0 -80
  123. package/cjs/src/templates/app/lib/setting/index.js +0 -61
  124. package/cjs/src/templates/app/lib/summary/Summary.Template.js +0 -43
  125. package/cjs/src/templates/app/lib/summary/Summary.Unit.js +0 -38
  126. package/cjs/src/templates/app/lib/summary/Summary.Util.js +0 -33
  127. package/cjs/src/templates/app/lib/summary/Summary.View.js +0 -51
  128. package/cjs/src/templates/app/lib/summary/Summary.Zone.js +0 -62
  129. package/cjs/src/templates/app/lib/summary/index.js +0 -67
  130. package/cjs/src/templates/app/lib/user/User.Template.js +0 -65
  131. package/cjs/src/templates/app/lib/user/User.Unit.js +0 -38
  132. package/cjs/src/templates/app/lib/user/User.Util.js +0 -94
  133. package/cjs/src/templates/app/lib/user/User.View.js +0 -66
  134. package/cjs/src/templates/app/lib/user/User.Zone.js +0 -74
  135. package/cjs/src/templates/app/lib/user/index.js +0 -61
  136. package/cjs/src/templates/app/page.test.ts.template +0 -10
  137. package/cjs/src/templates/app/playwright.config.ts.template +0 -6
  138. package/cjs/src/templates/app/postcss.config.js.template +0 -10
  139. package/cjs/src/templates/app/public/manifest.json.template +0 -67
  140. package/cjs/src/templates/app/tsconfig.json.template +0 -22
  141. package/cjs/src/templates/app/tsconfig.spec.json.template +0 -7
  142. package/cjs/src/templates/app/ui/Footer.js +0 -67
  143. package/cjs/src/templates/app/ui/MainHeader.js +0 -131
  144. package/cjs/src/templates/crudPages/[__model__Id]/edit/page.js +0 -73
  145. package/cjs/src/templates/crudPages/[__model__Id]/page.js +0 -83
  146. package/cjs/src/templates/crudPages/new/page.js +0 -70
  147. package/cjs/src/templates/crudPages/page.js +0 -71
  148. package/cjs/src/templates/libRoot/.gitignore.template +0 -15
  149. package/cjs/src/templates/libRoot/env/env.server.example.ts.template +0 -7
  150. package/cjs/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
  151. package/cjs/src/templates/libRoot/lib/setting/Setting.Template.js +0 -57
  152. package/cjs/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -38
  153. package/cjs/src/templates/libRoot/lib/setting/Setting.Util.js +0 -34
  154. package/cjs/src/templates/libRoot/lib/setting/Setting.View.js +0 -51
  155. package/cjs/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -80
  156. package/cjs/src/templates/libRoot/lib/setting/index.js +0 -61
  157. package/cjs/src/templates/libRoot/lib/summary/Summary.Template.js +0 -43
  158. package/cjs/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -38
  159. package/cjs/src/templates/libRoot/lib/summary/Summary.Util.js +0 -33
  160. package/cjs/src/templates/libRoot/lib/summary/Summary.View.js +0 -51
  161. package/cjs/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -62
  162. package/cjs/src/templates/libRoot/lib/summary/index.js +0 -67
  163. package/cjs/src/templates/libRoot/lib/user/User.Template.js +0 -65
  164. package/cjs/src/templates/libRoot/lib/user/User.Unit.js +0 -38
  165. package/cjs/src/templates/libRoot/lib/user/User.Util.js +0 -94
  166. package/cjs/src/templates/libRoot/lib/user/User.View.js +0 -66
  167. package/cjs/src/templates/libRoot/lib/user/User.Zone.js +0 -74
  168. package/cjs/src/templates/libRoot/lib/user/index.js +0 -61
  169. package/cjs/src/templates/libRoot/package.json.template +0 -4
  170. package/cjs/src/templates/libRoot/tsconfig.json.template +0 -13
  171. package/cjs/src/templates/libRoot/tsconfig.spec.json.template +0 -7
  172. package/cjs/src/templates/localDev/docker-compose.yaml.template +0 -36
  173. package/cjs/src/templates/module/__Model__.Template.js +0 -54
  174. package/cjs/src/templates/module/__Model__.Unit.js +0 -42
  175. package/cjs/src/templates/module/__Model__.Util.js +0 -70
  176. package/cjs/src/templates/module/__Model__.View.js +0 -48
  177. package/cjs/src/templates/module/__Model__.Zone.js +0 -83
  178. package/cjs/src/templates/module/index.js +0 -61
  179. package/cjs/src/templates/pkgRoot/tsconfig.json.template +0 -15
  180. package/cjs/src/templates/workspaceRoot/.env.template +0 -20
  181. package/cjs/src/templates/workspaceRoot/.gitignore.template +0 -118
  182. package/cjs/src/templates/workspaceRoot/.prettierignore.template +0 -10
  183. package/cjs/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
  184. package/cjs/src/templates/workspaceRoot/.swcrc.template +0 -9
  185. package/cjs/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
  186. package/cjs/src/templates/workspaceRoot/README.md.template +0 -37
  187. package/cjs/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
  188. package/cjs/src/templates/workspaceRoot/package.json.template +0 -43
  189. package/cjs/src/templates/workspaceRoot/tsconfig.json.template +0 -29
  190. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.js +0 -27
  191. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/page.js +0 -108
  192. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.js +0 -22
  193. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.js +0 -30
  194. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.js +0 -21
  195. package/esm/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.js +0 -31
  196. package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/layout.js +0 -23
  197. package/esm/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.js +0 -40
  198. package/esm/src/templates/app/app/[lang]/(__appName__)/layout.js +0 -34
  199. package/esm/src/templates/app/app/[lang]/(__appName__)/styles.css.template +0 -19
  200. package/esm/src/templates/app/app/[lang]/admin/layout.js +0 -34
  201. package/esm/src/templates/app/app/[lang]/admin/page.js +0 -43
  202. package/esm/src/templates/app/app/csr.js +0 -14
  203. package/esm/src/templates/app/app/index.html.template +0 -13
  204. package/esm/src/templates/app/app/layout.js +0 -18
  205. package/esm/src/templates/app/capacitor.config.ts.template +0 -8
  206. package/esm/src/templates/app/env/env.client.debug.ts.template +0 -7
  207. package/esm/src/templates/app/env/env.client.develop.ts.template +0 -7
  208. package/esm/src/templates/app/env/env.client.local.ts.template +0 -7
  209. package/esm/src/templates/app/env/env.client.main.ts.template +0 -7
  210. package/esm/src/templates/app/env/env.client.testing.ts.template +0 -7
  211. package/esm/src/templates/app/env/env.server.debug.ts.template +0 -15
  212. package/esm/src/templates/app/env/env.server.develop.ts.template +0 -15
  213. package/esm/src/templates/app/env/env.server.local.ts.template +0 -15
  214. package/esm/src/templates/app/env/env.server.main.ts.template +0 -15
  215. package/esm/src/templates/app/env/env.server.testing.ts.template +0 -7
  216. package/esm/src/templates/app/lib/setting/Setting.Template.js +0 -37
  217. package/esm/src/templates/app/lib/setting/Setting.Unit.js +0 -18
  218. package/esm/src/templates/app/lib/setting/Setting.Util.js +0 -14
  219. package/esm/src/templates/app/lib/setting/Setting.View.js +0 -31
  220. package/esm/src/templates/app/lib/setting/Setting.Zone.js +0 -60
  221. package/esm/src/templates/app/lib/setting/index.js +0 -41
  222. package/esm/src/templates/app/lib/summary/Summary.Template.js +0 -23
  223. package/esm/src/templates/app/lib/summary/Summary.Unit.js +0 -18
  224. package/esm/src/templates/app/lib/summary/Summary.Util.js +0 -13
  225. package/esm/src/templates/app/lib/summary/Summary.View.js +0 -31
  226. package/esm/src/templates/app/lib/summary/Summary.Zone.js +0 -42
  227. package/esm/src/templates/app/lib/summary/index.js +0 -47
  228. package/esm/src/templates/app/lib/user/User.Template.js +0 -45
  229. package/esm/src/templates/app/lib/user/User.Unit.js +0 -18
  230. package/esm/src/templates/app/lib/user/User.Util.js +0 -74
  231. package/esm/src/templates/app/lib/user/User.View.js +0 -46
  232. package/esm/src/templates/app/lib/user/User.Zone.js +0 -54
  233. package/esm/src/templates/app/lib/user/index.js +0 -41
  234. package/esm/src/templates/app/page.test.ts.template +0 -10
  235. package/esm/src/templates/app/playwright.config.ts.template +0 -6
  236. package/esm/src/templates/app/postcss.config.js.template +0 -10
  237. package/esm/src/templates/app/public/manifest.json.template +0 -67
  238. package/esm/src/templates/app/tsconfig.json.template +0 -22
  239. package/esm/src/templates/app/tsconfig.spec.json.template +0 -7
  240. package/esm/src/templates/app/ui/Footer.js +0 -47
  241. package/esm/src/templates/app/ui/MainHeader.js +0 -111
  242. package/esm/src/templates/crudPages/[__model__Id]/edit/page.js +0 -53
  243. package/esm/src/templates/crudPages/[__model__Id]/page.js +0 -63
  244. package/esm/src/templates/crudPages/new/page.js +0 -50
  245. package/esm/src/templates/crudPages/page.js +0 -51
  246. package/esm/src/templates/libRoot/.gitignore.template +0 -15
  247. package/esm/src/templates/libRoot/env/env.server.example.ts.template +0 -7
  248. package/esm/src/templates/libRoot/env/env.server.testing.ts.template +0 -7
  249. package/esm/src/templates/libRoot/lib/setting/Setting.Template.js +0 -37
  250. package/esm/src/templates/libRoot/lib/setting/Setting.Unit.js +0 -18
  251. package/esm/src/templates/libRoot/lib/setting/Setting.Util.js +0 -14
  252. package/esm/src/templates/libRoot/lib/setting/Setting.View.js +0 -31
  253. package/esm/src/templates/libRoot/lib/setting/Setting.Zone.js +0 -60
  254. package/esm/src/templates/libRoot/lib/setting/index.js +0 -41
  255. package/esm/src/templates/libRoot/lib/summary/Summary.Template.js +0 -23
  256. package/esm/src/templates/libRoot/lib/summary/Summary.Unit.js +0 -18
  257. package/esm/src/templates/libRoot/lib/summary/Summary.Util.js +0 -13
  258. package/esm/src/templates/libRoot/lib/summary/Summary.View.js +0 -31
  259. package/esm/src/templates/libRoot/lib/summary/Summary.Zone.js +0 -42
  260. package/esm/src/templates/libRoot/lib/summary/index.js +0 -47
  261. package/esm/src/templates/libRoot/lib/user/User.Template.js +0 -45
  262. package/esm/src/templates/libRoot/lib/user/User.Unit.js +0 -18
  263. package/esm/src/templates/libRoot/lib/user/User.Util.js +0 -74
  264. package/esm/src/templates/libRoot/lib/user/User.View.js +0 -46
  265. package/esm/src/templates/libRoot/lib/user/User.Zone.js +0 -54
  266. package/esm/src/templates/libRoot/lib/user/index.js +0 -41
  267. package/esm/src/templates/libRoot/package.json.template +0 -4
  268. package/esm/src/templates/libRoot/tsconfig.json.template +0 -13
  269. package/esm/src/templates/libRoot/tsconfig.spec.json.template +0 -7
  270. package/esm/src/templates/localDev/docker-compose.yaml.template +0 -36
  271. package/esm/src/templates/module/__Model__.Template.js +0 -34
  272. package/esm/src/templates/module/__Model__.Unit.js +0 -22
  273. package/esm/src/templates/module/__Model__.Util.js +0 -50
  274. package/esm/src/templates/module/__Model__.View.js +0 -28
  275. package/esm/src/templates/module/__Model__.Zone.js +0 -63
  276. package/esm/src/templates/module/index.js +0 -41
  277. package/esm/src/templates/pkgRoot/tsconfig.json.template +0 -15
  278. package/esm/src/templates/workspaceRoot/.env.template +0 -20
  279. package/esm/src/templates/workspaceRoot/.gitignore.template +0 -118
  280. package/esm/src/templates/workspaceRoot/.prettierignore.template +0 -10
  281. package/esm/src/templates/workspaceRoot/.prettierrc.json.template +0 -6
  282. package/esm/src/templates/workspaceRoot/.swcrc.template +0 -9
  283. package/esm/src/templates/workspaceRoot/.vscode/settings.json.template +0 -13
  284. package/esm/src/templates/workspaceRoot/README.md.template +0 -37
  285. package/esm/src/templates/workspaceRoot/eslint.config.ts.template +0 -3
  286. package/esm/src/templates/workspaceRoot/package.json.template +0 -43
  287. package/esm/src/templates/workspaceRoot/tsconfig.json.template +0 -29
  288. package/src/application/application.prompt.d.ts +0 -2
  289. package/src/templates/app/app/[lang]/(__appName__)/(public)/forgotpassword/page.d.ts +0 -9
  290. package/src/templates/app/app/[lang]/(__appName__)/(public)/page.d.ts +0 -9
  291. package/src/templates/app/app/[lang]/(__appName__)/(public)/privacy/page.d.ts +0 -9
  292. package/src/templates/app/app/[lang]/(__appName__)/(public)/signin/page.d.ts +0 -9
  293. package/src/templates/app/app/[lang]/(__appName__)/(public)/termsofservice/page.d.ts +0 -10
  294. package/src/templates/app/app/[lang]/(__appName__)/(public)/unknown/page.d.ts +0 -9
  295. package/src/templates/app/app/[lang]/(__appName__)/(user)/layout.d.ts +0 -9
  296. package/src/templates/app/app/[lang]/(__appName__)/(user)/self/page.d.ts +0 -9
  297. package/src/templates/app/app/[lang]/(__appName__)/layout.d.ts +0 -9
  298. package/src/templates/app/app/[lang]/admin/layout.d.ts +0 -9
  299. package/src/templates/app/app/[lang]/admin/page.d.ts +0 -9
  300. package/src/templates/app/app/csr.d.ts +0 -9
  301. package/src/templates/app/app/layout.d.ts +0 -9
  302. package/src/templates/app/lib/setting/Setting.Template.d.ts +0 -9
  303. package/src/templates/app/lib/setting/Setting.Unit.d.ts +0 -9
  304. package/src/templates/app/lib/setting/Setting.Util.d.ts +0 -9
  305. package/src/templates/app/lib/setting/Setting.View.d.ts +0 -9
  306. package/src/templates/app/lib/setting/Setting.Zone.d.ts +0 -9
  307. package/src/templates/app/lib/setting/index.d.ts +0 -9
  308. package/src/templates/app/lib/summary/Summary.Template.d.ts +0 -9
  309. package/src/templates/app/lib/summary/Summary.Unit.d.ts +0 -9
  310. package/src/templates/app/lib/summary/Summary.Util.d.ts +0 -9
  311. package/src/templates/app/lib/summary/Summary.View.d.ts +0 -9
  312. package/src/templates/app/lib/summary/Summary.Zone.d.ts +0 -9
  313. package/src/templates/app/lib/summary/index.d.ts +0 -9
  314. package/src/templates/app/lib/user/User.Template.d.ts +0 -9
  315. package/src/templates/app/lib/user/User.Unit.d.ts +0 -9
  316. package/src/templates/app/lib/user/User.Util.d.ts +0 -9
  317. package/src/templates/app/lib/user/User.View.d.ts +0 -9
  318. package/src/templates/app/lib/user/User.Zone.d.ts +0 -9
  319. package/src/templates/app/lib/user/index.d.ts +0 -9
  320. package/src/templates/app/ui/Footer.d.ts +0 -9
  321. package/src/templates/app/ui/MainHeader.d.ts +0 -10
  322. package/src/templates/crudPages/[__model__Id]/edit/page.d.ts +0 -11
  323. package/src/templates/crudPages/[__model__Id]/page.d.ts +0 -11
  324. package/src/templates/crudPages/new/page.d.ts +0 -11
  325. package/src/templates/crudPages/page.d.ts +0 -11
  326. package/src/templates/libRoot/lib/setting/Setting.Template.d.ts +0 -9
  327. package/src/templates/libRoot/lib/setting/Setting.Unit.d.ts +0 -9
  328. package/src/templates/libRoot/lib/setting/Setting.Util.d.ts +0 -9
  329. package/src/templates/libRoot/lib/setting/Setting.View.d.ts +0 -9
  330. package/src/templates/libRoot/lib/setting/Setting.Zone.d.ts +0 -9
  331. package/src/templates/libRoot/lib/setting/index.d.ts +0 -9
  332. package/src/templates/libRoot/lib/summary/Summary.Template.d.ts +0 -9
  333. package/src/templates/libRoot/lib/summary/Summary.Unit.d.ts +0 -9
  334. package/src/templates/libRoot/lib/summary/Summary.Util.d.ts +0 -9
  335. package/src/templates/libRoot/lib/summary/Summary.View.d.ts +0 -9
  336. package/src/templates/libRoot/lib/summary/Summary.Zone.d.ts +0 -9
  337. package/src/templates/libRoot/lib/summary/index.d.ts +0 -9
  338. package/src/templates/libRoot/lib/user/User.Template.d.ts +0 -9
  339. package/src/templates/libRoot/lib/user/User.Unit.d.ts +0 -9
  340. package/src/templates/libRoot/lib/user/User.Util.d.ts +0 -9
  341. package/src/templates/libRoot/lib/user/User.View.d.ts +0 -9
  342. package/src/templates/libRoot/lib/user/User.Zone.d.ts +0 -9
  343. package/src/templates/libRoot/lib/user/index.d.ts +0 -9
  344. package/src/templates/module/__Model__.Template.d.ts +0 -11
  345. package/src/templates/module/__Model__.Unit.d.ts +0 -11
  346. package/src/templates/module/__Model__.Util.d.ts +0 -11
  347. package/src/templates/module/__Model__.View.d.ts +0 -11
  348. package/src/templates/module/__Model__.Zone.d.ts +0 -11
  349. package/src/templates/module/index.d.ts +0 -11
@@ -0,0 +1,588 @@
1
+ # Model Signal Implementation Guide for Akan.js
2
+
3
+ ## Purpose and Role of Model Signal Files
4
+
5
+ `model.signal.ts` files serve as the communication bridge between client and server in Akan.js applications. They implement a declarative pattern that simplifies and standardizes data flow throughout your application, while providing strong typing and automatic code generation.
6
+
7
+ Signals provide five key functionalities:
8
+
9
+ 1. **Data Queries** (`@Query`) - Fetch data with typed parameters and responses
10
+ 2. **Data Mutations** (`@Mutation`) - Modify data with transactional safety
11
+ 3. **Real-time Messaging** (`@Message`) - Handle WebSocket communication
12
+ 4. **Background Processing** (`@Process`) - Execute long-running jobs
13
+ 5. **Publish/Subscribe** (`@Pubsub`) - Manage real-time data subscriptions
14
+
15
+ The Signal system abstracts away the underlying transport mechanisms (GraphQL, REST, WebSockets) while maintaining type safety across client and server.
16
+
17
+ ## Signal Class Structure
18
+
19
+ A typical model.signal.ts file follows this structure:
20
+
21
+ ```typescript
22
+ import { ID, Int } from "@akanjs/base";
23
+ import { SortOf } from "@akanjs/constant";
24
+ import { Arg, DbSignal, Mutation, Query, resolve, Self, Signal } from "@akanjs/signal";
25
+
26
+ import { cnst, Srvs } from "../cnst";
27
+ import type * as db from "../db";
28
+
29
+ @Signal(() => cnst.ModelName)
30
+ export class ModelNameSignal extends DbSignal(cnst.modelNameCnst, Srvs, {
31
+ guards: { get: Query.Public, cru: Mutation.User },
32
+ }) {
33
+ // Signal methods here...
34
+ }
35
+ ```
36
+
37
+ Key components:
38
+
39
+ - `@Signal()` decorator defines this class as a signal provider
40
+ - `DbSignal()` higher-order function provides standard CRUD operations
41
+ - `guards` option configures default access control for CRUD operations
42
+ - Service references are injected from `Srvs` imported from cnst.ts
43
+
44
+ ## Decorator Reference
45
+
46
+ ### 1. @Query Decorator
47
+
48
+ Used for read-only operations with access control levels:
49
+
50
+ ```typescript
51
+ @Query.Public(() => [cnst.Product]) // Public access, returns array of Products
52
+ async productListInFeatured(
53
+ @Arg.Query("skip", () => Int, { nullable: true }) skip: number | null,
54
+ @Arg.Query("limit", () => Int, { nullable: true }) limit: number | null,
55
+ @Arg.Query("sort", () => String, { nullable: true }) sort: SortOf<cnst.ProductFilter> | null
56
+ ) {
57
+ const products = await this.productService.listFeatured({ skip, limit, sort });
58
+ return resolve<cnst.Product[]>(products); // Type-safe resolution
59
+ }
60
+ ```
61
+
62
+ Access control levels:
63
+
64
+ - `Query.Public` - Available to unauthenticated users
65
+ - `Query.User` - Requires user authentication
66
+ - `Query.Admin` - Requires admin access
67
+ - `Query.SuperAdmin` - Requires super admin access
68
+ - `Query.Every` - Available to all authenticated users (any role)
69
+
70
+ ### 2. @Mutation Decorator
71
+
72
+ Used for operations that modify data, with similar access control:
73
+
74
+ ```typescript
75
+ @Mutation.User(() => cnst.ChatRoom) // User-level access, returns ChatRoom
76
+ async openChatRoom(
77
+ @Arg.Param("root", () => ID) root: string,
78
+ @Arg.Param("targetId", () => ID) targetId: string,
79
+ @Self() self: Self // Gets current user automatically
80
+ ) {
81
+ const chatRoom = await this.chatRoomService.open({
82
+ targetId,
83
+ userId: self.id,
84
+ root,
85
+ });
86
+ return resolve<cnst.ChatRoom>(chatRoom);
87
+ }
88
+ ```
89
+
90
+ ### 3. @Message Decorator
91
+
92
+ Handles real-time socket messages for instant communication:
93
+
94
+ ```typescript
95
+ @Message.User(() => Boolean) // User-level access, returns Boolean
96
+ async readChat(
97
+ @Arg.Msg("root", () => ID) root: string,
98
+ @Arg.Msg("userId", () => ID) userId: string
99
+ ) {
100
+ const chat = await this.chatRoomService.readChat(root, userId);
101
+ return resolve<boolean>(!!chat);
102
+ }
103
+ ```
104
+
105
+ ### 4. @Process Decorator
106
+
107
+ For background processing on the server:
108
+
109
+ ```typescript
110
+ @Process.Federation(() => Boolean) // Federation scope, returns Boolean
111
+ async archiveDbBackup(
112
+ @Arg.Msg("dbBackupId", () => String) dbBackupId: string
113
+ ) {
114
+ await this.dbBackupService.archiveDbBackup(dbBackupId);
115
+ return done(true); // Use done() for process completion
116
+ }
117
+ ```
118
+
119
+ Process scopes:
120
+
121
+ - `Process.Federation` - Run on federation servers
122
+ - `Process.Batch` - Run on batch processing servers
123
+ - `Process.All` - Run on all server types
124
+
125
+ ### 5. @Pubsub Decorator
126
+
127
+ Manages real-time subscriptions:
128
+
129
+ ```typescript
130
+ @Pubsub.Public(() => cnst.Chat) // Public subscription, emits Chat objects
131
+ chatAdded(
132
+ @Arg.Room("root", () => ID) root: string, // Room parameter for subscription
133
+ @Ws() ws: Ws // WebSocket context
134
+ ) {
135
+ return subscribe<cnst.Chat>(); // Subscribe to this type
136
+ }
137
+ ```
138
+
139
+ ## Parameter Decorators
140
+
141
+ Signals use parameter decorators to define how data is passed:
142
+
143
+ 1. **HTTP/GraphQL Parameters**
144
+
145
+ - `@Arg.Query()` - URL query parameters
146
+ - `@Arg.Param()` - URL path parameters
147
+ - `@Arg.Body()` - Request body data
148
+ - `@Arg.Upload()` - File uploads
149
+
150
+ 2. **WebSocket Parameters**
151
+
152
+ - `@Arg.Msg()` - Message data
153
+ - `@Arg.Room()` - Room for subscription
154
+
155
+ 3. **Context Parameters**
156
+ - `@Self()` - Current authenticated user
157
+ - `@Account()` - User account information
158
+ - `@UserIp()` - Client IP address
159
+ - `@Ws()` - WebSocket context
160
+
161
+ ## Slice Pattern for Data Access
162
+
163
+ The slice pattern standardizes data access with consistent naming and pagination:
164
+
165
+ ```typescript
166
+ // * /////////////////////////////////////
167
+ // * Self Slice
168
+ @Query.User(() => [cnst.ChatRoom])
169
+ async chatRoomListInSelf( // listIn<SliceName> pattern
170
+ @Arg.Query("skip", () => Int, { nullable: true }) skip: number | null,
171
+ @Arg.Query("limit", () => Int, { nullable: true }) limit: number | null,
172
+ @Arg.Query("sort", () => String, { nullable: true }) sort: SortOf<cnst.ChatRoomFilter> | null,
173
+ @Self() self: Self
174
+ ) {
175
+ const chatRooms = await this.chatRoomService.listInUser(self.id, { skip, limit, sort });
176
+ return resolve<cnst.ChatRoom[]>(chatRooms);
177
+ }
178
+
179
+ @Query.User(() => cnst.ChatRoomInsight)
180
+ async chatRoomInsightInSelf( // insightIn<SliceName> pattern
181
+ @Self() self: Self
182
+ ) {
183
+ const chatRoomInsight = await this.chatRoomService.insightInUser(self.id);
184
+ return resolve<cnst.ChatRoomInsight>(chatRoomInsight);
185
+ }
186
+ // * Self Slice
187
+ // * /////////////////////////////////////
188
+ ```
189
+
190
+ Common slices:
191
+
192
+ - `Self` - Data related to the current user
193
+ - `Public` - Publicly accessible data
194
+ - `Featured` - Highlighted items
195
+ - `Root/Parent` - Items within a parent container
196
+ - Custom domain slices (e.g., `DevApp`, `Init`)
197
+
198
+ ## Client-Side Signal Usage
199
+
200
+ ### 1. Direct API Calls
201
+
202
+ ```typescript
203
+ import { productGet, productListInFeatured } from "./product.signal";
204
+
205
+ // Fetch a single product
206
+ const product = await productGet("product-123");
207
+
208
+ // Fetch a list with parameters
209
+ const featuredProducts = await productListInFeatured(0, 10, "price-asc");
210
+ ```
211
+
212
+ ### 2. Store Integration
213
+
214
+ ```typescript
215
+ // product.store.ts
216
+ import { create } from "zustand";
217
+ import { productListInFeatured, productInsightInFeatured } from "./product.signal";
218
+
219
+ export const useProductStore = create<ProductStore>((set) => ({
220
+ featured: [],
221
+ insight: undefined,
222
+
223
+ loadFeatured: async (page = 1, limit = 10) => {
224
+ const [products, insight] = await Promise.all([
225
+ productListInFeatured((page - 1) * limit, limit, "popular"),
226
+ productInsightInFeatured(),
227
+ ]);
228
+
229
+ set({ featured: products, insight });
230
+ },
231
+ }));
232
+ ```
233
+
234
+ ### 3. React Component Integration
235
+
236
+ ```tsx
237
+ import { useEffect } from "react";
238
+ import { useProductStore } from "./product.store";
239
+
240
+ function FeaturedProducts() {
241
+ const { featured, insight, loadFeatured } = useProductStore();
242
+
243
+ useEffect(() => {
244
+ loadFeatured();
245
+ }, []);
246
+
247
+ return (
248
+ <div>
249
+ <h3>Featured Products ({insight?.count})</h3>
250
+ {featured.map((product) => (
251
+ <ProductCard key={product.id} product={product} />
252
+ ))}
253
+ </div>
254
+ );
255
+ }
256
+ ```
257
+
258
+ ### 4. Real-Time Subscriptions
259
+
260
+ ```tsx
261
+ import { useEffect } from "react";
262
+ import { subscribeChatAdded } from "./chatRoom.signal";
263
+ import { useChatStore } from "./chat.store";
264
+
265
+ function ChatRoom({ roomId }) {
266
+ const { addChat } = useChatStore();
267
+
268
+ useEffect(() => {
269
+ // Subscribe to real-time updates
270
+ const unsubscribe = subscribeChatAdded(roomId, (chat) => {
271
+ addChat(chat);
272
+ });
273
+
274
+ return () => {
275
+ // Cleanup subscription
276
+ unsubscribe();
277
+ };
278
+ }, [roomId]);
279
+
280
+ // Component JSX...
281
+ }
282
+ ```
283
+
284
+ ## Advanced Patterns
285
+
286
+ ### 1. DbSignal for Standard CRUD
287
+
288
+ DbSignal creates standard operations that you don't need to implement:
289
+
290
+ ```typescript
291
+ @Signal(() => cnst.Board)
292
+ export class BoardSignal extends DbSignal(cnst.boardCnst, Srvs, {
293
+ guards: { get: Query.Public, cru: Mutation.Admin },
294
+ }) {
295
+ // Custom methods beyond CRUD go here
296
+ }
297
+ ```
298
+
299
+ This automatically provides:
300
+
301
+ - `getBoard(id)` - Get by ID
302
+ - `lightBoard(id)` - Get lightweight version
303
+ - `boardList(filter, options)` - List with pagination
304
+ - `boardInsight(filter)` - Get counts/statistics
305
+ - `boardExists(filter)` - Check existence
306
+ - `createBoard(data)` - Create new record
307
+ - `updateBoard(id, data)` - Update existing record
308
+ - `removeBoard(id)` - Soft-delete record
309
+
310
+ ### 2. Combined Queries
311
+
312
+ ```typescript
313
+ @Query.Public(() => cnst.DashboardData)
314
+ async getDashboard(@Self() self: Self) {
315
+ // Parallel data fetching
316
+ const [stats, notifications, activities] = await Promise.all([
317
+ this.statsService.getUserStats(self.id),
318
+ this.notificationService.getRecent(self.id, { limit: 5 }),
319
+ this.activityService.getRecent(self.id, { limit: 10 })
320
+ ]);
321
+
322
+ // Return combined result
323
+ return resolve<cnst.DashboardData>({
324
+ stats,
325
+ notifications,
326
+ activities
327
+ });
328
+ }
329
+ ```
330
+
331
+ ### 3. Batch Operations
332
+
333
+ ```typescript
334
+ @Mutation.Admin(() => [cnst.User])
335
+ async bulkUpdateUserStatus(
336
+ @Arg.Body("userIds", () => [ID]) userIds: string[],
337
+ @Arg.Body("status", () => String) status: cnst.UserStatus
338
+ ) {
339
+ const users = await this.userService.bulkUpdateStatus(userIds, status);
340
+ return resolve<cnst.User[]>(users);
341
+ }
342
+ ```
343
+
344
+ ### 4. Filtered Access Control
345
+
346
+ ```typescript
347
+ @Query.User(() => cnst.ProjectDetails)
348
+ async getProjectDetails(
349
+ @Arg.Param("projectId", () => ID) projectId: string,
350
+ @Self() self: Self
351
+ ) {
352
+ // Check permissions within the method
353
+ const hasAccess = await this.projectService.checkUserAccess(projectId, self.id);
354
+ if (!hasAccess) {
355
+ throw new Error("Access denied");
356
+ }
357
+
358
+ const project = await this.projectService.getDetails(projectId);
359
+ return resolve<cnst.ProjectDetails>(project);
360
+ }
361
+ ```
362
+
363
+ ## Best Practices
364
+
365
+ ### 1. Naming Conventions
366
+
367
+ - **Method Names**:
368
+
369
+ - Use `modelListIn<Slice>` for list queries
370
+ - Use `modelInsightIn<Slice>` for insight queries
371
+ - Prefix mutations with verbs (`createUser`, `updateProfile`)
372
+ - Use descriptive names that indicate functionality
373
+
374
+ - **Parameter Names**:
375
+ - Use consistent names across similar methods
376
+ - Match service method parameter names where possible
377
+
378
+ ### 2. Type Safety
379
+
380
+ - Always specify return types in decorators: `@Query.Public(() => ModelType)`
381
+ - Always use `resolve<Type>()` with explicit type
382
+ - Define parameter types with GraphQL scalar types: `() => ID`, `() => Int`
383
+ - Use nullability consistently: `{ nullable: true }`
384
+
385
+ ### 3. Performance
386
+
387
+ - Use pagination parameters consistently (`skip`/`limit` or `page`/`pageSize`)
388
+ - Implement slices for focused data retrieval
389
+ - Use parallel requests with `Promise.all` for combined data
390
+ - Consider implementing cursor-based pagination for large datasets
391
+
392
+ ### 4. Security
393
+
394
+ - Apply appropriate access control decorators
395
+ - Validate input data in signals or services
396
+ - Use the `@Self()` decorator to ensure user-scoped operations
397
+ - Implement rate limiting for public endpoints
398
+
399
+ ### 5. Error Handling
400
+
401
+ - Use try/catch blocks for operations that might fail
402
+ - Return standardized error formats
403
+ - Add logging for debugging purposes
404
+ - Handle database errors gracefully
405
+
406
+ ## Implementation Examples
407
+
408
+ ### Basic CRUD Signal with DbSignal
409
+
410
+ ```typescript
411
+ @Signal(() => cnst.Product)
412
+ export class ProductSignal extends DbSignal(cnst.productCnst, Srvs, {
413
+ guards: { get: Query.Public, cru: Mutation.Admin },
414
+ }) {
415
+ // Custom methods beyond auto-generated CRUD
416
+ @Query.Public(() => [cnst.Product])
417
+ async productListInFeatured(
418
+ @Arg.Query("skip", () => Int, { nullable: true }) skip: number | null,
419
+ @Arg.Query("limit", () => Int, { nullable: true }) limit: number | null
420
+ ) {
421
+ const products = await this.productService.listFeatured({ skip, limit });
422
+ return resolve<cnst.Product[]>(products);
423
+ }
424
+
425
+ @Mutation.Admin(() => Boolean)
426
+ async toggleProductFeatured(
427
+ @Arg.Param("productId", () => ID) productId: string,
428
+ @Arg.Body("featured", () => Boolean) featured: boolean
429
+ ) {
430
+ await this.productService.setFeatured(productId, featured);
431
+ return resolve<boolean>(true);
432
+ }
433
+ }
434
+ ```
435
+
436
+ ### Real-Time Chat Signal
437
+
438
+ ```typescript
439
+ @Signal(() => cnst.Chat)
440
+ export class ChatSignal {
441
+ @Mutation.User(() => cnst.Chat)
442
+ async sendChat(
443
+ @Arg.Body("roomId", () => ID) roomId: string,
444
+ @Arg.Body("message", () => String) message: string,
445
+ @Self() self: Self
446
+ ) {
447
+ const chat = await this.chatService.create(roomId, self.id, message);
448
+ return resolve<cnst.Chat>(chat);
449
+ }
450
+
451
+ @Message.User(() => Boolean)
452
+ async markAsRead(@Arg.Msg("chatId", () => ID) chatId: string, @Self() self: Self) {
453
+ await this.chatService.markAsRead(chatId, self.id);
454
+ return resolve<boolean>(true);
455
+ }
456
+
457
+ @Pubsub.User(() => cnst.Chat)
458
+ chatReceived(@Arg.Room("roomId", () => ID) roomId: string, @Ws() ws: Ws) {
459
+ return subscribe<cnst.Chat>();
460
+ }
461
+ }
462
+ ```
463
+
464
+ ### Background Processing Signal
465
+
466
+ ```typescript
467
+ @Signal(() => cnst.Report)
468
+ export class ReportSignal {
469
+ @Mutation.Admin(() => cnst.Report)
470
+ async generateReport(
471
+ @Arg.Body("type", () => String) type: cnst.ReportType,
472
+ @Arg.Body("parameters", () => cnst.ReportParameters) parameters: cnst.ReportParameters,
473
+ @Self() self: Self
474
+ ) {
475
+ // Create report record
476
+ const report = await this.reportService.initReport(type, parameters, self.id);
477
+
478
+ // Queue background process
479
+ await this.reportService.queueReportGeneration(report.id);
480
+
481
+ return resolve<cnst.Report>(report);
482
+ }
483
+
484
+ @Process.Batch(() => Boolean)
485
+ async processReport(@Arg.Msg("reportId", () => ID) reportId: string) {
486
+ await this.reportService.generateReport(reportId);
487
+ return done(true);
488
+ }
489
+ }
490
+ ```
491
+
492
+ ## Troubleshooting
493
+
494
+ ### Common Issues
495
+
496
+ 1. **Type Mismatch Errors**
497
+
498
+ - Ensure GraphQL types match TypeScript types
499
+ - Check nullable parameters and provide default values
500
+ - Verify service method return types match signal return types
501
+
502
+ 2. **Authentication Errors**
503
+
504
+ - Verify guard levels match your security requirements
505
+ - Check that @Self() is used in user-scoped operations
506
+ - Test with different user roles to verify access control
507
+
508
+ 3. **Real-Time Communication Issues**
509
+
510
+ - Ensure room names are consistent between subscriptions and messages
511
+ - Verify WebSocket connection is established
512
+ - Check that subscription events are being triggered correctly
513
+
514
+ 4. **Missing Data in Client**
515
+ - Verify signal method parameters match client call parameters
516
+ - Check that resolve<Type>() is being used correctly
517
+ - Ensure proper error handling on the client side
518
+
519
+ ### Debugging Tips
520
+
521
+ 1. Enable verbose logging in development
522
+ 2. Use network inspection tools to examine requests/responses
523
+ 3. Add temporary logging in signal methods
524
+ 4. Test signals directly in a backend-only environment
525
+ 5. Use GraphQL playground to test queries/mutations
526
+
527
+ ## Advanced Topics
528
+
529
+ ### Custom Signal Decorators
530
+
531
+ You can create custom decorators for reusable patterns:
532
+
533
+ ```typescript
534
+ // Create a custom slice decorator
535
+ export function SelfSlice<T>(returnType: () => T) {
536
+ return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
537
+ Query.User(returnType)(target, propertyKey, descriptor);
538
+ // Add additional metadata or behavior
539
+ };
540
+ }
541
+ ```
542
+
543
+ ### Signal Integration with External APIs
544
+
545
+ ```typescript
546
+ @Signal(() => cnst.ExternalData)
547
+ export class ExternalApiSignal {
548
+ @Query.Public(() => cnst.WeatherData)
549
+ async getWeatherData(@Arg.Query("location", () => String) location: string) {
550
+ // Call external API with proper error handling
551
+ try {
552
+ const data = await this.externalApiService.fetchWeather(location);
553
+ return resolve<cnst.WeatherData>(data);
554
+ } catch (error) {
555
+ // Handle and transform errors from external API
556
+ throw new Error(`Weather API error: ${error.message}`);
557
+ }
558
+ }
559
+ }
560
+ ```
561
+
562
+ ### Caching Strategies
563
+
564
+ Signals can implement caching for performance:
565
+
566
+ ```typescript
567
+ @Signal(() => cnst.Product)
568
+ export class ProductSignal extends DbSignal(cnst.productCnst, Srvs) {
569
+ @Query.Public(() => cnst.Product)
570
+ async getProduct(@Arg.Param("productId", () => ID) productId: string) {
571
+ // Check cache first
572
+ const cached = await this.cacheService.get(`product:${productId}`);
573
+ if (cached) {
574
+ return resolve<cnst.Product>(cached);
575
+ }
576
+
577
+ // Fetch from database if not cached
578
+ const product = await this.productService.get(productId);
579
+
580
+ // Cache for future requests
581
+ await this.cacheService.set(`product:${productId}`, product, 3600);
582
+
583
+ return resolve<cnst.Product>(product);
584
+ }
585
+ }
586
+ ```
587
+
588
+ Remember that signals should be pure TypeScript with no framework-specific code, as they're used by both client and server. The Akan.js framework handles the conversion to the appropriate transport mechanism.