@supersoniks/concorde 4.9.92 → 4.9.93
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.
- package/ai/cursor/rules/concorde.mdc +7 -0
- package/ai/jetbrains/rules/concorde.md +6 -0
- package/ai/skills/concorde/SKILL.md +48 -0
- package/build-infos.json +1 -1
- package/concorde-core.bundle.js +257 -257
- package/concorde-core.es.js +3148 -3077
- package/dist/concorde-core.bundle.js +257 -257
- package/dist/concorde-core.es.js +3148 -3077
- package/dist/js/core/decorators/api.js +108 -16
- package/dist/js/core/decorators/api.js.map +1 -1
- package/dist/js/core/utils/api.js +29 -8
- package/dist/js/core/utils/api.js.map +1 -1
- package/dist/types/core/decorators/api.d.ts +21 -12
- package/dist/types/core/decorators/api.d.ts.map +1 -1
- package/dist/types/core/utils/api.d.ts +1 -1
- package/dist/types/core/utils/api.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/decorators/api.post.spec.ts +99 -4
- package/src/core/decorators/api.spec.ts +90 -0
- package/src/core/decorators/api.ts +212 -92
- package/src/core/utils/api.spec.ts +73 -0
- package/src/core/utils/api.ts +44 -11
- package/src/docs/_decorators/get.md +31 -0
- package/src/docs/_decorators/patch.md +9 -0
- package/src/docs/_decorators/post.md +11 -0
- package/src/docs/_decorators/put.md +9 -0
- package/src/docs/components/docs-demo-sources.ts +14 -0
- package/src/docs/example/decorators-demo-post.ts +70 -0
- package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +59 -0
- package/src/docs/search/docs-search.json +120 -5
- package/src/tsconfig.tsbuildinfo +1 -1
package/src/core/utils/api.ts
CHANGED
|
@@ -49,6 +49,11 @@ export type ApiResult<T> = {
|
|
|
49
49
|
/** @deprecated Utiliser `ApiResult`. */
|
|
50
50
|
export type ApiGetResult<T> = ApiResult<T>;
|
|
51
51
|
|
|
52
|
+
type SharedGetResult = {
|
|
53
|
+
processed: ResultTypeInterface;
|
|
54
|
+
response?: Response;
|
|
55
|
+
};
|
|
56
|
+
|
|
52
57
|
/** Extrait le corps typé depuis le résultat traité par `handleResult`. */
|
|
53
58
|
function extractTypedApiResult<T>(
|
|
54
59
|
processed: ResultTypeInterface | null | undefined,
|
|
@@ -67,7 +72,10 @@ class API {
|
|
|
67
72
|
/**
|
|
68
73
|
* Ce tableau static permet de ne pas appeler plusieurs fois le même service lors d'appel concurrents en GET.
|
|
69
74
|
*/
|
|
70
|
-
private static loadingGetPromises: Map<
|
|
75
|
+
private static loadingGetPromises: Map<
|
|
76
|
+
string,
|
|
77
|
+
Promise<SharedGetResult | null>
|
|
78
|
+
> = new Map();
|
|
71
79
|
/**
|
|
72
80
|
* L'url de base du service sans endpoint
|
|
73
81
|
*/
|
|
@@ -202,10 +210,14 @@ class API {
|
|
|
202
210
|
if (httpCode === 498 && !API.failledTokenUpdates.has(this.serviceURL)) {
|
|
203
211
|
this.handleInvalidToken(this.token);
|
|
204
212
|
if (lastCall.apiMethod === "get") {
|
|
205
|
-
|
|
213
|
+
const retryResult = await this.get(
|
|
206
214
|
lastCall.path,
|
|
207
215
|
lastCall.additionalHeaders,
|
|
208
216
|
);
|
|
217
|
+
if (retryResult == null) {
|
|
218
|
+
throw new Error("GET retry failed after token refresh");
|
|
219
|
+
}
|
|
220
|
+
result = retryResult;
|
|
209
221
|
} else {
|
|
210
222
|
result = await this[lastCall.apiMethod](
|
|
211
223
|
lastCall.path,
|
|
@@ -384,13 +396,16 @@ class API {
|
|
|
384
396
|
});
|
|
385
397
|
}
|
|
386
398
|
|
|
387
|
-
async get<T>(
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
}
|
|
399
|
+
async get<T>(
|
|
400
|
+
path: string,
|
|
401
|
+
additionalHeaders?: HeadersInit,
|
|
402
|
+
): Promise<(T & ResultTypeInterface) | null> {
|
|
392
403
|
const regExp = /dataProvider\((.*?)\)(.*?)$/;
|
|
393
404
|
if (regExp.test(path)) {
|
|
405
|
+
if (this.blockUntilDone) {
|
|
406
|
+
await this.firstCallDone();
|
|
407
|
+
API.firstCallDoneFlags.set(this.serviceURL, "loading");
|
|
408
|
+
}
|
|
394
409
|
const match = path.match(regExp);
|
|
395
410
|
if (!match) throw new Error("dataProvider path is not valid");
|
|
396
411
|
return await this.localGet<T>(match[1], match[2]);
|
|
@@ -405,9 +420,21 @@ class API {
|
|
|
405
420
|
const mapKey = JSON.stringify({
|
|
406
421
|
url: url,
|
|
407
422
|
headers: headers,
|
|
423
|
+
credentials: this.credentials,
|
|
424
|
+
cache: this.cache,
|
|
425
|
+
keepAlive: this.keepAlive,
|
|
408
426
|
});
|
|
427
|
+
|
|
428
|
+
// Les GET non bloquants doivent pouvoir rejoindre une requête déjà en vol.
|
|
429
|
+
// Sinon firstCallDone() sérialise les appels avant que la map de déduplication
|
|
430
|
+
// ne soit consultée, ce qui déclenche deux fetch pour deux consommateurs.
|
|
431
|
+
if (this.blockUntilDone) {
|
|
432
|
+
await this.firstCallDone();
|
|
433
|
+
API.firstCallDoneFlags.set(this.serviceURL, "loading");
|
|
434
|
+
}
|
|
435
|
+
|
|
409
436
|
if (!API.loadingGetPromises.has(mapKey)) {
|
|
410
|
-
const promise = new Promise(async (resolve) => {
|
|
437
|
+
const promise = new Promise<SharedGetResult | null>(async (resolve) => {
|
|
411
438
|
try {
|
|
412
439
|
const result = await fetch(url, {
|
|
413
440
|
headers: headers,
|
|
@@ -416,16 +443,22 @@ class API {
|
|
|
416
443
|
keepalive: this.keepAlive,
|
|
417
444
|
});
|
|
418
445
|
const handledResult = await this.handleResult(result, lastCall);
|
|
419
|
-
resolve(
|
|
446
|
+
resolve({
|
|
447
|
+
processed: handledResult,
|
|
448
|
+
response: this.lastResult,
|
|
449
|
+
});
|
|
420
450
|
} catch (e) {
|
|
451
|
+
API.firstCallDoneFlags.set(this.serviceURL, "error");
|
|
421
452
|
resolve(null);
|
|
422
453
|
}
|
|
423
454
|
});
|
|
424
455
|
API.loadingGetPromises.set(mapKey, promise);
|
|
425
456
|
}
|
|
426
|
-
const
|
|
457
|
+
const sharedResult = await API.loadingGetPromises.get(mapKey);
|
|
427
458
|
API.loadingGetPromises.delete(mapKey);
|
|
428
|
-
|
|
459
|
+
if (!sharedResult) return null;
|
|
460
|
+
this.lastResult = sharedResult.response;
|
|
461
|
+
return sharedResult.processed as T & ResultTypeInterface;
|
|
429
462
|
}
|
|
430
463
|
|
|
431
464
|
/**
|
|
@@ -17,6 +17,19 @@ const usersEndpoint = new Endpoint<User[]>("users");
|
|
|
17
17
|
payload?: ApiResult<User[]>;
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
The same decorator adapts to a method. The method receives the complete
|
|
21
|
+
`ApiResult<T>` payload after each GET:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
@get(usersEndpoint)
|
|
25
|
+
handleUsers(payload?: ApiResult<User[]>) {
|
|
26
|
+
if (!payload) return;
|
|
27
|
+
|
|
28
|
+
console.log(payload.response?.status);
|
|
29
|
+
console.log(payload.result);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
20
33
|
The first argument is always an
|
|
21
34
|
[`Endpoint<T>`](#docs/_misc/endpoint.md/endpoint). API configuration is read
|
|
22
35
|
from the HTML scope (`serviceURL`, token, etc.), so the component is usually
|
|
@@ -46,6 +59,22 @@ async refresh() {
|
|
|
46
59
|
`refetch(component)` returns a `Promise<ApiResult<T> | undefined>` that resolves
|
|
47
60
|
after the GET has completed.
|
|
48
61
|
|
|
62
|
+
The named handle can also decorate a method and be reused for refetching:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const usersGet = get(new Endpoint<User[]>("users"));
|
|
66
|
+
|
|
67
|
+
@usersGet
|
|
68
|
+
handleUsers(payload?: ApiResult<User[]>) {
|
|
69
|
+
// ...
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@refetch(usersGet)
|
|
73
|
+
reloadUsers() {
|
|
74
|
+
// The GET runs and handleUsers receives its payload.
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
49
78
|
### From a method decorator
|
|
50
79
|
|
|
51
80
|
The refetch can decorate a local method. The default is `after`; if the
|
|
@@ -116,6 +145,8 @@ import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
|
|
|
116
145
|
<template>
|
|
117
146
|
<docs-demo-sources for="demo-api-get"></docs-demo-sources>
|
|
118
147
|
<demo-api-get></demo-api-get>
|
|
148
|
+
<docs-demo-sources for="demo-api-get-method"></docs-demo-sources>
|
|
149
|
+
<demo-api-get-method></demo-api-get-method>
|
|
119
150
|
<docs-demo-sources for="demo-api-get-configuration-key"></docs-demo-sources>
|
|
120
151
|
<demo-api-get-configuration-key></demo-api-get-configuration-key>
|
|
121
152
|
</template>
|
|
@@ -16,6 +16,15 @@ const patchUser = patch(new Endpoint<User>("users/42"), bodyKey);
|
|
|
16
16
|
payload?: ApiResult<User>;
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
The same decorator adapts to a method:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
@patch(new Endpoint<User>("users/42"), bodyKey)
|
|
23
|
+
handlePatch(payload?: ApiResult<User>) {
|
|
24
|
+
if (payload?.response?.ok) console.log(payload.result);
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
19
28
|
To run the operation again from the component:
|
|
20
29
|
|
|
21
30
|
```typescript
|
|
@@ -17,6 +17,15 @@ const createUser = post(new Endpoint<User>("users"), userBodyKey);
|
|
|
17
17
|
payload?: ApiResult<User>;
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
The same decorator adapts to a method and receives the complete payload:
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
@post(new Endpoint<User>("users"), userBodyKey)
|
|
24
|
+
handleCreate(payload?: ApiResult<User>) {
|
|
25
|
+
if (payload?.response?.ok) console.log(payload.result);
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
20
29
|
The current body is read from `userBodyKey`. By default, the POST is sent when
|
|
21
30
|
the component connects and after each body mutation. Mutations in the same
|
|
22
31
|
frame are coalesced into one request.
|
|
@@ -120,6 +129,8 @@ import { Endpoint } from "@supersoniks/concorde/utils/endpoint";
|
|
|
120
129
|
<template>
|
|
121
130
|
<docs-demo-sources for="demo-api-post"></docs-demo-sources>
|
|
122
131
|
<demo-api-post></demo-api-post>
|
|
132
|
+
<docs-demo-sources for="demo-api-post-method"></docs-demo-sources>
|
|
133
|
+
<demo-api-post-method></demo-api-post-method>
|
|
123
134
|
<docs-demo-sources for="demo-api-post-dynamic"></docs-demo-sources>
|
|
124
135
|
<demo-api-post-dynamic></demo-api-post-dynamic>
|
|
125
136
|
</template>
|
|
@@ -16,6 +16,15 @@ const updateUser = put(new Endpoint<User>("users/42"), bodyKey);
|
|
|
16
16
|
payload?: ApiResult<User>;
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
The same decorator adapts to a method:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
@put(new Endpoint<User>("users/42"), bodyKey)
|
|
23
|
+
handleUpdate(payload?: ApiResult<User>) {
|
|
24
|
+
if (payload?.response?.ok) console.log(payload.result);
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
19
28
|
To run the operation again from the component:
|
|
20
29
|
|
|
21
30
|
```typescript
|
|
@@ -252,6 +252,13 @@ export const DOCS_DEMO_SOURCE_REGISTRY: Record<string, DocsSource[]> = {
|
|
|
252
252
|
{ path: "src/docs/example/decorators-demo-geo.ts", label: "geo API" },
|
|
253
253
|
{ path: "src/docs/mock-api/router.ts", label: "mock router" },
|
|
254
254
|
],
|
|
255
|
+
"demo-api-get-method": [
|
|
256
|
+
{
|
|
257
|
+
path: "src/docs/example/decorators-demo-subscribe-publish-get-demos.ts",
|
|
258
|
+
label: "demo-api-get-method",
|
|
259
|
+
},
|
|
260
|
+
{ path: "src/docs/example/decorators-demo-geo.ts", label: "geo API" },
|
|
261
|
+
],
|
|
255
262
|
"demo-api-get-configuration-key": [
|
|
256
263
|
{
|
|
257
264
|
path: "src/docs/example/decorators-demo-subscribe-publish-get-demos.ts",
|
|
@@ -276,6 +283,13 @@ export const DOCS_DEMO_SOURCE_REGISTRY: Record<string, DocsSource[]> = {
|
|
|
276
283
|
},
|
|
277
284
|
{ path: "src/docs/mock-api/router.ts", label: "mock router" },
|
|
278
285
|
],
|
|
286
|
+
"demo-api-post-method": [
|
|
287
|
+
{
|
|
288
|
+
path: "src/docs/example/decorators-demo-post.ts",
|
|
289
|
+
label: "demo-api-post-method",
|
|
290
|
+
},
|
|
291
|
+
{ path: "src/docs/mock-api/router.ts", label: "mock router" },
|
|
292
|
+
],
|
|
279
293
|
"demo-api-post-dynamic": [
|
|
280
294
|
{
|
|
281
295
|
path: "src/docs/example/decorators-demo-post.ts",
|
|
@@ -65,6 +65,12 @@ export const docsDemoPostPublishRequestKey = new DataProviderKey<RegisterRequest
|
|
|
65
65
|
export const docsDemoPostTriggerKey = new DataProviderKey<number>(
|
|
66
66
|
"docsDemoPostTrigger",
|
|
67
67
|
);
|
|
68
|
+
export const docsDemoPostMethodRequestKey = new DataProviderKey<RegisterRequest>(
|
|
69
|
+
"docsDemoPostMethodRequest",
|
|
70
|
+
);
|
|
71
|
+
export const docsDemoPostMethodTriggerKey = new DataProviderKey<number>(
|
|
72
|
+
"docsDemoPostMethodTrigger",
|
|
73
|
+
);
|
|
68
74
|
export const docsDemoPostDynamicRequestKey = new DataProviderKey<SessionSyncRequest>(
|
|
69
75
|
"docsDemoPostDynamicRequest",
|
|
70
76
|
);
|
|
@@ -140,6 +146,70 @@ export class DemoApiPost extends LitElement {
|
|
|
140
146
|
}
|
|
141
147
|
}
|
|
142
148
|
|
|
149
|
+
@customElement("demo-api-post-method")
|
|
150
|
+
export class DemoApiPostMethod extends LitElement {
|
|
151
|
+
static styles = [tailwind];
|
|
152
|
+
|
|
153
|
+
@state()
|
|
154
|
+
private payload?: ApiResult<RegisterResult>;
|
|
155
|
+
|
|
156
|
+
connectedCallback() {
|
|
157
|
+
super.connectedCallback();
|
|
158
|
+
set(docsDemoPostMethodRequestKey, {
|
|
159
|
+
email: "method@concorde.local",
|
|
160
|
+
password: "method-password",
|
|
161
|
+
});
|
|
162
|
+
set(docsDemoPostMethodTriggerKey, 0);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@post(
|
|
166
|
+
registerPostEndpoint,
|
|
167
|
+
docsDemoPostMethodRequestKey,
|
|
168
|
+
docsDemoReqresApiConfigurationKey,
|
|
169
|
+
{ triggerKey: docsDemoPostMethodTriggerKey },
|
|
170
|
+
)
|
|
171
|
+
handlePayload(payload?: ApiResult<RegisterResult>) {
|
|
172
|
+
this.payload = payload;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private updateBody() {
|
|
176
|
+
set(docsDemoPostMethodRequestKey, {
|
|
177
|
+
email: `method-${Date.now()}@concorde.local`,
|
|
178
|
+
password: "method-password",
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private resend() {
|
|
183
|
+
dp(docsDemoPostMethodTriggerKey).invalidate();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
render() {
|
|
187
|
+
const result = this.payload?.result;
|
|
188
|
+
return html`
|
|
189
|
+
<div class="space-y-3">
|
|
190
|
+
<div class="flex flex-wrap items-center gap-2">
|
|
191
|
+
<span class="text-sm font-medium">✉️ POST function mode</span>
|
|
192
|
+
<sonic-button size="sm" @click=${this.updateBody}>
|
|
193
|
+
Update body & POST
|
|
194
|
+
</sonic-button>
|
|
195
|
+
<sonic-button size="sm" variant="secondary" @click=${this.resend}>
|
|
196
|
+
Invalidate trigger
|
|
197
|
+
</sonic-button>
|
|
198
|
+
</div>
|
|
199
|
+
<p class="text-sm text-neutral-600 dark:text-neutral-400">
|
|
200
|
+
The <code>@post</code> decorator calls
|
|
201
|
+
<code>handlePayload</code> with the complete API payload.
|
|
202
|
+
</p>
|
|
203
|
+
<p class="text-xs text-neutral-500">
|
|
204
|
+
HTTP status:
|
|
205
|
+
<strong>${this.payload?.response?.status ?? "loading…"}</strong>
|
|
206
|
+
· email: <strong>${result?.email ?? "—"}</strong>
|
|
207
|
+
</p>
|
|
208
|
+
</div>
|
|
209
|
+
`;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
143
213
|
@customElement("demo-api-post-dynamic")
|
|
144
214
|
export class DemoApiPostDynamic extends LitElement {
|
|
145
215
|
static styles = [tailwind];
|
|
@@ -5,6 +5,7 @@ import type { ApiResult } from "@supersoniks/concorde/core/utils/api";
|
|
|
5
5
|
import { DataProviderKey } from "@supersoniks/concorde/core/utils/dataProviderKey";
|
|
6
6
|
import { sub } from "@supersoniks/concorde/directives";
|
|
7
7
|
import {
|
|
8
|
+
dp,
|
|
8
9
|
get as storeGet,
|
|
9
10
|
set,
|
|
10
11
|
} from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
@@ -28,6 +29,9 @@ const geoCommunesGet = get(
|
|
|
28
29
|
geoCommunesApiGetEndpoint,
|
|
29
30
|
docsDemoGeoApiConfigurationKey,
|
|
30
31
|
);
|
|
32
|
+
const geoCommunesMethodTriggerKey = new DataProviderKey<number>(
|
|
33
|
+
"docsDemoGeoCommunesMethodTrigger",
|
|
34
|
+
);
|
|
31
35
|
|
|
32
36
|
@customElement("demo-publish")
|
|
33
37
|
export class DemoPublish extends LitElement {
|
|
@@ -124,6 +128,61 @@ export class DemoApiGet extends LitElement {
|
|
|
124
128
|
}
|
|
125
129
|
}
|
|
126
130
|
|
|
131
|
+
@customElement("demo-api-get-method")
|
|
132
|
+
export class DemoApiGetMethod extends LitElement {
|
|
133
|
+
static styles = [tailwind];
|
|
134
|
+
|
|
135
|
+
@state()
|
|
136
|
+
private payload?: ApiResult<GeoCommuneRow[]>;
|
|
137
|
+
|
|
138
|
+
connectedCallback() {
|
|
139
|
+
super.connectedCallback();
|
|
140
|
+
set(geoCommunesMethodTriggerKey, 0);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@get(geoCommunesApiGetEndpoint, docsDemoGeoApiConfigurationKey, {
|
|
144
|
+
triggerKey: geoCommunesMethodTriggerKey,
|
|
145
|
+
})
|
|
146
|
+
handlePayload(payload?: ApiResult<GeoCommuneRow[]>) {
|
|
147
|
+
this.payload = payload;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private refresh() {
|
|
151
|
+
dp(geoCommunesMethodTriggerKey).invalidate();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
render() {
|
|
155
|
+
const rows = this.payload?.result ?? [];
|
|
156
|
+
return html`
|
|
157
|
+
<div class="space-y-3">
|
|
158
|
+
<div class="flex flex-wrap items-center gap-3">
|
|
159
|
+
<span class="text-sm font-medium">🗺️ GET function mode</span>
|
|
160
|
+
<sonic-button size="sm" @click=${this.refresh}>
|
|
161
|
+
Invalidate trigger
|
|
162
|
+
</sonic-button>
|
|
163
|
+
</div>
|
|
164
|
+
<p class="text-sm text-neutral-600 dark:text-neutral-400">
|
|
165
|
+
The <code>@get</code> decorator calls <code>handlePayload</code> with
|
|
166
|
+
the complete API payload.
|
|
167
|
+
</p>
|
|
168
|
+
<p class="text-xs text-neutral-500">
|
|
169
|
+
HTTP status:
|
|
170
|
+
<strong>${this.payload?.response?.status ?? "loading…"}</strong>
|
|
171
|
+
</p>
|
|
172
|
+
<ul class="grid gap-1 sm:grid-cols-2">
|
|
173
|
+
${rows.slice(0, 6).map(
|
|
174
|
+
(commune) =>
|
|
175
|
+
html`<li class="text-sm">
|
|
176
|
+
${commune.nom}
|
|
177
|
+
<span class="text-neutral-500">(${commune.code})</span>
|
|
178
|
+
</li>`,
|
|
179
|
+
)}
|
|
180
|
+
</ul>
|
|
181
|
+
</div>
|
|
182
|
+
`;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
127
186
|
@customElement("demo-api-get-configuration-key")
|
|
128
187
|
export class DemoApiGetConfigurationKey extends LitElement {
|
|
129
188
|
static styles = [tailwind];
|
|
@@ -4714,6 +4714,21 @@
|
|
|
4714
4714
|
}
|
|
4715
4715
|
}
|
|
4716
4716
|
},
|
|
4717
|
+
{
|
|
4718
|
+
"search": "The same decorator adapts to a method. The method receives the complete\nApiResult<T> payload after each GET:\n",
|
|
4719
|
+
"files": {
|
|
4720
|
+
"docs/_decorators/get.md": {
|
|
4721
|
+
"title": "@get",
|
|
4722
|
+
"hashes": {
|
|
4723
|
+
"minimal-usage": {
|
|
4724
|
+
"count": 1,
|
|
4725
|
+
"title": "Minimal usage",
|
|
4726
|
+
"type": "paragraph"
|
|
4727
|
+
}
|
|
4728
|
+
}
|
|
4729
|
+
}
|
|
4730
|
+
}
|
|
4731
|
+
},
|
|
4717
4732
|
{
|
|
4718
4733
|
"search": "The first argument is always an\nEndpoint<T>. API configuration is read\nfrom the HTML scope (serviceURL, token, etc.), so the component is usually\nplaced below an element that provides this configuration.\n",
|
|
4719
4734
|
"files": {
|
|
@@ -4745,7 +4760,37 @@
|
|
|
4745
4760
|
}
|
|
4746
4761
|
},
|
|
4747
4762
|
{
|
|
4748
|
-
"search": "
|
|
4763
|
+
"search": "refetch(component) returns a Promise<ApiResult<T> | undefined> that resolves\nafter the GET has completed.\n",
|
|
4764
|
+
"files": {
|
|
4765
|
+
"docs/_decorators/get.md": {
|
|
4766
|
+
"title": "@get",
|
|
4767
|
+
"hashes": {
|
|
4768
|
+
"from-the-component": {
|
|
4769
|
+
"count": 1,
|
|
4770
|
+
"title": "From the component",
|
|
4771
|
+
"type": "paragraph"
|
|
4772
|
+
}
|
|
4773
|
+
}
|
|
4774
|
+
}
|
|
4775
|
+
}
|
|
4776
|
+
},
|
|
4777
|
+
{
|
|
4778
|
+
"search": "The named handle can also decorate a method and be reused for refetching:\n",
|
|
4779
|
+
"files": {
|
|
4780
|
+
"docs/_decorators/get.md": {
|
|
4781
|
+
"title": "@get",
|
|
4782
|
+
"hashes": {
|
|
4783
|
+
"from-the-component": {
|
|
4784
|
+
"count": 1,
|
|
4785
|
+
"title": "From the component",
|
|
4786
|
+
"type": "paragraph"
|
|
4787
|
+
}
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4790
|
+
}
|
|
4791
|
+
},
|
|
4792
|
+
{
|
|
4793
|
+
"search": "The refetch can decorate a local method. The default is after; if the\nmethod returns a Promise, the GET waits for its resolution. The decorated method\ncall also waits for the refetch to complete.\n",
|
|
4749
4794
|
"files": {
|
|
4750
4795
|
"docs/_decorators/get.md": {
|
|
4751
4796
|
"title": "@get",
|
|
@@ -4760,7 +4805,7 @@
|
|
|
4760
4805
|
}
|
|
4761
4806
|
},
|
|
4762
4807
|
{
|
|
4763
|
-
"search": "Use { when: "before" } when the GET must
|
|
4808
|
+
"search": "Use { when: "before" } when the GET must complete before the method runs:\n",
|
|
4764
4809
|
"files": {
|
|
4765
4810
|
"docs/_decorators/get.md": {
|
|
4766
4811
|
"title": "@get",
|
|
@@ -5799,6 +5844,31 @@
|
|
|
5799
5844
|
}
|
|
5800
5845
|
}
|
|
5801
5846
|
},
|
|
5847
|
+
{
|
|
5848
|
+
"search": "The same decorator adapts to a method:\n",
|
|
5849
|
+
"files": {
|
|
5850
|
+
"docs/_decorators/patch.md": {
|
|
5851
|
+
"title": "@patch",
|
|
5852
|
+
"hashes": {
|
|
5853
|
+
"minimal-usage": {
|
|
5854
|
+
"count": 1,
|
|
5855
|
+
"title": "Minimal usage",
|
|
5856
|
+
"type": "paragraph"
|
|
5857
|
+
}
|
|
5858
|
+
}
|
|
5859
|
+
},
|
|
5860
|
+
"docs/_decorators/put.md": {
|
|
5861
|
+
"title": "@put",
|
|
5862
|
+
"hashes": {
|
|
5863
|
+
"minimal-usage": {
|
|
5864
|
+
"count": 1,
|
|
5865
|
+
"title": "Minimal usage",
|
|
5866
|
+
"type": "paragraph"
|
|
5867
|
+
}
|
|
5868
|
+
}
|
|
5869
|
+
}
|
|
5870
|
+
}
|
|
5871
|
+
},
|
|
5802
5872
|
{
|
|
5803
5873
|
"search": "To run the operation again from the component:\n",
|
|
5804
5874
|
"files": {
|
|
@@ -5824,6 +5894,21 @@
|
|
|
5824
5894
|
}
|
|
5825
5895
|
}
|
|
5826
5896
|
},
|
|
5897
|
+
{
|
|
5898
|
+
"search": "send(component) returns a Promise resolved after the PATCH completes. See\n@post for the method-decorator form and the\nwhen: "before" option.\n",
|
|
5899
|
+
"files": {
|
|
5900
|
+
"docs/_decorators/patch.md": {
|
|
5901
|
+
"title": "@patch",
|
|
5902
|
+
"hashes": {
|
|
5903
|
+
"minimal-usage": {
|
|
5904
|
+
"count": 1,
|
|
5905
|
+
"title": "Minimal usage",
|
|
5906
|
+
"type": "paragraph"
|
|
5907
|
+
}
|
|
5908
|
+
}
|
|
5909
|
+
}
|
|
5910
|
+
}
|
|
5911
|
+
},
|
|
5827
5912
|
{
|
|
5828
5913
|
"search": "The PATCH is also sent automatically when the body mutates, unless\nautoPostOnBodyMutation: false is set. The available options are described in\n@post:\n",
|
|
5829
5914
|
"files": {
|
|
@@ -5909,6 +5994,21 @@
|
|
|
5909
5994
|
}
|
|
5910
5995
|
}
|
|
5911
5996
|
},
|
|
5997
|
+
{
|
|
5998
|
+
"search": "The same decorator adapts to a method and receives the complete payload:\n",
|
|
5999
|
+
"files": {
|
|
6000
|
+
"docs/_decorators/post.md": {
|
|
6001
|
+
"title": "@post",
|
|
6002
|
+
"hashes": {
|
|
6003
|
+
"minimal-usage": {
|
|
6004
|
+
"count": 1,
|
|
6005
|
+
"title": "Minimal usage",
|
|
6006
|
+
"type": "paragraph"
|
|
6007
|
+
}
|
|
6008
|
+
}
|
|
6009
|
+
}
|
|
6010
|
+
}
|
|
6011
|
+
},
|
|
5912
6012
|
{
|
|
5913
6013
|
"search": "The current body is read from userBodyKey. By default, the POST is sent when\nthe component connects and after each body mutation. Mutations in the same\nframe are coalesced into one request.\n",
|
|
5914
6014
|
"files": {
|
|
@@ -5955,7 +6055,7 @@
|
|
|
5955
6055
|
}
|
|
5956
6056
|
},
|
|
5957
6057
|
{
|
|
5958
|
-
"search": "send() is useful for “Save” or “Retry” buttons
|
|
6058
|
+
"search": "send() returns a Promise<ApiResult<T> | undefined> that resolves after the\noperation completes. It is useful for “Save” or “Retry” buttons and can repeat\nan operation with side effects.\n",
|
|
5959
6059
|
"files": {
|
|
5960
6060
|
"docs/_decorators/post.md": {
|
|
5961
6061
|
"title": "@post",
|
|
@@ -5970,7 +6070,7 @@
|
|
|
5970
6070
|
}
|
|
5971
6071
|
},
|
|
5972
6072
|
{
|
|
5973
|
-
"search": "The send action can decorate a local method. It runs after the method by\ndefault
|
|
6073
|
+
"search": "The send action can decorate a local method. It runs after the method by\ndefault, waits for an eventual Promise to resolve, and the decorated method\ncall waits for the send to complete:\n",
|
|
5974
6074
|
"files": {
|
|
5975
6075
|
"docs/_decorators/post.md": {
|
|
5976
6076
|
"title": "@post",
|
|
@@ -5985,7 +6085,7 @@
|
|
|
5985
6085
|
}
|
|
5986
6086
|
},
|
|
5987
6087
|
{
|
|
5988
|
-
"search": "Use { when: "before" } when the
|
|
6088
|
+
"search": "Use { when: "before" } when the send must complete before the method runs:\n",
|
|
5989
6089
|
"files": {
|
|
5990
6090
|
"docs/_decorators/post.md": {
|
|
5991
6091
|
"title": "@post",
|
|
@@ -6149,6 +6249,21 @@
|
|
|
6149
6249
|
}
|
|
6150
6250
|
}
|
|
6151
6251
|
},
|
|
6252
|
+
{
|
|
6253
|
+
"search": "send(component) returns a Promise resolved after the PUT completes. See\n@post for the method-decorator form and the\nwhen: "before" option.\n",
|
|
6254
|
+
"files": {
|
|
6255
|
+
"docs/_decorators/put.md": {
|
|
6256
|
+
"title": "@put",
|
|
6257
|
+
"hashes": {
|
|
6258
|
+
"minimal-usage": {
|
|
6259
|
+
"count": 1,
|
|
6260
|
+
"title": "Minimal usage",
|
|
6261
|
+
"type": "paragraph"
|
|
6262
|
+
}
|
|
6263
|
+
}
|
|
6264
|
+
}
|
|
6265
|
+
}
|
|
6266
|
+
},
|
|
6152
6267
|
{
|
|
6153
6268
|
"search": "The PUT is also sent automatically when the body mutates, unless\nautoPostOnBodyMutation: false is set. See\n@post for the option details:\n",
|
|
6154
6269
|
"files": {
|
package/src/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./components.ts","./concorde-loaded.ts","./css.d.ts","./dataprovider.ts","./decorators.ts","./directives.ts","./index.ts","./mixins.ts","./utils.ts","./core/core.ts","./core/_types/endpoint.ts","./core/_types/key.ts","./core/_types/types.ts","./core/components/functional/functional.ts","./core/components/functional/date/date.ts","./core/components/functional/example/example.ts","./core/components/functional/fetch/fetch.ts","./core/components/functional/if/if.test.ts","./core/components/functional/if/if.ts","./core/components/functional/list/list.demo.ts","./core/components/functional/list/list.spec.ts","./core/components/functional/list/list.ts","./core/components/functional/mix/mix.ts","./core/components/functional/queue/queue.demo.ts","./core/components/functional/queue/queue.ts","./core/components/functional/router/redirect.ts","./core/components/functional/router/router.demo.ts","./core/components/functional/router/router.spec.ts","./core/components/functional/router/router.ts","./core/components/functional/sdui/SDUIDescriptorTransformer.ts","./core/components/functional/sdui/sdui-utils.ts","./core/components/functional/sdui/sdui.ts","./core/components/functional/sdui/types.ts","./core/components/functional/sonic-scope/sonic-scope.ts","./core/components/functional/states/states.demo.ts","./core/components/functional/states/states.spec.ts","./core/components/functional/states/states.ts","./core/components/functional/submit/submit.ts","./core/components/functional/subscriber/subscriber.ts","./core/components/functional/translation/translation.ts","./core/components/functional/value/value.ts","./core/components/ui/ui.ts","./core/components/ui/_css/scroll.ts","./core/components/ui/_css/shadow.ts","./core/components/ui/_css/size.ts","./core/components/ui/_css/type.ts","./core/components/ui/alert/alert.ts","./core/components/ui/alert-messages/alert-messages.ts","./core/components/ui/badge/badge.ts","./core/components/ui/button/button.ts","./core/components/ui/captcha/altchaStyles.ts","./core/components/ui/captcha/captcha.ts","./core/components/ui/card/card-footer.ts","./core/components/ui/card/card-header-descripton.ts","./core/components/ui/card/card-header.ts","./core/components/ui/card/card-main.ts","./core/components/ui/card/card.ts","./core/components/ui/divider/divider.ts","./core/components/ui/form/checkbox/checkbox.ts","./core/components/ui/form/css/form-control.ts","./core/components/ui/form/fieldset/fieldset.ts","./core/components/ui/form/fieldset/legend-description.ts","./core/components/ui/form/fieldset/legend.ts","./core/components/ui/form/form-actions/form-actions.ts","./core/components/ui/form/form-layout/form-layout.ts","./core/components/ui/form/input/input.ts","./core/components/ui/form/input/password-helper.ts","./core/components/ui/form/input/same-value-helper.ts","./core/components/ui/form/input-autocomplete/input-autocomplete.ts","./core/components/ui/form/radio/radio.ts","./core/components/ui/form/select/select.ts","./core/components/ui/form/switch/switch.ts","./core/components/ui/form/textarea/textarea.ts","./core/components/ui/group/group.ts","./core/components/ui/icon/icon.stories.ts","./core/components/ui/icon/icon.ts","./core/components/ui/icon/icons.ts","./core/components/ui/image/image.ts","./core/components/ui/link/link.ts","./core/components/ui/loader/loader.stories.ts","./core/components/ui/loader/loader.ts","./core/components/ui/loader/styles/fixed.ts","./core/components/ui/loader/styles/inline.ts","./core/components/ui/menu/menu-item.ts","./core/components/ui/menu/menu.ts","./core/components/ui/modal/modal-actions.ts","./core/components/ui/modal/modal-close.ts","./core/components/ui/modal/modal-content.ts","./core/components/ui/modal/modal-subtitle.ts","./core/components/ui/modal/modal-title.ts","./core/components/ui/modal/modal-utils.ts","./core/components/ui/modal/modal.ts","./core/components/ui/pop/pop.ts","./core/components/ui/progress/progress.ts","./core/components/ui/table/table-caption.ts","./core/components/ui/table/table-tbody.ts","./core/components/ui/table/table-td.ts","./core/components/ui/table/table-tfoot.ts","./core/components/ui/table/table-th.ts","./core/components/ui/table/table-thead.ts","./core/components/ui/table/table-tr.ts","./core/components/ui/table/table.ts","./core/components/ui/theme/theme.ts","./core/components/ui/theme/theme-collection/core-variables.ts","./core/components/ui/theme/theme-collection/dark.ts","./core/components/ui/theme/theme-collection/light.ts","./core/components/ui/toast/message-subscriber.ts","./core/components/ui/toast/toast-item.ts","./core/components/ui/toast/toast.ts","./core/components/ui/toast/types.ts","./core/components/ui/tooltip/tooltip.ts","./core/decorators/Subscriber.ts","./core/decorators/api.post.spec.ts","./core/decorators/api.spec.ts","./core/decorators/api.ts","./core/decorators/lifecycle.ts","./core/decorators/subscriber/ancestorAttribute.spec.ts","./core/decorators/subscriber/ancestorAttribute.ts","./core/decorators/subscriber/autoFill.ts","./core/decorators/subscriber/autoSubscribe.ts","./core/decorators/subscriber/bind.ts","./core/decorators/subscriber/common.ts","./core/decorators/subscriber/dynamicPath.spec.ts","./core/decorators/subscriber/dynamicPath.ts","./core/decorators/subscriber/dynamicPropertyWatch.spec.ts","./core/decorators/subscriber/dynamicPropertyWatch.ts","./core/decorators/subscriber/handle.disambig.spec.ts","./core/decorators/subscriber/handle.skip.spec.ts","./core/decorators/subscriber/handle.ts","./core/decorators/subscriber/onAssign.ts","./core/decorators/subscriber/publish.spec.ts","./core/decorators/subscriber/publish.ts","./core/decorators/subscriber/publisherPath.ts","./core/decorators/subscriber/subscribe.spec.ts","./core/decorators/subscriber/subscribe.ts","./core/directives/DataProvider.sub.spec.ts","./core/directives/DataProvider.ts","./core/directives/Wording.ts","./core/mixins/Fetcher.ts","./core/mixins/FormCheckable.ts","./core/mixins/FormElement.ts","./core/mixins/FormInput.ts","./core/mixins/Subscriber.ts","./core/mixins/TemplatesContainer.ts","./core/mixins/mixins.ts","./core/utils/AncestorAttributeObserver.ts","./core/utils/Arrays.ts","./core/utils/DataBindObserver.ts","./core/utils/Electron.ts","./core/utils/Format.ts","./core/utils/HTML.ts","./core/utils/LocationHandler.ts","./core/utils/Objects.ts","./core/utils/PublisherProxy.ts","./core/utils/SafariScrollGuard.ts","./core/utils/Utils.ts","./core/utils/aesCrypto.ts","./core/utils/api.ts","./core/utils/dataProviderKey.spec.ts","./core/utils/dataProviderKey.ts","./core/utils/dpOptions.spec.ts","./core/utils/endpoint.spec.ts","./core/utils/endpoint.ts","./core/utils/publisherPathKey.spec.ts","./core/utils/route.spec.ts","./core/utils/route.ts","./core/utils/url-pattern.ts","./test-utils/TestUtils.ts"],"version":"5.9.2"}
|
|
1
|
+
{"root":["./components.ts","./concorde-loaded.ts","./css.d.ts","./dataprovider.ts","./decorators.ts","./directives.ts","./index.ts","./mixins.ts","./utils.ts","./core/core.ts","./core/_types/endpoint.ts","./core/_types/key.ts","./core/_types/types.ts","./core/components/functional/functional.ts","./core/components/functional/date/date.ts","./core/components/functional/example/example.ts","./core/components/functional/fetch/fetch.ts","./core/components/functional/if/if.test.ts","./core/components/functional/if/if.ts","./core/components/functional/list/list.demo.ts","./core/components/functional/list/list.spec.ts","./core/components/functional/list/list.ts","./core/components/functional/mix/mix.ts","./core/components/functional/queue/queue.demo.ts","./core/components/functional/queue/queue.ts","./core/components/functional/router/redirect.ts","./core/components/functional/router/router.demo.ts","./core/components/functional/router/router.spec.ts","./core/components/functional/router/router.ts","./core/components/functional/sdui/SDUIDescriptorTransformer.ts","./core/components/functional/sdui/sdui-utils.ts","./core/components/functional/sdui/sdui.ts","./core/components/functional/sdui/types.ts","./core/components/functional/sonic-scope/sonic-scope.ts","./core/components/functional/states/states.demo.ts","./core/components/functional/states/states.spec.ts","./core/components/functional/states/states.ts","./core/components/functional/submit/submit.ts","./core/components/functional/subscriber/subscriber.ts","./core/components/functional/translation/translation.ts","./core/components/functional/value/value.ts","./core/components/ui/ui.ts","./core/components/ui/_css/scroll.ts","./core/components/ui/_css/shadow.ts","./core/components/ui/_css/size.ts","./core/components/ui/_css/type.ts","./core/components/ui/alert/alert.ts","./core/components/ui/alert-messages/alert-messages.ts","./core/components/ui/badge/badge.ts","./core/components/ui/button/button.ts","./core/components/ui/captcha/altchaStyles.ts","./core/components/ui/captcha/captcha.ts","./core/components/ui/card/card-footer.ts","./core/components/ui/card/card-header-descripton.ts","./core/components/ui/card/card-header.ts","./core/components/ui/card/card-main.ts","./core/components/ui/card/card.ts","./core/components/ui/divider/divider.ts","./core/components/ui/form/checkbox/checkbox.ts","./core/components/ui/form/css/form-control.ts","./core/components/ui/form/fieldset/fieldset.ts","./core/components/ui/form/fieldset/legend-description.ts","./core/components/ui/form/fieldset/legend.ts","./core/components/ui/form/form-actions/form-actions.ts","./core/components/ui/form/form-layout/form-layout.ts","./core/components/ui/form/input/input.ts","./core/components/ui/form/input/password-helper.ts","./core/components/ui/form/input/same-value-helper.ts","./core/components/ui/form/input-autocomplete/input-autocomplete.ts","./core/components/ui/form/radio/radio.ts","./core/components/ui/form/select/select.ts","./core/components/ui/form/switch/switch.ts","./core/components/ui/form/textarea/textarea.ts","./core/components/ui/group/group.ts","./core/components/ui/icon/icon.stories.ts","./core/components/ui/icon/icon.ts","./core/components/ui/icon/icons.ts","./core/components/ui/image/image.ts","./core/components/ui/link/link.ts","./core/components/ui/loader/loader.stories.ts","./core/components/ui/loader/loader.ts","./core/components/ui/loader/styles/fixed.ts","./core/components/ui/loader/styles/inline.ts","./core/components/ui/menu/menu-item.ts","./core/components/ui/menu/menu.ts","./core/components/ui/modal/modal-actions.ts","./core/components/ui/modal/modal-close.ts","./core/components/ui/modal/modal-content.ts","./core/components/ui/modal/modal-subtitle.ts","./core/components/ui/modal/modal-title.ts","./core/components/ui/modal/modal-utils.ts","./core/components/ui/modal/modal.ts","./core/components/ui/pop/pop.ts","./core/components/ui/progress/progress.ts","./core/components/ui/table/table-caption.ts","./core/components/ui/table/table-tbody.ts","./core/components/ui/table/table-td.ts","./core/components/ui/table/table-tfoot.ts","./core/components/ui/table/table-th.ts","./core/components/ui/table/table-thead.ts","./core/components/ui/table/table-tr.ts","./core/components/ui/table/table.ts","./core/components/ui/theme/theme.ts","./core/components/ui/theme/theme-collection/core-variables.ts","./core/components/ui/theme/theme-collection/dark.ts","./core/components/ui/theme/theme-collection/light.ts","./core/components/ui/toast/message-subscriber.ts","./core/components/ui/toast/toast-item.ts","./core/components/ui/toast/toast.ts","./core/components/ui/toast/types.ts","./core/components/ui/tooltip/tooltip.ts","./core/decorators/Subscriber.ts","./core/decorators/api.post.spec.ts","./core/decorators/api.spec.ts","./core/decorators/api.ts","./core/decorators/lifecycle.ts","./core/decorators/subscriber/ancestorAttribute.spec.ts","./core/decorators/subscriber/ancestorAttribute.ts","./core/decorators/subscriber/autoFill.ts","./core/decorators/subscriber/autoSubscribe.ts","./core/decorators/subscriber/bind.ts","./core/decorators/subscriber/common.ts","./core/decorators/subscriber/dynamicPath.spec.ts","./core/decorators/subscriber/dynamicPath.ts","./core/decorators/subscriber/dynamicPropertyWatch.spec.ts","./core/decorators/subscriber/dynamicPropertyWatch.ts","./core/decorators/subscriber/handle.disambig.spec.ts","./core/decorators/subscriber/handle.skip.spec.ts","./core/decorators/subscriber/handle.ts","./core/decorators/subscriber/onAssign.ts","./core/decorators/subscriber/publish.spec.ts","./core/decorators/subscriber/publish.ts","./core/decorators/subscriber/publisherPath.ts","./core/decorators/subscriber/subscribe.spec.ts","./core/decorators/subscriber/subscribe.ts","./core/directives/DataProvider.sub.spec.ts","./core/directives/DataProvider.ts","./core/directives/Wording.ts","./core/mixins/Fetcher.ts","./core/mixins/FormCheckable.ts","./core/mixins/FormElement.ts","./core/mixins/FormInput.ts","./core/mixins/Subscriber.ts","./core/mixins/TemplatesContainer.ts","./core/mixins/mixins.ts","./core/utils/AncestorAttributeObserver.ts","./core/utils/Arrays.ts","./core/utils/DataBindObserver.ts","./core/utils/Electron.ts","./core/utils/Format.ts","./core/utils/HTML.ts","./core/utils/LocationHandler.ts","./core/utils/Objects.ts","./core/utils/PublisherProxy.ts","./core/utils/SafariScrollGuard.ts","./core/utils/Utils.ts","./core/utils/aesCrypto.ts","./core/utils/api.spec.ts","./core/utils/api.ts","./core/utils/dataProviderKey.spec.ts","./core/utils/dataProviderKey.ts","./core/utils/dpOptions.spec.ts","./core/utils/endpoint.spec.ts","./core/utils/endpoint.ts","./core/utils/publisherPathKey.spec.ts","./core/utils/route.spec.ts","./core/utils/route.ts","./core/utils/url-pattern.ts","./test-utils/TestUtils.ts"],"version":"5.9.2"}
|