@supersoniks/concorde 4.9.9 → 4.9.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/build-infos.json +1 -1
  2. package/concorde-core.bundle.js +241 -241
  3. package/concorde-core.es.js +2931 -2851
  4. package/dist/concorde-core.bundle.js +241 -241
  5. package/dist/concorde-core.es.js +2931 -2851
  6. package/dist/js/core/decorators/api.js +146 -43
  7. package/dist/js/core/decorators/api.js.map +1 -1
  8. package/dist/js/decorators.js +4 -0
  9. package/dist/js/decorators.js.map +1 -1
  10. package/dist/types/core/decorators/api.d.ts +87 -60
  11. package/dist/types/core/decorators/api.d.ts.map +1 -1
  12. package/dist/types/decorators.d.ts +3 -1
  13. package/dist/types/decorators.d.ts.map +1 -1
  14. package/docs/assets/index-D2Q3JyQ6.css +1 -0
  15. package/docs/assets/{index-hElUgV9_.js → index-DURr6O71.js} +651 -736
  16. package/docs/crawl/docs/_decorators/get.html +89 -81
  17. package/docs/crawl/docs/_decorators/patch.html +43 -23
  18. package/docs/crawl/docs/_decorators/post.html +101 -72
  19. package/docs/crawl/docs/_decorators/put.html +44 -21
  20. package/docs/crawl/docs/_getting-started/ai-agents.html +45 -6
  21. package/docs/crawl/hubs/decorators.html +145 -70
  22. package/docs/crawl/hubs/remote-data.html +145 -70
  23. package/docs/index.html +2 -2
  24. package/docs/llms-full.txt +276 -147
  25. package/docs/llms.txt +4 -4
  26. package/docs/src/core/components/functional/queue/queue.md +0 -0
  27. package/docs/src/core/components/ui/button/button.md +0 -0
  28. package/docs/src/docs/_decorators/get.md +88 -80
  29. package/docs/src/docs/_decorators/patch.md +41 -25
  30. package/docs/src/docs/_decorators/post.md +104 -62
  31. package/docs/src/docs/_decorators/put.md +42 -24
  32. package/docs/src/docs/_getting-started/ai-agents.md +24 -4
  33. package/docs/src/docs/search/docs-search.json +182 -112
  34. package/docs/src/tsconfig.json +270 -267
  35. package/package.json +1 -1
  36. package/src/core/decorators/api.post.spec.ts +79 -1
  37. package/src/core/decorators/api.spec.ts +141 -1
  38. package/src/core/decorators/api.ts +330 -180
  39. package/src/decorators.ts +7 -0
  40. package/src/docs/_decorators/get.md +88 -80
  41. package/src/docs/_decorators/patch.md +41 -25
  42. package/src/docs/_decorators/post.md +104 -62
  43. package/src/docs/_decorators/put.md +42 -24
  44. package/src/docs/components/docs-demo-sources.ts +9 -14
  45. package/src/docs/example/decorators-demo-geo.ts +0 -21
  46. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +42 -133
  47. package/src/docs/search/docs-search.json +128 -133
  48. package/docs/assets/index-Bnp7gVaA.css +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supersoniks/concorde",
3
- "version": "4.9.9",
3
+ "version": "4.9.92",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "",
@@ -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");