@supersoniks/concorde 4.5.2 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/.gitlab-ci.yml +23 -0
  2. package/README.md +106 -55
  3. package/ai/AGENTS.md +52 -0
  4. package/ai/README.md +30 -0
  5. package/ai/cursor/rules/concorde-menu.mdc +15 -0
  6. package/ai/cursor/rules/concorde-scope.mdc +14 -0
  7. package/ai/cursor/rules/concorde-theme.mdc +13 -0
  8. package/ai/cursor/rules/concorde.mdc +49 -0
  9. package/ai/jetbrains/rules/concorde.md +39 -0
  10. package/ai/skills/concorde/SKILL.md +220 -0
  11. package/ai/skills/concorde-get-set-dp/SKILL.md +194 -0
  12. package/ai/skills/concorde-imports/SKILL.md +78 -0
  13. package/ai/skills/concorde-menu/SKILL.md +74 -0
  14. package/ai/skills/concorde-scope/SKILL.md +70 -0
  15. package/ai/skills/concorde-theme/SKILL.md +46 -0
  16. package/build-infos.json +1 -1
  17. package/concorde-core.bundle.js +159 -159
  18. package/concorde-core.es.js +1915 -1809
  19. package/dist/altcha-widget.js +2662 -0
  20. package/dist/concorde-core.bundle.js +159 -159
  21. package/dist/concorde-core.es.js +1915 -1809
  22. package/dist/docs-mock-api-sw.js +589 -0
  23. package/dist/docs-mock-api-sw.js.map +7 -0
  24. package/docs/altcha-widget.js +2662 -0
  25. package/docs/assets/index-D9pxaQYK.js +7508 -0
  26. package/docs/assets/index-t0-i22oI.css +1 -0
  27. package/docs/docs-mock-api-sw.js +589 -0
  28. package/docs/docs-mock-api-sw.js.map +7 -0
  29. package/docs/index.html +2 -2
  30. package/docs/src/core/components/functional/fetch/fetch.md +13 -11
  31. package/docs/src/core/components/functional/if/if.md +4 -11
  32. package/docs/src/core/components/functional/list/list.md +60 -194
  33. package/docs/src/core/components/functional/queue/queue.md +70 -85
  34. package/docs/src/core/components/functional/router/router.md +62 -97
  35. package/docs/src/core/components/functional/states/states.md +2 -2
  36. package/docs/src/core/components/functional/submit/submit.md +86 -55
  37. package/docs/src/core/components/ui/captcha/captcha.md +2 -2
  38. package/docs/src/core/components/ui/card/card.md +1 -1
  39. package/docs/src/core/components/ui/form/checkbox/checkbox.md +5 -32
  40. package/docs/src/core/components/ui/form/input/input.md +5 -30
  41. package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +6 -4
  42. package/docs/src/core/components/ui/form/radio/radio.md +5 -32
  43. package/docs/src/core/components/ui/form/select/select.md +5 -31
  44. package/docs/src/core/components/ui/form/switch/switch.md +5 -32
  45. package/docs/src/core/components/ui/loader/loader.md +1 -13
  46. package/docs/src/core/components/ui/table/table.md +3 -3
  47. package/docs/src/docs/_core-concept/dataFlow.md +73 -0
  48. package/docs/src/docs/_core-concept/subscriber.md +9 -10
  49. package/docs/src/docs/_decorators/ancestor-attribute.md +4 -3
  50. package/docs/src/docs/_decorators/auto-subscribe.md +19 -16
  51. package/docs/src/docs/_decorators/bind.md +20 -17
  52. package/docs/src/docs/_decorators/get.md +7 -4
  53. package/docs/src/docs/_decorators/handle.md +171 -0
  54. package/docs/src/docs/_decorators/on-assign.md +99 -73
  55. package/docs/src/docs/_decorators/publish.md +2 -1
  56. package/docs/src/docs/_decorators/subscribe.md +70 -9
  57. package/docs/src/docs/_decorators/wait-for-ancestors.md +13 -10
  58. package/docs/src/docs/_directives/sub.md +91 -0
  59. package/docs/src/docs/_getting-started/ai-agents.md +56 -0
  60. package/docs/src/docs/_getting-started/concorde-manual-install.md +133 -0
  61. package/docs/src/docs/_getting-started/concorde-outside.md +13 -123
  62. package/docs/src/docs/_getting-started/create-a-component.md +2 -0
  63. package/docs/src/docs/_getting-started/my-first-component.md +236 -0
  64. package/docs/src/docs/_getting-started/my-first-subscriber.md +29 -83
  65. package/docs/src/docs/_getting-started/pubsub.md +21 -134
  66. package/docs/src/docs/_getting-started/start.md +26 -18
  67. package/docs/src/docs/_misc/api-configuration.md +79 -0
  68. package/docs/src/docs/_misc/dataProviderKey.md +38 -5
  69. package/docs/src/docs/_misc/docs-mock-api.md +60 -0
  70. package/docs/src/docs/_misc/endpoint.md +2 -1
  71. package/docs/src/docs/_misc/html-integration.md +13 -0
  72. package/docs/src/docs/search/docs-search.json +4163 -873
  73. package/docs/src/tsconfig.json +380 -317
  74. package/gitlab/job_tests.sh +55 -0
  75. package/package.json +37 -3
  76. package/public/altcha-widget.js +2662 -0
  77. package/public/docs-mock-api-sw.js +589 -0
  78. package/public/docs-mock-api-sw.js.map +7 -0
  79. package/scripts/ai-init.mjs +167 -0
  80. package/scripts/docs-mock-api-vite-plugin.ts +116 -0
  81. package/scripts/docs-open-in-editor-plugin.ts +130 -0
  82. package/scripts/pre-publish.mjs +2 -1
  83. package/src/core/components/functional/example/example.ts +1 -1
  84. package/src/core/components/functional/fetch/fetch.md +13 -11
  85. package/src/core/components/functional/if/if.md +4 -11
  86. package/src/core/components/functional/list/list.demo.ts +4 -4
  87. package/src/core/components/functional/list/list.md +60 -194
  88. package/src/core/components/functional/list/list.ts +8 -7
  89. package/src/core/components/functional/queue/queue.demo.ts +1 -1
  90. package/src/core/components/functional/queue/queue.md +70 -85
  91. package/src/core/components/functional/queue/queue.ts +4 -4
  92. package/src/core/components/functional/router/router.md +62 -97
  93. package/src/core/components/functional/router/router.ts +1 -1
  94. package/src/core/components/functional/states/states.md +2 -2
  95. package/src/core/components/functional/submit/submit.md +86 -55
  96. package/src/core/components/functional/submit/submit.ts +10 -3
  97. package/src/core/components/ui/captcha/captcha.md +2 -2
  98. package/src/core/components/ui/card/card.md +1 -1
  99. package/src/core/components/ui/form/checkbox/checkbox.md +5 -32
  100. package/src/core/components/ui/form/input/input.md +5 -30
  101. package/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +6 -4
  102. package/src/core/components/ui/form/radio/radio.md +5 -32
  103. package/src/core/components/ui/form/select/select.md +5 -31
  104. package/src/core/components/ui/form/switch/switch.md +5 -32
  105. package/src/core/components/ui/loader/loader.md +1 -13
  106. package/src/core/components/ui/table/table.md +3 -3
  107. package/src/core/decorators/Subscriber.ts +2 -0
  108. package/src/core/decorators/subscriber/handle.disambig.spec.ts +20 -0
  109. package/src/core/decorators/subscriber/handle.skip.spec.ts +37 -0
  110. package/src/core/decorators/subscriber/handle.ts +128 -0
  111. package/src/core/decorators/subscriber/onAssign.ts +94 -4
  112. package/src/core/directives/DataProvider.sub.spec.ts +96 -0
  113. package/src/core/directives/DataProvider.ts +109 -40
  114. package/src/core/utils/PublisherProxy.ts +33 -18
  115. package/src/core/utils/dataProviderKey.ts +23 -0
  116. package/src/core/utils/publisherPathKey.spec.ts +58 -0
  117. package/src/decorators.ts +6 -0
  118. package/src/docs/_core-concept/dataFlow.md +73 -0
  119. package/src/docs/_core-concept/subscriber.md +9 -10
  120. package/src/docs/_decorators/ancestor-attribute.md +4 -3
  121. package/src/docs/_decorators/auto-subscribe.md +19 -16
  122. package/src/docs/_decorators/bind.md +20 -17
  123. package/src/docs/_decorators/get.md +7 -4
  124. package/src/docs/_decorators/handle.md +171 -0
  125. package/src/docs/_decorators/on-assign.md +99 -47
  126. package/src/docs/_decorators/publish.md +2 -1
  127. package/src/docs/_decorators/subscribe.md +70 -9
  128. package/src/docs/_decorators/wait-for-ancestors.md +13 -10
  129. package/src/docs/_directives/sub.md +91 -0
  130. package/src/docs/_getting-started/ai-agents.md +56 -0
  131. package/src/docs/_getting-started/concorde-manual-install.md +133 -0
  132. package/src/docs/_getting-started/concorde-outside.md +13 -123
  133. package/src/docs/_getting-started/create-a-component.md +2 -0
  134. package/src/docs/_getting-started/my-first-component.md +236 -0
  135. package/src/docs/_getting-started/my-first-subscriber.md +29 -83
  136. package/src/docs/_getting-started/pubsub.md +21 -134
  137. package/src/docs/_getting-started/start.md +26 -18
  138. package/src/docs/_misc/api-configuration.md +79 -0
  139. package/src/docs/_misc/dataProviderKey.md +38 -5
  140. package/src/docs/_misc/docs-mock-api.md +60 -0
  141. package/src/docs/_misc/endpoint.md +2 -1
  142. package/src/docs/_misc/html-integration.md +13 -0
  143. package/src/docs/code.ts +58 -12
  144. package/src/docs/components/docs-demo-sources.ts +397 -0
  145. package/src/docs/components/docs-lit-demo-raw.ts +28 -0
  146. package/src/docs/components/docs-lit-demo.ts +166 -0
  147. package/src/docs/components/docs-source-link.ts +72 -0
  148. package/src/docs/docs-location.ts +54 -0
  149. package/src/docs/docs.ts +12 -0
  150. package/src/docs/example/decorators-demo-bind-demos.ts +41 -46
  151. package/src/docs/example/decorators-demo-geo.ts +16 -11
  152. package/src/docs/example/decorators-demo-init.ts +2 -228
  153. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +142 -12
  154. package/src/docs/example/decorators-demo.ts +71 -70
  155. package/src/docs/example/docs-api-config-demos.ts +234 -0
  156. package/src/docs/example/docs-joke-demos.ts +297 -0
  157. package/src/docs/example/docs-list-demos.ts +179 -0
  158. package/src/docs/example/docs-provider-keys.ts +315 -0
  159. package/src/docs/example/docs-queue-demos.ts +114 -0
  160. package/src/docs/example/docs-router-demos.ts +89 -0
  161. package/src/docs/example/docs-submit-demos.ts +455 -0
  162. package/src/docs/example/docs-toggle-demos.ts +73 -0
  163. package/src/docs/example/docs-user-two-scopes.ts +37 -0
  164. package/src/docs/example/docs-users-list.ts +71 -0
  165. package/src/docs/example/users.ts +41 -24
  166. package/src/docs/mock-api/api-config-mock.ts +152 -0
  167. package/src/docs/mock-api/fixtures.ts +377 -0
  168. package/src/docs/mock-api/register.ts +25 -0
  169. package/src/docs/mock-api/router.ts +234 -0
  170. package/src/docs/mock-api/service-worker.ts +23 -0
  171. package/src/docs/mock-api/urls.ts +11 -0
  172. package/src/docs/navigation/navigation.ts +43 -7
  173. package/src/docs/search/docs-search.json +4193 -858
  174. package/src/docs/search/markdown-renderer.ts +7 -3
  175. package/src/docs/search/page.ts +11 -14
  176. package/src/docs/search/sonic-code-markdown.spec.ts +29 -0
  177. package/src/docs/search/sonic-code-markdown.ts +28 -0
  178. package/src/docs.ts +4 -0
  179. package/src/tsconfig.json +96 -0
  180. package/src/tsconfig.tsbuildinfo +1 -1
  181. package/vite.config.mts +8 -0
  182. package/docs/assets/index-CaysOMFz.js +0 -5046
  183. package/docs/assets/index-D8mGoXzF.css +0 -1
  184. package/docs/src/docs/_misc/templates-demo.md +0 -19
  185. package/src/docs/_misc/templates-demo.md +0 -19
@@ -1,8 +1,17 @@
1
1
  # @subscribe
2
2
 
3
- Read-only binding: **only** `DataProviderKey<T>` (no legacy string path). No `reflect` option the publisher updates the property, not the other way around.
3
+ Keeps a **Lit property** in sync with a **read-only** slice of the DataProvider store. You pass a [`DataProviderKey`](#docs/_misc/dataProviderKey.md/dataProviderKey); when that path changes, the property updates and the component re-renders.
4
4
 
5
- For bidirectional binding or string paths, use [@bind](#docs/_decorators/bind.md/bind).
5
+ Typical setup (same idea as [My first component](#docs/_getting-started/my-first-component.md/my-first-component)):
6
+
7
+ | Piece | Role |
8
+ |-------|------|
9
+ | **Type** `T` | Shape of the object at that path (`DocsUserData`, `{ count: number }`, …) |
10
+ | **Key** | `DataProviderKey<T, U>` — static path (`"cart"`) or dynamic (`"users.${userIndex}"`, `"${dataProvider}"`) |
11
+ | **Scope on the host** | Properties listed in `U` (e.g. `dataProvider`, `userIndex`) — often filled via [`@ancestorAttribute`](#docs/_decorators/ancestor-attribute.md/ancestor-attribute) |
12
+ | **`@subscribe(key)`** | Mirrors the store into `@state()` (or another property); read-only from the component side |
13
+
14
+ For **writing** back to the store from component state, use [@publish](#docs/_decorators/publish.md/publish). In templates, the same paths work with [sub()](#docs/_directives/sub.md/sub).
6
15
 
7
16
  ## Import
8
17
 
@@ -10,27 +19,79 @@ For bidirectional binding or string paths, use [@bind](#docs/_decorators/bind.md
10
19
  <template>
11
20
  import { subscribe } from "@supersoniks/concorde/decorators";
12
21
  import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
13
- //
22
+
14
23
  type Data = { count: number };
15
- const dataKey = new DataProviderKey<Data>("data");
16
- //
24
+ const dataKey = new DataProviderKey&lt;Data&gt;("data");
25
+
17
26
  @subscribe(dataKey.count)
18
27
  @state()
19
28
  count = 0;
20
29
  </template>
21
30
  </sonic-code>
22
31
 
23
- ## Highlights
32
+ ## Static path
24
33
 
25
- - Strict typing: the property type must match `T`.
26
- - Dynamic paths: placeholders in `DataProviderKey`, resolved from the host component’s properties.
34
+ The key path is fixed. The property type must match `T` at that segment.
35
+
36
+ <sonic-code language="typescript">
37
+ <template>
38
+ const cartKey = new DataProviderKey&lt;{ items: string[] }&gt;("cart");
39
+
40
+ @subscribe(cartKey)
41
+ @state()
42
+ cart: { items: string[] } | null = null;
43
+ </template>
44
+ </sonic-code>
45
+
46
+ ## Dynamic path and scope
47
+
48
+ Placeholders `${prop}` in the key string are resolved from **properties on the same component**. Declare them in the key’s second generic so TypeScript expects them on the host:
49
+
50
+ <sonic-code language="typescript">
51
+ <template>
52
+ type User = { firstName: string; lastName: string; email: string };
53
+
54
+ @subscribe(new DataProviderKey&lt;User, { userIndex: number }&gt;("demoUsers.${userIndex}"))
55
+ @state()
56
+ user: User | null = null;
57
+
58
+ @property({ type: Number }) userIndex = 0;
59
+ </template>
60
+ </sonic-code>
61
+
62
+ When `userIndex` changes, `@subscribe` re-resolves the path and refreshes `user`.
63
+
64
+ ## Row / ancestor scope
65
+
66
+ List items (and wrappers like `<div dataProvider="…">`) set which branch the child reads. Pattern from the tutorial:
67
+
68
+ <sonic-code language="typescript">
69
+ <template>
70
+ export const rowKey = new DataProviderKey&lt;
71
+ User,
72
+ { dataProvider: string | null }
73
+ &gt;("${dataProvider}");
74
+
75
+ @ancestorAttribute("dataProvider")
76
+ dataProvider: string | null = null;
77
+
78
+ @subscribe(rowKey)
79
+ @state()
80
+ user: User | null = null;
81
+ </template>
82
+ </sonic-code>
27
83
 
28
84
  ## Demo
29
85
 
30
86
  <sonic-code>
31
87
  <template>
88
+ <docs-demo-sources for="demo-subscribe-dynamic"></docs-demo-sources>
32
89
  <demo-subscribe-dynamic></demo-subscribe-dynamic>
33
90
  </template>
34
91
  </sonic-code>
35
92
 
36
- See also [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey).
93
+ ## See also
94
+
95
+ - [Data flow](#docs/_core-concept/dataFlow.md/dataFlow) — overview
96
+ - [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey) — paths and host generics
97
+ - [sub()](#docs/_directives/sub.md/sub) — same paths inside `html` templates
@@ -30,7 +30,7 @@ The parent is registered via `customElements.define()` (vanilla JS) rather than
30
30
  <template>
31
31
  import { html, LitElement } from "lit";
32
32
  import { customElement, state } from "lit/decorators.js";
33
- //
33
+
34
34
  // Parent: registered later via customElements.define(), not @customElement
35
35
  @dispatchConnectedEvent()
36
36
  export class DemoWaitAncestorContainer extends LitElement {
@@ -38,21 +38,21 @@ export class DemoWaitAncestorContainer extends LitElement {
38
38
  return html`<slot></slot>`;
39
39
  }
40
40
  }
41
- //
41
+
42
42
  // Child: waits for parent before initializing
43
43
  @customElement("demo-wait-ancestor-value")
44
44
  @awaitConnectedAncestors("demo-wait-ancestor-container[dataProvider]")
45
45
  export class DemoWaitAncestorValue extends LitElement {
46
46
  @ancestorAttribute("dataProvider")
47
47
  dataProvider: string | null = null;
48
- //
48
+
49
49
  @state() initializedAt: string = "";
50
- //
50
+
51
51
  connectedCallback() {
52
52
  super.connectedCallback();
53
53
  this.initializedAt = new Date().toISOString();
54
54
  }
55
- //
55
+
56
56
  render() {
57
57
  return html`
58
58
  <p>DataProvider from ancestor: <strong>${this.dataProvider || "—"}</strong></p>
@@ -60,7 +60,7 @@ export class DemoWaitAncestorValue extends LitElement {
60
60
  `;
61
61
  }
62
62
  }
63
- //
63
+
64
64
  // Demo section: register parent via customElements.define() when user clicks
65
65
  @customElement("demo-wait-ancestors-section")
66
66
  export class DemoWaitAncestorsSection extends LitElement {
@@ -83,7 +83,8 @@ export class DemoWaitAncestorsSection extends LitElement {
83
83
 
84
84
  <sonic-code>
85
85
  <template>
86
- <demo-wait-ancestors-section></demo-wait-ancestors-section>
86
+ <docs-demo-sources for="demo-wait-ancestors-section"></docs-demo-sources>
87
+ <demo-wait-ancestors-section></demo-wait-ancestors-section>
87
88
  </template>
88
89
  </sonic-code>
89
90
 
@@ -105,7 +106,8 @@ When the parent is defined at load and already in the DOM, the child initializes
105
106
 
106
107
  <sonic-code>
107
108
  <template>
108
- <demo-wait-ancestors-static-section></demo-wait-ancestors-static-section>
109
+ <docs-demo-sources for="demo-wait-ancestors-static-section"></docs-demo-sources>
110
+ <demo-wait-ancestors-static-section></demo-wait-ancestors-static-section>
109
111
  </template>
110
112
  </sonic-code>
111
113
 
@@ -113,7 +115,8 @@ When the parent is defined at load and already in the DOM, the child initializes
113
115
 
114
116
  <sonic-code>
115
117
  <template>
116
- <demo-wait-ancestors-ready-section></demo-wait-ancestors-ready-section>
118
+ <docs-demo-sources for="demo-wait-ancestors-ready-section"></docs-demo-sources>
119
+ <demo-wait-ancestors-ready-section></demo-wait-ancestors-ready-section>
117
120
  </template>
118
121
  </sonic-code>
119
122
 
@@ -145,7 +148,7 @@ The `sonic-connected` event bubbles, so you can listen to it from anywhere:
145
148
  <sonic-code language="typescript">
146
149
  <template>
147
150
  import { CONNECTED } from "@supersoniks/concorde/decorators";
148
- //
151
+
149
152
  someConnectable.addEventListener(CONNECTED, (e) => {
150
153
  console.log("Component connected:", e.target);
151
154
  });
@@ -0,0 +1,91 @@
1
+ # sub()
2
+
3
+ Read-only Lit directive: displays the current **DataProvider** value and updates whenever it is assigned.
4
+
5
+ ## Import
6
+
7
+ <sonic-code language="typescript">
8
+ <template>
9
+ import { sub } from "@supersoniks/concorde/directives";
10
+ </template>
11
+ </sonic-code>
12
+
13
+ ## String path
14
+
15
+ <sonic-code language="typescript">
16
+ <template>
17
+ render() {
18
+ return html`&lt;p&gt;Count: ${sub("myCounter.count")}&lt;/p&gt;`;
19
+ }
20
+ </template>
21
+ </sonic-code>
22
+
23
+ ## DataProviderKey (static)
24
+
25
+ <sonic-code language="typescript">
26
+ <template>
27
+ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
28
+ import { sub } from "@supersoniks/concorde/directives";
29
+
30
+ const counterKey = new DataProviderKey&lt;{ count: number }&gt;("myCounter");
31
+
32
+ render() {
33
+ return html`&lt;p&gt;${sub(counterKey.count)}&lt;/p&gt;`;
34
+ }
35
+ </template>
36
+ </sonic-code>
37
+
38
+ ## Dynamic DataProviderKey (`${prop}`)
39
+
40
+ Like `@subscribe`: the path is resolved on the template **host component**; the directive re-subscribes when observed props change.
41
+
42
+ <sonic-code language="typescript">
43
+ <template>
44
+ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
45
+ import { sub } from "@supersoniks/concorde/directives";
46
+
47
+ type User = { firstName: string; lastName: string; email: string };
48
+ const userKey = new DataProviderKey&lt;User, { userIndex: number }&gt;(
49
+ "demoUsers.${userIndex}",
50
+ );
51
+
52
+ @customElement("demo-sub-dynamic")
53
+ export class DemoSubDynamic extends LitElement {
54
+ @property({ type: Number }) userIndex = 0;
55
+
56
+ render() {
57
+ return html`
58
+ &lt;p&gt;${sub(userKey.email)}&lt;/p&gt;
59
+ `;
60
+ }
61
+ }
62
+ </template>
63
+ </sonic-code>
64
+
65
+ ## Demo
66
+
67
+ <sonic-code toggleCode>
68
+ <template>
69
+ <docs-demo-sources for="demo-sub-template"></docs-demo-sources>
70
+ <demo-sub-template></demo-sub-template>
71
+ </template>
72
+ </sonic-code>
73
+
74
+ ## Concatenation (forms)
75
+
76
+ <sonic-code language="typescript">
77
+ <template>
78
+ html`&lt;span&gt;${sub(this.formDataProvider + ".email")}&lt;/span&gt;`
79
+ </template>
80
+ </sonic-code>
81
+
82
+ ## sub() vs get() / set() / dp()
83
+
84
+ | API | Context | Dynamic `${…}` |
85
+ |-----|----------|------------------|
86
+ | `sub()` | Lit template, reactive | Yes |
87
+ | `get` / `set` / `dp` | Imperative code | No |
88
+
89
+ Do not replace `sub(path)` with `get(path)` in a template: `get` returns a one-time snapshot.
90
+
91
+ See [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey), [@subscribe](#docs/_decorators/subscribe.md/subscribe), and the `concorde-get-set-dp` migration skill.
@@ -0,0 +1,56 @@
1
+ # AI agents (skills & AGENTS.md)
2
+
3
+ Concorde ships **skills**, **rules**, and a root **`AGENTS.md`** so Cursor, JetBrains AI Assistant, and other coding agents follow framework patterns (DataProvider, decorators, short imports, scope, theme, migrations).
4
+
5
+ On a [starter](#docs/_getting-started/concorde-outside.md/concorde-outside) project, run `yarn ai:sync` after install. On a [manual / brownfield](#docs/_getting-started/concorde-manual-install.md/concorde-manual-install) project, install Concorde first, then use `ai-init` below.
6
+
7
+ ## Dedicated commands
8
+
9
+ | Context | Command |
10
+ |---------|---------|
11
+ | [create-concorde-ts-starter](https://www.npmjs.com/package/@supersoniks/create-concorde-ts-starter) project | `yarn ai:sync` |
12
+ | Any consumer app (after `yarn add @supersoniks/concorde`) | `node node_modules/@supersoniks/concorde/scripts/ai-init.mjs` |
13
+ | Concorde repo (contributors) | `yarn ai-init` |
14
+
15
+ <sonic-code language="shell">
16
+ <template>
17
+ # Starter (from project root)
18
+ yarn ai:sync
19
+
20
+ # Manual / existing project
21
+ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
22
+ </template>
23
+ </sonic-code>
24
+
25
+ ## Useful flags
26
+
27
+ | Flag | Effect |
28
+ |------|--------|
29
+ | `--merge-agents` | Append to an existing `AGENTS.md` instead of replacing it |
30
+ | `--overlay <dir>` | Copy extra rules/skills from another layer (e.g. starter kit) |
31
+ | `--cursor-only` | Install only `.cursor/skills` and `.cursor/rules` |
32
+ | `--jetbrains-only` | Install only `.aiassistant/rules/` |
33
+
34
+ ## What gets installed
35
+
36
+ | Path | Role |
37
+ |------|------|
38
+ | `AGENTS.md` | Project-level guide for agents (Concorde conventions) |
39
+ | `.cursor/skills/concorde/` | Core Lit + DataProvider patterns |
40
+ | `.cursor/skills/concorde-imports/` | Short `@supersoniks/concorde/…` import paths |
41
+ | `.cursor/skills/concorde-scope/` | `serviceURL`, `formDataProvider`, API configuration |
42
+ | `.cursor/skills/concorde-theme/` | `sonic-theme` and `--sc-*` tokens |
43
+ | `.cursor/skills/concorde-menu/` | `sonic-menu` navigation |
44
+ | `.cursor/skills/concorde-get-set-dp/` | `get` / `set` / `dp` and `DataProviderKey` migration |
45
+ | `.cursor/rules/concorde.mdc` | Cursor rules (always-on patterns) |
46
+ | `.aiassistant/rules/concorde.md` | JetBrains AI Assistant rules |
47
+
48
+ ## Workflow
49
+
50
+ 1. **Starter project:** [Installation](#docs/_getting-started/concorde-outside.md/concorde-outside) — `yarn ai:sync` is wired in the kit.
51
+ 2. **Existing / manual Vite project:** [Manual installation](#docs/_getting-started/concorde-manual-install.md/concorde-manual-install), then **`ai-init`** after `yarn add @supersoniks/concorde`.
52
+ 3. Commit `AGENTS.md`, `.cursor/`, and `.aiassistant/` if your team shares agent settings.
53
+ 4. Re-run the same command when you bump `@supersoniks/concorde` to refresh skills from `node_modules/@supersoniks/concorde/ai/`.
54
+ 5. In Cursor, skills under `.cursor/skills/` are picked up automatically; mention a skill in chat for focused tasks (e.g. migration → `concorde-get-set-dp`).
55
+
56
+ Source files in the npm package: `node_modules/@supersoniks/concorde/ai/` (see also `ai/README.md` in the [Concorde repository](https://github.com/supersoniks/concorde)).
@@ -0,0 +1,133 @@
1
+ # Manual installation (Vite)
2
+
3
+ > **Legacy** — for brownfield apps or custom stacks. New projects should use the [starter](#docs/_getting-started/concorde-outside.md/concorde-outside).
4
+
5
+ ## Brand New Vite Project
6
+
7
+ Tailwind configuration is not covered here yet.
8
+
9
+ ### Creating the Project
10
+
11
+ <sonic-code language="shell">
12
+ <template>
13
+ # Pure JavaScript project
14
+ yarn create vite --template vanilla-js
15
+ # TypeScript project
16
+ # (it is recommended to use this approach, which installs Lit separately if needed, via "yarn add lit")
17
+ yarn create vite --template vanilla-ts
18
+ # TypeScript + Lit project
19
+ # (creating new web components, for example, to extend the fetch or subscriber mixins)
20
+ yarn create vite --template lit-ts
21
+ </template>
22
+ </sonic-code>
23
+
24
+ Using Lit with TypeScript requires the following configuration in the "compilerOptions" section of the `tsconfig.json` file:
25
+
26
+ <sonic-code language="json">
27
+ <template>
28
+ "experimentalDecorators": true,
29
+ "useDefineForClassFields": false
30
+ </template>
31
+ </sonic-code>
32
+
33
+ ### Installing Concorde
34
+
35
+ Navigate to the project folder created and perform the installation:
36
+
37
+ <sonic-code language="shell">
38
+ <template>
39
+ yarn add @supersoniks/concorde
40
+ </template>
41
+ </sonic-code>
42
+
43
+ Agent skills (`AGENTS.md`, Cursor / JetBrains): see [AI agents](#docs/_getting-started/ai-agents.md/ai-agents) — run `node node_modules/@supersoniks/concorde/scripts/ai-init.mjs` after install.
44
+
45
+ ### Development / Build
46
+
47
+ <sonic-code language="shell">
48
+ <template>
49
+ # Development (you can add `--host` after the command chain in package.json's dev script instead of typing it each time as shown below)
50
+ yarn dev --host
51
+ # Build
52
+ yarn build
53
+ </template>
54
+ </sonic-code>
55
+
56
+ ## Shortcut Imports
57
+
58
+ Shortcut imports work by default in JavaScript, but in TypeScript, they are activated by choice as they inject data into *tsconfig.json*. Here is the command:
59
+
60
+ <sonic-code language="shell">
61
+ <template>
62
+ npx concorde enable-short-paths
63
+ </template>
64
+ </sonic-code>
65
+
66
+ Shortcut imports replace the actual paths with aliases as follows:
67
+
68
+ * `@supersoniks/concorde/core/components/functional_or_ui/component/component` becomes `@supersoniks/concorde/functional_or_ui/component`
69
+ * `@supersoniks/concorde/core/mixins_or_utils/class_name` becomes `@supersoniks/concorde/mixins_or_utils/class_name`
70
+
71
+ The original paths remain accessible. Shortcut imports are used for the examples later in this documentation.
72
+
73
+ ## Usage
74
+
75
+ ### Simple Integration in HTML
76
+
77
+ Import needed component in `main.ts` or wherever you want to use it:
78
+
79
+ <sonic-code language="typescript">
80
+ <template>
81
+ import "@supersoniks/concorde/ui/button";
82
+ </template>
83
+ </sonic-code>
84
+
85
+ Then in the render function ofyour component or in the HTML of the web page that includes the compiled JS, use the component as follows:
86
+
87
+ <sonic-code>
88
+ <template>
89
+ <sonic-button variant="outline">My button</sonic-button>
90
+ </template>
91
+ </sonic-code>
92
+
93
+ ### Using a Mixin to Create a New Lit Component
94
+
95
+ For example, create a file `my-element.ts` at the root:
96
+
97
+ <sonic-code language="typescript">
98
+ <template>
99
+ import { html, LitElement } from "lit";
100
+ import { customElement, property } from "lit/decorators.js";
101
+ import Fetcher from "@supersoniks/concorde/mixins/Fetcher";
102
+ import Subscriber from "@supersoniks/concorde/mixins/Subscriber";
103
+
104
+ @customElement("my-element")
105
+ export class SonicComponent extends Fetcher(Subscriber(LitElement)) {
106
+ @property() email = "";
107
+ @property() first_name = "";
108
+ @property() last_name = "";
109
+
110
+ render() {
111
+ return html`<div>
112
+ ${this.first_name} ${this.last_name} : ${this.email}
113
+ </div>`;
114
+ }
115
+ }
116
+ </template>
117
+ </sonic-code>
118
+
119
+ Import component `main.ts` or `main.js` or any other component that uses it to be compiled
120
+
121
+ <sonic-code language="typescript">
122
+ <template>
123
+ import "./my-element";
124
+ </template>
125
+ </sonic-code>
126
+
127
+ In the HTML of a JS or TS component or in the HTML of the web page containing the compiled JS:
128
+
129
+ <sonic-code language="html">
130
+ <template>
131
+ <my-element serviceURL="/docs-mock-api" dataProvider="api/users/2" key="data"></my-element>
132
+ </template>
133
+ </sonic-code>
@@ -1,8 +1,12 @@
1
1
  # Installation
2
2
 
3
+ <sonic-alert status="success" label="Recommended — use the starter" size="xl" background>
4
+ <p><strong>For almost all new projects, use <a href="https://www.npmjs.com/package/@supersoniks/create-concorde-ts-starter">create-concorde-ts-starter</a>.</strong></p>
5
+ <p>You get Vite + TypeScript + Lit + Tailwind, an example component, <code>npx concorde enable-short-paths</code> ready to run, and <code>yarn ai:sync</code> for <a href="#docs/_getting-started/ai-agents.md/ai-agents">AI agent skills</a> (<code>AGENTS.md</code>, Cursor / JetBrains rules) without extra setup.</p>
6
+ </sonic-alert>
7
+
3
8
  ## Starter
4
9
 
5
- The easiest way to use Concorde is by using the Concorde starter.
6
10
  The following command creates a new Vite project in TypeScript mode with Tailwind and an example component to get started.
7
11
 
8
12
  <sonic-code language="shell">
@@ -11,133 +15,19 @@ npx @supersoniks/create-concorde-ts-starter "project_name"
11
15
  </template>
12
16
  </sonic-code>
13
17
 
14
- ## Brand New Vite Project
15
-
16
-
17
- For a more manual configuration, you can refer to the following sections. <br/>
18
- However, the Tailwind configuration is not mentioned at the moment.
19
-
20
-
21
- ### Creating the Project
18
+ Then, from the project folder:
22
19
 
23
20
  <sonic-code language="shell">
24
21
  <template>
25
- # Pure JavaScript project
26
- yarn create vite --template vanilla-js
27
- # TypeScript project
28
- # (it is recommended to use this approach, which installs Lit separately if needed, via "yarn add lit")
29
- yarn create vite --template vanilla-ts
30
- # TypeScript + Lit project
31
- # (creating new web components, for example, to extend the fetch or subscriber mixins)
32
- yarn create vite --template lit-ts
33
- </template>
34
- </sonic-code>
35
-
36
- Using Lit with TypeScript requires the following configuration in the "compilerOptions" section of the `tsconfig.json` file:
37
-
38
- <sonic-code language="json">
39
- <template>
40
- "experimentalDecorators": true,
41
- "useDefineForClassFields": false
42
- </template>
43
- </sonic-code>
44
-
45
- ### Installing Concorde
46
-
47
- Navigate to the project folder created and perform the installation:
48
-
49
- <sonic-code language="shell">
50
- <template>
51
- yarn add @supersoniks/concorde
52
- </template>
53
- </sonic-code>
54
-
55
- ### Development / Build
56
-
57
- <sonic-code language="shell">
58
- <template>
59
- # Development (you can add `--host` after the command chain in package.json's dev script instead of typing it each time as shown below)
22
+ yarn install
60
23
  yarn dev --host
61
- # Build
62
- yarn build
63
24
  </template>
64
25
  </sonic-code>
65
26
 
66
- ## Shortcut Imports
67
-
68
- Shortcut imports work by default in JavaScript, but in TypeScript, they are activated by choice as they inject data into *tsconfig.json*. Here is the command:
69
-
70
- <sonic-code language="shell">
71
- <template>
72
- npx concorde enable-short-paths
73
- </template>
74
- </sonic-code>
75
-
76
- Shortcut imports replace the actual paths with aliases as follows:
77
-
78
- * `@supersoniks/concorde/core/components/functional_or_ui/component/component` becomes `@supersoniks/concorde/functional_or_ui/component`
79
- * `@supersoniks/concorde/core/mixins_or_utils/class_name` becomes `@supersoniks/concorde/mixins_or_utils/class_name`
27
+ ## Next steps
80
28
 
81
- The original paths remain accessible. Shortcut imports are used for the examples later in this documentation.
82
-
83
- ## Usage
84
-
85
- ### Simple Integration in HTML
86
-
87
- Import needed component in `main.ts` or wherever you want to use it:
88
-
89
- <sonic-code language="typescript">
90
- <template>
91
- import "@supersoniks/concorde/ui/button";
92
- </template>
93
- </sonic-code>
94
-
95
- Then in the render function ofyour component or in the HTML of the web page that includes the compiled JS, use the component as follows:
96
-
97
- <sonic-code>
98
- <template>
99
- <sonic-button variant="outline">My button</sonic-button>
100
- </template>
101
- </sonic-code>
102
-
103
- ### Using a Mixin to Create a New Lit Component
104
-
105
- For example, create a file `my-element.ts` at the root:
106
-
107
- <sonic-code language="typescript">
108
- <template>
109
- import { html, LitElement } from "lit";
110
- import { customElement, property } from "lit/decorators.js";
111
- import Fetcher from "@supersoniks/concorde/mixins/Fetcher";
112
- import Subscriber from "@supersoniks/concorde/mixins/Subscriber";
113
-
114
- @customElement("my-element")
115
- export class SonicComponent extends Fetcher(Subscriber(LitElement)) {
116
- @property() email = "";
117
- @property() first_name = "";
118
- @property() last_name = "";
119
-
120
- render() {
121
- return html`<div>
122
- ${this.first_name} ${this.last_name} : ${this.email}
123
- </div>`;
124
- }
125
- }
126
- </template>
127
- </sonic-code>
128
-
129
- Import component `main.ts` or `main.js` or any other component that uses it to be compiled
130
-
131
- <sonic-code language="typescript">
132
- <template>
133
- import "./my-element";
134
- </template>
135
- </sonic-code>
136
-
137
- In the HTML of a JS or TS component or in the HTML of the web page containing the compiled JS:
138
-
139
- <sonic-code language="html">
140
- <template>
141
- <my-element serviceURL="https://reqres.in" dataProvider="api/users/2" key="data"></my-element>
142
- </template>
143
- </sonic-code>
29
+ | Step | Page |
30
+ |------|------|
31
+ | Learn patterns | [My first component](#docs/_getting-started/my-first-component.md/my-first-component) |
32
+ | Agent skills | [AI agents (skills)](#docs/_getting-started/ai-agents.md/ai-agents) — `yarn ai:sync` on the starter |
33
+ | Brownfield / manual Vite | [Legacy: Manual installation](#docs/_getting-started/concorde-manual-install.md/concorde-manual-install) |
@@ -1,5 +1,7 @@
1
1
  # Creating components
2
2
 
3
+ > **New app components:** start with [My first component](#docs/_getting-started/my-first-component.md/my-first-component) and [Data flow](#docs/_core-concept/dataFlow.md/dataFlow). The `Subscriber` mixin below is [legacy](#docs/_core-concept/subscriber.md/subscriber).
4
+
3
5
  ## Where to put it?
4
6
 
5
7
  In this document, we consider the src directory of the project as the root.<br>