svelte-ag 1.2.7 → 1.3.0
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/form.svelte.d.ts +7 -10
- package/dist/api/form.svelte.d.ts.map +1 -1
- package/dist/api/form.svelte.js +6 -9
- package/dist/api/query/entrypoint.svelte.d.ts +14 -6
- package/dist/api/query/entrypoint.svelte.d.ts.map +1 -1
- package/dist/api/query/entrypoint.svelte.js +11 -5
- package/dist/api/query/entrypoint.unit.test.js +23 -25
- package/dist/api/query/query.svelte.d.ts +4 -5
- package/dist/api/query/query.svelte.d.ts.map +1 -1
- package/dist/api/query/query.svelte.js +8 -12
- package/dist/api/query/query.unit.test.js +21 -30
- package/dist/api/query/utils.svelte.d.ts +8 -2
- package/dist/api/query/utils.svelte.d.ts.map +1 -1
- package/dist/api/query/utils.svelte.js +5 -4
- package/dist/index.d.ts +29 -19
- package/dist/index.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/lib/api/form.svelte.ts +27 -34
- package/src/lib/api/query/entrypoint.svelte.ts +28 -11
- package/src/lib/api/query/entrypoint.unit.test.ts +25 -27
- package/src/lib/api/query/query.svelte.ts +18 -17
- package/src/lib/api/query/query.unit.test.ts +25 -35
- package/src/lib/api/query/utils.svelte.ts +5 -4
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { stringify } from 'devalue';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
ApiEndpointContract,
|
|
4
|
+
ApiEndpoints,
|
|
5
|
+
ApiInput,
|
|
6
|
+
ApiRequestFunction,
|
|
7
|
+
ApiSuccessBody,
|
|
8
|
+
ApiErrorBody,
|
|
9
|
+
ApiResponse
|
|
10
|
+
} from 'ts-ag';
|
|
3
11
|
|
|
4
12
|
import type { Cache } from './cache.svelte';
|
|
5
13
|
import type { BatchDetails } from './entrypoint.svelte';
|
|
@@ -17,8 +25,7 @@ export class Query<
|
|
|
17
25
|
#TIMEOUT = 1000 * 60 * 5; // 5 minutes
|
|
18
26
|
|
|
19
27
|
// -------- Set in constructor --------
|
|
20
|
-
#
|
|
21
|
-
#method: Method;
|
|
28
|
+
#endpoint: ApiEndpointContract<API, Path, Method>;
|
|
22
29
|
#input: ApiInput<API, Path, Method>;
|
|
23
30
|
#inputString: string;
|
|
24
31
|
#cacheKey: string;
|
|
@@ -37,15 +44,13 @@ export class Query<
|
|
|
37
44
|
|
|
38
45
|
// -------- Functions --------
|
|
39
46
|
constructor({
|
|
40
|
-
|
|
41
|
-
method,
|
|
47
|
+
endpoint,
|
|
42
48
|
input,
|
|
43
49
|
requestor,
|
|
44
50
|
cache,
|
|
45
51
|
opts
|
|
46
52
|
}: {
|
|
47
|
-
|
|
48
|
-
method: Method;
|
|
53
|
+
endpoint: ApiEndpointContract<API, Path, Method>;
|
|
49
54
|
input: ApiInput<API, Path, Method>;
|
|
50
55
|
requestor: Requestor<API, Path, Method>;
|
|
51
56
|
cache: Cache;
|
|
@@ -56,14 +61,13 @@ export class Query<
|
|
|
56
61
|
this.#requestor = requestor;
|
|
57
62
|
this.#cache = cache;
|
|
58
63
|
|
|
59
|
-
this.#
|
|
60
|
-
this.#method = method;
|
|
64
|
+
this.#endpoint = endpoint;
|
|
61
65
|
|
|
62
66
|
// if (this.#cachekey) this.#cache.deregister(this.#cachekey);
|
|
63
67
|
|
|
64
68
|
this.#input = input;
|
|
65
69
|
this.#inputString = stringify(input);
|
|
66
|
-
this.#cacheKey = cacheKey(
|
|
70
|
+
this.#cacheKey = cacheKey(endpoint, input);
|
|
67
71
|
|
|
68
72
|
this.#cache.register(this.#cacheKey, opts?.cache ?? { timeout: this.#TIMEOUT });
|
|
69
73
|
}
|
|
@@ -141,8 +145,7 @@ export class Requestor<
|
|
|
141
145
|
#batchDelay = 100;
|
|
142
146
|
|
|
143
147
|
// -------- Set in constructor --------
|
|
144
|
-
#
|
|
145
|
-
#method: Method;
|
|
148
|
+
#endpoint: ApiEndpointContract<API, Path, Method>;
|
|
146
149
|
#request: ApiRequestFunction<API>;
|
|
147
150
|
|
|
148
151
|
#canBatch: BatchDetails<API, Path, Method>['canBatch'];
|
|
@@ -164,14 +167,12 @@ export class Requestor<
|
|
|
164
167
|
#batchTimers: Record<string, NodeJS.Timeout | null> = {};
|
|
165
168
|
|
|
166
169
|
constructor(
|
|
167
|
-
|
|
168
|
-
method: Method,
|
|
170
|
+
endpoint: ApiEndpointContract<API, Path, Method>,
|
|
169
171
|
request: ApiRequestFunction<API>,
|
|
170
172
|
_cache: Cache,
|
|
171
173
|
batchDetails?: BatchDetails<API, Path, Method>
|
|
172
174
|
) {
|
|
173
|
-
this.#
|
|
174
|
-
this.#method = method;
|
|
175
|
+
this.#endpoint = endpoint;
|
|
175
176
|
this.#request = request;
|
|
176
177
|
this.#limiter = new RateLimiter();
|
|
177
178
|
// this.#cache = cache;
|
|
@@ -187,7 +188,7 @@ export class Requestor<
|
|
|
187
188
|
// if ('PUBLIC_ENVIRONMENT' in env && env.PUBLIC_ENVIRONMENT === 'development') {
|
|
188
189
|
// await sleep(1000);
|
|
189
190
|
// }
|
|
190
|
-
return await this.#limiter.add(() => this.#request(this.#
|
|
191
|
+
return await this.#limiter.add(() => this.#request(this.#endpoint, input));
|
|
191
192
|
}
|
|
192
193
|
|
|
193
194
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { stringify } from 'devalue';
|
|
2
|
-
import { createApiRequest, type ApiEndpoints } from 'ts-ag';
|
|
2
|
+
import { createApiRequest, type ApiEndpointContract, type ApiEndpoints } from 'ts-ag';
|
|
3
3
|
import * as v from 'valibot';
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
5
5
|
|
|
@@ -30,17 +30,17 @@ type BatchedUsersApi = {
|
|
|
30
30
|
|
|
31
31
|
const API_URL = 'https://api.example.test';
|
|
32
32
|
|
|
33
|
-
const
|
|
34
|
-
'/users'
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
}
|
|
33
|
+
const plainUsers_GET = {
|
|
34
|
+
path: '/users',
|
|
35
|
+
method: 'GET',
|
|
36
|
+
schema: v.object({ id: v.number() })
|
|
37
|
+
} satisfies ApiEndpointContract<PlainUsersApi, '/users', 'GET'>;
|
|
38
38
|
|
|
39
|
-
const
|
|
40
|
-
'/users'
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
}
|
|
39
|
+
const batchedUsers_POST = {
|
|
40
|
+
path: '/users',
|
|
41
|
+
method: 'POST',
|
|
42
|
+
schema: v.union([v.object({ id: v.number(), group: v.optional(v.string()) }), v.object({ ids: v.array(v.number()) })])
|
|
43
|
+
} satisfies ApiEndpointContract<BatchedUsersApi, '/users', 'POST'>;
|
|
44
44
|
|
|
45
45
|
function getSingleId(input: BatchedUsersApi['requestInput']): number {
|
|
46
46
|
return 'id' in input ? input.id : input.ids[0]!;
|
|
@@ -97,23 +97,22 @@ function deferred<T>() {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
function createPlainRequest() {
|
|
100
|
-
return createApiRequest<PlainUsersApi>(
|
|
100
|
+
return createApiRequest<PlainUsersApi>(API_URL, 'test');
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
function createBatchedRequest() {
|
|
104
|
-
return createApiRequest<BatchedUsersApi>(
|
|
104
|
+
return createApiRequest<BatchedUsersApi>(API_URL, 'test');
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
function createPlainRequestor() {
|
|
108
|
-
return new Requestor<PlainUsersApi, '/users', 'GET'>(
|
|
108
|
+
return new Requestor<PlainUsersApi, '/users', 'GET'>(plainUsers_GET, createPlainRequest(), new Cache());
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
function createBatchedRequestor(
|
|
112
|
-
batchDetails?: ConstructorParameters<typeof Requestor<BatchedUsersApi, '/users', 'POST'>>[
|
|
112
|
+
batchDetails?: ConstructorParameters<typeof Requestor<BatchedUsersApi, '/users', 'POST'>>[3]
|
|
113
113
|
) {
|
|
114
114
|
return new Requestor<BatchedUsersApi, '/users', 'POST'>(
|
|
115
|
-
|
|
116
|
-
'POST',
|
|
115
|
+
batchedUsers_POST,
|
|
117
116
|
createBatchedRequest(),
|
|
118
117
|
new Cache(),
|
|
119
118
|
batchDetails
|
|
@@ -355,8 +354,7 @@ describe('Query', () => {
|
|
|
355
354
|
const fetchMock = vi.fn().mockReturnValue(pending.promise);
|
|
356
355
|
vi.stubGlobal('fetch', fetchMock);
|
|
357
356
|
const query = new Query<PlainUsersApi, '/users', 'GET'>({
|
|
358
|
-
|
|
359
|
-
method: 'GET',
|
|
357
|
+
endpoint: plainUsers_GET,
|
|
360
358
|
input: { id: 1 },
|
|
361
359
|
requestor: createPlainRequestor(),
|
|
362
360
|
cache: new Cache()
|
|
@@ -378,8 +376,7 @@ describe('Query', () => {
|
|
|
378
376
|
const fetchMock = vi.fn(async () => jsonFetchResponse({ id: 1, name: 'Ada' }));
|
|
379
377
|
vi.stubGlobal('fetch', fetchMock);
|
|
380
378
|
const query = new Query<PlainUsersApi, '/users', 'GET'>({
|
|
381
|
-
|
|
382
|
-
method: 'GET',
|
|
379
|
+
endpoint: plainUsers_GET,
|
|
383
380
|
input: { id: 1 },
|
|
384
381
|
requestor: createPlainRequestor(),
|
|
385
382
|
cache: new Cache()
|
|
@@ -400,8 +397,7 @@ describe('Query', () => {
|
|
|
400
397
|
);
|
|
401
398
|
vi.stubGlobal('fetch', fetchMock);
|
|
402
399
|
const query = new Query<PlainUsersApi, '/users', 'GET'>({
|
|
403
|
-
|
|
404
|
-
method: 'GET',
|
|
400
|
+
endpoint: plainUsers_GET,
|
|
405
401
|
input: { id: 1 },
|
|
406
402
|
requestor: createPlainRequestor(),
|
|
407
403
|
cache: new Cache()
|
|
@@ -430,8 +426,7 @@ describe('Query', () => {
|
|
|
430
426
|
const fetchMock = vi.fn(async () => withResponseOverrides(jsonFetchResponse({ id: 1 })));
|
|
431
427
|
vi.stubGlobal('fetch', fetchMock);
|
|
432
428
|
const query = new Query<PlainUsersApi, '/users', 'GET'>({
|
|
433
|
-
|
|
434
|
-
method: 'GET',
|
|
429
|
+
endpoint: plainUsers_GET,
|
|
435
430
|
input: { id: 1 },
|
|
436
431
|
requestor: createPlainRequestor(),
|
|
437
432
|
cache: new Cache()
|
|
@@ -457,8 +452,7 @@ describe('Query', () => {
|
|
|
457
452
|
const fetchMock = vi.fn(async () => jsonFetchResponse({ id: 1, active: true }));
|
|
458
453
|
vi.stubGlobal('fetch', fetchMock);
|
|
459
454
|
const query = new Query<PlainUsersApi, '/users', 'GET'>({
|
|
460
|
-
|
|
461
|
-
method: 'GET',
|
|
455
|
+
endpoint: plainUsers_GET,
|
|
462
456
|
input: { id: 1 },
|
|
463
457
|
requestor: createPlainRequestor(),
|
|
464
458
|
cache: new Cache()
|
|
@@ -476,8 +470,7 @@ describe('Query', () => {
|
|
|
476
470
|
const fetchMock = vi.fn(async () => jsonFetchResponse({ message: 'missing' }, 404));
|
|
477
471
|
vi.stubGlobal('fetch', fetchMock);
|
|
478
472
|
const query = new Query<PlainUsersApi, '/users', 'GET'>({
|
|
479
|
-
|
|
480
|
-
method: 'GET',
|
|
473
|
+
endpoint: plainUsers_GET,
|
|
481
474
|
input: { id: 99 },
|
|
482
475
|
requestor: createPlainRequestor(),
|
|
483
476
|
cache: new Cache()
|
|
@@ -505,8 +498,7 @@ describe('Query', () => {
|
|
|
505
498
|
});
|
|
506
499
|
vi.stubGlobal('fetch', fetchMock);
|
|
507
500
|
const query = new Query<PlainUsersApi, '/users', 'GET'>({
|
|
508
|
-
|
|
509
|
-
method: 'GET',
|
|
501
|
+
endpoint: plainUsers_GET,
|
|
510
502
|
input: { id: 1 },
|
|
511
503
|
requestor: createPlainRequestor(),
|
|
512
504
|
cache: new Cache()
|
|
@@ -532,8 +524,7 @@ describe('Query', () => {
|
|
|
532
524
|
});
|
|
533
525
|
vi.stubGlobal('fetch', fetchMock);
|
|
534
526
|
const query = new Query<PlainUsersApi, '/users', 'GET'>({
|
|
535
|
-
|
|
536
|
-
method: 'GET',
|
|
527
|
+
endpoint: plainUsers_GET,
|
|
537
528
|
input: { id: 1 },
|
|
538
529
|
requestor: createPlainRequestor(),
|
|
539
530
|
cache: new Cache()
|
|
@@ -558,8 +549,7 @@ describe('Query', () => {
|
|
|
558
549
|
});
|
|
559
550
|
vi.stubGlobal('fetch', fetchMock);
|
|
560
551
|
const query = new Query<PlainUsersApi, '/users', 'GET'>({
|
|
561
|
-
|
|
562
|
-
method: 'GET',
|
|
552
|
+
endpoint: plainUsers_GET,
|
|
563
553
|
input: { id: 1 },
|
|
564
554
|
requestor: createPlainRequestor(),
|
|
565
555
|
cache: new Cache(),
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { stringify } from 'devalue';
|
|
2
|
+
import { endpointKey } from 'ts-ag';
|
|
2
3
|
|
|
3
|
-
export function batchQueryKey(path: string
|
|
4
|
-
return
|
|
4
|
+
export function batchQueryKey(endpoint: { path: string; method: string }) {
|
|
5
|
+
return endpointKey(endpoint);
|
|
5
6
|
}
|
|
6
7
|
|
|
7
|
-
export function cacheKey(path: string
|
|
8
|
-
return `${
|
|
8
|
+
export function cacheKey(endpoint: { path: string; method: string }, input: any) {
|
|
9
|
+
return `${endpointKey(endpoint)} ${stringify(input)}`;
|
|
9
10
|
}
|