@supersoniks/concorde 4.6.0 → 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 (179) 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 +127 -127
  18. package/concorde-core.es.js +1435 -1364
  19. package/dist/altcha-widget.js +2662 -0
  20. package/dist/concorde-core.bundle.js +127 -127
  21. package/dist/concorde-core.es.js +1435 -1364
  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 +34 -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/directives/DataProvider.sub.spec.ts +96 -0
  108. package/src/core/directives/DataProvider.ts +109 -40
  109. package/src/core/utils/PublisherProxy.ts +33 -18
  110. package/src/core/utils/dataProviderKey.ts +23 -0
  111. package/src/core/utils/publisherPathKey.spec.ts +58 -0
  112. package/src/docs/_core-concept/dataFlow.md +73 -0
  113. package/src/docs/_core-concept/subscriber.md +9 -10
  114. package/src/docs/_decorators/ancestor-attribute.md +4 -3
  115. package/src/docs/_decorators/auto-subscribe.md +19 -16
  116. package/src/docs/_decorators/bind.md +19 -16
  117. package/src/docs/_decorators/get.md +7 -4
  118. package/src/docs/_decorators/handle.md +15 -13
  119. package/src/docs/_decorators/on-assign.md +53 -53
  120. package/src/docs/_decorators/publish.md +2 -1
  121. package/src/docs/_decorators/subscribe.md +70 -9
  122. package/src/docs/_decorators/wait-for-ancestors.md +13 -10
  123. package/src/docs/_directives/sub.md +91 -0
  124. package/src/docs/_getting-started/ai-agents.md +56 -0
  125. package/src/docs/_getting-started/concorde-manual-install.md +133 -0
  126. package/src/docs/_getting-started/concorde-outside.md +13 -123
  127. package/src/docs/_getting-started/create-a-component.md +2 -0
  128. package/src/docs/_getting-started/my-first-component.md +236 -0
  129. package/src/docs/_getting-started/my-first-subscriber.md +29 -83
  130. package/src/docs/_getting-started/pubsub.md +21 -134
  131. package/src/docs/_getting-started/start.md +26 -18
  132. package/src/docs/_misc/api-configuration.md +79 -0
  133. package/src/docs/_misc/dataProviderKey.md +34 -1
  134. package/src/docs/_misc/docs-mock-api.md +60 -0
  135. package/src/docs/_misc/endpoint.md +2 -1
  136. package/src/docs/_misc/html-integration.md +13 -0
  137. package/src/docs/code.ts +58 -12
  138. package/src/docs/components/docs-demo-sources.ts +397 -0
  139. package/src/docs/components/docs-lit-demo-raw.ts +28 -0
  140. package/src/docs/components/docs-lit-demo.ts +166 -0
  141. package/src/docs/components/docs-source-link.ts +72 -0
  142. package/src/docs/docs-location.ts +54 -0
  143. package/src/docs/docs.ts +12 -0
  144. package/src/docs/example/decorators-demo-bind-demos.ts +41 -46
  145. package/src/docs/example/decorators-demo-geo.ts +16 -11
  146. package/src/docs/example/decorators-demo-init.ts +2 -228
  147. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +54 -14
  148. package/src/docs/example/decorators-demo.ts +71 -70
  149. package/src/docs/example/docs-api-config-demos.ts +234 -0
  150. package/src/docs/example/docs-joke-demos.ts +297 -0
  151. package/src/docs/example/docs-list-demos.ts +179 -0
  152. package/src/docs/example/docs-provider-keys.ts +315 -0
  153. package/src/docs/example/docs-queue-demos.ts +114 -0
  154. package/src/docs/example/docs-router-demos.ts +89 -0
  155. package/src/docs/example/docs-submit-demos.ts +455 -0
  156. package/src/docs/example/docs-toggle-demos.ts +73 -0
  157. package/src/docs/example/docs-user-two-scopes.ts +37 -0
  158. package/src/docs/example/docs-users-list.ts +71 -0
  159. package/src/docs/example/users.ts +41 -24
  160. package/src/docs/mock-api/api-config-mock.ts +152 -0
  161. package/src/docs/mock-api/fixtures.ts +377 -0
  162. package/src/docs/mock-api/register.ts +25 -0
  163. package/src/docs/mock-api/router.ts +234 -0
  164. package/src/docs/mock-api/service-worker.ts +23 -0
  165. package/src/docs/mock-api/urls.ts +11 -0
  166. package/src/docs/navigation/navigation.ts +39 -7
  167. package/src/docs/search/docs-search.json +4021 -936
  168. package/src/docs/search/markdown-renderer.ts +7 -3
  169. package/src/docs/search/page.ts +11 -14
  170. package/src/docs/search/sonic-code-markdown.spec.ts +29 -0
  171. package/src/docs/search/sonic-code-markdown.ts +28 -0
  172. package/src/docs.ts +4 -0
  173. package/src/tsconfig.json +87 -0
  174. package/src/tsconfig.tsbuildinfo +1 -1
  175. package/vite.config.mts +8 -0
  176. package/docs/assets/index-CaysOMFz.js +0 -5046
  177. package/docs/assets/index-D8mGoXzF.css +0 -1
  178. package/docs/src/docs/_misc/templates-demo.md +0 -19
  179. package/src/docs/_misc/templates-demo.md +0 -19
@@ -1,12 +1,14 @@
1
- # The subscriber mixin
1
+ # Legacy: Subscriber mixin
2
2
 
3
- This is a mixin that is commonly extended by Concorde core components and destination components. Pure UI components usually don't extend it, especially those outside of form components.
3
+ > **New app components:** [My first component](#docs/_getting-started/my-first-component.md/my-first-component) and [Data flow](#docs/_core-concept/dataFlow.md/dataFlow) extend `LitElement` with decorators (`@subscribe`, `@ancestorAttribute`, …). This mixin remains in **core** components (`sonic-list`, `sonic-fetch`, …) and [legacy tutorials](#docs/_getting-started/my-first-subscriber.md/my-first-subscriber).
4
+
5
+ The Subscriber mixin was commonly extended by Concorde core components and older destination components. Pure UI components usually don't extend it, especially those outside of form components.
4
6
 
5
7
  ## DataProvider Attribute: Automatic Filling of Subscriber Properties
6
8
 
7
9
  Upon being added to the DOM (connectedCallback), subscribers search for the first occurrence of the `dataProvider` attribute in their parent's HTML structure.
8
10
 
9
- The value of this attribute is used to obtain a publisher via the PublisherManager (see [🥨 Sharing Data](#docs/_getting-started/pubsub.md/pubsub)).
11
+ The value of this attribute is the DataProvider path (see [Data flow](#docs/_core-concept/dataFlow.md/dataFlow) and [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey); legacy API: [Sharing Data](#docs/_getting-started/pubsub.md/pubsub)).
10
12
 
11
13
  The subscriber then subscribes to the publisher as a data template to be filled.
12
14
 
@@ -51,14 +53,11 @@ Suppose that:
51
53
  </sonic-code>
52
54
  - We want to keep the display of an image and its `title` attribute up to date, as well as a "contact" button to email the person in the photo. The content of the subscriber could be as follows:
53
55
 
54
- <sonic-code language="html">
55
- <template>
56
- <img data-bind ::src="$img.avatar" ::title="ucFirst|$img.caption" />
57
- <a data-bind ::href="mailto:$email" ::inner-html="$email"></a>
58
- </template>
59
- </sonic-code>
56
+ In a **Lit** app, use the same data with [data configuration](#docs/_getting-started/my-first-component.md/my-first-component) (`@subscribe` + `DataProviderKey`) on a small row component — see `docs-user` in `src/docs/example/users.ts`.
57
+
58
+ For **HTML-only** embedding (no Lit), attribute binding is described in [HTML integration](#docs/_misc/html-integration.md/html-integration) and in the Legacy [Subscriber mixin](#docs/_core-concept/subscriber.md/subscriber) pages.
60
59
 
61
- This example also illustrates:
60
+ This pattern also illustrates:
62
61
 
63
62
  - Binding to subproperties using dot syntax, as done for the `src` attribute of the `img` tag.
64
63
  - Using a simple expression to include the property within a string, as in creating a `mailto` link.
@@ -25,15 +25,15 @@ The component reads `dataProvider` and `testAttribute` from its ancestor wrapper
25
25
  import { html, LitElement } from "lit";
26
26
  import { customElement } from "lit/decorators.js";
27
27
  import { ancestorAttribute } from "@supersoniks/concorde/decorators";
28
- //
28
+
29
29
  @customElement("demo-ancestor-attribute")
30
30
  export class DemoAncestorAttribute extends LitElement {
31
31
  @ancestorAttribute("dataProvider")
32
32
  dataProvider: string | null = null;
33
- //
33
+
34
34
  @ancestorAttribute("testAttribute")
35
35
  testAttribute: string | null = null;
36
- //
36
+
37
37
  render() {
38
38
  return html`
39
39
  <section>
@@ -49,6 +49,7 @@ export class DemoAncestorAttribute extends LitElement {
49
49
  <sonic-code>
50
50
  <template>
51
51
  <div dataProvider="demoDataProvider" testAttribute="test-value-123">
52
+ <docs-demo-sources for="demo-ancestor-attribute"></docs-demo-sources>
52
53
  <demo-ancestor-attribute></demo-ancestor-attribute>
53
54
  </div>
54
55
  </template>
@@ -1,5 +1,7 @@
1
1
  # @autoSubscribe
2
2
 
3
+ > **Legacy:** prefer [@subscribe](#docs/_decorators/subscribe.md/subscribe) + `DataProviderKey`. Examples below may still show `PublisherManager` for existing codebases.
4
+
3
5
  The `@autoSubscribe` decorator automatically detects which publishers are accessed within a method and subscribes to them. When any of these publishers change, the method is automatically re-executed.
4
6
 
5
7
  ## Principle
@@ -24,10 +26,10 @@ import { autoSubscribe } from "@supersoniks/concorde/decorators";
24
26
  @customElement("demo-auto-subscribe")
25
27
  export class DemoAutoSubscribe extends LitElement {
26
28
  static styles = [tailwind];
27
- //
29
+
28
30
  @state() displayText: string = "";
29
31
  @state() computedValue: number = 0;
30
- //
32
+
31
33
  @autoSubscribe()
32
34
  updateDisplay() {
33
35
  const value1 = PublisherManager.get("autoValue1").get() || 0;
@@ -35,7 +37,7 @@ export class DemoAutoSubscribe extends LitElement {
35
37
  this.computedValue = value1 + value2;
36
38
  this.displayText = `${value1} + ${value2} = ${this.computedValue}`;
37
39
  }
38
- //
40
+
39
41
  render() {
40
42
  return html`
41
43
  <p><strong>${this.displayText}</strong></p>
@@ -49,7 +51,7 @@ export class DemoAutoSubscribe extends LitElement {
49
51
  </div>
50
52
  `;
51
53
  }
52
- //
54
+
53
55
  randomizeValue(publisherId: string) {
54
56
  const value = PublisherManager.get(publisherId);
55
57
  value.set(Math.floor(Math.random() * 100));
@@ -61,6 +63,7 @@ export class DemoAutoSubscribe extends LitElement {
61
63
 
62
64
  <sonic-code >
63
65
  <template>
66
+ <docs-demo-sources for="demo-auto-subscribe"></docs-demo-sources>
64
67
  <demo-auto-subscribe></demo-auto-subscribe>
65
68
  </template>
66
69
  </sonic-code>
@@ -75,12 +78,12 @@ export class ReactiveView extends LitElement {
75
78
  render() {
76
79
  const data = PublisherManager.get("myData");
77
80
  const config = PublisherManager.get("config");
78
- //
81
+
79
82
  // This render method will be automatically re-executed
80
83
  // when myData or config change
81
84
  const value = data.get()?.value || 0;
82
85
  const multiplier = config.get()?.multiplier || 1;
83
- //
86
+
84
87
  return html`
85
88
  <div>
86
89
  <h1>Result: ${value * multiplier}</h1>
@@ -125,40 +128,40 @@ import { html, LitElement } from "lit";
125
128
  import { customElement } from "lit/decorators.js";
126
129
  import { autoSubscribe } from "@supersoniks/concorde/decorators";
127
130
  import { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy";
128
- //
131
+
129
132
  @customElement("shopping-cart")
130
133
  export class ShoppingCart extends LitElement {
131
134
  items: any[] = [];
132
135
  total: number = 0;
133
136
  discount: number = 0;
134
- //
137
+
135
138
  @autoSubscribe()
136
139
  calculateTotal() {
137
140
  const cart = PublisherManager.get("cart");
138
141
  const promo = PublisherManager.get("promo");
139
- //
142
+
140
143
  // Access cart items
141
144
  this.items = cart.items.get() || [];
142
- //
145
+
143
146
  // Access promo code
144
147
  const promoCode = promo.code.get() || "";
145
148
  const discountPercent = promoCode === "SAVE10" ? 0.1 : 0;
146
- //
149
+
147
150
  // Calculate totals
148
151
  const subtotal = this.items.reduce((sum, item) =>
149
152
  sum + (item.price * item.quantity), 0
150
153
  );
151
154
  this.discount = subtotal * discountPercent;
152
155
  this.total = subtotal - this.discount;
153
- //
156
+
154
157
  this.requestUpdate();
155
158
  }
156
- //
159
+
157
160
  connectedCallback() {
158
161
  super.connectedCallback();
159
162
  this.calculateTotal();
160
163
  }
161
- //
164
+
162
165
  render() {
163
166
  return html`
164
167
  <div class="cart">
@@ -175,14 +178,14 @@ export class ShoppingCart extends LitElement {
175
178
  `;
176
179
  }
177
180
  }
178
- //
181
+
179
182
  // When you update the publishers, calculateTotal is automatically called:
180
183
  const cart = PublisherManager.get("cart");
181
184
  cart.items.set([
182
185
  { name: "Product 1", price: 10, quantity: 2 },
183
186
  { name: "Product 2", price: 15, quantity: 1 }
184
187
  ]);
185
- //
188
+
186
189
  const promo = PublisherManager.get("promo");
187
190
  promo.code.set("SAVE10");
188
191
  // calculateTotal will be automatically called and the UI will update
@@ -8,7 +8,7 @@ For Lit re-renders, also add `@state()` on the same property.
8
8
 
9
9
  ## Principle
10
10
 
11
- The decorator subscribes via `PublisherManager` using dot notation. Publisher updates flow into the decorated property.
11
+ The decorator subscribes to the DataProvider store using dot notation or a `DataProviderKey`. Updates flow into the decorated property ([Data flow](#docs/_core-concept/dataFlow.md/dataFlow)).
12
12
 
13
13
  ## Import
14
14
 
@@ -25,26 +25,26 @@ import { bind } from "@supersoniks/concorde/decorators";
25
25
  @customElement("demo-bind")
26
26
  export class DemoBind extends LitElement {
27
27
  static styles = [tailwind];
28
- //
28
+
29
29
  @bind("demoData.firstName")
30
30
  @state()
31
31
  firstName = "";
32
- //
32
+
33
33
  @bind("demoData.lastName")
34
34
  @state()
35
35
  lastName: string = "";
36
- //
36
+
37
37
  @bind("demoData.count")
38
38
  @state()
39
39
  count: number = 0;
40
- //
40
+
41
41
  render() {
42
42
  return //......
43
43
  }
44
- //
44
+
45
45
  updateData() {
46
- const demoData = PublisherManager.get("demoData");
47
- const demoUsers = PublisherManager.get("demoUsers");
46
+ set(demoDataKey, { ...get(demoDataKey), count: get(demoDataKey).count + 1 });
47
+ // see demo-bind in src/docs/example/decorators-demo-bind-demos.ts
48
48
  const randomIndex = Math.floor(Math.random() * demoUsers.get().length);
49
49
  const randomUser = demoUsers.get()[randomIndex];
50
50
  demoData.set({
@@ -54,12 +54,13 @@ export class DemoBind extends LitElement {
54
54
  });
55
55
  }
56
56
  }
57
- //
57
+
58
58
  </template>
59
59
  </sonic-code>
60
60
 
61
61
  <sonic-code>
62
62
  <template>
63
+ <docs-demo-sources for="demo-bind"></docs-demo-sources>
63
64
  <demo-bind></demo-bind>
64
65
  </template>
65
66
  </sonic-code>
@@ -72,10 +73,10 @@ export class DemoBind extends LitElement {
72
73
  <template>
73
74
  import { bind } from "@supersoniks/concorde/decorators";
74
75
  import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
75
- //
76
+
76
77
  type Data = { count: number };
77
78
  const dataKey = new DataProviderKey<Data>("data");
78
- //
79
+
79
80
  @bind(dataKey.count, { reflect: true })
80
81
  @state()
81
82
  count: number = 0;
@@ -99,15 +100,15 @@ avatar: string;
99
100
  @customElement("demo-bind-reflect")
100
101
  export class DemoBindReflect extends LitElement {
101
102
  static styles = [tailwind];
102
- //
103
+
103
104
  @bind("bindReflectDemo.count", { reflect: true })
104
105
  @state()
105
106
  withReflect: number = 0;
106
- //
107
+
107
108
  @bind("bindReflectDemo.count")
108
109
  @state()
109
110
  withoutReflect: number = 0;
110
- //
111
+
111
112
  render() {
112
113
  return html`
113
114
  <div class="mb-3">
@@ -124,13 +125,14 @@ export class DemoBindReflect extends LitElement {
124
125
  `;
125
126
  }
126
127
  }
127
- //
128
+
128
129
  </template>
129
130
  </sonic-code>
130
131
 
131
132
  <sonic-code toggleCode>
132
133
  <template>
133
- <demo-bind-reflect></demo-bind-reflect>
134
+ <docs-demo-sources for="demo-bind-reflect"></docs-demo-sources>
135
+ <demo-bind-reflect></demo-bind-reflect>
134
136
  </template>
135
137
  </sonic-code>
136
138
 
@@ -148,6 +150,7 @@ Use `${prop}` or `${this.prop}` inside a **normal string literal** (not a JS tem
148
150
 
149
151
  <sonic-code>
150
152
  <template>
153
+ <docs-demo-sources for="demo-bind-dynamic"></docs-demo-sources>
151
154
  <demo-bind-dynamic></demo-bind-dynamic>
152
155
  </template>
153
156
  </sonic-code>
@@ -7,7 +7,7 @@ Pass an [`Endpoint<T>`](#docs/_misc/endpoint.md/endpoint) as the first argument.
7
7
  ## Configuration
8
8
 
9
9
  - **Default:** `HTML.getApiConfiguration(host)` (ancestor `serviceURL`, etc.).
10
- - **Second argument:** `DataProviderKey<APIConfiguration>` — config is read from the publisher at the resolved path; internal mutations trigger another GET.
10
+ - **Second argument:** `DataProviderKey<APIConfiguration>` — config is read from the publisher at the resolved path; internal mutations trigger another GET. See [API configuration](#docs/_misc/api-configuration.md/api-configuration) for mock demos.
11
11
 
12
12
  ## When the GET runs again
13
13
 
@@ -26,7 +26,7 @@ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
26
26
 
27
27
  ## Minimal example
28
28
 
29
- Same demo service as [`sonic-queue`](../../core/components/functional/queue/queue.demo.ts) (`geo.api.gouv.fr`). Publisher setup lives in `decorators-demo-geo.ts` and `decorators-demo-subscribe-publish-get-demos.ts`.
29
+ Same demo service as [`sonic-queue`](../../core/components/functional/queue/queue.demo.ts) (`/docs-mock-api/geo/`). Publisher setup lives in `decorators-demo-geo.ts` and `decorators-demo-subscribe-publish-get-demos.ts`.
30
30
 
31
31
  <sonic-code language="typescript">
32
32
  <template>
@@ -40,6 +40,7 @@ payload: ApiGetResult<User> | null = null;
40
40
 
41
41
  <sonic-code>
42
42
  <template>
43
+ <docs-demo-sources for="demo-api-get"></docs-demo-sources>
43
44
  <demo-api-get></demo-api-get>
44
45
  </template>
45
46
  </sonic-code>
@@ -48,15 +49,17 @@ Dynamic config and endpoint path (`demo-api-get-configuration-key` in doc source
48
49
 
49
50
  <sonic-code>
50
51
  <template>
52
+ <docs-demo-sources for="demo-api-get-configuration-key"></docs-demo-sources>
51
53
  <demo-api-get-configuration-key></demo-api-get-configuration-key>
52
54
  </template>
53
55
  </sonic-code>
54
56
 
55
- Scoped `@get` with `@publish` / `@subscribe` on the payload (see [@publish](#docs/_decorators/publish.md/publish) and [@subscribe](#docs/_decorators/subscribe.md/subscribe)) — wrap under an ancestor with `serviceURL="https://geo.api.gouv.fr/"`:
57
+ Scoped `@get` with `@publish` / `@subscribe` on the payload (see [@publish](#docs/_decorators/publish.md/publish) and [@subscribe](#docs/_decorators/subscribe.md/subscribe)) — wrap under an ancestor with `serviceURL="/docs-mock-api/geo/"`:
56
58
 
57
59
  <sonic-code>
58
60
  <template>
59
- <div serviceURL="https://geo.api.gouv.fr/">
61
+ <div serviceURL="/docs-mock-api/geo/">
62
+ <docs-demo-sources for="demo-api-get-publish-subscribe"></docs-demo-sources>
60
63
  <demo-api-get-publish-subscribe></demo-api-get-publish-subscribe>
61
64
  </div>
62
65
  </template>
@@ -12,6 +12,7 @@ By default the method is called on **every** assignment, even when the value is
12
12
  <template>
13
13
  import { handle, Skip } from "@supersoniks/concorde/decorators";
14
14
  import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
15
+ import { get, set } from "@supersoniks/concorde/utils";
15
16
  </template>
16
17
  </sonic-code>
17
18
 
@@ -21,24 +22,23 @@ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
21
22
  <template>
22
23
  type DemoCounterData = { count: number };
23
24
  const demoDataKey = new DataProviderKey&lt;DemoCounterData&gt;("demoData");
24
- //
25
+
25
26
  @customElement("demo-handle")
26
27
  export class DemoHandle extends LitElement {
27
28
  @state() doubled = 0;
28
29
  @state() lastUpdate = "";
29
- //
30
+
30
31
  @handle(demoDataKey.count)
31
32
  onCountChange(count: number) {
32
33
  this.doubled = count * 2;
33
34
  this.lastUpdate = new Date().toLocaleTimeString();
34
35
  }
35
- //
36
+
36
37
  incrementCount() {
37
- const publisher = PublisherManager.get("demoData");
38
- const data = publisher.get() as DemoCounterData;
39
- publisher.set({ ...data, count: data.count + 1 });
38
+ const data = get(demoDataKey);
39
+ set(demoDataKey, { ...data, count: data.count + 1 });
40
40
  }
41
- //
41
+
42
42
  render() {
43
43
  return html`
44
44
  &lt;p&gt;Doubled count: ${this.doubled}&lt;/p&gt;
@@ -52,6 +52,7 @@ export class DemoHandle extends LitElement {
52
52
 
53
53
  <sonic-code>
54
54
  <template>
55
+ <docs-demo-sources for="demo-handle"></docs-demo-sources>
55
56
  <demo-handle></demo-handle>
56
57
  </template>
57
58
  </sonic-code>
@@ -63,21 +64,21 @@ Placeholders in `DataProviderKey` resolve from the host component’s properties
63
64
  <sonic-code language="typescript">
64
65
  <template>
65
66
  type User = { firstName: string; lastName: string; email: string };
66
- //
67
+
67
68
  @customElement("demo-handle-dynamic")
68
69
  export class DemoHandleDynamic extends LitElement {
69
70
  @property({ type: Number })
70
71
  userIndex = 0;
71
- //
72
+
72
73
  @state() displayName = "";
73
74
  @state() lastUpdate = "";
74
- //
75
+
75
76
  @handle(new DataProviderKey&lt;User, { userIndex: number }&gt;("demoUsers.${userIndex}"))
76
77
  onUserAssigned(user: User) {
77
78
  this.displayName = `${user.firstName} ${user.lastName}`;
78
79
  this.lastUpdate = new Date().toLocaleTimeString();
79
80
  }
80
- //
81
+
81
82
  render() {
82
83
  return html`...`;
83
84
  }
@@ -87,6 +88,7 @@ export class DemoHandleDynamic extends LitElement {
87
88
 
88
89
  <sonic-code>
89
90
  <template>
91
+ <docs-demo-sources for="demo-handle-dynamic"></docs-demo-sources>
90
92
  <demo-handle-dynamic></demo-handle-dynamic>
91
93
  </template>
92
94
  </sonic-code>
@@ -100,10 +102,10 @@ export class DemoHandleDynamic extends LitElement {
100
102
  type QueueConfig = { onInactivity: { stillHere: { show: boolean } } };
101
103
  const config = new DataProviderKey&lt;QueueConfig&gt;("sessionQueueConfig");
102
104
  const idle = new DataProviderKey&lt;{ isIdle: boolean }&gt;("idleStatus");
103
- //
105
+
104
106
  @customElement("demo-handle-multi")
105
107
  export class DemoHandleMulti extends LitElement {
106
- //
108
+
107
109
  // show: boolean, isIdle: boolean — fully typed from the keys
108
110
  @handle(config.onInactivity.stillHere.show, idle.isIdle)
109
111
  onInactivity(show: boolean, isIdle: boolean) {