@supersoniks/concorde 4.9.9 → 4.9.92

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 (48) hide show
  1. package/build-infos.json +1 -1
  2. package/concorde-core.bundle.js +241 -241
  3. package/concorde-core.es.js +2931 -2851
  4. package/dist/concorde-core.bundle.js +241 -241
  5. package/dist/concorde-core.es.js +2931 -2851
  6. package/dist/js/core/decorators/api.js +146 -43
  7. package/dist/js/core/decorators/api.js.map +1 -1
  8. package/dist/js/decorators.js +4 -0
  9. package/dist/js/decorators.js.map +1 -1
  10. package/dist/types/core/decorators/api.d.ts +87 -60
  11. package/dist/types/core/decorators/api.d.ts.map +1 -1
  12. package/dist/types/decorators.d.ts +3 -1
  13. package/dist/types/decorators.d.ts.map +1 -1
  14. package/docs/assets/index-D2Q3JyQ6.css +1 -0
  15. package/docs/assets/{index-hElUgV9_.js → index-DURr6O71.js} +651 -736
  16. package/docs/crawl/docs/_decorators/get.html +89 -81
  17. package/docs/crawl/docs/_decorators/patch.html +43 -23
  18. package/docs/crawl/docs/_decorators/post.html +101 -72
  19. package/docs/crawl/docs/_decorators/put.html +44 -21
  20. package/docs/crawl/docs/_getting-started/ai-agents.html +45 -6
  21. package/docs/crawl/hubs/decorators.html +145 -70
  22. package/docs/crawl/hubs/remote-data.html +145 -70
  23. package/docs/index.html +2 -2
  24. package/docs/llms-full.txt +276 -147
  25. package/docs/llms.txt +4 -4
  26. package/docs/src/core/components/functional/queue/queue.md +0 -0
  27. package/docs/src/core/components/ui/button/button.md +0 -0
  28. package/docs/src/docs/_decorators/get.md +88 -80
  29. package/docs/src/docs/_decorators/patch.md +41 -25
  30. package/docs/src/docs/_decorators/post.md +104 -62
  31. package/docs/src/docs/_decorators/put.md +42 -24
  32. package/docs/src/docs/_getting-started/ai-agents.md +24 -4
  33. package/docs/src/docs/search/docs-search.json +182 -112
  34. package/docs/src/tsconfig.json +270 -267
  35. package/package.json +1 -1
  36. package/src/core/decorators/api.post.spec.ts +79 -1
  37. package/src/core/decorators/api.spec.ts +141 -1
  38. package/src/core/decorators/api.ts +330 -180
  39. package/src/decorators.ts +7 -0
  40. package/src/docs/_decorators/get.md +88 -80
  41. package/src/docs/_decorators/patch.md +41 -25
  42. package/src/docs/_decorators/post.md +104 -62
  43. package/src/docs/_decorators/put.md +42 -24
  44. package/src/docs/components/docs-demo-sources.ts +9 -14
  45. package/src/docs/example/decorators-demo-geo.ts +0 -21
  46. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +42 -133
  47. package/src/docs/search/docs-search.json +128 -133
  48. package/docs/assets/index-Bnp7gVaA.css +0 -1
@@ -4,8 +4,10 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>@put — Concorde</title>
7
- <meta name="description" content="Sends data through API.putDetailed. Same model as @post: decorated property is ApiResult&lt;T&gt; | null (request, response, result).">
8
- <meta name="keywords" content="Concorde, supersoniks, docs/_decorators/put, put, @put, decorator, API.putDetailed, ApiResult | null, request, response, result, Endpoint, DataProviderKey, ApiResult, @supersoniks/concorde/decorators">
7
+ <meta name="description" content="@put replaces a resource with the body from a publisher. It uses exactly the">
8
+ <meta name="keywords" content="Concorde, supersoniks, docs/_decorators/put, put, @put, decorator, Endpoint, DataProviderKey, ApiResult, send(component),
9
+
10
+ , when: &quot;before&quot;, autoPostOnBodyMutation: false, autoPostOnBodyMutation, skipIfBodyMissing">
9
11
  <meta name="concorde-doc-id" content="docs/_decorators/put">
10
12
  <link rel="canonical" href="https://concorde.supersoniks.org/crawl/docs/_decorators/put.html">
11
13
  </head>
@@ -15,32 +17,53 @@
15
17
  </header>
16
18
  <main>
17
19
  <article>
18
- <p class="doc-lead" id="doc-summary"><strong>Concorde decorator — @put</strong>. Sends data through API.putDetailed. Same model as @post: decorated property is ApiResult&lt;T&gt; | null (request, response, result). <span>Doc ID: <code>docs/_decorators/put</code>. Keywords: Concorde, supersoniks, docs/_decorators/put, put, @put, decorator, API.putDetailed, ApiResult | null, request, response, result, Endpoint, DataProviderKey, ApiResult, @supersoniks/concorde/decorators. URL: <a href="https://concorde.supersoniks.org/crawl/docs/_decorators/put.html">https://concorde.supersoniks.org/crawl/docs/_decorators/put.html</a>.</span></p>
20
+ <p class="doc-lead" id="doc-summary"><strong>Concorde decorator — @put</strong>. @put replaces a resource with the body from a publisher. It uses exactly the <span>Doc ID: <code>docs/_decorators/put</code>. Keywords: Concorde, supersoniks, docs/_decorators/put, put, @put, decorator, Endpoint, DataProviderKey, ApiResult, send(component),
21
+
22
+ , when: &quot;before&quot;, autoPostOnBodyMutation: false, autoPostOnBodyMutation, skipIfBodyMissing. URL: <a href="https://concorde.supersoniks.org/crawl/docs/_decorators/put.html">https://concorde.supersoniks.org/crawl/docs/_decorators/put.html</a>.</span></p>
19
23
  <h1 id="put">@put</h1>
20
- <p>Sends data through <a href="../../core/utils/api.ts"><code>API.putDetailed</code></a>. Same model as <a href="./post.html#post">@post</a>: decorated property is <strong><code>ApiResult&lt;T&gt; | null</code></strong> (<code>request</code>, <code>response</code>, <code>result</code>).</p>
21
- <p>Pass an <a href="../_misc/endpoint.html#endpoint"><code>Endpoint&lt;T&gt;</code></a> and a <code>DataProviderKey</code> for the <strong>request body</strong>. Import <code>put</code> and <code>ApiResult</code> from <code>@supersoniks/concorde/decorators</code>.</p>
22
- <h2 id="configuration">Configuration</h2>
23
- <p>Same as <a href="./post.html#post">@post</a> / <a href="./get.html#get">@get</a>: scoped <code>HTML.getApiConfiguration(host)</code> or <code>DataProviderKey&lt;APIConfiguration&gt;</code> as third argument.</p>
24
- <h2 id="options-putoptions">Options (<code>PutOptions</code>)</h2>
25
- <p>Same shape as <code>PostOptions</code> on <a href="./post.html#post">@post</a> (<code>ApiSendOptions</code>): <code>refetchEveryMs</code>, <code>skipIfBodyMissing</code>, <code>autoPostOnBodyMutation</code>, <code>triggerKey</code>, <code>skipEmptyPlaceholder</code>. See <a href="../_misc/dynamic-path.html#dynamic-path">Dynamic path placeholders</a> for <code>${sessionId}</code> and empty-string behaviour.</p>
24
+ <p><code>@put</code> replaces a resource with the body from a publisher. It uses exactly the
25
+ same model as <a href="./post.html#post">@post</a>:
26
+ <code>Endpoint&lt;T&gt;</code>, <code>DataProviderKey&lt;B&gt;</code>, <code>ApiResult&lt;T&gt;</code>, options, and the
27
+ <code>send(component)</code> handle.</p>
28
+ <h2 id="minimal-usage">Minimal usage</h2>
29
+ <pre><code class="language-typescript">const bodyKey = new DataProviderKey&lt;UpdateUser&gt;(&quot;users.form&quot;);
30
+ const updateUser = put(new Endpoint&lt;User&gt;(&quot;users/42&quot;), bodyKey);
31
+
32
+ @updateUser
33
+ @state()
34
+ payload?: ApiResult&lt;User&gt;;
35
+ </code></pre>
36
+ <p>To run the operation again from the component:</p>
37
+ <pre><code class="language-typescript">async update() {
38
+ await updateUser.send(this);
39
+ }
40
+ </code></pre>
41
+ <p><code>send(component)</code> returns a Promise resolved after the PUT completes. See
42
+ <a href="./post.html#post">@post</a> for the method-decorator form and the
43
+ <code>when: &quot;before&quot;</code> option.</p>
44
+ <p>The PUT is also sent automatically when the body mutates, unless
45
+ <code>autoPostOnBodyMutation: false</code> is set. See
46
+ <a href="./post.html#post">@post</a> for the option details:</p>
47
+ <ul>
48
+ <li><code>autoPostOnBodyMutation</code></li>
49
+ <li><code>skipIfBodyMissing</code></li>
50
+ <li><code>refetchEveryMs</code></li>
51
+ <li><code>skipEmptyPlaceholder</code></li>
52
+ <li><code>triggerKey</code></li>
53
+ </ul>
54
+ <p>Pass explicit API configuration as the third argument:</p>
55
+ <pre><code class="language-typescript">@put(endpoint, bodyKey, apiConfigurationKey)
56
+ </code></pre>
26
57
  <h2 id="import">Import</h2>
27
58
  <pre><code class="language-typescript">import { put, type ApiResult } from &quot;@supersoniks/concorde/decorators&quot;;
28
- import { Endpoint } from &quot;@supersoniks/concorde/utils/endpoint&quot;;
29
59
  import { DataProviderKey } from &quot;@supersoniks/concorde/dataProviderKey&quot;;
60
+ import { Endpoint } from &quot;@supersoniks/concorde/utils/endpoint&quot;;
30
61
  </code></pre>
31
- <h2 id="example">Example</h2>
32
- <pre><code class="language-typescript">const bodyKey = new DataProviderKey&amp;lt;UpdatePayload&amp;gt;(&quot;resourceBody&quot;);
33
-
34
- @put(new Endpoint&amp;lt;Resource, { resourceId: string }&amp;gt;(&quot;resources/${resourceId}&quot;), bodyKey)
35
- @state()
36
- payload?: ApiResult&amp;lt;Resource&amp;gt; | null;
37
- </code></pre>
38
- <p>Changing <code>resourceId</code> on the host re-runs the PUT when the path becomes ready — see <a href="../_misc/dynamic-path.html#dynamic-path">Dynamic path placeholders</a>.</p>
39
62
  <h2 id="see-also">See also</h2>
40
63
  <ul>
41
- <li><a href="./post.html#post">@post</a> — POST (live demos, polling, <code>@publish</code>)</li>
42
- <li><a href="./patch.html#patch">@patch</a> — partial update (PATCH)</li>
43
- <li><a href="../_misc/endpoint.html#endpoint">Endpoint</a> · <a href="../_misc/api-configuration.html#api-configuration">API configuration</a></li>
64
+ <li><a href="./post.html#post">@post</a> — options and triggers</li>
65
+ <li><a href="./patch.html#patch">@patch</a> — partial update</li>
66
+ <li><a href="../_misc/dynamic-path.html#dynamic-path">Dynamic path placeholders</a></li>
44
67
  </ul>
45
68
 
46
69
  </article>
@@ -6,7 +6,7 @@
6
6
  <title>AI agents (skills &amp; AGENTS.md) — Concorde</title>
7
7
  <meta name="description" content="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, migratio">
8
8
  <meta name="keywords" content="Concorde, supersoniks, docs/_getting-started/ai-agents, ai-agents, AI agents (skills &amp; AGENTS.md), guide, AGENTS.md, yarn ai:sync, ai-init, yarn add @supersoniks/concorde, |
9
- | Concorde repo (contributors) | , --merge-agents, --overlay , --cursor-only">
9
+ | Concorde repo (contributors) | , --skip-agents, --merge-agents, --force-agents">
10
10
  <meta name="concorde-doc-id" content="docs/_getting-started/ai-agents">
11
11
  <link rel="canonical" href="https://concorde.supersoniks.org/crawl/docs/_getting-started/ai-agents.html">
12
12
  </head>
@@ -17,7 +17,7 @@
17
17
  <main>
18
18
  <article>
19
19
  <p class="doc-lead" id="doc-summary"><strong>Concorde guide — AI agents (skills &amp; AGENTS.md)</strong>. 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, migratio <span>Doc ID: <code>docs/_getting-started/ai-agents</code>. Keywords: Concorde, supersoniks, docs/_getting-started/ai-agents, ai-agents, AI agents (skills &amp; AGENTS.md), guide, AGENTS.md, yarn ai:sync, ai-init, yarn add @supersoniks/concorde, |
20
- | Concorde repo (contributors) | , --merge-agents, --overlay , --cursor-only. URL: <a href="https://concorde.supersoniks.org/crawl/docs/_getting-started/ai-agents.html">https://concorde.supersoniks.org/crawl/docs/_getting-started/ai-agents.html</a>.</span></p>
20
+ | Concorde repo (contributors) | , --skip-agents, --merge-agents, --force-agents. URL: <a href="https://concorde.supersoniks.org/crawl/docs/_getting-started/ai-agents.html">https://concorde.supersoniks.org/crawl/docs/_getting-started/ai-agents.html</a>.</span></p>
21
21
  <h1 id="ai-agents-skills--agentsmd">AI agents (skills &amp; AGENTS.md)</h1>
22
22
  <p>Concorde ships <strong>skills</strong>, <strong>rules</strong>, and a root <strong><code>AGENTS.md</code></strong> so Cursor, JetBrains AI Assistant, and other coding agents follow framework patterns (DataProvider, decorators, short imports, scope, theme, migrations).</p>
23
23
  <p>On a <a href="./concorde-outside.html#concorde-outside">starter</a> project, run <code>yarn ai:sync</code> after install. On a <a href="./concorde-manual-install.html#concorde-manual-install">manual / brownfield</a> project, install Concorde first, then use <code>ai-init</code> below.</p>
@@ -57,12 +57,20 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
57
57
  </tr>
58
58
  </thead>
59
59
  <tbody><tr>
60
+ <td><code>--skip-agents</code></td>
61
+ <td>Never write <code>AGENTS.md</code> (skills / rules only)</td>
62
+ </tr>
63
+ <tr>
60
64
  <td><code>--merge-agents</code></td>
61
- <td>Append to an existing <code>AGENTS.md</code> instead of replacing it</td>
65
+ <td>Opt-in: keep the project preamble and append / refresh the Concorde block</td>
66
+ </tr>
67
+ <tr>
68
+ <td><code>--force-agents</code></td>
69
+ <td>Opt-in: <strong>replace</strong> the whole <code>AGENTS.md</code> (destructive)</td>
62
70
  </tr>
63
71
  <tr>
64
72
  <td><code>--overlay &lt;dir&gt;</code></td>
65
- <td>Copy extra rules/skills from another layer (e.g. starter kit)</td>
73
+ <td>Extra rules/skills + optional <code>AGENTS.concorde.md</code> for project-only Concorde agent notes</td>
66
74
  </tr>
67
75
  <tr>
68
76
  <td><code>--cursor-only</code></td>
@@ -73,6 +81,37 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
73
81
  <td>Install only <code>.aiassistant/rules/</code></td>
74
82
  </tr>
75
83
  </tbody></table>
84
+ <h2 id="agentsmd-policy-non-invasive"><code>AGENTS.md</code> policy (non-invasive)</h2>
85
+ <table>
86
+ <thead>
87
+ <tr>
88
+ <th>Situation</th>
89
+ <th>Default</th>
90
+ </tr>
91
+ </thead>
92
+ <tbody><tr>
93
+ <td>No <code>AGENTS.md</code></td>
94
+ <td>Create the Concorde guide</td>
95
+ </tr>
96
+ <tr>
97
+ <td>File with <code>&lt;!-- concorde-ai --&gt;</code></td>
98
+ <td>Refresh the managed zone only</td>
99
+ </tr>
100
+ <tr>
101
+ <td>File <strong>without</strong> marker (project notes)</td>
102
+ <td><strong>Left untouched</strong> — skills / rules are enough</td>
103
+ </tr>
104
+ <tr>
105
+ <td><code>--merge-agents</code> / <code>--force-agents</code> / <code>--skip-agents</code></td>
106
+ <td>See flags above</td>
107
+ </tr>
108
+ </tbody></table>
109
+ <pre><code class="language-text">[optional project preamble — short, project-only]
110
+ &lt;!-- concorde-ai --&gt;
111
+ &lt;package ai/AGENTS.md&gt;
112
+ [--- + overlay AGENTS.concorde.md]
113
+ </code></pre>
114
+ <p>Everything <strong>after</strong> <code>&lt;!-- concorde-ai --&gt;</code> is replaced on each <code>ai-init</code> run (idempotent). Do not paste a full copy of the Concorde guide above the marker — put project-specific notes in <code>AGENTS.concorde.md</code> (overlay). If the preamble duplicates package <code>AGENTS.md</code>, <code>ai-init</code> slims or drops it and prints a warning. Legacy filenames <code>AGENTS.overlay.md</code> / <code>AGENTS.starter.md</code> are still accepted with a deprecation warning.</p>
76
115
  <h2 id="what-gets-installed">What gets installed</h2>
77
116
  <table>
78
117
  <thead>
@@ -83,7 +122,7 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
83
122
  </thead>
84
123
  <tbody><tr>
85
124
  <td><code>AGENTS.md</code></td>
86
- <td>Project-level guide for agents (Concorde conventions)</td>
125
+ <td>Created only if missing; existing project-owned files are left alone unless <code>--merge-agents</code> / <code>--force-agents</code></td>
87
126
  </tr>
88
127
  <tr>
89
128
  <td><code>.cursor/skills/concorde/</code></td>
@@ -122,7 +161,7 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
122
161
  <ol>
123
162
  <li><strong>Starter project:</strong> <a href="./concorde-outside.html#concorde-outside">Installation</a> — <code>yarn ai:sync</code> is wired in the kit.</li>
124
163
  <li><strong>Existing / manual Vite project:</strong> <a href="./concorde-manual-install.html#concorde-manual-install">Manual installation</a>, then <strong><code>ai-init</code></strong> after <code>yarn add @supersoniks/concorde</code>.</li>
125
- <li>Commit <code>AGENTS.md</code>, <code>.cursor/</code>, and <code>.aiassistant/</code> if your team shares agent settings.</li>
164
+ <li>Commit <code>.cursor/</code> and <code>.aiassistant/</code> (and <code>AGENTS.md</code> only if you opted in / it was created) if your team shares agent settings.</li>
126
165
  <li>Re-run the same command when you bump <code>@supersoniks/concorde</code> to refresh skills from <code>node_modules/@supersoniks/concorde/ai/</code>.</li>
127
166
  <li>In Cursor, skills under <code>.cursor/skills/</code> are picked up automatically; mention a skill in chat for focused tasks (e.g. migration → <code>concorde-get-set-dp</code>).</li>
128
167
  </ol>
@@ -149,31 +149,55 @@ export class DemoBind extends LitElement {
149
149
  <section id="docs-_decorators-get" data-doc-id="docs/_decorators/get">
150
150
  <h2><a href="../docs/_decorators/get.html">@get</a></h2>
151
151
  <p><strong>Doc ID:</strong> <code>docs/_decorators/get</code> · <a href="../docs/_decorators/get.html">full page</a></p>
152
- <p>Loads data through API.getDetailed. The decorated property is ApiResult&lt;T&gt; | null: request, response (or null for dataProvider(...) resolution without HTTP), and typed result.</p>
152
+ <p>@get loads data and stores the result in an optional ApiResult&lt;T&gt; property.</p>
153
153
  <pre class="doc-excerpt">@get
154
154
 
155
- Loads data through API.getDetailed. The decorated property is ApiResult | null: request, response (or null for dataProvider(...) resolution without HTTP), and typed result.
155
+ @get loads data and stores the result in an optional ApiResult property.
156
+ The property is undefined until a result is available.
156
157
 
157
- Pass an Endpoint as the first argument. Import get and ApiResult from @supersoniks/concorde/decorators, and Endpoint from @supersoniks/concorde/utils/endpoint.
158
+ - payload.result: typed data;
159
+ - payload.response: the HTTP response;
160
+ - payload.request: the request that was sent.
158
161
 
159
- Configuration
162
+ Minimal usage
160
163
 
161
- - Default: HTML.getApiConfiguration(host) (ancestor serviceURL, etc.).
162
- - Second argument: DataProviderKey — config is read from the publisher at the resolved path; internal mutations trigger another GET. See API configuration for mock demos.
164
+ const usersEndpoint = new Endpoint (&quot;users&quot;);
163
165
 
164
- Dynamic path
166
+ @get(usersEndpoint)
167
+ @state()
168
+ payload?: ApiResult ;
169
+
170
+ The first argument is always an
171
+ Endpoint . API configuration is read
172
+ from the HTML scope (serviceURL, token, etc.), so the component is usually
173
+ placed below an element that provides this configuration.
174
+
175
+ Refetching a GET
176
+
177
+ From the component
178
+
179
+ Keep the decorator in a constant to access refetch(component). Refetch only
180
+ targets the instance passed as the argument, even before it has received a
181
+ result.
182
+
183
+ const usersGet = get(new Endpoint (&quot;users&quot;));
165
184
 
166
- ${prop} on the endpoint or config key is resolved on the host. While a placeholder is null or undefined, no GET runs. Optional skipEmptyPlaceholder: true also blocks &quot;&quot; (empty string only). Details: Dynamic path placeholders.
185
+ @usersGet
186
+ @state()
187
+ payload?: ApiResult ;
188
+
189
+ async refresh() {
190
+ const payload = await usersGet.refetch(this);
191
+ console.log(payload?.result);
192
+ }
167
193
 
168
- Options (GetOptions)
194
+ refetch(component) returns a Promise | undefined&gt; that resolves
195
+ after the GET has completed.
169
196
 
170
- Pass as the second argument (scoped config) or third (with a configuration key). Same shape as send decorators where applicable:
197
+ From a method decorator
171
198
 
172
- | Option | Description |
173
- |--------|-------------|
174
- | skipEmptyPlaceholder | Treat &quot;&quot; as not ready (see Dynamic path). |
175
- | refetchEveryMs | Automatic polling interval (ms). 0 or omitted = no polling. |
176
- | tri</pre>
199
+ The refetch can decorate a local method. The default is after; if the
200
+ method returns a Promise, the GET waits for its resol</pre>
177
201
  </section>
178
202
  <section id="docs-_decorators-handle" data-doc-id="docs/_decorators/handle">
179
203
  <h2><a href="../docs/_decorators/handle.html">@handle</a></h2>
@@ -253,71 +277,105 @@ export class DemoOnAssign extends LitElement {
253
277
  <section id="docs-_decorators-patch" data-doc-id="docs/_decorators/patch">
254
278
  <h2><a href="../docs/_decorators/patch.html">@patch</a></h2>
255
279
  <p><strong>Doc ID:</strong> <code>docs/_decorators/patch</code> · <a href="../docs/_decorators/patch.html">full page</a></p>
256
- <p>Sends data through API.patchDetailed. Same model as @post: decorated property is ApiResult&lt;T&gt; | null (request, response, result).</p>
280
+ <p>@patch applies a partial update with the body from a publisher. It uses the</p>
257
281
  <pre class="doc-excerpt">@patch
258
282
 
259
- Sends data through API.patchDetailed. Same model as @post: decorated property is ApiResult | null (request, response, result).
283
+ @patch applies a partial update with the body from a publisher. It uses the
284
+ same model as @post:
285
+ Endpoint , DataProviderKey , ApiResult , options, and the
286
+ send(component) handle.
260
287
 
261
- Pass an Endpoint and a DataProviderKey for the request body. Import patch and ApiResult from @supersoniks/concorde/decorators.
288
+ Minimal usage
262
289
 
263
- Configuration
290
+ const bodyKey = new DataProviderKey &gt;(&quot;users.patch&quot;);
291
+ const patchUser = patch(new Endpoint (&quot;users/42&quot;), bodyKey);
264
292
 
265
- Same as @post / @get: scoped HTML.getApiConfiguration(host) or DataProviderKey as third argument.
293
+ @patchUser
294
+ @state()
295
+ payload?: ApiResult ;
266
296
 
267
- Options (PatchOptions)
297
+ To run the operation again from the component:
268
298
 
269
- Same shape as PostOptions on @post (ApiSendOptions): refetchEveryMs, skipIfBodyMissing, autoPostOnBodyMutation, triggerKey, skipEmptyPlaceholder. See Dynamic path placeholders for ${sessionId} and empty-string behaviour.
299
+ async savePatch() {
300
+ await patchUser.send(this);
301
+ }
270
302
 
271
- Import
303
+ send(component) returns a Promise resolved after the PATCH completes. See
304
+ @post for the method-decorator form and the
305
+ when: &quot;before&quot; option.
272
306
 
273
- import { patch, type ApiResult } from &quot;@supersoniks/concorde/decorators&quot;;
274
- import { Endpoint } from &quot;@supersoniks/concorde/utils/endpoint&quot;;
275
- import { DataProviderKey } from &quot;@supersoniks/concorde/dataProviderKey&quot;;
307
+ The PATCH is also sent automatically when the body mutates, unless
308
+ autoPostOnBodyMutation: false is set. The available options are described in
309
+ @post:
276
310
 
277
- Example
311
+ - autoPostOnBodyMutation
312
+ - skipIfBodyMissing
313
+ - refetchEveryMs
314
+ - skipEmptyPlaceholder
315
+ - triggerKey
278
316
 
279
- const patchBodyKey = new DataProviderKey&amp;lt;Partial&amp;lt;Resource&amp;gt;&amp;gt;(&quot;resourcePatch&quot;);
317
+ Pass explicit API configuration as the third argument:
280
318
 
281
- @patch(
282
- new Endpoint&amp;lt;Resource, { resourceId: string }&amp;gt;(&quot;resources/${resourceId}&quot;),
283
- patchBodyKey,
284
- { skipEmptyPlaceholder: true },
285
- )
286
- @state()
287
- payload?: ApiResult&amp;lt;Resource&amp;gt; | null;
319
+ @patch(endpoint, bodyKey, apiConfigurationKey)
320
+
321
+ Import
322
+
323
+ import { patch, type ApiResult } from &quot;@supersoniks/concorde/decorators&quot;;
324
+ import { DataProviderKey } from &quot;@supersoniks/concorde/dataProviderKey&quot;;
325
+ import { Endpoint } from &quot;@supersoniks/concorde/utils/endpoint&quot;;
288
326
 
289
327
  See also
290
328
 
291
- - @post — POST (live demos)
292
- - @put — full rep</pre>
329
+ - @post —</pre>
293
330
  </section>
294
331
  <section id="docs-_decorators-post" data-doc-id="docs/_decorators/post">
295
332
  <h2><a href="../docs/_decorators/post.html">@post</a></h2>
296
333
  <p><strong>Doc ID:</strong> <code>docs/_decorators/post</code> · <a href="../docs/_decorators/post.html">full page</a></p>
297
- <p>Sends data through API.postDetailed. The decorated property is ApiResult&lt;T&gt; | null: request, response, and typed result.</p>
334
+ <p>@post sends the contents of a publisher and stores the response in an</p>
298
335
  <pre class="doc-excerpt">@post
299
336
 
300
- Sends data through API.postDetailed. The decorated property is ApiResult | null: request, response, and typed result.
337
+ @post sends the contents of a publisher and stores the response in an
338
+ optional ApiResult property. The property is undefined until a result
339
+ is available.
340
+
341
+ Minimal usage
342
+
343
+ Pass an Endpoint and a DataProviderKey for the request body.
344
+
345
+ const userBodyKey = new DataProviderKey (&quot;users.form&quot;);
346
+ const createUser = post(new Endpoint (&quot;users&quot;), userBodyKey);
347
+
348
+ @createUser
349
+ @state()
350
+ payload?: ApiResult ;
351
+
352
+ The current body is read from userBodyKey. By default, the POST is sent when
353
+ the component connects and after each body mutation. Mutations in the same
354
+ frame are coalesced into one request.
355
+
356
+ API configuration is read from the HTML scope, as with
357
+ @get.
301
358
 
302
- Pass an Endpoint as the first argument and a DataProviderKey for the request body as the second. Import post and ApiResult from @supersoniks/concorde/decorators, and Endpoint from @supersoniks/concorde/utils/endpoint.
359
+ Sending the POST again
303
360
 
304
- Configuration
361
+ From the component
305
362
 
306
- Same as @get: scoped HTML.getApiConfiguration(host) by default, or DataProviderKey as third argument. See API configuration for mock demos.
363
+ Keep the decorator to access send(component). The body is read again when the
364
+ operation runs.
307
365
 
308
- Optional PostOptions (third or fourth argument)
366
+ async saveAgain() {
367
+ const payload = await createUser.send(this);
368
+ console.log(payload?.result);
369
+ }
309
370
 
310
- | Option | Description |
311
- |--------|-------------|
312
- | refetchEveryMs | Re-post on an interval (ms). |
313
- | skipIfBodyMissing | Skip when body publisher is null/undefined (default: true). |
314
- | autoPostOnBodyMutation | Re-post when the body publisher mutates (default: true). false = manual via triggerKey.invalidate(). |
315
- | skipEmptyPlaceholder | If true, a placeholder resolved to '' blocks the request (empty string only — not 0 or false). See Dynamic paths. |
316
- | triggerKey | DataProviderKey — invalidate() re-runs the POST with the current body. |
371
+ send() returns a Promise | undefined&gt; that resolves after the
372
+ operation completes. It is useful for “Save” or “Retry” buttons and can repeat
373
+ an operation with side effects.
317
374
 
318
- When the POST runs again
375
+ From a method decorator
319
376
 
320
- - Body publisher onInternalMutation when autoPostOnBodyMutation is true (defa</pre>
377
+ The send action can decorate a local method. It runs after the method by
378
+ default, waits for an eventu</pre>
321
379
  </section>
322
380
  <section id="docs-_decorators-publish" data-doc-id="docs/_decorators/publish">
323
381
  <h2><a href="../docs/_decorators/publish.html">@publish</a></h2>
@@ -365,40 +423,57 @@ Dynamic paths use the same placeholder rules as @bind / @subscribe. Resolution a
365
423
  <section id="docs-_decorators-put" data-doc-id="docs/_decorators/put">
366
424
  <h2><a href="../docs/_decorators/put.html">@put</a></h2>
367
425
  <p><strong>Doc ID:</strong> <code>docs/_decorators/put</code> · <a href="../docs/_decorators/put.html">full page</a></p>
368
- <p>Sends data through API.putDetailed. Same model as @post: decorated property is ApiResult&lt;T&gt; | null (request, response, result).</p>
426
+ <p>@put replaces a resource with the body from a publisher. It uses exactly the</p>
369
427
  <pre class="doc-excerpt">@put
370
428
 
371
- Sends data through API.putDetailed. Same model as @post: decorated property is ApiResult | null (request, response, result).
429
+ @put replaces a resource with the body from a publisher. It uses exactly the
430
+ same model as @post:
431
+ Endpoint , DataProviderKey , ApiResult , options, and the
432
+ send(component) handle.
372
433
 
373
- Pass an Endpoint and a DataProviderKey for the request body. Import put and ApiResult from @supersoniks/concorde/decorators.
434
+ Minimal usage
374
435
 
375
- Configuration
436
+ const bodyKey = new DataProviderKey (&quot;users.form&quot;);
437
+ const updateUser = put(new Endpoint (&quot;users/42&quot;), bodyKey);
376
438
 
377
- Same as @post / @get: scoped HTML.getApiConfiguration(host) or DataProviderKey as third argument.
439
+ @updateUser
440
+ @state()
441
+ payload?: ApiResult ;
378
442
 
379
- Options (PutOptions)
443
+ To run the operation again from the component:
380
444
 
381
- Same shape as PostOptions on @post (ApiSendOptions): refetchEveryMs, skipIfBodyMissing, autoPostOnBodyMutation, triggerKey, skipEmptyPlaceholder. See Dynamic path placeholders for ${sessionId} and empty-string behaviour.
445
+ async update() {
446
+ await updateUser.send(this);
447
+ }
382
448
 
383
- Import
449
+ send(component) returns a Promise resolved after the PUT completes. See
450
+ @post for the method-decorator form and the
451
+ when: &quot;before&quot; option.
384
452
 
385
- import { put, type ApiResult } from &quot;@supersoniks/concorde/decorators&quot;;
386
- import { Endpoint } from &quot;@supersoniks/concorde/utils/endpoint&quot;;
387
- import { DataProviderKey } from &quot;@supersoniks/concorde/dataProviderKey&quot;;
453
+ The PUT is also sent automatically when the body mutates, unless
454
+ autoPostOnBodyMutation: false is set. See
455
+ @post for the option details:
388
456
 
389
- Example
457
+ - autoPostOnBodyMutation
458
+ - skipIfBodyMissing
459
+ - refetchEveryMs
460
+ - skipEmptyPlaceholder
461
+ - triggerKey
390
462
 
391
- const bodyKey = new DataProviderKey&amp;lt;UpdatePayload&amp;gt;(&quot;resourceBody&quot;);
463
+ Pass explicit API configuration as the third argument:
392
464
 
393
- @put(new Endpoint&amp;lt;Resource, { resourceId: string }&amp;gt;(&quot;resources/${resourceId}&quot;), bodyKey)
394
- @state()
395
- payload?: ApiResult&amp;lt;Resource&amp;gt; | null;
465
+ @put(endpoint, bodyKey, apiConfigurationKey)
396
466
 
397
- Changing resourceId on the host re-runs the PUT when the path becomes ready — see Dynamic path placeholders.
467
+ Import
468
+
469
+ import { put, type ApiResult } from &quot;@supersoniks/concorde/decorators&quot;;
470
+ import { DataProviderKey } from &quot;@supersoniks/concorde/dataProviderKey&quot;;
471
+ import { Endpoint } from &quot;@supersoniks/concorde/utils/endpoint&quot;;
398
472
 
399
473
  See also
400
474
 
401
- - @post —</pre>
475
+ - @post — options and triggers
476
+ - @</pre>
402
477
  </section>
403
478
  <section id="docs-_decorators-subscribe" data-doc-id="docs/_decorators/subscribe">
404
479
  <h2><a href="../docs/_decorators/subscribe.html">@subscribe</a></h2>