svelte-ag 1.2.5 → 1.2.7
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/dist/api/query/query.svelte.d.ts.map +1 -1
- package/dist/api/query/query.svelte.js +7 -2
- package/dist/api/query/query.unit.test.js +42 -0
- package/dist/bin/build-tailwind-manifest.d.ts.map +1 -1
- package/dist/components/carousel/index.d.ts +10 -12
- package/dist/components/carousel/index.d.ts.map +1 -1
- package/dist/components/form/index.d.ts +12 -13
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/search/index.d.ts +7 -8
- package/dist/components/search/index.d.ts.map +1 -1
- package/dist/components/sidebar/index.d.ts +31 -35
- package/dist/components/sidebar/index.d.ts.map +1 -1
- package/dist/index.d.ts +18 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/vite/index.d.ts.map +1 -1
- package/package.json +34 -34
- package/src/lib/api/query/query.svelte.ts +8 -4
- package/src/lib/api/query/query.unit.test.ts +64 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-ag",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.7",
|
|
4
4
|
"description": "Useful svelte components",
|
|
5
5
|
"bugs": "https://github.com/ageorgeh/svelte-ag/issues",
|
|
6
6
|
"author": "Alexander Hornung",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"bits-ui": "^2.18.1",
|
|
54
54
|
"clsx": "^2.1.1",
|
|
55
55
|
"dequal": "^2.0.3",
|
|
56
|
-
"devalue": "^5.8.
|
|
56
|
+
"devalue": "^5.8.1",
|
|
57
57
|
"embla-carousel-svelte": "8.6.0",
|
|
58
58
|
"es-module-lexer": "^2.1.0",
|
|
59
59
|
"formsnap": "2.0.1",
|
|
@@ -61,56 +61,56 @@
|
|
|
61
61
|
"runed": "0.37.1",
|
|
62
62
|
"svelte-toolbelt": "^0.10.6",
|
|
63
63
|
"sveltekit-superforms": "2.30.1",
|
|
64
|
-
"tailwind-merge": "^3.
|
|
64
|
+
"tailwind-merge": "^3.6.0",
|
|
65
65
|
"tailwind-variants": "^3.2.2",
|
|
66
|
-
"ts-ag": "^1.2.
|
|
66
|
+
"ts-ag": "^1.2.7",
|
|
67
67
|
"tsc-alias": "^1.8.17",
|
|
68
|
-
"valibot": "^1.4.
|
|
68
|
+
"valibot": "^1.4.1"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@actions/languageserver": "^0.3.
|
|
71
|
+
"@actions/languageserver": "^0.3.57",
|
|
72
72
|
"@eslint/js": "^10.0.1",
|
|
73
|
-
"@iconify/json": "^2.2.
|
|
73
|
+
"@iconify/json": "^2.2.483",
|
|
74
74
|
"@iconify/tailwind4": "^1.2.3",
|
|
75
75
|
"@iconify/types": "^2.0.0",
|
|
76
|
-
"@internationalized/date": "^3.12.
|
|
77
|
-
"@lucide/svelte": "^1.
|
|
78
|
-
"@playwright/test": "1.
|
|
76
|
+
"@internationalized/date": "^3.12.2",
|
|
77
|
+
"@lucide/svelte": "^1.17.0",
|
|
78
|
+
"@playwright/test": "1.60.0",
|
|
79
79
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
80
|
-
"@sveltejs/kit": "^2.
|
|
81
|
-
"@sveltejs/package": "^2.5.
|
|
82
|
-
"@sveltejs/vite-plugin-svelte": "^7.1.
|
|
80
|
+
"@sveltejs/kit": "^2.63.0",
|
|
81
|
+
"@sveltejs/package": "^2.5.8",
|
|
82
|
+
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
83
83
|
"@tailwindcss/typography": "^0.5.19",
|
|
84
|
-
"@tailwindcss/vite": "^4.
|
|
84
|
+
"@tailwindcss/vite": "^4.3.0",
|
|
85
85
|
"@testing-library/svelte": "^5.3.1",
|
|
86
|
-
"@types/node": "^24.
|
|
87
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
88
|
-
"eslint": "^10.
|
|
86
|
+
"@types/node": "^24.13.0",
|
|
87
|
+
"@typescript/native-preview": "7.0.0-dev.20260604.1",
|
|
88
|
+
"eslint": "^10.4.1",
|
|
89
89
|
"eslint-plugin-better-tailwindcss": "^4.5.0",
|
|
90
|
-
"eslint-plugin-svelte": "^3.
|
|
90
|
+
"eslint-plugin-svelte": "^3.19.0",
|
|
91
91
|
"globals": "^17.6.0",
|
|
92
|
-
"happy-dom": "^20.
|
|
92
|
+
"happy-dom": "^20.10.1",
|
|
93
93
|
"husky": "^9.1.7",
|
|
94
|
-
"lint-staged": "^17.0.
|
|
95
|
-
"oxfmt": "^0.
|
|
96
|
-
"rolldown": "1.
|
|
97
|
-
"rolldown-plugin-dts": "^0.
|
|
94
|
+
"lint-staged": "^17.0.7",
|
|
95
|
+
"oxfmt": "^0.53.0",
|
|
96
|
+
"rolldown": "1.1.0",
|
|
97
|
+
"rolldown-plugin-dts": "^0.25.2",
|
|
98
98
|
"rollup-plugin-svelte": "^7.2.3",
|
|
99
99
|
"semantic-release": "^25.0.3",
|
|
100
|
-
"svelte": "^5.
|
|
101
|
-
"svelte-check": "^4.
|
|
102
|
-
"svelte-preprocess": "^6.0.
|
|
103
|
-
"svelte2tsx": "^0.7.
|
|
104
|
-
"tailwindcss": "4.
|
|
105
|
-
"tsdown": "^0.
|
|
106
|
-
"tsx": "^4.
|
|
100
|
+
"svelte": "^5.56.2",
|
|
101
|
+
"svelte-check": "^4.6.0",
|
|
102
|
+
"svelte-preprocess": "^6.0.5",
|
|
103
|
+
"svelte2tsx": "^0.7.56",
|
|
104
|
+
"tailwindcss": "4.3.0",
|
|
105
|
+
"tsdown": "^0.22.2",
|
|
106
|
+
"tsx": "^4.22.4",
|
|
107
107
|
"tw-animate-css": "^1.4.0",
|
|
108
|
-
"type-fest": "^5.
|
|
108
|
+
"type-fest": "^5.7.0",
|
|
109
109
|
"typescript": "^6.0.3",
|
|
110
|
-
"typescript-eslint": "^8.
|
|
110
|
+
"typescript-eslint": "^8.60.1",
|
|
111
111
|
"typescript-svelte-plugin": "^0.3.52",
|
|
112
|
-
"vite": "^8.0.
|
|
113
|
-
"vitest": "^4.1.
|
|
112
|
+
"vite": "^8.0.16",
|
|
113
|
+
"vitest": "^4.1.8"
|
|
114
114
|
},
|
|
115
115
|
"peerDependencies": {
|
|
116
116
|
"@sveltejs/kit": "^2.0.0",
|
|
@@ -195,19 +195,19 @@ export class Requestor<
|
|
|
195
195
|
* Then it separates the outputs and resolves each of the promises
|
|
196
196
|
*/
|
|
197
197
|
private async flushBatchQueue(batchId: string): Promise<void> {
|
|
198
|
-
const queue = this.#batchQueue[batchId]
|
|
198
|
+
const queue = this.#batchQueue[batchId]?.splice(0) ?? [];
|
|
199
|
+
if (queue.length === 0) return;
|
|
199
200
|
|
|
200
201
|
// TODO maybe remove the unBatchOutput function and just always return the
|
|
201
202
|
// same response and then its on each consumer of each query to find the relevant records
|
|
202
203
|
try {
|
|
203
204
|
const batchedInput = this.#batchInput(queue.map((q) => q.input));
|
|
204
|
-
|
|
205
205
|
const res = await this.fetch(batchedInput);
|
|
206
|
+
|
|
206
207
|
const output = await this.#unBatchOutput(
|
|
207
208
|
queue.map((q) => q.input),
|
|
208
209
|
res
|
|
209
210
|
);
|
|
210
|
-
|
|
211
211
|
if (output.length !== queue.length) {
|
|
212
212
|
throw new Error(`Batch output length mismatch for ${batchId}`);
|
|
213
213
|
}
|
|
@@ -232,8 +232,12 @@ export class Requestor<
|
|
|
232
232
|
|
|
233
233
|
if (!this.#batchTimers[batchId]) {
|
|
234
234
|
this.#batchTimers[batchId] = setTimeout(() => {
|
|
235
|
+
delete this.#batchTimers[batchId];
|
|
236
|
+
|
|
235
237
|
void this.flushBatchQueue(batchId).finally(() => {
|
|
236
|
-
|
|
238
|
+
if (this.#batchQueue[batchId]?.length === 0) {
|
|
239
|
+
delete this.#batchQueue[batchId];
|
|
240
|
+
}
|
|
237
241
|
});
|
|
238
242
|
}, this.#batchDelay);
|
|
239
243
|
}
|
|
@@ -272,6 +272,70 @@ describe('Requestor', () => {
|
|
|
272
272
|
|
|
273
273
|
await Promise.all([p1Expectation, p2Expectation]);
|
|
274
274
|
});
|
|
275
|
+
|
|
276
|
+
it('schedules a new batch for requests added while a previous batch is in flight', async () => {
|
|
277
|
+
const firstFetch = deferred<Response>();
|
|
278
|
+
const secondFetch = deferred<Response>();
|
|
279
|
+
|
|
280
|
+
const fetchMock = vi.fn((_url: string, init?: RequestInit) => {
|
|
281
|
+
if (init?.body === JSON.stringify({ ids: [1] })) {
|
|
282
|
+
return firstFetch.promise;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (init?.body === JSON.stringify({ ids: [2] })) {
|
|
286
|
+
return secondFetch.promise;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
throw new Error(`Unexpected request body: ${String(init?.body)}`);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
293
|
+
|
|
294
|
+
const requestor = createBatchedRequestor({
|
|
295
|
+
canBatch: (input) => ('group' in input && input.group) || false,
|
|
296
|
+
batchInput: (inputs) => ({ ids: inputs.map(getSingleId) }),
|
|
297
|
+
unBatchOutput: (inputs) => inputs.map((input) => jsonResponse({ id: getSingleId(input) }))
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
const p1 = requestor.request({ id: 1, group: 'team' });
|
|
301
|
+
|
|
302
|
+
await vi.advanceTimersByTimeAsync(100);
|
|
303
|
+
|
|
304
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
305
|
+
expect(fetchMock).toHaveBeenLastCalledWith(
|
|
306
|
+
`${API_URL}//users`,
|
|
307
|
+
expect.objectContaining({
|
|
308
|
+
method: 'POST',
|
|
309
|
+
body: JSON.stringify({ ids: [1] }),
|
|
310
|
+
credentials: 'include'
|
|
311
|
+
})
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
const p2 = requestor.request({ id: 2, group: 'team' });
|
|
315
|
+
|
|
316
|
+
await vi.advanceTimersByTimeAsync(99);
|
|
317
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
318
|
+
|
|
319
|
+
await vi.advanceTimersByTimeAsync(1);
|
|
320
|
+
|
|
321
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
322
|
+
expect(fetchMock).toHaveBeenLastCalledWith(
|
|
323
|
+
`${API_URL}//users`,
|
|
324
|
+
expect.objectContaining({
|
|
325
|
+
method: 'POST',
|
|
326
|
+
body: JSON.stringify({ ids: [2] }),
|
|
327
|
+
credentials: 'include'
|
|
328
|
+
})
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
firstFetch.resolve(jsonFetchResponse({ ok: true }));
|
|
332
|
+
secondFetch.resolve(jsonFetchResponse({ ok: true }));
|
|
333
|
+
|
|
334
|
+
const [response1, response2] = await Promise.all([p1, p2]);
|
|
335
|
+
|
|
336
|
+
await expect(response1.json()).resolves.toEqual({ id: 1 });
|
|
337
|
+
await expect(response2.json()).resolves.toEqual({ id: 2 });
|
|
338
|
+
});
|
|
275
339
|
});
|
|
276
340
|
|
|
277
341
|
describe('Query', () => {
|