@supersoniks/concorde 4.9.7 → 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 (72) hide show
  1. package/build-infos.json +1 -1
  2. package/concorde-core.bundle.js +265 -265
  3. package/concorde-core.es.js +4600 -4385
  4. package/dist/concorde-core.bundle.js +265 -265
  5. package/dist/concorde-core.es.js +4600 -4385
  6. package/dist/js/core/components/functional/queue/queue.js +25 -153
  7. package/dist/js/core/components/functional/queue/queue.js.map +1 -1
  8. package/dist/js/core/components/ui/_css/scroll.js +2 -0
  9. package/dist/js/core/components/ui/_css/scroll.js.map +1 -1
  10. package/dist/js/core/decorators/api.js +92 -2
  11. package/dist/js/core/decorators/api.js.map +1 -1
  12. package/dist/js/core/utils/SafariScrollGuard.js +384 -0
  13. package/dist/js/core/utils/SafariScrollGuard.js.map +1 -0
  14. package/dist/js/decorators.js +4 -0
  15. package/dist/js/decorators.js.map +1 -1
  16. package/dist/js/utils.js +3 -0
  17. package/dist/js/utils.js.map +1 -1
  18. package/dist/types/core/components/functional/queue/queue.d.ts +8 -24
  19. package/dist/types/core/components/functional/queue/queue.d.ts.map +1 -1
  20. package/dist/types/core/components/ui/_css/scroll.d.ts.map +1 -1
  21. package/dist/types/core/decorators/api.d.ts +82 -60
  22. package/dist/types/core/decorators/api.d.ts.map +1 -1
  23. package/dist/types/core/utils/SafariScrollGuard.d.ts +36 -0
  24. package/dist/types/core/utils/SafariScrollGuard.d.ts.map +1 -0
  25. package/dist/types/decorators.d.ts +3 -1
  26. package/dist/types/decorators.d.ts.map +1 -1
  27. package/dist/types/utils.d.ts +1 -0
  28. package/dist/types/utils.d.ts.map +1 -1
  29. package/docs/assets/index-BL6WVF7g.css +1 -0
  30. package/docs/assets/{index-hElUgV9_.js → index-DVn8AeyA.js} +572 -555
  31. package/docs/crawl/docs/_decorators/get.html +64 -81
  32. package/docs/crawl/docs/_decorators/patch.html +35 -23
  33. package/docs/crawl/docs/_decorators/post.html +72 -72
  34. package/docs/crawl/docs/_decorators/put.html +36 -21
  35. package/docs/crawl/docs/_getting-started/ai-agents.html +45 -6
  36. package/docs/crawl/hubs/decorators.html +141 -69
  37. package/docs/crawl/hubs/remote-data.html +141 -69
  38. package/docs/index.html +2 -2
  39. package/docs/llms-full.txt +203 -149
  40. package/docs/llms.txt +4 -4
  41. package/docs/src/core/components/functional/queue/queue.md +0 -0
  42. package/docs/src/core/components/ui/button/button.md +0 -0
  43. package/docs/src/docs/_decorators/get.md +55 -81
  44. package/docs/src/docs/_decorators/patch.md +36 -25
  45. package/docs/src/docs/_decorators/post.md +71 -62
  46. package/docs/src/docs/_decorators/put.md +37 -24
  47. package/docs/src/docs/_getting-started/ai-agents.md +24 -4
  48. package/docs/src/docs/search/docs-search.json +151 -1
  49. package/docs/src/tsconfig.json +3 -0
  50. package/package.json +6 -2
  51. package/src/core/components/functional/queue/queue.ts +33 -164
  52. package/src/core/components/ui/_css/scroll.ts +3 -0
  53. package/src/core/decorators/api.post.spec.ts +79 -1
  54. package/src/core/decorators/api.spec.ts +100 -1
  55. package/src/core/decorators/api.ts +252 -138
  56. package/src/core/utils/SafariScrollGuard.ts +429 -0
  57. package/src/decorators.ts +7 -0
  58. package/src/docs/_decorators/get.md +81 -80
  59. package/src/docs/_decorators/patch.md +36 -25
  60. package/src/docs/_decorators/post.md +99 -62
  61. package/src/docs/_decorators/put.md +37 -24
  62. package/src/docs/components/docs-demo-sources.ts +1 -6
  63. package/src/docs/example/decorators-demo-geo.ts +0 -21
  64. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +41 -132
  65. package/src/docs/search/docs-search.json +156 -241
  66. package/src/docs/tailwind/css/tailwind.css +0 -0
  67. package/src/tsconfig.json +3 -0
  68. package/src/tsconfig.tsbuildinfo +1 -1
  69. package/src/utils.ts +13 -0
  70. package/vite.config.mts +4 -0
  71. package/vitest.setup.ts +22 -0
  72. package/docs/assets/index-Bnp7gVaA.css +0 -1
@@ -3134,97 +3134,91 @@ Shared data: Sharing data.
3134
3134
 
3135
3135
  - URL: https://concorde.supersoniks.org/crawl/docs/_decorators/get.html
3136
3136
  - Doc ID: docs/_decorators/get
3137
- - Keywords: Concorde, supersoniks, docs/_decorators/get, get, @get, decorator, API.getDetailed, ApiResult | null, request, response, null, dataProvider(...), result, Endpoint, ApiResult
3137
+ - Keywords: Concorde, supersoniks, docs/_decorators/get, get, @get, decorator, ApiResult | null, payload.result, payload.response, payload.request,
3138
3138
 
3139
- @get
3139
+ The first argument is always an
3140
+ [, serviceURL, refetch(component),
3140
3141
 
3141
- Loads data through API.getDetailed. The decorated property is ApiResult | null: request, response (or null for dataProvider(...) resolution without HTTP), and typed result.
3142
+ ## Options (, skipEmptyPlaceholder
3142
3143
 
3143
- Pass an Endpoint as the first argument. Import get and ApiResult from @supersoniks/concorde/decorators, and Endpoint from @supersoniks/concorde/utils/endpoint.
3144
+ @get
3144
3145
 
3145
- Configuration
3146
+ @get loads data and stores the result in an ApiResult | null property.
3146
3147
 
3147
- - Default: HTML.getApiConfiguration(host) (ancestor serviceURL, etc.).
3148
- - Second argument: DataProviderKey — config is read from the publisher at the resolved path; internal mutations trigger another GET. See API configuration for mock demos.
3148
+ - payload.result: typed data;
3149
+ - payload.response: the HTTP response;
3150
+ - payload.request: the request that was sent.
3149
3151
 
3150
- Dynamic path
3152
+ Minimal usage
3151
3153
 
3152
- ${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 "" (empty string only). Details: Dynamic path placeholders.
3154
+ const usersEndpoint = new Endpoint ("users");
3153
3155
 
3154
- Options (GetOptions)
3156
+ @get(usersEndpoint)
3157
+ @state()
3158
+ payload: ApiResult | null = null;
3155
3159
 
3156
- Pass as the second argument (scoped config) or third (with a configuration key). Same shape as send decorators where applicable:
3160
+ The first argument is always an
3161
+ Endpoint . API configuration is read
3162
+ from the HTML scope (serviceURL, token, etc.), so the component is usually
3163
+ placed below an element that provides this configuration.
3157
3164
 
3158
- | Option | Description |
3159
- |--------|-------------|
3160
- | skipEmptyPlaceholder | Treat "" as not ready (see Dynamic path). |
3161
- | refetchEveryMs | Automatic polling interval (ms). 0 or omitted = no polling. |
3162
- | triggerKey | DataProviderKey — PublisherManager.get(...).invalidate() on that publisher re-runs the GET. |
3165
+ Refetching a GET
3163
3166
 
3164
- Manual refetch (triggerKey)
3167
+ From the component
3165
3168
 
3166
- Same pattern as @post: a publisher acts as a signal, independent of the response payload.
3169
+ Keep the decorator in a constant to access refetch(component). Refetch only
3170
+ targets the instance passed as the argument, even before it has received a
3171
+ result.
3167
3172
 
3168
- import { get, type ApiResult } from "@supersoniks/concorde/decorators";
3169
- import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
3170
- import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
3171
- import { dp } from "@supersoniks/concorde/core/utils/PublisherProxy";
3173
+ const usersGet = get(new Endpoint ("users"));
3172
3174
 
3173
- const geoCommunesEndpoint = new Endpoint (
3174
- "communes?limit=5&fields=nom,code",
3175
- );
3176
- const geoCommunesRefreshKey = new DataProviderKey (
3177
- "docsDemoGeoCommunesRefresh",
3178
- );
3179
-
3180
- @get(geoCommunesEndpoint, apiConfigurationKey, {
3181
- triggerKey: geoCommunesRefreshKey,
3182
- })
3175
+ @usersGet
3183
3176
  @state()
3184
3177
  payload: ApiResult | null = null;
3185
3178
 
3186
- // Same component or anywhere else:
3187
- dp(geoCommunesRefreshKey).invalidate();
3188
-
3189
- Prefer triggerKey over mutating the API configuration publisher when you only want to reload the same URL — no need to touch serviceURL, tokens, etc.
3179
+ refresh() {
3180
+ usersGet.refetch(this);
3181
+ }
3190
3182
 
3191
- The docs mock adds an X-Fetched-At response header on /docs-mock-api/geo/communes so live demos can show when the last fetch happened (response.headers.get("X-Fetched-At")).
3183
+ Options (GetOptions)
3192
3184
 
3193
- When the GET runs again
3185
+ Options are the second argument, or the third argument when an API
3186
+ configuration key is provided.
3194
3187
 
3195
- - A referenced Lit property changes (endpoint path and/or config key contains ${...}).
3196
- - set on the active configuration publisher (onInternalMutation).
3197
- - triggerKey publisher invalidate().
3198
- - refetchEveryMs polling (after each successful fetch).
3188
+ - skipEmptyPlaceholder: blocks the GET when ${prop} is "".
3189
+ - refetchEveryMs: automatically runs the GET again after this interval
3190
+ (milliseconds). Omit the option, or use 0, to disable polling.
3199
3191
 
3200
- Import
3192
+ With a configuration key, use:
3201
3193
 
3202
- import { get, type ApiResult } from "@supersoniks/concorde/decorators";
3203
- import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
3204
- import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
3194
+ @get(usersEndpoint, apiConfigurationKey)
3205
3195
 
3206
- Minimal example
3196
+ When the GET runs again
3207
3197
 
3208
- Same demo service as sonic-queue (/docs-mock-api/geo/). Publisher setup lives in decorators-demo-geo.ts and decorators-demo-subscribe-publish-get-demos.ts.
3198
+ - when the component connects and configuration is available;
3199
+ - when a property used in ${...} changes;
3200
+ - when a configuration publisher changes;
3201
+ - after each response when refetchEveryMs is set.
3209
3202
 
3210
- @get(new Endpoint ("users/${userId}"))
3211
- @state()
3212
- payload: ApiResult | null = null;
3203
+ See Dynamic path placeholders for
3204
+ dynamic path details.
3213
3205
 
3214
- Live demos
3215
-
3216
- @get with triggerKey — refresh button + X-Fetched-At timestamp in the UI:
3206
+ Import
3217
3207
 
3218
- Dynamic config and endpoint path. Manual refetch is triggered from a separate component (same triggerKey publisher):
3208
+ import { get, type ApiResult } from "@supersoniks/concorde/decorators";
3209
+ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
3210
+ import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
3219
3211
 
3220
- Scoped @get with @publish / @subscribe on the payload (see @publish and @subscribe) — wrap under an ancestor with serviceURL="/docs-mock-api/geo/":
3212
+ Demos
3221
3213
 
3222
- Stale responses are ignored if the path or generation changed before the request finished.
3214
+ See @post,
3215
+ @put, and
3216
+ @patch for write operations.
3223
3217
 
3224
- See also
3218
+ Advanced
3225
3219
 
3226
- - Dynamic path placeholders
3227
- - @post · @put · @patch — send decorators (same path rules)
3220
+ External invalidation is currently available through triggerKey; it is kept
3221
+ out of the main usage examples.
3228
3222
 
3229
3223
  ---
3230
3224
 
@@ -3731,44 +3725,53 @@ Notes
3731
3725
 
3732
3726
  - URL: https://concorde.supersoniks.org/crawl/docs/_decorators/patch.html
3733
3727
  - Doc ID: docs/_decorators/patch
3734
- - Keywords: Concorde, supersoniks, docs/_decorators/patch, patch, @patch, decorator, API.patchDetailed, ApiResult | null, request, response, result, Endpoint, DataProviderKey, ApiResult, @supersoniks/concorde/decorators
3728
+ - Keywords: Concorde, supersoniks, docs/_decorators/patch, patch, @patch, decorator, Endpoint, DataProviderKey, ApiResult, send(component), autoPostOnBodyMutation: false, autoPostOnBodyMutation, skipIfBodyMissing, refetchEveryMs, skipEmptyPlaceholder
3735
3729
 
3736
3730
  @patch
3737
3731
 
3738
- Sends data through API.patchDetailed. Same model as @post: decorated property is ApiResult | null (request, response, result).
3732
+ @patch applies a partial update with the body from a publisher. It uses the
3733
+ same model as @post:
3734
+ Endpoint , DataProviderKey , ApiResult , options, and the
3735
+ send(component) handle.
3739
3736
 
3740
- Pass an Endpoint and a DataProviderKey for the request body. Import patch and ApiResult from @supersoniks/concorde/decorators.
3737
+ Minimal usage
3741
3738
 
3742
- Configuration
3739
+ const bodyKey = new DataProviderKey >("users.patch");
3740
+ const patchUser = patch(new Endpoint ("users/42"), bodyKey);
3743
3741
 
3744
- Same as @post / @get: scoped HTML.getApiConfiguration(host) or DataProviderKey as third argument.
3742
+ @patchUser
3743
+ @state()
3744
+ payload: ApiResult | null = null;
3745
3745
 
3746
- Options (PatchOptions)
3746
+ To run the operation again from the component:
3747
3747
 
3748
- Same shape as PostOptions on @post (ApiSendOptions): refetchEveryMs, skipIfBodyMissing, autoPostOnBodyMutation, triggerKey, skipEmptyPlaceholder. See Dynamic path placeholders for ${sessionId} and empty-string behaviour.
3748
+ savePatch() {
3749
+ patchUser.send(this);
3750
+ }
3749
3751
 
3750
- Import
3752
+ The PATCH is also sent automatically when the body mutates, unless
3753
+ autoPostOnBodyMutation: false is set. The available options are described in
3754
+ @post:
3751
3755
 
3752
- import { patch, type ApiResult } from "@supersoniks/concorde/decorators";
3753
- import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
3754
- import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
3756
+ - autoPostOnBodyMutation
3757
+ - skipIfBodyMissing
3758
+ - refetchEveryMs
3759
+ - skipEmptyPlaceholder
3755
3760
 
3756
- Example
3761
+ Pass explicit API configuration as the third argument:
3757
3762
 
3758
- const patchBodyKey = new DataProviderKey<Partial<Resource>>("resourcePatch");
3763
+ @patch(endpoint, bodyKey, apiConfigurationKey)
3759
3764
 
3760
- @patch(
3761
- new Endpoint<Resource, { resourceId: string }>("resources/${resourceId}"),
3762
- patchBodyKey,
3763
- { skipEmptyPlaceholder: true },
3764
- )
3765
- @state()
3766
- payload?: ApiResult<Resource> | null;
3765
+ Import
3766
+
3767
+ import { patch, type ApiResult } from "@supersoniks/concorde/decorators";
3768
+ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
3769
+ import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
3767
3770
 
3768
3771
  See also
3769
3772
 
3770
- - @post — POST (live demos)
3771
- - @put — full replacement (PUT)
3773
+ - @post — options and triggers
3774
+ - @put — full replacement
3772
3775
  - Dynamic path placeholders
3773
3776
 
3774
3777
  ---
@@ -3777,72 +3780,95 @@ See also
3777
3780
 
3778
3781
  - URL: https://concorde.supersoniks.org/crawl/docs/_decorators/post.html
3779
3782
  - Doc ID: docs/_decorators/post
3780
- - Keywords: Concorde, supersoniks, docs/_decorators/post, post, @post, decorator, API.postDetailed, ApiResult | null, request, response, result, Endpoint, DataProviderKey, ApiResult, @supersoniks/concorde/decorators
3783
+ - Keywords: Concorde, supersoniks, docs/_decorators/post, post, @post, decorator, ApiResult | null, Endpoint, DataProviderKey,
3784
+
3785
+ The current body is read from , send(component),
3786
+
3787
+ , PostOptions, autoPostOnBodyMutation, true
3781
3788
 
3782
3789
  @post
3783
3790
 
3784
- Sends data through API.postDetailed. The decorated property is ApiResult | null: request, response, and typed result.
3791
+ @post sends the contents of a publisher and stores the response in an
3792
+ ApiResult | null property.
3785
3793
 
3786
- 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.
3794
+ Minimal usage
3787
3795
 
3788
- Configuration
3796
+ Pass an Endpoint and a DataProviderKey for the request body.
3789
3797
 
3790
- Same as @get: scoped HTML.getApiConfiguration(host) by default, or DataProviderKey as third argument. See API configuration for mock demos.
3798
+ const userBodyKey = new DataProviderKey ("users.form");
3799
+ const createUser = post(new Endpoint ("users"), userBodyKey);
3791
3800
 
3792
- Optional PostOptions (third or fourth argument)
3801
+ @createUser
3802
+ @state()
3803
+ payload: ApiResult | null = null;
3793
3804
 
3794
- | Option | Description |
3795
- |--------|-------------|
3796
- | refetchEveryMs | Re-post on an interval (ms). |
3797
- | skipIfBodyMissing | Skip when body publisher is null/undefined (default: true). |
3798
- | autoPostOnBodyMutation | Re-post when the body publisher mutates (default: true). false = manual via triggerKey.invalidate(). |
3799
- | skipEmptyPlaceholder | If true, a placeholder resolved to '' blocks the request (empty string only — not 0 or false). See Dynamic paths. |
3800
- | triggerKey | DataProviderKey — invalidate() re-runs the POST with the current body. |
3805
+ The current body is read from userBodyKey. By default, the POST is sent when
3806
+ the component connects and after each body mutation. Mutations in the same
3807
+ frame are coalesced into one request.
3801
3808
 
3802
- When the POST runs again
3809
+ API configuration is read from the HTML scope, as with
3810
+ @get.
3803
3811
 
3804
- - Body publisher onInternalMutation when autoPostOnBodyMutation is true (default). Plusieurs mutations synchrones dans la même frame sont regroupées en un seul POST via requestAnimationFrame.
3805
- - Endpoint path dependency changes (${sessionId} on the host).
3806
- - Configuration publisher mutation.
3807
- - triggerKey publisher invalidate().
3808
- - refetchEveryMs timer (if set).
3812
+ Sending the POST again
3809
3813
 
3810
- Import
3814
+ From the component
3811
3815
 
3812
- import { post, publish, type ApiResult } from "@supersoniks/concorde/decorators";
3813
- import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
3814
- import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
3816
+ Keep the decorator to access send(component). The body is read again when the
3817
+ operation runs.
3815
3818
 
3816
- Minimal example
3819
+ saveAgain() {
3820
+ createUser.send(this);
3821
+ }
3817
3822
 
3818
- Mock service: POST /docs-mock-api/api/register (same route as sonic-submit demos). Publisher setup lives in decorators-demo-post.ts.
3823
+ send() is useful for “Save” or “Retry” buttons. It can repeat an operation
3824
+ with side effects.
3819
3825
 
3820
- const syncRequest = new DataProviderKey<SyncRequest>("syncRequest");
3821
- const syncTrigger = new DataProviderKey<number>("syncTrigger");
3826
+ Options (PostOptions)
3822
3827
 
3823
- @post(
3824
- new Endpoint<SyncResponse, { sessionId: string }>("sessions/${sessionId}/sync"),
3825
- syncRequest,
3826
- { triggerKey: syncTrigger },
3827
- )
3828
- @state()
3829
- payload?: ApiResult<SyncResponse> | null;
3828
+ Options are the third argument, or the fourth argument when a configuration key
3829
+ is provided.
3830
3830
 
3831
- Live demos
3831
+ - autoPostOnBodyMutation: send after a body mutation (default: true). Set
3832
+ it to false to use send().
3833
+ - skipIfBodyMissing: skip when the body is null or undefined (default:
3834
+ true).
3835
+ - refetchEveryMs: repeat the POST at this interval. Use it only when
3836
+ repeating the operation is intended.
3837
+ - skipEmptyPlaceholder: block the request when a ${...} placeholder is
3838
+ "".
3832
3839
 
3833
- Dynamic endpoint path — changing sessionId on the host re-runs the POST (POST /docs-mock-api/api/sessions/{id}/sync):
3840
+ With a configuration key:
3834
3841
 
3835
- @post + @publish on the same property (see @publish):
3842
+ @post(endpoint, userBodyKey, apiConfigurationKey)
3836
3843
 
3837
- Stale responses are ignored if the path or generation changed before the request finished.
3844
+ See Dynamic path placeholders for
3845
+ dynamic path details.
3838
3846
 
3839
- Note: plusieurs composants @post sur la même page qui partagent le même bodyKey enverront chacun une requête à chaque mutation du body — utiliser une clé par composant (voir les deux démos live ci-dessus).
3847
+ When the POST is sent
3840
3848
 
3841
- Path placeholders (${sessionId}, …): Dynamic path placeholders.
3849
+ - when the component connects and the body and configuration are available;
3850
+ - after a body mutation, unless autoPostOnBodyMutation: false;
3851
+ - when a property used in ${...} changes;
3852
+ - when a configuration publisher changes;
3853
+ - when send() is called;
3854
+ - after each response when refetchEveryMs is set.
3842
3855
 
3843
- See also
3856
+ Import
3857
+
3858
+ import { post, type ApiResult } from "@supersoniks/concorde/decorators";
3859
+ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
3860
+ import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
3861
+
3862
+ Demos
3863
+
3864
+ See @put and
3865
+ @patch: they use the same model with a
3866
+ different HTTP method.
3844
3867
 
3845
- - @put · @patch — same decorator model, PUT / PATCH via putDetailed / patchDetailed
3868
+ Advanced
3869
+
3870
+ External invalidation is currently available through triggerKey; it is kept
3871
+ out of the main usage examples.
3846
3872
 
3847
3873
  ---
3848
3874
 
@@ -3897,43 +3923,54 @@ Dynamic paths use the same placeholder rules as @bind / @subscribe. Resolution a
3897
3923
 
3898
3924
  - URL: https://concorde.supersoniks.org/crawl/docs/_decorators/put.html
3899
3925
  - Doc ID: docs/_decorators/put
3900
- - Keywords: Concorde, supersoniks, docs/_decorators/put, put, @put, decorator, API.putDetailed, ApiResult | null, request, response, result, Endpoint, DataProviderKey, ApiResult, @supersoniks/concorde/decorators
3926
+ - Keywords: Concorde, supersoniks, docs/_decorators/put, put, @put, decorator, Endpoint, DataProviderKey, ApiResult, send(component), autoPostOnBodyMutation: false, autoPostOnBodyMutation, skipIfBodyMissing, refetchEveryMs, skipEmptyPlaceholder
3901
3927
 
3902
3928
  @put
3903
3929
 
3904
- Sends data through API.putDetailed. Same model as @post: decorated property is ApiResult | null (request, response, result).
3930
+ @put replaces a resource with the body from a publisher. It uses exactly the
3931
+ same model as @post:
3932
+ Endpoint , DataProviderKey , ApiResult , options, and the
3933
+ send(component) handle.
3905
3934
 
3906
- Pass an Endpoint and a DataProviderKey for the request body. Import put and ApiResult from @supersoniks/concorde/decorators.
3935
+ Minimal usage
3907
3936
 
3908
- Configuration
3937
+ const bodyKey = new DataProviderKey ("users.form");
3938
+ const updateUser = put(new Endpoint ("users/42"), bodyKey);
3909
3939
 
3910
- Same as @post / @get: scoped HTML.getApiConfiguration(host) or DataProviderKey as third argument.
3940
+ @updateUser
3941
+ @state()
3942
+ payload: ApiResult | null = null;
3911
3943
 
3912
- Options (PutOptions)
3944
+ To run the operation again from the component:
3913
3945
 
3914
- Same shape as PostOptions on @post (ApiSendOptions): refetchEveryMs, skipIfBodyMissing, autoPostOnBodyMutation, triggerKey, skipEmptyPlaceholder. See Dynamic path placeholders for ${sessionId} and empty-string behaviour.
3946
+ update() {
3947
+ updateUser.send(this);
3948
+ }
3915
3949
 
3916
- Import
3950
+ The PUT is also sent automatically when the body mutates, unless
3951
+ autoPostOnBodyMutation: false is set. See
3952
+ @post for the option details:
3917
3953
 
3918
- import { put, type ApiResult } from "@supersoniks/concorde/decorators";
3919
- import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
3920
- import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
3954
+ - autoPostOnBodyMutation
3955
+ - skipIfBodyMissing
3956
+ - refetchEveryMs
3957
+ - skipEmptyPlaceholder
3921
3958
 
3922
- Example
3959
+ Pass explicit API configuration as the third argument:
3923
3960
 
3924
- const bodyKey = new DataProviderKey<UpdatePayload>("resourceBody");
3961
+ @put(endpoint, bodyKey, apiConfigurationKey)
3925
3962
 
3926
- @put(new Endpoint<Resource, { resourceId: string }>("resources/${resourceId}"), bodyKey)
3927
- @state()
3928
- payload?: ApiResult<Resource> | null;
3963
+ Import
3929
3964
 
3930
- Changing resourceId on the host re-runs the PUT when the path becomes ready — see Dynamic path placeholders.
3965
+ import { put, type ApiResult } from "@supersoniks/concorde/decorators";
3966
+ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
3967
+ import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
3931
3968
 
3932
3969
  See also
3933
3970
 
3934
- - @post — POST (live demos, polling, @publish)
3935
- - @patch — partial update (PATCH)
3936
- - Endpoint · API configuration
3971
+ - @post — options and triggers
3972
+ - @patch — partial update
3973
+ - Dynamic path placeholders
3937
3974
 
3938
3975
  ---
3939
3976
 
@@ -4233,7 +4270,7 @@ See DataProviderKey, @subscribe, and the concorde-get-set-dp migration skill.
4233
4270
  - URL: https://concorde.supersoniks.org/crawl/docs/_getting-started/ai-agents.html
4234
4271
  - Doc ID: docs/_getting-started/ai-agents
4235
4272
  - Keywords: Concorde, supersoniks, docs/_getting-started/ai-agents, ai-agents, AI agents (skills & AGENTS.md), guide, AGENTS.md, yarn ai:sync, ai-init, yarn add @supersoniks/concorde, |
4236
- | Concorde repo (contributors) | , --merge-agents, --overlay , --cursor-only
4273
+ | Concorde repo (contributors) | , --skip-agents, --merge-agents, --force-agents
4237
4274
 
4238
4275
  AI agents (skills & AGENTS.md)
4239
4276
 
@@ -4259,16 +4296,33 @@ Useful flags
4259
4296
 
4260
4297
  | Flag | Effect |
4261
4298
  |------|--------|
4262
- | --merge-agents | Append to an existing AGENTS.md instead of replacing it |
4263
- | --overlay | Copy extra rules/skills from another layer (e.g. starter kit) |
4299
+ | --skip-agents | Never write AGENTS.md (skills / rules only) |
4300
+ | --merge-agents | Opt-in: keep the project preamble and append / refresh the Concorde block |
4301
+ | --force-agents | Opt-in: replace the whole AGENTS.md (destructive) |
4302
+ | --overlay | Extra rules/skills + optional AGENTS.concorde.md for project-only Concorde agent notes |
4264
4303
  | --cursor-only | Install only .cursor/skills and .cursor/rules |
4265
4304
  | --jetbrains-only | Install only .aiassistant/rules/ |
4266
4305
 
4306
+ AGENTS.md policy (non-invasive)
4307
+
4308
+ | Situation | Default |
4309
+ |-----------|---------|
4310
+ | No AGENTS.md | Create the Concorde guide |
4311
+ | File with | Refresh the managed zone only |
4312
+ | File without marker (project notes) | Left untouched — skills / rules are enough |
4313
+ | --merge-agents / --force-agents / --skip-agents | See flags above |
4314
+
4315
+ [optional project preamble — short, project-only]
4316
+
4317
+ [--- + overlay AGENTS.concorde.md]
4318
+
4319
+ Everything after is replaced on each ai-init run (idempotent). Do not paste a full copy of the Concorde guide above the marker — put project-specific notes in AGENTS.concorde.md (overlay). If the preamble duplicates package AGENTS.md, ai-init slims or drops it and prints a warning. Legacy filenames AGENTS.overlay.md / AGENTS.starter.md are still accepted with a deprecation warning.
4320
+
4267
4321
  What gets installed
4268
4322
 
4269
4323
  | Path | Role |
4270
4324
  |------|------|
4271
- | AGENTS.md | Project-level guide for agents (Concorde conventions) |
4325
+ | AGENTS.md | Created only if missing; existing project-owned files are left alone unless --merge-agents / --force-agents |
4272
4326
  | .cursor/skills/concorde/ | Core Lit + DataProvider patterns |
4273
4327
  | .cursor/skills/concorde-imports/ | Short @supersoniks/concorde/… import paths |
4274
4328
  | .cursor/skills/concorde-scope/ | serviceURL, formDataProvider, API configuration |
@@ -4282,7 +4336,7 @@ Workflow
4282
4336
 
4283
4337
  1. Starter project: Installation — yarn ai:sync is wired in the kit.
4284
4338
  2. Existing / manual Vite project: Manual installation, then ai-init after yarn add @supersoniks/concorde.
4285
- 3. Commit AGENTS.md, .cursor/, and .aiassistant/ if your team shares agent settings.
4339
+ 3. Commit .cursor/ and .aiassistant/ (and AGENTS.md only if you opted in / it was created) if your team shares agent settings.
4286
4340
  4. Re-run the same command when you bump @supersoniks/concorde to refresh skills from nodemodules/@supersoniks/concorde/ai/.
4287
4341
  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).
4288
4342
 
package/docs/llms.txt CHANGED
@@ -71,13 +71,13 @@ Custom
71
71
  - [@ancestorAttribute](https://concorde.supersoniks.org/crawl/docs/_decorators/ancestor-attribute.html) (docs/_decorators/ancestor-attribute): The @ancestorAttribute decorator automatically injects the value of an ancestor's attribute into a class property at the time of connectedCallback.
72
72
  - [@autoSubscribe](https://concorde.supersoniks.org/crawl/docs/_decorators/auto-subscribe.html) (docs/_decorators/auto-subscribe): > Legacy: prefer @subscribe + DataProviderKey. Examples below may still show PublisherManager for existing codebases.
73
73
  - [@bind](https://concorde.supersoniks.org/crawl/docs/_decorators/bind.html) (docs/_decorators/bind): Binds a class property to a path in a publisher. The property updates when publisher data changes.
74
- - [@get](https://concorde.supersoniks.org/crawl/docs/_decorators/get.html) (docs/_decorators/get): Loads data through API.getDetailed. The decorated property is ApiResult<T> | null: request, response (or null for dataProvider(...) resolution without HTTP), and typed result.
74
+ - [@get](https://concorde.supersoniks.org/crawl/docs/_decorators/get.html) (docs/_decorators/get): @get loads data and stores the result in an ApiResult<T> | null property.
75
75
  - [@handle](https://concorde.supersoniks.org/crawl/docs/_decorators/handle.html) (docs/_decorators/handle): Typed callback on one or more DataProviderKey<T> paths: invokes the decorated method when a publisher assigns a value (calculations, side effects, updating other @state properties, etc.).
76
76
  - [@onAssign](https://concorde.supersoniks.org/crawl/docs/_decorators/on-assign.html) (docs/_decorators/on-assign): > New apps: use @handle with DataProviderKey (Data flow). @onAssign uses untyped string paths; it remains documented for existing codebases — see Migrating to @handle below.
77
- - [@patch](https://concorde.supersoniks.org/crawl/docs/_decorators/patch.html) (docs/_decorators/patch): Sends data through API.patchDetailed. Same model as @post: decorated property is ApiResult<T> | null (request, response, result).
78
- - [@post](https://concorde.supersoniks.org/crawl/docs/_decorators/post.html) (docs/_decorators/post): Sends data through API.postDetailed. The decorated property is ApiResult<T> | null: request, response, and typed result.
77
+ - [@patch](https://concorde.supersoniks.org/crawl/docs/_decorators/patch.html) (docs/_decorators/patch): @patch applies a partial update with the body from a publisher. It uses the
78
+ - [@post](https://concorde.supersoniks.org/crawl/docs/_decorators/post.html) (docs/_decorators/post): @post sends the contents of a publisher and stores the response in an
79
79
  - [@publish](https://concorde.supersoniks.org/crawl/docs/_decorators/publish.html) (docs/_decorators/publish): Write-only binding: assigning to the property publishes to the DataProviderKey path. No read subscription (inverse of @subscribe).
80
- - [@put](https://concorde.supersoniks.org/crawl/docs/_decorators/put.html) (docs/_decorators/put): Sends data through API.putDetailed. Same model as @post: decorated property is ApiResult<T> | null (request, response, result).
80
+ - [@put](https://concorde.supersoniks.org/crawl/docs/_decorators/put.html) (docs/_decorators/put): @put replaces a resource with the body from a publisher. It uses exactly the
81
81
  - [@subscribe](https://concorde.supersoniks.org/crawl/docs/_decorators/subscribe.html) (docs/_decorators/subscribe): Keeps a Lit property in sync with a read-only slice of the DataProvider store. You pass a DataProviderKey; when that path changes, the property updates and the component re-renders.
82
82
  - [@awaitConnectedAncestors and @dispatchConnectedEvent](https://concorde.supersoniks.org/crawl/docs/_decorators/wait-for-ancestors.html) (docs/_decorators/wait-for-ancestors): The @awaitConnectedAncestors and @dispatchConnectedEvent decorators delay a web component's initialization until its matching ancestors have executed their connectedCallback. This is when contextual e
83
83
  - [sub()](https://concorde.supersoniks.org/crawl/docs/_directives/sub.html) (docs/_directives/sub): Read-only Lit directive: displays the current DataProvider value and updates whenever it is assigned.
File without changes