@supersoniks/concorde 4.9.9 → 4.9.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build-infos.json +1 -1
- package/concorde-core.bundle.js +241 -241
- package/concorde-core.es.js +2931 -2851
- package/dist/concorde-core.bundle.js +241 -241
- package/dist/concorde-core.es.js +2931 -2851
- package/dist/js/core/decorators/api.js +146 -43
- package/dist/js/core/decorators/api.js.map +1 -1
- package/dist/js/decorators.js +4 -0
- package/dist/js/decorators.js.map +1 -1
- package/dist/types/core/decorators/api.d.ts +87 -60
- package/dist/types/core/decorators/api.d.ts.map +1 -1
- package/dist/types/decorators.d.ts +3 -1
- package/dist/types/decorators.d.ts.map +1 -1
- package/docs/assets/index-D2Q3JyQ6.css +1 -0
- package/docs/assets/{index-hElUgV9_.js → index-DURr6O71.js} +651 -736
- package/docs/crawl/docs/_decorators/get.html +89 -81
- package/docs/crawl/docs/_decorators/patch.html +43 -23
- package/docs/crawl/docs/_decorators/post.html +101 -72
- package/docs/crawl/docs/_decorators/put.html +44 -21
- package/docs/crawl/docs/_getting-started/ai-agents.html +45 -6
- package/docs/crawl/hubs/decorators.html +145 -70
- package/docs/crawl/hubs/remote-data.html +145 -70
- package/docs/index.html +2 -2
- package/docs/llms-full.txt +276 -147
- package/docs/llms.txt +4 -4
- package/docs/src/core/components/functional/queue/queue.md +0 -0
- package/docs/src/core/components/ui/button/button.md +0 -0
- package/docs/src/docs/_decorators/get.md +88 -80
- package/docs/src/docs/_decorators/patch.md +41 -25
- package/docs/src/docs/_decorators/post.md +104 -62
- package/docs/src/docs/_decorators/put.md +42 -24
- package/docs/src/docs/_getting-started/ai-agents.md +24 -4
- package/docs/src/docs/search/docs-search.json +182 -112
- package/docs/src/tsconfig.json +270 -267
- package/package.json +1 -1
- package/src/core/decorators/api.post.spec.ts +79 -1
- package/src/core/decorators/api.spec.ts +141 -1
- package/src/core/decorators/api.ts +330 -180
- package/src/decorators.ts +7 -0
- package/src/docs/_decorators/get.md +88 -80
- package/src/docs/_decorators/patch.md +41 -25
- package/src/docs/_decorators/post.md +104 -62
- package/src/docs/_decorators/put.md +42 -24
- package/src/docs/components/docs-demo-sources.ts +9 -14
- package/src/docs/example/decorators-demo-geo.ts +0 -21
- package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +42 -133
- package/src/docs/search/docs-search.json +128 -133
- package/docs/assets/index-Bnp7gVaA.css +0 -1
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ import API, {
|
|
|
5
5
|
type ApiResult,
|
|
6
6
|
} from "@supersoniks/concorde/core/utils/api";
|
|
7
7
|
import { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
8
|
-
import { patch, post, put } from "./api";
|
|
8
|
+
import { patch, post, put, send } from "./api";
|
|
9
9
|
|
|
10
10
|
async function flushSendFrames() {
|
|
11
11
|
await new Promise<void>((resolve) => {
|
|
@@ -68,6 +68,84 @@ describe("post", () => {
|
|
|
68
68
|
expect(el.payload?.result).toEqual({ ok: true });
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
+
it("expose un send local avec le body courant", async () => {
|
|
72
|
+
const bodyPubId = "postSpecLocalSend";
|
|
73
|
+
const pub = PublisherManager.get(bodyPubId);
|
|
74
|
+
pub.set({ value: "first" });
|
|
75
|
+
const bodyKey = new DataProviderKey<{ value: string }>(bodyPubId);
|
|
76
|
+
const syncEp = new Endpoint<{ ok: boolean }>("items/local-send");
|
|
77
|
+
const localPost = post(syncEp, bodyKey);
|
|
78
|
+
const tag = "test-api-post-local-send";
|
|
79
|
+
|
|
80
|
+
class C extends HTMLElement {
|
|
81
|
+
@localPost
|
|
82
|
+
payload: ApiResult<{ ok: boolean }> | null = null;
|
|
83
|
+
}
|
|
84
|
+
if (!customElements.get(tag)) {
|
|
85
|
+
customElements.define(tag, C);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const wrap = document.createElement("div");
|
|
89
|
+
wrap.setAttribute("serviceURL", "https://api.example.test");
|
|
90
|
+
const el = document.createElement(tag) as InstanceType<typeof C>;
|
|
91
|
+
wrap.appendChild(el);
|
|
92
|
+
document.body.appendChild(wrap);
|
|
93
|
+
|
|
94
|
+
await flushSendFrames();
|
|
95
|
+
vi.mocked(API.prototype.postDetailed).mockClear();
|
|
96
|
+
|
|
97
|
+
pub.set({ value: "second" });
|
|
98
|
+
const payload = await localPost.send(el);
|
|
99
|
+
|
|
100
|
+
expect(API.prototype.postDetailed).toHaveBeenCalledTimes(1);
|
|
101
|
+
expect(API.prototype.postDetailed).toHaveBeenCalledWith(
|
|
102
|
+
"items/local-send",
|
|
103
|
+
{ value: "second" },
|
|
104
|
+
);
|
|
105
|
+
expect(payload?.result).toEqual({ ok: true });
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("peut décorer une méthode avec send après sa résolution", async () => {
|
|
109
|
+
const bodyPubId = "postSpecMethodSend";
|
|
110
|
+
const pub = PublisherManager.get(bodyPubId);
|
|
111
|
+
pub.set({ value: "first" });
|
|
112
|
+
const bodyKey = new DataProviderKey<{ value: string }>(bodyPubId);
|
|
113
|
+
const syncEp = new Endpoint<{ ok: boolean }>("items/method-send");
|
|
114
|
+
const localPost = post(syncEp, bodyKey);
|
|
115
|
+
const tag = "test-api-post-method-send";
|
|
116
|
+
|
|
117
|
+
class C extends HTMLElement {
|
|
118
|
+
@localPost
|
|
119
|
+
payload: ApiResult<{ ok: boolean }> | null = null;
|
|
120
|
+
|
|
121
|
+
@send(localPost)
|
|
122
|
+
async save() {
|
|
123
|
+
await Promise.resolve();
|
|
124
|
+
pub.set({ value: "after" });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (!customElements.get(tag)) {
|
|
128
|
+
customElements.define(tag, C);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const wrap = document.createElement("div");
|
|
132
|
+
wrap.setAttribute("serviceURL", "https://api.example.test");
|
|
133
|
+
const el = document.createElement(tag) as InstanceType<typeof C>;
|
|
134
|
+
wrap.appendChild(el);
|
|
135
|
+
document.body.appendChild(wrap);
|
|
136
|
+
|
|
137
|
+
await flushSendFrames();
|
|
138
|
+
vi.mocked(API.prototype.postDetailed).mockClear();
|
|
139
|
+
|
|
140
|
+
await el.save();
|
|
141
|
+
await flushSendFrames();
|
|
142
|
+
|
|
143
|
+
expect(API.prototype.postDetailed).toHaveBeenCalledWith(
|
|
144
|
+
"items/method-send",
|
|
145
|
+
{ value: "after" },
|
|
146
|
+
);
|
|
147
|
+
});
|
|
148
|
+
|
|
71
149
|
it("endpoint dynamique et relance quand le body publisher mute", async () => {
|
|
72
150
|
const bodyPubId = "postSpecBody2";
|
|
73
151
|
const pub = PublisherManager.get(bodyPubId);
|
|
@@ -6,7 +6,7 @@ import API, {
|
|
|
6
6
|
type ApiResult,
|
|
7
7
|
} from "@supersoniks/concorde/core/utils/api";
|
|
8
8
|
import { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy";
|
|
9
|
-
import { get } from "./api";
|
|
9
|
+
import { get, refetch } from "./api";
|
|
10
10
|
|
|
11
11
|
const staticConfig: APIConfiguration = {
|
|
12
12
|
serviceURL: "https://api.example.test",
|
|
@@ -190,6 +190,146 @@ describe("get", () => {
|
|
|
190
190
|
expect(el.payload?.result).toEqual({ id: "loaded" });
|
|
191
191
|
});
|
|
192
192
|
|
|
193
|
+
it("expose un refetch local avant et après le premier payload", async () => {
|
|
194
|
+
const pubId = "getSpecLocalRefetch";
|
|
195
|
+
PublisherManager.get(pubId).set(staticConfig);
|
|
196
|
+
const confKey = new DataProviderKey<APIConfiguration>(pubId);
|
|
197
|
+
const itemEp = new Endpoint<{ id: string }>("items/local");
|
|
198
|
+
const localGet = get(itemEp, confKey);
|
|
199
|
+
const tag = "test-api-get-local-refetch";
|
|
200
|
+
|
|
201
|
+
class C extends HTMLElement {
|
|
202
|
+
@localGet
|
|
203
|
+
payload: ApiResult<{ id: string }> | null = null;
|
|
204
|
+
}
|
|
205
|
+
if (!customElements.get(tag)) {
|
|
206
|
+
customElements.define(tag, C);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const el = document.createElement(tag) as InstanceType<typeof C>;
|
|
210
|
+
document.body.appendChild(el);
|
|
211
|
+
|
|
212
|
+
const firstRefetch = localGet.refetch(el);
|
|
213
|
+
expect(firstRefetch).toBeInstanceOf(Promise);
|
|
214
|
+
const firstPayload = await firstRefetch;
|
|
215
|
+
expect(API.prototype.getDetailed).toHaveBeenCalledTimes(1);
|
|
216
|
+
expect(firstPayload?.result).toEqual({ id: "loaded" });
|
|
217
|
+
|
|
218
|
+
vi.mocked(API.prototype.getDetailed).mockClear();
|
|
219
|
+
el.payload = mockPayload({ id: "manual" });
|
|
220
|
+
const secondPayload = await localGet.refetch(el);
|
|
221
|
+
|
|
222
|
+
expect(API.prototype.getDetailed).toHaveBeenCalledTimes(1);
|
|
223
|
+
expect(secondPayload?.result).toEqual({ id: "loaded" });
|
|
224
|
+
expect(el.payload?.result).toEqual({ id: "loaded" });
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it("ne refait plus de GET avec un handle local après déconnexion", async () => {
|
|
228
|
+
const pubId = "getSpecLocalRefetchDisconnect";
|
|
229
|
+
PublisherManager.get(pubId).set(staticConfig);
|
|
230
|
+
const confKey = new DataProviderKey<APIConfiguration>(pubId);
|
|
231
|
+
const localGet = get(
|
|
232
|
+
new Endpoint<{ id: string }>("items/local-disconnect"),
|
|
233
|
+
confKey,
|
|
234
|
+
);
|
|
235
|
+
const tag = "test-api-get-local-refetch-disconnect";
|
|
236
|
+
|
|
237
|
+
class C extends HTMLElement {
|
|
238
|
+
@localGet
|
|
239
|
+
payload: ApiResult<{ id: string }> | null = null;
|
|
240
|
+
}
|
|
241
|
+
if (!customElements.get(tag)) {
|
|
242
|
+
customElements.define(tag, C);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const el = document.createElement(tag) as InstanceType<typeof C>;
|
|
246
|
+
document.body.appendChild(el);
|
|
247
|
+
await flushGetFrames();
|
|
248
|
+
vi.mocked(API.prototype.getDetailed).mockClear();
|
|
249
|
+
|
|
250
|
+
el.remove();
|
|
251
|
+
await localGet.refetch(el);
|
|
252
|
+
|
|
253
|
+
expect(API.prototype.getDetailed).not.toHaveBeenCalled();
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it("peut décorer une méthode et refetcher après sa résolution", async () => {
|
|
257
|
+
const pubId = "getSpecMethodRefetch";
|
|
258
|
+
PublisherManager.get(pubId).set(staticConfig);
|
|
259
|
+
const confKey = new DataProviderKey<APIConfiguration>(pubId);
|
|
260
|
+
const rowEp = new Endpoint<{ id: string }, { rowId: string }>(
|
|
261
|
+
"rows/${rowId}",
|
|
262
|
+
);
|
|
263
|
+
const localGet = get(rowEp, confKey);
|
|
264
|
+
const tag = "test-api-get-method-refetch";
|
|
265
|
+
|
|
266
|
+
class C extends HTMLElement {
|
|
267
|
+
rowId = "42";
|
|
268
|
+
|
|
269
|
+
@localGet
|
|
270
|
+
payload: ApiResult<{ id: string }> | null = null;
|
|
271
|
+
|
|
272
|
+
@refetch(localGet)
|
|
273
|
+
async reload() {
|
|
274
|
+
await Promise.resolve();
|
|
275
|
+
this.rowId = "84";
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (!customElements.get(tag)) {
|
|
279
|
+
customElements.define(tag, C);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const el = document.createElement(tag) as InstanceType<typeof C>;
|
|
283
|
+
document.body.appendChild(el);
|
|
284
|
+
await flushGetFrames();
|
|
285
|
+
vi.mocked(API.prototype.getDetailed).mockClear();
|
|
286
|
+
|
|
287
|
+
await el.reload();
|
|
288
|
+
await flushGetFrames();
|
|
289
|
+
|
|
290
|
+
expect(API.prototype.getDetailed).toHaveBeenCalledWith("rows/84");
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it("attend le refetch avant la méthode avec when before", async () => {
|
|
294
|
+
const pubId = "getSpecMethodRefetchBefore";
|
|
295
|
+
PublisherManager.get(pubId).set(staticConfig);
|
|
296
|
+
const confKey = new DataProviderKey<APIConfiguration>(pubId);
|
|
297
|
+
const localGet = get(
|
|
298
|
+
new Endpoint<{ id: string }>("items/before"),
|
|
299
|
+
confKey,
|
|
300
|
+
);
|
|
301
|
+
const events: string[] = [];
|
|
302
|
+
const tag = "test-api-get-method-refetch-before";
|
|
303
|
+
|
|
304
|
+
class C extends HTMLElement {
|
|
305
|
+
@localGet
|
|
306
|
+
payload: ApiResult<{ id: string }> | null = null;
|
|
307
|
+
|
|
308
|
+
@refetch(localGet, { when: "before" })
|
|
309
|
+
reload() {
|
|
310
|
+
events.push("method");
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
if (!customElements.get(tag)) {
|
|
314
|
+
customElements.define(tag, C);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const el = document.createElement(tag) as InstanceType<typeof C>;
|
|
318
|
+
document.body.appendChild(el);
|
|
319
|
+
await flushGetFrames();
|
|
320
|
+
vi.mocked(API.prototype.getDetailed).mockClear();
|
|
321
|
+
events.length = 0;
|
|
322
|
+
vi.mocked(API.prototype.getDetailed).mockImplementation(async () => {
|
|
323
|
+
events.push("request");
|
|
324
|
+
return mockPayload({ id: "loaded" }) as never;
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
await el.reload();
|
|
328
|
+
|
|
329
|
+
expect(events).toEqual(["request", "method"]);
|
|
330
|
+
expect(API.prototype.getDetailed).toHaveBeenCalledWith("items/before");
|
|
331
|
+
});
|
|
332
|
+
|
|
193
333
|
it("refetch automatique avec refetchEveryMs", async () => {
|
|
194
334
|
vi.useFakeTimers();
|
|
195
335
|
const itemEp = new Endpoint<{ id: string }>("items/1");
|