@supersoniks/concorde 4.9.9 → 4.9.91

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 +2908 -2845
  4. package/dist/concorde-core.bundle.js +241 -241
  5. package/dist/concorde-core.es.js +2908 -2845
  6. package/dist/js/core/decorators/api.js +92 -2
  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 +82 -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-BL6WVF7g.css +1 -0
  15. package/docs/assets/{index-hElUgV9_.js → index-DVn8AeyA.js} +572 -555
  16. package/docs/crawl/docs/_decorators/get.html +64 -81
  17. package/docs/crawl/docs/_decorators/patch.html +35 -23
  18. package/docs/crawl/docs/_decorators/post.html +72 -72
  19. package/docs/crawl/docs/_decorators/put.html +36 -21
  20. package/docs/crawl/docs/_getting-started/ai-agents.html +45 -6
  21. package/docs/crawl/hubs/decorators.html +141 -69
  22. package/docs/crawl/hubs/remote-data.html +141 -69
  23. package/docs/index.html +2 -2
  24. package/docs/llms-full.txt +203 -149
  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 +55 -81
  29. package/docs/src/docs/_decorators/patch.md +36 -25
  30. package/docs/src/docs/_decorators/post.md +71 -62
  31. package/docs/src/docs/_decorators/put.md +37 -24
  32. package/docs/src/docs/_getting-started/ai-agents.md +24 -4
  33. package/docs/src/docs/search/docs-search.json +151 -1
  34. package/docs/src/tsconfig.json +3 -0
  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 +100 -1
  38. package/src/core/decorators/api.ts +252 -138
  39. package/src/decorators.ts +7 -0
  40. package/src/docs/_decorators/get.md +81 -80
  41. package/src/docs/_decorators/patch.md +36 -25
  42. package/src/docs/_decorators/post.md +99 -62
  43. package/src/docs/_decorators/put.md +37 -24
  44. package/src/docs/components/docs-demo-sources.ts +1 -6
  45. package/src/docs/example/decorators-demo-geo.ts +0 -21
  46. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +41 -132
  47. package/src/docs/search/docs-search.json +128 -133
  48. package/docs/assets/index-Bnp7gVaA.css +0 -1
@@ -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,56 @@ 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 ApiResult&lt;T&gt; | null 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 ApiResult | null property.
156
156
 
157
- Pass an Endpoint as the first argument. Import get and ApiResult from @supersoniks/concorde/decorators, and Endpoint from @supersoniks/concorde/utils/endpoint.
157
+ - payload.result: typed data;
158
+ - payload.response: the HTTP response;
159
+ - payload.request: the request that was sent.
158
160
 
159
- Configuration
161
+ Minimal usage
160
162
 
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.
163
+ const usersEndpoint = new Endpoint (&quot;users&quot;);
163
164
 
164
- Dynamic path
165
+ @get(usersEndpoint)
166
+ @state()
167
+ payload: ApiResult | null = null;
168
+
169
+ The first argument is always an
170
+ Endpoint . API configuration is read
171
+ from the HTML scope (serviceURL, token, etc.), so the component is usually
172
+ placed below an element that provides this configuration.
173
+
174
+ Refetching a GET
165
175
 
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.
176
+ From the component
177
+
178
+ Keep the decorator in a constant to access refetch(component). Refetch only
179
+ targets the instance passed as the argument, even before it has received a
180
+ result.
181
+
182
+ const usersGet = get(new Endpoint (&quot;users&quot;));
183
+
184
+ @usersGet
185
+ @state()
186
+ payload: ApiResult | null = null;
187
+
188
+ refresh() {
189
+ usersGet.refetch(this);
190
+ }
167
191
 
168
192
  Options (GetOptions)
169
193
 
170
- Pass as the second argument (scoped config) or third (with a configuration key). Same shape as send decorators where applicable:
194
+ Options are the second argument, or the third argument when an API
195
+ configuration key is provided.
171
196
 
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>
197
+ - skipEmptyPlaceholder: blocks the GET when ${prop} is &quot;&quot;.
198
+ - refetchEveryMs: automatically runs the GET again after this interval
199
+ (milliseconds). Omit the option, or use 0, to disable polling.
200
+
201
+ With a configurat</pre>
177
202
  </section>
178
203
  <section id="docs-_decorators-handle" data-doc-id="docs/_decorators/handle">
179
204
  <h2><a href="../docs/_decorators/handle.html">@handle</a></h2>
@@ -253,71 +278,105 @@ export class DemoOnAssign extends LitElement {
253
278
  <section id="docs-_decorators-patch" data-doc-id="docs/_decorators/patch">
254
279
  <h2><a href="../docs/_decorators/patch.html">@patch</a></h2>
255
280
  <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>
281
+ <p>@patch applies a partial update with the body from a publisher. It uses the</p>
257
282
  <pre class="doc-excerpt">@patch
258
283
 
259
- Sends data through API.patchDetailed. Same model as @post: decorated property is ApiResult | null (request, response, result).
284
+ @patch applies a partial update with the body from a publisher. It uses the
285
+ same model as @post:
286
+ Endpoint , DataProviderKey , ApiResult , options, and the
287
+ send(component) handle.
288
+
289
+ Minimal usage
260
290
 
261
- Pass an Endpoint and a DataProviderKey for the request body. Import patch and ApiResult from @supersoniks/concorde/decorators.
291
+ const bodyKey = new DataProviderKey &gt;(&quot;users.patch&quot;);
292
+ const patchUser = patch(new Endpoint (&quot;users/42&quot;), bodyKey);
262
293
 
263
- Configuration
294
+ @patchUser
295
+ @state()
296
+ payload: ApiResult | null = null;
264
297
 
265
- Same as @post / @get: scoped HTML.getApiConfiguration(host) or DataProviderKey as third argument.
298
+ To run the operation again from the component:
266
299
 
267
- Options (PatchOptions)
300
+ savePatch() {
301
+ patchUser.send(this);
302
+ }
268
303
 
269
- Same shape as PostOptions on @post (ApiSendOptions): refetchEveryMs, skipIfBodyMissing, autoPostOnBodyMutation, triggerKey, skipEmptyPlaceholder. See Dynamic path placeholders for ${sessionId} and empty-string behaviour.
304
+ The PATCH is also sent automatically when the body mutates, unless
305
+ autoPostOnBodyMutation: false is set. The available options are described in
306
+ @post:
270
307
 
271
- Import
308
+ - autoPostOnBodyMutation
309
+ - skipIfBodyMissing
310
+ - refetchEveryMs
311
+ - skipEmptyPlaceholder
272
312
 
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;;
313
+ Pass explicit API configuration as the third argument:
276
314
 
277
- Example
315
+ @patch(endpoint, bodyKey, apiConfigurationKey)
278
316
 
279
- const patchBodyKey = new DataProviderKey&amp;lt;Partial&amp;lt;Resource&amp;gt;&amp;gt;(&quot;resourcePatch&quot;);
317
+ Import
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
+ import { patch, type ApiResult } from &quot;@supersoniks/concorde/decorators&quot;;
320
+ import { DataProviderKey } from &quot;@supersoniks/concorde/dataProviderKey&quot;;
321
+ import { Endpoint } from &quot;@supersoniks/concorde/utils/endpoint&quot;;
288
322
 
289
323
  See also
290
324
 
291
- - @post — POST (live demos)
292
- - @put — full rep</pre>
325
+ - @post — options and triggers
326
+ - @put — full replacement
327
+ - Dynamic path placeholders</pre>
293
328
  </section>
294
329
  <section id="docs-_decorators-post" data-doc-id="docs/_decorators/post">
295
330
  <h2><a href="../docs/_decorators/post.html">@post</a></h2>
296
331
  <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>
332
+ <p>@post sends the contents of a publisher and stores the response in an</p>
298
333
  <pre class="doc-excerpt">@post
299
334
 
300
- Sends data through API.postDetailed. The decorated property is ApiResult | null: request, response, and typed result.
335
+ @post sends the contents of a publisher and stores the response in an
336
+ ApiResult | null property.
337
+
338
+ Minimal usage
339
+
340
+ Pass an Endpoint and a DataProviderKey for the request body.
301
341
 
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.
342
+ const userBodyKey = new DataProviderKey (&quot;users.form&quot;);
343
+ const createUser = post(new Endpoint (&quot;users&quot;), userBodyKey);
303
344
 
304
- Configuration
345
+ @createUser
346
+ @state()
347
+ payload: ApiResult | null = null;
348
+
349
+ The current body is read from userBodyKey. By default, the POST is sent when
350
+ the component connects and after each body mutation. Mutations in the same
351
+ frame are coalesced into one request.
305
352
 
306
- Same as @get: scoped HTML.getApiConfiguration(host) by default, or DataProviderKey as third argument. See API configuration for mock demos.
353
+ API configuration is read from the HTML scope, as with
354
+ @get.
307
355
 
308
- Optional PostOptions (third or fourth argument)
356
+ Sending the POST again
309
357
 
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. |
358
+ From the component
317
359
 
318
- When the POST runs again
360
+ Keep the decorator to access send(component). The body is read again when the
361
+ operation runs.
319
362
 
320
- - Body publisher onInternalMutation when autoPostOnBodyMutation is true (defa</pre>
363
+ saveAgain() {
364
+ createUser.send(this);
365
+ }
366
+
367
+ send() is useful for “Save” or “Retry” buttons. It can repeat an operation
368
+ with side effects.
369
+
370
+ Options (PostOptions)
371
+
372
+ Options are the third argument, or the fourth argument when a configuration key
373
+ is provided.
374
+
375
+ - autoPostOnBodyMutation: send after a body mutation (default: true). Set
376
+ it to false to use send().
377
+ - skipIfBodyMissing: skip when the body is null or undefined (default:
378
+ true).
379
+ - refetchE</pre>
321
380
  </section>
322
381
  <section id="docs-_decorators-publish" data-doc-id="docs/_decorators/publish">
323
382
  <h2><a href="../docs/_decorators/publish.html">@publish</a></h2>
@@ -365,40 +424,53 @@ Dynamic paths use the same placeholder rules as @bind / @subscribe. Resolution a
365
424
  <section id="docs-_decorators-put" data-doc-id="docs/_decorators/put">
366
425
  <h2><a href="../docs/_decorators/put.html">@put</a></h2>
367
426
  <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>
427
+ <p>@put replaces a resource with the body from a publisher. It uses exactly the</p>
369
428
  <pre class="doc-excerpt">@put
370
429
 
371
- Sends data through API.putDetailed. Same model as @post: decorated property is ApiResult | null (request, response, result).
430
+ @put replaces a resource with the body from a publisher. It uses exactly the
431
+ same model as @post:
432
+ Endpoint , DataProviderKey , ApiResult , options, and the
433
+ send(component) handle.
372
434
 
373
- Pass an Endpoint and a DataProviderKey for the request body. Import put and ApiResult from @supersoniks/concorde/decorators.
435
+ Minimal usage
374
436
 
375
- Configuration
437
+ const bodyKey = new DataProviderKey (&quot;users.form&quot;);
438
+ const updateUser = put(new Endpoint (&quot;users/42&quot;), bodyKey);
376
439
 
377
- Same as @post / @get: scoped HTML.getApiConfiguration(host) or DataProviderKey as third argument.
440
+ @updateUser
441
+ @state()
442
+ payload: ApiResult | null = null;
378
443
 
379
- Options (PutOptions)
444
+ To run the operation again from the component:
380
445
 
381
- Same shape as PostOptions on @post (ApiSendOptions): refetchEveryMs, skipIfBodyMissing, autoPostOnBodyMutation, triggerKey, skipEmptyPlaceholder. See Dynamic path placeholders for ${sessionId} and empty-string behaviour.
446
+ update() {
447
+ updateUser.send(this);
448
+ }
382
449
 
383
- Import
450
+ The PUT is also sent automatically when the body mutates, unless
451
+ autoPostOnBodyMutation: false is set. See
452
+ @post for the option details:
384
453
 
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;;
454
+ - autoPostOnBodyMutation
455
+ - skipIfBodyMissing
456
+ - refetchEveryMs
457
+ - skipEmptyPlaceholder
388
458
 
389
- Example
459
+ Pass explicit API configuration as the third argument:
390
460
 
391
- const bodyKey = new DataProviderKey&amp;lt;UpdatePayload&amp;gt;(&quot;resourceBody&quot;);
461
+ @put(endpoint, bodyKey, apiConfigurationKey)
392
462
 
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;
463
+ Import
396
464
 
397
- Changing resourceId on the host re-runs the PUT when the path becomes ready — see Dynamic path placeholders.
465
+ import { put, type ApiResult } from &quot;@supersoniks/concorde/decorators&quot;;
466
+ import { DataProviderKey } from &quot;@supersoniks/concorde/dataProviderKey&quot;;
467
+ import { Endpoint } from &quot;@supersoniks/concorde/utils/endpoint&quot;;
398
468
 
399
469
  See also
400
470
 
401
- - @post —</pre>
471
+ - @post — options and triggers
472
+ - @patch — partial update
473
+ - Dynamic path placeholders</pre>
402
474
  </section>
403
475
  <section id="docs-_decorators-subscribe" data-doc-id="docs/_decorators/subscribe">
404
476
  <h2><a href="../docs/_decorators/subscribe.html">@subscribe</a></h2>