@supersoniks/concorde 5.1.1 → 5.1.3-immutable.1

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 (459) hide show
  1. package/.agents/skills/concorde-docs/SKILL.md +153 -0
  2. package/.agents/skills/{concorde-component-docs/template.md → concorde-docs/templates/component.md} +6 -2
  3. package/.agents/skills/concorde-docs/templates/decorator.md +43 -0
  4. package/.agents/skills/concorde-docs/templates/guide.md +25 -0
  5. package/.claude/skills +1 -0
  6. package/.github/workflows/ci.yml +21 -0
  7. package/.github-export-ignore +30 -0
  8. package/CONTRIBUTING.md +59 -0
  9. package/DEV.md +54 -0
  10. package/LICENSE +21 -0
  11. package/OPEN_SOURCE_CHECKPOINT.md +133 -0
  12. package/README.md +4 -4
  13. package/ai/README.md +29 -41
  14. package/ai/skills/concorde/SKILL.md +54 -324
  15. package/ai/skills/concorde/rules/composition.md +32 -0
  16. package/ai/skills/concorde/rules/data.md +47 -0
  17. package/ai/skills/concorde/rules/http.md +25 -0
  18. package/ai/skills/concorde/rules/lists-forms.md +35 -0
  19. package/ai/skills/concorde/rules/styling.md +46 -0
  20. package/ai/skills/concorde/rules/troubleshooting.md +45 -0
  21. package/build-infos.json +1 -1
  22. package/concorde-core.bundle.js +177 -177
  23. package/concorde-core.es.js +4993 -4833
  24. package/custom-elements-manifest.public.config.mjs +8 -0
  25. package/{.tmp-cem/custom-elements.json → custom-elements.json} +11758 -8904
  26. package/dist/concorde-core.bundle.js +177 -177
  27. package/dist/concorde-core.es.js +4993 -4833
  28. package/dist/docs-mock-api-sw.js +58 -223
  29. package/dist/docs-mock-api-sw.js.map +4 -4
  30. package/dist/img/concorde/plane_01.jpg +0 -0
  31. package/dist/img/concorde/plane_02.jpg +0 -0
  32. package/dist/img/concorde/plane_03.jpg +0 -0
  33. package/dist/img/concorde/plane_04.jpg +0 -0
  34. package/dist/img/concorde/plane_05.jpg +0 -0
  35. package/dist/img/concorde/plane_06.jpg +0 -0
  36. package/dist/img/concorde/plane_07.jpg +0 -0
  37. package/dist/img/concorde/plane_08.jpg +0 -0
  38. package/dist/img/concorde/plane_09.jpg +0 -0
  39. package/dist/img/concorde/plane_10.jpg +0 -0
  40. package/dist/img/concorde/plane_11.jpg +0 -0
  41. package/dist/img/concorde/plane_12.jpg +0 -0
  42. package/dist/img/concorde/plane_13.jpg +0 -0
  43. package/dist/img/og-concorde.jpg +0 -0
  44. package/dist/robots.txt +11 -10
  45. package/docs/assets/index-D_alEsng.js +12122 -0
  46. package/docs/crawl/core/components/functional/date/date.html +190 -0
  47. package/docs/crawl/core/components/functional/fetch/fetch.html +109 -0
  48. package/docs/crawl/core/components/functional/if/if.html +27 -0
  49. package/docs/crawl/core/components/functional/jsonata/jsonata.html +79 -0
  50. package/docs/crawl/core/components/functional/list/list.html +70 -0
  51. package/docs/crawl/core/components/functional/mix/mix.html +45 -0
  52. package/docs/crawl/core/components/functional/queue/queue.html +96 -0
  53. package/docs/crawl/core/components/functional/router/router.html +106 -0
  54. package/docs/crawl/core/components/functional/sdui/sdui-extension-points.html +126 -0
  55. package/docs/crawl/core/components/functional/sdui/sdui.html +368 -0
  56. package/docs/crawl/core/components/functional/states/states.html +66 -0
  57. package/docs/crawl/core/components/functional/submit/submit.html +160 -0
  58. package/docs/crawl/core/components/functional/subscriber/subscriber.html +67 -0
  59. package/docs/crawl/core/components/functional/value/value.html +51 -0
  60. package/docs/crawl/core/components/ui/alert/alert.html +211 -0
  61. package/docs/crawl/core/components/ui/alert-messages/alert-messages.html +131 -0
  62. package/docs/crawl/core/components/ui/badge/badge.html +197 -0
  63. package/docs/crawl/core/components/ui/button/button.html +150 -0
  64. package/docs/crawl/core/components/ui/captcha/captcha.html +112 -0
  65. package/docs/crawl/core/components/ui/card/card.html +253 -0
  66. package/docs/crawl/core/components/ui/divider/divider.html +144 -0
  67. package/docs/crawl/core/components/ui/form/checkbox/checkbox.html +73 -0
  68. package/docs/crawl/core/components/ui/form/fieldset/fieldset.html +266 -0
  69. package/docs/crawl/core/components/ui/form/form-actions/form-actions.html +122 -0
  70. package/docs/crawl/core/components/ui/form/form-layout/form-layout.html +121 -0
  71. package/docs/crawl/core/components/ui/form/input/input.html +109 -0
  72. package/docs/crawl/core/components/ui/form/input-autocomplete/input-autocomplete.html +38 -0
  73. package/docs/crawl/core/components/ui/form/radio/radio.html +56 -0
  74. package/docs/crawl/core/components/ui/form/select/select.html +73 -0
  75. package/docs/crawl/core/components/ui/form/switch/switch.html +56 -0
  76. package/docs/crawl/core/components/ui/form/textarea/textarea.html +59 -0
  77. package/docs/crawl/core/components/ui/group/group.html +104 -0
  78. package/docs/crawl/core/components/ui/icon/icon.html +222 -0
  79. package/docs/crawl/core/components/ui/image/image.html +298 -0
  80. package/docs/crawl/core/components/ui/link/link.html +100 -0
  81. package/docs/crawl/core/components/ui/loader/loader.html +124 -0
  82. package/docs/crawl/core/components/ui/menu/menu.html +394 -0
  83. package/docs/crawl/core/components/ui/modal/modal.html +342 -0
  84. package/docs/crawl/core/components/ui/pop/pop.html +296 -0
  85. package/docs/crawl/core/components/ui/progress/progress.html +131 -0
  86. package/docs/crawl/core/components/ui/table/table.html +545 -0
  87. package/docs/crawl/core/components/ui/theme/theme.html +131 -0
  88. package/docs/crawl/core/components/ui/toast/toast.html +233 -0
  89. package/docs/crawl/core/components/ui/tooltip/tooltip.html +140 -0
  90. package/docs/crawl/docs/_core-concept/dataFlow.html +177 -0
  91. package/docs/crawl/docs/_core-concept/overview.html +66 -0
  92. package/docs/crawl/docs/_core-concept/subscriber.html +75 -0
  93. package/docs/crawl/docs/_decorators/ancestor-attribute.html +117 -0
  94. package/docs/crawl/docs/_decorators/auto-subscribe.html +202 -0
  95. package/docs/crawl/docs/_decorators/bind.html +141 -0
  96. package/docs/crawl/docs/_decorators/get.html +149 -0
  97. package/docs/crawl/docs/_decorators/handle.html +165 -0
  98. package/docs/crawl/docs/_decorators/on-assign.html +355 -0
  99. package/docs/crawl/docs/_decorators/patch.html +78 -0
  100. package/docs/crawl/docs/_decorators/post.html +139 -0
  101. package/docs/crawl/docs/_decorators/publish.html +61 -0
  102. package/docs/crawl/docs/_decorators/put.html +78 -0
  103. package/docs/crawl/docs/_decorators/subscribe.html +109 -0
  104. package/docs/crawl/docs/_decorators/wait-for-ancestors.html +137 -0
  105. package/docs/crawl/docs/_directives/sub.html +93 -0
  106. package/docs/crawl/docs/_getting-started/ai-agents.html +173 -0
  107. package/docs/crawl/docs/_getting-started/concorde-manual-install.html +100 -0
  108. package/docs/crawl/docs/_getting-started/concorde-outside.html +58 -0
  109. package/docs/crawl/docs/_getting-started/create-a-component.html +111 -0
  110. package/docs/crawl/docs/_getting-started/my-first-component.html +189 -0
  111. package/docs/crawl/docs/_getting-started/my-first-subscriber.html +110 -0
  112. package/docs/crawl/docs/_getting-started/pubsub.html +62 -0
  113. package/docs/crawl/docs/_getting-started/start.html +76 -0
  114. package/docs/crawl/docs/_getting-started/theming.html +333 -0
  115. package/docs/crawl/docs/_misc/api-configuration.html +149 -0
  116. package/docs/crawl/docs/_misc/dataProviderKey.html +135 -0
  117. package/docs/crawl/docs/_misc/docs-mock-api.html +158 -0
  118. package/docs/crawl/docs/_misc/dynamic-path.html +180 -0
  119. package/docs/crawl/docs/_misc/endpoint.html +50 -0
  120. package/docs/crawl/docs/_misc/formelement-subscriber-removal.html +138 -0
  121. package/docs/crawl/docs/_misc/html-integration.html +48 -0
  122. package/docs/crawl/hubs/decorators.html +547 -0
  123. package/docs/crawl/hubs/form-components.html +381 -0
  124. package/docs/crawl/hubs/remote-data.html +452 -0
  125. package/docs/crawl/index.html +103 -0
  126. package/docs/index.html +1 -1
  127. package/docs/llms-full.txt +7174 -0
  128. package/docs/llms.txt +98 -0
  129. package/docs/sitemap.xml +243 -0
  130. package/docs/src/core/components/functional/date/date.md +290 -0
  131. package/docs/src/core/components/functional/fetch/fetch.md +125 -0
  132. package/docs/src/core/components/functional/if/if.md +9 -0
  133. package/docs/src/core/components/functional/jsonata/jsonata.md +56 -0
  134. package/docs/src/core/components/functional/list/list.md +65 -0
  135. package/docs/src/core/components/functional/mix/mix.md +41 -0
  136. package/docs/src/core/components/functional/queue/queue.md +72 -0
  137. package/docs/src/core/components/functional/router/router.md +94 -0
  138. package/docs/src/core/components/functional/sdui/component-catalog.gaps.json +511 -0
  139. package/docs/src/core/components/functional/sdui/component-catalog.json +3103 -0
  140. package/docs/src/core/components/functional/sdui/default-library.json +108 -0
  141. package/docs/src/core/components/functional/sdui/example.json +99 -0
  142. package/docs/src/core/components/functional/sdui/sdui-extension-points.md +94 -0
  143. package/docs/src/core/components/functional/sdui/sdui.md +478 -0
  144. package/docs/src/core/components/functional/states/states.md +87 -0
  145. package/docs/src/core/components/functional/submit/submit.md +114 -0
  146. package/docs/src/core/components/functional/subscriber/subscriber.md +91 -0
  147. package/docs/src/core/components/functional/value/value.md +35 -0
  148. package/docs/src/core/components/ui/alert/alert.md +196 -0
  149. package/docs/src/core/components/ui/alert-messages/alert-messages.md +85 -0
  150. package/docs/src/core/components/ui/badge/badge.md +188 -0
  151. package/docs/src/core/components/ui/button/button.md +183 -0
  152. package/docs/src/core/components/ui/captcha/captcha.md +71 -0
  153. package/docs/src/core/components/ui/card/card.md +215 -0
  154. package/docs/src/core/components/ui/divider/divider.md +129 -0
  155. package/docs/src/core/components/ui/form/checkbox/checkbox.md +77 -0
  156. package/docs/src/core/components/ui/form/fieldset/fieldset.md +205 -0
  157. package/docs/src/core/components/ui/form/form-actions/form-actions.md +100 -0
  158. package/docs/src/core/components/ui/form/form-layout/form-layout.md +119 -0
  159. package/docs/src/core/components/ui/form/input/input.md +142 -0
  160. package/docs/src/core/components/ui/form/radio/radio.md +57 -0
  161. package/docs/src/core/components/ui/form/select/select.md +71 -0
  162. package/docs/src/core/components/ui/form/switch/switch.md +57 -0
  163. package/docs/src/core/components/ui/form/textarea/textarea.md +65 -0
  164. package/docs/src/core/components/ui/group/group.md +75 -0
  165. package/docs/src/core/components/ui/icon/icon.md +214 -0
  166. package/docs/src/core/components/ui/icon/icons.json +1 -0
  167. package/docs/src/core/components/ui/image/image.md +233 -0
  168. package/docs/src/core/components/ui/link/link.md +81 -0
  169. package/docs/src/core/components/ui/loader/loader.md +112 -0
  170. package/docs/src/core/components/ui/menu/menu.md +370 -0
  171. package/docs/src/core/components/ui/modal/modal.md +235 -0
  172. package/docs/src/core/components/ui/pop/pop.md +294 -0
  173. package/docs/src/core/components/ui/progress/progress.md +109 -0
  174. package/docs/src/core/components/ui/table/table.md +431 -0
  175. package/docs/src/core/components/ui/theme/theme.md +122 -0
  176. package/docs/src/core/components/ui/toast/toast.md +216 -0
  177. package/docs/src/core/components/ui/tooltip/tooltip.md +124 -0
  178. package/{src → docs/src}/docs/_core-concept/subscriber.md +0 -0
  179. package/{src → docs/src}/docs/_getting-started/my-first-subscriber.md +0 -0
  180. package/{src → docs/src}/docs/_getting-started/pubsub.md +0 -0
  181. package/docs/src/docs/_getting-started/theming.md +253 -0
  182. package/docs/src/docs/search/docs-search.json +12242 -0
  183. package/docs/src/tag-list.json +1 -0
  184. package/docs/src/tsconfig-model.json +23 -0
  185. package/docs/src/tsconfig.declarations.json +22 -0
  186. package/docs/src/tsconfig.emit.json +23 -0
  187. package/docs/src/tsconfig.json +1332 -0
  188. package/gitlab/job_github_mirror.sh +39 -0
  189. package/index.html +157 -5
  190. package/package.json +22 -4
  191. package/public/docs-mock-api-sw.js +58 -223
  192. package/public/docs-mock-api-sw.js.map +4 -4
  193. package/public/img/concorde/plane_01.jpg +0 -0
  194. package/public/img/concorde/plane_02.jpg +0 -0
  195. package/public/img/concorde/plane_03.jpg +0 -0
  196. package/public/img/concorde/plane_04.jpg +0 -0
  197. package/public/img/concorde/plane_05.jpg +0 -0
  198. package/public/img/concorde/plane_06.jpg +0 -0
  199. package/public/img/concorde/plane_07.jpg +0 -0
  200. package/public/img/concorde/plane_08.jpg +0 -0
  201. package/public/img/concorde/plane_09.jpg +0 -0
  202. package/public/img/concorde/plane_10.jpg +0 -0
  203. package/public/img/concorde/plane_11.jpg +0 -0
  204. package/public/img/concorde/plane_12.jpg +0 -0
  205. package/public/img/concorde/plane_13.jpg +0 -0
  206. package/public/img/og-concorde.jpg +0 -0
  207. package/public/robots.txt +11 -10
  208. package/scripts/ai-init.mjs +104 -379
  209. package/scripts/ai-init.test.mjs +81 -239
  210. package/scripts/docs-markdown-vite-plugin.ts +43 -0
  211. package/scripts/docs-public-url.mjs +56 -0
  212. package/scripts/docs.htaccess +82 -0
  213. package/scripts/generate-cem.mjs +244 -0
  214. package/scripts/generate-cem.test.mjs +122 -0
  215. package/scripts/generate-crawl-docs.mjs +233 -118
  216. package/scripts/generate-crawl-docs.test.mjs +124 -0
  217. package/scripts/generate-sdui-catalog.mjs +11 -10
  218. package/scripts/github-export.mjs +150 -0
  219. package/scripts/post-build-docs.js +37 -50
  220. package/scripts/post-build.mjs +0 -0
  221. package/scripts/pre-publish.mjs +2 -1
  222. package/scripts/site-pages.mjs +212 -0
  223. package/scripts/site-pages.test.mjs +116 -0
  224. package/site-pages/about.md +22 -0
  225. package/site-pages/privacy.md +32 -0
  226. package/src/core/components/functional/date/date.md +91 -231
  227. package/src/core/components/functional/example/example.ts +3 -1
  228. package/src/core/components/functional/fetch/fetch.md +66 -83
  229. package/src/core/components/functional/if/if.md +28 -3
  230. package/src/core/components/functional/if/if.ts +0 -0
  231. package/src/core/components/functional/jsonata/jsonata.md +42 -37
  232. package/src/core/components/functional/list/list.demo.ts +0 -0
  233. package/src/core/components/functional/list/list.md +103 -43
  234. package/src/core/components/functional/list/list.ts +17 -4
  235. package/src/core/components/functional/mix/mix.md +31 -26
  236. package/src/core/components/functional/queue/queue.demo.ts +10 -7
  237. package/src/core/components/functional/queue/queue.md +40 -61
  238. package/src/core/components/functional/router/router.demo.ts +16 -16
  239. package/src/core/components/functional/router/router.md +64 -65
  240. package/src/core/components/functional/router/router.ts +0 -0
  241. package/src/core/components/functional/sdui/SDUIDescriptorTransformer.ts +0 -0
  242. package/src/core/components/functional/sdui/component-catalog.gaps.json +1 -1
  243. package/src/core/components/functional/sdui/component-catalog.json +2 -2
  244. package/src/core/components/functional/sdui/example.json +19 -86
  245. package/src/core/components/functional/sdui/sdui-extension-points.md +1 -1
  246. package/src/core/components/functional/sdui/sdui-immutable.spec.ts +74 -0
  247. package/src/core/components/functional/sdui/sdui.md +187 -358
  248. package/src/core/components/functional/sdui/sdui.ts +33 -8
  249. package/src/core/components/functional/sdui/types.ts +0 -0
  250. package/src/core/components/functional/states/states.demo.ts +21 -22
  251. package/src/core/components/functional/states/states.md +86 -61
  252. package/src/core/components/functional/states/states.ts +1 -1
  253. package/src/core/components/functional/submit/submit.md +64 -72
  254. package/src/core/components/functional/submit/submit.spec.ts +60 -0
  255. package/src/core/components/functional/submit/submit.ts +6 -3
  256. package/src/core/components/functional/subscriber/subscriber.ts +0 -0
  257. package/src/core/components/functional/translation/translation.md +38 -0
  258. package/src/core/components/functional/value/value.md +34 -22
  259. package/src/core/components/functional/value/value.ts +0 -0
  260. package/src/core/components/ui/_css/size.ts +0 -0
  261. package/src/core/components/ui/alert/alert.md +48 -58
  262. package/src/core/components/ui/badge/badge.md +27 -34
  263. package/src/core/components/ui/button/button.md +139 -106
  264. package/src/core/components/ui/captcha/altchaStyles.ts +0 -0
  265. package/src/core/components/ui/captcha/captcha.md +17 -32
  266. package/src/core/components/ui/card/card.md +6 -6
  267. package/src/core/components/ui/divider/divider.md +8 -11
  268. package/src/core/components/ui/form/checkbox/checkbox.md +90 -42
  269. package/src/core/components/ui/form/fieldset/fieldset.md +31 -75
  270. package/src/core/components/ui/form/form-actions/form-actions.md +14 -16
  271. package/src/core/components/ui/form/form-layout/form-layout.md +19 -29
  272. package/src/core/components/ui/form/input/input.md +108 -90
  273. package/src/core/components/ui/form/input/input.ts +8 -2
  274. package/src/core/components/ui/form/radio/radio.md +65 -30
  275. package/src/core/components/ui/form/select/select.md +60 -45
  276. package/src/core/components/ui/form/switch/switch.md +57 -34
  277. package/src/core/components/ui/form/textarea/textarea.md +55 -38
  278. package/src/core/components/ui/group/group.md +35 -33
  279. package/src/core/components/ui/icon/icon.md +4 -4
  280. package/src/core/components/ui/image/image.md +41 -107
  281. package/src/core/components/ui/link/link.md +6 -6
  282. package/src/core/components/ui/loader/loader.md +30 -55
  283. package/src/core/components/ui/menu/menu.md +27 -27
  284. package/src/core/components/ui/modal/modal.md +72 -96
  285. package/src/core/components/ui/pop/pop.md +80 -158
  286. package/src/core/components/ui/progress/progress.md +2 -2
  287. package/src/core/components/ui/table/table.md +91 -255
  288. package/src/core/components/ui/theme/theme.md +11 -36
  289. package/src/core/components/ui/toast/toast.md +48 -117
  290. package/src/core/components/ui/tooltip/tooltip.md +27 -62
  291. package/src/core/decorators/subscriber/bind.ts +9 -14
  292. package/src/core/decorators/subscriber/subscribe.ts +15 -9
  293. package/src/core/decorators/subscriber/subscribe.type-test.ts +14 -5
  294. package/src/core/mixins/Subscriber.ts +0 -0
  295. package/src/core/utils/DataBindObserver.ts +0 -0
  296. package/src/core/utils/LocationHandler.spec.ts +80 -0
  297. package/src/core/utils/LocationHandler.ts +5 -9
  298. package/src/core/utils/Objects.ts +0 -0
  299. package/src/core/utils/PublisherProxy.ts +166 -125
  300. package/src/core/utils/deepReadonly.spec.ts +66 -0
  301. package/src/core/utils/deepReadonly.ts +71 -0
  302. package/src/core/utils/immutableValue.spec.ts +54 -0
  303. package/src/core/utils/immutableValue.ts +102 -0
  304. package/src/core/utils/nestedDotForm.spec.ts +88 -0
  305. package/src/core/utils/publisherImmutable.spec.ts +76 -0
  306. package/src/core/utils/route.ts +0 -0
  307. package/src/core/utils/strictGet.spec.ts +61 -0
  308. package/src/core/utils/strictGet.ts +102 -0
  309. package/src/css.d.ts +19 -0
  310. package/src/docs/components/docs-demo-sources.ts +55 -140
  311. package/src/docs/components/docs-lit-demo.ts +1 -3
  312. package/src/docs/components/docs-source-link.ts +0 -82
  313. package/src/docs/decorators/ancestor-attribute.md +59 -0
  314. package/src/docs/decorators/auto-subscribe.md +40 -0
  315. package/src/docs/decorators/bind.md +76 -0
  316. package/src/docs/decorators/get.md +160 -0
  317. package/src/docs/decorators/handle.md +119 -0
  318. package/src/docs/decorators/on-assign.md +63 -0
  319. package/src/docs/decorators/patch.md +44 -0
  320. package/src/docs/decorators/post.md +134 -0
  321. package/src/docs/decorators/publish.md +56 -0
  322. package/src/docs/decorators/put.md +51 -0
  323. package/src/docs/decorators/subscribe.md +87 -0
  324. package/src/docs/decorators/wait-for-ancestors.md +76 -0
  325. package/src/docs/directives/sub.md +75 -0
  326. package/src/docs/directives/t.md +73 -0
  327. package/src/docs/docs-location.spec.ts +56 -0
  328. package/src/docs/docs-location.ts +133 -32
  329. package/src/docs/docs.ts +1 -2
  330. package/src/docs/example/decorators-demo-bind-demos.ts +83 -135
  331. package/src/docs/example/decorators-demo-geo.ts +30 -19
  332. package/src/docs/example/decorators-demo-post.ts +88 -186
  333. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +165 -268
  334. package/src/docs/example/decorators-demo.ts +85 -98
  335. package/src/docs/example/docs-api-config-demos.ts +19 -20
  336. package/src/docs/example/docs-flight-demos.ts +147 -0
  337. package/src/docs/example/docs-jsonata-demos.ts +52 -52
  338. package/src/docs/example/docs-list-demos.ts +43 -123
  339. package/src/docs/example/docs-provider-keys.ts +21 -28
  340. package/src/docs/example/docs-queue-demos.ts +37 -77
  341. package/src/docs/example/docs-router-demos.ts +20 -25
  342. package/src/docs/example/docs-submit-demos.ts +48 -48
  343. package/src/docs/example/docs-toggle-demos.ts +4 -3
  344. package/src/docs/example/users.ts +0 -0
  345. package/src/docs/getting-started/ai-agents.md +50 -0
  346. package/src/docs/getting-started/create-a-component.md +136 -0
  347. package/src/docs/getting-started/dataFlow.md +87 -0
  348. package/src/docs/getting-started/installation.md +36 -0
  349. package/src/docs/getting-started/my-first-component.md +227 -0
  350. package/src/docs/getting-started/start.md +35 -0
  351. package/src/docs/header/header.ts +11 -6
  352. package/src/docs/home/catalog.ts +1 -1
  353. package/src/docs/home/home.ts +20 -11
  354. package/src/docs/layout.ts +12 -13
  355. package/src/docs/misc/api-configuration.md +79 -0
  356. package/src/docs/misc/dataProviderKey.md +168 -0
  357. package/src/docs/misc/docs-mock-api.md +62 -0
  358. package/src/docs/misc/dynamic-path.md +71 -0
  359. package/src/docs/misc/endpoint.md +45 -0
  360. package/src/docs/misc/html-integration.md +14 -0
  361. package/src/docs/misc/publisher-get-immutability-docs-crawl.json +902 -0
  362. package/src/docs/misc/publisher-get-immutability-docs-recheck.json +13 -0
  363. package/src/docs/misc/publisher-get-immutability-study.md +229 -0
  364. package/src/docs/mock-api/api-config-mock.ts +5 -0
  365. package/src/docs/mock-api/fixtures.ts +0 -278
  366. package/src/docs/mock-api/flights.ts +89 -0
  367. package/src/docs/mock-api/router.ts +3 -4
  368. package/src/docs/mock-api/urls.ts +1 -2
  369. package/src/docs/navigation/navigation.ts +84 -101
  370. package/src/docs/navigation/toc.ts +7 -4
  371. package/src/docs/search/docs-search.json +3188 -5153
  372. package/src/docs/search/markdown-renderer.ts +31 -8
  373. package/src/docs/search/page.ts +9 -6
  374. package/src/docs/search/search.ts +154 -122
  375. package/src/docs/tailwind/css/docs/content.css +4 -5
  376. package/src/tsconfig.declarations.json +22 -0
  377. package/src/tsconfig.emit.json +23 -0
  378. package/src/tsconfig.json +53 -5
  379. package/src/tsconfig.tsbuildinfo +1 -1
  380. package/vite.config.mts +11 -2
  381. package/.agents/skills/concorde-component-docs/SKILL.md +0 -194
  382. package/.taste-skill/after/desktop-fold.jpg +0 -0
  383. package/.taste-skill/after/desktop-page-01.jpg +0 -0
  384. package/.taste-skill/after/desktop-page-02.jpg +0 -0
  385. package/.taste-skill/after/desktop-page-03.jpg +0 -0
  386. package/.taste-skill/after/mobile-fold.jpg +0 -0
  387. package/.taste-skill/after/mobile-page-01.jpg +0 -0
  388. package/.taste-skill/after/report.json +0 -4103
  389. package/.taste-skill/after/tablet-fold.jpg +0 -0
  390. package/.taste-skill/after/tablet-page-01.jpg +0 -0
  391. package/.taste-skill/after/tablet-page-02.jpg +0 -0
  392. package/.taste-skill/before/desktop-fold.jpg +0 -0
  393. package/.taste-skill/before/desktop-page-01.jpg +0 -0
  394. package/.taste-skill/before/desktop-page-02.jpg +0 -0
  395. package/.taste-skill/before/mobile-fold.jpg +0 -0
  396. package/.taste-skill/before/mobile-page-01.jpg +0 -0
  397. package/.taste-skill/before/report.json +0 -2556
  398. package/.taste-skill/before/tablet-fold.jpg +0 -0
  399. package/.taste-skill/before/tablet-page-01.jpg +0 -0
  400. package/.taste-skill/direction.json +0 -510
  401. package/.taste-skill/notes.md +0 -84
  402. package/.taste-skill/prod/desktop-fold.jpg +0 -0
  403. package/.taste-skill/prod/desktop-page-01.jpg +0 -0
  404. package/.taste-skill/prod/desktop-page-02.jpg +0 -0
  405. package/.taste-skill/prod/desktop-page-03.jpg +0 -0
  406. package/.taste-skill/prod/mobile-fold.jpg +0 -0
  407. package/.taste-skill/prod/mobile-page-01.jpg +0 -0
  408. package/.taste-skill/prod/mobile-page-02.jpg +0 -0
  409. package/.taste-skill/prod/report.json +0 -1973
  410. package/.taste-skill/prod/tablet-fold.jpg +0 -0
  411. package/.taste-skill/prod/tablet-page-01.jpg +0 -0
  412. package/.taste-skill/prod/tablet-page-02.jpg +0 -0
  413. package/AUDIT.md +0 -228
  414. package/PLAN-AMELIORATION.md +0 -220
  415. package/ai/AGENTS.md +0 -56
  416. package/ai/cursor/rules/concorde-menu.mdc +0 -15
  417. package/ai/cursor/rules/concorde-scope.mdc +0 -14
  418. package/ai/cursor/rules/concorde-theme.mdc +0 -13
  419. package/ai/cursor/rules/concorde.mdc +0 -66
  420. package/ai/jetbrains/rules/concorde.md +0 -53
  421. package/ai/skills/concorde-get-set-dp/SKILL.md +0 -194
  422. package/ai/skills/concorde-imports/SKILL.md +0 -78
  423. package/ai/skills/concorde-menu/SKILL.md +0 -74
  424. package/ai/skills/concorde-scope/SKILL.md +0 -70
  425. package/ai/skills/concorde-theme/SKILL.md +0 -57
  426. package/docs/assets/index-Bb-_LRyY.js +0 -12280
  427. package/src/docs/example/docs-input-autocomplete-demos.ts +0 -110
  428. package/src/docs/example/docs-joke-demos.ts +0 -297
  429. /package/{src → docs/src}/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -0
  430. /package/{src → docs/src}/docs/_core-concept/dataFlow.md +0 -0
  431. /package/{src → docs/src}/docs/_core-concept/overview.md +0 -0
  432. /package/{src → docs/src}/docs/_decorators/ancestor-attribute.md +0 -0
  433. /package/{src → docs/src}/docs/_decorators/auto-subscribe.md +0 -0
  434. /package/{src → docs/src}/docs/_decorators/bind.md +0 -0
  435. /package/{src → docs/src}/docs/_decorators/get.md +0 -0
  436. /package/{src → docs/src}/docs/_decorators/handle.md +0 -0
  437. /package/{src → docs/src}/docs/_decorators/on-assign.md +0 -0
  438. /package/{src → docs/src}/docs/_decorators/patch.md +0 -0
  439. /package/{src → docs/src}/docs/_decorators/post.md +0 -0
  440. /package/{src → docs/src}/docs/_decorators/publish.md +0 -0
  441. /package/{src → docs/src}/docs/_decorators/put.md +0 -0
  442. /package/{src → docs/src}/docs/_decorators/subscribe.md +0 -0
  443. /package/{src → docs/src}/docs/_decorators/wait-for-ancestors.md +0 -0
  444. /package/{src → docs/src}/docs/_directives/sub.md +0 -0
  445. /package/{src → docs/src}/docs/_getting-started/ai-agents.md +0 -0
  446. /package/{src → docs/src}/docs/_getting-started/concorde-manual-install.md +0 -0
  447. /package/{src → docs/src}/docs/_getting-started/concorde-outside.md +0 -0
  448. /package/{src → docs/src}/docs/_getting-started/create-a-component.md +0 -0
  449. /package/{src → docs/src}/docs/_getting-started/my-first-component.md +0 -0
  450. /package/{src → docs/src}/docs/_getting-started/start.md +0 -0
  451. /package/{src → docs/src}/docs/_misc/api-configuration.md +0 -0
  452. /package/{src → docs/src}/docs/_misc/dataProviderKey.md +0 -0
  453. /package/{src → docs/src}/docs/_misc/docs-mock-api.md +0 -0
  454. /package/{src → docs/src}/docs/_misc/dynamic-path.md +0 -0
  455. /package/{src → docs/src}/docs/_misc/endpoint.md +0 -0
  456. /package/{src → docs/src}/docs/_misc/formelement-subscriber-removal.md +0 -0
  457. /package/{src → docs/src}/docs/_misc/html-integration.md +0 -0
  458. /package/src/docs/{_getting-started → getting-started}/components.md +0 -0
  459. /package/src/docs/{_getting-started → getting-started}/theming.md +0 -0
@@ -0,0 +1,13 @@
1
+ {
2
+ "generatedAt": "2026-10-29T14:46:01.703Z",
3
+ "baseA": "https://127.0.0.1:3010",
4
+ "baseB": "https://127.0.0.1:3011",
5
+ "pageCount": 43,
6
+ "pagesWithDiffs": 0,
7
+ "diffs": [],
8
+ "summary": {
9
+ "errors": [],
10
+ "warns": [],
11
+ "infos": []
12
+ }
13
+ }
@@ -0,0 +1,229 @@
1
+ # Étude — immutabilité DataProvider / `get()` (REDMINE-79567)
2
+
3
+ > **Nature :** étude d’opportunité + ADR de direction.
4
+ > Branche : `79567_publisher_get_immutability_study`.
5
+ > **Recadrage (oct. 2026) :** la cible n’est plus un empilement de gardes opt-in, mais un **store immutable** clair.
6
+
7
+ ## 0. Décision de direction (ADR)
8
+
9
+ ### Contrat cible
10
+
11
+ > **Le publisher possède les données. On ne mute jamais. On remplace.**
12
+
13
+ | API | Comportement |
14
+ |-----|----------------|
15
+ | `set(value)` / `update(recipe)` | Ownership à l’entrée : copie (clone / Immer `produce`), commit, puis **freeze** (ou équivalent) de la valeur stockée |
16
+ | `get()` | Vue **lecture seule** de la valeur commitée — muter → erreur nette |
17
+ | Écritures | Uniquement `set` / `setIn` / `update` — plus de patch in-place de `_value_` |
18
+ | Comportement | **Un seul** en prod (pas de mode « soft » comme design final) |
19
+
20
+ ### Ce qu’on ne garde pas comme design produit
21
+
22
+ Empiler `DeepReadonly` + `strictGet` warn/throw + clone parfois = **pansements** autour d’un moteur encore mutable. Utile en **radar de migration**, pas comme architecture cible.
23
+
24
+ ### Conséquence technique
25
+
26
+ Refonte du moteur `PublisherProxy` : plus de `_value_[k] = …` / `delete _value_[k]` / sync parent par mutation. Updates **immutables** (Immer ou `setIn` maison) sur tout chemin d’écriture (y compris traps Proxy / sous-proxies).
27
+
28
+ ---
29
+
30
+ ## 1. Problème (rappel)
31
+
32
+ Aujourd’hui `get()` renvoie la **référence live** de `_value_`. Une mutation locale (`cart.items.push…`) contourne `set` et les listeners → état partagé / UI désynchronisés.
33
+
34
+ Écritures « officielles » (`set`, sous-proxies, `publisher.clé = …`) notifient ; le trou est **get + mutation** et **réutilisation de la ref passée à `set`**.
35
+
36
+ Fichier central : `src/core/utils/PublisherProxy.ts`.
37
+
38
+ ---
39
+
40
+ ## 2. Alternatives évaluées
41
+
42
+ | | Approche | Verdict |
43
+ |---|----------|---------|
44
+ | A | Freeze live **sans** refonte `set` | **Non** — casse le moteur actuel |
45
+ | B | Clone / Proxy readonly à chaque `get()` | **Non** comme défaut — cher, identité cassée |
46
+ | C | Clone défensif seul sans freeze | **Insuffisant** — n’enseigne pas le contrat |
47
+ | D | `strictGet` opt-in warn/throw | **Outil de migration** seulement |
48
+ | E | Lint / convention seule | **Complément**, pas une garantie |
49
+ | F | **Store immutable** (set ownership + get readonly + updates immutables) | **Cible** |
50
+
51
+ ### Perf (ordre de grandeur)
52
+
53
+ 1. Status quo / typage seul — 0 runtime
54
+ 2. Proxy `strictGet` — faible, sur `get`
55
+ 3. Freeze **après** commit immutable — lectures cheap ; coût sur **écritures**
56
+ 4. Deep clone à chaque `get` — à éviter
57
+ 5. Freeze live + mute in-place — incompatible
58
+
59
+ Le modèle F met le coût là où il est acceptable (écritures), avec une sémantique nette.
60
+
61
+ ---
62
+
63
+ ## 3. Cible — store immutable (détail)
64
+
65
+ ### 3.1 Moteur Concorde à réécrire
66
+
67
+ - `set` / traps Proxy / sync parent-enfant : **immutable updates** uniquement.
68
+ - Après commit : freeze deep (ou structure déjà immutable).
69
+ - `get()` / `onAssign` : renvoient la valeur frozen (même ref tant que le commit n’a pas changé → `get() === get()` OK entre deux `set`).
70
+ - API `update(draft => { … })` (Immer) recommandée pour les updates nested ergonomiques.
71
+ - Valeurs non clonables (`EventSource`, instances, fonctions) : **hors store** ou wrappers documentés (ex. Mercure / laqueue).
72
+
73
+ ### 3.2 Surface apps
74
+
75
+ - Interdit : muter après `get`, muter la ref passée à `set`, `.sort()` in-place dans `onAssign`.
76
+ - Obligatoire : `const next = …; set(next)` ou `update(draft => …)`.
77
+
78
+ ### 3.3 Rôle du spike actuel sur cette branche
79
+
80
+ Déjà présent (ne pas confondre avec la cible) :
81
+
82
+ - `DeepReadonly` sur `get` / `onAssign` (typage).
83
+ - `PublisherManager.strictGet = "off" | "warn" | "throw"` (Proxy sur le résultat de `get`, **sans** freeze de `_value_`).
84
+
85
+ → **Radar** pour lister les mutations pendant la migration vers F. Destiné à disparaître ou à se réduire une fois le moteur immutable en place.
86
+
87
+ ---
88
+
89
+ ## 4. Canal de livraison — dist-tag npm (reco)
90
+
91
+ Oui : publier le chantier sur un **dist-tag npm dédié**, pas sur `latest`, le temps d’un usage approfondi.
92
+
93
+ ### Pourquoi c’est adapté ici
94
+
95
+ - Breaking **moteur + contrat** : les apps ne doivent pas le prendre par un bump semver « normal » par erreur.
96
+ - Billetterie / smart-belt / lecovoit / laqueue peuvent opter **explicitement** :
97
+ `"@supersoniks/concorde": "npm:@supersoniks/concorde@immutable"`
98
+ ou version `5.x.x-immutable.n` + tag `immutable`.
99
+ - CI / smokes sur le tag sans bloquer prod `latest`.
100
+ - Feedback réel (perf panier, Mercure, placement) avant major.
101
+
102
+ ### Proposition de tags
103
+
104
+ | Tag | Usage |
105
+ |-----|--------|
106
+ | `latest` | Ligne stable actuelle (mutable + éventuellement radar `strictGet` si un jour mergé à part) |
107
+ | `immutable` (ou `next-immutable`) | Ligne de dev du store immutable — **usage approfondi** |
108
+ | (plus tard) `latest` major | Quand la migration Billetterie + checklist sont vertes |
109
+
110
+ Versions du type `6.0.0-immutable.1`, `.2`, … (prerelease) : claires dans le lockfile, republish fréquentes OK.
111
+
112
+ ### Ce qu’il ne faut pas faire
113
+
114
+ - Remplacer `latest` trop tôt.
115
+ - Multiplier les tags flous (`test`, `julien`, …) — **un** tag métier `immutable`.
116
+ - Laisser `strictGet` opt-in comme « la » release : ce n’est pas le produit final.
117
+
118
+ ### Avis
119
+
120
+ **Go dist-tag `immutable`.** C’est le bon niveau de netteté : chantier puissant isolé, adoption volontaire, mesure avant major. Le spike `strictGet` peut vivre sur la même branche/tag comme aide à la migration, documenté comme temporaire.
121
+
122
+ ---
123
+
124
+ ## 5. Impact consommateurs (rappel audit)
125
+
126
+ | Projet | Volume / note | Priorité migration |
127
+ |--------|----------------|-------------------|
128
+ | **la-billetterie** | ~860 fichiers dp, ~216 get / ~392 set ; cart, AC, placing, forms | **P0** |
129
+ | smart-belt-drive | Peu de get ; `onAssign` + `.sort()` in-place | P1 |
130
+ | lecovoit | Peu de get, surtout set | P2 |
131
+ | laqueue | Très peu ; Mercure / non-clonables à traiter | P2 |
132
+ | link / starter | Faible | P3 |
133
+
134
+ Zones Billetterie chaudes : `access-control/**`, `utils/cart.ts` + `components/cart/**`, `placing/**`, subscription / tarifs, forms, ~300 `onAssign`, legacy `lb_placement` JS.
135
+
136
+ ---
137
+
138
+ ## 6. Plan recadré
139
+
140
+ ```
141
+ Phase 0 Étude + ADR direction immutable ✅
142
+ Phase 1 Radar DeepReadonly + strictGet ✅
143
+ Phase 2 Moteur immutable sur branche ✅ → publish npm tag `immutable`
144
+ Phase 3 App pilote sur le tag
145
+ Phase 4 Billetterie (puis SBD, lecovoit, laqueue) sur le tag
146
+ Phase 5 Major Concorde sur `latest` quand go-live OK
147
+ ```
148
+
149
+ ### Critères go-live major
150
+
151
+ - Smokes Billetterie (panier, placing, AC, forms, abonnements, submit, localStorage) verts sur le tag.
152
+ - Pas de régression perf au-delà du seuil convenu sur écritures panier / scan.
153
+ - Doc dataFlow = contrat immutable uniquement.
154
+ - Stratégie explicite pour non-clonables.
155
+ - `strictGet` retiré ou réduit à un assert interne inutile en prod.
156
+
157
+ ---
158
+
159
+ ## 7. Verdict
160
+
161
+ | Question | Réponse |
162
+ |----------|---------|
163
+ | Problème de contrat réel ? | **Oui** |
164
+ | Design cible ? | **Store immutable** (F), pas la pile de gardes |
165
+ | Freeze live sans refonte ? | **Non** |
166
+ | Clone à chaque `get` ? | **Non** |
167
+ | `strictGet` / `DeepReadonly` ? | **Radar de migration**, pas la cible |
168
+ | Publier sur un tag npm dédié pendant le dev ? | **Oui — `immutable`** |
169
+ | Ce ticket 79567 | Étude + direction ; chantier moteur = ticket(s) d’implémentation + tag |
170
+
171
+ ## 8. Suite immédiate
172
+
173
+ 1. Publish dist-tag npm `immutable` depuis cette branche.
174
+ 2. App pilote (starter / module Billetterie borné).
175
+ 3. Migration Billetterie + smokes.
176
+ 4. Major sur `latest` quand critères § go-live OK.
177
+
178
+ ## 9. Implémenté sur la branche
179
+
180
+ - Helpers : `src/core/utils/immutableValue.ts` (`takeOwnership`, `deepFreeze`, `setAtKey`, `deleteAtKey`)
181
+ - `PublisherProxy.set` : ownership + freeze ; sync parent immutable (plus de `_value_[k] =`)
182
+ - Traps Proxy `set` / `deleteProperty` : via `set` / rebuild
183
+ - `get()` : valeur frozen (même ref jusqu’au prochain `set`)
184
+ - Non-clonable : warn + stocké tel quel sans freeze
185
+ - Specs : `immutableValue.spec.ts`, `publisherImmutable.spec.ts`, etc.
186
+ - Correctifs doc/runtime déjà livrés sur la branche : boucle `sonic-list` / `_metadata_`, clone SDUI, shallow-copy submit, `sameValueAs` en dot-notation
187
+
188
+ ## 10. Crawl docs rendu — branche vs `master` (29 oct. 2026)
189
+
190
+ Comparaison automatisée des pages de la nav docs : **A** = branche `79567_publisher_get_immutability_study`, **B** = `master`.
191
+
192
+ Métriques : `bodyChars`, sections `h2`, blocs `sonic-code` (radios/inputs/lists/sdui + hauteurs interactives), `docs-lit-demo`, erreurs console (hors bruit SW 404).
193
+
194
+ Artefacts JSON (bruts) :
195
+
196
+ - `src/docs/misc/publisher-get-immutability-docs-crawl.json` — 68 pages (crawl parallèle initial)
197
+ - `src/docs/misc/publisher-get-immutability-docs-recheck.json` — 43 pages à risque (crawl séquentiel)
198
+
199
+ ### Résultat
200
+
201
+ | Passe | Pages | Diffs structurantes (error) | Notes |
202
+ |-------|------:|----------------------------:|-------|
203
+ | Recheck séquentiel | 43 | **0** | Pas de contrôle disparu, pas de preview collapsée, pas d’erreur freeze |
204
+ | Crawl parallèle 68 | 68 | **0** error | 5 pages avec diffs info/warn uniquement |
205
+
206
+ ### Diffs relevés (pas de régression immutable)
207
+
208
+ | Page | Nature | Action |
209
+ |------|--------|--------|
210
+ | `/core/components/ui/form/radio` | Section **Nested keys** ajoutée sur la branche | Doc volontaire — à garder ou retirer selon review doc |
211
+ | `/core/components/ui/form/input` | Idem Nested keys + `sameValueAs` dot-notation | Idem |
212
+ | `/docs/directives/t` | Contenu plus riche sur A (sections Import/Usage/…) | Hors immutable — écart de contenu markdown ; vérifier si attendu sur la branche |
213
+ | `/docs/misc/dataProviderKey` | Faux positif crawl parallèle (`bodyChars: 0`) | **Revalidé OK** au recheck / visite manuelle (2615 chars, 9 codes) |
214
+ | `/docs/misc/html-integration` | Console `498` ponctuelle au crawl parallèle | **Revalidé OK** (même rendu A/B, 838 chars) — bruit réseau, pas un gel publisher |
215
+
216
+ ### Correctifs déjà faits (hors crawl, signalés avant)
217
+
218
+ - `sonic-list` boucle infinie (`_metadata_`)
219
+ - SDUI mute sur descripteur frozen
220
+ - Submit `delete` sur `get()` frozen
221
+
222
+ ### À corriger ultérieurement (backlog crawl)
223
+
224
+ 1. **Décider** du sort des sections Nested keys radio/input (ajoutées pendant le debug) — doc only.
225
+ 2. **Vérifier** l’écart markdown `docs/directives/t` vs `master` (pas lié au store).
226
+ 3. Rejouer le crawl séquentiel après les prochains correctifs moteur avant publish tag `immutable`.
227
+ 4. Optionnel : intégrer le script de crawl dans un smoke CI docs (ports dédiés + Chromium system).
228
+
229
+ **Verdict crawl :** pas de régression de rendu docs imputable au store immutable sur l’échantillon recheck (43 pages). Les seuls écarts stables sont documentaires (Nested keys, éventuellement `t`).
@@ -15,6 +15,11 @@ export const DOCS_MOCK_EVENTS_API_TOKEN = "docs-mock-events-token";
15
15
  const WORDING_CATALOG: Record<string, Record<string, string>> = {
16
16
  "api-config.greeting": { fr: "Bonjour", en: "Hello" },
17
17
  "api-config.farewell": { fr: "Au revoir", en: "Goodbye" },
18
+ "flight.boarding": { fr: "Embarquement immédiat", en: "Now boarding" },
19
+ "flight.gate": {
20
+ fr: "Rendez-vous porte <strong>B12</strong>",
21
+ en: "Please proceed to gate <strong>B12</strong>",
22
+ },
18
23
  "api-config.hint": {
19
24
  fr: "Libellés servis par le mock /wording/labels",
20
25
  en: "Labels served by mock /wording/labels",
@@ -97,281 +97,3 @@ export const DOCS_GEO_COMMUNES: GeoCommuneRow[] = [
97
97
  { nom: "Montpellier", code: "34172" },
98
98
  { nom: "Rennes", code: "35238" },
99
99
  ];
100
-
101
- /** JokeAPI-style content flags (checkbox / radio / switch blacklist demos). */
102
- export type DocsJokeFlagKey =
103
- | "nsfw"
104
- | "religious"
105
- | "political"
106
- | "racist"
107
- | "sexist"
108
- | "explicit";
109
-
110
- /** Forme proche de JokeAPI v2 (`key="jokes"` sur sonic-queue / list). */
111
- export type DocsJokeItem = {
112
- categories: string[];
113
- createdAt: string;
114
- id: number;
115
- joke: string;
116
- lang: "fr" | "en";
117
- flags: Record<DocsJokeFlagKey, boolean>;
118
- safe: boolean;
119
- type: string;
120
- setup?: string;
121
- delivery?: string;
122
- };
123
-
124
- const jokeFlags = (
125
- partial: Partial<Record<DocsJokeFlagKey, boolean>> = {},
126
- ): Record<DocsJokeFlagKey, boolean> => ({
127
- nsfw: false,
128
- religious: false,
129
- political: false,
130
- racist: false,
131
- sexist: false,
132
- explicit: false,
133
- ...partial,
134
- });
135
-
136
- export type DocsJokeApiResponse = {
137
- error: boolean;
138
- amount: number;
139
- jokes: DocsJokeItem[];
140
- };
141
-
142
- const SAMPLE_JOKES: DocsJokeItem[] = [
143
- {
144
- categories: ["Programming"],
145
- createdAt: "2020-01-01 00:00:00",
146
- id: 1,
147
- lang: "en",
148
- joke: "Why do programmers prefer dark mode? Because light attracts bugs.",
149
- flags: jokeFlags(),
150
- safe: true,
151
- type: "single",
152
- },
153
- {
154
- categories: ["Misc"],
155
- createdAt: "2020-01-02 00:00:00",
156
- id: 2,
157
- lang: "en",
158
- joke: "I told my computer I needed a break — it said: no problem, I'll go to sleep.",
159
- flags: jokeFlags({ nsfw: true }),
160
- safe: false,
161
- type: "single",
162
- },
163
- {
164
- categories: ["Pun"],
165
- createdAt: "2020-01-03 00:00:00",
166
- id: 3,
167
- lang: "en",
168
- joke: "Concorde docs run offline: even the API is a local joke.",
169
- flags: jokeFlags(),
170
- safe: true,
171
- type: "single",
172
- },
173
- {
174
- categories: ["Animals"],
175
- createdAt: "2020-01-04 00:00:00",
176
- id: 4,
177
- lang: "en",
178
- joke: "The dog ate my homework and my pull request.",
179
- flags: jokeFlags({ political: true }),
180
- safe: true,
181
- type: "single",
182
- },
183
- {
184
- categories: ["Animals", "Pun"],
185
- createdAt: "2020-01-05 00:00:00",
186
- id: 5,
187
- lang: "fr",
188
- joke: "Quel est le chien préféré des développeurs ? Le labrador Retriever.",
189
- flags: jokeFlags(),
190
- safe: true,
191
- type: "single",
192
- },
193
- {
194
- categories: ["Animals"],
195
- createdAt: "2020-01-06 00:00:00",
196
- id: 6,
197
- lang: "fr",
198
- joke: "Un chat et un chien discutent de TypeScript : le chien dit « woof », le chat compile.",
199
- flags: jokeFlags({ racist: true }),
200
- safe: false,
201
- type: "single",
202
- },
203
- {
204
- categories: ["Misc"],
205
- createdAt: "2020-01-07 00:00:00",
206
- id: 7,
207
- lang: "fr",
208
- joke: "Pourquoi les blagues offline sont-elles fiables ? Parce qu'elles passent par le Service Worker.",
209
- flags: jokeFlags({ religious: true }),
210
- safe: true,
211
- type: "single",
212
- },
213
- {
214
- categories: ["Programming"],
215
- createdAt: "2020-01-08 00:00:00",
216
- id: 8,
217
- lang: "fr",
218
- joke: "Mon compilateur et mon chien : tous deux ignorent mes commandes jusqu'au build.",
219
- flags: jokeFlags({ sexist: true }),
220
- safe: false,
221
- type: "single",
222
- },
223
- {
224
- categories: ["Misc"],
225
- createdAt: "2020-01-09 00:00:00",
226
- id: 9,
227
- lang: "en",
228
- joke: "A SQL query walks into a bar, walks up to two tables and asks: Can I join you?",
229
- flags: jokeFlags({ explicit: true }),
230
- safe: false,
231
- type: "single",
232
- },
233
- {
234
- categories: ["Pun"],
235
- createdAt: "2020-01-10 00:00:00",
236
- id: 10,
237
- lang: "fr",
238
- joke: "J'ai cherché « chien » dans la doc : le mock API a répondu.",
239
- flags: jokeFlags(),
240
- safe: true,
241
- type: "single",
242
- },
243
- {
244
- categories: ["Misc"],
245
- createdAt: "2020-01-11 00:00:00",
246
- id: 11,
247
- lang: "en",
248
- joke: "There are only two hard things in Computer Science: cache invalidation and naming things.",
249
- flags: jokeFlags({ political: true, explicit: true }),
250
- safe: false,
251
- type: "single",
252
- },
253
- {
254
- categories: ["Animals"],
255
- createdAt: "2020-01-12 00:00:00",
256
- id: 12,
257
- lang: "fr",
258
- joke: "Le golden retriever a récupéré la donnée du publisher.",
259
- flags: jokeFlags({ racist: true, sexist: true }),
260
- safe: false,
261
- type: "two-liner",
262
- setup: "Pourquoi le chien aime Concorde ?",
263
- delivery: "Parce qu'il sait fetch.",
264
- },
265
- {
266
- categories: ["Misc"],
267
- createdAt: "2020-01-13 00:00:00",
268
- id: 13,
269
- lang: "en",
270
- joke: "My code and my conscience: both have too many warnings.",
271
- flags: jokeFlags(),
272
- safe: true,
273
- type: "single",
274
- },
275
- {
276
- categories: ["Programming"],
277
- createdAt: "2020-01-14 00:00:00",
278
- id: 14,
279
- lang: "en",
280
- joke: "Git blame is just a mirror.",
281
- flags: jokeFlags({ religious: true, political: true }),
282
- safe: false,
283
- type: "single",
284
- },
285
- ];
286
-
287
- /** `blacklistFlags` from queue filter form (comma-separated or repeated param). */
288
- export function parseBlacklistFlags(url: URL): DocsJokeFlagKey[] {
289
- const keys = new Set<DocsJokeFlagKey>();
290
- const valid: DocsJokeFlagKey[] = [
291
- "nsfw",
292
- "religious",
293
- "political",
294
- "racist",
295
- "sexist",
296
- "explicit",
297
- ];
298
- const add = (raw: string) => {
299
- raw
300
- .split(",")
301
- .map((s) => s.trim().toLowerCase())
302
- .forEach((part) => {
303
- if (valid.includes(part as DocsJokeFlagKey)) keys.add(part as DocsJokeFlagKey);
304
- });
305
- };
306
- url.searchParams.getAll("blacklistFlags").forEach(add);
307
- const single = url.searchParams.get("blacklistFlags");
308
- if (single) add(single);
309
- return [...keys];
310
- }
311
-
312
- /** Exclude jokes that match any blacklisted flag (JokeAPI-style). */
313
- export function applyJokeBlacklist(
314
- jokes: DocsJokeItem[],
315
- blacklist: DocsJokeFlagKey[],
316
- ): DocsJokeItem[] {
317
- if (!blacklist.length) return jokes;
318
- return jokes.filter(
319
- (j) => !blacklist.some((flag) => j.flags[flag] === true),
320
- );
321
- }
322
-
323
- /** Filtre doc joke queue (`contains`, `lang`, `blacklistFlags` via `dataFilterProvider`). */
324
- export function filterDocsJokes(
325
- jokes: DocsJokeItem[],
326
- url: URL,
327
- ): DocsJokeItem[] {
328
- let pool = jokes;
329
- const contains = url.searchParams.get("contains")?.trim().toLowerCase();
330
- if (contains) {
331
- pool = pool.filter((j) => {
332
- const haystack = [j.joke, j.setup, j.delivery, ...j.categories]
333
- .filter(Boolean)
334
- .join(" ")
335
- .toLowerCase();
336
- return haystack.includes(contains);
337
- });
338
- }
339
- const lang = url.searchParams.get("lang")?.trim().toLowerCase();
340
- if (lang === "fr" || lang === "en") {
341
- pool = pool.filter((j) => j.lang === lang);
342
- }
343
- pool = applyJokeBlacklist(pool, parseBlacklistFlags(url));
344
- return pool;
345
- }
346
-
347
- /**
348
- * Réponse type JokeAPI v2.
349
- * - `amount` : taille du lot si pas de `offset`
350
- * - `offset` + `limit` / `per_page` : pagination (sonic-queue lazy)
351
- * - `contains`, `lang`, `blacklistFlags` : filtres formulaire (queue « Remove following jokes »)
352
- */
353
- export function buildJokeApiResponse(url: URL): DocsJokeApiResponse {
354
- const pool = filterDocsJokes(SAMPLE_JOKES, url);
355
- const amount = Math.max(
356
- 1,
357
- parseInt(url.searchParams.get("amount") || "10", 10),
358
- );
359
- const hasOffset = url.searchParams.has("offset");
360
- const limit = Math.max(
361
- 1,
362
- parseInt(
363
- url.searchParams.get("limit") ||
364
- url.searchParams.get("per_page") ||
365
- String(amount),
366
- 10,
367
- ),
368
- );
369
- const offset = Math.max(0, parseInt(url.searchParams.get("offset") || "0", 10));
370
- const start = hasOffset ? offset : 0;
371
- const count = hasOffset ? limit : amount;
372
- const jokes = pool.slice(start, start + count).map((j, i) => ({
373
- ...j,
374
- id: start + i + 1,
375
- }));
376
- return { error: false, amount: jokes.length, jokes };
377
- }
@@ -0,0 +1,89 @@
1
+ /** Fictional flight board for list / queue filter demos (`key="flights"`). */
2
+ export type DocsFlightStatus =
3
+ | "on-time"
4
+ | "boarding"
5
+ | "delayed"
6
+ | "landed"
7
+ | "cancelled";
8
+
9
+ export type DocsFlight = {
10
+ id: number;
11
+ code: string;
12
+ direction: "departures" | "arrivals";
13
+ airport: string;
14
+ city: string;
15
+ time: string;
16
+ gate: string;
17
+ status: DocsFlightStatus;
18
+ };
19
+
20
+ const row = (
21
+ code: string,
22
+ direction: DocsFlight["direction"],
23
+ airport: string,
24
+ city: string,
25
+ time: string,
26
+ gate: string,
27
+ status: DocsFlightStatus,
28
+ ): Omit<DocsFlight, "id"> => ({
29
+ code,
30
+ direction,
31
+ airport,
32
+ city,
33
+ time,
34
+ gate,
35
+ status,
36
+ });
37
+
38
+ const FLIGHTS: Omit<DocsFlight, "id">[] = [
39
+ row("CN 001", "departures", "JFK", "New York", "08:15", "B12", "boarding"),
40
+ row("CN 014", "departures", "LHR", "London", "08:40", "A03", "on-time"),
41
+ row("CN 102", "departures", "GIG", "Rio de Janeiro", "09:05", "C21", "delayed"),
42
+ row("CN 220", "departures", "DKR", "Dakar", "09:30", "C07", "on-time"),
43
+ row("CN 305", "departures", "IAD", "Washington", "10:10", "B04", "cancelled"),
44
+ row("CN 412", "departures", "BAH", "Bahrain", "10:45", "D02", "delayed"),
45
+ row("CN 518", "departures", "SIN", "Singapore", "11:20", "D14", "on-time"),
46
+ row("CN 633", "departures", "YUL", "Montreal", "12:00", "A11", "on-time"),
47
+ row("CN 002", "arrivals", "JFK", "New York", "07:50", "B10", "landed"),
48
+ row("CN 015", "arrivals", "LHR", "London", "08:25", "A05", "landed"),
49
+ row("CN 103", "arrivals", "GIG", "Rio de Janeiro", "09:15", "C20", "delayed"),
50
+ row("CN 221", "arrivals", "DKR", "Dakar", "09:55", "C08", "on-time"),
51
+ row("CN 306", "arrivals", "IAD", "Washington", "10:35", "B06", "on-time"),
52
+ row("CN 413", "arrivals", "BAH", "Bahrain", "11:05", "D03", "cancelled"),
53
+ row("CN 519", "arrivals", "SIN", "Singapore", "11:40", "D15", "delayed"),
54
+ row("CN 634", "arrivals", "YUL", "Montreal", "12:30", "A12", "on-time"),
55
+ ];
56
+
57
+ /**
58
+ * `GET /flights` — filters:
59
+ * - `direction`: `departures` · `arrivals`
60
+ * - `q`: substring on code / city / airport
61
+ * - `status`: comma-separated statuses to keep (`all` or empty = no filter)
62
+ * - `offset` + `limit`: pagination for sonic-queue
63
+ */
64
+ export function buildFlightsResponse(url: URL): { flights: DocsFlight[] } {
65
+ const p = url.searchParams;
66
+ let pool = FLIGHTS.map((f, i) => ({ ...f, id: i + 1 }));
67
+
68
+ const direction = p.get("direction");
69
+ if (direction === "departures" || direction === "arrivals") {
70
+ pool = pool.filter((f) => f.direction === direction);
71
+ }
72
+ const q = p.get("q")?.trim().toLowerCase();
73
+ if (q) {
74
+ pool = pool.filter((f) =>
75
+ [f.code, f.city, f.airport].join(" ").toLowerCase().includes(q),
76
+ );
77
+ }
78
+ const statuses = (p.get("status") || "")
79
+ .split(",")
80
+ .map((s) => s.trim())
81
+ .filter((s) => s && s !== "all");
82
+ if (statuses.length) {
83
+ pool = pool.filter((f) => statuses.includes(f.status));
84
+ }
85
+
86
+ const offset = Math.max(0, parseInt(p.get("offset") || "0", 10));
87
+ const limit = Math.max(1, parseInt(p.get("limit") || "20", 10));
88
+ return { flights: pool.slice(offset, offset + limit) };
89
+ }
@@ -1,8 +1,8 @@
1
1
  import { handleApiConfigMockRequest } from "./api-config-mock";
2
+ import { buildFlightsResponse } from "./flights";
2
3
  import {
3
4
  DOCS_GEO_COMMUNES,
4
5
  DOCS_REQRES_USERS,
5
- buildJokeApiResponse,
6
6
  filterDocsUsers,
7
7
  type GeoCommuneRow,
8
8
  type ReqresUserResponse,
@@ -291,9 +291,8 @@ export async function handleDocsMockApiRequest(
291
291
  });
292
292
  }
293
293
 
294
- const jokeMatch = subPath.match(/^\/jokes\/joke\/([^/]+)$/);
295
- if (jokeMatch) {
296
- return json(buildJokeApiResponse(url));
294
+ if (subPath === "/flights") {
295
+ return json(buildFlightsResponse(url));
297
296
  }
298
297
 
299
298
  return json({ error: "Not found", path: subPath }, { status: 404 });
@@ -7,5 +7,4 @@ export const DOCS_MOCK_REQRES_SERVICE = DOCS_MOCK_API_BASE;
7
7
  /** Remplace https://geo.api.gouv.fr/ — chemins `communes?…`. */
8
8
  export const DOCS_MOCK_GEO_SERVICE = `${DOCS_MOCK_API_BASE}/geo/`;
9
9
 
10
- /** Remplace https://v2.jokeapi.dev — chemins `joke/Any?…`. */
11
- export const DOCS_MOCK_JOKES_SERVICE = `${DOCS_MOCK_API_BASE}/jokes`;
10
+